@burdenoff/microfe-vibecontrols 2026.608.1 → 2026.608.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,6 +20,10 @@ var r = t()(n((e, t) => ({
20
20
  sessionsGroupBy: "none",
21
21
  sessionsTargetFilter: "all",
22
22
  sessionInfoPanelOpen: !1,
23
+ lastUsedAgentId: null,
24
+ lastUsedVibeId: null,
25
+ lastUsedSessionType: "TMUX",
26
+ lastUsedProfile: "default",
23
27
  setCurrentView: (t) => e({ currentView: t }),
24
28
  setCurrentTab: (t) => e({ currentTab: t }),
25
29
  setActiveAgentId: (t) => e((e) => ({
@@ -92,6 +96,12 @@ var r = t()(n((e, t) => ({
92
96
  setSessionsGroupBy: (t) => e({ sessionsGroupBy: t }),
93
97
  setSessionsTargetFilter: (t) => e({ sessionsTargetFilter: t }),
94
98
  setSessionInfoPanelOpen: (t) => e({ sessionInfoPanelOpen: t }),
99
+ setLastUsedSessionDefaults: (t) => e((e) => ({
100
+ lastUsedAgentId: t.agentId === void 0 ? e.lastUsedAgentId : t.agentId,
101
+ lastUsedVibeId: t.vibeId === void 0 ? e.lastUsedVibeId : t.vibeId,
102
+ lastUsedSessionType: t.sessionType ?? e.lastUsedSessionType,
103
+ lastUsedProfile: t.profile ?? e.lastUsedProfile
104
+ })),
95
105
  activeCatalogId: null,
96
106
  activeComponentId: null,
97
107
  activeTemplateId: null,
@@ -161,6 +171,10 @@ var r = t()(n((e, t) => ({
161
171
  sessionsGroupBy: "none",
162
172
  sessionsTargetFilter: "all",
163
173
  sessionInfoPanelOpen: !1,
174
+ lastUsedAgentId: null,
175
+ lastUsedVibeId: null,
176
+ lastUsedSessionType: "TMUX",
177
+ lastUsedProfile: "default",
164
178
  activeCatalogId: null,
165
179
  activeComponentId: null,
166
180
  activeTemplateId: null,
@@ -189,6 +203,10 @@ var r = t()(n((e, t) => ({
189
203
  sessionsGroupBy: e.sessionsGroupBy,
190
204
  sessionsTargetFilter: e.sessionsTargetFilter,
191
205
  sessionInfoPanelOpen: e.sessionInfoPanelOpen,
206
+ lastUsedAgentId: e.lastUsedAgentId,
207
+ lastUsedVibeId: e.lastUsedVibeId,
208
+ lastUsedSessionType: e.lastUsedSessionType,
209
+ lastUsedProfile: e.lastUsedProfile,
192
210
  activeCatalogId: e.activeCatalogId,
193
211
  activeComponentId: e.activeComponentId,
194
212
  activeTemplateId: e.activeTemplateId,
@@ -1 +1 @@
1
- {"version":3,"file":"vibeControlsStore.js","names":[],"sources":["../../src/store/vibeControlsStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\nimport type { VibeControlsView, VibeControlsTab } from '@/types';\nimport type { SessionsGroupBy } from '@/components/sessions';\n\n/** Persisted terminal tab info (minimal data for restoration) */\nexport interface PersistedTerminalTab {\n sessionId: string;\n name: string;\n /** Pinned tabs sort to the front and survive \"close others\". */\n pinned?: boolean;\n}\n\ninterface VibeControlsState {\n // View state\n currentView: VibeControlsView;\n currentTab: VibeControlsTab;\n\n // Active context — the currently focused agent, vibe, and session.\n // Persisted to localStorage so the selection survives page refreshes.\n activeAgentId: string | null;\n activeVibeId: string | null;\n activeSessionId: string | null;\n\n // Legacy selection aliases (kept for backward compatibility with pages)\n selectedAgentId: string | null;\n selectedSessionId: string | null;\n selectedVibeId: string | null;\n\n /**\n * Per-agent \"connecting\" overlay timestamps shown after Edit Tunnel save\n * while the backend pushes OAuth creds → agent finalize() → /health/ready\n * flips to ok. The value is the *earliest* wall-clock timestamp at which\n * the overlay is allowed to clear — used as a grace window so a stale\n * `healthy:true` cache delivered during the connecting window cannot\n * clear it prematurely (root cause of the historical CONNECTING →\n * DEGRADED → ACTIVE flicker after Edit Tunnel save).\n *\n * Lives in the global store (not in AgentsPage local React state) so the\n * overlay survives navigation to AgentDetailsPage and back — the\n * documented user recovery path navigates into AgentDetailsPage so the\n * `pushAgentGatewayAuth` auto-recovery fires, and unmounting AgentsPage\n * used to discard the set entirely.\n *\n * In-memory only — not persisted (a \"connecting\" state has no meaning\n * across full page reloads).\n */\n connectingAgents: Record<string, number>;\n\n /**\n * Active profile name keyed by agent id. Phase 5B (multi-profile-per-daemon)\n * — every aiApi call constructs the canonical\n * `/api/profiles/<profile>/<rest>` path and so needs to know which profile\n * is currently selected for a given agent. The selector is exposed via\n * `useActiveAgentProfile(agentId)`.\n */\n activeProfilePerAgent: Record<string, string>;\n\n // UI state\n sidebarOpen: boolean;\n\n // Terminal tabs state (persisted for better UX when navigating away and back)\n terminalTabs: PersistedTerminalTab[];\n activeTerminalTabId: string | null;\n sessionsViewMode: 'terminal' | 'grid' | 'list';\n /** How the Sessions grid/list views cluster sessions. */\n sessionsGroupBy: SessionsGroupBy;\n /** Target id the Sessions list is filtered to ('all' = no filter). */\n sessionsTargetFilter: string;\n /** Whether the per-session info side panel is open. */\n sessionInfoPanelOpen: boolean;\n\n // Actions\n setCurrentView: (view: VibeControlsView) => void;\n setCurrentTab: (tab: VibeControlsTab) => void;\n\n /** Set the active agent (also resets vibe and session if agent changes) */\n setActiveAgentId: (id: string | null) => void;\n /** Set the active vibe (also resets session if vibe changes) */\n setActiveVibeId: (id: string | null) => void;\n /** Set the active session */\n setActiveSessionId: (id: string | null) => void;\n /** Clear all active context */\n clearActiveContext: () => void;\n /** Set the active profile for a given agent (Phase 5B). */\n setActiveProfile: (agentId: string, profile: string) => void;\n /** Read the currently-active profile for an agent (defaults to \"default\"). */\n getActiveProfile: (agentId: string | null | undefined) => string;\n\n /**\n * Mark an agent as \"connecting\" (e.g. immediately after an Edit Tunnel\n * save). `graceMs` is a minimum wall-clock window during which the\n * overlay cannot be cleared by an incoming probe — defends against a\n * stale `healthy:true` Apollo-cache hit racing the in-flight refetch.\n */\n markAgentConnecting: (agentId: string, graceMs?: number) => void;\n /** Clear the \"connecting\" overlay for a single agent. */\n clearAgentConnecting: (agentId: string) => void;\n /**\n * Returns true while the connecting overlay is still active for the\n * agent (entry exists AND grace window has not elapsed OR a probe\n * hasn't yet flipped it healthy).\n */\n isAgentConnecting: (agentId: string) => boolean;\n\n // Legacy setters (call through to active context)\n setSelectedAgentId: (id: string | null) => void;\n setSelectedSessionId: (id: string | null) => void;\n setSelectedVibeId: (id: string | null) => void;\n\n toggleSidebar: () => void;\n setSidebarOpen: (open: boolean) => void;\n\n // Terminal tabs actions\n setTerminalTabs: (tabs: PersistedTerminalTab[]) => void;\n addTerminalTab: (tab: PersistedTerminalTab) => void;\n removeTerminalTab: (sessionId: string) => void;\n setActiveTerminalTabId: (sessionId: string | null) => void;\n setSessionsViewMode: (mode: 'terminal' | 'grid' | 'list') => void;\n setSessionsGroupBy: (groupBy: SessionsGroupBy) => void;\n setSessionsTargetFilter: (targetId: string) => void;\n setSessionInfoPanelOpen: (open: boolean) => void;\n\n // Catalog / Component / Template active context\n activeCatalogId: string | null;\n activeComponentId: string | null;\n activeTemplateId: string | null;\n setActiveCatalogId: (id: string | null) => void;\n setActiveComponentId: (id: string | null) => void;\n setActiveTemplateId: (id: string | null) => void;\n\n // VibeDeck state\n activeVibeDeckId: string | null;\n setActiveVibeDeckId: (id: string | null) => void;\n vibeDeckMode: 'preview' | 'edit';\n setVibeDeckMode: (mode: 'preview' | 'edit') => void;\n\n // ─── iframe-plugin tab system ──────────────────────────────────────\n /**\n * Per-user, per-mountPoint, per-contextKey tab ordering. Backed by\n * the `wspace-vibecontrols-svc` UserPreferences slot — the local\n * store is a write-through cache. Reads merge against the live\n * registry on every consumer call (drop stale, append new at end).\n */\n tabOrder: Record<string, Record<string, string[]>>;\n /** Replace the entire stored order for a (mountPoint, contextKey) pair. */\n setTabOrder: (mountPoint: string, contextKey: string, order: string[]) => void;\n /** Clear the stored order so reads fall through to the registry default. */\n resetTabOrder: (mountPoint: string, contextKey: string) => void;\n /** Bulk-replace the entire tabOrder map (used by backend hydration). */\n hydrateTabOrder: (next: Record<string, Record<string, string[]>>) => void;\n\n /**\n * Per-Vibe default agent (per user). Consulted by `useEffectiveAgent`\n * before the multi-agent heuristic. Backed by the same UserPreferences\n * slot above; hydrate on app boot.\n */\n defaultAgentForVibe: Record<string, string>;\n setDefaultAgentForVibe: (vibeId: string, agentId: string) => void;\n clearDefaultAgentForVibe: (vibeId: string) => void;\n hydrateDefaultAgentForVibe: (next: Record<string, string>) => void;\n\n /**\n * User's default IDE command for \"Open in editor\" actions. Token from\n * `IDE_PRESETS` (`code`, `cursor`, `idea`, ...). `null` falls back to\n * `code`. Backend mirror: `UserPreferences.preferredIdeCommand`.\n */\n preferredIdeCommand: string | null;\n setPreferredIdeCommand: (cmd: string | null) => void;\n hydratePreferredIdeCommand: (cmd: string | null) => void;\n\n /** Per-Vibe IDE override. Precedence: override → user default → 'code'. */\n vibeIdeOverrides: Record<string, string>;\n setVibeIdeOverride: (vibeId: string, cmd: string) => void;\n clearVibeIdeOverride: (vibeId: string) => void;\n hydrateVibeIdeOverrides: (next: Record<string, string>) => void;\n\n /** Reset all persisted state to defaults (used on logout / account switch) */\n resetStore: () => void;\n}\n\nexport const useVibeControlsStore = create<VibeControlsState>()(\n persist(\n (set, get) => ({\n // Initial state\n currentView: 'agents',\n currentTab: 'overview',\n activeAgentId: null,\n activeVibeId: null,\n activeSessionId: null,\n selectedAgentId: null,\n selectedSessionId: null,\n selectedVibeId: null,\n activeProfilePerAgent: {},\n connectingAgents: {},\n sidebarOpen: true,\n terminalTabs: [],\n activeTerminalTabId: null,\n sessionsViewMode: 'terminal',\n sessionsGroupBy: 'none',\n sessionsTargetFilter: 'all',\n sessionInfoPanelOpen: false,\n\n // Actions\n setCurrentView: (view) => set({ currentView: view }),\n setCurrentTab: (tab) => set({ currentTab: tab }),\n\n setActiveAgentId: (id) =>\n set((state) => ({\n activeAgentId: id,\n selectedAgentId: id,\n // Reset vibe and session when agent changes\n ...(id !== state.activeAgentId\n ? {\n activeVibeId: null,\n activeSessionId: null,\n selectedVibeId: null,\n selectedSessionId: null,\n }\n : {}),\n })),\n\n setActiveVibeId: (id) =>\n set((state) => ({\n activeVibeId: id,\n selectedVibeId: id,\n // Reset session when vibe changes\n ...(id !== state.activeVibeId ? { activeSessionId: null, selectedSessionId: null } : {}),\n })),\n\n setActiveSessionId: (id) =>\n set({\n activeSessionId: id,\n selectedSessionId: id,\n }),\n\n clearActiveContext: () =>\n set({\n activeAgentId: null,\n activeVibeId: null,\n activeSessionId: null,\n selectedAgentId: null,\n selectedVibeId: null,\n selectedSessionId: null,\n }),\n\n setActiveProfile: (agentId, profile) =>\n set((state) => ({\n activeProfilePerAgent: {\n ...state.activeProfilePerAgent,\n [agentId]: profile,\n },\n })),\n\n getActiveProfile: (agentId) => {\n if (!agentId) return 'default';\n return get().activeProfilePerAgent[agentId] ?? 'default';\n },\n\n markAgentConnecting: (agentId, graceMs = 1500) =>\n set((state) => ({\n connectingAgents: {\n ...state.connectingAgents,\n [agentId]: Date.now() + graceMs,\n },\n })),\n\n clearAgentConnecting: (agentId) =>\n set((state) => {\n if (!(agentId in state.connectingAgents)) return state;\n const next = { ...state.connectingAgents };\n delete next[agentId];\n return { connectingAgents: next };\n }),\n\n isAgentConnecting: (agentId) => agentId in get().connectingAgents,\n\n // Legacy setters\n setSelectedAgentId: (id) => set({ selectedAgentId: id, activeAgentId: id }),\n setSelectedSessionId: (id) => set({ selectedSessionId: id, activeSessionId: id }),\n setSelectedVibeId: (id) => set({ selectedVibeId: id, activeVibeId: id }),\n\n toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),\n setSidebarOpen: (open) => set({ sidebarOpen: open }),\n\n // Terminal tabs actions\n setTerminalTabs: (tabs) => set({ terminalTabs: tabs }),\n addTerminalTab: (tab) =>\n set((state) => {\n // Don't add duplicates\n if (state.terminalTabs.some((t) => t.sessionId === tab.sessionId)) {\n return state;\n }\n return { terminalTabs: [...state.terminalTabs, tab] };\n }),\n removeTerminalTab: (sessionId) =>\n set((state) => ({\n terminalTabs: state.terminalTabs.filter((t) => t.sessionId !== sessionId),\n // Clear active tab if it was removed\n activeTerminalTabId:\n state.activeTerminalTabId === sessionId ? null : state.activeTerminalTabId,\n })),\n setActiveTerminalTabId: (sessionId) => set({ activeTerminalTabId: sessionId }),\n setSessionsViewMode: (mode) => set({ sessionsViewMode: mode }),\n setSessionsGroupBy: (groupBy) => set({ sessionsGroupBy: groupBy }),\n setSessionsTargetFilter: (targetId) => set({ sessionsTargetFilter: targetId }),\n setSessionInfoPanelOpen: (open) => set({ sessionInfoPanelOpen: open }),\n\n // Catalog / Component / Template\n activeCatalogId: null,\n activeComponentId: null,\n activeTemplateId: null,\n setActiveCatalogId: (id) => set({ activeCatalogId: id }),\n setActiveComponentId: (id) => set({ activeComponentId: id }),\n setActiveTemplateId: (id) => set({ activeTemplateId: id }),\n\n // VibeDeck\n activeVibeDeckId: null,\n setActiveVibeDeckId: (id) => set({ activeVibeDeckId: id }),\n vibeDeckMode: 'preview',\n setVibeDeckMode: (mode) => set({ vibeDeckMode: mode }),\n\n // iframe-plugin tab system\n tabOrder: {},\n setTabOrder: (mountPoint, contextKey, order) =>\n set((state) => ({\n tabOrder: {\n ...state.tabOrder,\n [mountPoint]: {\n ...(state.tabOrder[mountPoint] ?? {}),\n [contextKey]: order,\n },\n },\n })),\n resetTabOrder: (mountPoint, contextKey) =>\n set((state) => {\n const mountBucket = state.tabOrder[mountPoint];\n if (!mountBucket || !(contextKey in mountBucket)) return state;\n const nextMountBucket = { ...mountBucket };\n delete nextMountBucket[contextKey];\n return {\n tabOrder: {\n ...state.tabOrder,\n [mountPoint]: nextMountBucket,\n },\n };\n }),\n hydrateTabOrder: (next) => set({ tabOrder: next }),\n\n defaultAgentForVibe: {},\n setDefaultAgentForVibe: (vibeId, agentId) =>\n set((state) => ({\n defaultAgentForVibe: { ...state.defaultAgentForVibe, [vibeId]: agentId },\n })),\n clearDefaultAgentForVibe: (vibeId) =>\n set((state) => {\n if (!(vibeId in state.defaultAgentForVibe)) return state;\n const next = { ...state.defaultAgentForVibe };\n delete next[vibeId];\n return { defaultAgentForVibe: next };\n }),\n hydrateDefaultAgentForVibe: (next) => set({ defaultAgentForVibe: next }),\n\n preferredIdeCommand: null,\n setPreferredIdeCommand: (cmd) => set({ preferredIdeCommand: cmd }),\n hydratePreferredIdeCommand: (cmd) => set({ preferredIdeCommand: cmd }),\n\n vibeIdeOverrides: {},\n setVibeIdeOverride: (vibeId, cmd) =>\n set((state) => ({\n vibeIdeOverrides: { ...state.vibeIdeOverrides, [vibeId]: cmd },\n })),\n clearVibeIdeOverride: (vibeId) =>\n set((state) => {\n if (!(vibeId in state.vibeIdeOverrides)) return state;\n const next = { ...state.vibeIdeOverrides };\n delete next[vibeId];\n return { vibeIdeOverrides: next };\n }),\n hydrateVibeIdeOverrides: (next) => set({ vibeIdeOverrides: next }),\n\n // Reset\n resetStore: () =>\n set({\n activeAgentId: null,\n activeVibeId: null,\n activeSessionId: null,\n selectedAgentId: null,\n selectedVibeId: null,\n selectedSessionId: null,\n activeProfilePerAgent: {},\n connectingAgents: {},\n sidebarOpen: true,\n terminalTabs: [],\n activeTerminalTabId: null,\n sessionsViewMode: 'terminal',\n sessionsGroupBy: 'none',\n sessionsTargetFilter: 'all',\n sessionInfoPanelOpen: false,\n activeCatalogId: null,\n activeComponentId: null,\n activeTemplateId: null,\n activeVibeDeckId: null,\n vibeDeckMode: 'preview',\n tabOrder: {},\n defaultAgentForVibe: {},\n preferredIdeCommand: null,\n vibeIdeOverrides: {},\n }),\n }),\n {\n name: 'vibecontrols-context',\n storage: createProfileScopedStorage(),\n // Persist context, UI state, and terminal tabs\n partialize: (state) => ({\n activeAgentId: state.activeAgentId,\n activeVibeId: state.activeVibeId,\n activeSessionId: state.activeSessionId,\n selectedAgentId: state.selectedAgentId,\n selectedVibeId: state.selectedVibeId,\n selectedSessionId: state.selectedSessionId,\n activeProfilePerAgent: state.activeProfilePerAgent,\n sidebarOpen: state.sidebarOpen,\n terminalTabs: state.terminalTabs,\n activeTerminalTabId: state.activeTerminalTabId,\n sessionsViewMode: state.sessionsViewMode,\n sessionsGroupBy: state.sessionsGroupBy,\n sessionsTargetFilter: state.sessionsTargetFilter,\n sessionInfoPanelOpen: state.sessionInfoPanelOpen,\n activeCatalogId: state.activeCatalogId,\n activeComponentId: state.activeComponentId,\n activeTemplateId: state.activeTemplateId,\n activeVibeDeckId: state.activeVibeDeckId,\n vibeDeckMode: state.vibeDeckMode,\n tabOrder: state.tabOrder,\n defaultAgentForVibe: state.defaultAgentForVibe,\n preferredIdeCommand: state.preferredIdeCommand,\n vibeIdeOverrides: state.vibeIdeOverrides,\n }),\n merge: (persisted, current) => {\n const p = (persisted ?? {}) as Partial<VibeControlsState>;\n return {\n ...current,\n ...p,\n tabOrder: p.tabOrder ?? current.tabOrder ?? {},\n defaultAgentForVibe: p.defaultAgentForVibe ?? current.defaultAgentForVibe ?? {},\n sessionsGroupBy: p.sessionsGroupBy ?? current.sessionsGroupBy ?? 'none',\n sessionsTargetFilter: p.sessionsTargetFilter ?? current.sessionsTargetFilter ?? 'all',\n sessionInfoPanelOpen: p.sessionInfoPanelOpen ?? current.sessionInfoPanelOpen ?? false,\n };\n },\n }\n )\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"vibeControlsStore.js","names":[],"sources":["../../src/store/vibeControlsStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\nimport type { VibeControlsView, VibeControlsTab } from '@/types';\nimport type { SessionsGroupBy } from '@/components/sessions';\n\n/** Persisted terminal tab info (minimal data for restoration) */\nexport interface PersistedTerminalTab {\n sessionId: string;\n name: string;\n /** Pinned tabs sort to the front and survive \"close others\". */\n pinned?: boolean;\n}\n\ninterface VibeControlsState {\n // View state\n currentView: VibeControlsView;\n currentTab: VibeControlsTab;\n\n // Active context — the currently focused agent, vibe, and session.\n // Persisted to localStorage so the selection survives page refreshes.\n activeAgentId: string | null;\n activeVibeId: string | null;\n activeSessionId: string | null;\n\n // Legacy selection aliases (kept for backward compatibility with pages)\n selectedAgentId: string | null;\n selectedSessionId: string | null;\n selectedVibeId: string | null;\n\n /**\n * Per-agent \"connecting\" overlay timestamps shown after Edit Tunnel save\n * while the backend pushes OAuth creds → agent finalize() → /health/ready\n * flips to ok. The value is the *earliest* wall-clock timestamp at which\n * the overlay is allowed to clear — used as a grace window so a stale\n * `healthy:true` cache delivered during the connecting window cannot\n * clear it prematurely (root cause of the historical CONNECTING →\n * DEGRADED → ACTIVE flicker after Edit Tunnel save).\n *\n * Lives in the global store (not in AgentsPage local React state) so the\n * overlay survives navigation to AgentDetailsPage and back — the\n * documented user recovery path navigates into AgentDetailsPage so the\n * `pushAgentGatewayAuth` auto-recovery fires, and unmounting AgentsPage\n * used to discard the set entirely.\n *\n * In-memory only — not persisted (a \"connecting\" state has no meaning\n * across full page reloads).\n */\n connectingAgents: Record<string, number>;\n\n /**\n * Active profile name keyed by agent id. Phase 5B (multi-profile-per-daemon)\n * — every aiApi call constructs the canonical\n * `/api/profiles/<profile>/<rest>` path and so needs to know which profile\n * is currently selected for a given agent. The selector is exposed via\n * `useActiveAgentProfile(agentId)`.\n */\n activeProfilePerAgent: Record<string, string>;\n\n // UI state\n sidebarOpen: boolean;\n\n // Terminal tabs state (persisted for better UX when navigating away and back)\n terminalTabs: PersistedTerminalTab[];\n activeTerminalTabId: string | null;\n sessionsViewMode: 'terminal' | 'grid' | 'list';\n /** How the Sessions grid/list views cluster sessions. */\n sessionsGroupBy: SessionsGroupBy;\n /** Target id the Sessions list is filtered to ('all' = no filter). */\n sessionsTargetFilter: string;\n /** Whether the per-session info side panel is open. */\n sessionInfoPanelOpen: boolean;\n\n /**\n * Last-used \"New Session\" settings, remembered so the \"+\" button can\n * one-click quick-create a terminal without re-prompting the form.\n * `lastUsedSessionType` defaults to 'TMUX'; `lastUsedProfile` to 'default'.\n */\n lastUsedAgentId: string | null;\n lastUsedVibeId: string | null;\n lastUsedSessionType: string;\n lastUsedProfile: string;\n\n // Actions\n setCurrentView: (view: VibeControlsView) => void;\n setCurrentTab: (tab: VibeControlsTab) => void;\n\n /** Set the active agent (also resets vibe and session if agent changes) */\n setActiveAgentId: (id: string | null) => void;\n /** Set the active vibe (also resets session if vibe changes) */\n setActiveVibeId: (id: string | null) => void;\n /** Set the active session */\n setActiveSessionId: (id: string | null) => void;\n /** Clear all active context */\n clearActiveContext: () => void;\n /** Set the active profile for a given agent (Phase 5B). */\n setActiveProfile: (agentId: string, profile: string) => void;\n /** Read the currently-active profile for an agent (defaults to \"default\"). */\n getActiveProfile: (agentId: string | null | undefined) => string;\n\n /**\n * Mark an agent as \"connecting\" (e.g. immediately after an Edit Tunnel\n * save). `graceMs` is a minimum wall-clock window during which the\n * overlay cannot be cleared by an incoming probe — defends against a\n * stale `healthy:true` Apollo-cache hit racing the in-flight refetch.\n */\n markAgentConnecting: (agentId: string, graceMs?: number) => void;\n /** Clear the \"connecting\" overlay for a single agent. */\n clearAgentConnecting: (agentId: string) => void;\n /**\n * Returns true while the connecting overlay is still active for the\n * agent (entry exists AND grace window has not elapsed OR a probe\n * hasn't yet flipped it healthy).\n */\n isAgentConnecting: (agentId: string) => boolean;\n\n // Legacy setters (call through to active context)\n setSelectedAgentId: (id: string | null) => void;\n setSelectedSessionId: (id: string | null) => void;\n setSelectedVibeId: (id: string | null) => void;\n\n toggleSidebar: () => void;\n setSidebarOpen: (open: boolean) => void;\n\n // Terminal tabs actions\n setTerminalTabs: (tabs: PersistedTerminalTab[]) => void;\n addTerminalTab: (tab: PersistedTerminalTab) => void;\n removeTerminalTab: (sessionId: string) => void;\n setActiveTerminalTabId: (sessionId: string | null) => void;\n setSessionsViewMode: (mode: 'terminal' | 'grid' | 'list') => void;\n setSessionsGroupBy: (groupBy: SessionsGroupBy) => void;\n setSessionsTargetFilter: (targetId: string) => void;\n setSessionInfoPanelOpen: (open: boolean) => void;\n /** Remember the last-used New Session settings for one-click quick-create. */\n setLastUsedSessionDefaults: (defaults: {\n agentId?: string | null;\n vibeId?: string | null;\n sessionType?: string;\n profile?: string;\n }) => void;\n\n // Catalog / Component / Template active context\n activeCatalogId: string | null;\n activeComponentId: string | null;\n activeTemplateId: string | null;\n setActiveCatalogId: (id: string | null) => void;\n setActiveComponentId: (id: string | null) => void;\n setActiveTemplateId: (id: string | null) => void;\n\n // VibeDeck state\n activeVibeDeckId: string | null;\n setActiveVibeDeckId: (id: string | null) => void;\n vibeDeckMode: 'preview' | 'edit';\n setVibeDeckMode: (mode: 'preview' | 'edit') => void;\n\n // ─── iframe-plugin tab system ──────────────────────────────────────\n /**\n * Per-user, per-mountPoint, per-contextKey tab ordering. Backed by\n * the `wspace-vibecontrols-svc` UserPreferences slot — the local\n * store is a write-through cache. Reads merge against the live\n * registry on every consumer call (drop stale, append new at end).\n */\n tabOrder: Record<string, Record<string, string[]>>;\n /** Replace the entire stored order for a (mountPoint, contextKey) pair. */\n setTabOrder: (mountPoint: string, contextKey: string, order: string[]) => void;\n /** Clear the stored order so reads fall through to the registry default. */\n resetTabOrder: (mountPoint: string, contextKey: string) => void;\n /** Bulk-replace the entire tabOrder map (used by backend hydration). */\n hydrateTabOrder: (next: Record<string, Record<string, string[]>>) => void;\n\n /**\n * Per-Vibe default agent (per user). Consulted by `useEffectiveAgent`\n * before the multi-agent heuristic. Backed by the same UserPreferences\n * slot above; hydrate on app boot.\n */\n defaultAgentForVibe: Record<string, string>;\n setDefaultAgentForVibe: (vibeId: string, agentId: string) => void;\n clearDefaultAgentForVibe: (vibeId: string) => void;\n hydrateDefaultAgentForVibe: (next: Record<string, string>) => void;\n\n /**\n * User's default IDE command for \"Open in editor\" actions. Token from\n * `IDE_PRESETS` (`code`, `cursor`, `idea`, ...). `null` falls back to\n * `code`. Backend mirror: `UserPreferences.preferredIdeCommand`.\n */\n preferredIdeCommand: string | null;\n setPreferredIdeCommand: (cmd: string | null) => void;\n hydratePreferredIdeCommand: (cmd: string | null) => void;\n\n /** Per-Vibe IDE override. Precedence: override → user default → 'code'. */\n vibeIdeOverrides: Record<string, string>;\n setVibeIdeOverride: (vibeId: string, cmd: string) => void;\n clearVibeIdeOverride: (vibeId: string) => void;\n hydrateVibeIdeOverrides: (next: Record<string, string>) => void;\n\n /** Reset all persisted state to defaults (used on logout / account switch) */\n resetStore: () => void;\n}\n\nexport const useVibeControlsStore = create<VibeControlsState>()(\n persist(\n (set, get) => ({\n // Initial state\n currentView: 'agents',\n currentTab: 'overview',\n activeAgentId: null,\n activeVibeId: null,\n activeSessionId: null,\n selectedAgentId: null,\n selectedSessionId: null,\n selectedVibeId: null,\n activeProfilePerAgent: {},\n connectingAgents: {},\n sidebarOpen: true,\n terminalTabs: [],\n activeTerminalTabId: null,\n sessionsViewMode: 'terminal',\n sessionsGroupBy: 'none',\n sessionsTargetFilter: 'all',\n sessionInfoPanelOpen: false,\n lastUsedAgentId: null,\n lastUsedVibeId: null,\n lastUsedSessionType: 'TMUX',\n lastUsedProfile: 'default',\n\n // Actions\n setCurrentView: (view) => set({ currentView: view }),\n setCurrentTab: (tab) => set({ currentTab: tab }),\n\n setActiveAgentId: (id) =>\n set((state) => ({\n activeAgentId: id,\n selectedAgentId: id,\n // Reset vibe and session when agent changes\n ...(id !== state.activeAgentId\n ? {\n activeVibeId: null,\n activeSessionId: null,\n selectedVibeId: null,\n selectedSessionId: null,\n }\n : {}),\n })),\n\n setActiveVibeId: (id) =>\n set((state) => ({\n activeVibeId: id,\n selectedVibeId: id,\n // Reset session when vibe changes\n ...(id !== state.activeVibeId ? { activeSessionId: null, selectedSessionId: null } : {}),\n })),\n\n setActiveSessionId: (id) =>\n set({\n activeSessionId: id,\n selectedSessionId: id,\n }),\n\n clearActiveContext: () =>\n set({\n activeAgentId: null,\n activeVibeId: null,\n activeSessionId: null,\n selectedAgentId: null,\n selectedVibeId: null,\n selectedSessionId: null,\n }),\n\n setActiveProfile: (agentId, profile) =>\n set((state) => ({\n activeProfilePerAgent: {\n ...state.activeProfilePerAgent,\n [agentId]: profile,\n },\n })),\n\n getActiveProfile: (agentId) => {\n if (!agentId) return 'default';\n return get().activeProfilePerAgent[agentId] ?? 'default';\n },\n\n markAgentConnecting: (agentId, graceMs = 1500) =>\n set((state) => ({\n connectingAgents: {\n ...state.connectingAgents,\n [agentId]: Date.now() + graceMs,\n },\n })),\n\n clearAgentConnecting: (agentId) =>\n set((state) => {\n if (!(agentId in state.connectingAgents)) return state;\n const next = { ...state.connectingAgents };\n delete next[agentId];\n return { connectingAgents: next };\n }),\n\n isAgentConnecting: (agentId) => agentId in get().connectingAgents,\n\n // Legacy setters\n setSelectedAgentId: (id) => set({ selectedAgentId: id, activeAgentId: id }),\n setSelectedSessionId: (id) => set({ selectedSessionId: id, activeSessionId: id }),\n setSelectedVibeId: (id) => set({ selectedVibeId: id, activeVibeId: id }),\n\n toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),\n setSidebarOpen: (open) => set({ sidebarOpen: open }),\n\n // Terminal tabs actions\n setTerminalTabs: (tabs) => set({ terminalTabs: tabs }),\n addTerminalTab: (tab) =>\n set((state) => {\n // Don't add duplicates\n if (state.terminalTabs.some((t) => t.sessionId === tab.sessionId)) {\n return state;\n }\n return { terminalTabs: [...state.terminalTabs, tab] };\n }),\n removeTerminalTab: (sessionId) =>\n set((state) => ({\n terminalTabs: state.terminalTabs.filter((t) => t.sessionId !== sessionId),\n // Clear active tab if it was removed\n activeTerminalTabId:\n state.activeTerminalTabId === sessionId ? null : state.activeTerminalTabId,\n })),\n setActiveTerminalTabId: (sessionId) => set({ activeTerminalTabId: sessionId }),\n setSessionsViewMode: (mode) => set({ sessionsViewMode: mode }),\n setSessionsGroupBy: (groupBy) => set({ sessionsGroupBy: groupBy }),\n setSessionsTargetFilter: (targetId) => set({ sessionsTargetFilter: targetId }),\n setSessionInfoPanelOpen: (open) => set({ sessionInfoPanelOpen: open }),\n setLastUsedSessionDefaults: (defaults) =>\n set((state) => ({\n lastUsedAgentId:\n defaults.agentId !== undefined ? defaults.agentId : state.lastUsedAgentId,\n lastUsedVibeId: defaults.vibeId !== undefined ? defaults.vibeId : state.lastUsedVibeId,\n lastUsedSessionType: defaults.sessionType ?? state.lastUsedSessionType,\n lastUsedProfile: defaults.profile ?? state.lastUsedProfile,\n })),\n\n // Catalog / Component / Template\n activeCatalogId: null,\n activeComponentId: null,\n activeTemplateId: null,\n setActiveCatalogId: (id) => set({ activeCatalogId: id }),\n setActiveComponentId: (id) => set({ activeComponentId: id }),\n setActiveTemplateId: (id) => set({ activeTemplateId: id }),\n\n // VibeDeck\n activeVibeDeckId: null,\n setActiveVibeDeckId: (id) => set({ activeVibeDeckId: id }),\n vibeDeckMode: 'preview',\n setVibeDeckMode: (mode) => set({ vibeDeckMode: mode }),\n\n // iframe-plugin tab system\n tabOrder: {},\n setTabOrder: (mountPoint, contextKey, order) =>\n set((state) => ({\n tabOrder: {\n ...state.tabOrder,\n [mountPoint]: {\n ...(state.tabOrder[mountPoint] ?? {}),\n [contextKey]: order,\n },\n },\n })),\n resetTabOrder: (mountPoint, contextKey) =>\n set((state) => {\n const mountBucket = state.tabOrder[mountPoint];\n if (!mountBucket || !(contextKey in mountBucket)) return state;\n const nextMountBucket = { ...mountBucket };\n delete nextMountBucket[contextKey];\n return {\n tabOrder: {\n ...state.tabOrder,\n [mountPoint]: nextMountBucket,\n },\n };\n }),\n hydrateTabOrder: (next) => set({ tabOrder: next }),\n\n defaultAgentForVibe: {},\n setDefaultAgentForVibe: (vibeId, agentId) =>\n set((state) => ({\n defaultAgentForVibe: { ...state.defaultAgentForVibe, [vibeId]: agentId },\n })),\n clearDefaultAgentForVibe: (vibeId) =>\n set((state) => {\n if (!(vibeId in state.defaultAgentForVibe)) return state;\n const next = { ...state.defaultAgentForVibe };\n delete next[vibeId];\n return { defaultAgentForVibe: next };\n }),\n hydrateDefaultAgentForVibe: (next) => set({ defaultAgentForVibe: next }),\n\n preferredIdeCommand: null,\n setPreferredIdeCommand: (cmd) => set({ preferredIdeCommand: cmd }),\n hydratePreferredIdeCommand: (cmd) => set({ preferredIdeCommand: cmd }),\n\n vibeIdeOverrides: {},\n setVibeIdeOverride: (vibeId, cmd) =>\n set((state) => ({\n vibeIdeOverrides: { ...state.vibeIdeOverrides, [vibeId]: cmd },\n })),\n clearVibeIdeOverride: (vibeId) =>\n set((state) => {\n if (!(vibeId in state.vibeIdeOverrides)) return state;\n const next = { ...state.vibeIdeOverrides };\n delete next[vibeId];\n return { vibeIdeOverrides: next };\n }),\n hydrateVibeIdeOverrides: (next) => set({ vibeIdeOverrides: next }),\n\n // Reset\n resetStore: () =>\n set({\n activeAgentId: null,\n activeVibeId: null,\n activeSessionId: null,\n selectedAgentId: null,\n selectedVibeId: null,\n selectedSessionId: null,\n activeProfilePerAgent: {},\n connectingAgents: {},\n sidebarOpen: true,\n terminalTabs: [],\n activeTerminalTabId: null,\n sessionsViewMode: 'terminal',\n sessionsGroupBy: 'none',\n sessionsTargetFilter: 'all',\n sessionInfoPanelOpen: false,\n lastUsedAgentId: null,\n lastUsedVibeId: null,\n lastUsedSessionType: 'TMUX',\n lastUsedProfile: 'default',\n activeCatalogId: null,\n activeComponentId: null,\n activeTemplateId: null,\n activeVibeDeckId: null,\n vibeDeckMode: 'preview',\n tabOrder: {},\n defaultAgentForVibe: {},\n preferredIdeCommand: null,\n vibeIdeOverrides: {},\n }),\n }),\n {\n name: 'vibecontrols-context',\n storage: createProfileScopedStorage(),\n // Persist context, UI state, and terminal tabs\n partialize: (state) => ({\n activeAgentId: state.activeAgentId,\n activeVibeId: state.activeVibeId,\n activeSessionId: state.activeSessionId,\n selectedAgentId: state.selectedAgentId,\n selectedVibeId: state.selectedVibeId,\n selectedSessionId: state.selectedSessionId,\n activeProfilePerAgent: state.activeProfilePerAgent,\n sidebarOpen: state.sidebarOpen,\n terminalTabs: state.terminalTabs,\n activeTerminalTabId: state.activeTerminalTabId,\n sessionsViewMode: state.sessionsViewMode,\n sessionsGroupBy: state.sessionsGroupBy,\n sessionsTargetFilter: state.sessionsTargetFilter,\n sessionInfoPanelOpen: state.sessionInfoPanelOpen,\n lastUsedAgentId: state.lastUsedAgentId,\n lastUsedVibeId: state.lastUsedVibeId,\n lastUsedSessionType: state.lastUsedSessionType,\n lastUsedProfile: state.lastUsedProfile,\n activeCatalogId: state.activeCatalogId,\n activeComponentId: state.activeComponentId,\n activeTemplateId: state.activeTemplateId,\n activeVibeDeckId: state.activeVibeDeckId,\n vibeDeckMode: state.vibeDeckMode,\n tabOrder: state.tabOrder,\n defaultAgentForVibe: state.defaultAgentForVibe,\n preferredIdeCommand: state.preferredIdeCommand,\n vibeIdeOverrides: state.vibeIdeOverrides,\n }),\n merge: (persisted, current) => {\n const p = (persisted ?? {}) as Partial<VibeControlsState>;\n return {\n ...current,\n ...p,\n tabOrder: p.tabOrder ?? current.tabOrder ?? {},\n defaultAgentForVibe: p.defaultAgentForVibe ?? current.defaultAgentForVibe ?? {},\n sessionsGroupBy: p.sessionsGroupBy ?? current.sessionsGroupBy ?? 'none',\n sessionsTargetFilter: p.sessionsTargetFilter ?? current.sessionsTargetFilter ?? 'all',\n sessionInfoPanelOpen: p.sessionInfoPanelOpen ?? current.sessionInfoPanelOpen ?? false,\n };\n },\n }\n )\n);\n"],"mappings":"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"}
@@ -1461,6 +1461,7 @@ var e = {
1461
1461
  notInstalled: "Code-server isn't installed on this agent. Install it from the Plugins tab to enable Open Editor.",
1462
1462
  openEditor: "Open Editor",
1463
1463
  opened: "Opened",
1464
+ popupBlocked: "Your browser blocked the editor tab. Allow pop-ups for this site, then click Open Editor again.",
1464
1465
  retry: "Retry",
1465
1466
  starting: "Starting..."
1466
1467
  },
@@ -1931,9 +1932,13 @@ var e = {
1931
1932
  reconnect: "Reconnect",
1932
1933
  reconnectNow: "Reconnect Now",
1933
1934
  rename: "Rename",
1935
+ restartSession: "Restart",
1934
1936
  restartTerminal: "Restart Terminal",
1935
1937
  retry: "Retry",
1938
+ sessionErrored: "Session ended",
1936
1939
  sessionInfo: "Session info",
1940
+ sessionStopped: "Session stopped",
1941
+ sessionStoppedHint: "This terminal is no longer running.",
1937
1942
  shareSession: "Share / offer session",
1938
1943
  stopTerminal: "Stop Terminal",
1939
1944
  unpinTab: "Unpin Tab",