@burdenoff/microfe-vibecontrols 2026.601.9 → 2026.601.11
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/_virtual/_rolldown/runtime.js +2 -5
- package/dist/components/graph/AgentGraphView.js +237 -0
- package/dist/components/graph/AgentGraphView.js.map +1 -0
- package/dist/components/graph/AgentNode.js +54 -0
- package/dist/components/graph/AgentNode.js.map +1 -0
- package/dist/components/graph/TargetNode.js +76 -0
- package/dist/components/graph/TargetNode.js.map +1 -0
- package/dist/components/tunnels/TunnelCreateWizard.js +219 -214
- package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
- package/dist/generated/wspace-operations.js +1644 -1853
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js +12 -14
- package/dist/generated/wspace-types.js.map +1 -1
- package/dist/index.js +10 -10
- package/dist/pages/AgentGraphPage.js +118 -251
- package/dist/pages/AgentGraphPage.js.map +1 -1
- package/dist/pages/AgentsPage.js +259 -246
- package/dist/pages/AgentsPage.js.map +1 -1
- package/dist/pages/SessionsPage.js +742 -728
- package/dist/pages/SessionsPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +303 -285
- package/dist/pages/VibeDeckPage.js.map +1 -1
- package/dist/pages/tunnels/TunnelsTab.js +79 -74
- package/dist/pages/tunnels/TunnelsTab.js.map +1 -1
- package/dist/providers/QuotaExhaustedProvider.js +27 -18
- package/dist/providers/QuotaExhaustedProvider.js.map +1 -1
- package/package.json +1 -3
- package/dist/components/graph/MeshAgentNode.js +0 -74
- package/dist/components/graph/MeshAgentNode.js.map +0 -1
- package/dist/components/graph/MeshDeployWizard.js +0 -393
- package/dist/components/graph/MeshDeployWizard.js.map +0 -1
- package/dist/components/graph/MeshGraphView.js +0 -190
- package/dist/components/graph/MeshGraphView.js.map +0 -1
- package/dist/components/graph/MeshNodeActions.js +0 -70
- package/dist/components/graph/MeshNodeActions.js.map +0 -1
- package/dist/components/graph/MeshRequestPanel.js +0 -240
- package/dist/components/graph/MeshRequestPanel.js.map +0 -1
- package/dist/components/graph/meshTypes.js +0 -11
- package/dist/components/graph/meshTypes.js.map +0 -1
- package/dist/components/graph/nodeIcons.js +0 -31
- package/dist/components/graph/nodeIcons.js.map +0 -1
- package/dist/node_modules/dagre/index.js +0 -24
- package/dist/node_modules/dagre/index.js.map +0 -1
- package/dist/node_modules/dagre/lib/acyclic.js +0 -47
- package/dist/node_modules/dagre/lib/acyclic.js.map +0 -1
- package/dist/node_modules/dagre/lib/add-border-segments.js +0 -32
- package/dist/node_modules/dagre/lib/add-border-segments.js.map +0 -1
- package/dist/node_modules/dagre/lib/coordinate-system.js +0 -57
- package/dist/node_modules/dagre/lib/coordinate-system.js.map +0 -1
- package/dist/node_modules/dagre/lib/data/list.js +0 -30
- package/dist/node_modules/dagre/lib/data/list.js.map +0 -1
- package/dist/node_modules/dagre/lib/debug.js +0 -31
- package/dist/node_modules/dagre/lib/debug.js.map +0 -1
- package/dist/node_modules/dagre/lib/graphlib.js +0 -15
- package/dist/node_modules/dagre/lib/graphlib.js.map +0 -1
- package/dist/node_modules/dagre/lib/greedy-fas.js +0 -74
- package/dist/node_modules/dagre/lib/greedy-fas.js.map +0 -1
- package/dist/node_modules/dagre/lib/layout.js +0 -305
- package/dist/node_modules/dagre/lib/layout.js.map +0 -1
- package/dist/node_modules/dagre/lib/lodash.js +0 -67
- package/dist/node_modules/dagre/lib/lodash.js.map +0 -1
- package/dist/node_modules/dagre/lib/nesting-graph.js +0 -76
- package/dist/node_modules/dagre/lib/nesting-graph.js.map +0 -1
- package/dist/node_modules/dagre/lib/normalize.js +0 -45
- package/dist/node_modules/dagre/lib/normalize.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/add-subgraph-constraints.js +0 -24
- package/dist/node_modules/dagre/lib/order/add-subgraph-constraints.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/barycenter.js +0 -34
- package/dist/node_modules/dagre/lib/order/barycenter.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/build-layer-graph.js +0 -32
- package/dist/node_modules/dagre/lib/order/build-layer-graph.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/cross-count.js +0 -39
- package/dist/node_modules/dagre/lib/order/cross-count.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/index.js +0 -50
- package/dist/node_modules/dagre/lib/order/index.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/init-order.js +0 -28
- package/dist/node_modules/dagre/lib/order/init-order.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/resolve-conflicts.js +0 -61
- package/dist/node_modules/dagre/lib/order/resolve-conflicts.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/sort-subgraph.js +0 -50
- package/dist/node_modules/dagre/lib/order/sort-subgraph.js.map +0 -1
- package/dist/node_modules/dagre/lib/order/sort.js +0 -34
- package/dist/node_modules/dagre/lib/order/sort.js.map +0 -1
- package/dist/node_modules/dagre/lib/parent-dummy-chains.js +0 -50
- package/dist/node_modules/dagre/lib/parent-dummy-chains.js.map +0 -1
- package/dist/node_modules/dagre/lib/position/bk.js +0 -212
- package/dist/node_modules/dagre/lib/position/bk.js.map +0 -1
- package/dist/node_modules/dagre/lib/position/index.js +0 -30
- package/dist/node_modules/dagre/lib/position/index.js.map +0 -1
- package/dist/node_modules/dagre/lib/rank/feasible-tree.js +0 -39
- package/dist/node_modules/dagre/lib/rank/feasible-tree.js.map +0 -1
- package/dist/node_modules/dagre/lib/rank/index.js +0 -35
- package/dist/node_modules/dagre/lib/rank/index.js.map +0 -1
- package/dist/node_modules/dagre/lib/rank/network-simplex.js +0 -90
- package/dist/node_modules/dagre/lib/rank/network-simplex.js.map +0 -1
- package/dist/node_modules/dagre/lib/rank/util.js +0 -31
- package/dist/node_modules/dagre/lib/rank/util.js.map +0 -1
- package/dist/node_modules/dagre/lib/util.js +0 -151
- package/dist/node_modules/dagre/lib/util.js.map +0 -1
- package/dist/node_modules/dagre/lib/version.js +0 -10
- package/dist/node_modules/dagre/lib/version.js.map +0 -1
- package/dist/node_modules/graphlib/index.js +0 -19
- package/dist/node_modules/graphlib/index.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/components.js +0 -21
- package/dist/node_modules/graphlib/lib/alg/components.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/dfs.js +0 -25
- package/dist/node_modules/graphlib/lib/alg/dfs.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/dijkstra-all.js +0 -18
- package/dist/node_modules/graphlib/lib/alg/dijkstra-all.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/dijkstra.js +0 -31
- package/dist/node_modules/graphlib/lib/alg/dijkstra.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/find-cycles.js +0 -18
- package/dist/node_modules/graphlib/lib/alg/find-cycles.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/floyd-warshall.js +0 -41
- package/dist/node_modules/graphlib/lib/alg/floyd-warshall.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/index.js +0 -33
- package/dist/node_modules/graphlib/lib/alg/index.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/is-acyclic.js +0 -21
- package/dist/node_modules/graphlib/lib/alg/is-acyclic.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/postorder.js +0 -15
- package/dist/node_modules/graphlib/lib/alg/postorder.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/preorder.js +0 -15
- package/dist/node_modules/graphlib/lib/alg/preorder.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/prim.js +0 -35
- package/dist/node_modules/graphlib/lib/alg/prim.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/tarjan.js +0 -34
- package/dist/node_modules/graphlib/lib/alg/tarjan.js.map +0 -1
- package/dist/node_modules/graphlib/lib/alg/topsort.js +0 -23
- package/dist/node_modules/graphlib/lib/alg/topsort.js.map +0 -1
- package/dist/node_modules/graphlib/lib/data/priority-queue.js +0 -56
- package/dist/node_modules/graphlib/lib/data/priority-queue.js.map +0 -1
- package/dist/node_modules/graphlib/lib/graph.js +0 -196
- package/dist/node_modules/graphlib/lib/graph.js.map +0 -1
- package/dist/node_modules/graphlib/lib/index.js +0 -15
- package/dist/node_modules/graphlib/lib/index.js.map +0 -1
- package/dist/node_modules/graphlib/lib/json.js +0 -55
- package/dist/node_modules/graphlib/lib/json.js.map +0 -1
- package/dist/node_modules/graphlib/lib/lodash.js +0 -47
- package/dist/node_modules/graphlib/lib/lodash.js.map +0 -1
- package/dist/node_modules/graphlib/lib/version.js +0 -10
- package/dist/node_modules/graphlib/lib/version.js.map +0 -1
- package/dist/node_modules/lodash/_arrayEach.js +0 -14
- package/dist/node_modules/lodash/_arrayEach.js.map +0 -1
- package/dist/node_modules/lodash/_arrayReduce.js +0 -15
- package/dist/node_modules/lodash/_arrayReduce.js.map +0 -1
- package/dist/node_modules/lodash/_asciiSize.js +0 -11
- package/dist/node_modules/lodash/_asciiSize.js.map +0 -1
- package/dist/node_modules/lodash/_assignMergeValue.js +0 -16
- package/dist/node_modules/lodash/_assignMergeValue.js.map +0 -1
- package/dist/node_modules/lodash/_assignValue.js +0 -17
- package/dist/node_modules/lodash/_assignValue.js.map +0 -1
- package/dist/node_modules/lodash/_baseAssign.js +0 -16
- package/dist/node_modules/lodash/_baseAssign.js.map +0 -1
- package/dist/node_modules/lodash/_baseAssignIn.js +0 -16
- package/dist/node_modules/lodash/_baseAssignIn.js.map +0 -1
- package/dist/node_modules/lodash/_baseClone.js +0 -64
- package/dist/node_modules/lodash/_baseClone.js.map +0 -1
- package/dist/node_modules/lodash/_baseCreate.js +0 -21
- package/dist/node_modules/lodash/_baseCreate.js.map +0 -1
- package/dist/node_modules/lodash/_baseFilter.js +0 -18
- package/dist/node_modules/lodash/_baseFilter.js.map +0 -1
- package/dist/node_modules/lodash/_baseHas.js +0 -14
- package/dist/node_modules/lodash/_baseHas.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsMap.js +0 -16
- package/dist/node_modules/lodash/_baseIsMap.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsSet.js +0 -16
- package/dist/node_modules/lodash/_baseIsSet.js.map +0 -1
- package/dist/node_modules/lodash/_baseKeysIn.js +0 -20
- package/dist/node_modules/lodash/_baseKeysIn.js.map +0 -1
- package/dist/node_modules/lodash/_baseMerge.js +0 -27
- package/dist/node_modules/lodash/_baseMerge.js.map +0 -1
- package/dist/node_modules/lodash/_baseMergeDeep.js +0 -39
- package/dist/node_modules/lodash/_baseMergeDeep.js.map +0 -1
- package/dist/node_modules/lodash/_basePick.js +0 -18
- package/dist/node_modules/lodash/_basePick.js.map +0 -1
- package/dist/node_modules/lodash/_basePickBy.js +0 -21
- package/dist/node_modules/lodash/_basePickBy.js.map +0 -1
- package/dist/node_modules/lodash/_baseReduce.js +0 -15
- package/dist/node_modules/lodash/_baseReduce.js.map +0 -1
- package/dist/node_modules/lodash/_baseSet.js +0 -30
- package/dist/node_modules/lodash/_baseSet.js.map +0 -1
- package/dist/node_modules/lodash/_baseValues.js +0 -17
- package/dist/node_modules/lodash/_baseValues.js.map +0 -1
- package/dist/node_modules/lodash/_baseZipObject.js +0 -17
- package/dist/node_modules/lodash/_baseZipObject.js.map +0 -1
- package/dist/node_modules/lodash/_castFunction.js +0 -15
- package/dist/node_modules/lodash/_castFunction.js.map +0 -1
- package/dist/node_modules/lodash/_cloneArrayBuffer.js +0 -16
- package/dist/node_modules/lodash/_cloneArrayBuffer.js.map +0 -1
- package/dist/node_modules/lodash/_cloneBuffer.js +0 -17
- package/dist/node_modules/lodash/_cloneBuffer.js.map +0 -1
- package/dist/node_modules/lodash/_cloneDataView.js +0 -16
- package/dist/node_modules/lodash/_cloneDataView.js.map +0 -1
- package/dist/node_modules/lodash/_cloneRegExp.js +0 -15
- package/dist/node_modules/lodash/_cloneRegExp.js.map +0 -1
- package/dist/node_modules/lodash/_cloneSymbol.js +0 -15
- package/dist/node_modules/lodash/_cloneSymbol.js.map +0 -1
- package/dist/node_modules/lodash/_cloneTypedArray.js +0 -16
- package/dist/node_modules/lodash/_cloneTypedArray.js.map +0 -1
- package/dist/node_modules/lodash/_copyArray.js +0 -15
- package/dist/node_modules/lodash/_copyArray.js.map +0 -1
- package/dist/node_modules/lodash/_copyObject.js +0 -22
- package/dist/node_modules/lodash/_copyObject.js.map +0 -1
- package/dist/node_modules/lodash/_copySymbols.js +0 -16
- package/dist/node_modules/lodash/_copySymbols.js.map +0 -1
- package/dist/node_modules/lodash/_copySymbolsIn.js +0 -16
- package/dist/node_modules/lodash/_copySymbolsIn.js.map +0 -1
- package/dist/node_modules/lodash/_createAssigner.js +0 -23
- package/dist/node_modules/lodash/_createAssigner.js.map +0 -1
- package/dist/node_modules/lodash/_flatRest.js +0 -17
- package/dist/node_modules/lodash/_flatRest.js.map +0 -1
- package/dist/node_modules/lodash/_getAllKeysIn.js +0 -17
- package/dist/node_modules/lodash/_getAllKeysIn.js.map +0 -1
- package/dist/node_modules/lodash/_getSymbolsIn.js +0 -18
- package/dist/node_modules/lodash/_getSymbolsIn.js.map +0 -1
- package/dist/node_modules/lodash/_initCloneArray.js +0 -15
- package/dist/node_modules/lodash/_initCloneArray.js.map +0 -1
- package/dist/node_modules/lodash/_initCloneByTag.js +0 -40
- package/dist/node_modules/lodash/_initCloneByTag.js.map +0 -1
- package/dist/node_modules/lodash/_initCloneObject.js +0 -17
- package/dist/node_modules/lodash/_initCloneObject.js.map +0 -1
- package/dist/node_modules/lodash/_nativeKeysIn.js +0 -15
- package/dist/node_modules/lodash/_nativeKeysIn.js.map +0 -1
- package/dist/node_modules/lodash/_safeGet.js +0 -13
- package/dist/node_modules/lodash/_safeGet.js.map +0 -1
- package/dist/node_modules/lodash/_stringSize.js +0 -17
- package/dist/node_modules/lodash/_stringSize.js.map +0 -1
- package/dist/node_modules/lodash/_unicodeSize.js +0 -25
- package/dist/node_modules/lodash/_unicodeSize.js.map +0 -1
- package/dist/node_modules/lodash/clone.js +0 -15
- package/dist/node_modules/lodash/clone.js.map +0 -1
- package/dist/node_modules/lodash/cloneDeep.js +0 -15
- package/dist/node_modules/lodash/cloneDeep.js.map +0 -1
- package/dist/node_modules/lodash/defaults.js +0 -23
- package/dist/node_modules/lodash/defaults.js.map +0 -1
- package/dist/node_modules/lodash/each.js +0 -11
- package/dist/node_modules/lodash/each.js.map +0 -1
- package/dist/node_modules/lodash/filter.js +0 -18
- package/dist/node_modules/lodash/filter.js.map +0 -1
- package/dist/node_modules/lodash/flatten.js +0 -15
- package/dist/node_modules/lodash/flatten.js.map +0 -1
- package/dist/node_modules/lodash/forEach.js +0 -18
- package/dist/node_modules/lodash/forEach.js.map +0 -1
- package/dist/node_modules/lodash/forIn.js +0 -17
- package/dist/node_modules/lodash/forIn.js.map +0 -1
- package/dist/node_modules/lodash/has.js +0 -16
- package/dist/node_modules/lodash/has.js.map +0 -1
- package/dist/node_modules/lodash/isArrayLikeObject.js +0 -16
- package/dist/node_modules/lodash/isArrayLikeObject.js.map +0 -1
- package/dist/node_modules/lodash/isEmpty.js +0 -28
- package/dist/node_modules/lodash/isEmpty.js.map +0 -1
- package/dist/node_modules/lodash/isMap.js +0 -14
- package/dist/node_modules/lodash/isMap.js.map +0 -1
- package/dist/node_modules/lodash/isSet.js +0 -14
- package/dist/node_modules/lodash/isSet.js.map +0 -1
- package/dist/node_modules/lodash/isUndefined.js +0 -13
- package/dist/node_modules/lodash/isUndefined.js.map +0 -1
- package/dist/node_modules/lodash/keysIn.js +0 -17
- package/dist/node_modules/lodash/keysIn.js.map +0 -1
- package/dist/node_modules/lodash/merge.js +0 -15
- package/dist/node_modules/lodash/merge.js.map +0 -1
- package/dist/node_modules/lodash/pick.js +0 -15
- package/dist/node_modules/lodash/pick.js.map +0 -1
- package/dist/node_modules/lodash/reduce.js +0 -20
- package/dist/node_modules/lodash/reduce.js.map +0 -1
- package/dist/node_modules/lodash/size.js +0 -22
- package/dist/node_modules/lodash/size.js.map +0 -1
- package/dist/node_modules/lodash/toPlainObject.js +0 -16
- package/dist/node_modules/lodash/toPlainObject.js.map +0 -1
- package/dist/node_modules/lodash/transform.js +0 -31
- package/dist/node_modules/lodash/transform.js.map +0 -1
- package/dist/node_modules/lodash/union.js +0 -17
- package/dist/node_modules/lodash/union.js.map +0 -1
- package/dist/node_modules/lodash/uniqueId.js +0 -16
- package/dist/node_modules/lodash/uniqueId.js.map +0 -1
- package/dist/node_modules/lodash/values.js +0 -16
- package/dist/node_modules/lodash/values.js.map +0 -1
- package/dist/node_modules/lodash/zipObject.js +0 -16
- package/dist/node_modules/lodash/zipObject.js.map +0 -1
|
@@ -15,9 +15,6 @@ var e = Object.create, t = Object.defineProperty, n = Object.getOwnPropertyDescr
|
|
|
15
15
|
}, l = (n, r, a) => (a = n == null ? {} : e(i(n)), c(r || !n || !n.__esModule ? t(a, "default", {
|
|
16
16
|
value: n,
|
|
17
17
|
enumerable: !0
|
|
18
|
-
}) : a, n))
|
|
19
|
-
if (typeof require < "u") return require.apply(this, arguments);
|
|
20
|
-
throw Error("Calling `require` for \"" + e + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
21
|
-
});
|
|
18
|
+
}) : a, n));
|
|
22
19
|
//#endregion
|
|
23
|
-
export { o as __commonJSMin, s as __exportAll,
|
|
20
|
+
export { o as __commonJSMin, s as __exportAll, l as __toESM };
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
|
+
import { TargetNode as t } from "./TargetNode.js";
|
|
3
|
+
import { AgentNode as n } from "./AgentNode.js";
|
|
4
|
+
import { ConnectionPermissionsDialog as r } from "./ConnectionPermissionsDialog.js";
|
|
5
|
+
import { useCallback as i, useEffect as a, useLayoutEffect as o, useMemo as s, useRef as c, useState as l } from "react";
|
|
6
|
+
import { CheckCircle as u } from "lucide-react";
|
|
7
|
+
import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
8
|
+
import { Background as m, BackgroundVariant as h, Controls as g, MarkerType as _, MiniMap as v, ReactFlow as y, useEdgesState as b, useNodesState as x } from "@xyflow/react";
|
|
9
|
+
import "@xyflow/react/dist/style.css";
|
|
10
|
+
//#region src/components/graph/AgentGraphView.tsx
|
|
11
|
+
var S = {
|
|
12
|
+
targetNode: t,
|
|
13
|
+
agentNode: n
|
|
14
|
+
}, C = 280, w = 100, T = 48, E = 8, D = 16, O = 16, k = 100, A = 40;
|
|
15
|
+
function j(e) {
|
|
16
|
+
return e >= C * 4 + k * 3 ? 4 : e >= C * 3 + k * 2 ? 3 : e >= C * 2 + k ? 2 : 1;
|
|
17
|
+
}
|
|
18
|
+
function M(e) {
|
|
19
|
+
return w + Math.max(e.agents.length, 1) * (T + E) + O;
|
|
20
|
+
}
|
|
21
|
+
function N(e, t, n, r) {
|
|
22
|
+
let i = [], a = [], o = Math.ceil(e.length / n), s = Array.from({ length: o }, (t, r) => e.slice(r * n, (r + 1) * n).reduce((e, t) => Math.max(e, M(t)), 0)), c = s.reduce((e, t, n) => (e.push(n === 0 ? 0 : e[n - 1] + s[n - 1] + A), e), []);
|
|
23
|
+
return e.forEach((e, t) => {
|
|
24
|
+
let a = t % n, o = Math.floor(t / n), s = M(e), l = a * (C + k), u = c[o];
|
|
25
|
+
i.push({
|
|
26
|
+
id: `target-${e.id}`,
|
|
27
|
+
type: "targetNode",
|
|
28
|
+
position: {
|
|
29
|
+
x: l,
|
|
30
|
+
y: u
|
|
31
|
+
},
|
|
32
|
+
data: {
|
|
33
|
+
entityId: e.id,
|
|
34
|
+
name: e.name,
|
|
35
|
+
nodeType: "target",
|
|
36
|
+
type: e.type,
|
|
37
|
+
status: e.status,
|
|
38
|
+
host: e.host,
|
|
39
|
+
agentCount: e.agents.length,
|
|
40
|
+
onActivate: r ? () => r("target", e.id) : void 0
|
|
41
|
+
},
|
|
42
|
+
className: r ? "cursor-pointer" : void 0,
|
|
43
|
+
style: {
|
|
44
|
+
width: C,
|
|
45
|
+
height: s
|
|
46
|
+
}
|
|
47
|
+
}), e.agents.forEach((t, n) => {
|
|
48
|
+
i.push({
|
|
49
|
+
id: `agent-${t.id}`,
|
|
50
|
+
type: "agentNode",
|
|
51
|
+
position: {
|
|
52
|
+
x: D,
|
|
53
|
+
y: w + n * (T + E)
|
|
54
|
+
},
|
|
55
|
+
parentId: `target-${e.id}`,
|
|
56
|
+
extent: "parent",
|
|
57
|
+
data: {
|
|
58
|
+
entityId: t.id,
|
|
59
|
+
name: t.name,
|
|
60
|
+
nodeType: "agent",
|
|
61
|
+
version: t.version,
|
|
62
|
+
isActive: t.isActive,
|
|
63
|
+
onActivate: r ? () => r("agent", t.id) : void 0
|
|
64
|
+
},
|
|
65
|
+
className: r ? "cursor-pointer" : void 0,
|
|
66
|
+
style: { width: C - D * 2 }
|
|
67
|
+
});
|
|
68
|
+
}), e.agents.length === 0 && i.push({
|
|
69
|
+
id: `empty-${e.id}`,
|
|
70
|
+
type: "agentNode",
|
|
71
|
+
position: {
|
|
72
|
+
x: D,
|
|
73
|
+
y: w
|
|
74
|
+
},
|
|
75
|
+
parentId: `target-${e.id}`,
|
|
76
|
+
extent: "parent",
|
|
77
|
+
data: {
|
|
78
|
+
name: "No agent installed",
|
|
79
|
+
version: "",
|
|
80
|
+
isActive: !1,
|
|
81
|
+
isEmpty: !0
|
|
82
|
+
},
|
|
83
|
+
style: { width: C - D * 2 }
|
|
84
|
+
});
|
|
85
|
+
}), t.forEach((e) => {
|
|
86
|
+
let t = `agent-${e.sourceAgent.id}`, n = `target-${e.target.id}`;
|
|
87
|
+
if (!i.some((e) => e.id === t) || !i.some((e) => e.id === n)) return;
|
|
88
|
+
let r = e.status === "connected";
|
|
89
|
+
a.push({
|
|
90
|
+
id: `edge-${e.id}`,
|
|
91
|
+
source: t,
|
|
92
|
+
target: n,
|
|
93
|
+
label: e.protocol,
|
|
94
|
+
data: e,
|
|
95
|
+
type: "default",
|
|
96
|
+
animated: r,
|
|
97
|
+
markerEnd: { type: _.ArrowClosed },
|
|
98
|
+
style: {
|
|
99
|
+
stroke: r ? "var(--color-status-success-border)" : "var(--color-border-strong)",
|
|
100
|
+
strokeWidth: 2
|
|
101
|
+
},
|
|
102
|
+
labelStyle: {
|
|
103
|
+
fontSize: 10,
|
|
104
|
+
fontWeight: 600
|
|
105
|
+
},
|
|
106
|
+
labelBgStyle: { fill: "transparent" },
|
|
107
|
+
labelBgPadding: [4, 2]
|
|
108
|
+
});
|
|
109
|
+
}), {
|
|
110
|
+
nodes: i,
|
|
111
|
+
edges: a
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function P({ targets: t, connections: n, onUpdatePermissions: _, availablePermissions: C, availableScopes: w, onNodeClick: T, fullHeight: E }) {
|
|
115
|
+
let D = e(), O = c(null), [k, A] = l(() => typeof window > "u" ? 3 : j(window.innerWidth));
|
|
116
|
+
o(() => {
|
|
117
|
+
let e = (e) => {
|
|
118
|
+
A((t) => {
|
|
119
|
+
let n = j(e);
|
|
120
|
+
return t === n ? t : n;
|
|
121
|
+
});
|
|
122
|
+
}, t = () => {
|
|
123
|
+
let t = O.current?.clientWidth;
|
|
124
|
+
typeof t == "number" && t > 0 && e(t);
|
|
125
|
+
};
|
|
126
|
+
t();
|
|
127
|
+
let n = typeof ResizeObserver < "u" ? new ResizeObserver((t) => {
|
|
128
|
+
let n = t[0];
|
|
129
|
+
n && e(n.contentRect.width);
|
|
130
|
+
}) : null;
|
|
131
|
+
return n && O.current ? n.observe(O.current) : window.addEventListener("resize", t), () => {
|
|
132
|
+
n || window.removeEventListener("resize", t), n?.disconnect();
|
|
133
|
+
};
|
|
134
|
+
}, []);
|
|
135
|
+
let { nodes: M, edges: P } = s(() => N(t, n, k, T), [
|
|
136
|
+
t,
|
|
137
|
+
n,
|
|
138
|
+
k,
|
|
139
|
+
T
|
|
140
|
+
]), [F, I, L] = x(M), [R, z, B] = b(P), [V, H] = l(null), [U, W] = l(!1);
|
|
141
|
+
a(() => {
|
|
142
|
+
let { nodes: e, edges: r } = N(t, n, k, T);
|
|
143
|
+
I(e), z(r);
|
|
144
|
+
}, [
|
|
145
|
+
t,
|
|
146
|
+
n,
|
|
147
|
+
k,
|
|
148
|
+
T,
|
|
149
|
+
I,
|
|
150
|
+
z
|
|
151
|
+
]);
|
|
152
|
+
let G = i((e, t) => {
|
|
153
|
+
if (!T) return;
|
|
154
|
+
let { entityId: n, nodeType: r } = t.data ?? {};
|
|
155
|
+
!n || !r || T(r, n);
|
|
156
|
+
}, [T]), K = i((e, t) => {
|
|
157
|
+
let r = n.find((e) => `edge-${e.id}` === t.id);
|
|
158
|
+
r && H(r);
|
|
159
|
+
}, [n]), q = i((e, t) => {
|
|
160
|
+
V && _ && _(V.id, e, t), H(null), W(!0), setTimeout(() => W(!1), 3e3);
|
|
161
|
+
}, [V, _]);
|
|
162
|
+
return /* @__PURE__ */ p(d, { children: [
|
|
163
|
+
/* @__PURE__ */ f("div", {
|
|
164
|
+
ref: O,
|
|
165
|
+
className: "w-full rounded-lg border border-border-default overflow-hidden bg-bg-secondary",
|
|
166
|
+
style: { height: E ? "100%" : "500px" },
|
|
167
|
+
children: /* @__PURE__ */ p(y, {
|
|
168
|
+
nodes: F,
|
|
169
|
+
edges: R,
|
|
170
|
+
nodesDraggable: !1,
|
|
171
|
+
onNodesChange: L,
|
|
172
|
+
onEdgesChange: B,
|
|
173
|
+
onNodeClick: G,
|
|
174
|
+
onEdgeClick: K,
|
|
175
|
+
nodeTypes: S,
|
|
176
|
+
fitView: !0,
|
|
177
|
+
fitViewOptions: { padding: .2 },
|
|
178
|
+
minZoom: .2,
|
|
179
|
+
maxZoom: 2,
|
|
180
|
+
panOnDrag: !0,
|
|
181
|
+
proOptions: { hideAttribution: !0 },
|
|
182
|
+
children: [
|
|
183
|
+
/* @__PURE__ */ f(m, {
|
|
184
|
+
variant: h.Dots,
|
|
185
|
+
gap: 20,
|
|
186
|
+
size: 1,
|
|
187
|
+
className: "!fill-text-tertiary/10"
|
|
188
|
+
}),
|
|
189
|
+
/* @__PURE__ */ f(g, {
|
|
190
|
+
showInteractive: !1,
|
|
191
|
+
style: {
|
|
192
|
+
background: "var(--color-bg-primary)",
|
|
193
|
+
border: "1px solid var(--color-border-default)",
|
|
194
|
+
borderRadius: 8,
|
|
195
|
+
boxShadow: "0 1px 4px var(--color-border-default)"
|
|
196
|
+
},
|
|
197
|
+
className: "[&_button]:!bg-[var(--color-bg-primary)] [&_button]:!border-[var(--color-border-default)] [&_button]:!fill-[var(--color-text-secondary)] [&_button:hover]:!bg-[var(--color-bg-sunken)]"
|
|
198
|
+
}),
|
|
199
|
+
/* @__PURE__ */ f(v, {
|
|
200
|
+
zoomable: !0,
|
|
201
|
+
pannable: !0,
|
|
202
|
+
style: {
|
|
203
|
+
height: 80,
|
|
204
|
+
width: 120,
|
|
205
|
+
background: "var(--color-bg-primary)",
|
|
206
|
+
border: "1px solid var(--color-border-default)",
|
|
207
|
+
borderRadius: 8
|
|
208
|
+
},
|
|
209
|
+
maskColor: "var(--color-bg-default)"
|
|
210
|
+
})
|
|
211
|
+
]
|
|
212
|
+
})
|
|
213
|
+
}),
|
|
214
|
+
V && /* @__PURE__ */ f(r, {
|
|
215
|
+
connection: V,
|
|
216
|
+
availablePermissions: C,
|
|
217
|
+
availableScopes: w,
|
|
218
|
+
onSave: q,
|
|
219
|
+
onClose: () => H(null)
|
|
220
|
+
}),
|
|
221
|
+
U && /* @__PURE__ */ p("div", {
|
|
222
|
+
"data-testid": "save-toast",
|
|
223
|
+
className: "fixed bottom-4 right-4 z-[200] flex items-center gap-2 bg-bg-elevated border border-border-default rounded-lg shadow-lg px-4 py-2.5 text-sm",
|
|
224
|
+
children: [/* @__PURE__ */ f(u, {
|
|
225
|
+
size: 16,
|
|
226
|
+
className: "text-status-success-text flex-shrink-0"
|
|
227
|
+
}), /* @__PURE__ */ f("span", {
|
|
228
|
+
className: "text-text-primary",
|
|
229
|
+
children: D("vibecontrols.graph.permissionsSaved", "Permissions saved")
|
|
230
|
+
})]
|
|
231
|
+
})
|
|
232
|
+
] });
|
|
233
|
+
}
|
|
234
|
+
//#endregion
|
|
235
|
+
export { P as AgentGraphView };
|
|
236
|
+
|
|
237
|
+
//# sourceMappingURL=AgentGraphView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentGraphView.js","names":[],"sources":["../../../src/components/graph/AgentGraphView.tsx"],"sourcesContent":["/**\n * Agent Graph — React Flow visualization of targets and agent connections.\n *\n * Targets render as group nodes (sub-flows). Agents render as child nodes\n * inside their target. Connections render as directed edges.\n * Click edge → edit RBAC permissions/scopes.\n */\n\nimport { useCallback, useMemo, useState, useEffect, useLayoutEffect, useRef } from 'react';\nimport { CheckCircle } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport {\n ReactFlow,\n Background,\n Controls,\n MiniMap,\n useNodesState,\n useEdgesState,\n type Node,\n type Edge,\n type NodeTypes,\n MarkerType,\n BackgroundVariant,\n} from '@xyflow/react';\nimport '@xyflow/react/dist/style.css';\nimport { TargetNode } from './TargetNode';\nimport { AgentNode } from './AgentNode';\nimport { ConnectionPermissionsDialog } from './ConnectionPermissionsDialog';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface GraphTarget {\n id: string;\n name: string;\n type: string;\n status: string;\n host?: string | null;\n agents: Array<{\n id: string;\n name: string;\n version: string;\n isActive: boolean;\n }>;\n}\n\ninterface GraphConnection {\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\ninterface AgentGraphViewProps {\n targets: GraphTarget[];\n connections: GraphConnection[];\n onUpdatePermissions?: (connectionId: string, permissions: string[], scopes: string[]) => void;\n availablePermissions?: string[];\n availableScopes?: string[];\n onNodeClick?: (nodeType: 'target' | 'agent', id: string) => void;\n fullHeight?: boolean;\n}\n\ninterface InteractiveNodeData {\n nodeType?: 'target' | 'agent';\n entityId?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Custom node types\n// ---------------------------------------------------------------------------\n\nconst nodeTypes: NodeTypes = {\n targetNode: TargetNode,\n agentNode: AgentNode,\n};\n\n// ---------------------------------------------------------------------------\n// Layout — bounding boxes expand to fit agents\n// ---------------------------------------------------------------------------\n\nconst TARGET_WIDTH = 280;\nconst TARGET_HEADER_HEIGHT = 100; // Must clear: p-3(12) + badge(22) + mb(4) + name(20) + host(16) + count(18) + gap(8)\nconst AGENT_NODE_HEIGHT = 48;\nconst AGENT_GAP = 8;\nconst AGENT_MARGIN_X = 16;\nconst TARGET_PADDING_BOTTOM = 16;\nconst TARGET_GAP_X = 100;\nconst TARGET_GAP_Y = 40;\n\nfunction getTargetsPerRow(width: number): number {\n // These thresholds are container-width based and derived from the graph's\n // actual target-card geometry so each layout bucket fits without overflow.\n if (width >= TARGET_WIDTH * 4 + TARGET_GAP_X * 3) return 4;\n if (width >= TARGET_WIDTH * 3 + TARGET_GAP_X * 2) return 3;\n if (width >= TARGET_WIDTH * 2 + TARGET_GAP_X) return 2;\n return 1;\n}\n\nfunction computeTargetHeight(target: GraphTarget): number {\n const agentSlots = Math.max(target.agents.length, 1);\n return (\n TARGET_HEADER_HEIGHT + agentSlots * (AGENT_NODE_HEIGHT + AGENT_GAP) + TARGET_PADDING_BOTTOM\n );\n}\n\nfunction buildGraphElements(\n targets: GraphTarget[],\n connections: GraphConnection[],\n targetsPerRow: number,\n onNodeClick?: (nodeType: 'target' | 'agent', id: string) => void\n): { nodes: Node[]; edges: Edge[] } {\n const nodes: Node[] = [];\n const edges: Edge[] = [];\n\n // Pre-compute per-row max heights for accurate vertical positioning\n const rowCount = Math.ceil(targets.length / targetsPerRow);\n const rowMaxHeights = Array.from({ length: rowCount }, (_, rowIdx) =>\n targets\n .slice(rowIdx * targetsPerRow, (rowIdx + 1) * targetsPerRow)\n .reduce((max, t) => Math.max(max, computeTargetHeight(t)), 0)\n );\n const rowYOffsets = rowMaxHeights.reduce<number[]>((acc, h, i) => {\n acc.push(i === 0 ? 0 : acc[i - 1] + rowMaxHeights[i - 1] + TARGET_GAP_Y);\n return acc;\n }, []);\n\n targets.forEach((target, idx) => {\n const col = idx % targetsPerRow;\n const row = Math.floor(idx / targetsPerRow);\n\n // Calculate target height based on actual number of agents\n const targetHeight = computeTargetHeight(target);\n\n const x = col * (TARGET_WIDTH + TARGET_GAP_X);\n const y = rowYOffsets[row];\n\n // Target group node\n nodes.push({\n id: `target-${target.id}`,\n type: 'targetNode',\n position: { x, y },\n data: {\n entityId: target.id,\n name: target.name,\n nodeType: 'target',\n type: target.type,\n status: target.status,\n host: target.host,\n agentCount: target.agents.length,\n onActivate: onNodeClick ? () => onNodeClick('target', target.id) : undefined,\n },\n className: onNodeClick ? 'cursor-pointer' : undefined,\n style: {\n width: TARGET_WIDTH,\n height: targetHeight,\n },\n });\n\n // Agent child nodes\n target.agents.forEach((agent, agentIdx) => {\n nodes.push({\n id: `agent-${agent.id}`,\n type: 'agentNode',\n position: {\n x: AGENT_MARGIN_X,\n y: TARGET_HEADER_HEIGHT + agentIdx * (AGENT_NODE_HEIGHT + AGENT_GAP),\n },\n parentId: `target-${target.id}`,\n extent: 'parent' as const,\n data: {\n entityId: agent.id,\n name: agent.name,\n nodeType: 'agent',\n version: agent.version,\n isActive: agent.isActive,\n onActivate: onNodeClick ? () => onNodeClick('agent', agent.id) : undefined,\n },\n className: onNodeClick ? 'cursor-pointer' : undefined,\n style: { width: TARGET_WIDTH - AGENT_MARGIN_X * 2 },\n });\n });\n\n // Empty placeholder if no agents\n if (target.agents.length === 0) {\n nodes.push({\n id: `empty-${target.id}`,\n type: 'agentNode',\n position: {\n x: AGENT_MARGIN_X,\n y: TARGET_HEADER_HEIGHT,\n },\n parentId: `target-${target.id}`,\n extent: 'parent' as const,\n data: { name: 'No agent installed', version: '', isActive: false, isEmpty: true },\n style: { width: TARGET_WIDTH - AGENT_MARGIN_X * 2 },\n });\n }\n });\n\n // Edges\n connections.forEach((conn) => {\n const sourceNodeId = `agent-${conn.sourceAgent.id}`;\n const targetNodeId = `target-${conn.target.id}`;\n if (!nodes.some((n) => n.id === sourceNodeId) || !nodes.some((n) => n.id === targetNodeId))\n return;\n\n const isConnected = conn.status === 'connected';\n edges.push({\n id: `edge-${conn.id}`,\n source: sourceNodeId,\n target: targetNodeId,\n label: conn.protocol,\n data: conn as unknown as Record<string, unknown>,\n type: 'default',\n animated: isConnected,\n markerEnd: { type: MarkerType.ArrowClosed },\n style: {\n stroke: isConnected ? 'var(--color-status-success-border)' : 'var(--color-border-strong)',\n strokeWidth: 2,\n },\n labelStyle: { fontSize: 10, fontWeight: 600 },\n labelBgStyle: { fill: 'transparent' },\n labelBgPadding: [4, 2] as [number, number],\n });\n });\n\n return { nodes, edges };\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function AgentGraphView({\n targets,\n connections,\n onUpdatePermissions,\n availablePermissions,\n availableScopes,\n onNodeClick,\n fullHeight,\n}: AgentGraphViewProps) {\n const tr = useTr();\n const containerRef = useRef<HTMLDivElement>(null);\n const [targetsPerRow, setTargetsPerRow] = useState(() =>\n typeof window === 'undefined' ? 3 : getTargetsPerRow(window.innerWidth)\n );\n\n useLayoutEffect(() => {\n const updateTargetsPerRow = (width: number) => {\n setTargetsPerRow((current) => {\n const next = getTargetsPerRow(width);\n return current === next ? current : next;\n });\n };\n\n const updateFromContainer = () => {\n const width = containerRef.current?.clientWidth;\n if (typeof width === 'number' && width > 0) {\n updateTargetsPerRow(width);\n }\n };\n\n updateFromContainer();\n\n const resizeObserver =\n typeof ResizeObserver !== 'undefined'\n ? new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry) updateTargetsPerRow(entry.contentRect.width);\n })\n : null;\n\n if (resizeObserver && containerRef.current) {\n resizeObserver.observe(containerRef.current);\n } else {\n window.addEventListener('resize', updateFromContainer);\n }\n\n return () => {\n if (!resizeObserver) {\n window.removeEventListener('resize', updateFromContainer);\n }\n resizeObserver?.disconnect();\n };\n }, []);\n\n const { nodes: initialNodes, edges: initialEdges } = useMemo(\n () => buildGraphElements(targets, connections, targetsPerRow, onNodeClick),\n [targets, connections, targetsPerRow, onNodeClick]\n );\n\n const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);\n const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);\n const [selectedConnection, setSelectedConnection] = useState<GraphConnection | null>(null);\n const [permSaved, setPermSaved] = useState(false);\n\n // Re-sync nodes/edges when targets/connections change (e.g. root agent filter)\n useEffect(() => {\n const { nodes: newNodes, edges: newEdges } = buildGraphElements(\n targets,\n connections,\n targetsPerRow,\n onNodeClick\n );\n setNodes(newNodes);\n setEdges(newEdges);\n }, [targets, connections, targetsPerRow, onNodeClick, setNodes, setEdges]);\n\n const handleNodeClick = useCallback(\n (_event: React.MouseEvent, node: Node) => {\n if (!onNodeClick) return;\n\n const { entityId, nodeType } = (node.data ?? {}) as InteractiveNodeData;\n if (!entityId || !nodeType) return;\n\n onNodeClick(nodeType, entityId);\n },\n [onNodeClick]\n );\n\n const handleEdgeClick = useCallback(\n (_event: React.MouseEvent, edge: Edge) => {\n const conn = connections.find((c) => `edge-${c.id}` === edge.id);\n if (conn) setSelectedConnection(conn);\n },\n [connections]\n );\n\n const handleSavePermissions = useCallback(\n (permissions: string[], scopes: string[]) => {\n if (selectedConnection && onUpdatePermissions) {\n onUpdatePermissions(selectedConnection.id, permissions, scopes);\n }\n setSelectedConnection(null);\n setPermSaved(true);\n setTimeout(() => setPermSaved(false), 3000);\n },\n [selectedConnection, onUpdatePermissions]\n );\n\n const height = fullHeight ? '100%' : '500px';\n\n return (\n <>\n <div\n ref={containerRef}\n className=\"w-full rounded-lg border border-border-default overflow-hidden bg-bg-secondary\"\n style={{ height }}\n >\n <ReactFlow\n nodes={nodes}\n edges={edges}\n nodesDraggable={false}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n nodeTypes={nodeTypes}\n fitView\n fitViewOptions={{ padding: 0.2 }}\n minZoom={0.2}\n maxZoom={2}\n panOnDrag={true}\n proOptions={{ hideAttribution: true }}\n >\n <Background\n variant={BackgroundVariant.Dots}\n gap={20}\n size={1}\n className=\"!fill-text-tertiary/10\"\n />\n <Controls\n showInteractive={false}\n style={{\n background: 'var(--color-bg-primary)',\n border: '1px solid var(--color-border-default)',\n borderRadius: 8,\n boxShadow: '0 1px 4px var(--color-border-default)',\n }}\n className=\"[&_button]:!bg-[var(--color-bg-primary)] [&_button]:!border-[var(--color-border-default)] [&_button]:!fill-[var(--color-text-secondary)] [&_button:hover]:!bg-[var(--color-bg-sunken)]\"\n />\n <MiniMap\n zoomable\n pannable\n style={{\n height: 80,\n width: 120,\n background: 'var(--color-bg-primary)',\n border: '1px solid var(--color-border-default)',\n borderRadius: 8,\n }}\n maskColor=\"var(--color-bg-default)\"\n />\n </ReactFlow>\n </div>\n\n {selectedConnection && (\n <ConnectionPermissionsDialog\n connection={selectedConnection}\n availablePermissions={availablePermissions}\n availableScopes={availableScopes}\n onSave={handleSavePermissions}\n onClose={() => setSelectedConnection(null)}\n />\n )}\n\n {permSaved && (\n <div\n data-testid=\"save-toast\"\n className=\"fixed bottom-4 right-4 z-[200] flex items-center gap-2 bg-bg-elevated border border-border-default rounded-lg shadow-lg px-4 py-2.5 text-sm\"\n >\n <CheckCircle size={16} className=\"text-status-success-text flex-shrink-0\" />\n <span className=\"text-text-primary\">\n {tr('vibecontrols.graph.permissionsSaved', 'Permissions saved')}\n </span>\n </div>\n )}\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
|
+
import { memo as t } from "react";
|
|
3
|
+
import { Bot as n } from "lucide-react";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
import { Handle as a, Position as o } from "@xyflow/react";
|
|
6
|
+
//#region src/components/graph/AgentNode.tsx
|
|
7
|
+
function s({ data: t }) {
|
|
8
|
+
let s = e(), c = t;
|
|
9
|
+
return c.isEmpty ? /* @__PURE__ */ r("div", {
|
|
10
|
+
className: "rounded-lg border border-dashed border-border-default p-2 text-center",
|
|
11
|
+
children: /* @__PURE__ */ r("span", {
|
|
12
|
+
className: "text-[10px] italic text-text-tertiary",
|
|
13
|
+
children: s("vibecontrols.graph.noAgentInstalled", "No agent installed")
|
|
14
|
+
})
|
|
15
|
+
}) : /* @__PURE__ */ i("div", {
|
|
16
|
+
className: "rounded-lg border border-border-default bg-bg-surface shadow-sm p-2 flex items-center gap-2 hover:shadow-md transition-shadow",
|
|
17
|
+
role: c.onActivate ? "button" : void 0,
|
|
18
|
+
tabIndex: c.onActivate ? 0 : void 0,
|
|
19
|
+
"aria-label": c.onActivate ? `Navigate to agent ${c.name}` : void 0,
|
|
20
|
+
onKeyDown: (e) => {
|
|
21
|
+
c.onActivate && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), c.onActivate());
|
|
22
|
+
},
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ r(a, {
|
|
25
|
+
type: "source",
|
|
26
|
+
position: o.Right,
|
|
27
|
+
className: "!bg-action-primary-bg !w-2 !h-2 !border-0"
|
|
28
|
+
}),
|
|
29
|
+
/* @__PURE__ */ r(n, {
|
|
30
|
+
size: 14,
|
|
31
|
+
className: "text-action-primary-bg shrink-0"
|
|
32
|
+
}),
|
|
33
|
+
/* @__PURE__ */ i("div", {
|
|
34
|
+
className: "min-w-0 flex-1",
|
|
35
|
+
children: [/* @__PURE__ */ r("div", {
|
|
36
|
+
className: "text-xs font-medium text-text-primary truncate",
|
|
37
|
+
children: c.name
|
|
38
|
+
}), c.version && /* @__PURE__ */ i("div", {
|
|
39
|
+
className: "text-[10px] text-text-tertiary",
|
|
40
|
+
children: ["v", c.version]
|
|
41
|
+
})]
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ r("span", {
|
|
44
|
+
className: `size-2 rounded-full shrink-0 ${c.isActive ? "bg-status-success-bg" : "bg-bg-disabled"}`,
|
|
45
|
+
title: c.isActive ? "Active" : "Offline"
|
|
46
|
+
})
|
|
47
|
+
]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
var c = t(s);
|
|
51
|
+
//#endregion
|
|
52
|
+
export { c as AgentNode };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=AgentNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentNode.js","names":[],"sources":["../../../src/components/graph/AgentNode.tsx"],"sourcesContent":["/**\n * AgentNode — React Flow custom node for an Agent (child inside a Target group).\n * Uses design tokens for seamless light/dark mode.\n */\n\nimport { memo } from 'react';\nimport { Handle, Position, type NodeProps } from '@xyflow/react';\nimport { Bot } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\nfunction AgentNodeComponent({ data }: NodeProps) {\n const tr = useTr();\n const d = data as {\n name: string;\n version: string;\n isActive: boolean;\n isEmpty?: boolean;\n onActivate?: () => void;\n };\n\n if (d.isEmpty) {\n return (\n <div className=\"rounded-lg border border-dashed border-border-default p-2 text-center\">\n <span className=\"text-[10px] italic text-text-tertiary\">\n {tr('vibecontrols.graph.noAgentInstalled', 'No agent installed')}\n </span>\n </div>\n );\n }\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!d.onActivate) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n d.onActivate();\n }\n };\n\n return (\n <div\n className=\"rounded-lg border border-border-default bg-bg-surface shadow-sm p-2 flex items-center gap-2 hover:shadow-md transition-shadow\"\n role={d.onActivate ? 'button' : undefined}\n tabIndex={d.onActivate ? 0 : undefined}\n aria-label={d.onActivate ? `Navigate to agent ${d.name}` : undefined}\n onKeyDown={handleKeyDown}\n >\n <Handle\n type=\"source\"\n position={Position.Right}\n className=\"!bg-action-primary-bg !w-2 !h-2 !border-0\"\n />\n\n <Bot size={14} className=\"text-action-primary-bg shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-xs font-medium text-text-primary truncate\">{d.name}</div>\n {d.version && <div className=\"text-[10px] text-text-tertiary\">v{d.version}</div>}\n </div>\n <span\n className={`size-2 rounded-full shrink-0 ${d.isActive ? 'bg-status-success-bg' : 'bg-bg-disabled'}`}\n title={d.isActive ? 'Active' : 'Offline'}\n />\n </div>\n );\n}\n\nexport const AgentNode = memo(AgentNodeComponent);\n"],"mappings":";;;;;;AAUA,SAAS,EAAmB,EAAE,WAAmB;CAC/C,IAAM,IAAK,GAAO,EACZ,IAAI;AA0BV,QAlBI,EAAE,UAEF,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,QAAD;GAAM,WAAU;aACb,EAAG,uCAAuC,qBAAqB;GAC3D,CAAA;EACH,CAAA,GAaR,kBAAC,OAAD;EACE,WAAU;EACV,MAAM,EAAE,aAAa,WAAW,KAAA;EAChC,UAAU,EAAE,aAAa,IAAI,KAAA;EAC7B,cAAY,EAAE,aAAa,qBAAqB,EAAE,SAAS,KAAA;EAC3D,YAdmB,MAA+C;AAC/D,KAAE,eACH,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,gBAAgB,EACtB,EAAE,YAAY;;YAKhB;GAOE,kBAAC,GAAD;IACE,MAAK;IACL,UAAU,EAAS;IACnB,WAAU;IACV,CAAA;GAEF,kBAAC,GAAD;IAAK,MAAM;IAAI,WAAU;IAAoC,CAAA;GAC7D,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAkD,EAAE;KAAW,CAAA,EAC7E,EAAE,WAAW,kBAAC,OAAD;KAAK,WAAU;eAAf,CAAgD,KAAE,EAAE,QAAc;OAC5E;;GACN,kBAAC,QAAD;IACE,WAAW,gCAAgC,EAAE,WAAW,yBAAyB;IACjF,OAAO,EAAE,WAAW,WAAW;IAC/B,CAAA;GACE;;;AAIV,IAAa,IAAY,EAAK,EAAmB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
|
+
import { memo as t } from "react";
|
|
3
|
+
import { Laptop as n, Monitor as r, ScreenShare as i, Server as a } from "lucide-react";
|
|
4
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
|
+
import { Handle as c, Position as l } from "@xyflow/react";
|
|
6
|
+
//#region src/components/graph/TargetNode.tsx
|
|
7
|
+
var u = {
|
|
8
|
+
DIRECT: {
|
|
9
|
+
icon: n,
|
|
10
|
+
badge: "bg-accent-blue-subtle text-accent-blue",
|
|
11
|
+
border: "border-accent-blue/20 bg-accent-blue-subtle/50"
|
|
12
|
+
},
|
|
13
|
+
SSH: {
|
|
14
|
+
icon: a,
|
|
15
|
+
badge: "bg-status-success-bg-subtle text-status-success-text",
|
|
16
|
+
border: "border-status-success-border/20 bg-status-success-bg-subtle/50"
|
|
17
|
+
},
|
|
18
|
+
RDP: {
|
|
19
|
+
icon: r,
|
|
20
|
+
badge: "bg-status-warning-bg-subtle text-status-warning-text",
|
|
21
|
+
border: "border-status-warning-border/20 bg-status-warning-bg-subtle/50"
|
|
22
|
+
},
|
|
23
|
+
VNC: {
|
|
24
|
+
icon: i,
|
|
25
|
+
badge: "bg-accent-purple-subtle text-accent-purple",
|
|
26
|
+
border: "border-accent-purple/20 bg-accent-purple-subtle/50"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
function d({ data: t }) {
|
|
30
|
+
e();
|
|
31
|
+
let n = t, r = u[n.type] || u.DIRECT, i = r.icon, a = n.status === "connected";
|
|
32
|
+
return /* @__PURE__ */ s("div", {
|
|
33
|
+
className: `rounded-xl border-2 p-3 ${r.border} h-full w-full`,
|
|
34
|
+
role: n.onActivate ? "button" : void 0,
|
|
35
|
+
tabIndex: n.onActivate ? 0 : void 0,
|
|
36
|
+
"aria-label": n.onActivate ? `Navigate to target ${n.name}` : void 0,
|
|
37
|
+
onKeyDown: (e) => {
|
|
38
|
+
n.onActivate && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), n.onActivate());
|
|
39
|
+
},
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ o(c, {
|
|
42
|
+
type: "target",
|
|
43
|
+
position: l.Left,
|
|
44
|
+
className: "!bg-text-tertiary !w-2 !h-2 !border-0"
|
|
45
|
+
}),
|
|
46
|
+
/* @__PURE__ */ s("div", {
|
|
47
|
+
className: "flex items-center gap-2 mb-1",
|
|
48
|
+
children: [/* @__PURE__ */ s("span", {
|
|
49
|
+
className: `inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider rounded ${r.badge}`,
|
|
50
|
+
children: [/* @__PURE__ */ o(i, { size: 10 }), n.type]
|
|
51
|
+
}), /* @__PURE__ */ o("span", { className: `ml-auto size-2 rounded-full ${a ? "bg-status-success-bg" : "bg-bg-disabled"}` })]
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ o("div", {
|
|
54
|
+
className: "font-semibold text-sm text-text-primary truncate",
|
|
55
|
+
children: n.name
|
|
56
|
+
}),
|
|
57
|
+
n.host && /* @__PURE__ */ o("div", {
|
|
58
|
+
className: "text-xs text-text-tertiary truncate",
|
|
59
|
+
children: n.host
|
|
60
|
+
}),
|
|
61
|
+
/* @__PURE__ */ s("div", {
|
|
62
|
+
className: "text-[10px] text-text-tertiary mt-1",
|
|
63
|
+
children: [
|
|
64
|
+
n.agentCount,
|
|
65
|
+
" agent",
|
|
66
|
+
n.agentCount === 1 ? "" : "s"
|
|
67
|
+
]
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
var f = t(d);
|
|
73
|
+
//#endregion
|
|
74
|
+
export { f as TargetNode };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=TargetNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TargetNode.js","names":[],"sources":["../../../src/components/graph/TargetNode.tsx"],"sourcesContent":["/**\n * TargetNode — React Flow custom node for a Target (group/sub-flow container).\n * Uses design tokens for seamless light/dark mode.\n */\n\nimport { memo } from 'react';\nimport { Handle, Position, type NodeProps } from '@xyflow/react';\nimport { Server, Monitor, ScreenShare, Laptop } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\nconst typeConfig: Record<string, { icon: typeof Server; badge: string; border: string }> = {\n DIRECT: {\n icon: Laptop,\n badge: 'bg-accent-blue-subtle text-accent-blue',\n border: 'border-accent-blue/20 bg-accent-blue-subtle/50',\n },\n SSH: {\n icon: Server,\n badge: 'bg-status-success-bg-subtle text-status-success-text',\n border: 'border-status-success-border/20 bg-status-success-bg-subtle/50',\n },\n RDP: {\n icon: Monitor,\n badge: 'bg-status-warning-bg-subtle text-status-warning-text',\n border: 'border-status-warning-border/20 bg-status-warning-bg-subtle/50',\n },\n VNC: {\n icon: ScreenShare,\n badge: 'bg-accent-purple-subtle text-accent-purple',\n border: 'border-accent-purple/20 bg-accent-purple-subtle/50',\n },\n};\n\nfunction TargetNodeComponent({ data }: NodeProps) {\n const tr = useTr();\n const d = data as {\n name: string;\n type: string;\n status: string;\n host?: string;\n agentCount: number;\n onActivate?: () => void;\n };\n const config = typeConfig[d.type] || typeConfig.DIRECT;\n const Icon = config.icon;\n const isConnected = d.status === 'connected';\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!d.onActivate) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n d.onActivate();\n }\n };\n\n return (\n <div\n className={`rounded-xl border-2 p-3 ${config.border} h-full w-full`}\n role={d.onActivate ? 'button' : undefined}\n tabIndex={d.onActivate ? 0 : undefined}\n aria-label={d.onActivate ? `Navigate to target ${d.name}` : undefined}\n onKeyDown={handleKeyDown}\n >\n <Handle\n type=\"target\"\n position={Position.Left}\n className=\"!bg-text-tertiary !w-2 !h-2 !border-0\"\n />\n\n <div className=\"flex items-center gap-2 mb-1\">\n <span\n className={`inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wider rounded ${config.badge}`}\n >\n <Icon size={10} />\n {d.type}\n </span>\n <span\n className={`ml-auto size-2 rounded-full ${isConnected ? 'bg-status-success-bg' : 'bg-bg-disabled'}`}\n />\n </div>\n <div className=\"font-semibold text-sm text-text-primary truncate\">{d.name}</div>\n {d.host && <div className=\"text-xs text-text-tertiary truncate\">{d.host}</div>}\n <div className=\"text-[10px] text-text-tertiary mt-1\">\n {d.agentCount} agent{d.agentCount !== 1 ? 's' : ''}\n </div>\n </div>\n );\n}\n\nexport const TargetNode = memo(TargetNodeComponent);\n"],"mappings":";;;;;;AAUA,IAAM,IAAqF;CACzF,QAAQ;EACN,MAAM;EACN,OAAO;EACP,QAAQ;EACT;CACD,KAAK;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACT;CACD,KAAK;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACT;CACD,KAAK;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACT;CACF;AAED,SAAS,EAAoB,EAAE,WAAmB;AACrC,IAAO;CAClB,IAAM,IAAI,GAQJ,IAAS,EAAW,EAAE,SAAS,EAAW,QAC1C,IAAO,EAAO,MACd,IAAc,EAAE,WAAW;AAUjC,QACE,kBAAC,OAAD;EACE,WAAW,2BAA2B,EAAO,OAAO;EACpD,MAAM,EAAE,aAAa,WAAW,KAAA;EAChC,UAAU,EAAE,aAAa,IAAI,KAAA;EAC7B,cAAY,EAAE,aAAa,sBAAsB,EAAE,SAAS,KAAA;EAC5D,YAdmB,MAA+C;AAC/D,KAAE,eACH,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,gBAAgB,EACtB,EAAE,YAAY;;YAKhB;GAOE,kBAAC,GAAD;IACE,MAAK;IACL,UAAU,EAAS;IACnB,WAAU;IACV,CAAA;GAEF,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KACE,WAAW,uGAAuG,EAAO;eAD3H,CAGE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAE,KACE;QACP,kBAAC,QAAD,EACE,WAAW,+BAA+B,IAAc,yBAAyB,oBACjF,CAAA,CACE;;GACN,kBAAC,OAAD;IAAK,WAAU;cAAoD,EAAE;IAAW,CAAA;GAC/E,EAAE,QAAQ,kBAAC,OAAD;IAAK,WAAU;cAAuC,EAAE;IAAW,CAAA;GAC9E,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,EAAE;KAAW;KAAO,EAAE,eAAe,IAAU,KAAN;KACtC;;GACF;;;AAIV,IAAa,IAAa,EAAK,EAAoB"}
|