@algolia/wizard 0.41.0-rc.131.290 → 0.42.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 +202 -285
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -5,7 +5,7 @@ import { render } from "ink";
|
|
|
5
5
|
|
|
6
6
|
// src/ui/App.tsx
|
|
7
7
|
import { Box as Box20, Text as Text20, useApp, useInput as useInput7, useWindowSize as useWindowSize7 } from "ink";
|
|
8
|
-
import
|
|
8
|
+
import Spinner2 from "ink-spinner";
|
|
9
9
|
|
|
10
10
|
// src/core/store.ts
|
|
11
11
|
import { create } from "zustand";
|
|
@@ -259,14 +259,10 @@ var useWizard = create((set, get) => ({
|
|
|
259
259
|
error: null,
|
|
260
260
|
inputReq: null,
|
|
261
261
|
_resolve: null,
|
|
262
|
-
settingUpAppId: null,
|
|
263
|
-
setSettingUpApp: (appId) => set({ settingUpAppId: appId }),
|
|
264
262
|
// `endAuth` lands on 'preflight', not 'idle': sign-in happens after the
|
|
265
263
|
// welcome screen, so going back would gate the run a second time.
|
|
266
264
|
beginAuth: () => set({ phase: "authenticating", cliOutput: [] }),
|
|
267
|
-
endAuth: () => set(
|
|
268
|
-
(s) => s.phase === "authenticating" ? { phase: "preflight", cliOutput: [] } : {}
|
|
269
|
-
),
|
|
265
|
+
endAuth: () => set((s) => s.phase === "authenticating" ? { phase: "preflight" } : {}),
|
|
270
266
|
confirmStart: () => set(
|
|
271
267
|
(s) => s.phase === "idle" ? { phase: "preflight", homeScreen: "home" } : {}
|
|
272
268
|
),
|
|
@@ -413,8 +409,7 @@ var useWizard = create((set, get) => ({
|
|
|
413
409
|
logs: [],
|
|
414
410
|
error: null,
|
|
415
411
|
inputReq: null,
|
|
416
|
-
_resolve: null
|
|
417
|
-
settingUpAppId: null
|
|
412
|
+
_resolve: null
|
|
418
413
|
});
|
|
419
414
|
}
|
|
420
415
|
}));
|
|
@@ -642,7 +637,6 @@ function Notices({
|
|
|
642
637
|
|
|
643
638
|
// src/ui/PromptInput.tsx
|
|
644
639
|
import { Box as Box9, Text as Text9 } from "ink";
|
|
645
|
-
import Spinner from "ink-spinner";
|
|
646
640
|
import TextInput from "ink-text-input";
|
|
647
641
|
import { useState as useState6 } from "react";
|
|
648
642
|
|
|
@@ -663,27 +657,25 @@ function SelectRow({
|
|
|
663
657
|
labelWidth,
|
|
664
658
|
highlightBackground = true,
|
|
665
659
|
usePadding = false,
|
|
666
|
-
disabled = false,
|
|
667
660
|
children
|
|
668
661
|
}) {
|
|
669
|
-
const
|
|
670
|
-
const labelColor = disabled ? COLORS.dim : active ? highlightBackground ? COLORS.highlight.fg : COLORS.success : COLORS.primary;
|
|
662
|
+
const labelColor = highlighted ? highlightBackground ? COLORS.highlight.fg : COLORS.success : COLORS.primary;
|
|
671
663
|
return /* @__PURE__ */ jsxs3(
|
|
672
664
|
Box4,
|
|
673
665
|
{
|
|
674
666
|
width,
|
|
675
667
|
paddingX: usePadding ? 1 : 0,
|
|
676
668
|
paddingY: usePadding ? 1 : 0,
|
|
677
|
-
backgroundColor:
|
|
669
|
+
backgroundColor: highlighted && highlightBackground ? COLORS.highlight.bg : void 0,
|
|
678
670
|
children: [
|
|
679
671
|
/* @__PURE__ */ jsx3(Box4, { width: labelWidth, children: /* @__PURE__ */ jsxs3(
|
|
680
672
|
Text4,
|
|
681
673
|
{
|
|
682
674
|
color: labelColor,
|
|
683
|
-
bold:
|
|
675
|
+
bold: highlighted && !highlightBackground,
|
|
684
676
|
wrap: "truncate",
|
|
685
677
|
children: [
|
|
686
|
-
|
|
678
|
+
highlighted ? "\u276F " : " ",
|
|
687
679
|
label
|
|
688
680
|
]
|
|
689
681
|
}
|
|
@@ -883,14 +875,6 @@ var ARROW_WIDTH = 4;
|
|
|
883
875
|
var COLUMN_GAP = 2;
|
|
884
876
|
var BAR_PADDING = 2;
|
|
885
877
|
var ROW_HEIGHT = 3;
|
|
886
|
-
function nextSelectableIndex(start, dir, rowCount, isDisabled) {
|
|
887
|
-
let i = start;
|
|
888
|
-
for (let step = 0; step < rowCount; step++) {
|
|
889
|
-
i = (i + dir + rowCount) % rowCount;
|
|
890
|
-
if (!isDisabled(i)) return i;
|
|
891
|
-
}
|
|
892
|
-
return start;
|
|
893
|
-
}
|
|
894
878
|
function SelectPrompt({
|
|
895
879
|
options,
|
|
896
880
|
onSelect,
|
|
@@ -902,18 +886,15 @@ function SelectPrompt({
|
|
|
902
886
|
multi,
|
|
903
887
|
cancelable,
|
|
904
888
|
secondary,
|
|
905
|
-
disabled,
|
|
906
889
|
defaultSelectedIndex = 0
|
|
907
890
|
}) {
|
|
891
|
+
const [index, setIndex] = useState5(
|
|
892
|
+
() => defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0
|
|
893
|
+
);
|
|
894
|
+
const [checked, setChecked] = useState5(() => /* @__PURE__ */ new Set());
|
|
908
895
|
const hasCancel = Boolean(multi || cancelable);
|
|
909
896
|
const rows = hasCancel ? [...options, "Cancel"] : options;
|
|
910
897
|
const cancelIndex = hasCancel ? options.length : -1;
|
|
911
|
-
const isDisabled = (i) => i !== cancelIndex && Boolean(disabled?.[i]);
|
|
912
|
-
const [index, setIndex] = useState5(() => {
|
|
913
|
-
const start = defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0;
|
|
914
|
-
return isDisabled(start) ? nextSelectableIndex(start, 1, rows.length, isDisabled) : start;
|
|
915
|
-
});
|
|
916
|
-
const [checked, setChecked] = useState5(() => /* @__PURE__ */ new Set());
|
|
917
898
|
const hints = [];
|
|
918
899
|
if (rows.length > 1) hints.push({ key: "[\u2191] [\u2193]", label: "move" });
|
|
919
900
|
if (multi) hints.push({ key: "[space]", label: "select" });
|
|
@@ -953,15 +934,9 @@ function SelectPrompt({
|
|
|
953
934
|
useInput2((input, key) => {
|
|
954
935
|
if (rows.length === 0) return;
|
|
955
936
|
if (key.upArrow || input === "k") {
|
|
956
|
-
setIndex((i) =>
|
|
957
|
-
const next = (i - 1 + rows.length) % rows.length;
|
|
958
|
-
return isDisabled(next) ? i : next;
|
|
959
|
-
});
|
|
937
|
+
setIndex((i) => (i - 1 + rows.length) % rows.length);
|
|
960
938
|
} else if (key.downArrow || input === "j") {
|
|
961
|
-
setIndex((i) =>
|
|
962
|
-
const next = (i + 1) % rows.length;
|
|
963
|
-
return isDisabled(next) ? i : next;
|
|
964
|
-
});
|
|
939
|
+
setIndex((i) => (i + 1) % rows.length);
|
|
965
940
|
} else if (multi && input === " " && index !== cancelIndex) {
|
|
966
941
|
setChecked((prev) => {
|
|
967
942
|
const next = new Set(prev);
|
|
@@ -972,7 +947,6 @@ function SelectPrompt({
|
|
|
972
947
|
} else if (key.return) {
|
|
973
948
|
if (index === cancelIndex) {
|
|
974
949
|
onSelect(CANCEL);
|
|
975
|
-
} else if (isDisabled(index)) {
|
|
976
950
|
} else if (!multi) {
|
|
977
951
|
onSelect(options[index]);
|
|
978
952
|
} else if (checked.size > 0) {
|
|
@@ -997,12 +971,10 @@ function SelectPrompt({
|
|
|
997
971
|
const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
|
|
998
972
|
const sec = isCancel ? void 0 : secondary?.[i];
|
|
999
973
|
const isText = sec?.kind === "text";
|
|
1000
|
-
const rowDisabled = isDisabled(i);
|
|
1001
974
|
return /* @__PURE__ */ jsxs7(
|
|
1002
975
|
SelectRow,
|
|
1003
976
|
{
|
|
1004
977
|
highlighted,
|
|
1005
|
-
disabled: rowDisabled,
|
|
1006
978
|
width: isText ? "100%" : barWidth,
|
|
1007
979
|
labelWidth: isText ? labelWidth : barLabelWidth,
|
|
1008
980
|
label: `${bullet}${option}`,
|
|
@@ -1012,7 +984,7 @@ function SelectPrompt({
|
|
|
1012
984
|
Text8,
|
|
1013
985
|
{
|
|
1014
986
|
wrap: "truncate",
|
|
1015
|
-
color:
|
|
987
|
+
color: highlighted ? COLORS.primary : COLORS.muted,
|
|
1016
988
|
children: sec.value
|
|
1017
989
|
}
|
|
1018
990
|
) }),
|
|
@@ -1059,23 +1031,11 @@ function EnterToContinuePrompt({
|
|
|
1059
1031
|
function PromptInput() {
|
|
1060
1032
|
const { phase, inputReq, submitInput } = useWizard();
|
|
1061
1033
|
const [draft, setDraft] = useState6("");
|
|
1062
|
-
const [submittedReq, setSubmittedReq] = useState6(null);
|
|
1063
1034
|
const promptKey = inputReq && `${inputReq.promptType}:${inputReq.prompt}`;
|
|
1064
|
-
const submitting = inputReq != null && submittedReq === inputReq;
|
|
1065
1035
|
if (phase === "done" || phase === "error") {
|
|
1066
1036
|
return /* @__PURE__ */ jsx7(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text9, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
|
|
1067
1037
|
}
|
|
1068
1038
|
if (phase !== "awaitingInput" || !inputReq) return null;
|
|
1069
|
-
if (submitting) {
|
|
1070
|
-
return /* @__PURE__ */ jsx7(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsxs8(Text9, { color: COLORS.strong, bold: true, children: [
|
|
1071
|
-
/* @__PURE__ */ jsx7(Spinner, { type: "dots" }),
|
|
1072
|
-
" Continuing\u2026"
|
|
1073
|
-
] }) });
|
|
1074
|
-
}
|
|
1075
|
-
const handleSubmit = (value) => {
|
|
1076
|
-
setSubmittedReq(inputReq);
|
|
1077
|
-
submitInput(value);
|
|
1078
|
-
};
|
|
1079
1039
|
if (inputReq.promptType === "multipleChoice") {
|
|
1080
1040
|
return /* @__PURE__ */ jsx7(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx7(
|
|
1081
1041
|
SelectPrompt,
|
|
@@ -1086,11 +1046,10 @@ function PromptInput() {
|
|
|
1086
1046
|
table: inputReq.table,
|
|
1087
1047
|
options: inputReq.options,
|
|
1088
1048
|
secondary: inputReq.secondary,
|
|
1089
|
-
disabled: inputReq.disabled,
|
|
1090
1049
|
defaultSelectedIndex: inputReq.defaultSelectedIndex,
|
|
1091
1050
|
cancelable: inputReq.cancelable,
|
|
1092
1051
|
error: inputReq.error,
|
|
1093
|
-
onSelect:
|
|
1052
|
+
onSelect: submitInput
|
|
1094
1053
|
},
|
|
1095
1054
|
promptKey
|
|
1096
1055
|
) });
|
|
@@ -1106,7 +1065,7 @@ function PromptInput() {
|
|
|
1106
1065
|
table: inputReq.table,
|
|
1107
1066
|
options: inputReq.options,
|
|
1108
1067
|
error: inputReq.error,
|
|
1109
|
-
onSelect:
|
|
1068
|
+
onSelect: submitInput
|
|
1110
1069
|
},
|
|
1111
1070
|
promptKey
|
|
1112
1071
|
) });
|
|
@@ -1118,7 +1077,7 @@ function PromptInput() {
|
|
|
1118
1077
|
question: inputReq.prompt,
|
|
1119
1078
|
messages: inputReq.messages,
|
|
1120
1079
|
options: ["Continue"],
|
|
1121
|
-
onSelect:
|
|
1080
|
+
onSelect: submitInput
|
|
1122
1081
|
},
|
|
1123
1082
|
promptKey
|
|
1124
1083
|
) });
|
|
@@ -1145,7 +1104,7 @@ function PromptInput() {
|
|
|
1145
1104
|
messages: inputReq.messages,
|
|
1146
1105
|
options: labels,
|
|
1147
1106
|
secondary: inputReq.secondary,
|
|
1148
|
-
onSelect: (value) =>
|
|
1107
|
+
onSelect: (value) => submitInput(value === labels[0])
|
|
1149
1108
|
},
|
|
1150
1109
|
promptKey
|
|
1151
1110
|
) });
|
|
@@ -1605,10 +1564,6 @@ function reconcileWorkflowState(state, workflow) {
|
|
|
1605
1564
|
}
|
|
1606
1565
|
return state;
|
|
1607
1566
|
}
|
|
1608
|
-
async function loadResumableState(workflow) {
|
|
1609
|
-
const persisted = await loadWorkflowState(workflow.id);
|
|
1610
|
-
return persisted ? reconcileWorkflowState(persisted, workflow) : null;
|
|
1611
|
-
}
|
|
1612
1567
|
function initWorkflowState(workflow, now) {
|
|
1613
1568
|
return {
|
|
1614
1569
|
workflowId: workflow.id,
|
|
@@ -1711,11 +1666,11 @@ async function runStep(state, index, step, appId) {
|
|
|
1711
1666
|
durationMs: Date.now() - startedAt
|
|
1712
1667
|
});
|
|
1713
1668
|
}
|
|
1714
|
-
async function runWorkflow(workflow, appId
|
|
1669
|
+
async function runWorkflow(workflow, appId) {
|
|
1715
1670
|
const store = useWizard.getState();
|
|
1716
1671
|
try {
|
|
1717
|
-
const
|
|
1718
|
-
const state =
|
|
1672
|
+
const persisted = await loadWorkflowState(workflow.id);
|
|
1673
|
+
const state = (persisted && reconcileWorkflowState(persisted, workflow)) ?? initWorkflowState(workflow, nowIso());
|
|
1719
1674
|
ensureExecutedStepCount(state);
|
|
1720
1675
|
store.startWorkflow(
|
|
1721
1676
|
{
|
|
@@ -1807,89 +1762,14 @@ async function listIndices() {
|
|
|
1807
1762
|
return items.map((i) => ({ name: i.name, entries: i.entries })).sort((a, b) => a.name.localeCompare(b.name));
|
|
1808
1763
|
}
|
|
1809
1764
|
|
|
1810
|
-
// src/lib/algoliaApp.ts
|
|
1811
|
-
import { z as z5 } from "zod";
|
|
1812
|
-
var applicationSchema = z5.object({
|
|
1813
|
-
id: z5.string().min(1),
|
|
1814
|
-
name: z5.string().default(""),
|
|
1815
|
-
plan: z5.string().optional()
|
|
1816
|
-
});
|
|
1817
|
-
var listSchema = z5.array(
|
|
1818
|
-
z5.object({
|
|
1819
|
-
id: z5.string().min(1),
|
|
1820
|
-
name: z5.string().default(""),
|
|
1821
|
-
plan_label: z5.string().optional(),
|
|
1822
|
-
status: z5.string().optional(),
|
|
1823
|
-
acl: z5.array(z5.string()).optional()
|
|
1824
|
-
}).transform(({ id, name, plan_label, status, acl }) => ({
|
|
1825
|
-
id,
|
|
1826
|
-
name,
|
|
1827
|
-
plan: plan_label,
|
|
1828
|
-
status,
|
|
1829
|
-
acl
|
|
1830
|
-
}))
|
|
1831
|
-
);
|
|
1832
|
-
function canSelectApplication(app) {
|
|
1833
|
-
return app.status === "active" && (app.acl ?? []).includes("keys");
|
|
1834
|
-
}
|
|
1835
|
-
async function currentApplication() {
|
|
1836
|
-
let raw;
|
|
1837
|
-
try {
|
|
1838
|
-
raw = await runAlgoliaCli(["application", "current", "-o", "json"]);
|
|
1839
|
-
} catch {
|
|
1840
|
-
return null;
|
|
1841
|
-
}
|
|
1842
|
-
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
1843
|
-
return parsed.success ? parsed.data : null;
|
|
1844
|
-
}
|
|
1845
|
-
async function requireApplication() {
|
|
1846
|
-
const app = await currentApplication();
|
|
1847
|
-
if (!app) {
|
|
1848
|
-
throw new Error(
|
|
1849
|
-
"No Algolia application is selected. Run `npx @algolia/cli@latest application select` and restart the wizard."
|
|
1850
|
-
);
|
|
1851
|
-
}
|
|
1852
|
-
return app;
|
|
1853
|
-
}
|
|
1854
|
-
async function listApplications() {
|
|
1855
|
-
const raw = await runAlgoliaCli(["application", "list", "-o", "json"]);
|
|
1856
|
-
const parsed = listSchema.safeParse(parseJson(raw));
|
|
1857
|
-
if (!parsed.success) {
|
|
1858
|
-
throw new Error("Could not read the list of Algolia applications.");
|
|
1859
|
-
}
|
|
1860
|
-
return parsed.data;
|
|
1861
|
-
}
|
|
1862
|
-
async function selectApplication(id) {
|
|
1863
|
-
const raw = await runAlgoliaCli(
|
|
1864
|
-
["application", "select", "--non-interactive", "--app-id", id],
|
|
1865
|
-
{ onOutput: stderrSink }
|
|
1866
|
-
);
|
|
1867
|
-
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
1868
|
-
if (!parsed.success) {
|
|
1869
|
-
throw new Error(
|
|
1870
|
-
`Selected application ${id}, but the Algolia CLI returned an unreadable result.`
|
|
1871
|
-
);
|
|
1872
|
-
}
|
|
1873
|
-
return parsed.data;
|
|
1874
|
-
}
|
|
1875
|
-
function parseJson(text) {
|
|
1876
|
-
try {
|
|
1877
|
-
return JSON.parse(text);
|
|
1878
|
-
} catch {
|
|
1879
|
-
return void 0;
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
1765
|
// src/actions/selectIndex.ts
|
|
1884
1766
|
var CREATE_NEW_INDEX = "Create a new index\u2026";
|
|
1885
1767
|
var selectIndexStep = async (ctx) => {
|
|
1886
|
-
await requireApplication();
|
|
1887
1768
|
const indices = await listIndices();
|
|
1888
1769
|
const names = indices.map((i) => i.name);
|
|
1889
1770
|
const hasIndices = names.length > 0;
|
|
1890
1771
|
let error;
|
|
1891
|
-
|
|
1892
|
-
while (chosen === void 0) {
|
|
1772
|
+
for (; ; ) {
|
|
1893
1773
|
const selection = hasIndices ? await ctx.requestUserInput({
|
|
1894
1774
|
prompt: "Which index do you want to ingest into?",
|
|
1895
1775
|
promptType: "multipleChoice",
|
|
@@ -1908,9 +1788,9 @@ var selectIndexStep = async (ctx) => {
|
|
|
1908
1788
|
if (typeof selection !== "string") {
|
|
1909
1789
|
throw new Error("selectIndex received an unexpected non-text result");
|
|
1910
1790
|
}
|
|
1911
|
-
let
|
|
1791
|
+
let chosen;
|
|
1912
1792
|
if (!hasIndices) {
|
|
1913
|
-
|
|
1793
|
+
chosen = selection.trim();
|
|
1914
1794
|
} else if (selection === CREATE_NEW_INDEX) {
|
|
1915
1795
|
const name = await ctx.requestUserInput({
|
|
1916
1796
|
prompt: "Name the new index:",
|
|
@@ -1920,18 +1800,17 @@ var selectIndexStep = async (ctx) => {
|
|
|
1920
1800
|
if (typeof name !== "string") {
|
|
1921
1801
|
throw new Error("selectIndex received an unexpected non-text result");
|
|
1922
1802
|
}
|
|
1923
|
-
|
|
1803
|
+
chosen = name.trim();
|
|
1924
1804
|
} else {
|
|
1925
|
-
|
|
1805
|
+
chosen = selection;
|
|
1926
1806
|
}
|
|
1927
|
-
if (!
|
|
1807
|
+
if (!chosen) {
|
|
1928
1808
|
error = "Index name cannot be empty.";
|
|
1929
1809
|
continue;
|
|
1930
1810
|
}
|
|
1931
|
-
chosen
|
|
1811
|
+
ctx.setUserInput("index", chosen);
|
|
1812
|
+
return { selection: chosen };
|
|
1932
1813
|
}
|
|
1933
|
-
ctx.setUserInput("index", chosen);
|
|
1934
|
-
return { selection: chosen };
|
|
1935
1814
|
};
|
|
1936
1815
|
|
|
1937
1816
|
// src/lib/agent.ts
|
|
@@ -1950,7 +1829,7 @@ import "zod";
|
|
|
1950
1829
|
|
|
1951
1830
|
// src/lib/tools/listFiles.ts
|
|
1952
1831
|
import { tool } from "ai";
|
|
1953
|
-
import
|
|
1832
|
+
import z5 from "zod";
|
|
1954
1833
|
import { readdir } from "node:fs/promises";
|
|
1955
1834
|
|
|
1956
1835
|
// src/lib/tools/path.ts
|
|
@@ -1986,8 +1865,8 @@ async function hasSymlinkParent(ctx, target) {
|
|
|
1986
1865
|
function listFilesTool(ctx) {
|
|
1987
1866
|
return tool({
|
|
1988
1867
|
description: 'List files in a directory (default: the current working directory). Pass path to list a subdirectory directly \u2014 e.g. "packages/api" \u2014 without first changeDirectory-ing into it.',
|
|
1989
|
-
inputSchema:
|
|
1990
|
-
path:
|
|
1868
|
+
inputSchema: z5.object({
|
|
1869
|
+
path: z5.string().optional().describe("Directory to list, relative to cwd (default: cwd)")
|
|
1991
1870
|
}),
|
|
1992
1871
|
execute: async ({ path = "." }) => {
|
|
1993
1872
|
logger.info({ path }, "called listFiles tool");
|
|
@@ -2008,13 +1887,13 @@ function listFilesTool(ctx) {
|
|
|
2008
1887
|
|
|
2009
1888
|
// src/lib/tools/changeDirectory.ts
|
|
2010
1889
|
import { tool as tool2 } from "ai";
|
|
2011
|
-
import
|
|
1890
|
+
import z6 from "zod";
|
|
2012
1891
|
import { stat } from "node:fs/promises";
|
|
2013
1892
|
function changeDirectoryTool(ctx) {
|
|
2014
1893
|
return tool2({
|
|
2015
1894
|
description: "Change the current working directory. Subsequent file operations resolve relative to it. Returns the new working directory.",
|
|
2016
|
-
inputSchema:
|
|
2017
|
-
path:
|
|
1895
|
+
inputSchema: z6.object({
|
|
1896
|
+
path: z6.string().describe("Directory to change into")
|
|
2018
1897
|
}),
|
|
2019
1898
|
execute: async ({ path }) => {
|
|
2020
1899
|
logger.info({ path }, "called changeDirectory tool");
|
|
@@ -2036,13 +1915,13 @@ function changeDirectoryTool(ctx) {
|
|
|
2036
1915
|
|
|
2037
1916
|
// src/lib/tools/reportStatus.ts
|
|
2038
1917
|
import { tool as tool3 } from "ai";
|
|
2039
|
-
import
|
|
1918
|
+
import z7 from "zod";
|
|
2040
1919
|
function reportStatusTool(output) {
|
|
2041
1920
|
return tool3({
|
|
2042
1921
|
description: "Report the status of your execution. Return a reason in case of failure.",
|
|
2043
|
-
inputSchema:
|
|
2044
|
-
status:
|
|
2045
|
-
reason:
|
|
1922
|
+
inputSchema: z7.object({
|
|
1923
|
+
status: z7.enum(["success", "fail"]),
|
|
1924
|
+
reason: z7.string().optional(),
|
|
2046
1925
|
output
|
|
2047
1926
|
}),
|
|
2048
1927
|
execute: async ({ status, reason, output: output2 }) => {
|
|
@@ -2054,7 +1933,7 @@ function reportStatusTool(output) {
|
|
|
2054
1933
|
|
|
2055
1934
|
// src/lib/tools/readFile.ts
|
|
2056
1935
|
import { tool as tool4 } from "ai";
|
|
2057
|
-
import
|
|
1936
|
+
import z8 from "zod";
|
|
2058
1937
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
2059
1938
|
|
|
2060
1939
|
// src/lib/tools/env.ts
|
|
@@ -2082,8 +1961,8 @@ function redactEnvValues(content) {
|
|
|
2082
1961
|
function readFileTool(ctx) {
|
|
2083
1962
|
return tool4({
|
|
2084
1963
|
description: "Read the contents of a file at the given path",
|
|
2085
|
-
inputSchema:
|
|
2086
|
-
filePath:
|
|
1964
|
+
inputSchema: z8.object({
|
|
1965
|
+
filePath: z8.string().describe("Path to the file to read")
|
|
2087
1966
|
}),
|
|
2088
1967
|
execute: async ({ filePath }) => {
|
|
2089
1968
|
if (++ctx.counts.read > ctx.limits.read) {
|
|
@@ -2104,15 +1983,15 @@ function readFileTool(ctx) {
|
|
|
2104
1983
|
|
|
2105
1984
|
// src/lib/tools/writeFile.ts
|
|
2106
1985
|
import { tool as tool5 } from "ai";
|
|
2107
|
-
import
|
|
1986
|
+
import z9 from "zod";
|
|
2108
1987
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
2109
1988
|
import { dirname as dirname3 } from "node:path";
|
|
2110
1989
|
function writeFileTool(ctx) {
|
|
2111
1990
|
return tool5({
|
|
2112
1991
|
description: "Write content to a file at the given path, overwriting it. Writes to secret env files (.env, .env.local, etc.) are refused by this tool \u2014 call it anyway and the tool will tell you how to proceed.",
|
|
2113
|
-
inputSchema:
|
|
2114
|
-
filePath:
|
|
2115
|
-
content:
|
|
1992
|
+
inputSchema: z9.object({
|
|
1993
|
+
filePath: z9.string().describe("Path to the file to write"),
|
|
1994
|
+
content: z9.string().describe("Content to write to the file")
|
|
2116
1995
|
}),
|
|
2117
1996
|
execute: async ({ filePath, content }) => {
|
|
2118
1997
|
logger.info({ filePath }, "called writeFile tool");
|
|
@@ -2142,6 +2021,68 @@ import z13 from "zod";
|
|
|
2142
2021
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
|
|
2143
2022
|
import { dirname as dirname4, relative as relative3 } from "node:path";
|
|
2144
2023
|
|
|
2024
|
+
// src/lib/algoliaApp.ts
|
|
2025
|
+
import { z as z10 } from "zod";
|
|
2026
|
+
var applicationSchema = z10.object({
|
|
2027
|
+
id: z10.string().min(1),
|
|
2028
|
+
name: z10.string().default(""),
|
|
2029
|
+
plan: z10.string().optional()
|
|
2030
|
+
});
|
|
2031
|
+
var listSchema = z10.array(
|
|
2032
|
+
z10.object({
|
|
2033
|
+
id: z10.string().min(1),
|
|
2034
|
+
name: z10.string().default(""),
|
|
2035
|
+
plan_label: z10.string().optional()
|
|
2036
|
+
}).transform(({ id, name, plan_label }) => ({ id, name, plan: plan_label }))
|
|
2037
|
+
);
|
|
2038
|
+
async function currentApplication() {
|
|
2039
|
+
let raw;
|
|
2040
|
+
try {
|
|
2041
|
+
raw = await runAlgoliaCli(["application", "current", "-o", "json"]);
|
|
2042
|
+
} catch {
|
|
2043
|
+
return null;
|
|
2044
|
+
}
|
|
2045
|
+
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
2046
|
+
return parsed.success ? parsed.data : null;
|
|
2047
|
+
}
|
|
2048
|
+
async function requireApplication() {
|
|
2049
|
+
const app = await currentApplication();
|
|
2050
|
+
if (!app) {
|
|
2051
|
+
throw new Error(
|
|
2052
|
+
"No Algolia application is selected. Run `npx @algolia/cli@latest application select` and restart the wizard."
|
|
2053
|
+
);
|
|
2054
|
+
}
|
|
2055
|
+
return app;
|
|
2056
|
+
}
|
|
2057
|
+
async function listApplications() {
|
|
2058
|
+
const raw = await runAlgoliaCli(["application", "list", "-o", "json"]);
|
|
2059
|
+
const parsed = listSchema.safeParse(parseJson(raw));
|
|
2060
|
+
if (!parsed.success) {
|
|
2061
|
+
throw new Error("Could not read the list of Algolia applications.");
|
|
2062
|
+
}
|
|
2063
|
+
return parsed.data;
|
|
2064
|
+
}
|
|
2065
|
+
async function selectApplication(id) {
|
|
2066
|
+
const raw = await runAlgoliaCli(
|
|
2067
|
+
["application", "select", "--non-interactive", "--app-id", id],
|
|
2068
|
+
{ onOutput: stderrSink }
|
|
2069
|
+
);
|
|
2070
|
+
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
2071
|
+
if (!parsed.success) {
|
|
2072
|
+
throw new Error(
|
|
2073
|
+
`Selected application ${id}, but the Algolia CLI returned an unreadable result.`
|
|
2074
|
+
);
|
|
2075
|
+
}
|
|
2076
|
+
return parsed.data;
|
|
2077
|
+
}
|
|
2078
|
+
function parseJson(text) {
|
|
2079
|
+
try {
|
|
2080
|
+
return JSON.parse(text);
|
|
2081
|
+
} catch {
|
|
2082
|
+
return void 0;
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2145
2086
|
// src/lib/algoliaApiKey.ts
|
|
2146
2087
|
import { z as z12 } from "zod";
|
|
2147
2088
|
|
|
@@ -2149,13 +2090,13 @@ import { z as z12 } from "zod";
|
|
|
2149
2090
|
import { deletePassword, getPassword, setPassword } from "cross-keychain";
|
|
2150
2091
|
import { z as z11 } from "zod";
|
|
2151
2092
|
var SERVICE = "algolia-wizard";
|
|
2152
|
-
var
|
|
2093
|
+
var ACCOUNT = "api-keys";
|
|
2153
2094
|
var storedKeysSchema = z11.record(z11.string(), z11.string());
|
|
2154
2095
|
function entryId(kind, index, appId) {
|
|
2155
2096
|
return `${kind}:${appId}:${index}`;
|
|
2156
2097
|
}
|
|
2157
|
-
async function loadKeys(
|
|
2158
|
-
const raw = await getPassword(SERVICE,
|
|
2098
|
+
async function loadKeys() {
|
|
2099
|
+
const raw = await getPassword(SERVICE, ACCOUNT);
|
|
2159
2100
|
if (!raw) return {};
|
|
2160
2101
|
let payload;
|
|
2161
2102
|
try {
|
|
@@ -2177,47 +2118,47 @@ function serialized(op) {
|
|
|
2177
2118
|
});
|
|
2178
2119
|
return next;
|
|
2179
2120
|
}
|
|
2180
|
-
async function readStoredKey(kind,
|
|
2121
|
+
async function readStoredKey(kind, index, appId) {
|
|
2181
2122
|
try {
|
|
2182
|
-
return (await loadKeys(
|
|
2123
|
+
return (await loadKeys())[entryId(kind, index, appId)] ?? null;
|
|
2183
2124
|
} catch (err) {
|
|
2184
2125
|
logger.warn(
|
|
2185
|
-
{ err: err.message, kind, index, appId
|
|
2126
|
+
{ err: err.message, kind, index, appId },
|
|
2186
2127
|
"could not read the API key from the keychain"
|
|
2187
2128
|
);
|
|
2188
2129
|
return null;
|
|
2189
2130
|
}
|
|
2190
2131
|
}
|
|
2191
|
-
function storeKey(kind,
|
|
2132
|
+
function storeKey(kind, index, appId, value) {
|
|
2192
2133
|
return serialized(async () => {
|
|
2193
2134
|
const id = entryId(kind, index, appId);
|
|
2194
2135
|
try {
|
|
2195
|
-
const keys = await loadKeys(
|
|
2136
|
+
const keys = await loadKeys();
|
|
2196
2137
|
await setPassword(
|
|
2197
2138
|
SERVICE,
|
|
2198
|
-
|
|
2139
|
+
ACCOUNT,
|
|
2199
2140
|
JSON.stringify({ ...keys, [id]: value })
|
|
2200
2141
|
);
|
|
2201
|
-
if ((await loadKeys(
|
|
2142
|
+
if ((await loadKeys())[id] !== value) {
|
|
2202
2143
|
throw new Error("the keychain did not store the value");
|
|
2203
2144
|
}
|
|
2204
2145
|
} catch (err) {
|
|
2205
2146
|
logger.warn(
|
|
2206
|
-
{ err: err.message, kind, index, appId
|
|
2147
|
+
{ err: err.message, kind, index, appId },
|
|
2207
2148
|
"could not store the API key in the keychain; the next run will create another"
|
|
2208
2149
|
);
|
|
2209
2150
|
}
|
|
2210
2151
|
});
|
|
2211
2152
|
}
|
|
2212
|
-
function deleteStoredKeys(
|
|
2153
|
+
function deleteStoredKeys() {
|
|
2213
2154
|
return serialized(async () => {
|
|
2214
2155
|
try {
|
|
2215
|
-
await deletePassword(SERVICE,
|
|
2156
|
+
await deletePassword(SERVICE, ACCOUNT);
|
|
2216
2157
|
} catch (err) {
|
|
2217
2158
|
const message = err.message;
|
|
2218
2159
|
if (/not found/i.test(message)) return;
|
|
2219
2160
|
logger.warn(
|
|
2220
|
-
{ err: message
|
|
2161
|
+
{ err: message },
|
|
2221
2162
|
"could not delete the API keys from the keychain"
|
|
2222
2163
|
);
|
|
2223
2164
|
}
|
|
@@ -2225,16 +2166,6 @@ function deleteStoredKeys(userId) {
|
|
|
2225
2166
|
}
|
|
2226
2167
|
|
|
2227
2168
|
// src/lib/algoliaApiKey.ts
|
|
2228
|
-
function requireUserId() {
|
|
2229
|
-
const userId = useWizard.getState().user?.userId;
|
|
2230
|
-
if (!userId) {
|
|
2231
|
-
throw new Error("No Algolia user is signed in; cannot scope the API key.");
|
|
2232
|
-
}
|
|
2233
|
-
return userId;
|
|
2234
|
-
}
|
|
2235
|
-
async function currentUserId() {
|
|
2236
|
-
return useWizard.getState().user?.userId ?? (await getUser())?.userId ?? null;
|
|
2237
|
-
}
|
|
2238
2169
|
var WRITE_ACLS = [
|
|
2239
2170
|
"addObject",
|
|
2240
2171
|
"deleteObject",
|
|
@@ -2281,30 +2212,23 @@ async function keyExists(key) {
|
|
|
2281
2212
|
var resolved = /* @__PURE__ */ new Map();
|
|
2282
2213
|
async function forgetResolvedKeys() {
|
|
2283
2214
|
resolved.clear();
|
|
2284
|
-
|
|
2285
|
-
if (userId) await deleteStoredKeys(userId);
|
|
2215
|
+
await deleteStoredKeys();
|
|
2286
2216
|
}
|
|
2287
2217
|
function resolveKey(kind, index, appId, acls, description) {
|
|
2288
|
-
const
|
|
2289
|
-
const cacheKey = `${userId}:${kind}:${appId}:${index}`;
|
|
2218
|
+
const cacheKey = `${kind}:${appId}:${index}`;
|
|
2290
2219
|
const cached = resolved.get(cacheKey);
|
|
2291
2220
|
if (cached) return cached;
|
|
2292
|
-
const pending = provisionKey(
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
description
|
|
2299
|
-
).catch((err) => {
|
|
2300
|
-
resolved.delete(cacheKey);
|
|
2301
|
-
throw err;
|
|
2302
|
-
});
|
|
2221
|
+
const pending = provisionKey(kind, index, appId, acls, description).catch(
|
|
2222
|
+
(err) => {
|
|
2223
|
+
resolved.delete(cacheKey);
|
|
2224
|
+
throw err;
|
|
2225
|
+
}
|
|
2226
|
+
);
|
|
2303
2227
|
resolved.set(cacheKey, pending);
|
|
2304
2228
|
return pending;
|
|
2305
2229
|
}
|
|
2306
|
-
async function provisionKey(kind,
|
|
2307
|
-
const stored = await readStoredKey(kind,
|
|
2230
|
+
async function provisionKey(kind, index, appId, acls, description) {
|
|
2231
|
+
const stored = await readStoredKey(kind, index, appId);
|
|
2308
2232
|
if (stored) {
|
|
2309
2233
|
if (await keyExists(stored)) {
|
|
2310
2234
|
logger.info({ kind, index, appId }, "reusing the stored API key");
|
|
@@ -2316,7 +2240,7 @@ async function provisionKey(kind, userId, index, appId, acls, description) {
|
|
|
2316
2240
|
);
|
|
2317
2241
|
}
|
|
2318
2242
|
const key = await createKey(index, acls, description);
|
|
2319
|
-
await storeKey(kind,
|
|
2243
|
+
await storeKey(kind, index, appId, key);
|
|
2320
2244
|
return { key, source: "created" };
|
|
2321
2245
|
}
|
|
2322
2246
|
function resolveWriteKey(index, appId) {
|
|
@@ -3548,7 +3472,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3548
3472
|
// package.json
|
|
3549
3473
|
var package_default = {
|
|
3550
3474
|
name: "@algolia/wizard",
|
|
3551
|
-
version: "0.
|
|
3475
|
+
version: "0.42.0",
|
|
3552
3476
|
description: "Magically implement Algolia functionality in your codebase",
|
|
3553
3477
|
type: "module",
|
|
3554
3478
|
engines: {
|
|
@@ -4419,10 +4343,6 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
4419
4343
|
if (useCases.includes("ingestion")) {
|
|
4420
4344
|
ingestAppId = appId ?? (await requireApplication()).id;
|
|
4421
4345
|
}
|
|
4422
|
-
let ingestWriteKey;
|
|
4423
|
-
if (useCases.includes("ingestion") && ingestAppId) {
|
|
4424
|
-
ingestWriteKey = (await resolveWriteKey(targetIndex, ingestAppId)).key;
|
|
4425
|
-
}
|
|
4426
4346
|
let uploadFilePath;
|
|
4427
4347
|
let uploadWarning;
|
|
4428
4348
|
if (ingestionSource === "fileUpload") {
|
|
@@ -4485,9 +4405,9 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
4485
4405
|
let ingestDurationMs;
|
|
4486
4406
|
let ingestOutcomeMessage;
|
|
4487
4407
|
const ingestKeyAppId = ingestAppId;
|
|
4488
|
-
const ingestionTools = ingestKeyAppId
|
|
4408
|
+
const ingestionTools = ingestKeyAppId ? makeToolContext(repoRoot, async () => ({
|
|
4489
4409
|
[APP_ID_VAR]: ingestKeyAppId,
|
|
4490
|
-
[API_KEY_VAR]:
|
|
4410
|
+
[API_KEY_VAR]: (await resolveWriteKey(targetIndex, ingestKeyAppId)).key,
|
|
4491
4411
|
[INDEX_NAME_VAR]: targetIndex
|
|
4492
4412
|
})) : void 0;
|
|
4493
4413
|
const searchTools = makeToolContext(repoRoot);
|
|
@@ -5082,13 +5002,13 @@ import { Box as Box15, Text as Text15 } from "ink";
|
|
|
5082
5002
|
|
|
5083
5003
|
// src/ui/Steps.tsx
|
|
5084
5004
|
import { Box as Box13, Text as Text13 } from "ink";
|
|
5085
|
-
import
|
|
5005
|
+
import Spinner from "ink-spinner";
|
|
5086
5006
|
import { jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5087
5007
|
function Steps() {
|
|
5088
5008
|
const { steps } = useWizard();
|
|
5089
5009
|
const visibleSteps = steps.filter(isStepVisible);
|
|
5090
5010
|
return /* @__PURE__ */ jsx11(Box13, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx11(Box13, { flexDirection: "column", children: /* @__PURE__ */ jsxs12(Text13, { color: COLORS.status[s.status], children: [
|
|
5091
|
-
s.status === "running" ? /* @__PURE__ */ jsx11(
|
|
5011
|
+
s.status === "running" ? /* @__PURE__ */ jsx11(Spinner, { type: "dots" }) : MARKER[s.status],
|
|
5092
5012
|
" ",
|
|
5093
5013
|
s.title
|
|
5094
5014
|
] }) }, s.id)) });
|
|
@@ -5098,7 +5018,7 @@ function CurrentStep() {
|
|
|
5098
5018
|
const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
|
|
5099
5019
|
if (!currentStep) return null;
|
|
5100
5020
|
return /* @__PURE__ */ jsxs12(Text13, { color: COLORS.status.running, children: [
|
|
5101
|
-
/* @__PURE__ */ jsx11(
|
|
5021
|
+
/* @__PURE__ */ jsx11(Spinner, { type: "dots" }),
|
|
5102
5022
|
" ",
|
|
5103
5023
|
` ${currentStep.title}`
|
|
5104
5024
|
] });
|
|
@@ -5643,7 +5563,6 @@ function App() {
|
|
|
5643
5563
|
inputReq,
|
|
5644
5564
|
user,
|
|
5645
5565
|
workflow,
|
|
5646
|
-
settingUpAppId,
|
|
5647
5566
|
review: review2
|
|
5648
5567
|
} = useWizard();
|
|
5649
5568
|
const { exit } = useApp();
|
|
@@ -5659,7 +5578,7 @@ function App() {
|
|
|
5659
5578
|
const isCommandApprovalPrompt = isAwaitingUserInput && inputReq?.promptType === "commandApproval";
|
|
5660
5579
|
const promptPending = isAwaitingUserInput && !isCommandApprovalPrompt;
|
|
5661
5580
|
const holdForTip = stepHasTips && promptPending && tipState === "revealing";
|
|
5662
|
-
const showTips = stepHasTips && (phase === "running"
|
|
5581
|
+
const showTips = stepHasTips && (phase === "running" || isCommandApprovalPrompt || holdForTip);
|
|
5663
5582
|
const showNoticesInMain = !stepHasTips;
|
|
5664
5583
|
const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
|
|
5665
5584
|
useInput7(
|
|
@@ -5730,26 +5649,20 @@ function App() {
|
|
|
5730
5649
|
children: [
|
|
5731
5650
|
/* @__PURE__ */ jsxs18(Box20, { flexGrow: 2, flexDirection: "column", children: [
|
|
5732
5651
|
phase === "preflight" && !user && /* @__PURE__ */ jsx18(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.strong, bold: true, children: [
|
|
5733
|
-
/* @__PURE__ */ jsx18(
|
|
5652
|
+
/* @__PURE__ */ jsx18(Spinner2, { type: "dots" }),
|
|
5734
5653
|
" Signing in to Algolia"
|
|
5735
5654
|
] }) }),
|
|
5736
5655
|
phase === "preflight" && user && /* @__PURE__ */ jsx18(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.strong, bold: true, children: [
|
|
5737
|
-
/* @__PURE__ */ jsx18(
|
|
5656
|
+
/* @__PURE__ */ jsx18(Spinner2, { type: "dots" }),
|
|
5738
5657
|
" Getting things ready"
|
|
5739
5658
|
] }) }),
|
|
5740
5659
|
phase === "authenticating" && /* @__PURE__ */ jsxs18(Box20, { flexDirection: "column", marginBottom: 1, children: [
|
|
5741
5660
|
/* @__PURE__ */ jsxs18(Text20, { color: COLORS.strong, bold: true, children: [
|
|
5742
|
-
/* @__PURE__ */ jsx18(
|
|
5661
|
+
/* @__PURE__ */ jsx18(Spinner2, { type: "dots" }),
|
|
5743
5662
|
" Signing in to Algolia"
|
|
5744
5663
|
] }),
|
|
5745
5664
|
/* @__PURE__ */ jsx18(Text20, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
|
|
5746
5665
|
] }),
|
|
5747
|
-
settingUpAppId && /* @__PURE__ */ jsx18(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.strong, bold: true, children: [
|
|
5748
|
-
/* @__PURE__ */ jsx18(Spinner3, { type: "dots" }),
|
|
5749
|
-
" Setting up Wizard using app",
|
|
5750
|
-
" ",
|
|
5751
|
-
settingUpAppId
|
|
5752
|
-
] }) }),
|
|
5753
5666
|
/* @__PURE__ */ jsx18(CliOutput, {}),
|
|
5754
5667
|
showTips && currentStep && /* @__PURE__ */ jsx18(
|
|
5755
5668
|
Tips,
|
|
@@ -5820,72 +5733,50 @@ function readValue(raw) {
|
|
|
5820
5733
|
}
|
|
5821
5734
|
|
|
5822
5735
|
// src/lib/algoliaAppPicker.ts
|
|
5823
|
-
function
|
|
5824
|
-
return app.status !== "active" ? "Paused" : "Missing permissions";
|
|
5825
|
-
}
|
|
5826
|
-
function secondaryFor(app, highlightId) {
|
|
5827
|
-
if (!canSelectApplication(app)) {
|
|
5828
|
-
return { kind: "text", value: blockReasonFor(app) };
|
|
5829
|
-
}
|
|
5830
|
-
if (app.id === highlightId) {
|
|
5831
|
-
return { kind: "badge", value: "[DETECTED]" };
|
|
5832
|
-
}
|
|
5736
|
+
function secondaryFor(app) {
|
|
5833
5737
|
return app.plan ? { kind: "badge", value: app.plan } : void 0;
|
|
5834
5738
|
}
|
|
5835
5739
|
function labelFor(app) {
|
|
5836
5740
|
return app.name.trim() ? `${app.name} \u2014 ${app.id}` : app.id;
|
|
5837
5741
|
}
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
const store = useWizard.getState();
|
|
5845
|
-
store.setSettingUpApp(app.id);
|
|
5846
|
-
try {
|
|
5847
|
-
return await selectApplication(app.id);
|
|
5848
|
-
} finally {
|
|
5849
|
-
store.setSettingUpApp(null);
|
|
5850
|
-
}
|
|
5742
|
+
function selectAndReport(app) {
|
|
5743
|
+
useWizard.getState().pushCliOutput(
|
|
5744
|
+
"stdout",
|
|
5745
|
+
`Selecting ${labelFor(app)} \u2014 provisioning its API key\u2026`
|
|
5746
|
+
);
|
|
5747
|
+
return selectApplication(app.id);
|
|
5851
5748
|
}
|
|
5852
|
-
async function promptForApplication(
|
|
5749
|
+
async function promptForApplication(leadIn = []) {
|
|
5853
5750
|
const store = useWizard.getState();
|
|
5854
|
-
const
|
|
5855
|
-
if (
|
|
5751
|
+
const apps = await listApplications();
|
|
5752
|
+
if (apps.length === 0) {
|
|
5856
5753
|
throw new Error(
|
|
5857
5754
|
"This Algolia account has no applications. Create one in the Algolia dashboard, or with `npx @algolia/cli@latest application create`, then restart the wizard."
|
|
5858
5755
|
);
|
|
5859
5756
|
}
|
|
5860
|
-
if (
|
|
5861
|
-
|
|
5862
|
-
|
|
5757
|
+
if (apps.length === 1) {
|
|
5758
|
+
const only = apps[0];
|
|
5759
|
+
logger.info(
|
|
5760
|
+
{ app: only.id },
|
|
5761
|
+
"single application on the account; selecting it"
|
|
5863
5762
|
);
|
|
5763
|
+
for (const line of leadIn) store.pushCliOutput("stdout", line);
|
|
5764
|
+
return selectAndReport(only);
|
|
5864
5765
|
}
|
|
5865
|
-
const
|
|
5866
|
-
...
|
|
5867
|
-
|
|
5766
|
+
const messages = [
|
|
5767
|
+
...leadIn,
|
|
5768
|
+
"Which Algolia application should the wizard work in?"
|
|
5868
5769
|
];
|
|
5869
|
-
const envApp = highlight ? unordered.find((app) => app.id === highlight.id) : void 0;
|
|
5870
|
-
const highlightIndex = envApp && canSelectApplication(envApp) ? apps.indexOf(envApp) : -1;
|
|
5871
|
-
const messages = [];
|
|
5872
|
-
if (highlight && highlightIndex < 0) {
|
|
5873
|
-
messages.push(
|
|
5874
|
-
envApp ? `Could not use ${highlight.id} from ${highlight.file} \u2014 it\u2019s ${blockReasonFor(envApp).toLowerCase()}. Pick another below.` : `Could not use ${highlight.id} from ${highlight.file} \u2014 it may have been removed, or this account may not have access to it.`
|
|
5875
|
-
);
|
|
5876
|
-
}
|
|
5877
5770
|
for (; ; ) {
|
|
5878
5771
|
const choice = await store.requestUserInput({
|
|
5879
|
-
prompt: "
|
|
5772
|
+
prompt: "Select an application",
|
|
5880
5773
|
promptType: "multipleChoice",
|
|
5881
5774
|
options: apps.map(labelFor),
|
|
5882
|
-
secondary: apps.map(
|
|
5883
|
-
disabled: apps.map((app) => !canSelectApplication(app)),
|
|
5884
|
-
...highlightIndex >= 0 ? { defaultSelectedIndex: highlightIndex } : {},
|
|
5775
|
+
secondary: apps.map(secondaryFor),
|
|
5885
5776
|
messages
|
|
5886
5777
|
});
|
|
5887
5778
|
const chosen = apps.find((app) => labelFor(app) === choice);
|
|
5888
|
-
if (!chosen
|
|
5779
|
+
if (!chosen) {
|
|
5889
5780
|
throw new Error("Application picker received an unexpected selection");
|
|
5890
5781
|
}
|
|
5891
5782
|
try {
|
|
@@ -5901,15 +5792,42 @@ async function promptForApplication(highlight) {
|
|
|
5901
5792
|
}
|
|
5902
5793
|
}
|
|
5903
5794
|
}
|
|
5904
|
-
async function
|
|
5905
|
-
const
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5795
|
+
async function confirmEnvApplication(env, current) {
|
|
5796
|
+
const useEnv = `Use ${env.id} (from ${env.file})`;
|
|
5797
|
+
const choice = await useWizard.getState().requestUserInput({
|
|
5798
|
+
prompt: "Select an application",
|
|
5799
|
+
promptType: "multipleChoice",
|
|
5800
|
+
options: [
|
|
5801
|
+
useEnv,
|
|
5802
|
+
current ? `Use ${labelFor(current)} (already selected)` : "Pick a different application"
|
|
5803
|
+
],
|
|
5804
|
+
messages: [
|
|
5805
|
+
`${env.file} already sets ${env.name}=${env.id}.`,
|
|
5806
|
+
"Which Algolia application should the wizard work in?"
|
|
5807
|
+
]
|
|
5808
|
+
});
|
|
5809
|
+
return choice === useEnv;
|
|
5810
|
+
}
|
|
5811
|
+
async function selectEnvApplication(env) {
|
|
5812
|
+
try {
|
|
5813
|
+
return await selectAndReport({ id: env.id, name: "" });
|
|
5814
|
+
} catch (err) {
|
|
5815
|
+
logger.warn(
|
|
5816
|
+
{ app: env.id, err: err.message },
|
|
5817
|
+
"could not select the application named in env; falling back to the picker"
|
|
5818
|
+
);
|
|
5819
|
+
return promptForApplication([
|
|
5820
|
+
`Could not select ${env.id} from ${env.file} \u2014 it may have been removed, or this account may not have access to it.`
|
|
5821
|
+
]);
|
|
5909
5822
|
}
|
|
5823
|
+
}
|
|
5824
|
+
async function ensureApplication() {
|
|
5825
|
+
const current = await currentApplication();
|
|
5910
5826
|
const env = await findEnvApplicationId();
|
|
5911
|
-
if (
|
|
5912
|
-
|
|
5827
|
+
if (env && env.id !== current?.id && await confirmEnvApplication(env, current)) {
|
|
5828
|
+
return selectEnvApplication(env);
|
|
5829
|
+
}
|
|
5830
|
+
return current ?? await promptForApplication();
|
|
5913
5831
|
}
|
|
5914
5832
|
|
|
5915
5833
|
// src/lib/seed.ts
|
|
@@ -6273,15 +6191,14 @@ async function run(workflow) {
|
|
|
6273
6191
|
}
|
|
6274
6192
|
store.setUser(user);
|
|
6275
6193
|
let app;
|
|
6276
|
-
const resumableState = await loadResumableState(workflow);
|
|
6277
6194
|
try {
|
|
6278
|
-
app = await ensureApplication(
|
|
6195
|
+
app = await ensureApplication();
|
|
6279
6196
|
} catch (err) {
|
|
6280
6197
|
store.setError(err instanceof Error ? err.message : String(err));
|
|
6281
6198
|
await instance.waitUntilExit();
|
|
6282
6199
|
process.exit(1);
|
|
6283
6200
|
}
|
|
6284
|
-
runWorkflow(workflow, app.id
|
|
6201
|
+
runWorkflow(workflow, app.id);
|
|
6285
6202
|
}
|
|
6286
6203
|
await requestTerminalSize();
|
|
6287
6204
|
var started = await startup();
|