Skip to content

Commit 08106b0

Browse files
committed
docs: add hierarchical AGENTS.md knowledge base
Root knowledge base plus complexity-scored subdirectory files for the rust/ workspace, its five highest-mass crates (runtime, rusty-claude-cli, api, tools, commands, plugins), and the src/ Python porting workspace. Generated via init-deep: 13 parallel explore agents, LSP/ast-grep code map, centrality-scored placement. Snapshot in .omo/init-deep.json (local).
1 parent b71afdd commit 08106b0

9 files changed

Lines changed: 509 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# PROJECT KNOWLEDGE BASE
2+
3+
**Generated:** 2026-08-16
4+
**Commit:** b71afdd
5+
**Branch:** main
6+
7+
## OVERVIEW
8+
Claw Code: public Rust implementation of the `claw` CLI agent harness (Claude-Code-style). Canonical code lives in `rust/`; the repo is an agent-managed exhibit (harnesses plan/execute/verify per README), not a hand-operated product. `src/` is a companion Python porting/parity workspace, not production code.
9+
10+
## STRUCTURE
11+
```
12+
claw-code/
13+
├── rust/ # canonical Cargo workspace: 11 crates, `claw` binary
14+
├── src/ # Python porting workspace + reference_data/ parity snapshots
15+
├── tests/ # Python unittest validation of src/ + scripts/ (stdlib unittest)
16+
├── docs/ # g0XX gate verification maps + topic docs
17+
├── scripts/ # fmt.sh, dogfood-build.sh, roadmap/board helpers
18+
├── assets/ # README images only
19+
└── install.sh, Containerfile, docker-compose.yml
20+
```
21+
22+
## WHERE TO LOOK
23+
| Task | Location | Notes |
24+
|------|----------|-------|
25+
| CLI subcommands | rust/crates/rusty-claude-cli/src/main.rs | hand-rolled parser; CliAction enum ~L1162; dispatch in run() L995-1158 |
26+
| Sessions/permissions/MCP | rust/crates/runtime/src/ | 47 flat modules |
27+
| Provider clients | rust/crates/api/src/providers/ | anthropic.rs + openai_compat.rs |
28+
| Tool definitions | rust/crates/tools/src/lib.rs | 55-tool spec table L484-1348 |
29+
| Slash commands | rust/crates/commands/src/lib.rs | 120+ spec table L60-1047 |
30+
| Plugins/hooks | rust/crates/plugins/src/ | manifest = .claude-plugin/plugin.json |
31+
| Lean agent harness | rust/crates/claw-analog/src/lib.rs | lib+bin; tool loop over api+runtime |
32+
| RAG HTTP service | rust/crates/claw-rag-service/src/ | axum; SQLite + optional Qdrant |
33+
| Test mock server | rust/crates/mock-anthropic-service/ | SCENARIO_PREFIX scripted responses |
34+
| Python porting CLI | src/main.py | argparse: manifest, parity-audit, graphs |
35+
| Parity reference DB | src/reference_data/subsystems/ | 29 JSON snapshots of TS archive |
36+
37+
## CODE MAP
38+
| Symbol | Type | Location | Refs | Role |
39+
|--------|------|----------|------|------|
40+
| Session | struct | runtime/src/session.rs:117 | 229 | session persistence/lifecycle |
41+
| ConfigLoader | struct | runtime/src/config.rs:409 | 83 | config schema/load |
42+
| PluginManager | struct | plugins/src/lib.rs | 48 | plugin install/registry |
43+
| PermissionEnforcer | struct | runtime/src/permission_enforcer.rs:27 | 35 | pre-dispatch permission gate |
44+
| ConversationRuntime | struct | runtime/src/conversation.rs:130 | 32 | conversation loop driver |
45+
| McpServerManager | struct | runtime/src/mcp_stdio.rs:488 | 30 | MCP JSON-RPC processes |
46+
| HookRunner | struct | runtime/src/hooks.rs:155 | 25 | shell hook execution |
47+
| CliAction | enum | rusty-claude-cli/src/main.rs:1162 || 25 subcommand variants |
48+
| mvp_tool_specs | fn | tools/src/lib.rs:484 || static 55-tool table |
49+
| SLASH_COMMAND_SPECS | const | commands/src/lib.rs:60 || 120+ slash commands |
50+
51+
(Refs = rg count across rust/crates; rust-analyzer references timed out during mapping.)
52+
53+
## CONVENTIONS
54+
- `unsafe_code = "forbid"` workspace-wide; every crate opts in via `[lints] workspace = true`; clippy all=warn, pedantic=allow
55+
- Edition 2021, resolver 2, publish=false; no rust-toolchain pin (CI floats stable); no rustfmt.toml/clippy.toml — stock defaults
56+
- Giant flat files by design (main.rs 19.8k, tools/lib.rs 10.9k, commands/lib.rs 7.2k): organization is positional — types → spec table → dispatch → handlers → tests at EOF
57+
- Dual output paths everywhere: `render_x` + `render_x_json`; JSON errors to **stdout**, text errors to **stderr**
58+
- Tests: inline `#[cfg(test)] mod tests` primary; integration tests spawn `CARGO_BIN_EXE_claw` subprocess against mock-anthropic-service; tempfile everywhere; env-mutating tests serialize via env_lock/test_env_lock
59+
- Comments carry issue numbers (#824, #146); gate tests named by roadmap gate (g004_conformance.rs)
60+
- Python side: stdlib only, `python -m unittest`; src/ mixes camelCase (QueryEngine.py) and snake_case filenames
61+
62+
## ANTI-PATTERNS (THIS PROJECT)
63+
- NEVER `cargo install claw-code` — crates.io stub is deprecated and installs `claw-code-deprecated.exe`; build from source
64+
- Forbidden doc strings (CI-enforced by .github/scripts/check_doc_source_of_truth.py): old org links `github.com/Yeachan-Heo/claw-code`, `github.com/code-yeongyu/claw-code`, `discord.gg/6ztZB9jvWq`, `assets/clawd-hero.jpeg`
65+
- Deprecated config keys: `permissionMode``permissions.defaultMode`; `enabledPlugins``plugins.enabled`; env `RUSTY_CLAUDE_PERMISSION_MODE` is dead
66+
- Direct push to main is policy-blocked (`main_push_forbidden` approval scope)
67+
- Automation lanes must not merge/close remote PRs/issues (docs/anti-slop-triage.md)
68+
- `claw init` must not scaffold `dontAsk` permission mode (regression-pinned in output_format_contract.rs)
69+
- File-level `#![allow(dead_code)]` blocks (main.rs, session_control.rs) are tolerated legacy — do not extend the pattern
70+
71+
## UNIQUE STYLES
72+
- Dogfood build: scripts/dogfood-build.sh injects GIT_SHA; `claw version` provenance must equal HEAD
73+
- Mock parity: rust/mock_parity_scenarios.json drives CLI subprocess vs MockAnthropicService
74+
- Dogfooding uses `CLAW_CONFIG_HOME=$(mktemp -d)` for config isolation
75+
- Env contracts: GIT_SHA (build), CLAW_CONFIG_HOME (config dir), OLLAMA_HOST (provider override), `*_API_KEY`/`*_BASE_URL` per provider
76+
77+
## COMMANDS
78+
```bash
79+
scripts/fmt.sh --check # fmt check (apply: scripts/fmt.sh)
80+
cd rust && cargo clippy --workspace --all-targets -- -D warnings
81+
cd rust && cargo test --workspace
82+
cd rust && cargo build -p rusty-claude-cli # binary: rust/target/debug/claw
83+
python -m unittest discover -s tests # Python suite
84+
python .github/scripts/check_doc_source_of_truth.py && scripts/roadmap-check-ids.sh # docs/roadmap CI
85+
```
86+
87+
## NOTES
88+
- `claw` binary comes from crate `rusty-claude-cli` (package/bin name mismatch)
89+
- rust-ci.yml triggers only on rust/**, docs/**, listed meta file changes (path filters)
90+
- CI clippy job runs without `-D warnings` — weaker than the documented gate; known pre-existing failures recorded in docs/g002/g003 maps
91+
- `claw acp` is a status stub, not a real ACP server
92+
- rust/ has committed harness dotdirs (.clawd-agents/, .omc/, .sandbox-home/) — intentional

rust/AGENTS.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# AGENTS.md — rust/ workspace
2+
3+
## OVERVIEW
4+
5+
Virtual Cargo workspace (resolver 2, edition 2021) housing 11 crates that compose the `claw` CLI and supporting services.
6+
7+
## STRUCTURE
8+
9+
| Crate | Kind | Purpose |
10+
|---|---|---|
11+
| `rusty-claude-cli` | bin (`claw`) | Main CLI binary. Package name ≠ binary name. |
12+
| `claw-analog` | lib+bin | Alternate entry point; depends on api + runtime only. |
13+
| `claw-rag-service` | bin | RAG service. Only crate with `[features]` (`qdrant-index`). |
14+
| `mock-anthropic-service` | lib+bin | Mock Anthropic Messages API. Prints `MOCK_ANTHROPIC_BASE_URL`. Dev-dep for CLI and analog tests. |
15+
| `runtime` | lib | Core: sessions, permissions, MCP, conversation loop. ~47 modules. |
16+
| `api` | lib | Provider clients: Anthropic, OpenAI-compat (xAI, OpenAI, DashScope, Ollama). |
17+
| `tools` | lib | 55-tool surface area. Depends on `commands` (not vice versa). |
18+
| `commands` | lib | 120+ slash commands. |
19+
| `plugins` | lib | Plugin manifest and lifecycle. |
20+
| `telemetry` | lib | Request identity + analytics sinks. |
21+
| `compat-harness` | lib | Extracts upstream TS claude-code manifest/commands/tools for parity comparison. |
22+
23+
Dependency direction: `rusty-claude-cli` → tools/commands/runtime/api/plugins. `tools``commands`.
24+
25+
## WHERE TO LOOK
26+
27+
- **Parity testing**: `mock_parity_scenarios.json` at workspace root, loaded via `CARGO_MANIFEST_DIR/../../mock_parity_scenarios.json`. Scripts in `scripts/` (`run_mock_parity_harness.sh`, `run_mock_parity_diff.py`).
28+
- **CI**: `.github/workflows/rust-ci.yml` (fmt, clippy, test, docs, Windows smoke) and `release.yml` (v* tag builds for linux-x64/macos-arm64/windows-x64).
29+
- **Committed test fixtures**: `.clawd-agents/`, `.omc/`, `.sandbox-home/` are checked-in harness dotdirs.
30+
- **Docs**: `PARITY.md`, `TUI-ENHANCEMENT-PLAN.md`, `README.md` alongside this file.
31+
32+
## CONVENTIONS
33+
34+
Workspace lints (all crates opt in via `[lints] workspace = true`):
35+
- `unsafe_code` = **forbid**. No exceptions.
36+
- clippy `all` = warn, `pedantic` = allow. Explicitly allowed: `module_name_repetitions`, `missing_panics_doc`, `missing_errors_doc`.
37+
38+
No `rustfmt.toml` or `clippy.toml`. Stock defaults only.
39+
40+
TUI rule: formatting fns take `&mut impl Write`, never stdout directly. Never mix raw ANSI escapes with crossterm.
41+
42+
Library crates don't carry the `claw-` prefix. Binary crates do (except legacy `rusty-claude-cli`).
43+
44+
Workspace version is `0.1.3`, `publish = false`, MIT license.
45+
46+
No rust-toolchain file, no MSRV. CI pins `dtolnay/rust-toolchain@stable`.
47+
48+
## ANTI-PATTERNS
49+
50+
- Don't run `cargo fmt --manifest-path rust/Cargo.toml` from the repo root. Use `../scripts/fmt.sh` instead.
51+
- Don't add `unsafe` code. The lint is set to `forbid`, not `deny`. You can't `#[allow]` it.
52+
- Don't create dependencies from `commands``tools`. The arrow goes `tools``commands`.
53+
- Don't write TUI output directly to stdout or use raw ANSI escape sequences.
54+
- Don't add features to crates other than `claw-rag-service` without good reason; the workspace is feature-lean by design.
55+
56+
## COMMANDS
57+
58+
All run from `rust/`:
59+
60+
```sh
61+
# Format (check only)
62+
../scripts/fmt.sh --check
63+
64+
# Format (apply)
65+
../scripts/fmt.sh
66+
67+
# Lint (strict, matches what you should pass before pushing)
68+
cargo clippy --workspace --all-targets -- -D warnings
69+
70+
# Test
71+
cargo test --workspace
72+
73+
# Build specific binary
74+
cargo build -p rusty-claude-cli
75+
cargo build -p claw-analog
76+
cargo build -p claw-rag-service
77+
cargo build -p mock-anthropic-service
78+
```
79+
80+
Note: CI clippy runs without `-D warnings`, so the local check above is stricter than the gate.

rust/crates/api/AGENTS.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# AGENTS.md — api crate
2+
3+
## OVERVIEW
4+
5+
LLM provider client layer: dispatches Anthropic, xAI, OpenAI, DashScope, and Ollama behind two wire protocols (Anthropic Messages native, OpenAI Chat Completions compat).
6+
7+
## WHERE TO LOOK
8+
9+
| Module | What lives here |
10+
|---|---|
11+
| `client.rs` | `ProviderClient` enum (facade). `from_model(model)` resolves alias, picks `ProviderKind`, handles OLLAMA_HOST and DashScope qwen-prefix cases. `send_message`/`stream_message`. |
12+
| `providers/mod.rs` | `Provider` trait (generic, dead_code-allowed, not used for dispatch). `ProviderKind`, `resolve_model_alias`, `ProviderMetadata` (auth_env, base_url_env, default_base_url), `max_tokens_for_model[_with_override]`, capability/diagnostic reporting, `preflight_message_request` validation. |
13+
| `providers/anthropic.rs` | `AnthropicClient` (re-exported as `ApiClient` at crate root). Dual auth: API key env vs saved OAuth (`AuthSource`, `OAuthTokenSet`, token expiry checks). Base-url resolution. SSE `MessageStream`. Prompt-cache hooks. |
14+
| `providers/openai_compat.rs` | `OpenAiCompatClient` parameterized by `OpenAiCompatConfig` (presets: `xai()`, `openai()`, `dashscope()`, `OLLAMA_CONFIG`). Heavy translation layer: `build_chat_completion_request`, `translate_message`, `sanitize_tool_message_pairing`, `flatten_tool_result_content`. Model-quirk predicates (`is_reasoning_model`, etc.). Body-size estimation/guards. |
15+
| `types.rs` | Provider-agnostic wire types: `MessageRequest`, `InputMessage`, `ContentBlock`, `StreamEvent`, `Usage`, `ToolDefinition`, `ToolChoice`. |
16+
| `sse.rs` | `SseParser`, `parse_frame`. |
17+
| `http_client.rs` | reqwest builders, `ProxyConfig` from env proxy vars, `TimeoutConfig`. |
18+
| `error.rs` | `ApiError`. |
19+
| `prompt_cache.rs` | `PromptCache` + `Stats` (Anthropic-only). |
20+
| `lib.rs` | Curated `pub use` lists define the public surface. Also re-exports sibling telemetry crate items. |
21+
22+
## CONVENTIONS
23+
24+
- Module-private by default. `lib.rs` `pub use` lists are the sole public API surface.
25+
- `#[must_use]` on pure constructors.
26+
- Provider config follows an env-var pair pattern: `*_API_KEY` / `*_BASE_URL`, recorded in `ProviderMetadata`.
27+
- Leaf files carry targeted `#![allow(clippy::cast_possible_truncation)]` where needed.
28+
- Dispatch goes through the `ProviderClient` enum, not trait objects. The `Provider` trait exists but is dead-code-allowed.
29+
- Streams unify into `MessageStream` with `next_event()` yielding `StreamEvent`.
30+
31+
## TESTS
32+
33+
- Four integration test files under `tests/`:
34+
- `client_integration` — core client behavior
35+
- `openai_compat_integration` — OpenAI-compat translation paths
36+
- `provider_client_integration``ProviderClient` dispatch
37+
- `proxy_integration` — proxy config
38+
- Tests that touch env vars serialize through a shared `env_lock()` mutex. Don't skip this or you'll get flaky parallel failures.
39+
- `benches/request_building.rs` is the workspace's only Criterion bench. Targets hot translation functions. This file bulk-opts out of strict lints.

rust/crates/commands/AGENTS.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# commands crate
2+
3+
## OVERVIEW
4+
5+
REPL slash-command surface: parsing, spec registry, help rendering, and a handful of in-crate handlers. Single flat `src/lib.rs` (~7k lines). Deps: `plugins`, `runtime`, `serde_json` only. Note: `tools` depends on `commands`, not the reverse.
6+
7+
## lib.rs MAP
8+
9+
| Lines | Landmark |
10+
|-------------|----------|
11+
| 16–58 | Registry types: `CommandManifestEntry`, `CommandSource` (Builtin / InternalOnly / FeatureGated), `CommandRegistry`, `SlashCommandSpec`, `SkillSlashDispatch` |
12+
| 60–1047 | `SLASH_COMMAND_SPECS` static table. 120+ entries (help, status, sandbox, compact, model, permissions, clear, cost, resume, config, mcp, memory, init, diff, version, bughunter, commit, pr, issue, ultraplan, teleport, debug-tool-call, export, session, plugin, agents, skills, doctor, plan, review, tasks, theme, vim, voice, chat, ...) |
13+
| 1048–1303 | `SlashCommand` enum (~65 variants + `Unknown(String)`), `SlashCommandParseError`, `SlashCommand::parse` (L1218) |
14+
| 1515–1899 | Per-command arg parsers: `parse_mcp_command`, `parse_plugin_command`, `parse_session_command`, etc. |
15+
| 1900–2108 | Help/suggestion rendering: `render_slash_command_help*`, `suggest_slash_commands` (Levenshtein), category grouping |
16+
| 2109–2682 | Result types + handlers: `handle_plugins_slash_command`, `handle_agents/mcp/skills_slash_command(_json)`, skill dispatch/resolve |
17+
| 3160–5293 | Reporting layer: paired text and `_json` renderers for plugins/agents/skills/mcp reports, skill install/uninstall/create-agent logic, frontmatter parsing, root discovery |
18+
| 5294 | `handle_slash_command(input, session, compaction)` top dispatch. Only Compact and Help execute here; all other variants return to the REPL caller |
19+
| 5403–7183 | `mod tests` (~1780 lines) |
20+
21+
## ADDING A SLASH COMMAND
22+
23+
1. **Spec.** Add a `SlashCommandSpec` entry to `SLASH_COMMAND_SPECS`. Set `resume_supported` honestly.
24+
2. **Enum + parse.** Add a variant to `SlashCommand`. Wire a match arm in `SlashCommand::parse`. If the command takes arguments, add a dedicated `parse_*_command` function in the arg-parser block.
25+
3. **Handler.** Decide where execution lives:
26+
- In-crate (like Compact/Help): handle it inside `handle_slash_command`.
27+
- Returned to caller: just return the parsed variant. The REPL layer executes it.
28+
4. **Help.** Make sure the spec's `summary` and `argument_hint` are set so help rendering and suggestion matching pick it up automatically.
29+
5. **Tests.** Cover parsing (valid input, bad input, edge cases) in the inline `mod tests`.
30+
31+
## CONVENTIONS
32+
33+
- **Dual renderers.** Every report surface has a text variant and a `_json` variant: `handle_x` / `handle_x_json`, `render_*` / `render_*_json`. Keep them in sync.
34+
- **Error style.** Handlers return `std::io::Result`. Parse failures use `SlashCommandParseError`.
35+
- **Manifest registries.** Pattern is `entries: Vec<_Entry>` backed by the static spec table.
36+
- **Dependency direction.** This crate knows nothing about `tools`. Don't import it.
37+
- **No execution here.** Almost all commands pass through as parsed data. Only Compact and Help run inside this crate. Respect that boundary.

rust/crates/plugins/AGENTS.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# AGENTS.md — plugins crate
2+
3+
## OVERVIEW
4+
5+
Plugin subsystem: how third-party, builtin, and bundled tools/commands/hooks enter the runtime.
6+
7+
## WHERE TO LOOK
8+
9+
- `src/lib.rs` (~3,863 lines): the bulk of the crate. Manifest parsing (`.claude-plugin/plugin.json`), installed-plugin registry, lifecycle model, permission model, install/update management.
10+
- `src/hooks.rs`: hook event model (`HookEvent`, `HookRunResult`) and `HookRunner` for shell-hook execution. Re-exported from `lib.rs`. **Caution:** the runtime crate has its own `hooks.rs` with a separate `HookRunner` (execution + abort-signal side, around L155). Know which layer you need before editing.
11+
- `src/test_isolation.rs`: test isolation helpers.
12+
- `bundled/`: example plugin fixtures. `example-bundled/` and `sample-hooks/` each contain `.claude-plugin/plugin.json` plus `pre.sh`/`post.sh` shell hooks. Treat these as the reference shape when authoring a new plugin.
13+
14+
## CONVENTIONS
15+
16+
**Key public types** (all in `src/lib.rs` unless noted):
17+
18+
- Kinds/definitions: `PluginKind`, `PluginDefinition`, `BuiltinPlugin`, `BundledPlugin`, `ExternalPlugin`.
19+
- Manifests: `PluginManifest`, `PluginToolManifest`, `PluginToolDefinition`, `PluginToolPermission`, `PluginCommandManifest`.
20+
- Hooks: `PluginHooks`, `HookEvent`, `HookRunResult` (from `hooks.rs`).
21+
- Lifecycle/permissions: `PluginLifecycle`, `PluginPermission`.
22+
- Registry: `InstalledPluginRecord`, `InstalledPluginRegistry`, `RegisteredPlugin`, `PluginRegistry` (+ `Report`, `Summary`, `LoadFailure`).
23+
- Management: `PluginManager` (+ `Config`), `InstallOutcome`, `UpdateOutcome`.
24+
- Trait: `Plugin`.
25+
- Errors: `PluginError`.
26+
- Entry points: `builtin_plugins()`, `load_plugin_from_directory()`.
27+
28+
**Lifecycle spans two crates.** Manifest parsing and registry live here. Health checks, degraded-mode, and `PluginState` live in `runtime/src/plugin_lifecycle.rs`. Changes to plugin lifecycle logic often touch both.
29+
30+
**Plugin shape.** A plugin directory contains `.claude-plugin/plugin.json` at minimum. Shell hooks (`pre.sh`, `post.sh`) sit alongside. See `bundled/` for working examples.
31+
32+
**Consumers.** `PluginManager` has ~48 references across the workspace. CLI wires plugins via `RuntimePluginStateBuildOutput` in `rusty-claude-cli`. The tools crate exposes plugin tools through `GlobalToolRegistry`.
33+
34+
## NOTES
35+
36+
- Don't confuse the two `HookRunner` implementations. This crate's version handles the event model. The runtime crate's version handles execution and abort signals.
37+
- `lib.rs` is large. Most searches for plugin behavior start and end there.
38+
- Bundled plugin fixtures under `bundled/` are used in tests. Breaking their structure breaks CI.
39+
- Permission model is enforced at install time and checked at runtime. Both paths matter when modifying `PluginPermission`.

0 commit comments

Comments
 (0)