From 7ff9f94c41a9870e124a50133cd74b42295ab9ac Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Mon, 22 Jun 2026 00:08:21 +0900 Subject: feat: conversation lifecycle status (active/idle/closed) for tab persistence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 flag to filter by single status - --all flag to include closed FE handoff: frontend-conversation-lifecycle-handoff.md --- packages/cli/src/main.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'packages/cli/src/main.ts') diff --git a/packages/cli/src/main.ts b/packages/cli/src/main.ts index 6df6e23..e709f21 100644 --- a/packages/cli/src/main.ts +++ b/packages/cli/src/main.ts @@ -22,7 +22,7 @@ import { extractLastText, formatConversationList, renderEvent } from "./render.j const USAGE = `Usage: dispatch models [--server ] - dispatch list [] [--server ] + dispatch list [] [--status ] [--all] [--server ] dispatch read [--server ] dispatch open [--server ] dispatch send --text "..." [--queue] [--open] [--cwd ] [--effort ] [--server ] @@ -50,9 +50,14 @@ async function main(): Promise { break; } case "list": { + const status = parsed.all ? undefined : (parsed.status ?? "active,idle"); const result = await fetchConversations( { fetchImpl: globalThis.fetch }, - { server: parsed.server, ...(parsed.query !== undefined && { query: parsed.query }) }, + { + server: parsed.server, + ...(parsed.query !== undefined && { query: parsed.query }), + ...(status !== undefined && { status }), + }, ); const table = formatConversationList(result.conversations, Date.now()); if (table.length > 0) process.stdout.write(`${table}\n`); -- cgit v1.2.3