summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-21 22:54:00 +0900
committerAdam Malczewski <[email protected]>2026-06-21 22:54:00 +0900
commita8de5b2b9bec07a5ed5df54b859fa6ff5f98406f (patch)
tree54ffa30ec7b6fcef6d95f0da914381316d0d62c8
parent6c61fb52494b5a11f96b7ec814b625d61a67399c (diff)
downloaddispatch-web-a8de5b2b9bec07a5ed5df54b859fa6ff5f98406f.tar.gz
dispatch-web-a8de5b2b9bec07a5ed5df54b859fa6ff5f98406f.zip
fix: conversation.open opens tab without auto-switching
CLI --open should add the tab to the strip but leave the user on their current tab. Add openTab reducer (add without selecting) + use it in openConversation instead of createTab+selectTab.
-rw-r--r--src/app/store.svelte.ts36
-rw-r--r--src/features/tabs/tabs-store.svelte.ts6
-rw-r--r--src/features/tabs/tabs.ts11
3 files changed, 32 insertions, 21 deletions
diff --git a/src/app/store.svelte.ts b/src/app/store.svelte.ts
index 5159353..5a5245d 100644
--- a/src/app/store.svelte.ts
+++ b/src/app/store.svelte.ts
@@ -434,29 +434,23 @@ 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.
+ * Open a conversation tab — used by the `conversation.open` WS broadcast
+ * (CLI `--open` flag). If the conversation is already open, this is a no-op;
+ * otherwise create a chat store, load its history, subscribe to its live
+ * turns, and add the tab WITHOUT switching the active conversation (the user
+ * stays on their current tab; the new tab appears in the strip).
*/
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();
+ if (chatStores.has(conversationId)) return;
+ const store = createChatFor(conversationId, activeModel);
+ chatStores.set(conversationId, store);
+ void store.load();
+ subscribeChat(conversationId);
+ tabsStore.openTab({
+ conversationId,
+ model: activeModel,
+ title: "Conversation",
+ });
}
const socketOpts: SurfaceSocketOptions = {
diff --git a/src/features/tabs/tabs-store.svelte.ts b/src/features/tabs/tabs-store.svelte.ts
index cba527e..2e876f9 100644
--- a/src/features/tabs/tabs-store.svelte.ts
+++ b/src/features/tabs/tabs-store.svelte.ts
@@ -4,6 +4,7 @@ import {
closeTab as reduceCloseTab,
createTab as reduceCreateTab,
newDraft as reduceNewDraft,
+ openTab as reduceOpenTab,
selectTab as reduceSelectTab,
setModel as reduceSetModel,
setTitle as reduceSetTitle,
@@ -21,6 +22,8 @@ export interface TabsStore {
readonly activeTab: Tab | null;
newDraft(): void;
createTab(tab: Tab): void;
+ /** Add a tab WITHOUT focusing it (for `conversation.open`). No-op if already open. */
+ openTab(tab: Tab): void;
selectTab(conversationId: string): void;
closeTab(conversationId: string): void;
setModel(conversationId: string, model: string): void;
@@ -51,6 +54,9 @@ export function createTabsStore(storage: TabsStorage): TabsStore {
createTab(tab: Tab): void {
apply(reduceCreateTab(state, tab));
},
+ openTab(tab: Tab): void {
+ apply(reduceOpenTab(state, tab));
+ },
selectTab(conversationId: string): void {
apply(reduceSelectTab(state, conversationId));
},
diff --git a/src/features/tabs/tabs.ts b/src/features/tabs/tabs.ts
index 61ae58e..3360d3f 100644
--- a/src/features/tabs/tabs.ts
+++ b/src/features/tabs/tabs.ts
@@ -27,6 +27,17 @@ export function createTab(state: TabsState, tab: Tab): TabsState {
return { tabs, activeConversationId: tab.conversationId };
}
+/**
+ * Add a tab WITHOUT switching the active conversation — used by the
+ * `conversation.open` WS broadcast (CLI `--open`): the tab appears in the
+ * strip but the user stays on their current tab. No-op if already open.
+ */
+export function openTab(state: TabsState, tab: Tab): TabsState {
+ const exists = state.tabs.some((t) => t.conversationId === tab.conversationId);
+ if (exists) return state;
+ return { tabs: [...state.tabs, tab], activeConversationId: state.activeConversationId };
+}
+
export function selectTab(state: TabsState, conversationId: string): TabsState {
return { ...state, activeConversationId: conversationId };
}