Skip to content

fix(cli): stabilize statusline preset ordering#4634

Merged
BZ-D merged 2 commits into
QwenLM:mainfrom
shenyankm:sheny/statusline-fixed-order
May 31, 2026
Merged

fix(cli): stabilize statusline preset ordering#4634
BZ-D merged 2 commits into
QwenLM:mainfrom
shenyankm:sheny/statusline-fixed-order

Conversation

@shenyankm

Copy link
Copy Markdown
Contributor

What this PR does

This PR makes built-in /statusline preset items behave as a visible item set instead of using MultiSelect insertion order as the display order. Preset items are normalized and rendered using a fixed priority order, so manually written settings, saved dialog settings, preview output, and footer rendering stay consistent.

It also updates the model-related preset behavior so model-with-reasoning remains first, model-only appears immediately after it, and both model entries can be displayed together when selected. The preset order is adjusted to keep model information first, followed by high-frequency runtime information such as Git branch, context remaining, and session token totals.

Why it's needed

Before this change, disabling a statusline preset item and enabling it again caused the item to reappear at the end of the statusline. That made the statusline order unstable and harder to scan during normal use.

Using a fixed internal priority makes the preset configuration easier to reason about: items now represents which preset entries are visible, while display order is controlled by the built-in preset order. This preserves existing settings compatibility while improving the interactive /statusline experience.

Reviewer Test Plan

How to verify

Open /statusline, disable a selected preset item such as context-remaining, enable it again, and save. The saved preset items should return to the fixed priority order instead of appending the toggled item to the end.

Select both model-with-reasoning and model-only. The rendered statusline should show the model-with-reasoning entry first and the plain model entry second, for example qwen3-code-plus high | qwen3-code-plus when reasoning effort is configured.

Use a manually written preset config with items in a scrambled order. The preview and rendered statusline should still display items in the built-in priority order.

Local verification:

cd packages/cli && npx vitest run src/ui/statusLinePresets.test.ts src/ui/components/StatusLineDialog.test.tsx src/ui/hooks/useStatusLine.test.ts
cd packages/cli && npx eslint src/ui/statusLinePresets.ts src/ui/statusLinePresets.test.ts src/ui/components/StatusLineDialog.tsx src/ui/components/StatusLineDialog.test.tsx src/ui/hooks/useStatusLine.ts src/ui/hooks/useStatusLine.test.ts
git diff --check

Evidence (Before & After)

Before: toggling an existing preset item off and back on could move it to the end because the saved order followed MultiSelect insertion order.

After: toggled preset items are saved and rendered in the fixed priority order. Targeted tests cover normalization, dialog saving, preview ordering, footer rendering, and hook integration.

Tested on

OS Status
🍏 macOS ⚠️ not tested
🪟 Windows ✅ tested
🐧 Linux ⚠️ not tested

Environment (optional)

Windows PowerShell. Targeted Vitest tests, ESLint for touched files, and git diff --check pass locally. cd packages/cli && npm run typecheck is currently blocked by an existing missing @qwen-code/channel-feishu module/type dependency, unrelated to this statusline change.

Risk & Scope

  • Main risk or tradeoff: Users who relied on custom ordering within preset items will now see the built-in priority order instead. This matches the intended behavior that preset items controls visibility, not custom ordering.
  • Not validated / out of scope: Custom command statusline payloads are unchanged and were not modified. No new preset fields, schema changes, or user-configurable ordering controls are included.
  • Breaking changes / migration notes: No settings schema migration is required. The existing config id model remains supported; only the UI label is shown as model-only.

Linked Issues

Closes #4633

中文说明

What this PR does

此 PR 将内置 /statusline 预设项改为“可见项集合”语义,不再使用 MultiSelect 的插入顺序作为显示顺序。预设项会通过固定优先级进行归一化和渲染,因此手写 settings、弹窗保存、预览输出和 footer 实际渲染会保持一致。

同时,此 PR 调整了模型相关预设项行为:model-with-reasoning 保持第一位,model-only 紧随其后,并且当两者都被选中时可以同时显示。预设顺序也被调整为模型信息优先,然后显示 Git 分支、上下文剩余、会话 token 总量等高频运行信息。

Why it's needed

在此改动前,用户在 statusline 预设里关闭某个已选项后再重新开启,该项可能会被追加到末尾。这会让 statusline 顺序不稳定,正常使用时更难快速扫描。

使用固定内置优先级后,预设配置更容易理解:items 表示哪些预设项可见,而显示顺序由内置预设顺序控制。这样既保持现有 settings 兼容性,也改善了交互式 /statusline 的使用体验。

Reviewer Test Plan

How to verify

打开 /statusline,关闭一个已选预设项,例如 context-remaining,再重新开启并保存。保存后的 preset items 应回到固定优先级顺序,而不是把刚切换的项目追加到末尾。

同时选择 model-with-reasoningmodel-only。渲染出的 statusline 应先显示带 reasoning 的模型项,再显示纯模型项,例如 reasoning effort 已配置时显示 qwen3-code-plus high | qwen3-code-plus

手写一个乱序的 preset config。预览和实际渲染出的 statusline 仍应按照内置优先级显示。

本地验证:

cd packages/cli && npx vitest run src/ui/statusLinePresets.test.ts src/ui/components/StatusLineDialog.test.tsx src/ui/hooks/useStatusLine.test.ts
cd packages/cli && npx eslint src/ui/statusLinePresets.ts src/ui/statusLinePresets.test.ts src/ui/components/StatusLineDialog.tsx src/ui/components/StatusLineDialog.test.tsx src/ui/hooks/useStatusLine.ts src/ui/hooks/useStatusLine.test.ts
git diff --check

Evidence (Before & After)

Before:关闭某个已有预设项再重新开启时,该项可能移动到末尾,因为保存顺序跟随 MultiSelect 插入顺序。

After:被切换的预设项会按照固定优先级保存和渲染。目标测试覆盖了归一化、弹窗保存、预览顺序、footer 渲染和 hook 集成路径。

Tested on

OS Status
🍏 macOS ⚠️ not tested
🪟 Windows ✅ tested
🐧 Linux ⚠️ not tested

Environment (optional)

Windows PowerShell。本地已通过目标 Vitest、相关文件 ESLint 和 git diff --checkcd packages/cli && npm run typecheck 当前受既有 @qwen-code/channel-feishu 模块/类型依赖缺失影响,和本次 statusline 改动无关。

Risk & Scope

  • Main risk or tradeoff: 如果用户曾依赖 preset items 中的自定义顺序,现在会看到内置优先级顺序。这符合本次预期语义:preset items 控制是否显示,而不是自定义排序。
  • Not validated / out of scope: 自定义 command 类型 statusline payload 未改动,也未新增预设字段、schema 变更或用户自定义排序能力。
  • Breaking changes / migration notes: 不需要 settings schema 迁移。现有配置 id model 保持兼容;仅 UI label 显示为 model-only

Linked Issues

Closes #4633

Comment thread packages/cli/src/ui/statusLinePresets.ts
Add direct coverage for exported statusline preset helper behavior requested during PR review.

Constraint: Address PR QwenLM#4634 review feedback for direct exported helper tests.
Rejected: Relying on existing integration coverage | Direct tests were requested for exported helper contracts.
Confidence: high
Scope-risk: narrow
Directive: Keep preset item ordering and reasoning formatting contracts directly covered when these helpers change.
Tested: cd packages/cli && npx vitest run src/ui/statusLinePresets.test.ts; cd packages/cli && npx vitest run src/ui/statusLinePresets.test.ts src/ui/components/StatusLineDialog.test.tsx src/ui/hooks/useStatusLine.test.ts; cd packages/cli && npx eslint src/ui/statusLinePresets.ts src/ui/statusLinePresets.test.ts; git diff --check
Not-tested: Full repository test suite.
@shenyankm shenyankm requested a review from wenshao May 30, 2026 10:13
@wenshao

wenshao commented May 30, 2026

Copy link
Copy Markdown
Collaborator

Verification Report — PR #4634

Tested locally on: macOS Darwin 25.4.0 / Node.js v22.17.0
Commit: cebf6b09c (test(cli): make statusline helper contracts explicit)
Method: tmux parallel execution of all PR test plan items

Test Results

# Check Result Details
1 npx vitest run (statusLinePresets + StatusLineDialog + useStatusLine) ✅ PASS 82 tests passed (3 files), 15.4s
2 npx eslint (all 6 touched source + test files) ✅ PASS 0 warnings, 0 errors
3 git diff --check ✅ PASS No whitespace issues

Test Breakdown

File Tests
statusLinePresets.test.ts 17 passed
StatusLineDialog.test.tsx 5 passed
useStatusLine.test.ts 60 passed

Summary

All test plan items pass cleanly on macOS (first macOS verification for this PR, which was previously only tested on Windows). The preset normalization, dialog save ordering, preview output, and hook integration are all covered by the 82 tests.


Verified by wenshao

@wenshao wenshao 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 issues found. LGTM! ✅ The statusline preset ordering changes are clean — well-structured refactoring with thorough test coverage (82 tests pass). The previously noted gap around direct unit tests for orderStatusLinePresetItems and formatModelWithReasoning has been addressed. — qwen3.7-max via Qwen Code /review

@shenyankm

Copy link
Copy Markdown
Contributor Author

No issues found. LGTM! ✅ The statusline preset ordering changes are clean — well-structured refactoring with thorough test coverage (82 tests pass). The previously noted gap around direct unit tests for orderStatusLinePresetItems and formatModelWithReasoning has been addressed. — qwen3.7-max via Qwen Code /review

使用时发现,在配置/statusline时,可选项(左侧的)与项目自带的(右侧的)似乎重复;且与下方的mode共同显示为两行占位,能否优化,将右侧的“上下文显示”删除,使用/statusline中的即可(虽然不确定用户是否会配置),然后将mode切换移动到上一行右侧同行显示,感觉观感会好一些。想听听您的建议。
image

@wenshao wenshao requested a review from BZ-D May 30, 2026 15:37

@BZ-D BZ-D 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.

LGTM

@BZ-D BZ-D merged commit 54b6b20 into QwenLM:main May 31, 2026
9 checks passed
@shenyankm shenyankm deleted the sheny/statusline-fixed-order branch May 31, 2026 06:49
@wenshao

wenshao commented May 31, 2026

Copy link
Copy Markdown
Collaborator

@shenyankm 建议合理 👍 右侧 footer 的上下文显示(ContextUsageDisplay)和 statusline 里的 context-remaining / context-used 确实重复,值得收敛。

动手前有两个约束想先同步一下:

  1. 和上游对齐:Footer 现在的两行布局(statusline 在上、hints/mode 在下)是刻意跟 upstream 保持一致的(Footer.tsx 里有 // Layout matches upstream 注释)。把 mode 挪到上一行同行显示会和上游分歧,后续 merge 上游改动时容易冲突,这个取舍要先确认。

  2. 右侧 context 是兜底显示:它目前是无条件渲染的(只要 promptTokenCount > 0 && contextWindowSize 就显示),不依赖用户有没有配置 statusline。如果直接删掉,没有配置 statusline context 项的用户就看不到上下文占用了,属于 regression。

所以我倾向于一个条件隐藏的方案,而不是直接删:仅当 statusline 已经包含 context 项(context-remainingcontext-used)时,才隐藏右侧 footer 的 ContextUsageDisplay,否则保留兜底显示。这样既消除了重复,又不影响没配 statusline 的用户。mode 同行因为牵涉到和上游布局的分歧,可以单独低优先级评估。

方向 OK 的话,另开一个 issue/PR 单独跟进就行,不动已经合并的 #4634

@BZ-D

BZ-D commented May 31, 2026

Copy link
Copy Markdown
Collaborator

No issues found. LGTM! ✅ The statusline preset ordering changes are clean — well-structured refactoring with thorough test coverage (82 tests pass). The previously noted gap around direct unit tests for orderStatusLinePresetItems and formatModelWithReasoning has been addressed. — qwen3.7-max via Qwen Code /review

使用时发现,在配置/statusline时,可选项(左侧的)与项目自带的(右侧的)似乎重复;且与下方的mode共同显示为两行占位,能否优化,将右侧的“上下文显示”删除,使用/statusline中的即可(虽然不确定用户是否会配置),然后将mode切换移动到上一行右侧同行显示,感觉观感会好一些。想听听您的建议。 image

现在主流 Code CLI 的 Approval Mode 在 TUI 中均另起一行并左对齐显示,放到右边的话会改变用户心智,而且这个位置也不是固定的,会根据用户是否在 statusline 中 preset 了 remaining context 而呈现不同的 TUI。个人认为无需改动

@shenyankm

Copy link
Copy Markdown
Contributor Author

No issues found. LGTM! ✅ The statusline preset ordering changes are clean — well-structured refactoring with thorough test coverage (82 tests pass). The previously noted gap around direct unit tests for orderStatusLinePresetItems and formatModelWithReasoning has been addressed. — qwen3.7-max via Qwen Code /review

使用时发现,在配置/statusline时,可选项(左侧的)与项目自带的(右侧的)似乎重复;且与下方的mode共同显示为两行占位,能否优化,将右侧的“上下文显示”删除,使用/statusline中的即可(虽然不确定用户是否会配置),然后将mode切换移动到上一行右侧同行显示,感觉观感会好一些。想听听您的建议。 image

现在主流 Code CLI 的 Approval Mode 在 TUI 中均另起一行并左对齐显示,放到右边的话会改变用户心智,而且这个位置也不是固定的,会根据用户是否在 statusline 中 preset 了 remaining context 而呈现不同的 TUI。个人认为无需改动

👌

@shenyankm

Copy link
Copy Markdown
Contributor Author

@shenyankm 建议合理 👍 右侧 footer 的上下文显示(ContextUsageDisplay)和 statusline 里的 context-remaining / context-used 确实重复,值得收敛。

动手前有两个约束想先同步一下:

  1. 和上游对齐:Footer 现在的两行布局(statusline 在上、hints/mode 在下)是刻意跟 upstream 保持一致的(Footer.tsx 里有 // Layout matches upstream 注释)。把 mode 挪到上一行同行显示会和上游分歧,后续 merge 上游改动时容易冲突,这个取舍要先确认。
  2. 右侧 context 是兜底显示:它目前是无条件渲染的(只要 promptTokenCount > 0 && contextWindowSize 就显示),不依赖用户有没有配置 statusline。如果直接删掉,没有配置 statusline context 项的用户就看不到上下文占用了,属于 regression。

所以我倾向于一个条件隐藏的方案,而不是直接删:仅当 statusline 已经包含 context 项(context-remainingcontext-used)时,才隐藏右侧 footer 的 ContextUsageDisplay,否则保留兜底显示。这样既消除了重复,又不影响没配 statusline 的用户。mode 同行因为牵涉到和上游布局的分歧,可以单独低优先级评估。

方向 OK 的话,另开一个 issue/PR 单独跟进就行,不动已经合并的 #4634

收到!

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.

Improve statusline preset ordering and model display behavior

3 participants