mirror of
https://github.com/roger2ai/Claude-Code-Compiled.git
synced 2026-05-08 15:57:32 +08:00
- Move all .md documentation into docs/ directory - Rewrite README.md with English documentation covering: - All 22 missing source stubs added - Source code fixes (useEffectEvent, version check, auth, sandbox-runtime) - Bun compatibility shims (macro, bun-bundle) - 28 missing npm dependencies - Build and run instructions - Remove dist/ from tracking (users compile themselves)
359 lines
17 KiB
Markdown
359 lines
17 KiB
Markdown
# Claude Code 重构可行性评估
|
||
|
||
> 评估日期:2026-03-31
|
||
> 基于 7 份架构文档 + 源码静态分析
|
||
> 项目规模:1,886 源文件,512,670 行 TypeScript/TSX
|
||
|
||
---
|
||
|
||
## 1. 架构耦合度评估
|
||
|
||
### 1.1 God Modules(巨型模块)
|
||
|
||
| 文件 | 行数 | 被引用数 | 导出数 | 问题 |
|
||
|------|------|----------|--------|------|
|
||
| `bootstrap/state.ts` | 1,758 | **251** | **215** | 经典 God Module — 全局状态容器,session/cost/duration/cwd 全塞一个文件 |
|
||
| `utils/messages.ts` | 5,512 | 108 | 80+ | 消息常量 + 工具函数混杂,5500 行纯工具文件 |
|
||
| `utils/sessionStorage.ts` | 5,105 | — | — | 会话存储逻辑臃肿 |
|
||
| `utils/hooks.ts` | 5,022 | — | — | 与 React hooks 概念冲突(在 utils/ 下) |
|
||
| `utils/attachments.ts` | 3,997 | — | — | 附件处理逻辑过于集中 |
|
||
| `Tool.js` | ~792 | **259** | — | 工具接口定义被 259 个文件引用,变更成本极高 |
|
||
| `state/AppState.ts` | 1,190 | **171** | — | 应用状态类型 + store 混合 |
|
||
| `utils/config.ts` | 1,817 | **129** | — | 配置读写 + 全局缓存混杂 |
|
||
|
||
**关键判断:** `bootstrap/state.ts` 是最严重的耦合瓶颈。215 个导出、251 个消费者,任何修改都可能波及半个代码库。它本质上是一个伪装成模块的全局变量空间。
|
||
|
||
### 1.2 巨型文件
|
||
|
||
| 文件 | 行数 | 职责 | 问题 |
|
||
|------|------|------|------|
|
||
| `cli/print.ts` | 5,594 | 非交互输出模式 | 单文件 5500+ 行,职责不清 |
|
||
| `screens/REPL.tsx` | 5,005 | 主交互循环 | 244 个 import,是项目中 import 最多的文件 |
|
||
| `main.tsx` | 4,683 | CLI 入口 | 164 个 import,初始化 + 参数解析 + 会话管理全混 |
|
||
| `utils/bash/bashParser.ts` | 4,436 | Bash 解析 | 单一职责但体积过大 |
|
||
| `services/api/claude.ts` | 3,419 | API 客户端 | API 调用 + 流处理 + 重试 + token 管理 |
|
||
| `services/mcp/client.ts` | 3,348 | MCP 客户端 | 协议 + 连接 + 工具发现 + 资源管理 |
|
||
| `utils/plugins/pluginLoader.ts` | 3,302 | 插件加载 | 安装 + 验证 + 加载 + 版本管理 |
|
||
| `commands/insights.ts` | 3,200 | Insights 命令 | 单命令文件过大 |
|
||
| `bridge/bridgeMain.ts` | 2,999 | Bridge 主循环 | IDE 集成核心,耦合多协议 |
|
||
|
||
### 1.3 循环依赖与耦合热点
|
||
|
||
#### 确认的高耦合区域
|
||
|
||
```
|
||
bootstrap/state.ts ←——→ 251 个文件(星型拓扑,所有东西都连它)
|
||
↑
|
||
├── REPL.tsx (直接引用多个 state getter/setter)
|
||
├── main.tsx (直接引用多个 state getter/setter)
|
||
├── QueryEngine.ts
|
||
├── 几乎所有 commands/
|
||
├── 几乎所有 tools/
|
||
└── 大部分 hooks/
|
||
```
|
||
|
||
#### 潜在循环依赖
|
||
|
||
1. **`tools.ts` ↔ `commands.ts`**:tools.ts 不直接引用 commands.ts,但 QueryEngine.ts 同时引用两者,形成三角耦合
|
||
2. **`REPL.tsx` ↔ 多个 hooks**:REPL 导入 244 个模块,多个 hooks 又依赖 REPL 暴露的 context,形成隐式循环
|
||
3. **`permissions/` 跨层耦合**:权限逻辑分散在 `utils/permissions/`(24 文件)、`tools/BashTool/bashPermissions.ts`、`components/permissions/`(77 文件)、`hooks/toolPermission/` 四个位置
|
||
|
||
### 1.4 依赖扇出(Fan-out)热力图
|
||
|
||
```
|
||
bootstrap/state.ts ████████████████████████████ 251 文件
|
||
Tool.js ██████████████████████████ 259 文件
|
||
utils/config.ts ████████████████ 129 文件
|
||
AppState ████████████████████ 171 文件
|
||
utils/messages.ts ████████████ 108 文件
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 重构优先级矩阵(影响度 × 可行性)
|
||
|
||
```
|
||
高可行性 ─────────────────── 低可行性
|
||
┌─────────────────┬──────────────────┐
|
||
│ │ │
|
||
高 │ ★ P0 立即做 │ ★ P1 规划做 │
|
||
影 │ │ │
|
||
响 │ ① 拆分 bootstrap │ ④ REPL.tsx 拆分 │
|
||
度 │ /state.ts │ (5005 行) │
|
||
│ │ │
|
||
│ ② 提取权限模块 │ ⑤ main.tsx 拆分 │
|
||
│ (跨 4 层) │ (4683 行) │
|
||
│ │ │
|
||
│ ③ utils/ 整理 │ ⑥ 工具系统重构 │
|
||
│ (清理巨型文件) │ (42 工具统一) │
|
||
│ │ │
|
||
├─────────────────┼──────────────────┤
|
||
│ │ │
|
||
低 │ ★ P2 随时做 │ ★ P3 长期目标 │
|
||
影 │ │ │
|
||
响 │ ⑦ BashTool/PS │ ⑧ Bridge/Remote │
|
||
度 │ 代码去重 │ 解耦 │
|
||
│ │ │
|
||
│ ⑨ 组件层 >800行 │ ⑩ 插件系统重构 │
|
||
│ 文件拆分 │ (3302 行加载器) │
|
||
│ │ │
|
||
└─────────────────┴──────────────────┘
|
||
```
|
||
|
||
### 优先级详情
|
||
|
||
| # | 项目 | 影响 | 可行 | 理由 |
|
||
|---|------|------|------|------|
|
||
| ① | 拆分 `bootstrap/state.ts` | 🔴 极高 | 🟢 高 | 按领域拆成 6-8 个子模块(session, cost, cwd, duration, tools, hooks),251 个引用点可通过 barrel export 过渡 |
|
||
| ② | 提取权限模块 | 🔴 高 | 🟡 中 | 当前跨 4 个目录,需要先统一接口,再迁移,逐步替换 |
|
||
| ③ | 清理 utils/ 巨型文件 | 🟡 中 | 🟢 高 | messages.ts / sessionStorage.ts / hooks.ts 各 5000+ 行,按职责拆分 |
|
||
| ④ | REPL.tsx 拆分 | 🔴 高 | 🔴 低 | 244 个 import,高度耦合 UI + 业务逻辑,需要先抽取业务逻辑层 |
|
||
| ⑤ | main.tsx 拆分 | 🔴 高 | 🔴 低 | 4683 行初始化 + CLI 解析混杂,Commander.js 定义可提取 |
|
||
| ⑥ | 工具系统统一 | 🟡 中 | 🔴 低 | 42 个工具接口已统一,但权限检查链分散 |
|
||
| ⑦ | BashTool/PS 去重 | 🟢 低 | 🟢 高 | 5706 行 readOnlyValidation 有明显重复,可提取共享层 |
|
||
| ⑧ | Bridge/Remote 解耦 | 🟡 中 | 🔴 低 | 涉及 WebSocket/JSON-RPC 协议层,需谨慎 |
|
||
| ⑨ | 大组件拆分 | 🟢 低 | 🟢 高 | PromptInput(2338), Config(1821) 等可直接拆 |
|
||
| ⑩ | 插件系统重构 | 🟡 中 | 🔴 低 | 3302 行加载器 + 2643 行市场管理器,复杂度高 |
|
||
|
||
---
|
||
|
||
## 3. 模块化拆分方案
|
||
|
||
### 3.1 Phase 1: `bootstrap/state.ts` 拆分(立即开始)
|
||
|
||
**现状:** 1 文件,215 导出,251 个引用者
|
||
|
||
**目标拆分:**
|
||
|
||
```
|
||
bootstrap/
|
||
├── state.ts ← barrel re-export(保持兼容)
|
||
├── session/
|
||
│ └── sessionState.ts ← getSessionId, switchSession, parent session
|
||
├── cost/
|
||
│ └── costState.ts ← totalCost, totalDuration, API duration
|
||
├── cwd/
|
||
│ └── cwdState.ts ← getOriginalCwd, setProjectRoot, getCwdState
|
||
├── tools/
|
||
│ └── toolState.ts ← turnToolDuration, turnHookDuration, counters
|
||
├── tokens/
|
||
│ └── tokenState.ts ← token budget, turn output tokens
|
||
└── runtime/
|
||
└── runtimeState.ts ← session hooks, direct connect, speculation
|
||
```
|
||
|
||
**策略:**
|
||
1. 创建子模块,从 state.ts 导出
|
||
2. state.ts 变为 barrel file(`export * from './session/sessionState.js'`)
|
||
3. 逐步将消费者迁移到直接导入子模块
|
||
4. 最终废弃 barrel file
|
||
|
||
**风险:** 低。barrel re-export 保证向后兼容。
|
||
|
||
### 3.2 Phase 2: 权限系统统一(2-4 周)
|
||
|
||
**现状:** 4 个位置分散实现
|
||
|
||
```
|
||
当前:
|
||
utils/permissions/ (24 files) — 引擎核心
|
||
tools/BashTool/bashPermissions.ts — Bash 专用
|
||
tools/PowerShellTool/powershellPermissions.ts — PS 专用
|
||
components/permissions/ (77 files) — UI 组件
|
||
hooks/toolPermission/ (4 files) — React hooks
|
||
|
||
目标:
|
||
core/permissions/
|
||
├── engine.ts ← 统一权限判断引擎
|
||
├── rules.ts ← 规则匹配
|
||
├── modes.ts ← 模式管理
|
||
├── classifiers.ts ← AI 分类器
|
||
└── types.ts ← 统一类型
|
||
|
||
tools/*/ ← 各工具只保留 tool-specific 逻辑
|
||
components/permissions/ ← 不变,依赖 core/permissions
|
||
hooks/toolPermission/ ← 不变,依赖 core/permissions
|
||
```
|
||
|
||
### 3.3 Phase 3: REPL.tsx 拆分(4-8 周)
|
||
|
||
**原则:** 先抽业务逻辑,再动 UI 组件
|
||
|
||
```
|
||
当前: screens/REPL.tsx (5005 行, 244 imports)
|
||
|
||
目标:
|
||
screens/
|
||
├── REPL.tsx ← 纯 UI 组合 (~1500 行)
|
||
├── useReplSession.ts ← 会话生命周期管理
|
||
├── useReplInput.ts ← 输入处理(从 244 import 中抽取)
|
||
├── useReplCommands.ts ← 命令调度
|
||
└── useReplQuery.ts ← 查询执行编排
|
||
|
||
services/repl/
|
||
├── queryOrchestrator.ts ← 查询编排(当前 REPL 中的 query 逻辑)
|
||
├── sessionManager.ts ← 会话管理
|
||
└── inputProcessor.ts ← 输入分类处理
|
||
```
|
||
|
||
**关键前置条件:** ① 已完成(bootstrap/state 拆分减少直接状态操作)
|
||
|
||
### 3.4 Phase 4: main.tsx 拆分
|
||
|
||
```
|
||
当前: main.tsx (4683 行)
|
||
|
||
目标:
|
||
main.tsx ← 入口 + 路由分发 (~800 行)
|
||
cli/
|
||
├── commanderSetup.ts ← Commander.js 配置 (~1500 行)
|
||
├── initialization.ts ← init 流程 (~800 行)
|
||
├── sessionLauncher.ts ← 会话启动分支 (~600 行)
|
||
└── urlHandlers.ts ← URL/deep link 处理 (~500 行)
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 技术债务识别
|
||
|
||
### 4.1 代码异味
|
||
|
||
| 异味 | 严重度 | 位置 | 说明 |
|
||
|------|--------|------|------|
|
||
| **God Module** | 🔴 严重 | `bootstrap/state.ts` | 215 导出,251 消费者,全局状态倾倒场 |
|
||
| **Blob** | 🔴 严重 | `REPL.tsx`, `main.tsx` | 5000+ 行单文件,违反 SRP |
|
||
| **Feature Envy** | 🟡 中等 | `utils/hooks.ts` | 5022 行工具函数文件名为 "hooks",但不是 React hooks |
|
||
| **Shotgun Surgery** | 🔴 严重 | 权限系统 | 改一个权限逻辑要改 4 个目录 |
|
||
| **Divergent Change** | 🟡 中等 | `utils/messages.ts` | 5512 行,每次修改可能触及不同职责 |
|
||
| **Data Clumps** | 🟡 中等 | `Tool.ts` + `AppState` | session/cwd/model 经常一起传递但没有组合类型 |
|
||
|
||
### 4.2 反模式
|
||
|
||
| 反模式 | 位置 | 说明 |
|
||
|--------|------|------|
|
||
| **全局状态滥用** | `bootstrap/state.ts` | 215 个 getter/setter 实质是全局变量,无依赖注入,不可测试 |
|
||
| **隐式依赖** | `REPL.tsx` | 244 个 import 使得组件无法独立测试或复用 |
|
||
| **跨层耦合** | 权限系统 | 业务逻辑(utils/permissions)、UI(components/permissions)、Hooks(hooks/toolPermission)、工具级(tools/BashTool/bashPermissions)四层互相引用 |
|
||
| **重复实现** | BashTool ↔ PowerShellTool | readOnlyValidation 两个文件各 ~1900 行,逻辑高度相似但独立实现 |
|
||
| **命名混淆** | `utils/hooks.ts` | 不是 React hooks,是通用工具函数,与 `hooks/` 目录产生歧义 |
|
||
|
||
### 4.3 动态导入使用评估
|
||
|
||
**当前状态:** 302 个 `await import()` + 277 个 `require()` + 960 个 `feature()` 调用
|
||
|
||
**评估:** 动态导入使用**已较充分**,但存在不一致:
|
||
|
||
- ✅ `main.tsx` 中重型模块(OpenTelemetry, gRPC, print.ts)已做延迟加载
|
||
- ✅ `feature('...')` 用于构建时死码消除,覆盖 12+ feature flags
|
||
- ⚠️ `REPL.tsx` 仅 4 处动态 import,大部分依赖是静态的
|
||
- ⚠️ `commands.ts` 静态导入所有 60+ 命令,应改为动态加载
|
||
- ❌ `tools.ts` 静态导入 42 个工具,启动时全部加载
|
||
|
||
**建议:** commands.ts 和 tools.ts 应按需动态导入,可减少初始 bundle ~30%。
|
||
|
||
### 4.4 类型安全问题
|
||
|
||
| 问题 | 位置 | 说明 |
|
||
|------|------|------|
|
||
| `any` 类型 | 多处 | permission result、tool output 等处有 `any` 残留 |
|
||
| 状态类型弱 | `bootstrap/state.ts` | 使用 module-level 变量而非 typed store,缺少变更追踪 |
|
||
| 条件类型分支 | `Command` 联合类型 | prompt/local/local-jsx 三种分支,模式匹配不完整 |
|
||
|
||
---
|
||
|
||
## 5. 重构路径建议
|
||
|
||
### 总体路线图
|
||
|
||
```
|
||
Phase 1 (1-2 周) Phase 2 (2-4 周) Phase 3 (4-8 周)
|
||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||
│ bootstrap/ │ │ 权限系统统一 │ │ REPL.tsx │
|
||
│ state.ts 拆分 │ ──────→ │ │ ──────→ │ 业务逻辑抽取 │
|
||
│ │ │ 核心引擎提取 │ │ │
|
||
└──────────────┘ └──────────────┘ └──────────────┘
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
Phase 4 (6-10 周) Phase 5 (8-12 周) Phase 6 (持续)
|
||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||
│ main.tsx 拆分 │ │ commands.ts │ │ 工具系统优化 │
|
||
│ │ ──────→ │ tools.ts │ ──────→ │ 组件层拆分 │
|
||
│ CLI 解析分离 │ │ 动态加载改造 │ │ 测试覆盖补全 │
|
||
└──────────────┘ └──────────────┘ └──────────────┘
|
||
```
|
||
|
||
### Phase 1 详细步骤(立即可执行)
|
||
|
||
1. **创建子模块目录结构**(30 分钟)
|
||
```
|
||
mkdir -p bootstrap/{session,cost,cwd,tools,tokens,runtime}
|
||
```
|
||
|
||
2. **提取 `sessionState.ts`**(2 小时)
|
||
- 移动 `getSessionId`, `switchSession`, `parentSession*` 等 ~25 个导出
|
||
- 在 `state.ts` 中添加 `export * from './session/sessionState.js'`
|
||
|
||
3. **提取 `costState.ts`**(2 小时)
|
||
- 移动 cost/duration 相关 ~30 个导出
|
||
|
||
4. **提取 `cwdState.ts`**(1 小时)
|
||
- 移动 cwd/project 相关 ~15 个导出
|
||
|
||
5. **提取 `toolState.ts`**(2 小时)
|
||
- 移动 tool duration/counter 相关 ~40 个导出
|
||
|
||
6. **提取 `tokenState.ts`**(1 小时)
|
||
- 移动 token budget 相关 ~20 个导出
|
||
|
||
7. **提取 `runtimeState.ts`**(2 小时)
|
||
- 移动 hooks/speculation/directConnect 等 ~85 个导出
|
||
|
||
8. **验证 barrel file 兼容性**(1 小时)
|
||
- 确保所有 251 个消费者的 import 路径不变
|
||
- 运行类型检查 + 单元测试
|
||
|
||
### Phase 2: 权限系统统一(关键路径)
|
||
|
||
**前置条件:** Phase 1 完成
|
||
|
||
1. 定义 `core/permissions/types.ts` — 统一 PermissionResult, PermissionMode 等类型
|
||
2. 实现 `core/permissions/engine.ts` — 通用权限判断引擎
|
||
3. 将 `utils/permissions/` (24 文件) 迁移到 `core/permissions/`
|
||
4. 创建 adapter 层让 BashTool/PowerShellTool 使用统一引擎
|
||
5. 迁移 `components/permissions/` 依赖到 `core/permissions/`
|
||
6. 迁移 `hooks/toolPermission/` 依赖到 `core/permissions/`
|
||
|
||
### 测试策略
|
||
|
||
每个 Phase 完成后必须验证:
|
||
- ✅ TypeScript 编译无新增错误
|
||
- ✅ 现有单元测试全部通过
|
||
- ✅ 启动时间无回退(`main.tsx` 的 profileCheckpoint 可用于测量)
|
||
- ✅ Bundle 大小无显著增长
|
||
|
||
---
|
||
|
||
## 6. 风险评估
|
||
|
||
| 风险 | 概率 | 影响 | 缓解 |
|
||
|------|------|------|------|
|
||
| barrel file 过渡期引入循环依赖 | 中 | 中 | 严格使用 `export * from`,不引入新逻辑 |
|
||
| REPL 拆分破坏流式渲染 | 高 | 高 | 以 hook 边界拆分,不动渲染层 |
|
||
| 权限系统迁移遗漏 | 中 | 极高 | 端到端测试覆盖 + 灰度 |
|
||
| 动态加载改造影响启动时间 | 低 | 中 | 保留 profileCheckpoint 监控 |
|
||
| 多 provider(Bedrock/Vertex)兼容性 | 低 | 高 | 每个 provider 独立测试 |
|
||
|
||
---
|
||
|
||
## 7. 结论
|
||
|
||
Claude Code 的架构在**工具系统**(`buildTool()` 接口统一)和**延迟加载**(960 个 feature flag)方面做得不错。但有三个结构性债务需要优先处理:
|
||
|
||
1. **`bootstrap/state.ts`** 是全局耦合的核心节点。215 个导出被 251 个文件引用,修改任何状态逻辑都可能产生级联影响。拆分它是最高 ROI 的重构动作。
|
||
|
||
2. **权限系统跨四层分散**是维护噩梦的根源。统一权限引擎能同时提升可维护性和安全性。
|
||
|
||
3. **REPL.tsx 和 main.tsx 的体积**使新人上手和 bug 定位变得困难。但拆分它们是 Phase 3+ 的工作,需要先解决底层耦合。
|
||
|
||
Phase 1(bootstrap/state 拆分)可在 1-2 周内完成,零风险,立即可启动。
|