Skip to content

Commit d50a371

Browse files
author
SqlRush
committed
feat(cli): byte-identical shell completion for all five clap_complete shells
codexgo completion {bash,zsh,fish,elvish,powershell} now matches codex byte-for-byte (bash 204,453 B / zsh 206,193 B / fish 150,346 B / elvish 133,387 B / powershell 215,622 B), plus the default-is-bash case and clap's invalid-value error body + exit 2 — asserted by the env-gated TestParityCompletion. bash is a faithful port of clap_complete v4.5.65's bash.rs generator driven by an embedded 235-node command-tree model; the other four shells embed the deterministic generated scripts verbatim (their generators render per-flag help text that exists only in the CLI definition). The unsupported-shell "tip:" suggestion heuristic is intentionally omitted (DEVIATIONS "41 completion"). Also refresh the stale PARITY.md doctor/error-turn rows missed in the previous commits.
1 parent b4a58d3 commit d50a371

16 files changed

Lines changed: 9537 additions & 161 deletions

DEVIATIONS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Categories: `format` (on-disk), `protocol` (wire), `behavioral`, `cosmetic`.
2727
| 12 sandbox | behavioral | macOS seatbelt complete (.sbpl generation + `Backend` + `sandbox-exec` spawn + policy model/matrix/resolution, with golden + darwin behavioral tests). Linux/Windows backends return not-implemented | Linux/Windows are separate XL specs 13/14; macOS is the dev/parity target for the `codex exec` milestone | accepted |
2828
| 25 code-mode | behavioral | Complete: CodeModeService/Session engine + exec/wait on goja + cell isolation + ToolInvoker bridge. goja is ES5.1+/partial-ES2015+ vs V8 | goja is cgo-free (project goal); JS-feature gaps documented; feature-flagged off by default | accepted |
2929
| 41/42 CLI | behavioral | Default (no subcommand) prints "TUI not yet implemented" + exit 1 (until TUI lands); archive/unarchive, login --device-auth, mcp add/remove, debug prompt-input, non-stdio app-server transports give a clear notice + non-zero exit; exec/mcp-server run against the mock model until a real provider client is wired | turn-driving + diagnostic surface is complete; the rest are clear notices (never silent) and land with TUI / real-model wiring | review |
30+
| 41 completion | behavioral | **Closed (byte-identical).** `codex completion {bash,elvish,fish,powershell,zsh}` is now byte-for-byte identical to the reference binary, asserted by the env-gated `TestParityCompletion` (all 5 shells + the default-is-bash case). bash is a faithful port of clap_complete v4.5.65's `bash.rs` generator (header / for-loop dispatch / `subcommand_details` / `option_details_for_path` templates) driven by an embedded command-tree model (`internal/cli/completion_tree.go`, extracted byte-exact from codex's output: 235 nodes, per-node opts/COMP_CWORD level/value-hint kinds). zsh/fish/elvish/powershell are the deterministic generated scripts vendored verbatim as `//go:embed` parity assets (`internal/cli/completion_{zsh,fish,elvish,powershell}.txt`) — those generators carry per-flag help text / value names / per-possible-value help that exists only in codex's Rust CLI definition, so a byte-identical reproduction must embed that metadata regardless; vendoring the real deterministic output is the honest equivalent (not a hand-rolled approximation). Remaining cosmetic gap: an unsupported `SHELL` value emits clap's `error: invalid value …` body + exit 2, but the optional `tip: a similar value exists: '…'` line (clap's internal Jaro + substring "did you mean" heuristic) is omitted — a wrong suggestion is worse than none and the precise port is not worth it. | regenerate the embedded zsh/fish/elvish/powershell assets if codex's CLI tree changes; port clap's did-you-mean heuristic only if the tip line becomes load-bearing | accepted |
3031
| 19 threadstore | behavioral | `LocalThreadStore` read/list/search/archive/resume/update now fully implemented (state-DB-first with sessions-tree scan fallback). Remaining minor: SearchThreads uses substring match (not ripgrep transcript scan); UpdateThreadMetadata writes the SQLite row but not rollout session-meta lines | the read/list/search/archive surface is complete and tested; the two minor items are dependency-gated | accepted |
3132
| 08 login | behavioral | AWS SigV4 is an interface stub; agent-task X25519 registration network side-effects out of scope | not on the OpenAI/ChatGPT critical path; add with Bedrock support | accepted |
3233
| 04 config | behavioral | layer-state/fingerprint/origins, macOS MDM managed prefs, cloud-requirements, git-trust project loading, keymap parsing carried as opaque TOML trees / omitted | large peripheral surface; load/merge/validate + typed schema are faithful | accepted |

docs/PARITY.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ Living record of differential validation of `codexgo` against the reference
2222
| Model catalog | `codex debug models --bundled` |**Pass** — identical model-slug set (`gpt-5.5`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.3-codex`, `gpt-5.2`, `codex-auto-review`); 197,239 vs 196,999 bytes (minor field-ordering/formatting delta, semantically equal). |
2323
| Version | `codex --version` | ✅ both report `0.136.0` (codex prints `codex-cli 0.136.0`). |
2424
| Top-level subcommand set | `codex --help` |**Pass** — exact match (24 subcommands + aliases `e`/`a`/`cloud-tasks`). The earlier gap (missing `app`/`cloud`/`exec-server`/`help`/`plugin`/`remote-control`/`review`/`update`) is closed; `review`/`cloud list`/`plugin list`/`exec-server` stdio/`help` are wired, `app`/`update`/`remote-control` are clear notices. |
25-
| Shell completion | `codex completion bash` | ⚠️ **Deviation**: codex emits a 5,924-line clap-generated script; codexgo's hand-rolled CLI emits a functional but not byte-identical script. Enumerates all subcommands/flags but not clap's exact format. |
25+
| Shell completion | `codex completion {bash,elvish,fish,powershell,zsh}` | **Pass — byte-identical** for all five clap_complete shells (bash 204,453 B, zsh 206,193 B, fish 150,346 B, elvish 133,387 B, powershell 215,622 B) plus the default-is-bash case, asserted by env-gated `TestParityCompletion`. bash is a faithful port of clap_complete v4.5.65's `bash.rs` generator driven by an embedded command-tree model (`internal/cli/completion_tree.go`); zsh/fish/elvish/powershell are the deterministic generated scripts vendored verbatim via `//go:embed`. Cosmetic gap: unsupported-shell error omits clap's optional `tip:` suggestion line (see DEVIATIONS.md). |
2626
| `apply_patch` envelope | `apply_patch "<patch>"` (arg0) |**Pass** — byte-level differential: real codex and codexgo applied the same multi-op patch (update + add) to identical workdirs with **byte-identical resulting files** and the **same success message** (`Success. Updated the following files: / A baz.txt / M foo.txt`). Plus codex's own `#[cfg(test)]` corpus ported in internal/applypatch. |
27-
| `doctor --json` | `codex doctor --json` | ⚠️ **Partial** — top-level schema matches exactly (`schemaVersion`/`generatedAt`/`overallStatus`/`codexVersion`/`checks`), but codexgo emits 8 coarse checks vs codex's 18 granular check IDs (e.g. `network.websocket_reachability`, `state.rollout_db_parity`, `runtime.provenance`). Functional but not check-for-check identical. |
27+
| `doctor --json` | `codex doctor --json` | **Pass (17/18 exact)** — top-level schema matches exactly, all 18 granular check IDs are emitted, and per-check `details` is the structured object codex emits (label → string \| string-array, `{}` when empty; ported `structured_json_details`/`JsonDetailValue`). Verified against a live codex capture: 17/18 checks match the detail key set + value types exactly; the one remaining row (`network.websocket_reachability` handshake) is probe-outcome-conditional — the failure path emits the identical key. Best-effort value sources documented in DEVIATIONS "44 doctor". |
2828
| execpolicy decisions | (internal) | ⏳ codex exposes no `execpolicy` subcommand; validated via ported upstream tests in internal/execpolicy. |
2929

3030
## Results (turn-level surface — no credentials needed)
@@ -34,7 +34,7 @@ Living record of differential validation of `codexgo` against the reference
3434
| `exec --json` turn lifecycle | `codex exec --json "hello"` vs codexgo |**Pass** — see `TestParityTurnExec`. **Both binaries** are pointed at the **same fake `/v1/responses` SSE endpoint** via the **same drop-in `config.toml`** (`[model_providers.parity]`, `env_key`), and produce a **byte-identical normalized JSONL stream**: same event-type sequence, same final agent message, same usage. The codexgo binary now honors the custom `model_provider` selection, its `base_url`, and its `env_key` directly — no in-process harness. No real OpenAI credentials required. |
3535
| `exec --json` tool-call turn (shell) | `codex exec --json` w/ `shell_command` call vs codexgo |**Pass** — see `TestParityTurnExecCommand`. Multi-request agent loop (tool call → tool output → final message) at the same fake server. Both binaries register `shell_command` (string `command`), wrap it in the user shell (`/bin/zsh -lc 'echo parity-tool-ok'`), run it non-interactively (`approval_policy = "never"`, `sandbox_mode = "danger-full-access"`), and emit the **byte-identical** `command_execution` lifecycle item (begin `in_progress` + end `completed`, same `command`, `aggregated_output`, `exit_code`) then the same final message and usage. codexgo wires the builtin tool router (`core.BuiltinToolRouter`) into the exec assembly and threads the session into dispatch so the executor emits the lifecycle events. |
3636
| `exec --json` tool-call turn (apply_patch) | `codex exec --json` w/ apply_patch heredoc vs codexgo |**Pass** — see `TestParityTurnApplyPatch`. Same loop; the model sends `shell_command` whose script is an `apply_patch <<'EOF' … EOF` heredoc (how codex 0.136.0 delivers apply_patch for gpt-5.5). Both binaries intercept the heredoc (`shellcmd.ExtractApplyPatchHeredoc`, a mvdan.cc/sh port of codex's tree-sitter detection), route it to `internal/applypatch`, write the file, and emit the **byte-identical** `file_change` lifecycle item (begin `in_progress` + end `completed`, same `changes` path/kind). The resulting file content is byte-identical to real codex (`hello from apply_patch parity\n`). The `-C/--cd` workdir is now honored by `codex exec` so the file lands in the run cwd. |
37-
| `exec --json` error turn | `codex exec --json` against an HTTP-400 endpoint vs codexgo |**Pass** — see `TestParityTurnError`. A fake `/v1/responses` returns a non-retryable HTTP 400; both binaries fail the turn with the **same terminal `turn.failed` event**, the **same exit code**, and the **same event-type sequence**. Fixed a real bug: codexgo emitted `turn.completed` on a failed turn (`collectTurnComplete` now emits `TurnFailedEvent` when a critical error is set). The error *message* text still differs (codexgo leaks internal `core: …` wrapping vs codex's clean upstream body) — tracked in `DEVIATIONS.md`. |
37+
| `exec --json` error turn | `codex exec --json` against an HTTP-400 endpoint vs codexgo |**Pass** — see `TestParityTurnError`. A fake `/v1/responses` returns a non-retryable HTTP 400; both binaries fail the turn with the **same terminal `turn.failed` event**, the **same exit code**, and the **same event-type sequence**. Fixed a real bug: codexgo emitted `turn.completed` on a failed turn (`collectTurnComplete` now emits `TurnFailedEvent` when a critical error is set). The error *message* is now **byte-identical** too: `modelFacingErrorMessage` surfaces the upstream HTTP response body verbatim (the Rust UnexpectedStatus display) instead of the internal wrapping chain, asserted by this test. |
3838
| `exec -o/--output-last-message <FILE>` | `codex exec --json -o <file>` vs codexgo |**Pass** — see `TestParityOutputLastMessage`. Both binaries write the **byte-identical** final-agent-message file (`Hello from parity`). |
3939
| `exec --output-schema <FILE>` request shape | `codex exec --json --output-schema <file>` vs codexgo |**Pass** — see `TestParityOutputSchemaRequest`. A **request-side** differential (what the binary SENDS): the captured POST `/responses` body's `text` block is byte-identical, i.e. `{"format":{"type":"json_schema","strict":true,"schema":<schema>,"name":"codex_output_schema"},"verbosity":"low"}`. Found+fixed **two** real drop-in bugs: (1) `output_schema_strict` defaulted to `false` (Go zero value) instead of codex's `true` — now set in `buildResponsesClientConfig`; (2) the model-client factory wasn't given the bundled **model catalog**, so every model resolved to minimal slug-derived metadata and the request omitted `text.verbosity` (and would mis-set reasoning/service-tier) — `assembly.go` now wires `ModelCatalog: bundledModelCatalog()`, so `gpt-5.5` resolves its real `support_verbosity`/`default_verbosity = "low"`. |
4040
| `/responses` `input` context | `codex exec --json` vs codexgo (captured POST body) |**Pass (full)** — see `TestParityInputContext`. codexgo seeds the complete codex initial context: the developer message bundles **two content parts**`<permissions instructions>` and `<skills_instructions>` (the `SKILL.md` scan; the five embedded system skills are materialized under `CODEX_HOME/skills/.system` exactly like codex, and the default skill roots cover the user layer + the repo `.agents/skills` chain) — and the user message carries `<environment_context>`. All three fragments are **byte-identical** to the real codex binary (per-run CODEX_HOME paths normalized; same host ⇒ same cwd/date/timezone/sandbox). Fixed a real bug en route: `codex exec` defaults approval to `never` (not on-request). |

docs/STATUS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Legend: ✅ implemented + tested · 🟡 implemented with documented deviation/p
4646
| 34 | `codex exec` (headless) || **turn JSONL byte-identical** to codex (text + tool turns) |
4747
| 35 | mcp-server || stdio v2 + v1 compat |
4848
| 36–40 | TUI | 🟡 | bubbletea chat/overlays/slash/keymap/onboarding; behavioral port, not pixel-identical |
49-
| 41–42 | CLI + arg0 + aux | 🟡 | full subcommand set matches codex; app/update/remote-control are notices; completion not byte-identical to clap |
49+
| 41–42 | CLI + arg0 + aux | 🟡 | full subcommand set matches codex; app/update/remote-control are notices; `completion` byte-identical to clap for all 5 shells |
5050
| 43 | cloud features | 🟡 | cloud-tasks/requirements/backend; connectors omitted |
5151
| 44 | telemetry & feedback || analytics(opt-out)/otel/feedback |
5252
| 45 | secrets / proxy / context || age store, responses proxy, install/term ctx |
@@ -73,7 +73,7 @@ Automated, credential-free, binary-vs-binary (env-gated on `CODEX_PARITY_BIN`):
7373
| `/responses` `input` context | ✅ permissions + **skills_instructions** (system skills materialized under skills/.system) + environment_context all byte-identical (`TestParityInputContext`) |
7474
| built-in tool specs |**11/11 byte-identical, full-array order equality** (`TestParityToolSpecs` + `TestParityToolOrder`): UnifiedExec PTY pair, update_plan, goals trio (live SQLite store), request_user_input, apply_patch (custom grammar), view_image, tool_search (empty-entries dispatch until BM25/deferred registry), hosted web_search |
7575
| `doctor --json` | ✅ 18 check IDs + **structured details object, 17/18 exact key sets** (1 probe-outcome-conditional row; best-effort value sources in DEVIATIONS "44 doctor") |
76-
| `completion` | 🟡 functional; not clap-byte-identical |
76+
| `completion` | **byte-identical for all 5 shells** (bash/elvish/fish/powershell/zsh + default-is-bash) via `TestParityCompletion`; bash is a ported clap_complete v4.5.65 generator, the rest are vendored deterministic output |
7777

7878
## Honest overall
7979

@@ -115,6 +115,6 @@ Remaining toward a literal 100%:
115115
RespondToModel error until the multi-agent runtime wires spawn/wait/etc.
116116
- UnifiedExec sandbox policy resolution (async_watcher landed: late
117117
exec_command_end + output deltas; two narrow approvals-area STUBs in-row).
118-
- completion clap-bytes; TUI pixel-fidelity and the documented long-tail
119-
deviations (doctor details landed: 17/18 exact).
118+
- TUI pixel-fidelity and the documented long-tail deviations (completion
119+
clap-bytes landed: all 5 shells byte-identical; doctor details: 17/18 exact).
120120
Rough faithful-and-verified completeness: **~87%**.

0 commit comments

Comments
 (0)