feat: add initial codemap documentation and architecture overview; include backend, data, dependencies, and frontend details
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Build & Test
|
||||
|
||||
```bash
|
||||
# Build (debug)
|
||||
cargo build
|
||||
|
||||
# Release build
|
||||
cargo build --release
|
||||
|
||||
# Run all tests
|
||||
cargo test
|
||||
|
||||
# Run a single test
|
||||
cargo test test_name
|
||||
|
||||
# Lint
|
||||
cargo clippy
|
||||
|
||||
# Lint with warnings-as-errors
|
||||
cargo clippy -- -D warnings
|
||||
```
|
||||
|
||||
Test modules are located inline in production files (not a separate `tests/` dir):
|
||||
- `src/app/harness.rs` — guard/verdict parsing tests
|
||||
- `src/app/runtime/stream/mod.rs` — SSE parser tests
|
||||
- `src/model/memory.rs` — memory CRUD + slugify tests
|
||||
- `src/model/editlog.rs` — edit log append/reload tests
|
||||
- `src/tool/fs/helpers.rs` — tool argument extraction tests
|
||||
|
||||
Tests use `#[cfg(test)] mod tests` blocks. There are 37 unit tests total.
|
||||
|
||||
Tracing output goes to `~/.local/share/zesdex/zesdex.log`. Set `RUST_LOG=debug` for verbose logging.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
Zesdex is an autonomous AI coding agent with a TUI — an OpenAI/Anthropic-compatible LLM client wrapped in a tool-use harness with 28 built-in tools.
|
||||
|
||||
Detailed architecture documentation is in `docs/CODEMAPS/`:
|
||||
|
||||
| File | Covers |
|
||||
|------|--------|
|
||||
| [`docs/CODEMAPS/architecture.md`](docs/CODEMAPS/architecture.md) | System layout, process modes, data flow, key files |
|
||||
| [`docs/CODEMAPS/backend.md`](docs/CODEMAPS/backend.md) | Provider, OAuth, IPC, workflow engine, MCP, review, bg bash |
|
||||
| [`docs/CODEMAPS/frontend.md`](docs/CODEMAPS/frontend.md) | TUI render pipeline, 16 overlays, toasts, input handling |
|
||||
| [`docs/CODEMAPS/data.md`](docs/CODEMAPS/data.md) | Persistence, SQLite msglog, memory files, settings/config |
|
||||
| [`docs/CODEMAPS/dependencies.md`](docs/CODEMAPS/dependencies.md) | 23 Rust crates, 5 external services |
|
||||
|
||||
### Entry Points
|
||||
|
||||
`src/main.rs` — three modes:
|
||||
- **Single-process** (default): TUI + agent loop in one process
|
||||
- **Daemon** (`--daemon`): background Unix socket server, handles LLM calls
|
||||
- **Attach** (`--attach <id>`): TUI-only client that connects to a daemon
|
||||
|
||||
### Core Flow
|
||||
|
||||
```
|
||||
Controller (key input → Action) → Event Loop → LLM stream → Tool execution → State mutation → TUI render
|
||||
│ │ │
|
||||
│ src/controller/input.rs │ src/app/runtime/actions/ │ src/tool/
|
||||
└── maps keys to Action enum │── dispatches Action::* └── 28 tool impls
|
||||
│ matching on Action variant
|
||||
│── applies state mutations
|
||||
```
|
||||
|
||||
### Key Patterns
|
||||
|
||||
- **State mutation** — `AppStateRest` is mutable in-place from `actions/mod.rs` and `controller/input.rs`. No generic update function.
|
||||
- **No DI** — modules call `Settings::load()`, `AppConfig::load()`, `all_tools()` directly.
|
||||
- **Logging** — `tracing::warn!` to `~/.local/share/zesdex/zesdex.log` (not stderr, avoids TUI corruption).
|
||||
- **Error handling** — `anyhow::Result` and `anyhow::bail!` throughout. No custom error types.
|
||||
- **Static strings** — MCP tool descriptions use `Box::leak` + `OnceLock` cache.
|
||||
- **Tools** — `trait Tool { fn name() -> &str, fn run() -> Result<String> }`, 28 impls, gated by `Harness`.
|
||||
- **Shell safety** — `tool/shell_filter/` blocks credential leaks and destructive git commands.
|
||||
|
||||
## Code Documentation
|
||||
|
||||
Every function, struct, enum, trait, module, and significant code block must have a doc comment (`///` or `//!`) that explains:
|
||||
|
||||
- **What** the function/module does (purpose, not how)
|
||||
- **Flow** — a brief ASCII or prose description of the code flow / data flow above each non-trivial function
|
||||
- **Why** — non-obvious decisions, edge cases, invariants
|
||||
- **Return** — what the caller gets back, especially for `Result` types
|
||||
|
||||
Examples:
|
||||
|
||||
```rust
|
||||
/// Parse an SSE data chunk into one or more StreamEvents.
|
||||
///
|
||||
/// Flow: buffer → split on '\n' → flush on blank line → JSON parse → match event type
|
||||
/// → return Token / ToolCallDelta / Usage / Done.
|
||||
///
|
||||
/// Edge case: chunk may split mid-line; remaining bytes stay in buffer
|
||||
/// for the next feed() call.
|
||||
fn feed(&mut self, chunk: &str) -> Vec<StreamEvent> { ... }
|
||||
|
||||
/// The single source-of-truth state struct for the entire application.
|
||||
///
|
||||
/// Mutated in-place from two locations: actions/mod.rs (apply_action)
|
||||
/// and controller/input.rs (key event handlers). Read-only from
|
||||
/// every other module.
|
||||
struct AppStateRest { ... }
|
||||
```
|
||||
|
||||
Rules:
|
||||
- Every `pub fn` needs a doc comment
|
||||
- Every `pub struct` / `pub enum` / `pub trait` needs a doc comment
|
||||
- Non-trivial private functions (≥10 lines) need a doc comment
|
||||
- Write the comment above the code it documents (not inline in the body)
|
||||
- Update comments when code behavior changes — stale docs are worse than no docs
|
||||
Reference in New Issue
Block a user