Data | 调用图¶
目的:理解"哪个函数被谁调用",便于改一处找所有影响点。 方法:从代码中提取的 import + 内部调用关系。
1. createStore 调用图¶
graph LR
main[main.tsx] -->|createStore| store[src/state/store.ts]
state[AppStateStore.ts] -->|类型| store
state[AppState.tsx] -->|getState/setState/subscribe| store
onChange[onChangeAppState.ts] -->|onChange 钩子| store
subgraph Consumers
REPL[screens/REPL.tsx] -->|useAppState| AppState[AppState.tsx]
onChange2[onChange] -->|setState| store
end
store --> subscribe[S subscribe]
store --> setState[S setState]
store --> getState[S getState]
2. findToolByName 调用图¶
graph LR
query[query.ts] -->|findToolByName| Tool[Tool.ts]
toolMatches[toolMatchesName] -->|内部| Tool
REPL[screens/REPL.tsx] -->|findToolByName| Tool
commands[commands.ts] -->|findToolByName| Tool
tools[tools.ts] -->|getTools 注册表| Tool
3. query() 调用图¶
graph LR
REPL[screens/REPL.tsx] -->|query| Q[query.ts]
Q -->|queryLoop| QL[queryLoop 内部]
QL -->|streamApi| API[services/api/claude.ts]
QL -->|tool.call| T[Tool.ts]
QL -->|canUseTool| Perm[utils/permissions]
QL -->|findToolByName| T2[Tool.ts]
QL -->|runAutoCompact| Compact[services/compact/]
QL -->|withRetry| Retry[services/api/withRetry.ts]
QL -->|normalizeMessagesForAPI| Utils[utils/messages.ts]
subgraph "QueryEngine"
QE[QueryEngine.ts] -->|内部调| Q
QE -->|ask| Caller[REPL/SDK 调用方]
end
4. createMCPConnection 调用图¶
graph LR
Init[entrypoints/init.ts] -->|加载 MCP 配置| MCPCfg[services/mcp/config.ts]
MCPCfg -->|addServer| Mgr[services/mcp/MCPConnectionManager.tsx]
Mgr -->|connect| T[Transport]
T -->|stdio| Stdio[stdio transport]
T -->|HTTP+SSE| HTTP[HTTP+SSE transport]
T -->|InProcess| InProc[InProcessTransport]
Mgr -->|initialize| H[handshake]
H -->|protocolVersion| M[MCP 协议]
Mgr -->|register| Reg[连接池]
Tool[tools/MCPTool/MCPTool.tsx] -->|callTool| Mgr
REPL[screens/REPL.tsx] -->|useManageMCPConnections| Hooks[services/mcp/useManageMCPConnections.ts]
Hooks -->|addServer/removeServer| Mgr
5. BashTool.call 调用图¶
graph LR
query[query.ts] -->|tool.call| BT[tools/BashTool/BashTool.tsx]
BT -->|validate| BV[validate]
BT -->|classifyCommand| CS[commandSemantics.ts]
BT -->|pathValidation| PV[pathValidation.ts]
BT -->|bashPermissions| BP[bashPermissions.ts]
BT -->|bashSecurity| BS[bashSecurity.ts]
BT -->|destructiveCommandWarning| DCW[destructiveCommandWarning.ts]
BT -->|shouldUseSandbox| SUS[shouldUseSandbox.ts]
BT -->|readOnlyValidation| RV[readOnlyValidation.ts]
BT -->|modeValidation| MV[modeValidation.ts]
BT -->|canUseTool| Perm[utils/permissions]
BT -->|spawn| OS[OS shell]
OS -->|stdout| BT
OS -->|stderr| BT
OS -->|exit code| BT
BT -->|UI 渲染| UI[tools/BashTool/UI.tsx]
6. 启动期调用图¶
graph LR
Bun[Bun Runtime] -->|加载| CLI[entrypoints/cli.tsx]
CLI -->|argv 解析| Argv[--version / --dump-system-prompt / etc]
CLI -->|动态 import| Main[main.tsx]
Main -->|prefetch| Pro[utils/startupProfiler.ts]
Main -->|prefetch| MDM[utils/settings/mdm/rawRead.ts]
Main -->|prefetch| KC[utils/secureStorage/keychainPrefetch.ts]
Main -->|init| Init[entrypoints/init.ts]
Init -->|loadGlobalConfig| Cfg[utils/config.ts]
Init -->|加载 MCP| MCPCfg[services/mcp/config.ts]
Init -->|initializeTelemetry| Tel[telemetry]
Init -->|startBackgroundHousekeeping| HK[housekeeping]
Main -->|launchRepl| Repl[replLauncher.tsx]
Repl -->|<REPL />| REPL[screens/REPL.tsx]
REPL -->|useAppState| State[state/AppState.tsx]
REPL -->|useInput| Ink[ink/hooks/use-input.ts]
REPL -->|85 hooks| Hooks[hooks/]
7. addToHistory 调用图¶
graph LR
REPL[screens/REPL.tsx] -->|addToHistory| Hist[history.ts]
PI[components/PromptInput/] -->|addToHistory| Hist
Hist -->|解析 references| Refs[parseReferences]
Hist -->|展开粘贴文本| Expand[expandPastedTextRefs]
Hist -->|写历史| Disk[~/.claude/history]
8. setCostStateForRestore 调用图¶
graph LR
Resume[commands/resume] -->|setCostStateForRestore| Cost[cost-tracker.ts]
Cost -->|getStoredSessionCosts| Disk[sessionStorage]
Cost -->|resetCostState| Internal[内部]
Cost -->|saveCurrentSessionCosts| Disk
9. 键位处理调用图¶
graph LR
Ink[ink/hooks/use-input.ts] -->|raw key| Dispatch[事件分发]
Dispatch -->|single char| L3[use-input 兜底]
Dispatch -->|chord| L1[useGlobalKeybindings]
L1 -->|Ctrl+C| Cancel[useCancelRequest]
L1 -->|Ctrl+L| Clear[清屏]
L1 -->|Ctrl+O| Full[全屏切换]
L1 -->|Ctrl+R| Search[历史搜索]
L2[useCommandKeybindings] -->|/command| Cmd[命令处理]
L0a[PromptInput 内部 use-input] -->|Esc| Delete[删字符]
L0a -->|Enter| Submit[提交]
L0a -->|↑↓| History[历史导航]
L0b[FuzzyPicker 内部 use-input] -->|Esc| Cancel
L0b -->|Enter| Select[选择]
L0c[Tabs 内部 use-input] -->|←→| Tab[切 tab]
10. 设置加载调用图¶
graph LR
Init[entrypoints/init.ts] -->|getGlobalConfig| Cfg[utils/config.ts]
Cfg -->|readFileSync| UserCfg[~/.claude/settings.json]
Cfg -->|readFileSync| ProjCfg[./.claude/settings.json]
Cfg -->|readFileSync| LocalCfg[./.claude/settings.local.json]
Cfg -->|合并| Merged[merged settings]
Merged -->|saveGlobalConfig| Disk[~/.claude/settings.json]
11. 关键洞察¶
11.1 调用图暴露"中心节点"¶
query.ts 是调用中心(被 5+ 个地方调用,自身调用 10+ 个东西)。
Tool.ts 是工具中心(被 30+ 个工具实现 + 5+ 个系统模块调用)。
改这两处影响最大。
11.2 调用图揭示"性能瓶颈"¶
BashTool.call调用 10+ 个校验/安全函数 → 可能慢BashParser.ts是 N-API 重操作 → 必须缓存Markdown.tsx的 marked.lexer → 有 LRU 缓存
11.3 启动期"预取"是显式的¶
startMdmRawRead、startKeychainPrefetch 都在 main.tsx 头部。
这意味着"启动期的代码模式是固定的"。
11.4 键位分层的物理意义¶
L1 (Global) → L2 (Command) → L3 (useInput) → L0 (Component)
这是 4 层职责分离,不是任意设计。