summaryrefslogtreecommitdiffhomepage
path: root/packages/transport-contract/src
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-22 00:08:21 +0900
committerAdam Malczewski <[email protected]>2026-06-22 00:08:21 +0900
commit7ff9f94c41a9870e124a50133cd74b42295ab9ac (patch)
tree3a3f09d843dc3263983fa44b384ecc3c1a32e750 /packages/transport-contract/src
parent037c136823a900e28864e4dd48e1dbe626e95dfb (diff)
downloaddispatch-7ff9f94c41a9870e124a50133cd74b42295ab9ac.tar.gz
dispatch-7ff9f94c41a9870e124a50133cd74b42295ab9ac.zip
feat: conversation lifecycle status (active/idle/closed) for tab persistence
Implement roadmap item 9: tab persistence across devices. Wire (0.10.0): - Add ConversationStatus type (active | idle | closed) - Add status field to ConversationMeta Transport-contract (0.14.0): - Add conversation.statusChanged WS message to WsServerMessage union - Re-export ConversationStatus Conversation-store: - Track status in ConversationMetaRow (default: idle) - getConversationStatus / setConversationStatus methods - listConversations accepts { status: ConversationStatus[] } filter - Old meta rows without status default to idle on read Session-orchestrator: - conversationStatusChanged hook descriptor - Emit on transitions: idle→active (turn start), active→idle (turn settle), →closed (closeConversation) - Persist status to store as fire-and-forget side effect - Declare hook in manifest contributes.hooks Transport-ws: - Subscribe to conversationStatusChanged hook - Broadcast conversation.statusChanged WS message to all clients Transport-http: - GET /conversations?status=active,idle filter (parseStatusFilter pure helper) - POST /conversations/:id/close now sets status to closed CLI: - dispatch list defaults to active,idle (excludes closed) - --status <state> flag to filter by single status - --all flag to include closed FE handoff: frontend-conversation-lifecycle-handoff.md
Diffstat (limited to 'packages/transport-contract/src')
-rw-r--r--packages/transport-contract/src/index.ts16
1 files changed, 15 insertions, 1 deletions
diff --git a/packages/transport-contract/src/index.ts b/packages/transport-contract/src/index.ts
index d8bfe50..237f4ab 100644
--- a/packages/transport-contract/src/index.ts
+++ b/packages/transport-contract/src/index.ts
@@ -23,6 +23,7 @@ import type { SurfaceClientMessage, SurfaceServerMessage } from "@dispatch/ui-co
import type {
AgentEvent,
ConversationMeta,
+ ConversationStatus,
QueuedMessage,
ReasoningEffort,
StoredChunk,
@@ -32,6 +33,7 @@ import type {
export type {
AgentEvent,
ConversationMeta,
+ ConversationStatus,
QueuedMessage,
ReasoningEffort,
StepMetrics,
@@ -483,7 +485,8 @@ export type WsServerMessage =
| SurfaceServerMessage
| ChatDeltaMessage
| ChatErrorMessage
- | ConversationOpenMessage;
+ | ConversationOpenMessage
+ | ConversationStatusChangedMessage;
// ─── Conversation list + metadata ────────────────────────────────────────────
@@ -498,6 +501,17 @@ export interface ConversationOpenMessage {
}
/**
+ * Broadcast to all connected WS clients when a conversation's lifecycle status
+ * changes (active/idle/closed). The frontend uses this to sync tab state across
+ * devices in real time.
+ */
+export interface ConversationStatusChangedMessage {
+ readonly type: "conversation.statusChanged";
+ readonly conversationId: string;
+ readonly status: ConversationStatus;
+}
+
+/**
* Response for `GET /conversations` — the list of all known conversations,
* sorted by `lastActivityAt` descending (most recent first). Each entry carries
* enough metadata for a conversation picker UI (id, title, timestamps).