cargo build # debug
cargo build --release # release (LTO, strip)The binary lands in target/{debug,release}/microcode.
cargo run -- chat
cargo run -- run "list rust files"cargo run is a bit slow because it pre-builds; for inner-loop hacking you may prefer cargo install --path . --debug once and use microcode directly.
cargo test # unit + integration
cargo test --no-fail-fast
cargo clippy -- -D warnings
cargo fmt --checkThe test suite covers:
- Each tool's happy path and the most common error case (
tests/tools_test.rs) - Permission policy: allowlist, denylist, yolo, non-interactive (
tests/permission_test.rs) - End-to-end agent loop with a mock provider (
tests/agent_test.rs)
We deliberately do not exercise the real Anthropic API in CI. Provider tests use the MockProvider in src/provider/mock.rs. If you want to smoke-test against the real API, run cargo run -- run "say hello" with ANTHROPIC_API_KEY set.
src/
├── main.rs # CLI entry
├── lib.rs # Re-exports + module declarations
├── cli.rs # clap argument tree
├── config.rs # Config loading + merging
├── error.rs # Error type
├── logging.rs # tracing init
├── permission.rs # Permission policy + interactive prompt
├── verifier.rs # cargo check hook
├── journal.rs # Per-session markdown log
├── run.rs # Top-level command runners (chat/run/init/config)
├── ui/mod.rs # Terminal output helpers
├── agent/
│ ├── mod.rs # The loop
│ └── system_prompt.rs # Prompt construction
├── provider/
│ ├── mod.rs # Provider trait + Message/ContentBlock types
│ ├── anthropic.rs # Anthropic Messages API client
│ └── mock.rs # Test-only canned-response provider
└── tools/
├── mod.rs # Tool trait, registry, dispatch
├── read.rs
├── write.rs
├── edit.rs
├── bash.rs
├── ls.rs
├── glob.rs
└── grep.rs
tests/
├── tools_test.rs
├── permission_test.rs
└── agent_test.rs
docs/
├── architecture.md
├── design-journal.md
└── tools.md
A tool is ~50 lines. Implement the Tool trait in a new file under src/tools/, register it in ToolRegistry::defaults(), and add a test in tests/tools_test.rs. See src/tools/read.rs as a template.
The contract:
name()is the wire identifier the model uses.description()is part of the prompt — short, action-oriented.input_schema()is JSON Schema. Anthropic's tool-use API enforces it.side_effect()decides whether the permission policy is consulted:Pure/Readskip the prompt,Mutatingdoes not.render_call()is what's shown to the user in the permission prompt and in the journal — make it scannable.
If your tool modifies files in a way that should trigger cargo check, extend CargoVerifier::should_run_for in src/verifier.rs.
Implement the Provider trait in a new file under src/provider/. The trait is async and small:
#[async_trait]
pub trait Provider: Send + Sync {
async fn complete(&self, req: CompletionRequest<'_>)
-> Result<CompletionResponse>;
}You'll need to translate to/from the wire format (see src/provider/anthropic.rs for shape — Anthropic uses tool_use/tool_result content blocks; OpenAI uses a different shape that you'd need to adapt).
For now run::build_agent hardcodes Anthropic. Generalising that to a provider = "..." config field is on the roadmap.
cargo fmtbefore pushing.cargo clippy --all-targets -- -D warningsshould be clean.- Don't introduce a dependency without a comment in the PR explaining why an existing one doesn't suffice.
- Keep comments minimal — name things well instead. The exception is
WHYfor non-obvious choices.
- Bump
versioninCargo.toml. - Update
CHANGELOG.md(which doesn't exist yet — TODO). - Tag:
git tag -s vX.Y.Z -m "vX.Y.Z"; push tags. - CI will build artifacts (TODO — no CI yet).
- Streaming responses (SSE parsing).
/costshowing dollar estimate./forkto branch the conversation cheaply.- OpenAI provider.
- MCP tool integration.
- Optional
cargo testhook (separate fromcargo check). - CHANGELOG + GitHub Actions release workflow.