@nmakarov/cli-toolkit 0.69.0 → 0.71.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/cli-runner.cjs +386 -192
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +386 -192
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +440 -208
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +430 -208
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +129 -91
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +129 -91
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +124 -90
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +121 -90
- package/dist/screen.js.map +1 -1
- package/dist/tasks.cjs +308 -117
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.js +301 -117
- package/dist/tasks.js.map +1 -1
- package/package.json +2 -2
package/dist/screen.cjs
CHANGED
|
@@ -29,6 +29,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/screen/index.js
|
|
30
30
|
var screen_exports = {};
|
|
31
31
|
__export(screen_exports, {
|
|
32
|
+
BAR_THUMB: () => BAR_THUMB,
|
|
33
|
+
BAR_TRACK: () => BAR_TRACK,
|
|
32
34
|
Box: () => import_ink6.Box,
|
|
33
35
|
Divider: () => Divider,
|
|
34
36
|
FooterPresets: () => FooterPresets,
|
|
@@ -38,6 +40,7 @@ __export(screen_exports, {
|
|
|
38
40
|
ListItem: () => ListItem,
|
|
39
41
|
MultiColumnListComponent: () => MultiColumnListComponent,
|
|
40
42
|
MultiColumnListWithPreviewComponent: () => MultiColumnListWithPreviewComponent,
|
|
43
|
+
PAGE_SCROLL_KEY_BINDINGS: () => PAGE_SCROLL_KEY_BINDINGS,
|
|
41
44
|
React: () => import_react6.default,
|
|
42
45
|
ScreenBody: () => ScreenBody,
|
|
43
46
|
ScreenContainer: () => ScreenContainer,
|
|
@@ -160,7 +163,43 @@ function ScreenFooter({ lines, textStyle }) {
|
|
|
160
163
|
// src/screen/list-components.js
|
|
161
164
|
var import_react2 = null; // Will be set by load();
|
|
162
165
|
var import_ink2 = null; // Will be set by load();
|
|
166
|
+
|
|
167
|
+
// src/screen/scrollbar.js
|
|
168
|
+
var BAR_THUMB = "#";
|
|
169
|
+
var BAR_TRACK = "|";
|
|
170
|
+
function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {
|
|
171
|
+
const view = Math.max(1, Math.floor(viewportRows));
|
|
172
|
+
const total = Math.max(0, Math.floor(totalLines));
|
|
173
|
+
if (total <= view) return null;
|
|
174
|
+
const maxScroll = total - view;
|
|
175
|
+
const thumbSize = Math.max(1, Math.round(view / total * view));
|
|
176
|
+
const travel = Math.max(0, view - thumbSize);
|
|
177
|
+
const s = Math.min(Math.max(0, Math.floor(scrollTop)), maxScroll);
|
|
178
|
+
const thumbStart = maxScroll === 0 ? 0 : Math.round(s / maxScroll * travel);
|
|
179
|
+
const glyphs = [];
|
|
180
|
+
for (let i = 0; i < view; i++) {
|
|
181
|
+
glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? BAR_THUMB : BAR_TRACK);
|
|
182
|
+
}
|
|
183
|
+
return glyphs;
|
|
184
|
+
}
|
|
185
|
+
var PAGE_SCROLL_KEY_BINDINGS = [
|
|
186
|
+
{ key: "upArrow", meta: true, caption: "page", action: "pageUp", order: 0 },
|
|
187
|
+
{ key: "downArrow", meta: true, caption: "page", action: "pageDown", order: 0 },
|
|
188
|
+
{ key: "upArrow", ctrl: true, caption: "page", action: "pageUp", order: 0 },
|
|
189
|
+
{ key: "downArrow", ctrl: true, caption: "page", action: "pageDown", order: 0 },
|
|
190
|
+
{ key: "pageUp", caption: "page", action: "pageUp", order: 0 },
|
|
191
|
+
{ key: "pageDown", caption: "page", action: "pageDown", order: 0 }
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
// src/screen/list-components.js
|
|
163
195
|
// Removed: intermediate assignment - code will access import variable directly
|
|
196
|
+
function clipNameForScrollbar(name, needsBar) {
|
|
197
|
+
if (!needsBar || name == null) return name;
|
|
198
|
+
const s = String(name);
|
|
199
|
+
if (s.length <= 1) return s;
|
|
200
|
+
if (/\s$/.test(s)) return s.slice(0, -1);
|
|
201
|
+
return s;
|
|
202
|
+
}
|
|
164
203
|
function MultiColumnListComponent({ items, ctx, selectedIndexRef }) {
|
|
165
204
|
const [, forceUpdate] = (0, import_react2.useState)({});
|
|
166
205
|
const termWidth = (process.stdout.columns || 80) - 8;
|
|
@@ -374,17 +413,42 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
374
413
|
});
|
|
375
414
|
ctx.setAction("scrollUp", () => {
|
|
376
415
|
const { scrollOffset: currentScrollOffset } = scrollStateRef.current;
|
|
377
|
-
|
|
378
|
-
setScrollOffset(newScrollOffset);
|
|
416
|
+
setScrollOffset(Math.max(0, currentScrollOffset - 1));
|
|
379
417
|
forceUpdate({});
|
|
380
418
|
});
|
|
381
419
|
ctx.setAction("scrollDown", () => {
|
|
382
420
|
const { scrollOffset: currentScrollOffset, maxHeight: currentMaxHeight, totalItems } = scrollStateRef.current;
|
|
383
421
|
const currentMaxScrollOffset = Math.max(0, totalItems - currentMaxHeight);
|
|
384
|
-
|
|
385
|
-
|
|
422
|
+
setScrollOffset(Math.min(currentMaxScrollOffset, currentScrollOffset + 1));
|
|
423
|
+
forceUpdate({});
|
|
424
|
+
});
|
|
425
|
+
ctx.setAction("pageUp", () => {
|
|
426
|
+
const { maxHeight: vh } = scrollStateRef.current;
|
|
427
|
+
const page = Math.max(1, vh || 1);
|
|
428
|
+
const newIndex = Math.max(0, selectedIndexRef.current - page);
|
|
429
|
+
selectedIndexRef.current = newIndex;
|
|
430
|
+
const list = displayItemsRef.current;
|
|
431
|
+
onSelectionChangeRef.current?.(newIndex, list[newIndex]);
|
|
432
|
+
setScrollOffset(newIndex);
|
|
386
433
|
forceUpdate({});
|
|
387
434
|
});
|
|
435
|
+
ctx.setAction("pageDown", () => {
|
|
436
|
+
const { maxHeight: vh, totalItems } = scrollStateRef.current;
|
|
437
|
+
const page = Math.max(1, vh || 1);
|
|
438
|
+
const maxIndex = Math.max(0, totalItems - 1);
|
|
439
|
+
const newIndex = Math.min(maxIndex, selectedIndexRef.current + page);
|
|
440
|
+
selectedIndexRef.current = newIndex;
|
|
441
|
+
const list = displayItemsRef.current;
|
|
442
|
+
onSelectionChangeRef.current?.(newIndex, list[newIndex]);
|
|
443
|
+
const maxScroll = Math.max(0, totalItems - page);
|
|
444
|
+
setScrollOffset(Math.min(maxScroll, Math.max(0, newIndex - page + 1)));
|
|
445
|
+
forceUpdate({});
|
|
446
|
+
});
|
|
447
|
+
const navBindings = [
|
|
448
|
+
{ key: "upArrow", caption: "navigate", action: "moveUp", order: 0 },
|
|
449
|
+
{ key: "downArrow", caption: "navigate", action: "moveDown", order: 0 },
|
|
450
|
+
...PAGE_SCROLL_KEY_BINDINGS
|
|
451
|
+
];
|
|
388
452
|
if (sortable) {
|
|
389
453
|
ctx.setAction("toggleSort", () => {
|
|
390
454
|
const nextSort = sortOrder === "none" ? "asc" : sortOrder === "asc" ? "desc" : "none";
|
|
@@ -431,8 +495,7 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
431
495
|
}
|
|
432
496
|
};
|
|
433
497
|
ctx.setKeyBinding([
|
|
434
|
-
|
|
435
|
-
{ key: "downArrow", caption: "navigate", action: "moveDown", order: 0 },
|
|
498
|
+
...navBindings,
|
|
436
499
|
{
|
|
437
500
|
key: "s",
|
|
438
501
|
caption: sortCaption,
|
|
@@ -442,47 +505,47 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
442
505
|
]);
|
|
443
506
|
ctx.update();
|
|
444
507
|
} else {
|
|
445
|
-
ctx.setKeyBinding(
|
|
446
|
-
{ key: "upArrow", caption: "navigate", action: "moveUp", order: 0 },
|
|
447
|
-
{ key: "downArrow", caption: "navigate", action: "moveDown", order: 0 }
|
|
448
|
-
]);
|
|
508
|
+
ctx.setKeyBinding(navBindings);
|
|
449
509
|
}
|
|
450
510
|
}, [sortOrder, sortable]);
|
|
451
511
|
const selectedIndex = selectedIndexRef.current;
|
|
512
|
+
const needsBar = displayItems.length > effectiveMaxHeight;
|
|
513
|
+
const barGlyphs = needsBar ? scrollbarGlyphs(effectiveMaxHeight, displayItems.length, clampedScrollOffset) : null;
|
|
514
|
+
const appendBar = (rowContent, displayIndex) => {
|
|
515
|
+
if (!barGlyphs) return rowContent;
|
|
516
|
+
const glyph = barGlyphs[displayIndex] ?? BAR_TRACK;
|
|
517
|
+
return h2(
|
|
518
|
+
import_ink2.Box,
|
|
519
|
+
{ flexDirection: "row" },
|
|
520
|
+
rowContent,
|
|
521
|
+
h2(import_ink2.Text, { color: glyph === BAR_THUMB ? "cyan" : "gray" }, glyph)
|
|
522
|
+
);
|
|
523
|
+
};
|
|
452
524
|
const defaultRenderItem = (item, isSelected, displayIndex, actualIndex) => {
|
|
453
525
|
const isFirstVisible = displayIndex === 0;
|
|
454
526
|
const isLastVisible = displayIndex === visibleItems.length - 1;
|
|
455
|
-
let arrowPrefix = "";
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
arrowPrefix = "\
|
|
459
|
-
} else if (isLastVisible && canScrollDown) {
|
|
460
|
-
arrowPrefix = "\u2193 ";
|
|
461
|
-
} else {
|
|
462
|
-
arrowPrefix = " ";
|
|
463
|
-
}
|
|
464
|
-
if (isSelected) {
|
|
465
|
-
selectionPrefix = selectionMarker;
|
|
466
|
-
} else {
|
|
467
|
-
selectionPrefix = " ".repeat(selectionMarker.length);
|
|
527
|
+
let arrowPrefix = " ";
|
|
528
|
+
if (!needsBar) {
|
|
529
|
+
if (isFirstVisible && canScrollUp) arrowPrefix = "\u2191 ";
|
|
530
|
+
else if (isLastVisible && canScrollDown) arrowPrefix = "\u2193 ";
|
|
468
531
|
}
|
|
532
|
+
const selectionPrefix = isSelected ? selectionMarker : " ".repeat(selectionMarker.length);
|
|
533
|
+
const label = clipNameForScrollbar(item.name, needsBar);
|
|
469
534
|
return h2(
|
|
470
535
|
import_ink2.Box,
|
|
471
536
|
{ flexDirection: "row" },
|
|
472
|
-
|
|
473
|
-
h2(import_ink2.Text, {
|
|
474
|
-
key: `arrow-${actualIndex}`,
|
|
475
|
-
color: "white"
|
|
476
|
-
}, arrowPrefix),
|
|
477
|
-
// Selection marker space (always same width, not highlighted)
|
|
537
|
+
h2(import_ink2.Text, { key: `arrow-${actualIndex}`, color: "white" }, arrowPrefix),
|
|
478
538
|
h2(import_ink2.Text, { key: `marker-${actualIndex}`, color: "white" }, selectionPrefix),
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
539
|
+
h2(
|
|
540
|
+
import_ink2.Text,
|
|
541
|
+
{
|
|
542
|
+
key: `name-${actualIndex}`,
|
|
543
|
+
color: isSelected ? "black" : "white",
|
|
544
|
+
backgroundColor: isSelected ? "cyan" : void 0,
|
|
545
|
+
bold: isSelected
|
|
546
|
+
},
|
|
547
|
+
label
|
|
548
|
+
)
|
|
486
549
|
);
|
|
487
550
|
};
|
|
488
551
|
const itemRenderer = renderItem || defaultRenderItem;
|
|
@@ -495,42 +558,32 @@ function ListComponent({ items, ctx, selectedIndexRef, renderItem, getTitle, sor
|
|
|
495
558
|
if (renderItem) {
|
|
496
559
|
const isFirstVisible = displayIndex === 0;
|
|
497
560
|
const isLastVisible = displayIndex === visibleItems.length - 1;
|
|
498
|
-
let arrowPrefix = "";
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
arrowPrefix = "\
|
|
502
|
-
} else if (isLastVisible && canScrollDown) {
|
|
503
|
-
arrowPrefix = "\u2193 ";
|
|
504
|
-
} else {
|
|
505
|
-
arrowPrefix = " ";
|
|
506
|
-
}
|
|
507
|
-
if (isSelected) {
|
|
508
|
-
selectionPrefix = selectionMarker;
|
|
509
|
-
} else {
|
|
510
|
-
selectionPrefix = " ".repeat(selectionMarker.length);
|
|
561
|
+
let arrowPrefix = " ";
|
|
562
|
+
if (!needsBar) {
|
|
563
|
+
if (isFirstVisible && canScrollUp) arrowPrefix = "\u2191 ";
|
|
564
|
+
else if (isLastVisible && canScrollDown) arrowPrefix = "\u2193 ";
|
|
511
565
|
}
|
|
566
|
+
const selectionPrefix = isSelected ? selectionMarker : " ".repeat(selectionMarker.length);
|
|
567
|
+
const clipped = needsBar ? { ...item, name: clipNameForScrollbar(item.name, true) } : item;
|
|
568
|
+
const row = h2(
|
|
569
|
+
import_ink2.Box,
|
|
570
|
+
{ flexDirection: "row" },
|
|
571
|
+
h2(import_ink2.Text, { key: `arrow-${actualIndex}`, color: "white" }, arrowPrefix),
|
|
572
|
+
h2(import_ink2.Text, { key: `marker-${actualIndex}`, color: "white" }, selectionPrefix),
|
|
573
|
+
renderItem(clipped, isSelected, displayIndex)
|
|
574
|
+
);
|
|
512
575
|
return h2(ScreenRow, {
|
|
513
576
|
key: `item-${actualIndex}`,
|
|
514
|
-
children:
|
|
515
|
-
import_ink2.Box,
|
|
516
|
-
{ flexDirection: "row" },
|
|
517
|
-
// Arrow (clickable if functional, not highlighted)
|
|
518
|
-
h2(import_ink2.Text, {
|
|
519
|
-
key: `arrow-${actualIndex}`,
|
|
520
|
-
color: "white"
|
|
521
|
-
}, arrowPrefix),
|
|
522
|
-
// Selection marker space (always same width, not highlighted)
|
|
523
|
-
h2(import_ink2.Text, { key: `marker-${actualIndex}`, color: "white" }, selectionPrefix),
|
|
524
|
-
// Custom rendered content
|
|
525
|
-
renderItem(item, isSelected, displayIndex)
|
|
526
|
-
)
|
|
527
|
-
});
|
|
528
|
-
} else {
|
|
529
|
-
return h2(ScreenRow, {
|
|
530
|
-
key: `item-${actualIndex}`,
|
|
531
|
-
children: itemRenderer(item, isSelected, displayIndex, actualIndex)
|
|
577
|
+
children: appendBar(row, displayIndex)
|
|
532
578
|
});
|
|
533
579
|
}
|
|
580
|
+
return h2(ScreenRow, {
|
|
581
|
+
key: `item-${actualIndex}`,
|
|
582
|
+
children: appendBar(
|
|
583
|
+
itemRenderer(item, isSelected, displayIndex, actualIndex),
|
|
584
|
+
displayIndex
|
|
585
|
+
)
|
|
586
|
+
});
|
|
534
587
|
})
|
|
535
588
|
);
|
|
536
589
|
}
|
|
@@ -990,8 +1043,6 @@ function InputField({ prompt, value, onChange: _onChange, onSubmit: _onSubmit })
|
|
|
990
1043
|
var import_react5 = null; // Will be set by load();
|
|
991
1044
|
var import_ink5 = null; // Will be set by load();
|
|
992
1045
|
// Removed: intermediate assignment - code will access import variable directly
|
|
993
|
-
var BAR_THUMB = "#";
|
|
994
|
-
var BAR_TRACK = "|";
|
|
995
1046
|
function wrapTextLines(text, cols) {
|
|
996
1047
|
const w = Math.max(1, Math.floor(Number(cols) || 1));
|
|
997
1048
|
const out = [];
|
|
@@ -1009,21 +1060,6 @@ function wrapTextLines(text, cols) {
|
|
|
1009
1060
|
}
|
|
1010
1061
|
return out;
|
|
1011
1062
|
}
|
|
1012
|
-
function scrollbarGlyphs(viewportRows, totalLines, scrollTop) {
|
|
1013
|
-
const view = Math.max(1, Math.floor(viewportRows));
|
|
1014
|
-
const total = Math.max(0, Math.floor(totalLines));
|
|
1015
|
-
if (total <= view) return null;
|
|
1016
|
-
const maxScroll = total - view;
|
|
1017
|
-
const thumbSize = Math.max(1, Math.round(view / total * view));
|
|
1018
|
-
const travel = Math.max(0, view - thumbSize);
|
|
1019
|
-
const s = Math.min(Math.max(0, Math.floor(scrollTop)), maxScroll);
|
|
1020
|
-
const thumbStart = maxScroll === 0 ? 0 : Math.round(s / maxScroll * travel);
|
|
1021
|
-
const glyphs = [];
|
|
1022
|
-
for (let i = 0; i < view; i++) {
|
|
1023
|
-
glyphs.push(i >= thumbStart && i < thumbStart + thumbSize ? BAR_THUMB : BAR_TRACK);
|
|
1024
|
-
}
|
|
1025
|
-
return glyphs;
|
|
1026
|
-
}
|
|
1027
1063
|
function padEndVisible(s, w) {
|
|
1028
1064
|
const t = String(s ?? "");
|
|
1029
1065
|
if (t.length >= w) return t.slice(0, w);
|
|
@@ -1032,12 +1068,7 @@ function padEndVisible(s, w) {
|
|
|
1032
1068
|
var SCROLL_KEYS = [
|
|
1033
1069
|
{ key: "upArrow", caption: "scroll", action: "scrollUp", order: 0 },
|
|
1034
1070
|
{ key: "downArrow", caption: "scroll", action: "scrollDown", order: 0 },
|
|
1035
|
-
|
|
1036
|
-
{ key: "downArrow", meta: true, caption: "page", action: "pageDown", order: 0 },
|
|
1037
|
-
{ key: "upArrow", ctrl: true, caption: "page", action: "pageUp", order: 0 },
|
|
1038
|
-
{ key: "downArrow", ctrl: true, caption: "page", action: "pageDown", order: 0 },
|
|
1039
|
-
{ key: "pageUp", caption: "page", action: "pageUp", order: 0 },
|
|
1040
|
-
{ key: "pageDown", caption: "page", action: "pageDown", order: 0 }
|
|
1071
|
+
...PAGE_SCROLL_KEY_BINDINGS
|
|
1041
1072
|
];
|
|
1042
1073
|
function ScrollableText({
|
|
1043
1074
|
ctx,
|
|
@@ -1283,6 +1314,8 @@ if (typeof window === "undefined") {
|
|
|
1283
1314
|
}
|
|
1284
1315
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1285
1316
|
0 && (module.exports = {
|
|
1317
|
+
BAR_THUMB,
|
|
1318
|
+
BAR_TRACK,
|
|
1286
1319
|
Box,
|
|
1287
1320
|
Divider,
|
|
1288
1321
|
FooterPresets,
|
|
@@ -1292,6 +1325,7 @@ if (typeof window === "undefined") {
|
|
|
1292
1325
|
ListItem,
|
|
1293
1326
|
MultiColumnListComponent,
|
|
1294
1327
|
MultiColumnListWithPreviewComponent,
|
|
1328
|
+
PAGE_SCROLL_KEY_BINDINGS,
|
|
1295
1329
|
React,
|
|
1296
1330
|
ScreenBody,
|
|
1297
1331
|
ScreenContainer,
|