@algolia/wizard 0.6.0-rc.53.32 → 0.6.0-rc.55.31

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 +462 -734
  2. package/package.json +3 -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 Box14, Text as Text14, useApp, useInput as useInput6, useWindowSize as useWindowSize8 } from "ink";
7
+ import { Box as Box13, Text as Text13, useApp, useInput as useInput6, useWindowSize as useWindowSize7 } from "ink";
8
8
 
9
9
  // src/core/store.ts
10
10
  import { create } from "zustand";
@@ -12,54 +12,20 @@ import { nanoid } from "nanoid";
12
12
 
13
13
  // src/lib/algoliaCli.ts
14
14
  import { spawn } from "node:child_process";
15
- function npxArgs(args) {
16
- return ["--yes", "@algolia/cli@latest", ...args];
15
+ import { createRequire } from "node:module";
16
+ var require2 = createRequire(import.meta.url);
17
+ function algoliaCliEntry() {
18
+ return require2.resolve("@algolia/cli/bin/run.js");
17
19
  }
18
- var shell = process.platform === "win32";
19
- function lineSplitter(emit) {
20
- let buffer = "";
21
- return {
22
- push(chunk) {
23
- buffer += chunk;
24
- const lines = buffer.split("\n");
25
- buffer = lines.pop() ?? "";
26
- for (const line of lines) emit(line.replace(/\r$/, ""));
27
- },
28
- flush() {
29
- if (buffer) emit(buffer.replace(/\r$/, ""));
30
- buffer = "";
31
- }
32
- };
33
- }
34
- var wizardSink = (stream, line) => {
35
- if (!line.trim()) return;
36
- useWizard.getState().pushCliOutput(stream, line);
37
- };
38
- function runAlgoliaCli(args, { onOutput } = {}) {
39
- const store2 = useWizard.getState();
40
- const logId = store2.logStart("tool", `algolia ${args.join(" ")}`);
20
+ function runAlgoliaCli(args) {
41
21
  return new Promise((resolve4, reject) => {
42
- const child = spawn("npx", npxArgs(args), { shell });
22
+ const child = spawn(process.execPath, [algoliaCliEntry(), ...args]);
43
23
  let stdout = "";
44
24
  let stderr = "";
45
- const splitters = {
46
- stdout: lineSplitter((line) => onOutput?.("stdout", line)),
47
- stderr: lineSplitter((line) => onOutput?.("stderr", line))
48
- };
49
- child.stdout.on("data", (chunk) => {
50
- const text = String(chunk);
51
- stdout += text;
52
- splitters.stdout.push(text);
53
- });
54
- child.stderr.on("data", (chunk) => {
55
- const text = String(chunk);
56
- stderr += text;
57
- splitters.stderr.push(text);
58
- });
25
+ child.stdout.on("data", (chunk) => stdout += chunk);
26
+ child.stderr.on("data", (chunk) => stderr += chunk);
59
27
  child.on("error", reject);
60
28
  child.on("close", (code) => {
61
- splitters.stdout.flush();
62
- splitters.stderr.flush();
63
29
  if (code === 0) {
64
30
  resolve4(stdout);
65
31
  } else {
@@ -71,16 +37,7 @@ function runAlgoliaCli(args, { onOutput } = {}) {
71
37
  );
72
38
  }
73
39
  });
74
- }).then(
75
- (out) => {
76
- useWizard.getState().logEnd(logId, "success");
77
- return out;
78
- },
79
- (err) => {
80
- useWizard.getState().logEnd(logId, "error");
81
- throw err;
82
- }
83
- );
40
+ });
84
41
  }
85
42
  async function getUser() {
86
43
  let raw;
@@ -95,21 +52,13 @@ async function getUser() {
95
52
  return null;
96
53
  }
97
54
  }
98
- function needsInteractiveTerminal(err) {
99
- const message = err instanceof Error ? err.message : String(err);
100
- return /non-interactive mode/i.test(message);
101
- }
102
55
  function runAuthLogin() {
103
- return runAlgoliaCli(["auth", "login", "--default"], {
104
- onOutput: wizardSink
105
- }).then(() => void 0);
106
- }
107
- function runAuthLoginInTerminal() {
108
56
  return new Promise((resolve4, reject) => {
109
- const child = spawn("npx", npxArgs(["auth", "login", "--default"]), {
110
- shell,
111
- stdio: "inherit"
112
- });
57
+ const child = spawn(
58
+ process.execPath,
59
+ [algoliaCliEntry(), "auth", "login", "--default"],
60
+ { stdio: "inherit" }
61
+ );
113
62
  child.on("error", reject);
114
63
  child.on("close", (code) => {
115
64
  if (code === 0) resolve4();
@@ -222,7 +171,6 @@ function describeInputValue(value) {
222
171
  return Array.isArray(value) ? value.join(", ") : value;
223
172
  }
224
173
  var NOTICE_INTERVAL_MS = 2e3;
225
- var CLI_OUTPUT_LIMIT = 200;
226
174
  var useWizard = create((set, get) => ({
227
175
  phase: "idle",
228
176
  homeScreen: "home",
@@ -234,23 +182,10 @@ var useWizard = create((set, get) => ({
234
182
  notices: [],
235
183
  _noticeQueue: [],
236
184
  _noticeTimer: null,
237
- cliOutput: [],
238
- targetIndex: null,
239
185
  logs: [],
240
186
  error: null,
241
187
  inputReq: null,
242
188
  _resolve: null,
243
- // Brackets a CLI subprocess that needs the screen. `endAuth` must land back
244
- // on exactly 'idle': `confirmStart` is a no-op from any other phase and
245
- // `waitForStart` resolves on any non-idle phase, so ending anywhere else
246
- // either skips the welcome screen or ignores its spacebar forever.
247
- beginAuth: () => set({ phase: "authenticating", cliOutput: [] }),
248
- // Re-enters the auth phase *keeping* the CLI output on screen, for returning
249
- // from a prompt raised mid-sign-in (`submitInput` leaves the phase at
250
- // 'running'). Clearing here would blank the login output the user was reading
251
- // the instant they answered.
252
- resumeAuth: () => set({ phase: "authenticating" }),
253
- endAuth: () => set((s) => s.phase === "authenticating" ? { phase: "idle" } : {}),
254
189
  // Advances past the welcome screen. Only meaningful from 'idle' — once the
255
190
  // workflow is running there's nothing left to confirm.
256
191
  // Reset `homeScreen` so preflight shows Welcome, not the Learn more sub-view.
@@ -261,7 +196,7 @@ var useWizard = create((set, get) => ({
261
196
  openLearnMore: () => set({ homeScreen: "learnMore" }),
262
197
  backToHome: () => set({ homeScreen: "home" }),
263
198
  // Resolves once the phase leaves 'idle', whether that happens before or
264
- // after this is called (the welcome screen's spacebar handler is what
199
+ // after this is called (the welcome screen's enter handler is what
265
200
  // drives the transition via `confirmStart`).
266
201
  waitForStart: () => new Promise((resolve4) => {
267
202
  if (get().phase !== "idle") {
@@ -285,13 +220,7 @@ var useWizard = create((set, get) => ({
285
220
  syncSteps: (steps, currentStepIndex) => set({ steps, currentStepIndex }),
286
221
  setActiveStep: (index) => {
287
222
  get()._clearNoticeQueue();
288
- set({
289
- phase: "running",
290
- currentStepIndex: index,
291
- output: "",
292
- notices: [],
293
- cliOutput: []
294
- });
223
+ set({ phase: "running", currentStepIndex: index, output: "", notices: [] });
295
224
  },
296
225
  setUser: (user2) => set({ user: user2 }),
297
226
  appendToken: (text) => set((s) => ({ output: s.output + text })),
@@ -332,16 +261,6 @@ var useWizard = create((set, get) => ({
332
261
  get()._clearNoticeQueue();
333
262
  set({ notices: [] });
334
263
  },
335
- // Unthrottled, unlike `pushNotice`: these lines arrive at whatever rate the
336
- // subprocess emits them, and holding them back would land output after the
337
- // command it belongs to has already exited.
338
- pushCliOutput: (stream, text) => set((s) => ({
339
- cliOutput: [...s.cliOutput, { id: nanoid(), stream, text }].slice(
340
- -CLI_OUTPUT_LIMIT
341
- )
342
- })),
343
- clearCliOutput: () => set({ cliOutput: [] }),
344
- setTargetIndex: (index) => set({ targetIndex: index }),
345
264
  logStart: (kind, name, input) => {
346
265
  const id = nanoid();
347
266
  set((s) => ({
@@ -386,8 +305,6 @@ var useWizard = create((set, get) => ({
386
305
  currentStepIndex: 0,
387
306
  output: "",
388
307
  notices: [],
389
- cliOutput: [],
390
- targetIndex: null,
391
308
  logs: [],
392
309
  error: null,
393
310
  inputReq: null,
@@ -396,88 +313,16 @@ var useWizard = create((set, get) => ({
396
313
  }
397
314
  }));
398
315
 
399
- // src/ui/CliOutput.tsx
400
- import { Box, Text, useWindowSize } from "ink";
401
-
402
- // src/ui/theme.ts
403
- var MARKER = {
404
- pending: "\u25CB",
405
- running: "\u25D0",
406
- done: "\u2713",
407
- error: "\u2716"
408
- };
409
- var BRAND = "#003DFF";
410
- var SECONDARY = "#5468FF";
411
- var DANGER = "#F86E7E";
412
- var COLORS = {
413
- brand: BRAND,
414
- primary: "#E6EDF3",
415
- secondary: SECONDARY,
416
- strong: "#FFFFFF",
417
- muted: "#8B949E",
418
- dim: "#484F58",
419
- highlight: { bg: "#12331C", fg: "#4ADE80" },
420
- badge: "#E3B341",
421
- danger: DANGER,
422
- success: "#4ADE80",
423
- bg: {
424
- main: "#0B0E14",
425
- sidebar: "#14171E"
426
- },
427
- border: "#30363D",
428
- accent: "#76A0FF",
429
- status: {
430
- pending: "gray",
431
- running: "#76A0FF",
432
- done: "#4ADE80",
433
- error: DANGER
434
- }
435
- };
436
-
437
- // src/ui/CliOutput.tsx
438
- import { jsxs } from "react/jsx-runtime";
439
- var CLI_MARKER = "\u203A";
440
- var RESERVED_ROWS = 16;
441
- var MAX_LINES = 12;
442
- function CliOutput() {
443
- const cliOutput = useWizard((s) => s.cliOutput);
444
- const { rows } = useWindowSize();
445
- if (!cliOutput.length) return null;
446
- const budget = Math.min(Math.max(rows - RESERVED_ROWS, 3), MAX_LINES);
447
- const visible = cliOutput.slice(-budget);
448
- const hidden = cliOutput.length - visible.length;
449
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
450
- hidden > 0 && /* @__PURE__ */ jsxs(Text, { color: COLORS.dim, children: [
451
- "\u2191 ",
452
- hidden,
453
- " earlier line(s)"
454
- ] }),
455
- visible.map((line) => /* @__PURE__ */ jsxs(
456
- Text,
457
- {
458
- color: line.stream === "stderr" ? COLORS.muted : COLORS.dim,
459
- wrap: "truncate",
460
- children: [
461
- CLI_MARKER,
462
- " ",
463
- line.text
464
- ]
465
- },
466
- line.id
467
- ))
468
- ] });
469
- }
470
-
471
316
  // src/ui/Notices.tsx
472
- import { Box as Box3, Text as Text3, useWindowSize as useWindowSize3 } from "ink";
317
+ import { Box as Box2, Text as Text2, useWindowSize as useWindowSize2 } from "ink";
473
318
  import { useEffect as useEffect2, useState as useState2 } from "react";
474
319
 
475
320
  // src/ui/Table.tsx
476
- import { Box as Box2, Text as Text2, measureElement, useWindowSize as useWindowSize2 } from "ink";
321
+ import { Box, Text, measureElement, useWindowSize } from "ink";
477
322
  import { useEffect, useRef, useState } from "react";
478
323
  import { jsx } from "react/jsx-runtime";
479
324
  function Table({ columns, rows }) {
480
- const { columns: termCols } = useWindowSize2();
325
+ const { columns: termCols } = useWindowSize();
481
326
  const ref = useRef(null);
482
327
  const [width, setWidth] = useState(0);
483
328
  useEffect(() => {
@@ -485,7 +330,7 @@ function Table({ columns, rows }) {
485
330
  }, [termCols, columns, rows]);
486
331
  if (rows.length === 0) return null;
487
332
  const lines = formatTable(columns, rows, width || void 0);
488
- return /* @__PURE__ */ jsx(Box2, { flexDirection: "column", ref, children: lines.map((line, i) => /* @__PURE__ */ jsx(Text2, { wrap: "truncate", children: line }, `tbl-${i}`)) });
333
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "column", ref, children: lines.map((line, i) => /* @__PURE__ */ jsx(Text, { wrap: "truncate", children: line }, `tbl-${i}`)) });
489
334
  }
490
335
  function formatTable(columns, rows, width) {
491
336
  const natural = columns.map(
@@ -525,10 +370,45 @@ function resize(widths, budget) {
525
370
  }
526
371
  var truncate = (s, width) => s.length <= width ? s : width <= 1 ? s.slice(0, width) : `${s.slice(0, width - 1)}\u2026`;
527
372
 
373
+ // src/ui/theme.ts
374
+ var MARKER = {
375
+ pending: "\u25CB",
376
+ running: "\u25D0",
377
+ done: "\u2713",
378
+ error: "\u2716"
379
+ };
380
+ var BRAND = "#003DFF";
381
+ var SECONDARY = "#5468FF";
382
+ var DANGER = "#F86E7E";
383
+ var COLORS = {
384
+ brand: BRAND,
385
+ primary: "#E6EDF3",
386
+ secondary: SECONDARY,
387
+ strong: "#FFFFFF",
388
+ muted: "#8B949E",
389
+ dim: "#484F58",
390
+ highlight: { bg: "#12331C", fg: "#4ADE80" },
391
+ badge: "#E3B341",
392
+ danger: DANGER,
393
+ success: "#4ADE80",
394
+ bg: {
395
+ main: "#0B0E14",
396
+ sidebar: "#14171E"
397
+ },
398
+ border: "#30363D",
399
+ accent: "#76A0FF",
400
+ status: {
401
+ pending: "gray",
402
+ running: "#76A0FF",
403
+ done: "#4ADE80",
404
+ error: DANGER
405
+ }
406
+ };
407
+
528
408
  // src/ui/Notices.tsx
529
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
409
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
530
410
  var AGENT_MARKER = "\u2726";
531
- var RESERVED_ROWS2 = 14;
411
+ var RESERVED_ROWS = 14;
532
412
  var PANEL_TEXT_WIDTH = 45;
533
413
  function messageLineCount(text) {
534
414
  return Math.max(1, Math.ceil(text.length / PANEL_TEXT_WIDTH));
@@ -542,7 +422,7 @@ function noticeLineCount(notice) {
542
422
  return messageLines + tableLines;
543
423
  }
544
424
  function fitVisibleNotices(notices, windowRows) {
545
- const budget = Math.max(windowRows - RESERVED_ROWS2, 3);
425
+ const budget = Math.max(windowRows - RESERVED_ROWS, 3);
546
426
  let used = 0;
547
427
  let count = 0;
548
428
  for (let i = notices.length - 1; i >= 0; i--) {
@@ -575,7 +455,7 @@ function parseHex(hex) {
575
455
  }
576
456
  function Notices() {
577
457
  const notices = useWizard((s) => s.notices);
578
- const { rows: windowRows } = useWindowSize3();
458
+ const { rows: windowRows } = useWindowSize2();
579
459
  const visible = fitVisibleNotices(notices, windowRows);
580
460
  const [pulseStep, setPulseStep] = useState2(0);
581
461
  useEffect2(() => {
@@ -592,14 +472,14 @@ function Notices() {
592
472
  }, []);
593
473
  if (!visible.length) return null;
594
474
  const pulseColor = PULSE_COLORS[pulseStep];
595
- return /* @__PURE__ */ jsx2(Box3, { flexDirection: "column", gap: 1, marginBottom: 1, children: visible.map((notice, i) => {
475
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", gap: 1, marginBottom: 1, children: visible.map((notice, i) => {
596
476
  const isLatest = i === visible.length - 1;
597
- return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", children: [
477
+ return /* @__PURE__ */ jsxs(Box2, { flexDirection: "column", children: [
598
478
  notice.messages?.map((m, j) => {
599
479
  const line = typeof m === "string" ? { text: m } : m;
600
480
  const prefix = j === 0 ? `${AGENT_MARKER} ` : " ";
601
- return /* @__PURE__ */ jsxs2(
602
- Text3,
481
+ return /* @__PURE__ */ jsxs(
482
+ Text2,
603
483
  {
604
484
  color: isLatest && !line.color ? pulseColor : line.color ?? COLORS.dim,
605
485
  bold: line.bold,
@@ -617,37 +497,37 @@ function Notices() {
617
497
  }
618
498
 
619
499
  // src/ui/PromptInput.tsx
620
- import { Box as Box6, Text as Text6, useInput as useInput2 } from "ink";
500
+ import { Box as Box5, Text as Text5, useInput as useInput2 } from "ink";
621
501
  import TextInput from "ink-text-input";
622
502
  import { useState as useState4 } from "react";
623
503
 
624
504
  // src/ui/NextAction.tsx
625
- import { Box as Box4, Text as Text4 } from "ink";
626
- import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
505
+ import { Box as Box3, Text as Text3 } from "ink";
506
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
627
507
  function NextAction({
628
508
  action,
629
509
  keyHint,
630
510
  hierarchy = "primary"
631
511
  }) {
632
- return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "row", gap: 1, children: [
633
- hierarchy === "primary" && /* @__PURE__ */ jsx3(Text4, { color: COLORS.success, bold: true, children: `> ${action}` }),
634
- hierarchy === "secondary" && /* @__PURE__ */ jsxs3(Fragment, { children: [
635
- /* @__PURE__ */ jsx3(Text4, { color: COLORS.success, bold: true, children: `>` }),
636
- /* @__PURE__ */ jsx3(Text4, { color: COLORS.primary, bold: true, children: action })
512
+ return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "row", gap: 1, children: [
513
+ hierarchy === "primary" && /* @__PURE__ */ jsx3(Text3, { color: COLORS.success, bold: true, children: `> ${action}` }),
514
+ hierarchy === "secondary" && /* @__PURE__ */ jsxs2(Fragment, { children: [
515
+ /* @__PURE__ */ jsx3(Text3, { color: COLORS.success, bold: true, children: `>` }),
516
+ /* @__PURE__ */ jsx3(Text3, { color: COLORS.primary, bold: true, children: action })
637
517
  ] }),
638
- /* @__PURE__ */ jsxs3(Box4, { children: [
639
- /* @__PURE__ */ jsx3(Text4, { color: COLORS.muted, children: "press " }),
640
- /* @__PURE__ */ jsx3(Text4, { color: COLORS.muted, children: `[` }),
641
- /* @__PURE__ */ jsx3(Text4, { color: COLORS.primary, children: keyHint }),
642
- /* @__PURE__ */ jsx3(Text4, { color: COLORS.muted, children: `]` })
518
+ /* @__PURE__ */ jsxs2(Box3, { children: [
519
+ /* @__PURE__ */ jsx3(Text3, { color: COLORS.muted, children: "press " }),
520
+ /* @__PURE__ */ jsx3(Text3, { color: COLORS.muted, children: `[` }),
521
+ /* @__PURE__ */ jsx3(Text3, { color: COLORS.primary, children: keyHint }),
522
+ /* @__PURE__ */ jsx3(Text3, { color: COLORS.muted, children: `]` })
643
523
  ] })
644
524
  ] });
645
525
  }
646
526
 
647
527
  // src/ui/SelectPrompt.tsx
648
- import { Box as Box5, Text as Text5, measureElement as measureElement2, useInput, useWindowSize as useWindowSize4 } from "ink";
528
+ import { Box as Box4, Text as Text4, measureElement as measureElement2, useInput, useWindowSize as useWindowSize3 } from "ink";
649
529
  import { useLayoutEffect, useRef as useRef2, useState as useState3 } from "react";
650
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
530
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
651
531
  var CANCEL = "cancel";
652
532
  var ARROW_WIDTH = 4;
653
533
  var COLUMN_GAP = 2;
@@ -684,7 +564,7 @@ function SelectPrompt({
684
564
  if (multi) hints.push({ key: "[space]", label: "select" });
685
565
  hints.push({ key: "[enter]", label: "confirm" });
686
566
  const containerRef = useRef2(null);
687
- const { columns } = useWindowSize4();
567
+ const { columns } = useWindowSize3();
688
568
  const [width, setWidth] = useState3(columns);
689
569
  useLayoutEffect(() => {
690
570
  if (containerRef.current) {
@@ -729,53 +609,53 @@ function SelectPrompt({
729
609
  }
730
610
  }
731
611
  });
732
- return /* @__PURE__ */ jsx4(Box5, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", gap: 1, width, children: [
733
- error && /* @__PURE__ */ jsx4(Text5, { color: COLORS.danger, children: error }),
734
- messages?.map((m, i) => /* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, children: m }, `msg-${i}`)),
612
+ return /* @__PURE__ */ jsx4(Box4, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", gap: 1, width, children: [
613
+ error && /* @__PURE__ */ jsx4(Text4, { color: COLORS.danger, children: error }),
614
+ messages?.map((m, i) => /* @__PURE__ */ jsx4(Text4, { color: COLORS.muted, children: m }, `msg-${i}`)),
735
615
  table && /* @__PURE__ */ jsx4(Table, { columns: table.columns, rows: table.rows }),
736
- /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
737
- question && /* @__PURE__ */ jsx4(Text5, { color: COLORS.muted, children: question }),
738
- helpText && /* @__PURE__ */ jsx4(Text5, { color: COLORS.dim, children: helpText })
616
+ /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", children: [
617
+ question && /* @__PURE__ */ jsx4(Text4, { color: COLORS.muted, children: question }),
618
+ helpText && /* @__PURE__ */ jsx4(Text4, { color: COLORS.dim, children: helpText })
739
619
  ] }),
740
- /* @__PURE__ */ jsx4(Box5, { flexDirection: "column", children: rows.map((option, i) => {
620
+ /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: rows.map((option, i) => {
741
621
  const highlighted = i === index;
742
622
  const isCancel = i === cancelIndex;
743
623
  const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
744
624
  const sec = isCancel ? void 0 : secondary?.[i];
745
625
  const labelColor = highlighted ? COLORS.highlight.fg : void 0;
746
- const label = /* @__PURE__ */ jsxs4(Text5, { color: labelColor, wrap: "truncate", children: [
626
+ const label = /* @__PURE__ */ jsxs3(Text4, { color: labelColor, wrap: "truncate", children: [
747
627
  highlighted ? "\u276F " : " ",
748
628
  bullet,
749
629
  option
750
630
  ] });
751
631
  const isText = sec?.kind === "text";
752
- return /* @__PURE__ */ jsxs4(
753
- Box5,
632
+ return /* @__PURE__ */ jsxs3(
633
+ Box4,
754
634
  {
755
635
  width: isText ? "100%" : barWidth,
756
636
  paddingX: 1,
757
637
  paddingY: 1,
758
638
  backgroundColor: highlighted ? COLORS.highlight.bg : void 0,
759
639
  children: [
760
- /* @__PURE__ */ jsx4(Box5, { width: isText ? labelWidth : barLabelWidth, children: label }),
761
- isText && textWidth > 0 && /* @__PURE__ */ jsx4(Box5, { width: textWidth, children: /* @__PURE__ */ jsx4(
762
- Text5,
640
+ /* @__PURE__ */ jsx4(Box4, { width: isText ? labelWidth : barLabelWidth, children: label }),
641
+ isText && textWidth > 0 && /* @__PURE__ */ jsx4(Box4, { width: textWidth, children: /* @__PURE__ */ jsx4(
642
+ Text4,
763
643
  {
764
644
  wrap: "truncate",
765
645
  color: highlighted ? COLORS.primary : COLORS.muted,
766
646
  children: sec.value
767
647
  }
768
648
  ) }),
769
- sec?.kind === "badge" && /* @__PURE__ */ jsx4(Box5, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx4(Text5, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
649
+ sec?.kind === "badge" && /* @__PURE__ */ jsx4(Box4, { width: badgeWidth, justifyContent: "flex-end", children: /* @__PURE__ */ jsx4(Text4, { color: COLORS.badge, wrap: "truncate", children: sec.value }) })
770
650
  ]
771
651
  },
772
652
  `row-${i}`
773
653
  );
774
654
  }) }),
775
- /* @__PURE__ */ jsx4(Text5, { children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs4(Text5, { children: [
655
+ /* @__PURE__ */ jsx4(Text4, { children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs3(Text4, { children: [
776
656
  i > 0 ? " " : "",
777
- /* @__PURE__ */ jsx4(Text5, { color: COLORS.primary, children: key }),
778
- /* @__PURE__ */ jsxs4(Text5, { color: COLORS.dim, children: [
657
+ /* @__PURE__ */ jsx4(Text4, { color: COLORS.primary, children: key }),
658
+ /* @__PURE__ */ jsxs3(Text4, { color: COLORS.dim, children: [
779
659
  " ",
780
660
  label
781
661
  ] })
@@ -784,22 +664,22 @@ function SelectPrompt({
784
664
  }
785
665
 
786
666
  // src/ui/PromptInput.tsx
787
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
667
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
788
668
  var ACCEPT_REJECT_OPTIONS = ["Accept", "Reject"];
789
- function SpaceToContinuePrompt({
669
+ function EnterToContinuePrompt({
790
670
  question,
791
671
  messages,
792
672
  onDecide
793
673
  }) {
794
- useInput2((input, key) => {
795
- if (input === " ") onDecide(true);
674
+ useInput2((_input, key) => {
675
+ if (key.return) onDecide(true);
796
676
  else if (key.escape) onDecide(false);
797
677
  });
798
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", gap: 1, children: [
799
- messages?.map((m, i) => /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: m }, `msg-${i}`)),
800
- question && /* @__PURE__ */ jsx5(Text6, { color: COLORS.primary, children: question }),
801
- /* @__PURE__ */ jsxs5(Box6, { gap: 1, flexDirection: "column", children: [
802
- /* @__PURE__ */ jsx5(NextAction, { action: "continue", keyHint: "space" }),
678
+ return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", gap: 1, children: [
679
+ messages?.map((m, i) => /* @__PURE__ */ jsx5(Text5, { color: COLORS.muted, children: m }, `msg-${i}`)),
680
+ question && /* @__PURE__ */ jsx5(Text5, { color: COLORS.primary, children: question }),
681
+ /* @__PURE__ */ jsxs4(Box5, { gap: 1, flexDirection: "column", children: [
682
+ /* @__PURE__ */ jsx5(NextAction, { action: "continue", keyHint: "enter" }),
803
683
  /* @__PURE__ */ jsx5(NextAction, { action: "decline", keyHint: "esc", hierarchy: "secondary" })
804
684
  ] })
805
685
  ] });
@@ -808,11 +688,11 @@ function PromptInput() {
808
688
  const { phase, inputReq, submitInput } = useWizard();
809
689
  const [draft, setDraft] = useState4("");
810
690
  if (phase === "done" || phase === "error") {
811
- return /* @__PURE__ */ jsx5(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text6, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
691
+ return /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "gray", dimColor: true, children: "Press Enter or Esc to exit" }) });
812
692
  }
813
693
  if (phase !== "awaitingInput" || !inputReq) return null;
814
694
  if (inputReq.promptType === "multipleChoice") {
815
- return /* @__PURE__ */ jsx5(Box6, { children: /* @__PURE__ */ jsx5(
695
+ return /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(
816
696
  SelectPrompt,
817
697
  {
818
698
  question: inputReq.prompt,
@@ -829,7 +709,7 @@ function PromptInput() {
829
709
  ) });
830
710
  }
831
711
  if (inputReq.promptType === "multiSelect") {
832
- return /* @__PURE__ */ jsx5(Box6, { children: /* @__PURE__ */ jsx5(
712
+ return /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(
833
713
  SelectPrompt,
834
714
  {
835
715
  multi: true,
@@ -844,7 +724,7 @@ function PromptInput() {
844
724
  ) });
845
725
  }
846
726
  if (inputReq.promptType === "notice") {
847
- return /* @__PURE__ */ jsx5(Box6, { children: /* @__PURE__ */ jsx5(
727
+ return /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(
848
728
  SelectPrompt,
849
729
  {
850
730
  question: inputReq.prompt,
@@ -854,9 +734,9 @@ function PromptInput() {
854
734
  }
855
735
  ) });
856
736
  }
857
- if (inputReq.promptType === "spaceToContinue") {
737
+ if (inputReq.promptType === "enterToContinue") {
858
738
  return /* @__PURE__ */ jsx5(
859
- SpaceToContinuePrompt,
739
+ EnterToContinuePrompt,
860
740
  {
861
741
  question: inputReq.prompt,
862
742
  messages: inputReq.messages,
@@ -866,7 +746,7 @@ function PromptInput() {
866
746
  }
867
747
  if (inputReq.promptType === "acceptReject") {
868
748
  const labels = inputReq.options?.length ? inputReq.options : ACCEPT_REJECT_OPTIONS;
869
- return /* @__PURE__ */ jsx5(Box6, { children: /* @__PURE__ */ jsx5(
749
+ return /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(
870
750
  SelectPrompt,
871
751
  {
872
752
  question: inputReq.prompt,
@@ -877,11 +757,11 @@ function PromptInput() {
877
757
  }
878
758
  ) });
879
759
  }
880
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
881
- inputReq.error && /* @__PURE__ */ jsx5(Text6, { color: COLORS.danger, children: inputReq.error }),
882
- inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: m }, `msg-${i}`)),
883
- /* @__PURE__ */ jsxs5(Box6, { children: [
884
- /* @__PURE__ */ jsxs5(Text6, { color: COLORS.primary, children: [
760
+ return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
761
+ inputReq.error && /* @__PURE__ */ jsx5(Text5, { color: COLORS.danger, children: inputReq.error }),
762
+ inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx5(Text5, { color: COLORS.muted, children: m }, `msg-${i}`)),
763
+ /* @__PURE__ */ jsxs4(Box5, { children: [
764
+ /* @__PURE__ */ jsxs4(Text5, { color: COLORS.primary, children: [
885
765
  inputReq.prompt,
886
766
  " "
887
767
  ] }),
@@ -903,7 +783,7 @@ function PromptInput() {
903
783
  // src/ui/Welcome.tsx
904
784
  import { dirname as dirname2, join as join3 } from "node:path";
905
785
  import { fileURLToPath } from "node:url";
906
- import { Box as Box7, Spacer, Text as Text7, useInput as useInput3, useWindowSize as useWindowSize5 } from "ink";
786
+ import { Box as Box6, Spacer, Text as Text6, useInput as useInput3, useWindowSize as useWindowSize4 } from "ink";
907
787
 
908
788
  // src/ui/copy/welcome.ts
909
789
  var sidebarItems = [
@@ -931,29 +811,29 @@ var sidebarItems = [
931
811
 
932
812
  // src/ui/Welcome.tsx
933
813
  import Image, { InkPictureProvider } from "ink-picture";
934
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
814
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
935
815
  var IMAGE_PATH = join3(dirname2(fileURLToPath(import.meta.url)), "algolia.png");
936
816
  function SidebarItem({
937
817
  title,
938
818
  description
939
819
  }) {
940
- return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", children: [
941
- /* @__PURE__ */ jsxs6(Box7, { gap: 1, children: [
942
- /* @__PURE__ */ jsx6(Text7, { color: COLORS.success, children: "\u2192" }),
943
- /* @__PURE__ */ jsx6(Text7, { color: COLORS.strong, bold: true, children: title })
820
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
821
+ /* @__PURE__ */ jsxs5(Box6, { gap: 1, children: [
822
+ /* @__PURE__ */ jsx6(Text6, { color: COLORS.success, children: "\u2192" }),
823
+ /* @__PURE__ */ jsx6(Text6, { color: COLORS.strong, bold: true, children: title })
944
824
  ] }),
945
- /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 2, children: [
825
+ /* @__PURE__ */ jsxs5(Box6, { flexDirection: "row", gap: 2, children: [
946
826
  /* @__PURE__ */ jsx6(Spacer, {}),
947
- /* @__PURE__ */ jsx6(Text7, { color: COLORS.muted, children: description })
827
+ /* @__PURE__ */ jsx6(Text6, { color: COLORS.muted, children: description })
948
828
  ] })
949
829
  ] });
950
830
  }
951
831
  function Welcome() {
952
832
  const confirmStart = useWizard((s) => s.confirmStart);
953
833
  const openLearnMore = useWizard((s) => s.openLearnMore);
954
- const { rows } = useWindowSize5();
955
- useInput3((input) => {
956
- if (input === " ") confirmStart();
834
+ const { rows } = useWindowSize4();
835
+ useInput3((input, key) => {
836
+ if (key.return) confirmStart();
957
837
  else if (input === "i") openLearnMore();
958
838
  });
959
839
  const scales = {
@@ -970,15 +850,15 @@ function Welcome() {
970
850
  if (rows < 30) {
971
851
  layout = scales["small"];
972
852
  }
973
- return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
853
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
974
854
  /* @__PURE__ */ jsx6(
975
- Box7,
855
+ Box6,
976
856
  {
977
857
  paddingY: layout.main.padding.y,
978
858
  paddingX: layout.main.padding.x,
979
859
  flexDirection: "column",
980
860
  justifyContent: "center",
981
- children: /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", gap: 2, children: [
861
+ children: /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", gap: 2, children: [
982
862
  /* @__PURE__ */ jsx6(InkPictureProvider, { children: /* @__PURE__ */ jsx6(
983
863
  Image,
984
864
  {
@@ -990,16 +870,16 @@ function Welcome() {
990
870
  protocol: "halfBlock"
991
871
  }
992
872
  ) }),
993
- /* @__PURE__ */ jsx6(Text7, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
994
- /* @__PURE__ */ jsxs6(Box7, { gap: 1, flexDirection: "column", children: [
995
- /* @__PURE__ */ jsx6(NextAction, { action: "start wizard", keyHint: "space" }),
873
+ /* @__PURE__ */ jsx6(Text6, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
874
+ /* @__PURE__ */ jsxs5(Box6, { gap: 1, flexDirection: "column", children: [
875
+ /* @__PURE__ */ jsx6(NextAction, { action: "start wizard", keyHint: "enter" }),
996
876
  /* @__PURE__ */ jsx6(NextAction, { action: "learn more", keyHint: "i", hierarchy: "secondary" })
997
877
  ] })
998
878
  ] })
999
879
  }
1000
880
  ),
1001
- /* @__PURE__ */ jsxs6(
1002
- Box7,
881
+ /* @__PURE__ */ jsxs5(
882
+ Box6,
1003
883
  {
1004
884
  backgroundColor: COLORS.bg.sidebar,
1005
885
  width: 40,
@@ -1009,7 +889,7 @@ function Welcome() {
1009
889
  flexDirection: "column",
1010
890
  justifyContent: "center",
1011
891
  children: [
1012
- /* @__PURE__ */ jsx6(Text7, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
892
+ /* @__PURE__ */ jsx6(Text6, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
1013
893
  sidebarItems.map((i, idx) => /* @__PURE__ */ jsx6(SidebarItem, { title: i.title, description: i.description }, idx))
1014
894
  ]
1015
895
  }
@@ -1019,7 +899,7 @@ function Welcome() {
1019
899
 
1020
900
  // src/ui/LearnMore.tsx
1021
901
  import { Fragment as Fragment2 } from "react";
1022
- import { Box as Box8, Text as Text8, useInput as useInput4, useWindowSize as useWindowSize6 } from "ink";
902
+ import { Box as Box7, Text as Text7, useInput as useInput4, useWindowSize as useWindowSize5 } from "ink";
1023
903
 
1024
904
  // src/ui/copy/learn-more.ts
1025
905
  var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
@@ -1056,7 +936,7 @@ var policyLinks = [
1056
936
  ];
1057
937
 
1058
938
  // src/ui/LearnMore.tsx
1059
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
939
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1060
940
  var TAG_COLORS = {
1061
941
  READ: COLORS.success,
1062
942
  WRITE: COLORS.badge,
@@ -1072,25 +952,25 @@ function NeverLine({
1072
952
  }) {
1073
953
  const used = segments.reduce((n, s) => n + s.text.length, 0);
1074
954
  const rightPad = Math.max(0, width - 2 - NEVER_BOX_PAD_X - used);
1075
- return /* @__PURE__ */ jsxs7(Text8, { children: [
1076
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: "\u2502" }),
955
+ return /* @__PURE__ */ jsxs6(Text7, { children: [
956
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: "\u2502" }),
1077
957
  " ".repeat(NEVER_BOX_PAD_X),
1078
- segments.map((s, i) => /* @__PURE__ */ jsx7(Text8, { color: s.color, bold: s.bold, children: s.text }, i)),
958
+ segments.map((s, i) => /* @__PURE__ */ jsx7(Text7, { color: s.color, bold: s.bold, children: s.text }, i)),
1079
959
  " ".repeat(rightPad),
1080
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: "\u2502" })
960
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: "\u2502" })
1081
961
  ] });
1082
962
  }
1083
963
  function LearnMore() {
1084
964
  const confirmStart = useWizard((s) => s.confirmStart);
1085
965
  const backToHome = useWizard((s) => s.backToHome);
1086
- const { columns } = useWindowSize6();
966
+ const { columns } = useWindowSize5();
1087
967
  const dividerWidth = Math.max(0, columns - PADDING_X * 2);
1088
- useInput4((input, key) => {
968
+ useInput4((_input, key) => {
1089
969
  if (key.escape) backToHome();
1090
- else if (input === " ") confirmStart();
970
+ else if (key.return) confirmStart();
1091
971
  });
1092
- return /* @__PURE__ */ jsxs7(
1093
- Box8,
972
+ return /* @__PURE__ */ jsxs6(
973
+ Box7,
1094
974
  {
1095
975
  flexDirection: "column",
1096
976
  paddingX: PADDING_X,
@@ -1098,20 +978,20 @@ function LearnMore() {
1098
978
  width: "100%",
1099
979
  gap: 1,
1100
980
  children: [
1101
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
1102
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: accessIntro }),
1103
- /* @__PURE__ */ jsx7(Box8, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", marginTop: 1, children: [
1104
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
1105
- /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, marginTop: 1, children: [
1106
- /* @__PURE__ */ jsx7(Box8, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx7(Text8, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
1107
- /* @__PURE__ */ jsx7(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsxs7(Text8, { children: [
1108
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.strong, bold: true, children: item.title }),
1109
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
981
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
982
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: accessIntro }),
983
+ /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", marginTop: 1, children: [
984
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
985
+ /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, marginTop: 1, children: [
986
+ /* @__PURE__ */ jsx7(Box7, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx7(Text7, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
987
+ /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", children: /* @__PURE__ */ jsxs6(Text7, { children: [
988
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.strong, bold: true, children: item.title }),
989
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
1110
990
  ] }) })
1111
991
  ] })
1112
992
  ] }, item.tag)) }),
1113
- /* @__PURE__ */ jsxs7(Box8, { marginTop: 1, flexDirection: "column", children: [
1114
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
993
+ /* @__PURE__ */ jsxs6(Box7, { marginTop: 1, flexDirection: "column", children: [
994
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
1115
995
  /* @__PURE__ */ jsx7(NeverLine, { width: dividerWidth }),
1116
996
  /* @__PURE__ */ jsx7(
1117
997
  NeverLine,
@@ -1120,7 +1000,7 @@ function LearnMore() {
1120
1000
  segments: [{ text: "I NEVER", color: COLORS.danger, bold: true }]
1121
1001
  }
1122
1002
  ),
1123
- neverItems.map((item) => /* @__PURE__ */ jsxs7(Fragment2, { children: [
1003
+ neverItems.map((item) => /* @__PURE__ */ jsxs6(Fragment2, { children: [
1124
1004
  /* @__PURE__ */ jsx7(NeverLine, { width: dividerWidth }),
1125
1005
  /* @__PURE__ */ jsx7(
1126
1006
  NeverLine,
@@ -1135,23 +1015,23 @@ function LearnMore() {
1135
1015
  )
1136
1016
  ] }, item)),
1137
1017
  /* @__PURE__ */ jsx7(NeverLine, { width: dividerWidth }),
1138
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
1018
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
1139
1019
  ] }),
1140
- /* @__PURE__ */ jsx7(Box8, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
1141
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
1142
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.accent, children: link.url })
1020
+ /* @__PURE__ */ jsx7(Box7, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, children: [
1021
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
1022
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.accent, children: link.url })
1143
1023
  ] }, link.label)) }),
1144
- /* @__PURE__ */ jsxs7(Box8, { marginTop: 1, flexDirection: "row", gap: 3, children: [
1145
- /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
1146
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "[" }),
1147
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.primary, children: "esc" }),
1148
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "] back" })
1024
+ /* @__PURE__ */ jsxs6(Box7, { marginTop: 1, flexDirection: "row", gap: 3, children: [
1025
+ /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, children: [
1026
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "[" }),
1027
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.primary, children: "esc" }),
1028
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "] back" })
1149
1029
  ] }),
1150
- /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
1151
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "[" }),
1152
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.primary, children: "space" }),
1153
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.muted, children: "]" }),
1154
- /* @__PURE__ */ jsx7(Text8, { color: COLORS.success, bold: true, children: "start wizard" })
1030
+ /* @__PURE__ */ jsxs6(Box7, { flexDirection: "row", gap: 1, children: [
1031
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "[" }),
1032
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.primary, children: "enter" }),
1033
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.muted, children: "]" }),
1034
+ /* @__PURE__ */ jsx7(Text7, { color: COLORS.success, bold: true, children: "start wizard" })
1155
1035
  ] })
1156
1036
  ] })
1157
1037
  ]
@@ -1160,10 +1040,10 @@ function LearnMore() {
1160
1040
  }
1161
1041
 
1162
1042
  // src/ui/Sidebar.tsx
1163
- import { Box as Box11, Text as Text11 } from "ink";
1043
+ import { Box as Box10, Text as Text10 } from "ink";
1164
1044
 
1165
1045
  // src/ui/Steps.tsx
1166
- import { Box as Box9, Text as Text9 } from "ink";
1046
+ import { Box as Box8, Text as Text8 } from "ink";
1167
1047
  import Spinner from "ink-spinner";
1168
1048
 
1169
1049
  // src/core/persistence.ts
@@ -1192,11 +1072,11 @@ async function clearWorkflowState(workflowId) {
1192
1072
  }
1193
1073
 
1194
1074
  // src/ui/Steps.tsx
1195
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1075
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1196
1076
  function Steps() {
1197
1077
  const { steps } = useWizard();
1198
1078
  const visibleSteps = steps.filter(isStepVisible);
1199
- return /* @__PURE__ */ jsx8(Box9, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx8(Box9, { flexDirection: "column", children: /* @__PURE__ */ jsxs8(Text9, { color: COLORS.status[s.status], children: [
1079
+ return /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsxs7(Text8, { color: COLORS.status[s.status], children: [
1200
1080
  s.status === "running" ? /* @__PURE__ */ jsx8(Spinner, { type: "dots" }) : MARKER[s.status],
1201
1081
  " ",
1202
1082
  s.title
@@ -1206,7 +1086,7 @@ function CurrentStep() {
1206
1086
  const { steps } = useWizard();
1207
1087
  const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
1208
1088
  if (!currentStep) return null;
1209
- return /* @__PURE__ */ jsxs8(Text9, { color: COLORS.status.running, children: [
1089
+ return /* @__PURE__ */ jsxs7(Text8, { color: COLORS.status.running, children: [
1210
1090
  /* @__PURE__ */ jsx8(Spinner, { type: "dots" }),
1211
1091
  " ",
1212
1092
  ` ${currentStep.title}`
@@ -1214,19 +1094,19 @@ function CurrentStep() {
1214
1094
  }
1215
1095
 
1216
1096
  // src/ui/Progress.tsx
1217
- import { Box as Box10, Text as Text10 } from "ink";
1218
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1097
+ import { Box as Box9, Text as Text9 } from "ink";
1098
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1219
1099
  function Progress() {
1220
1100
  const { steps, currentStepIndex } = useWizard();
1221
1101
  const visibleSteps = steps.filter(isStepVisible);
1222
1102
  if (visibleSteps.length === 0) return null;
1223
1103
  const visibleCountThroughCurrent = steps.slice(0, currentStepIndex + 1).filter(isStepVisible).length;
1224
1104
  const activeStepNumber = Math.max(1, visibleCountThroughCurrent);
1225
- return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, children: [
1226
- /* @__PURE__ */ jsx9(Text10, { color: COLORS.muted, children: "STEP" }),
1227
- /* @__PURE__ */ jsx9(Text10, { bold: true, children: activeStepNumber }),
1228
- /* @__PURE__ */ jsx9(Text10, { bold: true, children: "/" }),
1229
- /* @__PURE__ */ jsx9(Text10, { bold: true, children: visibleSteps.length })
1105
+ return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", gap: 1, children: [
1106
+ /* @__PURE__ */ jsx9(Text9, { color: COLORS.muted, children: "STEP" }),
1107
+ /* @__PURE__ */ jsx9(Text9, { bold: true, children: activeStepNumber }),
1108
+ /* @__PURE__ */ jsx9(Text9, { bold: true, children: "/" }),
1109
+ /* @__PURE__ */ jsx9(Text9, { bold: true, children: visibleSteps.length })
1230
1110
  ] });
1231
1111
  }
1232
1112
 
@@ -1237,10 +1117,10 @@ var sidebarCommands = [
1237
1117
  ];
1238
1118
 
1239
1119
  // src/ui/Sidebar.tsx
1240
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1120
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1241
1121
  function Sidebar() {
1242
- return /* @__PURE__ */ jsxs10(
1243
- Box11,
1122
+ return /* @__PURE__ */ jsxs9(
1123
+ Box10,
1244
1124
  {
1245
1125
  backgroundColor: "#14171E",
1246
1126
  width: 30,
@@ -1249,16 +1129,16 @@ function Sidebar() {
1249
1129
  flexDirection: "column",
1250
1130
  justifyContent: "space-between",
1251
1131
  children: [
1252
- /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", gap: 1, children: [
1253
- /* @__PURE__ */ jsx10(Text11, { color: COLORS.muted, children: "PROGRESS" }),
1132
+ /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", gap: 1, children: [
1133
+ /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: "PROGRESS" }),
1254
1134
  /* @__PURE__ */ jsx10(Steps, {})
1255
1135
  ] }),
1256
- /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", gap: 1, children: [
1136
+ /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", gap: 1, children: [
1257
1137
  /* @__PURE__ */ jsx10(Progress, {}),
1258
- /* @__PURE__ */ jsx10(Box11, { flexDirection: "column", children: sidebarCommands.map((c) => {
1259
- return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, children: [
1260
- /* @__PURE__ */ jsx10(Text11, { color: COLORS.primary, children: `[${c.keyHint}]` }),
1261
- /* @__PURE__ */ jsx10(Text11, { color: COLORS.muted, children: c.description })
1138
+ /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", children: sidebarCommands.map((c) => {
1139
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "row", gap: 1, children: [
1140
+ /* @__PURE__ */ jsx10(Text10, { color: COLORS.primary, children: `[${c.keyHint}]` }),
1141
+ /* @__PURE__ */ jsx10(Text10, { color: COLORS.muted, children: c.description })
1262
1142
  ] });
1263
1143
  }) })
1264
1144
  ] })
@@ -1268,12 +1148,12 @@ function Sidebar() {
1268
1148
  }
1269
1149
 
1270
1150
  // src/ui/Ribbon.tsx
1271
- import { Box as Box12, Text as Text12 } from "ink";
1272
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1151
+ import { Box as Box11, Text as Text11 } from "ink";
1152
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1273
1153
  function Ribbon() {
1274
1154
  const firstCommand = sidebarCommands[0];
1275
- return /* @__PURE__ */ jsxs11(
1276
- Box12,
1155
+ return /* @__PURE__ */ jsxs10(
1156
+ Box11,
1277
1157
  {
1278
1158
  backgroundColor: "#14171E",
1279
1159
  flexDirection: "row",
@@ -1283,9 +1163,9 @@ function Ribbon() {
1283
1163
  children: [
1284
1164
  /* @__PURE__ */ jsx11(Progress, {}),
1285
1165
  /* @__PURE__ */ jsx11(CurrentStep, {}),
1286
- /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: 1, children: [
1287
- /* @__PURE__ */ jsx11(Text12, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
1288
- /* @__PURE__ */ jsx11(Text12, { color: COLORS.muted, children: firstCommand.description })
1166
+ /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", gap: 1, children: [
1167
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
1168
+ /* @__PURE__ */ jsx11(Text11, { color: COLORS.muted, children: firstCommand.description })
1289
1169
  ] })
1290
1170
  ]
1291
1171
  }
@@ -1297,8 +1177,8 @@ import { useState as useState6 } from "react";
1297
1177
 
1298
1178
  // src/ui/Logs.tsx
1299
1179
  import { useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState5 } from "react";
1300
- import { Box as Box13, Text as Text13, measureElement as measureElement3, useInput as useInput5, useWindowSize as useWindowSize7 } from "ink";
1301
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1180
+ import { Box as Box12, Text as Text12, measureElement as measureElement3, useInput as useInput5, useWindowSize as useWindowSize6 } from "ink";
1181
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1302
1182
  var KIND_COLOR = {
1303
1183
  tool: COLORS.primary,
1304
1184
  prompt: COLORS.badge
@@ -1328,7 +1208,7 @@ function formatTimestamp(ms) {
1328
1208
  }
1329
1209
  function Logs() {
1330
1210
  const logs = useWizard((s) => s.logs);
1331
- const { rows, columns } = useWindowSize7();
1211
+ const { rows, columns } = useWindowSize6();
1332
1212
  const viewportRef = useRef3(null);
1333
1213
  const [viewportHeight, setViewportHeight] = useState5(0);
1334
1214
  const [viewportWidth, setViewportWidth] = useState5(0);
@@ -1365,10 +1245,10 @@ function Logs() {
1365
1245
  const visible = logs.slice(scrollOffset, scrollOffset + capacity);
1366
1246
  const hiddenAbove = scrollOffset;
1367
1247
  const hiddenBelow = logs.length - scrollOffset - visible.length;
1368
- return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
1369
- logs.length === 0 && /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: "No logs yet." }),
1370
- /* @__PURE__ */ jsxs12(Box13, { ref: viewportRef, flexDirection: "column", flexGrow: 1, children: [
1371
- hiddenAbove > 0 && /* @__PURE__ */ jsxs12(Text13, { color: COLORS.dim, children: [
1248
+ return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
1249
+ logs.length === 0 && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: "No logs yet." }),
1250
+ /* @__PURE__ */ jsxs11(Box12, { ref: viewportRef, flexDirection: "column", flexGrow: 1, children: [
1251
+ hiddenAbove > 0 && /* @__PURE__ */ jsxs11(Text12, { color: COLORS.dim, children: [
1372
1252
  "\u2191 ",
1373
1253
  hiddenAbove,
1374
1254
  " more"
@@ -1383,20 +1263,20 @@ function Logs() {
1383
1263
  const name = truncate2(entry.name, budget);
1384
1264
  budget -= name.length;
1385
1265
  const preview = rawPreview ? truncate2(rawPreview, budget) : "";
1386
- return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "row", gap: ROW_GAP, children: [
1387
- /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: timestamp }),
1388
- /* @__PURE__ */ jsx12(Text13, { color: logNameColor(entry), wrap: "truncate", children: name }),
1389
- preview && /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, wrap: "truncate", children: preview }),
1390
- durationText && /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: durationText })
1266
+ return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: ROW_GAP, children: [
1267
+ /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: timestamp }),
1268
+ /* @__PURE__ */ jsx12(Text12, { color: logNameColor(entry), wrap: "truncate", children: name }),
1269
+ preview && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, wrap: "truncate", children: preview }),
1270
+ durationText && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: durationText })
1391
1271
  ] }, entry.id);
1392
1272
  }),
1393
- hiddenBelow > 0 && /* @__PURE__ */ jsxs12(Text13, { color: COLORS.dim, children: [
1273
+ hiddenBelow > 0 && /* @__PURE__ */ jsxs11(Text12, { color: COLORS.dim, children: [
1394
1274
  "\u2193 ",
1395
1275
  hiddenBelow,
1396
1276
  " more"
1397
1277
  ] })
1398
1278
  ] }),
1399
- /* @__PURE__ */ jsx12(Text13, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
1279
+ /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
1400
1280
  ] });
1401
1281
  }
1402
1282
 
@@ -1420,11 +1300,11 @@ function track(event, payload) {
1420
1300
  }
1421
1301
 
1422
1302
  // src/ui/App.tsx
1423
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1303
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1424
1304
  function App() {
1425
1305
  const { phase, error, homeScreen, currentStepIndex, steps, inputReq } = useWizard();
1426
1306
  const { exit } = useApp();
1427
- const { columns, rows } = useWindowSize8();
1307
+ const { columns, rows } = useWindowSize7();
1428
1308
  const [showLogs, setShowLogs] = useState6(false);
1429
1309
  const finished = phase === "done" || phase === "error";
1430
1310
  const currentStep = steps[currentStepIndex];
@@ -1437,8 +1317,7 @@ function App() {
1437
1317
  { isActive: finished }
1438
1318
  );
1439
1319
  useInput6((_input, key) => {
1440
- if (phase === "idle" || phase === "preflight" || phase === "authenticating")
1441
- return;
1320
+ if (phase === "idle" || phase === "preflight") return;
1442
1321
  if (key.tab) {
1443
1322
  setShowLogs(!showLogs);
1444
1323
  track("AI Wizard Interaction", {
@@ -1448,7 +1327,7 @@ function App() {
1448
1327
  });
1449
1328
  }
1450
1329
  });
1451
- const escOwnedElsewhere = phase === "idle" || phase === "authenticating" || phase === "awaitingInput" && inputReq?.promptType === "spaceToContinue";
1330
+ const escOwnedElsewhere = phase === "idle" || phase === "awaitingInput" && inputReq?.promptType === "enterToContinue";
1452
1331
  useInput6((_input, key) => {
1453
1332
  if (escOwnedElsewhere) return;
1454
1333
  if (key.escape) {
@@ -1461,19 +1340,19 @@ function App() {
1461
1340
  exit();
1462
1341
  }
1463
1342
  });
1464
- const mainWindowVisible = phase === "authenticating" || phase === "running" || phase === "awaitingInput" || phase === "error" || phase === "done";
1343
+ const mainWindowVisible = phase === "running" || phase === "awaitingInput" || phase === "error" || phase === "done";
1465
1344
  const flexDirection = columns > 90 ? "row" : "column";
1466
1345
  const showSidebar = flexDirection === "row";
1467
- return /* @__PURE__ */ jsxs13(
1468
- Box14,
1346
+ return /* @__PURE__ */ jsxs12(
1347
+ Box13,
1469
1348
  {
1470
1349
  backgroundColor: COLORS.bg.main,
1471
1350
  flexDirection: "row",
1472
1351
  width: columns,
1473
1352
  minHeight: rows,
1474
1353
  children: [
1475
- mainWindowVisible && /* @__PURE__ */ jsxs13(
1476
- Box14,
1354
+ mainWindowVisible && /* @__PURE__ */ jsxs12(
1355
+ Box13,
1477
1356
  {
1478
1357
  flexDirection,
1479
1358
  width: "100%",
@@ -1481,8 +1360,8 @@ function App() {
1481
1360
  children: [
1482
1361
  showLogs ? /* @__PURE__ */ jsx13(Logs, {}) : (
1483
1362
  /* Fill the width beside the sidebar; row layout only (would grow vertically when stacked). */
1484
- /* @__PURE__ */ jsxs13(
1485
- Box14,
1363
+ /* @__PURE__ */ jsxs12(
1364
+ Box13,
1486
1365
  {
1487
1366
  flexDirection: "column",
1488
1367
  paddingX: 4,
@@ -1490,15 +1369,10 @@ function App() {
1490
1369
  width: showSidebar ? 70 : "100%",
1491
1370
  flexGrow: showSidebar ? 1 : 0,
1492
1371
  children: [
1493
- phase === "authenticating" && /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", marginBottom: 1, children: [
1494
- /* @__PURE__ */ jsx13(Text14, { color: COLORS.strong, bold: true, children: "Signing in to Algolia" }),
1495
- /* @__PURE__ */ jsx13(Text14, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
1496
- ] }),
1497
- /* @__PURE__ */ jsx13(CliOutput, {}),
1498
1372
  /* @__PURE__ */ jsx13(Notices, {}),
1499
1373
  /* @__PURE__ */ jsx13(PromptInput, {}),
1500
- phase === "running" && showSidebar && /* @__PURE__ */ jsx13(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx13(CurrentStep, {}) }),
1501
- phase === "error" && error && /* @__PURE__ */ jsx13(Box14, { marginTop: 1, children: /* @__PURE__ */ jsxs13(Text14, { color: COLORS.status.error, children: [
1374
+ phase === "running" && showSidebar && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx13(CurrentStep, {}) }),
1375
+ phase === "error" && error && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: COLORS.status.error, children: [
1502
1376
  "\u2716 ",
1503
1377
  error
1504
1378
  ] }) })
@@ -1752,7 +1626,7 @@ async function ensureConsent() {
1752
1626
  const store2 = useWizard.getState();
1753
1627
  const answer = await store2.requestUserInput({
1754
1628
  prompt: "Wizard will make AI-authored changes to this repository.",
1755
- promptType: "spaceToContinue",
1629
+ promptType: "enterToContinue",
1756
1630
  options: []
1757
1631
  });
1758
1632
  if (answer !== true) {
@@ -1910,134 +1784,61 @@ async function runWorkflow(workflow2, appId) {
1910
1784
  }
1911
1785
  }
1912
1786
 
1913
- // src/lib/algoliaApp.ts
1914
- import { z as z3 } from "zod";
1915
- var currentSchema = z3.object({
1916
- id: z3.string().min(1),
1917
- name: z3.string().default(""),
1918
- plan: z3.string().optional()
1919
- });
1920
- var listSchema = z3.array(
1921
- z3.object({
1922
- id: z3.string().min(1),
1923
- name: z3.string().default(""),
1924
- plan_label: z3.string().optional()
1925
- }).transform(({ id, name, plan_label }) => ({ id, name, plan: plan_label }))
1926
- );
1927
- async function currentApplication() {
1928
- let raw;
1787
+ // src/lib/algoliaProfile.ts
1788
+ import { readFile as readFile3 } from "node:fs/promises";
1789
+ import { createRequire as createRequire2 } from "node:module";
1790
+ import { homedir as homedir2 } from "node:os";
1791
+ import { join as join6 } from "node:path";
1792
+ import { parse as parseToml } from "toml";
1793
+ var require3 = createRequire2(import.meta.url);
1794
+ function configPath() {
1795
+ const base = process.env.XDG_CONFIG_HOME || join6(homedir2(), ".config");
1796
+ return join6(base, "algolia", "config.toml");
1797
+ }
1798
+ function profilesFromConfig(tomlText) {
1799
+ let parsed;
1929
1800
  try {
1930
- raw = await runAlgoliaCli(["application", "current", "-o", "json"]);
1801
+ parsed = parseToml(tomlText);
1931
1802
  } catch {
1932
- return null;
1933
- }
1934
- const parsed = currentSchema.safeParse(parseJson(raw));
1935
- return parsed.success ? parsed.data : null;
1936
- }
1937
- async function requireApplication() {
1938
- const app2 = await currentApplication();
1939
- if (!app2) {
1940
- throw new Error(
1941
- "No Algolia application is selected. Run `npx @algolia/cli@latest application select` and restart the wizard."
1942
- );
1943
- }
1944
- return app2;
1945
- }
1946
- async function listApplications() {
1947
- const raw = await runAlgoliaCli(["application", "list", "-o", "json"]);
1948
- const parsed = listSchema.safeParse(parseJson(raw));
1949
- if (!parsed.success) {
1950
- throw new Error("Could not read the list of Algolia applications.");
1803
+ return [];
1951
1804
  }
1952
- return parsed.data;
1953
- }
1954
- function selectableApplications(apps) {
1955
- const nameCounts = /* @__PURE__ */ new Map();
1956
- for (const app2 of apps) {
1957
- const name = app2.name.trim();
1958
- if (name) nameCounts.set(name, (nameCounts.get(name) ?? 0) + 1);
1959
- }
1960
- return apps.filter((app2) => nameCounts.get(app2.name.trim()) === 1);
1961
- }
1962
- async function selectApplication(name) {
1963
- await runAlgoliaCli(["application", "select", "--app-name", name]);
1964
- }
1965
- function parseJson(text) {
1805
+ const profiles = Object.entries(parsed).filter(
1806
+ ([, t]) => typeof t.application_id === "string" && typeof t.api_key === "string"
1807
+ ).map(([name, t]) => ({
1808
+ name,
1809
+ appId: t.application_id,
1810
+ apiKey: t.api_key,
1811
+ isDefault: t.default === true
1812
+ }));
1813
+ profiles.sort((a, b) => Number(b.isDefault) - Number(a.isDefault));
1814
+ return profiles.map(({ name, appId, apiKey }) => ({ name, appId, apiKey }));
1815
+ }
1816
+ async function loadActiveProfile() {
1817
+ let profiles;
1966
1818
  try {
1967
- return JSON.parse(text);
1819
+ profiles = profilesFromConfig(await readFile3(configPath(), "utf8"));
1968
1820
  } catch {
1969
- return void 0;
1821
+ profiles = [];
1970
1822
  }
1971
- }
1972
-
1973
- // src/lib/algoliaAppPicker.ts
1974
- function secondaryFor(app2) {
1975
- return app2.plan ? { kind: "badge", value: app2.plan } : void 0;
1976
- }
1977
- async function promptForApplication() {
1978
- const store2 = useWizard.getState();
1979
- const phaseBefore = store2.phase;
1980
- const all = await listApplications();
1981
- const selectable = selectableApplications(all);
1982
- const skipped = all.length - selectable.length;
1983
- if (selectable.length === 0) {
1984
- const why = all.length === 0 ? "this account has no applications" : "none of this account\u2019s applications have a unique name";
1823
+ const profile2 = profiles[0];
1824
+ if (!profile2) {
1985
1825
  throw new Error(
1986
- `No selectable Algolia application was found: the CLI selects an application by name, and ${why}. Name one in the Algolia dashboard, or run \`npx @algolia/cli@latest application select\` directly.`
1987
- );
1988
- }
1989
- const messages = ["Which Algolia application should the wizard work in?"];
1990
- if (skipped > 0) {
1991
- messages.push(
1992
- `${skipped} application${skipped === 1 ? "" : "s"} not listed: the CLI selects by name, so unnamed and duplicate-named ones can\u2019t be chosen here.`
1826
+ "No Algolia profile is configured. Run `npx @algolia/cli auth login` to authenticate."
1993
1827
  );
1994
1828
  }
1995
- for (; ; ) {
1996
- const choice = await store2.requestUserInput({
1997
- prompt: "Select an application",
1998
- promptType: "multipleChoice",
1999
- options: selectable.map((app2) => `${app2.name} \u2014 ${app2.id}`),
2000
- secondary: selectable.map(secondaryFor),
2001
- messages
2002
- });
2003
- const index = selectable.findIndex(
2004
- (app2) => `${app2.name} \u2014 ${app2.id}` === choice
2005
- );
2006
- const chosen = selectable[index];
2007
- if (!chosen) {
2008
- throw new Error("Application picker received an unexpected selection");
2009
- }
2010
- try {
2011
- await selectApplication(chosen.name);
2012
- } catch (err) {
2013
- logger.warn(
2014
- { app: chosen.id, err: err.message },
2015
- "application select failed; re-prompting"
2016
- );
2017
- messages.push(
2018
- `Could not select \u201C${chosen.name}\u201D. It may have been renamed or removed \u2014 pick another.`
2019
- );
2020
- continue;
2021
- }
2022
- if (phaseBefore === "authenticating") store2.resumeAuth();
2023
- logger.info({ app: chosen.id }, "selected Algolia application");
2024
- return chosen;
2025
- }
2026
- }
2027
- async function ensureApplication() {
2028
- return await currentApplication() ?? await promptForApplication();
1829
+ return profile2;
2029
1830
  }
2030
1831
 
2031
1832
  // src/workflows/default.ts
2032
- import { z as z26 } from "zod";
1833
+ import { z as z25 } from "zod";
2033
1834
 
2034
1835
  // src/actions/listIndices.ts
2035
- import { z as z4 } from "zod";
2036
- var indicesListSchema = z4.object({
2037
- items: z4.array(
2038
- z4.object({
2039
- name: z4.string(),
2040
- entries: z4.number().default(0)
1836
+ import { z as z3 } from "zod";
1837
+ var indicesListSchema = z3.object({
1838
+ items: z3.array(
1839
+ z3.object({
1840
+ name: z3.string(),
1841
+ entries: z3.number().default(0)
2041
1842
  })
2042
1843
  )
2043
1844
  });
@@ -2108,12 +1909,12 @@ import "zod";
2108
1909
 
2109
1910
  // src/lib/tools/listFiles.ts
2110
1911
  import { tool } from "ai";
2111
- import z5 from "zod";
1912
+ import z4 from "zod";
2112
1913
  import { readdir } from "node:fs/promises";
2113
1914
 
2114
1915
  // src/lib/tools/path.ts
2115
1916
  import { lstat } from "node:fs/promises";
2116
- import { resolve as resolve2, relative, isAbsolute, dirname as dirname3, join as join6, sep } from "node:path";
1917
+ import { resolve as resolve2, relative, isAbsolute, dirname as dirname3, join as join7, sep } from "node:path";
2117
1918
  function resolveInRoot(ctx, path) {
2118
1919
  const target = resolve2(ctx.cwd, path);
2119
1920
  const rel = relative(ctx.root, target);
@@ -2129,7 +1930,7 @@ async function hasSymlinkParent(ctx, target) {
2129
1930
  let current = ctx.root;
2130
1931
  const parts = relative(ctx.root, dirname3(target)).split(sep).filter(Boolean);
2131
1932
  for (const part of parts) {
2132
- current = join6(current, part);
1933
+ current = join7(current, part);
2133
1934
  try {
2134
1935
  if ((await lstat(current)).isSymbolicLink()) return true;
2135
1936
  } catch (err) {
@@ -2144,7 +1945,7 @@ async function hasSymlinkParent(ctx, target) {
2144
1945
  function listFilesTool(ctx) {
2145
1946
  return tool({
2146
1947
  description: "List files in the current working directory",
2147
- inputSchema: z5.object(),
1948
+ inputSchema: z4.object(),
2148
1949
  execute: async () => {
2149
1950
  logger.info("called listFiles tool");
2150
1951
  if (++ctx.counts.list > ctx.limits.list) {
@@ -2160,13 +1961,13 @@ function listFilesTool(ctx) {
2160
1961
 
2161
1962
  // src/lib/tools/changeDirectory.ts
2162
1963
  import { tool as tool2 } from "ai";
2163
- import z6 from "zod";
1964
+ import z5 from "zod";
2164
1965
  import { stat } from "node:fs/promises";
2165
1966
  function changeDirectoryTool(ctx) {
2166
1967
  return tool2({
2167
1968
  description: "Change the current working directory. Subsequent file operations resolve relative to it. Returns the new working directory.",
2168
- inputSchema: z6.object({
2169
- path: z6.string().describe("Directory to change into")
1969
+ inputSchema: z5.object({
1970
+ path: z5.string().describe("Directory to change into")
2170
1971
  }),
2171
1972
  execute: async ({ path }) => {
2172
1973
  logger.info({ path }, "called changeDirectory tool");
@@ -2188,13 +1989,13 @@ function changeDirectoryTool(ctx) {
2188
1989
 
2189
1990
  // src/lib/tools/reportStatus.ts
2190
1991
  import { tool as tool3 } from "ai";
2191
- import z7 from "zod";
1992
+ import z6 from "zod";
2192
1993
  function reportStatusTool(output) {
2193
1994
  return tool3({
2194
1995
  description: "Report the status of your execution. Return a reason in case of failure.",
2195
- inputSchema: z7.object({
2196
- status: z7.enum(["success", "fail"]),
2197
- reason: z7.string().optional(),
1996
+ inputSchema: z6.object({
1997
+ status: z6.enum(["success", "fail"]),
1998
+ reason: z6.string().optional(),
2198
1999
  output
2199
2000
  }),
2200
2001
  execute: async ({ status, reason, output: output2 }) => {
@@ -2206,8 +2007,8 @@ function reportStatusTool(output) {
2206
2007
 
2207
2008
  // src/lib/tools/readFile.ts
2208
2009
  import { tool as tool4 } from "ai";
2209
- import z8 from "zod";
2210
- import { readFile as readFile3 } from "node:fs/promises";
2010
+ import z7 from "zod";
2011
+ import { readFile as readFile4 } from "node:fs/promises";
2211
2012
 
2212
2013
  // src/lib/tools/env.ts
2213
2014
  import { basename } from "node:path";
@@ -2234,8 +2035,8 @@ function redactEnvValues(content) {
2234
2035
  function readFileTool(ctx) {
2235
2036
  return tool4({
2236
2037
  description: "Read the contents of a file at the given path",
2237
- inputSchema: z8.object({
2238
- filePath: z8.string().describe("Path to the file to read")
2038
+ inputSchema: z7.object({
2039
+ filePath: z7.string().describe("Path to the file to read")
2239
2040
  }),
2240
2041
  execute: async ({ filePath }) => {
2241
2042
  if (++ctx.counts.read > ctx.limits.read) {
@@ -2245,7 +2046,7 @@ function readFileTool(ctx) {
2245
2046
  const resolved = resolveInRoot(ctx, filePath);
2246
2047
  if (!resolved.ok) return resolved.error;
2247
2048
  try {
2248
- const content = await readFile3(resolved.target, "utf8");
2049
+ const content = await readFile4(resolved.target, "utf8");
2249
2050
  return isEnvFile(resolved.target) ? redactEnvValues(content) : content;
2250
2051
  } catch (err) {
2251
2052
  return `Error reading ${filePath}: ${err.message}`;
@@ -2256,15 +2057,15 @@ function readFileTool(ctx) {
2256
2057
 
2257
2058
  // src/lib/tools/writeFile.ts
2258
2059
  import { tool as tool5 } from "ai";
2259
- import z9 from "zod";
2060
+ import z8 from "zod";
2260
2061
  import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
2261
2062
  import { dirname as dirname4 } from "node:path";
2262
2063
  function writeFileTool(ctx) {
2263
2064
  return tool5({
2264
2065
  description: "Write content to a file at the given path, overwriting it. To set Algolia credentials in an env file, use writeCredentials instead of this tool.",
2265
- inputSchema: z9.object({
2266
- filePath: z9.string().describe("Path to the file to write"),
2267
- content: z9.string().describe("Content to write to the file")
2066
+ inputSchema: z8.object({
2067
+ filePath: z8.string().describe("Path to the file to write"),
2068
+ content: z8.string().describe("Content to write to the file")
2268
2069
  }),
2269
2070
  execute: async ({ filePath, content }) => {
2270
2071
  logger.info({ filePath }, "called writeFile tool");
@@ -2289,95 +2090,9 @@ function writeFileTool(ctx) {
2289
2090
 
2290
2091
  // src/lib/tools/writeAlgoliaCredentials.ts
2291
2092
  import { tool as tool6 } from "ai";
2292
- import z11 from "zod";
2293
- import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
2093
+ import z9 from "zod";
2094
+ import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
2294
2095
  import { dirname as dirname5 } from "node:path";
2295
-
2296
- // src/lib/algoliaApiKey.ts
2297
- import { z as z10 } from "zod";
2298
- var SAFE_ACLS = /* @__PURE__ */ new Set(["search", "browse", "listIndexes"]);
2299
- var WRITE_ACLS = [
2300
- "addObject",
2301
- "deleteObject",
2302
- "settings",
2303
- "editSettings",
2304
- "listIndexes"
2305
- ];
2306
- var WRITE_ACL_SET = new Set(WRITE_ACLS);
2307
- var apiKeySchema = z10.object({
2308
- value: z10.string().min(1),
2309
- acl: z10.array(z10.string()).default([]),
2310
- indexes: z10.array(z10.string()).default([])
2311
- });
2312
- var apiKeyListSchema = z10.object({
2313
- items: z10.array(apiKeySchema).optional(),
2314
- keys: z10.array(apiKeySchema).optional()
2315
- }).transform((o) => o.items ?? o.keys ?? []);
2316
- var createdKeySchema = z10.object({
2317
- key: z10.string().min(1).optional(),
2318
- value: z10.string().min(1).optional()
2319
- });
2320
- function canReuse(key, index) {
2321
- return key.acl.includes("search") && key.acl.every((acl) => SAFE_ACLS.has(acl)) && (key.indexes.length === 0 || key.indexes.includes("*") || key.indexes.includes(index));
2322
- }
2323
- async function createSearchKey(index) {
2324
- const stdout = await runAlgoliaCli([
2325
- "apikeys",
2326
- "create",
2327
- "--indices",
2328
- index,
2329
- "--acl",
2330
- "search,browse",
2331
- "--description",
2332
- `wizard search-only key for ${index}`,
2333
- "-o",
2334
- "json"
2335
- ]);
2336
- const { key, value } = createdKeySchema.parse(JSON.parse(stdout));
2337
- const created = key ?? value;
2338
- if (!created) throw new Error("apikeys create returned no key value");
2339
- return created;
2340
- }
2341
- function canReuseForWrites(key, index) {
2342
- return WRITE_ACLS.every((acl) => key.acl.includes(acl)) && key.acl.every((acl) => WRITE_ACL_SET.has(acl)) && key.indexes.includes(index);
2343
- }
2344
- async function resolveWriteKey(index) {
2345
- const stdout = await runAlgoliaCli(["apikeys", "list", "-o", "json"]);
2346
- const existing = apiKeyListSchema.parse(JSON.parse(stdout)).find((key2) => canReuseForWrites(key2, index))?.value;
2347
- if (existing) {
2348
- logger.info({ index }, "reusing existing write API key");
2349
- return existing;
2350
- }
2351
- logger.info({ index }, "no reusable write key found; creating one");
2352
- const created = await runAlgoliaCli([
2353
- "apikeys",
2354
- "create",
2355
- "--indices",
2356
- index,
2357
- "--acl",
2358
- WRITE_ACLS.join(","),
2359
- "--description",
2360
- `wizard write key for ${index}`,
2361
- "-o",
2362
- "json"
2363
- ]);
2364
- const { key, value } = createdKeySchema.parse(JSON.parse(created));
2365
- const writeKey = key ?? value;
2366
- if (!writeKey) throw new Error("apikeys create returned no key value");
2367
- return writeKey;
2368
- }
2369
- async function resolveSearchOnlyKey(index) {
2370
- const stdout = await runAlgoliaCli(["apikeys", "list", "-o", "json"]);
2371
- const existing = apiKeyListSchema.parse(JSON.parse(stdout)).find((key) => canReuse(key, index))?.value;
2372
- if (existing) {
2373
- logger.info({ index }, "reusing existing search-only API key");
2374
- return existing;
2375
- }
2376
- logger.info({ index }, "no reusable search-only key found; creating one");
2377
- return createSearchKey(index);
2378
- }
2379
-
2380
- // src/lib/tools/writeAlgoliaCredentials.ts
2381
2096
  var APP_ID_VAR = "ALGOLIA_APPLICATION_ID";
2382
2097
  var API_KEY_VAR = "ALGOLIA_WRITE_API_KEY";
2383
2098
  function appendEnv(content, entries) {
@@ -2391,9 +2106,9 @@ function hasEnv(content, name) {
2391
2106
  }
2392
2107
  function writeCredentialsTool(ctx) {
2393
2108
  return tool6({
2394
- description: `Write the active Algolia credentials (${APP_ID_VAR} and ${API_KEY_VAR}) into the given env file. The credentials come from the selected Algolia application, with a write key scoped to the target index; you only pass the path to the env file (e.g. ".env"). If the file already defines ${APP_ID_VAR} or ${API_KEY_VAR}, the write is skipped and existing values are left untouched.`,
2395
- inputSchema: z11.object({
2396
- filePath: z11.string().describe(
2109
+ description: `Write the active Algolia credentials (${APP_ID_VAR} and ${API_KEY_VAR}) into the given env file. The credentials are read from the local Algolia CLI profile; you only pass the path to the env file (e.g. ".env"). If the file already defines ${APP_ID_VAR} or ${API_KEY_VAR}, the write is skipped and existing values are left untouched.`,
2110
+ inputSchema: z9.object({
2111
+ filePath: z9.string().describe(
2397
2112
  'Path to the env file to write credentials into (e.g. ".env")'
2398
2113
  )
2399
2114
  }),
@@ -2401,17 +2116,11 @@ function writeCredentialsTool(ctx) {
2401
2116
  logger.info({ filePath }, "called writeCredentials tool");
2402
2117
  const resolved = resolveInRoot(ctx, filePath);
2403
2118
  if (resolved.ok === false) return resolved.error;
2404
- const targetIndex = useWizard.getState().targetIndex;
2405
- if (!targetIndex) {
2406
- return "Error: no target index is set for this run, so a scoped write key cannot be provisioned.";
2407
- }
2408
- let appId;
2409
- let writeKey;
2119
+ let profile2;
2410
2120
  try {
2411
- appId = (await requireApplication()).id;
2412
- writeKey = await resolveWriteKey(targetIndex);
2413
- } catch (err) {
2414
- return `Error: could not resolve Algolia credentials (${err.message}). Ask the user to authenticate with the Algolia CLI first.`;
2121
+ profile2 = await loadActiveProfile();
2122
+ } catch {
2123
+ return "Error: no Algolia profile is configured, so credentials cannot be written. Ask the user to authenticate with the Algolia CLI first.";
2415
2124
  }
2416
2125
  try {
2417
2126
  if (await hasSymlinkParent(ctx, resolved.target)) {
@@ -2419,7 +2128,7 @@ function writeCredentialsTool(ctx) {
2419
2128
  }
2420
2129
  let existing = "";
2421
2130
  try {
2422
- existing = await readFile4(resolved.target, "utf8");
2131
+ existing = await readFile5(resolved.target, "utf8");
2423
2132
  } catch (err) {
2424
2133
  if (err.code !== "ENOENT") throw err;
2425
2134
  }
@@ -2430,8 +2139,8 @@ function writeCredentialsTool(ctx) {
2430
2139
  return `Skipped: ${filePath} already defines ${present.join(" and ")}. Leaving existing credentials untouched.`;
2431
2140
  }
2432
2141
  const envWithCredentials = appendEnv(existing, [
2433
- [APP_ID_VAR, appId],
2434
- [API_KEY_VAR, writeKey]
2142
+ [APP_ID_VAR, profile2.appId],
2143
+ [API_KEY_VAR, profile2.apiKey]
2435
2144
  ]);
2436
2145
  await mkdir4(dirname5(resolved.target), { recursive: true });
2437
2146
  await writeFile4(resolved.target, envWithCredentials, "utf8");
@@ -2445,16 +2154,16 @@ function writeCredentialsTool(ctx) {
2445
2154
 
2446
2155
  // src/lib/tools/searchFiles.ts
2447
2156
  import { tool as tool7 } from "ai";
2448
- import z12 from "zod";
2449
- import { readdir as readdir2, readFile as readFile5 } from "node:fs/promises";
2450
- import { join as join7 } from "node:path";
2157
+ import z10 from "zod";
2158
+ import { readdir as readdir2, readFile as readFile6 } from "node:fs/promises";
2159
+ import { join as join8 } from "node:path";
2451
2160
  var MAX_QUERY_LENGTH = 1e3;
2452
2161
  async function walkFiles(dir) {
2453
2162
  const skip = /* @__PURE__ */ new Set(["node_modules", ".git", "dist"]);
2454
2163
  const out = [];
2455
2164
  for (const e of await readdir2(dir, { withFileTypes: true })) {
2456
2165
  if (e.name.startsWith(".") || skip.has(e.name)) continue;
2457
- const full = join7(dir, e.name);
2166
+ const full = join8(dir, e.name);
2458
2167
  if (e.isDirectory()) out.push(...await walkFiles(full));
2459
2168
  else if (e.isFile()) out.push(full);
2460
2169
  }
@@ -2463,9 +2172,9 @@ async function walkFiles(dir) {
2463
2172
  function searchFilesTool(ctx) {
2464
2173
  return tool7({
2465
2174
  description: "Search file contents for a JavaScript regular expression (RegExp syntax, not grep/PCRE). Returns matching lines as file:line:text.",
2466
- inputSchema: z12.object({
2467
- query: z12.string().describe("JavaScript RegExp pattern to search for"),
2468
- path: z12.string().optional().describe("Directory to search in (default: cwd)")
2175
+ inputSchema: z10.object({
2176
+ query: z10.string().describe("JavaScript RegExp pattern to search for"),
2177
+ path: z10.string().optional().describe("Directory to search in (default: cwd)")
2469
2178
  }),
2470
2179
  execute: async ({ query, path = "." }) => {
2471
2180
  logger.info({ query, path }, "called searchFiles tool");
@@ -2487,7 +2196,7 @@ function searchFilesTool(ctx) {
2487
2196
  for (const file of await walkFiles(resolved.target)) {
2488
2197
  let content;
2489
2198
  try {
2490
- content = await readFile5(file, "utf8");
2199
+ content = await readFile6(file, "utf8");
2491
2200
  } catch {
2492
2201
  continue;
2493
2202
  }
@@ -2509,7 +2218,7 @@ function searchFilesTool(ctx) {
2509
2218
 
2510
2219
  // src/lib/tools/verifyImplementation.ts
2511
2220
  import { tool as tool8 } from "ai";
2512
- import z13 from "zod";
2221
+ import z11 from "zod";
2513
2222
 
2514
2223
  // src/lib/tools/utils/runCommand.ts
2515
2224
  import { spawn as spawn2 } from "node:child_process";
@@ -2531,9 +2240,9 @@ function runCommand(command, args, cwd) {
2531
2240
  }
2532
2241
 
2533
2242
  // src/lib/tools/utils/packageManager.ts
2534
- import { readFile as readFile6 } from "node:fs/promises";
2243
+ import { readFile as readFile7 } from "node:fs/promises";
2535
2244
  import { existsSync } from "node:fs";
2536
- import { join as join8 } from "node:path";
2245
+ import { join as join9 } from "node:path";
2537
2246
  var LOCKFILES = [
2538
2247
  ["pnpm-lock.yaml", "pnpm"],
2539
2248
  ["yarn.lock", "yarn"],
@@ -2542,13 +2251,13 @@ var LOCKFILES = [
2542
2251
  ["package-lock.json", "npm"]
2543
2252
  ];
2544
2253
  async function readPackageJson(cwd = process.cwd()) {
2545
- return JSON.parse(await readFile6(join8(cwd, "package.json"), "utf8"));
2254
+ return JSON.parse(await readFile7(join9(cwd, "package.json"), "utf8"));
2546
2255
  }
2547
2256
  function packageManagerFrom(pkg) {
2548
2257
  return pkg.packageManager?.split("@")[0] ?? "npm";
2549
2258
  }
2550
2259
  function packageManagerFromLockfile(cwd) {
2551
- return LOCKFILES.find(([file]) => existsSync(join8(cwd, file)))?.[1];
2260
+ return LOCKFILES.find(([file]) => existsSync(join9(cwd, file)))?.[1];
2552
2261
  }
2553
2262
  async function detectPackageManager(cwd) {
2554
2263
  try {
@@ -2589,7 +2298,7 @@ async function runRepoVerificationCheck() {
2589
2298
  function verifyImplementationTool() {
2590
2299
  return tool8({
2591
2300
  description: "Run the repo's mechanical verification check for generated implementation changes. Detects lint/typecheck/check from package.json and returns structured pass/fail evidence for the verifier to interpret.",
2592
- inputSchema: z13.object(),
2301
+ inputSchema: z11.object(),
2593
2302
  execute: async () => {
2594
2303
  logger.info("called verifyImplementation tool");
2595
2304
  return runRepoVerificationCheck();
@@ -2603,7 +2312,7 @@ import { createAnthropic } from "@ai-sdk/anthropic";
2603
2312
  import { nanoid as nanoid2 } from "nanoid";
2604
2313
  import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
2605
2314
  import { dirname as dirname6 } from "node:path";
2606
- import z14 from "zod";
2315
+ import z12 from "zod";
2607
2316
  var DATA_DIR = ".algolia-wizard/data";
2608
2317
  var RECORD_MODEL = "claude-haiku-4-5";
2609
2318
  var MAX_RECORDS = 100;
@@ -2615,17 +2324,17 @@ var anthropic = createAnthropic({
2615
2324
  function generateRecordTool(ctx) {
2616
2325
  return tool9({
2617
2326
  description: "Generate realistic sample records for an entity and write them to a JSON file in the worktree. Provide the entity name and its attributes; this tool asks a model to invent varied, realistic values, each with a unique objectID, and returns the file path to read them from at runtime. Do not invent the record values or objectIDs yourself, and do not inline the returned records into the script \u2014 call this tool and read the file it writes.",
2618
- inputSchema: z14.object({
2619
- entityName: z14.string().describe("Name of the entity to generate records for."),
2620
- attributes: z14.array(z14.string()).describe("Attribute names each record must contain."),
2621
- count: z14.number().int().min(1).max(MAX_RECORDS).default(10).describe(`How many records to generate (max ${MAX_RECORDS}).`),
2622
- hint: z14.string().optional().describe("Optional context to steer realistic values.")
2327
+ inputSchema: z12.object({
2328
+ entityName: z12.string().describe("Name of the entity to generate records for."),
2329
+ attributes: z12.array(z12.string()).describe("Attribute names each record must contain."),
2330
+ count: z12.number().int().min(1).max(MAX_RECORDS).default(10).describe(`How many records to generate (max ${MAX_RECORDS}).`),
2331
+ hint: z12.string().optional().describe("Optional context to steer realistic values.")
2623
2332
  }),
2624
2333
  execute: async ({ entityName, attributes, count, hint }) => {
2625
2334
  logger.info({ entityName, count }, "called generateRecord tool");
2626
2335
  try {
2627
- const value = z14.union([z14.string(), z14.number(), z14.boolean(), z14.null()]);
2628
- const recordSchema = z14.object(
2336
+ const value = z12.union([z12.string(), z12.number(), z12.boolean(), z12.null()]);
2337
+ const recordSchema = z12.object(
2629
2338
  Object.fromEntries(attributes.map((attr) => [attr, value]))
2630
2339
  );
2631
2340
  const generateBatch = async (batchCount) => {
@@ -2635,8 +2344,8 @@ function generateRecordTool(ctx) {
2635
2344
  const { output } = await generateText({
2636
2345
  model: anthropic(RECORD_MODEL),
2637
2346
  output: Output.object({
2638
- schema: z14.object({
2639
- records: z14.array(recordSchema).length(batchCount)
2347
+ schema: z12.object({
2348
+ records: z12.array(recordSchema).length(batchCount)
2640
2349
  })
2641
2350
  }),
2642
2351
  prompt: [
@@ -2694,12 +2403,12 @@ function generateRecordTool(ctx) {
2694
2403
 
2695
2404
  // src/lib/tools/notifyUser.ts
2696
2405
  import { tool as tool10 } from "ai";
2697
- import z15 from "zod";
2406
+ import z13 from "zod";
2698
2407
  function notifyUserTool() {
2699
2408
  return tool10({
2700
2409
  description: `Give the user a brief, high-level update on what you are currently doing or about to do next. This is for the big picture (e.g. "Reading through your data models", "Writing the search UI") \u2014 not granular detail like individual tool calls, which are already logged separately. Call it when you start a new phase of work or your focus shifts, just not on every step, enough to keep the user engaged. Don't say things like "starting", just describe what you are doing. Don't mention tool calls themselves, just general direction of the work.`,
2701
- inputSchema: z15.object({
2702
- message: z15.string().describe(
2410
+ inputSchema: z13.object({
2411
+ message: z13.string().describe(
2703
2412
  "Short, plain-language description of what you are doing now."
2704
2413
  )
2705
2414
  }),
@@ -2879,10 +2588,10 @@ async function runAgent(req) {
2879
2588
  }
2880
2589
 
2881
2590
  // src/actions/detectLanguage.ts
2882
- import z18 from "zod";
2883
- var detectLanguageSchema = z18.object({
2884
- languages: z18.array(z18.object({ name: z18.string(), version: z18.string() })),
2885
- frameworks: z18.array(z18.object({ name: z18.string(), version: z18.string() }))
2591
+ import z16 from "zod";
2592
+ var detectLanguageSchema = z16.object({
2593
+ languages: z16.array(z16.object({ name: z16.string(), version: z16.string() })),
2594
+ frameworks: z16.array(z16.object({ name: z16.string(), version: z16.string() }))
2886
2595
  });
2887
2596
  var detectLanguage = () => runAgent({
2888
2597
  instructions: [
@@ -2900,31 +2609,31 @@ var detectLanguage = () => runAgent({
2900
2609
  });
2901
2610
 
2902
2611
  // src/actions/analyzeCodebase.ts
2903
- import z19 from "zod";
2612
+ import z17 from "zod";
2904
2613
  var READONLY_TOOLS = [
2905
2614
  "listFiles",
2906
2615
  "changeDirectory",
2907
2616
  "readFile",
2908
2617
  "searchFiles"
2909
2618
  ];
2910
- var ingestionAnalysisSchema = z19.object({
2911
- ingestionAnalysis: z19.array(
2912
- z19.object({
2913
- name: z19.string(),
2914
- paths: z19.array(z19.string()),
2619
+ var ingestionAnalysisSchema = z17.object({
2620
+ ingestionAnalysis: z17.array(
2621
+ z17.object({
2622
+ name: z17.string(),
2623
+ paths: z17.array(z17.string()),
2915
2624
  // indexable fields the agent found for this entity
2916
- attributes: z19.array(z19.string())
2625
+ attributes: z17.array(z17.string())
2917
2626
  })
2918
2627
  )
2919
2628
  });
2920
- var searchImplementationAnalysisSchema = z19.object({
2921
- searchImplementationAnalysis: z19.string()
2629
+ var searchImplementationAnalysisSchema = z17.object({
2630
+ searchImplementationAnalysis: z17.string()
2922
2631
  });
2923
- var verificationSchema = z19.object({
2924
- verification: z19.array(z19.string())
2632
+ var verificationSchema = z17.object({
2633
+ verification: z17.array(z17.string())
2925
2634
  });
2926
2635
  var confirmedEntitiesFieldSchema = ingestionAnalysisSchema.shape.ingestionAnalysis.optional();
2927
- var analyzeCodebaseSchema = z19.object({
2636
+ var analyzeCodebaseSchema = z17.object({
2928
2637
  ingestionAnalysis: ingestionAnalysisSchema.shape.ingestionAnalysis.optional(),
2929
2638
  searchImplementationAnalysis: searchImplementationAnalysisSchema.shape.searchImplementationAnalysis.optional(),
2930
2639
  verification: verificationSchema.shape.verification.optional(),
@@ -2986,7 +2695,7 @@ async function runAnalysis(mode, extraInstructions = []) {
2986
2695
  // package.json
2987
2696
  var package_default = {
2988
2697
  name: "@algolia/wizard",
2989
- version: "0.6.0-rc.53.32",
2698
+ version: "0.6.0-rc.55.31",
2990
2699
  description: "Magically implement Algolia functionality in your codebase",
2991
2700
  type: "module",
2992
2701
  engines: {
@@ -3034,6 +2743,7 @@ var package_default = {
3034
2743
  dependencies: {
3035
2744
  "@ai-sdk/anthropic": "^3.0.81",
3036
2745
  "@ai-sdk/openai-compatible": "^2.0.47",
2746
+ "@algolia/cli": "^5.11.0",
3037
2747
  "@hono/node-server": "^2.0.10",
3038
2748
  "@mishieck/ink-titled-box": "^0.4.2",
3039
2749
  "@segment/analytics-node": "^3.1.0",
@@ -3048,6 +2758,7 @@ var package_default = {
3048
2758
  nanoid: "^5.1.15",
3049
2759
  pino: "^10.3.1",
3050
2760
  react: "^19.2.7",
2761
+ toml: "^4.1.1",
3051
2762
  varlock: "^1.5.1",
3052
2763
  zod: "^4.4.3",
3053
2764
  zustand: "^5.0.14"
@@ -3105,8 +2816,8 @@ async function askList(ctx, prompt, { required = false } = {}) {
3105
2816
  }
3106
2817
 
3107
2818
  // src/actions/confirmLanguage.ts
3108
- import z21 from "zod";
3109
- var confirmLanguageSchema = z21.object({
2819
+ import z19 from "zod";
2820
+ var confirmLanguageSchema = z19.object({
3110
2821
  languages: detectLanguageSchema.shape.languages
3111
2822
  });
3112
2823
  async function confirmLanguage(ctx) {
@@ -3127,8 +2838,8 @@ async function confirmLanguage(ctx) {
3127
2838
  }
3128
2839
 
3129
2840
  // src/actions/confirmFramework.ts
3130
- import z22 from "zod";
3131
- var confirmFrameworkSchema = z22.object({
2841
+ import z20 from "zod";
2842
+ var confirmFrameworkSchema = z20.object({
3132
2843
  frameworks: detectLanguageSchema.shape.frameworks
3133
2844
  });
3134
2845
  var CURATED_FRAMEWORKS = [
@@ -3256,8 +2967,8 @@ async function promptUser(ctx, params) {
3256
2967
  }
3257
2968
 
3258
2969
  // src/actions/confirmEntities.ts
3259
- import z23 from "zod";
3260
- var confirmEntitiesSchema = z23.object({
2970
+ import z21 from "zod";
2971
+ var confirmEntitiesSchema = z21.object({
3261
2972
  // Final detection — the focused re-run may supersede project-scan's.
3262
2973
  ingestionAnalysis: ingestionAnalysisSchema.shape.ingestionAnalysis.optional(),
3263
2974
  confirmedEntities: confirmedEntitiesFieldSchema
@@ -3327,15 +3038,15 @@ async function confirmEntities(ctx) {
3327
3038
  }
3328
3039
 
3329
3040
  // src/actions/review.ts
3330
- import { z as z24 } from "zod";
3331
- var reviewSchema = z24.object({
3041
+ import { z as z22 } from "zod";
3042
+ var reviewSchema = z22.object({
3332
3043
  // Broad, high-level takeaways grouped by theme (e.g. ingestion, search UI),
3333
3044
  // not one entry per workflow step — a step's raw output can be a long,
3334
3045
  // multi-paragraph blob (see implement.ts's summaries.join), and mirroring
3335
3046
  // that 1:1 is what made the old per-step summary an unreadable wall of text.
3336
- summaryPoints: z24.array(z24.string()),
3337
- reviewPrompt: z24.string(),
3338
- nextSteps: z24.array(z24.string())
3047
+ summaryPoints: z22.array(z22.string()),
3048
+ reviewPrompt: z22.string(),
3049
+ nextSteps: z22.array(z22.string())
3339
3050
  });
3340
3051
  function formatCompletedSteps(steps) {
3341
3052
  if (!steps.length) return "(no prior steps completed)";
@@ -3386,16 +3097,16 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
3386
3097
  };
3387
3098
 
3388
3099
  // src/actions/implement.ts
3389
- import z25 from "zod";
3100
+ import z24 from "zod";
3390
3101
 
3391
3102
  // src/lib/worktree.ts
3392
3103
  import { execFile, spawn as spawn3 } from "node:child_process";
3393
- import { copyFile, mkdir as mkdir6, readdir as readdir3, readFile as readFile7, stat as stat2, writeFile as writeFile6 } from "node:fs/promises";
3104
+ import { copyFile, mkdir as mkdir6, readdir as readdir3, readFile as readFile8, stat as stat2, writeFile as writeFile6 } from "node:fs/promises";
3394
3105
  import {
3395
3106
  basename as basename2,
3396
3107
  dirname as dirname7,
3397
3108
  isAbsolute as isAbsolute2,
3398
- join as join9,
3109
+ join as join10,
3399
3110
  relative as relative2,
3400
3111
  resolve as resolve3
3401
3112
  } from "node:path";
@@ -3429,7 +3140,7 @@ async function isWorkingTreeDirty(repoRoot) {
3429
3140
  return out.trim().length > 0;
3430
3141
  }
3431
3142
  async function pruneOldWorktrees(repoRoot) {
3432
- const dir = join9(stateDir(repoRoot), "worktrees");
3143
+ const dir = join10(stateDir(repoRoot), "worktrees");
3433
3144
  const stale = (await readdir3(dir).catch(() => [])).filter((name) => /^wizard-implement-\d+$/.test(name)).sort().reverse().slice(MAX_WIZARD_WORKTREES - 1);
3434
3145
  for (const slug of stale) {
3435
3146
  const branch = slug.replace("wizard-implement-", WIZARD_BRANCH_PREFIX);
@@ -3440,7 +3151,7 @@ async function pruneOldWorktrees(repoRoot) {
3440
3151
  "worktree",
3441
3152
  "remove",
3442
3153
  "--force",
3443
- join9(dir, slug)
3154
+ join10(dir, slug)
3444
3155
  ]);
3445
3156
  await git(["-C", repoRoot, "branch", "-D", branch]);
3446
3157
  } catch (err) {
@@ -3454,7 +3165,7 @@ async function pruneOldWorktrees(repoRoot) {
3454
3165
  async function createWorktree(repoRoot) {
3455
3166
  const branch = `${WIZARD_BRANCH_PREFIX}${Date.now()}`;
3456
3167
  const dirSlug = branch.replace(/\//g, "-");
3457
- const path = join9(stateDir(repoRoot), "worktrees", dirSlug);
3168
+ const path = join10(stateDir(repoRoot), "worktrees", dirSlug);
3458
3169
  await git(["-C", repoRoot, "worktree", "prune"]);
3459
3170
  await pruneOldWorktrees(repoRoot);
3460
3171
  await mkdir6(dirname7(path), { recursive: true });
@@ -3574,8 +3285,8 @@ async function copyUploadIntoWorktree(repoRoot, worktreePath, ingestDir, sourceP
3574
3285
  } catch {
3575
3286
  return { ok: false, reason: `"${sourcePath}" does not exist` };
3576
3287
  }
3577
- const relPath = join9(ingestDir, basename2(source));
3578
- const dest = join9(worktreePath, relPath);
3288
+ const relPath = join10(ingestDir, basename2(source));
3289
+ const dest = join10(worktreePath, relPath);
3579
3290
  try {
3580
3291
  await mkdir6(dirname7(dest), { recursive: true });
3581
3292
  await copyFile(source, dest);
@@ -3591,10 +3302,10 @@ function hasEnvVar(content, name) {
3591
3302
  return new RegExp(`^(\\s*(?:export\\s+)?${name})\\s*=`, "m").test(content);
3592
3303
  }
3593
3304
  async function writeSearchEnvValues(worktreePath, vars) {
3594
- const target = join9(worktreePath, ".env");
3305
+ const target = join10(worktreePath, ".env");
3595
3306
  let existing = "";
3596
3307
  try {
3597
- existing = await readFile7(target, "utf8");
3308
+ existing = await readFile8(target, "utf8");
3598
3309
  } catch (err) {
3599
3310
  if (err.code !== "ENOENT") throw err;
3600
3311
  }
@@ -3662,15 +3373,63 @@ async function confirmDirtyWorkingTree(ctx, repoRoot) {
3662
3373
  }
3663
3374
  }
3664
3375
 
3376
+ // src/lib/algoliaApiKey.ts
3377
+ import { z as z23 } from "zod";
3378
+ var SAFE_ACLS = /* @__PURE__ */ new Set(["search", "browse", "listIndexes"]);
3379
+ var apiKeySchema = z23.object({
3380
+ value: z23.string().min(1),
3381
+ acl: z23.array(z23.string()).default([]),
3382
+ indexes: z23.array(z23.string()).default([])
3383
+ });
3384
+ var apiKeyListSchema = z23.object({
3385
+ items: z23.array(apiKeySchema).optional(),
3386
+ keys: z23.array(apiKeySchema).optional()
3387
+ }).transform((o) => o.items ?? o.keys ?? []);
3388
+ var createdKeySchema = z23.object({
3389
+ key: z23.string().min(1).optional(),
3390
+ value: z23.string().min(1).optional()
3391
+ });
3392
+ function canReuse(key, index) {
3393
+ return key.acl.includes("search") && key.acl.every((acl) => SAFE_ACLS.has(acl)) && (key.indexes.length === 0 || key.indexes.includes("*") || key.indexes.includes(index));
3394
+ }
3395
+ async function createSearchKey(index) {
3396
+ const stdout = await runAlgoliaCli([
3397
+ "apikeys",
3398
+ "create",
3399
+ "--indices",
3400
+ index,
3401
+ "--acl",
3402
+ "search,browse",
3403
+ "--description",
3404
+ `wizard search-only key for ${index}`,
3405
+ "-o",
3406
+ "json"
3407
+ ]);
3408
+ const { key, value } = createdKeySchema.parse(JSON.parse(stdout));
3409
+ const created = key ?? value;
3410
+ if (!created) throw new Error("apikeys create returned no key value");
3411
+ return created;
3412
+ }
3413
+ async function resolveSearchOnlyKey(index) {
3414
+ const stdout = await runAlgoliaCli(["apikeys", "list", "-o", "json"]);
3415
+ const existing = apiKeyListSchema.parse(JSON.parse(stdout)).find((key) => canReuse(key, index))?.value;
3416
+ if (existing) {
3417
+ logger.info({ index }, "reusing existing search-only API key");
3418
+ return existing;
3419
+ }
3420
+ logger.info({ index }, "no reusable search-only key found; creating one");
3421
+ return createSearchKey(index);
3422
+ }
3423
+
3665
3424
  // src/lib/algoliaDocs.ts
3666
3425
  import { readFileSync, readdirSync, existsSync as existsSync2 } from "node:fs";
3667
- import { dirname as dirname8, join as join10 } from "node:path";
3426
+ import { dirname as dirname8, join as join11 } from "node:path";
3668
3427
  import { fileURLToPath as fileURLToPath2 } from "node:url";
3669
- var DOCS_SUBPATH = join10("docs", "algolia-sdk");
3428
+ var DOCS_SUBPATH = join11("docs", "algolia-sdk");
3670
3429
  function findDocsDir() {
3671
3430
  let dir = dirname8(fileURLToPath2(import.meta.url));
3672
3431
  for (; ; ) {
3673
- const candidate = join10(dir, DOCS_SUBPATH);
3432
+ const candidate = join11(dir, DOCS_SUBPATH);
3674
3433
  if (existsSync2(candidate)) return candidate;
3675
3434
  const parent = dirname8(dir);
3676
3435
  if (parent === dir) return void 0;
@@ -3693,7 +3452,7 @@ function loadAlgoliaDoc(language) {
3693
3452
  );
3694
3453
  return "";
3695
3454
  }
3696
- return readFileSync(join10(docsDir, files[0]), "utf8").trim();
3455
+ return readFileSync(join11(docsDir, files[0]), "utf8").trim();
3697
3456
  }
3698
3457
  function getNamedDoc(name, language) {
3699
3458
  const docsDir = findDocsDir();
@@ -3701,7 +3460,7 @@ function getNamedDoc(name, language) {
3701
3460
  logger.warn("docs/algolia-sdk not found");
3702
3461
  return "";
3703
3462
  }
3704
- const file = join10(docsDir, `${name}-${language}.md`);
3463
+ const file = join11(docsDir, `${name}-${language}.md`);
3705
3464
  if (!existsSync2(file)) {
3706
3465
  logger.warn({ name, language }, "named SDK reference not found");
3707
3466
  return "";
@@ -3728,50 +3487,50 @@ function shellQuote(value) {
3728
3487
  }
3729
3488
 
3730
3489
  // src/actions/implement.ts
3731
- var implementSchema = z25.object({
3732
- filesChanged: z25.array(z25.string()),
3733
- summary: z25.string(),
3490
+ var implementSchema = z24.object({
3491
+ filesChanged: z24.array(z24.string()),
3492
+ summary: z24.string(),
3734
3493
  // Absolute path to the throwaway worktree holding the generated changes, so
3735
3494
  // the user can open it (`cd <worktreePath>`) or inspect the diff
3736
3495
  // (`git -C <worktreePath> status/diff`).
3737
- worktreePath: z25.string().optional(),
3738
- ingestCommand: z25.string().optional(),
3496
+ worktreePath: z24.string().optional(),
3497
+ ingestCommand: z24.string().optional(),
3739
3498
  // True when the user accepted the run-now prompt and the wizard executed the
3740
3499
  // ingestion script; downstream steps use this to avoid telling the user to run
3741
3500
  // a script that already ran.
3742
- ingestScriptRan: z25.boolean().optional(),
3501
+ ingestScriptRan: z24.boolean().optional(),
3743
3502
  // Records ingested by the run-now execution, parsed from the script's
3744
3503
  // machine-readable count line; absent when the script didn't run or emitted
3745
3504
  // no parseable count.
3746
- ingestRecordCount: z25.number().optional(),
3505
+ ingestRecordCount: z24.number().optional(),
3747
3506
  // Wall-clock duration of the run-now ingestion execution, in ms.
3748
- ingestDurationMs: z25.number().optional(),
3749
- ingestionSource: z25.enum(["local", "fileUpload", "generated"]),
3507
+ ingestDurationMs: z24.number().optional(),
3508
+ ingestionSource: z24.enum(["local", "fileUpload", "generated"]),
3750
3509
  // Suggested names/values, built from framework detection. The search agent is
3751
3510
  // instructed to rename the prefix if it doesn't match the project's build
3752
3511
  // tool, so the names it actually wrote can differ — treat these as hints, not
3753
3512
  // ground truth (the agent's summary carries the final names).
3754
- searchEnvVars: z25.array(
3755
- z25.object({
3756
- name: z25.string(),
3757
- value: z25.string()
3513
+ searchEnvVars: z24.array(
3514
+ z24.object({
3515
+ name: z24.string(),
3516
+ value: z24.string()
3758
3517
  })
3759
3518
  ).optional()
3760
3519
  });
3761
- var implementationOutputSchema = z25.object({
3762
- summary: z25.string(),
3520
+ var implementationOutputSchema = z24.object({
3521
+ summary: z24.string(),
3763
3522
  // Ingestion only: how to run the generated script, as a structured pair the
3764
3523
  // wizard turns into an argv (`<runtime> <entrypoint>`) — never a free-form
3765
3524
  // command string. `runtime` is constrained to an allowlisted interpreter and
3766
3525
  // `entrypoint` is validated to a worktree-relative path before execution, so
3767
3526
  // the agent cannot inject extra commands or swap the interpreter.
3768
- runtime: z25.enum(INGEST_RUNTIMES).optional(),
3769
- entrypoint: z25.string().optional()
3527
+ runtime: z24.enum(INGEST_RUNTIMES).optional(),
3528
+ entrypoint: z24.string().optional()
3770
3529
  });
3771
- var verificationOutputSchema = z25.object({
3772
- summary: z25.string(),
3773
- sufficient: z25.boolean(),
3774
- additionalInstructions: z25.string().optional()
3530
+ var verificationOutputSchema = z24.object({
3531
+ summary: z24.string(),
3532
+ sufficient: z24.boolean(),
3533
+ additionalInstructions: z24.string().optional()
3775
3534
  });
3776
3535
  var MAX_IMPLEMENT_VERIFICATION_ATTEMPTS = 3;
3777
3536
  var DEFAULT_IMPLEMENT_USE_CASES = ["ingestion", "search"];
@@ -3885,7 +3644,7 @@ function searchInstructions(input) {
3885
3644
  doc,
3886
3645
  `Add the search UI at ${input.searchLocation ? `"${input.searchLocation}"` : "the best shared, always-rendered layout location (e.g. a header/nav component)"} so it is reachable across the app \u2014 at least a working SearchBox and Hits against the "${input.targetIndex}" index.`,
3887
3646
  "Read the App ID and a search-only API key from public env vars; never hardcode them. A search-only key is safe to expose client-side.",
3888
- // appId always resolves (requireApplication throws otherwise); only the
3647
+ // appId always resolves (loadActiveProfile throws otherwise); only the
3889
3648
  // search-only key is best-effort and can fall back to a placeholder.
3890
3649
  `Values: App ID "${input.appId}", search-only key ${input.searchKey ? `"${input.searchKey}"` : "(placeholder for the developer to fill in)"}.`,
3891
3650
  // Names are fixed, not the agent's to rename: the wizard writes the
@@ -4034,7 +3793,6 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
4034
3793
  }
4035
3794
  }
4036
3795
  const targetIndex = selected?.selection;
4037
- useWizard.getState().setTargetIndex(targetIndex ?? null);
4038
3796
  await assertGitRepoWithHead(repoRoot);
4039
3797
  if (await isWorkingTreeDirty(repoRoot)) {
4040
3798
  await confirmDirtyWorkingTree(ctx, repoRoot);
@@ -4045,7 +3803,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
4045
3803
  let appId;
4046
3804
  let searchKey;
4047
3805
  if (useCases.includes("search")) {
4048
- appId = (await requireApplication()).id;
3806
+ appId = (await loadActiveProfile()).appId;
4049
3807
  try {
4050
3808
  searchKey = await resolveSearchOnlyKey(targetIndex);
4051
3809
  } catch (err) {
@@ -4156,8 +3914,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
4156
3914
  messages: []
4157
3915
  }) === true;
4158
3916
  if (runNow) {
4159
- const ingestApp = await requireApplication();
4160
- const writeKey = await resolveWriteKey(targetIndex);
3917
+ const profile2 = await loadActiveProfile();
4161
3918
  ctx.notify({ messages: [`Writing records to "${targetIndex}"\u2026`] });
4162
3919
  const scriptLogId = ctx.logStart("runIngestScript", {
4163
3920
  runtime: ingestRuntime,
@@ -4169,8 +3926,8 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
4169
3926
  ingestRuntime,
4170
3927
  ingestEntrypoint,
4171
3928
  {
4172
- [APP_ID_VAR]: ingestApp.id,
4173
- [API_KEY_VAR]: writeKey
3929
+ [APP_ID_VAR]: profile2.appId,
3930
+ [API_KEY_VAR]: profile2.apiKey
4174
3931
  }
4175
3932
  );
4176
3933
  ctx.logEnd(scriptLogId, run.ok ? "success" : "error");
@@ -4242,7 +3999,7 @@ ${run.output}` : status;
4242
3999
  // No question being asked here, just an acknowledgement — the
4243
4000
  // continue/decline hints below already say "continue".
4244
4001
  prompt: "",
4245
- promptType: "spaceToContinue",
4002
+ promptType: "enterToContinue",
4246
4003
  options: [],
4247
4004
  messages: ingestOutcomeMessage ? [ingestOutcomeMessage, ...commandMessages] : commandMessages
4248
4005
  });
@@ -4381,8 +4138,8 @@ var defaultWorkflow = {
4381
4138
  defineStep({
4382
4139
  id: "select-index",
4383
4140
  title: "Set up index",
4384
- outputSchema: z26.object({
4385
- selection: z26.string()
4141
+ outputSchema: z25.object({
4142
+ selection: z25.string()
4386
4143
  }),
4387
4144
  run: (ctx) => selectIndexStep(ctx)
4388
4145
  }),
@@ -4463,54 +4220,25 @@ var store = useWizard.getState();
4463
4220
  var instance = render(/* @__PURE__ */ jsx14(App, {}), { incrementalRendering: true });
4464
4221
  var user = await getUser();
4465
4222
  if (!user) {
4466
- store.beginAuth();
4223
+ await instance.waitUntilRenderFlush();
4224
+ instance.cleanup();
4467
4225
  try {
4468
4226
  await runAuthLogin();
4469
4227
  } catch (err) {
4470
- if (!needsInteractiveTerminal(err)) {
4471
- store.setError(err instanceof Error ? err.message : String(err));
4472
- await instance.waitUntilExit();
4473
- process.exit(1);
4474
- }
4475
- try {
4476
- await promptForApplication();
4477
- } catch (pickErr) {
4478
- logger.warn(
4479
- { err: pickErr.message },
4480
- "in-wizard application selection failed; handing over the terminal"
4481
- );
4482
- await instance.waitUntilRenderFlush();
4483
- instance.cleanup();
4484
- try {
4485
- await runAuthLoginInTerminal();
4486
- } catch (fallbackErr) {
4487
- console.error(
4488
- fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)
4489
- );
4490
- process.exit(1);
4491
- }
4492
- instance = render(/* @__PURE__ */ jsx14(App, {}), { incrementalRendering: true });
4493
- store.clearCliOutput();
4494
- }
4228
+ console.error(err instanceof Error ? err.message : String(err));
4229
+ process.exit(1);
4495
4230
  }
4496
- store.endAuth();
4231
+ instance = render(/* @__PURE__ */ jsx14(App, {}), { incrementalRendering: true });
4497
4232
  user = await getUser();
4498
4233
  if (!user) {
4499
4234
  store.setError(
4500
- "Authentication completed but no Algolia user was returned. Try running `npx @algolia/cli@latest auth login` directly."
4235
+ "Authentication completed but no Algolia user was returned. Try running `npx @algolia/cli auth login` directly."
4501
4236
  );
4502
4237
  await instance.waitUntilExit();
4503
4238
  process.exit(1);
4504
4239
  }
4505
4240
  }
4506
4241
  store.setUser(user);
4242
+ var profile = await loadActiveProfile();
4507
4243
  await store.waitForStart();
4508
- var app;
4509
- try {
4510
- app = await ensureApplication();
4511
- } catch (err) {
4512
- store.setError(err instanceof Error ? err.message : String(err));
4513
- await instance.waitUntilExit();
4514
- process.exit(1);
4515
- }
4516
- runWorkflow(workflow, app.id);
4244
+ runWorkflow(workflow, profile?.appId);