feat: optimize compact mode UX — shortcuts, settings sync, and safety#3100
feat: optimize compact mode UX — shortcuts, settings sync, and safety#3100tanzhenxin merged 7 commits intomainfrom
Conversation
📋 Review SummaryThis PR delivers a comprehensive UX optimization for the compact mode (Ctrl+O) feature, building on top of #3047. The implementation is well-structured and addresses discoverability, settings synchronization, and safety concerns for tool approval prompts. The code quality is generally high with good attention to i18n, documentation, and consistent patterns across the codebase. 🔍 General Feedback
🎯 Specific Feedback🟡 High
🟢 Medium
🔵 Low
✅ Highlights
|
… improvements - Add Ctrl+O to keyboard shortcuts list (?) and /help command - Sync compact mode toggle from Settings dialog with CompactModeContext - Protect tool approval prompts from being hidden in compact mode (MainContent forces live rendering during WaitingForConfirmation) - Remove snapshot freezing on toggle — treat as persistent preference, not temporary peek (differs from Claude Code's session-scoped model) - Add compact mode tip to startup Tips rotation for non-intrusive discovery - Remove compact mode indicator from footer to reduce UI clutter - Add competitive analysis design doc (EN + ZH) comparing with Claude Code - Update user docs (settings.md) and i18n translations (en/zh/ru/pt) Relates to #3047, #2767, #2770 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove frozenSnapshot state, useEffect, and all related logic from AppContainer, MainContent, CompactModeContext, and test files - Simplify MainContent to always render live pendingHistoryItems - Delete compact-mode-design-zh.md (redundant Chinese translation) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a04f4cf to
a7acd1e
Compare
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. |
There was a problem hiding this comment.
Pull request overview
This PR improves the CLI “compact mode” UX by increasing shortcut discoverability, syncing Settings changes to live UI state, and removing the “snapshot freeze” behavior so rendering stays live (especially for confirmations and streaming).
Changes:
- Expose
Ctrl+Ocompact-mode toggle in the?shortcuts overlay,/help, and startup Tips. - Sync compact mode toggles in Settings to the in-session UI state via
CompactModeContext. - Remove frozen-snapshot rendering and the compact footer indicator; update docs and add a design/competitive analysis document.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/cli/src/ui/contexts/CompactModeContext.tsx | Simplifies compact mode context; adds setCompactMode for in-session sync. |
| packages/cli/src/ui/components/Tips.tsx | Adds compact-mode tip to startup tips rotation. |
| packages/cli/src/ui/components/SettingsDialog.tsx | Syncs ui.compactMode setting changes to CompactModeContext. |
| packages/cli/src/ui/components/messages/ToolMessage.test.tsx | Updates provider value shape after context change. |
| packages/cli/src/ui/components/MainContent.tsx | Removes frozen-snapshot rendering path; always renders live pending items. |
| packages/cli/src/ui/components/KeyboardShortcuts.tsx | Adds ctrl+o shortcut; adjusts column split counts. |
| packages/cli/src/ui/components/Help.tsx | Adds Ctrl+O to help shortcut list. |
| packages/cli/src/ui/components/Footer.tsx | Removes persistent compact indicator in footer. |
| packages/cli/src/ui/AppContainer.tsx | Removes frozen-snapshot state; provides setCompactMode via context; keeps refreshStatic() on Ctrl+O. |
| packages/cli/src/i18n/locales/en.js | Adds new compact-mode related translation keys. |
| packages/cli/src/i18n/locales/zh.js | Adds new compact-mode related translation keys (ZH). |
| packages/cli/src/i18n/locales/ru.js | Adds new compact-mode related translation keys (RU). |
| packages/cli/src/i18n/locales/pt.js | Adds new compact-mode related translation keys (PT). |
| docs/users/configuration/settings.md | Updates ui.compactMode documentation to reflect Settings toggle + safety guarantees. |
| docs/design/compact-mode/compact-mode-design.md | Adds compact mode competitive analysis / design doc. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Special handling for compact mode to sync with CompactModeContext | ||
| if (key === 'ui.compactMode' && newValue !== compactMode) { | ||
| setCompactMode?.(newValue as boolean); | ||
| } |
There was a problem hiding this comment.
Toggling ui.compactMode here updates React state, but it doesn’t trigger refreshStatic(). Because chat history is rendered inside Ink’s <Static>, the already-rendered history won’t be retroactively re-rendered like it is when toggling via Ctrl+O (which calls refreshStatic() in AppContainer). Consider calling useUIActions().refreshStatic() after setCompactMode so the UI updates immediately and consistently regardless of toggle entry point.
There was a problem hiding this comment.
Fixed in e45c997. Added useUIActions().refreshStatic() call after setCompactMode so Ink's <Static> history re-renders immediately, consistent with the Ctrl+O toggle path in AppContainer.
| // Column distribution for different layouts (4+4+4 for 3 cols, 6+6 for 2 cols) | ||
| const COLUMN_SPLITS: Record<number, number[]> = { | ||
| 3: [4, 4, 4], | ||
| 2: [6, 6], | ||
| 1: [12], | ||
| 3: [5, 4, 4], | ||
| 2: [7, 6], | ||
| 1: [13], | ||
| }; |
There was a problem hiding this comment.
The layout comment is now inaccurate: the column splits were changed to 5+4+4 / 7+6 / 13. Please update the comment so it matches the actual COLUMN_SPLITS values to avoid confusion during future changes.
There was a problem hiding this comment.
Fixed in e45c997. Updated comment to 5+4+4 for 3 cols, 7+6 for 2 cols.
| | Toggle semantics | Temporary peek at details | Persistent preference switch | | ||
| | Persistence | Session-only, resets on restart | Persisted to settings.json | | ||
| | Scope | Global screen switch (prompt ↔ transcript) | Per-component rendering toggle | | ||
| | Frozen snapshot | None (no concept) | Infrastructure exists, currently unused | |
There was a problem hiding this comment.
This document states that Qwen Code has a frozenSnapshot infrastructure (and that it’s “currently unused”), but this PR removes frozenSnapshot entirely from the UI code. Please update the table row to reflect the current implementation so the design doc doesn’t contradict the source.
| | Frozen snapshot | None (no concept) | Infrastructure exists, currently unused | | |
| | Frozen snapshot | None (no concept) | None (removed from UI code) | |
There was a problem hiding this comment.
Fixed in e45c997. Updated table row to None (removed) — frozenSnapshot was fully removed in this PR.
| ``` | ||
| ┌─────────────────────────────────────┐ | ||
| │ CompactModeContext │ | ||
| │ compactMode: boolean (default: false)│ | ||
| │ frozenSnapshot: items[] | null │ | ||
| │ setCompactMode: (v) => void │ | ||
| └──────────┬──────────────────────────┘ | ||
| │ |
There was a problem hiding this comment.
The Qwen Code architecture diagram still includes frozenSnapshot: items[] | null, but CompactModeContext no longer exposes or uses frozenSnapshot after this PR. Please update the diagram accordingly.
There was a problem hiding this comment.
Fixed in e45c997. Removed frozenSnapshot: items[] | null from the architecture diagram.
| | Component | File | Key Logic | | ||
| | --------------- | ------------------------------------- | ------------------------------------------------- | | ||
| | Toggle handler | `AppContainer.tsx:1684-1694` | Toggles `compactMode`, persists, clears snapshot | | ||
| | Context | `CompactModeContext.tsx` | `compactMode`, `frozenSnapshot`, `setCompactMode` | | ||
| | Tool group | `ToolGroupMessage.tsx:105-110` | `showCompact` with 4 force-expand conditions | | ||
| | Tool message | `ToolMessage.tsx:346-350` | Hides `displayRenderer` in compact mode | | ||
| | Compact display | `CompactToolGroupDisplay.tsx:49-108` | Single-line summary with status + hint | | ||
| | Confirmation | `ToolConfirmationMessage.tsx:113-147` | Simplified 3-option compact approval | | ||
| | Tips | `Tips.tsx:14-29` | Startup tip rotation includes compact mode hint | | ||
| | Settings sync | `SettingsDialog.tsx:189-192` | Syncs with CompactModeContext | | ||
| | MainContent | `MainContent.tsx:63-72` | frozenSnapshot with WaitingForConfirmation guard | | ||
| | Thinking | `HistoryItemDisplay.tsx:123-133` | Hides `gemini_thought` in compact mode | |
There was a problem hiding this comment.
The “Key Source Files” section references frozenSnapshot behavior (e.g., “clears snapshot”, and MainContent using a frozenSnapshot guard). Since frozenSnapshot was removed in this PR, these entries are now outdated and should be revised to match the current code paths.
There was a problem hiding this comment.
Fixed in e45c997. Updated all Key Source Files entries — removed snapshot references from Toggle handler, Context, Settings sync, and MainContent descriptions.
| 'to search history': 'to search history', | ||
| 'to paste images': 'to paste images', | ||
| 'for external editor': 'for external editor', | ||
| 'to toggle compact mode': 'to toggle compact mode', | ||
| 'Jump through words in the input': 'Jump through words in the input', |
There was a problem hiding this comment.
New i18n keys were added here for compact-mode discoverability, but other built-in locales (notably de.js and ja.js) do not define them, so those UIs will fall back to the English keys. Please add corresponding entries to all supported built-in locale files to keep translations consistent.
There was a problem hiding this comment.
Fixed in e45c997. Added to toggle compact mode, compact mode: on (Ctrl+O off), and the Tips string to both de.js and ja.js locales.
| // Special handling for compact mode to sync with CompactModeContext | ||
| if (key === 'ui.compactMode' && newValue !== compactMode) { | ||
| setCompactMode?.(newValue as boolean); | ||
| } |
There was a problem hiding this comment.
This PR adds new integration behavior for ui.compactMode (syncing the Settings toggle to CompactModeContext), but there doesn’t appear to be a test asserting that setCompactMode is called when the setting is toggled (similar to the existing VimModeContext integration coverage). Adding a focused test would help prevent regressions in Settings↔UI sync.
There was a problem hiding this comment.
Fixed in e45c997. Added a focused test should sync compact mode with CompactModeContext when toggled that verifies both setCompactMode and refreshStatic are called when ui.compactMode is toggled in the Settings dialog.
- Add refreshStatic() call after setCompactMode in SettingsDialog so already-rendered Static history updates immediately - Fix outdated column split comment in KeyboardShortcuts (5+4+4) - Update design doc: remove all frozenSnapshot references, renumber optimization recommendations, fix file reference descriptions - Add missing i18n keys for de.js and ja.js locales - Add test for SettingsDialog compact mode sync with CompactModeContext Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
hasConfirmingTool only checks ToolCallStatus.Confirming, but subagent approvals arrive via resultDisplay.pendingConfirmation while the tool status remains Executing. Add hasSubagentPendingConfirmation to the showCompact guard so tool groups with pending subagent confirmations are always force-expanded. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Review
Good work on the snapshot removal and the group-level showCompact guard for subagent confirmations. The frozen snapshot elimination simplifies MainContent.tsx significantly, and the competitive analysis in the design doc is a useful reference.
However, the tool group correctly expands, but the individual tool message inside it still hides its result in compact mode. Subagent approvals live inside that result, so the accept/reject controls never render.
To reproduce: start qwen in default approval mode, press Ctrl+O for compact mode, then ask it to spawn a subagent that writes a file. The tool group expands but the approval controls are missing. The only escape is Ctrl+O to disable compact mode.
Verdict
REQUEST_CHANGES — subagent approval controls hidden in compact mode is a blocker.
The previous fix (47ee03c) correctly force-expanded the tool group wrapper when a subagent had pending confirmation, but each inner ToolMessage still hid its resultDisplay due to compactMode check, which hid the AgentExecutionDisplay containing the inline confirmation UI. Add isAgentWithPendingConfirmation to forceShowResult conditions so the inner AgentExecutionDisplay is rendered even in compact mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@tanzhenxin Thanks for the thorough repro! You're exactly right — the group-level Fixed in 2ae5920: Added Verified locally with the reproduction steps you provided:
The complete fix now covers two layers:
PTAL when you have a moment 🙏 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| │ ToolGroupMessage │ | ||
| │ showCompact = compactMode │ | ||
| │ && !hasConfirmingTool │ | ||
| │ && !hasErrorTool │ | ||
| │ && !isEmbeddedShellFocused │ | ||
| │ && !isUserInitiated │ |
There was a problem hiding this comment.
The Qwen Code architecture diagram’s showCompact condition list is missing the new subagent-pending-confirmation guard (e.g. !hasSubagentPendingConfirmation). Please update the diagram so it matches the current ToolGroupMessage logic and accurately documents when compact mode is forced to expand.
| | Component | File | Key Logic | | ||
| | --------------- | ------------------------------------- | ----------------------------------------------- | | ||
| | Toggle handler | `AppContainer.tsx:1684-1690` | Toggles `compactMode`, persists to settings | | ||
| | Context | `CompactModeContext.tsx` | `compactMode`, `setCompactMode` | | ||
| | Tool group | `ToolGroupMessage.tsx:105-110` | `showCompact` with 4 force-expand conditions | | ||
| | Tool message | `ToolMessage.tsx:346-350` | Hides `displayRenderer` in compact mode | | ||
| | Compact display | `CompactToolGroupDisplay.tsx:49-108` | Single-line summary with status + hint | | ||
| | Confirmation | `ToolConfirmationMessage.tsx:113-147` | Simplified 3-option compact approval | | ||
| | Tips | `Tips.tsx:14-29` | Startup tip rotation includes compact mode hint | | ||
| | Settings sync | `SettingsDialog.tsx:189-193` | Syncs with CompactModeContext + refreshStatic | | ||
| | MainContent | `MainContent.tsx:60-76` | Renders live pendingHistoryItems | | ||
| | Thinking | `HistoryItemDisplay.tsx:123-133` | Hides `gemini_thought` in compact mode | | ||
|
|
||
| ### 3.3 Design Decisions | ||
|
|
||
| 1. **Verbose is the default.** Users see all tool output and thinking by default. | ||
| 2. **Persistent preference.** `compactMode` is saved to `settings.json` and survives across sessions. | ||
| 3. **Component-level rendering.** Each component reads `compactMode` from context and adjusts its own rendering. | ||
| 4. **Force-expand protection.** Four conditions override compact mode to ensure critical UI elements are always visible (confirmations, errors, shell, user-initiated). |
There was a problem hiding this comment.
This table row says showCompact has “4 force-expand conditions”, but the implementation now has an additional force-expand case for subagents awaiting approval (pending confirmation). Please update the count/wording here to avoid the design doc contradicting the code.
| | Component | File | Key Logic | | |
| | --------------- | ------------------------------------- | ----------------------------------------------- | | |
| | Toggle handler | `AppContainer.tsx:1684-1690` | Toggles `compactMode`, persists to settings | | |
| | Context | `CompactModeContext.tsx` | `compactMode`, `setCompactMode` | | |
| | Tool group | `ToolGroupMessage.tsx:105-110` | `showCompact` with 4 force-expand conditions | | |
| | Tool message | `ToolMessage.tsx:346-350` | Hides `displayRenderer` in compact mode | | |
| | Compact display | `CompactToolGroupDisplay.tsx:49-108` | Single-line summary with status + hint | | |
| | Confirmation | `ToolConfirmationMessage.tsx:113-147` | Simplified 3-option compact approval | | |
| | Tips | `Tips.tsx:14-29` | Startup tip rotation includes compact mode hint | | |
| | Settings sync | `SettingsDialog.tsx:189-193` | Syncs with CompactModeContext + refreshStatic | | |
| | MainContent | `MainContent.tsx:60-76` | Renders live pendingHistoryItems | | |
| | Thinking | `HistoryItemDisplay.tsx:123-133` | Hides `gemini_thought` in compact mode | | |
| ### 3.3 Design Decisions | |
| 1. **Verbose is the default.** Users see all tool output and thinking by default. | |
| 2. **Persistent preference.** `compactMode` is saved to `settings.json` and survives across sessions. | |
| 3. **Component-level rendering.** Each component reads `compactMode` from context and adjusts its own rendering. | |
| 4. **Force-expand protection.** Four conditions override compact mode to ensure critical UI elements are always visible (confirmations, errors, shell, user-initiated). | |
| | Component | File | Key Logic | | |
| | --------------- | ------------------------------------- | -------------------------------------------------------------------- | | |
| | Toggle handler | `AppContainer.tsx:1684-1690` | Toggles `compactMode`, persists to settings | | |
| | Context | `CompactModeContext.tsx` | `compactMode`, `setCompactMode` | | |
| | Tool group | `ToolGroupMessage.tsx:105-110` | `showCompact` with 5 force-expand conditions, including pending confirmation subagents | | |
| | Tool message | `ToolMessage.tsx:346-350` | Hides `displayRenderer` in compact mode | | |
| | Compact display | `CompactToolGroupDisplay.tsx:49-108` | Single-line summary with status + hint | | |
| | Confirmation | `ToolConfirmationMessage.tsx:113-147` | Simplified 3-option compact approval | | |
| | Tips | `Tips.tsx:14-29` | Startup tip rotation includes compact mode hint | | |
| | Settings sync | `SettingsDialog.tsx:189-193` | Syncs with CompactModeContext + refreshStatic | | |
| | MainContent | `MainContent.tsx:60-76` | Renders live pendingHistoryItems | | |
| | Thinking | `HistoryItemDisplay.tsx:123-133` | Hides `gemini_thought` in compact mode | | |
| ### 3.3 Design Decisions | |
| 1. **Verbose is the default.** Users see all tool output and thinking by default. | |
| 2. **Persistent preference.** `compactMode` is saved to `settings.json` and survives across sessions. | |
| 3. **Component-level rendering.** Each component reads `compactMode` from context and adjusts its own rendering. | |
| 4. **Force-expand protection.** Five conditions override compact mode to ensure critical UI elements are always visible (confirmations, errors, shell, user-initiated actions, and pending-confirmation subagents). |
| 1. **Verbose is the default.** Users see all tool output and thinking by default. | ||
| 2. **Persistent preference.** `compactMode` is saved to `settings.json` and survives across sessions. | ||
| 3. **Component-level rendering.** Each component reads `compactMode` from context and adjusts its own rendering. | ||
| 4. **Force-expand protection.** Four conditions override compact mode to ensure critical UI elements are always visible (confirmations, errors, shell, user-initiated). | ||
| 5. **No snapshot freezing.** The toggle always shows live output — no frozen snapshots. |
There was a problem hiding this comment.
The design decision text claims “Four conditions override compact mode”, but ToolGroupMessage now also force-expands when a subagent has pendingConfirmation. Please update this description so it reflects the current set of force-expand conditions.
| | Aspect | Claude Code | Qwen Code | | ||
| | ----------------------- | ------------------------------------------- | ---------------------------------------------------- | | ||
| | Mechanism | Overlay/modal layer (structurally separate) | Force-expand conditions in `showCompact` | | ||
| | Coverage | Complete — approvals can never be hidden | Complete — 4 conditions cover all interactive states | | ||
| | Compact confirmation UI | N/A (overlay is always full) | Simplified 3-option RadioButtonSelect | |
There was a problem hiding this comment.
This comparison table states Qwen Code has “4 conditions” covering all interactive states, but the current implementation includes an additional guard for subagent pending confirmation. Please update the table to reflect the current number/nature of force-expand conditions.
| | Aspect | Claude Code | Qwen Code | | |
| | ----------------------- | ------------------------------------------- | ---------------------------------------------------- | | |
| | Mechanism | Overlay/modal layer (structurally separate) | Force-expand conditions in `showCompact` | | |
| | Coverage | Complete — approvals can never be hidden | Complete — 4 conditions cover all interactive states | | |
| | Compact confirmation UI | N/A (overlay is always full) | Simplified 3-option RadioButtonSelect | | |
| | Aspect | Claude Code | Qwen Code | | |
| | ----------------------- | ------------------------------------------- | ----------------------------------------------------------------------------- | | |
| | Mechanism | Overlay/modal layer (structurally separate) | Force-expand conditions in `showCompact` | | |
| | Coverage | Complete — approvals can never be hidden | Complete — 5 conditions cover interactive states, including subagent pending confirmation | | |
| | Compact confirmation UI | N/A (overlay is always full) | Simplified 3-option RadioButtonSelect | |
wenshao
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅ — gpt-5.4 via Qwen Code /review
In compact mode, sequential tool calls across multiple LLM turns each produced a separate bordered box, defeating the "compact" intent. The model typically emits a `gemini_thought` between consecutive tool calls, which is hidden in compact mode — so visually the boxes look adjacent, but in `history` they are separated by hidden items. This commit adds render-time merging of consecutive tool_group history items, where "consecutive" allows hidden-in-compact items (`gemini_thought`, `gemini_thought_content`) between them. Key pieces: - New `mergeCompactToolGroups` utility that merges adjacent mergeable tool_groups, skipping hidden items between them. Force-expand conditions (Confirming/Error tools, subagent pending confirmation, user-initiated, focused embedded shell) preserve group boundaries so authorization prompts, errors, and shell focus stay visible. - `MainContent.tsx` applies the merger only when `compactMode === true` (verbose mode is unchanged) and calls `refreshStatic()` when a merge consolidates items, because Ink's `<Static>` is append-only and cannot replace already-committed terminal content. - `CompactToolGroupDisplay.tsx` shows a `× N` count when a merged group contains more than one tool, matching the existing single-turn multi-tool display style. - 19 unit tests covering empty/single/multiple groups, hidden-item skipping (the 8-tool real-world scenario), force-expand boundaries, mixed tool types, and complex sequences. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update: Merge consecutive tool groups in compact mode新增 commit 23cc45e 解决了一个紧凑模式下的体验问题:当模型在多个 LLM 轮次中连续调用工具时(如顺序执行 8 次 shell 命令),每次调用都会产生一个独立的边框,违背了紧凑模式"压缩显示"的初衷。 根本原因模型在每次 tool call 之间会产生一个 仅检查"直接相邻"的合并逻辑无法触发,因此用户在紧凑模式下仍然看到 N 个独立框。 实现要点新增
MainContent.tsx
CompactToolGroupDisplay.tsx
视觉效果之前(紧凑模式下 8 个独立框): 之后: 安全保证
测试覆盖
cc @tanzhenxin 麻烦再帮忙 review 一下这次的合并优化 🙏 |
| const currHLen = uiState.history.length; | ||
| const prevMLen = prevMergedLengthRef.current; | ||
| const currMLen = mergedHistory.length; | ||
| // History grew, but merged length stayed same or shrank → a merge happened. |
There was a problem hiding this comment.
[Critical] refreshStatic() is only triggered when history.length grows, but the compact projection can also change when no new history item is appended (for example when a tool changes from Executing to Success, or when embeddedShellFocused / activePtyId changes). In those cases Ink's append-only <Static> can keep the stale pre-merge / pre-expand output on screen.
A safer fix is to refresh whenever the compact-mode projection changes in a way <Static> cannot reconcile, not only when raw history grows.
— gpt-5.4 via Qwen Code /review
tanzhenxin
left a comment
There was a problem hiding this comment.
Re-review
The subagent confirmation blocker is correctly fixed with a two-layer approach — group-level expand via hasSubagentPendingConfirmation in showCompact, plus tool-level result display via isAgentWithPendingConfirmation in forceShowResult. Both layers are necessary.
The new mergeCompactToolGroups feature is well-implemented: clean separation, correct force-expand boundaries, no input mutation, and thorough test coverage (19 tests).
Regarding wenshao's refreshStatic() concern — this is a false positive. uiState.history (fed to <Static>) contains only finalized items whose statuses don't change after insertion. Status transitions (Executing → Complete) happen in pendingHistoryItems in the live area, unaffected by the merge logic.
Non-blocking items for follow-up:
- Debounce
refreshStatic()during rapid tool sequences - Extract duplicated
isAgentWithPendingConfirmationto shared utility - Remove dead i18n key
'compact mode: on (Ctrl+O off)'
Verdict
APPROVE — Blocker resolved, new feature is solid.
|
Hey @chiga0 — this is approved and auto-merge is enabled, but there's a merge conflict blocking it. Could you rebase on main and resolve the conflicts? It should merge automatically after that. Thanks! |
- i18n locales (de/en/ja/pt/ru/zh): keep both compact mode tip translation (HEAD) and new tips from main (QWEN.md, /btw, context warnings) - Tips.tsx: accept main's new tip registry system, replacing old hardcoded array - tipRegistry.ts: add compact-mode tip entry to the new registry
tanzhenxin
left a comment
There was a problem hiding this comment.
Review
Re-checked after new activity — only a merge conflict resolution commit, no substantive changes. Original approval still stands.
APPROVE
Concerns addressed in latest commits. Approving and merging.
Compact mode was removed from Footer by #3100; keep our multi-line statusLineLines API.

Summary
Comprehensive UX optimization for compact mode (Ctrl+O), built on top of #3047:
Ctrl+Oto?shortcuts overlay,/helpcommand, and startup Tips rotationMainContentforces live rendering duringWaitingForConfirmationstateFiles changed (15)
AppContainer.tsx,MainContent.tsx,CompactModeContext.tsxFooter.tsx,Help.tsx,KeyboardShortcuts.tsx,Tips.tsx,SettingsDialog.tsxen.js,zh.js,ru.js,pt.jssettings.md,compact-mode-design.md,compact-mode-design-zh.mdRelates to #3047, #2767, #2770
Test plan
?with empty input — verifyctrl+o to toggle compact modeappears in shortcuts list/help— verifyCtrl+Oshortcut is listedCtrl+Oduring streaming — verify live output continues (no frozen snapshot)!shell mode — verify shell remains expanded🤖 Generated with Claude Code