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