Files
zesdex/CLAUDE.md
T

7.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build & Test

# 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 System layout, process modes, data flow, key files
docs/CODEMAPS/backend.md Provider, OAuth, IPC, workflow engine, MCP, review, bg bash
docs/CODEMAPS/frontend.md TUI render pipeline, 16 overlays, toasts, input handling
docs/CODEMAPS/data.md Persistence, SQLite msglog, memory files, settings/config
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 mutationAppStateRest 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.
  • Loggingtracing::warn! to ~/.local/share/zesdex/zesdex.log (not stderr, avoids TUI corruption).
  • Error handlinganyhow::Result and anyhow::bail! throughout. No custom error types.
  • Static strings — MCP tool descriptions use Box::leak + OnceLock cache.
  • Toolstrait Tool { fn name() -> &str, fn run() -> Result<String> }, 28 impls, gated by Harness.
  • Shell safetytool/shell_filter/ blocks credential leaks and destructive git commands.

Company Pipeline (Division Architecture)

  • 5 divisions in src/app/subagent/division.rs: Strategy, Engineering, Quality, Security, Documentation.
  • Pipeline orchestrator in src/app/workflow/company.rs: two modes:
    • run_company_pipeline() — full 5-division pipeline
    • run_company_pipeline_quick() — 3-division (Strategy → Engineering → Quality)
  • Auto-CEO trigger in run_agent_turn() (actions/mod.rs): detects complex requests via is_complex_request() heuristics, auto-delegates to pipeline.
  • Override via /pipeline full|quick|skip sets MiscState::pipeline_override, consumed on next turn.
  • Live division progress in TUI panel (view/workflow.rs): shows division name + current tool via AgentStatus::progress.
  • Auto inline review after each edit: src/app/subagent/auto.rsspawn_quick_review() injects verdict back into LLM conversation.
  • Background subagents (test-gen, arch-review, security-review) fire asynchronously at turn end via TurnEvent::SystemNote.

Commit Convention

Gunakan Conventional Commits untuk semua commit. Format:

<type>(<scope>): <description>

Type & efek ke versi:

Type Bump Kapan pakai
feat minor Fitur baru
fix patch Perbaikan bug
chore patch Maintenance, update deps, dll
docs patch Perubahan dokumentasi/comment
refactor patch Refactor kode tanpa perubahan fungsional
test patch Nambah/ubah test
style patch Formatting, whitespace, lint
perf patch Optimasi performa
ci patch Perubahan CI/CD

Catatan:

  • Semua type menghasilkan release (patch minimal). Tidak ada commit yang "skip release".
  • Tambahkan BREAKING CHANGE: di body commit untuk bump major.
  • Scope opsional, tapi direkomendasikan (misal feat(agent):, fix(ipc):).

Contoh

feat(tool): add batch file delete

chore: bump reqwest to 0.12

refactor(harness): flatten guard pipeline

fix(ipc): reconnect loop on socket timeout

docs: add architecture diagram to README

BREAKING CHANGE: IPC frame header changed from 4-byte to 8-byte length

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:

/// 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