CC

ClaudeCode Source Analysis

模块拆解

模块

按职责和边界看模块,而不是按目录顺序看模块

命令、工具、查询、任务、权限、状态、扩展,这几类模块共同组成主骨架。真正需要理解的是“谁拥有决策权、谁只是装配器、谁承担副作用”。

本页回答什么问题

  • 命令系统和工具系统为什么要分开?
  • QueryEnginequery() 谁才是执行核心?
  • 任务系统和工具系统的边界在哪里?
  • 插件、MCP、skills 为什么不是一套统一扩展点?

模块 / 组件依赖图

这张图强调最重要的装配依赖和运行依赖,帮助判断改一个模块时最可能牵动哪里。它不是 import 全量图,而是架构层面的关键依赖图。

文件映射:src/utils/settings/*src/utils/permissions/*src/utils/plugins/*src/skills/loadSkillsDir.tssrc/commands.tssrc/Tool.tssrc/tools.tssrc/screens/REPL.tsxsrc/QueryEngine.tssrc/query.ts

关键观察:commands 和 tools 的扩展入口并不对称;插件和 skills 更偏向命令层,MCP 和 settings 更深地影响运行态与能力可见性。

命令系统

src/commands.ts 不是简单导出内建命令,而是一个 command aggregator。它会把 built-in commands、workflow commands、skills 生成的 prompt commands、plugin commands、dynamic commands 统一合并,再按 feature、可用性和可见性过滤。

  • 职责:为用户提供“显式操作入口”。
  • 边界:命令负责触发动作、改变模式、调用查询或应用行为,但不等于模型工具。
  • 隐式约束:新增命令不只是在目录里加文件,还要进入聚合、命名空间、可见性与帮助系统。
用户接口多来源合并availability 过滤

工具系统

src/tools.ts 定义模型可见的工具全集,并按 feature gate、环境、用户类型和启用条件决定最终暴露哪些工具。src/Tool.tsbuildTool() 会填入默认行为,例如 isConcurrencySafe = falseisReadOnly = false,这说明系统在默认值上更偏向保守而非乐观。

  • 职责:为模型提供“可执行能力面”。
  • 边界:工具不是 util 函数,而是受 schema、权限、并发和 telemetry 约束的协议对象。
  • 隐式约束:如果工具作者没有显式声明并发安全或只读性,系统会按更保守的策略处理。
模型接口上下文对象并发/权限敏感

查询执行层

src/QueryEngine.ts 是会话级 façade,负责 transcript、messages、usage、abort、session semantics;src/query.ts 是 turn 级共享内核,负责 memory prefetch、skill prefetch、context collapse、compact、budget、API 调用和 tool loop。这个划分是整个仓库最重要的职责边界之一。

关键结论:如果你把 QueryEngine 当成主执行器,会漏掉 REPL 直接调用 query() 的真实路径;如果你把 query() 当成唯一入口,又会看不到 headless/SDK 路径上的 transcript 和恢复语义。

任务与 agent

src/Task.ts 定义统一任务模型,src/tasks/* 提供 shell、local agent、remote agent、in-process teammate 等具体实现。src/tools/AgentTool/runAgent.ts 体现了这一层的复杂性:子 agent 并不是“起一个线程”,而是要装配技能、MCP、hook、transcript、任务上下文,再在结束时清理这些资源。

  • 职责:承载长生命周期、可观察、可取消、可能后台化的执行。
  • 边界:很多工具调用最终会生成任务,因此“工具层”和“任务层”不是替代关系,而是递进关系。

权限与安全

权限系统由 src/utils/permissions/*src/hooks/useCanUseTool.tsxsrc/components/permissions/* 共同组成。它不是单点判断,而是规则、classifier、hook、sandbox、UI prompt 叠加的判定管线。

  • 职责:把“可不可以执行”变成可解释、可治理的决策链。
  • 隐式约束:Bash 等敏感工具可能经过 speculative classifier 路径,说明判定不总是同步且不总在 UI 层发生。

状态与交互壳

AppStateAppStateStore 说明这里的状态不仅用于渲染,而是整个应用运行态的承载体。src/screens/REPL.tsx 则是最重要的集成壳:它把 prompt 提交、工具刷新、权限、消息、任务、通知、compact 和 session 恢复编织到一起。

插件 / MCP / Skills

  • 插件:pluginLoader.ts 负责安装、缓存、验证、marketplace 路径与版本目录;loadPluginCommands.ts 负责把 markdown command 装配进命令空间。
  • MCP:mcp/config.tsmcp/client.ts 负责配置合并、去重、连接、资源与工具发现。它更像外部能力协议。
  • Skills:loadSkillsDir.ts 基于 markdown/frontmatter 装配 prompt commands。它偏“流程与提示知识复用”,不是代码插件。
设计 rationale:三者拆开,是因为它们面对的问题不同。插件处理本地扩展分发,MCP 处理外部能力接入,skills 处理提示与流程复用。统一成一种机制反而会让能力边界更混乱。