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