fix(cli): statusline not re-rendering when switching from preset to command type#4706
fix(cli): statusline not re-rendering when switching from preset to command type#4706BZ-D wants to merge 6 commits into
Conversation
…ommand type When `/statusline [prompt]` triggers the statusline-setup agent to change the config type from preset to command, the in-memory LoadedSettings is never updated (the agent edits settings.json on disk via Edit/Write tools), so useStatusLine continues rendering the stale preset config. - Add LoadedSettings.reloadScopeFromDisk() to re-read a settings file from disk with env-var resolution and rawJson sync - Add notifyStatusLineReloaded callback that clears the stale preset override and bumps statusLineSettingsVersion to trigger re-render - Wire an onComplete callback in statuslineCommand that reloads user settings and notifies the statusline hook after the agent turn completes - Clear submitPromptOnCompleteRef on cancel/error to prevent stale callbacks from leaking to subsequent turns - Update statusline docs with preset mode reference, worktree JSON field, and preset-specific troubleshooting entries
onComplete fires when processGeminiStreamEvents returns, which happens as soon as tool calls are scheduled — before the statusline-setup agent has finished writing to settings.json. The fix adds a reload effect in useStatusLine that triggers when streamingState transitions to Idle (all tools done, no pending continuations), which is the true end of a model turn. The onComplete callback is kept as belt-and-suspenders for non-agentic slash commands (those that don't invoke tools), but the primary sync point is now the streamingState → Idle transition.
The onComplete callback fires when processGeminiStreamEvents returns, which is before the statusline-setup agent finishes writing settings.json. Remove the entire onComplete + notifyStatusLineReloaded plumbing and rely solely on the streamingState → Idle reload effect in useStatusLine. Also optimize the reload effect to compare the serialized statusLine config before and after reloading from disk, only bumping the re-render key when the config actually changed — avoids unnecessary doUpdate() calls on turns that didn't touch statusline settings.
📋 Review SummaryThis PR fixes a critical issue where the statusline doesn't re-render when switching from preset to command mode via the 🔍 General Feedback
🎯 Specific Feedback🟡 High
🟢 Medium
🔵 Low
✅ Highlights
|
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. |
Verification Report — PR #4706Commit: Test Results
Test File Breakdown
Execution Environment
VerdictAll 5 checks pass. 123 tests cover the changed useStatusLine hook, settings reload, and related statusline components. No regressions detected. |
|
Hey @BZ-D, thanks for the PR! Template: the body uses On direction: this is a real user-facing bug — On approach: the scope feels reasonable. Three logical pieces — Moving on to code review. 🔍 中文说明@BZ-D 感谢贡献! 模板: PR body 使用的是 方向: 这是个真实的用户可见 bug—— 方案: 范围合理,分三个逻辑部分—— 进入代码审查 🔍 — Qwen Code · qwen3.7-max |
|
Code review: Clean implementation, no blockers. My independent proposal was essentially the same — add a
Real-scenario testing: reproduced the bug and verified the fix with tmux. Before (main branch, no fix)Started dev build with preset statusline, edited Statusline still shows preset items ( After (this PR)Same scenario — preset statusline, edit settings to command type, send prompt: Statusline correctly switched to command output after the model turn completed. Fix verified. 中文说明代码审查: 实现干净,无阻塞问题。我的独立方案和 PR 基本一致——在
真实场景测试: 用 tmux 复现了 bug 并验证了修复。 改之前(main 分支,无修复): 用 preset statusline 启动 dev build,编辑 settings.json 改为 改之后(本 PR): 同样场景——statusline 在模型 turn 完成后正确切换为 command 输出( — Qwen Code · qwen3.7-max |
|
Stepping back — this is a clean, focused bugfix that does exactly what it says. The motivation is real (statusline going stale after the My independent proposal was essentially identical to the PR's approach, so there's no simpler path I can point to. The The The template mismatch from Stage 1 is still worth addressing before merge — the Reviewer Test Plan structure (especially the Evidence Before/After and Tested-on sections) exists for exactly this kind of before/after bugfix. Verdict: approve. The fix is correct, tested, and verified in a real session. The template can be cleaned up post-merge or in a follow-up. 中文说明退一步看——这是一个干净、聚焦的 bugfix,做到了它声称的一切。动机是真实的( 我的独立方案和 PR 基本一致,没有更简单的路径可走。
Stage 1 提到的模板不匹配仍建议在合并前处理——Reviewer Test Plan 的结构(特别是 Evidence Before/After 和 Tested-on 部分)正是为这类 before/after bugfix 设计的。 结论:批准。 修复正确、有测试、在真实会话中验证通过。模板可以后续清理。 — Qwen Code · qwen3.7-max |
pomelo-nwu
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
Summary
/statusline [prompt]triggers the statusline-setup agent to change the config type (e.g. preset → command), the in-memoryLoadedSettingsis never updated because the agent editssettings.jsonon disk via file tools — the statusline stays stale until CLI restartLoadedSettings.reloadScopeFromDisk()to re-read a settings file from disk with env-var resolutionuseStatusLinethat fires whenstreamingStatetransitions to Idle (true end of model turn), compares the on-diskui.statusLineconfig against in-memory, and triggers re-render only when it actually changedsubmitPromptOnCompleteRefon cancel/error inuseGeminiStreamto prevent stale callbacks leaking to subsequent turns/statuslinecommand entry in commands.mdTest plan
vitest run packages/cli/src/ui/hooks/useStatusLine.test.ts— 66 tests passvitest run packages/cli/src/ui/commands/statuslineCommand.test.ts— 4 tests passvitest run packages/cli/src/ui/hooks/slashCommandProcessor.test.ts— 48 tests passvitest run packages/cli/src/ui/components/StatusLineDialog.test.tsx— 5 tests passtsc --noEmit— 0 errors/statusline show git branch→ verify statusline switches to command output without restart🤖 Generated with Claude Code