Skip to content

Commit b15ec11

Browse files
committed
docs: add detailed Codex handoff document
1 parent 3b69ed5 commit b15ec11

1 file changed

Lines changed: 349 additions & 0 deletions

File tree

HANDOFF.md

Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
# CoahCode — Codex Handoff Document
2+
3+
## What This Is
4+
5+
CoahCode is a fork of [T3 Code](https://github.com/pingdotgg/t3code) (Theo's open-source AI coding agent) with a Cursor-grade agent harness bolted on. The harness adds parallel tool execution, MCP server support, LSP integration, skills/rules discovery, scheduled tasks, model switching mid-chat, steering (steer vs queue follow-ups), physics-based thread drag-and-drop, checkpoint snapshots, tool result spilling, skill auto-creation nudges, and mixture-of-agents mode.
6+
7+
**Repo:** https://github.com/coah80/coahcode
8+
**Local path:** `~/Projects/cursor-harness/coahcode-build`
9+
**Status:** Builds clean, dev server runs, 0 type errors. The harness engine is fully built but not yet wired into T3 Code's orchestration layer — it exists as a parallel system that needs integration.
10+
11+
---
12+
13+
## Tech Stack
14+
15+
| Layer | Technology |
16+
|-------|-----------|
17+
| Monorepo | Turborepo |
18+
| Runtime | Bun |
19+
| Server | Effect-TS, SQLite (via `@effect/sql-sqlite-bun`), WebSocket RPC |
20+
| Web | React 19, TanStack Router + Query, Tailwind CSS 4, Vite |
21+
| Desktop | Electron (via `apps/desktop`) |
22+
| AI Providers | Claude Agent SDK (`@anthropic-ai/claude-agent-sdk` v0.2.77), OpenAI Codex CLI |
23+
| Auth | Claude: OAuth via `claude login`. Codex: API key via `codex login` |
24+
25+
---
26+
27+
## Monorepo Structure
28+
29+
```
30+
coahcode-build/
31+
apps/
32+
server/ — Backend (Effect-TS services, SQLite, WebSocket RPC)
33+
src/
34+
provider/ — AI provider adapters (ClaudeAdapter, CodexAdapter)
35+
orchestration/ — Agent state machine (CQRS/event-sourced)
36+
terminal/ — PTY terminal management
37+
git/ — Git operations
38+
persistence/ — SQLite migrations + queries
39+
harness/ — *** OUR CODE *** (agent harness engine)
40+
web/ — Frontend (React, TanStack, Tailwind)
41+
src/
42+
components/ — UI components (chat/, settings/, ui/)
43+
hooks/ — Custom React hooks
44+
lib/ — React Query options, utilities
45+
rpc/ — WebSocket RPC client
46+
routes/ — TanStack Router file-based routes
47+
desktop/ — Electron shell
48+
marketing/ — Marketing site
49+
packages/
50+
contracts/ — Shared TypeScript types, RPC definitions, schemas
51+
shared/ — Shared utilities
52+
```
53+
54+
---
55+
56+
## The Harness (`apps/server/src/harness/`)
57+
58+
This is all our custom code. 18 files, ~2,500 lines.
59+
60+
### File Map
61+
62+
```
63+
harness/
64+
types.ts — All type definitions (ToolName, AgentConfig, AgentEvent, etc.)
65+
index.ts — Barrel exports for everything
66+
67+
engine/
68+
loop.ts — Core agent loop: stream model → collect tool calls → execute in parallel → loop
69+
prompt.ts — System prompt builder (Cursor-style sections)
70+
home.ts — Home workspace: discover projects in ~/Projects, ~/Developer, etc.
71+
scheduler.ts — Cron-based scheduled agent tasks (in-memory, needs persistence)
72+
steering.ts — Steer vs queue follow-up behavior
73+
modelSwitch.ts — Mid-chat model switching (pending switch applied after turn)
74+
skillNudge.ts — Periodic nudges to save reusable skills (every N turns)
75+
resultSpill.ts — Large tool outputs → temp file + preview (50K per-result, 200K per-turn)
76+
checkpoint.ts — Shadow git snapshots before file mutations (~/.coahcode/checkpoints/)
77+
mixtureOfAgents.ts — Fan hard problems to N models in parallel, synthesize answer
78+
79+
providers/
80+
anthropic.ts — Anthropic Messages API streaming with tool use
81+
openai.ts — OpenAI/OpenRouter Chat Completions streaming with tool use
82+
83+
tools/
84+
index.ts — 11 tool implementations + tool definitions
85+
Shell, Read, Write, StrReplace, Delete, Glob, Grep,
86+
ReadLints, TodoWrite, WebSearch, WebFetch
87+
88+
mcp/
89+
client.ts — MCP client: local (stdio) + remote (HTTP) servers
90+
McpManager class with connectAll, getAllTools, callTool
91+
92+
lsp/
93+
client.ts — LSP client: lazy spawn, JSON-RPC over stdio
94+
Built-in: TypeScript, Python, Go, Rust, CSS
95+
getDiagnostics, goToDefinition, hover
96+
97+
skills/
98+
loader.ts — SKILL.md discovery from ~/.claude/skills, ~/.cursor/skills, project dirs
99+
AGENTS.md/CLAUDE.md instruction loading
100+
Exposed as "Skill" tool for the model to call
101+
```
102+
103+
### How the Agent Loop Works (`engine/loop.ts`)
104+
105+
```
106+
1. Discover skills + load instructions from workspace
107+
2. Connect MCP servers (if configured)
108+
3. Build tool list: built-in + MCP + LSP + skills
109+
4. Build system prompt with instructions
110+
5. LOOP:
111+
a. Stream model response (Anthropic or OpenAI)
112+
b. Accumulate text + tool calls
113+
c. If no tool calls → done
114+
d. Checkpoint files about to be mutated (shadow git)
115+
e. Execute ALL tool calls in PARALLEL (Promise.all)
116+
- Route by prefix: mcp_* → MCP, LSP → LSP, Skill → skills, else → built-in
117+
f. Spill oversized results to temp files
118+
g. Append to conversation history
119+
h. Nudge skill/memory creation if enough turns passed
120+
i. Back to (a)
121+
6. Cleanup MCP connections
122+
```
123+
124+
### Key Design Decisions
125+
126+
- **Parallel execution** is the speed secret. All tool calls in a single model turn execute concurrently via `Promise.all`. This matches Cursor's architecture.
127+
- **MCP tools are namespaced** as `mcp_{serverName}_{toolName}` to avoid collisions.
128+
- **Skills are tools, not system prompt** — the model calls `Skill({name: "foo"})` and gets the skill content as tool output. This preserves prompt caching.
129+
- **Checkpoints are invisible** to the model. Shadow git repos in `~/.coahcode/checkpoints/` snapshot files before every Write/StrReplace/Delete.
130+
- **Result spilling** uses a 3-layer budget: per-result 50K chars, per-turn aggregate 200K chars. Oversized outputs get a head/tail preview + file path the model can `Read` later.
131+
132+
---
133+
134+
## Frontend Components We Added
135+
136+
### In `apps/web/src/components/`
137+
138+
| File | What It Does |
139+
|------|-------------|
140+
| `ScheduledTasks.tsx` | CRUD UI for cron-scheduled agent runs. Create/toggle/delete tasks with preset schedules and model picker. Wired to React Query → LocalApi stubs. |
141+
| `WorkspacePicker.tsx` | Search + select project workspaces. Shows git remote info. Create new projects. Wired to React Query → LocalApi stubs. |
142+
| `chat/ModelSwitcher.tsx` | Dropdown to switch models mid-chat. Groups by provider (Anthropic/OpenAI/OpenRouter). Shows tier badges (fast/standard/premium/reasoning). |
143+
| `chat/SteeringIndicator.tsx` | Shows "Steer" or "Queue" mode during active runs. Toggle between modes. |
144+
145+
### In `apps/web/src/hooks/`
146+
147+
| File | What It Does |
148+
|------|-------------|
149+
| `usePhysicsDrag.tsx` | Spring pendulum physics for dragging threads between folders. `DragGhost` component renders SVG string from cursor to dangling card. Uses `requestAnimationFrame` simulation loop. |
150+
151+
### In `apps/web/src/lib/`
152+
153+
| File | What It Does |
154+
|------|-------------|
155+
| `scheduledTasksReactQuery.ts` | TanStack Query options for scheduled tasks CRUD. Uses `ensureLocalApi()`. |
156+
| `workspaceReactQuery.ts` | TanStack Query options for workspace discovery + creation. |
157+
158+
### Branding Changes
159+
160+
- `apps/web/src/index.css` — Primary color changed from blue (hue 264) to purple (hue 303) in both light and dark mode
161+
- `apps/web/src/branding.ts``APP_BASE_NAME` changed to `"CoahCode"`
162+
- `apps/web/index.html` — Title changed to `"CoahCode"`
163+
- `apps/web/src/components/Sidebar.tsx` — Wordmark changed from T3 SVG logo to `<span className="text-primary font-bold">Coah</span>Code`
164+
165+
---
166+
167+
## Contracts Changes (`packages/contracts/src/`)
168+
169+
### `ipc.ts`
170+
- Added `scheduledTasks` and `workspace` namespaces to `LocalApi` interface
171+
- Added `ScheduledTaskInfo`, `ScheduledTaskCreateInput`, `WorkspaceProject` types
172+
173+
### `rpc.ts`
174+
- Added `WS_METHODS` entries: `scheduledTasks.list`, `.create`, `.delete`, `.toggle`, `workspace.discover`, `.create`, `.switch`
175+
- Added `Rpc.make()` definitions for all new methods
176+
- Added all new RPCs to `WsRpcGroup`
177+
178+
---
179+
180+
## What Works Right Now
181+
182+
1. **Build**`bun run build` passes clean (5/5 tasks, 0 errors)
183+
2. **Dev server**`bun run dev` starts web on :5733 and server on :13773
184+
3. **Auth** — Claude via `claude login` OAuth, Codex via API key
185+
4. **Chat** — Full T3 Code chat experience with Claude/Codex
186+
5. **Diffs** — File diff visualization
187+
6. **Terminals** — Integrated terminal sessions
188+
7. **Plan mode** — Plan sidebar with implementation flow
189+
8. **Purple accent** — Throughout light and dark themes
190+
9. **CoahCode branding** — Sidebar, title, settings
191+
10. **Steering indicator** — Shows in composer footer during active runs
192+
11. **ScheduledTasks UI** — Renders in settings page (data is in-memory stubs)
193+
194+
---
195+
196+
## What Needs Wiring (Priority Order)
197+
198+
### 1. Integrate Harness with Orchestration Engine (HIGH)
199+
200+
The harness in `apps/server/src/harness/` is a standalone agent loop. T3 Code has its own orchestration system in `apps/server/src/orchestration/` that manages threads, turns, events, and checkpoints via CQRS/event-sourcing with Effect-TS.
201+
202+
**What needs to happen:**
203+
- Create a `HarnessAdapter` that implements `ProviderAdapterShape` (see `apps/server/src/provider/Services/ProviderAdapter.ts`)
204+
- Register it in `ProviderAdapterRegistry` alongside `ClaudeAdapter` and `CodexAdapter`
205+
- The adapter should use `runAgentLoop()` from our harness engine
206+
- Map harness `AgentEvent` types to T3 Code's `ProviderRuntimeEvent` types
207+
- This lets users choose "CoahCode Harness" as a provider alongside Claude/Codex
208+
209+
**Key files to study:**
210+
- `apps/server/src/provider/Layers/ClaudeAdapter.ts` — Reference implementation
211+
- `apps/server/src/provider/Services/ProviderAdapter.ts` — Interface to implement
212+
- `apps/server/src/provider/Layers/ProviderAdapterRegistry.ts` — Registration
213+
- `apps/server/src/orchestration/Services/OrchestrationEngine.ts` — State machine
214+
215+
### 2. Wire Scheduled Tasks to Persistence (MEDIUM)
216+
217+
Currently `scheduledTasks` in `LocalApi` returns empty stubs. Needs:
218+
- SQLite migration for `scheduled_tasks` table
219+
- Effect service layer for CRUD
220+
- RPC handler in the server's WS handler (`apps/server/src/ws.ts`)
221+
- Wire the `scheduledTasksReactQuery` to use real RPC calls instead of stubs
222+
- Implement the actual scheduler that invokes `runAgentLoop()` on cron triggers
223+
224+
### 3. Wire Workspace Discovery to Real File System (MEDIUM)
225+
226+
Currently `workspace` in `LocalApi` returns empty stubs. Needs:
227+
- RPC handler that calls `discoverProjects()` from `harness/engine/home.ts`
228+
- Wire `workspaceReactQuery` to real RPC calls
229+
- Add workspace switcher to the sidebar (T3 Code already has project add/remove)
230+
231+
### 4. Wire Physics Drag into Sidebar Thread List (LOW)
232+
233+
`usePhysicsDrag.tsx` is built but not connected to the sidebar. Needs:
234+
- Import `usePhysicsDrag` and `DragGhost` in `Sidebar.tsx`
235+
- Add `onMouseDown={startDrag}` to thread items
236+
- Render `DragGhost` at the root level
237+
- Handle `onDrop` to move threads between projects
238+
- `data-drop-zone` attributes are already on project `<Collapsible>` elements
239+
240+
### 5. Wire ModelSwitcher into Composer (LOW)
241+
242+
`ModelSwitcher.tsx` is built but not rendered. T3 Code already has a `ProviderModelPicker` component in the composer footer. Options:
243+
- Replace `ProviderModelPicker` with our `ModelSwitcher` (more models, tier badges)
244+
- Or add `ModelSwitcher` as a secondary picker for mid-chat switching
245+
- Wire the `onSwitch` callback to `requestModelSwitch()` from `harness/engine/modelSwitch.ts`
246+
247+
### 6. Connect MCP Config to UI (LOW)
248+
249+
The harness `McpManager` accepts `McpServerConfig[]`. Needs:
250+
- Settings UI for adding/removing MCP servers (command + args for local, URL for remote)
251+
- Persist config to SQLite or JSON file
252+
- Pass configs to `runAgentLoop()` via `mcpConfigs` option
253+
254+
### 7. Connect LSP Manager Lifecycle (LOW)
255+
256+
The harness `LspManager` spawns LSP servers lazily. Needs:
257+
- Initialize `LspManager` at server startup
258+
- Pass it to `runAgentLoop()` via `lspManager` option
259+
- Clean up on server shutdown
260+
- Optional: settings UI for custom LSP server configs
261+
262+
---
263+
264+
## How to Run
265+
266+
```bash
267+
# Prerequisites: bun, claude login (for Claude), codex login (for Codex)
268+
cd ~/Projects/cursor-harness/coahcode-build
269+
bun install
270+
bun run dev
271+
# Open the pairing URL printed in the terminal
272+
```
273+
274+
## How to Build
275+
276+
```bash
277+
bun run build # Full production build
278+
bun run typecheck # Type checking only
279+
bun run test # Run tests
280+
bun run lint # Lint with oxlint
281+
```
282+
283+
## How to Update from Upstream T3 Code
284+
285+
```bash
286+
git fetch upstream main
287+
git merge upstream/main
288+
# Resolve conflicts (our files are in harness/ and won't conflict with upstream)
289+
# Re-check branding (Sidebar wordmark, index.css colors, branding.ts)
290+
bun run build # Verify
291+
```
292+
293+
---
294+
295+
## Architecture Diagram
296+
297+
```
298+
┌─────────────────────────────────────────────────────┐
299+
│ React Frontend (apps/web) │
300+
│ ├── ChatView + ChatComposer (existing T3 Code) │
301+
│ ├── ModelSwitcher (our addition) │
302+
│ ├── SteeringIndicator (our addition) │
303+
│ ├── ScheduledTasks (our addition) │
304+
│ ├── WorkspacePicker (our addition) │
305+
│ └── usePhysicsDrag (our addition) │
306+
├─────────────────────────────────────────────────────┤
307+
│ WebSocket RPC (packages/contracts/src/rpc.ts) │
308+
├─────────────────────────────────────────────────────┤
309+
│ Server (apps/server) │
310+
│ ├── OrchestrationEngine (existing — CQRS/ES) │
311+
│ ├── ProviderService (existing — routes to adapters) │
312+
│ │ ├── ClaudeAdapter (existing — Claude Agent SDK) │
313+
│ │ ├── CodexAdapter (existing — OpenAI Codex CLI) │
314+
│ │ └── HarnessAdapter (TODO — our harness) │
315+
│ ├── TerminalManager (existing) │
316+
│ ├── GitManager (existing) │
317+
│ └── Harness Engine (our addition) │
318+
│ ├── Agent Loop (parallel tool execution) │
319+
│ ├── Tools (Shell, Read, Write, Grep, etc.) │
320+
│ ├── MCP Client (local + remote servers) │
321+
│ ├── LSP Client (TS, Python, Go, Rust, CSS) │
322+
│ ├── Skills Loader (SKILL.md, AGENTS.md) │
323+
│ ├── Scheduler (cron tasks) │
324+
│ ├── Checkpoints (shadow git snapshots) │
325+
│ ├── Result Spilling (context budget) │
326+
│ ├── Skill Nudges (auto-capture knowledge) │
327+
│ └── Mixture of Agents (multi-model synthesis) │
328+
└─────────────────────────────────────────────────────┘
329+
```
330+
331+
---
332+
333+
## Reference: Cursor Decompilation
334+
335+
All extracted Cursor data is in `~/cursor-decompiled/` (17 files, 176KB). Key files:
336+
- `server-prompts.md` — 7 server-side system prompt variants
337+
- `server-tool-definitions.json` — 19 tool definitions captured from the model
338+
- `harness-architecture.md` — How Cursor's harness achieves its speed
339+
- `EXTRACTION-PLAYBOOK.md` — 14-step guide to re-extract after Cursor updates
340+
341+
The harness architecture in this codebase is modeled after Cursor's BiDi streaming tool loop with parallel execution, as documented in those files.
342+
343+
---
344+
345+
## Key Contacts
346+
347+
- **Original T3 Code:** https://github.com/pingdotgg/t3code (Theo/ping.gg)
348+
- **Cursor decompilation data:** `~/cursor-decompiled/`
349+
- **Memory system:** All project context is logged in mcp-memory (search for "CoahCode" or "cursor-decompiled")

0 commit comments

Comments
 (0)