@burdenoff/microfe-vibecontrols 2026.709.1 → 2026.709.2
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/pages/AgentsPage.js +263 -263
- package/dist/pages/AgentsPage.js.map +1 -1
- package/package.json +1 -1
package/dist/pages/AgentsPage.js
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { useAddAgentFromTunnelMutation as e, useAgentHeartbeatMutation as t, useCreateAgentMutation as n, useCreateTargetMutation as r, useDeactivateAgentMutation as i, useDeleteAgentMutation as ee, useListAgentsQuery as te, useListTargetsQuery as ne, useSetupAgentGatewayAuthMutation as re, useStartVibecontrolsAgentMutation as ie, useStopVibecontrolsAgentMutation as ae, useUpdateAgentMutation as oe,
|
|
2
|
-
import { useTr as
|
|
3
|
-
import { ConfirmDialog as
|
|
4
|
-
import { QuotaExhaustedDialog as
|
|
5
|
-
import { getQuotaDialogContent as
|
|
6
|
-
import { useVibeControls as
|
|
1
|
+
import { useAddAgentFromTunnelMutation as e, useAgentHeartbeatMutation as t, useCreateAgentMutation as n, useCreateTargetMutation as r, useDeactivateAgentMutation as i, useDeleteAgentMutation as ee, useListAgentsQuery as te, useListTargetsQuery as ne, useSetupAgentGatewayAuthMutation as re, useStartVibecontrolsAgentMutation as ie, useStopVibecontrolsAgentMutation as ae, useUpdateAgentMutation as oe, useVibecontrolsAgentHealthProbesLazyQuery as se, useVibecontrolsAgentHealthProbesQuery as ce } from "../generated/wspace-operations.js";
|
|
2
|
+
import { useTr as le } from "../shared/hooks/useTr.js";
|
|
3
|
+
import { ConfirmDialog as ue } from "../components/shared/ConfirmDialog.js";
|
|
4
|
+
import { QuotaExhaustedDialog as de } from "../components/shared/QuotaExhaustedDialog.js";
|
|
5
|
+
import { getQuotaDialogContent as fe, isQuotaExhaustedError as a, markQuotaHandledLocally as o } from "../utils/quotaUtils.js";
|
|
6
|
+
import { useVibeControls as pe, useVibeNavigate as me } from "../providers/VibeControlsProvider.js";
|
|
7
7
|
import { useVibeControlsStore as s } from "../store/vibeControlsStore.js";
|
|
8
|
-
import
|
|
9
|
-
import { PageHeader as
|
|
10
|
-
import { LoadingState as
|
|
11
|
-
import { ErrorState as
|
|
12
|
-
import { EntityTagPicker as
|
|
13
|
-
import { useDraftEntityTags as
|
|
14
|
-
import { EmptyState as
|
|
15
|
-
import { SearchInput as
|
|
16
|
-
import { FilterDropdown as
|
|
17
|
-
import { AgentSetupBanner as
|
|
18
|
-
import { GetHelpButton as
|
|
19
|
-
import { useField as
|
|
20
|
-
import { TagFilter as
|
|
8
|
+
import he from "../hooks/useCachedInitialData.js";
|
|
9
|
+
import { PageHeader as ge } from "../components/shared/PageHeader.js";
|
|
10
|
+
import { LoadingState as _e } from "../components/shared/LoadingState.js";
|
|
11
|
+
import { ErrorState as ve } from "../components/shared/ErrorState.js";
|
|
12
|
+
import { EntityTagPicker as ye } from "../components/shared/EntityTagPicker.js";
|
|
13
|
+
import { useDraftEntityTags as be } from "../hooks/useDraftEntityTags.js";
|
|
14
|
+
import { EmptyState as xe } from "../components/shared/EmptyState.js";
|
|
15
|
+
import { SearchInput as Se } from "../components/shared/SearchInput.js";
|
|
16
|
+
import { FilterDropdown as Ce } from "../components/shared/FilterDropdown.js";
|
|
17
|
+
import { AgentSetupBanner as we } from "../components/shared/AgentSetupBanner.js";
|
|
18
|
+
import { GetHelpButton as Te } from "../components/shared/GetHelpButton.js";
|
|
19
|
+
import { useField as Ee } from "../shared/hooks/useField.js";
|
|
20
|
+
import { TagFilter as De } from "../components/shared/TagFilter.js";
|
|
21
21
|
import "../components/shared/index.js";
|
|
22
|
-
import { VIBE_PERMISSIONS as
|
|
23
|
-
import { PageSkeleton as
|
|
22
|
+
import { VIBE_PERMISSIONS as Oe } from "../constants/permissions.js";
|
|
23
|
+
import { PageSkeleton as ke } from "../components/shared/PageSkeleton.js";
|
|
24
24
|
import { notify as c } from "../lib/toast.js";
|
|
25
|
-
import { AgentCard as
|
|
26
|
-
import { AgentList as
|
|
27
|
-
import { AgentForm as
|
|
25
|
+
import { AgentCard as Ae } from "../components/agents/AgentCard.js";
|
|
26
|
+
import { AgentList as je } from "../components/agents/AgentList.js";
|
|
27
|
+
import { AgentForm as Me } from "../components/agents/AgentForm.js";
|
|
28
28
|
import "../components/agents/index.js";
|
|
29
|
-
import { deriveAgentStatus as
|
|
30
|
-
import { useCallback as l, useEffect as u, useMemo as d, useRef as
|
|
31
|
-
import { Bot as
|
|
32
|
-
import { useSearchParams as
|
|
33
|
-
import { usePermissions as
|
|
34
|
-
import { AnimatePresence as
|
|
29
|
+
import { deriveAgentStatus as Ne } from "../utils/agentStatus.js";
|
|
30
|
+
import { useCallback as l, useEffect as u, useMemo as d, useRef as Pe, useState as f } from "react";
|
|
31
|
+
import { Bot as Fe, CheckSquare as Ie, Grid as Le, List as Re, Plus as p, RefreshCw as ze, Trash2 as Be, XSquare as Ve } from "lucide-react";
|
|
32
|
+
import { useSearchParams as He } from "react-router-dom";
|
|
33
|
+
import { usePermissions as Ue } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
34
|
+
import { AnimatePresence as We } from "framer-motion";
|
|
35
35
|
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
36
|
-
import { Button as
|
|
37
|
-
import { useEventBus as
|
|
38
|
-
import { AccessDenied as
|
|
39
|
-
import { MotionItem as
|
|
36
|
+
import { Button as Ge, Input as Ke, PagePurpose as qe, ResponsiveDialog as Je, ResponsiveDialogContent as Ye, ResponsiveDialogDescription as Xe, ResponsiveDialogFooter as Ze, ResponsiveDialogHeader as Qe, ResponsiveDialogTitle as $e } from "@burdenoff/fe-libs/ui";
|
|
37
|
+
import { useEventBus as et } from "@burdenoff/fe-libs/shared/events";
|
|
38
|
+
import { AccessDenied as tt, PermissionButton as nt } from "@burdenoff/fe-libs/shared/components";
|
|
39
|
+
import { MotionItem as rt, MotionList as it, MotionPage as g } from "@burdenoff/fe-libs/shared/motion";
|
|
40
40
|
//#region src/pages/AgentsPage.tsx
|
|
41
|
-
function
|
|
42
|
-
let { onAgentSelect:
|
|
41
|
+
function at() {
|
|
42
|
+
let { onAgentSelect: at, workspaceId: _ } = pe(), v = me(), y = et(), { hasPermission: ot, isLoading: st, permissions: ct } = Ue(), b = le(), lt = [
|
|
43
43
|
{
|
|
44
44
|
value: "all",
|
|
45
45
|
label: b("agentsPage.statusAll", "All Statuses")
|
|
@@ -56,7 +56,7 @@ function ot() {
|
|
|
56
56
|
value: "OFFLINE",
|
|
57
57
|
label: b("agentsPage.statusOffline", "Offline")
|
|
58
58
|
}
|
|
59
|
-
],
|
|
59
|
+
], ut = [
|
|
60
60
|
{
|
|
61
61
|
value: "all",
|
|
62
62
|
label: b("agentsPage.platformAll", "All Platforms")
|
|
@@ -73,31 +73,31 @@ function ot() {
|
|
|
73
73
|
value: "windows",
|
|
74
74
|
label: b("agentsPage.platformWindows", "Windows")
|
|
75
75
|
}
|
|
76
|
-
],
|
|
76
|
+
], dt = ot(Oe.AGENT_LIST), [x, ft] = f(""), [S, pt] = f("all"), [C, mt] = f("all"), [w, ht] = f("all"), [T, E] = f("grid"), [gt, D] = f(!1), [_t, vt] = f(!1), [O, yt] = He();
|
|
77
77
|
u(() => {
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
let e = new URLSearchParams(
|
|
81
|
-
e.delete("create"),
|
|
78
|
+
if (O.get("create") === "true") {
|
|
79
|
+
D(!0);
|
|
80
|
+
let e = new URLSearchParams(O);
|
|
81
|
+
e.delete("create"), yt(e, { replace: !0 });
|
|
82
82
|
}
|
|
83
|
-
}, [
|
|
84
|
-
let [
|
|
83
|
+
}, [O, yt]);
|
|
84
|
+
let [k, A] = f(null), [j, bt] = f(!1), M = s((e) => e.connectingAgents), xt = s((e) => e.markAgentConnecting), N = s((e) => e.clearAgentConnecting), St = d(() => new Set(Object.keys(M)), [M]), Ct = Pe(/* @__PURE__ */ new Map());
|
|
85
85
|
u(() => {
|
|
86
|
-
let e =
|
|
87
|
-
for (let t of Object.keys(
|
|
86
|
+
let e = Ct.current;
|
|
87
|
+
for (let t of Object.keys(M)) {
|
|
88
88
|
if (e.has(t)) continue;
|
|
89
89
|
let n = setTimeout(() => {
|
|
90
|
-
|
|
90
|
+
N(t), e.delete(t);
|
|
91
91
|
}, 3e4);
|
|
92
92
|
e.set(t, n);
|
|
93
93
|
}
|
|
94
|
-
for (let [t, n] of e.entries()) t in
|
|
94
|
+
for (let [t, n] of e.entries()) t in M || (clearTimeout(n), e.delete(t));
|
|
95
95
|
return () => {
|
|
96
96
|
for (let t of e.values()) clearTimeout(t);
|
|
97
97
|
e.clear();
|
|
98
98
|
};
|
|
99
|
-
}, [
|
|
100
|
-
let [
|
|
99
|
+
}, [M, N]);
|
|
100
|
+
let [P, F] = f(null), [wt, I] = f(!1), Tt = Pe(null), L = Ee({ hint: b("agentsPage.tunnelUrlHint", "Leave empty to clear. Agents with auto-tunnel report this automatically on startup.") }), [R, z] = f(/* @__PURE__ */ new Set()), [B, V] = f(!1), [Et, H] = f(!1), [U, W] = f(null), [Dt] = n({ refetchQueries: ["ListAgents"] }), { setDraftTagIds: Ot, flushTags: kt } = be("VIBECONTROLS_AGENT"), [At] = e({ refetchQueries: ["ListAgents"] }), [jt] = t({ refetchQueries: ["ListAgents"] }), [Mt] = i({ refetchQueries: ["ListAgents"] }), [Nt] = ie({ refetchQueries: ["ListAgents"] }), [Pt] = ae({ refetchQueries: ["ListAgents"] }), [Ft] = re({ refetchQueries: ["ListAgents"] }), { refetch: It } = he(), { data: Lt, loading: Rt, refetch: zt } = ne({
|
|
101
101
|
variables: {
|
|
102
102
|
workspaceId: _ ?? "",
|
|
103
103
|
limit: 50,
|
|
@@ -105,37 +105,37 @@ function ot() {
|
|
|
105
105
|
},
|
|
106
106
|
skip: !_,
|
|
107
107
|
fetchPolicy: "cache-and-network"
|
|
108
|
-
}),
|
|
108
|
+
}), Bt = Lt?.targets?.items ?? [], Vt = Bt.length > 0, [Ht] = oe({ refetchQueries: ["ListAgents"] }), [Ut] = ee({ refetchQueries: ["ListAgents"] }), [Wt] = r({
|
|
109
109
|
refetchQueries: ["VibeControlsInitialData", "ListTargets"],
|
|
110
110
|
awaitRefetchQueries: !0
|
|
111
|
-
}),
|
|
111
|
+
}), Gt = l(async (e) => {
|
|
112
112
|
if (!_ || !e.trim()) return null;
|
|
113
113
|
try {
|
|
114
|
-
let t = await
|
|
114
|
+
let t = await Wt({ variables: {
|
|
115
115
|
workspaceId: _,
|
|
116
116
|
input: {
|
|
117
117
|
type: "DIRECT",
|
|
118
118
|
name: e.trim()
|
|
119
119
|
}
|
|
120
120
|
} });
|
|
121
|
-
if (t.error && a(t.error)) throw o(),
|
|
121
|
+
if (t.error && a(t.error)) throw o(), W("target"), t.error;
|
|
122
122
|
let n = t.data?.createTarget;
|
|
123
|
-
return n ? (
|
|
123
|
+
return n ? (It(), zt(), {
|
|
124
124
|
id: n.id,
|
|
125
125
|
name: n.name,
|
|
126
126
|
type: n.type ?? "DIRECT",
|
|
127
127
|
status: n.status ?? "unknown"
|
|
128
128
|
}) : null;
|
|
129
129
|
} catch (e) {
|
|
130
|
-
if (a(e)) throw o(),
|
|
130
|
+
if (a(e)) throw o(), W("target"), e;
|
|
131
131
|
return null;
|
|
132
132
|
}
|
|
133
133
|
}, [
|
|
134
|
-
|
|
134
|
+
Wt,
|
|
135
|
+
It,
|
|
135
136
|
zt,
|
|
136
|
-
Ht,
|
|
137
137
|
_
|
|
138
|
-
]), { data:
|
|
138
|
+
]), { data: Kt, loading: G, error: qt, refetch: K } = te({
|
|
139
139
|
variables: {
|
|
140
140
|
filter: {
|
|
141
141
|
isActive: S === "ACTIVE" ? !0 : S === "OFFLINE" ? !1 : void 0,
|
|
@@ -145,26 +145,26 @@ function ot() {
|
|
|
145
145
|
},
|
|
146
146
|
fetchPolicy: "cache-first",
|
|
147
147
|
skip: !_
|
|
148
|
-
}), [
|
|
148
|
+
}), [Jt, Yt] = f(!1);
|
|
149
149
|
u(() => {
|
|
150
|
-
let e = window.setTimeout(() =>
|
|
150
|
+
let e = window.setTimeout(() => Yt(!0), 0);
|
|
151
151
|
return () => window.clearTimeout(e);
|
|
152
152
|
}, []);
|
|
153
|
-
let
|
|
153
|
+
let q = ce({
|
|
154
154
|
fetchPolicy: "cache-and-network",
|
|
155
155
|
nextFetchPolicy: "cache-first",
|
|
156
156
|
notifyOnNetworkStatusChange: !0,
|
|
157
|
-
skip: !_ || !
|
|
157
|
+
skip: !_ || !Jt,
|
|
158
158
|
pollInterval: 6e4
|
|
159
|
-
}), [
|
|
160
|
-
let e = /* @__PURE__ */ new Map(), t =
|
|
159
|
+
}), [Xt] = se({ fetchPolicy: "network-only" }), Zt = q.data === void 0, J = d(() => {
|
|
160
|
+
let e = /* @__PURE__ */ new Map(), t = q.data?.vibecontrolsAgentHealthProbes ?? [];
|
|
161
161
|
for (let n of t) e.set(n.agentId, {
|
|
162
162
|
agentId: n.agentId,
|
|
163
163
|
healthy: n.healthy,
|
|
164
164
|
errorMessage: n.errorMessage
|
|
165
165
|
});
|
|
166
166
|
return e;
|
|
167
|
-
}, [
|
|
167
|
+
}, [q.data]), Y = d(() => (Kt?.vibecontrolsAgents ?? []).map((e) => ({
|
|
168
168
|
id: e.id,
|
|
169
169
|
workspaceId: e.workspaceId,
|
|
170
170
|
name: e.name,
|
|
@@ -173,12 +173,12 @@ function ot() {
|
|
|
173
173
|
architecture: e.architecture,
|
|
174
174
|
version: e.version,
|
|
175
175
|
isActive: e.isActive,
|
|
176
|
-
status:
|
|
176
|
+
status: St.has(e.id) ? "CONNECTING" : Ne({
|
|
177
177
|
id: e.id,
|
|
178
178
|
isActive: e.isActive,
|
|
179
179
|
metadata: e.metadata
|
|
180
|
-
},
|
|
181
|
-
healthError:
|
|
180
|
+
}, J, { probesLoading: Zt }),
|
|
181
|
+
healthError: J.get(e.id)?.errorMessage ?? (e.lastGatewayAuthPushStatus === "failed" ? e.lastGatewayAuthPushError ?? "Gateway-auth push failed" : null),
|
|
182
182
|
lastHeartbeat: e.lastHeartbeat || null,
|
|
183
183
|
tunnelUrl: e.tunnelUrl ?? null,
|
|
184
184
|
tunnelStatus: e.tunnelStatus ?? null,
|
|
@@ -201,58 +201,58 @@ function ot() {
|
|
|
201
201
|
} : null
|
|
202
202
|
}))
|
|
203
203
|
})), [
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
Kt?.vibecontrolsAgents,
|
|
205
|
+
J,
|
|
206
|
+
Zt,
|
|
207
|
+
St
|
|
208
208
|
]);
|
|
209
209
|
u(() => {
|
|
210
|
-
let e = Object.keys(
|
|
210
|
+
let e = Object.keys(M);
|
|
211
211
|
if (e.length === 0) return;
|
|
212
212
|
let t = Date.now(), n = Infinity;
|
|
213
213
|
for (let r of e) {
|
|
214
|
-
let e =
|
|
215
|
-
e !== void 0 && (
|
|
214
|
+
let e = M[r];
|
|
215
|
+
e !== void 0 && (J.get(r)?.healthy === !0 && t >= e ? N(r) : e < n && (n = e));
|
|
216
216
|
}
|
|
217
217
|
if (n === Infinity) return;
|
|
218
218
|
let r = Math.max(0, n - t) + 50, i = setTimeout(() => {
|
|
219
219
|
let e = s.getState().connectingAgents;
|
|
220
220
|
for (let t of Object.keys(e)) {
|
|
221
221
|
let n = e[t];
|
|
222
|
-
n !== void 0 &&
|
|
222
|
+
n !== void 0 && J.get(t)?.healthy === !0 && Date.now() >= n && N(t);
|
|
223
223
|
}
|
|
224
224
|
}, r);
|
|
225
225
|
return () => clearTimeout(i);
|
|
226
226
|
}, [
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
227
|
+
J,
|
|
228
|
+
M,
|
|
229
|
+
N
|
|
230
230
|
]);
|
|
231
|
-
let
|
|
231
|
+
let X = d(() => Y.filter((e) => {
|
|
232
232
|
if (x) {
|
|
233
233
|
let t = x.toLowerCase();
|
|
234
234
|
if (!(e.name.toLowerCase().includes(t) || e.hostname?.toLowerCase().includes(t) || e.id.toLowerCase().includes(t))) return !1;
|
|
235
235
|
}
|
|
236
236
|
return !(w !== "all" && !(e.tagAssignments ?? []).some((e) => e.tagId === w));
|
|
237
237
|
}), [
|
|
238
|
-
|
|
238
|
+
Y,
|
|
239
239
|
x,
|
|
240
240
|
w
|
|
241
|
-
]),
|
|
242
|
-
v(`/agents/${e.id}`),
|
|
241
|
+
]), Qt = (e) => {
|
|
242
|
+
v(`/agents/${e.id}`), at?.({
|
|
243
243
|
id: e.id,
|
|
244
244
|
name: e.name,
|
|
245
245
|
type: e.platform || "unknown",
|
|
246
246
|
status: e.status || (e.isActive ? "ACTIVE" : "OFFLINE")
|
|
247
247
|
});
|
|
248
|
-
},
|
|
249
|
-
|
|
250
|
-
},
|
|
248
|
+
}, Z = () => {
|
|
249
|
+
D(!0), y.emitCustom("vibecontrols.agent.register_clicked", { workspaceId: _ ?? void 0 });
|
|
250
|
+
}, $t = async (e) => {
|
|
251
251
|
try {
|
|
252
|
-
|
|
252
|
+
vt(!0);
|
|
253
253
|
let t = e.tunnelUrl?.trim(), n = e.agentApiKey?.trim();
|
|
254
254
|
if (t && n) {
|
|
255
|
-
let r = await
|
|
255
|
+
let r = await At({ variables: { input: {
|
|
256
256
|
tunnelUrl: t,
|
|
257
257
|
apiKey: n,
|
|
258
258
|
...e.name ? { name: e.name } : {},
|
|
@@ -261,7 +261,7 @@ function ot() {
|
|
|
261
261
|
if (r.error) throw r.error;
|
|
262
262
|
let i = r.data?.addVibecontrolsAgentFromTunnel;
|
|
263
263
|
if (!i?.success) throw Error(i?.error || "Failed to onboard agent — probe or OAuth setup failed.");
|
|
264
|
-
if (i.agent?.id) return await
|
|
264
|
+
if (i.agent?.id) return await kt(i.agent.id), y.emitCustom("vibecontrols.agent.registered", {
|
|
265
265
|
workspaceId: _ ?? void 0,
|
|
266
266
|
agentId: i.agent.id
|
|
267
267
|
}), y.emitCustom("vibecontrols.agent.gateway_auth_setup", {
|
|
@@ -270,7 +270,7 @@ function ot() {
|
|
|
270
270
|
}), { id: i.agent.id };
|
|
271
271
|
throw Error("Agent onboarding returned no agent record.");
|
|
272
272
|
}
|
|
273
|
-
let r = await
|
|
273
|
+
let r = await Dt({ variables: { input: {
|
|
274
274
|
name: e.name,
|
|
275
275
|
hostname: e.hostname,
|
|
276
276
|
platform: e.platform,
|
|
@@ -280,69 +280,69 @@ function ot() {
|
|
|
280
280
|
...e.tunnelUrl ? { tunnelUrl: e.tunnelUrl } : {},
|
|
281
281
|
...e.tunnelStatus ? { tunnelStatus: e.tunnelStatus } : {}
|
|
282
282
|
} } }), i = r.data?.createVibecontrolsAgent;
|
|
283
|
-
if (i?.id) return await
|
|
283
|
+
if (i?.id) return await kt(i.id), y.emitCustom("vibecontrols.agent.registered", {
|
|
284
284
|
workspaceId: _ ?? void 0,
|
|
285
285
|
agentId: i.id
|
|
286
286
|
}), { id: i.id };
|
|
287
287
|
throw r.error ? r.error : Error("Agent creation failed — no data returned from the server.");
|
|
288
288
|
} catch (e) {
|
|
289
289
|
if (a(e)) {
|
|
290
|
-
o(),
|
|
290
|
+
o(), W("agent"), D(!1), y.emitCustom("vibecontrols.quota.agent_limit_hit", { workspaceId: _ ?? void 0 });
|
|
291
291
|
return;
|
|
292
292
|
}
|
|
293
293
|
throw console.error("Failed to create agent:", e), e;
|
|
294
294
|
} finally {
|
|
295
|
-
|
|
295
|
+
vt(!1);
|
|
296
296
|
}
|
|
297
|
-
},
|
|
297
|
+
}, en = async (e) => {
|
|
298
298
|
try {
|
|
299
|
-
let t = (await
|
|
299
|
+
let t = (await Nt({ variables: { agentId: e.id } })).data?.startVibecontrolsAgent;
|
|
300
300
|
if (!t?.success) {
|
|
301
301
|
if (/not yet configured|awaiting[-\s_]config/i.test(t?.error ?? "")) {
|
|
302
|
-
let t = (await
|
|
302
|
+
let t = (await Ft({ variables: { input: { agentId: e.id } } })).data?.setupAgentGatewayAuth;
|
|
303
303
|
if (t?.error) throw Error(`Agent needs credentials. Auto re-push failed: ${t.error}. Try "Re-push credentials" in Security tab.`);
|
|
304
304
|
if (!t) throw Error("Agent needs credentials. Auto re-push returned no result. Try \"Re-push credentials\" in Security tab.");
|
|
305
305
|
let n = t.agent?.lastGatewayAuthPushStatus, r = t.agent?.lastGatewayAuthPushError;
|
|
306
306
|
if (n === "failed") throw Error(`Credentials created but push to agent tunnel failed: ${r || "unknown error"}. Check that the agent can reach the workspace's gateway URLs from its host network.`);
|
|
307
|
-
let i = (await
|
|
307
|
+
let i = (await Nt({ variables: { agentId: e.id } })).data?.startVibecontrolsAgent;
|
|
308
308
|
if (!i?.success) throw Error(`Credentials pushed but lifecycle/start failed: ${i?.error || "unknown error"}. The agent has fresh credentials; try clicking Reconnect again or check vibe status on the host.`);
|
|
309
309
|
y.emitCustom("vibecontrols.agent.gateway_auth_setup", {
|
|
310
310
|
workspaceId: _ ?? void 0,
|
|
311
311
|
agentId: e.id
|
|
312
|
-
}), await
|
|
312
|
+
}), await jt({ variables: { id: e.id } }), c.success(`Agent "${e.name}" re-credentialed and started.`);
|
|
313
313
|
return;
|
|
314
314
|
}
|
|
315
315
|
throw Error(t?.error || "Failed to start agent");
|
|
316
316
|
}
|
|
317
|
-
await
|
|
317
|
+
await jt({ variables: { id: e.id } }), c.success(`Agent "${e.name}" started`);
|
|
318
318
|
} catch (e) {
|
|
319
319
|
console.error("Failed to start agent:", e), c.error(e instanceof Error ? e.message : "Failed to start agent");
|
|
320
320
|
}
|
|
321
|
-
},
|
|
321
|
+
}, tn = async (e) => {
|
|
322
322
|
try {
|
|
323
|
-
let t = (await
|
|
323
|
+
let t = (await Pt({ variables: { agentId: e.id } })).data?.stopVibecontrolsAgent;
|
|
324
324
|
if (!t?.success) throw Error(t?.error || "Failed to stop agent");
|
|
325
|
-
await
|
|
325
|
+
await Mt({ variables: { id: e.id } }), c.success(`Agent "${e.name}" stopped`);
|
|
326
326
|
} catch (e) {
|
|
327
327
|
console.error("Failed to stop agent:", e), c.error(e instanceof Error ? e.message : "Failed to stop agent");
|
|
328
328
|
}
|
|
329
|
-
},
|
|
330
|
-
|
|
331
|
-
},
|
|
332
|
-
if (!
|
|
333
|
-
let e =
|
|
334
|
-
|
|
329
|
+
}, nn = (e) => {
|
|
330
|
+
F(e);
|
|
331
|
+
}, rn = async () => {
|
|
332
|
+
if (!P) return;
|
|
333
|
+
let e = P;
|
|
334
|
+
I(!0);
|
|
335
335
|
try {
|
|
336
|
-
await
|
|
336
|
+
await Mt({
|
|
337
337
|
variables: { id: e.id },
|
|
338
338
|
refetchQueries: []
|
|
339
339
|
});
|
|
340
340
|
} catch (e) {
|
|
341
|
-
console.error("Failed to deactivate agent:", e), c.error(e instanceof Error ? e.message : "Failed to disconnect agent"),
|
|
341
|
+
console.error("Failed to deactivate agent:", e), c.error(e instanceof Error ? e.message : "Failed to disconnect agent"), I(!1), F(null), await K();
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
344
|
try {
|
|
345
|
-
await
|
|
345
|
+
await Ht({
|
|
346
346
|
variables: {
|
|
347
347
|
id: e.id,
|
|
348
348
|
input: {
|
|
@@ -355,16 +355,16 @@ function ot() {
|
|
|
355
355
|
} catch (e) {
|
|
356
356
|
console.error("Failed to clear tunnel fields:", e), c.error("Agent marked offline, but failed to clear connection fields — clear them manually in Settings.");
|
|
357
357
|
}
|
|
358
|
-
|
|
359
|
-
},
|
|
358
|
+
I(!1), F(null), await K();
|
|
359
|
+
}, an = (e) => {
|
|
360
360
|
v(`/agents/${e.id}`);
|
|
361
|
-
},
|
|
362
|
-
|
|
363
|
-
},
|
|
364
|
-
if (!
|
|
365
|
-
let e =
|
|
361
|
+
}, on = (e) => {
|
|
362
|
+
A(e);
|
|
363
|
+
}, sn = async () => {
|
|
364
|
+
if (!k) return;
|
|
365
|
+
let e = k.id, t = Tt.current?.value?.trim() || "";
|
|
366
366
|
try {
|
|
367
|
-
|
|
367
|
+
bt(!0), await Ht({
|
|
368
368
|
variables: {
|
|
369
369
|
id: e,
|
|
370
370
|
input: {
|
|
@@ -373,105 +373,105 @@ function ot() {
|
|
|
373
373
|
}
|
|
374
374
|
},
|
|
375
375
|
refetchQueries: ["ListAgents", "VibecontrolsAgentHealthProbes"]
|
|
376
|
-
}), t &&
|
|
376
|
+
}), t && xt(e), A(null);
|
|
377
377
|
} catch (e) {
|
|
378
378
|
console.error("Failed to update tunnel settings:", e);
|
|
379
379
|
} finally {
|
|
380
|
-
|
|
380
|
+
bt(!1);
|
|
381
381
|
}
|
|
382
|
-
},
|
|
383
|
-
|
|
382
|
+
}, cn = l((e) => {
|
|
383
|
+
z((t) => {
|
|
384
384
|
let n = new Set(t);
|
|
385
385
|
return n.has(e) ? n.delete(e) : n.add(e), n;
|
|
386
386
|
});
|
|
387
|
-
}, []),
|
|
388
|
-
|
|
389
|
-
}, [
|
|
390
|
-
|
|
391
|
-
}, []), $ =
|
|
392
|
-
if (
|
|
393
|
-
|
|
387
|
+
}, []), ln = l(() => {
|
|
388
|
+
z(new Set(X.map((e) => e.id)));
|
|
389
|
+
}, [X]), Q = l(() => {
|
|
390
|
+
z(/* @__PURE__ */ new Set());
|
|
391
|
+
}, []), $ = X.length > 0 && R.size === X.length, un = R.size > 0, dn = l(async () => {
|
|
392
|
+
if (R.size !== 0) {
|
|
393
|
+
V(!0);
|
|
394
394
|
try {
|
|
395
|
-
let e = await Promise.allSettled(Array.from(
|
|
396
|
-
n > 0 ? c.error(`Removed ${t}, failed to remove ${n} agent${n === 1 ? "" : "s"}`) : c.success(`Removed ${t} agent${t === 1 ? "" : "s"}`),
|
|
395
|
+
let e = await Promise.allSettled(Array.from(R).map((e) => Ut({ variables: { id: e } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.filter((e) => e.status === "rejected").length;
|
|
396
|
+
n > 0 ? c.error(`Removed ${t}, failed to remove ${n} agent${n === 1 ? "" : "s"}`) : c.success(`Removed ${t} agent${t === 1 ? "" : "s"}`), z(/* @__PURE__ */ new Set());
|
|
397
397
|
} catch (e) {
|
|
398
398
|
c.error(e instanceof Error ? e.message : "Failed to remove agents");
|
|
399
399
|
} finally {
|
|
400
|
-
|
|
400
|
+
V(!1), H(!1);
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
|
-
}, [
|
|
404
|
-
total:
|
|
405
|
-
active:
|
|
406
|
-
offline:
|
|
403
|
+
}, [R, Ut]), fn = {
|
|
404
|
+
total: Y.length,
|
|
405
|
+
active: Y.filter((e) => e.status === "ACTIVE").length,
|
|
406
|
+
offline: Y.filter((e) => e.status !== "ACTIVE").length
|
|
407
407
|
};
|
|
408
|
-
return
|
|
408
|
+
return st ? /* @__PURE__ */ m(g, {
|
|
409
409
|
className: "space-y-6 px-6 lg:px-8 py-6 bg-bg-canvas min-h-full",
|
|
410
|
-
children: /* @__PURE__ */ m(
|
|
411
|
-
}) :
|
|
410
|
+
children: /* @__PURE__ */ m(_e, { message: b("agentsPage.loadingPermissions", "Loading permissions...") })
|
|
411
|
+
}) : ct && ct.permissionStrings?.length > 0 && !dt ? /* @__PURE__ */ m(g, {
|
|
412
412
|
className: "space-y-6 px-6 lg:px-8 py-6 bg-bg-canvas min-h-full",
|
|
413
|
-
children: /* @__PURE__ */ m(
|
|
413
|
+
children: /* @__PURE__ */ m(tt, {
|
|
414
414
|
title: b("agentsPage.accessDeniedTitle", "Access Denied"),
|
|
415
415
|
description: b("agentsPage.accessDeniedDescription", "You don't have permission to view agents. Contact your workspace administrator for access.")
|
|
416
416
|
})
|
|
417
|
-
}) :
|
|
417
|
+
}) : qt && Y.length === 0 ? /* @__PURE__ */ m(g, {
|
|
418
418
|
className: "space-y-6 px-6 lg:px-8 py-6 bg-bg-canvas min-h-full",
|
|
419
|
-
children: /* @__PURE__ */ m(
|
|
419
|
+
children: /* @__PURE__ */ m(ve, {
|
|
420
420
|
title: b("agentsPage.failedLoad", "Failed to load agents"),
|
|
421
|
-
message:
|
|
422
|
-
onRetry: () =>
|
|
421
|
+
message: qt.message,
|
|
422
|
+
onRetry: () => K()
|
|
423
423
|
})
|
|
424
424
|
}) : /* @__PURE__ */ h(g, {
|
|
425
425
|
className: "space-y-6 px-6 lg:px-8 py-6 bg-bg-canvas min-h-full",
|
|
426
426
|
children: [
|
|
427
|
-
/* @__PURE__ */ m(
|
|
427
|
+
/* @__PURE__ */ m(ge, {
|
|
428
428
|
title: b("agentsPage.title", "Agents"),
|
|
429
429
|
description: b("agentsPage.descriptionOnline", "{{active}} of {{total}} agents online", {
|
|
430
|
-
active:
|
|
431
|
-
total:
|
|
430
|
+
active: fn.active,
|
|
431
|
+
total: fn.total
|
|
432
432
|
}),
|
|
433
433
|
actions: /* @__PURE__ */ h("div", {
|
|
434
434
|
className: "flex w-full flex-col items-end gap-2 sm:w-auto sm:flex-row sm:items-center",
|
|
435
435
|
children: [/* @__PURE__ */ m("button", {
|
|
436
436
|
type: "button",
|
|
437
437
|
onClick: () => {
|
|
438
|
-
|
|
438
|
+
K(), Xt();
|
|
439
439
|
},
|
|
440
|
-
disabled:
|
|
440
|
+
disabled: G || q.loading,
|
|
441
441
|
className: "flex items-center justify-center gap-2 px-3 py-2 max-md:min-h-11 max-md:min-w-11 text-text-secondary hover:bg-bg-sunken hover:text-text-primary rounded-button transition-colors disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
442
442
|
"aria-label": b("agentsPage.refreshTitle", "Refresh agents"),
|
|
443
443
|
title: b("agentsPage.refreshTitle", "Refresh agents"),
|
|
444
|
-
children: /* @__PURE__ */ m(
|
|
444
|
+
children: /* @__PURE__ */ m(ze, {
|
|
445
445
|
"aria-hidden": "true",
|
|
446
|
-
className: `size-4 ${
|
|
446
|
+
className: `size-4 ${G || q.loading ? "animate-spin" : ""}`
|
|
447
447
|
})
|
|
448
|
-
}),
|
|
449
|
-
permission:
|
|
448
|
+
}), Vt ? /* @__PURE__ */ m(nt, {
|
|
449
|
+
permission: Oe.AGENT_CREATE,
|
|
450
450
|
deniedBehavior: "disable",
|
|
451
451
|
deniedTooltip: b("agentsPage.deniedCreateTooltip", "You don't have permission to create agents"),
|
|
452
452
|
children: /* @__PURE__ */ h("button", {
|
|
453
453
|
type: "button",
|
|
454
|
-
onClick:
|
|
454
|
+
onClick: Z,
|
|
455
455
|
className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
456
456
|
children: [/* @__PURE__ */ m(p, { className: "size-4" }), b("agentsPage.addAgent", "Add Agent")]
|
|
457
457
|
})
|
|
458
458
|
}) : /* @__PURE__ */ h("button", {
|
|
459
459
|
type: "button",
|
|
460
|
-
onClick:
|
|
460
|
+
onClick: Z,
|
|
461
461
|
className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
462
462
|
children: [/* @__PURE__ */ m(p, { className: "size-4" }), b("agentsPage.addAgent", "Add Agent")]
|
|
463
463
|
})]
|
|
464
464
|
})
|
|
465
465
|
}),
|
|
466
|
-
/* @__PURE__ */ m(
|
|
467
|
-
icon: /* @__PURE__ */ m(
|
|
466
|
+
/* @__PURE__ */ m(qe, {
|
|
467
|
+
icon: /* @__PURE__ */ m(Fe, { className: "size-4" }),
|
|
468
468
|
children: b("agentsPage.purpose", "Agents are the lightweight programs you install on your own machines (laptop, server, CI runner) that let VibeControls securely run terminal sessions and tasks there. Register an agent here, then attach it to a vibe to give that workspace a place to actually execute work — your code never leaves your hardware.")
|
|
469
469
|
}),
|
|
470
|
-
|
|
470
|
+
Y.length === 0 && !G && /* @__PURE__ */ m(we, {
|
|
471
471
|
variant: "full",
|
|
472
472
|
dismissKey: "vibecontrols-agents-setup-banner"
|
|
473
473
|
}),
|
|
474
|
-
|
|
474
|
+
Y.length > 0 && /* @__PURE__ */ m(we, {
|
|
475
475
|
variant: "compact",
|
|
476
476
|
dismissKey: "vibecontrols-agents-compact-banner"
|
|
477
477
|
}),
|
|
@@ -479,9 +479,9 @@ function ot() {
|
|
|
479
479
|
className: "space-y-3",
|
|
480
480
|
children: [/* @__PURE__ */ h("div", {
|
|
481
481
|
className: "flex items-center gap-2",
|
|
482
|
-
children: [/* @__PURE__ */ m(
|
|
482
|
+
children: [/* @__PURE__ */ m(Se, {
|
|
483
483
|
value: x,
|
|
484
|
-
onChange:
|
|
484
|
+
onChange: ft,
|
|
485
485
|
placeholder: b("agentsPage.searchPlaceholder", "Search agents..."),
|
|
486
486
|
className: "flex-1 sm:w-64 sm:flex-none"
|
|
487
487
|
}), /* @__PURE__ */ h("div", {
|
|
@@ -489,26 +489,26 @@ function ot() {
|
|
|
489
489
|
children: [/* @__PURE__ */ m("button", {
|
|
490
490
|
type: "button",
|
|
491
491
|
onClick: () => {
|
|
492
|
-
|
|
492
|
+
E("grid"), z(/* @__PURE__ */ new Set());
|
|
493
493
|
},
|
|
494
494
|
className: `flex items-center justify-center p-1.5 sm:p-2 max-md:min-h-11 max-md:min-w-11 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${T === "grid" ? "bg-[var(--color-accent-soft)] text-text-primary" : "text-text-secondary hover:bg-bg-surface/60"}`,
|
|
495
495
|
"aria-label": b("agentsPage.gridViewTitle", "Grid view"),
|
|
496
496
|
"aria-pressed": T === "grid",
|
|
497
497
|
title: b("agentsPage.gridViewTitle", "Grid view"),
|
|
498
|
-
children: /* @__PURE__ */ m(
|
|
498
|
+
children: /* @__PURE__ */ m(Le, {
|
|
499
499
|
"aria-hidden": "true",
|
|
500
500
|
className: "size-4 text-text-secondary"
|
|
501
501
|
})
|
|
502
502
|
}), /* @__PURE__ */ m("button", {
|
|
503
503
|
type: "button",
|
|
504
504
|
onClick: () => {
|
|
505
|
-
|
|
505
|
+
E("list"), z(/* @__PURE__ */ new Set());
|
|
506
506
|
},
|
|
507
507
|
className: `flex items-center justify-center p-1.5 sm:p-2 max-md:min-h-11 max-md:min-w-11 rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${T === "list" ? "bg-[var(--color-accent-soft)] text-text-primary" : "text-text-secondary hover:bg-bg-surface/60"}`,
|
|
508
508
|
"aria-label": b("agentsPage.listViewTitle", "List view"),
|
|
509
509
|
"aria-pressed": T === "list",
|
|
510
510
|
title: b("agentsPage.listViewTitle", "List view"),
|
|
511
|
-
children: /* @__PURE__ */ m(
|
|
511
|
+
children: /* @__PURE__ */ m(Re, {
|
|
512
512
|
"aria-hidden": "true",
|
|
513
513
|
className: "size-4 text-text-secondary"
|
|
514
514
|
})
|
|
@@ -517,53 +517,53 @@ function ot() {
|
|
|
517
517
|
}), /* @__PURE__ */ h("div", {
|
|
518
518
|
className: "flex items-center gap-2 sm:gap-3 flex-wrap",
|
|
519
519
|
children: [
|
|
520
|
-
/* @__PURE__ */ m(
|
|
520
|
+
/* @__PURE__ */ m(Ce, {
|
|
521
521
|
label: b("agentsPage.filterStatus", "Status"),
|
|
522
522
|
value: S,
|
|
523
|
-
options:
|
|
524
|
-
onChange:
|
|
523
|
+
options: lt,
|
|
524
|
+
onChange: pt
|
|
525
525
|
}),
|
|
526
|
-
/* @__PURE__ */ m(
|
|
526
|
+
/* @__PURE__ */ m(Ce, {
|
|
527
527
|
label: b("agentsPage.filterPlatform", "Platform"),
|
|
528
528
|
value: C,
|
|
529
|
-
options:
|
|
530
|
-
onChange:
|
|
529
|
+
options: ut,
|
|
530
|
+
onChange: mt
|
|
531
531
|
}),
|
|
532
|
-
/* @__PURE__ */ m(
|
|
532
|
+
/* @__PURE__ */ m(De, {
|
|
533
533
|
label: b("agentsPage.filterTag", "Tag"),
|
|
534
534
|
value: w,
|
|
535
|
-
onChange:
|
|
535
|
+
onChange: ht
|
|
536
536
|
})
|
|
537
537
|
]
|
|
538
538
|
})]
|
|
539
539
|
}),
|
|
540
|
-
T === "grid" &&
|
|
540
|
+
T === "grid" && X.length > 0 && /* @__PURE__ */ m("div", {
|
|
541
541
|
className: "flex justify-end",
|
|
542
542
|
children: /* @__PURE__ */ h("button", {
|
|
543
543
|
type: "button",
|
|
544
|
-
onClick: $ ? Q :
|
|
544
|
+
onClick: $ ? Q : ln,
|
|
545
545
|
"aria-pressed": $,
|
|
546
546
|
className: "flex items-center gap-1.5 px-3 py-1.5 max-md:min-h-11 text-xs text-text-secondary hover:text-text-primary rounded-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
547
|
-
children: [/* @__PURE__ */ m(
|
|
547
|
+
children: [/* @__PURE__ */ m(Ie, {
|
|
548
548
|
"aria-hidden": "true",
|
|
549
549
|
className: "size-3.5"
|
|
550
550
|
}), $ ? b("agentsPage.deselectAll", "Deselect All") : b("agentsPage.selectAll", "Select All")]
|
|
551
551
|
})
|
|
552
552
|
}),
|
|
553
|
-
|
|
553
|
+
un && /* @__PURE__ */ h("div", {
|
|
554
554
|
className: "flex flex-col sm:flex-row items-start sm:items-center gap-3 px-4 py-2.5 bg-[var(--color-accent-soft)] border border-border-subtle rounded-card",
|
|
555
555
|
children: [/* @__PURE__ */ m("span", {
|
|
556
556
|
className: "text-sm font-medium text-text-primary",
|
|
557
|
-
children: b("agentsPage.selectedCount", "{{count}} agents selected", { count:
|
|
557
|
+
children: b("agentsPage.selectedCount", "{{count}} agents selected", { count: R.size })
|
|
558
558
|
}), /* @__PURE__ */ h("div", {
|
|
559
559
|
className: "flex items-center gap-1.5 sm:ml-auto",
|
|
560
560
|
children: [/* @__PURE__ */ h("button", {
|
|
561
561
|
type: "button",
|
|
562
|
-
onClick: () =>
|
|
563
|
-
disabled:
|
|
562
|
+
onClick: () => H(!0),
|
|
563
|
+
disabled: B,
|
|
564
564
|
className: "flex items-center gap-1.5 px-3 py-1.5 max-md:min-h-11 text-xs font-medium text-status-error-text bg-status-error-bg-subtle border border-status-error-border rounded-button hover:bg-status-error-bg-subtle/80 transition-colors disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
565
565
|
children: [
|
|
566
|
-
/* @__PURE__ */ m(
|
|
566
|
+
/* @__PURE__ */ m(Be, {
|
|
567
567
|
"aria-hidden": "true",
|
|
568
568
|
className: "size-3"
|
|
569
569
|
}),
|
|
@@ -575,7 +575,7 @@ function ot() {
|
|
|
575
575
|
onClick: Q,
|
|
576
576
|
className: "flex items-center gap-1.5 px-3 py-1.5 max-md:min-h-11 text-xs text-text-secondary hover:text-text-primary rounded-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
577
577
|
children: [
|
|
578
|
-
/* @__PURE__ */ m(
|
|
578
|
+
/* @__PURE__ */ m(Ve, {
|
|
579
579
|
"aria-hidden": "true",
|
|
580
580
|
className: "size-3"
|
|
581
581
|
}),
|
|
@@ -588,57 +588,57 @@ function ot() {
|
|
|
588
588
|
x || S !== "all" || C !== "all" ? /* @__PURE__ */ h("p", {
|
|
589
589
|
className: "text-sm text-text-secondary",
|
|
590
590
|
children: [b("agentsPage.showingResults", "Showing {{filtered}} of {{total}} agents", {
|
|
591
|
-
filtered:
|
|
592
|
-
total:
|
|
593
|
-
}),
|
|
591
|
+
filtered: X.length,
|
|
592
|
+
total: Y.length
|
|
593
|
+
}), G && /* @__PURE__ */ m("span", {
|
|
594
594
|
className: "ml-2 text-text-muted",
|
|
595
595
|
children: b("agentsPage.refreshing", "(refreshing...)")
|
|
596
596
|
})]
|
|
597
597
|
}) : null,
|
|
598
|
-
|
|
598
|
+
G && Y.length === 0 ? /* @__PURE__ */ m(ke, {
|
|
599
599
|
variant: "rows",
|
|
600
600
|
count: 6
|
|
601
|
-
}) :
|
|
601
|
+
}) : X.length > 0 ? /* @__PURE__ */ m(We, {
|
|
602
602
|
mode: "wait",
|
|
603
|
-
children: T === "grid" ? /* @__PURE__ */ m(
|
|
603
|
+
children: T === "grid" ? /* @__PURE__ */ m(it, {
|
|
604
604
|
"data-tour": "agents-page-grid-header",
|
|
605
605
|
stagger: .04,
|
|
606
606
|
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
607
|
-
children:
|
|
607
|
+
children: X.map((e) => /* @__PURE__ */ m(rt, {
|
|
608
608
|
className: "h-full",
|
|
609
|
-
children: /* @__PURE__ */ m(
|
|
609
|
+
children: /* @__PURE__ */ m(Ae, {
|
|
610
610
|
agent: e,
|
|
611
|
-
onSelect:
|
|
612
|
-
onStart:
|
|
613
|
-
onStop:
|
|
614
|
-
onDisconnect:
|
|
615
|
-
onConfigure:
|
|
616
|
-
onEditTunnelUrl:
|
|
617
|
-
selected:
|
|
618
|
-
onToggleSelect: () =>
|
|
611
|
+
onSelect: Qt,
|
|
612
|
+
onStart: en,
|
|
613
|
+
onStop: tn,
|
|
614
|
+
onDisconnect: nn,
|
|
615
|
+
onConfigure: an,
|
|
616
|
+
onEditTunnelUrl: on,
|
|
617
|
+
selected: R.has(e.id),
|
|
618
|
+
onToggleSelect: () => cn(e.id),
|
|
619
619
|
healthErrorMessage: e.healthError ?? null
|
|
620
620
|
})
|
|
621
621
|
}, e.id))
|
|
622
|
-
}, "grid-view") : /* @__PURE__ */ m(
|
|
622
|
+
}, "grid-view") : /* @__PURE__ */ m(it, {
|
|
623
623
|
stagger: .04,
|
|
624
|
-
children: /* @__PURE__ */ m(
|
|
624
|
+
children: /* @__PURE__ */ m(rt, {
|
|
625
625
|
variant: "fadeRight",
|
|
626
|
-
children: /* @__PURE__ */ m(
|
|
627
|
-
agents:
|
|
628
|
-
onSelect:
|
|
629
|
-
onStart:
|
|
630
|
-
onStop:
|
|
631
|
-
onDisconnect:
|
|
632
|
-
onSettings:
|
|
633
|
-
selectedIds:
|
|
634
|
-
onToggleSelect:
|
|
635
|
-
onSelectAll:
|
|
626
|
+
children: /* @__PURE__ */ m(je, {
|
|
627
|
+
agents: X,
|
|
628
|
+
onSelect: Qt,
|
|
629
|
+
onStart: en,
|
|
630
|
+
onStop: tn,
|
|
631
|
+
onDisconnect: nn,
|
|
632
|
+
onSettings: an,
|
|
633
|
+
selectedIds: R,
|
|
634
|
+
onToggleSelect: cn,
|
|
635
|
+
onSelectAll: ln,
|
|
636
636
|
onDeselectAll: Q
|
|
637
637
|
})
|
|
638
638
|
})
|
|
639
639
|
}, "list-view")
|
|
640
|
-
}) : /* @__PURE__ */ m(
|
|
641
|
-
icon: /* @__PURE__ */ m(
|
|
640
|
+
}) : /* @__PURE__ */ m(xe, {
|
|
641
|
+
icon: /* @__PURE__ */ m(Fe, { className: "size-8 text-text-secondary" }),
|
|
642
642
|
illustration: x || S !== "all" || C !== "all" ? "empty-search" : "empty-agents",
|
|
643
643
|
title: x || S !== "all" || C !== "all" ? b("agentsPage.emptyNoAgentsFound", "No agents found") : b("agentsPage.emptyNoAgentsConfigured", "No agents configured"),
|
|
644
644
|
description: x || S !== "all" || C !== "all" ? b("agentsPage.emptyAdjustSearch", "Try adjusting your search or filters") : b("agentsPage.emptyNoAgentsDescription", "Install the CLI agent on your machine, then add it here. You can create a target inline while adding the agent."),
|
|
@@ -647,7 +647,7 @@ function ot() {
|
|
|
647
647
|
children: [
|
|
648
648
|
/* @__PURE__ */ h("button", {
|
|
649
649
|
type: "button",
|
|
650
|
-
onClick:
|
|
650
|
+
onClick: Z,
|
|
651
651
|
className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
652
652
|
children: [/* @__PURE__ */ m(p, { className: "size-4" }), b("agentsPage.addAgent", "Add Agent")]
|
|
653
653
|
}),
|
|
@@ -657,119 +657,119 @@ function ot() {
|
|
|
657
657
|
className: "flex items-center gap-2 px-4 py-2 border border-border-subtle bg-bg-surface text-text-primary rounded-button hover:bg-bg-sunken hover:border-border-strong transition-all duration-200 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
658
658
|
children: b("agentsPage.setupGuide", "Setup guide")
|
|
659
659
|
}),
|
|
660
|
-
/* @__PURE__ */ m(
|
|
660
|
+
/* @__PURE__ */ m(Te, { prompt: "What is an Agent in VibeControls and how do I add one?" })
|
|
661
661
|
]
|
|
662
662
|
}) : void 0
|
|
663
663
|
}),
|
|
664
|
-
|
|
665
|
-
onSubmit:
|
|
666
|
-
onCancel: () =>
|
|
667
|
-
isLoading:
|
|
664
|
+
gt && /* @__PURE__ */ m(Me, {
|
|
665
|
+
onSubmit: $t,
|
|
666
|
+
onCancel: () => D(!1),
|
|
667
|
+
isLoading: _t,
|
|
668
668
|
onNavigate: (e) => {
|
|
669
|
-
|
|
669
|
+
D(!1), v(e);
|
|
670
670
|
},
|
|
671
|
-
targets:
|
|
671
|
+
targets: Bt.map((e) => ({
|
|
672
672
|
id: e.id,
|
|
673
673
|
name: e.name,
|
|
674
674
|
type: e.type || "DIRECT",
|
|
675
675
|
status: e.status
|
|
676
676
|
})),
|
|
677
|
-
targetsLoading:
|
|
678
|
-
onCreateTarget:
|
|
677
|
+
targetsLoading: Rt,
|
|
678
|
+
onCreateTarget: Gt,
|
|
679
679
|
extraSection: /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h3", {
|
|
680
680
|
className: "text-sm font-medium text-text-secondary mb-2",
|
|
681
681
|
children: b("agents.tags", "Tags")
|
|
682
|
-
}), /* @__PURE__ */ m(
|
|
682
|
+
}), /* @__PURE__ */ m(ye, {
|
|
683
683
|
entityType: "VIBECONTROLS_AGENT",
|
|
684
|
-
onDraftChange:
|
|
684
|
+
onDraftChange: Ot
|
|
685
685
|
})] })
|
|
686
686
|
}),
|
|
687
|
-
/* @__PURE__ */ m(
|
|
688
|
-
isOpen:
|
|
687
|
+
/* @__PURE__ */ m(ue, {
|
|
688
|
+
isOpen: P !== null,
|
|
689
689
|
onClose: () => {
|
|
690
|
-
|
|
690
|
+
wt || F(null);
|
|
691
691
|
},
|
|
692
|
-
onConfirm:
|
|
692
|
+
onConfirm: rn,
|
|
693
693
|
title: b("agentsPage.disconnectTitle", "Disconnect Agent"),
|
|
694
|
-
message:
|
|
694
|
+
message: P ? Ne(P) === "OFFLINE" ? b("agentsPage.disconnectOfflineMessage", "Clear the stored tunnel connection for {{name}}? This will remove the tunnel URL and API key from this offline agent.", { name: P.name }) : b("agentsPage.disconnectActiveMessage", "Mark {{name}} as offline and clear its tunnel connection? The agent process will not be stopped automatically — you may need to stop it manually on the host machine.", { name: P.name }) : "",
|
|
695
695
|
confirmLabel: b("agentsPage.disconnectConfirm", "Disconnect"),
|
|
696
696
|
variant: "danger",
|
|
697
|
-
isLoading:
|
|
697
|
+
isLoading: wt
|
|
698
698
|
}),
|
|
699
|
-
/* @__PURE__ */ m(
|
|
700
|
-
open:
|
|
699
|
+
/* @__PURE__ */ m(Je, {
|
|
700
|
+
open: k !== null,
|
|
701
701
|
onOpenChange: (e) => {
|
|
702
|
-
e ||
|
|
702
|
+
e || A(null);
|
|
703
703
|
},
|
|
704
|
-
children:
|
|
704
|
+
children: k ? /* @__PURE__ */ h(Ye, {
|
|
705
705
|
className: "sm:max-w-md",
|
|
706
706
|
children: [
|
|
707
|
-
/* @__PURE__ */ h(
|
|
707
|
+
/* @__PURE__ */ h(Qe, { children: [/* @__PURE__ */ m($e, { children: b("agentsPage.editTunnelTitle", "Edit Tunnel") }), /* @__PURE__ */ m(Xe, { children: b("agentsPage.editTunnelDescription", "Configure the cloudflared tunnel URL and API key for {{name}}.", { name: k.name }) })] }),
|
|
708
708
|
/* @__PURE__ */ h("div", {
|
|
709
709
|
className: "py-4",
|
|
710
710
|
children: [
|
|
711
711
|
/* @__PURE__ */ m("label", {
|
|
712
|
-
htmlFor:
|
|
712
|
+
htmlFor: L.id,
|
|
713
713
|
className: "mb-1.5 block text-sm font-medium text-text-primary",
|
|
714
714
|
children: b("agentsPage.tunnelUrlLabel", "Tunnel URL")
|
|
715
715
|
}),
|
|
716
|
-
/* @__PURE__ */ m(
|
|
717
|
-
...
|
|
718
|
-
ref:
|
|
716
|
+
/* @__PURE__ */ m(Ke, {
|
|
717
|
+
...L.inputProps,
|
|
718
|
+
ref: Tt,
|
|
719
719
|
type: "url",
|
|
720
|
-
defaultValue:
|
|
720
|
+
defaultValue: k.tunnelUrl || "",
|
|
721
721
|
placeholder: b("agentsPage.tunnelUrlPlaceholder", "https://example.trycloudflare.com"),
|
|
722
722
|
className: "text-base md:text-sm"
|
|
723
723
|
}),
|
|
724
724
|
/* @__PURE__ */ m("p", {
|
|
725
|
-
id:
|
|
725
|
+
id: L.hintId,
|
|
726
726
|
className: "mt-1.5 text-xs text-text-muted",
|
|
727
727
|
children: b("agentsPage.tunnelUrlHint", "Leave empty to clear. Agents with auto-tunnel report this automatically on startup.")
|
|
728
728
|
})
|
|
729
729
|
]
|
|
730
730
|
}),
|
|
731
|
-
/* @__PURE__ */ h(
|
|
731
|
+
/* @__PURE__ */ h(Ze, { children: [/* @__PURE__ */ m(Ge, {
|
|
732
732
|
type: "button",
|
|
733
733
|
variant: "outline",
|
|
734
|
-
onClick: () =>
|
|
734
|
+
onClick: () => A(null),
|
|
735
735
|
className: "max-md:min-h-11",
|
|
736
736
|
children: b("agentsPage.cancel", "Cancel")
|
|
737
|
-
}), /* @__PURE__ */ m(
|
|
737
|
+
}), /* @__PURE__ */ m(Ge, {
|
|
738
738
|
type: "button",
|
|
739
|
-
onClick:
|
|
740
|
-
disabled:
|
|
741
|
-
"aria-busy":
|
|
739
|
+
onClick: sn,
|
|
740
|
+
disabled: j,
|
|
741
|
+
"aria-busy": j,
|
|
742
742
|
className: "max-md:min-h-11",
|
|
743
|
-
children:
|
|
743
|
+
children: j ? b("agentsPage.saving", "Saving...") : b("agentsPage.save", "Save")
|
|
744
744
|
})] })
|
|
745
745
|
]
|
|
746
746
|
}) : null
|
|
747
747
|
}),
|
|
748
|
-
/* @__PURE__ */ m(
|
|
749
|
-
isOpen:
|
|
748
|
+
/* @__PURE__ */ m(ue, {
|
|
749
|
+
isOpen: Et,
|
|
750
750
|
onClose: () => {
|
|
751
|
-
|
|
751
|
+
B || H(!1);
|
|
752
752
|
},
|
|
753
|
-
onConfirm:
|
|
753
|
+
onConfirm: dn,
|
|
754
754
|
title: b("agentsPage.bulkDeleteTitle", "Remove agents"),
|
|
755
|
-
message: b("agentsPage.bulkDeleteConfirm", "Are you sure you want to remove {{count}} agent(s)? This cannot be undone.", { count:
|
|
755
|
+
message: b("agentsPage.bulkDeleteConfirm", "Are you sure you want to remove {{count}} agent(s)? This cannot be undone.", { count: R.size }),
|
|
756
756
|
confirmLabel: b("agentsPage.remove", "Remove"),
|
|
757
757
|
variant: "danger",
|
|
758
|
-
isLoading:
|
|
758
|
+
isLoading: B
|
|
759
759
|
}),
|
|
760
|
-
/* @__PURE__ */ m(
|
|
761
|
-
isOpen:
|
|
762
|
-
onClose: () =>
|
|
760
|
+
/* @__PURE__ */ m(de, {
|
|
761
|
+
isOpen: U !== null,
|
|
762
|
+
onClose: () => W(null),
|
|
763
763
|
onConfirm: () => {
|
|
764
|
-
|
|
764
|
+
W(null), v("/billing/plans");
|
|
765
765
|
},
|
|
766
|
-
title:
|
|
767
|
-
message:
|
|
766
|
+
title: fe(U ?? "generic").title,
|
|
767
|
+
message: fe(U ?? "generic").message
|
|
768
768
|
})
|
|
769
769
|
]
|
|
770
770
|
});
|
|
771
771
|
}
|
|
772
772
|
//#endregion
|
|
773
|
-
export {
|
|
773
|
+
export { at as AgentsPage };
|
|
774
774
|
|
|
775
775
|
//# sourceMappingURL=AgentsPage.js.map
|