AI Assistant

Claude Code has three top-level screen components in src/screens/ that serve as the main views of the application. Each screen is a React component rendered by the Ink runtime and manages its own lifecycle, state subscriptions, and child component tree.

REPL

src/screens/REPL.tsx is the primary interactive screen. It is the largest component in the codebase, orchestrating the full conversation loop.

Responsibilities

  • Conversation management: maintains the message array, handles message submission, and manages the query lifecycle
  • Permission handling: renders PermissionRequest dialogs and routes approval/denial through ToolUseConfirm callbacks
  • Tool execution: coordinates tool use with the query engine, including streaming tool execution and result display
  • Session persistence: saves conversation state to disk, manages session IDs, and handles cost tracking
  • Multi-agent coordination: routes input to the correct agent (leader, teammate, or named agent) via getActiveAgentForInput
  • UI layout: composes the message list, prompt input, spinners, dialogs, and footer into the terminal view

Key Integrations

The REPL screen imports and coordinates with a large number of subsystems:

QueryGuardclass
Manages query lifecycle, preventing concurrent queries and handling cancellation.
MessageSelectorcomponent
Filters messages for display and API submission.
PromptInputcomponent
Multi-mode input widget with history, completion, and paste handling.
VirtualMessageListcomponent
Virtualized scrollable message display with search highlighting.
PermissionRequestcomponent
Tool authorization dialogs.
CostThresholdDialogcomponent
Cost warning dialog when spending exceeds thresholds.
IdleReturnDialogcomponent
Dialog shown when user returns after inactivity.

Hooks Used

The REPL uses an extensive set of hooks for various capabilities:

// State management
useAppState(), useSetAppState()

// Terminal
useTerminalSize(), useTerminalFocus(), useTerminalTitle(), useTabStatus()
useSearchHighlight(), useInput(), useStdin()

// Features
useNotifications(), useCostSummary(), useFpsMetrics()
useLogMessages(), useReplBridge(), useIdeLogging()
useRemoteSession(), useDirectConnect(), useSSHSession()
useSkillImprovementSurvey(), useMoreRight()
useDeferredHookMessages(), useAfterFirstRender()

Session Lifecycle

When the REPL mounts, it:

  1. Initializes the file state cache with createFileStateCacheWithSizeLimit
  2. Loads system and user context via getSystemContext() and getUserContext()
  3. Builds the effective system prompt from getSystemPrompt() and buildEffectiveSystemPrompt()
  4. Starts background housekeeping tasks
  5. Consumes any early input buffered before React was ready
  6. Processes the initial message if one was set in AppState

Token Budget Display

The REPL tracks and displays token budget information:

import {
  getCurrentTurnTokenBudget,
  getTurnOutputTokens,
  getBudgetContinuationCount,
  getTotalInputTokens,
  snapshotOutputTokensForTurn,
} from '../bootstrap/state.js'

This information feeds into the spinner display (SpinnerWithVerb, BriefIdleStatus) to show the user how much of the token budget has been consumed.

ResumeConversation

src/screens/ResumeConversation.tsx handles restoring a previous session. It is shown when the user starts Claude Code with --resume or uses the /resume command.

Props

commandsCommand[]
Available slash commands.
worktreePathsstring[]
Worktree paths for multi-worktree projects.
initialToolsTool[]
Tool set for the resumed session.
mcpClientsMCPServerConnection[]
MCP server connections to restore.
dynamicMcpConfigRecord<string, ScopedMcpServerConfig>
Dynamic MCP configuration.
systemPromptstring | undefined
Custom system prompt override.
appendSystemPromptstring | undefined
Additional system prompt text.
initialSearchQuerystring | undefined
Pre-filled search query for session picker.
filterByPrboolean | number | string
Filter sessions by PR number or identifier.
forkSessionboolean
Whether to fork the session instead of continuing it.
thinkingConfigThinkingConfig
Extended thinking configuration.

Resume Flow

The resume process follows these steps:

The component loads session logs using loadSameRepoMessageLogsProgressive or loadAllProjectsMessageLogsProgressive. For PR-based filtering, it uses parsePrIdentifier to extract PR numbers from direct numbers or GitHub URLs.

The LogSelector component presents a scrollable list of sessions. Users can search by title, browse chronologically, or use agenticSessionSearch for intelligent matching.

loadConversationForResume deserializes the session file, restoring messages, metadata, and content replacements. checkCrossProjectResume validates that the session belongs to the current project.

Several state aspects are restored:

  • Session ID is switched via switchSession
  • Cost state is restored via restoreCostStateForSession
  • Agent context is computed via computeStandaloneAgentContext and restoreAgentFromSession
  • Worktree paths are restored via restoreWorktreeForResume
  • Session metadata is restored via restoreSessionMetadata

Once loading is complete, the component renders the REPL screen with the restored messages and configuration, seamlessly continuing the conversation.

Doctor

src/screens/Doctor.tsx provides system health diagnostics, accessed via the /doctor command.

Diagnostic Checks

The Doctor screen runs comprehensive health checks:

DiagnosticInfoobject
Core system diagnostics from getDoctorDiagnostic(): version, platform, Node.js version, shell, and environment.
ContextWarningsobject
Context-related warnings from checkContextWarnings(): CLAUDE.md issues, git configuration problems, etc.
NpmDistTagsobject
Version information from npm/GCS, showing current, stable, and latest versions for update checking.
AgentInfoobject
Agent configuration: active agents, user/project agent directories, and any failed agent file loads.
VersionLockInfoobject
PID-based lock state: whether locking is enabled, active locks, and stale locks cleaned.

Sections

The Doctor screen uses Pane components to organize information into sections:

  • Version and Environment: current version, available updates, platform info
  • Settings Validation: errors from useSettingsErrors(), displayed via ValidationErrorsList
  • Keybinding Warnings: keybinding conflicts from KeybindingWarnings
  • MCP Configuration: MCP parsing warnings from McpParsingWarnings
  • Sandbox: sandbox health via SandboxDoctorSection
  • Plugin Errors: plugin loading failures formatted via getPluginErrorMessage
  • Environment Variables: relevant env var validation via validateBoundedIntEnvVar

The Doctor screen uses PressEnterToContinue at the bottom, calling onDone when the user presses Enter. The onDone callback accepts an optional result string and display options, allowing the Doctor to report its findings back to the command system.

type Props = {
  onDone: (result?: string, options?: {
    display?: CommandResultDisplay
  }) => void
}

Suspense

The DistTagsDisplay component uses React Suspense with the use() hook to load version information asynchronously, showing a loading state while fetching npm/GCS dist tags.