@burdenoff/microfe-vibecontrols 2026.601.5 → 2026.601.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.
@@ -0,0 +1,17 @@
1
+ import { newInvariantError as e } from "../invariant/index.js";
2
+ import { checkDocument as t } from "./checkDocument.js";
3
+ //#region node_modules/@apollo/client/utilities/internal/getMainDefinition.js
4
+ function n(n) {
5
+ t(n);
6
+ let r;
7
+ for (let e of n.definitions) {
8
+ if (e.kind === "OperationDefinition") return e;
9
+ e.kind === "FragmentDefinition" && !r && (r = e);
10
+ }
11
+ if (r) return r;
12
+ throw e(12);
13
+ }
14
+ //#endregion
15
+ export { n as getMainDefinition };
16
+
17
+ //# sourceMappingURL=getMainDefinition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMainDefinition.js","names":[],"sources":["../../../../../../node_modules/@apollo/client/utilities/internal/getMainDefinition.js"],"sourcesContent":["import { newInvariantError } from \"@apollo/client/utilities/invariant\";\nimport { checkDocument } from \"./checkDocument.js\";\n/**\n * Returns the first operation definition from a GraphQL document. The function\n * prioritizes operation definitions over fragment definitions, which makes it\n * suitable for documents that may contain both. If no operation definition is\n * found, the first fragment definition will be returned. If no definitions are\n * found, an error is thrown.\n *\n * @remarks\n *\n * Use this function when you need to perform more advanced tasks with the main\n * definition AST node. If you want to determine when a document is a specific\n * operation type, prefer the `isQueryOperation`, `isMutationOperation`, and\n * `isSubscriptionOperation` utility functions instead.\n *\n * @param queryDoc - The GraphQL document to extract the definition from\n * @returns The main operation or fragment definition AST node\n *\n * @example\n *\n * ```ts\n * import { gql } from \"@apollo/client\";\n * import { getMainDefinition } from \"@apollo/client/utilities\";\n *\n * const query = gql`\n * query GetUser($id: ID!) {\n * user(id: $id) {\n * name\n * email\n * }\n * }\n * `;\n *\n * const definition = getMainDefinition(query);\n * ```\n *\n * @throws When the document contains no operation or fragment definitions\n */\nexport function getMainDefinition(queryDoc) {\n checkDocument(queryDoc);\n let fragmentDefinition;\n for (let definition of queryDoc.definitions) {\n if (definition.kind === \"OperationDefinition\") {\n return definition;\n }\n if (definition.kind === \"FragmentDefinition\" && !fragmentDefinition) {\n // we do this because we want to allow multiple fragment definitions\n // to precede an operation definition.\n fragmentDefinition = definition;\n }\n }\n if (fragmentDefinition) {\n return fragmentDefinition;\n }\n throw newInvariantError(12);\n}\n//# sourceMappingURL=getMainDefinition.js.map\n"],"x_google_ignoreList":[0],"mappings":";;;AAuCA,SAAgB,EAAkB,GAAU;AACxC,GAAc,EAAS;CACvB,IAAI;AACJ,MAAK,IAAI,KAAc,EAAS,aAAa;AACzC,MAAI,EAAW,SAAS,sBACpB,QAAO;AAEX,EAAI,EAAW,SAAS,wBAAwB,CAAC,MAG7C,IAAqB;;AAG7B,KAAI,EACA,QAAO;AAEX,OAAM,EAAkB,GAAG"}
@@ -6,26 +6,26 @@ import { LoadingState as c } from "../components/shared/LoadingState.js";
6
6
  import { ErrorState as l } from "../components/shared/ErrorState.js";
7
7
  import { EmptyState as u } from "../components/shared/EmptyState.js";
8
8
  import { GetHelpButton as d } from "../components/shared/GetHelpButton.js";
9
- import { SearchableSelect as ee } from "../components/shared/SearchableSelect.js";
9
+ import { SearchableSelect as f } from "../components/shared/SearchableSelect.js";
10
10
  import "../components/shared/index.js";
11
- import { VIBE_PERMISSIONS as f } from "../constants/permissions.js";
11
+ import { VIBE_PERMISSIONS as ee } from "../constants/permissions.js";
12
12
  import { AgentGraphView as p } from "../components/graph/AgentGraphView.js";
13
- import { useCallback as m, useMemo as h, useState as g } from "react";
14
- import { useI18n as _ } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
- import { GitBranch as v, Loader2 as y, Network as b } from "lucide-react";
16
- import { usePermissions as x } from "@burdenoff/fe-libs/shared/providers/shell";
17
- import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
18
- import { MotionPage as T } from "@burdenoff/fe-libs/shared/motion";
13
+ import { useCallback as m, useMemo as te, useState as h } from "react";
14
+ import { useI18n as g } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
+ import { GitBranch as _, Loader2 as v, Network as y } from "lucide-react";
16
+ import { usePermissions as b } from "@burdenoff/fe-libs/shared/providers/shell";
17
+ import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
18
+ import { MotionPage as w } from "@burdenoff/fe-libs/shared/motion";
19
19
  //#region src/pages/AgentGraphPage.tsx
20
- function E() {
21
- let { workspaceId: E } = i(), D = a(), { t: O } = _(), { hasPermission: k, isLoading: te, permissions: A } = x(), [j, M] = g(null), N = m((e, t, n) => {
22
- let r = O(e, n), i = r === e ? t : r;
20
+ function T() {
21
+ let { workspaceId: T } = i(), E = a(), { t: D } = g(), { hasPermission: O, isLoading: k, permissions: A } = b(), [j, M] = h(null), N = m((e, t, n) => {
22
+ let r = D(e, n), i = r === e ? t : r;
23
23
  return n ? Object.entries(n).reduce((e, [t, n]) => e.replace(`{{${t}}}`, String(n)), i) : i;
24
- }, [O]), { agents: P } = o(), { data: F } = n({
25
- variables: { workspaceId: E ?? "" },
26
- skip: !E,
24
+ }, [D]), { agents: P } = o(), { data: F } = n({
25
+ variables: { workspaceId: T ?? "" },
26
+ skip: !T,
27
27
  fetchPolicy: "cache-and-network"
28
- }), I = F?.targets?.items ?? [], L = h(() => {
28
+ }), I = F?.targets?.items ?? [], L = te(() => {
29
29
  let e = P.map((e) => ({
30
30
  value: e.id,
31
31
  label: N("agentGraph.scopeAgentPrefix", "Agent: {{name}}", { name: e.name })
@@ -38,97 +38,97 @@ function E() {
38
38
  P,
39
39
  I,
40
40
  N
41
- ]), [R, z] = g(""), { data: B } = e({ skip: !E }), V = B?.agentConnectionConfig.permissions ?? [], H = B?.agentConnectionConfig.scopes ?? [], { data: U, previousData: W, loading: G, error: K } = t({
41
+ ]), [R, z] = h(""), { data: B } = e({ skip: !T }), V = B?.agentConnectionConfig.permissions ?? [], H = B?.agentConnectionConfig.scopes ?? [], { data: U, previousData: W, loading: G, error: K, refetch: q } = t({
42
42
  variables: {
43
- workspaceId: E || "",
43
+ workspaceId: T || "",
44
44
  rootAgentId: j || void 0
45
45
  },
46
- skip: !E
47
- }), q = U?.agentGraph ?? W?.agentGraph, J = q?.targets ?? [], Y = q?.connections ?? [], X = G, Z = X && !q, Q = X && !!q, [$] = r(), ne = m((e, t) => {
46
+ skip: !T
47
+ }), J = U?.agentGraph ?? W?.agentGraph, Y = J?.targets ?? [], X = J?.connections ?? [], Z = G, ne = Z && !J, Q = Z && !!J, [$] = r(), re = m((e, t) => {
48
48
  if (e === "target") {
49
- D(`/agents?${new URLSearchParams({
49
+ E(`/agents?${new URLSearchParams({
50
50
  tab: "targets",
51
51
  selectedTargetId: t
52
52
  }).toString()}`);
53
53
  return;
54
54
  }
55
- D(`/agents/${t}`);
56
- }, [D]), re = m((e, t, n) => {
57
- $({ variables: {
55
+ E(`/agents/${t}`);
56
+ }, [E]), ie = m(async (e, t, n) => {
57
+ await $({ variables: {
58
58
  connectionId: e,
59
59
  input: {
60
60
  permissions: t,
61
61
  scopes: n
62
62
  }
63
- } });
64
- }, [$]);
65
- return te ? /* @__PURE__ */ C("div", {
63
+ } }), await q();
64
+ }, [q, $]);
65
+ return k ? /* @__PURE__ */ S("div", {
66
66
  className: "flex items-center justify-center min-h-[400px]",
67
- children: /* @__PURE__ */ C("p", {
67
+ children: /* @__PURE__ */ S("p", {
68
68
  className: "text-text-secondary",
69
69
  children: "Loading permissions…"
70
70
  })
71
- }) : A && (A.permissionStrings?.length ?? 0) > 0 && !k(f.AGENT_READ) ? /* @__PURE__ */ C("div", {
71
+ }) : A && (A.permissionStrings?.length ?? 0) > 0 && !O(ee.AGENT_READ) ? /* @__PURE__ */ S("div", {
72
72
  className: "flex items-center justify-center min-h-[400px]",
73
- children: /* @__PURE__ */ w("div", {
73
+ children: /* @__PURE__ */ C("div", {
74
74
  className: "text-center space-y-2",
75
- children: [/* @__PURE__ */ C("h2", {
75
+ children: [/* @__PURE__ */ S("h2", {
76
76
  className: "text-lg font-semibold text-foreground",
77
77
  children: "Access Denied"
78
- }), /* @__PURE__ */ C("p", {
78
+ }), /* @__PURE__ */ S("p", {
79
79
  className: "text-sm text-text-secondary",
80
80
  children: "You don't have permission to access this page."
81
81
  })]
82
82
  })
83
- }) : /* @__PURE__ */ w(T, { children: [
84
- /* @__PURE__ */ C(s, {
83
+ }) : /* @__PURE__ */ C(w, { children: [
84
+ /* @__PURE__ */ S(s, {
85
85
  title: N("nav.agentGraph", "Agent Graph"),
86
86
  description: N("agentGraph.description", "Visualize and manage connections between targets and agents.")
87
87
  }),
88
- Z && /* @__PURE__ */ C(c, { message: N("agentGraph.loading", "Loading agent graph...") }),
89
- !X && K && J.length === 0 && /* @__PURE__ */ C(l, {
88
+ ne && /* @__PURE__ */ S(c, { message: N("agentGraph.loading", "Loading agent graph...") }),
89
+ !Z && K && Y.length === 0 && /* @__PURE__ */ S(l, {
90
90
  title: N("agentGraph.failedLoad", "Failed to load agent graph"),
91
91
  message: K.message
92
92
  }),
93
- !X && !K && J.length === 0 && !R && /* @__PURE__ */ C(u, {
94
- icon: /* @__PURE__ */ C(b, { className: "size-8 text-text-secondary" }),
93
+ !Z && !K && Y.length === 0 && !R && /* @__PURE__ */ S(u, {
94
+ icon: /* @__PURE__ */ S(y, { className: "size-8 text-text-secondary" }),
95
95
  title: N("agentGraph.noTargetsConnected", "No targets connected"),
96
96
  description: N("agentGraph.noTargetsDescription", "Register an agent on a target to start visualizing your infrastructure topology."),
97
- action: /* @__PURE__ */ C(d, { prompt: "What is the Agent Graph in VibeControls and what does it show?" })
97
+ action: /* @__PURE__ */ S(d, { prompt: "What is the Agent Graph in VibeControls and what does it show?" })
98
98
  }),
99
- (J.length > 0 || R || Q) && /* @__PURE__ */ w(S, { children: [
100
- /* @__PURE__ */ w("div", {
99
+ (Y.length > 0 || R || Q) && /* @__PURE__ */ C(x, { children: [
100
+ /* @__PURE__ */ C("div", {
101
101
  className: "flex items-center gap-3 mt-4",
102
102
  children: [
103
- /* @__PURE__ */ w("div", {
103
+ /* @__PURE__ */ C("div", {
104
104
  className: "flex items-center gap-2",
105
105
  children: [
106
- /* @__PURE__ */ C(v, {
106
+ /* @__PURE__ */ S(_, {
107
107
  size: 16,
108
108
  className: "text-text-tertiary"
109
109
  }),
110
- /* @__PURE__ */ C("span", {
110
+ /* @__PURE__ */ S("span", {
111
111
  className: "text-sm font-medium text-text-secondary",
112
112
  children: N("agentGraph.countSummary", "{{targets}} targets, {{connections}} connections", {
113
- targets: J.length,
114
- connections: Y.length
113
+ targets: Y.length,
114
+ connections: X.length
115
115
  })
116
116
  }),
117
- Q && /* @__PURE__ */ w("span", {
117
+ Q && /* @__PURE__ */ C("span", {
118
118
  role: "status",
119
119
  "aria-live": "polite",
120
120
  className: "inline-flex items-center gap-1.5 rounded-full border border-border-default bg-bg-surface px-2.5 py-1 text-xs font-medium text-text-secondary",
121
- children: [/* @__PURE__ */ C(y, { className: "size-3.5 animate-spin text-action-primary-bg" }), N("agentGraph.refreshing", "Refreshing graph...")]
121
+ children: [/* @__PURE__ */ S(v, { className: "size-3.5 animate-spin text-action-primary-bg" }), N("agentGraph.refreshing", "Refreshing graph...")]
122
122
  })
123
123
  ]
124
124
  }),
125
- /* @__PURE__ */ C("div", { className: "flex-1" }),
126
- /* @__PURE__ */ w("div", {
125
+ /* @__PURE__ */ S("div", { className: "flex-1" }),
126
+ /* @__PURE__ */ C("div", {
127
127
  className: "flex items-center gap-2",
128
- children: [/* @__PURE__ */ C("label", {
128
+ children: [/* @__PURE__ */ S("label", {
129
129
  className: "text-xs font-medium text-text-secondary",
130
130
  children: N("agentGraph.scopeLabel", "Scope:")
131
- }), /* @__PURE__ */ C(ee, {
131
+ }), /* @__PURE__ */ S(f, {
132
132
  value: R,
133
133
  onChange: (e) => {
134
134
  z(e), e.startsWith("target:") ? M(null) : M(e || null);
@@ -136,41 +136,41 @@ function E() {
136
136
  options: L,
137
137
  placeholder: N("agentGraph.scopeAll", "All targets & agents"),
138
138
  clearable: !0,
139
- disabled: X,
139
+ disabled: Z,
140
140
  dropdownAlign: "right"
141
141
  })]
142
142
  })
143
143
  ]
144
144
  }),
145
- !X && K && /* @__PURE__ */ C(l, {
145
+ !Z && K && /* @__PURE__ */ S(l, {
146
146
  title: N("agentGraph.failedRefresh", "Failed to refresh agent graph"),
147
147
  message: K.message
148
148
  }),
149
- !X && J.length === 0 && R && /* @__PURE__ */ C(u, {
150
- icon: /* @__PURE__ */ C(b, { className: "size-8 text-text-secondary" }),
149
+ !Z && Y.length === 0 && R && /* @__PURE__ */ S(u, {
150
+ icon: /* @__PURE__ */ S(y, { className: "size-8 text-text-secondary" }),
151
151
  title: N("agentGraph.noScopeResults", "No results for this scope"),
152
152
  description: N("agentGraph.noScopeDescription", "No targets match the selected scope. Clear the filter to view all targets.")
153
153
  }),
154
- (J.length > 0 || Q) && /* @__PURE__ */ w("div", {
154
+ (Y.length > 0 || Q) && /* @__PURE__ */ C("div", {
155
155
  className: "mt-4 relative",
156
156
  style: {
157
157
  height: "calc(100vh - 280px)",
158
158
  minHeight: "400px"
159
159
  },
160
160
  "aria-busy": Q,
161
- children: [/* @__PURE__ */ C(p, {
162
- targets: J,
163
- connections: Y,
164
- onUpdatePermissions: re,
161
+ children: [/* @__PURE__ */ S(p, {
162
+ targets: Y,
163
+ connections: X,
164
+ onUpdatePermissions: ie,
165
165
  availablePermissions: V,
166
166
  availableScopes: H,
167
- onNodeClick: ne,
167
+ onNodeClick: re,
168
168
  fullHeight: !0
169
- }), Q && /* @__PURE__ */ C("div", {
169
+ }), Q && /* @__PURE__ */ S("div", {
170
170
  className: "absolute inset-0 z-10 flex items-center justify-center bg-bg-surface/60 backdrop-blur-[1px]",
171
- children: /* @__PURE__ */ w("div", {
171
+ children: /* @__PURE__ */ C("div", {
172
172
  className: "inline-flex items-center gap-2 rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-secondary shadow-md",
173
- children: [/* @__PURE__ */ C(y, { className: "size-4 animate-spin text-action-primary-bg" }), /* @__PURE__ */ C("span", { children: R ? N("agentGraph.loadingScope", "Applying selected scope...") : N("agentGraph.refreshing", "Refreshing graph...") })]
173
+ children: [/* @__PURE__ */ S(v, { className: "size-4 animate-spin text-action-primary-bg" }), /* @__PURE__ */ S("span", { children: R ? N("agentGraph.loadingScope", "Applying selected scope...") : N("agentGraph.refreshing", "Refreshing graph...") })]
174
174
  })
175
175
  })]
176
176
  })
@@ -178,6 +178,6 @@ function E() {
178
178
  ] });
179
179
  }
180
180
  //#endregion
181
- export { E as AgentGraphPage };
181
+ export { T as AgentGraphPage };
182
182
 
183
183
  //# sourceMappingURL=AgentGraphPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentGraphPage.js","names":[],"sources":["../../src/pages/AgentGraphPage.tsx"],"sourcesContent":["/**\n * Agent Graph Page — Dedicated full-page view of the agent connection graph.\n *\n * Shows targets as group nodes with agents inside (sub-flows) and\n * connections as directed edges. Supports root-node scoping and\n * RBAC permission editing.\n */\n\nimport { useState, useMemo, useCallback } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { GitBranch, Loader2, Network } from 'lucide-react';\nimport {\n PageHeader,\n SearchableSelect,\n LoadingState,\n ErrorState,\n EmptyState,\n GetHelpButton,\n} from '@/components/shared';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useVibeControls, useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\nimport {\n useGetAgentGraphQuery,\n useUpdateConnectionPermissionsMutation,\n useAgentConnectionConfigQuery,\n useListTargetsQuery,\n type ListTargetsQuery,\n} from '@/generated/wspace-operations';\n\ntype TargetItem = NonNullable<ListTargetsQuery['targets']['items'][number]>;\nimport { AgentGraphView } from '@/components/graph/AgentGraphView';\n\nexport function AgentGraphPage() {\n const { workspaceId } = useVibeControls();\n const navigate = useVibeNavigate();\n const { t } = useI18n();\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n const [rootAgentId, setRootAgentId] = useState<string | null>(null);\n\n const tr = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key, params);\n const template = translated === key ? fallback : translated;\n\n if (!params) return template;\n\n return Object.entries(params).reduce(\n (acc, [paramKey, paramValue]) => acc.replace(`{{${paramKey}}}`, String(paramValue)),\n template\n );\n },\n [t]\n );\n\n // Use cached initial data for agents; fetch targets directly\n const { agents: cachedAgents } = useCachedInitialData();\n const { data: targetsData } = useListTargetsQuery({\n variables: { workspaceId: workspaceId ?? '' },\n skip: !workspaceId,\n fetchPolicy: 'cache-and-network',\n });\n const cachedTargets = targetsData?.targets?.items ?? [];\n const scopeOptions = useMemo(() => {\n const agentOpts = cachedAgents.map((a) => ({\n value: a.id,\n label: tr('agentGraph.scopeAgentPrefix', 'Agent: {{name}}', { name: a.name }),\n }));\n const targetOpts = cachedTargets.map((tgt: TargetItem) => ({\n value: `target:${tgt.id}`,\n label: tr('agentGraph.scopeTargetPrefix', 'Target: {{name}}', { name: tgt.name }),\n }));\n return [...targetOpts, ...agentOpts];\n }, [cachedAgents, cachedTargets, tr]);\n\n const [scopeValue, setScopeValue] = useState<string>('');\n\n const { data: connectionConfigData } = useAgentConnectionConfigQuery({\n skip: !workspaceId,\n });\n\n const availablePermissions = connectionConfigData?.agentConnectionConfig.permissions ?? [];\n const availableScopes = connectionConfigData?.agentConnectionConfig.scopes ?? [];\n\n const {\n data: graphData,\n previousData,\n loading,\n error,\n } = useGetAgentGraphQuery({\n variables: {\n workspaceId: workspaceId || '',\n rootAgentId: rootAgentId || undefined,\n },\n skip: !workspaceId,\n });\n\n const resolvedAgentGraph = graphData?.agentGraph ?? previousData?.agentGraph;\n const graphTargets = resolvedAgentGraph?.targets ?? [];\n const graphConnections = resolvedAgentGraph?.connections ?? [];\n const isGraphLoading = loading;\n // Covers first load (including first scoped load) when no prior graph snapshot exists.\n const isInitialLoad = isGraphLoading && !resolvedAgentGraph;\n const isRefreshingGraph = isGraphLoading && Boolean(resolvedAgentGraph);\n\n const [updateConnectionPerms] = useUpdateConnectionPermissionsMutation();\n\n const handleNodeNavigate = useCallback(\n (nodeType: 'target' | 'agent', id: string) => {\n if (nodeType === 'target') {\n const targetParams = new URLSearchParams({\n tab: 'targets',\n selectedTargetId: id,\n });\n navigate(`/agents?${targetParams.toString()}`);\n return;\n }\n navigate(`/agents/${id}`);\n },\n [navigate]\n );\n\n const handleUpdatePermissions = useCallback(\n (connectionId: string, permissions: string[], scopes: string[]) => {\n void updateConnectionPerms({\n variables: { connectionId, input: { permissions, scopes } },\n });\n },\n [updateConnectionPerms]\n );\n\n if (permissionsLoading)\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <p className=\"text-text-secondary\">Loading permissions…</p>\n </div>\n );\n if (\n permissions &&\n (permissions.permissionStrings?.length ?? 0) > 0 &&\n !hasPermission(VIBE_PERMISSIONS.AGENT_READ)\n )\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-foreground\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don't have permission to access this page.\n </p>\n </div>\n </div>\n );\n\n return (\n <MotionPage>\n <PageHeader\n title={tr('nav.agentGraph', 'Agent Graph')}\n description={tr(\n 'agentGraph.description',\n 'Visualize and manage connections between targets and agents.'\n )}\n />\n\n {isInitialLoad && (\n <LoadingState message={tr('agentGraph.loading', 'Loading agent graph...')} />\n )}\n\n {/* Non-fatal error: show banner but don't hide graph if data is available */}\n {!isGraphLoading && error && graphTargets.length === 0 && (\n <ErrorState\n title={tr('agentGraph.failedLoad', 'Failed to load agent graph')}\n message={error.message}\n />\n )}\n\n {!isGraphLoading && !error && graphTargets.length === 0 && !scopeValue && (\n <EmptyState\n icon={<Network className=\"size-8 text-text-secondary\" />}\n title={tr('agentGraph.noTargetsConnected', 'No targets connected')}\n description={tr(\n 'agentGraph.noTargetsDescription',\n 'Register an agent on a target to start visualizing your infrastructure topology.'\n )}\n action={\n <GetHelpButton prompt=\"What is the Agent Graph in VibeControls and what does it show?\" />\n }\n />\n )}\n\n {/* Scope controls + graph: shown whenever we have data, or when a scope filter is\n active (so the user can always clear the filter and recover the full view) */}\n {(graphTargets.length > 0 || scopeValue || isRefreshingGraph) && (\n <>\n {/* Filters — always rendered so user can clear an active scope filter */}\n <div className=\"flex items-center gap-3 mt-4\">\n <div className=\"flex items-center gap-2\">\n <GitBranch size={16} className=\"text-text-tertiary\" />\n <span className=\"text-sm font-medium text-text-secondary\">\n {tr('agentGraph.countSummary', '{{targets}} targets, {{connections}} connections', {\n targets: graphTargets.length,\n connections: graphConnections.length,\n })}\n </span>\n\n {isRefreshingGraph && (\n <span\n role=\"status\"\n aria-live=\"polite\"\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border-default bg-bg-surface px-2.5 py-1 text-xs font-medium text-text-secondary\"\n >\n <Loader2 className=\"size-3.5 animate-spin text-action-primary-bg\" />\n {tr('agentGraph.refreshing', 'Refreshing graph...')}\n </span>\n )}\n </div>\n <div className=\"flex-1\" />\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs font-medium text-text-secondary\">\n {tr('agentGraph.scopeLabel', 'Scope:')}\n </label>\n <SearchableSelect\n value={scopeValue}\n onChange={(v: string) => {\n setScopeValue(v);\n // If selecting a target, clear rootAgentId; if agent, set it\n if (v.startsWith('target:')) {\n setRootAgentId(null);\n } else {\n setRootAgentId(v || null);\n }\n }}\n options={scopeOptions}\n placeholder={tr('agentGraph.scopeAll', 'All targets & agents')}\n clearable\n disabled={isGraphLoading}\n dropdownAlign=\"right\"\n />\n </div>\n </div>\n\n {!isGraphLoading && error && (\n <ErrorState\n title={tr('agentGraph.failedRefresh', 'Failed to refresh agent graph')}\n message={error.message}\n />\n )}\n\n {!isGraphLoading && graphTargets.length === 0 && scopeValue && (\n <EmptyState\n icon={<Network className=\"size-8 text-text-secondary\" />}\n title={tr('agentGraph.noScopeResults', 'No results for this scope')}\n description={tr(\n 'agentGraph.noScopeDescription',\n 'No targets match the selected scope. Clear the filter to view all targets.'\n )}\n />\n )}\n\n {(graphTargets.length > 0 || isRefreshingGraph) && (\n <div\n className=\"mt-4 relative\"\n style={{ height: 'calc(100vh - 280px)', minHeight: '400px' }}\n aria-busy={isRefreshingGraph}\n >\n <AgentGraphView\n targets={\n graphTargets as Array<{\n id: string;\n name: string;\n type: string;\n status: string;\n host?: string | null;\n agents: Array<{ id: string; name: string; version: string; isActive: boolean }>;\n }>\n }\n connections={\n graphConnections as Array<{\n id: string;\n protocol: string;\n status: string;\n permissions?: string[];\n scopes?: string[];\n label?: string | null;\n description?: string | null;\n sourceAgent: { id: string; name: string };\n target: { id: string; name: string; type: string };\n }>\n }\n onUpdatePermissions={handleUpdatePermissions}\n availablePermissions={availablePermissions}\n availableScopes={availableScopes}\n onNodeClick={handleNodeNavigate}\n fullHeight\n />\n {isRefreshingGraph && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-bg-surface/60 backdrop-blur-[1px]\">\n <div className=\"inline-flex items-center gap-2 rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-secondary shadow-md\">\n <Loader2 className=\"size-4 animate-spin text-action-primary-bg\" />\n <span>\n {scopeValue\n ? tr('agentGraph.loadingScope', 'Applying selected scope...')\n : tr('agentGraph.refreshing', 'Refreshing graph...')}\n </span>\n </div>\n </div>\n )}\n </div>\n )}\n </>\n )}\n </MotionPage>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AgentGraphPage.js","names":[],"sources":["../../src/pages/AgentGraphPage.tsx"],"sourcesContent":["/**\n * Agent Graph Page — Dedicated full-page view of the agent connection graph.\n *\n * Shows targets as group nodes with agents inside (sub-flows) and\n * connections as directed edges. Supports root-node scoping and\n * RBAC permission editing.\n */\n\nimport { useState, useMemo, useCallback } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { GitBranch, Loader2, Network } from 'lucide-react';\nimport {\n PageHeader,\n SearchableSelect,\n LoadingState,\n ErrorState,\n EmptyState,\n GetHelpButton,\n} from '@/components/shared';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useVibeControls, useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\nimport {\n useGetAgentGraphQuery,\n useUpdateConnectionPermissionsMutation,\n useAgentConnectionConfigQuery,\n useListTargetsQuery,\n type ListTargetsQuery,\n} from '@/generated/wspace-operations';\n\ntype TargetItem = NonNullable<ListTargetsQuery['targets']['items'][number]>;\nimport { AgentGraphView } from '@/components/graph/AgentGraphView';\n\nexport function AgentGraphPage() {\n const { workspaceId } = useVibeControls();\n const navigate = useVibeNavigate();\n const { t } = useI18n();\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n const [rootAgentId, setRootAgentId] = useState<string | null>(null);\n\n const tr = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key, params);\n const template = translated === key ? fallback : translated;\n\n if (!params) return template;\n\n return Object.entries(params).reduce(\n (acc, [paramKey, paramValue]) => acc.replace(`{{${paramKey}}}`, String(paramValue)),\n template\n );\n },\n [t]\n );\n\n // Use cached initial data for agents; fetch targets directly\n const { agents: cachedAgents } = useCachedInitialData();\n const { data: targetsData } = useListTargetsQuery({\n variables: { workspaceId: workspaceId ?? '' },\n skip: !workspaceId,\n fetchPolicy: 'cache-and-network',\n });\n const cachedTargets = targetsData?.targets?.items ?? [];\n const scopeOptions = useMemo(() => {\n const agentOpts = cachedAgents.map((a) => ({\n value: a.id,\n label: tr('agentGraph.scopeAgentPrefix', 'Agent: {{name}}', { name: a.name }),\n }));\n const targetOpts = cachedTargets.map((tgt: TargetItem) => ({\n value: `target:${tgt.id}`,\n label: tr('agentGraph.scopeTargetPrefix', 'Target: {{name}}', { name: tgt.name }),\n }));\n return [...targetOpts, ...agentOpts];\n }, [cachedAgents, cachedTargets, tr]);\n\n const [scopeValue, setScopeValue] = useState<string>('');\n\n const { data: connectionConfigData } = useAgentConnectionConfigQuery({\n skip: !workspaceId,\n });\n\n const availablePermissions = connectionConfigData?.agentConnectionConfig.permissions ?? [];\n const availableScopes = connectionConfigData?.agentConnectionConfig.scopes ?? [];\n\n const {\n data: graphData,\n previousData,\n loading,\n error,\n refetch,\n } = useGetAgentGraphQuery({\n variables: {\n workspaceId: workspaceId || '',\n rootAgentId: rootAgentId || undefined,\n },\n skip: !workspaceId,\n });\n\n const resolvedAgentGraph = graphData?.agentGraph ?? previousData?.agentGraph;\n const graphTargets = resolvedAgentGraph?.targets ?? [];\n const graphConnections = resolvedAgentGraph?.connections ?? [];\n const isGraphLoading = loading;\n // Covers first load (including first scoped load) when no prior graph snapshot exists.\n const isInitialLoad = isGraphLoading && !resolvedAgentGraph;\n const isRefreshingGraph = isGraphLoading && Boolean(resolvedAgentGraph);\n\n const [updateConnectionPerms] = useUpdateConnectionPermissionsMutation();\n\n const handleNodeNavigate = useCallback(\n (nodeType: 'target' | 'agent', id: string) => {\n if (nodeType === 'target') {\n const targetParams = new URLSearchParams({\n tab: 'targets',\n selectedTargetId: id,\n });\n navigate(`/agents?${targetParams.toString()}`);\n return;\n }\n navigate(`/agents/${id}`);\n },\n [navigate]\n );\n\n const handleUpdatePermissions = useCallback(\n async (connectionId: string, permissions: string[], scopes: string[]) => {\n await updateConnectionPerms({\n variables: { connectionId, input: { permissions, scopes } },\n });\n await refetch();\n },\n [refetch, updateConnectionPerms]\n );\n\n if (permissionsLoading)\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <p className=\"text-text-secondary\">Loading permissions…</p>\n </div>\n );\n if (\n permissions &&\n (permissions.permissionStrings?.length ?? 0) > 0 &&\n !hasPermission(VIBE_PERMISSIONS.AGENT_READ)\n )\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-foreground\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don't have permission to access this page.\n </p>\n </div>\n </div>\n );\n\n return (\n <MotionPage>\n <PageHeader\n title={tr('nav.agentGraph', 'Agent Graph')}\n description={tr(\n 'agentGraph.description',\n 'Visualize and manage connections between targets and agents.'\n )}\n />\n\n {isInitialLoad && (\n <LoadingState message={tr('agentGraph.loading', 'Loading agent graph...')} />\n )}\n\n {/* Non-fatal error: show banner but don't hide graph if data is available */}\n {!isGraphLoading && error && graphTargets.length === 0 && (\n <ErrorState\n title={tr('agentGraph.failedLoad', 'Failed to load agent graph')}\n message={error.message}\n />\n )}\n\n {!isGraphLoading && !error && graphTargets.length === 0 && !scopeValue && (\n <EmptyState\n icon={<Network className=\"size-8 text-text-secondary\" />}\n title={tr('agentGraph.noTargetsConnected', 'No targets connected')}\n description={tr(\n 'agentGraph.noTargetsDescription',\n 'Register an agent on a target to start visualizing your infrastructure topology.'\n )}\n action={\n <GetHelpButton prompt=\"What is the Agent Graph in VibeControls and what does it show?\" />\n }\n />\n )}\n\n {/* Scope controls + graph: shown whenever we have data, or when a scope filter is\n active (so the user can always clear the filter and recover the full view) */}\n {(graphTargets.length > 0 || scopeValue || isRefreshingGraph) && (\n <>\n {/* Filters — always rendered so user can clear an active scope filter */}\n <div className=\"flex items-center gap-3 mt-4\">\n <div className=\"flex items-center gap-2\">\n <GitBranch size={16} className=\"text-text-tertiary\" />\n <span className=\"text-sm font-medium text-text-secondary\">\n {tr('agentGraph.countSummary', '{{targets}} targets, {{connections}} connections', {\n targets: graphTargets.length,\n connections: graphConnections.length,\n })}\n </span>\n\n {isRefreshingGraph && (\n <span\n role=\"status\"\n aria-live=\"polite\"\n className=\"inline-flex items-center gap-1.5 rounded-full border border-border-default bg-bg-surface px-2.5 py-1 text-xs font-medium text-text-secondary\"\n >\n <Loader2 className=\"size-3.5 animate-spin text-action-primary-bg\" />\n {tr('agentGraph.refreshing', 'Refreshing graph...')}\n </span>\n )}\n </div>\n <div className=\"flex-1\" />\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs font-medium text-text-secondary\">\n {tr('agentGraph.scopeLabel', 'Scope:')}\n </label>\n <SearchableSelect\n value={scopeValue}\n onChange={(v: string) => {\n setScopeValue(v);\n // If selecting a target, clear rootAgentId; if agent, set it\n if (v.startsWith('target:')) {\n setRootAgentId(null);\n } else {\n setRootAgentId(v || null);\n }\n }}\n options={scopeOptions}\n placeholder={tr('agentGraph.scopeAll', 'All targets & agents')}\n clearable\n disabled={isGraphLoading}\n dropdownAlign=\"right\"\n />\n </div>\n </div>\n\n {!isGraphLoading && error && (\n <ErrorState\n title={tr('agentGraph.failedRefresh', 'Failed to refresh agent graph')}\n message={error.message}\n />\n )}\n\n {!isGraphLoading && graphTargets.length === 0 && scopeValue && (\n <EmptyState\n icon={<Network className=\"size-8 text-text-secondary\" />}\n title={tr('agentGraph.noScopeResults', 'No results for this scope')}\n description={tr(\n 'agentGraph.noScopeDescription',\n 'No targets match the selected scope. Clear the filter to view all targets.'\n )}\n />\n )}\n\n {(graphTargets.length > 0 || isRefreshingGraph) && (\n <div\n className=\"mt-4 relative\"\n style={{ height: 'calc(100vh - 280px)', minHeight: '400px' }}\n aria-busy={isRefreshingGraph}\n >\n <AgentGraphView\n targets={\n graphTargets as Array<{\n id: string;\n name: string;\n type: string;\n status: string;\n host?: string | null;\n agents: Array<{ id: string; name: string; version: string; isActive: boolean }>;\n }>\n }\n connections={\n graphConnections as Array<{\n id: string;\n protocol: string;\n status: string;\n permissions?: string[];\n scopes?: string[];\n label?: string | null;\n description?: string | null;\n sourceAgent: { id: string; name: string };\n target: { id: string; name: string; type: string };\n }>\n }\n onUpdatePermissions={handleUpdatePermissions}\n availablePermissions={availablePermissions}\n availableScopes={availableScopes}\n onNodeClick={handleNodeNavigate}\n fullHeight\n />\n {isRefreshingGraph && (\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-bg-surface/60 backdrop-blur-[1px]\">\n <div className=\"inline-flex items-center gap-2 rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-secondary shadow-md\">\n <Loader2 className=\"size-4 animate-spin text-action-primary-bg\" />\n <span>\n {scopeValue\n ? tr('agentGraph.loadingScope', 'Applying selected scope...')\n : tr('agentGraph.refreshing', 'Refreshing graph...')}\n </span>\n </div>\n </div>\n )}\n </div>\n )}\n </>\n )}\n </MotionPage>\n );\n}\n"],"mappings":"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"}