The fullscreen Plan Review overlay stayed mounted, focused, and fully
interactive after a choice was picked. showPlanReview's finish() resolves
the choice promise but deliberately defers the hide until #approvePlan
(guarded for #5688/#5319/#5689), so during slow async approval work — e.g.
context compaction — arrow keys still moved the cursor and repeat
Enter/Esc were silently swallowed by the settle guard, with the
fullscreen buffer masking all progress underneath. Users on Ghostty and
macOS Terminal read this as "/plan is frozen".
The overlay now flips to a committed state the moment a choice fires:
handleInput is a no-op, and the render shows a "<choice> — submitting…"
indicator plus an "applying your selection" footer. The deferred-hide
timing is untouched, so the existing stale-buffer and focus guards stay
intact.
Fixes#5926
- Removed `#compactedChildStart` state, `compactable` segment field, and `#compactCommittedPrefix()` method, stopping the local-frame pruning of committed finalized rows.
- Post-finalize mutations now surface on every render via version tracking, instead of requiring a destructive replay to rehydrate the compacted block.
- Changed `print-mode.ts` to use `session.getLastAssistantMessage()` instead of array tail read, fixing access to terminal assistant messages after compaction removal.
- Kept tall-preview pages inside the selected option row.\n- Compared cached overflow output against the initial width-adjusted render.\n\nNote: pre-existing repository formatting failures in bun check are not addressed by this PR.
Ask dialogs accepted the configured cancel binding but always advertised Escape. Derive the compact footer label from the active binding so the displayed key remains actionable.
Rich ask options previously exposed preview content only for the highlighted row. Render every preview beneath its option and keep long content reachable without reviving the split-pane layout.
TranscriptContainer gated committed-prefix compaction on version === undefined, so version-tracked AssistantMessageComponent history never compacted and every stream tick re-walked all N sealed blocks (depth-linear compose).
Compact fully-committed finalized blocks regardless of post-finalize version tracking: their rows are immutable native scrollback the terminal owns. A post-commit mutation no longer recommits on ordinary frames (no duplication) and rehydrates on the next destructive full replay (no loss). Adds the permanent bench/transcript-compose.bench.ts fixture; ratio(N5000/N500) drops 2.30 -> 0.90.
Fixes#5930
Added an opt-in viewport-pinned live-region policy and propagated it through transcript composition for in-flight vibe_wait TV walls.
Pinned mutable wall frames now repaint virtually until finalization, while append-only live regions retain their existing frozen-snapshot behavior.
Fixes#5777
Instead of including the xd:// device inventory in the system-prompt signature, mount/unmount events now inject a steered `xdev-mount-notice` message so the system prompt (and its provider cache prefix) stays byte-stable across MCP connects and disconnects. Full device docs are picked up opportunistically on the next unrelated rebuild.
Also caps external (dynamic-mount) device descriptions to 200 chars in `docsAll` to prevent server-controlled prose from consuming prompt budget; built-ins keep their full curated docs, and `read xd://` always returns the untruncated text.
Legacy `discoveryMode: "off"` → `tools.xdev: false` migration is removed; the setting keeps its own default without inference from the deprecated key.
- Normalized completed image_generation_call results into assistant image blocks.
- Persisted image bytes through the session blob store and rendered them in live, replay, ACP, proxy, telemetry, and HTML paths.
- Added response normalization, persistence, and TUI rendering regressions.
Fixes#4768
After #5239 compaction, a later render only fills segments from
#compactedChildStart, leaving undefined holes in the prefix. Iterating
those entries crashed when retiring IRC/ephemeral cards
(`segment2.component`). Guard undefined segment slots and cover the
sparse-hole path with a red/green regression.
- pickWeightedTip now takes the tip list and a uniform sample, exported for tests.
- Weighted-selection test sweeps a synthetic tip list, so shipping zero [NEW] tips no longer fails the suite.
- Refined dialog layout with stable height clamping and improved preview visibility logic.
- Simplified interaction flow by replacing the "Next" row with "Submit" tab confirmation.
- Enabled accessible option toggling using Enter and Space keys.
- Removed legacy chat integration and streamlined internal dialog state management.
- Added auto-sealing logic to `FinalizableBlock` to finalize displaceable snapshots when they enter the scrollback area.
- Updated TUI frame emission to publish committed rows and clamp them to segment bounds, ensuring accurate component updates.
- Introduced component tracking and cleanup in event controller tests to prevent resource leaks during finalization.
- Validated state transitions and post-emit synchronization through comprehensive new test suites for transcript and TUI components.
- Exposed retry fallback chains in the model settings panel.
- Added a /model action that assigns the selected model as the default retry fallback.
- Cleared retry cooldown suppression when users manually switch models.
Fixes#4533
- Added comprehensive unit tests for `TranscriptContainer` to verify uncommitted block tracking.
- Created integration tests ensuring `AssistantMessageComponent` correctly streams thinking and answer content into scrollback.
- Added tests verifying that expanded tool evaluation output records rows correctly without duplication after settling.
- Updated `AssistantMessageComponent` test suite to cover table streaming scenarios in the unsettled tail.
- Replaced commit-based stability checks with a unified `isTranscriptBlockFinalized` tracking mechanism.
- Removed deprecated provisional rendering configuration and flags across tool and renderer interfaces.
- Standardized native scrollback boundary logic to pin at the first unfinalized block using settled row verification.
- Updated and refactored test suites to validate block finalization and settled row boundaries instead of deprecated commit stability methods.
- Made resolveShapeForText choose silver16-bw for CJK-heavy auto transcripts while preserving explicit variants and unsafe glyph protection.
- Added silver16-bw to the snapcompact shape settings submenu and renamed unsupported-glyph warnings.
- Covered auto shape selection, explicit variant precedence, unsafe glyph scans, and settings option parity.
Fixes#4486
- Omit Next from the guest multi-select ui-request options until at least
one option is checked or a custom answer exists, mirroring the local
dialog's disabled-Next gating. The remote select has no disabled-row
concept, so Next is omitted rather than dimmed (PRRT_kwDOQxs0bc6OFbDW).
- Add the bottomBorder(1) term to the ask dialog's fixed-row budget so the
rendered dialog no longer overflows the viewport by one row
(PRRT_kwDOQxs0bc6OFbDY).
- Add focused tests: guest wire-level Next gating round trip, and dialog
height <= viewport assertion.
- Replace #requestGuestUiString's string|"unavailable"|undefined channel
with a tagged GuestUiResult ({answered}|{cancelled}|{unavailable}) so a
guest answer literally equal to "unavailable" no longer collides with
the transport-unavailable sentinel (PRRT_kwDOQxs0bc6OE3gN).
- Cap in-body question header rendering to MAX_HEADER_ROWS with ellipsis
truncation so long/multiline questions cannot push options off-screen
(PRRT_kwDOQxs0bc6OE3gS).
- Guest Other editor cancellation now continues the loop (multi) / re-shows
the select (single) instead of cancelling the whole ask
(PRRT_kwDOQxs0bc6OE3gU).
- Disable the Next row on a single-question multi-select until at least one
option or custom input is chosen, preventing empty-result submission
(PRRT_kwDOQxs0bc6OE3gY).
Op: correct
Restores: review:4375
- Widen ExtensionAskDialogResult to a union with { kind: "chat" } variant
so AskTool can distinguish chat handoff from cancel (undefined).
- AskDialogComponent.#finishChat passes { kind: "chat" } via onChat.
- Controller settles { kind: "chat" } locally and propagates a "chat"
sentinel through the guest/collab path instead of returning undefined.
- AskTool returns a chat-redirect AgentToolResult (chatRedirect details)
instead of aborting with ToolAbortError.
- #promptForNote prefills with the existing note only when editing the
same row (noteRowKey === rowItem.key), preventing cross-row note leaks.
- Add ask-dialog and ask tool tests for chat redirect and row-specific
note prefill.
- Reset the inactivity countdown in handleInput after the closed/prompt
guard, matching HookSelector/HookInput semantics so a user actively
navigating options/tabs is not auto-submitted by an absolute deadline.
- Add boundPromptTitle helper that flattens whitespace, wraps to the
terminal content width, and caps at 3 rows with ellipsis truncation;
apply it to custom-input and note prompt titles in the rich dialog
and the guest-UI editor path so long/multi-line questions stay usable.
- Drop totalRows from both ScrollView calls so the full allLines array
is sliced via scrollOffset + row; previously totalRows caused render
to read lines[row] instead of lines[scrollOffset + row], leaving the
viewport stuck at the top while the scrollbar thumb moved.
- Add tests for inactivity reset, bounded prompt titles, and scrolling.
Restores: review:4375
Op: correct
Adds the rich TUI ask dialog, additive schema fields, ask.enabled tool gating, note/preview/header support, chat redirect, and timeout behavior that defers while nested prompts are active instead of discarding user input.
Op: extend
The github renderer materializes plain Text per display rebuild, so its
animatedPendingPreview opt-in requested 30fps repaints with a frozen
glyph for the whole run_watch wait; drop the flag. Custom tools with
only one of renderCall/renderResult never route to the animated generic
fallback, so gate the unregistered-renderer spinner on both being
absent. Regression tests for both no-tick contracts.