-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Codex web app architecture #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
b674d43
275863c
f94bbc4
948947d
9b9f587
976c2ed
871fe5e
bb4f4d5
56349ee
84e3659
6238edb
1990db7
83ce5f4
f3d92c9
8cc7135
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,67 +1,88 @@ | ||||||||||||||||||||||||||||||||||||
| # CodeThing (Electron + Vite + Bun) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| CodeThing is a desktop shell for coding agents. This first implementation is: | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| 1. Codex-first: connects to `codex app-server` and streams turn/item events. | ||||||||||||||||||||||||||||||||||||
| 2. Provider-ready: renderer speaks a provider abstraction so Claude Code can plug in later. | ||||||||||||||||||||||||||||||||||||
| 3. Typed end-to-end: contracts validate payloads at preload/main boundaries. | ||||||||||||||||||||||||||||||||||||
| # CodeThing | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| CodeThing is a minimal web GUI for coding agents. Currently Codex-first, with Claude Code support coming soon. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Run `npx t3` in any project directory to launch the web interface. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Architecture | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| CodeThing runs as a **Node.js WebSocket server** that wraps `codex app-server` (JSON-RPC over stdio) and serves a React web app. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||
| ┌─────────────────────────────────┐ | ||||||||||||||||||||||||||||||||||||
| │ Browser (React + Vite) │ | ||||||||||||||||||||||||||||||||||||
| │ Connected via WebSocket │ | ||||||||||||||||||||||||||||||||||||
| └──────────┬──────────────────────┘ | ||||||||||||||||||||||||||||||||||||
| │ ws://localhost:3773 | ||||||||||||||||||||||||||||||||||||
| ┌──────────▼──────────────────────┐ | ||||||||||||||||||||||||||||||||||||
| │ apps/server (Node.js) │ | ||||||||||||||||||||||||||||||||||||
| │ WebSocket + HTTP static server │ | ||||||||||||||||||||||||||||||||||||
| │ ProviderManager │ | ||||||||||||||||||||||||||||||||||||
| │ CodexAppServerManager │ | ||||||||||||||||||||||||||||||||||||
| └──────────┬──────────────────────┘ | ||||||||||||||||||||||||||||||||||||
| │ JSON-RPC over stdio | ||||||||||||||||||||||||||||||||||||
| ┌──────────▼──────────────────────┐ | ||||||||||||||||||||||||||||||||||||
| │ codex app-server │ | ||||||||||||||||||||||||||||||||||||
| └─────────────────────────────────┘ | ||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add language specifier to fenced code block. The ASCII architecture diagram lacks a language specifier, which triggers a markdownlint warning (MD040). While 📝 Suggested fix-```
+```text
┌─────────────────────────────────┐
│ Browser (React + Vite) │📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.20.0)[warning] 11-11: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Workspace layout | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| - `/apps/desktop`: Electron main + preload process, includes provider and Codex session managers. | ||||||||||||||||||||||||||||||||||||
| - `/apps/renderer`: React + Vite UI for session control, conversation, and protocol event stream. | ||||||||||||||||||||||||||||||||||||
| - `/packages/contracts`: shared Zod schemas + TypeScript types for IPC and provider events. | ||||||||||||||||||||||||||||||||||||
| - `/apps/server`: Node.js WebSocket server. Wraps Codex app-server, serves the built renderer, and opens the browser on start. | ||||||||||||||||||||||||||||||||||||
| - `/apps/renderer`: React + Vite UI. Session control, conversation, and provider event rendering. Connects to the server via WebSocket. | ||||||||||||||||||||||||||||||||||||
| - `/packages/contracts`: Shared Zod schemas and TypeScript contracts for provider events, WebSocket protocol, and model/session types. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Codex prerequisites | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| - Install Codex CLI so `codex` is on your PATH. | ||||||||||||||||||||||||||||||||||||
| - Authenticate Codex before running CodeThing (for example via API key or ChatGPT auth supported by Codex). | ||||||||||||||||||||||||||||||||||||
| - CodeThing starts the server via `codex app-server` per session. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Security and boundary model | ||||||||||||||||||||||||||||||||||||
| ## Quick start | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| - `nodeIntegration: false` | ||||||||||||||||||||||||||||||||||||
| - `contextIsolation: true` | ||||||||||||||||||||||||||||||||||||
| - `sandbox: true` | ||||||||||||||||||||||||||||||||||||
| - Renderer talks only to `window.nativeApi` exposed by preload. | ||||||||||||||||||||||||||||||||||||
| - Preload and main both validate inputs using shared Zod schemas. | ||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||
| # Development (with hot reload) | ||||||||||||||||||||||||||||||||||||
| bun run dev | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| `sandbox: true` above is Electron renderer sandboxing. It is separate from Codex execution sandbox policy (`read-only`, `workspace-write`, `danger-full-access`) used when starting provider sessions. | ||||||||||||||||||||||||||||||||||||
| # Production | ||||||||||||||||||||||||||||||||||||
| bun run build | ||||||||||||||||||||||||||||||||||||
| bun run start | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Runtime modes | ||||||||||||||||||||||||||||||||||||
| # Or from any project directory after publishing: | ||||||||||||||||||||||||||||||||||||
| npx t3 | ||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| CodeThing has a global runtime mode switch in the sidebar: | ||||||||||||||||||||||||||||||||||||
| ## Scripts | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| - `Full access` (default): starts new sessions with `approvalPolicy: never` and `sandboxMode: danger-full-access`. | ||||||||||||||||||||||||||||||||||||
| - `Approval required`: starts new sessions with `approvalPolicy: on-request` and `sandboxMode: workspace-write`, then prompts in-app for command/file approvals. | ||||||||||||||||||||||||||||||||||||
| - `bun run dev` — Starts both the WebSocket server and Vite dev server in parallel with hot reload. | ||||||||||||||||||||||||||||||||||||
| - `bun run dev:server` — Starts just the WebSocket server (uses tsx for TS execution). | ||||||||||||||||||||||||||||||||||||
| - `bun run dev:web` — Starts just the Vite dev server for the renderer. | ||||||||||||||||||||||||||||||||||||
| - `bun run start` — Runs the production server (serves built renderer as static files). | ||||||||||||||||||||||||||||||||||||
| - `bun run build` — Builds contracts, renderer, and server through Turbo. | ||||||||||||||||||||||||||||||||||||
| - `bun run typecheck` — Strict TypeScript checks for all packages. | ||||||||||||||||||||||||||||||||||||
| - `bun run test` — Runs workspace tests. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Mode changes apply across all threads. Existing live sessions are restarted so old and new threads use the selected mode. | ||||||||||||||||||||||||||||||||||||
| ## Runtime modes | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Scripts | ||||||||||||||||||||||||||||||||||||
| CodeThing has a global runtime mode switch in the chat toolbar: | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| - `bun run dev`: starts contract build/watch, renderer dev server, and Electron process. | ||||||||||||||||||||||||||||||||||||
| - `bun run build`: builds contracts, renderer, and desktop bundles through Turbo. | ||||||||||||||||||||||||||||||||||||
| - `bun run typecheck`: strict TypeScript checks for all packages. | ||||||||||||||||||||||||||||||||||||
| - `bun run test`: runs workspace tests. | ||||||||||||||||||||||||||||||||||||
| - **Full access** (default): starts sessions with `approvalPolicy: never` and `sandboxMode: danger-full-access`. | ||||||||||||||||||||||||||||||||||||
| - **Supervised**: starts sessions with `approvalPolicy: on-request` and `sandboxMode: workspace-write`, then prompts in-app for command/file approvals. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## CI quality gates | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| - `.github/workflows/ci.yml` runs `bun run lint`, `bun run typecheck`, and `bun run test` on pull requests and pushes to `main`. | ||||||||||||||||||||||||||||||||||||
| ## Provider architecture | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Optional: | ||||||||||||||||||||||||||||||||||||
| The renderer communicates with the server via WebSocket using a simple JSON-RPC-style protocol: | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| - `ELECTRON_RENDERER_PORT=5180 bun run dev` if `5173` is already in use. | ||||||||||||||||||||||||||||||||||||
| - **Request/Response**: `{ id, method, params }` → `{ id, result }` or `{ id, error }` | ||||||||||||||||||||||||||||||||||||
| - **Push events**: `{ type: "push", channel, data }` for streaming provider events | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Provider architecture | ||||||||||||||||||||||||||||||||||||
| Methods mirror the `NativeApi` interface defined in `@acme/contracts`: | ||||||||||||||||||||||||||||||||||||
| - `providers.startSession`, `providers.sendTurn`, `providers.interruptTurn` | ||||||||||||||||||||||||||||||||||||
| - `providers.respondToRequest`, `providers.stopSession`, `providers.listSessions` | ||||||||||||||||||||||||||||||||||||
| - `shell.openInEditor`, `server.getConfig` | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| The renderer now depends on `nativeApi.providers.*`: | ||||||||||||||||||||||||||||||||||||
| Codex is the only implemented provider. `claudeCode` is reserved in contracts/UI. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| 1. `startSession` | ||||||||||||||||||||||||||||||||||||
| 2. `sendTurn` | ||||||||||||||||||||||||||||||||||||
| 3. `interruptTurn` | ||||||||||||||||||||||||||||||||||||
| 4. `respondToRequest` | ||||||||||||||||||||||||||||||||||||
| 5. `stopSession` | ||||||||||||||||||||||||||||||||||||
| 6. `listSessions` | ||||||||||||||||||||||||||||||||||||
| 7. `onEvent` | ||||||||||||||||||||||||||||||||||||
| ## CI quality gates | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Codex is the only implemented provider right now. `claudeCode` is reserved in contracts/UI but returns a not-implemented error in main-process dispatch. | ||||||||||||||||||||||||||||||||||||
| - `.github/workflows/ci.yml` runs `bun run lint`, `bun run typecheck`, and `bun run test` on pull requests and pushes to `main`. | ||||||||||||||||||||||||||||||||||||
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filename and header mismatch.
The file is named
AGENTS.mdbut the header reads# CLAUDE.md. This appears to be either an incomplete rename or a copy-paste issue. Consider renaming the file toCLAUDE.mdor updating the header to match the current filename.🤖 Prompt for AI Agents