Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.1.38
bun-version: 1.3.9

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Bun 1.3.9 release changelog breaking changes

💡 Result:

Bun v1.3.9 (published Feb 8, 2026) does not call out any explicit “breaking changes” section in the official changelog. The release is mostly new features, fixes, and perf work. [1]

Possible breaking / behavior-changing items to watch:

  • NO_PROXY is now respected even when you pass an explicit proxy option to fetch() / new WebSocket()—requests that previously went through the proxy may now bypass it (or vice‑versa, depending on your env). [1]
  • Security fix: HTTP server chunked encoding parser issue that could lead to request smuggling (behavior may change for malformed/ambiguous requests). [1]

Not breaking, but notable changelog items:

  • bun run --parallel / --sequential for running multiple scripts (with workspace/filter integration). [1]
  • bun:test mock() / spyOn() implement Symbol.dispose (works with using to auto-restore). [1]
  • --compile now supports ESM bytecode (--bytecode --format=esm). [1]
  • Fix for SIGILL crashes on older ARMv8.0 aarch64 CPUs. [1]

Source

  • [1] Bun v1.3.9 blog changelog (bun.com) (bun.com)

Citations:


🌐 Web query:

Bun version history 1.1.38 to 1.3.9 what changed

💡 Result:

Between Bun v1.1.38 (Nov 29, 2024) and Bun v1.3.9 (Feb 8, 2026), the highlights were:

  • v1.1.38: bugfix release (VSCode terminal/debugger hang, postgres crash, TypeScript minification bug, fetch() rare crash, Bun.FileSystemRouter.reload() fix), reusePort for Bun.listen/node:net, SQLite 3.45 → 3.47, plus other compatibility fixes. [1]
  • v1.2.3: major frontend tooling update—run .html directly as a dev server with hot reload/bundling; built-in routing for Bun.serve() (routes); bun init React template; bun install --analyze; plus Node.js compatibility and Bun.SQL improvements. [2]
  • v1.3.4: URLPattern API + fake timers in bun:test (and other fixes). [3]
  • v1.3.5: Bun.Terminal (PTY) support via Bun.spawn({ terminal: ... }) for truly interactive subprocesses. [4]
  • v1.3.6: Bun.Archive (create/extract tar/tar.gz) + Bun.JSONC.parse() (JSON-with-comments) and related tooling updates. [5]
  • v1.3.8: built-in Bun.markdown (CommonMark-compliant parser) + bun build --metafile-md for Markdown bundle analysis output. [6]
  • v1.3.9: bun run --parallel / --sequential for running multiple scripts; bun:test Symbol.dispose support for mock()/spyOn() (works with using); NO_PROXY honored even with explicit proxy options; --cpu-prof-interval; ESM bytecode support in --compile --bytecode; ARM crash fix on older ARMv8.0 CPUs; plus performance work (Markdown, AbortSignal) and a JavaScriptCore upgrade with multiple JIT/SIMD improvements. [7]

Sources: Bun blog release notes for v1.1.38, v1.2.3, v1.3.4, v1.3.5, v1.3.6, v1.3.8, v1.3.9. [1][2][3][4][5][6][7]


Confirm Bun 1.3.9 is tested against behavior changes before merging.

Bun 1.3.9 was published Feb 8, 2026 and is stable. However, the jump from 1.1.38 introduces two behavior-changing items to watch:

  • NO_PROXY is now respected even with an explicit proxy option to fetch() / new WebSocket()—requests may route differently than before.
  • HTTP chunked encoding parser security fix for request smuggling—malformed/ambiguous requests will behave differently.

Ensure bun run test && bun run check exercise code paths affected by these changes.

🤖 Prompt for AI Agents
In @.github/workflows/ci.yml at line 20, Update the CI entry that sets
"bun-version: 1.3.9" to ensure the test matrix actually exercises the changed
behaviors: add/modify a workflow step to run "bun run test && bun run check"
under bun-version: 1.3.9 and (optionally) add a matrix axis or additional job
that runs the same commands against the previous stable version (e.g., 1.1.38)
for comparison; explicitly ensure tests cover code paths using fetch() and new
WebSocket() (proxy behavior) and any HTTP server request parsing/handlers
(chunked encoding/request-smuggling scenarios) so differences are detected
before merging.


- name: Cache Bun and Turbo
uses: actions/cache@v4
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ node_modules
*.log
*.tsbuildinfo
apps/*/dist
apps/*/dist-electron
packages/*/dist
.env
.env.local
Expand Down
19 changes: 10 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# AGENTS.md
# CLAUDE.md

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Filename and header mismatch.

The file is named AGENTS.md but the header reads # CLAUDE.md. This appears to be either an incomplete rename or a copy-paste issue. Consider renaming the file to CLAUDE.md or updating the header to match the current filename.

🤖 Prompt for AI Agents
In `@AGENTS.md` at line 1, The top-level header in the file does not match the
filename: AGENTS.md contains “# CLAUDE.md”; update the header to match the
file's intent or rename the file to CLAUDE.md. Specifically either change the
markdown top-line header from “# CLAUDE.md” to “# AGENTS” (or a more appropriate
title) inside AGENTS.md, or rename the file to CLAUDE.md so the filename and
header are consistent.


## Project Snapshot
CodeThing is a minimal GUI for using code agents like Codex and Claude Code (coming soon).
CodeThing is a minimal web GUI for using code agents like Codex and Claude Code (coming soon).

This repository is a VERY EARLY WIP. Proposing sweeping changes that improve long-term maintainability is encouraged.

Expand All @@ -13,17 +13,18 @@ This repository is a VERY EARLY WIP. Proposing sweeping changes that improve lon
If a tradeoff is required, choose correctness and robustness over short-term convenience.

## Package Roles
- `apps/desktop`: Electron main/preload runtime. Owns provider orchestration, process/session lifecycle, and native IPC boundaries.
- `apps/renderer`: React/Vite UI. Owns session UX, conversation/event rendering, and client-side state.
- `packages/contracts`: Shared Zod schemas and TypeScript contracts for provider events, IPC payloads, and model/session types.
- `apps/server`: Node.js WebSocket server. Wraps Codex app-server (JSON-RPC over stdio), serves the React web app, and manages provider sessions.
- `apps/renderer`: React/Vite UI. Owns session UX, conversation/event rendering, and client-side state. Connects to the server via WebSocket.
- `packages/contracts`: Shared Zod schemas and TypeScript contracts for provider events, WebSocket protocol, and model/session types.

## Codex App Server (Important)
CodeThing is currently Codex-first. The desktop app starts `codex app-server` (JSON-RPC over stdio) per provider session, then streams structured events into the renderer through the provider APIs.
CodeThing is currently Codex-first. The server starts `codex app-server` (JSON-RPC over stdio) per provider session, then streams structured events to the browser through WebSocket push messages.

How we use it in this codebase:
- Session startup/resume and turn lifecycle are brokered in `apps/desktop/src/codexAppServerManager.ts`.
- Provider dispatch and thread event logging are coordinated in `apps/desktop/src/providerManager.ts`.
- Renderer consumes provider event streams via `nativeApi.providers.onEvent`.
- Session startup/resume and turn lifecycle are brokered in `apps/server/src/codexAppServerManager.ts`.
- Provider dispatch and thread event logging are coordinated in `apps/server/src/providerManager.ts`.
- WebSocket server routes NativeApi methods in `apps/server/src/wsServer.ts`.
- Renderer consumes provider event streams via WebSocket push on channel `providers.event`.

Docs:
- Codex App Server docs: https://developers.openai.com/codex/sdk/#app-server
Expand Down
105 changes: 63 additions & 42 deletions README.md
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifier to fenced code block.

The ASCII architecture diagram lacks a language specifier, which triggers a markdownlint warning (MD040). While text or plaintext would satisfy the linter, some renderers also support an empty language or none.

📝 Suggested fix
-```
+```text
 ┌─────────────────────────────────┐
 │  Browser (React + Vite)         │
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
┌─────────────────────────────────┐
│ 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 │
└─────────────────────────────────┘
```
🧰 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
In `@README.md` around lines 11 - 27, Add a language specifier to the fenced code
block containing the ASCII architecture diagram in README.md (e.g., use ```text
or ```plaintext) so the markdown linter MD040 is satisfied; locate the fenced
block that starts with the ASCII box diagram (the Browser/Server/Codex diagram)
and replace the opening ``` with ```text (or ```plaintext) to mark it as plain
text.


## 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 contracts, server, and web dev tasks via Turborepo's parallel task runner.
- `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`.
31 changes: 0 additions & 31 deletions apps/desktop/package.json

This file was deleted.

28 changes: 0 additions & 28 deletions apps/desktop/scripts/dev-electron.mjs

This file was deleted.

84 changes: 0 additions & 84 deletions apps/desktop/scripts/smoke-test.mjs

This file was deleted.

Loading