CLI startup

Startup is optimized around doing the least possible work until the path requires the full application. The entrypoint handles cheap exits and daemon/native-host modes first, then imports the full CLI and eventually launches the interactive Ink REPL.

Startup flow

src/entrypoints/cli.tsx
  handle zero-import paths
  handle daemon, native host, remote control, background, worktree paths
  configure bare mode
  startEarlyInputCapture()
  import ../main.js
  cliMain()

src/main.tsx
  build Commander program
  preAction global setup
  default command parses session options
  create AppState and SessionConfig
  launchRepl() for interactive paths

src/replLauncher.tsx
  import App and REPL
  renderAndRun(<App><REPL /></App>)
Entrypoint fast paths

The entrypoint explicitly documents that it should avoid eager imports. Its first branch handles --version without loading the app. It has similar early paths for dumping the system prompt, Chrome or computer-use native host behavior, daemon workers, remote control, background sessions, worktree and tmux helpers, and --bare environment setup.

This matters because the interactive app pulls in React, Ink, tools, MCP clients, settings, telemetry, and model code. Avoiding that cost for simple control-plane commands keeps startup fast and reduces side effects for special modes.

Commander and global setup

run() creates the Commander program. The global preAction stage performs setup that every normal command needs: MDM and keychain reads, initialization, terminal title, log sinks, plugin paths, migrations, feature and policy loading, and settings sync.

The default command registers most user-facing runtime inputs: --print, --append-system-prompt, --output-format, --input-format, --allowedTools, --disallowedTools, --mcp-config, --permission-mode, --model, and plugin or settings switches.

External reference: Commander.js.

Initial state and session config

Before launch, main.tsx builds initial app state and a session config. The session config is the handoff object that ties together commands, MCP commands, initial tools, MCP clients, dynamic MCP config, system prompt settings, thinking config, debug flags, and lifecycle callbacks such as onTurnComplete.

sessionConfig = {
  commands,
  mcpCommands,
  initialTools,
  mcpClients,
  dynamicMcpConfig,
  systemPrompt,
  thinkingConfig,
  onTurnComplete
}
Interactive launch paths

The app can enter the REPL from several paths: continuing a previous conversation, running remote-control flows, resuming a session, or starting a fresh session. These paths converge on launchRepl, which loads the UI modules and passes them into renderAndRun.