From 6f1af0d01f534099945f57df94e5f3627ef05ae1 Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Wed, 17 Dec 2025 23:48:50 -0700 Subject: [PATCH] move repo-code config objects to their own submodule --- signal-gateway-repo-code/src/config.rs | 61 ++++++++++++++++++++++++ signal-gateway-repo-code/src/lib.rs | 66 ++------------------------ 2 files changed, 66 insertions(+), 61 deletions(-) create mode 100644 signal-gateway-repo-code/src/config.rs diff --git a/signal-gateway-repo-code/src/config.rs b/signal-gateway-repo-code/src/config.rs new file mode 100644 index 0000000..d4a75d4 --- /dev/null +++ b/signal-gateway-repo-code/src/config.rs @@ -0,0 +1,61 @@ +//! Configuration types for repository code browsing. + +use serde::Deserialize; +use std::{path::PathBuf, str::FromStr}; + +/// A GitHub repository identifier (owner/repo). +#[derive(Clone, Debug, Deserialize)] +#[serde(try_from = "String")] +pub struct GitHubRepo { + /// The repository owner (user or organization). + pub owner: String, + /// The repository name. + pub repo: String, +} + +impl FromStr for GitHubRepo { + type Err = String; + + fn from_str(s: &str) -> Result { + let parts: Vec<&str> = s.split('/').collect(); + if parts.len() != 2 || parts[0].is_empty() || parts[1].is_empty() { + return Err(format!( + "invalid GitHub repo '{}': expected 'owner/repo' format", + s + )); + } + Ok(Self { + owner: parts[0].to_string(), + repo: parts[1].to_string(), + }) + } +} + +impl TryFrom for GitHubRepo { + type Error = String; + + fn try_from(s: String) -> Result { + s.parse() + } +} + +/// Configuration for an application's source code access. +#[derive(Clone, Debug, Deserialize)] +pub struct RepoCodeConfig { + /// Name of the application (used to identify it in tool calls). + pub name: String, + /// GitHub repository in "owner/repo" format. + pub github: GitHubRepo, + /// Path to file containing the GitHub personal access token. + /// Optional for public repositories (unauthenticated access has lower rate limits). + pub token_file: Option, + /// Glob patterns to filter which files are included from the tarball. + /// If non-empty, only files matching at least one pattern are kept. + /// Uses gitignore-style glob syntax (e.g., "*.rs", "src/**/*.rs"). + #[serde(default)] + pub glob: Vec, + /// Include files that aren't valid UTF-8 (using lossy conversion). + /// By default (false), non-UTF-8 files are skipped entirely. + #[serde(default)] + pub include_non_utf8: bool, +} diff --git a/signal-gateway-repo-code/src/lib.rs b/signal-gateway-repo-code/src/lib.rs index bd4ad56..c254583 100644 --- a/signal-gateway-repo-code/src/lib.rs +++ b/signal-gateway-repo-code/src/lib.rs @@ -3,77 +3,21 @@ //! This crate provides tools for browsing application source code by downloading //! tarballs from GitHub and caching them in memory. +mod config; + +pub use config::{GitHubRepo, RepoCodeConfig}; + use async_trait::async_trait; use flate2::read::GzDecoder; use globset::{Glob, GlobSet, GlobSetBuilder}; use regex::Regex; use serde::Deserialize; use signal_gateway_assistant::{Tool, ToolExecutor, ToolResult}; -use std::{ - collections::HashMap, error::Error, fmt::Write, future::Future, io::Read, path::PathBuf, - pin::Pin, str::FromStr, sync::Arc, -}; +use std::{collections::HashMap, error::Error, fmt::Write, future::Future, io::Read, pin::Pin, sync::Arc}; use tar::Archive; use tokio::sync::{Mutex, MutexGuard}; use tracing::{error, info, warn}; -/// A GitHub repository identifier (owner/repo). -#[derive(Clone, Debug, Deserialize)] -#[serde(try_from = "String")] -pub struct GitHubRepo { - /// The repository owner (user or organization). - pub owner: String, - /// The repository name. - pub repo: String, -} - -impl FromStr for GitHubRepo { - type Err = String; - - fn from_str(s: &str) -> Result { - let parts: Vec<&str> = s.split('/').collect(); - if parts.len() != 2 || parts[0].is_empty() || parts[1].is_empty() { - return Err(format!( - "invalid GitHub repo '{}': expected 'owner/repo' format", - s - )); - } - Ok(Self { - owner: parts[0].to_string(), - repo: parts[1].to_string(), - }) - } -} - -impl TryFrom for GitHubRepo { - type Error = String; - - fn try_from(s: String) -> Result { - s.parse() - } -} - -/// Configuration for an application's source code access. -#[derive(Clone, Debug, Deserialize)] -pub struct RepoCodeConfig { - /// Name of the application (used to identify it in tool calls). - pub name: String, - /// GitHub repository in "owner/repo" format. - pub github: GitHubRepo, - /// Path to file containing the GitHub personal access token. - /// Optional for public repositories (unauthenticated access has lower rate limits). - pub token_file: Option, - /// Glob patterns to filter which files are included from the tarball. - /// If non-empty, only files matching at least one pattern are kept. - /// Uses gitignore-style glob syntax (e.g., "*.rs", "src/**/*.rs"). - #[serde(default)] - pub glob: Vec, - /// Include files that aren't valid UTF-8 (using lossy conversion). - /// By default (false), non-UTF-8 files are skipped entirely. - #[serde(default)] - pub include_non_utf8: bool, -} - /// A file stored in memory from the tarball. #[derive(Debug, Clone)] struct CachedFile {