summaryrefslogtreecommitdiffhomepage
path: root/src/app
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-21 21:47:24 +0900
committerAdam Malczewski <[email protected]>2026-06-21 21:47:24 +0900
commitfd81987fcec0178ae2c466800b428e1b1dfc4ab0 (patch)
tree646e39ed43c64f763721553ba7a7821d62730df8 /src/app
parent90ab92626555bb6a764a3c15fc03ac3e36966226 (diff)
downloaddispatch-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.ts30
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