@algolia/wizard 0.38.0-rc.131.269 → 0.39.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.
Files changed (2) hide show
  1. package/dist/main.js +495 -459
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { render } from "ink";
5
5
 
6
6
  // src/ui/App.tsx
7
- import { Box as Box19, Text as Text19, useApp, useInput as useInput6, useWindowSize as useWindowSize7 } from "ink";
7
+ import { Box as Box20, Text as Text20, useApp, useInput as useInput7, useWindowSize as useWindowSize7 } from "ink";
8
8
  import Spinner2 from "ink-spinner";
9
9
 
10
10
  // src/core/store.ts
@@ -251,6 +251,7 @@ var useWizard = create((set, get) => ({
251
251
  _noticeQueue: [],
252
252
  _noticeTimer: null,
253
253
  cliOutput: [],
254
+ review: null,
254
255
  targetIndex: null,
255
256
  writtenFiles: [],
256
257
  approvedCommands: /* @__PURE__ */ new Set(),
@@ -258,14 +259,10 @@ var useWizard = create((set, get) => ({
258
259
  error: null,
259
260
  inputReq: null,
260
261
  _resolve: null,
261
- settingUpAppId: null,
262
- setSettingUpApp: (appId) => set({ settingUpAppId: appId }),
263
262
  // `endAuth` lands on 'preflight', not 'idle': sign-in happens after the
264
263
  // welcome screen, so going back would gate the run a second time.
265
264
  beginAuth: () => set({ phase: "authenticating", cliOutput: [] }),
266
- endAuth: () => set(
267
- (s) => s.phase === "authenticating" ? { phase: "preflight", cliOutput: [] } : {}
268
- ),
265
+ endAuth: () => set((s) => s.phase === "authenticating" ? { phase: "preflight" } : {}),
269
266
  confirmStart: () => set(
270
267
  (s) => s.phase === "idle" ? { phase: "preflight", homeScreen: "home" } : {}
271
268
  ),
@@ -298,7 +295,8 @@ var useWizard = create((set, get) => ({
298
295
  currentStepIndex: index,
299
296
  output: "",
300
297
  notices: [],
301
- cliOutput: []
298
+ cliOutput: [],
299
+ review: null
302
300
  });
303
301
  },
304
302
  setUser: (user) => set({ user }),
@@ -350,6 +348,7 @@ var useWizard = create((set, get) => ({
350
348
  )
351
349
  })),
352
350
  clearCliOutput: () => set({ cliOutput: [] }),
351
+ setReview: (review2) => set({ review: review2 }),
353
352
  setTargetIndex: (index) => set({ targetIndex: index }),
354
353
  recordWrittenFile: (path) => set((s) => ({ writtenFiles: [...s.writtenFiles, path] })),
355
354
  clearWrittenFiles: () => set({ writtenFiles: [] }),
@@ -403,14 +402,14 @@ var useWizard = create((set, get) => ({
403
402
  output: "",
404
403
  notices: [],
405
404
  cliOutput: [],
405
+ review: null,
406
406
  targetIndex: null,
407
407
  writtenFiles: [],
408
408
  approvedCommands: /* @__PURE__ */ new Set(),
409
409
  logs: [],
410
410
  error: null,
411
411
  inputReq: null,
412
- _resolve: null,
413
- settingUpAppId: null
412
+ _resolve: null
414
413
  });
415
414
  }
416
415
  }));
@@ -658,27 +657,25 @@ function SelectRow({
658
657
  labelWidth,
659
658
  highlightBackground = true,
660
659
  usePadding = false,
661
- disabled = false,
662
660
  children
663
661
  }) {
664
- const active = highlighted && !disabled;
665
- 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;
666
663
  return /* @__PURE__ */ jsxs3(
667
664
  Box4,
668
665
  {
669
666
  width,
670
667
  paddingX: usePadding ? 1 : 0,
671
668
  paddingY: usePadding ? 1 : 0,
672
- backgroundColor: active && highlightBackground ? COLORS.highlight.bg : void 0,
669
+ backgroundColor: highlighted && highlightBackground ? COLORS.highlight.bg : void 0,
673
670
  children: [
674
671
  /* @__PURE__ */ jsx3(Box4, { width: labelWidth, children: /* @__PURE__ */ jsxs3(
675
672
  Text4,
676
673
  {
677
674
  color: labelColor,
678
- bold: active && !highlightBackground,
675
+ bold: highlighted && !highlightBackground,
679
676
  wrap: "truncate",
680
677
  children: [
681
- active ? "\u276F " : " ",
678
+ highlighted ? "\u276F " : " ",
682
679
  label
683
680
  ]
684
681
  }
@@ -844,6 +841,7 @@ function useScrollWindow({
844
841
  const visibleCount = Math.min(capacity, Math.max(itemCount - offset, 0));
845
842
  return {
846
843
  viewportRef,
844
+ measured: size !== null,
847
845
  width: size?.width ?? columns,
848
846
  offset,
849
847
  capacity,
@@ -877,14 +875,6 @@ var ARROW_WIDTH = 4;
877
875
  var COLUMN_GAP = 2;
878
876
  var BAR_PADDING = 2;
879
877
  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
878
  function SelectPrompt({
889
879
  options,
890
880
  onSelect,
@@ -896,18 +886,15 @@ function SelectPrompt({
896
886
  multi,
897
887
  cancelable,
898
888
  secondary,
899
- disabled,
900
889
  defaultSelectedIndex = 0
901
890
  }) {
891
+ const [index, setIndex] = useState5(
892
+ () => defaultSelectedIndex > 0 && defaultSelectedIndex < options.length ? defaultSelectedIndex : 0
893
+ );
894
+ const [checked, setChecked] = useState5(() => /* @__PURE__ */ new Set());
902
895
  const hasCancel = Boolean(multi || cancelable);
903
896
  const rows = hasCancel ? [...options, "Cancel"] : options;
904
897
  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
898
  const hints = [];
912
899
  if (rows.length > 1) hints.push({ key: "[\u2191] [\u2193]", label: "move" });
913
900
  if (multi) hints.push({ key: "[space]", label: "select" });
@@ -947,15 +934,9 @@ function SelectPrompt({
947
934
  useInput2((input, key) => {
948
935
  if (rows.length === 0) return;
949
936
  if (key.upArrow || input === "k") {
950
- setIndex((i) => {
951
- const next = (i - 1 + rows.length) % rows.length;
952
- return isDisabled(next) ? i : next;
953
- });
937
+ setIndex((i) => (i - 1 + rows.length) % rows.length);
954
938
  } else if (key.downArrow || input === "j") {
955
- setIndex((i) => {
956
- const next = (i + 1) % rows.length;
957
- return isDisabled(next) ? i : next;
958
- });
939
+ setIndex((i) => (i + 1) % rows.length);
959
940
  } else if (multi && input === " " && index !== cancelIndex) {
960
941
  setChecked((prev) => {
961
942
  const next = new Set(prev);
@@ -966,7 +947,6 @@ function SelectPrompt({
966
947
  } else if (key.return) {
967
948
  if (index === cancelIndex) {
968
949
  onSelect(CANCEL);
969
- } else if (isDisabled(index)) {
970
950
  } else if (!multi) {
971
951
  onSelect(options[index]);
972
952
  } else if (checked.size > 0) {
@@ -991,12 +971,10 @@ function SelectPrompt({
991
971
  const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
992
972
  const sec = isCancel ? void 0 : secondary?.[i];
993
973
  const isText = sec?.kind === "text";
994
- const rowDisabled = isDisabled(i);
995
974
  return /* @__PURE__ */ jsxs7(
996
975
  SelectRow,
997
976
  {
998
977
  highlighted,
999
- disabled: rowDisabled,
1000
978
  width: isText ? "100%" : barWidth,
1001
979
  labelWidth: isText ? labelWidth : barLabelWidth,
1002
980
  label: `${bullet}${option}`,
@@ -1006,7 +984,7 @@ function SelectPrompt({
1006
984
  Text8,
1007
985
  {
1008
986
  wrap: "truncate",
1009
- color: rowDisabled ? COLORS.dim : highlighted ? COLORS.primary : COLORS.muted,
987
+ color: highlighted ? COLORS.primary : COLORS.muted,
1010
988
  children: sec.value
1011
989
  }
1012
990
  ) }),
@@ -1068,7 +1046,6 @@ function PromptInput() {
1068
1046
  table: inputReq.table,
1069
1047
  options: inputReq.options,
1070
1048
  secondary: inputReq.secondary,
1071
- disabled: inputReq.disabled,
1072
1049
  defaultSelectedIndex: inputReq.defaultSelectedIndex,
1073
1050
  cancelable: inputReq.cancelable,
1074
1051
  error: inputReq.error,
@@ -1140,7 +1117,7 @@ function PromptInput() {
1140
1117
  inputReq.prompt,
1141
1118
  " "
1142
1119
  ] }),
1143
- /* @__PURE__ */ jsx7(Text9, { color: COLORS.primary, children: /* @__PURE__ */ jsx7(
1120
+ /* @__PURE__ */ jsx7(Text9, { color: COLORS.strong, children: /* @__PURE__ */ jsx7(
1144
1121
  TextInput,
1145
1122
  {
1146
1123
  value: draft,
@@ -1155,6 +1132,121 @@ function PromptInput() {
1155
1132
  ] });
1156
1133
  }
1157
1134
 
1135
+ // src/ui/Review.tsx
1136
+ import { Box as Box10, Text as Text10, useInput as useInput3 } from "ink";
1137
+ import { useLayoutEffect as useLayoutEffect3, useState as useState7 } from "react";
1138
+ import { jsx as jsx8, jsxs as jsxs9 } from "react/jsx-runtime";
1139
+ var INGEST_SCRIPT = ".algolia-wizard/ingest.sh";
1140
+ function wrapText(text, width) {
1141
+ if (width <= 0) return [text];
1142
+ const lines = [];
1143
+ let line = "";
1144
+ for (const word of text.split(/\s+/).filter(Boolean)) {
1145
+ const candidate = line ? `${line} ${word}` : word;
1146
+ if (candidate.length <= width) {
1147
+ line = candidate;
1148
+ continue;
1149
+ }
1150
+ if (line) lines.push(line);
1151
+ let rest = word;
1152
+ while (rest.length > width) {
1153
+ lines.push(rest.slice(0, width));
1154
+ rest = rest.slice(width);
1155
+ }
1156
+ line = rest;
1157
+ }
1158
+ if (line) lines.push(line);
1159
+ return lines.length > 0 ? lines : [""];
1160
+ }
1161
+ function heading(text) {
1162
+ return { prefix: "", text, color: COLORS.strong, bold: true };
1163
+ }
1164
+ var BLANK = { prefix: "", text: " ", color: COLORS.dim };
1165
+ function itemRows(items, width, prefixFor, colorFor) {
1166
+ return items.flatMap((item, i) => {
1167
+ const { prefix, color: prefixColor } = prefixFor(i);
1168
+ const { color, bold } = colorFor(item);
1169
+ return wrapText(item, width - prefix.length).map((line, j) => ({
1170
+ prefix: j === 0 ? prefix : " ".repeat(prefix.length),
1171
+ prefixColor,
1172
+ text: line,
1173
+ color,
1174
+ bold
1175
+ }));
1176
+ });
1177
+ }
1178
+ function buildRows(review2, width) {
1179
+ const { summaryPoints, nextSteps, reviewPrompt } = review2;
1180
+ const numberWidth = String(nextSteps.length).length + 2;
1181
+ const rows = [];
1182
+ if (summaryPoints.length > 0) {
1183
+ rows.push(heading("What we did"));
1184
+ rows.push(
1185
+ ...itemRows(
1186
+ summaryPoints,
1187
+ width,
1188
+ () => ({ prefix: `${MARKER.done} `, color: COLORS.status.done }),
1189
+ () => ({ color: COLORS.primary, bold: false })
1190
+ )
1191
+ );
1192
+ }
1193
+ if (nextSteps.length > 0) {
1194
+ if (rows.length > 0) rows.push(BLANK);
1195
+ rows.push(heading("What to do next"));
1196
+ rows.push(
1197
+ ...itemRows(
1198
+ nextSteps,
1199
+ width,
1200
+ (i) => ({
1201
+ prefix: `${i + 1}.`.padEnd(numberWidth),
1202
+ color: COLORS.secondary
1203
+ }),
1204
+ (step) => step.includes(INGEST_SCRIPT) ? { color: COLORS.brand, bold: true } : { color: COLORS.primary, bold: false }
1205
+ )
1206
+ );
1207
+ }
1208
+ if (reviewPrompt) {
1209
+ if (rows.length > 0) rows.push(BLANK);
1210
+ rows.push(
1211
+ ...wrapText(reviewPrompt, width).map((line) => ({
1212
+ prefix: "",
1213
+ text: line,
1214
+ color: COLORS.brand
1215
+ }))
1216
+ );
1217
+ }
1218
+ return rows;
1219
+ }
1220
+ function ReviewPanel({ review: review2 }) {
1221
+ const [width, setWidth] = useState7(0);
1222
+ const rows = width > 0 ? buildRows(review2, width) : [];
1223
+ const scroll = useScrollWindow({ itemCount: rows.length });
1224
+ useLayoutEffect3(() => {
1225
+ if (scroll.measured) setWidth(scroll.width);
1226
+ }, [scroll.measured, scroll.width]);
1227
+ const scrollable = scroll.maxOffset > 0;
1228
+ useInput3(
1229
+ (_input, key) => {
1230
+ if (key.upArrow) scroll.scrollBy(-1);
1231
+ else if (key.downArrow) scroll.scrollBy(1);
1232
+ },
1233
+ { isActive: scrollable }
1234
+ );
1235
+ const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
1236
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", flexGrow: 1, children: [
1237
+ /* @__PURE__ */ jsx8(ScrollView, { scroll, children: visible.map((row, i) => /* @__PURE__ */ jsxs9(Text10, { wrap: "truncate", children: [
1238
+ row.prefix && /* @__PURE__ */ jsx8(Text10, { color: row.prefixColor ?? row.color, bold: row.bold, children: row.prefix }),
1239
+ /* @__PURE__ */ jsx8(Text10, { color: row.color, bold: row.bold, children: row.text })
1240
+ ] }, `review-row-${i}`)) }),
1241
+ scrollable && /* @__PURE__ */ jsx8(Text10, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
1242
+ ] });
1243
+ }
1244
+ function Review() {
1245
+ const review2 = useWizard((s) => s.review);
1246
+ if (!review2) return null;
1247
+ return /* @__PURE__ */ jsx8(ReviewPanel, { review: review2 });
1248
+ }
1249
+
1158
1250
  // src/workflows/default.ts
1159
1251
  import { z as z29 } from "zod";
1160
1252
 
@@ -1432,10 +1524,6 @@ function reconcileWorkflowState(state, workflow) {
1432
1524
  }
1433
1525
  return state;
1434
1526
  }
1435
- async function loadResumableState(workflow) {
1436
- const persisted = await loadWorkflowState(workflow.id);
1437
- return persisted ? reconcileWorkflowState(persisted, workflow) : null;
1438
- }
1439
1527
  function initWorkflowState(workflow, now) {
1440
1528
  return {
1441
1529
  workflowId: workflow.id,
@@ -1538,11 +1626,11 @@ async function runStep(state, index, step, appId) {
1538
1626
  durationMs: Date.now() - startedAt
1539
1627
  });
1540
1628
  }
1541
- async function runWorkflow(workflow, appId, resumableState) {
1629
+ async function runWorkflow(workflow, appId) {
1542
1630
  const store = useWizard.getState();
1543
1631
  try {
1544
- const resolved2 = resumableState !== void 0 ? resumableState : await loadResumableState(workflow);
1545
- const state = resolved2 ?? initWorkflowState(workflow, nowIso());
1632
+ const persisted = await loadWorkflowState(workflow.id);
1633
+ const state = (persisted && reconcileWorkflowState(persisted, workflow)) ?? initWorkflowState(workflow, nowIso());
1546
1634
  ensureExecutedStepCount(state);
1547
1635
  store.startWorkflow(
1548
1636
  {
@@ -1632,89 +1720,14 @@ async function listIndices() {
1632
1720
  return items.map((i) => ({ name: i.name, entries: i.entries })).sort((a, b) => a.name.localeCompare(b.name));
1633
1721
  }
1634
1722
 
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
1723
  // src/actions/selectIndex.ts
1709
1724
  var CREATE_NEW_INDEX = "Create a new index\u2026";
1710
1725
  var selectIndexStep = async (ctx) => {
1711
- await requireApplication();
1712
1726
  const indices = await listIndices();
1713
1727
  const names = indices.map((i) => i.name);
1714
1728
  const hasIndices = names.length > 0;
1715
1729
  let error;
1716
- let chosen;
1717
- while (chosen === void 0) {
1730
+ for (; ; ) {
1718
1731
  const selection = hasIndices ? await ctx.requestUserInput({
1719
1732
  prompt: "Which index do you want to ingest into?",
1720
1733
  promptType: "multipleChoice",
@@ -1733,9 +1746,9 @@ var selectIndexStep = async (ctx) => {
1733
1746
  if (typeof selection !== "string") {
1734
1747
  throw new Error("selectIndex received an unexpected non-text result");
1735
1748
  }
1736
- let candidate;
1749
+ let chosen;
1737
1750
  if (!hasIndices) {
1738
- candidate = selection.trim();
1751
+ chosen = selection.trim();
1739
1752
  } else if (selection === CREATE_NEW_INDEX) {
1740
1753
  const name = await ctx.requestUserInput({
1741
1754
  prompt: "Name the new index:",
@@ -1745,18 +1758,17 @@ var selectIndexStep = async (ctx) => {
1745
1758
  if (typeof name !== "string") {
1746
1759
  throw new Error("selectIndex received an unexpected non-text result");
1747
1760
  }
1748
- candidate = name.trim();
1761
+ chosen = name.trim();
1749
1762
  } else {
1750
- candidate = selection;
1763
+ chosen = selection;
1751
1764
  }
1752
- if (!candidate) {
1765
+ if (!chosen) {
1753
1766
  error = "Index name cannot be empty.";
1754
1767
  continue;
1755
1768
  }
1756
- chosen = candidate;
1769
+ ctx.setUserInput("index", chosen);
1770
+ return { selection: chosen };
1757
1771
  }
1758
- ctx.setUserInput("index", chosen);
1759
- return { selection: chosen };
1760
1772
  };
1761
1773
 
1762
1774
  // src/lib/agent.ts
@@ -1769,7 +1781,7 @@ import "zod";
1769
1781
 
1770
1782
  // src/lib/tools/listFiles.ts
1771
1783
  import { tool } from "ai";
1772
- import z6 from "zod";
1784
+ import z5 from "zod";
1773
1785
  import { readdir } from "node:fs/promises";
1774
1786
 
1775
1787
  // src/lib/tools/path.ts
@@ -1805,8 +1817,8 @@ async function hasSymlinkParent(ctx, target) {
1805
1817
  function listFilesTool(ctx) {
1806
1818
  return tool({
1807
1819
  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: z6.object({
1809
- path: z6.string().optional().describe("Directory to list, relative to cwd (default: cwd)")
1820
+ inputSchema: z5.object({
1821
+ path: z5.string().optional().describe("Directory to list, relative to cwd (default: cwd)")
1810
1822
  }),
1811
1823
  execute: async ({ path = "." }) => {
1812
1824
  logger.info({ path }, "called listFiles tool");
@@ -1827,13 +1839,13 @@ function listFilesTool(ctx) {
1827
1839
 
1828
1840
  // src/lib/tools/changeDirectory.ts
1829
1841
  import { tool as tool2 } from "ai";
1830
- import z7 from "zod";
1842
+ import z6 from "zod";
1831
1843
  import { stat } from "node:fs/promises";
1832
1844
  function changeDirectoryTool(ctx) {
1833
1845
  return tool2({
1834
1846
  description: "Change the current working directory. Subsequent file operations resolve relative to it. Returns the new working directory.",
1835
- inputSchema: z7.object({
1836
- path: z7.string().describe("Directory to change into")
1847
+ inputSchema: z6.object({
1848
+ path: z6.string().describe("Directory to change into")
1837
1849
  }),
1838
1850
  execute: async ({ path }) => {
1839
1851
  logger.info({ path }, "called changeDirectory tool");
@@ -1855,13 +1867,13 @@ function changeDirectoryTool(ctx) {
1855
1867
 
1856
1868
  // src/lib/tools/reportStatus.ts
1857
1869
  import { tool as tool3 } from "ai";
1858
- import z8 from "zod";
1870
+ import z7 from "zod";
1859
1871
  function reportStatusTool(output) {
1860
1872
  return tool3({
1861
1873
  description: "Report the status of your execution. Return a reason in case of failure.",
1862
- inputSchema: z8.object({
1863
- status: z8.enum(["success", "fail"]),
1864
- reason: z8.string().optional(),
1874
+ inputSchema: z7.object({
1875
+ status: z7.enum(["success", "fail"]),
1876
+ reason: z7.string().optional(),
1865
1877
  output
1866
1878
  }),
1867
1879
  execute: async ({ status, reason, output: output2 }) => {
@@ -1873,7 +1885,7 @@ function reportStatusTool(output) {
1873
1885
 
1874
1886
  // src/lib/tools/readFile.ts
1875
1887
  import { tool as tool4 } from "ai";
1876
- import z9 from "zod";
1888
+ import z8 from "zod";
1877
1889
  import { readFile as readFile3 } from "node:fs/promises";
1878
1890
 
1879
1891
  // src/lib/tools/env.ts
@@ -1901,8 +1913,8 @@ function redactEnvValues(content) {
1901
1913
  function readFileTool(ctx) {
1902
1914
  return tool4({
1903
1915
  description: "Read the contents of a file at the given path",
1904
- inputSchema: z9.object({
1905
- filePath: z9.string().describe("Path to the file to read")
1916
+ inputSchema: z8.object({
1917
+ filePath: z8.string().describe("Path to the file to read")
1906
1918
  }),
1907
1919
  execute: async ({ filePath }) => {
1908
1920
  if (++ctx.counts.read > ctx.limits.read) {
@@ -1923,15 +1935,15 @@ function readFileTool(ctx) {
1923
1935
 
1924
1936
  // src/lib/tools/writeFile.ts
1925
1937
  import { tool as tool5 } from "ai";
1926
- import z10 from "zod";
1938
+ import z9 from "zod";
1927
1939
  import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
1928
1940
  import { dirname as dirname3 } from "node:path";
1929
1941
  function writeFileTool(ctx) {
1930
1942
  return tool5({
1931
1943
  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: z10.object({
1933
- filePath: z10.string().describe("Path to the file to write"),
1934
- content: z10.string().describe("Content to write to the file")
1944
+ inputSchema: z9.object({
1945
+ filePath: z9.string().describe("Path to the file to write"),
1946
+ content: z9.string().describe("Content to write to the file")
1935
1947
  }),
1936
1948
  execute: async ({ filePath, content }) => {
1937
1949
  logger.info({ filePath }, "called writeFile tool");
@@ -1961,6 +1973,68 @@ import z13 from "zod";
1961
1973
  import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
1962
1974
  import { dirname as dirname4, relative as relative3 } from "node:path";
1963
1975
 
1976
+ // src/lib/algoliaApp.ts
1977
+ import { z as z10 } from "zod";
1978
+ var applicationSchema = z10.object({
1979
+ id: z10.string().min(1),
1980
+ name: z10.string().default(""),
1981
+ plan: z10.string().optional()
1982
+ });
1983
+ var listSchema = z10.array(
1984
+ z10.object({
1985
+ id: z10.string().min(1),
1986
+ name: z10.string().default(""),
1987
+ plan_label: z10.string().optional()
1988
+ }).transform(({ id, name, plan_label }) => ({ id, name, plan: plan_label }))
1989
+ );
1990
+ async function currentApplication() {
1991
+ let raw;
1992
+ try {
1993
+ raw = await runAlgoliaCli(["application", "current", "-o", "json"]);
1994
+ } catch {
1995
+ return null;
1996
+ }
1997
+ const parsed = applicationSchema.safeParse(parseJson(raw));
1998
+ return parsed.success ? parsed.data : null;
1999
+ }
2000
+ async function requireApplication() {
2001
+ const app = await currentApplication();
2002
+ if (!app) {
2003
+ throw new Error(
2004
+ "No Algolia application is selected. Run `npx @algolia/cli@latest application select` and restart the wizard."
2005
+ );
2006
+ }
2007
+ return app;
2008
+ }
2009
+ async function listApplications() {
2010
+ const raw = await runAlgoliaCli(["application", "list", "-o", "json"]);
2011
+ const parsed = listSchema.safeParse(parseJson(raw));
2012
+ if (!parsed.success) {
2013
+ throw new Error("Could not read the list of Algolia applications.");
2014
+ }
2015
+ return parsed.data;
2016
+ }
2017
+ async function selectApplication(id) {
2018
+ const raw = await runAlgoliaCli(
2019
+ ["application", "select", "--non-interactive", "--app-id", id],
2020
+ { onOutput: stderrSink }
2021
+ );
2022
+ const parsed = applicationSchema.safeParse(parseJson(raw));
2023
+ if (!parsed.success) {
2024
+ throw new Error(
2025
+ `Selected application ${id}, but the Algolia CLI returned an unreadable result.`
2026
+ );
2027
+ }
2028
+ return parsed.data;
2029
+ }
2030
+ function parseJson(text) {
2031
+ try {
2032
+ return JSON.parse(text);
2033
+ } catch {
2034
+ return void 0;
2035
+ }
2036
+ }
2037
+
1964
2038
  // src/lib/algoliaApiKey.ts
1965
2039
  import { z as z12 } from "zod";
1966
2040
 
@@ -1968,13 +2042,13 @@ import { z as z12 } from "zod";
1968
2042
  import { deletePassword, getPassword, setPassword } from "cross-keychain";
1969
2043
  import { z as z11 } from "zod";
1970
2044
  var SERVICE = "algolia-wizard";
1971
- var account = (userId) => `api-keys:${userId}`;
2045
+ var ACCOUNT = "api-keys";
1972
2046
  var storedKeysSchema = z11.record(z11.string(), z11.string());
1973
2047
  function entryId(kind, index, appId) {
1974
2048
  return `${kind}:${appId}:${index}`;
1975
2049
  }
1976
- async function loadKeys(userId) {
1977
- const raw = await getPassword(SERVICE, account(userId));
2050
+ async function loadKeys() {
2051
+ const raw = await getPassword(SERVICE, ACCOUNT);
1978
2052
  if (!raw) return {};
1979
2053
  let payload;
1980
2054
  try {
@@ -1996,47 +2070,47 @@ function serialized(op) {
1996
2070
  });
1997
2071
  return next;
1998
2072
  }
1999
- async function readStoredKey(kind, userId, index, appId) {
2073
+ async function readStoredKey(kind, index, appId) {
2000
2074
  try {
2001
- return (await loadKeys(userId))[entryId(kind, index, appId)] ?? null;
2075
+ return (await loadKeys())[entryId(kind, index, appId)] ?? null;
2002
2076
  } catch (err) {
2003
2077
  logger.warn(
2004
- { err: err.message, kind, index, appId, userId },
2078
+ { err: err.message, kind, index, appId },
2005
2079
  "could not read the API key from the keychain"
2006
2080
  );
2007
2081
  return null;
2008
2082
  }
2009
2083
  }
2010
- function storeKey(kind, userId, index, appId, value) {
2084
+ function storeKey(kind, index, appId, value) {
2011
2085
  return serialized(async () => {
2012
2086
  const id = entryId(kind, index, appId);
2013
2087
  try {
2014
- const keys = await loadKeys(userId);
2088
+ const keys = await loadKeys();
2015
2089
  await setPassword(
2016
2090
  SERVICE,
2017
- account(userId),
2091
+ ACCOUNT,
2018
2092
  JSON.stringify({ ...keys, [id]: value })
2019
2093
  );
2020
- if ((await loadKeys(userId))[id] !== value) {
2094
+ if ((await loadKeys())[id] !== value) {
2021
2095
  throw new Error("the keychain did not store the value");
2022
2096
  }
2023
2097
  } catch (err) {
2024
2098
  logger.warn(
2025
- { err: err.message, kind, index, appId, userId },
2099
+ { err: err.message, kind, index, appId },
2026
2100
  "could not store the API key in the keychain; the next run will create another"
2027
2101
  );
2028
2102
  }
2029
2103
  });
2030
2104
  }
2031
- function deleteStoredKeys(userId) {
2105
+ function deleteStoredKeys() {
2032
2106
  return serialized(async () => {
2033
2107
  try {
2034
- await deletePassword(SERVICE, account(userId));
2108
+ await deletePassword(SERVICE, ACCOUNT);
2035
2109
  } catch (err) {
2036
2110
  const message = err.message;
2037
2111
  if (/not found/i.test(message)) return;
2038
2112
  logger.warn(
2039
- { err: message, userId },
2113
+ { err: message },
2040
2114
  "could not delete the API keys from the keychain"
2041
2115
  );
2042
2116
  }
@@ -2044,16 +2118,6 @@ function deleteStoredKeys(userId) {
2044
2118
  }
2045
2119
 
2046
2120
  // 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
2121
  var WRITE_ACLS = [
2058
2122
  "addObject",
2059
2123
  "deleteObject",
@@ -2100,30 +2164,23 @@ async function keyExists(key) {
2100
2164
  var resolved = /* @__PURE__ */ new Map();
2101
2165
  async function forgetResolvedKeys() {
2102
2166
  resolved.clear();
2103
- const userId = await currentUserId();
2104
- if (userId) await deleteStoredKeys(userId);
2167
+ await deleteStoredKeys();
2105
2168
  }
2106
2169
  function resolveKey(kind, index, appId, acls, description) {
2107
- const userId = requireUserId();
2108
- const cacheKey = `${userId}:${kind}:${appId}:${index}`;
2170
+ const cacheKey = `${kind}:${appId}:${index}`;
2109
2171
  const cached = resolved.get(cacheKey);
2110
2172
  if (cached) return cached;
2111
- const pending = provisionKey(
2112
- kind,
2113
- userId,
2114
- index,
2115
- appId,
2116
- acls,
2117
- description
2118
- ).catch((err) => {
2119
- resolved.delete(cacheKey);
2120
- throw err;
2121
- });
2173
+ const pending = provisionKey(kind, index, appId, acls, description).catch(
2174
+ (err) => {
2175
+ resolved.delete(cacheKey);
2176
+ throw err;
2177
+ }
2178
+ );
2122
2179
  resolved.set(cacheKey, pending);
2123
2180
  return pending;
2124
2181
  }
2125
- async function provisionKey(kind, userId, index, appId, acls, description) {
2126
- const stored = await readStoredKey(kind, userId, index, appId);
2182
+ async function provisionKey(kind, index, appId, acls, description) {
2183
+ const stored = await readStoredKey(kind, index, appId);
2127
2184
  if (stored) {
2128
2185
  if (await keyExists(stored)) {
2129
2186
  logger.info({ kind, index, appId }, "reusing the stored API key");
@@ -2135,7 +2192,7 @@ async function provisionKey(kind, userId, index, appId, acls, description) {
2135
2192
  );
2136
2193
  }
2137
2194
  const key = await createKey(index, acls, description);
2138
- await storeKey(kind, userId, index, appId, key);
2195
+ await storeKey(kind, index, appId, key);
2139
2196
  return { key, source: "created" };
2140
2197
  }
2141
2198
  function resolveWriteKey(index, appId) {
@@ -3330,7 +3387,7 @@ async function runAnalysis(mode, extraInstructions = []) {
3330
3387
  // package.json
3331
3388
  var package_default = {
3332
3389
  name: "@algolia/wizard",
3333
- version: "0.38.0-rc.131.269",
3390
+ version: "0.39.0",
3334
3391
  description: "Magically implement Algolia functionality in your codebase",
3335
3392
  type: "module",
3336
3393
  engines: {
@@ -3696,23 +3753,6 @@ Output:
3696
3753
  ${JSON.stringify(s.output, null, 2)}`
3697
3754
  ).join("\n\n");
3698
3755
  }
3699
- function formatReviewSummary(result) {
3700
- const nextStepLines = result.nextSteps.map((step) => {
3701
- const isIngestCommand = step.includes(".algolia-wizard/ingest.sh");
3702
- return {
3703
- text: `\u2192 ${step}`,
3704
- color: isIngestCommand ? COLORS.brand : void 0,
3705
- bold: isIngestCommand
3706
- };
3707
- });
3708
- return [
3709
- // Plain lines, same as nextSteps' un-highlighted entries — the summary is
3710
- // an overview, not a call to action, so it gets no arrow/color/bold.
3711
- ...result.summaryPoints,
3712
- { text: result.reviewPrompt, color: COLORS.brand },
3713
- ...nextStepLines
3714
- ];
3715
- }
3716
3756
  var reviewStep = async (ctx, options) => {
3717
3757
  const result = await runAgent({
3718
3758
  instructions: [
@@ -3731,7 +3771,8 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
3731
3771
  outputSchema: reviewSchema,
3732
3772
  modelSize: "small"
3733
3773
  });
3734
- ctx.notify({ messages: formatReviewSummary(result) });
3774
+ ctx.clearNotices();
3775
+ useWizard.getState().setReview(result);
3735
3776
  return result;
3736
3777
  };
3737
3778
 
@@ -4217,10 +4258,6 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
4217
4258
  if (useCases.includes("ingestion")) {
4218
4259
  ingestAppId = appId ?? (await requireApplication()).id;
4219
4260
  }
4220
- let ingestWriteKey;
4221
- if (useCases.includes("ingestion") && ingestAppId) {
4222
- ingestWriteKey = (await resolveWriteKey(targetIndex, ingestAppId)).key;
4223
- }
4224
4261
  let uploadFilePath;
4225
4262
  let uploadWarning;
4226
4263
  if (ingestionSource === "fileUpload") {
@@ -4283,9 +4320,9 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
4283
4320
  let ingestDurationMs;
4284
4321
  let ingestOutcomeMessage;
4285
4322
  const ingestKeyAppId = ingestAppId;
4286
- const ingestionTools = ingestKeyAppId && ingestWriteKey ? makeToolContext(repoRoot, async () => ({
4323
+ const ingestionTools = ingestKeyAppId ? makeToolContext(repoRoot, async () => ({
4287
4324
  [APP_ID_VAR]: ingestKeyAppId,
4288
- [API_KEY_VAR]: ingestWriteKey,
4325
+ [API_KEY_VAR]: (await resolveWriteKey(targetIndex, ingestKeyAppId)).key,
4289
4326
  [INDEX_NAME_VAR]: targetIndex
4290
4327
  })) : void 0;
4291
4328
  const searchTools = makeToolContext(repoRoot);
@@ -4582,8 +4619,8 @@ function getWorkflow(id) {
4582
4619
  // src/ui/Welcome.tsx
4583
4620
  import { dirname as dirname8, join as join11 } from "node:path";
4584
4621
  import { fileURLToPath as fileURLToPath2 } from "node:url";
4585
- import { useState as useState7 } from "react";
4586
- import { Box as Box10, Spacer, Text as Text10, useInput as useInput3, useWindowSize as useWindowSize5 } from "ink";
4622
+ import { useState as useState8 } from "react";
4623
+ import { Box as Box11, Spacer, Text as Text11, useInput as useInput4, useWindowSize as useWindowSize5 } from "ink";
4587
4624
 
4588
4625
  // src/ui/copy/welcome.ts
4589
4626
  var sidebarItems = [
@@ -4611,7 +4648,7 @@ var sidebarItems = [
4611
4648
 
4612
4649
  // src/ui/Welcome.tsx
4613
4650
  import Image, { TerminalInfoContext, defaultTerminalInfo } from "ink-picture";
4614
- import { jsx as jsx8, jsxs as jsxs9 } from "react/jsx-runtime";
4651
+ import { jsx as jsx9, jsxs as jsxs10 } from "react/jsx-runtime";
4615
4652
  var IMAGE_PATH = join11(dirname8(fileURLToPath2(import.meta.url)), "algolia.png");
4616
4653
  var TERMINAL_INFO = {
4617
4654
  ...defaultTerminalInfo,
@@ -4622,14 +4659,14 @@ function SidebarItem({
4622
4659
  title,
4623
4660
  description
4624
4661
  }) {
4625
- return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", children: [
4626
- /* @__PURE__ */ jsxs9(Box10, { gap: 1, children: [
4627
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.success, children: "\u2192" }),
4628
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.strong, bold: true, children: title })
4662
+ return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", children: [
4663
+ /* @__PURE__ */ jsxs10(Box11, { gap: 1, children: [
4664
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.success, children: "\u2192" }),
4665
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.strong, bold: true, children: title })
4629
4666
  ] }),
4630
- /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 2, children: [
4631
- /* @__PURE__ */ jsx8(Spacer, {}),
4632
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: description })
4667
+ /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 2, children: [
4668
+ /* @__PURE__ */ jsx9(Spacer, {}),
4669
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: description })
4633
4670
  ] })
4634
4671
  ] });
4635
4672
  }
@@ -4641,8 +4678,8 @@ function Welcome() {
4641
4678
  { label: "start wizard", run: confirmStart },
4642
4679
  { label: "learn more", run: openLearnMore }
4643
4680
  ];
4644
- const [index, setIndex] = useState7(0);
4645
- useInput3((input, key) => {
4681
+ const [index, setIndex] = useState8(0);
4682
+ useInput4((input, key) => {
4646
4683
  if (key.upArrow || input === "k") {
4647
4684
  setIndex((i) => (i - 1 + actions.length) % actions.length);
4648
4685
  } else if (key.downArrow || input === "j") {
@@ -4665,16 +4702,16 @@ function Welcome() {
4665
4702
  if (rows < 30) {
4666
4703
  layout = scales["small"];
4667
4704
  }
4668
- return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
4669
- /* @__PURE__ */ jsx8(
4670
- Box10,
4705
+ return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
4706
+ /* @__PURE__ */ jsx9(
4707
+ Box11,
4671
4708
  {
4672
4709
  paddingY: layout.main.padding.y,
4673
4710
  paddingX: layout.main.padding.x,
4674
4711
  flexDirection: "column",
4675
4712
  justifyContent: "center",
4676
- children: /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", gap: 2, children: [
4677
- /* @__PURE__ */ jsx8(TerminalInfoContext.Provider, { value: TERMINAL_INFO, children: /* @__PURE__ */ jsx8(
4713
+ children: /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", gap: 2, children: [
4714
+ /* @__PURE__ */ jsx9(TerminalInfoContext.Provider, { value: TERMINAL_INFO, children: /* @__PURE__ */ jsx9(
4678
4715
  Image,
4679
4716
  {
4680
4717
  src: IMAGE_PATH,
@@ -4685,8 +4722,8 @@ function Welcome() {
4685
4722
  protocol: "halfBlock"
4686
4723
  }
4687
4724
  ) }),
4688
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
4689
- /* @__PURE__ */ jsx8(Box10, { flexDirection: "column", children: actions.map((action, i) => /* @__PURE__ */ jsx8(
4725
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
4726
+ /* @__PURE__ */ jsx9(Box11, { flexDirection: "column", children: actions.map((action, i) => /* @__PURE__ */ jsx9(
4690
4727
  SelectRow,
4691
4728
  {
4692
4729
  highlighted: i === index,
@@ -4695,21 +4732,21 @@ function Welcome() {
4695
4732
  },
4696
4733
  action.label
4697
4734
  )) }),
4698
- /* @__PURE__ */ jsxs9(Box10, { gap: 2, children: [
4699
- /* @__PURE__ */ jsxs9(Text10, { children: [
4700
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.primary, children: "[\u2191] [\u2193]" }),
4701
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.dim, children: " move" })
4735
+ /* @__PURE__ */ jsxs10(Box11, { gap: 2, children: [
4736
+ /* @__PURE__ */ jsxs10(Text11, { children: [
4737
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.primary, children: "[\u2191] [\u2193]" }),
4738
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.dim, children: " move" })
4702
4739
  ] }),
4703
- /* @__PURE__ */ jsxs9(Text10, { children: [
4704
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.primary, children: "[enter]" }),
4705
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.dim, children: " confirm" })
4740
+ /* @__PURE__ */ jsxs10(Text11, { children: [
4741
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.primary, children: "[enter]" }),
4742
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.dim, children: " confirm" })
4706
4743
  ] })
4707
4744
  ] })
4708
4745
  ] })
4709
4746
  }
4710
4747
  ),
4711
- /* @__PURE__ */ jsxs9(
4712
- Box10,
4748
+ /* @__PURE__ */ jsxs10(
4749
+ Box11,
4713
4750
  {
4714
4751
  backgroundColor: COLORS.bg.sidebar,
4715
4752
  width: 40,
@@ -4719,8 +4756,8 @@ function Welcome() {
4719
4756
  flexDirection: "column",
4720
4757
  justifyContent: "center",
4721
4758
  children: [
4722
- /* @__PURE__ */ jsx8(Text10, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
4723
- sidebarItems.map((i, idx) => /* @__PURE__ */ jsx8(SidebarItem, { title: i.title, description: i.description }, idx))
4759
+ /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
4760
+ sidebarItems.map((i, idx) => /* @__PURE__ */ jsx9(SidebarItem, { title: i.title, description: i.description }, idx))
4724
4761
  ]
4725
4762
  }
4726
4763
  )
@@ -4729,7 +4766,7 @@ function Welcome() {
4729
4766
 
4730
4767
  // src/ui/LearnMore.tsx
4731
4768
  import { Fragment } from "react";
4732
- import { Box as Box11, Text as Text11, useInput as useInput4, useWindowSize as useWindowSize6 } from "ink";
4769
+ import { Box as Box12, Text as Text12, useInput as useInput5, useWindowSize as useWindowSize6 } from "ink";
4733
4770
 
4734
4771
  // src/ui/copy/learn-more.ts
4735
4772
  var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
@@ -4771,7 +4808,7 @@ var policyLinks = [
4771
4808
  ];
4772
4809
 
4773
4810
  // src/ui/LearnMore.tsx
4774
- import { jsx as jsx9, jsxs as jsxs10 } from "react/jsx-runtime";
4811
+ import { jsx as jsx10, jsxs as jsxs11 } from "react/jsx-runtime";
4775
4812
  var TAG_COLORS = {
4776
4813
  READ: COLORS.success,
4777
4814
  WRITE: COLORS.badge,
@@ -4788,12 +4825,12 @@ function NeverLine({
4788
4825
  }) {
4789
4826
  const used = segments.reduce((n, s) => n + s.text.length, 0);
4790
4827
  const rightPad = Math.max(0, width - 2 - NEVER_BOX_PAD_X - used);
4791
- return /* @__PURE__ */ jsxs10(Text11, { color: COLORS.primary, children: [
4792
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.danger, children: "\u2502" }),
4828
+ return /* @__PURE__ */ jsxs11(Text12, { color: COLORS.primary, children: [
4829
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.danger, children: "\u2502" }),
4793
4830
  " ".repeat(NEVER_BOX_PAD_X),
4794
- segments.map((s, i) => /* @__PURE__ */ jsx9(Text11, { color: s.color, bold: s.bold, children: s.text }, i)),
4831
+ segments.map((s, i) => /* @__PURE__ */ jsx10(Text12, { color: s.color, bold: s.bold, children: s.text }, i)),
4795
4832
  " ".repeat(rightPad),
4796
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.danger, children: "\u2502" })
4833
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.danger, children: "\u2502" })
4797
4834
  ] });
4798
4835
  }
4799
4836
  function LearnMore() {
@@ -4801,12 +4838,12 @@ function LearnMore() {
4801
4838
  const backToHome = useWizard((s) => s.backToHome);
4802
4839
  const { columns } = useWindowSize6();
4803
4840
  const dividerWidth = Math.max(0, columns - PADDING_X * 2);
4804
- useInput4((_input, key) => {
4841
+ useInput5((_input, key) => {
4805
4842
  if (key.escape) backToHome();
4806
4843
  else if (key.return) confirmStart();
4807
4844
  });
4808
- return /* @__PURE__ */ jsxs10(
4809
- Box11,
4845
+ return /* @__PURE__ */ jsxs11(
4846
+ Box12,
4810
4847
  {
4811
4848
  flexDirection: "column",
4812
4849
  paddingX: PADDING_X,
@@ -4814,31 +4851,31 @@ function LearnMore() {
4814
4851
  width: "100%",
4815
4852
  gap: 1,
4816
4853
  children: [
4817
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
4818
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: accessIntro }),
4819
- /* @__PURE__ */ jsx9(Box11, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", marginTop: 1, children: [
4820
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
4821
- /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, marginTop: 1, children: [
4822
- /* @__PURE__ */ jsx9(Box11, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text11, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
4823
- /* @__PURE__ */ jsx9(Box11, { flexDirection: "column", children: /* @__PURE__ */ jsxs10(Text11, { color: COLORS.primary, children: [
4824
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.strong, bold: true, children: item.title }),
4825
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
4854
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
4855
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: accessIntro }),
4856
+ /* @__PURE__ */ jsx10(Box12, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", marginTop: 1, children: [
4857
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
4858
+ /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: 1, marginTop: 1, children: [
4859
+ /* @__PURE__ */ jsx10(Box12, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx10(Text12, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
4860
+ /* @__PURE__ */ jsx10(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsxs11(Text12, { color: COLORS.primary, children: [
4861
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.strong, bold: true, children: item.title }),
4862
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
4826
4863
  ] }) })
4827
4864
  ] })
4828
4865
  ] }, item.tag)) }),
4829
- /* @__PURE__ */ jsxs10(Box11, { marginTop: 1, flexDirection: "column", children: [
4830
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
4831
- /* @__PURE__ */ jsx9(NeverLine, { width: dividerWidth }),
4832
- /* @__PURE__ */ jsx9(
4866
+ /* @__PURE__ */ jsxs11(Box12, { marginTop: 1, flexDirection: "column", children: [
4867
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
4868
+ /* @__PURE__ */ jsx10(NeverLine, { width: dividerWidth }),
4869
+ /* @__PURE__ */ jsx10(
4833
4870
  NeverLine,
4834
4871
  {
4835
4872
  width: dividerWidth,
4836
4873
  segments: [{ text: "I NEVER", color: COLORS.danger, bold: true }]
4837
4874
  }
4838
4875
  ),
4839
- neverItems.map((item) => /* @__PURE__ */ jsxs10(Fragment, { children: [
4840
- /* @__PURE__ */ jsx9(NeverLine, { width: dividerWidth }),
4841
- /* @__PURE__ */ jsx9(
4876
+ neverItems.map((item) => /* @__PURE__ */ jsxs11(Fragment, { children: [
4877
+ /* @__PURE__ */ jsx10(NeverLine, { width: dividerWidth }),
4878
+ /* @__PURE__ */ jsx10(
4842
4879
  NeverLine,
4843
4880
  {
4844
4881
  width: dividerWidth,
@@ -4850,24 +4887,24 @@ function LearnMore() {
4850
4887
  }
4851
4888
  )
4852
4889
  ] }, item)),
4853
- /* @__PURE__ */ jsx9(NeverLine, { width: dividerWidth }),
4854
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
4890
+ /* @__PURE__ */ jsx10(NeverLine, { width: dividerWidth }),
4891
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
4855
4892
  ] }),
4856
- /* @__PURE__ */ jsx9(Box11, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, children: [
4857
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
4858
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.accent, children: link.url })
4893
+ /* @__PURE__ */ jsx10(Box12, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: 1, children: [
4894
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
4895
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.accent, children: link.url })
4859
4896
  ] }, link.label)) }),
4860
- /* @__PURE__ */ jsxs10(Box11, { marginTop: 1, flexDirection: "row", gap: 3, children: [
4861
- /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, children: [
4862
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: "[" }),
4863
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.primary, children: "esc" }),
4864
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: "] back" })
4897
+ /* @__PURE__ */ jsxs11(Box12, { marginTop: 1, flexDirection: "row", gap: 3, children: [
4898
+ /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: 1, children: [
4899
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "[" }),
4900
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.primary, children: "esc" }),
4901
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "] back" })
4865
4902
  ] }),
4866
- /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, children: [
4867
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: "[" }),
4868
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.primary, children: "enter" }),
4869
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: "]" }),
4870
- /* @__PURE__ */ jsx9(Text11, { color: COLORS.success, bold: true, children: "start wizard" })
4903
+ /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: 1, children: [
4904
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "[" }),
4905
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.primary, children: "enter" }),
4906
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "]" }),
4907
+ /* @__PURE__ */ jsx10(Text12, { color: COLORS.success, bold: true, children: "start wizard" })
4871
4908
  ] })
4872
4909
  ] })
4873
4910
  ]
@@ -4876,17 +4913,17 @@ function LearnMore() {
4876
4913
  }
4877
4914
 
4878
4915
  // src/ui/Sidebar.tsx
4879
- import { Box as Box14, Text as Text14 } from "ink";
4916
+ import { Box as Box15, Text as Text15 } from "ink";
4880
4917
 
4881
4918
  // src/ui/Steps.tsx
4882
- import { Box as Box12, Text as Text12 } from "ink";
4919
+ import { Box as Box13, Text as Text13 } from "ink";
4883
4920
  import Spinner from "ink-spinner";
4884
- import { jsx as jsx10, jsxs as jsxs11 } from "react/jsx-runtime";
4921
+ import { jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
4885
4922
  function Steps() {
4886
4923
  const { steps } = useWizard();
4887
4924
  const visibleSteps = steps.filter(isStepVisible);
4888
- return /* @__PURE__ */ jsx10(Box12, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx10(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsxs11(Text12, { color: COLORS.status[s.status], children: [
4889
- s.status === "running" ? /* @__PURE__ */ jsx10(Spinner, { type: "dots" }) : MARKER[s.status],
4925
+ 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: [
4926
+ s.status === "running" ? /* @__PURE__ */ jsx11(Spinner, { type: "dots" }) : MARKER[s.status],
4890
4927
  " ",
4891
4928
  s.title
4892
4929
  ] }) }, s.id)) });
@@ -4895,27 +4932,27 @@ function CurrentStep() {
4895
4932
  const { steps } = useWizard();
4896
4933
  const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
4897
4934
  if (!currentStep) return null;
4898
- return /* @__PURE__ */ jsxs11(Text12, { color: COLORS.status.running, children: [
4899
- /* @__PURE__ */ jsx10(Spinner, { type: "dots" }),
4935
+ return /* @__PURE__ */ jsxs12(Text13, { color: COLORS.status.running, children: [
4936
+ /* @__PURE__ */ jsx11(Spinner, { type: "dots" }),
4900
4937
  " ",
4901
4938
  ` ${currentStep.title}`
4902
4939
  ] });
4903
4940
  }
4904
4941
 
4905
4942
  // src/ui/Progress.tsx
4906
- import { Box as Box13, Text as Text13 } from "ink";
4907
- import { jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
4943
+ import { Box as Box14, Text as Text14 } from "ink";
4944
+ import { jsx as jsx12, jsxs as jsxs13 } from "react/jsx-runtime";
4908
4945
  function Progress() {
4909
4946
  const { steps, currentStepIndex } = useWizard();
4910
4947
  const visibleSteps = steps.filter(isStepVisible);
4911
4948
  if (visibleSteps.length === 0) return null;
4912
4949
  const visibleCountThroughCurrent = steps.slice(0, currentStepIndex + 1).filter(isStepVisible).length;
4913
4950
  const activeStepNumber = Math.max(1, visibleCountThroughCurrent);
4914
- return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "row", gap: 1, children: [
4915
- /* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "STEP" }),
4916
- /* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: activeStepNumber }),
4917
- /* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: "/" }),
4918
- /* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: visibleSteps.length })
4951
+ return /* @__PURE__ */ jsxs13(Box14, { flexDirection: "row", gap: 1, children: [
4952
+ /* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: "STEP" }),
4953
+ /* @__PURE__ */ jsx12(Text14, { color: COLORS.strong, bold: true, children: activeStepNumber }),
4954
+ /* @__PURE__ */ jsx12(Text14, { color: COLORS.strong, bold: true, children: "/" }),
4955
+ /* @__PURE__ */ jsx12(Text14, { color: COLORS.strong, bold: true, children: visibleSteps.length })
4919
4956
  ] });
4920
4957
  }
4921
4958
 
@@ -4926,10 +4963,10 @@ var sidebarCommands = [
4926
4963
  ];
4927
4964
 
4928
4965
  // src/ui/Sidebar.tsx
4929
- import { jsx as jsx12, jsxs as jsxs13 } from "react/jsx-runtime";
4966
+ import { jsx as jsx13, jsxs as jsxs14 } from "react/jsx-runtime";
4930
4967
  function Sidebar() {
4931
- return /* @__PURE__ */ jsxs13(
4932
- Box14,
4968
+ return /* @__PURE__ */ jsxs14(
4969
+ Box15,
4933
4970
  {
4934
4971
  backgroundColor: "#14171E",
4935
4972
  width: 30,
@@ -4938,16 +4975,16 @@ function Sidebar() {
4938
4975
  flexDirection: "column",
4939
4976
  justifyContent: "space-between",
4940
4977
  children: [
4941
- /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", gap: 1, children: [
4942
- /* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: "PROGRESS" }),
4943
- /* @__PURE__ */ jsx12(Steps, {})
4978
+ /* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", gap: 1, children: [
4979
+ /* @__PURE__ */ jsx13(Text15, { color: COLORS.muted, children: "PROGRESS" }),
4980
+ /* @__PURE__ */ jsx13(Steps, {})
4944
4981
  ] }),
4945
- /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", gap: 1, children: [
4946
- /* @__PURE__ */ jsx12(Progress, {}),
4947
- /* @__PURE__ */ jsx12(Box14, { flexDirection: "column", children: sidebarCommands.map((c) => {
4948
- return /* @__PURE__ */ jsxs13(Box14, { flexDirection: "row", gap: 1, children: [
4949
- /* @__PURE__ */ jsx12(Text14, { color: COLORS.primary, children: `[${c.keyHint}]` }),
4950
- /* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: c.description })
4982
+ /* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", gap: 1, children: [
4983
+ /* @__PURE__ */ jsx13(Progress, {}),
4984
+ /* @__PURE__ */ jsx13(Box15, { flexDirection: "column", children: sidebarCommands.map((c) => {
4985
+ return /* @__PURE__ */ jsxs14(Box15, { flexDirection: "row", gap: 1, children: [
4986
+ /* @__PURE__ */ jsx13(Text15, { color: COLORS.primary, children: `[${c.keyHint}]` }),
4987
+ /* @__PURE__ */ jsx13(Text15, { color: COLORS.muted, children: c.description })
4951
4988
  ] });
4952
4989
  }) })
4953
4990
  ] })
@@ -4957,12 +4994,12 @@ function Sidebar() {
4957
4994
  }
4958
4995
 
4959
4996
  // src/ui/Ribbon.tsx
4960
- import { Box as Box15, Text as Text15 } from "ink";
4961
- import { jsx as jsx13, jsxs as jsxs14 } from "react/jsx-runtime";
4997
+ import { Box as Box16, Text as Text16 } from "ink";
4998
+ import { jsx as jsx14, jsxs as jsxs15 } from "react/jsx-runtime";
4962
4999
  function Ribbon() {
4963
5000
  const firstCommand = sidebarCommands[0];
4964
- return /* @__PURE__ */ jsxs14(
4965
- Box15,
5001
+ return /* @__PURE__ */ jsxs15(
5002
+ Box16,
4966
5003
  {
4967
5004
  backgroundColor: "#14171E",
4968
5005
  flexDirection: "row",
@@ -4970,11 +5007,11 @@ function Ribbon() {
4970
5007
  paddingX: 2,
4971
5008
  paddingY: 1,
4972
5009
  children: [
4973
- /* @__PURE__ */ jsx13(Progress, {}),
4974
- /* @__PURE__ */ jsx13(CurrentStep, {}),
4975
- /* @__PURE__ */ jsxs14(Box15, { flexDirection: "row", gap: 1, children: [
4976
- /* @__PURE__ */ jsx13(Text15, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
4977
- /* @__PURE__ */ jsx13(Text15, { color: COLORS.muted, children: firstCommand.description })
5010
+ /* @__PURE__ */ jsx14(Progress, {}),
5011
+ /* @__PURE__ */ jsx14(CurrentStep, {}),
5012
+ /* @__PURE__ */ jsxs15(Box16, { flexDirection: "row", gap: 1, children: [
5013
+ /* @__PURE__ */ jsx14(Text16, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
5014
+ /* @__PURE__ */ jsx14(Text16, { color: COLORS.muted, children: firstCommand.description })
4978
5015
  ] })
4979
5016
  ]
4980
5017
  }
@@ -4982,11 +5019,11 @@ function Ribbon() {
4982
5019
  }
4983
5020
 
4984
5021
  // src/ui/App.tsx
4985
- import { useState as useState9 } from "react";
5022
+ import { useState as useState10 } from "react";
4986
5023
 
4987
5024
  // src/ui/Logs.tsx
4988
- import { Box as Box16, Text as Text16, useInput as useInput5 } from "ink";
4989
- import { jsx as jsx14, jsxs as jsxs15 } from "react/jsx-runtime";
5025
+ import { Box as Box17, Text as Text17, useInput as useInput6 } from "ink";
5026
+ import { jsx as jsx15, jsxs as jsxs16 } from "react/jsx-runtime";
4990
5027
  var KIND_COLOR = {
4991
5028
  tool: COLORS.primary,
4992
5029
  prompt: COLORS.badge
@@ -5017,14 +5054,14 @@ function formatTimestamp(ms) {
5017
5054
  function Logs() {
5018
5055
  const logs = useWizard((s) => s.logs);
5019
5056
  const scroll = useScrollWindow({ itemCount: logs.length, followBottom: true });
5020
- useInput5((_input, key) => {
5057
+ useInput6((_input, key) => {
5021
5058
  if (key.upArrow) scroll.scrollBy(-1);
5022
5059
  else if (key.downArrow) scroll.scrollBy(1);
5023
5060
  });
5024
5061
  const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
5025
- return /* @__PURE__ */ jsxs15(Box16, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
5026
- logs.length === 0 && /* @__PURE__ */ jsx14(Text16, { color: COLORS.dim, children: "No logs yet." }),
5027
- /* @__PURE__ */ jsx14(ScrollView, { scroll, children: visible.map((entry) => {
5062
+ return /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
5063
+ logs.length === 0 && /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, children: "No logs yet." }),
5064
+ /* @__PURE__ */ jsx15(ScrollView, { scroll, children: visible.map((entry) => {
5028
5065
  const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
5029
5066
  const durationText = entry.kind === "tool" && entry.durationMs !== void 0 ? `${entry.durationMs}ms` : "";
5030
5067
  const rawPreview = rawInputText(entry.input);
@@ -5034,25 +5071,25 @@ function Logs() {
5034
5071
  const name = truncate2(entry.name, budget);
5035
5072
  budget -= name.length;
5036
5073
  const preview = rawPreview ? truncate2(rawPreview, budget) : "";
5037
- return /* @__PURE__ */ jsxs15(Box16, { flexDirection: "row", gap: ROW_GAP, children: [
5038
- /* @__PURE__ */ jsx14(Text16, { color: COLORS.dim, children: timestamp }),
5039
- /* @__PURE__ */ jsx14(Text16, { color: logNameColor(entry), wrap: "truncate", children: name }),
5040
- preview && /* @__PURE__ */ jsx14(Text16, { color: COLORS.dim, wrap: "truncate", children: preview }),
5041
- durationText && /* @__PURE__ */ jsx14(Text16, { color: COLORS.dim, children: durationText })
5074
+ return /* @__PURE__ */ jsxs16(Box17, { flexDirection: "row", gap: ROW_GAP, children: [
5075
+ /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, children: timestamp }),
5076
+ /* @__PURE__ */ jsx15(Text17, { color: logNameColor(entry), wrap: "truncate", children: name }),
5077
+ preview && /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, wrap: "truncate", children: preview }),
5078
+ durationText && /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, children: durationText })
5042
5079
  ] }, entry.id);
5043
5080
  }) }),
5044
- /* @__PURE__ */ jsx14(Text16, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
5081
+ /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
5045
5082
  ] });
5046
5083
  }
5047
5084
 
5048
5085
  // src/ui/Tips.tsx
5049
- import { useEffect as useEffect3, useRef as useRef4, useState as useState8 } from "react";
5050
- import { Box as Box18, Text as Text18 } from "ink";
5086
+ import { useEffect as useEffect3, useRef as useRef4, useState as useState9 } from "react";
5087
+ import { Box as Box19, Text as Text19 } from "ink";
5051
5088
  import terminalLink from "terminal-link";
5052
5089
 
5053
5090
  // src/ui/Code.tsx
5054
- import { Box as Box17, Text as Text17 } from "ink";
5055
- import { jsx as jsx15 } from "react/jsx-runtime";
5091
+ import { Box as Box18, Text as Text18 } from "ink";
5092
+ import { jsx as jsx16 } from "react/jsx-runtime";
5056
5093
  var TOKEN_RE = /("(?:\\.|[^"\\])*"|\btrue\b|\bfalse\b|\bnull\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|[{}[\]:,])/g;
5057
5094
  function highlightJson(json) {
5058
5095
  const parts = json.split(TOKEN_RE);
@@ -5061,22 +5098,22 @@ function highlightJson(json) {
5061
5098
  if (part[0] === '"') {
5062
5099
  const next = parts.slice(i + 1).find((p) => p.trim());
5063
5100
  const isKey = next?.trimStart().startsWith(":");
5064
- return /* @__PURE__ */ jsx15(Text17, { color: isKey ? "cyan" : "green", children: part }, i);
5101
+ return /* @__PURE__ */ jsx16(Text18, { color: isKey ? "cyan" : "green", children: part }, i);
5065
5102
  }
5066
5103
  if (part === "true" || part === "false" || part === "null") {
5067
- return /* @__PURE__ */ jsx15(Text17, { color: "magenta", children: part }, i);
5104
+ return /* @__PURE__ */ jsx16(Text18, { color: "magenta", children: part }, i);
5068
5105
  }
5069
5106
  if (/^-?\d/.test(part)) {
5070
- return /* @__PURE__ */ jsx15(Text17, { color: "yellow", children: part }, i);
5107
+ return /* @__PURE__ */ jsx16(Text18, { color: "yellow", children: part }, i);
5071
5108
  }
5072
5109
  if (/^[{}[\]:,]$/.test(part)) {
5073
- return /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, children: part }, i);
5110
+ return /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: part }, i);
5074
5111
  }
5075
- return /* @__PURE__ */ jsx15(Text17, { children: part }, i);
5112
+ return /* @__PURE__ */ jsx16(Text18, { children: part }, i);
5076
5113
  });
5077
5114
  }
5078
5115
  function Code({ children }) {
5079
- return /* @__PURE__ */ jsx15(Box17, { children: /* @__PURE__ */ jsx15(Text17, { children: highlightJson(children) }) });
5116
+ return /* @__PURE__ */ jsx16(Box18, { children: /* @__PURE__ */ jsx16(Text18, { children: highlightJson(children) }) });
5080
5117
  }
5081
5118
 
5082
5119
  // src/ui/copy/tips.ts
@@ -5290,26 +5327,26 @@ function tipsByIds(ids) {
5290
5327
  }
5291
5328
 
5292
5329
  // src/ui/Tips.tsx
5293
- import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
5330
+ import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
5294
5331
  var TICK_MS = 16;
5295
5332
  var CHUNK_HOLD_MS = 2e3;
5296
5333
  var HOLD_MS = 12e3;
5297
5334
  function TipTitle({ children }) {
5298
- return /* @__PURE__ */ jsxs16(Box18, { gap: 1, children: [
5299
- /* @__PURE__ */ jsx16(Text18, { color: "cyan", children: "\u2726" }),
5300
- /* @__PURE__ */ jsx16(Text18, { color: "white", bold: true, children })
5335
+ return /* @__PURE__ */ jsxs17(Box19, { gap: 1, children: [
5336
+ /* @__PURE__ */ jsx17(Text19, { color: "cyan", children: "\u2726" }),
5337
+ /* @__PURE__ */ jsx17(Text19, { color: "white", bold: true, children })
5301
5338
  ] });
5302
5339
  }
5303
5340
  function InlineSegment({ segment }) {
5304
5341
  switch (segment.type) {
5305
5342
  case "highlight":
5306
- return /* @__PURE__ */ jsx16(Text18, { color: COLORS.success, children: segment.value });
5343
+ return /* @__PURE__ */ jsx17(Text19, { color: COLORS.success, children: segment.value });
5307
5344
  case "link":
5308
- return /* @__PURE__ */ jsx16(Text18, { color: "cyan", underline: true, children: segment.href ? terminalLink(segment.value, segment.href) : segment.value });
5345
+ return /* @__PURE__ */ jsx17(Text19, { color: "cyan", underline: true, children: segment.href ? terminalLink(segment.value, segment.href) : segment.value });
5309
5346
  case "codeword":
5310
- return /* @__PURE__ */ jsx16(Text18, { color: COLORS.highlight.fg, backgroundColor: COLORS.highlight.bg, children: segment.value });
5347
+ return /* @__PURE__ */ jsx17(Text19, { color: COLORS.highlight.fg, backgroundColor: COLORS.highlight.bg, children: segment.value });
5311
5348
  default:
5312
- return /* @__PURE__ */ jsx16(Text18, { color: COLORS.muted, children: segment.value });
5349
+ return /* @__PURE__ */ jsx17(Text19, { color: COLORS.muted, children: segment.value });
5313
5350
  }
5314
5351
  }
5315
5352
  function TipContent({
@@ -5343,10 +5380,10 @@ function TipContent({
5343
5380
  blocks.push({ type: "inline", segments: [segment] });
5344
5381
  }
5345
5382
  }
5346
- return /* @__PURE__ */ jsx16(Box18, { flexDirection: "column", marginLeft: 2, gap: 1, children: blocks.map(
5347
- (block, i) => block.type === "code" ? /* @__PURE__ */ jsx16(Code, { children: block.segment.value }, i) : /* @__PURE__ */ jsx16(Text18, { children: block.segments.map((segment, j) => /* @__PURE__ */ jsxs16(Text18, { children: [
5383
+ return /* @__PURE__ */ jsx17(Box19, { flexDirection: "column", marginLeft: 2, gap: 1, children: blocks.map(
5384
+ (block, i) => block.type === "code" ? /* @__PURE__ */ jsx17(Code, { children: block.segment.value }, i) : /* @__PURE__ */ jsx17(Text19, { children: block.segments.map((segment, j) => /* @__PURE__ */ jsxs17(Text19, { children: [
5348
5385
  j > 0 && " ",
5349
- /* @__PURE__ */ jsx16(InlineSegment, { segment })
5386
+ /* @__PURE__ */ jsx17(InlineSegment, { segment })
5350
5387
  ] }, j)) }, i)
5351
5388
  ) });
5352
5389
  }
@@ -5363,8 +5400,8 @@ function Tips({
5363
5400
  progress.tipIndex = 0;
5364
5401
  progress.revealed = 0;
5365
5402
  }
5366
- const [tipIndex, setTipIndex] = useState8(resuming ? progress.tipIndex : 0);
5367
- const [revealed, setRevealed] = useState8(resuming ? progress.revealed : 0);
5403
+ const [tipIndex, setTipIndex] = useState9(resuming ? progress.tipIndex : 0);
5404
+ const [revealed, setRevealed] = useState9(resuming ? progress.revealed : 0);
5368
5405
  const tip = tips2.length > 0 ? tips2[tipIndex % tips2.length] : void 0;
5369
5406
  const contentLength = tip?.chunks.reduce((sum, c) => sum + c.value.length, 0) ?? 0;
5370
5407
  const totalLength = (tip?.title.length ?? 0) + contentLength;
@@ -5423,14 +5460,14 @@ function Tips({
5423
5460
  if (!tip) return null;
5424
5461
  const titleRevealed = tip.title.slice(0, revealed);
5425
5462
  const contentRevealed = Math.max(0, revealed - tip.title.length);
5426
- return /* @__PURE__ */ jsxs16(Box18, { flexDirection: "column", marginBottom: 1, gap: 1, children: [
5427
- /* @__PURE__ */ jsx16(TipTitle, { children: titleRevealed }),
5428
- /* @__PURE__ */ jsx16(TipContent, { chunks: tip.chunks, revealed: contentRevealed })
5463
+ return /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", marginBottom: 1, gap: 1, children: [
5464
+ /* @__PURE__ */ jsx17(TipTitle, { children: titleRevealed }),
5465
+ /* @__PURE__ */ jsx17(TipContent, { chunks: tip.chunks, revealed: contentRevealed })
5429
5466
  ] });
5430
5467
  }
5431
5468
 
5432
5469
  // src/ui/App.tsx
5433
- import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
5470
+ import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
5434
5471
  function App() {
5435
5472
  const {
5436
5473
  phase,
@@ -5441,12 +5478,12 @@ function App() {
5441
5478
  inputReq,
5442
5479
  user,
5443
5480
  workflow,
5444
- settingUpAppId
5481
+ review: review2
5445
5482
  } = useWizard();
5446
5483
  const { exit } = useApp();
5447
5484
  const { columns, rows } = useWindowSize7();
5448
- const [showLogs, setShowLogs] = useState9(false);
5449
- const [tipState, setTipState] = useState9("idle");
5485
+ const [showLogs, setShowLogs] = useState10(false);
5486
+ const [tipState, setTipState] = useState10("idle");
5450
5487
  const finished = phase === "done" || phase === "error";
5451
5488
  const currentStep = steps[currentStepIndex];
5452
5489
  const stepDef = workflow ? getWorkflow(workflow.id)?.steps.find((s) => s.id === currentStep?.id) : void 0;
@@ -5456,10 +5493,10 @@ function App() {
5456
5493
  const isCommandApprovalPrompt = isAwaitingUserInput && inputReq?.promptType === "commandApproval";
5457
5494
  const promptPending = isAwaitingUserInput && !isCommandApprovalPrompt;
5458
5495
  const holdForTip = stepHasTips && promptPending && tipState === "revealing";
5459
- const showTips = stepHasTips && (phase === "running" && currentStep?.status === "running" || isCommandApprovalPrompt || holdForTip);
5496
+ const showTips = stepHasTips && (phase === "running" || isCommandApprovalPrompt || holdForTip);
5460
5497
  const showNoticesInMain = !stepHasTips;
5461
- const showNotices = !isAwaitingUserInput || holdForTip;
5462
- useInput6(
5498
+ const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
5499
+ useInput7(
5463
5500
  (_input, key) => {
5464
5501
  if (key.return) {
5465
5502
  exit();
@@ -5467,7 +5504,7 @@ function App() {
5467
5504
  },
5468
5505
  { isActive: finished }
5469
5506
  );
5470
- useInput6((_input, key) => {
5507
+ useInput7((_input, key) => {
5471
5508
  if (phase === "idle" || phase === "authenticating") return;
5472
5509
  if (key.tab) {
5473
5510
  setShowLogs(!showLogs);
@@ -5479,7 +5516,7 @@ function App() {
5479
5516
  }
5480
5517
  });
5481
5518
  const escOwnedElsewhere = phase === "idle" || phase === "authenticating" || phase === "awaitingInput" && !holdForTip && (inputReq?.promptType === "enterToContinue" || inputReq?.promptType === "commandApproval");
5482
- useInput6((_input, key) => {
5519
+ useInput7((_input, key) => {
5483
5520
  if (escOwnedElsewhere) return;
5484
5521
  if (key.escape) {
5485
5522
  track("AI Wizard Interaction", {
@@ -5498,8 +5535,8 @@ function App() {
5498
5535
  /* Clamped to exactly the viewport: a taller frame makes Ink clear and repaint
5499
5536
  the whole screen, and the scrolling throws off its cursor arithmetic —
5500
5537
  flicker and leftover rows. */
5501
- /* @__PURE__ */ jsxs17(
5502
- Box19,
5538
+ /* @__PURE__ */ jsxs18(
5539
+ Box20,
5503
5540
  {
5504
5541
  backgroundColor: COLORS.bg.main,
5505
5542
  flexDirection: "row",
@@ -5507,16 +5544,16 @@ function App() {
5507
5544
  height: scrollsPastViewport ? void 0 : rows,
5508
5545
  overflow: scrollsPastViewport ? "visible" : "hidden",
5509
5546
  children: [
5510
- mainWindowVisible && /* @__PURE__ */ jsxs17(
5511
- Box19,
5547
+ mainWindowVisible && /* @__PURE__ */ jsxs18(
5548
+ Box20,
5512
5549
  {
5513
5550
  flexDirection,
5514
5551
  width: "100%",
5515
5552
  maxHeight: rows,
5516
5553
  justifyContent: "space-between",
5517
5554
  children: [
5518
- showLogs ? /* @__PURE__ */ jsx17(Logs, {}) : /* @__PURE__ */ jsxs17(
5519
- Box19,
5555
+ showLogs ? /* @__PURE__ */ jsx18(Logs, {}) : /* @__PURE__ */ jsxs18(
5556
+ Box20,
5520
5557
  {
5521
5558
  flexDirection: "column",
5522
5559
  paddingX: 4,
@@ -5525,30 +5562,24 @@ function App() {
5525
5562
  flexGrow: 1,
5526
5563
  gap: 1,
5527
5564
  children: [
5528
- /* @__PURE__ */ jsxs17(Box19, { flexGrow: 2, flexDirection: "column", children: [
5529
- phase === "preflight" && !user && /* @__PURE__ */ jsx17(Box19, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs17(Text19, { color: COLORS.strong, bold: true, children: [
5530
- /* @__PURE__ */ jsx17(Spinner2, { type: "dots" }),
5565
+ /* @__PURE__ */ jsxs18(Box20, { flexGrow: 2, flexDirection: "column", children: [
5566
+ phase === "preflight" && !user && /* @__PURE__ */ jsx18(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.strong, bold: true, children: [
5567
+ /* @__PURE__ */ jsx18(Spinner2, { type: "dots" }),
5531
5568
  " Signing in to Algolia"
5532
5569
  ] }) }),
5533
- phase === "preflight" && user && /* @__PURE__ */ jsx17(Box19, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs17(Text19, { color: COLORS.strong, bold: true, children: [
5534
- /* @__PURE__ */ jsx17(Spinner2, { type: "dots" }),
5570
+ phase === "preflight" && user && /* @__PURE__ */ jsx18(Box20, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.strong, bold: true, children: [
5571
+ /* @__PURE__ */ jsx18(Spinner2, { type: "dots" }),
5535
5572
  " Getting things ready"
5536
5573
  ] }) }),
5537
- phase === "authenticating" && /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", marginBottom: 1, children: [
5538
- /* @__PURE__ */ jsxs17(Text19, { color: COLORS.strong, bold: true, children: [
5539
- /* @__PURE__ */ jsx17(Spinner2, { type: "dots" }),
5574
+ phase === "authenticating" && /* @__PURE__ */ jsxs18(Box20, { flexDirection: "column", marginBottom: 1, children: [
5575
+ /* @__PURE__ */ jsxs18(Text20, { color: COLORS.strong, bold: true, children: [
5576
+ /* @__PURE__ */ jsx18(Spinner2, { type: "dots" }),
5540
5577
  " Signing in to Algolia"
5541
5578
  ] }),
5542
- /* @__PURE__ */ jsx17(Text19, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
5579
+ /* @__PURE__ */ jsx18(Text20, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
5543
5580
  ] }),
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
- /* @__PURE__ */ jsx17(CliOutput, {}),
5551
- showTips && currentStep && /* @__PURE__ */ jsx17(
5581
+ /* @__PURE__ */ jsx18(CliOutput, {}),
5582
+ showTips && currentStep && /* @__PURE__ */ jsx18(
5552
5583
  Tips,
5553
5584
  {
5554
5585
  stepId: currentStep.id,
@@ -5556,23 +5587,24 @@ function App() {
5556
5587
  onRevealStateChange: setTipState
5557
5588
  }
5558
5589
  ),
5559
- showNoticesInMain && showNotices && /* @__PURE__ */ jsx17(Notices, { showAll: true, border: false }),
5560
- !showTips && /* @__PURE__ */ jsx17(PromptInput, {}),
5561
- phase === "error" && error && /* @__PURE__ */ jsx17(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs17(Text19, { color: COLORS.status.error, children: [
5590
+ showNoticesInMain && showNotices && /* @__PURE__ */ jsx18(Notices, { showAll: true, border: false }),
5591
+ /* @__PURE__ */ jsx18(Review, {}),
5592
+ !showTips && /* @__PURE__ */ jsx18(PromptInput, {}),
5593
+ phase === "error" && error && /* @__PURE__ */ jsx18(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.status.error, children: [
5562
5594
  "\u2716 ",
5563
5595
  error
5564
5596
  ] }) })
5565
5597
  ] }),
5566
- !showNoticesInMain && showNotices && /* @__PURE__ */ jsx17(Notices, {}),
5567
- showTips && !holdForTip && /* @__PURE__ */ jsx17(PromptInput, {})
5598
+ !showNoticesInMain && showNotices && /* @__PURE__ */ jsx18(Notices, {}),
5599
+ showTips && !holdForTip && /* @__PURE__ */ jsx18(PromptInput, {})
5568
5600
  ]
5569
5601
  }
5570
5602
  ),
5571
- showSidebar ? /* @__PURE__ */ jsx17(Sidebar, {}) : /* @__PURE__ */ jsx17(Ribbon, {})
5603
+ showSidebar ? /* @__PURE__ */ jsx18(Sidebar, {}) : /* @__PURE__ */ jsx18(Ribbon, {})
5572
5604
  ]
5573
5605
  }
5574
5606
  ),
5575
- phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */ jsx17(LearnMore, {}) : /* @__PURE__ */ jsx17(Welcome, {}))
5607
+ phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */ jsx18(LearnMore, {}) : /* @__PURE__ */ jsx18(Welcome, {}))
5576
5608
  ]
5577
5609
  }
5578
5610
  )
@@ -5616,72 +5648,50 @@ function readValue(raw) {
5616
5648
  }
5617
5649
 
5618
5650
  // src/lib/algoliaAppPicker.ts
5619
- function blockReasonFor(app) {
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
- }
5651
+ function secondaryFor(app) {
5629
5652
  return app.plan ? { kind: "badge", value: app.plan } : void 0;
5630
5653
  }
5631
5654
  function labelFor(app) {
5632
5655
  return app.name.trim() ? `${app.name} \u2014 ${app.id}` : app.id;
5633
5656
  }
5634
- async function isEligible(app) {
5635
- const apps = await listApplications();
5636
- const full = apps.find((candidate) => candidate.id === app.id);
5637
- return full != null && canSelectApplication(full);
5638
- }
5639
- async function selectAndReport(app) {
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
- }
5657
+ function selectAndReport(app) {
5658
+ useWizard.getState().pushCliOutput(
5659
+ "stdout",
5660
+ `Selecting ${labelFor(app)} \u2014 provisioning its API key\u2026`
5661
+ );
5662
+ return selectApplication(app.id);
5647
5663
  }
5648
- async function promptForApplication(highlight) {
5664
+ async function promptForApplication(leadIn = []) {
5649
5665
  const store = useWizard.getState();
5650
- const unordered = await listApplications();
5651
- if (unordered.length === 0) {
5666
+ const apps = await listApplications();
5667
+ if (apps.length === 0) {
5652
5668
  throw new Error(
5653
5669
  "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
5670
  );
5655
5671
  }
5656
- if (!unordered.some(canSelectApplication)) {
5657
- throw new Error(
5658
- "None of the applications on this Algolia account are usable \u2014 each is either paused or missing key-management access. Activate one, or grant it the `keys` ACL, then restart the wizard."
5672
+ if (apps.length === 1) {
5673
+ const only = apps[0];
5674
+ logger.info(
5675
+ { app: only.id },
5676
+ "single application on the account; selecting it"
5659
5677
  );
5678
+ for (const line of leadIn) store.pushCliOutput("stdout", line);
5679
+ return selectAndReport(only);
5660
5680
  }
5661
- const apps = [
5662
- ...unordered.filter(canSelectApplication),
5663
- ...unordered.filter((app) => !canSelectApplication(app))
5681
+ const messages = [
5682
+ ...leadIn,
5683
+ "Which Algolia application should the wizard work in?"
5664
5684
  ];
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
5685
  for (; ; ) {
5674
5686
  const choice = await store.requestUserInput({
5675
- prompt: "Which Algolia application should the wizard work in?",
5687
+ prompt: "Select an application",
5676
5688
  promptType: "multipleChoice",
5677
5689
  options: apps.map(labelFor),
5678
- secondary: apps.map((app) => secondaryFor(app, highlight?.id)),
5679
- disabled: apps.map((app) => !canSelectApplication(app)),
5680
- ...highlightIndex >= 0 ? { defaultSelectedIndex: highlightIndex } : {},
5690
+ secondary: apps.map(secondaryFor),
5681
5691
  messages
5682
5692
  });
5683
5693
  const chosen = apps.find((app) => labelFor(app) === choice);
5684
- if (!chosen || !canSelectApplication(chosen)) {
5694
+ if (!chosen) {
5685
5695
  throw new Error("Application picker received an unexpected selection");
5686
5696
  }
5687
5697
  try {
@@ -5697,15 +5707,42 @@ async function promptForApplication(highlight) {
5697
5707
  }
5698
5708
  }
5699
5709
  }
5700
- async function ensureApplication(isResuming) {
5701
- const current = await currentApplication();
5702
- if (isResuming) {
5703
- if (current && await isEligible(current)) return current;
5704
- return promptForApplication();
5710
+ async function confirmEnvApplication(env, current) {
5711
+ const useEnv = `Use ${env.id} (from ${env.file})`;
5712
+ const choice = await useWizard.getState().requestUserInput({
5713
+ prompt: "Select an application",
5714
+ promptType: "multipleChoice",
5715
+ options: [
5716
+ useEnv,
5717
+ current ? `Use ${labelFor(current)} (already selected)` : "Pick a different application"
5718
+ ],
5719
+ messages: [
5720
+ `${env.file} already sets ${env.name}=${env.id}.`,
5721
+ "Which Algolia application should the wizard work in?"
5722
+ ]
5723
+ });
5724
+ return choice === useEnv;
5725
+ }
5726
+ async function selectEnvApplication(env) {
5727
+ try {
5728
+ return await selectAndReport({ id: env.id, name: "" });
5729
+ } catch (err) {
5730
+ logger.warn(
5731
+ { app: env.id, err: err.message },
5732
+ "could not select the application named in env; falling back to the picker"
5733
+ );
5734
+ return promptForApplication([
5735
+ `Could not select ${env.id} from ${env.file} \u2014 it may have been removed, or this account may not have access to it.`
5736
+ ]);
5705
5737
  }
5738
+ }
5739
+ async function ensureApplication() {
5740
+ const current = await currentApplication();
5706
5741
  const env = await findEnvApplicationId();
5707
- if (!env) return promptForApplication();
5708
- return promptForApplication({ id: env.id, file: env.file });
5742
+ if (env && env.id !== current?.id && await confirmEnvApplication(env, current)) {
5743
+ return selectEnvApplication(env);
5744
+ }
5745
+ return current ?? await promptForApplication();
5709
5746
  }
5710
5747
 
5711
5748
  // src/lib/seed.ts
@@ -5986,7 +6023,7 @@ function delay(ms) {
5986
6023
  }
5987
6024
 
5988
6025
  // src/main.tsx
5989
- import { jsx as jsx18 } from "react/jsx-runtime";
6026
+ import { jsx as jsx19 } from "react/jsx-runtime";
5990
6027
  async function startup() {
5991
6028
  setProjectRoot(process.cwd());
5992
6029
  let args;
@@ -6036,7 +6073,7 @@ ${formatStepList(workflow)}`);
6036
6073
  }
6037
6074
  async function run(workflow) {
6038
6075
  const store = useWizard.getState();
6039
- const instance = render(/* @__PURE__ */ jsx18(App, {}), { incrementalRendering: true });
6076
+ const instance = render(/* @__PURE__ */ jsx19(App, {}), { incrementalRendering: true });
6040
6077
  await store.waitForStart();
6041
6078
  store.syncSteps(
6042
6079
  workflow.steps.map((s) => ({
@@ -6069,15 +6106,14 @@ async function run(workflow) {
6069
6106
  }
6070
6107
  store.setUser(user);
6071
6108
  let app;
6072
- const resumableState = await loadResumableState(workflow);
6073
6109
  try {
6074
- app = await ensureApplication(resumableState != null);
6110
+ app = await ensureApplication();
6075
6111
  } catch (err) {
6076
6112
  store.setError(err instanceof Error ? err.message : String(err));
6077
6113
  await instance.waitUntilExit();
6078
6114
  process.exit(1);
6079
6115
  }
6080
- runWorkflow(workflow, app.id, resumableState);
6116
+ runWorkflow(workflow, app.id);
6081
6117
  }
6082
6118
  await requestTerminalSize();
6083
6119
  var started = await startup();