@kb-labs/shared-cli-ui 2.94.0 → 2.98.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/debug.cjs +19 -11
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.js +19 -11
- package/dist/debug.js.map +1 -1
- package/dist/index.cjs +905 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +239 -5
- package/dist/index.d.ts +239 -5
- package/dist/index.js +867 -105
- package/dist/index.js.map +1 -1
- package/dist/interactive/index.cjs +462 -0
- package/dist/interactive/index.cjs.map +1 -0
- package/dist/interactive/index.d.cts +74 -0
- package/dist/interactive/index.d.ts +74 -0
- package/dist/interactive/index.js +436 -0
- package/dist/interactive/index.js.map +1 -0
- package/package.json +12 -4
|
@@ -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 };
|