模块依赖图全拆¶
重要性:⭐⭐⭐⭐⭐(理解模块关系——1726 个文件 + ~10+ 循环依赖 + 5+ lazy require 模式) 范围:
src/全部 1884 个 .ts/.tsx 文件 方法:grep 全部 import / require 模式 → 分类 → 找循环
1. 总体数据¶
src/ 文件数: 1884
含 import 文件数: 1726 (91%)
循环 require 模式: 10+ (跨多文件)
lazy require 模式: 5+ 主流
外部依赖: ~50+ 个 npm 包
关键观察: - 91% 文件有 import(几乎所有文件都依赖别人) - 9% 文件可能纯函数(constants/types)
2. 分层架构(推测)¶
┌─────────────────────────────────────────────┐
│ Layer 0: entry(main.tsx) │
│ - 协调整体启动 │
└────────────────────┬────────────────────────┘
│
┌────────────────────▼────────────────────────┐
│ Layer 1: launchers(replLauncher, cli/) │
│ - REPL / print 模式分发 │
└────────────────────┬────────────────────────┘
│
┌────────────────────▼────────────────────────┐
│ Layer 2: screens(REPL.tsx) │
│ - UI 编排(Hooks-first) │
└────────────────────┬────────────────────────┘
│
┌────────────────────▼────────────────────────┐
│ Layer 3: business(services/, tools/) │
│ - 业务实现(API, MCP, Tools, Auth) │
└────────────────────┬────────────────────────┘
│
┌────────────────────▼────────────────────────┐
│ Layer 4: state(state/AppStateStore, │
│ bootstrap/, services/policyLimits) │
│ - 跨组件状态 │
└────────────────────┬────────────────────────┘
│
┌────────────────────▼────────────────────────┐
│ Layer 5: utils/utils/utils │
│ - 纯函数(无状态) │
└─────────────────────────────────────────────┘
5 层架构 —— 依赖单向向下(理论上)。
3. 5+ 循环依赖(实测发现)¶
3.1 main.tsx → teammate.ts → AppState.tsx → main.tsx¶
// main.tsx (行 70-72)
const getTeammateUtils = () => require('./utils/teammate.js') as typeof import('./utils/teammate.js');
// 注释:
// Lazy require to avoid circular dependency: teammate.ts -> AppState.tsx -> ... -> main.tsx
循环链:
解决:getter 包 require —— 第一次调用才 require。
3.2 coordinatorModeModule 循环¶
// main.tsx (行 76)
const coordinatorModeModule = feature('COORDINATOR_MODE')
? require('./coordinator/coordinatorMode.js')
: null;
推测:
解决:feature() 编译时门控 + require 兜底。
3.3 assistantModule (KAIROS) 循环¶
// main.tsx (行 80-81)
const assistantModule = feature('KAIROS')
? require('./assistant/index.js')
: null;
const kairosGate = feature('KAIROS')
? require('./assistant/gate.js')
: null;
推测:
解决:同样 lazy require + feature gate。
3.4 autoModeStateModule (TRANSCRIPT_CLASSIFIER) 循环¶
// main.tsx (行 171)
const autoModeStateModule = feature('TRANSCRIPT_CLASSIFIER')
? require('./utils/permissions/autoModeState.js')
: null;
推测:
解决:同上。
3.5 BriefTool 循环¶
// 多个文件 (4 处)
} = require('../tools/BriefTool/prompt.js') as typeof import('../tools/BriefTool/prompt.js');
} = require('../tools/BriefTool/BriefTool.js') as typeof import('../tools/BriefTool/BriefTool.js');
推测:
解决:lazy require。
3.6 proactiveModule 循环¶
// 2 处
const proactiveModule = feature('PROACTIVE') || feature('KAIROS')
? require('../proactive/index.js')
: null;
推测:
解决:lazy require。
3.7 snipCompact 循环¶
} = require('./services/compact/snipCompact.js') as typeof import('./services/compact/snipCompact.js');
推测:
解决:lazy require。
3.8 extractMemories 循环¶
} = require('../services/extractMemories/extractMemories.js') as typeof import('../services/extractMemories/extractMemories.js');
推测:
解决:lazy require。
3.9 teamMemPaths 循环¶
推测:
解决:lazy require。
3.10 contextCollapse/persist 循环¶
require('../services/contextCollapse/persist.js') as typeof import('../services/contextCollapse/persist.js');
推测:
解决:lazy require。
4. 循环依赖的共同模式¶
所有循环都是 main.tsx → X → ... → main.tsx 或 REPL.tsx → X → ... → REPL.tsx。
原因: - main.tsx 是入口,被所有东西依赖(间接) - AppState.tsx 是状态中心,被所有东西依赖
解决套路:
// 模式 1: getter 包 require
const getX = () => require('./X.js') as typeof import('./X.js');
// 模式 2: feature gate 包 require
const x = feature('X') ? require('./X.js') : null;
// 模式 3: 用到时再 require(动态 import)
const { x } = await import('./X.js');
3 种模式都用 —— 项目对循环依赖有成熟方案。
5. 主要依赖方向¶
5.1 React/Ink 框架(被依赖最多)¶
~500+ 文件 import ink.js 或 React。
5.2 AppState(被广泛依赖)¶
~100+ 文件 用 useAppState。
5.3 utils(基础工具)¶
utils 198 个目录 —— "工具大杂烩"。
5.4 services(业务)¶
services 47 个子目录 —— 业务封装。
5.5 tools(工具)¶
tools 103 个子目录 —— 工具集。
6. 5 大耦合热点(推测)¶
6.1 state/AppStateStore.ts¶
被~100+ 文件用 useAppState。
耦合影响:改 store schema 影响 100+ 文件。
6.2 Tool.ts¶
所有 tool 都继承。
耦合影响:改 Tool 接口影响 100+ 工具。
6.3 services/api/claude.ts (3419 行)¶
所有 API 调用 走这里。
耦合影响:改 API 影响所有功能。
6.4 commands.ts (25185 字节)¶
所有命令 注册在这里。
耦合影响:改 commands 影响 REPL。
6.5 history.ts (14081 字节)¶
所有消息 走这里。
耦合影响:改 history 影响所有 UI。
7. 模块耦合度分类¶
| 类型 | 文件数 | 特征 |
|---|---|---|
| 中心模块 | ~10 | 100+ 文件 import |
| 业务模块 | ~50 | 10-50 文件 import |
| 工具模块 | ~200 | < 10 文件 import |
| 叶子模块 | ~1500 | 0 文件 import(被引用的末端) |
模块分布: - 中心:~10 - 业务:~50 - 工具:~200 - 叶子:~1500
典型 —— 中心少,工具多,叶子最多。
8. 依赖方向分析¶
8.1 严格单向¶
UI (components/, screens/)
↓ only imports
business (services/, tools/)
↓ only imports
state (state/)
↓ only imports
utils (utils/)
理想分层 —— 单向依赖。
8.2 实际违反¶
- main.tsx 入口依赖太多(god module)
- REPL.tsx 入口依赖太多(god component)
- hooks/ 双向引用(hooks 之间互相用)
实际 —— 入口文件"例外"。
9. 外部依赖(npm)¶
通过 grep 包名(推测):
- react, react-dom
- ink, @inkjs/*
- commander, @commander-js/extra-typings
- chalk
- lodash-es
- zod
- bun:bundle (Bun 特有)
- crypto, fs, path (Node 内置)
~30+ npm 外部包(推测)。
10. import 风格统计¶
10.1 ES import vs CJS require¶
~99% ES, ~1% CJS (lazy require)。
10.2 路径风格¶
import { x } from './x.js' // 相对
import { x } from '../utils/x.js' // 多级相对
import { x } from 'src/utils/x.js' // src-absolute (较少)
~95% 相对路径 —— 5% 用 src-absolute。
10.3 扩展名¶
~100% 写 .js —— 即使是 TS 文件(NodeNext 模块解析要求)。
11. 关键洞察¶
11.1 循环依赖是"演进必然"¶
中心模块(main.tsx, AppState)被广泛依赖 —— 循环不可避免。
11.2 Lazy require 是"解法"¶
3 种模式:getter / feature gate / dynamic import。
11.3 入口文件"违反"分层¶
main.tsx / REPL.tsx 是编排 —— 依赖所有层。
11.4 中心模块 10 个¶
~10 个文件被 100+ 文件依赖 —— 改时要小心。
11.5 业务服务 47 个¶
足够多 —— 业务领域清晰切分。
11.6 工具 198 个 vs 业务 47 个¶
4 倍工具 —— 反映项目对 helper 的偏好。
11.7 ES import 99%¶
现代化 —— 几乎没有 CJS(除 lazy require)。
11.8 .js 扩展名 100%¶
NodeNext 规范 —— 即使 TS 也写 .js。
12. 改进建议(如果重构)¶
12.1 拆 main.tsx¶
4683 行 → 拆成 subcommand 目录(已部分做)。
12.2 拆 REPL.tsx¶
5005 行 → 拆成 screens(已部分做)。
12.3 减少 utils/ 数量¶
198 个 → 合并相似工具。
12.4 引入 dependency-cruiser¶
工具自动检查循环 + 分层违规。
13. 阅读建议¶
- grep
require\(['\"]\./* —— 找所有 lazy require - 用 madge 或类似工具 —— 自动生成依赖图
- 看 state/AppStateStore.ts —— 中心模块
- 看 services/api/claude.ts —— 最大业务
- 看 utils/ —— 198 个工具分类
14. 与其他分析的关系¶
| 文件 | 关系 |
|---|---|
architecture-history.md |
演进历史(动态) |
extensibility.md |
扩展点 |
error-handling-overview.md |
错误依赖 |
performance-history.md |
性能影响 |