zapdev 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -18
- package/dist/cli.js +2786 -0
- package/dist/index.js +4 -3714
- package/package.json +13 -14
package/dist/cli.js
ADDED
|
@@ -0,0 +1,2786 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
try {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
} catch (e2) {
|
|
11
|
+
throw mod = 0, e2;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
+
mod
|
|
29
|
+
));
|
|
30
|
+
|
|
31
|
+
// node_modules/sisteransi/src/index.js
|
|
32
|
+
var require_src = __commonJS({
|
|
33
|
+
"node_modules/sisteransi/src/index.js"(exports, module) {
|
|
34
|
+
"use strict";
|
|
35
|
+
var ESC2 = "\x1B";
|
|
36
|
+
var CSI2 = `${ESC2}[`;
|
|
37
|
+
var beep = "\x07";
|
|
38
|
+
var cursor3 = {
|
|
39
|
+
to(x2, y2) {
|
|
40
|
+
if (!y2) return `${CSI2}${x2 + 1}G`;
|
|
41
|
+
return `${CSI2}${y2 + 1};${x2 + 1}H`;
|
|
42
|
+
},
|
|
43
|
+
move(x2, y2) {
|
|
44
|
+
let ret = "";
|
|
45
|
+
if (x2 < 0) ret += `${CSI2}${-x2}D`;
|
|
46
|
+
else if (x2 > 0) ret += `${CSI2}${x2}C`;
|
|
47
|
+
if (y2 < 0) ret += `${CSI2}${-y2}A`;
|
|
48
|
+
else if (y2 > 0) ret += `${CSI2}${y2}B`;
|
|
49
|
+
return ret;
|
|
50
|
+
},
|
|
51
|
+
up: (count = 1) => `${CSI2}${count}A`,
|
|
52
|
+
down: (count = 1) => `${CSI2}${count}B`,
|
|
53
|
+
forward: (count = 1) => `${CSI2}${count}C`,
|
|
54
|
+
backward: (count = 1) => `${CSI2}${count}D`,
|
|
55
|
+
nextLine: (count = 1) => `${CSI2}E`.repeat(count),
|
|
56
|
+
prevLine: (count = 1) => `${CSI2}F`.repeat(count),
|
|
57
|
+
left: `${CSI2}G`,
|
|
58
|
+
hide: `${CSI2}?25l`,
|
|
59
|
+
show: `${CSI2}?25h`,
|
|
60
|
+
save: `${ESC2}7`,
|
|
61
|
+
restore: `${ESC2}8`
|
|
62
|
+
};
|
|
63
|
+
var scroll = {
|
|
64
|
+
up: (count = 1) => `${CSI2}S`.repeat(count),
|
|
65
|
+
down: (count = 1) => `${CSI2}T`.repeat(count)
|
|
66
|
+
};
|
|
67
|
+
var erase3 = {
|
|
68
|
+
screen: `${CSI2}2J`,
|
|
69
|
+
up: (count = 1) => `${CSI2}1J`.repeat(count),
|
|
70
|
+
down: (count = 1) => `${CSI2}J`.repeat(count),
|
|
71
|
+
line: `${CSI2}2K`,
|
|
72
|
+
lineEnd: `${CSI2}K`,
|
|
73
|
+
lineStart: `${CSI2}1K`,
|
|
74
|
+
lines(count) {
|
|
75
|
+
let clear = "";
|
|
76
|
+
for (let i3 = 0; i3 < count; i3++)
|
|
77
|
+
clear += this.line + (i3 < count - 1 ? cursor3.up() : "");
|
|
78
|
+
if (count)
|
|
79
|
+
clear += cursor3.left;
|
|
80
|
+
return clear;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
module.exports = { cursor: cursor3, scroll, erase: erase3, beep };
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
88
|
+
import { styleText } from "node:util";
|
|
89
|
+
import { stdout, stdin } from "node:process";
|
|
90
|
+
import * as l from "node:readline";
|
|
91
|
+
import l__default from "node:readline";
|
|
92
|
+
|
|
93
|
+
// node_modules/fast-string-truncated-width/dist/utils.js
|
|
94
|
+
var getCodePointsLength = /* @__PURE__ */ (() => {
|
|
95
|
+
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
96
|
+
return (input) => {
|
|
97
|
+
let surrogatePairsNr = 0;
|
|
98
|
+
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
99
|
+
while (SURROGATE_PAIR_RE.test(input)) {
|
|
100
|
+
surrogatePairsNr += 1;
|
|
101
|
+
}
|
|
102
|
+
return input.length - surrogatePairsNr;
|
|
103
|
+
};
|
|
104
|
+
})();
|
|
105
|
+
var isFullWidth = (x2) => {
|
|
106
|
+
return x2 === 12288 || x2 >= 65281 && x2 <= 65376 || x2 >= 65504 && x2 <= 65510;
|
|
107
|
+
};
|
|
108
|
+
var isWideNotCJKTNotEmoji = (x2) => {
|
|
109
|
+
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;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// node_modules/fast-string-truncated-width/dist/index.js
|
|
113
|
+
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
114
|
+
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
115
|
+
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;
|
|
116
|
+
var TAB_RE = /\t{1,1000}/y;
|
|
117
|
+
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");
|
|
118
|
+
var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
119
|
+
var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
|
|
120
|
+
var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
|
|
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, m3 = a3 === "return" ? -1 : 0;
|
|
533
|
+
l.moveCursor(r3, i3, m3, () => {
|
|
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, m3) => {
|
|
552
|
+
const d2 = n4 ? n4(c3, i3) : c3;
|
|
553
|
+
return i3 === 0 ? `${t3}${d2}` : i3 === m3.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
|
+
);
|
|
641
|
+
}
|
|
642
|
+
this.rl = l__default.createInterface({
|
|
643
|
+
input: this.input,
|
|
644
|
+
tabSize: 2,
|
|
645
|
+
prompt: "",
|
|
646
|
+
escapeCodeTimeout: 50,
|
|
647
|
+
terminal: true
|
|
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));
|
|
675
|
+
}
|
|
676
|
+
this.state !== "error" && (this.state = "submit");
|
|
677
|
+
}
|
|
678
|
+
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();
|
|
679
|
+
}
|
|
680
|
+
close() {
|
|
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));
|
|
688
|
+
}
|
|
689
|
+
render() {
|
|
690
|
+
const t3 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, {
|
|
691
|
+
hard: true,
|
|
692
|
+
trim: false
|
|
693
|
+
});
|
|
694
|
+
if (t3 !== this._prevFrame) {
|
|
695
|
+
if (this.state === "initial")
|
|
696
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
697
|
+
else {
|
|
698
|
+
const e2 = diffLines(this._prevFrame, t3), i3 = getRows(this.output);
|
|
699
|
+
if (this.restoreCursor(), e2) {
|
|
700
|
+
const n4 = Math.max(0, e2.numLinesAfter - i3), s2 = Math.max(0, e2.numLinesBefore - i3);
|
|
701
|
+
let r3 = e2.lines.find((o2) => o2 >= n4);
|
|
702
|
+
if (r3 === void 0) {
|
|
703
|
+
this._prevFrame = t3;
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
if (e2.lines.length === 1) {
|
|
707
|
+
this.output.write(import_sisteransi.cursor.move(0, r3 - s2)), this.output.write(import_sisteransi.erase.lines(1));
|
|
708
|
+
const o2 = t3.split(`
|
|
709
|
+
`);
|
|
710
|
+
this.output.write(o2[r3]), this._prevFrame = t3, this.output.write(import_sisteransi.cursor.move(0, o2.length - r3 - 1));
|
|
711
|
+
return;
|
|
712
|
+
} else if (e2.lines.length > 1) {
|
|
713
|
+
if (n4 < s2)
|
|
714
|
+
r3 = n4;
|
|
715
|
+
else {
|
|
716
|
+
const h3 = r3 - s2;
|
|
717
|
+
h3 > 0 && this.output.write(import_sisteransi.cursor.move(0, h3));
|
|
718
|
+
}
|
|
719
|
+
this.output.write(import_sisteransi.erase.down());
|
|
720
|
+
const f2 = t3.split(`
|
|
721
|
+
`).slice(r3);
|
|
722
|
+
this.output.write(f2.join(`
|
|
723
|
+
`)), this._prevFrame = t3;
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
this.output.write(import_sisteransi.erase.down());
|
|
728
|
+
}
|
|
729
|
+
this.output.write(t3), this.state === "initial" && (this.state = "active"), this._prevFrame = t3;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
};
|
|
733
|
+
var r = class extends V {
|
|
734
|
+
get cursor() {
|
|
735
|
+
return this.value ? 0 : 1;
|
|
736
|
+
}
|
|
737
|
+
get _value() {
|
|
738
|
+
return this.cursor === 0;
|
|
739
|
+
}
|
|
740
|
+
constructor(t3) {
|
|
741
|
+
super(t3, false), this.value = !!t3.initialValue, this.on("userInput", () => {
|
|
742
|
+
this.value = this._value;
|
|
743
|
+
}), this.on("confirm", (i3) => {
|
|
744
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i3, this.state = "submit", this.close();
|
|
745
|
+
}), this.on("cursor", () => {
|
|
746
|
+
this.value = !this.value;
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
var a = class extends V {
|
|
751
|
+
options;
|
|
752
|
+
cursor = 0;
|
|
753
|
+
get _value() {
|
|
754
|
+
return this.options[this.cursor]?.value;
|
|
755
|
+
}
|
|
756
|
+
get _enabledOptions() {
|
|
757
|
+
return this.options.filter((e2) => e2.disabled !== true);
|
|
758
|
+
}
|
|
759
|
+
toggleAll() {
|
|
760
|
+
const e2 = this._enabledOptions, i3 = this.value !== void 0 && this.value.length === e2.length;
|
|
761
|
+
this.value = i3 ? [] : e2.map((t3) => t3.value);
|
|
762
|
+
}
|
|
763
|
+
toggleInvert() {
|
|
764
|
+
const e2 = this.value;
|
|
765
|
+
if (!e2)
|
|
766
|
+
return;
|
|
767
|
+
const i3 = this._enabledOptions.filter((t3) => !e2.includes(t3.value));
|
|
768
|
+
this.value = i3.map((t3) => t3.value);
|
|
769
|
+
}
|
|
770
|
+
toggleValue() {
|
|
771
|
+
this.value === void 0 && (this.value = []);
|
|
772
|
+
const e2 = this.value.includes(this._value);
|
|
773
|
+
this.value = e2 ? this.value.filter((i3) => i3 !== this._value) : [...this.value, this._value];
|
|
774
|
+
}
|
|
775
|
+
constructor(e2) {
|
|
776
|
+
super(e2, false), this.options = e2.options, this.value = [...e2.initialValues ?? []];
|
|
777
|
+
const i3 = Math.max(
|
|
778
|
+
this.options.findIndex(({ value: t3 }) => t3 === e2.cursorAt),
|
|
779
|
+
0
|
|
780
|
+
);
|
|
781
|
+
this.cursor = this.options[i3]?.disabled ? findCursor(i3, 1, this.options) : i3, this.on("key", (t3, l3) => {
|
|
782
|
+
l3.name === "a" && this.toggleAll(), l3.name === "i" && this.toggleInvert();
|
|
783
|
+
}), this.on("cursor", (t3) => {
|
|
784
|
+
switch (t3) {
|
|
785
|
+
case "left":
|
|
786
|
+
case "up":
|
|
787
|
+
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
788
|
+
break;
|
|
789
|
+
case "down":
|
|
790
|
+
case "right":
|
|
791
|
+
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
792
|
+
break;
|
|
793
|
+
case "space":
|
|
794
|
+
this.toggleValue();
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
var n$1 = class n extends V {
|
|
801
|
+
options;
|
|
802
|
+
cursor = 0;
|
|
803
|
+
get _selectedValue() {
|
|
804
|
+
return this.options[this.cursor];
|
|
805
|
+
}
|
|
806
|
+
changeValue() {
|
|
807
|
+
const e2 = this._selectedValue;
|
|
808
|
+
this.value = e2 === void 0 ? void 0 : e2.value;
|
|
809
|
+
}
|
|
810
|
+
constructor(e2) {
|
|
811
|
+
super(e2, false), this.options = e2.options;
|
|
812
|
+
const o2 = this.options.findIndex(({ value: s2 }) => s2 === e2.initialValue), t3 = o2 === -1 ? 0 : o2;
|
|
813
|
+
this.cursor = this.options[t3]?.disabled ? findCursor(t3, 1, this.options) : t3, this.changeValue(), this.on("cursor", (s2) => {
|
|
814
|
+
switch (s2) {
|
|
815
|
+
case "left":
|
|
816
|
+
case "up":
|
|
817
|
+
this.cursor = findCursor(this.cursor, -1, this.options);
|
|
818
|
+
break;
|
|
819
|
+
case "down":
|
|
820
|
+
case "right":
|
|
821
|
+
this.cursor = findCursor(this.cursor, 1, this.options);
|
|
822
|
+
break;
|
|
823
|
+
}
|
|
824
|
+
this.changeValue();
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
var n2 = class extends V {
|
|
829
|
+
get userInputWithCursor() {
|
|
830
|
+
if (this.state === "submit")
|
|
831
|
+
return this.userInput;
|
|
832
|
+
const t3 = this.userInput;
|
|
833
|
+
if (this.cursor >= t3.length)
|
|
834
|
+
return `${this.userInput}\u2588`;
|
|
835
|
+
const r3 = t3.slice(0, this.cursor), s2 = t3.slice(this.cursor, this.cursor + 1), e2 = t3.slice(this.cursor + 1);
|
|
836
|
+
return `${r3}${styleText("inverse", s2)}${e2}`;
|
|
837
|
+
}
|
|
838
|
+
get cursor() {
|
|
839
|
+
return this._cursor;
|
|
840
|
+
}
|
|
841
|
+
constructor(t3) {
|
|
842
|
+
super({
|
|
843
|
+
...t3,
|
|
844
|
+
initialUserInput: t3.initialUserInput ?? t3.initialValue
|
|
845
|
+
}), this.on("userInput", (r3) => {
|
|
846
|
+
this._setValue(r3);
|
|
847
|
+
}), this.on("finalize", () => {
|
|
848
|
+
this.value || (this.value = t3.defaultValue), this.value === void 0 && (this.value = "");
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
854
|
+
import { styleText as styleText2, stripVTControlCharacters } from "node:util";
|
|
855
|
+
import process$1 from "node:process";
|
|
856
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
857
|
+
function isUnicodeSupported() {
|
|
858
|
+
if (process$1.platform !== "win32") {
|
|
859
|
+
return process$1.env.TERM !== "linux";
|
|
860
|
+
}
|
|
861
|
+
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";
|
|
862
|
+
}
|
|
863
|
+
var unicode = isUnicodeSupported();
|
|
864
|
+
var isCI = () => process.env.CI === "true";
|
|
865
|
+
var unicodeOr = (o2, e2) => unicode ? o2 : e2;
|
|
866
|
+
var S_STEP_ACTIVE = unicodeOr("\u25C6", "*");
|
|
867
|
+
var S_STEP_CANCEL = unicodeOr("\u25A0", "x");
|
|
868
|
+
var S_STEP_ERROR = unicodeOr("\u25B2", "x");
|
|
869
|
+
var S_STEP_SUBMIT = unicodeOr("\u25C7", "o");
|
|
870
|
+
var S_BAR_START = unicodeOr("\u250C", "T");
|
|
871
|
+
var S_BAR = unicodeOr("\u2502", "|");
|
|
872
|
+
var S_BAR_END = unicodeOr("\u2514", "\u2014");
|
|
873
|
+
var S_BAR_START_RIGHT = unicodeOr("\u2510", "T");
|
|
874
|
+
var S_BAR_END_RIGHT = unicodeOr("\u2518", "\u2014");
|
|
875
|
+
var S_RADIO_ACTIVE = unicodeOr("\u25CF", ">");
|
|
876
|
+
var S_RADIO_INACTIVE = unicodeOr("\u25CB", " ");
|
|
877
|
+
var S_CHECKBOX_ACTIVE = unicodeOr("\u25FB", "[\u2022]");
|
|
878
|
+
var S_CHECKBOX_SELECTED = unicodeOr("\u25FC", "[+]");
|
|
879
|
+
var S_CHECKBOX_INACTIVE = unicodeOr("\u25FB", "[ ]");
|
|
880
|
+
var S_PASSWORD_MASK = unicodeOr("\u25AA", "\u2022");
|
|
881
|
+
var S_BAR_H = unicodeOr("\u2500", "-");
|
|
882
|
+
var S_CORNER_TOP_RIGHT = unicodeOr("\u256E", "+");
|
|
883
|
+
var S_CONNECT_LEFT = unicodeOr("\u251C", "+");
|
|
884
|
+
var S_CORNER_BOTTOM_RIGHT = unicodeOr("\u256F", "+");
|
|
885
|
+
var S_CORNER_BOTTOM_LEFT = unicodeOr("\u2570", "+");
|
|
886
|
+
var S_CORNER_TOP_LEFT = unicodeOr("\u256D", "+");
|
|
887
|
+
var S_INFO = unicodeOr("\u25CF", "\u2022");
|
|
888
|
+
var S_SUCCESS = unicodeOr("\u25C6", "*");
|
|
889
|
+
var S_WARN = unicodeOr("\u25B2", "!");
|
|
890
|
+
var S_ERROR = unicodeOr("\u25A0", "x");
|
|
891
|
+
var symbol = (o2) => {
|
|
892
|
+
switch (o2) {
|
|
893
|
+
case "initial":
|
|
894
|
+
case "active":
|
|
895
|
+
return styleText2("cyan", S_STEP_ACTIVE);
|
|
896
|
+
case "cancel":
|
|
897
|
+
return styleText2("red", S_STEP_CANCEL);
|
|
898
|
+
case "error":
|
|
899
|
+
return styleText2("yellow", S_STEP_ERROR);
|
|
900
|
+
case "submit":
|
|
901
|
+
return styleText2("green", S_STEP_SUBMIT);
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
var symbolBar = (o2) => {
|
|
905
|
+
switch (o2) {
|
|
906
|
+
case "initial":
|
|
907
|
+
case "active":
|
|
908
|
+
return styleText2("cyan", S_BAR);
|
|
909
|
+
case "cancel":
|
|
910
|
+
return styleText2("red", S_BAR);
|
|
911
|
+
case "error":
|
|
912
|
+
return styleText2("yellow", S_BAR);
|
|
913
|
+
case "submit":
|
|
914
|
+
return styleText2("green", S_BAR);
|
|
915
|
+
}
|
|
916
|
+
};
|
|
917
|
+
function formatInstructionFooter(o2, e2) {
|
|
918
|
+
const r3 = [`${e2 ? `${styleText2("cyan", S_BAR)} ` : ""}${o2.join(" \u2022 ")}`];
|
|
919
|
+
return e2 && r3.push(styleText2("cyan", S_BAR_END)), r3;
|
|
920
|
+
}
|
|
921
|
+
var I = (l3, e2, w2, p2, b2, C2 = false) => {
|
|
922
|
+
let r3 = e2, O2 = 0;
|
|
923
|
+
if (C2)
|
|
924
|
+
for (let i3 = p2 - 1; i3 >= w2; i3--) {
|
|
925
|
+
const m3 = l3[i3];
|
|
926
|
+
if (m3 && (r3 -= m3.length), O2++, r3 <= b2) break;
|
|
927
|
+
}
|
|
928
|
+
else
|
|
929
|
+
for (let i3 = w2; i3 < p2; i3++) {
|
|
930
|
+
const m3 = l3[i3];
|
|
931
|
+
if (m3 && (r3 -= m3.length), O2++, r3 <= b2) break;
|
|
932
|
+
}
|
|
933
|
+
return { lineCount: r3, removals: O2 };
|
|
934
|
+
};
|
|
935
|
+
var limitOptions = ({
|
|
936
|
+
cursor: l3,
|
|
937
|
+
options: e2,
|
|
938
|
+
style: w2,
|
|
939
|
+
output: p2 = process.stdout,
|
|
940
|
+
maxItems: b2 = Number.POSITIVE_INFINITY,
|
|
941
|
+
columnPadding: C2 = 0,
|
|
942
|
+
rowPadding: r3 = 4
|
|
943
|
+
}) => {
|
|
944
|
+
const i3 = getColumns(p2) - C2, m3 = getRows(p2), M = styleText2("dim", "..."), v2 = Math.max(m3 - r3, 0), a3 = Math.max(Math.min(b2, v2), 5);
|
|
945
|
+
let f2 = 0;
|
|
946
|
+
l3 >= a3 - 3 && (f2 = Math.max(
|
|
947
|
+
Math.min(l3 - a3 + 3, e2.length - a3),
|
|
948
|
+
0
|
|
949
|
+
));
|
|
950
|
+
let d2 = a3 < e2.length && f2 > 0, c3 = a3 < e2.length && f2 + a3 < e2.length;
|
|
951
|
+
const W2 = Math.min(
|
|
952
|
+
f2 + a3,
|
|
953
|
+
e2.length
|
|
954
|
+
), s2 = [];
|
|
955
|
+
let g2 = 0;
|
|
956
|
+
d2 && g2++, c3 && g2++;
|
|
957
|
+
const T2 = f2 + (d2 ? 1 : 0), y2 = W2 - (c3 ? 1 : 0);
|
|
958
|
+
for (let t3 = T2; t3 < y2; t3++) {
|
|
959
|
+
const n4 = e2[t3], o2 = n4 ? w2(n4, t3 === l3) : "", h3 = wrapAnsi(o2, i3, {
|
|
960
|
+
hard: true,
|
|
961
|
+
trim: false
|
|
962
|
+
}).split(`
|
|
963
|
+
`);
|
|
964
|
+
s2.push(h3), g2 += h3.length;
|
|
965
|
+
}
|
|
966
|
+
if (g2 > v2) {
|
|
967
|
+
let t3 = 0, n4 = 0, o2 = g2;
|
|
968
|
+
const h3 = l3 - T2;
|
|
969
|
+
let u4 = v2;
|
|
970
|
+
const L = () => I(s2, o2, 0, h3, u4), E2 = () => I(
|
|
971
|
+
s2,
|
|
972
|
+
o2,
|
|
973
|
+
h3 + 1,
|
|
974
|
+
s2.length,
|
|
975
|
+
u4,
|
|
976
|
+
true
|
|
977
|
+
);
|
|
978
|
+
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));
|
|
979
|
+
}
|
|
980
|
+
const x2 = [];
|
|
981
|
+
d2 && x2.push(M);
|
|
982
|
+
for (const t3 of s2)
|
|
983
|
+
for (const n4 of t3)
|
|
984
|
+
x2.push(n4);
|
|
985
|
+
return c3 && x2.push(M), x2;
|
|
986
|
+
};
|
|
987
|
+
var confirm = (i3) => {
|
|
988
|
+
const a3 = i3.active ?? "Yes", s2 = i3.inactive ?? "No";
|
|
989
|
+
return new r({
|
|
990
|
+
active: a3,
|
|
991
|
+
inactive: s2,
|
|
992
|
+
signal: i3.signal,
|
|
993
|
+
input: i3.input,
|
|
994
|
+
output: i3.output,
|
|
995
|
+
initialValue: i3.initialValue ?? true,
|
|
996
|
+
render() {
|
|
997
|
+
const e2 = i3.withGuide ?? settings.withGuide, u4 = `${symbol(this.state)} `, l3 = e2 ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(
|
|
998
|
+
i3.output,
|
|
999
|
+
i3.message,
|
|
1000
|
+
l3,
|
|
1001
|
+
u4
|
|
1002
|
+
), o2 = `${e2 ? `${styleText2("gray", S_BAR)}
|
|
1003
|
+
` : ""}${f2}
|
|
1004
|
+
`, c3 = this.value ? a3 : s2;
|
|
1005
|
+
switch (this.state) {
|
|
1006
|
+
case "submit": {
|
|
1007
|
+
const r3 = e2 ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1008
|
+
return `${o2}${r3}${styleText2("dim", c3)}`;
|
|
1009
|
+
}
|
|
1010
|
+
case "cancel": {
|
|
1011
|
+
const r3 = e2 ? `${styleText2("gray", S_BAR)} ` : "";
|
|
1012
|
+
return `${o2}${r3}${styleText2(["strikethrough", "dim"], c3)}${e2 ? `
|
|
1013
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1014
|
+
}
|
|
1015
|
+
default: {
|
|
1016
|
+
const r3 = e2 ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e2 ? styleText2("cyan", S_BAR_END) : "";
|
|
1017
|
+
return `${o2}${r3}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a3}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a3)}`}${i3.vertical ? e2 ? `
|
|
1018
|
+
${styleText2("cyan", S_BAR)} ` : `
|
|
1019
|
+
` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s2)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s2}`}
|
|
1020
|
+
${g2}
|
|
1021
|
+
`;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}).prompt();
|
|
1026
|
+
};
|
|
1027
|
+
var MULTISELECT_INSTRUCTIONS = [
|
|
1028
|
+
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
1029
|
+
`${styleText2("dim", "Space:")} select`,
|
|
1030
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1031
|
+
];
|
|
1032
|
+
var m = (i3, u4) => i3.split(`
|
|
1033
|
+
`).map((d2) => u4(d2)).join(`
|
|
1034
|
+
`);
|
|
1035
|
+
var multiselect = (i3) => {
|
|
1036
|
+
const u4 = (t3, a3) => {
|
|
1037
|
+
const r3 = t3.label ?? String(t3.value);
|
|
1038
|
+
return a3 === "disabled" ? `${styleText2("gray", S_CHECKBOX_INACTIVE)} ${m(r3, (o2) => styleText2(["strikethrough", "gray"], o2))}${t3.hint ? ` ${styleText2("dim", `(${t3.hint ?? "disabled"})`)}` : ""}` : a3 === "active" ? `${styleText2("cyan", S_CHECKBOX_ACTIVE)} ${r3}${t3.hint ? ` ${styleText2("dim", `(${t3.hint})`)}` : ""}` : a3 === "selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${m(r3, (o2) => styleText2("dim", o2))}${t3.hint ? ` ${styleText2("dim", `(${t3.hint})`)}` : ""}` : a3 === "cancelled" ? `${m(r3, (o2) => styleText2(["strikethrough", "dim"], o2))}` : a3 === "active-selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${r3}${t3.hint ? ` ${styleText2("dim", `(${t3.hint})`)}` : ""}` : a3 === "submitted" ? `${m(r3, (o2) => styleText2("dim", o2))}` : `${styleText2("dim", S_CHECKBOX_INACTIVE)} ${m(r3, (o2) => styleText2("dim", o2))}`;
|
|
1039
|
+
}, d2 = i3.required ?? true, v2 = i3.showInstructions ?? true;
|
|
1040
|
+
return new a({
|
|
1041
|
+
options: i3.options,
|
|
1042
|
+
signal: i3.signal,
|
|
1043
|
+
input: i3.input,
|
|
1044
|
+
output: i3.output,
|
|
1045
|
+
initialValues: i3.initialValues,
|
|
1046
|
+
required: d2,
|
|
1047
|
+
cursorAt: i3.cursorAt,
|
|
1048
|
+
validate(t3) {
|
|
1049
|
+
if (d2 && (t3 === void 0 || t3.length === 0))
|
|
1050
|
+
return `Please select at least one option.
|
|
1051
|
+
${styleText2(
|
|
1052
|
+
"reset",
|
|
1053
|
+
styleText2(
|
|
1054
|
+
"dim",
|
|
1055
|
+
`Press ${styleText2(["gray", "bgWhite", "inverse"], " space ")} to select, ${styleText2(
|
|
1056
|
+
"gray",
|
|
1057
|
+
styleText2("bgWhite", styleText2("inverse", " enter "))
|
|
1058
|
+
)} to submit`
|
|
1059
|
+
)
|
|
1060
|
+
)}`;
|
|
1061
|
+
},
|
|
1062
|
+
render() {
|
|
1063
|
+
const t3 = i3.withGuide ?? settings.withGuide, a3 = wrapTextWithPrefix(
|
|
1064
|
+
i3.output,
|
|
1065
|
+
i3.message,
|
|
1066
|
+
t3 ? `${symbolBar(this.state)} ` : "",
|
|
1067
|
+
`${symbol(this.state)} `
|
|
1068
|
+
), r3 = `${t3 ? `${styleText2("gray", S_BAR)}
|
|
1069
|
+
` : ""}${a3}
|
|
1070
|
+
`, o2 = this.value ?? [], p2 = (n4, l3) => {
|
|
1071
|
+
if (n4.disabled)
|
|
1072
|
+
return u4(n4, "disabled");
|
|
1073
|
+
const s2 = o2.includes(n4.value);
|
|
1074
|
+
return l3 && s2 ? u4(n4, "active-selected") : s2 ? u4(n4, "selected") : u4(n4, l3 ? "active" : "inactive");
|
|
1075
|
+
};
|
|
1076
|
+
switch (this.state) {
|
|
1077
|
+
case "submit": {
|
|
1078
|
+
const n4 = this.options.filter(({ value: s2 }) => o2.includes(s2)).map((s2) => u4(s2, "submitted")).join(styleText2("dim", ", ")) || styleText2("dim", "none"), l3 = wrapTextWithPrefix(
|
|
1079
|
+
i3.output,
|
|
1080
|
+
n4,
|
|
1081
|
+
t3 ? `${styleText2("gray", S_BAR)} ` : ""
|
|
1082
|
+
);
|
|
1083
|
+
return `${r3}${l3}`;
|
|
1084
|
+
}
|
|
1085
|
+
case "cancel": {
|
|
1086
|
+
const n4 = this.options.filter(({ value: s2 }) => o2.includes(s2)).map((s2) => u4(s2, "cancelled")).join(styleText2("dim", ", "));
|
|
1087
|
+
if (n4.trim() === "")
|
|
1088
|
+
return `${r3}${styleText2("gray", S_BAR)}`;
|
|
1089
|
+
const l3 = wrapTextWithPrefix(
|
|
1090
|
+
i3.output,
|
|
1091
|
+
n4,
|
|
1092
|
+
t3 ? `${styleText2("gray", S_BAR)} ` : ""
|
|
1093
|
+
);
|
|
1094
|
+
return `${r3}${l3}${t3 ? `
|
|
1095
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1096
|
+
}
|
|
1097
|
+
case "error": {
|
|
1098
|
+
const n4 = t3 ? `${styleText2("yellow", S_BAR)} ` : "", l3 = this.error.split(`
|
|
1099
|
+
`).map(
|
|
1100
|
+
($, C2) => C2 === 0 ? `${t3 ? `${styleText2("yellow", S_BAR_END)} ` : ""}${styleText2("yellow", $)}` : ` ${$}`
|
|
1101
|
+
).join(`
|
|
1102
|
+
`), s2 = r3.split(`
|
|
1103
|
+
`).length, h3 = l3.split(`
|
|
1104
|
+
`).length + 1;
|
|
1105
|
+
return `${r3}${n4}${limitOptions({
|
|
1106
|
+
output: i3.output,
|
|
1107
|
+
options: this.options,
|
|
1108
|
+
cursor: this.cursor,
|
|
1109
|
+
maxItems: i3.maxItems,
|
|
1110
|
+
columnPadding: n4.length,
|
|
1111
|
+
rowPadding: s2 + h3,
|
|
1112
|
+
style: p2
|
|
1113
|
+
}).join(`
|
|
1114
|
+
${n4}`)}
|
|
1115
|
+
${l3}
|
|
1116
|
+
`;
|
|
1117
|
+
}
|
|
1118
|
+
default: {
|
|
1119
|
+
const n4 = t3 ? `${styleText2("cyan", S_BAR)} ` : "", l3 = r3.split(`
|
|
1120
|
+
`).length, s2 = v2 ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t3) : t3 ? [styleText2("cyan", S_BAR_END)] : [], h3 = s2.join(`
|
|
1121
|
+
`), $ = s2.length + 1;
|
|
1122
|
+
return `${r3}${n4}${limitOptions({
|
|
1123
|
+
output: i3.output,
|
|
1124
|
+
options: this.options,
|
|
1125
|
+
cursor: this.cursor,
|
|
1126
|
+
maxItems: i3.maxItems,
|
|
1127
|
+
columnPadding: n4.length,
|
|
1128
|
+
rowPadding: l3 + $,
|
|
1129
|
+
style: p2
|
|
1130
|
+
}).join(`
|
|
1131
|
+
${n4}`)}
|
|
1132
|
+
${h3}
|
|
1133
|
+
`;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
}).prompt();
|
|
1138
|
+
};
|
|
1139
|
+
var log = {
|
|
1140
|
+
message: (s2 = [], {
|
|
1141
|
+
symbol: e2 = styleText2("gray", S_BAR),
|
|
1142
|
+
secondarySymbol: r3 = styleText2("gray", S_BAR),
|
|
1143
|
+
output: m3 = process.stdout,
|
|
1144
|
+
spacing: l3 = 1,
|
|
1145
|
+
withGuide: c3
|
|
1146
|
+
} = {}) => {
|
|
1147
|
+
const t3 = [], o2 = c3 ?? settings.withGuide, f2 = o2 ? r3 : "", O2 = o2 ? `${e2} ` : "", u4 = o2 ? `${r3} ` : "";
|
|
1148
|
+
for (let i3 = 0; i3 < l3; i3++)
|
|
1149
|
+
t3.push(f2);
|
|
1150
|
+
const g2 = Array.isArray(s2) ? s2 : s2.split(`
|
|
1151
|
+
`);
|
|
1152
|
+
if (g2.length > 0) {
|
|
1153
|
+
const [i3, ...y2] = g2;
|
|
1154
|
+
i3.length > 0 ? t3.push(`${O2}${i3}`) : t3.push(o2 ? e2 : "");
|
|
1155
|
+
for (const p2 of y2)
|
|
1156
|
+
p2.length > 0 ? t3.push(`${u4}${p2}`) : t3.push(o2 ? r3 : "");
|
|
1157
|
+
}
|
|
1158
|
+
m3.write(`${t3.join(`
|
|
1159
|
+
`)}
|
|
1160
|
+
`);
|
|
1161
|
+
},
|
|
1162
|
+
info: (s2, e2) => {
|
|
1163
|
+
log.message(s2, { ...e2, symbol: styleText2("blue", S_INFO) });
|
|
1164
|
+
},
|
|
1165
|
+
success: (s2, e2) => {
|
|
1166
|
+
log.message(s2, { ...e2, symbol: styleText2("green", S_SUCCESS) });
|
|
1167
|
+
},
|
|
1168
|
+
step: (s2, e2) => {
|
|
1169
|
+
log.message(s2, { ...e2, symbol: styleText2("green", S_STEP_SUBMIT) });
|
|
1170
|
+
},
|
|
1171
|
+
warn: (s2, e2) => {
|
|
1172
|
+
log.message(s2, { ...e2, symbol: styleText2("yellow", S_WARN) });
|
|
1173
|
+
},
|
|
1174
|
+
/** alias for `log.warn()`. */
|
|
1175
|
+
warning: (s2, e2) => {
|
|
1176
|
+
log.warn(s2, e2);
|
|
1177
|
+
},
|
|
1178
|
+
error: (s2, e2) => {
|
|
1179
|
+
log.message(s2, { ...e2, symbol: styleText2("red", S_ERROR) });
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
var cancel = (o2 = "", t3) => {
|
|
1183
|
+
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
|
|
1184
|
+
i3.write(`${e2}${styleText2("red", o2)}
|
|
1185
|
+
|
|
1186
|
+
`);
|
|
1187
|
+
};
|
|
1188
|
+
var intro = (o2 = "", t3) => {
|
|
1189
|
+
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
|
|
1190
|
+
i3.write(`${e2}${o2}
|
|
1191
|
+
`);
|
|
1192
|
+
};
|
|
1193
|
+
var outro = (o2 = "", t3) => {
|
|
1194
|
+
const i3 = t3?.output ?? process.stdout, e2 = t3?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
|
|
1195
|
+
${styleText2("gray", S_BAR_END)} ` : "";
|
|
1196
|
+
i3.write(`${e2}${o2}
|
|
1197
|
+
|
|
1198
|
+
`);
|
|
1199
|
+
};
|
|
1200
|
+
var W = (l3) => styleText2("magenta", l3);
|
|
1201
|
+
var spinner = ({
|
|
1202
|
+
indicator: l3 = "dots",
|
|
1203
|
+
onCancel: h3,
|
|
1204
|
+
output: n4 = process.stdout,
|
|
1205
|
+
cancelMessage: G,
|
|
1206
|
+
errorMessage: O2,
|
|
1207
|
+
frames: E2 = unicode ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"],
|
|
1208
|
+
delay: F2 = unicode ? 80 : 120,
|
|
1209
|
+
signal: m3,
|
|
1210
|
+
...I3
|
|
1211
|
+
} = {}) => {
|
|
1212
|
+
const u4 = isCI();
|
|
1213
|
+
let M, T2, d2 = false, S2 = false, s2 = "", p2, w2 = performance.now();
|
|
1214
|
+
const x2 = getColumns(n4), k2 = I3?.styleFrame ?? W, g2 = (e2) => {
|
|
1215
|
+
const r3 = e2 > 1 ? O2 ?? settings.messages.error : G ?? settings.messages.cancel;
|
|
1216
|
+
S2 = e2 === 1, d2 && (a3(r3, e2), S2 && typeof h3 == "function" && h3());
|
|
1217
|
+
}, f2 = () => g2(2), i3 = () => g2(1), A = () => {
|
|
1218
|
+
process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i3), process.on("SIGTERM", i3), process.on("exit", g2), m3 && m3.addEventListener("abort", i3);
|
|
1219
|
+
}, H = () => {
|
|
1220
|
+
process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i3), process.removeListener("SIGTERM", i3), process.removeListener("exit", g2), m3 && m3.removeEventListener("abort", i3);
|
|
1221
|
+
}, y2 = () => {
|
|
1222
|
+
if (p2 === void 0) return;
|
|
1223
|
+
u4 && n4.write(`
|
|
1224
|
+
`);
|
|
1225
|
+
const r3 = wrapAnsi(p2, x2, {
|
|
1226
|
+
hard: true,
|
|
1227
|
+
trim: false
|
|
1228
|
+
}).split(`
|
|
1229
|
+
`);
|
|
1230
|
+
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());
|
|
1231
|
+
}, C2 = (e2) => e2.replace(/\.+$/, ""), _2 = (e2) => {
|
|
1232
|
+
const r3 = (performance.now() - e2) / 1e3, t3 = Math.floor(r3 / 60), o2 = Math.floor(r3 % 60);
|
|
1233
|
+
return t3 > 0 ? `[${t3}m ${o2}s]` : `[${o2}s]`;
|
|
1234
|
+
}, N2 = I3.withGuide ?? settings.withGuide, P2 = (e2 = "") => {
|
|
1235
|
+
d2 = true, M = block({ output: n4 }), s2 = C2(e2), w2 = performance.now(), N2 && n4.write(`${styleText2("gray", S_BAR)}
|
|
1236
|
+
`);
|
|
1237
|
+
let r3 = 0, t3 = 0;
|
|
1238
|
+
A(), T2 = setInterval(() => {
|
|
1239
|
+
if (u4 && s2 === p2)
|
|
1240
|
+
return;
|
|
1241
|
+
y2(), p2 = s2;
|
|
1242
|
+
const o2 = k2(E2[r3]);
|
|
1243
|
+
let v2;
|
|
1244
|
+
if (u4)
|
|
1245
|
+
v2 = `${o2} ${s2}...`;
|
|
1246
|
+
else if (l3 === "timer")
|
|
1247
|
+
v2 = `${o2} ${s2} ${_2(w2)}`;
|
|
1248
|
+
else {
|
|
1249
|
+
const B = ".".repeat(Math.floor(t3)).slice(0, 3);
|
|
1250
|
+
v2 = `${o2} ${s2}${B}`;
|
|
1251
|
+
}
|
|
1252
|
+
const j2 = wrapAnsi(v2, x2, {
|
|
1253
|
+
hard: true,
|
|
1254
|
+
trim: false
|
|
1255
|
+
});
|
|
1256
|
+
n4.write(j2), r3 = r3 + 1 < E2.length ? r3 + 1 : 0, t3 = t3 < 4 ? t3 + 0.125 : 0;
|
|
1257
|
+
}, F2);
|
|
1258
|
+
}, a3 = (e2 = "", r3 = 0, t3 = false) => {
|
|
1259
|
+
if (!d2) return;
|
|
1260
|
+
d2 = false, clearInterval(T2), y2();
|
|
1261
|
+
const o2 = r3 === 0 ? styleText2("green", S_STEP_SUBMIT) : r3 === 1 ? styleText2("red", S_STEP_CANCEL) : styleText2("red", S_STEP_ERROR);
|
|
1262
|
+
s2 = e2 ?? s2, t3 || (l3 === "timer" ? n4.write(`${o2} ${s2} ${_2(w2)}
|
|
1263
|
+
`) : n4.write(`${o2} ${s2}
|
|
1264
|
+
`)), H(), M();
|
|
1265
|
+
};
|
|
1266
|
+
return {
|
|
1267
|
+
start: P2,
|
|
1268
|
+
stop: (e2 = "") => a3(e2, 0),
|
|
1269
|
+
message: (e2 = "") => {
|
|
1270
|
+
s2 = C2(e2 ?? s2);
|
|
1271
|
+
},
|
|
1272
|
+
cancel: (e2 = "") => a3(e2, 1),
|
|
1273
|
+
error: (e2 = "") => a3(e2, 2),
|
|
1274
|
+
clear: () => a3("", 0, true),
|
|
1275
|
+
get isCancelled() {
|
|
1276
|
+
return S2;
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
};
|
|
1280
|
+
var u2 = {
|
|
1281
|
+
light: unicodeOr("\u2500", "-"),
|
|
1282
|
+
heavy: unicodeOr("\u2501", "="),
|
|
1283
|
+
block: unicodeOr("\u2588", "#")
|
|
1284
|
+
};
|
|
1285
|
+
var SELECT_INSTRUCTIONS = [
|
|
1286
|
+
`${styleText2("dim", "\u2191/\u2193")} to navigate`,
|
|
1287
|
+
`${styleText2("dim", "Enter:")} confirm`
|
|
1288
|
+
];
|
|
1289
|
+
var c = (t3, o2) => t3.includes(`
|
|
1290
|
+
`) ? t3.split(`
|
|
1291
|
+
`).map((d2) => o2(d2)).join(`
|
|
1292
|
+
`) : o2(t3);
|
|
1293
|
+
var select = (t3) => {
|
|
1294
|
+
const o2 = (n4, m3) => {
|
|
1295
|
+
if (n4 === void 0)
|
|
1296
|
+
return "";
|
|
1297
|
+
const s2 = n4.label ?? String(n4.value);
|
|
1298
|
+
switch (m3) {
|
|
1299
|
+
case "disabled":
|
|
1300
|
+
return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s2, (i3) => styleText2("gray", i3))}${n4.hint ? ` ${styleText2("dim", `(${n4.hint ?? "disabled"})`)}` : ""}`;
|
|
1301
|
+
case "selected":
|
|
1302
|
+
return `${c(s2, (i3) => styleText2("dim", i3))}`;
|
|
1303
|
+
case "active":
|
|
1304
|
+
return `${styleText2("green", S_RADIO_ACTIVE)} ${s2}${n4.hint ? ` ${styleText2("dim", `(${n4.hint})`)}` : ""}`;
|
|
1305
|
+
case "cancelled":
|
|
1306
|
+
return `${c(s2, (i3) => styleText2(["strikethrough", "dim"], i3))}`;
|
|
1307
|
+
default:
|
|
1308
|
+
return `${styleText2("dim", S_RADIO_INACTIVE)} ${c(s2, (i3) => styleText2("dim", i3))}`;
|
|
1309
|
+
}
|
|
1310
|
+
}, d2 = t3.showInstructions ?? true;
|
|
1311
|
+
return new n$1({
|
|
1312
|
+
options: t3.options,
|
|
1313
|
+
signal: t3.signal,
|
|
1314
|
+
input: t3.input,
|
|
1315
|
+
output: t3.output,
|
|
1316
|
+
initialValue: t3.initialValue,
|
|
1317
|
+
render() {
|
|
1318
|
+
const n4 = t3.withGuide ?? settings.withGuide, m3 = `${symbol(this.state)} `, s2 = `${symbolBar(this.state)} `, i3 = wrapTextWithPrefix(
|
|
1319
|
+
t3.output,
|
|
1320
|
+
t3.message,
|
|
1321
|
+
s2,
|
|
1322
|
+
m3
|
|
1323
|
+
), u4 = `${n4 ? `${styleText2("gray", S_BAR)}
|
|
1324
|
+
` : ""}${i3}
|
|
1325
|
+
`;
|
|
1326
|
+
switch (this.state) {
|
|
1327
|
+
case "submit": {
|
|
1328
|
+
const r3 = n4 ? `${styleText2("gray", S_BAR)} ` : "", a3 = wrapTextWithPrefix(
|
|
1329
|
+
t3.output,
|
|
1330
|
+
o2(this.options[this.cursor], "selected"),
|
|
1331
|
+
r3
|
|
1332
|
+
);
|
|
1333
|
+
return `${u4}${a3}`;
|
|
1334
|
+
}
|
|
1335
|
+
case "cancel": {
|
|
1336
|
+
const r3 = n4 ? `${styleText2("gray", S_BAR)} ` : "", a3 = wrapTextWithPrefix(
|
|
1337
|
+
t3.output,
|
|
1338
|
+
o2(this.options[this.cursor], "cancelled"),
|
|
1339
|
+
r3
|
|
1340
|
+
);
|
|
1341
|
+
return `${u4}${a3}${n4 ? `
|
|
1342
|
+
${styleText2("gray", S_BAR)}` : ""}`;
|
|
1343
|
+
}
|
|
1344
|
+
default: {
|
|
1345
|
+
const r3 = n4 ? `${styleText2("cyan", S_BAR)} ` : "", a3 = u4.split(`
|
|
1346
|
+
`).length, p2 = d2 ? formatInstructionFooter(SELECT_INSTRUCTIONS, n4) : n4 ? [styleText2("cyan", S_BAR_END)] : [], b2 = p2.join(`
|
|
1347
|
+
`), f2 = p2.length + 1;
|
|
1348
|
+
return `${u4}${r3}${limitOptions({
|
|
1349
|
+
output: t3.output,
|
|
1350
|
+
cursor: this.cursor,
|
|
1351
|
+
options: this.options,
|
|
1352
|
+
maxItems: t3.maxItems,
|
|
1353
|
+
columnPadding: r3.length,
|
|
1354
|
+
rowPadding: a3 + f2,
|
|
1355
|
+
style: (g2, x2) => o2(g2, g2.disabled ? "disabled" : x2 ? "active" : "inactive")
|
|
1356
|
+
}).join(`
|
|
1357
|
+
${r3}`)}
|
|
1358
|
+
${b2}
|
|
1359
|
+
`;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
}).prompt();
|
|
1364
|
+
};
|
|
1365
|
+
var i = `${styleText2("gray", S_BAR)} `;
|
|
1366
|
+
var text = (e2) => new n2({
|
|
1367
|
+
validate: e2.validate,
|
|
1368
|
+
placeholder: e2.placeholder,
|
|
1369
|
+
defaultValue: e2.defaultValue,
|
|
1370
|
+
initialValue: e2.initialValue,
|
|
1371
|
+
output: e2.output,
|
|
1372
|
+
signal: e2.signal,
|
|
1373
|
+
input: e2.input,
|
|
1374
|
+
render() {
|
|
1375
|
+
const i3 = e2?.withGuide ?? settings.withGuide, s2 = `${`${i3 ? `${styleText2("gray", S_BAR)}
|
|
1376
|
+
` : ""}${symbol(this.state)} `}${e2.message}
|
|
1377
|
+
`, c3 = e2.placeholder && e2.placeholder.length > 0 ? (
|
|
1378
|
+
// biome-ignore lint/style/noNonNullAssertion: guarded by placeholder.length > 0
|
|
1379
|
+
styleText2("inverse", e2.placeholder[0]) + styleText2("dim", e2.placeholder.slice(1))
|
|
1380
|
+
) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c3, l3 = this.value ?? "";
|
|
1381
|
+
switch (this.state) {
|
|
1382
|
+
case "error": {
|
|
1383
|
+
const n4 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r3 = i3 ? `${styleText2("yellow", S_BAR)} ` : "", d2 = i3 ? styleText2("yellow", S_BAR_END) : "";
|
|
1384
|
+
return `${s2.trim()}
|
|
1385
|
+
${r3}${o2}
|
|
1386
|
+
${d2}${n4}
|
|
1387
|
+
`;
|
|
1388
|
+
}
|
|
1389
|
+
case "submit": {
|
|
1390
|
+
const n4 = l3 ? ` ${styleText2("dim", l3)}` : "", r3 = i3 ? styleText2("gray", S_BAR) : "";
|
|
1391
|
+
return `${s2}${r3}${n4}`;
|
|
1392
|
+
}
|
|
1393
|
+
case "cancel": {
|
|
1394
|
+
const n4 = l3 ? ` ${styleText2(["strikethrough", "dim"], l3)}` : "", r3 = i3 ? styleText2("gray", S_BAR) : "";
|
|
1395
|
+
return `${s2}${r3}${n4}${l3.trim() ? `
|
|
1396
|
+
${r3}` : ""}`;
|
|
1397
|
+
}
|
|
1398
|
+
default: {
|
|
1399
|
+
const n4 = i3 ? `${styleText2("cyan", S_BAR)} ` : "", r3 = i3 ? styleText2("cyan", S_BAR_END) : "";
|
|
1400
|
+
return `${s2}${n4}${o2}
|
|
1401
|
+
${r3}
|
|
1402
|
+
`;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
}).prompt();
|
|
1407
|
+
|
|
1408
|
+
// node_modules/citty/dist/_chunks/libs/scule.mjs
|
|
1409
|
+
var NUMBER_CHAR_RE = /\d/;
|
|
1410
|
+
var STR_SPLITTERS = [
|
|
1411
|
+
"-",
|
|
1412
|
+
"_",
|
|
1413
|
+
"/",
|
|
1414
|
+
"."
|
|
1415
|
+
];
|
|
1416
|
+
function isUppercase(char = "") {
|
|
1417
|
+
if (NUMBER_CHAR_RE.test(char)) return;
|
|
1418
|
+
return char !== char.toLowerCase();
|
|
1419
|
+
}
|
|
1420
|
+
function splitByCase(str, separators) {
|
|
1421
|
+
const splitters = separators ?? STR_SPLITTERS;
|
|
1422
|
+
const parts = [];
|
|
1423
|
+
if (!str || typeof str !== "string") return parts;
|
|
1424
|
+
let buff = "";
|
|
1425
|
+
let previousUpper;
|
|
1426
|
+
let previousSplitter;
|
|
1427
|
+
for (const char of str) {
|
|
1428
|
+
const isSplitter = splitters.includes(char);
|
|
1429
|
+
if (isSplitter === true) {
|
|
1430
|
+
parts.push(buff);
|
|
1431
|
+
buff = "";
|
|
1432
|
+
previousUpper = void 0;
|
|
1433
|
+
continue;
|
|
1434
|
+
}
|
|
1435
|
+
const isUpper = isUppercase(char);
|
|
1436
|
+
if (previousSplitter === false) {
|
|
1437
|
+
if (previousUpper === false && isUpper === true) {
|
|
1438
|
+
parts.push(buff);
|
|
1439
|
+
buff = char;
|
|
1440
|
+
previousUpper = isUpper;
|
|
1441
|
+
continue;
|
|
1442
|
+
}
|
|
1443
|
+
if (previousUpper === true && isUpper === false && buff.length > 1) {
|
|
1444
|
+
const lastChar = buff.at(-1);
|
|
1445
|
+
parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
|
|
1446
|
+
buff = lastChar + char;
|
|
1447
|
+
previousUpper = isUpper;
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
buff += char;
|
|
1452
|
+
previousUpper = isUpper;
|
|
1453
|
+
previousSplitter = isSplitter;
|
|
1454
|
+
}
|
|
1455
|
+
parts.push(buff);
|
|
1456
|
+
return parts;
|
|
1457
|
+
}
|
|
1458
|
+
function upperFirst(str) {
|
|
1459
|
+
return str ? str[0].toUpperCase() + str.slice(1) : "";
|
|
1460
|
+
}
|
|
1461
|
+
function lowerFirst(str) {
|
|
1462
|
+
return str ? str[0].toLowerCase() + str.slice(1) : "";
|
|
1463
|
+
}
|
|
1464
|
+
function pascalCase(str, opts) {
|
|
1465
|
+
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => upperFirst(opts?.normalize ? p2.toLowerCase() : p2)).join("") : "";
|
|
1466
|
+
}
|
|
1467
|
+
function camelCase(str, opts) {
|
|
1468
|
+
return lowerFirst(pascalCase(str || "", opts));
|
|
1469
|
+
}
|
|
1470
|
+
function kebabCase(str, joiner) {
|
|
1471
|
+
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => p2.toLowerCase()).join(joiner ?? "-") : "";
|
|
1472
|
+
}
|
|
1473
|
+
function snakeCase(str) {
|
|
1474
|
+
return kebabCase(str || "", "_");
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
// node_modules/citty/dist/index.mjs
|
|
1478
|
+
import { parseArgs as parseArgs$1 } from "node:util";
|
|
1479
|
+
function toArray(val) {
|
|
1480
|
+
if (Array.isArray(val)) return val;
|
|
1481
|
+
return val === void 0 ? [] : [val];
|
|
1482
|
+
}
|
|
1483
|
+
function formatLineColumns(lines, linePrefix = "") {
|
|
1484
|
+
const maxLength = [];
|
|
1485
|
+
for (const line of lines) for (const [i3, element] of line.entries()) maxLength[i3] = Math.max(maxLength[i3] || 0, element.length);
|
|
1486
|
+
return lines.map((l3) => l3.map((c3, i3) => linePrefix + c3[i3 === 0 ? "padStart" : "padEnd"](maxLength[i3])).join(" ")).join("\n");
|
|
1487
|
+
}
|
|
1488
|
+
function resolveValue(input) {
|
|
1489
|
+
return typeof input === "function" ? input() : input;
|
|
1490
|
+
}
|
|
1491
|
+
var CLIError = class extends Error {
|
|
1492
|
+
code;
|
|
1493
|
+
constructor(message, code) {
|
|
1494
|
+
super(message);
|
|
1495
|
+
this.name = "CLIError";
|
|
1496
|
+
this.code = code;
|
|
1497
|
+
}
|
|
1498
|
+
};
|
|
1499
|
+
function parseRawArgs(args = [], opts = {}) {
|
|
1500
|
+
const booleans = new Set(opts.boolean || []);
|
|
1501
|
+
const strings = new Set(opts.string || []);
|
|
1502
|
+
const aliasMap = opts.alias || {};
|
|
1503
|
+
const defaults = opts.default || {};
|
|
1504
|
+
const aliasToMain = /* @__PURE__ */ new Map();
|
|
1505
|
+
const mainToAliases = /* @__PURE__ */ new Map();
|
|
1506
|
+
for (const [key, value] of Object.entries(aliasMap)) {
|
|
1507
|
+
const targets = value;
|
|
1508
|
+
for (const target of targets) {
|
|
1509
|
+
aliasToMain.set(key, target);
|
|
1510
|
+
if (!mainToAliases.has(target)) mainToAliases.set(target, []);
|
|
1511
|
+
mainToAliases.get(target).push(key);
|
|
1512
|
+
aliasToMain.set(target, key);
|
|
1513
|
+
if (!mainToAliases.has(key)) mainToAliases.set(key, []);
|
|
1514
|
+
mainToAliases.get(key).push(target);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
const options = {};
|
|
1518
|
+
function getType(name) {
|
|
1519
|
+
if (booleans.has(name)) return "boolean";
|
|
1520
|
+
const aliases = mainToAliases.get(name) || [];
|
|
1521
|
+
for (const alias of aliases) if (booleans.has(alias)) return "boolean";
|
|
1522
|
+
return "string";
|
|
1523
|
+
}
|
|
1524
|
+
function isStringType(name) {
|
|
1525
|
+
if (strings.has(name)) return true;
|
|
1526
|
+
const aliases = mainToAliases.get(name) || [];
|
|
1527
|
+
for (const alias of aliases) if (strings.has(alias)) return true;
|
|
1528
|
+
return false;
|
|
1529
|
+
}
|
|
1530
|
+
const allOptions = /* @__PURE__ */ new Set([
|
|
1531
|
+
...booleans,
|
|
1532
|
+
...strings,
|
|
1533
|
+
...Object.keys(aliasMap),
|
|
1534
|
+
...Object.values(aliasMap).flat(),
|
|
1535
|
+
...Object.keys(defaults)
|
|
1536
|
+
]);
|
|
1537
|
+
for (const name of allOptions) if (!options[name]) options[name] = {
|
|
1538
|
+
type: getType(name),
|
|
1539
|
+
default: defaults[name]
|
|
1540
|
+
};
|
|
1541
|
+
for (const [alias, main2] of aliasToMain.entries()) if (alias.length === 1 && options[main2] && !options[main2].short) options[main2].short = alias;
|
|
1542
|
+
const processedArgs = [];
|
|
1543
|
+
const negatedFlags = {};
|
|
1544
|
+
for (let i3 = 0; i3 < args.length; i3++) {
|
|
1545
|
+
const arg = args[i3];
|
|
1546
|
+
if (arg === "--") {
|
|
1547
|
+
processedArgs.push(...args.slice(i3));
|
|
1548
|
+
break;
|
|
1549
|
+
}
|
|
1550
|
+
if (arg.startsWith("--no-")) {
|
|
1551
|
+
const flagName = arg.slice(5);
|
|
1552
|
+
negatedFlags[flagName] = true;
|
|
1553
|
+
continue;
|
|
1554
|
+
}
|
|
1555
|
+
processedArgs.push(arg);
|
|
1556
|
+
}
|
|
1557
|
+
let parsed;
|
|
1558
|
+
try {
|
|
1559
|
+
parsed = parseArgs$1({
|
|
1560
|
+
args: processedArgs,
|
|
1561
|
+
options: Object.keys(options).length > 0 ? options : void 0,
|
|
1562
|
+
allowPositionals: true,
|
|
1563
|
+
strict: false
|
|
1564
|
+
});
|
|
1565
|
+
} catch {
|
|
1566
|
+
parsed = {
|
|
1567
|
+
values: {},
|
|
1568
|
+
positionals: processedArgs
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
const out = { _: [] };
|
|
1572
|
+
out._ = parsed.positionals;
|
|
1573
|
+
for (const [key, value] of Object.entries(parsed.values)) {
|
|
1574
|
+
let coerced = value;
|
|
1575
|
+
if (getType(key) === "boolean" && typeof value === "string") coerced = value !== "false";
|
|
1576
|
+
else if (isStringType(key) && typeof value === "boolean") coerced = "";
|
|
1577
|
+
out[key] = coerced;
|
|
1578
|
+
}
|
|
1579
|
+
for (const [name] of Object.entries(negatedFlags)) {
|
|
1580
|
+
out[name] = false;
|
|
1581
|
+
const mainName = aliasToMain.get(name);
|
|
1582
|
+
if (mainName) out[mainName] = false;
|
|
1583
|
+
const aliases = mainToAliases.get(name);
|
|
1584
|
+
if (aliases) for (const alias of aliases) out[alias] = false;
|
|
1585
|
+
}
|
|
1586
|
+
for (const [alias, main2] of aliasToMain.entries()) {
|
|
1587
|
+
if (out[alias] !== void 0 && out[main2] === void 0) out[main2] = out[alias];
|
|
1588
|
+
if (out[main2] !== void 0 && out[alias] === void 0) out[alias] = out[main2];
|
|
1589
|
+
if (out[alias] !== out[main2] && defaults[main2] === out[main2]) out[main2] = out[alias];
|
|
1590
|
+
}
|
|
1591
|
+
return out;
|
|
1592
|
+
}
|
|
1593
|
+
var noColor = /* @__PURE__ */ (() => {
|
|
1594
|
+
const env = globalThis.process?.env ?? {};
|
|
1595
|
+
return env.NO_COLOR === "1" || env.TERM === "dumb" || env.TEST || env.CI;
|
|
1596
|
+
})();
|
|
1597
|
+
var _c = (c3, r3 = 39) => (t3) => noColor ? t3 : `\x1B[${c3}m${t3}\x1B[${r3}m`;
|
|
1598
|
+
var bold = /* @__PURE__ */ _c(1, 22);
|
|
1599
|
+
var cyan = /* @__PURE__ */ _c(36);
|
|
1600
|
+
var gray = /* @__PURE__ */ _c(90);
|
|
1601
|
+
var underline = /* @__PURE__ */ _c(4, 24);
|
|
1602
|
+
function parseArgs(rawArgs, argsDef) {
|
|
1603
|
+
const parseOptions = {
|
|
1604
|
+
boolean: [],
|
|
1605
|
+
string: [],
|
|
1606
|
+
alias: {},
|
|
1607
|
+
default: {}
|
|
1608
|
+
};
|
|
1609
|
+
const args = resolveArgs(argsDef);
|
|
1610
|
+
for (const arg of args) {
|
|
1611
|
+
if (arg.type === "positional") continue;
|
|
1612
|
+
if (arg.type === "string" || arg.type === "enum") parseOptions.string.push(arg.name);
|
|
1613
|
+
else if (arg.type === "boolean") parseOptions.boolean.push(arg.name);
|
|
1614
|
+
if (arg.default !== void 0) parseOptions.default[arg.name] = arg.default;
|
|
1615
|
+
if (arg.alias) parseOptions.alias[arg.name] = arg.alias;
|
|
1616
|
+
const camelName = camelCase(arg.name);
|
|
1617
|
+
const kebabName = kebabCase(arg.name);
|
|
1618
|
+
if (camelName !== arg.name || kebabName !== arg.name) {
|
|
1619
|
+
const existingAliases = toArray(parseOptions.alias[arg.name] || []);
|
|
1620
|
+
if (camelName !== arg.name && !existingAliases.includes(camelName)) existingAliases.push(camelName);
|
|
1621
|
+
if (kebabName !== arg.name && !existingAliases.includes(kebabName)) existingAliases.push(kebabName);
|
|
1622
|
+
if (existingAliases.length > 0) parseOptions.alias[arg.name] = existingAliases;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
const parsed = parseRawArgs(rawArgs, parseOptions);
|
|
1626
|
+
const [...positionalArguments] = parsed._;
|
|
1627
|
+
const parsedArgsProxy = new Proxy(parsed, { get(target, prop) {
|
|
1628
|
+
return target[prop] ?? target[camelCase(prop)] ?? target[kebabCase(prop)];
|
|
1629
|
+
} });
|
|
1630
|
+
for (const [, arg] of args.entries()) if (arg.type === "positional") {
|
|
1631
|
+
const nextPositionalArgument = positionalArguments.shift();
|
|
1632
|
+
if (nextPositionalArgument !== void 0) parsedArgsProxy[arg.name] = nextPositionalArgument;
|
|
1633
|
+
else if (arg.default === void 0 && arg.required !== false) throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`, "EARG");
|
|
1634
|
+
else parsedArgsProxy[arg.name] = arg.default;
|
|
1635
|
+
} else if (arg.type === "enum") {
|
|
1636
|
+
const argument = parsedArgsProxy[arg.name];
|
|
1637
|
+
const options = arg.options || [];
|
|
1638
|
+
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");
|
|
1639
|
+
} else if (arg.required && parsedArgsProxy[arg.name] === void 0) throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
|
|
1640
|
+
return parsedArgsProxy;
|
|
1641
|
+
}
|
|
1642
|
+
function resolveArgs(argsDef) {
|
|
1643
|
+
const args = [];
|
|
1644
|
+
for (const [name, argDef] of Object.entries(argsDef || {})) args.push({
|
|
1645
|
+
...argDef,
|
|
1646
|
+
name,
|
|
1647
|
+
alias: toArray(argDef.alias)
|
|
1648
|
+
});
|
|
1649
|
+
return args;
|
|
1650
|
+
}
|
|
1651
|
+
async function resolvePlugins(plugins) {
|
|
1652
|
+
return Promise.all(plugins.map((p2) => resolveValue(p2)));
|
|
1653
|
+
}
|
|
1654
|
+
function defineCommand(def) {
|
|
1655
|
+
return def;
|
|
1656
|
+
}
|
|
1657
|
+
async function runCommand(cmd, opts) {
|
|
1658
|
+
const cmdArgs = await resolveValue(cmd.args || {});
|
|
1659
|
+
const parsedArgs = parseArgs(opts.rawArgs, cmdArgs);
|
|
1660
|
+
const context = {
|
|
1661
|
+
rawArgs: opts.rawArgs,
|
|
1662
|
+
args: parsedArgs,
|
|
1663
|
+
data: opts.data,
|
|
1664
|
+
cmd
|
|
1665
|
+
};
|
|
1666
|
+
const plugins = await resolvePlugins(cmd.plugins ?? []);
|
|
1667
|
+
let result;
|
|
1668
|
+
let runError;
|
|
1669
|
+
try {
|
|
1670
|
+
for (const plugin of plugins) await plugin.setup?.(context);
|
|
1671
|
+
if (typeof cmd.setup === "function") await cmd.setup(context);
|
|
1672
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
1673
|
+
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
1674
|
+
const subCommandArgIndex = findSubCommandIndex(opts.rawArgs, cmdArgs);
|
|
1675
|
+
const explicitName = opts.rawArgs[subCommandArgIndex];
|
|
1676
|
+
if (explicitName) {
|
|
1677
|
+
const subCommand = await _findSubCommand(subCommands, explicitName);
|
|
1678
|
+
if (!subCommand) throw new CLIError(`Unknown command ${cyan(explicitName)}`, "E_UNKNOWN_COMMAND");
|
|
1679
|
+
await runCommand(subCommand, { rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1) });
|
|
1680
|
+
} else {
|
|
1681
|
+
const defaultSubCommand = await resolveValue(cmd.default);
|
|
1682
|
+
if (defaultSubCommand) {
|
|
1683
|
+
if (cmd.run) throw new CLIError(`Cannot specify both 'run' and 'default' on the same command.`, "E_DEFAULT_CONFLICT");
|
|
1684
|
+
const subCommand = await _findSubCommand(subCommands, defaultSubCommand);
|
|
1685
|
+
if (!subCommand) throw new CLIError(`Default sub command ${cyan(defaultSubCommand)} not found in subCommands.`, "E_UNKNOWN_COMMAND");
|
|
1686
|
+
await runCommand(subCommand, { rawArgs: opts.rawArgs });
|
|
1687
|
+
} else if (!cmd.run) throw new CLIError(`No command specified.`, "E_NO_COMMAND");
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
if (typeof cmd.run === "function") result = await cmd.run(context);
|
|
1691
|
+
} catch (error) {
|
|
1692
|
+
runError = error;
|
|
1693
|
+
}
|
|
1694
|
+
const cleanupErrors = [];
|
|
1695
|
+
if (typeof cmd.cleanup === "function") try {
|
|
1696
|
+
await cmd.cleanup(context);
|
|
1697
|
+
} catch (error) {
|
|
1698
|
+
cleanupErrors.push(error);
|
|
1699
|
+
}
|
|
1700
|
+
for (const plugin of [...plugins].reverse()) try {
|
|
1701
|
+
await plugin.cleanup?.(context);
|
|
1702
|
+
} catch (error) {
|
|
1703
|
+
cleanupErrors.push(error);
|
|
1704
|
+
}
|
|
1705
|
+
if (runError) throw runError;
|
|
1706
|
+
if (cleanupErrors.length === 1) throw cleanupErrors[0];
|
|
1707
|
+
if (cleanupErrors.length > 1) throw new Error("Multiple cleanup errors", { cause: cleanupErrors });
|
|
1708
|
+
return { result };
|
|
1709
|
+
}
|
|
1710
|
+
async function resolveSubCommand(cmd, rawArgs, parent) {
|
|
1711
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
1712
|
+
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
1713
|
+
const subCommandArgIndex = findSubCommandIndex(rawArgs, await resolveValue(cmd.args || {}));
|
|
1714
|
+
const subCommandName = rawArgs[subCommandArgIndex];
|
|
1715
|
+
const subCommand = await _findSubCommand(subCommands, subCommandName);
|
|
1716
|
+
if (subCommand) return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);
|
|
1717
|
+
}
|
|
1718
|
+
return [cmd, parent];
|
|
1719
|
+
}
|
|
1720
|
+
async function _findSubCommand(subCommands, name) {
|
|
1721
|
+
if (name in subCommands) return resolveValue(subCommands[name]);
|
|
1722
|
+
for (const sub of Object.values(subCommands)) {
|
|
1723
|
+
const resolved = await resolveValue(sub);
|
|
1724
|
+
const meta = await resolveValue(resolved?.meta);
|
|
1725
|
+
if (meta?.alias) {
|
|
1726
|
+
if (toArray(meta.alias).includes(name)) return resolved;
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
function findSubCommandIndex(rawArgs, argsDef) {
|
|
1731
|
+
for (let i3 = 0; i3 < rawArgs.length; i3++) {
|
|
1732
|
+
const arg = rawArgs[i3];
|
|
1733
|
+
if (arg === "--") return -1;
|
|
1734
|
+
if (arg.startsWith("-")) {
|
|
1735
|
+
if (!arg.includes("=") && _isValueFlag(arg, argsDef)) i3++;
|
|
1736
|
+
continue;
|
|
1737
|
+
}
|
|
1738
|
+
return i3;
|
|
1739
|
+
}
|
|
1740
|
+
return -1;
|
|
1741
|
+
}
|
|
1742
|
+
function _isValueFlag(flag, argsDef) {
|
|
1743
|
+
const name = flag.replace(/^-{1,2}/, "");
|
|
1744
|
+
const normalized = camelCase(name);
|
|
1745
|
+
for (const [key, def] of Object.entries(argsDef)) {
|
|
1746
|
+
if (def.type !== "string" && def.type !== "enum") continue;
|
|
1747
|
+
if (normalized === camelCase(key)) return true;
|
|
1748
|
+
if ((Array.isArray(def.alias) ? def.alias : def.alias ? [def.alias] : []).includes(name)) return true;
|
|
1749
|
+
}
|
|
1750
|
+
return false;
|
|
1751
|
+
}
|
|
1752
|
+
async function showUsage(cmd, parent) {
|
|
1753
|
+
try {
|
|
1754
|
+
console.log(await renderUsage(cmd, parent) + "\n");
|
|
1755
|
+
} catch (error) {
|
|
1756
|
+
console.error(error);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
var negativePrefixRe = /^no[-A-Z]/;
|
|
1760
|
+
async function renderUsage(cmd, parent) {
|
|
1761
|
+
const cmdMeta = await resolveValue(cmd.meta || {});
|
|
1762
|
+
const cmdArgs = resolveArgs(await resolveValue(cmd.args || {}));
|
|
1763
|
+
const parentMeta = await resolveValue(parent?.meta || {});
|
|
1764
|
+
const commandName = `${parentMeta.name ? `${parentMeta.name} ` : ""}` + (cmdMeta.name || process.argv[1]);
|
|
1765
|
+
const argLines = [];
|
|
1766
|
+
const posLines = [];
|
|
1767
|
+
const commandsLines = [];
|
|
1768
|
+
const usageLine = [];
|
|
1769
|
+
for (const arg of cmdArgs) if (arg.type === "positional") {
|
|
1770
|
+
const name = arg.name.toUpperCase();
|
|
1771
|
+
const isRequired = arg.required !== false && arg.default === void 0;
|
|
1772
|
+
posLines.push([cyan(name + renderValueHint(arg)), renderDescription(arg, isRequired)]);
|
|
1773
|
+
usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
|
|
1774
|
+
} else {
|
|
1775
|
+
const isRequired = arg.required === true && arg.default === void 0;
|
|
1776
|
+
const argStr = [...(arg.alias || []).map((a3) => `-${a3}`), `--${arg.name}`].join(", ") + renderValueHint(arg);
|
|
1777
|
+
argLines.push([cyan(argStr), renderDescription(arg, isRequired)]);
|
|
1778
|
+
if (arg.type === "boolean" && (arg.default === true || arg.negativeDescription) && !negativePrefixRe.test(arg.name)) {
|
|
1779
|
+
const negativeArgStr = [...(arg.alias || []).map((a3) => `--no-${a3}`), `--no-${arg.name}`].join(", ");
|
|
1780
|
+
argLines.push([cyan(negativeArgStr), [arg.negativeDescription, isRequired ? gray("(Required)") : ""].filter(Boolean).join(" ")]);
|
|
1781
|
+
}
|
|
1782
|
+
if (isRequired) usageLine.push(`--${arg.name}` + renderValueHint(arg));
|
|
1783
|
+
}
|
|
1784
|
+
if (cmd.subCommands) {
|
|
1785
|
+
const commandNames = [];
|
|
1786
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
1787
|
+
for (const [name, sub] of Object.entries(subCommands)) {
|
|
1788
|
+
const meta = await resolveValue((await resolveValue(sub))?.meta);
|
|
1789
|
+
if (meta?.hidden) continue;
|
|
1790
|
+
const aliases = toArray(meta?.alias);
|
|
1791
|
+
const label = [name, ...aliases].join(", ");
|
|
1792
|
+
commandsLines.push([cyan(label), meta?.description || ""]);
|
|
1793
|
+
commandNames.push(name, ...aliases);
|
|
1794
|
+
}
|
|
1795
|
+
usageLine.push(commandNames.join("|"));
|
|
1796
|
+
}
|
|
1797
|
+
const usageLines = [];
|
|
1798
|
+
const version = cmdMeta.version || parentMeta.version;
|
|
1799
|
+
usageLines.push(gray(`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`), "");
|
|
1800
|
+
const hasOptions = argLines.length > 0 || posLines.length > 0;
|
|
1801
|
+
usageLines.push(`${underline(bold("USAGE"))} ${cyan(`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}`)}`, "");
|
|
1802
|
+
if (posLines.length > 0) {
|
|
1803
|
+
usageLines.push(underline(bold("ARGUMENTS")), "");
|
|
1804
|
+
usageLines.push(formatLineColumns(posLines, " "));
|
|
1805
|
+
usageLines.push("");
|
|
1806
|
+
}
|
|
1807
|
+
if (argLines.length > 0) {
|
|
1808
|
+
usageLines.push(underline(bold("OPTIONS")), "");
|
|
1809
|
+
usageLines.push(formatLineColumns(argLines, " "));
|
|
1810
|
+
usageLines.push("");
|
|
1811
|
+
}
|
|
1812
|
+
if (commandsLines.length > 0) {
|
|
1813
|
+
usageLines.push(underline(bold("COMMANDS")), "");
|
|
1814
|
+
usageLines.push(formatLineColumns(commandsLines, " "));
|
|
1815
|
+
usageLines.push("", `Use ${cyan(`${commandName} <command> --help`)} for more information about a command.`);
|
|
1816
|
+
}
|
|
1817
|
+
return usageLines.filter((l3) => typeof l3 === "string").join("\n");
|
|
1818
|
+
}
|
|
1819
|
+
function renderValueHint(arg) {
|
|
1820
|
+
const valueHint = arg.valueHint ? `=<${arg.valueHint}>` : "";
|
|
1821
|
+
const fallbackValueHint = valueHint || `=<${snakeCase(arg.name)}>`;
|
|
1822
|
+
if (!arg.type || arg.type === "positional" || arg.type === "boolean") return valueHint;
|
|
1823
|
+
if (arg.type === "enum" && arg.options?.length) return `=<${arg.options.join("|")}>`;
|
|
1824
|
+
return fallbackValueHint;
|
|
1825
|
+
}
|
|
1826
|
+
function renderDescription(arg, required) {
|
|
1827
|
+
const requiredHint = required ? gray("(Required)") : "";
|
|
1828
|
+
const defaultHint = arg.default === void 0 ? "" : gray(`(Default: ${arg.default})`);
|
|
1829
|
+
return [
|
|
1830
|
+
arg.description,
|
|
1831
|
+
requiredHint,
|
|
1832
|
+
defaultHint
|
|
1833
|
+
].filter(Boolean).join(" ");
|
|
1834
|
+
}
|
|
1835
|
+
async function runMain(cmd, opts = {}) {
|
|
1836
|
+
const rawArgs = opts.rawArgs || process.argv.slice(2);
|
|
1837
|
+
const showUsage$1 = opts.showUsage || showUsage;
|
|
1838
|
+
try {
|
|
1839
|
+
const builtinFlags = await _resolveBuiltinFlags(cmd);
|
|
1840
|
+
if (builtinFlags.help.length > 0 && rawArgs.some((arg) => builtinFlags.help.includes(arg))) {
|
|
1841
|
+
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
1842
|
+
process.exit(0);
|
|
1843
|
+
} else if (rawArgs.length === 1 && builtinFlags.version.includes(rawArgs[0])) {
|
|
1844
|
+
const meta = typeof cmd.meta === "function" ? await cmd.meta() : await cmd.meta;
|
|
1845
|
+
if (!meta?.version) throw new CLIError("No version specified", "E_NO_VERSION");
|
|
1846
|
+
console.log(meta.version);
|
|
1847
|
+
} else await runCommand(cmd, { rawArgs });
|
|
1848
|
+
} catch (error) {
|
|
1849
|
+
if (error instanceof CLIError) {
|
|
1850
|
+
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
1851
|
+
console.error(error.message);
|
|
1852
|
+
} else console.error(error, "\n");
|
|
1853
|
+
process.exit(1);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
async function _resolveBuiltinFlags(cmd) {
|
|
1857
|
+
const argsDef = await resolveValue(cmd.args || {});
|
|
1858
|
+
const userNames = /* @__PURE__ */ new Set();
|
|
1859
|
+
const userAliases = /* @__PURE__ */ new Set();
|
|
1860
|
+
for (const [name, def] of Object.entries(argsDef)) {
|
|
1861
|
+
userNames.add(name);
|
|
1862
|
+
for (const alias of toArray(def.alias)) userAliases.add(alias);
|
|
1863
|
+
}
|
|
1864
|
+
return {
|
|
1865
|
+
help: _getBuiltinFlags("help", "h", userNames, userAliases),
|
|
1866
|
+
version: _getBuiltinFlags("version", "v", userNames, userAliases)
|
|
1867
|
+
};
|
|
1868
|
+
}
|
|
1869
|
+
function _getBuiltinFlags(long, short, userNames, userAliases) {
|
|
1870
|
+
if (userNames.has(long) || userAliases.has(long)) return [];
|
|
1871
|
+
if (userNames.has(short) || userAliases.has(short)) return [`--${long}`];
|
|
1872
|
+
return [`--${long}`, `-${short}`];
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
// package.json
|
|
1876
|
+
var package_default = {
|
|
1877
|
+
name: "zapdev",
|
|
1878
|
+
version: "0.6.0",
|
|
1879
|
+
description: "Fast, performant and lightweight git chores and dev tools using your terminal and your own local LLM.",
|
|
1880
|
+
type: "module",
|
|
1881
|
+
bin: {
|
|
1882
|
+
zapdev: "./dist/index.js"
|
|
1883
|
+
},
|
|
1884
|
+
files: [
|
|
1885
|
+
"dist"
|
|
1886
|
+
],
|
|
1887
|
+
engines: {
|
|
1888
|
+
node: ">=20"
|
|
1889
|
+
},
|
|
1890
|
+
keywords: [
|
|
1891
|
+
"git",
|
|
1892
|
+
"cli",
|
|
1893
|
+
"commit",
|
|
1894
|
+
"conventional-commits",
|
|
1895
|
+
"ollama",
|
|
1896
|
+
"llm",
|
|
1897
|
+
"ai"
|
|
1898
|
+
],
|
|
1899
|
+
author: "Matthieu Vagnon <hi@mvagnon.dev>",
|
|
1900
|
+
license: "MIT",
|
|
1901
|
+
repository: {
|
|
1902
|
+
type: "git",
|
|
1903
|
+
url: "git+https://github.com/mvagnon/zapdev.git"
|
|
1904
|
+
},
|
|
1905
|
+
homepage: "https://github.com/mvagnon/zapdev#readme",
|
|
1906
|
+
bugs: {
|
|
1907
|
+
url: "https://github.com/mvagnon/zapdev/issues"
|
|
1908
|
+
},
|
|
1909
|
+
publishConfig: {
|
|
1910
|
+
access: "public"
|
|
1911
|
+
},
|
|
1912
|
+
scripts: {
|
|
1913
|
+
zapdev: "npm run build && node dist/index.js",
|
|
1914
|
+
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",
|
|
1915
|
+
lint: "eslint .",
|
|
1916
|
+
typecheck: "tsc --noEmit",
|
|
1917
|
+
test: "vitest run",
|
|
1918
|
+
prepack: "npm run build"
|
|
1919
|
+
},
|
|
1920
|
+
devDependencies: {
|
|
1921
|
+
"@clack/prompts": "^1.6.0",
|
|
1922
|
+
"@eslint/js": "^10.0.1",
|
|
1923
|
+
"@eslint/json": "^2.0.0",
|
|
1924
|
+
"@eslint/markdown": "^8.0.2",
|
|
1925
|
+
"@types/node": "^26.1.1",
|
|
1926
|
+
citty: "^0.2.2",
|
|
1927
|
+
esbuild: "^0.28.1",
|
|
1928
|
+
eslint: "^10.6.0",
|
|
1929
|
+
jiti: "^2.7.0",
|
|
1930
|
+
tinyexec: "^1.2.4",
|
|
1931
|
+
typescript: "^6.0.3",
|
|
1932
|
+
"typescript-eslint": "^8.62.1",
|
|
1933
|
+
vitest: "^4.1.9"
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
|
|
1937
|
+
// src/lib/branches.ts
|
|
1938
|
+
function parseDefaultBranch(originHead) {
|
|
1939
|
+
const trimmed = originHead.trim();
|
|
1940
|
+
if (!trimmed) return null;
|
|
1941
|
+
return trimmed.replace(/^origin\//, "");
|
|
1942
|
+
}
|
|
1943
|
+
function parseBranches(raw) {
|
|
1944
|
+
return raw.split("\n").map((branch) => branch.trim()).filter(Boolean);
|
|
1945
|
+
}
|
|
1946
|
+
function deletableBranches(all, protectedBranches) {
|
|
1947
|
+
const kept = new Set(protectedBranches.filter(Boolean));
|
|
1948
|
+
return all.filter((branch) => !kept.has(branch));
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
// src/lib/errors.ts
|
|
1952
|
+
function errorMessage(error) {
|
|
1953
|
+
return error instanceof Error ? error.message : String(error);
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
// src/lib/git.ts
|
|
1957
|
+
import { readdir } from "node:fs/promises";
|
|
1958
|
+
import { join } from "node:path";
|
|
1959
|
+
|
|
1960
|
+
// node_modules/tinyexec/dist/main.mjs
|
|
1961
|
+
import { spawn as e, spawnSync as t2 } from "node:child_process";
|
|
1962
|
+
import { cwd as n3 } from "node:process";
|
|
1963
|
+
import { basename as r2, delimiter as i2, dirname as a2, normalize as o, resolve as s } from "node:path";
|
|
1964
|
+
import { pipeline as c2 } from "node:stream/promises";
|
|
1965
|
+
import { PassThrough as l2 } from "node:stream";
|
|
1966
|
+
import u3 from "node:readline";
|
|
1967
|
+
import { closeSync as d, openSync as f, readSync as p, statSync as m2 } from "node:fs";
|
|
1968
|
+
var h2 = /^path$/i;
|
|
1969
|
+
var g = {
|
|
1970
|
+
key: "PATH",
|
|
1971
|
+
value: ""
|
|
1972
|
+
};
|
|
1973
|
+
function _(e2) {
|
|
1974
|
+
for (const t3 in e2) {
|
|
1975
|
+
if (!Object.prototype.hasOwnProperty.call(e2, t3) || !h2.test(t3)) continue;
|
|
1976
|
+
const n4 = e2[t3];
|
|
1977
|
+
if (!n4) return g;
|
|
1978
|
+
return {
|
|
1979
|
+
key: t3,
|
|
1980
|
+
value: n4
|
|
1981
|
+
};
|
|
1982
|
+
}
|
|
1983
|
+
return g;
|
|
1984
|
+
}
|
|
1985
|
+
function v(e2, t3) {
|
|
1986
|
+
const n4 = t3.value.split(i2);
|
|
1987
|
+
const r3 = [];
|
|
1988
|
+
let o2 = e2;
|
|
1989
|
+
let c3;
|
|
1990
|
+
do {
|
|
1991
|
+
r3.push(s(o2, "node_modules", ".bin"));
|
|
1992
|
+
c3 = o2;
|
|
1993
|
+
o2 = a2(o2);
|
|
1994
|
+
} while (o2 !== c3);
|
|
1995
|
+
r3.push(a2(process.execPath));
|
|
1996
|
+
const l3 = r3.concat(n4).join(i2);
|
|
1997
|
+
return {
|
|
1998
|
+
key: t3.key,
|
|
1999
|
+
value: l3
|
|
2000
|
+
};
|
|
2001
|
+
}
|
|
2002
|
+
function y(e2, t3, n4 = true) {
|
|
2003
|
+
const r3 = {
|
|
2004
|
+
...process.env,
|
|
2005
|
+
...t3
|
|
2006
|
+
};
|
|
2007
|
+
if (!n4) return r3;
|
|
2008
|
+
const i3 = v(e2, _(r3));
|
|
2009
|
+
r3[i3.key] = i3.value;
|
|
2010
|
+
return r3;
|
|
2011
|
+
}
|
|
2012
|
+
var b = (e2) => {
|
|
2013
|
+
let t3 = e2.length;
|
|
2014
|
+
const n4 = new l2();
|
|
2015
|
+
const r3 = () => {
|
|
2016
|
+
if (--t3 === 0) n4.end();
|
|
2017
|
+
};
|
|
2018
|
+
for (const t4 of e2) c2(t4, n4, { end: false }).then(r3).catch(r3);
|
|
2019
|
+
return n4;
|
|
2020
|
+
};
|
|
2021
|
+
var x = /([()\][%!^"`<>&|;, *?])/g;
|
|
2022
|
+
var S = /^#!\s*(.+)/;
|
|
2023
|
+
var C = /\.(?:com|exe)$/i;
|
|
2024
|
+
var w = /node_modules[\\/]\.bin[\\/][^\\/]+\.cmd$/i;
|
|
2025
|
+
var T = process.platform === "win32";
|
|
2026
|
+
var E = [
|
|
2027
|
+
".EXE",
|
|
2028
|
+
".CMD",
|
|
2029
|
+
".BAT",
|
|
2030
|
+
".COM"
|
|
2031
|
+
];
|
|
2032
|
+
function D(e2, t3 = [], n4 = {}) {
|
|
2033
|
+
if (n4.shell === true || !T) return {
|
|
2034
|
+
command: e2,
|
|
2035
|
+
args: t3,
|
|
2036
|
+
options: n4
|
|
2037
|
+
};
|
|
2038
|
+
let i3 = O(e2, n4);
|
|
2039
|
+
let a3 = null;
|
|
2040
|
+
if (i3 !== null) {
|
|
2041
|
+
const e3 = 150;
|
|
2042
|
+
const t4 = Buffer.alloc(e3);
|
|
2043
|
+
let n5 = null;
|
|
2044
|
+
try {
|
|
2045
|
+
n5 = f(i3, "r");
|
|
2046
|
+
p(n5, t4, 0, e3, 0);
|
|
2047
|
+
} catch {
|
|
2048
|
+
} finally {
|
|
2049
|
+
if (n5 !== null) d(n5);
|
|
2050
|
+
}
|
|
2051
|
+
const o2 = t4.toString().match(S);
|
|
2052
|
+
if (o2 !== null) {
|
|
2053
|
+
const e4 = o2[1].trim();
|
|
2054
|
+
const t5 = e4.indexOf(" ");
|
|
2055
|
+
const n6 = t5 !== -1 ? e4.slice(0, t5) : e4;
|
|
2056
|
+
const i4 = t5 !== -1 ? e4.slice(t5 + 1) : "";
|
|
2057
|
+
const s2 = r2(n6);
|
|
2058
|
+
a3 = s2 === "env" ? i4 || null : s2;
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
if (a3 !== null && i3 !== null) {
|
|
2062
|
+
t3 = [i3, ...t3];
|
|
2063
|
+
e2 = a3;
|
|
2064
|
+
i3 = O(e2, n4);
|
|
2065
|
+
}
|
|
2066
|
+
if (i3 === null || !C.test(i3)) {
|
|
2067
|
+
const r3 = i3 !== null && w.test(i3);
|
|
2068
|
+
e2 = o(e2);
|
|
2069
|
+
e2 = e2.replace(x, "^$1");
|
|
2070
|
+
t3 = t3.map((e3) => {
|
|
2071
|
+
e3 = e3.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"');
|
|
2072
|
+
e3 = e3.replace(/(?=(\\+?)?)\1$/, "$1$1");
|
|
2073
|
+
e3 = `"${e3}"`;
|
|
2074
|
+
e3 = e3.replace(x, "^$1");
|
|
2075
|
+
if (r3) e3 = e3.replace(x, "^$1");
|
|
2076
|
+
return e3;
|
|
2077
|
+
});
|
|
2078
|
+
t3 = [
|
|
2079
|
+
"/d",
|
|
2080
|
+
"/s",
|
|
2081
|
+
"/c",
|
|
2082
|
+
`"${[e2, ...t3].join(" ")}"`
|
|
2083
|
+
];
|
|
2084
|
+
e2 = n4.env?.comspec ?? "cmd.exe";
|
|
2085
|
+
n4 = {
|
|
2086
|
+
...n4,
|
|
2087
|
+
windowsVerbatimArguments: true
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
return {
|
|
2091
|
+
command: e2,
|
|
2092
|
+
args: t3,
|
|
2093
|
+
options: n4
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
function O(e2, t3) {
|
|
2097
|
+
const r3 = (t3.cwd ?? n3()).toString();
|
|
2098
|
+
const a3 = t3.env ?? process.env;
|
|
2099
|
+
const o2 = _(a3).value;
|
|
2100
|
+
const c3 = e2.includes("/") || e2.includes("\\") ? [""] : [r3, ...o2.split(i2)];
|
|
2101
|
+
const l3 = a3.PATHEXT ? a3.PATHEXT.split(i2) : E;
|
|
2102
|
+
if (e2.includes(".") && l3[0] !== "") l3.unshift("");
|
|
2103
|
+
for (const t4 of c3) {
|
|
2104
|
+
const n4 = s(r3, t4.startsWith('"') && t4.endsWith('"') && t4.length > 1 ? t4.slice(1, -1) : t4, e2);
|
|
2105
|
+
for (const e3 of l3) {
|
|
2106
|
+
const t5 = n4 + e3;
|
|
2107
|
+
try {
|
|
2108
|
+
if (m2(t5).isFile()) return t5;
|
|
2109
|
+
} catch {
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
return null;
|
|
2114
|
+
}
|
|
2115
|
+
var k = class extends Error {
|
|
2116
|
+
result;
|
|
2117
|
+
output;
|
|
2118
|
+
get exitCode() {
|
|
2119
|
+
if (this.result.exitCode !== null) return this.result.exitCode;
|
|
2120
|
+
}
|
|
2121
|
+
constructor(e2, t3) {
|
|
2122
|
+
super(`Process exited with non-zero status (${e2.exitCode})`);
|
|
2123
|
+
this.result = e2;
|
|
2124
|
+
this.output = t3;
|
|
2125
|
+
}
|
|
2126
|
+
};
|
|
2127
|
+
var j = {
|
|
2128
|
+
timeout: void 0,
|
|
2129
|
+
persist: false
|
|
2130
|
+
};
|
|
2131
|
+
var N = { windowsHide: true };
|
|
2132
|
+
function P(e2) {
|
|
2133
|
+
const t3 = new AbortController();
|
|
2134
|
+
for (const n4 of e2) {
|
|
2135
|
+
if (n4.aborted) {
|
|
2136
|
+
t3.abort();
|
|
2137
|
+
return n4;
|
|
2138
|
+
}
|
|
2139
|
+
const e3 = () => {
|
|
2140
|
+
t3.abort(n4.reason);
|
|
2141
|
+
};
|
|
2142
|
+
n4.addEventListener("abort", e3, { signal: t3.signal });
|
|
2143
|
+
}
|
|
2144
|
+
return t3.signal;
|
|
2145
|
+
}
|
|
2146
|
+
async function F(e2) {
|
|
2147
|
+
let t3 = "";
|
|
2148
|
+
try {
|
|
2149
|
+
for await (const n4 of e2) t3 += n4.toString();
|
|
2150
|
+
} catch {
|
|
2151
|
+
}
|
|
2152
|
+
return t3;
|
|
2153
|
+
}
|
|
2154
|
+
var I2 = class {
|
|
2155
|
+
_process;
|
|
2156
|
+
_aborted = false;
|
|
2157
|
+
_options;
|
|
2158
|
+
_command;
|
|
2159
|
+
_args;
|
|
2160
|
+
_resolveClose;
|
|
2161
|
+
_processClosed;
|
|
2162
|
+
_thrownError;
|
|
2163
|
+
get process() {
|
|
2164
|
+
return this._process;
|
|
2165
|
+
}
|
|
2166
|
+
get pid() {
|
|
2167
|
+
return this._process?.pid;
|
|
2168
|
+
}
|
|
2169
|
+
get exitCode() {
|
|
2170
|
+
if (this._process && this._process.exitCode !== null) return this._process.exitCode;
|
|
2171
|
+
}
|
|
2172
|
+
constructor(e2, t3, n4) {
|
|
2173
|
+
this._options = {
|
|
2174
|
+
...j,
|
|
2175
|
+
...n4
|
|
2176
|
+
};
|
|
2177
|
+
this._command = e2;
|
|
2178
|
+
this._args = t3 ?? [];
|
|
2179
|
+
this._processClosed = new Promise((e3) => {
|
|
2180
|
+
this._resolveClose = e3;
|
|
2181
|
+
});
|
|
2182
|
+
}
|
|
2183
|
+
kill(e2) {
|
|
2184
|
+
return this._process?.kill(e2) === true;
|
|
2185
|
+
}
|
|
2186
|
+
get aborted() {
|
|
2187
|
+
return this._aborted;
|
|
2188
|
+
}
|
|
2189
|
+
get killed() {
|
|
2190
|
+
return this._process?.killed === true;
|
|
2191
|
+
}
|
|
2192
|
+
pipe(e2, t3, n4) {
|
|
2193
|
+
return z(e2, t3, {
|
|
2194
|
+
...n4,
|
|
2195
|
+
stdin: this
|
|
2196
|
+
});
|
|
2197
|
+
}
|
|
2198
|
+
async *[Symbol.asyncIterator]() {
|
|
2199
|
+
const e2 = this._process;
|
|
2200
|
+
if (!e2) return;
|
|
2201
|
+
const t3 = [];
|
|
2202
|
+
if (this._streamErr) t3.push(this._streamErr);
|
|
2203
|
+
if (this._streamOut) t3.push(this._streamOut);
|
|
2204
|
+
const n4 = b(t3);
|
|
2205
|
+
const r3 = u3.createInterface({ input: n4 });
|
|
2206
|
+
for await (const e3 of r3) yield e3.toString();
|
|
2207
|
+
await this._processClosed;
|
|
2208
|
+
e2.removeAllListeners();
|
|
2209
|
+
if (this._thrownError) throw this._thrownError;
|
|
2210
|
+
if (this._options?.throwOnError && this.exitCode !== 0 && this.exitCode !== void 0) throw new k(this);
|
|
2211
|
+
}
|
|
2212
|
+
async _waitForOutput() {
|
|
2213
|
+
const e2 = this._process;
|
|
2214
|
+
if (!e2) throw new Error("No process was started");
|
|
2215
|
+
const [t3, n4] = await Promise.all([this._streamOut ? F(this._streamOut) : "", this._streamErr ? F(this._streamErr) : ""]);
|
|
2216
|
+
await this._processClosed;
|
|
2217
|
+
const { stdin: r3 } = this._options;
|
|
2218
|
+
if (r3 && typeof r3 !== "string") await r3;
|
|
2219
|
+
e2.removeAllListeners();
|
|
2220
|
+
if (this._thrownError) throw this._thrownError;
|
|
2221
|
+
const i3 = {
|
|
2222
|
+
stderr: n4,
|
|
2223
|
+
stdout: t3,
|
|
2224
|
+
exitCode: this.exitCode
|
|
2225
|
+
};
|
|
2226
|
+
if (this._options.throwOnError && this.exitCode !== 0 && this.exitCode !== void 0) throw new k(this, i3);
|
|
2227
|
+
return i3;
|
|
2228
|
+
}
|
|
2229
|
+
then(e2, t3) {
|
|
2230
|
+
return this._waitForOutput().then(e2, t3);
|
|
2231
|
+
}
|
|
2232
|
+
_streamOut;
|
|
2233
|
+
_streamErr;
|
|
2234
|
+
spawn() {
|
|
2235
|
+
const t3 = n3();
|
|
2236
|
+
const r3 = this._options;
|
|
2237
|
+
const i3 = {
|
|
2238
|
+
...N,
|
|
2239
|
+
...r3.nodeOptions
|
|
2240
|
+
};
|
|
2241
|
+
const a3 = [];
|
|
2242
|
+
this._resetState();
|
|
2243
|
+
if (r3.timeout !== void 0) a3.push(AbortSignal.timeout(r3.timeout));
|
|
2244
|
+
if (r3.signal !== void 0) a3.push(r3.signal);
|
|
2245
|
+
if (r3.persist === true) i3.detached = true;
|
|
2246
|
+
if (a3.length > 0) i3.signal = P(a3);
|
|
2247
|
+
i3.env = y(t3, i3.env, r3.nodePath);
|
|
2248
|
+
const o2 = D(this._command, this._args, i3);
|
|
2249
|
+
const s2 = e(o2.command, o2.args, o2.options);
|
|
2250
|
+
if (s2.stderr) this._streamErr = s2.stderr;
|
|
2251
|
+
if (s2.stdout) this._streamOut = s2.stdout;
|
|
2252
|
+
this._process = s2;
|
|
2253
|
+
s2.once("error", this._onError);
|
|
2254
|
+
s2.once("close", this._onClose);
|
|
2255
|
+
if (s2.stdin) {
|
|
2256
|
+
const { stdin: e2 } = r3;
|
|
2257
|
+
if (typeof e2 === "string") s2.stdin.end(e2);
|
|
2258
|
+
else e2?.process?.stdout?.pipe(s2.stdin);
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
_resetState() {
|
|
2262
|
+
this._aborted = false;
|
|
2263
|
+
this._processClosed = new Promise((e2) => {
|
|
2264
|
+
this._resolveClose = e2;
|
|
2265
|
+
});
|
|
2266
|
+
this._thrownError = void 0;
|
|
2267
|
+
}
|
|
2268
|
+
_onError = (e2) => {
|
|
2269
|
+
if (e2.name === "AbortError" && (!(e2.cause instanceof Error) || e2.cause.name !== "TimeoutError")) {
|
|
2270
|
+
this._aborted = true;
|
|
2271
|
+
return;
|
|
2272
|
+
}
|
|
2273
|
+
this._thrownError = e2;
|
|
2274
|
+
};
|
|
2275
|
+
_onClose = () => {
|
|
2276
|
+
if (this._resolveClose) this._resolveClose();
|
|
2277
|
+
};
|
|
2278
|
+
};
|
|
2279
|
+
var R2 = (e2, t3, n4) => {
|
|
2280
|
+
const r3 = new I2(e2, t3, n4);
|
|
2281
|
+
r3.spawn();
|
|
2282
|
+
return r3;
|
|
2283
|
+
};
|
|
2284
|
+
var z = R2;
|
|
2285
|
+
|
|
2286
|
+
// src/lib/git.ts
|
|
2287
|
+
var UPSTREAM_REF = "@{upstream}";
|
|
2288
|
+
var BRANCH_FORMAT = "%(refname:short)";
|
|
2289
|
+
async function git(args, cwd) {
|
|
2290
|
+
const result = await R2("git", args, { nodeOptions: { cwd } });
|
|
2291
|
+
if (result.exitCode !== 0) {
|
|
2292
|
+
throw new Error(result.stderr.trim() || `git ${args.join(" ")} failed`);
|
|
2293
|
+
}
|
|
2294
|
+
return result.stdout;
|
|
2295
|
+
}
|
|
2296
|
+
async function tryGit(args, cwd) {
|
|
2297
|
+
const result = await R2("git", args, { nodeOptions: { cwd } });
|
|
2298
|
+
return result.exitCode === 0 ? result.stdout : null;
|
|
2299
|
+
}
|
|
2300
|
+
async function stageAll() {
|
|
2301
|
+
await git(["add", "-A"]);
|
|
2302
|
+
}
|
|
2303
|
+
async function getStagedDiff() {
|
|
2304
|
+
return git(["diff", "--cached"]);
|
|
2305
|
+
}
|
|
2306
|
+
async function commit(message) {
|
|
2307
|
+
await git(["commit", "-m", message]);
|
|
2308
|
+
}
|
|
2309
|
+
async function currentBranch() {
|
|
2310
|
+
return (await git(["symbolic-ref", "--short", "HEAD"])).trim();
|
|
2311
|
+
}
|
|
2312
|
+
async function hasUpstream() {
|
|
2313
|
+
const result = await tryGit(["rev-parse", "--abbrev-ref", "--symbolic-full-name", UPSTREAM_REF]);
|
|
2314
|
+
return result !== null;
|
|
2315
|
+
}
|
|
2316
|
+
async function push() {
|
|
2317
|
+
await git(["push"]);
|
|
2318
|
+
}
|
|
2319
|
+
async function pushSetUpstream(branch) {
|
|
2320
|
+
await git(["push", "-u", "origin", branch]);
|
|
2321
|
+
}
|
|
2322
|
+
async function findGitRepos(start) {
|
|
2323
|
+
const repos = [];
|
|
2324
|
+
await collectRepos(start, repos);
|
|
2325
|
+
return repos.sort();
|
|
2326
|
+
}
|
|
2327
|
+
async function collectRepos(dir, repos) {
|
|
2328
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => null);
|
|
2329
|
+
if (!entries) return;
|
|
2330
|
+
if (entries.some((entry) => entry.name === ".git")) {
|
|
2331
|
+
repos.push(dir);
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
const subdirs = entries.filter(
|
|
2335
|
+
(entry) => entry.isDirectory() && entry.name !== "node_modules"
|
|
2336
|
+
);
|
|
2337
|
+
await Promise.all(subdirs.map((entry) => collectRepos(join(dir, entry.name), repos)));
|
|
2338
|
+
}
|
|
2339
|
+
async function fetchPrune(repo) {
|
|
2340
|
+
await git(["fetch", "--prune"], repo);
|
|
2341
|
+
}
|
|
2342
|
+
async function defaultBranch(repo) {
|
|
2343
|
+
const output = await tryGit(
|
|
2344
|
+
["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"],
|
|
2345
|
+
repo
|
|
2346
|
+
);
|
|
2347
|
+
return output === null ? null : parseDefaultBranch(output);
|
|
2348
|
+
}
|
|
2349
|
+
async function currentBranchAt(repo) {
|
|
2350
|
+
const output = await tryGit(["symbolic-ref", "--quiet", "--short", "HEAD"], repo);
|
|
2351
|
+
return output === null ? null : output.trim();
|
|
2352
|
+
}
|
|
2353
|
+
async function localBranches(repo) {
|
|
2354
|
+
return parseBranches(await git(["branch", `--format=${BRANCH_FORMAT}`], repo));
|
|
2355
|
+
}
|
|
2356
|
+
async function switchBranch(repo, branch) {
|
|
2357
|
+
await git(["switch", branch], repo);
|
|
2358
|
+
}
|
|
2359
|
+
async function deleteBranch(repo, branch) {
|
|
2360
|
+
await git(["branch", "-D", branch], repo);
|
|
2361
|
+
}
|
|
2362
|
+
async function pull(repo) {
|
|
2363
|
+
await git(["pull"], repo);
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
// src/commands/cleanup.ts
|
|
2367
|
+
var cleanupCommand = defineCommand({
|
|
2368
|
+
meta: {
|
|
2369
|
+
name: "cleanup",
|
|
2370
|
+
description: "Prune every git repo under a path, then delete stale local branches."
|
|
2371
|
+
},
|
|
2372
|
+
args: {
|
|
2373
|
+
path: {
|
|
2374
|
+
type: "positional",
|
|
2375
|
+
required: false,
|
|
2376
|
+
default: ".",
|
|
2377
|
+
description: "Directory to scan for git repos (recursively)."
|
|
2378
|
+
},
|
|
2379
|
+
stay: {
|
|
2380
|
+
type: "boolean",
|
|
2381
|
+
alias: "s",
|
|
2382
|
+
description: "Stay on the current branch instead of switching to the default."
|
|
2383
|
+
},
|
|
2384
|
+
pull: {
|
|
2385
|
+
type: "boolean",
|
|
2386
|
+
alias: "p",
|
|
2387
|
+
description: "Pull the checked-out branch after cleanup without asking."
|
|
2388
|
+
},
|
|
2389
|
+
yes: {
|
|
2390
|
+
type: "boolean",
|
|
2391
|
+
alias: "y",
|
|
2392
|
+
description: "Non-interactive: switch to default and delete every other local branch."
|
|
2393
|
+
}
|
|
2394
|
+
},
|
|
2395
|
+
async run({ args }) {
|
|
2396
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !args.yes;
|
|
2397
|
+
const options = { stay: Boolean(args.stay), pull: Boolean(args.pull) };
|
|
2398
|
+
const path = args.path || ".";
|
|
2399
|
+
if (interactive) intro("zapdev cleanup");
|
|
2400
|
+
const repos = await findGitRepos(path);
|
|
2401
|
+
if (repos.length === 0) {
|
|
2402
|
+
log.warn(`No git repository found under ${path}.`);
|
|
2403
|
+
if (interactive) outro("Nothing to do.");
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
for (const repo of repos) {
|
|
2407
|
+
const cancelled = await cleanupRepo(repo, options, interactive);
|
|
2408
|
+
if (cancelled) {
|
|
2409
|
+
cancel("Cancelled.");
|
|
2410
|
+
return;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
if (interactive) outro(`Done (${repos.length} repo${repos.length > 1 ? "s" : ""}).`);
|
|
2414
|
+
}
|
|
2415
|
+
});
|
|
2416
|
+
async function cleanupRepo(repo, options, interactive) {
|
|
2417
|
+
log.step(`Cleaning ${repo}`);
|
|
2418
|
+
const fetchLoader = interactive ? spinner() : void 0;
|
|
2419
|
+
fetchLoader?.start("Fetching + pruning\u2026");
|
|
2420
|
+
try {
|
|
2421
|
+
await fetchPrune(repo);
|
|
2422
|
+
fetchLoader?.stop("Fetched + pruned");
|
|
2423
|
+
} catch (error) {
|
|
2424
|
+
fetchLoader?.error("Fetch failed");
|
|
2425
|
+
log.warn(` Fetch failed, continuing: ${errorMessage(error)}`);
|
|
2426
|
+
}
|
|
2427
|
+
const [base, current] = await Promise.all([defaultBranch(repo), currentBranchAt(repo)]);
|
|
2428
|
+
if (!base) {
|
|
2429
|
+
log.warn(" Skipped: no origin/HEAD.");
|
|
2430
|
+
return false;
|
|
2431
|
+
}
|
|
2432
|
+
let endBranch = base;
|
|
2433
|
+
if (current && current !== base) {
|
|
2434
|
+
if (options.stay) {
|
|
2435
|
+
endBranch = current;
|
|
2436
|
+
} else if (interactive) {
|
|
2437
|
+
const choice = await select({
|
|
2438
|
+
message: "After cleanup, be on:",
|
|
2439
|
+
initialValue: base,
|
|
2440
|
+
options: [
|
|
2441
|
+
{ value: base, label: `Switch to ${base}` },
|
|
2442
|
+
{ value: current, label: `Stay on ${current} (keep it)` }
|
|
2443
|
+
]
|
|
2444
|
+
});
|
|
2445
|
+
if (isCancel(choice)) return true;
|
|
2446
|
+
endBranch = choice;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
if (current !== endBranch) {
|
|
2450
|
+
try {
|
|
2451
|
+
await switchBranch(repo, endBranch);
|
|
2452
|
+
} catch (error) {
|
|
2453
|
+
log.error(` Could not switch to ${endBranch}: ${errorMessage(error)}`);
|
|
2454
|
+
return false;
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
const candidates = deletableBranches(await localBranches(repo), [base, endBranch]);
|
|
2458
|
+
if (candidates.length === 0) {
|
|
2459
|
+
log.info(" No branch to delete.");
|
|
2460
|
+
} else {
|
|
2461
|
+
let toDelete = candidates;
|
|
2462
|
+
if (interactive) {
|
|
2463
|
+
const selected = await multiselect({
|
|
2464
|
+
message: "Branches to delete",
|
|
2465
|
+
options: candidates.map((branch) => ({ value: branch, label: branch })),
|
|
2466
|
+
required: false
|
|
2467
|
+
});
|
|
2468
|
+
if (isCancel(selected)) return true;
|
|
2469
|
+
toDelete = selected;
|
|
2470
|
+
}
|
|
2471
|
+
let deleted = 0;
|
|
2472
|
+
for (const branch of toDelete) {
|
|
2473
|
+
try {
|
|
2474
|
+
await deleteBranch(repo, branch);
|
|
2475
|
+
deleted += 1;
|
|
2476
|
+
} catch (error) {
|
|
2477
|
+
log.error(` Could not delete ${branch}: ${errorMessage(error)}`);
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
if (deleted > 0) log.success(` Deleted ${deleted} branch${deleted > 1 ? "es" : ""}.`);
|
|
2481
|
+
}
|
|
2482
|
+
let shouldPull = options.pull;
|
|
2483
|
+
if (!shouldPull && interactive) {
|
|
2484
|
+
const answer = await confirm({ message: `Pull ${endBranch}?`, initialValue: false });
|
|
2485
|
+
if (isCancel(answer)) return true;
|
|
2486
|
+
shouldPull = answer;
|
|
2487
|
+
}
|
|
2488
|
+
if (shouldPull) {
|
|
2489
|
+
const pullLoader = interactive ? spinner() : void 0;
|
|
2490
|
+
pullLoader?.start(`Pulling ${endBranch}\u2026`);
|
|
2491
|
+
try {
|
|
2492
|
+
await pull(repo);
|
|
2493
|
+
pullLoader?.stop(`\u2713 Pulled ${endBranch}`);
|
|
2494
|
+
} catch (error) {
|
|
2495
|
+
pullLoader?.error("Pull failed");
|
|
2496
|
+
log.error(` Pull failed: ${errorMessage(error)}`);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
return false;
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
// src/types/commit.ts
|
|
2503
|
+
var COMMIT_TYPES = [
|
|
2504
|
+
"feat",
|
|
2505
|
+
"fix",
|
|
2506
|
+
"chore",
|
|
2507
|
+
"docs",
|
|
2508
|
+
"style",
|
|
2509
|
+
"refactor",
|
|
2510
|
+
"perf",
|
|
2511
|
+
"test",
|
|
2512
|
+
"build",
|
|
2513
|
+
"ci",
|
|
2514
|
+
"revert"
|
|
2515
|
+
];
|
|
2516
|
+
|
|
2517
|
+
// src/lib/commit-message.ts
|
|
2518
|
+
function normalizeCommitType(input) {
|
|
2519
|
+
const normalized = input.trim().toLowerCase();
|
|
2520
|
+
return COMMIT_TYPES.includes(normalized) ? normalized : null;
|
|
2521
|
+
}
|
|
2522
|
+
function applyCommitType(systemPrompt, type) {
|
|
2523
|
+
return `${systemPrompt}
|
|
2524
|
+
|
|
2525
|
+
The type MUST be exactly "${type}".`;
|
|
2526
|
+
}
|
|
2527
|
+
var MAX_DIFF_CHARS = 12e3;
|
|
2528
|
+
function truncateDiff(diff, max = MAX_DIFF_CHARS) {
|
|
2529
|
+
return diff.length > max ? diff.slice(0, max) : diff;
|
|
2530
|
+
}
|
|
2531
|
+
function sanitizeCommitMessage(raw) {
|
|
2532
|
+
const firstLine = raw.split("\n", 1)[0] ?? "";
|
|
2533
|
+
return firstLine.replace(/[`"]/g, "").trim();
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// src/lib/config.ts
|
|
2537
|
+
var DEFAULT_OLLAMA_URL = "http://localhost:11434";
|
|
2538
|
+
var DEFAULT_MODEL = "deepseek-v4-flash:cloud";
|
|
2539
|
+
function resolveConfig(env = process.env, overrides = {}) {
|
|
2540
|
+
return {
|
|
2541
|
+
ollamaUrl: normalizeBaseUrl(overrides.ollamaUrl ?? env.OLLAMA_URL ?? DEFAULT_OLLAMA_URL),
|
|
2542
|
+
model: overrides.model ?? env.OLLAMA_MODEL ?? DEFAULT_MODEL
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
function normalizeBaseUrl(raw) {
|
|
2546
|
+
const trimmed = raw.trim().replace(/\/+$/, "");
|
|
2547
|
+
return /^https?:\/\//.test(trimmed) ? trimmed : `http://${trimmed}`;
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
// src/prompts/commit-message.md
|
|
2551
|
+
var commit_message_default = "You are zapdev, a CLI tool that creates commits quickly and reliably.\n\nGenerate ONE commit message in Conventional Commits format.\nA single line: imperative, English, \u226472 chars.\n\nStrictly follow this format:\n\n```text\ntype(scope): description\n```\n\nReply ONLY with the message, no backticks, no quotes, no explanation.\n";
|
|
2552
|
+
|
|
2553
|
+
// src/prompts/index.ts
|
|
2554
|
+
var COMMIT_SYSTEM_PROMPT = commit_message_default.trim();
|
|
2555
|
+
|
|
2556
|
+
// src/lib/ollama.ts
|
|
2557
|
+
var REQUEST_TIMEOUT_MS = 25e3;
|
|
2558
|
+
var KEEP_ALIVE = "30m";
|
|
2559
|
+
async function generateCommitMessage(diff, config, type) {
|
|
2560
|
+
const systemPrompt = type ? applyCommitType(COMMIT_SYSTEM_PROMPT, type) : COMMIT_SYSTEM_PROMPT;
|
|
2561
|
+
const content = await chat(config, [
|
|
2562
|
+
{ role: "system", content: systemPrompt },
|
|
2563
|
+
{ role: "user", content: truncateDiff(diff) }
|
|
2564
|
+
]);
|
|
2565
|
+
return sanitizeCommitMessage(content);
|
|
2566
|
+
}
|
|
2567
|
+
async function chat(config, messages) {
|
|
2568
|
+
const url = `${config.ollamaUrl}/api/chat`;
|
|
2569
|
+
let response;
|
|
2570
|
+
try {
|
|
2571
|
+
response = await fetch(url, {
|
|
2572
|
+
method: "POST",
|
|
2573
|
+
headers: { "content-type": "application/json" },
|
|
2574
|
+
body: JSON.stringify({
|
|
2575
|
+
model: config.model,
|
|
2576
|
+
stream: false,
|
|
2577
|
+
keep_alive: KEEP_ALIVE,
|
|
2578
|
+
options: { temperature: 0.2 },
|
|
2579
|
+
messages
|
|
2580
|
+
}),
|
|
2581
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
2582
|
+
});
|
|
2583
|
+
} catch (error) {
|
|
2584
|
+
throw new Error(describeRequestError(error, url), { cause: error });
|
|
2585
|
+
}
|
|
2586
|
+
const body = await response.json().catch(() => null);
|
|
2587
|
+
if (!response.ok) {
|
|
2588
|
+
throw new Error(`Ollama error: ${serverError(body) ?? `HTTP ${response.status}`}`);
|
|
2589
|
+
}
|
|
2590
|
+
const content = messageContent(body);
|
|
2591
|
+
if (content === null) throw new Error("Ollama returned an unexpected response shape.");
|
|
2592
|
+
return content;
|
|
2593
|
+
}
|
|
2594
|
+
function describeRequestError(error, url) {
|
|
2595
|
+
if (errorName(error) === "TimeoutError") {
|
|
2596
|
+
return `Ollama did not answer within ${REQUEST_TIMEOUT_MS / 1e3}s (${url}).`;
|
|
2597
|
+
}
|
|
2598
|
+
return `Could not reach Ollama at ${url}. Is it running?`;
|
|
2599
|
+
}
|
|
2600
|
+
function errorName(error) {
|
|
2601
|
+
if (error && typeof error === "object" && "name" in error && typeof error.name === "string") {
|
|
2602
|
+
return error.name;
|
|
2603
|
+
}
|
|
2604
|
+
return null;
|
|
2605
|
+
}
|
|
2606
|
+
function serverError(body) {
|
|
2607
|
+
if (body && typeof body === "object" && "error" in body && typeof body.error === "string") {
|
|
2608
|
+
return body.error;
|
|
2609
|
+
}
|
|
2610
|
+
return null;
|
|
2611
|
+
}
|
|
2612
|
+
function messageContent(body) {
|
|
2613
|
+
if (!body || typeof body !== "object" || !("message" in body)) return null;
|
|
2614
|
+
const message = body.message;
|
|
2615
|
+
if (!message || typeof message !== "object" || !("content" in message)) return null;
|
|
2616
|
+
return typeof message.content === "string" ? message.content : null;
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2619
|
+
// src/commands/commit.ts
|
|
2620
|
+
var commitCommand = defineCommand({
|
|
2621
|
+
meta: {
|
|
2622
|
+
name: "commit",
|
|
2623
|
+
description: "Stage all changes and commit with an LLM-generated Conventional Commits message."
|
|
2624
|
+
},
|
|
2625
|
+
args: {
|
|
2626
|
+
model: {
|
|
2627
|
+
type: "string",
|
|
2628
|
+
alias: "m",
|
|
2629
|
+
description: "Override the Ollama model (defaults to $OLLAMA_MODEL)."
|
|
2630
|
+
},
|
|
2631
|
+
type: {
|
|
2632
|
+
type: "string",
|
|
2633
|
+
alias: "t",
|
|
2634
|
+
description: `Force the Conventional Commits type (${COMMIT_TYPES.join(", ")}).`
|
|
2635
|
+
},
|
|
2636
|
+
push: {
|
|
2637
|
+
type: "boolean",
|
|
2638
|
+
alias: "p",
|
|
2639
|
+
description: "Push after committing without asking."
|
|
2640
|
+
},
|
|
2641
|
+
yes: {
|
|
2642
|
+
type: "boolean",
|
|
2643
|
+
alias: "y",
|
|
2644
|
+
description: "Skip prompts and commit directly."
|
|
2645
|
+
}
|
|
2646
|
+
},
|
|
2647
|
+
async run({ args }) {
|
|
2648
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2649
|
+
const config = resolveConfig(
|
|
2650
|
+
process.env,
|
|
2651
|
+
args.model ? { model: args.model } : {}
|
|
2652
|
+
);
|
|
2653
|
+
const type = args.type ? normalizeCommitType(args.type) : void 0;
|
|
2654
|
+
if (type === null) {
|
|
2655
|
+
log.error(
|
|
2656
|
+
`Invalid type "${args.type}". Valid types: ${COMMIT_TYPES.join(", ")}.`
|
|
2657
|
+
);
|
|
2658
|
+
process.exitCode = 1;
|
|
2659
|
+
return;
|
|
2660
|
+
}
|
|
2661
|
+
if (interactive) intro("zapdev commit");
|
|
2662
|
+
await stageAll();
|
|
2663
|
+
const diff = await getStagedDiff();
|
|
2664
|
+
if (!diff.trim()) {
|
|
2665
|
+
log.warn("Nothing to commit.");
|
|
2666
|
+
if (interactive) outro("Nothing to do.");
|
|
2667
|
+
return;
|
|
2668
|
+
}
|
|
2669
|
+
const loader = interactive ? spinner() : void 0;
|
|
2670
|
+
loader?.start("Generating commit message");
|
|
2671
|
+
let message;
|
|
2672
|
+
try {
|
|
2673
|
+
message = await generateCommitMessage(diff, config, type);
|
|
2674
|
+
} catch (error) {
|
|
2675
|
+
loader?.error("Generation failed");
|
|
2676
|
+
log.error(`Generation failed: ${errorMessage(error)}`);
|
|
2677
|
+
process.exitCode = 1;
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
if (!message) {
|
|
2681
|
+
loader?.error("Generation failed");
|
|
2682
|
+
log.error("Generation failed: the model returned an empty message.");
|
|
2683
|
+
process.exitCode = 1;
|
|
2684
|
+
return;
|
|
2685
|
+
}
|
|
2686
|
+
if (loader) loader.stop(message);
|
|
2687
|
+
else log.message(message);
|
|
2688
|
+
let finalMessage = message;
|
|
2689
|
+
if (interactive && !args.yes) {
|
|
2690
|
+
const action = await select({
|
|
2691
|
+
message: "Action",
|
|
2692
|
+
initialValue: "commit",
|
|
2693
|
+
options: [
|
|
2694
|
+
{ value: "commit", label: "Commit" },
|
|
2695
|
+
{ value: "edit", label: "Edit message" },
|
|
2696
|
+
{ value: "cancel", label: "Cancel" }
|
|
2697
|
+
]
|
|
2698
|
+
});
|
|
2699
|
+
if (isCancel(action) || action === "cancel") {
|
|
2700
|
+
cancel("Cancelled (changes left staged).");
|
|
2701
|
+
return;
|
|
2702
|
+
}
|
|
2703
|
+
if (action === "edit") {
|
|
2704
|
+
const edited = await text({
|
|
2705
|
+
message: "Edit message",
|
|
2706
|
+
initialValue: message
|
|
2707
|
+
});
|
|
2708
|
+
if (isCancel(edited)) {
|
|
2709
|
+
cancel("Cancelled (changes left staged).");
|
|
2710
|
+
return;
|
|
2711
|
+
}
|
|
2712
|
+
finalMessage = edited.trim();
|
|
2713
|
+
if (!finalMessage) {
|
|
2714
|
+
cancel("Empty message, cancelled.");
|
|
2715
|
+
return;
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
await commit(finalMessage);
|
|
2720
|
+
if (interactive) log.success(`Committed: ${finalMessage}`);
|
|
2721
|
+
let shouldPush = Boolean(args.push);
|
|
2722
|
+
if (!shouldPush && interactive && !args.yes) {
|
|
2723
|
+
const answer = await confirm({ message: "Push?", initialValue: false });
|
|
2724
|
+
if (isCancel(answer)) {
|
|
2725
|
+
if (interactive) outro("Committed. Not pushed.");
|
|
2726
|
+
return;
|
|
2727
|
+
}
|
|
2728
|
+
shouldPush = answer;
|
|
2729
|
+
}
|
|
2730
|
+
if (shouldPush) {
|
|
2731
|
+
const pushLoader = interactive ? spinner() : void 0;
|
|
2732
|
+
pushLoader?.start("Pushing");
|
|
2733
|
+
try {
|
|
2734
|
+
const [upstream, branch] = await Promise.all([hasUpstream(), currentBranch()]);
|
|
2735
|
+
if (upstream) await push();
|
|
2736
|
+
else await pushSetUpstream(branch);
|
|
2737
|
+
pushLoader?.stop("\u2713 Pushed");
|
|
2738
|
+
} catch (error) {
|
|
2739
|
+
pushLoader?.error("Push failed");
|
|
2740
|
+
log.error(`Push failed: ${errorMessage(error)}`);
|
|
2741
|
+
process.exitCode = 1;
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
if (interactive) outro("Done.");
|
|
2746
|
+
}
|
|
2747
|
+
});
|
|
2748
|
+
|
|
2749
|
+
// src/cli.ts
|
|
2750
|
+
var commands = {
|
|
2751
|
+
commit: commitCommand,
|
|
2752
|
+
cleanup: cleanupCommand
|
|
2753
|
+
};
|
|
2754
|
+
var MENU = {
|
|
2755
|
+
commit: "Stage all changes and commit with an AI-generated message",
|
|
2756
|
+
cleanup: "Prune repos and delete stale local branches"
|
|
2757
|
+
};
|
|
2758
|
+
var menuOptions = Object.keys(MENU).map((value) => ({
|
|
2759
|
+
value,
|
|
2760
|
+
label: value,
|
|
2761
|
+
hint: MENU[value]
|
|
2762
|
+
}));
|
|
2763
|
+
var main = defineCommand({
|
|
2764
|
+
meta: {
|
|
2765
|
+
name: "zapdev",
|
|
2766
|
+
version: package_default.version,
|
|
2767
|
+
description: "Fast, precise git chores from your terminal."
|
|
2768
|
+
},
|
|
2769
|
+
subCommands: commands,
|
|
2770
|
+
// citty runs this after a matched subcommand too, so bail out when one already ran.
|
|
2771
|
+
async run({ args, cmd }) {
|
|
2772
|
+
const selected = args._[0];
|
|
2773
|
+
if (selected && selected in commands) return;
|
|
2774
|
+
if (!(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
2775
|
+
await showUsage(cmd);
|
|
2776
|
+
return;
|
|
2777
|
+
}
|
|
2778
|
+
const choice = await select({ message: "Which command?", options: menuOptions });
|
|
2779
|
+
if (isCancel(choice)) {
|
|
2780
|
+
cancel("Cancelled.");
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
await runCommand(commands[choice], { rawArgs: [] });
|
|
2784
|
+
}
|
|
2785
|
+
});
|
|
2786
|
+
await runMain(main);
|