@algolia/wizard 0.12.0-rc.104.151 → 0.12.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 +513 -287
- 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
|
|
7
|
+
import { Box as Box16, Text as Text16, useApp, useInput as useInput7, useWindowSize as useWindowSize8 } from "ink";
|
|
8
8
|
|
|
9
9
|
// src/core/store.ts
|
|
10
10
|
import { create } from "zustand";
|
|
@@ -304,7 +304,10 @@ var useWizard = create((set, get) => ({
|
|
|
304
304
|
if (_noticeTimer === null) {
|
|
305
305
|
set({
|
|
306
306
|
notices: [...notices, notice],
|
|
307
|
-
_noticeTimer: setTimeout(
|
|
307
|
+
_noticeTimer: setTimeout(
|
|
308
|
+
() => get()._drainNoticeQueue(),
|
|
309
|
+
NOTICE_INTERVAL_MS
|
|
310
|
+
)
|
|
308
311
|
});
|
|
309
312
|
} else {
|
|
310
313
|
set({ _noticeQueue: [..._noticeQueue, notice] });
|
|
@@ -316,7 +319,10 @@ var useWizard = create((set, get) => ({
|
|
|
316
319
|
set((s) => ({
|
|
317
320
|
notices: [...s.notices, next],
|
|
318
321
|
_noticeQueue: rest,
|
|
319
|
-
_noticeTimer: setTimeout(
|
|
322
|
+
_noticeTimer: setTimeout(
|
|
323
|
+
() => get()._drainNoticeQueue(),
|
|
324
|
+
NOTICE_INTERVAL_MS
|
|
325
|
+
)
|
|
320
326
|
}));
|
|
321
327
|
} else {
|
|
322
328
|
set({ _noticeTimer: null });
|
|
@@ -364,13 +370,17 @@ var useWizard = create((set, get) => ({
|
|
|
364
370
|
await markInteraction();
|
|
365
371
|
get()._resolve?.(value);
|
|
366
372
|
set({ inputReq: null, _resolve: null, phase: "running" });
|
|
367
|
-
const id = get().logStart(
|
|
373
|
+
const id = get().logStart(
|
|
374
|
+
"prompt",
|
|
375
|
+
`User input: ${describeInputValue(value)}`
|
|
376
|
+
);
|
|
368
377
|
get().logEnd(id, "success");
|
|
369
378
|
},
|
|
370
379
|
setDone: () => set({ phase: "done" }),
|
|
371
380
|
setError: (message) => set({ phase: "error", error: message }),
|
|
372
381
|
reset: () => {
|
|
373
382
|
get()._clearNoticeQueue();
|
|
383
|
+
get()._resolve?.(false);
|
|
374
384
|
set({
|
|
375
385
|
phase: "idle",
|
|
376
386
|
homeScreen: "home",
|
|
@@ -622,10 +632,13 @@ function Notices() {
|
|
|
622
632
|
}
|
|
623
633
|
|
|
624
634
|
// src/ui/PromptInput.tsx
|
|
625
|
-
import { Box as
|
|
635
|
+
import { Box as Box8, Text as Text8, useInput as useInput3 } from "ink";
|
|
626
636
|
import TextInput from "ink-text-input";
|
|
627
637
|
import { useState as useState5 } from "react";
|
|
628
638
|
|
|
639
|
+
// src/ui/CommandApproval.tsx
|
|
640
|
+
import { Box as Box5, Text as Text5, useInput } from "ink";
|
|
641
|
+
|
|
629
642
|
// src/ui/NextAction.tsx
|
|
630
643
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
631
644
|
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -649,14 +662,60 @@ function NextAction({
|
|
|
649
662
|
] });
|
|
650
663
|
}
|
|
651
664
|
|
|
665
|
+
// src/ui/CommandApproval.tsx
|
|
666
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
667
|
+
function CommandApproval({
|
|
668
|
+
command,
|
|
669
|
+
onDecide
|
|
670
|
+
}) {
|
|
671
|
+
useInput((_input, key) => {
|
|
672
|
+
if (key.return) onDecide("approve");
|
|
673
|
+
else if (key.escape) onDecide("reject");
|
|
674
|
+
});
|
|
675
|
+
return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", gap: 1, children: [
|
|
676
|
+
/* @__PURE__ */ jsx4(Text5, { color: COLORS.primary, bold: true, children: "Run this command?" }),
|
|
677
|
+
/* @__PURE__ */ jsxs4(
|
|
678
|
+
Box5,
|
|
679
|
+
{
|
|
680
|
+
flexDirection: "column",
|
|
681
|
+
paddingLeft: 2,
|
|
682
|
+
borderStyle: "single",
|
|
683
|
+
borderColor: COLORS.success,
|
|
684
|
+
borderTop: false,
|
|
685
|
+
borderBottom: false,
|
|
686
|
+
borderRight: false,
|
|
687
|
+
gap: 1,
|
|
688
|
+
children: [
|
|
689
|
+
/* @__PURE__ */ jsxs4(Box5, { children: [
|
|
690
|
+
/* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, children: "$ " }),
|
|
691
|
+
/* @__PURE__ */ jsx4(Text5, { color: COLORS.strong, wrap: "wrap", children: command.command })
|
|
692
|
+
] }),
|
|
693
|
+
/* @__PURE__ */ jsxs4(Box5, { gap: 1, children: [
|
|
694
|
+
/* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, children: "in:" }),
|
|
695
|
+
/* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, wrap: "wrap", children: command.cwd })
|
|
696
|
+
] }),
|
|
697
|
+
command.explanation && /* @__PURE__ */ jsxs4(Box5, { gap: 1, children: [
|
|
698
|
+
/* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, children: "why:" }),
|
|
699
|
+
/* @__PURE__ */ jsx4(Text5, { color: COLORS.accent, wrap: "wrap", children: command.explanation })
|
|
700
|
+
] })
|
|
701
|
+
]
|
|
702
|
+
}
|
|
703
|
+
),
|
|
704
|
+
/* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
|
|
705
|
+
/* @__PURE__ */ jsx4(NextAction, { action: "approve", keyHint: "enter" }),
|
|
706
|
+
/* @__PURE__ */ jsx4(NextAction, { action: "reject", keyHint: "esc", hierarchy: "secondary" })
|
|
707
|
+
] })
|
|
708
|
+
] });
|
|
709
|
+
}
|
|
710
|
+
|
|
652
711
|
// src/ui/SelectPrompt.tsx
|
|
653
|
-
import { Box as
|
|
712
|
+
import { Box as Box7, Text as Text7, useInput as useInput2, useWindowSize as useWindowSize5 } from "ink";
|
|
654
713
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState4 } from "react";
|
|
655
714
|
|
|
656
715
|
// src/ui/ScrollView.tsx
|
|
657
|
-
import { Box as
|
|
716
|
+
import { Box as Box6, Text as Text6, measureElement as measureElement2, useWindowSize as useWindowSize4 } from "ink";
|
|
658
717
|
import { useCallback, useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
|
|
659
|
-
import { jsxs as
|
|
718
|
+
import { jsxs as jsxs5 } from "react/jsx-runtime";
|
|
660
719
|
var INDICATOR_ROWS = 2;
|
|
661
720
|
function fittedWidth(node, columns) {
|
|
662
721
|
let left = 0;
|
|
@@ -726,14 +785,14 @@ function useScrollWindow({
|
|
|
726
785
|
};
|
|
727
786
|
}
|
|
728
787
|
function ScrollView({ scroll, children }) {
|
|
729
|
-
return /* @__PURE__ */
|
|
730
|
-
scroll.hiddenAbove > 0 && /* @__PURE__ */
|
|
788
|
+
return /* @__PURE__ */ jsxs5(Box6, { ref: scroll.viewportRef, flexDirection: "column", flexGrow: 1, children: [
|
|
789
|
+
scroll.hiddenAbove > 0 && /* @__PURE__ */ jsxs5(Text6, { color: COLORS.dim, children: [
|
|
731
790
|
"\u2191 ",
|
|
732
791
|
scroll.hiddenAbove,
|
|
733
792
|
" more"
|
|
734
793
|
] }),
|
|
735
794
|
children,
|
|
736
|
-
scroll.hiddenBelow > 0 && /* @__PURE__ */
|
|
795
|
+
scroll.hiddenBelow > 0 && /* @__PURE__ */ jsxs5(Text6, { color: COLORS.dim, children: [
|
|
737
796
|
"\u2193 ",
|
|
738
797
|
scroll.hiddenBelow,
|
|
739
798
|
" more"
|
|
@@ -742,7 +801,7 @@ function ScrollView({ scroll, children }) {
|
|
|
742
801
|
}
|
|
743
802
|
|
|
744
803
|
// src/ui/SelectPrompt.tsx
|
|
745
|
-
import { jsx as
|
|
804
|
+
import { jsx as jsx5, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
746
805
|
var CANCEL = "cancel";
|
|
747
806
|
var ARROW_WIDTH = 4;
|
|
748
807
|
var COLUMN_GAP = 2;
|
|
@@ -804,7 +863,7 @@ function SelectPrompt({
|
|
|
804
863
|
revealIndex(index);
|
|
805
864
|
}, [index, revealIndex]);
|
|
806
865
|
const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
807
|
-
|
|
866
|
+
useInput2((input, key) => {
|
|
808
867
|
if (rows.length === 0) return;
|
|
809
868
|
if (key.upArrow || input === "k") {
|
|
810
869
|
setIndex((i) => (i - 1 + rows.length) % rows.length);
|
|
@@ -827,56 +886,56 @@ function SelectPrompt({
|
|
|
827
886
|
}
|
|
828
887
|
}
|
|
829
888
|
});
|
|
830
|
-
return /* @__PURE__ */
|
|
831
|
-
/* @__PURE__ */
|
|
832
|
-
error && /* @__PURE__ */
|
|
833
|
-
messages?.map((m, i) => /* @__PURE__ */
|
|
834
|
-
table && /* @__PURE__ */
|
|
835
|
-
/* @__PURE__ */
|
|
836
|
-
question && /* @__PURE__ */
|
|
837
|
-
helpText && /* @__PURE__ */
|
|
889
|
+
return /* @__PURE__ */ jsx5(Box7, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", gap: 1, width, children: [
|
|
890
|
+
/* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", gap: 1, flexShrink: 0, children: [
|
|
891
|
+
error && /* @__PURE__ */ jsx5(Text7, { color: COLORS.danger, children: error }),
|
|
892
|
+
messages?.map((m, i) => /* @__PURE__ */ jsx5(Text7, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
893
|
+
table && /* @__PURE__ */ jsx5(Table, { columns: table.columns, rows: table.rows }),
|
|
894
|
+
/* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
|
|
895
|
+
question && /* @__PURE__ */ jsx5(Text7, { color: COLORS.muted, children: question }),
|
|
896
|
+
helpText && /* @__PURE__ */ jsx5(Text7, { color: COLORS.dim, children: helpText })
|
|
838
897
|
] })
|
|
839
898
|
] }),
|
|
840
|
-
/* @__PURE__ */
|
|
899
|
+
/* @__PURE__ */ jsx5(ScrollView, { scroll, children: visible.map((option, visibleIndex) => {
|
|
841
900
|
const i = scroll.offset + visibleIndex;
|
|
842
901
|
const highlighted = i === index;
|
|
843
902
|
const isCancel = i === cancelIndex;
|
|
844
903
|
const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
|
|
845
904
|
const sec = isCancel ? void 0 : secondary?.[i];
|
|
846
905
|
const labelColor = highlighted ? COLORS.highlight.fg : void 0;
|
|
847
|
-
const label = /* @__PURE__ */
|
|
906
|
+
const label = /* @__PURE__ */ jsxs6(Text7, { color: labelColor, wrap: "truncate", children: [
|
|
848
907
|
highlighted ? "\u276F " : " ",
|
|
849
908
|
bullet,
|
|
850
909
|
option
|
|
851
910
|
] });
|
|
852
911
|
const isText = sec?.kind === "text";
|
|
853
|
-
return /* @__PURE__ */
|
|
854
|
-
|
|
912
|
+
return /* @__PURE__ */ jsxs6(
|
|
913
|
+
Box7,
|
|
855
914
|
{
|
|
856
915
|
width: isText ? "100%" : barWidth,
|
|
857
916
|
paddingX: 1,
|
|
858
917
|
paddingY: 1,
|
|
859
918
|
backgroundColor: highlighted ? COLORS.highlight.bg : void 0,
|
|
860
919
|
children: [
|
|
861
|
-
/* @__PURE__ */
|
|
862
|
-
isText && textWidth > 0 && /* @__PURE__ */
|
|
863
|
-
|
|
920
|
+
/* @__PURE__ */ jsx5(Box7, { width: isText ? labelWidth : barLabelWidth, children: label }),
|
|
921
|
+
isText && textWidth > 0 && /* @__PURE__ */ jsx5(Box7, { width: textWidth, children: /* @__PURE__ */ jsx5(
|
|
922
|
+
Text7,
|
|
864
923
|
{
|
|
865
924
|
wrap: "truncate",
|
|
866
925
|
color: highlighted ? COLORS.primary : COLORS.muted,
|
|
867
926
|
children: sec.value
|
|
868
927
|
}
|
|
869
928
|
) }),
|
|
870
|
-
sec?.kind === "badge" && /* @__PURE__ */
|
|
929
|
+
sec?.kind === "badge" && /* @__PURE__ */ jsx5(Box7, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx5(Text7, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
|
|
871
930
|
]
|
|
872
931
|
},
|
|
873
932
|
`row-${i}`
|
|
874
933
|
);
|
|
875
934
|
}) }),
|
|
876
|
-
/* @__PURE__ */
|
|
935
|
+
/* @__PURE__ */ jsx5(Box7, { flexShrink: 0, children: /* @__PURE__ */ jsx5(Text7, { children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs6(Text7, { children: [
|
|
877
936
|
i > 0 ? " " : "",
|
|
878
|
-
/* @__PURE__ */
|
|
879
|
-
/* @__PURE__ */
|
|
937
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.primary, children: key }),
|
|
938
|
+
/* @__PURE__ */ jsxs6(Text7, { color: COLORS.dim, children: [
|
|
880
939
|
" ",
|
|
881
940
|
label
|
|
882
941
|
] })
|
|
@@ -885,23 +944,23 @@ function SelectPrompt({
|
|
|
885
944
|
}
|
|
886
945
|
|
|
887
946
|
// src/ui/PromptInput.tsx
|
|
888
|
-
import { jsx as
|
|
947
|
+
import { jsx as jsx6, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
889
948
|
var ACCEPT_REJECT_OPTIONS = ["Accept", "Reject"];
|
|
890
949
|
function EnterToContinuePrompt({
|
|
891
950
|
question,
|
|
892
951
|
messages,
|
|
893
952
|
onDecide
|
|
894
953
|
}) {
|
|
895
|
-
|
|
954
|
+
useInput3((_input, key) => {
|
|
896
955
|
if (key.return) onDecide(true);
|
|
897
956
|
else if (key.escape) onDecide(false);
|
|
898
957
|
});
|
|
899
|
-
return /* @__PURE__ */
|
|
900
|
-
messages?.map((m, i) => /* @__PURE__ */
|
|
901
|
-
question && /* @__PURE__ */
|
|
902
|
-
/* @__PURE__ */
|
|
903
|
-
/* @__PURE__ */
|
|
904
|
-
/* @__PURE__ */
|
|
958
|
+
return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", gap: 1, children: [
|
|
959
|
+
messages?.map((m, i) => /* @__PURE__ */ jsx6(Text8, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
960
|
+
question && /* @__PURE__ */ jsx6(Text8, { color: COLORS.primary, children: question }),
|
|
961
|
+
/* @__PURE__ */ jsxs7(Box8, { gap: 1, flexDirection: "column", children: [
|
|
962
|
+
/* @__PURE__ */ jsx6(NextAction, { action: "continue", keyHint: "enter" }),
|
|
963
|
+
/* @__PURE__ */ jsx6(NextAction, { action: "decline", keyHint: "esc", hierarchy: "secondary" })
|
|
905
964
|
] })
|
|
906
965
|
] });
|
|
907
966
|
}
|
|
@@ -909,11 +968,11 @@ function PromptInput() {
|
|
|
909
968
|
const { phase, inputReq, submitInput } = useWizard();
|
|
910
969
|
const [draft, setDraft] = useState5("");
|
|
911
970
|
if (phase === "done" || phase === "error") {
|
|
912
|
-
return /* @__PURE__ */
|
|
971
|
+
return /* @__PURE__ */ jsx6(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text8, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
|
|
913
972
|
}
|
|
914
973
|
if (phase !== "awaitingInput" || !inputReq) return null;
|
|
915
974
|
if (inputReq.promptType === "multipleChoice") {
|
|
916
|
-
return /* @__PURE__ */
|
|
975
|
+
return /* @__PURE__ */ jsx6(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx6(
|
|
917
976
|
SelectPrompt,
|
|
918
977
|
{
|
|
919
978
|
question: inputReq.prompt,
|
|
@@ -930,7 +989,7 @@ function PromptInput() {
|
|
|
930
989
|
) });
|
|
931
990
|
}
|
|
932
991
|
if (inputReq.promptType === "multiSelect") {
|
|
933
|
-
return /* @__PURE__ */
|
|
992
|
+
return /* @__PURE__ */ jsx6(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx6(
|
|
934
993
|
SelectPrompt,
|
|
935
994
|
{
|
|
936
995
|
multi: true,
|
|
@@ -945,7 +1004,7 @@ function PromptInput() {
|
|
|
945
1004
|
) });
|
|
946
1005
|
}
|
|
947
1006
|
if (inputReq.promptType === "notice") {
|
|
948
|
-
return /* @__PURE__ */
|
|
1007
|
+
return /* @__PURE__ */ jsx6(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx6(
|
|
949
1008
|
SelectPrompt,
|
|
950
1009
|
{
|
|
951
1010
|
question: inputReq.prompt,
|
|
@@ -956,7 +1015,7 @@ function PromptInput() {
|
|
|
956
1015
|
) });
|
|
957
1016
|
}
|
|
958
1017
|
if (inputReq.promptType === "enterToContinue") {
|
|
959
|
-
return /* @__PURE__ */
|
|
1018
|
+
return /* @__PURE__ */ jsx6(
|
|
960
1019
|
EnterToContinuePrompt,
|
|
961
1020
|
{
|
|
962
1021
|
question: inputReq.prompt,
|
|
@@ -965,9 +1024,12 @@ function PromptInput() {
|
|
|
965
1024
|
}
|
|
966
1025
|
);
|
|
967
1026
|
}
|
|
1027
|
+
if (inputReq.promptType === "commandApproval" && inputReq.command) {
|
|
1028
|
+
return /* @__PURE__ */ jsx6(CommandApproval, { command: inputReq.command, onDecide: submitInput });
|
|
1029
|
+
}
|
|
968
1030
|
if (inputReq.promptType === "acceptReject") {
|
|
969
1031
|
const labels = inputReq.options?.length ? inputReq.options : ACCEPT_REJECT_OPTIONS;
|
|
970
|
-
return /* @__PURE__ */
|
|
1032
|
+
return /* @__PURE__ */ jsx6(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx6(
|
|
971
1033
|
SelectPrompt,
|
|
972
1034
|
{
|
|
973
1035
|
question: inputReq.prompt,
|
|
@@ -978,15 +1040,15 @@ function PromptInput() {
|
|
|
978
1040
|
}
|
|
979
1041
|
) });
|
|
980
1042
|
}
|
|
981
|
-
return /* @__PURE__ */
|
|
982
|
-
inputReq.error && /* @__PURE__ */
|
|
983
|
-
inputReq.messages?.map((m, i) => /* @__PURE__ */
|
|
984
|
-
/* @__PURE__ */
|
|
985
|
-
/* @__PURE__ */
|
|
1043
|
+
return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", children: [
|
|
1044
|
+
inputReq.error && /* @__PURE__ */ jsx6(Text8, { color: COLORS.danger, children: inputReq.error }),
|
|
1045
|
+
inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx6(Text8, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
1046
|
+
/* @__PURE__ */ jsxs7(Box8, { children: [
|
|
1047
|
+
/* @__PURE__ */ jsxs7(Text8, { color: COLORS.primary, children: [
|
|
986
1048
|
inputReq.prompt,
|
|
987
1049
|
" "
|
|
988
1050
|
] }),
|
|
989
|
-
/* @__PURE__ */
|
|
1051
|
+
/* @__PURE__ */ jsx6(
|
|
990
1052
|
TextInput,
|
|
991
1053
|
{
|
|
992
1054
|
value: draft,
|
|
@@ -1004,7 +1066,7 @@ function PromptInput() {
|
|
|
1004
1066
|
// src/ui/Welcome.tsx
|
|
1005
1067
|
import { dirname as dirname2, join as join3 } from "node:path";
|
|
1006
1068
|
import { fileURLToPath } from "node:url";
|
|
1007
|
-
import { Box as
|
|
1069
|
+
import { Box as Box9, Spacer, Text as Text9, useInput as useInput4, useWindowSize as useWindowSize6 } from "ink";
|
|
1008
1070
|
|
|
1009
1071
|
// src/ui/copy/welcome.ts
|
|
1010
1072
|
var sidebarItems = [
|
|
@@ -1031,26 +1093,21 @@ var sidebarItems = [
|
|
|
1031
1093
|
];
|
|
1032
1094
|
|
|
1033
1095
|
// src/ui/Welcome.tsx
|
|
1034
|
-
import Image, {
|
|
1035
|
-
import { jsx as
|
|
1096
|
+
import Image, { InkPictureProvider } from "ink-picture";
|
|
1097
|
+
import { jsx as jsx7, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1036
1098
|
var IMAGE_PATH = join3(dirname2(fileURLToPath(import.meta.url)), "algolia.png");
|
|
1037
|
-
var TERMINAL_INFO = {
|
|
1038
|
-
...defaultTerminalInfo,
|
|
1039
|
-
supportsUnicode: true,
|
|
1040
|
-
supportsColor: true
|
|
1041
|
-
};
|
|
1042
1099
|
function SidebarItem({
|
|
1043
1100
|
title,
|
|
1044
1101
|
description
|
|
1045
1102
|
}) {
|
|
1046
|
-
return /* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1103
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", children: [
|
|
1104
|
+
/* @__PURE__ */ jsxs8(Box9, { gap: 1, children: [
|
|
1105
|
+
/* @__PURE__ */ jsx7(Text9, { color: COLORS.success, children: "\u2192" }),
|
|
1106
|
+
/* @__PURE__ */ jsx7(Text9, { color: COLORS.strong, bold: true, children: title })
|
|
1050
1107
|
] }),
|
|
1051
|
-
/* @__PURE__ */
|
|
1052
|
-
/* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1108
|
+
/* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", gap: 2, children: [
|
|
1109
|
+
/* @__PURE__ */ jsx7(Spacer, {}),
|
|
1110
|
+
/* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: description })
|
|
1054
1111
|
] })
|
|
1055
1112
|
] });
|
|
1056
1113
|
}
|
|
@@ -1058,7 +1115,7 @@ function Welcome() {
|
|
|
1058
1115
|
const confirmStart = useWizard((s) => s.confirmStart);
|
|
1059
1116
|
const openLearnMore = useWizard((s) => s.openLearnMore);
|
|
1060
1117
|
const { rows } = useWindowSize6();
|
|
1061
|
-
|
|
1118
|
+
useInput4((input, key) => {
|
|
1062
1119
|
if (key.return) confirmStart();
|
|
1063
1120
|
else if (input === "i") openLearnMore();
|
|
1064
1121
|
});
|
|
@@ -1076,16 +1133,16 @@ function Welcome() {
|
|
|
1076
1133
|
if (rows < 30) {
|
|
1077
1134
|
layout = scales["small"];
|
|
1078
1135
|
}
|
|
1079
|
-
return /* @__PURE__ */
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
|
|
1136
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
|
|
1137
|
+
/* @__PURE__ */ jsx7(
|
|
1138
|
+
Box9,
|
|
1082
1139
|
{
|
|
1083
1140
|
paddingY: layout.main.padding.y,
|
|
1084
1141
|
paddingX: layout.main.padding.x,
|
|
1085
1142
|
flexDirection: "column",
|
|
1086
1143
|
justifyContent: "center",
|
|
1087
|
-
children: /* @__PURE__ */
|
|
1088
|
-
/* @__PURE__ */
|
|
1144
|
+
children: /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", gap: 2, children: [
|
|
1145
|
+
/* @__PURE__ */ jsx7(InkPictureProvider, { children: /* @__PURE__ */ jsx7(
|
|
1089
1146
|
Image,
|
|
1090
1147
|
{
|
|
1091
1148
|
src: IMAGE_PATH,
|
|
@@ -1096,16 +1153,16 @@ function Welcome() {
|
|
|
1096
1153
|
protocol: "halfBlock"
|
|
1097
1154
|
}
|
|
1098
1155
|
) }),
|
|
1099
|
-
/* @__PURE__ */
|
|
1100
|
-
/* @__PURE__ */
|
|
1101
|
-
/* @__PURE__ */
|
|
1102
|
-
/* @__PURE__ */
|
|
1156
|
+
/* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
|
|
1157
|
+
/* @__PURE__ */ jsxs8(Box9, { gap: 1, flexDirection: "column", children: [
|
|
1158
|
+
/* @__PURE__ */ jsx7(NextAction, { action: "start wizard", keyHint: "enter" }),
|
|
1159
|
+
/* @__PURE__ */ jsx7(NextAction, { action: "learn more", keyHint: "i", hierarchy: "secondary" })
|
|
1103
1160
|
] })
|
|
1104
1161
|
] })
|
|
1105
1162
|
}
|
|
1106
1163
|
),
|
|
1107
|
-
/* @__PURE__ */
|
|
1108
|
-
|
|
1164
|
+
/* @__PURE__ */ jsxs8(
|
|
1165
|
+
Box9,
|
|
1109
1166
|
{
|
|
1110
1167
|
backgroundColor: COLORS.bg.sidebar,
|
|
1111
1168
|
width: 40,
|
|
@@ -1115,8 +1172,8 @@ function Welcome() {
|
|
|
1115
1172
|
flexDirection: "column",
|
|
1116
1173
|
justifyContent: "center",
|
|
1117
1174
|
children: [
|
|
1118
|
-
/* @__PURE__ */
|
|
1119
|
-
sidebarItems.map((i, idx) => /* @__PURE__ */
|
|
1175
|
+
/* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
|
|
1176
|
+
sidebarItems.map((i, idx) => /* @__PURE__ */ jsx7(SidebarItem, { title: i.title, description: i.description }, idx))
|
|
1120
1177
|
]
|
|
1121
1178
|
}
|
|
1122
1179
|
)
|
|
@@ -1125,7 +1182,7 @@ function Welcome() {
|
|
|
1125
1182
|
|
|
1126
1183
|
// src/ui/LearnMore.tsx
|
|
1127
1184
|
import { Fragment as Fragment2 } from "react";
|
|
1128
|
-
import { Box as
|
|
1185
|
+
import { Box as Box10, Text as Text10, useInput as useInput5, useWindowSize as useWindowSize7 } from "ink";
|
|
1129
1186
|
|
|
1130
1187
|
// src/ui/copy/learn-more.ts
|
|
1131
1188
|
var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
|
|
@@ -1133,12 +1190,17 @@ var accessItems = [
|
|
|
1133
1190
|
{
|
|
1134
1191
|
tag: "READ",
|
|
1135
1192
|
title: "Project files",
|
|
1136
|
-
description: "reads
|
|
1193
|
+
description: "reads manifests, configs & source to detect your stack. Read-only; nothing is uploaded."
|
|
1137
1194
|
},
|
|
1138
1195
|
{
|
|
1139
1196
|
tag: "WRITE",
|
|
1140
1197
|
title: "Code changes",
|
|
1141
|
-
description: "creates & edits files (search UI, config)
|
|
1198
|
+
description: "creates & edits files (search UI, config) in a throwaway git worktree \u2014 your checkout is never touched."
|
|
1199
|
+
},
|
|
1200
|
+
{
|
|
1201
|
+
tag: "EXEC",
|
|
1202
|
+
title: "Setup commands",
|
|
1203
|
+
description: "runs dependency installs, the ingestion script & your own checks. Every command is shown in full and needs your OK; its output is shown as-is, so a command that prints a secret will display it."
|
|
1142
1204
|
},
|
|
1143
1205
|
{
|
|
1144
1206
|
tag: "NET",
|
|
@@ -1148,13 +1210,13 @@ var accessItems = [
|
|
|
1148
1210
|
{
|
|
1149
1211
|
tag: "KEY",
|
|
1150
1212
|
title: "Credentials",
|
|
1151
|
-
description: "
|
|
1213
|
+
description: "writes your Algolia app id and a search-only key (safe to expose) to .env in the worktree."
|
|
1152
1214
|
}
|
|
1153
1215
|
];
|
|
1154
1216
|
var neverItems = [
|
|
1155
1217
|
"Send your source code to a model or third party",
|
|
1156
1218
|
"Commit or push to git",
|
|
1157
|
-
"
|
|
1219
|
+
"Run a command you haven't approved"
|
|
1158
1220
|
];
|
|
1159
1221
|
var policyLinks = [
|
|
1160
1222
|
{ label: "Terms", url: "https://www.algolia.com/policies/terms" },
|
|
@@ -1162,10 +1224,11 @@ var policyLinks = [
|
|
|
1162
1224
|
];
|
|
1163
1225
|
|
|
1164
1226
|
// src/ui/LearnMore.tsx
|
|
1165
|
-
import { jsx as
|
|
1227
|
+
import { jsx as jsx8, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1166
1228
|
var TAG_COLORS = {
|
|
1167
1229
|
READ: COLORS.success,
|
|
1168
1230
|
WRITE: COLORS.badge,
|
|
1231
|
+
EXEC: COLORS.danger,
|
|
1169
1232
|
NET: COLORS.accent,
|
|
1170
1233
|
KEY: COLORS.muted
|
|
1171
1234
|
};
|
|
@@ -1178,12 +1241,12 @@ function NeverLine({
|
|
|
1178
1241
|
}) {
|
|
1179
1242
|
const used = segments.reduce((n, s) => n + s.text.length, 0);
|
|
1180
1243
|
const rightPad = Math.max(0, width - 2 - NEVER_BOX_PAD_X - used);
|
|
1181
|
-
return /* @__PURE__ */
|
|
1182
|
-
/* @__PURE__ */
|
|
1244
|
+
return /* @__PURE__ */ jsxs9(Text10, { children: [
|
|
1245
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.danger, children: "\u2502" }),
|
|
1183
1246
|
" ".repeat(NEVER_BOX_PAD_X),
|
|
1184
|
-
segments.map((s, i) => /* @__PURE__ */
|
|
1247
|
+
segments.map((s, i) => /* @__PURE__ */ jsx8(Text10, { color: s.color, bold: s.bold, children: s.text }, i)),
|
|
1185
1248
|
" ".repeat(rightPad),
|
|
1186
|
-
/* @__PURE__ */
|
|
1249
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.danger, children: "\u2502" })
|
|
1187
1250
|
] });
|
|
1188
1251
|
}
|
|
1189
1252
|
function LearnMore() {
|
|
@@ -1191,12 +1254,12 @@ function LearnMore() {
|
|
|
1191
1254
|
const backToHome = useWizard((s) => s.backToHome);
|
|
1192
1255
|
const { columns } = useWindowSize7();
|
|
1193
1256
|
const dividerWidth = Math.max(0, columns - PADDING_X * 2);
|
|
1194
|
-
|
|
1257
|
+
useInput5((_input, key) => {
|
|
1195
1258
|
if (key.escape) backToHome();
|
|
1196
1259
|
else if (key.return) confirmStart();
|
|
1197
1260
|
});
|
|
1198
|
-
return /* @__PURE__ */
|
|
1199
|
-
|
|
1261
|
+
return /* @__PURE__ */ jsxs9(
|
|
1262
|
+
Box10,
|
|
1200
1263
|
{
|
|
1201
1264
|
flexDirection: "column",
|
|
1202
1265
|
paddingX: PADDING_X,
|
|
@@ -1204,31 +1267,31 @@ function LearnMore() {
|
|
|
1204
1267
|
width: "100%",
|
|
1205
1268
|
gap: 1,
|
|
1206
1269
|
children: [
|
|
1207
|
-
/* @__PURE__ */
|
|
1208
|
-
/* @__PURE__ */
|
|
1209
|
-
/* @__PURE__ */
|
|
1210
|
-
/* @__PURE__ */
|
|
1211
|
-
/* @__PURE__ */
|
|
1212
|
-
/* @__PURE__ */
|
|
1213
|
-
/* @__PURE__ */
|
|
1214
|
-
/* @__PURE__ */
|
|
1215
|
-
/* @__PURE__ */
|
|
1270
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
|
|
1271
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: accessIntro }),
|
|
1272
|
+
/* @__PURE__ */ jsx8(Box10, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", marginTop: 1, children: [
|
|
1273
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
|
|
1274
|
+
/* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, marginTop: 1, children: [
|
|
1275
|
+
/* @__PURE__ */ jsx8(Box10, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx8(Text10, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
|
|
1276
|
+
/* @__PURE__ */ jsx8(Box10, { flexDirection: "column", children: /* @__PURE__ */ jsxs9(Text10, { children: [
|
|
1277
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.strong, bold: true, children: item.title }),
|
|
1278
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
|
|
1216
1279
|
] }) })
|
|
1217
1280
|
] })
|
|
1218
1281
|
] }, item.tag)) }),
|
|
1219
|
-
/* @__PURE__ */
|
|
1220
|
-
/* @__PURE__ */
|
|
1221
|
-
/* @__PURE__ */
|
|
1222
|
-
/* @__PURE__ */
|
|
1282
|
+
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
1283
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
|
|
1284
|
+
/* @__PURE__ */ jsx8(NeverLine, { width: dividerWidth }),
|
|
1285
|
+
/* @__PURE__ */ jsx8(
|
|
1223
1286
|
NeverLine,
|
|
1224
1287
|
{
|
|
1225
1288
|
width: dividerWidth,
|
|
1226
1289
|
segments: [{ text: "I NEVER", color: COLORS.danger, bold: true }]
|
|
1227
1290
|
}
|
|
1228
1291
|
),
|
|
1229
|
-
neverItems.map((item) => /* @__PURE__ */
|
|
1230
|
-
/* @__PURE__ */
|
|
1231
|
-
/* @__PURE__ */
|
|
1292
|
+
neverItems.map((item) => /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
1293
|
+
/* @__PURE__ */ jsx8(NeverLine, { width: dividerWidth }),
|
|
1294
|
+
/* @__PURE__ */ jsx8(
|
|
1232
1295
|
NeverLine,
|
|
1233
1296
|
{
|
|
1234
1297
|
width: dividerWidth,
|
|
@@ -1240,24 +1303,24 @@ function LearnMore() {
|
|
|
1240
1303
|
}
|
|
1241
1304
|
)
|
|
1242
1305
|
] }, item)),
|
|
1243
|
-
/* @__PURE__ */
|
|
1244
|
-
/* @__PURE__ */
|
|
1306
|
+
/* @__PURE__ */ jsx8(NeverLine, { width: dividerWidth }),
|
|
1307
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
|
|
1245
1308
|
] }),
|
|
1246
|
-
/* @__PURE__ */
|
|
1247
|
-
/* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1309
|
+
/* @__PURE__ */ jsx8(Box10, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, children: [
|
|
1310
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
|
|
1311
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.accent, children: link.url })
|
|
1249
1312
|
] }, link.label)) }),
|
|
1250
|
-
/* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1253
|
-
/* @__PURE__ */
|
|
1254
|
-
/* @__PURE__ */
|
|
1313
|
+
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexDirection: "row", gap: 3, children: [
|
|
1314
|
+
/* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, children: [
|
|
1315
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: "[" }),
|
|
1316
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.primary, children: "esc" }),
|
|
1317
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: "] back" })
|
|
1255
1318
|
] }),
|
|
1256
|
-
/* @__PURE__ */
|
|
1257
|
-
/* @__PURE__ */
|
|
1258
|
-
/* @__PURE__ */
|
|
1259
|
-
/* @__PURE__ */
|
|
1260
|
-
/* @__PURE__ */
|
|
1319
|
+
/* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, children: [
|
|
1320
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: "[" }),
|
|
1321
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.primary, children: "enter" }),
|
|
1322
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: "]" }),
|
|
1323
|
+
/* @__PURE__ */ jsx8(Text10, { color: COLORS.success, bold: true, children: "start wizard" })
|
|
1261
1324
|
] })
|
|
1262
1325
|
] })
|
|
1263
1326
|
]
|
|
@@ -1266,10 +1329,10 @@ function LearnMore() {
|
|
|
1266
1329
|
}
|
|
1267
1330
|
|
|
1268
1331
|
// src/ui/Sidebar.tsx
|
|
1269
|
-
import { Box as
|
|
1332
|
+
import { Box as Box13, Text as Text13 } from "ink";
|
|
1270
1333
|
|
|
1271
1334
|
// src/ui/Steps.tsx
|
|
1272
|
-
import { Box as
|
|
1335
|
+
import { Box as Box11, Text as Text11 } from "ink";
|
|
1273
1336
|
import Spinner from "ink-spinner";
|
|
1274
1337
|
|
|
1275
1338
|
// src/core/persistence.ts
|
|
@@ -1298,12 +1361,12 @@ async function clearWorkflowState(workflowId) {
|
|
|
1298
1361
|
}
|
|
1299
1362
|
|
|
1300
1363
|
// src/ui/Steps.tsx
|
|
1301
|
-
import { jsx as
|
|
1364
|
+
import { jsx as jsx9, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1302
1365
|
function Steps() {
|
|
1303
1366
|
const { steps } = useWizard();
|
|
1304
1367
|
const visibleSteps = steps.filter(isStepVisible);
|
|
1305
|
-
return /* @__PURE__ */
|
|
1306
|
-
s.status === "running" ? /* @__PURE__ */
|
|
1368
|
+
return /* @__PURE__ */ jsx9(Box11, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx9(Box11, { flexDirection: "column", children: /* @__PURE__ */ jsxs10(Text11, { color: COLORS.status[s.status], children: [
|
|
1369
|
+
s.status === "running" ? /* @__PURE__ */ jsx9(Spinner, { type: "dots" }) : MARKER[s.status],
|
|
1307
1370
|
" ",
|
|
1308
1371
|
s.title
|
|
1309
1372
|
] }) }, s.id)) });
|
|
@@ -1312,27 +1375,27 @@ function CurrentStep() {
|
|
|
1312
1375
|
const { steps } = useWizard();
|
|
1313
1376
|
const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
|
|
1314
1377
|
if (!currentStep) return null;
|
|
1315
|
-
return /* @__PURE__ */
|
|
1316
|
-
/* @__PURE__ */
|
|
1378
|
+
return /* @__PURE__ */ jsxs10(Text11, { color: COLORS.status.running, children: [
|
|
1379
|
+
/* @__PURE__ */ jsx9(Spinner, { type: "dots" }),
|
|
1317
1380
|
" ",
|
|
1318
1381
|
` ${currentStep.title}`
|
|
1319
1382
|
] });
|
|
1320
1383
|
}
|
|
1321
1384
|
|
|
1322
1385
|
// src/ui/Progress.tsx
|
|
1323
|
-
import { Box as
|
|
1324
|
-
import { jsx as
|
|
1386
|
+
import { Box as Box12, Text as Text12 } from "ink";
|
|
1387
|
+
import { jsx as jsx10, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1325
1388
|
function Progress() {
|
|
1326
1389
|
const { steps, currentStepIndex } = useWizard();
|
|
1327
1390
|
const visibleSteps = steps.filter(isStepVisible);
|
|
1328
1391
|
if (visibleSteps.length === 0) return null;
|
|
1329
1392
|
const visibleCountThroughCurrent = steps.slice(0, currentStepIndex + 1).filter(isStepVisible).length;
|
|
1330
1393
|
const activeStepNumber = Math.max(1, visibleCountThroughCurrent);
|
|
1331
|
-
return /* @__PURE__ */
|
|
1332
|
-
/* @__PURE__ */
|
|
1333
|
-
/* @__PURE__ */
|
|
1334
|
-
/* @__PURE__ */
|
|
1335
|
-
/* @__PURE__ */
|
|
1394
|
+
return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: 1, children: [
|
|
1395
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "STEP" }),
|
|
1396
|
+
/* @__PURE__ */ jsx10(Text12, { bold: true, children: activeStepNumber }),
|
|
1397
|
+
/* @__PURE__ */ jsx10(Text12, { bold: true, children: "/" }),
|
|
1398
|
+
/* @__PURE__ */ jsx10(Text12, { bold: true, children: visibleSteps.length })
|
|
1336
1399
|
] });
|
|
1337
1400
|
}
|
|
1338
1401
|
|
|
@@ -1343,10 +1406,10 @@ var sidebarCommands = [
|
|
|
1343
1406
|
];
|
|
1344
1407
|
|
|
1345
1408
|
// src/ui/Sidebar.tsx
|
|
1346
|
-
import { jsx as
|
|
1409
|
+
import { jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1347
1410
|
function Sidebar() {
|
|
1348
|
-
return /* @__PURE__ */
|
|
1349
|
-
|
|
1411
|
+
return /* @__PURE__ */ jsxs12(
|
|
1412
|
+
Box13,
|
|
1350
1413
|
{
|
|
1351
1414
|
backgroundColor: "#14171E",
|
|
1352
1415
|
width: 30,
|
|
@@ -1355,16 +1418,16 @@ function Sidebar() {
|
|
|
1355
1418
|
flexDirection: "column",
|
|
1356
1419
|
justifyContent: "space-between",
|
|
1357
1420
|
children: [
|
|
1358
|
-
/* @__PURE__ */
|
|
1359
|
-
/* @__PURE__ */
|
|
1360
|
-
/* @__PURE__ */
|
|
1421
|
+
/* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", gap: 1, children: [
|
|
1422
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "PROGRESS" }),
|
|
1423
|
+
/* @__PURE__ */ jsx11(Steps, {})
|
|
1361
1424
|
] }),
|
|
1362
|
-
/* @__PURE__ */
|
|
1363
|
-
/* @__PURE__ */
|
|
1364
|
-
/* @__PURE__ */
|
|
1365
|
-
return /* @__PURE__ */
|
|
1366
|
-
/* @__PURE__ */
|
|
1367
|
-
/* @__PURE__ */
|
|
1425
|
+
/* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", gap: 1, children: [
|
|
1426
|
+
/* @__PURE__ */ jsx11(Progress, {}),
|
|
1427
|
+
/* @__PURE__ */ jsx11(Box13, { flexDirection: "column", children: sidebarCommands.map((c) => {
|
|
1428
|
+
return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "row", gap: 1, children: [
|
|
1429
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.primary, children: `[${c.keyHint}]` }),
|
|
1430
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: c.description })
|
|
1368
1431
|
] });
|
|
1369
1432
|
}) })
|
|
1370
1433
|
] })
|
|
@@ -1374,12 +1437,12 @@ function Sidebar() {
|
|
|
1374
1437
|
}
|
|
1375
1438
|
|
|
1376
1439
|
// src/ui/Ribbon.tsx
|
|
1377
|
-
import { Box as
|
|
1378
|
-
import { jsx as
|
|
1440
|
+
import { Box as Box14, Text as Text14 } from "ink";
|
|
1441
|
+
import { jsx as jsx12, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1379
1442
|
function Ribbon() {
|
|
1380
1443
|
const firstCommand = sidebarCommands[0];
|
|
1381
|
-
return /* @__PURE__ */
|
|
1382
|
-
|
|
1444
|
+
return /* @__PURE__ */ jsxs13(
|
|
1445
|
+
Box14,
|
|
1383
1446
|
{
|
|
1384
1447
|
backgroundColor: "#14171E",
|
|
1385
1448
|
flexDirection: "row",
|
|
@@ -1387,11 +1450,11 @@ function Ribbon() {
|
|
|
1387
1450
|
paddingX: 2,
|
|
1388
1451
|
paddingY: 1,
|
|
1389
1452
|
children: [
|
|
1390
|
-
/* @__PURE__ */
|
|
1391
|
-
/* @__PURE__ */
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
/* @__PURE__ */
|
|
1453
|
+
/* @__PURE__ */ jsx12(Progress, {}),
|
|
1454
|
+
/* @__PURE__ */ jsx12(CurrentStep, {}),
|
|
1455
|
+
/* @__PURE__ */ jsxs13(Box14, { flexDirection: "row", gap: 1, children: [
|
|
1456
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
|
|
1457
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: firstCommand.description })
|
|
1395
1458
|
] })
|
|
1396
1459
|
]
|
|
1397
1460
|
}
|
|
@@ -1402,8 +1465,8 @@ function Ribbon() {
|
|
|
1402
1465
|
import { useState as useState6 } from "react";
|
|
1403
1466
|
|
|
1404
1467
|
// src/ui/Logs.tsx
|
|
1405
|
-
import { Box as
|
|
1406
|
-
import { jsx as
|
|
1468
|
+
import { Box as Box15, Text as Text15, useInput as useInput6 } from "ink";
|
|
1469
|
+
import { jsx as jsx13, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1407
1470
|
var KIND_COLOR = {
|
|
1408
1471
|
tool: COLORS.primary,
|
|
1409
1472
|
prompt: COLORS.badge
|
|
@@ -1434,14 +1497,14 @@ function formatTimestamp(ms) {
|
|
|
1434
1497
|
function Logs() {
|
|
1435
1498
|
const logs = useWizard((s) => s.logs);
|
|
1436
1499
|
const scroll = useScrollWindow({ itemCount: logs.length, followBottom: true });
|
|
1437
|
-
|
|
1500
|
+
useInput6((_input, key) => {
|
|
1438
1501
|
if (key.upArrow) scroll.scrollBy(-1);
|
|
1439
1502
|
else if (key.downArrow) scroll.scrollBy(1);
|
|
1440
1503
|
});
|
|
1441
1504
|
const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
1442
|
-
return /* @__PURE__ */
|
|
1443
|
-
logs.length === 0 && /* @__PURE__ */
|
|
1444
|
-
/* @__PURE__ */
|
|
1505
|
+
return /* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
|
|
1506
|
+
logs.length === 0 && /* @__PURE__ */ jsx13(Text15, { color: COLORS.dim, children: "No logs yet." }),
|
|
1507
|
+
/* @__PURE__ */ jsx13(ScrollView, { scroll, children: visible.map((entry) => {
|
|
1445
1508
|
const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
|
|
1446
1509
|
const durationText = entry.kind === "tool" && entry.durationMs !== void 0 ? `${entry.durationMs}ms` : "";
|
|
1447
1510
|
const rawPreview = rawInputText(entry.input);
|
|
@@ -1451,14 +1514,14 @@ function Logs() {
|
|
|
1451
1514
|
const name = truncate2(entry.name, budget);
|
|
1452
1515
|
budget -= name.length;
|
|
1453
1516
|
const preview = rawPreview ? truncate2(rawPreview, budget) : "";
|
|
1454
|
-
return /* @__PURE__ */
|
|
1455
|
-
/* @__PURE__ */
|
|
1456
|
-
/* @__PURE__ */
|
|
1457
|
-
preview && /* @__PURE__ */
|
|
1458
|
-
durationText && /* @__PURE__ */
|
|
1517
|
+
return /* @__PURE__ */ jsxs14(Box15, { flexDirection: "row", gap: ROW_GAP, children: [
|
|
1518
|
+
/* @__PURE__ */ jsx13(Text15, { color: COLORS.dim, children: timestamp }),
|
|
1519
|
+
/* @__PURE__ */ jsx13(Text15, { color: logNameColor(entry), wrap: "truncate", children: name }),
|
|
1520
|
+
preview && /* @__PURE__ */ jsx13(Text15, { color: COLORS.dim, wrap: "truncate", children: preview }),
|
|
1521
|
+
durationText && /* @__PURE__ */ jsx13(Text15, { color: COLORS.dim, children: durationText })
|
|
1459
1522
|
] }, entry.id);
|
|
1460
1523
|
}) }),
|
|
1461
|
-
/* @__PURE__ */
|
|
1524
|
+
/* @__PURE__ */ jsx13(Text15, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
|
|
1462
1525
|
] });
|
|
1463
1526
|
}
|
|
1464
1527
|
|
|
@@ -1650,7 +1713,7 @@ function track(event, payload) {
|
|
|
1650
1713
|
}
|
|
1651
1714
|
|
|
1652
1715
|
// src/ui/App.tsx
|
|
1653
|
-
import { jsx as
|
|
1716
|
+
import { jsx as jsx14, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1654
1717
|
function App() {
|
|
1655
1718
|
const { phase, error, homeScreen, currentStepIndex, steps, inputReq } = useWizard();
|
|
1656
1719
|
const { exit } = useApp();
|
|
@@ -1658,7 +1721,7 @@ function App() {
|
|
|
1658
1721
|
const [showLogs, setShowLogs] = useState6(false);
|
|
1659
1722
|
const finished = phase === "done" || phase === "error";
|
|
1660
1723
|
const currentStep = steps[currentStepIndex];
|
|
1661
|
-
|
|
1724
|
+
useInput7(
|
|
1662
1725
|
(_input, key) => {
|
|
1663
1726
|
if (key.return) {
|
|
1664
1727
|
exit();
|
|
@@ -1666,7 +1729,7 @@ function App() {
|
|
|
1666
1729
|
},
|
|
1667
1730
|
{ isActive: finished }
|
|
1668
1731
|
);
|
|
1669
|
-
|
|
1732
|
+
useInput7((_input, key) => {
|
|
1670
1733
|
if (phase === "idle" || phase === "authenticating") return;
|
|
1671
1734
|
if (key.tab) {
|
|
1672
1735
|
setShowLogs(!showLogs);
|
|
@@ -1677,8 +1740,8 @@ function App() {
|
|
|
1677
1740
|
});
|
|
1678
1741
|
}
|
|
1679
1742
|
});
|
|
1680
|
-
const escOwnedElsewhere = phase === "idle" || phase === "authenticating" || phase === "awaitingInput" && inputReq?.promptType === "enterToContinue";
|
|
1681
|
-
|
|
1743
|
+
const escOwnedElsewhere = phase === "idle" || phase === "authenticating" || phase === "awaitingInput" && (inputReq?.promptType === "enterToContinue" || inputReq?.promptType === "commandApproval");
|
|
1744
|
+
useInput7((_input, key) => {
|
|
1682
1745
|
if (escOwnedElsewhere) return;
|
|
1683
1746
|
if (key.escape) {
|
|
1684
1747
|
track("AI Wizard Interaction", {
|
|
@@ -1697,8 +1760,8 @@ function App() {
|
|
|
1697
1760
|
/* Clamped to exactly the viewport: a taller frame makes Ink clear and repaint
|
|
1698
1761
|
the whole screen, and the scrolling throws off its cursor arithmetic —
|
|
1699
1762
|
flicker and leftover rows. */
|
|
1700
|
-
/* @__PURE__ */
|
|
1701
|
-
|
|
1763
|
+
/* @__PURE__ */ jsxs15(
|
|
1764
|
+
Box16,
|
|
1702
1765
|
{
|
|
1703
1766
|
backgroundColor: COLORS.bg.main,
|
|
1704
1767
|
flexDirection: "row",
|
|
@@ -1706,16 +1769,16 @@ function App() {
|
|
|
1706
1769
|
height: scrollsPastViewport ? void 0 : rows,
|
|
1707
1770
|
overflow: scrollsPastViewport ? "visible" : "hidden",
|
|
1708
1771
|
children: [
|
|
1709
|
-
mainWindowVisible && /* @__PURE__ */
|
|
1710
|
-
|
|
1772
|
+
mainWindowVisible && /* @__PURE__ */ jsxs15(
|
|
1773
|
+
Box16,
|
|
1711
1774
|
{
|
|
1712
1775
|
flexDirection,
|
|
1713
1776
|
width: "100%",
|
|
1714
1777
|
maxHeight: rows,
|
|
1715
1778
|
justifyContent: "space-between",
|
|
1716
1779
|
children: [
|
|
1717
|
-
showLogs ? /* @__PURE__ */
|
|
1718
|
-
|
|
1780
|
+
showLogs ? /* @__PURE__ */ jsx14(Logs, {}) : /* @__PURE__ */ jsxs15(
|
|
1781
|
+
Box16,
|
|
1719
1782
|
{
|
|
1720
1783
|
flexDirection: "column",
|
|
1721
1784
|
paddingX: 4,
|
|
@@ -1723,26 +1786,26 @@ function App() {
|
|
|
1723
1786
|
width: showSidebar ? 70 : "100%",
|
|
1724
1787
|
flexGrow: 1,
|
|
1725
1788
|
children: [
|
|
1726
|
-
phase === "authenticating" && /* @__PURE__ */
|
|
1727
|
-
/* @__PURE__ */
|
|
1728
|
-
/* @__PURE__ */
|
|
1789
|
+
phase === "authenticating" && /* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", marginBottom: 1, children: [
|
|
1790
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.strong, bold: true, children: "Signing in to Algolia" }),
|
|
1791
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
|
|
1729
1792
|
] }),
|
|
1730
|
-
/* @__PURE__ */
|
|
1731
|
-
/* @__PURE__ */
|
|
1732
|
-
/* @__PURE__ */
|
|
1733
|
-
phase === "running" && showSidebar && /* @__PURE__ */
|
|
1734
|
-
phase === "error" && error && /* @__PURE__ */
|
|
1793
|
+
/* @__PURE__ */ jsx14(CliOutput, {}),
|
|
1794
|
+
/* @__PURE__ */ jsx14(Notices, {}),
|
|
1795
|
+
/* @__PURE__ */ jsx14(PromptInput, {}),
|
|
1796
|
+
phase === "running" && showSidebar && /* @__PURE__ */ jsx14(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx14(CurrentStep, {}) }),
|
|
1797
|
+
phase === "error" && error && /* @__PURE__ */ jsx14(Box16, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text16, { color: COLORS.status.error, children: [
|
|
1735
1798
|
"\u2716 ",
|
|
1736
1799
|
error
|
|
1737
1800
|
] }) })
|
|
1738
1801
|
]
|
|
1739
1802
|
}
|
|
1740
1803
|
),
|
|
1741
|
-
showSidebar ? /* @__PURE__ */
|
|
1804
|
+
showSidebar ? /* @__PURE__ */ jsx14(Sidebar, {}) : /* @__PURE__ */ jsx14(Ribbon, {})
|
|
1742
1805
|
]
|
|
1743
1806
|
}
|
|
1744
1807
|
),
|
|
1745
|
-
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */
|
|
1808
|
+
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */ jsx14(LearnMore, {}) : /* @__PURE__ */ jsx14(Welcome, {}))
|
|
1746
1809
|
]
|
|
1747
1810
|
}
|
|
1748
1811
|
)
|
|
@@ -1822,7 +1885,7 @@ async function ensureConsent() {
|
|
|
1822
1885
|
if (config.aiConsent) return;
|
|
1823
1886
|
const store = useWizard.getState();
|
|
1824
1887
|
const answer = await store.requestUserInput({
|
|
1825
|
-
prompt: "Wizard will make AI-authored changes to this repository.",
|
|
1888
|
+
prompt: "Wizard will make AI-authored changes to this repository, and will propose shell commands to set it up. You approve each command before it runs.",
|
|
1826
1889
|
promptType: "enterToContinue",
|
|
1827
1890
|
options: []
|
|
1828
1891
|
});
|
|
@@ -2178,7 +2241,7 @@ async function ensureApplication() {
|
|
|
2178
2241
|
}
|
|
2179
2242
|
|
|
2180
2243
|
// src/workflows/default.ts
|
|
2181
|
-
import { z as
|
|
2244
|
+
import { z as z29 } from "zod";
|
|
2182
2245
|
|
|
2183
2246
|
// src/actions/listIndices.ts
|
|
2184
2247
|
import { z as z5 } from "zod";
|
|
@@ -2901,13 +2964,187 @@ function verifyImplementationTool() {
|
|
|
2901
2964
|
});
|
|
2902
2965
|
}
|
|
2903
2966
|
|
|
2967
|
+
// src/lib/tools/runShell.ts
|
|
2968
|
+
import { tool as tool9 } from "ai";
|
|
2969
|
+
import z16 from "zod";
|
|
2970
|
+
|
|
2971
|
+
// src/lib/tools/utils/runShell.ts
|
|
2972
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
2973
|
+
|
|
2974
|
+
// src/lib/tools/context.ts
|
|
2975
|
+
var DEFAULT_TOOL_LIMITS = {
|
|
2976
|
+
list: 10,
|
|
2977
|
+
search: 10,
|
|
2978
|
+
read: 20,
|
|
2979
|
+
match: 100,
|
|
2980
|
+
shell: 30
|
|
2981
|
+
};
|
|
2982
|
+
var DEFAULT_SHELL_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
2983
|
+
async function refuseByDefault() {
|
|
2984
|
+
return "reject";
|
|
2985
|
+
}
|
|
2986
|
+
function createShellContext(overrides = {}) {
|
|
2987
|
+
return {
|
|
2988
|
+
env: async () => ({}),
|
|
2989
|
+
timeoutMs: DEFAULT_SHELL_TIMEOUT_MS,
|
|
2990
|
+
executions: [],
|
|
2991
|
+
approve: refuseByDefault,
|
|
2992
|
+
...overrides
|
|
2993
|
+
};
|
|
2994
|
+
}
|
|
2995
|
+
function createToolContext(limits = DEFAULT_TOOL_LIMITS, cwd = process.cwd(), shell2 = createShellContext()) {
|
|
2996
|
+
return {
|
|
2997
|
+
root: cwd,
|
|
2998
|
+
cwd,
|
|
2999
|
+
limits: { ...limits },
|
|
3000
|
+
counts: { list: 0, search: 0, read: 0, shell: 0 },
|
|
3001
|
+
shell: shell2
|
|
3002
|
+
};
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
// src/lib/tools/utils/runShell.ts
|
|
3006
|
+
var SIGKILL_DELAY_MS = 5e3;
|
|
3007
|
+
var HEAD_CHARS = 4e3;
|
|
3008
|
+
var TAIL_CHARS = 8e3;
|
|
3009
|
+
function truncateOutput(output) {
|
|
3010
|
+
if (output.length <= HEAD_CHARS + TAIL_CHARS) return output;
|
|
3011
|
+
const omitted = output.length - HEAD_CHARS - TAIL_CHARS;
|
|
3012
|
+
return [
|
|
3013
|
+
output.slice(0, HEAD_CHARS),
|
|
3014
|
+
`
|
|
3015
|
+
\u2026 [${omitted} characters omitted] \u2026
|
|
3016
|
+
`,
|
|
3017
|
+
output.slice(-TAIL_CHARS)
|
|
3018
|
+
].join("");
|
|
3019
|
+
}
|
|
3020
|
+
function runShell(command, opts) {
|
|
3021
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_SHELL_TIMEOUT_MS;
|
|
3022
|
+
const startedAt = Date.now();
|
|
3023
|
+
return new Promise((resolve4) => {
|
|
3024
|
+
let output = "";
|
|
3025
|
+
let timedOut = false;
|
|
3026
|
+
let settled = false;
|
|
3027
|
+
const child = spawn3(command, {
|
|
3028
|
+
shell: true,
|
|
3029
|
+
cwd: opts.cwd,
|
|
3030
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3031
|
+
env: { ...process.env, ...opts.env }
|
|
3032
|
+
});
|
|
3033
|
+
const finish = (exitCode) => {
|
|
3034
|
+
if (settled) return;
|
|
3035
|
+
settled = true;
|
|
3036
|
+
clearTimeout(timer);
|
|
3037
|
+
clearTimeout(killTimer);
|
|
3038
|
+
resolve4({
|
|
3039
|
+
exitCode,
|
|
3040
|
+
output: truncateOutput(output.trim()),
|
|
3041
|
+
timedOut,
|
|
3042
|
+
durationMs: Date.now() - startedAt
|
|
3043
|
+
});
|
|
3044
|
+
};
|
|
3045
|
+
let killTimer;
|
|
3046
|
+
const timer = setTimeout(() => {
|
|
3047
|
+
timedOut = true;
|
|
3048
|
+
output += `
|
|
3049
|
+
[timed out after ${timeoutMs}ms]`;
|
|
3050
|
+
child.kill("SIGTERM");
|
|
3051
|
+
killTimer = setTimeout(() => child.kill("SIGKILL"), SIGKILL_DELAY_MS);
|
|
3052
|
+
}, timeoutMs);
|
|
3053
|
+
child.stdout?.on("data", (d) => output += d);
|
|
3054
|
+
child.stderr?.on("data", (d) => output += d);
|
|
3055
|
+
child.on("error", (err) => {
|
|
3056
|
+
output += `Failed to run ${command}: ${err.message}`;
|
|
3057
|
+
finish(1);
|
|
3058
|
+
});
|
|
3059
|
+
child.on("close", (code) => finish(code ?? 1));
|
|
3060
|
+
});
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
// src/lib/tools/runShell.ts
|
|
3064
|
+
var shellChain = Promise.resolve();
|
|
3065
|
+
function serialize(work) {
|
|
3066
|
+
const result = shellChain.then(work);
|
|
3067
|
+
shellChain = result.catch(() => {
|
|
3068
|
+
});
|
|
3069
|
+
return result;
|
|
3070
|
+
}
|
|
3071
|
+
async function approveAndRun(ctx, command, cwd, explanation) {
|
|
3072
|
+
const decision = await ctx.shell.approve({ command, cwd, explanation });
|
|
3073
|
+
if (decision === "reject") {
|
|
3074
|
+
ctx.shell.executions.push({ command, cwd, approved: false });
|
|
3075
|
+
logger.info({ command }, "runShell: user rejected the command");
|
|
3076
|
+
return "The user rejected this command. Do not retry it. Propose a different command, or report the limitation via reportStatus.";
|
|
3077
|
+
}
|
|
3078
|
+
useWizard.getState().pushNotice({ messages: [`Running: ${command}`] });
|
|
3079
|
+
const env = await ctx.shell.env().catch((err) => {
|
|
3080
|
+
logger.warn({ err, command }, "runShell: could not resolve command env");
|
|
3081
|
+
return {};
|
|
3082
|
+
});
|
|
3083
|
+
const run2 = await (ctx.shell.run ?? runShell)(command, {
|
|
3084
|
+
cwd,
|
|
3085
|
+
env,
|
|
3086
|
+
timeoutMs: ctx.shell.timeoutMs
|
|
3087
|
+
});
|
|
3088
|
+
logger.info(
|
|
3089
|
+
{
|
|
3090
|
+
command,
|
|
3091
|
+
exitCode: run2.exitCode,
|
|
3092
|
+
timedOut: run2.timedOut,
|
|
3093
|
+
durationMs: run2.durationMs
|
|
3094
|
+
},
|
|
3095
|
+
"runShell finished"
|
|
3096
|
+
);
|
|
3097
|
+
await markInteraction();
|
|
3098
|
+
ctx.shell.executions.push({
|
|
3099
|
+
command,
|
|
3100
|
+
cwd,
|
|
3101
|
+
approved: true,
|
|
3102
|
+
exitCode: run2.exitCode,
|
|
3103
|
+
output: run2.output,
|
|
3104
|
+
timedOut: run2.timedOut,
|
|
3105
|
+
durationMs: run2.durationMs
|
|
3106
|
+
});
|
|
3107
|
+
return {
|
|
3108
|
+
exitCode: run2.exitCode,
|
|
3109
|
+
timedOut: run2.timedOut,
|
|
3110
|
+
output: run2.output
|
|
3111
|
+
};
|
|
3112
|
+
}
|
|
3113
|
+
function runShellTool(ctx) {
|
|
3114
|
+
return tool9({
|
|
3115
|
+
description: "Run a shell command in the project. Use this for anything the project needs done in its own ecosystem: installing dependencies, running a script you wrote, running the project's lint/typecheck/test commands. The user sees and approves every command before it runs, so write a clear `explanation`. If the user rejects a command, do not retry it \u2014 propose a different approach.",
|
|
3116
|
+
inputSchema: z16.object({
|
|
3117
|
+
command: z16.string().describe(
|
|
3118
|
+
"The command to run, exactly as it would be typed in a shell. Pipes, && and redirects are allowed."
|
|
3119
|
+
),
|
|
3120
|
+
cwd: z16.string().optional().describe(
|
|
3121
|
+
"Directory to run in, relative to the project root. Defaults to the project root."
|
|
3122
|
+
),
|
|
3123
|
+
explanation: z16.string().describe(
|
|
3124
|
+
"One short line telling the user what this command does and why, including any side effect (e.g. writes records to Algolia). This is what they approve against."
|
|
3125
|
+
)
|
|
3126
|
+
}),
|
|
3127
|
+
execute: async ({ command, cwd, explanation }) => {
|
|
3128
|
+
if (++ctx.counts.shell > ctx.limits.shell) {
|
|
3129
|
+
return `Refused: command limit (${ctx.limits.shell}) reached. Stop running commands and report what you have.`;
|
|
3130
|
+
}
|
|
3131
|
+
const resolved2 = resolveInRoot(ctx, cwd ?? ".");
|
|
3132
|
+
if (!resolved2.ok) return resolved2.error;
|
|
3133
|
+
logger.info({ command, cwd: resolved2.target }, "called runShell tool");
|
|
3134
|
+
return serialize(
|
|
3135
|
+
() => approveAndRun(ctx, command, resolved2.target, explanation)
|
|
3136
|
+
);
|
|
3137
|
+
}
|
|
3138
|
+
});
|
|
3139
|
+
}
|
|
3140
|
+
|
|
2904
3141
|
// src/lib/tools/generateRecord.ts
|
|
2905
|
-
import { tool as
|
|
3142
|
+
import { tool as tool10, generateText, Output, NoObjectGeneratedError } from "ai";
|
|
2906
3143
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2907
3144
|
import { nanoid as nanoid2 } from "nanoid";
|
|
2908
3145
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
2909
3146
|
import { dirname as dirname6 } from "node:path";
|
|
2910
|
-
import
|
|
3147
|
+
import z17 from "zod";
|
|
2911
3148
|
var DATA_DIR = ".algolia-wizard/data";
|
|
2912
3149
|
var RECORD_MODEL = "claude-haiku-4-5";
|
|
2913
3150
|
var MAX_RECORDS = 100;
|
|
@@ -2917,19 +3154,19 @@ var anthropic = createAnthropic({
|
|
|
2917
3154
|
apiKey: process.env.PROVIDER_API_KEY ?? ""
|
|
2918
3155
|
});
|
|
2919
3156
|
function generateRecordTool(ctx) {
|
|
2920
|
-
return
|
|
3157
|
+
return tool10({
|
|
2921
3158
|
description: "Generate realistic sample records for an entity and write them to a JSON file in the worktree. Provide the entity name and its attributes; this tool asks a model to invent varied, realistic values, each with a unique objectID, and returns the file path to read them from at runtime. Do not invent the record values or objectIDs yourself, and do not inline the returned records into the script \u2014 call this tool and read the file it writes.",
|
|
2922
|
-
inputSchema:
|
|
2923
|
-
entityName:
|
|
2924
|
-
attributes:
|
|
2925
|
-
count:
|
|
2926
|
-
hint:
|
|
3159
|
+
inputSchema: z17.object({
|
|
3160
|
+
entityName: z17.string().describe("Name of the entity to generate records for."),
|
|
3161
|
+
attributes: z17.array(z17.string()).describe("Attribute names each record must contain."),
|
|
3162
|
+
count: z17.number().int().min(1).max(MAX_RECORDS).default(10).describe(`How many records to generate (max ${MAX_RECORDS}).`),
|
|
3163
|
+
hint: z17.string().optional().describe("Optional context to steer realistic values.")
|
|
2927
3164
|
}),
|
|
2928
3165
|
execute: async ({ entityName, attributes, count, hint }) => {
|
|
2929
3166
|
logger.info({ entityName, count }, "called generateRecord tool");
|
|
2930
3167
|
try {
|
|
2931
|
-
const value =
|
|
2932
|
-
const recordSchema =
|
|
3168
|
+
const value = z17.union([z17.string(), z17.number(), z17.boolean(), z17.null()]);
|
|
3169
|
+
const recordSchema = z17.object(
|
|
2933
3170
|
Object.fromEntries(attributes.map((attr) => [attr, value]))
|
|
2934
3171
|
);
|
|
2935
3172
|
const generateBatch = async (batchCount) => {
|
|
@@ -2939,8 +3176,8 @@ function generateRecordTool(ctx) {
|
|
|
2939
3176
|
const { output } = await generateText({
|
|
2940
3177
|
model: anthropic(RECORD_MODEL),
|
|
2941
3178
|
output: Output.object({
|
|
2942
|
-
schema:
|
|
2943
|
-
records:
|
|
3179
|
+
schema: z17.object({
|
|
3180
|
+
records: z17.array(recordSchema).length(batchCount)
|
|
2944
3181
|
})
|
|
2945
3182
|
}),
|
|
2946
3183
|
prompt: [
|
|
@@ -2997,13 +3234,13 @@ function generateRecordTool(ctx) {
|
|
|
2997
3234
|
}
|
|
2998
3235
|
|
|
2999
3236
|
// src/lib/tools/notifyUser.ts
|
|
3000
|
-
import { tool as
|
|
3001
|
-
import
|
|
3237
|
+
import { tool as tool11 } from "ai";
|
|
3238
|
+
import z18 from "zod";
|
|
3002
3239
|
function notifyUserTool() {
|
|
3003
|
-
return
|
|
3240
|
+
return tool11({
|
|
3004
3241
|
description: `Give the user a brief, high-level update on what you are currently doing or about to do next. This is for the big picture (e.g. "Reading through your data models", "Writing the search UI") \u2014 not granular detail like individual tool calls, which are already logged separately. Call it when you start a new phase of work or your focus shifts, just not on every step, enough to keep the user engaged. Don't say things like "starting", just describe what you are doing. Don't mention tool calls themselves, just general direction of the work.`,
|
|
3005
|
-
inputSchema:
|
|
3006
|
-
message:
|
|
3242
|
+
inputSchema: z18.object({
|
|
3243
|
+
message: z18.string().describe(
|
|
3007
3244
|
"Short, plain-language description of what you are doing now."
|
|
3008
3245
|
)
|
|
3009
3246
|
}),
|
|
@@ -3015,22 +3252,6 @@ function notifyUserTool() {
|
|
|
3015
3252
|
});
|
|
3016
3253
|
}
|
|
3017
3254
|
|
|
3018
|
-
// src/lib/tools/context.ts
|
|
3019
|
-
var DEFAULT_TOOL_LIMITS = {
|
|
3020
|
-
list: 10,
|
|
3021
|
-
search: 10,
|
|
3022
|
-
read: 20,
|
|
3023
|
-
match: 100
|
|
3024
|
-
};
|
|
3025
|
-
function createToolContext(limits = DEFAULT_TOOL_LIMITS, cwd = process.cwd()) {
|
|
3026
|
-
return {
|
|
3027
|
-
root: cwd,
|
|
3028
|
-
cwd,
|
|
3029
|
-
limits,
|
|
3030
|
-
counts: { list: 0, search: 0, read: 0 }
|
|
3031
|
-
};
|
|
3032
|
-
}
|
|
3033
|
-
|
|
3034
3255
|
// src/lib/tools/index.ts
|
|
3035
3256
|
function withLogging(name, def) {
|
|
3036
3257
|
const execute = def.execute;
|
|
@@ -3066,6 +3287,7 @@ function createTools(ctx, { output, tools }) {
|
|
|
3066
3287
|
"verifyImplementation",
|
|
3067
3288
|
verifyImplementationTool()
|
|
3068
3289
|
),
|
|
3290
|
+
runShell: withLogging("runShell", runShellTool(ctx)),
|
|
3069
3291
|
generateRecord: withLogging("generateRecord", generateRecordTool(ctx)),
|
|
3070
3292
|
notifyUser: withLogging("notifyUser", notifyUserTool())
|
|
3071
3293
|
};
|
|
@@ -3100,7 +3322,7 @@ async function runAgent(req) {
|
|
|
3100
3322
|
baseURL: PROXY_BASE_URL,
|
|
3101
3323
|
fetch: proxyFetch
|
|
3102
3324
|
});
|
|
3103
|
-
const toolContext = createToolContext();
|
|
3325
|
+
const toolContext = req.toolContext ?? createToolContext();
|
|
3104
3326
|
const readTools = ["readFile", "searchFiles", "listFiles"];
|
|
3105
3327
|
const hasReadTools = !req.tools || req.tools.some((t) => readTools.includes(t));
|
|
3106
3328
|
const instructions = [
|
|
@@ -3165,7 +3387,11 @@ async function runAgent(req) {
|
|
|
3165
3387
|
"runAgent finished"
|
|
3166
3388
|
);
|
|
3167
3389
|
logger.info(
|
|
3168
|
-
{
|
|
3390
|
+
{
|
|
3391
|
+
counts: toolContext.counts,
|
|
3392
|
+
limits: toolContext.limits,
|
|
3393
|
+
commandsRun: toolContext.shell.executions.length
|
|
3394
|
+
},
|
|
3169
3395
|
"tool usage"
|
|
3170
3396
|
);
|
|
3171
3397
|
const toolResults = await stream.toolResults;
|
|
@@ -3183,10 +3409,10 @@ async function runAgent(req) {
|
|
|
3183
3409
|
}
|
|
3184
3410
|
|
|
3185
3411
|
// src/actions/detectLanguage.ts
|
|
3186
|
-
import
|
|
3187
|
-
var detectLanguageSchema =
|
|
3188
|
-
languages:
|
|
3189
|
-
frameworks:
|
|
3412
|
+
import z21 from "zod";
|
|
3413
|
+
var detectLanguageSchema = z21.object({
|
|
3414
|
+
languages: z21.array(z21.object({ name: z21.string(), version: z21.string() })),
|
|
3415
|
+
frameworks: z21.array(z21.object({ name: z21.string(), version: z21.string() }))
|
|
3190
3416
|
});
|
|
3191
3417
|
var detectLanguage = () => runAgent({
|
|
3192
3418
|
instructions: [
|
|
@@ -3204,31 +3430,31 @@ var detectLanguage = () => runAgent({
|
|
|
3204
3430
|
});
|
|
3205
3431
|
|
|
3206
3432
|
// src/actions/analyzeCodebase.ts
|
|
3207
|
-
import
|
|
3433
|
+
import z22 from "zod";
|
|
3208
3434
|
var READONLY_TOOLS = [
|
|
3209
3435
|
"listFiles",
|
|
3210
3436
|
"changeDirectory",
|
|
3211
3437
|
"readFile",
|
|
3212
3438
|
"searchFiles"
|
|
3213
3439
|
];
|
|
3214
|
-
var ingestionAnalysisSchema =
|
|
3215
|
-
ingestionAnalysis:
|
|
3216
|
-
|
|
3217
|
-
name:
|
|
3218
|
-
paths:
|
|
3440
|
+
var ingestionAnalysisSchema = z22.object({
|
|
3441
|
+
ingestionAnalysis: z22.array(
|
|
3442
|
+
z22.object({
|
|
3443
|
+
name: z22.string(),
|
|
3444
|
+
paths: z22.array(z22.string()),
|
|
3219
3445
|
// indexable fields the agent found for this entity
|
|
3220
|
-
attributes:
|
|
3446
|
+
attributes: z22.array(z22.string())
|
|
3221
3447
|
})
|
|
3222
3448
|
)
|
|
3223
3449
|
});
|
|
3224
|
-
var searchImplementationAnalysisSchema =
|
|
3225
|
-
searchImplementationAnalysis:
|
|
3450
|
+
var searchImplementationAnalysisSchema = z22.object({
|
|
3451
|
+
searchImplementationAnalysis: z22.string()
|
|
3226
3452
|
});
|
|
3227
|
-
var verificationSchema =
|
|
3228
|
-
verification:
|
|
3453
|
+
var verificationSchema = z22.object({
|
|
3454
|
+
verification: z22.array(z22.string())
|
|
3229
3455
|
});
|
|
3230
3456
|
var confirmedEntitiesFieldSchema = ingestionAnalysisSchema.shape.ingestionAnalysis.optional();
|
|
3231
|
-
var analyzeCodebaseSchema =
|
|
3457
|
+
var analyzeCodebaseSchema = z22.object({
|
|
3232
3458
|
ingestionAnalysis: ingestionAnalysisSchema.shape.ingestionAnalysis.optional(),
|
|
3233
3459
|
searchImplementationAnalysis: searchImplementationAnalysisSchema.shape.searchImplementationAnalysis.optional(),
|
|
3234
3460
|
verification: verificationSchema.shape.verification.optional(),
|
|
@@ -3290,7 +3516,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3290
3516
|
// package.json
|
|
3291
3517
|
var package_default = {
|
|
3292
3518
|
name: "@algolia/wizard",
|
|
3293
|
-
version: "0.12.0
|
|
3519
|
+
version: "0.12.0",
|
|
3294
3520
|
description: "Magically implement Algolia functionality in your codebase",
|
|
3295
3521
|
type: "module",
|
|
3296
3522
|
engines: {
|
|
@@ -3409,8 +3635,8 @@ async function askList(ctx, prompt, { required = false } = {}) {
|
|
|
3409
3635
|
}
|
|
3410
3636
|
|
|
3411
3637
|
// src/actions/confirmLanguage.ts
|
|
3412
|
-
import
|
|
3413
|
-
var confirmLanguageSchema =
|
|
3638
|
+
import z24 from "zod";
|
|
3639
|
+
var confirmLanguageSchema = z24.object({
|
|
3414
3640
|
languages: detectLanguageSchema.shape.languages
|
|
3415
3641
|
});
|
|
3416
3642
|
async function confirmLanguage(ctx) {
|
|
@@ -3431,8 +3657,8 @@ async function confirmLanguage(ctx) {
|
|
|
3431
3657
|
}
|
|
3432
3658
|
|
|
3433
3659
|
// src/actions/confirmFramework.ts
|
|
3434
|
-
import
|
|
3435
|
-
var confirmFrameworkSchema =
|
|
3660
|
+
import z25 from "zod";
|
|
3661
|
+
var confirmFrameworkSchema = z25.object({
|
|
3436
3662
|
frameworks: detectLanguageSchema.shape.frameworks
|
|
3437
3663
|
});
|
|
3438
3664
|
var CURATED_FRAMEWORKS = [
|
|
@@ -3560,8 +3786,8 @@ async function promptUser(ctx, params) {
|
|
|
3560
3786
|
}
|
|
3561
3787
|
|
|
3562
3788
|
// src/actions/confirmEntities.ts
|
|
3563
|
-
import
|
|
3564
|
-
var confirmEntitiesSchema =
|
|
3789
|
+
import z26 from "zod";
|
|
3790
|
+
var confirmEntitiesSchema = z26.object({
|
|
3565
3791
|
// Final detection — the focused re-run may supersede project-scan's.
|
|
3566
3792
|
ingestionAnalysis: ingestionAnalysisSchema.shape.ingestionAnalysis.optional(),
|
|
3567
3793
|
confirmedEntities: confirmedEntitiesFieldSchema
|
|
@@ -3631,15 +3857,15 @@ async function confirmEntities(ctx) {
|
|
|
3631
3857
|
}
|
|
3632
3858
|
|
|
3633
3859
|
// src/actions/review.ts
|
|
3634
|
-
import { z as
|
|
3635
|
-
var reviewSchema =
|
|
3860
|
+
import { z as z27 } from "zod";
|
|
3861
|
+
var reviewSchema = z27.object({
|
|
3636
3862
|
// Broad, high-level takeaways grouped by theme (e.g. ingestion, search UI),
|
|
3637
3863
|
// not one entry per workflow step — a step's raw output can be a long,
|
|
3638
3864
|
// multi-paragraph blob (see implement.ts's summaries.join), and mirroring
|
|
3639
3865
|
// that 1:1 is what made the old per-step summary an unreadable wall of text.
|
|
3640
|
-
summaryPoints:
|
|
3641
|
-
reviewPrompt:
|
|
3642
|
-
nextSteps:
|
|
3866
|
+
summaryPoints: z27.array(z27.string()),
|
|
3867
|
+
reviewPrompt: z27.string(),
|
|
3868
|
+
nextSteps: z27.array(z27.string())
|
|
3643
3869
|
});
|
|
3644
3870
|
function formatCompletedSteps(steps) {
|
|
3645
3871
|
if (!steps.length) return "(no prior steps completed)";
|
|
@@ -3690,10 +3916,10 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
|
|
|
3690
3916
|
};
|
|
3691
3917
|
|
|
3692
3918
|
// src/actions/implement.ts
|
|
3693
|
-
import
|
|
3919
|
+
import z28 from "zod";
|
|
3694
3920
|
|
|
3695
3921
|
// src/lib/worktree.ts
|
|
3696
|
-
import { execFile, spawn as
|
|
3922
|
+
import { execFile, spawn as spawn4 } from "node:child_process";
|
|
3697
3923
|
import { copyFile, mkdir as mkdir6, readdir as readdir3, readFile as readFile8, stat as stat2, writeFile as writeFile6 } from "node:fs/promises";
|
|
3698
3924
|
import {
|
|
3699
3925
|
basename as basename2,
|
|
@@ -3774,7 +4000,7 @@ async function installWorktreeDeps(worktreePath) {
|
|
|
3774
4000
|
const pm = await detectPackageManager(worktreePath);
|
|
3775
4001
|
return new Promise((resolve4) => {
|
|
3776
4002
|
let output = "";
|
|
3777
|
-
const child =
|
|
4003
|
+
const child = spawn4(pm, ["install"], {
|
|
3778
4004
|
cwd: worktreePath,
|
|
3779
4005
|
stdio: ["ignore", "pipe", "pipe"]
|
|
3780
4006
|
});
|
|
@@ -3843,7 +4069,7 @@ async function runIngestScript(worktreePath, runtime, entrypoint, env = {}) {
|
|
|
3843
4069
|
}
|
|
3844
4070
|
return new Promise((resolveRun) => {
|
|
3845
4071
|
let output = "";
|
|
3846
|
-
const child =
|
|
4072
|
+
const child = spawn4(runtime, [entrypoint], {
|
|
3847
4073
|
cwd: worktreePath,
|
|
3848
4074
|
shell: false,
|
|
3849
4075
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -4049,34 +4275,34 @@ function shellQuote(value) {
|
|
|
4049
4275
|
}
|
|
4050
4276
|
|
|
4051
4277
|
// src/actions/implement.ts
|
|
4052
|
-
var implementSchema =
|
|
4053
|
-
filesChanged:
|
|
4054
|
-
summary:
|
|
4055
|
-
worktreePath:
|
|
4056
|
-
ingestCommand:
|
|
4057
|
-
ingestScriptRan:
|
|
4058
|
-
ingestRecordCount:
|
|
4059
|
-
ingestDurationMs:
|
|
4060
|
-
ingestionSource:
|
|
4061
|
-
searchEnvVars:
|
|
4062
|
-
|
|
4063
|
-
name:
|
|
4064
|
-
value:
|
|
4278
|
+
var implementSchema = z28.object({
|
|
4279
|
+
filesChanged: z28.array(z28.string()),
|
|
4280
|
+
summary: z28.string(),
|
|
4281
|
+
worktreePath: z28.string().optional(),
|
|
4282
|
+
ingestCommand: z28.string().optional(),
|
|
4283
|
+
ingestScriptRan: z28.boolean().optional(),
|
|
4284
|
+
ingestRecordCount: z28.number().optional(),
|
|
4285
|
+
ingestDurationMs: z28.number().optional(),
|
|
4286
|
+
ingestionSource: z28.enum(["local", "fileUpload", "generated"]),
|
|
4287
|
+
searchEnvVars: z28.array(
|
|
4288
|
+
z28.object({
|
|
4289
|
+
name: z28.string(),
|
|
4290
|
+
value: z28.string()
|
|
4065
4291
|
})
|
|
4066
4292
|
).optional()
|
|
4067
4293
|
});
|
|
4068
|
-
var implementationOutputSchema =
|
|
4069
|
-
summary:
|
|
4294
|
+
var implementationOutputSchema = z28.object({
|
|
4295
|
+
summary: z28.string(),
|
|
4070
4296
|
// Ingestion only: a structured pair the wizard turns into an argv, never a
|
|
4071
4297
|
// free-form command string. `runtime` is allowlisted and `entrypoint` is
|
|
4072
4298
|
// validated worktree-relative, so the agent cannot inject extra commands.
|
|
4073
|
-
runtime:
|
|
4074
|
-
entrypoint:
|
|
4299
|
+
runtime: z28.enum(INGEST_RUNTIMES).optional(),
|
|
4300
|
+
entrypoint: z28.string().optional()
|
|
4075
4301
|
});
|
|
4076
|
-
var verificationOutputSchema =
|
|
4077
|
-
summary:
|
|
4078
|
-
sufficient:
|
|
4079
|
-
additionalInstructions:
|
|
4302
|
+
var verificationOutputSchema = z28.object({
|
|
4303
|
+
summary: z28.string(),
|
|
4304
|
+
sufficient: z28.boolean(),
|
|
4305
|
+
additionalInstructions: z28.string().optional()
|
|
4080
4306
|
});
|
|
4081
4307
|
var MAX_IMPLEMENT_VERIFICATION_ATTEMPTS = 3;
|
|
4082
4308
|
var DEFAULT_IMPLEMENT_USE_CASES = ["ingestion", "search"];
|
|
@@ -4754,8 +4980,8 @@ var defaultWorkflow = {
|
|
|
4754
4980
|
defineStep({
|
|
4755
4981
|
id: "select-index",
|
|
4756
4982
|
title: "Set up index",
|
|
4757
|
-
outputSchema:
|
|
4758
|
-
selection:
|
|
4983
|
+
outputSchema: z29.object({
|
|
4984
|
+
selection: z29.string()
|
|
4759
4985
|
}),
|
|
4760
4986
|
run: (ctx) => selectIndexStep(ctx)
|
|
4761
4987
|
}),
|
|
@@ -5059,7 +5285,7 @@ async function resetProjectState() {
|
|
|
5059
5285
|
}
|
|
5060
5286
|
|
|
5061
5287
|
// src/main.tsx
|
|
5062
|
-
import { jsx as
|
|
5288
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
5063
5289
|
async function startup() {
|
|
5064
5290
|
setProjectRoot(process.cwd());
|
|
5065
5291
|
let args;
|
|
@@ -5109,7 +5335,7 @@ ${formatStepList(workflow)}`);
|
|
|
5109
5335
|
}
|
|
5110
5336
|
async function run(workflow) {
|
|
5111
5337
|
const store = useWizard.getState();
|
|
5112
|
-
const instance = render(/* @__PURE__ */
|
|
5338
|
+
const instance = render(/* @__PURE__ */ jsx15(App, {}), { incrementalRendering: true });
|
|
5113
5339
|
await store.waitForStart();
|
|
5114
5340
|
let user = await getUser();
|
|
5115
5341
|
if (!user) {
|