main.tsx runs init() and setup(), loads commands, agents, tools, and config, and mounts Ink.
interactiveHelpers.tsx and dialogLaunchers.tsx handle trust and onboarding setup before the REPL becomes the long-lived screen.
screens/REPL.tsx is mounted with app state, command list, tool pool, agent definitions, MCP state, and session metadata.
2. Prompt input is captured
components/PromptInput/PromptInput.tsx collects the input.
utils/handlePromptSubmit.ts coordinates submission from the UI side.
The REPL stores transient UI state such as queued commands, paste references, IDE selection, prompt mode, and permission dialog state.
3. Input is converted into messages and side effects
utils/processUserInput/processUserInput.ts is the first important transformation layer.
It delegates plain-text prompt work to processTextPrompt.ts.
It can parse slash commands, attach pasted content, include IDE selections, run user prompt hooks, and decide whether the input should call the model at all.
Why this split exists: not every submission becomes an LLM query. Some become local command execution, local rendering, or hook-blocked actions.
4. Query execution begins
screens/REPL.tsx calls query() from query.ts.
query.ts normalizes messages, appends system and user context, inserts attachment messages, manages compact and retry state, and tracks turn budget.
5. The API request is built and streamed
services/api/claude.ts converts tools into API schemas, chooses provider, model, betas, and thinking options, applies prompt-caching logic, and opens the provider stream.
Stream events are normalized into internal message objects by helpers such as utils/messages.ts.
screens/REPL.tsx incrementally renders assistant text, thinking state, progress, and tool boundaries as they arrive.
6. Tool calls are detected and scheduled
When the assistant emits tool-use blocks, query.ts routes them into either StreamingToolExecutor or the batch path in services/tools/toolOrchestration.ts.
StreamingToolExecutor preserves ordering while tools are still arriving in the stream.
toolOrchestration.ts partitions tool calls into concurrency-safe read-only batches versus serial exclusive batches.
7. Each tool call is permission-checked
services/tools/toolExecution.ts drives each individual tool use.
It calls the canUseTool function produced by hooks/useCanUseTool.tsx.
useCanUseTool first asks utils/permissions/permissions.ts and hasPermissionsToUseTool() for the baseline decision.
Depending on the result, the system can auto-allow, auto-deny, wait for coordinator or worker permissions, use classifier results, or open an interactive permission dialog.
8. Tool implementation runs
tools.ts provided the concrete tool registry earlier in startup.
runToolUse() in toolExecution.ts resolves the tool by name, validates its schema, emits progress, runs hooks, executes the tool, and converts the result into user-visible and model-visible message blocks.
Tool implementations live in tools/*. Common families include shell and file tools, agent and task tools, MCP tool proxies, web fetch and search, plan tools, worktree tools, brief tools, and todo tools.
9. Tool results re-enter the same turn
Tool result messages are appended to the running conversation.
query.ts continues the turn if the model still has work to do.
Compacting, stop hooks, and token-budget continuation logic can add more transitions before the turn ends.
10. Turn state is persisted and surfaced
utils/sessionStorage.ts records transcript updates and session metadata.
utils/fileHistory.ts and attribution helpers update file history and commit-attribution snapshots.
cost-tracker.ts and bootstrap/state.ts capture usage, costs, durations, and telemetry.
screens/REPL.tsx updates tasks, notifications, spinner state, footer state, and remote or MCP indicators.
Where Interactive-Only Bugs Usually Hide
UI-only issues: screens/REPL.tsx, components/*, and hooks/*.
Permission dialog and approval behavior: hooks/useCanUseTool.tsx, components/permissions/*, and utils/permissions/*.
Prompt parsing and slash command oddities: utils/processUserInput/*, commands.ts, and commands/*.
Tool scheduling and ordering problems: query.ts, StreamingToolExecutor.ts, toolOrchestration.ts, and toolExecution.ts.