@burdenoff/microfe-vibecontrols 2026.514.3 → 2026.514.5

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.
@@ -11,15 +11,15 @@ function n({ panelRef: n, inputRef: r, onClose: i }) {
11
11
  t.preventDefault(), i();
12
12
  return;
13
13
  }
14
- if (o && t.key === "n") {
14
+ if (o && t.shiftKey && (t.key === "N" || t.key === "n")) {
15
15
  t.preventDefault(), e.getState().createConversation();
16
16
  return;
17
17
  }
18
- if (o && t.key === "e") {
18
+ if (o && t.shiftKey && (t.key === "E" || t.key === "e")) {
19
19
  t.preventDefault(), a.querySelector("[data-testid=\"assistant-export\"]")?.click();
20
20
  return;
21
21
  }
22
- if (t.key === "/" && !o) {
22
+ if (t.key === "/" && !o && !t.shiftKey) {
23
23
  let e = document.activeElement?.tagName;
24
24
  e !== "INPUT" && e !== "TEXTAREA" && (t.preventDefault(), r?.current?.focus());
25
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantKeyboardShortcuts.js","names":[],"sources":["../../src/hooks/useAssistantKeyboardShortcuts.ts"],"sourcesContent":["import { useEffect, type RefObject } from 'react';\nimport { useAssistantStore } from '@/store/assistantStore';\n\ninterface Options {\n panelRef: RefObject<HTMLDivElement | null>;\n inputRef?: RefObject<HTMLTextAreaElement | null>;\n onClose: () => void;\n}\n\n/**\n * Panel-scoped keyboard shortcuts for the AI assistant.\n *\n * - Escape: Close panel\n * - Ctrl+N / Cmd+N: New conversation\n * - Ctrl+E / Cmd+E: Export (triggers click on export button)\n * - /: Focus input (when not already focused)\n */\nexport function useAssistantKeyboardShortcuts({ panelRef, inputRef, onClose }: Options) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n const panel = panelRef.current;\n if (!panel) return;\n\n // Only handle shortcuts when the panel or its children are focused\n if (!panel.contains(document.activeElement) && document.activeElement !== panel) {\n return;\n }\n\n const isModKey = e.ctrlKey || e.metaKey;\n\n // Escape: close panel\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n return;\n }\n\n // Ctrl+N: new conversation\n if (isModKey && e.key === 'n') {\n e.preventDefault();\n useAssistantStore.getState().createConversation();\n return;\n }\n\n // Ctrl+E: export\n if (isModKey && e.key === 'e') {\n e.preventDefault();\n const exportBtn = panel.querySelector(\n '[data-testid=\"assistant-export\"]'\n ) as HTMLButtonElement;\n exportBtn?.click();\n return;\n }\n\n // /: focus input (when not in an input/textarea)\n if (e.key === '/' && !isModKey) {\n const tag = (document.activeElement as HTMLElement)?.tagName;\n if (tag !== 'INPUT' && tag !== 'TEXTAREA') {\n e.preventDefault();\n inputRef?.current?.focus();\n }\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [panelRef, inputRef, onClose]);\n}\n"],"mappings":";;;AAiBA,SAAgB,EAA8B,EAAE,aAAU,aAAU,cAAoB;AACtF,SAAgB;EACd,IAAM,KAAiB,MAAqB;GAC1C,IAAM,IAAQ,EAAS;AAIvB,OAHI,CAAC,KAGD,CAAC,EAAM,SAAS,SAAS,cAAc,IAAI,SAAS,kBAAkB,EACxE;GAGF,IAAM,IAAW,EAAE,WAAW,EAAE;AAGhC,OAAI,EAAE,QAAQ,UAAU;AAEtB,IADA,EAAE,gBAAgB,EAClB,GAAS;AACT;;AAIF,OAAI,KAAY,EAAE,QAAQ,KAAK;AAE7B,IADA,EAAE,gBAAgB,EAClB,EAAkB,UAAU,CAAC,oBAAoB;AACjD;;AAIF,OAAI,KAAY,EAAE,QAAQ,KAAK;AAEX,IADlB,EAAE,gBAAgB,EACA,EAAM,cACtB,qCACD,EACU,OAAO;AAClB;;AAIF,OAAI,EAAE,QAAQ,OAAO,CAAC,GAAU;IAC9B,IAAM,IAAO,SAAS,eAA+B;AACrD,IAAI,MAAQ,WAAW,MAAQ,eAC7B,EAAE,gBAAgB,EAClB,GAAU,SAAS,OAAO;;;AAMhC,SADA,SAAS,iBAAiB,WAAW,EAAc,QACtC,SAAS,oBAAoB,WAAW,EAAc;IAClE;EAAC;EAAU;EAAU;EAAQ,CAAC"}
1
+ {"version":3,"file":"useAssistantKeyboardShortcuts.js","names":[],"sources":["../../src/hooks/useAssistantKeyboardShortcuts.ts"],"sourcesContent":["import { useEffect, type RefObject } from 'react';\nimport { useAssistantStore } from '@/store/assistantStore';\n\ninterface Options {\n panelRef: RefObject<HTMLDivElement | null>;\n inputRef?: RefObject<HTMLTextAreaElement | null>;\n onClose: () => void;\n}\n\n/**\n * Panel-scoped keyboard shortcuts for the AI assistant.\n *\n * All shortcuts only fire when the assistant panel (or one of its children)\n * has focus, so they never override the host page's own shortcuts. We also\n * deliberately avoid the bare `Ctrl+N`/`Cmd+N`/`Ctrl+E`/`Ctrl+W` set the\n * browser owns at the OS level — those couldn't be cancelled reliably\n * anyway and were just adding visible \"shortcut listed, doesn't work\"\n * inconsistencies. The shortcuts here match the in-app shortcuts modal.\n *\n * - Escape: Close panel\n * - Ctrl/Cmd+Shift+N: New conversation\n * - Ctrl/Cmd+Shift+E: Export (triggers click on export button)\n * - /: Focus input (only when no input/textarea is already focused)\n */\nexport function useAssistantKeyboardShortcuts({ panelRef, inputRef, onClose }: Options) {\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n const panel = panelRef.current;\n if (!panel) return;\n\n // Only handle shortcuts when the panel or its children are focused.\n if (!panel.contains(document.activeElement) && document.activeElement !== panel) {\n return;\n }\n\n const isModKey = e.ctrlKey || e.metaKey;\n\n // Escape: close panel\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n return;\n }\n\n // Ctrl/Cmd+Shift+N: new conversation. Shift is required so we don't\n // fight the browser's `Ctrl+N` (new window).\n if (isModKey && e.shiftKey && (e.key === 'N' || e.key === 'n')) {\n e.preventDefault();\n useAssistantStore.getState().createConversation();\n return;\n }\n\n // Ctrl/Cmd+Shift+E: export. Shift required to avoid the browser's\n // `Ctrl+E` (search address bar in Chrome/Edge).\n if (isModKey && e.shiftKey && (e.key === 'E' || e.key === 'e')) {\n e.preventDefault();\n const exportBtn = panel.querySelector(\n '[data-testid=\"assistant-export\"]'\n ) as HTMLButtonElement | null;\n exportBtn?.click();\n return;\n }\n\n // /: focus input (when not in an input/textarea so single-key search\n // typing inside the page doesn't get hijacked).\n if (e.key === '/' && !isModKey && !e.shiftKey) {\n const tag = (document.activeElement as HTMLElement | null)?.tagName;\n if (tag !== 'INPUT' && tag !== 'TEXTAREA') {\n e.preventDefault();\n inputRef?.current?.focus();\n }\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [panelRef, inputRef, onClose]);\n}\n"],"mappings":";;;AAwBA,SAAgB,EAA8B,EAAE,aAAU,aAAU,cAAoB;AACtF,SAAgB;EACd,IAAM,KAAiB,MAAqB;GAC1C,IAAM,IAAQ,EAAS;AAIvB,OAHI,CAAC,KAGD,CAAC,EAAM,SAAS,SAAS,cAAc,IAAI,SAAS,kBAAkB,EACxE;GAGF,IAAM,IAAW,EAAE,WAAW,EAAE;AAGhC,OAAI,EAAE,QAAQ,UAAU;AAEtB,IADA,EAAE,gBAAgB,EAClB,GAAS;AACT;;AAKF,OAAI,KAAY,EAAE,aAAa,EAAE,QAAQ,OAAO,EAAE,QAAQ,MAAM;AAE9D,IADA,EAAE,gBAAgB,EAClB,EAAkB,UAAU,CAAC,oBAAoB;AACjD;;AAKF,OAAI,KAAY,EAAE,aAAa,EAAE,QAAQ,OAAO,EAAE,QAAQ,MAAM;AAE5C,IADlB,EAAE,gBAAgB,EACA,EAAM,cACtB,qCACD,EACU,OAAO;AAClB;;AAKF,OAAI,EAAE,QAAQ,OAAO,CAAC,KAAY,CAAC,EAAE,UAAU;IAC7C,IAAM,IAAO,SAAS,eAAsC;AAC5D,IAAI,MAAQ,WAAW,MAAQ,eAC7B,EAAE,gBAAgB,EAClB,GAAU,SAAS,OAAO;;;AAMhC,SADA,SAAS,iBAAiB,WAAW,EAAc,QACtC,SAAS,oBAAoB,WAAW,EAAc;IAClE;EAAC;EAAU;EAAU;EAAQ,CAAC"}
@@ -61,6 +61,10 @@ var s = {
61
61
  adminTab: "templates",
62
62
  selectedSessionIds: [],
63
63
  isFullscreen: !1,
64
+ sessionsRefreshTrigger: 0,
65
+ sdkAuthPrompt: null,
66
+ bumpSessionsRefresh: () => e((e) => ({ sessionsRefreshTrigger: e.sessionsRefreshTrigger + 1 })),
67
+ setSdkAuthPrompt: (t) => e({ sdkAuthPrompt: t }),
64
68
  openSession: (n, i) => {
65
69
  let a = t();
66
70
  if (a.tabs.find((e) => e.sessionId === n)) {
@@ -1 +1 @@
1
- {"version":3,"file":"agentManagerStore.js","names":[],"sources":["../../src/store/agentManagerStore.ts"],"sourcesContent":["/**\n * Agent Manager state management.\n *\n * Zustand store with profile-scoped persistence for multi-session\n * tabbed agent management. Follows the same pattern as assistantStore.ts.\n */\n\nimport { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\nimport type {\n AdminTab,\n AgentManagerMessage,\n AgentManagerSessionState,\n AgentManagerTab,\n AgentSdkType,\n DetailPanelTab,\n ProviderMode,\n SessionFilters,\n SidebarGroupBy,\n} from '@/types/agentManager';\n\n/** Default state for a new session */\nfunction createDefaultSessionState(): AgentManagerSessionState {\n return {\n messages: [],\n model: 'claude-sonnet-4-20250514',\n sdk: 'claude',\n mode: 'sdk',\n mcpServers: [],\n voiceEnabled: false,\n showThinking: true,\n contextHistoryLimit: 20,\n status: 'idle',\n rootPath: null,\n contextLevel: 'agent',\n vibeId: null,\n };\n}\n\nconst VALID_SDKS = new Set<AgentSdkType>([\n 'claude',\n 'codex',\n 'opencode',\n 'gemini',\n 'openai-compat',\n 'goose',\n 'amp',\n 'copilot',\n 'crush',\n 'pi',\n 'aider',\n 'plandex',\n]);\n\nfunction asSdk(value: unknown): AgentSdkType | null {\n return typeof value === 'string' && VALID_SDKS.has(value as AgentSdkType)\n ? (value as AgentSdkType)\n : null;\n}\n\nfunction asMode(value: unknown): ProviderMode | null {\n return value === 'sdk' || value === 'cli' ? value : null;\n}\n\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\n\ninterface AgentManagerState {\n // ── Tab management ──\n tabs: AgentManagerTab[];\n activeTabSessionId: string | null;\n tabLimit: number; // Max visible tabs before scrolling (default 10)\n\n // ── Per-session state ──\n sessionStates: Record<string, AgentManagerSessionState>;\n\n // ── Sidebar ──\n sidebarOpen: boolean;\n sidebarSearchQuery: string;\n sidebarFilters: SessionFilters;\n sidebarGroupBy: SidebarGroupBy;\n\n // ── Detail panel ──\n detailPanelOpen: boolean;\n detailPanelTab: DetailPanelTab;\n\n // ── Admin tab ──\n adminTab: AdminTab;\n\n // ── Bulk selection ──\n selectedSessionIds: string[];\n\n // ── Fullscreen ──\n isFullscreen: boolean;\n\n // ── Tab actions ──\n openSession: (sessionId: string, name?: string) => void;\n closeTab: (sessionId: string) => void;\n pinTab: (sessionId: string) => void;\n renameTab: (sessionId: string, name: string) => void;\n setTabLimit: (limit: number) => void;\n reorderTabs: (tabs: AgentManagerTab[]) => void;\n setActiveTab: (sessionId: string) => void;\n\n // ── Session state actions ──\n addMessage: (sessionId: string, message: AgentManagerMessage) => void;\n updateMessage: (sessionId: string, messageId: string, content: string) => void;\n setSessionModel: (sessionId: string, model: string) => void;\n setSessionSdk: (sessionId: string, sdk: AgentSdkType) => void;\n setSessionMode: (sessionId: string, mode: ProviderMode) => void;\n toggleVoice: (sessionId: string) => void;\n toggleThinking: (sessionId: string) => void;\n setSessionStatus: (sessionId: string, status: AgentManagerSessionState['status']) => void;\n setSessionRootPath: (sessionId: string, rootPath: string | null) => void;\n setSessionContextLevel: (\n sessionId: string,\n level: AgentManagerSessionState['contextLevel']\n ) => void;\n setSessionVibe: (sessionId: string, vibeId: string | null, rootPath: string | null) => void;\n hydrateSessionConfig: (\n sessionId: string,\n metadata: { agentType?: string | null; config?: Record<string, unknown> | null }\n ) => void;\n\n // ── Sidebar actions ──\n toggleSidebar: () => void;\n setSidebarOpen: (open: boolean) => void;\n setSidebarSearchQuery: (query: string) => void;\n setSidebarFilters: (filters: Partial<SessionFilters>) => void;\n resetSidebarFilters: () => void;\n setSidebarGroupBy: (groupBy: SidebarGroupBy) => void;\n\n // ── Detail panel actions ──\n toggleDetailPanel: () => void;\n setDetailPanelOpen: (open: boolean) => void;\n setDetailPanelTab: (tab: DetailPanelTab) => void;\n\n // ── Admin tab actions ──\n setAdminTab: (tab: AdminTab) => void;\n\n // ── Bulk selection actions ──\n toggleSessionSelection: (sessionId: string) => void;\n selectAllSessions: (sessionIds: string[]) => void;\n clearSelection: () => void;\n\n // ── Fullscreen ──\n toggleFullscreen: () => void;\n\n // ── Reset ──\n resetStore: () => void;\n}\n\nconst defaultFilters: SessionFilters = {\n status: [],\n model: [],\n sdk: [],\n dateRange: { from: null, to: null },\n searchQuery: '',\n};\n\nexport const useAgentManagerStore = create<AgentManagerState>()(\n persist(\n (set, get) => ({\n tabs: [],\n activeTabSessionId: null,\n tabLimit: 10,\n sessionStates: {},\n sidebarOpen: true,\n sidebarSearchQuery: '',\n sidebarFilters: { ...defaultFilters },\n sidebarGroupBy: 'date',\n detailPanelOpen: false,\n detailPanelTab: 'info',\n adminTab: 'templates',\n selectedSessionIds: [],\n isFullscreen: false,\n\n // ── Tab actions ──\n\n openSession: (sessionId: string, name?: string) => {\n const state = get();\n const existingTab = state.tabs.find((t) => t.sessionId === sessionId);\n\n if (existingTab) {\n set((prev) => ({\n activeTabSessionId: sessionId,\n sessionStates: {\n ...prev.sessionStates,\n [sessionId]: prev.sessionStates[sessionId] ?? createDefaultSessionState(),\n },\n }));\n return;\n }\n\n const newTab: AgentManagerTab = {\n sessionId,\n name: name ?? `Session ${state.tabs.length + 1}`,\n pinned: false,\n order: state.tabs.length,\n };\n\n set((prev) => ({\n tabs: [...prev.tabs, newTab],\n activeTabSessionId: sessionId,\n sessionStates: {\n ...prev.sessionStates,\n [sessionId]: prev.sessionStates[sessionId] ?? createDefaultSessionState(),\n },\n }));\n },\n\n closeTab: (sessionId: string) =>\n set((state) => {\n const filtered = state.tabs.filter((t) => t.sessionId !== sessionId);\n const nextSessionStates = { ...state.sessionStates };\n delete nextSessionStates[sessionId];\n\n let nextActive = state.activeTabSessionId;\n if (nextActive === sessionId) {\n nextActive = filtered.length > 0 ? filtered[filtered.length - 1].sessionId : null;\n }\n\n return {\n tabs: filtered,\n activeTabSessionId: nextActive,\n sessionStates: nextSessionStates,\n };\n }),\n\n pinTab: (sessionId: string) =>\n set((state) => ({\n tabs: state.tabs.map((t) =>\n t.sessionId === sessionId ? { ...t, pinned: !t.pinned } : t\n ),\n })),\n\n setTabLimit: (limit: number) => set({ tabLimit: Math.max(1, limit) }),\n\n renameTab: (sessionId: string, name: string) =>\n set((state) => ({\n tabs: state.tabs.map((t) => (t.sessionId === sessionId ? { ...t, name } : t)),\n })),\n\n reorderTabs: (tabs: AgentManagerTab[]) => set({ tabs }),\n\n setActiveTab: (sessionId: string) =>\n set((state) => ({\n activeTabSessionId: sessionId,\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: state.sessionStates[sessionId] ?? createDefaultSessionState(),\n },\n })),\n\n // ── Session state actions ──\n\n addMessage: (sessionId: string, message: AgentManagerMessage) =>\n set((state) => {\n const current = state.sessionStates[sessionId] ?? createDefaultSessionState();\n if (current.messages.some((existing) => existing.id === message.id)) return state;\n\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...current,\n messages: [...current.messages, message],\n },\n },\n };\n }),\n\n updateMessage: (sessionId: string, messageId: string, content: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...sessionState,\n messages: sessionState.messages.map((m) =>\n m.id === messageId ? { ...m, content } : m\n ),\n },\n },\n };\n }),\n\n setSessionModel: (sessionId: string, model: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, model },\n },\n };\n }),\n\n setSessionSdk: (sessionId: string, sdk: AgentSdkType) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, sdk },\n },\n };\n }),\n\n setSessionMode: (sessionId: string, mode: ProviderMode) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, mode },\n },\n };\n }),\n\n toggleVoice: (sessionId: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...sessionState,\n voiceEnabled: !sessionState.voiceEnabled,\n },\n },\n };\n }),\n\n toggleThinking: (sessionId: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...sessionState,\n showThinking: !sessionState.showThinking,\n },\n },\n };\n }),\n\n setSessionStatus: (sessionId: string, status: AgentManagerSessionState['status']) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, status },\n },\n };\n }),\n\n setSessionRootPath: (sessionId: string, rootPath: string | null) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, rootPath },\n },\n };\n }),\n\n setSessionContextLevel: (\n sessionId: string,\n level: AgentManagerSessionState['contextLevel']\n ) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, contextLevel: level },\n },\n };\n }),\n\n setSessionVibe: (sessionId: string, vibeId: string | null, rootPath: string | null) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, vibeId, rootPath },\n },\n };\n }),\n\n hydrateSessionConfig: (sessionId, metadata) =>\n set((state) => {\n const current = state.sessionStates[sessionId] ?? createDefaultSessionState();\n const config = metadata.config ?? {};\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...current,\n sdk: asSdk(metadata.agentType) ?? current.sdk,\n mode: asMode(config.mode) ?? current.mode,\n model: typeof config.model === 'string' ? config.model : current.model,\n },\n },\n };\n }),\n\n // ── Sidebar actions ──\n\n toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),\n\n setSidebarOpen: (open: boolean) => set({ sidebarOpen: open }),\n\n setSidebarSearchQuery: (query: string) => set({ sidebarSearchQuery: query }),\n\n setSidebarFilters: (filters: Partial<SessionFilters>) =>\n set((state) => ({\n sidebarFilters: { ...state.sidebarFilters, ...filters },\n })),\n\n resetSidebarFilters: () => set({ sidebarFilters: { ...defaultFilters } }),\n\n setSidebarGroupBy: (groupBy: SidebarGroupBy) => set({ sidebarGroupBy: groupBy }),\n\n // ── Detail panel actions ──\n\n toggleDetailPanel: () => set((state) => ({ detailPanelOpen: !state.detailPanelOpen })),\n\n setDetailPanelOpen: (open: boolean) => set({ detailPanelOpen: open }),\n\n setDetailPanelTab: (tab: DetailPanelTab) => set({ detailPanelTab: tab }),\n\n // ── Admin tab actions ──\n\n setAdminTab: (tab: AdminTab) => set({ adminTab: tab }),\n\n // ── Bulk selection actions ──\n\n toggleSessionSelection: (sessionId: string) =>\n set((state) => {\n const isSelected = state.selectedSessionIds.includes(sessionId);\n return {\n selectedSessionIds: isSelected\n ? state.selectedSessionIds.filter((id) => id !== sessionId)\n : [...state.selectedSessionIds, sessionId],\n };\n }),\n\n selectAllSessions: (sessionIds: string[]) => set({ selectedSessionIds: sessionIds }),\n\n clearSelection: () => set({ selectedSessionIds: [] }),\n\n // ── Fullscreen ──\n\n toggleFullscreen: () => set((state) => ({ isFullscreen: !state.isFullscreen })),\n\n // ── Reset ──\n\n resetStore: () =>\n set({\n tabs: [],\n activeTabSessionId: null,\n sessionStates: {},\n sidebarOpen: true,\n sidebarSearchQuery: '',\n sidebarFilters: { ...defaultFilters },\n sidebarGroupBy: 'date',\n detailPanelOpen: false,\n detailPanelTab: 'info',\n adminTab: 'templates',\n selectedSessionIds: [],\n }),\n }),\n {\n name: 'vibecontrols-agent-manager',\n storage: createProfileScopedStorage(),\n partialize: (state) => ({\n tabs: state.tabs,\n activeTabSessionId: state.activeTabSessionId,\n sidebarOpen: state.sidebarOpen,\n sidebarGroupBy: state.sidebarGroupBy,\n detailPanelOpen: state.detailPanelOpen,\n detailPanelTab: state.detailPanelTab,\n adminTab: state.adminTab,\n isFullscreen: state.isFullscreen,\n }),\n }\n )\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"agentManagerStore.js","names":[],"sources":["../../src/store/agentManagerStore.ts"],"sourcesContent":["/**\n * Agent Manager state management.\n *\n * Zustand store with profile-scoped persistence for multi-session\n * tabbed agent management. Follows the same pattern as assistantStore.ts.\n */\n\nimport { create } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\nimport type {\n AdminTab,\n AgentManagerMessage,\n AgentManagerSessionState,\n AgentManagerTab,\n AgentSdkType,\n DetailPanelTab,\n ProviderMode,\n SessionFilters,\n SidebarGroupBy,\n} from '@/types/agentManager';\n\n/** Default state for a new session */\nfunction createDefaultSessionState(): AgentManagerSessionState {\n return {\n messages: [],\n model: 'claude-sonnet-4-20250514',\n sdk: 'claude',\n mode: 'sdk',\n mcpServers: [],\n voiceEnabled: false,\n showThinking: true,\n contextHistoryLimit: 20,\n status: 'idle',\n rootPath: null,\n contextLevel: 'agent',\n vibeId: null,\n };\n}\n\nconst VALID_SDKS = new Set<AgentSdkType>([\n 'claude',\n 'codex',\n 'opencode',\n 'gemini',\n 'openai-compat',\n 'goose',\n 'amp',\n 'copilot',\n 'crush',\n 'pi',\n 'aider',\n 'plandex',\n]);\n\nfunction asSdk(value: unknown): AgentSdkType | null {\n return typeof value === 'string' && VALID_SDKS.has(value as AgentSdkType)\n ? (value as AgentSdkType)\n : null;\n}\n\nfunction asMode(value: unknown): ProviderMode | null {\n return value === 'sdk' || value === 'cli' ? value : null;\n}\n\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\n\ninterface AgentManagerState {\n // ── Tab management ──\n tabs: AgentManagerTab[];\n activeTabSessionId: string | null;\n tabLimit: number; // Max visible tabs before scrolling (default 10)\n\n // ── Per-session state ──\n sessionStates: Record<string, AgentManagerSessionState>;\n\n // ── Sidebar ──\n sidebarOpen: boolean;\n sidebarSearchQuery: string;\n sidebarFilters: SessionFilters;\n sidebarGroupBy: SidebarGroupBy;\n\n // ── Detail panel ──\n detailPanelOpen: boolean;\n detailPanelTab: DetailPanelTab;\n\n // ── Admin tab ──\n adminTab: AdminTab;\n\n // ── Bulk selection ──\n selectedSessionIds: string[];\n\n // ── Fullscreen ──\n isFullscreen: boolean;\n\n // ── Cross-component refresh signal (incremented after backend mutations\n // that affect the sessions list). Components watch this to re-fetch. ──\n sessionsRefreshTrigger: number;\n\n // ── SDK auth prompt request. Set when a streaming call returns an\n // SDK-auth-missing error so the chat surface can open the credentials\n // modal instead of erroring out. Null when no prompt is requested. ──\n sdkAuthPrompt: { agentId: string; reason: string } | null;\n\n // ── Tab actions ──\n openSession: (sessionId: string, name?: string) => void;\n closeTab: (sessionId: string) => void;\n pinTab: (sessionId: string) => void;\n renameTab: (sessionId: string, name: string) => void;\n setTabLimit: (limit: number) => void;\n reorderTabs: (tabs: AgentManagerTab[]) => void;\n setActiveTab: (sessionId: string) => void;\n\n // ── Session state actions ──\n addMessage: (sessionId: string, message: AgentManagerMessage) => void;\n updateMessage: (sessionId: string, messageId: string, content: string) => void;\n setSessionModel: (sessionId: string, model: string) => void;\n setSessionSdk: (sessionId: string, sdk: AgentSdkType) => void;\n setSessionMode: (sessionId: string, mode: ProviderMode) => void;\n toggleVoice: (sessionId: string) => void;\n toggleThinking: (sessionId: string) => void;\n setSessionStatus: (sessionId: string, status: AgentManagerSessionState['status']) => void;\n setSessionRootPath: (sessionId: string, rootPath: string | null) => void;\n setSessionContextLevel: (\n sessionId: string,\n level: AgentManagerSessionState['contextLevel']\n ) => void;\n setSessionVibe: (sessionId: string, vibeId: string | null, rootPath: string | null) => void;\n hydrateSessionConfig: (\n sessionId: string,\n metadata: { agentType?: string | null; config?: Record<string, unknown> | null }\n ) => void;\n\n // ── Sidebar actions ──\n toggleSidebar: () => void;\n setSidebarOpen: (open: boolean) => void;\n setSidebarSearchQuery: (query: string) => void;\n setSidebarFilters: (filters: Partial<SessionFilters>) => void;\n resetSidebarFilters: () => void;\n setSidebarGroupBy: (groupBy: SidebarGroupBy) => void;\n\n // ── Detail panel actions ──\n toggleDetailPanel: () => void;\n setDetailPanelOpen: (open: boolean) => void;\n setDetailPanelTab: (tab: DetailPanelTab) => void;\n\n // ── Admin tab actions ──\n setAdminTab: (tab: AdminTab) => void;\n\n // ── Bulk selection actions ──\n toggleSessionSelection: (sessionId: string) => void;\n selectAllSessions: (sessionIds: string[]) => void;\n clearSelection: () => void;\n\n // ── Fullscreen ──\n toggleFullscreen: () => void;\n\n // ── Refresh + SDK-auth-prompt actions ──\n bumpSessionsRefresh: () => void;\n setSdkAuthPrompt: (prompt: { agentId: string; reason: string } | null) => void;\n\n // ── Reset ──\n resetStore: () => void;\n}\n\nconst defaultFilters: SessionFilters = {\n status: [],\n model: [],\n sdk: [],\n dateRange: { from: null, to: null },\n searchQuery: '',\n};\n\nexport const useAgentManagerStore = create<AgentManagerState>()(\n persist(\n (set, get) => ({\n tabs: [],\n activeTabSessionId: null,\n tabLimit: 10,\n sessionStates: {},\n sidebarOpen: true,\n sidebarSearchQuery: '',\n sidebarFilters: { ...defaultFilters },\n sidebarGroupBy: 'date',\n detailPanelOpen: false,\n detailPanelTab: 'info',\n adminTab: 'templates',\n selectedSessionIds: [],\n isFullscreen: false,\n sessionsRefreshTrigger: 0,\n sdkAuthPrompt: null,\n\n bumpSessionsRefresh: () =>\n set((state) => ({ sessionsRefreshTrigger: state.sessionsRefreshTrigger + 1 })),\n setSdkAuthPrompt: (prompt) => set({ sdkAuthPrompt: prompt }),\n\n // ── Tab actions ──\n\n openSession: (sessionId: string, name?: string) => {\n const state = get();\n const existingTab = state.tabs.find((t) => t.sessionId === sessionId);\n\n if (existingTab) {\n set((prev) => ({\n activeTabSessionId: sessionId,\n sessionStates: {\n ...prev.sessionStates,\n [sessionId]: prev.sessionStates[sessionId] ?? createDefaultSessionState(),\n },\n }));\n return;\n }\n\n const newTab: AgentManagerTab = {\n sessionId,\n name: name ?? `Session ${state.tabs.length + 1}`,\n pinned: false,\n order: state.tabs.length,\n };\n\n set((prev) => ({\n tabs: [...prev.tabs, newTab],\n activeTabSessionId: sessionId,\n sessionStates: {\n ...prev.sessionStates,\n [sessionId]: prev.sessionStates[sessionId] ?? createDefaultSessionState(),\n },\n }));\n },\n\n closeTab: (sessionId: string) =>\n set((state) => {\n const filtered = state.tabs.filter((t) => t.sessionId !== sessionId);\n const nextSessionStates = { ...state.sessionStates };\n delete nextSessionStates[sessionId];\n\n let nextActive = state.activeTabSessionId;\n if (nextActive === sessionId) {\n nextActive = filtered.length > 0 ? filtered[filtered.length - 1].sessionId : null;\n }\n\n return {\n tabs: filtered,\n activeTabSessionId: nextActive,\n sessionStates: nextSessionStates,\n };\n }),\n\n pinTab: (sessionId: string) =>\n set((state) => ({\n tabs: state.tabs.map((t) =>\n t.sessionId === sessionId ? { ...t, pinned: !t.pinned } : t\n ),\n })),\n\n setTabLimit: (limit: number) => set({ tabLimit: Math.max(1, limit) }),\n\n renameTab: (sessionId: string, name: string) =>\n set((state) => ({\n tabs: state.tabs.map((t) => (t.sessionId === sessionId ? { ...t, name } : t)),\n })),\n\n reorderTabs: (tabs: AgentManagerTab[]) => set({ tabs }),\n\n setActiveTab: (sessionId: string) =>\n set((state) => ({\n activeTabSessionId: sessionId,\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: state.sessionStates[sessionId] ?? createDefaultSessionState(),\n },\n })),\n\n // ── Session state actions ──\n\n addMessage: (sessionId: string, message: AgentManagerMessage) =>\n set((state) => {\n const current = state.sessionStates[sessionId] ?? createDefaultSessionState();\n if (current.messages.some((existing) => existing.id === message.id)) return state;\n\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...current,\n messages: [...current.messages, message],\n },\n },\n };\n }),\n\n updateMessage: (sessionId: string, messageId: string, content: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...sessionState,\n messages: sessionState.messages.map((m) =>\n m.id === messageId ? { ...m, content } : m\n ),\n },\n },\n };\n }),\n\n setSessionModel: (sessionId: string, model: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, model },\n },\n };\n }),\n\n setSessionSdk: (sessionId: string, sdk: AgentSdkType) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, sdk },\n },\n };\n }),\n\n setSessionMode: (sessionId: string, mode: ProviderMode) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, mode },\n },\n };\n }),\n\n toggleVoice: (sessionId: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...sessionState,\n voiceEnabled: !sessionState.voiceEnabled,\n },\n },\n };\n }),\n\n toggleThinking: (sessionId: string) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...sessionState,\n showThinking: !sessionState.showThinking,\n },\n },\n };\n }),\n\n setSessionStatus: (sessionId: string, status: AgentManagerSessionState['status']) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, status },\n },\n };\n }),\n\n setSessionRootPath: (sessionId: string, rootPath: string | null) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, rootPath },\n },\n };\n }),\n\n setSessionContextLevel: (\n sessionId: string,\n level: AgentManagerSessionState['contextLevel']\n ) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, contextLevel: level },\n },\n };\n }),\n\n setSessionVibe: (sessionId: string, vibeId: string | null, rootPath: string | null) =>\n set((state) => {\n const sessionState = state.sessionStates[sessionId];\n if (!sessionState) return state;\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: { ...sessionState, vibeId, rootPath },\n },\n };\n }),\n\n hydrateSessionConfig: (sessionId, metadata) =>\n set((state) => {\n const current = state.sessionStates[sessionId] ?? createDefaultSessionState();\n const config = metadata.config ?? {};\n return {\n sessionStates: {\n ...state.sessionStates,\n [sessionId]: {\n ...current,\n sdk: asSdk(metadata.agentType) ?? current.sdk,\n mode: asMode(config.mode) ?? current.mode,\n model: typeof config.model === 'string' ? config.model : current.model,\n },\n },\n };\n }),\n\n // ── Sidebar actions ──\n\n toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),\n\n setSidebarOpen: (open: boolean) => set({ sidebarOpen: open }),\n\n setSidebarSearchQuery: (query: string) => set({ sidebarSearchQuery: query }),\n\n setSidebarFilters: (filters: Partial<SessionFilters>) =>\n set((state) => ({\n sidebarFilters: { ...state.sidebarFilters, ...filters },\n })),\n\n resetSidebarFilters: () => set({ sidebarFilters: { ...defaultFilters } }),\n\n setSidebarGroupBy: (groupBy: SidebarGroupBy) => set({ sidebarGroupBy: groupBy }),\n\n // ── Detail panel actions ──\n\n toggleDetailPanel: () => set((state) => ({ detailPanelOpen: !state.detailPanelOpen })),\n\n setDetailPanelOpen: (open: boolean) => set({ detailPanelOpen: open }),\n\n setDetailPanelTab: (tab: DetailPanelTab) => set({ detailPanelTab: tab }),\n\n // ── Admin tab actions ──\n\n setAdminTab: (tab: AdminTab) => set({ adminTab: tab }),\n\n // ── Bulk selection actions ──\n\n toggleSessionSelection: (sessionId: string) =>\n set((state) => {\n const isSelected = state.selectedSessionIds.includes(sessionId);\n return {\n selectedSessionIds: isSelected\n ? state.selectedSessionIds.filter((id) => id !== sessionId)\n : [...state.selectedSessionIds, sessionId],\n };\n }),\n\n selectAllSessions: (sessionIds: string[]) => set({ selectedSessionIds: sessionIds }),\n\n clearSelection: () => set({ selectedSessionIds: [] }),\n\n // ── Fullscreen ──\n\n toggleFullscreen: () => set((state) => ({ isFullscreen: !state.isFullscreen })),\n\n // ── Reset ──\n\n resetStore: () =>\n set({\n tabs: [],\n activeTabSessionId: null,\n sessionStates: {},\n sidebarOpen: true,\n sidebarSearchQuery: '',\n sidebarFilters: { ...defaultFilters },\n sidebarGroupBy: 'date',\n detailPanelOpen: false,\n detailPanelTab: 'info',\n adminTab: 'templates',\n selectedSessionIds: [],\n }),\n }),\n {\n name: 'vibecontrols-agent-manager',\n storage: createProfileScopedStorage(),\n partialize: (state) => ({\n tabs: state.tabs,\n activeTabSessionId: state.activeTabSessionId,\n sidebarOpen: state.sidebarOpen,\n sidebarGroupBy: state.sidebarGroupBy,\n detailPanelOpen: state.detailPanelOpen,\n detailPanelTab: state.detailPanelTab,\n adminTab: state.adminTab,\n isFullscreen: state.isFullscreen,\n }),\n }\n )\n);\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-vibecontrols",
3
- "version": "2026.514.3",
3
+ "version": "2026.514.5",
4
4
  "description": "VibeControls microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [