整体结构
Claude Code CLI 更适合按“职责链”理解,而不是按目录树理解。你需要知道的是模块如何接力运行,而不是文件夹如何排布。
从启动入口一路走到输入、主循环、工具、状态与扩展层。
先识别主干,再区分扩展和条件接入能力。
更快判断一个功能应该落到命令、工具、服务还是 UI 层。
为什么这样设计阅读结构
这个仓库体量大、功能杂、扩展点多,如果直接按src/ 子目录平铺去读,会遇到三个问题:- 很难区分主干和扩展。很多目录存在,但运行时未必总会进入。
- 很难建立因果顺序。你知道某个文件存在,但不知道它何时、为何被调起。
- 很难判断修改落点。不了解上游入口和下游依赖,就无法准确定位改动面。
主线结构图
src/main.tsx 负责预取、初始化调度、命令注入和运行模式切换。
src/entrypoints/init.ts 负责配置、环境变量、网络代理、遥测与清理器准备。
src/utils/processUserInput/processUserInput.ts 把输入转成命令、消息或查询请求。
src/commands.ts 与 src/commands/ 管理 slash command 的注册与分发。
src/tools.ts、src/tools/、src/Tool.ts 管理模型可调用能力。
src/QueryEngine.ts 串联消息、模型、工具调用、权限反馈与输出结果。
src/components/、src/ink/、src/state/ 负责界面呈现与状态同步。
src/services/、src/bridge/、src/plugins/、src/skills/ 负责接入外部能力。
为什么主循环是 QueryEngine
很多初读者会把main.tsx 误认为“核心逻辑”,但它更像调度入口。真正承载一轮对话生命周期的是 src/QueryEngine.ts:- 它持有会话消息与文件状态缓存。
- 它决定什么时候调用模型、什么时候进入工具循环。
- 它衔接权限拒绝、结构化输出、状态记录等横切逻辑。
main.tsx 是程序入口,QueryEngine.ts 才是业务主循环。为什么命令和工具要分开看
commands.ts 和 tools.ts 经常同时出现,但两者面向的对象不同:- 命令系统面向用户输入与本地交互。
- 工具系统面向模型执行与能力暴露。
/命令、还是挂到 Tool、还是只是内部服务。