InkdownInkdown
Start writing

Claude-Code

62 files·4 subfolders

Shared Workspace

Claude-Code
codex

01-entrypoints

Shared from "Claude-Code" on Inkdown

Entrypoints Architecture

Overview

Claude Code has multiple entry points depending on how it's launched. This is the front door of the application - where execution begins and branches.

Plain text
┌────────────────────────────────────────────────────────────────┐
│                        ENTRY POINTS                             │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐       │
│   │  CLI Entry  │    │ Bridge Entry│    │ Daemon Entry│       │
│   │  (cli.tsx)  │    │(bridgeMain) │    │(daemon/main)│       │
│   └──────┬──────┘    └──────┬──────┘    └──────┬──────┘       │
│          │                   │                   │            │
│          └───────────────────┼───────────────────┘            │
│                              │                                │
│                     ┌────────▼────────┐                       │
│                     │   Bootstrap      │                       │
│                     │  (bootstrap/)    │                       │
│                     └────────┬────────┘                       │
│                              │                                │
│                     ┌────────▼────────┐                       │
│                     │   main.tsx      │                       │
│                     │   (REPL/CLI)    │                       │
│                     └─────────────────┘                       │
│                                                                │
└────────────────────────────────────────────────────────────────┘
0000_start_here_index_and_recommended_reading_order.md
0100_project_overview_tech_stack_runtime_modes_and_folder_map.md
0200_startup_flow_entry_points_and_cold_start_sequence.md
0300_codebase_modules_layers_state_models_and_schemas.md
0400_system_architecture_and_design_rationale.md
0500_interactive_repl_request_flow_end_to_end.md
0600_headless_sdk_and_print_mode_request_flow_end_to_end.md
0700_mcp_integration_connection_and_tool_call_flow.md
0800_external_services_sdks_storage_and_local_dependencies.md
0900_environment_variables_settings_feature_flags_and_failure_modes.md
1000_non_obvious_patterns_gotchas_and_debugging_traps.md
1100_full_codebase_file_inventory_grouped_by_directory.md
kimi
00-overview.md
01-entrypoints.md
02-state-management.md
03-query-system.md
04-tools-system.md
05-tasks-system.md
06-ui-components.md
07-bridge-remote.md
08-services.md
09-skills-plugins.md
10-commands.md
11-testing-architecture.md
12-permission-system.md
13-build-system.md
14-ink-internals.md
15-git-internals.md
16-context-compaction.md
17-vim-mode.md
18-mailbox-notifications.md
19-session-persistence.md
20-hooks-system.md
21-error-recovery.md
README.md
qwen
00-overview.md
01-entry-points.md
02-query-engine.md
03-tools-and-tasks.md
04-commands-and-skills.md
05-state-management.md
06-ink-rendering.md
07-bridge-remote.md
08-mcp-services.md
09-services-overview.md
10-multi-agent.md
11-system-prompt-constants.md
12-tool-interface.md
13-memory-system.md
14-buddy-companion.md
15-keybindings.md
16-stop-hooks.md
17-vim-mode.md
18-upstreamproxy.md
19-cost-tracking-history.md
20-contexts-styles-onboarding.md
21-hooks.md
22-screens.md
tweets-explain
claude-code-memory-analysis.md
compact
memory-system
agentic-architecture

Primary Entry Point: cli.tsx

File: src/entrypoints/cli.tsx

This is the main entry when you type claude in your terminal.

Fast-Path Pattern

The CLI uses fast-path routing - special cases are handled before loading heavy modules:

TypeScript
// Example: --version is handled immediately
if (args.length === 1 && args[0] === '--version') {
  console.log(`${MACRO.VERSION} (Claude Code)`)
  return  // Exit early, no heavy imports
}
Entry Branches
BranchTriggerPurpose
--versionVersion flagPrint version and exit
--dump-system-promptDebug flagOutput system prompt
--claude-in-chrome-mcpChrome modeRun Chrome MCP server
--daemon-workerInternalSpawn daemon worker
remote-controlBridge modeRemote control session
daemonBackgroundRun supervisor daemon
ps/logs/attach/killSessionsBackground session management
--printHeadlessNon-interactive output
defaultInteractiveFull TUI REPL

Main Application: main.tsx

File: src/main.tsx (~800KB - the largest file)

This is where the full application initializes. Think of it as the main() function.

Startup Sequence
TypeScript
// 1. PROFILE: Mark entry point
profileCheckpoint('main_tsx_entry')

// 2. MDM/FETCH: Start async fetches early
startMdmRawRead()        // Mobile device management settings
startKeychainPrefetch()  // macOS keychain (OAuth tokens)

// 3. IMPORTS: Load heavy modules
import { getCommands } from './commands.js'
import { getTools } from './tools.js'

// 4. INIT: Initialize subsystems
initializeTelemetryAfterTrust()
initializeGrowthBook()
loadRemoteManagedSettings()

// 5. SETUP: CLI argument parsing
program
  .option('--model <model>', 'Set the model')
  .option('--verbose', 'Enable verbose mode')
  // ... more options

// 6. LAUNCH: Start the REPL or execute command
if (isNonInteractive) {
  await runNonInteractive()
} else {
  await launchRepl({ ... })
}
Side-Effect Imports Pattern

Notice the pattern at the very top:

TypeScript
// These side-effects must run before all other imports
import { profileCheckpoint } from './utils/startupProfiler.js'
profileCheckpoint('main_tsx_entry')

import { startMdmRawRead } from './utils/settings/mdm/rawRead.js'
startMdmRawRead()

Why? These start async operations immediately so they run in parallel with module loading.


Bootstrap State: bootstrap/state.ts

File: src/bootstrap/state.ts

This module holds global bootstrap configuration that must be available before React/State init.

What Lives Here
TypeScript
// Session identification
let sessionId: string
let userId: string

// Working directory state
let originalCwd: string
let additionalDirectories: string[]

// Feature flags (from GrowthBook)
let allowedChannels: ChannelPermission[]

// Mode flags
let isNonInteractiveSession: boolean
let isRemoteMode: boolean

// Model settings
let initialMainLoopModel: string
let mainLoopModelOverride: string | undefined
Why Separate from AppState?

AppState is React-connected. bootstrap/state is pre-React - it needs to be available before the UI initializes.


Bridge Entry Point

File: src/bridge/bridgeMain.ts

Launched via: claude remote-control

What It Does
  1. Authenticates with claude.ai
  2. Creates a bridge environment
  3. Polls for incoming commands
  4. Syncs local state to remote
Plain text
┌──────────────┐         ┌──────────────┐         ┌──────────────┐
│   Terminal   │◄───────►│  Bridge Core │◄───────►│  Claude.ai  │
│  (Running    │   WS    │  (Local)     │  HTTP   │  (Web UI)    │
│   Code)      │         │              │         │              │
└──────────────┘         └──────────────┘         └──────────────┘
Key Bridge Files
FilePurpose
bridgeMain.tsEntry point, initialization
remoteBridgeCore.tsCore polling and sync logic
bridgeMessaging.tsMessage routing
bridgeUI.tsUI coordination
initReplBridge.tsBridge-aware REPL init

Daemon Entry Point

File: src/daemon/main.ts

Launched via: claude daemon

Purpose

The daemon is a background supervisor that:

  • Manages persistent sessions
  • Spawns worker processes
  • Handles session recovery
  • Coordinates multiple clients
Architecture
Plain text
┌─────────────────────────────────────────┐
│           DAEMON SUPERVISOR             │
│              (daemon/main.ts)           │
├─────────────────────────────────────────┤
│  ┌─────────┐ ┌─────────┐ ┌─────────┐     │
│  │ Worker 1│ │ Worker 2│ │ Worker N│     │
│  │ (agent) │ │ (shell) │ │ (task)  │     │
│  └────┬────┘ └────┬────┘ └────┬────┘     │
│       └─────────────┴───────────┘         │
│              IPC / WebSocket             │
└─────────────────────────────────────────┘

Non-Interactive (Headless) Mode

Flow: cli.tsx → main.tsx → askNonInteractive()

Used for:

  • CI/CD pipelines
  • Scripts
  • SDK usage
  • Git hooks
Key Difference

No React/Ink UI. Uses direct stdout/stderr output.

TypeScript
// Interactive
await launchRepl({ ... })  // React + Ink

// Non-interactive
await askNonInteractive({ ... })  // Direct output

SDK Entry Point

File: src/entrypoints/sdk/

Exposes Claude Code as a programmatic API:

TypeScript
// Consumer code
import { ClaudeCodeSDK } from '@anthropic-ai/claude-code'

const claude = new ClaudeCodeSDK({
  apiKey: process.env.ANTHROPIC_API_KEY,
})

const result = await claude.run('Review this PR')

Initialization Phases

Understanding init order is crucial:

Plain text
Phase 1: CLI Parse (cli.tsx)
         ↓
Phase 2: Bootstrap (bootstrap/state.ts)
         ↓
Phase 3: Config Load (utils/config.ts)
         ↓
Phase 4: Auth (utils/auth.ts)
         ↓
Phase 5: Feature Flags (GrowthBook)
         ↓
Phase 6: State Init (state/AppState.tsx)
         ↓
Phase 7: UI Launch (launchRepl or non-interactive)

Key Concepts for Understanding Entrypoints

1. Feature Flags via feature()
TypeScript
import { feature } from 'bun:bundle'

// Build-time dead code elimination
if (feature('BRIDGE_MODE')) {
  // This code is only included if flag is enabled at build
}

feature() is a compile-time macro - not a runtime check!

2. Conditional Requires
TypeScript
// Lazy loading to break circular dependencies
const getTeammateUtils = () => require('./utils/teammate.js')

// Dead code elimination for ant-only features
const assistantModule = feature('KAIROS')
  ? require('./assistant/index.js')
  : null
3. Profile Checkpoints
TypeScript
profileCheckpoint('some_phase')
// ... do work ...
profileCheckpoint('some_phase_done')

// Later: profileReport() prints timings

Used to optimize startup performance.

4. Trust Check
TypeScript
checkHasTrustDialogAccepted()

Before full init, users must accept terms. Early exits if not trusted.


Common Entrypoint Patterns

Adding a New Subcommand
TypeScript
// In commands.ts (or commands/mycommand/index.ts)
const myCommand: Command = {
  type: 'prompt',
  name: 'mycommand',
  description: 'Does something cool',
  async getPromptForCommand(args, context) {
    return { messages: [{
      type: 'user',
      content: 'Execute mycommand with args: ' + args
    }]}
  }
}
Adding a New Flag
TypeScript
// In cli.tsx or main.tsx
program
  .option('--my-flag <value>', 'Description', 'default')

// Later:
const options = program.opts()
if (options.myFlag) {
  setMyFlagState(options.myFlag)
}

Debugging Entrypoints

Verbose Startup
Bash
claude --verbose

Shows profile checkpoints and init flow.

Profile Report
Bash
CLAUDE_CODE_PROFILE=1 claude

Prints detailed timing breakdown.

Debug Mode
Bash
claude --debug

Enables debug logging throughout.


Summary

Entry PointFileWhen Used
CLIcli.tsxPrimary entry
Mainmain.tsxFull initialization
Bridgebridge/bridgeMain.tsRemote control
Daemondaemon/main.tsBackground supervisor
SDKentrypoints/sdk/Programmatic API

The key insight: cli.tsx is the router, main.tsx is the application, and specialized entrypoints handle specific modes (bridge, daemon, headless).