Commit Graph

6377 Commits

Author SHA1 Message Date
Michael Bolin
72ea59f913 Merge f4af072751 into sapling-pr-archive-bolinfest 2026-01-13 21:59:58 -08:00
Michael Bolin
f4af072751 feat: add conversationId to MCP server messages 2026-01-13 21:59:54 -08:00
Michael Bolin
494119e754 merge commit for archive created by Sapling 2026-01-13 21:58:39 -08:00
Michael Bolin
0499d0cf7a feat: add conversationId to MCP server messages 2026-01-13 21:58:33 -08:00
Michael Bolin
7d5527fa7d merge commit for archive created by Sapling 2026-01-13 21:38:05 -08:00
Michael Bolin
0682e780cd feat: add conversationId to MCP server messages 2026-01-13 21:37:50 -08:00
Michael Bolin
903aee676f merge commit for archive created by Sapling 2026-01-13 21:19:41 -08:00
Michael Bolin
80aabc4232 feat: add conversationId to MCP server messages 2026-01-13 21:19:09 -08:00
Michael Bolin
f0992273e4 merge commit for archive created by Sapling 2026-01-13 21:13:34 -08:00
Michael Bolin
697e3a5ff5 feat: add conversationId to MCP server messages 2026-01-13 21:13:27 -08:00
Michael Bolin
3e682cc4eb Merge 6b5ba1fd92 into sapling-pr-archive-bolinfest 2026-01-13 21:12:15 -08:00
Michael Bolin
6b5ba1fd92 feat: add conversationId to MCP server messages 2026-01-13 21:10:08 -08:00
Eric Traut
31d9b6f4d2 Improve handling of config and rules errors for app server clients (#9182)
When an invalid config.toml key or value is detected, the CLI currently
just quits. This leaves the VSCE in a dead state.

This PR changes the behavior to not quit and bubble up the config error
to users to make it actionable. It also surfaces errors related to
"rules" parsing.

This allows us to surface these errors to users in the VSCE, like this:

<img width="342" height="129" alt="Screenshot 2026-01-13 at 4 29 22 PM"
src="https://github.com/user-attachments/assets/a79ffbe7-7604-400c-a304-c5165b6eebc4"
/>

<img width="346" height="244" alt="Screenshot 2026-01-13 at 4 45 06 PM"
src="https://github.com/user-attachments/assets/de874f7c-16a2-4a95-8c6d-15f10482e67b"
/>
2026-01-13 17:57:09 -08:00
Ahmed Ibrahim
5a82a72d93 Use offline cache for tui migrations (#9186) 2026-01-13 17:44:12 -08:00
Josh McKinney
ce49e92848 fix(tui): harden paste-burst state transitions (#9124)
User-facing symptom: On terminals that deliver pastes as rapid
KeyCode::Char/Enter streams (notably Windows), paste-burst transient
state
can leak into the next input. Users can see Enter insert a newline when
they meant to submit, or see characters appear late / handled through
the
wrong path.

System problem: PasteBurst is time-based. Clearing only the
classification window (e.g. via clear_window_after_non_char()) can erase
last_plain_char_time without emitting buffered text. If a buffer is
still
non-empty after that, flush_if_due() no longer has a timeout clock to
flush against, so the buffer can get "stuck" until another plain char
arrives.

This was surfaced while adding deterministic regression tests for
paste-burst behavior.

Fix: when disabling burst detection, defuse any in-flight burst state:
flush held/buffered text through handle_paste() (so it follows normal
paste integration), then clear timing and Enter suppression.

Document the rationale inline and update docs/tui-chat-composer.md so
"disable_paste_burst" matches the actual behavior.
2026-01-14 01:42:21 +00:00
Michael Bolin
9e54867c79 Merge b99319787f into sapling-pr-archive-bolinfest 2026-01-13 17:25:06 -08:00
Michael Bolin
b99319787f fix: prefer PathBuf to String for ParsePolicy::path field 2026-01-13 17:25:01 -08:00
Ahmed Ibrahim
4d787a2cc2 Renew cache ttl on etag match (#9174)
so we don't do unnecessary fetches
2026-01-14 01:21:41 +00:00
Ahmed Ibrahim
c96c26cf5b [CODEX-4427] improve parsed commands (#8933)
**make command summaries more accurate by distinguishing
list/search/read operations across common CLI tools.**
- Added parsing helpers to centralize operand/flag handling (cd_target,
sed_read_path, first_non_flag_operand, single_non_flag_operand,
parse_grep_like, awk_data_file_operand, python_walks_files,
is_python_command) and reused them in summarize_main_tokens/shell
parsing.
- Newly parsed list-files commands: git ls-files, rg --files (incl.
rga/ripgrep-all), eza/exa, tree, du, python -c file-walks, plus fd/find
map to ListFiles when no query.
- Newly parsed search commands: git grep, grep/egrep/fgrep, ag/ack/pt,
rg/rga files-with-matches flags (-l/-L, --files-with-matches,
--files-without-match), with improved flag skipping to avoid
misclassifying args as paths.
- Newly parsed read commands: bat/batcat, less, more, awk <file>, and
more flexible sed -n range + file detection.
- refine “small formatting command” detection for awk/sed, handle cd
with -- or multiple operands, keep pipeline summaries focused on primary
command.
2026-01-13 16:59:33 -08:00
Ahmed Ibrahim
7e33ac7eb6 clean models manager (#9168)
Have only the following Methods:
- `list_models`: getting current available models
- `try_list_models`: sync version no refresh for tui use
- `get_default_model`: get the default model (should be tightened to
core and received on session configuration)
- `get_model_info`: get `ModelInfo` for a specific model (should be
tightened to core but used in tests)
- `refresh_if_new_etag`: trigger refresh on different etags

Also move the cache to its own struct
2026-01-13 16:55:33 -08:00
github-actions[bot]
ebbbee70c6 Update models.json (#9136)
Automated update of models.json.

Co-authored-by: aibrahim-oai <219906144+aibrahim-oai@users.noreply.github.com>
2026-01-13 16:46:24 -08:00
pakrym-oai
5a70b1568f WebSocket test server script (#9175)
Very simple test server to test Responses API WebSocket transport
integration.
2026-01-13 16:21:14 -08:00
Michael Bolin
903a0c0933 feat: add bazel-codex entry to justfile (#9177)
This is less straightforward than I realized, so created an entry for
this in our `justfile`.

Verified that running `just bazel-codex` from anywhere in the repo uses
the user's `$PWD` as the one to run Codex.

While here, updated the `MODULE.bazel.lock`, though it looks like I need
to add a CI job that runs `bazel mod deps --lockfile_mode=error` or
something.
2026-01-13 16:16:22 -08:00
Michael Bolin
ec5f89ecf8 merge commit for archive created by Sapling 2026-01-13 16:11:07 -08:00
Michael Bolin
2cf5621f15 feat: add bazel-codex entry to justfile 2026-01-13 16:11:01 -08:00
Michael Bolin
5cf1b2adc9 merge commit for archive created by Sapling 2026-01-13 16:10:11 -08:00
Michael Bolin
17a7ac0449 feat: add bazel-codex entry to justfile 2026-01-13 16:10:02 -08:00
Michael Bolin
376186be98 Merge 7a2f62edb8 into sapling-pr-archive-bolinfest 2026-01-13 15:53:33 -08:00
Michael Bolin
7a2f62edb8 feat: add bazel-codex entry to justfile 2026-01-13 15:53:26 -08:00
Michael Bolin
4c673086bc fix: integration test for #9011 (#9166)
Adds an integration test for the new behavior introduced in
https://github.com/openai/codex/pull/9011. The work to create the test
setup was substantial enough that I thought it merited a separate PR.

This integration test spawns `codex` in TUI mode, which requires
spawning a PTY to run successfully, so I had to introduce quite a bit of
scaffolding in `run_codex_cli()`. I was surprised to discover that we
have not done this in our codebase before, so perhaps this should get
moved to a common location so it can be reused.

The test itself verifies that a malformed `rules` in `$CODEX_HOME`
prints a human-readable error message and exits nonzero.
2026-01-13 23:39:34 +00:00
Michael Bolin
64a640b785 Merge 904c88da7b into sapling-pr-archive-bolinfest 2026-01-13 15:33:12 -08:00
Michael Bolin
904c88da7b fix: Prefer raw strings (r#) where appropriate, particularly in tests.
Updated AGENTS.md to memorialize this practice.
2026-01-13 15:32:35 -08:00
Michael Bolin
ea6e0c4335 merge commit for archive created by Sapling 2026-01-13 15:23:19 -08:00
Michael Bolin
34be9ecca6 fix: integration test for #9011 2026-01-13 15:22:29 -08:00
Michael Bolin
2cd1a0a45e fix: report an appropriate error in the TUI for malformed rules (#9011)
The underlying issue is that when we encountered an error starting a
conversation (any sort of error, though making `$CODEX_HOME/rules` a
file rather than folder was the example in #8803), then we were writing
the message to stderr, but this could be printed over by our UI
framework so the user would not see it. In general, we disallow the use
of `eprintln!()` in this part of the code for exactly this reason,
though this was suppressed by an `#[allow(clippy::print_stderr)]`.

This attempts to clean things up by changing `handle_event()` and
`handle_tui_event()` to return a `Result<AppRunControl>` instead of a
`Result<bool>`, which is a new type introduced in this PR (and depends
on `ExitReason`, also a new type):

```rust
#[derive(Debug)]
pub(crate) enum AppRunControl {
    Continue,
    Exit(ExitReason),
}

#[derive(Debug, Clone)]
pub enum ExitReason {
    UserRequested,
    Fatal(String),
}
```

This makes it possible to exit the primary control flow of the TUI with
richer information. This PR adds `ExitReason` to the existing
`AppExitInfo` struct and updates `handle_app_exit()` to print the error
and exit code `1` in the event of `ExitReason::Fatal`.

I tried to create an integration test for this, but it was a bit
involved, so I published it as a separate PR:
https://github.com/openai/codex/pull/9166. For this PR, please have
faith in my manual testing!

Fixes https://github.com/openai/codex/issues/8803.




---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/9011).
* #9166
* __->__ #9011
2026-01-13 23:21:32 +00:00
pakrym-oai
9f8d3c14ce Fix flakiness in WebSocket tests (#9169)
The connection was being added to the list after the WebSocket response
was sent.

So the test can sometimes race and observe connections before the list
was updated.

After this change, connection and request is added to the list before
the response is sent.
2026-01-13 15:09:59 -08:00
xl-openai
89403c5e11 Allow close skill popup with esc. (#9165)
<img width="398" height="133" alt="image"
src="https://github.com/user-attachments/assets/3084e793-ce5b-4f92-ad60-4c73e65c21c5"
/>
<img width="242" height="86" alt="image"
src="https://github.com/user-attachments/assets/57dd5587-0aea-4a55-91b8-273702939cb2"
/>

You can now esc to quit the skill popup and submit the input as it is.
2026-01-13 15:02:44 -08:00
Michael Bolin
53e09ac55a merge commit for archive created by Sapling 2026-01-13 14:41:56 -08:00
Michael Bolin
b95623e031 fix: integration test for #9011 2026-01-13 14:41:31 -08:00
Michael Bolin
de88da3dd3 fix: report an appropriate error in the TUI for malformed rules 2026-01-13 14:41:02 -08:00
Michael Bolin
48f601bbec Merge 67ca792915 into sapling-pr-archive-bolinfest 2026-01-13 14:22:49 -08:00
Michael Bolin
67ca792915 fix: integration test for #9011 2026-01-13 14:22:42 -08:00
Michael Bolin
7736609e73 Merge e6d8dff7b2 into sapling-pr-archive-bolinfest 2026-01-13 14:14:12 -08:00
Michael Bolin
e6d8dff7b2 fix: integration test for #9011 2026-01-13 14:14:06 -08:00
Michael Bolin
8da1072ccc Merge dd01533396 into sapling-pr-archive-bolinfest 2026-01-13 13:59:20 -08:00
Michael Bolin
dd01533396 fix: integration test for #9011 2026-01-13 13:59:06 -08:00
Marius Wichtner
3c711f3d16 Fix spinner/Esc interrupt when MCP startup completes mid-turn (#8661)
## **Problem**

Codex’s TUI uses a single “task running” indicator (spinner + Esc interrupt hint)
to communicate “the UI is busy”. In practice, “busy” can mean two different
things: an agent turn is running, or MCP servers are still starting up. Without a
clear contract, those lifecycles can interfere: startup completion can clear the
spinner while a turn is still in progress, or the UI can appear idle while MCP is
still booting. This is user-visible confusion during the most important moments
(startup and the first turn), so it was worth making the contract explicit and
guarding it.

## **Mental model**

`ChatWidget` is the UI-side adapter for the `codex_core::protocol` event stream.
It receives `EventMsg` events and updates two major UI surfaces: the transcript
(history/streaming cells) and the bottom pane (composer + status indicator).

The key concept after this change is that the bottom pane’s “task running”
indicator is treated as **derived UI-busy state**, not “agent is running”. It is
considered active while either:
- an agent turn is in progress (`TurnStarted` → completion/abort), or
- MCP startup is in progress (`McpStartupUpdate` → `McpStartupComplete`).

Those lifecycles are tracked independently, and the bottom-pane indicator is
defined as their union.

## **Non-goals**

- This does not introduce separate UI indicators for “turn busy” vs “MCP busy”.
- This does not change MCP startup behavior, ordering guarantees, or core
  protocol semantics.
- This does not rework unrelated status/header rendering or transcript layout.

## **Tradeoffs**

- The “one flag represents multiple lifecycles” approach remains lossy: it
  preserves correct “busy vs idle” semantics but cannot express *which* kind of
  busy is happening without further UI changes.
- The design keeps complexity low by keeping a single derived boolean, rather
  than adding a more expressive bottom-pane state machine. That’s chosen because
  it matches existing UX and minimizes churn while fixing the confusion.

## **Architecture**

- `codex-core` owns the actual lifecycles and emits `codex_core::protocol`
  events.
- `ChatWidget` owns the UI interpretation of those lifecycles. It is responsible
  for keeping the bottom pane’s derived “busy” state consistent with the event
  stream, and for updating the status header when MCP progress updates arrive.
- The bottom pane remains a dumb renderer of the single “task running” flag; it
  does not learn about MCP or agent turns directly.

## **Observability**

- When working: the spinner/Esc hint stays visible during MCP startup and does
  not disappear mid-turn when `McpStartupComplete` arrives; startup status
  headers can update without clearing “busy” for an active turn.
- When broken: you’ll see the spinner/hint flicker off while output is still
  streaming, or the UI appears idle while MCP startup status is still changing.

## **Tests**

- Adds/strengthens a regression test that asserts MCP startup completion does
  not clear the “task running” indicator for an active turn (in both `tui` and
  `tui2` variants).
- These tests prove the **contract** (“busy is the union of turn + startup”) at
  the UI boundary; they do not attempt to validate MCP startup ordering,
  real-world startup timing, or backend integration behavior.

Fixes #7017

Signed-off-by: 2mawi2 <2mawi2@users.noreply.github.com>
Co-authored-by: 2mawi2 <2mawi2@users.noreply.github.com>
Co-authored-by: Josh McKinney <joshka@openai.com>
2026-01-13 13:56:09 -08:00
Josh McKinney
141d2b5022 test(tui): add deterministic paste-burst tests (#9121)
Replace the old timing-dependent non-ASCII paste test with deterministic
coverage by forcing an active `PasteBurst` and asserting the exact flush
payload.

Add focused unit tests for `PasteBurst` transitions, and add short
"Behavior:" rustdoc notes on chat composer tests to make the state
machine contracts explicit.
2026-01-13 21:55:44 +00:00
Dylan Hurd
ebacd28817 fix(windows-sandbox-rs) bump SETUP_VERSION (#9134)
## Summary
Bumps the windows setup version, to re-trigger windows sandbox setup for
users in the experimental sandbox. We've seen some drift in the ACL
controls, amongst a few other changes. Hopefully this should fix #9062.

## Testing
- [x] Tested locally
2026-01-13 13:47:29 -08:00
Michael Bolin
47805552a1 merge commit for archive created by Sapling 2026-01-13 13:29:35 -08:00