0050: Codex harness — ChatGPT subscription + in-app browser login #130
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "glen/0050-codex-harness"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds Codex CLI as the fourth external harness (pi/claude/cursor/codex), ChatGPT-subscription auth, with in-app login. Design + as-built: docs/0050-codex-harness.md. Everything mirrored from cursor (0038); live-checked end-to-end on bee 2026-10-18/19.
What's in
@ai-sdk/harness-codex@1.0.143(exact pin — pairs with our@ai-sdk/harness1.0.141 /provider-utils5.0.56, no stack bump; the tool-relay advisory GHSA-qw9h-448j-6rph affects ≤1.0.28 only). Bridge port 4002,codex({task})chat tool, kind unions everywhere,/h/codex/<id>view, usage bucket, project allow-list, logo/labels. No DB migration (kind is text); no sandbox image change (pnpm already baked; adapter pnpm-installs its bridge per sandbox).data/harness-auth/codex/auth.json(0600);CODEX_HOMEwired at boot so the adapter reads AND refreshes the file in place; enterprise account id ridesHarnessAgent({headers: {ChatGPT-Account-ID}})(the designed seam — our sandbox lacksaddRequestTransformations); runtime guard fails fast if any API-key env var would shadow the subscription.app_EMoamEEZ73f0CkXaXp7hrann, redirecthttp://localhost:1455/auth/callback, byte-shape pinned to the shipped CLI), you paste the localhost callback back on /settings, server validates state constant-time and exchanges FORM-ENCODED; account id read from the nestedhttps://api.openai.com/authclaim. Device-code flow secondary (Chad's enterprise workspace blocks it — proven live), paste-auth.json third. Tokens never enter logs, DB, or wire responses (test-enforced).gpt-5.6-sol(default),gpt-5.6-terra/luna,gpt-6-sol,gpt-6.1-sol,gpt-6-luna,gpt-6-astra(transiently "at capacity" live). gpt-5.5 and gpt-5.5-codex are rejected by the backend for ChatGPT accounts — the adapter's own default is stale, so codex routes MUST pin a model (validated, with guidance). Effort knob (low..xhigh,max) like claude's.Live evidence (bee, production path: real sandbox, real bridge, real turns)
Missing environment variable: CODEX_API_KEY).Review
Fresh-eyes review (review skill, separate context) returned merge-after-fixes: 2 should-fixes (runtime env-shadowing guard — was spike-only; modelless-route rejection — the API write path accepted a route that would send the rejected default) + 6 nits (misplaced comment, SANDBOXED_TOOLS miss, 1h→10min expiry margin so the adapter's own 5-min refresh window gets its chance, stale comments, boot warning on a diverging CODEX_HOME override, package.json churn). All 8 applied in
a1038b5and re-verified; reviewer's clean list: OAuth/PKCE/state handling, token hygiene across routes/UI/errors/tests, builder/headers seam, kind-union coverage, catalog/validation consistency, advisory claim.Tests
814 passed / 16 skipped (was 790 on main; +90 codex tests across auth, login (fake issuer incl. byte-exact wire shapes), routes/validation, builder, tool gating, catalog view, usage). Opt-in spike:
tests/codex-spike.integration.test.ts(CODEX_SPIKE=login_start|login_poll|turn).