@openagt/servers 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,54 +1,58 @@
1
- import { Button as e, Checkbox as t, Input as n, SettingsSection as r, defineModule as i, useModuleHost as a, usePolled as o } from "@openagt/dashboard/module";
2
- import { useEffect as s, useRef as c, useState as l } from "react";
3
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
1
+ import { Button as e, Checkbox as t, Input as n, QrCode as r, SettingsSection as i, defineModule as a, useModuleHost as o, usePolled as s } from "@openagt/dashboard/module";
2
+ import { useEffect as c, useRef as l, useState as u } from "react";
3
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
4
4
  //#region dashboard/servers.ts
5
- var f = (e) => typeof e == "string" && e ? e : void 0, p = [
5
+ var p = (e) => typeof e == "string" && e ? e : void 0, m = [
6
6
  "waiting",
7
7
  "running",
8
8
  "done",
9
9
  "failed"
10
10
  ];
11
- function m(e) {
12
- let { there: t, working: n, asking: r, wanted: i, account: a, since: o, ends: s, said: c } = e && typeof e == "object" ? e : {}, [l, u, d, p] = [
13
- f(a),
14
- f(o),
15
- f(s),
16
- f(c)
11
+ function h(e) {
12
+ let { there: t, working: n, asking: r, code: i, wanted: a, account: o, since: s, ends: c, said: l } = e && typeof e == "object" ? e : {}, [u, d, f, m, h] = [
13
+ p(o),
14
+ p(s),
15
+ p(c),
16
+ p(l),
17
+ p(i)
17
18
  ];
18
19
  return {
19
20
  there: t === !0,
20
21
  working: n === !0,
21
- ...r === !0 ? { asking: !0 } : {},
22
- ...i === !0 ? { wanted: !0 } : {},
23
- ...l ? { account: l } : {},
24
- ...u ? { since: u } : {},
25
- ...d ? { ends: d } : {},
26
- ...p ? { said: p } : {}
22
+ ...r === !0 ? {
23
+ asking: !0,
24
+ ...h ? { code: h } : {}
25
+ } : {},
26
+ ...a === !0 ? { wanted: !0 } : {},
27
+ ...u ? { account: u } : {},
28
+ ...d ? { since: d } : {},
29
+ ...f ? { ends: f } : {},
30
+ ...m ? { said: m } : {}
27
31
  };
28
32
  }
29
- function h(e) {
33
+ function g(e) {
30
34
  if (!e || typeof e != "object") return;
31
35
  let { servers: t } = e;
32
36
  if (!Array.isArray(t)) return;
33
37
  let n = [];
34
38
  for (let e of t) {
35
39
  if (!e || typeof e != "object") continue;
36
- let { address: t, url: r, user: i, fingerprint: a, working: o, adding: s, steps: c, logins: l } = e, { github: u, claude: d } = l && typeof l == "object" ? l : {}, [h, g, _, v] = [
37
- f(t),
38
- f(r),
39
- f(i),
40
- f(a)
40
+ let { address: t, url: r, user: i, fingerprint: a, working: o, adding: s, steps: c, logins: l } = e, { github: u, claude: d } = l && typeof l == "object" ? l : {}, [f, g, _, v] = [
41
+ p(t),
42
+ p(r),
43
+ p(i),
44
+ p(a)
41
45
  ];
42
- if (!h || !g || !_ || !Array.isArray(c)) continue;
46
+ if (!f || !g || !_ || !Array.isArray(c)) continue;
43
47
  let y = [];
44
48
  for (let e of c) {
45
49
  if (!e || typeof e != "object") continue;
46
50
  let { id: t, label: n, state: r, said: i } = e, [a, o, s] = [
47
- f(t),
48
- f(n),
49
- f(i)
51
+ p(t),
52
+ p(n),
53
+ p(i)
50
54
  ];
51
- a && o && p.includes(r) && y.push({
55
+ a && o && m.includes(r) && y.push({
52
56
  id: a,
53
57
  label: o,
54
58
  state: r,
@@ -56,7 +60,7 @@ function h(e) {
56
60
  });
57
61
  }
58
62
  n.push({
59
- address: h,
63
+ address: f,
60
64
  url: g,
61
65
  user: _,
62
66
  ...v ? { fingerprint: v } : {},
@@ -64,99 +68,91 @@ function h(e) {
64
68
  adding: s === !0,
65
69
  steps: y,
66
70
  logins: {
67
- github: m(u),
68
- claude: m(d)
71
+ github: h(u),
72
+ claude: h(d)
69
73
  }
70
74
  });
71
75
  }
72
76
  return n;
73
77
  }
74
- function g(e) {
78
+ function _(e) {
75
79
  if (!e || typeof e != "object") return;
76
- let { url: t, expires: n } = e, [r, i] = [f(t), f(n)];
80
+ let { url: t, expires: n } = e, [r, i] = [p(t), p(n)];
77
81
  return r && i ? {
78
82
  url: r,
79
83
  expires: i
80
84
  } : void 0;
81
85
  }
82
- async function _(e, t, n, r) {
83
- let i = {
86
+ async function v(e, t, n) {
87
+ let r = await e.runComputerCommand(t).catch((e) => ({
88
+ ok: !1,
89
+ error: e instanceof Error ? e.message : String(e)
90
+ }));
91
+ if (!r.ok) return r;
92
+ let i = n(r.output);
93
+ return i === void 0 ? {
84
94
  ok: !1,
85
- error: "no project to run the command in"
95
+ error: "the command answered something else than expected"
96
+ } : {
97
+ ok: !0,
98
+ value: i
86
99
  };
87
- for (let [a, o] of t.entries()) {
88
- let t = await e.runCommand(o.id, n).catch((e) => ({
89
- ok: !1,
90
- error: e instanceof Error ? e.message : String(e)
91
- }));
92
- if (t.ok) {
93
- let e = r(t.output);
94
- return e === void 0 ? {
95
- ok: !1,
96
- error: "the command answered something else than expected"
97
- } : {
98
- ok: !0,
99
- value: e
100
- };
101
- }
102
- a === 0 && (i = t);
103
- }
104
- return i;
105
100
  }
106
- var v = (e, t) => _(e, t, ["status"], h), y = (e, t, n, r, i, a = !1) => _(e, t, [
101
+ var y = (e) => v(e, ["status"], g), ee = (e, t, n, r, i = !1) => v(e, [
107
102
  "connect",
103
+ t,
108
104
  n,
109
105
  r,
110
- i,
111
- ...a ? ["github"] : []
112
- ], h);
106
+ ...i ? ["github"] : []
107
+ ], g);
113
108
  function b(e) {
114
109
  if (!e || typeof e != "object") return;
115
- let { account: t, problem: n } = e, [r, i] = [f(t), f(n)];
110
+ let { account: t, problem: n } = e, [r, i] = [p(t), p(n)];
116
111
  return r ? { account: r } : i ? { problem: i } : void 0;
117
112
  }
118
- var ee = (e, t) => _(e, t, ["github"], b), x = (e, t, n, r) => _(e, t, [
113
+ var te = (e) => v(e, ["github"], b), x = (e, t, n, r = !1) => v(e, [
119
114
  "login",
115
+ t,
120
116
  n,
121
- r
122
- ], h), S = (e, t, n, r) => _(e, t, [
117
+ ...r ? ["own"] : []
118
+ ], g), S = (e, t, n) => v(e, [
123
119
  "logout",
124
- n,
125
- r
126
- ], h), C = (e, t, n) => _(e, t, ["link", n], g), w = (e, t, n) => _(e, t, ["added", n], h), T = (e, t, n) => _(e, t, ["forget", n], h), E = void 0, te = void 0, ne = void 0, D = (e) => e === void 0 ? "" : new Date(e).toLocaleDateString(void 0, {
120
+ t,
121
+ n
122
+ ], g), C = (e, t) => v(e, ["link", t], _), w = (e, t) => v(e, ["added", t], g), T = (e, t) => v(e, ["forget", t], g), E = void 0, D = 5 * 6e4, ne = void 0, re = void 0, O = (e) => e === void 0 ? "" : new Date(e).toLocaleDateString(void 0, {
127
123
  day: "numeric",
128
124
  month: "short",
129
125
  year: "numeric"
130
126
  });
131
- function O({ label: e, words: t, said: n, children: r }) {
132
- return /* @__PURE__ */ d("li", {
127
+ function k({ label: e, words: t, said: n, children: r }) {
128
+ return /* @__PURE__ */ f("li", {
133
129
  "aria-label": e,
134
130
  className: "space-y-1",
135
- children: [/* @__PURE__ */ d("div", {
131
+ children: [/* @__PURE__ */ f("div", {
136
132
  className: "flex flex-wrap items-center justify-between gap-2",
137
- children: [/* @__PURE__ */ u("span", { children: t }), /* @__PURE__ */ u("div", {
133
+ children: [/* @__PURE__ */ d("span", { children: t }), /* @__PURE__ */ d("div", {
138
134
  className: "flex gap-2",
139
135
  children: r
140
136
  })]
141
- }), n !== void 0 && /* @__PURE__ */ u("pre", {
137
+ }), n !== void 0 && /* @__PURE__ */ d("pre", {
142
138
  role: "alert",
143
139
  className: "overflow-x-auto whitespace-pre-wrap rounded-md border border-border bg-background p-2 font-mono text-foreground",
144
140
  children: n
145
141
  })]
146
142
  });
147
143
  }
148
- var k = {
144
+ var A = {
149
145
  waiting: "○",
150
146
  running: "…",
151
147
  done: "✓",
152
148
  failed: "✕"
153
- }, re = {
149
+ }, ie = {
154
150
  waiting: "not started",
155
151
  running: "running",
156
152
  done: "done",
157
153
  failed: "failed"
158
- }, A = (e, t) => Object.fromEntries(Object.entries(e).filter(([e]) => e !== t));
159
- function j(e, t) {
154
+ }, j = (e, t) => Object.fromEntries(Object.entries(e).filter(([e]) => e !== t));
155
+ function ae(e, t) {
160
156
  let n = (e) => {
161
157
  let t = /^(\d+)\.(\d+)\.(\d+)/.exec(e);
162
158
  return t ? t.slice(1).map(Number) : void 0;
@@ -165,194 +161,244 @@ function j(e, t) {
165
161
  for (let e = 0; e < 3; e++) if (r[e] !== i[e]) return r[e] < i[e];
166
162
  return !1;
167
163
  }
168
- function M({ projects: i, everyMs: f = 3e3 }) {
169
- let p = a(), m = i.map((e) => e.id).join(","), { value: h, reload: g } = o(() => v(p, i), E, f, [m]), { value: _, reload: b } = o(() => p.machines(), te, Math.max(f, 1e4), []), { value: M } = o(() => ee(p, i), ne, Math.max(f, 5 * 6e4), [m]), N = M?.ok && "account" in M.value ? M.value.account : void 0, P = M === void 0 || N !== void 0 ? void 0 : M.ok ? "problem" in M.value ? M.value.problem : void 0 : M.error, [F, I] = l(""), [L, R] = l("root"), [z, B] = l(!1), [V, H] = l(!1), [U, W] = l(), [G, K] = l({}), q = c(/* @__PURE__ */ new Set()), J = h?.ok ? h.value : [], Y = (e, t = _) => t?.machines.find((t) => t.url === e.url), X = (e) => !e.working && e.steps.every((e) => e.state === "done"), Z = async (e) => {
170
- H(!0), W(void 0);
164
+ function M({ everyMs: a = 3e3 }) {
165
+ let p = o(), { value: m, reload: h } = s(() => y(p), E, a, []), { value: g, reload: _ } = s(() => p.machines(), ne, Math.max(a, 1e4), []), { value: v } = s(() => te(p), re, Math.max(a, 5 * 6e4), []), b = v?.ok && "account" in v.value ? v.value.account : void 0, M = v === void 0 || b !== void 0 ? void 0 : v.ok ? "problem" in v.value ? v.value.problem : void 0 : v.error, [N, P] = u(""), [F, I] = u("root"), [L, R] = u(!1), [z, B] = u(!1), [V, H] = u(), [U, W] = u({}), G = l(/* @__PURE__ */ new Set()), [K, q] = u(), J = m?.ok ? m.value : [], Y = (e, t = g) => t?.machines.find((t) => t.url === e.url), X = (e) => !e.working && e.steps.every((e) => e.state === "done"), Z = async (e) => {
166
+ B(!0), H(void 0);
171
167
  let t = await e();
172
- return t.ok || W(t.error), await g().catch(() => {}), H(!1), t.ok;
173
- }, Q = async (e, t, n = !1) => !_ || _.version === "unknown" ? (W("This computer could not say which OpenAgent it runs."), !1) : (K((t) => A(t, e)), Z(() => y(p, i, e, t, _.version, n))), $ = async (e) => {
174
- if (q.current.has(e.address)) return;
175
- q.current.add(e.address), K((t) => A(t, e.address));
176
- let t = (t) => K((n) => ({
168
+ return t.ok || H(t.error), await h().catch(() => {}), B(!1), t.ok;
169
+ }, Q = async (e, t, n = !1) => !g || g.version === "unknown" ? (H("This computer could not say which OpenAgent it runs."), !1) : (W((t) => j(t, e)), Z(() => ee(p, e, t, g.version, n))), $ = async (e) => {
170
+ if (G.current.has(e.address)) return;
171
+ G.current.add(e.address), W((t) => j(t, e.address));
172
+ let t = (t) => W((n) => ({
177
173
  ...n,
178
174
  [e.address]: t
179
175
  }));
180
176
  try {
181
177
  if (Y(e, await p.machines())?.version === void 0) {
182
- let n = await C(p, i, e.address), r = n.ok ? await p.addMachine(n.value.url, e.address) : n;
178
+ let n = await C(p, e.address), r = n.ok ? await p.addMachine(n.value.url, e.address) : n;
183
179
  if (!r.ok) return t(r.error);
184
180
  }
185
- let n = await w(p, i, e.address);
181
+ let n = await w(p, e.address);
186
182
  if (!n.ok) return t(n.error);
187
- await Promise.all([g(), b()]).catch(() => {});
183
+ await Promise.all([h(), _()]).catch(() => {});
188
184
  } catch (e) {
189
185
  t(e instanceof Error ? e.message : String(e));
190
186
  } finally {
191
- q.current.delete(e.address);
187
+ G.current.delete(e.address);
192
188
  }
193
189
  };
194
- return s(() => {
195
- if (_) for (let e of J) e.adding && X(e) && G[e.address] === void 0 && $(e);
196
- }), i.length === 0 ? null : /* @__PURE__ */ d(r, {
190
+ c(() => {
191
+ if (g) for (let e of J) e.adding && X(e) && U[e.address] === void 0 && $(e);
192
+ }), c(() => {
193
+ if (!K) return;
194
+ let e = setTimeout(() => q(void 0), Math.min(D, Math.max(0, Date.parse(K.expires) - Date.now())));
195
+ return () => clearTimeout(e);
196
+ }, [K]);
197
+ let oe = async (e) => {
198
+ B(!0), H(void 0), q(void 0);
199
+ let t = await C(p, e.address);
200
+ t.ok ? q({
201
+ ...t.value,
202
+ address: e.address
203
+ }) : H(t.error), B(!1);
204
+ };
205
+ return /* @__PURE__ */ f(i, {
197
206
  title: "Servers",
198
207
  description: "Connect your VPS: give its address and a user name, and OpenAgent installs itself there over SSH, with this computer's own SSH keys. The server then runs OpenAgent by itself, and is one of your machines.",
199
208
  children: [
200
- /* @__PURE__ */ d("form", {
209
+ /* @__PURE__ */ f("form", {
201
210
  onSubmit: (e) => {
202
- e.preventDefault(), !(!F.trim() || !L.trim()) && Q(F.trim(), L.trim(), z && N !== void 0).then((e) => e && I(""));
211
+ e.preventDefault(), !(!N.trim() || !F.trim()) && Q(N.trim(), F.trim(), L && b !== void 0).then((e) => e && P(""));
203
212
  },
204
213
  className: "flex flex-wrap items-end gap-2 py-3",
205
214
  children: [
206
- /* @__PURE__ */ d("label", {
215
+ /* @__PURE__ */ f("label", {
207
216
  className: "min-w-40 flex-1 space-y-1 text-xs text-muted-foreground",
208
- children: [/* @__PURE__ */ u("span", { children: "The server's address" }), /* @__PURE__ */ u(n, {
217
+ children: [/* @__PURE__ */ d("span", { children: "The server's address" }), /* @__PURE__ */ d(n, {
209
218
  "aria-label": "The server's address",
210
219
  placeholder: "203.0.113.5",
211
- value: F,
212
- onChange: (e) => I(e.target.value)
220
+ value: N,
221
+ onChange: (e) => P(e.target.value)
213
222
  })]
214
223
  }),
215
- /* @__PURE__ */ d("label", {
224
+ /* @__PURE__ */ f("label", {
216
225
  className: "w-32 space-y-1 text-xs text-muted-foreground",
217
- children: [/* @__PURE__ */ u("span", { children: "User name" }), /* @__PURE__ */ u(n, {
226
+ children: [/* @__PURE__ */ d("span", { children: "User name" }), /* @__PURE__ */ d(n, {
218
227
  "aria-label": "User name",
219
- value: L,
220
- onChange: (e) => R(e.target.value)
228
+ value: F,
229
+ onChange: (e) => I(e.target.value)
221
230
  })]
222
231
  }),
223
- /* @__PURE__ */ u(e, {
232
+ /* @__PURE__ */ d(e, {
224
233
  size: "sm",
225
234
  type: "submit",
226
- disabled: V || !_ || !F.trim() || !L.trim(),
235
+ disabled: z || !g || !N.trim() || !F.trim(),
227
236
  children: "Connect"
228
237
  })
229
238
  ]
230
239
  }),
231
- /* @__PURE__ */ d("div", {
240
+ /* @__PURE__ */ f("div", {
232
241
  className: "space-y-2 pb-3",
233
- children: [/* @__PURE__ */ d("label", {
242
+ children: [/* @__PURE__ */ f("label", {
234
243
  className: "flex items-start gap-2 text-xs",
235
- children: [/* @__PURE__ */ u(t, {
236
- checked: z && N !== void 0,
237
- onCheckedChange: (e) => B(e === !0),
238
- disabled: V || N === void 0,
244
+ children: [/* @__PURE__ */ d(t, {
245
+ checked: L && b !== void 0,
246
+ onCheckedChange: (e) => R(e === !0),
247
+ disabled: z || b === void 0,
239
248
  className: "mt-0.5",
240
249
  "aria-label": "Copy my GitHub login to the server"
241
- }), /* @__PURE__ */ d("span", { children: [
242
- N === void 0 ? "Copy my GitHub login to the server." : `Copy my GitHub login (${N}) to the server.`,
250
+ }), /* @__PURE__ */ f("span", { children: [
251
+ b === void 0 ? "Copy my GitHub login to the server." : `Copy my GitHub login (${b}) to the server.`,
243
252
  " ",
244
- /* @__PURE__ */ u("span", {
253
+ /* @__PURE__ */ d("span", {
245
254
  className: "text-muted-foreground",
246
- children: P ?? "It can do there all it can do here, and every agent that runs on the server works with it. It goes there at the install's end, to a server met for the first time too, whose key is taken as it is."
255
+ children: M ?? "It can do there all it can do here, and every agent that runs on the server works with it. It goes there at the install's end, to a server met for the first time too, whose key is taken as it is."
247
256
  })
248
257
  ] })]
249
- }), /* @__PURE__ */ u("p", {
258
+ }), /* @__PURE__ */ d("p", {
250
259
  className: "text-xs text-muted-foreground",
251
260
  children: "The user is root, or one that becomes root without a password. It is only used to install, to update and to give the server its logins: what runs on the server afterwards runs as a user of its own, openagent."
252
261
  })]
253
262
  }),
254
- J.length > 0 && /* @__PURE__ */ u("ul", {
263
+ J.length > 0 && /* @__PURE__ */ d("ul", {
255
264
  "aria-label": "Servers",
256
265
  className: "divide-y divide-border",
257
266
  children: J.map((t) => {
258
- let n = Y(t), r = !t.working && t.steps.some((e) => e.state === "failed"), a = n?.version !== void 0 && _ !== void 0 && j(n.version, _.version), o = G[t.address], { github: s, claude: c } = t.logins;
259
- return /* @__PURE__ */ d("li", {
267
+ let n = Y(t), i = !t.working && t.steps.some((e) => e.state === "failed"), a = n?.version !== void 0 && g !== void 0 && ae(n.version, g.version), o = U[t.address], { github: s, claude: c } = t.logins;
268
+ return /* @__PURE__ */ f("li", {
260
269
  "aria-label": t.address,
261
270
  className: "space-y-2 py-3",
262
271
  children: [
263
- /* @__PURE__ */ d("div", {
272
+ /* @__PURE__ */ f("div", {
264
273
  className: "flex flex-wrap items-center justify-between gap-2",
265
- children: [/* @__PURE__ */ d("div", {
274
+ children: [/* @__PURE__ */ f("div", {
266
275
  className: "min-w-0",
267
- children: [/* @__PURE__ */ u("p", {
276
+ children: [/* @__PURE__ */ d("p", {
268
277
  className: "truncate text-sm",
269
278
  children: t.address
270
- }), /* @__PURE__ */ u("p", {
279
+ }), /* @__PURE__ */ d("p", {
271
280
  className: "text-xs text-muted-foreground",
272
- children: t.working ? "OpenAgent is being installed." : n?.version === void 0 ? n ? "Does not answer right now." : X(t) && !t.adding ? "Installed, and not among your machines." : `Logs in as ${t.user}.` : a ? `OpenAgent ${n.version}: behind this computer, which runs ${_.version}.` : `OpenAgent ${n.version}.`
281
+ children: t.working ? "OpenAgent is being installed." : n?.version === void 0 ? n ? "Does not answer right now." : X(t) && !t.adding ? "Installed, and not among your machines." : `Logs in as ${t.user}.` : a ? `OpenAgent ${n.version}: behind this computer, which runs ${g.version}.` : `OpenAgent ${n.version}.`
273
282
  })]
274
- }), /* @__PURE__ */ d("div", {
283
+ }), /* @__PURE__ */ f("div", {
275
284
  className: "flex gap-2",
276
285
  children: [
277
- a && !t.working && !r && /* @__PURE__ */ u(e, {
286
+ a && !t.working && !i && /* @__PURE__ */ d(e, {
278
287
  size: "sm",
279
- disabled: V,
288
+ disabled: z,
280
289
  "aria-label": `Update ${t.address}`,
281
290
  onClick: () => void Q(t.address, t.user),
282
291
  children: "Update"
283
292
  }),
284
- r && /* @__PURE__ */ u(e, {
293
+ i && /* @__PURE__ */ d(e, {
285
294
  size: "sm",
286
- disabled: V,
295
+ disabled: z,
287
296
  "aria-label": `Try ${t.address} again`,
288
297
  onClick: () => void Q(t.address, t.user, s.wanted === !0),
289
298
  children: "Try again"
290
299
  }),
291
- X(t) && n?.version === void 0 && (o !== void 0 || !t.adding) && /* @__PURE__ */ u(e, {
300
+ X(t) && n?.version === void 0 && (o !== void 0 || !t.adding) && /* @__PURE__ */ d(e, {
292
301
  size: "sm",
293
302
  variant: "outline",
294
- disabled: V,
303
+ disabled: z,
295
304
  "aria-label": `Add ${t.address} to Machines`,
296
305
  onClick: () => void $(t),
297
306
  children: n ? "Add again" : "Add to Machines"
298
307
  }),
299
- !t.working && /* @__PURE__ */ u(e, {
308
+ X(t) && /* @__PURE__ */ d(e, {
309
+ size: "sm",
310
+ variant: "outline",
311
+ disabled: z,
312
+ "aria-label": `Add a device to ${t.address}`,
313
+ onClick: () => void oe(t),
314
+ children: "Add device"
315
+ }),
316
+ !t.working && /* @__PURE__ */ d(e, {
300
317
  size: "sm",
301
318
  variant: "outline",
302
- disabled: V,
319
+ disabled: z,
303
320
  "aria-label": `Remove ${t.address}`,
304
321
  title: "Takes the server off this list. Nothing is changed on the server: its logins stay there until you remove them.",
305
- onClick: () => void Z(() => T(p, i, t.address)),
322
+ onClick: () => void Z(() => T(p, t.address)),
306
323
  children: "Remove"
307
324
  })
308
325
  ]
309
326
  })]
310
327
  }),
311
- /* @__PURE__ */ d("ol", {
328
+ K?.address === t.address && /* @__PURE__ */ f("div", {
329
+ className: "space-y-2",
330
+ children: [
331
+ /* @__PURE__ */ d(r, {
332
+ text: K.url,
333
+ label: `The code a new device scans to get into ${t.address}`
334
+ }),
335
+ /* @__PURE__ */ d("p", {
336
+ className: "text-xs text-muted-foreground",
337
+ children: "Scan it with the device's camera: it opens OpenAgent on the server, from anywhere. The code works once, for five minutes."
338
+ }),
339
+ /* @__PURE__ */ f("div", {
340
+ className: "flex flex-wrap items-center gap-3",
341
+ children: [/* @__PURE__ */ d("a", {
342
+ href: K.url,
343
+ target: "_blank",
344
+ rel: "noreferrer",
345
+ className: "text-xs underline",
346
+ onClick: () => q(void 0),
347
+ children: "Let this browser in instead"
348
+ }), /* @__PURE__ */ d(e, {
349
+ size: "sm",
350
+ variant: "outline",
351
+ onClick: () => q(void 0),
352
+ children: "Done"
353
+ })]
354
+ })
355
+ ]
356
+ }),
357
+ /* @__PURE__ */ f("ol", {
312
358
  "aria-label": `The install on ${t.address}`,
313
359
  className: "space-y-1 text-xs",
314
360
  children: [
315
- t.steps.map((e) => /* @__PURE__ */ d("li", {
316
- "aria-label": `${e.label}: ${re[e.state]}`,
361
+ t.steps.map((e) => /* @__PURE__ */ f("li", {
362
+ "aria-label": `${e.label}: ${ie[e.state]}`,
317
363
  children: [
318
- /* @__PURE__ */ d("span", {
364
+ /* @__PURE__ */ f("span", {
319
365
  className: e.state === "failed" ? "text-danger" : e.state === "waiting" ? "text-muted-foreground" : void 0,
320
- children: [/* @__PURE__ */ u("span", {
366
+ children: [/* @__PURE__ */ d("span", {
321
367
  "aria-hidden": !0,
322
368
  className: "inline-block w-4",
323
- children: k[e.state]
369
+ children: A[e.state]
324
370
  }), e.label]
325
371
  }),
326
- e.id === "login" && e.state === "done" && t.fingerprint !== void 0 && /* @__PURE__ */ u("span", {
372
+ e.id === "login" && e.state === "done" && t.fingerprint !== void 0 && /* @__PURE__ */ d("span", {
327
373
  className: "ml-2 font-mono text-muted-foreground",
328
374
  children: `The server's key: ${t.fingerprint}`
329
375
  }),
330
- e.said !== void 0 && e.state === "failed" && /* @__PURE__ */ u("pre", {
376
+ e.said !== void 0 && e.state === "failed" && /* @__PURE__ */ d("pre", {
331
377
  role: "alert",
332
378
  className: "mt-1 ml-4 overflow-x-auto whitespace-pre-wrap rounded-md border border-border bg-background p-2 font-mono text-foreground",
333
379
  children: e.said
334
380
  })
335
381
  ]
336
382
  }, e.id)),
337
- t.logins.github.working && /* @__PURE__ */ d("li", {
383
+ t.logins.github.working && /* @__PURE__ */ f("li", {
338
384
  "aria-label": "Your GitHub login: not copied yet",
339
385
  className: "text-muted-foreground",
340
- children: [/* @__PURE__ */ u("span", {
386
+ children: [/* @__PURE__ */ d("span", {
341
387
  "aria-hidden": !0,
342
388
  className: "inline-block w-4",
343
- children: k[t.steps.every((e) => e.state === "done") ? "running" : "waiting"]
389
+ children: A[t.steps.every((e) => e.state === "done") ? "running" : "waiting"]
344
390
  }), "Your GitHub login"]
345
391
  }),
346
- X(t) && /* @__PURE__ */ d("li", {
392
+ X(t) && /* @__PURE__ */ f("li", {
347
393
  "aria-label": `Among your machines: ${n ? "done" : o === void 0 ? t.adding ? "running" : "not started" : "failed"}`,
348
- children: [/* @__PURE__ */ d("span", {
394
+ children: [/* @__PURE__ */ f("span", {
349
395
  className: n ? void 0 : o === void 0 ? "text-muted-foreground" : "text-danger",
350
- children: [/* @__PURE__ */ u("span", {
396
+ children: [/* @__PURE__ */ d("span", {
351
397
  "aria-hidden": !0,
352
398
  className: "inline-block w-4",
353
- children: k[n ? "done" : o === void 0 ? t.adding ? "running" : "waiting" : "failed"]
399
+ children: A[n ? "done" : o === void 0 ? t.adding ? "running" : "waiting" : "failed"]
354
400
  }), "Among your machines"]
355
- }), o !== void 0 && !n && /* @__PURE__ */ u("pre", {
401
+ }), o !== void 0 && !n && /* @__PURE__ */ d("pre", {
356
402
  role: "alert",
357
403
  className: "mt-1 ml-4 overflow-x-auto whitespace-pre-wrap rounded-md border border-border bg-background p-2 font-mono text-foreground",
358
404
  children: o
@@ -360,49 +406,68 @@ function M({ projects: i, everyMs: f = 3e3 }) {
360
406
  })
361
407
  ]
362
408
  }),
363
- X(t) && /* @__PURE__ */ d("ul", {
409
+ X(t) && /* @__PURE__ */ f("ul", {
364
410
  "aria-label": `The logins on ${t.address}`,
365
411
  className: "space-y-2 border-t border-border pt-2 text-xs",
366
- children: [/* @__PURE__ */ d(O, {
412
+ children: [/* @__PURE__ */ f(k, {
367
413
  label: "GitHub",
368
- words: s.working ? "GitHub: one moment, the server is being told." : s.there ? `GitHub: logged in as ${s.account ?? "you"} since ${D(s.since)}.` : s.said === void 0 ? "GitHub: no login on the server." : "GitHub: the last try did not go through.",
414
+ words: s.asking && s.code !== void 0 ? `GitHub: type the code ${s.code} at github.com/login/device, and say yes there.` : s.working ? "GitHub: one moment, the server is being told." : s.there ? `GitHub: logged in as ${s.account ?? "you"} since ${O(s.since)}.` : s.said === void 0 ? "GitHub: no login on the server." : "GitHub: the last try did not go through.",
369
415
  said: s.working ? void 0 : s.said,
370
- children: [/* @__PURE__ */ u(e, {
371
- size: "sm",
372
- variant: "outline",
373
- disabled: V || s.working || N === void 0,
374
- "aria-label": `Copy my GitHub login to ${t.address}`,
375
- title: N === void 0 ? P : `Copies the login of ${N} from this computer to the server, over SSH.`,
376
- onClick: () => void Z(() => x(p, i, t.address, "github")),
377
- children: s.there ? "Copy again" : "Copy my login"
378
- }), (s.there || s.said !== void 0) && !s.working && /* @__PURE__ */ u(e, {
379
- size: "sm",
380
- variant: "outline",
381
- disabled: V,
382
- "aria-label": `Remove the GitHub login from ${t.address}`,
383
- title: "Deletes the login on the server. The login itself stays good: it is this computer's own. To end it everywhere, take it back on github.com and log this computer's gh in again.",
384
- onClick: () => void Z(() => S(p, i, t.address, "github")),
385
- children: "Remove"
386
- })]
387
- }), /* @__PURE__ */ d(O, {
416
+ children: [
417
+ /* @__PURE__ */ d(e, {
418
+ size: "sm",
419
+ variant: "outline",
420
+ disabled: z || s.working || b === void 0,
421
+ "aria-label": `Copy my GitHub login to ${t.address}`,
422
+ title: b === void 0 ? M : `Copies the login of ${b} from this computer to the server, over SSH.`,
423
+ onClick: () => void Z(() => x(p, t.address, "github")),
424
+ children: s.there ? "Copy again" : "Copy my login"
425
+ }),
426
+ /* @__PURE__ */ d(e, {
427
+ size: "sm",
428
+ variant: "outline",
429
+ disabled: z || s.working && s.asking !== !0,
430
+ "aria-label": `Log in to GitHub for ${t.address}`,
431
+ title: "The server asks GitHub for a login of its own. GitHub gives a short code: you type it at github.com/login/device and say yes there. This computer's own GitHub login is not touched, and the login the server had is replaced.",
432
+ onClick: () => void Z(() => x(p, t.address, "github", !0)),
433
+ children: s.asking ? "Start over" : "Log in to GitHub"
434
+ }),
435
+ s.asking && s.code !== void 0 && /* @__PURE__ */ d("a", {
436
+ href: "https://github.com/login/device",
437
+ target: "_blank",
438
+ rel: "noreferrer",
439
+ className: "self-center underline",
440
+ children: "Open GitHub"
441
+ }),
442
+ (s.there || s.said !== void 0) && !s.working && /* @__PURE__ */ d(e, {
443
+ size: "sm",
444
+ variant: "outline",
445
+ disabled: z,
446
+ "aria-label": `Remove the GitHub login from ${t.address}`,
447
+ title: "Deletes the login on the server. The login itself is not ended by this: a copied one is this computer's own and stays good. To end one everywhere, take it back on github.com.",
448
+ onClick: () => void Z(() => S(p, t.address, "github")),
449
+ children: "Remove"
450
+ })
451
+ ]
452
+ }), /* @__PURE__ */ f(k, {
388
453
  label: "Claude",
389
- words: c.asking ? "Claude: say yes in the page this computer's browser opened." : c.working ? "Claude: one moment, the server is being told." : c.there ? `Claude: logged in since ${D(c.since)}, good until about ${D(c.ends)}.` : c.said === void 0 ? "Claude: not logged in on the server." : "Claude: the last try did not go through.",
454
+ words: c.asking ? "Claude: say yes in the page this computer's browser opened." : c.working ? "Claude: one moment, the server is being told." : c.there ? `Claude: logged in since ${O(c.since)}, good until about ${O(c.ends)}.` : c.said === void 0 ? "Claude: not logged in on the server." : "Claude: the last try did not go through.",
390
455
  said: c.working ? void 0 : c.said,
391
- children: [/* @__PURE__ */ u(e, {
456
+ children: [/* @__PURE__ */ d(e, {
392
457
  size: "sm",
393
458
  variant: c.there || c.working ? "outline" : "default",
394
- disabled: V || c.working && c.asking !== !0,
459
+ disabled: z || c.working && c.asking !== !0,
395
460
  "aria-label": `Log in to Claude for ${t.address}`,
396
461
  title: "Opens this computer's browser, where you say yes once. The login is made for this server alone and lasts a year; this computer's own Claude login is not touched.",
397
- onClick: () => void Z(() => x(p, i, t.address, "claude")),
462
+ onClick: () => void Z(() => x(p, t.address, "claude")),
398
463
  children: c.asking ? "Start over" : c.there ? "Log in again" : "Log in to Claude"
399
- }), (c.there || c.said !== void 0) && !c.working && /* @__PURE__ */ u(e, {
464
+ }), (c.there || c.said !== void 0) && !c.working && /* @__PURE__ */ d(e, {
400
465
  size: "sm",
401
466
  variant: "outline",
402
- disabled: V,
467
+ disabled: z,
403
468
  "aria-label": `Remove the Claude login from ${t.address}`,
404
469
  title: "Deletes the login on the server and starts OpenAgent there again without it. An agent at work there keeps it until it ends. The login itself stays good until its year is over.",
405
- onClick: () => void Z(() => S(p, i, t.address, "claude")),
470
+ onClick: () => void Z(() => S(p, t.address, "claude")),
406
471
  children: "Remove"
407
472
  })]
408
473
  })]
@@ -411,26 +476,26 @@ function M({ projects: i, everyMs: f = 3e3 }) {
411
476
  }, t.address);
412
477
  })
413
478
  }),
414
- h !== void 0 && !h.ok && /* @__PURE__ */ u("p", {
479
+ m !== void 0 && !m.ok && /* @__PURE__ */ d("p", {
415
480
  role: "alert",
416
481
  className: "py-3 text-xs text-danger",
417
- children: `The servers could not be read: ${h.error}`
482
+ children: `The servers could not be read: ${m.error}`
418
483
  }),
419
- U !== void 0 && /* @__PURE__ */ u("p", {
484
+ V !== void 0 && /* @__PURE__ */ d("p", {
420
485
  role: "alert",
421
486
  className: "py-3 text-xs text-danger",
422
- children: U
487
+ children: V
423
488
  })
424
489
  ]
425
490
  });
426
491
  }
427
492
  //#endregion
428
493
  //#region dashboard/index.tsx
429
- var N = i({
494
+ var N = a({
430
495
  settings: [{
431
496
  id: "servers",
432
497
  order: 20,
433
- Section: M
498
+ Section: () => /* @__PURE__ */ d(M, {})
434
499
  }],
435
500
  stylesheet: "dashboard.css"
436
501
  });