Commit Graph
5126 Commits
Author SHA1 Message Date
Felipe Coury 107af5e583 fix(tui): make streaming width deterministic before first render 2026-04-06 13:36:23 -03:00
Felipe Coury 4c9b69b75d fix(tui): guard tick_batch zero drain and remove needless async tests
- tick_batch(0) now returns empty instead of silently draining one line
- has_live_tail avoids Vec allocation via field comparison
- Convert 15 sync-only controller tests from tokio::test to #[test]
2026-04-06 13:35:50 -03:00
Felipe Coury 2fd2259286 fix(tui): streaming remap and resize 2026-04-06 13:35:05 -03:00
Felipe Coury 4afa1d0a77 test(tui): unit tests for column-metrics and spillover detection
Address reviewer concerns about self-referential test coverage:

- Column-metrics: 6 tests for TableColumnKind classification,
  preferred_column_floor caps, and next_column_to_shrink priority.
- Spillover detection: 6 tests for is_spillover_row covering each
  heuristic branch and negative cases.
2026-04-06 13:33:32 -03:00
Felipe Coury e64f777765 fix(tui): streamed table resize corruption and history reflow robustness 2026-04-06 13:33:31 -03:00
Felipe Coury edc5008dd0 tui: fix interrupt behavior during heavy streaming 2026-04-06 13:31:52 -03:00
Felipe Coury e7381d57ba tui: add incremental table holdback scanner and timing probes 2026-04-06 13:26:29 -03:00
Felipe Coury 282ff99bf5 tui: reduce table streaming cost with prefix-cache fast paths 2026-04-06 13:26:29 -03:00
Felipe Coury f1ee30daa3 tui: use source-mapped boundaries for stream resize remap 2026-04-06 13:26:28 -03:00
Felipe Coury 3c9f8d1eaf tui: tighten table holdback boundaries and add streaming coverage 2026-04-06 13:22:52 -03:00
Felipe Coury 27ed715de7 fix(tui): wrap fallback tables and clamp narrow stream widths 2026-04-06 13:21:54 -03:00
Felipe Coury 31bd54d7a2 fix(tui): narrow pending holdback and honor blockquote fences 2026-04-06 13:20:54 -03:00
Felipe Coury b0fe9b742d fix(tui): keep commit animation alive for active plan stream 2026-04-06 13:20:54 -03:00
Felipe Coury 75f05c8bda fix(tui): tighten fence indent and sparse spillover detection 2026-04-06 13:19:49 -03:00
Felipe Coury de9c17d1e2 docs(tui): documentation pass over table rendering pipeline
Add module-level, type-level, and function-level documentation across
the table rendering pipeline: table_detect, width, markdown,
markdown_render, and streaming/controller. Separate spillover lines
from table grid output via RenderedTableLines so spillover prose
routes through normal word wrapping instead of bypassing it.
2026-04-06 13:19:49 -03:00
Felipe Coury 0830073146 fix(tui): track resize reflow across stream consolidation 2026-04-06 13:19:21 -03:00
Felipe Coury f6ef212f76 fix(tui): detect single-column tables and narrow spillover 2026-04-06 13:17:53 -03:00
Felipe Coury 2d6cb4ed1a fix(tui): clear transient tails and spill trailing label lines 2026-04-06 13:17:53 -03:00
Felipe Coury ed087e1fa4 fix(tui): avoid committing transient stream tail cells 2026-04-06 13:16:56 -03:00
Felipe Coury d9035a61b0 docs(tui): clarify markdown table streaming contracts 2026-04-06 13:16:13 -03:00
Felipe Coury 38664bc2fb fix(tui): keep link suffixes inside table cells 2026-04-06 13:15:21 -03:00
Felipe Coury 7b7f233e36 fix(tui): escape pipes in table fallback rows 2026-04-06 13:14:40 -03:00
Felipe Coury be9006c161 fix(tui): centralize usable-width guards for narrow layouts 2026-04-06 13:14:40 -03:00
Felipe Coury 8a94c65989 fix(tui): tighten spillover and fence-close table parsing 2026-04-06 13:13:05 -03:00
Felipe Coury 14d66912f3 docs(tui): documentation pass over table rendering pipeline
Add module, type, and function-level doc comments across the table
rendering change. Fix typos ("taht", "mirros", "stabe", "durin").
Expand streaming controller module docs to cover holdback and resize
handling. Document width allocation, spillover detection, consolidation,
and prewrapped line rendering contracts. No runtime behavior changes
in documentation edits; also includes extracted draw helpers in app.rs
and a fence-detection fix in markdown.rs.
2026-04-06 13:13:04 -03:00
Felipe Coury 004e85e09e feat(tui): integrate table rendering into streaming pipeline with reflow
Wire the Unicode box-drawing table renderer into the live streaming
path with holdback-aware commit logic, post-stream cell consolidation,
and debounced resize reflow.

Key additions:
- StreamCore: shared bookkeeping deduplicating Stream/PlanStreamController
- Table holdback: fence-aware state machine keeps buffer mutable during table detection
- AgentMarkdownCell: stores raw markdown source, re-renders at any width on demand
- ConsolidateAgentMessage: backward-walk replaces streamed cells with single consolidated cell
- Resize reflow: debounced (75ms) re-render of all transcript cells after terminal resize
2026-04-06 13:12:29 -03:00
Felipe Coury ff310bb9e0 feat(tui): render markdown tables with Unicode box-drawing borders
Add proper table rendering to the markdown renderer using Unicode
box-drawing characters (┌─┬┐│├─┼┤└─┴┘) instead of raw pipe syntax.
Supports column alignment, cell wrapping at narrow widths, tables
inside blockquotes, escaped pipes, and styled inline content.
2026-04-06 13:04:55 -03:00
Eric Traut 54dbbb839e (tui): Decode percent-escaped bare local file links (#16810)
Addresses #16622

Problem: bare local file links in TUI markdown render percent-encoded
path bytes literally, unlike file:// links.

Solution: decode bare path targets before local-path expansion and add
regression coverage for spaces and Unicode.
2026-04-06 08:52:18 -07:00
Eric Traut f44eb29181 Annotate skill doc reads with skill names (#16813)
Addresses #16303

Problem: Skill doc reads render as plain `Read SKILL.md`, so the TUI
hides which skill was opened.

Solution: Best-effort annotate exact `SKILL.md` reads with the matching
loaded skill name from `skills_all` before rendering exec cells.

Before:
```
• Explored
  └ Read SKILL.md
```

After:
```
• Explored
  └ Read SKILL.md (pr-babysitter skill)
```
2026-04-06 08:51:34 -07:00
Eric Traut 4294031a93 Fix resume picker timestamp labels and stability (#16822)
Problem: The resume picker used awkward "Created at" and "Updated at"
headers, and its relative timestamps changed while navigating because
they were recomputed on each redraw.

Solution: Rename the headers to "Created" and "Updated", and anchor
relative timestamp formatting to the picker load time so the displayed
ages stay stable while browsing.
2026-04-06 08:51:13 -07:00
Eric Traut fb41a79f37 [regression] Fix ephemeral turn backfill in exec (#16795)
Addresses #16781

Problem: `codex exec --ephemeral` backfilled empty `turn/completed`
items with `thread/read(includeTurns=true)`, which app-server rejects
for ephemeral threads.

This is a regression introduced in the recent conversion of "exec" to
use app server rather than call the core directly.

Solution: Skip turn-item backfill for ephemeral exec threads while
preserving the existing recovery path for non-ephemeral sessions.
2026-04-06 08:45:58 -07:00
Eric Traut ab58141e22 Fix TUI fast mode toggle regression (#16833)
Addresses #16832

Problem: After `/fast on`, the TUI omitted an explicit service-tier
clear on later turns, so `/fast off` left app-server sessions stuck on
`priority` until restart.

Solution: Always submit the current service tier with user turns,
including an explicit clear when Fast mode is off, and add a regression
test for the `/fast on` -> `/fast off` flow.
2026-04-06 08:43:35 -07:00
Eric Traut 82b061afb2 Fix CJK word navigation in the TUI composer (#16829)
Addresses #16584

Problem: TUI word-wise cursor movement treated entire CJK runs as a
single word, so Option/Alt+Left and Right skipped too far when editing
East Asian text.

Solution: Use Unicode word-boundary segments within each non-whitespace
run so CJK text advances one segment at a time while preserving
separator and delete-word behavior, and add regression coverage for CJK
and mixed-script navigation.

Testing: Manually tested solution by pasting text that includes CJK
characters into the composer and confirmed that keyboard navigation
worked correctly (after confirming it didn't prior to the change).
2026-04-06 08:37:42 -07:00
Thibault Sottiaux 624c69e840 [codex] add response proxy subagent header test (#16876)
This adds end-to-end coverage for `responses-api-proxy` request dumps
when Codex spawns a subagent and validates that the `x-codex-window-id`
and `x-openai-subagent` are properly set.
2026-04-06 08:18:46 -07:00
Eric Traut e65ee38579 Clarify codex exec approval help (#16888)
Addresses #13614

Problem: `codex exec --help` implied that `--full-auto` also changed
exec approval mode, even though non-interactive exec stays headless and
does not support interactive approval prompts.

Solution: clarify the `--full-auto` help text so it only describes the
sandbox behavior it actually enables for `codex exec`.
2026-04-05 23:31:15 -07:00
Eric Traut d9b899309d Fix misleading codex exec help usage (#16881)
Addresses #15535

Problem: `codex exec --help` advertised a second positional `[COMMAND]`
even though `exec` only accepts a prompt or a subcommand.

Solution: Override the `exec` usage string so the help output shows the
two supported invocation forms instead of the phantom positional.
2026-04-05 22:09:19 -07:00
Eric Traut b5edeb98a0 Fix flaky permissions escalation test on Windows (#16825)
Problem: `rejects_escalated_permissions_when_policy_not_on_request`
retried a real shell command after asserting the escalation rejection,
so Windows CI could fail on command startup timing instead of approval
behavior.

Solution: Keep the rejection assertion, verify no turn permissions were
granted, and assert through exec-policy evaluation that the same command
would be allowed without escalation instead of timing a subprocess.
2026-04-05 10:51:01 -07:00
Eric Traut 152b676597 Fix flaky test relating to metadata remote URL (#16823)
This test was flaking on Windows.

Problem: The Windows CI test for turn metadata compared git remote URLs
byte-for-byte even though equivalent remotes can be formatted
differently across Git code paths.

Solution: Normalize the expected and actual origin URLs in the test by
trimming whitespace, removing a trailing slash, and stripping a trailing
.git suffix before comparing.
2026-04-05 10:50:29 -07:00
4fd5c35c4f [codex-analytics] subagent analytics (#15915)
- creates custom event that emits subagent thread analytics from core
- wires client metadata (`product_client_id, client_name,
client_version`), through from app-server
- creates `created_at `timestamp in core
- subagent analytics are behind `FeatureFlag::GeneralAnalytics`

PR stack
- [[telemetry] thread events
#15690](https://github.com/openai/codex/pull/15690)
- --> [[telemetry] subagent events
#15915](https://github.com/openai/codex/pull/15915)
- [[telemetry] turn events
#15591](https://github.com/openai/codex/pull/15591)
- [[telemetry] steer events
#15697](https://github.com/openai/codex/pull/15697)
- [[telemetry] queued prompt data
#15804](https://github.com/openai/codex/pull/15804)

Notes:
- core does not spawn a subagent thread for compact, but represented in
mapping for consistency

`INFO | 2026-04-01 13:08:12 | codex_backend.routers.analytics_events |
analytics_events.track_analytics_events:399 | Tracked
codex_thread_initialized event params={'thread_id':
'019d4aa9-233b-70f2-a958-c3dbae1e30fa', 'product_surface': 'codex',
'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name':
'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process',
'experimental_api_enabled': None}, 'runtime': {'codex_rs_version':
'0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0',
'runtime_arch': 'aarch64'}, 'model': 'gpt-5.3-codex', 'ephemeral':
False, 'initialization_mode': 'new', 'created_at': 1775074091,
'thread_source': 'subagent', 'subagent_source': 'thread_spawn',
'parent_thread_id': '019d4aa8-51ec-77e3-bafb-2c1b8e29e385'} | `

`INFO | 2026-04-01 13:08:41 | codex_backend.routers.analytics_events |
analytics_events.track_analytics_events:399 | Tracked
codex_thread_initialized event params={'thread_id':
'019d4aa9-94e3-75f1-8864-ff8ad0e55e1e', 'product_surface': 'codex',
'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name':
'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process',
'experimental_api_enabled': None}, 'runtime': {'codex_rs_version':
'0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0',
'runtime_arch': 'aarch64'}, 'model': 'gpt-5.3-codex', 'ephemeral':
False, 'initialization_mode': 'new', 'created_at': 1775074120,
'thread_source': 'subagent', 'subagent_source': 'review',
'parent_thread_id': None} | `

---------

Co-authored-by: jif-oai <jif@openai.com>
Co-authored-by: Michael Bolin <mbolin@openai.com>
2026-04-04 11:06:43 -07:00
Andrey Mishchenko cca36c5681 Add CODEX_SKIP_VENDORED_BWRAP (#16763)
For building on Linux without bubblewrap.
2026-04-03 20:24:49 -10:00
Thibault Sottiaux 9e19004bc2 [codex] add context-window lineage headers (#16758)
This change adds client-owned context-window and parent thread id
headers to all requests to responses api.
2026-04-04 05:54:31 +00:00
Michael Bolin 39097ab65d ci: align Bazel repo cache and Windows clippy target handling (#16740)
## Why

Bazel CI had two independent Windows issues:

- The workflow saved/restored `~/.cache/bazel-repo-cache`, but
`.bazelrc` configured `common:ci-windows
--repository_cache=D:/a/.cache/bazel-repo-cache`, so `actions/cache` and
Bazel could point at different directories.
- The Windows `Bazel clippy` job passed the full explicit target list
from `//codex-rs/...`, but some of those explicit targets are
intentionally incompatible with `//:local_windows`.
`run-argument-comment-lint-bazel.sh` already handles that with
`--skip_incompatible_explicit_targets`; the clippy workflow path did
not.

I also tried switching the workflow cache path to
`D:\a\.cache\bazel-repo-cache`, but the Windows clippy job repeatedly
failed with `Failed to restore: Cache service responded with 400`, so
the final change standardizes on `$HOME/.cache/bazel-repo-cache` and
makes cache restore non-fatal.

## What Changed

- Expose one repository-cache path from
`.github/actions/setup-bazel-ci/action.yml` and export that path as
`BAZEL_REPOSITORY_CACHE` so `run-bazel-ci.sh` passes it to Bazel after
`--config=ci-*`.
- Move `actions/cache/restore` out of the composite action into
`.github/workflows/bazel.yml`, and make restore failures non-fatal
there.
- Save exactly the exported cache path in `.github/workflows/bazel.yml`.
- Remove `common:ci-windows
--repository_cache=D:/a/.cache/bazel-repo-cache` from `.bazelrc` so the
Windows CI config no longer disagrees with the workflow cache path.
- Pass `--skip_incompatible_explicit_targets` in the Windows `Bazel
clippy` job so incompatible explicit targets do not fail analysis while
the lint aspect still traverses compatible Rust dependencies.

## Verification

- Parsed `.github/actions/setup-bazel-ci/action.yml` and
`.github/workflows/bazel.yml` with Ruby's YAML loader.
- Resubmitted PR `#16740`; CI is rerunning on the amended commit.
2026-04-03 20:18:33 -07:00
Michael Bolin 3a22e10172 test: avoid PowerShell startup in Windows auth fixture (#16737)
## Why

`provider_auth_command_supplies_bearer_token` and
`provider_auth_command_refreshes_after_401` were still flaky under
Windows Bazel because the generated fixture used `powershell.exe`, whose
startup can be slow enough to trip the provider-auth timeout in CI.

## What

Replace the generated Windows auth fixture script in
`codex-rs/core/tests/suite/client.rs` with a small `.cmd` script
executed by `cmd.exe /D /Q /C`, and advance `tokens.txt` one line at a
time so the refresh-after-401 test still gets the second token on the
second invocation.

Also align the fixture timeout with the provider-auth default (`5_000`
ms) to avoid introducing a test-only timing budget that is stricter than
production behavior.

## Testing

Left to CI, specifically the Windows Bazel
`//codex-rs/core:core-all-test` coverage for the two provider-auth
command tests.
2026-04-03 20:05:39 -07:00
Michael Bolin c9e706f8b6 Back out "bazel: lint rust_test targets in clippy workflow (#16450)" (#16757)
This backs out https://github.com/openai/codex/pull/16450 because it was
not good to go yet.
2026-04-03 20:01:26 -07:00
Ahmed Ibrahim 8a19dbb177 Add spawn context for MultiAgentV2 children (#16746) 2026-04-03 19:56:59 -07:00
Thibault Sottiaux 6edb865cc6 [codex] add responses proxy JSON dumps (#16753)
This makes Responses API proxy request/response dumping first-class by
adding an optional `--dump-dir` flag that emits paired JSON files with
shared sequence/timestamp prefixes, captures full request and response
headers and records parsed JSON bodies.
2026-04-03 16:51:18 -10:00
Ahmed IbrahimandCodex 13d828d236 Use Node 24 for npm publish (#16755)
Avoid self-upgrading the runner's bundled npm in release publishing;
Node 24 already provides an npm CLI that supports trusted publishing.

Co-authored-by: Codex <noreply@openai.com>
2026-04-03 19:26:41 -07:00
Ahmed IbrahimandCodex e4f1b3a65e Preempt mailbox mail after reasoning/commentary items (#16725)
Send pending mailbox mail after completed reasoning or commentary items
so follow-up requests can pick it up mid-turn.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-03 18:29:05 -07:00
Thibault Sottiaux 91ca49e53c [codex] allow disabling environment context injection (#16745)
This adds an `include_environment_context` config/profile flag that
defaults on, and guards both initial injection and later environment
updates to allow skipping injection of `<environment_context>`.
2026-04-03 18:06:52 -07:00
Thibault Sottiaux 8d19646861 [codex] allow disabling prompt instruction blocks (#16735)
This PR adds root and profile config switches to omit the generated
`<permissions instructions>` and `<apps_instructions>` prompt blocks
while keeping both enabled by default, and it gates both the initial
developer-context injection and later permissions diff injection so
turning the permissions block off stays effective across turn-context
overrides.

Also added a prompt debug tool that can be used as `codex debug
prompt-input "hello"` and dumps the constructed items list.
2026-04-03 23:47:56 +00:00