@algolia/wizard 0.9.0-rc.71.62 → 0.9.0-rc.72.60
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 +359 -154
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -892,12 +892,12 @@ var sidebarItems = [
|
|
|
892
892
|
description: "push 100 records to Algolia in seconds"
|
|
893
893
|
},
|
|
894
894
|
{
|
|
895
|
-
title: "detect your
|
|
896
|
-
description: "React, Vue, Angular,
|
|
895
|
+
title: "detect your stack",
|
|
896
|
+
description: "React, Vue, Angular, Rails, Django, Laravel & more"
|
|
897
897
|
},
|
|
898
898
|
{
|
|
899
899
|
title: "scaffold a search UI",
|
|
900
|
-
description: "a styled InstantSearch
|
|
900
|
+
description: "a styled InstantSearch UI, wired into your app or templates"
|
|
901
901
|
},
|
|
902
902
|
{
|
|
903
903
|
title: "ship it",
|
|
@@ -1003,7 +1003,7 @@ var accessItems = [
|
|
|
1003
1003
|
{
|
|
1004
1004
|
tag: "READ",
|
|
1005
1005
|
title: "Project files",
|
|
1006
|
-
description: "reads package.json, configs & source to detect your stack. Read-only; nothing is uploaded."
|
|
1006
|
+
description: "reads your dependency manifests (package.json\u2026), configs & source to detect your stack. Read-only; nothing is uploaded."
|
|
1007
1007
|
},
|
|
1008
1008
|
{
|
|
1009
1009
|
tag: "WRITE",
|
|
@@ -2221,15 +2221,138 @@ function writeCredentialsTool(ctx) {
|
|
|
2221
2221
|
// src/lib/tools/searchFiles.ts
|
|
2222
2222
|
import { tool as tool7 } from "ai";
|
|
2223
2223
|
import z10 from "zod";
|
|
2224
|
-
import { readdir as readdir2, readFile as
|
|
2224
|
+
import { readdir as readdir2, readFile as readFile7 } from "node:fs/promises";
|
|
2225
|
+
import { join as join9 } from "node:path";
|
|
2226
|
+
|
|
2227
|
+
// src/lib/tools/utils/packageManager.ts
|
|
2228
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
2229
|
+
import { existsSync } from "node:fs";
|
|
2225
2230
|
import { join as join8 } from "node:path";
|
|
2231
|
+
var LOCKFILES = [
|
|
2232
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
2233
|
+
["yarn.lock", "yarn"],
|
|
2234
|
+
["bun.lockb", "bun"],
|
|
2235
|
+
["bun.lock", "bun"],
|
|
2236
|
+
["package-lock.json", "npm"]
|
|
2237
|
+
];
|
|
2238
|
+
async function readPackageJson(cwd = process.cwd()) {
|
|
2239
|
+
return JSON.parse(await readFile6(join8(cwd, "package.json"), "utf8"));
|
|
2240
|
+
}
|
|
2241
|
+
function packageManagerFrom(pkg) {
|
|
2242
|
+
return pkg.packageManager?.split("@")[0] ?? "npm";
|
|
2243
|
+
}
|
|
2244
|
+
function packageManagerFromLockfile(cwd) {
|
|
2245
|
+
return LOCKFILES.find(([file]) => existsSync(join8(cwd, file)))?.[1];
|
|
2246
|
+
}
|
|
2247
|
+
async function detectPackageManager(cwd) {
|
|
2248
|
+
try {
|
|
2249
|
+
const pkg = await readPackageJson(cwd);
|
|
2250
|
+
if (pkg.packageManager) return packageManagerFrom(pkg);
|
|
2251
|
+
} catch {
|
|
2252
|
+
}
|
|
2253
|
+
return packageManagerFromLockfile(cwd) ?? "npm";
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
// src/lib/shell.ts
|
|
2257
|
+
function shellQuote(value) {
|
|
2258
|
+
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
// src/lib/languages.ts
|
|
2262
|
+
var ENTRYPOINT_TOKEN = "{entrypoint}";
|
|
2263
|
+
var INGEST_DIR = ".algolia-wizard";
|
|
2264
|
+
var LANGUAGE_PROFILES = {
|
|
2265
|
+
javascript: {
|
|
2266
|
+
id: "javascript",
|
|
2267
|
+
displayName: "JavaScript/TypeScript",
|
|
2268
|
+
aliases: [
|
|
2269
|
+
"javascript",
|
|
2270
|
+
"js",
|
|
2271
|
+
"typescript",
|
|
2272
|
+
"ts",
|
|
2273
|
+
"node",
|
|
2274
|
+
"nodejs",
|
|
2275
|
+
"node.js",
|
|
2276
|
+
"bun",
|
|
2277
|
+
"deno",
|
|
2278
|
+
"ecmascript",
|
|
2279
|
+
"jsx",
|
|
2280
|
+
"tsx"
|
|
2281
|
+
],
|
|
2282
|
+
manifests: ["package.json"],
|
|
2283
|
+
// The concrete npm-family manager is resolved by detectPackageManager (it
|
|
2284
|
+
// honours the package.json `packageManager` field, which lockfiles can't
|
|
2285
|
+
// express), so one spec covers all four and `resolveToolchain` rewrites the
|
|
2286
|
+
// binary below.
|
|
2287
|
+
packageManagers: [
|
|
2288
|
+
{
|
|
2289
|
+
id: "npm",
|
|
2290
|
+
dependency: { mode: "agent-declares", file: "package.json" },
|
|
2291
|
+
installSteps: [{ argv: ["npm", "install"] }],
|
|
2292
|
+
ingest: {
|
|
2293
|
+
kind: "auto",
|
|
2294
|
+
argv: ["node", ENTRYPOINT_TOKEN],
|
|
2295
|
+
entrypointExtensions: [".mjs", ".cjs", ".js"]
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
],
|
|
2299
|
+
sdk: { packageName: "algoliasearch", versionPin: "^5", docKey: "js" },
|
|
2300
|
+
ingestEntrypointExample: `${INGEST_DIR}/ingest.mjs`,
|
|
2301
|
+
// package.json scripts are repo-defined, so they're resolved at run time by
|
|
2302
|
+
// repoVerification rather than listed here.
|
|
2303
|
+
verification: [],
|
|
2304
|
+
envReadInstruction: "Read them from `process.env`.",
|
|
2305
|
+
skipDirs: ["node_modules", "dist", "build", "coverage", ".next", "out"]
|
|
2306
|
+
}
|
|
2307
|
+
};
|
|
2308
|
+
var DEFAULT_LANGUAGE_ID = "javascript";
|
|
2309
|
+
var JAVASCRIPT = "javascript";
|
|
2310
|
+
var CURATED_LANGUAGES = Object.values(
|
|
2311
|
+
LANGUAGE_PROFILES
|
|
2312
|
+
).map((profile) => profile.displayName);
|
|
2313
|
+
function normalizeLanguageName(name) {
|
|
2314
|
+
return name.toLowerCase().trim().replace(/[\s_-]+/g, "");
|
|
2315
|
+
}
|
|
2316
|
+
var ALIAS_TO_ID = /* @__PURE__ */ new Map();
|
|
2317
|
+
for (const profile of Object.values(LANGUAGE_PROFILES)) {
|
|
2318
|
+
for (const alias of [profile.id, profile.displayName, ...profile.aliases]) {
|
|
2319
|
+
ALIAS_TO_ID.set(normalizeLanguageName(alias), profile.id);
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
function resolveLanguageProfile(name) {
|
|
2323
|
+
const id = ALIAS_TO_ID.get(normalizeLanguageName(name));
|
|
2324
|
+
return id ? LANGUAGE_PROFILES[id] : void 0;
|
|
2325
|
+
}
|
|
2326
|
+
function isSameLanguage(a, b) {
|
|
2327
|
+
const x = resolveLanguageProfile(a);
|
|
2328
|
+
const y = resolveLanguageProfile(b);
|
|
2329
|
+
if (x && y) return x.id === y.id;
|
|
2330
|
+
if (x || y) return false;
|
|
2331
|
+
const folded = normalizeLanguageName(a);
|
|
2332
|
+
return folded !== "" && folded === normalizeLanguageName(b);
|
|
2333
|
+
}
|
|
2334
|
+
var BASE_SKIP_DIRS = ["node_modules", ".git", "dist"];
|
|
2335
|
+
var ALL_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
2336
|
+
...BASE_SKIP_DIRS,
|
|
2337
|
+
...Object.values(LANGUAGE_PROFILES).flatMap((p) => p.skipDirs)
|
|
2338
|
+
]);
|
|
2339
|
+
var ALLOWED_BINARIES = new Set(
|
|
2340
|
+
Object.values(LANGUAGE_PROFILES).flatMap((profile) => [
|
|
2341
|
+
...profile.packageManagers.flatMap((pm) => [
|
|
2342
|
+
...pm.installSteps.map((s) => s.argv[0]),
|
|
2343
|
+
...pm.ingest.kind === "auto" ? [pm.ingest.argv[0]] : []
|
|
2344
|
+
]),
|
|
2345
|
+
...profile.verification.map((v) => v.argv[0])
|
|
2346
|
+
])
|
|
2347
|
+
);
|
|
2348
|
+
|
|
2349
|
+
// src/lib/tools/searchFiles.ts
|
|
2226
2350
|
var MAX_QUERY_LENGTH = 1e3;
|
|
2227
2351
|
async function walkFiles(dir) {
|
|
2228
|
-
const skip = /* @__PURE__ */ new Set(["node_modules", ".git", "dist"]);
|
|
2229
2352
|
const out = [];
|
|
2230
2353
|
for (const e of await readdir2(dir, { withFileTypes: true })) {
|
|
2231
|
-
if (e.name.startsWith(".") ||
|
|
2232
|
-
const full =
|
|
2354
|
+
if (e.name.startsWith(".") || ALL_SKIP_DIRS.has(e.name)) continue;
|
|
2355
|
+
const full = join9(dir, e.name);
|
|
2233
2356
|
if (e.isDirectory()) out.push(...await walkFiles(full));
|
|
2234
2357
|
else if (e.isFile()) out.push(full);
|
|
2235
2358
|
}
|
|
@@ -2262,7 +2385,7 @@ function searchFilesTool(ctx) {
|
|
|
2262
2385
|
for (const file of await walkFiles(resolved.target)) {
|
|
2263
2386
|
let content;
|
|
2264
2387
|
try {
|
|
2265
|
-
content = await
|
|
2388
|
+
content = await readFile7(file, "utf8");
|
|
2266
2389
|
} catch {
|
|
2267
2390
|
continue;
|
|
2268
2391
|
}
|
|
@@ -2286,6 +2409,10 @@ function searchFilesTool(ctx) {
|
|
|
2286
2409
|
import { tool as tool8 } from "ai";
|
|
2287
2410
|
import z11 from "zod";
|
|
2288
2411
|
|
|
2412
|
+
// src/lib/tools/repoVerification.ts
|
|
2413
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
2414
|
+
import { join as join10 } from "node:path";
|
|
2415
|
+
|
|
2289
2416
|
// src/lib/tools/utils/runCommand.ts
|
|
2290
2417
|
import { spawn as spawn2 } from "node:child_process";
|
|
2291
2418
|
var INSTALL_TIMEOUT_MS = 15 * 6e4;
|
|
@@ -2337,71 +2464,89 @@ Timed out after ${seconds}s: ${command} ${args.join(" ")}`.trim(),
|
|
|
2337
2464
|
});
|
|
2338
2465
|
}
|
|
2339
2466
|
|
|
2340
|
-
// src/lib/tools/utils/packageManager.ts
|
|
2341
|
-
import { readFile as readFile7 } from "node:fs/promises";
|
|
2342
|
-
import { existsSync } from "node:fs";
|
|
2343
|
-
import { join as join9 } from "node:path";
|
|
2344
|
-
var LOCKFILES = [
|
|
2345
|
-
["pnpm-lock.yaml", "pnpm"],
|
|
2346
|
-
["yarn.lock", "yarn"],
|
|
2347
|
-
["bun.lockb", "bun"],
|
|
2348
|
-
["bun.lock", "bun"],
|
|
2349
|
-
["package-lock.json", "npm"]
|
|
2350
|
-
];
|
|
2351
|
-
async function readPackageJson(cwd = process.cwd()) {
|
|
2352
|
-
return JSON.parse(await readFile7(join9(cwd, "package.json"), "utf8"));
|
|
2353
|
-
}
|
|
2354
|
-
function packageManagerFrom(pkg) {
|
|
2355
|
-
return pkg.packageManager?.split("@")[0] ?? "npm";
|
|
2356
|
-
}
|
|
2357
|
-
function packageManagerFromLockfile(cwd) {
|
|
2358
|
-
return LOCKFILES.find(([file]) => existsSync(join9(cwd, file)))?.[1];
|
|
2359
|
-
}
|
|
2360
|
-
async function detectPackageManager(cwd) {
|
|
2361
|
-
try {
|
|
2362
|
-
const pkg = await readPackageJson(cwd);
|
|
2363
|
-
if (pkg.packageManager) return packageManagerFrom(pkg);
|
|
2364
|
-
} catch {
|
|
2365
|
-
}
|
|
2366
|
-
return packageManagerFromLockfile(cwd) ?? "npm";
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
2467
|
// src/lib/tools/repoVerification.ts
|
|
2370
2468
|
var VERIFICATION_SCRIPT_CANDIDATES = ["lint", "typecheck", "check"];
|
|
2371
|
-
async function
|
|
2469
|
+
async function runCheck(command, binary, args) {
|
|
2470
|
+
const { code, output } = await runCommand(binary, args, {
|
|
2471
|
+
timeoutMs: VERIFY_TIMEOUT_MS
|
|
2472
|
+
});
|
|
2473
|
+
return { command, exitCode: code, ok: code === 0, output: output.trim() };
|
|
2474
|
+
}
|
|
2475
|
+
async function javascriptChecks() {
|
|
2372
2476
|
let pkg;
|
|
2373
2477
|
try {
|
|
2374
2478
|
pkg = await readPackageJson();
|
|
2375
2479
|
} catch (err) {
|
|
2376
|
-
|
|
2377
|
-
|
|
2480
|
+
return {
|
|
2481
|
+
limitation: `Could not read package.json to detect verification conventions: ${err.message}`
|
|
2482
|
+
};
|
|
2378
2483
|
}
|
|
2379
2484
|
const scripts = pkg.scripts ?? {};
|
|
2380
2485
|
const present = VERIFICATION_SCRIPT_CANDIDATES.filter((s) => s in scripts);
|
|
2381
2486
|
if (present.length === 0) {
|
|
2382
|
-
|
|
2383
|
-
|
|
2487
|
+
return {
|
|
2488
|
+
limitation: `No verification script found in package.json (looked for: ${VERIFICATION_SCRIPT_CANDIDATES.join(", ")}).`
|
|
2489
|
+
};
|
|
2384
2490
|
}
|
|
2385
2491
|
const pm = await detectPackageManager(process.cwd());
|
|
2386
2492
|
const checks = [];
|
|
2387
2493
|
for (const script of present) {
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2494
|
+
checks.push(
|
|
2495
|
+
await runCheck(`${pm} run ${script}`, pm, ["run", script])
|
|
2496
|
+
);
|
|
2497
|
+
}
|
|
2498
|
+
return { checks };
|
|
2499
|
+
}
|
|
2500
|
+
async function registryChecks(id) {
|
|
2501
|
+
const profile = LANGUAGE_PROFILES[id];
|
|
2502
|
+
const runnable = profile.verification.filter(
|
|
2503
|
+
(spec) => !spec.requiresFile || existsSync2(join10(process.cwd(), spec.requiresFile))
|
|
2504
|
+
);
|
|
2505
|
+
if (runnable.length === 0) {
|
|
2506
|
+
return {
|
|
2507
|
+
limitation: `No mechanical verification available for ${profile.displayName} in this repo.`
|
|
2508
|
+
};
|
|
2393
2509
|
}
|
|
2394
|
-
|
|
2510
|
+
const checks = [];
|
|
2511
|
+
for (const spec of runnable) {
|
|
2512
|
+
checks.push(
|
|
2513
|
+
await runCheck(spec.argv.join(" "), spec.argv[0], [...spec.argv.slice(1)])
|
|
2514
|
+
);
|
|
2515
|
+
}
|
|
2516
|
+
return { checks };
|
|
2517
|
+
}
|
|
2518
|
+
async function runRepoVerificationCheck(languages = [DEFAULT_LANGUAGE_ID]) {
|
|
2519
|
+
const ids = [...new Set(languages)];
|
|
2520
|
+
if (ids.length === 0) ids.push(DEFAULT_LANGUAGE_ID);
|
|
2521
|
+
const checks = [];
|
|
2522
|
+
const limitations = [];
|
|
2523
|
+
for (const id of ids) {
|
|
2524
|
+
const result = id === JAVASCRIPT ? await javascriptChecks() : await registryChecks(id);
|
|
2525
|
+
if ("checks" in result) checks.push(...result.checks);
|
|
2526
|
+
else limitations.push(result.limitation);
|
|
2527
|
+
}
|
|
2528
|
+
if (checks.length === 0) {
|
|
2529
|
+
return {
|
|
2530
|
+
ok: false,
|
|
2531
|
+
checks: [],
|
|
2532
|
+
limitation: limitations.join(" ") || "No verification checks available."
|
|
2533
|
+
};
|
|
2534
|
+
}
|
|
2535
|
+
return {
|
|
2536
|
+
ok: checks.every((c) => c.ok),
|
|
2537
|
+
checks,
|
|
2538
|
+
...limitations.length ? { limitation: limitations.join(" ") } : {}
|
|
2539
|
+
};
|
|
2395
2540
|
}
|
|
2396
2541
|
|
|
2397
2542
|
// src/lib/tools/verifyImplementation.ts
|
|
2398
|
-
function verifyImplementationTool() {
|
|
2543
|
+
function verifyImplementationTool(ctx) {
|
|
2399
2544
|
return tool8({
|
|
2400
|
-
description: "Run the repo's mechanical verification
|
|
2545
|
+
description: "Run the repo's mechanical verification checks for generated implementation changes. Uses the conventions of the repo's languages (package.json lint/typecheck/check scripts for JavaScript, the equivalent compile/analyze command elsewhere) and returns structured pass/fail evidence for the verifier to interpret.",
|
|
2401
2546
|
inputSchema: z11.object(),
|
|
2402
2547
|
execute: async () => {
|
|
2403
|
-
logger.info("called verifyImplementation tool");
|
|
2404
|
-
return runRepoVerificationCheck();
|
|
2548
|
+
logger.info({ languages: ctx.languages }, "called verifyImplementation tool");
|
|
2549
|
+
return runRepoVerificationCheck(ctx.languages);
|
|
2405
2550
|
}
|
|
2406
2551
|
});
|
|
2407
2552
|
}
|
|
@@ -2527,12 +2672,17 @@ var DEFAULT_TOOL_LIMITS = {
|
|
|
2527
2672
|
read: 20,
|
|
2528
2673
|
match: 100
|
|
2529
2674
|
};
|
|
2530
|
-
function createToolContext(
|
|
2675
|
+
function createToolContext({
|
|
2676
|
+
limits = DEFAULT_TOOL_LIMITS,
|
|
2677
|
+
cwd = process.cwd(),
|
|
2678
|
+
languages = [DEFAULT_LANGUAGE_ID]
|
|
2679
|
+
} = {}) {
|
|
2531
2680
|
return {
|
|
2532
2681
|
root: cwd,
|
|
2533
2682
|
cwd,
|
|
2534
2683
|
limits,
|
|
2535
|
-
counts: { list: 0, search: 0, read: 0 }
|
|
2684
|
+
counts: { list: 0, search: 0, read: 0 },
|
|
2685
|
+
languages: languages.length ? languages : [DEFAULT_LANGUAGE_ID]
|
|
2536
2686
|
};
|
|
2537
2687
|
}
|
|
2538
2688
|
|
|
@@ -2569,7 +2719,7 @@ function createTools(ctx, { output, tools }) {
|
|
|
2569
2719
|
searchFiles: withLogging("searchFiles", searchFilesTool(ctx)),
|
|
2570
2720
|
verifyImplementation: withLogging(
|
|
2571
2721
|
"verifyImplementation",
|
|
2572
|
-
verifyImplementationTool()
|
|
2722
|
+
verifyImplementationTool(ctx)
|
|
2573
2723
|
),
|
|
2574
2724
|
generateRecord: withLogging("generateRecord", generateRecordTool(ctx)),
|
|
2575
2725
|
notifyUser: withLogging("notifyUser", notifyUserTool())
|
|
@@ -2605,7 +2755,7 @@ async function runAgent(req) {
|
|
|
2605
2755
|
baseURL: PROXY_BASE_URL,
|
|
2606
2756
|
fetch: proxyFetch
|
|
2607
2757
|
});
|
|
2608
|
-
const toolContext = createToolContext();
|
|
2758
|
+
const toolContext = createToolContext({ languages: req.languages });
|
|
2609
2759
|
const readTools = ["readFile", "searchFiles", "listFiles"];
|
|
2610
2760
|
const hasReadTools = !req.tools || req.tools.some((t) => readTools.includes(t));
|
|
2611
2761
|
const instructions = [
|
|
@@ -2696,8 +2846,11 @@ var detectLanguageSchema = z16.object({
|
|
|
2696
2846
|
var detectLanguage = () => runAgent({
|
|
2697
2847
|
instructions: [
|
|
2698
2848
|
"Analyze the codebase and determine the programming languages and frameworks used",
|
|
2849
|
+
"Start from the dependency manifests: package.json.",
|
|
2850
|
+
"List the language that owns the backend/data code first \u2014 that is the one an ingestion script will be written in.",
|
|
2699
2851
|
"If a superset language is found, exclude the subset language. TS-over-JS.",
|
|
2700
2852
|
"If a meta-framework is used, exclude the framework. Next-over-React.",
|
|
2853
|
+
"Frameworks include backend and server-rendering frameworks (e.g. Rails, Django, Laravel, Symfony, Spring Boot, ASP.NET Core, Flask, Gin, Ktor) as well as frontend ones (React, Vue, Angular, Svelte) and mobile ones (Flutter, SwiftUI).",
|
|
2701
2854
|
"Return the exact version",
|
|
2702
2855
|
"Exclude things like CSS frameworks, build tools, or testing frameworks",
|
|
2703
2856
|
'Use as few tools as possible, but do not guess. If you cant find the answer, say "unknown"',
|
|
@@ -2795,7 +2948,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
2795
2948
|
// package.json
|
|
2796
2949
|
var package_default = {
|
|
2797
2950
|
name: "@algolia/wizard",
|
|
2798
|
-
version: "0.9.0-rc.
|
|
2951
|
+
version: "0.9.0-rc.72.60",
|
|
2799
2952
|
description: "Magically implement Algolia functionality in your codebase",
|
|
2800
2953
|
type: "module",
|
|
2801
2954
|
engines: {
|
|
@@ -2898,82 +3051,139 @@ function parseEntries(raw) {
|
|
|
2898
3051
|
return raw.split(",").map(clean).filter(Boolean).slice(0, MAX_ENTRIES).map((name) => ({ name, version: "unknown" }));
|
|
2899
3052
|
}
|
|
2900
3053
|
var summarize = (entries) => entries.length ? entries.map((e) => e.name).join(", ") : "none";
|
|
2901
|
-
|
|
3054
|
+
|
|
3055
|
+
// src/actions/confirmLanguage.ts
|
|
3056
|
+
import z19 from "zod";
|
|
3057
|
+
var confirmLanguageSchema = z19.object({
|
|
3058
|
+
languages: detectLanguageSchema.shape.languages
|
|
3059
|
+
});
|
|
3060
|
+
var OTHER_OPTION = "Other";
|
|
3061
|
+
function confirmed(languages) {
|
|
3062
|
+
track("AI Wizard Language Confirmed", { languages });
|
|
3063
|
+
return { languages };
|
|
3064
|
+
}
|
|
3065
|
+
async function askOtherLanguage(ctx) {
|
|
3066
|
+
let prompt = "enter the language for your ingestion script";
|
|
2902
3067
|
for (; ; ) {
|
|
2903
3068
|
const answer = await ctx.requestUserInput({
|
|
2904
3069
|
prompt,
|
|
2905
3070
|
promptType: "textInput",
|
|
2906
|
-
options: []
|
|
2907
|
-
helpText: 'Comma-separated, e.g. "TypeScript, Node".'
|
|
3071
|
+
options: []
|
|
2908
3072
|
});
|
|
2909
3073
|
if (typeof answer !== "string") {
|
|
2910
|
-
throw new Error("
|
|
3074
|
+
throw new Error("confirmLanguage received an unexpected non-text result");
|
|
2911
3075
|
}
|
|
2912
|
-
const
|
|
2913
|
-
if (
|
|
2914
|
-
prompt = "
|
|
3076
|
+
const name = parseEntries(answer)[0]?.name;
|
|
3077
|
+
if (name) return name;
|
|
3078
|
+
prompt = "please enter a language name:";
|
|
2915
3079
|
}
|
|
2916
3080
|
}
|
|
2917
|
-
|
|
2918
|
-
// src/actions/confirmLanguage.ts
|
|
2919
|
-
import z19 from "zod";
|
|
2920
|
-
var confirmLanguageSchema = z19.object({
|
|
2921
|
-
languages: detectLanguageSchema.shape.languages
|
|
2922
|
-
});
|
|
2923
3081
|
async function confirmLanguage(ctx) {
|
|
2924
3082
|
const detected = ctx.getStepOutput("project-scan");
|
|
2925
|
-
const
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
3083
|
+
const detectedLanguages = detected.languages ?? [];
|
|
3084
|
+
const others = (chosen) => detectedLanguages.filter((l) => !isSameLanguage(l.name, chosen));
|
|
3085
|
+
const primary = detectedLanguages[0];
|
|
3086
|
+
if (primary) {
|
|
3087
|
+
const accepted = await ctx.requestUserInput({
|
|
3088
|
+
prompt: `Write the ingestion script in ${primary.name}?`,
|
|
3089
|
+
promptType: "acceptReject",
|
|
3090
|
+
options: [`Confirm ${primary.name}`, "Use a different language"],
|
|
3091
|
+
secondary: [{ kind: "badge", value: "[DETECTED]" }, void 0],
|
|
3092
|
+
messages: detectedLanguages.length > 1 ? [`Detected: ${summarize(detectedLanguages)}`] : []
|
|
3093
|
+
});
|
|
3094
|
+
if (accepted === true) return confirmed(detectedLanguages);
|
|
3095
|
+
}
|
|
3096
|
+
const options = [...CURATED_LANGUAGES];
|
|
3097
|
+
for (const language of detectedLanguages) {
|
|
3098
|
+
if (!options.some((o) => isSameLanguage(o, language.name))) {
|
|
3099
|
+
options.push(language.name);
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
options.push(OTHER_OPTION);
|
|
3103
|
+
const detectedFor = (option) => detectedLanguages.find((l) => isSameLanguage(option, l.name));
|
|
3104
|
+
const secondary = options.map(
|
|
3105
|
+
(o) => detectedFor(o) ? { kind: "badge", value: "[DETECTED]" } : void 0
|
|
3106
|
+
);
|
|
3107
|
+
const defaultSelectedIndex = Math.max(
|
|
3108
|
+
options.findIndex((o) => detectedFor(o)),
|
|
3109
|
+
0
|
|
3110
|
+
);
|
|
3111
|
+
const selection = await ctx.requestUserInput({
|
|
3112
|
+
prompt: "select the language for your ingestion script",
|
|
3113
|
+
promptType: "multipleChoice",
|
|
3114
|
+
options,
|
|
3115
|
+
secondary,
|
|
3116
|
+
defaultSelectedIndex
|
|
2936
3117
|
});
|
|
2937
|
-
|
|
3118
|
+
if (typeof selection !== "string") {
|
|
3119
|
+
throw new Error("confirmLanguage received an unexpected non-text result");
|
|
3120
|
+
}
|
|
3121
|
+
const name = selection === OTHER_OPTION ? await askOtherLanguage(ctx) : selection;
|
|
3122
|
+
const version = detectedFor(name)?.version ?? "unknown";
|
|
3123
|
+
return confirmed([{ name, version }, ...others(name)]);
|
|
2938
3124
|
}
|
|
2939
3125
|
|
|
2940
3126
|
// src/actions/confirmFramework.ts
|
|
2941
3127
|
import z20 from "zod";
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
var
|
|
2946
|
-
|
|
2947
|
-
"
|
|
2948
|
-
"
|
|
2949
|
-
"
|
|
2950
|
-
"
|
|
2951
|
-
|
|
3128
|
+
|
|
3129
|
+
// src/lib/frameworks.ts
|
|
3130
|
+
var BACKEND_ONLY_FRAMEWORK = "Backend only / API";
|
|
3131
|
+
var FRAMEWORKS = [
|
|
3132
|
+
// Frontend — InstantSearch component flavors.
|
|
3133
|
+
{ name: "Next.js", strategy: "react", aliases: ["next", "nextjs"] },
|
|
3134
|
+
{ name: "React", strategy: "react", aliases: ["reactjs"] },
|
|
3135
|
+
{ name: "Vue", strategy: "vue", aliases: ["vuejs", "nuxt", "nuxtjs"] },
|
|
3136
|
+
{ name: "Angular", strategy: "angular", aliases: ["angularjs"] },
|
|
3137
|
+
// No Svelte InstantSearch flavor exists, so it uses InstantSearch.js.
|
|
3138
|
+
{ name: "Svelte", strategy: "js", aliases: ["sveltekit"] },
|
|
3139
|
+
{
|
|
3140
|
+
name: "Vanilla JS",
|
|
3141
|
+
strategy: "js",
|
|
3142
|
+
aliases: ["vanilla", "javascript", "js", "astro", "vite"]
|
|
3143
|
+
},
|
|
3144
|
+
// Backend — Algolia's official framework integrations. Server-rendered
|
|
3145
|
+
// templates get InstantSearch.js from a CDN.
|
|
3146
|
+
{
|
|
3147
|
+
name: "Rails",
|
|
3148
|
+
strategy: "cdn-template",
|
|
3149
|
+
aliases: ["rubyonrails", "ruby on rails", "erb"]
|
|
3150
|
+
},
|
|
3151
|
+
{ name: "Django", strategy: "cdn-template", aliases: ["jinja", "jinja2"] },
|
|
3152
|
+
{ name: "Laravel", strategy: "cdn-template", aliases: ["blade"] },
|
|
3153
|
+
{ name: "Symfony", strategy: "cdn-template", aliases: ["twig"] },
|
|
3154
|
+
// Mobile — Algolia ships InstantSearch iOS/Android and Dart clients, but the
|
|
3155
|
+
// wizard can't scaffold a native UI, so it points at the docs instead.
|
|
3156
|
+
{ name: "Flutter", strategy: "none", aliases: [] },
|
|
3157
|
+
{ name: "iOS", strategy: "none", aliases: ["swiftui", "uikit"] },
|
|
3158
|
+
{ name: "Android", strategy: "none", aliases: ["jetpack compose", "compose"] },
|
|
3159
|
+
{ name: BACKEND_ONLY_FRAMEWORK, strategy: "cdn-template", aliases: [] }
|
|
2952
3160
|
];
|
|
2953
|
-
var
|
|
3161
|
+
var CURATED_FRAMEWORKS = FRAMEWORKS.map(
|
|
3162
|
+
(f) => f.name
|
|
3163
|
+
);
|
|
2954
3164
|
var normalize = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
2955
|
-
var
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
javascript: "vanillajs",
|
|
2969
|
-
js: "vanillajs"
|
|
2970
|
-
};
|
|
2971
|
-
var isSameFramework = (a, b) => {
|
|
2972
|
-
const x = FRAMEWORK_ALIASES[normalize(a)] ?? normalize(a);
|
|
2973
|
-
const y = FRAMEWORK_ALIASES[normalize(b)] ?? normalize(b);
|
|
3165
|
+
var ALIAS_TO_NAME = /* @__PURE__ */ new Map();
|
|
3166
|
+
for (const framework of FRAMEWORKS) {
|
|
3167
|
+
for (const alias of [framework.name, ...framework.aliases]) {
|
|
3168
|
+
ALIAS_TO_NAME.set(normalize(alias), framework.name);
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
var STRATEGY_BY_NAME = new Map(FRAMEWORKS.map((f) => [f.name, f.strategy]));
|
|
3172
|
+
function canonicalFrameworkName(name) {
|
|
3173
|
+
return ALIAS_TO_NAME.get(normalize(name));
|
|
3174
|
+
}
|
|
3175
|
+
function isSameFramework(a, b) {
|
|
3176
|
+
const x = canonicalFrameworkName(a) ?? normalize(a);
|
|
3177
|
+
const y = canonicalFrameworkName(b) ?? normalize(b);
|
|
2974
3178
|
return x !== "" && x === y;
|
|
2975
|
-
}
|
|
2976
|
-
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
// src/actions/confirmFramework.ts
|
|
3182
|
+
var confirmFrameworkSchema = z20.object({
|
|
3183
|
+
frameworks: detectLanguageSchema.shape.frameworks
|
|
3184
|
+
});
|
|
3185
|
+
var OTHER_OPTION2 = "Other";
|
|
3186
|
+
function confirmed2(name, version) {
|
|
2977
3187
|
const frameworks = [{ name, version: version ?? "unknown" }];
|
|
2978
3188
|
track("AI Wizard Frontend Framework Confirmed", { frameworks });
|
|
2979
3189
|
return { frameworks };
|
|
@@ -3001,7 +3211,7 @@ async function confirmFramework(ctx) {
|
|
|
3001
3211
|
for (const fw of detectedFrameworks) {
|
|
3002
3212
|
if (!options.some((o) => isSameFramework(o, fw.name))) options.push(fw.name);
|
|
3003
3213
|
}
|
|
3004
|
-
options.push(
|
|
3214
|
+
options.push(OTHER_OPTION2);
|
|
3005
3215
|
const detectedFor = (option) => detectedFrameworks.find((fw) => isSameFramework(option, fw.name));
|
|
3006
3216
|
const primary = detectedFrameworks[0];
|
|
3007
3217
|
if (primary) {
|
|
@@ -3011,7 +3221,7 @@ async function confirmFramework(ctx) {
|
|
|
3011
3221
|
options: [`Confirm ${primary.name}`, "Use a different framework"],
|
|
3012
3222
|
secondary: [{ kind: "badge", value: "[DETECTED]" }, void 0]
|
|
3013
3223
|
});
|
|
3014
|
-
if (accepted === true) return
|
|
3224
|
+
if (accepted === true) return confirmed2(primary.name, primary.version);
|
|
3015
3225
|
}
|
|
3016
3226
|
const secondary = options.map(
|
|
3017
3227
|
(o) => detectedFor(o) ? { kind: "badge", value: "[DETECTED]" } : void 0
|
|
@@ -3021,7 +3231,7 @@ async function confirmFramework(ctx) {
|
|
|
3021
3231
|
0
|
|
3022
3232
|
);
|
|
3023
3233
|
const selection = await ctx.requestUserInput({
|
|
3024
|
-
prompt: "select
|
|
3234
|
+
prompt: "select the framework that renders your UI",
|
|
3025
3235
|
promptType: "multipleChoice",
|
|
3026
3236
|
options,
|
|
3027
3237
|
secondary,
|
|
@@ -3030,10 +3240,10 @@ async function confirmFramework(ctx) {
|
|
|
3030
3240
|
if (typeof selection !== "string") {
|
|
3031
3241
|
throw new Error("confirmFramework received an unexpected non-text result");
|
|
3032
3242
|
}
|
|
3033
|
-
if (selection ===
|
|
3034
|
-
return
|
|
3243
|
+
if (selection === OTHER_OPTION2) {
|
|
3244
|
+
return confirmed2(await askOtherFramework(ctx));
|
|
3035
3245
|
}
|
|
3036
|
-
return
|
|
3246
|
+
return confirmed2(selection, detectedFor(selection)?.version);
|
|
3037
3247
|
}
|
|
3038
3248
|
|
|
3039
3249
|
// src/actions/promptUser.ts
|
|
@@ -3126,15 +3336,15 @@ async function confirmEntities(ctx) {
|
|
|
3126
3336
|
onSubmit: () => {
|
|
3127
3337
|
}
|
|
3128
3338
|
});
|
|
3129
|
-
const
|
|
3130
|
-
if (
|
|
3339
|
+
const confirmed3 = typeof selection === "string" ? entities.filter((e) => e.name === selection) : [];
|
|
3340
|
+
if (confirmed3.length === 0) {
|
|
3131
3341
|
throw new Error("User cancelled entity selection \u2014 analysis halted.");
|
|
3132
3342
|
}
|
|
3133
|
-
ctx.setUserInput("confirmedEntities",
|
|
3343
|
+
ctx.setUserInput("confirmedEntities", confirmed3);
|
|
3134
3344
|
track("AI Wizard Entities Confirmed", {
|
|
3135
|
-
entities: toEntitySummary(
|
|
3345
|
+
entities: toEntitySummary(confirmed3)
|
|
3136
3346
|
});
|
|
3137
|
-
return { ingestionAnalysis: entities, confirmedEntities:
|
|
3347
|
+
return { ingestionAnalysis: entities, confirmedEntities: confirmed3 };
|
|
3138
3348
|
}
|
|
3139
3349
|
|
|
3140
3350
|
// src/actions/review.ts
|
|
@@ -3206,7 +3416,7 @@ import {
|
|
|
3206
3416
|
basename as basename2,
|
|
3207
3417
|
dirname as dirname7,
|
|
3208
3418
|
isAbsolute as isAbsolute2,
|
|
3209
|
-
join as
|
|
3419
|
+
join as join11,
|
|
3210
3420
|
relative as relative2,
|
|
3211
3421
|
resolve as resolve3
|
|
3212
3422
|
} from "node:path";
|
|
@@ -3240,7 +3450,7 @@ async function isWorkingTreeDirty(repoRoot) {
|
|
|
3240
3450
|
return out.trim().length > 0;
|
|
3241
3451
|
}
|
|
3242
3452
|
async function pruneOldWorktrees(repoRoot) {
|
|
3243
|
-
const dir =
|
|
3453
|
+
const dir = join11(stateDir(repoRoot), "worktrees");
|
|
3244
3454
|
const stale = (await readdir3(dir).catch(() => [])).filter((name) => /^wizard-implement-\d+$/.test(name)).sort().reverse().slice(MAX_WIZARD_WORKTREES - 1);
|
|
3245
3455
|
for (const slug of stale) {
|
|
3246
3456
|
const branch = slug.replace("wizard-implement-", WIZARD_BRANCH_PREFIX);
|
|
@@ -3251,7 +3461,7 @@ async function pruneOldWorktrees(repoRoot) {
|
|
|
3251
3461
|
"worktree",
|
|
3252
3462
|
"remove",
|
|
3253
3463
|
"--force",
|
|
3254
|
-
|
|
3464
|
+
join11(dir, slug)
|
|
3255
3465
|
]);
|
|
3256
3466
|
await git(["-C", repoRoot, "branch", "-D", branch]);
|
|
3257
3467
|
} catch (err) {
|
|
@@ -3265,7 +3475,7 @@ async function pruneOldWorktrees(repoRoot) {
|
|
|
3265
3475
|
async function createWorktree(repoRoot) {
|
|
3266
3476
|
const branch = `${WIZARD_BRANCH_PREFIX}${Date.now()}`;
|
|
3267
3477
|
const dirSlug = branch.replace(/\//g, "-");
|
|
3268
|
-
const path =
|
|
3478
|
+
const path = join11(stateDir(repoRoot), "worktrees", dirSlug);
|
|
3269
3479
|
await git(["-C", repoRoot, "worktree", "prune"]);
|
|
3270
3480
|
await pruneOldWorktrees(repoRoot);
|
|
3271
3481
|
await mkdir6(dirname7(path), { recursive: true });
|
|
@@ -3385,8 +3595,8 @@ async function copyUploadIntoWorktree(repoRoot, worktreePath, ingestDir, sourceP
|
|
|
3385
3595
|
} catch {
|
|
3386
3596
|
return { ok: false, reason: `"${sourcePath}" does not exist` };
|
|
3387
3597
|
}
|
|
3388
|
-
const relPath =
|
|
3389
|
-
const dest =
|
|
3598
|
+
const relPath = join11(ingestDir, basename2(source));
|
|
3599
|
+
const dest = join11(worktreePath, relPath);
|
|
3390
3600
|
try {
|
|
3391
3601
|
await mkdir6(dirname7(dest), { recursive: true });
|
|
3392
3602
|
await copyFile(source, dest);
|
|
@@ -3402,7 +3612,7 @@ function hasEnvVar(content, name) {
|
|
|
3402
3612
|
return new RegExp(`^(\\s*(?:export\\s+)?${name})\\s*=`, "m").test(content);
|
|
3403
3613
|
}
|
|
3404
3614
|
async function writeSearchEnvValues(worktreePath, vars) {
|
|
3405
|
-
const target =
|
|
3615
|
+
const target = join11(worktreePath, ".env");
|
|
3406
3616
|
let existing = "";
|
|
3407
3617
|
try {
|
|
3408
3618
|
existing = await readFile8(target, "utf8");
|
|
@@ -3522,15 +3732,15 @@ async function resolveSearchOnlyKey(index) {
|
|
|
3522
3732
|
}
|
|
3523
3733
|
|
|
3524
3734
|
// src/lib/algoliaDocs.ts
|
|
3525
|
-
import { readFileSync, readdirSync, existsSync as
|
|
3526
|
-
import { dirname as dirname8, join as
|
|
3735
|
+
import { readFileSync, readdirSync, existsSync as existsSync3 } from "node:fs";
|
|
3736
|
+
import { dirname as dirname8, join as join12 } from "node:path";
|
|
3527
3737
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
3528
|
-
var DOCS_SUBPATH =
|
|
3738
|
+
var DOCS_SUBPATH = join12("docs", "algolia-sdk");
|
|
3529
3739
|
function findDocsDir() {
|
|
3530
3740
|
let dir = dirname8(fileURLToPath2(import.meta.url));
|
|
3531
3741
|
for (; ; ) {
|
|
3532
|
-
const candidate =
|
|
3533
|
-
if (
|
|
3742
|
+
const candidate = join12(dir, DOCS_SUBPATH);
|
|
3743
|
+
if (existsSync3(candidate)) return candidate;
|
|
3534
3744
|
const parent = dirname8(dir);
|
|
3535
3745
|
if (parent === dir) return void 0;
|
|
3536
3746
|
dir = parent;
|
|
@@ -3552,7 +3762,7 @@ function loadAlgoliaDoc(language) {
|
|
|
3552
3762
|
);
|
|
3553
3763
|
return "";
|
|
3554
3764
|
}
|
|
3555
|
-
return readFileSync(
|
|
3765
|
+
return readFileSync(join12(docsDir, files[0]), "utf8").trim();
|
|
3556
3766
|
}
|
|
3557
3767
|
function getNamedDoc(name, language) {
|
|
3558
3768
|
const docsDir = findDocsDir();
|
|
@@ -3560,8 +3770,8 @@ function getNamedDoc(name, language) {
|
|
|
3560
3770
|
logger.warn("docs/algolia-sdk not found");
|
|
3561
3771
|
return "";
|
|
3562
3772
|
}
|
|
3563
|
-
const file =
|
|
3564
|
-
if (!
|
|
3773
|
+
const file = join12(docsDir, `${name}-${language}.md`);
|
|
3774
|
+
if (!existsSync3(file)) {
|
|
3565
3775
|
logger.warn({ name, language }, "named SDK reference not found");
|
|
3566
3776
|
return "";
|
|
3567
3777
|
}
|
|
@@ -3581,11 +3791,6 @@ function getFrameworkSpecificDoc(frameworks) {
|
|
|
3581
3791
|
return loadAlgoliaDoc("js");
|
|
3582
3792
|
}
|
|
3583
3793
|
|
|
3584
|
-
// src/lib/shell.ts
|
|
3585
|
-
function shellQuote(value) {
|
|
3586
|
-
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
3587
|
-
}
|
|
3588
|
-
|
|
3589
3794
|
// src/actions/implement.ts
|
|
3590
3795
|
var implementSchema = z24.object({
|
|
3591
3796
|
filesChanged: z24.array(z24.string()),
|
|
@@ -3634,7 +3839,7 @@ var verificationOutputSchema = z24.object({
|
|
|
3634
3839
|
});
|
|
3635
3840
|
var MAX_IMPLEMENT_VERIFICATION_ATTEMPTS = 3;
|
|
3636
3841
|
var DEFAULT_IMPLEMENT_USE_CASES = ["ingestion", "search"];
|
|
3637
|
-
var
|
|
3842
|
+
var INGEST_DIR2 = ".algolia-wizard";
|
|
3638
3843
|
function detectUiFramework(language) {
|
|
3639
3844
|
const names = language.frameworks.map((f) => f.name.toLowerCase());
|
|
3640
3845
|
if (names.some((n) => n.includes("vue") || n.includes("nuxt"))) return "Vue";
|
|
@@ -3898,7 +4103,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
3898
4103
|
await confirmDirtyWorkingTree(ctx, repoRoot);
|
|
3899
4104
|
}
|
|
3900
4105
|
const normalized = normalizeFindingPaths(findings);
|
|
3901
|
-
const
|
|
4106
|
+
const confirmed3 = normalized.confirmedEntities;
|
|
3902
4107
|
const searchLocation = normalized.searchImplementationAnalysis;
|
|
3903
4108
|
let appId;
|
|
3904
4109
|
let searchKey;
|
|
@@ -3922,7 +4127,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
3922
4127
|
const copied = await copyUploadIntoWorktree(
|
|
3923
4128
|
repoRoot,
|
|
3924
4129
|
worktree,
|
|
3925
|
-
|
|
4130
|
+
INGEST_DIR2,
|
|
3926
4131
|
uploadSourcePath ?? ""
|
|
3927
4132
|
);
|
|
3928
4133
|
if (copied.ok) {
|
|
@@ -3938,14 +4143,14 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
3938
4143
|
}
|
|
3939
4144
|
const input = {
|
|
3940
4145
|
findings: normalized,
|
|
3941
|
-
confirmed:
|
|
4146
|
+
confirmed: confirmed3,
|
|
3942
4147
|
searchLocation,
|
|
3943
4148
|
targetIndex,
|
|
3944
4149
|
language,
|
|
3945
4150
|
appId,
|
|
3946
4151
|
searchKey,
|
|
3947
4152
|
searchEnvVars: searchEnvVars(language, appId, searchKey),
|
|
3948
|
-
ingestDir:
|
|
4153
|
+
ingestDir: INGEST_DIR2,
|
|
3949
4154
|
ingestionSource,
|
|
3950
4155
|
uploadFilePath,
|
|
3951
4156
|
// language.frameworks already prefers the confirm-framework step output,
|
|
@@ -4037,7 +4242,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
4037
4242
|
ingestRecordCount = parseIngestRecordCount(run2.output);
|
|
4038
4243
|
if (ingestRecordCount != null) {
|
|
4039
4244
|
track("AI Wizard Ingest Successful", {
|
|
4040
|
-
entity_name:
|
|
4245
|
+
entity_name: confirmed3?.map((e) => e.name).join(", ") || "unknown",
|
|
4041
4246
|
record_count: ingestRecordCount,
|
|
4042
4247
|
duration_ms: ingestDurationMs
|
|
4043
4248
|
});
|
|
@@ -4518,7 +4723,7 @@ function parseCliArgs(argv) {
|
|
|
4518
4723
|
|
|
4519
4724
|
// src/lib/resetState.ts
|
|
4520
4725
|
import { readdir as readdir4, rm as rm2 } from "node:fs/promises";
|
|
4521
|
-
import { join as
|
|
4726
|
+
import { join as join13 } from "node:path";
|
|
4522
4727
|
var KEEP = ["wizard.log"];
|
|
4523
4728
|
async function resetProjectState() {
|
|
4524
4729
|
const dir = stateDir();
|
|
@@ -4530,7 +4735,7 @@ async function resetProjectState() {
|
|
|
4530
4735
|
}
|
|
4531
4736
|
const targets = entries.filter((name) => !KEEP.includes(name));
|
|
4532
4737
|
await Promise.all(
|
|
4533
|
-
targets.map((name) => rm2(
|
|
4738
|
+
targets.map((name) => rm2(join13(dir, name), { recursive: true, force: true }))
|
|
4534
4739
|
);
|
|
4535
4740
|
return { dir, removed: targets };
|
|
4536
4741
|
}
|