@algolia/wizard 0.50.0 → 0.52.0-rc.136.364
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 +507 -325
- package/package.json +1 -2
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
|
|
7
|
+
import { Box as Box20, Text as Text21, useApp, useInput as useInput8, useWindowSize as useWindowSize7 } from "ink";
|
|
8
8
|
import Spinner3 from "ink-spinner";
|
|
9
9
|
|
|
10
10
|
// src/core/store.ts
|
|
@@ -239,6 +239,9 @@ function describeInputValue(value) {
|
|
|
239
239
|
}
|
|
240
240
|
var NOTICE_INTERVAL_MS = 2e3;
|
|
241
241
|
var CLI_OUTPUT_LIMIT = 200;
|
|
242
|
+
function commandApprovalKey(command, cwd) {
|
|
243
|
+
return `${cwd}\0${command}`;
|
|
244
|
+
}
|
|
242
245
|
var useWizard = create((set, get) => ({
|
|
243
246
|
phase: "idle",
|
|
244
247
|
homeScreen: "home",
|
|
@@ -356,10 +359,17 @@ var useWizard = create((set, get) => ({
|
|
|
356
359
|
setTargetIndex: (index) => set({ targetIndex: index }),
|
|
357
360
|
recordWrittenFile: (path) => set((s) => ({ writtenFiles: [...s.writtenFiles, path] })),
|
|
358
361
|
clearWrittenFiles: () => set({ writtenFiles: [] }),
|
|
359
|
-
isCommandApproved: (command, cwd) => get().approvedCommands.has(
|
|
362
|
+
isCommandApproved: (command, cwd) => get().approvedCommands.has(commandApprovalKey(command, cwd)),
|
|
360
363
|
approveCommand: (command, cwd) => set((s) => ({
|
|
361
|
-
approvedCommands: new Set(s.approvedCommands).add(
|
|
364
|
+
approvedCommands: new Set(s.approvedCommands).add(
|
|
365
|
+
commandApprovalKey(command, cwd)
|
|
366
|
+
)
|
|
362
367
|
})),
|
|
368
|
+
revokeCommand: (command, cwd) => set((s) => {
|
|
369
|
+
const approvedCommands = new Set(s.approvedCommands);
|
|
370
|
+
approvedCommands.delete(commandApprovalKey(command, cwd));
|
|
371
|
+
return { approvedCommands };
|
|
372
|
+
}),
|
|
363
373
|
logStart: (kind, name, input) => {
|
|
364
374
|
const id = nanoid();
|
|
365
375
|
set((s) => ({
|
|
@@ -641,10 +651,9 @@ function Notices({
|
|
|
641
651
|
}
|
|
642
652
|
|
|
643
653
|
// src/ui/PromptInput.tsx
|
|
644
|
-
import { Box as Box9, Text as
|
|
654
|
+
import { Box as Box9, Text as Text10 } from "ink";
|
|
645
655
|
import Spinner from "ink-spinner";
|
|
646
|
-
import
|
|
647
|
-
import { useState as useState6 } from "react";
|
|
656
|
+
import { useState as useState7 } from "react";
|
|
648
657
|
|
|
649
658
|
// src/ui/CommandApproval.tsx
|
|
650
659
|
import { Box as Box6, Text as Text6 } from "ink";
|
|
@@ -739,9 +748,11 @@ function DecisionSelect({
|
|
|
739
748
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
740
749
|
function CommandApproval({
|
|
741
750
|
command,
|
|
751
|
+
messages,
|
|
742
752
|
onDecide
|
|
743
753
|
}) {
|
|
744
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}`)),
|
|
745
756
|
/* @__PURE__ */ jsx5(Text6, { color: COLORS.primary, bold: true, children: "Run this command?" }),
|
|
746
757
|
/* @__PURE__ */ jsxs5(
|
|
747
758
|
Box6,
|
|
@@ -783,14 +794,62 @@ function CommandApproval({
|
|
|
783
794
|
] });
|
|
784
795
|
}
|
|
785
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
|
+
|
|
786
845
|
// src/ui/SelectPrompt.tsx
|
|
787
|
-
import { Box as Box8, Text as
|
|
788
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as
|
|
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";
|
|
789
848
|
|
|
790
849
|
// src/ui/ScrollView.tsx
|
|
791
|
-
import { Box as Box7, Text as
|
|
792
|
-
import { useCallback, useLayoutEffect, useRef as useRef2, useState as
|
|
793
|
-
import { jsxs as
|
|
850
|
+
import { Box as Box7, Text as Text8, measureElement as measureElement2, useWindowSize as useWindowSize3 } from "ink";
|
|
851
|
+
import { useCallback, useLayoutEffect, useRef as useRef2, useState as useState5 } from "react";
|
|
852
|
+
import { jsxs as jsxs7 } from "react/jsx-runtime";
|
|
794
853
|
var INDICATOR_ROWS = 2;
|
|
795
854
|
function fittedWidth(node, columns) {
|
|
796
855
|
let left = 0;
|
|
@@ -806,7 +865,7 @@ function useScrollWindow({
|
|
|
806
865
|
}) {
|
|
807
866
|
const viewportRef = useRef2(null);
|
|
808
867
|
const { columns } = useWindowSize3();
|
|
809
|
-
const [size, setSize] =
|
|
868
|
+
const [size, setSize] = useState5(
|
|
810
869
|
null
|
|
811
870
|
);
|
|
812
871
|
useLayoutEffect(() => {
|
|
@@ -819,7 +878,7 @@ function useScrollWindow({
|
|
|
819
878
|
});
|
|
820
879
|
const capacity = size === null || itemCount * rowHeight <= size.height ? itemCount : Math.max(Math.floor((size.height - INDICATOR_ROWS) / rowHeight), 1);
|
|
821
880
|
const maxOffset = Math.max(itemCount - capacity, 0);
|
|
822
|
-
const [offset, setOffset] =
|
|
881
|
+
const [offset, setOffset] = useState5(0);
|
|
823
882
|
const prevMaxOffsetRef = useRef2(0);
|
|
824
883
|
useLayoutEffect(() => {
|
|
825
884
|
const wasAtBottom = offset >= prevMaxOffsetRef.current;
|
|
@@ -861,14 +920,14 @@ function useScrollWindow({
|
|
|
861
920
|
};
|
|
862
921
|
}
|
|
863
922
|
function ScrollView({ scroll, children }) {
|
|
864
|
-
return /* @__PURE__ */
|
|
865
|
-
scroll.hiddenAbove > 0 && /* @__PURE__ */
|
|
923
|
+
return /* @__PURE__ */ jsxs7(Box7, { ref: scroll.viewportRef, flexDirection: "column", flexGrow: 1, children: [
|
|
924
|
+
scroll.hiddenAbove > 0 && /* @__PURE__ */ jsxs7(Text8, { color: COLORS.dim, children: [
|
|
866
925
|
"\u2191 ",
|
|
867
926
|
scroll.hiddenAbove,
|
|
868
927
|
" more"
|
|
869
928
|
] }),
|
|
870
929
|
children,
|
|
871
|
-
scroll.hiddenBelow > 0 && /* @__PURE__ */
|
|
930
|
+
scroll.hiddenBelow > 0 && /* @__PURE__ */ jsxs7(Text8, { color: COLORS.dim, children: [
|
|
872
931
|
"\u2193 ",
|
|
873
932
|
scroll.hiddenBelow,
|
|
874
933
|
" more"
|
|
@@ -877,7 +936,7 @@ function ScrollView({ scroll, children }) {
|
|
|
877
936
|
}
|
|
878
937
|
|
|
879
938
|
// src/ui/SelectPrompt.tsx
|
|
880
|
-
import { jsx as
|
|
939
|
+
import { jsx as jsx7, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
881
940
|
var CANCEL = "cancel";
|
|
882
941
|
var ARROW_WIDTH = 4;
|
|
883
942
|
var COLUMN_GAP = 2;
|
|
@@ -909,18 +968,18 @@ function SelectPrompt({
|
|
|
909
968
|
const rows = hasCancel ? [...options, "Cancel"] : options;
|
|
910
969
|
const cancelIndex = hasCancel ? options.length : -1;
|
|
911
970
|
const isDisabled = (i) => i !== cancelIndex && Boolean(disabled?.[i]);
|
|
912
|
-
const [index, setIndex] =
|
|
971
|
+
const [index, setIndex] = useState6(() => {
|
|
913
972
|
const start = defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0;
|
|
914
973
|
return isDisabled(start) ? nextSelectableIndex(start, 1, rows.length, isDisabled) : start;
|
|
915
974
|
});
|
|
916
|
-
const [checked, setChecked] =
|
|
975
|
+
const [checked, setChecked] = useState6(() => /* @__PURE__ */ new Set());
|
|
917
976
|
const hints = [];
|
|
918
977
|
if (rows.length > 1) hints.push({ key: "[\u2191] [\u2193]", label: "move" });
|
|
919
978
|
if (multi) hints.push({ key: "[space]", label: "select" });
|
|
920
979
|
hints.push({ key: "[enter]", label: "confirm" });
|
|
921
980
|
const containerRef = useRef3(null);
|
|
922
981
|
const { columns } = useWindowSize4();
|
|
923
|
-
const [width, setWidth] =
|
|
982
|
+
const [width, setWidth] = useState6(columns);
|
|
924
983
|
useLayoutEffect2(() => {
|
|
925
984
|
if (!containerRef.current) return;
|
|
926
985
|
const measured = fittedWidth(containerRef.current, columns);
|
|
@@ -950,7 +1009,7 @@ function SelectPrompt({
|
|
|
950
1009
|
revealIndex(index);
|
|
951
1010
|
}, [index, revealIndex]);
|
|
952
1011
|
const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
953
|
-
|
|
1012
|
+
useInput3((input, key) => {
|
|
954
1013
|
if (rows.length === 0) return;
|
|
955
1014
|
if (key.upArrow || input === "k") {
|
|
956
1015
|
setIndex((i) => nextSelectableIndex(i, -1, rows.length, isDisabled));
|
|
@@ -975,17 +1034,17 @@ function SelectPrompt({
|
|
|
975
1034
|
}
|
|
976
1035
|
}
|
|
977
1036
|
});
|
|
978
|
-
return /* @__PURE__ */
|
|
979
|
-
/* @__PURE__ */
|
|
980
|
-
error && /* @__PURE__ */
|
|
981
|
-
messages?.map((m, i) => /* @__PURE__ */
|
|
982
|
-
table && /* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
984
|
-
question && /* @__PURE__ */
|
|
985
|
-
helpText && /* @__PURE__ */
|
|
1037
|
+
return /* @__PURE__ */ jsx7(Box8, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, width, children: [
|
|
1038
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, flexShrink: 0, children: [
|
|
1039
|
+
error && /* @__PURE__ */ jsx7(Text9, { color: COLORS.danger, children: error }),
|
|
1040
|
+
messages?.map((m, i) => /* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
1041
|
+
table && /* @__PURE__ */ jsx7(Table, { columns: table.columns, rows: table.rows }),
|
|
1042
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1043
|
+
question && /* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: question }),
|
|
1044
|
+
helpText && /* @__PURE__ */ jsx7(Text9, { color: COLORS.dim, children: helpText })
|
|
986
1045
|
] })
|
|
987
1046
|
] }),
|
|
988
|
-
/* @__PURE__ */
|
|
1047
|
+
/* @__PURE__ */ jsx7(ScrollView, { scroll, children: visible.map((option, visibleIndex) => {
|
|
989
1048
|
const i = scroll.offset + visibleIndex;
|
|
990
1049
|
const highlighted = i === index;
|
|
991
1050
|
const isCancel = i === cancelIndex;
|
|
@@ -993,7 +1052,7 @@ function SelectPrompt({
|
|
|
993
1052
|
const sec = isCancel ? void 0 : secondary?.[i];
|
|
994
1053
|
const isText = sec?.kind === "text";
|
|
995
1054
|
const rowDisabled = isDisabled(i);
|
|
996
|
-
return /* @__PURE__ */
|
|
1055
|
+
return /* @__PURE__ */ jsxs8(
|
|
997
1056
|
SelectRow,
|
|
998
1057
|
{
|
|
999
1058
|
highlighted,
|
|
@@ -1003,24 +1062,24 @@ function SelectPrompt({
|
|
|
1003
1062
|
label: `${bullet}${option}`,
|
|
1004
1063
|
usePadding: true,
|
|
1005
1064
|
children: [
|
|
1006
|
-
isText && textWidth > 0 && /* @__PURE__ */
|
|
1007
|
-
|
|
1065
|
+
isText && textWidth > 0 && /* @__PURE__ */ jsx7(Box8, { width: textWidth, children: /* @__PURE__ */ jsx7(
|
|
1066
|
+
Text9,
|
|
1008
1067
|
{
|
|
1009
1068
|
wrap: "truncate",
|
|
1010
1069
|
color: rowDisabled ? COLORS.dim : highlighted ? COLORS.primary : COLORS.muted,
|
|
1011
1070
|
children: sec.value
|
|
1012
1071
|
}
|
|
1013
1072
|
) }),
|
|
1014
|
-
sec?.kind === "badge" && /* @__PURE__ */
|
|
1073
|
+
sec?.kind === "badge" && /* @__PURE__ */ jsx7(Box8, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx7(Text9, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
|
|
1015
1074
|
]
|
|
1016
1075
|
},
|
|
1017
1076
|
`row-${i}`
|
|
1018
1077
|
);
|
|
1019
1078
|
}) }),
|
|
1020
|
-
/* @__PURE__ */
|
|
1079
|
+
/* @__PURE__ */ jsx7(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx7(Text9, { color: COLORS.dim, children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs8(Text9, { color: COLORS.dim, children: [
|
|
1021
1080
|
i > 0 ? " " : "",
|
|
1022
|
-
/* @__PURE__ */
|
|
1023
|
-
/* @__PURE__ */
|
|
1081
|
+
/* @__PURE__ */ jsx7(Text9, { color: COLORS.primary, children: key }),
|
|
1082
|
+
/* @__PURE__ */ jsxs8(Text9, { color: COLORS.dim, children: [
|
|
1024
1083
|
" ",
|
|
1025
1084
|
label
|
|
1026
1085
|
] })
|
|
@@ -1029,17 +1088,17 @@ function SelectPrompt({
|
|
|
1029
1088
|
}
|
|
1030
1089
|
|
|
1031
1090
|
// src/ui/PromptInput.tsx
|
|
1032
|
-
import { jsx as
|
|
1091
|
+
import { jsx as jsx8, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1033
1092
|
var ACCEPT_REJECT_OPTIONS = ["Accept", "Reject"];
|
|
1034
1093
|
function EnterToContinuePrompt({
|
|
1035
1094
|
question,
|
|
1036
1095
|
messages,
|
|
1037
1096
|
onDecide
|
|
1038
1097
|
}) {
|
|
1039
|
-
return /* @__PURE__ */
|
|
1040
|
-
messages?.map((m, i) => /* @__PURE__ */
|
|
1041
|
-
question && /* @__PURE__ */
|
|
1042
|
-
/* @__PURE__ */
|
|
1098
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, children: [
|
|
1099
|
+
messages?.map((m, i) => /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
1100
|
+
question && /* @__PURE__ */ jsx8(Text10, { color: COLORS.primary, children: question }),
|
|
1101
|
+
/* @__PURE__ */ jsx8(
|
|
1043
1102
|
DecisionSelect,
|
|
1044
1103
|
{
|
|
1045
1104
|
actions: [
|
|
@@ -1053,17 +1112,17 @@ function EnterToContinuePrompt({
|
|
|
1053
1112
|
}
|
|
1054
1113
|
function PromptInput() {
|
|
1055
1114
|
const { phase, inputReq, submitInput } = useWizard();
|
|
1056
|
-
const [draft, setDraft] =
|
|
1057
|
-
const [submittedReq, setSubmittedReq] =
|
|
1115
|
+
const [draft, setDraft] = useState7("");
|
|
1116
|
+
const [submittedReq, setSubmittedReq] = useState7(null);
|
|
1058
1117
|
const promptKey = inputReq && `${inputReq.promptType}:${inputReq.prompt}`;
|
|
1059
1118
|
const submitting = inputReq != null && submittedReq === inputReq;
|
|
1060
1119
|
if (phase === "done" || phase === "error") {
|
|
1061
|
-
return /* @__PURE__ */
|
|
1120
|
+
return /* @__PURE__ */ jsx8(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text10, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
|
|
1062
1121
|
}
|
|
1063
1122
|
if (phase !== "awaitingInput" || !inputReq) return null;
|
|
1064
1123
|
if (submitting) {
|
|
1065
|
-
return /* @__PURE__ */
|
|
1066
|
-
/* @__PURE__ */
|
|
1124
|
+
return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsxs9(Text10, { color: COLORS.strong, bold: true, children: [
|
|
1125
|
+
/* @__PURE__ */ jsx8(Spinner, { type: "dots" }),
|
|
1067
1126
|
" Continuing\u2026"
|
|
1068
1127
|
] }) });
|
|
1069
1128
|
}
|
|
@@ -1072,7 +1131,7 @@ function PromptInput() {
|
|
|
1072
1131
|
submitInput(value);
|
|
1073
1132
|
};
|
|
1074
1133
|
if (inputReq.promptType === "multipleChoice") {
|
|
1075
|
-
return /* @__PURE__ */
|
|
1134
|
+
return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx8(
|
|
1076
1135
|
SelectPrompt,
|
|
1077
1136
|
{
|
|
1078
1137
|
question: inputReq.prompt,
|
|
@@ -1091,7 +1150,7 @@ function PromptInput() {
|
|
|
1091
1150
|
) });
|
|
1092
1151
|
}
|
|
1093
1152
|
if (inputReq.promptType === "multiSelect") {
|
|
1094
|
-
return /* @__PURE__ */
|
|
1153
|
+
return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx8(
|
|
1095
1154
|
SelectPrompt,
|
|
1096
1155
|
{
|
|
1097
1156
|
multi: true,
|
|
@@ -1107,10 +1166,9 @@ function PromptInput() {
|
|
|
1107
1166
|
) });
|
|
1108
1167
|
}
|
|
1109
1168
|
if (inputReq.promptType === "notice") {
|
|
1110
|
-
return /* @__PURE__ */
|
|
1169
|
+
return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx8(
|
|
1111
1170
|
SelectPrompt,
|
|
1112
1171
|
{
|
|
1113
|
-
question: inputReq.prompt,
|
|
1114
1172
|
messages: inputReq.messages,
|
|
1115
1173
|
options: ["Continue"],
|
|
1116
1174
|
onSelect: handleSubmit
|
|
@@ -1119,7 +1177,7 @@ function PromptInput() {
|
|
|
1119
1177
|
) });
|
|
1120
1178
|
}
|
|
1121
1179
|
if (inputReq.promptType === "enterToContinue") {
|
|
1122
|
-
return /* @__PURE__ */
|
|
1180
|
+
return /* @__PURE__ */ jsx8(
|
|
1123
1181
|
EnterToContinuePrompt,
|
|
1124
1182
|
{
|
|
1125
1183
|
question: inputReq.prompt,
|
|
@@ -1129,11 +1187,18 @@ function PromptInput() {
|
|
|
1129
1187
|
);
|
|
1130
1188
|
}
|
|
1131
1189
|
if (inputReq.promptType === "commandApproval" && inputReq.command) {
|
|
1132
|
-
return /* @__PURE__ */
|
|
1190
|
+
return /* @__PURE__ */ jsx8(
|
|
1191
|
+
CommandApproval,
|
|
1192
|
+
{
|
|
1193
|
+
command: inputReq.command,
|
|
1194
|
+
messages: inputReq.messages,
|
|
1195
|
+
onDecide: submitInput
|
|
1196
|
+
}
|
|
1197
|
+
);
|
|
1133
1198
|
}
|
|
1134
1199
|
if (inputReq.promptType === "acceptReject") {
|
|
1135
1200
|
const labels = inputReq.options?.length ? inputReq.options : ACCEPT_REJECT_OPTIONS;
|
|
1136
|
-
return /* @__PURE__ */
|
|
1201
|
+
return /* @__PURE__ */ jsx8(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx8(
|
|
1137
1202
|
SelectPrompt,
|
|
1138
1203
|
{
|
|
1139
1204
|
question: inputReq.prompt,
|
|
@@ -1145,16 +1210,16 @@ function PromptInput() {
|
|
|
1145
1210
|
promptKey
|
|
1146
1211
|
) });
|
|
1147
1212
|
}
|
|
1148
|
-
return /* @__PURE__ */
|
|
1149
|
-
inputReq.error && /* @__PURE__ */
|
|
1150
|
-
inputReq.messages?.map((m, i) => /* @__PURE__ */
|
|
1151
|
-
/* @__PURE__ */
|
|
1152
|
-
/* @__PURE__ */
|
|
1213
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
1214
|
+
inputReq.error && /* @__PURE__ */ jsx8(Text10, { color: COLORS.danger, children: inputReq.error }),
|
|
1215
|
+
inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
1216
|
+
/* @__PURE__ */ jsxs9(Box9, { children: [
|
|
1217
|
+
/* @__PURE__ */ jsxs9(Text10, { color: COLORS.primary, children: [
|
|
1153
1218
|
inputReq.prompt,
|
|
1154
1219
|
" "
|
|
1155
1220
|
] }),
|
|
1156
|
-
/* @__PURE__ */
|
|
1157
|
-
|
|
1221
|
+
/* @__PURE__ */ jsx8(
|
|
1222
|
+
FreeTextInput,
|
|
1158
1223
|
{
|
|
1159
1224
|
value: draft,
|
|
1160
1225
|
onChange: setDraft,
|
|
@@ -1163,15 +1228,15 @@ function PromptInput() {
|
|
|
1163
1228
|
setDraft("");
|
|
1164
1229
|
}
|
|
1165
1230
|
}
|
|
1166
|
-
)
|
|
1231
|
+
)
|
|
1167
1232
|
] })
|
|
1168
1233
|
] });
|
|
1169
1234
|
}
|
|
1170
1235
|
|
|
1171
1236
|
// src/ui/Review.tsx
|
|
1172
|
-
import { Box as Box10, Text as
|
|
1173
|
-
import { useLayoutEffect as useLayoutEffect3, useState as
|
|
1174
|
-
import { jsx as
|
|
1237
|
+
import { Box as Box10, Text as Text11, useInput as useInput4 } from "ink";
|
|
1238
|
+
import { useLayoutEffect as useLayoutEffect3, useState as useState8 } from "react";
|
|
1239
|
+
import { jsx as jsx9, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1175
1240
|
var INGEST_SCRIPT = ".algolia-wizard/ingest.sh";
|
|
1176
1241
|
function wrapText(text, width) {
|
|
1177
1242
|
if (width <= 0) return [text];
|
|
@@ -1254,14 +1319,14 @@ function buildRows(review2, width) {
|
|
|
1254
1319
|
return rows;
|
|
1255
1320
|
}
|
|
1256
1321
|
function ReviewPanel({ review: review2 }) {
|
|
1257
|
-
const [width, setWidth] =
|
|
1322
|
+
const [width, setWidth] = useState8(0);
|
|
1258
1323
|
const rows = width > 0 ? buildRows(review2, width) : [];
|
|
1259
1324
|
const scroll = useScrollWindow({ itemCount: rows.length });
|
|
1260
1325
|
useLayoutEffect3(() => {
|
|
1261
1326
|
if (scroll.measured) setWidth(scroll.width);
|
|
1262
1327
|
}, [scroll.measured, scroll.width]);
|
|
1263
1328
|
const scrollable = scroll.maxOffset > 0;
|
|
1264
|
-
|
|
1329
|
+
useInput4(
|
|
1265
1330
|
(_input, key) => {
|
|
1266
1331
|
if (key.upArrow) scroll.scrollBy(-1);
|
|
1267
1332
|
else if (key.downArrow) scroll.scrollBy(1);
|
|
@@ -1269,18 +1334,18 @@ function ReviewPanel({ review: review2 }) {
|
|
|
1269
1334
|
{ isActive: scrollable }
|
|
1270
1335
|
);
|
|
1271
1336
|
const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
1272
|
-
return /* @__PURE__ */
|
|
1273
|
-
/* @__PURE__ */
|
|
1274
|
-
row.prefix && /* @__PURE__ */
|
|
1275
|
-
/* @__PURE__ */
|
|
1337
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", flexGrow: 1, children: [
|
|
1338
|
+
/* @__PURE__ */ jsx9(ScrollView, { scroll, children: visible.map((row, i) => /* @__PURE__ */ jsxs10(Text11, { wrap: "truncate", children: [
|
|
1339
|
+
row.prefix && /* @__PURE__ */ jsx9(Text11, { color: row.prefixColor ?? row.color, bold: row.bold, children: row.prefix }),
|
|
1340
|
+
/* @__PURE__ */ jsx9(Text11, { color: row.color, bold: row.bold, children: row.text })
|
|
1276
1341
|
] }, `review-row-${i}`)) }),
|
|
1277
|
-
scrollable && /* @__PURE__ */
|
|
1342
|
+
scrollable && /* @__PURE__ */ jsx9(Text11, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
|
|
1278
1343
|
] });
|
|
1279
1344
|
}
|
|
1280
1345
|
function Review() {
|
|
1281
1346
|
const review2 = useWizard((s) => s.review);
|
|
1282
1347
|
if (!review2) return null;
|
|
1283
|
-
return /* @__PURE__ */
|
|
1348
|
+
return /* @__PURE__ */ jsx9(ReviewPanel, { review: review2 });
|
|
1284
1349
|
}
|
|
1285
1350
|
|
|
1286
1351
|
// src/workflows/default.ts
|
|
@@ -2651,9 +2716,16 @@ function searchFilesTool(ctx) {
|
|
|
2651
2716
|
}
|
|
2652
2717
|
|
|
2653
2718
|
// src/lib/tools/runShell.ts
|
|
2654
|
-
import { tool as
|
|
2719
|
+
import { tool as tool9, generateText, Output } from "ai";
|
|
2655
2720
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2721
|
+
import z16 from "zod";
|
|
2722
|
+
import { relative as relative5 } from "node:path";
|
|
2723
|
+
|
|
2724
|
+
// src/lib/tools/reviewScript.ts
|
|
2725
|
+
import { tool as tool8 } from "ai";
|
|
2656
2726
|
import z15 from "zod";
|
|
2727
|
+
import { createHash } from "node:crypto";
|
|
2728
|
+
import { readFile as readFile7, stat as stat2 } from "node:fs/promises";
|
|
2657
2729
|
import { relative as relative4 } from "node:path";
|
|
2658
2730
|
|
|
2659
2731
|
// src/lib/tools/utils/prompt.ts
|
|
@@ -2665,6 +2737,116 @@ function serializePrompt(work) {
|
|
|
2665
2737
|
return result;
|
|
2666
2738
|
}
|
|
2667
2739
|
|
|
2740
|
+
// src/lib/tools/reviewScript.ts
|
|
2741
|
+
var reviewedCommandApprovals = /* @__PURE__ */ new WeakMap();
|
|
2742
|
+
async function fileDigest(filePath) {
|
|
2743
|
+
const content = await readFile7(filePath);
|
|
2744
|
+
return createHash("sha256").update(content).digest("hex");
|
|
2745
|
+
}
|
|
2746
|
+
function grantReviewedCommandApproval(ctx, approval) {
|
|
2747
|
+
reviewedCommandApprovals.set(ctx, approval);
|
|
2748
|
+
}
|
|
2749
|
+
function getReviewedCommandApproval(ctx, command, cwd) {
|
|
2750
|
+
const approval = reviewedCommandApprovals.get(ctx);
|
|
2751
|
+
if (approval?.command !== command || approval.cwd !== cwd) return void 0;
|
|
2752
|
+
return approval;
|
|
2753
|
+
}
|
|
2754
|
+
function clearReviewedCommandApproval(ctx) {
|
|
2755
|
+
reviewedCommandApprovals.delete(ctx);
|
|
2756
|
+
}
|
|
2757
|
+
function revokeCommandApprovals(ctx, command, cwd) {
|
|
2758
|
+
clearReviewedCommandApproval(ctx);
|
|
2759
|
+
useWizard.getState().revokeCommand(command, cwd);
|
|
2760
|
+
}
|
|
2761
|
+
async function reviewedCommandApprovalIsCurrent(approval) {
|
|
2762
|
+
const currentDigest = await fileDigest(approval.filePath).catch(() => null);
|
|
2763
|
+
return currentDigest === approval.digest;
|
|
2764
|
+
}
|
|
2765
|
+
function reviewScriptTool(ctx) {
|
|
2766
|
+
return tool8({
|
|
2767
|
+
description: "Call this as soon as the ingestion script is finished and before you run it. It summarizes the records that will be written, then asks the user to review the script and approve the exact command that will run it, so a matching runShell call needs no second approval.",
|
|
2768
|
+
inputSchema: z15.object({
|
|
2769
|
+
filePath: z15.string().describe(
|
|
2770
|
+
"Path to the script to review, relative to the project root."
|
|
2771
|
+
),
|
|
2772
|
+
command: z15.string().min(1).describe("The exact command that runShell will use to run the script."),
|
|
2773
|
+
cwd: z15.string().describe(
|
|
2774
|
+
"The exact working directory that runShell will use, relative to the current tool working directory."
|
|
2775
|
+
),
|
|
2776
|
+
entityName: z15.string().trim().min(1).max(100).regex(/^[^\r\n]+$/).describe("The exact entity name selected by the user."),
|
|
2777
|
+
usesGeneratedRecords: z15.boolean().describe(
|
|
2778
|
+
"Whether the script reads generated sample records instead of the selected real data source."
|
|
2779
|
+
)
|
|
2780
|
+
}),
|
|
2781
|
+
execute: async ({
|
|
2782
|
+
filePath,
|
|
2783
|
+
command,
|
|
2784
|
+
cwd,
|
|
2785
|
+
entityName,
|
|
2786
|
+
usesGeneratedRecords
|
|
2787
|
+
}) => {
|
|
2788
|
+
logger.info(
|
|
2789
|
+
{ filePath, command, cwd, entityName, usesGeneratedRecords },
|
|
2790
|
+
"called reviewScript tool"
|
|
2791
|
+
);
|
|
2792
|
+
const resolved2 = resolveInRoot(ctx, filePath);
|
|
2793
|
+
if (resolved2.ok === false) return resolved2.error;
|
|
2794
|
+
const resolvedCwd = resolveInRoot(ctx, cwd);
|
|
2795
|
+
if (resolvedCwd.ok === false) return resolvedCwd.error;
|
|
2796
|
+
const displayCwd = relative4(ctx.root, resolvedCwd.target) || ".";
|
|
2797
|
+
const displayFilePath = relative4(ctx.root, resolved2.target);
|
|
2798
|
+
const ingestionSummary = usesGeneratedRecords ? `This will push ${entityName} records from generated sample data to Algolia. You can replace the sample dataset with your real data source in ${displayFilePath}.` : `This will push ${entityName} records from your selected source to Algolia.`;
|
|
2799
|
+
return serializePrompt(async () => {
|
|
2800
|
+
revokeCommandApprovals(ctx, command, resolvedCwd.target);
|
|
2801
|
+
const isFile = await stat2(resolved2.target).then(
|
|
2802
|
+
(s) => s.isFile(),
|
|
2803
|
+
() => false
|
|
2804
|
+
);
|
|
2805
|
+
if (!isFile) {
|
|
2806
|
+
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
2807
|
+
}
|
|
2808
|
+
const reviewedDigest = await fileDigest(resolved2.target).catch(
|
|
2809
|
+
() => null
|
|
2810
|
+
);
|
|
2811
|
+
if (reviewedDigest === null) {
|
|
2812
|
+
return `Refused: ${filePath} could not be read. Write the script first, then review it again.`;
|
|
2813
|
+
}
|
|
2814
|
+
const answer = await useWizard.getState().requestUserInput({
|
|
2815
|
+
prompt: "Run this command?",
|
|
2816
|
+
promptType: "commandApproval",
|
|
2817
|
+
options: [],
|
|
2818
|
+
messages: [
|
|
2819
|
+
`We have created your ingestion script. Please review it at ${displayFilePath} before approving.`
|
|
2820
|
+
],
|
|
2821
|
+
command: {
|
|
2822
|
+
command,
|
|
2823
|
+
cwd: displayCwd,
|
|
2824
|
+
explanation: ingestionSummary
|
|
2825
|
+
}
|
|
2826
|
+
});
|
|
2827
|
+
if (answer !== "approve") {
|
|
2828
|
+
revokeCommandApprovals(ctx, command, resolvedCwd.target);
|
|
2829
|
+
return "The user declined to run this ingestion script. Do not run it.";
|
|
2830
|
+
}
|
|
2831
|
+
const approvedDigest = await fileDigest(resolved2.target).catch(
|
|
2832
|
+
() => null
|
|
2833
|
+
);
|
|
2834
|
+
if (approvedDigest !== reviewedDigest) {
|
|
2835
|
+
return "The ingestion script changed while it was being reviewed. Call reviewScript again before running it.";
|
|
2836
|
+
}
|
|
2837
|
+
ctx.reviewed.push(resolved2.target);
|
|
2838
|
+
grantReviewedCommandApproval(ctx, {
|
|
2839
|
+
command,
|
|
2840
|
+
cwd: resolvedCwd.target,
|
|
2841
|
+
filePath: resolved2.target,
|
|
2842
|
+
digest: reviewedDigest
|
|
2843
|
+
});
|
|
2844
|
+
return "The user reviewed the script and approved this exact command. Run it now with the same cwd.";
|
|
2845
|
+
});
|
|
2846
|
+
}
|
|
2847
|
+
});
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2668
2850
|
// src/lib/tools/utils/runShell.ts
|
|
2669
2851
|
import { spawn as spawn2 } from "node:child_process";
|
|
2670
2852
|
|
|
@@ -2763,7 +2945,7 @@ function storeApproval(root) {
|
|
|
2763
2945
|
return async (req) => {
|
|
2764
2946
|
const store = useWizard.getState();
|
|
2765
2947
|
if (store.isCommandApproved(req.command, req.cwd)) return "approve";
|
|
2766
|
-
const rel =
|
|
2948
|
+
const rel = relative5(root, req.cwd);
|
|
2767
2949
|
const answer = await store.requestUserInput({
|
|
2768
2950
|
prompt: "Run this command?",
|
|
2769
2951
|
promptType: "commandApproval",
|
|
@@ -2778,6 +2960,7 @@ function storeApproval(root) {
|
|
|
2778
2960
|
return "approve";
|
|
2779
2961
|
};
|
|
2780
2962
|
}
|
|
2963
|
+
var SUCCESS_EXIT_CODE = 0;
|
|
2781
2964
|
var FILE_IO_COMMANDS = /* @__PURE__ */ new Set([
|
|
2782
2965
|
"ls",
|
|
2783
2966
|
"find",
|
|
@@ -2916,9 +3099,9 @@ function fastPathSafety(command) {
|
|
|
2916
3099
|
return void 0;
|
|
2917
3100
|
}
|
|
2918
3101
|
var CLASSIFIER_MODEL = "claude-haiku-4-5";
|
|
2919
|
-
var commandSafetySchema =
|
|
2920
|
-
safe:
|
|
2921
|
-
reason:
|
|
3102
|
+
var commandSafetySchema = z16.object({
|
|
3103
|
+
safe: z16.boolean(),
|
|
3104
|
+
reason: z16.string().describe("One short sentence explaining the verdict.")
|
|
2922
3105
|
});
|
|
2923
3106
|
function defaultCreateModel() {
|
|
2924
3107
|
const token = getAuthToken();
|
|
@@ -2978,12 +3161,15 @@ async function classifyCommandSafety(createModel, command, cwd, explanation, app
|
|
|
2978
3161
|
return false;
|
|
2979
3162
|
}
|
|
2980
3163
|
}
|
|
2981
|
-
async function
|
|
2982
|
-
|
|
2983
|
-
const env = await ctx.shell.env().catch((err) => {
|
|
3164
|
+
async function resolveShellEnv(ctx, command) {
|
|
3165
|
+
return ctx.shell.env().catch((err) => {
|
|
2984
3166
|
logger.warn({ err, command }, "runShell: could not resolve command env");
|
|
2985
3167
|
return {};
|
|
2986
3168
|
});
|
|
3169
|
+
}
|
|
3170
|
+
async function runAndRecord(ctx, command, cwd, resolvedEnv) {
|
|
3171
|
+
useWizard.getState().pushNotice({ messages: [`Running: ${command}`] });
|
|
3172
|
+
const env = resolvedEnv ?? await resolveShellEnv(ctx, command);
|
|
2987
3173
|
const run2 = await (ctx.shell.run ?? runShell)(command, {
|
|
2988
3174
|
cwd,
|
|
2989
3175
|
env,
|
|
@@ -3014,6 +3200,19 @@ async function runAndRecord(ctx, command, cwd) {
|
|
|
3014
3200
|
output: run2.output
|
|
3015
3201
|
};
|
|
3016
3202
|
}
|
|
3203
|
+
async function runReviewedCommand(ctx, command, cwd) {
|
|
3204
|
+
const approval = getReviewedCommandApproval(ctx, command, cwd);
|
|
3205
|
+
if (!approval) return void 0;
|
|
3206
|
+
const env = await resolveShellEnv(ctx, command);
|
|
3207
|
+
if (!await reviewedCommandApprovalIsCurrent(approval)) {
|
|
3208
|
+
return `Refused: ${relative5(ctx.root, approval.filePath)} changed after review. Call reviewScript again before running it.`;
|
|
3209
|
+
}
|
|
3210
|
+
const result = await runAndRecord(ctx, command, cwd, env);
|
|
3211
|
+
if (result.exitCode === SUCCESS_EXIT_CODE && !result.timedOut) {
|
|
3212
|
+
clearReviewedCommandApproval(ctx);
|
|
3213
|
+
}
|
|
3214
|
+
return result;
|
|
3215
|
+
}
|
|
3017
3216
|
async function approveAndRun(ctx, command, cwd, explanation) {
|
|
3018
3217
|
const decision = await ctx.shell.approve({ command, cwd, explanation });
|
|
3019
3218
|
if (decision === "reject") {
|
|
@@ -3024,16 +3223,16 @@ async function approveAndRun(ctx, command, cwd, explanation) {
|
|
|
3024
3223
|
return runAndRecord(ctx, command, cwd);
|
|
3025
3224
|
}
|
|
3026
3225
|
function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
3027
|
-
return
|
|
3226
|
+
return tool9({
|
|
3028
3227
|
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. Do not use this to find or read files \u2014 use listFiles, searchFiles, and readFile instead of shell file-listing, reading, or search commands (ls/find/tree/cat/head/tail/grep/rg and similar). This tool refuses all of those outright: the dedicated tools enforce the project-root boundary and secret redaction that a raw shell read would bypass, and they won't count against this tool's command budget. The user approves any command that could change the project before it runs, so write a clear `explanation`. A command judged read-only (inspection, or running tests/typecheck/lint without an autofix flag, in any language) runs immediately without approval. If the user rejects a command, do not retry it \u2014 propose a different approach.",
|
|
3029
|
-
inputSchema:
|
|
3030
|
-
command:
|
|
3228
|
+
inputSchema: z16.object({
|
|
3229
|
+
command: z16.string().describe(
|
|
3031
3230
|
"The command to run, exactly as it would be typed in a shell. Pipes, && and redirects are allowed."
|
|
3032
3231
|
),
|
|
3033
|
-
cwd:
|
|
3232
|
+
cwd: z16.string().optional().describe(
|
|
3034
3233
|
"Directory to run in, relative to the project root. Defaults to the project root."
|
|
3035
3234
|
),
|
|
3036
|
-
explanation:
|
|
3235
|
+
explanation: z16.string().describe(
|
|
3037
3236
|
"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."
|
|
3038
3237
|
)
|
|
3039
3238
|
}),
|
|
@@ -3042,16 +3241,22 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
3042
3241
|
return `Refused: command limit (${ctx.limits.shell}) reached. Stop running commands and report what you have.`;
|
|
3043
3242
|
}
|
|
3044
3243
|
const resolved2 = resolveInRoot(ctx, cwd ?? ".");
|
|
3045
|
-
if (
|
|
3244
|
+
if (resolved2.ok === false) return resolved2.error;
|
|
3046
3245
|
if (isFileIOCommand(command)) {
|
|
3047
3246
|
return "Refused: use listFiles or searchFiles to find files, and readFile to read one, instead of a shell file-listing, reading, or search command (ls/find/fd/tree/dir/locate/cat/head/tail/less/more/tac/nl/grep/egrep/fgrep/rg/ack/ag/xxd/hexdump/od/strings).";
|
|
3048
3247
|
}
|
|
3049
3248
|
logger.info({ command, cwd: resolved2.target }, "called runShell tool");
|
|
3249
|
+
const reviewed = await serializePrompt(
|
|
3250
|
+
() => runReviewedCommand(ctx, command, resolved2.target)
|
|
3251
|
+
);
|
|
3252
|
+
if (reviewed !== void 0) return reviewed;
|
|
3050
3253
|
const fast = fastPathSafety(command);
|
|
3051
3254
|
let isSafe = fast;
|
|
3255
|
+
let usedStoredApproval = false;
|
|
3052
3256
|
if (isSafe === void 0) {
|
|
3053
3257
|
const store = useWizard.getState();
|
|
3054
|
-
|
|
3258
|
+
usedStoredApproval = store.isCommandApproved(command, resolved2.target);
|
|
3259
|
+
isSafe = usedStoredApproval;
|
|
3055
3260
|
if (!isSafe) {
|
|
3056
3261
|
isSafe = await classifyCommandSafety(
|
|
3057
3262
|
createModel,
|
|
@@ -3062,54 +3267,18 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
3062
3267
|
);
|
|
3063
3268
|
}
|
|
3064
3269
|
}
|
|
3065
|
-
if (isSafe) {
|
|
3066
|
-
return serializePrompt(
|
|
3067
|
-
() => runAndRecord(ctx, command, resolved2.target)
|
|
3068
|
-
);
|
|
3069
|
-
}
|
|
3070
|
-
return serializePrompt(
|
|
3071
|
-
() => approveAndRun(ctx, command, resolved2.target, explanation)
|
|
3072
|
-
);
|
|
3073
|
-
}
|
|
3074
|
-
});
|
|
3075
|
-
}
|
|
3076
|
-
|
|
3077
|
-
// src/lib/tools/reviewScript.ts
|
|
3078
|
-
import { tool as tool9 } from "ai";
|
|
3079
|
-
import z16 from "zod";
|
|
3080
|
-
import { stat as stat2 } from "node:fs/promises";
|
|
3081
|
-
import { relative as relative5 } from "node:path";
|
|
3082
|
-
function reviewScriptTool(ctx) {
|
|
3083
|
-
return tool9({
|
|
3084
|
-
description: "Call this as soon as the ingestion script is finished and before you run it, so the user can review it.It shows the file path and returns once they have confirmed reviewing it.",
|
|
3085
|
-
inputSchema: z16.object({
|
|
3086
|
-
filePath: z16.string().describe(
|
|
3087
|
-
"Path to the script to review, relative to the project root."
|
|
3088
|
-
)
|
|
3089
|
-
}),
|
|
3090
|
-
execute: async ({ filePath }) => {
|
|
3091
|
-
logger.info({ filePath }, "called reviewScript tool");
|
|
3092
|
-
const resolved2 = resolveInRoot(ctx, filePath);
|
|
3093
|
-
if (resolved2.ok === false) return resolved2.error;
|
|
3094
|
-
const isFile = await stat2(resolved2.target).then(
|
|
3095
|
-
(s) => s.isFile(),
|
|
3096
|
-
() => false
|
|
3097
|
-
);
|
|
3098
|
-
if (!isFile) {
|
|
3099
|
-
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
3100
|
-
}
|
|
3101
3270
|
return serializePrompt(async () => {
|
|
3102
|
-
await
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
return
|
|
3271
|
+
const lateReview = await runReviewedCommand(
|
|
3272
|
+
ctx,
|
|
3273
|
+
command,
|
|
3274
|
+
resolved2.target
|
|
3275
|
+
);
|
|
3276
|
+
if (lateReview !== void 0) return lateReview;
|
|
3277
|
+
const storedApprovalIsCurrent = !usedStoredApproval || useWizard.getState().isCommandApproved(command, resolved2.target);
|
|
3278
|
+
if (isSafe && storedApprovalIsCurrent) {
|
|
3279
|
+
return runAndRecord(ctx, command, resolved2.target);
|
|
3280
|
+
}
|
|
3281
|
+
return approveAndRun(ctx, command, resolved2.target, explanation);
|
|
3113
3282
|
});
|
|
3114
3283
|
}
|
|
3115
3284
|
});
|
|
@@ -3604,7 +3773,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3604
3773
|
// package.json
|
|
3605
3774
|
var package_default = {
|
|
3606
3775
|
name: "@algolia/wizard",
|
|
3607
|
-
version: "0.
|
|
3776
|
+
version: "0.52.0-rc.136.364",
|
|
3608
3777
|
description: "Magically implement Algolia functionality in your codebase",
|
|
3609
3778
|
type: "module",
|
|
3610
3779
|
engines: {
|
|
@@ -3662,7 +3831,6 @@ var package_default = {
|
|
|
3662
3831
|
ink: "^7.0.5",
|
|
3663
3832
|
"ink-picture": "^2.1.0",
|
|
3664
3833
|
"ink-spinner": "^5.0.0",
|
|
3665
|
-
"ink-text-input": "^6.0.0",
|
|
3666
3834
|
ioredis: "^5.11.1",
|
|
3667
3835
|
nanoid: "^5.1.15",
|
|
3668
3836
|
pino: "^10.3.1",
|
|
@@ -4307,8 +4475,8 @@ function ingestionInstructions(input) {
|
|
|
4307
4475
|
...algoliaClientDoc(input),
|
|
4308
4476
|
"Install the Algolia client with the project's own package manager via runShell, declaring it in whatever manifest the project uses (e.g. package.json, requirements.txt, Gemfile, go.mod, composer.json) so the dependency is not just installed ad hoc.",
|
|
4309
4477
|
`If the script loads its env vars from a file (e.g. via dotenv or an equivalent for its language) rather than the process environment directly, decide that up front and call writeCredentials on that file before you finish the script \u2014 do not wait to discover the need for it by having a writeFile call refused.`,
|
|
4310
|
-
|
|
4311
|
-
'Then run the script yourself via runShell
|
|
4478
|
+
`When the script is finished, decide the exact command and cwd you will use to run it, then call reviewScript with that filePath, command, cwd, the exact selected entityName, and usesGeneratedRecords set to ${input.ingestionSource === "generated"}. Wait for the developer to review it because running it writes records to a live index. Do not run it before that call returns.`,
|
|
4479
|
+
'Then, without changing directories, run the script yourself via runShell using the exact same command and cwd. Report the command you ran as "ingestCommand" so the developer can re-run it. Its explanation must say that running it writes records to Algolia.',
|
|
4312
4480
|
"The summary should be extremely concise.",
|
|
4313
4481
|
...sourceSpecificInstructions(input)
|
|
4314
4482
|
] : []
|
|
@@ -4688,19 +4856,33 @@ ${detail}` : ""}`
|
|
|
4688
4856
|
product_area: "AI Wizard"
|
|
4689
4857
|
});
|
|
4690
4858
|
}
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
}
|
|
4859
|
+
if (ingestScriptRan) {
|
|
4860
|
+
await ctx.requestUserInput({
|
|
4861
|
+
prompt: "Continue",
|
|
4862
|
+
promptType: "notice",
|
|
4863
|
+
options: [],
|
|
4864
|
+
messages: [
|
|
4865
|
+
ingestOutcomeMessage,
|
|
4866
|
+
"View your ingested records in the Algolia dashboard:",
|
|
4867
|
+
"https://dashboard.algolia.com/explorer/browse",
|
|
4868
|
+
"When you're ready to continue, we'll move on to search implementation."
|
|
4869
|
+
]
|
|
4870
|
+
});
|
|
4871
|
+
} else {
|
|
4872
|
+
const commandMessages = ingestCommand ? [`Ingestion command: ${ingestCommand}`] : [];
|
|
4873
|
+
await ctx.requestUserInput({
|
|
4874
|
+
prompt: "",
|
|
4875
|
+
promptType: "enterToContinue",
|
|
4876
|
+
options: [],
|
|
4877
|
+
// One message per line: Notices.tsx counts a message as one wrapped
|
|
4878
|
+
// line, so an embedded newline overflows the panel's height accounting.
|
|
4879
|
+
messages: [
|
|
4880
|
+
ingestOutcomeMessage,
|
|
4881
|
+
...ingestFailureDetail?.split("\n").filter((l) => l.trim()) ?? [],
|
|
4882
|
+
...commandMessages
|
|
4883
|
+
]
|
|
4884
|
+
});
|
|
4885
|
+
}
|
|
4704
4886
|
}
|
|
4705
4887
|
let searchConfigFile;
|
|
4706
4888
|
if (useCases.includes("search")) {
|
|
@@ -5058,8 +5240,8 @@ function getWorkflow(id) {
|
|
|
5058
5240
|
// src/ui/Welcome.tsx
|
|
5059
5241
|
import { dirname as dirname8, join as join11 } from "node:path";
|
|
5060
5242
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5061
|
-
import { useState as
|
|
5062
|
-
import { Box as Box11, Spacer, Text as
|
|
5243
|
+
import { useState as useState9 } from "react";
|
|
5244
|
+
import { Box as Box11, Spacer, Text as Text12, useInput as useInput5, useWindowSize as useWindowSize5 } from "ink";
|
|
5063
5245
|
|
|
5064
5246
|
// src/ui/copy/welcome.ts
|
|
5065
5247
|
var sidebarItems = [
|
|
@@ -5087,7 +5269,7 @@ var sidebarItems = [
|
|
|
5087
5269
|
|
|
5088
5270
|
// src/ui/Welcome.tsx
|
|
5089
5271
|
import Image, { TerminalInfoContext, defaultTerminalInfo } from "ink-picture";
|
|
5090
|
-
import { jsx as
|
|
5272
|
+
import { jsx as jsx10, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5091
5273
|
var IMAGE_PATH = join11(dirname8(fileURLToPath2(import.meta.url)), "algolia.png");
|
|
5092
5274
|
var TERMINAL_INFO = {
|
|
5093
5275
|
...defaultTerminalInfo,
|
|
@@ -5098,14 +5280,14 @@ function SidebarItem({
|
|
|
5098
5280
|
title,
|
|
5099
5281
|
description
|
|
5100
5282
|
}) {
|
|
5101
|
-
return /* @__PURE__ */
|
|
5102
|
-
/* @__PURE__ */
|
|
5103
|
-
/* @__PURE__ */
|
|
5104
|
-
/* @__PURE__ */
|
|
5283
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
5284
|
+
/* @__PURE__ */ jsxs11(Box11, { gap: 1, children: [
|
|
5285
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.success, children: "\u2192" }),
|
|
5286
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.strong, bold: true, children: title })
|
|
5105
5287
|
] }),
|
|
5106
|
-
/* @__PURE__ */
|
|
5107
|
-
/* @__PURE__ */
|
|
5108
|
-
/* @__PURE__ */
|
|
5288
|
+
/* @__PURE__ */ jsxs11(Box11, { flexDirection: "row", gap: 2, children: [
|
|
5289
|
+
/* @__PURE__ */ jsx10(Spacer, {}),
|
|
5290
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: description })
|
|
5109
5291
|
] })
|
|
5110
5292
|
] });
|
|
5111
5293
|
}
|
|
@@ -5117,8 +5299,8 @@ function Welcome() {
|
|
|
5117
5299
|
{ label: "start wizard", run: confirmStart },
|
|
5118
5300
|
{ label: "learn more", run: openLearnMore }
|
|
5119
5301
|
];
|
|
5120
|
-
const [index, setIndex] =
|
|
5121
|
-
|
|
5302
|
+
const [index, setIndex] = useState9(0);
|
|
5303
|
+
useInput5((input, key) => {
|
|
5122
5304
|
if (key.upArrow || input === "k") {
|
|
5123
5305
|
setIndex((i) => (i - 1 + actions.length) % actions.length);
|
|
5124
5306
|
} else if (key.downArrow || input === "j") {
|
|
@@ -5141,16 +5323,16 @@ function Welcome() {
|
|
|
5141
5323
|
if (rows < 30) {
|
|
5142
5324
|
layout = scales["small"];
|
|
5143
5325
|
}
|
|
5144
|
-
return /* @__PURE__ */
|
|
5145
|
-
/* @__PURE__ */
|
|
5326
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
|
|
5327
|
+
/* @__PURE__ */ jsx10(
|
|
5146
5328
|
Box11,
|
|
5147
5329
|
{
|
|
5148
5330
|
paddingY: layout.main.padding.y,
|
|
5149
5331
|
paddingX: layout.main.padding.x,
|
|
5150
5332
|
flexDirection: "column",
|
|
5151
5333
|
justifyContent: "center",
|
|
5152
|
-
children: /* @__PURE__ */
|
|
5153
|
-
/* @__PURE__ */
|
|
5334
|
+
children: /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", gap: 2, children: [
|
|
5335
|
+
/* @__PURE__ */ jsx10(TerminalInfoContext.Provider, { value: TERMINAL_INFO, children: /* @__PURE__ */ jsx10(
|
|
5154
5336
|
Image,
|
|
5155
5337
|
{
|
|
5156
5338
|
src: IMAGE_PATH,
|
|
@@ -5161,8 +5343,8 @@ function Welcome() {
|
|
|
5161
5343
|
protocol: "halfBlock"
|
|
5162
5344
|
}
|
|
5163
5345
|
) }),
|
|
5164
|
-
/* @__PURE__ */
|
|
5165
|
-
/* @__PURE__ */
|
|
5346
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
|
|
5347
|
+
/* @__PURE__ */ jsx10(Box11, { flexDirection: "column", children: actions.map((action, i) => /* @__PURE__ */ jsx10(
|
|
5166
5348
|
SelectRow,
|
|
5167
5349
|
{
|
|
5168
5350
|
highlighted: i === index,
|
|
@@ -5171,20 +5353,20 @@ function Welcome() {
|
|
|
5171
5353
|
},
|
|
5172
5354
|
action.label
|
|
5173
5355
|
)) }),
|
|
5174
|
-
/* @__PURE__ */
|
|
5175
|
-
/* @__PURE__ */
|
|
5176
|
-
/* @__PURE__ */
|
|
5177
|
-
/* @__PURE__ */
|
|
5356
|
+
/* @__PURE__ */ jsxs11(Box11, { gap: 2, children: [
|
|
5357
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
5358
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.primary, children: "[\u2191] [\u2193]" }),
|
|
5359
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.dim, children: " move" })
|
|
5178
5360
|
] }),
|
|
5179
|
-
/* @__PURE__ */
|
|
5180
|
-
/* @__PURE__ */
|
|
5181
|
-
/* @__PURE__ */
|
|
5361
|
+
/* @__PURE__ */ jsxs11(Text12, { children: [
|
|
5362
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.primary, children: "[enter]" }),
|
|
5363
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.dim, children: " confirm" })
|
|
5182
5364
|
] })
|
|
5183
5365
|
] })
|
|
5184
5366
|
] })
|
|
5185
5367
|
}
|
|
5186
5368
|
),
|
|
5187
|
-
/* @__PURE__ */
|
|
5369
|
+
/* @__PURE__ */ jsxs11(
|
|
5188
5370
|
Box11,
|
|
5189
5371
|
{
|
|
5190
5372
|
backgroundColor: COLORS.bg.sidebar,
|
|
@@ -5195,8 +5377,8 @@ function Welcome() {
|
|
|
5195
5377
|
flexDirection: "column",
|
|
5196
5378
|
justifyContent: "center",
|
|
5197
5379
|
children: [
|
|
5198
|
-
/* @__PURE__ */
|
|
5199
|
-
sidebarItems.map((i, idx) => /* @__PURE__ */
|
|
5380
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
|
|
5381
|
+
sidebarItems.map((i, idx) => /* @__PURE__ */ jsx10(SidebarItem, { title: i.title, description: i.description }, idx))
|
|
5200
5382
|
]
|
|
5201
5383
|
}
|
|
5202
5384
|
)
|
|
@@ -5205,7 +5387,7 @@ function Welcome() {
|
|
|
5205
5387
|
|
|
5206
5388
|
// src/ui/LearnMore.tsx
|
|
5207
5389
|
import { Fragment } from "react";
|
|
5208
|
-
import { Box as Box12, Text as
|
|
5390
|
+
import { Box as Box12, Text as Text13, useInput as useInput6, useWindowSize as useWindowSize6 } from "ink";
|
|
5209
5391
|
|
|
5210
5392
|
// src/ui/copy/learn-more.ts
|
|
5211
5393
|
var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
|
|
@@ -5247,7 +5429,7 @@ var policyLinks = [
|
|
|
5247
5429
|
];
|
|
5248
5430
|
|
|
5249
5431
|
// src/ui/LearnMore.tsx
|
|
5250
|
-
import { jsx as
|
|
5432
|
+
import { jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5251
5433
|
var TAG_COLORS = {
|
|
5252
5434
|
READ: COLORS.success,
|
|
5253
5435
|
WRITE: COLORS.badge,
|
|
@@ -5264,12 +5446,12 @@ function NeverLine({
|
|
|
5264
5446
|
}) {
|
|
5265
5447
|
const used = segments.reduce((n, s) => n + s.text.length, 0);
|
|
5266
5448
|
const rightPad = Math.max(0, width - 2 - NEVER_BOX_PAD_X - used);
|
|
5267
|
-
return /* @__PURE__ */
|
|
5268
|
-
/* @__PURE__ */
|
|
5449
|
+
return /* @__PURE__ */ jsxs12(Text13, { color: COLORS.primary, children: [
|
|
5450
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.danger, children: "\u2502" }),
|
|
5269
5451
|
" ".repeat(NEVER_BOX_PAD_X),
|
|
5270
|
-
segments.map((s, i) => /* @__PURE__ */
|
|
5452
|
+
segments.map((s, i) => /* @__PURE__ */ jsx11(Text13, { color: s.color, bold: s.bold, children: s.text }, i)),
|
|
5271
5453
|
" ".repeat(rightPad),
|
|
5272
|
-
/* @__PURE__ */
|
|
5454
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.danger, children: "\u2502" })
|
|
5273
5455
|
] });
|
|
5274
5456
|
}
|
|
5275
5457
|
function LearnMore() {
|
|
@@ -5277,11 +5459,11 @@ function LearnMore() {
|
|
|
5277
5459
|
const backToHome = useWizard((s) => s.backToHome);
|
|
5278
5460
|
const { columns } = useWindowSize6();
|
|
5279
5461
|
const dividerWidth = Math.max(0, columns - PADDING_X * 2);
|
|
5280
|
-
|
|
5462
|
+
useInput6((_input, key) => {
|
|
5281
5463
|
if (key.escape) backToHome();
|
|
5282
5464
|
else if (key.return) confirmStart();
|
|
5283
5465
|
});
|
|
5284
|
-
return /* @__PURE__ */
|
|
5466
|
+
return /* @__PURE__ */ jsxs12(
|
|
5285
5467
|
Box12,
|
|
5286
5468
|
{
|
|
5287
5469
|
flexDirection: "column",
|
|
@@ -5290,31 +5472,31 @@ function LearnMore() {
|
|
|
5290
5472
|
width: "100%",
|
|
5291
5473
|
gap: 1,
|
|
5292
5474
|
children: [
|
|
5293
|
-
/* @__PURE__ */
|
|
5294
|
-
/* @__PURE__ */
|
|
5295
|
-
/* @__PURE__ */
|
|
5296
|
-
/* @__PURE__ */
|
|
5297
|
-
/* @__PURE__ */
|
|
5298
|
-
/* @__PURE__ */
|
|
5299
|
-
/* @__PURE__ */
|
|
5300
|
-
/* @__PURE__ */
|
|
5301
|
-
/* @__PURE__ */
|
|
5475
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
|
|
5476
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: accessIntro }),
|
|
5477
|
+
/* @__PURE__ */ jsx11(Box12, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginTop: 1, children: [
|
|
5478
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
|
|
5479
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, marginTop: 1, children: [
|
|
5480
|
+
/* @__PURE__ */ jsx11(Box12, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text13, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
|
|
5481
|
+
/* @__PURE__ */ jsx11(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsxs12(Text13, { color: COLORS.primary, children: [
|
|
5482
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: item.title }),
|
|
5483
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
|
|
5302
5484
|
] }) })
|
|
5303
5485
|
] })
|
|
5304
5486
|
] }, item.tag)) }),
|
|
5305
|
-
/* @__PURE__ */
|
|
5306
|
-
/* @__PURE__ */
|
|
5307
|
-
/* @__PURE__ */
|
|
5308
|
-
/* @__PURE__ */
|
|
5487
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", children: [
|
|
5488
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
|
|
5489
|
+
/* @__PURE__ */ jsx11(NeverLine, { width: dividerWidth }),
|
|
5490
|
+
/* @__PURE__ */ jsx11(
|
|
5309
5491
|
NeverLine,
|
|
5310
5492
|
{
|
|
5311
5493
|
width: dividerWidth,
|
|
5312
5494
|
segments: [{ text: "I NEVER", color: COLORS.danger, bold: true }]
|
|
5313
5495
|
}
|
|
5314
5496
|
),
|
|
5315
|
-
neverItems.map((item) => /* @__PURE__ */
|
|
5316
|
-
/* @__PURE__ */
|
|
5317
|
-
/* @__PURE__ */
|
|
5497
|
+
neverItems.map((item) => /* @__PURE__ */ jsxs12(Fragment, { children: [
|
|
5498
|
+
/* @__PURE__ */ jsx11(NeverLine, { width: dividerWidth }),
|
|
5499
|
+
/* @__PURE__ */ jsx11(
|
|
5318
5500
|
NeverLine,
|
|
5319
5501
|
{
|
|
5320
5502
|
width: dividerWidth,
|
|
@@ -5326,24 +5508,24 @@ function LearnMore() {
|
|
|
5326
5508
|
}
|
|
5327
5509
|
)
|
|
5328
5510
|
] }, item)),
|
|
5329
|
-
/* @__PURE__ */
|
|
5330
|
-
/* @__PURE__ */
|
|
5511
|
+
/* @__PURE__ */ jsx11(NeverLine, { width: dividerWidth }),
|
|
5512
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
|
|
5331
5513
|
] }),
|
|
5332
|
-
/* @__PURE__ */
|
|
5333
|
-
/* @__PURE__ */
|
|
5334
|
-
/* @__PURE__ */
|
|
5514
|
+
/* @__PURE__ */ jsx11(Box12, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, children: [
|
|
5515
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
|
|
5516
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.accent, children: link.url })
|
|
5335
5517
|
] }, link.label)) }),
|
|
5336
|
-
/* @__PURE__ */
|
|
5337
|
-
/* @__PURE__ */
|
|
5338
|
-
/* @__PURE__ */
|
|
5339
|
-
/* @__PURE__ */
|
|
5340
|
-
/* @__PURE__ */
|
|
5518
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", gap: 3, children: [
|
|
5519
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, children: [
|
|
5520
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "[" }),
|
|
5521
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.primary, children: "esc" }),
|
|
5522
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "] back" })
|
|
5341
5523
|
] }),
|
|
5342
|
-
/* @__PURE__ */
|
|
5343
|
-
/* @__PURE__ */
|
|
5344
|
-
/* @__PURE__ */
|
|
5345
|
-
/* @__PURE__ */
|
|
5346
|
-
/* @__PURE__ */
|
|
5524
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, children: [
|
|
5525
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "[" }),
|
|
5526
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.primary, children: "enter" }),
|
|
5527
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "]" }),
|
|
5528
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.success, bold: true, children: "start wizard" })
|
|
5347
5529
|
] })
|
|
5348
5530
|
] })
|
|
5349
5531
|
]
|
|
@@ -5352,17 +5534,17 @@ function LearnMore() {
|
|
|
5352
5534
|
}
|
|
5353
5535
|
|
|
5354
5536
|
// src/ui/Sidebar.tsx
|
|
5355
|
-
import { Box as Box15, Text as
|
|
5537
|
+
import { Box as Box15, Text as Text16 } from "ink";
|
|
5356
5538
|
|
|
5357
5539
|
// src/ui/Steps.tsx
|
|
5358
|
-
import { Box as Box13, Text as
|
|
5540
|
+
import { Box as Box13, Text as Text14 } from "ink";
|
|
5359
5541
|
import Spinner2 from "ink-spinner";
|
|
5360
|
-
import { jsx as
|
|
5542
|
+
import { jsx as jsx12, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5361
5543
|
function Steps() {
|
|
5362
5544
|
const { steps } = useWizard();
|
|
5363
5545
|
const visibleSteps = steps.filter(isStepVisible);
|
|
5364
|
-
return /* @__PURE__ */
|
|
5365
|
-
s.status === "running" ? /* @__PURE__ */
|
|
5546
|
+
return /* @__PURE__ */ jsx12(Box13, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx12(Box13, { flexDirection: "column", children: /* @__PURE__ */ jsxs13(Text14, { color: COLORS.status[s.status], children: [
|
|
5547
|
+
s.status === "running" ? /* @__PURE__ */ jsx12(Spinner2, { type: "dots" }) : MARKER[s.status],
|
|
5366
5548
|
" ",
|
|
5367
5549
|
s.title
|
|
5368
5550
|
] }) }, s.id)) });
|
|
@@ -5371,27 +5553,27 @@ function CurrentStep() {
|
|
|
5371
5553
|
const { steps } = useWizard();
|
|
5372
5554
|
const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
|
|
5373
5555
|
if (!currentStep) return null;
|
|
5374
|
-
return /* @__PURE__ */
|
|
5375
|
-
/* @__PURE__ */
|
|
5556
|
+
return /* @__PURE__ */ jsxs13(Text14, { color: COLORS.status.running, children: [
|
|
5557
|
+
/* @__PURE__ */ jsx12(Spinner2, { type: "dots" }),
|
|
5376
5558
|
" ",
|
|
5377
5559
|
` ${currentStep.title}`
|
|
5378
5560
|
] });
|
|
5379
5561
|
}
|
|
5380
5562
|
|
|
5381
5563
|
// src/ui/Progress.tsx
|
|
5382
|
-
import { Box as Box14, Text as
|
|
5383
|
-
import { jsx as
|
|
5564
|
+
import { Box as Box14, Text as Text15 } from "ink";
|
|
5565
|
+
import { jsx as jsx13, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5384
5566
|
function Progress() {
|
|
5385
5567
|
const { steps, currentStepIndex } = useWizard();
|
|
5386
5568
|
const visibleSteps = steps.filter(isStepVisible);
|
|
5387
5569
|
if (visibleSteps.length === 0) return null;
|
|
5388
5570
|
const visibleCountThroughCurrent = steps.slice(0, currentStepIndex + 1).filter(isStepVisible).length;
|
|
5389
5571
|
const activeStepNumber = Math.max(1, visibleCountThroughCurrent);
|
|
5390
|
-
return /* @__PURE__ */
|
|
5391
|
-
/* @__PURE__ */
|
|
5392
|
-
/* @__PURE__ */
|
|
5393
|
-
/* @__PURE__ */
|
|
5394
|
-
/* @__PURE__ */
|
|
5572
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "row", gap: 1, children: [
|
|
5573
|
+
/* @__PURE__ */ jsx13(Text15, { color: COLORS.muted, children: "STEP" }),
|
|
5574
|
+
/* @__PURE__ */ jsx13(Text15, { color: COLORS.strong, bold: true, children: activeStepNumber }),
|
|
5575
|
+
/* @__PURE__ */ jsx13(Text15, { color: COLORS.strong, bold: true, children: "/" }),
|
|
5576
|
+
/* @__PURE__ */ jsx13(Text15, { color: COLORS.strong, bold: true, children: visibleSteps.length })
|
|
5395
5577
|
] });
|
|
5396
5578
|
}
|
|
5397
5579
|
|
|
@@ -5402,9 +5584,9 @@ var sidebarCommands = [
|
|
|
5402
5584
|
];
|
|
5403
5585
|
|
|
5404
5586
|
// src/ui/Sidebar.tsx
|
|
5405
|
-
import { jsx as
|
|
5587
|
+
import { jsx as jsx14, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5406
5588
|
function Sidebar() {
|
|
5407
|
-
return /* @__PURE__ */
|
|
5589
|
+
return /* @__PURE__ */ jsxs15(
|
|
5408
5590
|
Box15,
|
|
5409
5591
|
{
|
|
5410
5592
|
backgroundColor: "#14171E",
|
|
@@ -5414,16 +5596,16 @@ function Sidebar() {
|
|
|
5414
5596
|
flexDirection: "column",
|
|
5415
5597
|
justifyContent: "space-between",
|
|
5416
5598
|
children: [
|
|
5417
|
-
/* @__PURE__ */
|
|
5418
|
-
/* @__PURE__ */
|
|
5419
|
-
/* @__PURE__ */
|
|
5599
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
5600
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.muted, children: "PROGRESS" }),
|
|
5601
|
+
/* @__PURE__ */ jsx14(Steps, {})
|
|
5420
5602
|
] }),
|
|
5421
|
-
/* @__PURE__ */
|
|
5422
|
-
/* @__PURE__ */
|
|
5423
|
-
/* @__PURE__ */
|
|
5424
|
-
return /* @__PURE__ */
|
|
5425
|
-
/* @__PURE__ */
|
|
5426
|
-
/* @__PURE__ */
|
|
5603
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", gap: 1, children: [
|
|
5604
|
+
/* @__PURE__ */ jsx14(Progress, {}),
|
|
5605
|
+
/* @__PURE__ */ jsx14(Box15, { flexDirection: "column", children: sidebarCommands.map((c) => {
|
|
5606
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "row", gap: 1, children: [
|
|
5607
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.primary, children: `[${c.keyHint}]` }),
|
|
5608
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.muted, children: c.description })
|
|
5427
5609
|
] }, c.keyHint);
|
|
5428
5610
|
}) })
|
|
5429
5611
|
] })
|
|
@@ -5433,11 +5615,11 @@ function Sidebar() {
|
|
|
5433
5615
|
}
|
|
5434
5616
|
|
|
5435
5617
|
// src/ui/Ribbon.tsx
|
|
5436
|
-
import { Box as Box16, Text as
|
|
5437
|
-
import { jsx as
|
|
5618
|
+
import { Box as Box16, Text as Text17 } from "ink";
|
|
5619
|
+
import { jsx as jsx15, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5438
5620
|
function Ribbon() {
|
|
5439
5621
|
const firstCommand = sidebarCommands[0];
|
|
5440
|
-
return /* @__PURE__ */
|
|
5622
|
+
return /* @__PURE__ */ jsxs16(
|
|
5441
5623
|
Box16,
|
|
5442
5624
|
{
|
|
5443
5625
|
backgroundColor: "#14171E",
|
|
@@ -5446,11 +5628,11 @@ function Ribbon() {
|
|
|
5446
5628
|
paddingX: 2,
|
|
5447
5629
|
paddingY: 1,
|
|
5448
5630
|
children: [
|
|
5449
|
-
/* @__PURE__ */
|
|
5450
|
-
/* @__PURE__ */
|
|
5451
|
-
/* @__PURE__ */
|
|
5452
|
-
/* @__PURE__ */
|
|
5453
|
-
/* @__PURE__ */
|
|
5631
|
+
/* @__PURE__ */ jsx15(Progress, {}),
|
|
5632
|
+
/* @__PURE__ */ jsx15(CurrentStep, {}),
|
|
5633
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "row", gap: 1, children: [
|
|
5634
|
+
/* @__PURE__ */ jsx15(Text17, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
|
|
5635
|
+
/* @__PURE__ */ jsx15(Text17, { color: COLORS.muted, children: firstCommand.description })
|
|
5454
5636
|
] })
|
|
5455
5637
|
]
|
|
5456
5638
|
}
|
|
@@ -5458,11 +5640,11 @@ function Ribbon() {
|
|
|
5458
5640
|
}
|
|
5459
5641
|
|
|
5460
5642
|
// src/ui/App.tsx
|
|
5461
|
-
import { useState as
|
|
5643
|
+
import { useState as useState11 } from "react";
|
|
5462
5644
|
|
|
5463
5645
|
// src/ui/Logs.tsx
|
|
5464
|
-
import { Box as Box17, Text as
|
|
5465
|
-
import { jsx as
|
|
5646
|
+
import { Box as Box17, Text as Text18, useInput as useInput7 } from "ink";
|
|
5647
|
+
import { jsx as jsx16, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5466
5648
|
var KIND_COLOR = {
|
|
5467
5649
|
tool: COLORS.primary,
|
|
5468
5650
|
prompt: COLORS.badge
|
|
@@ -5493,14 +5675,14 @@ function formatTimestamp(ms) {
|
|
|
5493
5675
|
function Logs() {
|
|
5494
5676
|
const logs = useWizard((s) => s.logs);
|
|
5495
5677
|
const scroll = useScrollWindow({ itemCount: logs.length, followBottom: true });
|
|
5496
|
-
|
|
5678
|
+
useInput7((_input, key) => {
|
|
5497
5679
|
if (key.upArrow) scroll.scrollBy(-1);
|
|
5498
5680
|
else if (key.downArrow) scroll.scrollBy(1);
|
|
5499
5681
|
});
|
|
5500
5682
|
const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
5501
|
-
return /* @__PURE__ */
|
|
5502
|
-
logs.length === 0 && /* @__PURE__ */
|
|
5503
|
-
/* @__PURE__ */
|
|
5683
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
|
|
5684
|
+
logs.length === 0 && /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: "No logs yet." }),
|
|
5685
|
+
/* @__PURE__ */ jsx16(ScrollView, { scroll, children: visible.map((entry) => {
|
|
5504
5686
|
const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
|
|
5505
5687
|
const durationText = entry.kind === "tool" && entry.durationMs !== void 0 ? `${entry.durationMs}ms` : "";
|
|
5506
5688
|
const rawPreview = rawInputText(entry.input);
|
|
@@ -5510,25 +5692,25 @@ function Logs() {
|
|
|
5510
5692
|
const name = truncate3(entry.name, budget);
|
|
5511
5693
|
budget -= name.length;
|
|
5512
5694
|
const preview = rawPreview ? truncate3(rawPreview, budget) : "";
|
|
5513
|
-
return /* @__PURE__ */
|
|
5514
|
-
/* @__PURE__ */
|
|
5515
|
-
/* @__PURE__ */
|
|
5516
|
-
preview && /* @__PURE__ */
|
|
5517
|
-
durationText && /* @__PURE__ */
|
|
5695
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "row", gap: ROW_GAP, children: [
|
|
5696
|
+
/* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: timestamp }),
|
|
5697
|
+
/* @__PURE__ */ jsx16(Text18, { color: logNameColor(entry), wrap: "truncate", children: name }),
|
|
5698
|
+
preview && /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, wrap: "truncate", children: preview }),
|
|
5699
|
+
durationText && /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: durationText })
|
|
5518
5700
|
] }, entry.id);
|
|
5519
5701
|
}) }),
|
|
5520
|
-
/* @__PURE__ */
|
|
5702
|
+
/* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
|
|
5521
5703
|
] });
|
|
5522
5704
|
}
|
|
5523
5705
|
|
|
5524
5706
|
// src/ui/Tips.tsx
|
|
5525
|
-
import { useEffect as useEffect3, useRef as useRef4, useState as
|
|
5526
|
-
import { Box as Box19, Text as
|
|
5707
|
+
import { useEffect as useEffect3, useRef as useRef4, useState as useState10 } from "react";
|
|
5708
|
+
import { Box as Box19, Text as Text20 } from "ink";
|
|
5527
5709
|
import terminalLink from "terminal-link";
|
|
5528
5710
|
|
|
5529
5711
|
// src/ui/Code.tsx
|
|
5530
|
-
import { Box as Box18, Text as
|
|
5531
|
-
import { jsx as
|
|
5712
|
+
import { Box as Box18, Text as Text19 } from "ink";
|
|
5713
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
5532
5714
|
var TOKEN_RE = /("(?:\\.|[^"\\])*"|\btrue\b|\bfalse\b|\bnull\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|[{}[\]:,])/g;
|
|
5533
5715
|
function highlightJson(json) {
|
|
5534
5716
|
const parts = json.split(TOKEN_RE);
|
|
@@ -5537,22 +5719,22 @@ function highlightJson(json) {
|
|
|
5537
5719
|
if (part[0] === '"') {
|
|
5538
5720
|
const next = parts.slice(i + 1).find((p) => p.trim());
|
|
5539
5721
|
const isKey = next?.trimStart().startsWith(":");
|
|
5540
|
-
return /* @__PURE__ */
|
|
5722
|
+
return /* @__PURE__ */ jsx17(Text19, { color: isKey ? "cyan" : "green", children: part }, i);
|
|
5541
5723
|
}
|
|
5542
5724
|
if (part === "true" || part === "false" || part === "null") {
|
|
5543
|
-
return /* @__PURE__ */
|
|
5725
|
+
return /* @__PURE__ */ jsx17(Text19, { color: "magenta", children: part }, i);
|
|
5544
5726
|
}
|
|
5545
5727
|
if (/^-?\d/.test(part)) {
|
|
5546
|
-
return /* @__PURE__ */
|
|
5728
|
+
return /* @__PURE__ */ jsx17(Text19, { color: "yellow", children: part }, i);
|
|
5547
5729
|
}
|
|
5548
5730
|
if (/^[{}[\]:,]$/.test(part)) {
|
|
5549
|
-
return /* @__PURE__ */
|
|
5731
|
+
return /* @__PURE__ */ jsx17(Text19, { color: COLORS.dim, children: part }, i);
|
|
5550
5732
|
}
|
|
5551
|
-
return /* @__PURE__ */
|
|
5733
|
+
return /* @__PURE__ */ jsx17(Text19, { children: part }, i);
|
|
5552
5734
|
});
|
|
5553
5735
|
}
|
|
5554
5736
|
function Code({ children }) {
|
|
5555
|
-
return /* @__PURE__ */
|
|
5737
|
+
return /* @__PURE__ */ jsx17(Box18, { children: /* @__PURE__ */ jsx17(Text19, { children: highlightJson(children) }) });
|
|
5556
5738
|
}
|
|
5557
5739
|
|
|
5558
5740
|
// src/ui/copy/tips.ts
|
|
@@ -5766,26 +5948,26 @@ function tipsByIds(ids) {
|
|
|
5766
5948
|
}
|
|
5767
5949
|
|
|
5768
5950
|
// src/ui/Tips.tsx
|
|
5769
|
-
import { jsx as
|
|
5951
|
+
import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5770
5952
|
var TICK_MS = 16;
|
|
5771
5953
|
var CHUNK_HOLD_MS = 2e3;
|
|
5772
5954
|
var HOLD_MS = 12e3;
|
|
5773
5955
|
function TipTitle({ children }) {
|
|
5774
|
-
return /* @__PURE__ */
|
|
5775
|
-
/* @__PURE__ */
|
|
5776
|
-
/* @__PURE__ */
|
|
5956
|
+
return /* @__PURE__ */ jsxs18(Box19, { gap: 1, children: [
|
|
5957
|
+
/* @__PURE__ */ jsx18(Text20, { color: "cyan", children: "\u2726" }),
|
|
5958
|
+
/* @__PURE__ */ jsx18(Text20, { color: "white", bold: true, children })
|
|
5777
5959
|
] });
|
|
5778
5960
|
}
|
|
5779
5961
|
function InlineSegment({ segment }) {
|
|
5780
5962
|
switch (segment.type) {
|
|
5781
5963
|
case "highlight":
|
|
5782
|
-
return /* @__PURE__ */
|
|
5964
|
+
return /* @__PURE__ */ jsx18(Text20, { color: COLORS.success, children: segment.value });
|
|
5783
5965
|
case "link":
|
|
5784
|
-
return /* @__PURE__ */
|
|
5966
|
+
return /* @__PURE__ */ jsx18(Text20, { color: "cyan", underline: true, children: segment.href ? terminalLink(segment.value, segment.href) : segment.value });
|
|
5785
5967
|
case "codeword":
|
|
5786
|
-
return /* @__PURE__ */
|
|
5968
|
+
return /* @__PURE__ */ jsx18(Text20, { color: COLORS.highlight.fg, backgroundColor: COLORS.highlight.bg, children: segment.value });
|
|
5787
5969
|
default:
|
|
5788
|
-
return /* @__PURE__ */
|
|
5970
|
+
return /* @__PURE__ */ jsx18(Text20, { color: COLORS.muted, children: segment.value });
|
|
5789
5971
|
}
|
|
5790
5972
|
}
|
|
5791
5973
|
function TipContent({
|
|
@@ -5819,10 +6001,10 @@ function TipContent({
|
|
|
5819
6001
|
blocks.push({ type: "inline", segments: [segment] });
|
|
5820
6002
|
}
|
|
5821
6003
|
}
|
|
5822
|
-
return /* @__PURE__ */
|
|
5823
|
-
(block, i) => block.type === "code" ? /* @__PURE__ */
|
|
6004
|
+
return /* @__PURE__ */ jsx18(Box19, { flexDirection: "column", marginLeft: 2, gap: 1, children: blocks.map(
|
|
6005
|
+
(block, i) => block.type === "code" ? /* @__PURE__ */ jsx18(Code, { children: block.segment.value }, i) : /* @__PURE__ */ jsx18(Text20, { children: block.segments.map((segment, j) => /* @__PURE__ */ jsxs18(Text20, { children: [
|
|
5824
6006
|
j > 0 && " ",
|
|
5825
|
-
/* @__PURE__ */
|
|
6007
|
+
/* @__PURE__ */ jsx18(InlineSegment, { segment })
|
|
5826
6008
|
] }, j)) }, i)
|
|
5827
6009
|
) });
|
|
5828
6010
|
}
|
|
@@ -5839,8 +6021,8 @@ function Tips({
|
|
|
5839
6021
|
progress.tipIndex = 0;
|
|
5840
6022
|
progress.revealed = 0;
|
|
5841
6023
|
}
|
|
5842
|
-
const [tipIndex, setTipIndex] =
|
|
5843
|
-
const [revealed, setRevealed] =
|
|
6024
|
+
const [tipIndex, setTipIndex] = useState10(resuming ? progress.tipIndex : 0);
|
|
6025
|
+
const [revealed, setRevealed] = useState10(resuming ? progress.revealed : 0);
|
|
5844
6026
|
const tip = tips2.length > 0 ? tips2[tipIndex % tips2.length] : void 0;
|
|
5845
6027
|
const contentLength = tip?.chunks.reduce((sum, c) => sum + c.value.length, 0) ?? 0;
|
|
5846
6028
|
const totalLength = (tip?.title.length ?? 0) + contentLength;
|
|
@@ -5899,14 +6081,14 @@ function Tips({
|
|
|
5899
6081
|
if (!tip) return null;
|
|
5900
6082
|
const titleRevealed = tip.title.slice(0, revealed);
|
|
5901
6083
|
const contentRevealed = Math.max(0, revealed - tip.title.length);
|
|
5902
|
-
return /* @__PURE__ */
|
|
5903
|
-
/* @__PURE__ */
|
|
5904
|
-
/* @__PURE__ */
|
|
6084
|
+
return /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", marginBottom: 1, gap: 1, children: [
|
|
6085
|
+
/* @__PURE__ */ jsx18(TipTitle, { children: titleRevealed }),
|
|
6086
|
+
/* @__PURE__ */ jsx18(TipContent, { chunks: tip.chunks, revealed: contentRevealed })
|
|
5905
6087
|
] });
|
|
5906
6088
|
}
|
|
5907
6089
|
|
|
5908
6090
|
// src/ui/App.tsx
|
|
5909
|
-
import { jsx as
|
|
6091
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5910
6092
|
function App() {
|
|
5911
6093
|
const {
|
|
5912
6094
|
phase,
|
|
@@ -5922,8 +6104,8 @@ function App() {
|
|
|
5922
6104
|
} = useWizard();
|
|
5923
6105
|
const { exit } = useApp();
|
|
5924
6106
|
const { columns, rows } = useWindowSize7();
|
|
5925
|
-
const [showLogs, setShowLogs] =
|
|
5926
|
-
const [tipState, setTipState] =
|
|
6107
|
+
const [showLogs, setShowLogs] = useState11(false);
|
|
6108
|
+
const [tipState, setTipState] = useState11("idle");
|
|
5927
6109
|
const finished = phase === "done" || phase === "error";
|
|
5928
6110
|
const currentStep = steps[currentStepIndex];
|
|
5929
6111
|
const stepDef = workflow ? getWorkflow(workflow.id)?.steps.find((s) => s.id === currentStep?.id) : void 0;
|
|
@@ -5936,7 +6118,7 @@ function App() {
|
|
|
5936
6118
|
const showTips = stepHasTips && (phase === "running" && currentStep?.status === "running" || isCommandApprovalPrompt || holdForTip);
|
|
5937
6119
|
const showNoticesInMain = !stepHasTips;
|
|
5938
6120
|
const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
|
|
5939
|
-
|
|
6121
|
+
useInput8(
|
|
5940
6122
|
(_input, key) => {
|
|
5941
6123
|
if (key.return) {
|
|
5942
6124
|
exit();
|
|
@@ -5944,7 +6126,7 @@ function App() {
|
|
|
5944
6126
|
},
|
|
5945
6127
|
{ isActive: finished }
|
|
5946
6128
|
);
|
|
5947
|
-
|
|
6129
|
+
useInput8((_input, key) => {
|
|
5948
6130
|
if (phase === "idle" || phase === "authenticating") return;
|
|
5949
6131
|
if (key.tab) {
|
|
5950
6132
|
setShowLogs(!showLogs);
|
|
@@ -5956,7 +6138,7 @@ function App() {
|
|
|
5956
6138
|
}
|
|
5957
6139
|
});
|
|
5958
6140
|
const escOwnedElsewhere = phase === "idle" || phase === "authenticating" || phase === "awaitingInput" && !holdForTip && (inputReq?.promptType === "enterToContinue" || inputReq?.promptType === "commandApproval");
|
|
5959
|
-
|
|
6141
|
+
useInput8((_input, key) => {
|
|
5960
6142
|
if (escOwnedElsewhere) return;
|
|
5961
6143
|
if (key.escape) {
|
|
5962
6144
|
track("AI Wizard Interaction", {
|
|
@@ -5975,7 +6157,7 @@ function App() {
|
|
|
5975
6157
|
/* Clamped to exactly the viewport: a taller frame makes Ink clear and repaint
|
|
5976
6158
|
the whole screen, and the scrolling throws off its cursor arithmetic —
|
|
5977
6159
|
flicker and leftover rows. */
|
|
5978
|
-
/* @__PURE__ */
|
|
6160
|
+
/* @__PURE__ */ jsxs19(
|
|
5979
6161
|
Box20,
|
|
5980
6162
|
{
|
|
5981
6163
|
backgroundColor: COLORS.bg.main,
|
|
@@ -5984,7 +6166,7 @@ function App() {
|
|
|
5984
6166
|
height: scrollsPastViewport ? void 0 : rows,
|
|
5985
6167
|
overflow: scrollsPastViewport ? "visible" : "hidden",
|
|
5986
6168
|
children: [
|
|
5987
|
-
mainWindowVisible && /* @__PURE__ */
|
|
6169
|
+
mainWindowVisible && /* @__PURE__ */ jsxs19(
|
|
5988
6170
|
Box20,
|
|
5989
6171
|
{
|
|
5990
6172
|
flexDirection,
|
|
@@ -5992,7 +6174,7 @@ function App() {
|
|
|
5992
6174
|
maxHeight: rows,
|
|
5993
6175
|
justifyContent: "space-between",
|
|
5994
6176
|
children: [
|
|
5995
|
-
showLogs ? /* @__PURE__ */
|
|
6177
|
+
showLogs ? /* @__PURE__ */ jsx19(Logs, {}) : /* @__PURE__ */ jsxs19(
|
|
5996
6178
|
Box20,
|
|
5997
6179
|
{
|
|
5998
6180
|
flexDirection: "column",
|
|
@@ -6002,30 +6184,30 @@ function App() {
|
|
|
6002
6184
|
flexGrow: 1,
|
|
6003
6185
|
gap: 1,
|
|
6004
6186
|
children: [
|
|
6005
|
-
/* @__PURE__ */
|
|
6006
|
-
phase === "preflight" && !user && /* @__PURE__ */
|
|
6007
|
-
/* @__PURE__ */
|
|
6187
|
+
/* @__PURE__ */ jsxs19(Box20, { flexGrow: 2, flexDirection: "column", children: [
|
|
6188
|
+
phase === "preflight" && !user && /* @__PURE__ */ jsx19(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs19(Text21, { color: COLORS.strong, bold: true, children: [
|
|
6189
|
+
/* @__PURE__ */ jsx19(Spinner3, { type: "dots" }),
|
|
6008
6190
|
" Signing in to Algolia"
|
|
6009
6191
|
] }) }),
|
|
6010
|
-
phase === "preflight" && user && /* @__PURE__ */
|
|
6011
|
-
/* @__PURE__ */
|
|
6192
|
+
phase === "preflight" && user && /* @__PURE__ */ jsx19(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs19(Text21, { color: COLORS.strong, bold: true, children: [
|
|
6193
|
+
/* @__PURE__ */ jsx19(Spinner3, { type: "dots" }),
|
|
6012
6194
|
" Getting things ready"
|
|
6013
6195
|
] }) }),
|
|
6014
|
-
phase === "authenticating" && /* @__PURE__ */
|
|
6015
|
-
/* @__PURE__ */
|
|
6016
|
-
/* @__PURE__ */
|
|
6196
|
+
phase === "authenticating" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", marginBottom: 1, children: [
|
|
6197
|
+
/* @__PURE__ */ jsxs19(Text21, { color: COLORS.strong, bold: true, children: [
|
|
6198
|
+
/* @__PURE__ */ jsx19(Spinner3, { type: "dots" }),
|
|
6017
6199
|
" Signing in to Algolia"
|
|
6018
6200
|
] }),
|
|
6019
|
-
/* @__PURE__ */
|
|
6201
|
+
/* @__PURE__ */ jsx19(Text21, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
|
|
6020
6202
|
] }),
|
|
6021
|
-
settingUpAppId && /* @__PURE__ */
|
|
6022
|
-
/* @__PURE__ */
|
|
6203
|
+
settingUpAppId && /* @__PURE__ */ jsx19(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs19(Text21, { color: COLORS.strong, bold: true, children: [
|
|
6204
|
+
/* @__PURE__ */ jsx19(Spinner3, { type: "dots" }),
|
|
6023
6205
|
" Setting up Wizard using app",
|
|
6024
6206
|
" ",
|
|
6025
6207
|
settingUpAppId
|
|
6026
6208
|
] }) }),
|
|
6027
|
-
/* @__PURE__ */
|
|
6028
|
-
showTips && currentStep && /* @__PURE__ */
|
|
6209
|
+
/* @__PURE__ */ jsx19(CliOutput, {}),
|
|
6210
|
+
showTips && currentStep && /* @__PURE__ */ jsx19(
|
|
6029
6211
|
Tips,
|
|
6030
6212
|
{
|
|
6031
6213
|
stepId: currentStep.id,
|
|
@@ -6033,24 +6215,24 @@ function App() {
|
|
|
6033
6215
|
onRevealStateChange: setTipState
|
|
6034
6216
|
}
|
|
6035
6217
|
),
|
|
6036
|
-
showNoticesInMain && showNotices && /* @__PURE__ */
|
|
6037
|
-
/* @__PURE__ */
|
|
6038
|
-
!showTips && /* @__PURE__ */
|
|
6039
|
-
phase === "error" && error && /* @__PURE__ */
|
|
6218
|
+
showNoticesInMain && showNotices && /* @__PURE__ */ jsx19(Notices, { showAll: true, border: false }),
|
|
6219
|
+
/* @__PURE__ */ jsx19(Review, {}),
|
|
6220
|
+
!showTips && /* @__PURE__ */ jsx19(PromptInput, {}),
|
|
6221
|
+
phase === "error" && error && /* @__PURE__ */ jsx19(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs19(Text21, { color: COLORS.status.error, children: [
|
|
6040
6222
|
"\u2716 ",
|
|
6041
6223
|
error
|
|
6042
6224
|
] }) })
|
|
6043
6225
|
] }),
|
|
6044
|
-
!showNoticesInMain && showNotices && /* @__PURE__ */
|
|
6045
|
-
showTips && !holdForTip && /* @__PURE__ */
|
|
6226
|
+
!showNoticesInMain && showNotices && /* @__PURE__ */ jsx19(Notices, {}),
|
|
6227
|
+
showTips && !holdForTip && /* @__PURE__ */ jsx19(PromptInput, {})
|
|
6046
6228
|
]
|
|
6047
6229
|
}
|
|
6048
6230
|
),
|
|
6049
|
-
showSidebar ? /* @__PURE__ */
|
|
6231
|
+
showSidebar ? /* @__PURE__ */ jsx19(Sidebar, {}) : /* @__PURE__ */ jsx19(Ribbon, {})
|
|
6050
6232
|
]
|
|
6051
6233
|
}
|
|
6052
6234
|
),
|
|
6053
|
-
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */
|
|
6235
|
+
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */ jsx19(LearnMore, {}) : /* @__PURE__ */ jsx19(Welcome, {}))
|
|
6054
6236
|
]
|
|
6055
6237
|
}
|
|
6056
6238
|
)
|
|
@@ -6058,7 +6240,7 @@ function App() {
|
|
|
6058
6240
|
}
|
|
6059
6241
|
|
|
6060
6242
|
// src/lib/envAppId.ts
|
|
6061
|
-
import { readFile as
|
|
6243
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
6062
6244
|
import { join as join12 } from "node:path";
|
|
6063
6245
|
var ENV_FILES = [".env", ".env.local"];
|
|
6064
6246
|
var APP_ID_LINE = /^[ \t]*(?:export[ \t]+)?([A-Z0-9_]*ALGOLIA_APP(?:LICATION)?_ID)[ \t]*=[ \t]*(.*)$/gm;
|
|
@@ -6066,7 +6248,7 @@ async function findEnvApplicationId(root = process.cwd()) {
|
|
|
6066
6248
|
for (const file of ENV_FILES) {
|
|
6067
6249
|
let content;
|
|
6068
6250
|
try {
|
|
6069
|
-
content = await
|
|
6251
|
+
content = await readFile8(join12(root, file), "utf8");
|
|
6070
6252
|
} catch (err) {
|
|
6071
6253
|
if (err.code !== "ENOENT") {
|
|
6072
6254
|
logger.warn(
|
|
@@ -6417,7 +6599,7 @@ function delay(ms) {
|
|
|
6417
6599
|
}
|
|
6418
6600
|
|
|
6419
6601
|
// src/main.tsx
|
|
6420
|
-
import { jsx as
|
|
6602
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
6421
6603
|
async function startup() {
|
|
6422
6604
|
setProjectRoot(process.cwd());
|
|
6423
6605
|
let args;
|
|
@@ -6468,7 +6650,7 @@ ${formatStepList(workflow)}`);
|
|
|
6468
6650
|
async function run(opts) {
|
|
6469
6651
|
const { workflow, skipResumePrompt } = opts;
|
|
6470
6652
|
const store = useWizard.getState();
|
|
6471
|
-
const instance = render(/* @__PURE__ */
|
|
6653
|
+
const instance = render(/* @__PURE__ */ jsx20(App, {}), { incrementalRendering: true });
|
|
6472
6654
|
await store.waitForStart();
|
|
6473
6655
|
store.syncSteps(
|
|
6474
6656
|
workflow.steps.map((s) => ({
|