@burdenoff/microfe-vibecontrols 2026.529.9 → 2026.529.10

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.
@@ -1,22 +1,32 @@
1
1
  import { SearchableSelect as e } from "../shared/SearchableSelect.js";
2
2
  import "../shared/index.js";
3
- import { useCallback as t, useState as n } from "react";
4
- import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
- import { Check as i, CheckCircle2 as a, ChevronDown as o, ChevronLeft as ee, ChevronRight as s, Copy as te, Download as ne, Eye as re, EyeOff as ie, Loader2 as c, Plus as l, RefreshCw as u, Settings2 as ae, Terminal as oe, X as se, XCircle as d } from "lucide-react";
6
- import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
3
+ import { useCallback as t, useEffect as n, useState as r } from "react";
4
+ import { useI18n as i } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
+ import { Check as a, CheckCircle2 as o, ChevronDown as ee, ChevronLeft as te, ChevronRight as s, Copy as ne, Download as re, Eye as ie, EyeOff as ae, Loader2 as c, Plus as oe, RefreshCw as se, Settings2 as ce, Terminal as le, X as ue, XCircle as l } from "lucide-react";
6
+ import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
7
7
  //#region src/components/agents/AgentForm.tsx
8
- function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y, targetsLoading: b, onCreateTarget: x, extraSection: ce }) {
9
- let { t: le } = r(), S = (e, t) => {
10
- let n = le(e);
8
+ function p({ onSubmit: p, onCancel: m, isLoading: h, onNavigate: de, targets: g, targetsLoading: fe, onCreateTarget: _, extraSection: v }) {
9
+ let { t: pe } = i(), y = (e, t) => {
10
+ let n = pe(e);
11
11
  return n === e ? t : n;
12
- }, [C, w] = n("details"), [T, ue] = n(!1), [E, de] = n(!1), [fe, D] = n(null), [O, pe] = n(""), [k, A] = n(""), [j, M] = n(""), [N, P] = n(""), [F, I] = n(!1), [L, R] = n(""), [z, B] = n(!1), [V, H] = n(null), [U, me] = n(!1), [W, G] = n(null), [K, q] = n(null), [J, he] = n(""), [ge, _e] = n("linux"), [ve, ye] = n("x86_64"), [be, xe] = n("1.0.0"), [Se, Y] = n(null), [X, Ce] = n(!1), [we, Te] = n("default"), Ee = t((e, t) => {
13
- navigator.clipboard.writeText(e), D(t), setTimeout(() => D(null), 2e3);
14
- }, []), De = (e) => {
12
+ }, [b, x] = r("details"), [S, me] = r(!1), [C, he] = r(!1), [ge, w] = r(null), [T, E] = r(""), [D, _e] = r(!1), [O, k] = r(""), [A, j] = r(""), [M, N] = r("");
13
+ n(() => {
14
+ if (D || !M) return;
15
+ let e = (g ?? []).find((e) => e.id === M);
16
+ e?.name && E(e.name);
17
+ }, [
18
+ M,
19
+ g,
20
+ D
21
+ ]);
22
+ let [P, F] = r(!1), [I, L] = r(""), [R, z] = r(!1), [B, V] = r(null), [H, U] = r(!1), [W, G] = r(null), [K, q] = r(null), [J, ve] = r(""), [ye, be] = r("linux"), [xe, Se] = r("x86_64"), [Ce, we] = r("1.0.0"), [Te, Y] = r(null), [X, Ee] = r(!1), [De, Oe] = r("default"), ke = t((e, t) => {
23
+ navigator.clipboard.writeText(e), w(t), setTimeout(() => w(null), 2e3);
24
+ }, []), Ae = (e) => {
15
25
  let t = e.trim();
16
26
  return t.endsWith("/") && (t = t.slice(0, -1)), t;
17
- }, Oe = async () => {
18
- let e = De(k);
19
- e && (me(!0), G(null), q(null), await Promise.all([(async () => {
27
+ }, je = async () => {
28
+ let e = Ae(O);
29
+ e && (U(!0), G(null), q(null), await Promise.all([(async () => {
20
30
  try {
21
31
  let t = await fetch(`${e}/health`, { signal: AbortSignal.timeout(1e4) });
22
32
  if (!t.ok) {
@@ -34,7 +44,7 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
34
44
  version: n.version || "unknown",
35
45
  uptime: n.uptime || 0
36
46
  }
37
- }), n.version && xe(n.version);
47
+ }), n.version && we(n.version);
38
48
  } catch (e) {
39
49
  G({
40
50
  ok: !1,
@@ -44,7 +54,7 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
44
54
  })(), (async () => {
45
55
  try {
46
56
  let t = {};
47
- j && (t["x-agent-api-key"] = j);
57
+ A && (t["x-agent-api-key"] = A);
48
58
  let n = await fetch(`${e}/api/profiles/default/agent/identity`, {
49
59
  headers: t,
50
60
  signal: AbortSignal.timeout(1e4)
@@ -64,399 +74,399 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
64
74
  platform: a,
65
75
  arch: o
66
76
  }
67
- }), i && he(i), a && _e(a), o && ye(o), !O && i && pe(i);
77
+ }), i && ve(i), a && be(a), o && Se(o), !D && !M && i && E(i);
68
78
  } catch (e) {
69
79
  q({
70
80
  ok: !1,
71
81
  error: e instanceof DOMException && e.name === "AbortError" ? "Identity check timed out after 10s" : e instanceof Error ? e.message : "Identity check failed"
72
82
  });
73
83
  }
74
- })()]), me(!1));
75
- }, ke = async () => {
84
+ })()]), U(!1));
85
+ }, Me = async () => {
76
86
  Y(null);
77
- let e = we.trim() || "default", t = {
78
- name: O || J || "Unnamed Agent",
87
+ let e = De.trim() || "default", t = {
88
+ name: T || J || "Unnamed Agent",
79
89
  hostname: J || "unknown",
80
- platform: ge,
81
- architecture: ve,
82
- version: be,
83
- tunnelUrl: De(k),
90
+ platform: ye,
91
+ architecture: xe,
92
+ version: Ce,
93
+ tunnelUrl: Ae(O),
84
94
  tunnelStatus: "ACTIVE",
85
- agentApiKey: j,
95
+ agentApiKey: A,
86
96
  metadata: { profile: e },
87
- ...N ? { targetId: N } : {}
97
+ ...M ? { targetId: M } : {}
88
98
  };
89
99
  try {
90
- let e = (await h(t))?.id || null;
100
+ let e = (await p(t))?.id || null;
91
101
  if (!e) {
92
102
  Y("Agent creation returned no ID. The agent may already exist.");
93
103
  return;
94
104
  }
95
- v ? v(`/agents/${e}`) : g();
105
+ de ? de(`/agents/${e}`) : m();
96
106
  } catch (e) {
97
107
  Y(e instanceof Error ? e.message : "Failed to create agent");
98
108
  }
99
- }, Ae = W?.ok && K?.ok, Z = y && y.length > 0, je = (x || Z) && N.length === 0, Me = k.trim().length > 0 && !je, Ne = t(async () => {
100
- if (!(!x || !L.trim())) {
101
- B(!0), H(null);
109
+ }, Ne = W?.ok && K?.ok, Z = g && g.length > 0, Pe = (_ || Z) && M.length === 0, Fe = O.trim().length > 0 && !Pe, Ie = t(async () => {
110
+ if (!(!_ || !I.trim())) {
111
+ z(!0), V(null);
102
112
  try {
103
- let e = await x(L.trim());
104
- e ? (P(e.id), I(!1), R("")) : H(S("agentsPage.inlineTargetFailed", "Failed to create target. Please try again."));
113
+ let e = await _(I.trim());
114
+ e ? (N(e.id), F(!1), L("")) : V(y("agentsPage.inlineTargetFailed", "Failed to create target. Please try again."));
105
115
  } catch (e) {
106
- H(e instanceof Error ? e.message : "Failed to create target");
116
+ V(e instanceof Error ? e.message : "Failed to create target");
107
117
  } finally {
108
- B(!1);
118
+ z(!1);
109
119
  }
110
120
  }
111
121
  }, [
112
- x,
113
- L,
114
- S
115
- ]), Pe = (e, t) => /* @__PURE__ */ p("button", {
122
+ _,
123
+ I,
124
+ y
125
+ ]), Le = (e, t) => /* @__PURE__ */ d("button", {
116
126
  type: "button",
117
- onClick: () => Ee(e, t),
127
+ onClick: () => ke(e, t),
118
128
  className: "p-1 rounded hover:bg-bg-elevated transition-colors",
119
- title: S("agentsPage.copy", "Copy"),
120
- children: fe === t ? /* @__PURE__ */ p(i, { className: "size-3.5 text-status-success-text" }) : /* @__PURE__ */ p(te, { className: "size-3.5 text-text-secondary" })
129
+ title: y("agentsPage.copy", "Copy"),
130
+ children: ge === t ? /* @__PURE__ */ d(a, { className: "size-3.5 text-status-success-text" }) : /* @__PURE__ */ d(ne, { className: "size-3.5 text-text-secondary" })
121
131
  }), Q = [{
122
132
  key: "details",
123
133
  label: "Setup"
124
134
  }, {
125
135
  key: "validate",
126
136
  label: "Validate"
127
- }], $ = Q.findIndex((e) => e.key === C);
128
- return /* @__PURE__ */ p("div", {
137
+ }], $ = Q.findIndex((e) => e.key === b);
138
+ return /* @__PURE__ */ d("div", {
129
139
  className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay",
130
- children: /* @__PURE__ */ m("div", {
140
+ children: /* @__PURE__ */ f("div", {
131
141
  className: "w-full max-w-xl bg-bg-surface rounded-lg shadow-xl max-h-[90vh] overflow-y-auto",
132
142
  children: [
133
- /* @__PURE__ */ m("div", {
143
+ /* @__PURE__ */ f("div", {
134
144
  className: "flex items-center justify-between px-6 py-4 border-b border-border-default sticky top-0 bg-bg-surface z-10",
135
- children: [/* @__PURE__ */ p("h2", {
145
+ children: [/* @__PURE__ */ d("h2", {
136
146
  className: "text-lg font-semibold text-text-primary",
137
- children: S("agentsPage.addNewAgent", "Add New Agent")
138
- }), /* @__PURE__ */ p("button", {
147
+ children: y("agentsPage.addNewAgent", "Add New Agent")
148
+ }), /* @__PURE__ */ d("button", {
139
149
  type: "button",
140
- onClick: g,
150
+ onClick: m,
141
151
  className: "p-1 rounded hover:bg-bg-sunken transition-colors",
142
- children: /* @__PURE__ */ p(se, { className: "size-5 text-text-secondary" })
152
+ children: /* @__PURE__ */ d(ue, { className: "size-5 text-text-secondary" })
143
153
  })]
144
154
  }),
145
- /* @__PURE__ */ p("div", {
155
+ /* @__PURE__ */ d("div", {
146
156
  className: "flex items-center gap-2 px-6 pt-4 pb-2",
147
- children: Q.map((e, t) => /* @__PURE__ */ m("div", {
157
+ children: Q.map((e, t) => /* @__PURE__ */ f("div", {
148
158
  className: "flex items-center gap-2",
149
159
  children: [
150
- /* @__PURE__ */ p("div", {
160
+ /* @__PURE__ */ d("div", {
151
161
  className: `flex items-center justify-center size-7 rounded-full text-xs font-semibold transition-colors ${t < $ ? "bg-status-success-bg text-status-success-text" : t === $ ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary"}`,
152
- children: t < $ ? /* @__PURE__ */ p(a, { className: "size-4" }) : t + 1
162
+ children: t < $ ? /* @__PURE__ */ d(o, { className: "size-4" }) : t + 1
153
163
  }),
154
- /* @__PURE__ */ p("span", {
164
+ /* @__PURE__ */ d("span", {
155
165
  className: `text-sm ${t === $ ? "font-medium text-text-primary" : "text-text-secondary"}`,
156
166
  children: e.label
157
167
  }),
158
- t < Q.length - 1 && /* @__PURE__ */ p(s, { className: "size-4 text-text-muted" })
168
+ t < Q.length - 1 && /* @__PURE__ */ d(s, { className: "size-4 text-text-muted" })
159
169
  ]
160
170
  }, e.key))
161
171
  }),
162
- /* @__PURE__ */ m("div", {
172
+ /* @__PURE__ */ f("div", {
163
173
  className: "p-6",
164
- children: [C === "details" && /* @__PURE__ */ m("div", {
174
+ children: [b === "details" && /* @__PURE__ */ f("div", {
165
175
  className: "space-y-4",
166
176
  children: [
167
- /* @__PURE__ */ m("div", {
177
+ /* @__PURE__ */ f("div", {
168
178
  className: "border border-border-default rounded-lg overflow-hidden",
169
- children: [/* @__PURE__ */ m("button", {
179
+ children: [/* @__PURE__ */ f("button", {
170
180
  type: "button",
171
- onClick: () => de(!E),
181
+ onClick: () => he(!C),
172
182
  className: "w-full flex items-center justify-between px-4 py-3 bg-bg-sunken hover:bg-bg-sunken/80 transition-colors",
173
- children: [/* @__PURE__ */ m("div", {
183
+ children: [/* @__PURE__ */ f("div", {
174
184
  className: "flex items-center gap-2",
175
- children: [/* @__PURE__ */ p(ne, { className: "size-4 text-action-primary-bg" }), /* @__PURE__ */ p("span", {
185
+ children: [/* @__PURE__ */ d(re, { className: "size-4 text-action-primary-bg" }), /* @__PURE__ */ d("span", {
176
186
  className: "text-sm font-medium text-text-primary",
177
- children: S("agentsPage.installInstructions", "Agent Install Instructions")
187
+ children: y("agentsPage.installInstructions", "Agent Install Instructions")
178
188
  })]
179
- }), /* @__PURE__ */ p(s, { className: `size-4 text-text-secondary transition-transform ${E ? "rotate-90" : ""}` })]
180
- }), E && /* @__PURE__ */ p("div", {
189
+ }), /* @__PURE__ */ d(s, { className: `size-4 text-text-secondary transition-transform ${C ? "rotate-90" : ""}` })]
190
+ }), C && /* @__PURE__ */ d("div", {
181
191
  className: "px-4 py-3 space-y-3 border-t border-border-default",
182
- children: /* @__PURE__ */ p("div", {
192
+ children: /* @__PURE__ */ d("div", {
183
193
  className: "space-y-2",
184
194
  children: [
185
195
  {
186
- label: S("agentsPage.installStep1", "1. Install the agent CLI"),
196
+ label: y("agentsPage.installStep1", "1. Install the agent CLI"),
187
197
  cmd: "npm install -g @vibecontrols/agent@latest"
188
198
  },
189
199
  {
190
- label: S("agentsPage.installStep2", "2. Start the agent"),
200
+ label: y("agentsPage.installStep2", "2. Start the agent"),
191
201
  cmd: "vibe start"
192
202
  },
193
203
  {
194
- label: S("agentsPage.installStep3", "3. Get the API key"),
204
+ label: y("agentsPage.installStep3", "3. Get the API key"),
195
205
  cmd: "vibe key"
196
206
  },
197
207
  {
198
- label: S("agentsPage.installStep4", "4. Start the tunnel"),
208
+ label: y("agentsPage.installStep4", "4. Start the tunnel"),
199
209
  cmd: "vibe tunnel agent --start"
200
210
  }
201
- ].map((e) => /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
211
+ ].map((e) => /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("p", {
202
212
  className: "text-xs text-text-secondary mb-1",
203
213
  children: e.label
204
- }), /* @__PURE__ */ m("div", {
214
+ }), /* @__PURE__ */ f("div", {
205
215
  className: "flex items-center gap-2 bg-bg-sunken rounded-md px-3 py-1.5 font-mono text-xs text-text-primary",
206
216
  children: [
207
- /* @__PURE__ */ p(oe, { className: "size-3 text-text-muted flex-shrink-0" }),
208
- /* @__PURE__ */ p("code", {
217
+ /* @__PURE__ */ d(le, { className: "size-3 text-text-muted flex-shrink-0" }),
218
+ /* @__PURE__ */ d("code", {
209
219
  className: "flex-1",
210
220
  children: e.cmd
211
221
  }),
212
- Pe(e.cmd, e.cmd)
222
+ Le(e.cmd, e.cmd)
213
223
  ]
214
224
  })] }, e.cmd))
215
225
  })
216
226
  })]
217
227
  }),
218
- /* @__PURE__ */ m("div", { children: [
219
- /* @__PURE__ */ m("label", {
228
+ /* @__PURE__ */ f("div", { children: [
229
+ /* @__PURE__ */ f("label", {
220
230
  className: "block text-sm font-medium text-text-primary mb-1",
221
231
  children: [
222
- S("agentsPage.target", "Target"),
232
+ y("agentsPage.target", "Target"),
223
233
  " ",
224
- /* @__PURE__ */ p("span", {
234
+ /* @__PURE__ */ d("span", {
225
235
  className: "text-status-error-text",
226
236
  children: "*"
227
237
  })
228
238
  ]
229
239
  }),
230
- Z && !F && /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(e, {
231
- placeholder: S("agentsPage.selectTarget", "Select a target..."),
232
- searchPlaceholder: S("agentsPage.searchTargets", "Search targets..."),
233
- options: (y ?? []).map((e) => ({
240
+ Z && !P && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d(e, {
241
+ placeholder: y("agentsPage.selectTarget", "Select a target..."),
242
+ searchPlaceholder: y("agentsPage.searchTargets", "Search targets..."),
243
+ options: (g ?? []).map((e) => ({
234
244
  value: e.id,
235
245
  label: e.name,
236
246
  description: `${e.type}${e.status ? ` · ${e.status}` : ""}`
237
247
  })),
238
- value: N,
239
- onChange: P,
248
+ value: M,
249
+ onChange: N,
240
250
  clearable: !0
241
- }), /* @__PURE__ */ m("p", {
251
+ }), /* @__PURE__ */ f("p", {
242
252
  className: "mt-1 text-xs text-text-muted",
243
253
  children: [
244
- S("agentsPage.targetDescription", "The target machine this agent will be installed on."),
254
+ y("agentsPage.targetDescription", "The target machine this agent will be installed on."),
245
255
  " ",
246
- x && /* @__PURE__ */ m("button", {
256
+ _ && /* @__PURE__ */ f("button", {
247
257
  type: "button",
248
258
  onClick: () => {
249
- I(!0), R(O.trim() || "");
259
+ F(!0), L(T.trim() || "");
250
260
  },
251
261
  className: "text-action-primary-bg hover:underline inline-flex items-center gap-1",
252
- children: [/* @__PURE__ */ p(l, { className: "size-3" }), S("agentsPage.createNewTarget", "Create a new target")]
262
+ children: [/* @__PURE__ */ d(oe, { className: "size-3" }), y("agentsPage.createNewTarget", "Create a new target")]
253
263
  })
254
264
  ]
255
265
  })] }),
256
- !Z && !b && x && !F && /* @__PURE__ */ m("div", {
266
+ !Z && !fe && _ && !P && /* @__PURE__ */ f("div", {
257
267
  className: "p-3 bg-bg-sunken border border-border-default rounded-lg",
258
- children: [/* @__PURE__ */ p("p", {
268
+ children: [/* @__PURE__ */ d("p", {
259
269
  className: "text-sm text-text-secondary mb-2",
260
- children: S("agentsPage.noTargetsInlinePrompt", "You don't have any targets yet. Create one now to install this agent on it.")
261
- }), /* @__PURE__ */ m("button", {
270
+ children: y("agentsPage.noTargetsInlinePrompt", "You don't have any targets yet. Create one now to install this agent on it.")
271
+ }), /* @__PURE__ */ f("button", {
262
272
  type: "button",
263
273
  onClick: () => {
264
- I(!0), R(O.trim() || "");
274
+ F(!0), L(T.trim() || "");
265
275
  },
266
276
  className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:opacity-90",
267
- children: [/* @__PURE__ */ p(l, { className: "size-4" }), S("agentsPage.createFirstTarget", "Create first target")]
277
+ children: [/* @__PURE__ */ d(oe, { className: "size-4" }), y("agentsPage.createFirstTarget", "Create first target")]
268
278
  })]
269
279
  }),
270
- F && x && /* @__PURE__ */ m("div", {
280
+ P && _ && /* @__PURE__ */ f("div", {
271
281
  className: "p-3 bg-bg-sunken border border-border-default rounded-lg space-y-2",
272
282
  children: [
273
- /* @__PURE__ */ p("p", {
283
+ /* @__PURE__ */ d("p", {
274
284
  className: "text-xs font-medium text-text-secondary",
275
- children: S("agentsPage.newDirectTarget", "New target (Direct — you can change the type later)")
285
+ children: y("agentsPage.newDirectTarget", "New target (Direct — you can change the type later)")
276
286
  }),
277
- /* @__PURE__ */ p("input", {
287
+ /* @__PURE__ */ d("input", {
278
288
  "aria-label": "control",
279
289
  type: "text",
280
- value: L,
281
- onChange: (e) => R(e.target.value),
282
- placeholder: S("agentsPage.targetName", "Target name"),
290
+ value: I,
291
+ onChange: (e) => L(e.target.value),
292
+ placeholder: y("agentsPage.targetName", "Target name"),
283
293
  className: "w-full px-3 py-2 text-sm bg-bg-elevated border border-border-default rounded-md text-text-primary placeholder-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg",
284
294
  onKeyDown: (e) => {
285
- e.key === "Enter" && (e.preventDefault(), Ne());
295
+ e.key === "Enter" && (e.preventDefault(), Ie());
286
296
  }
287
297
  }),
288
- V && /* @__PURE__ */ p("p", {
298
+ B && /* @__PURE__ */ d("p", {
289
299
  className: "text-xs text-status-error-text",
290
- children: V
300
+ children: B
291
301
  }),
292
- /* @__PURE__ */ m("div", {
302
+ /* @__PURE__ */ f("div", {
293
303
  className: "flex items-center gap-2",
294
- children: [/* @__PURE__ */ m("button", {
304
+ children: [/* @__PURE__ */ f("button", {
295
305
  type: "button",
296
- onClick: () => void Ne(),
297
- disabled: !L.trim() || z,
306
+ onClick: () => void Ie(),
307
+ disabled: !I.trim() || R,
298
308
  className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:opacity-90 disabled:opacity-50",
299
- children: [z ? /* @__PURE__ */ p(c, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ p(i, { className: "size-3.5" }), S("agentsPage.create", "Create")]
300
- }), /* @__PURE__ */ p("button", {
309
+ children: [R ? /* @__PURE__ */ d(c, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ d(a, { className: "size-3.5" }), y("agentsPage.create", "Create")]
310
+ }), /* @__PURE__ */ d("button", {
301
311
  type: "button",
302
312
  onClick: () => {
303
- I(!1), R(""), H(null);
313
+ F(!1), L(""), V(null);
304
314
  },
305
315
  className: "px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary",
306
- children: S("agentsPage.cancel", "Cancel")
316
+ children: y("agentsPage.cancel", "Cancel")
307
317
  })]
308
318
  })
309
319
  ]
310
320
  }),
311
- b && !Z && /* @__PURE__ */ m("div", {
321
+ fe && !Z && /* @__PURE__ */ f("div", {
312
322
  className: "p-3 bg-bg-sunken border border-border-default rounded-lg flex items-center gap-2 text-sm text-text-secondary",
313
- children: [/* @__PURE__ */ p(c, { className: "size-4 animate-spin" }), S("agentsPage.loadingTargets", "Loading targets...")]
323
+ children: [/* @__PURE__ */ d(c, { className: "size-4 animate-spin" }), y("agentsPage.loadingTargets", "Loading targets...")]
314
324
  })
315
325
  ] }),
316
- /* @__PURE__ */ m("div", { children: [
317
- /* @__PURE__ */ m("label", {
326
+ /* @__PURE__ */ f("div", { children: [
327
+ /* @__PURE__ */ f("label", {
318
328
  className: "block text-sm font-medium text-text-primary mb-1",
319
329
  children: [
320
- S("agentsPage.apiTunnelUrl", "API / Tunnel URL"),
330
+ y("agentsPage.apiTunnelUrl", "API / Tunnel URL"),
321
331
  " ",
322
- /* @__PURE__ */ p("span", {
332
+ /* @__PURE__ */ d("span", {
323
333
  className: "text-status-error-text",
324
334
  children: "*"
325
335
  })
326
336
  ]
327
337
  }),
328
- /* @__PURE__ */ p("input", {
338
+ /* @__PURE__ */ d("input", {
329
339
  "aria-label": "https://your-tunnel.trycloudflare.com",
330
340
  type: "url",
331
- value: k,
332
- onChange: (e) => A(e.target.value),
341
+ value: O,
342
+ onChange: (e) => k(e.target.value),
333
343
  placeholder: "https://your-tunnel.trycloudflare.com",
334
344
  required: !0,
335
345
  className: "w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono"
336
346
  }),
337
- /* @__PURE__ */ p("p", {
347
+ /* @__PURE__ */ d("p", {
338
348
  className: "mt-1 text-xs text-text-muted",
339
- children: S("agentsPage.tunnelUrlHint", "The agent's tunnel URL or local API URL (e.g. http://localhost:3005)")
349
+ children: y("agentsPage.tunnelUrlHint", "The agent's tunnel URL or local API URL (e.g. http://localhost:3005)")
340
350
  })
341
351
  ] }),
342
- /* @__PURE__ */ m("div", { children: [
343
- /* @__PURE__ */ m("label", {
352
+ /* @__PURE__ */ f("div", { children: [
353
+ /* @__PURE__ */ f("label", {
344
354
  className: "block text-sm font-medium text-text-primary mb-1",
345
355
  children: [
346
- S("agentsPage.agentApiKey", "Agent API Key"),
356
+ y("agentsPage.agentApiKey", "Agent API Key"),
347
357
  " ",
348
- /* @__PURE__ */ p("span", {
358
+ /* @__PURE__ */ d("span", {
349
359
  className: "text-status-error-text",
350
360
  children: "*"
351
361
  })
352
362
  ]
353
363
  }),
354
- /* @__PURE__ */ m("div", {
364
+ /* @__PURE__ */ f("div", {
355
365
  className: "relative",
356
- children: [/* @__PURE__ */ p("input", {
366
+ children: [/* @__PURE__ */ d("input", {
357
367
  "aria-label": "vcak_...",
358
- type: T ? "text" : "password",
359
- value: j,
360
- onChange: (e) => M(e.target.value),
368
+ type: S ? "text" : "password",
369
+ value: A,
370
+ onChange: (e) => j(e.target.value),
361
371
  placeholder: "vcak_...",
362
372
  required: !0,
363
373
  className: "w-full px-3 py-2 pr-10 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono"
364
- }), /* @__PURE__ */ p("button", {
374
+ }), /* @__PURE__ */ d("button", {
365
375
  type: "button",
366
- onClick: () => ue(!T),
376
+ onClick: () => me(!S),
367
377
  className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded hover:bg-bg-elevated transition-colors",
368
- children: p(T ? ie : re, { className: "size-4 text-text-secondary" })
378
+ children: d(S ? ae : ie, { className: "size-4 text-text-secondary" })
369
379
  })]
370
380
  }),
371
- /* @__PURE__ */ m("p", {
381
+ /* @__PURE__ */ f("p", {
372
382
  className: "mt-1 text-xs text-text-muted",
373
383
  children: [
374
- S("agentsPage.apiKeyHint", "Run"),
384
+ y("agentsPage.apiKeyHint", "Run"),
375
385
  " ",
376
- /* @__PURE__ */ p("code", {
386
+ /* @__PURE__ */ d("code", {
377
387
  className: "bg-bg-sunken px-1 rounded",
378
388
  children: "vibe key"
379
389
  }),
380
390
  " ",
381
- S("agentsPage.apiKeyHintSuffix", "on the agent to get this. Changes on restart.")
391
+ y("agentsPage.apiKeyHintSuffix", "on the agent to get this. Changes on restart.")
382
392
  ]
383
393
  })
384
394
  ] }),
385
- /* @__PURE__ */ m("div", {
395
+ /* @__PURE__ */ f("div", {
386
396
  className: "border border-border-default rounded-lg overflow-hidden",
387
- children: [/* @__PURE__ */ m("button", {
397
+ children: [/* @__PURE__ */ f("button", {
388
398
  type: "button",
389
- onClick: () => Ce((e) => !e),
399
+ onClick: () => Ee((e) => !e),
390
400
  className: "w-full flex items-center justify-between px-4 py-2.5 bg-bg-sunken hover:bg-bg-sunken/80 transition-colors",
391
401
  "aria-expanded": X,
392
402
  "data-testid": "agent-form-advanced-toggle",
393
- children: [/* @__PURE__ */ m("div", {
403
+ children: [/* @__PURE__ */ f("div", {
394
404
  className: "flex items-center gap-2",
395
- children: [/* @__PURE__ */ p(ae, { className: "size-4 text-text-secondary" }), /* @__PURE__ */ p("span", {
405
+ children: [/* @__PURE__ */ d(ce, { className: "size-4 text-text-secondary" }), /* @__PURE__ */ d("span", {
396
406
  className: "text-sm font-medium text-text-primary",
397
- children: S("agentsPage.advancedOptions", "Advanced options")
407
+ children: y("agentsPage.advancedOptions", "Advanced options")
398
408
  })]
399
- }), /* @__PURE__ */ p(o, { className: `size-4 text-text-secondary transition-transform ${X ? "rotate-180" : ""}` })]
400
- }), X && /* @__PURE__ */ p("div", {
409
+ }), /* @__PURE__ */ d(ee, { className: `size-4 text-text-secondary transition-transform ${X ? "rotate-180" : ""}` })]
410
+ }), X && /* @__PURE__ */ d("div", {
401
411
  className: "px-4 py-3 space-y-3 border-t border-border-default",
402
- children: /* @__PURE__ */ m("div", { children: [
403
- /* @__PURE__ */ p("label", {
412
+ children: /* @__PURE__ */ f("div", { children: [
413
+ /* @__PURE__ */ d("label", {
404
414
  className: "block text-sm font-medium text-text-primary mb-1",
405
- children: S("agentsPage.profileName", "Profile name")
415
+ children: y("agentsPage.profileName", "Profile name")
406
416
  }),
407
- /* @__PURE__ */ p("input", {
417
+ /* @__PURE__ */ d("input", {
408
418
  "aria-label": "default",
409
419
  type: "text",
410
- value: we,
411
- onChange: (e) => Te(e.target.value),
420
+ value: De,
421
+ onChange: (e) => Oe(e.target.value),
412
422
  placeholder: "default",
413
423
  className: "w-full px-3 py-2 text-sm bg-bg-surface border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono",
414
424
  "data-testid": "agent-form-profile-input"
415
425
  }),
416
- /* @__PURE__ */ p("p", {
426
+ /* @__PURE__ */ d("p", {
417
427
  className: "mt-1 text-xs text-text-muted",
418
- children: S("agentsPage.profileNameHint", "Each profile runs an isolated CLI on the daemon. Leave as \"default\" unless you want this agent to host multiple parallel profiles.")
428
+ children: y("agentsPage.profileNameHint", "Each profile runs an isolated CLI on the daemon. Leave as \"default\" unless you want this agent to host multiple parallel profiles.")
419
429
  })
420
430
  ] })
421
431
  })]
422
432
  }),
423
- ce && /* @__PURE__ */ p("div", {
433
+ v && /* @__PURE__ */ d("div", {
424
434
  className: "border-t border-border-default pt-4 mt-4",
425
- children: ce
435
+ children: v
426
436
  }),
427
- /* @__PURE__ */ m("div", {
437
+ /* @__PURE__ */ f("div", {
428
438
  className: "flex items-center justify-between pt-4",
429
- children: [/* @__PURE__ */ p("button", {
439
+ children: [/* @__PURE__ */ d("button", {
430
440
  type: "button",
431
- onClick: g,
441
+ onClick: m,
432
442
  className: "px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors",
433
- children: S("agentsPage.cancel", "Cancel")
434
- }), /* @__PURE__ */ m("button", {
443
+ children: y("agentsPage.cancel", "Cancel")
444
+ }), /* @__PURE__ */ f("button", {
435
445
  type: "button",
436
- disabled: !Me,
446
+ disabled: !Fe,
437
447
  onClick: () => {
438
- w("validate"), Oe();
448
+ x("validate"), je();
439
449
  },
440
450
  className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50",
441
- children: [S("agentsPage.nextValidate", "Next: Validate"), /* @__PURE__ */ p(s, { className: "size-4" })]
451
+ children: [y("agentsPage.nextValidate", "Next: Validate"), /* @__PURE__ */ d(s, { className: "size-4" })]
442
452
  })]
443
453
  })
444
454
  ]
445
- }), C === "validate" && /* @__PURE__ */ m("div", {
455
+ }), b === "validate" && /* @__PURE__ */ f("div", {
446
456
  className: "space-y-4",
447
457
  children: [
448
- /* @__PURE__ */ m("div", {
458
+ /* @__PURE__ */ f("div", {
449
459
  className: "space-y-3",
450
- children: [/* @__PURE__ */ m("div", {
460
+ children: [/* @__PURE__ */ f("div", {
451
461
  className: `flex items-center gap-3 p-3 rounded-lg border ${W === null ? "border-border-default bg-bg-sunken" : W.ok ? "border-status-success-text/20 bg-status-success-bg/30" : "border-status-error-text/20 bg-status-error-bg/30"}`,
452
- children: [U && !W ? /* @__PURE__ */ p(c, { className: "size-5 text-text-secondary animate-spin" }) : W?.ok ? /* @__PURE__ */ p(a, { className: "size-5 text-status-success-text" }) : W ? /* @__PURE__ */ p(d, { className: "size-5 text-status-error-text" }) : /* @__PURE__ */ p("div", { className: "size-5 rounded-full border-2 border-border-default" }), /* @__PURE__ */ m("div", {
462
+ children: [H && !W ? /* @__PURE__ */ d(c, { className: "size-5 text-text-secondary animate-spin" }) : W?.ok ? /* @__PURE__ */ d(o, { className: "size-5 text-status-success-text" }) : W ? /* @__PURE__ */ d(l, { className: "size-5 text-status-error-text" }) : /* @__PURE__ */ d("div", { className: "size-5 rounded-full border-2 border-border-default" }), /* @__PURE__ */ f("div", {
453
463
  className: "flex-1",
454
464
  children: [
455
- /* @__PURE__ */ p("p", {
465
+ /* @__PURE__ */ d("p", {
456
466
  className: "text-sm font-medium text-text-primary",
457
- children: S("agentsPage.healthCheck", "Health Check")
467
+ children: y("agentsPage.healthCheck", "Health Check")
458
468
  }),
459
- W?.ok && W.data && /* @__PURE__ */ m("p", {
469
+ W?.ok && W.data && /* @__PURE__ */ f("p", {
460
470
  className: "text-xs text-text-secondary",
461
471
  children: [
462
472
  "Status: ",
@@ -468,22 +478,22 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
468
478
  "s"
469
479
  ]
470
480
  }),
471
- W && !W.ok && /* @__PURE__ */ p("p", {
481
+ W && !W.ok && /* @__PURE__ */ d("p", {
472
482
  className: "text-xs text-status-error-text",
473
483
  children: W.error
474
484
  })
475
485
  ]
476
486
  })]
477
- }), /* @__PURE__ */ m("div", {
487
+ }), /* @__PURE__ */ f("div", {
478
488
  className: `flex items-center gap-3 p-3 rounded-lg border ${K === null ? "border-border-default bg-bg-sunken" : K.ok ? "border-status-success-text/20 bg-status-success-bg/30" : "border-status-error-text/20 bg-status-error-bg/30"}`,
479
- children: [U && !K ? /* @__PURE__ */ p(c, { className: "size-5 text-text-secondary animate-spin" }) : K?.ok ? /* @__PURE__ */ p(a, { className: "size-5 text-status-success-text" }) : K ? /* @__PURE__ */ p(d, { className: "size-5 text-status-error-text" }) : /* @__PURE__ */ p("div", { className: "size-5 rounded-full border-2 border-border-default" }), /* @__PURE__ */ m("div", {
489
+ children: [H && !K ? /* @__PURE__ */ d(c, { className: "size-5 text-text-secondary animate-spin" }) : K?.ok ? /* @__PURE__ */ d(o, { className: "size-5 text-status-success-text" }) : K ? /* @__PURE__ */ d(l, { className: "size-5 text-status-error-text" }) : /* @__PURE__ */ d("div", { className: "size-5 rounded-full border-2 border-border-default" }), /* @__PURE__ */ f("div", {
480
490
  className: "flex-1",
481
491
  children: [
482
- /* @__PURE__ */ p("p", {
492
+ /* @__PURE__ */ d("p", {
483
493
  className: "text-sm font-medium text-text-primary",
484
- children: S("agentsPage.apiAccess", "API Access")
494
+ children: y("agentsPage.apiAccess", "API Access")
485
495
  }),
486
- K?.ok && K.data && /* @__PURE__ */ m("p", {
496
+ K?.ok && K.data && /* @__PURE__ */ f("p", {
487
497
  className: "text-xs text-text-secondary",
488
498
  children: [
489
499
  "Host: ",
@@ -495,7 +505,7 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
495
505
  K.data.arch
496
506
  ]
497
507
  }),
498
- K && !K.ok && /* @__PURE__ */ p("p", {
508
+ K && !K.ok && /* @__PURE__ */ d("p", {
499
509
  className: "text-xs text-status-error-text",
500
510
  children: K.error
501
511
  })
@@ -503,70 +513,72 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
503
513
  })]
504
514
  })]
505
515
  }),
506
- !U && (!W?.ok || !K?.ok) && /* @__PURE__ */ m("button", {
516
+ !H && (!W?.ok || !K?.ok) && /* @__PURE__ */ f("button", {
507
517
  type: "button",
508
- onClick: Oe,
518
+ onClick: je,
509
519
  className: "flex items-center gap-2 px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-md transition-colors",
510
- children: [/* @__PURE__ */ p(u, { className: "size-3.5" }), S("agentsPage.retryValidation", "Retry validation")]
520
+ children: [/* @__PURE__ */ d(se, { className: "size-3.5" }), y("agentsPage.retryValidation", "Retry validation")]
511
521
  }),
512
- Ae && /* @__PURE__ */ m("div", {
522
+ Ne && /* @__PURE__ */ f("div", {
513
523
  className: "space-y-3 pt-2",
514
524
  children: [
515
- /* @__PURE__ */ p("p", {
525
+ /* @__PURE__ */ d("p", {
516
526
  className: "text-sm font-medium text-text-primary",
517
- children: S("agentsPage.detectedAgentInfo", "Detected Agent Info")
527
+ children: y("agentsPage.detectedAgentInfo", "Detected Agent Info")
518
528
  }),
519
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
529
+ /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
520
530
  className: "block text-xs font-medium text-text-secondary mb-1",
521
- children: S("agentsPage.name", "Name")
522
- }), /* @__PURE__ */ p("input", {
531
+ children: y("agentsPage.name", "Name")
532
+ }), /* @__PURE__ */ d("input", {
523
533
  "aria-label": "control",
524
534
  type: "text",
525
- value: O,
526
- onChange: (e) => pe(e.target.value),
535
+ value: T,
536
+ onChange: (e) => {
537
+ E(e.target.value), _e(!0);
538
+ },
527
539
  placeholder: J,
528
540
  className: "w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg"
529
541
  })] }),
530
- /* @__PURE__ */ m("div", {
542
+ /* @__PURE__ */ f("div", {
531
543
  className: "grid grid-cols-2 gap-3",
532
- children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
544
+ children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
533
545
  className: "block text-xs font-medium text-text-secondary mb-1",
534
- children: S("agentsPage.platform", "Platform")
535
- }), /* @__PURE__ */ m("select", {
536
- value: ge,
537
- onChange: (e) => _e(e.target.value),
546
+ children: y("agentsPage.platform", "Platform")
547
+ }), /* @__PURE__ */ f("select", {
548
+ value: ye,
549
+ onChange: (e) => be(e.target.value),
538
550
  className: "w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg",
539
551
  children: [
540
- /* @__PURE__ */ p("option", {
552
+ /* @__PURE__ */ d("option", {
541
553
  value: "linux",
542
554
  children: "Linux"
543
555
  }),
544
- /* @__PURE__ */ p("option", {
556
+ /* @__PURE__ */ d("option", {
545
557
  value: "darwin",
546
558
  children: "macOS"
547
559
  }),
548
- /* @__PURE__ */ p("option", {
560
+ /* @__PURE__ */ d("option", {
549
561
  value: "windows",
550
562
  children: "Windows"
551
563
  })
552
564
  ]
553
- })] }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
565
+ })] }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
554
566
  className: "block text-xs font-medium text-text-secondary mb-1",
555
- children: S("agentsPage.architecture", "Architecture")
556
- }), /* @__PURE__ */ m("select", {
557
- value: ve,
558
- onChange: (e) => ye(e.target.value),
567
+ children: y("agentsPage.architecture", "Architecture")
568
+ }), /* @__PURE__ */ f("select", {
569
+ value: xe,
570
+ onChange: (e) => Se(e.target.value),
559
571
  className: "w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg",
560
572
  children: [
561
- /* @__PURE__ */ p("option", {
573
+ /* @__PURE__ */ d("option", {
562
574
  value: "x86_64",
563
575
  children: "x86_64"
564
576
  }),
565
- /* @__PURE__ */ p("option", {
577
+ /* @__PURE__ */ d("option", {
566
578
  value: "arm64",
567
579
  children: "arm64"
568
580
  }),
569
- /* @__PURE__ */ p("option", {
581
+ /* @__PURE__ */ d("option", {
570
582
  value: "aarch64",
571
583
  children: "aarch64"
572
584
  })
@@ -575,44 +587,44 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
575
587
  })
576
588
  ]
577
589
  }),
578
- Se && /* @__PURE__ */ m("div", {
590
+ Te && /* @__PURE__ */ f("div", {
579
591
  className: "p-3 bg-status-error-bg/30 border border-status-error-text/20 rounded-lg",
580
- children: [/* @__PURE__ */ m("div", {
592
+ children: [/* @__PURE__ */ f("div", {
581
593
  className: "flex items-center gap-2",
582
- children: [/* @__PURE__ */ p(d, { className: "size-5 text-status-error-text flex-shrink-0" }), /* @__PURE__ */ p("p", {
594
+ children: [/* @__PURE__ */ d(l, { className: "size-5 text-status-error-text flex-shrink-0" }), /* @__PURE__ */ d("p", {
583
595
  className: "text-sm text-status-error-text",
584
- children: Se
596
+ children: Te
585
597
  })]
586
- }), /* @__PURE__ */ m("div", {
598
+ }), /* @__PURE__ */ f("div", {
587
599
  className: "flex items-center gap-2 mt-3",
588
- children: [/* @__PURE__ */ m("button", {
600
+ children: [/* @__PURE__ */ f("button", {
589
601
  type: "button",
590
602
  onClick: () => {
591
- Y(null), w("details"), A(""), M(""), G(null), q(null);
603
+ Y(null), x("details"), k(""), j(""), G(null), q(null);
592
604
  },
593
605
  className: "flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors",
594
- children: [/* @__PURE__ */ p(u, { className: "size-3.5" }), S("agentsPage.tryDifferentAgent", "Try Different Agent")]
595
- }), /* @__PURE__ */ p("button", {
606
+ children: [/* @__PURE__ */ d(se, { className: "size-3.5" }), y("agentsPage.tryDifferentAgent", "Try Different Agent")]
607
+ }), /* @__PURE__ */ d("button", {
596
608
  type: "button",
597
- onClick: g,
609
+ onClick: m,
598
610
  className: "px-3 py-1.5 text-sm font-medium text-text-secondary hover:text-text-primary transition-colors",
599
- children: S("agentsPage.close", "Close")
611
+ children: y("agentsPage.close", "Close")
600
612
  })]
601
613
  })]
602
614
  }),
603
- /* @__PURE__ */ m("div", {
615
+ /* @__PURE__ */ f("div", {
604
616
  className: "flex items-center justify-between pt-4",
605
- children: [/* @__PURE__ */ m("button", {
617
+ children: [/* @__PURE__ */ f("button", {
606
618
  type: "button",
607
- onClick: () => w("details"),
619
+ onClick: () => x("details"),
608
620
  className: "flex items-center gap-1 px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors",
609
- children: [/* @__PURE__ */ p(ee, { className: "size-4" }), S("agentsPage.back", "Back")]
610
- }), /* @__PURE__ */ p("button", {
621
+ children: [/* @__PURE__ */ d(te, { className: "size-4" }), y("agentsPage.back", "Back")]
622
+ }), /* @__PURE__ */ d("button", {
611
623
  type: "button",
612
- disabled: !Ae || _ || U,
613
- onClick: ke,
624
+ disabled: !Ne || h || H,
625
+ onClick: Me,
614
626
  className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50",
615
- children: _ ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(c, { className: "size-4 animate-spin" }), S("agentsPage.adding", "Adding...")] }) : /* @__PURE__ */ m(f, { children: [S("agentsPage.addAgent", "Add Agent"), /* @__PURE__ */ p(s, { className: "size-4" })] })
627
+ children: h ? /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d(c, { className: "size-4 animate-spin" }), y("agentsPage.adding", "Adding...")] }) : /* @__PURE__ */ f(u, { children: [y("agentsPage.addAgent", "Add Agent"), /* @__PURE__ */ d(s, { className: "size-4" })] })
616
628
  })]
617
629
  })
618
630
  ]
@@ -623,6 +635,6 @@ function h({ onSubmit: h, onCancel: g, isLoading: _, onNavigate: v, targets: y,
623
635
  });
624
636
  }
625
637
  //#endregion
626
- export { h as AgentForm };
638
+ export { p as AgentForm };
627
639
 
628
640
  //# sourceMappingURL=AgentForm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentForm.js","names":[],"sources":["../../../src/components/agents/AgentForm.tsx"],"sourcesContent":["import { useState, useCallback } from 'react';\nimport type { ReactNode } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n X,\n Eye,\n EyeOff,\n CheckCircle2,\n XCircle,\n Loader2,\n ChevronRight,\n ChevronLeft,\n ChevronDown,\n Copy,\n Check,\n Terminal,\n Download,\n RefreshCw,\n Plus,\n Settings2,\n} from 'lucide-react';\n// useProbeAgentTunnelLazyQuery removed: validate now hits the agent's tunnel\n// URL directly from the browser (see validateAgent below).\nimport { SearchableSelect } from '@/components/shared';\nimport type { SearchableSelectOption } from '@/components/shared';\n\ntype WizardStage = 'details' | 'validate';\n\ninterface TargetOption {\n id: string;\n name: string;\n type: string;\n status: string;\n}\n\ninterface AgentFormProps {\n onSubmit: (data: Record<string, unknown>) => Promise<{ id: string } | void>;\n onCancel: () => void;\n isLoading?: boolean;\n /** Navigate to a path (used to go to agent details after creation) */\n onNavigate?: (path: string) => void;\n /** Available targets for the agent to be installed on */\n targets?: TargetOption[];\n /** Whether targets are still loading */\n targetsLoading?: boolean;\n /**\n * Create a new target inline. When provided, the form shows a\n * \"+ Create new target\" affordance that lets users create a DIRECT\n * target on the fly without leaving the dialog. Must return the new\n * target so the form can auto-select it.\n */\n onCreateTarget?: (name: string) => Promise<TargetOption | null>;\n /** Optional extra content (e.g. a draft EntityTagPicker) rendered above the configure-stage actions. */\n extraSection?: ReactNode;\n}\n\nexport function AgentForm({\n onSubmit,\n onCancel,\n isLoading,\n onNavigate,\n targets,\n targetsLoading,\n onCreateTarget,\n extraSection,\n}: AgentFormProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n const [stage, setStage] = useState<WizardStage>('details');\n const [showApiKey, setShowApiKey] = useState(false);\n const [showInstallInstructions, setShowInstallInstructions] = useState(false);\n const [copiedCommand, setCopiedCommand] = useState<string | null>(null);\n\n // Stage 1: Basic details\n const [name, setName] = useState('');\n const [tunnelUrl, setTunnelUrl] = useState('');\n const [agentApiKey, setAgentApiKey] = useState('');\n const [selectedTargetId, setSelectedTargetId] = useState('');\n\n // Inline target creation state\n const [showInlineTarget, setShowInlineTarget] = useState(false);\n const [inlineTargetName, setInlineTargetName] = useState('');\n const [creatingTarget, setCreatingTarget] = useState(false);\n const [inlineTargetError, setInlineTargetError] = useState<string | null>(null);\n\n // Stage 2: Validation (via backend-proxied GraphQL query)\n const [validating, setValidating] = useState(false);\n const [healthResult, setHealthResult] = useState<{\n ok: boolean;\n data?: { status: string; version: string; uptime: number };\n error?: string;\n } | null>(null);\n const [identityResult, setIdentityResult] = useState<{\n ok: boolean;\n data?: { hostname: string; platform: string; arch: string };\n error?: string;\n } | null>(null);\n\n // Auto-detected fields (editable overrides)\n const [detectedHostname, setDetectedHostname] = useState('');\n const [detectedPlatform, setDetectedPlatform] = useState('linux');\n const [detectedArch, setDetectedArch] = useState('x86_64');\n const [detectedVersion, setDetectedVersion] = useState('1.0.0');\n\n // Error state for creation failures\n const [createError, setCreateError] = useState<string | null>(null);\n\n // Advanced options (Phase 5B: per-daemon profile name).\n // Defaults to \"default\" (autofilled but editable). Disclosure is closed\n // by default — users only need to touch this for multi-profile setups.\n const [showAdvanced, setShowAdvanced] = useState(false);\n const [profile, setProfile] = useState('default');\n\n const copyToClipboard = useCallback((text: string, id: string) => {\n navigator.clipboard.writeText(text);\n setCopiedCommand(id);\n setTimeout(() => setCopiedCommand(null), 2000);\n }, []);\n\n const normalizeUrl = (url: string) => {\n let u = url.trim();\n if (u.endsWith('/')) u = u.slice(0, -1);\n return u;\n };\n\n // Validate the agent by probing /health and /api/profiles/default/agent/identity\n // directly from the browser. The agent exposes CORS-allowed endpoints for\n // app.vibecontrols.com (see agent's createApp() — `@elysiajs/cors` is wired\n // for the host origin), so the browser can reach the tunnel URL without a\n // backend proxy. The earlier backend-proxy approach (probeAgentTunnel query)\n // is still wired into the schema, but in production we observed the proxy\n // hanging at the ACA egress layer regardless of timeout, so we bypass it for\n // the wizard validate step. Each fetch is bounded by a 10s AbortSignal so a\n // dead tunnel surfaces a real error instead of an infinite spinner.\n const validateAgent = async () => {\n const baseUrl = normalizeUrl(tunnelUrl);\n if (!baseUrl) return;\n\n setValidating(true);\n setHealthResult(null);\n setIdentityResult(null);\n\n const probeHealth = async (): Promise<void> => {\n try {\n const res = await fetch(`${baseUrl}/health`, {\n signal: AbortSignal.timeout(10_000),\n });\n if (!res.ok) {\n setHealthResult({ ok: false, error: `HTTP ${String(res.status)}: ${res.statusText}` });\n return;\n }\n const data = (await res.json()) as {\n status?: string;\n version?: string;\n uptime?: number;\n };\n setHealthResult({\n ok: true,\n data: {\n status: data.status || 'healthy',\n version: data.version || 'unknown',\n uptime: data.uptime || 0,\n },\n });\n if (data.version) setDetectedVersion(data.version);\n } catch (err) {\n const isTimeout = err instanceof DOMException && err.name === 'AbortError';\n setHealthResult({\n ok: false,\n error: isTimeout\n ? 'Health check timed out after 10s'\n : err instanceof Error\n ? err.message\n : 'Health check failed',\n });\n }\n };\n\n const probeIdentity = async (): Promise<void> => {\n try {\n const headers: Record<string, string> = {};\n if (agentApiKey) headers['x-agent-api-key'] = agentApiKey;\n const res = await fetch(`${baseUrl}/api/profiles/default/agent/identity`, {\n headers,\n signal: AbortSignal.timeout(10_000),\n });\n if (!res.ok) {\n setIdentityResult({\n ok: false,\n error:\n res.status === 401\n ? 'Invalid API key'\n : `HTTP ${String(res.status)}: ${res.statusText}`,\n });\n return;\n }\n const data = (await res.json()) as {\n hostname?: string;\n platform?: string;\n arch?: string;\n };\n const hostname = data.hostname || '';\n const platform = data.platform || 'linux';\n const arch = data.arch || 'x86_64';\n setIdentityResult({ ok: true, data: { hostname, platform, arch } });\n if (hostname) setDetectedHostname(hostname);\n if (platform) setDetectedPlatform(platform);\n if (arch) setDetectedArch(arch);\n if (!name && hostname) setName(hostname);\n } catch (err) {\n const isTimeout = err instanceof DOMException && err.name === 'AbortError';\n setIdentityResult({\n ok: false,\n error: isTimeout\n ? 'Identity check timed out after 10s'\n : err instanceof Error\n ? err.message\n : 'Identity check failed',\n });\n }\n };\n\n // Run both probes in parallel so the user sees results as fast as the\n // slower of the two — instead of stacking 20s in series on failure paths.\n await Promise.all([probeHealth(), probeIdentity()]);\n\n setValidating(false);\n };\n\n // Create the agent and close the modal\n const handleCreateAgent = async () => {\n setCreateError(null);\n\n // Pipe the chosen profile through `metadata.profile`. Phase 5A (svc) is\n // adding first-class AgentProfile rows; in the meantime the backend\n // also reads `metadata.profile` so the create path keeps working\n // regardless of which side of the cut-over the cluster is on.\n const trimmedProfile = profile.trim() || 'default';\n const data: Record<string, unknown> = {\n name: name || detectedHostname || 'Unnamed Agent',\n hostname: detectedHostname || 'unknown',\n platform: detectedPlatform,\n architecture: detectedArch,\n version: detectedVersion,\n tunnelUrl: normalizeUrl(tunnelUrl),\n tunnelStatus: 'ACTIVE',\n agentApiKey,\n metadata: { profile: trimmedProfile },\n ...(selectedTargetId ? { targetId: selectedTargetId } : {}),\n };\n\n try {\n const result = await onSubmit(data);\n const newAgentId = result?.id || null;\n\n if (!newAgentId) {\n // Mutation succeeded but returned no agent ID — treat as failure\n setCreateError('Agent creation returned no ID. The agent may already exist.');\n return;\n }\n\n // Close the modal — the agent list will refetch automatically\n if (onNavigate) {\n onNavigate(`/agents/${newAgentId}`);\n } else {\n onCancel();\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to create agent';\n setCreateError(message);\n }\n };\n\n const isValidationPassed = healthResult?.ok && identityResult?.ok;\n const hasTargets = targets && targets.length > 0;\n // The user must either pick or inline-create a target if inline creation\n // is enabled; otherwise we only require it when targets already exist.\n const targetRequiredButMissing = onCreateTarget\n ? selectedTargetId.length === 0\n : hasTargets && selectedTargetId.length === 0;\n const canProceedToValidate = tunnelUrl.trim().length > 0 && !targetRequiredButMissing;\n\n const handleInlineCreateTarget = useCallback(async () => {\n if (!onCreateTarget || !inlineTargetName.trim()) return;\n setCreatingTarget(true);\n setInlineTargetError(null);\n try {\n const created = await onCreateTarget(inlineTargetName.trim());\n if (created) {\n setSelectedTargetId(created.id);\n setShowInlineTarget(false);\n setInlineTargetName('');\n } else {\n setInlineTargetError(\n tr('agentsPage.inlineTargetFailed', 'Failed to create target. Please try again.')\n );\n }\n } catch (err) {\n setInlineTargetError(err instanceof Error ? err.message : 'Failed to create target');\n } finally {\n setCreatingTarget(false);\n }\n }, [onCreateTarget, inlineTargetName, tr]);\n\n const renderCopyButton = (text: string, id: string) => (\n <button\n type=\"button\"\n onClick={() => copyToClipboard(text, id)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors\"\n title={tr('agentsPage.copy', 'Copy')}\n >\n {copiedCommand === id ? (\n <Check className=\"size-3.5 text-status-success-text\" />\n ) : (\n <Copy className=\"size-3.5 text-text-secondary\" />\n )}\n </button>\n );\n\n // Stepper\n const steps = [\n { key: 'details', label: 'Setup' },\n { key: 'validate', label: 'Validate' },\n ];\n\n const currentStepIndex = steps.findIndex((s) => s.key === stage);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay\">\n <div className=\"w-full max-w-xl bg-bg-surface rounded-lg shadow-xl max-h-[90vh] overflow-y-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default sticky top-0 bg-bg-surface z-10\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('agentsPage.addNewAgent', 'Add New Agent')}\n </h2>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n >\n <X className=\"size-5 text-text-secondary\" />\n </button>\n </div>\n\n {/* Stepper */}\n <div className=\"flex items-center gap-2 px-6 pt-4 pb-2\">\n {steps.map((step, i) => (\n <div key={step.key} className=\"flex items-center gap-2\">\n <div\n className={`flex items-center justify-center size-7 rounded-full text-xs font-semibold transition-colors ${\n i < currentStepIndex\n ? 'bg-status-success-bg text-status-success-text'\n : i === currentStepIndex\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {i < currentStepIndex ? <CheckCircle2 className=\"size-4\" /> : i + 1}\n </div>\n <span\n className={`text-sm ${i === currentStepIndex ? 'font-medium text-text-primary' : 'text-text-secondary'}`}\n >\n {step.label}\n </span>\n {i < steps.length - 1 && <ChevronRight className=\"size-4 text-text-muted\" />}\n </div>\n ))}\n </div>\n\n <div className=\"p-6\">\n {/* Stage 1: Setup */}\n {stage === 'details' && (\n <div className=\"space-y-4\">\n {/* Install instructions (collapsible) */}\n <div className=\"border border-border-default rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setShowInstallInstructions(!showInstallInstructions)}\n className=\"w-full flex items-center justify-between px-4 py-3 bg-bg-sunken hover:bg-bg-sunken/80 transition-colors\"\n >\n <div className=\"flex items-center gap-2\">\n <Download className=\"size-4 text-action-primary-bg\" />\n <span className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.installInstructions', 'Agent Install Instructions')}\n </span>\n </div>\n <ChevronRight\n className={`size-4 text-text-secondary transition-transform ${showInstallInstructions ? 'rotate-90' : ''}`}\n />\n </button>\n {showInstallInstructions && (\n <div className=\"px-4 py-3 space-y-3 border-t border-border-default\">\n <div className=\"space-y-2\">\n {[\n {\n label: tr('agentsPage.installStep1', '1. Install the agent CLI'),\n cmd: 'npm install -g @vibecontrols/agent@latest',\n },\n {\n label: tr('agentsPage.installStep2', '2. Start the agent'),\n cmd: 'vibe start',\n },\n {\n label: tr('agentsPage.installStep3', '3. Get the API key'),\n cmd: 'vibe key',\n },\n {\n label: tr('agentsPage.installStep4', '4. Start the tunnel'),\n cmd: 'vibe tunnel agent --start',\n },\n ].map((step) => (\n <div key={step.cmd}>\n <p className=\"text-xs text-text-secondary mb-1\">{step.label}</p>\n <div className=\"flex items-center gap-2 bg-bg-sunken rounded-md px-3 py-1.5 font-mono text-xs text-text-primary\">\n <Terminal className=\"size-3 text-text-muted flex-shrink-0\" />\n <code className=\"flex-1\">{step.cmd}</code>\n {renderCopyButton(step.cmd, step.cmd)}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Target Selection — with inline creation */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.target', 'Target')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n\n {hasTargets && !showInlineTarget && (\n <>\n <SearchableSelect\n placeholder={tr('agentsPage.selectTarget', 'Select a target...')}\n searchPlaceholder={tr('agentsPage.searchTargets', 'Search targets...')}\n options={(targets ?? []).map(\n (tgt): SearchableSelectOption => ({\n value: tgt.id,\n label: tgt.name,\n description: `${tgt.type}${tgt.status ? ` · ${tgt.status}` : ''}`,\n })\n )}\n value={selectedTargetId}\n onChange={setSelectedTargetId}\n clearable\n />\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr(\n 'agentsPage.targetDescription',\n 'The target machine this agent will be installed on.'\n )}{' '}\n {onCreateTarget && (\n <button\n type=\"button\"\n onClick={() => {\n setShowInlineTarget(true);\n setInlineTargetName(name.trim() || '');\n }}\n className=\"text-action-primary-bg hover:underline inline-flex items-center gap-1\"\n >\n <Plus className=\"size-3\" />\n {tr('agentsPage.createNewTarget', 'Create a new target')}\n </button>\n )}\n </p>\n </>\n )}\n\n {/* Empty state prompt (no targets exist yet) */}\n {!hasTargets && !targetsLoading && onCreateTarget && !showInlineTarget && (\n <div className=\"p-3 bg-bg-sunken border border-border-default rounded-lg\">\n <p className=\"text-sm text-text-secondary mb-2\">\n {tr(\n 'agentsPage.noTargetsInlinePrompt',\n \"You don't have any targets yet. Create one now to install this agent on it.\"\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => {\n setShowInlineTarget(true);\n setInlineTargetName(name.trim() || '');\n }}\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:opacity-90\"\n >\n <Plus className=\"size-4\" />\n {tr('agentsPage.createFirstTarget', 'Create first target')}\n </button>\n </div>\n )}\n\n {/* Inline creation form */}\n {showInlineTarget && onCreateTarget && (\n <div className=\"p-3 bg-bg-sunken border border-border-default rounded-lg space-y-2\">\n <p className=\"text-xs font-medium text-text-secondary\">\n {tr(\n 'agentsPage.newDirectTarget',\n 'New target (Direct — you can change the type later)'\n )}\n </p>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={inlineTargetName}\n onChange={(e) => setInlineTargetName(e.target.value)}\n placeholder={tr('agentsPage.targetName', 'Target name')}\n className=\"w-full px-3 py-2 text-sm bg-bg-elevated border border-border-default rounded-md text-text-primary placeholder-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n void handleInlineCreateTarget();\n }\n }}\n />\n {inlineTargetError && (\n <p className=\"text-xs text-status-error-text\">{inlineTargetError}</p>\n )}\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => void handleInlineCreateTarget()}\n disabled={!inlineTargetName.trim() || creatingTarget}\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:opacity-90 disabled:opacity-50\"\n >\n {creatingTarget ? (\n <Loader2 className=\"size-3.5 animate-spin\" />\n ) : (\n <Check className=\"size-3.5\" />\n )}\n {tr('agentsPage.create', 'Create')}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setShowInlineTarget(false);\n setInlineTargetName('');\n setInlineTargetError(null);\n }}\n className=\"px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr('agentsPage.cancel', 'Cancel')}\n </button>\n </div>\n </div>\n )}\n\n {/* Loading placeholder */}\n {targetsLoading && !hasTargets && (\n <div className=\"p-3 bg-bg-sunken border border-border-default rounded-lg flex items-center gap-2 text-sm text-text-secondary\">\n <Loader2 className=\"size-4 animate-spin\" />\n {tr('agentsPage.loadingTargets', 'Loading targets...')}\n </div>\n )}\n </div>\n\n {/* API/Tunnel URL */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.apiTunnelUrl', 'API / Tunnel URL')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n aria-label=\"https://your-tunnel.trycloudflare.com\"\n type=\"url\"\n value={tunnelUrl}\n onChange={(e) => setTunnelUrl(e.target.value)}\n placeholder=\"https://your-tunnel.trycloudflare.com\"\n required\n className=\"w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr(\n 'agentsPage.tunnelUrlHint',\n \"The agent's tunnel URL or local API URL (e.g. http://localhost:3005)\"\n )}\n </p>\n </div>\n\n {/* Agent API Key */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.agentApiKey', 'Agent API Key')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <div className=\"relative\">\n <input\n aria-label=\"vcak_...\"\n type={showApiKey ? 'text' : 'password'}\n value={agentApiKey}\n onChange={(e) => setAgentApiKey(e.target.value)}\n placeholder=\"vcak_...\"\n required\n className=\"w-full px-3 py-2 pr-10 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n <button\n type=\"button\"\n onClick={() => setShowApiKey(!showApiKey)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded hover:bg-bg-elevated transition-colors\"\n >\n {showApiKey ? (\n <EyeOff className=\"size-4 text-text-secondary\" />\n ) : (\n <Eye className=\"size-4 text-text-secondary\" />\n )}\n </button>\n </div>\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr('agentsPage.apiKeyHint', 'Run')}{' '}\n <code className=\"bg-bg-sunken px-1 rounded\">vibe key</code>{' '}\n {tr(\n 'agentsPage.apiKeyHintSuffix',\n 'on the agent to get this. Changes on restart.'\n )}\n </p>\n </div>\n\n {/* Advanced options — per-daemon profile name (Phase 5B) */}\n <div className=\"border border-border-default rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setShowAdvanced((v) => !v)}\n className=\"w-full flex items-center justify-between px-4 py-2.5 bg-bg-sunken hover:bg-bg-sunken/80 transition-colors\"\n aria-expanded={showAdvanced}\n data-testid=\"agent-form-advanced-toggle\"\n >\n <div className=\"flex items-center gap-2\">\n <Settings2 className=\"size-4 text-text-secondary\" />\n <span className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.advancedOptions', 'Advanced options')}\n </span>\n </div>\n <ChevronDown\n className={`size-4 text-text-secondary transition-transform ${showAdvanced ? 'rotate-180' : ''}`}\n />\n </button>\n {showAdvanced && (\n <div className=\"px-4 py-3 space-y-3 border-t border-border-default\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.profileName', 'Profile name')}\n </label>\n <input\n aria-label=\"default\"\n type=\"text\"\n value={profile}\n onChange={(e) => setProfile(e.target.value)}\n placeholder=\"default\"\n className=\"w-full px-3 py-2 text-sm bg-bg-surface border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n data-testid=\"agent-form-profile-input\"\n />\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr(\n 'agentsPage.profileNameHint',\n 'Each profile runs an isolated CLI on the daemon. Leave as \"default\" unless you want this agent to host multiple parallel profiles.'\n )}\n </p>\n </div>\n </div>\n )}\n </div>\n\n {extraSection && (\n <div className=\"border-t border-border-default pt-4 mt-4\">{extraSection}</div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center justify-between pt-4\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n {tr('agentsPage.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n disabled={!canProceedToValidate}\n onClick={() => {\n setStage('validate');\n validateAgent();\n }}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {tr('agentsPage.nextValidate', 'Next: Validate')}\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n </div>\n )}\n\n {/* Stage 2: Validate */}\n {stage === 'validate' && (\n <div className=\"space-y-4\">\n {/* Validation Results */}\n <div className=\"space-y-3\">\n {/* Health Check */}\n <div\n className={`flex items-center gap-3 p-3 rounded-lg border ${\n healthResult === null\n ? 'border-border-default bg-bg-sunken'\n : healthResult.ok\n ? 'border-status-success-text/20 bg-status-success-bg/30'\n : 'border-status-error-text/20 bg-status-error-bg/30'\n }`}\n >\n {validating && !healthResult ? (\n <Loader2 className=\"size-5 text-text-secondary animate-spin\" />\n ) : healthResult?.ok ? (\n <CheckCircle2 className=\"size-5 text-status-success-text\" />\n ) : healthResult ? (\n <XCircle className=\"size-5 text-status-error-text\" />\n ) : (\n <div className=\"size-5 rounded-full border-2 border-border-default\" />\n )}\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.healthCheck', 'Health Check')}\n </p>\n {healthResult?.ok && healthResult.data && (\n <p className=\"text-xs text-text-secondary\">\n Status: {healthResult.data.status} | Version: {healthResult.data.version} |\n Uptime: {Math.round(healthResult.data.uptime)}s\n </p>\n )}\n {healthResult && !healthResult.ok && (\n <p className=\"text-xs text-status-error-text\">{healthResult.error}</p>\n )}\n </div>\n </div>\n\n {/* API Access Check */}\n <div\n className={`flex items-center gap-3 p-3 rounded-lg border ${\n identityResult === null\n ? 'border-border-default bg-bg-sunken'\n : identityResult.ok\n ? 'border-status-success-text/20 bg-status-success-bg/30'\n : 'border-status-error-text/20 bg-status-error-bg/30'\n }`}\n >\n {validating && !identityResult ? (\n <Loader2 className=\"size-5 text-text-secondary animate-spin\" />\n ) : identityResult?.ok ? (\n <CheckCircle2 className=\"size-5 text-status-success-text\" />\n ) : identityResult ? (\n <XCircle className=\"size-5 text-status-error-text\" />\n ) : (\n <div className=\"size-5 rounded-full border-2 border-border-default\" />\n )}\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.apiAccess', 'API Access')}\n </p>\n {identityResult?.ok && identityResult.data && (\n <p className=\"text-xs text-text-secondary\">\n Host: {identityResult.data.hostname} | {identityResult.data.platform} /{' '}\n {identityResult.data.arch}\n </p>\n )}\n {identityResult && !identityResult.ok && (\n <p className=\"text-xs text-status-error-text\">{identityResult.error}</p>\n )}\n </div>\n </div>\n </div>\n\n {/* Retry button */}\n {!validating && (!healthResult?.ok || !identityResult?.ok) && (\n <button\n type=\"button\"\n onClick={validateAgent}\n className=\"flex items-center gap-2 px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-md transition-colors\"\n >\n <RefreshCw className=\"size-3.5\" />\n {tr('agentsPage.retryValidation', 'Retry validation')}\n </button>\n )}\n\n {/* Detected info (editable overrides) */}\n {isValidationPassed && (\n <div className=\"space-y-3 pt-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.detectedAgentInfo', 'Detected Agent Info')}\n </p>\n\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('agentsPage.name', 'Name')}\n </label>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={detectedHostname}\n className=\"w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('agentsPage.platform', 'Platform')}\n </label>\n <select\n value={detectedPlatform}\n onChange={(e) => setDetectedPlatform(e.target.value)}\n className=\"w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n >\n <option value=\"linux\">Linux</option>\n <option value=\"darwin\">macOS</option>\n <option value=\"windows\">Windows</option>\n </select>\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('agentsPage.architecture', 'Architecture')}\n </label>\n <select\n value={detectedArch}\n onChange={(e) => setDetectedArch(e.target.value)}\n className=\"w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n >\n <option value=\"x86_64\">x86_64</option>\n <option value=\"arm64\">arm64</option>\n <option value=\"aarch64\">aarch64</option>\n </select>\n </div>\n </div>\n </div>\n )}\n\n {/* Creation error */}\n {createError && (\n <div className=\"p-3 bg-status-error-bg/30 border border-status-error-text/20 rounded-lg\">\n <div className=\"flex items-center gap-2\">\n <XCircle className=\"size-5 text-status-error-text flex-shrink-0\" />\n <p className=\"text-sm text-status-error-text\">{createError}</p>\n </div>\n <div className=\"flex items-center gap-2 mt-3\">\n <button\n type=\"button\"\n onClick={() => {\n setCreateError(null);\n // Reset form to allow entering different credentials\n setStage('details');\n setTunnelUrl('');\n setAgentApiKey('');\n setHealthResult(null);\n setIdentityResult(null);\n }}\n className=\"flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n <RefreshCw className=\"size-3.5\" />\n {tr('agentsPage.tryDifferentAgent', 'Try Different Agent')}\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-3 py-1.5 text-sm font-medium text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('agentsPage.close', 'Close')}\n </button>\n </div>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center justify-between pt-4\">\n <button\n type=\"button\"\n onClick={() => setStage('details')}\n className=\"flex items-center gap-1 px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n <ChevronLeft className=\"size-4\" />\n {tr('agentsPage.back', 'Back')}\n </button>\n <button\n type=\"button\"\n disabled={!isValidationPassed || isLoading || validating}\n onClick={handleCreateAgent}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {isLoading ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {tr('agentsPage.adding', 'Adding...')}\n </>\n ) : (\n <>\n {tr('agentsPage.addAgent', 'Add Agent')}\n <ChevronRight className=\"size-4\" />\n </>\n )}\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AgentForm.js","names":[],"sources":["../../../src/components/agents/AgentForm.tsx"],"sourcesContent":["import { useEffect, useState, useCallback } from 'react';\nimport type { ReactNode } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n X,\n Eye,\n EyeOff,\n CheckCircle2,\n XCircle,\n Loader2,\n ChevronRight,\n ChevronLeft,\n ChevronDown,\n Copy,\n Check,\n Terminal,\n Download,\n RefreshCw,\n Plus,\n Settings2,\n} from 'lucide-react';\n// useProbeAgentTunnelLazyQuery removed: validate now hits the agent's tunnel\n// URL directly from the browser (see validateAgent below).\nimport { SearchableSelect } from '@/components/shared';\nimport type { SearchableSelectOption } from '@/components/shared';\n\ntype WizardStage = 'details' | 'validate';\n\ninterface TargetOption {\n id: string;\n name: string;\n type: string;\n status: string;\n}\n\ninterface AgentFormProps {\n onSubmit: (data: Record<string, unknown>) => Promise<{ id: string } | void>;\n onCancel: () => void;\n isLoading?: boolean;\n /** Navigate to a path (used to go to agent details after creation) */\n onNavigate?: (path: string) => void;\n /** Available targets for the agent to be installed on */\n targets?: TargetOption[];\n /** Whether targets are still loading */\n targetsLoading?: boolean;\n /**\n * Create a new target inline. When provided, the form shows a\n * \"+ Create new target\" affordance that lets users create a DIRECT\n * target on the fly without leaving the dialog. Must return the new\n * target so the form can auto-select it.\n */\n onCreateTarget?: (name: string) => Promise<TargetOption | null>;\n /** Optional extra content (e.g. a draft EntityTagPicker) rendered above the configure-stage actions. */\n extraSection?: ReactNode;\n}\n\nexport function AgentForm({\n onSubmit,\n onCancel,\n isLoading,\n onNavigate,\n targets,\n targetsLoading,\n onCreateTarget,\n extraSection,\n}: AgentFormProps) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string) => {\n const v = t(key);\n return v === key ? fallback : v;\n };\n const [stage, setStage] = useState<WizardStage>('details');\n const [showApiKey, setShowApiKey] = useState(false);\n const [showInstallInstructions, setShowInstallInstructions] = useState(false);\n const [copiedCommand, setCopiedCommand] = useState<string | null>(null);\n\n // Stage 1: Basic details\n const [name, setName] = useState('');\n // Tracks whether the operator has typed into the name field. Once true,\n // we stop overwriting the value from auto-fill sources (target select +\n // identity probe) so we never clobber their input.\n const [nameEdited, setNameEdited] = useState(false);\n const [tunnelUrl, setTunnelUrl] = useState('');\n const [agentApiKey, setAgentApiKey] = useState('');\n const [selectedTargetId, setSelectedTargetId] = useState('');\n\n // When the operator picks a target, autofill the agent name with the\n // target's display name. Skip if they've already typed something into\n // the name field. The svc append a `-2`/`-3` suffix on collision so\n // it's safe to suggest a duplicate; the actual stored name comes back\n // on the create response.\n useEffect(() => {\n if (nameEdited) return;\n if (!selectedTargetId) return;\n const picked = (targets ?? []).find((t) => t.id === selectedTargetId);\n if (picked?.name) setName(picked.name);\n }, [selectedTargetId, targets, nameEdited]);\n\n // Inline target creation state\n const [showInlineTarget, setShowInlineTarget] = useState(false);\n const [inlineTargetName, setInlineTargetName] = useState('');\n const [creatingTarget, setCreatingTarget] = useState(false);\n const [inlineTargetError, setInlineTargetError] = useState<string | null>(null);\n\n // Stage 2: Validation (via backend-proxied GraphQL query)\n const [validating, setValidating] = useState(false);\n const [healthResult, setHealthResult] = useState<{\n ok: boolean;\n data?: { status: string; version: string; uptime: number };\n error?: string;\n } | null>(null);\n const [identityResult, setIdentityResult] = useState<{\n ok: boolean;\n data?: { hostname: string; platform: string; arch: string };\n error?: string;\n } | null>(null);\n\n // Auto-detected fields (editable overrides)\n const [detectedHostname, setDetectedHostname] = useState('');\n const [detectedPlatform, setDetectedPlatform] = useState('linux');\n const [detectedArch, setDetectedArch] = useState('x86_64');\n const [detectedVersion, setDetectedVersion] = useState('1.0.0');\n\n // Error state for creation failures\n const [createError, setCreateError] = useState<string | null>(null);\n\n // Advanced options (Phase 5B: per-daemon profile name).\n // Defaults to \"default\" (autofilled but editable). Disclosure is closed\n // by default — users only need to touch this for multi-profile setups.\n const [showAdvanced, setShowAdvanced] = useState(false);\n const [profile, setProfile] = useState('default');\n\n const copyToClipboard = useCallback((text: string, id: string) => {\n navigator.clipboard.writeText(text);\n setCopiedCommand(id);\n setTimeout(() => setCopiedCommand(null), 2000);\n }, []);\n\n const normalizeUrl = (url: string) => {\n let u = url.trim();\n if (u.endsWith('/')) u = u.slice(0, -1);\n return u;\n };\n\n // Validate the agent by probing /health and /api/profiles/default/agent/identity\n // directly from the browser. The agent exposes CORS-allowed endpoints for\n // app.vibecontrols.com (see agent's createApp() — `@elysiajs/cors` is wired\n // for the host origin), so the browser can reach the tunnel URL without a\n // backend proxy. The earlier backend-proxy approach (probeAgentTunnel query)\n // is still wired into the schema, but in production we observed the proxy\n // hanging at the ACA egress layer regardless of timeout, so we bypass it for\n // the wizard validate step. Each fetch is bounded by a 10s AbortSignal so a\n // dead tunnel surfaces a real error instead of an infinite spinner.\n const validateAgent = async () => {\n const baseUrl = normalizeUrl(tunnelUrl);\n if (!baseUrl) return;\n\n setValidating(true);\n setHealthResult(null);\n setIdentityResult(null);\n\n const probeHealth = async (): Promise<void> => {\n try {\n const res = await fetch(`${baseUrl}/health`, {\n signal: AbortSignal.timeout(10_000),\n });\n if (!res.ok) {\n setHealthResult({ ok: false, error: `HTTP ${String(res.status)}: ${res.statusText}` });\n return;\n }\n const data = (await res.json()) as {\n status?: string;\n version?: string;\n uptime?: number;\n };\n setHealthResult({\n ok: true,\n data: {\n status: data.status || 'healthy',\n version: data.version || 'unknown',\n uptime: data.uptime || 0,\n },\n });\n if (data.version) setDetectedVersion(data.version);\n } catch (err) {\n const isTimeout = err instanceof DOMException && err.name === 'AbortError';\n setHealthResult({\n ok: false,\n error: isTimeout\n ? 'Health check timed out after 10s'\n : err instanceof Error\n ? err.message\n : 'Health check failed',\n });\n }\n };\n\n const probeIdentity = async (): Promise<void> => {\n try {\n const headers: Record<string, string> = {};\n if (agentApiKey) headers['x-agent-api-key'] = agentApiKey;\n const res = await fetch(`${baseUrl}/api/profiles/default/agent/identity`, {\n headers,\n signal: AbortSignal.timeout(10_000),\n });\n if (!res.ok) {\n setIdentityResult({\n ok: false,\n error:\n res.status === 401\n ? 'Invalid API key'\n : `HTTP ${String(res.status)}: ${res.statusText}`,\n });\n return;\n }\n const data = (await res.json()) as {\n hostname?: string;\n platform?: string;\n arch?: string;\n };\n const hostname = data.hostname || '';\n const platform = data.platform || 'linux';\n const arch = data.arch || 'x86_64';\n setIdentityResult({ ok: true, data: { hostname, platform, arch } });\n if (hostname) setDetectedHostname(hostname);\n if (platform) setDetectedPlatform(platform);\n if (arch) setDetectedArch(arch);\n // Auto-fill the name from the probe's hostname unless (a) the\n // operator has manually typed a name, or (b) a target is already\n // selected (target name wins as the canonical autogenerated\n // value — see the selectedTargetId effect below).\n if (!nameEdited && !selectedTargetId && hostname) setName(hostname);\n } catch (err) {\n const isTimeout = err instanceof DOMException && err.name === 'AbortError';\n setIdentityResult({\n ok: false,\n error: isTimeout\n ? 'Identity check timed out after 10s'\n : err instanceof Error\n ? err.message\n : 'Identity check failed',\n });\n }\n };\n\n // Run both probes in parallel so the user sees results as fast as the\n // slower of the two — instead of stacking 20s in series on failure paths.\n await Promise.all([probeHealth(), probeIdentity()]);\n\n setValidating(false);\n };\n\n // Create the agent and close the modal\n const handleCreateAgent = async () => {\n setCreateError(null);\n\n // Pipe the chosen profile through `metadata.profile`. Phase 5A (svc) is\n // adding first-class AgentProfile rows; in the meantime the backend\n // also reads `metadata.profile` so the create path keeps working\n // regardless of which side of the cut-over the cluster is on.\n const trimmedProfile = profile.trim() || 'default';\n const data: Record<string, unknown> = {\n name: name || detectedHostname || 'Unnamed Agent',\n hostname: detectedHostname || 'unknown',\n platform: detectedPlatform,\n architecture: detectedArch,\n version: detectedVersion,\n tunnelUrl: normalizeUrl(tunnelUrl),\n tunnelStatus: 'ACTIVE',\n agentApiKey,\n metadata: { profile: trimmedProfile },\n ...(selectedTargetId ? { targetId: selectedTargetId } : {}),\n };\n\n try {\n const result = await onSubmit(data);\n const newAgentId = result?.id || null;\n\n if (!newAgentId) {\n // Mutation succeeded but returned no agent ID — treat as failure\n setCreateError('Agent creation returned no ID. The agent may already exist.');\n return;\n }\n\n // Close the modal — the agent list will refetch automatically\n if (onNavigate) {\n onNavigate(`/agents/${newAgentId}`);\n } else {\n onCancel();\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Failed to create agent';\n setCreateError(message);\n }\n };\n\n const isValidationPassed = healthResult?.ok && identityResult?.ok;\n const hasTargets = targets && targets.length > 0;\n // The user must either pick or inline-create a target if inline creation\n // is enabled; otherwise we only require it when targets already exist.\n const targetRequiredButMissing = onCreateTarget\n ? selectedTargetId.length === 0\n : hasTargets && selectedTargetId.length === 0;\n const canProceedToValidate = tunnelUrl.trim().length > 0 && !targetRequiredButMissing;\n\n const handleInlineCreateTarget = useCallback(async () => {\n if (!onCreateTarget || !inlineTargetName.trim()) return;\n setCreatingTarget(true);\n setInlineTargetError(null);\n try {\n const created = await onCreateTarget(inlineTargetName.trim());\n if (created) {\n setSelectedTargetId(created.id);\n setShowInlineTarget(false);\n setInlineTargetName('');\n } else {\n setInlineTargetError(\n tr('agentsPage.inlineTargetFailed', 'Failed to create target. Please try again.')\n );\n }\n } catch (err) {\n setInlineTargetError(err instanceof Error ? err.message : 'Failed to create target');\n } finally {\n setCreatingTarget(false);\n }\n }, [onCreateTarget, inlineTargetName, tr]);\n\n const renderCopyButton = (text: string, id: string) => (\n <button\n type=\"button\"\n onClick={() => copyToClipboard(text, id)}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors\"\n title={tr('agentsPage.copy', 'Copy')}\n >\n {copiedCommand === id ? (\n <Check className=\"size-3.5 text-status-success-text\" />\n ) : (\n <Copy className=\"size-3.5 text-text-secondary\" />\n )}\n </button>\n );\n\n // Stepper\n const steps = [\n { key: 'details', label: 'Setup' },\n { key: 'validate', label: 'Validate' },\n ];\n\n const currentStepIndex = steps.findIndex((s) => s.key === stage);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay\">\n <div className=\"w-full max-w-xl bg-bg-surface rounded-lg shadow-xl max-h-[90vh] overflow-y-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default sticky top-0 bg-bg-surface z-10\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('agentsPage.addNewAgent', 'Add New Agent')}\n </h2>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"p-1 rounded hover:bg-bg-sunken transition-colors\"\n >\n <X className=\"size-5 text-text-secondary\" />\n </button>\n </div>\n\n {/* Stepper */}\n <div className=\"flex items-center gap-2 px-6 pt-4 pb-2\">\n {steps.map((step, i) => (\n <div key={step.key} className=\"flex items-center gap-2\">\n <div\n className={`flex items-center justify-center size-7 rounded-full text-xs font-semibold transition-colors ${\n i < currentStepIndex\n ? 'bg-status-success-bg text-status-success-text'\n : i === currentStepIndex\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {i < currentStepIndex ? <CheckCircle2 className=\"size-4\" /> : i + 1}\n </div>\n <span\n className={`text-sm ${i === currentStepIndex ? 'font-medium text-text-primary' : 'text-text-secondary'}`}\n >\n {step.label}\n </span>\n {i < steps.length - 1 && <ChevronRight className=\"size-4 text-text-muted\" />}\n </div>\n ))}\n </div>\n\n <div className=\"p-6\">\n {/* Stage 1: Setup */}\n {stage === 'details' && (\n <div className=\"space-y-4\">\n {/* Install instructions (collapsible) */}\n <div className=\"border border-border-default rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setShowInstallInstructions(!showInstallInstructions)}\n className=\"w-full flex items-center justify-between px-4 py-3 bg-bg-sunken hover:bg-bg-sunken/80 transition-colors\"\n >\n <div className=\"flex items-center gap-2\">\n <Download className=\"size-4 text-action-primary-bg\" />\n <span className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.installInstructions', 'Agent Install Instructions')}\n </span>\n </div>\n <ChevronRight\n className={`size-4 text-text-secondary transition-transform ${showInstallInstructions ? 'rotate-90' : ''}`}\n />\n </button>\n {showInstallInstructions && (\n <div className=\"px-4 py-3 space-y-3 border-t border-border-default\">\n <div className=\"space-y-2\">\n {[\n {\n label: tr('agentsPage.installStep1', '1. Install the agent CLI'),\n cmd: 'npm install -g @vibecontrols/agent@latest',\n },\n {\n label: tr('agentsPage.installStep2', '2. Start the agent'),\n cmd: 'vibe start',\n },\n {\n label: tr('agentsPage.installStep3', '3. Get the API key'),\n cmd: 'vibe key',\n },\n {\n label: tr('agentsPage.installStep4', '4. Start the tunnel'),\n cmd: 'vibe tunnel agent --start',\n },\n ].map((step) => (\n <div key={step.cmd}>\n <p className=\"text-xs text-text-secondary mb-1\">{step.label}</p>\n <div className=\"flex items-center gap-2 bg-bg-sunken rounded-md px-3 py-1.5 font-mono text-xs text-text-primary\">\n <Terminal className=\"size-3 text-text-muted flex-shrink-0\" />\n <code className=\"flex-1\">{step.cmd}</code>\n {renderCopyButton(step.cmd, step.cmd)}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Target Selection — with inline creation */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.target', 'Target')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n\n {hasTargets && !showInlineTarget && (\n <>\n <SearchableSelect\n placeholder={tr('agentsPage.selectTarget', 'Select a target...')}\n searchPlaceholder={tr('agentsPage.searchTargets', 'Search targets...')}\n options={(targets ?? []).map(\n (tgt): SearchableSelectOption => ({\n value: tgt.id,\n label: tgt.name,\n description: `${tgt.type}${tgt.status ? ` · ${tgt.status}` : ''}`,\n })\n )}\n value={selectedTargetId}\n onChange={setSelectedTargetId}\n clearable\n />\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr(\n 'agentsPage.targetDescription',\n 'The target machine this agent will be installed on.'\n )}{' '}\n {onCreateTarget && (\n <button\n type=\"button\"\n onClick={() => {\n setShowInlineTarget(true);\n setInlineTargetName(name.trim() || '');\n }}\n className=\"text-action-primary-bg hover:underline inline-flex items-center gap-1\"\n >\n <Plus className=\"size-3\" />\n {tr('agentsPage.createNewTarget', 'Create a new target')}\n </button>\n )}\n </p>\n </>\n )}\n\n {/* Empty state prompt (no targets exist yet) */}\n {!hasTargets && !targetsLoading && onCreateTarget && !showInlineTarget && (\n <div className=\"p-3 bg-bg-sunken border border-border-default rounded-lg\">\n <p className=\"text-sm text-text-secondary mb-2\">\n {tr(\n 'agentsPage.noTargetsInlinePrompt',\n \"You don't have any targets yet. Create one now to install this agent on it.\"\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => {\n setShowInlineTarget(true);\n setInlineTargetName(name.trim() || '');\n }}\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:opacity-90\"\n >\n <Plus className=\"size-4\" />\n {tr('agentsPage.createFirstTarget', 'Create first target')}\n </button>\n </div>\n )}\n\n {/* Inline creation form */}\n {showInlineTarget && onCreateTarget && (\n <div className=\"p-3 bg-bg-sunken border border-border-default rounded-lg space-y-2\">\n <p className=\"text-xs font-medium text-text-secondary\">\n {tr(\n 'agentsPage.newDirectTarget',\n 'New target (Direct — you can change the type later)'\n )}\n </p>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={inlineTargetName}\n onChange={(e) => setInlineTargetName(e.target.value)}\n placeholder={tr('agentsPage.targetName', 'Target name')}\n className=\"w-full px-3 py-2 text-sm bg-bg-elevated border border-border-default rounded-md text-text-primary placeholder-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n void handleInlineCreateTarget();\n }\n }}\n />\n {inlineTargetError && (\n <p className=\"text-xs text-status-error-text\">{inlineTargetError}</p>\n )}\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => void handleInlineCreateTarget()}\n disabled={!inlineTargetName.trim() || creatingTarget}\n className=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:opacity-90 disabled:opacity-50\"\n >\n {creatingTarget ? (\n <Loader2 className=\"size-3.5 animate-spin\" />\n ) : (\n <Check className=\"size-3.5\" />\n )}\n {tr('agentsPage.create', 'Create')}\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setShowInlineTarget(false);\n setInlineTargetName('');\n setInlineTargetError(null);\n }}\n className=\"px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary\"\n >\n {tr('agentsPage.cancel', 'Cancel')}\n </button>\n </div>\n </div>\n )}\n\n {/* Loading placeholder */}\n {targetsLoading && !hasTargets && (\n <div className=\"p-3 bg-bg-sunken border border-border-default rounded-lg flex items-center gap-2 text-sm text-text-secondary\">\n <Loader2 className=\"size-4 animate-spin\" />\n {tr('agentsPage.loadingTargets', 'Loading targets...')}\n </div>\n )}\n </div>\n\n {/* API/Tunnel URL */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.apiTunnelUrl', 'API / Tunnel URL')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n aria-label=\"https://your-tunnel.trycloudflare.com\"\n type=\"url\"\n value={tunnelUrl}\n onChange={(e) => setTunnelUrl(e.target.value)}\n placeholder=\"https://your-tunnel.trycloudflare.com\"\n required\n className=\"w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr(\n 'agentsPage.tunnelUrlHint',\n \"The agent's tunnel URL or local API URL (e.g. http://localhost:3005)\"\n )}\n </p>\n </div>\n\n {/* Agent API Key */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.agentApiKey', 'Agent API Key')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <div className=\"relative\">\n <input\n aria-label=\"vcak_...\"\n type={showApiKey ? 'text' : 'password'}\n value={agentApiKey}\n onChange={(e) => setAgentApiKey(e.target.value)}\n placeholder=\"vcak_...\"\n required\n className=\"w-full px-3 py-2 pr-10 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n />\n <button\n type=\"button\"\n onClick={() => setShowApiKey(!showApiKey)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded hover:bg-bg-elevated transition-colors\"\n >\n {showApiKey ? (\n <EyeOff className=\"size-4 text-text-secondary\" />\n ) : (\n <Eye className=\"size-4 text-text-secondary\" />\n )}\n </button>\n </div>\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr('agentsPage.apiKeyHint', 'Run')}{' '}\n <code className=\"bg-bg-sunken px-1 rounded\">vibe key</code>{' '}\n {tr(\n 'agentsPage.apiKeyHintSuffix',\n 'on the agent to get this. Changes on restart.'\n )}\n </p>\n </div>\n\n {/* Advanced options — per-daemon profile name (Phase 5B) */}\n <div className=\"border border-border-default rounded-lg overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setShowAdvanced((v) => !v)}\n className=\"w-full flex items-center justify-between px-4 py-2.5 bg-bg-sunken hover:bg-bg-sunken/80 transition-colors\"\n aria-expanded={showAdvanced}\n data-testid=\"agent-form-advanced-toggle\"\n >\n <div className=\"flex items-center gap-2\">\n <Settings2 className=\"size-4 text-text-secondary\" />\n <span className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.advancedOptions', 'Advanced options')}\n </span>\n </div>\n <ChevronDown\n className={`size-4 text-text-secondary transition-transform ${showAdvanced ? 'rotate-180' : ''}`}\n />\n </button>\n {showAdvanced && (\n <div className=\"px-4 py-3 space-y-3 border-t border-border-default\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('agentsPage.profileName', 'Profile name')}\n </label>\n <input\n aria-label=\"default\"\n type=\"text\"\n value={profile}\n onChange={(e) => setProfile(e.target.value)}\n placeholder=\"default\"\n className=\"w-full px-3 py-2 text-sm bg-bg-surface border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg font-mono\"\n data-testid=\"agent-form-profile-input\"\n />\n <p className=\"mt-1 text-xs text-text-muted\">\n {tr(\n 'agentsPage.profileNameHint',\n 'Each profile runs an isolated CLI on the daemon. Leave as \"default\" unless you want this agent to host multiple parallel profiles.'\n )}\n </p>\n </div>\n </div>\n )}\n </div>\n\n {extraSection && (\n <div className=\"border-t border-border-default pt-4 mt-4\">{extraSection}</div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center justify-between pt-4\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n {tr('agentsPage.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n disabled={!canProceedToValidate}\n onClick={() => {\n setStage('validate');\n validateAgent();\n }}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {tr('agentsPage.nextValidate', 'Next: Validate')}\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n </div>\n )}\n\n {/* Stage 2: Validate */}\n {stage === 'validate' && (\n <div className=\"space-y-4\">\n {/* Validation Results */}\n <div className=\"space-y-3\">\n {/* Health Check */}\n <div\n className={`flex items-center gap-3 p-3 rounded-lg border ${\n healthResult === null\n ? 'border-border-default bg-bg-sunken'\n : healthResult.ok\n ? 'border-status-success-text/20 bg-status-success-bg/30'\n : 'border-status-error-text/20 bg-status-error-bg/30'\n }`}\n >\n {validating && !healthResult ? (\n <Loader2 className=\"size-5 text-text-secondary animate-spin\" />\n ) : healthResult?.ok ? (\n <CheckCircle2 className=\"size-5 text-status-success-text\" />\n ) : healthResult ? (\n <XCircle className=\"size-5 text-status-error-text\" />\n ) : (\n <div className=\"size-5 rounded-full border-2 border-border-default\" />\n )}\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.healthCheck', 'Health Check')}\n </p>\n {healthResult?.ok && healthResult.data && (\n <p className=\"text-xs text-text-secondary\">\n Status: {healthResult.data.status} | Version: {healthResult.data.version} |\n Uptime: {Math.round(healthResult.data.uptime)}s\n </p>\n )}\n {healthResult && !healthResult.ok && (\n <p className=\"text-xs text-status-error-text\">{healthResult.error}</p>\n )}\n </div>\n </div>\n\n {/* API Access Check */}\n <div\n className={`flex items-center gap-3 p-3 rounded-lg border ${\n identityResult === null\n ? 'border-border-default bg-bg-sunken'\n : identityResult.ok\n ? 'border-status-success-text/20 bg-status-success-bg/30'\n : 'border-status-error-text/20 bg-status-error-bg/30'\n }`}\n >\n {validating && !identityResult ? (\n <Loader2 className=\"size-5 text-text-secondary animate-spin\" />\n ) : identityResult?.ok ? (\n <CheckCircle2 className=\"size-5 text-status-success-text\" />\n ) : identityResult ? (\n <XCircle className=\"size-5 text-status-error-text\" />\n ) : (\n <div className=\"size-5 rounded-full border-2 border-border-default\" />\n )}\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.apiAccess', 'API Access')}\n </p>\n {identityResult?.ok && identityResult.data && (\n <p className=\"text-xs text-text-secondary\">\n Host: {identityResult.data.hostname} | {identityResult.data.platform} /{' '}\n {identityResult.data.arch}\n </p>\n )}\n {identityResult && !identityResult.ok && (\n <p className=\"text-xs text-status-error-text\">{identityResult.error}</p>\n )}\n </div>\n </div>\n </div>\n\n {/* Retry button */}\n {!validating && (!healthResult?.ok || !identityResult?.ok) && (\n <button\n type=\"button\"\n onClick={validateAgent}\n className=\"flex items-center gap-2 px-3 py-1.5 text-sm text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-md transition-colors\"\n >\n <RefreshCw className=\"size-3.5\" />\n {tr('agentsPage.retryValidation', 'Retry validation')}\n </button>\n )}\n\n {/* Detected info (editable overrides) */}\n {isValidationPassed && (\n <div className=\"space-y-3 pt-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('agentsPage.detectedAgentInfo', 'Detected Agent Info')}\n </p>\n\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('agentsPage.name', 'Name')}\n </label>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={name}\n onChange={(e) => {\n setName(e.target.value);\n setNameEdited(true);\n }}\n placeholder={detectedHostname}\n className=\"w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('agentsPage.platform', 'Platform')}\n </label>\n <select\n value={detectedPlatform}\n onChange={(e) => setDetectedPlatform(e.target.value)}\n className=\"w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n >\n <option value=\"linux\">Linux</option>\n <option value=\"darwin\">macOS</option>\n <option value=\"windows\">Windows</option>\n </select>\n </div>\n <div>\n <label className=\"block text-xs font-medium text-text-secondary mb-1\">\n {tr('agentsPage.architecture', 'Architecture')}\n </label>\n <select\n value={detectedArch}\n onChange={(e) => setDetectedArch(e.target.value)}\n className=\"w-full px-3 py-1.5 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n >\n <option value=\"x86_64\">x86_64</option>\n <option value=\"arm64\">arm64</option>\n <option value=\"aarch64\">aarch64</option>\n </select>\n </div>\n </div>\n </div>\n )}\n\n {/* Creation error */}\n {createError && (\n <div className=\"p-3 bg-status-error-bg/30 border border-status-error-text/20 rounded-lg\">\n <div className=\"flex items-center gap-2\">\n <XCircle className=\"size-5 text-status-error-text flex-shrink-0\" />\n <p className=\"text-sm text-status-error-text\">{createError}</p>\n </div>\n <div className=\"flex items-center gap-2 mt-3\">\n <button\n type=\"button\"\n onClick={() => {\n setCreateError(null);\n // Reset form to allow entering different credentials\n setStage('details');\n setTunnelUrl('');\n setAgentApiKey('');\n setHealthResult(null);\n setIdentityResult(null);\n }}\n className=\"flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n <RefreshCw className=\"size-3.5\" />\n {tr('agentsPage.tryDifferentAgent', 'Try Different Agent')}\n </button>\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-3 py-1.5 text-sm font-medium text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('agentsPage.close', 'Close')}\n </button>\n </div>\n </div>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center justify-between pt-4\">\n <button\n type=\"button\"\n onClick={() => setStage('details')}\n className=\"flex items-center gap-1 px-4 py-2 text-sm font-medium text-text-primary bg-bg-sunken border border-border-default rounded-md hover:bg-bg-elevated transition-colors\"\n >\n <ChevronLeft className=\"size-4\" />\n {tr('agentsPage.back', 'Back')}\n </button>\n <button\n type=\"button\"\n disabled={!isValidationPassed || isLoading || validating}\n onClick={handleCreateAgent}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {isLoading ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {tr('agentsPage.adding', 'Adding...')}\n </>\n ) : (\n <>\n {tr('agentsPage.addAgent', 'Add Agent')}\n <ChevronRight className=\"size-4\" />\n </>\n )}\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-vibecontrols",
3
- "version": "2026.529.9",
3
+ "version": "2026.529.10",
4
4
  "description": "VibeControls microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [