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