Add MyCodex: a cross-platform desktop app for the @openai/codex engine#1
Add MyCodex: a cross-platform desktop app for the @openai/codex engine#1devin-ai-integration[bot] wants to merge 2 commits into
Conversation
…/codex engine MyCodex wraps the official Codex engine in an Electron desktop shell with a sessions sidebar, working-folder picker, interrupt control, and the engine running in an embedded xterm.js terminal driven by node-pty. Handles the three GUI-packaging pitfalls: login-shell PATH/TERM reconstruction before spawning the engine, asar:false so the bundled binary is spawnable, and chmod +x on node-pty's spawn-helper / the engine binary. Isolated under mycodex/ (not a bun workspace), so it does not affect the opencode monorepo's install or typecheck.
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Found while testing the electron-builder output: - The platform engine package is hoisted differently when installed by the packager (nested under @openai/codex/node_modules), so findCodexBinary now searches both the top-level and nested roots plus a bounded recursive fallback. - Add scripts/**/* to the build files glob (fix-pty-permissions.js is required at startup and was missing from the package, crashing the packaged app). - Send electron-builder output to release/ so it cannot recursively include the renderer's dist/.
Runtime test results — packaged Linux buildTested the packaged build ( Demo recording (T1→T6):
T3 — Real Codex TUI renders through the PTY (the core integration)"Start a session" spawns the real T1 — Launch + engine detection
T2 — Working-folder pickerNative GTK dialog opens; selecting T4 — Bidirectional PTY (keystrokes)Down moved the T5 — Interrupt button delivers ESCOn the API-key sub-screen ("Press esc to go back"), clicking Interrupt returned to the main menu — confirming the button delivers ESC ( T6 — Persistence across full restartKilled the process and relaunched; the working folder restored to Notes — untested flows, a cosmetic quirk, and CIUntested (auth skipped): send a message, file-edit approval, diff view, functional turn-interrupt, real Cosmetic quirk (not functional): the sidebar folder box shows CI: 0 checks ran — GitHub Actions isn't triggered for this branch on the fork, and MyCodex is an isolated top-level dir (not a bun workspace), so it doesn't affect opencode's own pipeline. Not a failure. Tested by Devin — session: https://app.devin.ai/sessions/a2330658806b42acab0d0b0ce33ddecf |
Summary
MyCodex is a cross-platform Electron desktop app (isolated top-level
mycodex/dir, not a bun workspace, so it does not touch opencode's install/typecheck) that wraps the official open-source@openai/codexengine. Rather than reimplementing Codex's chat/approvals/diff UI, it embeds the real Codex TUI in an xterm.js terminal driven by node-pty — so every acceptance feature (send a message, file-edit approval, diff, interrupt, resume) is the engine's own native behavior rendered inside a desktop shell with a session sidebar, working-folder picker, and an Interrupt button.How it works
src/main/main.js,src/main/codex.js):pty.spawn(codexBinary, resumeId ? ["resume", resumeId] : [], { env }). Output streams to the renderer viapty:data → term.write; keystrokes goterm.onData → writePty → engine stdin. The Interrupt button sends ESC:pty:interrupt → term.write("\x1b").src/main/env.jsresolves a full login-shell env ($SHELL -ilc) before spawning, merges PATH, setsTERM=xterm-256color.asar:falseinpackage.jsonbuild config so the bundled engine binary is spawnable.chmod +x→scripts/fix-pty-permissions.jsruns at postinstall and app startup (no-op on Linux which uses forkpty; needed on macOS).codex.js listSessions()reads~/.codex/sessions/*.jsonl; clicking a session callslaunch({resumeId})→codex resume <id>. Working folder + last session persist inlocalStorageand reload on init.Packaging fixes in this PR (commit
e216a4e)Two real bugs found by testing the packaged build (not just the dev tree):
@openai/codex/node_modules/@openai/codex-linux-x64instead of hoisting it.codex.jsnow searches both hoisted and nested roots (candidateNodeModuleRoots+ recursivesearchBinaryfallback).scripts/in the bundle:scripts/**/*was absent from the electron-builderfilesglob, so the packaged app crashed withCannot find module '../../scripts/fix-pty-permissions'. Added tofiles.Testing status
Tested the packaged Linux build (
release/linux-unpacked/mycodex, asar:false) on the VM GUI. A recorded walkthrough of six auth-free tests all passed: launch + engine detection (engine: codex ✓), working-folder picker, real Codex TUI rendering through the PTY, bidirectional keystrokes, Interrupt-button ESC delivery, and working-folder persistence across a full restart.Untested (auth skipped by request): the credentialed agent flow — send a message, file-edit approval, diff view, functional turn-interrupt, real
codex resume. These mechanisms are wired (paths above) but were not exercised live; they "should work in theory" but I have not verified them.Known minor cosmetic quirk (not functional): the sidebar folder box renders
~/Projects/mycodexasProjects/mycodex/~because.folder-pathusesdirection: rtl(styles.css:115) for tail-truncation. The stored value is correct (top-bar shows~/Projects/mycodex; folder persists correctly). One-line CSS follow-up available.See the test-results comment below for screenshots and the recording.
Link to Devin session: https://app.devin.ai/sessions/a2330658806b42acab0d0b0ce33ddecf
Requested by: @01clauding