Commit Graph
2394 Commits
Author SHA1 Message Date
Eric Traut fd5018e044 Add a dedicated codex agents dashboard command (#39114)
## What changed

- Add `codex agents` to open the shared agents overview without creating a new session.
- Start the local background app server automatically on Unix, or connect to a server supplied with `--remote`.
- Reject invocation-specific session overrides that cannot apply to shared sessions.
- When the overview is opened from an embedded session, offer to start the background server without moving or interrupting the current session.

## Testing

- Cover command-line parsing and rejection of incompatible overrides.
- Snapshot the embedded-session background-server prompt.

GitOrigin-RevId: 60845dfebc48d820dc4ff090626d30452127f062
2026-08-18 00:31:51 +00:00
Eric Traut 319b2f72b1 Make the agents overview an interactive task dashboard (#39112)
## What changed

- Let users start tasks, open root sessions, rename tasks, and stop active work directly from the agents overview.
- Show details for the selected task on wide terminals and limit the overview to root sessions while still reflecting background activity.
- Preserve draft input and pending server requests when switching sessions so running roots and their subagents can continue in the background.
- Apply the selected project's working directory when dispatching from project grouping, including remote workspaces.

## Testing

- Expand overview rendering and interaction coverage for root filtering, dispatch, search, selection, renaming, and responsive input.
- Cover switching away from roots with running subagents and retaining background server requests.

GitOrigin-RevId: b7b0d33b7ecc077498efb756a0ad2fd425158b17
2026-08-17 23:47:55 +00:00
Tamir Duberstein 050aa077b5 Avoid redundant terminal size queries during history insertion (#39100)
## What changed

- Pass the screen size already available to TUI draw and history-tail paths into history insertion.
- Use the terminal's cached screen size for direct history insertion calls instead of querying the backend again.
- Extend the terminal size-query regression test to cover history insertion.

GitOrigin-RevId: 44c7a0f0bc5bc365d8d0c72d7e26587ed17a4821
2026-08-17 22:58:25 +00:00
Eric Traut 4617d4d21d Add an agents overview dashboard to the TUI (#39094)
## What changed

- Add `/agents` to open a full-screen dashboard of loaded root sessions from the shared app server, with subagent status reflected in each root session.
- Support search, navigation, and grouping sessions by project or status.
- Refresh the dashboard when relevant thread notifications arrive, while preserving its selection and view preferences.
- Show a clear message when the dashboard is unavailable with the embedded app server.

## Testing

- Add coverage for dashboard rendering, status grouping, persisted view state, and restoring the conversation viewport after closing the dashboard.
- Cover `/agents` command discovery and dispatch from parent-owned threads.

GitOrigin-RevId: 6651f4c47358116e1809da3ac8844a5842026a95
2026-08-17 22:50:25 +00:00
Eric Traut 83d015375e Add a command to queue messages for existing sessions (#39092)
## What changed

- Add `codex queue --thread <THREAD> --message <TEXT>` to submit a text message through the `thread/queue/add` app-server API.
- Resolve active sessions by UUID or exact name across interactive, exec, and custom sources, and reject ambiguous names.
- Support local and explicit remote app servers while reporting incompatible servers and configuration overrides instead of silently changing the target.
- Reject empty messages and image attachments.

## Testing

- Add CLI coverage for remote submission, validation, unsupported servers, and local-daemon routing.
- Add session lookup and queue tests for stale, non-interactive, custom, and duplicate session names.

GitOrigin-RevId: 44c233f752b63a85c85b92fa6da303336e4ddeca
2026-08-17 22:44:37 +00:00
Eric Traut 0c14c73471 Harden TUI subagent navigation (#39088)
## What changed

- Use `/subagents` consistently for the subagent picker and status UI, removing the `/agent` alias.
- Rejoin already-loaded subagent threads without overriding their existing settings.
- Route notifications and approval requests only to the active thread or its known subagents, discard unrelated startup events, and avoid replaying resolved approvals.

## Testing

- Add coverage for filtering buffered startup events, dropping resolved approvals, preserving owned subagent approvals, and resuming threads without setting overrides.

GitOrigin-RevId: b4e597f7cd4756faccf31d8b964e7a172f5ab0eb
2026-08-17 22:31:13 +00:00
iceweasel-oai 2013e04354 Preserve filesystem permission path conventions (#39084)
## Why

Filesystem permission paths can use a convention that differs from the host
running Codex. Converting them immediately to native absolute paths can change
the meaning of ambiguous paths such as `/C:/secret` or Windows UNC paths.

## What changed

- Store literal filesystem permission paths as `PathUri` values through the
  runtime policy and execution protocol.
- Keep legacy string-based serialization at explicit protocol boundaries and
  reject conversions that cannot be represented losslessly.
- Encode native paths as opaque URIs when a normal file URI would imply the
  wrong path convention.

## Testing

Added coverage for cross-platform and ambiguous path round trips, UNC path
variants, permission-profile serialization, and deny-policy enforcement.

GitOrigin-RevId: 5247713796d1f2bb4e02f94eb9fc82d4698060f0
2026-08-17 21:49:30 +00:00
Eric Traut 34e4823a1d Prompt for project trust in remote TUI workspaces (#39082)
## What changed

- Query the remote app server for project config layers before starting a thread and show the trust prompt when the project has no existing decision.
- Resolve relative remote working directories and repository-root trust targets, then persist accepted trust through `config/batchWrite` on the remote server.
- Preserve existing trusted and untrusted decisions, including an untrusted repository that contains the requested working directory.
- Exit when the remote trust prompt is declined and ignore repeated key events in the trust selector.

## Testing

- Add coverage for remote trust detection, persistence, thread startup, existing decisions, nested untrusted projects, and rendering a remote Git subdirectory.

GitOrigin-RevId: e5fba2ea23bad1fb28f01df522cadbe05fcbb942
2026-08-17 21:06:34 +00:00
Tamir Duberstein 9c099e94a2 Bound TUI thread replay buffers by delta size (#39081)
## Why

The per-thread replay buffer limited its event count, but streamed agent-message
deltas could still retain an unbounded amount of text while a thread was
inactive.

## What changed

- Coalesce adjacent deltas for the same thread, turn, and item into chunks of up
  to 4 KiB.
- Limit buffered agent-message deltas to 256 KiB, discard a single delta larger
  than that limit, and evict the oldest events when either buffer limit is
  exceeded.
- Keep pending input and approval state in sync when eviction removes the
  corresponding request, including clearing side-thread status indicators.

## Testing

Added coverage for delta coalescing, byte-based eviction, oversized deltas,
replaying only retained text, and side-thread status updates after eviction.

GitOrigin-RevId: 88d85353a124467d467822d2fd9854312b68d547
2026-08-17 21:03:06 +00:00
Benjamin Carlsson e92627bf7e Build filesystem JSON params only for remote TUI sessions (#39077)
## Why

In-process app-server filesystem requests use typed protocol requests and do
not need JSON-RPC parameters.

## What changed

Pass remote filesystem parameters to `request_fs_path` as closures and
evaluate them only when the session uses a remote request handle.

GitOrigin-RevId: 623c8733542553d73e2c0e4c4a60d40258bc91c1
2026-08-17 20:46:43 +00:00
Tamir Duberstein 37efa18be2 Avoid redundant terminal row clears (#39075)
## Why

The custom TUI buffer diff emitted `ClearToEnd` for unchanged trailing blank
regions, producing unnecessary terminal output.

## What changed

- Clear a row tail only when its cached contents changed or a wide glyph overlaps
  the clear boundary.
- Keep blank cells marked `AlwaysUpdate` in the drawable region so viewport
  invalidation still forces them to repaint.
- Preserve Ratatui's native cell diff behavior for the remaining updates.

## Testing

Add coverage for unchanged row tails, forced blank-cell updates, and shrinking
wide graphemes, including half-width katakana with combining marks.

GitOrigin-RevId: a9cac06f5624032a2b8c80a66c651cf3e85ec7fb
2026-08-17 20:43:12 +00:00
Charlie Marsh d327527a3d Limit terminal hyperlink layout to the visible viewport (#39065)
## What changed

- Skip hyperlink layout for wrapped rows above the scroll offset and stop once
  processing reaches the bottom of the viewport.
- Resolve each rendered link destination once while marking its visible cells.
- Add coverage for hyperlinks that span visible wrapped rows after scrolling.

GitOrigin-RevId: c1506d47fa3f1b895966dc2cde7d5b859c201792
2026-08-17 20:06:41 +00:00
Benjamin Carlsson 1aa3a68e7b Restrict queued-message editing to its dedicated binding (#39064)
## What changed

- Stop treating Vim normal-mode history-up as an alias for editing the latest queued message.
- Continue to edit queued messages through the configured `chat.edit_queued_message` binding.

GitOrigin-RevId: d830e0976a38725e948d420c1a5f374bb13fe945
2026-08-17 20:02:50 +00:00
Charlie Marsh b6e153c985 Render only visible rows in the transcript pager (#39063)
## Why

Scrolling the transcript pager previously rendered a scratch buffer containing
all rows through the visible viewport, including hidden content above it. This
made rendering work and buffer size grow with the scroll offset.

## What changed

- Add viewport-aware rendering for committed transcript cells and the live tail.
- Forward scrolled rendering through cached and inset renderables while keeping
  the full-height fallback for renderables that do not support it.
- Keep hyperlink metadata aligned with scrolled text.

## Testing

Add coverage comparing viewport-aware output with the full-height fallback
across wrapping widths, offsets, insets, styles, hyperlinks, and live tails.

GitOrigin-RevId: 630c30c4a61969a50f2b34701ca1dd87788a4298
2026-08-17 19:59:22 +00:00
Charlie Marsh 386a7b629c Avoid rerendering streamed code fences (#39061)
## Why

The streaming TUI rerendered the entire mutable Markdown block whenever a
newline-bearing delta arrived. For long fenced code blocks, this repeatedly
parsed and syntax-highlighted the growing fence.

## What changed

- Detect open, top-level, language-tagged code fences and append newly
  completed lines directly to the existing render.
- Preserve Syntect parser state across appended lines so multiline syntax and
  the active theme remain consistent.
- Fall back to the canonical Markdown renderer for ambiguous fence syntax,
  theme changes, incomplete lines, and highlighting limit transitions.

## Testing

Added coverage that compares streamed output with full renders across syntax
styles, Unicode, links, blank lines, fence variants, theme changes, and
highlighting limits. A long-fence test also verifies that the rendered prefix
is retained as new lines arrive.

GitOrigin-RevId: 036db2b7bc93607083b8001f8b4fa3cbb58c713e
2026-08-17 19:49:47 +00:00
Tamir Duberstein 796325f1e5 Rate-limit TUI frames from their actual emission time (#39057)
## Why

Recording a late frame's requested deadline as its emission time can leave the
rate limiter with a stale timestamp, allowing the next frame to be emitted
immediately in a redraw burst.

## What changed

Record the current time when the frame scheduler sends a draw notification so
the 120 FPS limit is measured from the actual emission.

## Testing

Add a paused-time regression test that submits an overdue draw and verifies the
next frame waits for `MIN_FRAME_INTERVAL`.

GitOrigin-RevId: 8c9a5ac0bf858b2ad87838f6d7c67c9470fdfc61
2026-08-17 19:34:05 +00:00
Charlie Marsh fe5889928c Use installed callable apps for TUI mentions (#39051)
## Why

The app directory is a discovery catalog and can include apps that are not
callable in the active thread. Using it for `$` suggestions can therefore
offer mentions that cannot be used.

## What changed

- Load mention candidates from `app/installed`, enrich callable apps through
  bounded `app/read` batches, and retain compatibility with app servers that
  do not support `app/installed`.
- Keep the mention catalog separate from the `/apps` directory cache and scope
  results to the current thread, workspace, and account.
- Refresh mentions after app notifications, enablement changes, configuration
  updates, and apps MCP readiness, while immediately removing disabled apps.

## Testing

Add coverage for batching and fallback behavior, stale scoped results,
notification refreshes, enablement changes, MCP startup races, and filtering
non-callable apps from mentions.

GitOrigin-RevId: 4d9e20794aed30cc97120170792fb555b86fe1e7
2026-08-17 19:11:34 +00:00
Benjamin Carlsson 1a8bac9405 Avoid rendering sub-agent activity twice in the TUI (#39049)
## Why

The app server sends sub-agent activity in both item-started and item-completed
notifications, causing the TUI to add the same activity to history twice.

## What changed

Render live sub-agent activity when the item completes instead of also rendering
it when the item starts. Preserve the existing replay behavior.

## Testing

Add a regression test that sends matching started and completed notifications
and verifies that the activity produces one history cell.

GitOrigin-RevId: 76a66f3657fe297f37067ed672ab9642997b4499
2026-08-17 19:02:05 +00:00
Abhinav 0f21cb3413 Enforce managed authentication backend settings (#39043)
## What changed

- Add `cli_auth_credentials_store` and `chatgpt_base_url` as exact managed requirements loaded from local requirements configuration.
- Apply these requirements to runtime and bootstrap authentication configuration, overriding user-configured values.
- Expose the managed values through `configRequirements/read` and reject attempts to change them through config write APIs.
- Ignore these local-only authentication requirements in cloud-managed requirement layers.

## Testing

- Cover requirement loading and composition, runtime and bootstrap overrides, app-server responses, and read-only config writes.

GitOrigin-RevId: 8ea9c096386072036ca5441f3d48af8707988a65
2026-08-17 18:35:54 +00:00
Charlie Marsh a8525b139c Bound legacy resume preview scans (#39033)
## Why

Building a resume-picker preview for a legacy session should not require loading its full thread history.

## What changed

- Read up to six preview lines by scanning at most 1 MiB from the end of a local legacy rollout.
- Fall back to the existing history hydration path when the local file is unavailable, the bounded scan is incomplete, or the tail contains a rollback.
- Keep the initial `thread/read` request turn-free while loading the preview.

## Testing

Added coverage for compaction, rollbacks, oversized records, exhausted scan budgets, and app-server request parameters.

GitOrigin-RevId: a8950f03d8b56323f268fd3355c6a38a16cb9833
2026-08-17 17:14:46 +00:00
Charlie Marsh dc473903ab Encapsulate TUI shimmer under the motion module (#39032)
## Why

Direct access to shimmer primitives can bypass the reduced-motion handling
introduced in https://github.com/openai/codex/pull/20564.

## What changed

- Make `shimmer` a private child of `motion` and restrict `shimmer_spans` to
  its parent module, so Rust visibility enforces the animation boundary.
- Remove the source-scanning regression test that previously checked this
  boundary with regular expressions.

GitOrigin-RevId: 1f4cccacaa907992c636cd1e9cd2829b7653f811
2026-08-17 17:10:16 +00:00
Charlie Marsh 8892aa8fa0 Speed up the in-app resume cwd test (#39030)
## What changed

- Reuse shared directory fixtures and local and remote app-server instances across the resume cwd case matrix.
- Seed the runtime working-directory override directly so each case focuses on resume behavior without starting and replacing an extra thread.
- Run the test on a four-thread Tokio runtime and shut down each shared server after all cases complete.

GitOrigin-RevId: 4bc4978abc546882f26bcb5e3591ff9673758b4a
2026-08-17 17:04:09 +00:00
Charlie Marsh 10fbb61838 Cache the test pet spritesheet encoding (#39028)
## Why

Pet tests reuse the same blank WebP spritesheet fixture, so encoding a new image
for every temporary path does unnecessary repeated work.

## What changed

Encode the test spritesheet once with `LazyLock`, then write the cached WebP bytes
to each requested fixture path.

GitOrigin-RevId: 26d75bb1bac448717ca63aeb82eb4e500c86fad8
2026-08-17 16:58:24 +00:00
Charlie Marsh 171ae66d74 Use simulated time in the long typing test (#39026)
## Why

The 1,000-character human-like typing test waited on the wall clock after
every keypress, making the test unnecessarily slow.

## What changed

Advance an injected timestamp by the recommended paste flush delay and flush
the paste-burst detector explicitly after each character. This preserves the
coverage that slow typing appears directly without creating a paste
placeholder, without sleeping between keypresses.

GitOrigin-RevId: 0c1beb40283f7d73a381cd221725ab4227c8e233
2026-08-17 16:54:49 +00:00
Charlie Marsh c6ba7b7f8e Speed up the large diff highlighting test (#39025)
## What changed

Construct the oversized unified diff fixture directly instead of generating it
from two large input strings. Keep the fixture just above
`MAX_HIGHLIGHT_LINES` so the test continues to verify that syntax highlighting
is skipped for large updates.

GitOrigin-RevId: 8f8853e03a50ff9f53e77b2ba0956cf85ee17c07
2026-08-17 16:50:47 +00:00
Charlie Marsh f0904922f6 Reduce retained MCP result data in TUI history (#39023)
## Why

MCP tool results can contain multi-megabyte image, audio, or resource bodies,
even though TUI history renders only summaries for those content types.

## What changed

- Project completed MCP results into width-independent display data, dropping
  media and resource bodies that history does not render.
- Preserve text output, JSON fallbacks, error state, Node REPL rendering, and
  the fully decoded image-output marker.
- Add tests covering width-dependent rendering, image validation, and Node REPL
  text fields on non-text and unknown content blocks.

GitOrigin-RevId: 2cfddf0864093e6837a4431e541f7a9cab544a68
2026-08-17 16:46:26 +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
Eric Traut 09bc28f348 Restrict Windows IDE pipe client impersonation (#39020)
## Why

Windows named pipe servers can impersonate connected clients. IDE context
connections only require the server to identify the client, so they should not
grant broader impersonation rights.

## What changed

Open Windows IDE context pipes with `SECURITY_SQOS_PRESENT` and
`SECURITY_IDENTIFICATION`, limiting the server's impersonation token to the
identification level.

## Testing

Add a Windows regression test that connects to a named pipe, asks the server to
impersonate the client, and verifies that the resulting token has the
`SecurityIdentification` level.

GitOrigin-RevId: 51ef080f3367857987e03b0113a476040ea40e56
2026-08-17 16:34:21 +00:00
Anton Panasenko 3b4569a920 Add experimental app-server project APIs (#38940)
## What changed

- Add SQLite-backed `project/list`, `project/read`, `project/create`,
  `project/import`, `project/update`, `project/move`, and `project/delete`
  endpoints with ordered roots, metadata, manual positioning, pagination, and
  idempotent creation.
- Add project assignment to thread start, metadata updates, list filtering,
  and fork inheritance. Project deletion clears assignments without deleting
  threads.
- Emit `project/changed` and `thread/project/updated` notifications after
  committed changes, and export the new protocol schemas and TypeScript types.

## Testing

- Cover project lifecycle and ordering, idempotency, atomic imports, cursor and
  filter validation, thread assignment, deletion, and fork inheritance.

GitOrigin-RevId: 47ae621be01ab8ef70a74a629fb29a5c5709ea33
2026-08-17 04:01:37 +00:00
Eric Traut 1f41cc5d92 Compact successful command activity in the TUI (#38921)
## What changed

- Group consecutive successful agent and unified-exec startup commands into a compact `Ran N commands` entry while preserving their full transcript.
- Flush command groups at interaction boundaries, after failures, and after 32 completed commands. Keep manual shell commands and failed or declined commands visible.
- Apply the same grouping rules when replaying thread history without duplicating command starts or disturbing unrelated active commands.

## Testing

- Add TUI coverage for live and replayed grouping, transcript preservation, failures, overlapping commands, group limits, and interaction boundaries.

GitOrigin-RevId: d6602a20201644012fcff3d6cecf4690024383a9
2026-08-17 00:32:09 +00:00
Benjamin Carlsson cd8dc1e9b6 Stop rendering columns after filling their area (#38913)
## What changed

Stop visiting remaining `ColumnRenderable` children once the render position
reaches the bottom of the available area.

GitOrigin-RevId: 5b7f2c657f65879119b1b840e82f47b1c5f9e3db
2026-08-16 23:05:11 +00:00
Benjamin Carlsson 2bc43d516e Edit queued messages with Vim history-up (#38907)
## What changed

- When the composer is empty in Vim normal mode, make the configured history-up binding restore the latest queued follow-up for editing.
- Remove the restored message from the queue so submitting the edited version replaces it instead of creating a duplicate.
- Preserve normal history navigation when the composer has text or a popup is active, and honor remapped Vim bindings.

## Testing

- Add TUI tests covering repeated edit-and-requeue cycles and a remapped history-up binding.

GitOrigin-RevId: 0b04dd964d3fc6fdcd10712aa4d5fd81cbbd2255
2026-08-16 21:48:41 +00:00
Benjamin Carlsson ed32158e90 Add working-directory commands to the TUI (#38894)
## What changed

- Add `/cd [path]` for changing an idle local session's working directory while preserving conversation history. Relative paths resolve from the current directory, and omitting the path selects `~`.
- Reload project configuration, instructions, permissions, keybindings, file search, and hooks for the destination before replacing the active session.
- Reject unsafe transitions, including active or queued work, background terminals, remote environments, untrusted destinations, and incompatible permission profiles.
- Add `/pwd` and its `/cwd` alias to display the current working directory, and discard asynchronous results left over from the previous directory.

## Testing

- Cover command parsing, aliases, default paths, session eligibility, transition failures, history preservation, destination policy loading, hooks, and stale events.

GitOrigin-RevId: 1a987c029f157a087ba02c0f26e022260409132b
2026-08-16 19:48:07 +00:00
Benjamin Carlsson 9bfaf7a076 Share editor keymaps across TUI composer components (#38837)
## What changed

- Store the editor portion of `RuntimeKeymap` in an `Arc` so the chat composer
  and its embedded textarea use the same keymap snapshot.
- Initialize the textarea from the composer's default runtime keymap and keep
  custom binding updates shared between both components.
- Use copy-on-write when tests and binding resolution need to mutate editor
  bindings.

## Testing

- Verify that applying custom editor bindings shares the same keymap allocation
  with the composer and textarea.

GitOrigin-RevId: 7f3b0afd6cc784e23deee8819e5c2c37a3709c68
2026-08-16 05:59:34 +00:00
viyatb-oai 73abda8bfe Isolate external editor buffers from sandbox-writable paths (#38830)
## Why

External editor buffers can contain the current composer text and should not be
placed in directories exposed as writable by a restricted filesystem policy.

## What changed

- Create editor buffer files under a protected `editor` directory, trying the
  configured Codex home, the default Codex home, and a workspace fallback.
- Reject candidates that overlap writable roots or resolve through symbolic
  links, while preserving external editor support for full-disk-write policies.
- Surface an editor error when no protected directory is available.

## Testing

Add coverage for writable roots, aliases, symbolic links, fallback selection,
temporary-directory grants, full-disk-write policies, and editor invocation.

GitOrigin-RevId: df1029d81b327678991ab84ffd1077f0e5855631
2026-08-16 03:14:17 +00:00
Benjamin Carlsson 49db349ffd Avoid allocating per character when decorating hyperlinks (#38823)
Encode each character into a stack buffer before appending it to the
decorated span, avoiding a temporary `String` allocation for every character.

GitOrigin-RevId: 72ec1ad5363391dffee089f04073d827d8c459bf
2026-08-16 01:34:51 +00:00
Benjamin Carlsson 1ba9ce8910 Avoid cloning TUI history span content (#38822)
GitOrigin-RevId: f189b7afa5c585c4456a2f4ee795827ec4d79907
2026-08-16 01:31:22 +00:00
Charlie Marsh a95a6fe333 Show resume and fork status during TUI startup (#38788)
## What changed

- Display a dimmed `Resuming session…` or `Forking session…` status above the provisional composer based on the requested session action.
- Update or clear the status after session selection resolves, while preserving the composer height and any startup draft text.

## Testing

- Add snapshot coverage for resume and fork loading states and transitions back to a fresh session.

GitOrigin-RevId: 9d37b2d0e390d28dee310dd7a5b9fa992db2c25c
2026-08-15 17:30:13 +00:00
Charlie Marsh a7edf37cb4 Remove the TUI test dependency on codex-cli (#38746)
## What changed

Remove the unused `codex-cli` dev-dependency and the no-op import that kept it
visible to `cargo-shear`. TUI tests continue to locate spawned binaries through
`codex-utils-cargo-bin`.

GitOrigin-RevId: ba5855590c6f0300845170f15f39d77c0611a60a
2026-08-15 11:01:30 +00:00
Charlie Marsh 3c7ae4a812 Scope TUI app directory state to the active context (#38743)
## Why

App directory data and in-flight requests can outlive the account, workspace, or thread that produced them, allowing stale apps to appear in the current TUI context.

## What changed

- Invalidate cached app data, dismiss the app picker, and start a fresh fetch when the account, workspace, or thread changes.
- Tag app directory fetches with their originating thread, workspace, and scope generation, and ignore queued requests or results that no longer match.
- Treat `AppListUpdated` notifications as revalidation signals instead of directly adopting their unscoped contents, with deduplication and a bounded error retry.

## Testing

Added coverage for stale request and result rejection, context invalidation, picker dismissal, and notification revalidation.

GitOrigin-RevId: f20930a0598a6abbdfb3c7826ec955346fe2da7a
2026-08-15 10:57:15 +00:00
Abhinav 85fc4def35 Add MCP tool handler support to the hooks engine (#38705)
## What changed

- Discover synchronous `mcp_tool` hook handlers and invoke their configured MCP server and tool through a supplied executor.
- Expand nested hook-event placeholders in MCP tool inputs while preserving JSON types, and process tool output through the existing hook output contract.
- Represent hook details as handler-specific metadata in `hooks/list`, including MCP server and tool fields, and show those details in the TUI hooks browser.
- Skip unsupported `SessionEnd` MCP hooks and runtimes without MCP invocation support with startup warnings.

## Testing

- Cover argument expansion, missing placeholders, MCP invocation and hook decisions, discovery warnings, `hooks/list` metadata, and TUI rendering.

GitOrigin-RevId: 295b845471fe92bd7ad7cd272fbcd2c3713912e0
2026-08-15 05:53:54 +00:00
kevinlin-openai 3685a61dad Normalize CRLF line endings in pasted text (#38704)
## Why

Replacing every carriage return with a line feed turns each CRLF pair into two
line breaks when text is pasted into the TUI composer.

## What changed

Normalize CRLF pairs before converting remaining bare carriage returns, so each
pasted line ending becomes a single line feed while existing line feeds remain
unchanged.

## Testing

Add a regression test covering mixed CRLF, bare CR, and LF line endings.

GitOrigin-RevId: 86c66d2a52fae52c9ae58c2f24a49eed685b60be
2026-08-15 05:43:44 +00:00
Darius Karel 233739e76a Exclude shortcut-modified input from TUI paste bursts (#38675)
## What changed

- Treat plain, Shift-modified, and Windows AltGr character events as text-producing input for paste-burst detection.
- Exclude Super, Hyper, and Meta character events from paste bursts, flushing any pending text before handling them as shortcuts.

## Testing

- Add coverage for plain and Shift-modified spaces, shortcut-modified spaces, pending burst flushes, and platform-specific AltGr input.

GitOrigin-RevId: 3c43224966307fd014eb1586dce0c53ee56c75aa
2026-08-15 00:32:58 +00:00
kevinlin-openai 274727d37f Delete Thai combining marks one at a time in the composer (#38662)
## Why

Backspace should let users remove Thai vowel and tone marks without deleting the
entire grapheme cluster.

## What changed

- Treat Thai nonspacing marks as individual backward-deletion boundaries.
- Keep embedded text elements atomic and preserve the existing behavior for
  other grapheme clusters, including decomposed Latin text and joined emoji.

## Testing

Add coverage for successive deletion of Thai marks, cursor rendering after
deletion, unchanged non-Thai grapheme handling, and atomic Thai text elements.

GitOrigin-RevId: f4834183909d93f4b4dd92f5d93e89235dc2b621
2026-08-14 22:35:23 +00:00
Charlie Marsh 5186e2ccc3 Skip terminal hyperlink layout when no links are present (#38657)
## What changed

Return early from `mark_buffer_hyperlinks` when none of the supplied lines
contain hyperlink metadata, avoiding unnecessary paragraph layout work.

GitOrigin-RevId: bdd6727f3dab7cef87646f97ac955e848cfcfee2
2026-08-14 21:54:14 +00:00
Charlie Marsh aa1b81e46f Reuse the TUI startup account response during bootstrap (#38649)
## Why

The TUI reads the account to determine login status, then bootstrap reads the
same account again during startup.

## What changed

- Preserve the login-status account response and pass it to app-server
  bootstrap, avoiding the second account request.
- Discard the prefetched response when onboarding or a resume-directory prompt
  allows authentication to change, when a picker replaces the app-server
  session, or when the model provider changes.

## Testing

- Verify bootstrap reuses a prefetched account without issuing another account
  request and retains its account metadata.
- Verify normal bootstrap still reads the account when none was prefetched.
- Verify matching resume directories skip the interactive prompt.

GitOrigin-RevId: 8da1b9104b9e7f048c4254399b126116798d641a
2026-08-14 20:59:34 +00:00
Charlie Marsh efa97f9bc6 Show onboarding when Codex home lacks authentication state (#38644)
## Why

Routine state such as history, logs, sessions, or temporary files does not mean
that the default account can authenticate. Treating any non-pristine Codex home
as configured can show the composer before onboarding is complete.

## What changed

- Base the startup decision on authentication-relevant state instead of requiring
  an empty Codex home. Existing credentials, configuration, workload identity,
  managed configuration, or a running local daemon continue to keep the composer
  visible.
- Treat an unreadable or ambiguous home conservatively and keep the composer
  visible.
- Allow onboarding when the legacy `--search` flag is the only configuration
  override.

## Testing

Expanded startup preflight and draft tests to cover existing home state,
credential sources, workload identity markers, daemon state, ambiguous paths,
and search-only overrides.

GitOrigin-RevId: 76837e3fd6aa714f2a7f72d191088a3faae23515
2026-08-14 20:38:52 +00:00
Charlie Marsh 6d97d4c102 Delay the startup composer until first-login onboarding (#38643)
## Why

On a pristine default installation, the provisional composer can appear before
first-login onboarding takes over the terminal.

## What changed

- Detect pristine local installations conservatively, accounting for existing
  Codex state, custom homes, access tokens, system configuration, and managed
  configuration sources, including macOS managed preferences.
- Keep the composer hidden and ignore draft input until onboarding completes,
  while still allowing startup cancellation with `Ctrl-C` or `Ctrl-D`.
- Reveal the configured composer after onboarding for normal new-session
  launches; resume and fork pickers retain their existing startup flow.

## Testing

- Cover pristine and existing home layouts, environment credentials, system and
  managed configuration, inaccessible state, onboarding input suppression,
  cancellation, and the transition to the composer.

GitOrigin-RevId: c1a47ea3ba7c1ff1dd229895c0362b6dd9bfd713
2026-08-14 20:35:11 +00:00
Charlie Marsh a0bed4be21 Keep the composer editable during TUI startup (#38642)
## Why

Configuration and app-server initialization can take time before the main TUI is ready, leaving users unable to begin drafting a prompt.

## What changed

- Show a provisional composer while startup work runs and carry its text, cursor position, paste state, and attachments into the initialized chat.
- Limit the provisional composer to safe editing and cancellation, and quarantine input around session pickers, approvals, and other actionable startup screens.
- Preserve configuration validation before terminal checks and recover terminal state cleanly from startup failures and caught panics.

## Testing

- Cover startup editing, multiline and large pastes, keymaps, cancellation, session-picker handoff, approval boundaries, and draft restoration.
- Verify non-interactive launches report configuration errors before terminal errors.

GitOrigin-RevId: fe04a85cfbbcff21ff87fa81fd17474827858575
2026-08-14 20:30:30 +00:00
Charlie Marsh 58d2daba45 Harden TUI startup input handling (#38641)
## Why

Terminal probes and other bootstrap work can leave keys or partial control
sequences buffered before an interactive startup screen is visible. Those
inputs must not accidentally select or confirm an action, while typeahead
intended for the composer should survive terminal initialization.

## What changed

- Replay user input consumed by Unix startup probes through Crossterm while
  filtering completed terminal color replies, and avoid consuming the Windows
  console input queue when detecting default colors.
- Drain decoded and unread input after rendering actionable startup screens,
  including onboarding trust, migration, update, provider, resume, and hooks
  prompts. Keep incomplete control sequences quarantined and fail closed when
  an input boundary cannot be resolved.
- Restore terminal modes if initialization exits early and bound terminal probe
  reads by time and byte limits.

## Testing

Add parser, boundary, onboarding, and PTY coverage for preserved typeahead,
split escape sequences, bracketed paste, delayed input, and fresh input after
an interactive screen becomes ready.

GitOrigin-RevId: 321198996cdd88fe9b43c4a762e750bff450482c
2026-08-14 20:23:49 +00:00