@burdenoff/microfe-vibecontrols 2026.519.6 → 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,34 +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
- pollInterval: 3e4
138
- }), { data: J } = ae({ skip: !b }), kt = q.data === void 0 && J === void 0, Y = l(() => {
139
- 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 ?? [];
140
141
  for (let n of t) e.set(n.agentId, {
141
142
  agentId: n.agentId,
142
143
  healthy: n.healthy,
143
144
  errorMessage: n.errorMessage
144
145
  });
145
146
  return e;
146
- }, [q.data, J]), X = l(() => (Dt?.vibecontrolsAgents ?? []).map((e) => ({
147
+ }, [J.data, Y]), Z = c(() => (At?.vibecontrolsAgents ?? []).map((e) => ({
147
148
  id: e.id,
148
149
  workspaceId: e.workspaceId,
149
150
  name: e.name,
@@ -152,12 +153,12 @@ function y() {
152
153
  architecture: e.architecture,
153
154
  version: e.version,
154
155
  isActive: e.isActive,
155
- status: nt.has(e.id) ? "CONNECTING" : we({
156
+ status: M.has(e.id) ? "CONNECTING" : De({
156
157
  id: e.id,
157
158
  isActive: e.isActive,
158
159
  metadata: e.metadata
159
- }, Y, { probesLoading: kt }),
160
- 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),
161
162
  lastHeartbeat: e.lastHeartbeat || null,
162
163
  tunnelUrl: e.tunnelUrl ?? null,
163
164
  tunnelStatus: e.tunnelStatus ?? null,
@@ -181,62 +182,62 @@ function y() {
181
182
  } : null
182
183
  }))
183
184
  })), [
184
- Dt?.vibecontrolsAgents,
185
- Y,
186
- kt,
187
- nt
185
+ At?.vibecontrolsAgents,
186
+ X,
187
+ Mt,
188
+ M
188
189
  ]);
189
- c(() => {
190
- let e = Object.keys(j);
190
+ s(() => {
191
+ let e = Object.keys(A);
191
192
  if (e.length === 0) return;
192
193
  let t = Date.now(), n = Infinity;
193
194
  for (let r of e) {
194
- let e = j[r];
195
- 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));
196
197
  }
197
198
  if (n === Infinity) return;
198
199
  let r = Math.max(0, n - t) + 50, i = setTimeout(() => {
199
200
  let e = a.getState().connectingAgents;
200
201
  for (let t of Object.keys(e)) {
201
202
  let n = e[t];
202
- 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);
203
204
  }
204
205
  }, r);
205
206
  return () => clearTimeout(i);
206
207
  }, [
207
- Y,
208
- j,
209
- M
208
+ X,
209
+ A,
210
+ j
210
211
  ]);
211
- let Z = l(() => X.filter((e) => {
212
- if (C) {
213
- let t = C.toLowerCase();
212
+ let Q = c(() => Z.filter((e) => {
213
+ if (b) {
214
+ let t = b.toLowerCase();
214
215
  if (!(e.name.toLowerCase().includes(t) || e.hostname?.toLowerCase().includes(t) || e.id.toLowerCase().includes(t))) return !1;
215
216
  }
216
- return !(E !== "all" && !(e.tagAssignments ?? []).some((e) => e.tagId === E));
217
+ return !(C !== "all" && !(e.tagAssignments ?? []).some((e) => e.tagId === C));
217
218
  }), [
218
- X,
219
- C,
220
- E
219
+ Z,
220
+ b,
221
+ C
221
222
  ]);
222
- c(() => () => {
223
- H.current && clearTimeout(H.current);
223
+ s(() => () => {
224
+ U.current && clearTimeout(U.current);
224
225
  }, []);
225
- let At = (e) => {
226
- x(`/agents/${e.id}`), y?.({
226
+ let Nt = (e) => {
227
+ v(`/agents/${e.id}`), He?.({
227
228
  id: e.id,
228
229
  name: e.name,
229
230
  type: e.platform || "unknown",
230
231
  status: e.status || (e.isActive ? "ACTIVE" : "OFFLINE")
231
232
  });
232
- }, Q = () => {
233
- O(!0);
234
- }, jt = async (e) => {
233
+ }, $ = () => {
234
+ T(!0);
235
+ }, Pt = async (e) => {
235
236
  try {
236
- Qe(!0);
237
+ rt(!0);
237
238
  let t = e.tunnelUrl?.trim(), n = e.agentApiKey?.trim();
238
239
  if (t && n) {
239
- let r = await ft({ variables: { input: {
240
+ let r = await ht({ variables: { input: {
240
241
  tunnelUrl: t,
241
242
  apiKey: n,
242
243
  ...e.name ? { name: e.name } : {},
@@ -245,10 +246,10 @@ function y() {
245
246
  if (r.error) throw r.error;
246
247
  let i = r.data?.addVibecontrolsAgentFromTunnel;
247
248
  if (!i?.success) throw Error(i?.error || "Failed to onboard agent — probe or OAuth setup failed.");
248
- if (i.agent?.id) return { id: i.agent.id };
249
+ if (i.agent?.id) return await mt(i.agent.id), { id: i.agent.id };
249
250
  throw Error("Agent onboarding returned no agent record.");
250
251
  }
251
- let r = await dt({ variables: { input: {
252
+ let r = await ft({ variables: { input: {
252
253
  name: e.name,
253
254
  hostname: e.hostname,
254
255
  platform: e.platform,
@@ -258,50 +259,50 @@ function y() {
258
259
  ...e.tunnelUrl ? { tunnelUrl: e.tunnelUrl } : {},
259
260
  ...e.tunnelStatus ? { tunnelStatus: e.tunnelStatus } : {}
260
261
  } } }), i = r.data?.createVibecontrolsAgent;
261
- if (i?.id) return { id: i.id };
262
+ if (i?.id) return await mt(i.id), { id: i.id };
262
263
  throw r.error ? r.error : Error("Agent creation failed — no data returned from the server.");
263
264
  } catch (e) {
264
- if (pe(e)) {
265
- V(!0), O(!1);
265
+ if (me(e)) {
266
+ H(!0), T(!1);
266
267
  return;
267
268
  }
268
269
  throw console.error("Failed to create agent:", e), e;
269
270
  } finally {
270
- Qe(!1);
271
+ rt(!1);
271
272
  }
272
- }, Mt = async (e) => {
273
+ }, Ft = async (e) => {
273
274
  try {
274
- let t = (await ht({ variables: { agentId: e.id } })).data?.startVibecontrolsAgent;
275
+ let t = (await vt({ variables: { agentId: e.id } })).data?.startVibecontrolsAgent;
275
276
  if (!t?.success) throw Error(t?.error || "Failed to start agent");
276
- await pt({ variables: { id: e.id } }), U(`Agent "${e.name}" started`);
277
+ await gt({ variables: { id: e.id } }), W(`Agent "${e.name}" started`);
277
278
  } catch (e) {
278
- 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");
279
280
  }
280
- }, Nt = async (e) => {
281
+ }, It = async (e) => {
281
282
  try {
282
- let t = (await gt({ variables: { agentId: e.id } })).data?.stopVibecontrolsAgent;
283
+ let t = (await yt({ variables: { agentId: e.id } })).data?.stopVibecontrolsAgent;
283
284
  if (!t?.success) throw Error(t?.error || "Failed to stop agent");
284
- await mt({ variables: { id: e.id } }), U(`Agent "${e.name}" stopped`);
285
+ await _t({ variables: { id: e.id } }), W(`Agent "${e.name}" stopped`);
285
286
  } catch (e) {
286
- 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");
287
288
  }
288
- }, $ = (e) => {
289
+ }, Lt = (e) => {
289
290
  P(e);
290
- }, Pt = async () => {
291
+ }, Rt = async () => {
291
292
  if (!N) return;
292
293
  let e = N;
293
294
  I(!0);
294
295
  try {
295
- await mt({
296
+ await _t({
296
297
  variables: { id: e.id },
297
298
  refetchQueries: []
298
299
  });
299
300
  } catch (e) {
300
- 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();
301
302
  return;
302
303
  }
303
304
  try {
304
- await Ct({
305
+ await Et({
305
306
  variables: {
306
307
  id: e.id,
307
308
  input: {
@@ -311,20 +312,20 @@ function y() {
311
312
  }
312
313
  },
313
314
  refetchQueries: []
314
- }), U(`Agent "${e.name}" disconnected`);
315
+ }), W(`Agent "${e.name}" disconnected`);
315
316
  } catch (e) {
316
- 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.");
317
318
  }
318
- I(!1), P(null), await K();
319
- }, Ft = (e) => {
320
- x(`/agents/${e.id}`);
321
- }, It = (e) => {
322
- A(e);
323
- }, Lt = async () => {
324
- if (!k) return;
325
- 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() || "";
326
327
  try {
327
- et(!0), await Ct({
328
+ k(!0), await Et({
328
329
  variables: {
329
330
  id: e,
330
331
  input: {
@@ -334,283 +335,290 @@ function y() {
334
335
  }
335
336
  },
336
337
  refetchQueries: ["ListAgents", "VibecontrolsAgentHealthProbes"]
337
- }), t && tt(e), A(null);
338
+ }), t && it(e), D(null);
338
339
  } catch (e) {
339
340
  console.error("Failed to update tunnel settings:", e);
340
341
  } finally {
341
- et(!1);
342
+ k(!1);
342
343
  }
343
- }, Rt = s((e) => {
344
+ }, Ht = o((e) => {
344
345
  R((t) => {
345
346
  let n = new Set(t);
346
347
  return n.has(e) ? n.delete(e) : n.add(e), n;
347
348
  });
348
- }, []), zt = s(() => {
349
- R(new Set(Z.map((e) => e.id)));
350
- }, [Z]), Bt = s(() => {
349
+ }, []), Ut = o(() => {
350
+ R(new Set(Q.map((e) => e.id)));
351
+ }, [Q]), Wt = o(() => {
351
352
  R(/* @__PURE__ */ new Set());
352
- }, []), Vt = Z.length > 0 && L.size === Z.length, Ht = L.size > 0, Ut = s(async () => {
353
- 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 }))) {
354
- 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);
355
356
  try {
356
- 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;
357
- 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());
358
359
  } catch (e) {
359
- W(e instanceof Error ? e.message : "Failed to remove agents");
360
+ G(e instanceof Error ? e.message : "Failed to remove agents");
360
361
  } finally {
361
- st(!1);
362
+ lt(!1);
362
363
  }
363
364
  }
364
365
  }, [
365
366
  L,
366
- wt,
367
- W,
368
- U
369
- ]), Wt = {
370
- total: X.length,
371
- active: X.filter((e) => e.isActive).length,
372
- 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
373
374
  };
374
- return ze ? /* @__PURE__ */ m(v, {
375
+ return We ? /* @__PURE__ */ p(g, {
375
376
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
376
- children: /* @__PURE__ */ m(o, { message: S("agentsPage.loadingPermissions", "Loading permissions...") })
377
- }) : 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, {
378
379
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
379
- children: /* @__PURE__ */ m(Ie, {
380
- title: S("agentsPage.accessDeniedTitle", "Access Denied"),
381
- 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.")
382
383
  })
383
- }) : G && X.length === 0 ? /* @__PURE__ */ m(v, {
384
+ }) : K && Z.length === 0 ? /* @__PURE__ */ p(g, {
384
385
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
385
- children: /* @__PURE__ */ m(o, { message: S("agentsPage.loadingAgents", "Loading agents...") })
386
- }) : 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, {
387
388
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
388
- children: /* @__PURE__ */ m(de, {
389
- title: S("agentsPage.failedLoad", "Failed to load agents"),
390
- message: Ot.message,
391
- onRetry: () => K()
389
+ children: /* @__PURE__ */ p(fe, {
390
+ title: y("agentsPage.failedLoad", "Failed to load agents"),
391
+ message: jt.message,
392
+ onRetry: () => q()
392
393
  })
393
- }) : /* @__PURE__ */ h(v, {
394
+ }) : /* @__PURE__ */ m(g, {
394
395
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
395
396
  children: [
396
- ct && /* @__PURE__ */ m("div", {
397
+ z && /* @__PURE__ */ p("div", {
397
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",
398
- children: ct
399
+ children: z
399
400
  }),
400
- lt && /* @__PURE__ */ m("div", {
401
+ ut && /* @__PURE__ */ p("div", {
401
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",
402
- children: lt
403
+ children: ut
403
404
  }),
404
- /* @__PURE__ */ m(ue, {
405
- title: S("agentsPage.title", "Agents"),
406
- description: S("agentsPage.descriptionOnline", "{{active}} of {{total}} agents online", {
407
- active: Wt.active,
408
- 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
409
410
  }),
410
- actions: /* @__PURE__ */ h("div", {
411
+ actions: /* @__PURE__ */ m("div", {
411
412
  className: "flex w-full flex-col items-end gap-2 sm:w-auto sm:flex-row sm:items-center",
412
- children: [/* @__PURE__ */ m("button", {
413
+ children: [/* @__PURE__ */ p("button", {
413
414
  onClick: () => {
414
- K(), q.refetch();
415
+ q(), J.refetch();
415
416
  },
416
- disabled: G || q.loading,
417
+ disabled: K || J.loading,
417
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",
418
- title: S("agentsPage.refreshTitle", "Refresh agents"),
419
- children: /* @__PURE__ */ m(Ae, { className: `w-4 h-4 ${G || q.loading ? "animate-spin" : ""}` })
420
- }), St ? /* @__PURE__ */ m(Le, {
421
- 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,
422
423
  deniedBehavior: "disable",
423
- deniedTooltip: S("agentsPage.deniedCreateTooltip", "You don't have permission to create agents"),
424
- children: /* @__PURE__ */ h("button", {
425
- onClick: Q,
424
+ deniedTooltip: y("agentsPage.deniedCreateTooltip", "You don't have permission to create agents"),
425
+ children: /* @__PURE__ */ m("button", {
426
+ onClick: $,
426
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",
427
- 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")]
428
429
  })
429
- }) : /* @__PURE__ */ h("button", {
430
- onClick: Q,
430
+ }) : /* @__PURE__ */ m("button", {
431
+ onClick: $,
431
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",
432
- 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")]
433
434
  })]
434
435
  })
435
436
  }),
436
- X.length === 0 && !G && /* @__PURE__ */ m(_e, {
437
+ Z.length === 0 && !K && /* @__PURE__ */ p(be, {
437
438
  variant: "full",
438
439
  dismissKey: "vibecontrols-agents-setup-banner"
439
440
  }),
440
- X.length > 0 && /* @__PURE__ */ m(_e, {
441
+ Z.length > 0 && /* @__PURE__ */ p(be, {
441
442
  variant: "compact",
442
443
  dismissKey: "vibecontrols-agents-compact-banner"
443
444
  }),
444
- /* @__PURE__ */ h("div", {
445
+ /* @__PURE__ */ m("div", {
445
446
  className: "space-y-3",
446
- children: [/* @__PURE__ */ h("div", {
447
+ children: [/* @__PURE__ */ m("div", {
447
448
  className: "flex items-center gap-2",
448
- children: [/* @__PURE__ */ m(he, {
449
- value: C,
450
- onChange: Ge,
451
- placeholder: S("agentsPage.searchPlaceholder", "Search agents..."),
449
+ children: [/* @__PURE__ */ p(ve, {
450
+ value: b,
451
+ onChange: Xe,
452
+ placeholder: y("agentsPage.searchPlaceholder", "Search agents..."),
452
453
  className: "flex-1 sm:w-64 sm:flex-none"
453
- }), /* @__PURE__ */ h("div", {
454
+ }), /* @__PURE__ */ m("div", {
454
455
  className: "flex items-center gap-1 bg-bg-sunken rounded-md p-1 flex-shrink-0",
455
- children: [/* @__PURE__ */ m("button", {
456
+ children: [/* @__PURE__ */ p("button", {
456
457
  onClick: () => {
457
- Ye("grid"), R(/* @__PURE__ */ new Set());
458
+ et("grid"), R(/* @__PURE__ */ new Set());
458
459
  },
459
- className: `p-1.5 sm:p-2 rounded ${D === "grid" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
460
- title: S("agentsPage.gridViewTitle", "Grid view"),
461
- children: /* @__PURE__ */ m(Oe, { className: "w-4 h-4 text-text-secondary" })
462
- }), /* @__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", {
463
464
  onClick: () => {
464
- Ye("list"), R(/* @__PURE__ */ new Set());
465
+ et("list"), R(/* @__PURE__ */ new Set());
465
466
  },
466
- className: `p-1.5 sm:p-2 rounded ${D === "list" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
467
- title: S("agentsPage.listViewTitle", "List view"),
468
- 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" })
469
470
  })]
470
471
  })]
471
- }), /* @__PURE__ */ h("div", {
472
+ }), /* @__PURE__ */ m("div", {
472
473
  className: "flex items-center gap-2 sm:gap-3 flex-wrap",
473
474
  children: [
474
- /* @__PURE__ */ m(ge, {
475
- label: S("agentsPage.filterStatus", "Status"),
476
- value: w,
477
- options: He,
478
- onChange: Ke
475
+ /* @__PURE__ */ p(ye, {
476
+ label: y("agentsPage.filterStatus", "Status"),
477
+ value: x,
478
+ options: qe,
479
+ onChange: Ze
479
480
  }),
480
- /* @__PURE__ */ m(ge, {
481
- label: S("agentsPage.filterPlatform", "Platform"),
482
- value: T,
483
- options: Ue,
484
- onChange: qe
481
+ /* @__PURE__ */ p(ye, {
482
+ label: y("agentsPage.filterPlatform", "Platform"),
483
+ value: S,
484
+ options: Je,
485
+ onChange: Qe
485
486
  }),
486
- /* @__PURE__ */ m(ye, {
487
- label: S("agentsPage.filterTag", "Tag"),
488
- value: E,
489
- onChange: Je
487
+ /* @__PURE__ */ p(Se, {
488
+ label: y("agentsPage.filterTag", "Tag"),
489
+ value: C,
490
+ onChange: $e
490
491
  })
491
492
  ]
492
493
  })]
493
494
  }),
494
- Z.length > 0 && /* @__PURE__ */ m("div", {
495
+ Q.length > 0 && /* @__PURE__ */ p("div", {
495
496
  className: "flex items-center gap-2 flex-wrap",
496
- children: /* @__PURE__ */ m("div", {
497
+ children: /* @__PURE__ */ p("div", {
497
498
  className: "ml-auto flex items-center gap-2",
498
- children: /* @__PURE__ */ h("button", {
499
- onClick: Vt ? Bt : zt,
499
+ children: /* @__PURE__ */ m("button", {
500
+ onClick: Gt ? Wt : Ut,
500
501
  className: "flex items-center gap-1.5 px-3 py-1.5 text-xs text-text-secondary hover:text-text-primary transition-colors",
501
- 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")]
502
503
  })
503
504
  })
504
505
  }),
505
- Ht && /* @__PURE__ */ h("div", {
506
+ Kt && /* @__PURE__ */ m("div", {
506
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",
507
- children: [/* @__PURE__ */ m("span", {
508
+ children: [/* @__PURE__ */ p("span", {
508
509
  className: "text-sm font-medium text-text-primary",
509
- children: S("agentsPage.selectedCount", "{{count}} agents selected", { count: L.size })
510
- }), /* @__PURE__ */ h("div", {
510
+ children: y("agentsPage.selectedCount", "{{count}} agents selected", { count: L.size })
511
+ }), /* @__PURE__ */ m("div", {
511
512
  className: "flex items-center gap-1.5 sm:ml-auto",
512
- children: [/* @__PURE__ */ h("button", {
513
- onClick: Ut,
514
- disabled: ot,
513
+ children: [/* @__PURE__ */ m("button", {
514
+ onClick: qt,
515
+ disabled: ct,
515
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",
516
517
  children: [
517
- /* @__PURE__ */ m(je, { className: "w-3 h-3" }),
518
+ /* @__PURE__ */ p(Pe, { className: "w-3 h-3" }),
518
519
  " ",
519
- S("agentsPage.remove", "Remove")
520
+ y("agentsPage.remove", "Remove")
520
521
  ]
521
- }), /* @__PURE__ */ h("button", {
522
- onClick: Bt,
522
+ }), /* @__PURE__ */ m("button", {
523
+ onClick: Wt,
523
524
  className: "flex items-center gap-1.5 px-3 py-1.5 text-xs text-text-secondary hover:text-text-primary transition-colors",
524
525
  children: [
525
- /* @__PURE__ */ m(Me, { className: "w-3 h-3" }),
526
+ /* @__PURE__ */ p(Fe, { className: "w-3 h-3" }),
526
527
  " ",
527
- S("agentsPage.deselect", "Deselect")
528
+ y("agentsPage.deselect", "Deselect")
528
529
  ]
529
530
  })]
530
531
  })]
531
532
  }),
532
- C || w !== "all" || T !== "all" ? /* @__PURE__ */ h("p", {
533
+ b || x !== "all" || S !== "all" ? /* @__PURE__ */ m("p", {
533
534
  className: "text-sm text-text-secondary",
534
- children: [S("agentsPage.showingResults", "Showing {{filtered}} of {{total}} agents", {
535
- filtered: Z.length,
536
- total: X.length
537
- }), 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", {
538
539
  className: "ml-2 text-text-muted",
539
- children: S("agentsPage.refreshing", "(refreshing...)")
540
+ children: y("agentsPage.refreshing", "(refreshing...)")
540
541
  })]
541
542
  }) : null,
542
- Z.length > 0 ? /* @__PURE__ */ m(p, {
543
+ Q.length > 0 ? /* @__PURE__ */ p(f, {
543
544
  mode: "wait",
544
- children: D === "grid" ? /* @__PURE__ */ m(_, {
545
+ children: w === "grid" ? /* @__PURE__ */ p(h, {
545
546
  stagger: .04,
546
547
  className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
547
- children: Z.map((e) => /* @__PURE__ */ m(g, { children: /* @__PURE__ */ m(xe, {
548
+ children: Q.map((e) => /* @__PURE__ */ p(ze, { children: /* @__PURE__ */ p(we, {
548
549
  agent: e,
549
- onSelect: At,
550
- onStart: Mt,
551
- onStop: Nt,
552
- onDisconnect: $,
553
- onConfigure: Ft,
554
- onEditTunnelUrl: It,
550
+ onSelect: Nt,
551
+ onStart: Ft,
552
+ onStop: It,
553
+ onDisconnect: Lt,
554
+ onConfigure: zt,
555
+ onEditTunnelUrl: Bt,
555
556
  selected: L.has(e.id),
556
- onToggleSelect: () => Rt(e.id),
557
+ onToggleSelect: () => Ht(e.id),
557
558
  healthErrorMessage: e.healthError ?? null
558
559
  }) }, e.id))
559
- }, "grid-view") : /* @__PURE__ */ m(_, {
560
+ }, "grid-view") : /* @__PURE__ */ p(h, {
560
561
  stagger: .04,
561
- children: /* @__PURE__ */ m(g, {
562
+ children: /* @__PURE__ */ p(ze, {
562
563
  variant: "fadeRight",
563
- children: /* @__PURE__ */ m(Se, {
564
- agents: Z,
565
- onSelect: At,
566
- onStart: Mt,
567
- onStop: Nt,
568
- onDisconnect: $,
569
- 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
570
571
  })
571
572
  })
572
573
  }, "list-view")
573
- }) : /* @__PURE__ */ m(me, {
574
- icon: /* @__PURE__ */ m(Ee, { className: "w-8 h-8 text-text-secondary" }),
575
- title: C || w !== "all" || T !== "all" ? S("agentsPage.emptyNoAgentsFound", "No agents found") : S("agentsPage.emptyNoAgentsConfigured", "No agents configured"),
576
- 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."),
577
- 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", {
578
579
  className: "flex flex-wrap items-center gap-3",
579
580
  children: [
580
- /* @__PURE__ */ h("button", {
581
- onClick: Q,
581
+ /* @__PURE__ */ m("button", {
582
+ onClick: $,
582
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",
583
- 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")]
584
585
  }),
585
- /* @__PURE__ */ m("button", {
586
- onClick: () => x("/getting-started"),
586
+ /* @__PURE__ */ p("button", {
587
+ onClick: () => v("/getting-started"),
587
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",
588
- children: S("agentsPage.setupGuide", "Setup guide")
589
+ children: y("agentsPage.setupGuide", "Setup guide")
589
590
  }),
590
- /* @__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?" })
591
592
  ]
592
593
  }) : void 0
593
594
  }),
594
- Xe && /* @__PURE__ */ m(Ce, {
595
- onSubmit: jt,
596
- onCancel: () => O(!1),
597
- isLoading: Ze,
595
+ tt && /* @__PURE__ */ p(Ee, {
596
+ onSubmit: Pt,
597
+ onCancel: () => T(!1),
598
+ isLoading: nt,
598
599
  onNavigate: (e) => {
599
- O(!1), x(e);
600
+ T(!1), v(e);
600
601
  },
601
- targets: bt.map((e) => ({
602
+ targets: Ct.map((e) => ({
602
603
  id: e.id,
603
604
  name: e.name,
604
605
  type: e.type || "DIRECT",
605
606
  status: e.status
606
607
  })),
607
- targetsLoading: xt,
608
- 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
+ })] })
609
617
  }),
610
- /* @__PURE__ */ m(p, { children: N && /* @__PURE__ */ m("div", {
618
+ /* @__PURE__ */ p(f, { children: N && /* @__PURE__ */ p("div", {
611
619
  className: "fixed inset-0 bg-bg-overlay flex items-center justify-center z-50 p-4 sm:p-6",
612
620
  onClick: () => !F && P(null),
613
- children: /* @__PURE__ */ h(Pe.div, {
621
+ children: /* @__PURE__ */ m(Le.div, {
614
622
  initial: {
615
623
  opacity: 0,
616
624
  scale: .95
@@ -627,32 +635,32 @@ function y() {
627
635
  className: "bg-bg-surface border border-border-default rounded-lg shadow-xl w-full max-w-sm p-4 sm:p-6",
628
636
  onClick: (e) => e.stopPropagation(),
629
637
  children: [
630
- /* @__PURE__ */ m("h3", {
638
+ /* @__PURE__ */ p("h3", {
631
639
  className: "text-lg font-semibold text-text-primary mb-1",
632
640
  children: "Disconnect Agent"
633
641
  }),
634
- /* @__PURE__ */ m("p", {
642
+ /* @__PURE__ */ p("p", {
635
643
  className: "text-sm text-text-secondary mb-4",
636
- children: we(N) === "OFFLINE" ? /* @__PURE__ */ h(Fe, { children: [
644
+ children: De(N) === "OFFLINE" ? /* @__PURE__ */ m(Re, { children: [
637
645
  "Clear the stored tunnel connection for",
638
646
  " ",
639
- /* @__PURE__ */ m("strong", { children: N.name }),
647
+ /* @__PURE__ */ p("strong", { children: N.name }),
640
648
  "? This will remove the tunnel URL and API key from this offline agent."
641
- ] }) : /* @__PURE__ */ h(Fe, { children: [
649
+ ] }) : /* @__PURE__ */ m(Re, { children: [
642
650
  "Mark ",
643
- /* @__PURE__ */ m("strong", { children: N.name }),
651
+ /* @__PURE__ */ p("strong", { children: N.name }),
644
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."
645
653
  ] })
646
654
  }),
647
- /* @__PURE__ */ h("div", {
655
+ /* @__PURE__ */ m("div", {
648
656
  className: "flex justify-end gap-2",
649
- children: [/* @__PURE__ */ m("button", {
657
+ children: [/* @__PURE__ */ p("button", {
650
658
  onClick: () => P(null),
651
659
  disabled: F,
652
660
  className: "px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50",
653
661
  children: "Cancel"
654
- }), /* @__PURE__ */ m("button", {
655
- onClick: Pt,
662
+ }), /* @__PURE__ */ p("button", {
663
+ onClick: Rt,
656
664
  disabled: F,
657
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",
658
666
  children: F ? "Disconnecting..." : "Disconnect"
@@ -661,10 +669,10 @@ function y() {
661
669
  ]
662
670
  })
663
671
  }) }),
664
- /* @__PURE__ */ m(p, { children: k && /* @__PURE__ */ m("div", {
672
+ /* @__PURE__ */ p(f, { children: E && /* @__PURE__ */ p("div", {
665
673
  className: "fixed inset-0 bg-bg-overlay flex items-center justify-center z-50 p-4 sm:p-6",
666
- onClick: () => A(null),
667
- children: /* @__PURE__ */ h(Pe.div, {
674
+ onClick: () => D(null),
675
+ children: /* @__PURE__ */ m(Le.div, {
668
676
  initial: {
669
677
  opacity: 0,
670
678
  scale: .95
@@ -681,72 +689,72 @@ function y() {
681
689
  className: "bg-bg-surface border border-border-default rounded-lg shadow-xl w-full max-w-md p-4 sm:p-6",
682
690
  onClick: (e) => e.stopPropagation(),
683
691
  children: [
684
- /* @__PURE__ */ m("h3", {
692
+ /* @__PURE__ */ p("h3", {
685
693
  className: "text-lg font-semibold text-text-primary mb-1",
686
- children: S("agentsPage.editTunnelTitle", "Edit Tunnel")
694
+ children: y("agentsPage.editTunnelTitle", "Edit Tunnel")
687
695
  }),
688
- /* @__PURE__ */ m("p", {
696
+ /* @__PURE__ */ p("p", {
689
697
  className: "text-sm text-text-secondary mb-4",
690
- 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 })
691
699
  }),
692
- /* @__PURE__ */ h("div", {
700
+ /* @__PURE__ */ m("div", {
693
701
  className: "space-y-4",
694
- children: [/* @__PURE__ */ h("div", { children: [
695
- /* @__PURE__ */ m("label", {
702
+ children: [/* @__PURE__ */ m("div", { children: [
703
+ /* @__PURE__ */ p("label", {
696
704
  className: "block text-sm font-medium text-text-primary mb-1",
697
- children: S("agentsPage.tunnelUrlLabel", "Tunnel URL")
705
+ children: y("agentsPage.tunnelUrlLabel", "Tunnel URL")
698
706
  }),
699
- /* @__PURE__ */ m("input", {
700
- ref: it,
707
+ /* @__PURE__ */ p("input", {
708
+ ref: ot,
701
709
  type: "url",
702
- defaultValue: k.tunnelUrl || "",
703
- placeholder: S("agentsPage.tunnelUrlPlaceholder", "https://example.trycloudflare.com"),
710
+ defaultValue: E.tunnelUrl || "",
711
+ placeholder: y("agentsPage.tunnelUrlPlaceholder", "https://example.trycloudflare.com"),
704
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",
705
713
  autoFocus: !0
706
714
  }),
707
- /* @__PURE__ */ m("p", {
715
+ /* @__PURE__ */ p("p", {
708
716
  className: "text-xs text-text-muted mt-1",
709
- 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.")
710
718
  })
711
- ] }), /* @__PURE__ */ h("div", { children: [
712
- /* @__PURE__ */ m("label", {
719
+ ] }), /* @__PURE__ */ m("div", { children: [
720
+ /* @__PURE__ */ p("label", {
713
721
  className: "block text-sm font-medium text-text-primary mb-1",
714
- children: S("agentsPage.agentApiKeyLabel", "Agent API Key")
722
+ children: y("agentsPage.agentApiKeyLabel", "Agent API Key")
715
723
  }),
716
- /* @__PURE__ */ m("input", {
717
- ref: at,
724
+ /* @__PURE__ */ p("input", {
725
+ ref: st,
718
726
  type: "text",
719
- defaultValue: k.agentApiKey || "",
720
- placeholder: S("agentsPage.agentApiKeyPlaceholder", "sk-agent-..."),
727
+ defaultValue: E.agentApiKey || "",
728
+ placeholder: y("agentsPage.agentApiKeyPlaceholder", "sk-agent-..."),
721
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"
722
730
  }),
723
- /* @__PURE__ */ m("p", {
731
+ /* @__PURE__ */ p("p", {
724
732
  className: "text-xs text-text-muted mt-1",
725
- 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.")
726
734
  })
727
735
  ] })]
728
736
  }),
729
- /* @__PURE__ */ h("div", {
737
+ /* @__PURE__ */ m("div", {
730
738
  className: "flex justify-end gap-2 mt-5",
731
- children: [/* @__PURE__ */ m("button", {
732
- onClick: () => A(null),
739
+ children: [/* @__PURE__ */ p("button", {
740
+ onClick: () => D(null),
733
741
  className: "px-4 py-2 text-sm text-text-secondary hover:bg-bg-sunken rounded-md transition-colors",
734
- children: S("agentsPage.cancel", "Cancel")
735
- }), /* @__PURE__ */ m("button", {
736
- onClick: Lt,
737
- disabled: $e,
742
+ children: y("agentsPage.cancel", "Cancel")
743
+ }), /* @__PURE__ */ p("button", {
744
+ onClick: Vt,
745
+ disabled: O,
738
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",
739
- children: $e ? S("agentsPage.saving", "Saving...") : S("agentsPage.save", "Save")
747
+ children: O ? y("agentsPage.saving", "Saving...") : y("agentsPage.save", "Save")
740
748
  })]
741
749
  })
742
750
  ]
743
751
  })
744
752
  }) }),
745
- /* @__PURE__ */ m(fe, {
746
- isOpen: ut,
747
- onClose: () => V(!1),
753
+ /* @__PURE__ */ p(pe, {
754
+ isOpen: dt,
755
+ onClose: () => H(!1),
748
756
  onConfirm: () => {
749
- V(!1), x("/billing");
757
+ H(!1), v("/billing");
750
758
  },
751
759
  title: "Agent Quota Reached",
752
760
  message: "You've used all available agent slots on your current plan. Upgrade your plan to register more agents."
@@ -755,6 +763,6 @@ function y() {
755
763
  });
756
764
  }
757
765
  //#endregion
758
- export { y as AgentsPage };
766
+ export { He as AgentsPage };
759
767
 
760
768
  //# sourceMappingURL=AgentsPage.js.map