Enable running the desktop apps on Linux for development - #336
Enable running the desktop apps on Linux for development#336vishaltandale00 wants to merge 9 commits into
Conversation
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb5411bc0e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| await writeFile( | ||
| join(codexHome, "auth.json"), | ||
| `${JSON.stringify({ auth_mode: "apikey", OPENAI_API_KEY: apiKey })}\n`, | ||
| { mode: 0o600 }, |
There was a problem hiding this comment.
Keep API keys out of persistent auth files
For every secret-backed Codex turn, this writes the raw provider key to a long-lived CODEX_HOME/auth.json and never removes it, creating a plaintext credential copy outside Electron's OS-backed credential store; mode 0600 does not protect the key from backups, filesystem disclosure, or later same-user processes. This contradicts the PRD's credential-storage boundary, so use an ephemeral authentication handoff or reliably remove the file after Codex has loaded it.
AGENTS.md reference: AGENTS.md:L17-L20
Useful? React with 👍 / 👎.
| if (context.access?.kind === "secret") { | ||
| const apiKey = context.access.fields["api-key"]; | ||
| const codexHome = environment.CODEX_HOME; | ||
| if (apiKey !== undefined && apiKey !== "" && codexHome !== undefined && codexHome !== "") { | ||
| await (this.dependencies.writeCodexApiKeyAuthFile ?? writeCodexApiKeyAuthFile)(codexHome, apiKey); |
There was a problem hiding this comment.
Admit OpenRouter and Vercel before writing their auth
When the selected API-key provider is OpenRouter or Vercel AI Router, execution never reaches this new auth block: selectedModel() still accepts only codex-subscription and openai-api, graphEnvironment() similarly rejects other secret adapters, and harnesses/codex-basic.yaml excludes both adapters even though the desktop runtime requirements map them to codex.basic. Consequently those connected provider routes still cannot complete a turn; widen the implementation and catalog compatibility checks and cover each production adapter at the broker-to-harness seam.
AGENTS.md reference: AGENTS.md:L17-L20
Useful? React with 👍 / 👎.
| "linux-x64": Object.freeze({ | ||
| key: "linux-x64", |
There was a problem hiding this comment.
Add Linux to the Eval runtime target resolver
On an ordinary linux-x64 checkout, npm run eval-app:dev still exits before creating a window: desktop/eval-main/configuration-paths.mjs calls desktopTargetFromEnvironment(), whose target registry has no Linux entry and throws Unsupported Relayer Desktop target: linux-x64. Adding Linux only to the managed-runtime catalog therefore does not enable the newly documented Eval command; add a development-only Linux target path to the Eval resolver without adding it to the signed-release matrix, and exercise the default Linux resolution in a deterministic test.
AGENTS.md reference: AGENTS.md:L19-L20
Useful? React with 👍 / 👎.
| // Linux ("0.0"), which the managed-runtime and updater code reject. Use the product | ||
| // version declared in package.json for development builds; packaged releases keep the | ||
| // sealed app version. | ||
| const desktopVersion = app.isPackaged ? app.getVersion() : (metadata.version || app.getVersion()); |
There was a problem hiding this comment.
Use the Linux development identity for telemetry
On the newly supported Linux development path, authenticated error reporting is always disabled: the startup call still passes Electron's invalid app.getVersion() value ("0.0") instead of this new desktopVersion, causing telemetry release validation to fail and return null; after correcting that call, developmentProjection() would still reject linux-x64 through the release-only desktopTarget() registry. Pass the normalized version and add a development-only Linux telemetry projection so this platform does not silently lose all main, renderer, and child-process error reports.
AGENTS.md reference: AGENTS.md:L19-L20
Useful? React with 👍 / 👎.
Add a linux-x64 managed-runtime catalog target so the unsigned Relayer Dev and Relayer Eval builds resolve the vendored Codex (x86_64-unknown-linux-musl) and downloadable Claude runtimes on Linux. Fix two Linux-only startup crashes in the desktop main process: skip constructing the packaged auto-updater in development (the Linux AppImageUpdater rejects the dev version at construction), and use the package.json product version for development builds because Electron's app.getVersion() is not valid semver for the unsigned Linux app. Signed release targets remain macOS + Windows x64 (ADR 0002). Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
Record the accepted decision to run the unsigned Relayer Dev and Relayer Eval builds on linux-x64 for development while keeping signed release targets on macOS and Windows x64. Update the README development guide, ADR 0002 consequences, and the PRD desktop release section. Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
Provider connections store credentials via Electron safeStorage, which needs an OS Secret Service. Document running the desktop apps inside a D-Bus session with an unlocked gnome-keyring on headless Linux. Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
The Codex runtime authenticates an API-key provider from CODEX_HOME/auth.json;
setting only OPENAI_API_KEY in the environment is ignored (requests go out with
no bearer, yielding 401). codex.basic now writes {auth_mode: apikey,
OPENAI_API_KEY} into the isolated per-provider CODEX_HOME for secret-access
providers (openai-api, openrouter, vercel-ai-router) before launching Codex, so
the Desktop GUI can complete a turn with a connected OpenAI/OpenRouter/Vercel
provider. The write is injectable for tests; integration and unit tests cover
the auth.json content.
Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
fb5411b to
7aa3d9f
Compare
Unpackaged Relayer Eval resolved through the signed-release target registry, so npm run eval-app:dev failed on linux-x64 before a window opened. Resolve Linux only for unpackaged Eval and keep packaged/signed targets on macOS and Windows x64. Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
codex.basic already mapped those adapters at the desktop runtime boundary, but selectedModel, graphEnvironment, and the production YAML catalog still rejected them. Write CODEX_HOME/auth.json only for the Codex turn and delete it afterward so the durable secret stays in the OS credential store. Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
OpenRouter and Vercel require a discovered catalog before execution access. The integration fixture now returns a valid catalog so those adapters reach the same ephemeral auth.json seam as openai-api. Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
Admit the adapters in the checked-in configuration fixtures and expect onboarding to select the product default harness now that those providers are compatible with codex.basic. Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
Removing auth.json in every turn finally raced concurrent Completes that share one provider home. Retain a process-local use count and unlink only when the last turn using that home settles. Co-authored-by: Vishal <vishaltandale00@users.noreply.github.com>
Summary
Two related pieces of work to make Relayer usable on Linux for development, rebased onto current
main, plus the Codex P1 review fixes:linux-x64(unsignedRelayer Dev/Relayer Eval), keeping signed release targets on macOS + Windows x64 per ADR 0002.codex.basicauthenticate API-key providers, so the Desktop GUI can complete a live turn with a connected OpenAI/OpenRouter/Vercel provider.Codex P1 fixes
npm run eval-app:devnow resolves a development-onlylinux-x64host inevalRuntimeTarget. Packaged/signed target resolution still fails closed for Linux.codex.basicselected-model, secret-access, and production YAML catalog (codex-basic, graph-search twin, high) now admit those adapters. Broker-to-harness coverage runs each production secret adapter. Onboarding now selects the product default harness (codex-basic) for those adapters because they are compatible.CODEX_HOME/auth.jsonis written only for Codex turns that need it. A process-local use count keeps the file while overlapping secret Completes share that home, then deletes it when the last turn settles (including turn failure). The durable key stays in the OS credential store (PRD AGT-007).Changes
Linux development host
desktop/main/managed-runtimes/catalog.mjs: add alinux-x64managed-runtime target (Codexx86_64-unknown-linux-musl, already vendored; Claude@anthropic-ai/claude-agent-sdk-linux-x64).desktop/eval-main/configuration-paths.mjs: admitlinux-x64only for unpackaged Eval; packaged Eval still uses the signed-release registry.desktop/main/index.mjs: don't construct the packaged auto-updater in dev (LinuxAppImageUpdaterrejects the unsigned dev version at construction); use thepackage.jsonproduct version in dev (Electronapp.getVersion()is invalid semver,"0.0", on the unsigned Linux app).README.md(Linux dev guide: display, setuidchrome-sandbox, D-Bus +gnome-keyringforsafeStorage),docs/decisions/0002-desktop-release-contract.md,docs/prd/index.html.API-key auth for
codex.basic(Desktop GUI send)packages/harness-host/src/implementations/codex-basic.ts: forsecret-access providers (openai-api,openrouter,vercel-ai-router), write{auth_mode:"apikey","OPENAI_API_KEY":<key>}into the isolated per-providerCODEX_HOME/auth.jsonbefore launching Codex, then delete that file when the last in-process turn using that home settles.Verification
Plan: rebase onto
main; map the three P1 seams to in-process tests; run those tests in the edit loop; thennpm run buildandnpm run check.Ran:
cda132b1085245ac17543d71f5f59e0d1e1b4c25:codex-basic46 passed, including ephemeral auth, overlap refcount, OpenRouter/Vercel admission. Earlier on1c3840d:eval-configuration-paths,managed-runtime-provider-integration,configuration,provider-straightforward-flowalso passed (97 tests combined withcodex-basicat that snapshot).evalRuntimeTarget({platform:"linux", architecture:"x64"})returnslinux-x64; packaged anddesktopTargetstill throwUnsupported Relayer Desktop target: linux-x64.npm run buildpassed on1c3840d.npm run checkon1c3840d: cargo/fmt/clippy/tsc/workspaces passed. Vitest: 1941 passed, 27 skipped, 1 failed:packages/eval-runner/test/calibration-autonomous-cases.test.ts"accepts one known-good implementation for every coding verifier" timed out at 20s. That file is unchanged in this PR; the timeout also reproduces in isolation. Remaining check chapters after Vitest (test:codex-secret-boundary, Python, Ladybug lint, PRD readability) passed.@relayer/harness-hosttsc --noEmitpassed oncda132b.Not claimed: live OpenRouter/Vercel Desktop send, packaged Linux Eval, or signed-release Linux. Codex P2 (Linux telemetry still uses Electron's invalid
0.0version / release-only target registry) is unaddressed.Adversarial review
bc-8a8822ba-2fe8-5f64-aa4a-766647ae4f6e1c3840dcf2746da7447e5c5863fde2eb57cbd729(P1 mapping). Follow-upcda132b1085245ac17543d71f5f59e0d1e1b4c25addresses the overlapping-Complete finding from that review; invalidate the1c3840dassertion for the auth-file lifecycle and use this HEAD for that seam.codex.basicadmission, ephemeralauth.jsonauth.jsonin the isolated providerCODEX_HOMEuntil a later secret turn for that home overwrites or removes it. There is no process-start sweeper. Unpackaged Eval is the Linux host that was gated; official unsigned packaging still uses the signed-release target registry.Known limitation
codex.basicsendsreasoning.effort(fromcodex-basic.yaml), which non-reasoning models likegpt-4oreject with HTTP 400 (Unsupported parameter: 'reasoning.effort'). Use a reasoning-capable model (e.g.gpt-5.6-sol) in the Desktop GUI.Environment note
Running Electron headless needs a display (
DISPLAY=:1), a setuid-rootchrome-sandbox, and — for provider credential storage — a D-Bus session with an unlockedgnome-keyring.