@pi-unipi/ask-user 2.0.0 → 2.0.1
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/ask-ui.ts +61 -22
- package/package.json +1 -1
package/ask-ui.ts
CHANGED
|
@@ -450,6 +450,20 @@ export function renderAskUI(params: {
|
|
|
450
450
|
theme: Theme,
|
|
451
451
|
width: number,
|
|
452
452
|
) {
|
|
453
|
+
const addWrappedOptionLine = (prefix: string, content: string) => {
|
|
454
|
+
const prefixWidth = visibleWidth(prefix);
|
|
455
|
+
const contentWidth = Math.max(1, width - prefixWidth);
|
|
456
|
+
const continuationPrefix = " ".repeat(prefixWidth);
|
|
457
|
+
const wrapped = wrapTextWithAnsi(content, contentWidth);
|
|
458
|
+
for (let lineIndex = 0; lineIndex < wrapped.length; lineIndex++) {
|
|
459
|
+
add((lineIndex === 0 ? prefix : continuationPrefix) + wrapped[lineIndex]);
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
const addWrappedDescription = (description: string) => {
|
|
464
|
+
addWrappedOptionLine(" ", theme.fg("muted", description));
|
|
465
|
+
};
|
|
466
|
+
|
|
453
467
|
for (let i = 0; i < displayOptions.length; i++) {
|
|
454
468
|
const opt = displayOptions[i];
|
|
455
469
|
const isSelected = i === optionIndex;
|
|
@@ -467,11 +481,9 @@ export function renderAskUI(params: {
|
|
|
467
481
|
label = `${opt.label}: "${customText}"`;
|
|
468
482
|
}
|
|
469
483
|
|
|
470
|
-
|
|
471
|
-
prefix +
|
|
472
|
-
|
|
473
|
-
" " +
|
|
474
|
-
theme.fg(isSelected ? "accent" : "text", label),
|
|
484
|
+
addWrappedOptionLine(
|
|
485
|
+
prefix + theme.fg(color, `[${box}]`) + " ",
|
|
486
|
+
theme.fg(isSelected ? "accent" : "text", label),
|
|
475
487
|
);
|
|
476
488
|
|
|
477
489
|
// Show edit indicator if in edit mode for this option
|
|
@@ -493,11 +505,9 @@ export function renderAskUI(params: {
|
|
|
493
505
|
label = `${opt.label}: "${optCustom}"`;
|
|
494
506
|
}
|
|
495
507
|
|
|
496
|
-
|
|
497
|
-
prefix +
|
|
498
|
-
|
|
499
|
-
" " +
|
|
500
|
-
theme.fg(isSelected ? "accent" : "text", label),
|
|
508
|
+
addWrappedOptionLine(
|
|
509
|
+
prefix + theme.fg(color, `[${box}]`) + " ",
|
|
510
|
+
theme.fg(isSelected ? "accent" : "text", label),
|
|
501
511
|
);
|
|
502
512
|
|
|
503
513
|
// Show edit indicator if in edit mode for this option
|
|
@@ -525,11 +535,11 @@ export function renderAskUI(params: {
|
|
|
525
535
|
label += theme.fg("dim", " ↗");
|
|
526
536
|
}
|
|
527
537
|
|
|
528
|
-
|
|
529
|
-
prefix
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
538
|
+
addWrappedOptionLine(
|
|
539
|
+
prefix,
|
|
540
|
+
isSelected
|
|
541
|
+
? theme.fg("accent", label)
|
|
542
|
+
: theme.fg("text", label),
|
|
533
543
|
);
|
|
534
544
|
|
|
535
545
|
// Show edit indicator if in edit mode for this option
|
|
@@ -543,7 +553,7 @@ export function renderAskUI(params: {
|
|
|
543
553
|
|
|
544
554
|
// Description
|
|
545
555
|
if (opt.description) {
|
|
546
|
-
|
|
556
|
+
addWrappedDescription(opt.description);
|
|
547
557
|
}
|
|
548
558
|
}
|
|
549
559
|
}
|
|
@@ -564,17 +574,46 @@ export function renderAskUI(params: {
|
|
|
564
574
|
export function createRenderCall() {
|
|
565
575
|
return (args: Record<string, unknown>, theme: Theme, _context: unknown) => {
|
|
566
576
|
const question = (args.question as string) || "";
|
|
567
|
-
const
|
|
577
|
+
const context = (args.context as string | undefined) || "";
|
|
578
|
+
const options = Array.isArray(args.options)
|
|
579
|
+
? (args.options as Array<Record<string, unknown>>)
|
|
580
|
+
: [];
|
|
568
581
|
const mode = args.allowMultiple ? "multi-select" : "single-select";
|
|
582
|
+
const allowFreeform = args.allowFreeform !== false;
|
|
569
583
|
const count = options.length;
|
|
570
584
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
theme.fg("
|
|
585
|
+
const lines: string[] = [];
|
|
586
|
+
lines.push(
|
|
587
|
+
theme.fg("toolTitle", theme.bold("ask_user")) +
|
|
588
|
+
theme.fg("dim", ` (${count} option${count !== 1 ? "s" : ""}, ${mode}${allowFreeform ? ", freeform" : ""})`),
|
|
589
|
+
);
|
|
590
|
+
if (context) {
|
|
591
|
+
lines.push(theme.fg("muted", "Context: ") + theme.fg("text", context));
|
|
592
|
+
}
|
|
593
|
+
lines.push(theme.fg("muted", "Question: ") + theme.fg("text", question));
|
|
594
|
+
|
|
574
595
|
if (count > 0) {
|
|
575
|
-
|
|
596
|
+
lines.push(theme.fg("muted", "Options:"));
|
|
597
|
+
options.forEach((option, index) => {
|
|
598
|
+
const label = String(option.label ?? option.value ?? `Option ${index + 1}`);
|
|
599
|
+
const action = typeof option.action === "string" && option.action !== "select"
|
|
600
|
+
? theme.fg("dim", ` [${option.action}]`)
|
|
601
|
+
: "";
|
|
602
|
+
lines.push(
|
|
603
|
+
theme.fg("dim", ` ${index + 1}. `) +
|
|
604
|
+
theme.fg("text", label) +
|
|
605
|
+
action,
|
|
606
|
+
);
|
|
607
|
+
if (typeof option.description === "string" && option.description.trim()) {
|
|
608
|
+
lines.push(theme.fg("muted", ` ${option.description}`));
|
|
609
|
+
}
|
|
610
|
+
if (typeof option.prefill === "string" && option.prefill.trim()) {
|
|
611
|
+
lines.push(theme.fg("dim", ` prefill: ${option.prefill}`));
|
|
612
|
+
}
|
|
613
|
+
});
|
|
576
614
|
}
|
|
577
|
-
|
|
615
|
+
|
|
616
|
+
return new Text(lines.join("\n"), 0, 0);
|
|
578
617
|
};
|
|
579
618
|
}
|
|
580
619
|
|