Workspace structure
The workspace lives underclaude-code-rust/ and is organized as a Cargo workspace with resolver = "2", edition 2021.
| Package | Type | Purpose |
|---|---|---|
cc-core | Library | Shared types, error enum, config, permissions, history, cost tracking, hooks |
cc-api | Library | Anthropic Messages API client with SSE streaming and retry logic |
cc-tools | Library | All 33 built-in tool implementations |
cc-query | Library | Agentic query loop, auto-compact, sub-agent tool, cron scheduler |
cc-tui | Library | Terminal UI (ratatui + crossterm) |
cc-commands | Library | Slash command registry and implementations |
cc-mcp | Library | JSON-RPC 2.0 MCP client over stdio subprocess transport |
cc-bridge | Library | Bridge protocol for claude.ai remote control |
claude-code | Binary | CLI entry point; binary named claude |
Dependency flow
cc-core is the only crate with no upstream dependencies within the workspace. Every other crate depends on it for shared types, error handling, and configuration. The CLI binary wires everything together.
Agentic query loop
The core of Claurst is the agentic loop implemented incc-query. A single user turn follows this flow:
Receive user input
The TUI or headless runner receives a user prompt and appends it to the in-process message history as a
Message::user(...).Build the API request
run_query_loop() converts the message history to Vec<ApiMessage>, converts available tools to Vec<ApiToolDefinition>, and assembles a CreateMessageRequest with the system prompt and optional thinking budget.Stream the response
AnthropicClient::create_message_stream() spawns a background Tokio task that reads the SSE response body line by line and sends StreamEvent values over an mpsc channel (buffer: 256). A StreamAccumulator collects deltas into a complete Message.Execute tools
When
stop_reason is tool_use, the loop iterates over every ContentBlock::ToolUse in the response. For each block it fires PreToolUse hooks, calls execute_tool(), fires PostToolUse hooks, and collects ToolResult values into a Message::user_blocks(result_blocks) appended to the history.Loop or return
If tool results were appended, the loop continues from step 2. The loop terminates when
stop_reason is end_turn or stop_sequence (returns QueryOutcome::EndTurn), max_tokens (returns QueryOutcome::MaxTokens), the turn counter exceeds max_turns (default: 10), or the CancellationToken fires.<compact-summary> block, keeping the last 10 messages intact.
TUI layer
cc-tui replaces the TypeScript Ink/React rendering layer with an immediate-mode terminal UI:
- Backend:
ratatui+crossterm. The terminal is placed in raw mode withcrossterm::terminal::enable_raw_mode()and switched to the alternate screen buffer. - Layout: Three vertical chunks — messages area (flex fill), input box (3 rows), status bar (1 row).
- Rendering: User messages render in Cyan, assistant messages in Green. Streaming text in progress renders in Yellow italic. The status bar shows the active model and current session cost.
- Input:
App::handle_key_event()processesKeyEventvalues.Ctrl+Ccancels a streaming response; if the input is empty it quits. Up/Down navigates input history.F1or?toggles the help overlay. - Widgets: A centered
render_permission_dialog()popup handles user permission prompts. A braille spinner (⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏) animates during tool execution.
run_headless() streams QueryEvent values to stdout in text, json, or stream-json output formats without starting the TUI.
Async runtime
All async code uses Tokio with thefull feature set. The #[tokio::main] macro is applied to main() in crates/cli/src/main.rs. Every tool’s execute() method is async via async_trait. Cancellation is propagated through tokio_util::sync::CancellationToken.
Key shared dependencies
| Crate | Version | Role |
|---|---|---|
tokio | 1.44 | Async runtime (full features) |
reqwest | 0.12 | HTTP client (rustls-tls, streaming) |
ratatui | 0.29 | Terminal UI framework |
crossterm | 0.28 | Cross-platform terminal backend |
clap | 4 | CLI argument parsing |
serde / serde_json | 1 | Serialization |
schemars | 0.8 | JSON Schema generation for tool inputs |
async-trait | 0.1 | Async trait support |
dashmap | 6 | Concurrent hash maps for global state |
parking_lot | 0.12 | Faster mutexes |
Tool system
How the Tool trait works, the 33 built-in tools, and input schema validation.
Permissions
Permission modes, categories, layered settings, and protected files.
Memory
Short-term session history, the memdir long-term store, and the AutoDream consolidation system.
Back to overview
Return to the documentation home.