jevgrep 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/jgrep.js ADDED
@@ -0,0 +1,2309 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
+
30
+ // src/jgrep.ts
31
+ import fs from "node:fs";
32
+ import os from "node:os";
33
+ import path from "node:path";
34
+ import { execFileSync } from "node:child_process";
35
+ import { createHash } from "node:crypto";
36
+ function chunk(file, text, opts = { minLines: 5, maxLines: 60 }) {
37
+ const lines = text.split(`
38
+ `);
39
+ const out = [];
40
+ let start = 0;
41
+ const flush = (end) => {
42
+ const t = lines.slice(start, end).join(`
43
+ `);
44
+ if (t.trim())
45
+ out.push({ file, start: start + 1, end, text: t });
46
+ start = end;
47
+ };
48
+ for (let i = 1;i < lines.length; i++) {
49
+ const len = i - start;
50
+ const boundary = /^[^\s})\]]/.test(lines[i]) && !/^(else|catch|finally|\.)/.test(lines[i]);
51
+ if (len >= opts.maxLines || boundary && len >= opts.minLines)
52
+ flush(i);
53
+ }
54
+ flush(lines.length);
55
+ return out;
56
+ }
57
+ function diffChunks(diff) {
58
+ const out = [];
59
+ let file = "";
60
+ let cur = null;
61
+ const push = () => {
62
+ if (cur && cur.text.trim())
63
+ out.push(cur);
64
+ cur = null;
65
+ };
66
+ for (const line of diff.split(`
67
+ `)) {
68
+ if (line.startsWith("+++ ")) {
69
+ push();
70
+ file = line.slice(4).replace(/^b\//, "");
71
+ continue;
72
+ }
73
+ const m = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/.exec(line);
74
+ if (m) {
75
+ push();
76
+ const start = Number(m[1]), count = m[2] === undefined ? 1 : Number(m[2]);
77
+ if (file === "/dev/null")
78
+ continue;
79
+ cur = { file, start, end: Math.max(start, start + count - 1), text: "" };
80
+ continue;
81
+ }
82
+ if (line.startsWith("diff --git")) {
83
+ push();
84
+ continue;
85
+ }
86
+ if (cur)
87
+ cur.text += (cur.text ? `
88
+ ` : "") + line;
89
+ }
90
+ push();
91
+ return out;
92
+ }
93
+ function gitDiff(args, cwd = process.cwd()) {
94
+ return execFileSync("git", ["diff", "--no-color", "--unified=3", ...args], { cwd, encoding: "utf8", maxBuffer: 64 << 20 });
95
+ }
96
+ function listFiles(paths) {
97
+ const files = new Set;
98
+ for (const p of paths) {
99
+ if (!fs.existsSync(p))
100
+ throw new Error(`no such path: ${p}`);
101
+ if (fs.statSync(p).isFile()) {
102
+ files.add(p);
103
+ continue;
104
+ }
105
+ try {
106
+ execFileSync("git", ["ls-files", "-z", "-co", "--exclude-standard", "--", p], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).split("\x00").filter(Boolean).forEach((f) => files.add(f));
107
+ } catch {
108
+ walk(p, files);
109
+ }
110
+ }
111
+ return [...files].filter((f) => {
112
+ try {
113
+ return fs.statSync(f).isFile();
114
+ } catch {
115
+ return false;
116
+ }
117
+ }).sort();
118
+ }
119
+ function walk(root, out, dir = root) {
120
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
121
+ if (SKIP_DIRS.has(e.name) || e.name.startsWith("."))
122
+ continue;
123
+ if (out.size > MAX_WALK_FILES) {
124
+ const shown = path.resolve(root) === process.cwd() ? "the current directory" : root;
125
+ throw new Error(`${shown} is not a git repo and has more than ${MAX_WALK_FILES} files.
126
+ ` + `Run jgrep inside a project, or pass its path: jgrep "..." ~/Documents/<project>`);
127
+ }
128
+ const p = path.join(dir, e.name);
129
+ e.isDirectory() ? walk(root, out, p) : out.add(p);
130
+ }
131
+ }
132
+ function readText(file) {
133
+ const st = fs.statSync(file);
134
+ if (st.size > 1e6)
135
+ return null;
136
+ const buf = fs.readFileSync(file);
137
+ if (buf.subarray(0, 8000).includes(0))
138
+ return null;
139
+ return buf.toString("utf8");
140
+ }
141
+ function chunkPaths(paths) {
142
+ const chunks = [];
143
+ for (const file of listFiles(paths)) {
144
+ const text = readText(file);
145
+ if (text !== null)
146
+ chunks.push(...chunk(file, text));
147
+ }
148
+ return chunks;
149
+ }
150
+ function buildRequest(question, chunks, kind = "code") {
151
+ const state = { chunks: chunks.map((c, i) => ({ id: `c${i}`, file: c.file, lines: `${c.start}-${c.end}`, [kind]: c.text })) };
152
+ const what = kind === "diff" ? "Does that diff hunk (lines starting with + were added, - removed) match this description" : "Does that code match this description";
153
+ const questions = {};
154
+ chunks.forEach((_, i) => {
155
+ questions[`c${i}`] = { type: "noul", instructions: `Look only at the chunk with id "c${i}". ${what}: ${question}` };
156
+ });
157
+ return { model: MODEL, state, questions };
158
+ }
159
+ async function ask(question, chunks, kind, apiKey, f) {
160
+ const body = JSON.stringify(buildRequest(question, chunks, kind));
161
+ for (let attempt = 0;; attempt++) {
162
+ const res = await f(ENDPOINT, {
163
+ method: "POST",
164
+ headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
165
+ body,
166
+ signal: AbortSignal.timeout(30000)
167
+ });
168
+ if (res.ok) {
169
+ const json = await res.json();
170
+ return { ps: chunks.map((_, i) => json.answers[`c${i}`]?.noul ?? NaN), tokens: json.usage?.input_tokens ?? 0 };
171
+ }
172
+ if ((res.status === 429 || res.status >= 500) && attempt < 3) {
173
+ await new Promise((r) => setTimeout(r, 500 * 2 ** attempt));
174
+ continue;
175
+ }
176
+ if (res.status === 401)
177
+ throw new Error("TypeSafe API rejected the key (401). Check TYPESAFE_API_KEY.");
178
+ throw new Error(`TypeSafe API ${res.status}: ${(await res.text()).slice(0, 200)}`);
179
+ }
180
+ }
181
+ function loadCache() {
182
+ try {
183
+ return JSON.parse(fs.readFileSync(CACHE_FILE, "utf8"));
184
+ } catch {
185
+ return {};
186
+ }
187
+ }
188
+ function saveCache(c) {
189
+ try {
190
+ fs.mkdirSync(path.dirname(CACHE_FILE), { recursive: true });
191
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(c));
192
+ } catch {}
193
+ }
194
+ async function jgrep(question, chunks, o) {
195
+ const kind = o.kind ?? "code";
196
+ const cache = o.cache ?? {};
197
+ const f = o.fetchImpl ?? fetch;
198
+ const all = new Array(chunks.length);
199
+ const todo = [];
200
+ chunks.forEach((c, i) => {
201
+ const hit = cache[key(question, kind, c)];
202
+ if (hit !== undefined)
203
+ all[i] = { ...c, p: hit };
204
+ else
205
+ todo.push(i);
206
+ });
207
+ const cached = chunks.length - todo.length;
208
+ const batches = [];
209
+ for (let i = 0;i < todo.length; i += o.batch)
210
+ batches.push(todo.slice(i, i + o.batch));
211
+ let tokens = 0, done = 0, next = 0;
212
+ const worker = async () => {
213
+ while (next < batches.length) {
214
+ const b = batches[next++];
215
+ const { ps, tokens: t } = await ask(question, b.map((i) => chunks[i]), kind, o.apiKey, f);
216
+ tokens += t;
217
+ b.forEach((ci, j) => {
218
+ all[ci] = { ...chunks[ci], p: ps[j] };
219
+ if (Number.isFinite(ps[j]))
220
+ cache[key(question, kind, chunks[ci])] = ps[j];
221
+ });
222
+ o.onProgress?.(++done, batches.length);
223
+ }
224
+ };
225
+ await Promise.all(Array.from({ length: Math.min(o.concurrency, batches.length) }, worker));
226
+ const hits = all.filter((h) => h.p >= o.threshold);
227
+ return { hits, all, chunks: chunks.length, tokens, cached };
228
+ }
229
+ function resolveApiKey(env = process.env) {
230
+ if (env.TYPESAFE_API_KEY?.trim())
231
+ return env.TYPESAFE_API_KEY.trim();
232
+ for (const file of [path.join(process.cwd(), ".env"), CONFIG_FILE]) {
233
+ try {
234
+ const m = fs.readFileSync(file, "utf8").match(/^\s*(?:export\s+)?TYPESAFE_API_KEY\s*=\s*["']?([^"'\r\n#]+)/m);
235
+ if (m)
236
+ return m[1].trim();
237
+ } catch {}
238
+ }
239
+ throw new Error("No TypeSafe API key. Run `jgrep init` (or export TYPESAFE_API_KEY).");
240
+ }
241
+ async function verifyApiKey(apiKey, f = fetch) {
242
+ const res = await f(ENDPOINT, {
243
+ method: "POST",
244
+ headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
245
+ body: JSON.stringify({ model: MODEL, state: "ping", questions: { ok: { type: "noul", instructions: "Is the state the word ping?" } } }),
246
+ signal: AbortSignal.timeout(15000)
247
+ });
248
+ const model = res.ok ? (await res.json()).model : undefined;
249
+ return { ok: res.ok, status: res.status, model };
250
+ }
251
+ function saveApiKey(apiKey) {
252
+ fs.mkdirSync(path.dirname(CONFIG_FILE), { recursive: true, mode: 448 });
253
+ fs.writeFileSync(CONFIG_FILE, `TYPESAFE_API_KEY=${apiKey}
254
+ `, { mode: 384 });
255
+ return CONFIG_FILE;
256
+ }
257
+ function installSkills(skillSrc, home = os.homedir(), agents = ["claude", "codex"]) {
258
+ const out = [];
259
+ for (const a of agents) {
260
+ const base = path.join(home, `.${a}`);
261
+ if (!fs.existsSync(base))
262
+ continue;
263
+ const dir = path.join(base, "skills", "jgrep");
264
+ fs.mkdirSync(dir, { recursive: true });
265
+ fs.copyFileSync(skillSrc, path.join(dir, "SKILL.md"));
266
+ out.push(dir);
267
+ }
268
+ return out;
269
+ }
270
+ var ENDPOINT = "https://api.typesafe.ai/v1/systemone", MODEL = "jev-latest", USD_PER_M_INPUT = 0.042, SKIP_DIRS, MAX_WALK_FILES = 5000, CACHE_FILE, key = (q, kind, c) => createHash("sha1").update(`${MODEL}\x00${kind}\x00${q}\x00${c.text}`).digest("hex"), CONFIG_FILE;
271
+ var init_jgrep = __esm(() => {
272
+ SKIP_DIRS = new Set(["node_modules", ".git", "dist", "build", ".next", "target", "vendor"]);
273
+ CACHE_FILE = path.join(os.homedir(), ".cache", "jgrep", "cache.json");
274
+ CONFIG_FILE = path.join(os.homedir(), ".config", "jgrep", "env");
275
+ });
276
+
277
+ // node_modules/fast-string-truncated-width/dist/utils.js
278
+ var getCodePointsLength, isFullWidth = (x) => {
279
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
280
+ }, isWideNotCJKTNotEmoji = (x) => {
281
+ return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
282
+ };
283
+ var init_utils = __esm(() => {
284
+ getCodePointsLength = (() => {
285
+ const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
286
+ return (input) => {
287
+ let surrogatePairsNr = 0;
288
+ SURROGATE_PAIR_RE.lastIndex = 0;
289
+ while (SURROGATE_PAIR_RE.test(input)) {
290
+ surrogatePairsNr += 1;
291
+ }
292
+ return input.length - surrogatePairsNr;
293
+ };
294
+ })();
295
+ });
296
+
297
+ // node_modules/fast-string-truncated-width/dist/index.js
298
+ var ANSI_RE, CONTROL_RE, CJKT_WIDE_RE, TAB_RE, EMOJI_RE, LATIN_RE, MODIFIER_RE, NO_TRUNCATION, getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
299
+ const LIMIT = truncationOptions.limit ?? Infinity;
300
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
301
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
302
+ const ANSI_WIDTH = 0;
303
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
304
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
305
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
306
+ const FULL_WIDTH_WIDTH = 2;
307
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
308
+ const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
309
+ const PARSE_BLOCKS = [
310
+ [LATIN_RE, REGULAR_WIDTH],
311
+ [ANSI_RE, ANSI_WIDTH],
312
+ [CONTROL_RE, CONTROL_WIDTH],
313
+ [TAB_RE, TAB_WIDTH],
314
+ [EMOJI_RE, EMOJI_WIDTH],
315
+ [CJKT_WIDE_RE, WIDE_WIDTH]
316
+ ];
317
+ let indexPrev = 0;
318
+ let index = 0;
319
+ let length = input.length;
320
+ let lengthExtra = 0;
321
+ let truncationEnabled = false;
322
+ let truncationIndex = length;
323
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
324
+ let unmatchedStart = 0;
325
+ let unmatchedEnd = 0;
326
+ let width = 0;
327
+ let widthExtra = 0;
328
+ outer:
329
+ while (true) {
330
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
331
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
332
+ lengthExtra = 0;
333
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
334
+ const codePoint = char.codePointAt(0) || 0;
335
+ if (isFullWidth(codePoint)) {
336
+ widthExtra = FULL_WIDTH_WIDTH;
337
+ } else if (isWideNotCJKTNotEmoji(codePoint)) {
338
+ widthExtra = WIDE_WIDTH;
339
+ } else {
340
+ widthExtra = REGULAR_WIDTH;
341
+ }
342
+ if (width + widthExtra > truncationLimit) {
343
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
344
+ }
345
+ if (width + widthExtra > LIMIT) {
346
+ truncationEnabled = true;
347
+ break outer;
348
+ }
349
+ lengthExtra += char.length;
350
+ width += widthExtra;
351
+ }
352
+ unmatchedStart = unmatchedEnd = 0;
353
+ }
354
+ if (index >= length) {
355
+ break outer;
356
+ }
357
+ for (let i = 0, l = PARSE_BLOCKS.length;i < l; i++) {
358
+ const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
359
+ BLOCK_RE.lastIndex = index;
360
+ if (BLOCK_RE.test(input)) {
361
+ lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
362
+ widthExtra = lengthExtra * BLOCK_WIDTH;
363
+ if (width + widthExtra > truncationLimit) {
364
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
365
+ }
366
+ if (width + widthExtra > LIMIT) {
367
+ truncationEnabled = true;
368
+ break outer;
369
+ }
370
+ width += widthExtra;
371
+ unmatchedStart = indexPrev;
372
+ unmatchedEnd = index;
373
+ index = indexPrev = BLOCK_RE.lastIndex;
374
+ continue outer;
375
+ }
376
+ }
377
+ index += 1;
378
+ }
379
+ return {
380
+ width: truncationEnabled ? truncationLimit : width,
381
+ index: truncationEnabled ? truncationIndex : length,
382
+ truncated: truncationEnabled,
383
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
384
+ };
385
+ }, dist_default;
386
+ var init_dist = __esm(() => {
387
+ init_utils();
388
+ ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
389
+ CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
390
+ 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;
391
+ TAB_RE = /\t{1,1000}/y;
392
+ EMOJI_RE = /[\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;
393
+ LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
394
+ MODIFIER_RE = /\p{M}+/gu;
395
+ NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
396
+ dist_default = getStringTruncatedWidth;
397
+ });
398
+
399
+ // node_modules/fast-string-width/dist/index.js
400
+ var NO_TRUNCATION2, fastStringWidth = (input, options = {}) => {
401
+ return dist_default(input, NO_TRUNCATION2, options).width;
402
+ }, dist_default2;
403
+ var init_dist2 = __esm(() => {
404
+ init_dist();
405
+ NO_TRUNCATION2 = {
406
+ limit: Infinity,
407
+ ellipsis: "",
408
+ ellipsisWidth: 0
409
+ };
410
+ dist_default2 = fastStringWidth;
411
+ });
412
+
413
+ // node_modules/fast-wrap-ansi/lib/main.js
414
+ function wrapAnsi(string, columns, options) {
415
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join(`
416
+ `);
417
+ }
418
+ var ESC = "\x1B", CSI = "›", END_CODE = 39, ANSI_ESCAPE_BELL = "\x07", ANSI_CSI = "[", ANSI_OSC = "]", ANSI_SGR_TERMINATOR = "m", ANSI_ESCAPE_LINK, GROUP_REGEX, getClosingCode = (openingCode) => {
419
+ if (openingCode >= 30 && openingCode <= 37)
420
+ return 39;
421
+ if (openingCode >= 90 && openingCode <= 97)
422
+ return 39;
423
+ if (openingCode >= 40 && openingCode <= 47)
424
+ return 49;
425
+ if (openingCode >= 100 && openingCode <= 107)
426
+ return 49;
427
+ if (openingCode === 1 || openingCode === 2)
428
+ return 22;
429
+ if (openingCode === 3)
430
+ return 23;
431
+ if (openingCode === 4)
432
+ return 24;
433
+ if (openingCode === 7)
434
+ return 27;
435
+ if (openingCode === 8)
436
+ return 28;
437
+ if (openingCode === 9)
438
+ return 29;
439
+ if (openingCode === 0)
440
+ return 0;
441
+ return;
442
+ }, wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`, wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`, wrapWord = (rows, word, columns) => {
443
+ const characters = word[Symbol.iterator]();
444
+ let isInsideEscape = false;
445
+ let isInsideLinkEscape = false;
446
+ let lastRow = rows.at(-1);
447
+ let visible = lastRow === undefined ? 0 : dist_default2(lastRow);
448
+ let currentCharacter = characters.next();
449
+ let nextCharacter = characters.next();
450
+ let rawCharacterIndex = 0;
451
+ while (!currentCharacter.done) {
452
+ const character = currentCharacter.value;
453
+ const characterLength = dist_default2(character);
454
+ if (visible + characterLength <= columns) {
455
+ rows[rows.length - 1] += character;
456
+ } else {
457
+ rows.push(character);
458
+ visible = 0;
459
+ }
460
+ if (character === ESC || character === CSI) {
461
+ isInsideEscape = true;
462
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
463
+ }
464
+ if (isInsideEscape) {
465
+ if (isInsideLinkEscape) {
466
+ if (character === ANSI_ESCAPE_BELL) {
467
+ isInsideEscape = false;
468
+ isInsideLinkEscape = false;
469
+ }
470
+ } else if (character === ANSI_SGR_TERMINATOR) {
471
+ isInsideEscape = false;
472
+ }
473
+ } else {
474
+ visible += characterLength;
475
+ if (visible === columns && !nextCharacter.done) {
476
+ rows.push("");
477
+ visible = 0;
478
+ }
479
+ }
480
+ currentCharacter = nextCharacter;
481
+ nextCharacter = characters.next();
482
+ rawCharacterIndex += character.length;
483
+ }
484
+ lastRow = rows.at(-1);
485
+ if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
486
+ rows[rows.length - 2] += rows.pop();
487
+ }
488
+ }, stringVisibleTrimSpacesRight = (string) => {
489
+ const words = string.split(" ");
490
+ let last = words.length;
491
+ while (last) {
492
+ if (dist_default2(words[last - 1])) {
493
+ break;
494
+ }
495
+ last--;
496
+ }
497
+ if (last === words.length) {
498
+ return string;
499
+ }
500
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
501
+ }, exec = (string, columns, options = {}) => {
502
+ if (options.trim !== false && string.trim() === "") {
503
+ return "";
504
+ }
505
+ let returnValue = "";
506
+ let escapeCode;
507
+ let escapeUrl;
508
+ const words = string.split(" ");
509
+ let rows = [""];
510
+ let rowLength = 0;
511
+ for (let index = 0;index < words.length; index++) {
512
+ const word = words[index];
513
+ if (options.trim !== false) {
514
+ const row = rows.at(-1) ?? "";
515
+ const trimmed = row.trimStart();
516
+ if (row.length !== trimmed.length) {
517
+ rows[rows.length - 1] = trimmed;
518
+ rowLength = dist_default2(trimmed);
519
+ }
520
+ }
521
+ if (index !== 0) {
522
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
523
+ rows.push("");
524
+ rowLength = 0;
525
+ }
526
+ if (rowLength || options.trim === false) {
527
+ rows[rows.length - 1] += " ";
528
+ rowLength++;
529
+ }
530
+ }
531
+ const wordLength = dist_default2(word);
532
+ if (options.hard && wordLength > columns) {
533
+ const remainingColumns = columns - rowLength;
534
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
535
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
536
+ if (breaksStartingNextLine < breaksStartingThisLine) {
537
+ rows.push("");
538
+ }
539
+ wrapWord(rows, word, columns);
540
+ rowLength = dist_default2(rows.at(-1) ?? "");
541
+ continue;
542
+ }
543
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
544
+ if (options.wordWrap === false && rowLength < columns) {
545
+ wrapWord(rows, word, columns);
546
+ rowLength = dist_default2(rows.at(-1) ?? "");
547
+ continue;
548
+ }
549
+ rows.push("");
550
+ rowLength = 0;
551
+ }
552
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
553
+ wrapWord(rows, word, columns);
554
+ rowLength = dist_default2(rows.at(-1) ?? "");
555
+ continue;
556
+ }
557
+ rows[rows.length - 1] += word;
558
+ rowLength += wordLength;
559
+ }
560
+ if (options.trim !== false) {
561
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
562
+ }
563
+ const preString = rows.join(`
564
+ `);
565
+ let inSurrogate = false;
566
+ for (let i = 0;i < preString.length; i++) {
567
+ const character = preString[i];
568
+ returnValue += character;
569
+ if (!inSurrogate) {
570
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
571
+ if (inSurrogate) {
572
+ continue;
573
+ }
574
+ } else {
575
+ inSurrogate = false;
576
+ }
577
+ if (character === ESC || character === CSI) {
578
+ GROUP_REGEX.lastIndex = i + 1;
579
+ const groupsResult = GROUP_REGEX.exec(preString);
580
+ const groups = groupsResult?.groups;
581
+ if (groups?.code !== undefined) {
582
+ const code = Number.parseFloat(groups.code);
583
+ escapeCode = code === END_CODE ? undefined : code;
584
+ } else if (groups?.uri !== undefined) {
585
+ escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
586
+ }
587
+ }
588
+ if (preString[i + 1] === `
589
+ `) {
590
+ if (escapeUrl) {
591
+ returnValue += wrapAnsiHyperlink("");
592
+ }
593
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
594
+ if (escapeCode && closingCode) {
595
+ returnValue += wrapAnsiCode(closingCode);
596
+ }
597
+ } else if (character === `
598
+ `) {
599
+ if (escapeCode && getClosingCode(escapeCode)) {
600
+ returnValue += wrapAnsiCode(escapeCode);
601
+ }
602
+ if (escapeUrl) {
603
+ returnValue += wrapAnsiHyperlink(escapeUrl);
604
+ }
605
+ }
606
+ }
607
+ return returnValue;
608
+ }, CRLF_OR_LF;
609
+ var init_main = __esm(() => {
610
+ init_dist2();
611
+ ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
612
+ GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
613
+ CRLF_OR_LF = /\r?\n/;
614
+ });
615
+
616
+ // node_modules/sisteransi/src/index.js
617
+ var require_src = __commonJS((exports, module) => {
618
+ var ESC2 = "\x1B";
619
+ var CSI2 = `${ESC2}[`;
620
+ var beep = "\x07";
621
+ var cursor = {
622
+ to(x, y) {
623
+ if (!y)
624
+ return `${CSI2}${x + 1}G`;
625
+ return `${CSI2}${y + 1};${x + 1}H`;
626
+ },
627
+ move(x, y) {
628
+ let ret = "";
629
+ if (x < 0)
630
+ ret += `${CSI2}${-x}D`;
631
+ else if (x > 0)
632
+ ret += `${CSI2}${x}C`;
633
+ if (y < 0)
634
+ ret += `${CSI2}${-y}A`;
635
+ else if (y > 0)
636
+ ret += `${CSI2}${y}B`;
637
+ return ret;
638
+ },
639
+ up: (count = 1) => `${CSI2}${count}A`,
640
+ down: (count = 1) => `${CSI2}${count}B`,
641
+ forward: (count = 1) => `${CSI2}${count}C`,
642
+ backward: (count = 1) => `${CSI2}${count}D`,
643
+ nextLine: (count = 1) => `${CSI2}E`.repeat(count),
644
+ prevLine: (count = 1) => `${CSI2}F`.repeat(count),
645
+ left: `${CSI2}G`,
646
+ hide: `${CSI2}?25l`,
647
+ show: `${CSI2}?25h`,
648
+ save: `${ESC2}7`,
649
+ restore: `${ESC2}8`
650
+ };
651
+ var scroll = {
652
+ up: (count = 1) => `${CSI2}S`.repeat(count),
653
+ down: (count = 1) => `${CSI2}T`.repeat(count)
654
+ };
655
+ var erase = {
656
+ screen: `${CSI2}2J`,
657
+ up: (count = 1) => `${CSI2}1J`.repeat(count),
658
+ down: (count = 1) => `${CSI2}J`.repeat(count),
659
+ line: `${CSI2}2K`,
660
+ lineEnd: `${CSI2}K`,
661
+ lineStart: `${CSI2}1K`,
662
+ lines(count) {
663
+ let clear = "";
664
+ for (let i = 0;i < count; i++)
665
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
666
+ if (count)
667
+ clear += cursor.left;
668
+ return clear;
669
+ }
670
+ };
671
+ module.exports = { cursor, scroll, erase, beep };
672
+ });
673
+
674
+ // node_modules/@clack/core/dist/index.mjs
675
+ import { styleText } from "node:util";
676
+ import { stdout, stdin } from "node:process";
677
+ import * as l from "node:readline";
678
+ import l__default from "node:readline";
679
+ import { ReadStream } from "node:tty";
680
+ function findCursor(s, o, l2) {
681
+ if (!l2.some((r) => !r.disabled))
682
+ return s;
683
+ const t = s + o, n = Math.max(l2.length - 1, 0), e = t < 0 ? n : t > n ? 0 : t;
684
+ return l2[e]?.disabled ? findCursor(e, o < 0 ? -1 : 1, l2) : e;
685
+ }
686
+ function findTextCursor(s, o, l2, i) {
687
+ const t = i.split(`
688
+ `);
689
+ let n = 0, e = s;
690
+ for (const r of t) {
691
+ if (e <= r.length)
692
+ break;
693
+ e -= r.length + 1, n++;
694
+ }
695
+ for (n = Math.max(0, Math.min(t.length - 1, n + l2)), e = Math.min(e, t[n].length) + o;e < 0 && n > 0; )
696
+ n--, e += t[n].length + 1;
697
+ for (;e > t[n].length && n < t.length - 1; )
698
+ e -= t[n].length + 1, n++;
699
+ e = Math.max(0, Math.min(t[n].length, e));
700
+ let h = 0;
701
+ for (let r = 0;r < n; r++)
702
+ h += t[r].length + 1;
703
+ return h + e;
704
+ }
705
+ function isAccessible(n) {
706
+ if (n !== undefined)
707
+ return n;
708
+ if (settings.accessible !== undefined)
709
+ return settings.accessible;
710
+ const e = process.env.ACCESSIBLE;
711
+ return e !== undefined && e !== "" && e !== "0" && e !== "false";
712
+ }
713
+ function isActionKey(n, e) {
714
+ if (typeof n == "string")
715
+ return settings.aliases.get(n) === e;
716
+ for (const s of n)
717
+ if (s !== undefined && isActionKey(s, e))
718
+ return true;
719
+ return false;
720
+ }
721
+ function diffLines(i, s) {
722
+ if (i === s)
723
+ return;
724
+ const e = i.split(`
725
+ `), t2 = s.split(`
726
+ `), r = Math.max(e.length, t2.length), f = [];
727
+ for (let n = 0;n < r; n++)
728
+ e[n] !== t2[n] && f.push(n);
729
+ return {
730
+ lines: f,
731
+ numLinesBefore: e.length,
732
+ numLinesAfter: t2.length,
733
+ numLines: r
734
+ };
735
+ }
736
+ function isCancel(e) {
737
+ return e === CANCEL_SYMBOL;
738
+ }
739
+ function setRawMode(e, r) {
740
+ const o = e;
741
+ o.isTTY && o.setRawMode(r);
742
+ }
743
+ function block({
744
+ input: e = stdin,
745
+ output: r = stdout,
746
+ overwrite: o = true,
747
+ hideCursor: n = true
748
+ } = {}) {
749
+ const s = l.createInterface({
750
+ input: e,
751
+ output: r,
752
+ prompt: "",
753
+ tabSize: 1
754
+ });
755
+ l.emitKeypressEvents(e, s), e instanceof ReadStream && e.isTTY && e.setRawMode(true);
756
+ const t2 = (f, { name: a, sequence: w }) => {
757
+ const c = String(f);
758
+ if (isActionKey([c, a, w], "cancel")) {
759
+ n && r.write(import_sisteransi.cursor.show), process.exit(0);
760
+ return;
761
+ }
762
+ if (!o)
763
+ return;
764
+ const i = a === "return" ? 0 : -1, m = a === "return" ? -1 : 0;
765
+ l.moveCursor(r, i, m, () => {
766
+ l.clearLine(r, 1, () => {
767
+ e.once("keypress", t2);
768
+ });
769
+ });
770
+ };
771
+ return n && r.write(import_sisteransi.cursor.hide), e.once("keypress", t2), () => {
772
+ e.off("keypress", t2), n && r.write(import_sisteransi.cursor.show), e instanceof ReadStream && e.isTTY && !R && e.setRawMode(false), s.terminal = false, s.close();
773
+ };
774
+ }
775
+ function wrapTextWithPrefix(e, r, o, n = o, s = o, t2) {
776
+ const f = getColumns(e ?? stdout);
777
+ return wrapAnsi(r, f - o.length, {
778
+ hard: true,
779
+ trim: false
780
+ }).split(`
781
+ `).map((c, i, m) => {
782
+ const d = t2 ? t2(c, i) : c;
783
+ return i === 0 ? `${n}${d}` : i === m.length - 1 ? `${s}${d}` : `${o}${d}`;
784
+ }).join(`
785
+ `);
786
+ }
787
+ function runValidation(e, a) {
788
+ if ("~standard" in e) {
789
+ const n = e["~standard"].validate(a);
790
+ return n instanceof Promise ? n.then((r) => r.issues?.at(0)?.message) : n.issues?.at(0)?.message;
791
+ }
792
+ return e(a);
793
+ }
794
+
795
+ class y {
796
+ input;
797
+ output;
798
+ _abortSignal;
799
+ rl;
800
+ opts;
801
+ _render;
802
+ _track = false;
803
+ _prevFrame = "";
804
+ _subscribers = /* @__PURE__ */ new Map;
805
+ _cursor = 0;
806
+ state = "initial";
807
+ error = "";
808
+ value;
809
+ userInput = "";
810
+ get accessible() {
811
+ return isAccessible(this.opts.accessible);
812
+ }
813
+ constructor(t2, e = true) {
814
+ const { input: i = stdin, output: s = stdout, render: r, signal: n, ...o } = t2;
815
+ this.opts = o, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = r.bind(this), this._track = e, this._abortSignal = n, this.input = i, this.output = s;
816
+ }
817
+ unsubscribe() {
818
+ this._subscribers.clear();
819
+ }
820
+ setSubscriber(t2, e) {
821
+ const i = this._subscribers.get(t2) ?? [];
822
+ i.push(e), this._subscribers.set(t2, i);
823
+ }
824
+ on(t2, e) {
825
+ this.setSubscriber(t2, { cb: e });
826
+ }
827
+ once(t2, e) {
828
+ this.setSubscriber(t2, { cb: e, once: true });
829
+ }
830
+ emit(t2, ...e) {
831
+ const i = this._subscribers.get(t2) ?? [], s = [];
832
+ for (const r of i)
833
+ r.cb(...e), r.once && s.push(() => i.splice(i.indexOf(r), 1));
834
+ for (const r of s)
835
+ r();
836
+ }
837
+ prompt() {
838
+ return new Promise((t2) => {
839
+ if (this._abortSignal) {
840
+ if (this._abortSignal.aborted)
841
+ return this.state = "cancel", this.close(), t2(CANCEL_SYMBOL);
842
+ this._abortSignal.addEventListener("abort", () => {
843
+ this.state = "cancel", this.close();
844
+ }, { once: true });
845
+ }
846
+ this.rl = l__default.createInterface({
847
+ input: this.input,
848
+ tabSize: 2,
849
+ prompt: "",
850
+ escapeCodeTimeout: 50,
851
+ terminal: true
852
+ }), this.rl.prompt(), this.opts.initialUserInput !== undefined && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), setRawMode(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
853
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(this.value);
854
+ }), this.once("cancel", () => {
855
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(CANCEL_SYMBOL);
856
+ });
857
+ });
858
+ }
859
+ _isActionKey(t2, e) {
860
+ return t2 === "\t";
861
+ }
862
+ _shouldSubmit(t2, e) {
863
+ return true;
864
+ }
865
+ _setValue(t2) {
866
+ this.value = t2, this.emit("value", this.value);
867
+ }
868
+ _setUserInput(t2, e) {
869
+ this.userInput = t2 ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
870
+ }
871
+ _clearUserInput() {
872
+ this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
873
+ }
874
+ async onKeypress(t2, e) {
875
+ if (this.state !== "validating") {
876
+ if (this._track && e.name !== "return" && (e.name && this._isActionKey(t2, e) && 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"), e?.name && (!this._track && settings.aliases.has(e.name) && this.emit("cursor", settings.aliases.get(e.name)), settings.actions.has(e.name) && this.emit("cursor", e.name)), t2 && (t2.toLowerCase() === "y" || t2.toLowerCase() === "n") && this.emit("confirm", t2.toLowerCase() === "y"), this.emit("key", t2, e), e?.name === "return" && this._shouldSubmit(t2, e)) {
877
+ if (this.opts.validate) {
878
+ const i = runValidation(this.opts.validate, this.value);
879
+ let s;
880
+ i instanceof Promise ? (this.state = "validating", this.render(), s = await i) : s = i, s && (this.error = s instanceof Error ? s.message : s, this.state = "error", this.rl?.write(this.userInput));
881
+ }
882
+ this.state !== "error" && (this.state = "submit");
883
+ }
884
+ isActionKey([t2, e?.name, e?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
885
+ }
886
+ }
887
+ close() {
888
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
889
+ `), setRawMode(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
890
+ }
891
+ restoreCursor() {
892
+ const t2 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
893
+ `).length - 1;
894
+ this.output.write(import_sisteransi.cursor.move(-999, t2 * -1));
895
+ }
896
+ render() {
897
+ const t2 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, {
898
+ hard: true,
899
+ trim: false
900
+ });
901
+ if (t2 !== this._prevFrame) {
902
+ if (this.state === "initial")
903
+ this.output.write(import_sisteransi.cursor.hide);
904
+ else {
905
+ const e = diffLines(this._prevFrame, t2), i = getRows(this.output);
906
+ if (this.restoreCursor(), e) {
907
+ const s = Math.max(0, e.numLinesAfter - i), r = Math.max(0, e.numLinesBefore - i);
908
+ let n = e.lines.find((o) => o >= s);
909
+ if (n === undefined) {
910
+ this._prevFrame = t2;
911
+ return;
912
+ }
913
+ if (e.lines.length === 1) {
914
+ this.output.write(import_sisteransi.cursor.move(0, n - r)), this.output.write(import_sisteransi.erase.lines(1));
915
+ const o = t2.split(`
916
+ `);
917
+ this.output.write(o[n]), this._prevFrame = t2, this.output.write(import_sisteransi.cursor.move(0, o.length - n - 1));
918
+ return;
919
+ } else if (e.lines.length > 1) {
920
+ if (s < r)
921
+ n = s;
922
+ else {
923
+ const h = n - r;
924
+ h > 0 && this.output.write(import_sisteransi.cursor.move(0, h));
925
+ }
926
+ this.output.write(import_sisteransi.erase.down());
927
+ const f = t2.split(`
928
+ `).slice(n);
929
+ this.output.write(f.join(`
930
+ `)), this._prevFrame = t2;
931
+ return;
932
+ }
933
+ }
934
+ this.output.write(import_sisteransi.erase.down());
935
+ }
936
+ this.output.write(t2), this.state === "initial" && (this.state = "active"), this._prevFrame = t2;
937
+ }
938
+ }
939
+ }
940
+ function p$1(l2, e) {
941
+ if (l2 === undefined || e.length === 0)
942
+ return 0;
943
+ const i = e.findIndex((s) => s.value === l2);
944
+ return i !== -1 ? i : 0;
945
+ }
946
+ function m(l2, e) {
947
+ return (e.label ?? String(e.value)).toLowerCase().includes(l2.toLowerCase());
948
+ }
949
+ function g(l2, e) {
950
+ if (e)
951
+ return l2 ? e : e[0];
952
+ }
953
+ function M(r2) {
954
+ return [...r2].map((t2) => _[t2]);
955
+ }
956
+ function P(r2) {
957
+ const i = new Intl.DateTimeFormat(r2, {
958
+ year: "numeric",
959
+ month: "2-digit",
960
+ day: "2-digit"
961
+ }).formatToParts(new Date(2000, 0, 15)), s = [];
962
+ let n = "/";
963
+ for (const e of i)
964
+ e.type === "literal" ? n = e.value.trim() || e.value : (e.type === "year" || e.type === "month" || e.type === "day") && s.push({ type: e.type, len: e.type === "year" ? 4 : 2 });
965
+ return { segments: s, separator: n };
966
+ }
967
+ function p(r2) {
968
+ return Number.parseInt((r2 || "0").replace(/_/g, "0"), 10) || 0;
969
+ }
970
+ function f(r2) {
971
+ return {
972
+ year: p(r2.year),
973
+ month: p(r2.month),
974
+ day: p(r2.day)
975
+ };
976
+ }
977
+ function c(r2, t2) {
978
+ return new Date(r2 || 2001, t2 || 1, 0).getDate();
979
+ }
980
+ function b(r2) {
981
+ const { year: t2, month: i, day: s } = f(r2);
982
+ if (!t2 || t2 < 0 || t2 > 9999 || !i || i < 1 || i > 12 || !s || s < 1)
983
+ return;
984
+ const n = new Date(Date.UTC(t2, i - 1, s));
985
+ if (!(n.getUTCFullYear() !== t2 || n.getUTCMonth() !== i - 1 || n.getUTCDate() !== s))
986
+ return { year: t2, month: i, day: s };
987
+ }
988
+ function C(r2) {
989
+ const t2 = b(r2);
990
+ return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
991
+ }
992
+ function T2(r2, t2, i, s) {
993
+ const n = i ? {
994
+ year: i.getUTCFullYear(),
995
+ month: i.getUTCMonth() + 1,
996
+ day: i.getUTCDate()
997
+ } : null, e = s ? {
998
+ year: s.getUTCFullYear(),
999
+ month: s.getUTCMonth() + 1,
1000
+ day: s.getUTCDate()
1001
+ } : null;
1002
+ return r2 === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r2 === "month" ? {
1003
+ min: n && t2.year === n.year ? n.month : 1,
1004
+ max: e && t2.year === e.year ? e.month : 12
1005
+ } : {
1006
+ min: n && t2.year === n.year && t2.month === n.month ? n.day : 1,
1007
+ max: e && t2.year === e.year && t2.month === e.month ? e.day : c(t2.year, t2.month)
1008
+ };
1009
+ }
1010
+ var import_sisteransi, a$1, t, settings, R, CANCEL_SYMBOL, getColumns = (e) => ("columns" in e) && typeof e.columns == "number" ? e.columns : 80, getRows = (e) => ("rows" in e) && typeof e.rows == "number" ? e.rows : 20, T$1, r, _, U, u$2, o, h, a, u$1, n$1;
1011
+ var init_dist3 = __esm(() => {
1012
+ init_main();
1013
+ import_sisteransi = __toESM(require_src(), 1);
1014
+ a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
1015
+ t = [
1016
+ "January",
1017
+ "February",
1018
+ "March",
1019
+ "April",
1020
+ "May",
1021
+ "June",
1022
+ "July",
1023
+ "August",
1024
+ "September",
1025
+ "October",
1026
+ "November",
1027
+ "December"
1028
+ ];
1029
+ settings = {
1030
+ actions: new Set(a$1),
1031
+ aliases: /* @__PURE__ */ new Map([
1032
+ ["k", "up"],
1033
+ ["j", "down"],
1034
+ ["h", "left"],
1035
+ ["l", "right"],
1036
+ ["\x03", "cancel"],
1037
+ ["escape", "cancel"]
1038
+ ]),
1039
+ messages: {
1040
+ cancel: "Canceled",
1041
+ error: "Something went wrong"
1042
+ },
1043
+ withGuide: true,
1044
+ accessible: undefined,
1045
+ date: {
1046
+ monthNames: [...t],
1047
+ messages: {
1048
+ required: "Please enter a valid date",
1049
+ invalidMonth: "There are only 12 months in a year",
1050
+ invalidDay: (n, e) => `There are only ${n} days in ${e}`,
1051
+ afterMin: (n) => `Date must be on or after ${n.toISOString().slice(0, 10)}`,
1052
+ beforeMax: (n) => `Date must be on or before ${n.toISOString().slice(0, 10)}`
1053
+ }
1054
+ }
1055
+ };
1056
+ R = globalThis.process.platform.startsWith("win");
1057
+ CANCEL_SYMBOL = Symbol("clack:cancel");
1058
+ T$1 = class T extends y {
1059
+ filteredOptions;
1060
+ multiple;
1061
+ isNavigating = false;
1062
+ selectedValues = [];
1063
+ focusedValue;
1064
+ #e = 0;
1065
+ #s = "";
1066
+ #t;
1067
+ #i;
1068
+ #n;
1069
+ #l;
1070
+ get cursor() {
1071
+ return this.#e;
1072
+ }
1073
+ get userInputWithCursor() {
1074
+ if (!this.userInput)
1075
+ return styleText(["inverse", "hidden"], "_");
1076
+ if (this._cursor >= this.userInput.length)
1077
+ return `${this.userInput}█`;
1078
+ const e = this.userInput.slice(0, this.cursor), t2 = this.userInput.slice(this.cursor, this.cursor + 1), i = this.userInput.slice(this.cursor + 1);
1079
+ return `${e}${styleText("inverse", t2)}${i}`;
1080
+ }
1081
+ get options() {
1082
+ return typeof this.#i == "function" ? this.#i() : this.#i;
1083
+ }
1084
+ constructor(e) {
1085
+ super(e), this.#i = e.options, this.#n = e.placeholder, this.#l = e.completeOnTab === true;
1086
+ const t2 = this.options;
1087
+ this.filteredOptions = [...t2], this.multiple = e.multiple === true, this.#t = typeof e.options == "function" ? e.filter : e.filter ?? m;
1088
+ let i;
1089
+ if (e.initialValue && Array.isArray(e.initialValue) ? this.multiple ? i = e.initialValue : i = e.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (i = [this.options[0]?.value]), i)
1090
+ for (const s of i) {
1091
+ const n = t2.findIndex((r) => r.value === s);
1092
+ n !== -1 && (this.toggleSelected(s), this.#e = n);
1093
+ }
1094
+ this.focusedValue = this.options[this.#e]?.value, this.on("key", (s, n) => this.#u(s, n)), this.on("userInput", (s) => this.#o(s));
1095
+ }
1096
+ _isActionKey(e, t2) {
1097
+ return e === "\t" || this.multiple && this.isNavigating && t2.name === "space" && e !== undefined && e !== "";
1098
+ }
1099
+ #u(e, t2) {
1100
+ const i = t2.name === "up", s = t2.name === "down", n = t2.name === "return", r = this.userInput === "" || this.userInput === "\t", u = this.#n, d = this.options, c = u !== undefined && u !== "" && d.some((o) => !o.disabled && (this.#t ? this.#t(u, o) : true));
1101
+ if (t2.name === "tab" && r && c) {
1102
+ this.userInput === "\t" && this._clearUserInput(), this._setUserInput(u, true), this.isNavigating = false;
1103
+ return;
1104
+ }
1105
+ if (t2.name === "tab" && this.#l && !this.multiple && this.focusedValue !== undefined) {
1106
+ const o = String(this.focusedValue);
1107
+ this._clearUserInput(), this._setUserInput(o, true), this.isNavigating = false;
1108
+ return;
1109
+ }
1110
+ i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = g(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (t2.name === "tab" || this.isNavigating && t2.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
1111
+ }
1112
+ deselectAll() {
1113
+ this.selectedValues = [];
1114
+ }
1115
+ toggleSelected(e) {
1116
+ this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(e) ? this.selectedValues = this.selectedValues.filter((t2) => t2 !== e) : this.selectedValues = [...this.selectedValues, e] : this.selectedValues = [e]);
1117
+ }
1118
+ #o(e) {
1119
+ if (e !== this.#s) {
1120
+ this.#s = e;
1121
+ const t2 = this.options;
1122
+ e && this.#t ? this.filteredOptions = t2.filter((n) => this.#t?.(e, n)) : this.filteredOptions = [...t2];
1123
+ const i = p$1(this.focusedValue, this.filteredOptions);
1124
+ this.#e = findCursor(i, 0, this.filteredOptions);
1125
+ const s = this.filteredOptions[this.#e];
1126
+ s && !s.disabled ? this.focusedValue = s.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
1127
+ }
1128
+ }
1129
+ };
1130
+ r = class r extends y {
1131
+ get cursor() {
1132
+ return this.value ? 0 : 1;
1133
+ }
1134
+ get _value() {
1135
+ return this.cursor === 0;
1136
+ }
1137
+ constructor(t2) {
1138
+ super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
1139
+ this.value = this._value;
1140
+ }), this.on("confirm", (i) => {
1141
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i, this.state = "submit", this.close();
1142
+ }), this.on("cursor", () => {
1143
+ this.value = !this.value;
1144
+ });
1145
+ }
1146
+ };
1147
+ _ = {
1148
+ Y: { type: "year", len: 4 },
1149
+ M: { type: "month", len: 2 },
1150
+ D: { type: "day", len: 2 }
1151
+ };
1152
+ U = class U extends y {
1153
+ #i;
1154
+ #o;
1155
+ #t;
1156
+ #h;
1157
+ #u;
1158
+ #e = { segmentIndex: 0, positionInSegment: 0 };
1159
+ #n = true;
1160
+ #s = null;
1161
+ inlineError = "";
1162
+ get segmentCursor() {
1163
+ return { ...this.#e };
1164
+ }
1165
+ get segmentValues() {
1166
+ return { ...this.#t };
1167
+ }
1168
+ get segments() {
1169
+ return this.#i;
1170
+ }
1171
+ get separator() {
1172
+ return this.#o;
1173
+ }
1174
+ get formattedValue() {
1175
+ return this.#l(this.#t);
1176
+ }
1177
+ #l(t2) {
1178
+ return this.#i.map((i) => t2[i.type]).join(this.#o);
1179
+ }
1180
+ #r() {
1181
+ this._setUserInput(this.#l(this.#t)), this._setValue(C(this.#t) ?? undefined);
1182
+ }
1183
+ constructor(t2) {
1184
+ const i = t2.format ? { segments: M(t2.format), separator: t2.separator ?? "/" } : P(t2.locale), s = t2.separator ?? i.separator, n = t2.format ? M(t2.format) : i.segments, e = t2.initialValue ?? t2.defaultValue, m2 = e ? {
1185
+ year: String(e.getUTCFullYear()).padStart(4, "0"),
1186
+ month: String(e.getUTCMonth() + 1).padStart(2, "0"),
1187
+ day: String(e.getUTCDate()).padStart(2, "0")
1188
+ } : { year: "____", month: "__", day: "__" }, o = n.map((a) => m2[a.type]).join(s);
1189
+ super({ ...t2, initialUserInput: o }, false), this.#i = n, this.#o = s, this.#t = m2, this.#h = t2.minDate, this.#u = t2.maxDate, this.#r(), this.on("cursor", (a) => this.#f(a)), this.on("key", (a, u) => this.#y(a, u)), this.on("finalize", () => this.#p(t2));
1190
+ }
1191
+ #a() {
1192
+ const t2 = Math.max(0, Math.min(this.#e.segmentIndex, this.#i.length - 1)), i = this.#i[t2];
1193
+ if (i)
1194
+ return this.#e.positionInSegment = Math.max(0, Math.min(this.#e.positionInSegment, i.len - 1)), { segment: i, index: t2 };
1195
+ }
1196
+ #m(t2) {
1197
+ this.inlineError = "", this.#s = null;
1198
+ const i = this.#a();
1199
+ i && (this.#e.segmentIndex = Math.max(0, Math.min(this.#i.length - 1, i.index + t2)), this.#e.positionInSegment = 0, this.#n = true);
1200
+ }
1201
+ #d(t2) {
1202
+ const i = this.#a();
1203
+ if (!i)
1204
+ return;
1205
+ const { segment: s } = i, n = this.#t[s.type], e = !n || n.replace(/_/g, "") === "", m2 = Number.parseInt((n || "0").replace(/_/g, "0"), 10) || 0, o = T2(s.type, f(this.#t), this.#h, this.#u);
1206
+ let a;
1207
+ e ? a = t2 === 1 ? o.min : o.max : a = Math.max(Math.min(o.max, m2 + t2), o.min), this.#t = {
1208
+ ...this.#t,
1209
+ [s.type]: a.toString().padStart(s.len, "0")
1210
+ }, this.#n = true, this.#s = null, this.#r();
1211
+ }
1212
+ #f(t2) {
1213
+ if (t2)
1214
+ switch (t2) {
1215
+ case "right":
1216
+ return this.#m(1);
1217
+ case "left":
1218
+ return this.#m(-1);
1219
+ case "up":
1220
+ return this.#d(1);
1221
+ case "down":
1222
+ return this.#d(-1);
1223
+ }
1224
+ }
1225
+ #y(t2, i) {
1226
+ if (i?.name === "backspace" || i?.sequence === "" || i?.sequence === "\b" || t2 === "" || t2 === "\b") {
1227
+ this.inlineError = "";
1228
+ const n = this.#a();
1229
+ if (!n)
1230
+ return;
1231
+ if (!this.#t[n.segment.type].replace(/_/g, "")) {
1232
+ this.#m(-1);
1233
+ return;
1234
+ }
1235
+ this.#t[n.segment.type] = "_".repeat(n.segment.len), this.#n = true, this.#e.positionInSegment = 0, this.#r();
1236
+ return;
1237
+ }
1238
+ if (i?.name === "tab") {
1239
+ this.inlineError = "";
1240
+ const n = this.#a();
1241
+ if (!n)
1242
+ return;
1243
+ const e = i.shift ? -1 : 1, m2 = n.index + e;
1244
+ m2 >= 0 && m2 < this.#i.length && (this.#e.segmentIndex = m2, this.#e.positionInSegment = 0, this.#n = true);
1245
+ return;
1246
+ }
1247
+ if (t2 && /^[0-9]$/.test(t2)) {
1248
+ const n = this.#a();
1249
+ if (!n)
1250
+ return;
1251
+ const { segment: e } = n, m2 = !this.#t[e.type].replace(/_/g, "");
1252
+ if (this.#n && this.#s !== null && !m2) {
1253
+ const h = this.#s + t2, d = { ...this.#t, [e.type]: h }, g2 = this.#g(d, e);
1254
+ if (g2) {
1255
+ this.inlineError = g2, this.#s = null, this.#n = false;
1256
+ return;
1257
+ }
1258
+ this.inlineError = "", this.#t[e.type] = h, this.#s = null, this.#n = false, this.#r(), n.index < this.#i.length - 1 && (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true);
1259
+ return;
1260
+ }
1261
+ this.#n && !m2 && (this.#t[e.type] = "_".repeat(e.len), this.#e.positionInSegment = 0), this.#n = false, this.#s = null;
1262
+ const o = this.#t[e.type], a = o.indexOf("_"), u = a >= 0 ? a : Math.min(this.#e.positionInSegment, e.len - 1);
1263
+ if (u < 0 || u >= e.len)
1264
+ return;
1265
+ let l2 = o.slice(0, u) + t2 + o.slice(u + 1), D = false;
1266
+ if (u === 0 && o === "__" && (e.type === "month" || e.type === "day")) {
1267
+ const h = Number.parseInt(t2, 10);
1268
+ l2 = `0${t2}`, D = h <= (e.type === "month" ? 1 : 2);
1269
+ }
1270
+ if (e.type === "year" && (l2 = (o.replace(/_/g, "") + t2).padStart(e.len, "_")), !l2.includes("_")) {
1271
+ const h = { ...this.#t, [e.type]: l2 }, d = this.#g(h, e);
1272
+ if (d) {
1273
+ this.inlineError = d;
1274
+ return;
1275
+ }
1276
+ }
1277
+ this.inlineError = "", this.#t[e.type] = l2;
1278
+ const y2 = l2.includes("_") ? undefined : b(this.#t);
1279
+ if (y2) {
1280
+ const { year: h, month: d } = y2, g2 = c(h, d);
1281
+ this.#t = {
1282
+ year: String(Math.max(0, Math.min(9999, h))).padStart(4, "0"),
1283
+ month: String(Math.max(1, Math.min(12, d))).padStart(2, "0"),
1284
+ day: String(Math.max(1, Math.min(g2, y2.day))).padStart(2, "0")
1285
+ };
1286
+ }
1287
+ this.#r();
1288
+ const S = l2.indexOf("_");
1289
+ D ? (this.#n = true, this.#s = t2) : S >= 0 ? this.#e.positionInSegment = S : a >= 0 && n.index < this.#i.length - 1 ? (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true) : this.#e.positionInSegment = Math.min(u + 1, e.len - 1);
1290
+ }
1291
+ }
1292
+ #g(t2, i) {
1293
+ const { month: s, day: n } = f(t2);
1294
+ if (i.type === "month" && (s < 0 || s > 12))
1295
+ return settings.date.messages.invalidMonth;
1296
+ if (i.type === "day" && (n < 0 || n > 31))
1297
+ return settings.date.messages.invalidDay(31, "any month");
1298
+ }
1299
+ #p(t2) {
1300
+ const { year: i, month: s, day: n } = f(this.#t);
1301
+ if (i && s && n) {
1302
+ const e = c(i, s);
1303
+ this.#t = {
1304
+ ...this.#t,
1305
+ day: String(Math.min(n, e)).padStart(2, "0")
1306
+ };
1307
+ }
1308
+ this.value = C(this.#t) ?? t2.defaultValue ?? undefined;
1309
+ }
1310
+ };
1311
+ u$2 = class u extends y {
1312
+ options;
1313
+ cursor = 0;
1314
+ #t;
1315
+ getGroupItems(t2) {
1316
+ return this.options.filter((r2) => r2.group === t2);
1317
+ }
1318
+ isGroupSelected(t2) {
1319
+ const r2 = this.getGroupItems(t2), e = this.value;
1320
+ return e === undefined ? false : r2.every((s) => e.includes(s.value));
1321
+ }
1322
+ toggleValue() {
1323
+ const t2 = this.options[this.cursor];
1324
+ if (t2 !== undefined)
1325
+ if (this.value === undefined && (this.value = []), t2.group === true) {
1326
+ const r2 = t2.value, e = this.getGroupItems(r2);
1327
+ this.isGroupSelected(r2) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
1328
+ } else {
1329
+ const r2 = this.value.includes(t2.value);
1330
+ this.value = r2 ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
1331
+ }
1332
+ }
1333
+ constructor(t2) {
1334
+ super(t2, false);
1335
+ const { options: r2 } = t2;
1336
+ this.#t = t2.selectableGroups !== false, this.options = Object.entries(r2).flatMap(([e, s]) => [
1337
+ { value: e, group: true, label: e },
1338
+ ...s.map((i) => ({ ...i, group: e }))
1339
+ ]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t2.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
1340
+ switch (e) {
1341
+ case "left":
1342
+ case "up": {
1343
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
1344
+ const s = this.options[this.cursor]?.group === true;
1345
+ !this.#t && s && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
1346
+ break;
1347
+ }
1348
+ case "down":
1349
+ case "right": {
1350
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
1351
+ const s = this.options[this.cursor]?.group === true;
1352
+ !this.#t && s && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
1353
+ break;
1354
+ }
1355
+ case "space":
1356
+ this.toggleValue();
1357
+ break;
1358
+ }
1359
+ });
1360
+ }
1361
+ };
1362
+ o = /* @__PURE__ */ new Set(["up", "down", "left", "right"]);
1363
+ h = class h extends y {
1364
+ #t = false;
1365
+ #s;
1366
+ focused = "editor";
1367
+ get userInputWithCursor() {
1368
+ if (this.state === "submit")
1369
+ return this.userInput;
1370
+ const t2 = this.userInput;
1371
+ if (this.cursor >= t2.length)
1372
+ return `${t2}█`;
1373
+ const s = t2.slice(0, this.cursor), r2 = t2.slice(this.cursor, this.cursor + 1), i = t2.slice(this.cursor + 1);
1374
+ return r2 === `
1375
+ ` ? `${s}█
1376
+ ${i}` : `${s}${styleText("inverse", r2)}${i}`;
1377
+ }
1378
+ get cursor() {
1379
+ return this._cursor;
1380
+ }
1381
+ #r(t2) {
1382
+ if (this.userInput.length === 0) {
1383
+ this._setUserInput(t2);
1384
+ return;
1385
+ }
1386
+ this._setUserInput(this.userInput.slice(0, this.cursor) + t2 + this.userInput.slice(this.cursor));
1387
+ }
1388
+ #i(t2) {
1389
+ const s = this.value ?? "";
1390
+ switch (t2) {
1391
+ case "up":
1392
+ this._cursor = findTextCursor(this._cursor, 0, -1, s);
1393
+ return;
1394
+ case "down":
1395
+ this._cursor = findTextCursor(this._cursor, 0, 1, s);
1396
+ return;
1397
+ case "left":
1398
+ this._cursor = findTextCursor(this._cursor, -1, 0, s);
1399
+ return;
1400
+ case "right":
1401
+ this._cursor = findTextCursor(this._cursor, 1, 0, s);
1402
+ return;
1403
+ }
1404
+ }
1405
+ _shouldSubmit(t2, s) {
1406
+ if (this.#s)
1407
+ return this.focused === "submit" ? true : (this.#r(`
1408
+ `), this._cursor++, false);
1409
+ const r2 = this.#t;
1410
+ return this.#t = true, r2 && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
1411
+ ` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#r(`
1412
+ `), this._cursor++, false);
1413
+ }
1414
+ constructor(t2) {
1415
+ const s = t2.initialUserInput ?? t2.initialValue;
1416
+ super({
1417
+ ...t2,
1418
+ initialUserInput: s
1419
+ }, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r2, i) => {
1420
+ if (i?.name && o.has(i.name)) {
1421
+ this.#t = false, this.#i(i.name);
1422
+ return;
1423
+ }
1424
+ if (r2 === "\t" && this.#s) {
1425
+ this.focused = this.focused === "editor" ? "submit" : "editor";
1426
+ return;
1427
+ }
1428
+ if (i?.name !== "return") {
1429
+ if (this.#t = false, i?.name === "backspace" && this.cursor > 0) {
1430
+ this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--;
1431
+ return;
1432
+ }
1433
+ if (i?.name === "delete" && this.cursor < this.userInput.length) {
1434
+ this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
1435
+ return;
1436
+ }
1437
+ r2 && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r2 ?? ""), this._cursor++);
1438
+ }
1439
+ }), this.on("userInput", (r2) => {
1440
+ this._setValue(r2);
1441
+ }), this.on("finalize", () => {
1442
+ this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
1443
+ });
1444
+ }
1445
+ };
1446
+ a = class a extends y {
1447
+ options;
1448
+ cursor = 0;
1449
+ get _value() {
1450
+ return this.options[this.cursor]?.value;
1451
+ }
1452
+ get _enabledOptions() {
1453
+ return this.options.filter((e) => e.disabled !== true);
1454
+ }
1455
+ toggleAll() {
1456
+ const e = this._enabledOptions, i = this.value !== undefined && this.value.length === e.length;
1457
+ this.value = i ? [] : e.map((t2) => t2.value);
1458
+ }
1459
+ toggleInvert() {
1460
+ const e = this.value;
1461
+ if (!e)
1462
+ return;
1463
+ const i = this._enabledOptions.filter((t2) => !e.includes(t2.value));
1464
+ this.value = i.map((t2) => t2.value);
1465
+ }
1466
+ toggleValue() {
1467
+ this.value === undefined && (this.value = []);
1468
+ const e = this.value.includes(this._value);
1469
+ this.value = e ? this.value.filter((i) => i !== this._value) : [...this.value, this._value];
1470
+ }
1471
+ constructor(e) {
1472
+ super(e, false), this.options = e.options, this.value = [...e.initialValues ?? []];
1473
+ const i = Math.max(this.options.findIndex(({ value: t2 }) => t2 === e.cursorAt), 0);
1474
+ this.cursor = this.options[i]?.disabled ? findCursor(i, 1, this.options) : i, this.on("key", (t2, l2) => {
1475
+ l2.name === "a" && this.toggleAll(), l2.name === "i" && this.toggleInvert();
1476
+ }), this.on("cursor", (t2) => {
1477
+ switch (t2) {
1478
+ case "left":
1479
+ case "up":
1480
+ this.cursor = findCursor(this.cursor, -1, this.options);
1481
+ break;
1482
+ case "down":
1483
+ case "right":
1484
+ this.cursor = findCursor(this.cursor, 1, this.options);
1485
+ break;
1486
+ case "space":
1487
+ this.toggleValue();
1488
+ break;
1489
+ }
1490
+ });
1491
+ }
1492
+ };
1493
+ u$1 = class u2 extends y {
1494
+ _mask = "•";
1495
+ get cursor() {
1496
+ return this._cursor;
1497
+ }
1498
+ get masked() {
1499
+ return this.userInput.replaceAll(/./g, this._mask);
1500
+ }
1501
+ get userInputWithCursor() {
1502
+ if (this.state === "submit" || this.state === "cancel")
1503
+ return this.masked;
1504
+ const t2 = this.userInput;
1505
+ if (this.cursor >= t2.length)
1506
+ return `${this.masked}${styleText(["inverse", "hidden"], "_")}`;
1507
+ const s = this.masked, r2 = s.slice(0, this.cursor), i = s.slice(this.cursor, this.cursor + 1), o2 = s.slice(this.cursor + 1);
1508
+ return `${r2}${styleText("inverse", i)}${o2}`;
1509
+ }
1510
+ clear() {
1511
+ this._clearUserInput();
1512
+ }
1513
+ constructor({ mask: t2, ...s }) {
1514
+ super(s), this._mask = t2 ?? "•", this.on("userInput", (r2) => {
1515
+ this._setValue(r2);
1516
+ }), this.on("finalize", () => {
1517
+ this.value === undefined && (this.value = "");
1518
+ });
1519
+ }
1520
+ };
1521
+ n$1 = class n extends y {
1522
+ options;
1523
+ cursor = 0;
1524
+ get _selectedValue() {
1525
+ return this.options[this.cursor];
1526
+ }
1527
+ changeValue() {
1528
+ const e = this._selectedValue;
1529
+ this.value = e === undefined ? undefined : e.value;
1530
+ }
1531
+ constructor(e) {
1532
+ super(e, false), this.options = e.options;
1533
+ const o2 = this.options.findIndex(({ value: s }) => s === e.initialValue), t2 = o2 === -1 ? 0 : o2;
1534
+ this.cursor = this.options[t2]?.disabled ? findCursor(t2, 1, this.options) : t2, this.changeValue(), this.on("cursor", (s) => {
1535
+ switch (s) {
1536
+ case "left":
1537
+ case "up":
1538
+ this.cursor = findCursor(this.cursor, -1, this.options);
1539
+ break;
1540
+ case "down":
1541
+ case "right":
1542
+ this.cursor = findCursor(this.cursor, 1, this.options);
1543
+ break;
1544
+ }
1545
+ this.changeValue();
1546
+ });
1547
+ }
1548
+ };
1549
+ });
1550
+
1551
+ // node_modules/@clack/prompts/dist/index.mjs
1552
+ import { styleText as styleText2, stripVTControlCharacters } from "node:util";
1553
+ import process$1 from "node:process";
1554
+ function isUnicodeSupported() {
1555
+ if (process$1.platform !== "win32") {
1556
+ return process$1.env.TERM !== "linux";
1557
+ }
1558
+ return Boolean(process$1.env.CI) || Boolean(process$1.env.WT_SESSION) || Boolean(process$1.env.TERMINUS_SUBLIME) || process$1.env.ConEmuTask === "{cmd::Cmder}" || process$1.env.TERM_PROGRAM === "Terminus-Sublime" || process$1.env.TERM_PROGRAM === "vscode" || process$1.env.TERM === "xterm-256color" || process$1.env.TERM === "alacritty" || process$1.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
1559
+ }
1560
+ function formatInstructionFooter(o2, e) {
1561
+ const r2 = [`${e ? `${styleText2("cyan", S_BAR)} ` : ""}${o2.join(" • ")}`];
1562
+ return e && r2.push(styleText2("cyan", S_BAR_END)), r2;
1563
+ }
1564
+ var import_sisteransi2, unicode, isCI = () => process.env.CI === "true", unicodeOr = (o2, e) => unicode ? o2 : e, S_STEP_ACTIVE, S_STEP_CANCEL, S_STEP_ERROR, S_STEP_SUBMIT, S_BAR_START, S_BAR, S_BAR_END, S_BAR_START_RIGHT, S_BAR_END_RIGHT, S_RADIO_ACTIVE, S_RADIO_INACTIVE, S_CHECKBOX_ACTIVE, S_CHECKBOX_SELECTED, S_CHECKBOX_INACTIVE, S_PASSWORD_MASK, S_BAR_H, S_CORNER_TOP_RIGHT, S_CONNECT_LEFT, S_CORNER_BOTTOM_RIGHT, S_CORNER_BOTTOM_LEFT, S_CORNER_TOP_LEFT, S_INFO, S_SUCCESS, S_WARN, S_ERROR, symbol = (o2) => {
1565
+ switch (o2) {
1566
+ case "initial":
1567
+ case "active":
1568
+ return styleText2("cyan", S_STEP_ACTIVE);
1569
+ case "cancel":
1570
+ return styleText2("red", S_STEP_CANCEL);
1571
+ case "error":
1572
+ return styleText2("yellow", S_STEP_ERROR);
1573
+ case "submit":
1574
+ return styleText2("green", S_STEP_SUBMIT);
1575
+ case "validating":
1576
+ return styleText2("dim", S_STEP_ACTIVE);
1577
+ }
1578
+ }, symbolBar = (o2) => {
1579
+ switch (o2) {
1580
+ case "initial":
1581
+ case "active":
1582
+ return styleText2("cyan", S_BAR);
1583
+ case "cancel":
1584
+ return styleText2("red", S_BAR);
1585
+ case "error":
1586
+ return styleText2("yellow", S_BAR);
1587
+ case "submit":
1588
+ return styleText2("green", S_BAR);
1589
+ }
1590
+ }, I = (l2, e, w, p2, b2, C2 = false) => {
1591
+ let r2 = e, O = 0;
1592
+ if (C2)
1593
+ for (let i = p2 - 1;i >= w; i--) {
1594
+ const m2 = l2[i];
1595
+ if (m2 && (r2 -= m2.length), O++, r2 <= b2)
1596
+ break;
1597
+ }
1598
+ else
1599
+ for (let i = w;i < p2; i++) {
1600
+ const m2 = l2[i];
1601
+ if (m2 && (r2 -= m2.length), O++, r2 <= b2)
1602
+ break;
1603
+ }
1604
+ return { lineCount: r2, removals: O };
1605
+ }, limitOptions = ({
1606
+ cursor: l2,
1607
+ options: e,
1608
+ style: w,
1609
+ output: p2 = process.stdout,
1610
+ maxItems: b2 = Number.POSITIVE_INFINITY,
1611
+ columnPadding: C2 = 0,
1612
+ rowPadding: r2 = 4
1613
+ }) => {
1614
+ const i = getColumns(p2) - C2, m2 = getRows(p2), M2 = styleText2("dim", "..."), v = Math.max(m2 - r2, 0), a2 = Math.max(Math.min(b2, v), 5);
1615
+ let f2 = 0;
1616
+ l2 >= a2 - 3 && (f2 = Math.max(Math.min(l2 - a2 + 3, e.length - a2), 0));
1617
+ let d = a2 < e.length && f2 > 0, c2 = a2 < e.length && f2 + a2 < e.length;
1618
+ const W = Math.min(f2 + a2, e.length), s = [];
1619
+ let g2 = 0;
1620
+ d && g2++, c2 && g2++;
1621
+ const T3 = f2 + (d ? 1 : 0), y2 = W - (c2 ? 1 : 0);
1622
+ for (let t2 = T3;t2 < y2; t2++) {
1623
+ const n3 = e[t2], o2 = n3 ? w(n3, t2 === l2) : "", h2 = wrapAnsi(o2, i, {
1624
+ hard: true,
1625
+ trim: false
1626
+ }).split(`
1627
+ `);
1628
+ s.push(h2), g2 += h2.length;
1629
+ }
1630
+ if (g2 > v) {
1631
+ let t2 = 0, n3 = 0, o2 = g2;
1632
+ const h2 = l2 - T3;
1633
+ let u4 = v;
1634
+ const L = () => I(s, o2, 0, h2, u4), E = () => I(s, o2, h2 + 1, s.length, u4, true);
1635
+ d ? ({ lineCount: o2, removals: t2 } = L(), o2 > u4 && (c2 || (u4 -= 1), { lineCount: o2, removals: n3 } = E())) : (c2 || (u4 -= 1), { lineCount: o2, removals: n3 } = E(), o2 > u4 && (u4 -= 1, { lineCount: o2, removals: t2 } = L())), t2 > 0 && (d = true, s.splice(0, t2)), n3 > 0 && (c2 = true, s.splice(s.length - n3, n3));
1636
+ }
1637
+ const x = [];
1638
+ d && x.push(M2);
1639
+ for (const t2 of s)
1640
+ for (const n3 of t2)
1641
+ x.push(n3);
1642
+ return c2 && x.push(M2), x;
1643
+ }, confirm = (e) => {
1644
+ const a2 = e.active ?? "Yes", o2 = e.inactive ?? "No";
1645
+ return new r({
1646
+ active: a2,
1647
+ inactive: o2,
1648
+ signal: e.signal,
1649
+ input: e.input,
1650
+ output: e.output,
1651
+ initialValue: e.initialValue ?? true,
1652
+ render() {
1653
+ const i = e.withGuide ?? settings.withGuide, u4 = `${symbol(this.state)} `, l2 = i ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(e.output, e.message, l2, u4), s = `${i ? `${styleText2("gray", S_BAR)}
1654
+ ` : ""}${f2}
1655
+ `, c2 = this.value ? a2 : o2;
1656
+ switch (this.state) {
1657
+ case "submit": {
1658
+ const r2 = i ? `${styleText2("gray", S_BAR)} ` : "";
1659
+ return `${s}${r2}${styleText2("dim", c2)}`;
1660
+ }
1661
+ case "cancel": {
1662
+ const r2 = i ? `${styleText2("gray", S_BAR)} ` : "";
1663
+ return `${s}${r2}${styleText2(["strikethrough", "dim"], c2)}${i ? `
1664
+ ${styleText2("gray", S_BAR)}` : ""}`;
1665
+ }
1666
+ default: {
1667
+ const r2 = i ? `${styleText2("cyan", S_BAR)} ` : "", g2 = i ? styleText2("cyan", S_BAR_END) : "";
1668
+ return `${s}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a2}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a2)}`}${e.vertical ? i ? `
1669
+ ${styleText2("cyan", S_BAR)} ` : `
1670
+ ` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", o2)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${o2}`}
1671
+ ${g2}
1672
+ `;
1673
+ }
1674
+ }
1675
+ }
1676
+ }).prompt();
1677
+ }, MULTISELECT_INSTRUCTIONS, m2 = (i, u4) => i.split(`
1678
+ `).map((d) => u4(d)).join(`
1679
+ `), multiselect = (i) => {
1680
+ const u4 = (t2, a2) => {
1681
+ const r2 = t2.label ?? String(t2.value);
1682
+ return a2 === "disabled" ? `${styleText2("gray", S_CHECKBOX_INACTIVE)} ${m2(r2, (o2) => styleText2(["strikethrough", "gray"], o2))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint ?? "disabled"})`)}` : ""}` : a2 === "active" ? `${styleText2("cyan", S_CHECKBOX_ACTIVE)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a2 === "selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${m2(r2, (o2) => styleText2("dim", o2))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a2 === "cancelled" ? `${m2(r2, (o2) => styleText2(["strikethrough", "dim"], o2))}` : a2 === "active-selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a2 === "submitted" ? `${m2(r2, (o2) => styleText2("dim", o2))}` : `${styleText2("dim", S_CHECKBOX_INACTIVE)} ${m2(r2, (o2) => styleText2("dim", o2))}`;
1683
+ }, d = i.required ?? true, x = i.showInstructions ?? true;
1684
+ return new a({
1685
+ options: i.options,
1686
+ signal: i.signal,
1687
+ input: i.input,
1688
+ output: i.output,
1689
+ initialValues: i.initialValues,
1690
+ required: d,
1691
+ cursorAt: i.cursorAt,
1692
+ validate(t2) {
1693
+ if (d && (t2 === undefined || t2.length === 0))
1694
+ return `Please select at least one option.
1695
+ ${styleText2("reset", styleText2("dim", `Press ${styleText2(["gray", "bgWhite", "inverse"], " space ")} to select, ${styleText2("gray", styleText2("bgWhite", styleText2("inverse", " enter ")))} to submit`))}`;
1696
+ },
1697
+ render() {
1698
+ const t2 = i.withGuide ?? settings.withGuide, a2 = wrapTextWithPrefix(i.output, i.message, t2 ? `${symbolBar(this.state)} ` : "", `${symbol(this.state)} `), r2 = `${t2 ? `${styleText2("gray", S_BAR)}
1699
+ ` : ""}${a2}
1700
+ `, o2 = this.value ?? [], g2 = (n3, l2) => {
1701
+ if (n3.disabled)
1702
+ return u4(n3, "disabled");
1703
+ const s = o2.includes(n3.value);
1704
+ return l2 && s ? u4(n3, "active-selected") : s ? u4(n3, "selected") : u4(n3, l2 ? "active" : "inactive");
1705
+ };
1706
+ switch (this.state) {
1707
+ case "submit": {
1708
+ const n3 = this.options.filter(({ value: s }) => o2.includes(s)).map((s) => u4(s, "submitted")).join(styleText2("dim", ", ")) || styleText2("dim", "none"), l2 = wrapTextWithPrefix(i.output, n3, t2 ? `${styleText2("gray", S_BAR)} ` : "");
1709
+ return `${r2}${l2}`;
1710
+ }
1711
+ case "cancel": {
1712
+ const n3 = this.options.filter(({ value: s }) => o2.includes(s)).map((s) => u4(s, "cancelled")).join(styleText2("dim", ", "));
1713
+ if (n3.trim() === "")
1714
+ return `${r2}${styleText2("gray", S_BAR)}`;
1715
+ const l2 = wrapTextWithPrefix(i.output, n3, t2 ? `${styleText2("gray", S_BAR)} ` : "");
1716
+ return `${r2}${l2}${t2 ? `
1717
+ ${styleText2("gray", S_BAR)}` : ""}`;
1718
+ }
1719
+ case "error": {
1720
+ const n3 = t2 ? `${styleText2("yellow", S_BAR)} ` : "", l2 = this.error.split(`
1721
+ `).map(($, v) => v === 0 ? `${t2 ? `${styleText2("yellow", S_BAR_END)} ` : ""}${styleText2("yellow", $)}` : ` ${$}`).join(`
1722
+ `), s = r2.split(`
1723
+ `).length, h2 = l2.split(`
1724
+ `).length + 1;
1725
+ return `${r2}${n3}${limitOptions({
1726
+ output: i.output,
1727
+ options: this.options,
1728
+ cursor: this.cursor,
1729
+ maxItems: i.maxItems,
1730
+ columnPadding: n3.length,
1731
+ rowPadding: s + h2,
1732
+ style: g2
1733
+ }).join(`
1734
+ ${n3}`)}
1735
+ ${l2}
1736
+ `;
1737
+ }
1738
+ default: {
1739
+ const n3 = t2 ? `${styleText2("cyan", S_BAR)} ` : "", l2 = r2.split(`
1740
+ `).length, s = x ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t2) : t2 ? [styleText2("cyan", S_BAR_END)] : [], h2 = s.join(`
1741
+ `), $ = s.length + 1;
1742
+ return `${r2}${n3}${limitOptions({
1743
+ output: i.output,
1744
+ options: this.options,
1745
+ cursor: this.cursor,
1746
+ maxItems: i.maxItems,
1747
+ columnPadding: n3.length,
1748
+ rowPadding: l2 + $,
1749
+ style: g2
1750
+ }).join(`
1751
+ ${n3}`)}
1752
+ ${h2}
1753
+ `;
1754
+ }
1755
+ }
1756
+ }
1757
+ }).prompt();
1758
+ }, log, cancel = (o2 = "", t2) => {
1759
+ const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
1760
+ i.write(`${e}${styleText2("red", o2)}
1761
+
1762
+ `);
1763
+ }, intro = (o2 = "", t2) => {
1764
+ const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
1765
+ i.write(`${e}${o2}
1766
+ `);
1767
+ }, outro = (o2 = "", t2) => {
1768
+ const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
1769
+ ${styleText2("gray", S_BAR_END)} ` : "";
1770
+ i.write(`${e}${o2}
1771
+
1772
+ `);
1773
+ }, W$1 = (o2) => o2, C2 = (o2, e, s) => {
1774
+ const a2 = {
1775
+ hard: true,
1776
+ trim: false
1777
+ }, i = wrapAnsi(o2, e, a2).split(`
1778
+ `), c2 = i.reduce((n3, t2) => Math.max(dist_default2(t2), n3), 0), u4 = i.map(s).reduce((n3, t2) => Math.max(dist_default2(t2), n3), 0), g2 = e - (u4 - c2);
1779
+ return wrapAnsi(o2, g2, a2);
1780
+ }, note = (o2 = "", e = "", s) => {
1781
+ const a2 = s?.output ?? process$1.stdout, i = s?.withGuide ?? settings.withGuide, c2 = s?.format ?? W$1, g2 = ["", ...C2(o2, getColumns(a2) - 6, c2).split(`
1782
+ `).map(c2), ""], n3 = dist_default2(e), t2 = Math.max(g2.reduce((m3, F) => {
1783
+ const O = dist_default2(F);
1784
+ return O > m3 ? O : m3;
1785
+ }, 0), n3) + 2, h2 = g2.map((m3) => `${styleText2("gray", S_BAR)} ${m3}${" ".repeat(t2 - dist_default2(m3))}${styleText2("gray", S_BAR)}`).join(`
1786
+ `), T3 = i ? `${styleText2("gray", S_BAR)}
1787
+ ` : "", l$1 = i ? S_CONNECT_LEFT : S_CORNER_BOTTOM_LEFT;
1788
+ a2.write(`${T3}${styleText2("green", S_STEP_SUBMIT)} ${styleText2("reset", e)} ${styleText2("gray", S_BAR_H.repeat(Math.max(t2 - n3 - 1, 1)) + S_CORNER_TOP_RIGHT)}
1789
+ ${h2}
1790
+ ${styleText2("gray", l$1 + S_BAR_H.repeat(t2 + 2) + S_CORNER_BOTTOM_RIGHT)}
1791
+ `);
1792
+ }, password = (e) => new u$1({
1793
+ validate: e.validate,
1794
+ mask: e.mask ?? S_PASSWORD_MASK,
1795
+ signal: e.signal,
1796
+ input: e.input,
1797
+ output: e.output,
1798
+ render() {
1799
+ const r2 = e.withGuide ?? settings.withGuide, o2 = `${r2 ? `${styleText2("gray", S_BAR)}
1800
+ ` : ""}${symbol(this.state)} ${e.message}
1801
+ `, m3 = this.userInputWithCursor, i = this.masked;
1802
+ switch (this.state) {
1803
+ case "error": {
1804
+ const s = r2 ? `${styleText2("yellow", S_BAR)} ` : "", n3 = r2 ? `${styleText2("yellow", S_BAR_END)} ` : "", d = i ?? "";
1805
+ return e.clearOnError && this.clear(), `${o2.trim()}
1806
+ ${s}${d}
1807
+ ${n3}${styleText2("yellow", this.error)}
1808
+ `;
1809
+ }
1810
+ case "submit": {
1811
+ const s = r2 ? `${styleText2("gray", S_BAR)} ` : "", n3 = i ? styleText2("dim", i) : "";
1812
+ return `${o2}${s}${n3}`;
1813
+ }
1814
+ case "cancel": {
1815
+ const s = r2 ? `${styleText2("gray", S_BAR)} ` : "", n3 = i ? styleText2(["strikethrough", "dim"], i) : "";
1816
+ return `${o2}${s}${n3}${i && r2 ? `
1817
+ ${styleText2("gray", S_BAR)}` : ""}`;
1818
+ }
1819
+ default: {
1820
+ const s = r2 ? `${styleText2("cyan", S_BAR)} ` : "", n3 = r2 ? styleText2("cyan", S_BAR_END) : "";
1821
+ return `${o2}${s}${m3}
1822
+ ${n3}
1823
+ `;
1824
+ }
1825
+ }
1826
+ }
1827
+ }).prompt(), W = (l2) => styleText2("magenta", l2), spinner = ({
1828
+ indicator: l2 = "dots",
1829
+ onCancel: h2,
1830
+ output: n3 = process.stdout,
1831
+ cancelMessage: G,
1832
+ errorMessage: O,
1833
+ frames: E = unicode ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"],
1834
+ delay: F = unicode ? 80 : 120,
1835
+ signal: m3,
1836
+ ...I2
1837
+ } = {}) => {
1838
+ const u4 = isCI();
1839
+ let M2, T3, d = false, S = false, s = "", p2, w = performance.now();
1840
+ const x = getColumns(n3), k = I2?.styleFrame ?? W, g2 = (e) => {
1841
+ const r2 = e > 1 ? O ?? settings.messages.error : G ?? settings.messages.cancel;
1842
+ S = e === 1, d && (a2(r2, e), S && typeof h2 == "function" && h2());
1843
+ }, f2 = () => g2(2), i = () => g2(1), A = () => {
1844
+ process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i), process.on("SIGTERM", i), process.on("exit", g2), m3 && m3.addEventListener("abort", i);
1845
+ }, H = () => {
1846
+ process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i), process.removeListener("SIGTERM", i), process.removeListener("exit", g2), m3 && m3.removeEventListener("abort", i);
1847
+ }, y2 = () => {
1848
+ if (p2 === undefined)
1849
+ return;
1850
+ u4 && n3.write(`
1851
+ `);
1852
+ const r2 = wrapAnsi(p2, x, {
1853
+ hard: true,
1854
+ trim: false
1855
+ }).split(`
1856
+ `);
1857
+ r2.length > 1 && n3.write(import_sisteransi2.cursor.up(r2.length - 1)), n3.write(import_sisteransi2.cursor.to(0)), n3.write(import_sisteransi2.erase.down());
1858
+ }, C3 = (e) => e.replace(/\.+$/, ""), _2 = (e) => {
1859
+ const r2 = (performance.now() - e) / 1000, t2 = Math.floor(r2 / 60), o2 = Math.floor(r2 % 60);
1860
+ return t2 > 0 ? `[${t2}m ${o2}s]` : `[${o2}s]`;
1861
+ }, N = I2.withGuide ?? settings.withGuide, P2 = (e = "") => {
1862
+ d = true, M2 = block({ output: n3 }), s = C3(e), w = performance.now(), N && n3.write(`${styleText2("gray", S_BAR)}
1863
+ `);
1864
+ let r2 = 0, t2 = 0;
1865
+ A(), T3 = setInterval(() => {
1866
+ if (u4 && s === p2)
1867
+ return;
1868
+ y2(), p2 = s;
1869
+ const o2 = k(E[r2]);
1870
+ let v;
1871
+ if (u4)
1872
+ v = `${o2} ${s}...`;
1873
+ else if (l2 === "timer")
1874
+ v = `${o2} ${s} ${_2(w)}`;
1875
+ else {
1876
+ const B = ".".repeat(Math.floor(t2)).slice(0, 3);
1877
+ v = `${o2} ${s}${B}`;
1878
+ }
1879
+ const j = wrapAnsi(v, x, {
1880
+ hard: true,
1881
+ trim: false
1882
+ });
1883
+ n3.write(j), r2 = r2 + 1 < E.length ? r2 + 1 : 0, t2 = t2 < 4 ? t2 + 0.125 : 0;
1884
+ }, F);
1885
+ }, a2 = (e = "", r2 = 0, t2 = false) => {
1886
+ if (!d)
1887
+ return;
1888
+ d = false, clearInterval(T3), y2();
1889
+ const o2 = r2 === 0 ? styleText2("green", S_STEP_SUBMIT) : r2 === 1 ? styleText2("red", S_STEP_CANCEL) : styleText2("red", S_STEP_ERROR);
1890
+ s = e ?? s, t2 || (l2 === "timer" ? n3.write(`${o2} ${s} ${_2(w)}
1891
+ `) : n3.write(`${o2} ${s}
1892
+ `)), H(), M2();
1893
+ };
1894
+ return {
1895
+ start: P2,
1896
+ stop: (e = "") => a2(e, 0),
1897
+ message: (e = "") => {
1898
+ s = C3(e ?? s);
1899
+ },
1900
+ cancel: (e = "") => a2(e, 1),
1901
+ error: (e = "") => a2(e, 2),
1902
+ clear: () => a2("", 0, true),
1903
+ get isCancelled() {
1904
+ return S;
1905
+ }
1906
+ };
1907
+ }, u4, SELECT_INSTRUCTIONS, c2 = (t2, o2) => t2.includes(`
1908
+ `) ? t2.split(`
1909
+ `).map((d) => o2(d)).join(`
1910
+ `) : o2(t2), select = (t2) => {
1911
+ const o2 = (n3, m3) => {
1912
+ if (n3 === undefined)
1913
+ return "";
1914
+ const s = n3.label ?? String(n3.value);
1915
+ switch (m3) {
1916
+ case "disabled":
1917
+ return `${styleText2("gray", S_RADIO_INACTIVE)} ${c2(s, (i) => styleText2("gray", i))}${n3.hint ? ` ${styleText2("dim", `(${n3.hint ?? "disabled"})`)}` : ""}`;
1918
+ case "selected":
1919
+ return `${c2(s, (i) => styleText2("dim", i))}`;
1920
+ case "active":
1921
+ return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${n3.hint ? ` ${styleText2("dim", `(${n3.hint})`)}` : ""}`;
1922
+ case "cancelled":
1923
+ return `${c2(s, (i) => styleText2(["strikethrough", "dim"], i))}`;
1924
+ default:
1925
+ return `${styleText2("dim", S_RADIO_INACTIVE)} ${c2(s, (i) => styleText2("dim", i))}`;
1926
+ }
1927
+ }, d = t2.showInstructions ?? true;
1928
+ return new n$1({
1929
+ options: t2.options,
1930
+ signal: t2.signal,
1931
+ input: t2.input,
1932
+ output: t2.output,
1933
+ initialValue: t2.initialValue,
1934
+ render() {
1935
+ const n3 = t2.withGuide ?? settings.withGuide, m3 = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, i = wrapTextWithPrefix(t2.output, t2.message, s, m3), u5 = `${n3 ? `${styleText2("gray", S_BAR)}
1936
+ ` : ""}${i}
1937
+ `;
1938
+ switch (this.state) {
1939
+ case "submit": {
1940
+ const r2 = n3 ? `${styleText2("gray", S_BAR)} ` : "", a2 = wrapTextWithPrefix(t2.output, o2(this.options[this.cursor], "selected"), r2);
1941
+ return `${u5}${a2}`;
1942
+ }
1943
+ case "cancel": {
1944
+ const r2 = n3 ? `${styleText2("gray", S_BAR)} ` : "", a2 = wrapTextWithPrefix(t2.output, o2(this.options[this.cursor], "cancelled"), r2);
1945
+ return `${u5}${a2}${n3 ? `
1946
+ ${styleText2("gray", S_BAR)}` : ""}`;
1947
+ }
1948
+ default: {
1949
+ const r2 = n3 ? `${styleText2("cyan", S_BAR)} ` : "", a2 = u5.split(`
1950
+ `).length, p2 = d ? formatInstructionFooter(SELECT_INSTRUCTIONS, n3) : n3 ? [styleText2("cyan", S_BAR_END)] : [], f2 = p2.join(`
1951
+ `), b2 = p2.length + 1;
1952
+ return `${u5}${r2}${limitOptions({
1953
+ output: t2.output,
1954
+ cursor: this.cursor,
1955
+ options: this.options,
1956
+ maxItems: t2.maxItems,
1957
+ columnPadding: r2.length,
1958
+ rowPadding: a2 + b2,
1959
+ style: (g2, x) => o2(g2, g2.disabled ? "disabled" : x ? "active" : "inactive")
1960
+ }).join(`
1961
+ ${r2}`)}
1962
+ ${f2}
1963
+ `;
1964
+ }
1965
+ }
1966
+ }
1967
+ }).prompt();
1968
+ }, i;
1969
+ var init_dist4 = __esm(() => {
1970
+ init_dist3();
1971
+ init_dist3();
1972
+ init_main();
1973
+ init_dist2();
1974
+ import_sisteransi2 = __toESM(require_src(), 1);
1975
+ unicode = isUnicodeSupported();
1976
+ S_STEP_ACTIVE = unicodeOr("◆", "*");
1977
+ S_STEP_CANCEL = unicodeOr("■", "x");
1978
+ S_STEP_ERROR = unicodeOr("▲", "x");
1979
+ S_STEP_SUBMIT = unicodeOr("◇", "o");
1980
+ S_BAR_START = unicodeOr("┌", "T");
1981
+ S_BAR = unicodeOr("│", "|");
1982
+ S_BAR_END = unicodeOr("└", "—");
1983
+ S_BAR_START_RIGHT = unicodeOr("┐", "T");
1984
+ S_BAR_END_RIGHT = unicodeOr("┘", "—");
1985
+ S_RADIO_ACTIVE = unicodeOr("●", ">");
1986
+ S_RADIO_INACTIVE = unicodeOr("○", " ");
1987
+ S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]");
1988
+ S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]");
1989
+ S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]");
1990
+ S_PASSWORD_MASK = unicodeOr("▪", "•");
1991
+ S_BAR_H = unicodeOr("─", "-");
1992
+ S_CORNER_TOP_RIGHT = unicodeOr("╮", "+");
1993
+ S_CONNECT_LEFT = unicodeOr("├", "+");
1994
+ S_CORNER_BOTTOM_RIGHT = unicodeOr("╯", "+");
1995
+ S_CORNER_BOTTOM_LEFT = unicodeOr("╰", "+");
1996
+ S_CORNER_TOP_LEFT = unicodeOr("╭", "+");
1997
+ S_INFO = unicodeOr("●", "•");
1998
+ S_SUCCESS = unicodeOr("◆", "*");
1999
+ S_WARN = unicodeOr("▲", "!");
2000
+ S_ERROR = unicodeOr("■", "x");
2001
+ MULTISELECT_INSTRUCTIONS = [
2002
+ `${styleText2("dim", "↑/↓")} to navigate`,
2003
+ `${styleText2("dim", "Space:")} select`,
2004
+ `${styleText2("dim", "Enter:")} confirm`
2005
+ ];
2006
+ log = {
2007
+ message: (s = [], {
2008
+ symbol: e = styleText2("gray", S_BAR),
2009
+ secondarySymbol: r2 = styleText2("gray", S_BAR),
2010
+ output: m3 = process.stdout,
2011
+ spacing: l2 = 1,
2012
+ withGuide: c2
2013
+ } = {}) => {
2014
+ const t2 = [], o2 = c2 ?? settings.withGuide, f2 = o2 ? r2 : "", O = o2 ? `${e} ` : "", u4 = o2 ? `${r2} ` : "";
2015
+ for (let i = 0;i < l2; i++)
2016
+ t2.push(f2);
2017
+ const g2 = Array.isArray(s) ? s : s.split(`
2018
+ `);
2019
+ if (g2.length > 0) {
2020
+ const [i, ...y2] = g2;
2021
+ i.length > 0 ? t2.push(`${O}${i}`) : t2.push(o2 ? e : "");
2022
+ for (const p2 of y2)
2023
+ p2.length > 0 ? t2.push(`${u4}${p2}`) : t2.push(o2 ? r2 : "");
2024
+ }
2025
+ m3.write(`${t2.join(`
2026
+ `)}
2027
+ `);
2028
+ },
2029
+ info: (s, e) => {
2030
+ log.message(s, { ...e, symbol: styleText2("blue", S_INFO) });
2031
+ },
2032
+ success: (s, e) => {
2033
+ log.message(s, { ...e, symbol: styleText2("green", S_SUCCESS) });
2034
+ },
2035
+ step: (s, e) => {
2036
+ log.message(s, { ...e, symbol: styleText2("green", S_STEP_SUBMIT) });
2037
+ },
2038
+ warn: (s, e) => {
2039
+ log.message(s, { ...e, symbol: styleText2("yellow", S_WARN) });
2040
+ },
2041
+ warning: (s, e) => {
2042
+ log.warn(s, e);
2043
+ },
2044
+ error: (s, e) => {
2045
+ log.message(s, { ...e, symbol: styleText2("red", S_ERROR) });
2046
+ }
2047
+ };
2048
+ u4 = {
2049
+ light: unicodeOr("─", "-"),
2050
+ heavy: unicodeOr("━", "="),
2051
+ block: unicodeOr("█", "#")
2052
+ };
2053
+ SELECT_INSTRUCTIONS = [
2054
+ `${styleText2("dim", "↑/↓")} to navigate`,
2055
+ `${styleText2("dim", "Enter:")} confirm`
2056
+ ];
2057
+ i = `${styleText2("gray", S_BAR)} `;
2058
+ });
2059
+
2060
+ // src/init.ts
2061
+ var exports_init = {};
2062
+ __export(exports_init, {
2063
+ init: () => init,
2064
+ REPO_URL: () => REPO_URL
2065
+ });
2066
+ import fs2 from "node:fs";
2067
+ import os2 from "node:os";
2068
+ import path2 from "node:path";
2069
+ import { fileURLToPath } from "node:url";
2070
+ import { execFile } from "node:child_process";
2071
+ function bail(msg = "Setup cancelled.") {
2072
+ cancel(msg);
2073
+ process.exit(1);
2074
+ }
2075
+ function openUrl(url) {
2076
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
2077
+ const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
2078
+ execFile(cmd, args, () => {});
2079
+ }
2080
+ async function init() {
2081
+ intro("jgrep init");
2082
+ let existing;
2083
+ try {
2084
+ existing = resolveApiKey();
2085
+ } catch {}
2086
+ if (existing) {
2087
+ const keep = guard(await confirm({
2088
+ message: `A TypeSafe key is already configured (…${existing.slice(-4)}). Keep it?`,
2089
+ initialValue: true
2090
+ }));
2091
+ if (!keep)
2092
+ existing = undefined;
2093
+ }
2094
+ let apiKey = existing;
2095
+ let model;
2096
+ while (!apiKey) {
2097
+ const typed = guard(await password({
2098
+ message: `Paste your TypeSafe API key (${CONSOLE_URL})`,
2099
+ validate: (v) => v?.trim() ? undefined : "The key is required: jgrep cannot run without it."
2100
+ })).trim();
2101
+ const s = spinner();
2102
+ s.start("Checking the key against api.typesafe.ai");
2103
+ try {
2104
+ const r2 = await verifyApiKey(typed);
2105
+ if (r2.ok) {
2106
+ s.stop(`Key accepted (${r2.model ?? "jev"})`);
2107
+ apiKey = typed;
2108
+ model = r2.model;
2109
+ } else {
2110
+ s.stop(`Rejected with HTTP ${r2.status}`, 1);
2111
+ }
2112
+ } catch (e) {
2113
+ s.stop(`Could not reach the API: ${e.message}`, 1);
2114
+ }
2115
+ if (!apiKey) {
2116
+ const again = guard(await confirm({ message: "Try another key?", initialValue: true }));
2117
+ if (!again)
2118
+ bail("No working key; run `jgrep init` again later.");
2119
+ }
2120
+ }
2121
+ if (!existing) {
2122
+ const where = guard(await select({
2123
+ message: "Where should the key live?",
2124
+ options: [
2125
+ { value: "global", label: "~/.config/jgrep/env", hint: "recommended: works in every project" },
2126
+ { value: "project", label: "./.env in this directory", hint: "add .env to .gitignore" },
2127
+ { value: "none", label: "Don't save", hint: "I'll export TYPESAFE_API_KEY myself" }
2128
+ ]
2129
+ }));
2130
+ if (where === "global")
2131
+ log.success(`Saved to ${saveApiKey(apiKey)} (mode 600)`);
2132
+ else if (where === "project") {
2133
+ fs2.appendFileSync(".env", `TYPESAFE_API_KEY=${apiKey}
2134
+ `);
2135
+ log.success("Appended to ./.env");
2136
+ if (!fs2.existsSync(".gitignore") || !fs2.readFileSync(".gitignore", "utf8").split(`
2137
+ `).includes(".env")) {
2138
+ log.warn(".env is not in .gitignore");
2139
+ }
2140
+ } else
2141
+ log.info(`Not saved. Use: export TYPESAFE_API_KEY=…`);
2142
+ }
2143
+ const agents = [
2144
+ { value: "claude", label: "Claude Code", hint: "~/.claude/skills/jgrep" },
2145
+ { value: "codex", label: "Codex", hint: "~/.codex/skills/jgrep" }
2146
+ ].filter((a2) => fs2.existsSync(path2.join(os2.homedir(), `.${a2.value}`)));
2147
+ if (agents.length && fs2.existsSync(SKILL_SRC)) {
2148
+ const picked = guard(await multiselect({
2149
+ message: "Teach your coding agents to use jgrep? (space to toggle, enter to continue)",
2150
+ options: agents,
2151
+ required: false
2152
+ }));
2153
+ if (picked.length) {
2154
+ for (const dir of installSkills(SKILL_SRC, os2.homedir(), picked))
2155
+ log.success(`Skill installed: ${dir}`);
2156
+ }
2157
+ }
2158
+ const star = guard(await confirm({ message: "Enjoying jgrep? Give it a star on GitHub", initialValue: true }));
2159
+ if (star) {
2160
+ openUrl(REPO_URL);
2161
+ log.info(REPO_URL);
2162
+ }
2163
+ note([
2164
+ `jgrep "catches an error and silently ignores it" src/`,
2165
+ `jgrep -C "validates the webhook signature" app/`,
2166
+ `jgrep --diff --staged "leaves debug output behind"`
2167
+ ].join(`
2168
+ `), "Try it");
2169
+ outro(model ? `Ready (${model}). Key: ${existing ? "existing" : CONFIG_FILE}` : "Ready.");
2170
+ }
2171
+ var REPO_URL = "https://github.com/kyu1204/jgrep", CONSOLE_URL = "https://console.typesafe.ai", SKILL_SRC, guard = (v) => isCancel(v) ? bail() : v;
2172
+ var init_init = __esm(() => {
2173
+ init_dist4();
2174
+ init_jgrep();
2175
+ SKILL_SRC = path2.join(path2.dirname(fileURLToPath(import.meta.url)), "..", "skill", "SKILL.md");
2176
+ });
2177
+
2178
+ // src/cli.ts
2179
+ init_jgrep();
2180
+ var VERSION = "0.2.0";
2181
+ var USAGE = `jgrep ${VERSION} — semantic grep powered by Jev (TypeSafe)
2182
+
2183
+ usage: jgrep init interactive setup (API key, agent skills)
2184
+ jgrep [options] "<description>" [path ...]
2185
+ jgrep [options] --diff [ref] "<description>"
2186
+
2187
+ -t, --threshold <p> print chunks with probability >= p (default 0.7)
2188
+ -C, --show print the matching chunk body under each hit
2189
+ -a, --all print every chunk with its probability, best first
2190
+ --json machine-readable output
2191
+ --diff [ref] grep git diff hunks instead of files
2192
+ (working tree by default, or against <ref>)
2193
+ --staged with --diff: staged changes only
2194
+ -b, --batch <n> chunks per request (default 16)
2195
+ -c, --concurrency <n> parallel requests (default 16)
2196
+ --no-cache ignore and do not write ~/.cache/jgrep
2197
+ -v, --version print version
2198
+
2199
+ exit status: 0 when something matched, 1 when nothing did, 2 on error.
2200
+ CI lint: ! jgrep --diff origin/main "adds an endpoint without an auth check"
2201
+
2202
+ examples:
2203
+ jgrep "catches an error and silently ignores it" src/
2204
+ jgrep -C "reads user input without validating it" app/
2205
+ jgrep --diff --staged "changes billing logic without touching tests"`;
2206
+ var tty = process.stdout.isTTY && !process.env.NO_COLOR;
2207
+ var c3 = (code, s) => tty ? `\x1B[${code}m${s}\x1B[0m` : s;
2208
+ function parse(argv) {
2209
+ const o2 = { threshold: 0.7, batch: 16, concurrency: 16, all: false, show: false, json: false, cache: true, diff: null };
2210
+ const rest = [];
2211
+ const positionalsAfter = (i2) => argv.slice(i2 + 1).filter((x) => !x.startsWith("-")).length;
2212
+ for (let i2 = 0;i2 < argv.length; i2++) {
2213
+ const a2 = argv[i2];
2214
+ if (a2 === "-t" || a2 === "--threshold")
2215
+ o2.threshold = Number(argv[++i2]);
2216
+ else if (a2 === "-b" || a2 === "--batch")
2217
+ o2.batch = Number(argv[++i2]);
2218
+ else if (a2 === "-c" || a2 === "--concurrency")
2219
+ o2.concurrency = Number(argv[++i2]);
2220
+ else if (a2 === "-a" || a2 === "--all")
2221
+ o2.all = true;
2222
+ else if (a2 === "-C" || a2 === "--show")
2223
+ o2.show = true;
2224
+ else if (a2 === "--json")
2225
+ o2.json = true;
2226
+ else if (a2 === "--no-cache")
2227
+ o2.cache = false;
2228
+ else if (a2 === "--staged")
2229
+ (o2.diff ??= []).push("--staged");
2230
+ else if (a2 === "--diff") {
2231
+ o2.diff ??= [];
2232
+ const next = argv[i2 + 1];
2233
+ if (next && !next.startsWith("-") && (rest.length > 0 || positionalsAfter(i2 + 1) > 0))
2234
+ o2.diff.push(argv[++i2]);
2235
+ } else if (a2 === "-h" || a2 === "--help") {
2236
+ console.log(USAGE);
2237
+ process.exit(0);
2238
+ } else if (a2 === "-V" || a2 === "-v" || a2 === "--version") {
2239
+ console.log(VERSION);
2240
+ process.exit(0);
2241
+ } else if (a2.startsWith("-") && a2 !== "-")
2242
+ throw new Error(`unknown option ${a2} (try --help)`);
2243
+ else
2244
+ rest.push(a2);
2245
+ }
2246
+ if (![o2.threshold, o2.batch, o2.concurrency].every((n3) => Number.isFinite(n3) && n3 >= 0))
2247
+ throw new Error("numeric option expected");
2248
+ return { ...o2, question: rest[0], paths: rest.slice(1) };
2249
+ }
2250
+ async function main() {
2251
+ if (process.argv[2] === "init") {
2252
+ const { init: init2 } = await Promise.resolve().then(() => (init_init(), exports_init));
2253
+ return init2();
2254
+ }
2255
+ const o2 = parse(process.argv.slice(2));
2256
+ if (!o2.question) {
2257
+ console.error(USAGE);
2258
+ process.exit(2);
2259
+ }
2260
+ const t0 = Date.now();
2261
+ const kind = o2.diff ? "diff" : "code";
2262
+ const chunks = o2.diff ? diffChunks(gitDiff(o2.diff)) : chunkPaths(o2.paths.length ? o2.paths : ["."]);
2263
+ if (!chunks.length) {
2264
+ console.error(o2.diff ? "empty diff" : "no text files found");
2265
+ process.exit(1);
2266
+ }
2267
+ const cache = o2.cache ? loadCache() : {};
2268
+ const r2 = await jgrep(o2.question, chunks, {
2269
+ ...o2,
2270
+ kind,
2271
+ apiKey: resolveApiKey(),
2272
+ cache,
2273
+ onProgress: (d, n3) => {
2274
+ if (process.stderr.isTTY)
2275
+ process.stderr.write(`\r${d}/${n3} requests`);
2276
+ }
2277
+ });
2278
+ if (o2.cache)
2279
+ saveCache(cache);
2280
+ if (process.stderr.isTTY)
2281
+ process.stderr.write("\r\x1B[K");
2282
+ const rows = o2.all ? [...r2.all].sort((a2, b2) => b2.p - a2.p) : r2.hits;
2283
+ if (o2.json) {
2284
+ console.log(JSON.stringify(rows.map((h2) => ({ file: h2.file, start: h2.start, end: h2.end, p: h2.p, text: h2.text })), null, 2));
2285
+ } else {
2286
+ for (const h2 of rows) {
2287
+ const head = h2.text.split(`
2288
+ `).find((l2) => l2.trim() && !l2.startsWith("@@"))?.trim().slice(0, 90) ?? "";
2289
+ const pcol = h2.p >= o2.threshold ? "32" : "90";
2290
+ console.log(`${c3("35", h2.file)}${c3("36", ":")}${c3("32", `${h2.start}-${h2.end}`)} ${c3(pcol, `p=${h2.p.toFixed(2)}`)} ${head}`);
2291
+ if (o2.show)
2292
+ console.log(h2.text.split(`
2293
+ `).map((l2) => " " + l2).join(`
2294
+ `) + `
2295
+ `);
2296
+ }
2297
+ }
2298
+ const cost = r2.tokens * USD_PER_M_INPUT / 1e6;
2299
+ console.error(c3("90", `${r2.hits.length} hits / ${r2.chunks} chunks (${r2.cached} cached) · ${r2.tokens} tokens · $${cost.toFixed(4)} · ${((Date.now() - t0) / 1000).toFixed(1)}s`));
2300
+ process.exit(r2.hits.length ? 0 : 1);
2301
+ }
2302
+ if (!process.env.JGREP_NO_MAIN)
2303
+ main().catch((e) => {
2304
+ console.error(c3("31", e.message));
2305
+ process.exit(2);
2306
+ });
2307
+ export {
2308
+ parse
2309
+ };