summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.dispatch/package-agent.md17
-rw-r--r--.dispatch/transport-contract.reference.md125
-rw-r--r--.dispatch/wire.reference.md247
-rw-r--r--backend-handoff.md67
-rw-r--r--bun.lock17
-rw-r--r--package.json9
6 files changed, 476 insertions, 6 deletions
diff --git a/.dispatch/package-agent.md b/.dispatch/package-agent.md
index a5666e4..c98b326 100644
--- a/.dispatch/package-agent.md
+++ b/.dispatch/package-agent.md
@@ -23,11 +23,18 @@ it, test it, and write a report — nothing else. If no single unit is named, st
## What you may read (visibility)
- **Your own unit:** every file, freely.
-- **The contract you consume:** reproduced IN-REPO at
- `.dispatch/ui-contract.reference.md` — read THAT. Your code imports
- `@dispatch/ui-contract` normally, but **do NOT read `node_modules/@dispatch/*`** — it
- symlinks to the backend repo (OUTSIDE this repo) and a headless permission prompt will
- HANG the run (see "Headless read boundary").
+- **The contracts you consume:** reproduced IN-REPO under `.dispatch/*.reference.md` — read THOSE:
+ - `.dispatch/ui-contract.reference.md` — `@dispatch/ui-contract` (surfaces + surface WS protocol).
+ - `.dispatch/wire.reference.md` — `@dispatch/wire` (`Chunk`/`StoredChunk`+`seq`/`ChatMessage`/
+ `AgentEvent`/`TurnSealedEvent`/`Usage` — the chat wire types).
+ - `.dispatch/transport-contract.reference.md` — `@dispatch/transport-contract` (HTTP endpoints +
+ `ChatRequest`/`ModelsResponse`/`ConversationHistoryResponse` + WS chat ops + the unified
+ `WsClientMessage`/`WsServerMessage` unions).
+
+ Your code imports `@dispatch/ui-contract` / `@dispatch/wire` / `@dispatch/transport-contract`
+ normally, but **do NOT read `node_modules/@dispatch/*`** — they symlink to the backend repo
+ (OUTSIDE this repo) and a headless permission prompt will HANG the run (see "Headless read
+ boundary").
- **Sibling units — PUBLIC SURFACE only:** their `index.ts` exports. Don't read
their internals (needing them ⇒ the contract is incomplete → report a CR).
diff --git a/.dispatch/transport-contract.reference.md b/.dispatch/transport-contract.reference.md
new file mode 100644
index 0000000..3a7a59c
--- /dev/null
+++ b/.dispatch/transport-contract.reference.md
@@ -0,0 +1,125 @@
+# `@dispatch/transport-contract` — in-repo reference (read THIS, not node_modules)
+
+> MIRRORS the backend's `@dispatch/transport-contract` package source so headless FE agents can read
+> the HTTP + WebSocket wire shapes WITHOUT following the `file:` dep symlink out of this repo (which
+> hangs on a permission prompt). Your CODE still imports `@dispatch/transport-contract` normally —
+> this file is for READING only.
+>
+> **Orchestrator:** SNAPSHOT of `[email protected]`. Regenerate whenever it changes.
+> Depends on `@dispatch/wire` (see `wire.reference.md`) + `@dispatch/ui-contract`
+> (see `ui-contract.reference.md`).
+
+## Endpoints (backend, confirmed live — CORS wildcard `*`, HTTP port 24203, WS port 24205)
+
+- `POST /chat` — body `ChatRequest` (JSON); response NDJSON stream, one `AgentEvent` per line;
+ resolved id also in `X-Conversation-Id` header.
+- `GET /models` — `ModelsResponse`.
+- `GET /conversations/:id?sinceSeq=<n>` — `ConversationHistoryResponse`: RAW, append-order,
+ seq-ordered slice with `seq > n` (NOT reconciled — dangling tool-calls returned as-is).
+ `latestSeq` = last chunk's `seq`, or the requested `sinceSeq` when caught up (empty `chunks`).
+- 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`**
+ (seq lives only on `StoredChunk`, obtained via the `sinceSeq` sync after `turn-sealed`).
+- DEFERRED (not built; do not depend on): `GET /conversations` (list), `POST /conversations/:id/cancel`.
+
+```ts
+/**
+ * Transport contract — the typed description of Dispatch's client–server API
+ * (HTTP + WebSocket). Types-only (zero runtime). Each side owns its own
+ * (de)serialization — the contract is the SHAPES, not the codec.
+ *
+ * The WebSocket carries BOTH chat ops (here) and surface ops (in
+ * `@dispatch/ui-contract`) over one connection; the unified `WsClientMessage` /
+ * `WsServerMessage` unions below compose them. Chat ops are new, non-colliding
+ * `type` variants (`chat.*`) — the shipped surface protocol is unchanged.
+ */
+
+import type { SurfaceClientMessage, SurfaceServerMessage } from "@dispatch/ui-contract";
+import type { AgentEvent, StoredChunk } from "@dispatch/wire";
+
+export type { AgentEvent, StoredChunk } from "@dispatch/wire";
+
+/**
+ * Request body for `POST /chat` (sent as JSON).
+ *
+ * The response is an NDJSON stream: one JSON-encoded `AgentEvent` per line.
+ * The resolved conversation id is also returned in the `X-Conversation-Id`
+ * response header (useful when `conversationId` was omitted).
+ */
+export interface ChatRequest {
+ /** The conversation to continue. Omit to start fresh — server mints an id (X-Conversation-Id). */
+ readonly conversationId?: string;
+ /** The user's message text for this turn. */
+ readonly message: string;
+ /** Model name in `<credentialName>/<model>` form (one of `GET /models`). Omit = server default. */
+ readonly model?: string;
+ /** Working directory for this turn's tool execution. Defaults server-side. Not part of the prompt. */
+ readonly cwd?: string;
+}
+
+/**
+ * Response body for `GET /models` — the model catalog. Each entry is a model
+ * name in `<credentialName>/<model>` form (exactly `ChatRequest.model`).
+ */
+export interface ModelsResponse {
+ readonly models: readonly string[];
+}
+
+/**
+ * Response body for `GET /conversations/:id?sinceSeq=<n>` — the incremental
+ * read-side history endpoint a long-lived client uses to (re)hydrate cheaply.
+ *
+ * `chunks` is the RAW, append-order, seq-ordered slice with `seq > sinceSeq`
+ * (or the whole log when `sinceSeq` is omitted/0). NOT reconciled: a dangling
+ * tool-call is returned as-is. `latestSeq` is the `seq` of the LAST chunk, or —
+ * when the slice is empty (caught up) — the requested `sinceSeq` (0 for a full
+ * read of an empty conversation). After applying, the client's new cursor is
+ * always `latestSeq`; empty `chunks` means "nothing new past your cursor".
+ */
+export interface ConversationHistoryResponse {
+ readonly chunks: readonly StoredChunk[];
+ readonly latestSeq: number;
+}
+
+// ─── 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
+// never collide with surface ones.
+
+/**
+ * Client → server: start or continue a turn over the WS connection. Same fields
+ * as the HTTP `ChatRequest`; omit `conversationId` to start fresh — the resolved
+ * id arrives on the streamed `AgentEvent`s (each carries `conversationId`).
+ */
+export interface ChatSendMessage extends ChatRequest {
+ readonly type: "chat.send";
+}
+
+/**
+ * Server → client: one `AgentEvent` from an in-flight turn (text-delta,
+ * tool-call, usage, done, turn-sealed, …). Fold these into the transcript
+ * exactly as the HTTP NDJSON stream — same events, different carrier.
+ */
+export interface ChatDeltaMessage {
+ readonly type: "chat.delta";
+ readonly event: AgentEvent;
+}
+
+/**
+ * Server → client: a chat-scoped TRANSPORT error — e.g. a malformed `chat.send`
+ * or a failure before a turn could start. (Errors DURING a turn arrive as a
+ * `TurnErrorEvent` inside a `chat.delta`.)
+ */
+export interface ChatErrorMessage {
+ readonly type: "chat.error";
+ readonly conversationId?: string;
+ readonly message: string;
+}
+
+/** Every client → server WS message: surface ops + chat ops. Discriminate on `type`. */
+export type WsClientMessage = SurfaceClientMessage | ChatSendMessage;
+
+/** Every server → client WS message: surface ops + chat ops. Discriminate on `type`. */
+export type WsServerMessage = SurfaceServerMessage | ChatDeltaMessage | ChatErrorMessage;
+```
diff --git a/.dispatch/wire.reference.md b/.dispatch/wire.reference.md
new file mode 100644
index 0000000..ccf07bd
--- /dev/null
+++ b/.dispatch/wire.reference.md
@@ -0,0 +1,247 @@
+# `@dispatch/wire` — in-repo reference (read THIS, not node_modules)
+
+> MIRRORS the backend's `@dispatch/wire` package source so headless FE agents can read the wire
+> types WITHOUT following the `file:` dep symlink out of this repo (which hangs on a permission
+> prompt). Your CODE still imports `@dispatch/wire` normally — this file is for READING only.
+>
+> **Orchestrator:** SNAPSHOT of `[email protected]`. Regenerate whenever `@dispatch/wire` changes.
+
+```ts
+/**
+ * @dispatch/wire — pure wire types shared by the kernel, the transport
+ * contract, and out-of-repo clients (the web frontend).
+ *
+ * Types ONLY: zero runtime, zero `@dispatch/*` dependencies, so a client can
+ * depend on the wire without pulling the kernel runtime.
+ */
+
+// ─── Conversation model ─────────────────────────────────────────────────────
+
+/** Who produced a message. */
+export type Role = "system" | "user" | "assistant" | "tool";
+
+/** Opaque identifier for a turn (one user→assistant cycle). */
+export type TurnId = string & { readonly __brand: "TurnId" };
+
+/** Opaque identifier for a step (one LLM round-trip within a turn). */
+export type StepId = string & { readonly __brand: "StepId" };
+
+/**
+ * A chunk is one ordered piece of a message — the atomic unit of the
+ * append-only conversation log. Discriminated by `type`.
+ */
+export type Chunk =
+ | TextChunk
+ | ThinkingChunk
+ | ToolCallChunk
+ | ToolResultChunk
+ | ErrorChunk
+ | SystemChunk;
+
+/** A piece of plain text content from the assistant or user. */
+export interface TextChunk {
+ readonly type: "text";
+ readonly text: string;
+}
+
+/** A piece of model reasoning / thinking content (e.g. extended thinking). */
+export interface ThinkingChunk {
+ readonly type: "thinking";
+ readonly text: string;
+}
+
+/**
+ * A model's request to run a tool. The kernel routes by `name`; the tool
+ * implementation never sees this directly — it receives parsed `input` via
+ * `ToolContract.execute`.
+ */
+export interface ToolCallChunk {
+ readonly type: "tool-call";
+ readonly toolCallId: string;
+ readonly toolName: string;
+ readonly input: unknown;
+}
+
+/**
+ * The result of a tool execution, attributed to the originating tool-call id.
+ * The kernel guarantees every tool-call chunk gets exactly one result chunk
+ * (synthesized if interrupted — see reconcile).
+ */
+export interface ToolResultChunk {
+ readonly type: "tool-result";
+ readonly toolCallId: string;
+ readonly toolName: string;
+ readonly content: string;
+ readonly isError: boolean;
+}
+
+/** An error that occurred during generation or tool dispatch. */
+export interface ErrorChunk {
+ readonly type: "error";
+ readonly message: string;
+ readonly code?: string;
+}
+
+/**
+ * A system-injected message (e.g. system prompt, context assembly output).
+ * Kept distinct from text so the log records provenance.
+ */
+export interface SystemChunk {
+ readonly type: "system";
+ readonly text: string;
+}
+
+/**
+ * A chat message: a role plus an ordered sequence of chunks. Messages are the
+ * unit passed to and from the provider; chunks are the unit persisted and
+ * rendered.
+ */
+export interface ChatMessage {
+ readonly role: Role;
+ readonly chunks: readonly Chunk[];
+}
+
+/**
+ * A persisted chunk plus its sync metadata. The append-only conversation log
+ * stamps every chunk with a monotonic, gap-free, per-conversation `seq` (the
+ * sync cursor, assigned in append order) and records the `role` of the message
+ * it belongs to. This makes a flat seq-ordered stream both incrementally
+ * syncable ("give me chunks after seq N") and regroupable into messages by the
+ * client. `chunk` is the pure content unit, unchanged — `Chunk` itself never
+ * carries storage metadata (it is also passed to/from the provider, which has
+ * no use for a cursor).
+ */
+export interface StoredChunk {
+ readonly seq: number;
+ readonly role: Role;
+ readonly chunk: Chunk;
+}
+
+// ─── Usage ──────────────────────────────────────────────────────────────────
+
+/**
+ * Token usage counters for a single step. All fields are counts of tokens.
+ * Cache fields are optional because not all providers expose cache metrics.
+ */
+export interface Usage {
+ readonly inputTokens: number;
+ readonly outputTokens: number;
+ readonly cacheReadTokens?: number;
+ readonly cacheWriteTokens?: number;
+}
+
+// ─── Outward events ─────────────────────────────────────────────────────────
+
+/**
+ * The union of all events the runtime emits outward during a turn.
+ * Consumers (transport, persistence, notifications) pattern-match on `type`.
+ */
+export type AgentEvent =
+ | StatusEvent
+ | TurnStartEvent
+ | TurnTextDeltaEvent
+ | TurnReasoningDeltaEvent
+ | TurnToolCallEvent
+ | TurnToolResultEvent
+ | TurnToolOutputEvent
+ | TurnUsageEvent
+ | TurnErrorEvent
+ | TurnDoneEvent
+ | TurnSealedEvent;
+
+/** Status change for a conversation (e.g. idle → running). */
+export interface StatusEvent {
+ readonly type: "status";
+ readonly conversationId: string;
+ readonly status: string;
+}
+
+/** A turn has begun. */
+export interface TurnStartEvent {
+ readonly type: "turn-start";
+ readonly conversationId: string;
+ readonly turnId: string;
+}
+
+/** Incremental text content from the model during a turn. */
+export interface TurnTextDeltaEvent {
+ readonly type: "text-delta";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly delta: string;
+}
+
+/** Incremental reasoning / thinking content during a turn. */
+export interface TurnReasoningDeltaEvent {
+ readonly type: "reasoning-delta";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly delta: string;
+}
+
+/** The model has requested a tool to be run. */
+export interface TurnToolCallEvent {
+ readonly type: "tool-call";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly toolCallId: string;
+ readonly toolName: string;
+ readonly input: unknown;
+}
+
+/** A tool has completed execution. */
+export interface TurnToolResultEvent {
+ readonly type: "tool-result";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly toolCallId: string;
+ readonly toolName: string;
+ readonly content: string;
+ readonly isError: boolean;
+}
+
+/** Streaming output from a tool execution (e.g. shell stdout/stderr). */
+export interface TurnToolOutputEvent {
+ readonly type: "tool-output";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly toolCallId: string;
+ readonly data: string;
+ readonly stream: "stdout" | "stderr";
+}
+
+/** Token usage for the current step or turn. */
+export interface TurnUsageEvent {
+ readonly type: "usage";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly usage: Usage;
+}
+
+/** An error occurred during the turn. */
+export interface TurnErrorEvent {
+ readonly type: "error";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly message: string;
+ readonly code?: string;
+}
+
+/** The turn has completed (model finished generating). */
+export interface TurnDoneEvent {
+ readonly type: "done";
+ readonly conversationId: string;
+ readonly turnId: string;
+ readonly reason: string;
+}
+
+/**
+ * The turn has been sealed — all chunks persisted, history is final.
+ * This is the hook point for post-turn extensions (compaction, cache-warm).
+ */
+export interface TurnSealedEvent {
+ readonly type: "turn-sealed";
+ readonly conversationId: string;
+ readonly turnId: string;
+}
+```
diff --git a/backend-handoff.md b/backend-handoff.md
new file mode 100644
index 0000000..eef9a78
--- /dev/null
+++ b/backend-handoff.md
@@ -0,0 +1,67 @@
+# Backend handoff — LIVING doc (FE ⇄ backend, couriered by the user)
+
+> **Purpose:** the single rolling document the FE orchestrator keeps current so the user can hand off
+> the whole FE↔backend seam at any time — on completion OR at a roadblock. Updated continuously.
+> **From:** dispatch-web orchestrator · **To:** arch-rewrite orchestrator · **Courier:** the user.
+> `lsp` does NOT span the repos (ORCHESTRATOR §5) — every cross-repo ask flows through here.
+
+_Last updated: 2026-06-06 — Slice 2 kicked off (unit summons in flight)._
+
+---
+
+## 1. Current FE status
+
+| Slice | State |
+|---|---|
+| **Slice 1** — surface system + WS + composition root | ✅ DONE, committed, green (svelte-check 0/0, 91 vitest, biome clean, build ok). |
+| **Slice 2** — conversation transcript: cache + delta streaming (design §6) | 🔧 IN PROGRESS — contracts pinned + mirrored; FE units being built (see §4). |
+
+## 2. Pinned backend contracts (consumed by the FE)
+
+All three pinned as `file:` deps at **`@0.1.0`** and live-verified consumable (import smoke-test passes):
+
+| Package | Used for |
+|---|---|
+| `@dispatch/ui-contract` | surfaces + surface WS protocol (Slice 1) |
+| `@dispatch/wire` | chat wire types: `Chunk`/`StoredChunk`(+`seq`)/`ChatMessage`/`AgentEvent`/`TurnSealedEvent`/`Usage` |
+| `@dispatch/transport-contract` | HTTP endpoints + `ChatRequest`/`ModelsResponse`/`ConversationHistoryResponse` + WS chat ops + unified `WsClientMessage`/`WsServerMessage` |
+
+Backend endpoints in use (port **24203** HTTP, **24205** WS, CORS wildcard `*` — all confirmed live):
+`POST /chat` (NDJSON), `GET /models`, `GET /conversations/:id?sinceSeq=<n>`, WS `chat.send`→`chat.delta`.
+Confirmed invariants C1–C4 (raw seq-ordered history slice · one path-agnostic WS multiplexing surface+chat · `turn-sealed` fires post-persist = cache-commit · live deltas carry no `seq`).
+
+Mirrored in-repo for headless agents: `.dispatch/ui-contract.reference.md`, `.dispatch/wire.reference.md`,
+`.dispatch/transport-contract.reference.md` (regenerated on any contract bump).
+
+## 3. Open items FOR THE BACKEND
+
+### 3.1 Resolved / answered
+- ✅ Wire-types split, per-chunk `seq`, history endpoint, WS chat multiplexing, CORS — all delivered
+ (backend commit `812621c`).
+
+### 3.2 FYI — non-blocking gotcha (no action required unless you publish externally)
+- **`workspace:*` breaks external `file:` consumption under bun.** `transport-contract`'s deps are
+ `@dispatch/ui-contract`/`@dispatch/wire` at `workspace:*`; `bun install` from dispatch-web could not
+ resolve them ("Workspace dependency not found"). **Worked around FE-side** with a `package.json`
+ `overrides` block mapping both to their `file:` paths — no backend change needed now. If you ever
+ publish these to a registry, prefer real semver ranges over `workspace:*` for out-of-monorepo
+ consumers.
+
+### 3.3 Pending asks / roadblocks
+- _(none open)_ — Slice 2 has all the backend contracts it needs.
+
+## 4. Looking ahead — FE Slice 2 unit map (no backend dependency)
+
+Pure-core / injected-shell decomposition, built by single-owner agents in this repo:
+`core/chunks` (the one transcript reducer) · `core/wire` (contract-conformance type-tests) ·
+`adapters/ws` (extend for `chat.send`/`chat.delta`) · `features/conversation-cache`
+(pure `reconcileCache`/`selectEvictions` + IndexedDB port) · `adapters/idb` (IndexedDB impl) ·
+`features/chat` (view-model + UI) · `app` (wiring). None require backend changes.
+
+## 5. Likely NEXT backend asks (heads-up, not yet requested)
+
+These belong to **later** FE slices (design §7 "later slice") — flagged early so they're on your radar:
+- `GET /conversations` — conversation list / sidebar (FE history explorer / conversation switcher).
+- `POST /conversations/:id/cancel` — "stop generating".
+
+When the FE reaches those slices, the concrete request will be filed here in §3.3.
diff --git a/bun.lock b/bun.lock
index 6689953..42819aa 100644
--- a/bun.lock
+++ b/bun.lock
@@ -5,7 +5,9 @@
"": {
"name": "dispatch-web",
"dependencies": {
+ "@dispatch/transport-contract": "file:../arch-rewrite/packages/transport-contract",
"@dispatch/ui-contract": "file:../arch-rewrite/packages/ui-contract",
+ "@dispatch/wire": "file:../arch-rewrite/packages/wire",
},
"devDependencies": {
"@biomejs/biome": "^2.4.16",
@@ -14,6 +16,7 @@
"@testing-library/svelte": "^5.2.0",
"@testing-library/user-event": "^14.6.1",
"@tsconfig/svelte": "^5.0.0",
+ "fake-indexeddb": "^6.0.0",
"jsdom": "^25.0.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
@@ -23,6 +26,10 @@
},
},
},
+ "overrides": {
+ "@dispatch/ui-contract": "file:../arch-rewrite/packages/ui-contract",
+ "@dispatch/wire": "file:../arch-rewrite/packages/wire",
+ },
"packages": {
"@adobe/css-tools": ["@adobe/[email protected]", "", {}, "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q=="],
@@ -62,8 +69,12 @@
"@csstools/css-tokenizer": ["@csstools/[email protected]", "", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="],
+ "@dispatch/transport-contract": ["@dispatch/transport-contract@file:../arch-rewrite/packages/transport-contract", { "dependencies": { "@dispatch/ui-contract": "workspace:*", "@dispatch/wire": "workspace:*" } }],
+
"@dispatch/ui-contract": ["@dispatch/ui-contract@file:../arch-rewrite/packages/ui-contract", {}],
+ "@dispatch/wire": ["@dispatch/wire@file:../arch-rewrite/packages/wire", {}],
+
"@esbuild/aix-ppc64": ["@esbuild/[email protected]", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
"@esbuild/android-arm": ["@esbuild/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
@@ -296,6 +307,8 @@
"expect-type": ["[email protected]", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
+ "fake-indexeddb": ["[email protected]", "", {}, "sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w=="],
+
"fdir": ["[email protected]", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
"form-data": ["[email protected]", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="],
@@ -462,6 +475,10 @@
"zimmerframe": ["[email protected]", "", {}, "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="],
+ "@dispatch/transport-contract/@dispatch/ui-contract": ["@dispatch/ui-contract@file:../arch-rewrite/packages/ui-contract", {}],
+
+ "@dispatch/transport-contract/@dispatch/wire": ["@dispatch/wire@file:../arch-rewrite/packages/wire", {}],
+
"@testing-library/dom/aria-query": ["[email protected]", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="],
"@testing-library/dom/dom-accessibility-api": ["[email protected]", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="],
diff --git a/package.json b/package.json
index cf856d3..1ed3b3f 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,13 @@
"check:fix": "biome check --write ."
},
"dependencies": {
- "@dispatch/ui-contract": "file:../arch-rewrite/packages/ui-contract"
+ "@dispatch/transport-contract": "file:../arch-rewrite/packages/transport-contract",
+ "@dispatch/ui-contract": "file:../arch-rewrite/packages/ui-contract",
+ "@dispatch/wire": "file:../arch-rewrite/packages/wire"
+ },
+ "overrides": {
+ "@dispatch/ui-contract": "file:../arch-rewrite/packages/ui-contract",
+ "@dispatch/wire": "file:../arch-rewrite/packages/wire"
},
"devDependencies": {
"@biomejs/biome": "^2.4.16",
@@ -23,6 +29,7 @@
"@testing-library/svelte": "^5.2.0",
"@testing-library/user-event": "^14.6.1",
"@tsconfig/svelte": "^5.0.0",
+ "fake-indexeddb": "^6.0.0",
"jsdom": "^25.0.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",