@habemus-papadum/aiui 0.5.0 → 0.6.0

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.
package/dist/cli.js CHANGED
@@ -1,26 +1,151 @@
1
1
  #!/usr/bin/env node
2
- import { Command as wt } from "commander";
3
- import { join as d, resolve as C, delimiter as gt, dirname as bt } from "node:path";
4
- import { cacheDir as F, packageRoot as V, runningFromSource as yt, isCi as ie, discoverSessionBrowser as U, openInSessionBrowser as R, sessionBrowserBinary as Oe, launchSessionBrowser as je, decideBrowserAction as vt } from "@habemus-papadum/aiui-util";
5
- import { execa as T } from "execa";
6
- import { existsSync as v, mkdirSync as G, writeFileSync as K, readFileSync as L, realpathSync as $t, readdirSync as Y, chmodSync as Ct, accessSync as kt, constants as xt, rmSync as Tt, lstatSync as It } from "node:fs";
7
- import { detectBrowserPlatform as Ne, resolveBuildId as Ue, Browser as E, getInstalledBrowsers as Le, install as Et, uninstall as Pt } from "@puppeteer/browsers";
8
- import { u as _, l as S, C as ve, m as Dt, d as ee, p as te, c as St, r as ne, a as Me, f as k, b as Re, e as At } from "./config-Cis6kCik.js";
9
- import { createInterface as _t } from "node:readline/promises";
10
- import u from "chalk";
11
- import { projectCacheDir as Be, listMcpServers as M, selectMcpServer as He, agentsByPid as Fe, listClaudeAgents as Ve } from "@habemus-papadum/aiui-claude-channel";
12
- import { homedir as se, networkInterfaces as Ge } from "node:os";
13
- import { spawn as Ot } from "node:child_process";
14
- import { Separator as oe, select as O, input as jt } from "@inquirer/prompts";
15
- async function W(e, t, n) {
16
- const o = _t({ input: process.stdin, output: process.stderr });
2
+ import { Command as yt } from "commander";
3
+ import { join as h, resolve as x, dirname as Oe, delimiter as vt } from "node:path";
4
+ import { packageRoot as K, runningFromSource as $t, isCi as ce, cacheDir as Y, discoverSessionBrowser as U, openInSessionBrowser as H, sessionBrowserBinary as Ue, launchSessionBrowser as Me, decideBrowserAction as kt } from "@habemus-papadum/aiui-util";
5
+ import { execa as E } from "execa";
6
+ import { readFileSync as M, existsSync as v, writeFileSync as W, realpathSync as Ct, mkdirSync as z, readdirSync as q, chmodSync as xt, accessSync as It, constants as Et, rmSync as Pt, lstatSync as Dt } from "node:fs";
7
+ import { projectCacheDir as Le, listMcpServers as L, selectMcpServer as Be, agentsByPid as Re, listClaudeAgents as He } from "@habemus-papadum/aiui-claude-channel";
8
+ import { r as B, D as St, M as Fe, u as N, l as P, a as le, C as $e, m as Tt, d as oe, p as re, c as At, b as ie, e as Ve, f as I, g as Ge, h as Nt } from "./config-xLcoLiLT.js";
9
+ import l from "chalk";
10
+ import { detectBrowserPlatform as Ke, resolveBuildId as Ye, Browser as ke, getInstalledBrowsers as We, install as _t, uninstall as jt } from "@puppeteer/browsers";
11
+ import { createInterface as Ot } from "node:readline/promises";
12
+ import { homedir as ue, networkInterfaces as ze } from "node:os";
13
+ import { Separator as se, select as _, input as Ut } from "@inquirer/prompts";
14
+ function J(e, t) {
15
+ const n = K(e), o = JSON.parse(M(h(n, "package.json"), "utf8")), r = typeof o.bin == "string" ? o.bin : Mt(o.bin);
16
+ if (!r)
17
+ throw new Error(
18
+ `package ${e} declares no bin`
19
+ );
20
+ if ($t(n)) {
21
+ const i = r.replace(/^\.?\/?dist\//, "src/").replace(/\.js$/, ".ts");
22
+ return { command: process.execPath, args: ["--import", "tsx", x(n, i)] };
23
+ }
24
+ return { command: process.execPath, args: [x(n, r)] };
25
+ }
26
+ function Mt(e) {
27
+ return e ? Object.values(e)[0] : void 0;
28
+ }
29
+ function y(e, t) {
30
+ console.error(`${l.bgRed.white.bold(" ERROR ")} ${l.red.bold(e)}`), t && console.error(l.dim(t));
31
+ }
32
+ function C(e, t) {
33
+ console.error(`${l.bgYellow.black.bold(" WARN ")} ${l.yellow.bold(e)}`), t && console.error(l.dim(t));
34
+ }
35
+ function g(e, t) {
36
+ console.error(`${l.bgCyan.black.bold(" NOTE ")} ${l.cyan(e)}`), t && console.error(l.dim(t));
37
+ }
38
+ const Lt = "chrome-devtools", Bt = "@habemus-papadum/aiui-intent-client", Rt = "default", Ht = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
39
+ function qe(e, t = {}, n = process.env) {
40
+ return e.noChrome ? !1 : e.chrome ? !0 : t.enabled === !1 ? !1 : !ce(n);
41
+ }
42
+ function T(e, t = {}, n = process.cwd()) {
43
+ if (t.executablePath && t.channel)
44
+ throw new Error(
45
+ "config sets both chrome.executablePath and chrome.channel — they pick the browser two different ways; keep exactly one"
46
+ );
47
+ const o = e.chromeProfile !== void 0 || e.chromeDataDir !== void 0, r = e.chromeDataDir ?? (o ? void 0 : t.dataDir), i = e.chromeProfile ?? (o ? void 0 : t.profile), s = Ft(t);
48
+ return {
49
+ userDataDir: Gt({ dataDir: r, profile: i, variant: s }, n),
50
+ variant: s,
51
+ // A configured endpoint means the browser is managed elsewhere (usually
52
+ // another machine) — that's always attach, whatever `mode` says.
53
+ mode: t.browserUrl ? "attach" : t.mode ?? "attach",
54
+ browserUrl: t.browserUrl,
55
+ debugPort: t.debugPort ?? 0,
56
+ executablePath: t.executablePath && x(n, t.executablePath),
57
+ channel: t.channel,
58
+ headless: t.headless ?? !1
59
+ };
60
+ }
61
+ function Ft(e) {
62
+ return e.channel ? `chrome-${e.channel}` : e.executablePath ? `custom-${Vt(e.executablePath)}` : B(e);
63
+ }
64
+ function Vt(e) {
65
+ let t = 5381;
66
+ for (let n = 0; n < e.length; n++)
67
+ t = (t * 33 ^ e.charCodeAt(n)) >>> 0;
68
+ return t.toString(36);
69
+ }
70
+ function Gt(e, t = process.cwd()) {
71
+ if (e.dataDir)
72
+ return x(t, e.dataDir);
73
+ const n = e.profile ?? Rt;
74
+ if (!Ht.test(n))
75
+ throw new Error(
76
+ `invalid chrome profile name "${n}" — use letters, digits, ".", "_", "-" (or --aiui-chrome-data-dir for an arbitrary path)`
77
+ );
78
+ const o = e.variant ?? St;
79
+ return h(Le(t), "chrome", o, n);
80
+ }
81
+ const Kt = "dist-ext";
82
+ function Yt() {
83
+ try {
84
+ const e = Ct(K(Bt));
85
+ return { root: e, outDir: h(e, Kt) };
86
+ } catch {
87
+ return;
88
+ }
89
+ }
90
+ function Wt(e) {
91
+ return e === void 0 ? { state: "absent" } : v(h(e.outDir, "manifest.json")) ? { state: "ready", dir: e.outDir } : { state: "unbuilt", root: e.root };
92
+ }
93
+ function j() {
94
+ return Wt(Yt());
95
+ }
96
+ function Je(e) {
97
+ e.state === "unbuilt" && g(
98
+ "the aiui intent client has no MV3 bundle yet, so this launch won't load it",
99
+ `Build it once: pnpm -C packages/aiui-intent-client build:ext
100
+ then relaunch — or load it into the RUNNING browser:
101
+ pnpm -C packages/aiui-intent-client ext`
102
+ );
103
+ }
104
+ function Xe(e, t) {
105
+ if (!t.length || e.executablePath)
106
+ return;
107
+ const n = h(e.userDataDir, "aiui-extension-autoload-hint");
108
+ if (!v(n)) {
109
+ g(
110
+ "the aiui intent client can't auto-load into regular Chrome (≥ 137 ignores --load-extension)",
111
+ `Load it once in the launched Chrome — chrome://extensions → Developer mode → Load unpacked →
112
+ ${t.join(`
113
+ `)}
114
+ — and this profile remembers it. Or use the managed browser (\`aiui chrome install\`),
115
+ which auto-loads it. This note won't repeat for this profile.`
116
+ );
117
+ try {
118
+ W(n, `${(/* @__PURE__ */ new Date()).toISOString()}
119
+ `);
120
+ } catch {
121
+ }
122
+ }
123
+ }
124
+ function te(e) {
125
+ return {
126
+ command: "npx",
127
+ args: ["-y", "chrome-devtools-mcp@latest", "--browser-url", e]
128
+ };
129
+ }
130
+ function zt(e, t = []) {
131
+ const n = [
132
+ "-y",
133
+ "chrome-devtools-mcp@latest",
134
+ "--userDataDir",
135
+ e.userDataDir,
136
+ "--ignoreDefaultChromeArg=--disable-extensions"
137
+ ];
138
+ return e.executablePath && n.push("--executablePath", e.executablePath), e.channel && n.push("--channel", e.channel), e.headless && n.push("--headless"), t.length && n.push(`--chromeArg=--load-extension=${t.join(",")}`), { command: "npx", args: n };
139
+ }
140
+ async function X(e, t, n) {
141
+ const o = Ot({ input: process.stdin, output: process.stderr });
17
142
  try {
18
143
  const r = t.map(
19
- (i) => ` ${u.bold(`[${i.key === n ? i.key.toUpperCase() : i.key}]`)} ${i.label}`
144
+ (i) => ` ${l.bold(`[${i.key === n ? i.key.toUpperCase() : i.key}]`)} ${i.label}`
20
145
  ).join(`
21
146
  `);
22
147
  for (; ; ) {
23
- const s = (await o.question(`${u.cyan(e)}
148
+ const s = (await o.question(`${l.cyan(e)}
24
149
  ${r}
25
150
  > `)).trim().toLowerCase();
26
151
  if (!s) {
@@ -36,33 +161,52 @@ ${r}
36
161
  o.close();
37
162
  }
38
163
  }
39
- function b(e, t) {
40
- console.error(`${u.bgRed.white.bold(" ERROR ")} ${u.red.bold(e)}`), t && console.error(u.dim(t));
41
- }
42
- function $(e, t) {
43
- console.error(`${u.bgYellow.black.bold(" WARN ")} ${u.yellow.bold(e)}`), t && console.error(u.dim(t));
44
- }
45
- function w(e, t) {
46
- console.error(`${u.bgCyan.black.bold(" NOTE ")} ${u.cyan(e)}`), t && console.error(u.dim(t));
47
- }
48
- const Ke = 1440 * 60 * 1e3, Nt = 4e3;
49
- function A(e = !0) {
50
- return F("chrome", { create: e });
51
- }
52
- const Ye = "update-state.json";
53
- function q() {
164
+ const Ze = 1440 * 60 * 1e3, qt = 4e3, Jt = {
165
+ chromium: {
166
+ flavor: "chromium",
167
+ browser: ke.CHROMIUM,
168
+ latestTag: "latest",
169
+ displayName: "Chromium",
170
+ cacheSubdir: "chromium",
171
+ approxSizeMb: 150
172
+ },
173
+ "chrome-for-testing": {
174
+ flavor: "chrome-for-testing",
175
+ browser: ke.CHROME,
176
+ latestTag: "stable",
177
+ displayName: "Chrome for Testing",
178
+ cacheSubdir: "chrome",
179
+ approxSizeMb: 160
180
+ }
181
+ };
182
+ function k(e) {
183
+ return Jt[e];
184
+ }
185
+ function A(e, t = !0) {
186
+ return Y(k(e).cacheSubdir, { create: t });
187
+ }
188
+ function Xt(e = !1) {
189
+ return Fe.map((t) => A(t, e));
190
+ }
191
+ const Qe = "update-state.json";
192
+ function Z(e) {
54
193
  try {
55
- return JSON.parse(L(d(A(!1), Ye), "utf8"));
194
+ return JSON.parse(
195
+ M(h(A(e, !1), Qe), "utf8")
196
+ );
56
197
  } catch {
57
198
  return {};
58
199
  }
59
200
  }
60
- function z(e) {
61
- const t = A();
62
- G(t, { recursive: !0 }), K(d(t, Ye), `${JSON.stringify({ ...q(), ...e })}
63
- `);
201
+ function Q(e, t) {
202
+ const n = A(e);
203
+ z(n, { recursive: !0 }), W(
204
+ h(n, Qe),
205
+ `${JSON.stringify({ ...Z(e), ...t })}
206
+ `
207
+ );
64
208
  }
65
- function ae(e, t) {
209
+ function de(e, t) {
66
210
  const n = e.split(".").map(Number), o = t.split(".").map(Number);
67
211
  for (let r = 0; r < Math.max(n.length, o.length); r++) {
68
212
  const i = (n[r] ?? 0) - (o[r] ?? 0);
@@ -71,133 +215,134 @@ function ae(e, t) {
71
215
  }
72
216
  return 0;
73
217
  }
74
- async function ce() {
75
- const e = A(!1);
76
- if (!v(e))
218
+ async function F(e) {
219
+ const t = k(e), n = A(e, !1);
220
+ if (!v(n))
77
221
  return;
78
- const o = (await Le({ cacheDir: e })).filter((r) => r.browser === E.CHROME).sort((r, i) => ae(r.buildId, i.buildId)).at(-1);
79
- return o && { buildId: o.buildId, executablePath: o.executablePath };
80
- }
81
- async function le(e = {}) {
82
- const { maxAgeMs: t = Ke, timeoutMs: n = Nt, now: o = Date.now() } = e, r = q();
83
- if (r.latestBuildId && r.checkedAt && o - r.checkedAt < t)
84
- return r.latestBuildId;
85
- const i = Ne();
86
- if (i)
222
+ const r = (await We({ cacheDir: n })).filter((i) => i.browser === t.browser).sort((i, s) => de(i.buildId, s.buildId)).at(-1);
223
+ return r && { flavor: e, buildId: r.buildId, executablePath: r.executablePath };
224
+ }
225
+ async function he(e, t = {}) {
226
+ const { maxAgeMs: n = Ze, timeoutMs: o = qt, now: r = Date.now() } = t, i = Z(e);
227
+ if (i.latestBuildId && i.checkedAt && r - i.checkedAt < n)
228
+ return i.latestBuildId;
229
+ const s = Ke();
230
+ if (s)
87
231
  try {
88
- const s = await Rt(
89
- Ue(E.CHROME, i, "stable"),
90
- n
232
+ const c = k(e), a = await tn(
233
+ Ye(c.browser, s, c.latestTag),
234
+ o
91
235
  );
92
- return z({ checkedAt: o, latestBuildId: s }), s;
236
+ return Q(e, { checkedAt: r, latestBuildId: a }), a;
93
237
  } catch {
94
- return r.latestBuildId;
238
+ return i.latestBuildId;
95
239
  }
96
240
  }
97
- async function P(e) {
98
- const t = A(), n = await Et({
99
- browser: E.CHROME,
100
- buildId: e,
101
- cacheDir: t,
241
+ async function D(e, t) {
242
+ const n = k(e), o = A(e), r = await _t({
243
+ browser: n.browser,
244
+ buildId: t,
245
+ cacheDir: o,
102
246
  downloadProgressCallback: "default"
103
- }), o = (await Le({ cacheDir: t })).filter(
104
- (r) => r.browser === E.CHROME && r.buildId !== e
247
+ }), i = (await We({ cacheDir: o })).filter(
248
+ (s) => s.browser === n.browser && s.buildId !== t
105
249
  );
106
- for (const r of o)
107
- await Pt({ browser: E.CHROME, buildId: r.buildId, cacheDir: t });
108
- return { buildId: e, executablePath: n.executablePath };
109
- }
110
- async function Ut(e) {
111
- const t = Ne();
112
- if (!t)
113
- throw new Error("could not detect a supported platform for Chrome for Testing");
114
- const n = await Ue(E.CHROME, t, "stable");
115
- z({ checkedAt: Date.now(), latestBuildId: n });
116
- const o = await ce();
117
- if (o && ae(o.buildId, n) >= 0)
118
- return e(`Chrome for Testing ${o.buildId} is up to date`), { ...o, outcome: "current" };
119
- e(
120
- o ? `updating Chrome for Testing ${o.buildId} → ${n}…` : `installing Chrome for Testing ${n}…`
250
+ for (const s of i)
251
+ await jt({ browser: n.browser, buildId: s.buildId, cacheDir: o });
252
+ return { flavor: e, buildId: t, executablePath: r.executablePath };
253
+ }
254
+ async function Zt(e, t) {
255
+ const n = k(e), o = Ke();
256
+ if (!o)
257
+ throw new Error(`could not detect a supported platform for ${n.displayName}`);
258
+ const r = await Ye(n.browser, o, n.latestTag);
259
+ Q(e, { checkedAt: Date.now(), latestBuildId: r });
260
+ const i = await F(e);
261
+ if (i && de(i.buildId, r) >= 0)
262
+ return t(`${n.displayName} ${i.buildId} is up to date`), { ...i, outcome: "current" };
263
+ t(
264
+ i ? `updating ${n.displayName} ${i.buildId} → ${r}…` : `installing ${n.displayName} ${r}…`
121
265
  );
122
- const r = await P(n);
123
- return e(`Chrome for Testing ${n} installed at ${r.executablePath}`), { ...r, outcome: o ? "updated" : "installed" };
266
+ const s = await D(e, r);
267
+ return t(`${n.displayName} ${r} installed at ${s.executablePath}`), { ...s, outcome: i ? "updated" : "installed" };
124
268
  }
125
- async function We(e) {
126
- const { mode: t, interactive: n, now: o = Date.now() } = e, r = await ce();
127
- if (t === "off" || !n)
128
- return r == null ? void 0 : r.executablePath;
129
- if (!r)
130
- return Lt(t, o);
131
- const i = await le({ now: o });
132
- return !i || ae(i, r.buildId) <= 0 ? r.executablePath : Mt(t, r, i);
269
+ async function et(e) {
270
+ const { flavor: t, mode: n, interactive: o, now: r = Date.now() } = e, i = await F(t);
271
+ if (n === "off" || !o)
272
+ return i == null ? void 0 : i.executablePath;
273
+ if (!i)
274
+ return Qt(t, n, r);
275
+ const s = await he(t, { now: r });
276
+ return !s || de(s, i.buildId) <= 0 ? i.executablePath : en(t, n, i, s);
133
277
  }
134
- async function Lt(e, t) {
135
- const n = await le({ now: t });
136
- if (!n)
278
+ async function Qt(e, t, n) {
279
+ const o = k(e), r = await he(e, { now: n });
280
+ if (!r)
137
281
  return;
138
- if (e === "auto")
139
- return w(`installing Chrome for Testing ${n} (chrome.forTesting: "auto")…`), (await P(n)).executablePath;
140
- const o = q();
141
- if (o.installDeclinedAt && t - o.installDeclinedAt < Ke)
282
+ if (t === "auto")
283
+ return g(`installing ${o.displayName} ${r} (chrome.manage: "auto")…`), (await D(e, r)).executablePath;
284
+ const i = Z(e);
285
+ if (i.installDeclinedAt && n - i.installDeclinedAt < Ze)
142
286
  return;
143
- const r = await W(
144
- `Chrome for Testing isn't installed. It's the recommended browser for aiui — version-pinned, separate from your real Chrome, and it auto-loads the aiui DevTools panel (branded Chrome can't). Download ${n} (~160 MB) to ${A(!1)}?`,
287
+ const s = await X(
288
+ `${o.displayName} isn't installed. It's the recommended browser for aiui — version-pinned, separate from your real Chrome, and it auto-loads the aiui intent client (branded Chrome can't). Download ${r} (~${o.approxSizeMb} MB) to ${A(e, !1)}?`,
145
289
  [
146
290
  { key: "y", label: "yes, install it" },
147
291
  { key: "n", label: "not now — use the regular Chrome (asks again tomorrow)" },
148
- { key: "never", label: 'never — stop offering (writes chrome.forTesting: "off")' }
292
+ { key: "never", label: 'never — stop offering (writes chrome.manage: "off")' }
149
293
  ],
150
294
  "y"
151
295
  );
152
- if (r === "y")
153
- return (await P(n)).executablePath;
154
- if (r === "never") {
155
- const i = _((s) => {
156
- s.chrome = { ...s.chrome, forTesting: "off" };
296
+ if (s === "y")
297
+ return (await D(e, r)).executablePath;
298
+ if (s === "never") {
299
+ const c = N((a) => {
300
+ a.chrome = { ...a.chrome, manage: "off" };
157
301
  });
158
- w(`wrote chrome.forTesting: "off" to ${i}`);
302
+ g(`wrote chrome.manage: "off" to ${c}`);
159
303
  } else
160
- z({ installDeclinedAt: t });
161
- }
162
- async function Mt(e, t, n) {
163
- if (e === "auto")
164
- return w(
165
- `updating Chrome for Testing ${t.buildId} → ${n} (chrome.forTesting: "auto")…`
166
- ), (await P(n)).executablePath;
167
- if (q().skippedBuildId === n)
168
- return t.executablePath;
169
- switch (await W(
170
- `Your Chrome for Testing (${t.buildId}) is out of date — latest stable is ${n}. Update?`,
304
+ Q(e, { installDeclinedAt: n });
305
+ }
306
+ async function en(e, t, n, o) {
307
+ const r = k(e);
308
+ if (t === "auto")
309
+ return g(
310
+ `updating ${r.displayName} ${n.buildId} → ${o} (chrome.manage: "auto")…`
311
+ ), (await D(e, o)).executablePath;
312
+ if (Z(e).skippedBuildId === o)
313
+ return n.executablePath;
314
+ switch (await X(
315
+ `Your ${r.displayName} (${n.buildId}) is out of date — latest is ${o}. Update?`,
171
316
  [
172
317
  { key: "y", label: "yes, just this once" },
173
- { key: "a", label: 'automatically, now and from here on (writes chrome.forTesting: "auto")' },
318
+ { key: "a", label: 'automatically, now and from here on (writes chrome.manage: "auto")' },
174
319
  {
175
320
  key: "s",
176
- label: `skip ${n} — keep ${t.buildId}, don't ask again for this version`
321
+ label: `skip ${o} — keep ${n.buildId}, don't ask again for this version`
177
322
  },
178
- { key: "never", label: 'never ask again (writes chrome.forTesting: "off")' }
323
+ { key: "never", label: 'never ask again (writes chrome.manage: "off")' }
179
324
  ],
180
325
  "y"
181
326
  )) {
182
327
  case "y":
183
- return (await P(n)).executablePath;
328
+ return (await D(e, o)).executablePath;
184
329
  case "a": {
185
- const r = _((i) => {
186
- i.chrome = { ...i.chrome, forTesting: "auto" };
330
+ const s = N((c) => {
331
+ c.chrome = { ...c.chrome, manage: "auto" };
187
332
  });
188
- return w(`wrote chrome.forTesting: "auto" to ${r}`), (await P(n)).executablePath;
333
+ return g(`wrote chrome.manage: "auto" to ${s}`), (await D(e, o)).executablePath;
189
334
  }
190
335
  case "never": {
191
- const r = _((i) => {
192
- i.chrome = { ...i.chrome, forTesting: "off" };
336
+ const s = N((c) => {
337
+ c.chrome = { ...c.chrome, manage: "off" };
193
338
  });
194
- return w(`wrote chrome.forTesting: "off" to ${r}`), t.executablePath;
339
+ return g(`wrote chrome.manage: "off" to ${s}`), n.executablePath;
195
340
  }
196
341
  default:
197
- return z({ skippedBuildId: n }), t.executablePath;
342
+ return Q(e, { skippedBuildId: o }), n.executablePath;
198
343
  }
199
344
  }
200
- async function Rt(e, t) {
345
+ async function tn(e, t) {
201
346
  let n;
202
347
  try {
203
348
  return await Promise.race([
@@ -210,131 +355,25 @@ async function Rt(e, t) {
210
355
  clearTimeout(n);
211
356
  }
212
357
  }
213
- function J(e, t) {
214
- const n = V(e), o = JSON.parse(L(d(n, "package.json"), "utf8")), r = typeof o.bin == "string" ? o.bin : Bt(o.bin);
215
- if (!r)
216
- throw new Error(
217
- `package ${e} declares no bin`
218
- );
219
- if (yt(n)) {
220
- const i = r.replace(/^\.?\/?dist\//, "src/").replace(/\.js$/, ".ts");
221
- return { command: process.execPath, args: ["--import", "tsx", C(n, i)] };
222
- }
223
- return { command: process.execPath, args: [C(n, r)] };
224
- }
225
- function Bt(e) {
226
- return e ? Object.values(e)[0] : void 0;
227
- }
228
- const Ht = "chrome-devtools", Ft = "@habemus-papadum/aiui-intent-client", Vt = "default", Gt = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
229
- function qe(e, t = {}, n = process.env) {
230
- return e.noChrome ? !1 : e.chrome ? !0 : t.enabled === !1 ? !1 : !ie(n);
231
- }
232
- function x(e, t = {}, n = process.cwd()) {
233
- if (t.executablePath && t.channel)
234
- throw new Error(
235
- "config sets both chrome.executablePath and chrome.channel — they pick the browser two different ways; keep exactly one"
236
- );
237
- const o = e.chromeProfile !== void 0 || e.chromeDataDir !== void 0, r = e.chromeDataDir ?? (o ? void 0 : t.dataDir), i = e.chromeProfile ?? (o ? void 0 : t.profile);
238
- return {
239
- userDataDir: ze({ dataDir: r, profile: i }, n),
240
- // A configured endpoint means the browser is managed elsewhere (usually
241
- // another machine) — that's always attach, whatever `mode` says.
242
- mode: t.browserUrl ? "attach" : t.mode ?? "attach",
243
- browserUrl: t.browserUrl,
244
- debugPort: t.debugPort ?? 0,
245
- executablePath: t.executablePath && C(n, t.executablePath),
246
- channel: t.channel,
247
- headless: t.headless ?? !1
248
- };
249
- }
250
- function ze(e, t = process.cwd()) {
251
- if (e.dataDir)
252
- return C(t, e.dataDir);
253
- const n = e.profile ?? Vt;
254
- if (!Gt.test(n))
255
- throw new Error(
256
- `invalid chrome profile name "${n}" — use letters, digits, ".", "_", "-" (or --aiui-chrome-data-dir for an arbitrary path)`
257
- );
258
- return d(Be(t), "chrome", n);
259
- }
260
- const Kt = "dist-ext";
261
- function Yt() {
262
- try {
263
- const e = $t(V(Ft));
264
- return { root: e, outDir: d(e, Kt) };
265
- } catch {
266
- return;
267
- }
268
- }
269
- function Wt(e) {
270
- return e === void 0 ? { state: "absent" } : v(d(e.outDir, "manifest.json")) ? { state: "ready", dir: e.outDir } : { state: "unbuilt", root: e.root };
271
- }
272
- function j() {
273
- return Wt(Yt());
274
- }
275
- function Je(e) {
276
- e.state === "unbuilt" && w(
277
- "the aiui intent client has no MV3 bundle yet, so this launch won't load it",
278
- `Build it once: pnpm -C packages/aiui-intent-client build:ext
279
- then relaunch — or load it into the RUNNING browser:
280
- pnpm -C packages/aiui-intent-client ext`
281
- );
282
- }
283
- function Xe(e, t) {
284
- if (!t.length || e.executablePath)
285
- return;
286
- const n = d(e.userDataDir, "aiui-extension-autoload-hint");
287
- if (!v(n)) {
288
- w(
289
- "the aiui intent client can't auto-load into regular Chrome (≥ 137 ignores --load-extension)",
290
- `Load it once in the launched Chrome — chrome://extensions → Developer mode → Load unpacked →
291
- ${t.join(`
292
- `)}
293
- — and this profile remembers it. Or switch to Chrome for Testing (\`aiui chrome install\`),
294
- which auto-loads it. This note won't repeat for this profile.`
295
- );
296
- try {
297
- K(n, `${(/* @__PURE__ */ new Date()).toISOString()}
298
- `);
299
- } catch {
300
- }
301
- }
302
- }
303
- function Z(e) {
304
- return {
305
- command: "npx",
306
- args: ["-y", "chrome-devtools-mcp@latest", "--browser-url", e]
307
- };
308
- }
309
- function qt(e, t = []) {
310
- const n = [
311
- "-y",
312
- "chrome-devtools-mcp@latest",
313
- "--userDataDir",
314
- e.userDataDir,
315
- "--ignoreDefaultChromeArg=--disable-extensions"
316
- ];
317
- return e.executablePath && n.push("--executablePath", e.executablePath), e.channel && n.push("--channel", e.channel), e.headless && n.push("--headless"), t.length && n.push(`--chromeArg=--load-extension=${t.join(",")}`), { command: "npx", args: n };
318
- }
319
- const N = "com.habemus_papadum.aiui", ue = "cdpbfpcelmifhagikjlfpgfipggcmdeg";
320
- function Ze(e, t) {
358
+ const O = "com.habemus_papadum.aiui", fe = "cdpbfpcelmifhagikjlfpgfipggcmdeg";
359
+ function tt(e, t) {
321
360
  if (e === "darwin") {
322
- const n = d(t, "Library", "Application Support");
361
+ const n = h(t, "Library", "Application Support");
323
362
  return [
324
- d(n, "Google", "Chrome", "NativeMessagingHosts"),
325
- d(n, "Chromium", "NativeMessagingHosts"),
326
- d(n, "Microsoft Edge", "NativeMessagingHosts")
363
+ h(n, "Google", "Chrome", "NativeMessagingHosts"),
364
+ h(n, "Chromium", "NativeMessagingHosts"),
365
+ h(n, "Microsoft Edge", "NativeMessagingHosts")
327
366
  ];
328
367
  }
329
368
  if (e === "linux")
330
369
  return [
331
- d(t, ".config", "google-chrome", "NativeMessagingHosts"),
332
- d(t, ".config", "chromium", "NativeMessagingHosts"),
333
- d(t, ".config", "microsoft-edge", "NativeMessagingHosts")
370
+ h(t, ".config", "google-chrome", "NativeMessagingHosts"),
371
+ h(t, ".config", "chromium", "NativeMessagingHosts"),
372
+ h(t, ".config", "microsoft-edge", "NativeMessagingHosts")
334
373
  ];
335
374
  throw new Error(`aiui extension: unsupported platform ${e} (macOS/Linux only for now)`);
336
375
  }
337
- function zt(e, t, n) {
376
+ function nn(e, t, n) {
338
377
  const o = (r) => `"${r.replace(/(["\\$`])/g, "\\$1")}"`;
339
378
  return [
340
379
  "#!/bin/sh",
@@ -346,35 +385,35 @@ function zt(e, t, n) {
346
385
  ].join(`
347
386
  `);
348
387
  }
349
- const Jt = ["install-native-host", "status"];
350
- async function Xt(e, t = {}) {
388
+ const on = ["install-native-host", "status"];
389
+ async function rn(e, t = {}) {
351
390
  switch (e) {
352
391
  case "install-native-host":
353
- Qt(t);
392
+ an(t);
354
393
  return;
355
394
  case "status":
356
- en();
395
+ cn();
357
396
  return;
358
397
  case "dev":
359
398
  case "reload":
360
- b(
399
+ y(
361
400
  `aiui extension ${e} is gone — the frozen aiui-extension was deleted`,
362
401
  `The intent client's extension is a static build:
363
402
  pnpm -C packages/aiui-intent-client ext (build + load into the session browser)`
364
403
  ), process.exitCode = 1;
365
404
  return;
366
405
  default:
367
- throw new Error(`aiui extension: unknown action "${e}" (${Jt.join(" | ")})`);
406
+ throw new Error(`aiui extension: unknown action "${e}" (${on.join(" | ")})`);
368
407
  }
369
408
  }
370
- function Qe() {
371
- return d(F("native-host", { create: !0 }), "aiui-native-host.sh");
409
+ function nt() {
410
+ return h(Y("native-host", { create: !0 }), "aiui-native-host.sh");
372
411
  }
373
- function et(e) {
374
- const t = J("@habemus-papadum/aiui"), n = V("@habemus-papadum/aiui"), o = Qe();
375
- tt(o, zt(n, t.command, t.args)), Ct(o, 493);
412
+ function ot(e) {
413
+ const t = J("@habemus-papadum/aiui"), n = K("@habemus-papadum/aiui"), o = nt();
414
+ rt(o, nn(n, t.command, t.args)), xt(o, 493);
376
415
  const r = {
377
- name: N,
416
+ name: O,
378
417
  description: "aiui native-messaging host: channel discovery for the aiui intent client",
379
418
  path: o,
380
419
  type: "stdio",
@@ -384,29 +423,29 @@ function et(e) {
384
423
  allowed_origins: [
385
424
  .../* @__PURE__ */ new Set([
386
425
  `chrome-extension://${e}/`,
387
- `chrome-extension://${ue}/`
426
+ `chrome-extension://${fe}/`
388
427
  ])
389
428
  ]
390
429
  };
391
430
  return { wrapper: o, body: `${JSON.stringify(r, null, 2)}
392
431
  ` };
393
432
  }
394
- function tt(e, t) {
433
+ function rt(e, t) {
395
434
  try {
396
- if (L(e, "utf8") === t)
435
+ if (M(e, "utf8") === t)
397
436
  return !1;
398
437
  } catch {
399
438
  }
400
- return K(e, t), !0;
439
+ return W(e, t), !0;
401
440
  }
402
- function Zt(e, t = {}) {
403
- const { body: n } = et(t.extensionId ?? ue), o = d(e, "NativeMessagingHosts");
404
- G(o, { recursive: !0 }), tt(d(o, `${N}.json`), n);
441
+ function sn(e, t = {}) {
442
+ const { body: n } = ot(t.extensionId ?? fe), o = h(e, "NativeMessagingHosts");
443
+ z(o, { recursive: !0 }), rt(h(o, `${O}.json`), n);
405
444
  }
406
- function B(e, t, n) {
445
+ function V(e, t, n) {
407
446
  if (t)
408
447
  try {
409
- Zt(e);
448
+ sn(e);
410
449
  } catch (o) {
411
450
  n(
412
451
  "couldn't install the native-messaging host into the browser profile — the intent extension will need a manually typed port",
@@ -414,14 +453,14 @@ function B(e, t, n) {
414
453
  );
415
454
  }
416
455
  }
417
- function Qt(e) {
418
- const t = e.extensionId ?? ue, { wrapper: n, body: o } = et(t);
456
+ function an(e) {
457
+ const t = e.extensionId ?? fe, { wrapper: n, body: o } = ot(t);
419
458
  process.stdout.write(`wrote ${n}
420
459
  `);
421
- for (const r of Ze(process.platform, se())) {
422
- G(r, { recursive: !0 });
423
- const i = d(r, `${N}.json`);
424
- K(i, o), process.stdout.write(`wrote ${i}
460
+ for (const r of tt(process.platform, ue())) {
461
+ z(r, { recursive: !0 });
462
+ const i = h(r, `${O}.json`);
463
+ W(i, o), process.stdout.write(`wrote ${i}
425
464
  `);
426
465
  }
427
466
  process.stdout.write(
@@ -432,22 +471,22 @@ automatically — this global install is for browsers aiui does not manage.)
432
471
  `
433
472
  );
434
473
  }
435
- function en() {
436
- const e = Qe();
474
+ function cn() {
475
+ const e = nt();
437
476
  process.stdout.write(`wrapper: ${e} ${v(e) ? "(present)" : "(MISSING)"}
438
477
  `);
439
- for (const o of Ze(process.platform, se()))
440
- $e(d(o, `${N}.json`));
441
- const t = d(process.cwd(), ".aiui-cache", "chrome");
478
+ for (const o of tt(process.platform, ue()))
479
+ Ce(h(o, `${O}.json`));
480
+ const t = h(process.cwd(), ".aiui-cache", "chrome");
442
481
  let n = [];
443
482
  try {
444
- n = Y(t, { withFileTypes: !0 }).filter((o) => o.isDirectory()).map((o) => o.name);
483
+ n = q(t, { withFileTypes: !0 }).filter((o) => o.isDirectory()).map((o) => o.name);
445
484
  } catch {
446
485
  }
447
486
  for (const o of n)
448
- $e(d(t, o, "NativeMessagingHosts", `${N}.json`));
487
+ Ce(h(t, o, "NativeMessagingHosts", `${O}.json`));
449
488
  }
450
- function $e(e) {
489
+ function Ce(e) {
451
490
  var t;
452
491
  if (!v(e)) {
453
492
  process.stdout.write(`absent: ${e}
@@ -455,7 +494,7 @@ function $e(e) {
455
494
  return;
456
495
  }
457
496
  try {
458
- const n = JSON.parse(L(e, "utf8"));
497
+ const n = JSON.parse(M(e, "utf8"));
459
498
  process.stdout.write(`present: ${e} → ${(t = n.allowed_origins) == null ? void 0 : t.join(", ")}
460
499
  `);
461
500
  } catch {
@@ -463,11 +502,11 @@ function $e(e) {
463
502
  `);
464
503
  }
465
504
  }
466
- const tn = 9222;
467
- async function nn(e) {
468
- const n = { ...S().chrome };
505
+ const ln = 9222;
506
+ async function un(e) {
507
+ const n = { ...P().chrome };
469
508
  if (n.browserUrl) {
470
- w(
509
+ g(
471
510
  `config pins chrome.browserUrl to ${n.browserUrl} — the browser is managed elsewhere`,
472
511
  "Run `aiui browser` on the machine that should host it (and drop browserUrl there)."
473
512
  );
@@ -475,28 +514,28 @@ async function nn(e) {
475
514
  }
476
515
  let o, r;
477
516
  try {
478
- o = Ce(e.remotePort, "--remote-port") ?? tn, r = Ce(e.port, "--port");
517
+ o = xe(e.remotePort, "--remote-port") ?? ln, r = xe(e.port, "--port");
479
518
  } catch (a) {
480
- b(a instanceof Error ? a.message : String(a)), process.exitCode = 1;
519
+ y(a instanceof Error ? a.message : String(a)), process.exitCode = 1;
481
520
  return;
482
521
  }
483
522
  const i = {
484
523
  chromeProfile: e.tunnel ? void 0 : e.profile,
485
- chromeDataDir: e.dataDir ?? (e.tunnel ? on(e.tunnel, e.profile) : void 0)
524
+ chromeDataDir: e.dataDir ?? (e.tunnel ? dn(e.tunnel, e.profile) : void 0)
486
525
  };
487
- let s = x(i, n);
526
+ let s = T(i, n);
488
527
  r !== void 0 && (s = { ...s, debugPort: r });
489
528
  let c = await U(s.userDataDir);
490
529
  if (c)
491
- B(
530
+ V(
492
531
  s.userDataDir,
493
532
  j().state === "ready",
494
- w
495
- ), ke("session browser already running", s, c), e.open && (await R(c.browserUrl, e.open), console.log(`opened ${e.open}`));
533
+ g
534
+ ), Ie("session browser already running", s, c), e.open && (await H(c.browserUrl, e.open), console.log(`opened ${e.open}`));
496
535
  else {
497
- const a = !!process.stdin.isTTY && !!process.stdout.isTTY && !ie();
536
+ const a = !!process.stdin.isTTY && !!process.stdout.isTTY && !ce();
498
537
  try {
499
- const l = await nt({
538
+ const u = await it({
500
539
  flags: i,
501
540
  config: n,
502
541
  interactive: a,
@@ -504,60 +543,57 @@ async function nn(e) {
504
543
  headless: e.headless,
505
544
  startUrl: e.open
506
545
  });
507
- c = l.session, s = l.settings;
508
- } catch (l) {
509
- b(
546
+ c = u.session, s = u.settings;
547
+ } catch (u) {
548
+ y(
510
549
  "the session browser failed to start",
511
- l instanceof Error ? l.message : String(l)
550
+ u instanceof Error ? u.message : String(u)
512
551
  ), process.exitCode = 1;
513
552
  return;
514
553
  }
515
- ke("session browser started", s, c);
554
+ Ie("session browser started", s, c);
516
555
  }
517
- e.tunnel ? await an(e.tunnel, o, c.port) : cn(c, o);
556
+ e.tunnel ? await pn(e.tunnel, o, c.port) : mn(c, o);
518
557
  }
519
- async function nt(e) {
520
- let t = e.config ?? {};
521
- const n = e.flags ?? {}, o = () => {
522
- const l = x(n, t);
523
- return e.debugPort === void 0 ? l : { ...l, debugPort: e.debugPort };
524
- };
525
- let r = o();
526
- if (!t.executablePath && !t.channel) {
527
- const l = await We({
528
- mode: t.forTesting ?? "prompt",
558
+ async function it(e) {
559
+ const t = e.config ?? {}, n = e.flags ?? {};
560
+ let o = T(n, t);
561
+ if (e.debugPort !== void 0 && (o = { ...o, debugPort: e.debugPort }), !t.executablePath && !t.channel) {
562
+ const a = await et({
563
+ flavor: B(t),
564
+ mode: le(t),
529
565
  interactive: e.interactive
530
566
  });
531
- l && (t = { ...t, executablePath: l }, r = o());
567
+ a && (o = { ...o, executablePath: a });
532
568
  }
533
- const i = j(), s = i.state === "ready" ? [i.dir] : [];
534
- B(r.userDataDir, i.state === "ready", w), e.interactive && (Xe(r, s), Je(i));
535
- let c;
569
+ const r = j(), i = r.state === "ready" ? [r.dir] : [];
570
+ V(o.userDataDir, r.state === "ready", g), e.interactive && (Xe(o, i), Je(r));
571
+ let s;
536
572
  try {
537
- c = Oe(r);
538
- } catch (l) {
573
+ s = Ue(o);
574
+ } catch (a) {
539
575
  throw new Error(
540
- `${l instanceof Error ? l.message : String(l)}
541
- Install Chrome for Testing with \`aiui chrome install\`, or set chrome.executablePath.`
576
+ `${a instanceof Error ? a.message : String(a)}
577
+ Install the managed browser with \`aiui chrome install\`, or set chrome.executablePath.`
542
578
  );
543
579
  }
544
- return { session: await je({
545
- binary: c,
546
- userDataDir: r.userDataDir,
547
- debugPort: r.debugPort,
548
- extensionDirs: s,
549
- headless: r.headless || e.headless,
580
+ return { session: await Me({
581
+ binary: s,
582
+ userDataDir: o.userDataDir,
583
+ debugPort: o.debugPort,
584
+ extensionDirs: i,
585
+ headless: o.headless || e.headless,
550
586
  startUrl: e.startUrl
551
- }), settings: r };
587
+ }), settings: o };
552
588
  }
553
- function on(e, t) {
554
- const n = t ?? rn(e);
555
- return d(F("browser-profiles", { create: !1 }), n);
589
+ function dn(e, t) {
590
+ const n = t ?? hn(e);
591
+ return h(Y("browser-profiles", { create: !1 }), n);
556
592
  }
557
- function rn(e) {
593
+ function hn(e) {
558
594
  return (e.includes("@") ? e.slice(e.indexOf("@") + 1) : e).replace(/[^A-Za-z0-9._-]/g, "-") || "remote";
559
595
  }
560
- function sn(e, t, n) {
596
+ function fn(e, t, n) {
561
597
  return [
562
598
  // No remote command — the connection exists only to carry the forward...
563
599
  "-N",
@@ -570,28 +606,28 @@ function sn(e, t, n) {
570
606
  e
571
607
  ];
572
608
  }
573
- function ot(e) {
609
+ function st(e) {
574
610
  return `aiui claude --aiui-browser-url http://127.0.0.1:${e}`;
575
611
  }
576
- async function an(e, t, n) {
612
+ async function pn(e, t, n) {
577
613
  console.log(
578
614
  `
579
615
  tunneling ${e}:${t} → localhost:${n} — on ${e}, run:
580
616
 
581
- ${ot(t)}
617
+ ${st(t)}
582
618
 
583
619
  (Ctrl-C closes the tunnel; the browser stays running.)`
584
620
  );
585
- const o = await T("ssh", sn(e, t, n), {
621
+ const o = await E("ssh", fn(e, t, n), {
586
622
  stdio: "inherit",
587
623
  reject: !1
588
624
  });
589
- o.failed && !o.isTerminated && (b(
625
+ o.failed && !o.isTerminated && (y(
590
626
  `the ssh tunnel to ${e} exited (code ${o.exitCode})`,
591
627
  "A taken remote port exits immediately (ExitOnForwardFailure) — try another --remote-port. The browser is still running; rerun `aiui browser --tunnel …` to reconnect."
592
628
  ), process.exitCode = 1);
593
629
  }
594
- function Ce(e, t) {
630
+ function xe(e, t) {
595
631
  if (e === void 0)
596
632
  return;
597
633
  const n = Number(e);
@@ -599,63 +635,85 @@ function Ce(e, t) {
599
635
  throw new Error(`invalid ${t} ${e} — expected 0..65535`);
600
636
  return n;
601
637
  }
602
- function ke(e, t, n) {
638
+ function Ie(e, t, n) {
603
639
  console.log(e), console.log(` profile: ${t.userDataDir}`), console.log(` debug endpoint: ${n.browserUrl}`);
604
640
  }
605
- function cn(e, t) {
641
+ function mn(e, t) {
606
642
  console.log(
607
643
  `
608
644
  An \`aiui claude\` in this profile's project attaches automatically. For a *remote*
609
645
  session, rerun with \`--tunnel <[user@]host>\` — or do it by hand:
610
646
  ssh -N -o ExitOnForwardFailure=yes -R ${t}:localhost:${e.port} <host>
611
- then, on the remote: ${ot(t)}`
647
+ then, on the remote: ${st(t)}`
612
648
  );
613
649
  }
614
- async function ln(e, t) {
650
+ async function wn(e, t) {
615
651
  var i, s;
616
- const n = S(), o = x(
652
+ const n = P(), o = T(
617
653
  { chromeProfile: t.profile, chromeDataDir: t.dataDir },
618
654
  n.chrome ?? {}
619
655
  ), r = ((i = n.chrome) == null ? void 0 : i.browserUrl) ?? ((s = await U(o.userDataDir)) == null ? void 0 : s.browserUrl);
620
656
  if (!r) {
621
- b(
657
+ y(
622
658
  "no session browser is running for this profile",
623
659
  `Start one with \`aiui browser\` (profile: ${o.userDataDir}).`
624
660
  ), process.exitCode = 1;
625
661
  return;
626
662
  }
627
663
  try {
628
- await R(r, e), console.log(`opened ${e}`);
664
+ await H(r, e), console.log(`opened ${e}`);
629
665
  } catch (c) {
630
- b(`couldn't open ${e}`, c instanceof Error ? c.message : String(c)), process.exitCode = 1;
666
+ y(`couldn't open ${e}`, c instanceof Error ? c.message : String(c)), process.exitCode = 1;
631
667
  }
632
668
  }
633
- async function un(e) {
634
- const [t] = e;
669
+ async function gn(e) {
670
+ const [t, n] = e;
635
671
  switch (t) {
636
672
  case "install":
637
- case "update":
638
- await Ut((n) => console.log(n));
673
+ case "update": {
674
+ const o = bn(n);
675
+ if ("error" in o) {
676
+ y(o.error, "Usage: aiui chrome install [chromium | chrome-for-testing]"), process.exitCode = 1;
677
+ return;
678
+ }
679
+ await Zt(o.flavor, (r) => console.log(r));
639
680
  return;
681
+ }
640
682
  case "status":
641
- await dn();
683
+ await yn();
642
684
  return;
643
685
  default:
644
- b(
686
+ y(
645
687
  t ? `unknown aiui chrome action: ${t}` : "aiui chrome needs an action",
646
- "Usage: aiui chrome <install | update | status>"
688
+ "Usage: aiui chrome <install | update [flavor] | status>"
647
689
  ), process.exitCode = 1;
648
690
  return;
649
691
  }
650
692
  }
651
- async function dn() {
652
- const t = S().chrome ?? {}, n = { chrome: !1, noChrome: !1 }, o = await ce(), r = await le();
653
- if (console.log("Chrome for Testing (managed):"), o) {
654
- const m = r === void 0 ? "(latest stable unknown — offline?)" : r === o.buildId ? "(latest stable)" : `(latest stable is ${r} — run \`aiui chrome update\`)`;
655
- console.log(` installed ${o.buildId} ${m}`), console.log(` ${o.executablePath}`);
656
- } else
657
- console.log(" not installed — `aiui chrome install` (recommended; auto-loads the panel)");
658
- if (console.log(` startup checks (chrome.forTesting): ${t.forTesting ?? "prompt"}`), console.log(`
693
+ function bn(e) {
694
+ if (e === void 0)
695
+ return { flavor: B(P().chrome) };
696
+ const n = {
697
+ chromium: "chromium",
698
+ "chrome-for-testing": "chrome-for-testing",
699
+ cft: "chrome-for-testing"
700
+ }[e];
701
+ return n ? { flavor: n } : { error: `unknown browser "${e}" — use chromium or chrome-for-testing` };
702
+ }
703
+ async function yn() {
704
+ const t = P().chrome ?? {}, n = { chrome: !1, noChrome: !1 }, o = B(t);
705
+ console.log("Managed browsers:"), console.log(` preferred (chrome.managed): ${k(o).displayName}`);
706
+ for (const p of Fe) {
707
+ const w = k(p), b = p === o ? " *preferred*" : "", $ = await F(p);
708
+ if ($) {
709
+ const d = await he(p), R = d === void 0 ? "(latest unknown — offline?)" : d === $.buildId ? "(latest)" : `(latest is ${d} — \`aiui chrome update ${p}\`)`;
710
+ console.log(` ${w.displayName}${b}: ${$.buildId} ${R}`), console.log(` ${$.executablePath}`);
711
+ } else {
712
+ const d = p === o ? "aiui chrome install" : `aiui chrome install ${p}`;
713
+ console.log(` ${w.displayName}${b}: not installed — \`${d}\``);
714
+ }
715
+ }
716
+ if (console.log(` startup checks (chrome.manage): ${le(t)}`), console.log(`
659
717
  This directory would launch:`), !qe(n, t)) {
660
718
  console.log(" nothing — the Chrome DevTools MCP is disabled here");
661
719
  return;
@@ -664,16 +722,14 @@ This directory would launch:`), !qe(n, t)) {
664
722
  console.log(` connection: attach to ${t.browserUrl} (chrome.browserUrl)`), console.log(" the browser is managed elsewhere — nothing launches on this machine");
665
723
  return;
666
724
  }
667
- const i = { ...t };
668
- !i.executablePath && !i.channel && o && (i.executablePath = o.executablePath);
669
- const s = x({}, i), c = await U(s.userDataDir), a = s.mode === "attach" ? c ? `attach to the running session browser at ${c.browserUrl}` : "attach a session browser starts with the next interactive launch (or `aiui browser`)" : "launch chrome-devtools-mcp starts a private browser on the agent's first tool use";
670
- console.log(` connection: ${a}`);
671
- const l = s.executablePath ? s.executablePath === (o == null ? void 0 : o.executablePath) ? `Chrome for Testing ${o.buildId}` : s.executablePath : s.channel ? `installed Chrome (${s.channel} channel)` : "installed Chrome (stable)";
672
- console.log(` browser: ${l}${s.headless ? " — headless" : ""}`), console.log(` user data dir: ${s.userDataDir}`);
673
- const p = d(ze({}, process.cwd()), "..");
674
- if (v(p)) {
675
- const m = Y(p, { withFileTypes: !0 }).filter((g) => g.isDirectory()).map((g) => g.name);
676
- m.length && console.log(` profiles here: ${m.join(", ")}`);
725
+ const r = T({}, t), i = r.executablePath || r.channel ? void 0 : await F(o), s = await U(r.userDataDir), c = r.mode === "attach" ? s ? `attach to the running session browser at ${s.browserUrl}` : "attach — a session browser starts with the next interactive launch (or `aiui browser`)" : "launch — chrome-devtools-mcp starts a private browser on the agent's first tool use";
726
+ console.log(` connection: ${c}`);
727
+ const a = r.executablePath ? r.executablePath : r.channel ? `installed Chrome (${r.channel} channel)` : i ? `${k(o).displayName} ${i.buildId} (managed)` : `${k(o).displayName} (managednot yet installed)`;
728
+ console.log(` browser: ${a}${r.headless ? " — headless" : ""}`), console.log(` profile variant: ${r.variant}`), console.log(` user data dir: ${r.userDataDir}`);
729
+ const u = !r.channel, m = Oe(r.userDataDir);
730
+ if (v(m)) {
731
+ const p = q(m, { withFileTypes: !0 }).filter((w) => w.isDirectory()).map((w) => w.name);
732
+ p.length && console.log(` profiles here (${r.variant}): ${p.join(", ")}`);
677
733
  }
678
734
  console.log(`
679
735
  aiui intent client (the extension launches auto-load):`);
@@ -690,96 +746,96 @@ aiui intent client (the extension launches auto-load):`);
690
746
  );
691
747
  break;
692
748
  case "ready":
693
- console.log(` ${f.dir}`), hn(s.executablePath);
749
+ console.log(` ${f.dir}`), vn(u);
694
750
  break;
695
751
  }
696
752
  }
697
- function hn(e) {
698
- e ? console.log(" auto-loads via --load-extension (honored by Chrome for Testing/Chromium)") : (console.log(" can NOT auto-load into branded Chrome ≥ 137 — load it unpacked once"), console.log(
753
+ function vn(e) {
754
+ e ? console.log(" auto-loads via --load-extension (honored by Chromium/Chrome for Testing)") : (console.log(" can NOT auto-load into branded Chrome ≥ 137 — load it unpacked once"), console.log(
699
755
  " (chrome://extensions → Developer mode → Load unpacked), or `aiui chrome install`"
700
756
  ));
701
757
  }
702
- const fn = "--aiui-";
703
- function rt(e) {
758
+ const $n = "--aiui-";
759
+ function at(e) {
704
760
  if (e.includes("--help") || e.includes("-h"))
705
761
  return "help";
706
762
  if (e.includes("--version") || e.includes("-v"))
707
763
  return "version";
708
764
  }
709
- function de(e) {
710
- let t, n, o = !1, r = !1, i = !1, s = !1, c, a, l, p;
765
+ function pe(e) {
766
+ let t, n, o = !1, r = !1, i = !1, s = !1, c, a, u, m;
711
767
  const f = [];
712
- for (let m = 0; m < e.length; m++) {
713
- const g = e[m];
714
- if (!g.startsWith(fn)) {
715
- f.push(g);
768
+ for (let p = 0; p < e.length; p++) {
769
+ const w = e[p];
770
+ if (!w.startsWith($n)) {
771
+ f.push(w);
716
772
  continue;
717
773
  }
718
- const y = g.indexOf("="), I = y === -1 ? g : g.slice(0, y);
719
- let h = y === -1 ? void 0 : g.slice(y + 1);
720
- switch (I) {
774
+ const b = w.indexOf("="), $ = b === -1 ? w : w.slice(0, b);
775
+ let d = b === -1 ? void 0 : w.slice(b + 1);
776
+ switch ($) {
721
777
  case "--aiui-tag": {
722
- if (h === void 0 && (h = e[++m]), !h)
778
+ if (d === void 0 && (d = e[++p]), !d)
723
779
  throw new Error("--aiui-tag requires a non-empty value");
724
- t = h;
780
+ t = d;
725
781
  break;
726
782
  }
727
783
  case "--aiui-mcp": {
728
- if (h === void 0 && (h = e[++m]), !h)
784
+ if (d === void 0 && (d = e[++p]), !d)
729
785
  throw new Error("--aiui-mcp requires a non-empty value");
730
- n = h;
786
+ n = d;
731
787
  break;
732
788
  }
733
789
  case "--aiui-chrome": {
734
- if (h !== void 0)
790
+ if (d !== void 0)
735
791
  throw new Error("--aiui-chrome takes no value");
736
792
  o = !0;
737
793
  break;
738
794
  }
739
795
  case "--aiui-no-chrome": {
740
- if (h !== void 0)
796
+ if (d !== void 0)
741
797
  throw new Error("--aiui-no-chrome takes no value");
742
798
  r = !0;
743
799
  break;
744
800
  }
745
801
  case "--aiui-browser": {
746
- if (h !== void 0)
802
+ if (d !== void 0)
747
803
  throw new Error("--aiui-browser takes no value");
748
804
  i = !0;
749
805
  break;
750
806
  }
751
807
  case "--aiui-no-browser": {
752
- if (h !== void 0)
808
+ if (d !== void 0)
753
809
  throw new Error("--aiui-no-browser takes no value");
754
810
  s = !0;
755
811
  break;
756
812
  }
757
813
  case "--aiui-chrome-profile": {
758
- if (h === void 0 && (h = e[++m]), !h)
814
+ if (d === void 0 && (d = e[++p]), !d)
759
815
  throw new Error("--aiui-chrome-profile requires a non-empty value");
760
- c = h;
816
+ c = d;
761
817
  break;
762
818
  }
763
819
  case "--aiui-chrome-data-dir": {
764
- if (h === void 0 && (h = e[++m]), !h)
820
+ if (d === void 0 && (d = e[++p]), !d)
765
821
  throw new Error("--aiui-chrome-data-dir requires a non-empty value");
766
- a = h;
822
+ a = d;
767
823
  break;
768
824
  }
769
825
  case "--aiui-browser-url": {
770
- if (h === void 0 && (h = e[++m]), !h)
826
+ if (d === void 0 && (d = e[++p]), !d)
771
827
  throw new Error("--aiui-browser-url requires a non-empty value");
772
- l = h;
828
+ u = d;
773
829
  break;
774
830
  }
775
831
  case "--aiui-bind": {
776
- if (h === void 0 && (h = e[++m]), !h || !ve.includes(h))
777
- throw new Error(`--aiui-bind requires one of: ${ve.join(", ")}`);
778
- p = h;
832
+ if (d === void 0 && (d = e[++p]), !d || !$e.includes(d))
833
+ throw new Error(`--aiui-bind requires one of: ${$e.join(", ")}`);
834
+ m = d;
779
835
  break;
780
836
  }
781
837
  default:
782
- throw new Error(`unknown aiui option: ${I}`);
838
+ throw new Error(`unknown aiui option: ${$}`);
783
839
  }
784
840
  }
785
841
  if (o && r)
@@ -788,7 +844,7 @@ function de(e) {
788
844
  throw new Error("--aiui-browser and --aiui-no-browser are mutually exclusive");
789
845
  if (c !== void 0 && a !== void 0)
790
846
  throw new Error("--aiui-chrome-profile and --aiui-chrome-data-dir are mutually exclusive");
791
- if (l !== void 0 && (c !== void 0 || a !== void 0))
847
+ if (u !== void 0 && (c !== void 0 || a !== void 0))
792
848
  throw new Error(
793
849
  "--aiui-browser-url means the browser is managed elsewhere — it can't be combined with --aiui-chrome-profile or --aiui-chrome-data-dir"
794
850
  );
@@ -801,116 +857,100 @@ function de(e) {
801
857
  noBrowser: s,
802
858
  chromeProfile: c,
803
859
  chromeDataDir: a,
804
- browserUrl: l,
805
- bind: p,
860
+ browserUrl: u,
861
+ bind: m,
806
862
  passthrough: f
807
863
  };
808
864
  }
809
- function it(e) {
865
+ function ct(e) {
810
866
  var t;
811
867
  return { bind: e.bind ?? ((t = e.config.channel) == null ? void 0 : t.bind) ?? "loopback" };
812
868
  }
813
- function st(e) {
869
+ function lt(e) {
814
870
  return ["--bind", e.bind];
815
871
  }
816
- const pn = /* @__PURE__ */ new Set(["serve", "mcp"]);
817
- function mn(e, t) {
872
+ const kn = /* @__PURE__ */ new Set(["serve", "mcp"]);
873
+ function Cn(e, t) {
818
874
  return e.some((n) => n === t || n.startsWith(`${t}=`));
819
875
  }
820
- function at(e) {
876
+ function ut(e) {
821
877
  const t = e.find((n) => !n.startsWith("-"));
822
- return t !== void 0 && pn.has(t);
878
+ return t !== void 0 && kn.has(t);
823
879
  }
824
- function wn(e, t) {
825
- if (!at(e))
880
+ function xn(e, t) {
881
+ if (!ut(e))
826
882
  return e;
827
- const n = st(t), o = [...e];
883
+ const n = lt(t), o = [...e];
828
884
  for (let r = 0; r < n.length; r += 2) {
829
885
  const i = n[r], s = n[r + 1];
830
- mn(e, i) || o.push(i, s);
886
+ Cn(e, i) || o.push(i, s);
831
887
  }
832
888
  return o;
833
889
  }
834
- const gn = {
835
- darwin: 2147578994,
836
- linux: 21522
837
- }, bn = 'open(my $t,"+<","/dev/tty") or exit 0; my $c="\\r"; ioctl($t,$ARGV[0]+0,$c);', yn = [250, 750];
838
- function vn(e = yn) {
839
- const t = gn[process.platform];
840
- if (t !== void 0)
841
- for (const n of e)
842
- setTimeout(() => {
843
- try {
844
- Ot("perl", ["-e", bn, String(t)], { stdio: "ignore" }).on("error", () => {
845
- });
846
- } catch {
847
- }
848
- }, n).unref();
849
- }
850
- const $n = `One-time setup — how should aiui launch Claude Code?
890
+ const In = `One-time setup — how should aiui launch Claude Code?
851
891
  With --dangerously-skip-permissions, every agent action (shell commands, file writes,
852
892
  network, the browser) runs without asking you first. Fast, and dangerous. It's a personal
853
893
  preference — aiui works fine either way. Saved as claude.skipPermissions in your user
854
- config; edit or delete it there to change your mind.`, Cn = `One-time setup — where should the channel's web server bind?
894
+ config; edit or delete it there to change your mind.`, En = `One-time setup — where should the channel's web server bind?
855
895
  Binding the HOST interface puts the session's whole web surface on your network,
856
896
  UNAUTHENTICATED — the iPad paint page (\`aiui paint url\` prints its URL), but also prompt
857
897
  injection, /debug, and every sidecar. That's the simple, single-port way to use the iPad —
858
898
  on a network that is yours alone (a home LAN), not on café Wi-Fi. LOOPBACK keeps everything
859
899
  this-machine-only; reaching it from an iPad is then up to you — tunnel the channel port
860
900
  however you like (Tailscale, \`ssh -L\`). Saved as channel.bind in your user config;
861
- --aiui-bind wins per launch.`, kn = `One-time setup — auto-dismiss Claude Code's channel prompt?
901
+ --aiui-bind wins per launch.`, Pn = `One-time setup — auto-dismiss Claude Code's channel prompt?
862
902
  aiui loads a custom development channel, so Claude Code shows a one-key acknowledgement
863
903
  prompt at every startup. aiui can dismiss it for you: shortly after launch it injects a
864
904
  single Enter keystroke into this terminal (a best-effort TIOCSTI ioctl on /dev/tty — it
865
905
  literally "types" the Enter for you; on platforms that forbid that, nothing happens and
866
906
  you press it yourself). Saying no just means pressing Enter once per launch. Saved as
867
907
  claude.enterNudge in your user config.`;
868
- async function xn(e, t = W) {
908
+ async function Dn(e, t = X) {
869
909
  var o, r, i;
870
910
  let n = e;
871
911
  if (((o = n.claude) == null ? void 0 : o.skipPermissions) === void 0) {
872
- const s = await t($n, [
912
+ const s = await t(In, [
873
913
  { key: "y", label: "yes — skip permissions; nothing asks before acting" },
874
914
  { key: "n", label: "no — keep Claude Code's own permission prompts" }
875
915
  ]);
876
- n = xe(n, "skipPermissions", s === "y");
916
+ n = Ee(n, "skipPermissions", s === "y");
877
917
  }
878
918
  if (((r = n.claude) == null ? void 0 : r.enterNudge) === void 0) {
879
- const s = await t(kn, [
919
+ const s = await t(Pn, [
880
920
  { key: "y", label: "yes — press Enter for me at startup" },
881
921
  { key: "n", label: "no — I'll press it myself each launch" }
882
922
  ]);
883
- n = xe(n, "enterNudge", s === "y");
923
+ n = Ee(n, "enterNudge", s === "y");
884
924
  }
885
925
  if (((i = n.channel) == null ? void 0 : i.bind) === void 0) {
886
- const s = await t(Cn, [
926
+ const s = await t(En, [
887
927
  { key: "h", label: "host — reachable on my (trusted) network; the iPad just works" },
888
928
  { key: "l", label: "loopback — this machine only; I'll tunnel when I want the iPad" }
889
929
  ]);
890
- n = Tn(n, s === "h" ? "host" : "loopback");
930
+ n = Sn(n, s === "h" ? "host" : "loopback");
891
931
  }
892
932
  return n;
893
933
  }
894
- function xe(e, t, n) {
895
- const o = _((r) => {
934
+ function Ee(e, t, n) {
935
+ const o = N((r) => {
896
936
  r.claude = { ...r.claude, [t]: n };
897
937
  });
898
- return w(`wrote claude.${t}: ${n} to ${o}`), { ...e, claude: { ...e.claude, [t]: n } };
938
+ return g(`wrote claude.${t}: ${n} to ${o}`), { ...e, claude: { ...e.claude, [t]: n } };
899
939
  }
900
- function Tn(e, t) {
901
- const n = _((o) => {
940
+ function Sn(e, t) {
941
+ const n = N((o) => {
902
942
  o.channel = { ...o.channel, bind: t };
903
943
  });
904
- return w(`wrote channel.bind: ${t} to ${n}`), { ...e, channel: { ...e.channel, bind: t } };
944
+ return g(`wrote channel.bind: ${t} to ${n}`), { ...e, channel: { ...e.channel, bind: t } };
905
945
  }
906
- const In = "https://generativelanguage.googleapis.com/v1beta/models", En = 3e3;
907
- async function Pn(e = {}) {
946
+ const Tn = "https://generativelanguage.googleapis.com/v1beta/models", An = 3e3;
947
+ async function Nn(e = {}) {
908
948
  var a;
909
949
  const {
910
950
  verify: t = !0,
911
951
  env: n = process.env,
912
952
  fetchImpl: o = fetch,
913
- timeoutMs: r = En
953
+ timeoutMs: r = An
914
954
  } = e, i = (a = n.GEMINI_API_KEY) == null ? void 0 : a.trim();
915
955
  if (!i)
916
956
  return "missing";
@@ -918,17 +958,17 @@ async function Pn(e = {}) {
918
958
  return "unverified";
919
959
  const s = new AbortController(), c = setTimeout(() => s.abort(), r);
920
960
  try {
921
- const l = await o(`${In}?key=${encodeURIComponent(i)}`, {
961
+ const u = await o(`${Tn}?key=${encodeURIComponent(i)}`, {
922
962
  signal: s.signal
923
963
  });
924
- return l.ok ? "valid" : l.status === 400 || l.status === 401 || l.status === 403 ? "invalid" : "unverified";
964
+ return u.ok ? "valid" : u.status === 400 || u.status === 401 || u.status === 403 ? "invalid" : "unverified";
925
965
  } catch {
926
966
  return "unverified";
927
967
  } finally {
928
968
  clearTimeout(c);
929
969
  }
930
970
  }
931
- function Dn(e) {
971
+ function _n(e) {
932
972
  switch (e) {
933
973
  case "valid":
934
974
  return null;
@@ -952,18 +992,18 @@ function Dn(e) {
952
992
  };
953
993
  }
954
994
  }
955
- function Sn(e) {
956
- const t = Dn(e);
957
- t && (t.level === "warn" ? $(t.title, t.detail) : w(t.title, t.detail));
995
+ function jn(e) {
996
+ const t = _n(e);
997
+ t && (t.level === "warn" ? C(t.title, t.detail) : g(t.title, t.detail));
958
998
  }
959
- const An = "https://api.openai.com/v1/models", _n = 3e3;
960
- async function On(e = {}) {
999
+ const On = "https://api.openai.com/v1/models", Un = 3e3;
1000
+ async function Mn(e = {}) {
961
1001
  var a;
962
1002
  const {
963
1003
  verify: t = !0,
964
1004
  env: n = process.env,
965
1005
  fetchImpl: o = fetch,
966
- timeoutMs: r = _n
1006
+ timeoutMs: r = Un
967
1007
  } = e, i = (a = n.OPENAI_API_KEY) == null ? void 0 : a.trim();
968
1008
  if (!i)
969
1009
  return "missing";
@@ -971,18 +1011,18 @@ async function On(e = {}) {
971
1011
  return "unverified";
972
1012
  const s = new AbortController(), c = setTimeout(() => s.abort(), r);
973
1013
  try {
974
- const l = await o(An, {
1014
+ const u = await o(On, {
975
1015
  headers: { authorization: `Bearer ${i}` },
976
1016
  signal: s.signal
977
1017
  });
978
- return l.ok ? "valid" : l.status === 401 || l.status === 403 ? "invalid" : "unverified";
1018
+ return u.ok ? "valid" : u.status === 401 || u.status === 403 ? "invalid" : "unverified";
979
1019
  } catch {
980
1020
  return "unverified";
981
1021
  } finally {
982
1022
  clearTimeout(c);
983
1023
  }
984
1024
  }
985
- function jn(e) {
1025
+ function Ln(e) {
986
1026
  switch (e) {
987
1027
  case "valid":
988
1028
  return null;
@@ -1008,91 +1048,89 @@ and compare that against the start of your real key. Until it's fixed, transcrip
1008
1048
  };
1009
1049
  }
1010
1050
  }
1011
- function Nn(e) {
1012
- const t = jn(e);
1013
- t && (t.level === "warn" ? $(t.title, t.detail) : w(t.title, t.detail));
1051
+ function Bn(e) {
1052
+ const t = Ln(e);
1053
+ t && (t.level === "warn" ? C(t.title, t.detail) : g(t.title, t.detail));
1014
1054
  }
1015
- const he = "0.5.0";
1016
- function Un(e) {
1017
- const t = (process.env.PATH ?? "").split(gt).filter(Boolean), n = process.platform === "win32" ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";") : [""];
1055
+ const me = "0.6.0";
1056
+ function Rn(e) {
1057
+ const t = (process.env.PATH ?? "").split(vt).filter(Boolean), n = process.platform === "win32" ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";") : [""];
1018
1058
  for (const o of t)
1019
1059
  for (const r of n)
1020
1060
  try {
1021
- return kt(d(o, e + r), xt.X_OK), !0;
1061
+ return It(h(o, e + r), Et.X_OK), !0;
1022
1062
  } catch {
1023
1063
  }
1024
1064
  return !1;
1025
1065
  }
1026
- const Ln = "@habemus-papadum/aiui-claude-channel", Mn = "@habemus-papadum/aiui-claude-plugin", Te = "aiui";
1027
- async function Rn(e = []) {
1028
- var ge, be;
1029
- const t = de(e), { tag: n, passthrough: o } = t, r = rt(o);
1066
+ const Hn = "@habemus-papadum/aiui-claude-channel", Fn = "@habemus-papadum/aiui-claude-plugin", Pe = "aiui";
1067
+ async function Vn(e = []) {
1068
+ var ye;
1069
+ const t = pe(e), { tag: n, passthrough: o } = t, r = at(o);
1030
1070
  if (r) {
1031
- r === "help" ? Hn() : console.log(`aiui ${he}`), await Bn(o);
1071
+ r === "help" ? Kn() : console.log(`aiui ${me}`), await Gn(o);
1032
1072
  return;
1033
1073
  }
1034
- let i = S();
1035
- const s = Vn(o) && !ie();
1036
- s && (i = await xn(i));
1037
- const c = await On({ verify: s });
1038
- s && Nn(c);
1039
- const a = await Pn({ verify: s });
1040
- if (s && Sn(a), !ct())
1074
+ let i = P();
1075
+ const s = Wn(o) && !ce();
1076
+ s && (i = await Dn(i));
1077
+ const c = await Mn({ verify: s });
1078
+ s && Bn(c);
1079
+ const a = await Nn({ verify: s });
1080
+ if (s && jn(a), !dt())
1041
1081
  return;
1042
- const l = C(V(Mn), "marketplace", "plugins"), p = J(Ln), f = [...p.args, "mcp"];
1082
+ const u = x(K(Fn), "marketplace", "plugins"), m = J(Hn), f = [...m.args, "mcp"];
1043
1083
  n && f.push("--tag", n);
1044
- const m = it({ config: i, bind: t.bind });
1045
- f.push(...st(m));
1046
- const g = {
1047
- [Te]: { command: p.command, args: f }
1084
+ const p = ct({ config: i, bind: t.bind });
1085
+ f.push(...lt(p));
1086
+ const w = {
1087
+ [Pe]: { command: m.command, args: f }
1048
1088
  };
1049
- let y = { enabled: !1 };
1089
+ let b = { enabled: !1 };
1050
1090
  if (qe(t, i.chrome)) {
1051
- const X = {
1091
+ const ee = {
1052
1092
  ...i.chrome,
1053
1093
  ...t.browserUrl ? { browserUrl: t.browserUrl } : {}
1054
- }, ye = await Fn(t, X, s);
1055
- g[Ht] = ye.entry, y = ye.info;
1094
+ }, ve = await Yn(t, ee, s);
1095
+ w[Lt] = ve.entry, b = ve.info;
1056
1096
  }
1057
- const I = {
1097
+ const $ = {
1058
1098
  launcher: "aiui claude",
1059
- chromeDevtools: y,
1099
+ chromeDevtools: b,
1060
1100
  openaiKey: c,
1061
1101
  geminiKey: a
1062
1102
  };
1063
- f.push("--launch-info", JSON.stringify(I));
1064
- const h = JSON.stringify({ mcpServers: g }), me = [d(l, "aiui"), d(l, "frontend-design")];
1065
- y.enabled && me.push(d(l, "session-browser"));
1066
- const mt = [
1067
- ...((ge = i.claude) == null ? void 0 : ge.skipPermissions) ?? !0 ? ["--dangerously-skip-permissions"] : [],
1103
+ f.push("--launch-info", JSON.stringify($));
1104
+ const d = JSON.stringify({ mcpServers: w }), R = [h(u, "aiui"), h(u, "frontend-design")];
1105
+ b.enabled && R.push(h(u, "session-browser"));
1106
+ const bt = [
1107
+ ...((ye = i.claude) == null ? void 0 : ye.skipPermissions) ?? !0 ? ["--dangerously-skip-permissions"] : [],
1068
1108
  "--mcp-config",
1069
- h,
1070
- ...me.flatMap((X) => ["--plugin-dir", X]),
1109
+ d,
1110
+ ...R.flatMap((ee) => ["--plugin-dir", ee]),
1071
1111
  // Custom channels are a research preview and not on the approved allowlist,
1072
1112
  // so opt this session into loading ours as a development channel.
1073
1113
  "--dangerously-load-development-channels",
1074
- `server:${Te}`
1075
- ];
1076
- s && (((be = i.claude) == null ? void 0 : be.enterNudge) ?? !0) && vn();
1077
- const we = await T("claude", [...mt, ...o], {
1114
+ `server:${Pe}`
1115
+ ], be = await E("claude", [...bt, ...o], {
1078
1116
  stdio: "inherit",
1079
1117
  reject: !1
1080
1118
  });
1081
- we.exitCode && (process.exitCode = we.exitCode);
1119
+ be.exitCode && (process.exitCode = be.exitCode);
1082
1120
  }
1083
- function ct() {
1084
- return Un("claude") ? !0 : (b(
1121
+ function dt() {
1122
+ return Rn("claude") ? !0 : (y(
1085
1123
  "`claude` was not found on your PATH",
1086
1124
  "Install Claude Code and make sure the `claude` command is available, then try again."
1087
1125
  ), process.exitCode = 1, !1);
1088
1126
  }
1089
- async function Bn(e) {
1090
- if (!ct())
1127
+ async function Gn(e) {
1128
+ if (!dt())
1091
1129
  return;
1092
- const t = await T("claude", e, { stdio: "inherit", reject: !1 });
1130
+ const t = await E("claude", e, { stdio: "inherit", reject: !1 });
1093
1131
  t.exitCode && (process.exitCode = t.exitCode);
1094
1132
  }
1095
- function Hn() {
1133
+ function Kn() {
1096
1134
  console.log(`aiui claude — launch Claude Code wired with the aiui channel, plugin, and browser MCP
1097
1135
 
1098
1136
  aiui's own flags (everything else forwards to claude verbatim):
@@ -1115,22 +1153,23 @@ Durable settings live in config.json (project .aiui-cache/ + user cache) — see
1115
1153
  Configuration guide. What follows is claude's own --help:
1116
1154
  `);
1117
1155
  }
1118
- async function Fn(e, t, n) {
1156
+ async function Yn(e, t, n) {
1119
1157
  if (t.browserUrl)
1120
1158
  return {
1121
- entry: Z(t.browserUrl),
1159
+ entry: te(t.browserUrl),
1122
1160
  info: { enabled: !0, connection: "attach", browserUrl: t.browserUrl }
1123
1161
  };
1124
- let o = { ...t }, r = x(e, o);
1162
+ const o = t;
1163
+ let r = T(e, o);
1125
1164
  if (r.mode === "attach") {
1126
1165
  const a = await U(r.userDataDir);
1127
1166
  if (a)
1128
- return B(
1167
+ return V(
1129
1168
  r.userDataDir,
1130
1169
  j().state === "ready",
1131
- $
1170
+ C
1132
1171
  ), {
1133
- entry: Z(a.browserUrl),
1172
+ entry: te(a.browserUrl),
1134
1173
  info: {
1135
1174
  enabled: !0,
1136
1175
  connection: "attach",
@@ -1140,12 +1179,16 @@ async function Fn(e, t, n) {
1140
1179
  };
1141
1180
  }
1142
1181
  if (!o.executablePath && !o.channel) {
1143
- const a = await We({ mode: o.forTesting ?? "prompt", interactive: n });
1144
- a && (o = { ...o, executablePath: a }, r = x(e, o));
1182
+ const a = await et({
1183
+ flavor: B(o),
1184
+ mode: le(o),
1185
+ interactive: n
1186
+ });
1187
+ a && (r = { ...r, executablePath: a });
1145
1188
  }
1146
- G(r.userDataDir, { recursive: !0 });
1189
+ z(r.userDataDir, { recursive: !0 });
1147
1190
  const i = j(), s = i.state === "ready" ? [i.dir] : [];
1148
- B(r.userDataDir, i.state === "ready", $), n && (Xe(r, s), Je(i));
1191
+ V(r.userDataDir, i.state === "ready", C), n && (Xe(r, s), Je(i));
1149
1192
  const c = {
1150
1193
  userDataDir: r.userDataDir,
1151
1194
  executablePath: r.executablePath,
@@ -1155,15 +1198,15 @@ async function Fn(e, t, n) {
1155
1198
  };
1156
1199
  if (r.mode === "attach" && n)
1157
1200
  try {
1158
- const a = await je({
1159
- binary: Oe(r),
1201
+ const a = await Me({
1202
+ binary: Ue(r),
1160
1203
  userDataDir: r.userDataDir,
1161
1204
  debugPort: r.debugPort,
1162
1205
  extensionDirs: s,
1163
1206
  headless: r.headless
1164
1207
  });
1165
1208
  return {
1166
- entry: Z(a.browserUrl),
1209
+ entry: te(a.browserUrl),
1167
1210
  info: {
1168
1211
  enabled: !0,
1169
1212
  connection: "attach",
@@ -1172,60 +1215,60 @@ async function Fn(e, t, n) {
1172
1215
  }
1173
1216
  };
1174
1217
  } catch (a) {
1175
- $(
1218
+ C(
1176
1219
  "couldn't start the session browser — falling back to a browser private to the MCP",
1177
1220
  a instanceof Error ? a.message : String(a)
1178
1221
  );
1179
1222
  }
1180
1223
  return {
1181
- entry: qt(r, s),
1224
+ entry: zt(r, s),
1182
1225
  info: { enabled: !0, connection: "launch", ...c }
1183
1226
  };
1184
1227
  }
1185
- function Vn(e) {
1228
+ function Wn(e) {
1186
1229
  return !process.stdin.isTTY || !process.stdout.isTTY ? !1 : !e.some((t) => t === "-p" || t === "--print");
1187
1230
  }
1188
- function Gn(e = process.cwd()) {
1231
+ function zn(e = process.cwd()) {
1189
1232
  return {
1190
- project: Be(e),
1191
- user: F(void 0, { create: !1 }),
1192
- browser: A(!1)
1233
+ project: Le(e),
1234
+ user: Y(void 0, { create: !1 }),
1235
+ browsers: Xt(!1)
1193
1236
  };
1194
1237
  }
1195
- function Kn(e, t) {
1238
+ function qn(e, t) {
1196
1239
  const n = [];
1197
1240
  return e.userOnly || n.push({ label: "project cache", path: t.project }), e.projectOnly || n.push(
1198
1241
  e.keepBrowser ? {
1199
- label: "user cache (keeping Chrome for Testing)",
1242
+ label: "user cache (keeping the managed browsers)",
1200
1243
  path: t.user,
1201
- keep: [t.browser]
1244
+ keep: t.browsers
1202
1245
  } : { label: "user cache", path: t.user }
1203
1246
  ), n;
1204
1247
  }
1205
- function Yn(e) {
1248
+ function Jn(e) {
1206
1249
  var o;
1207
1250
  if (!v(e.path))
1208
1251
  return [];
1209
1252
  if (!((o = e.keep) != null && o.length))
1210
1253
  return [e.path];
1211
- const t = new Set(e.keep.map((r) => C(r)));
1254
+ const t = new Set(e.keep.map((r) => x(r)));
1212
1255
  let n;
1213
1256
  try {
1214
- n = Y(e.path);
1257
+ n = q(e.path);
1215
1258
  } catch {
1216
1259
  return [];
1217
1260
  }
1218
- return n.map((r) => C(d(e.path, r))).filter((r) => !t.has(r));
1261
+ return n.map((r) => x(h(e.path, r))).filter((r) => !t.has(r));
1219
1262
  }
1220
- async function Wn(e = {}) {
1263
+ async function Xn(e = {}) {
1221
1264
  if (e.projectOnly && e.userOnly) {
1222
- b(
1265
+ y(
1223
1266
  "pass at most one of --project-only / --user-only",
1224
1267
  "with neither, `aiui clean` removes both"
1225
1268
  ), process.exitCode = 1;
1226
1269
  return;
1227
1270
  }
1228
- const t = process.cwd(), o = Kn(e, Gn(t)).map((f) => ({ target: f, paths: Yn(f) })).filter((f) => f.paths.length > 0);
1271
+ const t = process.cwd(), o = qn(e, zn(t)).map((f) => ({ target: f, paths: Jn(f) })).filter((f) => f.paths.length > 0);
1229
1272
  if (o.length === 0) {
1230
1273
  console.log("nothing to clean — no aiui state here or in the user cache.");
1231
1274
  return;
@@ -1233,39 +1276,39 @@ async function Wn(e = {}) {
1233
1276
  let r = 0;
1234
1277
  console.log(`aiui clean will remove:
1235
1278
  `);
1236
- for (const { target: f, paths: m } of o) {
1237
- const g = m.reduce((y, I) => y + re(I), 0);
1238
- r += g, console.log(` ${Q(g).padStart(9)} ${f.label}`), console.log(` ${" ".repeat(9)} ${u.dim(f.path)}`);
1279
+ for (const { target: f, paths: p } of o) {
1280
+ const w = p.reduce((b, $) => b + ae($), 0);
1281
+ r += w, console.log(` ${ne(w).padStart(9)} ${f.label}`), console.log(` ${" ".repeat(9)} ${l.dim(f.path)}`);
1239
1282
  }
1240
1283
  console.log(`
1241
- ${Q(r).padStart(9)} total
1284
+ ${ne(r).padStart(9)} total
1242
1285
  `);
1243
1286
  const i = !e.projectOnly, s = i && !e.keepBrowser, c = [
1244
1287
  "traces and session-browser logins are cleared",
1245
1288
  i && "the Claude permission prompt (claude.skipPermissions) returns on next launch",
1246
- s && "Chrome for Testing re-downloads (~160 MB) on the next `aiui claude`"
1289
+ s && "the managed browser re-downloads (~150-160 MB) on the next `aiui claude`"
1247
1290
  ].filter((f) => !!f);
1248
1291
  console.log("This resets aiui toward a fresh install:");
1249
1292
  for (const f of c)
1250
1293
  console.log(` • ${f}`);
1251
1294
  console.log("");
1252
- const a = M(t);
1253
- if (a.length && $(
1295
+ const a = L(t);
1296
+ if (a.length && C(
1254
1297
  `${a.length} aiui session${a.length === 1 ? "" : "s"} still running`,
1255
1298
  "stop them first — a live session rewrites its registry entry as it exits, and an open browser can lock files being deleted"
1256
1299
  ), e.dryRun) {
1257
- w("dry run — nothing was deleted");
1300
+ g("dry run — nothing was deleted");
1258
1301
  return;
1259
1302
  }
1260
1303
  if (!e.yes) {
1261
1304
  if (!process.stdin.isTTY) {
1262
- b(
1305
+ y(
1263
1306
  "refusing to delete without confirmation",
1264
1307
  "re-run with --yes for a non-interactive clean, or from a terminal"
1265
1308
  ), process.exitCode = 1;
1266
1309
  return;
1267
1310
  }
1268
- if (await W(
1311
+ if (await X(
1269
1312
  "Delete these now?",
1270
1313
  [
1271
1314
  { key: "y", label: "yes, delete" },
@@ -1277,28 +1320,28 @@ async function Wn(e = {}) {
1277
1320
  return;
1278
1321
  }
1279
1322
  }
1280
- let l = 0, p = 0;
1323
+ let u = 0, m = 0;
1281
1324
  for (const { paths: f } of o)
1282
- for (const m of f) {
1283
- const g = re(m);
1325
+ for (const p of f) {
1326
+ const w = ae(p);
1284
1327
  try {
1285
- Tt(m, { recursive: !0, force: !0 }), l += g;
1286
- } catch (y) {
1287
- p++, $(
1288
- `could not remove ${m}`,
1289
- y instanceof Error ? y.message : String(y)
1328
+ Pt(p, { recursive: !0, force: !0 }), u += w;
1329
+ } catch (b) {
1330
+ m++, C(
1331
+ `could not remove ${p}`,
1332
+ b instanceof Error ? b.message : String(b)
1290
1333
  );
1291
1334
  }
1292
1335
  }
1293
- p && $(
1294
- `${p} path${p === 1 ? "" : "s"} could not be deleted`,
1336
+ m && C(
1337
+ `${m} path${m === 1 ? "" : "s"} could not be deleted`,
1295
1338
  "a running browser can lock its files — close the session browser and re-run"
1296
- ), console.log(`clean complete — freed ~${Q(l)}.`);
1339
+ ), console.log(`clean complete — freed ~${ne(u)}.`);
1297
1340
  }
1298
- function re(e) {
1341
+ function ae(e) {
1299
1342
  let t;
1300
1343
  try {
1301
- t = It(e);
1344
+ t = Dt(e);
1302
1345
  } catch {
1303
1346
  return 0;
1304
1347
  }
@@ -1306,16 +1349,16 @@ function re(e) {
1306
1349
  return t.size;
1307
1350
  let n;
1308
1351
  try {
1309
- n = Y(e);
1352
+ n = q(e);
1310
1353
  } catch {
1311
1354
  return 0;
1312
1355
  }
1313
1356
  let o = 0;
1314
1357
  for (const r of n)
1315
- o += re(d(e, r));
1358
+ o += ae(h(e, r));
1316
1359
  return o;
1317
1360
  }
1318
- function Q(e) {
1361
+ function ne(e) {
1319
1362
  if (e < 1024)
1320
1363
  return `${e} B`;
1321
1364
  const t = ["KB", "MB", "GB", "TB"];
@@ -1324,35 +1367,35 @@ function Q(e) {
1324
1367
  n /= 1024, o++;
1325
1368
  return `${n.toFixed(1)} ${t[o]}`;
1326
1369
  }
1327
- function D(e = process.cwd()) {
1328
- const t = St(e);
1370
+ function S(e = process.cwd()) {
1371
+ const t = At(e);
1329
1372
  return {
1330
1373
  paths: t,
1331
- user: ne(t.user) ?? {},
1332
- project: ne(t.project) ?? {}
1374
+ user: ie(t.user) ?? {},
1375
+ project: ie(t.project) ?? {}
1333
1376
  };
1334
1377
  }
1335
- function fe(e) {
1336
- return Me().map((t) => {
1337
- const n = Ie(e.user, t), o = Ie(e.project, t), r = o ?? n, i = o !== void 0 ? "project" : n !== void 0 ? "user" : t.field.default !== void 0 ? "default" : "unset";
1378
+ function we(e) {
1379
+ return Ve().map((t) => {
1380
+ const n = De(e.user, t), o = De(e.project, t), r = o ?? n, i = o !== void 0 ? "project" : n !== void 0 ? "user" : t.field.default !== void 0 ? "default" : "unset";
1338
1381
  return { ...t, userValue: n, projectValue: o, effective: r, source: i };
1339
1382
  });
1340
1383
  }
1341
- function Ie(e, t) {
1384
+ function De(e, t) {
1342
1385
  var o;
1343
1386
  return (o = e[t.section.name]) == null ? void 0 : o[t.field.key];
1344
1387
  }
1345
- function pe(e, t) {
1346
- const n = fe(t).find((o) => o.path === e);
1347
- return n || (b(
1388
+ function ge(e, t) {
1389
+ const n = we(t).find((o) => o.path === e);
1390
+ return n || (y(
1348
1391
  `unknown config key: ${e}`,
1349
1392
  `Known keys:
1350
- ${Me().map((o) => o.path).join(`
1393
+ ${Ve().map((o) => o.path).join(`
1351
1394
  `)}`
1352
1395
  ), process.exitCode = 1), n;
1353
1396
  }
1354
- function qn(e = {}, t = process.cwd()) {
1355
- const n = D(t), o = fe(n);
1397
+ function Zn(e = {}, t = process.cwd()) {
1398
+ const n = S(t), o = we(n);
1356
1399
  if (e.json) {
1357
1400
  console.log(
1358
1401
  JSON.stringify(
@@ -1363,7 +1406,7 @@ function qn(e = {}, t = process.cwd()) {
1363
1406
  },
1364
1407
  user: n.user,
1365
1408
  project: n.project,
1366
- effective: Dt(n.user, n.project)
1409
+ effective: Tt(n.user, n.project)
1367
1410
  },
1368
1411
  null,
1369
1412
  2
@@ -1371,95 +1414,95 @@ function qn(e = {}, t = process.cwd()) {
1371
1414
  );
1372
1415
  return;
1373
1416
  }
1374
- console.log(`user: ${n.paths.user}${Ee(n.paths.user)}`), console.log(`project: ${n.paths.project}${Ee(n.paths.project)}`);
1417
+ console.log(`user: ${n.paths.user}${Se(n.paths.user)}`), console.log(`project: ${n.paths.project}${Se(n.paths.project)}`);
1375
1418
  const r = Math.max(...o.map((s) => s.path.length));
1376
1419
  let i = "";
1377
1420
  for (const s of o)
1378
1421
  s.section.name !== i && (i = s.section.name, console.log(`
1379
- ${u.bold(i)} ${u.dim(`— ${s.section.summary}`)}`)), console.log(` ${s.path.padEnd(r + 2)}${lt(s)}`);
1422
+ ${l.bold(i)} ${l.dim(`— ${s.section.summary}`)}`)), console.log(` ${s.path.padEnd(r + 2)}${ht(s)}`);
1380
1423
  console.log(
1381
- u.dim(
1424
+ l.dim(
1382
1425
  "\nProject beats user per key; CLI flags beat both. `aiui config` browses the docs interactively."
1383
1426
  )
1384
1427
  );
1385
1428
  }
1386
- function Ee(e) {
1387
- return v(e) ? "" : u.dim(" (not present)");
1429
+ function Se(e) {
1430
+ return v(e) ? "" : l.dim(" (not present)");
1388
1431
  }
1389
- function lt(e) {
1390
- return e.effective !== void 0 ? `${u.cyan(k(e.effective))} ${u.dim(`(${e.source})`)}` : u.dim(
1391
- e.field.default !== void 0 ? `default: ${k(e.field.default)}` : "unset"
1432
+ function ht(e) {
1433
+ return e.effective !== void 0 ? `${l.cyan(I(e.effective))} ${l.dim(`(${e.source})`)}` : l.dim(
1434
+ e.field.default !== void 0 ? `default: ${I(e.field.default)}` : "unset"
1392
1435
  );
1393
1436
  }
1394
- function zn(e, t = process.cwd()) {
1395
- const n = D(t), o = pe(e, n);
1437
+ function Qn(e, t = process.cwd()) {
1438
+ const n = S(t), o = ge(e, n);
1396
1439
  if (o) {
1397
1440
  if (o.effective !== void 0) {
1398
1441
  console.log(String(o.effective));
1399
1442
  const r = o.source === "project" ? n.paths.project : n.paths.user;
1400
- console.error(u.dim(`# set in the ${o.source} config: ${r}`));
1443
+ console.error(l.dim(`# set in the ${o.source} config: ${r}`));
1401
1444
  return;
1402
1445
  }
1403
1446
  if (o.field.default !== void 0) {
1404
- console.log(String(o.field.default)), console.error(u.dim(`# built-in default — ${ee(o.field)}`));
1447
+ console.log(String(o.field.default)), console.error(l.dim(`# built-in default — ${oe(o.field)}`));
1405
1448
  return;
1406
1449
  }
1407
1450
  console.error(
1408
- u.dim(`# not set in any config file — default: ${ee(o.field)}`)
1451
+ l.dim(`# not set in any config file — default: ${oe(o.field)}`)
1409
1452
  );
1410
1453
  }
1411
1454
  }
1412
- function Jn(e, t, n = {}, o = process.cwd()) {
1413
- const r = D(o), i = pe(e, r);
1455
+ function eo(e, t, n = {}, o = process.cwd()) {
1456
+ const r = S(o), i = ge(e, r);
1414
1457
  if (!i)
1415
1458
  return;
1416
- const s = te(i.field, t);
1459
+ const s = re(i.field, t);
1417
1460
  if ("error" in s) {
1418
- b(`invalid value for ${i.path}: ${t}`, s.error), process.exitCode = 1;
1461
+ y(`invalid value for ${i.path}: ${t}`, s.error), process.exitCode = 1;
1419
1462
  return;
1420
1463
  }
1421
- ut(r, i, s.value, n.project ? "project" : "user");
1464
+ ft(r, i, s.value, n.project ? "project" : "user");
1422
1465
  }
1423
- function ut(e, t, n, o) {
1424
- const r = Re(e.paths[o], (i) => {
1466
+ function ft(e, t, n, o) {
1467
+ const r = Ge(e.paths[o], (i) => {
1425
1468
  const s = i;
1426
1469
  s[t.section.name] = { ...s[t.section.name], [t.field.key]: n };
1427
1470
  });
1428
- w(`wrote ${t.path}: ${k(n)} to ${r}`);
1471
+ g(`wrote ${t.path}: ${I(n)} to ${r}`);
1429
1472
  }
1430
- function Xn(e, t = {}, n = process.cwd()) {
1431
- const o = D(n), r = pe(e, o);
1432
- r && dt(o, r, t.project ? "project" : "user");
1473
+ function to(e, t = {}, n = process.cwd()) {
1474
+ const o = S(n), r = ge(e, o);
1475
+ r && pt(o, r, t.project ? "project" : "user");
1433
1476
  }
1434
- function dt(e, t, n) {
1477
+ function pt(e, t, n) {
1435
1478
  var c;
1436
1479
  const o = e.paths[n];
1437
- if (((c = (ne(o) ?? {})[t.section.name]) == null ? void 0 : c[t.field.key]) === void 0) {
1438
- w(`${t.path} is not set in the ${n} config (${o})`);
1480
+ if (((c = (ie(o) ?? {})[t.section.name]) == null ? void 0 : c[t.field.key]) === void 0) {
1481
+ g(`${t.path} is not set in the ${n} config (${o})`);
1439
1482
  return;
1440
1483
  }
1441
- const s = Re(o, (a) => {
1442
- const l = a, p = { ...l[t.section.name] };
1443
- delete p[t.field.key], Object.keys(p).length === 0 ? delete l[t.section.name] : l[t.section.name] = p;
1484
+ const s = Ge(o, (a) => {
1485
+ const u = a, m = { ...u[t.section.name] };
1486
+ delete m[t.field.key], Object.keys(m).length === 0 ? delete u[t.section.name] : u[t.section.name] = m;
1444
1487
  });
1445
- w(`removed ${t.path} from ${s}`);
1488
+ g(`removed ${t.path} from ${s}`);
1446
1489
  }
1447
- async function Pe(e = process.cwd()) {
1490
+ async function Te(e = process.cwd()) {
1448
1491
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
1449
- b(
1492
+ y(
1450
1493
  "aiui config tui needs an interactive terminal",
1451
1494
  "In scripts and non-TTY sessions use `aiui config show` (or `show --json`)."
1452
1495
  ), process.exitCode = 1;
1453
1496
  return;
1454
1497
  }
1455
- const t = D(e).paths;
1456
- console.log(u.dim(`user: ${Se(t.user)}`)), console.log(u.dim(`project: ${Se(t.project)}`));
1498
+ const t = S(e).paths;
1499
+ console.log(l.dim(`user: ${Ne(t.user)}`)), console.log(l.dim(`project: ${Ne(t.project)}`));
1457
1500
  try {
1458
1501
  for (; ; ) {
1459
- const n = D(e), o = await Zn(n);
1502
+ const n = S(e), o = await no(n);
1460
1503
  if (!o)
1461
1504
  return;
1462
- await eo(n, o);
1505
+ await ro(n, o);
1463
1506
  }
1464
1507
  } catch (n) {
1465
1508
  if (n instanceof Error && n.name === "ExitPromptError")
@@ -1467,35 +1510,35 @@ async function Pe(e = process.cwd()) {
1467
1510
  throw n;
1468
1511
  }
1469
1512
  }
1470
- async function Zn(e) {
1471
- const t = fe(e), n = Math.max(...t.map((r) => r.path.length)) + 2, o = [];
1472
- for (const r of At) {
1473
- o.push(new oe(u.dim(`── ${r.name} — ${r.summary}`)));
1513
+ async function no(e) {
1514
+ const t = we(e), n = Math.max(...t.map((r) => r.path.length)) + 2, o = [];
1515
+ for (const r of Nt) {
1516
+ o.push(new se(l.dim(`── ${r.name} — ${r.summary}`)));
1474
1517
  for (const i of t.filter((s) => s.section.name === r.name))
1475
1518
  o.push({
1476
- name: `${i.path.padEnd(n)}${lt(i)}`,
1519
+ name: `${i.path.padEnd(n)}${ht(i)}`,
1477
1520
  value: i,
1478
- description: Qn(i)
1521
+ description: oo(i)
1479
1522
  });
1480
1523
  }
1481
- return o.push(new oe(" ")), o.push({ name: "exit", value: void 0, description: "Leave the config browser." }), O({
1524
+ return o.push(new se(" ")), o.push({ name: "exit", value: void 0, description: "Leave the config browser." }), _({
1482
1525
  message: "aiui config",
1483
1526
  choices: o,
1484
1527
  pageSize: o.length,
1485
1528
  loop: !1
1486
1529
  });
1487
1530
  }
1488
- function Qn(e) {
1489
- const t = [u.bold(e.field.summary)];
1490
- return e.field.doc && t.push(no(e.field.doc, 76)), t.push(""), e.field.type === "enum" && t.push(`allowed: ${(e.field.values ?? []).join(" | ")}`), t.push(`default: ${ee(e.field)}`), t.push(`user: ${De(e.userValue)}`), t.push(`project: ${De(e.projectValue)}`), t.push(
1491
- `effective: ${e.effective !== void 0 ? `${k(e.effective)} (from the ${e.source} config)` : "the built-in default"}`
1531
+ function oo(e) {
1532
+ const t = [l.bold(e.field.summary)];
1533
+ return e.field.doc && t.push(so(e.field.doc, 76)), t.push(""), e.field.type === "enum" && t.push(`allowed: ${(e.field.values ?? []).join(" | ")}`), t.push(`default: ${oe(e.field)}`), t.push(`user: ${Ae(e.userValue)}`), t.push(`project: ${Ae(e.projectValue)}`), t.push(
1534
+ `effective: ${e.effective !== void 0 ? `${I(e.effective)} (from the ${e.source} config)` : "the built-in default"}`
1492
1535
  ), t.join(`
1493
1536
  `);
1494
1537
  }
1495
- function De(e) {
1496
- return e === void 0 ? u.dim("(not set)") : k(e);
1538
+ function Ae(e) {
1539
+ return e === void 0 ? l.dim("(not set)") : I(e);
1497
1540
  }
1498
- async function eo(e, t) {
1541
+ async function ro(e, t) {
1499
1542
  const n = [
1500
1543
  {
1501
1544
  name: "set in the user config",
@@ -1511,13 +1554,13 @@ This project only; the file may be shared or committed by a team.`
1511
1554
  }
1512
1555
  ];
1513
1556
  t.userValue !== void 0 && n.push({
1514
- name: `unset in the user config (currently ${k(t.userValue)})`,
1557
+ name: `unset in the user config (currently ${I(t.userValue)})`,
1515
1558
  value: "unset-user"
1516
1559
  }), t.projectValue !== void 0 && n.push({
1517
- name: `unset in the project config (currently ${k(t.projectValue)})`,
1560
+ name: `unset in the project config (currently ${I(t.projectValue)})`,
1518
1561
  value: "unset-project"
1519
- }), n.push(new oe()), n.push({ name: "back", value: "back" });
1520
- const o = await O({
1562
+ }), n.push(new se()), n.push({ name: "back", value: "back" });
1563
+ const o = await _({
1521
1564
  message: `${t.path} — ${t.field.summary}`,
1522
1565
  choices: n
1523
1566
  });
@@ -1525,45 +1568,45 @@ This project only; the file may be shared or committed by a team.`
1525
1568
  return;
1526
1569
  const r = o.endsWith("project") ? "project" : "user";
1527
1570
  if (o.startsWith("unset")) {
1528
- dt(e, t, r);
1571
+ pt(e, t, r);
1529
1572
  return;
1530
1573
  }
1531
- const i = await to(t);
1532
- i !== void 0 && ut(e, t, i, r);
1574
+ const i = await io(t);
1575
+ i !== void 0 && ft(e, t, i, r);
1533
1576
  }
1534
- async function to(e) {
1577
+ async function io(e) {
1535
1578
  const t = (r) => r === e.effective ? " (current)" : r === e.field.default ? " (default)" : "";
1536
1579
  if (e.field.type === "boolean")
1537
- return O({
1580
+ return _({
1538
1581
  message: `${e.path} =`,
1539
1582
  choices: [!0, !1].map((r) => ({
1540
- name: `${r}${u.dim(t(r))}`,
1583
+ name: `${r}${l.dim(t(r))}`,
1541
1584
  value: r
1542
1585
  }))
1543
1586
  });
1544
1587
  if (e.field.type === "enum")
1545
- return O({
1588
+ return _({
1546
1589
  message: `${e.path} =`,
1547
1590
  choices: (e.field.values ?? []).map((r) => ({
1548
- name: `${r}${u.dim(t(r))}`,
1591
+ name: `${r}${l.dim(t(r))}`,
1549
1592
  value: r
1550
1593
  }))
1551
1594
  });
1552
- const n = await jt({
1595
+ const n = await Ut({
1553
1596
  message: `${e.path} = `,
1554
1597
  default: e.effective !== void 0 ? String(e.effective) : void 0,
1555
1598
  validate: (r) => {
1556
- const i = te(e.field, r);
1599
+ const i = re(e.field, r);
1557
1600
  return "error" in i ? i.error : !0;
1558
1601
  }
1559
- }), o = te(e.field, n);
1602
+ }), o = re(e.field, n);
1560
1603
  return "error" in o ? void 0 : o.value;
1561
1604
  }
1562
- function Se(e) {
1563
- const t = se();
1605
+ function Ne(e) {
1606
+ const t = ue();
1564
1607
  return e.startsWith(t) ? `~${e.slice(t.length)}` : e;
1565
1608
  }
1566
- function no(e, t) {
1609
+ function so(e, t) {
1567
1610
  const n = [];
1568
1611
  let o = "";
1569
1612
  for (const r of e.split(/\s+/))
@@ -1571,7 +1614,7 @@ function no(e, t) {
1571
1614
  return o && n.push(o), n.join(`
1572
1615
  `);
1573
1616
  }
1574
- function oo(e, t) {
1617
+ function ao(e, t) {
1575
1618
  if (t !== void 0) {
1576
1619
  const n = e.find((o) => o.tag === t);
1577
1620
  if (!n) {
@@ -1584,42 +1627,42 @@ function oo(e, t) {
1584
1627
  }
1585
1628
  return e.length > 0 ? { select: e } : {};
1586
1629
  }
1587
- const ro = "vite";
1588
- async function io(e = []) {
1589
- const t = de(e), { mcp: n, tag: o, passthrough: r } = t, i = rt(r);
1630
+ const co = "vite";
1631
+ async function lo(e = []) {
1632
+ const t = pe(e), { mcp: n, tag: o, passthrough: r } = t, i = at(r);
1590
1633
  if (i) {
1591
- i === "help" ? uo() : console.log(`aiui ${he}`), await lo(r);
1634
+ i === "help" ? mo() : console.log(`aiui ${me}`), await po(r);
1592
1635
  return;
1593
1636
  }
1594
- (n !== void 0 || o !== void 0) && $(
1637
+ (n !== void 0 || o !== void 0) && C(
1595
1638
  "aiui vite no longer connects the app to a channel",
1596
1639
  "--aiui-mcp / --aiui-tag are ignored. The app reaches the channel through the intent client served at /intent/, not a build-time port. (The standalone panel's own `pnpm dev` still selects a channel — that page is served on Vite's origin, not the channel's.)"
1597
1640
  );
1598
- const s = ft();
1641
+ const s = wt();
1599
1642
  if (!s)
1600
1643
  return;
1601
1644
  const c = {};
1602
1645
  process.stdout.isTTY && !("FORCE_COLOR" in process.env) && !("NO_COLOR" in process.env) && (c.FORCE_COLOR = "1");
1603
- const a = T(s.command, [...s.args, ...r], {
1646
+ const a = E(s.command, [...s.args, ...r], {
1604
1647
  stdio: ["inherit", "pipe", "inherit"],
1605
1648
  buffer: !1,
1606
1649
  reject: !1,
1607
1650
  env: c
1608
1651
  });
1609
- a.stdout && co(a.stdout, process.stdout, (p) => {
1610
- ht(p, t);
1652
+ a.stdout && fo(a.stdout, process.stdout, (m) => {
1653
+ mt(m, t);
1611
1654
  });
1612
- const l = await a;
1613
- l.exitCode && (process.exitCode = l.exitCode);
1655
+ const u = await a;
1656
+ u.exitCode && (process.exitCode = u.exitCode);
1614
1657
  }
1615
- const so = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
1616
- function ao(e) {
1617
- const n = e.replace(so, "").match(
1658
+ const uo = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
1659
+ function ho(e) {
1660
+ const n = e.replace(uo, "").match(
1618
1661
  /\bLocal:\s+(https?:\/\/(?:localhost|127\.0\.0\.1|\[::1\])(?::\d+)?\/?\S*)/
1619
1662
  );
1620
1663
  return n == null ? void 0 : n[1];
1621
1664
  }
1622
- function co(e, t, n) {
1665
+ function fo(e, t, n) {
1623
1666
  let o = "", r = !1;
1624
1667
  e.on("data", (i) => {
1625
1668
  if (t.write(i), !r) {
@@ -1630,7 +1673,7 @@ function co(e, t, n) {
1630
1673
  break;
1631
1674
  const c = o.slice(0, s);
1632
1675
  o = o.slice(s + 1);
1633
- const a = ao(c);
1676
+ const a = ho(c);
1634
1677
  if (a) {
1635
1678
  r = !0, o = "", n(a);
1636
1679
  return;
@@ -1640,16 +1683,16 @@ function co(e, t, n) {
1640
1683
  }
1641
1684
  });
1642
1685
  }
1643
- async function ht(e, t) {
1686
+ async function mt(e, t) {
1644
1687
  try {
1645
1688
  const n = {
1646
- ...S().chrome,
1689
+ ...P().chrome,
1647
1690
  ...t.browserUrl ? { browserUrl: t.browserUrl } : {}
1648
- }, o = vt(t, n);
1691
+ }, o = kt(t, n);
1649
1692
  if (o.kind === "skip")
1650
1693
  return;
1651
1694
  if (o.kind === "hint") {
1652
- w(
1695
+ g(
1653
1696
  `detected a headless environment (${o.reason}) — not opening a browser`,
1654
1697
  `Assuming the dev server's port is already forwarded, open ${e} in the browser
1655
1698
  on your local machine. (Pass --aiui-browser to open one here anyway.)`
@@ -1657,45 +1700,45 @@ on your local machine. (Pass --aiui-browser to open one here anyway.)`
1657
1700
  return;
1658
1701
  }
1659
1702
  if (n.browserUrl) {
1660
- await R(n.browserUrl, e), console.error(u.dim(`aiui: opened ${e} in the browser at ${n.browserUrl}`));
1703
+ await H(n.browserUrl, e), console.error(l.dim(`aiui: opened ${e} in the browser at ${n.browserUrl}`));
1661
1704
  return;
1662
1705
  }
1663
- const r = x(t, n), i = await U(r.userDataDir);
1664
- i ? (await R(i.browserUrl, e), console.error(u.dim(`aiui: opened ${e} in the session browser`))) : (await nt({
1706
+ const r = T(t, n), i = await U(r.userDataDir);
1707
+ i ? (await H(i.browserUrl, e), console.error(l.dim(`aiui: opened ${e} in the session browser`))) : (await it({
1665
1708
  flags: t,
1666
1709
  config: n,
1667
1710
  interactive: !1,
1668
1711
  startUrl: e
1669
- }), console.error(u.dim(`aiui: opened ${e} in a new session browser`)));
1712
+ }), console.error(l.dim(`aiui: opened ${e} in a new session browser`)));
1670
1713
  } catch (n) {
1671
- $(
1714
+ C(
1672
1715
  "couldn't open the app in the session browser — the dev server is unaffected",
1673
1716
  n instanceof Error ? n.message : String(n)
1674
1717
  );
1675
1718
  }
1676
1719
  }
1677
- function ft() {
1720
+ function wt() {
1678
1721
  try {
1679
- return J(ro);
1722
+ return J(co);
1680
1723
  } catch {
1681
- b(
1724
+ y(
1682
1725
  "Vite is not available",
1683
1726
  "`vite` should be installed as a dependency of aiui — try reinstalling."
1684
1727
  ), process.exitCode = 1;
1685
1728
  return;
1686
1729
  }
1687
1730
  }
1688
- async function lo(e) {
1689
- const t = ft();
1731
+ async function po(e) {
1732
+ const t = wt();
1690
1733
  if (!t)
1691
1734
  return;
1692
- const n = await T(t.command, [...t.args, ...e], {
1735
+ const n = await E(t.command, [...t.args, ...e], {
1693
1736
  stdio: "inherit",
1694
1737
  reject: !1
1695
1738
  });
1696
1739
  n.exitCode && (process.exitCode = n.exitCode);
1697
1740
  }
1698
- function uo() {
1741
+ function mo() {
1699
1742
  console.log(`aiui vite — launch Vite and open the app in the session browser
1700
1743
 
1701
1744
  aiui's own flags (everything else forwards to vite verbatim):
@@ -1715,35 +1758,35 @@ intent panel, served on Vite's own origin, is the exception: its \`pnpm dev\`
1715
1758
  selects a channel itself.) What follows is vite's own --help:
1716
1759
  `);
1717
1760
  }
1718
- async function ho(e = {}) {
1719
- const t = oo(M(), e.mcp);
1761
+ async function wo(e = {}) {
1762
+ const t = ao(L(), e.mcp);
1720
1763
  if (t.error) {
1721
- b("Could not resolve an aiui channel", t.error), process.exitCode = 1;
1764
+ y("Could not resolve an aiui channel", t.error), process.exitCode = 1;
1722
1765
  return;
1723
1766
  }
1724
- const n = t.select ? await He(t.select) : t.server;
1767
+ const n = t.select ? await Be(t.select) : t.server;
1725
1768
  if (!n) {
1726
1769
  console.log("No running aiui channel to open — start one with `aiui claude`."), process.exitCode = 1;
1727
1770
  return;
1728
1771
  }
1729
1772
  const o = `http://127.0.0.1:${n.port}/`;
1730
- console.log(`${u.cyan("aiui debug")} — the channel console`), console.log(` ${u.bold(o)}`), console.log(
1731
- u.dim(` channel "${n.tag}" (${n.cwd}) on port ${n.port}`) + u.dim(" — the dashboard links to the trace debugger at /__aiui/debug.")
1732
- ), e.open !== !1 && await ht(o, de([]));
1773
+ console.log(`${l.cyan("aiui debug")} — the channel console`), console.log(` ${l.bold(o)}`), console.log(
1774
+ l.dim(` channel "${n.tag}" (${n.cwd}) on port ${n.port}`) + l.dim(" — the dashboard links to the trace debugger at /__aiui/debug.")
1775
+ ), e.open !== !1 && await mt(o, pe([]));
1733
1776
  }
1734
- const Ae = [".env", ".env.local", ".env.dev", ".env.dev.local"];
1735
- function fo(e) {
1777
+ const _e = [".env", ".env.local", ".env.dev", ".env.dev.local"];
1778
+ function go(e) {
1736
1779
  let t = e;
1737
1780
  for (; ; ) {
1738
- if (v(d(t, "pnpm-workspace.yaml")) || v(d(t, ".git")))
1781
+ if (v(h(t, "pnpm-workspace.yaml")) || v(h(t, ".git")))
1739
1782
  return t;
1740
- const n = bt(t);
1783
+ const n = Oe(t);
1741
1784
  if (n === t)
1742
1785
  return e;
1743
1786
  t = n;
1744
1787
  }
1745
1788
  }
1746
- function po(e) {
1789
+ function bo(e) {
1747
1790
  const t = /* @__PURE__ */ new Map();
1748
1791
  for (const n of e.split(`
1749
1792
  `)) {
@@ -1758,21 +1801,21 @@ function po(e) {
1758
1801
  }
1759
1802
  return t;
1760
1803
  }
1761
- function _e(e) {
1804
+ function je(e) {
1762
1805
  return `'${e.replace(/'/g, "'\\''")}'`;
1763
1806
  }
1764
- function mo(e) {
1807
+ function yo(e) {
1765
1808
  const t = [];
1766
1809
  t.push(
1767
1810
  // biome-ignore lint/suspicious/noTemplateCurlyInString: shell parameter expansion, not a JS template
1768
1811
  'if [ -z "${_AIUI_OLD_PATH:-}" ]; then _AIUI_OLD_PATH="$PATH"; export _AIUI_OLD_PATH; fi;'
1769
1812
  );
1770
1813
  for (const o of [...e.pathDirs].reverse()) {
1771
- const r = _e(o);
1814
+ const r = je(o);
1772
1815
  t.push(`case ":$PATH:" in *":"${r}":"*) : ;; *) PATH=${r}":$PATH"; export PATH ;; esac;`);
1773
1816
  }
1774
1817
  for (const [o, r] of e.vars)
1775
- t.push(`export ${o}=${_e(r)};`);
1818
+ t.push(`export ${o}=${je(r)};`);
1776
1819
  const n = e.vars.size > 0 ? ` unset ${[...e.vars.keys()].join(" ")};` : "";
1777
1820
  return t.push(
1778
1821
  `aiui_deactivate () { if [ -n "\${_AIUI_OLD_PATH:-}" ]; then PATH="$_AIUI_OLD_PATH"; export PATH; unset _AIUI_OLD_PATH; fi;${n} unset -f aiui_deactivate; };`
@@ -1780,55 +1823,55 @@ function mo(e) {
1780
1823
  `)}
1781
1824
  `;
1782
1825
  }
1783
- function wo() {
1784
- const e = process.cwd(), t = fo(e), n = [d(t, "bin"), d(t, "node_modules", ".bin")];
1785
- e !== t && n.push(d(e, "node_modules", ".bin"));
1826
+ function vo() {
1827
+ const e = process.cwd(), t = go(e), n = [h(t, "bin"), h(t, "node_modules", ".bin")];
1828
+ e !== t && n.push(h(e, "node_modules", ".bin"));
1786
1829
  const o = n.filter((c) => v(c)), r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
1787
- for (const c of Ae) {
1788
- const a = d(t, c);
1830
+ for (const c of _e) {
1831
+ const a = h(t, c);
1789
1832
  if (v(a))
1790
- for (const [l, p] of po(L(a, "utf8")))
1791
- r.set(l, p), i.set(l, c);
1833
+ for (const [u, m] of bo(M(a, "utf8")))
1834
+ r.set(u, m), i.set(u, c);
1792
1835
  }
1793
- process.stdout.write(mo({ pathDirs: o, vars: r }));
1836
+ process.stdout.write(yo({ pathDirs: o, vars: r }));
1794
1837
  const s = [...r.keys()].map((c) => `${c} (${i.get(c)})`);
1795
1838
  process.stderr.write(
1796
- u.dim(
1839
+ l.dim(
1797
1840
  `aiui env: root ${t}
1798
1841
  aiui env: PATH + ${o.length > 0 ? o.join(", ") : "(nothing found)"}
1799
- aiui env: export ${s.length > 0 ? s.join(", ") : `(none — no ${Ae.join("/")} at root)`}
1842
+ aiui env: export ${s.length > 0 ? s.join(", ") : `(none — no ${_e.join("/")} at root)`}
1800
1843
  aiui env: activate with eval "$(aiui env)" — undo with aiui_deactivate
1801
1844
  `
1802
1845
  )
1803
1846
  );
1804
1847
  }
1805
- const go = "@habemus-papadum/aiui-claude-channel";
1806
- async function bo(e = []) {
1848
+ const $o = "@habemus-papadum/aiui-claude-channel";
1849
+ async function ko(e = []) {
1807
1850
  let t;
1808
1851
  try {
1809
- t = J(go);
1852
+ t = J($o);
1810
1853
  } catch {
1811
- b(
1854
+ y(
1812
1855
  "The aiui Claude channel CLI is not available",
1813
1856
  "`@habemus-papadum/aiui-claude-channel` should be installed as a dependency of aiui — try reinstalling."
1814
1857
  ), process.exitCode = 1;
1815
1858
  return;
1816
1859
  }
1817
- const n = at(e) ? wn(e, it({ config: S() })) : e, o = await T(t.command, [...t.args, ...n], {
1860
+ const n = ut(e) ? xn(e, ct({ config: P() })) : e, o = await E(t.command, [...t.args, ...n], {
1818
1861
  stdio: "inherit",
1819
1862
  reject: !1
1820
1863
  });
1821
1864
  o.exitCode && (process.exitCode = o.exitCode);
1822
1865
  }
1823
- function yo(e) {
1866
+ function Co(e) {
1824
1867
  const t = Buffer.from(JSON.stringify(e), "utf8"), n = Buffer.allocUnsafe(4 + t.length);
1825
- return pt() ? n.writeUInt32LE(t.length, 0) : n.writeUInt32BE(t.length, 0), t.copy(n, 4), n;
1868
+ return gt() ? n.writeUInt32LE(t.length, 0) : n.writeUInt32BE(t.length, 0), t.copy(n, 4), n;
1826
1869
  }
1827
- function vo(e) {
1870
+ function xo(e) {
1828
1871
  const t = [];
1829
1872
  let n = 0;
1830
1873
  for (; e.length - n >= 4; ) {
1831
- const o = pt() ? e.readUInt32LE(n) : e.readUInt32BE(n);
1874
+ const o = gt() ? e.readUInt32LE(n) : e.readUInt32BE(n);
1832
1875
  if (e.length - n - 4 < o)
1833
1876
  break;
1834
1877
  const r = e.subarray(n + 4, n + 4 + o);
@@ -1841,12 +1884,12 @@ function vo(e) {
1841
1884
  }
1842
1885
  return { messages: t, rest: e.subarray(n) };
1843
1886
  }
1844
- function pt() {
1887
+ function gt() {
1845
1888
  return new Uint8Array(new Uint32Array([1]).buffer)[0] === 1;
1846
1889
  }
1847
- function $o(e) {
1890
+ function Io(e) {
1848
1891
  const t = e !== null && typeof e == "object" ? e.cmd : void 0;
1849
- return t === "ping" ? { ok: !0, at: (/* @__PURE__ */ new Date()).toISOString() } : t === "version" ? { ok: !0, version: 1 } : t === "listChannels" ? { ok: !0, channels: M().map((o) => ({
1892
+ return t === "ping" ? { ok: !0, at: (/* @__PURE__ */ new Date()).toISOString() } : t === "version" ? { ok: !0, version: 1 } : t === "listChannels" ? { ok: !0, channels: L().map((o) => ({
1850
1893
  tag: o.tag,
1851
1894
  port: o.port,
1852
1895
  pid: o.pid,
@@ -1856,33 +1899,33 @@ function $o(e) {
1856
1899
  ...o.debug === !0 ? { debug: !0 } : {}
1857
1900
  })) } : { ok: !1, error: `unknown cmd ${JSON.stringify(t)}` };
1858
1901
  }
1859
- async function Co() {
1902
+ async function Eo() {
1860
1903
  let e = Buffer.alloc(0);
1861
1904
  process.stdin.on("data", (t) => {
1862
1905
  e = Buffer.concat([e, t]);
1863
- const { messages: n, rest: o } = vo(e);
1906
+ const { messages: n, rest: o } = xo(e);
1864
1907
  e = o;
1865
1908
  for (const r of n) {
1866
1909
  let i;
1867
1910
  try {
1868
- i = $o(r);
1911
+ i = Io(r);
1869
1912
  } catch (s) {
1870
1913
  i = { ok: !1, error: s instanceof Error ? s.message : String(s) };
1871
1914
  }
1872
- process.stdout.write(yo(i));
1915
+ process.stdout.write(Co(i));
1873
1916
  }
1874
1917
  }), await new Promise((t) => {
1875
1918
  process.stdin.on("end", t), process.stdin.on("close", t);
1876
1919
  });
1877
1920
  }
1878
- function ko() {
1921
+ function Po() {
1879
1922
  const e = [];
1880
- for (const t of Object.values(Ge()))
1923
+ for (const t of Object.values(ze()))
1881
1924
  for (const n of t ?? [])
1882
1925
  n.family === "IPv4" && !n.internal && e.push(n.address);
1883
1926
  return e;
1884
1927
  }
1885
- async function H(e, t) {
1928
+ async function G(e, t) {
1886
1929
  try {
1887
1930
  const n = await fetch(`http://127.0.0.1:${e}${t}`, {
1888
1931
  signal: AbortSignal.timeout(1500)
@@ -1892,85 +1935,85 @@ async function H(e, t) {
1892
1935
  return;
1893
1936
  }
1894
1937
  }
1895
- async function xo(e, t) {
1896
- const n = await H(
1938
+ async function Do(e, t) {
1939
+ const n = await G(
1897
1940
  e,
1898
1941
  `${t}/info`
1899
1942
  );
1900
1943
  if (!(n != null && n.ok))
1901
1944
  return;
1902
- const o = await H(e, "/health"), r = (o == null ? void 0 : o.host) !== void 0 && o.host !== "127.0.0.1";
1945
+ const o = await G(e, "/health"), r = (o == null ? void 0 : o.host) !== void 0 && o.host !== "127.0.0.1";
1903
1946
  return {
1904
1947
  lan: r,
1905
- urls: r ? ko().map((i) => `http://${i}:${e}${t}/`) : [`http://127.0.0.1:${e}${t}/`],
1948
+ urls: r ? Po().map((i) => `http://${i}:${e}${t}/`) : [`http://127.0.0.1:${e}${t}/`],
1906
1949
  hosts: n.hosts ?? 0,
1907
1950
  clients: n.clients ?? 0
1908
1951
  };
1909
1952
  }
1910
- function To(e) {
1953
+ function So(e) {
1911
1954
  const t = { name: "loopback", address: "127.0.0.1" };
1912
1955
  if (e === void 0 || e === "127.0.0.1")
1913
1956
  return [t];
1914
1957
  const n = [];
1915
- for (const [o, r] of Object.entries(Ge()))
1958
+ for (const [o, r] of Object.entries(ze()))
1916
1959
  for (const i of r ?? [])
1917
1960
  i.family === "IPv4" && !i.internal && n.push({ name: o, address: i.address });
1918
1961
  return [...n, t];
1919
1962
  }
1920
- async function Io(e) {
1963
+ async function To(e) {
1921
1964
  if (process.platform !== "darwin")
1922
1965
  return !1;
1923
1966
  try {
1924
- return await T("pbcopy", { input: e }), !0;
1967
+ return await E("pbcopy", { input: e }), !0;
1925
1968
  } catch {
1926
1969
  return !1;
1927
1970
  }
1928
1971
  }
1929
- function Eo(e, t) {
1972
+ function Ao(e, t) {
1930
1973
  var n;
1931
1974
  return e.name ?? ((n = t.get(e.ppid)) == null ? void 0 : n.name) ?? e.cwd;
1932
1975
  }
1933
- function Po(e = {}) {
1934
- return e.json ? Ao("/pencil") : Do("/pencil", "pencil");
1976
+ function No(e = {}) {
1977
+ return e.json ? Oo("/pencil") : _o("/pencil", "pencil");
1935
1978
  }
1936
- async function Do(e, t) {
1937
- const n = M();
1979
+ async function _o(e, t) {
1980
+ const n = L();
1938
1981
  if (n.length === 0) {
1939
- So(t);
1982
+ jo(t);
1940
1983
  return;
1941
1984
  }
1942
- const o = await He(n), r = await H(o.port, `${e}/info`);
1985
+ const o = await Be(n), r = await G(o.port, `${e}/info`);
1943
1986
  if (!(r != null && r.ok)) {
1944
1987
  console.log(
1945
- `${u.bold(Eo(o, Fe(Ve())))} is not hosting the ${t} surface.`
1988
+ `${l.bold(Ao(o, Re(He())))} is not hosting the ${t} surface.`
1946
1989
  ), process.exitCode = 1;
1947
1990
  return;
1948
1991
  }
1949
- const i = await H(o.port, "/health"), s = To(i == null ? void 0 : i.host), c = (i == null ? void 0 : i.host) !== void 0 && i.host !== "127.0.0.1", l = `http://${(s.length === 1 ? s[0] : await O({
1992
+ const i = await G(o.port, "/health"), s = So(i == null ? void 0 : i.host), c = (i == null ? void 0 : i.host) !== void 0 && i.host !== "127.0.0.1", u = `http://${(s.length === 1 ? s[0] : await _({
1950
1993
  message: "Which host interface should the iPad reach the channel on?",
1951
1994
  choices: s.map((f) => ({
1952
- name: `${f.address} ${u.dim(`(${f.name})`)}`,
1995
+ name: `${f.address} ${l.dim(`(${f.name})`)}`,
1953
1996
  value: f
1954
1997
  }))
1955
- })).address}:${o.port}${e}/`, p = await Io(l);
1956
- console.log(""), console.log(` ${u.cyan(l)}`), console.log(""), p ? (console.log(u.dim(" Copied to your clipboard.")), console.log(
1957
- u.dim(" Use Universal Clipboard (⌘V on the iPad) to paste it into Safari there.")
1958
- )) : console.log(u.dim(" (Copy it to the iPad however you like.)")), c || console.log(
1959
- u.dim(
1998
+ })).address}:${o.port}${e}/`, m = await To(u);
1999
+ console.log(""), console.log(` ${l.cyan(u)}`), console.log(""), m ? (console.log(l.dim(" Copied to your clipboard.")), console.log(
2000
+ l.dim(" Use Universal Clipboard (⌘V on the iPad) to paste it into Safari there.")
2001
+ )) : console.log(l.dim(" (Copy it to the iPad however you like.)")), c || console.log(
2002
+ l.dim(
1960
2003
  " This channel is loopback-only: the iPad needs a tunnel to this port (Tailscale, ssh -L), or relaunch with --aiui-bind host."
1961
2004
  )
1962
2005
  ), console.log("");
1963
2006
  }
1964
- function So(e) {
1965
- console.log(`No running channel is hosting the ${e} surface.`), console.log(""), console.log(`Every channel hosts it — start a session with ${u.cyan("aiui claude")} (or a`), console.log(
1966
- `standalone ${u.cyan("aiui mcp serve")}), then run this again to reach the ${e} surface.`
2007
+ function jo(e) {
2008
+ console.log(`No running channel is hosting the ${e} surface.`), console.log(""), console.log(`Every channel hosts it — start a session with ${l.cyan("aiui claude")} (or a`), console.log(
2009
+ `standalone ${l.cyan("aiui mcp serve")}), then run this again to reach the ${e} surface.`
1967
2010
  ), process.exitCode = 1;
1968
2011
  }
1969
- async function Ao(e, t) {
2012
+ async function Oo(e, t) {
1970
2013
  var i;
1971
- const n = M(), o = n.length > 0 ? Fe(Ve()) : /* @__PURE__ */ new Map(), r = [];
2014
+ const n = L(), o = n.length > 0 ? Re(He()) : /* @__PURE__ */ new Map(), r = [];
1972
2015
  for (const s of n) {
1973
- const c = await xo(s.port, e);
2016
+ const c = await Do(s.port, e);
1974
2017
  if (c) {
1975
2018
  const a = s.name ?? ((i = o.get(s.ppid)) == null ? void 0 : i.name);
1976
2019
  r.push({
@@ -1984,9 +2027,11 @@ async function Ao(e, t) {
1984
2027
  }
1985
2028
  console.log(JSON.stringify({ targets: r }, null, 2));
1986
2029
  }
1987
- function _o() {
1988
- const e = new wt();
1989
- e.name("aiui").description("ai ui frontends — thin launchers for Claude, Vite, and the channel CLI").version(he).enablePositionalOptions(), e.command("claude").description("launch Claude (extra args are forwarded, e.g. `aiui claude --resume`)").allowUnknownOption().allowExcessArguments().helpOption(!1).argument("[args...]", "arguments forwarded to claude").action((o) => Rn(o)), e.command("vite").description("launch Vite (extra args are forwarded, e.g. `aiui vite dev`)").allowUnknownOption().allowExcessArguments().helpOption(!1).argument("[args...]", "arguments forwarded to vite").action((o) => io(o)), e.command("debug").description("open the channel console (dashboard + trace debugger) in the session browser").option("--mcp <tag>", "target a channel by registry tag (skips the selector)").option("--no-open", "print the URL but don't open the browser").action((o) => ho(o)), e.command("chrome").description("manage the agent's browser: install | update | status").argument("<action>", "install | update | status").action((o) => un([o])), e.command("browser").description(
2030
+ function Uo() {
2031
+ const e = new yt();
2032
+ e.name("aiui").description("ai ui frontends — thin launchers for Claude, Vite, and the channel CLI").version(me).enablePositionalOptions(), e.command("claude").description("launch Claude (extra args are forwarded, e.g. `aiui claude --resume`)").allowUnknownOption().allowExcessArguments().helpOption(!1).argument("[args...]", "arguments forwarded to claude").action((o) => Vn(o)), e.command("vite").description("launch Vite (extra args are forwarded, e.g. `aiui vite dev`)").allowUnknownOption().allowExcessArguments().helpOption(!1).argument("[args...]", "arguments forwarded to vite").action((o) => lo(o)), e.command("debug").description("open the channel console (dashboard + trace debugger) in the session browser").option("--mcp <tag>", "target a channel by registry tag (skips the selector)").option("--no-open", "print the URL but don't open the browser").action((o) => wo(o)), e.command("chrome").description("manage the agent's browser: install | update | status").argument("<action>", "install | update | status").argument("[flavor]", "for install/update: chromium | chrome-for-testing (default: configured)").action(
2033
+ (o, r) => gn(r === void 0 ? [o] : [o, r])
2034
+ ), e.command("browser").description(
1990
2035
  "start (or find) the shared session browser; --tunnel does the whole remote-dev local half"
1991
2036
  ).option(
1992
2037
  "--profile <name>",
@@ -1994,13 +2039,13 @@ function _o() {
1994
2039
  ).option("--data-dir <path>", "explicit Chrome user data dir").option("--port <port>", "fixed local DevTools debug port (default: OS-assigned)").option("--headless", "launch with no UI").option("--open <url>", "also open this URL in it").option(
1995
2040
  "--tunnel <[user@]host>",
1996
2041
  "reverse-tunnel the debug port to this host (Ctrl-C closes it)"
1997
- ).option("--remote-port <port>", "fixed port on the tunnel's remote side (default: 9222)").action((o) => nn(o)), e.command("extension").description("the intent client extension's native host: install-native-host | status").argument("<action>", "install-native-host | status").option("--extension-id <id>", "extension id for allowed_origins (default: the pinned id)").action((o, r) => Xt(o, r)), e.command("native-host", { hidden: !0 }).description("(internal) Chrome native-messaging host — spawned by the browser").action(() => Co()), e.command("clean").description(
1998
- "reset aiui state (project + user cache, incl. Chrome for Testing) for a clean-slate demo"
1999
- ).option("--project-only", "only this repo's .aiui-cache/").option("--user-only", "only the user cache (~/.cache/aiui)").option("--keep-browser", "keep Chrome for Testing (skip the ~160 MB re-download)").option("-n, --dry-run", "print what would be deleted, then stop").option("-y, --yes", "delete without the confirmation prompt").action((o) => Wn(o)), e.command("open").description("open a URL in the session browser, e.g. `aiui open http://localhost:5173`").argument("<url>", "the URL to open").option("--profile <name>", "named profile under .aiui-cache/chrome/").option("--data-dir <path>", "explicit Chrome user data dir").action((o, r) => ln(o, r)), e.command("env").description('print shell code to activate this checkout — use as: eval "$(aiui env)"').action(() => wo());
2000
- const t = e.command("config").description("inspect and edit aiui's config.json — tui | show | get | set | unset").action(() => Pe());
2001
- return t.command("tui").description("browse every setting interactively: docs, defaults, current values, editing").action(() => Pe()), t.command("show").description("every key with its effective value and which file set it").option("--json", "machine-readable: file paths, per-level values, effective merge").action((o) => qn(o)), t.command("get").description("print a key's effective value (provenance goes to stderr)").argument("<key>", 'dotted key, e.g. "chrome.mode"').action((o) => zn(o)), t.command("set").description("set a key in the user config (or the project's with --project)").argument("<key>", 'dotted key, e.g. "chrome.mode"').argument("<value>", "the new value, validated against the schema").option("--project", "write .aiui-cache/config.json here instead of the user config").action((o, r, i) => Jn(o, r, i)), t.command("unset").description("remove a key from the user config (or the project's with --project)").argument("<key>", 'dotted key, e.g. "claude.skipPermissions"').option("--project", "remove from .aiui-cache/config.json here instead of the user config").action((o, r) => Xn(o, r)), e.command("mcp").description("run a channel command (forwards to aiui-claude-channel), e.g. `aiui mcp quick`").allowUnknownOption().allowExcessArguments().helpOption(!1).argument("[args...]", "arguments forwarded to the aiui-claude-channel CLI").action((o) => bo(o)), e.command("pencil").description("the remote pencil — url (where the iPad should connect)").command("url").description("pick a channel + interface, print the iPad URL and copy it to the clipboard").option("--json", "machine-readable targets (every hosting channel, no prompts)").action((o) => Po(o)), e;
2042
+ ).option("--remote-port <port>", "fixed port on the tunnel's remote side (default: 9222)").action((o) => un(o)), e.command("extension").description("the intent client extension's native host: install-native-host | status").argument("<action>", "install-native-host | status").option("--extension-id <id>", "extension id for allowed_origins (default: the pinned id)").action((o, r) => rn(o, r)), e.command("native-host", { hidden: !0 }).description("(internal) Chrome native-messaging host — spawned by the browser").action(() => Eo()), e.command("clean").description(
2043
+ "reset aiui state (project + user cache, incl. the managed browser) for a clean-slate demo"
2044
+ ).option("--project-only", "only this repo's .aiui-cache/").option("--user-only", "only the user cache (~/.cache/aiui)").option("--keep-browser", "keep the managed browser (skip the ~150-160 MB re-download)").option("-n, --dry-run", "print what would be deleted, then stop").option("-y, --yes", "delete without the confirmation prompt").action((o) => Xn(o)), e.command("open").description("open a URL in the session browser, e.g. `aiui open http://localhost:5173`").argument("<url>", "the URL to open").option("--profile <name>", "named profile under .aiui-cache/chrome/").option("--data-dir <path>", "explicit Chrome user data dir").action((o, r) => wn(o, r)), e.command("env").description('print shell code to activate this checkout — use as: eval "$(aiui env)"').action(() => vo());
2045
+ const t = e.command("config").description("inspect and edit aiui's config.json — tui | show | get | set | unset").action(() => Te());
2046
+ return t.command("tui").description("browse every setting interactively: docs, defaults, current values, editing").action(() => Te()), t.command("show").description("every key with its effective value and which file set it").option("--json", "machine-readable: file paths, per-level values, effective merge").action((o) => Zn(o)), t.command("get").description("print a key's effective value (provenance goes to stderr)").argument("<key>", 'dotted key, e.g. "chrome.mode"').action((o) => Qn(o)), t.command("set").description("set a key in the user config (or the project's with --project)").argument("<key>", 'dotted key, e.g. "chrome.mode"').argument("<value>", "the new value, validated against the schema").option("--project", "write .aiui-cache/config.json here instead of the user config").action((o, r, i) => eo(o, r, i)), t.command("unset").description("remove a key from the user config (or the project's with --project)").argument("<key>", 'dotted key, e.g. "claude.skipPermissions"').option("--project", "remove from .aiui-cache/config.json here instead of the user config").action((o, r) => to(o, r)), e.command("mcp").description("run a channel command (forwards to aiui-claude-channel), e.g. `aiui mcp quick`").allowUnknownOption().allowExcessArguments().helpOption(!1).argument("[args...]", "arguments forwarded to the aiui-claude-channel CLI").action((o) => ko(o)), e.command("pencil").description("the remote pencil — url (where the iPad should connect)").command("url").description("pick a channel + interface, print the iPad URL and copy it to the clipboard").option("--json", "machine-readable targets (every hosting channel, no prompts)").action((o) => No(o)), e;
2002
2047
  }
2003
- _o().parseAsync().catch((e) => {
2048
+ Uo().parseAsync().catch((e) => {
2004
2049
  console.error(e instanceof Error ? e.message : e), process.exitCode = 1;
2005
2050
  });
2006
2051
  //# sourceMappingURL=cli.js.map