superslate 0.2.1 → 0.3.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.
Files changed (4) hide show
  1. package/LICENSE +63 -4
  2. package/README.md +34 -9
  3. package/dist/cli.js +2477 -184
  4. package/package.json +11 -9
package/dist/cli.js CHANGED
@@ -1,15 +1,1650 @@
1
1
  #!/usr/bin/env node
2
2
  // @bun
3
+ var __create = Object.create;
4
+ var __getProtoOf = Object.getPrototypeOf;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
13
+ var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
21
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
22
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ if (canCache)
30
+ cache.set(mod, to);
31
+ return to;
32
+ };
33
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+
35
+ // node_modules/sisteransi/src/index.js
36
+ var require_src = __commonJS((exports, module) => {
37
+ var ESC2 = "\x1B";
38
+ var CSI2 = `${ESC2}[`;
39
+ var beep = "\x07";
40
+ var cursor = {
41
+ to(x, y) {
42
+ if (!y)
43
+ return `${CSI2}${x + 1}G`;
44
+ return `${CSI2}${y + 1};${x + 1}H`;
45
+ },
46
+ move(x, y) {
47
+ let ret = "";
48
+ if (x < 0)
49
+ ret += `${CSI2}${-x}D`;
50
+ else if (x > 0)
51
+ ret += `${CSI2}${x}C`;
52
+ if (y < 0)
53
+ ret += `${CSI2}${-y}A`;
54
+ else if (y > 0)
55
+ ret += `${CSI2}${y}B`;
56
+ return ret;
57
+ },
58
+ up: (count = 1) => `${CSI2}${count}A`,
59
+ down: (count = 1) => `${CSI2}${count}B`,
60
+ forward: (count = 1) => `${CSI2}${count}C`,
61
+ backward: (count = 1) => `${CSI2}${count}D`,
62
+ nextLine: (count = 1) => `${CSI2}E`.repeat(count),
63
+ prevLine: (count = 1) => `${CSI2}F`.repeat(count),
64
+ left: `${CSI2}G`,
65
+ hide: `${CSI2}?25l`,
66
+ show: `${CSI2}?25h`,
67
+ save: `${ESC2}7`,
68
+ restore: `${ESC2}8`
69
+ };
70
+ var scroll = {
71
+ up: (count = 1) => `${CSI2}S`.repeat(count),
72
+ down: (count = 1) => `${CSI2}T`.repeat(count)
73
+ };
74
+ var erase = {
75
+ screen: `${CSI2}2J`,
76
+ up: (count = 1) => `${CSI2}1J`.repeat(count),
77
+ down: (count = 1) => `${CSI2}J`.repeat(count),
78
+ line: `${CSI2}2K`,
79
+ lineEnd: `${CSI2}K`,
80
+ lineStart: `${CSI2}1K`,
81
+ lines(count) {
82
+ let clear = "";
83
+ for (let i = 0;i < count; i++)
84
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
85
+ if (count)
86
+ clear += cursor.left;
87
+ return clear;
88
+ }
89
+ };
90
+ module.exports = { cursor, scroll, erase, beep };
91
+ });
92
+
93
+ // node_modules/@clack/core/dist/index.mjs
94
+ import { styleText } from "node:util";
95
+ import { stdout, stdin } from "node:process";
96
+ import * as l from "node:readline";
97
+ import l__default from "node:readline";
98
+
99
+ // node_modules/fast-string-truncated-width/dist/utils.js
100
+ var getCodePointsLength = (() => {
101
+ const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
102
+ return (input) => {
103
+ let surrogatePairsNr = 0;
104
+ SURROGATE_PAIR_RE.lastIndex = 0;
105
+ while (SURROGATE_PAIR_RE.test(input)) {
106
+ surrogatePairsNr += 1;
107
+ }
108
+ return input.length - surrogatePairsNr;
109
+ };
110
+ })();
111
+ var isFullWidth = (x) => {
112
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
113
+ };
114
+ var isWideNotCJKTNotEmoji = (x) => {
115
+ return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
116
+ };
117
+
118
+ // node_modules/fast-string-truncated-width/dist/index.js
119
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
120
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
121
+ 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;
122
+ var TAB_RE = /\t{1,1000}/y;
123
+ var EMOJI_RE = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu;
124
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
125
+ var MODIFIER_RE = /\p{M}+/gu;
126
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
127
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
128
+ const LIMIT = truncationOptions.limit ?? Infinity;
129
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
130
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
131
+ const ANSI_WIDTH = 0;
132
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
133
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
134
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
135
+ const FULL_WIDTH_WIDTH = 2;
136
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
137
+ const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
138
+ const PARSE_BLOCKS = [
139
+ [LATIN_RE, REGULAR_WIDTH],
140
+ [ANSI_RE, ANSI_WIDTH],
141
+ [CONTROL_RE, CONTROL_WIDTH],
142
+ [TAB_RE, TAB_WIDTH],
143
+ [EMOJI_RE, EMOJI_WIDTH],
144
+ [CJKT_WIDE_RE, WIDE_WIDTH]
145
+ ];
146
+ let indexPrev = 0;
147
+ let index = 0;
148
+ let length = input.length;
149
+ let lengthExtra = 0;
150
+ let truncationEnabled = false;
151
+ let truncationIndex = length;
152
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
153
+ let unmatchedStart = 0;
154
+ let unmatchedEnd = 0;
155
+ let width = 0;
156
+ let widthExtra = 0;
157
+ outer:
158
+ while (true) {
159
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
160
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
161
+ lengthExtra = 0;
162
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
163
+ const codePoint = char.codePointAt(0) || 0;
164
+ if (isFullWidth(codePoint)) {
165
+ widthExtra = FULL_WIDTH_WIDTH;
166
+ } else if (isWideNotCJKTNotEmoji(codePoint)) {
167
+ widthExtra = WIDE_WIDTH;
168
+ } else {
169
+ widthExtra = REGULAR_WIDTH;
170
+ }
171
+ if (width + widthExtra > truncationLimit) {
172
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
173
+ }
174
+ if (width + widthExtra > LIMIT) {
175
+ truncationEnabled = true;
176
+ break outer;
177
+ }
178
+ lengthExtra += char.length;
179
+ width += widthExtra;
180
+ }
181
+ unmatchedStart = unmatchedEnd = 0;
182
+ }
183
+ if (index >= length) {
184
+ break outer;
185
+ }
186
+ for (let i = 0, l = PARSE_BLOCKS.length;i < l; i++) {
187
+ const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
188
+ BLOCK_RE.lastIndex = index;
189
+ if (BLOCK_RE.test(input)) {
190
+ lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
191
+ widthExtra = lengthExtra * BLOCK_WIDTH;
192
+ if (width + widthExtra > truncationLimit) {
193
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
194
+ }
195
+ if (width + widthExtra > LIMIT) {
196
+ truncationEnabled = true;
197
+ break outer;
198
+ }
199
+ width += widthExtra;
200
+ unmatchedStart = indexPrev;
201
+ unmatchedEnd = index;
202
+ index = indexPrev = BLOCK_RE.lastIndex;
203
+ continue outer;
204
+ }
205
+ }
206
+ index += 1;
207
+ }
208
+ return {
209
+ width: truncationEnabled ? truncationLimit : width,
210
+ index: truncationEnabled ? truncationIndex : length,
211
+ truncated: truncationEnabled,
212
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
213
+ };
214
+ };
215
+ var dist_default = getStringTruncatedWidth;
216
+
217
+ // node_modules/fast-string-width/dist/index.js
218
+ var NO_TRUNCATION2 = {
219
+ limit: Infinity,
220
+ ellipsis: "",
221
+ ellipsisWidth: 0
222
+ };
223
+ var fastStringWidth = (input, options = {}) => {
224
+ return dist_default(input, NO_TRUNCATION2, options).width;
225
+ };
226
+ var dist_default2 = fastStringWidth;
227
+
228
+ // node_modules/fast-wrap-ansi/lib/main.js
229
+ var ESC = "\x1B";
230
+ var CSI = "›";
231
+ var END_CODE = 39;
232
+ var ANSI_ESCAPE_BELL = "\x07";
233
+ var ANSI_CSI = "[";
234
+ var ANSI_OSC = "]";
235
+ var ANSI_SGR_TERMINATOR = "m";
236
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
237
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
238
+ var getClosingCode = (openingCode) => {
239
+ if (openingCode >= 30 && openingCode <= 37)
240
+ return 39;
241
+ if (openingCode >= 90 && openingCode <= 97)
242
+ return 39;
243
+ if (openingCode >= 40 && openingCode <= 47)
244
+ return 49;
245
+ if (openingCode >= 100 && openingCode <= 107)
246
+ return 49;
247
+ if (openingCode === 1 || openingCode === 2)
248
+ return 22;
249
+ if (openingCode === 3)
250
+ return 23;
251
+ if (openingCode === 4)
252
+ return 24;
253
+ if (openingCode === 7)
254
+ return 27;
255
+ if (openingCode === 8)
256
+ return 28;
257
+ if (openingCode === 9)
258
+ return 29;
259
+ if (openingCode === 0)
260
+ return 0;
261
+ return;
262
+ };
263
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
264
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
265
+ var wrapWord = (rows, word, columns) => {
266
+ const characters = word[Symbol.iterator]();
267
+ let isInsideEscape = false;
268
+ let isInsideLinkEscape = false;
269
+ let lastRow = rows.at(-1);
270
+ let visible = lastRow === undefined ? 0 : dist_default2(lastRow);
271
+ let currentCharacter = characters.next();
272
+ let nextCharacter = characters.next();
273
+ let rawCharacterIndex = 0;
274
+ while (!currentCharacter.done) {
275
+ const character = currentCharacter.value;
276
+ const characterLength = dist_default2(character);
277
+ if (visible + characterLength <= columns) {
278
+ rows[rows.length - 1] += character;
279
+ } else {
280
+ rows.push(character);
281
+ visible = 0;
282
+ }
283
+ if (character === ESC || character === CSI) {
284
+ isInsideEscape = true;
285
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
286
+ }
287
+ if (isInsideEscape) {
288
+ if (isInsideLinkEscape) {
289
+ if (character === ANSI_ESCAPE_BELL) {
290
+ isInsideEscape = false;
291
+ isInsideLinkEscape = false;
292
+ }
293
+ } else if (character === ANSI_SGR_TERMINATOR) {
294
+ isInsideEscape = false;
295
+ }
296
+ } else {
297
+ visible += characterLength;
298
+ if (visible === columns && !nextCharacter.done) {
299
+ rows.push("");
300
+ visible = 0;
301
+ }
302
+ }
303
+ currentCharacter = nextCharacter;
304
+ nextCharacter = characters.next();
305
+ rawCharacterIndex += character.length;
306
+ }
307
+ lastRow = rows.at(-1);
308
+ if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
309
+ rows[rows.length - 2] += rows.pop();
310
+ }
311
+ };
312
+ var stringVisibleTrimSpacesRight = (string) => {
313
+ const words = string.split(" ");
314
+ let last = words.length;
315
+ while (last) {
316
+ if (dist_default2(words[last - 1])) {
317
+ break;
318
+ }
319
+ last--;
320
+ }
321
+ if (last === words.length) {
322
+ return string;
323
+ }
324
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
325
+ };
326
+ var exec = (string, columns, options = {}) => {
327
+ if (options.trim !== false && string.trim() === "") {
328
+ return "";
329
+ }
330
+ let returnValue = "";
331
+ let escapeCode;
332
+ let escapeUrl;
333
+ const words = string.split(" ");
334
+ let rows = [""];
335
+ let rowLength = 0;
336
+ for (let index = 0;index < words.length; index++) {
337
+ const word = words[index];
338
+ if (options.trim !== false) {
339
+ const row = rows.at(-1) ?? "";
340
+ const trimmed = row.trimStart();
341
+ if (row.length !== trimmed.length) {
342
+ rows[rows.length - 1] = trimmed;
343
+ rowLength = dist_default2(trimmed);
344
+ }
345
+ }
346
+ if (index !== 0) {
347
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
348
+ rows.push("");
349
+ rowLength = 0;
350
+ }
351
+ if (rowLength || options.trim === false) {
352
+ rows[rows.length - 1] += " ";
353
+ rowLength++;
354
+ }
355
+ }
356
+ const wordLength = dist_default2(word);
357
+ if (options.hard && wordLength > columns) {
358
+ const remainingColumns = columns - rowLength;
359
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
360
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
361
+ if (breaksStartingNextLine < breaksStartingThisLine) {
362
+ rows.push("");
363
+ }
364
+ wrapWord(rows, word, columns);
365
+ rowLength = dist_default2(rows.at(-1) ?? "");
366
+ continue;
367
+ }
368
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
369
+ if (options.wordWrap === false && rowLength < columns) {
370
+ wrapWord(rows, word, columns);
371
+ rowLength = dist_default2(rows.at(-1) ?? "");
372
+ continue;
373
+ }
374
+ rows.push("");
375
+ rowLength = 0;
376
+ }
377
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
378
+ wrapWord(rows, word, columns);
379
+ rowLength = dist_default2(rows.at(-1) ?? "");
380
+ continue;
381
+ }
382
+ rows[rows.length - 1] += word;
383
+ rowLength += wordLength;
384
+ }
385
+ if (options.trim !== false) {
386
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
387
+ }
388
+ const preString = rows.join(`
389
+ `);
390
+ let inSurrogate = false;
391
+ for (let i = 0;i < preString.length; i++) {
392
+ const character = preString[i];
393
+ returnValue += character;
394
+ if (!inSurrogate) {
395
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
396
+ if (inSurrogate) {
397
+ continue;
398
+ }
399
+ } else {
400
+ inSurrogate = false;
401
+ }
402
+ if (character === ESC || character === CSI) {
403
+ GROUP_REGEX.lastIndex = i + 1;
404
+ const groupsResult = GROUP_REGEX.exec(preString);
405
+ const groups = groupsResult?.groups;
406
+ if (groups?.code !== undefined) {
407
+ const code = Number.parseFloat(groups.code);
408
+ escapeCode = code === END_CODE ? undefined : code;
409
+ } else if (groups?.uri !== undefined) {
410
+ escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
411
+ }
412
+ }
413
+ if (preString[i + 1] === `
414
+ `) {
415
+ if (escapeUrl) {
416
+ returnValue += wrapAnsiHyperlink("");
417
+ }
418
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
419
+ if (escapeCode && closingCode) {
420
+ returnValue += wrapAnsiCode(closingCode);
421
+ }
422
+ } else if (character === `
423
+ `) {
424
+ if (escapeCode && getClosingCode(escapeCode)) {
425
+ returnValue += wrapAnsiCode(escapeCode);
426
+ }
427
+ if (escapeUrl) {
428
+ returnValue += wrapAnsiHyperlink(escapeUrl);
429
+ }
430
+ }
431
+ }
432
+ return returnValue;
433
+ };
434
+ var CRLF_OR_LF = /\r?\n/;
435
+ function wrapAnsi(string, columns, options) {
436
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join(`
437
+ `);
438
+ }
439
+
440
+ // node_modules/@clack/core/dist/index.mjs
441
+ var import_sisteransi = __toESM(require_src(), 1);
442
+ import { ReadStream } from "node:tty";
443
+ function findCursor(s, o, l2) {
444
+ if (!l2.some((r) => !r.disabled))
445
+ return s;
446
+ const t = s + o, n = Math.max(l2.length - 1, 0), e = t < 0 ? n : t > n ? 0 : t;
447
+ return l2[e]?.disabled ? findCursor(e, o < 0 ? -1 : 1, l2) : e;
448
+ }
449
+ function findTextCursor(s, o, l2, i) {
450
+ const t = i.split(`
451
+ `);
452
+ let n = 0, e = s;
453
+ for (const r of t) {
454
+ if (e <= r.length)
455
+ break;
456
+ e -= r.length + 1, n++;
457
+ }
458
+ for (n = Math.max(0, Math.min(t.length - 1, n + l2)), e = Math.min(e, t[n].length) + o;e < 0 && n > 0; )
459
+ n--, e += t[n].length + 1;
460
+ for (;e > t[n].length && n < t.length - 1; )
461
+ e -= t[n].length + 1, n++;
462
+ e = Math.max(0, Math.min(t[n].length, e));
463
+ let h = 0;
464
+ for (let r = 0;r < n; r++)
465
+ h += t[r].length + 1;
466
+ return h + e;
467
+ }
468
+ var a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
469
+ var t = [
470
+ "January",
471
+ "February",
472
+ "March",
473
+ "April",
474
+ "May",
475
+ "June",
476
+ "July",
477
+ "August",
478
+ "September",
479
+ "October",
480
+ "November",
481
+ "December"
482
+ ];
483
+ var settings = {
484
+ actions: new Set(a$1),
485
+ aliases: /* @__PURE__ */ new Map([
486
+ ["k", "up"],
487
+ ["j", "down"],
488
+ ["h", "left"],
489
+ ["l", "right"],
490
+ ["\x03", "cancel"],
491
+ ["escape", "cancel"]
492
+ ]),
493
+ messages: {
494
+ cancel: "Canceled",
495
+ error: "Something went wrong"
496
+ },
497
+ withGuide: true,
498
+ date: {
499
+ monthNames: [...t],
500
+ messages: {
501
+ required: "Please enter a valid date",
502
+ invalidMonth: "There are only 12 months in a year",
503
+ invalidDay: (n, e) => `There are only ${n} days in ${e}`,
504
+ afterMin: (n) => `Date must be on or after ${n.toISOString().slice(0, 10)}`,
505
+ beforeMax: (n) => `Date must be on or before ${n.toISOString().slice(0, 10)}`
506
+ }
507
+ }
508
+ };
509
+ function isActionKey(n, e) {
510
+ if (typeof n == "string")
511
+ return settings.aliases.get(n) === e;
512
+ for (const s of n)
513
+ if (s !== undefined && isActionKey(s, e))
514
+ return true;
515
+ return false;
516
+ }
517
+ function diffLines(i, s) {
518
+ if (i === s)
519
+ return;
520
+ const e = i.split(`
521
+ `), t2 = s.split(`
522
+ `), r = Math.max(e.length, t2.length), f = [];
523
+ for (let n = 0;n < r; n++)
524
+ e[n] !== t2[n] && f.push(n);
525
+ return {
526
+ lines: f,
527
+ numLinesBefore: e.length,
528
+ numLinesAfter: t2.length,
529
+ numLines: r
530
+ };
531
+ }
532
+ var R = globalThis.process.platform.startsWith("win");
533
+ var CANCEL_SYMBOL = Symbol("clack:cancel");
534
+ function isCancel(e) {
535
+ return e === CANCEL_SYMBOL;
536
+ }
537
+ function setRawMode(e, r) {
538
+ const o = e;
539
+ o.isTTY && o.setRawMode(r);
540
+ }
541
+ function block({
542
+ input: e = stdin,
543
+ output: r = stdout,
544
+ overwrite: o = true,
545
+ hideCursor: t2 = true
546
+ } = {}) {
547
+ const s = l.createInterface({
548
+ input: e,
549
+ output: r,
550
+ prompt: "",
551
+ tabSize: 1
552
+ });
553
+ l.emitKeypressEvents(e, s), e instanceof ReadStream && e.isTTY && e.setRawMode(true);
554
+ const n = (f, { name: a, sequence: p }) => {
555
+ const c = String(f);
556
+ if (isActionKey([c, a, p], "cancel")) {
557
+ t2 && r.write(import_sisteransi.cursor.show), process.exit(0);
558
+ return;
559
+ }
560
+ if (!o)
561
+ return;
562
+ const i = a === "return" ? 0 : -1, m = a === "return" ? -1 : 0;
563
+ l.moveCursor(r, i, m, () => {
564
+ l.clearLine(r, 1, () => {
565
+ e.once("keypress", n);
566
+ });
567
+ });
568
+ };
569
+ return t2 && r.write(import_sisteransi.cursor.hide), e.once("keypress", n), () => {
570
+ e.off("keypress", n), t2 && r.write(import_sisteransi.cursor.show), e instanceof ReadStream && e.isTTY && !R && e.setRawMode(false), s.terminal = false, s.close();
571
+ };
572
+ }
573
+ var getColumns = (e) => ("columns" in e) && typeof e.columns == "number" ? e.columns : 80;
574
+ var getRows = (e) => ("rows" in e) && typeof e.rows == "number" ? e.rows : 20;
575
+ function wrapTextWithPrefix(e, r, o, t2 = o, s = o, n) {
576
+ const f = getColumns(e ?? stdout);
577
+ return wrapAnsi(r, f - o.length, {
578
+ hard: true,
579
+ trim: false
580
+ }).split(`
581
+ `).map((c, i, m) => {
582
+ const d = n ? n(c, i) : c;
583
+ return i === 0 ? `${t2}${d}` : i === m.length - 1 ? `${s}${d}` : `${o}${d}`;
584
+ }).join(`
585
+ `);
586
+ }
587
+ function runValidation(e, n) {
588
+ if ("~standard" in e) {
589
+ const a = e["~standard"].validate(n);
590
+ if (a instanceof Promise)
591
+ throw new TypeError("Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic.");
592
+ return a.issues?.at(0)?.message;
593
+ }
594
+ return e(n);
595
+ }
596
+
597
+ class V {
598
+ input;
599
+ output;
600
+ _abortSignal;
601
+ rl;
602
+ opts;
603
+ _render;
604
+ _track = false;
605
+ _prevFrame = "";
606
+ _subscribers = /* @__PURE__ */ new Map;
607
+ _cursor = 0;
608
+ state = "initial";
609
+ error = "";
610
+ value;
611
+ userInput = "";
612
+ constructor(t2, e = true) {
613
+ const { input: i = stdin, output: n = stdout, render: s, signal: r, ...o } = t2;
614
+ this.opts = o, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = s.bind(this), this._track = e, this._abortSignal = r, this.input = i, this.output = n;
615
+ }
616
+ unsubscribe() {
617
+ this._subscribers.clear();
618
+ }
619
+ setSubscriber(t2, e) {
620
+ const i = this._subscribers.get(t2) ?? [];
621
+ i.push(e), this._subscribers.set(t2, i);
622
+ }
623
+ on(t2, e) {
624
+ this.setSubscriber(t2, { cb: e });
625
+ }
626
+ once(t2, e) {
627
+ this.setSubscriber(t2, { cb: e, once: true });
628
+ }
629
+ emit(t2, ...e) {
630
+ const i = this._subscribers.get(t2) ?? [], n = [];
631
+ for (const s of i)
632
+ s.cb(...e), s.once && n.push(() => i.splice(i.indexOf(s), 1));
633
+ for (const s of n)
634
+ s();
635
+ }
636
+ prompt() {
637
+ return new Promise((t2) => {
638
+ if (this._abortSignal) {
639
+ if (this._abortSignal.aborted)
640
+ return this.state = "cancel", this.close(), t2(CANCEL_SYMBOL);
641
+ this._abortSignal.addEventListener("abort", () => {
642
+ this.state = "cancel", this.close();
643
+ }, { once: true });
644
+ }
645
+ this.rl = l__default.createInterface({
646
+ input: this.input,
647
+ tabSize: 2,
648
+ prompt: "",
649
+ escapeCodeTimeout: 50,
650
+ terminal: true
651
+ }), this.rl.prompt(), this.opts.initialUserInput !== undefined && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), setRawMode(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
652
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(this.value);
653
+ }), this.once("cancel", () => {
654
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t2(CANCEL_SYMBOL);
655
+ });
656
+ });
657
+ }
658
+ _isActionKey(t2, e) {
659
+ return t2 === "\t";
660
+ }
661
+ _shouldSubmit(t2, e) {
662
+ return true;
663
+ }
664
+ _setValue(t2) {
665
+ this.value = t2, this.emit("value", this.value);
666
+ }
667
+ _setUserInput(t2, e) {
668
+ this.userInput = t2 ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
669
+ }
670
+ _clearUserInput() {
671
+ this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
672
+ }
673
+ onKeypress(t2, e) {
674
+ if (this._track && e.name !== "return" && (e.name && this._isActionKey(t2, e) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), e?.name && (!this._track && settings.aliases.has(e.name) && this.emit("cursor", settings.aliases.get(e.name)), settings.actions.has(e.name) && this.emit("cursor", e.name)), t2 && (t2.toLowerCase() === "y" || t2.toLowerCase() === "n") && this.emit("confirm", t2.toLowerCase() === "y"), this.emit("key", t2, e), e?.name === "return" && this._shouldSubmit(t2, e)) {
675
+ if (this.opts.validate) {
676
+ const i = runValidation(this.opts.validate, this.value);
677
+ i && (this.error = i instanceof Error ? i.message : i, this.state = "error", this.rl?.write(this.userInput));
678
+ }
679
+ this.state !== "error" && (this.state = "submit");
680
+ }
681
+ isActionKey([t2, e?.name, e?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
682
+ }
683
+ close() {
684
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
685
+ `), setRawMode(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
686
+ }
687
+ restoreCursor() {
688
+ const t2 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
689
+ `).length - 1;
690
+ this.output.write(import_sisteransi.cursor.move(-999, t2 * -1));
691
+ }
692
+ render() {
693
+ const t2 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, {
694
+ hard: true,
695
+ trim: false
696
+ });
697
+ if (t2 !== this._prevFrame) {
698
+ if (this.state === "initial")
699
+ this.output.write(import_sisteransi.cursor.hide);
700
+ else {
701
+ const e = diffLines(this._prevFrame, t2), i = getRows(this.output);
702
+ if (this.restoreCursor(), e) {
703
+ const n = Math.max(0, e.numLinesAfter - i), s = Math.max(0, e.numLinesBefore - i);
704
+ let r = e.lines.find((o) => o >= n);
705
+ if (r === undefined) {
706
+ this._prevFrame = t2;
707
+ return;
708
+ }
709
+ if (e.lines.length === 1) {
710
+ this.output.write(import_sisteransi.cursor.move(0, r - s)), this.output.write(import_sisteransi.erase.lines(1));
711
+ const o = t2.split(`
712
+ `);
713
+ this.output.write(o[r]), this._prevFrame = t2, this.output.write(import_sisteransi.cursor.move(0, o.length - r - 1));
714
+ return;
715
+ } else if (e.lines.length > 1) {
716
+ if (n < s)
717
+ r = n;
718
+ else {
719
+ const h = r - s;
720
+ h > 0 && this.output.write(import_sisteransi.cursor.move(0, h));
721
+ }
722
+ this.output.write(import_sisteransi.erase.down());
723
+ const f = t2.split(`
724
+ `).slice(r);
725
+ this.output.write(f.join(`
726
+ `)), this._prevFrame = t2;
727
+ return;
728
+ }
729
+ }
730
+ this.output.write(import_sisteransi.erase.down());
731
+ }
732
+ this.output.write(t2), this.state === "initial" && (this.state = "active"), this._prevFrame = t2;
733
+ }
734
+ }
735
+ }
736
+ function p$1(l2, e) {
737
+ if (l2 === undefined || e.length === 0)
738
+ return 0;
739
+ const i = e.findIndex((s) => s.value === l2);
740
+ return i !== -1 ? i : 0;
741
+ }
742
+ function g(l2, e) {
743
+ return (e.label ?? String(e.value)).toLowerCase().includes(l2.toLowerCase());
744
+ }
745
+ function m(l2, e) {
746
+ if (e)
747
+ return l2 ? e : e[0];
748
+ }
749
+ var T$1 = class T extends V {
750
+ filteredOptions;
751
+ multiple;
752
+ isNavigating = false;
753
+ selectedValues = [];
754
+ focusedValue;
755
+ #e = 0;
756
+ #s = "";
757
+ #t;
758
+ #i;
759
+ #n;
760
+ get cursor() {
761
+ return this.#e;
762
+ }
763
+ get userInputWithCursor() {
764
+ if (!this.userInput)
765
+ return styleText(["inverse", "hidden"], "_");
766
+ if (this._cursor >= this.userInput.length)
767
+ return `${this.userInput}█`;
768
+ const e = this.userInput.slice(0, this.cursor), t2 = this.userInput.slice(this.cursor, this.cursor + 1), i = this.userInput.slice(this.cursor + 1);
769
+ return `${e}${styleText("inverse", t2)}${i}`;
770
+ }
771
+ get options() {
772
+ return typeof this.#i == "function" ? this.#i() : this.#i;
773
+ }
774
+ constructor(e) {
775
+ super(e), this.#i = e.options, this.#n = e.placeholder;
776
+ const t2 = this.options;
777
+ this.filteredOptions = [...t2], this.multiple = e.multiple === true, this.#t = typeof e.options == "function" ? e.filter : e.filter ?? g;
778
+ let i;
779
+ if (e.initialValue && Array.isArray(e.initialValue) ? this.multiple ? i = e.initialValue : i = e.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (i = [this.options[0]?.value]), i)
780
+ for (const s of i) {
781
+ const n = t2.findIndex((o) => o.value === s);
782
+ n !== -1 && (this.toggleSelected(s), this.#e = n);
783
+ }
784
+ this.focusedValue = this.options[this.#e]?.value, this.on("key", (s, n) => this.#l(s, n)), this.on("userInput", (s) => this.#u(s));
785
+ }
786
+ _isActionKey(e, t2) {
787
+ return e === "\t" || this.multiple && this.isNavigating && t2.name === "space" && e !== undefined && e !== "";
788
+ }
789
+ #l(e, t2) {
790
+ const i = t2.name === "up", s = t2.name === "down", n = t2.name === "return", o = this.userInput === "" || this.userInput === "\t", u = this.#n, a = this.options, f = u !== undefined && u !== "" && a.some((r) => !r.disabled && (this.#t ? this.#t(u, r) : true));
791
+ if (t2.name === "tab" && o && f) {
792
+ this.userInput === "\t" && this._clearUserInput(), this._setUserInput(u, true), this.isNavigating = false;
793
+ return;
794
+ }
795
+ i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = m(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (t2.name === "tab" || this.isNavigating && t2.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
796
+ }
797
+ deselectAll() {
798
+ this.selectedValues = [];
799
+ }
800
+ toggleSelected(e) {
801
+ this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(e) ? this.selectedValues = this.selectedValues.filter((t2) => t2 !== e) : this.selectedValues = [...this.selectedValues, e] : this.selectedValues = [e]);
802
+ }
803
+ #u(e) {
804
+ if (e !== this.#s) {
805
+ this.#s = e;
806
+ const t2 = this.options;
807
+ e && this.#t ? this.filteredOptions = t2.filter((n) => this.#t?.(e, n)) : this.filteredOptions = [...t2];
808
+ const i = p$1(this.focusedValue, this.filteredOptions);
809
+ this.#e = findCursor(i, 0, this.filteredOptions);
810
+ const s = this.filteredOptions[this.#e];
811
+ s && !s.disabled ? this.focusedValue = s.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
812
+ }
813
+ }
814
+ };
815
+
816
+ class r extends V {
817
+ get cursor() {
818
+ return this.value ? 0 : 1;
819
+ }
820
+ get _value() {
821
+ return this.cursor === 0;
822
+ }
823
+ constructor(t2) {
824
+ super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
825
+ this.value = this._value;
826
+ }), this.on("confirm", (i) => {
827
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = i, this.state = "submit", this.close();
828
+ }), this.on("cursor", () => {
829
+ this.value = !this.value;
830
+ });
831
+ }
832
+ }
833
+ var _ = {
834
+ Y: { type: "year", len: 4 },
835
+ M: { type: "month", len: 2 },
836
+ D: { type: "day", len: 2 }
837
+ };
838
+ function M(r2) {
839
+ return [...r2].map((t2) => _[t2]);
840
+ }
841
+ function P(r2) {
842
+ const i = new Intl.DateTimeFormat(r2, {
843
+ year: "numeric",
844
+ month: "2-digit",
845
+ day: "2-digit"
846
+ }).formatToParts(new Date(2000, 0, 15)), s = [];
847
+ let n = "/";
848
+ for (const e of i)
849
+ e.type === "literal" ? n = e.value.trim() || e.value : (e.type === "year" || e.type === "month" || e.type === "day") && s.push({ type: e.type, len: e.type === "year" ? 4 : 2 });
850
+ return { segments: s, separator: n };
851
+ }
852
+ function p(r2) {
853
+ return Number.parseInt((r2 || "0").replace(/_/g, "0"), 10) || 0;
854
+ }
855
+ function f(r2) {
856
+ return {
857
+ year: p(r2.year),
858
+ month: p(r2.month),
859
+ day: p(r2.day)
860
+ };
861
+ }
862
+ function c(r2, t2) {
863
+ return new Date(r2 || 2001, t2 || 1, 0).getDate();
864
+ }
865
+ function b(r2) {
866
+ const { year: t2, month: i, day: s } = f(r2);
867
+ if (!t2 || t2 < 0 || t2 > 9999 || !i || i < 1 || i > 12 || !s || s < 1)
868
+ return;
869
+ const n = new Date(Date.UTC(t2, i - 1, s));
870
+ if (!(n.getUTCFullYear() !== t2 || n.getUTCMonth() !== i - 1 || n.getUTCDate() !== s))
871
+ return { year: t2, month: i, day: s };
872
+ }
873
+ function C(r2) {
874
+ const t2 = b(r2);
875
+ return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
876
+ }
877
+ function T2(r2, t2, i, s) {
878
+ const n = i ? {
879
+ year: i.getUTCFullYear(),
880
+ month: i.getUTCMonth() + 1,
881
+ day: i.getUTCDate()
882
+ } : null, e = s ? {
883
+ year: s.getUTCFullYear(),
884
+ month: s.getUTCMonth() + 1,
885
+ day: s.getUTCDate()
886
+ } : null;
887
+ return r2 === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r2 === "month" ? {
888
+ min: n && t2.year === n.year ? n.month : 1,
889
+ max: e && t2.year === e.year ? e.month : 12
890
+ } : {
891
+ min: n && t2.year === n.year && t2.month === n.month ? n.day : 1,
892
+ max: e && t2.year === e.year && t2.month === e.month ? e.day : c(t2.year, t2.month)
893
+ };
894
+ }
895
+
896
+ class U extends V {
897
+ #i;
898
+ #o;
899
+ #t;
900
+ #h;
901
+ #u;
902
+ #e = { segmentIndex: 0, positionInSegment: 0 };
903
+ #n = true;
904
+ #s = null;
905
+ inlineError = "";
906
+ get segmentCursor() {
907
+ return { ...this.#e };
908
+ }
909
+ get segmentValues() {
910
+ return { ...this.#t };
911
+ }
912
+ get segments() {
913
+ return this.#i;
914
+ }
915
+ get separator() {
916
+ return this.#o;
917
+ }
918
+ get formattedValue() {
919
+ return this.#l(this.#t);
920
+ }
921
+ #l(t2) {
922
+ return this.#i.map((i) => t2[i.type]).join(this.#o);
923
+ }
924
+ #r() {
925
+ this._setUserInput(this.#l(this.#t)), this._setValue(C(this.#t) ?? undefined);
926
+ }
927
+ constructor(t2) {
928
+ const i = t2.format ? { segments: M(t2.format), separator: t2.separator ?? "/" } : P(t2.locale), s = t2.separator ?? i.separator, n = t2.format ? M(t2.format) : i.segments, e = t2.initialValue ?? t2.defaultValue, m2 = e ? {
929
+ year: String(e.getUTCFullYear()).padStart(4, "0"),
930
+ month: String(e.getUTCMonth() + 1).padStart(2, "0"),
931
+ day: String(e.getUTCDate()).padStart(2, "0")
932
+ } : { year: "____", month: "__", day: "__" }, o = n.map((a) => m2[a.type]).join(s);
933
+ super({ ...t2, initialUserInput: o }, false), this.#i = n, this.#o = s, this.#t = m2, this.#h = t2.minDate, this.#u = t2.maxDate, this.#r(), this.on("cursor", (a) => this.#f(a)), this.on("key", (a, u) => this.#y(a, u)), this.on("finalize", () => this.#p(t2));
934
+ }
935
+ #a() {
936
+ const t2 = Math.max(0, Math.min(this.#e.segmentIndex, this.#i.length - 1)), i = this.#i[t2];
937
+ if (i)
938
+ return this.#e.positionInSegment = Math.max(0, Math.min(this.#e.positionInSegment, i.len - 1)), { segment: i, index: t2 };
939
+ }
940
+ #m(t2) {
941
+ this.inlineError = "", this.#s = null;
942
+ const i = this.#a();
943
+ i && (this.#e.segmentIndex = Math.max(0, Math.min(this.#i.length - 1, i.index + t2)), this.#e.positionInSegment = 0, this.#n = true);
944
+ }
945
+ #d(t2) {
946
+ const i = this.#a();
947
+ if (!i)
948
+ return;
949
+ const { segment: s } = i, n = this.#t[s.type], e = !n || n.replace(/_/g, "") === "", m2 = Number.parseInt((n || "0").replace(/_/g, "0"), 10) || 0, o = T2(s.type, f(this.#t), this.#h, this.#u);
950
+ let a;
951
+ e ? a = t2 === 1 ? o.min : o.max : a = Math.max(Math.min(o.max, m2 + t2), o.min), this.#t = {
952
+ ...this.#t,
953
+ [s.type]: a.toString().padStart(s.len, "0")
954
+ }, this.#n = true, this.#s = null, this.#r();
955
+ }
956
+ #f(t2) {
957
+ if (t2)
958
+ switch (t2) {
959
+ case "right":
960
+ return this.#m(1);
961
+ case "left":
962
+ return this.#m(-1);
963
+ case "up":
964
+ return this.#d(1);
965
+ case "down":
966
+ return this.#d(-1);
967
+ }
968
+ }
969
+ #y(t2, i) {
970
+ if (i?.name === "backspace" || i?.sequence === "" || i?.sequence === "\b" || t2 === "" || t2 === "\b") {
971
+ this.inlineError = "";
972
+ const n = this.#a();
973
+ if (!n)
974
+ return;
975
+ if (!this.#t[n.segment.type].replace(/_/g, "")) {
976
+ this.#m(-1);
977
+ return;
978
+ }
979
+ this.#t[n.segment.type] = "_".repeat(n.segment.len), this.#n = true, this.#e.positionInSegment = 0, this.#r();
980
+ return;
981
+ }
982
+ if (i?.name === "tab") {
983
+ this.inlineError = "";
984
+ const n = this.#a();
985
+ if (!n)
986
+ return;
987
+ const e = i.shift ? -1 : 1, m2 = n.index + e;
988
+ m2 >= 0 && m2 < this.#i.length && (this.#e.segmentIndex = m2, this.#e.positionInSegment = 0, this.#n = true);
989
+ return;
990
+ }
991
+ if (t2 && /^[0-9]$/.test(t2)) {
992
+ const n = this.#a();
993
+ if (!n)
994
+ return;
995
+ const { segment: e } = n, m2 = !this.#t[e.type].replace(/_/g, "");
996
+ if (this.#n && this.#s !== null && !m2) {
997
+ const h = this.#s + t2, d = { ...this.#t, [e.type]: h }, g2 = this.#g(d, e);
998
+ if (g2) {
999
+ this.inlineError = g2, this.#s = null, this.#n = false;
1000
+ return;
1001
+ }
1002
+ this.inlineError = "", this.#t[e.type] = h, this.#s = null, this.#n = false, this.#r(), n.index < this.#i.length - 1 && (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true);
1003
+ return;
1004
+ }
1005
+ this.#n && !m2 && (this.#t[e.type] = "_".repeat(e.len), this.#e.positionInSegment = 0), this.#n = false, this.#s = null;
1006
+ const o = this.#t[e.type], a = o.indexOf("_"), u = a >= 0 ? a : Math.min(this.#e.positionInSegment, e.len - 1);
1007
+ if (u < 0 || u >= e.len)
1008
+ return;
1009
+ let l2 = o.slice(0, u) + t2 + o.slice(u + 1), D = false;
1010
+ if (u === 0 && o === "__" && (e.type === "month" || e.type === "day")) {
1011
+ const h = Number.parseInt(t2, 10);
1012
+ l2 = `0${t2}`, D = h <= (e.type === "month" ? 1 : 2);
1013
+ }
1014
+ if (e.type === "year" && (l2 = (o.replace(/_/g, "") + t2).padStart(e.len, "_")), !l2.includes("_")) {
1015
+ const h = { ...this.#t, [e.type]: l2 }, d = this.#g(h, e);
1016
+ if (d) {
1017
+ this.inlineError = d;
1018
+ return;
1019
+ }
1020
+ }
1021
+ this.inlineError = "", this.#t[e.type] = l2;
1022
+ const y = l2.includes("_") ? undefined : b(this.#t);
1023
+ if (y) {
1024
+ const { year: h, month: d } = y, g2 = c(h, d);
1025
+ this.#t = {
1026
+ year: String(Math.max(0, Math.min(9999, h))).padStart(4, "0"),
1027
+ month: String(Math.max(1, Math.min(12, d))).padStart(2, "0"),
1028
+ day: String(Math.max(1, Math.min(g2, y.day))).padStart(2, "0")
1029
+ };
1030
+ }
1031
+ this.#r();
1032
+ const S = l2.indexOf("_");
1033
+ D ? (this.#n = true, this.#s = t2) : S >= 0 ? this.#e.positionInSegment = S : a >= 0 && n.index < this.#i.length - 1 ? (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true) : this.#e.positionInSegment = Math.min(u + 1, e.len - 1);
1034
+ }
1035
+ }
1036
+ #g(t2, i) {
1037
+ const { month: s, day: n } = f(t2);
1038
+ if (i.type === "month" && (s < 0 || s > 12))
1039
+ return settings.date.messages.invalidMonth;
1040
+ if (i.type === "day" && (n < 0 || n > 31))
1041
+ return settings.date.messages.invalidDay(31, "any month");
1042
+ }
1043
+ #p(t2) {
1044
+ const { year: i, month: s, day: n } = f(this.#t);
1045
+ if (i && s && n) {
1046
+ const e = c(i, s);
1047
+ this.#t = {
1048
+ ...this.#t,
1049
+ day: String(Math.min(n, e)).padStart(2, "0")
1050
+ };
1051
+ }
1052
+ this.value = C(this.#t) ?? t2.defaultValue ?? undefined;
1053
+ }
1054
+ }
1055
+ var u$2 = class u extends V {
1056
+ options;
1057
+ cursor = 0;
1058
+ #t;
1059
+ getGroupItems(t2) {
1060
+ return this.options.filter((r2) => r2.group === t2);
1061
+ }
1062
+ isGroupSelected(t2) {
1063
+ const r2 = this.getGroupItems(t2), e = this.value;
1064
+ return e === undefined ? false : r2.every((s) => e.includes(s.value));
1065
+ }
1066
+ toggleValue() {
1067
+ const t2 = this.options[this.cursor];
1068
+ if (t2 !== undefined)
1069
+ if (this.value === undefined && (this.value = []), t2.group === true) {
1070
+ const r2 = t2.value, e = this.getGroupItems(r2);
1071
+ this.isGroupSelected(r2) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
1072
+ } else {
1073
+ const r2 = this.value.includes(t2.value);
1074
+ this.value = r2 ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
1075
+ }
1076
+ }
1077
+ constructor(t2) {
1078
+ super(t2, false);
1079
+ const { options: r2 } = t2;
1080
+ this.#t = t2.selectableGroups !== false, this.options = Object.entries(r2).flatMap(([e, s]) => [
1081
+ { value: e, group: true, label: e },
1082
+ ...s.map((i) => ({ ...i, group: e }))
1083
+ ]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t2.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
1084
+ switch (e) {
1085
+ case "left":
1086
+ case "up": {
1087
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
1088
+ const s = this.options[this.cursor]?.group === true;
1089
+ !this.#t && s && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
1090
+ break;
1091
+ }
1092
+ case "down":
1093
+ case "right": {
1094
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
1095
+ const s = this.options[this.cursor]?.group === true;
1096
+ !this.#t && s && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
1097
+ break;
1098
+ }
1099
+ case "space":
1100
+ this.toggleValue();
1101
+ break;
1102
+ }
1103
+ });
1104
+ }
1105
+ };
1106
+ var o = /* @__PURE__ */ new Set(["up", "down", "left", "right"]);
1107
+
1108
+ class h extends V {
1109
+ #t = false;
1110
+ #s;
1111
+ focused = "editor";
1112
+ get userInputWithCursor() {
1113
+ if (this.state === "submit")
1114
+ return this.userInput;
1115
+ const t2 = this.userInput;
1116
+ if (this.cursor >= t2.length)
1117
+ return `${t2}█`;
1118
+ const s = t2.slice(0, this.cursor), r2 = t2.slice(this.cursor, this.cursor + 1), i = t2.slice(this.cursor + 1);
1119
+ return r2 === `
1120
+ ` ? `${s}█
1121
+ ${i}` : `${s}${styleText("inverse", r2)}${i}`;
1122
+ }
1123
+ get cursor() {
1124
+ return this._cursor;
1125
+ }
1126
+ #r(t2) {
1127
+ if (this.userInput.length === 0) {
1128
+ this._setUserInput(t2);
1129
+ return;
1130
+ }
1131
+ this._setUserInput(this.userInput.slice(0, this.cursor) + t2 + this.userInput.slice(this.cursor));
1132
+ }
1133
+ #i(t2) {
1134
+ const s = this.value ?? "";
1135
+ switch (t2) {
1136
+ case "up":
1137
+ this._cursor = findTextCursor(this._cursor, 0, -1, s);
1138
+ return;
1139
+ case "down":
1140
+ this._cursor = findTextCursor(this._cursor, 0, 1, s);
1141
+ return;
1142
+ case "left":
1143
+ this._cursor = findTextCursor(this._cursor, -1, 0, s);
1144
+ return;
1145
+ case "right":
1146
+ this._cursor = findTextCursor(this._cursor, 1, 0, s);
1147
+ return;
1148
+ }
1149
+ }
1150
+ _shouldSubmit(t2, s) {
1151
+ if (this.#s)
1152
+ return this.focused === "submit" ? true : (this.#r(`
1153
+ `), this._cursor++, false);
1154
+ const r2 = this.#t;
1155
+ return this.#t = true, r2 && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
1156
+ ` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#r(`
1157
+ `), this._cursor++, false);
1158
+ }
1159
+ constructor(t2) {
1160
+ const s = t2.initialUserInput ?? t2.initialValue;
1161
+ super({
1162
+ ...t2,
1163
+ initialUserInput: s
1164
+ }, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r2, i) => {
1165
+ if (i?.name && o.has(i.name)) {
1166
+ this.#t = false, this.#i(i.name);
1167
+ return;
1168
+ }
1169
+ if (r2 === "\t" && this.#s) {
1170
+ this.focused = this.focused === "editor" ? "submit" : "editor";
1171
+ return;
1172
+ }
1173
+ if (i?.name !== "return") {
1174
+ if (this.#t = false, i?.name === "backspace" && this.cursor > 0) {
1175
+ this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--;
1176
+ return;
1177
+ }
1178
+ if (i?.name === "delete" && this.cursor < this.userInput.length) {
1179
+ this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
1180
+ return;
1181
+ }
1182
+ r2 && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r2 ?? ""), this._cursor++);
1183
+ }
1184
+ }), this.on("userInput", (r2) => {
1185
+ this._setValue(r2);
1186
+ }), this.on("finalize", () => {
1187
+ this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
1188
+ });
1189
+ }
1190
+ }
1191
+
1192
+ class a extends V {
1193
+ options;
1194
+ cursor = 0;
1195
+ get _value() {
1196
+ return this.options[this.cursor]?.value;
1197
+ }
1198
+ get _enabledOptions() {
1199
+ return this.options.filter((e) => e.disabled !== true);
1200
+ }
1201
+ toggleAll() {
1202
+ const e = this._enabledOptions, i = this.value !== undefined && this.value.length === e.length;
1203
+ this.value = i ? [] : e.map((t2) => t2.value);
1204
+ }
1205
+ toggleInvert() {
1206
+ const e = this.value;
1207
+ if (!e)
1208
+ return;
1209
+ const i = this._enabledOptions.filter((t2) => !e.includes(t2.value));
1210
+ this.value = i.map((t2) => t2.value);
1211
+ }
1212
+ toggleValue() {
1213
+ this.value === undefined && (this.value = []);
1214
+ const e = this.value.includes(this._value);
1215
+ this.value = e ? this.value.filter((i) => i !== this._value) : [...this.value, this._value];
1216
+ }
1217
+ constructor(e) {
1218
+ super(e, false), this.options = e.options, this.value = [...e.initialValues ?? []];
1219
+ const i = Math.max(this.options.findIndex(({ value: t2 }) => t2 === e.cursorAt), 0);
1220
+ this.cursor = this.options[i]?.disabled ? findCursor(i, 1, this.options) : i, this.on("key", (t2, l2) => {
1221
+ l2.name === "a" && this.toggleAll(), l2.name === "i" && this.toggleInvert();
1222
+ }), this.on("cursor", (t2) => {
1223
+ switch (t2) {
1224
+ case "left":
1225
+ case "up":
1226
+ this.cursor = findCursor(this.cursor, -1, this.options);
1227
+ break;
1228
+ case "down":
1229
+ case "right":
1230
+ this.cursor = findCursor(this.cursor, 1, this.options);
1231
+ break;
1232
+ case "space":
1233
+ this.toggleValue();
1234
+ break;
1235
+ }
1236
+ });
1237
+ }
1238
+ }
1239
+ var u$1 = class u2 extends V {
1240
+ _mask = "•";
1241
+ get cursor() {
1242
+ return this._cursor;
1243
+ }
1244
+ get masked() {
1245
+ return this.userInput.replaceAll(/./g, this._mask);
1246
+ }
1247
+ get userInputWithCursor() {
1248
+ if (this.state === "submit" || this.state === "cancel")
1249
+ return this.masked;
1250
+ const t2 = this.userInput;
1251
+ if (this.cursor >= t2.length)
1252
+ return `${this.masked}${styleText(["inverse", "hidden"], "_")}`;
1253
+ const s = this.masked, r2 = s.slice(0, this.cursor), i = s.slice(this.cursor, this.cursor + 1), o2 = s.slice(this.cursor + 1);
1254
+ return `${r2}${styleText("inverse", i)}${o2}`;
1255
+ }
1256
+ clear() {
1257
+ this._clearUserInput();
1258
+ }
1259
+ constructor({ mask: t2, ...s }) {
1260
+ super(s), this._mask = t2 ?? "•", this.on("userInput", (r2) => {
1261
+ this._setValue(r2);
1262
+ }), this.on("finalize", () => {
1263
+ this.value === undefined && (this.value = "");
1264
+ });
1265
+ }
1266
+ };
1267
+ var n$1 = class n extends V {
1268
+ options;
1269
+ cursor = 0;
1270
+ get _selectedValue() {
1271
+ return this.options[this.cursor];
1272
+ }
1273
+ changeValue() {
1274
+ const e = this._selectedValue;
1275
+ this.value = e === undefined ? undefined : e.value;
1276
+ }
1277
+ constructor(e) {
1278
+ super(e, false), this.options = e.options;
1279
+ const o2 = this.options.findIndex(({ value: s }) => s === e.initialValue), t2 = o2 === -1 ? 0 : o2;
1280
+ this.cursor = this.options[t2]?.disabled ? findCursor(t2, 1, this.options) : t2, this.changeValue(), this.on("cursor", (s) => {
1281
+ switch (s) {
1282
+ case "left":
1283
+ case "up":
1284
+ this.cursor = findCursor(this.cursor, -1, this.options);
1285
+ break;
1286
+ case "down":
1287
+ case "right":
1288
+ this.cursor = findCursor(this.cursor, 1, this.options);
1289
+ break;
1290
+ }
1291
+ this.changeValue();
1292
+ });
1293
+ }
1294
+ };
1295
+ class n2 extends V {
1296
+ get userInputWithCursor() {
1297
+ if (this.state === "submit")
1298
+ return this.userInput;
1299
+ const t2 = this.userInput;
1300
+ if (this.cursor >= t2.length)
1301
+ return `${this.userInput}█`;
1302
+ const r2 = t2.slice(0, this.cursor), s = t2.slice(this.cursor, this.cursor + 1), e = t2.slice(this.cursor + 1);
1303
+ return `${r2}${styleText("inverse", s)}${e}`;
1304
+ }
1305
+ get cursor() {
1306
+ return this._cursor;
1307
+ }
1308
+ constructor(t2) {
1309
+ super({
1310
+ ...t2,
1311
+ initialUserInput: t2.initialUserInput ?? t2.initialValue
1312
+ }), this.on("userInput", (r2) => {
1313
+ this._setValue(r2);
1314
+ }), this.on("finalize", () => {
1315
+ this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
1316
+ });
1317
+ }
1318
+ }
1319
+
1320
+ // node_modules/@clack/prompts/dist/index.mjs
1321
+ import { styleText as styleText2, stripVTControlCharacters } from "node:util";
1322
+ import process$1 from "node:process";
1323
+ var import_sisteransi2 = __toESM(require_src(), 1);
1324
+ function isUnicodeSupported() {
1325
+ if (process$1.platform !== "win32") {
1326
+ return process$1.env.TERM !== "linux";
1327
+ }
1328
+ return Boolean(process$1.env.CI) || Boolean(process$1.env.WT_SESSION) || Boolean(process$1.env.TERMINUS_SUBLIME) || process$1.env.ConEmuTask === "{cmd::Cmder}" || process$1.env.TERM_PROGRAM === "Terminus-Sublime" || process$1.env.TERM_PROGRAM === "vscode" || process$1.env.TERM === "xterm-256color" || process$1.env.TERM === "alacritty" || process$1.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
1329
+ }
1330
+ var unicode = isUnicodeSupported();
1331
+ var isCI = () => process.env.CI === "true";
1332
+ var unicodeOr = (o2, e) => unicode ? o2 : e;
1333
+ var S_STEP_ACTIVE = unicodeOr("◆", "*");
1334
+ var S_STEP_CANCEL = unicodeOr("■", "x");
1335
+ var S_STEP_ERROR = unicodeOr("▲", "x");
1336
+ var S_STEP_SUBMIT = unicodeOr("◇", "o");
1337
+ var S_BAR_START = unicodeOr("┌", "T");
1338
+ var S_BAR = unicodeOr("│", "|");
1339
+ var S_BAR_END = unicodeOr("└", "—");
1340
+ var S_BAR_START_RIGHT = unicodeOr("┐", "T");
1341
+ var S_BAR_END_RIGHT = unicodeOr("┘", "—");
1342
+ var S_RADIO_ACTIVE = unicodeOr("●", ">");
1343
+ var S_RADIO_INACTIVE = unicodeOr("○", " ");
1344
+ var S_CHECKBOX_ACTIVE = unicodeOr("◻", "[•]");
1345
+ var S_CHECKBOX_SELECTED = unicodeOr("◼", "[+]");
1346
+ var S_CHECKBOX_INACTIVE = unicodeOr("◻", "[ ]");
1347
+ var S_PASSWORD_MASK = unicodeOr("▪", "•");
1348
+ var S_BAR_H = unicodeOr("─", "-");
1349
+ var S_CORNER_TOP_RIGHT = unicodeOr("╮", "+");
1350
+ var S_CONNECT_LEFT = unicodeOr("├", "+");
1351
+ var S_CORNER_BOTTOM_RIGHT = unicodeOr("╯", "+");
1352
+ var S_CORNER_BOTTOM_LEFT = unicodeOr("╰", "+");
1353
+ var S_CORNER_TOP_LEFT = unicodeOr("╭", "+");
1354
+ var S_INFO = unicodeOr("●", "•");
1355
+ var S_SUCCESS = unicodeOr("◆", "*");
1356
+ var S_WARN = unicodeOr("▲", "!");
1357
+ var S_ERROR = unicodeOr("■", "x");
1358
+ var symbol = (o2) => {
1359
+ switch (o2) {
1360
+ case "initial":
1361
+ case "active":
1362
+ return styleText2("cyan", S_STEP_ACTIVE);
1363
+ case "cancel":
1364
+ return styleText2("red", S_STEP_CANCEL);
1365
+ case "error":
1366
+ return styleText2("yellow", S_STEP_ERROR);
1367
+ case "submit":
1368
+ return styleText2("green", S_STEP_SUBMIT);
1369
+ }
1370
+ };
1371
+ var confirm = (i) => {
1372
+ const a2 = i.active ?? "Yes", s = i.inactive ?? "No";
1373
+ return new r({
1374
+ active: a2,
1375
+ inactive: s,
1376
+ signal: i.signal,
1377
+ input: i.input,
1378
+ output: i.output,
1379
+ initialValue: i.initialValue ?? true,
1380
+ render() {
1381
+ const e = i.withGuide ?? settings.withGuide, u4 = `${symbol(this.state)} `, l2 = e ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(i.output, i.message, l2, u4), o2 = `${e ? `${styleText2("gray", S_BAR)}
1382
+ ` : ""}${f2}
1383
+ `, c2 = this.value ? a2 : s;
1384
+ switch (this.state) {
1385
+ case "submit": {
1386
+ const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
1387
+ return `${o2}${r2}${styleText2("dim", c2)}`;
1388
+ }
1389
+ case "cancel": {
1390
+ const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
1391
+ return `${o2}${r2}${styleText2(["strikethrough", "dim"], c2)}${e ? `
1392
+ ${styleText2("gray", S_BAR)}` : ""}`;
1393
+ }
1394
+ default: {
1395
+ const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e ? styleText2("cyan", S_BAR_END) : "";
1396
+ return `${o2}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a2}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a2)}`}${i.vertical ? e ? `
1397
+ ${styleText2("cyan", S_BAR)} ` : `
1398
+ ` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s}`}
1399
+ ${g2}
1400
+ `;
1401
+ }
1402
+ }
1403
+ }
1404
+ }).prompt();
1405
+ };
1406
+ var MULTISELECT_INSTRUCTIONS = [
1407
+ `${styleText2("dim", "↑/↓")} to navigate`,
1408
+ `${styleText2("dim", "Space:")} select`,
1409
+ `${styleText2("dim", "Enter:")} confirm`
1410
+ ];
1411
+ var log = {
1412
+ message: (s = [], {
1413
+ symbol: e = styleText2("gray", S_BAR),
1414
+ secondarySymbol: r2 = styleText2("gray", S_BAR),
1415
+ output: m2 = process.stdout,
1416
+ spacing: l2 = 1,
1417
+ withGuide: c2
1418
+ } = {}) => {
1419
+ const t2 = [], o2 = c2 ?? settings.withGuide, f2 = o2 ? r2 : "", O = o2 ? `${e} ` : "", u4 = o2 ? `${r2} ` : "";
1420
+ for (let i = 0;i < l2; i++)
1421
+ t2.push(f2);
1422
+ const g2 = Array.isArray(s) ? s : s.split(`
1423
+ `);
1424
+ if (g2.length > 0) {
1425
+ const [i, ...y] = g2;
1426
+ i.length > 0 ? t2.push(`${O}${i}`) : t2.push(o2 ? e : "");
1427
+ for (const p2 of y)
1428
+ p2.length > 0 ? t2.push(`${u4}${p2}`) : t2.push(o2 ? r2 : "");
1429
+ }
1430
+ m2.write(`${t2.join(`
1431
+ `)}
1432
+ `);
1433
+ },
1434
+ info: (s, e) => {
1435
+ log.message(s, { ...e, symbol: styleText2("blue", S_INFO) });
1436
+ },
1437
+ success: (s, e) => {
1438
+ log.message(s, { ...e, symbol: styleText2("green", S_SUCCESS) });
1439
+ },
1440
+ step: (s, e) => {
1441
+ log.message(s, { ...e, symbol: styleText2("green", S_STEP_SUBMIT) });
1442
+ },
1443
+ warn: (s, e) => {
1444
+ log.message(s, { ...e, symbol: styleText2("yellow", S_WARN) });
1445
+ },
1446
+ warning: (s, e) => {
1447
+ log.warn(s, e);
1448
+ },
1449
+ error: (s, e) => {
1450
+ log.message(s, { ...e, symbol: styleText2("red", S_ERROR) });
1451
+ }
1452
+ };
1453
+ var cancel = (o2 = "", t2) => {
1454
+ const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_END)} ` : "";
1455
+ i.write(`${e}${styleText2("red", o2)}
1456
+
1457
+ `);
1458
+ };
1459
+ var intro = (o2 = "", t2) => {
1460
+ const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR_START)} ` : "";
1461
+ i.write(`${e}${o2}
1462
+ `);
1463
+ };
1464
+ var outro = (o2 = "", t2) => {
1465
+ const i = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText2("gray", S_BAR)}
1466
+ ${styleText2("gray", S_BAR_END)} ` : "";
1467
+ i.write(`${e}${o2}
1468
+
1469
+ `);
1470
+ };
1471
+ var password = (r2) => new u$1({
1472
+ validate: r2.validate,
1473
+ mask: r2.mask ?? S_PASSWORD_MASK,
1474
+ signal: r2.signal,
1475
+ input: r2.input,
1476
+ output: r2.output,
1477
+ render() {
1478
+ const e = r2.withGuide ?? settings.withGuide, o2 = `${e ? `${styleText2("gray", S_BAR)}
1479
+ ` : ""}${symbol(this.state)} ${r2.message}
1480
+ `, c2 = this.userInputWithCursor, i = this.masked;
1481
+ switch (this.state) {
1482
+ case "error": {
1483
+ const s = e ? `${styleText2("yellow", S_BAR)} ` : "", n3 = e ? `${styleText2("yellow", S_BAR_END)} ` : "", l2 = i ?? "";
1484
+ return r2.clearOnError && this.clear(), `${o2.trim()}
1485
+ ${s}${l2}
1486
+ ${n3}${styleText2("yellow", this.error)}
1487
+ `;
1488
+ }
1489
+ case "submit": {
1490
+ const s = e ? `${styleText2("gray", S_BAR)} ` : "", n3 = i ? styleText2("dim", i) : "";
1491
+ return `${o2}${s}${n3}`;
1492
+ }
1493
+ case "cancel": {
1494
+ const s = e ? `${styleText2("gray", S_BAR)} ` : "", n3 = i ? styleText2(["strikethrough", "dim"], i) : "";
1495
+ return `${o2}${s}${n3}${i && e ? `
1496
+ ${styleText2("gray", S_BAR)}` : ""}`;
1497
+ }
1498
+ default: {
1499
+ const s = e ? `${styleText2("cyan", S_BAR)} ` : "", n3 = e ? styleText2("cyan", S_BAR_END) : "";
1500
+ return `${o2}${s}${c2}
1501
+ ${n3}
1502
+ `;
1503
+ }
1504
+ }
1505
+ }
1506
+ }).prompt();
1507
+ var W = (l2) => styleText2("magenta", l2);
1508
+ var spinner = ({
1509
+ indicator: l2 = "dots",
1510
+ onCancel: h2,
1511
+ output: n3 = process.stdout,
1512
+ cancelMessage: G,
1513
+ errorMessage: O,
1514
+ frames: E = unicode ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"],
1515
+ delay: F = unicode ? 80 : 120,
1516
+ signal: m2,
1517
+ ...I
1518
+ } = {}) => {
1519
+ const u4 = isCI();
1520
+ let M2, T3, d = false, S = false, s = "", p2, w = performance.now();
1521
+ const x = getColumns(n3), k = I?.styleFrame ?? W, g2 = (e) => {
1522
+ const r2 = e > 1 ? O ?? settings.messages.error : G ?? settings.messages.cancel;
1523
+ S = e === 1, d && (a2(r2, e), S && typeof h2 == "function" && h2());
1524
+ }, f2 = () => g2(2), i = () => g2(1), A = () => {
1525
+ process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i), process.on("SIGTERM", i), process.on("exit", g2), m2 && m2.addEventListener("abort", i);
1526
+ }, H = () => {
1527
+ process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i), process.removeListener("SIGTERM", i), process.removeListener("exit", g2), m2 && m2.removeEventListener("abort", i);
1528
+ }, y = () => {
1529
+ if (p2 === undefined)
1530
+ return;
1531
+ u4 && n3.write(`
1532
+ `);
1533
+ const r2 = wrapAnsi(p2, x, {
1534
+ hard: true,
1535
+ trim: false
1536
+ }).split(`
1537
+ `);
1538
+ r2.length > 1 && n3.write(import_sisteransi2.cursor.up(r2.length - 1)), n3.write(import_sisteransi2.cursor.to(0)), n3.write(import_sisteransi2.erase.down());
1539
+ }, C2 = (e) => e.replace(/\.+$/, ""), _2 = (e) => {
1540
+ const r2 = (performance.now() - e) / 1000, t2 = Math.floor(r2 / 60), o2 = Math.floor(r2 % 60);
1541
+ return t2 > 0 ? `[${t2}m ${o2}s]` : `[${o2}s]`;
1542
+ }, N = I.withGuide ?? settings.withGuide, P2 = (e = "") => {
1543
+ d = true, M2 = block({ output: n3 }), s = C2(e), w = performance.now(), N && n3.write(`${styleText2("gray", S_BAR)}
1544
+ `);
1545
+ let r2 = 0, t2 = 0;
1546
+ A(), T3 = setInterval(() => {
1547
+ if (u4 && s === p2)
1548
+ return;
1549
+ y(), p2 = s;
1550
+ const o2 = k(E[r2]);
1551
+ let v;
1552
+ if (u4)
1553
+ v = `${o2} ${s}...`;
1554
+ else if (l2 === "timer")
1555
+ v = `${o2} ${s} ${_2(w)}`;
1556
+ else {
1557
+ const B = ".".repeat(Math.floor(t2)).slice(0, 3);
1558
+ v = `${o2} ${s}${B}`;
1559
+ }
1560
+ const j = wrapAnsi(v, x, {
1561
+ hard: true,
1562
+ trim: false
1563
+ });
1564
+ n3.write(j), r2 = r2 + 1 < E.length ? r2 + 1 : 0, t2 = t2 < 4 ? t2 + 0.125 : 0;
1565
+ }, F);
1566
+ }, a2 = (e = "", r2 = 0, t2 = false) => {
1567
+ if (!d)
1568
+ return;
1569
+ d = false, clearInterval(T3), y();
1570
+ const o2 = r2 === 0 ? styleText2("green", S_STEP_SUBMIT) : r2 === 1 ? styleText2("red", S_STEP_CANCEL) : styleText2("red", S_STEP_ERROR);
1571
+ s = e ?? s, t2 || (l2 === "timer" ? n3.write(`${o2} ${s} ${_2(w)}
1572
+ `) : n3.write(`${o2} ${s}
1573
+ `)), H(), M2();
1574
+ };
1575
+ return {
1576
+ start: P2,
1577
+ stop: (e = "") => a2(e, 0),
1578
+ message: (e = "") => {
1579
+ s = C2(e ?? s);
1580
+ },
1581
+ cancel: (e = "") => a2(e, 1),
1582
+ error: (e = "") => a2(e, 2),
1583
+ clear: () => a2("", 0, true),
1584
+ get isCancelled() {
1585
+ return S;
1586
+ }
1587
+ };
1588
+ };
1589
+ var u4 = {
1590
+ light: unicodeOr("─", "-"),
1591
+ heavy: unicodeOr("━", "="),
1592
+ block: unicodeOr("█", "#")
1593
+ };
1594
+ var SELECT_INSTRUCTIONS = [
1595
+ `${styleText2("dim", "↑/↓")} to navigate`,
1596
+ `${styleText2("dim", "Enter:")} confirm`
1597
+ ];
1598
+ var i = `${styleText2("gray", S_BAR)} `;
1599
+ var text = (e) => new n2({
1600
+ validate: e.validate,
1601
+ placeholder: e.placeholder,
1602
+ defaultValue: e.defaultValue,
1603
+ initialValue: e.initialValue,
1604
+ output: e.output,
1605
+ signal: e.signal,
1606
+ input: e.input,
1607
+ render() {
1608
+ const i2 = e?.withGuide ?? settings.withGuide, s = `${`${i2 ? `${styleText2("gray", S_BAR)}
1609
+ ` : ""}${symbol(this.state)} `}${e.message}
1610
+ `, c2 = e.placeholder && e.placeholder.length > 0 ? styleText2("inverse", e.placeholder[0]) + styleText2("dim", e.placeholder.slice(1)) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c2, l2 = this.value ?? "";
1611
+ switch (this.state) {
1612
+ case "error": {
1613
+ const n3 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r2 = i2 ? `${styleText2("yellow", S_BAR)} ` : "", d = i2 ? styleText2("yellow", S_BAR_END) : "";
1614
+ return `${s.trim()}
1615
+ ${r2}${o2}
1616
+ ${d}${n3}
1617
+ `;
1618
+ }
1619
+ case "submit": {
1620
+ const n3 = l2 ? ` ${styleText2("dim", l2)}` : "", r2 = i2 ? styleText2("gray", S_BAR) : "";
1621
+ return `${s}${r2}${n3}`;
1622
+ }
1623
+ case "cancel": {
1624
+ const n3 = l2 ? ` ${styleText2(["strikethrough", "dim"], l2)}` : "", r2 = i2 ? styleText2("gray", S_BAR) : "";
1625
+ return `${s}${r2}${n3}${l2.trim() ? `
1626
+ ${r2}` : ""}`;
1627
+ }
1628
+ default: {
1629
+ const n3 = i2 ? `${styleText2("cyan", S_BAR)} ` : "", r2 = i2 ? styleText2("cyan", S_BAR_END) : "";
1630
+ return `${s}${n3}${o2}
1631
+ ${r2}
1632
+ `;
1633
+ }
1634
+ }
1635
+ }
1636
+ }).prompt();
3
1637
 
4
1638
  // src/cli.ts
5
- import * as prompts5 from "@clack/prompts";
6
- import { mkdir as mkdir5, mkdtemp as mkdtemp2, readFile as readFile6, readdir as readdir2, rename as rename2, rm as rm4, rmdir, stat as stat5 } from "fs/promises";
1639
+ import { existsSync, readdirSync, statSync } from "fs";
1640
+ import { mkdir as mkdir5, mkdtemp as mkdtemp2, readFile as readFile6, readdir as readdir2, rename as rename2, rm as rm5, rmdir, stat as stat5 } from "fs/promises";
7
1641
  import { createConnection, createServer } from "net";
8
1642
  import { fileURLToPath as fileURLToPath2 } from "url";
9
- import { dirname as dirname2, join as join7, relative as relative2, resolve as resolve4, sep } from "path";
1643
+ import { dirname as dirname2, join as join8, relative as relative2, resolve as resolve4, sep } from "path";
10
1644
 
11
1645
  // src/constants.ts
12
1646
  var CLI_NAME = "superslate";
1647
+ var LICENSE_KEY_VARIABLE = "SUPERSLATE_LICENSE_KEY";
13
1648
 
14
1649
  // src/constants.ts
15
1650
  var CLI_NAME2 = "superslate";
@@ -18,7 +1653,10 @@ var BUYER_CLI_NAME = "create-app";
18
1653
  var BUYER_CLI_PACKAGE_NAME = "create-app";
19
1654
  var DEFAULT_SCOPE = "@app";
20
1655
  var SOURCE_BRAND_NAME = "superslate";
21
- var TEMPLATE_REPOSITORY = "superslate-dev/superslate";
1656
+ var DELIVERY_BASE_URL = "https://dl.superslate.dev";
1657
+ var DELIVERY_URL_VARIABLE = "SUPERSLATE_DELIVERY_URL";
1658
+ var LICENSE_KEY_VARIABLE2 = "SUPERSLATE_LICENSE_KEY";
1659
+ var LICENSE_KEY_PREFIX = "SUPERSLATE-";
22
1660
 
23
1661
  // src/core.ts
24
1662
  function validateAppName(value) {
@@ -55,8 +1693,532 @@ function validateBrandName(value) {
55
1693
  }
56
1694
  var SCOPE_EXTENSIONS = new Set([".json", ".jsonc", ".md", ".ts", ".tsx", ".yaml", ".yml"]);
57
1695
 
1696
+ // src/delivery.ts
1697
+ var RELEASE_TAG_PATTERN = /^v\d+\.\d+\.\d+(?:-rc\.\d+)?$/;
1698
+ function validateLicenseKey(value) {
1699
+ const key = value.trim();
1700
+ if (!key)
1701
+ return "Enter the licence key from your purchase receipt.";
1702
+ if (/\s/.test(key))
1703
+ return "A licence key does not contain spaces.";
1704
+ if (!key.startsWith(LICENSE_KEY_PREFIX) || key.length === LICENSE_KEY_PREFIX.length) {
1705
+ return `A ${CLI_NAME2} licence key starts with ${LICENSE_KEY_PREFIX}. Copy it from your purchase receipt or the customer portal.`;
1706
+ }
1707
+ return;
1708
+ }
1709
+ function readLicenseKeyFromEnvironment(environment = process.env) {
1710
+ return environment[LICENSE_KEY_VARIABLE2]?.trim() || undefined;
1711
+ }
1712
+ function normalizeSourceVersion(value) {
1713
+ const trimmed = value.trim();
1714
+ const releaseTag = trimmed.startsWith("v") ? trimmed : `v${trimmed}`;
1715
+ if (!RELEASE_TAG_PATTERN.test(releaseTag)) {
1716
+ throw new Error(`Source version must be an immutable release such as 1.2.3: ${value}`);
1717
+ }
1718
+ return releaseTag;
1719
+ }
1720
+
1721
+ // node_modules/@clack/prompts/dist/index.mjs
1722
+ import { styleText as styleText3, stripVTControlCharacters as stripVTControlCharacters2 } from "node:util";
1723
+ import process$12 from "node:process";
1724
+ var import_sisteransi3 = __toESM(require_src(), 1);
1725
+ function isUnicodeSupported2() {
1726
+ if (process$12.platform !== "win32") {
1727
+ return process$12.env.TERM !== "linux";
1728
+ }
1729
+ return Boolean(process$12.env.CI) || Boolean(process$12.env.WT_SESSION) || Boolean(process$12.env.TERMINUS_SUBLIME) || process$12.env.ConEmuTask === "{cmd::Cmder}" || process$12.env.TERM_PROGRAM === "Terminus-Sublime" || process$12.env.TERM_PROGRAM === "vscode" || process$12.env.TERM === "xterm-256color" || process$12.env.TERM === "alacritty" || process$12.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
1730
+ }
1731
+ var unicode2 = isUnicodeSupported2();
1732
+ var isCI2 = () => process.env.CI === "true";
1733
+ var unicodeOr2 = (o2, e) => unicode2 ? o2 : e;
1734
+ var S_STEP_ACTIVE2 = unicodeOr2("◆", "*");
1735
+ var S_STEP_CANCEL2 = unicodeOr2("■", "x");
1736
+ var S_STEP_ERROR2 = unicodeOr2("▲", "x");
1737
+ var S_STEP_SUBMIT2 = unicodeOr2("◇", "o");
1738
+ var S_BAR_START2 = unicodeOr2("┌", "T");
1739
+ var S_BAR2 = unicodeOr2("│", "|");
1740
+ var S_BAR_END2 = unicodeOr2("└", "—");
1741
+ var S_BAR_START_RIGHT2 = unicodeOr2("┐", "T");
1742
+ var S_BAR_END_RIGHT2 = unicodeOr2("┘", "—");
1743
+ var S_RADIO_ACTIVE2 = unicodeOr2("●", ">");
1744
+ var S_RADIO_INACTIVE2 = unicodeOr2("○", " ");
1745
+ var S_CHECKBOX_ACTIVE2 = unicodeOr2("◻", "[•]");
1746
+ var S_CHECKBOX_SELECTED2 = unicodeOr2("◼", "[+]");
1747
+ var S_CHECKBOX_INACTIVE2 = unicodeOr2("◻", "[ ]");
1748
+ var S_PASSWORD_MASK2 = unicodeOr2("▪", "•");
1749
+ var S_BAR_H2 = unicodeOr2("─", "-");
1750
+ var S_CORNER_TOP_RIGHT2 = unicodeOr2("╮", "+");
1751
+ var S_CONNECT_LEFT2 = unicodeOr2("├", "+");
1752
+ var S_CORNER_BOTTOM_RIGHT2 = unicodeOr2("╯", "+");
1753
+ var S_CORNER_BOTTOM_LEFT2 = unicodeOr2("╰", "+");
1754
+ var S_CORNER_TOP_LEFT2 = unicodeOr2("╭", "+");
1755
+ var S_INFO2 = unicodeOr2("●", "•");
1756
+ var S_SUCCESS2 = unicodeOr2("◆", "*");
1757
+ var S_WARN2 = unicodeOr2("▲", "!");
1758
+ var S_ERROR2 = unicodeOr2("■", "x");
1759
+ var symbol2 = (o2) => {
1760
+ switch (o2) {
1761
+ case "initial":
1762
+ case "active":
1763
+ return styleText3("cyan", S_STEP_ACTIVE2);
1764
+ case "cancel":
1765
+ return styleText3("red", S_STEP_CANCEL2);
1766
+ case "error":
1767
+ return styleText3("yellow", S_STEP_ERROR2);
1768
+ case "submit":
1769
+ return styleText3("green", S_STEP_SUBMIT2);
1770
+ }
1771
+ };
1772
+ var symbolBar = (o2) => {
1773
+ switch (o2) {
1774
+ case "initial":
1775
+ case "active":
1776
+ return styleText3("cyan", S_BAR2);
1777
+ case "cancel":
1778
+ return styleText3("red", S_BAR2);
1779
+ case "error":
1780
+ return styleText3("yellow", S_BAR2);
1781
+ case "submit":
1782
+ return styleText3("green", S_BAR2);
1783
+ }
1784
+ };
1785
+ function formatInstructionFooter(o2, e) {
1786
+ const r2 = [`${e ? `${styleText3("cyan", S_BAR2)} ` : ""}${o2.join(" • ")}`];
1787
+ return e && r2.push(styleText3("cyan", S_BAR_END2)), r2;
1788
+ }
1789
+ var I = (l2, e, w, p2, b2, C2 = false) => {
1790
+ let r2 = e, O = 0;
1791
+ if (C2)
1792
+ for (let i2 = p2 - 1;i2 >= w; i2--) {
1793
+ const m2 = l2[i2];
1794
+ if (m2 && (r2 -= m2.length), O++, r2 <= b2)
1795
+ break;
1796
+ }
1797
+ else
1798
+ for (let i2 = w;i2 < p2; i2++) {
1799
+ const m2 = l2[i2];
1800
+ if (m2 && (r2 -= m2.length), O++, r2 <= b2)
1801
+ break;
1802
+ }
1803
+ return { lineCount: r2, removals: O };
1804
+ };
1805
+ var limitOptions = ({
1806
+ cursor: l2,
1807
+ options: e,
1808
+ style: w,
1809
+ output: p2 = process.stdout,
1810
+ maxItems: b2 = Number.POSITIVE_INFINITY,
1811
+ columnPadding: C2 = 0,
1812
+ rowPadding: r2 = 4
1813
+ }) => {
1814
+ const i2 = getColumns(p2) - C2, m2 = getRows(p2), M2 = styleText3("dim", "..."), v = Math.max(m2 - r2, 0), a2 = Math.max(Math.min(b2, v), 5);
1815
+ let f2 = 0;
1816
+ l2 >= a2 - 3 && (f2 = Math.max(Math.min(l2 - a2 + 3, e.length - a2), 0));
1817
+ let d = a2 < e.length && f2 > 0, c2 = a2 < e.length && f2 + a2 < e.length;
1818
+ const W2 = Math.min(f2 + a2, e.length), s = [];
1819
+ let g2 = 0;
1820
+ d && g2++, c2 && g2++;
1821
+ const T3 = f2 + (d ? 1 : 0), y = W2 - (c2 ? 1 : 0);
1822
+ for (let t2 = T3;t2 < y; t2++) {
1823
+ const n3 = e[t2], o2 = n3 ? w(n3, t2 === l2) : "", h2 = wrapAnsi(o2, i2, {
1824
+ hard: true,
1825
+ trim: false
1826
+ }).split(`
1827
+ `);
1828
+ s.push(h2), g2 += h2.length;
1829
+ }
1830
+ if (g2 > v) {
1831
+ let t2 = 0, n3 = 0, o2 = g2;
1832
+ const h2 = l2 - T3;
1833
+ let u5 = v;
1834
+ const L = () => I(s, o2, 0, h2, u5), E = () => I(s, o2, h2 + 1, s.length, u5, true);
1835
+ d ? ({ lineCount: o2, removals: t2 } = L(), o2 > u5 && (c2 || (u5 -= 1), { lineCount: o2, removals: n3 } = E())) : (c2 || (u5 -= 1), { lineCount: o2, removals: n3 } = E(), o2 > u5 && (u5 -= 1, { lineCount: o2, removals: t2 } = L())), t2 > 0 && (d = true, s.splice(0, t2)), n3 > 0 && (c2 = true, s.splice(s.length - n3, n3));
1836
+ }
1837
+ const x = [];
1838
+ d && x.push(M2);
1839
+ for (const t2 of s)
1840
+ for (const n3 of t2)
1841
+ x.push(n3);
1842
+ return c2 && x.push(M2), x;
1843
+ };
1844
+ var confirm2 = (i2) => {
1845
+ const a2 = i2.active ?? "Yes", s = i2.inactive ?? "No";
1846
+ return new r({
1847
+ active: a2,
1848
+ inactive: s,
1849
+ signal: i2.signal,
1850
+ input: i2.input,
1851
+ output: i2.output,
1852
+ initialValue: i2.initialValue ?? true,
1853
+ render() {
1854
+ const e = i2.withGuide ?? settings.withGuide, u5 = `${symbol2(this.state)} `, l2 = e ? `${styleText3("gray", S_BAR2)} ` : "", f2 = wrapTextWithPrefix(i2.output, i2.message, l2, u5), o2 = `${e ? `${styleText3("gray", S_BAR2)}
1855
+ ` : ""}${f2}
1856
+ `, c2 = this.value ? a2 : s;
1857
+ switch (this.state) {
1858
+ case "submit": {
1859
+ const r2 = e ? `${styleText3("gray", S_BAR2)} ` : "";
1860
+ return `${o2}${r2}${styleText3("dim", c2)}`;
1861
+ }
1862
+ case "cancel": {
1863
+ const r2 = e ? `${styleText3("gray", S_BAR2)} ` : "";
1864
+ return `${o2}${r2}${styleText3(["strikethrough", "dim"], c2)}${e ? `
1865
+ ${styleText3("gray", S_BAR2)}` : ""}`;
1866
+ }
1867
+ default: {
1868
+ const r2 = e ? `${styleText3("cyan", S_BAR2)} ` : "", g2 = e ? styleText3("cyan", S_BAR_END2) : "";
1869
+ return `${o2}${r2}${this.value ? `${styleText3("green", S_RADIO_ACTIVE2)} ${a2}` : `${styleText3("dim", S_RADIO_INACTIVE2)} ${styleText3("dim", a2)}`}${i2.vertical ? e ? `
1870
+ ${styleText3("cyan", S_BAR2)} ` : `
1871
+ ` : ` ${styleText3("dim", "/")} `}${this.value ? `${styleText3("dim", S_RADIO_INACTIVE2)} ${styleText3("dim", s)}` : `${styleText3("green", S_RADIO_ACTIVE2)} ${s}`}
1872
+ ${g2}
1873
+ `;
1874
+ }
1875
+ }
1876
+ }
1877
+ }).prompt();
1878
+ };
1879
+ var MULTISELECT_INSTRUCTIONS2 = [
1880
+ `${styleText3("dim", "↑/↓")} to navigate`,
1881
+ `${styleText3("dim", "Space:")} select`,
1882
+ `${styleText3("dim", "Enter:")} confirm`
1883
+ ];
1884
+ var m2 = (i2, u5) => i2.split(`
1885
+ `).map((d) => u5(d)).join(`
1886
+ `);
1887
+ var multiselect = (i2) => {
1888
+ const u5 = (t2, a2) => {
1889
+ const r2 = t2.label ?? String(t2.value);
1890
+ return a2 === "disabled" ? `${styleText3("gray", S_CHECKBOX_INACTIVE2)} ${m2(r2, (o2) => styleText3(["strikethrough", "gray"], o2))}${t2.hint ? ` ${styleText3("dim", `(${t2.hint ?? "disabled"})`)}` : ""}` : a2 === "active" ? `${styleText3("cyan", S_CHECKBOX_ACTIVE2)} ${r2}${t2.hint ? ` ${styleText3("dim", `(${t2.hint})`)}` : ""}` : a2 === "selected" ? `${styleText3("green", S_CHECKBOX_SELECTED2)} ${m2(r2, (o2) => styleText3("dim", o2))}${t2.hint ? ` ${styleText3("dim", `(${t2.hint})`)}` : ""}` : a2 === "cancelled" ? `${m2(r2, (o2) => styleText3(["strikethrough", "dim"], o2))}` : a2 === "active-selected" ? `${styleText3("green", S_CHECKBOX_SELECTED2)} ${r2}${t2.hint ? ` ${styleText3("dim", `(${t2.hint})`)}` : ""}` : a2 === "submitted" ? `${m2(r2, (o2) => styleText3("dim", o2))}` : `${styleText3("dim", S_CHECKBOX_INACTIVE2)} ${m2(r2, (o2) => styleText3("dim", o2))}`;
1891
+ }, d = i2.required ?? true, v = i2.showInstructions ?? true;
1892
+ return new a({
1893
+ options: i2.options,
1894
+ signal: i2.signal,
1895
+ input: i2.input,
1896
+ output: i2.output,
1897
+ initialValues: i2.initialValues,
1898
+ required: d,
1899
+ cursorAt: i2.cursorAt,
1900
+ validate(t2) {
1901
+ if (d && (t2 === undefined || t2.length === 0))
1902
+ return `Please select at least one option.
1903
+ ${styleText3("reset", styleText3("dim", `Press ${styleText3(["gray", "bgWhite", "inverse"], " space ")} to select, ${styleText3("gray", styleText3("bgWhite", styleText3("inverse", " enter ")))} to submit`))}`;
1904
+ },
1905
+ render() {
1906
+ const t2 = i2.withGuide ?? settings.withGuide, a2 = wrapTextWithPrefix(i2.output, i2.message, t2 ? `${symbolBar(this.state)} ` : "", `${symbol2(this.state)} `), r2 = `${t2 ? `${styleText3("gray", S_BAR2)}
1907
+ ` : ""}${a2}
1908
+ `, o2 = this.value ?? [], p2 = (n3, l2) => {
1909
+ if (n3.disabled)
1910
+ return u5(n3, "disabled");
1911
+ const s = o2.includes(n3.value);
1912
+ return l2 && s ? u5(n3, "active-selected") : s ? u5(n3, "selected") : u5(n3, l2 ? "active" : "inactive");
1913
+ };
1914
+ switch (this.state) {
1915
+ case "submit": {
1916
+ const n3 = this.options.filter(({ value: s }) => o2.includes(s)).map((s) => u5(s, "submitted")).join(styleText3("dim", ", ")) || styleText3("dim", "none"), l2 = wrapTextWithPrefix(i2.output, n3, t2 ? `${styleText3("gray", S_BAR2)} ` : "");
1917
+ return `${r2}${l2}`;
1918
+ }
1919
+ case "cancel": {
1920
+ const n3 = this.options.filter(({ value: s }) => o2.includes(s)).map((s) => u5(s, "cancelled")).join(styleText3("dim", ", "));
1921
+ if (n3.trim() === "")
1922
+ return `${r2}${styleText3("gray", S_BAR2)}`;
1923
+ const l2 = wrapTextWithPrefix(i2.output, n3, t2 ? `${styleText3("gray", S_BAR2)} ` : "");
1924
+ return `${r2}${l2}${t2 ? `
1925
+ ${styleText3("gray", S_BAR2)}` : ""}`;
1926
+ }
1927
+ case "error": {
1928
+ const n3 = t2 ? `${styleText3("yellow", S_BAR2)} ` : "", l2 = this.error.split(`
1929
+ `).map(($, C2) => C2 === 0 ? `${t2 ? `${styleText3("yellow", S_BAR_END2)} ` : ""}${styleText3("yellow", $)}` : ` ${$}`).join(`
1930
+ `), s = r2.split(`
1931
+ `).length, h2 = l2.split(`
1932
+ `).length + 1;
1933
+ return `${r2}${n3}${limitOptions({
1934
+ output: i2.output,
1935
+ options: this.options,
1936
+ cursor: this.cursor,
1937
+ maxItems: i2.maxItems,
1938
+ columnPadding: n3.length,
1939
+ rowPadding: s + h2,
1940
+ style: p2
1941
+ }).join(`
1942
+ ${n3}`)}
1943
+ ${l2}
1944
+ `;
1945
+ }
1946
+ default: {
1947
+ const n3 = t2 ? `${styleText3("cyan", S_BAR2)} ` : "", l2 = r2.split(`
1948
+ `).length, s = v ? formatInstructionFooter(MULTISELECT_INSTRUCTIONS2, t2) : t2 ? [styleText3("cyan", S_BAR_END2)] : [], h2 = s.join(`
1949
+ `), $ = s.length + 1;
1950
+ return `${r2}${n3}${limitOptions({
1951
+ output: i2.output,
1952
+ options: this.options,
1953
+ cursor: this.cursor,
1954
+ maxItems: i2.maxItems,
1955
+ columnPadding: n3.length,
1956
+ rowPadding: l2 + $,
1957
+ style: p2
1958
+ }).join(`
1959
+ ${n3}`)}
1960
+ ${h2}
1961
+ `;
1962
+ }
1963
+ }
1964
+ }
1965
+ }).prompt();
1966
+ };
1967
+ var log2 = {
1968
+ message: (s = [], {
1969
+ symbol: e = styleText3("gray", S_BAR2),
1970
+ secondarySymbol: r2 = styleText3("gray", S_BAR2),
1971
+ output: m3 = process.stdout,
1972
+ spacing: l2 = 1,
1973
+ withGuide: c2
1974
+ } = {}) => {
1975
+ const t2 = [], o2 = c2 ?? settings.withGuide, f2 = o2 ? r2 : "", O = o2 ? `${e} ` : "", u5 = o2 ? `${r2} ` : "";
1976
+ for (let i2 = 0;i2 < l2; i2++)
1977
+ t2.push(f2);
1978
+ const g2 = Array.isArray(s) ? s : s.split(`
1979
+ `);
1980
+ if (g2.length > 0) {
1981
+ const [i2, ...y] = g2;
1982
+ i2.length > 0 ? t2.push(`${O}${i2}`) : t2.push(o2 ? e : "");
1983
+ for (const p2 of y)
1984
+ p2.length > 0 ? t2.push(`${u5}${p2}`) : t2.push(o2 ? r2 : "");
1985
+ }
1986
+ m3.write(`${t2.join(`
1987
+ `)}
1988
+ `);
1989
+ },
1990
+ info: (s, e) => {
1991
+ log2.message(s, { ...e, symbol: styleText3("blue", S_INFO2) });
1992
+ },
1993
+ success: (s, e) => {
1994
+ log2.message(s, { ...e, symbol: styleText3("green", S_SUCCESS2) });
1995
+ },
1996
+ step: (s, e) => {
1997
+ log2.message(s, { ...e, symbol: styleText3("green", S_STEP_SUBMIT2) });
1998
+ },
1999
+ warn: (s, e) => {
2000
+ log2.message(s, { ...e, symbol: styleText3("yellow", S_WARN2) });
2001
+ },
2002
+ warning: (s, e) => {
2003
+ log2.warn(s, e);
2004
+ },
2005
+ error: (s, e) => {
2006
+ log2.message(s, { ...e, symbol: styleText3("red", S_ERROR2) });
2007
+ }
2008
+ };
2009
+ var cancel2 = (o2 = "", t2) => {
2010
+ const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText3("gray", S_BAR_END2)} ` : "";
2011
+ i2.write(`${e}${styleText3("red", o2)}
2012
+
2013
+ `);
2014
+ };
2015
+ var intro2 = (o2 = "", t2) => {
2016
+ const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText3("gray", S_BAR_START2)} ` : "";
2017
+ i2.write(`${e}${o2}
2018
+ `);
2019
+ };
2020
+ var outro2 = (o2 = "", t2) => {
2021
+ const i2 = t2?.output ?? process.stdout, e = t2?.withGuide ?? settings.withGuide ? `${styleText3("gray", S_BAR2)}
2022
+ ${styleText3("gray", S_BAR_END2)} ` : "";
2023
+ i2.write(`${e}${o2}
2024
+
2025
+ `);
2026
+ };
2027
+ var W2 = (l2) => styleText3("magenta", l2);
2028
+ var spinner2 = ({
2029
+ indicator: l2 = "dots",
2030
+ onCancel: h2,
2031
+ output: n3 = process.stdout,
2032
+ cancelMessage: G,
2033
+ errorMessage: O,
2034
+ frames: E = unicode2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"],
2035
+ delay: F = unicode2 ? 80 : 120,
2036
+ signal: m3,
2037
+ ...I2
2038
+ } = {}) => {
2039
+ const u5 = isCI2();
2040
+ let M2, T3, d = false, S = false, s = "", p2, w = performance.now();
2041
+ const x = getColumns(n3), k = I2?.styleFrame ?? W2, g2 = (e) => {
2042
+ const r2 = e > 1 ? O ?? settings.messages.error : G ?? settings.messages.cancel;
2043
+ S = e === 1, d && (a2(r2, e), S && typeof h2 == "function" && h2());
2044
+ }, f2 = () => g2(2), i2 = () => g2(1), A = () => {
2045
+ process.on("uncaughtExceptionMonitor", f2), process.on("unhandledRejection", f2), process.on("SIGINT", i2), process.on("SIGTERM", i2), process.on("exit", g2), m3 && m3.addEventListener("abort", i2);
2046
+ }, H = () => {
2047
+ process.removeListener("uncaughtExceptionMonitor", f2), process.removeListener("unhandledRejection", f2), process.removeListener("SIGINT", i2), process.removeListener("SIGTERM", i2), process.removeListener("exit", g2), m3 && m3.removeEventListener("abort", i2);
2048
+ }, y = () => {
2049
+ if (p2 === undefined)
2050
+ return;
2051
+ u5 && n3.write(`
2052
+ `);
2053
+ const r2 = wrapAnsi(p2, x, {
2054
+ hard: true,
2055
+ trim: false
2056
+ }).split(`
2057
+ `);
2058
+ r2.length > 1 && n3.write(import_sisteransi3.cursor.up(r2.length - 1)), n3.write(import_sisteransi3.cursor.to(0)), n3.write(import_sisteransi3.erase.down());
2059
+ }, C2 = (e) => e.replace(/\.+$/, ""), _2 = (e) => {
2060
+ const r2 = (performance.now() - e) / 1000, t2 = Math.floor(r2 / 60), o2 = Math.floor(r2 % 60);
2061
+ return t2 > 0 ? `[${t2}m ${o2}s]` : `[${o2}s]`;
2062
+ }, N = I2.withGuide ?? settings.withGuide, P2 = (e = "") => {
2063
+ d = true, M2 = block({ output: n3 }), s = C2(e), w = performance.now(), N && n3.write(`${styleText3("gray", S_BAR2)}
2064
+ `);
2065
+ let r2 = 0, t2 = 0;
2066
+ A(), T3 = setInterval(() => {
2067
+ if (u5 && s === p2)
2068
+ return;
2069
+ y(), p2 = s;
2070
+ const o2 = k(E[r2]);
2071
+ let v;
2072
+ if (u5)
2073
+ v = `${o2} ${s}...`;
2074
+ else if (l2 === "timer")
2075
+ v = `${o2} ${s} ${_2(w)}`;
2076
+ else {
2077
+ const B = ".".repeat(Math.floor(t2)).slice(0, 3);
2078
+ v = `${o2} ${s}${B}`;
2079
+ }
2080
+ const j = wrapAnsi(v, x, {
2081
+ hard: true,
2082
+ trim: false
2083
+ });
2084
+ n3.write(j), r2 = r2 + 1 < E.length ? r2 + 1 : 0, t2 = t2 < 4 ? t2 + 0.125 : 0;
2085
+ }, F);
2086
+ }, a2 = (e = "", r2 = 0, t2 = false) => {
2087
+ if (!d)
2088
+ return;
2089
+ d = false, clearInterval(T3), y();
2090
+ const o2 = r2 === 0 ? styleText3("green", S_STEP_SUBMIT2) : r2 === 1 ? styleText3("red", S_STEP_CANCEL2) : styleText3("red", S_STEP_ERROR2);
2091
+ s = e ?? s, t2 || (l2 === "timer" ? n3.write(`${o2} ${s} ${_2(w)}
2092
+ `) : n3.write(`${o2} ${s}
2093
+ `)), H(), M2();
2094
+ };
2095
+ return {
2096
+ start: P2,
2097
+ stop: (e = "") => a2(e, 0),
2098
+ message: (e = "") => {
2099
+ s = C2(e ?? s);
2100
+ },
2101
+ cancel: (e = "") => a2(e, 1),
2102
+ error: (e = "") => a2(e, 2),
2103
+ clear: () => a2("", 0, true),
2104
+ get isCancelled() {
2105
+ return S;
2106
+ }
2107
+ };
2108
+ };
2109
+ var u5 = {
2110
+ light: unicodeOr2("─", "-"),
2111
+ heavy: unicodeOr2("━", "="),
2112
+ block: unicodeOr2("█", "#")
2113
+ };
2114
+ var SELECT_INSTRUCTIONS2 = [
2115
+ `${styleText3("dim", "↑/↓")} to navigate`,
2116
+ `${styleText3("dim", "Enter:")} confirm`
2117
+ ];
2118
+ var c2 = (t2, o2) => t2.includes(`
2119
+ `) ? t2.split(`
2120
+ `).map((d) => o2(d)).join(`
2121
+ `) : o2(t2);
2122
+ var select = (t2) => {
2123
+ const o2 = (n3, m3) => {
2124
+ if (n3 === undefined)
2125
+ return "";
2126
+ const s = n3.label ?? String(n3.value);
2127
+ switch (m3) {
2128
+ case "disabled":
2129
+ return `${styleText3("gray", S_RADIO_INACTIVE2)} ${c2(s, (i2) => styleText3("gray", i2))}${n3.hint ? ` ${styleText3("dim", `(${n3.hint ?? "disabled"})`)}` : ""}`;
2130
+ case "selected":
2131
+ return `${c2(s, (i2) => styleText3("dim", i2))}`;
2132
+ case "active":
2133
+ return `${styleText3("green", S_RADIO_ACTIVE2)} ${s}${n3.hint ? ` ${styleText3("dim", `(${n3.hint})`)}` : ""}`;
2134
+ case "cancelled":
2135
+ return `${c2(s, (i2) => styleText3(["strikethrough", "dim"], i2))}`;
2136
+ default:
2137
+ return `${styleText3("dim", S_RADIO_INACTIVE2)} ${c2(s, (i2) => styleText3("dim", i2))}`;
2138
+ }
2139
+ }, d = t2.showInstructions ?? true;
2140
+ return new n$1({
2141
+ options: t2.options,
2142
+ signal: t2.signal,
2143
+ input: t2.input,
2144
+ output: t2.output,
2145
+ initialValue: t2.initialValue,
2146
+ render() {
2147
+ const n3 = t2.withGuide ?? settings.withGuide, m3 = `${symbol2(this.state)} `, s = `${symbolBar(this.state)} `, i2 = wrapTextWithPrefix(t2.output, t2.message, s, m3), u6 = `${n3 ? `${styleText3("gray", S_BAR2)}
2148
+ ` : ""}${i2}
2149
+ `;
2150
+ switch (this.state) {
2151
+ case "submit": {
2152
+ const r2 = n3 ? `${styleText3("gray", S_BAR2)} ` : "", a2 = wrapTextWithPrefix(t2.output, o2(this.options[this.cursor], "selected"), r2);
2153
+ return `${u6}${a2}`;
2154
+ }
2155
+ case "cancel": {
2156
+ const r2 = n3 ? `${styleText3("gray", S_BAR2)} ` : "", a2 = wrapTextWithPrefix(t2.output, o2(this.options[this.cursor], "cancelled"), r2);
2157
+ return `${u6}${a2}${n3 ? `
2158
+ ${styleText3("gray", S_BAR2)}` : ""}`;
2159
+ }
2160
+ default: {
2161
+ const r2 = n3 ? `${styleText3("cyan", S_BAR2)} ` : "", a2 = u6.split(`
2162
+ `).length, p2 = d ? formatInstructionFooter(SELECT_INSTRUCTIONS2, n3) : n3 ? [styleText3("cyan", S_BAR_END2)] : [], b2 = p2.join(`
2163
+ `), f2 = p2.length + 1;
2164
+ return `${u6}${r2}${limitOptions({
2165
+ output: t2.output,
2166
+ cursor: this.cursor,
2167
+ options: this.options,
2168
+ maxItems: t2.maxItems,
2169
+ columnPadding: r2.length,
2170
+ rowPadding: a2 + f2,
2171
+ style: (g2, x) => o2(g2, g2.disabled ? "disabled" : x ? "active" : "inactive")
2172
+ }).join(`
2173
+ ${r2}`)}
2174
+ ${b2}
2175
+ `;
2176
+ }
2177
+ }
2178
+ }
2179
+ }).prompt();
2180
+ };
2181
+ var i2 = `${styleText3("gray", S_BAR2)} `;
2182
+ var text2 = (e) => new n2({
2183
+ validate: e.validate,
2184
+ placeholder: e.placeholder,
2185
+ defaultValue: e.defaultValue,
2186
+ initialValue: e.initialValue,
2187
+ output: e.output,
2188
+ signal: e.signal,
2189
+ input: e.input,
2190
+ render() {
2191
+ const i3 = e?.withGuide ?? settings.withGuide, s = `${`${i3 ? `${styleText3("gray", S_BAR2)}
2192
+ ` : ""}${symbol2(this.state)} `}${e.message}
2193
+ `, c3 = e.placeholder && e.placeholder.length > 0 ? styleText3("inverse", e.placeholder[0]) + styleText3("dim", e.placeholder.slice(1)) : styleText3(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c3, l2 = this.value ?? "";
2194
+ switch (this.state) {
2195
+ case "error": {
2196
+ const n3 = this.error ? ` ${styleText3("yellow", this.error)}` : "", r2 = i3 ? `${styleText3("yellow", S_BAR2)} ` : "", d = i3 ? styleText3("yellow", S_BAR_END2) : "";
2197
+ return `${s.trim()}
2198
+ ${r2}${o2}
2199
+ ${d}${n3}
2200
+ `;
2201
+ }
2202
+ case "submit": {
2203
+ const n3 = l2 ? ` ${styleText3("dim", l2)}` : "", r2 = i3 ? styleText3("gray", S_BAR2) : "";
2204
+ return `${s}${r2}${n3}`;
2205
+ }
2206
+ case "cancel": {
2207
+ const n3 = l2 ? ` ${styleText3(["strikethrough", "dim"], l2)}` : "", r2 = i3 ? styleText3("gray", S_BAR2) : "";
2208
+ return `${s}${r2}${n3}${l2.trim() ? `
2209
+ ${r2}` : ""}`;
2210
+ }
2211
+ default: {
2212
+ const n3 = i3 ? `${styleText3("cyan", S_BAR2)} ` : "", r2 = i3 ? styleText3("cyan", S_BAR_END2) : "";
2213
+ return `${s}${n3}${o2}
2214
+ ${r2}
2215
+ `;
2216
+ }
2217
+ }
2218
+ }
2219
+ }).prompt();
2220
+
58
2221
  // src/agent-setup.ts
59
- import * as prompts from "@clack/prompts";
60
2222
  import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
61
2223
  import { dirname, join as join2, resolve } from "node:path";
62
2224
 
@@ -74,19 +2236,19 @@ function runCaptured(command, options) {
74
2236
  env: options.env ?? process.env,
75
2237
  stdio: ["ignore", "pipe", "pipe"]
76
2238
  });
77
- let stdout = "";
2239
+ let stdout2 = "";
78
2240
  let stderr = "";
79
2241
  child.stdout.setEncoding("utf8");
80
2242
  child.stderr.setEncoding("utf8");
81
2243
  child.stdout.on("data", (chunk) => {
82
- stdout += chunk;
2244
+ stdout2 += chunk;
83
2245
  });
84
2246
  child.stderr.on("data", (chunk) => {
85
2247
  stderr += chunk;
86
2248
  });
87
2249
  child.on("error", reject);
88
2250
  child.on("close", (code, signal) => {
89
- resolve({ exitCode: code ?? (signal ? 1 : 0), stdout, stderr });
2251
+ resolve({ exitCode: code ?? (signal ? 1 : 0), stdout: stdout2, stderr });
90
2252
  });
91
2253
  });
92
2254
  }
@@ -334,7 +2496,7 @@ async function chooseClients(parsed) {
334
2496
  if (!process.stdin.isTTY) {
335
2497
  throw new Error("Interactive setup needs a terminal. Pass --clients and --yes instead.");
336
2498
  }
337
- const selected = await prompts.multiselect({
2499
+ const selected = await multiselect({
338
2500
  message: "Connect which local coding clients?",
339
2501
  required: true,
340
2502
  options: CLIENTS.map((client) => ({
@@ -344,8 +2506,8 @@ async function chooseClients(parsed) {
344
2506
  })),
345
2507
  initialValues: detected
346
2508
  });
347
- if (prompts.isCancel(selected)) {
348
- prompts.cancel("No agent clients were configured.");
2509
+ if (isCancel(selected)) {
2510
+ cancel2("No agent clients were configured.");
349
2511
  return;
350
2512
  }
351
2513
  return selected;
@@ -379,29 +2541,28 @@ async function runAgentSetup(argv, cliName) {
379
2541
  const clients = await chooseClients(parsed);
380
2542
  if (!clients)
381
2543
  return;
382
- prompts.intro("superslate local agent context");
2544
+ intro2("superslate local agent context");
383
2545
  if (parsed.dryRun) {
384
2546
  for (const client of clients) {
385
- prompts.log.info(`${client}
2547
+ log2.info(`${client}
386
2548
  ${dryRunDescription(client, root)}`);
387
2549
  }
388
- prompts.outro("Dry run complete. No client configuration was changed.");
2550
+ outro2("Dry run complete. No client configuration was changed.");
389
2551
  return;
390
2552
  }
391
- const progress = prompts.spinner();
2553
+ const progress = spinner2();
392
2554
  progress.start("Testing the local MCP server");
393
2555
  await smokeServer(root);
394
2556
  progress.stop("Local MCP server passed its protocol self-check");
395
2557
  for (const client of clients) {
396
2558
  const result = client === "codex" ? await configureCodex(root) : client === "cursor" ? await configureCursor(root) : await configureClaude(root);
397
- prompts.log.success(`${client}: ${result}`);
2559
+ log2.success(`${client}: ${result}`);
398
2560
  }
399
- prompts.log.info("Restart configured clients, then ask: “Use plan_change for my next feature.”");
400
- prompts.outro("superslate agent context is ready.");
2561
+ log2.info("Restart configured clients, then ask: “Use plan_change for my next feature.”");
2562
+ outro2("superslate agent context is ready.");
401
2563
  }
402
2564
 
403
2565
  // src/deployment-cli.ts
404
- import * as prompts3 from "@clack/prompts";
405
2566
  import { readFile as readFile3 } from "node:fs/promises";
406
2567
  import { resolve as resolve2 } from "node:path";
407
2568
 
@@ -616,12 +2777,11 @@ async function applyDeploymentSelection(repositoryRoot, projectName, selection)
616
2777
  }
617
2778
 
618
2779
  // src/deployment-prompts.ts
619
- import * as prompts2 from "@clack/prompts";
620
2780
  class DeploymentPromptCancelled extends Error {
621
2781
  }
622
2782
  async function unwrap(value) {
623
- if (prompts2.isCancel(value)) {
624
- prompts2.cancel("Deployment configuration was not changed.");
2783
+ if (isCancel(value)) {
2784
+ cancel2("Deployment configuration was not changed.");
625
2785
  throw new DeploymentPromptCancelled;
626
2786
  }
627
2787
  return value;
@@ -642,7 +2802,7 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
642
2802
  haEnabled: defaults.haEnabled ?? false
643
2803
  };
644
2804
  }
645
- const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap(await prompts2.select({
2805
+ const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap(await select({
646
2806
  message: "Backend cloud",
647
2807
  options: [
648
2808
  { value: "aws", label: "AWS", hint: "ECS Fargate + RDS PostgreSQL" },
@@ -650,7 +2810,7 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
650
2810
  { value: "azure", label: "Azure", hint: "Container Apps + Flexible Server" }
651
2811
  ]
652
2812
  })));
653
- const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap(await prompts2.select({
2813
+ const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap(await select({
654
2814
  message: "Frontend host",
655
2815
  options: [
656
2816
  { value: "native", label: "Cloud native", hint: "Managed with the backend" },
@@ -662,7 +2822,7 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
662
2822
  }
663
2823
  ]
664
2824
  })));
665
- const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap(await prompts2.select({
2825
+ const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap(await select({
666
2826
  message: "Object storage",
667
2827
  options: storageProvidersByCloud[cloud].map((provider) => ({
668
2828
  value: provider,
@@ -670,29 +2830,29 @@ async function collectDeploymentSelection(defaults = {}, nonInteractive = false)
670
2830
  hint: provider === defaultStorageProviders[cloud] ? "Cloud-native default" : ""
671
2831
  }))
672
2832
  }))));
673
- const environment = defaults.environment ?? await unwrap(await prompts2.text({
2833
+ const environment = defaults.environment ?? await unwrap(await text2({
674
2834
  message: "Deployment environment",
675
2835
  placeholder: "production",
676
2836
  defaultValue: "production",
677
2837
  validate: (value) => validateDeploymentEnvironment(value || "production")
678
2838
  }));
679
- const region = defaults.region ?? await unwrap(await prompts2.text({
2839
+ const region = defaults.region ?? await unwrap(await text2({
680
2840
  message: `${cloud.toUpperCase()} region`,
681
2841
  placeholder: defaultRegions[cloud],
682
2842
  defaultValue: defaultRegions[cloud],
683
2843
  validate: (value) => validateRegion(value || defaultRegions[cloud])
684
2844
  }));
685
- const apiDomain = defaults.apiDomain ?? await unwrap(await prompts2.text({
2845
+ const apiDomain = defaults.apiDomain ?? await unwrap(await text2({
686
2846
  message: "Production API domain",
687
2847
  placeholder: "api.example.com",
688
2848
  validate: (value) => validateDomain(value ?? "")
689
2849
  }));
690
- const frontendDomain = defaults.frontendDomain ?? await unwrap(await prompts2.text({
2850
+ const frontendDomain = defaults.frontendDomain ?? await unwrap(await text2({
691
2851
  message: "Production frontend domain",
692
2852
  placeholder: "app.example.com",
693
2853
  validate: (value) => validateDomain(value ?? "")
694
2854
  }));
695
- const haEnabled = defaults.haEnabled ?? await unwrap(await prompts2.confirm({
2855
+ const haEnabled = defaults.haEnabled ?? await unwrap(await confirm2({
696
2856
  message: "Enable the higher-availability profile?",
697
2857
  initialValue: false
698
2858
  }));
@@ -750,17 +2910,17 @@ async function runDeploymentConfigure(argv, productName, repositoryRoot = proces
750
2910
  const rootPackage = JSON.parse(await readFile3(`${root}/package.json`, "utf8"));
751
2911
  if (!rootPackage.name)
752
2912
  throw new Error("Root package name is required for deployment setup.");
753
- prompts3.intro(`${productName} deployment setup`);
2913
+ intro2(`${productName} deployment setup`);
754
2914
  try {
755
2915
  const selection = await collectDeploymentSelection(parsed, parsed.yes);
756
2916
  const removed = await applyDeploymentSelection(root, rootPackage.name, selection);
757
- prompts3.log.success(`${selection.cloud.toUpperCase()} + ${selection.storageProvider} + ${selection.frontendTarget} is locked for ${selection.environment}.`);
758
- prompts3.log.info(`${removed.length} unused deployment paths removed.`);
759
- prompts3.log.step("Next");
760
- prompts3.log.message(`Review deployment/config.json
2917
+ log2.success(`${selection.cloud.toUpperCase()} + ${selection.storageProvider} + ${selection.frontendTarget} is locked for ${selection.environment}.`);
2918
+ log2.info(`${removed.length} unused deployment paths removed.`);
2919
+ log2.step("Next");
2920
+ log2.message(`Review deployment/config.json
761
2921
  Configure the protected GitHub environment
762
2922
  Dispatch .github/workflows/deploy-cloud.yml`);
763
- prompts3.outro("Deployment configuration is ready to commit.");
2923
+ outro2("Deployment configuration is ready to commit.");
764
2924
  } catch (error) {
765
2925
  if (error instanceof DeploymentPromptCancelled)
766
2926
  return;
@@ -783,19 +2943,19 @@ function runCaptured2(command, options) {
783
2943
  env: options.env ?? process.env,
784
2944
  stdio: ["ignore", "pipe", "pipe"]
785
2945
  });
786
- let stdout = "";
2946
+ let stdout2 = "";
787
2947
  let stderr = "";
788
2948
  child.stdout.setEncoding("utf8");
789
2949
  child.stderr.setEncoding("utf8");
790
2950
  child.stdout.on("data", (chunk) => {
791
- stdout += chunk;
2951
+ stdout2 += chunk;
792
2952
  });
793
2953
  child.stderr.on("data", (chunk) => {
794
2954
  stderr += chunk;
795
2955
  });
796
2956
  child.on("error", reject);
797
2957
  child.on("close", (code, signal) => {
798
- resolve3({ exitCode: code ?? (signal ? 1 : 0), stdout, stderr });
2958
+ resolve3({ exitCode: code ?? (signal ? 1 : 0), stdout: stdout2, stderr });
799
2959
  });
800
2960
  });
801
2961
  }
@@ -834,12 +2994,11 @@ function isEntrypoint(moduleUrl) {
834
2994
  }
835
2995
 
836
2996
  // src/deployment-prompts.ts
837
- import * as prompts4 from "@clack/prompts";
838
2997
  class DeploymentPromptCancelled2 extends Error {
839
2998
  }
840
2999
  async function unwrap2(value) {
841
- if (prompts4.isCancel(value)) {
842
- prompts4.cancel("Deployment configuration was not changed.");
3000
+ if (isCancel(value)) {
3001
+ cancel2("Deployment configuration was not changed.");
843
3002
  throw new DeploymentPromptCancelled2;
844
3003
  }
845
3004
  return value;
@@ -860,7 +3019,7 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
860
3019
  haEnabled: defaults.haEnabled ?? false
861
3020
  };
862
3021
  }
863
- const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap2(await prompts4.select({
3022
+ const cloud = defaults.cloud ?? parseDeploymentCloud(await unwrap2(await select({
864
3023
  message: "Backend cloud",
865
3024
  options: [
866
3025
  { value: "aws", label: "AWS", hint: "ECS Fargate + RDS PostgreSQL" },
@@ -868,7 +3027,7 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
868
3027
  { value: "azure", label: "Azure", hint: "Container Apps + Flexible Server" }
869
3028
  ]
870
3029
  })));
871
- const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap2(await prompts4.select({
3030
+ const frontendTarget = defaults.frontendTarget ?? parseFrontendTarget(await unwrap2(await select({
872
3031
  message: "Frontend host",
873
3032
  options: [
874
3033
  { value: "native", label: "Cloud native", hint: "Managed with the backend" },
@@ -880,7 +3039,7 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
880
3039
  }
881
3040
  ]
882
3041
  })));
883
- const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap2(await prompts4.select({
3042
+ const storageProvider = defaults.storageProvider ?? (storageProvidersByCloud[cloud].length === 1 ? storageProvidersByCloud[cloud][0] ?? defaultStorageProviders[cloud] : parseStorageProvider(await unwrap2(await select({
884
3043
  message: "Object storage",
885
3044
  options: storageProvidersByCloud[cloud].map((provider) => ({
886
3045
  value: provider,
@@ -888,29 +3047,29 @@ async function collectDeploymentSelection2(defaults = {}, nonInteractive = false
888
3047
  hint: provider === defaultStorageProviders[cloud] ? "Cloud-native default" : ""
889
3048
  }))
890
3049
  }))));
891
- const environment = defaults.environment ?? await unwrap2(await prompts4.text({
3050
+ const environment = defaults.environment ?? await unwrap2(await text2({
892
3051
  message: "Deployment environment",
893
3052
  placeholder: "production",
894
3053
  defaultValue: "production",
895
3054
  validate: (value) => validateDeploymentEnvironment(value || "production")
896
3055
  }));
897
- const region = defaults.region ?? await unwrap2(await prompts4.text({
3056
+ const region = defaults.region ?? await unwrap2(await text2({
898
3057
  message: `${cloud.toUpperCase()} region`,
899
3058
  placeholder: defaultRegions[cloud],
900
3059
  defaultValue: defaultRegions[cloud],
901
3060
  validate: (value) => validateRegion(value || defaultRegions[cloud])
902
3061
  }));
903
- const apiDomain = defaults.apiDomain ?? await unwrap2(await prompts4.text({
3062
+ const apiDomain = defaults.apiDomain ?? await unwrap2(await text2({
904
3063
  message: "Production API domain",
905
3064
  placeholder: "api.example.com",
906
3065
  validate: (value) => validateDomain(value ?? "")
907
3066
  }));
908
- const frontendDomain = defaults.frontendDomain ?? await unwrap2(await prompts4.text({
3067
+ const frontendDomain = defaults.frontendDomain ?? await unwrap2(await text2({
909
3068
  message: "Production frontend domain",
910
3069
  placeholder: "app.example.com",
911
3070
  validate: (value) => validateDomain(value ?? "")
912
3071
  }));
913
- const haEnabled = defaults.haEnabled ?? await unwrap2(await prompts4.confirm({
3072
+ const haEnabled = defaults.haEnabled ?? await unwrap2(await confirm2({
914
3073
  message: "Enable the higher-availability profile?",
915
3074
  initialValue: false
916
3075
  }));
@@ -1129,11 +3288,92 @@ async function applyDeploymentSelection2(repositoryRoot, projectName, selection)
1129
3288
  // src/scaffold.ts
1130
3289
  import { execFile } from "node:child_process";
1131
3290
  import { createHash } from "node:crypto";
1132
- import { cp, lstat, mkdir as mkdir4, mkdtemp, readFile as readFile5, readdir, rm as rm3, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
3291
+ import { cp, lstat, mkdir as mkdir4, mkdtemp, readFile as readFile5, readdir, rm as rm4, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
1133
3292
  import { tmpdir } from "node:os";
1134
- import { basename, join as join6, relative, resolve as resolve3 } from "node:path";
3293
+ import { basename, join as join7, relative, resolve as resolve3 } from "node:path";
1135
3294
  import { promisify } from "node:util";
1136
3295
 
3296
+ // src/delivery.ts
3297
+ import { createWriteStream } from "node:fs";
3298
+ import { rm as rm3 } from "node:fs/promises";
3299
+ import { join as join6 } from "node:path";
3300
+ import { Readable } from "node:stream";
3301
+ import { pipeline } from "node:stream/promises";
3302
+ var RELEASE_TAG_PATTERN2 = /^v\d+\.\d+\.\d+(?:-rc\.\d+)?$/;
3303
+ var INDEX_TIMEOUT_MS = 15000;
3304
+ var DOWNLOAD_TIMEOUT_MS = 300000;
3305
+ function deliveryBaseUrl(environment = process.env) {
3306
+ const configured = environment[DELIVERY_URL_VARIABLE]?.trim();
3307
+ return (configured || DELIVERY_BASE_URL).replace(/\/+$/, "");
3308
+ }
3309
+ function releaseAssetNames(releaseTag) {
3310
+ const artifact = `foundation-source-${releaseTag}.tar.gz`;
3311
+ return {
3312
+ artifact,
3313
+ checksum: `${artifact}.sha256`,
3314
+ manifest: `foundation-source-${releaseTag}.manifest.json`
3315
+ };
3316
+ }
3317
+ function describeFailure(status, subject) {
3318
+ if (status === 401) {
3319
+ return "That licence key was not accepted. Copy it exactly from your purchase receipt or the customer portal (polar.sh).";
3320
+ }
3321
+ if (status === 429) {
3322
+ return "Too many download requests for this licence key. Wait a minute and try again.";
3323
+ }
3324
+ if (status === 404)
3325
+ return `${subject} is not available for download.`;
3326
+ if (status >= 500) {
3327
+ return "Source delivery is temporarily unavailable. Wait a few minutes and try again.";
3328
+ }
3329
+ return `Source delivery refused the request (HTTP ${status}).`;
3330
+ }
3331
+ async function requestDelivery(url, init, subject) {
3332
+ let response;
3333
+ try {
3334
+ response = await fetch(url, init);
3335
+ } catch {
3336
+ throw new Error("Could not reach source delivery. Check your network connection and try again.");
3337
+ }
3338
+ if (!response.ok)
3339
+ throw new Error(describeFailure(response.status, subject));
3340
+ return response;
3341
+ }
3342
+ async function resolveRelease(licenseKey, baseUrl = deliveryBaseUrl()) {
3343
+ const response = await requestDelivery(`${baseUrl}/v1/releases`, {
3344
+ method: "POST",
3345
+ headers: { "content-type": "application/json" },
3346
+ body: JSON.stringify({ key: licenseKey }),
3347
+ signal: AbortSignal.timeout(INDEX_TIMEOUT_MS)
3348
+ }, "The release index");
3349
+ let index;
3350
+ try {
3351
+ index = await response.json();
3352
+ } catch {
3353
+ index = undefined;
3354
+ }
3355
+ if (!index || !RELEASE_TAG_PATTERN2.test(index.latest) || !Array.isArray(index.versions)) {
3356
+ throw new Error(`Source delivery returned an unreadable release index.`);
3357
+ }
3358
+ return index;
3359
+ }
3360
+ async function downloadAsset(licenseKey, releaseTag, assetName, directory, baseUrl = deliveryBaseUrl()) {
3361
+ const response = await requestDelivery(`${baseUrl}/v1/source/${encodeURIComponent(releaseTag)}/${encodeURIComponent(assetName)}`, {
3362
+ headers: { authorization: `Bearer ${licenseKey}` },
3363
+ signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
3364
+ }, releaseTag);
3365
+ if (!response.body)
3366
+ throw new Error(`Source delivery returned an empty ${assetName}.`);
3367
+ const path = join6(directory, assetName);
3368
+ try {
3369
+ await pipeline(Readable.fromWeb(response.body), createWriteStream(path));
3370
+ } catch {
3371
+ await rm3(path, { force: true });
3372
+ throw new Error(`Downloading ${assetName} was interrupted. Try again in a few minutes.`);
3373
+ }
3374
+ return path;
3375
+ }
3376
+
1137
3377
  // src/core.ts
1138
3378
  import { randomBytes } from "node:crypto";
1139
3379
  import { extname } from "node:path";
@@ -1364,7 +3604,49 @@ into this repository.
1364
3604
  }
1365
3605
  return rewritten;
1366
3606
  }
1367
- var SELLER_ONLY_ROOT_SCRIPTS = ["release:distribute"];
3607
+ var REQUIRED_BUYER_CLI_CONSTANTS = ["CLI_NAME", "CLI_PACKAGE_NAME", "DEFAULT_SCOPE"];
3608
+ function rewriteBuyerCliConstants(content, scope, brandName) {
3609
+ const buyerVariablePrefix = BUYER_CLI_NAME.toUpperCase().replaceAll("-", "_");
3610
+ const buyerConstants = [
3611
+ ["CLI_NAME", BUYER_CLI_NAME],
3612
+ ["CLI_PACKAGE_NAME", BUYER_CLI_PACKAGE_NAME],
3613
+ ["DEFAULT_SCOPE", normalizeScope2(scope)],
3614
+ ["SOURCE_BRAND_NAME", brandName],
3615
+ ["TEMPLATE_REPOSITORY", "OWNER/REPOSITORY"],
3616
+ ["DELIVERY_BASE_URL", "https://releases.example.com"],
3617
+ ["DELIVERY_URL_VARIABLE", `${buyerVariablePrefix}_DELIVERY_URL`],
3618
+ ["LICENSE_KEY_VARIABLE", `${buyerVariablePrefix}_LICENSE_KEY`],
3619
+ ["LICENSE_KEY_PREFIX", "LICENSE-"]
3620
+ ];
3621
+ let rewritten = content;
3622
+ for (const [name, value] of buyerConstants) {
3623
+ const declaration = new RegExp(`^export const ${name} = '[^']*'$`, "m");
3624
+ if (!declaration.test(rewritten)) {
3625
+ if (REQUIRED_BUYER_CLI_CONSTANTS.includes(name)) {
3626
+ throw new Error(`Source CLI constants are missing ${name}.`);
3627
+ }
3628
+ continue;
3629
+ }
3630
+ rewritten = rewritten.replace(declaration, `export const ${name} = '${value}'`);
3631
+ }
3632
+ const leaked = [
3633
+ CLI_PACKAGE_NAME,
3634
+ SOURCE_BRAND_NAME,
3635
+ DELIVERY_BASE_URL,
3636
+ DELIVERY_URL_VARIABLE,
3637
+ LICENSE_KEY_VARIABLE2,
3638
+ LICENSE_KEY_PREFIX
3639
+ ].filter((identity) => rewritten.includes(identity));
3640
+ if (leaked.length > 0) {
3641
+ throw new Error(`Buyer CLI constants still name the source product: ${leaked.join(", ")}`);
3642
+ }
3643
+ return rewritten;
3644
+ }
3645
+ var SELLER_ONLY_ROOT_SCRIPTS = [
3646
+ "release:distribute",
3647
+ "release:publish-cli",
3648
+ "release:upload"
3649
+ ];
1368
3650
  function stripSellerOnlyRootScripts(content) {
1369
3651
  const manifest = JSON.parse(content);
1370
3652
  for (const script of SELLER_ONLY_ROOT_SCRIPTS)
@@ -1434,8 +3716,6 @@ function isTemplatePathExcluded(relativePath) {
1434
3716
  return true;
1435
3717
  if (normalized === "internal" || normalized.startsWith("internal/"))
1436
3718
  return true;
1437
- if (normalized === ".github/workflows/publish-npm.yml")
1438
- return true;
1439
3719
  if (normalized === ".github/workflows/internal-commercial.yml")
1440
3720
  return true;
1441
3721
  if (normalized === "apps/worker" || normalized.startsWith("apps/worker/"))
@@ -1503,7 +3783,7 @@ async function copyLocalTemplate(source, target) {
1503
3783
  async function assertNoSymbolicLinks(directory, root = directory, skipExcludedPaths = false) {
1504
3784
  const entries = await readdir(directory, { withFileTypes: true });
1505
3785
  for (const entry of entries) {
1506
- const path = join6(directory, entry.name);
3786
+ const path = join7(directory, entry.name);
1507
3787
  const relativePath = relative(root, path);
1508
3788
  if (skipExcludedPaths && isTemplatePathExcluded(relativePath))
1509
3789
  continue;
@@ -1526,57 +3806,33 @@ function verifyReleaseMetadata(checksum, manifest, artifactName, digest, templat
1526
3806
  throw new Error(`${CLI_NAME2} release manifest does not match the downloaded source artifact.`);
1527
3807
  }
1528
3808
  }
1529
- async function downloadReleaseAsset(templateRef, fileName, directory) {
1530
- try {
1531
- await execFileAsync("gh", [
1532
- "release",
1533
- "download",
1534
- templateRef,
1535
- "--repo",
1536
- TEMPLATE_REPOSITORY,
1537
- "--pattern",
1538
- fileName,
1539
- "--dir",
1540
- directory
1541
- ]);
1542
- } catch {
1543
- throw new Error(`Unable to download ${templateRef}. Confirm that GitHub CLI is installed, run ` + `\`gh auth login\`, and accept your ${CLI_NAME2} repository invitation.`);
1544
- }
1545
- }
1546
- async function downloadGitHubTemplate(target, templateRef) {
1547
- if (!/^v\d+\.\d+\.\d+(?:-rc\.\d+)?$/.test(templateRef)) {
1548
- throw new Error(`${CLI_NAME2} template reference must be an immutable release tag: ${templateRef}`);
1549
- }
1550
- const temporaryDirectory = await mkdtemp(join6(tmpdir(), `${CLI_NAME2}-`));
1551
- const artifactName = `foundation-source-${templateRef}.tar.gz`;
1552
- const checksumName = `${artifactName}.sha256`;
1553
- const manifestName = `foundation-source-${templateRef}.manifest.json`;
1554
- const archivePath = join6(temporaryDirectory, artifactName);
1555
- const extractedPath = join6(temporaryDirectory, "template");
3809
+ async function downloadLicensedTemplate(target, licenseKey, sourceVersion) {
3810
+ const baseUrl = deliveryBaseUrl();
3811
+ const releaseTag = sourceVersion ?? (await resolveRelease(licenseKey, baseUrl)).latest;
3812
+ const { artifact, checksum: checksumName, manifest: manifestName } = releaseAssetNames(releaseTag);
3813
+ const temporaryDirectory = await mkdtemp(join7(tmpdir(), `${CLI_NAME2}-`));
3814
+ const extractedPath = join7(temporaryDirectory, "template");
1556
3815
  try {
1557
- await execFileAsync("gh", ["auth", "status", "--hostname", "github.com"]).catch(() => {
1558
- throw new Error(`${CLI_NAME2} source access requires GitHub CLI authentication. Run \`gh auth login\` first.`);
1559
- });
1560
- await downloadReleaseAsset(templateRef, artifactName, temporaryDirectory);
1561
- await downloadReleaseAsset(templateRef, checksumName, temporaryDirectory);
1562
- await downloadReleaseAsset(templateRef, manifestName, temporaryDirectory);
3816
+ const archivePath = await downloadAsset(licenseKey, releaseTag, artifact, temporaryDirectory, baseUrl);
3817
+ await downloadAsset(licenseKey, releaseTag, checksumName, temporaryDirectory, baseUrl);
3818
+ await downloadAsset(licenseKey, releaseTag, manifestName, temporaryDirectory, baseUrl);
1563
3819
  const archive = await readFile5(archivePath);
1564
3820
  const digest = createHash("sha256").update(archive).digest("hex");
1565
- const checksum = await readFile5(join6(temporaryDirectory, checksumName), "utf8");
1566
- const manifest = JSON.parse(await readFile5(join6(temporaryDirectory, manifestName), "utf8"));
1567
- verifyReleaseMetadata(checksum, manifest, artifactName, digest, templateRef);
3821
+ const checksum = await readFile5(join7(temporaryDirectory, checksumName), "utf8");
3822
+ const manifest = JSON.parse(await readFile5(join7(temporaryDirectory, manifestName), "utf8"));
3823
+ verifyReleaseMetadata(checksum, manifest, artifact, digest, releaseTag);
1568
3824
  await mkdir4(extractedPath);
1569
3825
  await execFileAsync("tar", ["-xzf", archivePath, "-C", extractedPath, "--strip-components=1"]);
1570
3826
  await copyLocalTemplate(extractedPath, target);
1571
3827
  } finally {
1572
- await rm3(temporaryDirectory, { recursive: true, force: true });
3828
+ await rm4(temporaryDirectory, { recursive: true, force: true });
1573
3829
  }
1574
3830
  }
1575
3831
  async function walk(directory) {
1576
3832
  const entries = await readdir(directory, { withFileTypes: true });
1577
3833
  const paths = [];
1578
3834
  for (const entry of entries) {
1579
- const path = join6(directory, entry.name);
3835
+ const path = join7(directory, entry.name);
1580
3836
  if (entry.isSymbolicLink()) {
1581
3837
  throw new Error(`Generated template contains a symbolic link: ${path}`);
1582
3838
  }
@@ -1618,7 +3874,7 @@ async function applyScopeRewrite(target, scope) {
1618
3874
  async function applyBrandRewrite(target, brandName) {
1619
3875
  const report = { files: 0, replacements: 0 };
1620
3876
  for (const entry of BRAND_MANIFEST) {
1621
- const path = join6(target, entry.path);
3877
+ const path = join7(target, entry.path);
1622
3878
  const replacements = await rewriteFile(path, (content) => {
1623
3879
  const result = rewriteBrandContent(content, brandName);
1624
3880
  if (result.replacements > 0 && path.endsWith(".tsx")) {
@@ -1633,27 +3889,27 @@ async function applyBrandRewrite(target, brandName) {
1633
3889
  return report;
1634
3890
  }
1635
3891
  async function generateEnvironmentFiles(target, databasePort = 5432) {
1636
- const serverExample = await readFile5(join6(target, "apps/server/.env.example"), "utf8");
1637
- await writeFile4(join6(target, "apps/server/.env"), generateServerEnv(serverExample, undefined, databasePort));
1638
- const webExample = await readFile5(join6(target, "apps/web/.env.example"), "utf8");
1639
- await writeFile4(join6(target, "apps/web/.env"), webExample);
1640
- const docsExample = await readFile5(join6(target, "apps/docs/.env.example"), "utf8");
1641
- await writeFile4(join6(target, "apps/docs/.env"), docsExample);
1642
- await writeFile4(join6(target, ".env"), `POSTGRES_PORT=${databasePort}
3892
+ const serverExample = await readFile5(join7(target, "apps/server/.env.example"), "utf8");
3893
+ await writeFile4(join7(target, "apps/server/.env"), generateServerEnv(serverExample, undefined, databasePort));
3894
+ const webExample = await readFile5(join7(target, "apps/web/.env.example"), "utf8");
3895
+ await writeFile4(join7(target, "apps/web/.env"), webExample);
3896
+ const docsExample = await readFile5(join7(target, "apps/docs/.env.example"), "utf8");
3897
+ await writeFile4(join7(target, "apps/docs/.env"), docsExample);
3898
+ await writeFile4(join7(target, ".env"), `POSTGRES_PORT=${databasePort}
1643
3899
  `);
1644
3900
  }
1645
3901
  async function neutralizeAgentInstructions(target) {
1646
- const agentPath = join6(target, "AGENTS.md");
1647
- const claudePath = join6(target, "CLAUDE.md");
3902
+ const agentPath = join7(target, "AGENTS.md");
3903
+ const claudePath = join7(target, "CLAUDE.md");
1648
3904
  await writeFile4(agentPath, rewriteBuyerAgentInstructions(await readFile5(agentPath, "utf8")));
1649
3905
  await writeFile4(claudePath, rewriteBuyerClaudeInstructions(await readFile5(claudePath, "utf8")));
1650
- const rootPackagePath = join6(target, "package.json");
3906
+ const rootPackagePath = join7(target, "package.json");
1651
3907
  await writeFile4(rootPackagePath, stripSellerOnlyRootScripts(await readFile5(rootPackagePath, "utf8")));
1652
3908
  }
1653
3909
  async function neutralizeSourceCli(target, scope, brandName) {
1654
3910
  if (String(CLI_NAME2) === BUYER_CLI_NAME && String(CLI_PACKAGE_NAME) === BUYER_CLI_PACKAGE_NAME)
1655
3911
  return;
1656
- const rootPackagePath = join6(target, "package.json");
3912
+ const rootPackagePath = join7(target, "package.json");
1657
3913
  const rootPackage = JSON.parse(await readFile5(rootPackagePath, "utf8"));
1658
3914
  const sourceScript = rootPackage.scripts?.[CLI_NAME2];
1659
3915
  if (!sourceScript)
@@ -1662,7 +3918,7 @@ async function neutralizeSourceCli(target, scope, brandName) {
1662
3918
  delete rootPackage.scripts[CLI_NAME2];
1663
3919
  await writeFile4(rootPackagePath, `${JSON.stringify(rootPackage, null, 2)}
1664
3920
  `);
1665
- const cliPackagePath = join6(target, "packages/create-app/package.json");
3921
+ const cliPackagePath = join7(target, "packages/create-app/package.json");
1666
3922
  const cliPackage = JSON.parse(await readFile5(cliPackagePath, "utf8"));
1667
3923
  if (cliPackage.name !== CLI_PACKAGE_NAME || !cliPackage.bin?.[CLI_NAME2]) {
1668
3924
  throw new Error(`Source CLI package must expose ${CLI_PACKAGE_NAME} as ${CLI_NAME2}.`);
@@ -1670,6 +3926,8 @@ async function neutralizeSourceCli(target, scope, brandName) {
1670
3926
  cliPackage.bin = { [BUYER_CLI_NAME]: "./src/cli.ts" };
1671
3927
  delete cliPackage.description;
1672
3928
  delete cliPackage.homepage;
3929
+ delete cliPackage.bugs;
3930
+ delete cliPackage.author;
1673
3931
  delete cliPackage.repository;
1674
3932
  delete cliPackage.keywords;
1675
3933
  delete cliPackage.files;
@@ -1677,23 +3935,14 @@ async function neutralizeSourceCli(target, scope, brandName) {
1677
3935
  const { name: _sourceName, version: cliVersion, ...cliPackageRemainder } = cliPackage;
1678
3936
  await writeFile4(cliPackagePath, `${JSON.stringify({ name: BUYER_CLI_PACKAGE_NAME, version: cliVersion, private: true, ...cliPackageRemainder }, null, 2)}
1679
3937
  `);
1680
- const constantsPath = join6(target, "packages/create-app/src/constants.ts");
1681
- const constants3 = await readFile5(constantsPath, "utf8");
1682
- const cliDeclaration = `export const CLI_NAME = '${CLI_NAME2}'`;
1683
- const packageDeclaration = `export const CLI_PACKAGE_NAME = '${CLI_PACKAGE_NAME}'`;
1684
- const scopeDeclaration = `export const DEFAULT_SCOPE = '@app'`;
1685
- const repositoryDeclaration = `export const TEMPLATE_REPOSITORY = '${TEMPLATE_REPOSITORY}'`;
1686
- const brandDeclaration = `export const SOURCE_BRAND_NAME = '${SOURCE_BRAND_NAME}'`;
1687
- if (!constants3.includes(cliDeclaration) || !constants3.includes(packageDeclaration) || !constants3.includes(scopeDeclaration) || !constants3.includes(repositoryDeclaration) || !constants3.includes(brandDeclaration)) {
1688
- throw new Error("Source CLI constants do not match the package identity.");
1689
- }
1690
- await writeFile4(constantsPath, constants3.replace(cliDeclaration, `export const CLI_NAME = '${BUYER_CLI_NAME}'`).replace(packageDeclaration, `export const CLI_PACKAGE_NAME = '${BUYER_CLI_PACKAGE_NAME}'`).replace(scopeDeclaration, `export const DEFAULT_SCOPE = '${normalizeScope2(scope)}'`).replace(repositoryDeclaration, "export const TEMPLATE_REPOSITORY = 'OWNER/REPOSITORY'").replace(brandDeclaration, `export const SOURCE_BRAND_NAME = '${brandName}'`));
1691
- const brandingPath = join6(target, "docs/golden-paths/customize-branding-design-tokens.md");
3938
+ const constantsPath = join7(target, "packages/create-app/src/constants.ts");
3939
+ await writeFile4(constantsPath, rewriteBuyerCliConstants(await readFile5(constantsPath, "utf8"), scope, brandName));
3940
+ const brandingPath = join7(target, "docs/golden-paths/customize-branding-design-tokens.md");
1692
3941
  const branding = await readFile5(brandingPath, "utf8");
1693
3942
  await writeFile4(brandingPath, branding.replaceAll(`pnpm ${CLI_NAME2}`, `pnpm ${BUYER_CLI_NAME}`));
1694
- const setupPath = join6(target, "docs/setup.md");
3943
+ const setupPath = join7(target, "docs/setup.md");
1695
3944
  await writeFile4(setupPath, rewriteBuyerSetupInstructions(await readFile5(setupPath, "utf8")));
1696
- const releasesPath = join6(target, "docs/releases.md");
3945
+ const releasesPath = join7(target, "docs/releases.md");
1697
3946
  await writeFile4(releasesPath, rewriteBuyerReleaseInstructions(await readFile5(releasesPath, "utf8")));
1698
3947
  }
1699
3948
  async function initializeRepository(target) {
@@ -1715,12 +3964,12 @@ async function scaffold(options) {
1715
3964
  try {
1716
3965
  if (options.from)
1717
3966
  await copyLocalTemplate(options.from, target);
1718
- else if (options.templateRef)
1719
- await downloadGitHubTemplate(target, options.templateRef);
1720
- else {
1721
- throw new Error(`A local source path or immutable ${CLI_NAME2} release is required.`);
3967
+ else if (options.licenseKey) {
3968
+ await downloadLicensedTemplate(target, options.licenseKey, options.sourceVersion);
3969
+ } else {
3970
+ throw new Error(`A local source path or a ${CLI_NAME2} licence key is required.`);
1722
3971
  }
1723
- const packagePath = join6(target, "package.json");
3972
+ const packagePath = join7(target, "package.json");
1724
3973
  const packageReplacements = await rewriteFile(packagePath, (content) => rewriteRootPackageName(content, options.appName));
1725
3974
  const scope = await applyScopeRewrite(target, options.scope);
1726
3975
  await neutralizeAgentInstructions(target);
@@ -1741,7 +3990,7 @@ async function scaffold(options) {
1741
3990
  }))?.isDirectory()) {
1742
3991
  const entries = await readdir(target);
1743
3992
  if (entries.length === 0)
1744
- await rm3(target, { recursive: true, force: true });
3993
+ await rm4(target, { recursive: true, force: true });
1745
3994
  }
1746
3995
  throw error;
1747
3996
  }
@@ -1758,6 +4007,8 @@ function usage() {
1758
4007
  Create a buyer-owned SaaS application from your licensed ${suggestBrandName(CLI_NAME)} release.
1759
4008
 
1760
4009
  Options:
4010
+ --license-key <key> Licence key from your purchase (or set ${LICENSE_KEY_VARIABLE})
4011
+ --source-version <version> Pin an immutable release (default: the latest you are entitled to)
1761
4012
  --from <path> Use a local source checkout (maintainer/testing)
1762
4013
  --scope <namespace> Advanced workspace namespace override (default: derived from brand)
1763
4014
  --brand <name> Display name (default: derived from app name)
@@ -1802,7 +4053,11 @@ function parseArguments(argv) {
1802
4053
  const argument = argv[index];
1803
4054
  if (argument === "--from")
1804
4055
  parsed.from = takeValue3(argv, index++, argument);
1805
- else if (argument === "--scope")
4056
+ else if (argument === "--license-key")
4057
+ parsed.licenseKey = takeValue3(argv, index++, argument);
4058
+ else if (argument === "--source-version") {
4059
+ parsed.sourceVersion = normalizeSourceVersion(takeValue3(argv, index++, argument));
4060
+ } else if (argument === "--scope")
1806
4061
  parsed.scope = takeValue3(argv, index++, argument);
1807
4062
  else if (argument === "--brand")
1808
4063
  parsed.brandName = takeValue3(argv, index++, argument);
@@ -1870,28 +4125,60 @@ function suggestScope(brandName, fallbackAppName) {
1870
4125
  return namespace || fallbackAppName;
1871
4126
  }
1872
4127
  async function unwrapPrompt(value) {
1873
- if (prompts5.isCancel(value)) {
1874
- prompts5.cancel("No project was created.");
4128
+ if (isCancel(value)) {
4129
+ cancel("No project was created.");
1875
4130
  throw new CliCancelled;
1876
4131
  }
1877
4132
  return value;
1878
4133
  }
4134
+ function describeTargetConflict(appName) {
4135
+ const target = resolve4(process.cwd(), appName);
4136
+ if (!existsSync(target))
4137
+ return;
4138
+ if (!statSync(target).isDirectory())
4139
+ return `./${appName} already exists as a file.`;
4140
+ if (readdirSync(target).length > 0) {
4141
+ return `./${appName} already exists and is not empty. Pick another name, or remove it first.`;
4142
+ }
4143
+ return;
4144
+ }
4145
+ async function collectLicenseKey(parsed) {
4146
+ const supplied = parsed.licenseKey?.trim() ?? readLicenseKeyFromEnvironment();
4147
+ if (supplied) {
4148
+ const error = validateLicenseKey(supplied);
4149
+ if (error)
4150
+ throw new Error(error);
4151
+ return supplied.trim();
4152
+ }
4153
+ if (parsed.yes || !process.stdin.isTTY) {
4154
+ throw new Error(`A licence key is required. Pass --license-key or set ${LICENSE_KEY_VARIABLE}.`);
4155
+ }
4156
+ const entered = await unwrapPrompt(await password({
4157
+ message: "Licence key",
4158
+ validate: (value) => validateLicenseKey(value ?? "")
4159
+ }));
4160
+ return entered.trim();
4161
+ }
1879
4162
  async function collectOptions(parsed) {
1880
4163
  if (parsed.yes && !parsed.appName)
1881
4164
  throw new Error("Pass an app name when using --yes.");
1882
4165
  if (!parsed.yes && !process.stdin.isTTY && !parsed.appName) {
1883
4166
  throw new Error("Interactive prompts need a terminal. Pass an app name and --yes instead.");
1884
4167
  }
1885
- const appName = parsed.appName ?? await unwrapPrompt(await prompts5.text({
4168
+ const appName = parsed.appName ?? await unwrapPrompt(await text({
1886
4169
  message: "App name",
1887
4170
  placeholder: "my-saas",
1888
- validate: (value) => validateAppName(value ?? "")
4171
+ validate: (value) => validateAppName(value ?? "") ?? describeTargetConflict(value ?? "")
1889
4172
  }));
1890
4173
  const appNameError = validateAppName(appName);
1891
4174
  if (appNameError)
1892
4175
  throw new Error(appNameError);
4176
+ const targetConflict = describeTargetConflict(appName);
4177
+ if (targetConflict)
4178
+ throw new Error(targetConflict);
4179
+ const licenseKey = parsed.from ? undefined : await collectLicenseKey(parsed);
1893
4180
  const suggestedBrand = suggestBrandName(appName);
1894
- const brandName = parsed.brandName ?? (parsed.yes ? suggestedBrand : await unwrapPrompt(await prompts5.text({
4181
+ const brandName = parsed.brandName ?? (parsed.yes ? suggestedBrand : await unwrapPrompt(await text({
1895
4182
  message: "Brand name",
1896
4183
  placeholder: suggestedBrand,
1897
4184
  defaultValue: suggestedBrand,
@@ -1901,22 +4188,22 @@ async function collectOptions(parsed) {
1901
4188
  if (brandError)
1902
4189
  throw new Error(brandError);
1903
4190
  const scope = normalizeScope(parsed.scope ?? suggestScope(brandName, appName));
1904
- const initializeGit = parsed.initializeGit ?? (parsed.yes ? true : await unwrapPrompt(await prompts5.confirm({
4191
+ const initializeGit = parsed.initializeGit ?? (parsed.yes ? true : await unwrapPrompt(await confirm({
1905
4192
  message: "Initialize a Git repository?",
1906
4193
  initialValue: true
1907
4194
  })));
1908
- const installDependencies = parsed.installDependencies ?? (parsed.yes ? true : await unwrapPrompt(await prompts5.confirm({
4195
+ const installDependencies = parsed.installDependencies ?? (parsed.yes ? true : await unwrapPrompt(await confirm({
1909
4196
  message: "Install dependencies with pnpm?",
1910
4197
  initialValue: true
1911
4198
  })));
1912
4199
  if (parsed.startDevelopment && !installDependencies) {
1913
4200
  throw new Error("--start requires dependency installation. Remove --no-install.");
1914
4201
  }
1915
- const startDevelopment = parsed.startDevelopment ?? (parsed.yes || !installDependencies ? false : await unwrapPrompt(await prompts5.confirm({
4202
+ const startDevelopment = parsed.startDevelopment ?? (parsed.yes || !installDependencies ? false : await unwrapPrompt(await confirm({
1916
4203
  message: "Start local development now?",
1917
4204
  initialValue: true
1918
4205
  })));
1919
- const setupDeployment = parsed.setupDeployment ?? (parsed.yes ? false : await unwrapPrompt(await prompts5.confirm({
4206
+ const setupDeployment = parsed.setupDeployment ?? (parsed.yes ? false : await unwrapPrompt(await confirm({
1920
4207
  message: "Set up cloud deployment now?",
1921
4208
  initialValue: false
1922
4209
  })));
@@ -1924,6 +4211,8 @@ async function collectOptions(parsed) {
1924
4211
  return {
1925
4212
  appName,
1926
4213
  from: parsed.from ? resolve4(parsed.from) : undefined,
4214
+ licenseKey,
4215
+ sourceVersion: parsed.sourceVersion,
1927
4216
  scope,
1928
4217
  brandName,
1929
4218
  initializeGit,
@@ -1938,15 +4227,6 @@ async function readCliVersion() {
1938
4227
  throw new Error(`${CLI_NAME} package version is missing.`);
1939
4228
  return packageJson.version;
1940
4229
  }
1941
- function templateRefForVersion(version) {
1942
- if (!/^\d+\.\d+\.\d+(?:-rc\.\d+)?$/.test(version)) {
1943
- throw new Error(`${CLI_NAME} package version is not release-compatible: ${version}`);
1944
- }
1945
- if (version === "0.0.0") {
1946
- throw new Error(`This pre-release ${CLI_NAME} checkout requires --from <local-source-path>.`);
1947
- }
1948
- return `v${version}`;
1949
- }
1950
4230
  async function assertTargetAvailable(target) {
1951
4231
  const targetStat = await stat5(target).catch(() => {
1952
4232
  return;
@@ -2008,8 +4288,8 @@ function assertSiblingTarget(source, target) {
2008
4288
  throw new Error(`Create the new app beside the ${CLI_NAME} source checkout, not inside it.`);
2009
4289
  }
2010
4290
  }
2011
- function commandFailureOutput(stdout, stderr) {
2012
- const output = (stderr.trim() || stdout.trim()).split(`
4291
+ function commandFailureOutput(stdout2, stderr) {
4292
+ const output = (stderr.trim() || stdout2.trim()).split(`
2013
4293
  `).slice(-12).join(`
2014
4294
  `);
2015
4295
  return output ? `
@@ -2017,39 +4297,36 @@ function commandFailureOutput(stdout, stderr) {
2017
4297
  ${output}` : "";
2018
4298
  }
2019
4299
  async function installDependencies(target) {
2020
- const { stdout, stderr, exitCode } = await runCaptured2(["pnpm", "install", "--frozen-lockfile"], {
4300
+ const { stdout: stdout2, stderr, exitCode } = await runCaptured2(["pnpm", "install", "--frozen-lockfile"], {
2021
4301
  cwd: target,
2022
4302
  env: { ...process.env, CI: "1" }
2023
4303
  });
2024
4304
  if (exitCode !== 0) {
2025
- throw new Error(`Dependency installation failed.${commandFailureOutput(stdout, stderr)}`);
4305
+ throw new Error(`Dependency installation failed.${commandFailureOutput(stdout2, stderr)}`);
2026
4306
  }
2027
4307
  }
2028
4308
  async function runCapturedCommand(command, target) {
2029
- const { stdout, stderr, exitCode } = await runCaptured2(command, { cwd: target });
4309
+ const { stdout: stdout2, stderr, exitCode } = await runCaptured2(command, { cwd: target });
2030
4310
  if (exitCode !== 0) {
2031
- throw new Error(`${command.join(" ")} failed.${commandFailureOutput(stdout, stderr)}`);
4311
+ throw new Error(`${command.join(" ")} failed.${commandFailureOutput(stdout2, stderr)}`);
2032
4312
  }
2033
4313
  }
4314
+ async function occupiedDevelopmentPorts() {
4315
+ const results = await Promise.all([5173, 8000].map(async (port) => ({ port, available: await isPortAvailable(port) })));
4316
+ return results.filter((result) => !result.available).map((result) => result.port);
4317
+ }
2034
4318
  async function startDevelopment(target) {
2035
- const occupiedPorts = (await Promise.all([5173, 8000].map(async (port) => ({
2036
- port,
2037
- available: await isPortAvailable(port)
2038
- })))).filter((result) => !result.available).map((result) => result.port);
2039
- if (occupiedPorts.length > 0) {
2040
- throw new Error(`Cannot start development because port ${occupiedPorts.join(", ")} is in use.`);
2041
- }
2042
4319
  await runStep("Starting local Postgres", "Local Postgres is ready", () => runCapturedCommand(["docker", "compose", "up", "-d", "--wait", "postgres"], target));
2043
- prompts5.log.info(`Web http://localhost:5173
4320
+ log.info(`Web http://localhost:5173
2044
4321
  API http://localhost:8000`);
2045
- prompts5.outro("Development servers are starting. Ctrl+C stops app servers; Postgres stays running.");
4322
+ outro("Development servers are starting. Ctrl+C stops app servers; Postgres stays running.");
2046
4323
  const exitCode = await runInherited(["vp", "run", "-r", "--parallel", "dev"], { cwd: target });
2047
4324
  if (exitCode !== 0 && exitCode !== 130) {
2048
4325
  throw new Error(`Development servers exited with code ${exitCode}.`);
2049
4326
  }
2050
4327
  }
2051
4328
  async function runStep(pending, complete, action, indicator = "dots") {
2052
- const progress = prompts5.spinner({ indicator });
4329
+ const progress = spinner({ indicator });
2053
4330
  progress.start(pending);
2054
4331
  try {
2055
4332
  const result = await action();
@@ -2060,22 +4337,22 @@ async function runStep(pending, complete, action, indicator = "dots") {
2060
4337
  throw error;
2061
4338
  }
2062
4339
  }
2063
- async function createApplication(options, version) {
4340
+ async function createApplication(options) {
2064
4341
  const target = resolve4(process.cwd(), options.appName);
2065
4342
  await assertTargetAvailable(target);
2066
4343
  assertSiblingTarget(options.from, target);
2067
4344
  const databasePort = await findAvailablePort();
2068
4345
  await mkdir5(dirname2(target), { recursive: true });
2069
- const staging = await mkdtemp2(join7(dirname2(target), `.${options.appName}-${CLI_NAME}-`));
4346
+ const staging = await mkdtemp2(join8(dirname2(target), `.${options.appName}-${CLI_NAME}-`));
2070
4347
  try {
2071
- const templateRef = options.from ? undefined : templateRefForVersion(version);
2072
4348
  await runStep("Preparing your application", "Application source prepared", () => scaffold({
2073
4349
  appName: options.appName,
2074
4350
  scope: options.scope,
2075
4351
  brandName: options.brandName,
2076
4352
  targetDirectory: staging,
2077
4353
  from: options.from,
2078
- templateRef,
4354
+ licenseKey: options.licenseKey,
4355
+ sourceVersion: options.sourceVersion,
2079
4356
  initializeGit: options.initializeGit,
2080
4357
  databasePort
2081
4358
  }));
@@ -2092,7 +4369,7 @@ async function createApplication(options, version) {
2092
4369
  await rename2(staging, target);
2093
4370
  return { target, databasePort };
2094
4371
  } catch (error) {
2095
- await rm4(staging, { recursive: true, force: true });
4372
+ await rm5(staging, { recursive: true, force: true });
2096
4373
  throw error;
2097
4374
  }
2098
4375
  }
@@ -2111,6 +4388,11 @@ function completionDetails(target, options, databasePort) {
2111
4388
  database: `Postgres localhost:${databasePort}`
2112
4389
  };
2113
4390
  }
4391
+ function printRunnableCommands(commands) {
4392
+ console.log(`
4393
+ ${commands}
4394
+ `);
4395
+ }
2114
4396
  async function main() {
2115
4397
  const argv = process.argv.slice(2);
2116
4398
  if (argv[0] === "agent") {
@@ -2135,32 +4417,40 @@ async function main() {
2135
4417
  console.log(version);
2136
4418
  return;
2137
4419
  }
2138
- prompts5.intro(`${suggestBrandName(CLI_NAME)} ${version} \xB7 production SaaS foundation`);
4420
+ intro(`${suggestBrandName(CLI_NAME)} ${version} \xB7 production SaaS foundation`);
2139
4421
  const options = await collectOptions(parsed);
2140
- const { target, databasePort } = await createApplication(options, version);
4422
+ const { target, databasePort } = await createApplication(options);
2141
4423
  const completion = completionDetails(target, options, databasePort);
2142
- prompts5.log.success(`Created ${completion.directory}`);
4424
+ log.success(`Created ${completion.directory}`);
2143
4425
  if (!options.startDevelopment) {
2144
- prompts5.log.step("Run locally");
2145
- prompts5.log.message(completion.commands);
2146
- prompts5.log.info(`Web http://localhost:5173
4426
+ log.step("Run locally");
4427
+ log.info(`Web http://localhost:5173
2147
4428
  API http://localhost:8000
2148
4429
  ${completion.database}`);
2149
4430
  if (options.deployment) {
2150
- prompts5.log.info(`Deployment ${options.deployment.cloud.toUpperCase()} + ${options.deployment.storageProvider} + ${options.deployment.frontendTarget} locked. Review deployment/README.md.`);
4431
+ log.info(`Deployment ${options.deployment.cloud.toUpperCase()} + ${options.deployment.storageProvider} + ${options.deployment.frontendTarget} locked. Review deployment/README.md.`);
2151
4432
  } else {
2152
- prompts5.log.info("Deployment deferred. Run `pnpm deploy:configure` when you are ready.");
4433
+ log.info("Deployment deferred. Run `pnpm deploy:configure` when you are ready.");
2153
4434
  }
2154
- prompts5.outro(`${options.brandName} is ready.`);
4435
+ outro(`${options.brandName} is ready.`);
4436
+ printRunnableCommands(completion.commands);
4437
+ return;
4438
+ }
4439
+ const occupiedPorts = await occupiedDevelopmentPorts();
4440
+ if (occupiedPorts.length > 0) {
4441
+ log.warn(`Port ${occupiedPorts.join(" and ")} already in use, so the development servers were not started.`);
4442
+ log.step("Free the port, then run");
4443
+ outro(`${options.brandName} is ready at ${completion.directory}.`);
4444
+ printRunnableCommands(completion.commands);
2155
4445
  return;
2156
4446
  }
2157
4447
  try {
2158
4448
  await startDevelopment(target);
2159
4449
  } catch (error) {
2160
- prompts5.log.error(error instanceof Error ? error.message : String(error));
2161
- prompts5.log.info(`The application was created at ${completion.directory}.`);
2162
- prompts5.log.step("Start it manually");
2163
- prompts5.log.message(completion.commands);
4450
+ log.error(error instanceof Error ? error.message : String(error));
4451
+ log.step("Start it manually");
4452
+ outro(`${options.brandName} is ready at ${completion.directory}.`);
4453
+ printRunnableCommands(completion.commands);
2164
4454
  process.exitCode = 1;
2165
4455
  }
2166
4456
  }
@@ -2168,16 +4458,19 @@ if (isEntrypoint(import.meta.url)) {
2168
4458
  main().catch((error) => {
2169
4459
  if (error instanceof CliCancelled)
2170
4460
  return;
2171
- prompts5.log.error(error instanceof Error ? error.message : String(error));
2172
- prompts5.outro("No project was created.");
4461
+ log.error(error instanceof Error ? error.message : String(error));
4462
+ outro("No project was created.");
2173
4463
  process.exitCode = 1;
2174
4464
  });
2175
4465
  }
2176
4466
  export {
2177
4467
  usage,
2178
- templateRefForVersion,
2179
4468
  suggestScope,
2180
4469
  suggestBrandName,
4470
+ printRunnableCommands,
2181
4471
  parseArguments,
2182
- findAvailablePort
4472
+ occupiedDevelopmentPorts,
4473
+ findAvailablePort,
4474
+ describeTargetConflict,
4475
+ collectLicenseKey
2183
4476
  };