fix(cli): drop duplicate fake properties breaking the main build - #10022
Conversation
|
⏳ Approval still deferred — 1 PR CI workflow run(s) still in progress for ⏳ 审批仍在延迟中 —— |
|
Thanks for the PR! Template: the essentials are covered in substance — motivation ( Problem: observed, not theoretical. Main is red right now — the Direction: fully aligned — this unblocks the main build. No CHANGELOG signal needed for a build repair. Size: not applicable — test file only, 2 deletions, 0 production logic lines. Approach: the scope is exactly right and cannot be more minimal. For each duplicate pair the kept declaration is behaviorally equivalent to today's runtime winner: the later property wins in JS object literals, so for Risk: no elevated risk signals — test-file-only change, none of the revert-correlated high-risk paths matched. Moving on to code review. 🔍 中文说明感谢贡献! 模板:核心内容已实质覆盖——动机( 问题:已观测到的真实问题,不是理论性加固。main 当前是红的—— 方向:完全对齐——解除 main 构建阻塞。构建修复无需 CHANGELOG 信号。 规模:不适用——纯测试文件,删除 2 行,0 行生产代码。 方案:范围恰好,已是最小改动。每对重复声明中保留的一份与今天运行时生效者行为等价:JS 对象字面量中后声明者生效,因此 风险:无升级风险信号——仅测试文件改动,未命中任何与 revert 相关的高风险路径。 进入代码审查 🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewMy independent proposal for "main fails to compile on duplicate object properties in the session-swap telemetry fakes" is exactly what this diff does: delete one declaration from each duplicated pair in
Testing evidence — the PR's own CI via API (this unattended run executes no PR code)CI on the reviewed commit was still settling at fetch time — the That is the runner's disk filling up while extracting dependencies — a two-line deletion in a test file cannot cause it, and the job never reached compilation. CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 Pending at fetch time: the build + unit-suite result for this branch — those jobs had not reached execution behind the ENOSPC attempt, and per policy this review does not poll. The build itself ( 中文说明代码审查针对"session-swap telemetry fake 中重复对象属性导致 main 编译失败",我的独立方案与本 diff 完全一致:删除
测试证据——PR 自身 CI(经 API 读取;本 unattended 运行不执行 PR 代码)抓取时被审提交的 CI 尚未跑完—— 抓取时尚未决出:本分支的构建 + 单测结果——相关作业排在 ENOSPC 尝试之后尚未执行,按规约本审查不轮询。构建本身( — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — a provably correct two-line repair of a red main; the only nit is that the PR body's headings deviate from the template. Stepping back: this is a maintainer repairing their own regression from this morning (#9998). The failure is observed and pinpointed — main's The one reservation is process, not code: the body uses CI on the reviewed commit is still settling — the 中文说明置信度:4/5 —— 对红色 main 的一次可证明正确的两行修复;唯一的小问题是 PR 正文标题与模板不一致。 退一步看:这是维护者修复自己今晨引入的回归(#9998)。故障已被观测且精确定位——main 的 唯一保留意见在流程而非代码:正文用 被审提交上的 CI 仍在进行——抓取时 — Qwen Code · qwen3.8-max Reviewed at |
The merge stacked two duplicate keys in this file and the previous commit removed only getCurrentCustomTitle; the sessionService fake also carries getSessionDisplayName twice. Identical expressions, and a JS literal keeps the last one — behaviour unchanged. Matches #10022's fix of main line for line, so neither merge order conflicts.
#9998 re-added getSessionDisplayName and getCurrentCustomTitle to the session-swap telemetry fakes, which already declared both. TS1117 fails tsc --build, breaking every workflow that runs npm run build on main.
d83802c to
dbc958e
Compare
|
Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. 中文请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。 |
chiga0
left a comment
There was a problem hiding this comment.
Checked and approved — no blockers.
Diagnosis confirmed. On main, session-swap-telemetry.test.ts contains two properties declared twice in the same object literal:
getSessionDisplayNameat lines 186 and 197 (bothvi.fn().mockResolvedValue(undefined))getCurrentCustomTitleat lines 211 and 215 (() => undefinedthenvi.fn().mockReturnValue(undefined))
TypeScript TS1117 rejects both; the CLI package cannot compile.
Fix is correct. This PR removes the second getSessionDisplayName (the redundant identical copy) and the first getCurrentCustomTitle (the plain-function () => undefined added by #9998). The surviving getCurrentCustomTitle: vi.fn().mockReturnValue(undefined) is the original mock — a strictly better form for testing since it is spyable. Net behavioral change: none.
CI
Test (ubuntu-latest, Node 22.x): 🔄 in progress at review timeTest (macos-latest, Node 22.x),Test (windows-latest, Node 22.x): ⏭ SKIPPED (path filter; change is test-only)Desktop Shell (ubuntu/windows): ✅ passDependency CVE audit+Secret scan: ✅ pass
Reviewed with AI assistance.
qqqys
left a comment
There was a problem hiding this comment.
Verified locally against upstream/main (526809d) in a clean worktree — this is the complete fix for the broken main build, and it is behavior-preserving.
Scope of the breakage. A fresh npm ci on main fails in prepare → tsc --build with exactly two errors and nothing else:
src/ui/hooks/session-swap-telemetry.test.ts(197,5): error TS1117: An object literal cannot have multiple properties with the same name.
src/ui/hooks/session-swap-telemetry.test.ts(215,7): error TS1117: An object literal cannot have multiple properties with the same name.
How it landed. #9998 (merged 08:32Z) and #9994 (merged 12:32Z) each added getSessionDisplayName and getCurrentCustomTitle to the same fakes in makeFakeEnv(), at different offsets. git blame on main confirms the split: line 186 / 215 from 2d42f4244 (#9998), line 197 / 211 from 50c553550 (#9994). The two hunks do not overlap textually, so the merge was clean and neither PR's own CI could see it — ci.yml checks out refs/pull/{N}/head, so a PR never builds the merged result.
Why this diff is right. Duplicate keys resolve last-wins, so before the fix line 197 and line 215 were the live ones. This PR deletes 197 (the survivor at 186 is the identical vi.fn().mockResolvedValue(undefined)) and 211 (the survivor at 215 already won). Runtime behavior is unchanged; only the type error goes away.
Evidence after applying this diff:
npm run build --workspace=packages/cli→ exit 0, no TS errors.npx vitest run src/ui/hooks/session-swap-telemetry.test.ts --root packages/cli→ 10 passed (1 file).
LGTM — worth landing quickly, since every PR that merges main after 50c553550 now reds at the install step on a file outside its own diff.
中文说明
已在干净 worktree 中针对 upstream/main(526809dd91)本地验证:这就是 main 构建被打断的完整修复,且不改变运行时行为。
破坏范围。 在 main 上全新 npm ci 会在 prepare → tsc --build 阶段失败,报错只有以下两条,没有其他问题:
src/ui/hooks/session-swap-telemetry.test.ts(197,5): error TS1117: An object literal cannot have multiple properties with the same name.
src/ui/hooks/session-swap-telemetry.test.ts(215,7): error TS1117: An object literal cannot have multiple properties with the same name.
是怎么合进来的。 #9998(08:32Z 合入)和 #9994(12:32Z 合入)各自在 makeFakeEnv() 的同一批 fake 上添加了 getSessionDisplayName 和 getCurrentCustomTitle,只是插入位置不同。main 上的 git blame 印证了这一点:186 / 215 行来自 2d42f4244(#9998),197 / 211 行来自 50c553550(#9994)。两处改动在文本上不重叠,因此合并没有冲突,而任何一个 PR 自己的 CI 都看不到对方——ci.yml 检出的是 refs/pull/{N}/head,PR 从不构建合并后的结果。
为什么这个 diff 是对的。 重复键遵循后者生效,所以修复前真正生效的是第 197 行和第 215 行。本 PR 删除第 197 行(保留的 186 行是完全相同的 vi.fn().mockResolvedValue(undefined))和第 211 行(保留的 215 行本来就是生效的那个)。运行时行为不变,只是消除了类型错误。
应用此 diff 后的验证结果:
npm run build --workspace=packages/cli→ 退出码 0,无 TS 报错。npx vitest run src/ui/hooks/session-swap-telemetry.test.ts --root packages/cli→ 10 个测试通过(1 个文件)。
LGTM——建议尽快合入,因为在 50c553550 之后合过 main 的 PR,都会在 install 阶段因为一个不属于自己 diff 的文件而变红。
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
…he split key, harden the oracle's edges R17-1: the duplicate-key cleanups each removed a DIFFERENT copy of getSessionDisplayName (#10022 on main, its twin here) and the clean merge resolved to zero — the /branch hook TypeError'd on the absent method and three telemetry tests went red. One copy restored, with a comment pinning why exactly one. R17-2: the scope-emptied split keyed on file PRESENCE, which cannot see a discarded change (file present, cited bytes gone), and no channel named the affected paths at all. The capture now publishes incremental.scope.supersededPaths — cached paths whose recorded change is gone from this capture — and the bullet routes the SUPERSEDED split through membership, both directions. R17-3: check-attr answers diff=unspecified byte-identically for the no-rule state and an explicit diff=unspecified value, so with diff.unspecified.binary configured a rendering flip crossed the anchor unseen. The config's presence now takes the whole answered dimension to UNHASHABLE; without it — every ordinary repo — nothing changes. R17-4: the candidate path is stable per target with no lease, so a concurrent same-target run overwrites it mid-round undetectably. The plan now publishes cacheCandidateStateId beside the path and Step 8 compares before promoting; a mismatch is a withheld candidate. R17-5: sparse-checkout S-tags every out-of-cone path by design, so the oracle read non-empty on every sample in every sparse repo — permanent non-convergence on a clean materialized tree. Under core.sparseCheckout an S path counts only while it exists on disk (nothing to hide an edit in); the assume-unchanged family is never exempted, and outside sparse an absent S path stays a hidden deletion. R17-6 entrance 2 (created by this diff): the 64-char cap's `-` joiner made every exactly-55-char uncapped stem a strict sweep-prefix of every capped stem sharing its head, so cleanup deleted the capped twin's live artifacts. The joiner is now `~`, outside the token alphabet, making capped stems prefix-free against ALL stems. Entrance 1 (organic dash-prefix tokens) predates this PR and is tracked in #10057. Every fix mutation-checked: dropped sample-0 exemption, reverted sparse filter, removed unspecified special-case, dropped supersededPaths, and a `-` joiner each turn exactly their new tests red.
|
Released in v0.22.2. |
Motivation
Main is currently red: every workflow that installs dependencies fails during the prepare build, e.g. the SDK Java daemon E2E run and the npm cache producer run from the latest push to main.
The root cause is a test-fake regression from #9998: the session-swap telemetry fakes already declared a session display name lookup and a custom title lookup, and that PR added both properties a second time in the same object literals. TypeScript rejects duplicate object properties (TS1117), so the CLI package no longer compiles.
Changes
Removes the two duplicate declarations, keeping the versions added by #9998 (the later property wins at runtime today, so behavior is unchanged). Two lines deleted, nothing else touched.
Reviewer Test Plan
How to verify: check out this branch, run
npm install(its prepare step performs the full build that fails on main), and confirm it completes. Running the session-swap telemetry test file should show all 10 tests passing. Verified locally: full build succeeds and the suite passes.