@sahyll/ai 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3322 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
3
+ var __create = Object.create;
4
+ var __getProtoOf = Object.getPrototypeOf;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
13
+ var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
21
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
22
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ if (canCache)
30
+ cache.set(mod, to);
31
+ return to;
32
+ };
33
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
35
+
36
+ // node_modules/picocolors/picocolors.js
37
+ var require_picocolors = __commonJS((exports, module) => {
38
+ var p = process || {};
39
+ var argv = p.argv || [];
40
+ var env = p.env || {};
41
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
42
+ var formatter = (open, close, replace = open) => (input) => {
43
+ let string = "" + input, index = string.indexOf(close, open.length);
44
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
45
+ };
46
+ var replaceClose = (string, close, replace, index) => {
47
+ let result = "", cursor = 0;
48
+ do {
49
+ result += string.substring(cursor, index) + replace;
50
+ cursor = index + close.length;
51
+ index = string.indexOf(close, cursor);
52
+ } while (~index);
53
+ return result + string.substring(cursor);
54
+ };
55
+ var createColors = (enabled = isColorSupported) => {
56
+ let f = enabled ? formatter : () => String;
57
+ return {
58
+ isColorSupported: enabled,
59
+ reset: f("\x1B[0m", "\x1B[0m"),
60
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
61
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
62
+ italic: f("\x1B[3m", "\x1B[23m"),
63
+ underline: f("\x1B[4m", "\x1B[24m"),
64
+ inverse: f("\x1B[7m", "\x1B[27m"),
65
+ hidden: f("\x1B[8m", "\x1B[28m"),
66
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
67
+ black: f("\x1B[30m", "\x1B[39m"),
68
+ red: f("\x1B[31m", "\x1B[39m"),
69
+ green: f("\x1B[32m", "\x1B[39m"),
70
+ yellow: f("\x1B[33m", "\x1B[39m"),
71
+ blue: f("\x1B[34m", "\x1B[39m"),
72
+ magenta: f("\x1B[35m", "\x1B[39m"),
73
+ cyan: f("\x1B[36m", "\x1B[39m"),
74
+ white: f("\x1B[37m", "\x1B[39m"),
75
+ gray: f("\x1B[90m", "\x1B[39m"),
76
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
77
+ bgRed: f("\x1B[41m", "\x1B[49m"),
78
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
79
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
80
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
81
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
82
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
83
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
84
+ blackBright: f("\x1B[90m", "\x1B[39m"),
85
+ redBright: f("\x1B[91m", "\x1B[39m"),
86
+ greenBright: f("\x1B[92m", "\x1B[39m"),
87
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
88
+ blueBright: f("\x1B[94m", "\x1B[39m"),
89
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
90
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
91
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
92
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
93
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
94
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
95
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
96
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
97
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
98
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
99
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
100
+ };
101
+ };
102
+ module.exports = createColors();
103
+ module.exports.createColors = createColors;
104
+ });
105
+
106
+ // node_modules/isexe/dist/commonjs/index.min.js
107
+ var require_index_min = __commonJS((exports) => {
108
+ var a = (t, e) => () => (e || t((e = { exports: {} }).exports, e), e.exports);
109
+ var _ = a((i) => {
110
+ Object.defineProperty(i, "__esModule", { value: true });
111
+ i.sync = i.isexe = undefined;
112
+ var M = __require("node:fs"), x = __require("node:fs/promises"), q = async (t, e = {}) => {
113
+ let { ignoreErrors: r = false } = e;
114
+ try {
115
+ return d(await (0, x.stat)(t), e);
116
+ } catch (s) {
117
+ let n = s;
118
+ if (r || n.code === "EACCES")
119
+ return false;
120
+ throw n;
121
+ }
122
+ };
123
+ i.isexe = q;
124
+ var m = (t, e = {}) => {
125
+ let { ignoreErrors: r = false } = e;
126
+ try {
127
+ return d((0, M.statSync)(t), e);
128
+ } catch (s) {
129
+ let n = s;
130
+ if (r || n.code === "EACCES")
131
+ return false;
132
+ throw n;
133
+ }
134
+ };
135
+ i.sync = m;
136
+ var d = (t, e) => t.isFile() && A(t, e), A = (t, e) => {
137
+ let r = e.uid ?? process.getuid?.(), s = e.groups ?? process.getgroups?.() ?? [], n = e.gid ?? process.getgid?.() ?? s[0];
138
+ if (r === undefined || n === undefined)
139
+ throw new Error("cannot get uid or gid");
140
+ let u = new Set([n, ...s]), c = t.mode, S = t.uid, P = t.gid, f = parseInt("100", 8), l = parseInt("010", 8), j = parseInt("001", 8), C = f | l;
141
+ return !!(c & j || c & l && u.has(P) || c & f && S === r || c & C && r === 0);
142
+ };
143
+ });
144
+ var g = a((o) => {
145
+ Object.defineProperty(o, "__esModule", { value: true });
146
+ o.sync = o.isexe = undefined;
147
+ var T = __require("node:fs"), I = __require("node:fs/promises"), D = __require("node:path"), F = async (t, e = {}) => {
148
+ let { ignoreErrors: r = false } = e;
149
+ try {
150
+ return y(await (0, I.stat)(t), t, e);
151
+ } catch (s) {
152
+ let n = s;
153
+ if (r || n.code === "EACCES")
154
+ return false;
155
+ throw n;
156
+ }
157
+ };
158
+ o.isexe = F;
159
+ var L = (t, e = {}) => {
160
+ let { ignoreErrors: r = false } = e;
161
+ try {
162
+ return y((0, T.statSync)(t), t, e);
163
+ } catch (s) {
164
+ let n = s;
165
+ if (r || n.code === "EACCES")
166
+ return false;
167
+ throw n;
168
+ }
169
+ };
170
+ o.sync = L;
171
+ var B = (t, e) => {
172
+ let { pathExt: r = process.env.PATHEXT || "" } = e, s = r.split(D.delimiter);
173
+ if (s.indexOf("") !== -1)
174
+ return true;
175
+ for (let n of s) {
176
+ let u = n.toLowerCase(), c = t.substring(t.length - u.length).toLowerCase();
177
+ if (u && c === u)
178
+ return true;
179
+ }
180
+ return false;
181
+ }, y = (t, e, r) => t.isFile() && B(e, r);
182
+ });
183
+ var p = a((h) => {
184
+ Object.defineProperty(h, "__esModule", { value: true });
185
+ });
186
+ var v = exports && exports.__createBinding || (Object.create ? function(t, e, r, s) {
187
+ s === undefined && (s = r);
188
+ var n = Object.getOwnPropertyDescriptor(e, r);
189
+ (!n || ("get" in n ? !e.__esModule : n.writable || n.configurable)) && (n = { enumerable: true, get: function() {
190
+ return e[r];
191
+ } }), Object.defineProperty(t, s, n);
192
+ } : function(t, e, r, s) {
193
+ s === undefined && (s = r), t[s] = e[r];
194
+ });
195
+ var G = exports && exports.__setModuleDefault || (Object.create ? function(t, e) {
196
+ Object.defineProperty(t, "default", { enumerable: true, value: e });
197
+ } : function(t, e) {
198
+ t.default = e;
199
+ });
200
+ var w = exports && exports.__importStar || function() {
201
+ var t = function(e) {
202
+ return t = Object.getOwnPropertyNames || function(r) {
203
+ var s = [];
204
+ for (var n in r)
205
+ Object.prototype.hasOwnProperty.call(r, n) && (s[s.length] = n);
206
+ return s;
207
+ }, t(e);
208
+ };
209
+ return function(e) {
210
+ if (e && e.__esModule)
211
+ return e;
212
+ var r = {};
213
+ if (e != null)
214
+ for (var s = t(e), n = 0;n < s.length; n++)
215
+ s[n] !== "default" && v(r, e, s[n]);
216
+ return G(r, e), r;
217
+ };
218
+ }();
219
+ var X = exports && exports.__exportStar || function(t, e) {
220
+ for (var r in t)
221
+ r !== "default" && !Object.prototype.hasOwnProperty.call(e, r) && v(e, t, r);
222
+ };
223
+ Object.defineProperty(exports, "__esModule", { value: true });
224
+ exports.sync = exports.isexe = exports.posix = exports.win32 = undefined;
225
+ var E = w(_());
226
+ exports.posix = E;
227
+ var O = w(g());
228
+ exports.win32 = O;
229
+ X(p(), exports);
230
+ var H = process.env._ISEXE_TEST_PLATFORM_ || process.platform;
231
+ var b = H === "win32" ? O : E;
232
+ exports.isexe = b.isexe;
233
+ exports.sync = b.sync;
234
+ });
235
+
236
+ // node_modules/which/lib/index.js
237
+ var require_lib = __commonJS((exports, module) => {
238
+ var { isexe, sync: isexeSync } = require_index_min();
239
+ var { join, delimiter, sep, posix } = __require("path");
240
+ var isWindows = process.platform === "win32";
241
+ var rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? "" : sep}]`.replace(/(\\)/g, "\\$1"));
242
+ var rRel = new RegExp(`^\\.${rSlash.source}`);
243
+ var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
244
+ var getPathInfo = (cmd, {
245
+ path: optPath = process.env.PATH,
246
+ pathExt: optPathExt = process.env.PATHEXT,
247
+ delimiter: optDelimiter = delimiter
248
+ }) => {
249
+ const pathEnv = cmd.match(rSlash) ? [""] : [
250
+ ...isWindows ? [process.cwd()] : [],
251
+ ...(optPath || "").split(optDelimiter)
252
+ ];
253
+ if (isWindows) {
254
+ const pathExtExe = optPathExt || [".EXE", ".CMD", ".BAT", ".COM"].join(optDelimiter);
255
+ const pathExt = pathExtExe.split(optDelimiter).flatMap((item) => [item, item.toLowerCase()]);
256
+ if (cmd.includes(".") && pathExt[0] !== "") {
257
+ pathExt.unshift("");
258
+ }
259
+ return { pathEnv, pathExt, pathExtExe };
260
+ }
261
+ return { pathEnv, pathExt: [""] };
262
+ };
263
+ var getPathPart = (raw, cmd) => {
264
+ const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
265
+ const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
266
+ return prefix + join(pathPart, cmd);
267
+ };
268
+ var which = async (cmd, opt = {}) => {
269
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
270
+ const found = [];
271
+ for (const envPart of pathEnv) {
272
+ const p = getPathPart(envPart, cmd);
273
+ for (const ext of pathExt) {
274
+ const withExt = p + ext;
275
+ const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true });
276
+ if (is) {
277
+ if (!opt.all) {
278
+ return withExt;
279
+ }
280
+ found.push(withExt);
281
+ }
282
+ }
283
+ }
284
+ if (opt.all && found.length) {
285
+ return found;
286
+ }
287
+ if (opt.nothrow) {
288
+ return null;
289
+ }
290
+ throw getNotFoundError(cmd);
291
+ };
292
+ var whichSync = (cmd, opt = {}) => {
293
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
294
+ const found = [];
295
+ for (const pathEnvPart of pathEnv) {
296
+ const p = getPathPart(pathEnvPart, cmd);
297
+ for (const ext of pathExt) {
298
+ const withExt = p + ext;
299
+ const is = isexeSync(withExt, { pathExt: pathExtExe, ignoreErrors: true });
300
+ if (is) {
301
+ if (!opt.all) {
302
+ return withExt;
303
+ }
304
+ found.push(withExt);
305
+ }
306
+ }
307
+ }
308
+ if (opt.all && found.length) {
309
+ return found;
310
+ }
311
+ if (opt.nothrow) {
312
+ return null;
313
+ }
314
+ throw getNotFoundError(cmd);
315
+ };
316
+ module.exports = which;
317
+ which.sync = whichSync;
318
+ });
319
+
320
+ // node_modules/sisteransi/src/index.js
321
+ var require_src = __commonJS((exports, module) => {
322
+ var ESC = "\x1B";
323
+ var CSI = `${ESC}[`;
324
+ var beep = "\x07";
325
+ var cursor = {
326
+ to(x, y) {
327
+ if (!y)
328
+ return `${CSI}${x + 1}G`;
329
+ return `${CSI}${y + 1};${x + 1}H`;
330
+ },
331
+ move(x, y) {
332
+ let ret = "";
333
+ if (x < 0)
334
+ ret += `${CSI}${-x}D`;
335
+ else if (x > 0)
336
+ ret += `${CSI}${x}C`;
337
+ if (y < 0)
338
+ ret += `${CSI}${-y}A`;
339
+ else if (y > 0)
340
+ ret += `${CSI}${y}B`;
341
+ return ret;
342
+ },
343
+ up: (count = 1) => `${CSI}${count}A`,
344
+ down: (count = 1) => `${CSI}${count}B`,
345
+ forward: (count = 1) => `${CSI}${count}C`,
346
+ backward: (count = 1) => `${CSI}${count}D`,
347
+ nextLine: (count = 1) => `${CSI}E`.repeat(count),
348
+ prevLine: (count = 1) => `${CSI}F`.repeat(count),
349
+ left: `${CSI}G`,
350
+ hide: `${CSI}?25l`,
351
+ show: `${CSI}?25h`,
352
+ save: `${ESC}7`,
353
+ restore: `${ESC}8`
354
+ };
355
+ var scroll = {
356
+ up: (count = 1) => `${CSI}S`.repeat(count),
357
+ down: (count = 1) => `${CSI}T`.repeat(count)
358
+ };
359
+ var erase = {
360
+ screen: `${CSI}2J`,
361
+ up: (count = 1) => `${CSI}1J`.repeat(count),
362
+ down: (count = 1) => `${CSI}J`.repeat(count),
363
+ line: `${CSI}2K`,
364
+ lineEnd: `${CSI}K`,
365
+ lineStart: `${CSI}1K`,
366
+ lines(count) {
367
+ let clear = "";
368
+ for (let i = 0;i < count; i++)
369
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
370
+ if (count)
371
+ clear += cursor.left;
372
+ return clear;
373
+ }
374
+ };
375
+ module.exports = { cursor, scroll, erase, beep };
376
+ });
377
+
378
+ // src/index.ts
379
+ var import_picocolors5 = __toESM(require_picocolors(), 1);
380
+ import { spawn as spawn5 } from "node:child_process";
381
+ import fs8 from "node:fs/promises";
382
+ import path7 from "node:path";
383
+
384
+ // src/agents.ts
385
+ var import_which = __toESM(require_lib(), 1);
386
+ import fs from "node:fs/promises";
387
+ import os from "node:os";
388
+ import path from "node:path";
389
+ var HOME = os.homedir();
390
+ var braceDollar = (v) => "${" + v + "}";
391
+ var envBrace = (v) => "{env:" + v + "}";
392
+ var plainDollar = (v) => "$" + v;
393
+ function bearer(c, interp) {
394
+ if (c.authMode === "none")
395
+ return;
396
+ return c.authMode === "env" ? `Bearer ${interp(c.envVarName)}` : `Bearer ${c.token}`;
397
+ }
398
+ function httpEntry(interp, opts = {}) {
399
+ const typeValue = opts.typeValue === undefined ? "http" : opts.typeValue;
400
+ const urlField = opts.urlField ?? "url";
401
+ return (c) => {
402
+ const e = {};
403
+ if (typeValue)
404
+ e.type = typeValue;
405
+ e[urlField] = c.url;
406
+ if (opts.extra)
407
+ Object.assign(e, opts.extra);
408
+ const h = bearer(c, interp);
409
+ if (h)
410
+ e.headers = { Authorization: h };
411
+ return e;
412
+ };
413
+ }
414
+ function codexEntry(c) {
415
+ if (c.authMode === "none")
416
+ return { url: c.url };
417
+ if (c.authMode === "env")
418
+ return { url: c.url, bearer_token_env_var: c.envVarName };
419
+ return { url: c.url, http_headers: { Authorization: `Bearer ${c.token}` } };
420
+ }
421
+ var AGENTS = [
422
+ {
423
+ id: "claude",
424
+ label: "Claude Code",
425
+ kind: "cli",
426
+ bin: "claude",
427
+ binPaths: [
428
+ path.join(HOME, ".claude", "local", "claude"),
429
+ path.join(HOME, ".local", "bin", "claude"),
430
+ "/opt/homebrew/bin/claude",
431
+ "/usr/local/bin/claude"
432
+ ],
433
+ installCmd: ["npm", "install", "-g", "@anthropic-ai/claude-code"],
434
+ scope: "project",
435
+ configPath: ".mcp.json",
436
+ format: "json",
437
+ containerKey: "mcpServers",
438
+ authMode: "env",
439
+ markers: [".mcp.json", ".claude"],
440
+ entry: httpEntry(braceDollar)
441
+ },
442
+ {
443
+ id: "codex",
444
+ label: "Codex",
445
+ kind: "cli",
446
+ bin: "codex",
447
+ binPaths: [path.join(HOME, ".local", "bin", "codex"), "/opt/homebrew/bin/codex", "/usr/local/bin/codex"],
448
+ installCmd: ["npm", "install", "-g", "@openai/codex"],
449
+ scope: "project",
450
+ configPath: path.join(".codex", "config.toml"),
451
+ format: "toml",
452
+ containerKey: "mcp_servers",
453
+ authMode: "env",
454
+ markers: [".codex"],
455
+ entry: codexEntry
456
+ },
457
+ {
458
+ id: "gemini",
459
+ label: "Gemini CLI",
460
+ kind: "cli",
461
+ bin: "gemini",
462
+ binPaths: [path.join(HOME, ".local", "bin", "gemini"), "/opt/homebrew/bin/gemini", "/usr/local/bin/gemini"],
463
+ installCmd: ["npm", "install", "-g", "@google/gemini-cli"],
464
+ scope: "project",
465
+ configPath: path.join(".gemini", "settings.json"),
466
+ format: "json",
467
+ containerKey: "mcpServers",
468
+ authMode: "env",
469
+ markers: [".gemini"],
470
+ homeMarkers: [".gemini"],
471
+ entry: httpEntry(braceDollar, { typeValue: null, urlField: "httpUrl" })
472
+ },
473
+ {
474
+ id: "opencode",
475
+ label: "OpenCode",
476
+ kind: "cli",
477
+ bin: "opencode",
478
+ binPaths: [path.join(HOME, ".local", "bin", "opencode"), "/opt/homebrew/bin/opencode", "/usr/local/bin/opencode"],
479
+ installCmd: ["npm", "install", "-g", "opencode-ai"],
480
+ scope: "project",
481
+ configPath: "opencode.json",
482
+ format: "json",
483
+ containerKey: "mcp",
484
+ authMode: "env",
485
+ markers: ["opencode.json", ".opencode"],
486
+ entry: httpEntry(envBrace, { typeValue: "remote", extra: { enabled: true } })
487
+ },
488
+ {
489
+ id: "copilot",
490
+ label: "Copilot CLI",
491
+ kind: "cli",
492
+ bin: "copilot",
493
+ binPaths: [path.join(HOME, ".local", "bin", "copilot")],
494
+ installCmd: ["npm", "install", "-g", "@github/copilot"],
495
+ scope: "global",
496
+ configPath: path.join(HOME, ".copilot", "mcp-config.json"),
497
+ format: "json",
498
+ containerKey: "mcpServers",
499
+ authMode: "env",
500
+ homeMarkers: [".copilot"],
501
+ entry: httpEntry(plainDollar)
502
+ },
503
+ {
504
+ id: "cursor",
505
+ label: "Cursor",
506
+ kind: "gui",
507
+ scope: "project",
508
+ configPath: path.join(".cursor", "mcp.json"),
509
+ format: "json",
510
+ containerKey: "mcpServers",
511
+ authMode: "literal",
512
+ markers: [".cursor"],
513
+ homeMarkers: [".cursor"],
514
+ entry: httpEntry(braceDollar)
515
+ },
516
+ {
517
+ id: "windsurf",
518
+ label: "Windsurf",
519
+ kind: "gui",
520
+ scope: "project",
521
+ configPath: path.join(".windsurf", "mcp_config.json"),
522
+ format: "json",
523
+ containerKey: "mcpServers",
524
+ authMode: "literal",
525
+ markers: [".windsurf"],
526
+ homeMarkers: [".codeium", ".windsurf"],
527
+ entry: httpEntry(braceDollar)
528
+ },
529
+ {
530
+ id: "vscode",
531
+ label: "VS Code / Copilot",
532
+ kind: "gui",
533
+ scope: "project",
534
+ configPath: path.join(".vscode", "mcp.json"),
535
+ format: "json",
536
+ containerKey: "servers",
537
+ authMode: "literal",
538
+ markers: [path.join(".vscode", "mcp.json"), path.join(".github", "copilot-instructions.md")],
539
+ vscodeExt: true,
540
+ entry: httpEntry(braceDollar)
541
+ }
542
+ ];
543
+ var LAUNCHABLE = AGENTS.filter((a) => a.kind === "cli");
544
+ function findAgent(id) {
545
+ return AGENTS.find((a) => a.id === id);
546
+ }
547
+ function configFileFor(agent, cwd) {
548
+ return agent.scope === "global" ? agent.configPath : path.join(cwd, agent.configPath);
549
+ }
550
+ async function findBin(agent) {
551
+ if (agent.bin) {
552
+ try {
553
+ return await import_which.default(agent.bin);
554
+ } catch {}
555
+ }
556
+ for (const p of agent.binPaths ?? []) {
557
+ if (await exists(p))
558
+ return p;
559
+ }
560
+ return null;
561
+ }
562
+ async function detectAgents(cwd, include = []) {
563
+ const out = [];
564
+ for (const a of AGENTS) {
565
+ if (a.id === "claude" || include.includes(a.id) || await isDetected(a, cwd)) {
566
+ out.push(a);
567
+ }
568
+ }
569
+ return out;
570
+ }
571
+ async function isDetected(a, cwd) {
572
+ if (a.bin && await findBin(a))
573
+ return true;
574
+ for (const m of a.markers ?? []) {
575
+ if (await exists(path.join(cwd, m)))
576
+ return true;
577
+ }
578
+ for (const m of a.homeMarkers ?? []) {
579
+ if (await exists(path.join(HOME, m)))
580
+ return true;
581
+ }
582
+ if (a.vscodeExt && await hasVscodeCopilot())
583
+ return true;
584
+ return false;
585
+ }
586
+ async function hasVscodeCopilot() {
587
+ const roots = [
588
+ path.join(HOME, ".vscode", "extensions"),
589
+ path.join(HOME, ".vscode-insiders", "extensions")
590
+ ];
591
+ for (const root of roots) {
592
+ try {
593
+ const entries = await fs.readdir(root);
594
+ if (entries.some((e) => e.toLowerCase().startsWith("github.copilot")))
595
+ return true;
596
+ } catch {}
597
+ }
598
+ return false;
599
+ }
600
+ async function exists(p) {
601
+ try {
602
+ await fs.access(p);
603
+ return true;
604
+ } catch {
605
+ return false;
606
+ }
607
+ }
608
+
609
+ // src/config.ts
610
+ import fs2 from "node:fs/promises";
611
+
612
+ // src/paths.ts
613
+ import path2 from "node:path";
614
+ import os2 from "node:os";
615
+ function xdgConfigHome() {
616
+ return process.env.XDG_CONFIG_HOME || path2.join(os2.homedir(), ".config");
617
+ }
618
+ var juspayConfigDir = path2.join(xdgConfigHome(), "juspay");
619
+ var juspayConfigPath = path2.join(juspayConfigDir, "config.json");
620
+ var juspayOauthPath = path2.join(juspayConfigDir, "oauth.json");
621
+
622
+ // src/config.ts
623
+ async function readConfig() {
624
+ let raw;
625
+ try {
626
+ raw = await fs2.readFile(juspayConfigPath, "utf8");
627
+ } catch (err) {
628
+ if (err.code === "ENOENT")
629
+ return null;
630
+ throw err;
631
+ }
632
+ const parsed = JSON.parse(raw);
633
+ if (!isConfig(parsed)) {
634
+ throw new Error(`Invalid config at ${juspayConfigPath}. Expected { merchant_id, client_id, environment }. ` + "Re-run `npx @sahyll/ai init` to recreate.");
635
+ }
636
+ return parsed;
637
+ }
638
+ async function writeConfig(config) {
639
+ await fs2.mkdir(juspayConfigDir, { recursive: true });
640
+ await fs2.writeFile(juspayConfigPath, JSON.stringify(config, null, 2) + `
641
+ `, "utf8");
642
+ await fs2.chmod(juspayConfigPath, 384);
643
+ }
644
+ function isConfig(value) {
645
+ if (!value || typeof value !== "object")
646
+ return false;
647
+ const v = value;
648
+ return typeof v.merchant_id === "string" && v.merchant_id.length > 0 && typeof v.client_id === "string" && v.client_id.length > 0 && (v.environment === "sandbox" || v.environment === "production");
649
+ }
650
+
651
+ // src/servers.ts
652
+ var JUSPAY_MCP_ISSUER = "https://mcp.juspay.in/dashboard";
653
+ var JUSPAY_MCP_ENDPOINT = "https://mcp.juspay.in/dashboard/juspay-dashboard-stream";
654
+ var DOCS_MCP_ENDPOINT = "https://mcp.juspay.in/dashboard/juspay-docs-stream";
655
+ var DOCS_MCP_NAME = "docs-mcp-server";
656
+ var DASHBOARD_MCP_NAME = "juspay-mcp";
657
+ var OUR_MCP_NAMES = [DOCS_MCP_NAME, DASHBOARD_MCP_NAME];
658
+ var MCP_TOKEN_VAR = "JUSPAY_MCP_TOKEN";
659
+ var SKILLS_PACKAGE = "sahyll/juspay-skills/skills/integrate";
660
+ var PACKAGE_NAME = "@sahyll/ai";
661
+ var CLI_VERSION = "0.4.0";
662
+ var USER_AGENT = `juspay-ai-cli/${CLI_VERSION} (+https://juspay.in)`;
663
+
664
+ // src/mcp-call.ts
665
+ async function callMcpTool(endpoint, bearer2, tool, args = {}) {
666
+ let sessionId;
667
+ const initResult = await rpc(endpoint, bearer2, sessionId, {
668
+ jsonrpc: "2.0",
669
+ id: 1,
670
+ method: "initialize",
671
+ params: {
672
+ protocolVersion: "2025-06-18",
673
+ capabilities: {},
674
+ clientInfo: { name: "juspay-ai-cli", version: CLI_VERSION }
675
+ }
676
+ });
677
+ sessionId = initResult.sessionId;
678
+ if ("error" in initResult.body) {
679
+ throw new Error(`MCP initialize failed: ${initResult.body.error.message}`);
680
+ }
681
+ await postNotification(endpoint, bearer2, sessionId, {
682
+ jsonrpc: "2.0",
683
+ method: "notifications/initialized"
684
+ });
685
+ const callResult = await rpc(endpoint, bearer2, sessionId, {
686
+ jsonrpc: "2.0",
687
+ id: 2,
688
+ method: "tools/call",
689
+ params: { name: tool, arguments: args }
690
+ });
691
+ if ("error" in callResult.body) {
692
+ throw new Error(`MCP tool '${tool}' failed: ${callResult.body.error.message}`);
693
+ }
694
+ return callResult.body.result;
695
+ }
696
+ async function rpc(endpoint, bearer2, sessionId, payload) {
697
+ const res = await fetch(endpoint, {
698
+ method: "POST",
699
+ headers: buildHeaders(bearer2, sessionId),
700
+ body: JSON.stringify(payload)
701
+ });
702
+ if (!res.ok) {
703
+ const text = await res.text().catch(() => "");
704
+ throw new Error(`MCP HTTP ${res.status}: ${text.slice(0, 400)}`);
705
+ }
706
+ const sid = res.headers.get("mcp-session-id") ?? sessionId;
707
+ const body = await readJsonRpc(res);
708
+ return { body, sessionId: sid ?? undefined };
709
+ }
710
+ async function postNotification(endpoint, bearer2, sessionId, payload) {
711
+ await fetch(endpoint, {
712
+ method: "POST",
713
+ headers: buildHeaders(bearer2, sessionId),
714
+ body: JSON.stringify(payload)
715
+ });
716
+ }
717
+ function buildHeaders(bearer2, sessionId) {
718
+ const h = {
719
+ "Content-Type": "application/json",
720
+ Accept: "application/json, text/event-stream",
721
+ Authorization: `Bearer ${bearer2}`,
722
+ "User-Agent": USER_AGENT
723
+ };
724
+ if (sessionId)
725
+ h["Mcp-Session-Id"] = sessionId;
726
+ return h;
727
+ }
728
+ async function readJsonRpc(res) {
729
+ const ct = res.headers.get("content-type") ?? "";
730
+ const text = await res.text();
731
+ if (ct.includes("text/event-stream")) {
732
+ for (const line of text.split(/\r?\n/)) {
733
+ if (line.startsWith("data:")) {
734
+ const json = line.slice(5).trim();
735
+ if (json)
736
+ return JSON.parse(json);
737
+ }
738
+ }
739
+ throw new Error("SSE response contained no JSON-RPC payload.");
740
+ }
741
+ return JSON.parse(text);
742
+ }
743
+
744
+ // src/oauth.ts
745
+ var import_picocolors = __toESM(require_picocolors(), 1);
746
+ import crypto from "node:crypto";
747
+ import http from "node:http";
748
+ import { spawn } from "node:child_process";
749
+ var REDIRECT_PORT = 33418;
750
+ var REDIRECT_URI = `http://localhost:${REDIRECT_PORT}/callback`;
751
+ var OAUTH_TIMEOUT_MS = 5 * 60 * 1000;
752
+ var SCOPES = [
753
+ "analytics:read",
754
+ "orders:read",
755
+ "orders:write",
756
+ "settings:read",
757
+ "gateways:read",
758
+ "reports:read",
759
+ "users:read",
760
+ "alerts:read"
761
+ ].join(" ");
762
+ async function runOAuthFlow(issuer) {
763
+ const meta = await discover(issuer);
764
+ const dcr = await registerClient(meta.registration_endpoint);
765
+ const verifier = base64url(crypto.randomBytes(32));
766
+ const challenge = base64url(crypto.createHash("sha256").update(verifier).digest());
767
+ const state = base64url(crypto.randomBytes(16));
768
+ const { code, returnedState } = await captureCode((codeUrl) => {
769
+ const authUrl = meta.authorization_endpoint + "?" + new URLSearchParams({
770
+ response_type: "code",
771
+ client_id: dcr.client_id,
772
+ redirect_uri: REDIRECT_URI,
773
+ scope: SCOPES,
774
+ state,
775
+ code_challenge: challenge,
776
+ code_challenge_method: "S256"
777
+ }).toString();
778
+ process.stdout.write(" " + import_picocolors.default.dim(`If the browser doesn't open: ${authUrl}
779
+ `));
780
+ openBrowser(authUrl);
781
+ return codeUrl;
782
+ });
783
+ if (returnedState !== state) {
784
+ throw new Error("OAuth state mismatch — aborting.");
785
+ }
786
+ const tok = await exchangeCode({
787
+ tokenEndpoint: meta.token_endpoint,
788
+ code,
789
+ verifier,
790
+ clientId: dcr.client_id,
791
+ clientSecret: dcr.client_secret
792
+ });
793
+ const issuedAt = Math.floor(Date.now() / 1000);
794
+ return {
795
+ issuer,
796
+ client_id: dcr.client_id,
797
+ client_secret: dcr.client_secret,
798
+ access_token: tok.access_token,
799
+ refresh_token: tok.refresh_token,
800
+ expires_at: issuedAt + tok.expires_in,
801
+ scope: tok.scope ?? SCOPES
802
+ };
803
+ }
804
+ async function refreshOAuthFlow(state) {
805
+ const meta = await discover(state.issuer);
806
+ const tok = await refreshToken({
807
+ tokenEndpoint: meta.token_endpoint,
808
+ refreshToken: state.refresh_token,
809
+ clientId: state.client_id,
810
+ clientSecret: state.client_secret
811
+ });
812
+ const issuedAt = Math.floor(Date.now() / 1000);
813
+ return {
814
+ issuer: state.issuer,
815
+ client_id: state.client_id,
816
+ client_secret: state.client_secret,
817
+ access_token: tok.access_token,
818
+ refresh_token: tok.refresh_token ?? state.refresh_token,
819
+ expires_at: issuedAt + tok.expires_in,
820
+ scope: tok.scope ?? state.scope
821
+ };
822
+ }
823
+ async function discover(issuer) {
824
+ const url = issuer.replace(/\/$/, "") + "/.well-known/oauth-authorization-server";
825
+ const r = await fetchJson(url);
826
+ if (!r.authorization_endpoint || !r.token_endpoint || !r.registration_endpoint) {
827
+ throw new Error(`Auth server metadata at ${url} is missing required endpoints.`);
828
+ }
829
+ return r;
830
+ }
831
+ async function registerClient(registrationEndpoint) {
832
+ const body = {
833
+ client_name: "juspay-ai-cli",
834
+ redirect_uris: [REDIRECT_URI],
835
+ grant_types: ["authorization_code", "refresh_token"],
836
+ response_types: ["code"],
837
+ scope: SCOPES
838
+ };
839
+ const r = await fetchJson(registrationEndpoint, {
840
+ method: "POST",
841
+ headers: { "Content-Type": "application/json" },
842
+ body: JSON.stringify(body)
843
+ });
844
+ if (!r.client_id || !r.client_secret) {
845
+ throw new Error("Dynamic client registration did not return client_id/client_secret.");
846
+ }
847
+ return r;
848
+ }
849
+ async function exchangeCode(params) {
850
+ const form = new URLSearchParams({
851
+ grant_type: "authorization_code",
852
+ code: params.code,
853
+ redirect_uri: REDIRECT_URI,
854
+ client_id: params.clientId,
855
+ client_secret: params.clientSecret,
856
+ code_verifier: params.verifier
857
+ });
858
+ const r = await fetchJson(params.tokenEndpoint, {
859
+ method: "POST",
860
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
861
+ body: form.toString()
862
+ });
863
+ if (!r.access_token || !r.refresh_token || typeof r.expires_in !== "number") {
864
+ throw new Error("Token endpoint did not return access_token/refresh_token/expires_in.");
865
+ }
866
+ return r;
867
+ }
868
+ async function refreshToken(params) {
869
+ const form = new URLSearchParams({
870
+ grant_type: "refresh_token",
871
+ refresh_token: params.refreshToken,
872
+ client_id: params.clientId,
873
+ client_secret: params.clientSecret
874
+ });
875
+ const r = await fetchJson(params.tokenEndpoint, {
876
+ method: "POST",
877
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
878
+ body: form.toString()
879
+ });
880
+ if (!r.access_token || typeof r.expires_in !== "number") {
881
+ throw new Error("Refresh token endpoint did not return access_token/expires_in.");
882
+ }
883
+ return r;
884
+ }
885
+ function captureCode(startBrowser) {
886
+ return new Promise((resolve, reject) => {
887
+ let timer = null;
888
+ const cleanup = () => {
889
+ if (timer)
890
+ clearTimeout(timer);
891
+ server.close();
892
+ };
893
+ const server = http.createServer((req, res) => {
894
+ if (!req.url)
895
+ return;
896
+ const u = new URL(req.url, REDIRECT_URI);
897
+ if (u.pathname !== "/callback") {
898
+ res.writeHead(404);
899
+ res.end();
900
+ return;
901
+ }
902
+ const code = u.searchParams.get("code");
903
+ const returnedState = u.searchParams.get("state") ?? "";
904
+ const error = u.searchParams.get("error");
905
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
906
+ if (error) {
907
+ res.end(`<h2>Sign-in failed: ${escapeHtml(error)}</h2><p>You can close this tab.</p>`);
908
+ cleanup();
909
+ reject(new Error(`OAuth error from authorization server: ${error}`));
910
+ return;
911
+ }
912
+ if (!code) {
913
+ res.end("<h2>Missing code.</h2><p>You can close this tab.</p>");
914
+ cleanup();
915
+ reject(new Error("Authorization server callback was missing the code parameter."));
916
+ return;
917
+ }
918
+ res.end("<h2>Signed in successfully.</h2><p>You can close this tab and return to the terminal.</p>");
919
+ cleanup();
920
+ resolve({ code, returnedState });
921
+ });
922
+ server.on("error", (err) => {
923
+ cleanup();
924
+ if (err.code === "EADDRINUSE") {
925
+ reject(new Error(`Port ${REDIRECT_PORT} is already in use. Close whatever is using it and re-run \`npx @sahyll/ai init\`.`));
926
+ } else {
927
+ reject(err);
928
+ }
929
+ });
930
+ server.listen(REDIRECT_PORT, "127.0.0.1", () => {
931
+ startBrowser(REDIRECT_URI);
932
+ timer = setTimeout(() => {
933
+ cleanup();
934
+ reject(new Error(`Sign-in timed out after ${OAUTH_TIMEOUT_MS / 60000} minutes. Re-run \`npx @sahyll/ai init\` to retry.`));
935
+ }, OAUTH_TIMEOUT_MS);
936
+ });
937
+ });
938
+ }
939
+ function openBrowser(url) {
940
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
941
+ const args = process.platform === "win32" ? ["", url] : [url];
942
+ spawn(cmd, args, { stdio: "ignore", detached: true, shell: process.platform === "win32" }).unref();
943
+ }
944
+ async function fetchJson(url, init) {
945
+ let res;
946
+ try {
947
+ res = await fetch(url, {
948
+ ...init,
949
+ headers: {
950
+ Accept: "application/json",
951
+ "User-Agent": USER_AGENT,
952
+ ...init?.headers ?? {}
953
+ }
954
+ });
955
+ } catch (err) {
956
+ const cause = err.cause;
957
+ const detail = cause?.code ? `${cause.code}${cause.message ? ` — ${cause.message}` : ""}` : err.message;
958
+ throw new Error(`Could not reach ${url}
959
+ ${detail}`);
960
+ }
961
+ if (!res.ok) {
962
+ const text = await res.text().catch(() => "");
963
+ throw new Error(`HTTP ${res.status} from ${url}${text ? `: ${text.slice(0, 300)}` : ""}`);
964
+ }
965
+ return res.json();
966
+ }
967
+ function base64url(buf) {
968
+ return buf.toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
969
+ }
970
+ function escapeHtml(s) {
971
+ return s.replace(/[&<>"']/g, (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : c === ">" ? "&gt;" : c === '"' ? "&quot;" : "&#39;");
972
+ }
973
+
974
+ // src/oauth-config.ts
975
+ import fs3 from "node:fs/promises";
976
+ async function readOAuth() {
977
+ let raw;
978
+ try {
979
+ raw = await fs3.readFile(juspayOauthPath, "utf8");
980
+ } catch (err) {
981
+ if (err.code === "ENOENT")
982
+ return null;
983
+ throw err;
984
+ }
985
+ const parsed = JSON.parse(raw);
986
+ if (!isOAuthState(parsed)) {
987
+ throw new Error(`Invalid OAuth state at ${juspayOauthPath}. Re-run \`npx @sahyll/ai init\` to recreate.`);
988
+ }
989
+ return parsed;
990
+ }
991
+ async function writeOAuth(state) {
992
+ await fs3.mkdir(juspayConfigDir, { recursive: true });
993
+ await fs3.writeFile(juspayOauthPath, JSON.stringify(state, null, 2) + `
994
+ `, "utf8");
995
+ await fs3.chmod(juspayOauthPath, 384);
996
+ }
997
+ function isOAuthState(value) {
998
+ if (!value || typeof value !== "object")
999
+ return false;
1000
+ const v = value;
1001
+ return typeof v.issuer === "string" && typeof v.client_id === "string" && typeof v.client_secret === "string" && typeof v.access_token === "string" && typeof v.refresh_token === "string" && typeof v.expires_at === "number" && typeof v.scope === "string";
1002
+ }
1003
+
1004
+ // src/ui.ts
1005
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
1006
+ var ANSI_RE = /\x1B\[[0-9;]*m/g;
1007
+ function visibleLen(s) {
1008
+ return s.replace(ANSI_RE, "").length;
1009
+ }
1010
+ var SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
1011
+
1012
+ class Spinner {
1013
+ timer = null;
1014
+ frame = 0;
1015
+ message;
1016
+ interactive;
1017
+ constructor(message) {
1018
+ this.message = message;
1019
+ this.interactive = Boolean(process.stdout.isTTY);
1020
+ }
1021
+ start() {
1022
+ if (!this.interactive) {
1023
+ process.stdout.write(" " + import_picocolors2.default.dim("→ ") + this.message + `
1024
+ `);
1025
+ return this;
1026
+ }
1027
+ process.stdout.write("\x1B[?25l");
1028
+ this.render();
1029
+ this.timer = setInterval(() => this.render(), 80);
1030
+ return this;
1031
+ }
1032
+ update(message) {
1033
+ this.message = message;
1034
+ if (!this.interactive) {
1035
+ process.stdout.write(" " + import_picocolors2.default.dim("→ ") + message + `
1036
+ `);
1037
+ }
1038
+ }
1039
+ done(finalMessage) {
1040
+ this.stop();
1041
+ process.stdout.write(" " + import_picocolors2.default.green("✓ ") + finalMessage + `
1042
+ `);
1043
+ }
1044
+ fail(finalMessage) {
1045
+ this.stop();
1046
+ process.stdout.write(" " + import_picocolors2.default.red("✗ ") + finalMessage + `
1047
+ `);
1048
+ }
1049
+ render() {
1050
+ const glyph = import_picocolors2.default.cyan(SPINNER_FRAMES[this.frame]);
1051
+ process.stdout.write("\r\x1B[K " + glyph + " " + this.message);
1052
+ this.frame = (this.frame + 1) % SPINNER_FRAMES.length;
1053
+ }
1054
+ stop() {
1055
+ if (this.timer) {
1056
+ clearInterval(this.timer);
1057
+ this.timer = null;
1058
+ }
1059
+ if (this.interactive) {
1060
+ process.stdout.write("\r\x1B[K");
1061
+ process.stdout.write("\x1B[?25h");
1062
+ }
1063
+ }
1064
+ }
1065
+ function spin(message) {
1066
+ return new Spinner(message).start();
1067
+ }
1068
+ function banner() {
1069
+ process.stdout.write(`
1070
+ `);
1071
+ process.stdout.write(" " + import_picocolors2.default.cyan(import_picocolors2.default.bold("Juspay for AI agents")) + `
1072
+ `);
1073
+ process.stdout.write(`
1074
+ `);
1075
+ }
1076
+ function step(msg) {
1077
+ process.stdout.write(" " + import_picocolors2.default.dim("→ ") + msg + `
1078
+ `);
1079
+ }
1080
+ function done(msg) {
1081
+ process.stdout.write(" " + import_picocolors2.default.green("✓ ") + msg + `
1082
+ `);
1083
+ }
1084
+ function info(msg) {
1085
+ process.stdout.write(" " + import_picocolors2.default.dim(msg) + `
1086
+ `);
1087
+ }
1088
+ function warn(msg) {
1089
+ process.stdout.write(" " + import_picocolors2.default.yellow("⚠ ") + msg + `
1090
+ `);
1091
+ }
1092
+ function summaryBox(title, rows) {
1093
+ const labelWidth = Math.max(...rows.map((r) => visibleLen(r.label)));
1094
+ const composed = rows.map((r) => {
1095
+ const padding = " ".repeat(labelWidth - visibleLen(r.label) + 2);
1096
+ return import_picocolors2.default.green("✓ ") + import_picocolors2.default.bold(r.label) + padding + r.value;
1097
+ });
1098
+ const widest = Math.max(visibleLen(` Setup `) + title.length, ...composed.map(visibleLen));
1099
+ const innerWidth = Math.max(widest + 4, 44);
1100
+ const top = " " + import_picocolors2.default.dim("╭─ ") + import_picocolors2.default.bold(title) + " " + import_picocolors2.default.dim("─".repeat(innerWidth - title.length - 4)) + import_picocolors2.default.dim("╮");
1101
+ const empty = " " + import_picocolors2.default.dim("│") + " ".repeat(innerWidth) + import_picocolors2.default.dim("│");
1102
+ const bottom = " " + import_picocolors2.default.dim("╰" + "─".repeat(innerWidth) + "╯");
1103
+ process.stdout.write(`
1104
+ `);
1105
+ process.stdout.write(top + `
1106
+ `);
1107
+ process.stdout.write(empty + `
1108
+ `);
1109
+ for (const line of composed) {
1110
+ const pad = " ".repeat(Math.max(0, innerWidth - visibleLen(line) - 4));
1111
+ process.stdout.write(" " + import_picocolors2.default.dim("│") + " " + line + pad + " " + import_picocolors2.default.dim("│") + `
1112
+ `);
1113
+ }
1114
+ process.stdout.write(empty + `
1115
+ `);
1116
+ process.stdout.write(bottom + `
1117
+ `);
1118
+ }
1119
+
1120
+ // src/init.ts
1121
+ async function runInit(opts = {}) {
1122
+ const tokens = await acquireTokens({ force: opts.force ?? false });
1123
+ const expiresOn = new Date(tokens.expires_at * 1000).toDateString();
1124
+ done(`Authenticated · session valid until ${expiresOn}`);
1125
+ const s = spin("Fetching merchant details...");
1126
+ let merchantId;
1127
+ try {
1128
+ merchantId = await fetchMerchantId(tokens.access_token);
1129
+ } catch (err) {
1130
+ s.fail("Could not fetch merchant details");
1131
+ throw err;
1132
+ }
1133
+ s.done(`Merchant: ${merchantId}`);
1134
+ return {
1135
+ merchant_id: merchantId,
1136
+ client_id: merchantId,
1137
+ environment: opts.env ?? "production"
1138
+ };
1139
+ }
1140
+ async function acquireTokens(opts) {
1141
+ if (!opts.force) {
1142
+ const existing = await readOAuth().catch(() => null);
1143
+ if (existing && isStillValid(existing)) {
1144
+ try {
1145
+ const refreshed = await refreshOAuthFlow(existing);
1146
+ await writeOAuth(refreshed);
1147
+ return refreshed;
1148
+ } catch {
1149
+ return existing;
1150
+ }
1151
+ }
1152
+ }
1153
+ step("Opening browser for sign-in...");
1154
+ const fresh = await runOAuthFlow(JUSPAY_MCP_ISSUER);
1155
+ await writeOAuth(fresh);
1156
+ return fresh;
1157
+ }
1158
+ function isStillValid(state) {
1159
+ const skewSeconds = 24 * 60 * 60;
1160
+ return state.expires_at > Math.floor(Date.now() / 1000) + skewSeconds;
1161
+ }
1162
+ async function fetchMerchantId(bearer2) {
1163
+ const result = await callMcpTool(JUSPAY_MCP_ENDPOINT, bearer2, "juspay_get_merchant_details", {});
1164
+ const merchantId = extractMerchantId(result);
1165
+ if (!merchantId) {
1166
+ throw new Error("Could not find merchantId in juspay_get_merchant_details response. " + "Report this issue if it persists.");
1167
+ }
1168
+ return merchantId;
1169
+ }
1170
+ function extractMerchantId(result) {
1171
+ if (!result || typeof result !== "object")
1172
+ return;
1173
+ const r = result;
1174
+ if (typeof r.merchantId === "string")
1175
+ return r.merchantId;
1176
+ if (r.structuredContent && typeof r.structuredContent === "object") {
1177
+ const sc = r.structuredContent;
1178
+ if (typeof sc.merchantId === "string")
1179
+ return sc.merchantId;
1180
+ }
1181
+ if (Array.isArray(r.content)) {
1182
+ for (const item of r.content) {
1183
+ if (item && typeof item === "object") {
1184
+ const it = item;
1185
+ if (it.type === "text" && typeof it.text === "string") {
1186
+ try {
1187
+ const parsed = JSON.parse(it.text);
1188
+ if (typeof parsed.merchantId === "string")
1189
+ return parsed.merchantId;
1190
+ } catch {}
1191
+ }
1192
+ }
1193
+ }
1194
+ }
1195
+ return;
1196
+ }
1197
+
1198
+ // src/launcher.ts
1199
+ import { spawn as spawn2 } from "node:child_process";
1200
+ import fs4 from "node:fs/promises";
1201
+ import os3 from "node:os";
1202
+ import path3 from "node:path";
1203
+
1204
+ // node_modules/@clack/core/dist/index.mjs
1205
+ var import_sisteransi = __toESM(require_src(), 1);
1206
+ import { stdin as j, stdout as M } from "node:process";
1207
+ import O from "node:readline";
1208
+ import { Writable as X } from "node:stream";
1209
+ function DD({ onlyFirst: e = false } = {}) {
1210
+ const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
1211
+ return new RegExp(t, e ? undefined : "g");
1212
+ }
1213
+ var uD = DD();
1214
+ function P(e) {
1215
+ if (typeof e != "string")
1216
+ throw new TypeError(`Expected a \`string\`, got \`${typeof e}\``);
1217
+ return e.replace(uD, "");
1218
+ }
1219
+ function L(e) {
1220
+ return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
1221
+ }
1222
+ var W = { exports: {} };
1223
+ (function(e) {
1224
+ var u = {};
1225
+ e.exports = u, u.eastAsianWidth = function(F) {
1226
+ var s = F.charCodeAt(0), i = F.length == 2 ? F.charCodeAt(1) : 0, D = s;
1227
+ return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D = s << 10 | i, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
1228
+ }, u.characterLength = function(F) {
1229
+ var s = this.eastAsianWidth(F);
1230
+ return s == "F" || s == "W" || s == "A" ? 2 : 1;
1231
+ };
1232
+ function t(F) {
1233
+ return F.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
1234
+ }
1235
+ u.length = function(F) {
1236
+ for (var s = t(F), i = 0, D = 0;D < s.length; D++)
1237
+ i = i + this.characterLength(s[D]);
1238
+ return i;
1239
+ }, u.slice = function(F, s, i) {
1240
+ textLen = u.length(F), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
1241
+ for (var D = "", r = 0, n = t(F), E = 0;E < n.length; E++) {
1242
+ var a = n[E], o = u.length(a);
1243
+ if (r >= s - (o == 2 ? 1 : 0))
1244
+ if (r + o <= i)
1245
+ D += a;
1246
+ else
1247
+ break;
1248
+ r += o;
1249
+ }
1250
+ return D;
1251
+ };
1252
+ })(W);
1253
+ var tD = W.exports;
1254
+ var eD = L(tD);
1255
+ var FD = function() {
1256
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
1257
+ };
1258
+ var sD = L(FD);
1259
+ function p(e, u = {}) {
1260
+ if (typeof e != "string" || e.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, e = P(e), e.length === 0))
1261
+ return 0;
1262
+ e = e.replace(sD(), " ");
1263
+ const t = u.ambiguousIsNarrow ? 1 : 2;
1264
+ let F = 0;
1265
+ for (const s of e) {
1266
+ const i = s.codePointAt(0);
1267
+ if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879)
1268
+ continue;
1269
+ switch (eD.eastAsianWidth(s)) {
1270
+ case "F":
1271
+ case "W":
1272
+ F += 2;
1273
+ break;
1274
+ case "A":
1275
+ F += t;
1276
+ break;
1277
+ default:
1278
+ F += 1;
1279
+ }
1280
+ }
1281
+ return F;
1282
+ }
1283
+ var w = 10;
1284
+ var N = (e = 0) => (u) => `\x1B[${u + e}m`;
1285
+ var I = (e = 0) => (u) => `\x1B[${38 + e};5;${u}m`;
1286
+ var R = (e = 0) => (u, t, F) => `\x1B[${38 + e};2;${u};${t};${F}m`;
1287
+ var C = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
1288
+ Object.keys(C.modifier);
1289
+ var iD = Object.keys(C.color);
1290
+ var rD = Object.keys(C.bgColor);
1291
+ [...iD, ...rD];
1292
+ function CD() {
1293
+ const e = new Map;
1294
+ for (const [u, t] of Object.entries(C)) {
1295
+ for (const [F, s] of Object.entries(t))
1296
+ C[F] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, t[F] = C[F], e.set(s[0], s[1]);
1297
+ Object.defineProperty(C, u, { value: t, enumerable: false });
1298
+ }
1299
+ return Object.defineProperty(C, "codes", { value: e, enumerable: false }), C.color.close = "\x1B[39m", C.bgColor.close = "\x1B[49m", C.color.ansi = N(), C.color.ansi256 = I(), C.color.ansi16m = R(), C.bgColor.ansi = N(w), C.bgColor.ansi256 = I(w), C.bgColor.ansi16m = R(w), Object.defineProperties(C, { rgbToAnsi256: { value: (u, t, F) => u === t && t === F ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(t / 255 * 5) + Math.round(F / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
1300
+ const t = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
1301
+ if (!t)
1302
+ return [0, 0, 0];
1303
+ let [F] = t;
1304
+ F.length === 3 && (F = [...F].map((i) => i + i).join(""));
1305
+ const s = Number.parseInt(F, 16);
1306
+ return [s >> 16 & 255, s >> 8 & 255, s & 255];
1307
+ }, enumerable: false }, hexToAnsi256: { value: (u) => C.rgbToAnsi256(...C.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
1308
+ if (u < 8)
1309
+ return 30 + u;
1310
+ if (u < 16)
1311
+ return 90 + (u - 8);
1312
+ let t, F, s;
1313
+ if (u >= 232)
1314
+ t = ((u - 232) * 10 + 8) / 255, F = t, s = t;
1315
+ else {
1316
+ u -= 16;
1317
+ const r = u % 36;
1318
+ t = Math.floor(u / 36) / 5, F = Math.floor(r / 6) / 5, s = r % 6 / 5;
1319
+ }
1320
+ const i = Math.max(t, F, s) * 2;
1321
+ if (i === 0)
1322
+ return 30;
1323
+ let D = 30 + (Math.round(s) << 2 | Math.round(F) << 1 | Math.round(t));
1324
+ return i === 2 && (D += 60), D;
1325
+ }, enumerable: false }, rgbToAnsi: { value: (u, t, F) => C.ansi256ToAnsi(C.rgbToAnsi256(u, t, F)), enumerable: false }, hexToAnsi: { value: (u) => C.ansi256ToAnsi(C.hexToAnsi256(u)), enumerable: false } }), C;
1326
+ }
1327
+ var ED = CD();
1328
+ var d = new Set(["\x1B", "›"]);
1329
+ var oD = 39;
1330
+ var y = "\x07";
1331
+ var V = "[";
1332
+ var nD = "]";
1333
+ var G = "m";
1334
+ var _ = `${nD}8;;`;
1335
+ var z = (e) => `${d.values().next().value}${V}${e}${G}`;
1336
+ var K = (e) => `${d.values().next().value}${_}${e}${y}`;
1337
+ var aD = (e) => e.split(" ").map((u) => p(u));
1338
+ var k = (e, u, t) => {
1339
+ const F = [...u];
1340
+ let s = false, i = false, D = p(P(e[e.length - 1]));
1341
+ for (const [r, n] of F.entries()) {
1342
+ const E = p(n);
1343
+ if (D + E <= t ? e[e.length - 1] += n : (e.push(n), D = 0), d.has(n) && (s = true, i = F.slice(r + 1).join("").startsWith(_)), s) {
1344
+ i ? n === y && (s = false, i = false) : n === G && (s = false);
1345
+ continue;
1346
+ }
1347
+ D += E, D === t && r < F.length - 1 && (e.push(""), D = 0);
1348
+ }
1349
+ !D && e[e.length - 1].length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
1350
+ };
1351
+ var hD = (e) => {
1352
+ const u = e.split(" ");
1353
+ let t = u.length;
1354
+ for (;t > 0 && !(p(u[t - 1]) > 0); )
1355
+ t--;
1356
+ return t === u.length ? e : u.slice(0, t).join(" ") + u.slice(t).join("");
1357
+ };
1358
+ var lD = (e, u, t = {}) => {
1359
+ if (t.trim !== false && e.trim() === "")
1360
+ return "";
1361
+ let F = "", s, i;
1362
+ const D = aD(e);
1363
+ let r = [""];
1364
+ for (const [E, a] of e.split(" ").entries()) {
1365
+ t.trim !== false && (r[r.length - 1] = r[r.length - 1].trimStart());
1366
+ let o = p(r[r.length - 1]);
1367
+ if (E !== 0 && (o >= u && (t.wordWrap === false || t.trim === false) && (r.push(""), o = 0), (o > 0 || t.trim === false) && (r[r.length - 1] += " ", o++)), t.hard && D[E] > u) {
1368
+ const c = u - o, f = 1 + Math.floor((D[E] - c - 1) / u);
1369
+ Math.floor((D[E] - 1) / u) < f && r.push(""), k(r, a, u);
1370
+ continue;
1371
+ }
1372
+ if (o + D[E] > u && o > 0 && D[E] > 0) {
1373
+ if (t.wordWrap === false && o < u) {
1374
+ k(r, a, u);
1375
+ continue;
1376
+ }
1377
+ r.push("");
1378
+ }
1379
+ if (o + D[E] > u && t.wordWrap === false) {
1380
+ k(r, a, u);
1381
+ continue;
1382
+ }
1383
+ r[r.length - 1] += a;
1384
+ }
1385
+ t.trim !== false && (r = r.map((E) => hD(E)));
1386
+ const n = [...r.join(`
1387
+ `)];
1388
+ for (const [E, a] of n.entries()) {
1389
+ if (F += a, d.has(a)) {
1390
+ const { groups: c } = new RegExp(`(?:\\${V}(?<code>\\d+)m|\\${_}(?<uri>.*)${y})`).exec(n.slice(E).join("")) || { groups: {} };
1391
+ if (c.code !== undefined) {
1392
+ const f = Number.parseFloat(c.code);
1393
+ s = f === oD ? undefined : f;
1394
+ } else
1395
+ c.uri !== undefined && (i = c.uri.length === 0 ? undefined : c.uri);
1396
+ }
1397
+ const o = ED.codes.get(Number(s));
1398
+ n[E + 1] === `
1399
+ ` ? (i && (F += K("")), s && o && (F += z(o))) : a === `
1400
+ ` && (s && o && (F += z(s)), i && (F += K(i)));
1401
+ }
1402
+ return F;
1403
+ };
1404
+ function Y(e, u, t) {
1405
+ return String(e).normalize().replace(/\r\n/g, `
1406
+ `).split(`
1407
+ `).map((F) => lD(F, u, t)).join(`
1408
+ `);
1409
+ }
1410
+ var xD = ["up", "down", "left", "right", "space", "enter", "cancel"];
1411
+ var B = { actions: new Set(xD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
1412
+ function $(e, u) {
1413
+ if (typeof e == "string")
1414
+ return B.aliases.get(e) === u;
1415
+ for (const t of e)
1416
+ if (t !== undefined && $(t, u))
1417
+ return true;
1418
+ return false;
1419
+ }
1420
+ function BD(e, u) {
1421
+ if (e === u)
1422
+ return;
1423
+ const t = e.split(`
1424
+ `), F = u.split(`
1425
+ `), s = [];
1426
+ for (let i = 0;i < Math.max(t.length, F.length); i++)
1427
+ t[i] !== F[i] && s.push(i);
1428
+ return s;
1429
+ }
1430
+ var AD = globalThis.process.platform.startsWith("win");
1431
+ var S = Symbol("clack:cancel");
1432
+ function pD(e) {
1433
+ return e === S;
1434
+ }
1435
+ function m(e, u) {
1436
+ const t = e;
1437
+ t.isTTY && t.setRawMode(u);
1438
+ }
1439
+ var gD = Object.defineProperty;
1440
+ var vD = (e, u, t) => (u in e) ? gD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
1441
+ var h = (e, u, t) => (vD(e, typeof u != "symbol" ? u + "" : u, t), t);
1442
+
1443
+ class x {
1444
+ constructor(u, t = true) {
1445
+ h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", false), h(this, "_prevFrame", ""), h(this, "_subscribers", new Map), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
1446
+ const { input: F = j, output: s = M, render: i, signal: D, ...r } = u;
1447
+ this.opts = r, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = t, this._abortSignal = D, this.input = F, this.output = s;
1448
+ }
1449
+ unsubscribe() {
1450
+ this._subscribers.clear();
1451
+ }
1452
+ setSubscriber(u, t) {
1453
+ const F = this._subscribers.get(u) ?? [];
1454
+ F.push(t), this._subscribers.set(u, F);
1455
+ }
1456
+ on(u, t) {
1457
+ this.setSubscriber(u, { cb: t });
1458
+ }
1459
+ once(u, t) {
1460
+ this.setSubscriber(u, { cb: t, once: true });
1461
+ }
1462
+ emit(u, ...t) {
1463
+ const F = this._subscribers.get(u) ?? [], s = [];
1464
+ for (const i of F)
1465
+ i.cb(...t), i.once && s.push(() => F.splice(F.indexOf(i), 1));
1466
+ for (const i of s)
1467
+ i();
1468
+ }
1469
+ prompt() {
1470
+ return new Promise((u, t) => {
1471
+ if (this._abortSignal) {
1472
+ if (this._abortSignal.aborted)
1473
+ return this.state = "cancel", this.close(), u(S);
1474
+ this._abortSignal.addEventListener("abort", () => {
1475
+ this.state = "cancel", this.close();
1476
+ }, { once: true });
1477
+ }
1478
+ const F = new X;
1479
+ F._write = (s, i, D) => {
1480
+ this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
1481
+ }, this.input.pipe(F), this.rl = O.createInterface({ input: this.input, output: F, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), O.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), m(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
1482
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(this.value);
1483
+ }), this.once("cancel", () => {
1484
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(S);
1485
+ });
1486
+ });
1487
+ }
1488
+ onKeypress(u, t) {
1489
+ if (this.state === "error" && (this.state = "active"), t?.name && (!this._track && B.aliases.has(t.name) && this.emit("cursor", B.aliases.get(t.name)), B.actions.has(t.name) && this.emit("cursor", t.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === "\t" && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), t?.name === "return") {
1490
+ if (!this.value && this.opts.placeholder && (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder)), this.opts.validate) {
1491
+ const F = this.opts.validate(this.value);
1492
+ F && (this.error = F instanceof Error ? F.message : F, this.state = "error", this.rl?.write(this.value));
1493
+ }
1494
+ this.state !== "error" && (this.state = "submit");
1495
+ }
1496
+ $([u, t?.name, t?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
1497
+ }
1498
+ close() {
1499
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
1500
+ `), m(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
1501
+ }
1502
+ restoreCursor() {
1503
+ const u = Y(this._prevFrame, process.stdout.columns, { hard: true }).split(`
1504
+ `).length - 1;
1505
+ this.output.write(import_sisteransi.cursor.move(-999, u * -1));
1506
+ }
1507
+ render() {
1508
+ const u = Y(this._render(this) ?? "", process.stdout.columns, { hard: true });
1509
+ if (u !== this._prevFrame) {
1510
+ if (this.state === "initial")
1511
+ this.output.write(import_sisteransi.cursor.hide);
1512
+ else {
1513
+ const t = BD(this._prevFrame, u);
1514
+ if (this.restoreCursor(), t && t?.length === 1) {
1515
+ const F = t[0];
1516
+ this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.lines(1));
1517
+ const s = u.split(`
1518
+ `);
1519
+ this.output.write(s[F]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - F - 1));
1520
+ return;
1521
+ }
1522
+ if (t && t?.length > 1) {
1523
+ const F = t[0];
1524
+ this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.down());
1525
+ const s = u.split(`
1526
+ `).slice(F);
1527
+ this.output.write(s.join(`
1528
+ `)), this._prevFrame = u;
1529
+ return;
1530
+ }
1531
+ this.output.write(import_sisteransi.erase.down());
1532
+ }
1533
+ this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
1534
+ }
1535
+ }
1536
+ }
1537
+
1538
+ class dD extends x {
1539
+ get cursor() {
1540
+ return this.value ? 0 : 1;
1541
+ }
1542
+ get _value() {
1543
+ return this.cursor === 0;
1544
+ }
1545
+ constructor(u) {
1546
+ super(u, false), this.value = !!u.initialValue, this.on("value", () => {
1547
+ this.value = this._value;
1548
+ }), this.on("confirm", (t) => {
1549
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = t, this.state = "submit", this.close();
1550
+ }), this.on("cursor", () => {
1551
+ this.value = !this.value;
1552
+ });
1553
+ }
1554
+ }
1555
+ var A;
1556
+ A = new WeakMap;
1557
+
1558
+ // node_modules/@clack/prompts/dist/index.mjs
1559
+ var import_picocolors3 = __toESM(require_picocolors(), 1);
1560
+ var import_sisteransi2 = __toESM(require_src(), 1);
1561
+ import y2 from "node:process";
1562
+ function ce() {
1563
+ return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
1564
+ }
1565
+ var V2 = ce();
1566
+ var u = (t, n) => V2 ? t : n;
1567
+ var le = u("◆", "*");
1568
+ var L2 = u("■", "x");
1569
+ var W2 = u("▲", "x");
1570
+ var C2 = u("◇", "o");
1571
+ var ue = u("┌", "T");
1572
+ var o = u("│", "|");
1573
+ var d2 = u("└", "—");
1574
+ var k2 = u("●", ">");
1575
+ var P2 = u("○", " ");
1576
+ var A2 = u("◻", "[•]");
1577
+ var T = u("◼", "[+]");
1578
+ var F = u("◻", "[ ]");
1579
+ var $e = u("▪", "•");
1580
+ var _2 = u("─", "-");
1581
+ var me = u("╮", "+");
1582
+ var de = u("├", "+");
1583
+ var pe = u("╯", "+");
1584
+ var q = u("●", "•");
1585
+ var D = u("◆", "*");
1586
+ var U = u("▲", "!");
1587
+ var K2 = u("■", "x");
1588
+ var b2 = (t) => {
1589
+ switch (t) {
1590
+ case "initial":
1591
+ case "active":
1592
+ return import_picocolors3.default.cyan(le);
1593
+ case "cancel":
1594
+ return import_picocolors3.default.red(L2);
1595
+ case "error":
1596
+ return import_picocolors3.default.yellow(W2);
1597
+ case "submit":
1598
+ return import_picocolors3.default.green(C2);
1599
+ }
1600
+ };
1601
+ var ye = (t) => {
1602
+ const n = t.active ?? "Yes", r = t.inactive ?? "No";
1603
+ return new dD({ active: n, inactive: r, initialValue: t.initialValue ?? true, render() {
1604
+ const i = `${import_picocolors3.default.gray(o)}
1605
+ ${b2(this.state)} ${t.message}
1606
+ `, s = this.value ? n : r;
1607
+ switch (this.state) {
1608
+ case "submit":
1609
+ return `${i}${import_picocolors3.default.gray(o)} ${import_picocolors3.default.dim(s)}`;
1610
+ case "cancel":
1611
+ return `${i}${import_picocolors3.default.gray(o)} ${import_picocolors3.default.strikethrough(import_picocolors3.default.dim(s))}
1612
+ ${import_picocolors3.default.gray(o)}`;
1613
+ default:
1614
+ return `${i}${import_picocolors3.default.cyan(o)} ${this.value ? `${import_picocolors3.default.green(k2)} ${n}` : `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(n)}`} ${import_picocolors3.default.dim("/")} ${this.value ? `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(r)}` : `${import_picocolors3.default.green(k2)} ${r}`}
1615
+ ${import_picocolors3.default.cyan(d2)}
1616
+ `;
1617
+ }
1618
+ } }).prompt();
1619
+ };
1620
+ var J = `${import_picocolors3.default.gray(o)} `;
1621
+
1622
+ // src/launcher.ts
1623
+ async function ensureAgentBin(agent) {
1624
+ const found = await findBin(agent);
1625
+ if (found)
1626
+ return found;
1627
+ if (!agent.installCmd)
1628
+ return null;
1629
+ const ok = await ye({
1630
+ message: `${agent.label} isn't installed. Install it with \`${agent.installCmd.join(" ")}\`?`,
1631
+ initialValue: true
1632
+ });
1633
+ if (pD(ok) || !ok) {
1634
+ info(`Skipping. Install it yourself with: ${agent.installCmd.join(" ")}`);
1635
+ return null;
1636
+ }
1637
+ await runInstall(agent.installCmd);
1638
+ return findBin(agent);
1639
+ }
1640
+ function launchAgent(bin, args, token) {
1641
+ const child = spawn2(bin, args, {
1642
+ stdio: "inherit",
1643
+ env: { ...process.env, [MCP_TOKEN_VAR]: token }
1644
+ });
1645
+ child.on("exit", (code) => process.exit(code ?? 0));
1646
+ }
1647
+ async function prepareAgentLaunch(agent) {
1648
+ if (agent.id === "claude")
1649
+ await clearClaudeNeedsAuthCache();
1650
+ }
1651
+ async function clearClaudeNeedsAuthCache() {
1652
+ const file = path3.join(os3.homedir(), ".claude", "mcp-needs-auth-cache.json");
1653
+ let cache;
1654
+ try {
1655
+ cache = JSON.parse(await fs4.readFile(file, "utf8"));
1656
+ } catch {
1657
+ return;
1658
+ }
1659
+ let changed = false;
1660
+ for (const name of OUR_MCP_NAMES) {
1661
+ if (Object.prototype.hasOwnProperty.call(cache, name)) {
1662
+ delete cache[name];
1663
+ changed = true;
1664
+ }
1665
+ }
1666
+ if (!changed)
1667
+ return;
1668
+ await fs4.writeFile(file, JSON.stringify(cache, null, 2) + `
1669
+ `, { mode: 384 });
1670
+ }
1671
+ function runInstall(cmd) {
1672
+ return new Promise((resolve, reject) => {
1673
+ const [bin, ...args] = cmd;
1674
+ const child = spawn2(bin, args, { stdio: "inherit" });
1675
+ child.on("error", reject);
1676
+ child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`\`${cmd.join(" ")}\` exited ${code}`)));
1677
+ });
1678
+ }
1679
+
1680
+ // src/mcp-writer.ts
1681
+ import fs5 from "node:fs/promises";
1682
+ import path4 from "node:path";
1683
+
1684
+ // node_modules/smol-toml/dist/error.js
1685
+ /*!
1686
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
1687
+ * SPDX-License-Identifier: BSD-3-Clause
1688
+ *
1689
+ * Redistribution and use in source and binary forms, with or without
1690
+ * modification, are permitted provided that the following conditions are met:
1691
+ *
1692
+ * 1. Redistributions of source code must retain the above copyright notice, this
1693
+ * list of conditions and the following disclaimer.
1694
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
1695
+ * this list of conditions and the following disclaimer in the
1696
+ * documentation and/or other materials provided with the distribution.
1697
+ * 3. Neither the name of the copyright holder nor the names of its contributors
1698
+ * may be used to endorse or promote products derived from this software without
1699
+ * specific prior written permission.
1700
+ *
1701
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1702
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1703
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1704
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
1705
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1706
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1707
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1708
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1709
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1710
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1711
+ */
1712
+ function getLineColFromPtr(string, ptr) {
1713
+ let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
1714
+ return [lines.length, lines.pop().length + 1];
1715
+ }
1716
+ function makeCodeBlock(string, line, column) {
1717
+ let lines = string.split(/\r\n|\n|\r/g);
1718
+ let codeblock = "";
1719
+ let numberLen = (Math.log10(line + 1) | 0) + 1;
1720
+ for (let i = line - 1;i <= line + 1; i++) {
1721
+ let l2 = lines[i - 1];
1722
+ if (!l2)
1723
+ continue;
1724
+ codeblock += i.toString().padEnd(numberLen, " ");
1725
+ codeblock += ": ";
1726
+ codeblock += l2;
1727
+ codeblock += `
1728
+ `;
1729
+ if (i === line) {
1730
+ codeblock += " ".repeat(numberLen + column + 2);
1731
+ codeblock += `^
1732
+ `;
1733
+ }
1734
+ }
1735
+ return codeblock;
1736
+ }
1737
+
1738
+ class TomlError extends Error {
1739
+ line;
1740
+ column;
1741
+ codeblock;
1742
+ constructor(message, options) {
1743
+ const [line, column] = getLineColFromPtr(options.toml, options.ptr);
1744
+ const codeblock = makeCodeBlock(options.toml, line, column);
1745
+ super(`Invalid TOML document: ${message}
1746
+
1747
+ ${codeblock}`, options);
1748
+ this.line = line;
1749
+ this.column = column;
1750
+ this.codeblock = codeblock;
1751
+ }
1752
+ }
1753
+
1754
+ // node_modules/smol-toml/dist/util.js
1755
+ /*!
1756
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
1757
+ * SPDX-License-Identifier: BSD-3-Clause
1758
+ *
1759
+ * Redistribution and use in source and binary forms, with or without
1760
+ * modification, are permitted provided that the following conditions are met:
1761
+ *
1762
+ * 1. Redistributions of source code must retain the above copyright notice, this
1763
+ * list of conditions and the following disclaimer.
1764
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
1765
+ * this list of conditions and the following disclaimer in the
1766
+ * documentation and/or other materials provided with the distribution.
1767
+ * 3. Neither the name of the copyright holder nor the names of its contributors
1768
+ * may be used to endorse or promote products derived from this software without
1769
+ * specific prior written permission.
1770
+ *
1771
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1772
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1773
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1774
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
1775
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1776
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1777
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1778
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1779
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1780
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1781
+ */
1782
+ function isEscaped(str, ptr) {
1783
+ let i = 0;
1784
+ while (str[ptr - ++i] === "\\")
1785
+ ;
1786
+ return --i && i % 2;
1787
+ }
1788
+ function indexOfNewline(str, start = 0, end = str.length) {
1789
+ let idx = str.indexOf(`
1790
+ `, start);
1791
+ if (str[idx - 1] === "\r")
1792
+ idx--;
1793
+ return idx <= end ? idx : -1;
1794
+ }
1795
+ function skipComment(str, ptr) {
1796
+ for (let i = ptr;i < str.length; i++) {
1797
+ let c = str[i];
1798
+ if (c === `
1799
+ `)
1800
+ return i;
1801
+ if (c === "\r" && str[i + 1] === `
1802
+ `)
1803
+ return i + 1;
1804
+ if (c < " " && c !== "\t" || c === "") {
1805
+ throw new TomlError("control characters are not allowed in comments", {
1806
+ toml: str,
1807
+ ptr
1808
+ });
1809
+ }
1810
+ }
1811
+ return str.length;
1812
+ }
1813
+ function skipVoid(str, ptr, banNewLines, banComments) {
1814
+ let c;
1815
+ while (true) {
1816
+ while ((c = str[ptr]) === " " || c === "\t" || !banNewLines && (c === `
1817
+ ` || c === "\r" && str[ptr + 1] === `
1818
+ `))
1819
+ ptr++;
1820
+ if (banComments || c !== "#")
1821
+ break;
1822
+ ptr = skipComment(str, ptr);
1823
+ }
1824
+ return ptr;
1825
+ }
1826
+ function skipUntil(str, ptr, sep, end, banNewLines = false) {
1827
+ if (!end) {
1828
+ ptr = indexOfNewline(str, ptr);
1829
+ return ptr < 0 ? str.length : ptr;
1830
+ }
1831
+ for (let i = ptr;i < str.length; i++) {
1832
+ let c = str[i];
1833
+ if (c === "#") {
1834
+ i = indexOfNewline(str, i);
1835
+ } else if (c === sep) {
1836
+ return i + 1;
1837
+ } else if (c === end || banNewLines && (c === `
1838
+ ` || c === "\r" && str[i + 1] === `
1839
+ `)) {
1840
+ return i;
1841
+ }
1842
+ }
1843
+ throw new TomlError("cannot find end of structure", {
1844
+ toml: str,
1845
+ ptr
1846
+ });
1847
+ }
1848
+ function getStringEnd(str, seek) {
1849
+ let first = str[seek];
1850
+ let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2] ? str.slice(seek, seek + 3) : first;
1851
+ seek += target.length - 1;
1852
+ do
1853
+ seek = str.indexOf(target, ++seek);
1854
+ while (seek > -1 && first !== "'" && isEscaped(str, seek));
1855
+ if (seek > -1) {
1856
+ seek += target.length;
1857
+ if (target.length > 1) {
1858
+ if (str[seek] === first)
1859
+ seek++;
1860
+ if (str[seek] === first)
1861
+ seek++;
1862
+ }
1863
+ }
1864
+ return seek;
1865
+ }
1866
+
1867
+ // node_modules/smol-toml/dist/date.js
1868
+ /*!
1869
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
1870
+ * SPDX-License-Identifier: BSD-3-Clause
1871
+ *
1872
+ * Redistribution and use in source and binary forms, with or without
1873
+ * modification, are permitted provided that the following conditions are met:
1874
+ *
1875
+ * 1. Redistributions of source code must retain the above copyright notice, this
1876
+ * list of conditions and the following disclaimer.
1877
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
1878
+ * this list of conditions and the following disclaimer in the
1879
+ * documentation and/or other materials provided with the distribution.
1880
+ * 3. Neither the name of the copyright holder nor the names of its contributors
1881
+ * may be used to endorse or promote products derived from this software without
1882
+ * specific prior written permission.
1883
+ *
1884
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1885
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1886
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1887
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
1888
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1889
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1890
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1891
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1892
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1893
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1894
+ */
1895
+ var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
1896
+
1897
+ class TomlDate extends Date {
1898
+ #hasDate = false;
1899
+ #hasTime = false;
1900
+ #offset = null;
1901
+ constructor(date) {
1902
+ let hasDate = true;
1903
+ let hasTime = true;
1904
+ let offset = "Z";
1905
+ if (typeof date === "string") {
1906
+ let match = date.match(DATE_TIME_RE);
1907
+ if (match) {
1908
+ if (!match[1]) {
1909
+ hasDate = false;
1910
+ date = `0000-01-01T${date}`;
1911
+ }
1912
+ hasTime = !!match[2];
1913
+ hasTime && date[10] === " " && (date = date.replace(" ", "T"));
1914
+ if (match[2] && +match[2] > 23) {
1915
+ date = "";
1916
+ } else {
1917
+ offset = match[3] || null;
1918
+ date = date.toUpperCase();
1919
+ if (!offset && hasTime)
1920
+ date += "Z";
1921
+ }
1922
+ } else {
1923
+ date = "";
1924
+ }
1925
+ }
1926
+ super(date);
1927
+ if (!isNaN(this.getTime())) {
1928
+ this.#hasDate = hasDate;
1929
+ this.#hasTime = hasTime;
1930
+ this.#offset = offset;
1931
+ }
1932
+ }
1933
+ isDateTime() {
1934
+ return this.#hasDate && this.#hasTime;
1935
+ }
1936
+ isLocal() {
1937
+ return !this.#hasDate || !this.#hasTime || !this.#offset;
1938
+ }
1939
+ isDate() {
1940
+ return this.#hasDate && !this.#hasTime;
1941
+ }
1942
+ isTime() {
1943
+ return this.#hasTime && !this.#hasDate;
1944
+ }
1945
+ isValid() {
1946
+ return this.#hasDate || this.#hasTime;
1947
+ }
1948
+ toISOString() {
1949
+ let iso = super.toISOString();
1950
+ if (this.isDate())
1951
+ return iso.slice(0, 10);
1952
+ if (this.isTime())
1953
+ return iso.slice(11, 23);
1954
+ if (this.#offset === null)
1955
+ return iso.slice(0, -1);
1956
+ if (this.#offset === "Z")
1957
+ return iso;
1958
+ let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
1959
+ offset = this.#offset[0] === "-" ? offset : -offset;
1960
+ let offsetDate = new Date(this.getTime() - offset * 60000);
1961
+ return offsetDate.toISOString().slice(0, -1) + this.#offset;
1962
+ }
1963
+ static wrapAsOffsetDateTime(jsDate, offset = "Z") {
1964
+ let date = new TomlDate(jsDate);
1965
+ date.#offset = offset;
1966
+ return date;
1967
+ }
1968
+ static wrapAsLocalDateTime(jsDate) {
1969
+ let date = new TomlDate(jsDate);
1970
+ date.#offset = null;
1971
+ return date;
1972
+ }
1973
+ static wrapAsLocalDate(jsDate) {
1974
+ let date = new TomlDate(jsDate);
1975
+ date.#hasTime = false;
1976
+ date.#offset = null;
1977
+ return date;
1978
+ }
1979
+ static wrapAsLocalTime(jsDate) {
1980
+ let date = new TomlDate(jsDate);
1981
+ date.#hasDate = false;
1982
+ date.#offset = null;
1983
+ return date;
1984
+ }
1985
+ }
1986
+
1987
+ // node_modules/smol-toml/dist/primitive.js
1988
+ /*!
1989
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
1990
+ * SPDX-License-Identifier: BSD-3-Clause
1991
+ *
1992
+ * Redistribution and use in source and binary forms, with or without
1993
+ * modification, are permitted provided that the following conditions are met:
1994
+ *
1995
+ * 1. Redistributions of source code must retain the above copyright notice, this
1996
+ * list of conditions and the following disclaimer.
1997
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
1998
+ * this list of conditions and the following disclaimer in the
1999
+ * documentation and/or other materials provided with the distribution.
2000
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2001
+ * may be used to endorse or promote products derived from this software without
2002
+ * specific prior written permission.
2003
+ *
2004
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2005
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2006
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2007
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2008
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2009
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2010
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2011
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2012
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2013
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2014
+ */
2015
+ var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
2016
+ var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
2017
+ var LEADING_ZERO = /^[+-]?0[0-9_]/;
2018
+ var ESCAPE_REGEX = /^[0-9a-f]{2,8}$/i;
2019
+ var ESC_MAP = {
2020
+ b: "\b",
2021
+ t: "\t",
2022
+ n: `
2023
+ `,
2024
+ f: "\f",
2025
+ r: "\r",
2026
+ e: "\x1B",
2027
+ '"': '"',
2028
+ "\\": "\\"
2029
+ };
2030
+ function parseString(str, ptr = 0, endPtr = str.length) {
2031
+ let isLiteral = str[ptr] === "'";
2032
+ let isMultiline = str[ptr++] === str[ptr] && str[ptr] === str[ptr + 1];
2033
+ if (isMultiline) {
2034
+ endPtr -= 2;
2035
+ if (str[ptr += 2] === "\r")
2036
+ ptr++;
2037
+ if (str[ptr] === `
2038
+ `)
2039
+ ptr++;
2040
+ }
2041
+ let tmp = 0;
2042
+ let isEscape;
2043
+ let parsed = "";
2044
+ let sliceStart = ptr;
2045
+ while (ptr < endPtr - 1) {
2046
+ let c = str[ptr++];
2047
+ if (c === `
2048
+ ` || c === "\r" && str[ptr] === `
2049
+ `) {
2050
+ if (!isMultiline) {
2051
+ throw new TomlError("newlines are not allowed in strings", {
2052
+ toml: str,
2053
+ ptr: ptr - 1
2054
+ });
2055
+ }
2056
+ } else if (c < " " && c !== "\t" || c === "") {
2057
+ throw new TomlError("control characters are not allowed in strings", {
2058
+ toml: str,
2059
+ ptr: ptr - 1
2060
+ });
2061
+ }
2062
+ if (isEscape) {
2063
+ isEscape = false;
2064
+ if (c === "x" || c === "u" || c === "U") {
2065
+ let code = str.slice(ptr, ptr += c === "x" ? 2 : c === "u" ? 4 : 8);
2066
+ if (!ESCAPE_REGEX.test(code)) {
2067
+ throw new TomlError("invalid unicode escape", {
2068
+ toml: str,
2069
+ ptr: tmp
2070
+ });
2071
+ }
2072
+ try {
2073
+ parsed += String.fromCodePoint(parseInt(code, 16));
2074
+ } catch {
2075
+ throw new TomlError("invalid unicode escape", {
2076
+ toml: str,
2077
+ ptr: tmp
2078
+ });
2079
+ }
2080
+ } else if (isMultiline && (c === `
2081
+ ` || c === " " || c === "\t" || c === "\r")) {
2082
+ ptr = skipVoid(str, ptr - 1, true);
2083
+ if (str[ptr] !== `
2084
+ ` && str[ptr] !== "\r") {
2085
+ throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
2086
+ toml: str,
2087
+ ptr: tmp
2088
+ });
2089
+ }
2090
+ ptr = skipVoid(str, ptr);
2091
+ } else if (c in ESC_MAP) {
2092
+ parsed += ESC_MAP[c];
2093
+ } else {
2094
+ throw new TomlError("unrecognized escape sequence", {
2095
+ toml: str,
2096
+ ptr: tmp
2097
+ });
2098
+ }
2099
+ sliceStart = ptr;
2100
+ } else if (!isLiteral && c === "\\") {
2101
+ tmp = ptr - 1;
2102
+ isEscape = true;
2103
+ parsed += str.slice(sliceStart, tmp);
2104
+ }
2105
+ }
2106
+ return parsed + str.slice(sliceStart, endPtr - 1);
2107
+ }
2108
+ function parseValue(value, toml, ptr, integersAsBigInt) {
2109
+ if (value === "true")
2110
+ return true;
2111
+ if (value === "false")
2112
+ return false;
2113
+ if (value === "-inf")
2114
+ return -Infinity;
2115
+ if (value === "inf" || value === "+inf")
2116
+ return Infinity;
2117
+ if (value === "nan" || value === "+nan" || value === "-nan")
2118
+ return NaN;
2119
+ if (value === "-0")
2120
+ return integersAsBigInt ? 0n : 0;
2121
+ let isInt = INT_REGEX.test(value);
2122
+ if (isInt || FLOAT_REGEX.test(value)) {
2123
+ if (LEADING_ZERO.test(value)) {
2124
+ throw new TomlError("leading zeroes are not allowed", {
2125
+ toml,
2126
+ ptr
2127
+ });
2128
+ }
2129
+ value = value.replace(/_/g, "");
2130
+ let numeric = +value;
2131
+ if (isNaN(numeric)) {
2132
+ throw new TomlError("invalid number", {
2133
+ toml,
2134
+ ptr
2135
+ });
2136
+ }
2137
+ if (isInt) {
2138
+ if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
2139
+ throw new TomlError("integer value cannot be represented losslessly", {
2140
+ toml,
2141
+ ptr
2142
+ });
2143
+ }
2144
+ if (isInt || integersAsBigInt === true)
2145
+ numeric = BigInt(value);
2146
+ }
2147
+ return numeric;
2148
+ }
2149
+ const date = new TomlDate(value);
2150
+ if (!date.isValid()) {
2151
+ throw new TomlError("invalid value", {
2152
+ toml,
2153
+ ptr
2154
+ });
2155
+ }
2156
+ return date;
2157
+ }
2158
+
2159
+ // node_modules/smol-toml/dist/extract.js
2160
+ /*!
2161
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2162
+ * SPDX-License-Identifier: BSD-3-Clause
2163
+ *
2164
+ * Redistribution and use in source and binary forms, with or without
2165
+ * modification, are permitted provided that the following conditions are met:
2166
+ *
2167
+ * 1. Redistributions of source code must retain the above copyright notice, this
2168
+ * list of conditions and the following disclaimer.
2169
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2170
+ * this list of conditions and the following disclaimer in the
2171
+ * documentation and/or other materials provided with the distribution.
2172
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2173
+ * may be used to endorse or promote products derived from this software without
2174
+ * specific prior written permission.
2175
+ *
2176
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2177
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2178
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2179
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2180
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2181
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2182
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2183
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2184
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2185
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2186
+ */
2187
+ function sliceAndTrimEndOf(str, startPtr, endPtr) {
2188
+ let value = str.slice(startPtr, endPtr);
2189
+ let commentIdx = value.indexOf("#");
2190
+ if (commentIdx > -1) {
2191
+ skipComment(str, commentIdx);
2192
+ value = value.slice(0, commentIdx);
2193
+ }
2194
+ return [value.trimEnd(), commentIdx];
2195
+ }
2196
+ function extractValue(str, ptr, end, depth, integersAsBigInt) {
2197
+ if (depth === 0) {
2198
+ throw new TomlError("document contains excessively nested structures. aborting.", {
2199
+ toml: str,
2200
+ ptr
2201
+ });
2202
+ }
2203
+ let c = str[ptr];
2204
+ if (c === "[" || c === "{") {
2205
+ let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
2206
+ if (end) {
2207
+ endPtr2 = skipVoid(str, endPtr2);
2208
+ if (str[endPtr2] === ",")
2209
+ endPtr2++;
2210
+ else if (str[endPtr2] !== end) {
2211
+ throw new TomlError("expected comma or end of structure", {
2212
+ toml: str,
2213
+ ptr: endPtr2
2214
+ });
2215
+ }
2216
+ }
2217
+ return [value, endPtr2];
2218
+ }
2219
+ let endPtr;
2220
+ if (c === '"' || c === "'") {
2221
+ endPtr = getStringEnd(str, ptr);
2222
+ let parsed = parseString(str, ptr, endPtr);
2223
+ if (end) {
2224
+ endPtr = skipVoid(str, endPtr);
2225
+ if (str[endPtr] && str[endPtr] !== "," && str[endPtr] !== end && str[endPtr] !== `
2226
+ ` && str[endPtr] !== "\r") {
2227
+ throw new TomlError("unexpected character encountered", {
2228
+ toml: str,
2229
+ ptr: endPtr
2230
+ });
2231
+ }
2232
+ endPtr += +(str[endPtr] === ",");
2233
+ }
2234
+ return [parsed, endPtr];
2235
+ }
2236
+ endPtr = skipUntil(str, ptr, ",", end);
2237
+ let slice = sliceAndTrimEndOf(str, ptr, endPtr - +(str[endPtr - 1] === ","));
2238
+ if (!slice[0]) {
2239
+ throw new TomlError("incomplete key-value declaration: no value specified", {
2240
+ toml: str,
2241
+ ptr
2242
+ });
2243
+ }
2244
+ if (end && slice[1] > -1) {
2245
+ endPtr = skipVoid(str, ptr + slice[1]);
2246
+ endPtr += +(str[endPtr] === ",");
2247
+ }
2248
+ return [
2249
+ parseValue(slice[0], str, ptr, integersAsBigInt),
2250
+ endPtr
2251
+ ];
2252
+ }
2253
+
2254
+ // node_modules/smol-toml/dist/struct.js
2255
+ /*!
2256
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2257
+ * SPDX-License-Identifier: BSD-3-Clause
2258
+ *
2259
+ * Redistribution and use in source and binary forms, with or without
2260
+ * modification, are permitted provided that the following conditions are met:
2261
+ *
2262
+ * 1. Redistributions of source code must retain the above copyright notice, this
2263
+ * list of conditions and the following disclaimer.
2264
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2265
+ * this list of conditions and the following disclaimer in the
2266
+ * documentation and/or other materials provided with the distribution.
2267
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2268
+ * may be used to endorse or promote products derived from this software without
2269
+ * specific prior written permission.
2270
+ *
2271
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2272
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2273
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2274
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2275
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2276
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2277
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2278
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2279
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2280
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2281
+ */
2282
+ var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
2283
+ function parseKey(str, ptr, end = "=") {
2284
+ let dot = ptr - 1;
2285
+ let parsed = [];
2286
+ let endPtr = str.indexOf(end, ptr);
2287
+ if (endPtr < 0) {
2288
+ throw new TomlError("incomplete key-value: cannot find end of key", {
2289
+ toml: str,
2290
+ ptr
2291
+ });
2292
+ }
2293
+ do {
2294
+ let c = str[ptr = ++dot];
2295
+ if (c !== " " && c !== "\t") {
2296
+ if (c === '"' || c === "'") {
2297
+ if (c === str[ptr + 1] && c === str[ptr + 2]) {
2298
+ throw new TomlError("multiline strings are not allowed in keys", {
2299
+ toml: str,
2300
+ ptr
2301
+ });
2302
+ }
2303
+ let eos = getStringEnd(str, ptr);
2304
+ if (eos < 0) {
2305
+ throw new TomlError("unfinished string encountered", {
2306
+ toml: str,
2307
+ ptr
2308
+ });
2309
+ }
2310
+ dot = str.indexOf(".", eos);
2311
+ let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
2312
+ let newLine = indexOfNewline(strEnd);
2313
+ if (newLine > -1) {
2314
+ throw new TomlError("newlines are not allowed in keys", {
2315
+ toml: str,
2316
+ ptr: ptr + dot + newLine
2317
+ });
2318
+ }
2319
+ if (strEnd.trimStart()) {
2320
+ throw new TomlError("found extra tokens after the string part", {
2321
+ toml: str,
2322
+ ptr: eos
2323
+ });
2324
+ }
2325
+ if (endPtr < eos) {
2326
+ endPtr = str.indexOf(end, eos);
2327
+ if (endPtr < 0) {
2328
+ throw new TomlError("incomplete key-value: cannot find end of key", {
2329
+ toml: str,
2330
+ ptr
2331
+ });
2332
+ }
2333
+ }
2334
+ parsed.push(parseString(str, ptr, eos));
2335
+ } else {
2336
+ dot = str.indexOf(".", ptr);
2337
+ let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
2338
+ if (!KEY_PART_RE.test(part)) {
2339
+ throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
2340
+ toml: str,
2341
+ ptr
2342
+ });
2343
+ }
2344
+ parsed.push(part.trimEnd());
2345
+ }
2346
+ }
2347
+ } while (dot + 1 && dot < endPtr);
2348
+ return [parsed, skipVoid(str, endPtr + 1, true, true)];
2349
+ }
2350
+ function parseInlineTable(str, ptr, depth, integersAsBigInt) {
2351
+ let res = {};
2352
+ let seen = new Set;
2353
+ let c;
2354
+ ptr++;
2355
+ while ((c = str[ptr++]) !== "}" && c) {
2356
+ if (c === ",") {
2357
+ throw new TomlError("expected value, found comma", {
2358
+ toml: str,
2359
+ ptr: ptr - 1
2360
+ });
2361
+ } else if (c === "#")
2362
+ ptr = skipComment(str, ptr);
2363
+ else if (c !== " " && c !== "\t" && c !== `
2364
+ ` && c !== "\r") {
2365
+ let k3;
2366
+ let t = res;
2367
+ let hasOwn = false;
2368
+ let [key, keyEndPtr] = parseKey(str, ptr - 1);
2369
+ for (let i = 0;i < key.length; i++) {
2370
+ if (i)
2371
+ t = hasOwn ? t[k3] : t[k3] = {};
2372
+ k3 = key[i];
2373
+ if ((hasOwn = Object.hasOwn(t, k3)) && (typeof t[k3] !== "object" || seen.has(t[k3]))) {
2374
+ throw new TomlError("trying to redefine an already defined value", {
2375
+ toml: str,
2376
+ ptr
2377
+ });
2378
+ }
2379
+ if (!hasOwn && k3 === "__proto__") {
2380
+ Object.defineProperty(t, k3, { enumerable: true, configurable: true, writable: true });
2381
+ }
2382
+ }
2383
+ if (hasOwn) {
2384
+ throw new TomlError("trying to redefine an already defined value", {
2385
+ toml: str,
2386
+ ptr
2387
+ });
2388
+ }
2389
+ let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
2390
+ seen.add(value);
2391
+ t[k3] = value;
2392
+ ptr = valueEndPtr;
2393
+ }
2394
+ }
2395
+ if (!c) {
2396
+ throw new TomlError("unfinished table encountered", {
2397
+ toml: str,
2398
+ ptr
2399
+ });
2400
+ }
2401
+ return [res, ptr];
2402
+ }
2403
+ function parseArray(str, ptr, depth, integersAsBigInt) {
2404
+ let res = [];
2405
+ let c;
2406
+ ptr++;
2407
+ while ((c = str[ptr++]) !== "]" && c) {
2408
+ if (c === ",") {
2409
+ throw new TomlError("expected value, found comma", {
2410
+ toml: str,
2411
+ ptr: ptr - 1
2412
+ });
2413
+ } else if (c === "#")
2414
+ ptr = skipComment(str, ptr);
2415
+ else if (c !== " " && c !== "\t" && c !== `
2416
+ ` && c !== "\r") {
2417
+ let e2 = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
2418
+ res.push(e2[0]);
2419
+ ptr = e2[1];
2420
+ }
2421
+ }
2422
+ if (!c) {
2423
+ throw new TomlError("unfinished array encountered", {
2424
+ toml: str,
2425
+ ptr
2426
+ });
2427
+ }
2428
+ return [res, ptr];
2429
+ }
2430
+
2431
+ // node_modules/smol-toml/dist/parse.js
2432
+ /*!
2433
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2434
+ * SPDX-License-Identifier: BSD-3-Clause
2435
+ *
2436
+ * Redistribution and use in source and binary forms, with or without
2437
+ * modification, are permitted provided that the following conditions are met:
2438
+ *
2439
+ * 1. Redistributions of source code must retain the above copyright notice, this
2440
+ * list of conditions and the following disclaimer.
2441
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2442
+ * this list of conditions and the following disclaimer in the
2443
+ * documentation and/or other materials provided with the distribution.
2444
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2445
+ * may be used to endorse or promote products derived from this software without
2446
+ * specific prior written permission.
2447
+ *
2448
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2449
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2450
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2451
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2452
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2453
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2454
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2455
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2456
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2457
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2458
+ */
2459
+ function peekTable(key, table, meta, type) {
2460
+ let t = table;
2461
+ let m2 = meta;
2462
+ let k3;
2463
+ let hasOwn = false;
2464
+ let state;
2465
+ for (let i = 0;i < key.length; i++) {
2466
+ if (i) {
2467
+ t = hasOwn ? t[k3] : t[k3] = {};
2468
+ m2 = (state = m2[k3]).c;
2469
+ if (type === 0 && (state.t === 1 || state.t === 2)) {
2470
+ return null;
2471
+ }
2472
+ if (state.t === 2) {
2473
+ let l2 = t.length - 1;
2474
+ t = t[l2];
2475
+ m2 = m2[l2].c;
2476
+ }
2477
+ }
2478
+ k3 = key[i];
2479
+ if ((hasOwn = Object.hasOwn(t, k3)) && m2[k3]?.t === 0 && m2[k3]?.d) {
2480
+ return null;
2481
+ }
2482
+ if (!hasOwn) {
2483
+ if (k3 === "__proto__") {
2484
+ Object.defineProperty(t, k3, { enumerable: true, configurable: true, writable: true });
2485
+ Object.defineProperty(m2, k3, { enumerable: true, configurable: true, writable: true });
2486
+ }
2487
+ m2[k3] = {
2488
+ t: i < key.length - 1 && type === 2 ? 3 : type,
2489
+ d: false,
2490
+ i: 0,
2491
+ c: {}
2492
+ };
2493
+ }
2494
+ }
2495
+ state = m2[k3];
2496
+ if (state.t !== type && !(type === 1 && state.t === 3)) {
2497
+ return null;
2498
+ }
2499
+ if (type === 2) {
2500
+ if (!state.d) {
2501
+ state.d = true;
2502
+ t[k3] = [];
2503
+ }
2504
+ t[k3].push(t = {});
2505
+ state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
2506
+ }
2507
+ if (state.d) {
2508
+ return null;
2509
+ }
2510
+ state.d = true;
2511
+ if (type === 1) {
2512
+ t = hasOwn ? t[k3] : t[k3] = {};
2513
+ } else if (type === 0 && hasOwn) {
2514
+ return null;
2515
+ }
2516
+ return [k3, t, state.c];
2517
+ }
2518
+ function parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
2519
+ let res = {};
2520
+ let meta = {};
2521
+ let tbl = res;
2522
+ let m2 = meta;
2523
+ for (let ptr = skipVoid(toml, 0);ptr < toml.length; ) {
2524
+ if (toml[ptr] === "[") {
2525
+ let isTableArray = toml[++ptr] === "[";
2526
+ let k3 = parseKey(toml, ptr += +isTableArray, "]");
2527
+ if (isTableArray) {
2528
+ if (toml[k3[1] - 1] !== "]") {
2529
+ throw new TomlError("expected end of table declaration", {
2530
+ toml,
2531
+ ptr: k3[1] - 1
2532
+ });
2533
+ }
2534
+ k3[1]++;
2535
+ }
2536
+ let p2 = peekTable(k3[0], res, meta, isTableArray ? 2 : 1);
2537
+ if (!p2) {
2538
+ throw new TomlError("trying to redefine an already defined table or value", {
2539
+ toml,
2540
+ ptr
2541
+ });
2542
+ }
2543
+ m2 = p2[2];
2544
+ tbl = p2[1];
2545
+ ptr = k3[1];
2546
+ } else {
2547
+ let k3 = parseKey(toml, ptr);
2548
+ let p2 = peekTable(k3[0], tbl, m2, 0);
2549
+ if (!p2) {
2550
+ throw new TomlError("trying to redefine an already defined table or value", {
2551
+ toml,
2552
+ ptr
2553
+ });
2554
+ }
2555
+ let v = extractValue(toml, k3[1], undefined, maxDepth, integersAsBigInt);
2556
+ p2[1][p2[0]] = v[0];
2557
+ ptr = v[1];
2558
+ }
2559
+ ptr = skipVoid(toml, ptr, true);
2560
+ if (toml[ptr] && toml[ptr] !== `
2561
+ ` && toml[ptr] !== "\r") {
2562
+ throw new TomlError("each key-value declaration must be followed by an end-of-line", {
2563
+ toml,
2564
+ ptr
2565
+ });
2566
+ }
2567
+ ptr = skipVoid(toml, ptr);
2568
+ }
2569
+ return res;
2570
+ }
2571
+
2572
+ // node_modules/smol-toml/dist/stringify.js
2573
+ /*!
2574
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2575
+ * SPDX-License-Identifier: BSD-3-Clause
2576
+ *
2577
+ * Redistribution and use in source and binary forms, with or without
2578
+ * modification, are permitted provided that the following conditions are met:
2579
+ *
2580
+ * 1. Redistributions of source code must retain the above copyright notice, this
2581
+ * list of conditions and the following disclaimer.
2582
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2583
+ * this list of conditions and the following disclaimer in the
2584
+ * documentation and/or other materials provided with the distribution.
2585
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2586
+ * may be used to endorse or promote products derived from this software without
2587
+ * specific prior written permission.
2588
+ *
2589
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2590
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2591
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2592
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2593
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2594
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2595
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2596
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2597
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2598
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2599
+ */
2600
+ var BARE_KEY = /^[a-z0-9-_]+$/i;
2601
+ function extendedTypeOf(obj) {
2602
+ let type = typeof obj;
2603
+ if (type === "object") {
2604
+ if (Array.isArray(obj))
2605
+ return "array";
2606
+ if (obj instanceof Date)
2607
+ return "date";
2608
+ }
2609
+ return type;
2610
+ }
2611
+ function isArrayOfTables(obj) {
2612
+ for (let i = 0;i < obj.length; i++) {
2613
+ if (extendedTypeOf(obj[i]) !== "object")
2614
+ return false;
2615
+ }
2616
+ return obj.length != 0;
2617
+ }
2618
+ function formatString(s) {
2619
+ return JSON.stringify(s).replace(/\x7f/g, "\\u007f");
2620
+ }
2621
+ function stringifyValue(val, type, depth, numberAsFloat) {
2622
+ if (depth === 0) {
2623
+ throw new Error("Could not stringify the object: maximum object depth exceeded");
2624
+ }
2625
+ if (type === "number") {
2626
+ if (isNaN(val))
2627
+ return "nan";
2628
+ if (val === Infinity)
2629
+ return "inf";
2630
+ if (val === -Infinity)
2631
+ return "-inf";
2632
+ if (numberAsFloat && Number.isInteger(val))
2633
+ return val.toFixed(1);
2634
+ return val.toString();
2635
+ }
2636
+ if (type === "bigint" || type === "boolean") {
2637
+ return val.toString();
2638
+ }
2639
+ if (type === "string") {
2640
+ return formatString(val);
2641
+ }
2642
+ if (type === "date") {
2643
+ if (isNaN(val.getTime())) {
2644
+ throw new TypeError("cannot serialize invalid date");
2645
+ }
2646
+ return val.toISOString();
2647
+ }
2648
+ if (type === "object") {
2649
+ return stringifyInlineTable(val, depth, numberAsFloat);
2650
+ }
2651
+ if (type === "array") {
2652
+ return stringifyArray(val, depth, numberAsFloat);
2653
+ }
2654
+ }
2655
+ function stringifyInlineTable(obj, depth, numberAsFloat) {
2656
+ let keys = Object.keys(obj);
2657
+ if (keys.length === 0)
2658
+ return "{}";
2659
+ let res = "{ ";
2660
+ for (let i = 0;i < keys.length; i++) {
2661
+ let k3 = keys[i];
2662
+ if (i)
2663
+ res += ", ";
2664
+ res += BARE_KEY.test(k3) ? k3 : formatString(k3);
2665
+ res += " = ";
2666
+ res += stringifyValue(obj[k3], extendedTypeOf(obj[k3]), depth - 1, numberAsFloat);
2667
+ }
2668
+ return res + " }";
2669
+ }
2670
+ function stringifyArray(array, depth, numberAsFloat) {
2671
+ if (array.length === 0)
2672
+ return "[]";
2673
+ let res = "[ ";
2674
+ for (let i = 0;i < array.length; i++) {
2675
+ if (i)
2676
+ res += ", ";
2677
+ if (array[i] === null || array[i] === undefined) {
2678
+ throw new TypeError("arrays cannot contain null or undefined values");
2679
+ }
2680
+ res += stringifyValue(array[i], extendedTypeOf(array[i]), depth - 1, numberAsFloat);
2681
+ }
2682
+ return res + " ]";
2683
+ }
2684
+ function stringifyArrayTable(array, key, depth, numberAsFloat) {
2685
+ if (depth === 0) {
2686
+ throw new Error("Could not stringify the object: maximum object depth exceeded");
2687
+ }
2688
+ let res = "";
2689
+ for (let i = 0;i < array.length; i++) {
2690
+ res += `${res && `
2691
+ `}[[${key}]]
2692
+ `;
2693
+ res += stringifyTable(0, array[i], key, depth, numberAsFloat);
2694
+ }
2695
+ return res;
2696
+ }
2697
+ function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat) {
2698
+ if (depth === 0) {
2699
+ throw new Error("Could not stringify the object: maximum object depth exceeded");
2700
+ }
2701
+ let preamble = "";
2702
+ let tables = "";
2703
+ let keys = Object.keys(obj);
2704
+ for (let i = 0;i < keys.length; i++) {
2705
+ let k3 = keys[i];
2706
+ if (obj[k3] !== null && obj[k3] !== undefined) {
2707
+ let type = extendedTypeOf(obj[k3]);
2708
+ if (type === "symbol" || type === "function") {
2709
+ throw new TypeError(`cannot serialize values of type '${type}'`);
2710
+ }
2711
+ let key = BARE_KEY.test(k3) ? k3 : formatString(k3);
2712
+ if (type === "array" && isArrayOfTables(obj[k3])) {
2713
+ tables += (tables && `
2714
+ `) + stringifyArrayTable(obj[k3], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat);
2715
+ } else if (type === "object") {
2716
+ let tblKey = prefix ? `${prefix}.${key}` : key;
2717
+ tables += (tables && `
2718
+ `) + stringifyTable(tblKey, obj[k3], tblKey, depth - 1, numberAsFloat);
2719
+ } else {
2720
+ preamble += key;
2721
+ preamble += " = ";
2722
+ preamble += stringifyValue(obj[k3], type, depth, numberAsFloat);
2723
+ preamble += `
2724
+ `;
2725
+ }
2726
+ }
2727
+ }
2728
+ if (tableKey && (preamble || !tables))
2729
+ preamble = preamble ? `[${tableKey}]
2730
+ ${preamble}` : `[${tableKey}]`;
2731
+ return preamble && tables ? `${preamble}
2732
+ ${tables}` : preamble || tables;
2733
+ }
2734
+ function stringify(obj, { maxDepth = 1000, numbersAsFloat = false } = {}) {
2735
+ if (extendedTypeOf(obj) !== "object") {
2736
+ throw new TypeError("stringify can only be called with an object");
2737
+ }
2738
+ let str = stringifyTable(0, obj, "", maxDepth, numbersAsFloat);
2739
+ if (str[str.length - 1] !== `
2740
+ `)
2741
+ return str + `
2742
+ `;
2743
+ return str;
2744
+ }
2745
+
2746
+ // node_modules/smol-toml/dist/index.js
2747
+ /*!
2748
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2749
+ * SPDX-License-Identifier: BSD-3-Clause
2750
+ *
2751
+ * Redistribution and use in source and binary forms, with or without
2752
+ * modification, are permitted provided that the following conditions are met:
2753
+ *
2754
+ * 1. Redistributions of source code must retain the above copyright notice, this
2755
+ * list of conditions and the following disclaimer.
2756
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2757
+ * this list of conditions and the following disclaimer in the
2758
+ * documentation and/or other materials provided with the distribution.
2759
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2760
+ * may be used to endorse or promote products derived from this software without
2761
+ * specific prior written permission.
2762
+ *
2763
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2764
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2765
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2766
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2767
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2768
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2769
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2770
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2771
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2772
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2773
+ */
2774
+
2775
+ // src/mcp-writer.ts
2776
+ var TOKEN_RE = /^[\w._:+\-/=]+$/;
2777
+ async function writeMcp(agent, ctx) {
2778
+ if (agent.authMode === "literal" && !TOKEN_RE.test(ctx.token)) {
2779
+ throw new Error("Bearer token contains unexpected characters; refusing to write config.");
2780
+ }
2781
+ const file = configFileFor(agent, ctx.cwd);
2782
+ const entries = {
2783
+ [DOCS_MCP_NAME]: agent.entry({ url: DOCS_MCP_ENDPOINT, authMode: "none", token: ctx.token, envVarName: MCP_TOKEN_VAR }),
2784
+ [DASHBOARD_MCP_NAME]: agent.entry({
2785
+ url: JUSPAY_MCP_ENDPOINT,
2786
+ authMode: agent.authMode,
2787
+ token: ctx.token,
2788
+ envVarName: MCP_TOKEN_VAR
2789
+ })
2790
+ };
2791
+ await fs5.mkdir(path4.dirname(file), { recursive: true });
2792
+ if (agent.format === "json") {
2793
+ await mergeJson(file, agent.containerKey, entries);
2794
+ } else {
2795
+ await mergeToml(file, agent.containerKey, entries);
2796
+ }
2797
+ await fs5.chmod(file, 384).catch(() => {});
2798
+ return file;
2799
+ }
2800
+ async function removeMcp(agent, cwd) {
2801
+ const file = configFileFor(agent, cwd);
2802
+ let raw;
2803
+ try {
2804
+ raw = await fs5.readFile(file, "utf8");
2805
+ } catch {
2806
+ return false;
2807
+ }
2808
+ const config = agent.format === "json" ? JSON.parse(raw) : parse(raw);
2809
+ const container = config[agent.containerKey];
2810
+ if (!container)
2811
+ return false;
2812
+ let changed = false;
2813
+ for (const name of OUR_MCP_NAMES) {
2814
+ if (container[name]) {
2815
+ delete container[name];
2816
+ changed = true;
2817
+ }
2818
+ }
2819
+ if (!changed)
2820
+ return false;
2821
+ const out = agent.format === "json" ? JSON.stringify(config, null, 2) + `
2822
+ ` : stringify(config);
2823
+ await fs5.writeFile(file, out, { mode: 384 });
2824
+ return true;
2825
+ }
2826
+ async function mergeJson(file, containerKey, entries) {
2827
+ let config = {};
2828
+ try {
2829
+ config = JSON.parse(await fs5.readFile(file, "utf8"));
2830
+ } catch {}
2831
+ const container = config[containerKey] && typeof config[containerKey] === "object" ? config[containerKey] : {};
2832
+ Object.assign(container, entries);
2833
+ config[containerKey] = container;
2834
+ await fs5.writeFile(file, JSON.stringify(config, null, 2) + `
2835
+ `, { mode: 384 });
2836
+ }
2837
+ async function mergeToml(file, containerKey, entries) {
2838
+ let config = {};
2839
+ try {
2840
+ config = parse(await fs5.readFile(file, "utf8"));
2841
+ } catch {}
2842
+ const container = config[containerKey] && typeof config[containerKey] === "object" ? config[containerKey] : {};
2843
+ Object.assign(container, entries);
2844
+ config[containerKey] = container;
2845
+ await fs5.writeFile(file, stringify(config), { mode: 384 });
2846
+ }
2847
+
2848
+ // src/skills-installer.ts
2849
+ import { spawn as spawn3 } from "node:child_process";
2850
+ import fs6 from "node:fs/promises";
2851
+ import path5 from "node:path";
2852
+ var OUR_SKILL = "integrate";
2853
+ function addSkills(cwd) {
2854
+ return runSkills(["add", SKILLS_PACKAGE], cwd);
2855
+ }
2856
+ async function ensureClaudeSkillLink(cwd) {
2857
+ const src = path5.join(cwd, ".agents", "skills", OUR_SKILL);
2858
+ try {
2859
+ await fs6.access(src);
2860
+ } catch {
2861
+ return;
2862
+ }
2863
+ const dest = path5.join(cwd, ".claude", "skills", OUR_SKILL);
2864
+ await fs6.mkdir(path5.dirname(dest), { recursive: true });
2865
+ try {
2866
+ await fs6.lstat(dest);
2867
+ return;
2868
+ } catch {}
2869
+ const relTarget = path5.join("..", "..", ".agents", "skills", OUR_SKILL);
2870
+ try {
2871
+ await fs6.symlink(relTarget, dest, "dir");
2872
+ } catch {
2873
+ await fs6.cp(src, dest, { recursive: true });
2874
+ }
2875
+ }
2876
+ async function removeSkills(cwd) {
2877
+ const removed = [];
2878
+ const dirs = [
2879
+ path5.join(cwd, ".agents", "skills", OUR_SKILL),
2880
+ path5.join(cwd, ".claude", "skills", OUR_SKILL)
2881
+ ];
2882
+ for (const dir of dirs) {
2883
+ try {
2884
+ await fs6.access(dir);
2885
+ await fs6.rm(dir, { recursive: true, force: true });
2886
+ removed.push(path5.relative(cwd, dir));
2887
+ } catch {}
2888
+ }
2889
+ return removed;
2890
+ }
2891
+ function runSkills(args, cwd) {
2892
+ return new Promise((resolve, reject) => {
2893
+ const child = spawn3("npx", ["-y", "skills", ...args], { cwd, stdio: "inherit" });
2894
+ child.on("error", reject);
2895
+ child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`skills ${args[0]} exited ${code}`)));
2896
+ });
2897
+ }
2898
+
2899
+ // src/setup.ts
2900
+ var import_picocolors4 = __toESM(require_picocolors(), 1);
2901
+ import { spawn as spawn4 } from "node:child_process";
2902
+ import fs7 from "node:fs/promises";
2903
+ import path6 from "node:path";
2904
+ var import_which2 = __toESM(require_lib(), 1);
2905
+ async function runSetup(cwd, token, include = []) {
2906
+ const agents = await detectAgents(cwd, include);
2907
+ const labels = [];
2908
+ const configs = [];
2909
+ const gitignore = [];
2910
+ const s = spin(`Configuring MCP for ${agents.length} agent(s)...`);
2911
+ for (const a of agents) {
2912
+ try {
2913
+ const file = await writeMcp(a, { cwd, token });
2914
+ configs.push(file);
2915
+ labels.push(a.label);
2916
+ if (a.authMode === "literal" && a.scope === "project") {
2917
+ gitignore.push(path6.relative(cwd, file));
2918
+ }
2919
+ } catch (err) {
2920
+ info(`${a.label}: ${err.message}`);
2921
+ }
2922
+ }
2923
+ s.done(`Configured ${labels.join(", ")}`);
2924
+ if (gitignore.length > 0)
2925
+ await updateGitignore(cwd, gitignore);
2926
+ step("Installing skills — follow the prompts below:");
2927
+ try {
2928
+ await addSkills(cwd);
2929
+ await ensureClaudeSkillLink(cwd);
2930
+ done("Skills installed (.agents/skills/ + .claude/skills/)");
2931
+ } catch (err) {
2932
+ warn(`Skills install failed: ${err.message}`);
2933
+ }
2934
+ return { cwd, agents: labels, configs };
2935
+ }
2936
+ async function ensureGlobalCli() {
2937
+ try {
2938
+ await import_which2.default("juspay");
2939
+ return;
2940
+ } catch {}
2941
+ const ok = await ye({
2942
+ message: `Install the \`juspay\` command globally so you can run \`juspay claude\`? (npm i -g ${PACKAGE_NAME})`,
2943
+ initialValue: true
2944
+ });
2945
+ if (pD(ok) || !ok) {
2946
+ info(`Skipped. You can still launch with: npx ${PACKAGE_NAME} <agent>`);
2947
+ return;
2948
+ }
2949
+ const sp = spin("Installing the juspay command globally...");
2950
+ try {
2951
+ await run("npm", ["install", "-g", PACKAGE_NAME]);
2952
+ sp.done("Installed `juspay` — try: juspay claude");
2953
+ } catch (err) {
2954
+ sp.fail(`Global install failed (${err.message}). Use: npx ${PACKAGE_NAME} <agent>`);
2955
+ }
2956
+ }
2957
+ function run(bin, args) {
2958
+ return new Promise((resolve, reject) => {
2959
+ const child = spawn4(bin, args, { stdio: "ignore" });
2960
+ child.on("error", reject);
2961
+ child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`${bin} exited ${code}`)));
2962
+ });
2963
+ }
2964
+ async function updateGitignore(cwd, relPaths) {
2965
+ const gitignorePath = path6.join(cwd, ".gitignore");
2966
+ const hasGitignore = await exists2(gitignorePath);
2967
+ if (!hasGitignore && !await isInsideGitRepo(cwd))
2968
+ return;
2969
+ const existing = hasGitignore ? await fs7.readFile(gitignorePath, "utf8") : "";
2970
+ const marker = "# Juspay AI CLI — token-bearing configs; do not commit";
2971
+ const known = new Set(existing.split(/\r?\n/));
2972
+ const toAdd = relPaths.filter((p2) => !known.has(p2));
2973
+ if (toAdd.length === 0)
2974
+ return;
2975
+ const header = existing.includes(marker) ? "" : marker + `
2976
+ `;
2977
+ const block = `
2978
+ ` + header + toAdd.join(`
2979
+ `) + `
2980
+ `;
2981
+ const updated = existing === "" || existing.endsWith(`
2982
+ `) ? existing + block : existing + `
2983
+ ` + block;
2984
+ await fs7.writeFile(gitignorePath, updated, "utf8");
2985
+ process.stdout.write(" " + import_picocolors4.default.dim(`→ Added ${toAdd.join(", ")} to .gitignore (token-bearing)
2986
+ `));
2987
+ }
2988
+ async function exists2(p2) {
2989
+ try {
2990
+ await fs7.access(p2);
2991
+ return true;
2992
+ } catch {
2993
+ return false;
2994
+ }
2995
+ }
2996
+ async function isInsideGitRepo(dir) {
2997
+ let current = path6.resolve(dir);
2998
+ while (true) {
2999
+ if (await exists2(path6.join(current, ".git")))
3000
+ return true;
3001
+ const parent = path6.dirname(current);
3002
+ if (parent === current)
3003
+ return false;
3004
+ current = parent;
3005
+ }
3006
+ }
3007
+
3008
+ // src/token.ts
3009
+ async function getToken() {
3010
+ const oauth = await readOAuth();
3011
+ if (!oauth)
3012
+ throw new Error("No session found. Run `npx @sahyll/ai` first.");
3013
+ return oauth.access_token;
3014
+ }
3015
+
3016
+ // src/index.ts
3017
+ var SESSION_SKEW_SECONDS = 24 * 60 * 60;
3018
+ function isUnderNpx() {
3019
+ return process.env.npm_command === "exec" || (process.env.npm_execpath || "").includes("npx") || (process.env.npm_config_user_agent || "").includes("npx") || (process.env.INIT_CWD || process.cwd()).includes("_npx");
3020
+ }
3021
+ function homeShort(p2) {
3022
+ return p2.replace(process.env.HOME ?? "~", "~");
3023
+ }
3024
+ function showBanner() {
3025
+ banner();
3026
+ }
3027
+ function showHelp(underNpx) {
3028
+ if (underNpx) {
3029
+ process.stdout.write(` Usage: npx ${PACKAGE_NAME} [command]
3030
+
3031
+ `);
3032
+ process.stdout.write(import_picocolors5.default.dim(` Sets up Juspay MCP + skills for this project and installs the
3033
+ `));
3034
+ process.stdout.write(import_picocolors5.default.dim(" `juspay` command. Launch agents afterwards with `juspay <agent>`.\n\n"));
3035
+ process.stdout.write(` Commands:
3036
+ `);
3037
+ process.stdout.write(" (no command) Sign in + set up MCP + skills, install the `juspay` command\n");
3038
+ process.stdout.write(` init Same as above (add --force to re-run sign-in)
3039
+ `);
3040
+ process.stdout.write(` update Re-write configs + re-install skills
3041
+ `);
3042
+ process.stdout.write(` list List skills installed in this project
3043
+ `);
3044
+ process.stdout.write(` logout Clear stored credentials
3045
+ `);
3046
+ process.stdout.write(` uninstall Remove EVERYTHING: the juspay command, credentials,
3047
+ `);
3048
+ process.stdout.write(` and this project's MCP + skills
3049
+ `);
3050
+ process.stdout.write(` help Show this help
3051
+
3052
+ `);
3053
+ process.stdout.write(" After setup, launch an agent: " + import_picocolors5.default.cyan("juspay claude") + import_picocolors5.default.dim(` (or codex, gemini, opencode, copilot)
3054
+
3055
+ `));
3056
+ return;
3057
+ }
3058
+ process.stdout.write(` Usage: juspay <agent|command>
3059
+
3060
+ `);
3061
+ process.stdout.write(import_picocolors5.default.dim(` Launch an AI agent with Juspay MCP + skills enabled.
3062
+
3063
+ `));
3064
+ process.stdout.write(` Agents (launchable):
3065
+ `);
3066
+ process.stdout.write(" " + LAUNCHABLE.map((a) => a.id).join(", ") + `
3067
+ `);
3068
+ process.stdout.write(import_picocolors5.default.dim(` (cursor, windsurf, vscode are GUI apps — configured; open them yourself)
3069
+
3070
+ `));
3071
+ process.stdout.write(` Commands:
3072
+ `);
3073
+ process.stdout.write(` <agent> Launch that agent (sets up this project on first run)
3074
+ `);
3075
+ process.stdout.write(` update Re-write configs + re-install skills
3076
+ `);
3077
+ process.stdout.write(` list List skills installed in this project
3078
+ `);
3079
+ process.stdout.write(` uninstall Remove Juspay MCP + skills from this project
3080
+ `);
3081
+ process.stdout.write(` logout Clear stored credentials
3082
+ `);
3083
+ process.stdout.write(` help Show this help
3084
+
3085
+ `);
3086
+ process.stdout.write(" First time? Run " + import_picocolors5.default.cyan(`npx ${PACKAGE_NAME}`) + import_picocolors5.default.dim(` to sign in and set up.
3087
+
3088
+ `));
3089
+ }
3090
+ function parseEnv(args) {
3091
+ const i = args.indexOf("--env");
3092
+ if (i === -1)
3093
+ return;
3094
+ const val = args[i + 1];
3095
+ if (val !== "sandbox" && val !== "production") {
3096
+ throw new Error("--env must be 'sandbox' or 'production'.");
3097
+ }
3098
+ return val;
3099
+ }
3100
+ async function ensureSession(args) {
3101
+ const cfg = await readConfig().catch(() => null);
3102
+ const oauth = await readOAuth().catch(() => null);
3103
+ const valid = oauth && oauth.expires_at > Math.floor(Date.now() / 1000) + SESSION_SKEW_SECONDS;
3104
+ if (cfg && valid)
3105
+ return;
3106
+ const fresh = await runInit({ env: parseEnv(args) });
3107
+ await writeConfig(fresh);
3108
+ }
3109
+ async function projectConfigured(cwd) {
3110
+ try {
3111
+ await fs8.access(path7.join(cwd, ".agents", "skills", "integrate"));
3112
+ return true;
3113
+ } catch {
3114
+ return false;
3115
+ }
3116
+ }
3117
+ async function runList() {
3118
+ const skillsDir = path7.join(process.cwd(), ".agents", "skills");
3119
+ let entries = [];
3120
+ try {
3121
+ const dirents = await fs8.readdir(skillsDir, { withFileTypes: true });
3122
+ entries = dirents.filter((d3) => d3.isDirectory() || d3.isSymbolicLink()).map((d3) => d3.name);
3123
+ } catch {
3124
+ entries = [];
3125
+ }
3126
+ if (entries.length === 0) {
3127
+ process.stdout.write(" " + import_picocolors5.default.yellow("⚠ ") + `No skills in this project. Run \`npx ${PACKAGE_NAME}\`.
3128
+ `);
3129
+ return;
3130
+ }
3131
+ process.stdout.write(" " + import_picocolors5.default.cyan("Skills in this project (.agents/skills/):") + `
3132
+ `);
3133
+ for (const skill of entries)
3134
+ process.stdout.write(` • ${skill}
3135
+ `);
3136
+ }
3137
+ async function removeProjectArtifacts(cwd) {
3138
+ const removedMcp = [];
3139
+ for (const a of AGENTS) {
3140
+ if (await removeMcp(a, cwd))
3141
+ removedMcp.push(a.label);
3142
+ }
3143
+ if (removedMcp.length > 0) {
3144
+ done(`Removed Juspay MCP from: ${removedMcp.join(", ")}`);
3145
+ } else {
3146
+ info("• No Juspay MCP entries found in this project");
3147
+ }
3148
+ const removedSkills = await removeSkills(cwd);
3149
+ if (removedSkills.length > 0) {
3150
+ done(`Removed skills from: ${removedSkills.join(", ")}`);
3151
+ } else {
3152
+ info("• No Juspay skills found in this project");
3153
+ }
3154
+ }
3155
+ async function runUninstall() {
3156
+ await removeProjectArtifacts(process.cwd());
3157
+ process.stdout.write(`
3158
+ ` + import_picocolors5.default.cyan("Juspay context removed from this project.") + `
3159
+ `);
3160
+ process.stdout.write(import_picocolors5.default.dim(" (Per-project — run `juspay uninstall` in other projects to clean them too.)\n"));
3161
+ process.stdout.write(import_picocolors5.default.dim(` (To remove the tool itself: npx ${PACKAGE_NAME} uninstall)
3162
+
3163
+ `));
3164
+ }
3165
+ async function runFullUninstall() {
3166
+ await removeProjectArtifacts(process.cwd());
3167
+ await fs8.rm(juspayConfigDir, { recursive: true, force: true });
3168
+ done(`Cleared stored credentials (${homeShort(juspayConfigDir)})`);
3169
+ const sp = spin(`Uninstalling the juspay command (npm rm -g ${PACKAGE_NAME})...`);
3170
+ try {
3171
+ await run2("npm", ["rm", "-g", PACKAGE_NAME]);
3172
+ sp.done("Uninstalled the juspay command");
3173
+ } catch (err) {
3174
+ sp.fail(`Could not remove it automatically (${err.message}). Run: npm rm -g ${PACKAGE_NAME}`);
3175
+ }
3176
+ process.stdout.write(`
3177
+ ` + import_picocolors5.default.cyan("Juspay fully removed.") + `
3178
+
3179
+ `);
3180
+ }
3181
+ async function runLogout() {
3182
+ await fs8.rm(juspayConfigDir, { recursive: true, force: true });
3183
+ done(`Cleared stored credentials (${homeShort(juspayConfigDir)})`);
3184
+ }
3185
+ function nextSteps() {
3186
+ process.stdout.write(`
3187
+ ` + import_picocolors5.default.bold("Next steps") + `
3188
+ `);
3189
+ process.stdout.write(" " + import_picocolors5.default.dim("Launch an agent (MCP + skills already wired in):") + `
3190
+ `);
3191
+ process.stdout.write(" " + import_picocolors5.default.cyan("juspay claude") + import_picocolors5.default.dim(" # or codex, gemini, opencode, copilot") + `
3192
+
3193
+ `);
3194
+ process.stdout.write(" " + import_picocolors5.default.dim("Project cleanup (MCP + skills): ") + import_picocolors5.default.cyan("juspay uninstall") + `
3195
+ `);
3196
+ process.stdout.write(" " + import_picocolors5.default.dim("Remove the tool entirely: ") + import_picocolors5.default.cyan(`npx ${PACKAGE_NAME} uninstall`) + `
3197
+
3198
+ `);
3199
+ }
3200
+ async function printSetupSummary(result) {
3201
+ const oauth = await readOAuth().catch(() => null);
3202
+ const cfg = await readConfig().catch(() => null);
3203
+ const rows = [];
3204
+ if (oauth) {
3205
+ rows.push({ label: "Session ", value: `valid until ${new Date(oauth.expires_at * 1000).toDateString()}` });
3206
+ }
3207
+ if (cfg) {
3208
+ rows.push({ label: "Merchant ", value: cfg.merchant_id });
3209
+ rows.push({ label: "Environment", value: cfg.environment });
3210
+ }
3211
+ rows.push({ label: "MCPs ", value: "docs-mcp-server, juspay-mcp" });
3212
+ if (result.agents.length > 0)
3213
+ rows.push({ label: "Agents ", value: result.agents.join(", ") });
3214
+ rows.push({ label: "Skills ", value: "integrate (.agents/skills/)" });
3215
+ rows.push({ label: "Project ", value: homeShort(result.cwd) });
3216
+ summaryBox("Setup complete", rows);
3217
+ nextSteps();
3218
+ }
3219
+ function run2(bin, args) {
3220
+ return new Promise((resolve, reject) => {
3221
+ const child = spawn5(bin, args, { stdio: "ignore" });
3222
+ child.on("error", reject);
3223
+ child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`${bin} exited ${code}`)));
3224
+ });
3225
+ }
3226
+ async function main() {
3227
+ const args = process.argv.slice(2);
3228
+ const command = args[0];
3229
+ const underNpx = isUnderNpx();
3230
+ const invocation = underNpx ? `npx ${PACKAGE_NAME}` : "juspay";
3231
+ if (command === "help" || command === "--help" || command === "-h") {
3232
+ showBanner();
3233
+ showHelp(underNpx);
3234
+ return;
3235
+ }
3236
+ if (command === "uninstall") {
3237
+ showBanner();
3238
+ if (underNpx)
3239
+ await runFullUninstall();
3240
+ else
3241
+ await runUninstall();
3242
+ return;
3243
+ }
3244
+ if (command === "logout") {
3245
+ showBanner();
3246
+ await runLogout();
3247
+ return;
3248
+ }
3249
+ if (command === "list") {
3250
+ showBanner();
3251
+ await runList();
3252
+ return;
3253
+ }
3254
+ showBanner();
3255
+ const cwd = process.cwd();
3256
+ if (command === "update") {
3257
+ await ensureSession(args);
3258
+ const token2 = await getToken();
3259
+ const result = await runSetup(cwd, token2);
3260
+ done(`Updated ${result.agents.join(", ")} in ${homeShort(result.cwd)}`);
3261
+ return;
3262
+ }
3263
+ if (command === "init") {
3264
+ const force = args.includes("--force");
3265
+ const cfg = await runInit({ env: parseEnv(args), force });
3266
+ await writeConfig(cfg);
3267
+ const token2 = await getToken();
3268
+ const result = await runSetup(cwd, token2);
3269
+ await ensureGlobalCli();
3270
+ await printSetupSummary(result);
3271
+ return;
3272
+ }
3273
+ if (!command) {
3274
+ if (underNpx) {
3275
+ await ensureSession(args);
3276
+ const token2 = await getToken();
3277
+ const result = await runSetup(cwd, token2);
3278
+ await ensureGlobalCli();
3279
+ await printSetupSummary(result);
3280
+ } else {
3281
+ showHelp(false);
3282
+ }
3283
+ return;
3284
+ }
3285
+ const agent = findAgent(command);
3286
+ if (!agent) {
3287
+ throw new Error(`Unknown command or agent '${command}'. Run \`${invocation} help\`.`);
3288
+ }
3289
+ if (underNpx) {
3290
+ warn(`Launching agents is done with the \`juspay\` command — e.g. \`juspay ${agent.id}\`.`);
3291
+ info(`Run \`npx ${PACKAGE_NAME}\` (no agent) to sign in and set up first; it installs the \`juspay\` command.`);
3292
+ return;
3293
+ }
3294
+ await ensureSession(args);
3295
+ const token = await getToken();
3296
+ if (!await projectConfigured(cwd)) {
3297
+ const result = await runSetup(cwd, token, [agent.id]);
3298
+ await printSetupSummary(result);
3299
+ } else {
3300
+ await writeMcp(agent, { cwd, token }).catch((err) => {
3301
+ warn(`Could not refresh ${agent.label} MCP config: ${err.message}`);
3302
+ });
3303
+ }
3304
+ if (agent.kind === "gui") {
3305
+ info(`${agent.label} is a GUI app — configured for this project. Just open it.`);
3306
+ return;
3307
+ }
3308
+ const bin = await ensureAgentBin(agent);
3309
+ if (!bin) {
3310
+ warn(`${agent.label} isn't available. This project is configured — install it and re-run \`juspay ${agent.id}\`.`);
3311
+ return;
3312
+ }
3313
+ step(`Launching ${agent.label}...`);
3314
+ await prepareAgentLaunch(agent);
3315
+ launchAgent(bin, args.slice(1), token);
3316
+ }
3317
+ main().catch((err) => {
3318
+ const message = err instanceof Error ? err.message : String(err);
3319
+ process.stderr.write(import_picocolors5.default.red("✗ ") + message + `
3320
+ `);
3321
+ process.exit(1);
3322
+ });