@algolia/wizard 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +158 -81
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2246,7 +2246,7 @@ async function ensureApplication() {
|
|
|
2246
2246
|
}
|
|
2247
2247
|
|
|
2248
2248
|
// src/workflows/default.ts
|
|
2249
|
-
import { z as
|
|
2249
|
+
import { z as z29 } from "zod";
|
|
2250
2250
|
|
|
2251
2251
|
// src/actions/listIndices.ts
|
|
2252
2252
|
import { z as z5 } from "zod";
|
|
@@ -2980,6 +2980,15 @@ import { tool as tool8 } from "ai";
|
|
|
2980
2980
|
import z15 from "zod";
|
|
2981
2981
|
import { relative as relative4 } from "node:path";
|
|
2982
2982
|
|
|
2983
|
+
// src/lib/tools/utils/prompt.ts
|
|
2984
|
+
var chain = Promise.resolve();
|
|
2985
|
+
function serializePrompt(work) {
|
|
2986
|
+
const result = chain.then(work);
|
|
2987
|
+
chain = result.catch(() => {
|
|
2988
|
+
});
|
|
2989
|
+
return result;
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2983
2992
|
// src/lib/tools/utils/runShell.ts
|
|
2984
2993
|
import { spawn as spawn2 } from "node:child_process";
|
|
2985
2994
|
|
|
@@ -3010,7 +3019,8 @@ function createToolContext(limits = DEFAULT_TOOL_LIMITS, cwd = process.cwd(), sh
|
|
|
3010
3019
|
cwd,
|
|
3011
3020
|
limits: { ...limits },
|
|
3012
3021
|
counts: { list: 0, search: 0, read: 0, shell: 0 },
|
|
3013
|
-
shell: shell2
|
|
3022
|
+
shell: shell2,
|
|
3023
|
+
reviewed: []
|
|
3014
3024
|
};
|
|
3015
3025
|
}
|
|
3016
3026
|
|
|
@@ -3088,13 +3098,6 @@ function storeApproval(root) {
|
|
|
3088
3098
|
return answer === "approve" ? "approve" : "reject";
|
|
3089
3099
|
};
|
|
3090
3100
|
}
|
|
3091
|
-
var shellChain = Promise.resolve();
|
|
3092
|
-
function serialize(work) {
|
|
3093
|
-
const result = shellChain.then(work);
|
|
3094
|
-
shellChain = result.catch(() => {
|
|
3095
|
-
});
|
|
3096
|
-
return result;
|
|
3097
|
-
}
|
|
3098
3101
|
async function approveAndRun(ctx, command, cwd, explanation) {
|
|
3099
3102
|
const decision = await ctx.shell.approve({ command, cwd, explanation });
|
|
3100
3103
|
if (decision === "reject") {
|
|
@@ -3158,20 +3161,81 @@ function runShellTool(ctx) {
|
|
|
3158
3161
|
const resolved2 = resolveInRoot(ctx, cwd ?? ".");
|
|
3159
3162
|
if (!resolved2.ok) return resolved2.error;
|
|
3160
3163
|
logger.info({ command, cwd: resolved2.target }, "called runShell tool");
|
|
3161
|
-
return
|
|
3164
|
+
return serializePrompt(
|
|
3162
3165
|
() => approveAndRun(ctx, command, resolved2.target, explanation)
|
|
3163
3166
|
);
|
|
3164
3167
|
}
|
|
3165
3168
|
});
|
|
3166
3169
|
}
|
|
3167
3170
|
|
|
3171
|
+
// src/lib/tools/reviewScript.ts
|
|
3172
|
+
import { tool as tool9 } from "ai";
|
|
3173
|
+
import z16 from "zod";
|
|
3174
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
3175
|
+
import { relative as relative5 } from "node:path";
|
|
3176
|
+
|
|
3177
|
+
// src/lib/editor.ts
|
|
3178
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
3179
|
+
function openInEditor(filePath) {
|
|
3180
|
+
const { command, args } = process.platform === "darwin" ? (
|
|
3181
|
+
// -t forces the default *text* editor; plain `open` on an extension
|
|
3182
|
+
// with no handler (.mjs, .py) pops a "choose an application" dialog.
|
|
3183
|
+
{ command: "open", args: ["-t", filePath] }
|
|
3184
|
+
) : process.platform === "win32" ? { command: "cmd", args: ["/c", "start", "", filePath] } : { command: "xdg-open", args: [filePath] };
|
|
3185
|
+
try {
|
|
3186
|
+
const child = spawn3(command, args, { stdio: "ignore", detached: true });
|
|
3187
|
+
child.on("error", () => {
|
|
3188
|
+
});
|
|
3189
|
+
child.unref();
|
|
3190
|
+
} catch {
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
|
|
3194
|
+
// src/lib/tools/reviewScript.ts
|
|
3195
|
+
function reviewScriptTool(ctx) {
|
|
3196
|
+
return tool9({
|
|
3197
|
+
description: "Show a script you have written to the user and wait while they read it. Call this as soon as the script is finished and before you run it for the first time, so nothing with a side effect happens behind their back. It opens the file in their editor and returns once they have confirmed.",
|
|
3198
|
+
inputSchema: z16.object({
|
|
3199
|
+
filePath: z16.string().describe(
|
|
3200
|
+
"Path to the script to review, relative to the project root."
|
|
3201
|
+
)
|
|
3202
|
+
}),
|
|
3203
|
+
execute: async ({ filePath }) => {
|
|
3204
|
+
logger.info({ filePath }, "called reviewScript tool");
|
|
3205
|
+
const resolved2 = resolveInRoot(ctx, filePath);
|
|
3206
|
+
if (resolved2.ok === false) return resolved2.error;
|
|
3207
|
+
const isFile = await stat2(resolved2.target).then(
|
|
3208
|
+
(s) => s.isFile(),
|
|
3209
|
+
() => false
|
|
3210
|
+
);
|
|
3211
|
+
if (!isFile) {
|
|
3212
|
+
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
3213
|
+
}
|
|
3214
|
+
return serializePrompt(async () => {
|
|
3215
|
+
openInEditor(resolved2.target);
|
|
3216
|
+
await useWizard.getState().requestUserInput({
|
|
3217
|
+
prompt: "",
|
|
3218
|
+
promptType: "enterToContinue",
|
|
3219
|
+
options: [],
|
|
3220
|
+
messages: [
|
|
3221
|
+
`Please review ${relative5(ctx.root, resolved2.target)} before it runs:`,
|
|
3222
|
+
resolved2.target
|
|
3223
|
+
]
|
|
3224
|
+
});
|
|
3225
|
+
ctx.reviewed.push(resolved2.target);
|
|
3226
|
+
return "The user has reviewed the script. You may run it now.";
|
|
3227
|
+
});
|
|
3228
|
+
}
|
|
3229
|
+
});
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3168
3232
|
// src/lib/tools/generateRecord.ts
|
|
3169
|
-
import { tool as
|
|
3233
|
+
import { tool as tool10, generateText, Output, NoObjectGeneratedError } from "ai";
|
|
3170
3234
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
3171
3235
|
import { nanoid as nanoid2 } from "nanoid";
|
|
3172
3236
|
import { mkdir as mkdir5, writeFile as writeFile6 } from "node:fs/promises";
|
|
3173
3237
|
import { dirname as dirname6 } from "node:path";
|
|
3174
|
-
import
|
|
3238
|
+
import z17 from "zod";
|
|
3175
3239
|
var DATA_DIR = ".algolia-wizard/data";
|
|
3176
3240
|
var RECORD_MODEL = "claude-haiku-4-5";
|
|
3177
3241
|
var MAX_RECORDS = 100;
|
|
@@ -3181,19 +3245,19 @@ var anthropic = createAnthropic({
|
|
|
3181
3245
|
apiKey: process.env.PROVIDER_API_KEY ?? ""
|
|
3182
3246
|
});
|
|
3183
3247
|
function generateRecordTool(ctx) {
|
|
3184
|
-
return
|
|
3248
|
+
return tool10({
|
|
3185
3249
|
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.",
|
|
3186
|
-
inputSchema:
|
|
3187
|
-
entityName:
|
|
3188
|
-
attributes:
|
|
3189
|
-
count:
|
|
3190
|
-
hint:
|
|
3250
|
+
inputSchema: z17.object({
|
|
3251
|
+
entityName: z17.string().describe("Name of the entity to generate records for."),
|
|
3252
|
+
attributes: z17.array(z17.string()).describe("Attribute names each record must contain."),
|
|
3253
|
+
count: z17.number().int().min(1).max(MAX_RECORDS).default(10).describe(`How many records to generate (max ${MAX_RECORDS}).`),
|
|
3254
|
+
hint: z17.string().optional().describe("Optional context to steer realistic values.")
|
|
3191
3255
|
}),
|
|
3192
3256
|
execute: async ({ entityName, attributes, count, hint }) => {
|
|
3193
3257
|
logger.info({ entityName, count }, "called generateRecord tool");
|
|
3194
3258
|
try {
|
|
3195
|
-
const value =
|
|
3196
|
-
const recordSchema =
|
|
3259
|
+
const value = z17.union([z17.string(), z17.number(), z17.boolean(), z17.null()]);
|
|
3260
|
+
const recordSchema = z17.object(
|
|
3197
3261
|
Object.fromEntries(attributes.map((attr) => [attr, value]))
|
|
3198
3262
|
);
|
|
3199
3263
|
const generateBatch = async (batchCount) => {
|
|
@@ -3203,8 +3267,8 @@ function generateRecordTool(ctx) {
|
|
|
3203
3267
|
const { output } = await generateText({
|
|
3204
3268
|
model: anthropic(RECORD_MODEL),
|
|
3205
3269
|
output: Output.object({
|
|
3206
|
-
schema:
|
|
3207
|
-
records:
|
|
3270
|
+
schema: z17.object({
|
|
3271
|
+
records: z17.array(recordSchema).length(batchCount)
|
|
3208
3272
|
})
|
|
3209
3273
|
}),
|
|
3210
3274
|
prompt: [
|
|
@@ -3261,13 +3325,13 @@ function generateRecordTool(ctx) {
|
|
|
3261
3325
|
}
|
|
3262
3326
|
|
|
3263
3327
|
// src/lib/tools/notifyUser.ts
|
|
3264
|
-
import { tool as
|
|
3265
|
-
import
|
|
3328
|
+
import { tool as tool11 } from "ai";
|
|
3329
|
+
import z18 from "zod";
|
|
3266
3330
|
function notifyUserTool() {
|
|
3267
|
-
return
|
|
3331
|
+
return tool11({
|
|
3268
3332
|
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.`,
|
|
3269
|
-
inputSchema:
|
|
3270
|
-
message:
|
|
3333
|
+
inputSchema: z18.object({
|
|
3334
|
+
message: z18.string().describe(
|
|
3271
3335
|
"Short, plain-language description of what you are doing now."
|
|
3272
3336
|
)
|
|
3273
3337
|
}),
|
|
@@ -3311,6 +3375,7 @@ function createTools(ctx, { output, tools }) {
|
|
|
3311
3375
|
),
|
|
3312
3376
|
searchFiles: withLogging("searchFiles", searchFilesTool(ctx)),
|
|
3313
3377
|
runShell: withLogging("runShell", runShellTool(ctx)),
|
|
3378
|
+
reviewScript: withLogging("reviewScript", reviewScriptTool(ctx)),
|
|
3314
3379
|
generateRecord: withLogging("generateRecord", generateRecordTool(ctx)),
|
|
3315
3380
|
notifyUser: withLogging("notifyUser", notifyUserTool())
|
|
3316
3381
|
};
|
|
@@ -3432,10 +3497,10 @@ async function runAgent(req) {
|
|
|
3432
3497
|
}
|
|
3433
3498
|
|
|
3434
3499
|
// src/actions/detectLanguage.ts
|
|
3435
|
-
import
|
|
3436
|
-
var detectLanguageSchema =
|
|
3437
|
-
languages:
|
|
3438
|
-
frameworks:
|
|
3500
|
+
import z21 from "zod";
|
|
3501
|
+
var detectLanguageSchema = z21.object({
|
|
3502
|
+
languages: z21.array(z21.object({ name: z21.string(), version: z21.string() })),
|
|
3503
|
+
frameworks: z21.array(z21.object({ name: z21.string(), version: z21.string() }))
|
|
3439
3504
|
});
|
|
3440
3505
|
var detectLanguage = () => runAgent({
|
|
3441
3506
|
instructions: [
|
|
@@ -3453,31 +3518,31 @@ var detectLanguage = () => runAgent({
|
|
|
3453
3518
|
});
|
|
3454
3519
|
|
|
3455
3520
|
// src/actions/analyzeCodebase.ts
|
|
3456
|
-
import
|
|
3521
|
+
import z22 from "zod";
|
|
3457
3522
|
var READONLY_TOOLS = [
|
|
3458
3523
|
"listFiles",
|
|
3459
3524
|
"changeDirectory",
|
|
3460
3525
|
"readFile",
|
|
3461
3526
|
"searchFiles"
|
|
3462
3527
|
];
|
|
3463
|
-
var ingestionAnalysisSchema =
|
|
3464
|
-
ingestionAnalysis:
|
|
3465
|
-
|
|
3466
|
-
name:
|
|
3467
|
-
paths:
|
|
3528
|
+
var ingestionAnalysisSchema = z22.object({
|
|
3529
|
+
ingestionAnalysis: z22.array(
|
|
3530
|
+
z22.object({
|
|
3531
|
+
name: z22.string(),
|
|
3532
|
+
paths: z22.array(z22.string()),
|
|
3468
3533
|
// indexable fields the agent found for this entity
|
|
3469
|
-
attributes:
|
|
3534
|
+
attributes: z22.array(z22.string())
|
|
3470
3535
|
})
|
|
3471
3536
|
)
|
|
3472
3537
|
});
|
|
3473
|
-
var searchImplementationAnalysisSchema =
|
|
3474
|
-
searchImplementationAnalysis:
|
|
3538
|
+
var searchImplementationAnalysisSchema = z22.object({
|
|
3539
|
+
searchImplementationAnalysis: z22.string()
|
|
3475
3540
|
});
|
|
3476
|
-
var verificationSchema =
|
|
3477
|
-
verification:
|
|
3541
|
+
var verificationSchema = z22.object({
|
|
3542
|
+
verification: z22.array(z22.string())
|
|
3478
3543
|
});
|
|
3479
3544
|
var confirmedEntitiesFieldSchema = ingestionAnalysisSchema.shape.ingestionAnalysis.optional();
|
|
3480
|
-
var analyzeCodebaseSchema =
|
|
3545
|
+
var analyzeCodebaseSchema = z22.object({
|
|
3481
3546
|
ingestionAnalysis: ingestionAnalysisSchema.shape.ingestionAnalysis.optional(),
|
|
3482
3547
|
searchImplementationAnalysis: searchImplementationAnalysisSchema.shape.searchImplementationAnalysis.optional(),
|
|
3483
3548
|
verification: verificationSchema.shape.verification.optional(),
|
|
@@ -3539,7 +3604,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3539
3604
|
// package.json
|
|
3540
3605
|
var package_default = {
|
|
3541
3606
|
name: "@algolia/wizard",
|
|
3542
|
-
version: "0.
|
|
3607
|
+
version: "0.17.0",
|
|
3543
3608
|
description: "Magically implement Algolia functionality in your codebase",
|
|
3544
3609
|
type: "module",
|
|
3545
3610
|
engines: {
|
|
@@ -3658,8 +3723,8 @@ async function askList(ctx, prompt, { required = false } = {}) {
|
|
|
3658
3723
|
}
|
|
3659
3724
|
|
|
3660
3725
|
// src/actions/confirmLanguage.ts
|
|
3661
|
-
import
|
|
3662
|
-
var confirmLanguageSchema =
|
|
3726
|
+
import z24 from "zod";
|
|
3727
|
+
var confirmLanguageSchema = z24.object({
|
|
3663
3728
|
languages: detectLanguageSchema.shape.languages
|
|
3664
3729
|
});
|
|
3665
3730
|
async function confirmLanguage(ctx) {
|
|
@@ -3680,8 +3745,8 @@ async function confirmLanguage(ctx) {
|
|
|
3680
3745
|
}
|
|
3681
3746
|
|
|
3682
3747
|
// src/actions/confirmFramework.ts
|
|
3683
|
-
import
|
|
3684
|
-
var confirmFrameworkSchema =
|
|
3748
|
+
import z25 from "zod";
|
|
3749
|
+
var confirmFrameworkSchema = z25.object({
|
|
3685
3750
|
frameworks: detectLanguageSchema.shape.frameworks
|
|
3686
3751
|
});
|
|
3687
3752
|
var CURATED_FRAMEWORKS = [
|
|
@@ -3814,8 +3879,8 @@ async function promptUser(ctx, params) {
|
|
|
3814
3879
|
}
|
|
3815
3880
|
|
|
3816
3881
|
// src/actions/confirmEntities.ts
|
|
3817
|
-
import
|
|
3818
|
-
var confirmEntitiesSchema =
|
|
3882
|
+
import z26 from "zod";
|
|
3883
|
+
var confirmEntitiesSchema = z26.object({
|
|
3819
3884
|
// Final detection — the focused re-run may supersede project-scan's.
|
|
3820
3885
|
ingestionAnalysis: ingestionAnalysisSchema.shape.ingestionAnalysis.optional(),
|
|
3821
3886
|
confirmedEntities: confirmedEntitiesFieldSchema
|
|
@@ -3885,15 +3950,15 @@ async function confirmEntities(ctx) {
|
|
|
3885
3950
|
}
|
|
3886
3951
|
|
|
3887
3952
|
// src/actions/review.ts
|
|
3888
|
-
import { z as
|
|
3889
|
-
var reviewSchema =
|
|
3953
|
+
import { z as z27 } from "zod";
|
|
3954
|
+
var reviewSchema = z27.object({
|
|
3890
3955
|
// Broad, high-level takeaways grouped by theme (e.g. ingestion, search UI),
|
|
3891
3956
|
// not one entry per workflow step — a step's raw output can be a long,
|
|
3892
3957
|
// multi-paragraph blob (see implement.ts's summaries.join), and mirroring
|
|
3893
3958
|
// that 1:1 is what made the old per-step summary an unreadable wall of text.
|
|
3894
|
-
summaryPoints:
|
|
3895
|
-
reviewPrompt:
|
|
3896
|
-
nextSteps:
|
|
3959
|
+
summaryPoints: z27.array(z27.string()),
|
|
3960
|
+
reviewPrompt: z27.string(),
|
|
3961
|
+
nextSteps: z27.array(z27.string())
|
|
3897
3962
|
});
|
|
3898
3963
|
function formatCompletedSteps(steps) {
|
|
3899
3964
|
if (!steps.length) return "(no prior steps completed)";
|
|
@@ -3944,12 +4009,12 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
|
|
|
3944
4009
|
};
|
|
3945
4010
|
|
|
3946
4011
|
// src/actions/implement.ts
|
|
3947
|
-
import
|
|
4012
|
+
import z28 from "zod";
|
|
3948
4013
|
import { join as join12 } from "node:path";
|
|
3949
4014
|
|
|
3950
4015
|
// src/lib/worktree.ts
|
|
3951
4016
|
import { execFile as execFile2 } from "node:child_process";
|
|
3952
|
-
import { copyFile, mkdir as mkdir6, readdir as readdir3, readFile as readFile8, stat as
|
|
4017
|
+
import { copyFile, mkdir as mkdir6, readdir as readdir3, readFile as readFile8, stat as stat3, writeFile as writeFile7 } from "node:fs/promises";
|
|
3953
4018
|
import { basename as basename2, dirname as dirname7, isAbsolute as isAbsolute2, join as join10, resolve as resolve3 } from "node:path";
|
|
3954
4019
|
var MAX_BUFFER = 32 * 1024 * 1024;
|
|
3955
4020
|
var MAX_WIZARD_WORKTREES = 3;
|
|
@@ -4020,7 +4085,7 @@ async function copyUploadIntoWorktree(repoRoot, worktreePath, ingestDir, sourceP
|
|
|
4020
4085
|
}
|
|
4021
4086
|
const source = isAbsolute2(trimmed) ? trimmed : resolve3(repoRoot, trimmed);
|
|
4022
4087
|
try {
|
|
4023
|
-
if (!(await
|
|
4088
|
+
if (!(await stat3(source)).isFile()) {
|
|
4024
4089
|
return { ok: false, reason: `"${sourcePath}" is not a file` };
|
|
4025
4090
|
}
|
|
4026
4091
|
} catch {
|
|
@@ -4195,30 +4260,30 @@ function shellQuote(value) {
|
|
|
4195
4260
|
}
|
|
4196
4261
|
|
|
4197
4262
|
// src/actions/implement.ts
|
|
4198
|
-
var implementSchema =
|
|
4199
|
-
filesChanged:
|
|
4200
|
-
summary:
|
|
4201
|
-
worktreePath:
|
|
4202
|
-
ingestCommand:
|
|
4203
|
-
ingestScriptRan:
|
|
4204
|
-
ingestRecordCount:
|
|
4205
|
-
ingestDurationMs:
|
|
4206
|
-
ingestionSource:
|
|
4207
|
-
searchEnvVars:
|
|
4208
|
-
|
|
4209
|
-
name:
|
|
4210
|
-
value:
|
|
4263
|
+
var implementSchema = z28.object({
|
|
4264
|
+
filesChanged: z28.array(z28.string()),
|
|
4265
|
+
summary: z28.string(),
|
|
4266
|
+
worktreePath: z28.string().optional(),
|
|
4267
|
+
ingestCommand: z28.string().optional(),
|
|
4268
|
+
ingestScriptRan: z28.boolean().optional(),
|
|
4269
|
+
ingestRecordCount: z28.number().optional(),
|
|
4270
|
+
ingestDurationMs: z28.number().optional(),
|
|
4271
|
+
ingestionSource: z28.enum(["local", "fileUpload", "generated"]),
|
|
4272
|
+
searchEnvVars: z28.array(
|
|
4273
|
+
z28.object({
|
|
4274
|
+
name: z28.string(),
|
|
4275
|
+
value: z28.string()
|
|
4211
4276
|
})
|
|
4212
4277
|
).optional()
|
|
4213
4278
|
});
|
|
4214
|
-
var implementationOutputSchema =
|
|
4215
|
-
summary:
|
|
4216
|
-
ingestCommand:
|
|
4279
|
+
var implementationOutputSchema = z28.object({
|
|
4280
|
+
summary: z28.string(),
|
|
4281
|
+
ingestCommand: z28.string().optional()
|
|
4217
4282
|
});
|
|
4218
|
-
var verificationOutputSchema =
|
|
4219
|
-
summary:
|
|
4220
|
-
sufficient:
|
|
4221
|
-
additionalInstructions:
|
|
4283
|
+
var verificationOutputSchema = z28.object({
|
|
4284
|
+
summary: z28.string(),
|
|
4285
|
+
sufficient: z28.boolean(),
|
|
4286
|
+
additionalInstructions: z28.string().optional()
|
|
4222
4287
|
});
|
|
4223
4288
|
var MAX_IMPLEMENT_VERIFICATION_ATTEMPTS = 3;
|
|
4224
4289
|
var DEFAULT_IMPLEMENT_USE_CASES = ["ingestion", "search"];
|
|
@@ -4351,6 +4416,7 @@ function ingestionInstructions(input) {
|
|
|
4351
4416
|
"After a successful ingest, the script must print exactly one line to stdout in the form `ALGOLIA_WIZARD_RECORD_COUNT=<n>`, where <n> is the total number of records pushed to Algolia. Print it last, on its own line, with no surrounding text.",
|
|
4352
4417
|
...algoliaClientDoc(input),
|
|
4353
4418
|
"Install the Algolia client with the project's own package manager via runShell, declaring it in whatever manifest the project uses (e.g. package.json, requirements.txt, Gemfile, go.mod, composer.json) so the dependency is not just installed ad hoc.",
|
|
4419
|
+
"When the script is finished, call reviewScript with its path and wait: running it writes records to a live index, so the developer reads it first. Do not run it before that call returns.",
|
|
4354
4420
|
'Then run the script yourself via runShell, and report the command you ran as "ingestCommand" so the developer can re-run it. Its explanation must say that running it writes records to Algolia.',
|
|
4355
4421
|
"The summary should be extremely concise.",
|
|
4356
4422
|
...sourceSpecificInstructions(input)
|
|
@@ -4421,6 +4487,7 @@ var useCaseToolMap = {
|
|
|
4421
4487
|
"writeFile",
|
|
4422
4488
|
"writeCredentials",
|
|
4423
4489
|
"runShell",
|
|
4490
|
+
"reviewScript",
|
|
4424
4491
|
"notifyUser"
|
|
4425
4492
|
],
|
|
4426
4493
|
search: [...FS_READ_TOOLS, "writeFile", "runShell", "notifyUser"],
|
|
@@ -4675,7 +4742,8 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
4675
4742
|
const result = await runImplementationUseCase("ingestion");
|
|
4676
4743
|
summaries.push(formatSummary("ingestion", result.summary));
|
|
4677
4744
|
ingestCommand = result.ingestCommand;
|
|
4678
|
-
const
|
|
4745
|
+
const ingestionContext = ingestionTools ?? searchTools;
|
|
4746
|
+
const executions = ingestionContext.shell.executions;
|
|
4679
4747
|
const {
|
|
4680
4748
|
run: ingestRun,
|
|
4681
4749
|
attempt: ingestAttempt,
|
|
@@ -4684,6 +4752,15 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES, existingWo
|
|
|
4684
4752
|
ingestScriptRan = ingestRun != null;
|
|
4685
4753
|
ingestRecordCount = recordCount;
|
|
4686
4754
|
ingestDurationMs = ingestRun?.durationMs;
|
|
4755
|
+
if (ingestScriptRan && ingestionContext.reviewed.length === 0) {
|
|
4756
|
+
summaries.push(
|
|
4757
|
+
"\u26A0\uFE0F The ingestion script ran without being shown to you for review. Read it in the worktree before trusting the index contents."
|
|
4758
|
+
);
|
|
4759
|
+
logger.warn(
|
|
4760
|
+
{ ingestCommand },
|
|
4761
|
+
"implement: ingestion ran without a reviewScript call"
|
|
4762
|
+
);
|
|
4763
|
+
}
|
|
4687
4764
|
if (ingestScriptRan) {
|
|
4688
4765
|
ingestOutcomeMessage = `\u2705 Ingestion succeeded${ingestRecordCount != null ? ` \u2014 ${ingestRecordCount} record(s) indexed.` : "."}`;
|
|
4689
4766
|
if (ingestRecordCount != null) {
|
|
@@ -4913,8 +4990,8 @@ var defaultWorkflow = {
|
|
|
4913
4990
|
defineStep({
|
|
4914
4991
|
id: "select-index",
|
|
4915
4992
|
title: "Set up index",
|
|
4916
|
-
outputSchema:
|
|
4917
|
-
selection:
|
|
4993
|
+
outputSchema: z29.object({
|
|
4994
|
+
selection: z29.string()
|
|
4918
4995
|
}),
|
|
4919
4996
|
run: (ctx) => selectIndexStep(ctx)
|
|
4920
4997
|
}),
|