02 / 20 Architecture 1,902 files · 35 directories · 513K lines

2,000+ files. 35 directories. One async generator at the core.

The codebase is organized by function: tools, services, components, utilities. The system boots in ~200ms by overlapping I/O with module loading. The conversation loop is an async generator. Tools execute while the API response is still streaming.

1,902
Source files — TypeScript & TSX
35
Top-level dirs in src/
~200ms
Boot time — parallel I/O
1,729
Lines in query.ts

01 — Folder Structure

The src/ directory organized by function. Every top-level directory with file counts from the actual source.

DirectoryFilesWhat's Inside
utils/564Permissions (24 files), bash AST parser, sandbox adapter, model routing, settings, git ops, swarm backends (tmux/iTerm/in-process), computer use, deep links, memory, telemetry, suggestions
components/389Ink terminal UI — messages, permission dialogs, settings panels, diff viewer, task list, team management, design system, prompt input
commands/20784 slash commands each in own dir — /help, /plan, /review, /buddy, /voice. 24+ internal-only stripped from external builds
tools/18443 tool implementations — Bash, FileEdit, FileRead, FileWrite, Glob, Grep, Agent, MCP, WebFetch, Skill, Task*, Team*, Cron*, Plan, Worktree, LSP
services/130API client (multi-provider), MCP protocol (24 files), StreamingToolExecutor, compaction, analytics, OAuth, plugins, policy limits, prompt suggestion, memory extraction, autoDream, team memory sync
hooks/104React hooks — useStream, useTools, tool permissions, notifications. 20 hook events (Setup → Stop)
ink/96Custom Ink fork — React reconciler, Yoga WASM flexbox, ANSI parser/optimizer, DOM, frame rendering, double-buffering, terminal I/O, events, hit testing, selection
bridge/31IDE/remote — OAuth, JWT refresh, trusted devices, WebSocket, SSE, session management, keepalive
constants/21Prompts, system prompt sections, API limits, spinner verbs, cyber risk instructions, OAuth scopes
skills/2019 bundled skills — /schedule, /loop, /claude-api, /simplify, /ship, /investigate. Plus loading infra
cli/19CLI entry (cli.tsx 39KB), headless/print mode (212KB), transport handlers
keybindings/14Custom keyboard shortcuts — schema, parser, resolver, validator, chord bindings, defaults
tasks/12Task runners — RemoteAgent, InProcessTeammate, LocalAgent, LocalShell, DreamTask
migrations/11Model renames (Fennec→Opus, Sonnet 4.5→4.6), settings migrations, consent tracking
types/11Permission types, hook types, command types, plugin types, generated protobuf
context/9React contexts — prompt overlay, FPS metrics, mailbox, notifications, stats, modal, voice
memdir/8Memory system — MEMORY.md loader, 4 memory types, scan, relevance scoring, team memory prompts
entrypoints/8CLI bootstrap, SDK entry, MCP server entry, init sequence, sandbox types
buddy/6Companion sprite — 18 species, procedural generation, animation, sprites
state/6Zustand store, AppState types, store factory, snapshots
vim/5Full vim mode — motions, operators, 11 text objects, state machine, dot-repeat
query/4Core loop — token budget, stop hooks, config, dependencies
native-ts/4Native bindings — color-diff, file-index, yoga-layout (WASM)
remote/4Remote session management, WebSocket, SDK adapter, permission bridge
screens/3REPL.tsx (896KB), ResumeConversation.tsx (60KB), Doctor.tsx (73KB)
server/3Direct connect sessions, connection manager
plugins/2Plugin loading, built-in plugin registry
upstreamproxy/2Upstream proxy + relay for CCR mTLS
coordinator/1Coordinator mode — worker orchestration with shared scratchpad
voice/1Voice mode enablement (SoX + mic + OAuth + kill-switch)

02 — Boot Sequence

What happens when you type claude — a 3-phase pipeline that overlaps I/O with module loading. Side effects fire before 187 imports resolve.

Phase 1 — CLI Fast-Path (<50ms)

01
cli.tsx loads
--version exits immediately. --daemon-worker, --chrome-native-host, --computer-use-mcp route to handlers. Zero module evaluation.
02
Feature flags (compile-time)
Bun's feature() eliminates code at build time. 26 flags — external builds strip all ANT-only code. Binary is measurably smaller.

Phase 2 — Initialization (Parallel I/O, ~200ms)

03
Parallel prefetch (lines 12-20 of main.tsx)
startMdmRawRead() spawns plutil/reg query (~135ms). startKeychainPrefetch() fires two keychain reads (~65ms). Both overlap with 187 imports resolving.
04
Auth validated
OAuth from ~/.claude/auth.json or ANTHROPIC_API_KEY. Provider detection: Bedrock/Vertex/Foundry env vars.
05
Config cascade + GrowthBook
Policy → User → Project → Local → CLI. CLAUDE.md walks dir tree. 100+ tengu_* gates fetched async (disk-cached).

Phase 3 — REPL Setup

06
setCwd → hooks → worktree → tools → MCP
setCwd() MUST be first. Hooks config frozen. 43 tools loaded. MCP servers connected in parallel.
07
System prompt from 10+ sources
Role, tool schemas, CLAUDE.md, MEMORY.md, memories, git context, OS info, MCP instructions, hooks, tips.
08
Ink renders → loop idles
React reconciler + Yoga WASM. Double-buffered. Background tasks started. Idle.
getIsNonInteractiveSession()
runHeadless()
JSON to stdout
launchRepl()
Trust → REPL

03 — Query Loop — The Core Cycle

The conversation loop (query.ts, 1,729 lines) is an async generator. The REPL consumes events via for await.

1
Compaction
4 strategies: snip, microcompact, autocompact (at ~167K tokens), context collapse. Deep dive →
2
API Call (streaming)
System prompt from 10+ sources. Prompt caching with cache_control. Tokens rendered in real-time.
3
Tool Execution — starts BEFORE stream ends
StreamingToolExecutor queues tool_use blocks as they arrive. Concurrent-safe tools parallel (max 10). Sibling abort on Bash errors.
↓ continuation
4
Continue, Retry, or Return
tool_use → loop. Prompt too long → compact. Max tokens → increase (max 3). Capacity → fallback model. End turn → return.
Post-sampling hooks: auto-compact check, memory extraction (forked agent every turn), prompt suggestion (CHOMP), speculation (pre-compute next turn), auto-dream (24h + 5 sessions). Full deep dive →

04 — Rendering Pipeline

The src/ink/ directory (96 files) is a heavily modified Ink fork — not a thin wrapper.

React Components
389 files
Custom Reconciler
reconciler.ts
Custom DOM
dom.ts
Yoga (WASM)
Flexbox
Frame Buffer
Double-buffered
Terminal
ANSI

What the Ink fork adds

  • Custom React reconciler for terminal DOM
  • Yoga WASM flexbox layout engine
  • Double-buffered ANSI rendering
  • ANSI parser + optimizer pools
  • Hit testing + text selection + search highlighting
  • Mouse tracking (mode-1003)
  • Alternate screen mode

3 Screens

  • REPL.tsx — main screen (896KB)
  • ResumeConversation.tsx — session resume (60KB)
  • Doctor.tsx — diagnostics (73KB)

Key Primitives

  • Box, Text, Button, ScrollBox, Link, RawAnsi

05 — State Architecture

Two-layer system: a global singleton for process-lifetime data, and a Zustand store for React-integrated UI state.

Bootstrap State global singleton

150+ fields surviving the entire process:

  • originalCwd, projectRoot
  • totalCostUSD, totalAPIDuration, totalToolDuration
  • modelUsage — per-model token accounting
  • sessionId, agentColorMap
  • lastAPIRequest — debugging (sans messages)
  • cachedClaudeMdContent — for auto-mode classifier

App State Zustand + React Context

Immutable (DeepImmutable):

  • mainLoopModel, fastMode, effortValue
  • toolPermissionContext (mode + rules)
  • replBridgeEnabled/Connected

Mutable:

  • messages[], MCP connections, tasks, plugins
  • notifications, swarm context, speculation state

06 — Feature Gate System

Bun's feature() enables compile-time dead code elimination. Not runtime checks — code is physically absent from the binary.

How it works

if (feature('COORDINATOR_MODE')) { ... } — the entire block is removed from the external binary at build time. 26 flags total, almost all ANT-only. External builds are measurably smaller.

What it means

The source you're reading includes ~26 features that don't exist in the binary you download. Coordinator mode, ML classifier, voice, computer use, buddy. Internal and external are architecturally different products.