Commit Graph
27 Commits
Author SHA1 Message Date
alexsong-oai f91edce53b Add Google Cloud Vertex AI setup to TUI onboarding (#57857)
## What changed

- Add a sign-in wizard behind `features.gcp_setup_wizard`, disabled by default, to collect a project ID, optional location, and optional credential file. Users can leave the credential file blank to use Application Default Credentials.
- Delegate credential validation and configuration persistence to the app-server, showing progress and allowing retries after errors.
- Share editable single-line fields with Bedrock setup and compact the sign-in menu when terminal height is limited.

## Testing

Add onboarding tests and snapshots covering feature gating, field editing, navigation, validation failures, successful configuration persistence, and compact menu rendering.

GitOrigin-RevId: 96eb31e847aa1c2d503176be68ff2e2efe4722fa
2026-10-28 23:06:34 +00:00
Benjamin Carlsson fab1a57545 Preserve rich composer content in Vim registers (#57564)
## What changed

- Retain mention targets, image paths, and collapsed paste contents when copying or deleting into the register. Pasting creates fresh element identities and image/paste labels.
- Preserve rich register contents across draft clears and composer replacement.
- Capture `Ctrl+Y` register contents for dot-repeat, restore exact mention bindings through undo/redo, and keep pasted rich objects atomic in Replace mode.

## Testing

Add composer tests and snapshots for repeated rich pastes, register handoff, undo/redo, Replace-mode Backspace, and selection replacement. Add a test ensuring register contents are omitted from debug output.

GitOrigin-RevId: d543d21fd542492af49cce01c2a673e6d3d01664
2026-10-27 21:13:45 +00:00
Ian MacLeod 7077b1edb9 Enable text selection and mouse scrolling in the warning viewer (#57271)
## What changed

- Allow selecting warning text while preserving wrapped URLs and hard line breaks when copying.
- Add mouse-wheel scrolling within the warning body and keep page navigation working after selection.
- Use the shared menu surface and show configured scroll hints only for directions with more content.
- Preserve painted backgrounds when rendering text selections.

## Testing

Add coverage for warning selection without changing the draft, paging after selection, wheel scrolling and directional hints, and selection boundaries in scrolled text containing tabs and wrapped words. Update warning panel snapshots.

GitOrigin-RevId: c4b77277a60b7b4af92043cb3761769ddc636454
2026-10-26 21:36:05 +00:00
Benjamin Carlsson 5009a99dfc Render slash command prefixes as composer prompt markers (#54742)
## What changed

- Display the leading `/` in the prompt marker instead of the editable text, sharing prefix state with shell mode's `!`.
- Preserve command prefixes and text element offsets across submission, queuing, history, and external editing. Keep prefixes literal in plain-text composers.
- Track composer-owned slash command elements separately, omit them from exported draft elements, and refresh them when command availability changes.
- Let backward deletion at the start of the text remove the prompt prefix while preserving selected-text deletion and Vim Replace recovery.

## Testing

Add regression coverage for slash prompt cursor placement, prefix deletion, history search highlighting, dynamic command availability, and Vim Replace restoration, including Unicode text. Update rendering snapshots for the slash prompt marker.

GitOrigin-RevId: 0da42da8e98bf7885f9b0ba2c8d5ad4f44d6847e
2026-10-17 00:03:04 +00:00
Felipe Coury 3517671c60 Extend copy-on-select to composer text (#53753)
## What changed

Apply `tui.copy_on_select` to composer mouse selections on release, including X11 PRIMARY publication when enabled. Keep editable selections highlighted so typing can replace the selected text, even when `tui.copy_on_select_clear_selection` is enabled.

Share clipboard destination handling across the transcript, footer, and composer. Apply automatic deselection to footer selections after confirmed delivery, and release composer and footer PRIMARY ownership on focus loss or resume. Update configuration descriptions to clarify the behavior across all three surfaces.

## Testing

Add composer tests covering copy on release, retained selection highlights, replacement by typing, PRIMARY ownership lifetime, and clipboard-only status reporting for pending copies.

GitOrigin-RevId: 46999a32170149193fca561741000e97dfc458cf
2026-10-13 19:45:14 +00:00
Eric Traut a9b0815167 Support Windows clipboard text paste shortcuts in the TUI (#53224)
## Why

`Ctrl+V` previously attempted only image paste, so a text-only clipboard produced an image-paste error. `Shift+Insert` did not use the clipboard paste path.

## What changed

- On Windows, let `Ctrl+V` and `Shift+Insert` paste images first, then read clipboard text asynchronously when no image is available. Keep clipboard access errors distinct from missing images.
- Allow keyboard paste into composer selections and active history or Vim search queries, including inline mode with right-click paste disabled.
- Flush buffered typing before explicit paste to preserve input order. Discard pending clipboard text when the thread or editable target changes, while allowing shortcut releases and repeated paste shortcuts to leave the read pending.

## Testing

Extend shortcut and clipboard-worker tests to cover text fallback, multiline Unicode text, stale-read cancellation, shortcut releases and repeats, and read-only drafts. Add assertions for history-search preview stability and selection changes.

GitOrigin-RevId: 080c1c05a4587e325cea938a6e28c646b9ac5837
2026-10-11 23:44:43 +00:00
Eric Traut 97c1f62898 Fix startup draft recovery for pending Vim Replace keys (#53148)
## Why

Startup recovery treated a buffered Vim Replace key as an insertion, so the recovered unsent text could differ from the eventual edit. Replacing the first character of `abcd` with `X` should recover `Xbcd`, not `Xabcd`.

## What changed

Preserve the distinction between held typed keys and buffered pastes when building recovery snapshots. Apply Vim Replace semantics to held keys, including mouse selections and the bash-mode prefix offset, without consuming live pending input. Keep buffered pastes literal so the live paste path retains responsibility for large-paste and image classification.

## Testing

Add regression tests for recovery after startup draft handoff and replacement of mouse-selected text with and without the bash-mode prefix. Verify that taking a recovery snapshot leaves live input unchanged and that flushing the held key produces the same text.

GitOrigin-RevId: 97fada635ad9f0f01042b8e96020372d6df9d951
2026-10-11 15:38:44 +00:00
Benjamin Carlsson 37f53199a6 Use the shared text editor for command-center task renaming (#50216)
## What changed

Replace the rename field with a single-line `TextArea` that honors configured editor bindings and the composer's Vim setting. Start renaming in insert mode and support Vim Escape recovery on legacy terminals.

Strip carriage returns and newlines from titles and pasted text, keep Vim linewise pastes inline, and scroll horizontally at grapheme boundaries to keep the cursor visible.

## Testing

Add single-line editor coverage for newline filtering, Vim commands, repeat edits, and inline yanks. Extend command-center tests to cover Vim renaming across status-filter changes and cursor placement in narrow layouts.

GitOrigin-RevId: 8d320d6b6de9f77e18292169418383929ca6ceda
2026-10-02 07:22:28 +00:00
Ian MacLeod 6ece7bfc21 Keep fullscreen prompts bounded and scrollable (#50109)
## Why

Long drafts need to remain browsable while leaving room for the transcript. Remote image attachments also need to leave an editable prompt row visible.

## What changed

- Cap the fullscreen composer, including padding and hints, at two-thirds of the screen, with a minimum of eight rows when the screen allows.
- Support mouse-wheel browsing without moving the caret or changing transcript selection, search, or activity focus. Show arrows for hidden prompt rows and hide the cursor when the caret is offscreen.
- Resume caret following on editor input, paste, and external edits.
- Keep the selected remote image visible while reserving space for prompt text.

## Testing

Add regression tests and snapshots for fullscreen scrolling, caret restoration after navigation, paste and external edits, remote image navigation and deletion, resizing at scroll boundaries, and disconnected editing.

GitOrigin-RevId: 9a1e4ce14b3b3747e6d136207546327531339258
2026-10-01 22:00:12 +00:00
Benjamin Carlsson 1983c48fd1 Continue Markdown blockquotes when pasting multiline text (#49357)
## Why

Pasting multiple lines into a blockquote previously left subsequent lines unquoted.

## What changed

- Continue the current line's `> ` prefix across pasted lines, including blank and trailing lines, in the TUI composer and embedded answer fields.
- Append two unquoted newlines so typing resumes in the next Markdown block. Preserve quoting when large paste placeholders expand on submission.
- Use a shared edit target for paste context and insertion so selection replacement uses the prefix at the replacement start.
- Keep shell input and provisional startup pastes literal.

## Testing

Add unit tests and rendering snapshots for blockquote pastes, embedded answers, cursor placement, selection replacement, and large-paste expansion. Add textarea tests for forward and backward selections, adjacent elements, and Vim Replace backspace recovery.

GitOrigin-RevId: 525a7951aa16a25d49cc3be98822d0dd0709de97
2026-09-29 20:22:34 +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 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 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 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
Benjamin Carlsson 5a0419edb5 Add Vim replace mode to the TUI composer (#42194)
## What changed

- Add Vim Replace mode, entered with `R`, which overwrites graphemes and appends at the end of a line.
- Restore overwritten text with Backspace and record replace edits for undo and dot-repeat.
- Preserve composer behavior for attachments, completions, paste bursts, history previews, and external editor imports while replacing text.
- Expose `vim_normal.enter_replace_mode` in the configurable TUI keymap.

## Testing

- Add coverage for grapheme replacement, Backspace recovery, dot-repeat, custom bindings, atomic attachments, completions, paste handling, and history interactions.

GitOrigin-RevId: cb04e3adcce013c1eb7b82c994b00e944310c481
2026-09-02 03:35:41 +00:00
Benjamin Carlsson 9c7edd4bc3 Add Vim undo to the TUI composer (#41941)
## Why

Composer drafts include attachments, mention targets, and deferred paste payloads in addition to visible text. Vim undo needs to restore that complete state as a single edit.

## What changed

- Add bounded, draft-level Vim undo history, with `u` as the configurable default binding in normal mode.
- Group complete Vim commands and insert sessions into undo steps, including direct composer changes such as pastes and attachments.
- Preserve undo, repeat, and search state when a reverse-history preview is canceled, and start fresh history when another prompt is accepted.

## Testing

- Cover grouped edits, custom bindings, history and search interactions, attachments, and large paste payloads.

GitOrigin-RevId: 12ecdb3c34a2d66f5d856aa2f82dc15bd91b230b
2026-09-01 00:21:22 +00:00
Benjamin Carlsson 0344625ccf Start fresh Vim drafts in Insert mode (#41921)
## What changed

- Start the composer in Vim Insert mode when Vim is enabled and return to
  Insert mode after submissions and slash-command dispatch.
- Record the fresh Insert session as a Vim edit so `.` can repeat text entered
  in a new draft.
- Keep `/` and `?` as Normal-mode composer searches, and let Backspace cancel
  an empty search query and any pending operator without changing the draft.

## Testing

- Add coverage for startup, submitted and queued drafts, inline and goal slash
  commands, repeatable edits, and canceled searches.

GitOrigin-RevId: 1a5ee30c44685d2b2a037e46c3ab4ab611024919
2026-08-31 22:26:09 +00:00
Benjamin Carlsson 63d213884d Add Vim search motions to the composer (#41586)
## What changed

- Add draft-local forward and backward literal search with `/` and `?`, plus
  wrapped repeat navigation with `n` and `N`.
- Support search motions after delete, change, and yank operators, while keeping
  queries separate from the draft and skipping atomic elements and partial
  grapheme matches.
- Render and edit the query in the composer footer, highlight matches, and add
  configurable `tui.keymap.vim_search` bindings to the keymap picker and schema.

## Testing

- Cover navigation, wrapping, operator composition, repeat behavior, Unicode
  graphemes, atomic elements, query editing, paste handling, and rendering.

GitOrigin-RevId: 087b080ff8fd74e48456c6b899c07ea5eed38e0c
2026-08-30 00:42:00 +00:00
Benjamin Carlsson d47e5cc0e2 Add Vim buffer jump motions (#40958)
## What changed

- Add `gg` and `G` motions to jump to the first and last buffer lines.
- Support the motions with delete, change, and yank operators, including dot-repeat for edits.
- Expose normal-mode and operator-motion bindings in the configurable keymap while preserving conflicting user bindings.

## Testing

- Cover buffer jumps, operator combinations, repeat behavior, chord routing, and custom remapping.

GitOrigin-RevId: 24a9178cf7964053aaf9a8cd268c5434dda0778e
2026-08-26 19:31:52 +00:00
Benjamin Carlsson 98ee29c7cd Add Vim character find and till motions (#40785)
## What changed

- Add line-local `f`, `F`, `t`, and `T` motions to Vim normal mode.
- Support the motions with `c`, `d`, and `y`, including dot-repeat for changes.
- Expose separate configurable normal-mode and operator-motion bindings, while preserving existing custom keymaps that use the new defaults.
- Keep character targeting aligned to extended grapheme boundaries and skip embedded composer elements.

## Testing

- Cover forward and backward motion and operator ranges, missing and adjacent targets, cancellation, dot-repeat, custom bindings, shifted terminal key events, grapheme clusters, and embedded elements.

GitOrigin-RevId: 2610cf9a13538d9ae9b890c01417ca25316c1d60
2026-08-26 04:18:49 +00:00
Charlie Marsh d6174a8798 Preserve composer hyperlinks across wrapped lines (#40720)
## What changed

- Detect visible HTTP(S) URLs in the composer and attach the complete OSC 8 destination to every wrapped fragment, including when part of the URL is scrolled offscreen.
- Cache hyperlink metadata with the textarea wrap state while leaving masked input and destinations larger than 8 KiB unannotated.
- Make shared hyperlink mapping grapheme-aware, recognize Unicode whitespace boundaries, and scan URLs and trailing delimiters incrementally for large inputs.

## Testing

- Add coverage for wrapped and scrolled URLs, joined emoji, Unicode whitespace, preserved highlighting, masked input, cache invalidation, oversized destinations, and drafts containing many URLs.

GitOrigin-RevId: 40facdf2fe79438c91c82bff2d849c342f1ab28a
2026-08-25 22:05:48 +00:00
Benjamin Carlsson c1db22a3cd Add dot-repeat to Vim mode (#40521)
## What changed

- Bind `.` in Vim normal mode to repeat the last complete edit.
- Record semantic delete, change, replace, paste, and insert-mode actions so repeats preserve motions, text objects, inserted text, and editor actions across keymap changes.
- Expose `vim_normal.repeat_last_change` in the configurable keymap and keymap picker, including conflict handling for existing custom bindings.

## Testing

- Add coverage for repeating deletes, replacements, complete changes, pasted and literal text, insert-mode editor actions, custom bindings, unavailable motions, and cleared buffers.

GitOrigin-RevId: 3213df964811e7902377ff1d93641e59f4037914
2026-08-25 02:34:04 +00:00
Benjamin Carlsson c3db180493 Skip postprocessing for short composer input (#39744)
## What changed

Return the initial wrapping ranges directly when the composer input produces a
single line and its byte length is less than the available width. This avoids
the additional grapheme and word-boundary pass for input that cannot wrap.

GitOrigin-RevId: 55d990a354fcc61e9a90d5796b4b39d16742cc50
2026-08-20 17:00:05 +00:00
Benjamin Carlsson 631d5a8b02 Expand Vim change commands and add character replacement (#39661)
## What changed

- Add the configurable `vim_normal.replace_char` action, bound to `r` by default, to replace the grapheme under the cursor while remaining in normal mode.
- Support change-operator motions such as `cw`, `c$`, `cj`, and `ck`, plus the repeated `cc` command for changing the current line.
- Let `Esc` cancel a pending replacement before it reaches composer-level handling.
- Preserve existing custom Vim bindings and chord prefixes when introducing the new default.

## Testing

- Cover replacement, grapheme boundaries, remapping and unbinding, change motions, cancellation, keymap conflicts, and keymap picker snapshots.

GitOrigin-RevId: 98feb4eeb57142c37adb73abfe58d1f703b9270d
2026-08-20 08:13:56 +00:00
Charlie Marsh 0841d9bba5 Hang soft-break whitespace in the TUI composer (#39022)
## Why

Keeping overflowing separators with the following word can add whitespace-only
rows and make composer wrapping differ from the queued-input preview.

## What changed

- Hang breakable whitespace from the preceding visual row at soft word breaks
  while preserving the underlying editable text.
- Keep indentation, trailing whitespace, mandatory breaks, and nonbreaking spaces
  visible and editable according to their existing semantics.
- Align cursor placement, scrolling, vertical navigation, masked rendering, and
  styled overlays with the visible wrapped content, including after resizes.

## Testing

Add focused wrapping, rendering, cursor, editing, scrolling, navigation, Unicode
separator, long whitespace-run, and resize coverage.

GitOrigin-RevId: 7fbdb0a4bf33cfee20c4c19dca5aee74df4f892c
2026-08-17 16:39:37 +00:00
Charlie Marsh a16863f870 Keep wrapped composer whitespace with following text (#37709)
## Why

Overflowing whitespace in the TUI composer could occupy a separate blank row
instead of remaining attached to the text that follows it.

## What changed

- Add composer-specific, grapheme-safe wrapping that keeps breakable Unicode
  whitespace with the following word while preserving semantic breakpoints such
  as hyphens and nonbreaking spaces.
- Preserve cursor insertion rows and positions as content reflows, including
  across full lines and wrapped fragments.
- Keep wrapping linear for maximum-length unbroken input.

## Testing

Add focused rendering and cursor tests for ASCII and Unicode whitespace,
hyphenated words, reflowed fragments, and maximum-length input.

GitOrigin-RevId: fb7713e33bfddf37460b6c2f6f0c9700f31d86bf
2026-08-09 15:49:17 +00:00
Felipe Coury 8d398d3c52 feat(tui): add vim text object bindings (#24382)
## Why

Vim mode currently supports some normal-mode operators and motions, but
common text-object combinations like `ciw`, `daw`, `di(`, and
quote/bracket variants are still missing. That makes the composer feel
incomplete for users who expect operator + text object editing to work
inside prompts.

Closes #21383.

## What Changed

- Add Vim pending-state support for operator/text-object sequences.
- Add `c` as a normal-mode operator for text objects, so combinations
like `ciw` delete the object and enter insert mode.
- Support word, WORD, delimiter, and quote text objects:
  - `iw`, `aw`, `iW`, `aW`
  - `i(`, `a(`, `i)`, `a)`, `ib`, `ab`
  - `i[`, `a[`, `i]`, `a]`
  - `i{`, `a{`, `i}`, `a}`, `iB`, `aB`
  - `i"`, `a"`, `i'`, `a'`, `i\``, `a\``
- Add configurable keymap entries and keymap picker coverage for the new
Vim text-object context.
- Regenerate the config schema and update keymap picker snapshots.

## How to Test

Manual smoke test:

1. Start Codex with Vim composer mode enabled.
2. Type a draft such as:
   ```text
   alpha beta gamma
   call(foo[bar], {"x": "hello world"})
   say "one \"two\" three" now
   ```
3. Put the cursor on `beta`, press `ciw`, and confirm `beta` is removed
and the composer enters insert mode.
4. Escape back to normal mode, put the cursor on `gamma`, press `daw`,
and confirm `gamma` plus surrounding whitespace is removed.
5. Put the cursor inside `foo[bar]`, press `di[`, and confirm only `bar`
is removed.
6. Put the cursor inside `call(...)`, press `da(`, and confirm the whole
parenthesized section is removed.
7. Put the cursor inside the quoted text, press `ci"`, and confirm the
quote contents are removed and insert mode starts.
8. Verify cancellation does not edit text: press `d` then `Esc`, and
press `d` then `i` then `Esc`.

Targeted tests:

- `cargo test -p codex-tui --lib vim_`
- `cargo nextest run -p codex-tui keymap_setup::tests`

Additional local checks:

- `just write-config-schema`
- `just fmt`
- `just fix -p codex-tui`
- `git diff --check`
- `cargo insta pending-snapshots --manifest-path tui/Cargo.toml`

Local full-suite note: `just test -p codex-tui` ran to completion. The
keymap snapshot failures were expected and accepted. Two unrelated
guardian feature-flag tests still fail locally:
-
`app::tests::update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default`
-
`app::tests::update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`

`just argument-comment-lint` is currently blocked locally by Bazel
analysis before the lint runs because `compiler-rt` has an empty
`include/sanitizer/*.h` glob in the local Bazel cache. The touched Rust
diff was manually inspected for opaque positional literals.
2026-05-27 15:15:03 -03:00