zapdev 1.11.0 → 1.13.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 +21 -71
- package/dist/cli.js +1288 -1276
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -84,1079 +84,565 @@ var require_src = __commonJS({
|
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
// node_modules/
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const parts = [];
|
|
102
|
-
if (!str || typeof str !== "string") return parts;
|
|
103
|
-
let buff = "";
|
|
104
|
-
let previousUpper;
|
|
105
|
-
let previousSplitter;
|
|
106
|
-
for (const char of str) {
|
|
107
|
-
const isSplitter = splitters.includes(char);
|
|
108
|
-
if (isSplitter === true) {
|
|
109
|
-
parts.push(buff);
|
|
110
|
-
buff = "";
|
|
111
|
-
previousUpper = void 0;
|
|
112
|
-
continue;
|
|
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;
|
|
113
101
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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;
|
|
121
173
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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;
|
|
128
197
|
}
|
|
129
198
|
}
|
|
130
|
-
|
|
131
|
-
previousUpper = isUpper;
|
|
132
|
-
previousSplitter = isSplitter;
|
|
199
|
+
index += 1;
|
|
133
200
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
function pascalCase(str, opts) {
|
|
144
|
-
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => upperFirst(opts?.normalize ? p2.toLowerCase() : p2)).join("") : "";
|
|
145
|
-
}
|
|
146
|
-
function camelCase(str, opts) {
|
|
147
|
-
return lowerFirst(pascalCase(str || "", opts));
|
|
148
|
-
}
|
|
149
|
-
function kebabCase(str, joiner) {
|
|
150
|
-
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => p2.toLowerCase()).join(joiner ?? "-") : "";
|
|
151
|
-
}
|
|
152
|
-
function snakeCase(str) {
|
|
153
|
-
return kebabCase(str || "", "_");
|
|
154
|
-
}
|
|
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;
|
|
155
209
|
|
|
156
|
-
// node_modules/
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
function formatLineColumns(lines, linePrefix = "") {
|
|
163
|
-
const maxLength = [];
|
|
164
|
-
for (const line of lines) for (const [i3, element] of line.entries()) maxLength[i3] = Math.max(maxLength[i3] || 0, element.length);
|
|
165
|
-
return lines.map((l3) => l3.map((c3, i3) => linePrefix + c3[i3 === 0 ? "padStart" : "padEnd"](maxLength[i3])).join(" ")).join("\n");
|
|
166
|
-
}
|
|
167
|
-
function resolveValue(input) {
|
|
168
|
-
return typeof input === "function" ? input() : input;
|
|
169
|
-
}
|
|
170
|
-
var CLIError = class extends Error {
|
|
171
|
-
code;
|
|
172
|
-
constructor(message, code) {
|
|
173
|
-
super(message);
|
|
174
|
-
this.name = "CLIError";
|
|
175
|
-
this.code = code;
|
|
176
|
-
}
|
|
210
|
+
// node_modules/fast-string-width/dist/index.js
|
|
211
|
+
var NO_TRUNCATION2 = {
|
|
212
|
+
limit: Infinity,
|
|
213
|
+
ellipsis: "",
|
|
214
|
+
ellipsisWidth: 0
|
|
177
215
|
};
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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;
|
|
228
275
|
}
|
|
229
|
-
if (
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
continue;
|
|
276
|
+
if (character === ESC || character === CSI) {
|
|
277
|
+
isInsideEscape = true;
|
|
278
|
+
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
233
279
|
}
|
|
234
|
-
|
|
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;
|
|
235
299
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
args: processedArgs,
|
|
240
|
-
options: Object.keys(options).length > 0 ? options : void 0,
|
|
241
|
-
allowPositionals: true,
|
|
242
|
-
strict: false
|
|
243
|
-
});
|
|
244
|
-
} catch {
|
|
245
|
-
parsed = {
|
|
246
|
-
values: {},
|
|
247
|
-
positionals: processedArgs
|
|
248
|
-
};
|
|
300
|
+
lastRow = rows.at(-1);
|
|
301
|
+
if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
|
|
302
|
+
rows[rows.length - 2] += rows.pop();
|
|
249
303
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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--;
|
|
257
313
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const mainName = aliasToMain.get(name);
|
|
261
|
-
if (mainName) out[mainName] = false;
|
|
262
|
-
const aliases = mainToAliases.get(name);
|
|
263
|
-
if (aliases) for (const alias of aliases) out[alias] = false;
|
|
314
|
+
if (last === words.length) {
|
|
315
|
+
return string;
|
|
264
316
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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 "";
|
|
269
322
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
alias: {},
|
|
286
|
-
default: {}
|
|
287
|
-
};
|
|
288
|
-
const args = resolveArgs(argsDef);
|
|
289
|
-
for (const arg of args) {
|
|
290
|
-
if (arg.type === "positional") continue;
|
|
291
|
-
if (arg.type === "string" || arg.type === "enum") parseOptions.string.push(arg.name);
|
|
292
|
-
else if (arg.type === "boolean") parseOptions.boolean.push(arg.name);
|
|
293
|
-
if (arg.default !== void 0) parseOptions.default[arg.name] = arg.default;
|
|
294
|
-
if (arg.alias) parseOptions.alias[arg.name] = arg.alias;
|
|
295
|
-
const camelName = camelCase(arg.name);
|
|
296
|
-
const kebabName = kebabCase(arg.name);
|
|
297
|
-
if (camelName !== arg.name || kebabName !== arg.name) {
|
|
298
|
-
const existingAliases = toArray(parseOptions.alias[arg.name] || []);
|
|
299
|
-
if (camelName !== arg.name && !existingAliases.includes(camelName)) existingAliases.push(camelName);
|
|
300
|
-
if (kebabName !== arg.name && !existingAliases.includes(kebabName)) existingAliases.push(kebabName);
|
|
301
|
-
if (existingAliases.length > 0) parseOptions.alias[arg.name] = existingAliases;
|
|
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
|
+
}
|
|
302
338
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (nextPositionalArgument !== void 0) parsedArgsProxy[arg.name] = nextPositionalArgument;
|
|
312
|
-
else if (arg.default === void 0 && arg.required !== false) throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`, "EARG");
|
|
313
|
-
else parsedArgsProxy[arg.name] = arg.default;
|
|
314
|
-
} else if (arg.type === "enum") {
|
|
315
|
-
const argument = parsedArgsProxy[arg.name];
|
|
316
|
-
const options = arg.options || [];
|
|
317
|
-
if (argument !== void 0 && options.length > 0 && !options.includes(argument)) throw new CLIError(`Invalid value for argument: ${cyan(`--${arg.name}`)} (${cyan(argument)}). Expected one of: ${options.map((o2) => cyan(o2)).join(", ")}.`, "EARG");
|
|
318
|
-
} else if (arg.required && parsedArgsProxy[arg.name] === void 0) throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
|
|
319
|
-
return parsedArgsProxy;
|
|
320
|
-
}
|
|
321
|
-
function resolveArgs(argsDef) {
|
|
322
|
-
const args = [];
|
|
323
|
-
for (const [name, argDef] of Object.entries(argsDef || {})) args.push({
|
|
324
|
-
...argDef,
|
|
325
|
-
name,
|
|
326
|
-
alias: toArray(argDef.alias)
|
|
327
|
-
});
|
|
328
|
-
return args;
|
|
329
|
-
}
|
|
330
|
-
async function resolvePlugins(plugins) {
|
|
331
|
-
return Promise.all(plugins.map((p2) => resolveValue(p2)));
|
|
332
|
-
}
|
|
333
|
-
function defineCommand(def) {
|
|
334
|
-
return def;
|
|
335
|
-
}
|
|
336
|
-
async function runCommand(cmd, opts) {
|
|
337
|
-
const cmdArgs = await resolveValue(cmd.args || {});
|
|
338
|
-
const parsedArgs = parseArgs(opts.rawArgs, cmdArgs);
|
|
339
|
-
const context = {
|
|
340
|
-
rawArgs: opts.rawArgs,
|
|
341
|
-
args: parsedArgs,
|
|
342
|
-
data: opts.data,
|
|
343
|
-
cmd
|
|
344
|
-
};
|
|
345
|
-
const plugins = await resolvePlugins(cmd.plugins ?? []);
|
|
346
|
-
let result;
|
|
347
|
-
let runError;
|
|
348
|
-
try {
|
|
349
|
-
for (const plugin of plugins) await plugin.setup?.(context);
|
|
350
|
-
if (typeof cmd.setup === "function") await cmd.setup(context);
|
|
351
|
-
const subCommands = await resolveValue(cmd.subCommands);
|
|
352
|
-
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
353
|
-
const subCommandArgIndex = findSubCommandIndex(opts.rawArgs, cmdArgs);
|
|
354
|
-
const explicitName = opts.rawArgs[subCommandArgIndex];
|
|
355
|
-
if (explicitName) {
|
|
356
|
-
const subCommand = await _findSubCommand(subCommands, explicitName);
|
|
357
|
-
if (!subCommand) throw new CLIError(`Unknown command ${cyan(explicitName)}`, "E_UNKNOWN_COMMAND");
|
|
358
|
-
await runCommand(subCommand, { rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1) });
|
|
359
|
-
} else {
|
|
360
|
-
const defaultSubCommand = await resolveValue(cmd.default);
|
|
361
|
-
if (defaultSubCommand) {
|
|
362
|
-
if (cmd.run) throw new CLIError(`Cannot specify both 'run' and 'default' on the same command.`, "E_DEFAULT_CONFLICT");
|
|
363
|
-
const subCommand = await _findSubCommand(subCommands, defaultSubCommand);
|
|
364
|
-
if (!subCommand) throw new CLIError(`Default sub command ${cyan(defaultSubCommand)} not found in subCommands.`, "E_UNKNOWN_COMMAND");
|
|
365
|
-
await runCommand(subCommand, { rawArgs: opts.rawArgs });
|
|
366
|
-
} else if (!cmd.run) throw new CLIError(`No command specified.`, "E_NO_COMMAND");
|
|
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++;
|
|
367
347
|
}
|
|
368
348
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
await plugin.cleanup?.(context);
|
|
381
|
-
} catch (error) {
|
|
382
|
-
cleanupErrors.push(error);
|
|
383
|
-
}
|
|
384
|
-
if (runError) throw runError;
|
|
385
|
-
if (cleanupErrors.length === 1) throw cleanupErrors[0];
|
|
386
|
-
if (cleanupErrors.length > 1) throw new Error("Multiple cleanup errors", { cause: cleanupErrors });
|
|
387
|
-
return { result };
|
|
388
|
-
}
|
|
389
|
-
async function resolveSubCommand(cmd, rawArgs, parent) {
|
|
390
|
-
const subCommands = await resolveValue(cmd.subCommands);
|
|
391
|
-
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
392
|
-
const subCommandArgIndex = findSubCommandIndex(rawArgs, await resolveValue(cmd.args || {}));
|
|
393
|
-
const subCommandName = rawArgs[subCommandArgIndex];
|
|
394
|
-
const subCommand = await _findSubCommand(subCommands, subCommandName);
|
|
395
|
-
if (subCommand) return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);
|
|
396
|
-
}
|
|
397
|
-
return [cmd, parent];
|
|
398
|
-
}
|
|
399
|
-
async function _findSubCommand(subCommands, name) {
|
|
400
|
-
if (name in subCommands) return resolveValue(subCommands[name]);
|
|
401
|
-
for (const sub of Object.values(subCommands)) {
|
|
402
|
-
const resolved = await resolveValue(sub);
|
|
403
|
-
const meta = await resolveValue(resolved?.meta);
|
|
404
|
-
if (meta?.alias) {
|
|
405
|
-
if (toArray(meta.alias).includes(name)) return resolved;
|
|
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;
|
|
406
360
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
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) ?? "");
|
|
415
373
|
continue;
|
|
416
374
|
}
|
|
417
|
-
|
|
375
|
+
rows[rows.length - 1] += word;
|
|
376
|
+
rowLength += wordLength;
|
|
418
377
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
function _isValueFlag(flag, argsDef) {
|
|
422
|
-
const name = flag.replace(/^-{1,2}/, "");
|
|
423
|
-
const normalized = camelCase(name);
|
|
424
|
-
for (const [key, def] of Object.entries(argsDef)) {
|
|
425
|
-
if (def.type !== "string" && def.type !== "enum") continue;
|
|
426
|
-
if (normalized === camelCase(key)) return true;
|
|
427
|
-
if ((Array.isArray(def.alias) ? def.alias : def.alias ? [def.alias] : []).includes(name)) return true;
|
|
378
|
+
if (options.trim !== false) {
|
|
379
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
428
380
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
+
}
|
|
436
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");
|
|
437
427
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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)}`
|
|
460
478
|
}
|
|
461
|
-
if (isRequired) usageLine.push(`--${arg.name}` + renderValueHint(arg));
|
|
462
479
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
if (
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
commandsLines.push([cyan(label), meta?.description || ""]);
|
|
472
|
-
commandNames.push(name, ...aliases);
|
|
480
|
+
};
|
|
481
|
+
function updateSettings(n4) {
|
|
482
|
+
if (n4.aliases !== void 0) {
|
|
483
|
+
const e2 = n4.aliases;
|
|
484
|
+
for (const s2 in e2) {
|
|
485
|
+
if (!Object.hasOwn(e2, s2)) continue;
|
|
486
|
+
const i3 = e2[s2];
|
|
487
|
+
i3 === void 0 || !settings.actions.has(i3) || settings.aliases.has(s2) || settings.aliases.set(s2, i3);
|
|
473
488
|
}
|
|
474
|
-
usageLine.push(commandNames.join("|"));
|
|
475
|
-
}
|
|
476
|
-
const usageLines = [];
|
|
477
|
-
const version = cmdMeta.version || parentMeta.version;
|
|
478
|
-
usageLines.push(gray(`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`), "");
|
|
479
|
-
const hasOptions = argLines.length > 0 || posLines.length > 0;
|
|
480
|
-
usageLines.push(`${underline(bold("USAGE"))} ${cyan(`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}`)}`, "");
|
|
481
|
-
if (posLines.length > 0) {
|
|
482
|
-
usageLines.push(underline(bold("ARGUMENTS")), "");
|
|
483
|
-
usageLines.push(formatLineColumns(posLines, " "));
|
|
484
|
-
usageLines.push("");
|
|
485
489
|
}
|
|
486
|
-
if (
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
usageLines.push("");
|
|
490
|
+
if (n4.messages !== void 0) {
|
|
491
|
+
const e2 = n4.messages;
|
|
492
|
+
e2.cancel !== void 0 && (settings.messages.cancel = e2.cancel), e2.error !== void 0 && (settings.messages.error = e2.error);
|
|
490
493
|
}
|
|
491
|
-
if (
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
usageLines.push("", `Use ${cyan(`${commandName} <command> --help`)} for more information about a command.`);
|
|
494
|
+
if (n4.withGuide !== void 0 && (settings.withGuide = n4.withGuide !== false), n4.date !== void 0) {
|
|
495
|
+
const e2 = n4.date;
|
|
496
|
+
e2.monthNames !== void 0 && (settings.date.monthNames = [...e2.monthNames]), e2.messages !== void 0 && (e2.messages.required !== void 0 && (settings.date.messages.required = e2.messages.required), e2.messages.invalidMonth !== void 0 && (settings.date.messages.invalidMonth = e2.messages.invalidMonth), e2.messages.invalidDay !== void 0 && (settings.date.messages.invalidDay = e2.messages.invalidDay), e2.messages.afterMin !== void 0 && (settings.date.messages.afterMin = e2.messages.afterMin), e2.messages.beforeMax !== void 0 && (settings.date.messages.beforeMax = e2.messages.beforeMax));
|
|
495
497
|
}
|
|
496
|
-
return usageLines.filter((l3) => typeof l3 === "string").join("\n");
|
|
497
498
|
}
|
|
498
|
-
function
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
499
|
+
function isActionKey(n4, e2) {
|
|
500
|
+
if (typeof n4 == "string")
|
|
501
|
+
return settings.aliases.get(n4) === e2;
|
|
502
|
+
for (const s2 of n4)
|
|
503
|
+
if (s2 !== void 0 && isActionKey(s2, e2))
|
|
504
|
+
return true;
|
|
505
|
+
return false;
|
|
504
506
|
}
|
|
505
|
-
function
|
|
506
|
-
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
].filter(Boolean).join(" ");
|
|
513
|
-
}
|
|
514
|
-
async function runMain(cmd, opts = {}) {
|
|
515
|
-
const rawArgs = opts.rawArgs || process.argv.slice(2);
|
|
516
|
-
const showUsage$1 = opts.showUsage || showUsage;
|
|
517
|
-
try {
|
|
518
|
-
const builtinFlags = await _resolveBuiltinFlags(cmd);
|
|
519
|
-
if (builtinFlags.help.length > 0 && rawArgs.some((arg) => builtinFlags.help.includes(arg))) {
|
|
520
|
-
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
521
|
-
process.exit(0);
|
|
522
|
-
} else if (rawArgs.length === 1 && builtinFlags.version.includes(rawArgs[0])) {
|
|
523
|
-
const meta = typeof cmd.meta === "function" ? await cmd.meta() : await cmd.meta;
|
|
524
|
-
if (!meta?.version) throw new CLIError("No version specified", "E_NO_VERSION");
|
|
525
|
-
console.log(meta.version);
|
|
526
|
-
} else await runCommand(cmd, { rawArgs });
|
|
527
|
-
} catch (error) {
|
|
528
|
-
if (error instanceof CLIError) {
|
|
529
|
-
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
530
|
-
console.error(error.message);
|
|
531
|
-
} else console.error(error, "\n");
|
|
532
|
-
process.exit(1);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
async function _resolveBuiltinFlags(cmd) {
|
|
536
|
-
const argsDef = await resolveValue(cmd.args || {});
|
|
537
|
-
const userNames = /* @__PURE__ */ new Set();
|
|
538
|
-
const userAliases = /* @__PURE__ */ new Set();
|
|
539
|
-
for (const [name, def] of Object.entries(argsDef)) {
|
|
540
|
-
userNames.add(name);
|
|
541
|
-
for (const alias of toArray(def.alias)) userAliases.add(alias);
|
|
542
|
-
}
|
|
507
|
+
function diffLines(i3, s2) {
|
|
508
|
+
if (i3 === s2) return;
|
|
509
|
+
const e2 = i3.split(`
|
|
510
|
+
`), t3 = s2.split(`
|
|
511
|
+
`), r3 = Math.max(e2.length, t3.length), f2 = [];
|
|
512
|
+
for (let n4 = 0; n4 < r3; n4++)
|
|
513
|
+
e2[n4] !== t3[n4] && f2.push(n4);
|
|
543
514
|
return {
|
|
544
|
-
|
|
545
|
-
|
|
515
|
+
lines: f2,
|
|
516
|
+
numLinesBefore: e2.length,
|
|
517
|
+
numLinesAfter: t3.length,
|
|
518
|
+
numLines: r3
|
|
546
519
|
};
|
|
547
520
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
return
|
|
521
|
+
var R = globalThis.process.platform.startsWith("win");
|
|
522
|
+
var CANCEL_SYMBOL = /* @__PURE__ */ Symbol("clack:cancel");
|
|
523
|
+
function isCancel(e2) {
|
|
524
|
+
return e2 === CANCEL_SYMBOL;
|
|
552
525
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
"
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
"ai"
|
|
576
|
-
],
|
|
577
|
-
author: "Matthieu Vagnon <hi@mvagnon.dev>",
|
|
578
|
-
license: "MIT",
|
|
579
|
-
repository: {
|
|
580
|
-
type: "git",
|
|
581
|
-
url: "git+https://github.com/mvagnon/zapdev.git"
|
|
582
|
-
},
|
|
583
|
-
homepage: "https://github.com/mvagnon/zapdev#readme",
|
|
584
|
-
bugs: {
|
|
585
|
-
url: "https://github.com/mvagnon/zapdev/issues"
|
|
586
|
-
},
|
|
587
|
-
publishConfig: {
|
|
588
|
-
access: "public"
|
|
589
|
-
},
|
|
590
|
-
scripts: {
|
|
591
|
-
zapdev: "npm run build && node dist/index.js",
|
|
592
|
-
build: "esbuild src/cli.ts --bundle --platform=node --format=esm --target=node20 --loader:.md=text --outfile=dist/cli.js && esbuild src/index.ts --platform=node --format=esm --target=node20 --outfile=dist/index.js",
|
|
593
|
-
lint: "eslint .",
|
|
594
|
-
typecheck: "tsc --noEmit",
|
|
595
|
-
test: "vitest run",
|
|
596
|
-
prepack: "npm run build"
|
|
597
|
-
},
|
|
598
|
-
devDependencies: {
|
|
599
|
-
"@clack/prompts": "^1.6.0",
|
|
600
|
-
"@eslint/js": "^10.0.1",
|
|
601
|
-
"@eslint/json": "^2.0.0",
|
|
602
|
-
"@eslint/markdown": "^8.0.2",
|
|
603
|
-
"@types/node": "^26.1.1",
|
|
604
|
-
citty: "^0.2.2",
|
|
605
|
-
esbuild: "^0.28.1",
|
|
606
|
-
eslint: "^10.6.0",
|
|
607
|
-
jiti: "^2.7.0",
|
|
608
|
-
tinyexec: "^1.2.4",
|
|
609
|
-
typescript: "^6.0.3",
|
|
610
|
-
"typescript-eslint": "^8.62.1",
|
|
611
|
-
vitest: "^4.1.9"
|
|
612
|
-
}
|
|
613
|
-
};
|
|
614
|
-
|
|
615
|
-
// src/commands/commit.ts
|
|
616
|
-
import { basename } from "node:path";
|
|
617
|
-
import { styleText as styleText4 } from "node:util";
|
|
618
|
-
|
|
619
|
-
// node_modules/@clack/core/dist/index.mjs
|
|
620
|
-
import { styleText } from "node:util";
|
|
621
|
-
import { stdout, stdin } from "node:process";
|
|
622
|
-
import * as l from "node:readline";
|
|
623
|
-
import l__default from "node:readline";
|
|
624
|
-
|
|
625
|
-
// node_modules/fast-string-truncated-width/dist/utils.js
|
|
626
|
-
var getCodePointsLength = /* @__PURE__ */ (() => {
|
|
627
|
-
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
628
|
-
return (input) => {
|
|
629
|
-
let surrogatePairsNr = 0;
|
|
630
|
-
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
631
|
-
while (SURROGATE_PAIR_RE.test(input)) {
|
|
632
|
-
surrogatePairsNr += 1;
|
|
526
|
+
function setRawMode(e2, r3) {
|
|
527
|
+
const o2 = e2;
|
|
528
|
+
o2.isTTY && o2.setRawMode(r3);
|
|
529
|
+
}
|
|
530
|
+
function block({
|
|
531
|
+
input: e2 = stdin,
|
|
532
|
+
output: r3 = stdout,
|
|
533
|
+
overwrite: o2 = true,
|
|
534
|
+
hideCursor: t3 = true
|
|
535
|
+
} = {}) {
|
|
536
|
+
const s2 = l.createInterface({
|
|
537
|
+
input: e2,
|
|
538
|
+
output: r3,
|
|
539
|
+
prompt: "",
|
|
540
|
+
tabSize: 1
|
|
541
|
+
});
|
|
542
|
+
l.emitKeypressEvents(e2, s2), e2 instanceof ReadStream && e2.isTTY && e2.setRawMode(true);
|
|
543
|
+
const n4 = (f2, { name: a3, sequence: p2 }) => {
|
|
544
|
+
const c3 = String(f2);
|
|
545
|
+
if (isActionKey([c3, a3, p2], "cancel")) {
|
|
546
|
+
t3 && r3.write(import_sisteransi.cursor.show), process.exit(0);
|
|
547
|
+
return;
|
|
633
548
|
}
|
|
634
|
-
|
|
549
|
+
if (!o2) return;
|
|
550
|
+
const i3 = a3 === "return" ? 0 : -1, m2 = a3 === "return" ? -1 : 0;
|
|
551
|
+
l.moveCursor(r3, i3, m2, () => {
|
|
552
|
+
l.clearLine(r3, 1, () => {
|
|
553
|
+
e2.once("keypress", n4);
|
|
554
|
+
});
|
|
555
|
+
});
|
|
635
556
|
};
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
return x2 === 12288 || x2 >= 65281 && x2 <= 65376 || x2 >= 65504 && x2 <= 65510;
|
|
639
|
-
};
|
|
640
|
-
var isWideNotCJKTNotEmoji = (x2) => {
|
|
641
|
-
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;
|
|
642
|
-
};
|
|
643
|
-
|
|
644
|
-
// node_modules/fast-string-truncated-width/dist/index.js
|
|
645
|
-
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
646
|
-
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
647
|
-
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;
|
|
648
|
-
var TAB_RE = /\t{1,1000}/y;
|
|
649
|
-
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");
|
|
650
|
-
var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
651
|
-
var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
|
|
652
|
-
var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
|
|
653
|
-
var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
654
|
-
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
655
|
-
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
656
|
-
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
|
|
657
|
-
const ANSI_WIDTH = 0;
|
|
658
|
-
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
659
|
-
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
660
|
-
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
661
|
-
const FULL_WIDTH_WIDTH = 2;
|
|
662
|
-
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
663
|
-
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
664
|
-
const PARSE_BLOCKS = [
|
|
665
|
-
[LATIN_RE, REGULAR_WIDTH],
|
|
666
|
-
[ANSI_RE, ANSI_WIDTH],
|
|
667
|
-
[CONTROL_RE, CONTROL_WIDTH],
|
|
668
|
-
[TAB_RE, TAB_WIDTH],
|
|
669
|
-
[EMOJI_RE, EMOJI_WIDTH],
|
|
670
|
-
[CJKT_WIDE_RE, WIDE_WIDTH]
|
|
671
|
-
];
|
|
672
|
-
let indexPrev = 0;
|
|
673
|
-
let index = 0;
|
|
674
|
-
let length = input.length;
|
|
675
|
-
let lengthExtra = 0;
|
|
676
|
-
let truncationEnabled = false;
|
|
677
|
-
let truncationIndex = length;
|
|
678
|
-
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
679
|
-
let unmatchedStart = 0;
|
|
680
|
-
let unmatchedEnd = 0;
|
|
681
|
-
let width = 0;
|
|
682
|
-
let widthExtra = 0;
|
|
683
|
-
outer: while (true) {
|
|
684
|
-
if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
|
|
685
|
-
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
|
|
686
|
-
lengthExtra = 0;
|
|
687
|
-
for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
|
|
688
|
-
const codePoint = char.codePointAt(0) || 0;
|
|
689
|
-
if (isFullWidth(codePoint)) {
|
|
690
|
-
widthExtra = FULL_WIDTH_WIDTH;
|
|
691
|
-
} else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
692
|
-
widthExtra = WIDE_WIDTH;
|
|
693
|
-
} else {
|
|
694
|
-
widthExtra = REGULAR_WIDTH;
|
|
695
|
-
}
|
|
696
|
-
if (width + widthExtra > truncationLimit) {
|
|
697
|
-
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
698
|
-
}
|
|
699
|
-
if (width + widthExtra > LIMIT) {
|
|
700
|
-
truncationEnabled = true;
|
|
701
|
-
break outer;
|
|
702
|
-
}
|
|
703
|
-
lengthExtra += char.length;
|
|
704
|
-
width += widthExtra;
|
|
705
|
-
}
|
|
706
|
-
unmatchedStart = unmatchedEnd = 0;
|
|
707
|
-
}
|
|
708
|
-
if (index >= length) {
|
|
709
|
-
break outer;
|
|
710
|
-
}
|
|
711
|
-
for (let i3 = 0, l3 = PARSE_BLOCKS.length; i3 < l3; i3++) {
|
|
712
|
-
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i3];
|
|
713
|
-
BLOCK_RE.lastIndex = index;
|
|
714
|
-
if (BLOCK_RE.test(input)) {
|
|
715
|
-
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
716
|
-
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
717
|
-
if (width + widthExtra > truncationLimit) {
|
|
718
|
-
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
719
|
-
}
|
|
720
|
-
if (width + widthExtra > LIMIT) {
|
|
721
|
-
truncationEnabled = true;
|
|
722
|
-
break outer;
|
|
723
|
-
}
|
|
724
|
-
width += widthExtra;
|
|
725
|
-
unmatchedStart = indexPrev;
|
|
726
|
-
unmatchedEnd = index;
|
|
727
|
-
index = indexPrev = BLOCK_RE.lastIndex;
|
|
728
|
-
continue outer;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
index += 1;
|
|
732
|
-
}
|
|
733
|
-
return {
|
|
734
|
-
width: truncationEnabled ? truncationLimit : width,
|
|
735
|
-
index: truncationEnabled ? truncationIndex : length,
|
|
736
|
-
truncated: truncationEnabled,
|
|
737
|
-
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
557
|
+
return t3 && r3.write(import_sisteransi.cursor.hide), e2.once("keypress", n4), () => {
|
|
558
|
+
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();
|
|
738
559
|
};
|
|
739
|
-
}
|
|
740
|
-
var
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
763
|
-
var getClosingCode = (openingCode) => {
|
|
764
|
-
if (openingCode >= 30 && openingCode <= 37)
|
|
765
|
-
return 39;
|
|
766
|
-
if (openingCode >= 90 && openingCode <= 97)
|
|
767
|
-
return 39;
|
|
768
|
-
if (openingCode >= 40 && openingCode <= 47)
|
|
769
|
-
return 49;
|
|
770
|
-
if (openingCode >= 100 && openingCode <= 107)
|
|
771
|
-
return 49;
|
|
772
|
-
if (openingCode === 1 || openingCode === 2)
|
|
773
|
-
return 22;
|
|
774
|
-
if (openingCode === 3)
|
|
775
|
-
return 23;
|
|
776
|
-
if (openingCode === 4)
|
|
777
|
-
return 24;
|
|
778
|
-
if (openingCode === 7)
|
|
779
|
-
return 27;
|
|
780
|
-
if (openingCode === 8)
|
|
781
|
-
return 28;
|
|
782
|
-
if (openingCode === 9)
|
|
783
|
-
return 29;
|
|
784
|
-
if (openingCode === 0)
|
|
785
|
-
return 0;
|
|
786
|
-
return void 0;
|
|
787
|
-
};
|
|
788
|
-
var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
789
|
-
var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
790
|
-
var wrapWord = (rows, word, columns) => {
|
|
791
|
-
const characters = word[Symbol.iterator]();
|
|
792
|
-
let isInsideEscape = false;
|
|
793
|
-
let isInsideLinkEscape = false;
|
|
794
|
-
let lastRow = rows.at(-1);
|
|
795
|
-
let visible = lastRow === void 0 ? 0 : dist_default2(lastRow);
|
|
796
|
-
let currentCharacter = characters.next();
|
|
797
|
-
let nextCharacter = characters.next();
|
|
798
|
-
let rawCharacterIndex = 0;
|
|
799
|
-
while (!currentCharacter.done) {
|
|
800
|
-
const character = currentCharacter.value;
|
|
801
|
-
const characterLength = dist_default2(character);
|
|
802
|
-
if (visible + characterLength <= columns) {
|
|
803
|
-
rows[rows.length - 1] += character;
|
|
804
|
-
} else {
|
|
805
|
-
rows.push(character);
|
|
806
|
-
visible = 0;
|
|
807
|
-
}
|
|
808
|
-
if (character === ESC || character === CSI) {
|
|
809
|
-
isInsideEscape = true;
|
|
810
|
-
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
811
|
-
}
|
|
812
|
-
if (isInsideEscape) {
|
|
813
|
-
if (isInsideLinkEscape) {
|
|
814
|
-
if (character === ANSI_ESCAPE_BELL) {
|
|
815
|
-
isInsideEscape = false;
|
|
816
|
-
isInsideLinkEscape = false;
|
|
817
|
-
}
|
|
818
|
-
} else if (character === ANSI_SGR_TERMINATOR) {
|
|
819
|
-
isInsideEscape = false;
|
|
820
|
-
}
|
|
821
|
-
} else {
|
|
822
|
-
visible += characterLength;
|
|
823
|
-
if (visible === columns && !nextCharacter.done) {
|
|
824
|
-
rows.push("");
|
|
825
|
-
visible = 0;
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
currentCharacter = nextCharacter;
|
|
829
|
-
nextCharacter = characters.next();
|
|
830
|
-
rawCharacterIndex += character.length;
|
|
560
|
+
}
|
|
561
|
+
var getColumns = (e2) => "columns" in e2 && typeof e2.columns == "number" ? e2.columns : 80;
|
|
562
|
+
var getRows = (e2) => "rows" in e2 && typeof e2.rows == "number" ? e2.rows : 20;
|
|
563
|
+
function wrapTextWithPrefix(e2, r3, o2, t3 = o2, s2 = o2, n4) {
|
|
564
|
+
const f2 = getColumns(e2 ?? stdout);
|
|
565
|
+
return wrapAnsi(r3, f2 - o2.length, {
|
|
566
|
+
hard: true,
|
|
567
|
+
trim: false
|
|
568
|
+
}).split(`
|
|
569
|
+
`).map((c3, i3, m2) => {
|
|
570
|
+
const d2 = n4 ? n4(c3, i3) : c3;
|
|
571
|
+
return i3 === 0 ? `${t3}${d2}` : i3 === m2.length - 1 ? `${s2}${d2}` : `${o2}${d2}`;
|
|
572
|
+
}).join(`
|
|
573
|
+
`);
|
|
574
|
+
}
|
|
575
|
+
function runValidation(e2, n4) {
|
|
576
|
+
if ("~standard" in e2) {
|
|
577
|
+
const a3 = e2["~standard"].validate(n4);
|
|
578
|
+
if (a3 instanceof Promise)
|
|
579
|
+
throw new TypeError(
|
|
580
|
+
"Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic."
|
|
581
|
+
);
|
|
582
|
+
return a3.issues?.at(0)?.message;
|
|
831
583
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
584
|
+
return e2(n4);
|
|
585
|
+
}
|
|
586
|
+
var V = class {
|
|
587
|
+
input;
|
|
588
|
+
output;
|
|
589
|
+
_abortSignal;
|
|
590
|
+
rl;
|
|
591
|
+
opts;
|
|
592
|
+
_render;
|
|
593
|
+
_track = false;
|
|
594
|
+
_prevFrame = "";
|
|
595
|
+
_subscribers = /* @__PURE__ */ new Map();
|
|
596
|
+
_cursor = 0;
|
|
597
|
+
state = "initial";
|
|
598
|
+
error = "";
|
|
599
|
+
value;
|
|
600
|
+
userInput = "";
|
|
601
|
+
constructor(t3, e2 = true) {
|
|
602
|
+
const { input: i3 = stdin, output: n4 = stdout, render: s2, signal: r3, ...o2 } = t3;
|
|
603
|
+
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;
|
|
835
604
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
if (dist_default2(words[last - 1])) {
|
|
842
|
-
break;
|
|
843
|
-
}
|
|
844
|
-
last--;
|
|
605
|
+
/**
|
|
606
|
+
* Unsubscribe all listeners
|
|
607
|
+
*/
|
|
608
|
+
unsubscribe() {
|
|
609
|
+
this._subscribers.clear();
|
|
845
610
|
}
|
|
846
|
-
|
|
847
|
-
|
|
611
|
+
/**
|
|
612
|
+
* Set a subscriber with opts
|
|
613
|
+
* @param event - The event name
|
|
614
|
+
*/
|
|
615
|
+
setSubscriber(t3, e2) {
|
|
616
|
+
const i3 = this._subscribers.get(t3) ?? [];
|
|
617
|
+
i3.push(e2), this._subscribers.set(t3, i3);
|
|
848
618
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
619
|
+
/**
|
|
620
|
+
* Subscribe to an event
|
|
621
|
+
* @param event - The event name
|
|
622
|
+
* @param cb - The callback
|
|
623
|
+
*/
|
|
624
|
+
on(t3, e2) {
|
|
625
|
+
this.setSubscriber(t3, { cb: e2 });
|
|
854
626
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const word = words[index];
|
|
863
|
-
if (options.trim !== false) {
|
|
864
|
-
const row = rows.at(-1) ?? "";
|
|
865
|
-
const trimmed = row.trimStart();
|
|
866
|
-
if (row.length !== trimmed.length) {
|
|
867
|
-
rows[rows.length - 1] = trimmed;
|
|
868
|
-
rowLength = dist_default2(trimmed);
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
if (index !== 0) {
|
|
872
|
-
if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
|
|
873
|
-
rows.push("");
|
|
874
|
-
rowLength = 0;
|
|
875
|
-
}
|
|
876
|
-
if (rowLength || options.trim === false) {
|
|
877
|
-
rows[rows.length - 1] += " ";
|
|
878
|
-
rowLength++;
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
const wordLength = dist_default2(word);
|
|
882
|
-
if (options.hard && wordLength > columns) {
|
|
883
|
-
const remainingColumns = columns - rowLength;
|
|
884
|
-
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
885
|
-
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
886
|
-
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
887
|
-
rows.push("");
|
|
888
|
-
}
|
|
889
|
-
wrapWord(rows, word, columns);
|
|
890
|
-
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
891
|
-
continue;
|
|
892
|
-
}
|
|
893
|
-
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
894
|
-
if (options.wordWrap === false && rowLength < columns) {
|
|
895
|
-
wrapWord(rows, word, columns);
|
|
896
|
-
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
897
|
-
continue;
|
|
898
|
-
}
|
|
899
|
-
rows.push("");
|
|
900
|
-
rowLength = 0;
|
|
901
|
-
}
|
|
902
|
-
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
903
|
-
wrapWord(rows, word, columns);
|
|
904
|
-
rowLength = dist_default2(rows.at(-1) ?? "");
|
|
905
|
-
continue;
|
|
906
|
-
}
|
|
907
|
-
rows[rows.length - 1] += word;
|
|
908
|
-
rowLength += wordLength;
|
|
627
|
+
/**
|
|
628
|
+
* Subscribe to an event once
|
|
629
|
+
* @param event - The event name
|
|
630
|
+
* @param cb - The callback
|
|
631
|
+
*/
|
|
632
|
+
once(t3, e2) {
|
|
633
|
+
this.setSubscriber(t3, { cb: e2, once: true });
|
|
909
634
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
const
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
continue;
|
|
922
|
-
}
|
|
923
|
-
} else {
|
|
924
|
-
inSurrogate = false;
|
|
925
|
-
}
|
|
926
|
-
if (character === ESC || character === CSI) {
|
|
927
|
-
GROUP_REGEX.lastIndex = i3 + 1;
|
|
928
|
-
const groupsResult = GROUP_REGEX.exec(preString);
|
|
929
|
-
const groups = groupsResult?.groups;
|
|
930
|
-
if (groups?.code !== void 0) {
|
|
931
|
-
const code = Number.parseFloat(groups.code);
|
|
932
|
-
escapeCode = code === END_CODE ? void 0 : code;
|
|
933
|
-
} else if (groups?.uri !== void 0) {
|
|
934
|
-
escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
if (preString[i3 + 1] === "\n") {
|
|
938
|
-
if (escapeUrl) {
|
|
939
|
-
returnValue += wrapAnsiHyperlink("");
|
|
940
|
-
}
|
|
941
|
-
const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
|
|
942
|
-
if (escapeCode && closingCode) {
|
|
943
|
-
returnValue += wrapAnsiCode(closingCode);
|
|
944
|
-
}
|
|
945
|
-
} else if (character === "\n") {
|
|
946
|
-
if (escapeCode && getClosingCode(escapeCode)) {
|
|
947
|
-
returnValue += wrapAnsiCode(escapeCode);
|
|
948
|
-
}
|
|
949
|
-
if (escapeUrl) {
|
|
950
|
-
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
951
|
-
}
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
return returnValue;
|
|
955
|
-
};
|
|
956
|
-
var CRLF_OR_LF = /\r?\n/;
|
|
957
|
-
function wrapAnsi(string, columns, options) {
|
|
958
|
-
return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
// node_modules/@clack/core/dist/index.mjs
|
|
962
|
-
var import_sisteransi = __toESM(require_src(), 1);
|
|
963
|
-
import { ReadStream } from "node:tty";
|
|
964
|
-
function findCursor(s2, o2, l3) {
|
|
965
|
-
if (!l3.some((r3) => !r3.disabled))
|
|
966
|
-
return s2;
|
|
967
|
-
const t3 = s2 + o2, n4 = Math.max(l3.length - 1, 0), e2 = t3 < 0 ? n4 : t3 > n4 ? 0 : t3;
|
|
968
|
-
return l3[e2]?.disabled ? findCursor(e2, o2 < 0 ? -1 : 1, l3) : e2;
|
|
969
|
-
}
|
|
970
|
-
var a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
971
|
-
var t = [
|
|
972
|
-
"January",
|
|
973
|
-
"February",
|
|
974
|
-
"March",
|
|
975
|
-
"April",
|
|
976
|
-
"May",
|
|
977
|
-
"June",
|
|
978
|
-
"July",
|
|
979
|
-
"August",
|
|
980
|
-
"September",
|
|
981
|
-
"October",
|
|
982
|
-
"November",
|
|
983
|
-
"December"
|
|
984
|
-
];
|
|
985
|
-
var settings = {
|
|
986
|
-
actions: new Set(a$1),
|
|
987
|
-
aliases: /* @__PURE__ */ new Map([
|
|
988
|
-
// vim support
|
|
989
|
-
["k", "up"],
|
|
990
|
-
["j", "down"],
|
|
991
|
-
["h", "left"],
|
|
992
|
-
["l", "right"],
|
|
993
|
-
["", "cancel"],
|
|
994
|
-
// opinionated defaults!
|
|
995
|
-
["escape", "cancel"]
|
|
996
|
-
]),
|
|
997
|
-
messages: {
|
|
998
|
-
cancel: "Canceled",
|
|
999
|
-
error: "Something went wrong"
|
|
1000
|
-
},
|
|
1001
|
-
withGuide: true,
|
|
1002
|
-
date: {
|
|
1003
|
-
monthNames: [...t],
|
|
1004
|
-
messages: {
|
|
1005
|
-
required: "Please enter a valid date",
|
|
1006
|
-
invalidMonth: "There are only 12 months in a year",
|
|
1007
|
-
invalidDay: (n4, e2) => `There are only ${n4} days in ${e2}`,
|
|
1008
|
-
afterMin: (n4) => `Date must be on or after ${n4.toISOString().slice(0, 10)}`,
|
|
1009
|
-
beforeMax: (n4) => `Date must be on or before ${n4.toISOString().slice(0, 10)}`
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1013
|
-
function isActionKey(n4, e2) {
|
|
1014
|
-
if (typeof n4 == "string")
|
|
1015
|
-
return settings.aliases.get(n4) === e2;
|
|
1016
|
-
for (const s2 of n4)
|
|
1017
|
-
if (s2 !== void 0 && isActionKey(s2, e2))
|
|
1018
|
-
return true;
|
|
1019
|
-
return false;
|
|
1020
|
-
}
|
|
1021
|
-
function diffLines(i3, s2) {
|
|
1022
|
-
if (i3 === s2) return;
|
|
1023
|
-
const e2 = i3.split(`
|
|
1024
|
-
`), t3 = s2.split(`
|
|
1025
|
-
`), r3 = Math.max(e2.length, t3.length), f2 = [];
|
|
1026
|
-
for (let n4 = 0; n4 < r3; n4++)
|
|
1027
|
-
e2[n4] !== t3[n4] && f2.push(n4);
|
|
1028
|
-
return {
|
|
1029
|
-
lines: f2,
|
|
1030
|
-
numLinesBefore: e2.length,
|
|
1031
|
-
numLinesAfter: t3.length,
|
|
1032
|
-
numLines: r3
|
|
1033
|
-
};
|
|
1034
|
-
}
|
|
1035
|
-
var R = globalThis.process.platform.startsWith("win");
|
|
1036
|
-
var CANCEL_SYMBOL = /* @__PURE__ */ Symbol("clack:cancel");
|
|
1037
|
-
function isCancel(e2) {
|
|
1038
|
-
return e2 === CANCEL_SYMBOL;
|
|
1039
|
-
}
|
|
1040
|
-
function setRawMode(e2, r3) {
|
|
1041
|
-
const o2 = e2;
|
|
1042
|
-
o2.isTTY && o2.setRawMode(r3);
|
|
1043
|
-
}
|
|
1044
|
-
function block({
|
|
1045
|
-
input: e2 = stdin,
|
|
1046
|
-
output: r3 = stdout,
|
|
1047
|
-
overwrite: o2 = true,
|
|
1048
|
-
hideCursor: t3 = true
|
|
1049
|
-
} = {}) {
|
|
1050
|
-
const s2 = l.createInterface({
|
|
1051
|
-
input: e2,
|
|
1052
|
-
output: r3,
|
|
1053
|
-
prompt: "",
|
|
1054
|
-
tabSize: 1
|
|
1055
|
-
});
|
|
1056
|
-
l.emitKeypressEvents(e2, s2), e2 instanceof ReadStream && e2.isTTY && e2.setRawMode(true);
|
|
1057
|
-
const n4 = (f2, { name: a3, sequence: p2 }) => {
|
|
1058
|
-
const c3 = String(f2);
|
|
1059
|
-
if (isActionKey([c3, a3, p2], "cancel")) {
|
|
1060
|
-
t3 && r3.write(import_sisteransi.cursor.show), process.exit(0);
|
|
1061
|
-
return;
|
|
1062
|
-
}
|
|
1063
|
-
if (!o2) return;
|
|
1064
|
-
const i3 = a3 === "return" ? 0 : -1, m2 = a3 === "return" ? -1 : 0;
|
|
1065
|
-
l.moveCursor(r3, i3, m2, () => {
|
|
1066
|
-
l.clearLine(r3, 1, () => {
|
|
1067
|
-
e2.once("keypress", n4);
|
|
1068
|
-
});
|
|
1069
|
-
});
|
|
1070
|
-
};
|
|
1071
|
-
return t3 && r3.write(import_sisteransi.cursor.hide), e2.once("keypress", n4), () => {
|
|
1072
|
-
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();
|
|
1073
|
-
};
|
|
1074
|
-
}
|
|
1075
|
-
var getColumns = (e2) => "columns" in e2 && typeof e2.columns == "number" ? e2.columns : 80;
|
|
1076
|
-
var getRows = (e2) => "rows" in e2 && typeof e2.rows == "number" ? e2.rows : 20;
|
|
1077
|
-
function wrapTextWithPrefix(e2, r3, o2, t3 = o2, s2 = o2, n4) {
|
|
1078
|
-
const f2 = getColumns(e2 ?? stdout);
|
|
1079
|
-
return wrapAnsi(r3, f2 - o2.length, {
|
|
1080
|
-
hard: true,
|
|
1081
|
-
trim: false
|
|
1082
|
-
}).split(`
|
|
1083
|
-
`).map((c3, i3, m2) => {
|
|
1084
|
-
const d2 = n4 ? n4(c3, i3) : c3;
|
|
1085
|
-
return i3 === 0 ? `${t3}${d2}` : i3 === m2.length - 1 ? `${s2}${d2}` : `${o2}${d2}`;
|
|
1086
|
-
}).join(`
|
|
1087
|
-
`);
|
|
1088
|
-
}
|
|
1089
|
-
function runValidation(e2, n4) {
|
|
1090
|
-
if ("~standard" in e2) {
|
|
1091
|
-
const a3 = e2["~standard"].validate(n4);
|
|
1092
|
-
if (a3 instanceof Promise)
|
|
1093
|
-
throw new TypeError(
|
|
1094
|
-
"Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic."
|
|
1095
|
-
);
|
|
1096
|
-
return a3.issues?.at(0)?.message;
|
|
1097
|
-
}
|
|
1098
|
-
return e2(n4);
|
|
1099
|
-
}
|
|
1100
|
-
var V = class {
|
|
1101
|
-
input;
|
|
1102
|
-
output;
|
|
1103
|
-
_abortSignal;
|
|
1104
|
-
rl;
|
|
1105
|
-
opts;
|
|
1106
|
-
_render;
|
|
1107
|
-
_track = false;
|
|
1108
|
-
_prevFrame = "";
|
|
1109
|
-
_subscribers = /* @__PURE__ */ new Map();
|
|
1110
|
-
_cursor = 0;
|
|
1111
|
-
state = "initial";
|
|
1112
|
-
error = "";
|
|
1113
|
-
value;
|
|
1114
|
-
userInput = "";
|
|
1115
|
-
constructor(t3, e2 = true) {
|
|
1116
|
-
const { input: i3 = stdin, output: n4 = stdout, render: s2, signal: r3, ...o2 } = t3;
|
|
1117
|
-
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;
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
* Unsubscribe all listeners
|
|
1121
|
-
*/
|
|
1122
|
-
unsubscribe() {
|
|
1123
|
-
this._subscribers.clear();
|
|
1124
|
-
}
|
|
1125
|
-
/**
|
|
1126
|
-
* Set a subscriber with opts
|
|
1127
|
-
* @param event - The event name
|
|
1128
|
-
*/
|
|
1129
|
-
setSubscriber(t3, e2) {
|
|
1130
|
-
const i3 = this._subscribers.get(t3) ?? [];
|
|
1131
|
-
i3.push(e2), this._subscribers.set(t3, i3);
|
|
1132
|
-
}
|
|
1133
|
-
/**
|
|
1134
|
-
* Subscribe to an event
|
|
1135
|
-
* @param event - The event name
|
|
1136
|
-
* @param cb - The callback
|
|
1137
|
-
*/
|
|
1138
|
-
on(t3, e2) {
|
|
1139
|
-
this.setSubscriber(t3, { cb: e2 });
|
|
1140
|
-
}
|
|
1141
|
-
/**
|
|
1142
|
-
* Subscribe to an event once
|
|
1143
|
-
* @param event - The event name
|
|
1144
|
-
* @param cb - The callback
|
|
1145
|
-
*/
|
|
1146
|
-
once(t3, e2) {
|
|
1147
|
-
this.setSubscriber(t3, { cb: e2, once: true });
|
|
1148
|
-
}
|
|
1149
|
-
/**
|
|
1150
|
-
* Emit an event with data
|
|
1151
|
-
* @param event - The event name
|
|
1152
|
-
* @param data - The data to pass to the callback
|
|
1153
|
-
*/
|
|
1154
|
-
emit(t3, ...e2) {
|
|
1155
|
-
const i3 = this._subscribers.get(t3) ?? [], n4 = [];
|
|
1156
|
-
for (const s2 of i3)
|
|
1157
|
-
s2.cb(...e2), s2.once && n4.push(() => i3.splice(i3.indexOf(s2), 1));
|
|
1158
|
-
for (const s2 of n4)
|
|
1159
|
-
s2();
|
|
635
|
+
/**
|
|
636
|
+
* Emit an event with data
|
|
637
|
+
* @param event - The event name
|
|
638
|
+
* @param data - The data to pass to the callback
|
|
639
|
+
*/
|
|
640
|
+
emit(t3, ...e2) {
|
|
641
|
+
const i3 = this._subscribers.get(t3) ?? [], n4 = [];
|
|
642
|
+
for (const s2 of i3)
|
|
643
|
+
s2.cb(...e2), s2.once && n4.push(() => i3.splice(i3.indexOf(s2), 1));
|
|
644
|
+
for (const s2 of n4)
|
|
645
|
+
s2();
|
|
1160
646
|
}
|
|
1161
647
|
prompt() {
|
|
1162
648
|
return new Promise((t3) => {
|
|
@@ -1344,6 +830,7 @@ function isUnicodeSupported() {
|
|
|
1344
830
|
}
|
|
1345
831
|
var unicode = isUnicodeSupported();
|
|
1346
832
|
var isCI = () => process.env.CI === "true";
|
|
833
|
+
var isTTY = (o2) => o2.isTTY === true;
|
|
1347
834
|
var unicodeOr = (o2, e2) => unicode ? o2 : e2;
|
|
1348
835
|
var S_STEP_ACTIVE = unicodeOr("\u25C6", "*");
|
|
1349
836
|
var S_STEP_CANCEL = unicodeOr("\u25A0", "x");
|
|
@@ -1589,7 +1076,7 @@ var spinner = ({
|
|
|
1589
1076
|
const x2 = getColumns(n4), k2 = I3?.styleFrame ?? W, g2 = (e2) => {
|
|
1590
1077
|
const r3 = e2 > 1 ? O2 ?? settings.messages.error : G ?? settings.messages.cancel;
|
|
1591
1078
|
S2 = e2 === 1, d2 && (a3(r3, e2), S2 && typeof h3 == "function" && h3());
|
|
1592
|
-
}, f2 = () => g2(2), i3 = () => g2(1),
|
|
1079
|
+
}, f2 = () => g2(2), i3 = () => g2(1), A2 = () => {
|
|
1593
1080
|
process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i3), process.on("SIGTERM", i3), process.on("exit", g2), m2 && m2.addEventListener("abort", i3);
|
|
1594
1081
|
}, H = () => {
|
|
1595
1082
|
process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i3), process.removeListener("SIGTERM", i3), process.removeListener("exit", g2), m2 && m2.removeEventListener("abort", i3);
|
|
@@ -1610,7 +1097,7 @@ var spinner = ({
|
|
|
1610
1097
|
d2 = true, M = block({ output: n4 }), s2 = C2(e2), w2 = performance.now(), N2 && n4.write(`${styleText2("gray", S_BAR)}
|
|
1611
1098
|
`);
|
|
1612
1099
|
let r3 = 0, t3 = 0;
|
|
1613
|
-
|
|
1100
|
+
A2(), T2 = setInterval(() => {
|
|
1614
1101
|
if (u4 && s2 === p2)
|
|
1615
1102
|
return;
|
|
1616
1103
|
y2(), p2 = s2;
|
|
@@ -1738,14 +1225,131 @@ ${b2}
|
|
|
1738
1225
|
}).prompt();
|
|
1739
1226
|
};
|
|
1740
1227
|
var i = `${styleText2("gray", S_BAR)} `;
|
|
1741
|
-
var
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1228
|
+
var A = (l3) => l3.replace(/\x1b\[(?:\d+;)*\d*[ABCDEFGHfJKSTsu]|\x1b\[(s|u)/g, "");
|
|
1229
|
+
var taskLog = (l3) => {
|
|
1230
|
+
const r3 = l3.output ?? process.stdout, O2 = getColumns(r3), i3 = styleText2("gray", S_BAR), p2 = l3.spacing ?? 1, k2 = 3, m2 = l3.retainLog === true, d2 = !isCI() && isTTY(r3);
|
|
1231
|
+
r3.write(`${i3}
|
|
1232
|
+
`), r3.write(`${styleText2("green", S_STEP_SUBMIT)} ${l3.title}
|
|
1233
|
+
`);
|
|
1234
|
+
for (let e2 = 0; e2 < p2; e2++)
|
|
1235
|
+
r3.write(`${i3}
|
|
1236
|
+
`);
|
|
1237
|
+
const n4 = [
|
|
1238
|
+
{
|
|
1239
|
+
value: "",
|
|
1240
|
+
full: ""
|
|
1241
|
+
}
|
|
1242
|
+
];
|
|
1243
|
+
let v2 = false;
|
|
1244
|
+
const f2 = (e2) => {
|
|
1245
|
+
if (n4.length === 0)
|
|
1246
|
+
return;
|
|
1247
|
+
let s2 = 0;
|
|
1248
|
+
e2 && (s2 += p2 + 2);
|
|
1249
|
+
for (const t3 of n4) {
|
|
1250
|
+
const { value: o2, result: a3 } = t3;
|
|
1251
|
+
let g2 = a3?.message ?? o2;
|
|
1252
|
+
if (g2.length === 0)
|
|
1253
|
+
continue;
|
|
1254
|
+
a3 === void 0 && t3.header !== void 0 && t3.header !== "" && (g2 += `
|
|
1255
|
+
${t3.header}`);
|
|
1256
|
+
const E2 = g2.split(`
|
|
1257
|
+
`).reduce((b2, w2) => w2 === "" ? b2 + 1 : b2 + Math.ceil((w2.length + k2) / O2), 0);
|
|
1258
|
+
s2 += E2;
|
|
1259
|
+
}
|
|
1260
|
+
s2 > 0 && (s2 += 1, r3.write(import_sisteransi2.erase.lines(s2)));
|
|
1261
|
+
}, h3 = (e2, s2, t3) => {
|
|
1262
|
+
const o2 = t3 ? `${e2.full}
|
|
1263
|
+
${e2.value}` : e2.value;
|
|
1264
|
+
e2.header !== void 0 && e2.header !== "" && log.message(
|
|
1265
|
+
e2.header.split(`
|
|
1266
|
+
`).map((a3) => styleText2("bold", a3)),
|
|
1267
|
+
{
|
|
1268
|
+
output: r3,
|
|
1269
|
+
secondarySymbol: i3,
|
|
1270
|
+
symbol: i3,
|
|
1271
|
+
spacing: 0
|
|
1272
|
+
}
|
|
1273
|
+
), log.message(
|
|
1274
|
+
o2.split(`
|
|
1275
|
+
`).map((a3) => styleText2("dim", a3)),
|
|
1276
|
+
{
|
|
1277
|
+
output: r3,
|
|
1278
|
+
secondarySymbol: i3,
|
|
1279
|
+
symbol: i3,
|
|
1280
|
+
spacing: s2 ?? p2
|
|
1281
|
+
}
|
|
1282
|
+
);
|
|
1283
|
+
}, T2 = () => {
|
|
1284
|
+
for (const e2 of n4) {
|
|
1285
|
+
const { header: s2, value: t3, full: o2 } = e2;
|
|
1286
|
+
(s2 === void 0 || s2.length === 0) && t3.length === 0 || h3(e2, void 0, m2 === true && o2.length > 0);
|
|
1287
|
+
}
|
|
1288
|
+
}, L = (e2, s2, t3) => {
|
|
1289
|
+
if (f2(false), (t3?.raw !== true || !v2) && e2.value !== "" && (e2.value += `
|
|
1290
|
+
`), e2.value += A(s2), v2 = t3?.raw === true, l3.limit !== void 0) {
|
|
1291
|
+
const o2 = e2.value.split(`
|
|
1292
|
+
`), a3 = o2.length - l3.limit;
|
|
1293
|
+
if (a3 > 0) {
|
|
1294
|
+
const g2 = o2.splice(0, a3);
|
|
1295
|
+
m2 && (e2.full += (e2.full === "" ? "" : `
|
|
1296
|
+
`) + g2.join(`
|
|
1297
|
+
`));
|
|
1298
|
+
}
|
|
1299
|
+
e2.value = o2.join(`
|
|
1300
|
+
`);
|
|
1301
|
+
}
|
|
1302
|
+
d2 && y2();
|
|
1303
|
+
}, y2 = () => {
|
|
1304
|
+
for (const e2 of n4)
|
|
1305
|
+
e2.result ? e2.result.status === "error" ? log.error(e2.result.message, { output: r3, secondarySymbol: i3, spacing: 0 }) : log.success(e2.result.message, { output: r3, secondarySymbol: i3, spacing: 0 }) : e2.value !== "" && h3(e2, 0);
|
|
1306
|
+
}, B = (e2, s2) => {
|
|
1307
|
+
f2(false), e2.result = s2, d2 && y2();
|
|
1308
|
+
};
|
|
1309
|
+
return {
|
|
1310
|
+
message(e2, s2) {
|
|
1311
|
+
L(n4[0], e2, s2);
|
|
1312
|
+
},
|
|
1313
|
+
group(e2) {
|
|
1314
|
+
const s2 = {
|
|
1315
|
+
header: e2,
|
|
1316
|
+
value: "",
|
|
1317
|
+
full: ""
|
|
1318
|
+
};
|
|
1319
|
+
return n4.push(s2), {
|
|
1320
|
+
message(t3, o2) {
|
|
1321
|
+
L(s2, t3, o2);
|
|
1322
|
+
},
|
|
1323
|
+
error(t3) {
|
|
1324
|
+
B(s2, {
|
|
1325
|
+
status: "error",
|
|
1326
|
+
message: t3
|
|
1327
|
+
});
|
|
1328
|
+
},
|
|
1329
|
+
success(t3) {
|
|
1330
|
+
B(s2, {
|
|
1331
|
+
status: "success",
|
|
1332
|
+
message: t3
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
},
|
|
1337
|
+
error(e2, s2) {
|
|
1338
|
+
f2(true), log.error(e2, { output: r3, secondarySymbol: i3, spacing: 1 }), s2?.showLog !== false && T2(), n4.splice(1, n4.length - 1), n4[0].value = "", n4[0].full = "";
|
|
1339
|
+
},
|
|
1340
|
+
success(e2, s2) {
|
|
1341
|
+
f2(true), log.success(e2, { output: r3, secondarySymbol: i3, spacing: 1 }), s2?.showLog === true && T2(), n4.splice(1, n4.length - 1), n4[0].value = "", n4[0].full = "";
|
|
1342
|
+
}
|
|
1343
|
+
};
|
|
1344
|
+
};
|
|
1345
|
+
var text = (e2) => new n2({
|
|
1346
|
+
validate: e2.validate,
|
|
1347
|
+
placeholder: e2.placeholder,
|
|
1348
|
+
defaultValue: e2.defaultValue,
|
|
1349
|
+
initialValue: e2.initialValue,
|
|
1350
|
+
output: e2.output,
|
|
1351
|
+
signal: e2.signal,
|
|
1352
|
+
input: e2.input,
|
|
1749
1353
|
render() {
|
|
1750
1354
|
const i3 = e2?.withGuide ?? settings.withGuide, s2 = `${`${i3 ? `${styleText2("gray", S_BAR)}
|
|
1751
1355
|
` : ""}${symbol(this.state)} `}${e2.message}
|
|
@@ -1778,64 +1382,541 @@ ${r3}
|
|
|
1778
1382
|
}
|
|
1779
1383
|
}
|
|
1780
1384
|
}
|
|
1781
|
-
}).prompt();
|
|
1782
|
-
|
|
1783
|
-
//
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
}
|
|
1795
|
-
function
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
let
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1385
|
+
}).prompt();
|
|
1386
|
+
|
|
1387
|
+
// node_modules/citty/dist/_chunks/libs/scule.mjs
|
|
1388
|
+
var NUMBER_CHAR_RE = /\d/;
|
|
1389
|
+
var STR_SPLITTERS = [
|
|
1390
|
+
"-",
|
|
1391
|
+
"_",
|
|
1392
|
+
"/",
|
|
1393
|
+
"."
|
|
1394
|
+
];
|
|
1395
|
+
function isUppercase(char = "") {
|
|
1396
|
+
if (NUMBER_CHAR_RE.test(char)) return;
|
|
1397
|
+
return char !== char.toLowerCase();
|
|
1398
|
+
}
|
|
1399
|
+
function splitByCase(str, separators) {
|
|
1400
|
+
const splitters = separators ?? STR_SPLITTERS;
|
|
1401
|
+
const parts = [];
|
|
1402
|
+
if (!str || typeof str !== "string") return parts;
|
|
1403
|
+
let buff = "";
|
|
1404
|
+
let previousUpper;
|
|
1405
|
+
let previousSplitter;
|
|
1406
|
+
for (const char of str) {
|
|
1407
|
+
const isSplitter = splitters.includes(char);
|
|
1408
|
+
if (isSplitter === true) {
|
|
1409
|
+
parts.push(buff);
|
|
1410
|
+
buff = "";
|
|
1411
|
+
previousUpper = void 0;
|
|
1412
|
+
continue;
|
|
1413
|
+
}
|
|
1414
|
+
const isUpper = isUppercase(char);
|
|
1415
|
+
if (previousSplitter === false) {
|
|
1416
|
+
if (previousUpper === false && isUpper === true) {
|
|
1417
|
+
parts.push(buff);
|
|
1418
|
+
buff = char;
|
|
1419
|
+
previousUpper = isUpper;
|
|
1420
|
+
continue;
|
|
1421
|
+
}
|
|
1422
|
+
if (previousUpper === true && isUpper === false && buff.length > 1) {
|
|
1423
|
+
const lastChar = buff.at(-1);
|
|
1424
|
+
parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
|
|
1425
|
+
buff = lastChar + char;
|
|
1426
|
+
previousUpper = isUpper;
|
|
1427
|
+
continue;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
buff += char;
|
|
1431
|
+
previousUpper = isUpper;
|
|
1432
|
+
previousSplitter = isSplitter;
|
|
1433
|
+
}
|
|
1434
|
+
parts.push(buff);
|
|
1435
|
+
return parts;
|
|
1436
|
+
}
|
|
1437
|
+
function upperFirst(str) {
|
|
1438
|
+
return str ? str[0].toUpperCase() + str.slice(1) : "";
|
|
1439
|
+
}
|
|
1440
|
+
function lowerFirst(str) {
|
|
1441
|
+
return str ? str[0].toLowerCase() + str.slice(1) : "";
|
|
1442
|
+
}
|
|
1443
|
+
function pascalCase(str, opts) {
|
|
1444
|
+
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => upperFirst(opts?.normalize ? p2.toLowerCase() : p2)).join("") : "";
|
|
1445
|
+
}
|
|
1446
|
+
function camelCase(str, opts) {
|
|
1447
|
+
return lowerFirst(pascalCase(str || "", opts));
|
|
1448
|
+
}
|
|
1449
|
+
function kebabCase(str, joiner) {
|
|
1450
|
+
return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p2) => p2.toLowerCase()).join(joiner ?? "-") : "";
|
|
1451
|
+
}
|
|
1452
|
+
function snakeCase(str) {
|
|
1453
|
+
return kebabCase(str || "", "_");
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// node_modules/citty/dist/index.mjs
|
|
1457
|
+
import { parseArgs as parseArgs$1 } from "node:util";
|
|
1458
|
+
function toArray(val) {
|
|
1459
|
+
if (Array.isArray(val)) return val;
|
|
1460
|
+
return val === void 0 ? [] : [val];
|
|
1461
|
+
}
|
|
1462
|
+
function formatLineColumns(lines, linePrefix = "") {
|
|
1463
|
+
const maxLength = [];
|
|
1464
|
+
for (const line of lines) for (const [i3, element] of line.entries()) maxLength[i3] = Math.max(maxLength[i3] || 0, element.length);
|
|
1465
|
+
return lines.map((l3) => l3.map((c3, i3) => linePrefix + c3[i3 === 0 ? "padStart" : "padEnd"](maxLength[i3])).join(" ")).join("\n");
|
|
1466
|
+
}
|
|
1467
|
+
function resolveValue(input) {
|
|
1468
|
+
return typeof input === "function" ? input() : input;
|
|
1469
|
+
}
|
|
1470
|
+
var CLIError = class extends Error {
|
|
1471
|
+
code;
|
|
1472
|
+
constructor(message, code) {
|
|
1473
|
+
super(message);
|
|
1474
|
+
this.name = "CLIError";
|
|
1475
|
+
this.code = code;
|
|
1476
|
+
}
|
|
1477
|
+
};
|
|
1478
|
+
function parseRawArgs(args = [], opts = {}) {
|
|
1479
|
+
const booleans = new Set(opts.boolean || []);
|
|
1480
|
+
const strings = new Set(opts.string || []);
|
|
1481
|
+
const aliasMap = opts.alias || {};
|
|
1482
|
+
const defaults = opts.default || {};
|
|
1483
|
+
const aliasToMain = /* @__PURE__ */ new Map();
|
|
1484
|
+
const mainToAliases = /* @__PURE__ */ new Map();
|
|
1485
|
+
for (const [key, value] of Object.entries(aliasMap)) {
|
|
1486
|
+
const targets = value;
|
|
1487
|
+
for (const target of targets) {
|
|
1488
|
+
aliasToMain.set(key, target);
|
|
1489
|
+
if (!mainToAliases.has(target)) mainToAliases.set(target, []);
|
|
1490
|
+
mainToAliases.get(target).push(key);
|
|
1491
|
+
aliasToMain.set(target, key);
|
|
1492
|
+
if (!mainToAliases.has(key)) mainToAliases.set(key, []);
|
|
1493
|
+
mainToAliases.get(key).push(target);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
const options = {};
|
|
1497
|
+
function getType(name) {
|
|
1498
|
+
if (booleans.has(name)) return "boolean";
|
|
1499
|
+
const aliases = mainToAliases.get(name) || [];
|
|
1500
|
+
for (const alias of aliases) if (booleans.has(alias)) return "boolean";
|
|
1501
|
+
return "string";
|
|
1502
|
+
}
|
|
1503
|
+
function isStringType(name) {
|
|
1504
|
+
if (strings.has(name)) return true;
|
|
1505
|
+
const aliases = mainToAliases.get(name) || [];
|
|
1506
|
+
for (const alias of aliases) if (strings.has(alias)) return true;
|
|
1507
|
+
return false;
|
|
1508
|
+
}
|
|
1509
|
+
const allOptions = /* @__PURE__ */ new Set([
|
|
1510
|
+
...booleans,
|
|
1511
|
+
...strings,
|
|
1512
|
+
...Object.keys(aliasMap),
|
|
1513
|
+
...Object.values(aliasMap).flat(),
|
|
1514
|
+
...Object.keys(defaults)
|
|
1515
|
+
]);
|
|
1516
|
+
for (const name of allOptions) if (!options[name]) options[name] = {
|
|
1517
|
+
type: getType(name),
|
|
1518
|
+
default: defaults[name]
|
|
1519
|
+
};
|
|
1520
|
+
for (const [alias, main2] of aliasToMain.entries()) if (alias.length === 1 && options[main2] && !options[main2].short) options[main2].short = alias;
|
|
1521
|
+
const processedArgs = [];
|
|
1522
|
+
const negatedFlags = {};
|
|
1523
|
+
for (let i3 = 0; i3 < args.length; i3++) {
|
|
1524
|
+
const arg = args[i3];
|
|
1525
|
+
if (arg === "--") {
|
|
1526
|
+
processedArgs.push(...args.slice(i3));
|
|
1527
|
+
break;
|
|
1528
|
+
}
|
|
1529
|
+
if (arg.startsWith("--no-")) {
|
|
1530
|
+
const flagName = arg.slice(5);
|
|
1531
|
+
negatedFlags[flagName] = true;
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
processedArgs.push(arg);
|
|
1535
|
+
}
|
|
1536
|
+
let parsed;
|
|
1537
|
+
try {
|
|
1538
|
+
parsed = parseArgs$1({
|
|
1539
|
+
args: processedArgs,
|
|
1540
|
+
options: Object.keys(options).length > 0 ? options : void 0,
|
|
1541
|
+
allowPositionals: true,
|
|
1542
|
+
strict: false
|
|
1543
|
+
});
|
|
1544
|
+
} catch {
|
|
1545
|
+
parsed = {
|
|
1546
|
+
values: {},
|
|
1547
|
+
positionals: processedArgs
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
const out = { _: [] };
|
|
1551
|
+
out._ = parsed.positionals;
|
|
1552
|
+
for (const [key, value] of Object.entries(parsed.values)) {
|
|
1553
|
+
let coerced = value;
|
|
1554
|
+
if (getType(key) === "boolean" && typeof value === "string") coerced = value !== "false";
|
|
1555
|
+
else if (isStringType(key) && typeof value === "boolean") coerced = "";
|
|
1556
|
+
out[key] = coerced;
|
|
1557
|
+
}
|
|
1558
|
+
for (const [name] of Object.entries(negatedFlags)) {
|
|
1559
|
+
out[name] = false;
|
|
1560
|
+
const mainName = aliasToMain.get(name);
|
|
1561
|
+
if (mainName) out[mainName] = false;
|
|
1562
|
+
const aliases = mainToAliases.get(name);
|
|
1563
|
+
if (aliases) for (const alias of aliases) out[alias] = false;
|
|
1564
|
+
}
|
|
1565
|
+
for (const [alias, main2] of aliasToMain.entries()) {
|
|
1566
|
+
if (out[alias] !== void 0 && out[main2] === void 0) out[main2] = out[alias];
|
|
1567
|
+
if (out[main2] !== void 0 && out[alias] === void 0) out[alias] = out[main2];
|
|
1568
|
+
if (out[alias] !== out[main2] && defaults[main2] === out[main2]) out[main2] = out[alias];
|
|
1569
|
+
}
|
|
1570
|
+
return out;
|
|
1571
|
+
}
|
|
1572
|
+
var noColor = /* @__PURE__ */ (() => {
|
|
1573
|
+
const env = globalThis.process?.env ?? {};
|
|
1574
|
+
return env.NO_COLOR === "1" || env.TERM === "dumb" || env.TEST || env.CI;
|
|
1575
|
+
})();
|
|
1576
|
+
var _c = (c3, r3 = 39) => (t3) => noColor ? t3 : `\x1B[${c3}m${t3}\x1B[${r3}m`;
|
|
1577
|
+
var bold = /* @__PURE__ */ _c(1, 22);
|
|
1578
|
+
var cyan = /* @__PURE__ */ _c(36);
|
|
1579
|
+
var gray = /* @__PURE__ */ _c(90);
|
|
1580
|
+
var underline = /* @__PURE__ */ _c(4, 24);
|
|
1581
|
+
function parseArgs(rawArgs, argsDef) {
|
|
1582
|
+
const parseOptions = {
|
|
1583
|
+
boolean: [],
|
|
1584
|
+
string: [],
|
|
1585
|
+
alias: {},
|
|
1586
|
+
default: {}
|
|
1587
|
+
};
|
|
1588
|
+
const args = resolveArgs(argsDef);
|
|
1589
|
+
for (const arg of args) {
|
|
1590
|
+
if (arg.type === "positional") continue;
|
|
1591
|
+
if (arg.type === "string" || arg.type === "enum") parseOptions.string.push(arg.name);
|
|
1592
|
+
else if (arg.type === "boolean") parseOptions.boolean.push(arg.name);
|
|
1593
|
+
if (arg.default !== void 0) parseOptions.default[arg.name] = arg.default;
|
|
1594
|
+
if (arg.alias) parseOptions.alias[arg.name] = arg.alias;
|
|
1595
|
+
const camelName = camelCase(arg.name);
|
|
1596
|
+
const kebabName = kebabCase(arg.name);
|
|
1597
|
+
if (camelName !== arg.name || kebabName !== arg.name) {
|
|
1598
|
+
const existingAliases = toArray(parseOptions.alias[arg.name] || []);
|
|
1599
|
+
if (camelName !== arg.name && !existingAliases.includes(camelName)) existingAliases.push(camelName);
|
|
1600
|
+
if (kebabName !== arg.name && !existingAliases.includes(kebabName)) existingAliases.push(kebabName);
|
|
1601
|
+
if (existingAliases.length > 0) parseOptions.alias[arg.name] = existingAliases;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
const parsed = parseRawArgs(rawArgs, parseOptions);
|
|
1605
|
+
const [...positionalArguments] = parsed._;
|
|
1606
|
+
const parsedArgsProxy = new Proxy(parsed, { get(target, prop) {
|
|
1607
|
+
return target[prop] ?? target[camelCase(prop)] ?? target[kebabCase(prop)];
|
|
1608
|
+
} });
|
|
1609
|
+
for (const [, arg] of args.entries()) if (arg.type === "positional") {
|
|
1610
|
+
const nextPositionalArgument = positionalArguments.shift();
|
|
1611
|
+
if (nextPositionalArgument !== void 0) parsedArgsProxy[arg.name] = nextPositionalArgument;
|
|
1612
|
+
else if (arg.default === void 0 && arg.required !== false) throw new CLIError(`Missing required positional argument: ${arg.name.toUpperCase()}`, "EARG");
|
|
1613
|
+
else parsedArgsProxy[arg.name] = arg.default;
|
|
1614
|
+
} else if (arg.type === "enum") {
|
|
1615
|
+
const argument = parsedArgsProxy[arg.name];
|
|
1616
|
+
const options = arg.options || [];
|
|
1617
|
+
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");
|
|
1618
|
+
} else if (arg.required && parsedArgsProxy[arg.name] === void 0) throw new CLIError(`Missing required argument: --${arg.name}`, "EARG");
|
|
1619
|
+
return parsedArgsProxy;
|
|
1620
|
+
}
|
|
1621
|
+
function resolveArgs(argsDef) {
|
|
1622
|
+
const args = [];
|
|
1623
|
+
for (const [name, argDef] of Object.entries(argsDef || {})) args.push({
|
|
1624
|
+
...argDef,
|
|
1625
|
+
name,
|
|
1626
|
+
alias: toArray(argDef.alias)
|
|
1627
|
+
});
|
|
1628
|
+
return args;
|
|
1629
|
+
}
|
|
1630
|
+
async function resolvePlugins(plugins) {
|
|
1631
|
+
return Promise.all(plugins.map((p2) => resolveValue(p2)));
|
|
1632
|
+
}
|
|
1633
|
+
function defineCommand(def) {
|
|
1634
|
+
return def;
|
|
1635
|
+
}
|
|
1636
|
+
async function runCommand(cmd, opts) {
|
|
1637
|
+
const cmdArgs = await resolveValue(cmd.args || {});
|
|
1638
|
+
const parsedArgs = parseArgs(opts.rawArgs, cmdArgs);
|
|
1639
|
+
const context = {
|
|
1640
|
+
rawArgs: opts.rawArgs,
|
|
1641
|
+
args: parsedArgs,
|
|
1642
|
+
data: opts.data,
|
|
1643
|
+
cmd
|
|
1644
|
+
};
|
|
1645
|
+
const plugins = await resolvePlugins(cmd.plugins ?? []);
|
|
1646
|
+
let result;
|
|
1647
|
+
let runError;
|
|
1648
|
+
try {
|
|
1649
|
+
for (const plugin of plugins) await plugin.setup?.(context);
|
|
1650
|
+
if (typeof cmd.setup === "function") await cmd.setup(context);
|
|
1651
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
1652
|
+
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
1653
|
+
const subCommandArgIndex = findSubCommandIndex(opts.rawArgs, cmdArgs);
|
|
1654
|
+
const explicitName = opts.rawArgs[subCommandArgIndex];
|
|
1655
|
+
if (explicitName) {
|
|
1656
|
+
const subCommand = await _findSubCommand(subCommands, explicitName);
|
|
1657
|
+
if (!subCommand) throw new CLIError(`Unknown command ${cyan(explicitName)}`, "E_UNKNOWN_COMMAND");
|
|
1658
|
+
await runCommand(subCommand, { rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1) });
|
|
1659
|
+
} else {
|
|
1660
|
+
const defaultSubCommand = await resolveValue(cmd.default);
|
|
1661
|
+
if (defaultSubCommand) {
|
|
1662
|
+
if (cmd.run) throw new CLIError(`Cannot specify both 'run' and 'default' on the same command.`, "E_DEFAULT_CONFLICT");
|
|
1663
|
+
const subCommand = await _findSubCommand(subCommands, defaultSubCommand);
|
|
1664
|
+
if (!subCommand) throw new CLIError(`Default sub command ${cyan(defaultSubCommand)} not found in subCommands.`, "E_UNKNOWN_COMMAND");
|
|
1665
|
+
await runCommand(subCommand, { rawArgs: opts.rawArgs });
|
|
1666
|
+
} else if (!cmd.run) throw new CLIError(`No command specified.`, "E_NO_COMMAND");
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
if (typeof cmd.run === "function") result = await cmd.run(context);
|
|
1670
|
+
} catch (error) {
|
|
1671
|
+
runError = error;
|
|
1672
|
+
}
|
|
1673
|
+
const cleanupErrors = [];
|
|
1674
|
+
if (typeof cmd.cleanup === "function") try {
|
|
1675
|
+
await cmd.cleanup(context);
|
|
1676
|
+
} catch (error) {
|
|
1677
|
+
cleanupErrors.push(error);
|
|
1678
|
+
}
|
|
1679
|
+
for (const plugin of [...plugins].reverse()) try {
|
|
1680
|
+
await plugin.cleanup?.(context);
|
|
1681
|
+
} catch (error) {
|
|
1682
|
+
cleanupErrors.push(error);
|
|
1683
|
+
}
|
|
1684
|
+
if (runError) throw runError;
|
|
1685
|
+
if (cleanupErrors.length === 1) throw cleanupErrors[0];
|
|
1686
|
+
if (cleanupErrors.length > 1) throw new Error("Multiple cleanup errors", { cause: cleanupErrors });
|
|
1687
|
+
return { result };
|
|
1688
|
+
}
|
|
1689
|
+
async function resolveSubCommand(cmd, rawArgs, parent) {
|
|
1690
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
1691
|
+
if (subCommands && Object.keys(subCommands).length > 0) {
|
|
1692
|
+
const subCommandArgIndex = findSubCommandIndex(rawArgs, await resolveValue(cmd.args || {}));
|
|
1693
|
+
const subCommandName = rawArgs[subCommandArgIndex];
|
|
1694
|
+
const subCommand = await _findSubCommand(subCommands, subCommandName);
|
|
1695
|
+
if (subCommand) return resolveSubCommand(subCommand, rawArgs.slice(subCommandArgIndex + 1), cmd);
|
|
1696
|
+
}
|
|
1697
|
+
return [cmd, parent];
|
|
1698
|
+
}
|
|
1699
|
+
async function _findSubCommand(subCommands, name) {
|
|
1700
|
+
if (name in subCommands) return resolveValue(subCommands[name]);
|
|
1701
|
+
for (const sub of Object.values(subCommands)) {
|
|
1702
|
+
const resolved = await resolveValue(sub);
|
|
1703
|
+
const meta = await resolveValue(resolved?.meta);
|
|
1704
|
+
if (meta?.alias) {
|
|
1705
|
+
if (toArray(meta.alias).includes(name)) return resolved;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
function findSubCommandIndex(rawArgs, argsDef) {
|
|
1710
|
+
for (let i3 = 0; i3 < rawArgs.length; i3++) {
|
|
1711
|
+
const arg = rawArgs[i3];
|
|
1712
|
+
if (arg === "--") return -1;
|
|
1713
|
+
if (arg.startsWith("-")) {
|
|
1714
|
+
if (!arg.includes("=") && _isValueFlag(arg, argsDef)) i3++;
|
|
1715
|
+
continue;
|
|
1716
|
+
}
|
|
1717
|
+
return i3;
|
|
1718
|
+
}
|
|
1719
|
+
return -1;
|
|
1720
|
+
}
|
|
1721
|
+
function _isValueFlag(flag, argsDef) {
|
|
1722
|
+
const name = flag.replace(/^-{1,2}/, "");
|
|
1723
|
+
const normalized = camelCase(name);
|
|
1724
|
+
for (const [key, def] of Object.entries(argsDef)) {
|
|
1725
|
+
if (def.type !== "string" && def.type !== "enum") continue;
|
|
1726
|
+
if (normalized === camelCase(key)) return true;
|
|
1727
|
+
if ((Array.isArray(def.alias) ? def.alias : def.alias ? [def.alias] : []).includes(name)) return true;
|
|
1728
|
+
}
|
|
1729
|
+
return false;
|
|
1730
|
+
}
|
|
1731
|
+
async function showUsage(cmd, parent) {
|
|
1732
|
+
try {
|
|
1733
|
+
console.log(await renderUsage(cmd, parent) + "\n");
|
|
1734
|
+
} catch (error) {
|
|
1735
|
+
console.error(error);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
var negativePrefixRe = /^no[-A-Z]/;
|
|
1739
|
+
async function renderUsage(cmd, parent) {
|
|
1740
|
+
const cmdMeta = await resolveValue(cmd.meta || {});
|
|
1741
|
+
const cmdArgs = resolveArgs(await resolveValue(cmd.args || {}));
|
|
1742
|
+
const parentMeta = await resolveValue(parent?.meta || {});
|
|
1743
|
+
const commandName = `${parentMeta.name ? `${parentMeta.name} ` : ""}` + (cmdMeta.name || process.argv[1]);
|
|
1744
|
+
const argLines = [];
|
|
1745
|
+
const posLines = [];
|
|
1746
|
+
const commandsLines = [];
|
|
1747
|
+
const usageLine = [];
|
|
1748
|
+
for (const arg of cmdArgs) if (arg.type === "positional") {
|
|
1749
|
+
const name = arg.name.toUpperCase();
|
|
1750
|
+
const isRequired = arg.required !== false && arg.default === void 0;
|
|
1751
|
+
posLines.push([cyan(name + renderValueHint(arg)), renderDescription(arg, isRequired)]);
|
|
1752
|
+
usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
|
|
1753
|
+
} else {
|
|
1754
|
+
const isRequired = arg.required === true && arg.default === void 0;
|
|
1755
|
+
const argStr = [...(arg.alias || []).map((a3) => `-${a3}`), `--${arg.name}`].join(", ") + renderValueHint(arg);
|
|
1756
|
+
argLines.push([cyan(argStr), renderDescription(arg, isRequired)]);
|
|
1757
|
+
if (arg.type === "boolean" && (arg.default === true || arg.negativeDescription) && !negativePrefixRe.test(arg.name)) {
|
|
1758
|
+
const negativeArgStr = [...(arg.alias || []).map((a3) => `--no-${a3}`), `--no-${arg.name}`].join(", ");
|
|
1759
|
+
argLines.push([cyan(negativeArgStr), [arg.negativeDescription, isRequired ? gray("(Required)") : ""].filter(Boolean).join(" ")]);
|
|
1760
|
+
}
|
|
1761
|
+
if (isRequired) usageLine.push(`--${arg.name}` + renderValueHint(arg));
|
|
1762
|
+
}
|
|
1763
|
+
if (cmd.subCommands) {
|
|
1764
|
+
const commandNames = [];
|
|
1765
|
+
const subCommands = await resolveValue(cmd.subCommands);
|
|
1766
|
+
for (const [name, sub] of Object.entries(subCommands)) {
|
|
1767
|
+
const meta = await resolveValue((await resolveValue(sub))?.meta);
|
|
1768
|
+
if (meta?.hidden) continue;
|
|
1769
|
+
const aliases = toArray(meta?.alias);
|
|
1770
|
+
const label = [name, ...aliases].join(", ");
|
|
1771
|
+
commandsLines.push([cyan(label), meta?.description || ""]);
|
|
1772
|
+
commandNames.push(name, ...aliases);
|
|
1773
|
+
}
|
|
1774
|
+
usageLine.push(commandNames.join("|"));
|
|
1807
1775
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1776
|
+
const usageLines = [];
|
|
1777
|
+
const version = cmdMeta.version || parentMeta.version;
|
|
1778
|
+
usageLines.push(gray(`${cmdMeta.description} (${commandName + (version ? ` v${version}` : "")})`), "");
|
|
1779
|
+
const hasOptions = argLines.length > 0 || posLines.length > 0;
|
|
1780
|
+
usageLines.push(`${underline(bold("USAGE"))} ${cyan(`${commandName}${hasOptions ? " [OPTIONS]" : ""} ${usageLine.join(" ")}`)}`, "");
|
|
1781
|
+
if (posLines.length > 0) {
|
|
1782
|
+
usageLines.push(underline(bold("ARGUMENTS")), "");
|
|
1783
|
+
usageLines.push(formatLineColumns(posLines, " "));
|
|
1784
|
+
usageLines.push("");
|
|
1813
1785
|
}
|
|
1814
|
-
if (
|
|
1815
|
-
|
|
1786
|
+
if (argLines.length > 0) {
|
|
1787
|
+
usageLines.push(underline(bold("OPTIONS")), "");
|
|
1788
|
+
usageLines.push(formatLineColumns(argLines, " "));
|
|
1789
|
+
usageLines.push("");
|
|
1816
1790
|
}
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1791
|
+
if (commandsLines.length > 0) {
|
|
1792
|
+
usageLines.push(underline(bold("COMMANDS")), "");
|
|
1793
|
+
usageLines.push(formatLineColumns(commandsLines, " "));
|
|
1794
|
+
usageLines.push("", `Use ${cyan(`${commandName} <command> --help`)} for more information about a command.`);
|
|
1820
1795
|
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1796
|
+
return usageLines.filter((l3) => typeof l3 === "string").join("\n");
|
|
1797
|
+
}
|
|
1798
|
+
function renderValueHint(arg) {
|
|
1799
|
+
const valueHint = arg.valueHint ? `=<${arg.valueHint}>` : "";
|
|
1800
|
+
const fallbackValueHint = valueHint || `=<${snakeCase(arg.name)}>`;
|
|
1801
|
+
if (!arg.type || arg.type === "positional" || arg.type === "boolean") return valueHint;
|
|
1802
|
+
if (arg.type === "enum" && arg.options?.length) return `=<${arg.options.join("|")}>`;
|
|
1803
|
+
return fallbackValueHint;
|
|
1804
|
+
}
|
|
1805
|
+
function renderDescription(arg, required) {
|
|
1806
|
+
const requiredHint = required ? gray("(Required)") : "";
|
|
1807
|
+
const defaultHint = arg.default === void 0 ? "" : gray(`(Default: ${arg.default})`);
|
|
1808
|
+
return [
|
|
1809
|
+
arg.description,
|
|
1810
|
+
requiredHint,
|
|
1811
|
+
defaultHint
|
|
1812
|
+
].filter(Boolean).join(" ");
|
|
1813
|
+
}
|
|
1814
|
+
async function runMain(cmd, opts = {}) {
|
|
1815
|
+
const rawArgs = opts.rawArgs || process.argv.slice(2);
|
|
1816
|
+
const showUsage$1 = opts.showUsage || showUsage;
|
|
1817
|
+
try {
|
|
1818
|
+
const builtinFlags = await _resolveBuiltinFlags(cmd);
|
|
1819
|
+
if (builtinFlags.help.length > 0 && rawArgs.some((arg) => builtinFlags.help.includes(arg))) {
|
|
1820
|
+
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
1821
|
+
process.exit(0);
|
|
1822
|
+
} else if (rawArgs.length === 1 && builtinFlags.version.includes(rawArgs[0])) {
|
|
1823
|
+
const meta = typeof cmd.meta === "function" ? await cmd.meta() : await cmd.meta;
|
|
1824
|
+
if (!meta?.version) throw new CLIError("No version specified", "E_NO_VERSION");
|
|
1825
|
+
console.log(meta.version);
|
|
1826
|
+
} else await runCommand(cmd, { rawArgs });
|
|
1827
|
+
} catch (error) {
|
|
1828
|
+
if (error instanceof CLIError) {
|
|
1829
|
+
await showUsage$1(...await resolveSubCommand(cmd, rawArgs));
|
|
1830
|
+
console.error(error.message);
|
|
1831
|
+
} else console.error(error, "\n");
|
|
1832
|
+
process.exit(1);
|
|
1825
1833
|
}
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1834
|
+
}
|
|
1835
|
+
async function _resolveBuiltinFlags(cmd) {
|
|
1836
|
+
const argsDef = await resolveValue(cmd.args || {});
|
|
1837
|
+
const userNames = /* @__PURE__ */ new Set();
|
|
1838
|
+
const userAliases = /* @__PURE__ */ new Set();
|
|
1839
|
+
for (const [name, def] of Object.entries(argsDef)) {
|
|
1840
|
+
userNames.add(name);
|
|
1841
|
+
for (const alias of toArray(def.alias)) userAliases.add(alias);
|
|
1833
1842
|
}
|
|
1834
|
-
return
|
|
1843
|
+
return {
|
|
1844
|
+
help: _getBuiltinFlags("help", "h", userNames, userAliases),
|
|
1845
|
+
version: _getBuiltinFlags("version", "v", userNames, userAliases)
|
|
1846
|
+
};
|
|
1835
1847
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1848
|
+
function _getBuiltinFlags(long, short, userNames, userAliases) {
|
|
1849
|
+
if (userNames.has(long) || userAliases.has(long)) return [];
|
|
1850
|
+
if (userNames.has(short) || userAliases.has(short)) return [`--${long}`];
|
|
1851
|
+
return [`--${long}`, `-${short}`];
|
|
1838
1852
|
}
|
|
1853
|
+
|
|
1854
|
+
// package.json
|
|
1855
|
+
var package_default = {
|
|
1856
|
+
name: "zapdev",
|
|
1857
|
+
version: "1.13.0",
|
|
1858
|
+
description: "Fast, performant and lightweight git chores and dev tools using your terminal and an OpenAI-compatible LLM endpoint.",
|
|
1859
|
+
type: "module",
|
|
1860
|
+
bin: {
|
|
1861
|
+
zapdev: "./dist/index.js"
|
|
1862
|
+
},
|
|
1863
|
+
files: [
|
|
1864
|
+
"dist"
|
|
1865
|
+
],
|
|
1866
|
+
engines: {
|
|
1867
|
+
node: ">=20"
|
|
1868
|
+
},
|
|
1869
|
+
keywords: [
|
|
1870
|
+
"git",
|
|
1871
|
+
"cli",
|
|
1872
|
+
"commit",
|
|
1873
|
+
"conventional-commits",
|
|
1874
|
+
"llm",
|
|
1875
|
+
"ai"
|
|
1876
|
+
],
|
|
1877
|
+
author: "Matthieu Vagnon <hi@mvagnon.dev>",
|
|
1878
|
+
license: "MIT",
|
|
1879
|
+
repository: {
|
|
1880
|
+
type: "git",
|
|
1881
|
+
url: "git+https://github.com/mvagnon/zapdev.git"
|
|
1882
|
+
},
|
|
1883
|
+
homepage: "https://github.com/mvagnon/zapdev#readme",
|
|
1884
|
+
bugs: {
|
|
1885
|
+
url: "https://github.com/mvagnon/zapdev/issues"
|
|
1886
|
+
},
|
|
1887
|
+
publishConfig: {
|
|
1888
|
+
access: "public"
|
|
1889
|
+
},
|
|
1890
|
+
scripts: {
|
|
1891
|
+
zapdev: "npm run build && node dist/index.js",
|
|
1892
|
+
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",
|
|
1893
|
+
lint: "eslint .",
|
|
1894
|
+
typecheck: "tsc --noEmit",
|
|
1895
|
+
test: "vitest run",
|
|
1896
|
+
prepack: "npm run build"
|
|
1897
|
+
},
|
|
1898
|
+
devDependencies: {
|
|
1899
|
+
"@clack/prompts": "^1.6.0",
|
|
1900
|
+
"@eslint/js": "^10.0.1",
|
|
1901
|
+
"@eslint/json": "^2.0.0",
|
|
1902
|
+
"@eslint/markdown": "^8.0.2",
|
|
1903
|
+
"@types/node": "^26.1.1",
|
|
1904
|
+
citty: "^0.2.2",
|
|
1905
|
+
esbuild: "^0.28.1",
|
|
1906
|
+
eslint: "^10.6.0",
|
|
1907
|
+
jiti: "^2.7.0",
|
|
1908
|
+
tinyexec: "^1.2.4",
|
|
1909
|
+
typescript: "^6.0.3",
|
|
1910
|
+
"typescript-eslint": "^8.62.1",
|
|
1911
|
+
vitest: "^4.1.9"
|
|
1912
|
+
}
|
|
1913
|
+
};
|
|
1914
|
+
|
|
1915
|
+
// src/commands/commit.ts
|
|
1916
|
+
import { basename } from "node:path";
|
|
1917
|
+
import { styleText as styleText4 } from "node:util";
|
|
1918
|
+
|
|
1919
|
+
// src/lib/config.ts
|
|
1839
1920
|
function resolveHookTimeout(env = process.env) {
|
|
1840
1921
|
const timeout = Number(env.ZD_HOOK_TIMEOUT ?? 60) * 1e3;
|
|
1841
1922
|
if (!Number.isFinite(timeout) || timeout < 1 || timeout > 2147483647) {
|
|
@@ -1867,7 +1948,7 @@ function resolveConfig(env = process.env, overrides = {}) {
|
|
|
1867
1948
|
// src/lib/git.ts
|
|
1868
1949
|
import { execFileSync } from "node:child_process";
|
|
1869
1950
|
import { readdir } from "node:fs/promises";
|
|
1870
|
-
import { join
|
|
1951
|
+
import { join } from "node:path";
|
|
1871
1952
|
import { createInterface as createInterface2 } from "node:readline";
|
|
1872
1953
|
import { Readable } from "node:stream";
|
|
1873
1954
|
|
|
@@ -2197,6 +2278,18 @@ var R2 = (e2, t3, n4) => {
|
|
|
2197
2278
|
};
|
|
2198
2279
|
var z = R2;
|
|
2199
2280
|
|
|
2281
|
+
// src/lib/errors.ts
|
|
2282
|
+
var GitOutputError = class extends Error {
|
|
2283
|
+
constructor(message, hookFailureReported = false) {
|
|
2284
|
+
super(message);
|
|
2285
|
+
this.hookFailureReported = hookFailureReported;
|
|
2286
|
+
}
|
|
2287
|
+
hookFailureReported;
|
|
2288
|
+
};
|
|
2289
|
+
function errorMessage(error) {
|
|
2290
|
+
return error instanceof Error ? error.message : String(error);
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2200
2293
|
// src/lib/git-hooks.ts
|
|
2201
2294
|
function createHookReporter(onHook, onTimeout, timeout) {
|
|
2202
2295
|
const hooks = /* @__PURE__ */ new Map();
|
|
@@ -2233,19 +2326,23 @@ function createHookReporter(onHook, onTimeout, timeout) {
|
|
|
2233
2326
|
}
|
|
2234
2327
|
|
|
2235
2328
|
// src/lib/git.ts
|
|
2236
|
-
async function git(args, cwd, onHook,
|
|
2329
|
+
async function git(args, cwd, onHook, onOutput) {
|
|
2237
2330
|
const timeout = resolveHookTimeout();
|
|
2238
|
-
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY && ["commit", "
|
|
2331
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY && ["commit", "pull", "push"].includes(args[0] ?? ""));
|
|
2239
2332
|
const terminalState = interactive && process.platform !== "win32" ? execFileSync("stty", ["-g"], { stdio: ["inherit", "pipe", "ignore"], encoding: "utf8" }).trim() : void 0;
|
|
2240
|
-
if (interactive) onNativeOutput?.("start");
|
|
2241
2333
|
const child = R2("git", args, {
|
|
2242
2334
|
nodeOptions: {
|
|
2243
2335
|
cwd,
|
|
2244
2336
|
detached: !interactive && process.platform !== "win32",
|
|
2245
2337
|
env: { ...process.env, GIT_TRACE2_EVENT: "3" },
|
|
2246
|
-
stdio: interactive ? ["inherit",
|
|
2338
|
+
stdio: interactive ? ["inherit", onOutput ? "pipe" : "inherit", onOutput ? "pipe" : "inherit", "pipe"] : ["pipe", "pipe", "pipe", "pipe"]
|
|
2247
2339
|
}
|
|
2248
2340
|
});
|
|
2341
|
+
if (onOutput) {
|
|
2342
|
+
for (const stream of ["stdout", "stderr"]) {
|
|
2343
|
+
child.process?.[stream]?.setEncoding("utf8").on("data", (chunk) => onOutput(chunk, stream));
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2249
2346
|
let timeoutError;
|
|
2250
2347
|
let hookFailureReported = false;
|
|
2251
2348
|
const { report, close } = createHookReporter((event) => {
|
|
@@ -2273,18 +2370,14 @@ async function git(args, cwd, onHook, onNativeOutput) {
|
|
|
2273
2370
|
if (timeoutError) throw timeoutError;
|
|
2274
2371
|
if (result.exitCode !== 0) {
|
|
2275
2372
|
const message = result.stderr.trim() || `git ${args.join(" ")} failed`;
|
|
2276
|
-
if (interactive) throw new GitOutputError(message, hookFailureReported);
|
|
2373
|
+
if (interactive || onOutput) throw new GitOutputError(message, hookFailureReported);
|
|
2277
2374
|
throw new Error(message);
|
|
2278
2375
|
}
|
|
2279
2376
|
return result.stdout;
|
|
2280
2377
|
} finally {
|
|
2281
2378
|
reader?.close();
|
|
2282
2379
|
close();
|
|
2283
|
-
|
|
2284
|
-
if (terminalState) execFileSync("stty", [terminalState], { stdio: ["inherit", "ignore", "ignore"] });
|
|
2285
|
-
} finally {
|
|
2286
|
-
if (interactive) onNativeOutput?.("exit");
|
|
2287
|
-
}
|
|
2380
|
+
if (terminalState) execFileSync("stty", [terminalState], { stdio: ["inherit", "ignore", "ignore"] });
|
|
2288
2381
|
}
|
|
2289
2382
|
}
|
|
2290
2383
|
function killProcessTree(pid) {
|
|
@@ -2317,8 +2410,18 @@ async function stageAll(repo) {
|
|
|
2317
2410
|
async function getStagedDiff(repo) {
|
|
2318
2411
|
return git(["diff", "--cached"], repo);
|
|
2319
2412
|
}
|
|
2320
|
-
async function
|
|
2321
|
-
await git(["
|
|
2413
|
+
async function getStagedDiffStats(repo) {
|
|
2414
|
+
const output = await git(["diff", "--cached", "--numstat"], repo);
|
|
2415
|
+
const stats = { additions: 0, deletions: 0 };
|
|
2416
|
+
for (const line of output.trim().split("\n")) {
|
|
2417
|
+
const [additions, deletions] = line.split(" ");
|
|
2418
|
+
stats.additions += Number(additions) || 0;
|
|
2419
|
+
stats.deletions += Number(deletions) || 0;
|
|
2420
|
+
}
|
|
2421
|
+
return stats;
|
|
2422
|
+
}
|
|
2423
|
+
async function commit(repo, message, onHook, onOutput) {
|
|
2424
|
+
await git(["commit", "--quiet", "-m", message], repo, onHook, onOutput);
|
|
2322
2425
|
}
|
|
2323
2426
|
async function currentBranch(repo) {
|
|
2324
2427
|
return (await git(["symbolic-ref", "--short", "HEAD"], repo)).trim();
|
|
@@ -2326,8 +2429,8 @@ async function currentBranch(repo) {
|
|
|
2326
2429
|
async function switchBranch(repo, branch) {
|
|
2327
2430
|
await git(["check-ref-format", "--branch", branch], repo);
|
|
2328
2431
|
await git(["check-ref-format", `refs/heads/${branch}`], repo);
|
|
2329
|
-
const
|
|
2330
|
-
await git(
|
|
2432
|
+
const exists = await tryGit(["show-ref", "--verify", "--quiet", `refs/heads/${branch}`], repo) !== null;
|
|
2433
|
+
await git(exists ? ["switch", "--no-guess", "--", branch] : ["switch", "--no-track", "-c", branch], repo);
|
|
2331
2434
|
}
|
|
2332
2435
|
async function getRepoStatus(repo) {
|
|
2333
2436
|
const lines = (await git(["status", "--porcelain=v2", "--branch", "--untracked-files=normal"], repo)).trim().split("\n");
|
|
@@ -2343,20 +2446,9 @@ async function getPushRemote(repo, branch) {
|
|
|
2343
2446
|
if (upstream) return remotes.includes(upstream) ? upstream : null;
|
|
2344
2447
|
return remotes.length === 1 ? remotes[0] : null;
|
|
2345
2448
|
}
|
|
2346
|
-
async function push(repo, remote, branch, onHook,
|
|
2449
|
+
async function push(repo, remote, branch, onHook, onOutput) {
|
|
2347
2450
|
await git(["check-ref-format", "--branch", branch], repo);
|
|
2348
|
-
await git(
|
|
2349
|
-
}
|
|
2350
|
-
async function hasUnpushedCommits(repo, remote, branch, onHook, prefix, onNativeOutput) {
|
|
2351
|
-
if (await tryGit(["rev-parse", "--verify", "HEAD"], repo) === null) return false;
|
|
2352
|
-
await git(["check-ref-format", "--branch", branch], repo);
|
|
2353
|
-
const source = prefix ? (await git(["subtree", "split", `--prefix=${prefix}`, "--quiet", "HEAD"], repo)).trim() : "HEAD";
|
|
2354
|
-
const ref = `refs/heads/${branch}`;
|
|
2355
|
-
const refs = new Set((await git(["ls-remote", "--", remote, ref, "HEAD"], repo, onHook, onNativeOutput)).trim().split("\n").map((line) => line.split(" ")[1]));
|
|
2356
|
-
const target = refs.has(ref) ? ref : refs.has("HEAD") ? "HEAD" : null;
|
|
2357
|
-
if (!target) return true;
|
|
2358
|
-
await git(["fetch", "--quiet", "--", remote, target], repo, onHook, onNativeOutput);
|
|
2359
|
-
return Boolean((await git(["rev-list", "--max-count=1", `FETCH_HEAD..${source}`], repo)).trim());
|
|
2451
|
+
await git(["push", "--", remote, `HEAD:refs/heads/${branch}`], repo, onHook, onOutput);
|
|
2360
2452
|
}
|
|
2361
2453
|
async function findRepos(path) {
|
|
2362
2454
|
const root = await repoRoot(path);
|
|
@@ -2364,7 +2456,7 @@ async function findRepos(path) {
|
|
|
2364
2456
|
const entries = await readdir(path, { withFileTypes: true }).catch(() => null);
|
|
2365
2457
|
if (!entries) return [];
|
|
2366
2458
|
const dirs = entries.filter((entry) => entry.isDirectory() && entry.name !== "node_modules");
|
|
2367
|
-
const repos = await Promise.all(dirs.map((entry) => repoRoot(
|
|
2459
|
+
const repos = await Promise.all(dirs.map((entry) => repoRoot(join(path, entry.name))));
|
|
2368
2460
|
return repos.filter((dir) => dir !== null).sort();
|
|
2369
2461
|
}
|
|
2370
2462
|
async function repoRoot(dir) {
|
|
@@ -2490,12 +2582,41 @@ var COMMIT_TYPES = [
|
|
|
2490
2582
|
"revert"
|
|
2491
2583
|
];
|
|
2492
2584
|
|
|
2493
|
-
// src/commands/
|
|
2585
|
+
// src/commands/git-task.ts
|
|
2494
2586
|
import { styleText as styleText3 } from "node:util";
|
|
2495
|
-
|
|
2496
|
-
const
|
|
2497
|
-
|
|
2498
|
-
|
|
2587
|
+
async function runGitTask(label, operation, successMessage, run) {
|
|
2588
|
+
const title = `${label}: ${operation}`;
|
|
2589
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2590
|
+
let task;
|
|
2591
|
+
const onOutput = (chunk, stream) => {
|
|
2592
|
+
if (!interactive) {
|
|
2593
|
+
process[stream].write(chunk);
|
|
2594
|
+
return;
|
|
2595
|
+
}
|
|
2596
|
+
task ??= taskLog({ title, limit: 10, retainLog: true });
|
|
2597
|
+
task.message(chunk, { raw: true });
|
|
2598
|
+
};
|
|
2599
|
+
const onHook = (event) => {
|
|
2600
|
+
const hook = `${label}: ${event.name}`;
|
|
2601
|
+
const message = event.phase === "start" ? hook : `${hook}: ${event.exitCode === 0 ? "completed" : `failed (exit ${event.exitCode})`}`;
|
|
2602
|
+
if (task) task.message(message);
|
|
2603
|
+
else if (event.phase === "start") log.step(styleText3("bold", message));
|
|
2604
|
+
else if (event.exitCode === 0) log.success(message);
|
|
2605
|
+
else log.error(message);
|
|
2606
|
+
};
|
|
2607
|
+
log.info(title);
|
|
2608
|
+
try {
|
|
2609
|
+
await run(onHook, onOutput);
|
|
2610
|
+
if (task) task.success(successMessage, { showLog: true });
|
|
2611
|
+
else log.success(successMessage);
|
|
2612
|
+
return true;
|
|
2613
|
+
} catch (error) {
|
|
2614
|
+
const message = `${label}: ${operation} failed${error instanceof GitOutputError ? "" : `: ${errorMessage(error)}`}`;
|
|
2615
|
+
if (task) task.error(message);
|
|
2616
|
+
else if (!(error instanceof GitOutputError && error.hookFailureReported)) log.error(message);
|
|
2617
|
+
return false;
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2499
2620
|
|
|
2500
2621
|
// src/commands/commit.ts
|
|
2501
2622
|
var commitCommand = defineCommand({
|
|
@@ -2528,6 +2649,10 @@ var commitCommand = defineCommand({
|
|
|
2528
2649
|
alias: "p",
|
|
2529
2650
|
description: "Skip push confirmation and push the current branch."
|
|
2530
2651
|
},
|
|
2652
|
+
pull: {
|
|
2653
|
+
type: "boolean",
|
|
2654
|
+
description: "Pull fast-forward updates before staging or generating commit messages."
|
|
2655
|
+
},
|
|
2531
2656
|
staged: {
|
|
2532
2657
|
type: "boolean",
|
|
2533
2658
|
alias: "s",
|
|
@@ -2542,7 +2667,6 @@ var commitCommand = defineCommand({
|
|
|
2542
2667
|
async run({ args }) {
|
|
2543
2668
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2544
2669
|
let config;
|
|
2545
|
-
let subtrees;
|
|
2546
2670
|
try {
|
|
2547
2671
|
resolveHookTimeout();
|
|
2548
2672
|
config = resolveConfig(process.env, {
|
|
@@ -2550,13 +2674,11 @@ var commitCommand = defineCommand({
|
|
|
2550
2674
|
model: args.model,
|
|
2551
2675
|
effort: args.effort
|
|
2552
2676
|
});
|
|
2553
|
-
subtrees = await resolveSubtrees(process.cwd());
|
|
2554
2677
|
} catch (error) {
|
|
2555
2678
|
log.error(errorMessage(error));
|
|
2556
2679
|
process.exitCode = 1;
|
|
2557
2680
|
return;
|
|
2558
2681
|
}
|
|
2559
|
-
const publishSubtreeMode = Object.keys(subtrees).length > 0;
|
|
2560
2682
|
if (interactive) intro("zapdev commit");
|
|
2561
2683
|
const repos = await findRepos(process.cwd());
|
|
2562
2684
|
if (repos.length === 0) {
|
|
@@ -2564,6 +2686,15 @@ var commitCommand = defineCommand({
|
|
|
2564
2686
|
if (interactive) outro("Nothing to do.");
|
|
2565
2687
|
return;
|
|
2566
2688
|
}
|
|
2689
|
+
if (args.pull) {
|
|
2690
|
+
for (const repo of repos) {
|
|
2691
|
+
const label = basename(repo);
|
|
2692
|
+
if (!await runGitTask(label, "pull", `${label}: pulled`, (onHook, onOutput) => git(["pull", "--ff-only", "--no-rebase", "--no-autostash"], repo, onHook, onOutput))) {
|
|
2693
|
+
process.exitCode = 1;
|
|
2694
|
+
return;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2567
2698
|
let scan;
|
|
2568
2699
|
try {
|
|
2569
2700
|
scan = await hasGitleaks();
|
|
@@ -2580,14 +2711,15 @@ var commitCommand = defineCommand({
|
|
|
2580
2711
|
const { repo } = repository;
|
|
2581
2712
|
const { branch, hasChanges } = await getRepoStatus(repo);
|
|
2582
2713
|
repository.label = `${basename(repo)} (${branch})`;
|
|
2583
|
-
repository.pendingLabel = hasChanges ? styleText4(
|
|
2714
|
+
repository.pendingLabel = hasChanges ? styleText4("bold", repository.label) : repository.label;
|
|
2584
2715
|
if (!args.staged) await stageAll(repo);
|
|
2585
2716
|
const diff = await getStagedDiff(repo);
|
|
2586
2717
|
if (!diff.trim()) return null;
|
|
2718
|
+
const stats = await getStagedDiffStats(repo);
|
|
2587
2719
|
if (scan) await scanStagedChanges(repo);
|
|
2588
2720
|
const message = await generateCommitMessage(diff, config, args.type);
|
|
2589
2721
|
if (!message) throw new Error("The model returned an empty message.");
|
|
2590
|
-
return { ...repository, message };
|
|
2722
|
+
return { ...repository, message, stats };
|
|
2591
2723
|
}));
|
|
2592
2724
|
loader?.stop("Repositories prepared");
|
|
2593
2725
|
const drafts = [];
|
|
@@ -2628,13 +2760,14 @@ var commitCommand = defineCommand({
|
|
|
2628
2760
|
if (branch !== current) {
|
|
2629
2761
|
await switchBranch(draft.repo, branch);
|
|
2630
2762
|
draft.label = `${basename(draft.repo)} (${branch})`;
|
|
2631
|
-
draft.pendingLabel = styleText4(
|
|
2763
|
+
draft.pendingLabel = styleText4("bold", draft.label);
|
|
2632
2764
|
}
|
|
2633
2765
|
}
|
|
2634
|
-
|
|
2635
|
-
|
|
2766
|
+
if (!await runGitTask(draft.label, "commit", `${draft.label}: committed ${draft.message}`, (onHook, onOutput) => commit(draft.repo, draft.message, onHook, onOutput))) {
|
|
2767
|
+
process.exitCode = 1;
|
|
2768
|
+
continue;
|
|
2769
|
+
}
|
|
2636
2770
|
toSend.push(draft);
|
|
2637
|
-
log.success(`${draft.label}: committed ${draft.message}`);
|
|
2638
2771
|
} catch (error) {
|
|
2639
2772
|
reportGitFailure(`${draft.pendingLabel}: commit failed`, error);
|
|
2640
2773
|
process.exitCode = 1;
|
|
@@ -2642,39 +2775,35 @@ var commitCommand = defineCommand({
|
|
|
2642
2775
|
}
|
|
2643
2776
|
toSend.push(...unchanged);
|
|
2644
2777
|
if (toSend.length === 0) return;
|
|
2778
|
+
if (!interactive && !args.push) return;
|
|
2779
|
+
const destinations = [];
|
|
2780
|
+
for (const { repo, label } of toSend) {
|
|
2781
|
+
try {
|
|
2782
|
+
const branch = await currentBranch(repo);
|
|
2783
|
+
const remote = await getPushRemote(repo, branch);
|
|
2784
|
+
if (remote) destinations.push({ repo, label, branch, remote });
|
|
2785
|
+
else log.warn(`${label}: no remote or ambiguous remote choice. Skipping push; commit remains local.`);
|
|
2786
|
+
} catch (error) {
|
|
2787
|
+
reportGitFailure(`${label}: push failed`, error);
|
|
2788
|
+
process.exitCode = 1;
|
|
2789
|
+
return;
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2645
2792
|
let shouldPush = Boolean(args.push);
|
|
2646
|
-
if (!shouldPush && interactive) {
|
|
2793
|
+
if (!shouldPush && interactive && destinations.length) {
|
|
2647
2794
|
const answer = await confirm({
|
|
2648
|
-
message:
|
|
2795
|
+
message: `Push ${destinations.map(({ label }) => label).join(", ")}?`,
|
|
2649
2796
|
initialValue: false
|
|
2650
2797
|
});
|
|
2651
2798
|
if (isCancel(answer)) {
|
|
2652
|
-
outro(
|
|
2799
|
+
outro("Committed. Not pushed.");
|
|
2653
2800
|
return;
|
|
2654
2801
|
}
|
|
2655
2802
|
shouldPush = answer;
|
|
2656
2803
|
}
|
|
2657
2804
|
if (shouldPush) {
|
|
2658
|
-
for (const { repo, label } of
|
|
2659
|
-
|
|
2660
|
-
const current = await currentBranch(repo);
|
|
2661
|
-
const destinations = publishSubtreeMode ? Object.entries(subtrees) : [["", await getPushRemote(repo, current)]];
|
|
2662
|
-
for (const [prefix, remote] of destinations) {
|
|
2663
|
-
if (!remote) {
|
|
2664
|
-
log.warn(`${label}: no remote or ambiguous remote choice. Skipping push; commit remains local.`);
|
|
2665
|
-
continue;
|
|
2666
|
-
}
|
|
2667
|
-
log.info(`${label}: checking unpublished commits${prefix ? ` in ${prefix}` : ""} (${remote}/${current}).`);
|
|
2668
|
-
if (!await hasUnpushedCommits(repo, remote, current, reportHooks(label), prefix || void 0, reportNativeOutput)) {
|
|
2669
|
-
log.info(`${label}: no unpushed commits${prefix ? ` in ${prefix}` : ""}. Skipping.`);
|
|
2670
|
-
continue;
|
|
2671
|
-
}
|
|
2672
|
-
log.info(`${label}: pushing ${publishSubtreeMode ? `${prefix} \u2192 ` : ""}${remote}/${current}`);
|
|
2673
|
-
await push(repo, remote, current, reportHooks(label), prefix || void 0, reportNativeOutput);
|
|
2674
|
-
log.success(`${label}: pushed to ${remote}/${current}`);
|
|
2675
|
-
}
|
|
2676
|
-
} catch (error) {
|
|
2677
|
-
reportGitFailure(`${label}: ${publishSubtreeMode ? "publication" : "push"} failed`, error);
|
|
2805
|
+
for (const { repo, label, branch, remote } of destinations) {
|
|
2806
|
+
if (!await runGitTask(label, "push", `${label}: pushed to ${remote}/${branch}`, (onHook, onOutput) => push(repo, remote, branch, onHook, onOutput))) {
|
|
2678
2807
|
process.exitCode = 1;
|
|
2679
2808
|
outro("Sending stopped after a Git failure.");
|
|
2680
2809
|
return;
|
|
@@ -2688,21 +2817,11 @@ function reportGitFailure(message, error) {
|
|
|
2688
2817
|
if (error instanceof GitOutputError && error.hookFailureReported) return;
|
|
2689
2818
|
log.error(error instanceof GitOutputError ? message : `${message}: ${errorMessage(error)}`);
|
|
2690
2819
|
}
|
|
2691
|
-
function reportHooks(label) {
|
|
2692
|
-
const options = { secondarySymbol: "", withGuide: false };
|
|
2693
|
-
return (event) => {
|
|
2694
|
-
const hook = `${label}: ${event.name}`;
|
|
2695
|
-
if (event.phase === "start") {
|
|
2696
|
-
log.step(styleText4("bold", hook), options);
|
|
2697
|
-
} else {
|
|
2698
|
-
if (event.exitCode === 0) log.success(`${hook}: completed`, options);
|
|
2699
|
-
else log.error(`${hook}: failed (exit ${event.exitCode})`, options);
|
|
2700
|
-
}
|
|
2701
|
-
};
|
|
2702
|
-
}
|
|
2703
2820
|
async function reviewMessages(drafts, canPrompt) {
|
|
2704
2821
|
while (true) {
|
|
2705
|
-
for (const
|
|
2822
|
+
for (const { stats, pendingLabel, message } of drafts) {
|
|
2823
|
+
log.message(`(${styleText4("green", `+${stats.additions}`)} ${styleText4("red", `-${stats.deletions}`)}) ${pendingLabel}: ${message}`);
|
|
2824
|
+
}
|
|
2706
2825
|
if (!canPrompt) return drafts;
|
|
2707
2826
|
const action = await select({
|
|
2708
2827
|
message: "Action",
|
|
@@ -2733,115 +2852,8 @@ async function reviewMessages(drafts, canPrompt) {
|
|
|
2733
2852
|
}
|
|
2734
2853
|
}
|
|
2735
2854
|
|
|
2736
|
-
// src/lib/subtree-init.ts
|
|
2737
|
-
import { lstat, mkdir, writeFile } from "node:fs/promises";
|
|
2738
|
-
import { join as join3, resolve } from "node:path";
|
|
2739
|
-
function parseSubtreeSources(entries) {
|
|
2740
|
-
if (entries.length === 0) throw new Error("Provide at least one subtree as name=url.");
|
|
2741
|
-
const names = /* @__PURE__ */ new Set();
|
|
2742
|
-
return entries.map((entry) => {
|
|
2743
|
-
const separator = entry.indexOf("=");
|
|
2744
|
-
const name = entry.slice(0, separator);
|
|
2745
|
-
const url = entry.slice(separator + 1);
|
|
2746
|
-
if (separator < 1 || !/^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$/.test(name) || name === "zapdev.json" || name.includes("..") || name.endsWith(".") || name.endsWith(".lock") || !url.trim() || url.startsWith("-") || url.includes("\0")) {
|
|
2747
|
-
throw new Error(`Invalid source "${entry}": expected name=url with a simple folder and remote name.`);
|
|
2748
|
-
}
|
|
2749
|
-
if (names.has(name)) throw new Error(`Duplicate subtree name "${name}".`);
|
|
2750
|
-
names.add(name);
|
|
2751
|
-
return { name, url };
|
|
2752
|
-
});
|
|
2753
|
-
}
|
|
2754
|
-
async function initializeSubtrees(directory, sources, options = {}) {
|
|
2755
|
-
if (!directory.trim()) throw new Error("Directory cannot be empty.");
|
|
2756
|
-
if (options.origin !== void 0 && (!options.origin.trim() || options.origin.startsWith("-") || options.origin.includes("\0"))) {
|
|
2757
|
-
throw new Error("--origin must be a nonempty repository URL.");
|
|
2758
|
-
}
|
|
2759
|
-
const repo = resolve(directory);
|
|
2760
|
-
await mkdir(repo, { recursive: true });
|
|
2761
|
-
if (!await exists(join3(repo, ".git"))) await git(["init", "--quiet", "-b", "main"], repo);
|
|
2762
|
-
if ((await getRepoStatus(repo)).hasChanges) {
|
|
2763
|
-
throw new Error("Working tree must be clean before adding subtrees (including untracked files).");
|
|
2764
|
-
}
|
|
2765
|
-
const configPath = join3(repo, "zapdev.json");
|
|
2766
|
-
if (await exists(configPath) && (await lstat(configPath)).isSymbolicLink()) {
|
|
2767
|
-
throw new Error("Refusing to overwrite zapdev.json through a symbolic link.");
|
|
2768
|
-
}
|
|
2769
|
-
const settings2 = await readProjectConfig(repo);
|
|
2770
|
-
const mapping = new Map(Object.entries(settings2.subtrees ?? {}));
|
|
2771
|
-
const remotes = /* @__PURE__ */ new Map();
|
|
2772
|
-
if (options.origin !== void 0) remotes.set("origin", options.origin);
|
|
2773
|
-
for (const { name, url } of sources) {
|
|
2774
|
-
if (await exists(join3(repo, name))) throw new Error(`"${name}" already exists.`);
|
|
2775
|
-
const mappedRemote = mapping.get(name);
|
|
2776
|
-
if (mappedRemote && mappedRemote !== name) throw new Error(`"${name}" is already mapped to remote "${mappedRemote}".`);
|
|
2777
|
-
const plannedURL = remotes.get(name);
|
|
2778
|
-
if (plannedURL && plannedURL !== url) throw new Error(`Remote "${name}" was requested with another URL: ${plannedURL}`);
|
|
2779
|
-
remotes.set(name, url);
|
|
2780
|
-
}
|
|
2781
|
-
const missingRemotes = [];
|
|
2782
|
-
for (const [name, url] of remotes) {
|
|
2783
|
-
const existingURL = await tryGit(["remote", "get-url", name], repo);
|
|
2784
|
-
if (existingURL === null) missingRemotes.push([name, url]);
|
|
2785
|
-
else if (existingURL.trim() !== url) throw new Error(`Remote "${name}" already exists with another URL: ${existingURL.trim()}`);
|
|
2786
|
-
}
|
|
2787
|
-
const imports = [];
|
|
2788
|
-
for (const source of sources) {
|
|
2789
|
-
options.onProgress?.(`Detecting default branch for ${source.name}`);
|
|
2790
|
-
const refs = await git(["ls-remote", "--symref", "--", source.url, "HEAD"], repo, void 0, options.onNativeOutput);
|
|
2791
|
-
const branch = /^ref: refs\/heads\/(.+)\tHEAD$/m.exec(refs)?.[1];
|
|
2792
|
-
if (!branch) options.onWarning?.(`Could not detect default branch for ${source.name}; using main.`);
|
|
2793
|
-
imports.push({ ...source, branch: branch ?? "main" });
|
|
2794
|
-
}
|
|
2795
|
-
const initial = await tryGit(["rev-parse", "--verify", "HEAD"], repo) === null;
|
|
2796
|
-
for (const { name } of sources) mapping.set(name, name);
|
|
2797
|
-
await writeFile(configPath, `${JSON.stringify({ ...settings2, subtrees: Object.fromEntries(mapping) }, null, 2)}
|
|
2798
|
-
`);
|
|
2799
|
-
await git(["add", "--", "zapdev.json"], repo);
|
|
2800
|
-
if (initial || (await getStagedDiff(repo)).trim()) {
|
|
2801
|
-
await commit(repo, initial ? "chore: init" : "chore: configure subtrees", void 0, options.onNativeOutput);
|
|
2802
|
-
}
|
|
2803
|
-
for (const [name, url] of missingRemotes) await git(["remote", "add", name, url], repo);
|
|
2804
|
-
for (const { name, branch } of imports) {
|
|
2805
|
-
options.onProgress?.(`Adding ${name} (${branch})`);
|
|
2806
|
-
await git(["subtree", "add", `--prefix=${name}`, name, branch, "--squash"], repo, void 0, options.onNativeOutput);
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
async function exists(path) {
|
|
2810
|
-
return lstat(path).then(() => true, (error) => {
|
|
2811
|
-
if (error.code === "ENOENT") return false;
|
|
2812
|
-
throw error;
|
|
2813
|
-
});
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
|
-
// src/commands/subtree-init.ts
|
|
2817
|
-
var subtreeInitCommand = defineCommand({
|
|
2818
|
-
meta: { name: "subtree-init", description: "Initialize a repository with squashed subtrees and their named remotes." },
|
|
2819
|
-
args: {
|
|
2820
|
-
directory: { type: "positional", required: true, description: "Repository directory to create or extend." },
|
|
2821
|
-
subtree: { type: "positional", required: true, description: "name=url; add more positional sources for additional subtrees." },
|
|
2822
|
-
origin: { type: "string", description: "Optional URL for the parent repository's origin remote." }
|
|
2823
|
-
},
|
|
2824
|
-
async run({ args }) {
|
|
2825
|
-
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2826
|
-
try {
|
|
2827
|
-
const sources = parseSubtreeSources(args._.slice(1));
|
|
2828
|
-
if (interactive) intro("zapdev subtree-init");
|
|
2829
|
-
await initializeSubtrees(args.directory, sources, {
|
|
2830
|
-
origin: args.origin,
|
|
2831
|
-
onProgress: log.info,
|
|
2832
|
-
onWarning: log.warn,
|
|
2833
|
-
onNativeOutput: reportNativeOutput
|
|
2834
|
-
});
|
|
2835
|
-
if (interactive) outro("Subtrees ready.");
|
|
2836
|
-
else log.info("Subtrees ready.");
|
|
2837
|
-
} catch (error) {
|
|
2838
|
-
log.error(error instanceof GitOutputError ? "Subtree initialization failed." : errorMessage(error));
|
|
2839
|
-
process.exitCode = 1;
|
|
2840
|
-
}
|
|
2841
|
-
}
|
|
2842
|
-
});
|
|
2843
|
-
|
|
2844
2855
|
// src/cli.ts
|
|
2856
|
+
updateSettings({ withGuide: true });
|
|
2845
2857
|
var main = defineCommand({
|
|
2846
2858
|
meta: {
|
|
2847
2859
|
name: "zapdev",
|
|
@@ -2849,7 +2861,7 @@ var main = defineCommand({
|
|
|
2849
2861
|
description: "Fast, precise git chores from your terminal."
|
|
2850
2862
|
},
|
|
2851
2863
|
args: commitCommand.args,
|
|
2852
|
-
subCommands: { commit: commitCommand
|
|
2864
|
+
subCommands: { commit: commitCommand },
|
|
2853
2865
|
default: "commit"
|
|
2854
2866
|
});
|
|
2855
2867
|
await runMain(main);
|