@algolia/wizard 0.38.0-rc.131.269 → 0.38.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 +193 -263
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -258,14 +258,10 @@ var useWizard = create((set, get) => ({
|
|
|
258
258
|
error: null,
|
|
259
259
|
inputReq: null,
|
|
260
260
|
_resolve: null,
|
|
261
|
-
settingUpAppId: null,
|
|
262
|
-
setSettingUpApp: (appId) => set({ settingUpAppId: appId }),
|
|
263
261
|
// `endAuth` lands on 'preflight', not 'idle': sign-in happens after the
|
|
264
262
|
// welcome screen, so going back would gate the run a second time.
|
|
265
263
|
beginAuth: () => set({ phase: "authenticating", cliOutput: [] }),
|
|
266
|
-
endAuth: () => set(
|
|
267
|
-
(s) => s.phase === "authenticating" ? { phase: "preflight", cliOutput: [] } : {}
|
|
268
|
-
),
|
|
264
|
+
endAuth: () => set((s) => s.phase === "authenticating" ? { phase: "preflight" } : {}),
|
|
269
265
|
confirmStart: () => set(
|
|
270
266
|
(s) => s.phase === "idle" ? { phase: "preflight", homeScreen: "home" } : {}
|
|
271
267
|
),
|
|
@@ -409,8 +405,7 @@ var useWizard = create((set, get) => ({
|
|
|
409
405
|
logs: [],
|
|
410
406
|
error: null,
|
|
411
407
|
inputReq: null,
|
|
412
|
-
_resolve: null
|
|
413
|
-
settingUpAppId: null
|
|
408
|
+
_resolve: null
|
|
414
409
|
});
|
|
415
410
|
}
|
|
416
411
|
}));
|
|
@@ -658,27 +653,25 @@ function SelectRow({
|
|
|
658
653
|
labelWidth,
|
|
659
654
|
highlightBackground = true,
|
|
660
655
|
usePadding = false,
|
|
661
|
-
disabled = false,
|
|
662
656
|
children
|
|
663
657
|
}) {
|
|
664
|
-
const
|
|
665
|
-
const labelColor = disabled ? COLORS.dim : active ? highlightBackground ? COLORS.highlight.fg : COLORS.success : COLORS.primary;
|
|
658
|
+
const labelColor = highlighted ? highlightBackground ? COLORS.highlight.fg : COLORS.success : COLORS.primary;
|
|
666
659
|
return /* @__PURE__ */ jsxs3(
|
|
667
660
|
Box4,
|
|
668
661
|
{
|
|
669
662
|
width,
|
|
670
663
|
paddingX: usePadding ? 1 : 0,
|
|
671
664
|
paddingY: usePadding ? 1 : 0,
|
|
672
|
-
backgroundColor:
|
|
665
|
+
backgroundColor: highlighted && highlightBackground ? COLORS.highlight.bg : void 0,
|
|
673
666
|
children: [
|
|
674
667
|
/* @__PURE__ */ jsx3(Box4, { width: labelWidth, children: /* @__PURE__ */ jsxs3(
|
|
675
668
|
Text4,
|
|
676
669
|
{
|
|
677
670
|
color: labelColor,
|
|
678
|
-
bold:
|
|
671
|
+
bold: highlighted && !highlightBackground,
|
|
679
672
|
wrap: "truncate",
|
|
680
673
|
children: [
|
|
681
|
-
|
|
674
|
+
highlighted ? "\u276F " : " ",
|
|
682
675
|
label
|
|
683
676
|
]
|
|
684
677
|
}
|
|
@@ -877,14 +870,6 @@ var ARROW_WIDTH = 4;
|
|
|
877
870
|
var COLUMN_GAP = 2;
|
|
878
871
|
var BAR_PADDING = 2;
|
|
879
872
|
var ROW_HEIGHT = 3;
|
|
880
|
-
function nextSelectableIndex(start, dir, rowCount, isDisabled) {
|
|
881
|
-
let i = start;
|
|
882
|
-
for (let step = 0; step < rowCount; step++) {
|
|
883
|
-
i = (i + dir + rowCount) % rowCount;
|
|
884
|
-
if (!isDisabled(i)) return i;
|
|
885
|
-
}
|
|
886
|
-
return start;
|
|
887
|
-
}
|
|
888
873
|
function SelectPrompt({
|
|
889
874
|
options,
|
|
890
875
|
onSelect,
|
|
@@ -896,18 +881,15 @@ function SelectPrompt({
|
|
|
896
881
|
multi,
|
|
897
882
|
cancelable,
|
|
898
883
|
secondary,
|
|
899
|
-
disabled,
|
|
900
884
|
defaultSelectedIndex = 0
|
|
901
885
|
}) {
|
|
886
|
+
const [index, setIndex] = useState5(
|
|
887
|
+
() => defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0
|
|
888
|
+
);
|
|
889
|
+
const [checked, setChecked] = useState5(() => /* @__PURE__ */ new Set());
|
|
902
890
|
const hasCancel = Boolean(multi || cancelable);
|
|
903
891
|
const rows = hasCancel ? [...options, "Cancel"] : options;
|
|
904
892
|
const cancelIndex = hasCancel ? options.length : -1;
|
|
905
|
-
const isDisabled = (i) => i !== cancelIndex && Boolean(disabled?.[i]);
|
|
906
|
-
const [index, setIndex] = useState5(() => {
|
|
907
|
-
const start = defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0;
|
|
908
|
-
return isDisabled(start) ? nextSelectableIndex(start, 1, rows.length, isDisabled) : start;
|
|
909
|
-
});
|
|
910
|
-
const [checked, setChecked] = useState5(() => /* @__PURE__ */ new Set());
|
|
911
893
|
const hints = [];
|
|
912
894
|
if (rows.length > 1) hints.push({ key: "[\u2191] [\u2193]", label: "move" });
|
|
913
895
|
if (multi) hints.push({ key: "[space]", label: "select" });
|
|
@@ -947,15 +929,9 @@ function SelectPrompt({
|
|
|
947
929
|
useInput2((input, key) => {
|
|
948
930
|
if (rows.length === 0) return;
|
|
949
931
|
if (key.upArrow || input === "k") {
|
|
950
|
-
setIndex((i) =>
|
|
951
|
-
const next = (i - 1 + rows.length) % rows.length;
|
|
952
|
-
return isDisabled(next) ? i : next;
|
|
953
|
-
});
|
|
932
|
+
setIndex((i) => (i - 1 + rows.length) % rows.length);
|
|
954
933
|
} else if (key.downArrow || input === "j") {
|
|
955
|
-
setIndex((i) =>
|
|
956
|
-
const next = (i + 1) % rows.length;
|
|
957
|
-
return isDisabled(next) ? i : next;
|
|
958
|
-
});
|
|
934
|
+
setIndex((i) => (i + 1) % rows.length);
|
|
959
935
|
} else if (multi && input === " " && index !== cancelIndex) {
|
|
960
936
|
setChecked((prev) => {
|
|
961
937
|
const next = new Set(prev);
|
|
@@ -966,7 +942,6 @@ function SelectPrompt({
|
|
|
966
942
|
} else if (key.return) {
|
|
967
943
|
if (index === cancelIndex) {
|
|
968
944
|
onSelect(CANCEL);
|
|
969
|
-
} else if (isDisabled(index)) {
|
|
970
945
|
} else if (!multi) {
|
|
971
946
|
onSelect(options[index]);
|
|
972
947
|
} else if (checked.size > 0) {
|
|
@@ -991,12 +966,10 @@ function SelectPrompt({
|
|
|
991
966
|
const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
|
|
992
967
|
const sec = isCancel ? void 0 : secondary?.[i];
|
|
993
968
|
const isText = sec?.kind === "text";
|
|
994
|
-
const rowDisabled = isDisabled(i);
|
|
995
969
|
return /* @__PURE__ */ jsxs7(
|
|
996
970
|
SelectRow,
|
|
997
971
|
{
|
|
998
972
|
highlighted,
|
|
999
|
-
disabled: rowDisabled,
|
|
1000
973
|
width: isText ? "100%" : barWidth,
|
|
1001
974
|
labelWidth: isText ? labelWidth : barLabelWidth,
|
|
1002
975
|
label: `${bullet}${option}`,
|
|
@@ -1006,7 +979,7 @@ function SelectPrompt({
|
|
|
1006
979
|
Text8,
|
|
1007
980
|
{
|
|
1008
981
|
wrap: "truncate",
|
|
1009
|
-
color:
|
|
982
|
+
color: highlighted ? COLORS.primary : COLORS.muted,
|
|
1010
983
|
children: sec.value
|
|
1011
984
|
}
|
|
1012
985
|
) }),
|
|
@@ -1068,7 +1041,6 @@ function PromptInput() {
|
|
|
1068
1041
|
table: inputReq.table,
|
|
1069
1042
|
options: inputReq.options,
|
|
1070
1043
|
secondary: inputReq.secondary,
|
|
1071
|
-
disabled: inputReq.disabled,
|
|
1072
1044
|
defaultSelectedIndex: inputReq.defaultSelectedIndex,
|
|
1073
1045
|
cancelable: inputReq.cancelable,
|
|
1074
1046
|
error: inputReq.error,
|
|
@@ -1140,7 +1112,7 @@ function PromptInput() {
|
|
|
1140
1112
|
inputReq.prompt,
|
|
1141
1113
|
" "
|
|
1142
1114
|
] }),
|
|
1143
|
-
/* @__PURE__ */ jsx7(Text9, { color: COLORS.
|
|
1115
|
+
/* @__PURE__ */ jsx7(Text9, { color: COLORS.strong, children: /* @__PURE__ */ jsx7(
|
|
1144
1116
|
TextInput,
|
|
1145
1117
|
{
|
|
1146
1118
|
value: draft,
|
|
@@ -1432,10 +1404,6 @@ function reconcileWorkflowState(state, workflow) {
|
|
|
1432
1404
|
}
|
|
1433
1405
|
return state;
|
|
1434
1406
|
}
|
|
1435
|
-
async function loadResumableState(workflow) {
|
|
1436
|
-
const persisted = await loadWorkflowState(workflow.id);
|
|
1437
|
-
return persisted ? reconcileWorkflowState(persisted, workflow) : null;
|
|
1438
|
-
}
|
|
1439
1407
|
function initWorkflowState(workflow, now) {
|
|
1440
1408
|
return {
|
|
1441
1409
|
workflowId: workflow.id,
|
|
@@ -1538,11 +1506,11 @@ async function runStep(state, index, step, appId) {
|
|
|
1538
1506
|
durationMs: Date.now() - startedAt
|
|
1539
1507
|
});
|
|
1540
1508
|
}
|
|
1541
|
-
async function runWorkflow(workflow, appId
|
|
1509
|
+
async function runWorkflow(workflow, appId) {
|
|
1542
1510
|
const store = useWizard.getState();
|
|
1543
1511
|
try {
|
|
1544
|
-
const
|
|
1545
|
-
const state =
|
|
1512
|
+
const persisted = await loadWorkflowState(workflow.id);
|
|
1513
|
+
const state = (persisted && reconcileWorkflowState(persisted, workflow)) ?? initWorkflowState(workflow, nowIso());
|
|
1546
1514
|
ensureExecutedStepCount(state);
|
|
1547
1515
|
store.startWorkflow(
|
|
1548
1516
|
{
|
|
@@ -1632,89 +1600,14 @@ async function listIndices() {
|
|
|
1632
1600
|
return items.map((i) => ({ name: i.name, entries: i.entries })).sort((a, b) => a.name.localeCompare(b.name));
|
|
1633
1601
|
}
|
|
1634
1602
|
|
|
1635
|
-
// src/lib/algoliaApp.ts
|
|
1636
|
-
import { z as z5 } from "zod";
|
|
1637
|
-
var applicationSchema = z5.object({
|
|
1638
|
-
id: z5.string().min(1),
|
|
1639
|
-
name: z5.string().default(""),
|
|
1640
|
-
plan: z5.string().optional()
|
|
1641
|
-
});
|
|
1642
|
-
var listSchema = z5.array(
|
|
1643
|
-
z5.object({
|
|
1644
|
-
id: z5.string().min(1),
|
|
1645
|
-
name: z5.string().default(""),
|
|
1646
|
-
plan_label: z5.string().optional(),
|
|
1647
|
-
status: z5.string().optional(),
|
|
1648
|
-
acl: z5.array(z5.string()).optional()
|
|
1649
|
-
}).transform(({ id, name, plan_label, status, acl }) => ({
|
|
1650
|
-
id,
|
|
1651
|
-
name,
|
|
1652
|
-
plan: plan_label,
|
|
1653
|
-
status,
|
|
1654
|
-
acl
|
|
1655
|
-
}))
|
|
1656
|
-
);
|
|
1657
|
-
function canSelectApplication(app) {
|
|
1658
|
-
return app.status === "active" && (app.acl ?? []).includes("keys");
|
|
1659
|
-
}
|
|
1660
|
-
async function currentApplication() {
|
|
1661
|
-
let raw;
|
|
1662
|
-
try {
|
|
1663
|
-
raw = await runAlgoliaCli(["application", "current", "-o", "json"]);
|
|
1664
|
-
} catch {
|
|
1665
|
-
return null;
|
|
1666
|
-
}
|
|
1667
|
-
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
1668
|
-
return parsed.success ? parsed.data : null;
|
|
1669
|
-
}
|
|
1670
|
-
async function requireApplication() {
|
|
1671
|
-
const app = await currentApplication();
|
|
1672
|
-
if (!app) {
|
|
1673
|
-
throw new Error(
|
|
1674
|
-
"No Algolia application is selected. Run `npx @algolia/cli@latest application select` and restart the wizard."
|
|
1675
|
-
);
|
|
1676
|
-
}
|
|
1677
|
-
return app;
|
|
1678
|
-
}
|
|
1679
|
-
async function listApplications() {
|
|
1680
|
-
const raw = await runAlgoliaCli(["application", "list", "-o", "json"]);
|
|
1681
|
-
const parsed = listSchema.safeParse(parseJson(raw));
|
|
1682
|
-
if (!parsed.success) {
|
|
1683
|
-
throw new Error("Could not read the list of Algolia applications.");
|
|
1684
|
-
}
|
|
1685
|
-
return parsed.data;
|
|
1686
|
-
}
|
|
1687
|
-
async function selectApplication(id) {
|
|
1688
|
-
const raw = await runAlgoliaCli(
|
|
1689
|
-
["application", "select", "--non-interactive", "--app-id", id],
|
|
1690
|
-
{ onOutput: stderrSink }
|
|
1691
|
-
);
|
|
1692
|
-
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
1693
|
-
if (!parsed.success) {
|
|
1694
|
-
throw new Error(
|
|
1695
|
-
`Selected application ${id}, but the Algolia CLI returned an unreadable result.`
|
|
1696
|
-
);
|
|
1697
|
-
}
|
|
1698
|
-
return parsed.data;
|
|
1699
|
-
}
|
|
1700
|
-
function parseJson(text) {
|
|
1701
|
-
try {
|
|
1702
|
-
return JSON.parse(text);
|
|
1703
|
-
} catch {
|
|
1704
|
-
return void 0;
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
1603
|
// src/actions/selectIndex.ts
|
|
1709
1604
|
var CREATE_NEW_INDEX = "Create a new index\u2026";
|
|
1710
1605
|
var selectIndexStep = async (ctx) => {
|
|
1711
|
-
await requireApplication();
|
|
1712
1606
|
const indices = await listIndices();
|
|
1713
1607
|
const names = indices.map((i) => i.name);
|
|
1714
1608
|
const hasIndices = names.length > 0;
|
|
1715
1609
|
let error;
|
|
1716
|
-
|
|
1717
|
-
while (chosen === void 0) {
|
|
1610
|
+
for (; ; ) {
|
|
1718
1611
|
const selection = hasIndices ? await ctx.requestUserInput({
|
|
1719
1612
|
prompt: "Which index do you want to ingest into?",
|
|
1720
1613
|
promptType: "multipleChoice",
|
|
@@ -1733,9 +1626,9 @@ var selectIndexStep = async (ctx) => {
|
|
|
1733
1626
|
if (typeof selection !== "string") {
|
|
1734
1627
|
throw new Error("selectIndex received an unexpected non-text result");
|
|
1735
1628
|
}
|
|
1736
|
-
let
|
|
1629
|
+
let chosen;
|
|
1737
1630
|
if (!hasIndices) {
|
|
1738
|
-
|
|
1631
|
+
chosen = selection.trim();
|
|
1739
1632
|
} else if (selection === CREATE_NEW_INDEX) {
|
|
1740
1633
|
const name = await ctx.requestUserInput({
|
|
1741
1634
|
prompt: "Name the new index:",
|
|
@@ -1745,18 +1638,17 @@ var selectIndexStep = async (ctx) => {
|
|
|
1745
1638
|
if (typeof name !== "string") {
|
|
1746
1639
|
throw new Error("selectIndex received an unexpected non-text result");
|
|
1747
1640
|
}
|
|
1748
|
-
|
|
1641
|
+
chosen = name.trim();
|
|
1749
1642
|
} else {
|
|
1750
|
-
|
|
1643
|
+
chosen = selection;
|
|
1751
1644
|
}
|
|
1752
|
-
if (!
|
|
1645
|
+
if (!chosen) {
|
|
1753
1646
|
error = "Index name cannot be empty.";
|
|
1754
1647
|
continue;
|
|
1755
1648
|
}
|
|
1756
|
-
chosen
|
|
1649
|
+
ctx.setUserInput("index", chosen);
|
|
1650
|
+
return { selection: chosen };
|
|
1757
1651
|
}
|
|
1758
|
-
ctx.setUserInput("index", chosen);
|
|
1759
|
-
return { selection: chosen };
|
|
1760
1652
|
};
|
|
1761
1653
|
|
|
1762
1654
|
// src/lib/agent.ts
|
|
@@ -1769,7 +1661,7 @@ import "zod";
|
|
|
1769
1661
|
|
|
1770
1662
|
// src/lib/tools/listFiles.ts
|
|
1771
1663
|
import { tool } from "ai";
|
|
1772
|
-
import
|
|
1664
|
+
import z5 from "zod";
|
|
1773
1665
|
import { readdir } from "node:fs/promises";
|
|
1774
1666
|
|
|
1775
1667
|
// src/lib/tools/path.ts
|
|
@@ -1805,8 +1697,8 @@ async function hasSymlinkParent(ctx, target) {
|
|
|
1805
1697
|
function listFilesTool(ctx) {
|
|
1806
1698
|
return tool({
|
|
1807
1699
|
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.',
|
|
1808
|
-
inputSchema:
|
|
1809
|
-
path:
|
|
1700
|
+
inputSchema: z5.object({
|
|
1701
|
+
path: z5.string().optional().describe("Directory to list, relative to cwd (default: cwd)")
|
|
1810
1702
|
}),
|
|
1811
1703
|
execute: async ({ path = "." }) => {
|
|
1812
1704
|
logger.info({ path }, "called listFiles tool");
|
|
@@ -1827,13 +1719,13 @@ function listFilesTool(ctx) {
|
|
|
1827
1719
|
|
|
1828
1720
|
// src/lib/tools/changeDirectory.ts
|
|
1829
1721
|
import { tool as tool2 } from "ai";
|
|
1830
|
-
import
|
|
1722
|
+
import z6 from "zod";
|
|
1831
1723
|
import { stat } from "node:fs/promises";
|
|
1832
1724
|
function changeDirectoryTool(ctx) {
|
|
1833
1725
|
return tool2({
|
|
1834
1726
|
description: "Change the current working directory. Subsequent file operations resolve relative to it. Returns the new working directory.",
|
|
1835
|
-
inputSchema:
|
|
1836
|
-
path:
|
|
1727
|
+
inputSchema: z6.object({
|
|
1728
|
+
path: z6.string().describe("Directory to change into")
|
|
1837
1729
|
}),
|
|
1838
1730
|
execute: async ({ path }) => {
|
|
1839
1731
|
logger.info({ path }, "called changeDirectory tool");
|
|
@@ -1855,13 +1747,13 @@ function changeDirectoryTool(ctx) {
|
|
|
1855
1747
|
|
|
1856
1748
|
// src/lib/tools/reportStatus.ts
|
|
1857
1749
|
import { tool as tool3 } from "ai";
|
|
1858
|
-
import
|
|
1750
|
+
import z7 from "zod";
|
|
1859
1751
|
function reportStatusTool(output) {
|
|
1860
1752
|
return tool3({
|
|
1861
1753
|
description: "Report the status of your execution. Return a reason in case of failure.",
|
|
1862
|
-
inputSchema:
|
|
1863
|
-
status:
|
|
1864
|
-
reason:
|
|
1754
|
+
inputSchema: z7.object({
|
|
1755
|
+
status: z7.enum(["success", "fail"]),
|
|
1756
|
+
reason: z7.string().optional(),
|
|
1865
1757
|
output
|
|
1866
1758
|
}),
|
|
1867
1759
|
execute: async ({ status, reason, output: output2 }) => {
|
|
@@ -1873,7 +1765,7 @@ function reportStatusTool(output) {
|
|
|
1873
1765
|
|
|
1874
1766
|
// src/lib/tools/readFile.ts
|
|
1875
1767
|
import { tool as tool4 } from "ai";
|
|
1876
|
-
import
|
|
1768
|
+
import z8 from "zod";
|
|
1877
1769
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
1878
1770
|
|
|
1879
1771
|
// src/lib/tools/env.ts
|
|
@@ -1901,8 +1793,8 @@ function redactEnvValues(content) {
|
|
|
1901
1793
|
function readFileTool(ctx) {
|
|
1902
1794
|
return tool4({
|
|
1903
1795
|
description: "Read the contents of a file at the given path",
|
|
1904
|
-
inputSchema:
|
|
1905
|
-
filePath:
|
|
1796
|
+
inputSchema: z8.object({
|
|
1797
|
+
filePath: z8.string().describe("Path to the file to read")
|
|
1906
1798
|
}),
|
|
1907
1799
|
execute: async ({ filePath }) => {
|
|
1908
1800
|
if (++ctx.counts.read > ctx.limits.read) {
|
|
@@ -1923,15 +1815,15 @@ function readFileTool(ctx) {
|
|
|
1923
1815
|
|
|
1924
1816
|
// src/lib/tools/writeFile.ts
|
|
1925
1817
|
import { tool as tool5 } from "ai";
|
|
1926
|
-
import
|
|
1818
|
+
import z9 from "zod";
|
|
1927
1819
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
1928
1820
|
import { dirname as dirname3 } from "node:path";
|
|
1929
1821
|
function writeFileTool(ctx) {
|
|
1930
1822
|
return tool5({
|
|
1931
1823
|
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.",
|
|
1932
|
-
inputSchema:
|
|
1933
|
-
filePath:
|
|
1934
|
-
content:
|
|
1824
|
+
inputSchema: z9.object({
|
|
1825
|
+
filePath: z9.string().describe("Path to the file to write"),
|
|
1826
|
+
content: z9.string().describe("Content to write to the file")
|
|
1935
1827
|
}),
|
|
1936
1828
|
execute: async ({ filePath, content }) => {
|
|
1937
1829
|
logger.info({ filePath }, "called writeFile tool");
|
|
@@ -1961,6 +1853,68 @@ import z13 from "zod";
|
|
|
1961
1853
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
|
|
1962
1854
|
import { dirname as dirname4, relative as relative3 } from "node:path";
|
|
1963
1855
|
|
|
1856
|
+
// src/lib/algoliaApp.ts
|
|
1857
|
+
import { z as z10 } from "zod";
|
|
1858
|
+
var applicationSchema = z10.object({
|
|
1859
|
+
id: z10.string().min(1),
|
|
1860
|
+
name: z10.string().default(""),
|
|
1861
|
+
plan: z10.string().optional()
|
|
1862
|
+
});
|
|
1863
|
+
var listSchema = z10.array(
|
|
1864
|
+
z10.object({
|
|
1865
|
+
id: z10.string().min(1),
|
|
1866
|
+
name: z10.string().default(""),
|
|
1867
|
+
plan_label: z10.string().optional()
|
|
1868
|
+
}).transform(({ id, name, plan_label }) => ({ id, name, plan: plan_label }))
|
|
1869
|
+
);
|
|
1870
|
+
async function currentApplication() {
|
|
1871
|
+
let raw;
|
|
1872
|
+
try {
|
|
1873
|
+
raw = await runAlgoliaCli(["application", "current", "-o", "json"]);
|
|
1874
|
+
} catch {
|
|
1875
|
+
return null;
|
|
1876
|
+
}
|
|
1877
|
+
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
1878
|
+
return parsed.success ? parsed.data : null;
|
|
1879
|
+
}
|
|
1880
|
+
async function requireApplication() {
|
|
1881
|
+
const app = await currentApplication();
|
|
1882
|
+
if (!app) {
|
|
1883
|
+
throw new Error(
|
|
1884
|
+
"No Algolia application is selected. Run `npx @algolia/cli@latest application select` and restart the wizard."
|
|
1885
|
+
);
|
|
1886
|
+
}
|
|
1887
|
+
return app;
|
|
1888
|
+
}
|
|
1889
|
+
async function listApplications() {
|
|
1890
|
+
const raw = await runAlgoliaCli(["application", "list", "-o", "json"]);
|
|
1891
|
+
const parsed = listSchema.safeParse(parseJson(raw));
|
|
1892
|
+
if (!parsed.success) {
|
|
1893
|
+
throw new Error("Could not read the list of Algolia applications.");
|
|
1894
|
+
}
|
|
1895
|
+
return parsed.data;
|
|
1896
|
+
}
|
|
1897
|
+
async function selectApplication(id) {
|
|
1898
|
+
const raw = await runAlgoliaCli(
|
|
1899
|
+
["application", "select", "--non-interactive", "--app-id", id],
|
|
1900
|
+
{ onOutput: stderrSink }
|
|
1901
|
+
);
|
|
1902
|
+
const parsed = applicationSchema.safeParse(parseJson(raw));
|
|
1903
|
+
if (!parsed.success) {
|
|
1904
|
+
throw new Error(
|
|
1905
|
+
`Selected application ${id}, but the Algolia CLI returned an unreadable result.`
|
|
1906
|
+
);
|
|
1907
|
+
}
|
|
1908
|
+
return parsed.data;
|
|
1909
|
+
}
|
|
1910
|
+
function parseJson(text) {
|
|
1911
|
+
try {
|
|
1912
|
+
return JSON.parse(text);
|
|
1913
|
+
} catch {
|
|
1914
|
+
return void 0;
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1964
1918
|
// src/lib/algoliaApiKey.ts
|
|
1965
1919
|
import { z as z12 } from "zod";
|
|
1966
1920
|
|
|
@@ -1968,13 +1922,13 @@ import { z as z12 } from "zod";
|
|
|
1968
1922
|
import { deletePassword, getPassword, setPassword } from "cross-keychain";
|
|
1969
1923
|
import { z as z11 } from "zod";
|
|
1970
1924
|
var SERVICE = "algolia-wizard";
|
|
1971
|
-
var
|
|
1925
|
+
var ACCOUNT = "api-keys";
|
|
1972
1926
|
var storedKeysSchema = z11.record(z11.string(), z11.string());
|
|
1973
1927
|
function entryId(kind, index, appId) {
|
|
1974
1928
|
return `${kind}:${appId}:${index}`;
|
|
1975
1929
|
}
|
|
1976
|
-
async function loadKeys(
|
|
1977
|
-
const raw = await getPassword(SERVICE,
|
|
1930
|
+
async function loadKeys() {
|
|
1931
|
+
const raw = await getPassword(SERVICE, ACCOUNT);
|
|
1978
1932
|
if (!raw) return {};
|
|
1979
1933
|
let payload;
|
|
1980
1934
|
try {
|
|
@@ -1996,47 +1950,47 @@ function serialized(op) {
|
|
|
1996
1950
|
});
|
|
1997
1951
|
return next;
|
|
1998
1952
|
}
|
|
1999
|
-
async function readStoredKey(kind,
|
|
1953
|
+
async function readStoredKey(kind, index, appId) {
|
|
2000
1954
|
try {
|
|
2001
|
-
return (await loadKeys(
|
|
1955
|
+
return (await loadKeys())[entryId(kind, index, appId)] ?? null;
|
|
2002
1956
|
} catch (err) {
|
|
2003
1957
|
logger.warn(
|
|
2004
|
-
{ err: err.message, kind, index, appId
|
|
1958
|
+
{ err: err.message, kind, index, appId },
|
|
2005
1959
|
"could not read the API key from the keychain"
|
|
2006
1960
|
);
|
|
2007
1961
|
return null;
|
|
2008
1962
|
}
|
|
2009
1963
|
}
|
|
2010
|
-
function storeKey(kind,
|
|
1964
|
+
function storeKey(kind, index, appId, value) {
|
|
2011
1965
|
return serialized(async () => {
|
|
2012
1966
|
const id = entryId(kind, index, appId);
|
|
2013
1967
|
try {
|
|
2014
|
-
const keys = await loadKeys(
|
|
1968
|
+
const keys = await loadKeys();
|
|
2015
1969
|
await setPassword(
|
|
2016
1970
|
SERVICE,
|
|
2017
|
-
|
|
1971
|
+
ACCOUNT,
|
|
2018
1972
|
JSON.stringify({ ...keys, [id]: value })
|
|
2019
1973
|
);
|
|
2020
|
-
if ((await loadKeys(
|
|
1974
|
+
if ((await loadKeys())[id] !== value) {
|
|
2021
1975
|
throw new Error("the keychain did not store the value");
|
|
2022
1976
|
}
|
|
2023
1977
|
} catch (err) {
|
|
2024
1978
|
logger.warn(
|
|
2025
|
-
{ err: err.message, kind, index, appId
|
|
1979
|
+
{ err: err.message, kind, index, appId },
|
|
2026
1980
|
"could not store the API key in the keychain; the next run will create another"
|
|
2027
1981
|
);
|
|
2028
1982
|
}
|
|
2029
1983
|
});
|
|
2030
1984
|
}
|
|
2031
|
-
function deleteStoredKeys(
|
|
1985
|
+
function deleteStoredKeys() {
|
|
2032
1986
|
return serialized(async () => {
|
|
2033
1987
|
try {
|
|
2034
|
-
await deletePassword(SERVICE,
|
|
1988
|
+
await deletePassword(SERVICE, ACCOUNT);
|
|
2035
1989
|
} catch (err) {
|
|
2036
1990
|
const message = err.message;
|
|
2037
1991
|
if (/not found/i.test(message)) return;
|
|
2038
1992
|
logger.warn(
|
|
2039
|
-
{ err: message
|
|
1993
|
+
{ err: message },
|
|
2040
1994
|
"could not delete the API keys from the keychain"
|
|
2041
1995
|
);
|
|
2042
1996
|
}
|
|
@@ -2044,16 +1998,6 @@ function deleteStoredKeys(userId) {
|
|
|
2044
1998
|
}
|
|
2045
1999
|
|
|
2046
2000
|
// src/lib/algoliaApiKey.ts
|
|
2047
|
-
function requireUserId() {
|
|
2048
|
-
const userId = useWizard.getState().user?.userId;
|
|
2049
|
-
if (!userId) {
|
|
2050
|
-
throw new Error("No Algolia user is signed in; cannot scope the API key.");
|
|
2051
|
-
}
|
|
2052
|
-
return userId;
|
|
2053
|
-
}
|
|
2054
|
-
async function currentUserId() {
|
|
2055
|
-
return useWizard.getState().user?.userId ?? (await getUser())?.userId ?? null;
|
|
2056
|
-
}
|
|
2057
2001
|
var WRITE_ACLS = [
|
|
2058
2002
|
"addObject",
|
|
2059
2003
|
"deleteObject",
|
|
@@ -2100,30 +2044,23 @@ async function keyExists(key) {
|
|
|
2100
2044
|
var resolved = /* @__PURE__ */ new Map();
|
|
2101
2045
|
async function forgetResolvedKeys() {
|
|
2102
2046
|
resolved.clear();
|
|
2103
|
-
|
|
2104
|
-
if (userId) await deleteStoredKeys(userId);
|
|
2047
|
+
await deleteStoredKeys();
|
|
2105
2048
|
}
|
|
2106
2049
|
function resolveKey(kind, index, appId, acls, description) {
|
|
2107
|
-
const
|
|
2108
|
-
const cacheKey = `${userId}:${kind}:${appId}:${index}`;
|
|
2050
|
+
const cacheKey = `${kind}:${appId}:${index}`;
|
|
2109
2051
|
const cached = resolved.get(cacheKey);
|
|
2110
2052
|
if (cached) return cached;
|
|
2111
|
-
const pending = provisionKey(
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
description
|
|
2118
|
-
).catch((err) => {
|
|
2119
|
-
resolved.delete(cacheKey);
|
|
2120
|
-
throw err;
|
|
2121
|
-
});
|
|
2053
|
+
const pending = provisionKey(kind, index, appId, acls, description).catch(
|
|
2054
|
+
(err) => {
|
|
2055
|
+
resolved.delete(cacheKey);
|
|
2056
|
+
throw err;
|
|
2057
|
+
}
|
|
2058
|
+
);
|
|
2122
2059
|
resolved.set(cacheKey, pending);
|
|
2123
2060
|
return pending;
|
|
2124
2061
|
}
|
|
2125
|
-
async function provisionKey(kind,
|
|
2126
|
-
const stored = await readStoredKey(kind,
|
|
2062
|
+
async function provisionKey(kind, index, appId, acls, description) {
|
|
2063
|
+
const stored = await readStoredKey(kind, index, appId);
|
|
2127
2064
|
if (stored) {
|
|
2128
2065
|
if (await keyExists(stored)) {
|
|
2129
2066
|
logger.info({ kind, index, appId }, "reusing the stored API key");
|
|
@@ -2135,7 +2072,7 @@ async function provisionKey(kind, userId, index, appId, acls, description) {
|
|
|
2135
2072
|
);
|
|
2136
2073
|
}
|
|
2137
2074
|
const key = await createKey(index, acls, description);
|
|
2138
|
-
await storeKey(kind,
|
|
2075
|
+
await storeKey(kind, index, appId, key);
|
|
2139
2076
|
return { key, source: "created" };
|
|
2140
2077
|
}
|
|
2141
2078
|
function resolveWriteKey(index, appId) {
|
|
@@ -3330,7 +3267,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3330
3267
|
// package.json
|
|
3331
3268
|
var package_default = {
|
|
3332
3269
|
name: "@algolia/wizard",
|
|
3333
|
-
version: "0.38.0
|
|
3270
|
+
version: "0.38.0",
|
|
3334
3271
|
description: "Magically implement Algolia functionality in your codebase",
|
|
3335
3272
|
type: "module",
|
|
3336
3273
|
engines: {
|
|
@@ -4217,10 +4154,6 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
4217
4154
|
if (useCases.includes("ingestion")) {
|
|
4218
4155
|
ingestAppId = appId ?? (await requireApplication()).id;
|
|
4219
4156
|
}
|
|
4220
|
-
let ingestWriteKey;
|
|
4221
|
-
if (useCases.includes("ingestion") && ingestAppId) {
|
|
4222
|
-
ingestWriteKey = (await resolveWriteKey(targetIndex, ingestAppId)).key;
|
|
4223
|
-
}
|
|
4224
4157
|
let uploadFilePath;
|
|
4225
4158
|
let uploadWarning;
|
|
4226
4159
|
if (ingestionSource === "fileUpload") {
|
|
@@ -4283,9 +4216,9 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
4283
4216
|
let ingestDurationMs;
|
|
4284
4217
|
let ingestOutcomeMessage;
|
|
4285
4218
|
const ingestKeyAppId = ingestAppId;
|
|
4286
|
-
const ingestionTools = ingestKeyAppId
|
|
4219
|
+
const ingestionTools = ingestKeyAppId ? makeToolContext(repoRoot, async () => ({
|
|
4287
4220
|
[APP_ID_VAR]: ingestKeyAppId,
|
|
4288
|
-
[API_KEY_VAR]:
|
|
4221
|
+
[API_KEY_VAR]: (await resolveWriteKey(targetIndex, ingestKeyAppId)).key,
|
|
4289
4222
|
[INDEX_NAME_VAR]: targetIndex
|
|
4290
4223
|
})) : void 0;
|
|
4291
4224
|
const searchTools = makeToolContext(repoRoot);
|
|
@@ -5440,8 +5373,7 @@ function App() {
|
|
|
5440
5373
|
steps,
|
|
5441
5374
|
inputReq,
|
|
5442
5375
|
user,
|
|
5443
|
-
workflow
|
|
5444
|
-
settingUpAppId
|
|
5376
|
+
workflow
|
|
5445
5377
|
} = useWizard();
|
|
5446
5378
|
const { exit } = useApp();
|
|
5447
5379
|
const { columns, rows } = useWindowSize7();
|
|
@@ -5456,7 +5388,7 @@ function App() {
|
|
|
5456
5388
|
const isCommandApprovalPrompt = isAwaitingUserInput && inputReq?.promptType === "commandApproval";
|
|
5457
5389
|
const promptPending = isAwaitingUserInput && !isCommandApprovalPrompt;
|
|
5458
5390
|
const holdForTip = stepHasTips && promptPending && tipState === "revealing";
|
|
5459
|
-
const showTips = stepHasTips && (phase === "running"
|
|
5391
|
+
const showTips = stepHasTips && (phase === "running" || isCommandApprovalPrompt || holdForTip);
|
|
5460
5392
|
const showNoticesInMain = !stepHasTips;
|
|
5461
5393
|
const showNotices = !isAwaitingUserInput || holdForTip;
|
|
5462
5394
|
useInput6(
|
|
@@ -5541,12 +5473,6 @@ function App() {
|
|
|
5541
5473
|
] }),
|
|
5542
5474
|
/* @__PURE__ */ jsx17(Text19, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
|
|
5543
5475
|
] }),
|
|
5544
|
-
settingUpAppId && /* @__PURE__ */ jsx17(Box19, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs17(Text19, { color: COLORS.strong, bold: true, children: [
|
|
5545
|
-
/* @__PURE__ */ jsx17(Spinner2, { type: "dots" }),
|
|
5546
|
-
" Setting up Wizard using app",
|
|
5547
|
-
" ",
|
|
5548
|
-
settingUpAppId
|
|
5549
|
-
] }) }),
|
|
5550
5476
|
/* @__PURE__ */ jsx17(CliOutput, {}),
|
|
5551
5477
|
showTips && currentStep && /* @__PURE__ */ jsx17(
|
|
5552
5478
|
Tips,
|
|
@@ -5616,72 +5542,50 @@ function readValue(raw) {
|
|
|
5616
5542
|
}
|
|
5617
5543
|
|
|
5618
5544
|
// src/lib/algoliaAppPicker.ts
|
|
5619
|
-
function
|
|
5620
|
-
return app.status !== "active" ? "Paused" : "Missing permissions";
|
|
5621
|
-
}
|
|
5622
|
-
function secondaryFor(app, highlightId) {
|
|
5623
|
-
if (!canSelectApplication(app)) {
|
|
5624
|
-
return { kind: "text", value: blockReasonFor(app) };
|
|
5625
|
-
}
|
|
5626
|
-
if (app.id === highlightId) {
|
|
5627
|
-
return { kind: "badge", value: "[DETECTED]" };
|
|
5628
|
-
}
|
|
5545
|
+
function secondaryFor(app) {
|
|
5629
5546
|
return app.plan ? { kind: "badge", value: app.plan } : void 0;
|
|
5630
5547
|
}
|
|
5631
5548
|
function labelFor(app) {
|
|
5632
5549
|
return app.name.trim() ? `${app.name} \u2014 ${app.id}` : app.id;
|
|
5633
5550
|
}
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
const store = useWizard.getState();
|
|
5641
|
-
store.setSettingUpApp(app.id);
|
|
5642
|
-
try {
|
|
5643
|
-
return await selectApplication(app.id);
|
|
5644
|
-
} finally {
|
|
5645
|
-
store.setSettingUpApp(null);
|
|
5646
|
-
}
|
|
5551
|
+
function selectAndReport(app) {
|
|
5552
|
+
useWizard.getState().pushCliOutput(
|
|
5553
|
+
"stdout",
|
|
5554
|
+
`Selecting ${labelFor(app)} \u2014 provisioning its API key\u2026`
|
|
5555
|
+
);
|
|
5556
|
+
return selectApplication(app.id);
|
|
5647
5557
|
}
|
|
5648
|
-
async function promptForApplication(
|
|
5558
|
+
async function promptForApplication(leadIn = []) {
|
|
5649
5559
|
const store = useWizard.getState();
|
|
5650
|
-
const
|
|
5651
|
-
if (
|
|
5560
|
+
const apps = await listApplications();
|
|
5561
|
+
if (apps.length === 0) {
|
|
5652
5562
|
throw new Error(
|
|
5653
5563
|
"This Algolia account has no applications. Create one in the Algolia dashboard, or with `npx @algolia/cli@latest application create`, then restart the wizard."
|
|
5654
5564
|
);
|
|
5655
5565
|
}
|
|
5656
|
-
if (
|
|
5657
|
-
|
|
5658
|
-
|
|
5566
|
+
if (apps.length === 1) {
|
|
5567
|
+
const only = apps[0];
|
|
5568
|
+
logger.info(
|
|
5569
|
+
{ app: only.id },
|
|
5570
|
+
"single application on the account; selecting it"
|
|
5659
5571
|
);
|
|
5572
|
+
for (const line of leadIn) store.pushCliOutput("stdout", line);
|
|
5573
|
+
return selectAndReport(only);
|
|
5660
5574
|
}
|
|
5661
|
-
const
|
|
5662
|
-
...
|
|
5663
|
-
|
|
5575
|
+
const messages = [
|
|
5576
|
+
...leadIn,
|
|
5577
|
+
"Which Algolia application should the wizard work in?"
|
|
5664
5578
|
];
|
|
5665
|
-
const envApp = highlight ? unordered.find((app) => app.id === highlight.id) : void 0;
|
|
5666
|
-
const highlightIndex = envApp && canSelectApplication(envApp) ? apps.indexOf(envApp) : -1;
|
|
5667
|
-
const messages = [];
|
|
5668
|
-
if (highlight && highlightIndex < 0) {
|
|
5669
|
-
messages.push(
|
|
5670
|
-
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.`
|
|
5671
|
-
);
|
|
5672
|
-
}
|
|
5673
5579
|
for (; ; ) {
|
|
5674
5580
|
const choice = await store.requestUserInput({
|
|
5675
|
-
prompt: "
|
|
5581
|
+
prompt: "Select an application",
|
|
5676
5582
|
promptType: "multipleChoice",
|
|
5677
5583
|
options: apps.map(labelFor),
|
|
5678
|
-
secondary: apps.map(
|
|
5679
|
-
disabled: apps.map((app) => !canSelectApplication(app)),
|
|
5680
|
-
...highlightIndex >= 0 ? { defaultSelectedIndex: highlightIndex } : {},
|
|
5584
|
+
secondary: apps.map(secondaryFor),
|
|
5681
5585
|
messages
|
|
5682
5586
|
});
|
|
5683
5587
|
const chosen = apps.find((app) => labelFor(app) === choice);
|
|
5684
|
-
if (!chosen
|
|
5588
|
+
if (!chosen) {
|
|
5685
5589
|
throw new Error("Application picker received an unexpected selection");
|
|
5686
5590
|
}
|
|
5687
5591
|
try {
|
|
@@ -5697,15 +5601,42 @@ async function promptForApplication(highlight) {
|
|
|
5697
5601
|
}
|
|
5698
5602
|
}
|
|
5699
5603
|
}
|
|
5700
|
-
async function
|
|
5701
|
-
const
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5604
|
+
async function confirmEnvApplication(env, current) {
|
|
5605
|
+
const useEnv = `Use ${env.id} (from ${env.file})`;
|
|
5606
|
+
const choice = await useWizard.getState().requestUserInput({
|
|
5607
|
+
prompt: "Select an application",
|
|
5608
|
+
promptType: "multipleChoice",
|
|
5609
|
+
options: [
|
|
5610
|
+
useEnv,
|
|
5611
|
+
current ? `Use ${labelFor(current)} (already selected)` : "Pick a different application"
|
|
5612
|
+
],
|
|
5613
|
+
messages: [
|
|
5614
|
+
`${env.file} already sets ${env.name}=${env.id}.`,
|
|
5615
|
+
"Which Algolia application should the wizard work in?"
|
|
5616
|
+
]
|
|
5617
|
+
});
|
|
5618
|
+
return choice === useEnv;
|
|
5619
|
+
}
|
|
5620
|
+
async function selectEnvApplication(env) {
|
|
5621
|
+
try {
|
|
5622
|
+
return await selectAndReport({ id: env.id, name: "" });
|
|
5623
|
+
} catch (err) {
|
|
5624
|
+
logger.warn(
|
|
5625
|
+
{ app: env.id, err: err.message },
|
|
5626
|
+
"could not select the application named in env; falling back to the picker"
|
|
5627
|
+
);
|
|
5628
|
+
return promptForApplication([
|
|
5629
|
+
`Could not select ${env.id} from ${env.file} \u2014 it may have been removed, or this account may not have access to it.`
|
|
5630
|
+
]);
|
|
5705
5631
|
}
|
|
5632
|
+
}
|
|
5633
|
+
async function ensureApplication() {
|
|
5634
|
+
const current = await currentApplication();
|
|
5706
5635
|
const env = await findEnvApplicationId();
|
|
5707
|
-
if (
|
|
5708
|
-
|
|
5636
|
+
if (env && env.id !== current?.id && await confirmEnvApplication(env, current)) {
|
|
5637
|
+
return selectEnvApplication(env);
|
|
5638
|
+
}
|
|
5639
|
+
return current ?? await promptForApplication();
|
|
5709
5640
|
}
|
|
5710
5641
|
|
|
5711
5642
|
// src/lib/seed.ts
|
|
@@ -6069,15 +6000,14 @@ async function run(workflow) {
|
|
|
6069
6000
|
}
|
|
6070
6001
|
store.setUser(user);
|
|
6071
6002
|
let app;
|
|
6072
|
-
const resumableState = await loadResumableState(workflow);
|
|
6073
6003
|
try {
|
|
6074
|
-
app = await ensureApplication(
|
|
6004
|
+
app = await ensureApplication();
|
|
6075
6005
|
} catch (err) {
|
|
6076
6006
|
store.setError(err instanceof Error ? err.message : String(err));
|
|
6077
6007
|
await instance.waitUntilExit();
|
|
6078
6008
|
process.exit(1);
|
|
6079
6009
|
}
|
|
6080
|
-
runWorkflow(workflow, app.id
|
|
6010
|
+
runWorkflow(workflow, app.id);
|
|
6081
6011
|
}
|
|
6082
6012
|
await requestTerminalSize();
|
|
6083
6013
|
var started = await startup();
|