This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
devbase is a Rust workspace (edition 2024, Rust 1.95+) that compiles a developer's local workspace (Git repos, notes, skills, workflows) into structured context consumable by AI agents. It exposes 71 MCP tools over stdio, provides a ratatui terminal dashboard, and maintains a local SQLite registry with Tantivy BM25 + vector search.
Primary dev platform: Windows 11 (CI runs on windows-latest). Linux/macOS are community-supported.
License: AGPL-3.0-or-later / dual-licensed commercial. New source files must include the SPDX header.
Project knowledge bundle: The canonical AI-agent documentation lives in .knowledge/ as an Open Knowledge Format (OKF) bundle. Start with .knowledge/index.md for the full architecture map, registry migration policy, MCP tool-adding guide, and development conventions.
# Full build (release)
cargo build --release
# Run all tests (lib + integration + examples + bins)
cargo test --all-targets
# Run a specific test (note: .cargo/config.toml pins RUST_TEST_THREADS=1 locally)
cargo test <test_name> -- --test-threads=1 --nocapture
# Lint (zero warnings enforced in CI)
cargo clippy --all-targets -D warnings
# Format check
cargo fmt --check- Default:
tui,mcp,lang-rust,lang-python,lang-js-ts,lang-go - Optional:
embedding(Candle/Ollama backends),greptimedb,watch - Build without TUI/MCP:
cargo build --no-default-features
The crates/ directory holds 12 extracted sub-crates (e.g., devbase-registry, devbase-vault-wikilink, devbase-workflow-model). Test or build a single crate:
cargo test -p devbase-registry
cargo build -p devbase-core-typesscripts/ci-local.ps1 # Windows
scripts/ci-local.sh # Linux/macOS- Application/Protocol — CLI (
commands/), TUI (tui/), MCP Server (mcp/) - Semantic/Knowledge — Registry (
registry/), Search (search/), Knowledge Engine (knowledge_engine/), Vault (vault/), Workflow (workflow/), Skill Runtime (skill_runtime/) - Physical/Storage — SQLite WAL (
registry.db), Tantivy index, Git (git2), filesystem
src/main.rs— CLI only; delegates tocommands/submodules. Hard ceiling: <1000 lines (RF-4).src/lib.rs— Exports all 30+ modules; the binary is a thin wrapper.
| Layer | Modules | Responsibility |
|---|---|---|
| Interaction | commands/, tui/, mcp/ |
Human CLI, ratatui dashboard, 71 MCP tools over stdio |
| Compilation | registry/, search/, vault/, skill_runtime/, workflow/, knowledge_engine/, sync/ |
Compile repos/notes/skills/workflows into queryable knowledge |
| Reliability | SQLite WAL, Tantivy, git2, storage.rs |
Local-first durable storage, indexing, and audit trail |
devbase-core-types (zero internal coupling)
↓
{ devbase-registry, devbase-embedding, devbase-vault-*, devbase-skill-runtime-*, ... }
↓
src/ modules (commands, tui, mcp, registry, search, vault, ...)
devbase-core-typesis the bottom-most crate; it must not depend on any other devbase crate.- Workspace crates in
crates/must not import from the mainsrc/binary/library viacrate::. src/modules aggregate all workspace crates and internal modules;main.rsis the only binary entry point.
All 71 tools implement McpTool in src/mcp/mod.rs:
pub trait McpTool: Send + Sync + Clone {
fn name(&self) -> &'static str;
fn schema(&self) -> serde_json::Value;
async fn invoke(&self, args: serde_json::Value, ctx: &mut AppContext) -> anyhow::Result<serde_json::Value>;
async fn invoke_stream(...) -> anyhow::Result<Vec<ToolStreamEvent>>;
}Tools are registered in two places:
src/mcp/tools/mod.rs— module declarations andpub usesrc/mcp/mod.rs—McpToolEnumvariant +handle_requestrouting
StorageBackend trait (src/storage.rs) abstracts DB path, workspace dir, and index path. AppContext holds a dyn StorageBackend and provides connection() -> rusqlite::Connection. This enables hermetic testing with injected temp paths.
- SQLite WAL mode,
PRAGMA user_versiondrives migrations. src/registry/migrate.rs—CURRENT_SCHEMA_VERSION = 36; sequential migration functions.src/registry/test_helpers.rs—SCHEMA_DDLdefines the in-memory schema for tests.- Critical: any schema change must update both
migrate.rsandtest_helpers.rsSCHEMA_DDL(RF-3). - Migrations must call
backup::auto_backup_before_migration()before altering schema.
- BM25: Tantivy (
src/search/) for full-text over code symbols and vault notes. - Vector: SQLite BLOB + custom
cosine_similarityUDF (src/registry/migrate.rs); zero ML runtime dependency in default build. - Orchestrated in
src/search/hybrid.rs.
YAML-based DAG executor (src/workflow/). 5 step types: skill, subworkflow, parallel, condition, loop. Parsed into workflow-model crate, scheduled topologically, variables interpolated via workflow-interpolate crate.
Markdown notes with YAML frontmatter, wikilinks ([[note]], [[note#heading]], [[note#^block-id]]). Stored in workspace vault/ under PARA folders (00-Inbox, 01-Projects, 02-Areas, 03-Resources, 04-Archives, 99-Meta). BFS graph traversal for backlinks (src/vault/backlinks.rs).
Discovery (skill_runtime/discover.rs) → Install → Execute (executor.rs) → Score (scoring.rs) → Publish (publish.rs). SKILL.md frontmatter parsed by devbase-skill-runtime-parser. Context-aware execution injects DEVBASE_ACTIVE_CONTEXT env var.
src/sync/orchestrator.rs coordinates batch sync operations. sync_protocol.rs and devbase-sync-protocol crate define version-vector directory sync. Syncthing integration lives in devbase-syncthing-client.
These are enforced in CI via scripts/invariant-checks/run-checks.ps1. A violation is a blocking failure. RF-* map to AGENTS.md red-lines G1–G7.
| Rule | Maps | Summary |
|---|---|---|
| RF-1 | G1 | Dependency injection over global state. No new dirs::data_local_dir() / std::env::var_os hard-coding. |
| RF-2 | G2 | Hermetic testing. No std::env::set_var in tests. Use tempfile + injected StorageBackend. Tantivy/SQLite FS tests must be serialized. |
| RF-3 | G3 | SCHEMA_DDL and migrate.rs must stay atomically in sync. |
| RF-4 | G4 | main.rs ≤ 1000 lines; CLI commands live in commands/. |
| RF-5 | G6 | No cyclic crate:: dependencies between modules. |
| RF-6 | G5 | Zero unwrap() / expect() / panic!() in production code (outside #[cfg(test)]). |
| RF-7 | G7 | New modules with >5 internal crate:: refs cannot be extracted to workspace crates. Re-export files (src/symbol_links.rs, etc.) are RE-EXPORT ONLY. |
Additional tiered checks (from run-checks.ps1):
- T11:
mcp/tools/*.rsmust not userusqlite::Connectiondirectly. Known exceptions:repo.rs,brief.rs,impact.rs. - T12:
tui/render/must be pure consumer — no.execute(,.prepare(,registry::save/insert/update/delete.
src/test_utils.rs provides:
temp_db()— in-memory SQLite connection with full schemafixture_repo(id, path)/fixture_repo_with_tags(...)— minimalRepoEntry
- Always use
git2::Signature::now("Test", "test@example.com")instead ofrepo.signature()(CI has no global git identity). - Always
repo.set_head("refs/heads/main")and commit to"refs/heads/main"; default branch varies by platform.
TempDir may return short filenames (TEMP~1) while dunce::canonicalize returns long filenames. Normalize both sides before comparing paths in tests.
Current test count: 616+ passed (a small subset ignored) from cargo test --workspace -- --list.
Local .cargo/config.toml sets RUST_TEST_THREADS = "1". CI uses --test-threads=4. If you encounter flaky SQLite/Tantivy tests locally, reduce threads:
cargo test -- --test-threads=1- Create
src/mcp/tools/<tool_name>.rs - Implement
McpTooltrait - Register in
src/mcp/tools/mod.rs(pub mod+pub use) - Add variant to
McpToolEnuminsrc/mcp/mod.rs - Add routing arm in
src/mcp/mod.rshandle_request - Add unit tests in
src/mcp/tests.rs - Update README Tool matrix,
AGENTS.md, andCLAUDE.mdtool counts
All state-changing tools must be idempotent — use ON CONFLICT ... DO UPDATE or equivalent upsert logic.
- Add migration function in
src/registry/migrate.rs(sequential version block) - Use
ALTER TABLE ... ADD COLUMN(SQLite limitation) - Call
backup::auto_backup_before_migration()at the start - Update
CURRENT_SCHEMA_VERSION - Mirror changes into
src/registry/test_helpers.rsSCHEMA_DDL - Update
AGENTS.md,CLAUDE.md, and.knowledge/index.mdschema version numbers
Conventional Commits: feat(mcp):, fix(registry):, refactor(search):, docs:, perf:, test:.
Pre-commit gate (enforced by CI):
cargo test --all-targets
cargo clippy --all-targets -D warnings
cargo fmt --check| Path | Purpose |
|---|---|
src/main.rs |
CLI entry (thin wrapper) |
src/lib.rs |
Public module exports |
src/commands/ |
CLI subcommand implementations |
src/mcp/mod.rs |
MCP server, McpTool trait, tool routing |
src/mcp/tools/mod.rs |
Tool module registry |
src/registry/migrate.rs |
Schema migrations, CURRENT_SCHEMA_VERSION |
src/registry/test_helpers.rs |
SCHEMA_DDL, in-memory test fixtures |
src/storage.rs |
StorageBackend trait, AppContext |
src/search/hybrid.rs |
BM25 + vector hybrid search orchestration |
src/workflow/executor.rs |
YAML workflow DAG executor |
src/vault/backlinks.rs |
Wikilink BFS graph traversal |
crates/ |
12 workspace sub-crates (zero internal coupling) |
.knowledge/index.md |
Canonical OKF knowledge bundle entry point |
.knowledge/architecture/project-worktree.md |
Complete project worktree for module/file lookup |
scripts/invariant-checks/run-checks.ps1 |
CI architecture invariant checks |
.cargo/config.toml |
Local cargo config (RUST_TEST_THREADS=1) |
rustfmt.toml |
edition = "2024", max_width = 100 |
- Registry DB:
%LOCALAPPDATA%/devbase/registry.db(SQLite, WAL mode) - Workspace:
%LOCALAPPDATA%/devbase/workspace/(vault notes, assets, repo manifests) - Config:
~/.config/devbase/config.toml(credentials, preferences) - Index: Tantivy indices under workspace dir
These paths are never committed; .gitignore covers *.db, .devbase/, .env*, *.local.toml.