use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct SearchRequest {
#[schemars(
description = "Natural language search query describing the code you're looking for"
)]
pub query: String,
#[schemars(
description = "Filter by chunk type: function, method, class, struct, enum, interface, module, impl, trait, doc, section, table, code_block, commit, issue (alias: bead), other"
)]
pub r#type: Option<String>,
#[schemars(description = "Maximum number of results to return (default: 10)")]
pub limit: Option<usize>,
#[schemars(
description = "Search mode: 'hybrid' (combines semantic+keyword, default), 'semantic' (vector similarity), or 'keyword' (full-text)"
)]
pub mode: Option<String>,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
#[schemars(
description = "Include only chunks tagged with these tags (comma-separated, e.g. 'core,api')"
)]
pub tag: Option<String>,
#[schemars(
description = "Exclude chunks tagged with these tags (comma-separated, e.g. 'test,generated')"
)]
pub exclude_tag: Option<String>,
#[schemars(
description = "Scope results to a named context bundle (e.g. 'context/pipeline', 'hook'). Omit to search all files."
)]
pub bundle: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SearchResponse {
pub query: String,
pub mode: String,
pub count: usize,
pub results: Vec<SearchResultItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SearchResultItem {
pub id: String,
pub file_path: String,
pub name: Option<String>,
pub chunk_type: String,
pub source: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub repo: Option<String>,
pub start_line: u32,
pub end_line: u32,
pub score: f32,
pub match_type: Option<String>,
pub language: String,
pub content_preview: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct GrepRequest {
#[schemars(
description = "Pattern to search for. Supports full-text search queries, or regex if regex=true"
)]
pub pattern: String,
#[schemars(description = "Enable case-insensitive search")]
pub ignore_case: Option<bool>,
#[schemars(description = "Enable extended regex matching (post-filters FTS results)")]
pub regex: Option<bool>,
#[schemars(
description = "Filter by chunk type: function, method, class, struct, enum, interface, module, impl, trait, doc, section, table, code_block, commit, issue (alias: bead), other"
)]
pub r#type: Option<String>,
#[schemars(description = "Maximum number of results to return (default: 10)")]
pub limit: Option<usize>,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct GrepResponse {
pub pattern: String,
pub count: usize,
pub results: Vec<GrepResultItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct GrepResultItem {
pub file_path: String,
pub name: Option<String>,
pub chunk_type: String,
pub source: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub repo: Option<String>,
pub start_line: u32,
pub end_line: u32,
pub score: f32,
pub language: String,
pub content_preview: String,
pub matching_lines: Vec<MatchingLine>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct MatchingLine {
pub line_number: u32,
pub content: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ContextRequest {
#[schemars(description = "Natural language task description to assemble context for")]
pub query: String,
#[schemars(
description = "Maximum lines of code content to include in the context bundle (default: 500)"
)]
pub budget: Option<usize>,
#[schemars(
description = "Depth of temporal coupling expansion. 0 disables coupling, 1 expands one level (default: 1)"
)]
pub depth: Option<u32>,
#[schemars(
description = "Maximum number of coupled files to include per seed file (default: 3)"
)]
pub max_coupled: Option<usize>,
#[schemars(
description = "Maximum number of initial search results to use as seeds (default: 20)"
)]
pub limit: Option<usize>,
#[schemars(
description = "Minimum coupling score threshold for including related files (default: 0.1)"
)]
pub coupling_threshold: Option<f32>,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
#[schemars(
description = "Include only chunks tagged with these tags (comma-separated, e.g. 'core,api')"
)]
pub tag: Option<String>,
#[schemars(
description = "Exclude chunks tagged with these tags (comma-separated, e.g. 'test,generated')"
)]
pub exclude_tag: Option<String>,
#[schemars(
description = "Scope results to a named context bundle (e.g. 'context/pipeline', 'hook'). Omit to search all files."
)]
pub bundle: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ContextResponse {
pub query: String,
pub budget: ContextBudgetInfo,
pub files: Vec<ContextFileOutput>,
pub summary: ContextSummaryOutput,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ContextBudgetInfo {
pub max_lines: usize,
pub used_lines: usize,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ContextFileOutput {
pub path: String,
pub language: String,
pub relevance: String,
pub score: f32,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub coupled_to: Vec<String>,
pub chunks: Vec<ContextChunkOutput>,
#[serde(skip_serializing_if = "Option::is_none")]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ContextChunkOutput {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub chunk_type: String,
pub start_line: u32,
pub end_line: u32,
pub score: f32,
#[serde(skip_serializing_if = "Option::is_none")]
pub match_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ContextSummaryOutput {
pub total_files: usize,
pub total_chunks: usize,
pub direct_hits: usize,
pub coupled_additions: usize,
pub bridged_additions: usize,
pub source_files: usize,
pub doc_files: usize,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct RelatedRequest {
#[schemars(description = "File path (relative to repo root) to find related files for")]
pub file: String,
#[schemars(description = "Maximum number of related files to return (default: 10)")]
pub limit: Option<usize>,
#[schemars(description = "Minimum coupling score threshold (0.0-1.0, default: 0.0)")]
pub threshold: Option<f32>,
#[schemars(
description = "Repo the file belongs to (optional; disambiguates cross-repo coupling lookups in a multi-repo store)"
)]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct RelatedResponse {
pub file: String,
pub related: Vec<RelatedFile>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct RelatedFile {
pub path: String,
pub score: f32,
pub co_changes: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub repo: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct TestCoverageRequest {
#[schemars(
description = "File path (relative to repo root). A source file returns the test files that cover it; a test file returns the source files it covers."
)]
pub file: String,
#[schemars(description = "Maximum number of coverage links to return (default: 10)")]
pub limit: Option<usize>,
#[schemars(description = "Minimum coupling score threshold (0.0-1.0, default: 0.0)")]
pub threshold: Option<f32>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct TestCoverageResponse {
pub file: String,
pub link_kind: String,
pub links: Vec<CoverageLinkOutput>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct CoverageLinkOutput {
pub path: String,
pub score: f32,
pub co_changes: u32,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct FindRefsRequest {
#[schemars(
description = "Exact symbol name to find references for (e.g., 'parse_config', 'Config', 'handle_request')"
)]
pub symbol: String,
#[schemars(
description = "Filter by symbol type: function, method, class, struct, enum, interface, module, impl, trait"
)]
pub r#type: Option<String>,
#[schemars(description = "Maximum number of usage results to return (default: 20)")]
pub limit: Option<usize>,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct FindRefsResponse {
pub symbol: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub definition: Option<SymbolDefinitionOutput>,
pub usage_count: usize,
pub usages: Vec<SymbolUsageOutput>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SymbolDefinitionOutput {
pub name: String,
pub chunk_type: String,
pub file_path: String,
pub start_line: u32,
pub end_line: u32,
pub signature: String,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SymbolUsageOutput {
pub file_path: String,
pub line: u32,
pub context: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ListSymbolsRequest {
#[schemars(
description = "File path (relative to repo root) to list symbols for (e.g., 'src/main.rs', 'lib/config.ts')"
)]
pub file: String,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ListSymbolsResponse {
pub file: String,
pub count: usize,
pub symbols: Vec<SymbolItemOutput>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SymbolItemOutput {
pub name: String,
pub chunk_type: String,
pub start_line: u32,
pub end_line: u32,
pub signature: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ReadChunkRequest {
#[schemars(description = "File path (relative to repo root) containing the code chunk")]
pub file: String,
#[schemars(description = "Starting line number of the code chunk")]
pub start_line: u32,
#[schemars(description = "Ending line number of the code chunk")]
pub end_line: u32,
#[schemars(
description = "Number of context lines to include before and after the chunk (default: 0)"
)]
pub context: Option<u32>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ReadChunkResponse {
pub file: String,
pub start_line: u32,
pub end_line: u32,
pub actual_start_line: u32,
pub actual_end_line: u32,
pub content: String,
pub language: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct HotspotsRequest {
#[schemars(
description = "Time window for churn analysis (default: '1 year ago'). Examples: '6 months ago', '3 months ago', '2 years ago'"
)]
pub since: Option<String>,
#[schemars(description = "Maximum number of hotspots to return (default: 20)")]
pub limit: Option<usize>,
#[schemars(
description = "Minimum hotspot score threshold (0.0-1.0, default: 0.0). Higher values filter to only the most critical hotspots."
)]
pub threshold: Option<f32>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct HotspotsResponse {
pub count: usize,
pub since: String,
pub hotspots: Vec<HotspotItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct HotspotItem {
pub file: String,
pub score: f32,
pub churn: u32,
pub complexity: f32,
pub language: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct PrimeRequest {
#[schemars(
description = "Optional section name to show. Available: 'what bobbin does', 'architecture', 'supported languages', 'key commands', 'mcp tools', 'quick start', 'configuration'. Omit to show the full primer."
)]
pub section: Option<String>,
#[schemars(
description = "If true, show only the title and first section for a compact overview"
)]
pub brief: Option<bool>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct PrimeResponse {
pub primer: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub section: Option<String>,
pub initialized: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub stats: Option<PrimeStats>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct PrimeStats {
pub total_files: u64,
pub total_chunks: u64,
pub total_embeddings: u64,
pub languages: Vec<PrimeLanguageStats>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_indexed: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct PrimeLanguageStats {
pub language: String,
pub file_count: u64,
pub chunk_count: u64,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ImpactRequest {
#[schemars(
description = "File path or file:function target (e.g. 'src/auth.rs' or 'src/auth.rs:login_handler')"
)]
pub target: String,
#[schemars(
description = "Transitive expansion depth (1 = direct only, 2-3 = expand through results with score decay). Default: 1"
)]
pub depth: Option<u32>,
#[schemars(
description = "Which signals to use: 'combined' (default, uses all), 'coupling' (git co-change only), 'semantic' (vector similarity only), 'deps' (dependency graph, not yet available)"
)]
pub mode: Option<String>,
#[schemars(description = "Maximum number of results to return (default: 15)")]
pub limit: Option<usize>,
#[schemars(description = "Minimum impact score threshold (0.0-1.0, default: 0.1)")]
pub threshold: Option<f32>,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ImpactResponse {
pub target: String,
pub mode: String,
pub depth: u32,
pub count: usize,
pub results: Vec<ImpactResultItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ImpactResultItem {
pub file: String,
pub signal: String,
pub score: f32,
pub reason: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct SimilarRequest {
#[schemars(
description = "Target to find similar code for. Use 'file.rs:function_name' for a chunk reference, or free text like 'error handling with retry'. Required unless scan=true."
)]
pub target: Option<String>,
#[schemars(
description = "If true, scan entire codebase for near-duplicate clusters instead of searching for a specific target"
)]
pub scan: Option<bool>,
#[schemars(
description = "Minimum cosine similarity threshold (0.0-1.0, default: 0.85 for single target, 0.90 for scan)"
)]
pub threshold: Option<f32>,
#[schemars(
description = "Maximum number of results (single target) or clusters (scan mode) to return (default: 10)"
)]
pub limit: Option<usize>,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
#[schemars(
description = "In scan mode, compare chunks across different repos (default: false)"
)]
pub cross_repo: Option<bool>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SimilarResponse {
pub mode: String,
pub threshold: f32,
#[serde(skip_serializing_if = "Option::is_none")]
pub target: Option<String>,
pub count: usize,
pub results: Vec<SimilarResultItem>,
pub clusters: Vec<SimilarClusterItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SimilarResultItem {
pub file_path: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub chunk_type: String,
pub start_line: u32,
pub end_line: u32,
pub similarity: f32,
pub language: String,
pub explanation: String,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SimilarClusterItem {
pub representative: SimilarChunkRef,
pub avg_similarity: f32,
pub member_count: usize,
pub members: Vec<SimilarResultItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SimilarChunkRef {
pub file_path: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub chunk_type: String,
pub start_line: u32,
pub end_line: u32,
pub language: String,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ReviewRequest {
#[schemars(
description = "What to diff. Use 'unstaged' for working tree changes, 'staged' for staged changes, 'branch:<name>' to compare a branch against main, or a commit range like 'HEAD~3..HEAD'."
)]
pub diff: Option<String>,
#[schemars(
description = "Maximum lines of code content to include in the review context (default: 500)"
)]
pub budget: Option<usize>,
#[schemars(
description = "Depth of temporal coupling expansion. 0 disables coupling, 1 expands one level (default: 1)"
)]
pub depth: Option<u32>,
#[schemars(
description = "Filter results to a specific repository name. Omit to search across all indexed repos."
)]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ReviewResponse {
pub diff_description: String,
pub changed_files: Vec<ReviewChangedFile>,
pub budget: ContextBudgetInfo,
pub files: Vec<ContextFileOutput>,
pub summary: ContextSummaryOutput,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ReviewChangedFile {
pub path: String,
pub status: String,
pub added_lines: usize,
pub removed_lines: usize,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct SearchBeadsRequest {
#[schemars(
description = "Natural language search query to find relevant beads/issues (e.g. 'cert expiry', 'disk pressure', 'auth bug')"
)]
pub query: String,
#[schemars(
description = "Filter by priority level (1=P1 critical, 2=P2 high, 3=P3 medium, 4=P4 low)"
)]
pub priority: Option<i32>,
#[schemars(description = "Filter by issue status: 'open', 'in_progress', 'closed'")]
pub status: Option<String>,
#[schemars(description = "Filter by assignee (e.g. 'aegis/crew/braino')")]
pub assignee: Option<String>,
#[schemars(
description = "Filter by rig name (e.g. 'aegis', 'gastown'). Matches against the file_path prefix 'beads:<rig>:'."
)]
pub rig: Option<String>,
#[schemars(description = "Filter by issue type: 'bug', 'task', 'feature', 'epic', 'chore'")]
pub issue_type: Option<String>,
#[schemars(
description = "Filter by label (e.g. 'tech-debt', 'enhancement'). Matches if any label contains the filter string."
)]
pub label: Option<String>,
#[schemars(description = "Maximum number of results to return (default: 10)")]
pub limit: Option<usize>,
#[schemars(
description = "If true (default), enrich results with live status/priority/assignee read from the bead store itself. Set to false for faster indexed-only results."
)]
pub enrich: Option<bool>,
#[schemars(
description = "If true (default), omit the snippet field to reduce token overhead. Set to false to include a content snippet."
)]
pub compact: Option<bool>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct SearchBeadsResponse {
pub query: String,
pub count: usize,
pub results: Vec<BeadResultItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct BeadResultItem {
pub bead_id: String,
pub title: String,
pub priority: String,
pub status: String,
pub issue_type: String,
pub assignee: String,
pub owner: String,
pub rig: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub labels: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<String>,
pub relevance_score: f32,
pub match_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub snippet: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct DependenciesRequest {
#[schemars(description = "File path (relative to repo root) to show import dependencies for")]
pub file: String,
#[schemars(
description = "If true, show reverse dependencies (files that import this file) instead of forward dependencies"
)]
pub reverse: Option<bool>,
#[schemars(description = "If true, show both forward imports and reverse dependents")]
pub both: Option<bool>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct DependenciesResponse {
pub file: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub imports: Option<Vec<DependencyItem>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub imported_by: Option<Vec<DependencyItem>>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct DependencyItem {
pub path: String,
pub dep_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
pub resolved: bool,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct FileHistoryRequest {
#[schemars(description = "File path (relative to repo root) to show commit history for")]
pub file: String,
#[schemars(description = "Maximum number of commit entries to return (default: 20)")]
pub limit: Option<usize>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct FileHistoryResponse {
pub file: String,
pub entries: Vec<FileHistoryItem>,
pub stats: FileHistoryStats,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct FileHistoryItem {
pub date: String,
pub author: String,
pub message: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub issues: Vec<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct FileHistoryStats {
pub total_commits: usize,
pub authors: Vec<FileHistoryAuthor>,
pub churn_rate: f32,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct FileHistoryAuthor {
pub name: String,
pub commits: usize,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct StatusRequest {
#[schemars(description = "If true, include per-language breakdown in the response")]
pub detailed: Option<bool>,
#[schemars(
description = "Filter statistics to a specific repository name. Omit to show stats for all repos."
)]
pub repo: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct StatusResponse {
pub status: String,
pub total_files: u64,
pub total_chunks: u64,
pub total_embeddings: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_indexed: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dependency_stats: Option<StatusDependencyStats>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub repos: Vec<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub languages: Vec<StatusLanguageStats>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct StatusDependencyStats {
pub total: u64,
pub resolved: u64,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct StatusLanguageStats {
pub language: String,
pub file_count: u64,
pub chunk_count: u64,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct CommitSearchRequest {
#[schemars(
description = "Natural language query describing what commit(s) you're looking for. Examples: 'added authentication', 'fixed memory leak', 'refactored database layer'"
)]
pub query: String,
#[schemars(
description = "Filter to commits by a specific author (case-insensitive substring match)"
)]
pub author: Option<String>,
#[schemars(
description = "Filter to commits that touched a specific file path (substring match)"
)]
pub file: Option<String>,
#[schemars(description = "Maximum number of commit results to return (default: 10)")]
pub limit: Option<usize>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct CommitSearchResponse {
pub query: String,
pub count: usize,
pub results: Vec<CommitResultItem>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct CommitResultItem {
pub hash: String,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub author: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub date: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub files: Vec<String>,
pub score: f32,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ArchiveSearchRequest {
#[schemars(
description = "Natural language query to search archive records (e.g. 'deploy failures', 'cert renewal')"
)]
pub query: String,
#[schemars(
description = "Filter by archive source: 'hla' (IRC/Telegram chat logs) or 'pensieve' (agent memory records). Omit to search all sources."
)]
pub source: Option<String>,
#[schemars(
description = "Filter by name field value (e.g. 'telegram' for HLA channel, 'goldblum' for Pensieve agent)"
)]
pub filter: Option<String>,
#[schemars(description = "Only include records after this date (YYYY-MM-DD format)")]
pub after: Option<String>,
#[schemars(description = "Only include records before this date (YYYY-MM-DD format)")]
pub before: Option<String>,
#[schemars(description = "Maximum number of results to return (default: 10)")]
pub limit: Option<usize>,
#[schemars(description = "Search mode: 'hybrid' (default), 'semantic', or 'keyword'")]
pub mode: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ArchiveRecentRequest {
#[schemars(
description = "Only include records after this date (YYYY-MM-DD format). Optional — defaults to 30 days ago."
)]
pub after: Option<String>,
#[schemars(
description = "Filter by archive source: 'hla' (IRC/Telegram chat logs) or 'pensieve' (agent memory records). Omit to list from all sources."
)]
pub source: Option<String>,
#[schemars(description = "Maximum number of results to return (default: 20)")]
pub limit: Option<usize>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct FeedbackSubmitRequest {
#[schemars(
description = "Injection ID from [injection_id: inj-xxx] in context injection output"
)]
pub injection_id: String,
#[schemars(
description = "Rating for the injection quality: 'useful' (helped with task), 'noise' (irrelevant), or 'harmful' (actively misleading)"
)]
pub rating: String,
#[schemars(description = "Agent identity (auto-detected from environment if omitted)")]
pub agent: Option<String>,
#[schemars(description = "Optional explanation of why this rating was given (max 1000 chars)")]
pub reason: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct FeedbackListRequest {
#[schemars(description = "Filter by rating: 'useful', 'noise', or 'harmful'")]
pub rating: Option<String>,
#[schemars(description = "Filter by agent name")]
pub agent: Option<String>,
#[schemars(description = "Maximum number of results to return (default: 20, max: 50)")]
pub limit: Option<usize>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct FeedbackStatsRequest {
#[serde(default)]
#[schemars(description = "Group stats by 'bundle' or 'bead'. Omit for aggregated totals.")]
pub group_by: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct FeedbackLineageStoreRequest {
#[schemars(
description = "Feedback record IDs this action resolves. Get IDs from bobbin_feedback_list output."
)]
pub feedback_ids: Vec<i64>,
#[schemars(
description = "Type of action: 'code_fix' (bug fix or feature), 'config_change' (bobbin config tuning), 'tag_effect' (tag/annotation change), 'access_rule' (access control change), or 'exclusion_rule' (file exclusion)"
)]
pub action_type: String,
#[schemars(
description = "Bead ID this action is associated with (e.g. 'aegis-abc123'). Optional."
)]
pub bead: Option<String>,
#[schemars(description = "Git commit hash for the fix. Optional.")]
pub commit_hash: Option<String>,
#[schemars(
description = "What was done to address the feedback (e.g. 'Added exclusion rule for generated files')"
)]
pub description: String,
#[schemars(description = "Agent identity (auto-detected from environment if omitted)")]
pub agent: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct FeedbackLineageListRequest {
#[schemars(description = "Filter lineage records linked to a specific feedback ID")]
pub feedback_id: Option<i64>,
#[schemars(description = "Filter by bead ID (e.g. 'aegis-abc123')")]
pub bead: Option<String>,
#[schemars(description = "Filter by git commit hash")]
pub commit_hash: Option<String>,
#[schemars(description = "Maximum number of results (default: 20, max: 50)")]
pub limit: Option<usize>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeContextRequest {
#[schemars(
description = "Natural language query describing the knowledge graph entities you're looking for"
)]
pub query: String,
#[schemars(description = "Maximum number of knowledge graph entities to return (default: 20)")]
pub max_entities: Option<usize>,
#[schemars(
description = "Expand results by following graph links from direct hits (default: true)"
)]
pub expand_links: Option<bool>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum KnowledgeShareScopeKind {
Root,
Graph,
Group,
Construct,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeExportRequest {
pub scope_kind: KnowledgeShareScopeKind,
pub scope_value: Option<String>,
#[schemars(description = "RDF format: ntriples (canonical) or turtle")]
pub format: Option<String>,
#[schemars(description = "Return only byte count, triple count, and sha256 identity")]
pub digest_only: Option<bool>,
pub max_bytes: Option<usize>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeShareRequest {
pub scope_kind: KnowledgeShareScopeKind,
pub scope_value: Option<String>,
pub shapes: Option<Vec<String>>,
pub no_shapes: Option<bool>,
pub parent_share: Option<String>,
pub turtle_view: Option<bool>,
pub max_bytes: Option<usize>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeImportRequest {
pub manifest: serde_json::Value,
pub export_ntriples: String,
pub shapes_turtle: Option<String>,
pub source: String,
pub actor: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeImportPromoteRequest {
pub share_id: String,
pub actor: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeKnotRequest {
#[schemars(
description = "Facts to write, as RDF Turtle. Validated against the configured SHACL shapes before anything is committed."
)]
pub turtle: String,
#[schemars(
description = "Actor recorded as the author of this write (provenance). Omit only if the caller genuinely has no identity to record."
)]
pub actor: Option<String>,
#[schemars(
description = "Source of the facts (e.g. a file path, a tool name). Recorded alongside the write."
)]
pub source: Option<String>,
#[schemars(
description = "Optional SHACL shapes (Turtle) to validate this write against instead of the store's configured shapes"
)]
pub shapes: Option<String>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeInferredExtractRequest {
#[schemars(
description = "Markdown prose to run the inferred-track extractor over. Candidates are CLAIMS, not observations."
)]
pub text: String,
#[schemars(
description = "Repository name the prose belongs to, for IRI minting (default: adhoc)"
)]
pub repo: Option<String>,
#[schemars(
description = "File path the prose came from, for the source-chunk IRI (default: adhoc.md)"
)]
pub file_path: Option<String>,
#[schemars(
description = "Also land the stamped facts in the quarantined crew:inferred plane via /knot (default: false, preview only). Refused unless the embedded quipu enforces strict graph routing."
)]
pub push: Option<bool>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeQueryRequest {
#[schemars(description = "SPARQL SELECT query to run against the knowledge graph")]
pub query: String,
#[schemars(
description = "ISO-8601 timestamp for temporal query (what was true at this time?)"
)]
pub valid_at: Option<String>,
#[schemars(description = "Transaction ID for point-in-time query")]
pub tx: Option<i64>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct KnowledgeReconcileRequest {
#[schemars(
description = "Maximum per-mention detail entries to return (default: 50). The three counts are always complete."
)]
pub max_details: Option<usize>,
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct ChunkNeighborsRequest {
#[schemars(
description = "Chunk ID (the `id` field on search results). Preferred way to identify the anchor chunk. Either this or file+line is required."
)]
pub id: Option<String>,
#[schemars(
description = "Repo-relative file path — used with `line` to resolve the anchor chunk when no `id` is given"
)]
pub file: Option<String>,
#[schemars(
description = "Line number within `file`; the smallest chunk containing this line becomes the anchor"
)]
pub line: Option<u32>,
#[schemars(
description = "Repository name — disambiguates `file` when several indexed repos contain the same relative path"
)]
pub repo: Option<String>,
#[schemars(
description = "Filter edges by type: next_chunk, part_of, implements, impl_for, extends, tests, similar_to. Omit for all types."
)]
pub edge_type: Option<String>,
#[schemars(
description = "Direction relative to the anchor: \"out\" (anchor is edge source), \"in\" (anchor is edge target), or \"both\" (default). For next_chunk: out = following chunk, in = preceding. For part_of: out = containing parent, in = children."
)]
pub direction: Option<String>,
#[schemars(description = "Maximum number of neighbors to return (default: 20)")]
pub limit: Option<usize>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ChunkRef {
pub id: String,
pub file_path: String,
pub name: Option<String>,
pub chunk_type: String,
pub start_line: u32,
pub end_line: u32,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct NeighborItem {
pub edge_type: String,
pub direction: String,
#[serde(flatten)]
pub chunk: ChunkRef,
pub content_preview: String,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub struct ChunkNeighborsResponse {
pub chunk: ChunkRef,
pub count: usize,
pub neighbors: Vec<NeighborItem>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub dangling: Vec<String>,
}