Skip to content

test(cli): teach session-swap telemetry fakes the /branch title prerequisites - #9998

Merged
yiliang114 merged 1 commit into
QwenLM:mainfrom
yiliang114:fix/session-swap-telemetry-fakes
Aug 25, 2026
Merged

test(cli): teach session-swap telemetry fakes the /branch title prerequisites#9998
yiliang114 merged 1 commit into
QwenLM:mainfrom
yiliang114:fix/session-swap-telemetry-fakes

Conversation

@yiliang114

Copy link
Copy Markdown
Collaborator

What this PR does

Completes the fake environment used by the session-swap telemetry regression tests added in #9844: the fake recording service and session service gain the two title-related methods the real services have had since the branch-title work — the outgoing recorder's current custom title and the source session's display name. With those stubs in place, the three /branch scenarios drive the intended fork/swap/rollback paths again instead of dying at the first title lookup.

Why it's needed

The branch-title change that landed just before the regression suite taught /branch to read the outgoing recorder's custom title (and fall back to the source session's display name) before forking the JSONL. The regression PR branched from a base without that change, so its fake environment only stubs the recorder's finalize/flush and the session service's fork/load/remove/rename/title-prefix methods. Once both landed on main, every /branch scenario threw a "not a function" error before the fork, and main's CI fails three tests: a failed /branch restores the process-wide aggregate, a successful /branch keeps the replayed usage, and a failure after the UI re-key does not roll back or undo. The /resume scenarios never read those methods, which is why they stayed green. This PR completes the fakes only; no production code changes.

Reviewer Test Plan

How to verify

Run the session-swap telemetry regression file from packages/cli at main to observe the same three /branch failures as CI, then apply this change and rerun: the whole file passes (10/10). The /branch and /resume command suites stay green as well.

Evidence (Before & After)

Before: Tests 3 failed | 7 passed (10) — identical to main's CI. After: Tests 10 passed (10).

Tested on

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

Environment

N/A — unit tests only; CI covers the remaining platforms.

Risk & Scope

  • Main risk or tradeoff: none expected — test-only change; the added stubs return undefined, matching the state the scenarios assume (no pre-existing custom title or display name), so branch-title derivation still falls back to the first user prompt exactly as the assertions expect.
  • Not validated / out of scope: production behavior is untouched.
  • Breaking changes / migration notes: none.

Linked Issues

Follow-up to #9844; the missing fake surface comes from #9764.

中文说明

这个 PR 做了什么

补全 #9844 新增的会话切换 telemetry 回归测试所用的假环境:给假 recording service 和假 session service 补上分支标题功能落地后真实服务早已具备的两个标题相关方法——切出方 recorder 的当前自定义标题、源会话的展示名。补上后,三个 /branch 场景重新走预期的 fork/切换/回滚路径,而不是在第一步标题查询处就抛错。

为什么需要

紧邻该回归套件之前合入的分支标题改动让 /branch 在 fork JSONL 之前先读取切出方 recorder 的自定义标题(并回退到源会话展示名)。回归 PR 的分支基线不含该改动,假环境只 mock 了 recorder 的 finalize/flush 和 session service 的 fork/load/remove/rename/标题前缀查询。两者在 main 上汇合后,所有 /branch 场景在 fork 之前就抛 “not a function”,main 的 CI 因此挂三个用例:a failed /branch restores the process-wide aggregate、a successful /branch keeps the replayed usage、a failure after the UI re-key does not roll back or undo。/resume 场景不读这两个方法,所以一直绿。本 PR 只补假环境,不改任何生产代码。

如何验证

在 packages/cli 下于 main 跑该回归文件,复现与 CI 一致的三个 /branch 失败;应用本改动后重跑,整文件通过(10/10),/branch 与 /resume 命令套件同样保持绿。

证据(改动前后)

改动前:Tests 3 failed | 7 passed (10),与 main CI 一致。改动后:Tests 10 passed (10)

测试平台

macOS ✅;Windows / Linux 交由 CI(⚠️)。

环境

N/A —— 纯单测。

风险与范围

  • 主要风险:预期无。仅测试改动;新增 stub 返回 undefined,与场景假设的初始状态(没有既有自定义标题或展示名)一致,分支标题推导仍按断言预期回退到首条用户 prompt。
  • 未验证 / 超出范围:生产行为未触碰。
  • 破坏性变更:无。

关联 Issue

#9844 的后续修复;缺失的假接口来自 #9764

…quisites

QwenLM#9764 taught /branch to read the outgoing recorder's custom title and the source session's display name before forking. The QwenLM#9844 regression suite's fake environment predates that and lacks both methods, so on main every /branch scenario throws before the fork and three tests fail. Complete the fakes; no production change.
@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

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

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

@yiliang114
yiliang114 enabled auto-merge August 25, 2026 08:27

@chiga0 chiga0 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.

No blocking findings.

Scope: 1 file changed (test-only); +2 lines, both stub additions in makeFakeEnv(). No production code touched.

Checked:

  • Stub return types match real implementations:
    • chatRecordingService.ts:1077 getCurrentCustomTitle(): string | undefined (sync) -> mockReturnValue(undefined) correct
    • sessionService.ts:3132 getSessionDisplayName(): Promise<string | undefined> (async) -> mockResolvedValue(undefined) correct
  • Both stubs placed inside makeFakeEnv()'s sessionService / recorder fakes, consistent with surrounding mocks.
  • useBranchCommand.ts:178-184: getSessionDisplayName is only called when sourceCustomTitle === undefined && name === undefined. With the new stub returning undefined, that path still calls through and resolves to undefined, so branch-title derivation falls through to the first-user-prompt fallback exactly as the scenario assertions expect.
  • No logic change introduced; the two new stubs eliminate the "not a function" TypeError that crashed the three /branch scenarios once #9764 landed on main alongside #9844.

CI: Test (ubuntu-latest, Node 22.x) still in progress at review time -- ubuntu suite is the ground truth for these tests; macOS/Windows are SKIPPED (fork PR security model). precheck-pr SKIPPED is expected for fork PRs.

Reviewed with AI assistance.

@yiliang114
yiliang114 added this pull request to the merge queue Aug 25, 2026
Merged via the queue into QwenLM:main with commit 2d42f42 Aug 25, 2026
59 of 60 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the quick follow-up!

Template looks good ✓

Problem: real, and verified. #9764 (branch-title preservation, merged today 06:47 UTC) taught /branch to read the outgoing recorder's custom title and the source session's display name before forking the JSONL; #9844's regression suite (merged 06:53 UTC) was branched before that change, so its fake env lacks both methods. On main the fakes throw TypeError: ... is not a function at the first title lookup — I confirmed the call sites in the branch hook, the missing stubs in the test's fake env, and the merge timeline matches the description. Observed failure, not theory.

Direction: aligned — restoring a red unit suite on main is about as clearly in scope as it gets. Test-only; production telemetry code untouched.

Size: not applicable — one test file, +2/-0 (0 production lines).

Approach: the minimal fix. Two stubs with correct sync/async shapes (getCurrentCustomTitle is sync on the real recording service, getSessionDisplayName returns a Promise on the real session service), both yielding undefined, which keeps every scenario on its intended "no pre-existing title → fall back to the first prompt" path. Nothing to cut, no drive-by changes.

Risk: no elevated risk signals — the only changed file is a .test.ts, none of the revert-correlated paths are touched.

Moving on to code review. 🔍

中文说明

感谢快速跟进!

模板完整 ✓

问题:真实存在,且已核实。#9764(分支标题保留,今天 06:47 UTC 合入)让 /branch 在 fork JSONL 之前先读取切出方 recorder 的自定义标题和源会话的展示名;#9844 的回归套件(06:53 UTC 合入)分支基线早于该改动,其假环境缺这两个方法。在 main 上,假环境会在第一步标题查询处抛 TypeError: ... is not a function——已核对 branch hook 的调用点、测试假环境中缺失的 stub,以及两个 PR 的合入时间线,均与描述吻合。是已观测到的失败,不是理论问题。

方向:对齐——恢复 main 上变红的单测属于最明确的职责范围。纯测试改动,未触碰生产 telemetry 代码。

规模:不适用——单个测试文件,+2/-0(0 行生产代码)。

方案:最小修复。两个 stub,同步/异步形态正确(真实 recording service 的 getCurrentCustomTitle 是同步方法,真实 session service 的 getSessionDisplayName 返回 Promise),均返回 undefined,使各场景保持在预期的"无既有标题 → 回退到首条 prompt"路径。无可裁剪,无夹带改动。

风险:无升级风险信号——唯一改动文件是 .test.ts,未触碰任何与 revert 相关的高风险路径。

进入代码审查 🔍

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Code review

Two lines, and they're the right two lines. The branch hook now reads the outgoing recorder's custom title (sync) and the source session's display name (async) before forking, and this adds exactly those two stubs to the test's fake env. I checked the shapes against the real services: getCurrentCustomTitle(): string | undefined is synchronous, so mockReturnValue(undefined) is correct; getSessionDisplayName(): Promise<string | undefined> is async, so mockResolvedValue(undefined) is correct. Both mirror the mock shapes already used by useBranchCommand.test.ts.

With the stubs in place the fake env covers every method the /branch path touches — recorder: title lookup, finalize, flush; session service: display name, load, fork, rename, remove, and the title-prefix collision query via computeUniqueBranchTitle — so the three /branch scenarios reach the fork/swap/rollback paths they were written to exercise, with title derivation falling back to the first user prompt exactly as the assertions expect. No production code touched, nothing unrelated in the diff. No findings.

Testing evidence (this PR's own CI, read via API — PR code not executed here)

The decisive check is Test (ubuntu-latest, Node 22.x) — it runs the exact file this PR fixes, settling the claim (3 failed → 10 passed) directly. It was still running at review time; the table below is updated automatically once CI lands. The macOS/Windows unit jobs and the CLI integration job show skipped by workflow design on PR events — they only run in the merge queue.

Check Conclusion
Classify PR ✅ success
Test (ubuntu-latest, Node 22.x) ⏳ in progress
Test (macos-latest, Node 22.x) ⏭️ skipped (merge queue only)
Test (windows-latest, Node 22.x) ⏭️ skipped (merge queue only)
Integration Tests (CLI, No Sandbox) ⏭️ skipped (merge queue only)
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
Dependency CVE audit ✅ success
Secret scan (TruffleHog) ✅ success
precheck-pr / precheck ✅ success

Not verified independently: the before/after counts (3 failed | 7 passed10 passed) are the author's claim — consistent with main's code state (both stubs genuinely missing on main), and CI on this commit is the thing that confirms the "after". No user-visible behavior changes, so no real-scenario TUI testing applies.

中文说明

代码审查

两行改动,而且正是需要的两行。branch hook 现在会在 fork 之前读取切出方 recorder 的自定义标题(同步)和源会话的展示名(异步),本 PR 恰好给测试的假环境补上了这两个 stub。已与真实服务核对形态:getCurrentCustomTitle(): string | undefined 是同步方法,用 mockReturnValue(undefined) 正确;getSessionDisplayName(): Promise<string | undefined> 是异步方法,用 mockResolvedValue(undefined) 正确。两者与 useBranchCommand.test.ts 已有的 mock 形态一致。

补上后,假环境覆盖了 /branch 路径触及的全部方法——recorder:标题查询、finalize、flush;session service:展示名、load、fork、rename、remove,以及经由 computeUniqueBranchTitle 的标题前缀冲突查询——三个 /branch 场景因此能走到它们原本要验证的 fork/切换/回滚路径,标题推导按断言预期回退到首条用户 prompt。未触碰生产代码,diff 无无关改动。无审查发现。

测试证据(读取本 PR 自身 CI,未在此执行 PR 代码)

决定性检查是 Test (ubuntu-latest, Node 22.x)——它直接运行本 PR 修复的文件,可直接验证"3 失败 → 10 通过"的结论。审查时该 job 仍在运行,下方表格会在 CI 结束后自动更新。macOS/Windows 单测与 CLI 集成 job 显示 skipped 是工作流设计使然——它们只在合并队列中运行。审查时已完成的检查全部通过(桌面壳两项、依赖 CVE 审计、TruffleHog 密钥扫描、预检),无失败项。

未独立验证:before/after 数字(3 failed | 7 passed10 passed)是作者陈述——与 main 的代码状态一致(两个 stub 在 main 上确实缺失),最终由该提交的 CI 确认"之后"的状态。无用户可见行为变化,不适用真实场景 TUI 测试。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 5/5 — a verified red on main, fixed by exactly the two stubs the code path needs, nothing more.

Stepping back: this is the cleanest kind of follow-up. The problem is real and independently verified — #9764 added the two title lookups to the branch flow at 06:47 UTC, #9844's regression suite landed six minutes later from a base that predates them, and main's fake env has been missing both methods since. The fix is the minimal one: stub the two methods with undefined so every scenario stays on the "no pre-existing title → derive from first prompt" path the assertions already expect. My own take on how to fix this before reading the diff was identical, and there is no smaller version of it. No production code is touched, the stub shapes match the real services and the conventions of the neighboring test file, and the diff carries nothing else.

The one thing not yet settled is CI itself: the Ubuntu unit job — the check that runs this exact file — was still in flight at review time, so approval is deferred until CI lands green on b4c16b1b3bdf2fed5931f8ccc0712ff81237e87d rather than approved now. If it comes back green, this is ready to ship.

中文说明

置信度:5/5 —— main 上已核实的红灯,由该代码路径恰好需要的两个 stub 修复,多一分都没有。

退一步看:这是最干净的后续修复。问题真实且已独立核实——#9764 于 06:47 UTC 给 branch 流程加了两个标题查询,#9844 的回归套件六分钟后从早于它的基线合入,main 的假环境从此缺这两个方法。修复就是最小方案:把两个方法 stub 为 undefined,让所有场景保持在断言所预期的"无既有标题 → 从首条 prompt 推导"路径。我在看 diff 之前想到的修法与之完全一致,且不存在更小的版本。未触碰生产代码,stub 形态与真实服务及相邻测试文件的约定一致,diff 不含任何其他改动。

唯一未落定的是 CI 本身:运行该文件的 Ubuntu 单测 job 在审查时仍在执行,因此暂不批准——等 CI 在该提交上变绿后自动批准。若变绿,即可合入。

Qwen Code · qwen3.8-max

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

wenshao added a commit that referenced this pull request Aug 25, 2026
Carried in from main by the last merge: #9998 added the vi.fn variant
of getCurrentCustomTitle to the getChatRecordingService fake while
#9994's Live Host restore re-added the plain arrow variant in the same
literal — each PR built green alone, the clean merge stacked both keys,
and `tsc --build` fails the cli package with TS1117 inside `npm ci`'s
prepare step, so this PR's Install dependencies step dies on fresh
runners. Keep the vi.fn variant: a JS literal keeps the LAST key, so it
is the one every run actually used — behaviour unchanged, suite 10/10.

Same one-line fix as #10023 proposes for main; landing it here unblocks
this PR's CI without waiting, and the two are byte-identical so neither
merge order conflicts.
yiliang114 added a commit that referenced this pull request Aug 25, 2026
#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.
euntaek-hong pushed a commit to wrongbutworks/qwen-code that referenced this pull request Aug 25, 2026
…wenLM#10022)

QwenLM#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.
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.22.2.

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