zapdev 0.11.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -39
- package/dist/cli.js +1814 -2080
- package/package.json +2 -3
package/dist/cli.js
CHANGED
|
@@ -84,1698 +84,1700 @@ var require_src = __commonJS({
|
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
// node_modules
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
122
|
-
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
123
|
-
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
124
|
-
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
|
|
125
|
-
const ANSI_WIDTH = 0;
|
|
126
|
-
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
127
|
-
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
128
|
-
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
129
|
-
const FULL_WIDTH_WIDTH = 2;
|
|
130
|
-
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
131
|
-
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
132
|
-
const PARSE_BLOCKS = [
|
|
133
|
-
[LATIN_RE, REGULAR_WIDTH],
|
|
134
|
-
[ANSI_RE, ANSI_WIDTH],
|
|
135
|
-
[CONTROL_RE, CONTROL_WIDTH],
|
|
136
|
-
[TAB_RE, TAB_WIDTH],
|
|
137
|
-
[EMOJI_RE, EMOJI_WIDTH],
|
|
138
|
-
[CJKT_WIDE_RE, WIDE_WIDTH]
|
|
139
|
-
];
|
|
140
|
-
let indexPrev = 0;
|
|
141
|
-
let index = 0;
|
|
142
|
-
let length = input.length;
|
|
143
|
-
let lengthExtra = 0;
|
|
144
|
-
let truncationEnabled = false;
|
|
145
|
-
let truncationIndex = length;
|
|
146
|
-
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
147
|
-
let unmatchedStart = 0;
|
|
148
|
-
let unmatchedEnd = 0;
|
|
149
|
-
let width = 0;
|
|
150
|
-
let widthExtra = 0;
|
|
151
|
-
outer: while (true) {
|
|
152
|
-
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
|
|
153
|
-
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
|
|
154
|
-
lengthExtra = 0;
|
|
155
|
-
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
|
|
156
|
-
const codePoint = char.codePointAt(0) || 0;
|
|
157
|
-
if (isFullWidth(codePoint)) {
|
|
158
|
-
widthExtra = FULL_WIDTH_WIDTH;
|
|
159
|
-
} else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
160
|
-
widthExtra = WIDE_WIDTH;
|
|
161
|
-
} else {
|
|
162
|
-
widthExtra = REGULAR_WIDTH;
|
|
163
|
-
}
|
|
164
|
-
if (width + widthExtra > truncationLimit) {
|
|
165
|
-
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
166
|
-
}
|
|
167
|
-
if (width + widthExtra > LIMIT) {
|
|
168
|
-
truncationEnabled = true;
|
|
169
|
-
break outer;
|
|
170
|
-
}
|
|
171
|
-
lengthExtra += char.length;
|
|
172
|
-
width += widthExtra;
|
|
173
|
-
}
|
|
174
|
-
unmatchedStart = unmatchedEnd = 0;
|
|
175
|
-
}
|
|
176
|
-
if (index >= length) {
|
|
177
|
-
break outer;
|
|
178
|
-
}
|
|
179
|
-
for (let i3 = 0, l3 = PARSE_BLOCKS.length; i3 < l3; i3++) {
|
|
180
|
-
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i3];
|
|
181
|
-
BLOCK_RE.lastIndex = index;
|
|
182
|
-
if (BLOCK_RE.test(input)) {
|
|
183
|
-
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
184
|
-
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
185
|
-
if (width + widthExtra > truncationLimit) {
|
|
186
|
-
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
187
|
-
}
|
|
188
|
-
if (width + widthExtra > LIMIT) {
|
|
189
|
-
truncationEnabled = true;
|
|
190
|
-
break outer;
|
|
191
|
-
}
|
|
192
|
-
width += widthExtra;
|
|
193
|
-
unmatchedStart = indexPrev;
|
|
194
|
-
unmatchedEnd = index;
|
|
195
|
-
index = indexPrev = BLOCK_RE.lastIndex;
|
|
196
|
-
continue outer;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
index += 1;
|
|
200
|
-
}
|
|
201
|
-
return {
|
|
202
|
-
width: truncationEnabled ? truncationLimit : width,
|
|
203
|
-
index: truncationEnabled ? truncationIndex : length,
|
|
204
|
-
truncated: truncationEnabled,
|
|
205
|
-
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
206
|
-
};
|
|
207
|
-
};
|
|
208
|
-
var dist_default = getStringTruncatedWidth;
|
|
209
|
-
|
|
210
|
-
// node_modules/fast-string-width/dist/index.js
|
|
211
|
-
var NO_TRUNCATION2 = {
|
|
212
|
-
limit: Infinity,
|
|
213
|
-
ellipsis: "",
|
|
214
|
-
ellipsisWidth: 0
|
|
215
|
-
};
|
|
216
|
-
var fastStringWidth = (input, options = {}) => {
|
|
217
|
-
return dist_default(input, NO_TRUNCATION2, options).width;
|
|
218
|
-
};
|
|
219
|
-
var dist_default2 = fastStringWidth;
|
|
220
|
-
|
|
221
|
-
// node_modules/fast-wrap-ansi/lib/main.js
|
|
222
|
-
var ESC = "\x1B";
|
|
223
|
-
var CSI = "\x9B";
|
|
224
|
-
var END_CODE = 39;
|
|
225
|
-
var ANSI_ESCAPE_BELL = "\x07";
|
|
226
|
-
var ANSI_CSI = "[";
|
|
227
|
-
var ANSI_OSC = "]";
|
|
228
|
-
var ANSI_SGR_TERMINATOR = "m";
|
|
229
|
-
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
230
|
-
var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
231
|
-
var getClosingCode = (openingCode) => {
|
|
232
|
-
if (openingCode >= 30 && openingCode <= 37)
|
|
233
|
-
return 39;
|
|
234
|
-
if (openingCode >= 90 && openingCode <= 97)
|
|
235
|
-
return 39;
|
|
236
|
-
if (openingCode >= 40 && openingCode <= 47)
|
|
237
|
-
return 49;
|
|
238
|
-
if (openingCode >= 100 && openingCode <= 107)
|
|
239
|
-
return 49;
|
|
240
|
-
if (openingCode === 1 || openingCode === 2)
|
|
241
|
-
return 22;
|
|
242
|
-
if (openingCode === 3)
|
|
243
|
-
return 23;
|
|
244
|
-
if (openingCode === 4)
|
|
245
|
-
return 24;
|
|
246
|
-
if (openingCode === 7)
|
|
247
|
-
return 27;
|
|
248
|
-
if (openingCode === 8)
|
|
249
|
-
return 28;
|
|
250
|
-
if (openingCode === 9)
|
|
251
|
-
return 29;
|
|
252
|
-
if (openingCode === 0)
|
|
253
|
-
return 0;
|
|
254
|
-
return void 0;
|
|
255
|
-
};
|
|
256
|
-
var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
257
|
-
var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
258
|
-
var wrapWord = (rows, word, columns) => {
|
|
259
|
-
const characters = word[Symbol.iterator]();
|
|
260
|
-
let isInsideEscape = false;
|
|
261
|
-
let isInsideLinkEscape = false;
|
|
262
|
-
let lastRow = rows.at(-1);
|
|
263
|
-
let visible = lastRow === void 0 ? 0 : dist_default2(lastRow);
|
|
264
|
-
let currentCharacter = characters.next();
|
|
265
|
-
let nextCharacter = characters.next();
|
|
266
|
-
let rawCharacterIndex = 0;
|
|
267
|
-
while (!currentCharacter.done) {
|
|
268
|
-
const character = currentCharacter.value;
|
|
269
|
-
const characterLength = dist_default2(character);
|
|
270
|
-
if (visible + characterLength <= columns) {
|
|
271
|
-
rows[rows.length - 1] += character;
|
|
272
|
-
} else {
|
|
273
|
-
rows.push(character);
|
|
274
|
-
visible = 0;
|
|
275
|
-
}
|
|
276
|
-
if (character === ESC || character === CSI) {
|
|
277
|
-
isInsideEscape = true;
|
|
278
|
-
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
279
|
-
}
|
|
280
|
-
if (isInsideEscape) {
|
|
281
|
-
if (isInsideLinkEscape) {
|
|
282
|
-
if (character === ANSI_ESCAPE_BELL) {
|
|
283
|
-
isInsideEscape = false;
|
|
284
|
-
isInsideLinkEscape = false;
|
|
285
|
-
}
|
|
286
|
-
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
287
|
-
isInsideEscape = false;
|
|
288
|
-
}
|
|
289
|
-
} else {
|
|
290
|
-
visible += characterLength;
|
|
291
|
-
if (visible === columns && !nextCharacter.done) {
|
|
292
|
-
rows.push("");
|
|
293
|
-
visible = 0;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
currentCharacter = nextCharacter;
|
|
297
|
-
nextCharacter = characters.next();
|
|
298
|
-
rawCharacterIndex += character.length;
|
|
299
|
-
}
|
|
300
|
-
lastRow = rows.at(-1);
|
|
301
|
-
if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
|
|
302
|
-
rows[rows.length - 2] += rows.pop();
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
var stringVisibleTrimSpacesRight = (string) => {
|
|
306
|
-
const words = string.split(" ");
|
|
307
|
-
let last = words.length;
|
|
308
|
-
while (last) {
|
|
309
|
-
if (dist_default2(words[last - 1])) {
|
|
310
|
-
break;
|
|
311
|
-
}
|
|
312
|
-
last--;
|
|
313
|
-
}
|
|
314
|
-
if (last === words.length) {
|
|
315
|
-
return string;
|
|
316
|
-
}
|
|
317
|
-
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
318
|
-
};
|
|
319
|
-
var exec = (string, columns, options = {}) => {
|
|
320
|
-
if (options.trim !== false && string.trim() === "") {
|
|
321
|
-
return "";
|
|
322
|
-
}
|
|
323
|
-
let returnValue = "";
|
|
324
|
-
let escapeCode;
|
|
325
|
-
let escapeUrl;
|
|
326
|
-
const words = string.split(" ");
|
|
327
|
-
let rows = [""];
|
|
328
|
-
let rowLength = 0;
|
|
329
|
-
for (let index = 0; index < words.length; index++) {
|
|
330
|
-
const word = words[index];
|
|
331
|
-
if (options.trim !== false) {
|
|
332
|
-
const row = rows.at(-1) ?? "";
|
|
333
|
-
const trimmed = row.trimStart();
|
|
334
|
-
if (row.length !== trimmed.length) {
|
|
335
|
-
rows[rows.length - 1] = trimmed;
|
|
336
|
-
rowLength = dist_default2(trimmed);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
if (index !== 0) {
|
|
340
|
-
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
341
|
-
rows.push("");
|
|
342
|
-
rowLength = 0;
|
|
343
|
-
}
|
|
344
|
-
if (rowLength || options.trim === false) {
|
|
345
|
-
rows[rows.length - 1] += " ";
|
|
346
|
-
rowLength++;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
const wordLength = dist_default2(word);
|
|
350
|
-
if (options.hard && wordLength > columns) {
|
|
351
|
-
const remainingColumns = columns - rowLength;
|
|
352
|
-
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
353
|
-
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
354
|
-
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
355
|
-
rows.push("");
|
|
356
|
-
}
|
|
357
|
-
wrapWord(rows, word, columns);
|
|
358
|
-
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
362
|
-
if (options.wordWrap === false && rowLength < columns) {
|
|
363
|
-
wrapWord(rows, word, columns);
|
|
364
|
-
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
365
|
-
continue;
|
|
366
|
-
}
|
|
367
|
-
rows.push("");
|
|
368
|
-
rowLength = 0;
|
|
369
|
-
}
|
|
370
|
-
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
371
|
-
wrapWord(rows, word, columns);
|
|
372
|
-
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
373
|
-
continue;
|
|
374
|
-
}
|
|
375
|
-
rows[rows.length - 1] += word;
|
|
376
|
-
rowLength += wordLength;
|
|
377
|
-
}
|
|
378
|
-
if (options.trim !== false) {
|
|
379
|
-
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
380
|
-
}
|
|
381
|
-
const preString = rows.join("\n");
|
|
382
|
-
let inSurrogate = false;
|
|
383
|
-
for (let i3 = 0; i3 < preString.length; i3++) {
|
|
384
|
-
const character = preString[i3];
|
|
385
|
-
returnValue += character;
|
|
386
|
-
if (!inSurrogate) {
|
|
387
|
-
inSurrogate = character >= "\uD800" && character <= "\uDBFF";
|
|
388
|
-
if (inSurrogate) {
|
|
389
|
-
continue;
|
|
390
|
-
}
|
|
391
|
-
} else {
|
|
392
|
-
inSurrogate = false;
|
|
393
|
-
}
|
|
394
|
-
if (character === ESC || character === CSI) {
|
|
395
|
-
GROUP_REGEX.lastIndex = i3 + 1;
|
|
396
|
-
const groupsResult = GROUP_REGEX.exec(preString);
|
|
397
|
-
const groups = groupsResult?.groups;
|
|
398
|
-
if (groups?.code !== void 0) {
|
|
399
|
-
const code = Number.parseFloat(groups.code);
|
|
400
|
-
escapeCode = code === END_CODE ? void 0 : code;
|
|
401
|
-
} else if (groups?.uri !== void 0) {
|
|
402
|
-
escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
if (preString[i3 + 1] === "\n") {
|
|
406
|
-
if (escapeUrl) {
|
|
407
|
-
returnValue += wrapAnsiHyperlink("");
|
|
408
|
-
}
|
|
409
|
-
const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
|
|
410
|
-
if (escapeCode && closingCode) {
|
|
411
|
-
returnValue += wrapAnsiCode(closingCode);
|
|
412
|
-
}
|
|
413
|
-
} else if (character === "\n") {
|
|
414
|
-
if (escapeCode && getClosingCode(escapeCode)) {
|
|
415
|
-
returnValue += wrapAnsiCode(escapeCode);
|
|
416
|
-
}
|
|
417
|
-
if (escapeUrl) {
|
|
418
|
-
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
return returnValue;
|
|
423
|
-
};
|
|
424
|
-
var CRLF_OR_LF = /\r?\n/;
|
|
425
|
-
function wrapAnsi(string, columns, options) {
|
|
426
|
-
return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
// node_modules/@clack/core/dist/index.mjs
|
|
430
|
-
var import_sisteransi = __toESM(require_src(), 1);
|
|
431
|
-
import { ReadStream } from "node:tty";
|
|
432
|
-
function findCursor(s2, o2, l3) {
|
|
433
|
-
if (!l3.some((r3) => !r3.disabled))
|
|
434
|
-
return s2;
|
|
435
|
-
const t3 = s2 + o2, n4 = Math.max(l3.length - 1, 0), e2 = t3 < 0 ? n4 : t3 > n4 ? 0 : t3;
|
|
436
|
-
return l3[e2]?.disabled ? findCursor(e2, o2 < 0 ? -1 : 1, l3) : e2;
|
|
437
|
-
}
|
|
438
|
-
var a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
439
|
-
var t = [
|
|
440
|
-
"January",
|
|
441
|
-
"February",
|
|
442
|
-
"March",
|
|
443
|
-
"April",
|
|
444
|
-
"May",
|
|
445
|
-
"June",
|
|
446
|
-
"July",
|
|
447
|
-
"August",
|
|
448
|
-
"September",
|
|
449
|
-
"October",
|
|
450
|
-
"November",
|
|
451
|
-
"December"
|
|
452
|
-
];
|
|
453
|
-
var settings = {
|
|
454
|
-
actions: new Set(a$1),
|
|
455
|
-
aliases: /* @__PURE__ */ new Map([
|
|
456
|
-
// vim support
|
|
457
|
-
["k", "up"],
|
|
458
|
-
["j", "down"],
|
|
459
|
-
["h", "left"],
|
|
460
|
-
["l", "right"],
|
|
461
|
-
["", "cancel"],
|
|
462
|
-
// opinionated defaults!
|
|
463
|
-
["escape", "cancel"]
|
|
464
|
-
]),
|
|
465
|
-
messages: {
|
|
466
|
-
cancel: "Canceled",
|
|
467
|
-
error: "Something went wrong"
|
|
468
|
-
},
|
|
469
|
-
withGuide: true,
|
|
470
|
-
date: {
|
|
471
|
-
monthNames: [...t],
|
|
472
|
-
messages: {
|
|
473
|
-
required: "Please enter a valid date",
|
|
474
|
-
invalidMonth: "There are only 12 months in a year",
|
|
475
|
-
invalidDay: (n4, e2) => `There are only ${n4} days in ${e2}`,
|
|
476
|
-
afterMin: (n4) => `Date must be on or after ${n4.toISOString().slice(0, 10)}`,
|
|
477
|
-
beforeMax: (n4) => `Date must be on or before ${n4.toISOString().slice(0, 10)}`
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
};
|
|
481
|
-
function isActionKey(n4, e2) {
|
|
482
|
-
if (typeof n4 == "string")
|
|
483
|
-
return settings.aliases.get(n4) === e2;
|
|
484
|
-
for (const s2 of n4)
|
|
485
|
-
if (s2 !== void 0 && isActionKey(s2, e2))
|
|
486
|
-
return true;
|
|
487
|
-
return false;
|
|
488
|
-
}
|
|
489
|
-
function diffLines(i3, s2) {
|
|
490
|
-
if (i3 === s2) return;
|
|
491
|
-
const e2 = i3.split(`
|
|
492
|
-
`), t3 = s2.split(`
|
|
493
|
-
`), r3 = Math.max(e2.length, t3.length), f2 = [];
|
|
494
|
-
for (let n4 = 0; n4 < r3; n4++)
|
|
495
|
-
e2[n4] !== t3[n4] && f2.push(n4);
|
|
496
|
-
return {
|
|
497
|
-
lines: f2,
|
|
498
|
-
numLinesBefore: e2.length,
|
|
499
|
-
numLinesAfter: t3.length,
|
|
500
|
-
numLines: r3
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
var R = globalThis.process.platform.startsWith("win");
|
|
504
|
-
var CANCEL_SYMBOL = /* @__PURE__ */ Symbol("clack:cancel");
|
|
505
|
-
function isCancel(e2) {
|
|
506
|
-
return e2 === CANCEL_SYMBOL;
|
|
507
|
-
}
|
|
508
|
-
function setRawMode(e2, r3) {
|
|
509
|
-
const o2 = e2;
|
|
510
|
-
o2.isTTY && o2.setRawMode(r3);
|
|
511
|
-
}
|
|
512
|
-
function block({
|
|
513
|
-
input: e2 = stdin,
|
|
514
|
-
output: r3 = stdout,
|
|
515
|
-
overwrite: o2 = true,
|
|
516
|
-
hideCursor: t3 = true
|
|
517
|
-
} = {}) {
|
|
518
|
-
const s2 = l.createInterface({
|
|
519
|
-
input: e2,
|
|
520
|
-
output: r3,
|
|
521
|
-
prompt: "",
|
|
522
|
-
tabSize: 1
|
|
523
|
-
});
|
|
524
|
-
l.emitKeypressEvents(e2, s2), e2 instanceof ReadStream && e2.isTTY && e2.setRawMode(true);
|
|
525
|
-
const n4 = (f2, { name: a3, sequence: p2 }) => {
|
|
526
|
-
const c3 = String(f2);
|
|
527
|
-
if (isActionKey([c3, a3, p2], "cancel")) {
|
|
528
|
-
t3 && r3.write(import_sisteransi.cursor.show), process.exit(0);
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
if (!o2) return;
|
|
532
|
-
const i3 = a3 === "return" ? 0 : -1, m2 = a3 === "return" ? -1 : 0;
|
|
533
|
-
l.moveCursor(r3, i3, m2, () => {
|
|
534
|
-
l.clearLine(r3, 1, () => {
|
|
535
|
-
e2.once("keypress", n4);
|
|
536
|
-
});
|
|
537
|
-
});
|
|
538
|
-
};
|
|
539
|
-
return t3 && r3.write(import_sisteransi.cursor.hide), e2.once("keypress", n4), () => {
|
|
540
|
-
e2.off("keypress", n4), t3 && r3.write(import_sisteransi.cursor.show), e2 instanceof ReadStream && e2.isTTY && !R && e2.setRawMode(false), s2.terminal = false, s2.close();
|
|
541
|
-
};
|
|
542
|
-
}
|
|
543
|
-
var getColumns = (e2) => "columns" in e2 && typeof e2.columns == "number" ? e2.columns : 80;
|
|
544
|
-
var getRows = (e2) => "rows" in e2 && typeof e2.rows == "number" ? e2.rows : 20;
|
|
545
|
-
function wrapTextWithPrefix(e2, r3, o2, t3 = o2, s2 = o2, n4) {
|
|
546
|
-
const f2 = getColumns(e2 ?? stdout);
|
|
547
|
-
return wrapAnsi(r3, f2 - o2.length, {
|
|
548
|
-
hard: true,
|
|
549
|
-
trim: false
|
|
550
|
-
}).split(`
|
|
551
|
-
`).map((c3, i3, m2) => {
|
|
552
|
-
const d2 = n4 ? n4(c3, i3) : c3;
|
|
553
|
-
return i3 === 0 ? `${t3}${d2}` : i3 === m2.length - 1 ? `${s2}${d2}` : `${o2}${d2}`;
|
|
554
|
-
}).join(`
|
|
555
|
-
`);
|
|
556
|
-
}
|
|
557
|
-
function runValidation(e2, n4) {
|
|
558
|
-
if ("~standard" in e2) {
|
|
559
|
-
const a3 = e2["~standard"].validate(n4);
|
|
560
|
-
if (a3 instanceof Promise)
|
|
561
|
-
throw new TypeError(
|
|
562
|
-
"Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic."
|
|
563
|
-
);
|
|
564
|
-
return a3.issues?.at(0)?.message;
|
|
565
|
-
}
|
|
566
|
-
return e2(n4);
|
|
567
|
-
}
|
|
568
|
-
var V = class {
|
|
569
|
-
input;
|
|
570
|
-
output;
|
|
571
|
-
_abortSignal;
|
|
572
|
-
rl;
|
|
573
|
-
opts;
|
|
574
|
-
_render;
|
|
575
|
-
_track = false;
|
|
576
|
-
_prevFrame = "";
|
|
577
|
-
_subscribers = /* @__PURE__ */ new Map();
|
|
578
|
-
_cursor = 0;
|
|
579
|
-
state = "initial";
|
|
580
|
-
error = "";
|
|
581
|
-
value;
|
|
582
|
-
userInput = "";
|
|
583
|
-
constructor(t3, e2 = true) {
|
|
584
|
-
const { input: i3 = stdin, output: n4 = stdout, render: s2, signal: r3, ...o2 } = t3;
|
|
585
|
-
this.opts = o2, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = s2.bind(this), this._track = e2, this._abortSignal = r3, this.input = i3, this.output = n4;
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
* Unsubscribe all listeners
|
|
589
|
-
*/
|
|
590
|
-
unsubscribe() {
|
|
591
|
-
this._subscribers.clear();
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Set a subscriber with opts
|
|
595
|
-
* @param event - The event name
|
|
596
|
-
*/
|
|
597
|
-
setSubscriber(t3, e2) {
|
|
598
|
-
const i3 = this._subscribers.get(t3) ?? [];
|
|
599
|
-
i3.push(e2), this._subscribers.set(t3, i3);
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Subscribe to an event
|
|
603
|
-
* @param event - The event name
|
|
604
|
-
* @param cb - The callback
|
|
605
|
-
*/
|
|
606
|
-
on(t3, e2) {
|
|
607
|
-
this.setSubscriber(t3, { cb: e2 });
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* Subscribe to an event once
|
|
611
|
-
* @param event - The event name
|
|
612
|
-
* @param cb - The callback
|
|
613
|
-
*/
|
|
614
|
-
once(t3, e2) {
|
|
615
|
-
this.setSubscriber(t3, { cb: e2, once: true });
|
|
616
|
-
}
|
|
617
|
-
/**
|
|
618
|
-
* Emit an event with data
|
|
619
|
-
* @param event - The event name
|
|
620
|
-
* @param data - The data to pass to the callback
|
|
621
|
-
*/
|
|
622
|
-
emit(t3, ...e2) {
|
|
623
|
-
const i3 = this._subscribers.get(t3) ?? [], n4 = [];
|
|
624
|
-
for (const s2 of i3)
|
|
625
|
-
s2.cb(...e2), s2.once && n4.push(() => i3.splice(i3.indexOf(s2), 1));
|
|
626
|
-
for (const s2 of n4)
|
|
627
|
-
s2();
|
|
628
|
-
}
|
|
629
|
-
prompt() {
|
|
630
|
-
return new Promise((t3) => {
|
|
631
|
-
if (this._abortSignal) {
|
|
632
|
-
if (this._abortSignal.aborted)
|
|
633
|
-
return this.state = "cancel", this.close(), t3(CANCEL_SYMBOL);
|
|
634
|
-
this._abortSignal.addEventListener(
|
|
635
|
-
"abort",
|
|
636
|
-
() => {
|
|
637
|
-
this.state = "cancel", this.close();
|
|
638
|
-
},
|
|
639
|
-
{ once: true }
|
|
640
|
-
);
|
|
87
|
+
// node_modules/citty/dist/_chunks/libs/scule.mjs
|
|
88
|
+
var NUMBER_CHAR_RE = /\d/;
|
|
89
|
+
var STR_SPLITTERS = [
|
|
90
|
+
"-",
|
|
91
|
+
"_",
|
|
92
|
+
"/",
|
|
93
|
+
"."
|
|
94
|
+
];
|
|
95
|
+
function isUppercase(char = "") {
|
|
96
|
+
if (NUMBER_CHAR_RE.test(char)) return;
|
|
97
|
+
return char !== char.toLowerCase();
|
|
98
|
+
}
|
|
99
|
+
function splitByCase(str, separators) {
|
|
100
|
+
const splitters = separators ?? STR_SPLITTERS;
|
|
101
|
+
const parts = [];
|
|
102
|
+
if (!str || typeof str !== "string") return parts;
|
|
103
|
+
let buff = "";
|
|
104
|
+
let previousUpper;
|
|
105
|
+
let previousSplitter;
|
|
106
|
+
for (const char of str) {
|
|
107
|
+
const isSplitter = splitters.includes(char);
|
|
108
|
+
if (isSplitter === true) {
|
|
109
|
+
parts.push(buff);
|
|
110
|
+
buff = "";
|
|
111
|
+
previousUpper = void 0;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const isUpper = isUppercase(char);
|
|
115
|
+
if (previousSplitter === false) {
|
|
116
|
+
if (previousUpper === false && isUpper === true) {
|
|
117
|
+
parts.push(buff);
|
|
118
|
+
buff = char;
|
|
119
|
+
previousUpper = isUpper;
|
|
120
|
+
continue;
|
|
641
121
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
}), this.rl.prompt(), this.opts.initialUserInput !== void 0 && 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", () => {
|
|
649
|
-
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t3(this.value);
|
|
650
|
-
}), this.once("cancel", () => {
|
|
651
|
-
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t3(CANCEL_SYMBOL);
|
|
652
|
-
});
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
_isActionKey(t3, e2) {
|
|
656
|
-
return t3 === " ";
|
|
657
|
-
}
|
|
658
|
-
_shouldSubmit(t3, e2) {
|
|
659
|
-
return true;
|
|
660
|
-
}
|
|
661
|
-
_setValue(t3) {
|
|
662
|
-
this.value = t3, this.emit("value", this.value);
|
|
663
|
-
}
|
|
664
|
-
_setUserInput(t3, e2) {
|
|
665
|
-
this.userInput = t3 ?? "", this.emit("userInput", this.userInput), e2 && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
|
|
666
|
-
}
|
|
667
|
-
_clearUserInput() {
|
|
668
|
-
this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
|
|
669
|
-
}
|
|
670
|
-
onKeypress(t3, e2) {
|
|
671
|
-
if (this._track && e2.name !== "return" && (e2.name && this._isActionKey(t3, e2) && 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"), e2?.name && (!this._track && settings.aliases.has(e2.name) && this.emit("cursor", settings.aliases.get(e2.name)), settings.actions.has(e2.name) && this.emit("cursor", e2.name)), t3 && (t3.toLowerCase() === "y" || t3.toLowerCase() === "n") && this.emit("confirm", t3.toLowerCase() === "y"), this.emit("key", t3, e2), e2?.name === "return" && this._shouldSubmit(t3, e2)) {
|
|
672
|
-
if (this.opts.validate) {
|
|
673
|
-
const i3 = runValidation(this.opts.validate, this.value);
|
|
674
|
-
i3 && (this.error = i3 instanceof Error ? i3.message : i3, this.state = "error", this.rl?.write(this.userInput));
|
|
122
|
+
if (previousUpper === true && isUpper === false && buff.length > 1) {
|
|
123
|
+
const lastChar = buff.at(-1);
|
|
124
|
+
parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
|
|
125
|
+
buff = lastChar + char;
|
|
126
|
+
previousUpper = isUpper;
|
|
127
|
+
continue;
|
|
675
128
|
}
|
|
676
|
-
this.state !== "error" && (this.state = "submit");
|
|
677
129
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
682
|
-
`), setRawMode(this.input, false), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
683
|
-
}
|
|
684
|
-
restoreCursor() {
|
|
685
|
-
const t3 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
|
|
686
|
-
`).length - 1;
|
|
687
|
-
this.output.write(import_sisteransi.cursor.move(-999, t3 * -1));
|
|
130
|
+
buff += char;
|
|
131
|
+
previousUpper = isUpper;
|
|
132
|
+
previousSplitter = isSplitter;
|
|
688
133
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
134
|
+
parts.push(buff);
|
|
135
|
+
return parts;
|
|
136
|
+
}
|
|
137
|
+
function upperFirst(str) {
|
|
138
|
+
return str ? str[0].toUpperCase() + str.slice(1) : "";
|
|
139
|
+
}
|
|
140
|
+
function lowerFirst(str) {
|
|
141
|
+
return str ? str[0].toLowerCase() + str.slice(1) : "";
|
|
142
|
+
}
|
|
143
|
+
function pascalCase(str, opts) {
|
|
144
|
+
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => upperFirst(opts?.normalize ? p2.toLowerCase() : p2)).join("") : "";
|
|
145
|
+
}
|
|
146
|
+
function camelCase(str, opts) {
|
|
147
|
+
return lowerFirst(pascalCase(str || "", opts));
|
|
148
|
+
}
|
|
149
|
+
function kebabCase(str, joiner) {
|
|
150
|
+
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => p2.toLowerCase()).join(joiner ?? "-") : "";
|
|
151
|
+
}
|
|
152
|
+
function snakeCase(str) {
|
|
153
|
+
return kebabCase(str || "", "_");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// node_modules/citty/dist/index.mjs
|
|
157
|
+
import { parseArgs as parseArgs$1 } from "node:util";
|
|
158
|
+
function toArray(val) {
|
|
159
|
+
if (Array.isArray(val)) return val;
|
|
160
|
+
return val === void 0 ? [] : [val];
|
|
161
|
+
}
|
|
162
|
+
function formatLineColumns(lines, linePrefix = "") {
|
|
163
|
+
const maxLength = [];
|
|
164
|
+
for (const line of lines) for (const [i3, element] of line.entries()) maxLength[i3] = Math.max(maxLength[i3] || 0, element.length);
|
|
165
|
+
return lines.map((l3) => l3.map((c3, i3) => linePrefix + c3[i3 === 0 ? "padStart" : "padEnd"](maxLength[i3])).join(" ")).join("\n");
|
|
166
|
+
}
|
|
167
|
+
function resolveValue(input) {
|
|
168
|
+
return typeof input === "function" ? input() : input;
|
|
169
|
+
}
|
|
170
|
+
var CLIError = class extends Error {
|
|
171
|
+
code;
|
|
172
|
+
constructor(message, code) {
|
|
173
|
+
super(message);
|
|
174
|
+
this.name = "CLIError";
|
|
175
|
+
this.code = code;
|
|
731
176
|
}
|
|
732
177
|
};
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
|
|
178
|
+
function parseRawArgs(args = [], opts = {}) {
|
|
179
|
+
const booleans = new Set(opts.boolean || []);
|
|
180
|
+
const strings = new Set(opts.string || []);
|
|
181
|
+
const aliasMap = opts.alias || {};
|
|
182
|
+
const defaults = opts.default || {};
|
|
183
|
+
const aliasToMain = /* @__PURE__ */ new Map();
|
|
184
|
+
const mainToAliases = /* @__PURE__ */ new Map();
|
|
185
|
+
for (const [key, value] of Object.entries(aliasMap)) {
|
|
186
|
+
const targets = value;
|
|
187
|
+
for (const target of targets) {
|
|
188
|
+
aliasToMain.set(key, target);
|
|
189
|
+
if (!mainToAliases.has(target)) mainToAliases.set(target, []);
|
|
190
|
+
mainToAliases.get(target).push(key);
|
|
191
|
+
aliasToMain.set(target, key);
|
|
192
|
+
if (!mainToAliases.has(key)) mainToAliases.set(key, []);
|
|
193
|
+
mainToAliases.get(key).push(target);
|
|
194
|
+
}
|
|
739
195
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
this.value = !this.value;
|
|
747
|
-
});
|
|
196
|
+
const options = {};
|
|
197
|
+
function getType(name) {
|
|
198
|
+
if (booleans.has(name)) return "boolean";
|
|
199
|
+
const aliases = mainToAliases.get(name) || [];
|
|
200
|
+
for (const alias of aliases) if (booleans.has(alias)) return "boolean";
|
|
201
|
+
return "string";
|
|
748
202
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
return this.options[this.cursor];
|
|
203
|
+
function isStringType(name) {
|
|
204
|
+
if (strings.has(name)) return true;
|
|
205
|
+
const aliases = mainToAliases.get(name) || [];
|
|
206
|
+
for (const alias of aliases) if (strings.has(alias)) return true;
|
|
207
|
+
return false;
|
|
755
208
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
209
|
+
const allOptions = /* @__PURE__ */ new Set([
|
|
210
|
+
...booleans,
|
|
211
|
+
...strings,
|
|
212
|
+
...Object.keys(aliasMap),
|
|
213
|
+
...Object.values(aliasMap).flat(),
|
|
214
|
+
...Object.keys(defaults)
|
|
215
|
+
]);
|
|
216
|
+
for (const name of allOptions) if (!options[name]) options[name] = {
|
|
217
|
+
type: getType(name),
|
|
218
|
+
default: defaults[name]
|
|
219
|
+
};
|
|
220
|
+
for (const [alias, main2] of aliasToMain.entries()) if (alias.length === 1 && options[main2] && !options[main2].short) options[main2].short = alias;
|
|
221
|
+
const processedArgs = [];
|
|
222
|
+
const negatedFlags = {};
|
|
223
|
+
for (let i3 = 0; i3 < args.length; i3++) {
|
|
224
|
+
const arg = args[i3];
|
|
225
|
+
if (arg === "--") {
|
|
226
|
+
processedArgs.push(...args.slice(i3));
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
if (arg.startsWith("--no-")) {
|
|
230
|
+
const flagName = arg.slice(5);
|
|
231
|
+
negatedFlags[flagName] = true;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
processedArgs.push(arg);
|
|
759
235
|
}
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
768
|
-
break;
|
|
769
|
-
case "down":
|
|
770
|
-
case "right":
|
|
771
|
-
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
772
|
-
break;
|
|
773
|
-
}
|
|
774
|
-
this.changeValue();
|
|
236
|
+
let parsed;
|
|
237
|
+
try {
|
|
238
|
+
parsed = parseArgs$1({
|
|
239
|
+
args: processedArgs,
|
|
240
|
+
options: Object.keys(options).length > 0 ? options : void 0,
|
|
241
|
+
allowPositionals: true,
|
|
242
|
+
strict: false
|
|
775
243
|
});
|
|
244
|
+
} catch {
|
|
245
|
+
parsed = {
|
|
246
|
+
values: {},
|
|
247
|
+
positionals: processedArgs
|
|
248
|
+
};
|
|
776
249
|
}
|
|
777
|
-
};
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
return `${this.userInput}\u2588`;
|
|
785
|
-
const r3 = t3.slice(0, this.cursor), s2 = t3.slice(this.cursor, this.cursor + 1), e2 = t3.slice(this.cursor + 1);
|
|
786
|
-
return `${r3}${styleText("inverse", s2)}${e2}`;
|
|
250
|
+
const out = { _: [] };
|
|
251
|
+
out._ = parsed.positionals;
|
|
252
|
+
for (const [key, value] of Object.entries(parsed.values)) {
|
|
253
|
+
let coerced = value;
|
|
254
|
+
if (getType(key) === "boolean" && typeof value === "string") coerced = value !== "false";
|
|
255
|
+
else if (isStringType(key) && typeof value === "boolean") coerced = "";
|
|
256
|
+
out[key] = coerced;
|
|
787
257
|
}
|
|
788
|
-
|
|
789
|
-
|
|
258
|
+
for (const [name] of Object.entries(negatedFlags)) {
|
|
259
|
+
out[name] = false;
|
|
260
|
+
const mainName = aliasToMain.get(name);
|
|
261
|
+
if (mainName) out[mainName] = false;
|
|
262
|
+
const aliases = mainToAliases.get(name);
|
|
263
|
+
if (aliases) for (const alias of aliases) out[alias] = false;
|
|
790
264
|
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
}), this.on("userInput", (r3) => {
|
|
796
|
-
this._setValue(r3);
|
|
797
|
-
}), this.on("finalize", () => {
|
|
798
|
-
this.value || (this.value = t3.defaultValue), this.value === void 0 && (this.value = "");
|
|
799
|
-
});
|
|
265
|
+
for (const [alias, main2] of aliasToMain.entries()) {
|
|
266
|
+
if (out[alias] !== void 0 && out[main2] === void 0) out[main2] = out[alias];
|
|
267
|
+
if (out[main2] !== void 0 && out[alias] === void 0) out[alias] = out[main2];
|
|
268
|
+
if (out[alias] !== out[main2] && defaults[main2] === out[main2]) out[main2] = out[alias];
|
|
800
269
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
270
|
+
return out;
|
|
271
|
+
}
|
|
272
|
+
var noColor = /* @__PURE__ */ (() => {
|
|
273
|
+
const env = globalThis.process?.env ?? {};
|
|
274
|
+
return env.NO_COLOR === "1" || env.TERM === "dumb" || env.TEST || env.CI;
|
|
275
|
+
})();
|
|
276
|
+
var _c = (c3, r3 = 39) => (t3) => noColor ? t3 : `\x1B[${c3}m${t3}\x1B[${r3}m`;
|
|
277
|
+
var bold = /* @__PURE__ */ _c(1, 22);
|
|
278
|
+
var cyan = /* @__PURE__ */ _c(36);
|
|
279
|
+
var gray = /* @__PURE__ */ _c(90);
|
|
280
|
+
var underline = /* @__PURE__ */ _c(4, 24);
|
|
281
|
+
function parseArgs(rawArgs, argsDef) {
|
|
282
|
+
const parseOptions = {
|
|
283
|
+
boolean: [],
|
|
284
|
+
string: [],
|
|
285
|
+
alias: {},
|
|
286
|
+
default: {}
|
|
287
|
+
};
|
|
288
|
+
const args = resolveArgs(argsDef);
|
|
289
|
+
for (const arg of args) {
|
|
290
|
+
if (arg.type === "positional") continue;
|
|
291
|
+
if (arg.type === "string" || arg.type === "enum") parseOptions.string.push(arg.name);
|
|
292
|
+
else if (arg.type === "boolean") parseOptions.boolean.push(arg.name);
|
|
293
|
+
if (arg.default !== void 0) parseOptions.default[arg.name] = arg.default;
|
|
294
|
+
if (arg.alias) parseOptions.alias[arg.name] = arg.alias;
|
|
295
|
+
const camelName = camelCase(arg.name);
|
|
296
|
+
const kebabName = kebabCase(arg.name);
|
|
297
|
+
if (camelName !== arg.name || kebabName !== arg.name) {
|
|
298
|
+
const existingAliases = toArray(parseOptions.alias[arg.name] || []);
|
|
299
|
+
if (camelName !== arg.name && !existingAliases.includes(camelName)) existingAliases.push(camelName);
|
|
300
|
+
if (kebabName !== arg.name && !existingAliases.includes(kebabName)) existingAliases.push(kebabName);
|
|
301
|
+
if (existingAliases.length > 0) parseOptions.alias[arg.name] = existingAliases;
|
|
302
|
+
}
|
|
810
303
|
}
|
|
811
|
-
|
|
304
|
+
const parsed = parseRawArgs(rawArgs, parseOptions);
|
|
305
|
+
const [...positionalArguments] = parsed._;
|
|
306
|
+
const parsedArgsProxy = new Proxy(parsed, { get(target, prop) {
|
|
307
|
+
return target[prop] ?? target[camelCase(prop)] ?? target[kebabCase(prop)];
|
|
308
|
+
} });
|
|
309
|
+
for (const [, arg] of args.entries()) if (arg.type === "positional") {
|
|
310
|
+
const nextPositionalArgument = positionalArguments.shift();
|
|
311
|
+
if (nextPositionalArgument !== void 0) parsedArgsProxy[arg.name] = nextPositionalArgument;
|
|
312
|
+
else if (arg.default === void 0 && arg.required !== false) throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`, "EARG");
|
|
313
|
+
else parsedArgsProxy[arg.name] = arg.default;
|
|
314
|
+
} else if (arg.type === "enum") {
|
|
315
|
+
const argument = parsedArgsProxy[arg.name];
|
|
316
|
+
const options = arg.options || [];
|
|
317
|
+
if (argument !== void 0 && options.length > 0 && !options.includes(argument)) throw new CLIError(`Invalid value for argument: ${cyan(`--${arg.name}`)} (${cyan(argument)}). Expected one of: ${options.map((o2) => cyan(o2)).join(", ")}.`, "EARG");
|
|
318
|
+
} else if (arg.required && parsedArgsProxy[arg.name] === void 0) throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
|
|
319
|
+
return parsedArgsProxy;
|
|
812
320
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
321
|
+
function resolveArgs(argsDef) {
|
|
322
|
+
const args = [];
|
|
323
|
+
for (const [name, argDef] of Object.entries(argsDef || {})) args.push({
|
|
324
|
+
...argDef,
|
|
325
|
+
name,
|
|
326
|
+
alias: toArray(argDef.alias)
|
|
327
|
+
});
|
|
328
|
+
return args;
|
|
329
|
+
}
|
|
330
|
+
async function resolvePlugins(plugins) {
|
|
331
|
+
return Promise.all(plugins.map((p2) => resolveValue(p2)));
|
|
332
|
+
}
|
|
333
|
+
function defineCommand(def) {
|
|
334
|
+
return def;
|
|
335
|
+
}
|
|
336
|
+
async function runCommand(cmd, opts) {
|
|
337
|
+
const cmdArgs = await resolveValue(cmd.args || {});
|
|
338
|
+
const parsedArgs = parseArgs(opts.rawArgs, cmdArgs);
|
|
339
|
+
const context = {
|
|
340
|
+
rawArgs: opts.rawArgs,
|
|
341
|
+
args: parsedArgs,
|
|
342
|
+
data: opts.data,
|
|
343
|
+
cmd
|
|
344
|
+
};
|
|
345
|
+
const plugins = await resolvePlugins(cmd.plugins ?? []);
|
|
346
|
+
let result;
|
|
347
|
+
let runError;
|
|
348
|
+
try {
|
|
349
|
+
for (const plugin of plugins) await plugin.setup?.(context);
|
|
350
|
+
if (typeof cmd.setup === "function") await cmd.setup(context);
|
|
351
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
352
|
+
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
353
|
+
const subCommandArgIndex = findSubCommandIndex(opts.rawArgs, cmdArgs);
|
|
354
|
+
const explicitName = opts.rawArgs[subCommandArgIndex];
|
|
355
|
+
if (explicitName) {
|
|
356
|
+
const subCommand = await _findSubCommand(subCommands, explicitName);
|
|
357
|
+
if (!subCommand) throw new CLIError(`Unknown command ${cyan(explicitName)}`, "E_UNKNOWN_COMMAND");
|
|
358
|
+
await runCommand(subCommand, { rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1) });
|
|
359
|
+
} else {
|
|
360
|
+
const defaultSubCommand = await resolveValue(cmd.default);
|
|
361
|
+
if (defaultSubCommand) {
|
|
362
|
+
if (cmd.run) throw new CLIError(`Cannot specify both 'run' and 'default' on the same command.`, "E_DEFAULT_CONFLICT");
|
|
363
|
+
const subCommand = await _findSubCommand(subCommands, defaultSubCommand);
|
|
364
|
+
if (!subCommand) throw new CLIError(`Default sub command ${cyan(defaultSubCommand)} not found in subCommands.`, "E_UNKNOWN_COMMAND");
|
|
365
|
+
await runCommand(subCommand, { rawArgs: opts.rawArgs });
|
|
366
|
+
} else if (!cmd.run) throw new CLIError(`No command specified.`, "E_NO_COMMAND");
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (typeof cmd.run === "function") result = await cmd.run(context);
|
|
370
|
+
} catch (error) {
|
|
371
|
+
runError = error;
|
|
852
372
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
373
|
+
const cleanupErrors = [];
|
|
374
|
+
if (typeof cmd.cleanup === "function") try {
|
|
375
|
+
await cmd.cleanup(context);
|
|
376
|
+
} catch (error) {
|
|
377
|
+
cleanupErrors.push(error);
|
|
378
|
+
}
|
|
379
|
+
for (const plugin of [...plugins].reverse()) try {
|
|
380
|
+
await plugin.cleanup?.(context);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
cleanupErrors.push(error);
|
|
383
|
+
}
|
|
384
|
+
if (runError) throw runError;
|
|
385
|
+
if (cleanupErrors.length === 1) throw cleanupErrors[0];
|
|
386
|
+
if (cleanupErrors.length > 1) throw new Error("Multiple cleanup errors", { cause: cleanupErrors });
|
|
387
|
+
return { result };
|
|
388
|
+
}
|
|
389
|
+
async function resolveSubCommand(cmd, rawArgs, parent) {
|
|
390
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
391
|
+
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
392
|
+
const subCommandArgIndex = findSubCommandIndex(rawArgs, await resolveValue(cmd.args || {}));
|
|
393
|
+
const subCommandName = rawArgs[subCommandArgIndex];
|
|
394
|
+
const subCommand = await _findSubCommand(subCommands, subCommandName);
|
|
395
|
+
if (subCommand) return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);
|
|
865
396
|
}
|
|
866
|
-
|
|
867
|
-
function formatInstructionFooter(o2, e2) {
|
|
868
|
-
const r3 = [`${e2 ? `${styleText2("cyan", S_BAR)} ` : ""}${o2.join(" \u2022 ")}`];
|
|
869
|
-
return e2 && r3.push(styleText2("cyan", S_BAR_END)), r3;
|
|
397
|
+
return [cmd, parent];
|
|
870
398
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
399
|
+
async function _findSubCommand(subCommands, name) {
|
|
400
|
+
if (name in subCommands) return resolveValue(subCommands[name]);
|
|
401
|
+
for (const sub of Object.values(subCommands)) {
|
|
402
|
+
const resolved = await resolveValue(sub);
|
|
403
|
+
const meta = await resolveValue(resolved?.meta);
|
|
404
|
+
if (meta?.alias) {
|
|
405
|
+
if (toArray(meta.alias).includes(name)) return resolved;
|
|
877
406
|
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function findSubCommandIndex(rawArgs, argsDef) {
|
|
410
|
+
for (let i3 = 0; i3 < rawArgs.length; i3++) {
|
|
411
|
+
const arg = rawArgs[i3];
|
|
412
|
+
if (arg === "--") return -1;
|
|
413
|
+
if (arg.startsWith("-")) {
|
|
414
|
+
if (!arg.includes("=") && _isValueFlag(arg, argsDef)) i3++;
|
|
415
|
+
continue;
|
|
882
416
|
}
|
|
883
|
-
|
|
884
|
-
};
|
|
885
|
-
var limitOptions = ({
|
|
886
|
-
cursor: l3,
|
|
887
|
-
options: e2,
|
|
888
|
-
style: w2,
|
|
889
|
-
output: p2 = process.stdout,
|
|
890
|
-
maxItems: b2 = Number.POSITIVE_INFINITY,
|
|
891
|
-
columnPadding: C2 = 0,
|
|
892
|
-
rowPadding: r3 = 4
|
|
893
|
-
}) => {
|
|
894
|
-
const i3 = getColumns(p2) - C2, m2 = getRows(p2), M = styleText2("dim", "..."), v2 = Math.max(m2 - r3, 0), a3 = Math.max(Math.min(b2, v2), 5);
|
|
895
|
-
let f2 = 0;
|
|
896
|
-
l3 >= a3 - 3 && (f2 = Math.max(
|
|
897
|
-
Math.min(l3 - a3 + 3, e2.length - a3),
|
|
898
|
-
0
|
|
899
|
-
));
|
|
900
|
-
let d2 = a3 < e2.length && f2 > 0, c3 = a3 < e2.length && f2 + a3 < e2.length;
|
|
901
|
-
const W2 = Math.min(
|
|
902
|
-
f2 + a3,
|
|
903
|
-
e2.length
|
|
904
|
-
), s2 = [];
|
|
905
|
-
let g2 = 0;
|
|
906
|
-
d2 && g2++, c3 && g2++;
|
|
907
|
-
const T2 = f2 + (d2 ? 1 : 0), y2 = W2 - (c3 ? 1 : 0);
|
|
908
|
-
for (let t3 = T2; t3 < y2; t3++) {
|
|
909
|
-
const n4 = e2[t3], o2 = n4 ? w2(n4, t3 === l3) : "", h3 = wrapAnsi(o2, i3, {
|
|
910
|
-
hard: true,
|
|
911
|
-
trim: false
|
|
912
|
-
}).split(`
|
|
913
|
-
`);
|
|
914
|
-
s2.push(h3), g2 += h3.length;
|
|
417
|
+
return i3;
|
|
915
418
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
u4,
|
|
926
|
-
true
|
|
927
|
-
);
|
|
928
|
-
d2 ? ({ lineCount: o2, removals: t3 } = L(), o2 > u4 && (c3 || (u4 -= 1), { lineCount: o2, removals: n4 } = E2())) : (c3 || (u4 -= 1), { lineCount: o2, removals: n4 } = E2(), o2 > u4 && (u4 -= 1, { lineCount: o2, removals: t3 } = L())), t3 > 0 && (d2 = true, s2.splice(0, t3)), n4 > 0 && (c3 = true, s2.splice(s2.length - n4, n4));
|
|
419
|
+
return -1;
|
|
420
|
+
}
|
|
421
|
+
function _isValueFlag(flag, argsDef) {
|
|
422
|
+
const name = flag.replace(/^-{1,2}/, "");
|
|
423
|
+
const normalized = camelCase(name);
|
|
424
|
+
for (const [key, def] of Object.entries(argsDef)) {
|
|
425
|
+
if (def.type !== "string" && def.type !== "enum") continue;
|
|
426
|
+
if (normalized === camelCase(key)) return true;
|
|
427
|
+
if ((Array.isArray(def.alias) ? def.alias : def.alias ? [def.alias] : []).includes(name)) return true;
|
|
929
428
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
const r3 = e2 ? `${styleText2("gray", S_BAR)} ` : "";
|
|
962
|
-
return `${o2}${r3}${styleText2(["strikethrough", "dim"], c3)}${e2 ? `
|
|
963
|
-
${styleText2("gray", S_BAR)}` : ""}`;
|
|
964
|
-
}
|
|
965
|
-
default: {
|
|
966
|
-
const r3 = e2 ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e2 ? styleText2("cyan", S_BAR_END) : "";
|
|
967
|
-
return `${o2}${r3}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a3}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a3)}`}${i3.vertical ? e2 ? `
|
|
968
|
-
${styleText2("cyan", S_BAR)} ` : `
|
|
969
|
-
` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s2)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s2}`}
|
|
970
|
-
${g2}
|
|
971
|
-
`;
|
|
972
|
-
}
|
|
973
|
-
}
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
async function showUsage(cmd, parent) {
|
|
432
|
+
try {
|
|
433
|
+
console.log(await renderUsage(cmd, parent) + "\n");
|
|
434
|
+
} catch (error) {
|
|
435
|
+
console.error(error);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
var negativePrefixRe = /^no[-A-Z]/;
|
|
439
|
+
async function renderUsage(cmd, parent) {
|
|
440
|
+
const cmdMeta = await resolveValue(cmd.meta || {});
|
|
441
|
+
const cmdArgs = resolveArgs(await resolveValue(cmd.args || {}));
|
|
442
|
+
const parentMeta = await resolveValue(parent?.meta || {});
|
|
443
|
+
const commandName = `${parentMeta.name ? `${parentMeta.name} ` : ""}` + (cmdMeta.name || process.argv[1]);
|
|
444
|
+
const argLines = [];
|
|
445
|
+
const posLines = [];
|
|
446
|
+
const commandsLines = [];
|
|
447
|
+
const usageLine = [];
|
|
448
|
+
for (const arg of cmdArgs) if (arg.type === "positional") {
|
|
449
|
+
const name = arg.name.toUpperCase();
|
|
450
|
+
const isRequired = arg.required !== false && arg.default === void 0;
|
|
451
|
+
posLines.push([cyan(name + renderValueHint(arg)), renderDescription(arg, isRequired)]);
|
|
452
|
+
usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
|
|
453
|
+
} else {
|
|
454
|
+
const isRequired = arg.required === true && arg.default === void 0;
|
|
455
|
+
const argStr = [...(arg.alias || []).map((a3) => `-${a3}`), `--${arg.name}`].join(", ") + renderValueHint(arg);
|
|
456
|
+
argLines.push([cyan(argStr), renderDescription(arg, isRequired)]);
|
|
457
|
+
if (arg.type === "boolean" && (arg.default === true || arg.negativeDescription) && !negativePrefixRe.test(arg.name)) {
|
|
458
|
+
const negativeArgStr = [...(arg.alias || []).map((a3) => `--no-${a3}`), `--no-${arg.name}`].join(", ");
|
|
459
|
+
argLines.push([cyan(negativeArgStr), [arg.negativeDescription, isRequired ? gray("(Required)") : ""].filter(Boolean).join(" ")]);
|
|
974
460
|
}
|
|
975
|
-
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
spacing: l3 = 1,
|
|
988
|
-
withGuide: c3
|
|
989
|
-
} = {}) => {
|
|
990
|
-
const t3 = [], o2 = c3 ?? settings.withGuide, f2 = o2 ? r3 : "", O2 = o2 ? `${e2} ` : "", u4 = o2 ? `${r3} ` : "";
|
|
991
|
-
for (let i3 = 0; i3 < l3; i3++)
|
|
992
|
-
t3.push(f2);
|
|
993
|
-
const g2 = Array.isArray(s2) ? s2 : s2.split(`
|
|
994
|
-
`);
|
|
995
|
-
if (g2.length > 0) {
|
|
996
|
-
const [i3, ...y2] = g2;
|
|
997
|
-
i3.length > 0 ? t3.push(`${O2}${i3}`) : t3.push(o2 ? e2 : "");
|
|
998
|
-
for (const p2 of y2)
|
|
999
|
-
p2.length > 0 ? t3.push(`${u4}${p2}`) : t3.push(o2 ? r3 : "");
|
|
461
|
+
if (isRequired) usageLine.push(`--${arg.name}` + renderValueHint(arg));
|
|
462
|
+
}
|
|
463
|
+
if (cmd.subCommands) {
|
|
464
|
+
const commandNames = [];
|
|
465
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
466
|
+
for (const [name, sub] of Object.entries(subCommands)) {
|
|
467
|
+
const meta = await resolveValue((await resolveValue(sub))?.meta);
|
|
468
|
+
if (meta?.hidden) continue;
|
|
469
|
+
const aliases = toArray(meta?.alias);
|
|
470
|
+
const label = [name, ...aliases].join(", ");
|
|
471
|
+
commandsLines.push([cyan(label), meta?.description || ""]);
|
|
472
|
+
commandNames.push(name, ...aliases);
|
|
1000
473
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
474
|
+
usageLine.push(commandNames.join("|"));
|
|
475
|
+
}
|
|
476
|
+
const usageLines = [];
|
|
477
|
+
const version = cmdMeta.version || parentMeta.version;
|
|
478
|
+
usageLines.push(gray(`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`), "");
|
|
479
|
+
const hasOptions = argLines.length > 0 || posLines.length > 0;
|
|
480
|
+
usageLines.push(`${underline(bold("USAGE"))} ${cyan(`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}`)}`, "");
|
|
481
|
+
if (posLines.length > 0) {
|
|
482
|
+
usageLines.push(underline(bold("ARGUMENTS")), "");
|
|
483
|
+
usageLines.push(formatLineColumns(posLines, " "));
|
|
484
|
+
usageLines.push("");
|
|
485
|
+
}
|
|
486
|
+
if (argLines.length > 0) {
|
|
487
|
+
usageLines.push(underline(bold("OPTIONS")), "");
|
|
488
|
+
usageLines.push(formatLineColumns(argLines, " "));
|
|
489
|
+
usageLines.push("");
|
|
490
|
+
}
|
|
491
|
+
if (commandsLines.length > 0) {
|
|
492
|
+
usageLines.push(underline(bold("COMMANDS")), "");
|
|
493
|
+
usageLines.push(formatLineColumns(commandsLines, " "));
|
|
494
|
+
usageLines.push("", `Use ${cyan(`${commandName} <command> --help`)} for more information about a command.`);
|
|
495
|
+
}
|
|
496
|
+
return usageLines.filter((l3) => typeof l3 === "string").join("\n");
|
|
497
|
+
}
|
|
498
|
+
function renderValueHint(arg) {
|
|
499
|
+
const valueHint = arg.valueHint ? `=<${arg.valueHint}>` : "";
|
|
500
|
+
const fallbackValueHint = valueHint || `=<${snakeCase(arg.name)}>`;
|
|
501
|
+
if (!arg.type || arg.type === "positional" || arg.type === "boolean") return valueHint;
|
|
502
|
+
if (arg.type === "enum" && arg.options?.length) return `=<${arg.options.join("|")}>`;
|
|
503
|
+
return fallbackValueHint;
|
|
504
|
+
}
|
|
505
|
+
function renderDescription(arg, required) {
|
|
506
|
+
const requiredHint = required ? gray("(Required)") : "";
|
|
507
|
+
const defaultHint = arg.default === void 0 ? "" : gray(`(Default: ${arg.default})`);
|
|
508
|
+
return [
|
|
509
|
+
arg.description,
|
|
510
|
+
requiredHint,
|
|
511
|
+
defaultHint
|
|
512
|
+
].filter(Boolean).join(" ");
|
|
513
|
+
}
|
|
514
|
+
async function runMain(cmd, opts = {}) {
|
|
515
|
+
const rawArgs = opts.rawArgs || process.argv.slice(2);
|
|
516
|
+
const showUsage$1 = opts.showUsage || showUsage;
|
|
517
|
+
try {
|
|
518
|
+
const builtinFlags = await _resolveBuiltinFlags(cmd);
|
|
519
|
+
if (builtinFlags.help.length > 0 && rawArgs.some((arg) => builtinFlags.help.includes(arg))) {
|
|
520
|
+
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
521
|
+
process.exit(0);
|
|
522
|
+
} else if (rawArgs.length === 1 && builtinFlags.version.includes(rawArgs[0])) {
|
|
523
|
+
const meta = typeof cmd.meta === "function" ? await cmd.meta() : await cmd.meta;
|
|
524
|
+
if (!meta?.version) throw new CLIError("No version specified", "E_NO_VERSION");
|
|
525
|
+
console.log(meta.version);
|
|
526
|
+
} else await runCommand(cmd, { rawArgs });
|
|
527
|
+
} catch (error) {
|
|
528
|
+
if (error instanceof CLIError) {
|
|
529
|
+
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
530
|
+
console.error(error.message);
|
|
531
|
+
} else console.error(error, "\n");
|
|
532
|
+
process.exit(1);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async function _resolveBuiltinFlags(cmd) {
|
|
536
|
+
const argsDef = await resolveValue(cmd.args || {});
|
|
537
|
+
const userNames = /* @__PURE__ */ new Set();
|
|
538
|
+
const userAliases = /* @__PURE__ */ new Set();
|
|
539
|
+
for (const [name, def] of Object.entries(argsDef)) {
|
|
540
|
+
userNames.add(name);
|
|
541
|
+
for (const alias of toArray(def.alias)) userAliases.add(alias);
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
help: _getBuiltinFlags("help", "h", userNames, userAliases),
|
|
545
|
+
version: _getBuiltinFlags("version", "v", userNames, userAliases)
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function _getBuiltinFlags(long, short, userNames, userAliases) {
|
|
549
|
+
if (userNames.has(long) || userAliases.has(long)) return [];
|
|
550
|
+
if (userNames.has(short) || userAliases.has(short)) return [`--${long}`];
|
|
551
|
+
return [`--${long}`, `-${short}`];
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// package.json
|
|
555
|
+
var package_default = {
|
|
556
|
+
name: "zapdev",
|
|
557
|
+
version: "1.1.0",
|
|
558
|
+
description: "Fast, performant and lightweight git chores and dev tools using your terminal and an OpenAI-compatible LLM endpoint.",
|
|
559
|
+
type: "module",
|
|
560
|
+
bin: {
|
|
561
|
+
zapdev: "./dist/index.js"
|
|
1004
562
|
},
|
|
1005
|
-
|
|
1006
|
-
|
|
563
|
+
files: [
|
|
564
|
+
"dist"
|
|
565
|
+
],
|
|
566
|
+
engines: {
|
|
567
|
+
node: ">=20"
|
|
1007
568
|
},
|
|
1008
|
-
|
|
1009
|
-
|
|
569
|
+
keywords: [
|
|
570
|
+
"git",
|
|
571
|
+
"cli",
|
|
572
|
+
"commit",
|
|
573
|
+
"conventional-commits",
|
|
574
|
+
"llm",
|
|
575
|
+
"ai"
|
|
576
|
+
],
|
|
577
|
+
author: "Matthieu Vagnon <hi@mvagnon.dev>",
|
|
578
|
+
license: "MIT",
|
|
579
|
+
repository: {
|
|
580
|
+
type: "git",
|
|
581
|
+
url: "git+https://github.com/mvagnon/zapdev.git"
|
|
1010
582
|
},
|
|
1011
|
-
|
|
1012
|
-
|
|
583
|
+
homepage: "https://github.com/mvagnon/zapdev#readme",
|
|
584
|
+
bugs: {
|
|
585
|
+
url: "https://github.com/mvagnon/zapdev/issues"
|
|
1013
586
|
},
|
|
1014
|
-
|
|
1015
|
-
|
|
587
|
+
publishConfig: {
|
|
588
|
+
access: "public"
|
|
1016
589
|
},
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
590
|
+
scripts: {
|
|
591
|
+
zapdev: "npm run build && node dist/index.js",
|
|
592
|
+
build: "esbuild src/cli.ts --bundle --platform=node --format=esm --target=node20 --loader:.md=text --outfile=dist/cli.js && esbuild src/index.ts --platform=node --format=esm --target=node20 --outfile=dist/index.js",
|
|
593
|
+
lint: "eslint .",
|
|
594
|
+
typecheck: "tsc --noEmit",
|
|
595
|
+
test: "vitest run",
|
|
596
|
+
prepack: "npm run build"
|
|
1020
597
|
},
|
|
1021
|
-
|
|
1022
|
-
|
|
598
|
+
devDependencies: {
|
|
599
|
+
"@clack/prompts": "^1.6.0",
|
|
600
|
+
"@eslint/js": "^10.0.1",
|
|
601
|
+
"@eslint/json": "^2.0.0",
|
|
602
|
+
"@eslint/markdown": "^8.0.2",
|
|
603
|
+
"@types/node": "^26.1.1",
|
|
604
|
+
citty: "^0.2.2",
|
|
605
|
+
esbuild: "^0.28.1",
|
|
606
|
+
eslint: "^10.6.0",
|
|
607
|
+
jiti: "^2.7.0",
|
|
608
|
+
tinyexec: "^1.2.4",
|
|
609
|
+
typescript: "^6.0.3",
|
|
610
|
+
"typescript-eslint": "^8.62.1",
|
|
611
|
+
vitest: "^4.1.9"
|
|
1023
612
|
}
|
|
1024
613
|
};
|
|
1025
|
-
var cancel = (o2 = "", t3) => {
|
|
1026
|
-
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
|
|
1027
|
-
i3.write(`${e2}${styleText2("red", o2)}
|
|
1028
614
|
|
|
1029
|
-
|
|
1030
|
-
};
|
|
1031
|
-
var intro = (o2 = "", t3) => {
|
|
1032
|
-
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
|
|
1033
|
-
i3.write(`${e2}${o2}
|
|
1034
|
-
`);
|
|
1035
|
-
};
|
|
1036
|
-
var outro = (o2 = "", t3) => {
|
|
1037
|
-
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
|
|
1038
|
-
${styleText2("gray", S_BAR_END)} ` : "";
|
|
1039
|
-
i3.write(`${e2}${o2}
|
|
615
|
+
// src/commands/commit.ts
|
|
616
|
+
import { basename } from "node:path";
|
|
1040
617
|
|
|
1041
|
-
|
|
1042
|
-
};
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
clear: () => a3("", 0, true),
|
|
1118
|
-
get isCancelled() {
|
|
1119
|
-
return S2;
|
|
1120
|
-
}
|
|
1121
|
-
};
|
|
1122
|
-
};
|
|
1123
|
-
var u2 = {
|
|
1124
|
-
light: unicodeOr("\u2500", "-"),
|
|
1125
|
-
heavy: unicodeOr("\u2501", "="),
|
|
1126
|
-
block: unicodeOr("\u2588", "#")
|
|
1127
|
-
};
|
|
1128
|
-
var SELECT_INSTRUCTIONS = [
|
|
1129
|
-
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
1130
|
-
`${styleText2("dim", "Enter:")} confirm`
|
|
1131
|
-
];
|
|
1132
|
-
var c = (t3, o2) => t3.includes(`
|
|
1133
|
-
`) ? t3.split(`
|
|
1134
|
-
`).map((d2) => o2(d2)).join(`
|
|
1135
|
-
`) : o2(t3);
|
|
1136
|
-
var select = (t3) => {
|
|
1137
|
-
const o2 = (n4, m2) => {
|
|
1138
|
-
if (n4 === void 0)
|
|
1139
|
-
return "";
|
|
1140
|
-
const s2 = n4.label ?? String(n4.value);
|
|
1141
|
-
switch (m2) {
|
|
1142
|
-
case "disabled":
|
|
1143
|
-
return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s2, (i3) => styleText2("gray", i3))}${n4.hint ? ` ${styleText2("dim", `(${n4.hint ?? "disabled"})`)}` : ""}`;
|
|
1144
|
-
case "selected":
|
|
1145
|
-
return `${c(s2, (i3) => styleText2("dim", i3))}`;
|
|
1146
|
-
case "active":
|
|
1147
|
-
return `${styleText2("green", S_RADIO_ACTIVE)} ${s2}${n4.hint ? ` ${styleText2("dim", `(${n4.hint})`)}` : ""}`;
|
|
1148
|
-
case "cancelled":
|
|
1149
|
-
return `${c(s2, (i3) => styleText2(["strikethrough", "dim"], i3))}`;
|
|
1150
|
-
default:
|
|
1151
|
-
return `${styleText2("dim", S_RADIO_INACTIVE)} ${c(s2, (i3) => styleText2("dim", i3))}`;
|
|
1152
|
-
}
|
|
1153
|
-
}, d2 = t3.showInstructions ?? true;
|
|
1154
|
-
return new n$1({
|
|
1155
|
-
options: t3.options,
|
|
1156
|
-
signal: t3.signal,
|
|
1157
|
-
input: t3.input,
|
|
1158
|
-
output: t3.output,
|
|
1159
|
-
initialValue: t3.initialValue,
|
|
1160
|
-
render() {
|
|
1161
|
-
const n4 = t3.withGuide ?? settings.withGuide, m2 = `${symbol(this.state)} `, s2 = `${symbolBar(this.state)} `, i3 = wrapTextWithPrefix(
|
|
1162
|
-
t3.output,
|
|
1163
|
-
t3.message,
|
|
1164
|
-
s2,
|
|
1165
|
-
m2
|
|
1166
|
-
), u4 = `${n4 ? `${styleText2("gray", S_BAR)}
|
|
1167
|
-
` : ""}${i3}
|
|
1168
|
-
`;
|
|
1169
|
-
switch (this.state) {
|
|
1170
|
-
case "submit": {
|
|
1171
|
-
const r3 = n4 ? `${styleText2("gray", S_BAR)} ` : "", a3 = wrapTextWithPrefix(
|
|
1172
|
-
t3.output,
|
|
1173
|
-
o2(this.options[this.cursor], "selected"),
|
|
1174
|
-
r3
|
|
1175
|
-
);
|
|
1176
|
-
return `${u4}${a3}`;
|
|
618
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
619
|
+
import { styleText } from "node:util";
|
|
620
|
+
import { stdout, stdin } from "node:process";
|
|
621
|
+
import * as l from "node:readline";
|
|
622
|
+
import l__default from "node:readline";
|
|
623
|
+
|
|
624
|
+
// node_modules/fast-string-truncated-width/dist/utils.js
|
|
625
|
+
var getCodePointsLength = /* @__PURE__ */ (() => {
|
|
626
|
+
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
627
|
+
return (input) => {
|
|
628
|
+
let surrogatePairsNr = 0;
|
|
629
|
+
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
630
|
+
while (SURROGATE_PAIR_RE.test(input)) {
|
|
631
|
+
surrogatePairsNr += 1;
|
|
632
|
+
}
|
|
633
|
+
return input.length - surrogatePairsNr;
|
|
634
|
+
};
|
|
635
|
+
})();
|
|
636
|
+
var isFullWidth = (x2) => {
|
|
637
|
+
return x2 === 12288 || x2 >= 65281 && x2 <= 65376 || x2 >= 65504 && x2 <= 65510;
|
|
638
|
+
};
|
|
639
|
+
var isWideNotCJKTNotEmoji = (x2) => {
|
|
640
|
+
return x2 === 8987 || x2 === 9001 || x2 >= 12272 && x2 <= 12287 || x2 >= 12289 && x2 <= 12350 || x2 >= 12441 && x2 <= 12543 || x2 >= 12549 && x2 <= 12591 || x2 >= 12593 && x2 <= 12686 || x2 >= 12688 && x2 <= 12771 || x2 >= 12783 && x2 <= 12830 || x2 >= 12832 && x2 <= 12871 || x2 >= 12880 && x2 <= 19903 || x2 >= 65040 && x2 <= 65049 || x2 >= 65072 && x2 <= 65106 || x2 >= 65108 && x2 <= 65126 || x2 >= 65128 && x2 <= 65131 || x2 >= 127488 && x2 <= 127490 || x2 >= 127504 && x2 <= 127547 || x2 >= 127552 && x2 <= 127560 || x2 >= 131072 && x2 <= 196605 || x2 >= 196608 && x2 <= 262141;
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
// node_modules/fast-string-truncated-width/dist/index.js
|
|
644
|
+
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
645
|
+
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
646
|
+
var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
647
|
+
var TAB_RE = /\t{1,1000}/y;
|
|
648
|
+
var EMOJI_RE = new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*", "yu");
|
|
649
|
+
var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
650
|
+
var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
|
|
651
|
+
var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
|
|
652
|
+
var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
653
|
+
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
654
|
+
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
655
|
+
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
|
|
656
|
+
const ANSI_WIDTH = 0;
|
|
657
|
+
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
658
|
+
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
659
|
+
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
660
|
+
const FULL_WIDTH_WIDTH = 2;
|
|
661
|
+
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
662
|
+
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
663
|
+
const PARSE_BLOCKS = [
|
|
664
|
+
[LATIN_RE, REGULAR_WIDTH],
|
|
665
|
+
[ANSI_RE, ANSI_WIDTH],
|
|
666
|
+
[CONTROL_RE, CONTROL_WIDTH],
|
|
667
|
+
[TAB_RE, TAB_WIDTH],
|
|
668
|
+
[EMOJI_RE, EMOJI_WIDTH],
|
|
669
|
+
[CJKT_WIDE_RE, WIDE_WIDTH]
|
|
670
|
+
];
|
|
671
|
+
let indexPrev = 0;
|
|
672
|
+
let index = 0;
|
|
673
|
+
let length = input.length;
|
|
674
|
+
let lengthExtra = 0;
|
|
675
|
+
let truncationEnabled = false;
|
|
676
|
+
let truncationIndex = length;
|
|
677
|
+
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
678
|
+
let unmatchedStart = 0;
|
|
679
|
+
let unmatchedEnd = 0;
|
|
680
|
+
let width = 0;
|
|
681
|
+
let widthExtra = 0;
|
|
682
|
+
outer: while (true) {
|
|
683
|
+
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
|
|
684
|
+
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
|
|
685
|
+
lengthExtra = 0;
|
|
686
|
+
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
|
|
687
|
+
const codePoint = char.codePointAt(0) || 0;
|
|
688
|
+
if (isFullWidth(codePoint)) {
|
|
689
|
+
widthExtra = FULL_WIDTH_WIDTH;
|
|
690
|
+
} else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
691
|
+
widthExtra = WIDE_WIDTH;
|
|
692
|
+
} else {
|
|
693
|
+
widthExtra = REGULAR_WIDTH;
|
|
1177
694
|
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
t3.output,
|
|
1181
|
-
o2(this.options[this.cursor], "cancelled"),
|
|
1182
|
-
r3
|
|
1183
|
-
);
|
|
1184
|
-
return `${u4}${a3}${n4 ? `
|
|
1185
|
-
${styleText2("gray", S_BAR)}` : ""}`;
|
|
695
|
+
if (width + widthExtra > truncationLimit) {
|
|
696
|
+
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
1186
697
|
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
`), f2 = p2.length + 1;
|
|
1191
|
-
return `${u4}${r3}${limitOptions({
|
|
1192
|
-
output: t3.output,
|
|
1193
|
-
cursor: this.cursor,
|
|
1194
|
-
options: this.options,
|
|
1195
|
-
maxItems: t3.maxItems,
|
|
1196
|
-
columnPadding: r3.length,
|
|
1197
|
-
rowPadding: a3 + f2,
|
|
1198
|
-
style: (g2, x2) => o2(g2, g2.disabled ? "disabled" : x2 ? "active" : "inactive")
|
|
1199
|
-
}).join(`
|
|
1200
|
-
${r3}`)}
|
|
1201
|
-
${b2}
|
|
1202
|
-
`;
|
|
698
|
+
if (width + widthExtra > LIMIT) {
|
|
699
|
+
truncationEnabled = true;
|
|
700
|
+
break outer;
|
|
1203
701
|
}
|
|
702
|
+
lengthExtra += char.length;
|
|
703
|
+
width += widthExtra;
|
|
1204
704
|
}
|
|
705
|
+
unmatchedStart = unmatchedEnd = 0;
|
|
1205
706
|
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
return `${s2.trim()}
|
|
1228
|
-
${r3}${o2}
|
|
1229
|
-
${d2}${n4}
|
|
1230
|
-
`;
|
|
1231
|
-
}
|
|
1232
|
-
case "submit": {
|
|
1233
|
-
const n4 = l3 ? ` ${styleText2("dim", l3)}` : "", r3 = i3 ? styleText2("gray", S_BAR) : "";
|
|
1234
|
-
return `${s2}${r3}${n4}`;
|
|
1235
|
-
}
|
|
1236
|
-
case "cancel": {
|
|
1237
|
-
const n4 = l3 ? ` ${styleText2(["strikethrough", "dim"], l3)}` : "", r3 = i3 ? styleText2("gray", S_BAR) : "";
|
|
1238
|
-
return `${s2}${r3}${n4}${l3.trim() ? `
|
|
1239
|
-
${r3}` : ""}`;
|
|
1240
|
-
}
|
|
1241
|
-
default: {
|
|
1242
|
-
const n4 = i3 ? `${styleText2("cyan", S_BAR)} ` : "", r3 = i3 ? styleText2("cyan", S_BAR_END) : "";
|
|
1243
|
-
return `${s2}${n4}${o2}
|
|
1244
|
-
${r3}
|
|
1245
|
-
`;
|
|
707
|
+
if (index >= length) {
|
|
708
|
+
break outer;
|
|
709
|
+
}
|
|
710
|
+
for (let i3 = 0, l3 = PARSE_BLOCKS.length; i3 < l3; i3++) {
|
|
711
|
+
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i3];
|
|
712
|
+
BLOCK_RE.lastIndex = index;
|
|
713
|
+
if (BLOCK_RE.test(input)) {
|
|
714
|
+
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
715
|
+
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
716
|
+
if (width + widthExtra > truncationLimit) {
|
|
717
|
+
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
718
|
+
}
|
|
719
|
+
if (width + widthExtra > LIMIT) {
|
|
720
|
+
truncationEnabled = true;
|
|
721
|
+
break outer;
|
|
722
|
+
}
|
|
723
|
+
width += widthExtra;
|
|
724
|
+
unmatchedStart = indexPrev;
|
|
725
|
+
unmatchedEnd = index;
|
|
726
|
+
index = indexPrev = BLOCK_RE.lastIndex;
|
|
727
|
+
continue outer;
|
|
1246
728
|
}
|
|
1247
729
|
}
|
|
730
|
+
index += 1;
|
|
1248
731
|
}
|
|
1249
|
-
|
|
732
|
+
return {
|
|
733
|
+
width: truncationEnabled ? truncationLimit : width,
|
|
734
|
+
index: truncationEnabled ? truncationIndex : length,
|
|
735
|
+
truncated: truncationEnabled,
|
|
736
|
+
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
737
|
+
};
|
|
738
|
+
};
|
|
739
|
+
var dist_default = getStringTruncatedWidth;
|
|
1250
740
|
|
|
1251
|
-
// node_modules/
|
|
1252
|
-
var
|
|
1253
|
-
|
|
1254
|
-
"
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
741
|
+
// node_modules/fast-string-width/dist/index.js
|
|
742
|
+
var NO_TRUNCATION2 = {
|
|
743
|
+
limit: Infinity,
|
|
744
|
+
ellipsis: "",
|
|
745
|
+
ellipsisWidth: 0
|
|
746
|
+
};
|
|
747
|
+
var fastStringWidth = (input, options = {}) => {
|
|
748
|
+
return dist_default(input, NO_TRUNCATION2, options).width;
|
|
749
|
+
};
|
|
750
|
+
var dist_default2 = fastStringWidth;
|
|
751
|
+
|
|
752
|
+
// node_modules/fast-wrap-ansi/lib/main.js
|
|
753
|
+
var ESC = "\x1B";
|
|
754
|
+
var CSI = "\x9B";
|
|
755
|
+
var END_CODE = 39;
|
|
756
|
+
var ANSI_ESCAPE_BELL = "\x07";
|
|
757
|
+
var ANSI_CSI = "[";
|
|
758
|
+
var ANSI_OSC = "]";
|
|
759
|
+
var ANSI_SGR_TERMINATOR = "m";
|
|
760
|
+
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
761
|
+
var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
762
|
+
var getClosingCode = (openingCode) => {
|
|
763
|
+
if (openingCode >= 30 && openingCode <= 37)
|
|
764
|
+
return 39;
|
|
765
|
+
if (openingCode >= 90 && openingCode <= 97)
|
|
766
|
+
return 39;
|
|
767
|
+
if (openingCode >= 40 && openingCode <= 47)
|
|
768
|
+
return 49;
|
|
769
|
+
if (openingCode >= 100 && openingCode <= 107)
|
|
770
|
+
return 49;
|
|
771
|
+
if (openingCode === 1 || openingCode === 2)
|
|
772
|
+
return 22;
|
|
773
|
+
if (openingCode === 3)
|
|
774
|
+
return 23;
|
|
775
|
+
if (openingCode === 4)
|
|
776
|
+
return 24;
|
|
777
|
+
if (openingCode === 7)
|
|
778
|
+
return 27;
|
|
779
|
+
if (openingCode === 8)
|
|
780
|
+
return 28;
|
|
781
|
+
if (openingCode === 9)
|
|
782
|
+
return 29;
|
|
783
|
+
if (openingCode === 0)
|
|
784
|
+
return 0;
|
|
785
|
+
return void 0;
|
|
786
|
+
};
|
|
787
|
+
var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
788
|
+
var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
789
|
+
var wrapWord = (rows, word, columns) => {
|
|
790
|
+
const characters = word[Symbol.iterator]();
|
|
791
|
+
let isInsideEscape = false;
|
|
792
|
+
let isInsideLinkEscape = false;
|
|
793
|
+
let lastRow = rows.at(-1);
|
|
794
|
+
let visible = lastRow === void 0 ? 0 : dist_default2(lastRow);
|
|
795
|
+
let currentCharacter = characters.next();
|
|
796
|
+
let nextCharacter = characters.next();
|
|
797
|
+
let rawCharacterIndex = 0;
|
|
798
|
+
while (!currentCharacter.done) {
|
|
799
|
+
const character = currentCharacter.value;
|
|
800
|
+
const characterLength = dist_default2(character);
|
|
801
|
+
if (visible + characterLength <= columns) {
|
|
802
|
+
rows[rows.length - 1] += character;
|
|
803
|
+
} else {
|
|
804
|
+
rows.push(character);
|
|
805
|
+
visible = 0;
|
|
1277
806
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
807
|
+
if (character === ESC || character === CSI) {
|
|
808
|
+
isInsideEscape = true;
|
|
809
|
+
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
810
|
+
}
|
|
811
|
+
if (isInsideEscape) {
|
|
812
|
+
if (isInsideLinkEscape) {
|
|
813
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
814
|
+
isInsideEscape = false;
|
|
815
|
+
isInsideLinkEscape = false;
|
|
816
|
+
}
|
|
817
|
+
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
818
|
+
isInsideEscape = false;
|
|
1285
819
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
continue;
|
|
820
|
+
} else {
|
|
821
|
+
visible += characterLength;
|
|
822
|
+
if (visible === columns && !nextCharacter.done) {
|
|
823
|
+
rows.push("");
|
|
824
|
+
visible = 0;
|
|
1292
825
|
}
|
|
1293
826
|
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
827
|
+
currentCharacter = nextCharacter;
|
|
828
|
+
nextCharacter = characters.next();
|
|
829
|
+
rawCharacterIndex += character.length;
|
|
1297
830
|
}
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
function upperFirst(str) {
|
|
1302
|
-
return str ? str[0].toUpperCase() + str.slice(1) : "";
|
|
1303
|
-
}
|
|
1304
|
-
function lowerFirst(str) {
|
|
1305
|
-
return str ? str[0].toLowerCase() + str.slice(1) : "";
|
|
1306
|
-
}
|
|
1307
|
-
function pascalCase(str, opts) {
|
|
1308
|
-
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => upperFirst(opts?.normalize ? p2.toLowerCase() : p2)).join("") : "";
|
|
1309
|
-
}
|
|
1310
|
-
function camelCase(str, opts) {
|
|
1311
|
-
return lowerFirst(pascalCase(str || "", opts));
|
|
1312
|
-
}
|
|
1313
|
-
function kebabCase(str, joiner) {
|
|
1314
|
-
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => p2.toLowerCase()).join(joiner ?? "-") : "";
|
|
1315
|
-
}
|
|
1316
|
-
function snakeCase(str) {
|
|
1317
|
-
return kebabCase(str || "", "_");
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
// node_modules/citty/dist/index.mjs
|
|
1321
|
-
import { parseArgs as parseArgs$1 } from "node:util";
|
|
1322
|
-
function toArray(val) {
|
|
1323
|
-
if (Array.isArray(val)) return val;
|
|
1324
|
-
return val === void 0 ? [] : [val];
|
|
1325
|
-
}
|
|
1326
|
-
function formatLineColumns(lines, linePrefix = "") {
|
|
1327
|
-
const maxLength = [];
|
|
1328
|
-
for (const line of lines) for (const [i3, element] of line.entries()) maxLength[i3] = Math.max(maxLength[i3] || 0, element.length);
|
|
1329
|
-
return lines.map((l3) => l3.map((c3, i3) => linePrefix + c3[i3 === 0 ? "padStart" : "padEnd"](maxLength[i3])).join(" ")).join("\n");
|
|
1330
|
-
}
|
|
1331
|
-
function resolveValue(input) {
|
|
1332
|
-
return typeof input === "function" ? input() : input;
|
|
1333
|
-
}
|
|
1334
|
-
var CLIError = class extends Error {
|
|
1335
|
-
code;
|
|
1336
|
-
constructor(message, code) {
|
|
1337
|
-
super(message);
|
|
1338
|
-
this.name = "CLIError";
|
|
1339
|
-
this.code = code;
|
|
831
|
+
lastRow = rows.at(-1);
|
|
832
|
+
if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
|
|
833
|
+
rows[rows.length - 2] += rows.pop();
|
|
1340
834
|
}
|
|
1341
835
|
};
|
|
1342
|
-
|
|
1343
|
-
const
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
const mainToAliases = /* @__PURE__ */ new Map();
|
|
1349
|
-
for (const [key, value] of Object.entries(aliasMap)) {
|
|
1350
|
-
const targets = value;
|
|
1351
|
-
for (const target of targets) {
|
|
1352
|
-
aliasToMain.set(key, target);
|
|
1353
|
-
if (!mainToAliases.has(target)) mainToAliases.set(target, []);
|
|
1354
|
-
mainToAliases.get(target).push(key);
|
|
1355
|
-
aliasToMain.set(target, key);
|
|
1356
|
-
if (!mainToAliases.has(key)) mainToAliases.set(key, []);
|
|
1357
|
-
mainToAliases.get(key).push(target);
|
|
836
|
+
var stringVisibleTrimSpacesRight = (string) => {
|
|
837
|
+
const words = string.split(" ");
|
|
838
|
+
let last = words.length;
|
|
839
|
+
while (last) {
|
|
840
|
+
if (dist_default2(words[last - 1])) {
|
|
841
|
+
break;
|
|
1358
842
|
}
|
|
843
|
+
last--;
|
|
1359
844
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
if (booleans.has(name)) return "boolean";
|
|
1363
|
-
const aliases = mainToAliases.get(name) || [];
|
|
1364
|
-
for (const alias of aliases) if (booleans.has(alias)) return "boolean";
|
|
1365
|
-
return "string";
|
|
845
|
+
if (last === words.length) {
|
|
846
|
+
return string;
|
|
1366
847
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
return
|
|
848
|
+
return words.slice(0, last).join(" ") + words.slice(last).join("");
|
|
849
|
+
};
|
|
850
|
+
var exec = (string, columns, options = {}) => {
|
|
851
|
+
if (options.trim !== false && string.trim() === "") {
|
|
852
|
+
return "";
|
|
1372
853
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
const arg = args[i3];
|
|
1389
|
-
if (arg === "--") {
|
|
1390
|
-
processedArgs.push(...args.slice(i3));
|
|
1391
|
-
break;
|
|
854
|
+
let returnValue = "";
|
|
855
|
+
let escapeCode;
|
|
856
|
+
let escapeUrl;
|
|
857
|
+
const words = string.split(" ");
|
|
858
|
+
let rows = [""];
|
|
859
|
+
let rowLength = 0;
|
|
860
|
+
for (let index = 0; index < words.length; index++) {
|
|
861
|
+
const word = words[index];
|
|
862
|
+
if (options.trim !== false) {
|
|
863
|
+
const row = rows.at(-1) ?? "";
|
|
864
|
+
const trimmed = row.trimStart();
|
|
865
|
+
if (row.length !== trimmed.length) {
|
|
866
|
+
rows[rows.length - 1] = trimmed;
|
|
867
|
+
rowLength = dist_default2(trimmed);
|
|
868
|
+
}
|
|
1392
869
|
}
|
|
1393
|
-
if (
|
|
1394
|
-
|
|
1395
|
-
|
|
870
|
+
if (index !== 0) {
|
|
871
|
+
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
872
|
+
rows.push("");
|
|
873
|
+
rowLength = 0;
|
|
874
|
+
}
|
|
875
|
+
if (rowLength || options.trim === false) {
|
|
876
|
+
rows[rows.length - 1] += " ";
|
|
877
|
+
rowLength++;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
const wordLength = dist_default2(word);
|
|
881
|
+
if (options.hard && wordLength > columns) {
|
|
882
|
+
const remainingColumns = columns - rowLength;
|
|
883
|
+
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
884
|
+
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
885
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
886
|
+
rows.push("");
|
|
887
|
+
}
|
|
888
|
+
wrapWord(rows, word, columns);
|
|
889
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
1396
890
|
continue;
|
|
1397
891
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
const out = { _: [] };
|
|
1415
|
-
out._ = parsed.positionals;
|
|
1416
|
-
for (const [key, value] of Object.entries(parsed.values)) {
|
|
1417
|
-
let coerced = value;
|
|
1418
|
-
if (getType(key) === "boolean" && typeof value === "string") coerced = value !== "false";
|
|
1419
|
-
else if (isStringType(key) && typeof value === "boolean") coerced = "";
|
|
1420
|
-
out[key] = coerced;
|
|
892
|
+
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
893
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
894
|
+
wrapWord(rows, word, columns);
|
|
895
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
896
|
+
continue;
|
|
897
|
+
}
|
|
898
|
+
rows.push("");
|
|
899
|
+
rowLength = 0;
|
|
900
|
+
}
|
|
901
|
+
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
902
|
+
wrapWord(rows, word, columns);
|
|
903
|
+
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
rows[rows.length - 1] += word;
|
|
907
|
+
rowLength += wordLength;
|
|
1421
908
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
const mainName = aliasToMain.get(name);
|
|
1425
|
-
if (mainName) out[mainName] = false;
|
|
1426
|
-
const aliases = mainToAliases.get(name);
|
|
1427
|
-
if (aliases) for (const alias of aliases) out[alias] = false;
|
|
909
|
+
if (options.trim !== false) {
|
|
910
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
1428
911
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
912
|
+
const preString = rows.join("\n");
|
|
913
|
+
let inSurrogate = false;
|
|
914
|
+
for (let i3 = 0; i3 < preString.length; i3++) {
|
|
915
|
+
const character = preString[i3];
|
|
916
|
+
returnValue += character;
|
|
917
|
+
if (!inSurrogate) {
|
|
918
|
+
inSurrogate = character >= "\uD800" && character <= "\uDBFF";
|
|
919
|
+
if (inSurrogate) {
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
} else {
|
|
923
|
+
inSurrogate = false;
|
|
924
|
+
}
|
|
925
|
+
if (character === ESC || character === CSI) {
|
|
926
|
+
GROUP_REGEX.lastIndex = i3 + 1;
|
|
927
|
+
const groupsResult = GROUP_REGEX.exec(preString);
|
|
928
|
+
const groups = groupsResult?.groups;
|
|
929
|
+
if (groups?.code !== void 0) {
|
|
930
|
+
const code = Number.parseFloat(groups.code);
|
|
931
|
+
escapeCode = code === END_CODE ? void 0 : code;
|
|
932
|
+
} else if (groups?.uri !== void 0) {
|
|
933
|
+
escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
if (preString[i3 + 1] === "\n") {
|
|
937
|
+
if (escapeUrl) {
|
|
938
|
+
returnValue += wrapAnsiHyperlink("");
|
|
939
|
+
}
|
|
940
|
+
const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
|
|
941
|
+
if (escapeCode && closingCode) {
|
|
942
|
+
returnValue += wrapAnsiCode(closingCode);
|
|
943
|
+
}
|
|
944
|
+
} else if (character === "\n") {
|
|
945
|
+
if (escapeCode && getClosingCode(escapeCode)) {
|
|
946
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
947
|
+
}
|
|
948
|
+
if (escapeUrl) {
|
|
949
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
1433
952
|
}
|
|
1434
|
-
return
|
|
953
|
+
return returnValue;
|
|
954
|
+
};
|
|
955
|
+
var CRLF_OR_LF = /\r?\n/;
|
|
956
|
+
function wrapAnsi(string, columns, options) {
|
|
957
|
+
return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
|
|
1435
958
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
959
|
+
|
|
960
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
961
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
962
|
+
import { ReadStream } from "node:tty";
|
|
963
|
+
function findCursor(s2, o2, l3) {
|
|
964
|
+
if (!l3.some((r3) => !r3.disabled))
|
|
965
|
+
return s2;
|
|
966
|
+
const t3 = s2 + o2, n4 = Math.max(l3.length - 1, 0), e2 = t3 < 0 ? n4 : t3 > n4 ? 0 : t3;
|
|
967
|
+
return l3[e2]?.disabled ? findCursor(e2, o2 < 0 ? -1 : 1, l3) : e2;
|
|
968
|
+
}
|
|
969
|
+
var a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
970
|
+
var t = [
|
|
971
|
+
"January",
|
|
972
|
+
"February",
|
|
973
|
+
"March",
|
|
974
|
+
"April",
|
|
975
|
+
"May",
|
|
976
|
+
"June",
|
|
977
|
+
"July",
|
|
978
|
+
"August",
|
|
979
|
+
"September",
|
|
980
|
+
"October",
|
|
981
|
+
"November",
|
|
982
|
+
"December"
|
|
983
|
+
];
|
|
984
|
+
var settings = {
|
|
985
|
+
actions: new Set(a$1),
|
|
986
|
+
aliases: /* @__PURE__ */ new Map([
|
|
987
|
+
// vim support
|
|
988
|
+
["k", "up"],
|
|
989
|
+
["j", "down"],
|
|
990
|
+
["h", "left"],
|
|
991
|
+
["l", "right"],
|
|
992
|
+
["", "cancel"],
|
|
993
|
+
// opinionated defaults!
|
|
994
|
+
["escape", "cancel"]
|
|
995
|
+
]),
|
|
996
|
+
messages: {
|
|
997
|
+
cancel: "Canceled",
|
|
998
|
+
error: "Something went wrong"
|
|
999
|
+
},
|
|
1000
|
+
withGuide: true,
|
|
1001
|
+
date: {
|
|
1002
|
+
monthNames: [...t],
|
|
1003
|
+
messages: {
|
|
1004
|
+
required: "Please enter a valid date",
|
|
1005
|
+
invalidMonth: "There are only 12 months in a year",
|
|
1006
|
+
invalidDay: (n4, e2) => `There are only ${n4} days in ${e2}`,
|
|
1007
|
+
afterMin: (n4) => `Date must be on or after ${n4.toISOString().slice(0, 10)}`,
|
|
1008
|
+
beforeMax: (n4) => `Date must be on or before ${n4.toISOString().slice(0, 10)}`
|
|
1466
1009
|
}
|
|
1467
1010
|
}
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
return
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
else if (arg.default === void 0 && arg.required !== false) throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`, "EARG");
|
|
1477
|
-
else parsedArgsProxy[arg.name] = arg.default;
|
|
1478
|
-
} else if (arg.type === "enum") {
|
|
1479
|
-
const argument = parsedArgsProxy[arg.name];
|
|
1480
|
-
const options = arg.options || [];
|
|
1481
|
-
if (argument !== void 0 && options.length > 0 && !options.includes(argument)) throw new CLIError(`Invalid value for argument: ${cyan(`--${arg.name}`)} (${cyan(argument)}). Expected one of: ${options.map((o2) => cyan(o2)).join(", ")}.`, "EARG");
|
|
1482
|
-
} else if (arg.required && parsedArgsProxy[arg.name] === void 0) throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
|
|
1483
|
-
return parsedArgsProxy;
|
|
1011
|
+
};
|
|
1012
|
+
function isActionKey(n4, e2) {
|
|
1013
|
+
if (typeof n4 == "string")
|
|
1014
|
+
return settings.aliases.get(n4) === e2;
|
|
1015
|
+
for (const s2 of n4)
|
|
1016
|
+
if (s2 !== void 0 && isActionKey(s2, e2))
|
|
1017
|
+
return true;
|
|
1018
|
+
return false;
|
|
1484
1019
|
}
|
|
1485
|
-
function
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
return
|
|
1020
|
+
function diffLines(i3, s2) {
|
|
1021
|
+
if (i3 === s2) return;
|
|
1022
|
+
const e2 = i3.split(`
|
|
1023
|
+
`), t3 = s2.split(`
|
|
1024
|
+
`), r3 = Math.max(e2.length, t3.length), f2 = [];
|
|
1025
|
+
for (let n4 = 0; n4 < r3; n4++)
|
|
1026
|
+
e2[n4] !== t3[n4] && f2.push(n4);
|
|
1027
|
+
return {
|
|
1028
|
+
lines: f2,
|
|
1029
|
+
numLinesBefore: e2.length,
|
|
1030
|
+
numLinesAfter: t3.length,
|
|
1031
|
+
numLines: r3
|
|
1032
|
+
};
|
|
1493
1033
|
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1034
|
+
var R = globalThis.process.platform.startsWith("win");
|
|
1035
|
+
var CANCEL_SYMBOL = /* @__PURE__ */ Symbol("clack:cancel");
|
|
1036
|
+
function isCancel(e2) {
|
|
1037
|
+
return e2 === CANCEL_SYMBOL;
|
|
1496
1038
|
}
|
|
1497
|
-
function
|
|
1498
|
-
|
|
1039
|
+
function setRawMode(e2, r3) {
|
|
1040
|
+
const o2 = e2;
|
|
1041
|
+
o2.isTTY && o2.setRawMode(r3);
|
|
1499
1042
|
}
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1043
|
+
function block({
|
|
1044
|
+
input: e2 = stdin,
|
|
1045
|
+
output: r3 = stdout,
|
|
1046
|
+
overwrite: o2 = true,
|
|
1047
|
+
hideCursor: t3 = true
|
|
1048
|
+
} = {}) {
|
|
1049
|
+
const s2 = l.createInterface({
|
|
1050
|
+
input: e2,
|
|
1051
|
+
output: r3,
|
|
1052
|
+
prompt: "",
|
|
1053
|
+
tabSize: 1
|
|
1054
|
+
});
|
|
1055
|
+
l.emitKeypressEvents(e2, s2), e2 instanceof ReadStream && e2.isTTY && e2.setRawMode(true);
|
|
1056
|
+
const n4 = (f2, { name: a3, sequence: p2 }) => {
|
|
1057
|
+
const c3 = String(f2);
|
|
1058
|
+
if (isActionKey([c3, a3, p2], "cancel")) {
|
|
1059
|
+
t3 && r3.write(import_sisteransi.cursor.show), process.exit(0);
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
if (!o2) return;
|
|
1063
|
+
const i3 = a3 === "return" ? 0 : -1, m2 = a3 === "return" ? -1 : 0;
|
|
1064
|
+
l.moveCursor(r3, i3, m2, () => {
|
|
1065
|
+
l.clearLine(r3, 1, () => {
|
|
1066
|
+
e2.once("keypress", n4);
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1508
1069
|
};
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1070
|
+
return t3 && r3.write(import_sisteransi.cursor.hide), e2.once("keypress", n4), () => {
|
|
1071
|
+
e2.off("keypress", n4), t3 && r3.write(import_sisteransi.cursor.show), e2 instanceof ReadStream && e2.isTTY && !R && e2.setRawMode(false), s2.terminal = false, s2.close();
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
var getColumns = (e2) => "columns" in e2 && typeof e2.columns == "number" ? e2.columns : 80;
|
|
1075
|
+
var getRows = (e2) => "rows" in e2 && typeof e2.rows == "number" ? e2.rows : 20;
|
|
1076
|
+
function wrapTextWithPrefix(e2, r3, o2, t3 = o2, s2 = o2, n4) {
|
|
1077
|
+
const f2 = getColumns(e2 ?? stdout);
|
|
1078
|
+
return wrapAnsi(r3, f2 - o2.length, {
|
|
1079
|
+
hard: true,
|
|
1080
|
+
trim: false
|
|
1081
|
+
}).split(`
|
|
1082
|
+
`).map((c3, i3, m2) => {
|
|
1083
|
+
const d2 = n4 ? n4(c3, i3) : c3;
|
|
1084
|
+
return i3 === 0 ? `${t3}${d2}` : i3 === m2.length - 1 ? `${s2}${d2}` : `${o2}${d2}`;
|
|
1085
|
+
}).join(`
|
|
1086
|
+
`);
|
|
1087
|
+
}
|
|
1088
|
+
function runValidation(e2, n4) {
|
|
1089
|
+
if ("~standard" in e2) {
|
|
1090
|
+
const a3 = e2["~standard"].validate(n4);
|
|
1091
|
+
if (a3 instanceof Promise)
|
|
1092
|
+
throw new TypeError(
|
|
1093
|
+
"Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic."
|
|
1094
|
+
);
|
|
1095
|
+
return a3.issues?.at(0)?.message;
|
|
1096
|
+
}
|
|
1097
|
+
return e2(n4);
|
|
1098
|
+
}
|
|
1099
|
+
var V = class {
|
|
1100
|
+
input;
|
|
1101
|
+
output;
|
|
1102
|
+
_abortSignal;
|
|
1103
|
+
rl;
|
|
1104
|
+
opts;
|
|
1105
|
+
_render;
|
|
1106
|
+
_track = false;
|
|
1107
|
+
_prevFrame = "";
|
|
1108
|
+
_subscribers = /* @__PURE__ */ new Map();
|
|
1109
|
+
_cursor = 0;
|
|
1110
|
+
state = "initial";
|
|
1111
|
+
error = "";
|
|
1112
|
+
value;
|
|
1113
|
+
userInput = "";
|
|
1114
|
+
constructor(t3, e2 = true) {
|
|
1115
|
+
const { input: i3 = stdin, output: n4 = stdout, render: s2, signal: r3, ...o2 } = t3;
|
|
1116
|
+
this.opts = o2, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = s2.bind(this), this._track = e2, this._abortSignal = r3, this.input = i3, this.output = n4;
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Unsubscribe all listeners
|
|
1120
|
+
*/
|
|
1121
|
+
unsubscribe() {
|
|
1122
|
+
this._subscribers.clear();
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Set a subscriber with opts
|
|
1126
|
+
* @param event - The event name
|
|
1127
|
+
*/
|
|
1128
|
+
setSubscriber(t3, e2) {
|
|
1129
|
+
const i3 = this._subscribers.get(t3) ?? [];
|
|
1130
|
+
i3.push(e2), this._subscribers.set(t3, i3);
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Subscribe to an event
|
|
1134
|
+
* @param event - The event name
|
|
1135
|
+
* @param cb - The callback
|
|
1136
|
+
*/
|
|
1137
|
+
on(t3, e2) {
|
|
1138
|
+
this.setSubscriber(t3, { cb: e2 });
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Subscribe to an event once
|
|
1142
|
+
* @param event - The event name
|
|
1143
|
+
* @param cb - The callback
|
|
1144
|
+
*/
|
|
1145
|
+
once(t3, e2) {
|
|
1146
|
+
this.setSubscriber(t3, { cb: e2, once: true });
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* Emit an event with data
|
|
1150
|
+
* @param event - The event name
|
|
1151
|
+
* @param data - The data to pass to the callback
|
|
1152
|
+
*/
|
|
1153
|
+
emit(t3, ...e2) {
|
|
1154
|
+
const i3 = this._subscribers.get(t3) ?? [], n4 = [];
|
|
1155
|
+
for (const s2 of i3)
|
|
1156
|
+
s2.cb(...e2), s2.once && n4.push(() => i3.splice(i3.indexOf(s2), 1));
|
|
1157
|
+
for (const s2 of n4)
|
|
1158
|
+
s2();
|
|
1159
|
+
}
|
|
1160
|
+
prompt() {
|
|
1161
|
+
return new Promise((t3) => {
|
|
1162
|
+
if (this._abortSignal) {
|
|
1163
|
+
if (this._abortSignal.aborted)
|
|
1164
|
+
return this.state = "cancel", this.close(), t3(CANCEL_SYMBOL);
|
|
1165
|
+
this._abortSignal.addEventListener(
|
|
1166
|
+
"abort",
|
|
1167
|
+
() => {
|
|
1168
|
+
this.state = "cancel", this.close();
|
|
1169
|
+
},
|
|
1170
|
+
{ once: true }
|
|
1171
|
+
);
|
|
1531
1172
|
}
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1173
|
+
this.rl = l__default.createInterface({
|
|
1174
|
+
input: this.input,
|
|
1175
|
+
tabSize: 2,
|
|
1176
|
+
prompt: "",
|
|
1177
|
+
escapeCodeTimeout: 50,
|
|
1178
|
+
terminal: true
|
|
1179
|
+
}), this.rl.prompt(), this.opts.initialUserInput !== void 0 && 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", () => {
|
|
1180
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t3(this.value);
|
|
1181
|
+
}), this.once("cancel", () => {
|
|
1182
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t3(CANCEL_SYMBOL);
|
|
1183
|
+
});
|
|
1184
|
+
});
|
|
1536
1185
|
}
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
await cmd.cleanup(context);
|
|
1540
|
-
} catch (error) {
|
|
1541
|
-
cleanupErrors.push(error);
|
|
1186
|
+
_isActionKey(t3, e2) {
|
|
1187
|
+
return t3 === " ";
|
|
1542
1188
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
} catch (error) {
|
|
1546
|
-
cleanupErrors.push(error);
|
|
1189
|
+
_shouldSubmit(t3, e2) {
|
|
1190
|
+
return true;
|
|
1547
1191
|
}
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
if (cleanupErrors.length > 1) throw new Error("Multiple cleanup errors", { cause: cleanupErrors });
|
|
1551
|
-
return { result };
|
|
1552
|
-
}
|
|
1553
|
-
async function resolveSubCommand(cmd, rawArgs, parent) {
|
|
1554
|
-
const subCommands = await resolveValue(cmd.subCommands);
|
|
1555
|
-
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
1556
|
-
const subCommandArgIndex = findSubCommandIndex(rawArgs, await resolveValue(cmd.args || {}));
|
|
1557
|
-
const subCommandName = rawArgs[subCommandArgIndex];
|
|
1558
|
-
const subCommand = await _findSubCommand(subCommands, subCommandName);
|
|
1559
|
-
if (subCommand) return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);
|
|
1192
|
+
_setValue(t3) {
|
|
1193
|
+
this.value = t3, this.emit("value", this.value);
|
|
1560
1194
|
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
async function _findSubCommand(subCommands, name) {
|
|
1564
|
-
if (name in subCommands) return resolveValue(subCommands[name]);
|
|
1565
|
-
for (const sub of Object.values(subCommands)) {
|
|
1566
|
-
const resolved = await resolveValue(sub);
|
|
1567
|
-
const meta = await resolveValue(resolved?.meta);
|
|
1568
|
-
if (meta?.alias) {
|
|
1569
|
-
if (toArray(meta.alias).includes(name)) return resolved;
|
|
1570
|
-
}
|
|
1195
|
+
_setUserInput(t3, e2) {
|
|
1196
|
+
this.userInput = t3 ?? "", this.emit("userInput", this.userInput), e2 && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
|
|
1571
1197
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
if (
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1198
|
+
_clearUserInput() {
|
|
1199
|
+
this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
|
|
1200
|
+
}
|
|
1201
|
+
onKeypress(t3, e2) {
|
|
1202
|
+
if (this._track && e2.name !== "return" && (e2.name && this._isActionKey(t3, e2) && 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"), e2?.name && (!this._track && settings.aliases.has(e2.name) && this.emit("cursor", settings.aliases.get(e2.name)), settings.actions.has(e2.name) && this.emit("cursor", e2.name)), t3 && (t3.toLowerCase() === "y" || t3.toLowerCase() === "n") && this.emit("confirm", t3.toLowerCase() === "y"), this.emit("key", t3, e2), e2?.name === "return" && this._shouldSubmit(t3, e2)) {
|
|
1203
|
+
if (this.opts.validate) {
|
|
1204
|
+
const i3 = runValidation(this.opts.validate, this.value);
|
|
1205
|
+
i3 && (this.error = i3 instanceof Error ? i3.message : i3, this.state = "error", this.rl?.write(this.userInput));
|
|
1206
|
+
}
|
|
1207
|
+
this.state !== "error" && (this.state = "submit");
|
|
1580
1208
|
}
|
|
1581
|
-
|
|
1209
|
+
isActionKey([t3, e2?.name, e2?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
1582
1210
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
const name = flag.replace(/^-{1,2}/, "");
|
|
1587
|
-
const normalized = camelCase(name);
|
|
1588
|
-
for (const [key, def] of Object.entries(argsDef)) {
|
|
1589
|
-
if (def.type !== "string" && def.type !== "enum") continue;
|
|
1590
|
-
if (normalized === camelCase(key)) return true;
|
|
1591
|
-
if ((Array.isArray(def.alias) ? def.alias : def.alias ? [def.alias] : []).includes(name)) return true;
|
|
1211
|
+
close() {
|
|
1212
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
1213
|
+
`), setRawMode(this.input, false), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
1592
1214
|
}
|
|
1593
|
-
|
|
1594
|
-
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
console.log(await renderUsage(cmd, parent) + "\n");
|
|
1598
|
-
} catch (error) {
|
|
1599
|
-
console.error(error);
|
|
1215
|
+
restoreCursor() {
|
|
1216
|
+
const t3 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
|
|
1217
|
+
`).length - 1;
|
|
1218
|
+
this.output.write(import_sisteransi.cursor.move(-999, t3 * -1));
|
|
1600
1219
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1220
|
+
render() {
|
|
1221
|
+
const t3 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, {
|
|
1222
|
+
hard: true,
|
|
1223
|
+
trim: false
|
|
1224
|
+
});
|
|
1225
|
+
if (t3 !== this._prevFrame) {
|
|
1226
|
+
if (this.state === "initial")
|
|
1227
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
1228
|
+
else {
|
|
1229
|
+
const e2 = diffLines(this._prevFrame, t3), i3 = getRows(this.output);
|
|
1230
|
+
if (this.restoreCursor(), e2) {
|
|
1231
|
+
const n4 = Math.max(0, e2.numLinesAfter - i3), s2 = Math.max(0, e2.numLinesBefore - i3);
|
|
1232
|
+
let r3 = e2.lines.find((o2) => o2 >= n4);
|
|
1233
|
+
if (r3 === void 0) {
|
|
1234
|
+
this._prevFrame = t3;
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
if (e2.lines.length === 1) {
|
|
1238
|
+
this.output.write(import_sisteransi.cursor.move(0, r3 - s2)), this.output.write(import_sisteransi.erase.lines(1));
|
|
1239
|
+
const o2 = t3.split(`
|
|
1240
|
+
`);
|
|
1241
|
+
this.output.write(o2[r3]), this._prevFrame = t3, this.output.write(import_sisteransi.cursor.move(0, o2.length - r3 - 1));
|
|
1242
|
+
return;
|
|
1243
|
+
} else if (e2.lines.length > 1) {
|
|
1244
|
+
if (n4 < s2)
|
|
1245
|
+
r3 = n4;
|
|
1246
|
+
else {
|
|
1247
|
+
const h3 = r3 - s2;
|
|
1248
|
+
h3 > 0 && this.output.write(import_sisteransi.cursor.move(0, h3));
|
|
1249
|
+
}
|
|
1250
|
+
this.output.write(import_sisteransi.erase.down());
|
|
1251
|
+
const f2 = t3.split(`
|
|
1252
|
+
`).slice(r3);
|
|
1253
|
+
this.output.write(f2.join(`
|
|
1254
|
+
`)), this._prevFrame = t3;
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
this.output.write(import_sisteransi.erase.down());
|
|
1259
|
+
}
|
|
1260
|
+
this.output.write(t3), this.state === "initial" && (this.state = "active"), this._prevFrame = t3;
|
|
1624
1261
|
}
|
|
1625
|
-
if (isRequired) usageLine.push(`--${arg.name}` + renderValueHint(arg));
|
|
1626
1262
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1263
|
+
};
|
|
1264
|
+
var r = class extends V {
|
|
1265
|
+
get cursor() {
|
|
1266
|
+
return this.value ? 0 : 1;
|
|
1267
|
+
}
|
|
1268
|
+
get _value() {
|
|
1269
|
+
return this.cursor === 0;
|
|
1270
|
+
}
|
|
1271
|
+
constructor(t3) {
|
|
1272
|
+
super(t3, false), this.value = !!t3.initialValue, this.on("userInput", () => {
|
|
1273
|
+
this.value = this._value;
|
|
1274
|
+
}), this.on("confirm", (i3) => {
|
|
1275
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i3, this.state = "submit", this.close();
|
|
1276
|
+
}), this.on("cursor", () => {
|
|
1277
|
+
this.value = !this.value;
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1281
|
+
var n$1 = class n extends V {
|
|
1282
|
+
options;
|
|
1283
|
+
cursor = 0;
|
|
1284
|
+
get _selectedValue() {
|
|
1285
|
+
return this.options[this.cursor];
|
|
1286
|
+
}
|
|
1287
|
+
changeValue() {
|
|
1288
|
+
const e2 = this._selectedValue;
|
|
1289
|
+
this.value = e2 === void 0 ? void 0 : e2.value;
|
|
1290
|
+
}
|
|
1291
|
+
constructor(e2) {
|
|
1292
|
+
super(e2, false), this.options = e2.options;
|
|
1293
|
+
const o2 = this.options.findIndex(({ value: s2 }) => s2 === e2.initialValue), t3 = o2 === -1 ? 0 : o2;
|
|
1294
|
+
this.cursor = this.options[t3]?.disabled ? findCursor(t3, 1, this.options) : t3, this.changeValue(), this.on("cursor", (s2) => {
|
|
1295
|
+
switch (s2) {
|
|
1296
|
+
case "left":
|
|
1297
|
+
case "up":
|
|
1298
|
+
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
1299
|
+
break;
|
|
1300
|
+
case "down":
|
|
1301
|
+
case "right":
|
|
1302
|
+
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
1303
|
+
break;
|
|
1304
|
+
}
|
|
1305
|
+
this.changeValue();
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
var n2 = class extends V {
|
|
1310
|
+
get userInputWithCursor() {
|
|
1311
|
+
if (this.state === "submit")
|
|
1312
|
+
return this.userInput;
|
|
1313
|
+
const t3 = this.userInput;
|
|
1314
|
+
if (this.cursor >= t3.length)
|
|
1315
|
+
return `${this.userInput}\u2588`;
|
|
1316
|
+
const r3 = t3.slice(0, this.cursor), s2 = t3.slice(this.cursor, this.cursor + 1), e2 = t3.slice(this.cursor + 1);
|
|
1317
|
+
return `${r3}${styleText("inverse", s2)}${e2}`;
|
|
1639
1318
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
usageLines.push(gray(`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`), "");
|
|
1643
|
-
const hasOptions = argLines.length > 0 || posLines.length > 0;
|
|
1644
|
-
usageLines.push(`${underline(bold("USAGE"))} ${cyan(`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}`)}`, "");
|
|
1645
|
-
if (posLines.length > 0) {
|
|
1646
|
-
usageLines.push(underline(bold("ARGUMENTS")), "");
|
|
1647
|
-
usageLines.push(formatLineColumns(posLines, " "));
|
|
1648
|
-
usageLines.push("");
|
|
1319
|
+
get cursor() {
|
|
1320
|
+
return this._cursor;
|
|
1649
1321
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1322
|
+
constructor(t3) {
|
|
1323
|
+
super({
|
|
1324
|
+
...t3,
|
|
1325
|
+
initialUserInput: t3.initialUserInput ?? t3.initialValue
|
|
1326
|
+
}), this.on("userInput", (r3) => {
|
|
1327
|
+
this._setValue(r3);
|
|
1328
|
+
}), this.on("finalize", () => {
|
|
1329
|
+
this.value || (this.value = t3.defaultValue), this.value === void 0 && (this.value = "");
|
|
1330
|
+
});
|
|
1654
1331
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
1335
|
+
import { styleText as styleText2, stripVTControlCharacters } from "node:util";
|
|
1336
|
+
import process$1 from "node:process";
|
|
1337
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
1338
|
+
function isUnicodeSupported() {
|
|
1339
|
+
if (process$1.platform !== "win32") {
|
|
1340
|
+
return process$1.env.TERM !== "linux";
|
|
1659
1341
|
}
|
|
1660
|
-
return
|
|
1661
|
-
}
|
|
1662
|
-
function renderValueHint(arg) {
|
|
1663
|
-
const valueHint = arg.valueHint ? `=<${arg.valueHint}>` : "";
|
|
1664
|
-
const fallbackValueHint = valueHint || `=<${snakeCase(arg.name)}>`;
|
|
1665
|
-
if (!arg.type || arg.type === "positional" || arg.type === "boolean") return valueHint;
|
|
1666
|
-
if (arg.type === "enum" && arg.options?.length) return `=<${arg.options.join("|")}>`;
|
|
1667
|
-
return fallbackValueHint;
|
|
1668
|
-
}
|
|
1669
|
-
function renderDescription(arg, required) {
|
|
1670
|
-
const requiredHint = required ? gray("(Required)") : "";
|
|
1671
|
-
const defaultHint = arg.default === void 0 ? "" : gray(`(Default: ${arg.default})`);
|
|
1672
|
-
return [
|
|
1673
|
-
arg.description,
|
|
1674
|
-
requiredHint,
|
|
1675
|
-
defaultHint
|
|
1676
|
-
].filter(Boolean).join(" ");
|
|
1342
|
+
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";
|
|
1677
1343
|
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1344
|
+
var unicode = isUnicodeSupported();
|
|
1345
|
+
var isCI = () => process.env.CI === "true";
|
|
1346
|
+
var unicodeOr = (o2, e2) => unicode ? o2 : e2;
|
|
1347
|
+
var S_STEP_ACTIVE = unicodeOr("\u25C6", "*");
|
|
1348
|
+
var S_STEP_CANCEL = unicodeOr("\u25A0", "x");
|
|
1349
|
+
var S_STEP_ERROR = unicodeOr("\u25B2", "x");
|
|
1350
|
+
var S_STEP_SUBMIT = unicodeOr("\u25C7", "o");
|
|
1351
|
+
var S_BAR_START = unicodeOr("\u250C", "T");
|
|
1352
|
+
var S_BAR = unicodeOr("\u2502", "|");
|
|
1353
|
+
var S_BAR_END = unicodeOr("\u2514", "\u2014");
|
|
1354
|
+
var S_BAR_START_RIGHT = unicodeOr("\u2510", "T");
|
|
1355
|
+
var S_BAR_END_RIGHT = unicodeOr("\u2518", "\u2014");
|
|
1356
|
+
var S_RADIO_ACTIVE = unicodeOr("\u25CF", ">");
|
|
1357
|
+
var S_RADIO_INACTIVE = unicodeOr("\u25CB", " ");
|
|
1358
|
+
var S_CHECKBOX_ACTIVE = unicodeOr("\u25FB", "[\u2022]");
|
|
1359
|
+
var S_CHECKBOX_SELECTED = unicodeOr("\u25FC", "[+]");
|
|
1360
|
+
var S_CHECKBOX_INACTIVE = unicodeOr("\u25FB", "[ ]");
|
|
1361
|
+
var S_PASSWORD_MASK = unicodeOr("\u25AA", "\u2022");
|
|
1362
|
+
var S_BAR_H = unicodeOr("\u2500", "-");
|
|
1363
|
+
var S_CORNER_TOP_RIGHT = unicodeOr("\u256E", "+");
|
|
1364
|
+
var S_CONNECT_LEFT = unicodeOr("\u251C", "+");
|
|
1365
|
+
var S_CORNER_BOTTOM_RIGHT = unicodeOr("\u256F", "+");
|
|
1366
|
+
var S_CORNER_BOTTOM_LEFT = unicodeOr("\u2570", "+");
|
|
1367
|
+
var S_CORNER_TOP_LEFT = unicodeOr("\u256D", "+");
|
|
1368
|
+
var S_INFO = unicodeOr("\u25CF", "\u2022");
|
|
1369
|
+
var S_SUCCESS = unicodeOr("\u25C6", "*");
|
|
1370
|
+
var S_WARN = unicodeOr("\u25B2", "!");
|
|
1371
|
+
var S_ERROR = unicodeOr("\u25A0", "x");
|
|
1372
|
+
var symbol = (o2) => {
|
|
1373
|
+
switch (o2) {
|
|
1374
|
+
case "initial":
|
|
1375
|
+
case "active":
|
|
1376
|
+
return styleText2("cyan", S_STEP_ACTIVE);
|
|
1377
|
+
case "cancel":
|
|
1378
|
+
return styleText2("red", S_STEP_CANCEL);
|
|
1379
|
+
case "error":
|
|
1380
|
+
return styleText2("yellow", S_STEP_ERROR);
|
|
1381
|
+
case "submit":
|
|
1382
|
+
return styleText2("green", S_STEP_SUBMIT);
|
|
1697
1383
|
}
|
|
1698
|
-
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1384
|
+
};
|
|
1385
|
+
var symbolBar = (o2) => {
|
|
1386
|
+
switch (o2) {
|
|
1387
|
+
case "initial":
|
|
1388
|
+
case "active":
|
|
1389
|
+
return styleText2("cyan", S_BAR);
|
|
1390
|
+
case "cancel":
|
|
1391
|
+
return styleText2("red", S_BAR);
|
|
1392
|
+
case "error":
|
|
1393
|
+
return styleText2("yellow", S_BAR);
|
|
1394
|
+
case "submit":
|
|
1395
|
+
return styleText2("green", S_BAR);
|
|
1706
1396
|
}
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
}
|
|
1712
|
-
function _getBuiltinFlags(long, short, userNames, userAliases) {
|
|
1713
|
-
if (userNames.has(long) || userAliases.has(long)) return [];
|
|
1714
|
-
if (userNames.has(short) || userAliases.has(short)) return [`--${long}`];
|
|
1715
|
-
return [`--${long}`, `-${short}`];
|
|
1397
|
+
};
|
|
1398
|
+
function formatInstructionFooter(o2, e2) {
|
|
1399
|
+
const r3 = [`${e2 ? `${styleText2("cyan", S_BAR)} ` : ""}${o2.join(" \u2022 ")}`];
|
|
1400
|
+
return e2 && r3.push(styleText2("cyan", S_BAR_END)), r3;
|
|
1716
1401
|
}
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1402
|
+
var I = (l3, e2, w2, p2, b2, C2 = false) => {
|
|
1403
|
+
let r3 = e2, O2 = 0;
|
|
1404
|
+
if (C2)
|
|
1405
|
+
for (let i3 = p2 - 1; i3 >= w2; i3--) {
|
|
1406
|
+
const m2 = l3[i3];
|
|
1407
|
+
if (m2 && (r3 -= m2.length), O2++, r3 <= b2) break;
|
|
1408
|
+
}
|
|
1409
|
+
else
|
|
1410
|
+
for (let i3 = w2; i3 < p2; i3++) {
|
|
1411
|
+
const m2 = l3[i3];
|
|
1412
|
+
if (m2 && (r3 -= m2.length), O2++, r3 <= b2) break;
|
|
1413
|
+
}
|
|
1414
|
+
return { lineCount: r3, removals: O2 };
|
|
1415
|
+
};
|
|
1416
|
+
var limitOptions = ({
|
|
1417
|
+
cursor: l3,
|
|
1418
|
+
options: e2,
|
|
1419
|
+
style: w2,
|
|
1420
|
+
output: p2 = process.stdout,
|
|
1421
|
+
maxItems: b2 = Number.POSITIVE_INFINITY,
|
|
1422
|
+
columnPadding: C2 = 0,
|
|
1423
|
+
rowPadding: r3 = 4
|
|
1424
|
+
}) => {
|
|
1425
|
+
const i3 = getColumns(p2) - C2, m2 = getRows(p2), M = styleText2("dim", "..."), v2 = Math.max(m2 - r3, 0), a3 = Math.max(Math.min(b2, v2), 5);
|
|
1426
|
+
let f2 = 0;
|
|
1427
|
+
l3 >= a3 - 3 && (f2 = Math.max(
|
|
1428
|
+
Math.min(l3 - a3 + 3, e2.length - a3),
|
|
1429
|
+
0
|
|
1430
|
+
));
|
|
1431
|
+
let d2 = a3 < e2.length && f2 > 0, c3 = a3 < e2.length && f2 + a3 < e2.length;
|
|
1432
|
+
const W2 = Math.min(
|
|
1433
|
+
f2 + a3,
|
|
1434
|
+
e2.length
|
|
1435
|
+
), s2 = [];
|
|
1436
|
+
let g2 = 0;
|
|
1437
|
+
d2 && g2++, c3 && g2++;
|
|
1438
|
+
const T2 = f2 + (d2 ? 1 : 0), y2 = W2 - (c3 ? 1 : 0);
|
|
1439
|
+
for (let t3 = T2; t3 < y2; t3++) {
|
|
1440
|
+
const n4 = e2[t3], o2 = n4 ? w2(n4, t3 === l3) : "", h3 = wrapAnsi(o2, i3, {
|
|
1441
|
+
hard: true,
|
|
1442
|
+
trim: false
|
|
1443
|
+
}).split(`
|
|
1444
|
+
`);
|
|
1445
|
+
s2.push(h3), g2 += h3.length;
|
|
1446
|
+
}
|
|
1447
|
+
if (g2 > v2) {
|
|
1448
|
+
let t3 = 0, n4 = 0, o2 = g2;
|
|
1449
|
+
const h3 = l3 - T2;
|
|
1450
|
+
let u4 = v2;
|
|
1451
|
+
const L = () => I(s2, o2, 0, h3, u4), E2 = () => I(
|
|
1452
|
+
s2,
|
|
1453
|
+
o2,
|
|
1454
|
+
h3 + 1,
|
|
1455
|
+
s2.length,
|
|
1456
|
+
u4,
|
|
1457
|
+
true
|
|
1458
|
+
);
|
|
1459
|
+
d2 ? ({ lineCount: o2, removals: t3 } = L(), o2 > u4 && (c3 || (u4 -= 1), { lineCount: o2, removals: n4 } = E2())) : (c3 || (u4 -= 1), { lineCount: o2, removals: n4 } = E2(), o2 > u4 && (u4 -= 1, { lineCount: o2, removals: t3 } = L())), t3 > 0 && (d2 = true, s2.splice(0, t3)), n4 > 0 && (c3 = true, s2.splice(s2.length - n4, n4));
|
|
1460
|
+
}
|
|
1461
|
+
const x2 = [];
|
|
1462
|
+
d2 && x2.push(M);
|
|
1463
|
+
for (const t3 of s2)
|
|
1464
|
+
for (const n4 of t3)
|
|
1465
|
+
x2.push(n4);
|
|
1466
|
+
return c3 && x2.push(M), x2;
|
|
1467
|
+
};
|
|
1468
|
+
var confirm = (i3) => {
|
|
1469
|
+
const a3 = i3.active ?? "Yes", s2 = i3.inactive ?? "No";
|
|
1470
|
+
return new r({
|
|
1471
|
+
active: a3,
|
|
1472
|
+
inactive: s2,
|
|
1473
|
+
signal: i3.signal,
|
|
1474
|
+
input: i3.input,
|
|
1475
|
+
output: i3.output,
|
|
1476
|
+
initialValue: i3.initialValue ?? true,
|
|
1477
|
+
render() {
|
|
1478
|
+
const e2 = i3.withGuide ?? settings.withGuide, u4 = `${symbol(this.state)} `, l3 = e2 ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(
|
|
1479
|
+
i3.output,
|
|
1480
|
+
i3.message,
|
|
1481
|
+
l3,
|
|
1482
|
+
u4
|
|
1483
|
+
), o2 = `${e2 ? `${styleText2("gray", S_BAR)}
|
|
1484
|
+
` : ""}${f2}
|
|
1485
|
+
`, c3 = this.value ? a3 : s2;
|
|
1486
|
+
switch (this.state) {
|
|
1487
|
+
case "submit": {
|
|
1488
|
+
const r3 = e2 ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1489
|
+
return `${o2}${r3}${styleText2("dim", c3)}`;
|
|
1490
|
+
}
|
|
1491
|
+
case "cancel": {
|
|
1492
|
+
const r3 = e2 ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1493
|
+
return `${o2}${r3}${styleText2(["strikethrough", "dim"], c3)}${e2 ? `
|
|
1494
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1495
|
+
}
|
|
1496
|
+
default: {
|
|
1497
|
+
const r3 = e2 ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e2 ? styleText2("cyan", S_BAR_END) : "";
|
|
1498
|
+
return `${o2}${r3}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a3}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a3)}`}${i3.vertical ? e2 ? `
|
|
1499
|
+
${styleText2("cyan", S_BAR)} ` : `
|
|
1500
|
+
` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s2)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s2}`}
|
|
1501
|
+
${g2}
|
|
1502
|
+
`;
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
}).prompt();
|
|
1507
|
+
};
|
|
1508
|
+
var MULTISELECT_INSTRUCTIONS = [
|
|
1509
|
+
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
1510
|
+
`${styleText2("dim", "Space:")} select`,
|
|
1511
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1512
|
+
];
|
|
1513
|
+
var log = {
|
|
1514
|
+
message: (s2 = [], {
|
|
1515
|
+
symbol: e2 = styleText2("gray", S_BAR),
|
|
1516
|
+
secondarySymbol: r3 = styleText2("gray", S_BAR),
|
|
1517
|
+
output: m2 = process.stdout,
|
|
1518
|
+
spacing: l3 = 1,
|
|
1519
|
+
withGuide: c3
|
|
1520
|
+
} = {}) => {
|
|
1521
|
+
const t3 = [], o2 = c3 ?? settings.withGuide, f2 = o2 ? r3 : "", O2 = o2 ? `${e2} ` : "", u4 = o2 ? `${r3} ` : "";
|
|
1522
|
+
for (let i3 = 0; i3 < l3; i3++)
|
|
1523
|
+
t3.push(f2);
|
|
1524
|
+
const g2 = Array.isArray(s2) ? s2 : s2.split(`
|
|
1525
|
+
`);
|
|
1526
|
+
if (g2.length > 0) {
|
|
1527
|
+
const [i3, ...y2] = g2;
|
|
1528
|
+
i3.length > 0 ? t3.push(`${O2}${i3}`) : t3.push(o2 ? e2 : "");
|
|
1529
|
+
for (const p2 of y2)
|
|
1530
|
+
p2.length > 0 ? t3.push(`${u4}${p2}`) : t3.push(o2 ? r3 : "");
|
|
1531
|
+
}
|
|
1532
|
+
m2.write(`${t3.join(`
|
|
1533
|
+
`)}
|
|
1534
|
+
`);
|
|
1726
1535
|
},
|
|
1727
|
-
|
|
1728
|
-
"
|
|
1729
|
-
],
|
|
1730
|
-
engines: {
|
|
1731
|
-
node: ">=20"
|
|
1536
|
+
info: (s2, e2) => {
|
|
1537
|
+
log.message(s2, { ...e2, symbol: styleText2("blue", S_INFO) });
|
|
1732
1538
|
},
|
|
1733
|
-
|
|
1734
|
-
"
|
|
1735
|
-
"cli",
|
|
1736
|
-
"commit",
|
|
1737
|
-
"conventional-commits",
|
|
1738
|
-
"ollama",
|
|
1739
|
-
"llm",
|
|
1740
|
-
"ai"
|
|
1741
|
-
],
|
|
1742
|
-
author: "Matthieu Vagnon <hi@mvagnon.dev>",
|
|
1743
|
-
license: "MIT",
|
|
1744
|
-
repository: {
|
|
1745
|
-
type: "git",
|
|
1746
|
-
url: "git+https://github.com/mvagnon/zapdev.git"
|
|
1539
|
+
success: (s2, e2) => {
|
|
1540
|
+
log.message(s2, { ...e2, symbol: styleText2("green", S_SUCCESS) });
|
|
1747
1541
|
},
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
url: "https://github.com/mvagnon/zapdev/issues"
|
|
1542
|
+
step: (s2, e2) => {
|
|
1543
|
+
log.message(s2, { ...e2, symbol: styleText2("green", S_STEP_SUBMIT) });
|
|
1751
1544
|
},
|
|
1752
|
-
|
|
1753
|
-
|
|
1545
|
+
warn: (s2, e2) => {
|
|
1546
|
+
log.message(s2, { ...e2, symbol: styleText2("yellow", S_WARN) });
|
|
1754
1547
|
},
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
lint: "eslint .",
|
|
1759
|
-
typecheck: "tsc --noEmit",
|
|
1760
|
-
test: "vitest run",
|
|
1761
|
-
prepack: "npm run build"
|
|
1548
|
+
/** alias for `log.warn()`. */
|
|
1549
|
+
warning: (s2, e2) => {
|
|
1550
|
+
log.warn(s2, e2);
|
|
1762
1551
|
},
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
"@eslint/js": "^10.0.1",
|
|
1766
|
-
"@eslint/json": "^2.0.0",
|
|
1767
|
-
"@eslint/markdown": "^8.0.2",
|
|
1768
|
-
"@types/node": "^26.1.1",
|
|
1769
|
-
citty: "^0.2.2",
|
|
1770
|
-
esbuild: "^0.28.1",
|
|
1771
|
-
eslint: "^10.6.0",
|
|
1772
|
-
jiti: "^2.7.0",
|
|
1773
|
-
tinyexec: "^1.2.4",
|
|
1774
|
-
typescript: "^6.0.3",
|
|
1775
|
-
"typescript-eslint": "^8.62.1",
|
|
1776
|
-
vitest: "^4.1.9"
|
|
1552
|
+
error: (s2, e2) => {
|
|
1553
|
+
log.message(s2, { ...e2, symbol: styleText2("red", S_ERROR) });
|
|
1777
1554
|
}
|
|
1778
1555
|
};
|
|
1556
|
+
var cancel = (o2 = "", t3) => {
|
|
1557
|
+
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
|
|
1558
|
+
i3.write(`${e2}${styleText2("red", o2)}
|
|
1559
|
+
|
|
1560
|
+
`);
|
|
1561
|
+
};
|
|
1562
|
+
var intro = (o2 = "", t3) => {
|
|
1563
|
+
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
|
|
1564
|
+
i3.write(`${e2}${o2}
|
|
1565
|
+
`);
|
|
1566
|
+
};
|
|
1567
|
+
var outro = (o2 = "", t3) => {
|
|
1568
|
+
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
|
|
1569
|
+
${styleText2("gray", S_BAR_END)} ` : "";
|
|
1570
|
+
i3.write(`${e2}${o2}
|
|
1571
|
+
|
|
1572
|
+
`);
|
|
1573
|
+
};
|
|
1574
|
+
var W = (l3) => styleText2("magenta", l3);
|
|
1575
|
+
var spinner = ({
|
|
1576
|
+
indicator: l3 = "dots",
|
|
1577
|
+
onCancel: h3,
|
|
1578
|
+
output: n4 = process.stdout,
|
|
1579
|
+
cancelMessage: G,
|
|
1580
|
+
errorMessage: O2,
|
|
1581
|
+
frames: E2 = unicode ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"],
|
|
1582
|
+
delay: F2 = unicode ? 80 : 120,
|
|
1583
|
+
signal: m2,
|
|
1584
|
+
...I3
|
|
1585
|
+
} = {}) => {
|
|
1586
|
+
const u4 = isCI();
|
|
1587
|
+
let M, T2, d2 = false, S2 = false, s2 = "", p2, w2 = performance.now();
|
|
1588
|
+
const x2 = getColumns(n4), k2 = I3?.styleFrame ?? W, g2 = (e2) => {
|
|
1589
|
+
const r3 = e2 > 1 ? O2 ?? settings.messages.error : G ?? settings.messages.cancel;
|
|
1590
|
+
S2 = e2 === 1, d2 && (a3(r3, e2), S2 && typeof h3 == "function" && h3());
|
|
1591
|
+
}, f2 = () => g2(2), i3 = () => g2(1), A = () => {
|
|
1592
|
+
process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i3), process.on("SIGTERM", i3), process.on("exit", g2), m2 && m2.addEventListener("abort", i3);
|
|
1593
|
+
}, H = () => {
|
|
1594
|
+
process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i3), process.removeListener("SIGTERM", i3), process.removeListener("exit", g2), m2 && m2.removeEventListener("abort", i3);
|
|
1595
|
+
}, y2 = () => {
|
|
1596
|
+
if (p2 === void 0) return;
|
|
1597
|
+
u4 && n4.write(`
|
|
1598
|
+
`);
|
|
1599
|
+
const r3 = wrapAnsi(p2, x2, {
|
|
1600
|
+
hard: true,
|
|
1601
|
+
trim: false
|
|
1602
|
+
}).split(`
|
|
1603
|
+
`);
|
|
1604
|
+
r3.length > 1 && n4.write(import_sisteransi2.cursor.up(r3.length - 1)), n4.write(import_sisteransi2.cursor.to(0)), n4.write(import_sisteransi2.erase.down());
|
|
1605
|
+
}, C2 = (e2) => e2.replace(/\.+$/, ""), _2 = (e2) => {
|
|
1606
|
+
const r3 = (performance.now() - e2) / 1e3, t3 = Math.floor(r3 / 60), o2 = Math.floor(r3 % 60);
|
|
1607
|
+
return t3 > 0 ? `[${t3}m ${o2}s]` : `[${o2}s]`;
|
|
1608
|
+
}, N2 = I3.withGuide ?? settings.withGuide, P2 = (e2 = "") => {
|
|
1609
|
+
d2 = true, M = block({ output: n4 }), s2 = C2(e2), w2 = performance.now(), N2 && n4.write(`${styleText2("gray", S_BAR)}
|
|
1610
|
+
`);
|
|
1611
|
+
let r3 = 0, t3 = 0;
|
|
1612
|
+
A(), T2 = setInterval(() => {
|
|
1613
|
+
if (u4 && s2 === p2)
|
|
1614
|
+
return;
|
|
1615
|
+
y2(), p2 = s2;
|
|
1616
|
+
const o2 = k2(E2[r3]);
|
|
1617
|
+
let v2;
|
|
1618
|
+
if (u4)
|
|
1619
|
+
v2 = `${o2} ${s2}...`;
|
|
1620
|
+
else if (l3 === "timer")
|
|
1621
|
+
v2 = `${o2} ${s2} ${_2(w2)}`;
|
|
1622
|
+
else {
|
|
1623
|
+
const B = ".".repeat(Math.floor(t3)).slice(0, 3);
|
|
1624
|
+
v2 = `${o2} ${s2}${B}`;
|
|
1625
|
+
}
|
|
1626
|
+
const j2 = wrapAnsi(v2, x2, {
|
|
1627
|
+
hard: true,
|
|
1628
|
+
trim: false
|
|
1629
|
+
});
|
|
1630
|
+
n4.write(j2), r3 = r3 + 1 < E2.length ? r3 + 1 : 0, t3 = t3 < 4 ? t3 + 0.125 : 0;
|
|
1631
|
+
}, F2);
|
|
1632
|
+
}, a3 = (e2 = "", r3 = 0, t3 = false) => {
|
|
1633
|
+
if (!d2) return;
|
|
1634
|
+
d2 = false, clearInterval(T2), y2();
|
|
1635
|
+
const o2 = r3 === 0 ? styleText2("green", S_STEP_SUBMIT) : r3 === 1 ? styleText2("red", S_STEP_CANCEL) : styleText2("red", S_STEP_ERROR);
|
|
1636
|
+
s2 = e2 ?? s2, t3 || (l3 === "timer" ? n4.write(`${o2} ${s2} ${_2(w2)}
|
|
1637
|
+
`) : n4.write(`${o2} ${s2}
|
|
1638
|
+
`)), H(), M();
|
|
1639
|
+
};
|
|
1640
|
+
return {
|
|
1641
|
+
start: P2,
|
|
1642
|
+
stop: (e2 = "") => a3(e2, 0),
|
|
1643
|
+
message: (e2 = "") => {
|
|
1644
|
+
s2 = C2(e2 ?? s2);
|
|
1645
|
+
},
|
|
1646
|
+
cancel: (e2 = "") => a3(e2, 1),
|
|
1647
|
+
error: (e2 = "") => a3(e2, 2),
|
|
1648
|
+
clear: () => a3("", 0, true),
|
|
1649
|
+
get isCancelled() {
|
|
1650
|
+
return S2;
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
};
|
|
1654
|
+
var u2 = {
|
|
1655
|
+
light: unicodeOr("\u2500", "-"),
|
|
1656
|
+
heavy: unicodeOr("\u2501", "="),
|
|
1657
|
+
block: unicodeOr("\u2588", "#")
|
|
1658
|
+
};
|
|
1659
|
+
var SELECT_INSTRUCTIONS = [
|
|
1660
|
+
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
1661
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1662
|
+
];
|
|
1663
|
+
var c = (t3, o2) => t3.includes(`
|
|
1664
|
+
`) ? t3.split(`
|
|
1665
|
+
`).map((d2) => o2(d2)).join(`
|
|
1666
|
+
`) : o2(t3);
|
|
1667
|
+
var select = (t3) => {
|
|
1668
|
+
const o2 = (n4, m2) => {
|
|
1669
|
+
if (n4 === void 0)
|
|
1670
|
+
return "";
|
|
1671
|
+
const s2 = n4.label ?? String(n4.value);
|
|
1672
|
+
switch (m2) {
|
|
1673
|
+
case "disabled":
|
|
1674
|
+
return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s2, (i3) => styleText2("gray", i3))}${n4.hint ? ` ${styleText2("dim", `(${n4.hint ?? "disabled"})`)}` : ""}`;
|
|
1675
|
+
case "selected":
|
|
1676
|
+
return `${c(s2, (i3) => styleText2("dim", i3))}`;
|
|
1677
|
+
case "active":
|
|
1678
|
+
return `${styleText2("green", S_RADIO_ACTIVE)} ${s2}${n4.hint ? ` ${styleText2("dim", `(${n4.hint})`)}` : ""}`;
|
|
1679
|
+
case "cancelled":
|
|
1680
|
+
return `${c(s2, (i3) => styleText2(["strikethrough", "dim"], i3))}`;
|
|
1681
|
+
default:
|
|
1682
|
+
return `${styleText2("dim", S_RADIO_INACTIVE)} ${c(s2, (i3) => styleText2("dim", i3))}`;
|
|
1683
|
+
}
|
|
1684
|
+
}, d2 = t3.showInstructions ?? true;
|
|
1685
|
+
return new n$1({
|
|
1686
|
+
options: t3.options,
|
|
1687
|
+
signal: t3.signal,
|
|
1688
|
+
input: t3.input,
|
|
1689
|
+
output: t3.output,
|
|
1690
|
+
initialValue: t3.initialValue,
|
|
1691
|
+
render() {
|
|
1692
|
+
const n4 = t3.withGuide ?? settings.withGuide, m2 = `${symbol(this.state)} `, s2 = `${symbolBar(this.state)} `, i3 = wrapTextWithPrefix(
|
|
1693
|
+
t3.output,
|
|
1694
|
+
t3.message,
|
|
1695
|
+
s2,
|
|
1696
|
+
m2
|
|
1697
|
+
), u4 = `${n4 ? `${styleText2("gray", S_BAR)}
|
|
1698
|
+
` : ""}${i3}
|
|
1699
|
+
`;
|
|
1700
|
+
switch (this.state) {
|
|
1701
|
+
case "submit": {
|
|
1702
|
+
const r3 = n4 ? `${styleText2("gray", S_BAR)} ` : "", a3 = wrapTextWithPrefix(
|
|
1703
|
+
t3.output,
|
|
1704
|
+
o2(this.options[this.cursor], "selected"),
|
|
1705
|
+
r3
|
|
1706
|
+
);
|
|
1707
|
+
return `${u4}${a3}`;
|
|
1708
|
+
}
|
|
1709
|
+
case "cancel": {
|
|
1710
|
+
const r3 = n4 ? `${styleText2("gray", S_BAR)} ` : "", a3 = wrapTextWithPrefix(
|
|
1711
|
+
t3.output,
|
|
1712
|
+
o2(this.options[this.cursor], "cancelled"),
|
|
1713
|
+
r3
|
|
1714
|
+
);
|
|
1715
|
+
return `${u4}${a3}${n4 ? `
|
|
1716
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1717
|
+
}
|
|
1718
|
+
default: {
|
|
1719
|
+
const r3 = n4 ? `${styleText2("cyan", S_BAR)} ` : "", a3 = u4.split(`
|
|
1720
|
+
`).length, p2 = d2 ? formatInstructionFooter(SELECT_INSTRUCTIONS, n4) : n4 ? [styleText2("cyan", S_BAR_END)] : [], b2 = p2.join(`
|
|
1721
|
+
`), f2 = p2.length + 1;
|
|
1722
|
+
return `${u4}${r3}${limitOptions({
|
|
1723
|
+
output: t3.output,
|
|
1724
|
+
cursor: this.cursor,
|
|
1725
|
+
options: this.options,
|
|
1726
|
+
maxItems: t3.maxItems,
|
|
1727
|
+
columnPadding: r3.length,
|
|
1728
|
+
rowPadding: a3 + f2,
|
|
1729
|
+
style: (g2, x2) => o2(g2, g2.disabled ? "disabled" : x2 ? "active" : "inactive")
|
|
1730
|
+
}).join(`
|
|
1731
|
+
${r3}`)}
|
|
1732
|
+
${b2}
|
|
1733
|
+
`;
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
}).prompt();
|
|
1738
|
+
};
|
|
1739
|
+
var i = `${styleText2("gray", S_BAR)} `;
|
|
1740
|
+
var text = (e2) => new n2({
|
|
1741
|
+
validate: e2.validate,
|
|
1742
|
+
placeholder: e2.placeholder,
|
|
1743
|
+
defaultValue: e2.defaultValue,
|
|
1744
|
+
initialValue: e2.initialValue,
|
|
1745
|
+
output: e2.output,
|
|
1746
|
+
signal: e2.signal,
|
|
1747
|
+
input: e2.input,
|
|
1748
|
+
render() {
|
|
1749
|
+
const i3 = e2?.withGuide ?? settings.withGuide, s2 = `${`${i3 ? `${styleText2("gray", S_BAR)}
|
|
1750
|
+
` : ""}${symbol(this.state)} `}${e2.message}
|
|
1751
|
+
`, c3 = e2.placeholder && e2.placeholder.length > 0 ? (
|
|
1752
|
+
// biome-ignore lint/style/noNonNullAssertion: guarded by placeholder.length > 0
|
|
1753
|
+
styleText2("inverse", e2.placeholder[0]) + styleText2("dim", e2.placeholder.slice(1))
|
|
1754
|
+
) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c3, l3 = this.value ?? "";
|
|
1755
|
+
switch (this.state) {
|
|
1756
|
+
case "error": {
|
|
1757
|
+
const n4 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r3 = i3 ? `${styleText2("yellow", S_BAR)} ` : "", d2 = i3 ? styleText2("yellow", S_BAR_END) : "";
|
|
1758
|
+
return `${s2.trim()}
|
|
1759
|
+
${r3}${o2}
|
|
1760
|
+
${d2}${n4}
|
|
1761
|
+
`;
|
|
1762
|
+
}
|
|
1763
|
+
case "submit": {
|
|
1764
|
+
const n4 = l3 ? ` ${styleText2("dim", l3)}` : "", r3 = i3 ? styleText2("gray", S_BAR) : "";
|
|
1765
|
+
return `${s2}${r3}${n4}`;
|
|
1766
|
+
}
|
|
1767
|
+
case "cancel": {
|
|
1768
|
+
const n4 = l3 ? ` ${styleText2(["strikethrough", "dim"], l3)}` : "", r3 = i3 ? styleText2("gray", S_BAR) : "";
|
|
1769
|
+
return `${s2}${r3}${n4}${l3.trim() ? `
|
|
1770
|
+
${r3}` : ""}`;
|
|
1771
|
+
}
|
|
1772
|
+
default: {
|
|
1773
|
+
const n4 = i3 ? `${styleText2("cyan", S_BAR)} ` : "", r3 = i3 ? styleText2("cyan", S_BAR_END) : "";
|
|
1774
|
+
return `${s2}${n4}${o2}
|
|
1775
|
+
${r3}
|
|
1776
|
+
`;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
}).prompt();
|
|
1779
1781
|
|
|
1780
1782
|
// src/types/commit.ts
|
|
1781
1783
|
var COMMIT_TYPES = [
|
|
@@ -1812,23 +1814,25 @@ function sanitizeCommitMessage(raw) {
|
|
|
1812
1814
|
}
|
|
1813
1815
|
|
|
1814
1816
|
// src/lib/config.ts
|
|
1815
|
-
var DEFAULT_OLLAMA_URL = "http://localhost:11434";
|
|
1816
|
-
var DEFAULT_MODEL = "deepseek-v4-flash:cloud";
|
|
1817
|
-
var DEFAULT_EFFORT = "low";
|
|
1818
1817
|
function resolveConfig(env = process.env, overrides = {}) {
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
model: overrides.model ?? env.
|
|
1822
|
-
|
|
1823
|
-
effort: overrides.effort ?? optionalValue(env.OLLAMA_EFFORT) ?? DEFAULT_EFFORT
|
|
1818
|
+
const config = {
|
|
1819
|
+
url: (overrides.url ?? env.ZD_URL)?.trim() ?? "",
|
|
1820
|
+
model: (overrides.model ?? env.ZD_MODEL)?.trim() ?? "",
|
|
1821
|
+
effort: (overrides.effort ?? env.ZD_EFFORT)?.trim() ?? ""
|
|
1824
1822
|
};
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1823
|
+
for (const [key, value] of Object.entries(config)) {
|
|
1824
|
+
if (!value) throw new Error(`Set ZD_${key.toUpperCase()} or --${key} before generating a commit message.`);
|
|
1825
|
+
}
|
|
1826
|
+
let url;
|
|
1827
|
+
try {
|
|
1828
|
+
url = new URL(config.url);
|
|
1829
|
+
} catch {
|
|
1830
|
+
throw new Error("URL must be a complete HTTP(S) Chat Completions endpoint.");
|
|
1831
|
+
}
|
|
1832
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
1833
|
+
throw new Error("URL must be a complete HTTP(S) Chat Completions endpoint.");
|
|
1834
|
+
}
|
|
1835
|
+
return config;
|
|
1832
1836
|
}
|
|
1833
1837
|
|
|
1834
1838
|
// src/lib/git.ts
|
|
@@ -2161,40 +2165,8 @@ var R2 = (e2, t3, n4) => {
|
|
|
2161
2165
|
};
|
|
2162
2166
|
var z = R2;
|
|
2163
2167
|
|
|
2164
|
-
// src/lib/branches.ts
|
|
2165
|
-
function parseDefaultBranch(originHead) {
|
|
2166
|
-
const trimmed = originHead.trim();
|
|
2167
|
-
if (!trimmed) return null;
|
|
2168
|
-
return trimmed.replace(/^origin\//, "");
|
|
2169
|
-
}
|
|
2170
|
-
function parseBranches(raw) {
|
|
2171
|
-
return raw.split("\n").map((branch) => branch.trim()).filter(Boolean);
|
|
2172
|
-
}
|
|
2173
|
-
function deletableBranches(all, protectedBranches) {
|
|
2174
|
-
const kept = new Set(protectedBranches.filter(Boolean));
|
|
2175
|
-
return all.filter((branch) => !kept.has(branch));
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
// src/lib/worktrees.ts
|
|
2179
|
-
var WORKTREE_PREFIX = "worktree ";
|
|
2180
|
-
var BRANCH_PREFIX = "branch ";
|
|
2181
|
-
function parseWorktrees(porcelain) {
|
|
2182
|
-
const worktrees = [];
|
|
2183
|
-
let current = null;
|
|
2184
|
-
for (const line of porcelain.split("\n")) {
|
|
2185
|
-
if (line.startsWith(WORKTREE_PREFIX)) {
|
|
2186
|
-
current = { path: line.slice(WORKTREE_PREFIX.length).trim(), branch: null };
|
|
2187
|
-
worktrees.push(current);
|
|
2188
|
-
} else if (current && line.startsWith(BRANCH_PREFIX)) {
|
|
2189
|
-
current.branch = line.slice(BRANCH_PREFIX.length).trim().replace(/^refs\/heads\//, "");
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
return worktrees;
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
2168
|
// src/lib/git.ts
|
|
2196
2169
|
var UPSTREAM_REF = "@{upstream}";
|
|
2197
|
-
var BRANCH_FORMAT = "%(refname:short)";
|
|
2198
2170
|
async function git(args, cwd) {
|
|
2199
2171
|
const result = await R2("git", args, { nodeOptions: { cwd } });
|
|
2200
2172
|
if (result.exitCode !== 0) {
|
|
@@ -2206,98 +2178,52 @@ async function tryGit(args, cwd) {
|
|
|
2206
2178
|
const result = await R2("git", args, { nodeOptions: { cwd } });
|
|
2207
2179
|
return result.exitCode === 0 ? result.stdout : null;
|
|
2208
2180
|
}
|
|
2209
|
-
async function stageAll() {
|
|
2210
|
-
await git(["add", "-A"]);
|
|
2181
|
+
async function stageAll(repo) {
|
|
2182
|
+
await git(["add", "-A"], repo);
|
|
2211
2183
|
}
|
|
2212
|
-
async function getStagedDiff() {
|
|
2213
|
-
return git(["diff", "--cached"]);
|
|
2184
|
+
async function getStagedDiff(repo) {
|
|
2185
|
+
return git(["diff", "--cached"], repo);
|
|
2214
2186
|
}
|
|
2215
|
-
async function commit(message) {
|
|
2216
|
-
await git(["commit", "-m", message]);
|
|
2187
|
+
async function commit(repo, message) {
|
|
2188
|
+
await git(["commit", "-m", message], repo);
|
|
2217
2189
|
}
|
|
2218
|
-
async function currentBranch() {
|
|
2219
|
-
return (await git(["symbolic-ref", "--short", "HEAD"])).trim();
|
|
2190
|
+
async function currentBranch(repo) {
|
|
2191
|
+
return (await git(["symbolic-ref", "--short", "HEAD"], repo)).trim();
|
|
2220
2192
|
}
|
|
2221
|
-
async function hasUpstream() {
|
|
2222
|
-
const result = await tryGit(["rev-parse", "--abbrev-ref", "--symbolic-full-name", UPSTREAM_REF]);
|
|
2193
|
+
async function hasUpstream(repo) {
|
|
2194
|
+
const result = await tryGit(["rev-parse", "--abbrev-ref", "--symbolic-full-name", UPSTREAM_REF], repo);
|
|
2223
2195
|
return result !== null;
|
|
2224
2196
|
}
|
|
2225
|
-
async function push() {
|
|
2226
|
-
await git(["push"]);
|
|
2197
|
+
async function push(repo) {
|
|
2198
|
+
await git(["push"], repo);
|
|
2227
2199
|
}
|
|
2228
|
-
async function pushSetUpstream(branch) {
|
|
2229
|
-
await git(["push", "-u", "origin", branch]);
|
|
2200
|
+
async function pushSetUpstream(repo, branch) {
|
|
2201
|
+
await git(["push", "-u", "origin", branch], repo);
|
|
2230
2202
|
}
|
|
2231
|
-
async function pullRebase() {
|
|
2232
|
-
await git(["pull", "--rebase"]);
|
|
2203
|
+
async function pullRebase(repo) {
|
|
2204
|
+
await git(["pull", "--rebase"], repo);
|
|
2233
2205
|
}
|
|
2234
|
-
async function pullMerge() {
|
|
2235
|
-
await git(["pull", "--no-rebase", "--no-edit"]);
|
|
2206
|
+
async function pullMerge(repo) {
|
|
2207
|
+
await git(["pull", "--no-rebase", "--no-edit"], repo);
|
|
2236
2208
|
}
|
|
2237
|
-
async function fetchRemote() {
|
|
2238
|
-
await git(["fetch"]);
|
|
2209
|
+
async function fetchRemote(repo) {
|
|
2210
|
+
await git(["fetch"], repo);
|
|
2239
2211
|
}
|
|
2240
|
-
async function behindCount() {
|
|
2241
|
-
const out = await tryGit(["rev-list", "--count", `HEAD..${UPSTREAM_REF}`]);
|
|
2212
|
+
async function behindCount(repo) {
|
|
2213
|
+
const out = await tryGit(["rev-list", "--count", `HEAD..${UPSTREAM_REF}`], repo);
|
|
2242
2214
|
return out === null ? 0 : Number(out.trim()) || 0;
|
|
2243
2215
|
}
|
|
2244
2216
|
async function findRepos(path) {
|
|
2245
|
-
|
|
2217
|
+
const root = await repoRoot(path);
|
|
2218
|
+
if (root) return [root];
|
|
2246
2219
|
const entries = await readdir(path, { withFileTypes: true }).catch(() => null);
|
|
2247
2220
|
if (!entries) return [];
|
|
2248
2221
|
const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules");
|
|
2249
|
-
const repos = await Promise.all(
|
|
2250
|
-
dirs.map(async (entry) => {
|
|
2251
|
-
const dir = join(path, entry.name);
|
|
2252
|
-
return await isGitRepo(dir) ? dir : null;
|
|
2253
|
-
})
|
|
2254
|
-
);
|
|
2222
|
+
const repos = await Promise.all(dirs.map((entry) => repoRoot(join(path, entry.name))));
|
|
2255
2223
|
return repos.filter((dir) => dir !== null).sort();
|
|
2256
2224
|
}
|
|
2257
|
-
async function
|
|
2258
|
-
|
|
2259
|
-
return entries?.some((entry) => entry.name === ".git" && entry.isDirectory()) ?? false;
|
|
2260
|
-
}
|
|
2261
|
-
async function fetchPrune(repo) {
|
|
2262
|
-
await git(["fetch", "--prune"], repo);
|
|
2263
|
-
}
|
|
2264
|
-
async function defaultBranch(repo) {
|
|
2265
|
-
const output = await tryGit(
|
|
2266
|
-
["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"],
|
|
2267
|
-
repo
|
|
2268
|
-
);
|
|
2269
|
-
return output === null ? null : parseDefaultBranch(output);
|
|
2270
|
-
}
|
|
2271
|
-
async function currentBranchAt(repo) {
|
|
2272
|
-
const output = await tryGit(["symbolic-ref", "--quiet", "--short", "HEAD"], repo);
|
|
2273
|
-
return output === null ? null : output.trim();
|
|
2274
|
-
}
|
|
2275
|
-
async function localBranches(repo) {
|
|
2276
|
-
return parseBranches(await git(["branch", `--format=${BRANCH_FORMAT}`], repo));
|
|
2277
|
-
}
|
|
2278
|
-
async function branchExists(repo, branch) {
|
|
2279
|
-
const local = await tryGit(["show-ref", "--verify", "--quiet", `refs/heads/${branch}`], repo);
|
|
2280
|
-
if (local !== null) return true;
|
|
2281
|
-
const remote = await tryGit(
|
|
2282
|
-
["show-ref", "--verify", "--quiet", `refs/remotes/origin/${branch}`],
|
|
2283
|
-
repo
|
|
2284
|
-
);
|
|
2285
|
-
return remote !== null;
|
|
2286
|
-
}
|
|
2287
|
-
async function listWorktrees(repo) {
|
|
2288
|
-
return parseWorktrees(await git(["worktree", "list", "--porcelain"], repo));
|
|
2289
|
-
}
|
|
2290
|
-
async function removeWorktree(repo, path) {
|
|
2291
|
-
await git(["worktree", "remove", "--force", path], repo);
|
|
2292
|
-
}
|
|
2293
|
-
async function switchBranch(repo, branch) {
|
|
2294
|
-
await git(["switch", branch], repo);
|
|
2295
|
-
}
|
|
2296
|
-
async function deleteBranch(repo, branch) {
|
|
2297
|
-
await git(["branch", "-D", branch], repo);
|
|
2298
|
-
}
|
|
2299
|
-
async function pull(repo) {
|
|
2300
|
-
await git(["pull"], repo);
|
|
2225
|
+
async function repoRoot(dir) {
|
|
2226
|
+
return (await tryGit(["rev-parse", "--show-toplevel"], dir))?.trim() ?? null;
|
|
2301
2227
|
}
|
|
2302
2228
|
|
|
2303
2229
|
// src/lib/errors.ts
|
|
@@ -2317,8 +2243,11 @@ async function hasGitleaks() {
|
|
|
2317
2243
|
throw error;
|
|
2318
2244
|
}
|
|
2319
2245
|
}
|
|
2320
|
-
async function scanStagedChanges() {
|
|
2321
|
-
const result = await R2("gitleaks", ["git", "--staged"], {
|
|
2246
|
+
async function scanStagedChanges(repo) {
|
|
2247
|
+
const result = await R2("gitleaks", ["git", "--staged"], {
|
|
2248
|
+
nodePath: false,
|
|
2249
|
+
nodeOptions: { cwd: repo }
|
|
2250
|
+
});
|
|
2322
2251
|
if (result.exitCode === 0) return;
|
|
2323
2252
|
const output = result.stderr.trim() || result.stdout.trim();
|
|
2324
2253
|
throw new Error(output || "gitleaks git --staged failed");
|
|
@@ -2330,65 +2259,49 @@ var commit_message_default = "You are zapdev, a CLI tool that creates commits qu
|
|
|
2330
2259
|
// src/prompts/index.ts
|
|
2331
2260
|
var COMMIT_SYSTEM_PROMPT = commit_message_default.trim();
|
|
2332
2261
|
|
|
2333
|
-
// src/lib/
|
|
2262
|
+
// src/lib/llm.ts
|
|
2334
2263
|
var REQUEST_TIMEOUT_MS = 25e3;
|
|
2335
|
-
var KEEP_ALIVE = "30m";
|
|
2336
2264
|
async function generateCommitMessage(diff, config, type) {
|
|
2337
2265
|
const systemPrompt = type ? applyCommitType(COMMIT_SYSTEM_PROMPT, type) : COMMIT_SYSTEM_PROMPT;
|
|
2338
2266
|
const messages = [
|
|
2339
2267
|
{ role: "system", content: systemPrompt },
|
|
2340
2268
|
{ role: "user", content: truncateDiff(diff) }
|
|
2341
2269
|
];
|
|
2342
|
-
let content;
|
|
2343
|
-
try {
|
|
2344
|
-
content = await chat(config, config.model, messages);
|
|
2345
|
-
} catch (error) {
|
|
2346
|
-
if (!config.backupModel || config.backupModel === config.model) throw error;
|
|
2347
|
-
try {
|
|
2348
|
-
content = await chat(config, config.backupModel, messages);
|
|
2349
|
-
} catch (backupError) {
|
|
2350
|
-
throw new AggregateError(
|
|
2351
|
-
[error, backupError],
|
|
2352
|
-
`Primary model failed: ${errorMessage(error)} Backup model failed: ${errorMessage(backupError)}`,
|
|
2353
|
-
{ cause: backupError }
|
|
2354
|
-
);
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
return sanitizeCommitMessage(content);
|
|
2358
|
-
}
|
|
2359
|
-
async function chat(config, model, messages) {
|
|
2360
|
-
const url = `${config.ollamaUrl}/api/chat`;
|
|
2361
2270
|
let response;
|
|
2271
|
+
let body;
|
|
2362
2272
|
try {
|
|
2363
|
-
response = await fetch(url, {
|
|
2273
|
+
response = await fetch(config.url, {
|
|
2364
2274
|
method: "POST",
|
|
2365
2275
|
headers: { "content-type": "application/json" },
|
|
2366
2276
|
body: JSON.stringify({
|
|
2367
|
-
model,
|
|
2277
|
+
model: config.model,
|
|
2368
2278
|
stream: false,
|
|
2369
|
-
|
|
2370
|
-
think: config.effort,
|
|
2371
|
-
options: { temperature: 0.2 },
|
|
2279
|
+
reasoning_effort: config.effort,
|
|
2372
2280
|
messages
|
|
2373
2281
|
}),
|
|
2374
2282
|
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
2375
2283
|
});
|
|
2284
|
+
const text2 = await response.text();
|
|
2285
|
+
try {
|
|
2286
|
+
body = JSON.parse(text2);
|
|
2287
|
+
} catch {
|
|
2288
|
+
body = null;
|
|
2289
|
+
}
|
|
2376
2290
|
} catch (error) {
|
|
2377
|
-
throw new Error(describeRequestError(error
|
|
2291
|
+
throw new Error(describeRequestError(error), { cause: error });
|
|
2378
2292
|
}
|
|
2379
|
-
const body = await response.json().catch(() => null);
|
|
2380
2293
|
if (!response.ok) {
|
|
2381
|
-
throw new Error(`
|
|
2294
|
+
throw new Error(`LLM error: ${serverError(body) ?? `HTTP ${response.status}`}`);
|
|
2382
2295
|
}
|
|
2383
2296
|
const content = messageContent(body);
|
|
2384
|
-
if (content === null) throw new Error("
|
|
2385
|
-
return content;
|
|
2297
|
+
if (content === null) throw new Error("LLM returned an unexpected response shape.");
|
|
2298
|
+
return sanitizeCommitMessage(content);
|
|
2386
2299
|
}
|
|
2387
|
-
function describeRequestError(error
|
|
2300
|
+
function describeRequestError(error) {
|
|
2388
2301
|
if (errorName(error) === "TimeoutError") {
|
|
2389
|
-
return `
|
|
2302
|
+
return `LLM did not answer within ${REQUEST_TIMEOUT_MS / 1e3}s.`;
|
|
2390
2303
|
}
|
|
2391
|
-
return
|
|
2304
|
+
return "Could not complete the LLM request. Check URL and endpoint availability.";
|
|
2392
2305
|
}
|
|
2393
2306
|
function errorName(error) {
|
|
2394
2307
|
if (error && typeof error === "object" && "name" in error && typeof error.name === "string") {
|
|
@@ -2397,14 +2310,18 @@ function errorName(error) {
|
|
|
2397
2310
|
return null;
|
|
2398
2311
|
}
|
|
2399
2312
|
function serverError(body) {
|
|
2400
|
-
if (body
|
|
2401
|
-
|
|
2313
|
+
if (!body || typeof body !== "object" || !("error" in body)) return null;
|
|
2314
|
+
const error = body.error;
|
|
2315
|
+
if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
|
|
2316
|
+
return error.message;
|
|
2402
2317
|
}
|
|
2403
2318
|
return null;
|
|
2404
2319
|
}
|
|
2405
2320
|
function messageContent(body) {
|
|
2406
|
-
if (!body || typeof body !== "object" || !("
|
|
2407
|
-
const
|
|
2321
|
+
if (!body || typeof body !== "object" || !("choices" in body) || !Array.isArray(body.choices)) return null;
|
|
2322
|
+
const choice = body.choices[0];
|
|
2323
|
+
if (!choice || typeof choice !== "object" || !("message" in choice)) return null;
|
|
2324
|
+
const message = choice.message;
|
|
2408
2325
|
if (!message || typeof message !== "object" || !("content" in message)) return null;
|
|
2409
2326
|
return typeof message.content === "string" ? message.content : null;
|
|
2410
2327
|
}
|
|
@@ -2413,12 +2330,20 @@ function messageContent(body) {
|
|
|
2413
2330
|
var commitCommand = defineCommand({
|
|
2414
2331
|
meta: {
|
|
2415
2332
|
name: "commit",
|
|
2416
|
-
description: "
|
|
2333
|
+
description: "Generate and review commit messages for the current repo or direct child repos."
|
|
2417
2334
|
},
|
|
2418
2335
|
args: {
|
|
2336
|
+
url: {
|
|
2337
|
+
type: "string",
|
|
2338
|
+
description: "Override $ZD_URL, the complete Chat Completions endpoint."
|
|
2339
|
+
},
|
|
2419
2340
|
model: {
|
|
2420
2341
|
type: "string",
|
|
2421
|
-
description: "Override the
|
|
2342
|
+
description: "Override the model configured with $ZD_MODEL."
|
|
2343
|
+
},
|
|
2344
|
+
effort: {
|
|
2345
|
+
type: "string",
|
|
2346
|
+
description: "Override $ZD_EFFORT, sent as reasoning_effort."
|
|
2422
2347
|
},
|
|
2423
2348
|
type: {
|
|
2424
2349
|
type: "string",
|
|
@@ -2453,10 +2378,6 @@ var commitCommand = defineCommand({
|
|
|
2453
2378
|
},
|
|
2454
2379
|
async run({ args }) {
|
|
2455
2380
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2456
|
-
const config = resolveConfig(
|
|
2457
|
-
process.env,
|
|
2458
|
-
args.model ? { model: args.model } : {}
|
|
2459
|
-
);
|
|
2460
2381
|
if (args.rebase && args.merge) {
|
|
2461
2382
|
log.error("Choose either --rebase or --merge, not both.");
|
|
2462
2383
|
process.exitCode = 1;
|
|
@@ -2471,145 +2392,178 @@ var commitCommand = defineCommand({
|
|
|
2471
2392
|
process.exitCode = 1;
|
|
2472
2393
|
return;
|
|
2473
2394
|
}
|
|
2395
|
+
let config;
|
|
2396
|
+
try {
|
|
2397
|
+
config = resolveConfig(process.env, {
|
|
2398
|
+
url: args.url,
|
|
2399
|
+
model: args.model,
|
|
2400
|
+
effort: args.effort
|
|
2401
|
+
});
|
|
2402
|
+
} catch (error) {
|
|
2403
|
+
log.error(errorMessage(error));
|
|
2404
|
+
process.exitCode = 1;
|
|
2405
|
+
return;
|
|
2406
|
+
}
|
|
2474
2407
|
if (interactive) intro("zapdev commit");
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
log.warn("Nothing to commit.");
|
|
2408
|
+
const repos = await findRepos(process.cwd());
|
|
2409
|
+
if (repos.length === 0) {
|
|
2410
|
+
log.warn("No git repository found here or in direct children.");
|
|
2479
2411
|
if (interactive) outro("Nothing to do.");
|
|
2480
2412
|
return;
|
|
2481
2413
|
}
|
|
2414
|
+
let scan;
|
|
2482
2415
|
try {
|
|
2483
|
-
|
|
2484
|
-
const scanLoader = interactive ? spinner() : void 0;
|
|
2485
|
-
scanLoader?.start("Scanning staged changes with Gitleaks");
|
|
2486
|
-
try {
|
|
2487
|
-
await scanStagedChanges();
|
|
2488
|
-
scanLoader?.stop("No leaks found");
|
|
2489
|
-
} catch (error) {
|
|
2490
|
-
scanLoader?.error("Gitleaks check failed");
|
|
2491
|
-
throw error;
|
|
2492
|
-
}
|
|
2493
|
-
} else {
|
|
2494
|
-
log.info("Gitleaks not found, skipping secret scan.");
|
|
2495
|
-
}
|
|
2416
|
+
scan = await hasGitleaks();
|
|
2496
2417
|
} catch (error) {
|
|
2497
2418
|
log.error(`Gitleaks check failed: ${errorMessage(error)}`);
|
|
2498
2419
|
process.exitCode = 1;
|
|
2499
2420
|
return;
|
|
2500
2421
|
}
|
|
2422
|
+
if (!scan) log.info("Gitleaks not found, skipping secret scan.");
|
|
2501
2423
|
const loader = interactive ? spinner() : void 0;
|
|
2502
|
-
loader?.start("
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2424
|
+
loader?.start("Preparing repositories and generating commit messages in parallel");
|
|
2425
|
+
const results = await Promise.allSettled(repos.map(async (repo) => {
|
|
2426
|
+
if (!args.staged) await stageAll(repo);
|
|
2427
|
+
const diff = await getStagedDiff(repo);
|
|
2428
|
+
if (!diff.trim()) return null;
|
|
2429
|
+
if (scan) await scanStagedChanges(repo);
|
|
2430
|
+
const message = await generateCommitMessage(diff, config, type);
|
|
2431
|
+
if (!message) throw new Error("The model returned an empty message.");
|
|
2432
|
+
return { repo, message };
|
|
2433
|
+
}));
|
|
2434
|
+
loader?.stop("Repositories prepared");
|
|
2435
|
+
const drafts = [];
|
|
2436
|
+
for (const [index, result] of results.entries()) {
|
|
2437
|
+
if (result.status === "rejected") {
|
|
2438
|
+
log.error(`${basename(repos[index])}: ${errorMessage(result.reason)}`);
|
|
2439
|
+
process.exitCode = 1;
|
|
2440
|
+
} else if (result.value) {
|
|
2441
|
+
drafts.push(result.value);
|
|
2442
|
+
} else {
|
|
2443
|
+
log.info(`${basename(repos[index])}: nothing to commit.`);
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
if (drafts.length === 0) {
|
|
2447
|
+
if (interactive) outro("No commits prepared.");
|
|
2510
2448
|
return;
|
|
2511
2449
|
}
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
process.exitCode = 1;
|
|
2450
|
+
const selected = await reviewMessages(drafts, interactive && !args.yes);
|
|
2451
|
+
if (!selected) {
|
|
2452
|
+
cancel("Cancelled (changes left staged).");
|
|
2516
2453
|
return;
|
|
2517
2454
|
}
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
{ value: "edit", label: "Edit message" },
|
|
2528
|
-
{ value: "cancel", label: "Cancel" }
|
|
2529
|
-
]
|
|
2530
|
-
});
|
|
2531
|
-
if (isCancel(action) || action === "cancel") {
|
|
2532
|
-
cancel("Cancelled (changes left staged).");
|
|
2533
|
-
return;
|
|
2534
|
-
}
|
|
2535
|
-
if (action === "edit") {
|
|
2536
|
-
const edited = await text({
|
|
2537
|
-
message: "Edit message",
|
|
2538
|
-
initialValue: message
|
|
2539
|
-
});
|
|
2540
|
-
if (isCancel(edited)) {
|
|
2541
|
-
cancel("Cancelled (changes left staged).");
|
|
2542
|
-
return;
|
|
2543
|
-
}
|
|
2544
|
-
finalMessage = edited.trim();
|
|
2545
|
-
if (!finalMessage) {
|
|
2546
|
-
cancel("Empty message, cancelled.");
|
|
2547
|
-
return;
|
|
2548
|
-
}
|
|
2455
|
+
const committed = [];
|
|
2456
|
+
for (const draft of selected) {
|
|
2457
|
+
try {
|
|
2458
|
+
await commit(draft.repo, draft.message);
|
|
2459
|
+
committed.push(draft);
|
|
2460
|
+
log.success(`${basename(draft.repo)}: committed ${draft.message}`);
|
|
2461
|
+
} catch (error) {
|
|
2462
|
+
log.error(`${basename(draft.repo)}: commit failed: ${errorMessage(error)}`);
|
|
2463
|
+
process.exitCode = 1;
|
|
2549
2464
|
}
|
|
2550
2465
|
}
|
|
2551
|
-
|
|
2552
|
-
if (interactive) log.success(`Committed: ${finalMessage}`);
|
|
2466
|
+
if (committed.length === 0) return;
|
|
2553
2467
|
let shouldPush = Boolean(args.push);
|
|
2554
2468
|
if (!shouldPush && interactive && !args.yes) {
|
|
2555
|
-
const answer = await confirm({
|
|
2469
|
+
const answer = await confirm({
|
|
2470
|
+
message: `Push ${committed.map(({ repo }) => basename(repo)).join(", ")}?`,
|
|
2471
|
+
initialValue: false
|
|
2472
|
+
});
|
|
2556
2473
|
if (isCancel(answer)) {
|
|
2557
|
-
|
|
2474
|
+
outro("Committed. Not pushed.");
|
|
2558
2475
|
return;
|
|
2559
2476
|
}
|
|
2560
2477
|
shouldPush = answer;
|
|
2561
2478
|
}
|
|
2562
2479
|
if (shouldPush) {
|
|
2563
|
-
const
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2480
|
+
for (const { repo } of committed) {
|
|
2481
|
+
try {
|
|
2482
|
+
const pushed = await pushOptimistic(
|
|
2483
|
+
repo,
|
|
2484
|
+
interactive,
|
|
2485
|
+
interactive && !args.yes,
|
|
2486
|
+
syncStrategy
|
|
2487
|
+
);
|
|
2488
|
+
if (!pushed) process.exitCode = 1;
|
|
2489
|
+
} catch (error) {
|
|
2490
|
+
log.error(`${basename(repo)}: push failed: ${errorMessage(error)}`);
|
|
2491
|
+
process.exitCode = 1;
|
|
2492
|
+
}
|
|
2571
2493
|
}
|
|
2572
2494
|
}
|
|
2573
|
-
if (interactive) outro("Done.");
|
|
2495
|
+
if (interactive) outro(process.exitCode ? "Finished with errors." : "Done.");
|
|
2574
2496
|
}
|
|
2575
2497
|
});
|
|
2576
|
-
async function
|
|
2498
|
+
async function reviewMessages(drafts, canPrompt) {
|
|
2499
|
+
while (true) {
|
|
2500
|
+
for (const draft of drafts) log.message(`${basename(draft.repo)}: ${draft.message}`);
|
|
2501
|
+
if (!canPrompt) return drafts;
|
|
2502
|
+
const action = await select({
|
|
2503
|
+
message: "Action",
|
|
2504
|
+
initialValue: "all",
|
|
2505
|
+
options: [
|
|
2506
|
+
{ value: "all", label: drafts.length > 1 ? "Commit all" : "Commit" },
|
|
2507
|
+
...drafts.length > 1 ? drafts.map((draft) => ({
|
|
2508
|
+
value: { action: "commit", draft },
|
|
2509
|
+
label: `Commit only "${basename(draft.repo)}"`
|
|
2510
|
+
})) : [],
|
|
2511
|
+
...drafts.map((draft) => ({
|
|
2512
|
+
value: { action: "edit", draft },
|
|
2513
|
+
label: `Edit message for "${basename(draft.repo)}"`
|
|
2514
|
+
})),
|
|
2515
|
+
{ value: "cancel", label: "Cancel" }
|
|
2516
|
+
]
|
|
2517
|
+
});
|
|
2518
|
+
if (isCancel(action) || action === "cancel") return null;
|
|
2519
|
+
if (action === "all") return drafts;
|
|
2520
|
+
if (action.action === "commit") return [action.draft];
|
|
2521
|
+
const edited = await text({
|
|
2522
|
+
message: `Edit message for "${basename(action.draft.repo)}"`,
|
|
2523
|
+
initialValue: action.draft.message,
|
|
2524
|
+
validate: (value) => value?.trim() ? void 0 : "Message cannot be empty."
|
|
2525
|
+
});
|
|
2526
|
+
if (isCancel(edited)) return null;
|
|
2527
|
+
action.draft.message = edited.trim();
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
async function syncWithUpstream(repo, strategy, interactive) {
|
|
2577
2531
|
const loader = interactive ? spinner() : void 0;
|
|
2578
2532
|
const label = strategy === "rebase" ? "Rebase" : "Merge";
|
|
2579
|
-
loader?.start(
|
|
2533
|
+
loader?.start(`${basename(repo)}: pulling --${strategy === "rebase" ? "rebase" : "no-rebase"}`);
|
|
2580
2534
|
try {
|
|
2581
|
-
await (strategy === "rebase" ? pullRebase() : pullMerge());
|
|
2535
|
+
await (strategy === "rebase" ? pullRebase(repo) : pullMerge(repo));
|
|
2582
2536
|
loader?.stop(strategy === "rebase" ? "\u2713 Rebased on upstream" : "\u2713 Merged upstream");
|
|
2583
2537
|
return true;
|
|
2584
2538
|
} catch (error) {
|
|
2585
2539
|
loader?.error(`${label} failed`);
|
|
2586
|
-
log.error(`${label} failed (resolve conflicts, then push): ${errorMessage(error)}`);
|
|
2540
|
+
log.error(`${basename(repo)}: ${label} failed (resolve conflicts, then push): ${errorMessage(error)}`);
|
|
2587
2541
|
return false;
|
|
2588
2542
|
}
|
|
2589
2543
|
}
|
|
2590
|
-
async function pushOptimistic(interactive, canPrompt, strategy) {
|
|
2591
|
-
const [upstream, branch] = await Promise.all([hasUpstream(), currentBranch()]);
|
|
2592
|
-
const doPush = () => upstream ? push() : pushSetUpstream(branch);
|
|
2593
|
-
const first = await tryPush(interactive, doPush);
|
|
2544
|
+
async function pushOptimistic(repo, interactive, canPrompt, strategy) {
|
|
2545
|
+
const [upstream, branch] = await Promise.all([hasUpstream(repo), currentBranch(repo)]);
|
|
2546
|
+
const doPush = () => upstream ? push(repo) : pushSetUpstream(repo, branch);
|
|
2547
|
+
const first = await tryPush(repo, interactive, doPush);
|
|
2594
2548
|
if (first.ok) return true;
|
|
2595
|
-
if (upstream && await isBehind(interactive)) {
|
|
2596
|
-
const syncStrategy = strategy ?? await chooseSyncStrategy(canPrompt);
|
|
2597
|
-
if (!syncStrategy || !await syncWithUpstream(syncStrategy, interactive)) return false;
|
|
2598
|
-
const retry = await tryPush(interactive, doPush);
|
|
2549
|
+
if (upstream && await isBehind(repo, interactive)) {
|
|
2550
|
+
const syncStrategy = strategy ?? await chooseSyncStrategy(repo, canPrompt);
|
|
2551
|
+
if (!syncStrategy || !await syncWithUpstream(repo, syncStrategy, interactive)) return false;
|
|
2552
|
+
const retry = await tryPush(repo, interactive, doPush);
|
|
2599
2553
|
if (retry.ok) return true;
|
|
2600
|
-
log.error(
|
|
2554
|
+
log.error(`${basename(repo)}: push failed: ${errorMessage(retry.error)}`);
|
|
2601
2555
|
return false;
|
|
2602
2556
|
}
|
|
2603
|
-
log.error(
|
|
2557
|
+
log.error(`${basename(repo)}: push failed: ${errorMessage(first.error)}`);
|
|
2604
2558
|
return false;
|
|
2605
2559
|
}
|
|
2606
|
-
async function chooseSyncStrategy(interactive) {
|
|
2560
|
+
async function chooseSyncStrategy(repo, interactive) {
|
|
2607
2561
|
if (!interactive) {
|
|
2608
|
-
log.error(
|
|
2562
|
+
log.error(`${basename(repo)}: branch is behind upstream. Re-run with --rebase or --merge.`);
|
|
2609
2563
|
return null;
|
|
2610
2564
|
}
|
|
2611
2565
|
const action = await select({
|
|
2612
|
-
message:
|
|
2566
|
+
message: `${basename(repo)}: branch is behind upstream. How should zapdev sync it?`,
|
|
2613
2567
|
options: [
|
|
2614
2568
|
{ value: "rebase", label: "Rebase" },
|
|
2615
2569
|
{ value: "merge", label: "Merge" },
|
|
@@ -2622,9 +2576,9 @@ async function chooseSyncStrategy(interactive) {
|
|
|
2622
2576
|
}
|
|
2623
2577
|
return action;
|
|
2624
2578
|
}
|
|
2625
|
-
async function tryPush(interactive, doPush) {
|
|
2579
|
+
async function tryPush(repo, interactive, doPush) {
|
|
2626
2580
|
const loader = interactive ? spinner() : void 0;
|
|
2627
|
-
loader?.start(
|
|
2581
|
+
loader?.start(`${basename(repo)}: pushing`);
|
|
2628
2582
|
try {
|
|
2629
2583
|
await doPush();
|
|
2630
2584
|
loader?.stop("\u2713 Pushed");
|
|
@@ -2634,252 +2588,32 @@ async function tryPush(interactive, doPush) {
|
|
|
2634
2588
|
return { ok: false, error };
|
|
2635
2589
|
}
|
|
2636
2590
|
}
|
|
2637
|
-
async function isBehind(interactive) {
|
|
2591
|
+
async function isBehind(repo, interactive) {
|
|
2638
2592
|
const loader = interactive ? spinner() : void 0;
|
|
2639
|
-
loader?.start(
|
|
2593
|
+
loader?.start(`${basename(repo)}: checking upstream`);
|
|
2640
2594
|
try {
|
|
2641
|
-
await fetchRemote();
|
|
2642
|
-
const behind = await behindCount();
|
|
2595
|
+
await fetchRemote(repo);
|
|
2596
|
+
const behind = await behindCount(repo);
|
|
2643
2597
|
loader?.stop(
|
|
2644
2598
|
behind > 0 ? `Behind upstream by ${behind} commit${behind > 1 ? "s" : ""}` : "Up to date with upstream"
|
|
2645
2599
|
);
|
|
2646
2600
|
return behind > 0;
|
|
2647
2601
|
} catch (error) {
|
|
2648
2602
|
loader?.error("Could not check upstream");
|
|
2649
|
-
log.warn(
|
|
2650
|
-
return false;
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
|
|
2654
|
-
// src/commands/reset.ts
|
|
2655
|
-
var CANCEL = /* @__PURE__ */ Symbol("cancel");
|
|
2656
|
-
var resetCommand = defineCommand({
|
|
2657
|
-
meta: {
|
|
2658
|
-
name: "reset",
|
|
2659
|
-
description: "Switch each repo to a branch, then delete all other local branches and worktrees."
|
|
2660
|
-
},
|
|
2661
|
-
args: {
|
|
2662
|
-
path: {
|
|
2663
|
-
type: "positional",
|
|
2664
|
-
required: false,
|
|
2665
|
-
default: ".",
|
|
2666
|
-
description: "A git repo to reset, or a directory whose direct child repos are reset."
|
|
2667
|
-
},
|
|
2668
|
-
principal: {
|
|
2669
|
-
type: "boolean",
|
|
2670
|
-
alias: "p",
|
|
2671
|
-
description: "Switch every repo to its resolved principal branch (origin/HEAD)."
|
|
2672
|
-
},
|
|
2673
|
-
target: {
|
|
2674
|
-
type: "string",
|
|
2675
|
-
alias: "t",
|
|
2676
|
-
description: "Switch every repo to this branch, falling back to the principal one."
|
|
2677
|
-
},
|
|
2678
|
-
pull: {
|
|
2679
|
-
type: "boolean",
|
|
2680
|
-
description: "Pull the checked-out branch after reset without asking."
|
|
2681
|
-
},
|
|
2682
|
-
yes: {
|
|
2683
|
-
type: "boolean",
|
|
2684
|
-
alias: "y",
|
|
2685
|
-
description: "Non-interactive: switch and delete without confirmation."
|
|
2686
|
-
}
|
|
2687
|
-
},
|
|
2688
|
-
async run({ args }) {
|
|
2689
|
-
const assumeYes = Boolean(args.yes);
|
|
2690
|
-
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !assumeYes;
|
|
2691
|
-
const options = {
|
|
2692
|
-
principal: Boolean(args.principal),
|
|
2693
|
-
target: typeof args.target === "string" ? args.target.trim() : "",
|
|
2694
|
-
pull: Boolean(args.pull)
|
|
2695
|
-
};
|
|
2696
|
-
const path = args.path || ".";
|
|
2697
|
-
if (interactive) intro("zapdev reset");
|
|
2698
|
-
const repos = await findRepos(path);
|
|
2699
|
-
if (repos.length === 0) {
|
|
2700
|
-
log.warn(`No git repository found at or under ${path}.`);
|
|
2701
|
-
if (interactive) outro("Nothing to do.");
|
|
2702
|
-
return;
|
|
2703
|
-
}
|
|
2704
|
-
for (const repo of repos) {
|
|
2705
|
-
try {
|
|
2706
|
-
const cancelled = await resetRepo(repo, options, interactive, assumeYes);
|
|
2707
|
-
if (cancelled) {
|
|
2708
|
-
cancel("Cancelled.");
|
|
2709
|
-
return;
|
|
2710
|
-
}
|
|
2711
|
-
} catch (error) {
|
|
2712
|
-
log.error(`Skipped ${repo}: ${errorMessage(error)}`);
|
|
2713
|
-
}
|
|
2714
|
-
}
|
|
2715
|
-
if (interactive) outro(`Done (${repos.length} repo${repos.length > 1 ? "s" : ""}).`);
|
|
2716
|
-
}
|
|
2717
|
-
});
|
|
2718
|
-
async function resetRepo(repo, options, interactive, assumeYes) {
|
|
2719
|
-
log.step(`Resetting ${repo}`);
|
|
2720
|
-
const fetchLoader = interactive ? spinner() : void 0;
|
|
2721
|
-
fetchLoader?.start("Fetching + pruning\u2026");
|
|
2722
|
-
try {
|
|
2723
|
-
await fetchPrune(repo);
|
|
2724
|
-
fetchLoader?.stop("Fetched + pruned");
|
|
2725
|
-
} catch (error) {
|
|
2726
|
-
fetchLoader?.error("Fetch failed");
|
|
2727
|
-
log.warn(` Fetch failed, continuing: ${errorMessage(error)}`);
|
|
2728
|
-
}
|
|
2729
|
-
const [principal, current] = await Promise.all([defaultBranch(repo), currentBranchAt(repo)]);
|
|
2730
|
-
const endBranch = await resolveEndBranch(repo, principal, current, options, interactive);
|
|
2731
|
-
if (endBranch === CANCEL) return true;
|
|
2732
|
-
if (endBranch === null) return false;
|
|
2733
|
-
const [branches, worktrees] = await Promise.all([localBranches(repo), listWorktrees(repo)]);
|
|
2734
|
-
const branchesToDelete = deletableBranches(branches, [principal ?? "", endBranch]);
|
|
2735
|
-
const worktreesToRemove = worktrees.slice(1);
|
|
2736
|
-
if (branchesToDelete.length > 0 || worktreesToRemove.length > 0) {
|
|
2737
|
-
if (!assumeYes) {
|
|
2738
|
-
if (!interactive) {
|
|
2739
|
-
log.warn(" Refusing to delete non-interactively; pass --yes.");
|
|
2740
|
-
return false;
|
|
2741
|
-
}
|
|
2742
|
-
announcePlan(endBranch, branchesToDelete, worktreesToRemove);
|
|
2743
|
-
const ok = await confirm({ message: "Delete permanently?", initialValue: false });
|
|
2744
|
-
if (isCancel(ok)) return true;
|
|
2745
|
-
if (!ok) {
|
|
2746
|
-
log.info(" Skipped.");
|
|
2747
|
-
return false;
|
|
2748
|
-
}
|
|
2749
|
-
}
|
|
2750
|
-
await removeWorktrees(repo, worktreesToRemove);
|
|
2751
|
-
}
|
|
2752
|
-
if (!await switchTo(repo, current, endBranch)) return false;
|
|
2753
|
-
if (branchesToDelete.length > 0) await deleteBranches(repo, branchesToDelete);
|
|
2754
|
-
return maybePull(repo, endBranch, options, interactive);
|
|
2755
|
-
}
|
|
2756
|
-
async function resolveEndBranch(repo, principal, current, options, interactive) {
|
|
2757
|
-
if (options.target) {
|
|
2758
|
-
if (await branchExists(repo, options.target)) return options.target;
|
|
2759
|
-
if (principal) return principal;
|
|
2760
|
-
log.warn(` Target "${options.target}" not found and no origin/HEAD; skipped.`);
|
|
2761
|
-
return null;
|
|
2762
|
-
}
|
|
2763
|
-
if (options.principal || !interactive) {
|
|
2764
|
-
if (principal) return principal;
|
|
2765
|
-
log.warn(" No origin/HEAD to resolve the principal branch; skipped.");
|
|
2766
|
-
return null;
|
|
2767
|
-
}
|
|
2768
|
-
const branches = await localBranches(repo);
|
|
2769
|
-
if (branches.length === 0) return principal;
|
|
2770
|
-
const choice = await select({
|
|
2771
|
-
message: "Switch to:",
|
|
2772
|
-
initialValue: principal ?? current ?? branches[0],
|
|
2773
|
-
options: branches.map((branch) => ({
|
|
2774
|
-
value: branch,
|
|
2775
|
-
label: branch === principal ? `${branch} (principal)` : branch
|
|
2776
|
-
}))
|
|
2777
|
-
});
|
|
2778
|
-
if (isCancel(choice)) return CANCEL;
|
|
2779
|
-
return choice;
|
|
2780
|
-
}
|
|
2781
|
-
function announcePlan(endBranch, branches, worktrees) {
|
|
2782
|
-
log.info(` Switch to ${endBranch}`);
|
|
2783
|
-
if (branches.length > 0) {
|
|
2784
|
-
const label = branches.length > 1 ? "branches" : "branch";
|
|
2785
|
-
log.warn(` Delete ${branches.length} ${label}: ${branches.join(", ")}`);
|
|
2786
|
-
}
|
|
2787
|
-
if (worktrees.length > 0) {
|
|
2788
|
-
const label = worktrees.length > 1 ? "worktrees" : "worktree";
|
|
2789
|
-
const paths = worktrees.map((worktree) => worktree.path).join(", ");
|
|
2790
|
-
log.warn(` Remove ${worktrees.length} ${label}: ${paths}`);
|
|
2791
|
-
}
|
|
2792
|
-
}
|
|
2793
|
-
async function removeWorktrees(repo, worktrees) {
|
|
2794
|
-
let removed = 0;
|
|
2795
|
-
for (const worktree of worktrees) {
|
|
2796
|
-
try {
|
|
2797
|
-
await removeWorktree(repo, worktree.path);
|
|
2798
|
-
removed += 1;
|
|
2799
|
-
} catch (error) {
|
|
2800
|
-
log.error(` Could not remove worktree ${worktree.path}: ${errorMessage(error)}`);
|
|
2801
|
-
}
|
|
2802
|
-
}
|
|
2803
|
-
if (removed > 0) log.success(` Removed ${removed} worktree${removed > 1 ? "s" : ""}.`);
|
|
2804
|
-
}
|
|
2805
|
-
async function switchTo(repo, current, endBranch) {
|
|
2806
|
-
if (current === endBranch) return true;
|
|
2807
|
-
try {
|
|
2808
|
-
await switchBranch(repo, endBranch);
|
|
2809
|
-
return true;
|
|
2810
|
-
} catch (error) {
|
|
2811
|
-
log.error(` Could not switch to ${endBranch}: ${errorMessage(error)}`);
|
|
2603
|
+
log.warn(`${basename(repo)}: could not check upstream: ${errorMessage(error)}`);
|
|
2812
2604
|
return false;
|
|
2813
2605
|
}
|
|
2814
2606
|
}
|
|
2815
|
-
async function deleteBranches(repo, branches) {
|
|
2816
|
-
let deleted = 0;
|
|
2817
|
-
for (const branch of branches) {
|
|
2818
|
-
try {
|
|
2819
|
-
await deleteBranch(repo, branch);
|
|
2820
|
-
deleted += 1;
|
|
2821
|
-
} catch (error) {
|
|
2822
|
-
log.error(` Could not delete ${branch}: ${errorMessage(error)}`);
|
|
2823
|
-
}
|
|
2824
|
-
}
|
|
2825
|
-
if (deleted > 0) log.success(` Deleted ${deleted} branch${deleted > 1 ? "es" : ""}.`);
|
|
2826
|
-
}
|
|
2827
|
-
async function maybePull(repo, endBranch, options, interactive) {
|
|
2828
|
-
let shouldPull = options.pull;
|
|
2829
|
-
if (!shouldPull && interactive) {
|
|
2830
|
-
const answer = await confirm({ message: `Pull ${endBranch}?`, initialValue: false });
|
|
2831
|
-
if (isCancel(answer)) return true;
|
|
2832
|
-
shouldPull = answer;
|
|
2833
|
-
}
|
|
2834
|
-
if (shouldPull) {
|
|
2835
|
-
const loader = interactive ? spinner() : void 0;
|
|
2836
|
-
loader?.start(`Pulling ${endBranch}\u2026`);
|
|
2837
|
-
try {
|
|
2838
|
-
await pull(repo);
|
|
2839
|
-
loader?.stop(`\u2713 Pulled ${endBranch}`);
|
|
2840
|
-
} catch (error) {
|
|
2841
|
-
loader?.error("Pull failed");
|
|
2842
|
-
log.error(` Pull failed: ${errorMessage(error)}`);
|
|
2843
|
-
}
|
|
2844
|
-
}
|
|
2845
|
-
return false;
|
|
2846
|
-
}
|
|
2847
2607
|
|
|
2848
2608
|
// src/cli.ts
|
|
2849
|
-
var commands = {
|
|
2850
|
-
commit: commitCommand,
|
|
2851
|
-
reset: resetCommand
|
|
2852
|
-
};
|
|
2853
|
-
var MENU = {
|
|
2854
|
-
commit: "Stage all changes and commit with an AI-generated message",
|
|
2855
|
-
reset: "Switch repos to a branch and delete the other branches and worktrees"
|
|
2856
|
-
};
|
|
2857
|
-
var menuOptions = Object.keys(MENU).map((value) => ({
|
|
2858
|
-
value,
|
|
2859
|
-
label: value,
|
|
2860
|
-
hint: MENU[value]
|
|
2861
|
-
}));
|
|
2862
2609
|
var main = defineCommand({
|
|
2863
2610
|
meta: {
|
|
2864
2611
|
name: "zapdev",
|
|
2865
2612
|
version: package_default.version,
|
|
2866
2613
|
description: "Fast, precise git chores from your terminal."
|
|
2867
2614
|
},
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
const selected = args._[0];
|
|
2872
|
-
if (selected && selected in commands) return;
|
|
2873
|
-
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
2874
|
-
await showUsage(cmd);
|
|
2875
|
-
return;
|
|
2876
|
-
}
|
|
2877
|
-
const choice = await select({ message: "Which command?", options: menuOptions });
|
|
2878
|
-
if (isCancel(choice)) {
|
|
2879
|
-
cancel("Cancelled.");
|
|
2880
|
-
return;
|
|
2881
|
-
}
|
|
2882
|
-
await runCommand(commands[choice], { rawArgs: [] });
|
|
2883
|
-
}
|
|
2615
|
+
args: commitCommand.args,
|
|
2616
|
+
subCommands: { commit: commitCommand },
|
|
2617
|
+
default: "commit"
|
|
2884
2618
|
});
|
|
2885
2619
|
await runMain(main);
|