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