summaryrefslogtreecommitdiffhomepage
path: root/packages/wire
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-23 02:35:26 +0900
committerAdam Malczewski <[email protected]>2026-06-23 02:35:26 +0900
commit6d7b3923b40eb4baf3cefadfde236de646990713 (patch)
treedd97bcecc6ccac0d74d791d975af82ff0bdd3e5d /packages/wire
parent55177d549e60886338f58cb579534dc1a09f94ec (diff)
downloaddispatch-6d7b3923b40eb4baf3cefadfde236de646990713.tar.gz
dispatch-6d7b3923b40eb4baf3cefadfde236de646990713.zip
feat: workspaces contract + conversation-store implementation (Wave 0+1)
Wire 0.12.0: Workspace, WorkspaceEntry, ConversationMeta.workspaceId Transport-contract 0.16.0: workspaceId on ChatRequest/QueueRequest/ChatQueueMessage; workspace endpoint types (EnsureWorkspaceRequest, WorkspaceResponse, etc.) Kernel: re-export Workspace/WorkspaceEntry from contracts Conversation-store: workspace persistence + service methods (getWorkspace, ensureWorkspace, setWorkspaceTitle, setWorkspaceDefaultCwd, deleteWorkspace, listWorkspaces, getWorkspaceId, setWorkspaceId, getEffectiveCwd, isValidWorkspaceSlug); listConversations filter by workspaceId; forkHistory/replaceHistory preserve workspaceId. 111 tests pass. FE handoff: frontend-workspaces-handoff.md (courier doc) 18 typecheck errors in session-orchestrator/transport-http/cli test fakes (expected fan-out — fixed in Wave 2+3).
Diffstat (limited to 'packages/wire')
-rw-r--r--packages/wire/package.json2
-rw-r--r--packages/wire/src/index.ts40
2 files changed, 41 insertions, 1 deletions
diff --git a/packages/wire/package.json b/packages/wire/package.json
index e375c8f..027c0b3 100644
--- a/packages/wire/package.json
+++ b/packages/wire/package.json
@@ -1,6 +1,6 @@
{
"name": "@dispatch/wire",
- "version": "0.11.0",
+ "version": "0.12.0",
"type": "module",
"private": true,
"main": "dist/index.js",
diff --git a/packages/wire/src/index.ts b/packages/wire/src/index.ts
index 4ab8825..bade977 100644
--- a/packages/wire/src/index.ts
+++ b/packages/wire/src/index.ts
@@ -522,6 +522,12 @@ export interface ConversationMeta {
readonly title: string;
readonly status: ConversationStatus;
/**
+ * The workspace this conversation belongs to. Always present; reads as
+ * `"default"` for legacy conversations that were never explicitly assigned.
+ * Conversations created with no `workspaceId` default to `"default"`.
+ */
+ readonly workspaceId: string;
+ /**
* Set on a compacted conversation: points to the archive conversation ID
* that holds the full pre-compaction history. Absent on conversations
* that have never been compacted.
@@ -544,3 +550,37 @@ export interface CompactionResult {
readonly messagesSummarized: number;
readonly messagesKept: number;
}
+
+// ─── Workspaces ──────────────────────────────────────────────────────────────
+
+/**
+ * A named, URL-driven grouping of conversations that owns a default cwd.
+ * Every conversation belongs to exactly one workspace; conversations that
+ * haven't set their own per-conversation cwd inherit `defaultCwd`.
+ *
+ * Workspaces are backend-owned (so cross-device just works): the workspace
+ * entity and each conversation's `workspaceId` live server-side. The
+ * `"default"` workspace is always present and non-deletable; conversations
+ * created with no `workspaceId` are assigned to `"default"`.
+ */
+export interface Workspace {
+ /** The URL slug (immutable). Lowercase `[a-z0-9-]`, 1–40 chars. */
+ readonly id: string;
+ /** Display title (editable). Defaults to `id` on creation. */
+ readonly title: string;
+ /** The workspace's default cwd, or `null` (fall through to server default). */
+ readonly defaultCwd: string | null;
+ /** Epoch-ms when the workspace was first created. */
+ readonly createdAt: number;
+ /** Epoch-ms of the most recent conversation activity in this workspace. */
+ readonly lastActivityAt: number;
+}
+
+/**
+ * A workspace entry in the list response (`GET /workspaces`) — a `Workspace`
+ * plus a conversation count.
+ */
+export interface WorkspaceEntry extends Workspace {
+ /** Number of conversations assigned to this workspace. */
+ readonly conversationCount: number;
+}