@kb-labs/shared-cli-ui 2.93.0 → 2.96.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.
@@ -0,0 +1,462 @@
1
+ 'use strict';
2
+
3
+ var readline = require('readline');
4
+
5
+ function _interopNamespace(e) {
6
+ if (e && e.__esModule) return e;
7
+ var n = Object.create(null);
8
+ if (e) {
9
+ Object.keys(e).forEach(function (k) {
10
+ if (k !== 'default') {
11
+ var d = Object.getOwnPropertyDescriptor(e, k);
12
+ Object.defineProperty(n, k, d.get ? d : {
13
+ enumerable: true,
14
+ get: function () { return e[k]; }
15
+ });
16
+ }
17
+ });
18
+ }
19
+ n.default = e;
20
+ return Object.freeze(n);
21
+ }
22
+
23
+ var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
24
+
25
+ // src/interactive/terminal.ts
26
+ function isInteractive() {
27
+ return Boolean(
28
+ process.stdin.isTTY && process.stdout.isTTY && !process.env.CI && !process.env.NO_INTERACTIVE
29
+ );
30
+ }
31
+ function enableRawMode() {
32
+ if (process.stdin.isTTY) {
33
+ process.stdin.setRawMode(true);
34
+ }
35
+ }
36
+ function disableRawMode() {
37
+ if (process.stdin.isTTY) {
38
+ process.stdin.setRawMode(false);
39
+ }
40
+ }
41
+ function clearLine() {
42
+ process.stdout.write("\r\x1B[K");
43
+ }
44
+ function clearLines(n) {
45
+ for (let i = 0; i < n; i++) {
46
+ if (i > 0) {
47
+ process.stdout.write("\x1B[1A");
48
+ }
49
+ clearLine();
50
+ }
51
+ }
52
+ function hideCursor() {
53
+ process.stdout.write("\x1B[?25l");
54
+ }
55
+ function showCursor() {
56
+ process.stdout.write("\x1B[?25h");
57
+ }
58
+ function onKeypress(handler) {
59
+ readline__namespace.emitKeypressEvents(process.stdin);
60
+ const listener = (_, key) => {
61
+ if (key) {
62
+ handler(key);
63
+ }
64
+ };
65
+ process.stdin.on("keypress", listener);
66
+ process.stdin.resume();
67
+ return () => {
68
+ process.stdin.off("keypress", listener);
69
+ if (process.stdin.listenerCount("keypress") === 0) {
70
+ process.stdin.pause();
71
+ }
72
+ };
73
+ }
74
+ function isUpKey(key) {
75
+ return key.name === "up" || key.name === "k" && !key.ctrl;
76
+ }
77
+ function isDownKey(key) {
78
+ return key.name === "down" || key.name === "j" && !key.ctrl;
79
+ }
80
+ function isEnterKey(key) {
81
+ return key.name === "return" || key.name === "enter";
82
+ }
83
+ function isEscapeKey(key) {
84
+ return key.name === "escape" || key.name === "c" && key.ctrl || key.name === "q" && !key.ctrl;
85
+ }
86
+ function isSpaceKey(key) {
87
+ return key.name === "space";
88
+ }
89
+
90
+ // src/colors.ts
91
+ var CSI = "\x1B[";
92
+ var RESET = "\x1B[0m";
93
+ var createColor = (...codes) => (text2) => `${CSI}${codes.join(";")}m${text2}${RESET}`;
94
+ var accentBlue = "38;5;39";
95
+ var accentViolet = "38;5;99";
96
+ var accentTeal = "38;5;51";
97
+ var accentIndigo = "38;5;63";
98
+ var neutral = 37;
99
+ var neutralMuted = 90;
100
+ var colors = {
101
+ // Semantic colors
102
+ success: createColor(32),
103
+ error: createColor(31),
104
+ warning: createColor(33),
105
+ info: createColor(36),
106
+ // Accent palette (reused across CLI)
107
+ primary: createColor(accentBlue),
108
+ accent: createColor(accentViolet),
109
+ highlight: createColor(accentTeal),
110
+ secondary: createColor(accentIndigo),
111
+ emphasis: createColor("38;5;117"),
112
+ muted: createColor(neutralMuted),
113
+ foreground: createColor(neutral),
114
+ // Formatting helpers
115
+ dim: createColor(2),
116
+ bold: createColor(1),
117
+ underline: createColor(4),
118
+ inverse: createColor(7)
119
+ };
120
+ var symbolCharacters = {
121
+ success: "\u2713",
122
+ error: "\u2717",
123
+ warning: "\u26A0",
124
+ info: "\u25C6",
125
+ bullet: "\u2022",
126
+ clock: "\u25F7",
127
+ folder: "\u25B8",
128
+ package: "\u25C6",
129
+ pointer: "\u276F",
130
+ section: "\u2502",
131
+ step: "\u25CB",
132
+ stepDone: "\u25CF",
133
+ arrow: "\u2192",
134
+ diamond: "\u25C6"
135
+ };
136
+ ({
137
+ success: colors.success(symbolCharacters.success),
138
+ error: colors.error(symbolCharacters.error),
139
+ warning: colors.warning(symbolCharacters.warning),
140
+ info: colors.info(symbolCharacters.info),
141
+ bullet: colors.muted(symbolCharacters.bullet),
142
+ clock: colors.muted(symbolCharacters.clock),
143
+ folder: colors.primary(symbolCharacters.folder),
144
+ package: colors.accent(symbolCharacters.package),
145
+ pointer: colors.primary(symbolCharacters.pointer),
146
+ section: colors.muted(symbolCharacters.section),
147
+ step: colors.muted(symbolCharacters.step),
148
+ stepDone: colors.success(symbolCharacters.stepDone),
149
+ arrow: colors.primary(symbolCharacters.arrow),
150
+ diamond: colors.primary(symbolCharacters.diamond)
151
+ });
152
+ var isTruthyEnv = (value) => {
153
+ if (!value) {
154
+ return false;
155
+ }
156
+ const normalized = value.trim().toLowerCase();
157
+ return normalized !== "" && normalized !== "0" && normalized !== "false" && normalized !== "off";
158
+ };
159
+ var supportsColor = (() => {
160
+ if (typeof process === "undefined") {
161
+ return false;
162
+ }
163
+ const forceColor = process.env.FORCE_COLOR;
164
+ if (isTruthyEnv(process.env.NO_COLOR)) {
165
+ return false;
166
+ }
167
+ if (isTruthyEnv(forceColor)) {
168
+ return true;
169
+ }
170
+ if (!process.stdout) {
171
+ return false;
172
+ }
173
+ if (process.stdout.isTTY === false) {
174
+ return false;
175
+ }
176
+ return true;
177
+ })();
178
+ var passthrough = (fn) => (text2) => supportsColor ? fn(text2) : text2;
179
+ var safeColors = {
180
+ success: passthrough(colors.success),
181
+ error: passthrough(colors.error),
182
+ warning: passthrough(colors.warning),
183
+ info: passthrough(colors.info),
184
+ accent: passthrough(colors.accent),
185
+ primary: passthrough(colors.primary),
186
+ highlight: passthrough(colors.highlight),
187
+ secondary: passthrough(colors.secondary),
188
+ emphasis: passthrough(colors.emphasis),
189
+ foreground: passthrough(colors.foreground),
190
+ muted: passthrough(colors.muted),
191
+ dim: passthrough(colors.dim),
192
+ bold: passthrough(colors.bold),
193
+ underline: passthrough(colors.underline),
194
+ inverse: passthrough(colors.inverse)
195
+ };
196
+
197
+ // src/interactive/confirm.ts
198
+ async function confirm(options) {
199
+ const { message, defaultValue = false } = options;
200
+ if (!isInteractive()) {
201
+ return defaultValue;
202
+ }
203
+ const hint = defaultValue ? "(Y/n)" : "(y/N)";
204
+ process.stdout.write(`${safeColors.primary("\u25C6")} ${safeColors.bold(message)} ${safeColors.muted(hint)} `);
205
+ return new Promise((resolve) => {
206
+ const rl = readline__namespace.createInterface({ input: process.stdin, output: void 0 });
207
+ rl.once("line", (line) => {
208
+ rl.close();
209
+ const trimmed = line.trim().toLowerCase();
210
+ process.stdout.write("\n");
211
+ if (trimmed === "") {
212
+ resolve(defaultValue);
213
+ } else {
214
+ resolve(trimmed === "y" || trimmed === "yes");
215
+ }
216
+ });
217
+ rl.once("close", () => {
218
+ resolve(defaultValue);
219
+ });
220
+ });
221
+ }
222
+ async function text(options) {
223
+ const { message, placeholder, defaultValue = "", validate, mask = false } = options;
224
+ if (!isInteractive()) {
225
+ return defaultValue;
226
+ }
227
+ const hint = placeholder ? safeColors.muted(` (${placeholder})`) : "";
228
+ process.stdout.write(`${safeColors.primary("\u25C6")} ${safeColors.bold(message)}${hint}
229
+ `);
230
+ process.stdout.write(`${safeColors.muted("\u2502")} `);
231
+ return new Promise((resolve) => {
232
+ const rl = readline__namespace.createInterface({
233
+ input: process.stdin,
234
+ output: mask ? void 0 : process.stdout,
235
+ terminal: !mask
236
+ });
237
+ if (mask) {
238
+ process.stdin.on("data", (char) => {
239
+ const c = char.toString();
240
+ if (c === "\n" || c === "\r") {
241
+ return;
242
+ }
243
+ process.stdout.write("*");
244
+ });
245
+ }
246
+ rl.once("line", (line) => {
247
+ rl.close();
248
+ const value = line.trim() || defaultValue;
249
+ if (validate) {
250
+ const error = validate(value);
251
+ if (error) {
252
+ process.stdout.write(`${safeColors.error("\u2717")} ${safeColors.error(error)}
253
+ `);
254
+ resolve(text(options));
255
+ return;
256
+ }
257
+ }
258
+ process.stdout.write(`${safeColors.muted("\u2514")}
259
+ `);
260
+ resolve(value);
261
+ });
262
+ rl.once("close", () => {
263
+ resolve(defaultValue);
264
+ });
265
+ });
266
+ }
267
+
268
+ // src/interactive/select.ts
269
+ function renderSelect(message, choices, activeIndex, isFirst) {
270
+ const lines = [];
271
+ if (isFirst) {
272
+ lines.push(`${safeColors.primary("\u25C6")} ${safeColors.bold(message)}`);
273
+ lines.push(safeColors.muted("\u2502"));
274
+ }
275
+ for (let i = 0; i < choices.length; i++) {
276
+ const choice = choices[i];
277
+ if (!choice) {
278
+ continue;
279
+ }
280
+ const isActive = i === activeIndex;
281
+ const pointer = isActive ? safeColors.primary("\u276F") : " ";
282
+ const label = isActive ? safeColors.bold(choice.label) : safeColors.muted(choice.label);
283
+ const hint = choice.hint ? safeColors.muted(` \u2014 ${choice.hint}`) : "";
284
+ lines.push(`${safeColors.muted("\u2502")} ${pointer} ${label}${hint}`);
285
+ }
286
+ lines.push(safeColors.muted("\u2502"));
287
+ process.stdout.write(lines.join("\n") + "\n");
288
+ return lines.length;
289
+ }
290
+ async function select(options) {
291
+ const { message, choices, initialIndex = 0 } = options;
292
+ if (!isInteractive() || choices.length === 0) {
293
+ return choices[Math.min(initialIndex, choices.length - 1)].value;
294
+ }
295
+ let activeIndex = Math.min(initialIndex, choices.length - 1);
296
+ let lineCount = 0;
297
+ hideCursor();
298
+ enableRawMode();
299
+ lineCount = renderSelect(message, choices, activeIndex, true);
300
+ return new Promise((resolve) => {
301
+ const unsubscribe = onKeypress((key) => {
302
+ if (isUpKey(key)) {
303
+ activeIndex = (activeIndex - 1 + choices.length) % choices.length;
304
+ clearLines(lineCount);
305
+ lineCount = renderSelect(message, choices, activeIndex, false);
306
+ return;
307
+ }
308
+ if (isDownKey(key)) {
309
+ activeIndex = (activeIndex + 1) % choices.length;
310
+ clearLines(lineCount);
311
+ lineCount = renderSelect(message, choices, activeIndex, false);
312
+ return;
313
+ }
314
+ if (isEnterKey(key)) {
315
+ unsubscribe();
316
+ disableRawMode();
317
+ showCursor();
318
+ clearLines(lineCount + 2);
319
+ const selected = choices[activeIndex];
320
+ process.stdout.write(`${safeColors.primary("\u25C6")} ${safeColors.bold(message)} ${safeColors.muted(selected.label)}
321
+ `);
322
+ process.stdout.write(`${safeColors.muted("\u2514")}
323
+ `);
324
+ resolve(selected.value);
325
+ return;
326
+ }
327
+ if (isEscapeKey(key)) {
328
+ unsubscribe();
329
+ disableRawMode();
330
+ showCursor();
331
+ clearLines(lineCount + 2);
332
+ process.stdout.write(`${safeColors.muted("\u25C6")} ${safeColors.muted(message)} ${safeColors.muted("cancelled")}
333
+ `);
334
+ process.stdout.write(`${safeColors.muted("\u2514")}
335
+ `);
336
+ resolve(choices[initialIndex].value);
337
+ return;
338
+ }
339
+ });
340
+ });
341
+ }
342
+
343
+ // src/interactive/multi-select.ts
344
+ function renderMultiSelect(message, choices, checked, activeIndex, isFirst, error) {
345
+ const lines = [];
346
+ if (isFirst) {
347
+ lines.push(`${safeColors.primary("\u25C6")} ${safeColors.bold(message)} ${safeColors.muted("Space to toggle, Enter to confirm")}`);
348
+ lines.push(safeColors.muted("\u2502"));
349
+ }
350
+ for (let i = 0; i < choices.length; i++) {
351
+ const choice = choices[i];
352
+ if (!choice) {
353
+ continue;
354
+ }
355
+ const isActive = i === activeIndex;
356
+ const isChecked = checked.has(i);
357
+ const checkbox = isChecked ? safeColors.success("\u25C9") : safeColors.muted("\u25CB");
358
+ const pointer = isActive ? safeColors.primary("\u276F") : " ";
359
+ const label = isActive ? safeColors.bold(choice.label) : isChecked ? choice.label : safeColors.muted(choice.label);
360
+ const hint = choice.hint ? safeColors.muted(` \u2014 ${choice.hint}`) : "";
361
+ lines.push(`${safeColors.muted("\u2502")} ${pointer} ${checkbox} ${label}${hint}`);
362
+ }
363
+ if (error) {
364
+ lines.push(`${safeColors.muted("\u2502")}`);
365
+ lines.push(`${safeColors.muted("\u2502")} ${safeColors.error("\u2717")} ${safeColors.error(error)}`);
366
+ }
367
+ lines.push(safeColors.muted("\u2502"));
368
+ process.stdout.write(lines.join("\n") + "\n");
369
+ return lines.length;
370
+ }
371
+ async function multiSelect(options) {
372
+ const { message, choices, min } = options;
373
+ if (!isInteractive() || choices.length === 0) {
374
+ return choices.filter((c) => c.checked).map((c) => c.value);
375
+ }
376
+ let activeIndex = 0;
377
+ const checked = new Set(
378
+ choices.map((c, i) => c.checked ? i : -1).filter((i) => i >= 0)
379
+ );
380
+ let lineCount = 0;
381
+ let error;
382
+ hideCursor();
383
+ enableRawMode();
384
+ lineCount = renderMultiSelect(message, choices, checked, activeIndex, true, error);
385
+ return new Promise((resolve) => {
386
+ const unsubscribe = onKeypress((key) => {
387
+ if (isUpKey(key)) {
388
+ activeIndex = (activeIndex - 1 + choices.length) % choices.length;
389
+ clearLines(lineCount);
390
+ lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);
391
+ return;
392
+ }
393
+ if (isDownKey(key)) {
394
+ activeIndex = (activeIndex + 1) % choices.length;
395
+ clearLines(lineCount);
396
+ lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);
397
+ return;
398
+ }
399
+ if (isSpaceKey(key)) {
400
+ if (checked.has(activeIndex)) {
401
+ checked.delete(activeIndex);
402
+ } else {
403
+ checked.add(activeIndex);
404
+ }
405
+ error = void 0;
406
+ clearLines(lineCount);
407
+ lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);
408
+ return;
409
+ }
410
+ if (key.name === "a" && !key.ctrl) {
411
+ if (checked.size === choices.length) {
412
+ checked.clear();
413
+ } else {
414
+ choices.forEach((_, i) => checked.add(i));
415
+ }
416
+ clearLines(lineCount);
417
+ lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);
418
+ return;
419
+ }
420
+ if (isEnterKey(key)) {
421
+ if (min !== void 0 && checked.size < min) {
422
+ error = `Select at least ${min} option${min === 1 ? "" : "s"}`;
423
+ clearLines(lineCount);
424
+ lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);
425
+ return;
426
+ }
427
+ unsubscribe();
428
+ disableRawMode();
429
+ showCursor();
430
+ const headerLines = 2;
431
+ clearLines(lineCount + headerLines);
432
+ const selectedLabels = choices.filter((_, i) => checked.has(i)).map((c) => c.label).join(", ");
433
+ process.stdout.write(`${safeColors.primary("\u25C6")} ${safeColors.bold(message)} ${safeColors.muted(selectedLabels || "none")}
434
+ `);
435
+ process.stdout.write(`${safeColors.muted("\u2514")}
436
+ `);
437
+ resolve(choices.filter((_, i) => checked.has(i)).map((c) => c.value));
438
+ return;
439
+ }
440
+ if (isEscapeKey(key)) {
441
+ unsubscribe();
442
+ disableRawMode();
443
+ showCursor();
444
+ clearLines(lineCount + 2);
445
+ process.stdout.write(`${safeColors.muted("\u25C6")} ${safeColors.muted(message)} ${safeColors.muted("cancelled")}
446
+ `);
447
+ process.stdout.write(`${safeColors.muted("\u2514")}
448
+ `);
449
+ resolve([]);
450
+ return;
451
+ }
452
+ });
453
+ });
454
+ }
455
+
456
+ exports.confirm = confirm;
457
+ exports.isInteractive = isInteractive;
458
+ exports.multiSelect = multiSelect;
459
+ exports.select = select;
460
+ exports.text = text;
461
+ //# sourceMappingURL=index.cjs.map
462
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/interactive/terminal.ts","../../src/colors.ts","../../src/interactive/confirm.ts","../../src/interactive/text.ts","../../src/interactive/select.ts","../../src/interactive/multi-select.ts"],"names":["readline","text","readline2","readline3"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Low-level terminal utilities for interactive CLI prompts.\n * All functions check isInteractive() before using raw mode.\n */\n\nimport * as readline from 'node:readline';\n\nexport interface Key {\n name: string;\n ctrl: boolean;\n shift: boolean;\n meta: boolean;\n sequence: string;\n}\n\nexport function isInteractive(): boolean {\n return Boolean(\n process.stdin.isTTY &&\n process.stdout.isTTY &&\n !process.env.CI &&\n !process.env.NO_INTERACTIVE\n );\n}\n\nexport function enableRawMode(): void {\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n}\n\nexport function disableRawMode(): void {\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n}\n\nexport function clearLine(): void {\n process.stdout.write('\\r\\x1b[K');\n}\n\nexport function clearLines(n: number): void {\n for (let i = 0; i < n; i++) {\n if (i > 0) {process.stdout.write('\\x1b[1A');}\n clearLine();\n }\n}\n\nexport function hideCursor(): void {\n process.stdout.write('\\x1b[?25l');\n}\n\nexport function showCursor(): void {\n process.stdout.write('\\x1b[?25h');\n}\n\nexport function moveCursorUp(n: number): void {\n process.stdout.write(`\\x1b[${n}A`);\n}\n\n/**\n * Listen for keypresses. Returns an unsubscribe function.\n * Caller is responsible for enabling raw mode before calling.\n */\nexport function onKeypress(handler: (key: Key) => void): () => void {\n readline.emitKeypressEvents(process.stdin);\n\n const listener = (_: unknown, key: Key) => {\n if (key) {handler(key);}\n };\n\n process.stdin.on('keypress', listener);\n process.stdin.resume();\n\n return () => {\n process.stdin.off('keypress', listener);\n if (process.stdin.listenerCount('keypress') === 0) {\n process.stdin.pause();\n }\n };\n}\n\nexport function isUpKey(key: Key): boolean {\n return key.name === 'up' || (key.name === 'k' && !key.ctrl);\n}\n\nexport function isDownKey(key: Key): boolean {\n return key.name === 'down' || (key.name === 'j' && !key.ctrl);\n}\n\nexport function isEnterKey(key: Key): boolean {\n return key.name === 'return' || key.name === 'enter';\n}\n\nexport function isEscapeKey(key: Key): boolean {\n return key.name === 'escape' || (key.name === 'c' && key.ctrl) || (key.name === 'q' && !key.ctrl);\n}\n\nexport function isSpaceKey(key: Key): boolean {\n return key.name === 'space';\n}\n","/**\n * Minimalist color utilities for CLI output\n * Uses strategic color application - only for status, not decoration\n */\n\nconst CSI = '\\x1b[';\nconst RESET = '\\x1b[0m';\n\nconst createColor =\n (...codes: Array<number | string>) =>\n (text: string): string =>\n `${CSI}${codes.join(';')}m${text}${RESET}`;\n\nconst accentBlue = '38;5;39';\nconst accentViolet = '38;5;99';\nconst accentTeal = '38;5;51';\nconst accentIndigo = '38;5;63';\nconst neutral = 37;\nconst neutralMuted = 90;\n\nexport const colors = {\n // Semantic colors\n success: createColor(32),\n error: createColor(31),\n warning: createColor(33),\n info: createColor(36),\n\n // Accent palette (reused across CLI)\n primary: createColor(accentBlue),\n accent: createColor(accentViolet),\n highlight: createColor(accentTeal),\n secondary: createColor(accentIndigo),\n emphasis: createColor('38;5;117'),\n muted: createColor(neutralMuted),\n foreground: createColor(neutral),\n\n // Formatting helpers\n dim: createColor(2),\n bold: createColor(1),\n underline: createColor(4),\n inverse: createColor(7),\n};\n\n// Unicode symbols — KB Labs visual identity\nconst symbolCharacters = {\n success: '✓',\n error: '✗',\n warning: '⚠',\n info: '◆',\n bullet: '•',\n clock: '◷',\n folder: '▸',\n package: '◆',\n pointer: '❯',\n section: '│',\n step: '○',\n stepDone: '●',\n arrow: '→',\n diamond: '◆',\n};\n\nexport const symbols = {\n success: colors.success(symbolCharacters.success),\n error: colors.error(symbolCharacters.error),\n warning: colors.warning(symbolCharacters.warning),\n info: colors.info(symbolCharacters.info),\n bullet: colors.muted(symbolCharacters.bullet),\n clock: colors.muted(symbolCharacters.clock),\n folder: colors.primary(symbolCharacters.folder),\n package: colors.accent(symbolCharacters.package),\n pointer: colors.primary(symbolCharacters.pointer),\n section: colors.muted(symbolCharacters.section),\n step: colors.muted(symbolCharacters.step),\n stepDone: colors.success(symbolCharacters.stepDone),\n arrow: colors.primary(symbolCharacters.arrow),\n diamond: colors.primary(symbolCharacters.diamond),\n};\n\n// Check if colors are supported\nconst isTruthyEnv = (value: string | undefined): boolean => {\n if (!value) {return false;}\n const normalized = value.trim().toLowerCase();\n return normalized !== '' && normalized !== '0' && normalized !== 'false' && normalized !== 'off';\n};\n\nexport const supportsColor = (() => {\n if (typeof process === 'undefined') {return false;}\n\n const forceColor = process.env.FORCE_COLOR;\n if (isTruthyEnv(process.env.NO_COLOR)) {\n return false;\n }\n if (isTruthyEnv(forceColor)) {\n return true;\n }\n\n if (!process.stdout) {return false;}\n\n if (process.stdout.isTTY === false) {\n return false;\n }\n\n return true;\n})();\n\n// Color functions that respect NO_COLOR\nconst passthrough =\n (fn: (text: string) => string) =>\n (text: string): string =>\n supportsColor ? fn(text) : text;\n\nexport const safeColors = {\n success: passthrough(colors.success),\n error: passthrough(colors.error),\n warning: passthrough(colors.warning),\n info: passthrough(colors.info),\n accent: passthrough(colors.accent),\n primary: passthrough(colors.primary),\n highlight: passthrough(colors.highlight),\n secondary: passthrough(colors.secondary),\n emphasis: passthrough(colors.emphasis),\n foreground: passthrough(colors.foreground),\n muted: passthrough(colors.muted),\n dim: passthrough(colors.dim),\n bold: passthrough(colors.bold),\n underline: passthrough(colors.underline),\n inverse: passthrough(colors.inverse),\n};\n\nexport const safeSymbols = {\n success: supportsColor ? symbols.success : '✓',\n error: supportsColor ? symbols.error : '✗',\n warning: supportsColor ? symbols.warning : '⚠',\n info: supportsColor ? symbols.info : '◆',\n bullet: supportsColor ? symbols.bullet : '•',\n clock: supportsColor ? symbols.clock : '◷',\n folder: supportsColor ? symbols.folder : '▸',\n package: supportsColor ? symbols.package : '◆',\n pointer: supportsColor ? symbols.pointer : '❯',\n section: supportsColor ? symbols.section : '│',\n step: supportsColor ? symbols.step : '○',\n stepDone: supportsColor ? symbols.stepDone : '●',\n arrow: supportsColor ? symbols.arrow : '→',\n diamond: supportsColor ? symbols.diamond : '◆',\n // Box-drawing characters\n separator: '─',\n border: '│',\n topLeft: '┌',\n topRight: '┐',\n bottomLeft: '└',\n bottomRight: '┘',\n leftT: '├',\n rightT: '┤',\n};\n","/**\n * Interactive y/n confirmation prompt.\n *\n * @example\n * const ok = await confirm({ message: 'Deploy to production?', defaultValue: false })\n */\n\nimport * as readline from 'node:readline';\nimport { safeColors } from '../colors.js';\nimport { isInteractive } from './terminal.js';\n\nexport interface ConfirmOptions {\n message: string;\n defaultValue?: boolean;\n}\n\nexport async function confirm(options: ConfirmOptions): Promise<boolean> {\n const { message, defaultValue = false } = options;\n\n if (!isInteractive()) {\n return defaultValue;\n }\n\n const hint = defaultValue ? '(Y/n)' : '(y/N)';\n process.stdout.write(`${safeColors.primary('◆')} ${safeColors.bold(message)} ${safeColors.muted(hint)} `);\n\n return new Promise((resolve) => {\n const rl = readline.createInterface({ input: process.stdin, output: undefined });\n\n rl.once('line', (line) => {\n rl.close();\n const trimmed = line.trim().toLowerCase();\n process.stdout.write('\\n');\n if (trimmed === '') {\n resolve(defaultValue);\n } else {\n resolve(trimmed === 'y' || trimmed === 'yes');\n }\n });\n\n rl.once('close', () => {\n resolve(defaultValue);\n });\n });\n}\n","/**\n * Interactive text input prompt.\n *\n * @example\n * const name = await text({ message: 'Plugin name', placeholder: 'my-plugin', validate: v => v ? undefined : 'Required' })\n */\n\nimport * as readline from 'node:readline';\nimport { safeColors } from '../colors.js';\nimport { isInteractive } from './terminal.js';\n\nexport interface TextOptions {\n message: string;\n placeholder?: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n mask?: boolean;\n}\n\nexport async function text(options: TextOptions): Promise<string> {\n const { message, placeholder, defaultValue = '', validate, mask = false } = options;\n\n if (!isInteractive()) {\n return defaultValue;\n }\n\n const hint = placeholder ? safeColors.muted(` (${placeholder})`) : '';\n process.stdout.write(`${safeColors.primary('◆')} ${safeColors.bold(message)}${hint}\\n`);\n process.stdout.write(`${safeColors.muted('│')} `);\n\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: mask ? undefined : process.stdout,\n terminal: !mask,\n });\n\n if (mask) {\n process.stdin.on('data', (char) => {\n const c = char.toString();\n if (c === '\\n' || c === '\\r') {return;}\n process.stdout.write('*');\n });\n }\n\n rl.once('line', (line) => {\n rl.close();\n const value = line.trim() || defaultValue;\n\n if (validate) {\n const error = validate(value);\n if (error) {\n process.stdout.write(`${safeColors.error('✗')} ${safeColors.error(error)}\\n`);\n resolve(text(options));\n return;\n }\n }\n\n process.stdout.write(`${safeColors.muted('└')}\\n`);\n resolve(value);\n });\n\n rl.once('close', () => {\n resolve(defaultValue);\n });\n });\n}\n","/**\n * Interactive arrow-key single-select prompt.\n *\n * @example\n * const env = await select({\n * message: 'Select environment',\n * choices: [{ label: 'development', value: 'dev' }, { label: 'production', value: 'prod' }]\n * })\n */\n\nimport { safeColors } from '../colors.js';\nimport {\n isInteractive, enableRawMode, disableRawMode,\n hideCursor, showCursor, clearLines,\n onKeypress, isUpKey, isDownKey, isEnterKey, isEscapeKey,\n} from './terminal.js';\n\nexport interface SelectChoice<T> {\n label: string;\n value: T;\n hint?: string;\n}\n\nexport interface SelectOptions<T> {\n message: string;\n choices: SelectChoice<T>[];\n initialIndex?: number;\n}\n\nfunction renderSelect<T>(message: string, choices: SelectChoice<T>[], activeIndex: number, isFirst: boolean): number {\n const lines: string[] = [];\n\n if (isFirst) {\n lines.push(`${safeColors.primary('◆')} ${safeColors.bold(message)}`);\n lines.push(safeColors.muted('│'));\n }\n\n for (let i = 0; i < choices.length; i++) {\n const choice = choices[i];\n if (!choice) {continue;}\n const isActive = i === activeIndex;\n const pointer = isActive ? safeColors.primary('❯') : ' ';\n const label = isActive ? safeColors.bold(choice.label) : safeColors.muted(choice.label);\n const hint = choice.hint ? safeColors.muted(` — ${choice.hint}`) : '';\n lines.push(`${safeColors.muted('│')} ${pointer} ${label}${hint}`);\n }\n\n lines.push(safeColors.muted('│'));\n process.stdout.write(lines.join('\\n') + '\\n');\n return lines.length;\n}\n\nexport async function select<T>(options: SelectOptions<T>): Promise<T> {\n const { message, choices, initialIndex = 0 } = options;\n\n if (!isInteractive() || choices.length === 0) {\n return (choices[Math.min(initialIndex, choices.length - 1)] as SelectChoice<T>).value;\n }\n\n let activeIndex = Math.min(initialIndex, choices.length - 1);\n let lineCount = 0;\n\n hideCursor();\n enableRawMode();\n lineCount = renderSelect(message, choices, activeIndex, true);\n\n return new Promise((resolve) => {\n const unsubscribe = onKeypress((key) => {\n if (isUpKey(key)) {\n activeIndex = (activeIndex - 1 + choices.length) % choices.length;\n clearLines(lineCount);\n lineCount = renderSelect(message, choices, activeIndex, false);\n return;\n }\n\n if (isDownKey(key)) {\n activeIndex = (activeIndex + 1) % choices.length;\n clearLines(lineCount);\n lineCount = renderSelect(message, choices, activeIndex, false);\n return;\n }\n\n if (isEnterKey(key)) {\n unsubscribe();\n disableRawMode();\n showCursor();\n clearLines(lineCount + 2);\n const selected = choices[activeIndex] as SelectChoice<T>;\n process.stdout.write(`${safeColors.primary('◆')} ${safeColors.bold(message)} ${safeColors.muted(selected.label)}\\n`);\n process.stdout.write(`${safeColors.muted('└')}\\n`);\n resolve(selected.value);\n return;\n }\n\n if (isEscapeKey(key)) {\n unsubscribe();\n disableRawMode();\n showCursor();\n clearLines(lineCount + 2);\n process.stdout.write(`${safeColors.muted('◆')} ${safeColors.muted(message)} ${safeColors.muted('cancelled')}\\n`);\n process.stdout.write(`${safeColors.muted('└')}\\n`);\n resolve((choices[initialIndex] as SelectChoice<T>).value);\n return;\n }\n });\n });\n}\n","/**\n * Interactive checkbox multi-select prompt.\n * Space to toggle, Enter to confirm, 'a' to toggle all.\n *\n * @example\n * const plugins = await multiSelect({\n * message: 'Select plugins',\n * choices: [{ label: 'workflow', value: 'workflow', checked: true }, ...]\n * })\n */\n\nimport { safeColors } from '../colors.js';\nimport {\n isInteractive, enableRawMode, disableRawMode,\n hideCursor, showCursor, clearLines,\n onKeypress, isUpKey, isDownKey, isEnterKey, isEscapeKey, isSpaceKey,\n} from './terminal.js';\n\nexport interface MultiSelectChoice<T> {\n label: string;\n value: T;\n checked?: boolean;\n hint?: string;\n}\n\nexport interface MultiSelectOptions<T> {\n message: string;\n choices: MultiSelectChoice<T>[];\n min?: number;\n}\n\nfunction renderMultiSelect<T>(\n message: string,\n choices: MultiSelectChoice<T>[],\n checked: Set<number>,\n activeIndex: number,\n isFirst: boolean,\n error?: string,\n): number {\n const lines: string[] = [];\n\n if (isFirst) {\n lines.push(`${safeColors.primary('◆')} ${safeColors.bold(message)} ${safeColors.muted('Space to toggle, Enter to confirm')}`);\n lines.push(safeColors.muted('│'));\n }\n\n for (let i = 0; i < choices.length; i++) {\n const choice = choices[i];\n if (!choice) {continue;}\n const isActive = i === activeIndex;\n const isChecked = checked.has(i);\n const checkbox = isChecked ? safeColors.success('◉') : safeColors.muted('○');\n const pointer = isActive ? safeColors.primary('❯') : ' ';\n const label = isActive ? safeColors.bold(choice.label) : isChecked ? choice.label : safeColors.muted(choice.label);\n const hint = choice.hint ? safeColors.muted(` — ${choice.hint}`) : '';\n lines.push(`${safeColors.muted('│')} ${pointer} ${checkbox} ${label}${hint}`);\n }\n\n if (error) {\n lines.push(`${safeColors.muted('│')}`);\n lines.push(`${safeColors.muted('│')} ${safeColors.error('✗')} ${safeColors.error(error)}`);\n }\n\n lines.push(safeColors.muted('│'));\n process.stdout.write(lines.join('\\n') + '\\n');\n return lines.length;\n}\n\nexport async function multiSelect<T>(options: MultiSelectOptions<T>): Promise<T[]> {\n const { message, choices, min } = options;\n\n if (!isInteractive() || choices.length === 0) {\n return choices.filter((c) => c.checked).map((c) => c.value);\n }\n\n let activeIndex = 0;\n const checked = new Set<number>(\n choices.map((c, i) => (c.checked ? i : -1)).filter((i) => i >= 0)\n );\n let lineCount = 0;\n let error: string | undefined;\n\n hideCursor();\n enableRawMode();\n lineCount = renderMultiSelect(message, choices, checked, activeIndex, true, error);\n\n return new Promise((resolve) => {\n const unsubscribe = onKeypress((key) => {\n if (isUpKey(key)) {\n activeIndex = (activeIndex - 1 + choices.length) % choices.length;\n clearLines(lineCount);\n lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);\n return;\n }\n\n if (isDownKey(key)) {\n activeIndex = (activeIndex + 1) % choices.length;\n clearLines(lineCount);\n lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);\n return;\n }\n\n if (isSpaceKey(key)) {\n if (checked.has(activeIndex)) {\n checked.delete(activeIndex);\n } else {\n checked.add(activeIndex);\n }\n error = undefined;\n clearLines(lineCount);\n lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);\n return;\n }\n\n if (key.name === 'a' && !key.ctrl) {\n if (checked.size === choices.length) {\n checked.clear();\n } else {\n choices.forEach((_, i) => checked.add(i));\n }\n clearLines(lineCount);\n lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);\n return;\n }\n\n if (isEnterKey(key)) {\n if (min !== undefined && checked.size < min) {\n error = `Select at least ${min} option${min === 1 ? '' : 's'}`;\n clearLines(lineCount);\n lineCount = renderMultiSelect(message, choices, checked, activeIndex, false, error);\n return;\n }\n\n unsubscribe();\n disableRawMode();\n showCursor();\n const headerLines = 2;\n clearLines(lineCount + headerLines);\n\n const selectedLabels = choices\n .filter((_, i) => checked.has(i))\n .map((c) => c.label)\n .join(', ');\n process.stdout.write(`${safeColors.primary('◆')} ${safeColors.bold(message)} ${safeColors.muted(selectedLabels || 'none')}\\n`);\n process.stdout.write(`${safeColors.muted('└')}\\n`);\n\n resolve(choices.filter((_, i) => checked.has(i)).map((c) => c.value));\n return;\n }\n\n if (isEscapeKey(key)) {\n unsubscribe();\n disableRawMode();\n showCursor();\n clearLines(lineCount + 2);\n process.stdout.write(`${safeColors.muted('◆')} ${safeColors.muted(message)} ${safeColors.muted('cancelled')}\\n`);\n process.stdout.write(`${safeColors.muted('└')}\\n`);\n resolve([]);\n return;\n }\n });\n });\n}\n"]}
@@ -0,0 +1,74 @@
1
+ declare function isInteractive(): boolean;
2
+
3
+ /**
4
+ * Interactive y/n confirmation prompt.
5
+ *
6
+ * @example
7
+ * const ok = await confirm({ message: 'Deploy to production?', defaultValue: false })
8
+ */
9
+ interface ConfirmOptions {
10
+ message: string;
11
+ defaultValue?: boolean;
12
+ }
13
+ declare function confirm(options: ConfirmOptions): Promise<boolean>;
14
+
15
+ /**
16
+ * Interactive text input prompt.
17
+ *
18
+ * @example
19
+ * const name = await text({ message: 'Plugin name', placeholder: 'my-plugin', validate: v => v ? undefined : 'Required' })
20
+ */
21
+ interface TextOptions {
22
+ message: string;
23
+ placeholder?: string;
24
+ defaultValue?: string;
25
+ validate?: (value: string) => string | undefined;
26
+ mask?: boolean;
27
+ }
28
+ declare function text(options: TextOptions): Promise<string>;
29
+
30
+ /**
31
+ * Interactive arrow-key single-select prompt.
32
+ *
33
+ * @example
34
+ * const env = await select({
35
+ * message: 'Select environment',
36
+ * choices: [{ label: 'development', value: 'dev' }, { label: 'production', value: 'prod' }]
37
+ * })
38
+ */
39
+ interface SelectChoice<T> {
40
+ label: string;
41
+ value: T;
42
+ hint?: string;
43
+ }
44
+ interface SelectOptions<T> {
45
+ message: string;
46
+ choices: SelectChoice<T>[];
47
+ initialIndex?: number;
48
+ }
49
+ declare function select<T>(options: SelectOptions<T>): Promise<T>;
50
+
51
+ /**
52
+ * Interactive checkbox multi-select prompt.
53
+ * Space to toggle, Enter to confirm, 'a' to toggle all.
54
+ *
55
+ * @example
56
+ * const plugins = await multiSelect({
57
+ * message: 'Select plugins',
58
+ * choices: [{ label: 'workflow', value: 'workflow', checked: true }, ...]
59
+ * })
60
+ */
61
+ interface MultiSelectChoice<T> {
62
+ label: string;
63
+ value: T;
64
+ checked?: boolean;
65
+ hint?: string;
66
+ }
67
+ interface MultiSelectOptions<T> {
68
+ message: string;
69
+ choices: MultiSelectChoice<T>[];
70
+ min?: number;
71
+ }
72
+ declare function multiSelect<T>(options: MultiSelectOptions<T>): Promise<T[]>;
73
+
74
+ export { type ConfirmOptions, type MultiSelectChoice, type MultiSelectOptions, type SelectChoice, type SelectOptions, type TextOptions, confirm, isInteractive, multiSelect, select, text };