diff options
Diffstat (limited to 'context.md')
| -rw-r--r-- | context.md | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/context.md b/context.md new file mode 100644 index 0000000..896eed4 --- /dev/null +++ b/context.md @@ -0,0 +1,169 @@ +# Dispatch — Phase 1 Implementation Context + +This file captures all decisions, open questions, and constraints established during planning. It serves as the source of truth for any agent working on Phase 1 implementation. + +--- + +## Stack Decisions + +| Layer | Choice | Notes | +|---|---|---| +| Runtime | **Bun** | Runtime + package manager. Native SQLite, fast installs/execution | +| Backend framework | **Hono.js** | Lightweight, WebSocket support | +| Frontend framework | **Vite + Svelte + DaisyUI** | Strict TypeScript throughout | +| Language | **TypeScript (strict mode)** | Both frontend and backend | +| LLM SDK | **Vercel AI SDK (`ai`)** | Provider-agnostic, streaming, tool calling | +| Default LLM | **DeepSeek V4 Flash Free** | Via OpenCode Go (Zen). Hardcoded for Phase 1 | +| Database | **SQLite (no ORM)** | `bun:sqlite` (native), no Drizzle or other ORM | +| Testing | **Vitest** | Set up across all packages from day one | +| Linting/Formatting | **Biome** | Single tool for both linting and formatting. Confirmed compatible with OpenCode | +| Package Manager | **Bun workspaces** | Monorepo with `@dispatch/*` packages | +| Dev Server | **Separate ports + CORS** | Frontend `:5173`, backend `:3000`, explicit CORS | + +--- + +## Resolved Decisions + +### Streaming Architecture: WebSocket Only +All real-time communication flows over a single WebSocket connection: +- Chat messages (user -> server) +- Streaming LLM tokens (server -> client) +- Tool call notifications and results (server -> client) +- Agent status updates (server -> client) + +`POST /chat` is not a streaming endpoint — it just queues/sends a message. The WebSocket handles all real-time data. `GET /status` remains as a simple REST endpoint for polling agent state. + +### Database: SQLite Without ORM +No Drizzle ORM. Use `better-sqlite3` (or equivalent) directly with raw SQL. Keep it simple. The question of whether to set up persistence in Phase 1 or defer to Phase 5 is still open — the user indicated willingness to use SQLite but the timing wasn't finalized. **Default assumption: defer heavy persistence to Phase 5, but the library choice is locked in.** + +### Tool Scoping: Working Directory +File tools (`read_file`, `write_file`, `list_files`) will be scoped to a configurable working directory from Phase 1. This prevents accidental filesystem damage and provides a clean foundation for the permission system in Phase 2. + +### Testing: Vitest From Day One +Vitest set up across the monorepo. Unit tests for core logic (agent loop, tool registry, individual tools). + +### DaisyUI Theme: Configurable With Persistence +Support multiple DaisyUI themes with a user-selectable theme switcher in settings. The selected theme is remembered across sessions (localStorage or equivalent). + +### Default LLM Provider: DeepSeek V4 Flash via OpenRouter +The Phase 1 hardcoded model is DeepSeek V4 Flash, accessed through OpenRouter. This means: +- The Vercel AI SDK OpenRouter provider will be used +- A single `OPENROUTER_API_KEY` env var (or equivalent) is needed +- Model ID will be the OpenRouter model string for DeepSeek V4 Flash + +--- + +## Resolved Decisions (Previously Open Questions) + +### 1. Package Manager and Monorepo Tooling: Bun Workspaces +**Decision:** Bun as both runtime and package manager, using Bun workspaces. + +Bun workspaces work similarly to pnpm workspaces — `packages/core`, `packages/api`, and `packages/frontend` reference each other as `@dispatch/*` dependencies, and Bun symlinks them locally. + +### 2. Runtime: Bun +**Decision:** Bun is the runtime. + +Implications: +- Native SQLite via `bun:sqlite` — no need for `better-sqlite3` +- Bun is faster for installs, script execution, and testing +- Vitest is the test runner (works with Bun) +- No Node.js version to manage + +### 3. Dev Server Setup: Separate Ports + CORS +**Decision:** Frontend on `:5173` (Vite dev server), backend on `:3000` (Hono). Explicit CORS configuration on the backend. + +This means: +- Hono backend needs CORS middleware allowing the frontend origin +- WebSocket connections go directly to `:3000` from the frontend +- No Vite proxy configuration needed +- Production will also be cross-origin (matches the split deployment model) + +### 4. Biome Compatibility: Confirmed +**Decision:** Biome is fully compatible with OpenCode. + +OpenCode has Biome as a **built-in formatter**. It auto-detects `biome.json(c)` config files and handles `.js`, `.jsx`, `.ts`, `.tsx`, `.html`, `.css`, `.md`, `.json`, `.yaml`, and more. Just needs a `biome.json` in the project root and formatters enabled in OpenCode config (`"formatter": true` or `"formatter": {}`). + +--- + +## Phase 1 Scope (from plan.md) + +**Goal:** Chat with one agent in a browser, watch it read and write files. + +### Backend Tasks +- Project scaffolding (monorepo with `packages/core`, `packages/api`, `packages/frontend`) +- Agent runtime: message -> LLM -> tool call -> result -> repeat loop +- Vercel AI SDK integration with streaming responses +- Single provider config (DeepSeek V4 Flash via OpenRouter, env var for API key) +- Basic tools: + - `read_file` — read file contents (scoped to working directory) + - `write_file` — write/overwrite a file (scoped to working directory) + - `list_files` — glob/list directory contents (scoped to working directory) +- HTTP API: + - `POST /chat` — send a message (non-streaming, queues to agent) + - `GET /status` — agent status (idle, running, etc.) +- WebSocket: stream agent output tokens and tool calls in real-time + +### Frontend Tasks +- Single chat panel — text input field, send button +- Streamed response rendering (tokens appear as they arrive via WebSocket) +- Tool call display (collapsible: show tool name, arguments, result) +- Model/provider indicator in header +- Basic layout: chat takes full screen, clean and minimal +- Theme switcher in settings (DaisyUI themes, persisted to localStorage) + +### Done When +Open a browser, type "read the contents of package.json and summarize it," see the agent call `read_file`, stream back a summary. Ask it to create a new file — it calls `write_file` and confirms. + +--- + +## Project Structure (Planned) + +``` +dispatch/ + packages/ + core/ # Agent runtime, LLM integration, tools + src/ + agent/ # Agent loop, lifecycle + llm/ # Vercel AI SDK wrapper, provider config + tools/ # Tool registry, built-in tools (read_file, write_file, list_files) + types/ # Shared TypeScript types + tests/ + api/ # Hono HTTP + WebSocket server + src/ + routes/ # HTTP route handlers + ws/ # WebSocket handlers + tests/ + frontend/ # Vite + Svelte + DaisyUI client + src/ + lib/ # Svelte components, stores, utilities + routes/ # Page routes (if using SvelteKit) or views + tests/ + biome.json # Biome config (pending compatibility check) + tsconfig.base.json # Shared TypeScript config + package.json # Root workspace config + .env.example # Environment variables template (OPENROUTER_API_KEY, etc.) +``` + +--- + +## Concurrency Map (What Can Be Built in Parallel) + +Once scaffolding is complete, the following sections can be developed concurrently: + +``` +[A] Scaffolding (sequential — must be first) + | + +---> [B] Core Agent Runtime (agent loop, LLM, tool system) + | + +---> [C] API Server Shell (Hono setup, route stubs, WebSocket setup) + | + +---> [D] Frontend Shell (Svelte app, chat UI, WebSocket client, theme system) + +Then integration (sequential — depends on B, C, D): + +[E] Wire core into API (connect agent runtime to routes/WebSocket) +[F] Wire frontend to API (connect UI to live WebSocket) +[G] End-to-end testing and polish +``` + +Sections B, C, and D are independent and can be coded by concurrent agents. Section E requires B and C. Section F requires C and D. Section G requires everything. |
