Commit Graph

176 Commits

Author SHA1 Message Date
can1357 1b0d629a71 test(coding-agent): cover Ask single-select space input 2026-07-17 04:04:58 +02:00
can1357 3a75368b92 fix(images): preserve replay and transcript invariants 2026-07-16 03:48:59 +02:00
can1357 93cc1fed1c merged PR #5417: fix(openai): render native response images
# Conflicts:
#	packages/coding-agent/src/modes/components/chat-transcript-builder.ts
#	packages/coding-agent/test/agent-session-skill-keywords.test.ts
2026-07-16 03:48:21 +02:00
can1357 34f8eb70f0 fix(tui): honor ends during plan review reflow 2026-07-16 03:44:10 +02:00
can1357 37d38e1485 merged PR #5444: fix(tui): preserve Plan Review scroll position
# Conflicts:
#	packages/coding-agent/src/modes/components/plan-review-overlay.ts
2026-07-16 03:44:10 +02:00
can1357 ebaed59dda fix(tui): preserve deferred alternate exit 2026-07-16 03:32:00 +02:00
can1357 bf3764fa4d feat(coding-agent): stabilize system-prompt cache across xd:// mount changes via delta notices
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.
2026-07-15 19:07:31 +02:00
can1357 e755fcf983 Merge PR #5469: fix(tui): handle Kitty vim navigation sequences (@roboomp) 2026-07-14 22:58:46 +02:00
roboomp 3fa5ffd0b1 fix(tui): handled Kitty vim navigation sequences
Routed vim-style h/j/k/l navigation through the protocol-aware key matcher across custom coding-agent selectors and overlays.

Fixes #5314
2026-07-14 18:08:23 +00:00
roboomp dc2235fa9c fix(tui): preserved plan review scroll position
Retained relative body progress across transient non-scrollable render frames and added regression coverage for terminal-height changes.

Fixes #5232
2026-07-14 17:16:12 +00:00
roboomp b6b947bdbe fix(openai): rendered native response images
- 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
2026-07-14 16:15:53 +00:00
Rens Tillmann 2a09b22d9c Merge upstream main into fix/issue-4820-replay-safe-retention 2026-07-12 21:15:53 +00:00
T.C. Ferguson 26792f7b55 fix(tui): skip sparse compacted segments in isBlockUncommitted
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.
2026-07-12 21:09:19 +00:00
can1357 6bd51d4ad3 refactor(coding-agent): decoupled tip weight test from tips.txt data
- 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.
2026-07-12 20:46:29 +02:00
Hayden Evan 4fa5b61b05 Add plan review copy hotkey 2026-07-12 12:43:10 +02:00
Rens Tillmann 8ff98674e5 fix(tui): bound replay-safe transcript retention 2026-07-11 21:09:06 +00:00
can1357 bcee73e587 feat(coding-agent-modes): streamlined ask dialog workflow and layout
- 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.
2026-07-11 14:47:20 +02:00
can1357 6f65a58d1b merge PR #4375: feat(ask): add rich interactive dialog
Closes #4375
2026-07-11 14:15:55 +02:00
can1357 4a20b51ca8 feat: implemented auto-sealing for transcript blocks and TUI row emission
- 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.
2026-07-09 20:37:09 +02:00
can1357 8d484435c2 merge PR #4535: fix(coding-agent): restore fallback model selection 2026-07-08 15:19:38 +02:00
can1357 3458b037ae chore: update tests 2026-07-05 16:53:07 +02:00
can1357 46e0cdd4b6 test(coding-agent): cover copy selector cache invalidation 2026-07-05 13:39:10 +02:00
can1357 be5bb7c937 test(coding-agent): assert scoped tool spinner renders 2026-07-05 13:25:27 +02:00
can1357 7f3832a263 Merge PR #4489: fix(snapcompact): select silver shape for CJK-heavy auto text (@roboomp) 2026-07-05 13:03:08 +02:00
roboomp 1ac9802508 fix(coding-agent): restored fallback model selection
- 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
2026-07-04 16:42:38 +00:00
can1357 e8d1ab005e test(coding-agent): verified transcript component streaming and state management
- 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.
2026-07-04 12:15:23 +02:00
can1357 42fc4e6b0a refactor(agent): unified transcript block finalization logic
- 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.
2026-07-04 11:22:05 +02:00
roboomp a8add580d9 fix(snapcompact): selected silver for cjk auto shape
- 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
2026-07-04 03:54:55 +00:00
metaphorics f66e527674 fix(ask): guest multi-select Next gating, body height bottom border
- 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.
2026-07-03 14:17:31 +09:00
metaphorics 1d14e262bd fix(ask): tagged guest results, bounded headers, cancel-keeps-open, gated Next
- 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).
2026-07-03 13:00:26 +09:00
metaphorics 48b2a742c8 fix(ask): distinct chat redirect result, row-specific note prefill
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.
2026-07-03 11:52:51 +09:00
metaphorics 69c02c802a fix(ask): reset countdown on input, bound prompt titles, fix scroll viewport
- 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
2026-07-03 10:16:41 +09:00
metaphorics 38a5c8a893 feat(ask): add rich interactive dialog
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
2026-07-03 09:20:29 +09:00
can1357 ebf41281e7 fix(tui): stop spinner ticks for frozen pending previews
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.
2026-07-02 10:30:06 +02:00
can1357 6429de3e83 merge PR #4172: fix(tui): animate live tool spinners (@roboomp) 2026-07-02 10:30:06 +02:00
can1357 e4c3cba143 Merge PR #3875 (selective): skip double-format of revealed thinking blocks (@oldschoola)
Ports only the thinking double-format fix: resolveThinkingDisplay reuses block.thinking when rawThinking is set (buildDisplayMessage already formatted it), plus a single-entry memo in formatThinkingForDisplay and a rawThinking regression test. The PR's incremental reveal slicing is superseded by the already-merged #3848 (memoized grapheme slicing).
2026-07-01 22:37:36 +02:00
roboomp fb2804247a fix(tui): gated live tool spinner ticks
Added renderer metadata for pending and partial result paths that visibly consume spinner frames.

Stopped headerless bash pending previews from scheduling repaint ticks while preserving eval and shell header animation.
2026-07-01 18:34:12 +00:00
roboomp 469ff4a0ad fix(tui): stopped async tool spinner ticks
Excluded running async result snapshots from live partial spinner intervals so finalized background tool rows do not repaint scrollback.

Added regression coverage for async bash snapshots staying static.
2026-07-01 18:26:34 +00:00
roboomp 9e7814a638 fix(tui): animated live tool spinners
Started live partial tool spinner intervals for non-static tool blocks and forwarded spinner frames through eval and shell-style renderers.

Added regression coverage for live eval and shell preview spinner frames.

Fixes #4170
2026-07-01 18:19:31 +00:00
Jeff Scott Ward 329fb91643 fix: address hidden thinking review 2026-06-29 11:57:59 -04:00
Jeff Scott Ward 3854b0ec16 fix: describe hidden thinking pulse 2026-06-29 11:57:59 -04:00
can1357 f366e7bea8 Merge PR #3402: Shared TUI mouse-routing helpers and overlay selector migration (@wolfiesch)
# Conflicts:
#	packages/coding-agent/src/modes/components/settings-selector.ts
2026-06-27 01:40:11 +02:00
can1357 b72b83884d Merge PR #3216: feat: add provider in-flight request limits (@H4vC)
# Conflicts:
#	packages/coding-agent/src/modes/components/settings-selector.ts
2026-06-27 01:39:32 +02:00
can1357 8e206dbd54 Merge PR #3056: feat(coding-agent): add native terminal progress setting (@lederniermagicien) 2026-06-27 01:39:30 +02:00
can1357 366313df33 test(coding-agent): improved stdout geometry stubs in tests
- Added no-op setters to process.stdout properties in test geometry stubs.
- Prevented potential errors when code under test attempts to reassign stdout dimensions.
2026-06-25 05:15:40 +02:00
Wolfgang Schoenberger 16df865a88 test(coding-agent): cover inline-picker wrapper mouse offset
Add regression tests for all five inline-picker wrappers asserting a click
on the top border row is inert and a click on the first list row below it
confirms the first item, pinning the top-border line offset.
2026-06-24 20:09:48 -07:00
can1357 92d03466b7 Merge branch 'farm/c8a3da70/fix-resume-delete-scroll' into resume picker
Resolve the session-selector.ts conflict by integrating the delete-dialog
content-slot fix (#3283) on top of the fullscreen mouse-picker refactor.

The branch swapped the delete-confirmation dialog INTO a single content
slot (replacing the SessionList) so the picker is always
`chrome + max(list, dialog) + chrome` and never overflows the viewport.
Adjustments baked into this merge:

- Wrap the SessionList in `#contentSlot` and keep the dialog swapping into
  that slot, but preserve the new fullscreen path: mouse hit-testing,
  the pinned footer (`#footerLines`/`#footerStart`), and fill-height
  trimming all still work because the render offset now tracks
  `#contentSlot` (the list lives one level down).
- Keep both CHANGELOG entries (picker mouse/fullscreen + #3283 fix) and
  the ported scroll-stability regression test.
2026-06-23 02:46:56 +02:00
can1357 cffb804d3a feat(coding-agent): added mouse support and fullscreen rendering to session picker
- Enabled fullscreen overlay rendering for the terminal session picker.
- Implemented full mouse support including wheel-based scrolling and click-to-select functionality.
- Anchored the session picker footer to the bottom of the viewport to correct UI flickering.
- Added comprehensive unit tests for mouse interaction and layout constancy during resizing.
2026-06-23 02:25:30 +02:00
roboomp e266782604 fix(session-selector): swap delete dialog into SessionList slot
Earlier rounds shrank the SessionList by the dialog's row count to keep
the picker inside the viewport, but the SessionList could only claw back
whole session rows and bottomed out at zero entries. On a narrow
terminal with a long session title the dialog still wrapped past what
the SessionList could free, the picker overflowed the viewport, and the
TUI committed the header into native scrollback.

The picker now hosts the SessionList inside a single contentSlot
Container. Opening the delete confirmation swaps the dialog INTO that
slot (replacing the SessionList); closing it swaps the SessionList back.
The dialog therefore competes only with the SessionList's rendered
budget, not with the SessionList AND the picker chrome, so the picker
frame stays bounded by terminalRows even when the dialog wraps to many
rows. SessionList's external-reserve plumbing is no longer needed and is
removed.

Addresses PR #3285 second-round review feedback.
2026-06-23 00:05:53 +00:00
roboomp 964dc480c9 fix(session-selector): derive delete-dialog reserve from rendered height
The first round of the issue #3283 fix reserved a fixed 12 SessionList
rows for the delete confirmation dialog. On a narrow terminal or against
a long session name, HookSelectorComponent's Markdown title and help
text wrap past 12 rows; the picker would still overflow even after the
SessionList shrank to zero entries, and the TUI committed the picker
header into native scrollback again.

SessionSelectorComponent now overrides render() to measure the dialog's
actual rendered height at the live width before super.render() walks
the children, and pushes that as the SessionList's external-row reserve.
The dialog's own Container memoization makes the extra pre-render
essentially free.

Addresses PR #3285 review feedback.
2026-06-22 23:56:25 +00:00