@algolia/wizard 0.3.0-rc.47.9 → 0.4.0-rc.48.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +257 -55
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
import { render } from "ink";
|
|
5
5
|
|
|
6
6
|
// src/ui/App.tsx
|
|
7
|
-
import { Box as
|
|
7
|
+
import { Box as Box13, Text as Text13, useApp, useInput as useInput6, useWindowSize as useWindowSize6 } from "ink";
|
|
8
8
|
|
|
9
9
|
// src/core/store.ts
|
|
10
10
|
import { create } from "zustand";
|
|
11
|
+
import { nanoid } from "nanoid";
|
|
11
12
|
|
|
12
13
|
// src/lib/algoliaCli.ts
|
|
13
14
|
import { spawn } from "node:child_process";
|
|
@@ -165,6 +166,10 @@ async function markInteraction() {
|
|
|
165
166
|
function toUserInfo({ user_id, ...rest }) {
|
|
166
167
|
return { userId: user_id, ...rest };
|
|
167
168
|
}
|
|
169
|
+
function describeInputValue(value) {
|
|
170
|
+
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
171
|
+
return Array.isArray(value) ? value.join(", ") : value;
|
|
172
|
+
}
|
|
168
173
|
var NOTICE_INTERVAL_MS = 2e3;
|
|
169
174
|
var useWizard = create((set, get) => ({
|
|
170
175
|
phase: "idle",
|
|
@@ -177,6 +182,7 @@ var useWizard = create((set, get) => ({
|
|
|
177
182
|
notices: [],
|
|
178
183
|
_noticeQueue: [],
|
|
179
184
|
_noticeTimer: null,
|
|
185
|
+
logs: [],
|
|
180
186
|
error: null,
|
|
181
187
|
inputReq: null,
|
|
182
188
|
_resolve: null,
|
|
@@ -255,6 +261,21 @@ var useWizard = create((set, get) => ({
|
|
|
255
261
|
get()._clearNoticeQueue();
|
|
256
262
|
set({ notices: [] });
|
|
257
263
|
},
|
|
264
|
+
logStart: (kind, name, input) => {
|
|
265
|
+
const id = nanoid();
|
|
266
|
+
set((s) => ({
|
|
267
|
+
logs: [
|
|
268
|
+
...s.logs,
|
|
269
|
+
{ id, kind, name, input, status: "running", startedAt: Date.now() }
|
|
270
|
+
]
|
|
271
|
+
}));
|
|
272
|
+
return id;
|
|
273
|
+
},
|
|
274
|
+
logEnd: (id, status) => set((s) => ({
|
|
275
|
+
logs: s.logs.map(
|
|
276
|
+
(t) => t.id === id ? { ...t, status, durationMs: Date.now() - t.startedAt } : t
|
|
277
|
+
)
|
|
278
|
+
})),
|
|
258
279
|
requestUserInput: (req) => new Promise((resolve4) => {
|
|
259
280
|
set({
|
|
260
281
|
phase: "awaitingInput",
|
|
@@ -262,10 +283,15 @@ var useWizard = create((set, get) => ({
|
|
|
262
283
|
_resolve: resolve4
|
|
263
284
|
});
|
|
264
285
|
}),
|
|
286
|
+
// Logs what the user picked — not the prompt text that was shown, which
|
|
287
|
+
// may repeat or duplicate on-screen content and isn't the useful signal
|
|
288
|
+
// here.
|
|
265
289
|
submitInput: async (value) => {
|
|
266
290
|
await markInteraction();
|
|
267
291
|
get()._resolve?.(value);
|
|
268
292
|
set({ inputReq: null, _resolve: null, phase: "running" });
|
|
293
|
+
const id = get().logStart("prompt", `User input: ${describeInputValue(value)}`);
|
|
294
|
+
get().logEnd(id, "success");
|
|
269
295
|
},
|
|
270
296
|
setDone: () => set({ phase: "done" }),
|
|
271
297
|
setError: (message) => set({ phase: "error", error: message }),
|
|
@@ -279,6 +305,7 @@ var useWizard = create((set, get) => ({
|
|
|
279
305
|
currentStepIndex: 0,
|
|
280
306
|
output: "",
|
|
281
307
|
notices: [],
|
|
308
|
+
logs: [],
|
|
282
309
|
error: null,
|
|
283
310
|
inputReq: null,
|
|
284
311
|
_resolve: null
|
|
@@ -1112,53 +1139,205 @@ function Ribbon() {
|
|
|
1112
1139
|
}
|
|
1113
1140
|
|
|
1114
1141
|
// src/ui/App.tsx
|
|
1142
|
+
import { useState as useState6 } from "react";
|
|
1143
|
+
|
|
1144
|
+
// src/ui/Logs.tsx
|
|
1145
|
+
import { useLayoutEffect, useRef as useRef2, useState as useState5 } from "react";
|
|
1146
|
+
import { Box as Box12, Text as Text12, measureElement as measureElement2, useInput as useInput5, useWindowSize as useWindowSize5 } from "ink";
|
|
1115
1147
|
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1148
|
+
var KIND_COLOR = {
|
|
1149
|
+
tool: COLORS.primary,
|
|
1150
|
+
prompt: COLORS.badge
|
|
1151
|
+
};
|
|
1152
|
+
var STATUS_COLOR = {
|
|
1153
|
+
running: COLORS.status.running,
|
|
1154
|
+
error: COLORS.danger
|
|
1155
|
+
};
|
|
1156
|
+
function logNameColor(entry) {
|
|
1157
|
+
return STATUS_COLOR[entry.status] ?? KIND_COLOR[entry.kind];
|
|
1158
|
+
}
|
|
1159
|
+
var ROW_GAP = 1;
|
|
1160
|
+
function truncate2(str, maxWidth) {
|
|
1161
|
+
if (maxWidth <= 0) return "";
|
|
1162
|
+
return str.length > maxWidth ? `${str.slice(0, maxWidth - 1)}\u2026` : str;
|
|
1163
|
+
}
|
|
1164
|
+
function rawInputText(input) {
|
|
1165
|
+
if (input === void 0) return "";
|
|
1166
|
+
const str = typeof input === "string" ? input : JSON.stringify(input);
|
|
1167
|
+
if (!str || str === "{}") return "";
|
|
1168
|
+
return str.replace(/\s+/g, " ").trim();
|
|
1169
|
+
}
|
|
1170
|
+
function formatTimestamp(ms) {
|
|
1171
|
+
const d = new Date(ms);
|
|
1172
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
1173
|
+
return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
1174
|
+
}
|
|
1175
|
+
function Logs() {
|
|
1176
|
+
const logs = useWizard((s) => s.logs);
|
|
1177
|
+
const { rows, columns } = useWindowSize5();
|
|
1178
|
+
const viewportRef = useRef2(null);
|
|
1179
|
+
const [viewportHeight, setViewportHeight] = useState5(0);
|
|
1180
|
+
const [viewportWidth, setViewportWidth] = useState5(0);
|
|
1181
|
+
const [scrollOffset, setScrollOffset] = useState5(0);
|
|
1182
|
+
const prevMaxOffsetRef = useRef2(0);
|
|
1183
|
+
useLayoutEffect(() => {
|
|
1184
|
+
if (!viewportRef.current) return;
|
|
1185
|
+
const { width, height } = measureElement2(viewportRef.current);
|
|
1186
|
+
setViewportHeight(height);
|
|
1187
|
+
setViewportWidth(width);
|
|
1188
|
+
}, [rows, columns, logs.length === 0]);
|
|
1189
|
+
let capacity = viewportHeight;
|
|
1190
|
+
for (let i = 0; i < 2; i++) {
|
|
1191
|
+
const hasAbove = scrollOffset > 0;
|
|
1192
|
+
const hasBelow = scrollOffset + capacity < logs.length;
|
|
1193
|
+
capacity = Math.max(
|
|
1194
|
+
viewportHeight - (hasAbove ? 1 : 0) - (hasBelow ? 1 : 0),
|
|
1195
|
+
0
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1198
|
+
const capacityAtBottom = logs.length > viewportHeight ? Math.max(viewportHeight - 1, 0) : viewportHeight;
|
|
1199
|
+
const maxOffset = Math.max(logs.length - capacityAtBottom, 0);
|
|
1200
|
+
useLayoutEffect(() => {
|
|
1201
|
+
const wasAtBottom = scrollOffset >= prevMaxOffsetRef.current;
|
|
1202
|
+
prevMaxOffsetRef.current = maxOffset;
|
|
1203
|
+
setScrollOffset((o) => wasAtBottom ? maxOffset : Math.min(o, maxOffset));
|
|
1204
|
+
}, [maxOffset]);
|
|
1205
|
+
useInput5((_input, key) => {
|
|
1206
|
+
if (!key.upArrow && !key.downArrow) return;
|
|
1207
|
+
setScrollOffset(
|
|
1208
|
+
(o) => key.upArrow ? Math.max(o - 1, 0) : Math.min(o + 1, maxOffset)
|
|
1209
|
+
);
|
|
1210
|
+
});
|
|
1211
|
+
const visible = logs.slice(scrollOffset, scrollOffset + capacity);
|
|
1212
|
+
const hiddenAbove = scrollOffset;
|
|
1213
|
+
const hiddenBelow = logs.length - scrollOffset - visible.length;
|
|
1214
|
+
return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
|
|
1215
|
+
logs.length === 0 && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: "No logs yet." }),
|
|
1216
|
+
/* @__PURE__ */ jsxs11(Box12, { ref: viewportRef, flexDirection: "column", flexGrow: 1, children: [
|
|
1217
|
+
hiddenAbove > 0 && /* @__PURE__ */ jsxs11(Text12, { color: COLORS.dim, children: [
|
|
1218
|
+
"\u2191 ",
|
|
1219
|
+
hiddenAbove,
|
|
1220
|
+
" more"
|
|
1221
|
+
] }),
|
|
1222
|
+
visible.map((entry) => {
|
|
1223
|
+
const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
|
|
1224
|
+
const durationText = entry.kind === "tool" && entry.durationMs !== void 0 ? `${entry.durationMs}ms` : "";
|
|
1225
|
+
const rawPreview = rawInputText(entry.input);
|
|
1226
|
+
const partCount = 2 + (rawPreview ? 1 : 0) + (durationText ? 1 : 0);
|
|
1227
|
+
const gaps = (partCount - 1) * ROW_GAP;
|
|
1228
|
+
let budget = viewportWidth - timestamp.length - durationText.length - gaps;
|
|
1229
|
+
const name = truncate2(entry.name, budget);
|
|
1230
|
+
budget -= name.length;
|
|
1231
|
+
const preview = rawPreview ? truncate2(rawPreview, budget) : "";
|
|
1232
|
+
return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", gap: ROW_GAP, children: [
|
|
1233
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: timestamp }),
|
|
1234
|
+
/* @__PURE__ */ jsx12(Text12, { color: logNameColor(entry), wrap: "truncate", children: name }),
|
|
1235
|
+
preview && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, wrap: "truncate", children: preview }),
|
|
1236
|
+
durationText && /* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: durationText })
|
|
1237
|
+
] }, entry.id);
|
|
1238
|
+
}),
|
|
1239
|
+
hiddenBelow > 0 && /* @__PURE__ */ jsxs11(Text12, { color: COLORS.dim, children: [
|
|
1240
|
+
"\u2193 ",
|
|
1241
|
+
hiddenBelow,
|
|
1242
|
+
" more"
|
|
1243
|
+
] })
|
|
1244
|
+
] }),
|
|
1245
|
+
/* @__PURE__ */ jsx12(Text12, { color: COLORS.dim, children: "\u2191/\u2193 scroll" })
|
|
1246
|
+
] });
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/lib/events.ts
|
|
1250
|
+
import "zod";
|
|
1251
|
+
function track(event, payload) {
|
|
1252
|
+
const token = getAuthToken();
|
|
1253
|
+
if (!token) return;
|
|
1254
|
+
const userId = useWizard.getState().user?.userId;
|
|
1255
|
+
if (!userId) return;
|
|
1256
|
+
void proxyFetch(`${PROXY_BASE_URL}/events`, {
|
|
1257
|
+
method: "POST",
|
|
1258
|
+
headers: {
|
|
1259
|
+
"content-type": "application/json",
|
|
1260
|
+
authorization: `Bearer ${token}`
|
|
1261
|
+
},
|
|
1262
|
+
body: JSON.stringify({ userId, event, properties: payload })
|
|
1263
|
+
}).catch((err) => {
|
|
1264
|
+
logger.warn({ err, event }, "failed to send analytics event");
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// src/ui/App.tsx
|
|
1269
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1116
1270
|
function App() {
|
|
1117
|
-
const { phase, error, homeScreen } = useWizard();
|
|
1271
|
+
const { phase, error, homeScreen, currentStepIndex, steps, inputReq } = useWizard();
|
|
1118
1272
|
const { exit } = useApp();
|
|
1119
|
-
const { columns, rows } =
|
|
1273
|
+
const { columns, rows } = useWindowSize6();
|
|
1274
|
+
const [showLogs, setShowLogs] = useState6(false);
|
|
1120
1275
|
const finished = phase === "done" || phase === "error";
|
|
1121
|
-
|
|
1276
|
+
const currentStep = steps[currentStepIndex];
|
|
1277
|
+
useInput6(
|
|
1122
1278
|
(_input, key) => {
|
|
1123
|
-
if (key.return
|
|
1279
|
+
if (key.return) {
|
|
1124
1280
|
exit();
|
|
1125
1281
|
}
|
|
1126
1282
|
},
|
|
1127
1283
|
{ isActive: finished }
|
|
1128
1284
|
);
|
|
1285
|
+
useInput6((_input, key) => {
|
|
1286
|
+
if (phase === "idle" || phase === "preflight") return;
|
|
1287
|
+
if (key.tab) {
|
|
1288
|
+
setShowLogs(!showLogs);
|
|
1289
|
+
track("AI Wizard Interaction", {
|
|
1290
|
+
context: "global",
|
|
1291
|
+
key: "tab",
|
|
1292
|
+
currentStep: currentStep?.id
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
const escOwnedElsewhere = phase === "idle" || phase === "awaitingInput" && inputReq?.promptType === "spaceToContinue";
|
|
1297
|
+
useInput6((_input, key) => {
|
|
1298
|
+
if (escOwnedElsewhere) return;
|
|
1299
|
+
if (key.escape) {
|
|
1300
|
+
track("AI Wizard Interaction", {
|
|
1301
|
+
context: "global",
|
|
1302
|
+
key: "esc",
|
|
1303
|
+
// No step is active until `startWorkflow` — report the phase instead.
|
|
1304
|
+
currentStep: currentStep?.id ?? phase
|
|
1305
|
+
});
|
|
1306
|
+
exit();
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1129
1309
|
const mainWindowVisible = phase === "running" || phase === "awaitingInput" || phase === "error" || phase === "done";
|
|
1130
1310
|
const flexDirection = columns > 90 ? "row" : "column";
|
|
1131
1311
|
const showSidebar = flexDirection === "row";
|
|
1132
|
-
return /* @__PURE__ */
|
|
1133
|
-
|
|
1312
|
+
return /* @__PURE__ */ jsxs12(
|
|
1313
|
+
Box13,
|
|
1134
1314
|
{
|
|
1135
1315
|
backgroundColor: COLORS.bg.main,
|
|
1136
1316
|
flexDirection: "row",
|
|
1137
1317
|
width: columns,
|
|
1138
1318
|
minHeight: rows,
|
|
1139
1319
|
children: [
|
|
1140
|
-
mainWindowVisible && /* @__PURE__ */
|
|
1141
|
-
|
|
1320
|
+
mainWindowVisible && /* @__PURE__ */ jsxs12(
|
|
1321
|
+
Box13,
|
|
1142
1322
|
{
|
|
1143
1323
|
flexDirection,
|
|
1144
1324
|
width: "100%",
|
|
1145
1325
|
justifyContent: "space-between",
|
|
1146
1326
|
children: [
|
|
1147
|
-
/* @__PURE__ */
|
|
1148
|
-
/* @__PURE__ */
|
|
1149
|
-
/* @__PURE__ */
|
|
1150
|
-
phase === "running" && showSidebar && /* @__PURE__ */
|
|
1151
|
-
phase === "error" && error && /* @__PURE__ */
|
|
1327
|
+
showLogs ? /* @__PURE__ */ jsx13(Logs, {}) : /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", paddingX: 4, paddingY: 2, width: 70, children: [
|
|
1328
|
+
/* @__PURE__ */ jsx13(Notices, {}),
|
|
1329
|
+
/* @__PURE__ */ jsx13(PromptInput, {}),
|
|
1330
|
+
phase === "running" && showSidebar && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx13(CurrentStep, {}) }),
|
|
1331
|
+
phase === "error" && error && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: COLORS.status.error, children: [
|
|
1152
1332
|
"\u2716 ",
|
|
1153
1333
|
error
|
|
1154
1334
|
] }) })
|
|
1155
1335
|
] }),
|
|
1156
|
-
/* @__PURE__ */
|
|
1157
|
-
showSidebar ? /* @__PURE__ */ jsx12(Sidebar, {}) : /* @__PURE__ */ jsx12(Ribbon, {})
|
|
1336
|
+
showSidebar ? /* @__PURE__ */ jsx13(Sidebar, {}) : /* @__PURE__ */ jsx13(Ribbon, {})
|
|
1158
1337
|
]
|
|
1159
1338
|
}
|
|
1160
1339
|
),
|
|
1161
|
-
(phase === "idle" || phase === "preflight") && (homeScreen === "learnMore" ? /* @__PURE__ */
|
|
1340
|
+
(phase === "idle" || phase === "preflight") && (homeScreen === "learnMore" ? /* @__PURE__ */ jsx13(LearnMore, {}) : /* @__PURE__ */ jsx13(Welcome, {}))
|
|
1162
1341
|
]
|
|
1163
1342
|
}
|
|
1164
1343
|
);
|
|
@@ -1356,25 +1535,6 @@ function trackWorkflowError(ctx) {
|
|
|
1356
1535
|
);
|
|
1357
1536
|
}
|
|
1358
1537
|
|
|
1359
|
-
// src/lib/events.ts
|
|
1360
|
-
import "zod";
|
|
1361
|
-
function track(event, payload) {
|
|
1362
|
-
const token = getAuthToken();
|
|
1363
|
-
if (!token) return;
|
|
1364
|
-
const userId = useWizard.getState().user?.userId;
|
|
1365
|
-
if (!userId) return;
|
|
1366
|
-
void proxyFetch(`${PROXY_BASE_URL}/events`, {
|
|
1367
|
-
method: "POST",
|
|
1368
|
-
headers: {
|
|
1369
|
-
"content-type": "application/json",
|
|
1370
|
-
authorization: `Bearer ${token}`
|
|
1371
|
-
},
|
|
1372
|
-
body: JSON.stringify({ userId, event, properties: payload })
|
|
1373
|
-
}).catch((err) => {
|
|
1374
|
-
logger.warn({ err, event }, "failed to send analytics event");
|
|
1375
|
-
});
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
1538
|
// src/core/orchestrator.ts
|
|
1379
1539
|
function defineStep(step) {
|
|
1380
1540
|
return { visible: true, ...step };
|
|
@@ -1448,6 +1608,8 @@ async function makeContext(state) {
|
|
|
1448
1608
|
requestUserInput: (prompt) => useWizard.getState().requestUserInput(prompt),
|
|
1449
1609
|
notify: (notice) => useWizard.getState().pushNotice(notice),
|
|
1450
1610
|
clearNotices: () => useWizard.getState().clearNotices(),
|
|
1611
|
+
logStart: (name, input) => useWizard.getState().logStart("tool", name, input),
|
|
1612
|
+
logEnd: (id, status) => useWizard.getState().logEnd(id, status),
|
|
1451
1613
|
updateAlgoliaState: (key, value) => {
|
|
1452
1614
|
state.algoliaState[key] = value;
|
|
1453
1615
|
},
|
|
@@ -2100,7 +2262,7 @@ function verifyImplementationTool() {
|
|
|
2100
2262
|
// src/lib/tools/generateRecord.ts
|
|
2101
2263
|
import { tool as tool9, generateText, Output, NoObjectGeneratedError } from "ai";
|
|
2102
2264
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2103
|
-
import { nanoid } from "nanoid";
|
|
2265
|
+
import { nanoid as nanoid2 } from "nanoid";
|
|
2104
2266
|
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
2105
2267
|
import { dirname as dirname6 } from "node:path";
|
|
2106
2268
|
import z12 from "zod";
|
|
@@ -2146,7 +2308,7 @@ function generateRecordTool(ctx) {
|
|
|
2146
2308
|
// would otherwise drift to the same high-probability values and
|
|
2147
2309
|
// collide across batches. This per-batch seed pushes each call
|
|
2148
2310
|
// into a different region of the output space.
|
|
2149
|
-
`Variety seed: ${
|
|
2311
|
+
`Variety seed: ${nanoid2()}. Use it to diversify values.`
|
|
2150
2312
|
].filter(Boolean).join("\n")
|
|
2151
2313
|
});
|
|
2152
2314
|
return output.records;
|
|
@@ -2168,7 +2330,7 @@ function generateRecordTool(ctx) {
|
|
|
2168
2330
|
const batches = await Promise.all(batchSizes.map(generateBatch));
|
|
2169
2331
|
const records = batches.flat().map((record) => ({
|
|
2170
2332
|
...record,
|
|
2171
|
-
objectID:
|
|
2333
|
+
objectID: nanoid2()
|
|
2172
2334
|
}));
|
|
2173
2335
|
const slug = entityName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
2174
2336
|
const relPath = `${DATA_DIR}/${slug}.json`;
|
|
@@ -2228,18 +2390,42 @@ function createToolContext(limits = DEFAULT_TOOL_LIMITS, cwd = process.cwd()) {
|
|
|
2228
2390
|
}
|
|
2229
2391
|
|
|
2230
2392
|
// src/lib/tools/index.ts
|
|
2393
|
+
function withLogging(name, def) {
|
|
2394
|
+
const execute = def.execute;
|
|
2395
|
+
if (!execute) return def;
|
|
2396
|
+
return {
|
|
2397
|
+
...def,
|
|
2398
|
+
execute: async (input, options) => {
|
|
2399
|
+
const id = useWizard.getState().logStart("tool", name, input);
|
|
2400
|
+
try {
|
|
2401
|
+
const output = await execute(input, options);
|
|
2402
|
+
useWizard.getState().logEnd(id, "success");
|
|
2403
|
+
return output;
|
|
2404
|
+
} catch (err) {
|
|
2405
|
+
useWizard.getState().logEnd(id, "error");
|
|
2406
|
+
throw err;
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2231
2411
|
function createTools(ctx, { output, tools }) {
|
|
2232
2412
|
const all = {
|
|
2233
|
-
listFiles: listFilesTool(ctx),
|
|
2234
|
-
changeDirectory: changeDirectoryTool(ctx),
|
|
2235
|
-
reportStatus: reportStatusTool(output),
|
|
2236
|
-
readFile: readFileTool(ctx),
|
|
2237
|
-
writeFile: writeFileTool(ctx),
|
|
2238
|
-
writeCredentials:
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2413
|
+
listFiles: withLogging("listFiles", listFilesTool(ctx)),
|
|
2414
|
+
changeDirectory: withLogging("changeDirectory", changeDirectoryTool(ctx)),
|
|
2415
|
+
reportStatus: withLogging("reportStatus", reportStatusTool(output)),
|
|
2416
|
+
readFile: withLogging("readFile", readFileTool(ctx)),
|
|
2417
|
+
writeFile: withLogging("writeFile", writeFileTool(ctx)),
|
|
2418
|
+
writeCredentials: withLogging(
|
|
2419
|
+
"writeCredentials",
|
|
2420
|
+
writeCredentialsTool(ctx)
|
|
2421
|
+
),
|
|
2422
|
+
searchFiles: withLogging("searchFiles", searchFilesTool(ctx)),
|
|
2423
|
+
verifyImplementation: withLogging(
|
|
2424
|
+
"verifyImplementation",
|
|
2425
|
+
verifyImplementationTool()
|
|
2426
|
+
),
|
|
2427
|
+
generateRecord: withLogging("generateRecord", generateRecordTool(ctx)),
|
|
2428
|
+
notifyUser: withLogging("notifyUser", notifyUserTool())
|
|
2243
2429
|
};
|
|
2244
2430
|
if (!tools) return all;
|
|
2245
2431
|
const selection = /* @__PURE__ */ new Set([...tools, "reportStatus", "notifyUser"]);
|
|
@@ -2462,7 +2648,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
2462
2648
|
// package.json
|
|
2463
2649
|
var package_default = {
|
|
2464
2650
|
name: "@algolia/wizard",
|
|
2465
|
-
version: "0.
|
|
2651
|
+
version: "0.4.0-rc.48.12",
|
|
2466
2652
|
description: "Magically implement Algolia functionality in your codebase",
|
|
2467
2653
|
type: "module",
|
|
2468
2654
|
engines: {
|
|
@@ -3411,13 +3597,16 @@ function searchInstructions(input) {
|
|
|
3411
3597
|
doc,
|
|
3412
3598
|
`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.`,
|
|
3413
3599
|
"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.",
|
|
3414
|
-
|
|
3600
|
+
// appId always resolves (loadActiveProfile throws otherwise); only the
|
|
3601
|
+
// search-only key is best-effort and can fall back to a placeholder.
|
|
3602
|
+
`Values: App ID "${input.appId}", search-only key ${input.searchKey ? `"${input.searchKey}"` : "(placeholder for the developer to fill in)"}.`,
|
|
3415
3603
|
// Names are fixed, not the agent's to rename: the wizard writes the
|
|
3416
3604
|
// resolved app id / search-only key into ".env" under these exact names
|
|
3417
3605
|
// right after this step, so a renamed prefix here would leave the code
|
|
3418
3606
|
// reading a var the wizard never wrote.
|
|
3419
3607
|
`Use exactly these public env var names in the code: ${input.searchEnvVars.map(({ name }) => name).join(", ")}.`,
|
|
3420
|
-
'Add any Algolia/InstantSearch packages you import to package.json "dependencies" with a valid version range; the wizard installs them in the worktree after you finish.'
|
|
3608
|
+
'Add any Algolia/InstantSearch packages you import to package.json "dependencies" with a valid version range; the wizard installs them in the worktree after you finish.',
|
|
3609
|
+
"The summary should be extremely concise; do not mention env var setup or manual testing steps \u2014 the wizard writes the resolved credentials to .env and reports that separately."
|
|
3421
3610
|
];
|
|
3422
3611
|
}
|
|
3423
3612
|
function verificationInstructions(input) {
|
|
@@ -3638,7 +3827,14 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
3638
3827
|
tools: toolsForUseCase(currentUseCase, input.ingestionSource),
|
|
3639
3828
|
outputSchema: implementationOutputSchema
|
|
3640
3829
|
});
|
|
3830
|
+
ctx.notify({
|
|
3831
|
+
messages: [`Installing dependencies for ${currentUseCase}\u2026`]
|
|
3832
|
+
});
|
|
3833
|
+
const installLogId = ctx.logStart("installWorktreeDeps", {
|
|
3834
|
+
useCase: currentUseCase
|
|
3835
|
+
});
|
|
3641
3836
|
const install = await installWorktreeDeps(worktree);
|
|
3837
|
+
ctx.logEnd(installLogId, install.ok ? "success" : "error");
|
|
3642
3838
|
if (!install.ok) {
|
|
3643
3839
|
installFailed = true;
|
|
3644
3840
|
logger.warn(
|
|
@@ -3672,6 +3868,11 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
3672
3868
|
}) === true;
|
|
3673
3869
|
if (runNow) {
|
|
3674
3870
|
const profile2 = await loadActiveProfile();
|
|
3871
|
+
ctx.notify({ messages: [`Writing records to "${targetIndex}"\u2026`] });
|
|
3872
|
+
const scriptLogId = ctx.logStart("runIngestScript", {
|
|
3873
|
+
runtime: ingestRuntime,
|
|
3874
|
+
entrypoint: ingestEntrypoint
|
|
3875
|
+
});
|
|
3675
3876
|
const startedAt = Date.now();
|
|
3676
3877
|
const run = await runIngestScript(
|
|
3677
3878
|
worktree,
|
|
@@ -3682,6 +3883,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
3682
3883
|
[API_KEY_VAR]: profile2.apiKey
|
|
3683
3884
|
}
|
|
3684
3885
|
);
|
|
3886
|
+
ctx.logEnd(scriptLogId, run.ok ? "success" : "error");
|
|
3685
3887
|
ingestScriptRan = run.ran && run.ok;
|
|
3686
3888
|
if (ingestScriptRan) {
|
|
3687
3889
|
ingestDurationMs = Date.now() - startedAt;
|
|
@@ -3959,7 +4161,7 @@ function getWorkflow(id) {
|
|
|
3959
4161
|
}
|
|
3960
4162
|
|
|
3961
4163
|
// src/main.tsx
|
|
3962
|
-
import { jsx as
|
|
4164
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
3963
4165
|
var requestedId = process.argv[2] ?? defaultWorkflow.id;
|
|
3964
4166
|
var workflow = getWorkflow(requestedId);
|
|
3965
4167
|
if (!workflow) {
|
|
@@ -3968,7 +4170,7 @@ if (!workflow) {
|
|
|
3968
4170
|
process.exit(1);
|
|
3969
4171
|
}
|
|
3970
4172
|
var store = useWizard.getState();
|
|
3971
|
-
var instance = render(/* @__PURE__ */
|
|
4173
|
+
var instance = render(/* @__PURE__ */ jsx14(App, {}), { incrementalRendering: true });
|
|
3972
4174
|
var user = await getUser();
|
|
3973
4175
|
if (!user) {
|
|
3974
4176
|
await instance.waitUntilRenderFlush();
|
|
@@ -3979,7 +4181,7 @@ if (!user) {
|
|
|
3979
4181
|
console.error(err instanceof Error ? err.message : String(err));
|
|
3980
4182
|
process.exit(1);
|
|
3981
4183
|
}
|
|
3982
|
-
instance = render(/* @__PURE__ */
|
|
4184
|
+
instance = render(/* @__PURE__ */ jsx14(App, {}), { incrementalRendering: true });
|
|
3983
4185
|
user = await getUser();
|
|
3984
4186
|
if (!user) {
|
|
3985
4187
|
store.setError(
|