@burdenoff/microfe-vibecontrols 2026.522.5 → 2026.522.6
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.
- package/dist/components/ai/AIModeToggle.js +43 -0
- package/dist/components/ai/AIModeToggle.js.map +1 -0
- package/dist/components/vibe/VibeAgentEmptyState.js.map +1 -1
- package/dist/pages/CatalogPage.js.map +1 -1
- package/dist/pages/ComponentsPage.js.map +1 -1
- package/dist/pages/TemplatesPage.js.map +1 -1
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/ai/AIPage.js +91 -104
- package/dist/pages/ai/AIPage.js.map +1 -1
- package/dist/pages/ai/AgentManagerPage.js +99 -86
- package/dist/pages/ai/AgentManagerPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -21,135 +21,148 @@ import { BridleConfigPanel as x } from "../../components/agent-manager/BridleCon
|
|
|
21
21
|
import { AgentManagerCenter as S } from "../../components/agent-manager/AgentManagerCenter.js";
|
|
22
22
|
import { AgentManagerDetailPanel as C } from "../../components/agent-manager/AgentManagerDetailPanel.js";
|
|
23
23
|
import { ClaudeCredentialsCard as w } from "../../components/ai/ClaudeCredentialsCard.js";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
24
|
+
import { AIModeToggle as T } from "../../components/ai/AIModeToggle.js";
|
|
25
|
+
import { useAgentManagerKeyboard as E } from "../../hooks/useAgentManagerKeyboard.js";
|
|
26
|
+
import { Suspense as D, useCallback as O, useEffect as k, useMemo as A } from "react";
|
|
27
|
+
import { MessagesSquare as j } from "lucide-react";
|
|
28
|
+
import { useParams as M } from "react-router-dom";
|
|
29
|
+
import { jsx as N, jsxs as P } from "react/jsx-runtime";
|
|
30
|
+
import { MotionPage as F } from "@burdenoff/fe-libs/shared/motion";
|
|
30
31
|
//#region src/pages/ai/AgentManagerPage.tsx
|
|
31
|
-
function
|
|
32
|
-
let { tab:
|
|
33
|
-
if (
|
|
34
|
-
let e =
|
|
32
|
+
function I() {
|
|
33
|
+
let { tab: I, sessionId: L } = M(), R = e(), z = t(), { agents: B, loading: V, error: H } = r(), U = n((e) => e.activeAgentId), W = A(() => {
|
|
34
|
+
if (U) {
|
|
35
|
+
let e = B.find((e) => e.id === U);
|
|
35
36
|
if (e) return e;
|
|
36
37
|
}
|
|
37
|
-
return
|
|
38
|
-
}, [
|
|
39
|
-
id:
|
|
40
|
-
profile:
|
|
41
|
-
}), [
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
return B.find((e) => e.isActive && e.tunnelUrl && e.agentApiKey) ?? null;
|
|
39
|
+
}, [B, U]), G = W?.id ?? "", { active: K } = m(W?.id ?? null), q = A(() => ({
|
|
40
|
+
id: G,
|
|
41
|
+
profile: K
|
|
42
|
+
}), [G, K]), J = v((e) => e.openSession), Y = v((e) => e.activeTabSessionId), { initialLoading: X } = l(A(() => [u, ...d], []), G || null);
|
|
43
|
+
k(() => {
|
|
44
|
+
L && G && J(L, `Session ${L.slice(0, 8)}`);
|
|
44
45
|
}, [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
L,
|
|
47
|
+
G,
|
|
48
|
+
J
|
|
48
49
|
]);
|
|
49
|
-
let
|
|
50
|
-
if (
|
|
51
|
-
await _(
|
|
50
|
+
let Z = O(async (e) => {
|
|
51
|
+
if (G) try {
|
|
52
|
+
await _(q, e), o() && s("success");
|
|
52
53
|
} catch {
|
|
53
54
|
o() && s("error");
|
|
54
55
|
}
|
|
55
|
-
}, [
|
|
56
|
-
if (
|
|
57
|
-
await g(
|
|
56
|
+
}, [q]), Q = O(async (e) => {
|
|
57
|
+
if (G) try {
|
|
58
|
+
await g(q, e), o() && s("success");
|
|
58
59
|
} catch {
|
|
59
60
|
o() && s("error");
|
|
60
61
|
}
|
|
61
|
-
}, [
|
|
62
|
-
return
|
|
62
|
+
}, [q]);
|
|
63
|
+
return E(), V || G && X ? /* @__PURE__ */ N(F, {
|
|
63
64
|
className: "flex items-center justify-center h-full bg-bg-surface",
|
|
64
|
-
children: /* @__PURE__ */
|
|
65
|
-
}) :
|
|
65
|
+
children: /* @__PURE__ */ N(i, { message: R("vibecontrols.pages.ai.detectingAgent", "Detecting agent and plugin availability…") })
|
|
66
|
+
}) : H ? /* @__PURE__ */ N(F, {
|
|
66
67
|
className: "flex items-center justify-center h-full bg-bg-surface",
|
|
67
|
-
children: /* @__PURE__ */
|
|
68
|
+
children: /* @__PURE__ */ N(a, {
|
|
68
69
|
title: "Failed to load agents",
|
|
69
|
-
message:
|
|
70
|
+
message: H.message
|
|
70
71
|
})
|
|
71
|
-
}) :
|
|
72
|
+
}) : B.length === 0 ? /* @__PURE__ */ N(F, {
|
|
72
73
|
className: "flex items-center justify-center h-full bg-bg-surface p-8",
|
|
73
|
-
children: /* @__PURE__ */
|
|
74
|
-
icon: /* @__PURE__ */
|
|
75
|
-
title:
|
|
76
|
-
description:
|
|
77
|
-
action: /* @__PURE__ */
|
|
78
|
-
onClick: () =>
|
|
74
|
+
children: /* @__PURE__ */ N(c, {
|
|
75
|
+
icon: /* @__PURE__ */ N(j, { className: "w-8 h-8 text-text-secondary" }),
|
|
76
|
+
title: R("vibecontrols.pages.ai.noActiveAgentAvailable", "No agents available"),
|
|
77
|
+
description: R("vibecontrols.pages.ai.agentManagerRequiresAgent", "The Agent Manager needs at least one vibecontrols agent. Add one or start an existing one."),
|
|
78
|
+
action: /* @__PURE__ */ N("button", {
|
|
79
|
+
onClick: () => z("/agents"),
|
|
79
80
|
className: "px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors text-sm",
|
|
80
|
-
children:
|
|
81
|
+
children: R("vibecontrols.pages.ai.goToAgents", "Go to Agents")
|
|
81
82
|
})
|
|
82
83
|
})
|
|
83
|
-
}) :
|
|
84
|
+
}) : I === "config" ? /* @__PURE__ */ P(F, {
|
|
84
85
|
className: "flex flex-col h-[calc(100vh-6.5rem)] bg-bg-surface overflow-hidden",
|
|
85
|
-
children: [/* @__PURE__ */
|
|
86
|
+
children: [/* @__PURE__ */ P("div", {
|
|
86
87
|
className: "flex items-center justify-between gap-3 border-b border-border-default px-4 sm:px-6 py-3",
|
|
87
|
-
children: [/* @__PURE__ */
|
|
88
|
+
children: [/* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("p", {
|
|
88
89
|
className: "text-xs uppercase tracking-wide text-text-secondary",
|
|
89
|
-
children:
|
|
90
|
-
}), /* @__PURE__ */
|
|
90
|
+
children: R("vibecontrols.pages.ai.contextLabel", "Active context")
|
|
91
|
+
}), /* @__PURE__ */ N("h2", {
|
|
91
92
|
className: "text-sm font-semibold text-text-primary mt-0.5",
|
|
92
|
-
children:
|
|
93
|
-
})] }), /* @__PURE__ */
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
children: R("vibecontrols.pages.ai.configHeading", "AI configuration")
|
|
94
|
+
})] }), /* @__PURE__ */ P("div", {
|
|
95
|
+
className: "flex items-center gap-3",
|
|
96
|
+
children: [/* @__PURE__ */ N(T, {
|
|
97
|
+
aiHref: "/ai",
|
|
98
|
+
activeMode: "ai"
|
|
99
|
+
}), /* @__PURE__ */ N(h, {
|
|
100
|
+
label: R("vibecontrols.pages.ai.agentSelectorLabel", "Agent"),
|
|
101
|
+
compact: !0
|
|
102
|
+
})]
|
|
96
103
|
})]
|
|
97
|
-
}), /* @__PURE__ */
|
|
104
|
+
}), /* @__PURE__ */ N("div", {
|
|
98
105
|
className: "flex-1 overflow-auto p-4 sm:p-6 space-y-6",
|
|
99
|
-
children: /* @__PURE__ */
|
|
100
|
-
agentId:
|
|
101
|
-
children: [/* @__PURE__ */
|
|
106
|
+
children: /* @__PURE__ */ P(p, {
|
|
107
|
+
agentId: G || null,
|
|
108
|
+
children: [/* @__PURE__ */ N(w, { agent: q }), /* @__PURE__ */ N(x, { agent: q })]
|
|
102
109
|
})
|
|
103
110
|
})]
|
|
104
|
-
}) : /* @__PURE__ */
|
|
111
|
+
}) : /* @__PURE__ */ P(F, {
|
|
105
112
|
className: "flex flex-col h-[calc(100vh-6.5rem)] bg-bg-surface overflow-hidden",
|
|
106
|
-
children: [/* @__PURE__ */
|
|
113
|
+
children: [/* @__PURE__ */ P("div", {
|
|
107
114
|
className: "flex items-center justify-between gap-3 border-b border-border-default px-4 sm:px-6 py-3",
|
|
108
|
-
children: [/* @__PURE__ */
|
|
115
|
+
children: [/* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("p", {
|
|
109
116
|
className: "text-xs uppercase tracking-wide text-text-secondary",
|
|
110
|
-
children:
|
|
111
|
-
}), /* @__PURE__ */
|
|
117
|
+
children: R("vibecontrols.pages.ai.contextLabel", "Active context")
|
|
118
|
+
}), /* @__PURE__ */ N("h2", {
|
|
112
119
|
className: "text-sm font-semibold text-text-primary mt-0.5",
|
|
113
|
-
children:
|
|
114
|
-
})] }), /* @__PURE__ */
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
children: R("vibecontrols.pages.ai.contextHeading", "AI workbench")
|
|
121
|
+
})] }), /* @__PURE__ */ P("div", {
|
|
122
|
+
className: "flex items-center gap-3",
|
|
123
|
+
children: [/* @__PURE__ */ N(T, {
|
|
124
|
+
aiHref: "/ai",
|
|
125
|
+
activeMode: "ai"
|
|
126
|
+
}), /* @__PURE__ */ N(h, {
|
|
127
|
+
label: R("vibecontrols.pages.ai.agentSelectorLabel", "Agent"),
|
|
128
|
+
compact: !0
|
|
129
|
+
})]
|
|
117
130
|
})]
|
|
118
|
-
}), /* @__PURE__ */
|
|
131
|
+
}), /* @__PURE__ */ N("div", {
|
|
119
132
|
className: "flex-1 min-h-0 overflow-auto p-4 sm:p-6 lg:p-0",
|
|
120
|
-
children: /* @__PURE__ */
|
|
121
|
-
agentId:
|
|
122
|
-
children: /* @__PURE__ */
|
|
123
|
-
agentId:
|
|
133
|
+
children: /* @__PURE__ */ N(p, {
|
|
134
|
+
agentId: G || null,
|
|
135
|
+
children: /* @__PURE__ */ N(f, {
|
|
136
|
+
agentId: G || null,
|
|
124
137
|
requirements: [{
|
|
125
138
|
packages: [u],
|
|
126
139
|
mode: "all",
|
|
127
|
-
eyebrow:
|
|
128
|
-
title:
|
|
129
|
-
description:
|
|
140
|
+
eyebrow: R("vibecontrols.pages.ai.pluginRequiredEyebrow", "AI plugin required"),
|
|
141
|
+
title: R("vibecontrols.pages.ai.coreTitle", "Install the AI orchestrator"),
|
|
142
|
+
description: R("vibecontrols.pages.ai.coreDescription", "The AI page routes prompts and sessions through the AI orchestrator plugin on your agent. Install it to continue.")
|
|
130
143
|
}, {
|
|
131
144
|
packages: d,
|
|
132
145
|
mode: "any",
|
|
133
|
-
eyebrow:
|
|
134
|
-
title:
|
|
135
|
-
description:
|
|
146
|
+
eyebrow: R("vibecontrols.pages.ai.providerEyebrow", "AI provider required"),
|
|
147
|
+
title: R("vibecontrols.pages.ai.providerTitle", "Install at least one AI provider"),
|
|
148
|
+
description: R("vibecontrols.pages.ai.providerDescription", "Pick the AI harness you want to use. You can install more providers later from the Plugins tab on your agent.")
|
|
136
149
|
}],
|
|
137
|
-
children: /* @__PURE__ */
|
|
138
|
-
fallback: /* @__PURE__ */
|
|
150
|
+
children: /* @__PURE__ */ N(D, {
|
|
151
|
+
fallback: /* @__PURE__ */ N("div", {
|
|
139
152
|
className: "flex items-center justify-center h-full",
|
|
140
|
-
children: /* @__PURE__ */
|
|
153
|
+
children: /* @__PURE__ */ N(i, { message: "Loading..." })
|
|
141
154
|
}),
|
|
142
|
-
children: /* @__PURE__ */
|
|
143
|
-
sidebar: /* @__PURE__ */
|
|
144
|
-
agent:
|
|
145
|
-
onDeleteSession:
|
|
146
|
-
onDeleteSelected:
|
|
155
|
+
children: /* @__PURE__ */ N(y, {
|
|
156
|
+
sidebar: /* @__PURE__ */ N(b, {
|
|
157
|
+
agent: q,
|
|
158
|
+
onDeleteSession: Z,
|
|
159
|
+
onDeleteSelected: Q
|
|
147
160
|
}),
|
|
148
|
-
detailPanel:
|
|
149
|
-
sessionId:
|
|
150
|
-
agent:
|
|
161
|
+
detailPanel: Y ? /* @__PURE__ */ N(C, {
|
|
162
|
+
sessionId: Y,
|
|
163
|
+
agent: q
|
|
151
164
|
}) : void 0,
|
|
152
|
-
children: /* @__PURE__ */
|
|
165
|
+
children: /* @__PURE__ */ N(S, { agent: q })
|
|
153
166
|
})
|
|
154
167
|
})
|
|
155
168
|
})
|
|
@@ -158,6 +171,6 @@ function F() {
|
|
|
158
171
|
});
|
|
159
172
|
}
|
|
160
173
|
//#endregion
|
|
161
|
-
export {
|
|
174
|
+
export { I as AgentManagerPage };
|
|
162
175
|
|
|
163
176
|
//# sourceMappingURL=AgentManagerPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentManagerPage.js","names":[],"sources":["../../../src/pages/ai/AgentManagerPage.tsx"],"sourcesContent":["/**\n * AgentManagerPage — top-level page for the multi-session Agent Manager.\n *\n * Reads URL params (:tab, :sessionId), resolves the active agent via\n * useCachedInitialData(), auto-opens a session tab if the URL has a\n * sessionId, and renders the three-pane layout.\n */\n\nimport { Suspense, useCallback, useEffect, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { MessagesSquare } from 'lucide-react';\nimport { isNative, nativeNotify } from '../../utils/nativeBridge';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport {\n LoadingState,\n EmptyState,\n ErrorState,\n PluginGate,\n AgentSelector,\n RequireAgentReachable,\n} from '@/components/shared';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\nimport { useActiveAgentProfile } from '@/hooks/useActiveAgentProfile';\nimport { usePluginAvailability } from '@/hooks/usePluginAvailability';\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useAgentManagerKeyboard } from '@/hooks/useAgentManagerKeyboard';\nimport { terminateSession, bulkDeleteSessions } from '@/services/aiApi';\nimport { AgentManagerLayout } from '@/components/agent-manager/AgentManagerLayout';\nimport { AgentManagerSidebar } from '@/components/agent-manager/AgentManagerSidebar';\nimport { AgentManagerCenter } from '@/components/agent-manager/AgentManagerCenter';\nimport { AgentManagerDetailPanel } from '@/components/agent-manager/AgentManagerDetailPanel';\nimport { BridleConfigPanel } from '@/components/agent-manager/BridleConfigPanel';\nimport { ClaudeCredentialsCard } from '@/components/ai/ClaudeCredentialsCard';\nimport { AI_CORE_PACKAGE, AI_PROVIDER_PACKAGES } from '@/constants/pluginCatalog';\n\ninterface AgentManagerParams {\n tab?: string;\n sessionId?: string;\n}\n\nexport function AgentManagerPage() {\n const { tab: tabParam, sessionId: sessionIdParam } = useParams<\n AgentManagerParams & Record<string, string | undefined>\n >();\n const tr = useTr();\n const handleNavigate = useVibeNavigate();\n\n const { agents, loading: agentsLoading, error: agentsError } = useCachedInitialData();\n const selectedAgentId = useVibeControlsStore((s) => s.activeAgentId);\n\n // Prefer the user-selected agent from the store; fall back to the first\n // healthy one so the page works on first visit before the selector commits.\n const activeAgent = useMemo(() => {\n if (selectedAgentId) {\n const match = agents.find((a) => a.id === selectedAgentId);\n if (match) return match;\n }\n return agents.find((a) => a.isActive && a.tunnelUrl && a.agentApiKey) ?? null;\n }, [agents, selectedAgentId]);\n\n const agentId = activeAgent?.id ?? '';\n // AgentRef for canonical aiApi calls — agent → profile → plugins/data.\n const { active: activeProfile } = useActiveAgentProfile(activeAgent?.id ?? null);\n const agentRef = useMemo(\n () => ({ id: agentId, profile: activeProfile }),\n [agentId, activeProfile]\n );\n const openSession = useAgentManagerStore((s) => s.openSession);\n const activeTabSessionId = useAgentManagerStore((s) => s.activeTabSessionId);\n\n // Pre-fetch plugin availability at the page level so the detection phase\n // overlaps with the agents query's resolution. This collapses the two\n // sequential loading states (\"Loading agents...\" → \"Checking plugin\n // availability...\") into one unified wait, eliminating the flicker the\n // user saw between them.\n const detectionPackages = useMemo(() => [AI_CORE_PACKAGE, ...AI_PROVIDER_PACKAGES], []);\n const { initialLoading: pluginsInitialLoading } = usePluginAvailability(\n detectionPackages,\n agentId || null\n );\n\n // Auto-open session from URL param\n useEffect(() => {\n if (sessionIdParam && agentId) {\n openSession(sessionIdParam, `Session ${sessionIdParam.slice(0, 8)}`);\n }\n }, [sessionIdParam, agentId, openSession]);\n\n const handleDeleteSession = useCallback(\n async (sessionId: string) => {\n if (!agentId) return;\n try {\n await terminateSession(agentRef, sessionId);\n if (isNative()) void nativeNotify('success');\n } catch {\n if (isNative()) void nativeNotify('error');\n }\n },\n [agentRef]\n );\n\n const handleDeleteSelected = useCallback(\n async (sessionIds: string[]) => {\n if (!agentId) return;\n try {\n await bulkDeleteSessions(agentRef, sessionIds);\n if (isNative()) void nativeNotify('success');\n } catch {\n if (isNative()) void nativeNotify('error');\n }\n },\n [agentRef]\n );\n\n // Activate keyboard shortcuts (Ctrl+Shift+N, Ctrl+K, Ctrl+F, Escape)\n useAgentManagerKeyboard();\n\n // Single unified wait: show one LoadingState while either the agents\n // query or the plugin-availability probe is still in flight. Prevents\n // the two-step \"Loading agents...\" → \"Checking plugin availability...\"\n // cascade. `agentId && pluginsInitialLoading` also catches the case\n // where agents resolved but the plugin probe hasn't fired/settled yet.\n if (agentsLoading || (agentId && pluginsInitialLoading)) {\n return (\n <MotionPage className=\"flex items-center justify-center h-full bg-bg-surface\">\n <LoadingState\n message={tr(\n 'vibecontrols.pages.ai.detectingAgent',\n 'Detecting agent and plugin availability…'\n )}\n />\n </MotionPage>\n );\n }\n\n if (agentsError) {\n return (\n <MotionPage className=\"flex items-center justify-center h-full bg-bg-surface\">\n <ErrorState title=\"Failed to load agents\" message={agentsError.message} />\n </MotionPage>\n );\n }\n\n if (agents.length === 0) {\n return (\n <MotionPage className=\"flex items-center justify-center h-full bg-bg-surface p-8\">\n <EmptyState\n icon={<MessagesSquare className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibecontrols.pages.ai.noActiveAgentAvailable', 'No agents available')}\n description={tr(\n 'vibecontrols.pages.ai.agentManagerRequiresAgent',\n 'The Agent Manager needs at least one vibecontrols agent. Add one or start an existing one.'\n )}\n action={\n <button\n onClick={() => handleNavigate('/agents')}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors text-sm\"\n >\n {tr('vibecontrols.pages.ai.goToAgents', 'Go to Agents')}\n </button>\n }\n />\n </MotionPage>\n );\n }\n\n if (tabParam === 'config') {\n return (\n <MotionPage className=\"flex flex-col h-[calc(100vh-6.5rem)] bg-bg-surface overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border-default px-4 sm:px-6 py-3\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('vibecontrols.pages.ai.contextLabel', 'Active context')}\n </p>\n <h2 className=\"text-sm font-semibold text-text-primary mt-0.5\">\n {tr('vibecontrols.pages.ai.configHeading', 'AI configuration')}\n </h2>\n </div>\n <AgentSelector label={tr('vibecontrols.pages.ai.agentSelectorLabel', 'Agent')} compact />\n </div>\n\n <div className=\"flex-1 overflow-auto p-4 sm:p-6 space-y-6\">\n <RequireAgentReachable agentId={agentId || null}>\n <ClaudeCredentialsCard agent={agentRef} />\n <BridleConfigPanel agent={agentRef} />\n </RequireAgentReachable>\n </div>\n </MotionPage>\n );\n }\n\n return (\n <MotionPage className=\"flex flex-col h-[calc(100vh-6.5rem)] bg-bg-surface overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border-default px-4 sm:px-6 py-3\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('vibecontrols.pages.ai.contextLabel', 'Active context')}\n </p>\n <h2 className=\"text-sm font-semibold text-text-primary mt-0.5\">\n {tr('vibecontrols.pages.ai.contextHeading', 'AI workbench')}\n </h2>\n </div>\n <AgentSelector label={tr('vibecontrols.pages.ai.agentSelectorLabel', 'Agent')} compact />\n </div>\n\n <div className=\"flex-1 min-h-0 overflow-auto p-4 sm:p-6 lg:p-0\">\n <RequireAgentReachable agentId={agentId || null}>\n <PluginGate\n agentId={agentId || null}\n requirements={[\n {\n packages: [AI_CORE_PACKAGE],\n mode: 'all',\n eyebrow: tr('vibecontrols.pages.ai.pluginRequiredEyebrow', 'AI plugin required'),\n title: tr('vibecontrols.pages.ai.coreTitle', 'Install the AI orchestrator'),\n description: tr(\n 'vibecontrols.pages.ai.coreDescription',\n 'The AI page routes prompts and sessions through the AI orchestrator plugin on your agent. Install it to continue.'\n ),\n },\n {\n packages: AI_PROVIDER_PACKAGES,\n mode: 'any',\n eyebrow: tr('vibecontrols.pages.ai.providerEyebrow', 'AI provider required'),\n title: tr(\n 'vibecontrols.pages.ai.providerTitle',\n 'Install at least one AI provider'\n ),\n description: tr(\n 'vibecontrols.pages.ai.providerDescription',\n 'Pick the AI harness you want to use. You can install more providers later from the Plugins tab on your agent.'\n ),\n },\n ]}\n >\n <Suspense\n fallback={\n <div className=\"flex items-center justify-center h-full\">\n <LoadingState message=\"Loading...\" />\n </div>\n }\n >\n <AgentManagerLayout\n sidebar={\n <AgentManagerSidebar\n agent={agentRef}\n onDeleteSession={handleDeleteSession}\n onDeleteSelected={handleDeleteSelected}\n />\n }\n detailPanel={\n activeTabSessionId ? (\n <AgentManagerDetailPanel sessionId={activeTabSessionId} agent={agentRef} />\n ) : undefined\n }\n >\n <AgentManagerCenter agent={agentRef} />\n </AgentManagerLayout>\n </Suspense>\n </PluginGate>\n </RequireAgentReachable>\n </div>\n </MotionPage>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentManagerPage.js","names":[],"sources":["../../../src/pages/ai/AgentManagerPage.tsx"],"sourcesContent":["/**\n * AgentManagerPage — top-level page for the multi-session Agent Manager.\n *\n * Reads URL params (:tab, :sessionId), resolves the active agent via\n * useCachedInitialData(), auto-opens a session tab if the URL has a\n * sessionId, and renders the three-pane layout.\n */\n\nimport { Suspense, useCallback, useEffect, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { MessagesSquare } from 'lucide-react';\nimport { isNative, nativeNotify } from '../../utils/nativeBridge';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport {\n LoadingState,\n EmptyState,\n ErrorState,\n PluginGate,\n AgentSelector,\n RequireAgentReachable,\n} from '@/components/shared';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\nimport { useActiveAgentProfile } from '@/hooks/useActiveAgentProfile';\nimport { usePluginAvailability } from '@/hooks/usePluginAvailability';\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useAgentManagerKeyboard } from '@/hooks/useAgentManagerKeyboard';\nimport { terminateSession, bulkDeleteSessions } from '@/services/aiApi';\nimport { AgentManagerLayout } from '@/components/agent-manager/AgentManagerLayout';\nimport { AgentManagerSidebar } from '@/components/agent-manager/AgentManagerSidebar';\nimport { AgentManagerCenter } from '@/components/agent-manager/AgentManagerCenter';\nimport { AgentManagerDetailPanel } from '@/components/agent-manager/AgentManagerDetailPanel';\nimport { BridleConfigPanel } from '@/components/agent-manager/BridleConfigPanel';\nimport { ClaudeCredentialsCard } from '@/components/ai/ClaudeCredentialsCard';\nimport { AIModeToggle } from '@/components/ai/AIModeToggle';\nimport { AI_CORE_PACKAGE, AI_PROVIDER_PACKAGES } from '@/constants/pluginCatalog';\n\ninterface AgentManagerParams {\n tab?: string;\n sessionId?: string;\n}\n\nexport function AgentManagerPage() {\n const { tab: tabParam, sessionId: sessionIdParam } = useParams<\n AgentManagerParams & Record<string, string | undefined>\n >();\n const tr = useTr();\n const handleNavigate = useVibeNavigate();\n\n const { agents, loading: agentsLoading, error: agentsError } = useCachedInitialData();\n const selectedAgentId = useVibeControlsStore((s) => s.activeAgentId);\n\n // Prefer the user-selected agent from the store; fall back to the first\n // healthy one so the page works on first visit before the selector commits.\n const activeAgent = useMemo(() => {\n if (selectedAgentId) {\n const match = agents.find((a) => a.id === selectedAgentId);\n if (match) return match;\n }\n return agents.find((a) => a.isActive && a.tunnelUrl && a.agentApiKey) ?? null;\n }, [agents, selectedAgentId]);\n\n const agentId = activeAgent?.id ?? '';\n // AgentRef for canonical aiApi calls — agent → profile → plugins/data.\n const { active: activeProfile } = useActiveAgentProfile(activeAgent?.id ?? null);\n const agentRef = useMemo(\n () => ({ id: agentId, profile: activeProfile }),\n [agentId, activeProfile]\n );\n const openSession = useAgentManagerStore((s) => s.openSession);\n const activeTabSessionId = useAgentManagerStore((s) => s.activeTabSessionId);\n\n // Pre-fetch plugin availability at the page level so the detection phase\n // overlaps with the agents query's resolution. This collapses the two\n // sequential loading states (\"Loading agents...\" → \"Checking plugin\n // availability...\") into one unified wait, eliminating the flicker the\n // user saw between them.\n const detectionPackages = useMemo(() => [AI_CORE_PACKAGE, ...AI_PROVIDER_PACKAGES], []);\n const { initialLoading: pluginsInitialLoading } = usePluginAvailability(\n detectionPackages,\n agentId || null\n );\n\n // Auto-open session from URL param\n useEffect(() => {\n if (sessionIdParam && agentId) {\n openSession(sessionIdParam, `Session ${sessionIdParam.slice(0, 8)}`);\n }\n }, [sessionIdParam, agentId, openSession]);\n\n const handleDeleteSession = useCallback(\n async (sessionId: string) => {\n if (!agentId) return;\n try {\n await terminateSession(agentRef, sessionId);\n if (isNative()) void nativeNotify('success');\n } catch {\n if (isNative()) void nativeNotify('error');\n }\n },\n [agentRef]\n );\n\n const handleDeleteSelected = useCallback(\n async (sessionIds: string[]) => {\n if (!agentId) return;\n try {\n await bulkDeleteSessions(agentRef, sessionIds);\n if (isNative()) void nativeNotify('success');\n } catch {\n if (isNative()) void nativeNotify('error');\n }\n },\n [agentRef]\n );\n\n // Activate keyboard shortcuts (Ctrl+Shift+N, Ctrl+K, Ctrl+F, Escape)\n useAgentManagerKeyboard();\n\n // Single unified wait: show one LoadingState while either the agents\n // query or the plugin-availability probe is still in flight. Prevents\n // the two-step \"Loading agents...\" → \"Checking plugin availability...\"\n // cascade. `agentId && pluginsInitialLoading` also catches the case\n // where agents resolved but the plugin probe hasn't fired/settled yet.\n if (agentsLoading || (agentId && pluginsInitialLoading)) {\n return (\n <MotionPage className=\"flex items-center justify-center h-full bg-bg-surface\">\n <LoadingState\n message={tr(\n 'vibecontrols.pages.ai.detectingAgent',\n 'Detecting agent and plugin availability…'\n )}\n />\n </MotionPage>\n );\n }\n\n if (agentsError) {\n return (\n <MotionPage className=\"flex items-center justify-center h-full bg-bg-surface\">\n <ErrorState title=\"Failed to load agents\" message={agentsError.message} />\n </MotionPage>\n );\n }\n\n if (agents.length === 0) {\n return (\n <MotionPage className=\"flex items-center justify-center h-full bg-bg-surface p-8\">\n <EmptyState\n icon={<MessagesSquare className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibecontrols.pages.ai.noActiveAgentAvailable', 'No agents available')}\n description={tr(\n 'vibecontrols.pages.ai.agentManagerRequiresAgent',\n 'The Agent Manager needs at least one vibecontrols agent. Add one or start an existing one.'\n )}\n action={\n <button\n onClick={() => handleNavigate('/agents')}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors text-sm\"\n >\n {tr('vibecontrols.pages.ai.goToAgents', 'Go to Agents')}\n </button>\n }\n />\n </MotionPage>\n );\n }\n\n if (tabParam === 'config') {\n return (\n <MotionPage className=\"flex flex-col h-[calc(100vh-6.5rem)] bg-bg-surface overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border-default px-4 sm:px-6 py-3\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('vibecontrols.pages.ai.contextLabel', 'Active context')}\n </p>\n <h2 className=\"text-sm font-semibold text-text-primary mt-0.5\">\n {tr('vibecontrols.pages.ai.configHeading', 'AI configuration')}\n </h2>\n </div>\n <div className=\"flex items-center gap-3\">\n <AIModeToggle aiHref=\"/ai\" activeMode=\"ai\" />\n <AgentSelector\n label={tr('vibecontrols.pages.ai.agentSelectorLabel', 'Agent')}\n compact\n />\n </div>\n </div>\n\n <div className=\"flex-1 overflow-auto p-4 sm:p-6 space-y-6\">\n <RequireAgentReachable agentId={agentId || null}>\n <ClaudeCredentialsCard agent={agentRef} />\n <BridleConfigPanel agent={agentRef} />\n </RequireAgentReachable>\n </div>\n </MotionPage>\n );\n }\n\n return (\n <MotionPage className=\"flex flex-col h-[calc(100vh-6.5rem)] bg-bg-surface overflow-hidden\">\n <div className=\"flex items-center justify-between gap-3 border-b border-border-default px-4 sm:px-6 py-3\">\n <div>\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">\n {tr('vibecontrols.pages.ai.contextLabel', 'Active context')}\n </p>\n <h2 className=\"text-sm font-semibold text-text-primary mt-0.5\">\n {tr('vibecontrols.pages.ai.contextHeading', 'AI workbench')}\n </h2>\n </div>\n <div className=\"flex items-center gap-3\">\n {/* Plan toggle navigates to the canonical /ai-tools/plan\n workspace; the AI side stays on this AgentManagerPage. */}\n <AIModeToggle aiHref=\"/ai\" activeMode=\"ai\" />\n <AgentSelector label={tr('vibecontrols.pages.ai.agentSelectorLabel', 'Agent')} compact />\n </div>\n </div>\n\n <div className=\"flex-1 min-h-0 overflow-auto p-4 sm:p-6 lg:p-0\">\n <RequireAgentReachable agentId={agentId || null}>\n <PluginGate\n agentId={agentId || null}\n requirements={[\n {\n packages: [AI_CORE_PACKAGE],\n mode: 'all',\n eyebrow: tr('vibecontrols.pages.ai.pluginRequiredEyebrow', 'AI plugin required'),\n title: tr('vibecontrols.pages.ai.coreTitle', 'Install the AI orchestrator'),\n description: tr(\n 'vibecontrols.pages.ai.coreDescription',\n 'The AI page routes prompts and sessions through the AI orchestrator plugin on your agent. Install it to continue.'\n ),\n },\n {\n packages: AI_PROVIDER_PACKAGES,\n mode: 'any',\n eyebrow: tr('vibecontrols.pages.ai.providerEyebrow', 'AI provider required'),\n title: tr(\n 'vibecontrols.pages.ai.providerTitle',\n 'Install at least one AI provider'\n ),\n description: tr(\n 'vibecontrols.pages.ai.providerDescription',\n 'Pick the AI harness you want to use. You can install more providers later from the Plugins tab on your agent.'\n ),\n },\n ]}\n >\n <Suspense\n fallback={\n <div className=\"flex items-center justify-center h-full\">\n <LoadingState message=\"Loading...\" />\n </div>\n }\n >\n <AgentManagerLayout\n sidebar={\n <AgentManagerSidebar\n agent={agentRef}\n onDeleteSession={handleDeleteSession}\n onDeleteSelected={handleDeleteSelected}\n />\n }\n detailPanel={\n activeTabSessionId ? (\n <AgentManagerDetailPanel sessionId={activeTabSessionId} agent={agentRef} />\n ) : undefined\n }\n >\n <AgentManagerCenter agent={agentRef} />\n </AgentManagerLayout>\n </Suspense>\n </PluginGate>\n </RequireAgentReachable>\n </div>\n </MotionPage>\n );\n}\n"],"mappings":"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"}
|