diff options
| author | Adam Malczewski <[email protected]> | 2026-06-21 21:47:24 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-21 21:47:24 +0900 |
| commit | fd81987fcec0178ae2c466800b428e1b1dfc4ab0 (patch) | |
| tree | 646e39ed43c64f763721553ba7a7821d62730df8 /src/app | |
| parent | 90ab92626555bb6a764a3c15fc03ac3e36966226 (diff) | |
| download | dispatch-web-fd81987fcec0178ae2c466800b428e1b1dfc4ab0.tar.gz dispatch-web-fd81987fcec0178ae2c466800b428e1b1dfc4ab0.zip | |
feat(ws): handle conversation.open broadcast — open/focus tab from CLI --open
Consume the conversation.open handoff ([email protected], [email protected]).
Re-pinned file: deps + re-mirrored .dispatch/*.reference.md.
- WS adapter (logic.ts + index.ts): parse + route the new top-level
"conversation.open" WsServerMessage to an onConversationOpen handler
- app store: openConversation(id) opens (or focuses) a tab — creates a chat
store, loads history, subscribes to live turns, creates+selects the tab
- conformance guard + WS adapter tests cover the new type
- backend also shipped conversation metadata endpoints (GET /conversations,
GET /conversations/:id/last, GET/PUT /conversations/:id/title) — mirrored
but not yet consumed by the FE
682 tests green.
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/store.svelte.ts | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/app/store.svelte.ts b/src/app/store.svelte.ts index dc06ea1..5159353 100644 --- a/src/app/store.svelte.ts +++ b/src/app/store.svelte.ts @@ -3,6 +3,7 @@ import type { ChatErrorMessage, ConversationHistoryResponse, ConversationMetricsResponse, + ConversationOpenMessage, CwdResponse, LspStatusResponse, ModelsResponse, @@ -432,10 +433,39 @@ export function createAppStore(opts?: CreateAppStoreOptions): AppStore { let socket: ReturnType<typeof createSurfaceSocket> | null = null; + /** + * Open (or focus) a conversation tab — used by the `conversation.open` WS + * broadcast (CLI `--open` flag). If the conversation is already open, just + * focus it; otherwise create a chat store, load its history, subscribe to its + * live turns, and create+select the tab. + */ + function openConversation(conversationId: string): void { + const alreadyOpen = chatStores.has(conversationId); + if (!alreadyOpen) { + const store = createChatFor(conversationId, activeModel); + chatStores.set(conversationId, store); + void store.load(); + subscribeChat(conversationId); + tabsStore.createTab({ + conversationId, + model: activeModel, + title: "Conversation", + }); + } + tabsStore.selectTab(conversationId); + refreshActiveChat(); + syncSubscriptions(); + void refreshCwd(); + void refreshReasoningEffort(); + } + const socketOpts: SurfaceSocketOptions = { url: wsUrl, onMessage: handleServerMessage, onChat: handleChatMessage, + onConversationOpen(msg: ConversationOpenMessage): void { + openConversation(msg.conversationId); + }, onReopen() { // The server forgot our subscriptions on reconnect; re-send each with the // conversation it was subscribed under (protocolSubscribe would no-op since |
