src/— ACP server implementation. Entry point:src/index.ts.src/__tests__/— Vitest suite (behavior-focused tests around ACP/Codex events).src/app-server/— generated Codex app-server API types (regenerate vianpm run generate-types).dist/bin/— release-ready single-file executables and*.ziparchives..github/workflows/ci.yml— CI mirrors the local workflow: typecheck → tests → bundle.scripts/— release tooling (release-preflight.sh,next-preview-version.mjs), kept outsidesrc/so it stays out oftsc'srootDirand the published tarball; its tests sit next to it as*.test.mjs.
- Keep edits consistent with existing formatting.
- When adding env/config knobs, document them in
readme-dev.md. - When updating discriminated-union/event
switchstatements, do not add a trailing fallback likereturn nullonly to satisfy TypeScript. - Handle each variant with an explicit
case; if intentionally ignored, use an explicit no-op case.
- Tests live under
src/__tests__/and use Vitest. - Favor event-driven assertions (see
src/__tests__/CodexACPAgent/*). - Prefer snapshot-based tests using
toMatchFileSnapshot()over inline assertions. - When snapshot response data drifts, prefer replacing that response payload with a stable placeholder over asserting fragile fields (except for 'model/list').
- Focus on behavior and outputs rather than implementation details.
- Use
/run-codexskill (.claude/skills/run-codex/) to test with real Codex and observe actual events.
- Squash merges use the PR title as the commit subject, and release-please parses it to compute the next version. Titles must be conventional commits using one of:
feat,fix,perf,revert,docs,style,chore,refactor,test,build,ci.conventional-prs.ymlrejects anything else. - The title also decides the release:
feat:bumps the minor,fix:/perf:/revert:the patch, a!bumps the major, andchore:/ci:/docs:and friends do not release at all.
- Stable releases are fully automated by release-please. There is no manual release workflow, and the version is never chosen by hand — it follows from the commit history.
npm run release:preflightverifies it is safe to release and prints the PR number and version; thengh pr merge <pr-number> --squash.- The preflight is the guard-list as code; if it exits non-zero, follow what it prints rather than merging.
- Pushes to
maintrigger preview publishing directly, without waiting for CI or release-please. Automatic previews skip commits authored byacp-release-bot[bot]or whose message starts withchore(main): release. - Previews build and publish the exact pushed commit to npm under the
previewdist-tag, then independently tag it asv<version>and dispatch the agent registry update. Onlylatestis reserved for stable releases. Manual previews publish the requested ref;publish_npmapplies only to the stable channel. - Preview publish jobs are serialized without cancelling the running job, but newer pushes can replace a queued preview, so not every commit gets a preview. There is no staging branch.
- Full runbook, including how to recover a stalled release:
docs/RELEASES.md.
- Codex app-server usage: see https://github.com/openai/codex/blob/main/codex-rs/app-server/README.md when touching protocol/transport details, adding or consuming JSON-RPC methods, handling approvals/turn events, or updating generated schema/clients.
- App-server events: prefer
thread/*,turn/*, anditem/*event surfaces; avoid the deprecatedcodex/event/*API (planned removal). Keep implementations aligned with generated types insrc/app-server(includingv2exports).