diff options
| author | Adam Malczewski <[email protected]> | 2026-06-12 00:22:42 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-12 00:22:42 +0900 |
| commit | fd565a6555e8bc9f37f21cf9d900523ef3be531b (patch) | |
| tree | ecf2c365c0c5e0ccdfc1a9ae350af933e4860ed2 /.dispatch | |
| parent | e45cab2a2d9d7bf5e48ace7111fd84b1b9bf2df3 (diff) | |
| download | dispatch-web-fd565a6555e8bc9f37f21cf9d900523ef3be531b.tar.gz dispatch-web-fd565a6555e8bc9f37f21cf9d900523ef3be531b.zip | |
feat(workspace,smart-scroll): per-conversation cwd + LSP view; smart auto-scroll
workspace ([email protected]): a cwd field in the Model sidebar view (GET/PUT /conversations/:id/cwd) + a new 'Language Servers' view (GET /conversations/:id/lsp) with per-server connected/starting/error badges, spinner, error text, and refresh. Store-owned reactive cwd, re-seeded on focus change; works for DRAFTS too (targets the draft's client-minted id, which survives promotion, so turn 1 runs in the chosen cwd). Network seam normalizes the untyped LSP body.
smart-scroll: pure stick-to-bottom reducer + injected controller shell (scroll/scrollend + a ResizeObserver on the content so the view follows async height changes — markdown/highlight, images, collapses, viewport reflow), plus a floating scroll-to-bottom button. FIX: restore the transcript scrollbar — the refactor moved overflow-y-auto to an inner child, so the flex-1 container needed min-h-0 to constrain instead of growing to content.
harness: vitest-setup polyfills Element.scrollTo + ResizeObserver (jsdom implements neither), fixing App component tests. docs: backend-handoff pruned (CR-3 resolved/removed); added cwd/LSP verification courier (backend confirmed all 6 asks ✅); removed the resolved cache-warming-timer courier.
Verified: svelte-check 0 errors, biome clean, 523 tests pass, vite build OK.
Diffstat (limited to '.dispatch')
| -rw-r--r-- | .dispatch/transport-contract.reference.md | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/.dispatch/transport-contract.reference.md b/.dispatch/transport-contract.reference.md index 08f07ce..c2e2076 100644 --- a/.dispatch/transport-contract.reference.md +++ b/.dispatch/transport-contract.reference.md @@ -23,6 +23,16 @@ > `cache-warming-timer` payload + second "cache retention" `stat` ride the EXISTING `custom`/`stat` > kinds; the FE cache-warming feature parses them.) > +> **2026-06-11 delta (LSP + cwd handoff — package bumped to `0.5.0`):** adds per-conversation working +> directory `GET /conversations/:id/cwd` + `PUT /conversations/:id/cwd` (`CwdResponse`/`SetCwdRequest`, +> CORS now allows `PUT`) and per-conversation LSP status `GET /conversations/:id/lsp` +> (`LspStatusResponse`/`LspServerInfo`/`LspServerState`). The LSP GET LAZILY spawns+initializes the +> configured servers (can take a moment the first time per cwd; cached after) and returns once each +> server settles to `connected`/`error`. `servers` is `[]` when `cwd` is null. A `/chat`(`/warm`) +> request that omits `cwd` now defaults to the conversation's persisted cwd; one that sends `cwd` +> persists it. Consumed FE-side by the `workspace` feature (cwd field in the Model view + a +> "Language Servers" view). +> > **0.3.0 change (token + timing metrics):** adds the durable metrics READ endpoint > `GET /conversations/:id/metrics` → `ConversationMetricsResponse` (`{ turns: TurnMetrics[] }`), and > re-exports `StepMetrics` / `TurnMetrics` from `@dispatch/wire`. This is a SEPARATE read axis from @@ -48,6 +58,12 @@ missing/invalid `conversationId`. The warm is NEVER persisted/streamed/folded into real usage. - `GET /metrics/throughput?period=day|week|month&date=<...>` — `ThroughputResponse` (token-weighted tokens/sec per model over the window). Not part of cache-warming; listed for completeness. +- `GET /conversations/:id/cwd` — `CwdResponse` (`cwd` is `null` until set). +- `PUT /conversations/:id/cwd` — body `SetCwdRequest` → `200 CwdResponse`; `400 { error }` if `cwd` + missing/empty. CORS allows `PUT`. +- `GET /conversations/:id/lsp` — `LspStatusResponse`. LAZILY spawns+initializes the configured servers + on the first call per cwd (can take a moment; cached after); returns once each settles to + `connected`/`error`. `servers` is `[]` when `cwd` is null. - WebSocket on :24205 — ONE path-agnostic socket multiplexes surface ops (`@dispatch/ui-contract`) + chat ops (below). Open once, send `WsClientMessage`, receive `WsServerMessage`. Live `AgentEvent` deltas carry `conversationId`+`turnId` but **no `seq`** @@ -192,6 +208,49 @@ export interface WarmResponse { readonly expectedCacheRate: number; } +// ─── Per-conversation working directory (cwd) ───────────────────────────────── + +/** Response of `GET /conversations/:id/cwd`. `cwd` is null when never set. */ +export interface CwdResponse { + readonly conversationId: string; + readonly cwd: string | null; +} + +/** Body of `PUT /conversations/:id/cwd`. */ +export interface SetCwdRequest { + readonly cwd: string; +} + +// ─── Per-conversation LSP status ────────────────────────────────────────────── + +/** The connection state of a single language server for a workspace. */ +export type LspServerState = "connected" | "starting" | "error" | "not-started"; + +/** One language server's status as reported to the frontend. */ +export interface LspServerInfo { + /** Stable server id, e.g. "typescript", "luau-lsp". */ + readonly id: string; + /** Human-readable display name. */ + readonly name: string; + /** The resolved workspace root the server is (or would be) rooted at (absolute). */ + readonly root: string; + /** File extensions this server handles, e.g. [".ts", ".tsx"] or [".luau"]. */ + readonly extensions: readonly string[]; + /** Current connection state. */ + readonly state: LspServerState; + /** Present only when `state === "error"`: a short human-readable reason. */ + readonly error?: string; +} + +/** Response of `GET /conversations/:id/lsp`. */ +export interface LspStatusResponse { + readonly conversationId: string; + /** The conversation's persisted cwd, or null if unset (then `servers` is empty). */ + readonly cwd: string | null; + /** The language servers configured for `cwd` and their live state. */ + readonly servers: readonly LspServerInfo[]; +} + // ─── WebSocket chat ops ─────────────────────────────────────────────────────── // The persistent WS connection multiplexes chat ops (below) with surface ops // (`@dispatch/ui-contract`). Chat `type`s are namespaced (`chat.*`) so they |
