From fac44794432928d0341728642fd70eef87837da4 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sat, 6 Jun 2026 23:43:43 +0900 Subject: Slice 2 unblock: pin wire + transport-contract; mirror contracts - pin @dispatch/wire + @dispatch/transport-contract (+ ui-contract) as file: deps @0.1.0; overrides{} workaround for their workspace:* deps (bun can't resolve workspace: from outside the monorepo) - add fake-indexeddb (dev) for the upcoming IndexedDB adapter tests - mirror wire + transport-contract into .dispatch/*.reference.md for headless agents; point package-agent.md at all three references - backend-handoff.md: convert to a living FE<->backend seam doc Verified green: svelte-check 0/0, vitest 91, biome clean, build ok; contract import smoke-test passes. --- .dispatch/package-agent.md | 17 +- .dispatch/transport-contract.reference.md | 125 +++++++++++++++ .dispatch/wire.reference.md | 247 ++++++++++++++++++++++++++++++ backend-handoff.md | 67 ++++++++ bun.lock | 17 ++ package.json | 9 +- 6 files changed, 476 insertions(+), 6 deletions(-) create mode 100644 .dispatch/transport-contract.reference.md create mode 100644 .dispatch/wire.reference.md create mode 100644 backend-handoff.md 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 `transport-contract@0.1.0`. 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=` — `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 `/` 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 `/` form (exactly `ChatRequest.model`). + */ +export interface ModelsResponse { + readonly models: readonly string[]; +} + +/** + * Response body for `GET /conversations/:id?sinceSeq=` — 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 `wire@0.1.0`. 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=`, 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/css-tools@4.5.0", "", {}, "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q=="], @@ -62,8 +69,12 @@ "@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "", {}, "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/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], @@ -296,6 +307,8 @@ "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + "fake-indexeddb": ["fake-indexeddb@6.2.5", "", {}, "sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "form-data": ["form-data@4.0.5", "", { "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": ["zimmerframe@1.1.4", "", {}, "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": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="], "@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "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", -- cgit v1.2.3