Commit Graph
50 Commits
Author SHA1 Message Date
Felipe Coury cc7ba33601 Add a searchable /config preferences panel to the TUI (#52990)
## What changed

- Group preferences into Appearance, Notifications, Input, Sessions, and Text selection tabs, with search and links to existing theme, status line, terminal title, and keyboard editors.
- Persist preference changes to the selected local configuration file, apply supported changes immediately, and show save errors, configuration overrides, and restart requirements in the panel.
- Add a delayed notification test and controls for notification timing while preserving custom event filters.
- Add `tui.copy_on_select_clear_selection`, disabled by default, to clear transcript selection highlights only after confirmed automatic clipboard delivery.
- Keep local configuration editors usable while disconnected and prevent held activation keys or buffered input from triggering actions across editor and reconnect transitions.

## Testing

Add regression tests and rendering snapshots for panel navigation, search, dependency states, editor handoffs, offline persistence, notification timers, custom filter preservation, and confirmed-copy deselection.

GitOrigin-RevId: a16d218046060fcb6e61705a803fcd9297266e6e
2026-10-10 22:28:01 +00:00
Felipe Coury c3d3b142d1 Make pinned transcript prompts clickable (#52778)
## What changed

Clicking a pinned prompt header with an unmodified left click now scrolls the transcript to the original prompt. The click also ends text selection, cancels search, and clears activity focus. Track the prompt by entry identity so navigation remains correct when history is prepended.

## Testing

Update the prompt-header snapshot test to navigate by clicking the header after prepending history and verify that the original prompt becomes visible.

GitOrigin-RevId: dea811693853e3740909ab675b1339f701e01e02
2026-10-10 04:33:30 +00:00
Felipe Coury 39f4277087 Enable text selection in the fullscreen TUI footer (#52270)
## What changed

Allow mouse selection and plain-text copying of rendered status and footer text, honoring `tui.copy_on_select` and existing selection keyboard controls. Keep the selected region stable while other content updates, preserve Unicode and terminal hyperlinks, and clear selections when their region becomes invalid.

Defer warning clicks until a stationary mouse release so dragging selects text without opening the warning viewer. Preserve the composer draft and cursor while selecting footer text.

## Testing

Add unit and snapshot coverage for visible-text copying, Unicode and hyperlinks, selection invalidation, keyboard ownership, and stationary clicks versus drags. Add a fullscreen integration test for warning selection and draft preservation.

GitOrigin-RevId: dd14d7ede52e97e507be24c4d6ac0299f7388a9b
2026-10-08 20:49:14 +00:00
Eddie Chen cfc946f4e1 Expose and persist turn lineage across the app server (#51415)
## Why

Clients starting delegated work need to attribute descendant turns to the original turn and retain that attribution through completion and history reads.

## What changed

- Accept optional `parentTurnId` and `rootTurnId` in `turn/start`, and expose `rootTurnId` on returned turns and lifecycle notifications.
- Default new turns to their own root when none is supplied. Preserve the active turn's root when steering, ignoring incoming lineage fields.
- Carry root IDs through completion, interruption, recovery, and fork boundaries, and persist them for paginated history reads. Leave unknown roots null in older history.
- Update protocol schemas and generated TypeScript and Python bindings.

## Testing

Extend coverage for default and explicit roots, steering without changing lineage, interrupted and recovered turns, history reads after restart in both history modes, nested fork pagination, and compatibility with older database writers.

GitOrigin-RevId: f1a570a12bd11742929fd2e8b017e5d35aa07dcb
2026-10-06 16:56:39 +00:00
Benjamin Carlsson 3a69ec3ef8 Preserve local Markdown link labels in the TUI (#50695)
## Why

Path-like link labels were collapsed into their destinations, discarding the author's label text and formatting.

## What changed

Preserve nonblank local link labels alongside the formatted destination as `label (target)`, including in tables. Empty or whitespace-only labels show only the destination. Keep destination formatting and fall back to the original destination when a local file URL cannot be parsed.

Render file citations without a label so they continue to display only the formatted destination.

## Testing

Update rendering and transcript-copy tests and snapshots to cover preserved path labels, styled labels, empty labels, malformed file URLs, tables, and Markdown escaping.

GitOrigin-RevId: 2810b70f1ecdc59d7f90fa1b254b1e9069c8fc29
2026-10-03 18:44:14 +00:00
Eric Traut b741e480e2 Allow transcript selection and copying while bottom modals are open (#50564)
## Why

The plan confirmation prompt allowed transcript scrolling but blocked selecting and copying the visible plan text.

## What changed

Allow mouse selection and copying in the visible transcript while a bottom modal is open, preserving drags across redraws. Keep other keyboard input with the modal and suppress transcript link activation, disclosure toggles, and follow-control clicks during modal mouse handling.

## Testing

Extend the plan prompt test to cover selection, `Ctrl+Insert` copying, selection highlighting, and popup bounds. Add coverage confirming that ordinary and Control-clicks do not open links in selection-only mouse handling.

GitOrigin-RevId: 9e1fdfcb4bc18215e62a714f173bc8cb372b090a
2026-10-03 07:45:47 +00:00
Felipe Coury 9ce35d337a Use Enter to accept transcript Find results and Escape to cancel (#50503)
## Why

Accepting a Find result must not let a held `Enter` submit the composer draft, including when terminals report repeated keys as fresh presses.

## What changed

- Make `Enter` accept the displayed result for reading, while `Ctrl+P` and `Ctrl+N` navigate older and newer matches.
- Make `Escape` cancel query editing and restore the pre-search presentation; after acceptance, it returns to the latest transcript content.
- Consume unmodified `Enter` while reading a result, but let modified `Enter` reach configured composer bindings.
- Update footer hints to show acceptance, cancellation, and the active Find state.

## Testing

Extend input-routing coverage for repeated `Enter` presses and modified composer bindings. Update search tests and footer snapshots for acceptance, cancellation, and result navigation.

GitOrigin-RevId: 2a2b7c389240ffa941e3623d7fb7d877455fa9a5
2026-10-03 02:52:56 +00:00
Felipe Coury f5a2272c6c Copy transcript selections as literal text while preserving rich HTML (#50467)
## Why

Copying rendered transcript selections added Markdown formatting and escapes to the plain-text clipboard payload. Selecting bold text such as `hello` could paste as `**hello**`.

## What changed

Separate the literal selection text from the Markdown source used to render clipboard HTML. Plain-text copies omit inline formatting delimiters, added code fences, and Markdown escapes while retaining list and table structure. Rich-text pastes continue to preserve formatting through HTML.

## Testing

Update clipboard and transcript selection tests to verify literal text alongside rich HTML, including lists, inline code, paths with Markdown punctuation, hard breaks, streamed code blocks, and tables across layout widths.

GitOrigin-RevId: 980ee2ed0b0e201b581a3a301fa04d796c65af2e
2026-10-03 00:02:11 +00:00
Benjamin Carlsson c536ffcb18 Add keyboard copy selection to the owned transcript (#50434)
## What changed

- Make `/copy` select the latest completed response directly in the owned transcript. Navigate user messages, code blocks, and blockquotes with arrow keys or `j`/`k`, use `g`/`G` to jump to the ends, and press Enter to copy or Escape to close.
- Highlight selected blocks and keep surrounding context visible during navigation and resizing. Preserve source payloads for code and quotes, including rendered Mermaid diagrams and fenced Markdown tables.
- Pause queued submissions until copy mode closes, and report clipboard results in the transcript footer.

## Testing

Add tests for copy routing, keyboard navigation, highlighting and resize behavior, source whitespace and line endings, clipboard completion, and queued-input resumption.

GitOrigin-RevId: bd4f58ec17568f95d0e91014e5ddba33ca8bd57c
2026-10-02 21:42:23 +00:00
Benjamin Carlsson d61c7a824f Honor pager bindings for transcript page keys (#50396)
## Why

Transcript scrolling hardcoded `PageUp` and `PageDown` to full-page movement, ignoring customized pager bindings.

## What changed

Resolve unmodified `PageUp` and `PageDown` through the pager's scroll bindings so they can scroll by a full page, half a page, or one row, or remain unbound. Preserve the one-row overlap for full-page scrolling and leave pager typing shortcuts unhandled by the transcript.

## Testing

Add a regression test and snapshot covering default, half-page, single-row, and unbound configurations. Verify that `PageDown` reverses `PageUp` scrolling and that `j` and `Ctrl+u` remain unhandled.

GitOrigin-RevId: 945e99d7370f84f326ab71037be2924dddada32c
2026-10-02 18:29:19 +00:00
Eric Traut d64360f628 Support Ctrl+Insert for copying TUI selections (#50215)
## Why

Windows Terminal forwards `Ctrl+Insert` when its Copy action has no native terminal selection. Recognize this shortcut so it can copy text selected within Codex.

## What changed

Add `Ctrl+Insert` to the shared copy-key detection used by transcript and composer selections. Use the same detection for transcript input ownership so the selection consumes the shortcut before other input handlers.

## Testing

Extend transcript tests to verify `Ctrl+Insert` input ownership and copying. Extend composer tests and snapshots to verify that failed or unconfirmed copies preserve the selection, while confirmed copies clear it without changing the draft or cursor.

GitOrigin-RevId: 5a33c72cff4c4395511779a7051fc92f8bd5e5d7
2026-10-02 07:21:07 +00:00
Eric Traut 4dd51f4a5f Make transcript mouse scroll speed configurable (#50209)
## What changed

Add `tui.mouse_scroll_speed` as a finite positive multiplier for transcript mouse wheel scrolling, including transcript overlays and session previews. Change the default from three rows to one row per wheel event; set the multiplier to `3.0` to retain the previous speed.

Fractional values accumulate movement across events and discard the remainder when direction reverses. For example, `0.5` scrolls one row every two events. Following the latest output pauses only when a whole row moves.

## Testing

Add tests for configuration validation, integer and fractional scroll speeds, direction changes, decimal accumulation, and following behavior. Extend local settings coverage to include a command-line override for the new setting.

GitOrigin-RevId: d355e246fd943415f0ce5a6affe849f77f3615e6
2026-10-02 06:50:10 +00:00
Felipe Coury 1cc9917508 Keep transcript Find expansion scoped to the current match (#50045)
## Why

Starting Find expanded the entire transcript into detailed mode. Searching hidden content should preserve the compact view and manually expanded activities.

## What changed

- Search full transcript content, including hidden live output, and temporarily expand only the current matching entry.
- Preserve manual disclosure state and retained text revisions while reading or selecting a match. Allow activity controls while reading results.
- Use `Enter` or `Ctrl+P` for older matches and `Ctrl+N` for newer matches, with matching footer hints.

## Testing

Add regression tests and snapshots for selective expansion, manual disclosures, hidden live matches, retained selections across updates and resizing, and Find in compact transcript overlays.

GitOrigin-RevId: 618ee47ba6c3f3a5138c9e3fe0961e7faa3383da
2026-10-01 17:27:03 +00:00
Felipe Coury a97fb78085 Keep transcript Find results readable after closing the query (#50039)
## Why

Closing Find previously restored the pre-search view, making it difficult to read a match and its surrounding transcript context.

## What changed

- Make `Esc` with a nonempty query close query editing while preserving the query, highlighted match, and expanded output. A second `Esc` returns to the latest output; `Ctrl+C` cancels Find and restores the pre-search presentation.
- Allow paging through surrounding context and loading older history without losing the query. Keep `Ctrl+N` and `Ctrl+P` available for match navigation, and reopen Find to edit the retained query.
- Show context above matches when space permits, preserve match layouts across resizing, and display navigation and history status while reading results.

## Testing

Add regression tests and snapshots for retained results, surrounding context, resizing, paging around live output, older-history loading, and footer status. Update interaction tests for the additional `Esc` transition.

GitOrigin-RevId: d822956d3c6ffab88fc1665ebdf0c86ccf110899
2026-10-01 17:22:19 +00:00
Benjamin Carlsson d2f2c40095 Use platform-specific modifier labels in TUI shortcut hints (#49804)
## What changed

Render Control, Shift, and Alt as `⌃`, `⇧`, and `⌥` on macOS, and Control as `^` on Linux. Keep textual modifier labels on other platforms.

Route hard-coded shortcut hints through the shared key-label formatter so footers, overlays, pickers, and transcript notices use consistent notation.

## Testing

Update modifier-combination and chord label assertions, along with rendering snapshots and narrow-layout expectations for the shorter hints.

GitOrigin-RevId: 0d20fa218e4a11dfe7a81c8de64f8d25e093af03
2026-10-01 01:35:40 +00:00
Felipe Coury 0b43721d8d Copy selected file paths as plain text in the TUI (#49564)
## Why

Copying a rendered local file target such as `repo/foo_bar!` should preserve the selected path without adding Markdown escapes.

## What changed

Treat selections contained within rendered file targets as plain text, including partial selections and targets in tables. Coalesce adjacent file targets and inline code into literal ranges while preserving Markdown escaping when the selection includes surrounding content.

## Testing

Add regression coverage for partial paths, adjacent literal spans, styled links, table cells, special characters, and mixed selections at narrow and wide rendering widths.

GitOrigin-RevId: 94bcdacf14b013f9198cb84adfdb237eb644dd48
2026-09-30 10:21:00 +00:00
Benjamin Carlsson c6c7c8d270 Omit blockquote markers when copying quoted selections in the TUI (#49153)
## Why

Copying text selected within a blockquote adds Markdown quote markers that are not part of the selected content.

## What changed

Return plain text for selections containing only quoted content, preserving literal `>` characters and selected whitespace. For quoted tables and task lists, remove quote prefixes while retaining table reconstruction and checkbox states. Selections spanning quoted and unquoted content continue to preserve Markdown structure.

Preserve the existing logical source when marking list separator lines as omitted from Markdown copying.

## Testing

Add coverage for partial and nested blockquote selections, quoted tables and task lists at narrow and wide widths and after rewrapping, and copying a mouse-selected blockquote.

GitOrigin-RevId: 5ac0c8c47a77937e5a35c376d8908065217ad2dc
2026-09-29 03:49:47 +00:00
Benjamin Carlsson d7f7fa4106 Remove the plus separator after Option symbols in TUI key hints (#49136)
## What changed

Render macOS Option shortcuts as `⌥t` and `ctrl+⌥t` instead of `⌥+t` and `ctrl+⌥+t`. Keep `+` separators after text modifier labels such as `ctrl`, `shift`, and `alt`.

## Testing

Update key-label and chord assertions and UI snapshots to expect the compact labels across shortcut help, navigation hints, and tooltips.

GitOrigin-RevId: 7d52088ebce3dfa3f8bdad65eb159ca0fead8a31
2026-09-29 02:37:23 +00:00
Felipe Coury 0196495288 Add X11 primary selection and middle-click paste support (#49112)
## What changed

- Publish released mouse selections from both transcript views to X11 `PRIMARY` as plain text, even when copy-on-select is disabled. Preserve configured `CLIPBOARD` copying when it is enabled.
- Paste `PRIMARY` into the editable fullscreen composer on middle-click, including while a transcript selection remains active.
- Limit support to local Linux X11 sessions, excluding Wayland, SSH, tmux, WSL, and VS Code terminals.
- Retain the latest deferred selection publication and order it before a pending `PRIMARY` read, while giving explicit copies priority. Cancel stale deferred work when its selection or paste target is invalidated.
- Clarify that scrollback mode uses native terminal copy, paste, and scrollback.

## Testing

Add regression tests for selection publication with copy-on-select enabled and disabled, publication-before-read ordering, explicit-copy priority, cancellation of deferred work, and middle-click paste invalidation.

GitOrigin-RevId: 6ba7bddffda60183b7f9ad5cd69a97da8a4a8dcd
2026-09-29 00:40:54 +00:00
Felipe Coury 3074be908a Copy selections within inline code as plain text (#49041)
## Why

Copying text selected entirely within inline code added Markdown backticks that were not part of the selected content.

## What changed

Return only the selected content as plain text when the selection is contained within one inline code span, including in a single table cell. Preserve Markdown formatting for selections that also include surrounding content, and continue filtering control characters from table copies.

## Testing

Add regression coverage for full and partial inline code selections, embedded backticks, Unicode, whitespace, wrapping and resizing, and table selections with mixed content or control characters.

GitOrigin-RevId: c63e13cb781f9fca28ae53500cb4f9ae08b72c96
2026-09-28 17:51:00 +00:00
Benjamin Carlsson 6af89155d0 Show a hand pointer over transcript links in Ghostty and Kitty (#48827)
## What changed

- Show a hand pointer over actionable transcript links while Codex captures mouse input in Ghostty and Kitty, excluding sessions inside terminal multiplexers.
- Share link hit testing between hover and click activation, and refresh hover after rendering so scrolling and live output cannot leave a stale hand pointer.
- Suppress link hover during mouse presses and drags, overlays, and popups, and clear remembered mouse coordinates on focus loss, resize, and resume.
- Restore the terminal's pointer policy when releasing mouse capture, releasing Kitty's override and using a text pointer in Ghostty. Deduplicate pointer updates and preserve cleanup after write failures.

## Testing

Add tests for wrapped links containing wide characters, hover/click target agreement, scrolling, pointer transitions and restoration, write-failure retries, and hover invalidation.

GitOrigin-RevId: 1cf52e039a229e12260fa334879784c9bc1c8c87
2026-09-28 00:53:05 +00:00
Eric Traut 596f8c5c3c Match pinned transcript headers to the original prompt style (#48775)
## What changed

Add the `› ` prefix to pinned prompt headers, using bold red for spoken prompts and bold dim styling for other prompts. Reserve one column when truncating the header.

## Testing

Add a rendering test comparing pinned headers with the original prompt rows for both regular and spoken prompts. Update snapshots for the prefix and display-width truncation.

GitOrigin-RevId: 89c2d9267374ef8f6504058c12c078025f302fef
2026-09-27 19:47:40 +00:00
Felipe Coury e75b6b1e0c Show hidden output line counts in compact terminal activity (#48761)
## What changed

Replace generic output disclosure labels with counts such as `+ 5 lines (ctrl+t to expand)` for compact command activity, both live and in history. Count retained output lines hidden or clipped by the preview, excluding output discarded by storage limits.

Use the configured `open_transcript` shortcut and omit the hint when it does not fit or the action is unbound. Invalidate cached layouts when keybindings change. Keep generic `Show details` labels for other hidden details and keep disclosure controls outside copyable and searchable text.

## Testing

Add regression tests for live/history consistency, remapped and disabled shortcuts, and exclusion of hints from source text. Add snapshot coverage for fully visible output, hidden and clipped lines, command-only details, and storage-truncated output.

GitOrigin-RevId: c468be9b88b69dc3ca1abdb6b7be023244d32a57
2026-09-27 18:09:34 +00:00
Felipe Coury e8fdbf1f7c Use a consistent borderless session header in the TUI (#48562)
## What changed

- Use the compact title, version, and directory layout for all session headers, including resume, fork, and clear-screen flows. Remove the boxed model row and retain the optional greeting and YOLO permissions indicator.
- Share title styling with the status card and honor the active render mode and wrapping policy when inserting a fresh header after clearing the screen.

## Testing

Update header and startup snapshots for the borderless layout, narrow widths, and halfwidth directory characters. Add assertions that clearing history preserves the raw header in raw output mode.

GitOrigin-RevId: 0b91c1ce6646f9d9d1954b1442936abe93bdcd3c
2026-09-26 22:50:16 +00:00
Felipe Coury 75a714843b Preserve Markdown tables and whitespace when copying TUI responses (#48549)
## Why

Copied table selections became code blocks containing the rendered grid, losing table structure. Stripping trailing whitespace from completed responses also removed Markdown hard breaks and spaces in code.

## What changed

- Reconstruct Markdown tables from selected cells across grid and record layouts, preserving alignment, inline formatting, and list or blockquote nesting.
- Copy a single selected cell as inline content and leave unselected cells empty without adding their text. Escape literal pipes in table code spans and link destinations.
- Preserve trailing whitespace on lines unchanged by assistant directive removal.
- Keep blank rows in copied text without painting newline selection highlights on empty rows.

## Testing

Add regression coverage for wrapped and rewrapped tables, partial selections, empty cells, literal pipes, and separate table and code blocks. Update snapshots for nested tables and selection highlights, and verify completed-response copying preserves hard breaks and code whitespace.

GitOrigin-RevId: 661e4c8331f2737bedff286548f9343bac44e0cb
2026-09-26 21:58:39 +00:00
Felipe Coury 16c21e3f36 Preserve table cell source metadata through TUI rendering (#48548)
## What changed

- Retain table identity, column alignments, cell coordinates, source byte ranges, and inline formatting in copy metadata.
- Carry cell fragments through grid padding, wrapping, key/value layouts, and pipe output, including escaped pipes and empty cells.
- Preserve logical source metadata when remapping wrapped lines, even without hyperlinks.

## Testing

Add coverage for cell fragments across narrow and wide layouts, blank table continuations, and Markdown selection copy structure and visible transformations.

GitOrigin-RevId: 8422f224cffe2e74813394f0623b9167bdd4ac59
2026-09-26 21:58:17 +00:00
Felipe Coury 7f6c0f9387 Refresh the TUI welcome screen for new sessions (#48513)
## What changed

- Show a compact session header with a randomly selected greeting, preserving the greeting and blossom state from startup into the live session.
- Center a settled blossom in unused fullscreen space and replay its animation on click. Hide it while typing or when space is insufficient, and respect `tui.animations` and `tui.effects.welcome`.
- Hide startup tips in the fullscreen transcript while retaining them in terminal scrollback, and prevent hidden entries from shifting the first visible header.
- Keep the composer visible and responsive during daemon startup, routing startup diagnostics through tracing while direct lifecycle commands retain stderr output.

## Testing

Add regression tests and update snapshots for blossom placement and click replay, welcome opt-outs, greeting stability, startup transitions, tip visibility, and transcript spacing.

GitOrigin-RevId: ec7b082fbe25ced1180cad3348f5c76e48c0e92b
2026-09-26 18:59:50 +00:00
Felipe Coury ca41ed337f Show turn tips while working and after completion in the TUI (#48352)
## What changed

- Show a random tip beneath the working status after 30 seconds, using the existing tooltip catalog and current key bindings.
- Show completion tips only after successful turns with a final answer, starting with the third turn and spacing displayed tips by at least three turn starts. Limit completion tips to two per app session, and skip them when a working tip was already shown for that turn.
- Respect `tui.show_tooltips`, hide tips during composer or transcript interactions, and omit tips when space is insufficient. Count exposure only when a tip is rendered.
- Anchor completion tips after queued history updates, keep them outside transcript selection and search, and dismiss them on history replay or transcript clearing.

## Testing

Add lifecycle tests for timing, completion cadence, duplicate notifications, failed and interrupted turns, and hidden tips. Add rendering snapshots and assertions for completion ordering, resizing, limited terminal space, and exclusion from transcript selection and search.

GitOrigin-RevId: 9e956f5b0377e3be71f9574639c3c6ef11ad1168
2026-09-26 04:17:41 +00:00
Felipe Coury a33fb9751c Preserve Markdown formatting when copying transcript selections (#47896)
## Why

Transcript selections were copied as plain text, losing the formatting of rendered Markdown when pasted.

## What changed

- Retain semantic Markdown annotations through rendering, wrapping, and streaming, then serialize selected text with balanced markup.
- Preserve inline formatting, web links, headings, lists, blockquotes, and hard breaks in Markdown clipboard payloads.
- Keep code-only and other literal-only selections as plain text. In mixed selections, escape user prose and fence code, tables, and tool output to preserve their literal content.

## Testing

Add unit tests and Markdown/HTML snapshots covering partial selections, nested containers, escaping, links, resize stability, and streaming boundaries.

GitOrigin-RevId: f0476334a6bf8ad0fb57626627bd258443540852
2026-09-24 17:55:29 +00:00
Felipe Coury 12fd929f72 Keep the TUI responsive during clipboard copies (#47847)
## Why

Native clipboard setup and writes can block, preventing the TUI from processing input or closing overlays while a copy is in progress.

## What changed

- Route clipboard copies through one session worker that retains native clipboard ownership. Keep terminal escape output on the UI thread.
- Show pending and busy status messages, reject additional copies without queuing them, and ask users to retry image paste after an active copy finishes.
- Abandon setup after five seconds and prevent late delivery. Keep the worker busy until the blocked call returns, and bound shutdown waiting for clipboard handoff.
- Match completions to their originating requests so stale results cannot clear newer selections or unexpectedly resume transcript following. Retain selections on automatic copies, failures, and unconfirmed delivery.

## Testing

Add regression tests for blocked backends, overlay exit, copy and paste ordering, setup expiry, bounded shutdown, completion status messages, and preservation of replaced or moved selections.

GitOrigin-RevId: 4ba1f8da258b9d0700b0edec9ac0ba699f536785
2026-09-24 14:15:42 +00:00
Felipe Coury ab021e9f13 Add configurable copy-on-select for transcript selections (#47639)
## What changed

- Add `tui.copy_on_select` with `auto` (default), `always`, and `never` modes, and apply it to the fullscreen transcript, transcript overlay, and resume/fork previews.
- Enable `auto` in tmux and Zellij, and in direct macOS terminals except Ghostty and Kitty. On other platforms, enable it in direct terminals identified as iTerm2 or Terminal.app.
- Copy nonempty mouse selections on release, including word and line selections, while retaining their highlight. Preserve link activation and ignore empty selections.
- Clear composer selections after confirmed keyboard copies, matching right-click copies, while preserving the draft and cursor. Keep selections when copying fails or delivery is unconfirmed.

## Testing

Add coverage for terminal defaults and configuration overrides, copying on release, retained highlights, repeated clicks, link activation, and empty drags. Extend composer coverage to verify selection clearing for `Cmd-C`, `Ctrl-C`, and right-click across clipboard outcomes.

GitOrigin-RevId: 24e6f9e267ef3ab249c5356db736e094127f68b8
2026-09-23 19:37:42 +00:00
Eric Traut 39598ed178 Support Shift-click to extend transcript selections (#47414)
## What changed

Extend an existing transcript selection with Shift-click while preserving its original anchor and selection unit. Allow continued dragging and repeated extension in either direction, including whole-word selections made by double-clicking. An ordinary click still starts a fresh selection.

## Testing

Add tests for extension in both directions, preservation of selection units, continued dragging, and ordinary-click reset, plus a snapshot of word-selection highlighting.

GitOrigin-RevId: e6208c1bc6260ac26e7cd1f81c752b2c0b375f36
2026-09-23 00:56:42 +00:00
Felipe Coury 506a328dab Restore composer hints after clearing selection at the transcript bottom (#47384)
## Why

Selecting text can pause following while the final transcript row remains visible. Clearing that selection could leave an unnecessary `esc latest` hint in place of the composer hints.

## What changed

Only show the return-to-latest footer for paused navigation when the transcript tail is out of view. At the bottom, show selection shortcuts without the earlier-history status, then restore composer hints when the selection is cleared, even if following remains paused. Preserve loading and retry hints.

## Testing

Add regression coverage for selection, clicking away, and scrolling at the bottom with partial and complete history, plus selection above the bottom. Verify retry hints with selected text and update activity expectations and the composer-gap snapshot.

GitOrigin-RevId: aeb2109244d6c3214c945abb51cf469087d03074
2026-09-22 23:09:18 +00:00
Felipe Coury 1b1b58f5a5 Move the activity inspection hint into keyboard shortcut help (#47338)
## What changed

- Add “Inspect activity” to the shortcut help’s Session section, using the runtime `focus_activity` binding (`F4` by default) and hiding it when unbound.
- Remove the passive activity footer hint so composer hints remain available. Keep previous, next, details, and back controls while activity is focused, shortening them to fit the available width.

## Testing

Add snapshot coverage for default, remapped, and disabled activity shortcuts. Update footer coverage to verify the absence of passive hints and interactive controls at 20, 32, and 80 columns.

GitOrigin-RevId: 52ca6f4992778cd3cf3eebe163d533e69a8dabeb
2026-09-22 18:51:23 +00:00
Felipe Coury 0a73d55b80 Avoid redundant spacing above the transcript composer (#47331)
## Why

An empty composer hint row already separates activity from the input. Adding another separator wastes transcript space, especially in short terminals.

## What changed

Reserve the extra separator only when copy status text, a follow control, or a fitting hint occupies the shared row and the viewport has room. Recalculate the transcript layout in the same frame when adding that separator, and use a shared timestamp for copy status visibility and expiry.

## Testing

Extend snapshots for running turns with no hint, follow controls in short terminals, and copy status text at narrow widths and limited heights. Update resize assertions to check that the draft and caret remain stable relative to the terminal bottom.

GitOrigin-RevId: a73894063b759ec6b9a25f720e0e8007516109c8
2026-09-22 18:06:15 +00:00
Ian MacLeod 720a21ae66 Prevent horizontal transcript selection from triggering autoscroll (#47137)
## Why

Dragging horizontally along the top or bottom transcript row could trigger autoscroll, moving the text under the pointer while selecting it.

## What changed

Require vertical pointer movement from the initial press row before selection autoscroll can begin. Remember that movement so a vertical drag can return to its starting edge and still autoscroll, and preserve the original pointer row across wheel scrolling.

## Testing

Extend regression tests and snapshots for horizontal selection at both edges, stable selected text across repeated ticks, wheel scrolling before the first drag, and autoscroll after a vertical drag returns to its starting edge.

GitOrigin-RevId: e13f3a80adbead1eecbeb281301667c8e12e1541
2026-09-22 00:38:29 +00:00
Eric Traut f07aaf920b Highlight selected newlines in the transcript view (#47068)
## Why

Transcript selections could include a newline without showing it in the highlight, making `code` and `code\n` look identical.

## What changed

Highlight one trailing cell for selected hard line breaks when space permits, including newline separators between transcript entries. Track logical line endings so soft wraps and synthetic rows do not receive newline highlights.

## Testing

Add selection snapshots for hard breaks within and between entries, plus layout coverage for empty lines, wrapping, trailing whitespace, and synthetic rows. Update the app selection test to assert the leading newline highlight.

GitOrigin-RevId: d6f332c472598a3f79557b7ebb41730c6acc7820
2026-09-21 16:42:35 +00:00
Eric Traut 57567b8d9e Use shared, keymap-aware tips in the fullscreen composer (#46931)
## Why

Fullscreen composer hints used a small, fixed rotation, while catalog shortcut tips hard-coded default bindings. Tips should reflect the user's configured shortcuts and expose the shared catalog with working links.

## What changed

- Select complete, single-row catalog tips that fit the composer gap, keeping selection stable across redraws and varying it across sessions and turns.
- Prefer eligible startup announcements until a user turn begins, without restoring them after history is cleared. Cache parsed announcements while reevaluating eligibility.
- Resolve `{key:context.action}` placeholders using current primary shortcuts and chords; skip tips with invalid or unbound actions.
- Expand the tip catalog and share Markdown rendering between composer and session tips, preserving hyperlinks and supporting Ctrl/Super-click in the composer gap.
- Keep usage notices and interaction controls ahead of tips, and respect `show_tooltips` and idle, empty input.

## Testing

Add tests and snapshots for remapped shortcuts, unbound actions, stable tip selection, announcement dismissal, narrow layouts, styled links, and removal of stale link targets.

GitOrigin-RevId: 64751293d9f91e4444b112361540a73234f1d51d
2026-09-21 03:02:45 +00:00
Felipe Coury eaff9a5f14 Hide Back to bottom when the current transcript tail is visible (#46902)
## Why

Pausing transcript following can leave the current final row visible, making the “Back to bottom” control unnecessary after copying text, closing find, or enlarging the viewport.

## What changed

Base control visibility on whether the current transcript tail is visible, and hide it for an empty viewport. Keep the control available when a paused view shows an older live revision with new activity.

## Testing

Add regression coverage for empty viewports, copying at the bottom, closing find at the bottom, and resizing a paused view. Extend live-revision assertions and update the composer-gap snapshot to keep the gap blank in the paused detailed view at the tail.

GitOrigin-RevId: d33b4279f5f5f43ae76c34466c18e89b61ad766c
2026-09-20 23:15:50 +00:00
Felipe Coury 4ca8e7afff Make transcript list spacing uniform after streaming (#46899)
## Why

Adding blank lines only after multiline items gives lists uneven spacing. Completed lists in redrawable transcript views can use consistent spacing based on their rendered width.

## What changed

- Keep assistant and plan lists compact while streaming in the fullscreen transcript, without holding back completed list rows.
- On completion or interruption, separate all sibling items if any item spans multiple rows; keep single-line lists compact and recompute spacing on resize.
- Preserve the reader's displayed content when consolidating streamed cells, and include spacing policy in the Markdown render cache key.
- Retain existing list spacing for native terminal scrollback.

## Testing

Add regression and snapshot coverage for streaming completion and interruption, width-dependent reflow, reader position, nested and quoted lists, item paragraphs, and preservation of links and source metadata.

GitOrigin-RevId: b2230aaf76ae798ebb6bf15563f8b8dcb6f3d19d
2026-09-20 22:55:19 +00:00
Felipe Coury 2db0ab7af1 Add right-click copying for transcript and composer selections (#46895)
## What changed

Allow right-clicking inside the transcript or composer to copy its selected text using the existing clipboard status messages. Clear the selection only when the right-click copy is confirmed; retain it after failed or unconfirmed copies. Keyboard copies continue to retain composer selections.

Preserve the draft, cursor, and transcript reading position. Refresh composer layout before checking mouse coordinates, and respect modal and transcript input ownership.

## Testing

Add regression tests and snapshots covering copy outcomes, selection retention, reading position, editor bounds after layout changes, and input ownership.

GitOrigin-RevId: 322b303394378a20b2a25b3d218777c9ea65c92b
2026-09-20 22:11:51 +00:00
Eric Traut 9fdff739ea Enable plain clicks on transcript links and style bare URLs (#46884)
## Why

Transcript links required a modified click to open, and bare URLs lacked the visual styling of explicit Markdown links.

## What changed

- Open links on release after an unmodified, stationary left click. Cancel activation after dragging, scrolling, or releasing elsewhere so text selection remains usable.
- Apply Markdown link styling to bare URLs while preserving surrounding prose, existing emphasis, Unicode, and table wrapping.

## Testing

Add gesture tests for bare and Markdown links at narrow and wide widths, drag and scroll cancellation, and existing modified-click behavior. Add styling tests and snapshots covering punctuation, emphasis, tabs, Unicode, and wrapped table URLs.

GitOrigin-RevId: 23d12c901932d7e3586d841e5a0ece00e422fccd
2026-09-20 20:47:14 +00:00
Eric Traut e39839509a Add mouse selection and editing to the fullscreen composer (#46858)
## What changed

- Support click-to-position, drag selection, double-click word selection, and triple-click logical line selection in the composer, respecting wrapping, scrolling, and atomic grapheme and placeholder boundaries.
- Copy selected draft text through the existing clipboard status flow without changing the draft or selection, before interrupt and exit shortcuts consume the key.
- Replace or delete selected text with editor input, flush buffered typing before mouse edits, and reconcile removed paste and image placeholders.
- Coordinate composer gestures with transcript selections, completion popups, and modals. Use generic retry messages for copy failures.

## Testing

Add coverage for Unicode and wrapped-text hit testing, selection highlighting and editing, multiclick dragging, placeholder cleanup, history navigation, and fullscreen copy and input ownership.

GitOrigin-RevId: 939ef461ec67855b3e87c3c7ddd8a60a3250c7cd
2026-09-20 17:58:42 +00:00
Eric Traut f3f07753ca Extract shared text selection helpers for the TUI (#46857)
## What changed

Move selection units, word and logical-line boundaries, click counting, and copy-key detection into `text_selection`, and update the transcript view to use them. Clamp selection offsets to valid UTF-8 boundaries and exclude key-release events from copy-key detection. Make `TranscriptView::cancel_search` accessible throughout the crate.

## Testing

Update existing text-layout tests to exercise the shared selection ranges for wrapped lines, combining characters, and empty logical lines.

GitOrigin-RevId: 6a8b44b4aa97fe2965a5e330121dc22fddc335b5
2026-09-20 17:58:19 +00:00
Eric Traut 551844b3ef Add compact transcript browsing and prompt navigation to the TUI (#46739)
## What changed

- Make double `Esc` enter compact prompt browsing in the owned transcript view and inline overlay. Use left/right arrows to select prompts, up/down arrows to scroll, `Ctrl+T` to toggle details, and `Enter` to rewind and edit. `Esc` cancels browsing and restores the original reading position and presentation.
- Add a responsive browsing footer, a pinned prompt header for answer context, and contextual composer tips that respect `show_tooltips` and configured shortcuts.
- Load older history as prompt navigation needs it, preserve the selected prompt across pagination, and resolve rewind requests by cell identity. Reject remote prompt restoration when it contains local image paths or command syntax.
- Bound initial owned-transcript history loading to a budget of three screenfuls plus an item scan limit, independently of terminal scrollback settings.

## Testing

Add regression tests and snapshots for browsing, rewind, cancellation after resize and pagination, custom key bindings, search and selection precedence, offline input, prompt headers, composer tips, and history hydration.

GitOrigin-RevId: 1d9ef7b627f47c3def43e7aee7148b5909f6d357
2026-09-20 00:34:38 +00:00
Eric Traut df7f717c85 Add transcript search and per-activity detail controls (#46734)
## What changed

- Add incremental, case-insensitive literal search across transcript details, loading older history as needed. Use `F3` to start Find, or `/` in the transcript pager, and navigate matches in either direction. Closing Find restores the previous presentation and reading position.
- Add clickable activity detail controls and `F4` keyboard focus for inspecting individual activity groups in the owned transcript. Preserve expansion state as live activity becomes history.
- Expose configurable `global.find_transcript`, `global.focus_activity`, and `pager.find` bindings under `tui.keymap`. Let new defaults yield to existing custom bindings and show available completions for pending chords.

## Testing

Add regression coverage for Unicode matching, bounded scanning, paginated and changing history, selection during search, composer input isolation, activity controls, and custom shortcut conflicts.

GitOrigin-RevId: 5bcbcdfbca7c5c296c635ec9b079ccd7a908e336
2026-09-20 00:06:25 +00:00
Eric Traut f1feda2299 Integrate the interactive transcript into the alternate-screen TUI (#46733)
## What changed

- Render transcript history and live output above the composer when `features.transcript_v2` is enabled and alternate-screen rendering is available. Handle scrolling, selection, copying, links, and older-history pagination in the main view.
- Add a clickable return-to-latest control with new-activity hints and temporary clipboard status. Let plain Enter return to latest when the composer is empty.
- Reflow retained transcript content during drawing and preserve the launch-selected screen mode across configuration reloads and session transitions, including `--no-alt-screen` restrictions.
- Enter the alternate screen with its first synchronized frame, and box CLI startup futures to reduce stack usage during session transitions.

## Testing

Add regression coverage for transcript layout, input routing, follow controls, clipboard status, and screen-mode persistence. Add a PTY test for the first alternate-screen frame and clean exit, and extend session-transition coverage through the CLI dispatcher.

GitOrigin-RevId: 1daf077826c7744b0f57399d10d159923dc87a97
2026-09-20 00:06:00 +00:00
Eric Traut d7d9f2b9b5 Add selection and copying to the transcript viewer (#46732)
## What changed

- Add mouse selection, word and line selection, drag autoscrolling, and keyboard selection with `Ctrl+Space`. Support copying selected text and opening links with a modified click.
- Anchor reading positions and selections to source text so resizing, streaming completion, and history pagination preserve the displayed content. Preserve hard line breaks, indentation, tabs, and graphemes when copying, while excluding display gutters and soft wraps.
- Rejoin activity groups split across history pages while retaining the reader's displayed revision.
- Distinguish confirmed clipboard writes from unconfirmed terminal requests, and retain native clipboard ownership after the transcript overlay closes.
- Manage mouse capture and keyboard modes across overlay transitions, editor handoffs, and suspend/resume.

## Testing

Add regression tests for selection during live updates and pagination, source-text copying across resize, clipboard confirmation and lifetime, and terminal mode restoration.

GitOrigin-RevId: 6b2438f576567cbba755b2405915a25acf009b8d
2026-09-20 00:04:04 +00:00
Eric Traut a63ae005d4 Anchor transcript scrolling to entries and bound viewport rendering (#46721)
## Why

Transcript-wide row offsets depend on content that can change during pagination, streaming, and resizing. Computing an exact scroll percentage also requires laying out offscreen history.

## What changed

- Replace the transcript overlay's generic pager with `TranscriptView`, tracking entry identity and a display-row offset through history updates and stream consolidation. Clamp offsets within the entry on resize or replacement.
- Render through bounded layout caches and show `100%` only when following the latest output with no unloaded history.
- Keep the reading position while `Home` loads older pages, then jump to the beginning when loading completes.
- Refresh animations whenever live output is visible, including while scrolled up.
- Reveal selected prompts when backtracking and highlight their text without reversing gutters or padding.

## Testing

Add regression coverage for reading anchors across pagination and live-output completion, resize and consolidation, prompt visibility and highlighting, navigation before the first draw, and avoiding offscreen formatting for the percentage indicator.

GitOrigin-RevId: 105cb66f93c742ee537152419060a87f55896b44
2026-09-19 21:43:37 +00:00
Eric Traut 30ab0ee65b Cache transcript layouts across measurement and rendering (#46720)
## Why

The transcript overlay separately generated cell content for height measurement and rendering. Active cells backed by external state could also leave the live tail stale when their revision key did not change.

## What changed

- Share retained text layouts between measurement and painting, and render only visible rows while preserving wrapping, styles, and hyperlinks.
- Reuse stable layouts across frames, invalidating them when width, animation, syntax theme, or terminal colors change. Bound retention by entry count and text size, allowing a single oversized entry.
- Refresh externally mutable cells each frame and bypass live-tail reuse when any active source is not cacheable.

## Testing

Add coverage for layout reuse, eviction, invalidation, and live-tail refresh without a revision change. Expand the transcript snapshot to cover styled text, wide glyphs, wrapping, and hyperlinks.

GitOrigin-RevId: 7dfb737e762f7f056a38774d956f618090809a62
2026-09-19 21:43:15 +00:00