@algolia/wizard 0.61.0 → 0.62.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.
Files changed (2) hide show
  1. package/dist/main.js +379 -303
  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 Box20, Text as Text21, useApp, useInput as useInput8, useWindowSize as useWindowSize7 } from "ink";
7
+ import { Box as Box20, Text as Text21, useApp, useInput as useInput9, useWindowSize as useWindowSize7 } from "ink";
8
8
  import Spinner3 from "ink-spinner";
9
9
 
10
10
  // src/core/store.ts
@@ -651,12 +651,13 @@ function Notices({
651
651
  }
652
652
 
653
653
  // src/ui/PromptInput.tsx
654
- import { Box as Box9, Text as Text10 } from "ink";
654
+ import { Box as Box10, Text as Text11 } from "ink";
655
655
  import Spinner from "ink-spinner";
656
- import { useState as useState7 } from "react";
656
+ import { useState as useState9 } from "react";
657
657
 
658
658
  // src/ui/CommandApproval.tsx
659
- import { Box as Box6, Text as Text6 } from "ink";
659
+ import { Box as Box8, Text as Text8, useInput as useInput3 } from "ink";
660
+ import { useLayoutEffect as useLayoutEffect3, useState as useState6 } from "react";
660
661
 
661
662
  // src/ui/DecisionSelect.tsx
662
663
  import { Box as Box5, Text as Text5, useInput } from "ink";
@@ -707,13 +708,14 @@ function SelectRow({
707
708
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
708
709
  function DecisionSelect({
709
710
  actions,
710
- onDecide
711
+ onDecide,
712
+ extraHints = []
711
713
  }) {
712
714
  const [index, setIndex] = useState3(0);
713
- useInput((input, key) => {
714
- if (key.upArrow || input === "k") {
715
+ useInput((_input, key) => {
716
+ if (key.upArrow) {
715
717
  setIndex((i) => (i - 1 + actions.length) % actions.length);
716
- } else if (key.downArrow || input === "j") {
718
+ } else if (key.downArrow) {
717
719
  setIndex((i) => (i + 1) % actions.length);
718
720
  } else if (key.return) {
719
721
  onDecide(actions[index].value);
@@ -732,6 +734,13 @@ function DecisionSelect({
732
734
  action.label
733
735
  )) }),
734
736
  /* @__PURE__ */ jsxs4(Box5, { gap: 2, children: [
737
+ extraHints.map(({ key, label }) => /* @__PURE__ */ jsxs4(Text5, { children: [
738
+ /* @__PURE__ */ jsx4(Text5, { color: COLORS.primary, children: key }),
739
+ /* @__PURE__ */ jsxs4(Text5, { color: COLORS.dim, children: [
740
+ " ",
741
+ label
742
+ ] })
743
+ ] }, label)),
735
744
  /* @__PURE__ */ jsxs4(Text5, { children: [
736
745
  /* @__PURE__ */ jsx4(Text5, { color: COLORS.primary, children: "[\u2191] [\u2193]" }),
737
746
  /* @__PURE__ */ jsx4(Text5, { color: COLORS.dim, children: " move" })
@@ -744,112 +753,14 @@ function DecisionSelect({
744
753
  ] });
745
754
  }
746
755
 
747
- // src/ui/CommandApproval.tsx
748
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
749
- function CommandApproval({
750
- command,
751
- messages,
752
- onDecide
753
- }) {
754
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", gap: 1, children: [
755
- messages?.map((message, index) => /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: message }, `msg-${index}`)),
756
- /* @__PURE__ */ jsx5(Text6, { color: COLORS.primary, bold: true, children: "Run this command?" }),
757
- /* @__PURE__ */ jsxs5(
758
- Box6,
759
- {
760
- flexDirection: "column",
761
- paddingLeft: 2,
762
- borderStyle: "single",
763
- borderColor: COLORS.success,
764
- borderTop: false,
765
- borderBottom: false,
766
- borderRight: false,
767
- gap: 1,
768
- children: [
769
- /* @__PURE__ */ jsxs5(Box6, { children: [
770
- /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: "$ " }),
771
- /* @__PURE__ */ jsx5(Text6, { color: COLORS.strong, wrap: "wrap", children: command.command })
772
- ] }),
773
- /* @__PURE__ */ jsxs5(Box6, { gap: 1, children: [
774
- /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: "in:" }),
775
- /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, wrap: "wrap", children: command.cwd })
776
- ] }),
777
- command.explanation && /* @__PURE__ */ jsxs5(Box6, { gap: 1, children: [
778
- /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: "why:" }),
779
- /* @__PURE__ */ jsx5(Text6, { color: COLORS.accent, wrap: "wrap", children: command.explanation })
780
- ] })
781
- ]
782
- }
783
- ),
784
- /* @__PURE__ */ jsx5(
785
- DecisionSelect,
786
- {
787
- actions: [
788
- { label: "approve", value: "approve" },
789
- { label: "reject", value: "reject" }
790
- ],
791
- onDecide
792
- }
793
- )
794
- ] });
795
- }
796
-
797
- // src/ui/FreeTextInput.tsx
798
- import { Text as Text7, useInput as useInput2 } from "ink";
799
- import { useState as useState4 } from "react";
800
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
801
- function FreeTextInput({
802
- value,
803
- onChange,
804
- onSubmit
805
- }) {
806
- const [cursor, setCursor] = useState4(value.length);
807
- const at = Math.min(cursor, value.length);
808
- useInput2((input, key) => {
809
- if (key.upArrow || key.downArrow || key.tab || key.ctrl && input === "c") {
810
- return;
811
- }
812
- if (key.return) {
813
- onSubmit(value);
814
- return;
815
- }
816
- if (key.leftArrow) {
817
- setCursor(Math.max(0, at - 1));
818
- return;
819
- }
820
- if (key.rightArrow) {
821
- setCursor(Math.min(value.length, at + 1));
822
- return;
823
- }
824
- if (key.backspace || key.delete) {
825
- if (at === 0) return;
826
- onChange(value.slice(0, at - 1) + value.slice(at));
827
- setCursor(at - 1);
828
- return;
829
- }
830
- if (input) {
831
- onChange(value.slice(0, at) + input + value.slice(at));
832
- setCursor(at + input.length);
833
- }
834
- });
835
- const before = value.slice(0, at);
836
- const current = value.slice(at, at + 1) || " ";
837
- const after = value.slice(at + 1);
838
- return /* @__PURE__ */ jsxs6(Text7, { color: COLORS.strong, children: [
839
- before,
840
- /* @__PURE__ */ jsx6(Text7, { inverse: true, children: current }),
841
- after
842
- ] });
843
- }
844
-
845
- // src/ui/SelectPrompt.tsx
846
- import { Box as Box8, Text as Text9, useInput as useInput3, useWindowSize as useWindowSize4 } from "ink";
847
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState6 } from "react";
756
+ // src/ui/Review.tsx
757
+ import { Box as Box7, Text as Text7, useInput as useInput2 } from "ink";
758
+ import { useLayoutEffect as useLayoutEffect2, useState as useState5 } from "react";
848
759
 
849
760
  // src/ui/ScrollView.tsx
850
- import { Box as Box7, Text as Text8, measureElement as measureElement2, useWindowSize as useWindowSize3 } from "ink";
851
- import { useCallback, useLayoutEffect, useRef as useRef2, useState as useState5 } from "react";
852
- import { jsxs as jsxs7 } from "react/jsx-runtime";
761
+ import { Box as Box6, Text as Text6, measureElement as measureElement2, useWindowSize as useWindowSize3 } from "ink";
762
+ import { useCallback, useLayoutEffect, useRef as useRef2, useState as useState4 } from "react";
763
+ import { jsxs as jsxs5 } from "react/jsx-runtime";
853
764
  var INDICATOR_ROWS = 2;
854
765
  function fittedWidth(node, columns) {
855
766
  let left = 0;
@@ -865,7 +776,7 @@ function useScrollWindow({
865
776
  }) {
866
777
  const viewportRef = useRef2(null);
867
778
  const { columns } = useWindowSize3();
868
- const [size, setSize] = useState5(
779
+ const [size, setSize] = useState4(
869
780
  null
870
781
  );
871
782
  useLayoutEffect(() => {
@@ -878,7 +789,7 @@ function useScrollWindow({
878
789
  });
879
790
  const capacity = size === null || itemCount * rowHeight <= size.height ? itemCount : Math.max(Math.floor((size.height - INDICATOR_ROWS) / rowHeight), 1);
880
791
  const maxOffset = Math.max(itemCount - capacity, 0);
881
- const [offset, setOffset] = useState5(0);
792
+ const [offset, setOffset] = useState4(0);
882
793
  const prevMaxOffsetRef = useRef2(0);
883
794
  useLayoutEffect(() => {
884
795
  const wasAtBottom = offset >= prevMaxOffsetRef.current;
@@ -920,14 +831,14 @@ function useScrollWindow({
920
831
  };
921
832
  }
922
833
  function ScrollView({ scroll, children }) {
923
- return /* @__PURE__ */ jsxs7(Box7, { ref: scroll.viewportRef, flexDirection: "column", flexGrow: 1, children: [
924
- scroll.hiddenAbove > 0 && /* @__PURE__ */ jsxs7(Text8, { color: COLORS.dim, children: [
834
+ return /* @__PURE__ */ jsxs5(Box6, { ref: scroll.viewportRef, flexDirection: "column", flexGrow: 1, children: [
835
+ scroll.hiddenAbove > 0 && /* @__PURE__ */ jsxs5(Text6, { color: COLORS.dim, children: [
925
836
  "\u2191 ",
926
837
  scroll.hiddenAbove,
927
838
  " more"
928
839
  ] }),
929
840
  children,
930
- scroll.hiddenBelow > 0 && /* @__PURE__ */ jsxs7(Text8, { color: COLORS.dim, children: [
841
+ scroll.hiddenBelow > 0 && /* @__PURE__ */ jsxs5(Text6, { color: COLORS.dim, children: [
931
842
  "\u2193 ",
932
843
  scroll.hiddenBelow,
933
844
  " more"
@@ -935,8 +846,285 @@ function ScrollView({ scroll, children }) {
935
846
  ] });
936
847
  }
937
848
 
938
- // src/ui/SelectPrompt.tsx
849
+ // src/ui/Review.tsx
850
+ import { jsx as jsx5, jsxs as jsxs6 } from "react/jsx-runtime";
851
+ var INGEST_SCRIPT = ".algolia-wizard/ingest.sh";
852
+ function wrapText(text, width) {
853
+ if (width <= 0) return [text];
854
+ const lines = [];
855
+ let line = "";
856
+ for (const word of text.split(/\s+/).filter(Boolean)) {
857
+ const candidate = line ? `${line} ${word}` : word;
858
+ if (candidate.length <= width) {
859
+ line = candidate;
860
+ continue;
861
+ }
862
+ if (line) lines.push(line);
863
+ let rest = word;
864
+ while (rest.length > width) {
865
+ lines.push(rest.slice(0, width));
866
+ rest = rest.slice(width);
867
+ }
868
+ line = rest;
869
+ }
870
+ if (line) lines.push(line);
871
+ return lines.length > 0 ? lines : [""];
872
+ }
873
+ function heading(text) {
874
+ return { prefix: "", text, color: COLORS.strong, bold: true };
875
+ }
876
+ var BLANK = { prefix: "", text: " ", color: COLORS.dim };
877
+ function itemRows(items, width, prefixFor, colorFor) {
878
+ return items.flatMap((item, i) => {
879
+ const { prefix, color: prefixColor } = prefixFor(i);
880
+ const { color, bold } = colorFor(item);
881
+ return wrapText(item, width - prefix.length).map((line, j) => ({
882
+ prefix: j === 0 ? prefix : " ".repeat(prefix.length),
883
+ prefixColor,
884
+ text: line,
885
+ color,
886
+ bold
887
+ }));
888
+ });
889
+ }
890
+ function buildRows(review2, width) {
891
+ const { summaryPoints, nextSteps, reviewPrompt } = review2;
892
+ const numberWidth = String(nextSteps.length).length + 2;
893
+ const rows = [];
894
+ if (summaryPoints.length > 0) {
895
+ rows.push(heading("What we did"));
896
+ rows.push(
897
+ ...itemRows(
898
+ summaryPoints,
899
+ width,
900
+ () => ({ prefix: `${MARKER.done} `, color: COLORS.status.done }),
901
+ () => ({ color: COLORS.primary, bold: false })
902
+ )
903
+ );
904
+ }
905
+ if (nextSteps.length > 0) {
906
+ if (rows.length > 0) rows.push(BLANK);
907
+ rows.push(heading("What to do next"));
908
+ rows.push(
909
+ ...itemRows(
910
+ nextSteps,
911
+ width,
912
+ (i) => ({
913
+ prefix: `${i + 1}.`.padEnd(numberWidth),
914
+ color: COLORS.secondary
915
+ }),
916
+ (step) => step.includes(INGEST_SCRIPT) ? { color: COLORS.brand, bold: true } : { color: COLORS.primary, bold: false }
917
+ )
918
+ );
919
+ }
920
+ if (reviewPrompt) {
921
+ if (rows.length > 0) rows.push(BLANK);
922
+ rows.push(
923
+ ...wrapText(reviewPrompt, width).map((line) => ({
924
+ prefix: "",
925
+ text: line,
926
+ color: COLORS.brand
927
+ }))
928
+ );
929
+ }
930
+ return rows;
931
+ }
932
+ function ReviewPanel({ review: review2 }) {
933
+ const [width, setWidth] = useState5(0);
934
+ const rows = width > 0 ? buildRows(review2, width) : [];
935
+ const scroll = useScrollWindow({ itemCount: rows.length });
936
+ useLayoutEffect2(() => {
937
+ if (scroll.measured) setWidth(scroll.width);
938
+ }, [scroll.measured, scroll.width]);
939
+ const scrollable = scroll.maxOffset > 0;
940
+ useInput2(
941
+ (input, key) => {
942
+ if (input === "k" || key.upArrow) scroll.scrollBy(-1);
943
+ else if (input === "j" || key.downArrow) scroll.scrollBy(1);
944
+ },
945
+ { isActive: scrollable }
946
+ );
947
+ const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
948
+ return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", flexGrow: 1, children: [
949
+ /* @__PURE__ */ jsx5(ScrollView, { scroll, children: visible.map((row, i) => /* @__PURE__ */ jsxs6(Text7, { wrap: "truncate", children: [
950
+ row.prefix && /* @__PURE__ */ jsx5(Text7, { color: row.prefixColor ?? row.color, bold: row.bold, children: row.prefix }),
951
+ /* @__PURE__ */ jsx5(Text7, { color: row.color, bold: row.bold, children: row.text })
952
+ ] }, `review-row-${i}`)) }),
953
+ scrollable && /* @__PURE__ */ jsxs6(Text7, { children: [
954
+ /* @__PURE__ */ jsx5(Text7, { color: COLORS.primary, children: "[j] [k]" }),
955
+ /* @__PURE__ */ jsx5(Text7, { color: COLORS.dim, children: " scroll" })
956
+ ] })
957
+ ] });
958
+ }
959
+ function Review() {
960
+ const review2 = useWizard((s) => s.review);
961
+ if (!review2) return null;
962
+ return /* @__PURE__ */ jsx5(ReviewPanel, { review: review2 });
963
+ }
964
+
965
+ // src/ui/CommandApproval.tsx
966
+ import { jsx as jsx6, jsxs as jsxs7 } from "react/jsx-runtime";
967
+ var BLANK2 = { prefix: "", text: " ", color: COLORS.dim };
968
+ var COMMAND_PREFIX = "$ ";
969
+ function wrapExactLine(line, width) {
970
+ if (line.length === 0) return [" "];
971
+ const lines = [];
972
+ let i = 0;
973
+ while (i < line.length) {
974
+ if (line.length - i <= width) {
975
+ lines.push(line.slice(i));
976
+ break;
977
+ }
978
+ let end = i + width;
979
+ if (line.charAt(end) !== " ") {
980
+ const lastSpace = line.lastIndexOf(" ", end - 1);
981
+ if (lastSpace >= i) end = lastSpace + 1;
982
+ }
983
+ if (end <= i) end = i + width;
984
+ lines.push(line.slice(i, end));
985
+ i = end;
986
+ }
987
+ return lines;
988
+ }
989
+ function wrapExact(text, width) {
990
+ if (width <= 0) return [text || " "];
991
+ return text.split(/\r\n|\n|\r/).flatMap((line) => wrapExactLine(line, width));
992
+ }
993
+ function fieldLines(prefix, value, color, width) {
994
+ return wrapText(value, Math.max(width - prefix.length, 1)).map((text, i) => ({
995
+ prefix: i === 0 ? prefix : " ".repeat(prefix.length),
996
+ text,
997
+ color
998
+ }));
999
+ }
1000
+ function buildLines(command, width) {
1001
+ const lines = wrapExact(
1002
+ command.command,
1003
+ Math.max(width - COMMAND_PREFIX.length, 1)
1004
+ ).map((text, i) => ({
1005
+ prefix: i === 0 ? COMMAND_PREFIX : " ".repeat(COMMAND_PREFIX.length),
1006
+ text,
1007
+ color: COLORS.strong
1008
+ }));
1009
+ lines.push(BLANK2);
1010
+ lines.push(...fieldLines("in: ", command.cwd, COLORS.muted, width));
1011
+ if (command.explanation) {
1012
+ lines.push(BLANK2);
1013
+ lines.push(
1014
+ ...fieldLines("why: ", command.explanation, COLORS.accent, width)
1015
+ );
1016
+ }
1017
+ return lines;
1018
+ }
1019
+ function CommandApproval({
1020
+ command,
1021
+ messages,
1022
+ onDecide
1023
+ }) {
1024
+ const [width, setWidth] = useState6(0);
1025
+ const lines = width > 0 ? buildLines(command, width) : [];
1026
+ const scroll = useScrollWindow({ itemCount: lines.length });
1027
+ useLayoutEffect3(() => {
1028
+ if (scroll.measured) setWidth(scroll.width);
1029
+ }, [scroll.measured, scroll.width]);
1030
+ const scrollable = scroll.maxOffset > 0;
1031
+ useInput3(
1032
+ (input) => {
1033
+ if (input === "k") scroll.scrollBy(-1);
1034
+ else if (input === "j") scroll.scrollBy(1);
1035
+ },
1036
+ { isActive: scrollable }
1037
+ );
1038
+ const visible = lines.slice(scroll.offset, scroll.offset + scroll.capacity);
1039
+ return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", gap: 1, width: "100%", flexGrow: 1, flexShrink: 1, children: [
1040
+ messages?.map((message, index) => /* @__PURE__ */ jsx6(Text8, { color: COLORS.muted, children: message }, `msg-${index}`)),
1041
+ /* @__PURE__ */ jsx6(Text8, { color: COLORS.primary, bold: true, children: "Run this command?" }),
1042
+ /* @__PURE__ */ jsx6(
1043
+ Box8,
1044
+ {
1045
+ flexDirection: "column",
1046
+ paddingLeft: 2,
1047
+ borderStyle: "single",
1048
+ borderColor: COLORS.success,
1049
+ borderTop: false,
1050
+ borderBottom: false,
1051
+ borderRight: false,
1052
+ width: "100%",
1053
+ flexGrow: 1,
1054
+ flexShrink: 1,
1055
+ minHeight: 3,
1056
+ children: /* @__PURE__ */ jsx6(ScrollView, { scroll, children: visible.map((line, i) => /* @__PURE__ */ jsxs7(Text8, { wrap: "truncate", children: [
1057
+ line.prefix ? /* @__PURE__ */ jsx6(Text8, { color: COLORS.muted, children: line.prefix }) : null,
1058
+ /* @__PURE__ */ jsx6(Text8, { color: line.color, children: line.text })
1059
+ ] }, `cmd-${scroll.offset + i}`)) })
1060
+ }
1061
+ ),
1062
+ /* @__PURE__ */ jsx6(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx6(
1063
+ DecisionSelect,
1064
+ {
1065
+ actions: [
1066
+ { label: "approve", value: "approve" },
1067
+ { label: "reject", value: "reject" }
1068
+ ],
1069
+ onDecide,
1070
+ extraHints: scrollable ? [{ key: "[j] [k]", label: "scroll" }] : void 0
1071
+ }
1072
+ ) })
1073
+ ] });
1074
+ }
1075
+
1076
+ // src/ui/FreeTextInput.tsx
1077
+ import { Text as Text9, useInput as useInput4 } from "ink";
1078
+ import { useState as useState7 } from "react";
939
1079
  import { jsx as jsx7, jsxs as jsxs8 } from "react/jsx-runtime";
1080
+ function FreeTextInput({
1081
+ value,
1082
+ onChange,
1083
+ onSubmit
1084
+ }) {
1085
+ const [cursor, setCursor] = useState7(value.length);
1086
+ const at = Math.min(cursor, value.length);
1087
+ useInput4((input, key) => {
1088
+ if (key.upArrow || key.downArrow || key.tab || key.ctrl && input === "c") {
1089
+ return;
1090
+ }
1091
+ if (key.return) {
1092
+ onSubmit(value);
1093
+ return;
1094
+ }
1095
+ if (key.leftArrow) {
1096
+ setCursor(Math.max(0, at - 1));
1097
+ return;
1098
+ }
1099
+ if (key.rightArrow) {
1100
+ setCursor(Math.min(value.length, at + 1));
1101
+ return;
1102
+ }
1103
+ if (key.backspace || key.delete) {
1104
+ if (at === 0) return;
1105
+ onChange(value.slice(0, at - 1) + value.slice(at));
1106
+ setCursor(at - 1);
1107
+ return;
1108
+ }
1109
+ if (input) {
1110
+ onChange(value.slice(0, at) + input + value.slice(at));
1111
+ setCursor(at + input.length);
1112
+ }
1113
+ });
1114
+ const before = value.slice(0, at);
1115
+ const current = value.slice(at, at + 1) || " ";
1116
+ const after = value.slice(at + 1);
1117
+ return /* @__PURE__ */ jsxs8(Text9, { color: COLORS.strong, children: [
1118
+ before,
1119
+ /* @__PURE__ */ jsx7(Text9, { inverse: true, children: current }),
1120
+ after
1121
+ ] });
1122
+ }
1123
+
1124
+ // src/ui/SelectPrompt.tsx
1125
+ import { Box as Box9, Text as Text10, useInput as useInput5, useWindowSize as useWindowSize4 } from "ink";
1126
+ import { useLayoutEffect as useLayoutEffect4, useRef as useRef3, useState as useState8 } from "react";
1127
+ import { jsx as jsx8, jsxs as jsxs9 } from "react/jsx-runtime";
940
1128
  var CANCEL = "cancel";
941
1129
  var ARROW_WIDTH = 4;
942
1130
  var COLUMN_GAP = 2;
@@ -968,19 +1156,19 @@ function SelectPrompt({
968
1156
  const rows = hasCancel ? [...options, "Cancel"] : options;
969
1157
  const cancelIndex = hasCancel ? options.length : -1;
970
1158
  const isDisabled = (i) => i !== cancelIndex && Boolean(disabled?.[i]);
971
- const [index, setIndex] = useState6(() => {
1159
+ const [index, setIndex] = useState8(() => {
972
1160
  const start = defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0;
973
1161
  return isDisabled(start) ? nextSelectableIndex(start, 1, rows.length, isDisabled) : start;
974
1162
  });
975
- const [checked, setChecked] = useState6(() => /* @__PURE__ */ new Set());
1163
+ const [checked, setChecked] = useState8(() => /* @__PURE__ */ new Set());
976
1164
  const hints = [];
977
1165
  if (rows.length > 1) hints.push({ key: "[\u2191] [\u2193]", label: "move" });
978
1166
  if (multi) hints.push({ key: "[space]", label: "select" });
979
1167
  hints.push({ key: "[enter]", label: "confirm" });
980
1168
  const containerRef = useRef3(null);
981
1169
  const { columns } = useWindowSize4();
982
- const [width, setWidth] = useState6(columns);
983
- useLayoutEffect2(() => {
1170
+ const [width, setWidth] = useState8(columns);
1171
+ useLayoutEffect4(() => {
984
1172
  if (!containerRef.current) return;
985
1173
  const measured = fittedWidth(containerRef.current, columns);
986
1174
  setWidth((prev) => prev === measured ? prev : measured);
@@ -1005,11 +1193,11 @@ function SelectPrompt({
1005
1193
  rowHeight: ROW_HEIGHT
1006
1194
  });
1007
1195
  const { revealIndex } = scroll;
1008
- useLayoutEffect2(() => {
1196
+ useLayoutEffect4(() => {
1009
1197
  revealIndex(index);
1010
1198
  }, [index, revealIndex]);
1011
1199
  const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
1012
- useInput3((input, key) => {
1200
+ useInput5((input, key) => {
1013
1201
  if (rows.length === 0) return;
1014
1202
  if (key.upArrow || input === "k") {
1015
1203
  setIndex((i) => nextSelectableIndex(i, -1, rows.length, isDisabled));
@@ -1034,17 +1222,17 @@ function SelectPrompt({
1034
1222
  }
1035
1223
  }
1036
1224
  });
1037
- return /* @__PURE__ */ jsx7(Box8, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, width, children: [
1038
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, flexShrink: 0, children: [
1039
- error && /* @__PURE__ */ jsx7(Text9, { color: COLORS.danger, children: error }),
1040
- messages?.map((m, i) => /* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: m }, `msg-${i}`)),
1041
- table && /* @__PURE__ */ jsx7(Table, { columns: table.columns, rows: table.rows }),
1042
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
1043
- question && /* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: question }),
1044
- helpText && /* @__PURE__ */ jsx7(Text9, { color: COLORS.dim, children: helpText })
1225
+ return /* @__PURE__ */ jsx8(Box9, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, width, children: [
1226
+ /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, flexShrink: 0, children: [
1227
+ error && /* @__PURE__ */ jsx8(Text10, { color: COLORS.danger, children: error }),
1228
+ messages?.map((m, i) => /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: m }, `msg-${i}`)),
1229
+ table && /* @__PURE__ */ jsx8(Table, { columns: table.columns, rows: table.rows }),
1230
+ /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
1231
+ question && /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: question }),
1232
+ helpText && /* @__PURE__ */ jsx8(Text10, { color: COLORS.dim, children: helpText })
1045
1233
  ] })
1046
1234
  ] }),
1047
- /* @__PURE__ */ jsx7(ScrollView, { scroll, children: visible.map((option, visibleIndex) => {
1235
+ /* @__PURE__ */ jsx8(ScrollView, { scroll, children: visible.map((option, visibleIndex) => {
1048
1236
  const i = scroll.offset + visibleIndex;
1049
1237
  const highlighted = i === index;
1050
1238
  const isCancel = i === cancelIndex;
@@ -1052,7 +1240,7 @@ function SelectPrompt({
1052
1240
  const sec = isCancel ? void 0 : secondary?.[i];
1053
1241
  const isText = sec?.kind === "text";
1054
1242
  const rowDisabled = isDisabled(i);
1055
- return /* @__PURE__ */ jsxs8(
1243
+ return /* @__PURE__ */ jsxs9(
1056
1244
  SelectRow,
1057
1245
  {
1058
1246
  highlighted,
@@ -1062,24 +1250,24 @@ function SelectPrompt({
1062
1250
  label: `${bullet}${option}`,
1063
1251
  usePadding: true,
1064
1252
  children: [
1065
- isText && textWidth > 0 && /* @__PURE__ */ jsx7(Box8, { width: textWidth, children: /* @__PURE__ */ jsx7(
1066
- Text9,
1253
+ isText && textWidth > 0 && /* @__PURE__ */ jsx8(Box9, { width: textWidth, children: /* @__PURE__ */ jsx8(
1254
+ Text10,
1067
1255
  {
1068
1256
  wrap: "truncate",
1069
1257
  color: rowDisabled ? COLORS.dim : highlighted ? COLORS.primary : COLORS.muted,
1070
1258
  children: sec.value
1071
1259
  }
1072
1260
  ) }),
1073
- sec?.kind === "badge" && /* @__PURE__ */ jsx7(Box8, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx7(Text9, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
1261
+ sec?.kind === "badge" && /* @__PURE__ */ jsx8(Box9, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx8(Text10, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
1074
1262
  ]
1075
1263
  },
1076
1264
  `row-${i}`
1077
1265
  );
1078
1266
  }) }),
1079
- /* @__PURE__ */ jsx7(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx7(Text9, { color: COLORS.dim, children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs8(Text9, { color: COLORS.dim, children: [
1267
+ /* @__PURE__ */ jsx8(Box9, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text10, { color: COLORS.dim, children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs9(Text10, { color: COLORS.dim, children: [
1080
1268
  i > 0 ? " " : "",
1081
- /* @__PURE__ */ jsx7(Text9, { color: COLORS.primary, children: key }),
1082
- /* @__PURE__ */ jsxs8(Text9, { color: COLORS.dim, children: [
1269
+ /* @__PURE__ */ jsx8(Text10, { color: COLORS.primary, children: key }),
1270
+ /* @__PURE__ */ jsxs9(Text10, { color: COLORS.dim, children: [
1083
1271
  " ",
1084
1272
  label
1085
1273
  ] })
@@ -1088,17 +1276,17 @@ function SelectPrompt({
1088
1276
  }
1089
1277
 
1090
1278
  // src/ui/PromptInput.tsx
1091
- import { jsx as jsx8, jsxs as jsxs9 } from "react/jsx-runtime";
1279
+ import { jsx as jsx9, jsxs as jsxs10 } from "react/jsx-runtime";
1092
1280
  var ACCEPT_REJECT_OPTIONS = ["Accept", "Reject"];
1093
1281
  function EnterToContinuePrompt({
1094
1282
  question,
1095
1283
  messages,
1096
1284
  onDecide
1097
1285
  }) {
1098
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, children: [
1099
- messages?.map((m, i) => /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: m }, `msg-${i}`)),
1100
- question && /* @__PURE__ */ jsx8(Text10, { color: COLORS.primary, children: question }),
1101
- /* @__PURE__ */ jsx8(
1286
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", gap: 1, children: [
1287
+ messages?.map((m, i) => /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: m }, `msg-${i}`)),
1288
+ question && /* @__PURE__ */ jsx9(Text11, { color: COLORS.primary, children: question }),
1289
+ /* @__PURE__ */ jsx9(
1102
1290
  DecisionSelect,
1103
1291
  {
1104
1292
  actions: [
@@ -1112,17 +1300,17 @@ function EnterToContinuePrompt({
1112
1300
  }
1113
1301
  function PromptInput() {
1114
1302
  const { phase, inputReq, submitInput } = useWizard();
1115
- const [draft, setDraft] = useState7("");
1116
- const [submittedReq, setSubmittedReq] = useState7(null);
1303
+ const [draft, setDraft] = useState9("");
1304
+ const [submittedReq, setSubmittedReq] = useState9(null);
1117
1305
  const promptKey = inputReq && `${inputReq.promptType}:${inputReq.prompt}`;
1118
1306
  const submitting = inputReq != null && submittedReq === inputReq;
1119
1307
  if (phase === "done" || phase === "error") {
1120
- return /* @__PURE__ */ jsx8(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text10, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
1308
+ return /* @__PURE__ */ jsx9(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text11, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
1121
1309
  }
1122
1310
  if (phase !== "awaitingInput" || !inputReq) return null;
1123
1311
  if (submitting) {
1124
- return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsxs9(Text10, { color: COLORS.strong, bold: true, children: [
1125
- /* @__PURE__ */ jsx8(Spinner, { type: "dots" }),
1312
+ return /* @__PURE__ */ jsx9(Box10, { flexGrow: 1, children: /* @__PURE__ */ jsxs10(Text11, { color: COLORS.strong, bold: true, children: [
1313
+ /* @__PURE__ */ jsx9(Spinner, { type: "dots" }),
1126
1314
  " Continuing\u2026"
1127
1315
  ] }) });
1128
1316
  }
@@ -1131,7 +1319,7 @@ function PromptInput() {
1131
1319
  submitInput(value);
1132
1320
  };
1133
1321
  if (inputReq.promptType === "multipleChoice") {
1134
- return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx8(
1322
+ return /* @__PURE__ */ jsx9(Box10, { flexGrow: 1, children: /* @__PURE__ */ jsx9(
1135
1323
  SelectPrompt,
1136
1324
  {
1137
1325
  question: inputReq.prompt,
@@ -1150,7 +1338,7 @@ function PromptInput() {
1150
1338
  ) });
1151
1339
  }
1152
1340
  if (inputReq.promptType === "multiSelect") {
1153
- return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx8(
1341
+ return /* @__PURE__ */ jsx9(Box10, { flexGrow: 1, children: /* @__PURE__ */ jsx9(
1154
1342
  SelectPrompt,
1155
1343
  {
1156
1344
  multi: true,
@@ -1166,7 +1354,7 @@ function PromptInput() {
1166
1354
  ) });
1167
1355
  }
1168
1356
  if (inputReq.promptType === "notice") {
1169
- return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx8(
1357
+ return /* @__PURE__ */ jsx9(Box10, { flexGrow: 1, children: /* @__PURE__ */ jsx9(
1170
1358
  SelectPrompt,
1171
1359
  {
1172
1360
  messages: inputReq.messages,
@@ -1177,7 +1365,7 @@ function PromptInput() {
1177
1365
  ) });
1178
1366
  }
1179
1367
  if (inputReq.promptType === "enterToContinue") {
1180
- return /* @__PURE__ */ jsx8(
1368
+ return /* @__PURE__ */ jsx9(
1181
1369
  EnterToContinuePrompt,
1182
1370
  {
1183
1371
  question: inputReq.prompt,
@@ -1187,24 +1375,24 @@ function PromptInput() {
1187
1375
  );
1188
1376
  }
1189
1377
  if (inputReq.promptType === "commandApproval" && inputReq.command) {
1190
- return /* @__PURE__ */ jsx8(
1378
+ return /* @__PURE__ */ jsx9(Box10, { flexGrow: 1, children: /* @__PURE__ */ jsx9(
1191
1379
  CommandApproval,
1192
1380
  {
1193
1381
  command: inputReq.command,
1194
1382
  messages: inputReq.messages,
1195
1383
  onDecide: submitInput
1196
1384
  }
1197
- );
1385
+ ) });
1198
1386
  }
1199
1387
  if (inputReq.promptType === "acceptReject") {
1200
1388
  const labels = inputReq.options?.length ? inputReq.options : ACCEPT_REJECT_OPTIONS;
1201
- return /* @__PURE__ */ jsxs9(Box9, { flexGrow: 1, flexDirection: "column", gap: 1, children: [
1202
- inputReq.detectedLanguages && /* @__PURE__ */ jsxs9(Text10, { color: COLORS.muted, children: [
1389
+ return /* @__PURE__ */ jsxs10(Box10, { flexGrow: 1, flexDirection: "column", gap: 1, children: [
1390
+ inputReq.detectedLanguages && /* @__PURE__ */ jsxs10(Text11, { color: COLORS.muted, children: [
1203
1391
  "Languages:",
1204
1392
  " ",
1205
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.success, children: inputReq.detectedLanguages })
1393
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.success, children: inputReq.detectedLanguages })
1206
1394
  ] }),
1207
- /* @__PURE__ */ jsx8(
1395
+ /* @__PURE__ */ jsx9(
1208
1396
  SelectPrompt,
1209
1397
  {
1210
1398
  question: inputReq.prompt,
@@ -1217,15 +1405,15 @@ function PromptInput() {
1217
1405
  )
1218
1406
  ] });
1219
1407
  }
1220
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
1221
- inputReq.error && /* @__PURE__ */ jsx8(Text10, { color: COLORS.danger, children: inputReq.error }),
1222
- inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: m }, `msg-${i}`)),
1223
- /* @__PURE__ */ jsxs9(Box9, { children: [
1224
- /* @__PURE__ */ jsxs9(Text10, { color: COLORS.primary, children: [
1408
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
1409
+ inputReq.error && /* @__PURE__ */ jsx9(Text11, { color: COLORS.danger, children: inputReq.error }),
1410
+ inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: m }, `msg-${i}`)),
1411
+ /* @__PURE__ */ jsxs10(Box10, { children: [
1412
+ /* @__PURE__ */ jsxs10(Text11, { color: COLORS.primary, children: [
1225
1413
  inputReq.prompt,
1226
1414
  " "
1227
1415
  ] }),
1228
- /* @__PURE__ */ jsx8(
1416
+ /* @__PURE__ */ jsx9(
1229
1417
  FreeTextInput,
1230
1418
  {
1231
1419
  value: draft,
@@ -1240,121 +1428,6 @@ function PromptInput() {
1240
1428
  ] });
1241
1429
  }
1242
1430
 
1243
- // src/ui/Review.tsx
1244
- import { Box as Box10, Text as Text11, useInput as useInput4 } from "ink";
1245
- import { useLayoutEffect as useLayoutEffect3, useState as useState8 } from "react";
1246
- import { jsx as jsx9, jsxs as jsxs10 } from "react/jsx-runtime";
1247
- var INGEST_SCRIPT = ".algolia-wizard/ingest.sh";
1248
- function wrapText(text, width) {
1249
- if (width <= 0) return [text];
1250
- const lines = [];
1251
- let line = "";
1252
- for (const word of text.split(/\s+/).filter(Boolean)) {
1253
- const candidate = line ? `${line} ${word}` : word;
1254
- if (candidate.length <= width) {
1255
- line = candidate;
1256
- continue;
1257
- }
1258
- if (line) lines.push(line);
1259
- let rest = word;
1260
- while (rest.length > width) {
1261
- lines.push(rest.slice(0, width));
1262
- rest = rest.slice(width);
1263
- }
1264
- line = rest;
1265
- }
1266
- if (line) lines.push(line);
1267
- return lines.length > 0 ? lines : [""];
1268
- }
1269
- function heading(text) {
1270
- return { prefix: "", text, color: COLORS.strong, bold: true };
1271
- }
1272
- var BLANK = { prefix: "", text: " ", color: COLORS.dim };
1273
- function itemRows(items, width, prefixFor, colorFor) {
1274
- return items.flatMap((item, i) => {
1275
- const { prefix, color: prefixColor } = prefixFor(i);
1276
- const { color, bold } = colorFor(item);
1277
- return wrapText(item, width - prefix.length).map((line, j) => ({
1278
- prefix: j === 0 ? prefix : " ".repeat(prefix.length),
1279
- prefixColor,
1280
- text: line,
1281
- color,
1282
- bold
1283
- }));
1284
- });
1285
- }
1286
- function buildRows(review2, width) {
1287
- const { summaryPoints, nextSteps, reviewPrompt } = review2;
1288
- const numberWidth = String(nextSteps.length).length + 2;
1289
- const rows = [];
1290
- if (summaryPoints.length > 0) {
1291
- rows.push(heading("What we did"));
1292
- rows.push(
1293
- ...itemRows(
1294
- summaryPoints,
1295
- width,
1296
- () => ({ prefix: `${MARKER.done} `, color: COLORS.status.done }),
1297
- () => ({ color: COLORS.primary, bold: false })
1298
- )
1299
- );
1300
- }
1301
- if (nextSteps.length > 0) {
1302
- if (rows.length > 0) rows.push(BLANK);
1303
- rows.push(heading("What to do next"));
1304
- rows.push(
1305
- ...itemRows(
1306
- nextSteps,
1307
- width,
1308
- (i) => ({
1309
- prefix: `${i + 1}.`.padEnd(numberWidth),
1310
- color: COLORS.secondary
1311
- }),
1312
- (step) => step.includes(INGEST_SCRIPT) ? { color: COLORS.brand, bold: true } : { color: COLORS.primary, bold: false }
1313
- )
1314
- );
1315
- }
1316
- if (reviewPrompt) {
1317
- if (rows.length > 0) rows.push(BLANK);
1318
- rows.push(
1319
- ...wrapText(reviewPrompt, width).map((line) => ({
1320
- prefix: "",
1321
- text: line,
1322
- color: COLORS.brand
1323
- }))
1324
- );
1325
- }
1326
- return rows;
1327
- }
1328
- function ReviewPanel({ review: review2 }) {
1329
- const [width, setWidth] = useState8(0);
1330
- const rows = width > 0 ? buildRows(review2, width) : [];
1331
- const scroll = useScrollWindow({ itemCount: rows.length });
1332
- useLayoutEffect3(() => {
1333
- if (scroll.measured) setWidth(scroll.width);
1334
- }, [scroll.measured, scroll.width]);
1335
- const scrollable = scroll.maxOffset > 0;
1336
- useInput4(
1337
- (_input, key) => {
1338
- if (key.upArrow) scroll.scrollBy(-1);
1339
- else if (key.downArrow) scroll.scrollBy(1);
1340
- },
1341
- { isActive: scrollable }
1342
- );
1343
- const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
1344
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", flexGrow: 1, children: [
1345
- /* @__PURE__ */ jsx9(ScrollView, { scroll, children: visible.map((row, i) => /* @__PURE__ */ jsxs10(Text11, { wrap: "truncate", children: [
1346
- row.prefix && /* @__PURE__ */ jsx9(Text11, { color: row.prefixColor ?? row.color, bold: row.bold, children: row.prefix }),
1347
- /* @__PURE__ */ jsx9(Text11, { color: row.color, bold: row.bold, children: row.text })
1348
- ] }, `review-row-${i}`)) }),
1349
- scrollable && /* @__PURE__ */ jsx9(Text11, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
1350
- ] });
1351
- }
1352
- function Review() {
1353
- const review2 = useWizard((s) => s.review);
1354
- if (!review2) return null;
1355
- return /* @__PURE__ */ jsx9(ReviewPanel, { review: review2 });
1356
- }
1357
-
1358
1431
  // src/workflows/default.ts
1359
1432
  import { z as z29 } from "zod";
1360
1433
 
@@ -3905,7 +3978,7 @@ async function runAnalysis(mode, extraInstructions = []) {
3905
3978
  // package.json
3906
3979
  var package_default = {
3907
3980
  name: "@algolia/wizard",
3908
- version: "0.61.0",
3981
+ version: "0.62.0",
3909
3982
  description: "Magically implement Algolia functionality in your codebase",
3910
3983
  type: "module",
3911
3984
  engines: {
@@ -5383,8 +5456,8 @@ function getWorkflow(id) {
5383
5456
  // src/ui/Welcome.tsx
5384
5457
  import { dirname as dirname5, join as join11 } from "node:path";
5385
5458
  import { fileURLToPath as fileURLToPath2 } from "node:url";
5386
- import { useState as useState9 } from "react";
5387
- import { Box as Box11, Spacer, Text as Text12, useInput as useInput5, useWindowSize as useWindowSize5 } from "ink";
5459
+ import { useState as useState10 } from "react";
5460
+ import { Box as Box11, Spacer, Text as Text12, useInput as useInput6, useWindowSize as useWindowSize5 } from "ink";
5388
5461
 
5389
5462
  // src/ui/copy/welcome.ts
5390
5463
  var sidebarItems = [
@@ -5442,8 +5515,8 @@ function Welcome() {
5442
5515
  { label: "start wizard", run: confirmStart },
5443
5516
  { label: "learn more", run: openLearnMore }
5444
5517
  ];
5445
- const [index, setIndex] = useState9(0);
5446
- useInput5((input, key) => {
5518
+ const [index, setIndex] = useState10(0);
5519
+ useInput6((input, key) => {
5447
5520
  if (key.upArrow || input === "k") {
5448
5521
  setIndex((i) => (i - 1 + actions.length) % actions.length);
5449
5522
  } else if (key.downArrow || input === "j") {
@@ -5530,7 +5603,7 @@ function Welcome() {
5530
5603
 
5531
5604
  // src/ui/LearnMore.tsx
5532
5605
  import { Fragment } from "react";
5533
- import { Box as Box12, Text as Text13, useInput as useInput6, useWindowSize as useWindowSize6 } from "ink";
5606
+ import { Box as Box12, Text as Text13, useInput as useInput7, useWindowSize as useWindowSize6 } from "ink";
5534
5607
 
5535
5608
  // src/ui/copy/learn-more.ts
5536
5609
  var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
@@ -5602,7 +5675,7 @@ function LearnMore() {
5602
5675
  const backToHome = useWizard((s) => s.backToHome);
5603
5676
  const { columns } = useWindowSize6();
5604
5677
  const dividerWidth = Math.max(0, columns - PADDING_X * 2);
5605
- useInput6((_input, key) => {
5678
+ useInput7((_input, key) => {
5606
5679
  if (key.escape) backToHome();
5607
5680
  else if (key.return) confirmStart();
5608
5681
  });
@@ -5783,10 +5856,10 @@ function Ribbon() {
5783
5856
  }
5784
5857
 
5785
5858
  // src/ui/App.tsx
5786
- import { useState as useState11 } from "react";
5859
+ import { useState as useState12 } from "react";
5787
5860
 
5788
5861
  // src/ui/Logs.tsx
5789
- import { Box as Box17, Text as Text18, useInput as useInput7 } from "ink";
5862
+ import { Box as Box17, Text as Text18, useInput as useInput8 } from "ink";
5790
5863
  import { jsx as jsx16, jsxs as jsxs17 } from "react/jsx-runtime";
5791
5864
  var KIND_COLOR = {
5792
5865
  tool: COLORS.primary,
@@ -5818,9 +5891,9 @@ function formatTimestamp(ms) {
5818
5891
  function Logs() {
5819
5892
  const logs = useWizard((s) => s.logs);
5820
5893
  const scroll = useScrollWindow({ itemCount: logs.length, followBottom: true });
5821
- useInput7((_input, key) => {
5822
- if (key.upArrow) scroll.scrollBy(-1);
5823
- else if (key.downArrow) scroll.scrollBy(1);
5894
+ useInput8((input, key) => {
5895
+ if (input === "k" || key.upArrow) scroll.scrollBy(-1);
5896
+ else if (input === "j" || key.downArrow) scroll.scrollBy(1);
5824
5897
  });
5825
5898
  const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
5826
5899
  return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
@@ -5842,12 +5915,15 @@ function Logs() {
5842
5915
  durationText && /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: durationText })
5843
5916
  ] }, entry.id);
5844
5917
  }) }),
5845
- /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
5918
+ /* @__PURE__ */ jsxs17(Text18, { children: [
5919
+ /* @__PURE__ */ jsx16(Text18, { color: COLORS.primary, children: "[j] [k]" }),
5920
+ /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: " scroll" })
5921
+ ] })
5846
5922
  ] });
5847
5923
  }
5848
5924
 
5849
5925
  // src/ui/Tips.tsx
5850
- import { useEffect as useEffect3, useRef as useRef4, useState as useState10 } from "react";
5926
+ import { useEffect as useEffect3, useRef as useRef4, useState as useState11 } from "react";
5851
5927
  import { Box as Box19, Text as Text20 } from "ink";
5852
5928
  import terminalLink from "terminal-link";
5853
5929
 
@@ -6164,8 +6240,8 @@ function Tips({
6164
6240
  progress.tipIndex = 0;
6165
6241
  progress.revealed = 0;
6166
6242
  }
6167
- const [tipIndex, setTipIndex] = useState10(resuming ? progress.tipIndex : 0);
6168
- const [revealed, setRevealed] = useState10(resuming ? progress.revealed : 0);
6243
+ const [tipIndex, setTipIndex] = useState11(resuming ? progress.tipIndex : 0);
6244
+ const [revealed, setRevealed] = useState11(resuming ? progress.revealed : 0);
6169
6245
  const tip = tips2.length > 0 ? tips2[tipIndex % tips2.length] : void 0;
6170
6246
  const contentLength = tip?.chunks.reduce((sum, c) => sum + c.value.length, 0) ?? 0;
6171
6247
  const totalLength = (tip?.title.length ?? 0) + contentLength;
@@ -6247,8 +6323,8 @@ function App() {
6247
6323
  } = useWizard();
6248
6324
  const { exit } = useApp();
6249
6325
  const { columns, rows } = useWindowSize7();
6250
- const [showLogs, setShowLogs] = useState11(false);
6251
- const [tipState, setTipState] = useState11("idle");
6326
+ const [showLogs, setShowLogs] = useState12(false);
6327
+ const [tipState, setTipState] = useState12("idle");
6252
6328
  const finished = phase === "done" || phase === "error";
6253
6329
  const currentStep = steps[currentStepIndex];
6254
6330
  const stepDef = workflow ? getWorkflow(workflow.id)?.steps.find((s) => s.id === currentStep?.id) : void 0;
@@ -6261,7 +6337,7 @@ function App() {
6261
6337
  const showTips = stepHasTips && (phase === "running" && currentStep?.status === "running" || isCommandApprovalPrompt || holdForTip);
6262
6338
  const showNoticesInMain = !stepHasTips;
6263
6339
  const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
6264
- useInput8(
6340
+ useInput9(
6265
6341
  (_input, key) => {
6266
6342
  if (key.return) {
6267
6343
  exit();
@@ -6269,7 +6345,7 @@ function App() {
6269
6345
  },
6270
6346
  { isActive: finished }
6271
6347
  );
6272
- useInput8((_input, key) => {
6348
+ useInput9((_input, key) => {
6273
6349
  if (phase === "idle" || phase === "authenticating") return;
6274
6350
  if (key.tab) {
6275
6351
  setShowLogs(!showLogs);
@@ -6281,7 +6357,7 @@ function App() {
6281
6357
  }
6282
6358
  });
6283
6359
  const escOwnedElsewhere = phase === "idle" || phase === "authenticating" || phase === "awaitingInput" && !holdForTip && (inputReq?.promptType === "enterToContinue" || inputReq?.promptType === "commandApproval");
6284
- useInput8((_input, key) => {
6360
+ useInput9((_input, key) => {
6285
6361
  if (escOwnedElsewhere) return;
6286
6362
  if (key.escape) {
6287
6363
  track("AI Wizard Interaction", {
@@ -6744,7 +6820,7 @@ function delay(ms) {
6744
6820
  // package.json with { type: 'json' }
6745
6821
  var package_default2 = {
6746
6822
  name: "@algolia/wizard",
6747
- version: "0.61.0",
6823
+ version: "0.62.0",
6748
6824
  description: "Magically implement Algolia functionality in your codebase",
6749
6825
  type: "module",
6750
6826
  engines: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algolia/wizard",
3
- "version": "0.61.0",
3
+ "version": "0.62.0",
4
4
  "description": "Magically implement Algolia functionality in your codebase",
5
5
  "type": "module",
6
6
  "engines": {