@burdenoff/microfe-vibecontrols 2026.601.9 → 2026.601.10

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.
Files changed (267) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +2 -5
  2. package/dist/components/graph/AgentGraphView.js +237 -0
  3. package/dist/components/graph/AgentGraphView.js.map +1 -0
  4. package/dist/components/graph/AgentNode.js +54 -0
  5. package/dist/components/graph/AgentNode.js.map +1 -0
  6. package/dist/components/graph/TargetNode.js +76 -0
  7. package/dist/components/graph/TargetNode.js.map +1 -0
  8. package/dist/generated/wspace-operations.js +1644 -1853
  9. package/dist/generated/wspace-operations.js.map +1 -1
  10. package/dist/generated/wspace-types.js +12 -14
  11. package/dist/generated/wspace-types.js.map +1 -1
  12. package/dist/index.js +10 -10
  13. package/dist/pages/AgentGraphPage.js +118 -251
  14. package/dist/pages/AgentGraphPage.js.map +1 -1
  15. package/package.json +1 -3
  16. package/dist/components/graph/MeshAgentNode.js +0 -74
  17. package/dist/components/graph/MeshAgentNode.js.map +0 -1
  18. package/dist/components/graph/MeshDeployWizard.js +0 -393
  19. package/dist/components/graph/MeshDeployWizard.js.map +0 -1
  20. package/dist/components/graph/MeshGraphView.js +0 -190
  21. package/dist/components/graph/MeshGraphView.js.map +0 -1
  22. package/dist/components/graph/MeshNodeActions.js +0 -70
  23. package/dist/components/graph/MeshNodeActions.js.map +0 -1
  24. package/dist/components/graph/MeshRequestPanel.js +0 -240
  25. package/dist/components/graph/MeshRequestPanel.js.map +0 -1
  26. package/dist/components/graph/meshTypes.js +0 -11
  27. package/dist/components/graph/meshTypes.js.map +0 -1
  28. package/dist/components/graph/nodeIcons.js +0 -31
  29. package/dist/components/graph/nodeIcons.js.map +0 -1
  30. package/dist/node_modules/dagre/index.js +0 -24
  31. package/dist/node_modules/dagre/index.js.map +0 -1
  32. package/dist/node_modules/dagre/lib/acyclic.js +0 -47
  33. package/dist/node_modules/dagre/lib/acyclic.js.map +0 -1
  34. package/dist/node_modules/dagre/lib/add-border-segments.js +0 -32
  35. package/dist/node_modules/dagre/lib/add-border-segments.js.map +0 -1
  36. package/dist/node_modules/dagre/lib/coordinate-system.js +0 -57
  37. package/dist/node_modules/dagre/lib/coordinate-system.js.map +0 -1
  38. package/dist/node_modules/dagre/lib/data/list.js +0 -30
  39. package/dist/node_modules/dagre/lib/data/list.js.map +0 -1
  40. package/dist/node_modules/dagre/lib/debug.js +0 -31
  41. package/dist/node_modules/dagre/lib/debug.js.map +0 -1
  42. package/dist/node_modules/dagre/lib/graphlib.js +0 -15
  43. package/dist/node_modules/dagre/lib/graphlib.js.map +0 -1
  44. package/dist/node_modules/dagre/lib/greedy-fas.js +0 -74
  45. package/dist/node_modules/dagre/lib/greedy-fas.js.map +0 -1
  46. package/dist/node_modules/dagre/lib/layout.js +0 -305
  47. package/dist/node_modules/dagre/lib/layout.js.map +0 -1
  48. package/dist/node_modules/dagre/lib/lodash.js +0 -67
  49. package/dist/node_modules/dagre/lib/lodash.js.map +0 -1
  50. package/dist/node_modules/dagre/lib/nesting-graph.js +0 -76
  51. package/dist/node_modules/dagre/lib/nesting-graph.js.map +0 -1
  52. package/dist/node_modules/dagre/lib/normalize.js +0 -45
  53. package/dist/node_modules/dagre/lib/normalize.js.map +0 -1
  54. package/dist/node_modules/dagre/lib/order/add-subgraph-constraints.js +0 -24
  55. package/dist/node_modules/dagre/lib/order/add-subgraph-constraints.js.map +0 -1
  56. package/dist/node_modules/dagre/lib/order/barycenter.js +0 -34
  57. package/dist/node_modules/dagre/lib/order/barycenter.js.map +0 -1
  58. package/dist/node_modules/dagre/lib/order/build-layer-graph.js +0 -32
  59. package/dist/node_modules/dagre/lib/order/build-layer-graph.js.map +0 -1
  60. package/dist/node_modules/dagre/lib/order/cross-count.js +0 -39
  61. package/dist/node_modules/dagre/lib/order/cross-count.js.map +0 -1
  62. package/dist/node_modules/dagre/lib/order/index.js +0 -50
  63. package/dist/node_modules/dagre/lib/order/index.js.map +0 -1
  64. package/dist/node_modules/dagre/lib/order/init-order.js +0 -28
  65. package/dist/node_modules/dagre/lib/order/init-order.js.map +0 -1
  66. package/dist/node_modules/dagre/lib/order/resolve-conflicts.js +0 -61
  67. package/dist/node_modules/dagre/lib/order/resolve-conflicts.js.map +0 -1
  68. package/dist/node_modules/dagre/lib/order/sort-subgraph.js +0 -50
  69. package/dist/node_modules/dagre/lib/order/sort-subgraph.js.map +0 -1
  70. package/dist/node_modules/dagre/lib/order/sort.js +0 -34
  71. package/dist/node_modules/dagre/lib/order/sort.js.map +0 -1
  72. package/dist/node_modules/dagre/lib/parent-dummy-chains.js +0 -50
  73. package/dist/node_modules/dagre/lib/parent-dummy-chains.js.map +0 -1
  74. package/dist/node_modules/dagre/lib/position/bk.js +0 -212
  75. package/dist/node_modules/dagre/lib/position/bk.js.map +0 -1
  76. package/dist/node_modules/dagre/lib/position/index.js +0 -30
  77. package/dist/node_modules/dagre/lib/position/index.js.map +0 -1
  78. package/dist/node_modules/dagre/lib/rank/feasible-tree.js +0 -39
  79. package/dist/node_modules/dagre/lib/rank/feasible-tree.js.map +0 -1
  80. package/dist/node_modules/dagre/lib/rank/index.js +0 -35
  81. package/dist/node_modules/dagre/lib/rank/index.js.map +0 -1
  82. package/dist/node_modules/dagre/lib/rank/network-simplex.js +0 -90
  83. package/dist/node_modules/dagre/lib/rank/network-simplex.js.map +0 -1
  84. package/dist/node_modules/dagre/lib/rank/util.js +0 -31
  85. package/dist/node_modules/dagre/lib/rank/util.js.map +0 -1
  86. package/dist/node_modules/dagre/lib/util.js +0 -151
  87. package/dist/node_modules/dagre/lib/util.js.map +0 -1
  88. package/dist/node_modules/dagre/lib/version.js +0 -10
  89. package/dist/node_modules/dagre/lib/version.js.map +0 -1
  90. package/dist/node_modules/graphlib/index.js +0 -19
  91. package/dist/node_modules/graphlib/index.js.map +0 -1
  92. package/dist/node_modules/graphlib/lib/alg/components.js +0 -21
  93. package/dist/node_modules/graphlib/lib/alg/components.js.map +0 -1
  94. package/dist/node_modules/graphlib/lib/alg/dfs.js +0 -25
  95. package/dist/node_modules/graphlib/lib/alg/dfs.js.map +0 -1
  96. package/dist/node_modules/graphlib/lib/alg/dijkstra-all.js +0 -18
  97. package/dist/node_modules/graphlib/lib/alg/dijkstra-all.js.map +0 -1
  98. package/dist/node_modules/graphlib/lib/alg/dijkstra.js +0 -31
  99. package/dist/node_modules/graphlib/lib/alg/dijkstra.js.map +0 -1
  100. package/dist/node_modules/graphlib/lib/alg/find-cycles.js +0 -18
  101. package/dist/node_modules/graphlib/lib/alg/find-cycles.js.map +0 -1
  102. package/dist/node_modules/graphlib/lib/alg/floyd-warshall.js +0 -41
  103. package/dist/node_modules/graphlib/lib/alg/floyd-warshall.js.map +0 -1
  104. package/dist/node_modules/graphlib/lib/alg/index.js +0 -33
  105. package/dist/node_modules/graphlib/lib/alg/index.js.map +0 -1
  106. package/dist/node_modules/graphlib/lib/alg/is-acyclic.js +0 -21
  107. package/dist/node_modules/graphlib/lib/alg/is-acyclic.js.map +0 -1
  108. package/dist/node_modules/graphlib/lib/alg/postorder.js +0 -15
  109. package/dist/node_modules/graphlib/lib/alg/postorder.js.map +0 -1
  110. package/dist/node_modules/graphlib/lib/alg/preorder.js +0 -15
  111. package/dist/node_modules/graphlib/lib/alg/preorder.js.map +0 -1
  112. package/dist/node_modules/graphlib/lib/alg/prim.js +0 -35
  113. package/dist/node_modules/graphlib/lib/alg/prim.js.map +0 -1
  114. package/dist/node_modules/graphlib/lib/alg/tarjan.js +0 -34
  115. package/dist/node_modules/graphlib/lib/alg/tarjan.js.map +0 -1
  116. package/dist/node_modules/graphlib/lib/alg/topsort.js +0 -23
  117. package/dist/node_modules/graphlib/lib/alg/topsort.js.map +0 -1
  118. package/dist/node_modules/graphlib/lib/data/priority-queue.js +0 -56
  119. package/dist/node_modules/graphlib/lib/data/priority-queue.js.map +0 -1
  120. package/dist/node_modules/graphlib/lib/graph.js +0 -196
  121. package/dist/node_modules/graphlib/lib/graph.js.map +0 -1
  122. package/dist/node_modules/graphlib/lib/index.js +0 -15
  123. package/dist/node_modules/graphlib/lib/index.js.map +0 -1
  124. package/dist/node_modules/graphlib/lib/json.js +0 -55
  125. package/dist/node_modules/graphlib/lib/json.js.map +0 -1
  126. package/dist/node_modules/graphlib/lib/lodash.js +0 -47
  127. package/dist/node_modules/graphlib/lib/lodash.js.map +0 -1
  128. package/dist/node_modules/graphlib/lib/version.js +0 -10
  129. package/dist/node_modules/graphlib/lib/version.js.map +0 -1
  130. package/dist/node_modules/lodash/_arrayEach.js +0 -14
  131. package/dist/node_modules/lodash/_arrayEach.js.map +0 -1
  132. package/dist/node_modules/lodash/_arrayReduce.js +0 -15
  133. package/dist/node_modules/lodash/_arrayReduce.js.map +0 -1
  134. package/dist/node_modules/lodash/_asciiSize.js +0 -11
  135. package/dist/node_modules/lodash/_asciiSize.js.map +0 -1
  136. package/dist/node_modules/lodash/_assignMergeValue.js +0 -16
  137. package/dist/node_modules/lodash/_assignMergeValue.js.map +0 -1
  138. package/dist/node_modules/lodash/_assignValue.js +0 -17
  139. package/dist/node_modules/lodash/_assignValue.js.map +0 -1
  140. package/dist/node_modules/lodash/_baseAssign.js +0 -16
  141. package/dist/node_modules/lodash/_baseAssign.js.map +0 -1
  142. package/dist/node_modules/lodash/_baseAssignIn.js +0 -16
  143. package/dist/node_modules/lodash/_baseAssignIn.js.map +0 -1
  144. package/dist/node_modules/lodash/_baseClone.js +0 -64
  145. package/dist/node_modules/lodash/_baseClone.js.map +0 -1
  146. package/dist/node_modules/lodash/_baseCreate.js +0 -21
  147. package/dist/node_modules/lodash/_baseCreate.js.map +0 -1
  148. package/dist/node_modules/lodash/_baseFilter.js +0 -18
  149. package/dist/node_modules/lodash/_baseFilter.js.map +0 -1
  150. package/dist/node_modules/lodash/_baseHas.js +0 -14
  151. package/dist/node_modules/lodash/_baseHas.js.map +0 -1
  152. package/dist/node_modules/lodash/_baseIsMap.js +0 -16
  153. package/dist/node_modules/lodash/_baseIsMap.js.map +0 -1
  154. package/dist/node_modules/lodash/_baseIsSet.js +0 -16
  155. package/dist/node_modules/lodash/_baseIsSet.js.map +0 -1
  156. package/dist/node_modules/lodash/_baseKeysIn.js +0 -20
  157. package/dist/node_modules/lodash/_baseKeysIn.js.map +0 -1
  158. package/dist/node_modules/lodash/_baseMerge.js +0 -27
  159. package/dist/node_modules/lodash/_baseMerge.js.map +0 -1
  160. package/dist/node_modules/lodash/_baseMergeDeep.js +0 -39
  161. package/dist/node_modules/lodash/_baseMergeDeep.js.map +0 -1
  162. package/dist/node_modules/lodash/_basePick.js +0 -18
  163. package/dist/node_modules/lodash/_basePick.js.map +0 -1
  164. package/dist/node_modules/lodash/_basePickBy.js +0 -21
  165. package/dist/node_modules/lodash/_basePickBy.js.map +0 -1
  166. package/dist/node_modules/lodash/_baseReduce.js +0 -15
  167. package/dist/node_modules/lodash/_baseReduce.js.map +0 -1
  168. package/dist/node_modules/lodash/_baseSet.js +0 -30
  169. package/dist/node_modules/lodash/_baseSet.js.map +0 -1
  170. package/dist/node_modules/lodash/_baseValues.js +0 -17
  171. package/dist/node_modules/lodash/_baseValues.js.map +0 -1
  172. package/dist/node_modules/lodash/_baseZipObject.js +0 -17
  173. package/dist/node_modules/lodash/_baseZipObject.js.map +0 -1
  174. package/dist/node_modules/lodash/_castFunction.js +0 -15
  175. package/dist/node_modules/lodash/_castFunction.js.map +0 -1
  176. package/dist/node_modules/lodash/_cloneArrayBuffer.js +0 -16
  177. package/dist/node_modules/lodash/_cloneArrayBuffer.js.map +0 -1
  178. package/dist/node_modules/lodash/_cloneBuffer.js +0 -17
  179. package/dist/node_modules/lodash/_cloneBuffer.js.map +0 -1
  180. package/dist/node_modules/lodash/_cloneDataView.js +0 -16
  181. package/dist/node_modules/lodash/_cloneDataView.js.map +0 -1
  182. package/dist/node_modules/lodash/_cloneRegExp.js +0 -15
  183. package/dist/node_modules/lodash/_cloneRegExp.js.map +0 -1
  184. package/dist/node_modules/lodash/_cloneSymbol.js +0 -15
  185. package/dist/node_modules/lodash/_cloneSymbol.js.map +0 -1
  186. package/dist/node_modules/lodash/_cloneTypedArray.js +0 -16
  187. package/dist/node_modules/lodash/_cloneTypedArray.js.map +0 -1
  188. package/dist/node_modules/lodash/_copyArray.js +0 -15
  189. package/dist/node_modules/lodash/_copyArray.js.map +0 -1
  190. package/dist/node_modules/lodash/_copyObject.js +0 -22
  191. package/dist/node_modules/lodash/_copyObject.js.map +0 -1
  192. package/dist/node_modules/lodash/_copySymbols.js +0 -16
  193. package/dist/node_modules/lodash/_copySymbols.js.map +0 -1
  194. package/dist/node_modules/lodash/_copySymbolsIn.js +0 -16
  195. package/dist/node_modules/lodash/_copySymbolsIn.js.map +0 -1
  196. package/dist/node_modules/lodash/_createAssigner.js +0 -23
  197. package/dist/node_modules/lodash/_createAssigner.js.map +0 -1
  198. package/dist/node_modules/lodash/_flatRest.js +0 -17
  199. package/dist/node_modules/lodash/_flatRest.js.map +0 -1
  200. package/dist/node_modules/lodash/_getAllKeysIn.js +0 -17
  201. package/dist/node_modules/lodash/_getAllKeysIn.js.map +0 -1
  202. package/dist/node_modules/lodash/_getSymbolsIn.js +0 -18
  203. package/dist/node_modules/lodash/_getSymbolsIn.js.map +0 -1
  204. package/dist/node_modules/lodash/_initCloneArray.js +0 -15
  205. package/dist/node_modules/lodash/_initCloneArray.js.map +0 -1
  206. package/dist/node_modules/lodash/_initCloneByTag.js +0 -40
  207. package/dist/node_modules/lodash/_initCloneByTag.js.map +0 -1
  208. package/dist/node_modules/lodash/_initCloneObject.js +0 -17
  209. package/dist/node_modules/lodash/_initCloneObject.js.map +0 -1
  210. package/dist/node_modules/lodash/_nativeKeysIn.js +0 -15
  211. package/dist/node_modules/lodash/_nativeKeysIn.js.map +0 -1
  212. package/dist/node_modules/lodash/_safeGet.js +0 -13
  213. package/dist/node_modules/lodash/_safeGet.js.map +0 -1
  214. package/dist/node_modules/lodash/_stringSize.js +0 -17
  215. package/dist/node_modules/lodash/_stringSize.js.map +0 -1
  216. package/dist/node_modules/lodash/_unicodeSize.js +0 -25
  217. package/dist/node_modules/lodash/_unicodeSize.js.map +0 -1
  218. package/dist/node_modules/lodash/clone.js +0 -15
  219. package/dist/node_modules/lodash/clone.js.map +0 -1
  220. package/dist/node_modules/lodash/cloneDeep.js +0 -15
  221. package/dist/node_modules/lodash/cloneDeep.js.map +0 -1
  222. package/dist/node_modules/lodash/defaults.js +0 -23
  223. package/dist/node_modules/lodash/defaults.js.map +0 -1
  224. package/dist/node_modules/lodash/each.js +0 -11
  225. package/dist/node_modules/lodash/each.js.map +0 -1
  226. package/dist/node_modules/lodash/filter.js +0 -18
  227. package/dist/node_modules/lodash/filter.js.map +0 -1
  228. package/dist/node_modules/lodash/flatten.js +0 -15
  229. package/dist/node_modules/lodash/flatten.js.map +0 -1
  230. package/dist/node_modules/lodash/forEach.js +0 -18
  231. package/dist/node_modules/lodash/forEach.js.map +0 -1
  232. package/dist/node_modules/lodash/forIn.js +0 -17
  233. package/dist/node_modules/lodash/forIn.js.map +0 -1
  234. package/dist/node_modules/lodash/has.js +0 -16
  235. package/dist/node_modules/lodash/has.js.map +0 -1
  236. package/dist/node_modules/lodash/isArrayLikeObject.js +0 -16
  237. package/dist/node_modules/lodash/isArrayLikeObject.js.map +0 -1
  238. package/dist/node_modules/lodash/isEmpty.js +0 -28
  239. package/dist/node_modules/lodash/isEmpty.js.map +0 -1
  240. package/dist/node_modules/lodash/isMap.js +0 -14
  241. package/dist/node_modules/lodash/isMap.js.map +0 -1
  242. package/dist/node_modules/lodash/isSet.js +0 -14
  243. package/dist/node_modules/lodash/isSet.js.map +0 -1
  244. package/dist/node_modules/lodash/isUndefined.js +0 -13
  245. package/dist/node_modules/lodash/isUndefined.js.map +0 -1
  246. package/dist/node_modules/lodash/keysIn.js +0 -17
  247. package/dist/node_modules/lodash/keysIn.js.map +0 -1
  248. package/dist/node_modules/lodash/merge.js +0 -15
  249. package/dist/node_modules/lodash/merge.js.map +0 -1
  250. package/dist/node_modules/lodash/pick.js +0 -15
  251. package/dist/node_modules/lodash/pick.js.map +0 -1
  252. package/dist/node_modules/lodash/reduce.js +0 -20
  253. package/dist/node_modules/lodash/reduce.js.map +0 -1
  254. package/dist/node_modules/lodash/size.js +0 -22
  255. package/dist/node_modules/lodash/size.js.map +0 -1
  256. package/dist/node_modules/lodash/toPlainObject.js +0 -16
  257. package/dist/node_modules/lodash/toPlainObject.js.map +0 -1
  258. package/dist/node_modules/lodash/transform.js +0 -31
  259. package/dist/node_modules/lodash/transform.js.map +0 -1
  260. package/dist/node_modules/lodash/union.js +0 -17
  261. package/dist/node_modules/lodash/union.js.map +0 -1
  262. package/dist/node_modules/lodash/uniqueId.js +0 -16
  263. package/dist/node_modules/lodash/uniqueId.js.map +0 -1
  264. package/dist/node_modules/lodash/values.js +0 -16
  265. package/dist/node_modules/lodash/values.js.map +0 -1
  266. package/dist/node_modules/lodash/zipObject.js +0 -16
  267. 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)), u = /* @__PURE__ */ ((e) => typeof require < "u" ? require : typeof Proxy < "u" ? new Proxy(e, { get: (e, t) => (typeof require < "u" ? require : e)[t] }) : e)(function(e) {
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, u as __require, l as __toESM };
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":";;;;;;;;;;AA8EA,IAAM,IAAuB;CAC3B,YAAY;CACZ,WAAW;CACZ,EAMK,IAAe,KACf,IAAuB,KACvB,IAAoB,IACpB,IAAY,GACZ,IAAiB,IACjB,IAAwB,IACxB,IAAe,KACf,IAAe;AAErB,SAAS,EAAiB,GAAuB;AAM/C,QAHI,KAAS,IAAe,IAAI,IAAe,IAAU,IACrD,KAAS,IAAe,IAAI,IAAe,IAAU,IACrD,KAAS,IAAe,IAAI,IAAqB,IAC9C;;AAGT,SAAS,EAAoB,GAA6B;AAExD,QACE,IAFiB,KAAK,IAAI,EAAO,OAAO,QAAQ,EAAE,IAEb,IAAoB,KAAa;;AAI1E,SAAS,EACP,GACA,GACA,GACA,GACkC;CAClC,IAAM,IAAgB,EAAE,EAClB,IAAgB,EAAE,EAGlB,IAAW,KAAK,KAAK,EAAQ,SAAS,EAAc,EACpD,IAAgB,MAAM,KAAK,EAAE,QAAQ,GAAU,GAAG,GAAG,MACzD,EACG,MAAM,IAAS,IAAgB,IAAS,KAAK,EAAc,CAC3D,QAAQ,GAAK,MAAM,KAAK,IAAI,GAAK,EAAoB,EAAE,CAAC,EAAE,EAAE,CAChE,EACK,IAAc,EAAc,QAAkB,GAAK,GAAG,OAC1D,EAAI,KAAK,MAAM,IAAI,IAAI,EAAI,IAAI,KAAK,EAAc,IAAI,KAAK,EAAa,EACjE,IACN,EAAE,CAAC;AAsGN,QApGA,EAAQ,SAAS,GAAQ,MAAQ;EAC/B,IAAM,IAAM,IAAM,GACZ,IAAM,KAAK,MAAM,IAAM,EAAc,EAGrC,IAAe,EAAoB,EAAO,EAE1C,IAAI,KAAO,IAAe,IAC1B,IAAI,EAAY;AAiDtB,EA9CA,EAAM,KAAK;GACT,IAAI,UAAU,EAAO;GACrB,MAAM;GACN,UAAU;IAAE;IAAG;IAAG;GAClB,MAAM;IACJ,UAAU,EAAO;IACjB,MAAM,EAAO;IACb,UAAU;IACV,MAAM,EAAO;IACb,QAAQ,EAAO;IACf,MAAM,EAAO;IACb,YAAY,EAAO,OAAO;IAC1B,YAAY,UAAoB,EAAY,UAAU,EAAO,GAAG,GAAG,KAAA;IACpE;GACD,WAAW,IAAc,mBAAmB,KAAA;GAC5C,OAAO;IACL,OAAO;IACP,QAAQ;IACT;GACF,CAAC,EAGF,EAAO,OAAO,SAAS,GAAO,MAAa;AACzC,KAAM,KAAK;IACT,IAAI,SAAS,EAAM;IACnB,MAAM;IACN,UAAU;KACR,GAAG;KACH,GAAG,IAAuB,KAAY,IAAoB;KAC3D;IACD,UAAU,UAAU,EAAO;IAC3B,QAAQ;IACR,MAAM;KACJ,UAAU,EAAM;KAChB,MAAM,EAAM;KACZ,UAAU;KACV,SAAS,EAAM;KACf,UAAU,EAAM;KAChB,YAAY,UAAoB,EAAY,SAAS,EAAM,GAAG,GAAG,KAAA;KAClE;IACD,WAAW,IAAc,mBAAmB,KAAA;IAC5C,OAAO,EAAE,OAAO,IAAe,IAAiB,GAAG;IACpD,CAAC;IACF,EAGE,EAAO,OAAO,WAAW,KAC3B,EAAM,KAAK;GACT,IAAI,SAAS,EAAO;GACpB,MAAM;GACN,UAAU;IACR,GAAG;IACH,GAAG;IACJ;GACD,UAAU,UAAU,EAAO;GAC3B,QAAQ;GACR,MAAM;IAAE,MAAM;IAAsB,SAAS;IAAI,UAAU;IAAO,SAAS;IAAM;GACjF,OAAO,EAAE,OAAO,IAAe,IAAiB,GAAG;GACpD,CAAC;GAEJ,EAGF,EAAY,SAAS,MAAS;EAC5B,IAAM,IAAe,SAAS,EAAK,YAAY,MACzC,IAAe,UAAU,EAAK,OAAO;AAC3C,MAAI,CAAC,EAAM,MAAM,MAAM,EAAE,OAAO,EAAa,IAAI,CAAC,EAAM,MAAM,MAAM,EAAE,OAAO,EAAa,CACxF;EAEF,IAAM,IAAc,EAAK,WAAW;AACpC,IAAM,KAAK;GACT,IAAI,QAAQ,EAAK;GACjB,QAAQ;GACR,QAAQ;GACR,OAAO,EAAK;GACZ,MAAM;GACN,MAAM;GACN,UAAU;GACV,WAAW,EAAE,MAAM,EAAW,aAAa;GAC3C,OAAO;IACL,QAAQ,IAAc,uCAAuC;IAC7D,aAAa;IACd;GACD,YAAY;IAAE,UAAU;IAAI,YAAY;IAAK;GAC7C,cAAc,EAAE,MAAM,eAAe;GACrC,gBAAgB,CAAC,GAAG,EAAE;GACvB,CAAC;GACF,EAEK;EAAE;EAAO;EAAO;;AAOzB,SAAgB,EAAe,EAC7B,YACA,gBACA,wBACA,yBACA,oBACA,gBACA,iBACsB;CACtB,IAAM,IAAK,GAAO,EACZ,IAAe,EAAuB,KAAK,EAC3C,CAAC,GAAe,KAAoB,QACxC,OAAO,SAAW,MAAc,IAAI,EAAiB,OAAO,WAAW,CACxE;AAED,SAAsB;EACpB,IAAM,KAAuB,MAAkB;AAC7C,MAAkB,MAAY;IAC5B,IAAM,IAAO,EAAiB,EAAM;AACpC,WAAO,MAAY,IAAO,IAAU;KACpC;KAGE,UAA4B;GAChC,IAAM,IAAQ,EAAa,SAAS;AACpC,GAAI,OAAO,KAAU,YAAY,IAAQ,KACvC,EAAoB,EAAM;;AAI9B,KAAqB;EAErB,IAAM,IACJ,OAAO,iBAAmB,MACtB,IAAI,gBAAgB,MAAY;GAC9B,IAAM,IAAQ,EAAQ;AACtB,GAAI,KAAO,EAAoB,EAAM,YAAY,MAAM;IACvD,GACF;AAQN,SANI,KAAkB,EAAa,UACjC,EAAe,QAAQ,EAAa,QAAQ,GAE5C,OAAO,iBAAiB,UAAU,EAAoB,QAG3C;AAIX,GAHK,KACH,OAAO,oBAAoB,UAAU,EAAoB,EAE3D,GAAgB,YAAY;;IAE7B,EAAE,CAAC;CAEN,IAAM,EAAE,OAAO,GAAc,OAAO,MAAiB,QAC7C,EAAmB,GAAS,GAAa,GAAe,EAAY,EAC1E;EAAC;EAAS;EAAa;EAAe;EAAY,CACnD,EAEK,CAAC,GAAO,GAAU,KAAiB,EAAc,EAAa,EAC9D,CAAC,GAAO,GAAU,KAAiB,EAAc,EAAa,EAC9D,CAAC,GAAoB,KAAyB,EAAiC,KAAK,EACpF,CAAC,GAAW,KAAgB,EAAS,GAAM;AAGjD,SAAgB;EACd,IAAM,EAAE,OAAO,GAAU,OAAO,MAAa,EAC3C,GACA,GACA,GACA,EACD;AAED,EADA,EAAS,EAAS,EAClB,EAAS,EAAS;IACjB;EAAC;EAAS;EAAa;EAAe;EAAa;EAAU;EAAS,CAAC;CAE1E,IAAM,IAAkB,GACrB,GAA0B,MAAe;AACxC,MAAI,CAAC,EAAa;EAElB,IAAM,EAAE,aAAU,gBAAc,EAAK,QAAQ,EAAE;AAC3C,GAAC,KAAY,CAAC,KAElB,EAAY,GAAU,EAAS;IAEjC,CAAC,EAAY,CACd,EAEK,IAAkB,GACrB,GAA0B,MAAe;EACxC,IAAM,IAAO,EAAY,MAAM,MAAM,QAAQ,EAAE,SAAS,EAAK,GAAG;AAChE,EAAI,KAAM,EAAsB,EAAK;IAEvC,CAAC,EAAY,CACd,EAEK,IAAwB,GAC3B,GAAuB,MAAqB;AAM3C,EALI,KAAsB,KACxB,EAAoB,EAAmB,IAAI,GAAa,EAAO,EAEjE,EAAsB,KAAK,EAC3B,EAAa,GAAK,EAClB,iBAAiB,EAAa,GAAM,EAAE,IAAK;IAE7C,CAAC,GAAoB,EAAoB,CAC1C;AAID,QACE,kBAAA,GAAA,EAAA,UAAA;EACE,kBAAC,OAAD;GACE,KAAK;GACL,WAAU;GACV,OAAO,EAAE,QAPA,IAAa,SAAS,SAOd;aAEjB,kBAAC,GAAD;IACS;IACA;IACP,gBAAgB;IACD;IACA;IACf,aAAa;IACb,aAAa;IACF;IACX,SAAA;IACA,gBAAgB,EAAE,SAAS,IAAK;IAChC,SAAS;IACT,SAAS;IACT,WAAW;IACX,YAAY,EAAE,iBAAiB,IAAM;cAdvC;KAgBE,kBAAC,GAAD;MACE,SAAS,EAAkB;MAC3B,KAAK;MACL,MAAM;MACN,WAAU;MACV,CAAA;KACF,kBAAC,GAAD;MACE,iBAAiB;MACjB,OAAO;OACL,YAAY;OACZ,QAAQ;OACR,cAAc;OACd,WAAW;OACZ;MACD,WAAU;MACV,CAAA;KACF,kBAAC,GAAD;MACE,UAAA;MACA,UAAA;MACA,OAAO;OACL,QAAQ;OACR,OAAO;OACP,YAAY;OACZ,QAAQ;OACR,cAAc;OACf;MACD,WAAU;MACV,CAAA;KACQ;;GACR,CAAA;EAEL,KACC,kBAAC,GAAD;GACE,YAAY;GACU;GACL;GACjB,QAAQ;GACR,eAAe,EAAsB,KAAK;GAC1C,CAAA;EAGH,KACC,kBAAC,OAAD;GACE,eAAY;GACZ,WAAU;aAFZ,CAIE,kBAAC,GAAD;IAAa,MAAM;IAAI,WAAU;IAA2C,CAAA,EAC5E,kBAAC,QAAD;IAAM,WAAU;cACb,EAAG,uCAAuC,oBAAoB;IAC1D,CAAA,CACH;;EAEP,EAAA,CAAA"}
@@ -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"}