summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-05 18:40:28 +0900
committerAdam Malczewski <[email protected]>2026-06-05 18:40:28 +0900
commit368be032ef57638b558db659d70bfac00cb95cdd (patch)
tree61cf47e43e8d44bec2fe4e5e67c2d150df5ea0a5
parentcdd54554f575ad9d2b19015c565aab6ffd683be6 (diff)
downloaddispatch-368be032ef57638b558db659d70bfac00cb95cdd.tar.gz
dispatch-368be032ef57638b558db659d70bfac00cb95cdd.zip
docs: reorder roadmap — CLI first, then web frontend, then dedup/storage
User-set ordering: (1) CLI MVP (line-oriented, NOT a TUI; may have basic selectors; same mirrored-backend methodology with a careful design pass first — seed at notes/cli-design.md), (2) web frontend (Svelte + DaisyUI, notes/frontend-design.md), (3) dedup/storage growth. CLI design seed frames the same open questions as the web FE (pure-core/shell split, unit boundaries, transport, testing) adapted to a terminal client.
-rw-r--r--notes/cli-design.md58
-rw-r--r--tasks.md30
2 files changed, 75 insertions, 13 deletions
diff --git a/notes/cli-design.md b/notes/cli-design.md
new file mode 100644
index 0000000..2ba66d4
--- /dev/null
+++ b/notes/cli-design.md
@@ -0,0 +1,58 @@
+# CLI — Design Scratch
+
+> **Status:** IDEATION / scratch. NOT decided, NOT building yet. This is the HOME for the
+> CLI design pass (per user: **CLI first, then web frontend**). Promote settled parts into
+> `notes/restructure-plan.md` + harness files when we commit to building.
+>
+> **Read order (fresh agent picking this up):** `ORCHESTRATOR.md` → `AGENTS.md` (the
+> backend methodology we are MIRRORING) → `GLOSSARY.md` → this file.
+> **Mode = IDEATION WITH the user** (design/discuss, do NOT build yet). The user owns the
+> boundary (§5.2) + vocabulary (§5.6) calls.
+> **Constraints:** line-oriented CLI (NOT a TUI); may have basic selectors for e.g.
+> picking a conversation, but standard/basic stuff only. Same methodology as the backend
+> (minimal core, pure-core/inject-effects, typed contracts, one owner per unit,
+> asymmetric testing).
+
+---
+
+## 0. Goal
+A terminal CLI client for Dispatch: send a message, stream the multi-turn response
+(`conversationId`). Interactive: you're in a chat session, type a line, hit enter, see
+the streamed response line-by-line.
+
+## 1. Hard constraints (mirroring the backend methodology)
+- **Minimal core + feature modules.** Core = message loop + transport client + state
+ manager; features = output renderers, conversation picker, etc. Core never references
+ a concrete output mechanism directly — injected.
+- **Typed contracts as the only cross-unit surface.** Cross-module coupling anchored to
+ typed symbols (no string keys). The CLI↔backend seam is the `AgentEvent` union +
+ `/chat` NDJSON stream — ideally a shared typed contract so `lsp references` spans the
+ boundary.
+- **Pure-core / inject-effects / no ambient state.** Pure functions for every decision
+ (format output, merge state, parse input), zero I/O; the shell = `readline`/`stdin` +
+ `fetch` transport + `stdout`/`process.stdout.write` + filesystem — all injected.
+- **One owner per unit; asymmetric testing** — strict zero-internal-mock on pure logic;
+ lenient integration on the shell.
+
+## 2. Open questions (DECIDE in the design pass)
+- **Pure-core / shell split:** what's pure (message formatting, state reducer, event
+ parser) vs. what's the shell (readline, fetch/stream, stdout, ANSI/colour).
+- **Unit boundaries / first units:** transport client, message-loop engine, output
+ renderer, conversation store (persisted across sessions?). Granularity = USER's call.
+- **Conversation management:** list recent, pick one, start new — basic selectors (arrow
+ keys + enter, or numbered list). In-memory vs. a small local store.
+- **Output rendering:** streaming is incremental (ProviderEvent deltas → printed as they
+ arrive); tool calls / thinking — how to render (collapsible? plain text? ANSI
+ indentation?).
+- **Transport:** reuse the same `/chat` NDJSON fetch+ReadableStream path the web FE
+ would use. `trace-replay` could even feed CLI transport tests hermetically.
+- **Persistence:** remember the active `conversationId` across sessions? history? simple
+ JSON file or the conversation-store extension via HTTP.
+- **Testing tools:** vitest for pure logic (already in repo); shell integration tests
+ via PTY / spawned process? Or keep it thin-integration only (asymmetric).
+- **Monorepo placement:** `packages/cli/` — run as `bun packages/cli/src/main.ts`.
+- **Harness artifacts:** `.dispatch/rules/cli-*.md`, GLOSSARY terms (no synonym-drift),
+ ORCHESTRATOR additions for CLI summons.
+
+## 3. Decisions settled
+- (none yet — IDEATION.)
diff --git a/tasks.md b/tasks.md
index 51c1d13..fe88001 100644
--- a/tasks.md
+++ b/tasks.md
@@ -287,22 +287,26 @@ reports/phase-a-{kernel-logging,journal-sink}.md.
## ROADMAP — what's next (user-decided, §5.2)
-### Next: Frontend MVP
-Svelte + DaisyUI (same stack as old Dispatch). **Careful design pass FIRST** — the FE
-must be built with the SAME methodology as the backend (minimal core + feature modules,
-typed contracts as the only cross-unit surface, pure-core / inject-effects / no ambient
-state, one owner per unit, asymmetric testing). A dedicated design scratch lives at
-`notes/frontend-design.md` (IDEATION mode — design WITH the user before any summon).
-
-The old Dispatch frontend (`/home/tradam/projects/dispatch/dispatch-source`) is
+### 1. CLI (first, before web frontend)
+A **CLI** (NOT a TUI — line-oriented command-line interface; may have basic selectors
+for things like picking a conversation). Terminal client for Dispatch: send a message,
+render the streamed multi-turn response (`conversationId` threads history). Same
+methodology constraint as the backend: pure core (zero I/O) / inject effects / no ambient
+state / typed contracts / one owner per unit / asymmetric testing. A design pass FIRST
+— seed `notes/cli-design.md` (IDEATION with the user, like `notes/observability-design.md`
+and `notes/frontend-design.md`) before any summon.
+
+### 2. Web frontend (after CLI)
+Svelte + DaisyUI (same stack as old Dispatch). **Methodology mirror** — same constraints
+as the backend and the CLI. Design scratch lives at `notes/frontend-design.md` (IDEATION
+mode). Old Dispatch FE (`/home/tradam/projects/dispatch/dispatch-source`) is
REFERENCE-ONLY for UX/tech — do NOT copy its architecture. Port `FRONTEND_PORT=24204` is
-reserved in `.env`. When frontend BUILD begins: retire the AGENTS.md "Backend only for
-now (no frontend)" line, author new scoped `.dispatch/rules/frontend-*.md`, and update
+reserved in `.env`. When FE build begins: retire the AGENTS.md "Backend only for now (no
+frontend)" line, author new scoped `.dispatch/rules/frontend-*.md`, and update
ORCHESTRATOR.md §7 (repo geography) + §3 (rule scoping map).
-### After Frontend MVP: dedup / storage growth
+### 3. dedup / storage growth (after frontend)
The deferred trace-body de-duplication + rotation/compression (D5 volume-control +
`prefix.fingerprint` + §6 retention strategy) — already designed in
`notes/observability-design.md`, not yet built. `cacheReadTokens` (committed) is the
-cheap dedup signal; the workspace is ready. Prioritized AFTER the frontend per user
-roadmap.
+cheap dedup signal; the workspace is ready.