Skip to content

refactor(cli): remove unused ApiKeyInput component - #10139

Open
qqqys wants to merge 1 commit into
QwenLM:mainfrom
qqqys:simplify/api-key-input
Open

refactor(cli): remove unused ApiKeyInput component#10139
qqqys wants to merge 1 commit into
QwenLM:mainfrom
qqqys:simplify/api-key-input

Conversation

@qqqys

@qqqys qqqys commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Removes an API-key input component that nothing in the codebase references, together with the plan-type interface and the three plan-URL constants declared in the same file. The component once rendered the API-key entry screen for the subscription-plan authentication flows, but the application no longer imports or renders it anywhere; its only remaining references were its own declarations. The authentication experience that replaced it is the unified provider setup flow that now serves every provider, including the subscription plans. Nothing else changes — in particular, the two translation strings the component used are still used by live authentication screens, so every locale entry is kept.

Why it's needed

Dead surface is a cost: every contributor who reads it has to work out what wires it up, and the answer here is "nothing". The component was built for the plan-based API-key screens; the provider-first authentication refactor replaced those per-flow screens with a single generic provider setup experience and this file was left behind. No production caller, no test, no snapshot, no dynamic import path, and no documentation row references it — the three exported URL constants likewise appear only at their declarations, while the same URLs live on as literals in the provider presets and user docs where they are actually consumed. Removing it shrinks the auth UI surface a reviewer of that area must keep in their head.

Reviewer Test Plan

How to verify

This is a pure deletion of code nothing references. Verify the absence of consumers rather than behavior:

  1. rg -n '\bApiKeyInput\b' packages integrations integration-tests scripts .github docs-site — expect zero hits after this PR (before it the only hit was the component's own declaration). The similarly named navigateToCustomApiKeyInput test helper is a distinct identifier and is untouched.
  2. rg -n '\bApiKeyInputPlan\b|\bCODING_PLAN_API_KEY_URL\b|\bCODING_PLAN_INTL_API_KEY_URL\b|\bTOKEN_PLAN_API_KEY_URL\b' packages integration-tests — expect zero hits after this PR (before it each appeared only at its declaration in the removed file).
  3. npm run build && npm run bundle && npm run typecheck — all green locally with this change (a type-only break from a removed export would surface here; typecheck does not run in CI).
  4. npm run lint:ci — green locally with this change.

No user-visible behavior changes, so no before/after TUI evidence applies.

Evidence (Before & After)

N/A — non-UI change (dead-code deletion; nothing mounted or called this component).

Tested on

OS Status
🍏 macOS ⚠️
🪟 Windows ⚠️
🐧 Linux

Environment (optional)

Local npm run build && npm run bundle && npm run typecheck and npm run lint:ci in a clean worktree off upstream/main.

Risk & Scope

  • Main risk or tradeoff: essentially none — the component, its interface, and its three constants have zero consumers, verified by full-corpus search including string keys, dynamic-import shapes, build graphs, the test corpus, and tracked .qwen files; if a consumer were ever found, reverting the single commit restores everything.
  • Not validated / out of scope: macOS/Windows builds (no platform-specific code involved); no integration test run (no CLI behavior is touched by removing an unmounted component); dependency cleanup is not touched (ink-link keeps five live users).
  • Breaking changes / migration notes: none — the component, its plan-type interface, and the URL constants were never imported outside their own file. The two i18n keys it used remain consumed by the live provider setup flow, so no locale entries are removed.

Linked Issues

Part of the dead-surface cleanup tracked in #10000.

Machine details (find-simplifications)
  • id / class: api-key-input — class 5, added-then-removed scaffolding: a whole dead component file left behind when its feature was deliberately replaced.
  • Surface removed: packages/cli/src/ui/components/ApiKeyInput.tsx — 97 lines deleted, 0 added (git diff --numstat), the component, its plan-type interface, and three plan-URL constants.
  • Every consumer found and its kind: full-corpus grep (production and test corpora, snapshots, docs, docs-site, .github, .husky, .vscode, patches, root build/lint manifests, tracked .qwen files) resolves ApiKeyInput to exactly one reference — its own declaration. ApiKeyInputPlan appears only in-file as the component's own prop type; each of the three URL constants appears exactly once (its declaration). Zero module-path imports of the file. Zero production consumers. Hidden-consumer checklist rows run: string-keys (no registry or literal reference; the kebab-case api-key-input literals in the replacement wizard's design PRD are new-flow ViewLevel names, not references to this component), build-graph, generated, vi-mock, mirrors, dyn-import — all clean; cli-flags/assets not applicable. No test, snapshot, or integration-test reference (second pass without test exclusions); no locale entries to remove (both i18n keys the component used are still consumed by the live provider setup flow); no docs rows; no filename-allowlist entry (PascalCase .tsx needs none).
  • Proof steps run (survey protocol §3): ledger check (filed, no tombstone), recency (introduced 2026-02-10, last touched 2026-05-08 by the replacement refactor — ~110 days, past the 90-day gate; noted as just past), published-surface escape (territory is packages/cli/src — landable; the package exports only its entry and ./export, neither re-exports this file), full-corpus grep, own-file check, hidden-consumer checklist, test-only check, unwire history (deliberate: the provider-first auth refactor 997796f532 (refactor(cli): provider-first auth registry with unified install pipeline #3864, 2026-05-08) replaced the per-flow screens with the unified provider setup flow and left this file behind), design-doc ownership (the custom-API-key wizard PRD documents the replacement flow, not this component).
  • Re-verified at land time against freshly fetched upstream/main (f9f5f2fcb6): same single reference, no new consumer, branch base fetched successfully before cutting.
  • Verification: npm run build && npm run bundle && npm run typecheck green; npm run lint:ci green; targeted vitest skipped by design (the surface had no test — no applicable targeted unit test; corpus re-grep on the landing checkout returned zero surviving references). Self-audit: two clean passes.
  • No collateral: no snapshot entry, no locale-key removal (keys shared with live code), no docs rows, no allowlist row; ink-link keeps five live users.
中文说明

本 PR 做了什么

删除一个在代码库中已无任何引用的 API Key 输入组件,以及同一文件中声明的套餐类型接口和三个套餐 URL 常量。该组件曾用于渲染订阅套餐认证流程的 API Key 输入界面,但应用中已没有任何地方导入或渲染它;它仅存的引用就是它自己的声明。取代它的认证体验是如今服务于所有提供商(包括订阅套餐)的统一 provider 安装流程。除此之外没有任何其他改动——特别地,该组件使用的两条翻译文案仍被在用的认证界面使用,因此所有语言文件条目均予以保留。

为什么需要

死代码是一种成本:每个读到它的人都得弄清是什么在用它,而这里的答案是"没有任何东西"。该组件是为基于套餐的 API Key 界面而编写的;provider 优先的认证重构用单一的通用 provider 安装体验取代了那些按流程划分的界面,此文件被遗留下来。没有生产调用者、没有测试、没有快照、没有动态导入路径、也没有文档行引用它——三个导出的 URL 常量同样只出现在各自的声明处,而相同的 URL 以字面量形式继续存在于真正消费它们的 provider 预设与用户文档中。删除它可以缩小该领域的审阅者需要装在脑子里的认证 UI 表面。

评审者测试计划

如何验证

这是一次对无任何引用代码的纯删除。请验证消费者的缺失,而不是行为:

  1. rg -n '\bApiKeyInput\b' packages integrations integration-tests scripts .github docs-site —— 本 PR 之后应无任何命中(之前唯一的命中是该组件自身的声明)。名称相似的 navigateToCustomApiKeyInput 测试辅助函数是另一个标识符,未被触碰。
  2. rg -n '\bApiKeyInputPlan\b|\bCODING_PLAN_API_KEY_URL\b|\bCODING_PLAN_INTL_API_KEY_URL\b|\bTOKEN_PLAN_API_KEY_URL\b' packages integration-tests —— 本 PR 之后应无任何命中(之前每个符号都只出现在被删文件的声明处)。
  3. npm run build && npm run bundle && npm run typecheck —— 本地在包含本改动的情况下全部通过(删除导出可能引发的纯类型问题会在这里暴露;typecheck 不在 CI 中运行)。
  4. npm run lint:ci —— 本地在包含本改动的情况下通过。

由于没有用户可见的行为变化,无需前后对比的 TUI 证据。

证据(改动前后)

N/A —— 非 UI 改动(死代码删除;该组件从未被挂载或调用)。

测试环境

OS 状态
🍏 macOS ⚠️ 未测试
🪟 Windows ⚠️ 未测试
🐧 Linux ✅ 已测试

环境(可选)

在基于 upstream/main 的干净 worktree 中本地运行 npm run build && npm run bundle && npm run typechecknpm run lint:ci

风险与范围

  • 主要风险或权衡:基本没有——该组件、其接口与三个常量零消费者,已通过全语料库搜索(含字符串键、动态导入形态、构建图、测试语料与已跟踪的 .qwen 文件)验证;万一未来发现消费者,回滚这一个提交即可完整恢复。
  • 未验证 / 超出范围:macOS/Windows 构建(不涉及平台相关代码);未运行集成测试(删除未挂载的组件不触及任何 CLI 行为);不清理依赖(ink-link 仍有 5 处在用)。
  • 破坏性变更 / 迁移说明:无——该组件、套餐类型接口与 URL 常量从未在其自身文件之外被导入。其使用的两条 i18n 文案仍被在用的 provider 安装流程消费,因此不删除任何语言文件条目。

关联 Issue

属于 #10000 跟踪的死代码清理工作。

机器细节见上方英文 "Machine details (find-simplifications)" 折叠块:候选编号 api-key-input(第 5 类:功能被有意取代后遗留的整文件死组件),共删除 97 行、新增 0 行;全语料库搜索证明 ApiKeyInput 的唯一引用即其自身声明,ApiKeyInputPlan 仅作组件自身的属性类型使用,三个 URL 常量各仅出现于声明处,文件路径零导入;调查协议各步骤(含落地前对刚拉取的 upstream/main 基准 f9f5f2fcb6 的重新核验)均已执行;构建、打包、类型检查与 lint:ci 全部通过;因该表面本无测试,按流程跳过定向 vitest,以落地检出上的语料库复扫(零残留引用)兜底;无快照、无语言键删除(文案仍被在用代码消费)、无文档行、无允许列表条目等连带项,ink-link 仍有 5 处在用。

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: verified, not theoretical — re-checked against current main (83da723) on this re-run: ApiKeyInput, its ApiKeyInputPlan interface, and the three plan-URL constants have zero consumers anywhere in the corpus; the only hits are the declarations themselves (the lowercase apiKeyInput local in the vscode-ide-companion webview handler is a distinct identifier). The two i18n strings the component used are still consumed by the live provider setup flow (ProviderSetupSteps.tsx, useProviderSetupFlow.ts), so keeping every locale entry is correct — that claim checks out too.

Direction: aligned — this is dead-surface cleanup tracked in #10000, and the provider-first auth flow that replaced these per-plan screens is in place. Deleting an unmounted component changes no behavior.

Size: not applicable — packages/cli/src/ui/components/ is not a core-module path, and the change is −97/+0 in a single file regardless.

Approach: the scope feels right — this is already the minimal change (pure deletion of exactly the dead declarations; no drive-by edits, no locale deletions). Nothing to cut.

Risk: no elevated risk signals — no high-risk path match.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

问题:已核实,非理论性问题——本次 re-run 已对照当前 main83da723)重新核验:ApiKeyInput、其 ApiKeyInputPlan 接口以及三个 plan URL 常量在全库零消费者,唯一命中即其自身声明(vscode-ide-companion webview 处理器中的小写 apiKeyInput 局部变量是另一个标识符)。该组件使用的两条 i18n 文案仍被在用的 provider 设置流程(ProviderSetupSteps.tsxuseProviderSetupFlow.ts)消费,因此保留全部语言条目是正确的——这一说法也已核验属实。

方向:对齐——这是 #10000 跟踪的死代码表面清理,取代这些按 plan 划分界面的 provider 统一认证流程已经就位。删除未挂载的组件不改变任何行为。

规模:不适用——packages/cli/src/ui/components/ 不是核心模块路径,且改动本身仅为单文件 −97/+0。

方案:范围合理——这已是最小改动(纯删除恰好无人引用的声明;无顺手改动、无语言条目删除)。没有可砍的部分。

风险:无升级风险信号——未命中高风险路径。

进入代码审查 🔍

Qwen Code · qwen3.8-max

Reviewed at 66b5ad4adb4a8ed8bba46b9014fdfa87c789a07a · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Code review

No findings. My independent take on "remove an unreferenced component" is exactly what this diff does: prove zero consumers corpus-wide, delete the whole file, touch nothing else. I re-verified the load-bearing claims against current main (83da723) myself on this re-run rather than taking the description at its word:

  • ApiKeyInput, ApiKeyInputPlan, and the three *_PLAN_*_API_KEY_URL constants appear only at their own declarations — no imports, no barrel export, no dynamic reference. The lowercase apiKeyInput local in the vscode-ide-companion handler is a distinct identifier, untouched.
  • The two i18n keys the component used (API key cannot be empty., Enter to submit, Esc to go back) are still consumed by the live provider setup flow (useProviderSetupFlow.ts, ProviderSetupSteps.tsx), so keeping all locale entries is correct.
  • ink-link keeps five live importers after this deletion (ProviderSetupSteps, AuthDialog, ArenaStartDialog, StatusMessages, QwenOAuthProgress) and remains a direct dependency of packages/cli (package.json line 75) — the author's claim checks out. This also settles @doudouOUC's review observation: on today's main the "zero direct consumers" reading does not reproduce — consistent with the tree fetch being blocked on that machine at review time.

One file, −97/+0, no drive-by edits. Nothing to flag.

Testing

Evidence carried here: the PR's own CI results on the reviewed commit, fetched via the API (unattended run — I do not build or execute PR code). CI is now fully settled on 66b5ad4: zero failures across all 63 check runs. There is no behavioral claim in this PR for a sandboxed lane to settle — the oracle is the absence of consumers, statically verified above, and any dangling import of the removed exports would fail the build. (A sandboxed verification run was launched alongside this re-trigger and will post its own report here when done.)

Final CI results for 66b5ad4 — all green (auto-updated by the triage finalize job):

Check Conclusion
Classify PR ✅ success
Dependency CVE audit ✅ success
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
Secret scan (TruffleHog) ✅ success
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success

One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。

Notes on the signal, outside the table: everything that ran is green. The macOS/Windows Test lanes and Integration Tests (CLI, No Sandbox) are skipped by design on PRs — ci.yml gates them on merge_group/schedule/workflow_dispatch — pre-existing and unrelated to this change. CI also has no standalone typecheck job (the author ran it locally); with zero consumers that gap is theoretical, since any dangling import of the removed exports would break the build.

Real-scenario (tmux) testing: N/A — pure deletion of an unmounted component, nothing user-visible changes; and this is an unattended run in any case.

中文说明

代码审查:无问题。面对"删除无人引用的组件",我独立的方案与 diff 完全一致:全库证明零消费者后整文件删除、不动其他任何内容。本次 re-run 我对照当前 main83da723)自行复核了关键声明,而非照单全收:

  • ApiKeyInputApiKeyInputPlan 与三个 *_PLAN_*_API_KEY_URL 常量仅出现在自身声明处——无导入、无 barrel 导出、无动态引用;vscode-ide-companion 中的小写 apiKeyInput 局部变量是另一个标识符,未受影响。
  • 组件使用的两条 i18n 文案仍被在用的 provider 设置流程(useProviderSetupFlow.tsProviderSetupSteps.tsx)消费,因此保留全部语言条目正确。
  • 删除后 ink-link 仍有 5 处在用导入(ProviderSetupStepsAuthDialogArenaStartDialogStatusMessagesQwenOAuthProgress),且仍是 packages/cli 的直接依赖(package.json 第 75 行)——作者声明属实。这也澄清了 @doudouOUC 在评审中的观察:在今天的 main 上"零直接消费者"的说法无法复现——与评审时该机器无法拉取代码树的情况相符。

单文件 −97/+0,无顺手改动,无可指摘之处。

测试证据:本节引用的是被审提交自身 CI 的最终结果(经 API 获取;无人值守运行不构建、不执行 PR 代码)。66b5ad4 上的 CI 已全部结束:全部 63 个检查零失败。此 PR 没有需要沙盒验证通道裁决的行为性声明:判定标准就是"零消费者",已在上文静态验证;若有悬空导入,构建会直接失败。(本次 re-trigger 同时启动了一个沙盒验证运行,完成后会在此单独发布报告。)

表格之外的说明:所有实际运行的检查均为绿色。macOS/Windows 的 TestIntegration Tests (CLI, No Sandbox) 在 PR 上按设计跳过——ci.yml 将这些 lane 限定于 merge_group/schedule/workflow_dispatch——属既有配置,与本改动无关。另注意 CI 无独立 typecheck 任务(作者在本地运行过);在零消费者的前提下该缺口只是理论性的,任何对被删导出的悬空引用都会在构建中报错。

真实场景(tmux)测试:N/A——纯删除未挂载组件,无任何用户可见变化;且本次为无人值守运行。

Qwen Code · qwen3.8-max

Reviewed at 66b5ad4adb4a8ed8bba46b9014fdfa87c789a07a · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Confidence: 3/5 — clean review at every stage and CI fully green, but this is a cross-repository refactor PR, and that class is never auto-approved — the cap is pure policy, not doubt about the change.

Stepping back: my independent plan for "remove an unreferenced component" was exactly what landed here — prove zero consumers corpus-wide, delete the whole file, touch nothing else — and the diff matches it line for line. The problem is real and verified, not asserted: re-checked against current main today, the component, its plan interface, and the three URL constants have no consumers, the i18n keys it used remain live in the replacement provider setup flow, and ink-link keeps five other importers. It's the minimal possible change, trivially revertible, and part of the tracked dead-surface cleanup in #10000. doudouOUC's independent human review reached the same verdict — no blockers — and their one ink-link observation does not reproduce on today's tree (see the review comment above). CI on the reviewed commit is now fully settled: zero failures across all 63 checks.

The only reason this doesn't end in an approval is the guardrail: fork PRs with a refactor title always need a human maintainer's sign-off. So no approval here and no deferred-approval marker — a green CI run doesn't change that; a maintainer's approval is the remaining step.

中文说明

置信度:3/5 —— 各阶段审查均干净且 CI 已全绿,但这是一个跨仓库(fork)的 refactor PR,此类 PR 一律不自动批准——此上限纯属策略要求,而非对改动本身有疑虑。

退一步看整体:我面对"删除无人引用的组件"的独立方案与最终落地的完全一致——全库证明零消费者后整文件删除、不动其他内容,diff 逐行吻合。问题真实存在且经过验证,而非仅凭声明:今天已对照当前 main 重新核验,组件、其 plan 接口与三个 URL 常量无任何消费者,它使用的 i18n 文案在替代的 provider 设置流程中仍在用,ink-link 也仍有 5 处其他导入。这是最小改动、可轻易回滚,且属于 #10000 跟踪的死代码表面清理。doudouOUC 的独立人工评审结论相同——无阻塞项——其唯一关于 ink-link 的观察在今天的代码树上无法复现(见上文审查说明)。被审提交上的 CI 已全部结束:全部 63 个检查零失败。

唯一没有给出批准的原因是护栏:fork 的 refactor 标题 PR 必须由人类维护者签核。因此本次不批准、也不发出延迟批准标记——即使 CI 全绿也不会改变这一点;剩下的步骤是维护者的批准。

Qwen Code · qwen3.8-max

Reviewed at 66b5ad4adb4a8ed8bba46b9014fdfa87c789a07a · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

⏸️ Still deferred to @wenshao — per your re-trigger, the full pass ran again: every load-bearing claim re-verified against today's main (zero consumers of the component, its interface, and the three URL constants; i18n keys still live in the provider setup flow; ink-link keeps five importers and stays a direct dependency), CI fully green on 66b5ad4 (zero failures across all 63 checks), and doudouOUC's independent review also found no blockers. The review itself is done and clean; what remains is the fork-refactor guardrail, which only a maintainer can clear. If you're satisfied, your approval is the remaining step — the sandboxed verification launched alongside this re-trigger will post its report separately.

中文说明

⏸️ 继续转交 @wenshao —— 应你的重新触发,完整流程已再跑一遍:所有关键声明已对照今天的 main 重新核验(组件、其接口与三个 URL 常量零消费者;i18n 文案仍被 provider 设置流程使用;ink-link 仍有 5 处导入且仍是直接依赖),66b5ad4 上的 CI 全绿(63 个检查零失败),doudouOUC 的独立评审同样无阻塞项。审查本身已完成且干净;剩下的只有 fork refactor 护栏,只能由维护者放行。若你认可,你的批准即是最后一步——随本次重新触发启动的沙盒验证会另行发布报告。

@doudouOUC doudouOUC left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: PR #10139refactor(cli): remove unused ApiKeyInput component

Files: 1 file, +0/−97 lines
Author: @qqqys
Scope: Deletes dead packages/cli/src/ui/components/ApiKeyInput.tsx (component, ApiKeyInputPlan interface, 3 URL constants)

Verified

References (no consumers remain):

  • packages/cli/ — zero matches for ApiKeyInput (any identifier), zero imports from the file path, zero references to the URL constants (CODING_PLAN_API_KEY_URL, CODING_PLAN_INTL_API_KEY_URL, TOKEN_PLAN_API_KEY_URL), zero references to ApiKeyInputPlan.
  • packages/desktop/ has its own ApiKeyInput component under packages/desktop/apps/electron/src/renderer/components/apisetup/ — a completely separate component in a different package, not affected.
  • integration-tests/, .github/, docs-site/ — zero matches for the deleted identifiers.

Build & lint: Author reports npm run build && npm run bundle && npm run typecheck and npm run lint:ci green on Linux. Worktree fetch blocked on this Windows machine (known getaddrinfo issue), so Windows-side re-run is not possible here.

Minor observation

The PR description says ink-link keeps five live users. After removing this file, ink-link has zero direct consumers in packages/cli/src/. It appears in package-lock.json as a transitive dependency but is not a direct dependency of any package's package.json and is not installed in node_modules. This is not a blocker — the PR's scope is component removal, not dependency cleanup — but the claim about five live users appears to be stale.

Verdict

No blockers. The deletion is clean, well-documented, and correctly verified. The component, its interface, and its URL constants have zero consumers in the codebase. The ink-link note is a minor documentation inaccuracy (the dependency is transitive, not a direct dependency with five consumers), not a correctness issue.

Part of the dead-surface cleanup tracked in #10000.

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Downgraded from Approve to Comment: CI still running. Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

Not explored to full depth (tool budget reached): "agent 6c": none — all checks above ran to completion within the tool budget..

中文说明

⚠️ 已从批准降级为评论:CI still running。 仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

未探索到全部深度(达到工具调用预算):"agent 6c"none — all checks above ran to completion within the tool budget.

— qwen3.8-max via Qwen Code /review (v0.22.0)

@wenshao

wenshao commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 51 passed · 0 failed · 51 total

Flakiness gate: not applicable — no runnable changed test files (0 out-of-scope file(s) noted in the log)

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:51 通过 · 0 失败 · 51 总计

抖动门:不适用 — no runnable changed test files (0 out-of-scope file(s) noted in the log)

Verification report

PR #10139 Deep Verification — refactor(cli): remove unused ApiKeyInput component

Verdict: merge-ready — assertions: 51 pass / 0 fail (51 total) — verified head: 66b5ad4adb4a8ed8bba46b9014fdfa87c789a07a (base tip aa7a0f05431c73d8ed5903633fdf03128cc203a9, merge commit 5705e30ca7).

中文摘要

本 PR 删除了一个没有任何调用方的死代码组件 ApiKeyInput.tsx(含 ApiKeyInputPlan 接口与三个计划 URL 常量),共 97 行、单文件、单提交。

  • 判定merge-ready。全部脚本化断言通过,无新发现。
  • A/B 结论:中心主张("零消费者、删除不改变任何可观察行为")经两条独立证据链证实:
    1. 引用普查:base 侧该文件的全部引用均为文件自引用(0 个外部消费者);head 侧全仓库零命中。
    2. 构建产物 A/B:tsc 层面,base 产出 ApiKeyInput.{js,d.ts,js.map} 而 head 没有;esbuild bundle 层面,两侧产物归一化后 469/469 文件逐字节一致——因为该组件从未被入口图可达,base 的 bundle 里本来就没有它。删除一个从未进过产物的模块,产物不变。
  • 门禁:head 侧 npm run typecheck(全 workspace + integration)绿;lint:ci 等价命令绿(含活性探针);packages/cli 全量 vitest 24754 通过,出现的失败全部判定为容器环境问题并有 base 侧 A/A 对照(见下)。
  • Findings:无。PR 描述的各项主张(ink-link 仍有 5 个使用者、两个 i18n key 仍被活代码消费、三个 URL 以字面量形式存续)均逐一核实为准确。
  • 环境性失败说明:验证容器自身导出 QWEN_HOME,导致 settings.test.ts 中 12 个假定其未设置的测试失败;同一失败在 base 侧逐名复现(A/A),unset 后两侧均 169/169 通过——与本 PR 无关。全量运行中的 4 个 15s 超时为并发 CPU 争用所致,空闲复跑全绿。
  • 未覆盖:见报告 Not covered 一节(要点:bundle 对比的归一化仅针对已点名的三类环境差异;per-commit 归属只有一个提交故无需展开;未做 UI 截图对比——无可挂载的界面变化)。

Central claim and A/B

Central claim: the removed component, its ApiKeyInputPlan interface, and the three *_PLAN_API_KEY_URL constants have zero consumers, so the deletion changes no observable behavior.

Secondary claims: the two i18n keys the component used are still consumed by live auth screens; the three URLs survive as literals in provider presets/docs; navigateToCustomApiKeyInput (a distinct identifier) is untouched; ink-link keeps five live users.

Census cells (reference graph)

cell oracle base (HEAD^1) head (PR)
\bApiKeyInput\b over test-plan dirs hits outside the file itself 1 hit = the declaration only 0 hits
\bApiKeyInputPlan\b + 3 URL constants hits outside the file itself 5 hits = declarations only 0 hits
repo-wide safety net (constants/interface) any hit anywhere declarations only 0 hits
distinct-identifier control navigateToCustomApiKeyInput present n/a 2 hits (untouched)

Scripted: 14/14 assertions pass (01-census.mjs). See 02-census-reference-graph.png.

Build-artifact A/B cells

cell environment oracle base head
tsc output npm run build in each tree ApiKeyInput.{js,d.ts,js.map} emitted present (3 files) absent
esbuild bundle npm run bundle in each tree identifier census in chunks+cli.js 0 hits (never reachable) 0 hits
bundle content normalized multiset compare 469 files, byte totals 469/469 identical, Δ=0 bytes

The deletion is visible to the build system (tsc cell flips) but was never load-bearing in the shipped artifact: esbuild only bundles modules reachable from packages/cli/src/cli.ts, and nothing ever imported ApiKeyInput.tsx, so the base bundle already lacked it. That is the strongest form of a dead-code A/B — X/X cells unchanged. See 01-bundle-ab-base-vs-head.png.

Raw bundle byte totals differ by −27,894 bytes; the entire delta is accounted by three named confounds of building in a scratch worktree (git short-SHA string, content-hash chunk-name cascade, and ../../-prefixed module-path comments/CJS keys from symlink realpath resolution — 2,697 modules, each differing by an exact multiple of 6 bytes). After normalizing exactly those, byte totals are equal and every file matches.

Findings

None. Every PR claim checked out; see the walkthrough below.

Reviewer Test Plan walkthrough

  1. rg -n '\bApiKeyInput\b' packages integrations integration-tests scripts .github docs-sitezero hits at head ✓ (executed with git grep --extended-regexp; rg is not installed in this container — identical semantics over tracked files; the built dist/ was additionally word-boundary-grepped: zero hits).
  2. Same for \bApiKeyInputPlan\b|\bCODING_PLAN_API_KEY_URL\b|… over packages integration-testszero hits ✓.
  3. npm run build && npm run bundle && npm run typecheck → build+bundle pre-existed at head; npm run typecheck re-run at head: exit 0 across all workspaces + integration-tests ✓. The test plan's note "typecheck does not run in CI" is accurate: ci.yml runs only typecheck:integration (line 635), not the full workspace typecheck.
  4. npm run lint:ci → equivalent command (eslint . --ext .ts,.tsx --max-warnings 0 + eslint integration-tests --max-warnings 0)exit 0 ✓, with a liveness probe (a planted unused variable in packages/cli/src/lint-probe.ts was caught with @typescript-eslint/no-unused-vars, exit 1, then removed). Note: eslint . scans tmp/, which is not in the config ignores — verification scratch worktrees/harnesses must be excluded (--ignore-pattern 'tmp/'), otherwise the gate reports thousands of false errors.

Secondary claims verified

  • ink-link users: 6 importers at base (including ApiKeyInput.tsx) → exactly 5 at head (AuthDialog.tsx, ProviderSetupSteps.tsx, QwenOAuthProgress.tsx, ArenaStartDialog.tsx, StatusMessages.tsx) — matches the PR's "keeps five live users".
  • i18n keys: 'API key cannot be empty.' is still consumed by useProviderSetupFlow.ts:284; 'Enter to submit, Esc to go back' by ProviderSetupSteps.tsx:41 — both live, so keeping every locale entry is correct (no orphaned keys created by this PR).
  • URLs survive as literals: the two console URLs remain in docs/users/configuration/model-providers.md; the token-plan URL remains in packages/core/src/providers/presets/alibaba-token-plan.ts and packages/vscode-ide-companion/src/services/subscriptionPlanDefinitions.ts.
  • Commit reachability: local git rev-list HEAD^1..HEAD^2 = 1 commit, matching the metadata snapshot's 1-commit array — no shallow gap.

Test-suite evidence and environment attribution

run env result
head, full packages/cli suite container env (QWEN_HOME set), loaded machine 888/889 files, 24754 passed, 12 failed, 92 skipped
the 12 failures all in settings.test.ts (loadSettings/loadEnvironment) assume QWEN_HOME unset; environment.ts branches on process.env['QWEN_HOME']; this container exports it (the verify agent's own home)
head, settings.test.ts alone, env -u QWEN_HOME clean 169/169 pass
base, same file, env -u QWEN_HOME (A/A) clean 169/169 pass
base, same file, QWEN_HOME set (A/A) container env the identical 12 failures, name for name
head, full suite, env -u QWEN_HOME, loaded clean env 886/889 files; 4 failures = 3×15s timeouts + 1 chained assertion in the same file
head, the 3 timeout files re-run idle clean env 38 passed / 1 skipped, 0 failed (one test naturally takes ~6.5s on this machine — under concurrent builds+lint it crossed the 15s timeout)

Conclusion: every observed failure reproduces on base or disappears under the environment the tests require; none is attributable to a 97-line deletion of an unmounted component.

Not covered

  • No TUI before/after captures — the component was never mounted; there is no screen to capture (the PR says the same).
  • Sibling dead-code sweep — whether the same auth refactor left other orphaned files is out of scope for this PR (tracked under [find-simplifications] candidate ledger #10000 per the description); only this file's consumer graph was verified.
  • Base-side full npm run typecheck / full vitest suite — the base side was verified at the level the change can act on (census, build, bundle, and the settings-file A/A); a full base suite run would only re-measure the environment.
  • Integration tests — not run; the deletion cannot affect CLI behavior (proven by the bundle identity), matching the PR's own scope note.
  • dist/web-shell/ (335 files in head dist/) is produced by a separate serve-fast-path pipeline step the base tree never ran; excluded from the bundle comparison by scope, not by result.
  • Per-commit attribution — single-commit PR; the merge-ref checkout carries all three relevant commits.
  • The vitest A/A runs on base were executed in the terminal with observed counts; the head-side runs have full captured logs. rg is not present in the container (git grep used as the equivalent oracle).

Methodology

Environment: the CI verify container (node:22-bookworm), working tree at refs/pull/10139/merge (depth 2), npm ci + npm run build pre-run at HEAD. Base arm: git worktree add tmp/base-tree HEAD^1 wired to the already-installed root node_modules via symlinks (root + per-package, including packages/channels/*), plus a locally generated packages/web-templates build; the PR touches no package.json/lockfile, and the only internal symlink realpath worth naming — node_modules/@qwen-code/qwen-code-core → head tree packages/core — is byte-identical across the diff because the PR does not touch packages/core. Base bundle: npm run bundle in the worktree; base tsc cell: npm run build in packages/cli (composite tsc --build). Head gates: npm run typecheck, lint:ci equivalent with liveness probe, and npx vitest run in packages/cli. Harnesses 01-census.mjs, 02-bundle-ab.mjs, 03-gates.mjs (plus diagnostics diag-diff-chunks.mjs, diag-module-sizes.mjs) live in this directory with raw logs (logs-*.txt). Evidence images: 01-bundle-ab-base-vs-head.png, 02-census-reference-graph.png, 03-gates-and-attribution.png.

Flakiness gate log


verdict: n/a
summary: no runnable changed test files (0 out-of-scope file(s) noted in the log)

Evidence images

01-bundle-ab-base-vs-head

02-census-reference-graph

03-gates-and-attribution

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Triage re-run completed without a new review.

⚠️ The bot's only review on 66b5ad4adb4a8ed8bba46b9014fdfa87c789a07a is a COMMENTED one, which carries no vote — so it has no verdict of its own on this commit, and main needs two approving reviews: an approval left by another account is a separate vote and does not count as the bot's own. Two different things look like this, and the stage-3 comment above says which: the triage skill deferring on purpose at 3/5 — a fork refactor hitting the approval guardrail, or a core change escalated for maintainer awareness, both normal outcomes — or an earlier approval that a push dismissed, leaving only the comment behind, which needs a fresh review.

⚠️ 机器人在 66b5ad4adb4a8ed8bba46b9014fdfa87c789a07a 上唯一的评审是 COMMENTED不带票 —— 因此它在该 commit 上没有自己的裁决,而 main 需要两个批准(其他账号的批准是另一张票)。有两种情况长这样,上方的 stage-3 评论会说明是哪一种:triage skill 在 3/5 时有意 defer(fork refactor 命中审批护栏,或核心改动被升级交由维护者把关,两者都是正常结果);或者更早的批准被一次推送作废、只剩下这条评论,此时需要重新评审。

The stage comments above were updated with the latest result. View workflow run.

上方各阶段评论已更新为最新结果。查看工作流运行

@qqqys

qqqys commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the verification pass, @doudouOUC — the consumer analysis matches mine exactly. One correction on the ink-link observation, though: the description's claim is accurate and the note is not.

ink-link is a direct dependency, and it does have five live consumers after this PR:

$ git grep -l "from 'ink-link'" -- 'packages/cli/src/**/*.tsx' | grep -v test
packages/cli/src/ui/auth/AuthDialog.tsx
packages/cli/src/ui/auth/ProviderSetupSteps.tsx
packages/cli/src/ui/components/QwenOAuthProgress.tsx
packages/cli/src/ui/components/arena/ArenaStartDialog.tsx
packages/cli/src/ui/components/messages/StatusMessages.tsx
$ git show HEAD:packages/cli/package.json | grep ink-link
    "ink-link": "^4.1.0",

The removed ApiKeyInput.tsx was the sixth consumer (import Link from 'ink-link'; at line 14), so the count goes 6 → 5 across this diff. "Keeps five live users" is the post-removal number, which is why dependency cleanup is correctly listed as out of scope — removing the package would break five live screens.

I suspect the discrepancy comes from the environment you noted: with the worktree fetch blocked by the getaddrinfo issue and node_modules not installed, ink-link would look absent from the tree and unresolvable as a direct dependency even though packages/cli/package.json declares it.

Nothing to change in the diff or the description, so I've left both as they are. CI is now fully green (0 failures), which also clears the ⚠️ Downgraded from Approve to Comment: CI still running that the automated reviewer flagged.

中文说明

感谢核验 —— 消费者分析与我的结论一致。但关于 ink-link 的那条「次要观察」需要更正:描述中的说法是准确的。

ink-link 确实是直接依赖(packages/cli/package.json 第 75 行声明),且本 PR 之后在 packages/cli/src/ 中仍有五个生产消费者:AuthDialog.tsxProviderSetupSteps.tsxQwenOAuthProgress.tsxarena/ArenaStartDialog.tsxmessages/StatusMessages.tsx

被删除的 ApiKeyInput.tsx 正是第个消费者(第 14 行 import Link from 'ink-link';),因此本次改动使计数从 6 降到 5。「keeps five live users」正是删除之后的数字——这也正是把依赖清理列为 out of scope 的原因:移除该包会破坏五个仍在使用的界面。

差异很可能来自您提到的环境问题:worktree fetch 被 getaddrinfo 阻塞、node_modules 未安装时,即便 package.json 已声明,ink-link 在树中看起来也会像不存在且无法解析为直接依赖。

因此 diff 与描述均无需改动。CI 现已全绿(0 失败),自动评审那条 ⚠️ Downgraded from Approve to Comment: CI still running 的降级原因也已消失。

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.

4 participants