@algolia/wizard 0.8.0-rc.58.44 → 0.8.0-rc.58.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.js +296 -277
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { render } from "ink";
5
5
 
6
6
  // src/ui/App.tsx
7
- import { Box as Box13, Text as Text13, useApp, useInput as useInput6, useWindowSize as useWindowSize7 } from "ink";
7
+ import { Box as Box14, Text as Text14, useApp, useInput as useInput6, useWindowSize as useWindowSize7 } from "ink";
8
8
 
9
9
  // src/core/store.ts
10
10
  import { create } from "zustand";
@@ -497,9 +497,9 @@ function Notices() {
497
497
  }
498
498
 
499
499
  // src/ui/PromptInput.tsx
500
- import { Box as Box5, Text as Text5, useInput as useInput2 } from "ink";
500
+ import { Box as Box6, Text as Text6, useInput as useInput2 } from "ink";
501
501
  import TextInput from "ink-text-input";
502
- import { useState as useState4 } from "react";
502
+ import { useState as useState5 } from "react";
503
503
 
504
504
  // src/ui/NextAction.tsx
505
505
  import { Box as Box3, Text as Text3 } from "ink";
@@ -525,14 +525,13 @@ function NextAction({
525
525
  }
526
526
 
527
527
  // src/ui/SelectPrompt.tsx
528
- import { Box as Box4, Text as Text4, measureElement as measureElement2, useInput, useWindowSize as useWindowSize3 } from "ink";
529
- import { useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
530
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
531
- var CANCEL = "cancel";
532
- var ARROW_WIDTH = 4;
533
- var COLUMN_GAP = 2;
534
- var BAR_PADDING = 2;
535
- var ROW_HEIGHT = 3;
528
+ import { Box as Box5, Text as Text5, useInput, useWindowSize as useWindowSize4 } from "ink";
529
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState4 } from "react";
530
+
531
+ // src/ui/ScrollView.tsx
532
+ import { Box as Box4, Text as Text4, measureElement as measureElement2, useWindowSize as useWindowSize3 } from "ink";
533
+ import { useCallback, useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
534
+ import { jsxs as jsxs3 } from "react/jsx-runtime";
536
535
  var INDICATOR_ROWS = 2;
537
536
  function fittedWidth(node, columns) {
538
537
  let left = 0;
@@ -541,6 +540,89 @@ function fittedWidth(node, columns) {
541
540
  }
542
541
  return Math.max(Math.min(measureElement2(node).width, columns - left), 0);
543
542
  }
543
+ function useScrollWindow({
544
+ itemCount,
545
+ rowHeight = 1,
546
+ followBottom = false
547
+ }) {
548
+ const viewportRef = useRef2(null);
549
+ const { columns } = useWindowSize3();
550
+ const [size, setSize] = useState3(
551
+ null
552
+ );
553
+ useLayoutEffect(() => {
554
+ if (!viewportRef.current) return;
555
+ const width = fittedWidth(viewportRef.current, columns);
556
+ const { height } = measureElement2(viewportRef.current);
557
+ setSize(
558
+ (prev) => prev?.width === width && prev.height === height ? prev : { width, height }
559
+ );
560
+ });
561
+ const capacity = size === null || itemCount * rowHeight <= size.height ? itemCount : Math.max(Math.floor((size.height - INDICATOR_ROWS) / rowHeight), 1);
562
+ const maxOffset = Math.max(itemCount - capacity, 0);
563
+ const [offset, setOffset] = useState3(0);
564
+ const prevMaxOffsetRef = useRef2(0);
565
+ useLayoutEffect(() => {
566
+ const wasAtBottom = offset >= prevMaxOffsetRef.current;
567
+ prevMaxOffsetRef.current = maxOffset;
568
+ setOffset(
569
+ (o) => followBottom && wasAtBottom ? maxOffset : Math.min(o, maxOffset)
570
+ );
571
+ }, [maxOffset, followBottom]);
572
+ const scrollBy = useCallback(
573
+ (delta) => {
574
+ setOffset((o) => Math.min(Math.max(o + delta, 0), maxOffset));
575
+ },
576
+ [maxOffset]
577
+ );
578
+ const revealIndex = useCallback(
579
+ (index) => {
580
+ setOffset((o) => {
581
+ if (index < o) return index;
582
+ if (index >= o + capacity) {
583
+ return Math.min(index - capacity + 1, maxOffset);
584
+ }
585
+ return o;
586
+ });
587
+ },
588
+ [capacity, maxOffset]
589
+ );
590
+ const visibleCount = Math.min(capacity, Math.max(itemCount - offset, 0));
591
+ return {
592
+ viewportRef,
593
+ width: size?.width ?? columns,
594
+ offset,
595
+ capacity,
596
+ maxOffset,
597
+ hiddenAbove: Math.min(offset, itemCount),
598
+ hiddenBelow: Math.max(itemCount - offset - visibleCount, 0),
599
+ scrollBy,
600
+ revealIndex
601
+ };
602
+ }
603
+ function ScrollView({ scroll, children }) {
604
+ return /* @__PURE__ */ jsxs3(Box4, { ref: scroll.viewportRef, flexDirection: "column", flexGrow: 1, children: [
605
+ scroll.hiddenAbove > 0 && /* @__PURE__ */ jsxs3(Text4, { color: COLORS.dim, children: [
606
+ "\u2191 ",
607
+ scroll.hiddenAbove,
608
+ " more"
609
+ ] }),
610
+ children,
611
+ scroll.hiddenBelow > 0 && /* @__PURE__ */ jsxs3(Text4, { color: COLORS.dim, children: [
612
+ "\u2193 ",
613
+ scroll.hiddenBelow,
614
+ " more"
615
+ ] })
616
+ ] });
617
+ }
618
+
619
+ // src/ui/SelectPrompt.tsx
620
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
621
+ var CANCEL = "cancel";
622
+ var ARROW_WIDTH = 4;
623
+ var COLUMN_GAP = 2;
624
+ var BAR_PADDING = 2;
625
+ var ROW_HEIGHT = 3;
544
626
  function SelectPrompt({
545
627
  options,
546
628
  onSelect,
@@ -554,10 +636,10 @@ function SelectPrompt({
554
636
  secondary,
555
637
  defaultSelectedIndex = 0
556
638
  }) {
557
- const [index, setIndex] = useState3(
639
+ const [index, setIndex] = useState4(
558
640
  () => defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0
559
641
  );
560
- const [checked, setChecked] = useState3(() => /* @__PURE__ */ new Set());
642
+ const [checked, setChecked] = useState4(() => /* @__PURE__ */ new Set());
561
643
  const hasCancel = Boolean(multi || cancelable);
562
644
  const rows = hasCancel ? [...options, "Cancel"] : options;
563
645
  const cancelIndex = hasCancel ? options.length : -1;
@@ -565,19 +647,14 @@ function SelectPrompt({
565
647
  if (rows.length > 1) hints.push({ key: "[\u2191] [\u2193]", label: "move" });
566
648
  if (multi) hints.push({ key: "[space]", label: "select" });
567
649
  hints.push({ key: "[enter]", label: "confirm" });
568
- const containerRef = useRef2(null);
569
- const viewportRef = useRef2(null);
570
- const { columns, rows: windowRows } = useWindowSize3();
571
- const [width, setWidth] = useState3(columns);
572
- const [viewportHeight, setViewportHeight] = useState3(null);
573
- useLayoutEffect(() => {
574
- if (containerRef.current) {
575
- setWidth(fittedWidth(containerRef.current, columns));
576
- }
577
- if (viewportRef.current) {
578
- setViewportHeight(measureElement2(viewportRef.current).height);
579
- }
580
- }, [columns, windowRows, error, question, helpText, messages, table]);
650
+ const containerRef = useRef3(null);
651
+ const { columns } = useWindowSize4();
652
+ const [width, setWidth] = useState4(columns);
653
+ useLayoutEffect2(() => {
654
+ if (!containerRef.current) return;
655
+ const measured = fittedWidth(containerRef.current, columns);
656
+ setWidth((prev) => prev === measured ? prev : measured);
657
+ });
581
658
  const inner = Math.max(width - BAR_PADDING, 0);
582
659
  const labelWidth = Math.min(
583
660
  ARROW_WIDTH + (multi ? 2 : 0) + Math.max(0, ...rows.map((opt) => opt.length)) + COLUMN_GAP,
@@ -593,22 +670,15 @@ function SelectPrompt({
593
670
  const barWidth = Math.min(labelWidth + badgeWidth + BAR_PADDING, width);
594
671
  const barLabelWidth = Math.max(barWidth - BAR_PADDING - badgeWidth, 0);
595
672
  const textWidth = inner - labelWidth;
596
- const capacity = viewportHeight === null || rows.length * ROW_HEIGHT <= viewportHeight ? rows.length : Math.max(Math.floor((viewportHeight - INDICATOR_ROWS) / ROW_HEIGHT), 1);
597
- const maxOffset = Math.max(rows.length - capacity, 0);
598
- const [offset, setOffset] = useState3(0);
599
- useLayoutEffect(() => {
600
- setOffset((o) => {
601
- const clamped = Math.min(o, maxOffset);
602
- if (index < clamped) return index;
603
- if (index >= clamped + capacity) {
604
- return Math.min(index - capacity + 1, maxOffset);
605
- }
606
- return clamped;
607
- });
608
- }, [index, capacity, maxOffset]);
609
- const visible = rows.slice(offset, offset + capacity);
610
- const hiddenAbove = offset;
611
- const hiddenBelow = rows.length - offset - visible.length;
673
+ const scroll = useScrollWindow({
674
+ itemCount: rows.length,
675
+ rowHeight: ROW_HEIGHT
676
+ });
677
+ const { revealIndex } = scroll;
678
+ useLayoutEffect2(() => {
679
+ revealIndex(index);
680
+ }, [index, revealIndex]);
681
+ const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
612
682
  useInput((input, key) => {
613
683
  if (rows.length === 0) return;
614
684
  if (key.upArrow || input === "k") {
@@ -632,68 +702,56 @@ function SelectPrompt({
632
702
  }
633
703
  }
634
704
  });
635
- return /* @__PURE__ */ jsx4(Box4, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", gap: 1, width, children: [
636
- /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", gap: 1, flexShrink: 0, children: [
637
- error && /* @__PURE__ */ jsx4(Text4, { color: COLORS.danger, children: error }),
638
- messages?.map((m, i) => /* @__PURE__ */ jsx4(Text4, { color: COLORS.muted, children: m }, `msg-${i}`)),
705
+ return /* @__PURE__ */ jsx4(Box5, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", gap: 1, width, children: [
706
+ /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", gap: 1, flexShrink: 0, children: [
707
+ error && /* @__PURE__ */ jsx4(Text5, { color: COLORS.danger, children: error }),
708
+ messages?.map((m, i) => /* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, children: m }, `msg-${i}`)),
639
709
  table && /* @__PURE__ */ jsx4(Table, { columns: table.columns, rows: table.rows }),
640
- /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", children: [
641
- question && /* @__PURE__ */ jsx4(Text4, { color: COLORS.muted, children: question }),
642
- helpText && /* @__PURE__ */ jsx4(Text4, { color: COLORS.dim, children: helpText })
643
- ] })
644
- ] }),
645
- /* @__PURE__ */ jsxs3(Box4, { ref: viewportRef, flexDirection: "column", flexGrow: 1, children: [
646
- hiddenAbove > 0 && /* @__PURE__ */ jsxs3(Text4, { color: COLORS.dim, children: [
647
- "\u2191 ",
648
- hiddenAbove,
649
- " more"
650
- ] }),
651
- visible.map((option, visibleIndex) => {
652
- const i = offset + visibleIndex;
653
- const highlighted = i === index;
654
- const isCancel = i === cancelIndex;
655
- const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
656
- const sec = isCancel ? void 0 : secondary?.[i];
657
- const labelColor = highlighted ? COLORS.highlight.fg : void 0;
658
- const label = /* @__PURE__ */ jsxs3(Text4, { color: labelColor, wrap: "truncate", children: [
659
- highlighted ? "\u276F " : " ",
660
- bullet,
661
- option
662
- ] });
663
- const isText = sec?.kind === "text";
664
- return /* @__PURE__ */ jsxs3(
665
- Box4,
666
- {
667
- width: isText ? "100%" : barWidth,
668
- paddingX: 1,
669
- paddingY: 1,
670
- backgroundColor: highlighted ? COLORS.highlight.bg : void 0,
671
- children: [
672
- /* @__PURE__ */ jsx4(Box4, { width: isText ? labelWidth : barLabelWidth, children: label }),
673
- isText && textWidth > 0 && /* @__PURE__ */ jsx4(Box4, { width: textWidth, children: /* @__PURE__ */ jsx4(
674
- Text4,
675
- {
676
- wrap: "truncate",
677
- color: highlighted ? COLORS.primary : COLORS.muted,
678
- children: sec.value
679
- }
680
- ) }),
681
- sec?.kind === "badge" && /* @__PURE__ */ jsx4(Box4, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx4(Text4, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
682
- ]
683
- },
684
- `row-${i}`
685
- );
686
- }),
687
- hiddenBelow > 0 && /* @__PURE__ */ jsxs3(Text4, { color: COLORS.dim, children: [
688
- "\u2193 ",
689
- hiddenBelow,
690
- " more"
710
+ /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
711
+ question && /* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, children: question }),
712
+ helpText && /* @__PURE__ */ jsx4(Text5, { color: COLORS.dim, children: helpText })
691
713
  ] })
692
714
  ] }),
693
- /* @__PURE__ */ jsx4(Box4, { flexShrink: 0, children: /* @__PURE__ */ jsx4(Text4, { children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs3(Text4, { children: [
715
+ /* @__PURE__ */ jsx4(ScrollView, { scroll, children: visible.map((option, visibleIndex) => {
716
+ const i = scroll.offset + visibleIndex;
717
+ const highlighted = i === index;
718
+ const isCancel = i === cancelIndex;
719
+ const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
720
+ const sec = isCancel ? void 0 : secondary?.[i];
721
+ const labelColor = highlighted ? COLORS.highlight.fg : void 0;
722
+ const label = /* @__PURE__ */ jsxs4(Text5, { color: labelColor, wrap: "truncate", children: [
723
+ highlighted ? "\u276F " : " ",
724
+ bullet,
725
+ option
726
+ ] });
727
+ const isText = sec?.kind === "text";
728
+ return /* @__PURE__ */ jsxs4(
729
+ Box5,
730
+ {
731
+ width: isText ? "100%" : barWidth,
732
+ paddingX: 1,
733
+ paddingY: 1,
734
+ backgroundColor: highlighted ? COLORS.highlight.bg : void 0,
735
+ children: [
736
+ /* @__PURE__ */ jsx4(Box5, { width: isText ? labelWidth : barLabelWidth, children: label }),
737
+ isText && textWidth > 0 && /* @__PURE__ */ jsx4(Box5, { width: textWidth, children: /* @__PURE__ */ jsx4(
738
+ Text5,
739
+ {
740
+ wrap: "truncate",
741
+ color: highlighted ? COLORS.primary : COLORS.muted,
742
+ children: sec.value
743
+ }
744
+ ) }),
745
+ sec?.kind === "badge" && /* @__PURE__ */ jsx4(Box5, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx4(Text5, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
746
+ ]
747
+ },
748
+ `row-${i}`
749
+ );
750
+ }) }),
751
+ /* @__PURE__ */ jsx4(Box5, { flexShrink: 0, children: /* @__PURE__ */ jsx4(Text5, { children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs4(Text5, { children: [
694
752
  i > 0 ? " " : "",
695
- /* @__PURE__ */ jsx4(Text4, { color: COLORS.primary, children: key }),
696
- /* @__PURE__ */ jsxs3(Text4, { color: COLORS.dim, children: [
753
+ /* @__PURE__ */ jsx4(Text5, { color: COLORS.primary, children: key }),
754
+ /* @__PURE__ */ jsxs4(Text5, { color: COLORS.dim, children: [
697
755
  " ",
698
756
  label
699
757
  ] })
@@ -702,7 +760,7 @@ function SelectPrompt({
702
760
  }
703
761
 
704
762
  // src/ui/PromptInput.tsx
705
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
763
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
706
764
  var ACCEPT_REJECT_OPTIONS = ["Accept", "Reject"];
707
765
  function EnterToContinuePrompt({
708
766
  question,
@@ -713,10 +771,10 @@ function EnterToContinuePrompt({
713
771
  if (key.return) onDecide(true);
714
772
  else if (key.escape) onDecide(false);
715
773
  });
716
- return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", gap: 1, children: [
717
- messages?.map((m, i) => /* @__PURE__ */ jsx5(Text5, { color: COLORS.muted, children: m }, `msg-${i}`)),
718
- question && /* @__PURE__ */ jsx5(Text5, { color: COLORS.primary, children: question }),
719
- /* @__PURE__ */ jsxs4(Box5, { gap: 1, flexDirection: "column", children: [
774
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", gap: 1, children: [
775
+ messages?.map((m, i) => /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: m }, `msg-${i}`)),
776
+ question && /* @__PURE__ */ jsx5(Text6, { color: COLORS.primary, children: question }),
777
+ /* @__PURE__ */ jsxs5(Box6, { gap: 1, flexDirection: "column", children: [
720
778
  /* @__PURE__ */ jsx5(NextAction, { action: "continue", keyHint: "enter" }),
721
779
  /* @__PURE__ */ jsx5(NextAction, { action: "decline", keyHint: "esc", hierarchy: "secondary" })
722
780
  ] })
@@ -724,13 +782,13 @@ function EnterToContinuePrompt({
724
782
  }
725
783
  function PromptInput() {
726
784
  const { phase, inputReq, submitInput } = useWizard();
727
- const [draft, setDraft] = useState4("");
785
+ const [draft, setDraft] = useState5("");
728
786
  if (phase === "done" || phase === "error") {
729
- return /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
787
+ return /* @__PURE__ */ jsx5(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text6, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
730
788
  }
731
789
  if (phase !== "awaitingInput" || !inputReq) return null;
732
790
  if (inputReq.promptType === "multipleChoice") {
733
- return /* @__PURE__ */ jsx5(Box5, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
791
+ return /* @__PURE__ */ jsx5(Box6, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
734
792
  SelectPrompt,
735
793
  {
736
794
  question: inputReq.prompt,
@@ -747,7 +805,7 @@ function PromptInput() {
747
805
  ) });
748
806
  }
749
807
  if (inputReq.promptType === "multiSelect") {
750
- return /* @__PURE__ */ jsx5(Box5, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
808
+ return /* @__PURE__ */ jsx5(Box6, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
751
809
  SelectPrompt,
752
810
  {
753
811
  multi: true,
@@ -762,7 +820,7 @@ function PromptInput() {
762
820
  ) });
763
821
  }
764
822
  if (inputReq.promptType === "notice") {
765
- return /* @__PURE__ */ jsx5(Box5, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
823
+ return /* @__PURE__ */ jsx5(Box6, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
766
824
  SelectPrompt,
767
825
  {
768
826
  question: inputReq.prompt,
@@ -784,7 +842,7 @@ function PromptInput() {
784
842
  }
785
843
  if (inputReq.promptType === "acceptReject") {
786
844
  const labels = inputReq.options?.length ? inputReq.options : ACCEPT_REJECT_OPTIONS;
787
- return /* @__PURE__ */ jsx5(Box5, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
845
+ return /* @__PURE__ */ jsx5(Box6, { flexGrow: 1, children: /* @__PURE__ */ jsx5(
788
846
  SelectPrompt,
789
847
  {
790
848
  question: inputReq.prompt,
@@ -795,11 +853,11 @@ function PromptInput() {
795
853
  }
796
854
  ) });
797
855
  }
798
- return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
799
- inputReq.error && /* @__PURE__ */ jsx5(Text5, { color: COLORS.danger, children: inputReq.error }),
800
- inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx5(Text5, { color: COLORS.muted, children: m }, `msg-${i}`)),
801
- /* @__PURE__ */ jsxs4(Box5, { children: [
802
- /* @__PURE__ */ jsxs4(Text5, { color: COLORS.primary, children: [
856
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
857
+ inputReq.error && /* @__PURE__ */ jsx5(Text6, { color: COLORS.danger, children: inputReq.error }),
858
+ inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: m }, `msg-${i}`)),
859
+ /* @__PURE__ */ jsxs5(Box6, { children: [
860
+ /* @__PURE__ */ jsxs5(Text6, { color: COLORS.primary, children: [
803
861
  inputReq.prompt,
804
862
  " "
805
863
  ] }),
@@ -821,7 +879,7 @@ function PromptInput() {
821
879
  // src/ui/Welcome.tsx
822
880
  import { dirname as dirname2, join as join3 } from "node:path";
823
881
  import { fileURLToPath } from "node:url";
824
- import { Box as Box6, Spacer, Text as Text6, useInput as useInput3, useWindowSize as useWindowSize4 } from "ink";
882
+ import { Box as Box7, Spacer, Text as Text7, useInput as useInput3, useWindowSize as useWindowSize5 } from "ink";
825
883
 
826
884
  // src/ui/copy/welcome.ts
827
885
  var sidebarItems = [
@@ -849,27 +907,27 @@ var sidebarItems = [
849
907
 
850
908
  // src/ui/Welcome.tsx
851
909
  import Image, { InkPictureProvider } from "ink-picture";
852
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
910
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
853
911
  var IMAGE_PATH = join3(dirname2(fileURLToPath(import.meta.url)), "algolia.png");
854
912
  function SidebarItem({
855
913
  title,
856
914
  description
857
915
  }) {
858
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
859
- /* @__PURE__ */ jsxs5(Box6, { gap: 1, children: [
860
- /* @__PURE__ */ jsx6(Text6, { color: COLORS.success, children: "\u2192" }),
861
- /* @__PURE__ */ jsx6(Text6, { color: COLORS.strong, bold: true, children: title })
916
+ return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
917
+ /* @__PURE__ */ jsxs6(Box7, { gap: 1, children: [
918
+ /* @__PURE__ */ jsx6(Text7, { color: COLORS.success, children: "\u2192" }),
919
+ /* @__PURE__ */ jsx6(Text7, { color: COLORS.strong, bold: true, children: title })
862
920
  ] }),
863
- /* @__PURE__ */ jsxs5(Box6, { flexDirection: "row", gap: 2, children: [
921
+ /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 2, children: [
864
922
  /* @__PURE__ */ jsx6(Spacer, {}),
865
- /* @__PURE__ */ jsx6(Text6, { color: COLORS.muted, children: description })
923
+ /* @__PURE__ */ jsx6(Text7, { color: COLORS.muted, children: description })
866
924
  ] })
867
925
  ] });
868
926
  }
869
927
  function Welcome() {
870
928
  const confirmStart = useWizard((s) => s.confirmStart);
871
929
  const openLearnMore = useWizard((s) => s.openLearnMore);
872
- const { rows } = useWindowSize4();
930
+ const { rows } = useWindowSize5();
873
931
  useInput3((input, key) => {
874
932
  if (key.return) confirmStart();
875
933
  else if (input === "i") openLearnMore();
@@ -888,15 +946,15 @@ function Welcome() {
888
946
  if (rows < 30) {
889
947
  layout = scales["small"];
890
948
  }
891
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
949
+ return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
892
950
  /* @__PURE__ */ jsx6(
893
- Box6,
951
+ Box7,
894
952
  {
895
953
  paddingY: layout.main.padding.y,
896
954
  paddingX: layout.main.padding.x,
897
955
  flexDirection: "column",
898
956
  justifyContent: "center",
899
- children: /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", gap: 2, children: [
957
+ children: /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", gap: 2, children: [
900
958
  /* @__PURE__ */ jsx6(InkPictureProvider, { children: /* @__PURE__ */ jsx6(
901
959
  Image,
902
960
  {
@@ -908,16 +966,16 @@ function Welcome() {
908
966
  protocol: "halfBlock"
909
967
  }
910
968
  ) }),
911
- /* @__PURE__ */ jsx6(Text6, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
912
- /* @__PURE__ */ jsxs5(Box6, { gap: 1, flexDirection: "column", children: [
969
+ /* @__PURE__ */ jsx6(Text7, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
970
+ /* @__PURE__ */ jsxs6(Box7, { gap: 1, flexDirection: "column", children: [
913
971
  /* @__PURE__ */ jsx6(NextAction, { action: "start wizard", keyHint: "enter" }),
914
972
  /* @__PURE__ */ jsx6(NextAction, { action: "learn more", keyHint: "i", hierarchy: "secondary" })
915
973
  ] })
916
974
  ] })
917
975
  }
918
976
  ),
919
- /* @__PURE__ */ jsxs5(
920
- Box6,
977
+ /* @__PURE__ */ jsxs6(
978
+ Box7,
921
979
  {
922
980
  backgroundColor: COLORS.bg.sidebar,
923
981
  width: 40,
@@ -927,7 +985,7 @@ function Welcome() {
927
985
  flexDirection: "column",
928
986
  justifyContent: "center",
929
987
  children: [
930
- /* @__PURE__ */ jsx6(Text6, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
988
+ /* @__PURE__ */ jsx6(Text7, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
931
989
  sidebarItems.map((i, idx) => /* @__PURE__ */ jsx6(SidebarItem, { title: i.title, description: i.description }, idx))
932
990
  ]
933
991
  }
@@ -937,7 +995,7 @@ function Welcome() {
937
995
 
938
996
  // src/ui/LearnMore.tsx
939
997
  import { Fragment as Fragment2 } from "react";
940
- import { Box as Box7, Text as Text7, useInput as useInput4, useWindowSize as useWindowSize5 } from "ink";
998
+ import { Box as Box8, Text as Text8, useInput as useInput4, useWindowSize as useWindowSize6 } from "ink";
941
999
 
942
1000
  // src/ui/copy/learn-more.ts
943
1001
  var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
@@ -974,7 +1032,7 @@ var policyLinks = [
974
1032
  ];
975
1033
 
976
1034
  // src/ui/LearnMore.tsx
977
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1035
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
978
1036
  var TAG_COLORS = {
979
1037
  READ: COLORS.success,
980
1038
  WRITE: COLORS.badge,
@@ -990,25 +1048,25 @@ function NeverLine({
990
1048
  }) {
991
1049
  const used = segments.reduce((n, s) => n + s.text.length, 0);
992
1050
  const rightPad = Math.max(0, width - 2 - NEVER_BOX_PAD_X - used);
993
- return /* @__PURE__ */ jsxs6(Text7, { children: [
994
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: "\u2502" }),
1051
+ return /* @__PURE__ */ jsxs7(Text8, { children: [
1052
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: "\u2502" }),
995
1053
  " ".repeat(NEVER_BOX_PAD_X),
996
- segments.map((s, i) => /* @__PURE__ */ jsx7(Text7, { color: s.color, bold: s.bold, children: s.text }, i)),
1054
+ segments.map((s, i) => /* @__PURE__ */ jsx7(Text8, { color: s.color, bold: s.bold, children: s.text }, i)),
997
1055
  " ".repeat(rightPad),
998
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: "\u2502" })
1056
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: "\u2502" })
999
1057
  ] });
1000
1058
  }
1001
1059
  function LearnMore() {
1002
1060
  const confirmStart = useWizard((s) => s.confirmStart);
1003
1061
  const backToHome = useWizard((s) => s.backToHome);
1004
- const { columns } = useWindowSize5();
1062
+ const { columns } = useWindowSize6();
1005
1063
  const dividerWidth = Math.max(0, columns - PADDING_X * 2);
1006
1064
  useInput4((_input, key) => {
1007
1065
  if (key.escape) backToHome();
1008
1066
  else if (key.return) confirmStart();
1009
1067
  });
1010
- return /* @__PURE__ */ jsxs6(
1011
- Box7,
1068
+ return /* @__PURE__ */ jsxs7(
1069
+ Box8,
1012
1070
  {
1013
1071
  flexDirection: "column",
1014
1072
  paddingX: PADDING_X,
@@ -1016,20 +1074,20 @@ function LearnMore() {
1016
1074
  width: "100%",
1017
1075
  gap: 1,
1018
1076
  children: [
1019
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
1020
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: accessIntro }),
1021
- /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", marginTop: 1, children: [
1022
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
1023
- /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, marginTop: 1, children: [
1024
- /* @__PURE__ */ jsx7(Box7, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx7(Text7, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
1025
- /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", children: /* @__PURE__ */ jsxs6(Text7, { children: [
1026
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.strong, bold: true, children: item.title }),
1027
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
1077
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
1078
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: accessIntro }),
1079
+ /* @__PURE__ */ jsx7(Box8, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", marginTop: 1, children: [
1080
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
1081
+ /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, marginTop: 1, children: [
1082
+ /* @__PURE__ */ jsx7(Box8, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx7(Text8, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
1083
+ /* @__PURE__ */ jsx7(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsxs7(Text8, { children: [
1084
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.strong, bold: true, children: item.title }),
1085
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
1028
1086
  ] }) })
1029
1087
  ] })
1030
1088
  ] }, item.tag)) }),
1031
- /* @__PURE__ */ jsxs6(Box7, { marginTop: 1, flexDirection: "column", children: [
1032
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
1089
+ /* @__PURE__ */ jsxs7(Box8, { marginTop: 1, flexDirection: "column", children: [
1090
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
1033
1091
  /* @__PURE__ */ jsx7(NeverLine, { width: dividerWidth }),
1034
1092
  /* @__PURE__ */ jsx7(
1035
1093
  NeverLine,
@@ -1038,7 +1096,7 @@ function LearnMore() {
1038
1096
  segments: [{ text: "I NEVER", color: COLORS.danger, bold: true }]
1039
1097
  }
1040
1098
  ),
1041
- neverItems.map((item) => /* @__PURE__ */ jsxs6(Fragment2, { children: [
1099
+ neverItems.map((item) => /* @__PURE__ */ jsxs7(Fragment2, { children: [
1042
1100
  /* @__PURE__ */ jsx7(NeverLine, { width: dividerWidth }),
1043
1101
  /* @__PURE__ */ jsx7(
1044
1102
  NeverLine,
@@ -1053,23 +1111,23 @@ function LearnMore() {
1053
1111
  )
1054
1112
  ] }, item)),
1055
1113
  /* @__PURE__ */ jsx7(NeverLine, { width: dividerWidth }),
1056
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
1114
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
1057
1115
  ] }),
1058
- /* @__PURE__ */ jsx7(Box7, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, children: [
1059
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
1060
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.accent, children: link.url })
1116
+ /* @__PURE__ */ jsx7(Box8, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
1117
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
1118
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.accent, children: link.url })
1061
1119
  ] }, link.label)) }),
1062
- /* @__PURE__ */ jsxs6(Box7, { marginTop: 1, flexDirection: "row", gap: 3, children: [
1063
- /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, children: [
1064
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "[" }),
1065
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.primary, children: "esc" }),
1066
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "] back" })
1120
+ /* @__PURE__ */ jsxs7(Box8, { marginTop: 1, flexDirection: "row", gap: 3, children: [
1121
+ /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
1122
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "[" }),
1123
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.primary, children: "esc" }),
1124
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "] back" })
1067
1125
  ] }),
1068
- /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, children: [
1069
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "[" }),
1070
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.primary, children: "enter" }),
1071
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "]" }),
1072
- /* @__PURE__ */ jsx7(Text7, { color: COLORS.success, bold: true, children: "start wizard" })
1126
+ /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
1127
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "[" }),
1128
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.primary, children: "enter" }),
1129
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "]" }),
1130
+ /* @__PURE__ */ jsx7(Text8, { color: COLORS.success, bold: true, children: "start wizard" })
1073
1131
  ] })
1074
1132
  ] })
1075
1133
  ]
@@ -1078,10 +1136,10 @@ function LearnMore() {
1078
1136
  }
1079
1137
 
1080
1138
  // src/ui/Sidebar.tsx
1081
- import { Box as Box10, Text as Text10 } from "ink";
1139
+ import { Box as Box11, Text as Text11 } from "ink";
1082
1140
 
1083
1141
  // src/ui/Steps.tsx
1084
- import { Box as Box8, Text as Text8 } from "ink";
1142
+ import { Box as Box9, Text as Text9 } from "ink";
1085
1143
  import Spinner from "ink-spinner";
1086
1144
 
1087
1145
  // src/core/persistence.ts
@@ -1110,11 +1168,11 @@ async function clearWorkflowState(workflowId) {
1110
1168
  }
1111
1169
 
1112
1170
  // src/ui/Steps.tsx
1113
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1171
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1114
1172
  function Steps() {
1115
1173
  const { steps } = useWizard();
1116
1174
  const visibleSteps = steps.filter(isStepVisible);
1117
- return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsxs7(Text8, { color: COLORS.status[s.status], children: [
1175
+ return /* @__PURE__ */ jsx8(Box9, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx8(Box9, { flexDirection: "column", children: /* @__PURE__ */ jsxs8(Text9, { color: COLORS.status[s.status], children: [
1118
1176
  s.status === "running" ? /* @__PURE__ */ jsx8(Spinner, { type: "dots" }) : MARKER[s.status],
1119
1177
  " ",
1120
1178
  s.title
@@ -1124,7 +1182,7 @@ function CurrentStep() {
1124
1182
  const { steps } = useWizard();
1125
1183
  const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
1126
1184
  if (!currentStep) return null;
1127
- return /* @__PURE__ */ jsxs7(Text8, { color: COLORS.status.running, children: [
1185
+ return /* @__PURE__ */ jsxs8(Text9, { color: COLORS.status.running, children: [
1128
1186
  /* @__PURE__ */ jsx8(Spinner, { type: "dots" }),
1129
1187
  " ",
1130
1188
  ` ${currentStep.title}`
@@ -1132,19 +1190,19 @@ function CurrentStep() {
1132
1190
  }
1133
1191
 
1134
1192
  // src/ui/Progress.tsx
1135
- import { Box as Box9, Text as Text9 } from "ink";
1136
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1193
+ import { Box as Box10, Text as Text10 } from "ink";
1194
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1137
1195
  function Progress() {
1138
1196
  const { steps, currentStepIndex } = useWizard();
1139
1197
  const visibleSteps = steps.filter(isStepVisible);
1140
1198
  if (visibleSteps.length === 0) return null;
1141
1199
  const visibleCountThroughCurrent = steps.slice(0, currentStepIndex + 1).filter(isStepVisible).length;
1142
1200
  const activeStepNumber = Math.max(1, visibleCountThroughCurrent);
1143
- return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", gap: 1, children: [
1144
- /* @__PURE__ */ jsx9(Text9, { color: COLORS.muted, children: "STEP" }),
1145
- /* @__PURE__ */ jsx9(Text9, { bold: true, children: activeStepNumber }),
1146
- /* @__PURE__ */ jsx9(Text9, { bold: true, children: "/" }),
1147
- /* @__PURE__ */ jsx9(Text9, { bold: true, children: visibleSteps.length })
1201
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, children: [
1202
+ /* @__PURE__ */ jsx9(Text10, { color: COLORS.muted, children: "STEP" }),
1203
+ /* @__PURE__ */ jsx9(Text10, { bold: true, children: activeStepNumber }),
1204
+ /* @__PURE__ */ jsx9(Text10, { bold: true, children: "/" }),
1205
+ /* @__PURE__ */ jsx9(Text10, { bold: true, children: visibleSteps.length })
1148
1206
  ] });
1149
1207
  }
1150
1208
 
@@ -1155,10 +1213,10 @@ var sidebarCommands = [
1155
1213
  ];
1156
1214
 
1157
1215
  // src/ui/Sidebar.tsx
1158
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1216
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1159
1217
  function Sidebar() {
1160
- return /* @__PURE__ */ jsxs9(
1161
- Box10,
1218
+ return /* @__PURE__ */ jsxs10(
1219
+ Box11,
1162
1220
  {
1163
1221
  backgroundColor: "#14171E",
1164
1222
  width: 30,
@@ -1167,16 +1225,16 @@ function Sidebar() {
1167
1225
  flexDirection: "column",
1168
1226
  justifyContent: "space-between",
1169
1227
  children: [
1170
- /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", gap: 1, children: [
1171
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: "PROGRESS" }),
1228
+ /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", gap: 1, children: [
1229
+ /* @__PURE__ */ jsx10(Text11, { color: COLORS.muted, children: "PROGRESS" }),
1172
1230
  /* @__PURE__ */ jsx10(Steps, {})
1173
1231
  ] }),
1174
- /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", gap: 1, children: [
1232
+ /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", gap: 1, children: [
1175
1233
  /* @__PURE__ */ jsx10(Progress, {}),
1176
- /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", children: sidebarCommands.map((c) => {
1177
- return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, children: [
1178
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.primary, children: `[${c.keyHint}]` }),
1179
- /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: c.description })
1234
+ /* @__PURE__ */ jsx10(Box11, { flexDirection: "column", children: sidebarCommands.map((c) => {
1235
+ return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, children: [
1236
+ /* @__PURE__ */ jsx10(Text11, { color: COLORS.primary, children: `[${c.keyHint}]` }),
1237
+ /* @__PURE__ */ jsx10(Text11, { color: COLORS.muted, children: c.description })
1180
1238
  ] });
1181
1239
  }) })
1182
1240
  ] })
@@ -1186,12 +1244,12 @@ function Sidebar() {
1186
1244
  }
1187
1245
 
1188
1246
  // src/ui/Ribbon.tsx
1189
- import { Box as Box11, Text as Text11 } from "ink";
1190
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1247
+ import { Box as Box12, Text as Text12 } from "ink";
1248
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1191
1249
  function Ribbon() {
1192
1250
  const firstCommand = sidebarCommands[0];
1193
- return /* @__PURE__ */ jsxs10(
1194
- Box11,
1251
+ return /* @__PURE__ */ jsxs11(
1252
+ Box12,
1195
1253
  {
1196
1254
  backgroundColor: "#14171E",
1197
1255
  flexDirection: "row",
@@ -1201,9 +1259,9 @@ function Ribbon() {
1201
1259
  children: [
1202
1260
  /* @__PURE__ */ jsx11(Progress, {}),
1203
1261
  /* @__PURE__ */ jsx11(CurrentStep, {}),
1204
- /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, children: [
1205
- /* @__PURE__ */ jsx11(Text11, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
1206
- /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: firstCommand.description })
1262
+ /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: 1, children: [
1263
+ /* @__PURE__ */ jsx11(Text12, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
1264
+ /* @__PURE__ */ jsx11(Text12, { color: COLORS.muted, children: firstCommand.description })
1207
1265
  ] })
1208
1266
  ]
1209
1267
  }
@@ -1214,9 +1272,8 @@ function Ribbon() {
1214
1272
  import { useState as useState6 } from "react";
1215
1273
 
1216
1274
  // src/ui/Logs.tsx
1217
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState5 } from "react";
1218
- import { Box as Box12, Text as Text12, measureElement as measureElement3, useInput as useInput5, useWindowSize as useWindowSize6 } from "ink";
1219
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1275
+ import { Box as Box13, Text as Text13, useInput as useInput5 } from "ink";
1276
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1220
1277
  var KIND_COLOR = {
1221
1278
  tool: COLORS.primary,
1222
1279
  prompt: COLORS.badge
@@ -1246,75 +1303,32 @@ function formatTimestamp(ms) {
1246
1303
  }
1247
1304
  function Logs() {
1248
1305
  const logs = useWizard((s) => s.logs);
1249
- const { rows, columns } = useWindowSize6();
1250
- const viewportRef = useRef3(null);
1251
- const [viewportHeight, setViewportHeight] = useState5(0);
1252
- const [viewportWidth, setViewportWidth] = useState5(0);
1253
- const [scrollOffset, setScrollOffset] = useState5(0);
1254
- const prevMaxOffsetRef = useRef3(0);
1255
- useLayoutEffect2(() => {
1256
- if (!viewportRef.current) return;
1257
- const { width, height } = measureElement3(viewportRef.current);
1258
- setViewportHeight(height);
1259
- setViewportWidth(width);
1260
- }, [rows, columns, logs.length === 0]);
1261
- let capacity = viewportHeight;
1262
- for (let i = 0; i < 2; i++) {
1263
- const hasAbove = scrollOffset > 0;
1264
- const hasBelow = scrollOffset + capacity < logs.length;
1265
- capacity = Math.max(
1266
- viewportHeight - (hasAbove ? 1 : 0) - (hasBelow ? 1 : 0),
1267
- 0
1268
- );
1269
- }
1270
- const capacityAtBottom = logs.length > viewportHeight ? Math.max(viewportHeight - 1, 0) : viewportHeight;
1271
- const maxOffset = Math.max(logs.length - capacityAtBottom, 0);
1272
- useLayoutEffect2(() => {
1273
- const wasAtBottom = scrollOffset >= prevMaxOffsetRef.current;
1274
- prevMaxOffsetRef.current = maxOffset;
1275
- setScrollOffset((o) => wasAtBottom ? maxOffset : Math.min(o, maxOffset));
1276
- }, [maxOffset]);
1306
+ const scroll = useScrollWindow({ itemCount: logs.length, followBottom: true });
1277
1307
  useInput5((_input, key) => {
1278
- if (!key.upArrow && !key.downArrow) return;
1279
- setScrollOffset(
1280
- (o) => key.upArrow ? Math.max(o - 1, 0) : Math.min(o + 1, maxOffset)
1281
- );
1308
+ if (key.upArrow) scroll.scrollBy(-1);
1309
+ else if (key.downArrow) scroll.scrollBy(1);
1282
1310
  });
1283
- const visible = logs.slice(scrollOffset, scrollOffset + capacity);
1284
- const hiddenAbove = scrollOffset;
1285
- const hiddenBelow = logs.length - scrollOffset - visible.length;
1286
- return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
1287
- logs.length === 0 && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: "No logs yet." }),
1288
- /* @__PURE__ */ jsxs11(Box12, { ref: viewportRef, flexDirection: "column", flexGrow: 1, children: [
1289
- hiddenAbove > 0 && /* @__PURE__ */ jsxs11(Text12, { color: COLORS.dim, children: [
1290
- "\u2191 ",
1291
- hiddenAbove,
1292
- " more"
1293
- ] }),
1294
- visible.map((entry) => {
1295
- const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
1296
- const durationText = entry.kind === "tool" && entry.durationMs !== void 0 ? `${entry.durationMs}ms` : "";
1297
- const rawPreview = rawInputText(entry.input);
1298
- const partCount = 2 + (rawPreview ? 1 : 0) + (durationText ? 1 : 0);
1299
- const gaps = (partCount - 1) * ROW_GAP;
1300
- let budget = viewportWidth - timestamp.length - durationText.length - gaps;
1301
- const name = truncate2(entry.name, budget);
1302
- budget -= name.length;
1303
- const preview = rawPreview ? truncate2(rawPreview, budget) : "";
1304
- return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: ROW_GAP, children: [
1305
- /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: timestamp }),
1306
- /* @__PURE__ */ jsx12(Text12, { color: logNameColor(entry), wrap: "truncate", children: name }),
1307
- preview && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, wrap: "truncate", children: preview }),
1308
- durationText && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: durationText })
1309
- ] }, entry.id);
1310
- }),
1311
- hiddenBelow > 0 && /* @__PURE__ */ jsxs11(Text12, { color: COLORS.dim, children: [
1312
- "\u2193 ",
1313
- hiddenBelow,
1314
- " more"
1315
- ] })
1316
- ] }),
1317
- /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
1311
+ const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
1312
+ return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
1313
+ logs.length === 0 && /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: "No logs yet." }),
1314
+ /* @__PURE__ */ jsx12(ScrollView, { scroll, children: visible.map((entry) => {
1315
+ const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
1316
+ const durationText = entry.kind === "tool" && entry.durationMs !== void 0 ? `${entry.durationMs}ms` : "";
1317
+ const rawPreview = rawInputText(entry.input);
1318
+ const partCount = 2 + (rawPreview ? 1 : 0) + (durationText ? 1 : 0);
1319
+ const gaps = (partCount - 1) * ROW_GAP;
1320
+ let budget = scroll.width - timestamp.length - durationText.length - gaps;
1321
+ const name = truncate2(entry.name, budget);
1322
+ budget -= name.length;
1323
+ const preview = rawPreview ? truncate2(rawPreview, budget) : "";
1324
+ return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "row", gap: ROW_GAP, children: [
1325
+ /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: timestamp }),
1326
+ /* @__PURE__ */ jsx12(Text13, { color: logNameColor(entry), wrap: "truncate", children: name }),
1327
+ preview && /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, wrap: "truncate", children: preview }),
1328
+ durationText && /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: durationText })
1329
+ ] }, entry.id);
1330
+ }) }),
1331
+ /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
1318
1332
  ] });
1319
1333
  }
1320
1334
 
@@ -1506,7 +1520,7 @@ function track(event, payload) {
1506
1520
  }
1507
1521
 
1508
1522
  // src/ui/App.tsx
1509
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1523
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1510
1524
  function App() {
1511
1525
  const { phase, error, homeScreen, currentStepIndex, steps, inputReq } = useWizard();
1512
1526
  const { exit } = useApp();
@@ -1549,19 +1563,24 @@ function App() {
1549
1563
  const mainWindowVisible = phase === "running" || phase === "awaitingInput" || phase === "error" || phase === "done";
1550
1564
  const flexDirection = columns > 90 ? "row" : "column";
1551
1565
  const showSidebar = flexDirection === "row";
1552
- return /* @__PURE__ */ jsxs12(
1553
- Box13,
1566
+ return /* @__PURE__ */ jsxs13(
1567
+ Box14,
1554
1568
  {
1555
1569
  backgroundColor: COLORS.bg.main,
1556
1570
  flexDirection: "row",
1557
1571
  width: columns,
1558
1572
  minHeight: rows,
1559
1573
  children: [
1560
- mainWindowVisible && /* @__PURE__ */ jsxs12(
1561
- Box13,
1574
+ mainWindowVisible && // Ink sizes the root by width only, so without a cap the scrolling
1575
+ // lists in here grow to their content instead of windowing (see
1576
+ // `useScrollWindow`). The home screens below stay uncapped: they are
1577
+ // long static copy that would be clipped rather than windowed.
1578
+ /* @__PURE__ */ jsxs13(
1579
+ Box14,
1562
1580
  {
1563
1581
  flexDirection,
1564
1582
  width: "100%",
1583
+ maxHeight: rows,
1565
1584
  justifyContent: "space-between",
1566
1585
  children: [
1567
1586
  showLogs ? /* @__PURE__ */ jsx13(Logs, {}) : (
@@ -1569,8 +1588,8 @@ function App() {
1569
1588
  sidebar, height above the ribbon. The height matters even
1570
1589
  stacked: it is what the prompt's scrolling list measures itself
1571
1590
  against (see SelectPrompt). */
1572
- /* @__PURE__ */ jsxs12(
1573
- Box13,
1591
+ /* @__PURE__ */ jsxs13(
1592
+ Box14,
1574
1593
  {
1575
1594
  flexDirection: "column",
1576
1595
  paddingX: 4,
@@ -1580,8 +1599,8 @@ function App() {
1580
1599
  children: [
1581
1600
  /* @__PURE__ */ jsx13(Notices, {}),
1582
1601
  /* @__PURE__ */ jsx13(PromptInput, {}),
1583
- phase === "running" && showSidebar && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx13(CurrentStep, {}) }),
1584
- phase === "error" && error && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: COLORS.status.error, children: [
1602
+ phase === "running" && showSidebar && /* @__PURE__ */ jsx13(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx13(CurrentStep, {}) }),
1603
+ phase === "error" && error && /* @__PURE__ */ jsx13(Box14, { marginTop: 1, children: /* @__PURE__ */ jsxs13(Text14, { color: COLORS.status.error, children: [
1585
1604
  "\u2716 ",
1586
1605
  error
1587
1606
  ] }) })
@@ -2742,7 +2761,7 @@ async function runAnalysis(mode, extraInstructions = []) {
2742
2761
  // package.json
2743
2762
  var package_default = {
2744
2763
  name: "@algolia/wizard",
2745
- version: "0.8.0-rc.58.44",
2764
+ version: "0.8.0-rc.58.45",
2746
2765
  description: "Magically implement Algolia functionality in your codebase",
2747
2766
  type: "module",
2748
2767
  engines: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algolia/wizard",
3
- "version": "0.8.0-rc.58.44",
3
+ "version": "0.8.0-rc.58.45",
4
4
  "description": "Magically implement Algolia functionality in your codebase",
5
5
  "type": "module",
6
6
  "engines": {