概述
对 packages/core 和 packages/cli 进行了全面的架构审查,发现 14 项结构性问题,按严重度分级记录如下。本 issue 仅作为问题记录,是否优化、如何推进有待后续讨论。
P0 — 架构级问题
1. 核心类型系统被 @google/genai 绑架
ContentGenerator 接口的入参/出参直接使用 @google/genai 的类型(GenerateContentParameters, GenerateContentResponse 等),136 个文件直接 import 该包。所有非 Gemini 适配器(OpenAI、Anthropic)被迫先转入 Google 格式再转回自身格式,造成双重序列化。
影响:架构锁死在 Google SDK 类型上,模型协议升级需全链路改动。
2. Config 上帝对象(3129 行,149 个成员)
packages/core/src/config/config.ts 中的 Config 类承担了模型配置、权限管理、Shell 执行、文件系统、Git、MCP、扩展管理、会话、内存、Telemetry、IDE 集成等几乎所有职责。
影响:无法独立测试/替换任何子系统,所有模块耦合到同一个单例。
P1 — 严重维护性问题
3. AppContainer 组件严重臃肿(2874 行)
单个 React 组件使用了 39 个 useState、27 个 useCallback、25 个 useEffect、28 个 useRef,加上 50+ 自定义 hook import。
影响:状态管理失控,难以维护、测试和理解。
4. useGeminiStream 单 hook 2339 行
这个 hook 承担了 LLM 流式响应处理、工具调用调度、历史记录管理、错误分类与重试、UI 状态同步等全部职责。
影响:无法复用、测试或独立理解任何子功能。
5. Barrel Export 爆炸 + 模块自引用
core/src/index.ts 有 165 个 export 语句(373 行),且核心模块(如 coreToolScheduler.ts、permissionFlow.ts)通过 from '../index.js' 反向引用自己的 barrel(10+ 处),形成隐式循环依赖。
影响:编译膨胀,tree-shaking 无效,潜在循环依赖风险。
P2 — 需要清理的技术债
6. Fork 残留命名未清理(100+ 文件)
836 处 Google 版权 vs 712 处 Qwen 版权。关键残留:
GeminiClient → 实际是通用 LLM 客户端
GeminiChat → 通用对话管理
geminiMdFilename → 项目记忆文件(QWEN.md)
useGeminiStream → 通用 LLM 流式 hook
GeminiRespondingSpinner → 通用加载动画
gemini.tsx → CLI 主入口
影响:品牌混乱,新贡献者困惑。
7. memory/const.ts 与 tools/memory-config.ts 代码重复
两个文件几乎一模一样,都定义了 setGeminiMdFilename / getCurrentGeminiMdFilename / getAllGeminiMdFilenames。
影响:状态不一致风险。
8. shell.ts 单文件 3724 行
Shell 工具文件包含命令解析、权限检查、后台任务管理、Git commit attribution、命令执行、输出截断等全部逻辑。
9. 18 个 React Context 嵌套
组件树上挂了 18 层 Provider,任何一个 Context 值变化都会导致消费者重渲染。终端 UI 场景下存在性能隐患。
10. 文件命名风格不统一
当前三种风格混用:
| 风格 |
文件数 |
示例 |
| camelCase |
701 |
shellExecutionService.ts, useGeminiStream.ts |
| PascalCase |
340 |
AppContainer.tsx, ArenaManager.ts |
| kebab-case |
198 |
agent-core.ts, shell-utils.ts |
三种风格没有明确的使用规则(如"组件用 PascalCase,其余用 kebab-case"),同一目录下经常混用。应统一为一种风格(建议 kebab-case),或至少建立明确的约定。
11. 测试文件组织方式不统一
| 方式 |
文件数 |
同目录 .test.ts 共置 |
632 |
__tests__/ 目录 |
2 |
__e2e__/ 目录 |
1 |
绝大多数测试文件与源码共置在同一目录,导致源码目录文件数翻倍,浏览时噪音大。少数用了 __tests__/ 目录但不成体系。应讨论是否统一迁移至 __tests__/ 目录,或保持共置但明确为唯一标准。
P3 — 代码组织优化
12. 配置代码 8150 行分散四文件两包
core/src/config/config.ts(3129 行)
cli/src/config/config.ts(1721 行)
cli/src/config/settings.ts(1157 行)
cli/src/config/settingsSchema.ts(2143 行)
两层 config 边界模糊。
13. core/src/core/ 三层 core 命名冲突
路径 packages/core/src/core/coreToolScheduler.ts 中出现三层 "core"。该目录实际放的是 LLM 客户端层,应重命名为 llm/ 或 engine/。
14. 非交互模式代码散落 4 处 + 大小写不一致
cli/src/nonInteractiveCli.ts (根目录)
cli/src/nonInteractiveCliCommands.ts (根目录)
cli/src/nonInteractive/ (子目录,大写 I)
cli/src/ui/noninteractive/ (子目录,小写 i)
补充数据
| 指标 |
数值 |
| core + cli 总代码量 |
~253,000 行(非测试) |
| 超过 1000 行的非测试文件 |
25 个 |
| 超过 2000 行的非测试文件 |
7 个 |
@google/genai 直接 import 文件数 |
136 |
core/index.ts export 语句数 |
165 |
AppContainer useState 数量 |
39 |
| React Context 数量 |
18 |
| 文件命名 camelCase / PascalCase / kebab-case |
701 / 340 / 198 |
测试文件共置 / __tests__ 目录 |
632 / 2 |
本 issue 仅作为问题记录。是否优化、优先级排序和后续 PR 方案有待讨论。
概述
对
packages/core和packages/cli进行了全面的架构审查,发现 14 项结构性问题,按严重度分级记录如下。本 issue 仅作为问题记录,是否优化、如何推进有待后续讨论。P0 — 架构级问题
1. 核心类型系统被
@google/genai绑架ContentGenerator接口的入参/出参直接使用@google/genai的类型(GenerateContentParameters,GenerateContentResponse等),136 个文件直接 import 该包。所有非 Gemini 适配器(OpenAI、Anthropic)被迫先转入 Google 格式再转回自身格式,造成双重序列化。影响:架构锁死在 Google SDK 类型上,模型协议升级需全链路改动。
2.
Config上帝对象(3129 行,149 个成员)packages/core/src/config/config.ts中的Config类承担了模型配置、权限管理、Shell 执行、文件系统、Git、MCP、扩展管理、会话、内存、Telemetry、IDE 集成等几乎所有职责。影响:无法独立测试/替换任何子系统,所有模块耦合到同一个单例。
P1 — 严重维护性问题
3.
AppContainer组件严重臃肿(2874 行)单个 React 组件使用了 39 个 useState、27 个 useCallback、25 个 useEffect、28 个 useRef,加上 50+ 自定义 hook import。
影响:状态管理失控,难以维护、测试和理解。
4.
useGeminiStream单 hook 2339 行这个 hook 承担了 LLM 流式响应处理、工具调用调度、历史记录管理、错误分类与重试、UI 状态同步等全部职责。
影响:无法复用、测试或独立理解任何子功能。
5. Barrel Export 爆炸 + 模块自引用
core/src/index.ts有 165 个 export 语句(373 行),且核心模块(如coreToolScheduler.ts、permissionFlow.ts)通过from '../index.js'反向引用自己的 barrel(10+ 处),形成隐式循环依赖。影响:编译膨胀,tree-shaking 无效,潜在循环依赖风险。
P2 — 需要清理的技术债
6. Fork 残留命名未清理(100+ 文件)
836 处 Google 版权 vs 712 处 Qwen 版权。关键残留:
GeminiClient→ 实际是通用 LLM 客户端GeminiChat→ 通用对话管理geminiMdFilename→ 项目记忆文件(QWEN.md)useGeminiStream→ 通用 LLM 流式 hookGeminiRespondingSpinner→ 通用加载动画gemini.tsx→ CLI 主入口影响:品牌混乱,新贡献者困惑。
7.
memory/const.ts与tools/memory-config.ts代码重复两个文件几乎一模一样,都定义了
setGeminiMdFilename/getCurrentGeminiMdFilename/getAllGeminiMdFilenames。影响:状态不一致风险。
8.
shell.ts单文件 3724 行Shell 工具文件包含命令解析、权限检查、后台任务管理、Git commit attribution、命令执行、输出截断等全部逻辑。
9. 18 个 React Context 嵌套
组件树上挂了 18 层 Provider,任何一个 Context 值变化都会导致消费者重渲染。终端 UI 场景下存在性能隐患。
10. 文件命名风格不统一
当前三种风格混用:
shellExecutionService.ts,useGeminiStream.tsAppContainer.tsx,ArenaManager.tsagent-core.ts,shell-utils.ts三种风格没有明确的使用规则(如"组件用 PascalCase,其余用 kebab-case"),同一目录下经常混用。应统一为一种风格(建议 kebab-case),或至少建立明确的约定。
11. 测试文件组织方式不统一
.test.ts共置__tests__/目录__e2e__/目录绝大多数测试文件与源码共置在同一目录,导致源码目录文件数翻倍,浏览时噪音大。少数用了
__tests__/目录但不成体系。应讨论是否统一迁移至__tests__/目录,或保持共置但明确为唯一标准。P3 — 代码组织优化
12. 配置代码 8150 行分散四文件两包
core/src/config/config.ts(3129 行)cli/src/config/config.ts(1721 行)cli/src/config/settings.ts(1157 行)cli/src/config/settingsSchema.ts(2143 行)两层 config 边界模糊。
13.
core/src/core/三层 core 命名冲突路径
packages/core/src/core/coreToolScheduler.ts中出现三层 "core"。该目录实际放的是 LLM 客户端层,应重命名为llm/或engine/。14. 非交互模式代码散落 4 处 + 大小写不一致
补充数据
@google/genai直接 import 文件数core/index.tsexport 语句数AppContaineruseState 数量__tests__目录