@habemus-papadum/aiui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +427 -350
- package/dist/cli.js.map +1 -1
- package/dist/util/chrome.d.ts +3 -2
- package/dist/util/openai-preflight.d.ts +65 -0
- package/package.json +5 -5
- package/templates/demo/package.json +1 -0
- package/templates/demo/vite.config.ts +7 -1
package/dist/cli.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Command as
|
|
3
|
-
import { join as
|
|
4
|
-
import { cacheDir as
|
|
5
|
-
import { execa as
|
|
6
|
-
import { mkdirSync as
|
|
7
|
-
import { computeSystemExecutablePath as
|
|
8
|
-
import { projectCacheDir as
|
|
9
|
-
import { createInterface as
|
|
10
|
-
import
|
|
11
|
-
import { createRequire as
|
|
12
|
-
import { spawn as
|
|
13
|
-
import { fileURLToPath as
|
|
14
|
-
const
|
|
2
|
+
import { Command as Be } from "commander";
|
|
3
|
+
import { join as l, dirname as S, resolve as E, delimiter as Ve, relative as Ke } from "node:path";
|
|
4
|
+
import { cacheDir as q } from "@habemus-papadum/aiui-util";
|
|
5
|
+
import { execa as p } from "execa";
|
|
6
|
+
import { mkdirSync as k, rmSync as Ye, writeFileSync as T, readFileSync as P, existsSync as b, realpathSync as we, readdirSync as ge, accessSync as qe, constants as Ge, cpSync as Je, renameSync as We } from "node:fs";
|
|
7
|
+
import { computeSystemExecutablePath as ze, ChromeReleaseChannel as O, Browser as x, detectBrowserPlatform as be, resolveBuildId as ye, getInstalledBrowsers as ve, install as Xe, uninstall as Ze } from "@puppeteer/browsers";
|
|
8
|
+
import { projectCacheDir as xe, listMcpServers as Qe, selectMcpServer as et } from "@habemus-papadum/aiui-claude-channel";
|
|
9
|
+
import { createInterface as tt } from "node:readline/promises";
|
|
10
|
+
import g from "chalk";
|
|
11
|
+
import { createRequire as ot } from "node:module";
|
|
12
|
+
import { spawn as rt } from "node:child_process";
|
|
13
|
+
import { fileURLToPath as nt } from "node:url";
|
|
14
|
+
const Ce = "DevToolsActivePort", ae = 2e4;
|
|
15
15
|
async function I(e) {
|
|
16
|
-
const t =
|
|
17
|
-
if (t !== void 0 && await
|
|
16
|
+
const t = it(e);
|
|
17
|
+
if (t !== void 0 && await at(t))
|
|
18
18
|
return { browserUrl: `http://127.0.0.1:${t}`, port: t };
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function it(e) {
|
|
21
21
|
try {
|
|
22
|
-
const [t] =
|
|
22
|
+
const [t] = P(l(e, Ce), "utf8").split(`
|
|
23
23
|
`), o = Number(t);
|
|
24
24
|
return Number.isInteger(o) && o > 0 ? o : void 0;
|
|
25
25
|
} catch {
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
async function
|
|
29
|
+
async function at(e) {
|
|
30
30
|
try {
|
|
31
31
|
return (await fetch(`http://127.0.0.1:${e}/json/version`, {
|
|
32
32
|
signal: AbortSignal.timeout(1e3)
|
|
@@ -35,20 +35,20 @@ async function it(e) {
|
|
|
35
35
|
return !1;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
function
|
|
39
|
-
return e.executablePath ? e.executablePath :
|
|
38
|
+
function Ee(e) {
|
|
39
|
+
return e.executablePath ? e.executablePath : ze({
|
|
40
40
|
browser: x.CHROME,
|
|
41
|
-
channel:
|
|
41
|
+
channel: st[e.channel ?? "stable"]
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
-
const
|
|
44
|
+
const st = {
|
|
45
45
|
stable: O.STABLE,
|
|
46
46
|
beta: O.BETA,
|
|
47
47
|
dev: O.DEV,
|
|
48
48
|
canary: O.CANARY
|
|
49
49
|
};
|
|
50
50
|
async function $e(e) {
|
|
51
|
-
|
|
51
|
+
k(e.userDataDir, { recursive: !0 }), Ye(l(e.userDataDir, Ce), { force: !0 });
|
|
52
52
|
const t = [
|
|
53
53
|
`--remote-debugging-port=${e.debugPort ?? 0}`,
|
|
54
54
|
`--user-data-dir=${e.userDataDir}`,
|
|
@@ -56,7 +56,7 @@ async function $e(e) {
|
|
|
56
56
|
"--no-default-browser-check"
|
|
57
57
|
];
|
|
58
58
|
e.extensionDir && t.push(`--load-extension=${e.extensionDir}`), e.headless && t.push("--headless"), t.push(e.startUrl ?? "about:blank");
|
|
59
|
-
const o =
|
|
59
|
+
const o = p(e.binary, t, {
|
|
60
60
|
detached: !0,
|
|
61
61
|
stdio: "ignore",
|
|
62
62
|
reject: !1,
|
|
@@ -67,13 +67,13 @@ async function $e(e) {
|
|
|
67
67
|
o.then(() => {
|
|
68
68
|
n = !0;
|
|
69
69
|
});
|
|
70
|
-
const r = Date.now() +
|
|
70
|
+
const r = Date.now() + ae;
|
|
71
71
|
for (; Date.now() < r; ) {
|
|
72
72
|
const i = await I(e.userDataDir);
|
|
73
73
|
if (i) {
|
|
74
74
|
try {
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
T(
|
|
76
|
+
l(e.userDataDir, "aiui-browser.json"),
|
|
77
77
|
`${JSON.stringify({ pid: o.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
78
78
|
`
|
|
79
79
|
);
|
|
@@ -85,13 +85,13 @@ async function $e(e) {
|
|
|
85
85
|
throw new Error(
|
|
86
86
|
"the browser exited before exposing its DevTools endpoint — is another Chrome already running on this profile without a debug port? Close it and retry."
|
|
87
87
|
);
|
|
88
|
-
await
|
|
88
|
+
await ct(250);
|
|
89
89
|
}
|
|
90
90
|
throw new Error(
|
|
91
|
-
`the browser did not expose its DevTools endpoint within ${
|
|
91
|
+
`the browser did not expose its DevTools endpoint within ${ae / 1e3}s`
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
|
-
async function
|
|
94
|
+
async function Pe(e, t) {
|
|
95
95
|
const o = e.replace(/\/+$/, ""), n = await fetch(`${o}/json/new?${encodeURI(t)}`, {
|
|
96
96
|
method: "PUT",
|
|
97
97
|
signal: AbortSignal.timeout(3e3)
|
|
@@ -99,30 +99,30 @@ async function Ee(e, t) {
|
|
|
99
99
|
if (!n.ok)
|
|
100
100
|
throw new Error(`the browser refused to open the tab (${n.status} ${n.statusText})`);
|
|
101
101
|
}
|
|
102
|
-
function
|
|
102
|
+
function ct(e) {
|
|
103
103
|
return new Promise((t) => setTimeout(t, e));
|
|
104
104
|
}
|
|
105
|
-
const
|
|
105
|
+
const se = "config.json", ce = ["stable", "beta", "dev", "canary"], le = ["prompt", "auto", "off"], ue = ["attach", "launch"];
|
|
106
106
|
function De(e = process.cwd()) {
|
|
107
107
|
return {
|
|
108
|
-
user:
|
|
109
|
-
project:
|
|
108
|
+
user: l(q(void 0, { create: !1 }), se),
|
|
109
|
+
project: l(xe(e), se)
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
|
-
function
|
|
112
|
+
function N(e = process.cwd()) {
|
|
113
113
|
const t = De(e);
|
|
114
|
-
return
|
|
114
|
+
return lt(Y(t.user) ?? {}, Y(t.project) ?? {});
|
|
115
115
|
}
|
|
116
|
-
function
|
|
116
|
+
function lt(e, t) {
|
|
117
117
|
return {
|
|
118
118
|
claude: { ...e.claude, ...t.claude },
|
|
119
119
|
chrome: { ...e.chrome, ...t.chrome }
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
|
-
function
|
|
122
|
+
function Y(e) {
|
|
123
123
|
let t;
|
|
124
124
|
try {
|
|
125
|
-
t =
|
|
125
|
+
t = P(e, "utf8");
|
|
126
126
|
} catch {
|
|
127
127
|
return;
|
|
128
128
|
}
|
|
@@ -134,27 +134,27 @@ function q(e) {
|
|
|
134
134
|
`invalid JSON in ${e}: ${n instanceof Error ? n.message : String(n)}`
|
|
135
135
|
);
|
|
136
136
|
}
|
|
137
|
-
return
|
|
137
|
+
return ut(o, e);
|
|
138
138
|
}
|
|
139
|
-
function
|
|
140
|
-
const o =
|
|
141
|
-
|
|
139
|
+
function ut(e, t) {
|
|
140
|
+
const o = H(e, t, "the top level");
|
|
141
|
+
B(o, ["claude", "chrome"], t, "the top level");
|
|
142
142
|
const n = {};
|
|
143
143
|
if (o.claude !== void 0) {
|
|
144
|
-
const r =
|
|
145
|
-
|
|
146
|
-
skipPermissions:
|
|
144
|
+
const r = H(o.claude, t, '"claude"');
|
|
145
|
+
B(r, ["skipPermissions", "enterNudge"], t, '"claude"'), n.claude = de({
|
|
146
|
+
skipPermissions: w(
|
|
147
147
|
r.skipPermissions,
|
|
148
148
|
"boolean",
|
|
149
149
|
t,
|
|
150
150
|
"claude.skipPermissions"
|
|
151
151
|
),
|
|
152
|
-
enterNudge:
|
|
152
|
+
enterNudge: w(r.enterNudge, "boolean", t, "claude.enterNudge")
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
if (o.chrome !== void 0) {
|
|
156
|
-
const r =
|
|
157
|
-
|
|
156
|
+
const r = H(o.chrome, t, '"chrome"');
|
|
157
|
+
B(
|
|
158
158
|
r,
|
|
159
159
|
[
|
|
160
160
|
"enabled",
|
|
@@ -172,46 +172,46 @@ function lt(e, t) {
|
|
|
172
172
|
t,
|
|
173
173
|
'"chrome"'
|
|
174
174
|
);
|
|
175
|
-
const i =
|
|
176
|
-
if (i !== void 0 && !
|
|
175
|
+
const i = w(r.channel, "string", t, "chrome.channel");
|
|
176
|
+
if (i !== void 0 && !ce.includes(i))
|
|
177
177
|
throw new Error(
|
|
178
|
-
`invalid chrome.channel "${i}" in ${t} — expected one of: ${
|
|
178
|
+
`invalid chrome.channel "${i}" in ${t} — expected one of: ${ce.join(", ")}`
|
|
179
179
|
);
|
|
180
|
-
const a =
|
|
181
|
-
if (a !== void 0 && !
|
|
180
|
+
const a = w(r.forTesting, "string", t, "chrome.forTesting");
|
|
181
|
+
if (a !== void 0 && !le.includes(a))
|
|
182
182
|
throw new Error(
|
|
183
|
-
`invalid chrome.forTesting "${a}" in ${t} — expected one of: ${
|
|
183
|
+
`invalid chrome.forTesting "${a}" in ${t} — expected one of: ${le.join(", ")}`
|
|
184
184
|
);
|
|
185
|
-
const s =
|
|
186
|
-
if (s !== void 0 && !
|
|
185
|
+
const s = w(r.mode, "string", t, "chrome.mode");
|
|
186
|
+
if (s !== void 0 && !ue.includes(s))
|
|
187
187
|
throw new Error(
|
|
188
|
-
`invalid chrome.mode "${s}" in ${t} — expected one of: ${
|
|
188
|
+
`invalid chrome.mode "${s}" in ${t} — expected one of: ${ue.join(", ")}`
|
|
189
189
|
);
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
190
|
+
const c = w(r.browserUrl, "string", t, "chrome.browserUrl");
|
|
191
|
+
if (c !== void 0 && !dt(c))
|
|
192
192
|
throw new Error(
|
|
193
|
-
`invalid chrome.browserUrl "${
|
|
193
|
+
`invalid chrome.browserUrl "${c}" in ${t} — expected an http(s) URL like "http://127.0.0.1:9222"`
|
|
194
194
|
);
|
|
195
|
-
const u =
|
|
195
|
+
const u = w(r.debugPort, "number", t, "chrome.debugPort");
|
|
196
196
|
if (u !== void 0 && !(Number.isInteger(u) && u >= 0 && u <= 65535))
|
|
197
197
|
throw new Error(`invalid chrome.debugPort ${u} in ${t} — expected 0..65535`);
|
|
198
|
-
n.chrome =
|
|
199
|
-
enabled:
|
|
198
|
+
n.chrome = de({
|
|
199
|
+
enabled: w(r.enabled, "boolean", t, "chrome.enabled"),
|
|
200
200
|
mode: s,
|
|
201
|
-
browserUrl:
|
|
201
|
+
browserUrl: c,
|
|
202
202
|
debugPort: u,
|
|
203
|
-
profile:
|
|
204
|
-
dataDir:
|
|
205
|
-
executablePath:
|
|
203
|
+
profile: w(r.profile, "string", t, "chrome.profile"),
|
|
204
|
+
dataDir: w(r.dataDir, "string", t, "chrome.dataDir"),
|
|
205
|
+
executablePath: w(r.executablePath, "string", t, "chrome.executablePath"),
|
|
206
206
|
channel: i,
|
|
207
207
|
forTesting: a,
|
|
208
|
-
headless:
|
|
209
|
-
buildExtension:
|
|
208
|
+
headless: w(r.headless, "boolean", t, "chrome.headless"),
|
|
209
|
+
buildExtension: w(r.buildExtension, "boolean", t, "chrome.buildExtension")
|
|
210
210
|
});
|
|
211
211
|
}
|
|
212
212
|
return n;
|
|
213
213
|
}
|
|
214
|
-
function
|
|
214
|
+
function dt(e) {
|
|
215
215
|
try {
|
|
216
216
|
const t = new URL(e);
|
|
217
217
|
return t.protocol === "http:" || t.protocol === "https:";
|
|
@@ -219,42 +219,42 @@ function ut(e) {
|
|
|
219
219
|
return !1;
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
|
-
function
|
|
223
|
-
const t = De().user, o =
|
|
224
|
-
return e(o),
|
|
222
|
+
function U(e) {
|
|
223
|
+
const t = De().user, o = Y(t) ?? {};
|
|
224
|
+
return e(o), k(S(t), { recursive: !0 }), T(t, `${JSON.stringify(o, null, 2)}
|
|
225
225
|
`), t;
|
|
226
226
|
}
|
|
227
|
-
function
|
|
227
|
+
function de(e) {
|
|
228
228
|
return Object.fromEntries(Object.entries(e).filter(([, t]) => t !== void 0));
|
|
229
229
|
}
|
|
230
|
-
function
|
|
230
|
+
function H(e, t, o) {
|
|
231
231
|
if (typeof e != "object" || e === null || Array.isArray(e))
|
|
232
232
|
throw new Error(`expected an object at ${o} of ${t}`);
|
|
233
233
|
return e;
|
|
234
234
|
}
|
|
235
|
-
function
|
|
235
|
+
function B(e, t, o, n) {
|
|
236
236
|
for (const r of Object.keys(e))
|
|
237
237
|
if (!t.includes(r))
|
|
238
238
|
throw new Error(
|
|
239
239
|
`unknown key "${r}" at ${n} of ${o} — known keys: ${t.join(", ")}`
|
|
240
240
|
);
|
|
241
241
|
}
|
|
242
|
-
function
|
|
242
|
+
function w(e, t, o, n) {
|
|
243
243
|
if (e !== void 0) {
|
|
244
244
|
if (typeof e !== t)
|
|
245
245
|
throw new Error(`expected a ${t} for ${n} in ${o}`);
|
|
246
246
|
return e;
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
|
-
async function
|
|
250
|
-
const n =
|
|
249
|
+
async function G(e, t, o) {
|
|
250
|
+
const n = tt({ input: process.stdin, output: process.stderr });
|
|
251
251
|
try {
|
|
252
252
|
const r = t.map(
|
|
253
|
-
(i) => ` ${
|
|
253
|
+
(i) => ` ${g.bold(`[${i.key === o ? i.key.toUpperCase() : i.key}]`)} ${i.label}`
|
|
254
254
|
).join(`
|
|
255
255
|
`);
|
|
256
256
|
for (; ; ) {
|
|
257
|
-
const a = (await n.question(`${
|
|
257
|
+
const a = (await n.question(`${g.cyan(e)}
|
|
258
258
|
${r}
|
|
259
259
|
> `)).trim().toLowerCase();
|
|
260
260
|
if (!a) {
|
|
@@ -262,7 +262,7 @@ ${r}
|
|
|
262
262
|
return o;
|
|
263
263
|
continue;
|
|
264
264
|
}
|
|
265
|
-
const s = t.find((
|
|
265
|
+
const s = t.find((c) => c.key === a) ?? t.find((c) => c.label.toLowerCase().startsWith(a));
|
|
266
266
|
if (s)
|
|
267
267
|
return s.key;
|
|
268
268
|
}
|
|
@@ -271,32 +271,32 @@ ${r}
|
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
function m(e, t) {
|
|
274
|
-
console.error(`${
|
|
274
|
+
console.error(`${g.bgRed.white.bold(" ERROR ")} ${g.red.bold(e)}`), t && console.error(g.dim(t));
|
|
275
275
|
}
|
|
276
|
-
function
|
|
277
|
-
console.error(`${
|
|
276
|
+
function _(e, t) {
|
|
277
|
+
console.error(`${g.bgYellow.black.bold(" WARN ")} ${g.yellow.bold(e)}`), t && console.error(g.dim(t));
|
|
278
278
|
}
|
|
279
|
-
function
|
|
280
|
-
console.error(`${
|
|
279
|
+
function v(e, t) {
|
|
280
|
+
console.error(`${g.bgCyan.black.bold(" NOTE ")} ${g.cyan(e)}`), t && console.error(g.dim(t));
|
|
281
281
|
}
|
|
282
|
-
const
|
|
283
|
-
function
|
|
284
|
-
return
|
|
282
|
+
const ke = 1440 * 60 * 1e3, ht = 4e3;
|
|
283
|
+
function A(e = !0) {
|
|
284
|
+
return q("chrome", { create: e });
|
|
285
285
|
}
|
|
286
|
-
const
|
|
287
|
-
function
|
|
286
|
+
const Te = "update-state.json";
|
|
287
|
+
function R() {
|
|
288
288
|
try {
|
|
289
|
-
return JSON.parse(
|
|
289
|
+
return JSON.parse(P(l(A(!1), Te), "utf8"));
|
|
290
290
|
} catch {
|
|
291
291
|
return {};
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
|
-
function
|
|
295
|
-
const t =
|
|
296
|
-
|
|
294
|
+
function j(e) {
|
|
295
|
+
const t = A();
|
|
296
|
+
k(t, { recursive: !0 }), T(l(t, Te), `${JSON.stringify({ ...R(), ...e })}
|
|
297
297
|
`);
|
|
298
298
|
}
|
|
299
|
-
function
|
|
299
|
+
function J(e, t) {
|
|
300
300
|
const o = e.split(".").map(Number), n = t.split(".").map(Number);
|
|
301
301
|
for (let r = 0; r < Math.max(o.length, n.length); r++) {
|
|
302
302
|
const i = (o[r] ?? 0) - (n[r] ?? 0);
|
|
@@ -305,50 +305,50 @@ function W(e, t) {
|
|
|
305
305
|
}
|
|
306
306
|
return 0;
|
|
307
307
|
}
|
|
308
|
-
async function
|
|
309
|
-
const e =
|
|
310
|
-
if (!
|
|
308
|
+
async function W() {
|
|
309
|
+
const e = A(!1);
|
|
310
|
+
if (!b(e))
|
|
311
311
|
return;
|
|
312
|
-
const n = (await
|
|
312
|
+
const n = (await ve({ cacheDir: e })).filter((r) => r.browser === x.CHROME).sort((r, i) => J(r.buildId, i.buildId)).at(-1);
|
|
313
313
|
return n && { buildId: n.buildId, executablePath: n.executablePath };
|
|
314
314
|
}
|
|
315
|
-
async function
|
|
316
|
-
const { maxAgeMs: t =
|
|
315
|
+
async function z(e = {}) {
|
|
316
|
+
const { maxAgeMs: t = ke, timeoutMs: o = ht, now: n = Date.now() } = e, r = R();
|
|
317
317
|
if (r.latestBuildId && r.checkedAt && n - r.checkedAt < t)
|
|
318
318
|
return r.latestBuildId;
|
|
319
319
|
const i = be();
|
|
320
320
|
if (i)
|
|
321
321
|
try {
|
|
322
|
-
const a = await
|
|
323
|
-
|
|
322
|
+
const a = await wt(
|
|
323
|
+
ye(x.CHROME, i, "stable"),
|
|
324
324
|
o
|
|
325
325
|
);
|
|
326
|
-
return
|
|
326
|
+
return j({ checkedAt: n, latestBuildId: a }), a;
|
|
327
327
|
} catch {
|
|
328
328
|
return r.latestBuildId;
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
331
|
async function C(e) {
|
|
332
|
-
const t =
|
|
332
|
+
const t = A(), o = await Xe({
|
|
333
333
|
browser: x.CHROME,
|
|
334
334
|
buildId: e,
|
|
335
335
|
cacheDir: t,
|
|
336
336
|
downloadProgressCallback: "default"
|
|
337
|
-
}), n = (await
|
|
337
|
+
}), n = (await ve({ cacheDir: t })).filter(
|
|
338
338
|
(r) => r.browser === x.CHROME && r.buildId !== e
|
|
339
339
|
);
|
|
340
340
|
for (const r of n)
|
|
341
|
-
await
|
|
341
|
+
await Ze({ browser: x.CHROME, buildId: r.buildId, cacheDir: t });
|
|
342
342
|
return { buildId: e, executablePath: o.executablePath };
|
|
343
343
|
}
|
|
344
|
-
async function
|
|
344
|
+
async function ft(e) {
|
|
345
345
|
const t = be();
|
|
346
346
|
if (!t)
|
|
347
347
|
throw new Error("could not detect a supported platform for Chrome for Testing");
|
|
348
|
-
const o = await
|
|
349
|
-
|
|
350
|
-
const n = await
|
|
351
|
-
if (n &&
|
|
348
|
+
const o = await ye(x.CHROME, t, "stable");
|
|
349
|
+
j({ checkedAt: Date.now(), latestBuildId: o });
|
|
350
|
+
const n = await W();
|
|
351
|
+
if (n && J(n.buildId, o) >= 0)
|
|
352
352
|
return e(`Chrome for Testing ${n.buildId} is up to date`), { ...n, outcome: "current" };
|
|
353
353
|
e(
|
|
354
354
|
n ? `updating Chrome for Testing ${n.buildId} → ${o}…` : `installing Chrome for Testing ${o}…`
|
|
@@ -357,25 +357,25 @@ async function ht(e) {
|
|
|
357
357
|
return e(`Chrome for Testing ${o} installed at ${r.executablePath}`), { ...r, outcome: n ? "updated" : "installed" };
|
|
358
358
|
}
|
|
359
359
|
async function Ie(e) {
|
|
360
|
-
const { mode: t, interactive: o, now: n = Date.now() } = e, r = await
|
|
360
|
+
const { mode: t, interactive: o, now: n = Date.now() } = e, r = await W();
|
|
361
361
|
if (t === "off" || !o)
|
|
362
362
|
return r == null ? void 0 : r.executablePath;
|
|
363
363
|
if (!r)
|
|
364
|
-
return
|
|
365
|
-
const i = await
|
|
366
|
-
return !i ||
|
|
364
|
+
return mt(t, n);
|
|
365
|
+
const i = await z({ now: n });
|
|
366
|
+
return !i || J(i, r.buildId) <= 0 ? r.executablePath : pt(t, r, i);
|
|
367
367
|
}
|
|
368
|
-
async function
|
|
369
|
-
const o = await
|
|
368
|
+
async function mt(e, t) {
|
|
369
|
+
const o = await z({ now: t });
|
|
370
370
|
if (!o)
|
|
371
371
|
return;
|
|
372
372
|
if (e === "auto")
|
|
373
|
-
return
|
|
374
|
-
const n =
|
|
375
|
-
if (n.installDeclinedAt && t - n.installDeclinedAt <
|
|
373
|
+
return v(`installing Chrome for Testing ${o} (chrome.forTesting: "auto")…`), (await C(o)).executablePath;
|
|
374
|
+
const n = R();
|
|
375
|
+
if (n.installDeclinedAt && t - n.installDeclinedAt < ke)
|
|
376
376
|
return;
|
|
377
|
-
const r = await
|
|
378
|
-
`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 ${o} (~160 MB) to ${
|
|
377
|
+
const r = await G(
|
|
378
|
+
`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 ${o} (~160 MB) to ${A(!1)}?`,
|
|
379
379
|
[
|
|
380
380
|
{ key: "y", label: "yes, install it" },
|
|
381
381
|
{ key: "n", label: "not now — use the regular Chrome (asks again tomorrow)" },
|
|
@@ -386,21 +386,21 @@ async function ft(e, t) {
|
|
|
386
386
|
if (r === "y")
|
|
387
387
|
return (await C(o)).executablePath;
|
|
388
388
|
if (r === "never") {
|
|
389
|
-
const i =
|
|
389
|
+
const i = U((a) => {
|
|
390
390
|
a.chrome = { ...a.chrome, forTesting: "off" };
|
|
391
391
|
});
|
|
392
|
-
|
|
392
|
+
v(`wrote chrome.forTesting: "off" to ${i}`);
|
|
393
393
|
} else
|
|
394
|
-
|
|
394
|
+
j({ installDeclinedAt: t });
|
|
395
395
|
}
|
|
396
|
-
async function
|
|
396
|
+
async function pt(e, t, o) {
|
|
397
397
|
if (e === "auto")
|
|
398
|
-
return
|
|
398
|
+
return v(
|
|
399
399
|
`updating Chrome for Testing ${t.buildId} → ${o} (chrome.forTesting: "auto")…`
|
|
400
400
|
), (await C(o)).executablePath;
|
|
401
|
-
if (
|
|
401
|
+
if (R().skippedBuildId === o)
|
|
402
402
|
return t.executablePath;
|
|
403
|
-
switch (await
|
|
403
|
+
switch (await G(
|
|
404
404
|
`Your Chrome for Testing (${t.buildId}) is out of date — latest stable is ${o}. Update?`,
|
|
405
405
|
[
|
|
406
406
|
{ key: "y", label: "yes, just this once" },
|
|
@@ -416,22 +416,22 @@ async function mt(e, t, o) {
|
|
|
416
416
|
case "y":
|
|
417
417
|
return (await C(o)).executablePath;
|
|
418
418
|
case "a": {
|
|
419
|
-
const r =
|
|
419
|
+
const r = U((i) => {
|
|
420
420
|
i.chrome = { ...i.chrome, forTesting: "auto" };
|
|
421
421
|
});
|
|
422
|
-
return
|
|
422
|
+
return v(`wrote chrome.forTesting: "auto" to ${r}`), (await C(o)).executablePath;
|
|
423
423
|
}
|
|
424
424
|
case "never": {
|
|
425
|
-
const r =
|
|
425
|
+
const r = U((i) => {
|
|
426
426
|
i.chrome = { ...i.chrome, forTesting: "off" };
|
|
427
427
|
});
|
|
428
|
-
return
|
|
428
|
+
return v(`wrote chrome.forTesting: "off" to ${r}`), t.executablePath;
|
|
429
429
|
}
|
|
430
430
|
default:
|
|
431
|
-
return
|
|
431
|
+
return j({ skippedBuildId: o }), t.executablePath;
|
|
432
432
|
}
|
|
433
433
|
}
|
|
434
|
-
async function
|
|
434
|
+
async function wt(e, t) {
|
|
435
435
|
let o;
|
|
436
436
|
try {
|
|
437
437
|
return await Promise.race([
|
|
@@ -444,102 +444,117 @@ async function pt(e, t) {
|
|
|
444
444
|
clearTimeout(o);
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
|
-
const
|
|
448
|
-
function
|
|
447
|
+
const gt = ot(import.meta.url);
|
|
448
|
+
function D(e) {
|
|
449
449
|
const t = e.split("/");
|
|
450
|
-
for (const o of
|
|
451
|
-
const n =
|
|
452
|
-
if (
|
|
453
|
-
return
|
|
450
|
+
for (const o of gt.resolve.paths(e) ?? []) {
|
|
451
|
+
const n = l(o, ...t, "package.json");
|
|
452
|
+
if (b(n))
|
|
453
|
+
return S(n);
|
|
454
454
|
}
|
|
455
455
|
throw new Error(`could not locate the "${e}" package (is it installed?)`);
|
|
456
456
|
}
|
|
457
|
-
function
|
|
458
|
-
const o =
|
|
457
|
+
function X(e, t) {
|
|
458
|
+
const o = D(e), n = JSON.parse(P(l(o, "package.json"), "utf8")), r = typeof n.bin == "string" ? n.bin : bt(n.bin);
|
|
459
459
|
if (!r)
|
|
460
460
|
throw new Error(
|
|
461
461
|
`package ${e} declares no bin`
|
|
462
462
|
);
|
|
463
|
-
if (
|
|
463
|
+
if (b(l(o, "src"))) {
|
|
464
464
|
const i = r.replace(/^\.?\/?dist\//, "src/").replace(/\.js$/, ".ts");
|
|
465
|
-
return { command: process.execPath, args: ["--import", "tsx",
|
|
465
|
+
return { command: process.execPath, args: ["--import", "tsx", E(o, i)] };
|
|
466
466
|
}
|
|
467
|
-
return { command: process.execPath, args: [
|
|
467
|
+
return { command: process.execPath, args: [E(o, r)] };
|
|
468
468
|
}
|
|
469
469
|
function bt(e) {
|
|
470
470
|
return e ? Object.values(e)[0] : void 0;
|
|
471
471
|
}
|
|
472
|
-
const
|
|
472
|
+
const yt = "chrome-devtools", Ae = "@habemus-papadum/aiui-devtools-extension", vt = "default", xt = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
473
473
|
function Oe(e, t = {}, o = process.env) {
|
|
474
|
-
return e.noChrome ? !1 : e.chrome ? !0 : t.enabled === !1 ? !1 : !
|
|
474
|
+
return e.noChrome ? !1 : e.chrome ? !0 : t.enabled === !1 ? !1 : !Z(o);
|
|
475
475
|
}
|
|
476
|
-
function
|
|
476
|
+
function Z(e = process.env) {
|
|
477
477
|
const t = e.CI;
|
|
478
478
|
return t !== void 0 && t !== "" && t !== "0" && t.toLowerCase() !== "false";
|
|
479
479
|
}
|
|
480
|
-
function
|
|
480
|
+
function $(e, t = {}, o = process.cwd()) {
|
|
481
481
|
if (t.executablePath && t.channel)
|
|
482
482
|
throw new Error(
|
|
483
483
|
"config sets both chrome.executablePath and chrome.channel — they pick the browser two different ways; keep exactly one"
|
|
484
484
|
);
|
|
485
485
|
const n = e.chromeProfile !== void 0 || e.chromeDataDir !== void 0, r = e.chromeDataDir ?? (n ? void 0 : t.dataDir), i = e.chromeProfile ?? (n ? void 0 : t.profile);
|
|
486
486
|
return {
|
|
487
|
-
userDataDir:
|
|
487
|
+
userDataDir: Se({ dataDir: r, profile: i }, o),
|
|
488
488
|
// A configured endpoint means the browser is managed elsewhere (usually
|
|
489
489
|
// another machine) — that's always attach, whatever `mode` says.
|
|
490
490
|
mode: t.browserUrl ? "attach" : t.mode ?? "attach",
|
|
491
491
|
browserUrl: t.browserUrl,
|
|
492
492
|
debugPort: t.debugPort ?? 0,
|
|
493
|
-
executablePath: t.executablePath &&
|
|
493
|
+
executablePath: t.executablePath && E(o, t.executablePath),
|
|
494
494
|
channel: t.channel,
|
|
495
495
|
headless: t.headless ?? !1,
|
|
496
496
|
buildExtension: t.buildExtension ?? !0
|
|
497
497
|
};
|
|
498
498
|
}
|
|
499
|
-
function
|
|
499
|
+
function Se(e, t = process.cwd()) {
|
|
500
500
|
if (e.dataDir)
|
|
501
|
-
return
|
|
502
|
-
const o = e.profile ??
|
|
503
|
-
if (!
|
|
501
|
+
return E(t, e.dataDir);
|
|
502
|
+
const o = e.profile ?? vt;
|
|
503
|
+
if (!xt.test(o))
|
|
504
504
|
throw new Error(
|
|
505
505
|
`invalid chrome profile name "${o}" — use letters, digits, ".", "_", "-" (or --aiui-chrome-data-dir for an arbitrary path)`
|
|
506
506
|
);
|
|
507
|
-
return
|
|
507
|
+
return l(xe(t), "chrome", o);
|
|
508
508
|
}
|
|
509
|
-
function
|
|
509
|
+
function M() {
|
|
510
510
|
let e;
|
|
511
511
|
try {
|
|
512
|
-
e =
|
|
512
|
+
e = we(l(D(Ae), "extension"));
|
|
513
513
|
} catch {
|
|
514
514
|
return;
|
|
515
515
|
}
|
|
516
|
-
return
|
|
516
|
+
return b(l(e, "js")) ? e : void 0;
|
|
517
517
|
}
|
|
518
|
-
async function
|
|
518
|
+
async function Q() {
|
|
519
519
|
let e, t;
|
|
520
520
|
try {
|
|
521
|
-
e =
|
|
521
|
+
e = we(D(Ae)), t = l(D("typescript"), "bin", "tsc");
|
|
522
522
|
} catch {
|
|
523
523
|
return;
|
|
524
524
|
}
|
|
525
|
-
if (!
|
|
525
|
+
if (!b(l(e, "src")))
|
|
526
|
+
return;
|
|
527
|
+
const o = await p(process.execPath, [t, "-p", l(e, "tsconfig.json")], {
|
|
528
|
+
cwd: e,
|
|
529
|
+
reject: !1,
|
|
530
|
+
all: !0
|
|
531
|
+
});
|
|
532
|
+
if (o.exitCode) {
|
|
533
|
+
_(
|
|
534
|
+
"aiui-devtools-extension failed to compile — the DevTools panel will be stale or missing",
|
|
535
|
+
o.all || o.message
|
|
536
|
+
);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const n = l(e, "build-debug-ui.mjs");
|
|
540
|
+
if (!b(n))
|
|
526
541
|
return;
|
|
527
|
-
const
|
|
542
|
+
const r = await p(process.execPath, [n], {
|
|
528
543
|
cwd: e,
|
|
529
544
|
reject: !1,
|
|
530
545
|
all: !0
|
|
531
546
|
});
|
|
532
|
-
|
|
533
|
-
"aiui-devtools-extension
|
|
534
|
-
|
|
547
|
+
r.exitCode && _(
|
|
548
|
+
"aiui-devtools-extension debug-ui bundle failed — the Intent pane will be degraded",
|
|
549
|
+
r.all || r.message
|
|
535
550
|
);
|
|
536
551
|
}
|
|
537
|
-
function
|
|
552
|
+
function Ue(e, t) {
|
|
538
553
|
if (!t || e.executablePath)
|
|
539
554
|
return;
|
|
540
|
-
const o =
|
|
541
|
-
if (!
|
|
542
|
-
|
|
555
|
+
const o = l(e.userDataDir, "aiui-devtools-extension-hint");
|
|
556
|
+
if (!b(o)) {
|
|
557
|
+
v(
|
|
543
558
|
"the aiui DevTools panel can't auto-load into regular Chrome (≥ 137 ignores --load-extension)",
|
|
544
559
|
`Load it once in the launched Chrome — chrome://extensions → Developer mode → Load unpacked →
|
|
545
560
|
${t}
|
|
@@ -547,7 +562,7 @@ ${t}
|
|
|
547
562
|
which auto-loads it. This note won't repeat for this profile.`
|
|
548
563
|
);
|
|
549
564
|
try {
|
|
550
|
-
|
|
565
|
+
T(o, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
551
566
|
`);
|
|
552
567
|
} catch {
|
|
553
568
|
}
|
|
@@ -559,7 +574,7 @@ function V(e) {
|
|
|
559
574
|
args: ["-y", "chrome-devtools-mcp@latest", "--browser-url", e]
|
|
560
575
|
};
|
|
561
576
|
}
|
|
562
|
-
function
|
|
577
|
+
function Ct(e, t) {
|
|
563
578
|
const o = [
|
|
564
579
|
"-y",
|
|
565
580
|
"chrome-devtools-mcp@latest",
|
|
@@ -569,11 +584,11 @@ function xt(e, t) {
|
|
|
569
584
|
];
|
|
570
585
|
return e.executablePath && o.push("--executablePath", e.executablePath), e.channel && o.push("--channel", e.channel), e.headless && o.push("--headless"), t && o.push(`--chromeArg=--load-extension=${t}`), { command: "npx", args: o };
|
|
571
586
|
}
|
|
572
|
-
const
|
|
587
|
+
const Et = 9222;
|
|
573
588
|
async function $t(e) {
|
|
574
|
-
const o = { ...
|
|
589
|
+
const o = { ...N().chrome };
|
|
575
590
|
if (o.browserUrl) {
|
|
576
|
-
|
|
591
|
+
v(
|
|
577
592
|
`config pins chrome.browserUrl to ${o.browserUrl} — the browser is managed elsewhere`,
|
|
578
593
|
"Run `aiui browser` on the machine that should host it (and drop browserUrl there)."
|
|
579
594
|
);
|
|
@@ -581,31 +596,31 @@ async function $t(e) {
|
|
|
581
596
|
}
|
|
582
597
|
let n;
|
|
583
598
|
try {
|
|
584
|
-
n = Ne(e.remotePort, "--remote-port") ??
|
|
585
|
-
} catch (
|
|
586
|
-
m(
|
|
599
|
+
n = Ne(e.remotePort, "--remote-port") ?? Et;
|
|
600
|
+
} catch (c) {
|
|
601
|
+
m(c instanceof Error ? c.message : String(c)), process.exitCode = 1;
|
|
587
602
|
return;
|
|
588
603
|
}
|
|
589
604
|
let r = o;
|
|
590
605
|
const i = {
|
|
591
606
|
chromeProfile: e.tunnel ? void 0 : e.profile,
|
|
592
|
-
chromeDataDir: e.dataDir ?? (e.tunnel ?
|
|
607
|
+
chromeDataDir: e.dataDir ?? (e.tunnel ? Pt(e.tunnel, e.profile) : void 0)
|
|
593
608
|
};
|
|
594
|
-
let a =
|
|
609
|
+
let a = he($(i, r), e), s = await I(a.userDataDir);
|
|
595
610
|
if (s)
|
|
596
|
-
|
|
611
|
+
fe("session browser already running", a, s), e.open && (await Pe(s.browserUrl, e.open), console.log(`opened ${e.open}`));
|
|
597
612
|
else {
|
|
598
|
-
const
|
|
613
|
+
const c = !!process.stdin.isTTY && !!process.stdout.isTTY && !Z();
|
|
599
614
|
if (!r.executablePath && !r.channel) {
|
|
600
|
-
const h = await Ie({ mode: r.forTesting ?? "prompt", interactive:
|
|
601
|
-
h && (r = { ...r, executablePath: h }, a =
|
|
615
|
+
const h = await Ie({ mode: r.forTesting ?? "prompt", interactive: c });
|
|
616
|
+
h && (r = { ...r, executablePath: h }, a = he($(i, r), e));
|
|
602
617
|
}
|
|
603
|
-
a.buildExtension && await
|
|
604
|
-
const u =
|
|
605
|
-
|
|
618
|
+
a.buildExtension && await Q();
|
|
619
|
+
const u = M();
|
|
620
|
+
c && Ue(a, u);
|
|
606
621
|
let f;
|
|
607
622
|
try {
|
|
608
|
-
f =
|
|
623
|
+
f = Ee(a);
|
|
609
624
|
} catch (h) {
|
|
610
625
|
m(
|
|
611
626
|
"no browser to launch",
|
|
@@ -630,18 +645,18 @@ Install Chrome for Testing with \`aiui chrome install\`, or set chrome.executabl
|
|
|
630
645
|
), process.exitCode = 1;
|
|
631
646
|
return;
|
|
632
647
|
}
|
|
633
|
-
|
|
648
|
+
fe("session browser started", a, s);
|
|
634
649
|
}
|
|
635
|
-
e.tunnel ? await Tt(e.tunnel, n, s.port) :
|
|
650
|
+
e.tunnel ? await Tt(e.tunnel, n, s.port) : It(s, n);
|
|
636
651
|
}
|
|
637
|
-
function
|
|
652
|
+
function Pt(e, t) {
|
|
638
653
|
const o = t ?? Dt(e);
|
|
639
|
-
return
|
|
654
|
+
return l(q("browser-profiles", { create: !1 }), o);
|
|
640
655
|
}
|
|
641
656
|
function Dt(e) {
|
|
642
657
|
return (e.includes("@") ? e.slice(e.indexOf("@") + 1) : e).replace(/[^A-Za-z0-9._-]/g, "-") || "remote";
|
|
643
658
|
}
|
|
644
|
-
function
|
|
659
|
+
function kt(e, t, o) {
|
|
645
660
|
return [
|
|
646
661
|
// No remote command — the connection exists only to carry the forward...
|
|
647
662
|
"-N",
|
|
@@ -654,7 +669,7 @@ function Pt(e, t, o) {
|
|
|
654
669
|
e
|
|
655
670
|
];
|
|
656
671
|
}
|
|
657
|
-
function
|
|
672
|
+
function _e(e) {
|
|
658
673
|
return `aiui claude --aiui-browser-url http://127.0.0.1:${e}`;
|
|
659
674
|
}
|
|
660
675
|
async function Tt(e, t, o) {
|
|
@@ -662,11 +677,11 @@ async function Tt(e, t, o) {
|
|
|
662
677
|
`
|
|
663
678
|
tunneling ${e}:${t} → localhost:${o} — on ${e}, run:
|
|
664
679
|
|
|
665
|
-
${
|
|
680
|
+
${_e(t)}
|
|
666
681
|
|
|
667
682
|
(Ctrl-C closes the tunnel; the browser stays running.)`
|
|
668
683
|
);
|
|
669
|
-
const n = await
|
|
684
|
+
const n = await p("ssh", kt(e, t, o), {
|
|
670
685
|
stdio: "inherit",
|
|
671
686
|
reject: !1
|
|
672
687
|
});
|
|
@@ -683,25 +698,25 @@ function Ne(e, t) {
|
|
|
683
698
|
throw new Error(`invalid ${t} ${e} — expected 0..65535`);
|
|
684
699
|
return o;
|
|
685
700
|
}
|
|
686
|
-
function
|
|
701
|
+
function he(e, t) {
|
|
687
702
|
const o = Ne(t.port, "--port");
|
|
688
703
|
return o === void 0 ? e : { ...e, debugPort: o };
|
|
689
704
|
}
|
|
690
|
-
function
|
|
705
|
+
function fe(e, t, o) {
|
|
691
706
|
console.log(e), console.log(` profile: ${t.userDataDir}`), console.log(` debug endpoint: ${o.browserUrl}`);
|
|
692
707
|
}
|
|
693
|
-
function
|
|
708
|
+
function It(e, t) {
|
|
694
709
|
console.log(
|
|
695
710
|
`
|
|
696
711
|
An \`aiui claude\` in this profile's project attaches automatically. For a *remote*
|
|
697
712
|
session, rerun with \`--tunnel <[user@]host>\` — or do it by hand:
|
|
698
713
|
ssh -N -o ExitOnForwardFailure=yes -R ${t}:localhost:${e.port} <host>
|
|
699
|
-
then, on the remote: ${
|
|
714
|
+
then, on the remote: ${_e(t)}`
|
|
700
715
|
);
|
|
701
716
|
}
|
|
702
|
-
async function
|
|
717
|
+
async function At(e, t) {
|
|
703
718
|
var i, a;
|
|
704
|
-
const o =
|
|
719
|
+
const o = N(), n = $(
|
|
705
720
|
{ chromeProfile: t.profile, chromeDataDir: t.dataDir },
|
|
706
721
|
o.chrome ?? {}
|
|
707
722
|
), r = ((i = o.chrome) == null ? void 0 : i.browserUrl) ?? ((a = await I(n.userDataDir)) == null ? void 0 : a.browserUrl);
|
|
@@ -713,24 +728,24 @@ async function It(e, t) {
|
|
|
713
728
|
return;
|
|
714
729
|
}
|
|
715
730
|
try {
|
|
716
|
-
await
|
|
731
|
+
await Pe(r, e), console.log(`opened ${e}`);
|
|
717
732
|
} catch (s) {
|
|
718
733
|
m(`couldn't open ${e}`, s instanceof Error ? s.message : String(s)), process.exitCode = 1;
|
|
719
734
|
}
|
|
720
735
|
}
|
|
721
|
-
async function
|
|
736
|
+
async function Ot(e) {
|
|
722
737
|
const [t] = e;
|
|
723
738
|
switch (t) {
|
|
724
739
|
case "install":
|
|
725
740
|
case "update":
|
|
726
|
-
await
|
|
741
|
+
await ft((o) => console.log(o));
|
|
727
742
|
return;
|
|
728
743
|
case "status":
|
|
729
|
-
await
|
|
744
|
+
await St();
|
|
730
745
|
return;
|
|
731
746
|
case "extension": {
|
|
732
|
-
await
|
|
733
|
-
const o =
|
|
747
|
+
await Q();
|
|
748
|
+
const o = M();
|
|
734
749
|
if (!o) {
|
|
735
750
|
m(
|
|
736
751
|
"the aiui-devtools-extension is not available in this install",
|
|
@@ -749,11 +764,11 @@ async function St(e) {
|
|
|
749
764
|
return;
|
|
750
765
|
}
|
|
751
766
|
}
|
|
752
|
-
async function
|
|
753
|
-
const t =
|
|
767
|
+
async function St() {
|
|
768
|
+
const t = N().chrome ?? {}, o = { chrome: !1, noChrome: !1 }, n = await W(), r = await z();
|
|
754
769
|
if (console.log("Chrome for Testing (managed):"), n) {
|
|
755
|
-
const
|
|
756
|
-
console.log(` installed ${n.buildId} ${
|
|
770
|
+
const y = r === void 0 ? "(latest stable unknown — offline?)" : r === n.buildId ? "(latest stable)" : `(latest stable is ${r} — run \`aiui chrome update\`)`;
|
|
771
|
+
console.log(` installed ${n.buildId} ${y}`), console.log(` ${n.executablePath}`);
|
|
757
772
|
} else
|
|
758
773
|
console.log(" not installed — `aiui chrome install` (recommended; auto-loads the panel)");
|
|
759
774
|
if (console.log(` startup checks (chrome.forTesting): ${t.forTesting ?? "prompt"}`), console.log(`
|
|
@@ -767,18 +782,18 @@ This directory would launch:`), !Oe(o, t)) {
|
|
|
767
782
|
}
|
|
768
783
|
const i = { ...t };
|
|
769
784
|
!i.executablePath && !i.channel && n && (i.executablePath = n.executablePath);
|
|
770
|
-
const a =
|
|
771
|
-
console.log(` connection: ${
|
|
785
|
+
const a = $({}, i), s = await I(a.userDataDir), c = a.mode === "attach" ? s ? `attach to the running session browser at ${s.browserUrl}` : "attach — a session browser starts with the next interactive launch (or `aiui browser`)" : "launch — chrome-devtools-mcp starts a private browser on the agent's first tool use";
|
|
786
|
+
console.log(` connection: ${c}`);
|
|
772
787
|
const u = a.executablePath ? a.executablePath === (n == null ? void 0 : n.executablePath) ? `Chrome for Testing ${n.buildId}` : a.executablePath : a.channel ? `installed Chrome (${a.channel} channel)` : "installed Chrome (stable)";
|
|
773
788
|
console.log(` browser: ${u}${a.headless ? " — headless" : ""}`), console.log(` user data dir: ${a.userDataDir}`);
|
|
774
|
-
const f =
|
|
775
|
-
if (
|
|
776
|
-
const
|
|
777
|
-
|
|
789
|
+
const f = l(Se({}, process.cwd()), "..");
|
|
790
|
+
if (b(f)) {
|
|
791
|
+
const y = ge(f, { withFileTypes: !0 }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
792
|
+
y.length && console.log(` profiles here: ${y.join(", ")}`);
|
|
778
793
|
}
|
|
779
794
|
console.log(`
|
|
780
795
|
aiui DevTools panel:`);
|
|
781
|
-
const h =
|
|
796
|
+
const h = M();
|
|
782
797
|
if (!h) {
|
|
783
798
|
console.log(" not available (unbuilt dev checkout? run `aiui chrome extension` for help)");
|
|
784
799
|
return;
|
|
@@ -788,7 +803,7 @@ aiui DevTools panel:`);
|
|
|
788
803
|
));
|
|
789
804
|
}
|
|
790
805
|
const Ut = "--aiui-";
|
|
791
|
-
function
|
|
806
|
+
function Re(e) {
|
|
792
807
|
if (e.includes("--help") || e.includes("-h"))
|
|
793
808
|
return "help";
|
|
794
809
|
if (e.includes("--version") || e.includes("-v"))
|
|
@@ -796,16 +811,16 @@ function _e(e) {
|
|
|
796
811
|
}
|
|
797
812
|
function je(e) {
|
|
798
813
|
let t, o, n = !1, r = !1, i, a, s;
|
|
799
|
-
const
|
|
814
|
+
const c = [];
|
|
800
815
|
for (let u = 0; u < e.length; u++) {
|
|
801
816
|
const f = e[u];
|
|
802
817
|
if (!f.startsWith(Ut)) {
|
|
803
|
-
|
|
818
|
+
c.push(f);
|
|
804
819
|
continue;
|
|
805
820
|
}
|
|
806
|
-
const h = f.indexOf("="),
|
|
821
|
+
const h = f.indexOf("="), y = h === -1 ? f : f.slice(0, h);
|
|
807
822
|
let d = h === -1 ? void 0 : f.slice(h + 1);
|
|
808
|
-
switch (
|
|
823
|
+
switch (y) {
|
|
809
824
|
case "--aiui-tag": {
|
|
810
825
|
if (d === void 0 && (d = e[++u]), !d)
|
|
811
826
|
throw new Error("--aiui-tag requires a non-empty value");
|
|
@@ -849,7 +864,7 @@ function je(e) {
|
|
|
849
864
|
break;
|
|
850
865
|
}
|
|
851
866
|
default:
|
|
852
|
-
throw new Error(`unknown aiui option: ${
|
|
867
|
+
throw new Error(`unknown aiui option: ${y}`);
|
|
853
868
|
}
|
|
854
869
|
}
|
|
855
870
|
if (n && r)
|
|
@@ -860,130 +875,192 @@ function je(e) {
|
|
|
860
875
|
throw new Error(
|
|
861
876
|
"--aiui-browser-url means the browser is managed elsewhere — it can't be combined with --aiui-chrome-profile or --aiui-chrome-data-dir"
|
|
862
877
|
);
|
|
863
|
-
return { tag: t, mcp: o, chrome: n, noChrome: r, chromeProfile: i, chromeDataDir: a, browserUrl: s, passthrough:
|
|
878
|
+
return { tag: t, mcp: o, chrome: n, noChrome: r, chromeProfile: i, chromeDataDir: a, browserUrl: s, passthrough: c };
|
|
864
879
|
}
|
|
865
|
-
const
|
|
880
|
+
const _t = {
|
|
866
881
|
darwin: 2147578994,
|
|
867
882
|
linux: 21522
|
|
868
|
-
},
|
|
869
|
-
function
|
|
870
|
-
const t =
|
|
883
|
+
}, Nt = 'open(my $t,"+<","/dev/tty") or exit 0; my $c="\\r"; ioctl($t,$ARGV[0]+0,$c);', Rt = [250, 750];
|
|
884
|
+
function jt(e = Rt) {
|
|
885
|
+
const t = _t[process.platform];
|
|
871
886
|
if (t !== void 0)
|
|
872
887
|
for (const o of e)
|
|
873
888
|
setTimeout(() => {
|
|
874
889
|
try {
|
|
875
|
-
|
|
890
|
+
rt("perl", ["-e", Nt, String(t)], { stdio: "ignore" }).on("error", () => {
|
|
876
891
|
});
|
|
877
892
|
} catch {
|
|
878
893
|
}
|
|
879
894
|
}, o).unref();
|
|
880
895
|
}
|
|
881
|
-
const
|
|
896
|
+
const Mt = `One-time setup — how should aiui launch Claude Code?
|
|
882
897
|
With --dangerously-skip-permissions, every agent action (shell commands, file writes,
|
|
883
898
|
network, the browser) runs without asking you first. Fast, and dangerous. It's a personal
|
|
884
899
|
preference — aiui works fine either way. Saved as claude.skipPermissions in your user
|
|
885
|
-
config; edit or delete it there to change your mind.`,
|
|
900
|
+
config; edit or delete it there to change your mind.`, Lt = `One-time setup — auto-dismiss Claude Code's channel prompt?
|
|
886
901
|
aiui loads a custom development channel, so Claude Code shows a one-key acknowledgement
|
|
887
902
|
prompt at every startup. aiui can dismiss it for you: shortly after launch it injects a
|
|
888
903
|
single Enter keystroke into this terminal (a best-effort TIOCSTI ioctl on /dev/tty — it
|
|
889
904
|
literally "types" the Enter for you; on platforms that forbid that, nothing happens and
|
|
890
905
|
you press it yourself). Saying no just means pressing Enter once per launch. Saved as
|
|
891
906
|
claude.enterNudge in your user config.`;
|
|
892
|
-
async function
|
|
907
|
+
async function Ft(e, t = G) {
|
|
893
908
|
var n, r;
|
|
894
909
|
let o = e;
|
|
895
910
|
if (((n = o.claude) == null ? void 0 : n.skipPermissions) === void 0) {
|
|
896
|
-
const i = await t(
|
|
911
|
+
const i = await t(Mt, [
|
|
897
912
|
{ key: "y", label: "yes — skip permissions; nothing asks before acting" },
|
|
898
913
|
{ key: "n", label: "no — keep Claude Code's own permission prompts" }
|
|
899
914
|
]);
|
|
900
|
-
o =
|
|
915
|
+
o = me(o, "skipPermissions", i === "y");
|
|
901
916
|
}
|
|
902
917
|
if (((r = o.claude) == null ? void 0 : r.enterNudge) === void 0) {
|
|
903
|
-
const i = await t(
|
|
918
|
+
const i = await t(Lt, [
|
|
904
919
|
{ key: "y", label: "yes — press Enter for me at startup" },
|
|
905
920
|
{ key: "n", label: "no — I'll press it myself each launch" }
|
|
906
921
|
]);
|
|
907
|
-
o =
|
|
922
|
+
o = me(o, "enterNudge", i === "y");
|
|
908
923
|
}
|
|
909
924
|
return o;
|
|
910
925
|
}
|
|
911
|
-
function
|
|
912
|
-
const n =
|
|
926
|
+
function me(e, t, o) {
|
|
927
|
+
const n = U((r) => {
|
|
913
928
|
r.claude = { ...r.claude, [t]: o };
|
|
914
929
|
});
|
|
915
|
-
return
|
|
930
|
+
return v(`wrote claude.${t}: ${o} to ${n}`), { ...e, claude: { ...e.claude, [t]: o } };
|
|
931
|
+
}
|
|
932
|
+
const Ht = "https://api.openai.com/v1/models", Bt = 3e3;
|
|
933
|
+
async function Vt(e = {}) {
|
|
934
|
+
var c;
|
|
935
|
+
const {
|
|
936
|
+
verify: t = !0,
|
|
937
|
+
env: o = process.env,
|
|
938
|
+
fetchImpl: n = fetch,
|
|
939
|
+
timeoutMs: r = Bt
|
|
940
|
+
} = e, i = (c = o.OPENAI_API_KEY) == null ? void 0 : c.trim();
|
|
941
|
+
if (!i)
|
|
942
|
+
return "missing";
|
|
943
|
+
if (!t)
|
|
944
|
+
return "unverified";
|
|
945
|
+
const a = new AbortController(), s = setTimeout(() => a.abort(), r);
|
|
946
|
+
try {
|
|
947
|
+
const u = await n(Ht, {
|
|
948
|
+
headers: { authorization: `Bearer ${i}` },
|
|
949
|
+
signal: a.signal
|
|
950
|
+
});
|
|
951
|
+
return u.ok ? "valid" : u.status === 401 || u.status === 403 ? "invalid" : "unverified";
|
|
952
|
+
} catch {
|
|
953
|
+
return "unverified";
|
|
954
|
+
} finally {
|
|
955
|
+
clearTimeout(s);
|
|
956
|
+
}
|
|
916
957
|
}
|
|
917
|
-
|
|
918
|
-
|
|
958
|
+
function Kt(e) {
|
|
959
|
+
switch (e) {
|
|
960
|
+
case "valid":
|
|
961
|
+
return null;
|
|
962
|
+
case "missing":
|
|
963
|
+
return {
|
|
964
|
+
level: "warn",
|
|
965
|
+
title: "OPENAI_API_KEY is not set — the intent pipeline will run degraded",
|
|
966
|
+
detail: "Speech transcription and dictation correction fall back to mock/off mode. To enable them, export the key in the shell you run `aiui claude` from:\n export OPENAI_API_KEY=sk-…\nIt flows through to the channel process, which is where those calls happen."
|
|
967
|
+
};
|
|
968
|
+
case "invalid":
|
|
969
|
+
return {
|
|
970
|
+
level: "warn",
|
|
971
|
+
title: "OPENAI_API_KEY was rejected by OpenAI (401) — the intent pipeline will run degraded",
|
|
972
|
+
detail: `The key in your environment isn't valid. 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):
|
|
973
|
+
echo $OPENAI_API_KEY | head -c 12
|
|
974
|
+
and compare that against the start of your real key. Until it's fixed, transcription and correction run in mock/off mode.`
|
|
975
|
+
};
|
|
976
|
+
case "unverified":
|
|
977
|
+
return {
|
|
978
|
+
level: "note",
|
|
979
|
+
title: "couldn't verify OPENAI_API_KEY with OpenAI — continuing",
|
|
980
|
+
detail: "The check didn't complete (offline, a timeout, or a transient OpenAI error), so the key is unverified — not known-bad. Launch continues; if the intent pipeline degrades to mock/off, an unreachable or invalid key may be why."
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
function Yt(e) {
|
|
985
|
+
const t = Kt(e);
|
|
986
|
+
t && (t.level === "warn" ? _(t.title, t.detail) : v(t.title, t.detail));
|
|
987
|
+
}
|
|
988
|
+
const L = "0.2.0";
|
|
989
|
+
function ee(e) {
|
|
919
990
|
const t = (process.env.PATH ?? "").split(Ve).filter(Boolean), o = process.platform === "win32" ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";") : [""];
|
|
920
991
|
for (const n of t)
|
|
921
992
|
for (const r of o)
|
|
922
993
|
try {
|
|
923
|
-
return
|
|
994
|
+
return qe(l(n, e + r), Ge.X_OK), !0;
|
|
924
995
|
} catch {
|
|
925
996
|
}
|
|
926
997
|
return !1;
|
|
927
998
|
}
|
|
928
|
-
const
|
|
929
|
-
async function
|
|
930
|
-
var
|
|
931
|
-
const t = je(e), { tag: o, passthrough: n } = t, r =
|
|
999
|
+
const qt = "@habemus-papadum/aiui-claude-channel", Gt = "@habemus-papadum/aiui-claude-plugin", pe = "aiui";
|
|
1000
|
+
async function Jt(e = []) {
|
|
1001
|
+
var re, ne;
|
|
1002
|
+
const t = je(e), { tag: o, passthrough: n } = t, r = Re(n);
|
|
932
1003
|
if (r) {
|
|
933
|
-
r === "help" ?
|
|
1004
|
+
r === "help" ? zt() : console.log(`aiui ${L}`), await Wt(n);
|
|
934
1005
|
return;
|
|
935
1006
|
}
|
|
936
|
-
let i =
|
|
937
|
-
const a =
|
|
938
|
-
|
|
1007
|
+
let i = N();
|
|
1008
|
+
const a = Zt(n) && !Z();
|
|
1009
|
+
a && (i = await Ft(i));
|
|
1010
|
+
const s = await Vt({ verify: a });
|
|
1011
|
+
if (a && Yt(s), !Me())
|
|
939
1012
|
return;
|
|
940
|
-
const
|
|
941
|
-
o &&
|
|
942
|
-
const
|
|
943
|
-
[
|
|
1013
|
+
const c = E(D(Gt), "marketplace", "plugins"), u = X(qt), f = [...u.args, "mcp"];
|
|
1014
|
+
o && f.push("--tag", o);
|
|
1015
|
+
const h = {
|
|
1016
|
+
[pe]: { command: u.command, args: f }
|
|
944
1017
|
};
|
|
945
|
-
let
|
|
1018
|
+
let y = { enabled: !1 };
|
|
946
1019
|
if (Oe(t, i.chrome)) {
|
|
947
|
-
const
|
|
1020
|
+
const F = {
|
|
948
1021
|
...i.chrome,
|
|
949
1022
|
...t.browserUrl ? { browserUrl: t.browserUrl } : {}
|
|
950
|
-
},
|
|
951
|
-
|
|
1023
|
+
}, ie = await Xt(t, F, a);
|
|
1024
|
+
h[yt] = ie.entry, y = ie.info;
|
|
952
1025
|
}
|
|
953
|
-
const
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1026
|
+
const d = {
|
|
1027
|
+
launcher: "aiui claude",
|
|
1028
|
+
chromeDevtools: y,
|
|
1029
|
+
openaiKey: s
|
|
1030
|
+
};
|
|
1031
|
+
f.push("--launch-info", JSON.stringify(d));
|
|
1032
|
+
const Fe = JSON.stringify({ mcpServers: h }), te = [l(c, "aiui"), l(c, "frontend-design")];
|
|
1033
|
+
y.enabled && te.push(l(c, "session-browser"));
|
|
1034
|
+
const He = [
|
|
1035
|
+
...((re = i.claude) == null ? void 0 : re.skipPermissions) ?? !0 ? ["--dangerously-skip-permissions"] : [],
|
|
959
1036
|
"--mcp-config",
|
|
960
|
-
|
|
961
|
-
...
|
|
1037
|
+
Fe,
|
|
1038
|
+
...te.flatMap((F) => ["--plugin-dir", F]),
|
|
962
1039
|
// Custom channels are a research preview and not on the approved allowlist,
|
|
963
1040
|
// so opt this session into loading ours as a development channel.
|
|
964
1041
|
"--dangerously-load-development-channels",
|
|
965
|
-
`server:${
|
|
1042
|
+
`server:${pe}`
|
|
966
1043
|
];
|
|
967
|
-
a && (((
|
|
968
|
-
const
|
|
1044
|
+
a && (((ne = i.claude) == null ? void 0 : ne.enterNudge) ?? !0) && jt();
|
|
1045
|
+
const oe = await p("claude", [...He, ...n], {
|
|
969
1046
|
stdio: "inherit",
|
|
970
1047
|
reject: !1
|
|
971
1048
|
});
|
|
972
|
-
|
|
1049
|
+
oe.exitCode && (process.exitCode = oe.exitCode);
|
|
973
1050
|
}
|
|
974
1051
|
function Me() {
|
|
975
|
-
return
|
|
1052
|
+
return ee("claude") ? !0 : (m(
|
|
976
1053
|
"`claude` was not found on your PATH",
|
|
977
1054
|
"Install Claude Code and make sure the `claude` command is available, then try again."
|
|
978
1055
|
), process.exitCode = 1, !1);
|
|
979
1056
|
}
|
|
980
|
-
async function
|
|
1057
|
+
async function Wt(e) {
|
|
981
1058
|
if (!Me())
|
|
982
1059
|
return;
|
|
983
|
-
const t = await
|
|
1060
|
+
const t = await p("claude", e, { stdio: "inherit", reject: !1 });
|
|
984
1061
|
t.exitCode && (process.exitCode = t.exitCode);
|
|
985
1062
|
}
|
|
986
|
-
function
|
|
1063
|
+
function zt() {
|
|
987
1064
|
console.log(`aiui claude — launch Claude Code wired with the aiui channel, plugin, and browser MCP
|
|
988
1065
|
|
|
989
1066
|
aiui's own flags (everything else forwards to claude verbatim):
|
|
@@ -999,13 +1076,13 @@ Durable settings live in config.json (project .aiui-cache/ + user cache) — see
|
|
|
999
1076
|
Configuration guide. What follows is claude's own --help:
|
|
1000
1077
|
`);
|
|
1001
1078
|
}
|
|
1002
|
-
async function
|
|
1079
|
+
async function Xt(e, t, o) {
|
|
1003
1080
|
if (t.browserUrl)
|
|
1004
1081
|
return {
|
|
1005
1082
|
entry: V(t.browserUrl),
|
|
1006
1083
|
info: { enabled: !0, connection: "attach", browserUrl: t.browserUrl }
|
|
1007
1084
|
};
|
|
1008
|
-
let n = { ...t }, r =
|
|
1085
|
+
let n = { ...t }, r = $(e, n);
|
|
1009
1086
|
if (r.mode === "attach") {
|
|
1010
1087
|
const s = await I(r.userDataDir);
|
|
1011
1088
|
if (s)
|
|
@@ -1021,11 +1098,11 @@ async function Gt(e, t, o) {
|
|
|
1021
1098
|
}
|
|
1022
1099
|
if (!n.executablePath && !n.channel) {
|
|
1023
1100
|
const s = await Ie({ mode: n.forTesting ?? "prompt", interactive: o });
|
|
1024
|
-
s && (n = { ...n, executablePath: s }, r =
|
|
1101
|
+
s && (n = { ...n, executablePath: s }, r = $(e, n));
|
|
1025
1102
|
}
|
|
1026
|
-
|
|
1027
|
-
const i =
|
|
1028
|
-
o &&
|
|
1103
|
+
k(r.userDataDir, { recursive: !0 }), r.buildExtension && await Q();
|
|
1104
|
+
const i = M();
|
|
1105
|
+
o && Ue(r, i);
|
|
1029
1106
|
const a = {
|
|
1030
1107
|
userDataDir: r.userDataDir,
|
|
1031
1108
|
executablePath: r.executablePath,
|
|
@@ -1036,7 +1113,7 @@ async function Gt(e, t, o) {
|
|
|
1036
1113
|
if (r.mode === "attach" && o)
|
|
1037
1114
|
try {
|
|
1038
1115
|
const s = await $e({
|
|
1039
|
-
binary:
|
|
1116
|
+
binary: Ee(r),
|
|
1040
1117
|
userDataDir: r.userDataDir,
|
|
1041
1118
|
debugPort: r.debugPort,
|
|
1042
1119
|
extensionDir: i,
|
|
@@ -1052,22 +1129,22 @@ async function Gt(e, t, o) {
|
|
|
1052
1129
|
}
|
|
1053
1130
|
};
|
|
1054
1131
|
} catch (s) {
|
|
1055
|
-
|
|
1132
|
+
_(
|
|
1056
1133
|
"couldn't start the session browser — falling back to a browser private to the MCP",
|
|
1057
1134
|
s instanceof Error ? s.message : String(s)
|
|
1058
1135
|
);
|
|
1059
1136
|
}
|
|
1060
1137
|
return {
|
|
1061
|
-
entry:
|
|
1138
|
+
entry: Ct(r, i),
|
|
1062
1139
|
info: { enabled: !0, connection: "launch", ...a }
|
|
1063
1140
|
};
|
|
1064
1141
|
}
|
|
1065
|
-
function
|
|
1142
|
+
function Zt(e) {
|
|
1066
1143
|
return !process.stdin.isTTY || !process.stdout.isTTY ? !1 : !e.some((t) => t === "-p" || t === "--print");
|
|
1067
1144
|
}
|
|
1068
|
-
async function
|
|
1069
|
-
const o =
|
|
1070
|
-
switch (
|
|
1145
|
+
async function Qt(e, t = {}) {
|
|
1146
|
+
const o = E(process.cwd(), e ?? "aiui-demo");
|
|
1147
|
+
switch (eo(o)) {
|
|
1071
1148
|
case "occupied":
|
|
1072
1149
|
m(
|
|
1073
1150
|
`${o} already exists and isn't an aiui demo`,
|
|
@@ -1075,24 +1152,24 @@ async function Wt(e, t = {}) {
|
|
|
1075
1152
|
), process.exitCode = 1;
|
|
1076
1153
|
return;
|
|
1077
1154
|
case "existing-demo":
|
|
1078
|
-
|
|
1155
|
+
v(`existing demo found at ${o} — continuing where it left off`);
|
|
1079
1156
|
break;
|
|
1080
1157
|
case "new": {
|
|
1081
|
-
const n =
|
|
1158
|
+
const n = no();
|
|
1082
1159
|
if (!n) {
|
|
1083
1160
|
m("the demo template did not ship with this aiui install"), process.exitCode = 1;
|
|
1084
1161
|
return;
|
|
1085
1162
|
}
|
|
1086
|
-
|
|
1163
|
+
oo(n, o), console.log(`scaffolded the demo playground at ${o}`), await ro(o);
|
|
1087
1164
|
break;
|
|
1088
1165
|
}
|
|
1089
1166
|
}
|
|
1090
|
-
if (!t.skipInstall && !
|
|
1091
|
-
if (!
|
|
1092
|
-
|
|
1167
|
+
if (!t.skipInstall && !b(l(o, "node_modules")))
|
|
1168
|
+
if (!ee("npm"))
|
|
1169
|
+
v("npm not found on PATH — run your package manager's install in the demo yourself");
|
|
1093
1170
|
else {
|
|
1094
1171
|
console.log("installing dependencies (one time)…");
|
|
1095
|
-
const n = await
|
|
1172
|
+
const n = await p("npm", ["install", "--no-audit", "--no-fund"], {
|
|
1096
1173
|
cwd: o,
|
|
1097
1174
|
stdio: "inherit",
|
|
1098
1175
|
reject: !1
|
|
@@ -1102,59 +1179,59 @@ async function Wt(e, t = {}) {
|
|
|
1102
1179
|
return;
|
|
1103
1180
|
}
|
|
1104
1181
|
}
|
|
1105
|
-
|
|
1182
|
+
io(o);
|
|
1106
1183
|
}
|
|
1107
|
-
function
|
|
1184
|
+
function eo(e) {
|
|
1108
1185
|
var o;
|
|
1109
|
-
if (!
|
|
1186
|
+
if (!b(e))
|
|
1110
1187
|
return "new";
|
|
1111
1188
|
let t;
|
|
1112
1189
|
try {
|
|
1113
|
-
t =
|
|
1190
|
+
t = ge(e);
|
|
1114
1191
|
} catch {
|
|
1115
1192
|
return "occupied";
|
|
1116
1193
|
}
|
|
1117
1194
|
if (t.length === 0)
|
|
1118
1195
|
return "new";
|
|
1119
1196
|
try {
|
|
1120
|
-
if (((o = JSON.parse(
|
|
1197
|
+
if (((o = JSON.parse(P(l(e, "package.json"), "utf8")).aiui) == null ? void 0 : o.demo) === !0)
|
|
1121
1198
|
return "existing-demo";
|
|
1122
1199
|
} catch {
|
|
1123
1200
|
}
|
|
1124
1201
|
return "occupied";
|
|
1125
1202
|
}
|
|
1126
|
-
function
|
|
1203
|
+
function to(e) {
|
|
1127
1204
|
return /^\d+\.\d+\.\d+$/.test(e) ? `^${e}` : "latest";
|
|
1128
1205
|
}
|
|
1129
|
-
function
|
|
1130
|
-
|
|
1131
|
-
const o =
|
|
1132
|
-
|
|
1206
|
+
function oo(e, t) {
|
|
1207
|
+
k(t, { recursive: !0 }), Je(e, t, { recursive: !0 }), b(l(t, "gitignore")) && We(l(t, "gitignore"), l(t, ".gitignore"));
|
|
1208
|
+
const o = l(t, "package.json");
|
|
1209
|
+
T(
|
|
1133
1210
|
o,
|
|
1134
|
-
|
|
1211
|
+
P(o, "utf8").replaceAll(
|
|
1135
1212
|
"__AIUI_VERSION_RANGE__",
|
|
1136
|
-
|
|
1213
|
+
to(L)
|
|
1137
1214
|
)
|
|
1138
1215
|
);
|
|
1139
1216
|
}
|
|
1140
|
-
async function
|
|
1141
|
-
!
|
|
1217
|
+
async function ro(e) {
|
|
1218
|
+
!ee("git") || (await p("git", ["-C", e, "rev-parse", "--is-inside-work-tree"], {
|
|
1142
1219
|
reject: !1
|
|
1143
|
-
})).exitCode === 0 || (await
|
|
1220
|
+
})).exitCode === 0 || (await p("git", ["-C", e, "init", "--quiet"], { reject: !1 })).exitCode !== 0 || (await p("git", ["-C", e, "add", "-A"], { reject: !1 }), await p("git", ["-C", e, "commit", "--quiet", "-m", "aiui demo scaffold"], {
|
|
1144
1221
|
reject: !1
|
|
1145
1222
|
}));
|
|
1146
1223
|
}
|
|
1147
|
-
function
|
|
1148
|
-
let e =
|
|
1224
|
+
function no() {
|
|
1225
|
+
let e = S(nt(import.meta.url));
|
|
1149
1226
|
for (let t = 0; t < 4; t++) {
|
|
1150
|
-
const o =
|
|
1151
|
-
if (
|
|
1227
|
+
const o = l(e, "templates", "demo");
|
|
1228
|
+
if (b(l(o, "package.json")))
|
|
1152
1229
|
return o;
|
|
1153
|
-
e =
|
|
1230
|
+
e = S(e);
|
|
1154
1231
|
}
|
|
1155
1232
|
}
|
|
1156
|
-
function
|
|
1157
|
-
const t =
|
|
1233
|
+
function io(e) {
|
|
1234
|
+
const t = Ke(process.cwd(), e) || ".", o = t === "aiui-demo" ? "aiui demo" : `aiui demo ${t}`;
|
|
1158
1235
|
console.log(`
|
|
1159
1236
|
demo ready. Run the loop:
|
|
1160
1237
|
|
|
@@ -1169,11 +1246,11 @@ then open the app in the session browser (the window you share with the agent):
|
|
|
1169
1246
|
Click the ✳ aiui button on the page and type an intent — it lands in the session
|
|
1170
1247
|
as a prompt. Re-run \`${o}\` anytime to continue this sandbox.`);
|
|
1171
1248
|
}
|
|
1172
|
-
const
|
|
1173
|
-
async function
|
|
1249
|
+
const ao = "@habemus-papadum/aiui-claude-channel";
|
|
1250
|
+
async function so(e = []) {
|
|
1174
1251
|
let t;
|
|
1175
1252
|
try {
|
|
1176
|
-
t =
|
|
1253
|
+
t = X(ao);
|
|
1177
1254
|
} catch {
|
|
1178
1255
|
m(
|
|
1179
1256
|
"The aiui Claude channel CLI is not available",
|
|
@@ -1181,14 +1258,14 @@ async function to(e = []) {
|
|
|
1181
1258
|
), process.exitCode = 1;
|
|
1182
1259
|
return;
|
|
1183
1260
|
}
|
|
1184
|
-
const o = await
|
|
1261
|
+
const o = await p(t.command, [...t.args, ...e], {
|
|
1185
1262
|
stdio: "inherit",
|
|
1186
1263
|
reject: !1
|
|
1187
1264
|
});
|
|
1188
1265
|
o.exitCode && (process.exitCode = o.exitCode);
|
|
1189
1266
|
}
|
|
1190
|
-
const
|
|
1191
|
-
function
|
|
1267
|
+
const co = "vite", K = "VITE_AIUI_PORT";
|
|
1268
|
+
function lo(e, t) {
|
|
1192
1269
|
if (t !== void 0) {
|
|
1193
1270
|
const o = e.find((n) => n.tag === t);
|
|
1194
1271
|
if (!o) {
|
|
@@ -1201,37 +1278,37 @@ function ro(e, t) {
|
|
|
1201
1278
|
}
|
|
1202
1279
|
return e.length > 0 ? { select: e } : {};
|
|
1203
1280
|
}
|
|
1204
|
-
async function
|
|
1205
|
-
const { mcp: t, tag: o, passthrough: n } = je(e), r =
|
|
1281
|
+
async function uo(e = []) {
|
|
1282
|
+
const { mcp: t, tag: o, passthrough: n } = je(e), r = Re(n);
|
|
1206
1283
|
if (r) {
|
|
1207
|
-
r === "help" ?
|
|
1284
|
+
r === "help" ? fo() : console.log(`aiui ${L}`), await ho(n);
|
|
1208
1285
|
return;
|
|
1209
1286
|
}
|
|
1210
|
-
const i = t ?? o, a =
|
|
1287
|
+
const i = t ?? o, a = lo(Qe(), i);
|
|
1211
1288
|
if (a.error) {
|
|
1212
1289
|
m("Could not resolve an aiui channel", a.error), process.exitCode = 1;
|
|
1213
1290
|
return;
|
|
1214
1291
|
}
|
|
1215
|
-
const s = a.select ? await
|
|
1216
|
-
let
|
|
1217
|
-
s ? (
|
|
1218
|
-
|
|
1219
|
-
`aiui: connecting vite to channel "${s.tag}" (${s.cwd}) on port ${
|
|
1292
|
+
const s = a.select ? await et(a.select) : a.server;
|
|
1293
|
+
let c;
|
|
1294
|
+
s ? (c = String(s.port), console.error(
|
|
1295
|
+
g.dim(
|
|
1296
|
+
`aiui: connecting vite to channel "${s.tag}" (${s.cwd}) on port ${c} via ${K}`
|
|
1220
1297
|
)
|
|
1221
|
-
)) : console.error(
|
|
1298
|
+
)) : console.error(g.dim(`aiui: no running channel found — ${K} left unset`));
|
|
1222
1299
|
const u = Le();
|
|
1223
1300
|
if (!u)
|
|
1224
1301
|
return;
|
|
1225
|
-
const f = await
|
|
1302
|
+
const f = await p(u.command, [...u.args, ...n], {
|
|
1226
1303
|
stdio: "inherit",
|
|
1227
1304
|
reject: !1,
|
|
1228
|
-
...
|
|
1305
|
+
...c ? { env: { [K]: c } } : {}
|
|
1229
1306
|
});
|
|
1230
1307
|
f.exitCode && (process.exitCode = f.exitCode);
|
|
1231
1308
|
}
|
|
1232
1309
|
function Le() {
|
|
1233
1310
|
try {
|
|
1234
|
-
return
|
|
1311
|
+
return X(co);
|
|
1235
1312
|
} catch {
|
|
1236
1313
|
m(
|
|
1237
1314
|
"Vite is not available",
|
|
@@ -1240,17 +1317,17 @@ function Le() {
|
|
|
1240
1317
|
return;
|
|
1241
1318
|
}
|
|
1242
1319
|
}
|
|
1243
|
-
async function
|
|
1320
|
+
async function ho(e) {
|
|
1244
1321
|
const t = Le();
|
|
1245
1322
|
if (!t)
|
|
1246
1323
|
return;
|
|
1247
|
-
const o = await
|
|
1324
|
+
const o = await p(t.command, [...t.args, ...e], {
|
|
1248
1325
|
stdio: "inherit",
|
|
1249
1326
|
reject: !1
|
|
1250
1327
|
});
|
|
1251
1328
|
o.exitCode && (process.exitCode = o.exitCode);
|
|
1252
1329
|
}
|
|
1253
|
-
function
|
|
1330
|
+
function fo() {
|
|
1254
1331
|
console.log(`aiui vite — launch Vite connected to the running aiui channel
|
|
1255
1332
|
|
|
1256
1333
|
aiui's own flags (everything else forwards to vite verbatim):
|
|
@@ -1262,9 +1339,9 @@ Vite plugin picks it up there and wires the intent tool to it. What follows is
|
|
|
1262
1339
|
vite's own --help:
|
|
1263
1340
|
`);
|
|
1264
1341
|
}
|
|
1265
|
-
function
|
|
1266
|
-
const e = new
|
|
1267
|
-
return e.name("aiui").description("ai ui frontends — thin launchers for Claude, Vite, and the channel CLI").version(
|
|
1342
|
+
function mo() {
|
|
1343
|
+
const e = new Be();
|
|
1344
|
+
return e.name("aiui").description("ai ui frontends — thin launchers for Claude, Vite, and the channel CLI").version(L).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((t) => Jt(t)), 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((t) => uo(t)), e.command("chrome").description("manage the agent's browser: install | update | status | extension").argument("<action>", "install | update | status | extension").action((t) => Ot([t])), e.command("browser").description(
|
|
1268
1345
|
"start (or find) the shared session browser; --tunnel does the whole remote-dev local half"
|
|
1269
1346
|
).option(
|
|
1270
1347
|
"--profile <name>",
|
|
@@ -1272,9 +1349,9 @@ function so() {
|
|
|
1272
1349
|
).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(
|
|
1273
1350
|
"--tunnel <[user@]host>",
|
|
1274
1351
|
"reverse-tunnel the debug port to this host (Ctrl-C closes it)"
|
|
1275
|
-
).option("--remote-port <port>", "fixed port on the tunnel's remote side (default: 9222)").action((t) => $t(t)), e.command("demo").description("scaffold a runnable demo playground (safe to re-run; default dir: aiui-demo)").argument("[dir]", "target directory (default: aiui-demo)").option("--skip-install", "scaffold only — don't run npm install").action((t, o) =>
|
|
1352
|
+
).option("--remote-port <port>", "fixed port on the tunnel's remote side (default: 9222)").action((t) => $t(t)), e.command("demo").description("scaffold a runnable demo playground (safe to re-run; default dir: aiui-demo)").argument("[dir]", "target directory (default: aiui-demo)").option("--skip-install", "scaffold only — don't run npm install").action((t, o) => Qt(t, 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((t, o) => At(t, o)), 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((t) => so(t)), e;
|
|
1276
1353
|
}
|
|
1277
|
-
|
|
1354
|
+
mo().parseAsync().catch((e) => {
|
|
1278
1355
|
console.error(e instanceof Error ? e.message : e), process.exitCode = 1;
|
|
1279
1356
|
});
|
|
1280
1357
|
//# sourceMappingURL=cli.js.map
|