diff --git a/docs/architecture/adr-004-mcp-trait-decoupling.md b/docs/architecture/adr-004-mcp-trait-decoupling.md new file mode 100644 index 0000000..b35acec --- /dev/null +++ b/docs/architecture/adr-004-mcp-trait-decoupling.md @@ -0,0 +1,34 @@ +# ADR-004: MCP Tool Layer Trait Decoupling + +- **状态**: accepted +- **日期**: 2026-05-11 +- **作者**: devbase 架构优化会话 + +## 上下文 + +`src/mcp/tools/` 中的 MCP 工具实现直接内联调用 `crate::health::`、`crate::search::`、`crate::registry::` 等底层模块,导致: +- 工具层与业务层硬耦合,无法独立测试 +- `repo.rs` 等文件 `crate::` 内联引用超过 10 处,违反架构红线 +- 新增工具时容易引入隐式依赖 + +## 决策 + +为每个业务领域定义 trait(`ScanClient`、`HealthClient`、`RegistryClient`、`KnowledgeClient`、`SearchClient`、`RepoAnalyzer` 等),由 `AppContext` 统一实现,MCP 工具只依赖 trait。 + +## 后果 + +- **正面**: `repo.rs` `crate::` 引用从 11 降至 8(全部集中在 use 语句);工具层可独立单元测试;新增领域只需扩展 trait +- **负面**: trait 定义与实现分属不同文件,跳转成本略增;简单查询也需 trait 封装 +- **风险**: 过度抽象可能导致 trait 膨胀;需定期审查 trait 方法是否仍被使用 + +## 备选方案 + +| 方案 | 不选原因 | +|------|---------| +| 保持现状,仅清理 use 语句 | 未解决测试隔离问题 | +| 每个工具独立 service struct | 与现有 `AppContext` 模式冲突,引入更多类型 | + +## 相关决策 + +- 依赖:ADR-001(单 crate 模型使 trait 定义零成本) +- 被依赖:ADR-005(AppContext Clone 是 trait 在 spawn_blocking 中使用的前提) diff --git a/docs/architecture/adr-005-appcontext-clone.md b/docs/architecture/adr-005-appcontext-clone.md new file mode 100644 index 0000000..fe867e6 --- /dev/null +++ b/docs/architecture/adr-005-appcontext-clone.md @@ -0,0 +1,34 @@ +# ADR-005: AppContext Clone for Async Context Propagation + +- **状态**: accepted +- **日期**: 2026-05-11 +- **作者**: devbase 架构优化会话 + +## 上下文 + +MCP 工具频繁使用 `tokio::task::spawn_blocking` 执行 I/O 密集型操作(Tantivy 索引、SQLite 查询、文件系统遍历)。此前 `AppContext` 未实现 `Clone`,导致: +- 闭包内无法调用 `ctx.list_vault_notes()` 等 trait 方法 +- 被迫在 `spawn_blocking` 外获取 `conn` 再 move 进闭包,增加生命周期复杂度 +- `VaultClient`、`WorkflowClient` 等 trait 难以在异步上下文中使用 + +## 决策 + +将 `AppContext.env_cache` 从 `std::sync::Mutex` 改为 `Arc>`,并为 `AppContext` 添加 `#[derive(Clone)]`。 + +## 后果 + +- **正面**: `spawn_blocking` 闭包内可直接 `ctx.clone()` 后调用任意 trait 方法;统一 async/sync 边界处理模式 +- **负面**: `Clone` 后多个上下文共享同一 `Mutex`,并发修改 env_cache 的竞争概率微增(当前仅 daemon 定期刷新,可忽略) +- **风险**: 未来若向 `AppContext` 添加非 Clone 字段,需回退到显式字段 clone 模式 + +## 备选方案 + +| 方案 | 不选原因 | +|------|---------| +| 为每个 trait 定义无状态 Impl (ZST) | `RegistryClient` 等方法需 `conn`,无状态 impl 需传入 `Connection`,违反 T11 红线 | +| 使用 `Arc` 包装 | 增加一层间接,所有调用点需改为 `arc.ctx.method()`,改动面过大 | +| 将 `Pool` 单独 clone move 进闭包 | 已在使用,但无法调用 `DigestClient` 等需要 config/i18n 的 trait 方法 | + +## 相关决策 + +- 依赖:ADR-004(trait 化后,clone 成为 spawn_blocking 中使用 trait 的基础设施) diff --git a/docs/architecture/adr-template.md b/docs/architecture/adr-template.md index a10634e..a1f4f25 100644 --- a/docs/architecture/adr-template.md +++ b/docs/architecture/adr-template.md @@ -46,6 +46,9 @@ |------|------|------|------| | ADR-001 | 单 crate 模型(defer split)| accepted | 2026-04-26 | | ADR-002 | Candle CPU BERT 单条编码(batch 回滚)| accepted | 2026-05-04 | +| ADR-003 | Tantivy + SQLite 双写一致性策略 | proposed | 2026-05-11 | +| ADR-004 | MCP Tool Layer Trait Decoupling | accepted | 2026-05-11 | +| ADR-005 | AppContext Clone for Async Context Propagation | accepted | 2026-05-11 | ### ADR-001: 单 crate 模型(defer split) diff --git a/src/daemon.rs b/src/daemon.rs index 20891f6..039ffb7 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -1,5 +1,12 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 juice094 +//! Background daemon: periodic health checks, re-indexing, discovery, +//! daily digest generation, and relation graph maintenance. +//! +//! The daemon runs on a configurable schedule (`daemon.interval_seconds`) +//! and uses `tokio::spawn_blocking` for CPU- or I/O-heavy tasks to avoid +//! blocking the async runtime. + use crate::config::Config; use crate::digest::generate_daily_digest; use crate::discovery_engine::{discover_dependencies, discover_similar_projects}; diff --git a/src/embedding.rs b/src/embedding.rs index cc0d6d3..7472121 100644 --- a/src/embedding.rs +++ b/src/embedding.rs @@ -1,7 +1,11 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 juice094 -// RE-EXPORT ONLY — 实现已迁移至 devbase-embedding crate. -// 禁止在本文件中添加新代码。 +//! Embedding generation: local Candle-based BERT inference for code symbols. +//! +//! **Re-export only** — implementation lives in the `devbase-embedding` crate. +//! Do not add new code here; extend the extracted crate instead. +//! +//! Feature-gated behind `embedding`; disabled by default to reduce binary size. #[cfg(feature = "embedding")] pub use devbase_embedding::*; diff --git a/src/i18n/mod.rs b/src/i18n/mod.rs index f7e6c8b..654d819 100644 --- a/src/i18n/mod.rs +++ b/src/i18n/mod.rs @@ -1,5 +1,15 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 juice094 +//! Internationalization (i18n) layer for devbase. +//! +//! Provides language-specific UI strings for TUI, CLI, sync reports, and logs. +//! Supported languages: English (`en`) and Simplified Chinese (`zh_cn`). +//! +//! **Note on `#[allow(dead_code)]`**: Many string fields are accessed only when +//! the `tui` feature is enabled. Without this attribute, compiling without +//! `--features tui` would produce spurious dead-code warnings. The fields are +//! actively used in production builds with the default feature set. + #[derive(Clone, Copy)] #[allow(dead_code)] pub struct I18n { diff --git a/src/knowledge_engine/mod.rs b/src/knowledge_engine/mod.rs index f482e79..c8418ec 100644 --- a/src/knowledge_engine/mod.rs +++ b/src/knowledge_engine/mod.rs @@ -1,5 +1,15 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 juice094 +//! Knowledge engine: repository indexing, summary extraction, and module analysis. +//! +//! Orchestrates Tantivy full-text indexing, SQLite registry persistence, +//! semantic code indexing (AST + call graph), and optional embedding generation. +//! +//! Entry points: +//! - [`run_index`] — batch index all registered repos or a single path +//! - [`index_repo`] — index a single repo (standalone writer) +//! - [`index_repo_with_writer`] — index a single repo reusing an existing writer + pub mod fallback; pub mod index; pub mod index_state; diff --git a/src/registry.rs b/src/registry.rs index 1ffaccc..d4967cb 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -1,5 +1,12 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 juice094 +//! Registry layer: SQLite-backed entity storage and domain-specific submodules. +//! +//! Central types (`RepoEntry`, `VaultNote`, `PaperEntry`, etc.) and the +//! [`RegistryClient`] trait implementation on [`AppContext`]. +//! Submodules cover repos, health, knowledge, code metrics, call graphs, +//! dead-code analysis, and migrations. + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::path::PathBuf; diff --git a/src/storage.rs b/src/storage.rs index 4f14713..db90611 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,5 +1,13 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 juice094 +//! Storage abstraction and application context (`AppContext`). +//! +//! [`StorageBackend`] decouples concrete paths from consumers, enabling +//! test isolation via [`TempStorageBackend`] and future remote backends. +//! [`AppContext`] is the central dependency-injection container: it holds +//! the storage backend, database pool, config, i18n, and environment cache, +//! and implements all MCP client traits (`ScanClient`, `HealthClient`, etc.). + use crate::config::Config; use crate::i18n::{I18n, from_language}; use crate::registry::{ENTITY_TYPE_REPO, WorkspaceRegistry}; diff --git a/src/workflow/mod.rs b/src/workflow/mod.rs index eb534bc..be45150 100644 --- a/src/workflow/mod.rs +++ b/src/workflow/mod.rs @@ -1,5 +1,15 @@ // SPDX-License-Identifier: MIT // Copyright (c) 2026 juice094 +//! Workflow automation engine: YAML-defined multi-step pipelines with parallel +//! execution, variable interpolation, and SQLite-backed execution tracking. +//! +//! A workflow consists of ordered steps, each referencing a registered Skill. +//! The scheduler builds independent batches; the executor runs each batch in +//! parallel while preserving step ordering across batches. +//! +//! Key traits: +//! - [`WorkflowClient`] — MCP-facing API for listing, running, and querying workflows + pub mod executor; pub mod interpolate; pub mod model;