@algolia/wizard 0.61.0 → 0.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +682 -433
- 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
|
|
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
|
|
654
|
+
import { Box as Box10, Text as Text11 } from "ink";
|
|
655
655
|
import Spinner from "ink-spinner";
|
|
656
|
-
import { useState as
|
|
656
|
+
import { useState as useState9 } from "react";
|
|
657
657
|
|
|
658
658
|
// src/ui/CommandApproval.tsx
|
|
659
|
-
import { Box as
|
|
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((
|
|
714
|
-
if (key.upArrow
|
|
715
|
+
useInput((_input, key) => {
|
|
716
|
+
if (key.upArrow) {
|
|
715
717
|
setIndex((i) => (i - 1 + actions.length) % actions.length);
|
|
716
|
-
} else if (key.downArrow
|
|
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/
|
|
748
|
-
import {
|
|
749
|
-
|
|
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
|
|
851
|
-
import { useCallback, useLayoutEffect, useRef as useRef2, useState as
|
|
852
|
-
import { jsxs as
|
|
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] =
|
|
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] =
|
|
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__ */
|
|
924
|
-
scroll.hiddenAbove > 0 && /* @__PURE__ */
|
|
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__ */
|
|
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/
|
|
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] =
|
|
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] =
|
|
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] =
|
|
983
|
-
|
|
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
|
-
|
|
1196
|
+
useLayoutEffect4(() => {
|
|
1009
1197
|
revealIndex(index);
|
|
1010
1198
|
}, [index, revealIndex]);
|
|
1011
1199
|
const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
1012
|
-
|
|
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__ */
|
|
1038
|
-
/* @__PURE__ */
|
|
1039
|
-
error && /* @__PURE__ */
|
|
1040
|
-
messages?.map((m, i) => /* @__PURE__ */
|
|
1041
|
-
table && /* @__PURE__ */
|
|
1042
|
-
/* @__PURE__ */
|
|
1043
|
-
question && /* @__PURE__ */
|
|
1044
|
-
helpText && /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1066
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1082
|
-
/* @__PURE__ */
|
|
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
|
|
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__ */
|
|
1099
|
-
messages?.map((m, i) => /* @__PURE__ */
|
|
1100
|
-
question && /* @__PURE__ */
|
|
1101
|
-
/* @__PURE__ */
|
|
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] =
|
|
1116
|
-
const [submittedReq, setSubmittedReq] =
|
|
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__ */
|
|
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__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
1368
|
+
return /* @__PURE__ */ jsx9(
|
|
1181
1369
|
EnterToContinuePrompt,
|
|
1182
1370
|
{
|
|
1183
1371
|
question: inputReq.prompt,
|
|
@@ -1187,173 +1375,58 @@ function PromptInput() {
|
|
|
1187
1375
|
);
|
|
1188
1376
|
}
|
|
1189
1377
|
if (inputReq.promptType === "commandApproval" && inputReq.command) {
|
|
1190
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
1202
|
-
inputReq.detectedLanguages && /* @__PURE__ */
|
|
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__ */
|
|
1393
|
+
/* @__PURE__ */ jsx9(Text11, { color: COLORS.success, children: inputReq.detectedLanguages })
|
|
1206
1394
|
] }),
|
|
1207
|
-
/* @__PURE__ */
|
|
1208
|
-
SelectPrompt,
|
|
1209
|
-
{
|
|
1210
|
-
question: inputReq.prompt,
|
|
1211
|
-
messages: inputReq.messages,
|
|
1212
|
-
options: labels,
|
|
1213
|
-
secondary: inputReq.secondary,
|
|
1214
|
-
onSelect: (value) => handleSubmit(value === labels[0])
|
|
1215
|
-
},
|
|
1216
|
-
promptKey
|
|
1217
|
-
)
|
|
1218
|
-
] });
|
|
1219
|
-
}
|
|
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: [
|
|
1225
|
-
inputReq.prompt,
|
|
1226
|
-
" "
|
|
1227
|
-
] }),
|
|
1228
|
-
/* @__PURE__ */ jsx8(
|
|
1229
|
-
FreeTextInput,
|
|
1230
|
-
{
|
|
1231
|
-
value: draft,
|
|
1232
|
-
onChange: setDraft,
|
|
1233
|
-
onSubmit: (v) => {
|
|
1234
|
-
submitInput(v);
|
|
1235
|
-
setDraft("");
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
)
|
|
1239
|
-
] })
|
|
1240
|
-
] });
|
|
1241
|
-
}
|
|
1242
|
-
|
|
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 }
|
|
1395
|
+
/* @__PURE__ */ jsx9(
|
|
1396
|
+
SelectPrompt,
|
|
1397
|
+
{
|
|
1398
|
+
question: inputReq.prompt,
|
|
1399
|
+
messages: inputReq.messages,
|
|
1400
|
+
options: labels,
|
|
1401
|
+
secondary: inputReq.secondary,
|
|
1402
|
+
onSelect: (value) => handleSubmit(value === labels[0])
|
|
1403
|
+
},
|
|
1404
|
+
promptKey
|
|
1313
1405
|
)
|
|
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
|
-
);
|
|
1406
|
+
] });
|
|
1325
1407
|
}
|
|
1326
|
-
return
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
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" })
|
|
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: [
|
|
1413
|
+
inputReq.prompt,
|
|
1414
|
+
" "
|
|
1415
|
+
] }),
|
|
1416
|
+
/* @__PURE__ */ jsx9(
|
|
1417
|
+
FreeTextInput,
|
|
1418
|
+
{
|
|
1419
|
+
value: draft,
|
|
1420
|
+
onChange: setDraft,
|
|
1421
|
+
onSubmit: (v) => {
|
|
1422
|
+
submitInput(v);
|
|
1423
|
+
setDraft("");
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
)
|
|
1427
|
+
] })
|
|
1350
1428
|
] });
|
|
1351
1429
|
}
|
|
1352
|
-
function Review() {
|
|
1353
|
-
const review2 = useWizard((s) => s.review);
|
|
1354
|
-
if (!review2) return null;
|
|
1355
|
-
return /* @__PURE__ */ jsx9(ReviewPanel, { review: review2 });
|
|
1356
|
-
}
|
|
1357
1430
|
|
|
1358
1431
|
// src/workflows/default.ts
|
|
1359
1432
|
import { z as z29 } from "zod";
|
|
@@ -1624,23 +1697,137 @@ function trackWorkflowError(ctx) {
|
|
|
1624
1697
|
|
|
1625
1698
|
// src/lib/events.ts
|
|
1626
1699
|
import "zod";
|
|
1627
|
-
|
|
1700
|
+
var analyticsAppId = void 0;
|
|
1701
|
+
var analyticsAgentRunId = void 0;
|
|
1702
|
+
function setAnalyticsContext(next) {
|
|
1703
|
+
analyticsAppId = next.appId;
|
|
1704
|
+
analyticsAgentRunId = next.agentRunId;
|
|
1705
|
+
}
|
|
1706
|
+
function wizardErrorType(actionId, step, error) {
|
|
1707
|
+
if (actionId === "project-scan" || step === "project scan") {
|
|
1708
|
+
return "Scan Codebase";
|
|
1709
|
+
}
|
|
1710
|
+
if (actionId === "ingestion" || step === "Push Data" || step === "ingest records") {
|
|
1711
|
+
return "Ingest Records";
|
|
1712
|
+
}
|
|
1713
|
+
if (actionId === "search" || step === "create search ui") {
|
|
1714
|
+
if (error && error.toLowerCase().includes("verification failed")) {
|
|
1715
|
+
return "Wire Component to UI";
|
|
1716
|
+
}
|
|
1717
|
+
return "Generate UI";
|
|
1718
|
+
}
|
|
1719
|
+
return void 0;
|
|
1720
|
+
}
|
|
1721
|
+
function commonEventProperties() {
|
|
1722
|
+
const properties = {};
|
|
1723
|
+
if (analyticsAppId) properties.app_id = analyticsAppId;
|
|
1724
|
+
if (analyticsAgentRunId) properties.agent_run_id = analyticsAgentRunId;
|
|
1725
|
+
return properties;
|
|
1726
|
+
}
|
|
1727
|
+
function postAnalytics(path, body, label) {
|
|
1628
1728
|
if (isTelemetryOptedOut()) return;
|
|
1629
1729
|
const token = getAuthToken();
|
|
1630
1730
|
if (!token) return;
|
|
1631
1731
|
const userId = useWizard.getState().user?.userId;
|
|
1632
1732
|
if (!userId) return;
|
|
1633
|
-
void proxyFetch(`${PROXY_BASE_URL}
|
|
1733
|
+
void proxyFetch(`${PROXY_BASE_URL}${path}`, {
|
|
1634
1734
|
method: "POST",
|
|
1635
1735
|
headers: {
|
|
1636
1736
|
"content-type": "application/json",
|
|
1637
1737
|
authorization: `Bearer ${token}`
|
|
1638
1738
|
},
|
|
1639
|
-
body: JSON.stringify(
|
|
1739
|
+
body: JSON.stringify(body)
|
|
1640
1740
|
}).catch((err) => {
|
|
1641
|
-
logger.warn({ err, event }, "failed to send analytics event");
|
|
1741
|
+
logger.warn({ err, event: label }, "failed to send analytics event");
|
|
1642
1742
|
});
|
|
1643
1743
|
}
|
|
1744
|
+
function track(event, payload) {
|
|
1745
|
+
postAnalytics(
|
|
1746
|
+
"/events",
|
|
1747
|
+
{
|
|
1748
|
+
userId: useWizard.getState().user?.userId,
|
|
1749
|
+
event,
|
|
1750
|
+
properties: { ...payload, ...commonEventProperties() }
|
|
1751
|
+
},
|
|
1752
|
+
event
|
|
1753
|
+
);
|
|
1754
|
+
}
|
|
1755
|
+
function identify(traits) {
|
|
1756
|
+
const userId = useWizard.getState().user?.userId;
|
|
1757
|
+
postAnalytics("/identify", { userId, traits }, "identify");
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
// package.json
|
|
1761
|
+
var package_default = {
|
|
1762
|
+
name: "@algolia/wizard",
|
|
1763
|
+
version: "0.63.0",
|
|
1764
|
+
description: "Magically implement Algolia functionality in your codebase",
|
|
1765
|
+
type: "module",
|
|
1766
|
+
engines: {
|
|
1767
|
+
node: ">=24"
|
|
1768
|
+
},
|
|
1769
|
+
bin: {
|
|
1770
|
+
wizard: "dist/main.js"
|
|
1771
|
+
},
|
|
1772
|
+
files: [
|
|
1773
|
+
"dist",
|
|
1774
|
+
"docs"
|
|
1775
|
+
],
|
|
1776
|
+
scripts: {
|
|
1777
|
+
"build:proxy": "node scripts/build.mjs proxy",
|
|
1778
|
+
build: "node scripts/build.mjs",
|
|
1779
|
+
"dev:proxy": "touch .env && NODE_OPTIONS=--use-system-ca tsx watch --env-file=.env src/proxy/index.ts",
|
|
1780
|
+
dev: "touch .env && tsx --env-file=.env ./src/main.tsx",
|
|
1781
|
+
"env:load": "pnpm exec -- varlock load",
|
|
1782
|
+
prepare: "husky",
|
|
1783
|
+
prepublishOnly: "pnpm build",
|
|
1784
|
+
reset: "tsx ./scripts/reset-state.ts",
|
|
1785
|
+
"test:fixtures": "touch .env && tsx --env-file=.env ./fixtures/run-fixtures.ts",
|
|
1786
|
+
"test:tools": "tsx ./tool-evals/toolEval.ts",
|
|
1787
|
+
"test:tools:improve": "tsx ./tool-evals/improveFromPlan.ts",
|
|
1788
|
+
test: "vitest",
|
|
1789
|
+
typecheck: "tsc --noEmit -p tsconfig.json"
|
|
1790
|
+
},
|
|
1791
|
+
keywords: [],
|
|
1792
|
+
author: "",
|
|
1793
|
+
license: "ISC",
|
|
1794
|
+
packageManager: "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
|
|
1795
|
+
devDependencies: {
|
|
1796
|
+
"@clack/prompts": "^1.6.0",
|
|
1797
|
+
"@types/ioredis-mock": "^8.2.7",
|
|
1798
|
+
"@types/node": "^25.9.1",
|
|
1799
|
+
"@types/react": "^19.2.16",
|
|
1800
|
+
esbuild: "^0.28.0",
|
|
1801
|
+
husky: "^9.1.7",
|
|
1802
|
+
"ink-testing-library": "^4.0.0",
|
|
1803
|
+
"ioredis-mock": "^8.13.1",
|
|
1804
|
+
"lint-staged": "^17.0.8",
|
|
1805
|
+
tsx: "^4.22.3",
|
|
1806
|
+
typescript: "^6.0.3",
|
|
1807
|
+
vitest: "^4.1.8"
|
|
1808
|
+
},
|
|
1809
|
+
dependencies: {
|
|
1810
|
+
"@ai-sdk/anthropic": "^3.0.81",
|
|
1811
|
+
"@ai-sdk/openai-compatible": "^2.0.47",
|
|
1812
|
+
"@hono/node-server": "^2.0.10",
|
|
1813
|
+
"@segment/analytics-node": "^3.1.0",
|
|
1814
|
+
ai: "^6.0.190",
|
|
1815
|
+
"cross-keychain": "^1.1.0",
|
|
1816
|
+
dotenv: "^17.4.2",
|
|
1817
|
+
hono: "^4.12.27",
|
|
1818
|
+
ink: "^7.0.5",
|
|
1819
|
+
"ink-picture": "^2.1.0",
|
|
1820
|
+
"ink-spinner": "^5.0.0",
|
|
1821
|
+
ioredis: "^5.11.1",
|
|
1822
|
+
nanoid: "^5.1.15",
|
|
1823
|
+
pino: "^10.3.1",
|
|
1824
|
+
react: "^19.2.7",
|
|
1825
|
+
"terminal-link": "^5.0.0",
|
|
1826
|
+
varlock: "^1.5.1",
|
|
1827
|
+
zod: "^4.4.3",
|
|
1828
|
+
zustand: "^5.0.14"
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1644
1831
|
|
|
1645
1832
|
// src/core/orchestrator.ts
|
|
1646
1833
|
function defineStep(step) {
|
|
@@ -1693,9 +1880,37 @@ function initWorkflowState(workflow, now, appId) {
|
|
|
1693
1880
|
status: "pending"
|
|
1694
1881
|
})),
|
|
1695
1882
|
algoliaState: appId ? { appId } : {},
|
|
1696
|
-
userInputs: {}
|
|
1883
|
+
userInputs: {},
|
|
1884
|
+
agentRunId: crypto.randomUUID()
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1887
|
+
function ensureAgentRunId(state) {
|
|
1888
|
+
if (!state.agentRunId) state.agentRunId = crypto.randomUUID();
|
|
1889
|
+
}
|
|
1890
|
+
function completeEventProperties(state, totalDurationMs, stepCount) {
|
|
1891
|
+
const indexName = state.steps.find((s) => s.id === "select-index")?.output?.selection;
|
|
1892
|
+
const framework = state.steps.find((s) => s.id === "confirm-framework")?.output?.frameworks?.[0]?.name;
|
|
1893
|
+
return {
|
|
1894
|
+
total_duration_ms: totalDurationMs,
|
|
1895
|
+
duration_ms: totalDurationMs,
|
|
1896
|
+
step_count: stepCount,
|
|
1897
|
+
index_name: indexName ?? "unknown",
|
|
1898
|
+
framework: framework ?? "unknown"
|
|
1697
1899
|
};
|
|
1698
1900
|
}
|
|
1901
|
+
function errorCodeFrom(err) {
|
|
1902
|
+
let current = err;
|
|
1903
|
+
for (let i = 0; i < 4 && current; i++) {
|
|
1904
|
+
if (current && typeof current === "object" && "statusCode" in current) {
|
|
1905
|
+
const code = current.statusCode;
|
|
1906
|
+
if (typeof code === "number" || typeof code === "string") {
|
|
1907
|
+
return String(code);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
current = current instanceof Error ? current.cause : void 0;
|
|
1911
|
+
}
|
|
1912
|
+
return void 0;
|
|
1913
|
+
}
|
|
1699
1914
|
async function ensureConsent() {
|
|
1700
1915
|
const config = await loadConfig();
|
|
1701
1916
|
if (config.aiConsent) return;
|
|
@@ -1808,6 +2023,8 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1808
2023
|
try {
|
|
1809
2024
|
const state = await resolveWorkflowState(workflow, appId, options);
|
|
1810
2025
|
ensureExecutedStepCount(state);
|
|
2026
|
+
ensureAgentRunId(state);
|
|
2027
|
+
setAnalyticsContext({ appId, agentRunId: state.agentRunId });
|
|
1811
2028
|
store.startWorkflow(
|
|
1812
2029
|
{
|
|
1813
2030
|
id: workflow.id,
|
|
@@ -1818,6 +2035,11 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1818
2035
|
);
|
|
1819
2036
|
await ensureConsent();
|
|
1820
2037
|
trackWorkflowStart({ workflowId: workflow.id, appId });
|
|
2038
|
+
track("AI Wizard Started", {
|
|
2039
|
+
version: package_default.version,
|
|
2040
|
+
wizard_version: package_default.version,
|
|
2041
|
+
os: process.platform
|
|
2042
|
+
});
|
|
1821
2043
|
for (let i = state.currentStepIndex; i < workflow.steps.length; i++) {
|
|
1822
2044
|
await runStep(state, i, workflow.steps[i], appId);
|
|
1823
2045
|
}
|
|
@@ -1829,10 +2051,11 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1829
2051
|
total_duration: Math.round(totalDurationMs / 1e3),
|
|
1830
2052
|
total_steps: stepCount
|
|
1831
2053
|
});
|
|
1832
|
-
track(
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
2054
|
+
track(
|
|
2055
|
+
"AI Wizard Completed",
|
|
2056
|
+
completeEventProperties(state, totalDurationMs, stepCount)
|
|
2057
|
+
);
|
|
2058
|
+
identify({ is_Wizard_user: true });
|
|
1836
2059
|
await recordWorkflowRun(workflow.id, nowIso());
|
|
1837
2060
|
await clearWorkflowState(workflow.id);
|
|
1838
2061
|
store.setDone();
|
|
@@ -1873,10 +2096,15 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1873
2096
|
actionId: failedActionId,
|
|
1874
2097
|
cause: err
|
|
1875
2098
|
});
|
|
2099
|
+
const errorType = wizardErrorType(failedActionId, step, message);
|
|
2100
|
+
const errorCode2 = errorCodeFrom(err);
|
|
1876
2101
|
track("Error", {
|
|
1877
2102
|
step,
|
|
1878
2103
|
error: message,
|
|
1879
|
-
|
|
2104
|
+
error_message: message,
|
|
2105
|
+
product_area: "AI Wizard",
|
|
2106
|
+
...errorType ? { error_type: errorType } : {},
|
|
2107
|
+
...errorCode2 ? { error_code: errorCode2 } : {}
|
|
1880
2108
|
});
|
|
1881
2109
|
store.setError(message);
|
|
1882
2110
|
}
|
|
@@ -3456,7 +3684,7 @@ function generateRecordTool(ctx, createModel = defaultCreateModel2) {
|
|
|
3456
3684
|
try {
|
|
3457
3685
|
const anthropic = createModel();
|
|
3458
3686
|
const value = z17.union([z17.string(), z17.number(), z17.boolean(), z17.null()]);
|
|
3459
|
-
const
|
|
3687
|
+
const recordSchema2 = z17.object(
|
|
3460
3688
|
Object.fromEntries(attributes.map((attr) => [attr, value]))
|
|
3461
3689
|
);
|
|
3462
3690
|
const generateBatch = async (batchCount) => {
|
|
@@ -3467,7 +3695,7 @@ function generateRecordTool(ctx, createModel = defaultCreateModel2) {
|
|
|
3467
3695
|
model: anthropic(RECORD_MODEL),
|
|
3468
3696
|
output: Output2.object({
|
|
3469
3697
|
schema: z17.object({
|
|
3470
|
-
records: z17.array(
|
|
3698
|
+
records: z17.array(recordSchema2).length(batchCount)
|
|
3471
3699
|
})
|
|
3472
3700
|
}),
|
|
3473
3701
|
prompt: [
|
|
@@ -3902,78 +4130,6 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3902
4130
|
return Object.assign({}, ...results);
|
|
3903
4131
|
}
|
|
3904
4132
|
|
|
3905
|
-
// package.json
|
|
3906
|
-
var package_default = {
|
|
3907
|
-
name: "@algolia/wizard",
|
|
3908
|
-
version: "0.61.0",
|
|
3909
|
-
description: "Magically implement Algolia functionality in your codebase",
|
|
3910
|
-
type: "module",
|
|
3911
|
-
engines: {
|
|
3912
|
-
node: ">=24"
|
|
3913
|
-
},
|
|
3914
|
-
bin: {
|
|
3915
|
-
wizard: "dist/main.js"
|
|
3916
|
-
},
|
|
3917
|
-
files: [
|
|
3918
|
-
"dist",
|
|
3919
|
-
"docs"
|
|
3920
|
-
],
|
|
3921
|
-
scripts: {
|
|
3922
|
-
"build:proxy": "node scripts/build.mjs proxy",
|
|
3923
|
-
build: "node scripts/build.mjs",
|
|
3924
|
-
"dev:proxy": "touch .env && NODE_OPTIONS=--use-system-ca tsx watch --env-file=.env src/proxy/index.ts",
|
|
3925
|
-
dev: "touch .env && tsx --env-file=.env ./src/main.tsx",
|
|
3926
|
-
"env:load": "pnpm exec -- varlock load",
|
|
3927
|
-
prepare: "husky",
|
|
3928
|
-
prepublishOnly: "pnpm build",
|
|
3929
|
-
reset: "tsx ./scripts/reset-state.ts",
|
|
3930
|
-
"test:fixtures": "touch .env && tsx --env-file=.env ./fixtures/run-fixtures.ts",
|
|
3931
|
-
"test:tools": "tsx ./tool-evals/toolEval.ts",
|
|
3932
|
-
"test:tools:improve": "tsx ./tool-evals/improveFromPlan.ts",
|
|
3933
|
-
test: "vitest",
|
|
3934
|
-
typecheck: "tsc --noEmit -p tsconfig.json"
|
|
3935
|
-
},
|
|
3936
|
-
keywords: [],
|
|
3937
|
-
author: "",
|
|
3938
|
-
license: "ISC",
|
|
3939
|
-
packageManager: "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
|
|
3940
|
-
devDependencies: {
|
|
3941
|
-
"@clack/prompts": "^1.6.0",
|
|
3942
|
-
"@types/ioredis-mock": "^8.2.7",
|
|
3943
|
-
"@types/node": "^25.9.1",
|
|
3944
|
-
"@types/react": "^19.2.16",
|
|
3945
|
-
esbuild: "^0.28.0",
|
|
3946
|
-
husky: "^9.1.7",
|
|
3947
|
-
"ink-testing-library": "^4.0.0",
|
|
3948
|
-
"ioredis-mock": "^8.13.1",
|
|
3949
|
-
"lint-staged": "^17.0.8",
|
|
3950
|
-
tsx: "^4.22.3",
|
|
3951
|
-
typescript: "^6.0.3",
|
|
3952
|
-
vitest: "^4.1.8"
|
|
3953
|
-
},
|
|
3954
|
-
dependencies: {
|
|
3955
|
-
"@ai-sdk/anthropic": "^3.0.81",
|
|
3956
|
-
"@ai-sdk/openai-compatible": "^2.0.47",
|
|
3957
|
-
"@hono/node-server": "^2.0.10",
|
|
3958
|
-
"@segment/analytics-node": "^3.1.0",
|
|
3959
|
-
ai: "^6.0.190",
|
|
3960
|
-
"cross-keychain": "^1.1.0",
|
|
3961
|
-
dotenv: "^17.4.2",
|
|
3962
|
-
hono: "^4.12.27",
|
|
3963
|
-
ink: "^7.0.5",
|
|
3964
|
-
"ink-picture": "^2.1.0",
|
|
3965
|
-
"ink-spinner": "^5.0.0",
|
|
3966
|
-
ioredis: "^5.11.1",
|
|
3967
|
-
nanoid: "^5.1.15",
|
|
3968
|
-
pino: "^10.3.1",
|
|
3969
|
-
react: "^19.2.7",
|
|
3970
|
-
"terminal-link": "^5.0.0",
|
|
3971
|
-
varlock: "^1.5.1",
|
|
3972
|
-
zod: "^4.4.3",
|
|
3973
|
-
zustand: "^5.0.14"
|
|
3974
|
-
}
|
|
3975
|
-
};
|
|
3976
|
-
|
|
3977
4133
|
// src/actions/projectScan.ts
|
|
3978
4134
|
import "zod";
|
|
3979
4135
|
var projectScanSchema = detectLanguageSchema.extend({
|
|
@@ -3982,16 +4138,19 @@ var projectScanSchema = detectLanguageSchema.extend({
|
|
|
3982
4138
|
verification: analyzeCodebaseSchema.shape.verification
|
|
3983
4139
|
});
|
|
3984
4140
|
async function projectScan(ctx) {
|
|
4141
|
+
const startedAt = Date.now();
|
|
3985
4142
|
const [detected, analyses] = await Promise.all([
|
|
3986
4143
|
detectLanguage(),
|
|
3987
4144
|
runAnalysis()
|
|
3988
4145
|
]);
|
|
3989
|
-
|
|
3990
|
-
wizard_version: package_default.version,
|
|
3991
|
-
os: process.platform
|
|
3992
|
-
});
|
|
4146
|
+
const entities = toEntitySummary(analyses.ingestionAnalysis ?? []);
|
|
3993
4147
|
track("AI Wizard Scan Completed", {
|
|
3994
|
-
|
|
4148
|
+
languages: detected.languages,
|
|
4149
|
+
frameworks: detected.frameworks,
|
|
4150
|
+
data_models_found: entities.map((entity) => entity.name),
|
|
4151
|
+
back_end_language_detected: detected.languages[0]?.name ?? null,
|
|
4152
|
+
front_end_framework_detected: detected.frameworks[0]?.name ?? null,
|
|
4153
|
+
duration_ms: Date.now() - startedAt
|
|
3995
4154
|
});
|
|
3996
4155
|
for (const [key, value] of Object.entries(analyses)) {
|
|
3997
4156
|
ctx.setUserInput(key, value);
|
|
@@ -4089,7 +4248,7 @@ var isSameFramework = (a, b) => {
|
|
|
4089
4248
|
};
|
|
4090
4249
|
function confirmed(name, version) {
|
|
4091
4250
|
const frameworks = [{ name, version: version ?? "unknown" }];
|
|
4092
|
-
track("AI Wizard Frontend Framework Confirmed", { frameworks });
|
|
4251
|
+
track("AI Wizard Frontend Framework Confirmed", { frameworks, framework: name });
|
|
4093
4252
|
return { frameworks };
|
|
4094
4253
|
}
|
|
4095
4254
|
async function askOtherFramework(ctx) {
|
|
@@ -4193,6 +4352,11 @@ var confirmEntitiesSchema = z26.object({
|
|
|
4193
4352
|
confirmedEntities: confirmedEntitiesFieldSchema
|
|
4194
4353
|
});
|
|
4195
4354
|
var SUGGEST_ENTITY = "Suggest a different entity\u2026";
|
|
4355
|
+
function usedDetectedBackend(detected, confirmed2) {
|
|
4356
|
+
if (!detected?.length || !confirmed2?.length) return false;
|
|
4357
|
+
const detectedNames = new Set(detected.map((entry) => entry.name.toLowerCase()));
|
|
4358
|
+
return confirmed2.every((entry) => detectedNames.has(entry.name.toLowerCase()));
|
|
4359
|
+
}
|
|
4196
4360
|
async function askEntityName(ctx, opts) {
|
|
4197
4361
|
const blankHint = opts?.blankHint ?? "cancel";
|
|
4198
4362
|
const declared = await promptUser(ctx, {
|
|
@@ -4299,8 +4463,14 @@ async function confirmEntities(ctx) {
|
|
|
4299
4463
|
throw new Error("User cancelled entity selection \u2014 analysis halted.");
|
|
4300
4464
|
}
|
|
4301
4465
|
ctx.setUserInput("confirmedEntities", confirmed2);
|
|
4302
|
-
|
|
4303
|
-
|
|
4466
|
+
const languages = ctx.getStepOutput(
|
|
4467
|
+
"confirm-language"
|
|
4468
|
+
)?.languages;
|
|
4469
|
+
const summary = toEntitySummary(confirmed2);
|
|
4470
|
+
track("AI Wizard Data Model Confirmed", {
|
|
4471
|
+
data_model: summary[0]?.name ?? "unknown",
|
|
4472
|
+
attribute_count: summary[0]?.attributes.length ?? 0,
|
|
4473
|
+
used_detected_back_end: usedDetectedBackend(scan.languages, languages)
|
|
4304
4474
|
});
|
|
4305
4475
|
return { ingestionAnalysis: entities, confirmedEntities: confirmed2 };
|
|
4306
4476
|
}
|
|
@@ -4350,7 +4520,7 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
|
|
|
4350
4520
|
|
|
4351
4521
|
// src/actions/implement.ts
|
|
4352
4522
|
import z28 from "zod";
|
|
4353
|
-
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
4523
|
+
import { mkdir as mkdir5, readFile as readFile8 } from "node:fs/promises";
|
|
4354
4524
|
import { join as join10, relative as relative6 } from "node:path";
|
|
4355
4525
|
|
|
4356
4526
|
// src/lib/git.ts
|
|
@@ -4739,6 +4909,50 @@ function outputTail(output) {
|
|
|
4739
4909
|
if (!trimmed) return void 0;
|
|
4740
4910
|
return trimmed.length > INGEST_OUTPUT_TAIL_CHARS ? `\u2026${trimmed.slice(-INGEST_OUTPUT_TAIL_CHARS)}` : trimmed;
|
|
4741
4911
|
}
|
|
4912
|
+
function jsTypeName(value) {
|
|
4913
|
+
if (value === null) return "null";
|
|
4914
|
+
if (Array.isArray(value)) return "array";
|
|
4915
|
+
const type = typeof value;
|
|
4916
|
+
if (type === "string" || type === "number" || type === "boolean" || type === "object") {
|
|
4917
|
+
return type;
|
|
4918
|
+
}
|
|
4919
|
+
return "unknown";
|
|
4920
|
+
}
|
|
4921
|
+
async function firstRecordIn(filePath) {
|
|
4922
|
+
try {
|
|
4923
|
+
const parsed = JSON.parse(await readFile8(filePath, "utf8"));
|
|
4924
|
+
const first = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
4925
|
+
if (first && typeof first === "object" && !Array.isArray(first)) {
|
|
4926
|
+
return first;
|
|
4927
|
+
}
|
|
4928
|
+
} catch {
|
|
4929
|
+
return void 0;
|
|
4930
|
+
}
|
|
4931
|
+
return void 0;
|
|
4932
|
+
}
|
|
4933
|
+
async function ingestedRecordSample(repoRoot, entityName, uploadFilePath) {
|
|
4934
|
+
const candidates = [];
|
|
4935
|
+
if (entityName) {
|
|
4936
|
+
const slug = entityName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
4937
|
+
candidates.push(join10(repoRoot, INGEST_DIR, "data", `${slug}.json`));
|
|
4938
|
+
}
|
|
4939
|
+
if (uploadFilePath?.toLowerCase().endsWith(".json")) {
|
|
4940
|
+
candidates.push(join10(repoRoot, uploadFilePath));
|
|
4941
|
+
}
|
|
4942
|
+
for (const candidate of candidates) {
|
|
4943
|
+
const sample = await firstRecordIn(candidate);
|
|
4944
|
+
if (sample) return sample;
|
|
4945
|
+
}
|
|
4946
|
+
return void 0;
|
|
4947
|
+
}
|
|
4948
|
+
function recordSchema(sample, attributes) {
|
|
4949
|
+
if (sample) {
|
|
4950
|
+
return Object.fromEntries(
|
|
4951
|
+
Object.entries(sample).map(([key, value]) => [key, jsTypeName(value)])
|
|
4952
|
+
);
|
|
4953
|
+
}
|
|
4954
|
+
return Object.fromEntries(attributes.map((key) => [key, "unknown"]));
|
|
4955
|
+
}
|
|
4742
4956
|
function ingestFailure(attempt, executions) {
|
|
4743
4957
|
if (!attempt) {
|
|
4744
4958
|
return {
|
|
@@ -4968,11 +5182,24 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
4968
5182
|
if (ingestScriptRan) {
|
|
4969
5183
|
ingestOutcomeMessage = `\u2705 Ingestion succeeded${ingestRecordCount != null ? ` \u2014 ${ingestRecordCount} record(s) indexed.` : "."}`;
|
|
4970
5184
|
if (ingestRecordCount != null) {
|
|
5185
|
+
const data_model = confirmed2?.[0]?.name ?? "unknown";
|
|
5186
|
+
const sample = await ingestedRecordSample(
|
|
5187
|
+
repoRoot,
|
|
5188
|
+
confirmed2?.[0]?.name,
|
|
5189
|
+
uploadFilePath
|
|
5190
|
+
);
|
|
4971
5191
|
track("AI Wizard Ingest Successful", {
|
|
4972
|
-
|
|
5192
|
+
data_model,
|
|
4973
5193
|
record_count: ingestRecordCount,
|
|
4974
|
-
duration_ms: ingestDurationMs ?? 0
|
|
5194
|
+
duration_ms: ingestDurationMs ?? 0,
|
|
5195
|
+
index_name: targetIndex,
|
|
5196
|
+
record_schema: recordSchema(sample, confirmed2?.[0]?.attributes ?? [])
|
|
4975
5197
|
});
|
|
5198
|
+
} else {
|
|
5199
|
+
logger.warn(
|
|
5200
|
+
{ ingestCommand },
|
|
5201
|
+
"implement: ingestion ran but printed no record count; skipping Ingest Successful event"
|
|
5202
|
+
);
|
|
4976
5203
|
}
|
|
4977
5204
|
} else {
|
|
4978
5205
|
const { reason, detail } = ingestFailure(ingestAttempt, executions);
|
|
@@ -4996,7 +5223,10 @@ ${detail}` : ""}`
|
|
|
4996
5223
|
track("Error", {
|
|
4997
5224
|
step: "Push Data",
|
|
4998
5225
|
error: `ingestion did not complete: ${reason}`,
|
|
4999
|
-
|
|
5226
|
+
error_message: `ingestion did not complete: ${reason}`,
|
|
5227
|
+
error_type: "Ingest Records",
|
|
5228
|
+
product_area: "AI Wizard",
|
|
5229
|
+
...ingestAttempt?.exitCode != null ? { error_code: String(ingestAttempt.exitCode) } : {}
|
|
5000
5230
|
});
|
|
5001
5231
|
}
|
|
5002
5232
|
if (ingestScriptRan) {
|
|
@@ -5030,6 +5260,29 @@ ${detail}` : ""}`
|
|
|
5030
5260
|
let searchConfigFile;
|
|
5031
5261
|
if (useCases.includes("search")) {
|
|
5032
5262
|
let extraInstructions = [];
|
|
5263
|
+
const confirmedFrameworks = language.frameworks ?? [];
|
|
5264
|
+
const detectedFrameworks = scan.frameworks ?? [];
|
|
5265
|
+
const framework = confirmedFrameworks[0]?.name ?? "unknown";
|
|
5266
|
+
const used_detected_framework = confirmedFrameworks.some(
|
|
5267
|
+
(confirmedFw) => detectedFrameworks.some(
|
|
5268
|
+
(detectedFw) => isSameFramework(confirmedFw.name, detectedFw.name)
|
|
5269
|
+
)
|
|
5270
|
+
);
|
|
5271
|
+
const searchStartedAt = Date.now();
|
|
5272
|
+
const trackComponentGenerated = (mounted_successfully, attempts) => {
|
|
5273
|
+
const searchFilesChanged = [
|
|
5274
|
+
...new Set(useWizard.getState().writtenFiles)
|
|
5275
|
+
].map((file) => relative6(repoRoot, file));
|
|
5276
|
+
track("AI Wizard Frontend Component Generated", {
|
|
5277
|
+
file_paths: searchFilesChanged,
|
|
5278
|
+
framework,
|
|
5279
|
+
duration_ms: Date.now() - searchStartedAt,
|
|
5280
|
+
used_detected_framework,
|
|
5281
|
+
mounted_successfully,
|
|
5282
|
+
location_heuristic: searchLocation ?? "unknown",
|
|
5283
|
+
attempts
|
|
5284
|
+
});
|
|
5285
|
+
};
|
|
5033
5286
|
useWizard.getState().clearWrittenFiles();
|
|
5034
5287
|
for (let attempt = 1; attempt <= MAX_IMPLEMENT_VERIFICATION_ATTEMPTS; attempt++) {
|
|
5035
5288
|
if (attempt > 1) {
|
|
@@ -5054,19 +5307,12 @@ ${detail}` : ""}`
|
|
|
5054
5307
|
summaries.push(formatSummary("verification", verification.summary));
|
|
5055
5308
|
if (verification.sufficient) {
|
|
5056
5309
|
ctx.setUserInput("implementation", "success");
|
|
5057
|
-
|
|
5058
|
-
...new Set(useWizard.getState().writtenFiles)
|
|
5059
|
-
].map((file) => relative6(repoRoot, file));
|
|
5060
|
-
track("AI Wizard Frontend Component Generated", {
|
|
5061
|
-
filePaths: searchFilesChanged
|
|
5062
|
-
});
|
|
5063
|
-
track("AI Wizard Wired to UI", {
|
|
5064
|
-
location_heuristic: searchLocation ?? "unknown"
|
|
5065
|
-
});
|
|
5310
|
+
trackComponentGenerated(true, attempt);
|
|
5066
5311
|
break;
|
|
5067
5312
|
}
|
|
5068
5313
|
if (attempt === MAX_IMPLEMENT_VERIFICATION_ATTEMPTS) {
|
|
5069
5314
|
ctx.setUserInput("implementation", "fail");
|
|
5315
|
+
trackComponentGenerated(false, attempt);
|
|
5070
5316
|
throw new Error(
|
|
5071
5317
|
`Implementation verification failed after ${MAX_IMPLEMENT_VERIFICATION_ATTEMPTS} attempts: ${verification.additionalInstructions ?? verification.summary}`
|
|
5072
5318
|
);
|
|
@@ -5383,8 +5629,8 @@ function getWorkflow(id) {
|
|
|
5383
5629
|
// src/ui/Welcome.tsx
|
|
5384
5630
|
import { dirname as dirname5, join as join11 } from "node:path";
|
|
5385
5631
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5386
|
-
import { useState as
|
|
5387
|
-
import { Box as Box11, Spacer, Text as Text12, useInput as
|
|
5632
|
+
import { useState as useState10 } from "react";
|
|
5633
|
+
import { Box as Box11, Spacer, Text as Text12, useInput as useInput6, useWindowSize as useWindowSize5 } from "ink";
|
|
5388
5634
|
|
|
5389
5635
|
// src/ui/copy/welcome.ts
|
|
5390
5636
|
var sidebarItems = [
|
|
@@ -5442,8 +5688,8 @@ function Welcome() {
|
|
|
5442
5688
|
{ label: "start wizard", run: confirmStart },
|
|
5443
5689
|
{ label: "learn more", run: openLearnMore }
|
|
5444
5690
|
];
|
|
5445
|
-
const [index, setIndex] =
|
|
5446
|
-
|
|
5691
|
+
const [index, setIndex] = useState10(0);
|
|
5692
|
+
useInput6((input, key) => {
|
|
5447
5693
|
if (key.upArrow || input === "k") {
|
|
5448
5694
|
setIndex((i) => (i - 1 + actions.length) % actions.length);
|
|
5449
5695
|
} else if (key.downArrow || input === "j") {
|
|
@@ -5530,7 +5776,7 @@ function Welcome() {
|
|
|
5530
5776
|
|
|
5531
5777
|
// src/ui/LearnMore.tsx
|
|
5532
5778
|
import { Fragment } from "react";
|
|
5533
|
-
import { Box as Box12, Text as Text13, useInput as
|
|
5779
|
+
import { Box as Box12, Text as Text13, useInput as useInput7, useWindowSize as useWindowSize6 } from "ink";
|
|
5534
5780
|
|
|
5535
5781
|
// src/ui/copy/learn-more.ts
|
|
5536
5782
|
var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
|
|
@@ -5602,7 +5848,7 @@ function LearnMore() {
|
|
|
5602
5848
|
const backToHome = useWizard((s) => s.backToHome);
|
|
5603
5849
|
const { columns } = useWindowSize6();
|
|
5604
5850
|
const dividerWidth = Math.max(0, columns - PADDING_X * 2);
|
|
5605
|
-
|
|
5851
|
+
useInput7((_input, key) => {
|
|
5606
5852
|
if (key.escape) backToHome();
|
|
5607
5853
|
else if (key.return) confirmStart();
|
|
5608
5854
|
});
|
|
@@ -5783,10 +6029,10 @@ function Ribbon() {
|
|
|
5783
6029
|
}
|
|
5784
6030
|
|
|
5785
6031
|
// src/ui/App.tsx
|
|
5786
|
-
import { useState as
|
|
6032
|
+
import { useState as useState12 } from "react";
|
|
5787
6033
|
|
|
5788
6034
|
// src/ui/Logs.tsx
|
|
5789
|
-
import { Box as Box17, Text as Text18, useInput as
|
|
6035
|
+
import { Box as Box17, Text as Text18, useInput as useInput8 } from "ink";
|
|
5790
6036
|
import { jsx as jsx16, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5791
6037
|
var KIND_COLOR = {
|
|
5792
6038
|
tool: COLORS.primary,
|
|
@@ -5818,9 +6064,9 @@ function formatTimestamp(ms) {
|
|
|
5818
6064
|
function Logs() {
|
|
5819
6065
|
const logs = useWizard((s) => s.logs);
|
|
5820
6066
|
const scroll = useScrollWindow({ itemCount: logs.length, followBottom: true });
|
|
5821
|
-
|
|
5822
|
-
if (key.upArrow) scroll.scrollBy(-1);
|
|
5823
|
-
else if (key.downArrow) scroll.scrollBy(1);
|
|
6067
|
+
useInput8((input, key) => {
|
|
6068
|
+
if (input === "k" || key.upArrow) scroll.scrollBy(-1);
|
|
6069
|
+
else if (input === "j" || key.downArrow) scroll.scrollBy(1);
|
|
5824
6070
|
});
|
|
5825
6071
|
const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
5826
6072
|
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
|
|
@@ -5842,12 +6088,15 @@ function Logs() {
|
|
|
5842
6088
|
durationText && /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: durationText })
|
|
5843
6089
|
] }, entry.id);
|
|
5844
6090
|
}) }),
|
|
5845
|
-
/* @__PURE__ */
|
|
6091
|
+
/* @__PURE__ */ jsxs17(Text18, { children: [
|
|
6092
|
+
/* @__PURE__ */ jsx16(Text18, { color: COLORS.primary, children: "[j] [k]" }),
|
|
6093
|
+
/* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: " scroll" })
|
|
6094
|
+
] })
|
|
5846
6095
|
] });
|
|
5847
6096
|
}
|
|
5848
6097
|
|
|
5849
6098
|
// src/ui/Tips.tsx
|
|
5850
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as
|
|
6099
|
+
import { useEffect as useEffect3, useRef as useRef4, useState as useState11 } from "react";
|
|
5851
6100
|
import { Box as Box19, Text as Text20 } from "ink";
|
|
5852
6101
|
import terminalLink from "terminal-link";
|
|
5853
6102
|
|
|
@@ -6164,8 +6413,8 @@ function Tips({
|
|
|
6164
6413
|
progress.tipIndex = 0;
|
|
6165
6414
|
progress.revealed = 0;
|
|
6166
6415
|
}
|
|
6167
|
-
const [tipIndex, setTipIndex] =
|
|
6168
|
-
const [revealed, setRevealed] =
|
|
6416
|
+
const [tipIndex, setTipIndex] = useState11(resuming ? progress.tipIndex : 0);
|
|
6417
|
+
const [revealed, setRevealed] = useState11(resuming ? progress.revealed : 0);
|
|
6169
6418
|
const tip = tips2.length > 0 ? tips2[tipIndex % tips2.length] : void 0;
|
|
6170
6419
|
const contentLength = tip?.chunks.reduce((sum, c) => sum + c.value.length, 0) ?? 0;
|
|
6171
6420
|
const totalLength = (tip?.title.length ?? 0) + contentLength;
|
|
@@ -6247,8 +6496,8 @@ function App() {
|
|
|
6247
6496
|
} = useWizard();
|
|
6248
6497
|
const { exit } = useApp();
|
|
6249
6498
|
const { columns, rows } = useWindowSize7();
|
|
6250
|
-
const [showLogs, setShowLogs] =
|
|
6251
|
-
const [tipState, setTipState] =
|
|
6499
|
+
const [showLogs, setShowLogs] = useState12(false);
|
|
6500
|
+
const [tipState, setTipState] = useState12("idle");
|
|
6252
6501
|
const finished = phase === "done" || phase === "error";
|
|
6253
6502
|
const currentStep = steps[currentStepIndex];
|
|
6254
6503
|
const stepDef = workflow ? getWorkflow(workflow.id)?.steps.find((s) => s.id === currentStep?.id) : void 0;
|
|
@@ -6261,7 +6510,7 @@ function App() {
|
|
|
6261
6510
|
const showTips = stepHasTips && (phase === "running" && currentStep?.status === "running" || isCommandApprovalPrompt || holdForTip);
|
|
6262
6511
|
const showNoticesInMain = !stepHasTips;
|
|
6263
6512
|
const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
|
|
6264
|
-
|
|
6513
|
+
useInput9(
|
|
6265
6514
|
(_input, key) => {
|
|
6266
6515
|
if (key.return) {
|
|
6267
6516
|
exit();
|
|
@@ -6269,7 +6518,7 @@ function App() {
|
|
|
6269
6518
|
},
|
|
6270
6519
|
{ isActive: finished }
|
|
6271
6520
|
);
|
|
6272
|
-
|
|
6521
|
+
useInput9((_input, key) => {
|
|
6273
6522
|
if (phase === "idle" || phase === "authenticating") return;
|
|
6274
6523
|
if (key.tab) {
|
|
6275
6524
|
setShowLogs(!showLogs);
|
|
@@ -6281,7 +6530,7 @@ function App() {
|
|
|
6281
6530
|
}
|
|
6282
6531
|
});
|
|
6283
6532
|
const escOwnedElsewhere = phase === "idle" || phase === "authenticating" || phase === "awaitingInput" && !holdForTip && (inputReq?.promptType === "enterToContinue" || inputReq?.promptType === "commandApproval");
|
|
6284
|
-
|
|
6533
|
+
useInput9((_input, key) => {
|
|
6285
6534
|
if (escOwnedElsewhere) return;
|
|
6286
6535
|
if (key.escape) {
|
|
6287
6536
|
track("AI Wizard Interaction", {
|
|
@@ -6383,7 +6632,7 @@ function App() {
|
|
|
6383
6632
|
}
|
|
6384
6633
|
|
|
6385
6634
|
// src/lib/envAppId.ts
|
|
6386
|
-
import { readFile as
|
|
6635
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
6387
6636
|
import { join as join12 } from "node:path";
|
|
6388
6637
|
var ENV_FILES = [".env", ".env.local"];
|
|
6389
6638
|
var APP_ID_LINE = /^[ \t]*(?:export[ \t]+)?([A-Z0-9_]*ALGOLIA_APP(?:LICATION)?_ID)[ \t]*=[ \t]*(.*)$/gm;
|
|
@@ -6391,7 +6640,7 @@ async function findEnvApplicationId(root = process.cwd()) {
|
|
|
6391
6640
|
for (const file of ENV_FILES) {
|
|
6392
6641
|
let content;
|
|
6393
6642
|
try {
|
|
6394
|
-
content = await
|
|
6643
|
+
content = await readFile9(join12(root, file), "utf8");
|
|
6395
6644
|
} catch (err) {
|
|
6396
6645
|
if (err.code !== "ENOENT") {
|
|
6397
6646
|
logger.warn(
|
|
@@ -6744,7 +6993,7 @@ function delay(ms) {
|
|
|
6744
6993
|
// package.json with { type: 'json' }
|
|
6745
6994
|
var package_default2 = {
|
|
6746
6995
|
name: "@algolia/wizard",
|
|
6747
|
-
version: "0.
|
|
6996
|
+
version: "0.63.0",
|
|
6748
6997
|
description: "Magically implement Algolia functionality in your codebase",
|
|
6749
6998
|
type: "module",
|
|
6750
6999
|
engines: {
|