The claw code rust runtime is the engine behind every interaction in the Claw Code agent. While Python handles high-level orchestration and prompt engineering, the Rust layer accounts for roughly 72.9% of the codebase and is responsible for everything that must be fast, safe, and concurrent: HTTP streaming, file system operations, process management, permission checks, and the interactive terminal experience. The runtime is organized as a 6-crate Cargo workspace, each crate owning a clearly bounded domain.

6-크레이트 워크스페이스 개요

The Rust side of Claw Code is not a monolith. It is a Cargo workspace comprising six crates that compile independently and expose well-defined interfaces to each other. This separation enforces compile-time boundaries between the API transport layer, the runtime engine, the tool registry, the command parser, the TypeScript compatibility shim, and the terminal binary.

크레이트 용도 주요 지표
api Anthropic Messages API client — authentication, streaming, retry logic, OAuth 7 retryable status codes, exponential backoff
runtime Core engine — 16 internal modules covering bash execution, config, conversation loop, file ops, MCP, permissions, sessions, and more 16 modules, 12 bootstrap phases
tools Tool specifications with full JSON schemas and a unified execute_tool dispatch 19 tool specs
commands Slash command parser and handler 15 slash commands
compat-harness TypeScript compatibility layer for bridging the original TS codebase Interop shim
rusty-claude-cli Terminal binary — REPL, spinner, syntax highlighting, line editor, OAuth flow Braille spinner, 3 output formats

The api Crate: Anthropic Messages API Client

The api crate is the sole interface between Claw Code and Anthropic's servers. It handles authentication, request construction, response parsing, streaming via Server-Sent Events, and automatic retry with exponential backoff. Every message exchange — whether a single-shot request or a multi-turn streaming conversation — flows through this crate.

인증 모델

Authentication is managed through the AuthSource enum, which supports four variants to cover every deployment scenario:

The convenience function from_env() reads ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN from environment variables, automatically selecting the appropriate AuthSource variant based on which variables are present.

The AnthropicClient Struct

The central type is AnthropicClient, which holds the HTTP transport (powered by reqwest), the AuthSource, and retry configuration:

struct AnthropicClient { http: reqwest::Client, auth: AuthSource, base_url: String, // DEFAULT_BASE_URL = "https://api.anthropic.com" max_retries: u32, // DEFAULT_MAX_RETRIES = 2 initial_backoff: Duration, // DEFAULT_INITIAL_BACKOFF = 200ms max_backoff: Duration, // DEFAULT_MAX_BACKOFF = 2s }

Two primary methods handle message exchange:

For OAuth workflows, the crate exposes exchange_oauth_code() and refresh_oauth_token(), enabling the full authorization code exchange and token refresh cycle.

상수 및 기본값

상수
DEFAULT_BASE_URL "https://api.anthropic.com"
ANTHROPIC_VERSION "2023-06-01"
DEFAULT_MAX_RETRIES 2
DEFAULT_INITIAL_BACKOFF 200ms
DEFAULT_MAX_BACKOFF 2s

재시도 로직 및 오류 처리

The client automatically retries requests that fail with specific HTTP status codes. The following statuses are considered retryable: 408 (Request Timeout), 409 (Conflict), 429 (Too Many Requests), 500 (Internal Server Error), 502 (Bad Gateway), 503 (Service Unavailable), and 504 (Gateway Timeout). Retries use exponential backoff capped at max_backoff.

Errors are modeled by the ApiError enum:

API 타입

The crate defines the full request and response model for the Anthropic Messages API:

The runtime Crate: 16 Internal Modules

The runtime crate is the largest and most complex part of the claw code rust runtime. It contains 16 internal modules, each responsible for a distinct subsystem. Together they form the engine that drives every conversation turn: executing bash commands, managing configuration, running the tool-use loop, handling file operations, enforcing permissions, building system prompts, and tracking token usage.

bash

The bash module handles shell command execution. It defines BashCommandInput and BashCommandOutput types and executes commands via sh -lc (login shell) using tokio async with configurable timeouts. For long-running processes, background execution is supported through Command::spawn, which detaches the child process and returns immediately.

bootstrap

The bootstrap module defines a BootstrapPhase enum with 12 phases that the agent traverses during startup:

  1. CliEntry
  2. FastPathVersion
  3. StartupProfiler
  4. SystemPromptFastPath
  5. ChromeMcpFastPath
  6. DaemonWorkerFastPath
  7. BridgeFastPath
  8. DaemonFastPath
  9. BackgroundSessionFastPath
  10. TemplateFastPath
  11. EnvironmentRunnerFastPath
  12. MainRuntime

Each phase represents a checkpoint in the startup pipeline. The "FastPath" phases are optimized early-exit paths that skip unnecessary initialization when the agent detects it can satisfy the request without the full runtime (for example, printing the version number or reusing a cached system prompt).

compact

The compact module implements conversation compaction — the process of summarizing long conversations to fit within token limits. It uses a CompactionConfig with preserve_recent = 4 (keep the last 4 messages intact) and max_estimated_tokens = 10000. Token estimation uses a ~4 chars/token heuristic. The compaction process strips <analysis> tags, collects key files by extension (.rs, .ts, .tsx, .js, .json, .md), and truncates the generated summary at 160 characters.

config

Configuration in Claw Code is layered. The config module defines a ConfigSource enum (User, Project, Local) and discovers three configuration files in order:

  1. ~/.claude/settings.json — User-level settings.
  2. .claude/settings.json — Project-level settings (checked into version control).
  3. .claude/settings.local.json — Local overrides (git-ignored).

MCP server transports are modeled by the McpTransport enum with six variants: Stdio, Sse, Http, Ws, Sdk, and ClaudeAiProxy. Configuration merging uses a BTreeMap-based deep merge strategy where more specific sources (Local) override less specific ones (User).

conversation

The conversation module is the heart of the agent loop. It defines ConversationRuntime<C, T>, generic over two traits: ApiClient (for LLM communication) and ToolExecutor (for tool invocation). The runtime enforces a max_iterations = 16 limit on the tool-use loop. Each iteration sends the current message history to the LLM, checks whether the response includes tool calls, executes them if present, appends the results, and repeats — until either the model stops requesting tools or the iteration limit is reached.

file_ops

The file_ops module provides five core operations: read_file, write_file, edit_file, glob_search, and grep_search. The default head_limit is 250 lines, and glob results are truncated at 100 files. The edit_file function returns an EditFileOutput struct that includes both a structured_patch and a git_diff representation of the change, enabling downstream consumers to display or apply edits in whichever format suits their needs.

json

Rather than depending on serde_json, the claw code rust runtime includes a zero-dependency JSON parser. The json module defines a JsonValue enum with six variants: Null, Bool, Number, String, Array, and Object. It includes a full parser with unicode escape handling, keeping the dependency tree lean for contexts where minimizing compile times or binary size matters.

mcp and mcp_client

The mcp module handles MCP (Model Context Protocol) integration. It provides normalize_name_for_mcp for sanitizing tool names and uses the naming convention mcp__{server}__{tool} to namespace MCP tools. An FNV-1a hash is used for fast configuration comparison, detecting when MCP server configs have changed and need reconnection.

The mcp_client module builds on this with McpClientTransport (6 variants matching the McpTransport enum) and McpClientAuth (None or OAuth). The McpClientBootstrap type provides from_scoped_config for initializing MCP client connections from the layered configuration system.

oauth

The oauth module implements the full PKCE (Proof Key for Code Exchange) flow. It provides generate_pkce_pair and S256 challenge generation, stores tokens as OAuthTokenSet, and persists credentials at ~/.claude/credentials.json. File writes use atomic temp-file saves to prevent credential corruption if the process is interrupted mid-write.

permissions

Permission enforcement is handled by the permissions module. The PermissionMode enum has three variants: Allow, Deny, and Prompt. The PermissionPolicy type holds a per-tool BTreeMap mapping tool names to their permission modes. A PermissionPrompter trait allows different frontends (CLI, GUI, test harness) to provide their own interactive prompt implementation.

prompt

The prompt module constructs the system prompt sent to the LLM at the beginning of each conversation. The SystemPromptBuilder assembles context from multiple sources. Key constants:

The builder discovers CLAUDE.md files by walking ancestor directories from the current working directory upward. It applies content hash deduplication to avoid injecting the same instructions multiple times when a project has identical CLAUDE.md files at different directory levels.

remote

The remote module manages upstream proxy configuration. It defines DEFAULT_REMOTE_BASE_URL and maintains a list of 16 no-proxy hosts that bypass the upstream proxy, including localhost, anthropic.com, github.com, and others. This ensures that local development traffic and direct API calls are never accidentally routed through a proxy.

session

The session module defines the conversation data model. MessageRole has four variants: System, User, Assistant, and Tool. ContentBlock has three variants: Text, ToolUse, and ToolResult. The Session type provides full JSON serialization for persisting and resuming conversations.

sse

The sse module implements an incremental Server-Sent Events parser. The SseParser type exposes push_chunk for feeding in raw bytes as they arrive from the HTTP response stream, and finish to signal end-of-stream and flush any remaining buffered event. This design allows the streaming pipeline to process events as they arrive without waiting for the full response.

usage

The usage module tracks token consumption and cost. It defines ModelPricing with per-million-token rates:

모델 입력 (100만 토큰당) 출력 (100만 토큰당)
Sonnet $15 $75
Haiku $1 $5
Opus $15 $75

The TokenUsage type accumulates input and output token counts across a session, and format_usd converts the running total into a human-readable dollar amount.

The tools Crate: 19 Tool Specifications

The tools crate defines the complete tool registry available to the agent. Each of the 19 tool specs includes a full JSON schema describing its parameters, a description used in the system prompt, and an implementation wired through a unified execute_tool dispatch function. When the LLM emits a tool-use content block, the runtime looks up the tool name in this registry, validates the arguments against the schema, and calls the corresponding handler.

Tools span the full range of agent capabilities: file reading and writing, code editing with structured patches, glob and grep search, bash command execution, browser automation, and more. The JSON schema definitions ensure that the LLM produces well-formed tool calls that can be validated before execution, reducing the chance of runtime errors from malformed arguments.

The commands Crate: 15 Slash Commands

The commands crate implements the slash command system. A SlashCommand enum enumerates all 15 available commands, and a parse() function converts raw user input (e.g., /help, /clear, /compact) into the corresponding enum variant. The handle_slash_command function dispatches the parsed command to its handler, which may modify the session state, trigger a special action, or produce output directly.

The compat-harness Crate: TypeScript Compatibility

The compat-harness crate provides a TypeScript compatibility layer. Since Claw Code is a clean-room reimplementation of the original TypeScript-based Claude Code, this crate bridges the gap during the transition period — allowing certain TypeScript modules to be called from the Rust runtime and vice versa. It serves as the interop boundary that enables incremental migration without requiring a full rewrite to ship.

The rusty-claude-cli Crate: Terminal Binary

The rusty-claude-cli crate is the final binary that users actually run. It ties together all other crates into a polished terminal experience.

기본 모델

The default model is set to "claude-sonnet-4-20250514", configurable via command-line flags or environment variables.

터미널 경험

The CLI uses a braille spinner with 10 animation frames to indicate activity while waiting for LLM responses:

const SPINNER_FRAMES: [&str; 10] = [ "⠙", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏", ];

Syntax highlighting is powered by syntect with the base16-ocean.dark theme, and Markdown rendering uses pulldown_cmark. The line editor is built on crossterm in raw mode with the following key bindings:

OAuth 플로우

The binary includes a full OAuth login/logout flow, leveraging the oauth module from the runtime crate for PKCE challenge generation and token persistence.

출력 형식

Three output formats are supported: Text (human-readable, the default), Json (structured single-object output), and Ndjson (newline-delimited JSON for streaming consumption by other tools).

요청 생명주기: 엔드투엔드 데이터 흐름

Understanding how a single user message travels through the claw code rust runtime clarifies how the crates interact:

  1. The rusty-claude-cli line editor captures user input and passes it to the runtime crate's ConversationRuntime.
  2. The prompt module builds or updates the system prompt, discovering CLAUDE.md files and applying the instruction character limits.
  3. The session module appends the user message to the conversation history.
  4. The conversation module sends the full message list to the api crate via stream_message().
  5. The api crate constructs the HTTP request, attaches authentication headers, and opens an SSE connection.
  6. The sse module incrementally parses incoming chunks into StreamEvent variants.
  7. If the response includes ToolUse content blocks, the conversation module looks up each tool in the tools crate registry.
  8. The permissions module checks whether each tool call is allowed under the current PermissionPolicy.
  9. Approved tool calls are executed (e.g., bash module for shell commands, file_ops for file operations).
  10. Results are appended to the session and the loop repeats (up to 16 iterations).
  11. When the model emits a final text response without tool calls, the CLI renders it with syntax highlighting and Markdown formatting.
  12. The usage module updates the running token count and cost estimate.

핵심 설계 결정

왜 무의존성 JSON 파서인가?

The custom JsonValue parser avoids pulling in serde and serde_json, which together add significant compile time and binary size. Since the runtime only needs to parse and produce JSON for the API wire format and tool schemas — not arbitrary Rust struct serialization — a focused parser that handles the exact JSON subset needed is sufficient and keeps the dependency tree minimal.

왜 대화 루프에 제네릭 트레이트를 사용하는가?

Making ConversationRuntime<C, T> generic over ApiClient and ToolExecutor traits enables testing with mock implementations. The conversation loop logic can be exercised without real HTTP calls or file system side effects, which is critical for a system that executes potentially destructive operations on behalf of the user.

왜 자격 증명에 원자적 파일 쓰기를 사용하는가?

OAuth tokens stored at ~/.claude/credentials.json are written atomically via temp-file rename. If the agent process crashes mid-write, the previous credential file remains intact. This prevents the frustrating scenario where a user must re-authenticate because their credentials file was corrupted by an interrupted write.

왜 12단계 부트스트랩인가?

The bootstrap pipeline is designed for fast startup. Most invocations hit an early "FastPath" exit — for example, FastPathVersion returns the version string without initializing the full runtime, and SystemPromptFastPath reuses a cached prompt when nothing has changed. Only interactive sessions that need the complete conversation loop proceed all the way to MainRuntime.