|
| 1 | +--- |
| 2 | +"@open-codesign/providers": minor |
| 3 | +"@open-codesign/desktop": minor |
| 4 | +"@open-codesign/shared": minor |
| 5 | +"@open-codesign/core": minor |
| 6 | +"@open-codesign/i18n": patch |
| 7 | +--- |
| 8 | + |
| 9 | +feat(codex): unify ChatGPT subscription path onto pi-ai's built-in openai-codex-responses wire |
| 10 | + |
| 11 | +Phase 2 of the Codex subscription login work. The self-rolled Codex client |
| 12 | +path from Phase 1 is replaced by pi-ai's first-class `openai-codex-responses` |
| 13 | +adapter (shipped in pi-ai 0.67.68) so every provider — Anthropic, OpenAI, |
| 14 | +Gemini, ChatGPT Codex — now runs through the same core/pi-agent-core route |
| 15 | +with no provider-specific branching. |
| 16 | + |
| 17 | +### Schema + routing |
| 18 | +- `packages/shared`: extend `WireApiSchema` and `CanonicalWire` with |
| 19 | + `openai-codex-responses`; promote `CHATGPT_CODEX_PROVIDER_ID` to shared so |
| 20 | + `provider-settings` references the same literal the OAuth module writes |
| 21 | + without creating a module cycle. |
| 22 | +- `canonicalBaseUrl` passes codex URLs through untouched (pi-ai's wire |
| 23 | + appends `/codex/responses` itself); `modelsEndpointUrl` throws for codex |
| 24 | + (no discoverable /models endpoint — providers use `modelsHint`). |
| 25 | +- `packages/core`, `packages/providers`: `apiForWire` + `synthesizeWireModel` |
| 26 | + recognize the new wire; all 4 duplicated `'openai-chat' | …` unions |
| 27 | + consolidated onto the shared `WireApi` type. |
| 28 | + |
| 29 | +### Desktop wiring |
| 30 | +- New `apps/desktop/src/main/resolve-api-key.ts`: dependency-injected helper |
| 31 | + that routes ChatGPT provider id to the token store's auto-refreshing |
| 32 | + access token, and every other provider to the keychain-backed API key. |
| 33 | + Codex auth failures surface as `CodesignError(PROVIDER_AUTH_MISSING)` so |
| 34 | + the renderer's error-code routing stays consistent with the API-key-missing |
| 35 | + path. Covered by 7 unit tests via DI. |
| 36 | +- `main/index.ts`: `resolveActiveApiKeyFromState` replaces the inline |
| 37 | + `isChatgptCodex` validate / dispatch branches in all 4 IPC handlers |
| 38 | + (`codesign:v1:generate`, legacy `codesign:generate`, apply-comment, |
| 39 | + generate-title). Legacy `codesign:generate` no longer rejects codex. |
| 40 | +- Long-running agent runs: `GenerateInput.getApiKey` is a new optional async |
| 41 | + getter; the desktop passes it only for codex so pi-agent-core calls back |
| 42 | + into the token store on each LLM round-trip (auto-refreshes within the |
| 43 | + 5-min buffer). Mid-run sign-out errors are captured in a closure variable |
| 44 | + and rethrown verbatim from the post-agent branch so the structured |
| 45 | + `PROVIDER_AUTH_MISSING` code isn't lost to pi-agent-core's plain-string |
| 46 | + failure-message flattening. |
| 47 | + |
| 48 | +### Registration + migration |
| 49 | +- `codex-oauth-ipc.ts`: provider entry registers `wire=openai-codex-responses`, |
| 50 | + bare `baseUrl=https://chatgpt.com/backend-api`, and the full 9-model catalog |
| 51 | + (gpt-5.1 → gpt-5.4-mini), ordered flagship-first. |
| 52 | +- `migrateStaleCodexEntryIfNeeded()` runs once at boot and rewrites any |
| 53 | + Phase-1-shaped `chatgpt-codex` provider (`wire=openai-responses`, |
| 54 | + `baseUrl=/codex`) to the Phase 2 canonical values, so feat-branch testers |
| 55 | + don't need to sign out and back in after upgrade. No-op when the entry is |
| 56 | + absent or already canonical. |
| 57 | + |
| 58 | +### UI |
| 59 | +- `ChatgptLoginCard.tsx`: flipped out of "coming soon" mode back to the full |
| 60 | + three-state login/status/logout flow, with i18n keys in both locales. |
| 61 | + |
| 62 | +### Deletions (-963 LOC of Phase 1 code now provided by pi-ai) |
| 63 | +- `apps/desktop/src/main/codex-generate.ts` + test |
| 64 | +- `apps/desktop/src/main/codex-title.ts` |
| 65 | +- `packages/providers/src/codex/client.ts` + test |
| 66 | + |
| 67 | +OAuth-side code (`oauth.ts`, `oauth-server.ts`, `token-store.ts`) is unchanged |
| 68 | +— still the only codex-specific code, and it sits outside the generation link. |
0 commit comments