use std::collections::BTreeMap;
use rmcp::schemars;
use serde::{Deserialize, Serialize};
use super::cursor::Cursor;
use crate::path::RelPath;
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct OutlineParams {
pub path: RelPath,
#[serde(default)]
pub l2: bool,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct SearchSymbolsParams {
pub needle: String,
#[serde(default)]
pub kind: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct ListFilesParams {
#[serde(default)]
pub path_contains: Option<String>,
#[serde(default)]
pub language: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct DependentsParams {
pub module: String,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct StatusParams {}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct WorkingTreeStatusParams {}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct RecentChangesParams {
#[serde(default)]
pub limit: Option<u32>,
#[serde(default = "default_true")]
pub include_files: bool,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct CommitsTouchingParams {
pub path: RelPath,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct DiffOutlineParams {
pub path: RelPath,
#[serde(default)]
pub rev: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct RepoInfoParams {}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct BlameFileParams {
pub path: RelPath,
#[serde(default)]
pub line_start: Option<u32>,
#[serde(default)]
pub line_end: Option<u32>,
#[serde(default)]
pub rev: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct FindCommitsByPathParams {
pub pattern: String,
#[serde(default)]
pub window: Option<u32>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct HotFilesParams {
#[serde(default)]
pub window: Option<u32>,
#[serde(default)]
pub top_k: Option<u32>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct DiffFileParams {
pub rev_old: String,
pub rev_new: String,
pub path: RelPath,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct SymbolHistoryParams {
pub path: RelPath,
pub name: String,
#[serde(default)]
pub kind: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub hash_mode: Option<String>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct FindReferencesParams {
pub name: String,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct FindCallersParams {
pub path: RelPath,
pub name: String,
#[serde(default)]
pub kind: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct BlameSymbolParams {
pub path: RelPath,
pub name: String,
#[serde(default)]
pub kind: Option<String>,
#[serde(default)]
pub rev: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
fn default_true() -> bool {
true
}
#[derive(Debug, Serialize)]
pub(super) struct OutlineResponse {
pub path: RelPath,
pub language: String,
pub size_bytes: u64,
pub had_errors: bool,
pub error_count: u32,
pub symbols: Vec<SymbolView>,
pub imports: Vec<ImportView>,
#[serde(skip_serializing_if = "Option::is_none")]
pub calls: Option<Vec<CallView>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub docs: Option<Vec<DocView>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub l2_status: Option<&'static str>,
}
#[derive(Debug, Serialize)]
pub(super) struct SymbolView {
pub name: String,
pub kind: String,
pub start_row: u32,
pub start_col: u32,
pub start_byte: u32,
pub end_byte: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature: Option<String>,
}
#[derive(Debug, Serialize)]
pub(super) struct ImportView {
#[serde(skip_serializing_if = "Option::is_none")]
pub module: Option<String>,
pub raw: String,
pub start_byte: u32,
}
#[derive(Debug, Serialize)]
pub(super) struct CallView {
pub callee: String,
pub start_byte: u32,
}
#[derive(Debug, Serialize)]
pub(super) struct DocView {
pub text: String,
pub start_byte: u32,
}
#[derive(Debug, Serialize)]
pub(super) struct SearchHitView {
pub path: RelPath,
pub name: String,
pub kind: String,
pub start_row: u32,
pub start_col: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature: Option<String>,
}
#[derive(Debug, Serialize)]
pub(super) struct SearchResponse {
pub total: usize,
pub truncated: bool,
pub results: Vec<SearchHitView>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub cursor_invalidated: bool,
}
#[derive(Debug, Serialize)]
pub(super) struct ListFilesEntry {
pub path: RelPath,
pub language: String,
pub size_bytes: u64,
}
#[derive(Debug, Serialize)]
pub(super) struct ListFilesResponse {
pub total: usize,
pub returned: usize,
pub truncated: bool,
pub files: Vec<ListFilesEntry>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub cursor_invalidated: bool,
}
#[derive(Debug, Serialize)]
pub(super) struct DependentsResponse {
pub module: String,
pub paths: Vec<RelPath>,
}
#[derive(Debug, Serialize)]
pub(super) struct StatusResponse {
pub file_count: usize,
pub total_size_bytes: u64,
pub languages: BTreeMap<String, usize>,
pub cache_dir: String,
pub schema_version: u16,
pub root: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub submodules: Vec<RelPath>,
}
#[derive(Debug, Serialize)]
pub(super) struct CommitView {
pub sha: String,
pub short_sha: String,
pub summary: String,
pub author: String,
pub author_time_unix: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub files: Option<Vec<CommitFileView>>,
}
#[derive(Debug, Serialize)]
pub(super) struct CommitFileView {
pub path: RelPath,
pub change: &'static str,
}
#[derive(Debug, Serialize)]
pub(super) struct WorkingTreeStatusView {
pub staged_added: Vec<RelPath>,
pub staged_modified: Vec<RelPath>,
pub staged_deleted: Vec<RelPath>,
pub modified: Vec<RelPath>,
pub untracked: Vec<RelPath>,
pub is_clean: bool,
}
#[derive(Debug, Serialize)]
pub(super) struct RecentChangesResponse {
pub commits: Vec<CommitView>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub truncated: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncated_reason: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub cursor_invalidated: bool,
}
#[derive(Debug, Serialize)]
pub(super) struct CommitsTouchingResponse {
pub path: RelPath,
pub commits: Vec<CommitView>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub truncated: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncated_reason: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub cursor_invalidated: bool,
}
#[derive(Debug, Serialize)]
pub(super) struct DiffSymbolView {
pub name: String,
pub kind: String,
}
#[derive(Debug, Serialize)]
pub(super) struct DiffOutlineResponse {
pub path: RelPath,
pub rev: String,
pub added: Vec<DiffSymbolView>,
pub removed: Vec<DiffSymbolView>,
pub common: Vec<DiffSymbolView>,
#[serde(skip_serializing_if = "Option::is_none")]
pub note: Option<String>,
}
#[derive(Debug, Serialize)]
pub(super) struct BlameHunkView {
pub commit_sha: String,
pub short_sha: String,
pub start_line: u32,
pub len: u32,
pub source_start_line: u32,
pub author: String,
pub author_time_unix: i64,
pub summary: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_path: Option<RelPath>,
}
#[derive(Debug, Serialize)]
pub(super) struct BlameResponse {
pub path: RelPath,
pub suspect_sha: String,
pub hunks: Vec<BlameHunkView>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub truncated: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncated_reason: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
}
#[derive(Debug, Serialize)]
pub(super) struct BlameSymbolResponse {
pub path: RelPath,
pub suspect_sha: String,
pub name: String,
pub kind: String,
pub line_start: u32,
pub line_end: u32,
pub hunks: Vec<BlameHunkView>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub truncated: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncated_reason: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
}
#[derive(Debug, Serialize)]
pub(super) struct FindCommitsByPathResponse {
pub pattern: String,
pub window_inspected: u32,
pub commits: Vec<CommitView>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub cursor_invalidated: bool,
}
#[derive(Debug, Serialize)]
pub(super) struct HotFileEntry {
pub path: RelPath,
pub commits_touching: u32,
pub added: u32,
pub modified: u32,
pub deleted: u32,
}
#[derive(Debug, Serialize)]
pub(super) struct HotFilesResponse {
pub window_inspected: u32,
pub total_files_changed: u32,
pub files: Vec<HotFileEntry>,
}
#[derive(Debug, Serialize)]
pub(super) struct HunkView {
pub kind: &'static str,
pub old_line_start: u32,
pub old_line_count: u32,
pub new_line_start: u32,
pub new_line_count: u32,
pub text: String,
}
#[derive(Debug, Serialize)]
pub(super) struct DiffFileResponse {
pub path: RelPath,
pub rev_old: String,
pub rev_new: String,
pub present_at_old: bool,
pub present_at_new: bool,
pub hunks: Vec<HunkView>,
}
#[derive(Debug, Serialize)]
pub(super) struct SymbolHistoryEntry {
pub sha: String,
pub short_sha: String,
pub summary: String,
pub author: String,
pub author_time_unix: i64,
pub change: &'static str,
}
#[derive(Debug, Serialize)]
pub(super) struct SymbolHistoryResponse {
pub path: RelPath,
pub name: String,
pub kind: Option<String>,
pub commits_inspected: u32,
pub history: Vec<SymbolHistoryEntry>,
pub hash_mode: &'static str,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub truncated: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncated_reason: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub cursor_invalidated: bool,
}
#[derive(Debug, Serialize)]
pub(super) struct ReferenceHit {
pub path: RelPath,
pub line: u32,
pub column: u32,
pub callee: String,
}
#[derive(Debug, Serialize)]
pub(super) struct FindReferencesResponse {
pub name: String,
pub total: u32,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub total_is_partial: bool,
pub hits: Vec<ReferenceHit>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
}
#[derive(Debug, Serialize)]
pub(super) struct FindCallersResponse {
pub definition: Option<DefinitionView>,
pub total: u32,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub total_is_partial: bool,
pub hits: Vec<ReferenceHit>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
}
#[derive(Debug, Serialize)]
pub(super) struct DefinitionView {
pub path: RelPath,
pub name: String,
pub kind: &'static str,
pub start_row: u32,
pub start_col: u32,
}
#[derive(Debug, Serialize)]
pub(super) struct RepoInfoResponse {
pub workdir: String,
pub head_sha: Option<String>,
pub head_short_sha: Option<String>,
pub branch: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct MemoryPutParams {
pub key: String,
pub value: String,
#[serde(default)]
pub tags: Option<Vec<String>>,
#[serde(default = "default_true")]
pub embed: bool,
}
#[cfg(feature = "memory")]
#[derive(Debug, Serialize)]
pub(super) struct MemoryPutResponse {
pub key: String,
pub created_at: i64,
pub updated_at: i64,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct MemoryGetParams {
pub key: String,
}
#[cfg(feature = "memory")]
#[derive(Debug, Serialize, Deserialize)]
pub(super) struct MemoryEntry {
pub key: String,
pub value: String,
pub tags: Vec<String>,
pub created_at: i64,
pub updated_at: i64,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct MemoryListParams {
#[serde(default)]
pub prefix: Option<String>,
#[serde(default)]
pub tag: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub cursor: Option<Cursor>,
}
#[cfg(feature = "memory")]
#[derive(Debug, Serialize)]
pub(super) struct MemoryListResponse {
pub total: usize,
pub truncated: bool,
pub entries: Vec<MemoryEntry>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<Cursor>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct MemorySearchParams {
pub query: String,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default)]
pub tag: Option<String>,
}
#[cfg(feature = "memory")]
#[derive(Debug, Serialize)]
pub(super) struct MemorySearchHit {
pub key: String,
pub value: String,
pub tags: Vec<String>,
pub distance: f32,
}
#[cfg(feature = "memory")]
#[derive(Debug, Serialize)]
pub(super) struct MemorySearchResponse {
pub query: String,
pub hits: Vec<MemorySearchHit>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct MemoryDeleteParams {
pub key: String,
}
#[cfg(feature = "memory")]
#[derive(Debug, Serialize)]
pub(super) struct MemoryDeleteResponse {
pub deleted: bool,
}
#[cfg(feature = "memory")]
#[derive(Debug, Serialize, Deserialize)]
pub(super) struct MemoryRecord {
pub value: String,
pub tags: Vec<String>,
pub created_at: i64,
pub updated_at: i64,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct WorkspaceGrepParams {
pub pattern: String,
#[serde(default)]
pub language: Option<String>,
#[serde(default)]
pub path_contains: Option<String>,
#[serde(default)]
pub limit: Option<u32>,
#[serde(default = "default_true")]
pub include_context: bool,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub(super) struct GrepHit {
pub path: RelPath,
pub line_num: u32,
pub column: u32,
pub matched_text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub context_before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context_after: Option<String>,
}
#[derive(Debug, Serialize, schemars::JsonSchema)]
pub(super) struct WorkspaceGrepResponse {
pub pattern: String,
pub total_files_matched: usize,
pub total_matches: u32,
pub truncated: bool,
pub hits: Vec<GrepHit>,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct RescanParams {
#[serde(default)]
pub paths: Option<Vec<String>>,
}
#[derive(Debug, Serialize)]
pub(super) struct RescanResponse {
pub scanned: usize,
pub updated: usize,
pub removed: usize,
pub skipped_unchanged: usize,
pub skipped_no_lang: usize,
pub extract_failed: usize,
pub elapsed_ms: u128,
pub root: String,
}
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct TelemetrySummaryParams {
#[serde(default)]
pub window: Option<String>,
#[serde(default)]
pub tool: Option<String>,
}
#[derive(Debug, Serialize)]
pub(super) struct TelemetrySummaryResponse {
pub window: String,
pub total_calls: usize,
pub total_resp_bytes: u64,
pub total_est_tokens_saved: u64,
pub per_tool: Vec<ToolCallCount>,
pub per_baseline: Vec<BaselineCount>,
pub recent: Vec<RecentCallView>,
pub truncated: bool,
pub savings_note: &'static str,
}
#[derive(Debug, Serialize)]
pub(super) struct ToolCallCount {
pub tool: String,
pub calls: usize,
pub est_tokens_saved: u64,
}
#[derive(Debug, Serialize)]
pub(super) struct BaselineCount {
pub baseline: String,
pub calls: usize,
pub est_tokens_saved: u64,
}
#[derive(Debug, Serialize)]
pub(super) struct RecentCallView {
pub ts_micros: i64,
pub tool: String,
pub resp_bytes: u64,
pub elapsed_ms: u64,
pub est_tokens_saved: u64,
}
#[cfg(feature = "crawl")]
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct WebScrapeParams {
pub url: crate::url::Url,
#[serde(default = "WebScrapeParams::default_index")]
pub index: bool,
#[serde(default)]
pub scope: Option<String>,
}
#[cfg(feature = "crawl")]
impl WebScrapeParams {
fn default_index() -> bool {
true
}
}
#[cfg(feature = "crawl")]
#[derive(Debug, Serialize)]
pub(super) struct WebScrapeResponse {
pub url: String,
pub final_url: String,
pub status_code: u16,
pub content_type: String,
pub bytes: usize,
pub chunks_indexed: usize,
pub indexed: bool,
pub scope: String,
}
#[cfg(feature = "crawl")]
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct WebCrawlParams {
pub url: crate::url::Url,
#[serde(default)]
pub max_pages: Option<u32>,
#[serde(default)]
pub max_depth: Option<u32>,
#[serde(default)]
pub scope: Option<String>,
}
#[cfg(feature = "crawl")]
#[derive(Debug, Serialize)]
pub(super) struct WebCrawlResponse {
pub seed_url: String,
pub pages_visited: usize,
pub pages_indexed: usize,
pub total_chunks: usize,
pub scope: String,
pub pages: Vec<WebCrawlPageOutcome>,
pub error: Option<String>,
}
#[cfg(feature = "crawl")]
#[derive(Debug, Serialize)]
pub(super) struct WebCrawlPageOutcome {
pub url: String,
pub status_code: u16,
pub chunks_indexed: usize,
pub indexed: bool,
pub error: Option<String>,
}
#[cfg(feature = "crawl")]
#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
pub struct WebMapParams {
pub url: crate::url::Url,
}
#[cfg(feature = "crawl")]
#[derive(Debug, Serialize)]
pub(super) struct WebMapResponse {
pub url: String,
pub total_urls: usize,
pub urls: Vec<WebMapEntry>,
}
#[cfg(feature = "crawl")]
#[derive(Debug, Serialize)]
pub(super) struct WebMapEntry {
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub lastmod: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub changefreq: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<String>,
}
pub use super::types_documents::SearchDocumentsParams;
#[cfg(feature = "documents")]
pub(super) use super::types_documents::{DocumentSearchHit, SearchDocumentsResponse};
pub use super::types_graph::CallGraphParams;
pub use super::types_impls::FindImplementationsParams;