返回 CodeWhale
ARCHITECTURE.md
根目录 / docs / ARCHITECTURE.md
1 # Codewhale Architecture
2
3 This document provides an overview of the codewhale architecture for developers and contributors.
4
5 Current boundary note (read the workspace version from `Cargo.toml`; this
6 boundary has held since v0.9.1):
7 - `crates/tui` is still the live end-user runtime for the TUI, runtime API, task manager, and tool execution loop.
8 - Other workspace crates are being split out incrementally, but they are not yet the sole runtime source of truth.
9 - The LSP subsystem (`crates/tui/src/lsp/`) is fully wired into the engine's
10 post-tool-execution path (`core/engine/lsp_hooks.rs`), providing inline
11 diagnostics after `File` write, edit, and patch actions.
12 - The swarm agent system was removed in v0.8.5. The active sub-agent surface is
13 the single `agent` tool; persistent RLM sessions are available through the
14 deferred `rlm` action family.
15 No model-visible swarm tool remains in the active codebase.
16
17 ## High-Level Overview
18
19 ```
20 ┌─────────────────────────────────────────────────────────────────┐
21 │ User Interface │
22 │ ┌─────────────────┐ ┌─────────────────┐ ┌────────────────┐ │
23 │ │ TUI (ratatui) │ │ One-shot Mode │ │ Config/CLI │ │
24 │ └────────┬────────┘ └────────┬────────┘ └────────┬───────┘ │
25 └───────────┼─────────────────────┼────────────────────┼──────────┘
26 │ │ │
27 ▼ ▼ ▼
28 ┌─────────────────────────────────────────────────────────────────┐
29 │ Core Engine │
30 │ ┌─────────────────────────────────────────────────────────┐ │
31 │ │ Agent Loop (core/engine.rs) │ │
32 │ │ ┌─────────┐ ┌─────────────┐ ┌──────────────────────┐ │ │
33 │ │ │ Session │ │ Turn Mgmt │ │ Tool Orchestration │ │ │
34 │ │ └─────────┘ └─────────────┘ └──────────────────────┘ │ │
35 │ └─────────────────────────────────────────────────────────┘ │
36 └─────────────────────────────────────────────────────────────────┘
37 │ │ │
38 ▼ ▼ ▼
39 ┌─────────────────────────────────────────────────────────────────┐
40 │ Tool & Extension Layer │
41 │ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌────────────────┐ │
42 │ │ Tools │ │ Skills │ │ Hooks │ │ MCP Servers │ │
43 │ │ (shell, │ │ (plugins)│ │ (pre/ │ │ (external) │ │
44 │ │ file) │ │ │ │ post) │ │ │ │
45 │ └──────────┘ └──────────┘ └─────────┘ └────────────────┘ │
46 └─────────────────────────────────────────────────────────────────┘
47 │ │ │
48 ▼ ▼ ▼
49 ┌─────────────────────────────────────────────────────────────────┐
50 │ Runtime API + Task Management │
51 │ ┌─────────────────────────────┐ ┌──────────────────────────┐ │
52 │ │ HTTP/SSE Runtime API │ │ Persistent Task Manager │ │
53 │ │ (runtime_api.rs) │ │ (task_manager.rs) │ │
54 │ └─────────────────────────────┘ └──────────────────────────┘ │
55 └─────────────────────────────────────────────────────────────────┘
56 │ │
57 ▼ ▼
58 ┌─────────────────────────────────────────────────────────────────┐
59 │ LLM Layer │
60 │ ┌──────────────────────────────────────────────────────────┐ │
61 │ │ LLM Client Abstraction (llm_client.rs) │ │
62 │ │ ┌─────────────────┐ ┌─────────────────────────────┐ │ │
63 │ │ │ DeepSeek Client │ │ Compatible Client (DeepSeek)│ │ │
64 │ │ │ (client.rs) │ │ (client.rs) │ │ │
65 │ │ └─────────────────┘ └─────────────────────────────┘ │ │
66 │ └──────────────────────────────────────────────────────────┘ │
67 └─────────────────────────────────────────────────────────────────┘
68 ```
69
70 ## Module Organization
71
72 ### Entry Point
73
74 - **`main.rs`** - CLI argument parsing (clap), configuration loading, entry point routing
75
76 ### Core Components
77
78 - **`core/`** - Main engine components
79 - `engine.rs` - Engine state, operation handling, message processing
80 - `engine/turn_loop.rs` - Streaming turn loop and tool execution orchestration
81 - `session.rs` - Session state management
82 - `turn.rs` - Turn-based conversation handling
83 - `events.rs` - Event system for UI updates
84 - `ops.rs` - Core operations
85
86 ### Configuration
87
88 - **`config.rs`** - Configuration loading, profiles, environment variables
89 - **`settings.rs`** - Runtime settings management
90
91 ### Workspace Crates
92
93 - **`crates/tools`** - Shared tool invocation primitives, including tool result/error/capability types used by the TUI runtime.
94 - **`crates/agent`** - Model/provider registry (ModelRegistry) for resolving model IDs to provider endpoints.
95 - **`crates/app-server`** - HTTP/SSE + JSON-RPC app server transport for headless agent workflows.
96 - **`crates/config`** - Config loading, profiles, environment variable precedence, CLI runtime overrides.
97 - **`crates/core`** - Agent loop, session management, turn orchestration. (The
98 "capacity flow guardrails" once listed here were part of the removed capacity
99 system; no `capacity` symbol remains in this crate.)
100 - **`crates/execpolicy`** - Approval/sandbox policy engine for tool execution decisions.
101 - **`crates/hooks`** - Lifecycle hooks (stdout, jsonl, webhook) for pre/post tool events.
102 - **`crates/mcp`** - MCP client + stdio server for Model Context Protocol tool servers.
103 - **`crates/protocol`** - Request/response framing and protocol types.
104 - **`crates/secrets`** - OS keyring integration for API key storage.
105 - **`crates/state`** - SQLite thread/session persistence layer.
106 - **`crates/workflow`** / **`crates/workflow-js`** - Workflow engine and its
107 QuickJS scripting layer (renamed from the whaleflow crates).
108 - **`crates/lane`** - Lane runtime: durable, attachable running instances of
109 Fleet/Workflow work (`codewhale lane list/status/attach/logs/stop`).
110 - **`crates/release`** / **`crates/build-support`** - Release checks and build
111 plumbing.
112
113 ### LLM Integration
114
115 - **`client.rs`** - HTTP client for DeepSeek's documented OpenAI-compatible Chat Completions API
116 - **`llm_client.rs`** - Abstract LLM client trait with retry logic
117 - **`models.rs`** - Data structures for API requests/responses
118
119 #### DeepSeek API Endpoints
120
121 DeepSeek exposes OpenAI-compatible endpoints. The CLI uses:
122 - `https://api.deepseek.com/beta/chat/completions` - default v0.8.16 DeepSeek model turns
123 - `https://api.deepseek.com/beta/models` - default v0.8.16 live model discovery and health checks
124
125 `https://api.deepseek.com/v1` is accepted for OpenAI SDK compatibility, and
126 can still be configured explicitly to opt out of beta-only features such as
127 strict tool mode, chat prefix completion, and FIM completion. The public
128 DeepSeek docs do not document a Responses API path for this workflow; the engine
129 drives turns through Chat Completions.
130
131 ### Tool System
132
133 - **`tools/`** - Built-in tool implementations
134 - `mod.rs` - Tool registry and common types
135 - `shell.rs` - Shell command execution
136 - `file.rs` - File read/write operations
137 - `todo.rs` - Checklist tools plus legacy todo aliases
138 - `tasks.rs` - Model-visible durable task, gate, background shell, and PR-attempt tools
139 - `github.rs` - Read-only GitHub context and guarded comment/closure tools backed by `gh`
140 - `automation.rs` - Model-visible scheduling tools over `AutomationManager`
141 - `plan.rs` - Planning tools
142 - `subagent/` - Sub-agent launch and supervision. The one model-facing tool
143 is `agent`; the `agent_open`/`agent_eval`/`agent_close` lifecycle surface
144 was retired (see `subagent/coord.rs:5`)
145 - `spec.rs` - Tool specifications
146 - `rlm.rs` - Persistent Recursive Language Model (RLM) sessions — sandboxed Python REPLs with semantic helper calls and `var_handle` output support
147
148 ### Extension Systems
149
150 - **`mcp.rs`** - Model Context Protocol client for external tool servers
151 - **`skills.rs`** - Plugin/skill loading and execution
152 - **`hooks.rs`** - Pre/post execution hooks with conditions
153
154 ### User Interface
155
156 - **`tui/`** - Terminal UI components (ratatui-based)
157 - `app.rs` - Application state and message handling
158 - `ui.rs` - Event handling, streaming state, and rendering logic
159 - `approval.rs` - Tool approval dialog
160 - `clipboard.rs` - Clipboard handling
161 - `streaming.rs` - Streaming text collector
162
163 ### LSP Integration
164
165 - **`lsp/`** - Post-edit diagnostics injection (#136)
166 - `mod.rs` - `LspManager` — lazy per-language transport pool + config
167 - `client.rs` - `StdioLspTransport` — JSON-RPC over stdio with `didOpen`/`didChange`/`publishDiagnostics`
168 - `diagnostics.rs` - Diagnostic types, severity, and HTML-block renderer
169 - `registry.rs` - Language detection and the default server map: `rust-analyzer`,
170 `gopls`, `pyright-langserver`, `typescript-language-server`, `jdtls`,
171 `intelephense` (PHP), `vue-language-server`, `clangd` (`lsp/registry.rs:98-110`)
172 - Wired into the engine via `core/engine/lsp_hooks.rs` — called after every successful edit
173
174 ### Security
175
176 - **`sandbox/`** - platform sandbox policy preparation and denial reporting
177 - `mod.rs` - Sandbox type definitions
178 - `policy.rs` - Sandbox policy configuration
179 - `seatbelt.rs` - macOS Seatbelt profile generation
180 - `bwrap.rs` - opt-in Linux bubblewrap command wrapper
181 - `seccomp.rs` - dormant Linux seccomp implementation; not wired into commands
182 - `windows.rs` - Windows helper contract; not advertised until a Job
183 Object process-containment helper exists
184
185 ### Utilities
186
187 - **`utils.rs`** - Common utilities
188 - **`logging.rs`** - Logging infrastructure
189 - **`compaction.rs`** - Context compaction for long conversations
190 - **`purge.rs`** - Agent-driven context purging (surgical message removal/rewriting)
191 - **`pricing.rs`** - Cost estimation
192 - **`prompts.rs`** - System prompt templates
193 - **`runtime_api.rs`** - HTTP/SSE runtime API (`codewhale serve --http`)
194 - **`runtime_threads.rs`** - Durable thread/turn/item store + replayable event timeline
195 - **`task_manager.rs`** - Durable queue, worker pool, task timelines and artifacts
196
197 ## Data Flow
198
199 ### Interactive Session
200
201 1. User input received in TUI
202 2. Input processed by `core/engine.rs`
203 3. Message sent to LLM via `llm_client.rs`
204 4. Response streamed back, parsed in `client.rs`
205 5. Tool calls extracted and executed via `tools/`
206 6. Hooks triggered before/after tool execution
207 7. Results aggregated and sent back to LLM
208 8. Final response rendered in TUI
209
210 ### Crash Recovery + Offline Queue
211
212 1. Before sending user input, the TUI writes a checkpoint snapshot to `~/.codewhale/sessions/checkpoints/latest.json`
213 2. Startup remains fresh by default; prior sessions are resumed explicitly via `--resume`/`--continue` (or `Ctrl+R` in TUI)
214 3. While degraded/offline, new prompts are queued in-memory and mirrored to `~/.codewhale/sessions/checkpoints/offline_queue.json`
215 4. Queue edits (`/queue ...`) are persisted continuously so drafts and queued prompts survive restarts
216 5. Successful turn completion clears the active checkpoint and writes a durable session snapshot
217 6. Action-capable turns also take pre/post-turn side-git workspace snapshots under `~/.codewhale/snapshots/<project_hash>/<worktree_hash>/.git`; `/restore N` and `revert_turn` restore file state without changing conversation history or the user's `.git`
218
219 ### Tool Execution
220
221 1. LLM requests tool via `tool_use` content block
222 2. Tool registry looks up handler
223 3. Pre-execution hooks run
224 4. Approval requested when the effective permission posture and policy require it
225 5. Tool executed (possibly wrapped by Seatbelt on macOS or opt-in bubblewrap on Linux)
226 6. Post-execution hooks run
227 7. Result metadata is retained on runtime item records
228 8. **LSP post-edit hook**: after a `File` write, edit, or patch action (including a replay-only legacy alias), the engine runs `run_post_edit_lsp_hook()` when LSP is enabled to collect diagnostics
229 9. **Diagnostics flush**: before the next API request, `flush_pending_lsp_diagnostics()` injects any collected errors as a synthetic user message
230 10. Result returned to agent loop
231
232 ### Background Tasks
233
234 1. Client enqueues task (`/task add ...` or `POST /v1/tasks`)
235 2. `task_manager.rs` persists task + queue entry under `~/.codewhale/tasks`
236 3. Worker picks queued task (bounded pool), transitions to `running`
237 4. Task creates/uses a runtime thread and starts a runtime turn
238 5. `runtime_threads.rs` persists thread/turn/item records + monotonic event sequence
239 6. Timeline/tool summaries/artifact references are persisted incrementally
240 7. Checklist state, verifier gates, PR attempts, and guarded GitHub events are applied from tool metadata to the active task
241 8. Final state (`completed|failed|canceled`) is durable and queryable via TUI/API
242
243 Model-visible durable task tools are a surface over this same manager. They do
244 not introduce a parallel work system: `task_create` enqueues normal tasks,
245 `checklist_*` updates task-local progress, `task_gate_run` and completed
246 `task_shell_wait` attach verification evidence, and automation runs enqueue
247 ordinary durable tasks.
248
249 ### Runtime Thread/Turn Timeline
250
251 1. API/TUI creates or resumes a thread (`/v1/threads*`)
252 2. Turn starts on the thread (`/v1/threads/{id}/turns`)
253 3. Engine events are mapped to item lifecycle events (`item.started|item.delta|item.completed`)
254 4. Interrupt/steer operations apply to the active turn only
255 5. Compaction (auto/manual) is emitted as `context_compaction` item lifecycle
256 6. Purge (agent-driven) is emitted as `context_purge` item lifecycle
257 7. Clients replay history and resume with `/v1/threads/{id}/events?since_seq=<n>`
258
259 ### Durable Schema Gates
260
261 - `session_manager.rs`, `runtime_threads.rs`, and `task_manager.rs` embed `schema_version` on persisted records.
262 - On load, newer schema versions are rejected with explicit errors instead of silently truncating/overwriting data.
263 - This allows safe forward migrations and prevents corruption when binaries and stored state are out of sync.
264
265 ## Extension Points
266
267 ### Adding a New Tool
268
269 1. Create handler in `tools/`
270 2. Register in `tools/registry.rs`
271 3. Add tool specification (name, description, input schema)
272
273 ### Adding an MCP Server
274
275 1. Configure in `~/.codewhale/mcp.json`
276 2. Server auto-discovered at startup
277 3. Tools exposed to LLM automatically
278
279 ### Creating a Skill
280
281 1. Create skill directory with `SKILL.md`
282 2. Define skill prompt and optional scripts
283 3. Place in a CodeWhale-owned root (`~/.codewhale/skills/` or
284 `<workspace>/.codewhale/skills/`), or import from a compatible harness root
285 through `/skills`
286
287 See [SKILLS.md](SKILLS.md) for the Skills Manager, audit inventory, and the
288 rule that compatible roots (`.claude`, `.agents`, …) are never mutated in place.
289
290 ### Adding Hooks
291
292 Configure in `~/.codewhale/config.toml`:
293
294 ```toml
295 [[hooks]]
296 event = "tool_call_before"
297 command = "echo 'Running tool: $TOOL_NAME'"
298 ```
299
300 ## Key Design Decisions
301
302 1. **Streaming-first**: All LLM responses stream for responsiveness
303 2. **Tool safety**: Ask and Auto-Review require approval according to tool and
304 managed policy; Full Access removes ordinary prompts but not hard safety
305 holds. Side-effectful MCP tools use the same boundary.
306 3. **Extensibility**: MCP, skills, and hooks allow customization without code changes
307 4. **Cross-platform**: Core works on Linux/macOS/Windows. Sandbox guarantees
308 are platform-specific: macOS uses Seatbelt when available; Linux uses an
309 installed bubblewrap executable only when explicitly enabled; Windows has
310 no advertised OS command sandbox. Seccomp and the Windows helper contract
311 are not wired into command execution.
312 5. **Minimal dependencies**: Careful dependency selection for build speed
313 6. **Local-first runtime API**: HTTP/SSE endpoints are intended for trusted localhost access and are served by the `crates/tui` runtime today
314
315 ## Configuration Files
316
317 - `~/.codewhale/config.toml` - Main configuration (`~/.deepseek/config.toml` is still read as a legacy fallback)
318 - `/etc/deepseek/managed_config.toml` - Optional managed defaults layer (Unix)
319 - `/etc/deepseek/requirements.toml` - Optional allowed-policy constraints (Unix)
320 - `~/.codewhale/mcp.json` - MCP server configuration
321 - `~/.codewhale/skills/` - User skills directory
322 - `~/.codewhale/sessions/` - Session history
323 - `~/.codewhale/sessions/checkpoints/` - Crash checkpoint + offline queue persistence
324 - `~/.codewhale/snapshots/` - Side-git pre/post-turn workspace snapshots for `/restore` and `revert_turn`
325 - `~/.codewhale/tasks/` - Background task records, queue, timelines, artifacts
326 - `~/.codewhale/audit.log` - Append-only audit events for credential + approval/elevation actions
327
327 lines MARKDOWN