feat(ui): add ui.history.collapsePreviewCount to show last N turns when resuming collapsed sessions - #5848
Conversation
doudouOUC
left a comment
There was a problem hiding this comment.
Test (ubuntu-latest, Node 22.x)).
Two inline suggestions below. Overall this is a clean, well-scoped change (+130/-4, 7 files) with 52 tests passing locally, deterministic analysis clean (tsc/eslint 0 findings), and good backward-compat preservation at the default value.
| showInDialog: false, | ||
| }, | ||
| collapsePreviewCount: { | ||
| type: 'number', |
There was a problem hiding this comment.
[Suggestion] Schema declares type: 'number' but the boundary algorithm in applyCollapsePolicyAndSummary requires an integer — it uses strict equality (userTurnCount === collapsePreviewCount) against an integer counter. A float like 2.5 silently produces incorrect behavior (the loop never matches, falls through to unexpected collapse).
Other integer-valued settings in this same file use jsonSchemaOverride to enforce integer constraints (e.g., quorumSize at line 2288, stopHookBlockCap at line 2629, fileHistoryRetentionDays at line 1568).
| type: 'number', | |
| collapsePreviewCount: { | |
| type: 'number', | |
| label: 'Collapse Preview Count', | |
| category: 'UI', | |
| requiresRestart: false, | |
| default: 0, | |
| description: | |
| 'Number of most recent user turns to keep visible when collapsing history on resume. 0 collapses all restored history by default; -1 shows all restored history.', | |
| jsonSchemaOverride: { | |
| type: 'integer', | |
| minimum: -1, | |
| }, | |
| showInDialog: false, | |
| }, |
— qwen3.7-max via Qwen Code /review
| }), | ||
| ); | ||
| }); | ||
|
|
There was a problem hiding this comment.
[Suggestion] The userTurnCount < collapsePreviewCount fallback branch at resumeHistoryUtils.ts:586-588 is never exercised by the current test suite. The existing "covers all user turns" test uses previewCount=3 with exactly 3 user turns — the loop hits break (3 === 3), so boundary is set to 0 inside the loop, not via the post-loop fallback.
A test with previewCount exceeding the actual turn count would cover this distinct code path:
it('shows all items without a summary when preview count exceeds user turns', () => {
const rawItems = makeItems(); // 3 user turns
const result = applyCollapsePolicyAndSummary(rawItems, true, 5);
expect(result).toEqual(rawItems);
result.forEach(expectVisible);
});— qwen3.7-max via Qwen Code /review
doudouOUC
left a comment
There was a problem hiding this comment.
Test (ubuntu-latest, Node 22.x)).
— qwen3.7-max via Qwen Code /review
| if (userTurnCount === collapsePreviewCount) { | ||
| boundary = i; | ||
| break; | ||
| } |
There was a problem hiding this comment.
[Suggestion] userTurnCount === collapsePreviewCount uses strict equality against an always-integer counter. If collapsePreviewCount is a float (e.g. 1.5 — schema declares type: 'number' without integer constraints), the comparison never matches, the backward walk exhausts all items, and boundary stays at rawItems.length, collapsing everything instead of keeping ~1 turn visible.
| } | |
| if (userTurnCount >= collapsePreviewCount) { |
Using >= makes the loop stop at the Nth user turn for any N (integer or fractional) and makes the post-loop userTurnCount < collapsePreviewCount fallback consistent.
— qwen3.7-max via Qwen Code /review
| ); | ||
| }); | ||
|
|
||
| it('keeps the most recent N user turns visible and summarizes only hidden items', () => { |
There was a problem hiding this comment.
[Suggestion] No test covers collapsePreviewCount=1, the most common non-zero value users will configure. This is a meaningful boundary — it should keep exactly the last user turn (and its assistant response) visible while collapsing everything else. Currently tested values: 0, 2, 3, -1.
it('keeps only the last user turn visible when previewCount is 1', () => {
const result = applyCollapsePolicyAndSummary(makeItems(), true, 1);
expect(result).toHaveLength(7);
result.slice(0, 4).forEach(expectSuppressed);
result.slice(4, 6).forEach(expectVisible);
expect(result[6]).toEqual(
expect.objectContaining({
text: expect.stringContaining('4 messages hidden'),
display: { kind: 'collapse-summary' },
}),
);
});— qwen3.7-max via Qwen Code /review
wenshao
left a comment
There was a problem hiding this comment.
Re-reviewed at same SHA. No new issues found beyond the 4 suggestions from the prior review (integer schema enforcement, test coverage for boundary branches and collapsePreviewCount=1). Core boundary algorithm is correct across all edge cases. All 52 tests pass, CI green (30/30). LGTM! ✅
— qwen3.7-max via Qwen Code /review
✅ Maintainer verification — local build test + CI-failure diagnosisBuilt and ran the PR locally at head 1. The failing CI is real — diagnosed & reproduced 🔴The red check is
"collapsePreviewCount": {
"description": "Number of most recent user turns to keep visible when collapsing history on resume. 0 collapses all restored history by default; -1 shows all restored history.",
"type": "number",
"default": 0
}
2. Logic + tests — verified locally (exactly what CI skipped) ✅
My independent suite re-derives the documented semantics with harder data than the author's clean user/assistant pairs — interleaved
3. Integration wiring — audited ✅All three resume entry points ( 4. One non-blocking nit (consistent with my earlier review)The setting is Merge state
🇨🇳 中文版(点击展开)✅ 维护者验证 —— 本地构建测试 + CI 失败诊断在 head 1. CI 失败是真的 —— 已诊断并复现 🔴红的检查是
"collapsePreviewCount": {
"description": "Number of most recent user turns to keep visible when collapsing history on resume. 0 collapses all restored history by default; -1 shows all restored history.",
"type": "number",
"default": 0
}
2. 逻辑 + 测试 —— 本地已验证(正是 CI 跳过的部分)✅
我的独立用例用比作者更刁钻的数据重新推导了文档语义 —— 夹杂
3. 接线(集成)—— 已审计 ✅三个 resume 入口( 4. 一个不阻塞的小问题(与我之前的 review 一致)该设置是 合并状态
|
Build failure root cause: generated
|
doudouOUC
left a comment
There was a problem hiding this comment.
Integration test gap: The three call sites (AppContainer.tsx, useResumeCommand.ts, useBranchCommand.ts) all wire collapsePreviewCount from settings through to applyCollapsePolicyAndSummary(), but none of the integration tests exercise this path with a non-zero collapsePreviewCount. The unit tests in resumeHistoryUtils.test.ts cover the function logic thoroughly, but the end-to-end settings-to-function plumbing is untested. If a developer accidentally omits the parameter at a call site or introduces a typo in the settings key, no test would catch it.
expandCollapsedHistory test gap: No test exercises expandCollapsedHistory with the mixed-shape history that collapsePreviewCount > 0 produces (some items with suppressOnRestore: true, some without, plus a collapse-summary sentinel). The existing tests only cover fully-collapsed or no-collapse inputs.
— qwen3.7-max via Qwen Code /review
| @@ -496,6 +497,88 @@ describe('resumeHistoryUtils', () => { | |||
| }); | |||
| }); | |||
|
|
|||
There was a problem hiding this comment.
[Suggestion] Good unit test coverage for applyCollapsePolicyAndSummary itself, but the three call sites (AppContainer.tsx, useResumeCommand.ts, useBranchCommand.ts) that wire settings.merged.ui?.history?.collapsePreviewCount through to this function are not integration-tested with a non-zero collapsePreviewCount. If a developer accidentally omits the parameter at a call site or introduces a typo in the settings key, no test would catch it.
Consider adding at least one integration test (e.g., in useResumeCommand.test.ts) that sets collapsePreviewCount: 2 in the settings mock and asserts the loaded history has both suppressed and visible items plus a summary with the correct hidden count.
— qwen3.7-max via Qwen Code /review
| }); | ||
|
|
||
| describe('stripSuppressOnRestore', () => { | ||
| it('returns item unchanged when display is undefined', () => { |
There was a problem hiding this comment.
[Nice to have] No test exercises expandCollapsedHistory with the mixed-shape history that collapsePreviewCount > 0 produces — some items with suppressOnRestore: true (hidden prefix), some without (visible preview tail), and a collapse-summary sentinel. The existing expandCollapsedHistory tests only cover fully-collapsed or no-collapse inputs.
Consider adding a test case that constructs a partially-collapsed history (e.g., 2 suppressed + 4 visible + 1 collapse-summary) and asserts that expandCollapsedHistory returns all 6 original items with suppressOnRestore stripped and the collapse-summary removed.
— qwen3.7-max via Qwen Code /review
wenshao
left a comment
There was a problem hiding this comment.
Re-reviewed at c19c3c0. Core boundary algorithm is correct — traced through all edge cases (default 0, partial preview, -1 sentinel, empty history, fewer turns than requested). Tests pass locally (24 tests in resumeHistoryUtils.test.ts). Deterministic analysis clean (tsc, eslint: 0 findings). CI all green (12/12 checks).
Prior suggestions (integer schema, test coverage gaps) remain open for the author's consideration.
— qwen3.7-max via Qwen Code /review
| if (!collapseOnResume) return rawItems; | ||
| if (collapsePreviewCount === -1) return rawItems; | ||
|
|
||
| let boundary = rawItems.length; |
There was a problem hiding this comment.
[Suggestion] Negative values other than -1 silently fall through to full collapse
The === -1 check only catches the documented sentinel. Any other negative value (e.g., -2, -100) bypasses both the early-return here and the > 0 branch below, leaving boundary = rawItems.length — which collapses everything with a summary. The schema has no minimum constraint, so this is reachable from settings.
| let boundary = rawItems.length; | |
| if (collapsePreviewCount < 0) return rawItems; |
— bailian/glm-5.2 via Qwen Code /review
| }); | ||
|
|
||
| it('shows all items without a summary when preview count is -1', () => { | ||
| const rawItems = makeItems(); |
There was a problem hiding this comment.
[Suggestion] Test doesn't exercise leading non-USER items (common in real sessions)
The makeItems() fixture starts with a USER message. With collapsePreviewCount=3 and 3 user turns, boundary lands at index 0, so no items are hidden. But real sessions frequently start with INFO/system messages. With a leading INFO item, the same inputs produce boundary > 0 — items ARE hidden and a summary IS appended, contradicting the test name's implication.
Consider adding:
it('still hides leading non-user items when preview count covers all user turns', () => {
const items = [
{ id: 0, type: MessageType.INFO, text: 'system context' },
...makeItems(),
] as HistoryItem[];
const result = applyCollapsePolicyAndSummary(items, true, 3);
expect(result[0].display).toEqual(
expect.objectContaining({ suppressOnRestore: true }),
);
expect(result).toHaveLength(8);
expect(result[7].text).toContain('1 messages hidden');
});— bailian/glm-5.2 via Qwen Code /review
|
@qwen-code /triage |
|
Thanks for the PR, @mvanhorn! Template looks good ✓ (all required headings present, Linked Issues references #5759) On direction: this solves a real pain point. When On approach: the scope feels right — one new setting, one function signature change, three call-site wiring updates. No unrelated edits, no drive-by refactors. The backward-scan for Moving on to code review. 🔍 中文说明感谢贡献,@mvanhorn! 模板完整 ✓(所有必需标题均存在,关联 Issue 引用了 #5759) 方向:这解决了一个真实的痛点。启用 方案:范围合理——一个新设置、一个函数签名变更、三个调用点的接线更新。无无关改动,无顺手重构。从后向前扫描 进入代码审查 🔍 — Qwen Code · qwen3.7-max |
Code ReviewThe core logic change is clean and correct. Key observations:
No correctness bugs, security issues, or structural violations found. Test ResultsUnit tests (all pass):
Real-Scenario Testing (tmux)Created a 2-turn session ("say hello" → "now say goodbye"), then resumed with different collapsePreviewCount=1 (partial preview)Result: Last turn visible ("now say goodbye" + response), first turn collapsed, summary shows "2 messages hidden". ✓ collapsePreviewCount=0 (default, all collapsed)Result: All history collapsed, no turns previewed, summary shows "7 messages hidden" (includes the extra turn added during the accidental interactive test). Default behavior unchanged. ✓ 中文说明代码审查核心逻辑变更干净且正确。 关键观察:
未发现正确性 bug、安全问题或结构性违规。 测试结果单元测试(全部通过):
真实场景测试(tmux)创建了一个 2 轮会话("say hello" → "now say goodbye"),然后用不同的 collapsePreviewCount=1(部分预览)最后一轮可见("now say goodbye" + 响应),第一轮被折叠,摘要显示"2 messages hidden"。✓ collapsePreviewCount=0(默认,全部折叠)所有历史折叠,无轮次预览,摘要显示"7 messages hidden"(包含意外交互测试中增加的额外轮次)。默认行为不变。✓ — Qwen Code · qwen3.7-max |
ReflectionThis is a well-executed, focused PR. The problem is real (all-or-nothing collapse makes it hard to orient yourself when resuming), the solution is minimal (one setting, one function change, three wiring updates), and the execution is clean. My independent proposal would have been essentially the same: add a numeric setting that controls how many recent user turns to keep visible, scan backward from the end for The tmux tests confirm both the new partial-preview behavior and the backward-compatible default collapse. All 52 unit tests pass, typecheck and lint are clean, and the settings schema has been regenerated (resolving the previous CI blocker). The one non-blocking nit (no Verdict: Approve. ✅ 中文说明反思这是一个执行良好、范围集中的 PR。问题是真实的(全有或全无的折叠使得恢复时难以定位),解决方案是最小的(一个设置、一个函数变更、三个接线更新),执行干净。 我的独立方案本质上是相同的:添加一个数字设置来控制保留多少最近的用户轮次可见,从末尾向前扫描 tmux 测试确认了新的部分预览行为和向后兼容的默认折叠。所有 52 个单元测试通过,typecheck 和 lint 干净,settings schema 已重新生成(解决了之前的 CI 阻塞)。 一个不阻塞的小问题(数字设置缺少 结论: 批准 ✅ — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
✅ Maintainer re-verification at HEAD
|
collapsePreviewCount |
Visible turns in the TUI | Summary line |
|---|---|---|
0 (default) |
(none) | ● History collapsed: 8 messages hidden |
1 |
DELTA444 | ● History collapsed: 6 messages hidden |
2 |
CHARLIE333, DELTA444 | ● History collapsed: 4 messages hidden |
-1 |
all 4 turns | (no summary) |
5 (> turns) |
all 4 turns | (no summary) |
The count invariant is exact: each turn = 2 items, so keeping N turns hides 8 − 2N, and the summary counts only the hidden items. Real count=2 capture:
> Reply with exactly: CHARLIE333 and nothing else
✦ …CHARLIE333
> Reply with exactly: DELTA444 and nothing else
✦ …DELTA444
● History collapsed: 4 messages hidden. Use /history expand-now to show.
2. Base A/B — the decisive proof the new code is load-bearing
Reverted only applyCollapsePolicyAndSummary to its pre-PR body (keeping the signature so tsc passes), rebuilt the CLI, and resumed the same session at count=2:
| Binary | count=2 result |
|---|---|
PR c19c3c0 |
last 2 turns visible · 4 messages hidden ✅ |
| base (mutant) | everything collapsed · 8 messages hidden — setting silently ignored ❌ |
So the preview behavior comes entirely from this PR; without it the setting is a no-op.
3. Both resume entry points exercised live
qwen --resume <id>→AppContainer.tsx✅/resume <id>slash command →useResumeCommand.ts✅ (samecount=2→ last 2 turns +4 messages hidden)/branch(useBranchCommand.ts) not driven live, but it is the identical 2-line wiring and its 17 unit tests pass./history expand-nowafter a partial collapse re-revealed all 4 turns and dropped the summary → canonical history is untouched, exactly as the PR claims ("only thesuppressOnRestoredisplay flag is varied").
4. Unit tests + non-vacuousness
- 62 / 62 pass at head:
resumeHistoryUtils.test.ts(24) +useResumeCommand.test.ts(11) +useBranchCommand.test.ts(17) + my own independent suite (10 — harder data: interleavedtool_groupitems, a leading non-user item, out-of-range counts). - Mutation: with the function reverted to base, 8 count-sensitive tests fail (3 from the PR's suite — partial preview / preview-covers-all /
-1; 5 from mine), while the collapse-all andcollapseOnResume:falsetests stay green (correctly base-compatible). The new tests genuinely guard the change. npm run typecheck(cli) clean on the merged head.
5. CI / merge state
Test (ubuntu-latest, Node 22.x) pass 21m32s (the leg that runs the schema check + unit tests). PR is MERGEABLE · CLEAN · APPROVED.
6. Non-blocking nits (cosmetic robustness — unchanged from my earlier note)
collapsePreviewCountistype: "number"with no integer/min constraint. Verified live:2.5and-2both silently collapse everything (8 messages hidden) instead of a partial preview — only-1is the "show all" sentinel, and only positive integers yield a preview. Surprising but harmless (the default0path is byte-for-byte unchanged). Optional hardening: coerce to integer and clamp to>= -1.- Summary placement: on a partial collapse the summary renders below the visible recent turns (
…DELTA444then4 messages hidden), consistent with the existing collapse-all placement. Since the hidden items are the older ones, a top placement might read more naturally — purely a design call, not a correctness issue.
Verdict: verified merge-ready. Real-TUI behavior is correct on every branch, the new logic is load-bearing, tests are non-vacuous, and CI is green. The nits are optional polish, not blockers.
🇨🇳 中文版(点击展开)
✅ 维护者复验(HEAD c19c3c0)—— 真实 TUI 构建测试(tmux)+ 基线 A/B + 变异测试
接续我之前的评审(当时指出生成的 settings.schema.json 没重新生成):那个阻塞已由 c19c3c0 chore: regenerate settings schema 修复,Test (ubuntu-latest) 现在是绿的。我从当前 head 重新构建了真实的 qwen 二进制(npm ci && npm run build),并在 tmux 里端到端驱动验证。
结论:每个分支的行为都与规格一致;新逻辑确实承重(已用基线 A/B 证明);测试非空过;typecheck/CI 全绿 —— 可以合并。 下面两条是非阻塞的小问题。
1. 真实 TUI 行为矩阵
用 glm-5.2 录制了一个真实的 4 轮会话(ALPHA111 → BRAVO222 → CHARLIE333 → DELTA444,恢复后共 8 条历史项:4 条 user + 4 条 assistant),再用 qwen --resume <id> 在各设置下恢复(collapseOnResume: true):
collapsePreviewCount |
TUI 中可见的轮次 | 摘要行 |
|---|---|---|
0(默认) |
(无) | ● History collapsed: 8 messages hidden |
1 |
DELTA444 | ● History collapsed: 6 messages hidden |
2 |
CHARLIE333、DELTA444 | ● History collapsed: 4 messages hidden |
-1 |
全部 4 轮 | (无摘要) |
5(> 轮数) |
全部 4 轮 | (无摘要) |
计数不变式精确成立:每轮 2 条,保留 N 轮即隐藏 8 − 2N,摘要只统计被隐藏的条目。
2. 基线 A/B —— 证明新代码承重的关键证据
只把 applyCollapsePolicyAndSummary 还原成 PR 前的函数体(保留签名让 tsc 通过),重建 CLI,再用同一个会话在 count=2 下恢复:
| 二进制 | count=2 结果 |
|---|---|
PR c19c3c0 |
最后 2 轮可见 · 4 messages hidden ✅ |
| 基线(变异体) | 全部折叠 · 8 messages hidden,设置被静默忽略 ❌ |
即:preview 行为完全来自本 PR,没有它该设置就是个空操作。
3. 两个恢复入口都做了实测
qwen --resume <id>→AppContainer.tsx✅/resume <id>斜杠命令 →useResumeCommand.ts✅(同样count=2→ 最后 2 轮 +4 messages hidden)/branch(useBranchCommand.ts)未实测,但它是完全相同的两行接线,其 17 个单测通过。- 部分折叠后执行
/history expand-now重新显示了全部 4 轮并去掉了摘要 → 规范历史未被改动,与 PR 声明一致("只改suppressOnRestore显示标志")。
4. 单元测试 + 非空过验证
- head 上 62 / 62 通过:
resumeHistoryUtils.test.ts(24) +useResumeCommand.test.ts(11) +useBranchCommand.test.ts(17) + 我自己的独立套件(10 —— 用了更难的数据:穿插的tool_group项、起首的非 user 项、越界计数)。 - 变异测试: 把函数还原成基线后,8 个与计数相关的测试失败(PR 套件里 3 个 —— 部分预览/预览覆盖全部/
-1;我的 5 个),而 collapse-all 和collapseOnResume:false的测试仍绿(与基线兼容,正确)。新测试确实守住了这次改动。 npm run typecheck(cli)在合并后的 head 上干净。
5. CI / 合并状态
Test (ubuntu-latest, Node 22.x) 通过 21m32s(跑 schema 检查 + 单测的那条腿)。PR 为 MERGEABLE · CLEAN · APPROVED。
6. 非阻塞小问题(健壮性打磨,与上次一致)
collapsePreviewCount是type: "number",没有整数/最小值约束。 实测:2.5和-2都会静默折叠全部(8 messages hidden),而不是部分预览 —— 只有-1是 "全显" 哨兵值,且只有正整数才给预览。意外但无害(默认0路径逐字节不变)。可选加固:强制取整并钳到>= -1。- 摘要位置: 部分折叠时摘要渲染在可见的近期轮次下方(
…DELTA444之后才是4 messages hidden),与既有的 collapse-all 摆放一致。但被隐藏的是更早的内容,放到顶部可能更直观 —— 纯设计取舍,非正确性问题。
结论:复验通过,可合并。 每个分支的真实 TUI 行为都正确,新逻辑承重,测试非空过,CI 全绿;两条小问题属可选打磨,不阻塞合并。
Verified locally on macOS by building the real binary from c19c3c0 and driving it in tmux (recorded a live 4-turn session, resumed under each setting, base-A/B via source revert + CLI rebuild, vitest mutation). Not a substitute for the author's own platform testing.
DragonnZhang
left a comment
There was a problem hiding this comment.
Automated code review — no high-confidence critical findings in the changed code at this commit.
Reviewed applyCollapsePolicyAndSummary with the new collapsePreviewCount parameter. The boundary logic correctly handles: 0 (collapse all), -1 (show all, return early), N > available user turns (boundary=0, show all without summary), N ≤ available user turns (hide items before boundary). The summary count reflects boundary (hidden items only), not total items. Tests cover all cases including empty history. No critical issues found.
Generated by Claude Code
|
Maintainer note: current head The remaining unresolved review threads are suggestions / nice-to-haves rather than blockers. The two follow-ups I would keep on the radar are:
These can be handled either as a tiny pre-merge polish commit or a post-merge follow-up. They are not blocking from my side. |
Resolve conflict in docs/users/configuration/settings.md: keep main's new `ui.history.collapsePreviewCount` row (QwenLM#5848) alongside this branch's updated `ui.compactMode` description. The incoming side kept the stale "Toggle with Ctrl+O during a session" wording, which is wrong now that this branch retired compactMode in the terminal UI (Ctrl+O opens the full-detail transcript, it no longer toggles a mode), so the retired-in-TUI description is preserved. settingsSchema.ts, settings.schema.json, AppContainer.tsx and resumeHistoryUtils.ts auto-merged cleanly; regenerating the schema produced no diff, confirming the auto-merge was correct. Generated with AI Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
What this PR does
Adds a new
ui.history.collapsePreviewCountsetting (number, default0) that keeps the most recent N user turns visible while collapsing the rest of the restored transcript when resuming a session withui.history.collapseOnResumeenabled. A user turn is a user prompt plus its assistant response and associated tool/thinking items. The summary line's hidden count reflects only the items that were actually collapsed, and the summary is omitted when nothing is hidden.Why it's needed
Today, when
ui.history.collapseOnResumeis enabled, resuming a session hides the entire restored transcript and shows only a one-line summary. That avoids the slow full-history redraw, but it makes it impossible to see where you left off without running/history expand-now, which re-triggers the same slow redraw. As discussed in #5759, the resume-collapse path is currently all-or-nothing.collapsePreviewCountmakes the collapse partial so the last N turns stay readable while older context is summarized.Semantics:
0(default) collapses all restored history and the summary shows the full count (unchanged behavior);N(> 0) keeps the last N user turns visible, collapses earlier items, and the summary counts only the hidden items (if N is greater than or equal to the number of turns, all turns stay visible and no summary is appended);-1shows all restored history (equivalent tocollapseOnResume: false); whencollapseOnResumeisfalse,collapsePreviewCounthas no effect.Reviewer Test Plan
This is a non–user-visible logic change to the resume-history policy plus a new setting, covered by unit tests.
How to verify
applyCollapsePolicyAndSummarynow accepts acollapsePreviewCountargument and is exercised by new unit tests covering: default-collapse (all hidden, full summary count), partial preview (last N turns visible, summary counts only hidden items), preview larger than the turn count (all visible, no summary),-1(all visible, no summary),collapseOnResume: false(raw items unchanged), and empty history (no summary, no crash). The setting is read at the three resume call sites (AppContainer.tsx,useResumeCommand.ts,useBranchCommand.ts) and threaded through.Reviewer commands:
npx vitest run src/ui/utils/resumeHistoryUtils.test.ts(24 tests pass)npx vitest run src/ui/hooks/useResumeCommand.test.ts src/ui/hooks/useBranchCommand.test.ts(28 tests pass)npm run typecheck,npm run lint,npm run format— clean.Evidence (Before & After)
N/A (non–user-visible logic change to the resume-history policy; verified via unit tests and typecheck output above).
Tested on
Environment (optional)
N/A — unit tests only (
vitest,tsc --noEmit).Risk & Scope
MessageType.USERitems; the default0path is preserved byte-for-byte so existing collapse-on-resume behavior is unchanged./history expand-nowor the rewind/turn-mapping paths; canonical history is untouched (only thesuppressOnRestoredisplay flag is varied).0, which is the current behavior.Linked Issues
Fixes #5759