@omg-dev/app 0.1.321 → 0.1.323

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,9 +1,58 @@
1
1
  import { jsx as e } from "react/jsx-runtime";
2
- import { M as n } from "./embedded-Bk0VM5g-.js";
2
+ import { M as n } from "./embedded-BgLSMF4E.js";
3
3
  const t = `# Changelog
4
4
 
5
5
  Recent product updates and deployment notes.
6
6
 
7
+ ## August 9, 2026 - The named local URL goes, and the mobile app joins the audit (v0.1.323)
8
+
9
+ - **The named local URL (\`omg.local\`) is gone**, along with its Settings toggle.
10
+ It advertised a \`.local\` name for this machine's loopback over mDNS while the
11
+ server ran, on macOS only — and the caveat under the switch was most of the
12
+ story: you still had to install the PWA from \`localhost\`, because browsers only
13
+ treat localhost and loopback IPs as secure origins, so the \`.local\` name could
14
+ never register a service worker. A toggle whose own help text tells you not to
15
+ use it for the main flow was not worth its surface area. Setting an explicit
16
+ \`OMG_LOCAL_HOSTNAME\` in \`omg setup\` is untouched and still works.
17
+ - **The mobile app is finally covered by the dependency-advisory gate.** \`mobile/\`
18
+ is an Expo project on an npm lockfile and is not a workspace member, so
19
+ \`bun audit\` structurally could not see it — it was filed as a known exclusion
20
+ whose stated fix ("convert it to bun.lock") nobody was ever going to do. Two
21
+ high-severity advisories were sitting in there, visible to Dependabot and
22
+ invisible to our own green audit runs. The gate now audits each root with the
23
+ tool that can read it, so both advisories are recorded, dated, and re-verified
24
+ against the advisory API on every run.
25
+
26
+ ## August 9, 2026 - pi can sign in, and the agents page stops shouting (v0.1.322)
27
+
28
+ - **You can sign in to pi from Settings.** pi shipped with no sign-in at all —
29
+ just an \`ANTHROPIC_API_KEY\` note and two disabled buttons — because it has no
30
+ \`pi login\` command to drive; its login lives inside the interactive TUI. We now
31
+ use pi's own credential library in-process, so three providers connect from the
32
+ same UI as every other agent: **Claude (Pro/Max)** and **ChatGPT (Codex)** by
33
+ OAuth, and **OpenCode Zen** by API key. Credentials are written to pi's own
34
+ \`~/.pi/agent/auth.json\` under pi's lock, so a token refresh happening at the
35
+ same time cannot rotate a refresh token out from under itself.
36
+ - **pi can actually run as the provider you connected.** pi sessions could only
37
+ ever name one provider, so ChatGPT and Zen models would have been unreachable
38
+ even after signing in. Models now carry their provider, and only models whose
39
+ provider is connected are offered.
40
+ - **pi no longer reports "Ready" when nothing is configured.** The check treated
41
+ the existence of \`auth.json\` as proof of sign-in, but pi creates that file as
42
+ \`{}\` on first launch — so every machine that had ever started pi looked
43
+ connected. It now looks inside, and also counts env vars and pinned provider
44
+ keys.
45
+ - **The coding-agents settings page shows the state that matters.** It used to
46
+ print two badges, every check with its resolved binary path, an instructions
47
+ sentence, an install command and a login command — per agent, times seven. A
48
+ working agent now says nothing; a broken one says what is missing, and the
49
+ diagnostics are one tap down.
50
+ - **\`omg setup\` stopped handing out a URL it never checked.** On macOS the
51
+ summary's first line was \`http://omg.local:8766\` whenever \`dns-sd\` existed,
52
+ assuming the mDNS name had been claimed — which setup cannot see, and which
53
+ fails when mDNS is off or the name is already taken on the network. The summary
54
+ now shows only addresses it verified.
55
+
7
56
  ## August 9, 2026 - The browser tool goes, and macOS installs work in a plain shell (v0.1.321)
8
57
 
9
58
  - **The cloud-browser login profiles are gone.** They did not work reliably
@@ -1,7 +1,7 @@
1
1
  import { jsx as e, jsxs as i, Fragment as te } from "react/jsx-runtime";
2
- import { memo as ne, useState as m, useRef as T, useCallback as v, useEffect as C, useMemo as _, Suspense as I } from "react";
2
+ import { memo as ne, useState as m, useRef as T, useCallback as v, useEffect as C, useMemo as q, Suspense as I } from "react";
3
3
  import { createPortal as re } from "react-dom";
4
- import { F as oe, H, I as se, X as U, J as ie, K as ae, f as y, L as J, N as le, q as de, C as ce, O as L } from "./embedded-Bk0VM5g-.js";
4
+ import { z as oe, E as H, F as se, X as U, H as ie, I as ae, f as y, L as J, J as le, m as de, y as ce, N as L } from "./embedded-BgLSMF4E.js";
5
5
  import { c as me } from "./create-BrnHvSDE.js";
6
6
  /**
7
7
  * @license lucide-react v0.577.0 - ISC
@@ -31,7 +31,7 @@ function xe(n, s, o) {
31
31
  `);
32
32
  }
33
33
  const ge = L("session-file-tree", () => import("./FileTreePane-BG2k7gTc.js")), be = L("session-file-viewer", () => import("./FileViewer-DgjR_OJp.js")), ve = L("session-file-editor", () => import("./FileEditor-ByMnm-sa.js"));
34
- async function q(n) {
34
+ async function _(n) {
35
35
  const s = await H(n), o = await s.json().catch(() => ({}));
36
36
  if (!s.ok) throw new Error((o == null ? void 0 : o.error) || `${s.status}`);
37
37
  return o;
@@ -49,7 +49,7 @@ const N = ({ label: n }) => /* @__PURE__ */ i("div", { className: "flex items-ce
49
49
  n
50
50
  ] });
51
51
  function ke({ tree: n, onNavigate: s }) {
52
- const o = T(null), c = _(() => {
52
+ const o = T(null), c = q(() => {
53
53
  const t = n.root.split("/").filter(Boolean);
54
54
  return t.map((h, k) => {
55
55
  const x = "/" + t.slice(0, k + 1).join("/");
@@ -80,14 +80,14 @@ function ke({ tree: n, onNavigate: s }) {
80
80
  );
81
81
  }
82
82
  function we({ sid: n, onClose: s }) {
83
- const [o, c] = m(null), [t, h] = m(null), [k, x] = m(null), [g, j] = m(null), [a, S] = m(null), [R, $] = m(null), [W, P] = m(!1), [u, w] = m(!1), [z, O] = m(""), [p, f] = m({ kind: "idle" }), [K, F] = m("tree"), A = ye(), b = T(null), V = v((r) => {
83
+ const [o, c] = m(null), [t, h] = m(null), [k, x] = m(null), [g, j] = m(null), [a, z] = m(null), [R, $] = m(null), [W, P] = m(!1), [u, w] = m(!1), [S, A] = m(""), [p, f] = m({ kind: "idle" }), [V, E] = m("tree"), M = ye(), b = T(null), X = v((r) => {
84
84
  b.current = r;
85
- }, []), E = T(null);
85
+ }, []), F = T(null);
86
86
  C(() => {
87
87
  let r = !0;
88
88
  h(null), x(null);
89
89
  const d = o ? `?root=${encodeURIComponent(o)}` : "";
90
- return q(`/api/sessions/${n}/tree${d}`).then((l) => r && h(l.tree)).catch((l) => r && x(l instanceof Error ? l.message : String(l))), () => {
90
+ return _(`/api/sessions/${n}/tree${d}`).then((l) => r && h(l.tree)).catch((l) => r && x(l instanceof Error ? l.message : String(l))), () => {
91
91
  r = !1;
92
92
  };
93
93
  }, [n, o]), C(() => {
@@ -98,18 +98,18 @@ function we({ sid: n, onClose: s }) {
98
98
  window.removeEventListener("keydown", r), document.body.style.overflow = d;
99
99
  };
100
100
  }, [s]);
101
- const X = v(
101
+ const D = v(
102
102
  (r) => {
103
- t && (F("file"), r !== E.current && (E.current = r, j(r), w(!1), f({ kind: "idle" }), O(""), b.current = null, S(null), $(null), P(!0), q(
103
+ t && (E("file"), r !== F.current && (F.current = r, j(r), w(!1), f({ kind: "idle" }), A(""), b.current = null, z(null), $(null), P(!0), _(
104
104
  `/api/sessions/${n}/file?path=${encodeURIComponent(`${t.root}/${r}`)}`
105
105
  ).then((d) => {
106
- S(d.file), b.current = d.file.contents;
106
+ z(d.file), b.current = d.file.contents;
107
107
  }).catch((d) => $(d instanceof Error ? d.message : String(d))).finally(() => P(!1))));
108
108
  },
109
109
  [n, t]
110
- ), M = v((r) => {
111
- c(r), E.current = null, j(null), S(null), w(!1), F("tree");
112
- }, []), D = v(() => F("tree"), []), Y = _(
110
+ ), O = v((r) => {
111
+ c(r), F.current = null, j(null), z(null), w(!1), E("tree");
112
+ }, []), K = v(() => E("tree"), []), Y = q(
113
113
  () => a ? { ...a, contents: b.current ?? a.contents } : null,
114
114
  // eslint-disable-next-line react-hooks/exhaustive-deps -- `editing` is the
115
115
  // intended trigger; draftRef is a ref and deliberately not reactive.
@@ -120,7 +120,7 @@ function we({ sid: n, onClose: s }) {
120
120
  displayPath: r,
121
121
  original: a.contents,
122
122
  edited: b.current,
123
- note: z
123
+ note: S
124
124
  });
125
125
  if (!d.ok) {
126
126
  f({
@@ -149,7 +149,7 @@ function we({ sid: n, onClose: s }) {
149
149
  } catch (l) {
150
150
  f({ kind: "error", message: l instanceof Error ? l.message : String(l) });
151
151
  }
152
- }, [n, a, g, z]), Q = !!g && K === "file", B = p.kind === "sent" || p.kind === "error" ? "banner" : u ? "editor" : "content", Z = /* @__PURE__ */ e(
152
+ }, [n, a, g, S]), Q = !!g && V === "file", B = p.kind === "sent" || p.kind === "error" ? "banner" : u ? "editor" : "content", Z = /* @__PURE__ */ e(
153
153
  "div",
154
154
  {
155
155
  role: "dialog",
@@ -171,13 +171,13 @@ function we({ sid: n, onClose: s }) {
171
171
  /* @__PURE__ */ e(se, { className: "size-4 shrink-0 text-[var(--primary)]" }),
172
172
  /* @__PURE__ */ i("div", { className: "min-w-0 flex-1", children: [
173
173
  /* @__PURE__ */ e("div", { className: "text-sm font-semibold text-foreground", children: "Files" }),
174
- t ? /* @__PURE__ */ e(ke, { tree: t, onNavigate: M }) : null
174
+ t ? /* @__PURE__ */ e(ke, { tree: t, onNavigate: O }) : null
175
175
  ] }),
176
176
  t != null && t.parent ? /* @__PURE__ */ i(
177
177
  "button",
178
178
  {
179
179
  type: "button",
180
- onClick: () => M(t.parent),
180
+ onClick: () => O(t.parent),
181
181
  className: "flex min-h-9 shrink-0 items-center gap-1.5 rounded-lg border border-border px-2.5 text-[12px] text-muted-foreground transition-colors hover:bg-muted hover:text-foreground md:min-h-0 md:px-2 md:py-1 md:text-[11px]",
182
182
  children: [
183
183
  /* @__PURE__ */ e(pe, { className: "size-3.5 md:size-3" }),
@@ -208,7 +208,7 @@ function we({ sid: n, onClose: s }) {
208
208
  paths: t.paths,
209
209
  gitStatus: t.gitStatus,
210
210
  selectedPath: g,
211
- onSelectFile: X
211
+ onSelectFile: D
212
212
  }
213
213
  ) }) : /* @__PURE__ */ e(N, { label: "Listing files…" }) })
214
214
  ] }),
@@ -225,7 +225,7 @@ function we({ sid: n, onClose: s }) {
225
225
  "button",
226
226
  {
227
227
  type: "button",
228
- onClick: D,
228
+ onClick: K,
229
229
  "aria-label": "Back to file tree",
230
230
  className: "flex size-9 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-muted hover:text-foreground md:hidden",
231
231
  children: /* @__PURE__ */ e(ie, { className: "size-5" })
@@ -272,7 +272,7 @@ function we({ sid: n, onClose: s }) {
272
272
  R ? /* @__PURE__ */ i("div", { className: "px-3 py-2 text-[12px] text-[var(--destructive)]", children: [
273
273
  "Could not open: ",
274
274
  R
275
- ] }) : W || !a ? /* @__PURE__ */ e(N, { label: "Opening…" }) : a.binary ? /* @__PURE__ */ e("div", { className: "px-3 py-3 text-[12px] text-muted-foreground", children: "Binary file — not shown." }) : /* @__PURE__ */ e(I, { fallback: /* @__PURE__ */ e(N, { label: u ? "Loading editor…" : "Rendering…" }), children: u ? /* @__PURE__ */ e(ve, { file: Y ?? a, themeType: A, onChange: V }) : /* @__PURE__ */ e(be, { file: a, themeType: A }) }),
275
+ ] }) : W || !a ? /* @__PURE__ */ e(N, { label: "Opening…" }) : a.binary ? /* @__PURE__ */ e("div", { className: "px-3 py-3 text-[12px] text-muted-foreground", children: "Binary file — not shown." }) : /* @__PURE__ */ e(I, { fallback: /* @__PURE__ */ e(N, { label: u ? "Loading editor…" : "Rendering…" }), children: u ? /* @__PURE__ */ e(ve, { file: Y ?? a, themeType: M, onChange: X }) : /* @__PURE__ */ e(be, { file: a, themeType: M }) }),
276
276
  a != null && a.truncated ? /* @__PURE__ */ e("div", { className: "px-3 py-1.5 text-[11px] text-[var(--warning)]", children: "File truncated — only the first megabyte is shown." }) : null
277
277
  ]
278
278
  }
@@ -288,8 +288,8 @@ function we({ sid: n, onClose: s }) {
288
288
  /* @__PURE__ */ e(
289
289
  "textarea",
290
290
  {
291
- value: z,
292
- onChange: (r) => O(r.target.value),
291
+ value: S,
292
+ onChange: (r) => A(r.target.value),
293
293
  rows: 2,
294
294
  placeholder: "Optional: anything else the agent should do alongside this edit",
295
295
  className: "w-full resize-none rounded-lg border border-border bg-card px-2.5 py-2 text-[12px] text-foreground outline-none placeholder:text-muted-foreground focus:border-[var(--primary)]/50"
@@ -1,6 +1,6 @@
1
1
  import { jsxs as r, jsx as k, Fragment as vA } from "react/jsx-runtime";
2
2
  import { useState as L, useRef as S, useEffect as x, useCallback as Y } from "react";
3
- import { F as cA, p as wQ, X as DA, a9 as sQ, q as tQ, aa as eQ, ab as aQ, H as MQ, ac as hQ, R as NQ, C as cQ } from "./embedded-Bk0VM5g-.js";
3
+ import { z as cA, S as wQ, X as DA, a8 as sQ, m as tQ, a9 as eQ, aa as aQ, E as MQ, ab as hQ, R as NQ, y as cQ } from "./embedded-BgLSMF4E.js";
4
4
  /**
5
5
  * @license lucide-react v0.577.0 - ISC
6
6
  *
@@ -1,7 +1,7 @@
1
1
  import { jsx as ao } from "react/jsx-runtime";
2
2
  import { useRef as Dt, useCallback as Lt, useSyncExternalStore as ut, useEffect as so } from "react";
3
3
  import { g as io } from "./_commonjsHelpers-C6fGbg64.js";
4
- import { ad as uo } from "./embedded-Bk0VM5g-.js";
4
+ import { ac as uo } from "./embedded-BgLSMF4E.js";
5
5
  var Ar = "vercel.ai.error", co = Symbol.for(Ar), Ut, Ft, se = class Nr extends (Ft = Error, Ut = co, Ft) {
6
6
  /**
7
7
  * Creates an AI SDK Error.
@@ -0,0 +1,287 @@
1
+ import { jsxs as t, jsx as e, Fragment as G } from "react/jsx-runtime";
2
+ import { R as K, f as L, B as d, L as C, P as z, S as w, g as R, h as p, T, i as m, j as F, k as M, l as $, C as _, m as q, X as H, K as U } from "./embedded-BgLSMF4E.js";
3
+ import { useState as S } from "react";
4
+ function j(l) {
5
+ const i = l.filter((r) => !r.ok);
6
+ return i.length ? i.length === 1 ? `${i[0].label} missing` : `${i.length} checks failing` : null;
7
+ }
8
+ function A({ checks: l }) {
9
+ return /* @__PURE__ */ e("div", { className: "space-y-1", children: l.map((i) => /* @__PURE__ */ t(
10
+ "div",
11
+ {
12
+ className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground",
13
+ children: [
14
+ i.ok ? /* @__PURE__ */ e(q, { className: "size-3.5 shrink-0 text-success" }) : /* @__PURE__ */ e(H, { className: "size-3.5 shrink-0 text-destructive" }),
15
+ /* @__PURE__ */ e("span", { className: "shrink-0", children: i.label }),
16
+ i.detail ? /* @__PURE__ */ e("span", { className: "min-w-0 truncate text-muted-foreground/70", children: i.detail }) : null
17
+ ]
18
+ },
19
+ i.label
20
+ )) });
21
+ }
22
+ function I({
23
+ icon: l,
24
+ title: i,
25
+ note: r,
26
+ ok: u,
27
+ control: o,
28
+ open: c,
29
+ onToggle: h,
30
+ children: f
31
+ }) {
32
+ return /* @__PURE__ */ t("div", { className: "px-4 py-2.5", children: [
33
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-3", children: [
34
+ /* @__PURE__ */ t(
35
+ "button",
36
+ {
37
+ type: "button",
38
+ onClick: h,
39
+ "aria-expanded": c,
40
+ className: "flex min-w-0 flex-1 items-center gap-3 text-left",
41
+ children: [
42
+ /* @__PURE__ */ e("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-[8px] border border-border bg-background", children: l }),
43
+ /* @__PURE__ */ t("span", { className: "min-w-0 flex-1", children: [
44
+ /* @__PURE__ */ t("span", { className: "flex items-center gap-2", children: [
45
+ /* @__PURE__ */ e("span", { className: "truncate text-sm font-medium", children: i }),
46
+ u ? null : /* @__PURE__ */ e("span", { className: "size-1.5 shrink-0 rounded-full bg-destructive", "aria-hidden": !0 })
47
+ ] }),
48
+ r ? /* @__PURE__ */ e("span", { className: "block truncate text-xs text-muted-foreground", children: r }) : null
49
+ ] }),
50
+ /* @__PURE__ */ e(
51
+ _,
52
+ {
53
+ className: L(
54
+ "size-4 shrink-0 text-muted-foreground/60 transition-transform duration-150",
55
+ c && "rotate-180"
56
+ )
57
+ }
58
+ )
59
+ ]
60
+ }
61
+ ),
62
+ o
63
+ ] }),
64
+ c ? /* @__PURE__ */ e("div", { className: "mt-3 space-y-3 pl-11", children: f }) : null
65
+ ] });
66
+ }
67
+ function W({
68
+ provider: l,
69
+ onConnect: i,
70
+ onDisconnect: r
71
+ }) {
72
+ return /* @__PURE__ */ t("div", { className: "flex items-center gap-2 rounded-xl border border-border/70 bg-background/55 px-2.5 py-2", children: [
73
+ /* @__PURE__ */ t("span", { className: "min-w-0 flex-1", children: [
74
+ /* @__PURE__ */ e("span", { className: "block truncate text-xs font-medium", children: l.label }),
75
+ l.fromEnv ? /* @__PURE__ */ e("span", { className: "block truncate text-[11px] text-muted-foreground", children: "From the environment" }) : null
76
+ ] }),
77
+ l.connected ? /* @__PURE__ */ t(G, { children: [
78
+ /* @__PURE__ */ e("span", { className: "text-[11px] text-success", children: "Connected" }),
79
+ l.fromEnv ? null : /* @__PURE__ */ e(
80
+ "button",
81
+ {
82
+ type: "button",
83
+ onClick: () => r(l),
84
+ title: `Disconnect ${l.label}`,
85
+ "aria-label": `Disconnect ${l.label}`,
86
+ className: "flex size-7 items-center justify-center rounded-full text-muted-foreground transition hover:bg-destructive/10 hover:text-destructive",
87
+ children: /* @__PURE__ */ e(T, { className: "size-3.5" })
88
+ }
89
+ )
90
+ ] }) : /* @__PURE__ */ t(d, { size: "sm", variant: "outline", onClick: () => i(l), children: [
91
+ l.method === "oauth" ? /* @__PURE__ */ e(p, { className: "size-3.5" }) : /* @__PURE__ */ e(U, { className: "size-3.5" }),
92
+ "Connect"
93
+ ] })
94
+ ] });
95
+ }
96
+ function V({
97
+ setupChecks: l,
98
+ agents: i,
99
+ onVisibleChange: r,
100
+ onSetup: u,
101
+ onLogin: o,
102
+ onAddClaudeAccount: c,
103
+ onRemoveClaudeAccount: h,
104
+ onConnectPiProvider: f,
105
+ onDisconnectPiProvider: E,
106
+ onSetupCheck: D,
107
+ onRefresh: P
108
+ }) {
109
+ const [x, g] = S(!1), [N, O] = S(null), k = (n) => O((s) => s === n ? null : n);
110
+ async function B() {
111
+ if (!x) {
112
+ g(!0);
113
+ try {
114
+ await P(), $.success("Coding agents refreshed");
115
+ } catch (n) {
116
+ $.error(n instanceof Error ? n.message : "Could not refresh coding agents");
117
+ } finally {
118
+ g(!1);
119
+ }
120
+ }
121
+ }
122
+ return /* @__PURE__ */ t("div", { className: "mx-auto max-w-xl space-y-3 pb-10", "data-lfg-page-column": !0, children: [
123
+ /* @__PURE__ */ t("div", { className: "flex items-center justify-between px-4", children: [
124
+ /* @__PURE__ */ e("h2", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: "Coding agents" }),
125
+ /* @__PURE__ */ t(
126
+ "button",
127
+ {
128
+ type: "button",
129
+ onClick: () => void B(),
130
+ disabled: x,
131
+ className: "flex items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50",
132
+ children: [
133
+ /* @__PURE__ */ e(K, { className: L("size-3.5", x && "animate-spin") }),
134
+ "Refresh"
135
+ ]
136
+ }
137
+ )
138
+ ] }),
139
+ l.length ? /* @__PURE__ */ e("div", { className: "overflow-hidden rounded-2xl border border-border bg-card/40 divide-y divide-border", children: l.map((n) => /* @__PURE__ */ t(
140
+ I,
141
+ {
142
+ icon: /* @__PURE__ */ e(w, { className: "size-4 text-muted-foreground" }),
143
+ title: n.label,
144
+ note: j(n.checks),
145
+ ok: n.configured,
146
+ open: N === `setup:${n.key}`,
147
+ onToggle: () => k(`setup:${n.key}`),
148
+ children: [
149
+ /* @__PURE__ */ e(A, { checks: n.checks }),
150
+ n.instructions.map((s) => /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: s }, s)),
151
+ /* @__PURE__ */ t(
152
+ d,
153
+ {
154
+ size: "sm",
155
+ variant: "outline",
156
+ disabled: !n.canAutoSetup || n.running,
157
+ onClick: () => D(n.key),
158
+ title: n.canAutoSetup ? n.actionLabel : "Install a supported coding agent first",
159
+ children: [
160
+ n.running ? /* @__PURE__ */ e(C, { className: "size-4 animate-spin" }) : /* @__PURE__ */ e(z, { className: "size-4" }),
161
+ n.running ? "Running…" : n.actionLabel
162
+ ]
163
+ }
164
+ )
165
+ ]
166
+ },
167
+ n.key
168
+ )) }) : null,
169
+ /* @__PURE__ */ e("div", { className: "overflow-hidden rounded-2xl border border-border bg-card/40 divide-y divide-border", children: i.map((n) => {
170
+ const s = n.status, b = n.key === "aisdk" ? s.accounts ?? [] : [], y = s.providers ?? [], v = b.some((a) => a.connected);
171
+ return /* @__PURE__ */ t(
172
+ I,
173
+ {
174
+ icon: /* @__PURE__ */ e("img", { src: R(n.key), alt: M(n.key), className: "size-5" }),
175
+ title: n.label,
176
+ note: j(s.checks),
177
+ ok: s.configured,
178
+ open: N === `agent:${n.key}`,
179
+ onToggle: () => k(`agent:${n.key}`),
180
+ control: /* @__PURE__ */ e(
181
+ F,
182
+ {
183
+ checked: n.visible,
184
+ onCheckedChange: (a) => r(n.key, a),
185
+ "aria-label": `${n.label} visible in composer`
186
+ }
187
+ ),
188
+ children: [
189
+ /* @__PURE__ */ e(A, { checks: s.checks }),
190
+ b.length ? /* @__PURE__ */ e("div", { className: "space-y-1.5", children: b.map((a) => /* @__PURE__ */ t(
191
+ "div",
192
+ {
193
+ className: "flex items-center gap-2 rounded-xl border border-border/70 bg-background/55 px-2.5 py-2",
194
+ children: [
195
+ /* @__PURE__ */ t("span", { className: "relative flex size-7 shrink-0 items-center justify-center rounded-full bg-muted", children: [
196
+ /* @__PURE__ */ e("img", { src: R("aisdk"), alt: "", className: "size-4.5" }),
197
+ /* @__PURE__ */ e("span", { className: "absolute -bottom-0.5 -right-0.5 flex size-3.5 items-center justify-center rounded-full bg-foreground text-[8px] font-bold text-background ring-1 ring-background", children: a.number })
198
+ ] }),
199
+ /* @__PURE__ */ e("span", { className: "min-w-0 flex-1 truncate text-xs font-medium", children: a.label }),
200
+ a.connected ? /* @__PURE__ */ e("span", { className: "text-[11px] text-success", children: "Connected" }) : /* @__PURE__ */ t(
201
+ d,
202
+ {
203
+ size: "sm",
204
+ variant: "outline",
205
+ onClick: () => o(n.key, a.id),
206
+ children: [
207
+ /* @__PURE__ */ e(p, { className: "size-3.5" }),
208
+ "Connect"
209
+ ]
210
+ }
211
+ ),
212
+ a.removable ? /* @__PURE__ */ e(
213
+ "button",
214
+ {
215
+ type: "button",
216
+ onClick: () => h(a),
217
+ title: `Remove ${a.label}`,
218
+ "aria-label": `Remove ${a.label}`,
219
+ className: "flex size-7 items-center justify-center rounded-full text-muted-foreground transition hover:bg-destructive/10 hover:text-destructive",
220
+ children: /* @__PURE__ */ e(T, { className: "size-3.5" })
221
+ }
222
+ ) : null
223
+ ]
224
+ },
225
+ a.id
226
+ )) }) : null,
227
+ y.length ? /* @__PURE__ */ e("div", { className: "space-y-1.5", children: y.map((a) => /* @__PURE__ */ e(
228
+ W,
229
+ {
230
+ provider: a,
231
+ onConnect: f,
232
+ onDisconnect: E
233
+ },
234
+ a.id
235
+ )) }) : null,
236
+ s.instructions.map((a) => /* @__PURE__ */ e("p", { className: "text-xs text-muted-foreground", children: a }, a)),
237
+ !s.configured && (s.installCommand || s.loginCommand && !m.has(n.key)) ? /* @__PURE__ */ t("div", { className: "space-y-1 text-xs text-muted-foreground", children: [
238
+ s.installCommand ? /* @__PURE__ */ t("div", { className: "truncate", children: [
239
+ "Install: ",
240
+ /* @__PURE__ */ e("code", { children: s.installCommand })
241
+ ] }) : null,
242
+ s.loginCommand && !m.has(n.key) ? /* @__PURE__ */ t("div", { className: "truncate", children: [
243
+ "Login: ",
244
+ /* @__PURE__ */ e("code", { children: s.loginCommand })
245
+ ] }) : null
246
+ ] }) : null,
247
+ /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center gap-2", children: [
248
+ s.canAutoSetup ? /* @__PURE__ */ t(
249
+ d,
250
+ {
251
+ size: "sm",
252
+ variant: "outline",
253
+ disabled: s.setupRunning,
254
+ onClick: () => u(n.key),
255
+ title: "Run setup for this agent",
256
+ children: [
257
+ s.setupRunning ? /* @__PURE__ */ e(C, { className: "size-4 animate-spin" }) : /* @__PURE__ */ e(z, { className: "size-4" }),
258
+ s.setupRunning ? "Running…" : "Install"
259
+ ]
260
+ }
261
+ ) : null,
262
+ s.canLoginInTerminal ? /* @__PURE__ */ t(
263
+ d,
264
+ {
265
+ size: "sm",
266
+ variant: "outline",
267
+ disabled: s.setupRunning,
268
+ onClick: () => n.key === "aisdk" && v ? c() : o(n.key),
269
+ title: m.has(n.key) ? `Sign in to ${n.label} in your browser` : `Open terminal and run ${s.loginCommand}`,
270
+ children: [
271
+ m.has(n.key) ? /* @__PURE__ */ e(p, { className: "size-4" }) : /* @__PURE__ */ e(w, { className: "size-4" }),
272
+ n.key === "aisdk" && v ? "Add account" : "Login"
273
+ ]
274
+ }
275
+ ) : null,
276
+ /* @__PURE__ */ e("span", { className: "text-[11px] text-muted-foreground/70", children: s.omgCapabilityAccess === "mcp" ? "OMG tools" : "OMG prompt only" })
277
+ ] })
278
+ ]
279
+ },
280
+ n.key
281
+ );
282
+ }) })
283
+ ] });
284
+ }
285
+ export {
286
+ V as default
287
+ };