@swmansion/argent 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli-cmds.mjs CHANGED
@@ -1,8 +1,161 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+
28
+ // ../../node_modules/sisteransi/src/index.js
29
+ var require_src = __commonJS({
30
+ "../../node_modules/sisteransi/src/index.js"(exports, module) {
31
+ "use strict";
32
+ var ESC2 = "\x1B";
33
+ var CSI2 = `${ESC2}[`;
34
+ var beep = "\x07";
35
+ var cursor = {
36
+ to(x3, y) {
37
+ if (!y) return `${CSI2}${x3 + 1}G`;
38
+ return `${CSI2}${y + 1};${x3 + 1}H`;
39
+ },
40
+ move(x3, y) {
41
+ let ret = "";
42
+ if (x3 < 0) ret += `${CSI2}${-x3}D`;
43
+ else if (x3 > 0) ret += `${CSI2}${x3}C`;
44
+ if (y < 0) ret += `${CSI2}${-y}A`;
45
+ else if (y > 0) ret += `${CSI2}${y}B`;
46
+ return ret;
47
+ },
48
+ up: (count = 1) => `${CSI2}${count}A`,
49
+ down: (count = 1) => `${CSI2}${count}B`,
50
+ forward: (count = 1) => `${CSI2}${count}C`,
51
+ backward: (count = 1) => `${CSI2}${count}D`,
52
+ nextLine: (count = 1) => `${CSI2}E`.repeat(count),
53
+ prevLine: (count = 1) => `${CSI2}F`.repeat(count),
54
+ left: `${CSI2}G`,
55
+ hide: `${CSI2}?25l`,
56
+ show: `${CSI2}?25h`,
57
+ save: `${ESC2}7`,
58
+ restore: `${ESC2}8`
59
+ };
60
+ var scroll = {
61
+ up: (count = 1) => `${CSI2}S`.repeat(count),
62
+ down: (count = 1) => `${CSI2}T`.repeat(count)
63
+ };
64
+ var erase = {
65
+ screen: `${CSI2}2J`,
66
+ up: (count = 1) => `${CSI2}1J`.repeat(count),
67
+ down: (count = 1) => `${CSI2}J`.repeat(count),
68
+ line: `${CSI2}2K`,
69
+ lineEnd: `${CSI2}K`,
70
+ lineStart: `${CSI2}1K`,
71
+ lines(count) {
72
+ let clear = "";
73
+ for (let i = 0; i < count; i++)
74
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
75
+ if (count)
76
+ clear += cursor.left;
77
+ return clear;
78
+ }
79
+ };
80
+ module.exports = { cursor, scroll, erase, beep };
81
+ }
82
+ });
83
+
84
+ // ../../node_modules/picocolors/picocolors.js
85
+ var require_picocolors = __commonJS({
86
+ "../../node_modules/picocolors/picocolors.js"(exports, module) {
87
+ var p2 = process || {};
88
+ var argv = p2.argv || [];
89
+ var env = p2.env || {};
90
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p2.platform === "win32" || (p2.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
91
+ var formatter = (open, close, replace = open) => (input) => {
92
+ let string = "" + input, index = string.indexOf(close, open.length);
93
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
94
+ };
95
+ var replaceClose = (string, close, replace, index) => {
96
+ let result = "", cursor = 0;
97
+ do {
98
+ result += string.substring(cursor, index) + replace;
99
+ cursor = index + close.length;
100
+ index = string.indexOf(close, cursor);
101
+ } while (~index);
102
+ return result + string.substring(cursor);
103
+ };
104
+ var createColors = (enabled = isColorSupported) => {
105
+ let f2 = enabled ? formatter : () => String;
106
+ return {
107
+ isColorSupported: enabled,
108
+ reset: f2("\x1B[0m", "\x1B[0m"),
109
+ bold: f2("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
110
+ dim: f2("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
111
+ italic: f2("\x1B[3m", "\x1B[23m"),
112
+ underline: f2("\x1B[4m", "\x1B[24m"),
113
+ inverse: f2("\x1B[7m", "\x1B[27m"),
114
+ hidden: f2("\x1B[8m", "\x1B[28m"),
115
+ strikethrough: f2("\x1B[9m", "\x1B[29m"),
116
+ black: f2("\x1B[30m", "\x1B[39m"),
117
+ red: f2("\x1B[31m", "\x1B[39m"),
118
+ green: f2("\x1B[32m", "\x1B[39m"),
119
+ yellow: f2("\x1B[33m", "\x1B[39m"),
120
+ blue: f2("\x1B[34m", "\x1B[39m"),
121
+ magenta: f2("\x1B[35m", "\x1B[39m"),
122
+ cyan: f2("\x1B[36m", "\x1B[39m"),
123
+ white: f2("\x1B[37m", "\x1B[39m"),
124
+ gray: f2("\x1B[90m", "\x1B[39m"),
125
+ bgBlack: f2("\x1B[40m", "\x1B[49m"),
126
+ bgRed: f2("\x1B[41m", "\x1B[49m"),
127
+ bgGreen: f2("\x1B[42m", "\x1B[49m"),
128
+ bgYellow: f2("\x1B[43m", "\x1B[49m"),
129
+ bgBlue: f2("\x1B[44m", "\x1B[49m"),
130
+ bgMagenta: f2("\x1B[45m", "\x1B[49m"),
131
+ bgCyan: f2("\x1B[46m", "\x1B[49m"),
132
+ bgWhite: f2("\x1B[47m", "\x1B[49m"),
133
+ blackBright: f2("\x1B[90m", "\x1B[39m"),
134
+ redBright: f2("\x1B[91m", "\x1B[39m"),
135
+ greenBright: f2("\x1B[92m", "\x1B[39m"),
136
+ yellowBright: f2("\x1B[93m", "\x1B[39m"),
137
+ blueBright: f2("\x1B[94m", "\x1B[39m"),
138
+ magentaBright: f2("\x1B[95m", "\x1B[39m"),
139
+ cyanBright: f2("\x1B[96m", "\x1B[39m"),
140
+ whiteBright: f2("\x1B[97m", "\x1B[39m"),
141
+ bgBlackBright: f2("\x1B[100m", "\x1B[49m"),
142
+ bgRedBright: f2("\x1B[101m", "\x1B[49m"),
143
+ bgGreenBright: f2("\x1B[102m", "\x1B[49m"),
144
+ bgYellowBright: f2("\x1B[103m", "\x1B[49m"),
145
+ bgBlueBright: f2("\x1B[104m", "\x1B[49m"),
146
+ bgMagentaBright: f2("\x1B[105m", "\x1B[49m"),
147
+ bgCyanBright: f2("\x1B[106m", "\x1B[49m"),
148
+ bgWhiteBright: f2("\x1B[107m", "\x1B[49m")
149
+ };
150
+ };
151
+ module.exports = createColors();
152
+ module.exports.createColors = createColors;
153
+ }
154
+ });
2
155
 
3
156
  // ../argent-cli/src/run.ts
4
157
  import * as fs2 from "node:fs";
5
- import * as path2 from "node:path";
158
+ import * as path3 from "node:path";
6
159
 
7
160
  // ../argent-tools-client/src/launcher.ts
8
161
  import * as net from "node:net";
@@ -11,20 +164,36 @@ import * as path from "node:path";
11
164
  import * as readline from "node:readline";
12
165
  import { homedir } from "node:os";
13
166
  import { spawn } from "node:child_process";
14
- import { mkdir, writeFile, readFile, unlink } from "node:fs/promises";
167
+ import { randomBytes } from "node:crypto";
168
+ import { mkdir, writeFile, readFile, unlink, rename, chmod } from "node:fs/promises";
15
169
  var STATE_DIR = path.join(homedir(), ".argent");
16
170
  var STATE_FILE = path.join(STATE_DIR, "tool-server.json");
17
171
  var LOG_FILE = path.join(STATE_DIR, "tool-server.log");
18
- function buildToolsServerEnv(paths, port, baseEnv = process.env) {
19
- return {
172
+ var AUTH_TOKEN_BYTES = 32;
173
+ var AUTH_TOKEN_ENV = "ARGENT_AUTH_TOKEN";
174
+ var AUTOSPAWN_IDLE_TIMEOUT_MINUTES = 30;
175
+ function buildToolsServerEnv(paths, port, baseEnv = process.env, options = {}) {
176
+ const env = {
20
177
  ...baseEnv,
21
- PORT: String(port),
178
+ ARGENT_PORT: String(port),
22
179
  ARGENT_SIMULATOR_SERVER_DIR: paths.simulatorServerDir,
23
180
  ARGENT_NATIVE_DEVTOOLS_DIR: paths.nativeDevtoolsDir
24
181
  };
182
+ if (options.host !== void 0) env.ARGENT_HOST = options.host;
183
+ if (options.idleTimeoutMinutes !== void 0) {
184
+ env.ARGENT_IDLE_TIMEOUT_MINUTES = String(options.idleTimeoutMinutes);
185
+ }
186
+ if (options.token) env[AUTH_TOKEN_ENV] = options.token;
187
+ return env;
188
+ }
189
+ function generateToken() {
190
+ return randomBytes(AUTH_TOKEN_BYTES).toString("hex");
191
+ }
192
+ function generateAuthToken() {
193
+ return generateToken();
25
194
  }
26
195
  function findFreePort() {
27
- return new Promise((resolve2, reject) => {
196
+ return new Promise((resolve3, reject) => {
28
197
  const srv = net.createServer();
29
198
  srv.listen(0, "127.0.0.1", () => {
30
199
  const addr = srv.address();
@@ -35,7 +204,7 @@ function findFreePort() {
35
204
  const port = addr.port;
36
205
  srv.close((err) => {
37
206
  if (err) reject(err);
38
- else resolve2(port);
207
+ else resolve3(port);
39
208
  });
40
209
  });
41
210
  srv.on("error", reject);
@@ -49,12 +218,28 @@ function isProcessAlive(pid) {
49
218
  return false;
50
219
  }
51
220
  }
52
- async function isHealthy(port) {
221
+ function isToolsServerProcessAlive(pid) {
222
+ return isProcessAlive(pid);
223
+ }
224
+ function healthCheckHost(host) {
225
+ if (host === "0.0.0.0" || host === "") return "127.0.0.1";
226
+ if (host === "::" || host === "::0") return "::1";
227
+ return host;
228
+ }
229
+ function formatUrl(host, port) {
230
+ const h2 = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
231
+ return `http://${h2}:${port}`;
232
+ }
233
+ function authHeaders(token) {
234
+ return token ? { Authorization: `Bearer ${token}` } : {};
235
+ }
236
+ async function isToolsServerHealthy(port, host = "127.0.0.1", timeoutMs = 2e3, token) {
53
237
  const controller = new AbortController();
54
- const timer = setTimeout(() => controller.abort(), 2e3);
238
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
55
239
  try {
56
- const res = await fetch(`http://127.0.0.1:${port}/tools`, {
57
- signal: controller.signal
240
+ const res = await fetch(`${formatUrl(healthCheckHost(host), port)}/tools`, {
241
+ signal: controller.signal,
242
+ headers: authHeaders(token)
58
243
  });
59
244
  return res.ok;
60
245
  } catch {
@@ -63,8 +248,8 @@ async function isHealthy(port) {
63
248
  clearTimeout(timer);
64
249
  }
65
250
  }
66
- function spawnToolsServer(paths, port) {
67
- return new Promise((resolve2, reject) => {
251
+ function spawnToolsServer(paths, port, options = {}) {
252
+ return new Promise((resolve3, reject) => {
68
253
  let logFd;
69
254
  try {
70
255
  fs.mkdirSync(STATE_DIR, { recursive: true });
@@ -75,7 +260,7 @@ function spawnToolsServer(paths, port) {
75
260
  const child = spawn("node", [paths.bundlePath, "start"], {
76
261
  detached: true,
77
262
  stdio: ["ignore", "pipe", logFd],
78
- env: buildToolsServerEnv(paths, port)
263
+ env: buildToolsServerEnv(paths, port, process.env, options)
79
264
  });
80
265
  child.unref();
81
266
  const pid = child.pid;
@@ -91,12 +276,12 @@ function spawnToolsServer(paths, port) {
91
276
  };
92
277
  const rl = readline.createInterface({ input: child.stdout });
93
278
  rl.on("line", (line) => {
94
- const match = line.match(/Tools server listening on http:\/\/127\.0\.0\.1:(\d+)/);
279
+ const match = line.match(/Tools server listening on http:\/\/.+:(\d+)/);
95
280
  if (match) {
96
281
  const actualPort = parseInt(match[1], 10);
97
282
  rl.close();
98
283
  child.stdout?.resume();
99
- settle(() => resolve2({ port: actualPort, pid }));
284
+ settle(() => resolve3({ port: actualPort, pid }));
100
285
  }
101
286
  });
102
287
  child.on("error", (err) => {
@@ -114,7 +299,7 @@ function spawnToolsServer(paths, port) {
114
299
  rl.on("close", () => clearTimeout(timer));
115
300
  });
116
301
  }
117
- async function readState() {
302
+ async function readToolsServerState() {
118
303
  try {
119
304
  const raw = await readFile(STATE_FILE, "utf8");
120
305
  return JSON.parse(raw);
@@ -122,22 +307,73 @@ async function readState() {
122
307
  return null;
123
308
  }
124
309
  }
125
- async function writeState(state) {
310
+ async function writeToolsServerState(state) {
126
311
  await mkdir(STATE_DIR, { recursive: true });
127
- await writeFile(STATE_FILE, JSON.stringify(state, null, 2) + "\n", "utf8");
312
+ const tmp = `${STATE_FILE}.${process.pid}.tmp`;
313
+ try {
314
+ await writeFile(tmp, JSON.stringify(state, null, 2) + "\n", {
315
+ encoding: "utf8",
316
+ mode: 384
317
+ });
318
+ await chmod(tmp, 384);
319
+ await rename(tmp, STATE_FILE);
320
+ } catch (err) {
321
+ await unlink(tmp).catch(() => {
322
+ });
323
+ throw err;
324
+ }
325
+ }
326
+ function writeToolsServerStateSync(state) {
327
+ fs.mkdirSync(STATE_DIR, { recursive: true });
328
+ fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2) + "\n", {
329
+ encoding: "utf8",
330
+ mode: 384
331
+ });
332
+ fs.chmodSync(STATE_FILE, 384);
128
333
  }
129
- async function clearState() {
334
+ async function clearToolsServerState() {
130
335
  try {
131
336
  await unlink(STATE_FILE);
132
337
  } catch {
133
338
  }
134
339
  }
340
+ var readState = readToolsServerState;
341
+ var writeState = writeToolsServerState;
342
+ var clearState = clearToolsServerState;
343
+ var SIGTERM_GRACE_MS = 6e3;
344
+ var SIGKILL_GRACE_MS = 1e3;
345
+ var KILL_POLL_MS = 100;
346
+ async function waitForExit(pid, timeoutMs) {
347
+ const deadline = Date.now() + timeoutMs;
348
+ while (Date.now() < deadline) {
349
+ if (!isProcessAlive(pid)) return true;
350
+ await new Promise((r) => setTimeout(r, KILL_POLL_MS));
351
+ }
352
+ return !isProcessAlive(pid);
353
+ }
135
354
  async function killToolServer() {
136
355
  const state = await readState();
137
356
  if (!state) return;
138
- try {
139
- process.kill(state.pid, "SIGTERM");
140
- } catch {
357
+ let exited = !isProcessAlive(state.pid);
358
+ if (!exited) {
359
+ try {
360
+ process.kill(state.pid, "SIGTERM");
361
+ } catch {
362
+ exited = true;
363
+ }
364
+ }
365
+ if (!exited) {
366
+ exited = await waitForExit(state.pid, SIGTERM_GRACE_MS);
367
+ }
368
+ if (!exited) {
369
+ try {
370
+ process.kill(state.pid, "SIGKILL");
371
+ } catch {
372
+ exited = true;
373
+ }
374
+ if (!exited) {
375
+ await waitForExit(state.pid, SIGKILL_GRACE_MS);
376
+ }
141
377
  }
142
378
  await clearState();
143
379
  }
@@ -146,29 +382,154 @@ async function ensureToolsServer(paths) {
146
382
  if (state) {
147
383
  const alive = isProcessAlive(state.pid);
148
384
  if (alive) {
149
- const healthy = await isHealthy(state.port);
385
+ const host = state.host ?? "127.0.0.1";
386
+ const healthy = await isToolsServerHealthy(state.port, host, 2e3, state.token);
150
387
  if (healthy) {
151
- return `http://127.0.0.1:${state.port}`;
388
+ return {
389
+ url: formatUrl(healthCheckHost(host), state.port),
390
+ token: state.token ?? ""
391
+ };
152
392
  }
153
393
  }
154
394
  await clearState();
155
395
  }
396
+ const token = generateToken();
156
397
  const port = await findFreePort();
157
- const { port: actualPort, pid } = await spawnToolsServer(paths, port);
398
+ const { port: actualPort, pid } = await spawnToolsServer(paths, port, {
399
+ token,
400
+ idleTimeoutMinutes: AUTOSPAWN_IDLE_TIMEOUT_MINUTES
401
+ });
158
402
  await writeState({
159
403
  port: actualPort,
160
404
  pid,
161
405
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
162
- bundlePath: paths.bundlePath
406
+ bundlePath: paths.bundlePath,
407
+ host: "127.0.0.1",
408
+ token
409
+ });
410
+ return { url: formatUrl("127.0.0.1", actualPort), token };
411
+ }
412
+
413
+ // ../argent-tools-client/src/link-config.ts
414
+ import * as path2 from "node:path";
415
+ import { homedir as homedir2 } from "node:os";
416
+ import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2, unlink as unlink2, chmod as chmod2 } from "node:fs/promises";
417
+ var LINK_DIR = path2.join(homedir2(), ".argent");
418
+ var LINK_FILE = path2.join(LINK_DIR, "link.json");
419
+ async function readLinkConfig() {
420
+ try {
421
+ const raw = await readFile2(LINK_FILE, "utf8");
422
+ const parsed = JSON.parse(raw);
423
+ if (!parsed || typeof parsed.url !== "string" || typeof parsed.host !== "string" || typeof parsed.port !== "number" || typeof parsed.createdAt !== "string") {
424
+ return null;
425
+ }
426
+ return {
427
+ url: parsed.url,
428
+ host: parsed.host,
429
+ port: parsed.port,
430
+ createdAt: parsed.createdAt,
431
+ ...typeof parsed.token === "string" ? { token: parsed.token } : {}
432
+ };
433
+ } catch {
434
+ return null;
435
+ }
436
+ }
437
+ async function writeLinkConfig(cfg) {
438
+ await mkdir2(LINK_DIR, { recursive: true });
439
+ await writeFile2(LINK_FILE, JSON.stringify(cfg, null, 2) + "\n", {
440
+ encoding: "utf8",
441
+ mode: 384
163
442
  });
164
- return `http://127.0.0.1:${actualPort}`;
443
+ await chmod2(LINK_FILE, 384);
444
+ }
445
+ async function clearLinkConfig() {
446
+ try {
447
+ await unlink2(LINK_FILE);
448
+ } catch {
449
+ }
450
+ }
451
+ async function getResolvedToolsUrl() {
452
+ const envUrl = process.env.ARGENT_TOOLS_URL;
453
+ if (envUrl) {
454
+ const link3 = await readLinkConfig();
455
+ const envToken = process.env[AUTH_TOKEN_ENV];
456
+ return {
457
+ url: envUrl,
458
+ source: "env",
459
+ ...envToken ? { token: envToken } : {},
460
+ ...link3 ? { shadowedLink: link3 } : {}
461
+ };
462
+ }
463
+ const link2 = await readLinkConfig();
464
+ if (link2) {
465
+ return { url: link2.url, source: "link", ...link2.token ? { token: link2.token } : {} };
466
+ }
467
+ return { url: null, source: "none" };
468
+ }
469
+ var LINK_URL_SCHEME = "argent:";
470
+ function formatLinkUrl(parts) {
471
+ const h2 = parts.host.includes(":") && !parts.host.startsWith("[") ? `[${parts.host}]` : parts.host;
472
+ const auth = parts.token ? `${encodeURIComponent(parts.token)}@` : "";
473
+ return `${LINK_URL_SCHEME}//${auth}${h2}:${parts.port}`;
474
+ }
475
+ function parseLinkUrl(input) {
476
+ if (!input.startsWith(`${LINK_URL_SCHEME}//`)) return null;
477
+ let u;
478
+ try {
479
+ u = new URL(input);
480
+ } catch {
481
+ throw new Error(
482
+ `Invalid connection string "${input}" \u2014 expected argent://[<token>@]<host>:<port>`
483
+ );
484
+ }
485
+ const host = u.hostname.startsWith("[") ? u.hostname.slice(1, -1) : u.hostname;
486
+ if (!host) throw new Error(`Connection string "${input}" is missing a host.`);
487
+ if (!u.port) throw new Error(`Connection string "${input}" is missing a port.`);
488
+ const port = Number(u.port);
489
+ const token = u.username ? decodeURIComponent(u.username) : void 0;
490
+ return { host, port, ...token ? { token } : {} };
491
+ }
492
+ function httpFromHostPort(host, port) {
493
+ const h2 = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
494
+ return `http://${h2}:${port}`;
495
+ }
496
+ function parseLinkTarget(input) {
497
+ const argent = parseLinkUrl(input);
498
+ if (argent) {
499
+ return {
500
+ url: httpFromHostPort(argent.host, argent.port),
501
+ host: argent.host,
502
+ port: argent.port,
503
+ ...argent.token ? { token: argent.token } : {}
504
+ };
505
+ }
506
+ if (!/^https?:\/\//i.test(input)) return null;
507
+ let u;
508
+ try {
509
+ u = new URL(input);
510
+ } catch {
511
+ throw new Error(`Invalid URL "${input}" \u2014 expected http(s)://<host>[:<port>][/path].`);
512
+ }
513
+ const host = u.hostname.startsWith("[") ? u.hostname.slice(1, -1) : u.hostname;
514
+ if (!host) throw new Error(`URL "${input}" is missing a host.`);
515
+ const port = u.port ? Number(u.port) : u.protocol === "https:" ? 443 : 80;
516
+ const path6 = u.pathname === "/" ? "" : u.pathname.replace(/\/+$/, "");
517
+ const url = `${u.protocol}//${u.host}${path6}`;
518
+ const token = u.username ? decodeURIComponent(u.username) : void 0;
519
+ return { url, host, port, ...token ? { token } : {} };
165
520
  }
166
521
 
167
522
  // ../argent-tools-client/src/tools-client.ts
523
+ function authHeaders2(token) {
524
+ return token ? { Authorization: `Bearer ${token}` } : {};
525
+ }
168
526
  function createToolsClient(options = {}) {
169
527
  let cached = null;
170
528
  async function baseUrl() {
171
- if (process.env.ARGENT_TOOLS_URL) return process.env.ARGENT_TOOLS_URL;
529
+ const resolved = await getResolvedToolsUrl();
530
+ if (resolved.url) {
531
+ return { url: resolved.url, token: resolved.token ?? "" };
532
+ }
172
533
  if (cached) return cached;
173
534
  if (!options.paths) {
174
535
  throw new Error(
@@ -179,8 +540,8 @@ function createToolsClient(options = {}) {
179
540
  return cached;
180
541
  }
181
542
  async function fetchTools() {
182
- const url = await baseUrl();
183
- const res = await fetch(`${url}/tools`);
543
+ const { url, token } = await baseUrl();
544
+ const res = await fetch(`${url}/tools`, { headers: authHeaders2(token) });
184
545
  if (!res.ok) throw new Error(`GET /tools failed: ${res.status} ${res.statusText}`);
185
546
  const json = await res.json();
186
547
  return json.tools;
@@ -190,10 +551,10 @@ function createToolsClient(options = {}) {
190
551
  return tools2.find((t) => t.name === name) ?? null;
191
552
  }
192
553
  async function callTool(name, args) {
193
- const url = await baseUrl();
554
+ const { url, token } = await baseUrl();
194
555
  const res = await fetch(`${url}/tools/${encodeURIComponent(name)}`, {
195
556
  method: "POST",
196
- headers: { "Content-Type": "application/json" },
557
+ headers: { "Content-Type": "application/json", ...authHeaders2(token) },
197
558
  body: JSON.stringify(args ?? {})
198
559
  });
199
560
  const json = await res.json().catch(() => ({}));
@@ -259,7 +620,7 @@ function parseFlags(argv, schema) {
259
620
  continue;
260
621
  }
261
622
  if (tok === "--") {
262
- for (let j = i + 1; j < argv.length; j++) positional.push(argv[j]);
623
+ for (let j2 = i + 1; j2 < argv.length; j2++) positional.push(argv[j2]);
263
624
  break;
264
625
  }
265
626
  if (!tok.startsWith("--")) {
@@ -366,7 +727,7 @@ function renderFlagName(name, prop) {
366
727
  }
367
728
  function renderType(prop) {
368
729
  if (prop.enum && Array.isArray(prop.enum)) {
369
- return `enum: ${prop.enum.map((v) => JSON.stringify(v)).join(" | ")}`;
730
+ return `enum: ${prop.enum.map((v2) => JSON.stringify(v2)).join(" | ")}`;
370
731
  }
371
732
  if (prop.type === "array") {
372
733
  const item = prop.items?.type ?? "any";
@@ -388,9 +749,9 @@ function splitOptions(argv) {
388
749
  continue;
389
750
  }
390
751
  if (tok === "--out") {
391
- const v = argv[i + 1];
392
- if (!v) throw new FlagParseException("--out requires a path");
393
- outPath = v;
752
+ const v2 = argv[i + 1];
753
+ if (!v2) throw new FlagParseException("--out requires a path");
754
+ outPath = v2;
394
755
  i += 1;
395
756
  continue;
396
757
  }
@@ -403,13 +764,13 @@ function splitOptions(argv) {
403
764
  return { json, outPath, argvForFlags: rest };
404
765
  }
405
766
  async function readStdin() {
406
- return new Promise((resolve2, reject) => {
767
+ return new Promise((resolve3, reject) => {
407
768
  let data = "";
408
769
  process.stdin.setEncoding("utf8");
409
770
  process.stdin.on("data", (chunk) => {
410
771
  data += chunk;
411
772
  });
412
- process.stdin.on("end", () => resolve2(data));
773
+ process.stdin.on("end", () => resolve3(data));
413
774
  process.stdin.on("error", reject);
414
775
  });
415
776
  }
@@ -437,7 +798,7 @@ async function fetchImageToFile(result, outPath) {
437
798
  const res = await fetch(url);
438
799
  if (!res.ok) throw new Error(`Failed to download image: ${res.status} ${res.statusText}`);
439
800
  const buf = Buffer.from(await res.arrayBuffer());
440
- fs2.mkdirSync(path2.dirname(path2.resolve(outPath)), { recursive: true });
801
+ fs2.mkdirSync(path3.dirname(path3.resolve(outPath)), { recursive: true });
441
802
  fs2.writeFileSync(outPath, buf);
442
803
  }
443
804
  function renderResult(result, outputHint, json) {
@@ -507,8 +868,8 @@ Examples:
507
868
  process.exit(2);
508
869
  }
509
870
  }
510
- for (const [k, v] of Object.entries(parsed.args)) {
511
- payload[k] = v;
871
+ for (const [k2, v2] of Object.entries(parsed.args)) {
872
+ payload[k2] = v2;
512
873
  }
513
874
  let result;
514
875
  let note;
@@ -554,8 +915,8 @@ async function tools(argv, options) {
554
915
  console.log("(no tools registered)");
555
916
  return;
556
917
  }
557
- const sorted = [...list].sort((a, b) => a.name.localeCompare(b.name));
558
- const maxName = sorted.reduce((m, t) => Math.max(m, t.name.length), 0);
918
+ const sorted = [...list].sort((a, b2) => a.name.localeCompare(b2.name));
919
+ const maxName = sorted.reduce((m2, t) => Math.max(m2, t.name.length), 0);
559
920
  for (const t of sorted) {
560
921
  const summary = summarize(t.description);
561
922
  console.log(` ${t.name.padEnd(maxName, " ")} ${summary}`);
@@ -614,12 +975,12 @@ Options:
614
975
 
615
976
  // ../argent-cli/src/server.ts
616
977
  import * as fs3 from "node:fs";
617
- import * as path3 from "node:path";
618
- import { homedir as homedir2 } from "node:os";
978
+ import * as path4 from "node:path";
979
+ import { homedir as homedir3, networkInterfaces } from "node:os";
619
980
  import { spawn as spawn2 } from "node:child_process";
620
- var STATE_DIR2 = path3.join(homedir2(), ".argent");
621
- var STATE_FILE2 = path3.join(STATE_DIR2, "tool-server.json");
622
- var LOG_FILE2 = path3.join(STATE_DIR2, "tool-server.log");
981
+ var STATE_DIR2 = path4.join(homedir3(), ".argent");
982
+ var STATE_FILE2 = path4.join(STATE_DIR2, "tool-server.json");
983
+ var LOG_FILE2 = path4.join(STATE_DIR2, "tool-server.log");
623
984
  function readState2() {
624
985
  try {
625
986
  return JSON.parse(fs3.readFileSync(STATE_FILE2, "utf8"));
@@ -627,26 +988,6 @@ function readState2() {
627
988
  return null;
628
989
  }
629
990
  }
630
- function isProcessAlive2(pid) {
631
- try {
632
- process.kill(pid, 0);
633
- return true;
634
- } catch {
635
- return false;
636
- }
637
- }
638
- async function isHealthy2(port, timeoutMs = 2e3) {
639
- const controller = new AbortController();
640
- const timer = setTimeout(() => controller.abort(), timeoutMs);
641
- try {
642
- const res = await fetch(`http://127.0.0.1:${port}/tools`, { signal: controller.signal });
643
- return res.ok;
644
- } catch {
645
- return false;
646
- } finally {
647
- clearTimeout(timer);
648
- }
649
- }
650
991
  async function statusCmd(json) {
651
992
  const state = readState2();
652
993
  if (!state) {
@@ -657,14 +998,22 @@ async function statusCmd(json) {
657
998
  }
658
999
  return;
659
1000
  }
660
- const alive = isProcessAlive2(state.pid);
661
- const healthy = alive ? await isHealthy2(state.port) : false;
1001
+ const host = state.host ?? "127.0.0.1";
1002
+ const alive = isToolsServerProcessAlive(state.pid);
1003
+ const healthy = alive ? await isToolsServerHealthy(state.port, host, 2e3, state.token) : false;
662
1004
  if (json) {
663
- console.log(JSON.stringify({ running: alive && healthy, ...state, alive, healthy }, null, 2));
1005
+ const { token, ...publicState } = state;
1006
+ console.log(
1007
+ JSON.stringify(
1008
+ { running: alive && healthy, ...publicState, hasToken: !!token, alive, healthy },
1009
+ null,
1010
+ 2
1011
+ )
1012
+ );
664
1013
  return;
665
1014
  }
666
1015
  console.log(`tool-server:`);
667
- console.log(` url: http://127.0.0.1:${state.port}`);
1016
+ console.log(` url: ${formatUrl(host, state.port)}`);
668
1017
  console.log(` pid: ${state.pid}`);
669
1018
  console.log(` startedAt: ${state.startedAt}`);
670
1019
  console.log(` process: ${alive ? "alive" : "dead"}`);
@@ -695,12 +1044,312 @@ function logsCmd(follow) {
695
1044
  const child = spawn2("tail", ["-f", LOG_FILE2], { stdio: "inherit" });
696
1045
  child.on("exit", (code) => process.exit(code ?? 0));
697
1046
  }
698
- async function server(argv) {
1047
+ var StartFlagError = class extends Error {
1048
+ };
1049
+ function parseStartFlags(argv) {
1050
+ const flags2 = {
1051
+ port: null,
1052
+ host: "127.0.0.1",
1053
+ idleTimeoutMinutes: 0,
1054
+ detach: false,
1055
+ force: false,
1056
+ noAuth: false,
1057
+ help: false
1058
+ };
1059
+ for (let i = 0; i < argv.length; i++) {
1060
+ const tok = argv[i];
1061
+ const takeValue = (name) => {
1062
+ const v2 = argv[i + 1];
1063
+ if (v2 === void 0) throw new StartFlagError(`${name} requires a value`);
1064
+ i += 1;
1065
+ return v2;
1066
+ };
1067
+ if (tok === "--help" || tok === "-h") {
1068
+ flags2.help = true;
1069
+ continue;
1070
+ }
1071
+ if (tok === "--detach" || tok === "-d") {
1072
+ flags2.detach = true;
1073
+ continue;
1074
+ }
1075
+ if (tok === "--force") {
1076
+ flags2.force = true;
1077
+ continue;
1078
+ }
1079
+ if (tok === "--no-auth") {
1080
+ flags2.noAuth = true;
1081
+ continue;
1082
+ }
1083
+ if (tok === "--port" || tok === "-p") {
1084
+ flags2.port = parsePort(takeValue("--port"));
1085
+ continue;
1086
+ }
1087
+ if (tok.startsWith("--port=")) {
1088
+ flags2.port = parsePort(tok.slice("--port=".length));
1089
+ continue;
1090
+ }
1091
+ if (tok === "--host") {
1092
+ flags2.host = takeValue("--host");
1093
+ continue;
1094
+ }
1095
+ if (tok.startsWith("--host=")) {
1096
+ flags2.host = tok.slice("--host=".length);
1097
+ continue;
1098
+ }
1099
+ if (tok === "--idle-timeout") {
1100
+ flags2.idleTimeoutMinutes = parseIdle(takeValue("--idle-timeout"));
1101
+ continue;
1102
+ }
1103
+ if (tok.startsWith("--idle-timeout=")) {
1104
+ flags2.idleTimeoutMinutes = parseIdle(tok.slice("--idle-timeout=".length));
1105
+ continue;
1106
+ }
1107
+ throw new StartFlagError(`Unknown flag: ${tok}`);
1108
+ }
1109
+ return flags2;
1110
+ }
1111
+ var NON_NEGATIVE_INT = /^\d+$/;
1112
+ function parsePort(raw) {
1113
+ if (!NON_NEGATIVE_INT.test(raw) || Number(raw) > 65535) {
1114
+ throw new StartFlagError(`--port must be an integer 0..65535, got "${raw}"`);
1115
+ }
1116
+ return Number(raw);
1117
+ }
1118
+ function parseIdle(raw) {
1119
+ if (!NON_NEGATIVE_INT.test(raw)) {
1120
+ throw new StartFlagError(`--idle-timeout must be a non-negative integer, got "${raw}"`);
1121
+ }
1122
+ return Number(raw);
1123
+ }
1124
+ function printStartHelp() {
1125
+ console.log(`Usage: argent server start [flags]
1126
+
1127
+ Spawn a long-lived tool-server. Foreground by default so process supervisors
1128
+ (systemd, Docker, supervisord) can own the lifecycle.
1129
+
1130
+ Flags:
1131
+ --port, -p <n> Bind to port <n> (0 = pick a free port). Default: 3001
1132
+ --host <h> Bind address. Default: 127.0.0.1
1133
+ Use 0.0.0.0 to expose on every interface.
1134
+ --idle-timeout <m> Auto-shutdown after <m> idle minutes (0 disables).
1135
+ Default: 0 (never auto-shutdown).
1136
+ --detach, -d Run as a detached background process and return.
1137
+ --force If a tool-server is already running, kill it first.
1138
+ --no-auth Disable authentication (no token). Anyone who can
1139
+ reach the port can drive the server. Dev/trusted only.
1140
+ --help, -h Show this help.
1141
+
1142
+ Auth:
1143
+ By default the server mints a bearer token and prints a one-line connection
1144
+ string. Pair a client by pasting it into \`argent link\`:
1145
+ argent link argent://<token>@<host>:<port>
1146
+ Pass --no-auth to run without a token (unauthenticated).
1147
+
1148
+ Examples:
1149
+ argent server start
1150
+ argent server start --port 4000
1151
+ argent server start --host 0.0.0.0 --port 4000
1152
+ argent server start --detach
1153
+ argent server start --host 0.0.0.0 --no-auth
1154
+ `);
1155
+ }
1156
+ function isLoopback(host) {
1157
+ return host === "127.0.0.1" || host === "localhost" || host === "::1";
1158
+ }
1159
+ function isWildcard(host) {
1160
+ return host === "0.0.0.0" || host === "::" || host === "::0" || host === "";
1161
+ }
1162
+ function primaryLanIPv4() {
1163
+ const ifaces = networkInterfaces();
1164
+ for (const addrs of Object.values(ifaces)) {
1165
+ for (const ni of addrs ?? []) {
1166
+ if (ni.family === "IPv4" && !ni.internal) return ni.address;
1167
+ }
1168
+ }
1169
+ return null;
1170
+ }
1171
+ function resolveConnectHost(bindHost) {
1172
+ if (isWildcard(bindHost)) return primaryLanIPv4() ?? "127.0.0.1";
1173
+ return bindHost;
1174
+ }
1175
+ function printConnectionInfo(bindHost, port, token) {
1176
+ const connectHost = resolveConnectHost(bindHost);
1177
+ console.log("");
1178
+ console.log(" Connect a client:");
1179
+ console.log(` argent link ${formatLinkUrl({ host: connectHost, port, token })}`);
1180
+ const flagsForm = token ? `argent link --host ${connectHost} --port ${port} --token ${token}` : `argent link --host ${connectHost} --port ${port}`;
1181
+ console.log(` (or: ${flagsForm})${token ? "" : " [unauthenticated]"}`);
1182
+ if (isWildcard(bindHost)) {
1183
+ console.log(
1184
+ ` note: bound to ${bindHost}; ${connectHost} is a best guess \u2014 replace it with the address clients actually reach this machine on.`
1185
+ );
1186
+ }
1187
+ }
1188
+ async function ensureNoExistingServer(force) {
1189
+ const state = await readToolsServerState();
1190
+ if (!state) return;
1191
+ const alive = isToolsServerProcessAlive(state.pid);
1192
+ const healthy = alive ? await isToolsServerHealthy(state.port, state.host ?? "127.0.0.1") : false;
1193
+ if (alive && healthy && !force) {
1194
+ const url = formatUrl(state.host ?? "127.0.0.1", state.port);
1195
+ throw new StartFlagError(
1196
+ `tool-server is already running at ${url} (pid ${state.pid}).
1197
+ Use \`argent server stop\` first, or pass \`--force\` to replace it.`
1198
+ );
1199
+ }
1200
+ if (alive && force) {
1201
+ await killToolServer();
1202
+ } else {
1203
+ await clearToolsServerState();
1204
+ }
1205
+ }
1206
+ async function resolvePort(requested) {
1207
+ if (requested === null) return 3001;
1208
+ if (requested === 0) return findFreePort();
1209
+ return requested;
1210
+ }
1211
+ async function startCmd(argv, paths) {
1212
+ if (!paths) {
1213
+ console.error("argent server start: bundled runtime paths missing \u2014 this build is incomplete.");
1214
+ process.exit(1);
1215
+ }
1216
+ let flags2;
1217
+ try {
1218
+ flags2 = parseStartFlags(argv);
1219
+ } catch (err) {
1220
+ if (err instanceof StartFlagError) {
1221
+ console.error(`Error: ${err.message}
1222
+ `);
1223
+ printStartHelp();
1224
+ process.exit(2);
1225
+ }
1226
+ throw err;
1227
+ }
1228
+ if (flags2.help) {
1229
+ printStartHelp();
1230
+ return;
1231
+ }
1232
+ try {
1233
+ await ensureNoExistingServer(flags2.force);
1234
+ } catch (err) {
1235
+ if (err instanceof StartFlagError) {
1236
+ console.error(err.message);
1237
+ process.exit(1);
1238
+ }
1239
+ throw err;
1240
+ }
1241
+ const port = await resolvePort(flags2.port);
1242
+ const token = flags2.noAuth ? void 0 : generateAuthToken();
1243
+ if (!isLoopback(flags2.host)) {
1244
+ if (token) {
1245
+ process.stderr.write(
1246
+ `Note: tool-server will be reachable on ${flags2.host}:${port} over plain HTTP (bearer-token auth, no TLS). Keep it to a trusted network or VPN.
1247
+ `
1248
+ );
1249
+ } else {
1250
+ process.stderr.write(
1251
+ `WARNING: tool-server will be reachable on ${flags2.host}:${port} with NO auth (--no-auth) \u2014 anyone who can reach the port can drive it. Do not expose to untrusted networks.
1252
+ `
1253
+ );
1254
+ }
1255
+ }
1256
+ if (flags2.detach) {
1257
+ await runDetached(paths, port, flags2.host, flags2.idleTimeoutMinutes, token);
1258
+ return;
1259
+ }
1260
+ await runForeground(paths, port, flags2.host, flags2.idleTimeoutMinutes, token);
1261
+ }
1262
+ async function runDetached(paths, port, host, idleTimeoutMinutes, token) {
1263
+ const { port: actualPort, pid } = await spawnToolsServer(paths, port, {
1264
+ host,
1265
+ idleTimeoutMinutes,
1266
+ token
1267
+ });
1268
+ await writeToolsServerState({
1269
+ port: actualPort,
1270
+ pid,
1271
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
1272
+ bundlePath: paths.bundlePath,
1273
+ host,
1274
+ ...token ? { token } : {}
1275
+ });
1276
+ const url = formatUrl(host, actualPort);
1277
+ console.log(`tool-server started: ${url} (pid ${pid})`);
1278
+ printConnectionInfo(host, actualPort, token);
1279
+ console.log("");
1280
+ console.log(` logs: ${LOG_FILE2}`);
1281
+ console.log(` status: argent server status`);
1282
+ console.log(` stop: argent server stop`);
1283
+ }
1284
+ async function runForeground(paths, port, host, idleTimeoutMinutes, token) {
1285
+ const env = buildToolsServerEnv(paths, port, process.env, {
1286
+ host,
1287
+ idleTimeoutMinutes,
1288
+ token
1289
+ });
1290
+ const child = spawn2("node", [paths.bundlePath, "start"], {
1291
+ stdio: "inherit",
1292
+ env
1293
+ });
1294
+ const forward = (signal) => () => {
1295
+ try {
1296
+ child.kill(signal);
1297
+ } catch {
1298
+ }
1299
+ };
1300
+ const onInt = forward("SIGINT");
1301
+ const onTerm = forward("SIGTERM");
1302
+ process.on("SIGINT", onInt);
1303
+ process.on("SIGTERM", onTerm);
1304
+ let stateWritten = false;
1305
+ const childPid = child.pid;
1306
+ if (childPid !== void 0) {
1307
+ try {
1308
+ writeToolsServerStateSync({
1309
+ port,
1310
+ pid: childPid,
1311
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
1312
+ bundlePath: paths.bundlePath,
1313
+ host,
1314
+ ...token ? { token } : {}
1315
+ });
1316
+ stateWritten = true;
1317
+ } catch {
1318
+ }
1319
+ }
1320
+ printConnectionInfo(host, port, token);
1321
+ await new Promise(() => {
1322
+ const cleanup = () => {
1323
+ process.removeListener("SIGINT", onInt);
1324
+ process.removeListener("SIGTERM", onTerm);
1325
+ if (stateWritten) {
1326
+ clearToolsServerState().catch(() => {
1327
+ });
1328
+ }
1329
+ };
1330
+ child.on("error", (err) => {
1331
+ cleanup();
1332
+ console.error(`argent server start: failed to spawn tool-server: ${err.message}`);
1333
+ process.exit(1);
1334
+ });
1335
+ child.on("exit", (code, signal) => {
1336
+ cleanup();
1337
+ const exitCode = code ?? (signal ? 128 + (signalNumber(signal) ?? 0) : 0);
1338
+ process.exit(exitCode);
1339
+ });
1340
+ });
1341
+ }
1342
+ function signalNumber(signal) {
1343
+ const map = { SIGINT: 2, SIGTERM: 15, SIGHUP: 1, SIGKILL: 9 };
1344
+ return map[signal] ?? null;
1345
+ }
1346
+ async function server(argv, options) {
699
1347
  const sub = argv[0];
700
1348
  const json = argv.includes("--json");
701
1349
  const follow = argv.includes("-f") || argv.includes("--follow");
702
1350
  if (!sub || sub === "--help" || sub === "-h") {
703
1351
  console.log(`Usage:
1352
+ argent server start [flags] Spawn a long-lived tool-server (see --help)
704
1353
  argent server status [--json] Show tool-server pid, port, and health
705
1354
  argent server stop Terminate the running tool-server
706
1355
  argent server logs [-f] Print (or follow) the tool-server log
@@ -708,6 +1357,9 @@ async function server(argv) {
708
1357
  return;
709
1358
  }
710
1359
  switch (sub) {
1360
+ case "start":
1361
+ await startCmd(argv.slice(1), options?.paths);
1362
+ return;
711
1363
  case "status":
712
1364
  await statusCmd(json);
713
1365
  return;
@@ -722,8 +1374,1644 @@ async function server(argv) {
722
1374
  process.exit(1);
723
1375
  }
724
1376
  }
1377
+
1378
+ // ../../node_modules/@clack/core/dist/index.mjs
1379
+ import { styleText as v } from "node:util";
1380
+ import { stdout as x, stdin as D } from "node:process";
1381
+ import * as b from "node:readline";
1382
+ import E from "node:readline";
1383
+
1384
+ // ../../node_modules/fast-string-truncated-width/dist/utils.js
1385
+ var getCodePointsLength = /* @__PURE__ */ (() => {
1386
+ const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
1387
+ return (input) => {
1388
+ let surrogatePairsNr = 0;
1389
+ SURROGATE_PAIR_RE.lastIndex = 0;
1390
+ while (SURROGATE_PAIR_RE.test(input)) {
1391
+ surrogatePairsNr += 1;
1392
+ }
1393
+ return input.length - surrogatePairsNr;
1394
+ };
1395
+ })();
1396
+ var isFullWidth = (x3) => {
1397
+ return x3 === 12288 || x3 >= 65281 && x3 <= 65376 || x3 >= 65504 && x3 <= 65510;
1398
+ };
1399
+ var isWideNotCJKTNotEmoji = (x3) => {
1400
+ return x3 === 8987 || x3 === 9001 || x3 >= 12272 && x3 <= 12287 || x3 >= 12289 && x3 <= 12350 || x3 >= 12441 && x3 <= 12543 || x3 >= 12549 && x3 <= 12591 || x3 >= 12593 && x3 <= 12686 || x3 >= 12688 && x3 <= 12771 || x3 >= 12783 && x3 <= 12830 || x3 >= 12832 && x3 <= 12871 || x3 >= 12880 && x3 <= 19903 || x3 >= 65040 && x3 <= 65049 || x3 >= 65072 && x3 <= 65106 || x3 >= 65108 && x3 <= 65126 || x3 >= 65128 && x3 <= 65131 || x3 >= 127488 && x3 <= 127490 || x3 >= 127504 && x3 <= 127547 || x3 >= 127552 && x3 <= 127560 || x3 >= 131072 && x3 <= 196605 || x3 >= 196608 && x3 <= 262141;
1401
+ };
1402
+
1403
+ // ../../node_modules/fast-string-truncated-width/dist/index.js
1404
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
1405
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
1406
+ var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
1407
+ var TAB_RE = /\t{1,1000}/y;
1408
+ var EMOJI_RE = new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*", "yu");
1409
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
1410
+ var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
1411
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
1412
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
1413
+ const LIMIT = truncationOptions.limit ?? Infinity;
1414
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
1415
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
1416
+ const ANSI_WIDTH = 0;
1417
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
1418
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
1419
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
1420
+ const FULL_WIDTH_WIDTH = 2;
1421
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
1422
+ const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
1423
+ const PARSE_BLOCKS = [
1424
+ [LATIN_RE, REGULAR_WIDTH],
1425
+ [ANSI_RE, ANSI_WIDTH],
1426
+ [CONTROL_RE, CONTROL_WIDTH],
1427
+ [TAB_RE, TAB_WIDTH],
1428
+ [EMOJI_RE, EMOJI_WIDTH],
1429
+ [CJKT_WIDE_RE, WIDE_WIDTH]
1430
+ ];
1431
+ let indexPrev = 0;
1432
+ let index = 0;
1433
+ let length = input.length;
1434
+ let lengthExtra = 0;
1435
+ let truncationEnabled = false;
1436
+ let truncationIndex = length;
1437
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
1438
+ let unmatchedStart = 0;
1439
+ let unmatchedEnd = 0;
1440
+ let width = 0;
1441
+ let widthExtra = 0;
1442
+ outer: while (true) {
1443
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
1444
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
1445
+ lengthExtra = 0;
1446
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
1447
+ const codePoint = char.codePointAt(0) || 0;
1448
+ if (isFullWidth(codePoint)) {
1449
+ widthExtra = FULL_WIDTH_WIDTH;
1450
+ } else if (isWideNotCJKTNotEmoji(codePoint)) {
1451
+ widthExtra = WIDE_WIDTH;
1452
+ } else {
1453
+ widthExtra = REGULAR_WIDTH;
1454
+ }
1455
+ if (width + widthExtra > truncationLimit) {
1456
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
1457
+ }
1458
+ if (width + widthExtra > LIMIT) {
1459
+ truncationEnabled = true;
1460
+ break outer;
1461
+ }
1462
+ lengthExtra += char.length;
1463
+ width += widthExtra;
1464
+ }
1465
+ unmatchedStart = unmatchedEnd = 0;
1466
+ }
1467
+ if (index >= length) {
1468
+ break outer;
1469
+ }
1470
+ for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
1471
+ const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
1472
+ BLOCK_RE.lastIndex = index;
1473
+ if (BLOCK_RE.test(input)) {
1474
+ lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
1475
+ widthExtra = lengthExtra * BLOCK_WIDTH;
1476
+ if (width + widthExtra > truncationLimit) {
1477
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
1478
+ }
1479
+ if (width + widthExtra > LIMIT) {
1480
+ truncationEnabled = true;
1481
+ break outer;
1482
+ }
1483
+ width += widthExtra;
1484
+ unmatchedStart = indexPrev;
1485
+ unmatchedEnd = index;
1486
+ index = indexPrev = BLOCK_RE.lastIndex;
1487
+ continue outer;
1488
+ }
1489
+ }
1490
+ index += 1;
1491
+ }
1492
+ return {
1493
+ width: truncationEnabled ? truncationLimit : width,
1494
+ index: truncationEnabled ? truncationIndex : length,
1495
+ truncated: truncationEnabled,
1496
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
1497
+ };
1498
+ };
1499
+ var dist_default = getStringTruncatedWidth;
1500
+
1501
+ // ../../node_modules/fast-string-width/dist/index.js
1502
+ var NO_TRUNCATION2 = {
1503
+ limit: Infinity,
1504
+ ellipsis: "",
1505
+ ellipsisWidth: 0
1506
+ };
1507
+ var fastStringWidth = (input, options = {}) => {
1508
+ return dist_default(input, NO_TRUNCATION2, options).width;
1509
+ };
1510
+ var dist_default2 = fastStringWidth;
1511
+
1512
+ // ../../node_modules/fast-wrap-ansi/lib/main.js
1513
+ var ESC = "\x1B";
1514
+ var CSI = "\x9B";
1515
+ var END_CODE = 39;
1516
+ var ANSI_ESCAPE_BELL = "\x07";
1517
+ var ANSI_CSI = "[";
1518
+ var ANSI_OSC = "]";
1519
+ var ANSI_SGR_TERMINATOR = "m";
1520
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
1521
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
1522
+ var getClosingCode = (openingCode) => {
1523
+ if (openingCode >= 30 && openingCode <= 37)
1524
+ return 39;
1525
+ if (openingCode >= 90 && openingCode <= 97)
1526
+ return 39;
1527
+ if (openingCode >= 40 && openingCode <= 47)
1528
+ return 49;
1529
+ if (openingCode >= 100 && openingCode <= 107)
1530
+ return 49;
1531
+ if (openingCode === 1 || openingCode === 2)
1532
+ return 22;
1533
+ if (openingCode === 3)
1534
+ return 23;
1535
+ if (openingCode === 4)
1536
+ return 24;
1537
+ if (openingCode === 7)
1538
+ return 27;
1539
+ if (openingCode === 8)
1540
+ return 28;
1541
+ if (openingCode === 9)
1542
+ return 29;
1543
+ if (openingCode === 0)
1544
+ return 0;
1545
+ return void 0;
1546
+ };
1547
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
1548
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
1549
+ var wrapWord = (rows, word, columns) => {
1550
+ const characters = word[Symbol.iterator]();
1551
+ let isInsideEscape = false;
1552
+ let isInsideLinkEscape = false;
1553
+ let lastRow = rows.at(-1);
1554
+ let visible = lastRow === void 0 ? 0 : dist_default2(lastRow);
1555
+ let currentCharacter = characters.next();
1556
+ let nextCharacter = characters.next();
1557
+ let rawCharacterIndex = 0;
1558
+ while (!currentCharacter.done) {
1559
+ const character = currentCharacter.value;
1560
+ const characterLength = dist_default2(character);
1561
+ if (visible + characterLength <= columns) {
1562
+ rows[rows.length - 1] += character;
1563
+ } else {
1564
+ rows.push(character);
1565
+ visible = 0;
1566
+ }
1567
+ if (character === ESC || character === CSI) {
1568
+ isInsideEscape = true;
1569
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
1570
+ }
1571
+ if (isInsideEscape) {
1572
+ if (isInsideLinkEscape) {
1573
+ if (character === ANSI_ESCAPE_BELL) {
1574
+ isInsideEscape = false;
1575
+ isInsideLinkEscape = false;
1576
+ }
1577
+ } else if (character === ANSI_SGR_TERMINATOR) {
1578
+ isInsideEscape = false;
1579
+ }
1580
+ } else {
1581
+ visible += characterLength;
1582
+ if (visible === columns && !nextCharacter.done) {
1583
+ rows.push("");
1584
+ visible = 0;
1585
+ }
1586
+ }
1587
+ currentCharacter = nextCharacter;
1588
+ nextCharacter = characters.next();
1589
+ rawCharacterIndex += character.length;
1590
+ }
1591
+ lastRow = rows.at(-1);
1592
+ if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
1593
+ rows[rows.length - 2] += rows.pop();
1594
+ }
1595
+ };
1596
+ var stringVisibleTrimSpacesRight = (string) => {
1597
+ const words = string.split(" ");
1598
+ let last = words.length;
1599
+ while (last) {
1600
+ if (dist_default2(words[last - 1])) {
1601
+ break;
1602
+ }
1603
+ last--;
1604
+ }
1605
+ if (last === words.length) {
1606
+ return string;
1607
+ }
1608
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
1609
+ };
1610
+ var exec = (string, columns, options = {}) => {
1611
+ if (options.trim !== false && string.trim() === "") {
1612
+ return "";
1613
+ }
1614
+ let returnValue = "";
1615
+ let escapeCode;
1616
+ let escapeUrl;
1617
+ const words = string.split(" ");
1618
+ let rows = [""];
1619
+ let rowLength = 0;
1620
+ for (let index = 0; index < words.length; index++) {
1621
+ const word = words[index];
1622
+ if (options.trim !== false) {
1623
+ const row = rows.at(-1) ?? "";
1624
+ const trimmed = row.trimStart();
1625
+ if (row.length !== trimmed.length) {
1626
+ rows[rows.length - 1] = trimmed;
1627
+ rowLength = dist_default2(trimmed);
1628
+ }
1629
+ }
1630
+ if (index !== 0) {
1631
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
1632
+ rows.push("");
1633
+ rowLength = 0;
1634
+ }
1635
+ if (rowLength || options.trim === false) {
1636
+ rows[rows.length - 1] += " ";
1637
+ rowLength++;
1638
+ }
1639
+ }
1640
+ const wordLength = dist_default2(word);
1641
+ if (options.hard && wordLength > columns) {
1642
+ const remainingColumns = columns - rowLength;
1643
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
1644
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
1645
+ if (breaksStartingNextLine < breaksStartingThisLine) {
1646
+ rows.push("");
1647
+ }
1648
+ wrapWord(rows, word, columns);
1649
+ rowLength = dist_default2(rows.at(-1) ?? "");
1650
+ continue;
1651
+ }
1652
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
1653
+ if (options.wordWrap === false && rowLength < columns) {
1654
+ wrapWord(rows, word, columns);
1655
+ rowLength = dist_default2(rows.at(-1) ?? "");
1656
+ continue;
1657
+ }
1658
+ rows.push("");
1659
+ rowLength = 0;
1660
+ }
1661
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
1662
+ wrapWord(rows, word, columns);
1663
+ rowLength = dist_default2(rows.at(-1) ?? "");
1664
+ continue;
1665
+ }
1666
+ rows[rows.length - 1] += word;
1667
+ rowLength += wordLength;
1668
+ }
1669
+ if (options.trim !== false) {
1670
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
1671
+ }
1672
+ const preString = rows.join("\n");
1673
+ let inSurrogate = false;
1674
+ for (let i = 0; i < preString.length; i++) {
1675
+ const character = preString[i];
1676
+ returnValue += character;
1677
+ if (!inSurrogate) {
1678
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
1679
+ if (inSurrogate) {
1680
+ continue;
1681
+ }
1682
+ } else {
1683
+ inSurrogate = false;
1684
+ }
1685
+ if (character === ESC || character === CSI) {
1686
+ GROUP_REGEX.lastIndex = i + 1;
1687
+ const groupsResult = GROUP_REGEX.exec(preString);
1688
+ const groups = groupsResult?.groups;
1689
+ if (groups?.code !== void 0) {
1690
+ const code = Number.parseFloat(groups.code);
1691
+ escapeCode = code === END_CODE ? void 0 : code;
1692
+ } else if (groups?.uri !== void 0) {
1693
+ escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
1694
+ }
1695
+ }
1696
+ if (preString[i + 1] === "\n") {
1697
+ if (escapeUrl) {
1698
+ returnValue += wrapAnsiHyperlink("");
1699
+ }
1700
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
1701
+ if (escapeCode && closingCode) {
1702
+ returnValue += wrapAnsiCode(closingCode);
1703
+ }
1704
+ } else if (character === "\n") {
1705
+ if (escapeCode && getClosingCode(escapeCode)) {
1706
+ returnValue += wrapAnsiCode(escapeCode);
1707
+ }
1708
+ if (escapeUrl) {
1709
+ returnValue += wrapAnsiHyperlink(escapeUrl);
1710
+ }
1711
+ }
1712
+ }
1713
+ return returnValue;
1714
+ };
1715
+ var CRLF_OR_LF = /\r?\n/;
1716
+ function wrapAnsi(string, columns, options) {
1717
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
1718
+ }
1719
+
1720
+ // ../../node_modules/@clack/core/dist/index.mjs
1721
+ var import_sisteransi = __toESM(require_src(), 1);
1722
+ import { ReadStream as O } from "node:tty";
1723
+ function f(r, t, s) {
1724
+ if (!s.some((o) => !o.disabled)) return r;
1725
+ const e2 = r + t, i = Math.max(s.length - 1, 0), n = e2 < 0 ? i : e2 > i ? 0 : e2;
1726
+ return s[n].disabled ? f(n, t < 0 ? -1 : 1, s) : n;
1727
+ }
1728
+ var G = ["up", "down", "left", "right", "space", "enter", "cancel"];
1729
+ var K = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
1730
+ var h = { actions: new Set(G), aliases: /* @__PURE__ */ new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["", "cancel"], ["escape", "cancel"]]), messages: { cancel: "Canceled", error: "Something went wrong" }, withGuide: true, date: { monthNames: [...K], messages: { required: "Please enter a valid date", invalidMonth: "There are only 12 months in a year", invalidDay: (r, t) => `There are only ${r} days in ${t}`, afterMin: (r) => `Date must be on or after ${r.toISOString().slice(0, 10)}`, beforeMax: (r) => `Date must be on or before ${r.toISOString().slice(0, 10)}` } } };
1731
+ function C(r, t) {
1732
+ if (typeof r == "string") return h.aliases.get(r) === t;
1733
+ for (const s of r) if (s !== void 0 && C(s, t)) return true;
1734
+ return false;
1735
+ }
1736
+ function z(r, t) {
1737
+ if (r === t) return;
1738
+ const s = r.split(`
1739
+ `), e2 = t.split(`
1740
+ `), i = Math.max(s.length, e2.length), n = [];
1741
+ for (let o = 0; o < i; o++) s[o] !== e2[o] && n.push(o);
1742
+ return { lines: n, numLinesBefore: s.length, numLinesAfter: e2.length, numLines: i };
1743
+ }
1744
+ var Y = globalThis.process.platform.startsWith("win");
1745
+ var k = /* @__PURE__ */ Symbol("clack:cancel");
1746
+ function q(r) {
1747
+ return r === k;
1748
+ }
1749
+ function w(r, t) {
1750
+ const s = r;
1751
+ s.isTTY && s.setRawMode(t);
1752
+ }
1753
+ function R({ input: r = D, output: t = x, overwrite: s = true, hideCursor: e2 = true } = {}) {
1754
+ const i = b.createInterface({ input: r, output: t, prompt: "", tabSize: 1 });
1755
+ b.emitKeypressEvents(r, i), r instanceof O && r.isTTY && r.setRawMode(true);
1756
+ const n = (o, { name: u, sequence: a }) => {
1757
+ const l = String(o);
1758
+ if (C([l, u, a], "cancel")) {
1759
+ e2 && t.write(import_sisteransi.cursor.show), process.exit(0);
1760
+ return;
1761
+ }
1762
+ if (!s) return;
1763
+ const c = u === "return" ? 0 : -1, y = u === "return" ? -1 : 0;
1764
+ b.moveCursor(t, c, y, () => {
1765
+ b.clearLine(t, 1, () => {
1766
+ r.once("keypress", n);
1767
+ });
1768
+ });
1769
+ };
1770
+ return e2 && t.write(import_sisteransi.cursor.hide), r.once("keypress", n), () => {
1771
+ r.off("keypress", n), e2 && t.write(import_sisteransi.cursor.show), r instanceof O && r.isTTY && !Y && r.setRawMode(false), i.terminal = false, i.close();
1772
+ };
1773
+ }
1774
+ var A = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80;
1775
+ var L = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
1776
+ function W(r, t, s, e2 = s, i = s, n) {
1777
+ const o = A(r ?? x);
1778
+ return wrapAnsi(t, o - s.length, { hard: true, trim: false }).split(`
1779
+ `).map((u, a, l) => {
1780
+ const c = n ? n(u, a) : u;
1781
+ return a === 0 ? `${e2}${c}` : a === l.length - 1 ? `${i}${c}` : `${s}${c}`;
1782
+ }).join(`
1783
+ `);
1784
+ }
1785
+ var m = class {
1786
+ input;
1787
+ output;
1788
+ _abortSignal;
1789
+ rl;
1790
+ opts;
1791
+ _render;
1792
+ _track = false;
1793
+ _prevFrame = "";
1794
+ _subscribers = /* @__PURE__ */ new Map();
1795
+ _cursor = 0;
1796
+ state = "initial";
1797
+ error = "";
1798
+ value;
1799
+ userInput = "";
1800
+ constructor(t, s = true) {
1801
+ const { input: e2 = D, output: i = x, render: n, signal: o, ...u } = t;
1802
+ this.opts = u, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = n.bind(this), this._track = s, this._abortSignal = o, this.input = e2, this.output = i;
1803
+ }
1804
+ unsubscribe() {
1805
+ this._subscribers.clear();
1806
+ }
1807
+ setSubscriber(t, s) {
1808
+ const e2 = this._subscribers.get(t) ?? [];
1809
+ e2.push(s), this._subscribers.set(t, e2);
1810
+ }
1811
+ on(t, s) {
1812
+ this.setSubscriber(t, { cb: s });
1813
+ }
1814
+ once(t, s) {
1815
+ this.setSubscriber(t, { cb: s, once: true });
1816
+ }
1817
+ emit(t, ...s) {
1818
+ const e2 = this._subscribers.get(t) ?? [], i = [];
1819
+ for (const n of e2) n.cb(...s), n.once && i.push(() => e2.splice(e2.indexOf(n), 1));
1820
+ for (const n of i) n();
1821
+ }
1822
+ prompt() {
1823
+ return new Promise((t) => {
1824
+ if (this._abortSignal) {
1825
+ if (this._abortSignal.aborted) return this.state = "cancel", this.close(), t(k);
1826
+ this._abortSignal.addEventListener("abort", () => {
1827
+ this.state = "cancel", this.close();
1828
+ }, { once: true });
1829
+ }
1830
+ this.rl = E.createInterface({ input: this.input, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), this.rl.prompt(), this.opts.initialUserInput !== void 0 && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), w(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
1831
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t(this.value);
1832
+ }), this.once("cancel", () => {
1833
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t(k);
1834
+ });
1835
+ });
1836
+ }
1837
+ _isActionKey(t, s) {
1838
+ return t === " ";
1839
+ }
1840
+ _shouldSubmit(t, s) {
1841
+ return true;
1842
+ }
1843
+ _setValue(t) {
1844
+ this.value = t, this.emit("value", this.value);
1845
+ }
1846
+ _setUserInput(t, s) {
1847
+ this.userInput = t ?? "", this.emit("userInput", this.userInput), s && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
1848
+ }
1849
+ _clearUserInput() {
1850
+ this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
1851
+ }
1852
+ onKeypress(t, s) {
1853
+ if (this._track && s.name !== "return" && (s.name && this._isActionKey(t, s) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), s?.name && (!this._track && h.aliases.has(s.name) && this.emit("cursor", h.aliases.get(s.name)), h.actions.has(s.name) && this.emit("cursor", s.name)), t && (t.toLowerCase() === "y" || t.toLowerCase() === "n") && this.emit("confirm", t.toLowerCase() === "y"), this.emit("key", t?.toLowerCase(), s), s?.name === "return" && this._shouldSubmit(t, s)) {
1854
+ if (this.opts.validate) {
1855
+ const e2 = this.opts.validate(this.value);
1856
+ e2 && (this.error = e2 instanceof Error ? e2.message : e2, this.state = "error", this.rl?.write(this.userInput));
1857
+ }
1858
+ this.state !== "error" && (this.state = "submit");
1859
+ }
1860
+ C([t, s?.name, s?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
1861
+ }
1862
+ close() {
1863
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
1864
+ `), w(this.input, false), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
1865
+ }
1866
+ restoreCursor() {
1867
+ const t = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
1868
+ `).length - 1;
1869
+ this.output.write(import_sisteransi.cursor.move(-999, t * -1));
1870
+ }
1871
+ render() {
1872
+ const t = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
1873
+ if (t !== this._prevFrame) {
1874
+ if (this.state === "initial") this.output.write(import_sisteransi.cursor.hide);
1875
+ else {
1876
+ const s = z(this._prevFrame, t), e2 = L(this.output);
1877
+ if (this.restoreCursor(), s) {
1878
+ const i = Math.max(0, s.numLinesAfter - e2), n = Math.max(0, s.numLinesBefore - e2);
1879
+ let o = s.lines.find((u) => u >= i);
1880
+ if (o === void 0) {
1881
+ this._prevFrame = t;
1882
+ return;
1883
+ }
1884
+ if (s.lines.length === 1) {
1885
+ this.output.write(import_sisteransi.cursor.move(0, o - n)), this.output.write(import_sisteransi.erase.lines(1));
1886
+ const u = t.split(`
1887
+ `);
1888
+ this.output.write(u[o]), this._prevFrame = t, this.output.write(import_sisteransi.cursor.move(0, u.length - o - 1));
1889
+ return;
1890
+ } else if (s.lines.length > 1) {
1891
+ if (i < n) o = i;
1892
+ else {
1893
+ const a = o - n;
1894
+ a > 0 && this.output.write(import_sisteransi.cursor.move(0, a));
1895
+ }
1896
+ this.output.write(import_sisteransi.erase.down());
1897
+ const u = t.split(`
1898
+ `).slice(o);
1899
+ this.output.write(u.join(`
1900
+ `)), this._prevFrame = t;
1901
+ return;
1902
+ }
1903
+ }
1904
+ this.output.write(import_sisteransi.erase.down());
1905
+ }
1906
+ this.output.write(t), this.state === "initial" && (this.state = "active"), this._prevFrame = t;
1907
+ }
1908
+ }
1909
+ };
1910
+ var X = class extends m {
1911
+ get cursor() {
1912
+ return this.value ? 0 : 1;
1913
+ }
1914
+ get _value() {
1915
+ return this.cursor === 0;
1916
+ }
1917
+ constructor(t) {
1918
+ super(t, false), this.value = !!t.initialValue, this.on("userInput", () => {
1919
+ this.value = this._value;
1920
+ }), this.on("confirm", (s) => {
1921
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
1922
+ }), this.on("cursor", () => {
1923
+ this.value = !this.value;
1924
+ });
1925
+ }
1926
+ };
1927
+ var ut = class extends m {
1928
+ options;
1929
+ cursor = 0;
1930
+ get _selectedValue() {
1931
+ return this.options[this.cursor];
1932
+ }
1933
+ changeValue() {
1934
+ this.value = this._selectedValue.value;
1935
+ }
1936
+ constructor(t) {
1937
+ super(t, false), this.options = t.options;
1938
+ const s = this.options.findIndex(({ value: i }) => i === t.initialValue), e2 = s === -1 ? 0 : s;
1939
+ this.cursor = this.options[e2].disabled ? f(e2, 1, this.options) : e2, this.changeValue(), this.on("cursor", (i) => {
1940
+ switch (i) {
1941
+ case "left":
1942
+ case "up":
1943
+ this.cursor = f(this.cursor, -1, this.options);
1944
+ break;
1945
+ case "down":
1946
+ case "right":
1947
+ this.cursor = f(this.cursor, 1, this.options);
1948
+ break;
1949
+ }
1950
+ this.changeValue();
1951
+ });
1952
+ }
1953
+ };
1954
+ var ht = class extends m {
1955
+ get userInputWithCursor() {
1956
+ if (this.state === "submit") return this.userInput;
1957
+ const t = this.userInput;
1958
+ if (this.cursor >= t.length) return `${this.userInput}\u2588`;
1959
+ const s = t.slice(0, this.cursor), [e2, ...i] = t.slice(this.cursor);
1960
+ return `${s}${v("inverse", e2)}${i.join("")}`;
1961
+ }
1962
+ get cursor() {
1963
+ return this._cursor;
1964
+ }
1965
+ constructor(t) {
1966
+ super({ ...t, initialUserInput: t.initialUserInput ?? t.initialValue }), this.on("userInput", (s) => {
1967
+ this._setValue(s);
1968
+ }), this.on("finalize", () => {
1969
+ this.value || (this.value = t.defaultValue), this.value === void 0 && (this.value = "");
1970
+ });
1971
+ }
1972
+ };
1973
+
1974
+ // ../../node_modules/@clack/prompts/dist/index.mjs
1975
+ import { styleText as e, stripVTControlCharacters as nt2 } from "node:util";
1976
+ import V2 from "node:process";
1977
+ var import_sisteransi2 = __toESM(require_src(), 1);
1978
+ import { existsSync as Qt, lstatSync as wt, readdirSync as Zt } from "node:fs";
1979
+ import { dirname as bt, join as te } from "node:path";
1980
+ function ee() {
1981
+ return V2.platform !== "win32" ? V2.env.TERM !== "linux" : !!V2.env.CI || !!V2.env.WT_SESSION || !!V2.env.TERMINUS_SUBLIME || V2.env.ConEmuTask === "{cmd::Cmder}" || V2.env.TERM_PROGRAM === "Terminus-Sublime" || V2.env.TERM_PROGRAM === "vscode" || V2.env.TERM === "xterm-256color" || V2.env.TERM === "alacritty" || V2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
1982
+ }
1983
+ var tt = ee();
1984
+ var ot2 = () => process.env.CI === "true";
1985
+ var w2 = (t, i) => tt ? t : i;
1986
+ var Tt = w2("\u25C6", "*");
1987
+ var at2 = w2("\u25A0", "x");
1988
+ var ut2 = w2("\u25B2", "x");
1989
+ var H = w2("\u25C7", "o");
1990
+ var lt = w2("\u250C", "T");
1991
+ var $ = w2("\u2502", "|");
1992
+ var x2 = w2("\u2514", "\u2014");
1993
+ var _t = w2("\u2510", "T");
1994
+ var xt = w2("\u2518", "\u2014");
1995
+ var z2 = w2("\u25CF", ">");
1996
+ var U = w2("\u25CB", " ");
1997
+ var et2 = w2("\u25FB", "[\u2022]");
1998
+ var K2 = w2("\u25FC", "[+]");
1999
+ var Y2 = w2("\u25FB", "[ ]");
2000
+ var Et = w2("\u25AA", "\u2022");
2001
+ var st = w2("\u2500", "-");
2002
+ var ct = w2("\u256E", "+");
2003
+ var Gt = w2("\u251C", "+");
2004
+ var $t = w2("\u256F", "+");
2005
+ var dt = w2("\u2570", "+");
2006
+ var Mt = w2("\u256D", "+");
2007
+ var ht2 = w2("\u25CF", "\u2022");
2008
+ var pt = w2("\u25C6", "*");
2009
+ var mt = w2("\u25B2", "!");
2010
+ var gt = w2("\u25A0", "x");
2011
+ var P = (t) => {
2012
+ switch (t) {
2013
+ case "initial":
2014
+ case "active":
2015
+ return e("cyan", Tt);
2016
+ case "cancel":
2017
+ return e("red", at2);
2018
+ case "error":
2019
+ return e("yellow", ut2);
2020
+ case "submit":
2021
+ return e("green", H);
2022
+ }
2023
+ };
2024
+ var yt = (t) => {
2025
+ switch (t) {
2026
+ case "initial":
2027
+ case "active":
2028
+ return e("cyan", $);
2029
+ case "cancel":
2030
+ return e("red", $);
2031
+ case "error":
2032
+ return e("yellow", $);
2033
+ case "submit":
2034
+ return e("green", $);
2035
+ }
2036
+ };
2037
+ var Ot = (t, i, s, r, u, n = false) => {
2038
+ let a = i, c = 0;
2039
+ if (n) for (let o = r - 1; o >= s && (a -= t[o].length, c++, !(a <= u)); o--) ;
2040
+ else for (let o = s; o < r && (a -= t[o].length, c++, !(a <= u)); o++) ;
2041
+ return { lineCount: a, removals: c };
2042
+ };
2043
+ var F = ({ cursor: t, options: i, style: s, output: r = process.stdout, maxItems: u = Number.POSITIVE_INFINITY, columnPadding: n = 0, rowPadding: a = 4 }) => {
2044
+ const c = A(r) - n, o = L(r), l = e("dim", "..."), d = Math.max(o - a, 0), g = Math.max(Math.min(u, d), 5);
2045
+ let p2 = 0;
2046
+ t >= g - 3 && (p2 = Math.max(Math.min(t - g + 3, i.length - g), 0));
2047
+ let f2 = g < i.length && p2 > 0, h2 = g < i.length && p2 + g < i.length;
2048
+ const I = Math.min(p2 + g, i.length), m2 = [];
2049
+ let y = 0;
2050
+ f2 && y++, h2 && y++;
2051
+ const v2 = p2 + (f2 ? 1 : 0), C2 = I - (h2 ? 1 : 0);
2052
+ for (let b2 = v2; b2 < C2; b2++) {
2053
+ const G2 = wrapAnsi(s(i[b2], b2 === t), c, { hard: true, trim: false }).split(`
2054
+ `);
2055
+ m2.push(G2), y += G2.length;
2056
+ }
2057
+ if (y > d) {
2058
+ let b2 = 0, G2 = 0, M = y;
2059
+ const N = t - v2;
2060
+ let O2 = d;
2061
+ const j2 = () => Ot(m2, M, 0, N, O2), k2 = () => Ot(m2, M, N + 1, m2.length, O2, true);
2062
+ f2 ? ({ lineCount: M, removals: b2 } = j2(), M > O2 && (h2 || (O2 -= 1), { lineCount: M, removals: G2 } = k2())) : (h2 || (O2 -= 1), { lineCount: M, removals: G2 } = k2(), M > O2 && (O2 -= 1, { lineCount: M, removals: b2 } = j2())), b2 > 0 && (f2 = true, m2.splice(0, b2)), G2 > 0 && (h2 = true, m2.splice(m2.length - G2, G2));
2063
+ }
2064
+ const S = [];
2065
+ f2 && S.push(l);
2066
+ for (const b2 of m2) for (const G2 of b2) S.push(G2);
2067
+ return h2 && S.push(l), S;
2068
+ };
2069
+ var ue = (t) => {
2070
+ const i = t.active ?? "Yes", s = t.inactive ?? "No";
2071
+ return new X({ active: i, inactive: s, signal: t.signal, input: t.input, output: t.output, initialValue: t.initialValue ?? true, render() {
2072
+ const r = t.withGuide ?? h.withGuide, u = `${P(this.state)} `, n = r ? `${e("gray", $)} ` : "", a = W(t.output, t.message, n, u), c = `${r ? `${e("gray", $)}
2073
+ ` : ""}${a}
2074
+ `, o = this.value ? i : s;
2075
+ switch (this.state) {
2076
+ case "submit": {
2077
+ const l = r ? `${e("gray", $)} ` : "";
2078
+ return `${c}${l}${e("dim", o)}`;
2079
+ }
2080
+ case "cancel": {
2081
+ const l = r ? `${e("gray", $)} ` : "";
2082
+ return `${c}${l}${e(["strikethrough", "dim"], o)}${r ? `
2083
+ ${e("gray", $)}` : ""}`;
2084
+ }
2085
+ default: {
2086
+ const l = r ? `${e("cyan", $)} ` : "", d = r ? e("cyan", x2) : "";
2087
+ return `${c}${l}${this.value ? `${e("green", z2)} ${i}` : `${e("dim", U)} ${e("dim", i)}`}${t.vertical ? r ? `
2088
+ ${e("cyan", $)} ` : `
2089
+ ` : ` ${e("dim", "/")} `}${this.value ? `${e("dim", U)} ${e("dim", s)}` : `${e("green", z2)} ${s}`}
2090
+ ${d}
2091
+ `;
2092
+ }
2093
+ }
2094
+ } }).prompt();
2095
+ };
2096
+ var R2 = { message: (t = [], { symbol: i = e("gray", $), secondarySymbol: s = e("gray", $), output: r = process.stdout, spacing: u = 1, withGuide: n } = {}) => {
2097
+ const a = [], c = n ?? h.withGuide, o = c ? s : "", l = c ? `${i} ` : "", d = c ? `${s} ` : "";
2098
+ for (let p2 = 0; p2 < u; p2++) a.push(o);
2099
+ const g = Array.isArray(t) ? t : t.split(`
2100
+ `);
2101
+ if (g.length > 0) {
2102
+ const [p2, ...f2] = g;
2103
+ p2.length > 0 ? a.push(`${l}${p2}`) : a.push(c ? i : "");
2104
+ for (const h2 of f2) h2.length > 0 ? a.push(`${d}${h2}`) : a.push(c ? s : "");
2105
+ }
2106
+ r.write(`${a.join(`
2107
+ `)}
2108
+ `);
2109
+ }, info: (t, i) => {
2110
+ R2.message(t, { ...i, symbol: e("blue", ht2) });
2111
+ }, success: (t, i) => {
2112
+ R2.message(t, { ...i, symbol: e("green", pt) });
2113
+ }, step: (t, i) => {
2114
+ R2.message(t, { ...i, symbol: e("green", H) });
2115
+ }, warn: (t, i) => {
2116
+ R2.message(t, { ...i, symbol: e("yellow", mt) });
2117
+ }, warning: (t, i) => {
2118
+ R2.warn(t, i);
2119
+ }, error: (t, i) => {
2120
+ R2.message(t, { ...i, symbol: e("red", gt) });
2121
+ } };
2122
+ var me = (t = "", i) => {
2123
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? h.withGuide ? `${e("gray", x2)} ` : "";
2124
+ s.write(`${r}${e("red", t)}
2125
+
2126
+ `);
2127
+ };
2128
+ var ge = (t = "", i) => {
2129
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? h.withGuide ? `${e("gray", lt)} ` : "";
2130
+ s.write(`${r}${t}
2131
+ `);
2132
+ };
2133
+ var ye = (t = "", i) => {
2134
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? h.withGuide ? `${e("gray", $)}
2135
+ ${e("gray", x2)} ` : "";
2136
+ s.write(`${r}${t}
2137
+
2138
+ `);
2139
+ };
2140
+ var Te = (t) => e("magenta", t);
2141
+ var ft = ({ indicator: t = "dots", onCancel: i, output: s = process.stdout, cancelMessage: r, errorMessage: u, frames: n = tt ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], delay: a = tt ? 80 : 120, signal: c, ...o } = {}) => {
2142
+ const l = ot2();
2143
+ let d, g, p2 = false, f2 = false, h2 = "", I, m2 = performance.now();
2144
+ const y = A(s), v2 = o?.styleFrame ?? Te, C2 = (_) => {
2145
+ const A2 = _ > 1 ? u ?? h.messages.error : r ?? h.messages.cancel;
2146
+ f2 = _ === 1, p2 && (W2(A2, _), f2 && typeof i == "function" && i());
2147
+ }, S = () => C2(2), b2 = () => C2(1), G2 = () => {
2148
+ process.on("uncaughtExceptionMonitor", S), process.on("unhandledRejection", S), process.on("SIGINT", b2), process.on("SIGTERM", b2), process.on("exit", C2), c && c.addEventListener("abort", b2);
2149
+ }, M = () => {
2150
+ process.removeListener("uncaughtExceptionMonitor", S), process.removeListener("unhandledRejection", S), process.removeListener("SIGINT", b2), process.removeListener("SIGTERM", b2), process.removeListener("exit", C2), c && c.removeEventListener("abort", b2);
2151
+ }, N = () => {
2152
+ if (I === void 0) return;
2153
+ l && s.write(`
2154
+ `);
2155
+ const _ = wrapAnsi(I, y, { hard: true, trim: false }).split(`
2156
+ `);
2157
+ _.length > 1 && s.write(import_sisteransi2.cursor.up(_.length - 1)), s.write(import_sisteransi2.cursor.to(0)), s.write(import_sisteransi2.erase.down());
2158
+ }, O2 = (_) => _.replace(/\.+$/, ""), j2 = (_) => {
2159
+ const A2 = (performance.now() - _) / 1e3, L2 = Math.floor(A2 / 60), D2 = Math.floor(A2 % 60);
2160
+ return L2 > 0 ? `[${L2}m ${D2}s]` : `[${D2}s]`;
2161
+ }, k2 = o.withGuide ?? h.withGuide, rt2 = (_ = "") => {
2162
+ p2 = true, d = R({ output: s }), h2 = O2(_), m2 = performance.now(), k2 && s.write(`${e("gray", $)}
2163
+ `);
2164
+ let A2 = 0, L2 = 0;
2165
+ G2(), g = setInterval(() => {
2166
+ if (l && h2 === I) return;
2167
+ N(), I = h2;
2168
+ const D2 = v2(n[A2]);
2169
+ let Z;
2170
+ if (l) Z = `${D2} ${h2}...`;
2171
+ else if (t === "timer") Z = `${D2} ${h2} ${j2(m2)}`;
2172
+ else {
2173
+ const kt = ".".repeat(Math.floor(L2)).slice(0, 3);
2174
+ Z = `${D2} ${h2}${kt}`;
2175
+ }
2176
+ const Bt = wrapAnsi(Z, y, { hard: true, trim: false });
2177
+ s.write(Bt), A2 = A2 + 1 < n.length ? A2 + 1 : 0, L2 = L2 < 4 ? L2 + 0.125 : 0;
2178
+ }, a);
2179
+ }, W2 = (_ = "", A2 = 0, L2 = false) => {
2180
+ if (!p2) return;
2181
+ p2 = false, clearInterval(g), N();
2182
+ const D2 = A2 === 0 ? e("green", H) : A2 === 1 ? e("red", at2) : e("red", ut2);
2183
+ h2 = _ ?? h2, L2 || (t === "timer" ? s.write(`${D2} ${h2} ${j2(m2)}
2184
+ `) : s.write(`${D2} ${h2}
2185
+ `)), M(), d();
2186
+ };
2187
+ return { start: rt2, stop: (_ = "") => W2(_, 0), message: (_ = "") => {
2188
+ h2 = O2(_ ?? h2);
2189
+ }, cancel: (_ = "") => W2(_, 1), error: (_ = "") => W2(_, 2), clear: () => W2("", 0, true), get isCancelled() {
2190
+ return f2;
2191
+ } };
2192
+ };
2193
+ var jt = { light: w2("\u2500", "-"), heavy: w2("\u2501", "="), block: w2("\u2588", "#") };
2194
+ var it2 = (t, i) => t.includes(`
2195
+ `) ? t.split(`
2196
+ `).map((s) => i(s)).join(`
2197
+ `) : i(t);
2198
+ var xe = (t) => {
2199
+ const i = (s, r) => {
2200
+ const u = s.label ?? String(s.value);
2201
+ switch (r) {
2202
+ case "disabled":
2203
+ return `${e("gray", U)} ${it2(u, (n) => e("gray", n))}${s.hint ? ` ${e("dim", `(${s.hint ?? "disabled"})`)}` : ""}`;
2204
+ case "selected":
2205
+ return `${it2(u, (n) => e("dim", n))}`;
2206
+ case "active":
2207
+ return `${e("green", z2)} ${u}${s.hint ? ` ${e("dim", `(${s.hint})`)}` : ""}`;
2208
+ case "cancelled":
2209
+ return `${it2(u, (n) => e(["strikethrough", "dim"], n))}`;
2210
+ default:
2211
+ return `${e("dim", U)} ${it2(u, (n) => e("dim", n))}`;
2212
+ }
2213
+ };
2214
+ return new ut({ options: t.options, signal: t.signal, input: t.input, output: t.output, initialValue: t.initialValue, render() {
2215
+ const s = t.withGuide ?? h.withGuide, r = `${P(this.state)} `, u = `${yt(this.state)} `, n = W(t.output, t.message, u, r), a = `${s ? `${e("gray", $)}
2216
+ ` : ""}${n}
2217
+ `;
2218
+ switch (this.state) {
2219
+ case "submit": {
2220
+ const c = s ? `${e("gray", $)} ` : "", o = W(t.output, i(this.options[this.cursor], "selected"), c);
2221
+ return `${a}${o}`;
2222
+ }
2223
+ case "cancel": {
2224
+ const c = s ? `${e("gray", $)} ` : "", o = W(t.output, i(this.options[this.cursor], "cancelled"), c);
2225
+ return `${a}${o}${s ? `
2226
+ ${e("gray", $)}` : ""}`;
2227
+ }
2228
+ default: {
2229
+ const c = s ? `${e("cyan", $)} ` : "", o = s ? e("cyan", x2) : "", l = a.split(`
2230
+ `).length, d = s ? 2 : 1;
2231
+ return `${a}${c}${F({ output: t.output, cursor: this.cursor, options: this.options, maxItems: t.maxItems, columnPadding: c.length, rowPadding: l + d, style: (g, p2) => i(g, g.disabled ? "disabled" : p2 ? "active" : "inactive") }).join(`
2232
+ ${c}`)}
2233
+ ${o}
2234
+ `;
2235
+ }
2236
+ }
2237
+ } }).prompt();
2238
+ };
2239
+ var Nt = `${e("gray", $)} `;
2240
+ var Pe = (t) => new ht({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, output: t.output, signal: t.signal, input: t.input, render() {
2241
+ const i = t?.withGuide ?? h.withGuide, s = `${`${i ? `${e("gray", $)}
2242
+ ` : ""}${P(this.state)} `}${t.message}
2243
+ `, r = t.placeholder ? e("inverse", t.placeholder[0]) + e("dim", t.placeholder.slice(1)) : e(["inverse", "hidden"], "_"), u = this.userInput ? this.userInputWithCursor : r, n = this.value ?? "";
2244
+ switch (this.state) {
2245
+ case "error": {
2246
+ const a = this.error ? ` ${e("yellow", this.error)}` : "", c = i ? `${e("yellow", $)} ` : "", o = i ? e("yellow", x2) : "";
2247
+ return `${s.trim()}
2248
+ ${c}${u}
2249
+ ${o}${a}
2250
+ `;
2251
+ }
2252
+ case "submit": {
2253
+ const a = n ? ` ${e("dim", n)}` : "", c = i ? e("gray", $) : "";
2254
+ return `${s}${c}${a}`;
2255
+ }
2256
+ case "cancel": {
2257
+ const a = n ? ` ${e(["strikethrough", "dim"], n)}` : "", c = i ? e("gray", $) : "";
2258
+ return `${s}${c}${a}${n.trim() ? `
2259
+ ${c}` : ""}`;
2260
+ }
2261
+ default: {
2262
+ const a = i ? `${e("cyan", $)} ` : "", c = i ? e("cyan", x2) : "";
2263
+ return `${s}${a}${u}
2264
+ ${c}
2265
+ `;
2266
+ }
2267
+ }
2268
+ } }).prompt();
2269
+
2270
+ // ../argent-cli/src/link.ts
2271
+ var import_picocolors = __toESM(require_picocolors(), 1);
2272
+ var WILDCARD_HOSTS = /* @__PURE__ */ new Set(["0.0.0.0", "::", "::0", ""]);
2273
+ function isLoopback2(host) {
2274
+ return host === "127.0.0.1" || host === "localhost" || host === "::1";
2275
+ }
2276
+ function validateHost(raw) {
2277
+ const trimmed = raw.trim();
2278
+ if (WILDCARD_HOSTS.has(trimmed)) {
2279
+ throw new StartFlagError(
2280
+ `--host ${trimmed === "" ? '""' : trimmed} is a bind address, not a connect address \u2014 use 127.0.0.1 or the actual reachable host.`
2281
+ );
2282
+ }
2283
+ return trimmed;
2284
+ }
2285
+ function validateConnectPort(raw) {
2286
+ const port = parsePort(raw);
2287
+ if (port === 0) {
2288
+ throw new StartFlagError(`--port must be 1..65535 for a connect target, got "${raw}"`);
2289
+ }
2290
+ return port;
2291
+ }
2292
+ function parseLinkFlags(argv) {
2293
+ const flags2 = {
2294
+ host: null,
2295
+ port: null,
2296
+ token: null,
2297
+ url: null,
2298
+ yes: false,
2299
+ noVerify: false,
2300
+ help: false
2301
+ };
2302
+ for (let i = 0; i < argv.length; i++) {
2303
+ const tok = argv[i];
2304
+ const takeValue = (name) => {
2305
+ const v2 = argv[i + 1];
2306
+ if (v2 === void 0) throw new StartFlagError(`${name} requires a value`);
2307
+ i += 1;
2308
+ return v2;
2309
+ };
2310
+ if (tok === "--help" || tok === "-h") {
2311
+ flags2.help = true;
2312
+ continue;
2313
+ }
2314
+ if (tok === "--yes" || tok === "-y") {
2315
+ flags2.yes = true;
2316
+ continue;
2317
+ }
2318
+ if (tok === "--no-verify") {
2319
+ flags2.noVerify = true;
2320
+ continue;
2321
+ }
2322
+ if (tok === "--host") {
2323
+ flags2.host = validateHost(takeValue("--host"));
2324
+ continue;
2325
+ }
2326
+ if (tok.startsWith("--host=")) {
2327
+ flags2.host = validateHost(tok.slice("--host=".length));
2328
+ continue;
2329
+ }
2330
+ if (tok === "--port" || tok === "-p") {
2331
+ flags2.port = validateConnectPort(takeValue("--port"));
2332
+ continue;
2333
+ }
2334
+ if (tok.startsWith("--port=")) {
2335
+ flags2.port = validateConnectPort(tok.slice("--port=".length));
2336
+ continue;
2337
+ }
2338
+ if (tok === "--token") {
2339
+ flags2.token = takeValue("--token");
2340
+ continue;
2341
+ }
2342
+ if (tok.startsWith("--token=")) {
2343
+ flags2.token = tok.slice("--token=".length);
2344
+ continue;
2345
+ }
2346
+ if (!tok.startsWith("-")) {
2347
+ const parsed = parseLinkTarget(tok);
2348
+ if (!parsed) {
2349
+ throw new StartFlagError(
2350
+ `Unrecognized argument "${tok}". Expected an argent://\u2026 pairing string, an http(s):// URL, or flags (see --help).`
2351
+ );
2352
+ }
2353
+ flags2.host = validateHost(parsed.host);
2354
+ flags2.port = validateConnectPort(String(parsed.port));
2355
+ flags2.url = parsed.url;
2356
+ if (parsed.token) flags2.token = parsed.token;
2357
+ continue;
2358
+ }
2359
+ throw new StartFlagError(`Unknown flag: ${tok}`);
2360
+ }
2361
+ return flags2;
2362
+ }
2363
+ function parseUnlinkFlags(argv) {
2364
+ const flags2 = { yes: false, help: false };
2365
+ for (const tok of argv) {
2366
+ if (tok === "--help" || tok === "-h") {
2367
+ flags2.help = true;
2368
+ continue;
2369
+ }
2370
+ if (tok === "--yes" || tok === "-y") {
2371
+ flags2.yes = true;
2372
+ continue;
2373
+ }
2374
+ throw new StartFlagError(`Unknown flag: ${tok}`);
2375
+ }
2376
+ return flags2;
2377
+ }
2378
+ function printLinkHelp() {
2379
+ console.log(`Usage: argent link [<target>] [flags]
2380
+
2381
+ Route argent client requests (argent tools / run / mcp) to a remote tool-server
2382
+ instead of auto-spawning a local one. The target is persisted to ~/.argent/link.json
2383
+ and survives shell restarts.
2384
+
2385
+ <target> may be:
2386
+ - argent://[<token>@]<host>:<port> the string \`argent server start\` prints
2387
+ - http(s)://<host>[:<port>][/path] a full URL \u2014 use this for a reverse proxy
2388
+ or tunnel (ngrok, cloudflared, nginx). The
2389
+ scheme and any path prefix are preserved;
2390
+ requests go to <url>/tools.
2391
+
2392
+ The easiest LAN path is to paste the connection string from \`argent server start\`:
2393
+ argent link argent://<token>@10.0.0.42:3001
2394
+ For a tunnel, point at its public URL and pass the server's token:
2395
+ argent link https://argent.example.com --token <token>
2396
+
2397
+ Resolution order for the tool-server URL:
2398
+ 1. ARGENT_TOOLS_URL environment variable (highest precedence)
2399
+ 2. ~/.argent/link.json (this command)
2400
+ 3. Auto-spawn a local tool-server (default)
2401
+
2402
+ Flags:
2403
+ --host <h> Remote host or IP to connect to. Prompts interactively if
2404
+ omitted. Wildcards (0.0.0.0, ::) are bind addresses, not
2405
+ connect targets, and are rejected \u2014 use 127.0.0.1 or the
2406
+ actual reachable host.
2407
+ --port, -p <n> Remote port (1..65535). Defaults to 3001. Prompts if omitted.
2408
+ --token <t> Bearer token for a server that enforces auth. Usually
2409
+ supplied inside the argent:// string instead.
2410
+ --no-verify Skip the pre-flight GET /tools health check.
2411
+ --yes, -y Non-interactive. Requires --host (port defaults to 3001).
2412
+ Fails if --host is missing.
2413
+ --help, -h Show this help.
2414
+
2415
+ Examples:
2416
+ argent link argent://ab12\u2026c2@10.0.0.42:3001 Pair from a server-start string.
2417
+ argent link https://argent.example.com --token ab12\u2026c2
2418
+ Link through an HTTPS tunnel/proxy.
2419
+ argent link Interactive prompts for host and port.
2420
+ argent link --host 10.0.0.42 --port 3001 Confirms interactively, then saves.
2421
+ argent link --host 10.0.0.42 --token ab12\u2026c2 --yes
2422
+ Non-interactive, authenticated.
2423
+ argent link --host 10.0.0.42 --yes --no-verify
2424
+ Saves immediately, no health check.
2425
+
2426
+ Security:
2427
+ The token (if any) is stored 0600 and sent as a bearer header. An http:// link
2428
+ has no TLS \u2014 treat any non-loopback http link as trusted-network-only. Prefer
2429
+ an https:// tunnel/proxy when crossing untrusted networks.
2430
+
2431
+ Notes:
2432
+ - If ARGENT_TOOLS_URL is also set in your environment, it overrides the link.
2433
+ - To stop using the remote target, run \`argent unlink\`.
2434
+ - \`argent server start/stop/status\` manage the local tool-server lifecycle
2435
+ and are unaffected by linking.
2436
+ - Restart your editor (Claude / Cursor / VS Code) afterwards \u2014 a running
2437
+ \`argent mcp\` process caches the target at startup and won't pick up the
2438
+ new link until it's relaunched.
2439
+ `);
2440
+ }
2441
+ function printUnlinkHelp() {
2442
+ console.log(`Usage: argent unlink [flags]
2443
+
2444
+ Remove the persisted remote tool-server link (~/.argent/link.json) and return
2445
+ to default local auto-spawn behaviour.
2446
+
2447
+ Flags:
2448
+ --yes, -y Skip the confirmation prompt.
2449
+ --help, -h Show this help.
2450
+
2451
+ Examples:
2452
+ argent unlink Confirms, then removes the link.
2453
+ argent unlink --yes Removes without confirmation. Safe in scripts.
2454
+
2455
+ Notes:
2456
+ - No-op (exit 0) if no link is currently set.
2457
+ - If ARGENT_TOOLS_URL is also set in your environment, it still takes
2458
+ precedence after unlinking \u2014 unset it manually for fully local behaviour.
2459
+ - This does not stop or start any tool-server process. Use
2460
+ \`argent server stop\` if you also want to terminate a running local server.
2461
+ - Restart your editor afterwards \u2014 a running \`argent mcp\` process won't
2462
+ revert to local auto-spawn until it's relaunched.
2463
+ `);
2464
+ }
2465
+ async function promptHost(existing, initial) {
2466
+ const hostInput = await Pe({
2467
+ message: "Remote host or IP to connect to",
2468
+ placeholder: existing?.host ?? "127.0.0.1",
2469
+ initialValue: initial ?? existing?.host,
2470
+ validate(value) {
2471
+ if (!value || !value.trim()) return "Host cannot be empty.";
2472
+ const trimmed = value.trim();
2473
+ if (WILDCARD_HOSTS.has(trimmed)) {
2474
+ return `${trimmed} is a bind address, not a connect address \u2014 use 127.0.0.1 or the actual reachable host.`;
2475
+ }
2476
+ }
2477
+ });
2478
+ if (q(hostInput)) {
2479
+ me("Link cancelled.");
2480
+ process.exit(0);
2481
+ }
2482
+ return hostInput.trim();
2483
+ }
2484
+ async function promptPort(existing, initial) {
2485
+ const defaultPort = initial ?? existing?.port ?? 3001;
2486
+ const portInput = await Pe({
2487
+ message: "Remote port",
2488
+ placeholder: String(defaultPort),
2489
+ initialValue: String(defaultPort),
2490
+ validate(value) {
2491
+ if (!value || !value.trim()) return "Port cannot be empty.";
2492
+ try {
2493
+ validateConnectPort(value.trim());
2494
+ } catch (err) {
2495
+ if (err instanceof StartFlagError) return err.message;
2496
+ throw err;
2497
+ }
2498
+ }
2499
+ });
2500
+ if (q(portInput)) {
2501
+ me("Link cancelled.");
2502
+ process.exit(0);
2503
+ }
2504
+ return validateConnectPort(portInput.trim());
2505
+ }
2506
+ async function preflightHealth(url, token) {
2507
+ const controller = new AbortController();
2508
+ const timer = setTimeout(() => controller.abort(), 3e3);
2509
+ try {
2510
+ const res = await fetch(`${url}/tools`, {
2511
+ signal: controller.signal,
2512
+ headers: token ? { Authorization: `Bearer ${token}` } : {}
2513
+ });
2514
+ if (!res.ok) {
2515
+ const hint = res.status === 401 ? " \u2014 the server requires a token; pass --token or use the argent:// link from `server start`" : res.status === 403 ? " \u2014 the server refused this host (DNS-rebinding guard); reach it by its bind host or start it with --host" : "";
2516
+ return { ok: false, error: `${res.status} ${res.statusText}${hint}` };
2517
+ }
2518
+ return { ok: true };
2519
+ } catch (err) {
2520
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
2521
+ } finally {
2522
+ clearTimeout(timer);
2523
+ }
2524
+ }
2525
+ function printRestartHint() {
2526
+ console.log(
2527
+ import_picocolors.default.dim("Restart your editor to apply the change to any running `argent mcp` session.")
2528
+ );
2529
+ }
2530
+ function printSecurityCaveat(host, token, url) {
2531
+ if (isLoopback2(host)) return;
2532
+ const tls = url.startsWith("https://");
2533
+ if (tls) {
2534
+ if (!token) {
2535
+ process.stderr.write(
2536
+ import_picocolors.default.yellow(
2537
+ `WARNING: ${host} is reached over HTTPS but with NO token \u2014 anyone who can reach the URL can drive the server. Pair with a token.
2538
+ `
2539
+ )
2540
+ );
2541
+ }
2542
+ return;
2543
+ }
2544
+ if (token) {
2545
+ process.stderr.write(
2546
+ import_picocolors.default.dim(
2547
+ `Note: ${host} is reached over plain HTTP (bearer-token auth, no TLS). Keep this link to a trusted network or VPN, or front it with an https:// tunnel.
2548
+ `
2549
+ )
2550
+ );
2551
+ return;
2552
+ }
2553
+ process.stderr.write(
2554
+ import_picocolors.default.yellow(
2555
+ `WARNING: linked target ${host} is non-loopback and has NO token \u2014 tool calls travel over plain HTTP with no auth. Treat this link as trusted-network-only, or pair with a token (start the server without --no-auth).
2556
+ `
2557
+ )
2558
+ );
2559
+ }
2560
+ async function link(argv) {
2561
+ let flags2;
2562
+ try {
2563
+ flags2 = parseLinkFlags(argv);
2564
+ } catch (err) {
2565
+ if (err instanceof StartFlagError) {
2566
+ console.error(`Error: ${err.message}
2567
+ `);
2568
+ printLinkHelp();
2569
+ process.exit(2);
2570
+ }
2571
+ throw err;
2572
+ }
2573
+ if (flags2.help) {
2574
+ printLinkHelp();
2575
+ return;
2576
+ }
2577
+ if (flags2.yes && flags2.host === null) {
2578
+ console.error("Error: --yes requires --host (port defaults to 3001).\n");
2579
+ printLinkHelp();
2580
+ process.exit(2);
2581
+ }
2582
+ const existing = await readLinkConfig();
2583
+ let host;
2584
+ if (flags2.host !== null) {
2585
+ host = flags2.host;
2586
+ } else {
2587
+ ge(import_picocolors.default.bgCyan(import_picocolors.default.black(" argent link ")));
2588
+ if (existing) {
2589
+ R2.info(`Current link: ${import_picocolors.default.cyan(existing.url)} (${existing.createdAt})`);
2590
+ }
2591
+ host = await promptHost(existing);
2592
+ }
2593
+ let port;
2594
+ if (flags2.port !== null) {
2595
+ port = flags2.port;
2596
+ } else if (flags2.yes) {
2597
+ port = 3001;
2598
+ } else {
2599
+ port = await promptPort(existing);
2600
+ }
2601
+ const token = flags2.token ?? (existing && existing.host === host && existing.port === port ? existing.token : void 0);
2602
+ let url = flags2.url ?? formatUrl(host, port);
2603
+ if (!flags2.yes && existing) {
2604
+ if (existing.url === url) {
2605
+ R2.info(`Already linked to ${import_picocolors.default.cyan(url)}.`);
2606
+ ye("No changes.");
2607
+ return;
2608
+ }
2609
+ const overwrite = await ue({
2610
+ message: `Replace existing link ${import_picocolors.default.dim(existing.url)} with ${import_picocolors.default.cyan(url)}?`,
2611
+ initialValue: true
2612
+ });
2613
+ if (q(overwrite) || !overwrite) {
2614
+ me("Link cancelled.");
2615
+ process.exit(0);
2616
+ }
2617
+ }
2618
+ if (!flags2.noVerify) {
2619
+ while (true) {
2620
+ const spinnerActive = !flags2.yes;
2621
+ let spinner = null;
2622
+ if (spinnerActive) {
2623
+ spinner = ft();
2624
+ spinner.start(`Verifying tool-server at ${url}...`);
2625
+ }
2626
+ const result = await preflightHealth(url, token);
2627
+ if (result.ok) {
2628
+ if (spinner) spinner.stop(import_picocolors.default.green("Tool-server reachable."));
2629
+ break;
2630
+ }
2631
+ if (spinner) spinner.stop(import_picocolors.default.red("Verification failed."));
2632
+ const detail = result.error ? ` (${result.error})` : "";
2633
+ if (flags2.yes) {
2634
+ console.error(
2635
+ `Error: pre-flight GET ${url}/tools failed${detail}. Make sure the remote tool-server is running, or pass --no-verify to skip.`
2636
+ );
2637
+ process.exit(1);
2638
+ }
2639
+ R2.error(`pre-flight GET ${url}/tools failed${detail}.`);
2640
+ const action = await xe({
2641
+ message: "How would you like to proceed?",
2642
+ options: [
2643
+ { value: "retry", label: "Retry verification" },
2644
+ { value: "modify", label: "Modify host and port, then retry" },
2645
+ { value: "skip", label: "Skip verification and save anyway" },
2646
+ { value: "cancel", label: "Cancel" }
2647
+ ],
2648
+ initialValue: "retry"
2649
+ });
2650
+ if (q(action) || action === "cancel") {
2651
+ me("Link cancelled.");
2652
+ process.exit(0);
2653
+ }
2654
+ if (action === "skip") break;
2655
+ if (action === "modify") {
2656
+ host = await promptHost(existing, host);
2657
+ port = await promptPort(existing, port);
2658
+ url = formatUrl(host, port);
2659
+ }
2660
+ }
2661
+ }
2662
+ const cfg = {
2663
+ url,
2664
+ host,
2665
+ port,
2666
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2667
+ ...token ? { token } : {}
2668
+ };
2669
+ await writeLinkConfig(cfg);
2670
+ if (existing && existing.url !== url) {
2671
+ console.log(`${import_picocolors.default.green("\u2713")} Link updated: ${import_picocolors.default.dim(existing.url)} \u2192 ${import_picocolors.default.cyan(url)}`);
2672
+ } else {
2673
+ console.log(`${import_picocolors.default.green("\u2713")} Linked: ${import_picocolors.default.cyan(url)}`);
2674
+ }
2675
+ if (token) console.log(import_picocolors.default.dim(" auth: token stored in ~/.argent/link.json (0600)"));
2676
+ printSecurityCaveat(host, token, url);
2677
+ if (process.env.ARGENT_TOOLS_URL) {
2678
+ console.log(
2679
+ import_picocolors.default.yellow(
2680
+ `Note: ARGENT_TOOLS_URL=${process.env.ARGENT_TOOLS_URL} is set in your environment and takes precedence over the link.`
2681
+ )
2682
+ );
2683
+ }
2684
+ printRestartHint();
2685
+ }
2686
+ async function unlink3(argv) {
2687
+ let flags2;
2688
+ try {
2689
+ flags2 = parseUnlinkFlags(argv);
2690
+ } catch (err) {
2691
+ if (err instanceof StartFlagError) {
2692
+ console.error(`Error: ${err.message}
2693
+ `);
2694
+ printUnlinkHelp();
2695
+ process.exit(2);
2696
+ }
2697
+ throw err;
2698
+ }
2699
+ if (flags2.help) {
2700
+ printUnlinkHelp();
2701
+ return;
2702
+ }
2703
+ const existing = await readLinkConfig();
2704
+ if (!existing) {
2705
+ console.log("Not currently linked \u2014 already using local tool-server.");
2706
+ return;
2707
+ }
2708
+ if (!flags2.yes) {
2709
+ const confirmed = await ue({
2710
+ message: `Remove link to ${import_picocolors.default.cyan(existing.url)}?`,
2711
+ initialValue: true
2712
+ });
2713
+ if (q(confirmed) || !confirmed) {
2714
+ me("Unlink cancelled.");
2715
+ process.exit(0);
2716
+ }
2717
+ }
2718
+ await clearLinkConfig();
2719
+ console.log(`${import_picocolors.default.green("\u2713")} Unlinked from ${import_picocolors.default.dim(existing.url)}.`);
2720
+ if (process.env.ARGENT_TOOLS_URL) {
2721
+ console.log(
2722
+ import_picocolors.default.yellow(
2723
+ `The env var ARGENT_TOOLS_URL is also set in your shell (=${process.env.ARGENT_TOOLS_URL}) and takes precedence \u2014 unset it manually if you want fully local behaviour.`
2724
+ )
2725
+ );
2726
+ }
2727
+ printRestartHint();
2728
+ }
2729
+
2730
+ // ../argent-cli/src/flags.ts
2731
+ import * as fs4 from "node:fs";
2732
+ import * as path5 from "node:path";
2733
+ import { homedir as homedir4 } from "node:os";
2734
+ var FLAG_REGISTRY = [
2735
+ // {
2736
+ // name: "example-flag",
2737
+ // description: "One-line summary shown by `argent flags`.",
2738
+ // },
2739
+ ];
2740
+ function getFlagDefinition(name, registry = FLAG_REGISTRY) {
2741
+ return registry.find((def) => def.name === name);
2742
+ }
2743
+ var PROJECT_MARKERS = [".argent", ".git", "package.json"];
2744
+ function resolveProjectRoot(startDir) {
2745
+ const initial = path5.resolve(startDir);
2746
+ let current = initial;
2747
+ while (true) {
2748
+ for (const marker of PROJECT_MARKERS) {
2749
+ if (fs4.existsSync(path5.join(current, marker))) return current;
2750
+ }
2751
+ const parent = path5.dirname(current);
2752
+ if (parent === current) return initial;
2753
+ current = parent;
2754
+ }
2755
+ }
2756
+ function getFlagsPath(scope, options = {}) {
2757
+ const home = options.homeDir ?? homedir4();
2758
+ if (scope === "global") {
2759
+ return path5.join(home, ".argent", "flags.json");
2760
+ }
2761
+ const cwd = options.cwd ?? process.cwd();
2762
+ return path5.join(resolveProjectRoot(cwd), ".argent", "flags.json");
2763
+ }
2764
+ function readFlagsFile(filePath) {
2765
+ let raw;
2766
+ try {
2767
+ raw = fs4.readFileSync(filePath, "utf8");
2768
+ } catch {
2769
+ return {};
2770
+ }
2771
+ let parsed;
2772
+ try {
2773
+ parsed = JSON.parse(raw);
2774
+ } catch {
2775
+ return {};
2776
+ }
2777
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
2778
+ const flags2 = parsed.flags;
2779
+ if (!flags2 || typeof flags2 !== "object" || Array.isArray(flags2)) return {};
2780
+ const out = {};
2781
+ for (const [k2, v2] of Object.entries(flags2)) {
2782
+ if (typeof v2 === "boolean") out[k2] = v2;
2783
+ }
2784
+ return out;
2785
+ }
2786
+ function writeFlagsFile(filePath, flags2) {
2787
+ if (Object.keys(flags2).length === 0) {
2788
+ if (fs4.existsSync(filePath)) fs4.rmSync(filePath, { force: true });
2789
+ const parent = path5.dirname(filePath);
2790
+ try {
2791
+ if (fs4.existsSync(parent) && fs4.readdirSync(parent).length === 0) {
2792
+ fs4.rmdirSync(parent);
2793
+ }
2794
+ } catch {
2795
+ }
2796
+ return;
2797
+ }
2798
+ fs4.mkdirSync(path5.dirname(filePath), { recursive: true });
2799
+ const tmp = `${filePath}.${process.pid}.tmp`;
2800
+ fs4.writeFileSync(tmp, JSON.stringify({ flags: flags2 }, null, 2) + "\n");
2801
+ fs4.renameSync(tmp, filePath);
2802
+ }
2803
+ function readFlags(scope, options = {}) {
2804
+ return readFlagsFile(getFlagsPath(scope, options));
2805
+ }
2806
+ function setFlag(name, value, scope, options = {}) {
2807
+ const filePath = getFlagsPath(scope, options);
2808
+ const current = readFlagsFile(filePath);
2809
+ current[name] = value;
2810
+ writeFlagsFile(filePath, current);
2811
+ }
2812
+ function unsetFlag(name, scope, options = {}) {
2813
+ const filePath = getFlagsPath(scope, options);
2814
+ const current = readFlagsFile(filePath);
2815
+ if (!Object.hasOwn(current, name)) return false;
2816
+ delete current[name];
2817
+ writeFlagsFile(filePath, current);
2818
+ return true;
2819
+ }
2820
+ function isFlagEnabled(name, options = {}) {
2821
+ const projectFlags = readFlags("project", options);
2822
+ if (Object.hasOwn(projectFlags, name)) return projectFlags[name];
2823
+ const globalFlags = readFlags("global", options);
2824
+ if (Object.hasOwn(globalFlags, name)) return globalFlags[name];
2825
+ return false;
2826
+ }
2827
+ var FLAG_NAME_RE = /^[a-zA-Z][a-zA-Z0-9._-]*$/;
2828
+ function parseToggleArgs(argv, command) {
2829
+ let name = null;
2830
+ let scope = "global";
2831
+ let positionalOnly = false;
2832
+ for (let i = 0; i < argv.length; i++) {
2833
+ const tok = argv[i];
2834
+ if (positionalOnly) {
2835
+ if (name !== null) throw new Error(`Unexpected extra argument: "${tok}"`);
2836
+ name = tok;
2837
+ continue;
2838
+ }
2839
+ if (tok === "--") {
2840
+ positionalOnly = true;
2841
+ continue;
2842
+ }
2843
+ if (tok === "--scope") {
2844
+ const v2 = argv[i + 1];
2845
+ if (v2 === void 0) throw new Error("--scope requires a value (project|global)");
2846
+ scope = parseScope(v2);
2847
+ i += 1;
2848
+ continue;
2849
+ }
2850
+ if (tok.startsWith("--scope=")) {
2851
+ scope = parseScope(tok.slice("--scope=".length));
2852
+ continue;
2853
+ }
2854
+ if (tok.startsWith("--")) {
2855
+ throw new Error(`Unknown flag: ${tok}`);
2856
+ }
2857
+ if (name !== null) {
2858
+ throw new Error(`Unexpected extra argument: "${tok}"`);
2859
+ }
2860
+ name = tok;
2861
+ }
2862
+ if (name === null) {
2863
+ throw new Error(`Usage: argent ${command} <flag-name> [--scope project|global]`);
2864
+ }
2865
+ if (!FLAG_NAME_RE.test(name)) {
2866
+ throw new Error(
2867
+ `Invalid flag name "${name}". Must start with a letter and contain only letters, digits, ".", "_", or "-".`
2868
+ );
2869
+ }
2870
+ return { name, scope };
2871
+ }
2872
+ function parseScope(raw) {
2873
+ if (raw === "global" || raw === "project") return raw;
2874
+ throw new Error(`--scope must be "project" or "global", got "${raw}"`);
2875
+ }
2876
+ function printToggleHelp(command) {
2877
+ const summary = command === "enable" ? "Enable a predefined feature flag (see `argent flags`) at the chosen scope." : "Remove a feature flag entry at the chosen scope. Falls back to the global value if set; otherwise the flag is treated as off.";
2878
+ console.log(`Usage: argent ${command} <flag-name> [--scope project|global]
2879
+
2880
+ ${summary}
2881
+
2882
+ Storage:
2883
+ ~/.argent/flags.json (global, default)
2884
+ <project-root>/.argent/flags.json (project, with --scope project)
2885
+
2886
+ Options:
2887
+ --scope <global|project> Where to write (default: global)
2888
+ --help, -h Show this help
2889
+ `);
2890
+ }
2891
+ function runToggle(argv, command, registry) {
2892
+ if (argv.includes("--help") || argv.includes("-h")) {
2893
+ printToggleHelp(command);
2894
+ return;
2895
+ }
2896
+ let parsed;
2897
+ try {
2898
+ parsed = parseToggleArgs(argv, command);
2899
+ } catch (err) {
2900
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
2901
+ process.exit(2);
2902
+ }
2903
+ if (command === "enable" && getFlagDefinition(parsed.name, registry) === void 0) {
2904
+ console.error(
2905
+ `Error: Unknown feature flag "${parsed.name}". Run \`argent flags\` to see available flags.`
2906
+ );
2907
+ process.exit(2);
2908
+ }
2909
+ const filePath = getFlagsPath(parsed.scope);
2910
+ try {
2911
+ if (command === "enable") {
2912
+ setFlag(parsed.name, true, parsed.scope);
2913
+ } else {
2914
+ unsetFlag(parsed.name, parsed.scope);
2915
+ }
2916
+ } catch (err) {
2917
+ console.error(`Failed to ${command} flag: ${err instanceof Error ? err.message : String(err)}`);
2918
+ process.exit(1);
2919
+ }
2920
+ if (command === "enable") {
2921
+ console.log(`Enabled flag "${parsed.name}" (${parsed.scope}). Stored at ${filePath}.`);
2922
+ } else {
2923
+ console.log(`Disabled flag "${parsed.name}" (${parsed.scope}).`);
2924
+ }
2925
+ }
2926
+ function enable(argv, registry = FLAG_REGISTRY) {
2927
+ runToggle(argv, "enable", registry);
2928
+ }
2929
+ function disable(argv, registry = FLAG_REGISTRY) {
2930
+ runToggle(argv, "disable", registry);
2931
+ }
2932
+ function flags(argv, registry = FLAG_REGISTRY) {
2933
+ if (argv.includes("--help") || argv.includes("-h")) {
2934
+ console.log(`Usage: argent flags [--json]
2935
+
2936
+ List the available feature flags and their current state. Flags are
2937
+ predefined; project-scoped values override global ones.
2938
+
2939
+ Options:
2940
+ --json Print machine-readable JSON
2941
+ `);
2942
+ return;
2943
+ }
2944
+ const json = argv.includes("--json");
2945
+ const projectFlags = readFlags("project");
2946
+ const globalFlags = readFlags("global");
2947
+ const effective = {};
2948
+ for (const [k2, v2] of Object.entries(globalFlags)) effective[k2] = { value: v2, scope: "global" };
2949
+ for (const [k2, v2] of Object.entries(projectFlags)) effective[k2] = { value: v2, scope: "project" };
2950
+ const registryView = registry.map((def) => {
2951
+ const eff = Object.hasOwn(effective, def.name) ? effective[def.name] : void 0;
2952
+ return {
2953
+ name: def.name,
2954
+ description: def.description,
2955
+ enabled: eff?.value ?? false,
2956
+ scope: eff?.scope ?? null
2957
+ };
2958
+ });
2959
+ const known = new Set(registry.map((def) => def.name));
2960
+ const unrecognized = Object.keys(effective).filter((name) => !known.has(name)).sort().map((name) => ({ name, enabled: effective[name].value, scope: effective[name].scope }));
2961
+ if (json) {
2962
+ console.log(
2963
+ JSON.stringify(
2964
+ {
2965
+ flags: registryView,
2966
+ unrecognized,
2967
+ global: globalFlags,
2968
+ project: projectFlags,
2969
+ effective,
2970
+ paths: {
2971
+ global: getFlagsPath("global"),
2972
+ project: getFlagsPath("project")
2973
+ }
2974
+ },
2975
+ null,
2976
+ 2
2977
+ )
2978
+ );
2979
+ return;
2980
+ }
2981
+ if (registryView.length === 0) {
2982
+ console.log("No feature flags are defined.");
2983
+ } else {
2984
+ console.log("Feature flags (project overrides global):");
2985
+ const maxName = registryView.reduce((m2, f2) => Math.max(m2, f2.name.length), 0);
2986
+ for (const f2 of registryView) {
2987
+ const stateLabel = f2.enabled ? "enabled" : "disabled";
2988
+ const scopeLabel = f2.scope ? ` (${f2.scope})` : "";
2989
+ console.log(` ${f2.name.padEnd(maxName, " ")} ${stateLabel.padEnd(8)}${scopeLabel}`);
2990
+ console.log(` ${" ".repeat(maxName)} ${f2.description}`);
2991
+ }
2992
+ }
2993
+ if (unrecognized.length > 0) {
2994
+ console.log("\nStored but no longer recognized (safe to `argent disable`):");
2995
+ const maxName = unrecognized.reduce((m2, f2) => Math.max(m2, f2.name.length), 0);
2996
+ for (const f2 of unrecognized) {
2997
+ const stateLabel = f2.enabled ? "enabled" : "disabled";
2998
+ console.log(` ${f2.name.padEnd(maxName, " ")} ${stateLabel.padEnd(8)} (${f2.scope})`);
2999
+ }
3000
+ }
3001
+ console.log(`
3002
+ Global: ${getFlagsPath("global")}`);
3003
+ console.log(` Project: ${getFlagsPath("project")}`);
3004
+ }
725
3005
  export {
3006
+ FLAG_REGISTRY,
3007
+ disable,
3008
+ enable,
3009
+ flags,
3010
+ getFlagDefinition,
3011
+ isFlagEnabled,
3012
+ link,
726
3013
  run,
727
3014
  server,
728
- tools
3015
+ tools,
3016
+ unlink3 as unlink
729
3017
  };