@burdenoff/microfe-vibecontrols 2026.601.8 → 2026.601.9
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 +5 -2
- package/dist/components/graph/MeshAgentNode.js +74 -0
- package/dist/components/graph/MeshAgentNode.js.map +1 -0
- package/dist/components/graph/MeshDeployWizard.js +393 -0
- package/dist/components/graph/MeshDeployWizard.js.map +1 -0
- package/dist/components/graph/MeshGraphView.js +190 -0
- package/dist/components/graph/MeshGraphView.js.map +1 -0
- package/dist/components/graph/MeshNodeActions.js +70 -0
- package/dist/components/graph/MeshNodeActions.js.map +1 -0
- package/dist/components/graph/MeshRequestPanel.js +240 -0
- package/dist/components/graph/MeshRequestPanel.js.map +1 -0
- package/dist/components/graph/meshTypes.js +11 -0
- package/dist/components/graph/meshTypes.js.map +1 -0
- package/dist/components/graph/nodeIcons.js +31 -0
- package/dist/components/graph/nodeIcons.js.map +1 -0
- package/dist/components/sessions/TerminalPanel.js +483 -435
- package/dist/components/sessions/TerminalPanel.js.map +1 -1
- package/dist/generated/wspace-operations.js +1856 -1647
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js +14 -12
- package/dist/generated/wspace-types.js.map +1 -1
- package/dist/index.js +10 -10
- package/dist/node_modules/dagre/index.js +24 -0
- package/dist/node_modules/dagre/index.js.map +1 -0
- package/dist/node_modules/dagre/lib/acyclic.js +47 -0
- package/dist/node_modules/dagre/lib/acyclic.js.map +1 -0
- package/dist/node_modules/dagre/lib/add-border-segments.js +32 -0
- package/dist/node_modules/dagre/lib/add-border-segments.js.map +1 -0
- package/dist/node_modules/dagre/lib/coordinate-system.js +57 -0
- package/dist/node_modules/dagre/lib/coordinate-system.js.map +1 -0
- package/dist/node_modules/dagre/lib/data/list.js +30 -0
- package/dist/node_modules/dagre/lib/data/list.js.map +1 -0
- package/dist/node_modules/dagre/lib/debug.js +31 -0
- package/dist/node_modules/dagre/lib/debug.js.map +1 -0
- package/dist/node_modules/dagre/lib/graphlib.js +15 -0
- package/dist/node_modules/dagre/lib/graphlib.js.map +1 -0
- package/dist/node_modules/dagre/lib/greedy-fas.js +74 -0
- package/dist/node_modules/dagre/lib/greedy-fas.js.map +1 -0
- package/dist/node_modules/dagre/lib/layout.js +305 -0
- package/dist/node_modules/dagre/lib/layout.js.map +1 -0
- package/dist/node_modules/dagre/lib/lodash.js +67 -0
- package/dist/node_modules/dagre/lib/lodash.js.map +1 -0
- package/dist/node_modules/dagre/lib/nesting-graph.js +76 -0
- package/dist/node_modules/dagre/lib/nesting-graph.js.map +1 -0
- package/dist/node_modules/dagre/lib/normalize.js +45 -0
- package/dist/node_modules/dagre/lib/normalize.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/add-subgraph-constraints.js +24 -0
- package/dist/node_modules/dagre/lib/order/add-subgraph-constraints.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/barycenter.js +34 -0
- package/dist/node_modules/dagre/lib/order/barycenter.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/build-layer-graph.js +32 -0
- package/dist/node_modules/dagre/lib/order/build-layer-graph.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/cross-count.js +39 -0
- package/dist/node_modules/dagre/lib/order/cross-count.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/index.js +50 -0
- package/dist/node_modules/dagre/lib/order/index.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/init-order.js +28 -0
- package/dist/node_modules/dagre/lib/order/init-order.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/resolve-conflicts.js +61 -0
- package/dist/node_modules/dagre/lib/order/resolve-conflicts.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/sort-subgraph.js +50 -0
- package/dist/node_modules/dagre/lib/order/sort-subgraph.js.map +1 -0
- package/dist/node_modules/dagre/lib/order/sort.js +34 -0
- package/dist/node_modules/dagre/lib/order/sort.js.map +1 -0
- package/dist/node_modules/dagre/lib/parent-dummy-chains.js +50 -0
- package/dist/node_modules/dagre/lib/parent-dummy-chains.js.map +1 -0
- package/dist/node_modules/dagre/lib/position/bk.js +212 -0
- package/dist/node_modules/dagre/lib/position/bk.js.map +1 -0
- package/dist/node_modules/dagre/lib/position/index.js +30 -0
- package/dist/node_modules/dagre/lib/position/index.js.map +1 -0
- package/dist/node_modules/dagre/lib/rank/feasible-tree.js +39 -0
- package/dist/node_modules/dagre/lib/rank/feasible-tree.js.map +1 -0
- package/dist/node_modules/dagre/lib/rank/index.js +35 -0
- package/dist/node_modules/dagre/lib/rank/index.js.map +1 -0
- package/dist/node_modules/dagre/lib/rank/network-simplex.js +90 -0
- package/dist/node_modules/dagre/lib/rank/network-simplex.js.map +1 -0
- package/dist/node_modules/dagre/lib/rank/util.js +31 -0
- package/dist/node_modules/dagre/lib/rank/util.js.map +1 -0
- package/dist/node_modules/dagre/lib/util.js +151 -0
- package/dist/node_modules/dagre/lib/util.js.map +1 -0
- package/dist/node_modules/dagre/lib/version.js +10 -0
- package/dist/node_modules/dagre/lib/version.js.map +1 -0
- package/dist/node_modules/graphlib/index.js +19 -0
- package/dist/node_modules/graphlib/index.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/components.js +21 -0
- package/dist/node_modules/graphlib/lib/alg/components.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/dfs.js +25 -0
- package/dist/node_modules/graphlib/lib/alg/dfs.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/dijkstra-all.js +18 -0
- package/dist/node_modules/graphlib/lib/alg/dijkstra-all.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/dijkstra.js +31 -0
- package/dist/node_modules/graphlib/lib/alg/dijkstra.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/find-cycles.js +18 -0
- package/dist/node_modules/graphlib/lib/alg/find-cycles.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/floyd-warshall.js +41 -0
- package/dist/node_modules/graphlib/lib/alg/floyd-warshall.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/index.js +33 -0
- package/dist/node_modules/graphlib/lib/alg/index.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/is-acyclic.js +21 -0
- package/dist/node_modules/graphlib/lib/alg/is-acyclic.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/postorder.js +15 -0
- package/dist/node_modules/graphlib/lib/alg/postorder.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/preorder.js +15 -0
- package/dist/node_modules/graphlib/lib/alg/preorder.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/prim.js +35 -0
- package/dist/node_modules/graphlib/lib/alg/prim.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/tarjan.js +34 -0
- package/dist/node_modules/graphlib/lib/alg/tarjan.js.map +1 -0
- package/dist/node_modules/graphlib/lib/alg/topsort.js +23 -0
- package/dist/node_modules/graphlib/lib/alg/topsort.js.map +1 -0
- package/dist/node_modules/graphlib/lib/data/priority-queue.js +56 -0
- package/dist/node_modules/graphlib/lib/data/priority-queue.js.map +1 -0
- package/dist/node_modules/graphlib/lib/graph.js +196 -0
- package/dist/node_modules/graphlib/lib/graph.js.map +1 -0
- package/dist/node_modules/graphlib/lib/index.js +15 -0
- package/dist/node_modules/graphlib/lib/index.js.map +1 -0
- package/dist/node_modules/graphlib/lib/json.js +55 -0
- package/dist/node_modules/graphlib/lib/json.js.map +1 -0
- package/dist/node_modules/graphlib/lib/lodash.js +47 -0
- package/dist/node_modules/graphlib/lib/lodash.js.map +1 -0
- package/dist/node_modules/graphlib/lib/version.js +10 -0
- package/dist/node_modules/graphlib/lib/version.js.map +1 -0
- package/dist/node_modules/lodash/_arrayEach.js +14 -0
- package/dist/node_modules/lodash/_arrayEach.js.map +1 -0
- package/dist/node_modules/lodash/_arrayReduce.js +15 -0
- package/dist/node_modules/lodash/_arrayReduce.js.map +1 -0
- package/dist/node_modules/lodash/_asciiSize.js +11 -0
- package/dist/node_modules/lodash/_asciiSize.js.map +1 -0
- package/dist/node_modules/lodash/_assignMergeValue.js +16 -0
- package/dist/node_modules/lodash/_assignMergeValue.js.map +1 -0
- package/dist/node_modules/lodash/_assignValue.js +17 -0
- package/dist/node_modules/lodash/_assignValue.js.map +1 -0
- package/dist/node_modules/lodash/_baseAssign.js +16 -0
- package/dist/node_modules/lodash/_baseAssign.js.map +1 -0
- package/dist/node_modules/lodash/_baseAssignIn.js +16 -0
- package/dist/node_modules/lodash/_baseAssignIn.js.map +1 -0
- package/dist/node_modules/lodash/_baseClone.js +64 -0
- package/dist/node_modules/lodash/_baseClone.js.map +1 -0
- package/dist/node_modules/lodash/_baseCreate.js +21 -0
- package/dist/node_modules/lodash/_baseCreate.js.map +1 -0
- package/dist/node_modules/lodash/_baseFilter.js +18 -0
- package/dist/node_modules/lodash/_baseFilter.js.map +1 -0
- package/dist/node_modules/lodash/_baseHas.js +14 -0
- package/dist/node_modules/lodash/_baseHas.js.map +1 -0
- package/dist/node_modules/lodash/_baseIsMap.js +16 -0
- package/dist/node_modules/lodash/_baseIsMap.js.map +1 -0
- package/dist/node_modules/lodash/_baseIsSet.js +16 -0
- package/dist/node_modules/lodash/_baseIsSet.js.map +1 -0
- package/dist/node_modules/lodash/_baseKeysIn.js +20 -0
- package/dist/node_modules/lodash/_baseKeysIn.js.map +1 -0
- package/dist/node_modules/lodash/_baseMerge.js +27 -0
- package/dist/node_modules/lodash/_baseMerge.js.map +1 -0
- package/dist/node_modules/lodash/_baseMergeDeep.js +39 -0
- package/dist/node_modules/lodash/_baseMergeDeep.js.map +1 -0
- package/dist/node_modules/lodash/_basePick.js +18 -0
- package/dist/node_modules/lodash/_basePick.js.map +1 -0
- package/dist/node_modules/lodash/_basePickBy.js +21 -0
- package/dist/node_modules/lodash/_basePickBy.js.map +1 -0
- package/dist/node_modules/lodash/_baseReduce.js +15 -0
- package/dist/node_modules/lodash/_baseReduce.js.map +1 -0
- package/dist/node_modules/lodash/_baseSet.js +30 -0
- package/dist/node_modules/lodash/_baseSet.js.map +1 -0
- package/dist/node_modules/lodash/_baseValues.js +17 -0
- package/dist/node_modules/lodash/_baseValues.js.map +1 -0
- package/dist/node_modules/lodash/_baseZipObject.js +17 -0
- package/dist/node_modules/lodash/_baseZipObject.js.map +1 -0
- package/dist/node_modules/lodash/_castFunction.js +15 -0
- package/dist/node_modules/lodash/_castFunction.js.map +1 -0
- package/dist/node_modules/lodash/_cloneArrayBuffer.js +16 -0
- package/dist/node_modules/lodash/_cloneArrayBuffer.js.map +1 -0
- package/dist/node_modules/lodash/_cloneBuffer.js +17 -0
- package/dist/node_modules/lodash/_cloneBuffer.js.map +1 -0
- package/dist/node_modules/lodash/_cloneDataView.js +16 -0
- package/dist/node_modules/lodash/_cloneDataView.js.map +1 -0
- package/dist/node_modules/lodash/_cloneRegExp.js +15 -0
- package/dist/node_modules/lodash/_cloneRegExp.js.map +1 -0
- package/dist/node_modules/lodash/_cloneSymbol.js +15 -0
- package/dist/node_modules/lodash/_cloneSymbol.js.map +1 -0
- package/dist/node_modules/lodash/_cloneTypedArray.js +16 -0
- package/dist/node_modules/lodash/_cloneTypedArray.js.map +1 -0
- package/dist/node_modules/lodash/_copyArray.js +15 -0
- package/dist/node_modules/lodash/_copyArray.js.map +1 -0
- package/dist/node_modules/lodash/_copyObject.js +22 -0
- package/dist/node_modules/lodash/_copyObject.js.map +1 -0
- package/dist/node_modules/lodash/_copySymbols.js +16 -0
- package/dist/node_modules/lodash/_copySymbols.js.map +1 -0
- package/dist/node_modules/lodash/_copySymbolsIn.js +16 -0
- package/dist/node_modules/lodash/_copySymbolsIn.js.map +1 -0
- package/dist/node_modules/lodash/_createAssigner.js +23 -0
- package/dist/node_modules/lodash/_createAssigner.js.map +1 -0
- package/dist/node_modules/lodash/_flatRest.js +17 -0
- package/dist/node_modules/lodash/_flatRest.js.map +1 -0
- package/dist/node_modules/lodash/_getAllKeysIn.js +17 -0
- package/dist/node_modules/lodash/_getAllKeysIn.js.map +1 -0
- package/dist/node_modules/lodash/_getSymbolsIn.js +18 -0
- package/dist/node_modules/lodash/_getSymbolsIn.js.map +1 -0
- package/dist/node_modules/lodash/_initCloneArray.js +15 -0
- package/dist/node_modules/lodash/_initCloneArray.js.map +1 -0
- package/dist/node_modules/lodash/_initCloneByTag.js +40 -0
- package/dist/node_modules/lodash/_initCloneByTag.js.map +1 -0
- package/dist/node_modules/lodash/_initCloneObject.js +17 -0
- package/dist/node_modules/lodash/_initCloneObject.js.map +1 -0
- package/dist/node_modules/lodash/_nativeKeysIn.js +15 -0
- package/dist/node_modules/lodash/_nativeKeysIn.js.map +1 -0
- package/dist/node_modules/lodash/_safeGet.js +13 -0
- package/dist/node_modules/lodash/_safeGet.js.map +1 -0
- package/dist/node_modules/lodash/_stringSize.js +17 -0
- package/dist/node_modules/lodash/_stringSize.js.map +1 -0
- package/dist/node_modules/lodash/_unicodeSize.js +25 -0
- package/dist/node_modules/lodash/_unicodeSize.js.map +1 -0
- package/dist/node_modules/lodash/clone.js +15 -0
- package/dist/node_modules/lodash/clone.js.map +1 -0
- package/dist/node_modules/lodash/cloneDeep.js +15 -0
- package/dist/node_modules/lodash/cloneDeep.js.map +1 -0
- package/dist/node_modules/lodash/defaults.js +23 -0
- package/dist/node_modules/lodash/defaults.js.map +1 -0
- package/dist/node_modules/lodash/each.js +11 -0
- package/dist/node_modules/lodash/each.js.map +1 -0
- package/dist/node_modules/lodash/filter.js +18 -0
- package/dist/node_modules/lodash/filter.js.map +1 -0
- package/dist/node_modules/lodash/flatten.js +15 -0
- package/dist/node_modules/lodash/flatten.js.map +1 -0
- package/dist/node_modules/lodash/forEach.js +18 -0
- package/dist/node_modules/lodash/forEach.js.map +1 -0
- package/dist/node_modules/lodash/forIn.js +17 -0
- package/dist/node_modules/lodash/forIn.js.map +1 -0
- package/dist/node_modules/lodash/has.js +16 -0
- package/dist/node_modules/lodash/has.js.map +1 -0
- package/dist/node_modules/lodash/isArrayLikeObject.js +16 -0
- package/dist/node_modules/lodash/isArrayLikeObject.js.map +1 -0
- package/dist/node_modules/lodash/isEmpty.js +28 -0
- package/dist/node_modules/lodash/isEmpty.js.map +1 -0
- package/dist/node_modules/lodash/isMap.js +14 -0
- package/dist/node_modules/lodash/isMap.js.map +1 -0
- package/dist/node_modules/lodash/isSet.js +14 -0
- package/dist/node_modules/lodash/isSet.js.map +1 -0
- package/dist/node_modules/lodash/isUndefined.js +13 -0
- package/dist/node_modules/lodash/isUndefined.js.map +1 -0
- package/dist/node_modules/lodash/keysIn.js +17 -0
- package/dist/node_modules/lodash/keysIn.js.map +1 -0
- package/dist/node_modules/lodash/merge.js +15 -0
- package/dist/node_modules/lodash/merge.js.map +1 -0
- package/dist/node_modules/lodash/pick.js +15 -0
- package/dist/node_modules/lodash/pick.js.map +1 -0
- package/dist/node_modules/lodash/reduce.js +20 -0
- package/dist/node_modules/lodash/reduce.js.map +1 -0
- package/dist/node_modules/lodash/size.js +22 -0
- package/dist/node_modules/lodash/size.js.map +1 -0
- package/dist/node_modules/lodash/toPlainObject.js +16 -0
- package/dist/node_modules/lodash/toPlainObject.js.map +1 -0
- package/dist/node_modules/lodash/transform.js +31 -0
- package/dist/node_modules/lodash/transform.js.map +1 -0
- package/dist/node_modules/lodash/union.js +17 -0
- package/dist/node_modules/lodash/union.js.map +1 -0
- package/dist/node_modules/lodash/uniqueId.js +16 -0
- package/dist/node_modules/lodash/uniqueId.js.map +1 -0
- package/dist/node_modules/lodash/values.js +16 -0
- package/dist/node_modules/lodash/values.js.map +1 -0
- package/dist/node_modules/lodash/zipObject.js +16 -0
- package/dist/node_modules/lodash/zipObject.js.map +1 -0
- package/dist/pages/AgentGraphPage.js +251 -118
- package/dist/pages/AgentGraphPage.js.map +1 -1
- package/dist/pages/SessionsPage.js +957 -918
- package/dist/pages/SessionsPage.js.map +1 -1
- package/dist/translations/en.js +7 -1
- package/dist/translations/en.js.map +1 -1
- package/package.json +3 -1
- package/dist/components/graph/AgentGraphView.js +0 -237
- package/dist/components/graph/AgentGraphView.js.map +0 -1
- package/dist/components/graph/AgentNode.js +0 -54
- package/dist/components/graph/AgentNode.js.map +0 -1
- package/dist/components/graph/TargetNode.js +0 -76
- package/dist/components/graph/TargetNode.js.map +0 -1
|
@@ -15,6 +15,9 @@ 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))
|
|
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
|
+
});
|
|
19
22
|
//#endregion
|
|
20
|
-
export { o as __commonJSMin, s as __exportAll, l as __toESM };
|
|
23
|
+
export { o as __commonJSMin, s as __exportAll, u as __require, l as __toESM };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getNodeTypeConfig as e } from "./nodeIcons.js";
|
|
2
|
+
import { memo as t } from "react";
|
|
3
|
+
import { Bot as n, User as r, Users as i } from "lucide-react";
|
|
4
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
+
import { Handle as s, Position as c } from "@xyflow/react";
|
|
6
|
+
//#region src/components/graph/MeshAgentNode.tsx
|
|
7
|
+
function l({ data: t, selected: l }) {
|
|
8
|
+
let u = t, d = e(u.hostType), f = d.icon, p = u.isShared ? i : r;
|
|
9
|
+
return /* @__PURE__ */ o("div", {
|
|
10
|
+
className: `rounded-lg border bg-bg-surface shadow-sm p-2.5 flex flex-col gap-1.5 transition-shadow hover:shadow-md ${l ? "border-action-primary-bg ring-1 ring-action-primary-bg/40" : "border-border-default"}`,
|
|
11
|
+
style: { width: 200 },
|
|
12
|
+
role: u.onActivate ? "button" : void 0,
|
|
13
|
+
tabIndex: u.onActivate ? 0 : void 0,
|
|
14
|
+
"aria-label": u.onActivate ? `Open agent ${u.name}` : void 0,
|
|
15
|
+
onKeyDown: (e) => {
|
|
16
|
+
u.onActivate && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), u.onActivate());
|
|
17
|
+
},
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ a(s, {
|
|
20
|
+
type: "target",
|
|
21
|
+
position: c.Left,
|
|
22
|
+
className: "!bg-text-tertiary !w-2 !h-2 !border-0"
|
|
23
|
+
}),
|
|
24
|
+
/* @__PURE__ */ a(s, {
|
|
25
|
+
type: "source",
|
|
26
|
+
position: c.Right,
|
|
27
|
+
className: "!bg-action-primary-bg !w-2 !h-2 !border-0"
|
|
28
|
+
}),
|
|
29
|
+
/* @__PURE__ */ o("div", {
|
|
30
|
+
className: "flex items-center gap-2",
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ a(n, {
|
|
33
|
+
size: 14,
|
|
34
|
+
className: "text-action-primary-bg shrink-0"
|
|
35
|
+
}),
|
|
36
|
+
/* @__PURE__ */ o("div", {
|
|
37
|
+
className: "min-w-0 flex-1",
|
|
38
|
+
children: [/* @__PURE__ */ a("div", {
|
|
39
|
+
className: "text-xs font-semibold text-text-primary truncate",
|
|
40
|
+
children: u.name
|
|
41
|
+
}), u.version ? /* @__PURE__ */ o("div", {
|
|
42
|
+
className: "text-[10px] text-text-tertiary",
|
|
43
|
+
children: ["v", u.version]
|
|
44
|
+
}) : null]
|
|
45
|
+
}),
|
|
46
|
+
/* @__PURE__ */ a(p, {
|
|
47
|
+
size: 12,
|
|
48
|
+
className: `shrink-0 ${u.isShared ? "text-text-tertiary" : "text-accent-purple"}`,
|
|
49
|
+
"aria-label": u.isShared ? "Shared agent" : "Personal agent"
|
|
50
|
+
}),
|
|
51
|
+
/* @__PURE__ */ a("span", {
|
|
52
|
+
className: `size-2 rounded-full shrink-0 ${u.isActive ? "bg-status-success-bg" : "bg-bg-disabled"}`,
|
|
53
|
+
title: u.isActive ? "Active" : "Offline"
|
|
54
|
+
})
|
|
55
|
+
]
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ o("div", {
|
|
58
|
+
className: "flex items-center gap-1",
|
|
59
|
+
children: [/* @__PURE__ */ o("span", {
|
|
60
|
+
className: `inline-flex items-center gap-1 px-1.5 py-0.5 text-[9px] font-bold uppercase tracking-wider rounded ${d.badge}`,
|
|
61
|
+
children: [/* @__PURE__ */ a(f, { size: 9 }), u.hostType ?? "HOST"]
|
|
62
|
+
}), u.hostLabel ? /* @__PURE__ */ a("span", {
|
|
63
|
+
className: "text-[10px] text-text-tertiary truncate",
|
|
64
|
+
children: u.hostLabel
|
|
65
|
+
}) : null]
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
var u = t(l);
|
|
71
|
+
//#endregion
|
|
72
|
+
export { u as MeshAgentNode };
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=MeshAgentNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MeshAgentNode.js","names":[],"sources":["../../../src/components/graph/MeshAgentNode.tsx"],"sourcesContent":["/**\n * MeshAgentNode — React Flow custom node for an Agent in the agent-mesh graph.\n *\n * Unlike the target-centric AgentGraphView (where agents are children of a\n * target group), here the AGENT is the first-class node. It renders:\n * - the agent name + version\n * - an active/offline status dot\n * - a shared-vs-personal owner glyph (Users = shared, User = personal)\n * - a HOST badge built from the agent's `target.type` / `target.host` using\n * the shared node-icon map.\n *\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, User, Users } from 'lucide-react';\nimport { getNodeTypeConfig } from './nodeIcons';\n\nexport interface MeshAgentNodeData {\n name: string;\n version?: string | null;\n isActive: boolean;\n /** NULL ownerUserId => shared workspace agent; non-null => personal. */\n isShared: boolean;\n hostType?: string | null;\n hostLabel?: string | null;\n onActivate?: () => void;\n [key: string]: unknown;\n}\n\nfunction MeshAgentNodeComponent({ data, selected }: NodeProps) {\n const d = data as MeshAgentNodeData;\n const hostConfig = getNodeTypeConfig(d.hostType);\n const HostIcon = hostConfig.icon;\n const OwnerIcon = d.isShared ? Users : User;\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 bg-bg-surface shadow-sm p-2.5 flex flex-col gap-1.5 transition-shadow hover:shadow-md ${\n selected\n ? 'border-action-primary-bg ring-1 ring-action-primary-bg/40'\n : 'border-border-default'\n }`}\n style={{ width: 200 }}\n role={d.onActivate ? 'button' : undefined}\n tabIndex={d.onActivate ? 0 : undefined}\n aria-label={d.onActivate ? `Open agent ${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 <Handle\n type=\"source\"\n position={Position.Right}\n className=\"!bg-action-primary-bg !w-2 !h-2 !border-0\"\n />\n\n <div className=\"flex items-center gap-2\">\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-semibold text-text-primary truncate\">{d.name}</div>\n {d.version ? <div className=\"text-[10px] text-text-tertiary\">v{d.version}</div> : null}\n </div>\n <OwnerIcon\n size={12}\n className={`shrink-0 ${d.isShared ? 'text-text-tertiary' : 'text-accent-purple'}`}\n aria-label={d.isShared ? 'Shared agent' : 'Personal agent'}\n />\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 <div className=\"flex items-center gap-1\">\n <span\n className={`inline-flex items-center gap-1 px-1.5 py-0.5 text-[9px] font-bold uppercase tracking-wider rounded ${hostConfig.badge}`}\n >\n <HostIcon size={9} />\n {d.hostType ?? 'HOST'}\n </span>\n {d.hostLabel ? (\n <span className=\"text-[10px] text-text-tertiary truncate\">{d.hostLabel}</span>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport const MeshAgentNode = memo(MeshAgentNodeComponent);\n"],"mappings":";;;;;;AA+BA,SAAS,EAAuB,EAAE,SAAM,eAAuB;CAC7D,IAAM,IAAI,GACJ,IAAa,EAAkB,EAAE,SAAS,EAC1C,IAAW,EAAW,MACtB,IAAY,EAAE,WAAW,IAAQ;AAUvC,QACE,kBAAC,OAAD;EACE,WAAW,2GACT,IACI,8DACA;EAEN,OAAO,EAAE,OAAO,KAAK;EACrB,MAAM,EAAE,aAAa,WAAW,KAAA;EAChC,UAAU,EAAE,aAAa,IAAI,KAAA;EAC7B,cAAY,EAAE,aAAa,cAAc,EAAE,SAAS,KAAA;EACpD,YAnBmB,MAA+C;AAC/D,KAAE,eACH,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,gBAAgB,EACtB,EAAE,YAAY;;YAKhB;GAYE,kBAAC,GAAD;IACE,MAAK;IACL,UAAU,EAAS;IACnB,WAAU;IACV,CAAA;GACF,kBAAC,GAAD;IACE,MAAK;IACL,UAAU,EAAS;IACnB,WAAU;IACV,CAAA;GAEF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAK,MAAM;MAAI,WAAU;MAAoC,CAAA;KAC7D,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAoD,EAAE;OAAW,CAAA,EAC/E,EAAE,UAAU,kBAAC,OAAD;OAAK,WAAU;iBAAf,CAAgD,KAAE,EAAE,QAAc;WAAG,KAC9E;;KACN,kBAAC,GAAD;MACE,MAAM;MACN,WAAW,YAAY,EAAE,WAAW,uBAAuB;MAC3D,cAAY,EAAE,WAAW,iBAAiB;MAC1C,CAAA;KACF,kBAAC,QAAD;MACE,WAAW,gCAAgC,EAAE,WAAW,yBAAyB;MACjF,OAAO,EAAE,WAAW,WAAW;MAC/B,CAAA;KACE;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KACE,WAAW,sGAAsG,EAAW;eAD9H,CAGE,kBAAC,GAAD,EAAU,MAAM,GAAK,CAAA,EACpB,EAAE,YAAY,OACV;QACN,EAAE,YACD,kBAAC,QAAD;KAAM,WAAU;eAA2C,EAAE;KAAiB,CAAA,GAC5E,KACA;;GACF;;;AAIV,IAAa,IAAgB,EAAK,EAAuB"}
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { useDeployAgentViaMeshMutation as e, useMeshDeployJobStatusLazyQuery as t } from "../../generated/wspace-operations.js";
|
|
2
|
+
import { useTr as n } from "../../shared/hooks/useTr.js";
|
|
3
|
+
import { useCallback as r, useEffect as i, useMemo as a, useState as o } from "react";
|
|
4
|
+
import { Check as s, CheckCircle as ee, Laptop as te, Loader2 as c, Server as ne, X as re, XCircle as l } from "lucide-react";
|
|
5
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/graph/MeshDeployWizard.tsx
|
|
7
|
+
var f = {
|
|
8
|
+
probe: "Probing target",
|
|
9
|
+
"install-bun": "Installing Bun runtime",
|
|
10
|
+
"install-agent": "Installing VibeControls Agent",
|
|
11
|
+
autostart: "Configuring autostart",
|
|
12
|
+
plugins: "Installing plugins",
|
|
13
|
+
start: "Starting agent",
|
|
14
|
+
bootstrap: "Bootstrapping tunnel",
|
|
15
|
+
onboard: "Onboarding agent",
|
|
16
|
+
"store-creds": "Storing credentials",
|
|
17
|
+
"report-link": "Linking into mesh",
|
|
18
|
+
"probe-peer": "Probing new peer"
|
|
19
|
+
};
|
|
20
|
+
function p(e) {
|
|
21
|
+
return e && typeof e == "object" && !Array.isArray(e) ? e : null;
|
|
22
|
+
}
|
|
23
|
+
function m(e, t) {
|
|
24
|
+
let n = e?.[t];
|
|
25
|
+
return typeof n == "string" ? n : null;
|
|
26
|
+
}
|
|
27
|
+
var h = "px-3 py-2 text-sm rounded-md bg-bg-sunken border border-border-default text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40 w-full", g = "text-xs font-medium text-text-secondary mb-1 block";
|
|
28
|
+
function _({ sourceAgents: _, initialSourceAgentId: v, availablePermissions: y, onClose: b, onCompleted: x }) {
|
|
29
|
+
let S = n(), [C, ie] = o(v ?? _[0]?.id ?? ""), [w, T] = o("ssh"), [E, D] = o(""), [O, k] = o(22), [A, j] = o(""), [M, N] = o("agent"), [P, F] = o(""), [I, L] = o(""), [R, z] = o(!1), [B, V] = o(/* @__PURE__ */ new Set()), [H, U] = o(null), [W, G] = o(null), [K, q] = o(null), [J, { loading: Y }] = e(), [X] = t({ fetchPolicy: "network-only" }), Z = a(() => C ? w === "ssh" ? E.trim().length > 0 && A.trim().length > 0 : !0 : !1, [
|
|
30
|
+
C,
|
|
31
|
+
w,
|
|
32
|
+
E,
|
|
33
|
+
A
|
|
34
|
+
]), ae = r((e) => {
|
|
35
|
+
V((t) => {
|
|
36
|
+
let n = new Set(t);
|
|
37
|
+
return n.has(e) ? n.delete(e) : n.add(e), n;
|
|
38
|
+
});
|
|
39
|
+
}, []), Q = r(() => {
|
|
40
|
+
if (w === "same") return "localhost";
|
|
41
|
+
let e = E.trim(), t = A.trim(), n = t ? `${t}@${e}` : e;
|
|
42
|
+
return O && O !== 22 ? `${n}:${O}` : n;
|
|
43
|
+
}, [
|
|
44
|
+
w,
|
|
45
|
+
E,
|
|
46
|
+
A,
|
|
47
|
+
O
|
|
48
|
+
]), oe = r(async () => {
|
|
49
|
+
if (Z) {
|
|
50
|
+
q(null), G(null), U(null);
|
|
51
|
+
try {
|
|
52
|
+
let e = await J({ variables: {
|
|
53
|
+
rootAgentId: C,
|
|
54
|
+
input: {
|
|
55
|
+
target: Q(),
|
|
56
|
+
permissions: B.size > 0 ? Array.from(B) : void 0,
|
|
57
|
+
identityFile: w === "ssh" && M === "key" && P || void 0,
|
|
58
|
+
label: I || void 0,
|
|
59
|
+
connectExisting: R
|
|
60
|
+
}
|
|
61
|
+
} }), t = e.data?.deployAgentViaMesh;
|
|
62
|
+
if (e.error || t?.error || t?.ok === !1) {
|
|
63
|
+
q(t?.error ?? e.error?.message ?? S("mesh.deploy.failed", "Deploy failed"));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
let n = p(t?.data), r = m(n, "jobId");
|
|
67
|
+
if (!r) {
|
|
68
|
+
q(S("mesh.deploy.noJob", "Deploy started but no job id was returned by the agent."));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
U(r), G({
|
|
72
|
+
status: m(n, "status") ?? "running",
|
|
73
|
+
steps: []
|
|
74
|
+
});
|
|
75
|
+
} catch (e) {
|
|
76
|
+
q(e instanceof Error ? e.message : String(e));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}, [
|
|
80
|
+
Z,
|
|
81
|
+
J,
|
|
82
|
+
C,
|
|
83
|
+
Q,
|
|
84
|
+
B,
|
|
85
|
+
w,
|
|
86
|
+
M,
|
|
87
|
+
P,
|
|
88
|
+
I,
|
|
89
|
+
R,
|
|
90
|
+
S
|
|
91
|
+
]);
|
|
92
|
+
i(() => {
|
|
93
|
+
if (!H || !C) return;
|
|
94
|
+
let e = !1, t = () => {
|
|
95
|
+
X({ variables: {
|
|
96
|
+
rootAgentId: C,
|
|
97
|
+
jobId: H
|
|
98
|
+
} }).then((t) => {
|
|
99
|
+
if (e) return;
|
|
100
|
+
let n = t.data?.meshDeployJobStatus, r = p(n?.data);
|
|
101
|
+
if (!r) return;
|
|
102
|
+
let i = Array.isArray(r.steps) ? r.steps : [];
|
|
103
|
+
G({
|
|
104
|
+
status: m(r, "status") ?? "running",
|
|
105
|
+
steps: i,
|
|
106
|
+
error: m(r, "error") ?? n?.error ?? void 0
|
|
107
|
+
}), m(r, "status") === "completed" && x();
|
|
108
|
+
}).catch(() => {});
|
|
109
|
+
};
|
|
110
|
+
t();
|
|
111
|
+
let n = setInterval(t, 2e3);
|
|
112
|
+
return () => {
|
|
113
|
+
e = !0, clearInterval(n);
|
|
114
|
+
};
|
|
115
|
+
}, [
|
|
116
|
+
H,
|
|
117
|
+
C,
|
|
118
|
+
X,
|
|
119
|
+
x
|
|
120
|
+
]);
|
|
121
|
+
let $ = W?.status === "running" || H !== null && W?.status !== "completed" && W?.status !== "failed";
|
|
122
|
+
return /* @__PURE__ */ d("div", {
|
|
123
|
+
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
124
|
+
children: [/* @__PURE__ */ u("div", {
|
|
125
|
+
role: "button",
|
|
126
|
+
tabIndex: 0,
|
|
127
|
+
"aria-label": S("mesh.deploy.close", "Close"),
|
|
128
|
+
className: "fixed inset-0 bg-bg-overlay backdrop-blur-sm",
|
|
129
|
+
onClick: $ ? void 0 : b,
|
|
130
|
+
onKeyDown: (e) => {
|
|
131
|
+
!$ && (e.key === "Escape" || e.key === "Enter") && b();
|
|
132
|
+
}
|
|
133
|
+
}), /* @__PURE__ */ d("div", {
|
|
134
|
+
className: "relative bg-bg-surface rounded-xl shadow-2xl border border-border-default max-w-lg w-full mx-4 p-6 max-h-[90vh] overflow-auto",
|
|
135
|
+
children: [/* @__PURE__ */ d("div", {
|
|
136
|
+
className: "flex items-center justify-between mb-4",
|
|
137
|
+
children: [/* @__PURE__ */ u("h2", {
|
|
138
|
+
className: "text-lg font-semibold text-text-primary",
|
|
139
|
+
children: S("mesh.deploy.title", "Deploy Agent via Mesh")
|
|
140
|
+
}), !$ && /* @__PURE__ */ u("button", {
|
|
141
|
+
type: "button",
|
|
142
|
+
onClick: b,
|
|
143
|
+
className: "p-1 rounded-lg hover:bg-bg-sunken",
|
|
144
|
+
"aria-label": S("mesh.deploy.close", "Close"),
|
|
145
|
+
children: /* @__PURE__ */ u(re, { size: 18 })
|
|
146
|
+
})]
|
|
147
|
+
}), H ? /* @__PURE__ */ d("div", {
|
|
148
|
+
className: "space-y-3",
|
|
149
|
+
children: [
|
|
150
|
+
/* @__PURE__ */ u("p", {
|
|
151
|
+
className: "text-sm text-text-secondary",
|
|
152
|
+
children: S("mesh.deploy.deploying", "Deploying through {{agent}}…", { agent: _.find((e) => e.id === C)?.name ?? "agent" })
|
|
153
|
+
}),
|
|
154
|
+
/* @__PURE__ */ u("div", {
|
|
155
|
+
className: "space-y-2",
|
|
156
|
+
children: W && W.steps.length > 0 ? W.steps.map((e, t) => /* @__PURE__ */ d("div", {
|
|
157
|
+
className: "flex items-center gap-3",
|
|
158
|
+
children: [
|
|
159
|
+
e.status === "running" && /* @__PURE__ */ u(c, {
|
|
160
|
+
className: "animate-spin text-action-primary-bg",
|
|
161
|
+
size: 16
|
|
162
|
+
}),
|
|
163
|
+
e.status === "completed" && /* @__PURE__ */ u(ee, {
|
|
164
|
+
className: "text-status-success-text",
|
|
165
|
+
size: 16
|
|
166
|
+
}),
|
|
167
|
+
e.status === "failed" && /* @__PURE__ */ u(l, {
|
|
168
|
+
className: "text-status-error-text",
|
|
169
|
+
size: 16
|
|
170
|
+
}),
|
|
171
|
+
e.status === "skipped" && /* @__PURE__ */ u(s, {
|
|
172
|
+
className: "text-text-tertiary",
|
|
173
|
+
size: 16
|
|
174
|
+
}),
|
|
175
|
+
e.status === "pending" && /* @__PURE__ */ u("div", { className: "size-4 rounded-full border-2 border-border-default" }),
|
|
176
|
+
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("div", {
|
|
177
|
+
className: "text-sm font-medium text-text-primary",
|
|
178
|
+
children: S(`mesh.deploy.step.${e.step}`, f[e.step] ?? e.step)
|
|
179
|
+
}), e.message ? /* @__PURE__ */ u("div", {
|
|
180
|
+
className: "text-xs text-text-tertiary",
|
|
181
|
+
children: e.message
|
|
182
|
+
}) : null] })
|
|
183
|
+
]
|
|
184
|
+
}, `${e.step}-${t}`)) : /* @__PURE__ */ d("div", {
|
|
185
|
+
className: "flex items-center gap-3",
|
|
186
|
+
children: [/* @__PURE__ */ u(c, {
|
|
187
|
+
className: "animate-spin text-action-primary-bg",
|
|
188
|
+
size: 16
|
|
189
|
+
}), /* @__PURE__ */ u("span", {
|
|
190
|
+
className: "text-sm text-text-secondary",
|
|
191
|
+
children: S("mesh.deploy.starting", "Starting deploy job…")
|
|
192
|
+
})]
|
|
193
|
+
})
|
|
194
|
+
}),
|
|
195
|
+
W?.status === "completed" && /* @__PURE__ */ u("div", {
|
|
196
|
+
className: "rounded-lg border border-status-success-border bg-status-success-bg-subtle p-3 text-sm text-status-success-text",
|
|
197
|
+
children: S("mesh.deploy.success", "Agent deployed successfully!")
|
|
198
|
+
}),
|
|
199
|
+
W?.status === "failed" && /* @__PURE__ */ u("div", {
|
|
200
|
+
className: "rounded-lg border border-status-error-border bg-status-error-bg-subtle p-3 text-sm text-status-error-text",
|
|
201
|
+
children: W.error ?? S("mesh.deploy.jobFailed", "Deploy failed.")
|
|
202
|
+
}),
|
|
203
|
+
/* @__PURE__ */ u("button", {
|
|
204
|
+
type: "button",
|
|
205
|
+
onClick: b,
|
|
206
|
+
disabled: $,
|
|
207
|
+
className: "w-full px-4 py-2 rounded-md border border-border-default hover:bg-bg-sunken transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-sm font-medium text-text-primary",
|
|
208
|
+
children: $ ? S("mesh.deploy.deployingShort", "Deploying…") : S("common.close", "Close")
|
|
209
|
+
})
|
|
210
|
+
]
|
|
211
|
+
}) : /* @__PURE__ */ d("div", {
|
|
212
|
+
className: "space-y-4",
|
|
213
|
+
children: [
|
|
214
|
+
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
|
|
215
|
+
className: g,
|
|
216
|
+
htmlFor: "mesh-source-agent",
|
|
217
|
+
children: S("mesh.deploy.sourceAgent", "Source agent (deploys from)")
|
|
218
|
+
}), /* @__PURE__ */ d("select", {
|
|
219
|
+
id: "mesh-source-agent",
|
|
220
|
+
value: C,
|
|
221
|
+
onChange: (e) => ie(e.target.value),
|
|
222
|
+
className: h,
|
|
223
|
+
children: [_.length === 0 && /* @__PURE__ */ u("option", {
|
|
224
|
+
value: "",
|
|
225
|
+
children: S("mesh.deploy.noAgents", "No agents available")
|
|
226
|
+
}), _.map((e) => /* @__PURE__ */ d("option", {
|
|
227
|
+
value: e.id,
|
|
228
|
+
children: [
|
|
229
|
+
e.name,
|
|
230
|
+
" (",
|
|
231
|
+
e.hostname,
|
|
232
|
+
")",
|
|
233
|
+
e.isActive ? "" : " · offline"
|
|
234
|
+
]
|
|
235
|
+
}, e.id))]
|
|
236
|
+
})] }),
|
|
237
|
+
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("span", {
|
|
238
|
+
className: g,
|
|
239
|
+
children: S("mesh.deploy.mode", "Deploy mode")
|
|
240
|
+
}), /* @__PURE__ */ d("div", {
|
|
241
|
+
className: "flex gap-2",
|
|
242
|
+
children: [/* @__PURE__ */ d("button", {
|
|
243
|
+
type: "button",
|
|
244
|
+
onClick: () => T("ssh"),
|
|
245
|
+
className: `flex-1 inline-flex items-center justify-center gap-2 px-3 py-2 text-sm rounded-md border transition-colors ${w === "ssh" ? "border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg" : "border-border-default text-text-secondary hover:bg-bg-sunken"}`,
|
|
246
|
+
children: [/* @__PURE__ */ u(ne, { size: 14 }), S("mesh.deploy.modeSsh", "Remote (SSH)")]
|
|
247
|
+
}), /* @__PURE__ */ d("button", {
|
|
248
|
+
type: "button",
|
|
249
|
+
onClick: () => T("same"),
|
|
250
|
+
className: `flex-1 inline-flex items-center justify-center gap-2 px-3 py-2 text-sm rounded-md border transition-colors ${w === "same" ? "border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg" : "border-border-default text-text-secondary hover:bg-bg-sunken"}`,
|
|
251
|
+
children: [/* @__PURE__ */ u(te, { size: 14 }), S("mesh.deploy.modeSame", "Same machine")]
|
|
252
|
+
})]
|
|
253
|
+
})] }),
|
|
254
|
+
w === "ssh" && /* @__PURE__ */ d("div", {
|
|
255
|
+
className: "space-y-3",
|
|
256
|
+
children: [
|
|
257
|
+
/* @__PURE__ */ d("div", {
|
|
258
|
+
className: "grid grid-cols-3 gap-2",
|
|
259
|
+
children: [/* @__PURE__ */ d("div", {
|
|
260
|
+
className: "col-span-2",
|
|
261
|
+
children: [/* @__PURE__ */ u("label", {
|
|
262
|
+
className: g,
|
|
263
|
+
htmlFor: "mesh-host",
|
|
264
|
+
children: S("mesh.deploy.host", "Host / alias")
|
|
265
|
+
}), /* @__PURE__ */ u("input", {
|
|
266
|
+
id: "mesh-host",
|
|
267
|
+
type: "text",
|
|
268
|
+
value: E,
|
|
269
|
+
onChange: (e) => D(e.target.value),
|
|
270
|
+
placeholder: "prod-web-01 or 10.0.0.5",
|
|
271
|
+
className: `${h} font-mono`
|
|
272
|
+
})]
|
|
273
|
+
}), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
|
|
274
|
+
className: g,
|
|
275
|
+
htmlFor: "mesh-port",
|
|
276
|
+
children: S("mesh.deploy.port", "Port")
|
|
277
|
+
}), /* @__PURE__ */ u("input", {
|
|
278
|
+
id: "mesh-port",
|
|
279
|
+
type: "number",
|
|
280
|
+
value: O,
|
|
281
|
+
onChange: (e) => k(Number(e.target.value) || 22),
|
|
282
|
+
className: h
|
|
283
|
+
})] })]
|
|
284
|
+
}),
|
|
285
|
+
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
|
|
286
|
+
className: g,
|
|
287
|
+
htmlFor: "mesh-user",
|
|
288
|
+
children: S("mesh.deploy.user", "User")
|
|
289
|
+
}), /* @__PURE__ */ u("input", {
|
|
290
|
+
id: "mesh-user",
|
|
291
|
+
type: "text",
|
|
292
|
+
value: A,
|
|
293
|
+
onChange: (e) => j(e.target.value),
|
|
294
|
+
placeholder: "root",
|
|
295
|
+
className: `${h} font-mono`
|
|
296
|
+
})] }),
|
|
297
|
+
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("span", {
|
|
298
|
+
className: g,
|
|
299
|
+
children: S("mesh.deploy.auth", "Authentication")
|
|
300
|
+
}), /* @__PURE__ */ d("div", {
|
|
301
|
+
className: "flex gap-4",
|
|
302
|
+
children: [/* @__PURE__ */ d("label", {
|
|
303
|
+
className: "inline-flex items-center gap-2 text-sm text-text-primary cursor-pointer",
|
|
304
|
+
children: [/* @__PURE__ */ u("input", {
|
|
305
|
+
type: "radio",
|
|
306
|
+
name: "mesh-auth",
|
|
307
|
+
checked: M === "agent",
|
|
308
|
+
onChange: () => N("agent")
|
|
309
|
+
}), S("mesh.deploy.authAgent", "SSH agent / default key")]
|
|
310
|
+
}), /* @__PURE__ */ d("label", {
|
|
311
|
+
className: "inline-flex items-center gap-2 text-sm text-text-primary cursor-pointer",
|
|
312
|
+
children: [/* @__PURE__ */ u("input", {
|
|
313
|
+
type: "radio",
|
|
314
|
+
name: "mesh-auth",
|
|
315
|
+
checked: M === "key",
|
|
316
|
+
onChange: () => N("key")
|
|
317
|
+
}), S("mesh.deploy.authKey", "Key path")]
|
|
318
|
+
})]
|
|
319
|
+
})] }),
|
|
320
|
+
M === "key" && /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
|
|
321
|
+
className: g,
|
|
322
|
+
htmlFor: "mesh-key",
|
|
323
|
+
children: S("mesh.deploy.keyPath", "Identity file (key path)")
|
|
324
|
+
}), /* @__PURE__ */ u("input", {
|
|
325
|
+
id: "mesh-key",
|
|
326
|
+
type: "text",
|
|
327
|
+
value: P,
|
|
328
|
+
onChange: (e) => F(e.target.value),
|
|
329
|
+
placeholder: "~/.ssh/id_ed25519",
|
|
330
|
+
className: `${h} font-mono`
|
|
331
|
+
})] })
|
|
332
|
+
]
|
|
333
|
+
}),
|
|
334
|
+
/* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("label", {
|
|
335
|
+
className: g,
|
|
336
|
+
htmlFor: "mesh-label",
|
|
337
|
+
children: S("mesh.deploy.label", "Label (optional)")
|
|
338
|
+
}), /* @__PURE__ */ u("input", {
|
|
339
|
+
id: "mesh-label",
|
|
340
|
+
type: "text",
|
|
341
|
+
value: I,
|
|
342
|
+
onChange: (e) => L(e.target.value),
|
|
343
|
+
placeholder: S("mesh.deploy.labelPlaceholder", "e.g. Production web tier"),
|
|
344
|
+
className: h
|
|
345
|
+
})] }),
|
|
346
|
+
y && y.length > 0 && /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("span", {
|
|
347
|
+
className: g,
|
|
348
|
+
children: S("mesh.deploy.permissions", "Grant permissions on the new link")
|
|
349
|
+
}), /* @__PURE__ */ u("div", {
|
|
350
|
+
className: "flex flex-wrap gap-2",
|
|
351
|
+
children: y.map((e) => /* @__PURE__ */ u("button", {
|
|
352
|
+
type: "button",
|
|
353
|
+
onClick: () => ae(e),
|
|
354
|
+
className: `px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${B.has(e) ? "border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg" : "border-border-default text-text-secondary hover:bg-bg-sunken"}`,
|
|
355
|
+
children: e
|
|
356
|
+
}, e))
|
|
357
|
+
})] }),
|
|
358
|
+
/* @__PURE__ */ d("label", {
|
|
359
|
+
className: "flex items-center gap-2 text-sm text-text-primary cursor-pointer",
|
|
360
|
+
children: [/* @__PURE__ */ u("input", {
|
|
361
|
+
type: "checkbox",
|
|
362
|
+
checked: R,
|
|
363
|
+
onChange: (e) => z(e.target.checked)
|
|
364
|
+
}), S("mesh.deploy.connectExisting", "Connect to an existing agent on the target instead of installing")]
|
|
365
|
+
}),
|
|
366
|
+
K && /* @__PURE__ */ u("div", {
|
|
367
|
+
className: "rounded-lg border border-status-error-border bg-status-error-bg-subtle p-3 text-sm text-status-error-text",
|
|
368
|
+
children: K
|
|
369
|
+
}),
|
|
370
|
+
/* @__PURE__ */ d("div", {
|
|
371
|
+
className: "flex justify-end gap-2 pt-2 border-t border-border-default",
|
|
372
|
+
children: [/* @__PURE__ */ u("button", {
|
|
373
|
+
type: "button",
|
|
374
|
+
onClick: b,
|
|
375
|
+
className: "px-4 py-2 text-sm rounded-lg border border-border-default hover:bg-bg-sunken text-text-primary",
|
|
376
|
+
children: S("common.cancel", "Cancel")
|
|
377
|
+
}), /* @__PURE__ */ d("button", {
|
|
378
|
+
type: "button",
|
|
379
|
+
onClick: () => void oe(),
|
|
380
|
+
disabled: !Z || Y,
|
|
381
|
+
className: "inline-flex items-center gap-2 px-4 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg-hover disabled:opacity-50",
|
|
382
|
+
children: [Y ? /* @__PURE__ */ u(c, { className: "size-4 animate-spin" }) : null, S("mesh.deploy.submit", "Deploy")]
|
|
383
|
+
})]
|
|
384
|
+
})
|
|
385
|
+
]
|
|
386
|
+
})]
|
|
387
|
+
})]
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
//#endregion
|
|
391
|
+
export { _ as MeshDeployWizard };
|
|
392
|
+
|
|
393
|
+
//# sourceMappingURL=MeshDeployWizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MeshDeployWizard.js","names":[],"sources":["../../../src/components/graph/MeshDeployWizard.tsx"],"sourcesContent":["/**\n * MeshDeployWizard — deploy a new agent THROUGH the mesh from a chosen source\n * (root) agent. Supports two modes:\n * - \"Remote (SSH)\": deploy onto another machine over SSH (host/user/port/key).\n * - \"Same machine\": deploy a sibling agent on the source agent's own host.\n *\n * Submitting calls `deployAgentViaMesh({ rootAgentId, input })`, reads the\n * `{ jobId }` out of the AgentProxyResponse, then polls\n * `meshDeployJobStatus(rootAgentId, jobId)` on a 2s interval, rendering the\n * job's step list in a progress panel. On completion it calls `onCompleted`\n * so the caller can refetch the mesh graph.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { X, Loader2, CheckCircle, XCircle, Check, Server, Laptop } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport {\n useDeployAgentViaMeshMutation,\n useMeshDeployJobStatusLazyQuery,\n} from '@/generated/wspace-operations';\n\n// Step labels for the mesh-deploy job. Extends the install-job labels with the\n// mesh-specific bootstrap/onboard/peer-probe steps.\nconst stepLabels: Record<string, string> = {\n probe: 'Probing target',\n 'install-bun': 'Installing Bun runtime',\n 'install-agent': 'Installing VibeControls Agent',\n autostart: 'Configuring autostart',\n plugins: 'Installing plugins',\n start: 'Starting agent',\n bootstrap: 'Bootstrapping tunnel',\n onboard: 'Onboarding agent',\n 'store-creds': 'Storing credentials',\n 'report-link': 'Linking into mesh',\n 'probe-peer': 'Probing new peer',\n};\n\ninterface DeployJobStep {\n step: string;\n status: string;\n message?: string;\n}\n\ninterface DeployJob {\n status: 'running' | 'completed' | 'failed' | string;\n steps: DeployJobStep[];\n error?: string;\n}\n\ninterface SourceAgentOption {\n id: string;\n name: string;\n hostname: string;\n isActive: boolean;\n}\n\ninterface MeshDeployWizardProps {\n /** Agents that can act as the deploying root. */\n sourceAgents: SourceAgentOption[];\n /** Pre-seeded source (root) agent id (e.g. \"deploy from here\" on a node). */\n initialSourceAgentId?: string | null;\n availablePermissions?: string[];\n onClose: () => void;\n onCompleted: () => void;\n}\n\ntype DeployMode = 'ssh' | 'same';\ntype AuthMethod = 'agent' | 'key';\n\nfunction asRecord(v: unknown): Record<string, unknown> | null {\n return v && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : null;\n}\nfunction jstr(obj: Record<string, unknown> | null, key: string): string | null {\n const v = obj?.[key];\n return typeof v === 'string' ? v : null;\n}\n\nconst INPUT_CLASS =\n 'px-3 py-2 text-sm rounded-md bg-bg-sunken border border-border-default text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/40 w-full';\nconst LABEL_CLASS = 'text-xs font-medium text-text-secondary mb-1 block';\n\nexport function MeshDeployWizard({\n sourceAgents,\n initialSourceAgentId,\n availablePermissions,\n onClose,\n onCompleted,\n}: MeshDeployWizardProps) {\n const tr = useTr();\n\n const [sourceAgentId, setSourceAgentId] = useState<string>(\n initialSourceAgentId ?? sourceAgents[0]?.id ?? ''\n );\n const [mode, setMode] = useState<DeployMode>('ssh');\n const [host, setHost] = useState('');\n const [port, setPort] = useState(22);\n const [user, setUser] = useState('');\n const [authMethod, setAuthMethod] = useState<AuthMethod>('agent');\n const [keyPath, setKeyPath] = useState('');\n const [label, setLabel] = useState('');\n const [connectExisting, setConnectExisting] = useState(false);\n const [permissions, setPermissions] = useState<Set<string>>(new Set());\n\n const [jobId, setJobId] = useState<string | null>(null);\n const [job, setJob] = useState<DeployJob | null>(null);\n const [submitError, setSubmitError] = useState<string | null>(null);\n\n const [deploy, { loading: deploying }] = useDeployAgentViaMeshMutation();\n const [fetchJobStatus] = useMeshDeployJobStatusLazyQuery({ fetchPolicy: 'network-only' });\n\n const canSubmit = useMemo(() => {\n if (!sourceAgentId) return false;\n if (mode === 'ssh') {\n const targetSpec = host.trim();\n return targetSpec.length > 0 && user.trim().length > 0;\n }\n return true;\n }, [sourceAgentId, mode, host, user]);\n\n const togglePermission = useCallback((p: string) => {\n setPermissions((prev) => {\n const next = new Set(prev);\n if (next.has(p)) next.delete(p);\n else next.add(p);\n return next;\n });\n }, []);\n\n // Build the SSH `target` string the backend expects (user@host:port).\n const buildTargetString = useCallback((): string => {\n if (mode === 'same') return 'localhost';\n const trimmedHost = host.trim();\n const trimmedUser = user.trim();\n const base = trimmedUser ? `${trimmedUser}@${trimmedHost}` : trimmedHost;\n return port && port !== 22 ? `${base}:${port}` : base;\n }, [mode, host, user, port]);\n\n const handleSubmit = useCallback(async () => {\n if (!canSubmit) return;\n setSubmitError(null);\n setJob(null);\n setJobId(null);\n try {\n const res = await deploy({\n variables: {\n rootAgentId: sourceAgentId,\n input: {\n target: buildTargetString(),\n permissions: permissions.size > 0 ? Array.from(permissions) : undefined,\n identityFile: mode === 'ssh' && authMethod === 'key' ? keyPath || undefined : undefined,\n label: label || undefined,\n connectExisting,\n },\n },\n });\n const proxy = res.data?.deployAgentViaMesh;\n if (res.error || proxy?.error || proxy?.ok === false) {\n setSubmitError(\n proxy?.error ?? res.error?.message ?? tr('mesh.deploy.failed', 'Deploy failed')\n );\n return;\n }\n const data = asRecord(proxy?.data);\n const newJobId = jstr(data, 'jobId');\n if (!newJobId) {\n setSubmitError(\n tr('mesh.deploy.noJob', 'Deploy started but no job id was returned by the agent.')\n );\n return;\n }\n setJobId(newJobId);\n setJob({ status: jstr(data, 'status') ?? 'running', steps: [] });\n } catch (err) {\n setSubmitError(err instanceof Error ? err.message : String(err));\n }\n }, [\n canSubmit,\n deploy,\n sourceAgentId,\n buildTargetString,\n permissions,\n mode,\n authMethod,\n keyPath,\n label,\n connectExisting,\n tr,\n ]);\n\n // Poll the mesh-deploy job once a jobId is established.\n useEffect(() => {\n if (!jobId || !sourceAgentId) return;\n let cancelled = false;\n\n const poll = () => {\n void fetchJobStatus({ variables: { rootAgentId: sourceAgentId, jobId } })\n .then((result) => {\n if (cancelled) return;\n const proxy = result.data?.meshDeployJobStatus;\n const data = asRecord(proxy?.data);\n if (!data) return;\n const rawSteps = Array.isArray(data.steps) ? (data.steps as DeployJobStep[]) : [];\n setJob({\n status: jstr(data, 'status') ?? 'running',\n steps: rawSteps,\n error: jstr(data, 'error') ?? proxy?.error ?? undefined,\n });\n const status = jstr(data, 'status');\n if (status === 'completed') {\n onCompleted();\n }\n })\n .catch(() => {\n // transient — retry on next interval\n });\n };\n\n poll();\n const interval = setInterval(poll, 2000);\n return () => {\n cancelled = true;\n clearInterval(interval);\n };\n }, [jobId, sourceAgentId, fetchJobStatus, onCompleted]);\n\n const jobRunning =\n job?.status === 'running' ||\n (jobId !== null && job?.status !== 'completed' && job?.status !== 'failed');\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n role=\"button\"\n tabIndex={0}\n aria-label={tr('mesh.deploy.close', 'Close')}\n className=\"fixed inset-0 bg-bg-overlay backdrop-blur-sm\"\n onClick={!jobRunning ? onClose : undefined}\n onKeyDown={(e) => {\n if (!jobRunning && (e.key === 'Escape' || e.key === 'Enter')) onClose();\n }}\n />\n <div className=\"relative bg-bg-surface rounded-xl shadow-2xl border border-border-default max-w-lg w-full mx-4 p-6 max-h-[90vh] overflow-auto\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('mesh.deploy.title', 'Deploy Agent via Mesh')}\n </h2>\n {!jobRunning && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 rounded-lg hover:bg-bg-sunken\"\n aria-label={tr('mesh.deploy.close', 'Close')}\n >\n <X size={18} />\n </button>\n )}\n </div>\n\n {/* Job progress takes over once a job is running */}\n {jobId ? (\n <div className=\"space-y-3\">\n <p className=\"text-sm text-text-secondary\">\n {tr('mesh.deploy.deploying', 'Deploying through {{agent}}…', {\n agent: sourceAgents.find((a) => a.id === sourceAgentId)?.name ?? 'agent',\n })}\n </p>\n <div className=\"space-y-2\">\n {job && job.steps.length > 0 ? (\n job.steps.map((step, idx) => (\n <div key={`${step.step}-${idx}`} className=\"flex items-center gap-3\">\n {step.status === 'running' && (\n <Loader2 className=\"animate-spin text-action-primary-bg\" size={16} />\n )}\n {step.status === 'completed' && (\n <CheckCircle className=\"text-status-success-text\" size={16} />\n )}\n {step.status === 'failed' && (\n <XCircle className=\"text-status-error-text\" size={16} />\n )}\n {step.status === 'skipped' && (\n <Check className=\"text-text-tertiary\" size={16} />\n )}\n {step.status === 'pending' && (\n <div className=\"size-4 rounded-full border-2 border-border-default\" />\n )}\n <div>\n <div className=\"text-sm font-medium text-text-primary\">\n {tr(`mesh.deploy.step.${step.step}`, stepLabels[step.step] ?? step.step)}\n </div>\n {step.message ? (\n <div className=\"text-xs text-text-tertiary\">{step.message}</div>\n ) : null}\n </div>\n </div>\n ))\n ) : (\n <div className=\"flex items-center gap-3\">\n <Loader2 className=\"animate-spin text-action-primary-bg\" size={16} />\n <span className=\"text-sm text-text-secondary\">\n {tr('mesh.deploy.starting', 'Starting deploy job…')}\n </span>\n </div>\n )}\n </div>\n\n {job?.status === 'completed' && (\n <div className=\"rounded-lg border border-status-success-border bg-status-success-bg-subtle p-3 text-sm text-status-success-text\">\n {tr('mesh.deploy.success', 'Agent deployed successfully!')}\n </div>\n )}\n {job?.status === 'failed' && (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle p-3 text-sm text-status-error-text\">\n {job.error ?? tr('mesh.deploy.jobFailed', 'Deploy failed.')}\n </div>\n )}\n\n <button\n type=\"button\"\n onClick={onClose}\n disabled={jobRunning}\n className=\"w-full px-4 py-2 rounded-md border border-border-default hover:bg-bg-sunken transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-sm font-medium text-text-primary\"\n >\n {jobRunning\n ? tr('mesh.deploy.deployingShort', 'Deploying…')\n : tr('common.close', 'Close')}\n </button>\n </div>\n ) : (\n <div className=\"space-y-4\">\n {/* Source agent */}\n <div>\n <label className={LABEL_CLASS} htmlFor=\"mesh-source-agent\">\n {tr('mesh.deploy.sourceAgent', 'Source agent (deploys from)')}\n </label>\n <select\n id=\"mesh-source-agent\"\n value={sourceAgentId}\n onChange={(e) => setSourceAgentId(e.target.value)}\n className={INPUT_CLASS}\n >\n {sourceAgents.length === 0 && (\n <option value=\"\">{tr('mesh.deploy.noAgents', 'No agents available')}</option>\n )}\n {sourceAgents.map((a) => (\n <option key={a.id} value={a.id}>\n {a.name} ({a.hostname}){a.isActive ? '' : ' · offline'}\n </option>\n ))}\n </select>\n </div>\n\n {/* Mode toggle */}\n <div>\n <span className={LABEL_CLASS}>{tr('mesh.deploy.mode', 'Deploy mode')}</span>\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => setMode('ssh')}\n className={`flex-1 inline-flex items-center justify-center gap-2 px-3 py-2 text-sm rounded-md border transition-colors ${\n mode === 'ssh'\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default text-text-secondary hover:bg-bg-sunken'\n }`}\n >\n <Server size={14} />\n {tr('mesh.deploy.modeSsh', 'Remote (SSH)')}\n </button>\n <button\n type=\"button\"\n onClick={() => setMode('same')}\n className={`flex-1 inline-flex items-center justify-center gap-2 px-3 py-2 text-sm rounded-md border transition-colors ${\n mode === 'same'\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default text-text-secondary hover:bg-bg-sunken'\n }`}\n >\n <Laptop size={14} />\n {tr('mesh.deploy.modeSame', 'Same machine')}\n </button>\n </div>\n </div>\n\n {/* SSH fields */}\n {mode === 'ssh' && (\n <div className=\"space-y-3\">\n <div className=\"grid grid-cols-3 gap-2\">\n <div className=\"col-span-2\">\n <label className={LABEL_CLASS} htmlFor=\"mesh-host\">\n {tr('mesh.deploy.host', 'Host / alias')}\n </label>\n <input\n id=\"mesh-host\"\n type=\"text\"\n value={host}\n onChange={(e) => setHost(e.target.value)}\n placeholder=\"prod-web-01 or 10.0.0.5\"\n className={`${INPUT_CLASS} font-mono`}\n />\n </div>\n <div>\n <label className={LABEL_CLASS} htmlFor=\"mesh-port\">\n {tr('mesh.deploy.port', 'Port')}\n </label>\n <input\n id=\"mesh-port\"\n type=\"number\"\n value={port}\n onChange={(e) => setPort(Number(e.target.value) || 22)}\n className={INPUT_CLASS}\n />\n </div>\n </div>\n <div>\n <label className={LABEL_CLASS} htmlFor=\"mesh-user\">\n {tr('mesh.deploy.user', 'User')}\n </label>\n <input\n id=\"mesh-user\"\n type=\"text\"\n value={user}\n onChange={(e) => setUser(e.target.value)}\n placeholder=\"root\"\n className={`${INPUT_CLASS} font-mono`}\n />\n </div>\n <div>\n <span className={LABEL_CLASS}>{tr('mesh.deploy.auth', 'Authentication')}</span>\n <div className=\"flex gap-4\">\n <label className=\"inline-flex items-center gap-2 text-sm text-text-primary cursor-pointer\">\n <input\n type=\"radio\"\n name=\"mesh-auth\"\n checked={authMethod === 'agent'}\n onChange={() => setAuthMethod('agent')}\n />\n {tr('mesh.deploy.authAgent', 'SSH agent / default key')}\n </label>\n <label className=\"inline-flex items-center gap-2 text-sm text-text-primary cursor-pointer\">\n <input\n type=\"radio\"\n name=\"mesh-auth\"\n checked={authMethod === 'key'}\n onChange={() => setAuthMethod('key')}\n />\n {tr('mesh.deploy.authKey', 'Key path')}\n </label>\n </div>\n </div>\n {authMethod === 'key' && (\n <div>\n <label className={LABEL_CLASS} htmlFor=\"mesh-key\">\n {tr('mesh.deploy.keyPath', 'Identity file (key path)')}\n </label>\n <input\n id=\"mesh-key\"\n type=\"text\"\n value={keyPath}\n onChange={(e) => setKeyPath(e.target.value)}\n placeholder=\"~/.ssh/id_ed25519\"\n className={`${INPUT_CLASS} font-mono`}\n />\n </div>\n )}\n </div>\n )}\n\n {/* Label */}\n <div>\n <label className={LABEL_CLASS} htmlFor=\"mesh-label\">\n {tr('mesh.deploy.label', 'Label (optional)')}\n </label>\n <input\n id=\"mesh-label\"\n type=\"text\"\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n placeholder={tr('mesh.deploy.labelPlaceholder', 'e.g. Production web tier')}\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Permission chips */}\n {availablePermissions && availablePermissions.length > 0 && (\n <div>\n <span className={LABEL_CLASS}>\n {tr('mesh.deploy.permissions', 'Grant permissions on the new link')}\n </span>\n <div className=\"flex flex-wrap gap-2\">\n {availablePermissions.map((p) => (\n <button\n type=\"button\"\n key={p}\n onClick={() => togglePermission(p)}\n className={`px-3 py-1.5 text-xs font-medium rounded-lg border transition-colors ${\n permissions.has(p)\n ? 'border-action-primary-bg bg-action-primary-bg/10 text-action-primary-bg'\n : 'border-border-default text-text-secondary hover:bg-bg-sunken'\n }`}\n >\n {p}\n </button>\n ))}\n </div>\n </div>\n )}\n\n <label className=\"flex items-center gap-2 text-sm text-text-primary cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={connectExisting}\n onChange={(e) => setConnectExisting(e.target.checked)}\n />\n {tr(\n 'mesh.deploy.connectExisting',\n 'Connect to an existing agent on the target instead of installing'\n )}\n </label>\n\n {submitError && (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle p-3 text-sm text-status-error-text\">\n {submitError}\n </div>\n )}\n\n <div className=\"flex justify-end gap-2 pt-2 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm rounded-lg border border-border-default hover:bg-bg-sunken text-text-primary\"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleSubmit()}\n disabled={!canSubmit || deploying}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg-hover disabled:opacity-50\"\n >\n {deploying ? <Loader2 className=\"size-4 animate-spin\" /> : null}\n {tr('mesh.deploy.submit', 'Deploy')}\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|