Skip to content

refactor: core + cli 架构 Review — 12 项结构性问题清单 #4063

@pomelo-nwu

Description

@pomelo-nwu

概述

packages/corepackages/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.ts165 个 export 语句(373 行),且核心模块(如 coreToolScheduler.tspermissionFlow.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.tstools/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 方案有待讨论。

Metadata

Metadata

Assignees

No one assigned

    Labels

    category/cliCommand line interface and interactioncategory/coreCore engine and logicstatus/needs-triageIssue needs to be triaged and labeledtype/enhancementNon-bug improvement or optimization

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions