📄

Request My Resume

Thank you for your interest! To receive my resume, please reach out to me through any of the following channels:

Claude Code Source Code Walkthrough 01: From cli.tsx to main.tsx

Digital Strategy Review | 2026

Claude Code Source Code Walkthrough 01 | From cli.tsx to main.tsx: Understanding System Assembly

By Uncle Fruit · Reading Time / 8 Min

Claude Code Startup Assembly Visual

Preface

In this article, I want to thoroughly explain the startup chain. By clearly understanding the entry point and the assembly process first, we can avoid getting lost in local details when we later dive into query.ts, AgentTool, and REPL.tsx. The difficulty in reading Claude Code isn’t the number of files, but the fact that it is a runtime assembly process from the very first line of code.

01

From cli.tsx to main.tsx: How the System Starts

This article answers only one question: How does the Claude Code system evolve from a single command into a fully assembled runtime?

Without establishing this panoramic view, it is easy to get bogged down in local details when reading query.ts, AgentTool, or REPL.tsx. This is not a typical CLI that simply “parses commands and executes business logic”; it is an agent runtime with multiple operating modes, various execution backends, and complex capability-pruning logic.

02

I. A Look at src/entrypoints/cli.tsx

The role of src/entrypoints/cli.tsx is not just a “thin wrapper.” It acts as the first layer of the scheduler.

The most important fact here is that it does not import the entire system immediately. Instead, it performs a round of lightweight, performance-sensitive “fast-path” routing.

You can see from the source code that it clearly pursues two goals:

01 Do not load the full runtime for paths that do not require it.

02 Fork the entry points for different modes as early as possible.

1. Why use a fast-path here?

cli.tsx handles many paths that can return early, such as:

--version

--dump-system-prompt

--daemon-worker

remote-control / remote / sync / bridge

daemon

ps / logs / attach / kill / --bg

• Template-based commands

environment-runner

self-hosted-runner

--worktree --tmux related paths

This means that, architecturally, Claude Code acknowledges one thing:

“Claude Code” is not a single execution form, but a multi-entry system sharing a core set of capabilities.

In other words, the command-line foreground REPL is just one type of entry point; the background worker, bridge, daemon, and remote execution environments are essentially part of the same ecosystem.

2. Why use dynamic imports?

The heavy use of await import(...) here isn’t just a coding style; it is a deliberate startup control mechanism:

• Dependencies are only loaded when a specific branch is entered.

• It reduces module evaluation costs for common paths.

• It leaves clear boundaries for subsequent feature gates.

This is fundamentally different from many CLI projects that “import all modules first, then decide logic later.” Claude Code is more like a multi-mode runtime launcher.

3. What this means for the Agent system

We will see later that the agent has many execution forms:

• Local foreground

• Local background

• In-process teammate

• Tmux teammate

• Worktree agent

• Remote agent

If the entry layer didn’t separate these operating modes at the start, the system complexity would explode. Therefore, the core value of cli.tsx isn’t just “starting faster,” but clearly defining the system boundaries.

03

II. src/main.tsx is a Runtime Assembler, Not a Page Entry

main.tsx is large, but it shouldn’t be read as “one big component.” More accurately, it is the Claude Code runtime assembler.

It is responsible for assembling the following:

• config / settings / managed settings

• auth / OAuth / subscription / org policy

• analytics / GrowthBook / feature gates

• model selection and capability assessment

• MCP / plugin / skills

• tools / commands / agents

• store / AppState

• Final entry into a specific REPL mode

Its size is not due to confused responsibilities, but because it shoulders the master control duty of “assembling a runnable session.”

Claude Code Startup Flow Diagram

Startup is not a single-point execution, but a process of routing, assembly, and capability wiring.

04

III. The Five Stages of the Startup Process

I suggest understanding the startup path of main.tsx in five stages.

Stage 1: Warming up the slow path

At the very beginning of the file, several experienced steps are taken:

profileCheckpoint(...)

• Early initiation of MDM reading

• Early initiation of keychain prefetch

The intent here is clear: the author knows exactly which operations slow down the initial screen, so they move them forward and parallelize them.

This “warm-up” is not just a nice-to-have; it is a critical optimization for interactive systems. Because Claude Code must enter a high-interaction state immediately upon startup, it cannot afford to initialize slowly like a background script.

Stage 2: Initializing environment and policies

Before entering the main logic, the system gradually pulls up:

• Configuration and environment variable mapping

• Managed settings

• Remote managed settings

• Policy limits

• Auth / bootstrap information

• GrowthBook

• Analytics gate

This step determines what capabilities the current user, organization, and environment are allowed to see.

This is crucial because, in Claude Code, tools, agents, remote capabilities, bridges, and auto-mode are not exposed by default. They must pass through this layer of policy and configuration assessment.

Stage 3: Assembling the capability surface

Next, it assembles:

• commands

• tools

• agent definitions

• MCP clients / resources / commands

• plugins

• skills

The essence of this step is not “registering functions,” but forming a capability snapshot of the current session.

The getTools(...) layer is particularly critical. Claude Code does not treat tools as static SDK functions, but as a dynamic execution surface pruned by environment, permissions, modes, and feature gates.

Stage 4: Establishing the state store

main.tsx creates the store and prepares the initial state required for the REPL. This is the prerequisite for AppState to carry tasks, notifications, MCP, plugins, viewing-agents, and the permission queue.

In other words, this is not just “initializing React state,” but creating a session-level runtime state container.

Stage 5: Entering the REPL

Finally, the system enters the launchRepl(...) path based on various prerequisites.

This shows that the REPL is not a single page, but a unified interactive stage that accepts various startup results, such as:

• Normal local session

• Resumed session

• Remote viewer

• Foreground control surface for different modes

05

IV. main.tsx solves “Assembly,” not just “Startup”

If we summarize the responsibility of main.tsx in one sentence:

Before entering the first round of user interaction, it assembles the complete world model for the current session.

This world model includes:

• Who is the current user?

• What is the current model?

• What is the current permission mode?

• Which tools are visible?

• Which agents can be loaded?

• Are there any MCP / plugin / remote bridges?

• In what posture should the REPL start?

Why is this important? Because the subsequent query loop, tool orchestration, and AgentTool all assume these basic conditions have already been set.

In other words, main.tsx is the “pre-evaluator” for the entire system.

06

V. Architecturally, cli.tsx + main.tsx establish three boundaries

Together, these two files establish three important boundaries for the entire system.

Boundary 1: Operating mode boundary

cli.tsx decides which entry path you take:

• Lightweight command

• Daemon/bridge/background

• Full interactive runtime

Boundary 2: Capability boundary

main.tsx decides what this session can see:

• Which tools

• Which commands

• Which agents

• Which plugin / MCP capabilities

Boundary 3: Interaction boundary

launchRepl(...) decides how the user finally enters the system:

• Local foreground

• Resumed session

• Remote observation/control

From the source code structure, these two layers are not “startup scripts,” but the first line of defense that constrains the complex system that follows.

07

VI. Key points to focus on

If you intend to delve deeper into these two files, I suggest focusing on these questions:

01 Which paths are truncated early in cli.tsx, and why?

02 Which configurations must be completed early in main.tsx to prevent capability exposure errors later?

03 At which stage are getTools(...), agent definitions, MCP, and plugins assembled?

04 Why are there so many launchRepl(...) calls in main.tsx?

05 Why does it perform so many policy and capability assessments before the REPL starts?

Once you have thought through these five questions, you won’t mistake query.ts for a simple “chat loop” when you read it later.

08

VII. The Startup Flow at a Glance

Mermaid Chart 1

09

VIII. Conclusion

cli.tsx and main.tsx work together not just to “run the program,” but to:

• Split operating modes at the entry layer.

• Evaluate current session capabilities at the main assembly layer.

• Hand over the fully assembled runtime to the REPL.

This is the prerequisite for the entire agent runtime that follows. Because everything you read about the complexity later is built on the assumption that “the current world has already been assembled.”

The next article will enter the true heart of this world: query.ts, tools.ts, and toolOrchestration.ts.

Mr. Guo Logo

© 2026 Mr'Guo

Twitter Github WeChat