Skip to content

refactor(frontend): 消融 4 处自证死表面——composerApprovalMode 里同一个 3 元素枚举的 5 份手抄收成 1 张表(死常量变唯一来源),另删 shared 两个 0 消费者 key helper、workbench 一个死别名(连同其唯一 import)、web 一个值写错且 0 消费者的 threads 键(它指向 projects 根键,失效永远碰不到它声称寻址的 threads) (#2274) - #2277

Merged
DeliciousBuding merged 1 commit into
masterfrom
refactor/fe-dead-structure
Sep 3, 2026

Conversation

@DeliciousBuding

Copy link
Copy Markdown
Collaborator

一句话

消融 4 处自证的死表面;核心不是删,是把 composerApprovalMode.ts 里同一个 3 元素枚举的 5 份手抄收成 1 张表——那个"死常量"因此变成唯一来源,而不是被删掉。

关联 #2274(C-2 / A-15)。

改了什么

1. app/workbench/src/composerApprovalMode.ts:5 份 → 1 张表

同一个 mode → pickerValue → labelKey 三元组在这个 54 行文件里被写了 5 遍(lane 报告说 4 遍,实数 5):

原状 处置
COMPOSER_APPROVAL_MODES 数组(0 消费者 保留导出,改为从表派生 ⇒ 从死码变成唯一来源
approvalModeToPickerValue if/else 链 查表
pickerValueToApprovalMode 反向 if/else 链 查表
buildComposerApprovalModeOptions 手写三项 .map()
activeComposerApprovalModeLabel if/else 链 查表

行为逐值保持:三个 mode 的 pickerValue/labelKey 照搬,未知 mode 仍回落 suggest,未知 pickerValue 仍返回 null,选项顺序仍是 suggest / acceptEdits / plan。收益是结构性的:加一个 mode 从"改 5 处"变成"加 1 行",且一个 mode 不可能再出现在某个映射里却缺席于另一个。

2. 三处 0 消费者死表面(判据:全仓命中数 = 1,即只有自己的定义)

位置 是什么
app/shared/src/ui/DiffReviewPanelHelpers.ts leftLineKey / rightLineKey(8 行)——同族的 hunkStateKey 有消费者,保留
app/workbench/src/mockData.ts WORKBENCH_MOCK_AGENT_MCP_OPTIONS 死别名,连同它唯一使用的那个 import 别名一起删(否则留下未使用 import)
app/web/src/api/projectQueries.ts workspaceProjectThreadsQueryKey:0 消费者且值是错的——与紧邻上一行的 workspaceProjectsQueryKey 完全相同(都是 hubQueryKeys.projects.root),任何对它的失效都只会重拉项目列表、永远碰不到它声称寻址的 threads。就地留注释说明为什么刻意不再有本地 threads 键别名

刻意不做(证据不支持"死"这个定性)

证据

结果
pnpm -r typecheck 5 个包全绿
pnpm --filter {workbench,shared,web} test 4,726 个测试全绿:shared 150 文件/2,734、workbench 169/1,724、web 33/268,0 failed
pnpm --filter @agenthub/workbench linttsc --noEmit 绿
4 个死符号删除后复查 各 0 残留

未验证 / 可能错

  • pnpm --filter agenthub-web linteslint src --max-warnings 0仍报 6 个 no-explicit-any。已用 git stash 对照证明干净 master 上同样红,且 6 处全在我没碰的 4 个文件(agentQueries.ts ×3、webPlatformMapping.tswebWorkbenchProjects.tswebWorkbenchProjectsPort.ts),全是同一个模式 (key: string, options?: any) => string。根因是 CI 的 Lint Web step 挂着 continue-on-error: true结构上不可能让 CI 变红(desktop / mobile 的 lint step 同样如此)。这属另一批(把假门禁变真门禁),不在本 PR 范围内,本 PR 也没让它变好或变坏。
  • 未跑 desktop / mobile-rn 的测试与 lint:本 PR 未改这两个包的任何文件。

…举的 5 份手抄(车道报的是 4 份,实数 5:一个 0 消费者的 COMPOSER_APPROVAL_MODES 数组 + 4 条各自重列同一组 mode→pickerValue→labelKey 的 if/else 链)收成 1 张表 + 4 个查表函数,死常量因此变成唯一来源而不是被删掉;删 shared 的 leftLineKey/rightLineKey(全仓各只出现 1 次=自己的定义)、workbench mockData 的 WORKBENCH_MOCK_AGENT_MCP_OPTIONS 死别名连同它唯一使用的那个 import 别名、web projectQueries 里值写错且 0 消费者的 threads 键别名(它指向 projects 根键,任何对它的失效都只会重拉项目列表而永远碰不到它声称寻址的 threads) (#2274)

判据与自证(不采信车道结论,逐条自己 grep):
- 4 个死符号在 app/ 全树的命中数各为 1,即只有自己的定义,0 消费者 0 测试。
- workspaceProjectThreadsQueryKey 与紧邻上一行的 workspaceProjectsQueryKey
  **值完全相同**(都是 hubQueryKeys.projects.root),这是 #2274 A-15 说的
  「死导出且值是错的」,就地留注释说明为什么刻意不再有本地 threads 键别名。
- composerApprovalMode 的收敛是行为保持的:三个 mode 的 pickerValue 与
  labelKey 逐值照搬,未知 mode 仍回落 suggest、未知 pickerValue 仍返回 null、
  选项顺序仍是 suggest/acceptEdits/plan。该文件有专属测试
  composerApprovalMode.test.ts,改后全绿。

刻意不做(证据不支持「死」这个定性):
- WorkbenchProjectsPort 家族(#2274 C-3/S2):车道定性为「两个 shell 里都结构
  性不可达」,但自己 grep 出 **41 处引用**,含 desktop/App.tsx:237 的真实实例
  化与专属测试。「结构性不可达」是比「0 引用」强得多的断言,需要沿渲染路径追,
  删它属架构裁决(接通还是删)而非清死码 ⇒ 留给 #2274 的 S2,不在本批。
- resolveHubProjectsDefault / useWorkbenchProjectsRoute:同上,各自都有专属测试。
- rootPrefix()(C-5,0 消费者):它是 A-12 那 4 处 no-op 失效的现成解法,应当
  被接线而不是被删;接线要改键形状,等 #2261 的 S1 裁决。
- 34 个死 export 修饰符(C-4):跨 24 文件的纯机械改动,混进本批会让 review
  无法进行,且需要单独的编译验证轮次。

验证:pnpm -r typecheck 5 个包全绿;pnpm --filter {workbench,shared,web} test
共 **4,726 个测试全绿**(shared 150 文件/2,734、workbench 169/1,724、
web 33/268,0 failed);workbench lint(tsc --noEmit)绿。
web lint(eslint src)仍报 6 个 no-explicit-any,但经 git stash 对照证明
**在干净 master 上同样红**,且全部落在我没碰的 4 个文件(agentQueries.ts ×3、
webPlatformMapping.ts、webWorkbenchProjects.ts、webWorkbenchProjectsPort.ts),
根因是 CI 的 Lint Web step 挂着 continue-on-error ⇒ 结构上不可能让 CI 变红;
该假门禁另批处理,不在本 PR 范围内。

Co-authored-by: Cursor <cursor@vectorcontrol.tech>
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 0670dca0-ec0f-4f12-a676-7bd4b4a40743

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant