MODULO 8.5

🖥️ REPL Screen

6
Topicos
~60
Minutos
Deep
Nivel
Source
Tipo
1

💻 What REPL.tsx Does

The largest file in the codebase (~5,000 lines). Exports one function: REPL(props). Orchestrates conversation history, spinner, permission prompts, input box. Five internal layers: Props/Guards, State, Core Callbacks, Effects, Main Render.

💡 Why So Large

Genuine complexity: concurrency, permission queues, remote sessions, swarm workers, two render modes, session resume, keyboard navigation.

2

🔄 The Turn Lifecycle

onSubmit

Entry point. Handles immediate commands, idle-return gate, pending hooks, then routes to handlePromptSubmit.

onQuery

Concurrency guard via QueryGuard with generation counter. Stale finally blocks from cancelled queries don't corrupt state.

onQueryImpl

Actual work: builds system prompt, calls query(), streams response. Parallel async: system prompt + user context + killswitch checks.

💡 Ref Pattern

messages read via messagesRef.current (not closure) to keep onSubmit stable across ~30 setMessages calls per turn. Prevents memory leaks from pinned closure chains.

3

⏳ Loading State & Dialogs

Three independent loading sources: isQueryActive (local query), isExternalLoading (remote/SSH), hasRunningTeammates (swarm workers). Dialog priority via getFocusedInputDialog() - deterministic function returning single winner.

💡 Typing Suppression

Interrupt dialogs suppressed while user is typing. 1.5-second debounce resets after last keystroke.

4

💬 Messages Array

Not plain useState. Ref holds live value, state is render projection. Three consistency mechanisms: ephemeral progress replacement, compact boundary handling, deferred rendering via useDeferredValue.

💡 toolJSX Overlay

Local JSX commands cannot be overwritten by tool updates. In fullscreen, local-jsx renders in modal slot (absolute-positioned).

5

🔄 Session Resume

15-step sequence: deserialize messages, fire SessionEnd/Start hooks, copy plan slug, restore file history, restore agent definition, save/restore costs, switch sessionId, rename asciicast, clear/restore metadata, exit/enter worktree, reconstruct contentReplacementState.

💡 Why Clear Before Restore

restoreSessionMetadata only sets truthy fields. Without clear, resumed session would inherit previous session's cached values.

6

🎨 Render Tree & Optimizations

AlternateScreen > KeybindingSetup > FullscreenLayout with scrollable (Messages, spinner, toolJSX), bottom (PromptInput, dialogs), overlay (PermissionRequest), modal (local-jsx commands).

💡 AnimatedTerminalTitle Isolation

960ms spinner animation extracted to separate leaf component returning null. Only this tiny component re-renders on each tick, not the entire REPL tree.

📋 Resumo do Modulo

REPL.tsx is 5,000 lines of genuine complexity: concurrency, permissions, remote sessions, swarm, resume.
QueryGuard with generation numbers prevents stale finally blocks from corrupting state.
Reading state via refs inside callbacks keeps onSubmit stable across 30+ setMessages calls.
Dialog system is pure function: getFocusedInputDialog() returns one winner from deterministic priority list.
Auto-restore on interrupt runs outside generation guard by design (forceEnd bumps counter).
AnimatedTerminalTitle is isolated leaf component - 960ms tick never re-renders REPL tree.
Voltar