Repository navigation
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: agentclientprotocol/codex-acp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.2.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: agentclientprotocol/codex-acp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.2.1
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 2 commits
- 10 files changed
- 3 contributors
Commits on Oct 10, 2026
-
fix: resume a session without messages after an app-server restart (#604
) ## Problem A provider restart (`providers/set`, `providers/disable`) failed as a whole with "Internal error" when an open session had no messages yet. The provider change itself was applied, and every other session was resumed. Codex writes a thread to disk only with its first message. A session that never got one has no rollout, so `thread/resume` in the new app-server fails with "no rollout found for thread id …". The old app-server is gone, so `thread/read` fails too. The adapter collected that failure into an `AggregateError` and failed the provider request. This is the deterministic failure of the e2e test "does not run an untrusted hook, runs it after consent, and restores startup hooks after restart" (`e2e/hooks.test.ts`). The test is red on main's E2E workflow since #588. It failed the `verify` job of the 2.2.0 release, so **`v2.2.0` stays a tag and GitHub release that never reached npm**; this PR's release, 2.2.1, is the first published one after 2.1.1. ## Fix - The loss of such a session is now a typed `UnpersistedSessionLostError`, raised where the resume fails with a missing rollout (`AppServerRecovery.resumeError`). - The provider update completes, the same way it already does for a session that is refused or was replaced meanwhile. - The session reports the loss on its next use with the existing message: "had no messages yet and was lost when the Codex app-server restarted. Start a new session." Crash recovery already behaved this way. - Other resume failures still fail the provider update. ### Why the session is not recreated under the same id Codex can't bring back an unpersisted thread under its id: - `thread/start` takes no id. - `thread/resume` with `history` rejects an empty history, and a non-empty one would invent history. A new Codex thread behind the same ACP session id would only last as long as this agent process: ACP clients store the session id and `session/load` it later, and that id would then name no Codex thread. With `sessionIndex`, the conversation would also be listed under the new thread id. The session had no messages, so nothing is lost by starting a new one. ## The hooks e2e test With the restart fixed, the test still failed at its last step. It waited for the marker of a SessionStart hook after a `session/new` without a prompt. Codex 0.160.1 runs SessionStart hooks when the first turn of a thread starts, not on `thread/start`: checked against a real app-server, the marker appears only after `turn/start`. The test's check that an untrusted hook does not run also passed without running anything. The test now: 1. prompts an untrusted session and checks that no marker appears; 2. keeps a session without messages across the provider restart, and checks that its next prompt reports the loss; 3. prompts a session started after the trust, and checks that the marker appears. ## Not changed The e2e "applies an approved workspace file edit" also failed in that `verify` run, and there is no adapter cause. In the failing attempts the model ran `apply_patch` through a shell command (`bash -c 'apply_patch …'`). Codex asks for that as a command approval, which the test's responder cancels by design: it allows only edits and asserts zero execute requests. When the model uses the `apply_patch` tool, it gets a file-change approval and the test passes. The same test failed on main before (`ca1d971`). ## Test plan - [x] New unit test: a provider update with one session without messages and one persisted session completes. The persisted session runs a turn, and the empty one reports the loss on its next prompt. The test fails without the fix. - [x] `npm run typecheck`, `npm test` (1484 passed), `npm run bundle:all` - [x] `RUN_E2E_TESTS=true` `e2e/hooks.test.ts` locally (the live-key test needs the CI secret) - [x] E2E workflow on this branch (run 38012958734): 33 passed, including the live-key hooks test and "applies an approved workspace file edit" 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 9ac3254 - Browse repository at this point
Copy the full SHA 9ac3254View commit details -
chore(main): release 2.2.1 (#605)
🤖 I have created a release *beep* *boop* --- ## [2.2.1](v2.2.0...v2.2.1) (2026-10-10) ### Bug Fixes * resume a session without messages after an app-server restart ([#604](#604)) ([9ac3254](9ac3254)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: acp-release-bot[bot] <246668977+acp-release-bot[bot]@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for a2e74a4 - Browse repository at this point
Copy the full SHA a2e74a4View commit details
Loading
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v2.2.0...v2.2.1