Electron desktop runs network-sensitive OpenAI OAuth token exchange in the sidecar process, so the sidecar now receives system proxy env derived from Electron's cross-platform proxy resolver and the OAuth token client uses the existing proxy fetch options. General manual proxy settings also document and preserve authenticated proxy URLs.
The macOS fullscreen black-screen path is addressed by avoiding native fullscreen Spaces for app fullscreen toggles and by leaving fullscreen before hiding or closing the window.
Constraint: Electron packaged apps may not inherit shell HTTPS_PROXY env when launched from Finder.
Constraint: Manual authenticated proxies must remain standard HTTP(S) proxy URLs for Bun/undici compatibility.
Rejected: Store proxy username and password as separate fields | would require new secret-storage semantics and migration beyond this bugfix.
Rejected: Use native macOS fullscreen Spaces for the desktop app | reproduced black-screen behavior when hiding/closing from fullscreen.
Confidence: high
Scope-risk: moderate
Directive: Do not remove sidecar proxy env injection without retesting OpenAI OAuth from a packaged app launched outside a shell.
Tested: bun test src/services/openaiAuth/client.test.ts src/server/__tests__/haha-openai-oauth-service.test.ts
Tested: bun test src/server/__tests__/network-settings.test.ts
Tested: cd desktop && bun run test -- src/__tests__/generalSettings.test.tsx --run
Tested: cd desktop && bun run check:electron
Tested: git diff --check
Not-tested: bun run check:server blocked by expired quarantine entries server:cron-scheduler, server:providers-real, server:tasks, server:e2e:business-flow, server:e2e:full-flow
Not-tested: live OpenAI OAuth through a corporate authenticated proxy
OpenAI returns token-exchange failures at the OAuth boundary, so the desktop ChatGPT login path should send the same Codex-compatible headers as the reference implementation and preserve enough sanitized response detail to diagnose upstream rejections.
Constraint: OpenAI authorization codes and token responses are sensitive and must not be logged verbatim.
Rejected: Retry the pasted authorization code during debugging | the code is single-use sensitive material and the next generated code gives cleaner evidence.
Confidence: medium
Scope-risk: narrow
Directive: Keep token exchange diagnostics sanitized; do not include raw OAuth codes, refresh tokens, access tokens, or id tokens in errors.
Tested: bun test src/services/openaiAuth/client.test.ts
Tested: bun test src/server/__tests__/haha-openai-oauth-service.test.ts src/server/__tests__/haha-openai-oauth-api.test.ts src/services/openaiAuth/fetch.test.ts src/services/openaiAuth/storage.test.ts
Tested: bun run check:server
Tested: bun run verify
Not-tested: Full successful live OAuth exchange with a fresh user authorization code.
OpenAI rejects the authorize URL before callback when non-Codex query
parameters are sent. The ChatGPT OAuth flow now matches the sub2api
Codex-compatible shape by keeping originator out of the authorize URL
and using OpenAI-specific hex state and PKCE verifier values.
Constraint: The Codex OAuth client expects the standard authorize query shape used by sub2api.
Rejected: Keep originator=opencode in the OAuth URL | originator is a later ChatGPT API request header concern, not an OAuth authorize parameter.
Confidence: high
Scope-risk: narrow
Tested: bun test src/services/openaiAuth/client.test.ts src/server/__tests__/haha-openai-oauth-service.test.ts src/server/__tests__/haha-openai-oauth-api.test.ts src/services/openaiAuth/fetch.test.ts src/services/openaiAuth/storage.test.ts
Tested: git diff --check
Tested: bun run check:server
Not-tested: Live browser OAuth authorization against a real OpenAI account.