@algolia/wizard 0.46.0-rc.136.345 → 0.46.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 +84 -216
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -239,9 +239,6 @@ function describeInputValue(value) {
|
|
|
239
239
|
}
|
|
240
240
|
var NOTICE_INTERVAL_MS = 2e3;
|
|
241
241
|
var CLI_OUTPUT_LIMIT = 200;
|
|
242
|
-
function commandApprovalKey(command, cwd) {
|
|
243
|
-
return `${cwd}\0${command}`;
|
|
244
|
-
}
|
|
245
242
|
var useWizard = create((set, get) => ({
|
|
246
243
|
phase: "idle",
|
|
247
244
|
homeScreen: "home",
|
|
@@ -355,17 +352,10 @@ var useWizard = create((set, get) => ({
|
|
|
355
352
|
setTargetIndex: (index) => set({ targetIndex: index }),
|
|
356
353
|
recordWrittenFile: (path) => set((s) => ({ writtenFiles: [...s.writtenFiles, path] })),
|
|
357
354
|
clearWrittenFiles: () => set({ writtenFiles: [] }),
|
|
358
|
-
isCommandApproved: (command, cwd) => get().approvedCommands.has(
|
|
355
|
+
isCommandApproved: (command, cwd) => get().approvedCommands.has(`${cwd}\0${command}`),
|
|
359
356
|
approveCommand: (command, cwd) => set((s) => ({
|
|
360
|
-
approvedCommands: new Set(s.approvedCommands).add(
|
|
361
|
-
commandApprovalKey(command, cwd)
|
|
362
|
-
)
|
|
357
|
+
approvedCommands: new Set(s.approvedCommands).add(`${cwd}\0${command}`)
|
|
363
358
|
})),
|
|
364
|
-
revokeCommand: (command, cwd) => set((s) => {
|
|
365
|
-
const approvedCommands = new Set(s.approvedCommands);
|
|
366
|
-
approvedCommands.delete(commandApprovalKey(command, cwd));
|
|
367
|
-
return { approvedCommands };
|
|
368
|
-
}),
|
|
369
359
|
logStart: (kind, name, input) => {
|
|
370
360
|
const id = nanoid();
|
|
371
361
|
set((s) => ({
|
|
@@ -741,11 +731,9 @@ function DecisionSelect({
|
|
|
741
731
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
742
732
|
function CommandApproval({
|
|
743
733
|
command,
|
|
744
|
-
messages,
|
|
745
734
|
onDecide
|
|
746
735
|
}) {
|
|
747
736
|
return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", gap: 1, children: [
|
|
748
|
-
messages?.map((message, index) => /* @__PURE__ */ jsx5(Text6, { color: COLORS.muted, children: message }, `msg-${index}`)),
|
|
749
737
|
/* @__PURE__ */ jsx5(Text6, { color: COLORS.primary, bold: true, children: "Run this command?" }),
|
|
750
738
|
/* @__PURE__ */ jsxs5(
|
|
751
739
|
Box6,
|
|
@@ -1086,6 +1074,7 @@ function PromptInput() {
|
|
|
1086
1074
|
return /* @__PURE__ */ jsx7(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx7(
|
|
1087
1075
|
SelectPrompt,
|
|
1088
1076
|
{
|
|
1077
|
+
question: inputReq.prompt,
|
|
1089
1078
|
messages: inputReq.messages,
|
|
1090
1079
|
options: ["Continue"],
|
|
1091
1080
|
onSelect: submitInput
|
|
@@ -1104,14 +1093,7 @@ function PromptInput() {
|
|
|
1104
1093
|
);
|
|
1105
1094
|
}
|
|
1106
1095
|
if (inputReq.promptType === "commandApproval" && inputReq.command) {
|
|
1107
|
-
return /* @__PURE__ */ jsx7(
|
|
1108
|
-
CommandApproval,
|
|
1109
|
-
{
|
|
1110
|
-
command: inputReq.command,
|
|
1111
|
-
messages: inputReq.messages,
|
|
1112
|
-
onDecide: submitInput
|
|
1113
|
-
}
|
|
1114
|
-
);
|
|
1096
|
+
return /* @__PURE__ */ jsx7(CommandApproval, { command: inputReq.command, onDecide: submitInput });
|
|
1115
1097
|
}
|
|
1116
1098
|
if (inputReq.promptType === "acceptReject") {
|
|
1117
1099
|
const labels = inputReq.options?.length ? inputReq.options : ACCEPT_REJECT_OPTIONS;
|
|
@@ -2574,16 +2556,9 @@ function searchFilesTool(ctx) {
|
|
|
2574
2556
|
}
|
|
2575
2557
|
|
|
2576
2558
|
// src/lib/tools/runShell.ts
|
|
2577
|
-
import { tool as
|
|
2559
|
+
import { tool as tool8, generateText, Output } from "ai";
|
|
2578
2560
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2579
|
-
import z16 from "zod";
|
|
2580
|
-
import { relative as relative5 } from "node:path";
|
|
2581
|
-
|
|
2582
|
-
// src/lib/tools/reviewScript.ts
|
|
2583
|
-
import { tool as tool8 } from "ai";
|
|
2584
2561
|
import z15 from "zod";
|
|
2585
|
-
import { createHash } from "node:crypto";
|
|
2586
|
-
import { readFile as readFile7, stat as stat2 } from "node:fs/promises";
|
|
2587
2562
|
import { relative as relative4 } from "node:path";
|
|
2588
2563
|
|
|
2589
2564
|
// src/lib/tools/utils/prompt.ts
|
|
@@ -2595,116 +2570,6 @@ function serializePrompt(work) {
|
|
|
2595
2570
|
return result;
|
|
2596
2571
|
}
|
|
2597
2572
|
|
|
2598
|
-
// src/lib/tools/reviewScript.ts
|
|
2599
|
-
var reviewedCommandApprovals = /* @__PURE__ */ new WeakMap();
|
|
2600
|
-
async function fileDigest(filePath) {
|
|
2601
|
-
const content = await readFile7(filePath);
|
|
2602
|
-
return createHash("sha256").update(content).digest("hex");
|
|
2603
|
-
}
|
|
2604
|
-
function grantReviewedCommandApproval(ctx, approval) {
|
|
2605
|
-
reviewedCommandApprovals.set(ctx, approval);
|
|
2606
|
-
}
|
|
2607
|
-
function getReviewedCommandApproval(ctx, command, cwd) {
|
|
2608
|
-
const approval = reviewedCommandApprovals.get(ctx);
|
|
2609
|
-
if (approval?.command !== command || approval.cwd !== cwd) return void 0;
|
|
2610
|
-
return approval;
|
|
2611
|
-
}
|
|
2612
|
-
function clearReviewedCommandApproval(ctx) {
|
|
2613
|
-
reviewedCommandApprovals.delete(ctx);
|
|
2614
|
-
}
|
|
2615
|
-
function revokeCommandApprovals(ctx, command, cwd) {
|
|
2616
|
-
clearReviewedCommandApproval(ctx);
|
|
2617
|
-
useWizard.getState().revokeCommand(command, cwd);
|
|
2618
|
-
}
|
|
2619
|
-
async function reviewedCommandApprovalIsCurrent(approval) {
|
|
2620
|
-
const currentDigest = await fileDigest(approval.filePath).catch(() => null);
|
|
2621
|
-
return currentDigest === approval.digest;
|
|
2622
|
-
}
|
|
2623
|
-
function reviewScriptTool(ctx) {
|
|
2624
|
-
return tool8({
|
|
2625
|
-
description: "Call this as soon as the ingestion script is finished and before you run it. It summarizes the records that will be written, then asks the user to review the script and approve the exact command that will run it, so a matching runShell call needs no second approval.",
|
|
2626
|
-
inputSchema: z15.object({
|
|
2627
|
-
filePath: z15.string().describe(
|
|
2628
|
-
"Path to the script to review, relative to the project root."
|
|
2629
|
-
),
|
|
2630
|
-
command: z15.string().min(1).describe("The exact command that runShell will use to run the script."),
|
|
2631
|
-
cwd: z15.string().describe(
|
|
2632
|
-
"The exact working directory that runShell will use, relative to the current tool working directory."
|
|
2633
|
-
),
|
|
2634
|
-
entityName: z15.string().trim().min(1).max(100).regex(/^[^\r\n]+$/).describe("The exact entity name selected by the user."),
|
|
2635
|
-
usesGeneratedRecords: z15.boolean().describe(
|
|
2636
|
-
"Whether the script reads generated sample records instead of the selected real data source."
|
|
2637
|
-
)
|
|
2638
|
-
}),
|
|
2639
|
-
execute: async ({
|
|
2640
|
-
filePath,
|
|
2641
|
-
command,
|
|
2642
|
-
cwd,
|
|
2643
|
-
entityName,
|
|
2644
|
-
usesGeneratedRecords
|
|
2645
|
-
}) => {
|
|
2646
|
-
logger.info(
|
|
2647
|
-
{ filePath, command, cwd, entityName, usesGeneratedRecords },
|
|
2648
|
-
"called reviewScript tool"
|
|
2649
|
-
);
|
|
2650
|
-
const resolved2 = resolveInRoot(ctx, filePath);
|
|
2651
|
-
if (resolved2.ok === false) return resolved2.error;
|
|
2652
|
-
const resolvedCwd = resolveInRoot(ctx, cwd);
|
|
2653
|
-
if (resolvedCwd.ok === false) return resolvedCwd.error;
|
|
2654
|
-
const displayCwd = relative4(ctx.root, resolvedCwd.target) || ".";
|
|
2655
|
-
const displayFilePath = relative4(ctx.root, resolved2.target);
|
|
2656
|
-
const ingestionSummary = usesGeneratedRecords ? `This will push ${entityName} records from generated sample data to Algolia. You can replace the sample dataset with your real data source in ${displayFilePath}.` : `This will push ${entityName} records from your selected source to Algolia.`;
|
|
2657
|
-
return serializePrompt(async () => {
|
|
2658
|
-
revokeCommandApprovals(ctx, command, resolvedCwd.target);
|
|
2659
|
-
const isFile = await stat2(resolved2.target).then(
|
|
2660
|
-
(s) => s.isFile(),
|
|
2661
|
-
() => false
|
|
2662
|
-
);
|
|
2663
|
-
if (!isFile) {
|
|
2664
|
-
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
2665
|
-
}
|
|
2666
|
-
const reviewedDigest = await fileDigest(resolved2.target).catch(
|
|
2667
|
-
() => null
|
|
2668
|
-
);
|
|
2669
|
-
if (reviewedDigest === null) {
|
|
2670
|
-
return `Refused: ${filePath} could not be read. Write the script first, then review it again.`;
|
|
2671
|
-
}
|
|
2672
|
-
const answer = await useWizard.getState().requestUserInput({
|
|
2673
|
-
prompt: "Run this command?",
|
|
2674
|
-
promptType: "commandApproval",
|
|
2675
|
-
options: [],
|
|
2676
|
-
messages: [
|
|
2677
|
-
`We have created your ingestion script. Please review it at ${displayFilePath} before approving.`
|
|
2678
|
-
],
|
|
2679
|
-
command: {
|
|
2680
|
-
command,
|
|
2681
|
-
cwd: displayCwd,
|
|
2682
|
-
explanation: ingestionSummary
|
|
2683
|
-
}
|
|
2684
|
-
});
|
|
2685
|
-
if (answer !== "approve") {
|
|
2686
|
-
revokeCommandApprovals(ctx, command, resolvedCwd.target);
|
|
2687
|
-
return "The user declined to run this ingestion script. Do not run it.";
|
|
2688
|
-
}
|
|
2689
|
-
const approvedDigest = await fileDigest(resolved2.target).catch(
|
|
2690
|
-
() => null
|
|
2691
|
-
);
|
|
2692
|
-
if (approvedDigest !== reviewedDigest) {
|
|
2693
|
-
return "The ingestion script changed while it was being reviewed. Call reviewScript again before running it.";
|
|
2694
|
-
}
|
|
2695
|
-
ctx.reviewed.push(resolved2.target);
|
|
2696
|
-
grantReviewedCommandApproval(ctx, {
|
|
2697
|
-
command,
|
|
2698
|
-
cwd: resolvedCwd.target,
|
|
2699
|
-
filePath: resolved2.target,
|
|
2700
|
-
digest: reviewedDigest
|
|
2701
|
-
});
|
|
2702
|
-
return "The user reviewed the script and approved this exact command. Run it now with the same cwd.";
|
|
2703
|
-
});
|
|
2704
|
-
}
|
|
2705
|
-
});
|
|
2706
|
-
}
|
|
2707
|
-
|
|
2708
2573
|
// src/lib/tools/utils/runShell.ts
|
|
2709
2574
|
import { spawn as spawn2 } from "node:child_process";
|
|
2710
2575
|
|
|
@@ -2803,7 +2668,7 @@ function storeApproval(root) {
|
|
|
2803
2668
|
return async (req) => {
|
|
2804
2669
|
const store = useWizard.getState();
|
|
2805
2670
|
if (store.isCommandApproved(req.command, req.cwd)) return "approve";
|
|
2806
|
-
const rel =
|
|
2671
|
+
const rel = relative4(root, req.cwd);
|
|
2807
2672
|
const answer = await store.requestUserInput({
|
|
2808
2673
|
prompt: "Run this command?",
|
|
2809
2674
|
promptType: "commandApproval",
|
|
@@ -2956,9 +2821,9 @@ function fastPathSafety(command) {
|
|
|
2956
2821
|
return void 0;
|
|
2957
2822
|
}
|
|
2958
2823
|
var CLASSIFIER_MODEL = "claude-haiku-4-5";
|
|
2959
|
-
var commandSafetySchema =
|
|
2960
|
-
safe:
|
|
2961
|
-
reason:
|
|
2824
|
+
var commandSafetySchema = z15.object({
|
|
2825
|
+
safe: z15.boolean(),
|
|
2826
|
+
reason: z15.string().describe("One short sentence explaining the verdict.")
|
|
2962
2827
|
});
|
|
2963
2828
|
function defaultCreateModel() {
|
|
2964
2829
|
const token = getAuthToken();
|
|
@@ -3018,15 +2883,12 @@ async function classifyCommandSafety(createModel, command, cwd, explanation, app
|
|
|
3018
2883
|
return false;
|
|
3019
2884
|
}
|
|
3020
2885
|
}
|
|
3021
|
-
async function
|
|
3022
|
-
|
|
2886
|
+
async function runAndRecord(ctx, command, cwd) {
|
|
2887
|
+
useWizard.getState().pushNotice({ messages: [`Running: ${command}`] });
|
|
2888
|
+
const env = await ctx.shell.env().catch((err) => {
|
|
3023
2889
|
logger.warn({ err, command }, "runShell: could not resolve command env");
|
|
3024
2890
|
return {};
|
|
3025
2891
|
});
|
|
3026
|
-
}
|
|
3027
|
-
async function runAndRecord(ctx, command, cwd, resolvedEnv) {
|
|
3028
|
-
useWizard.getState().pushNotice({ messages: [`Running: ${command}`] });
|
|
3029
|
-
const env = resolvedEnv ?? await resolveShellEnv(ctx, command);
|
|
3030
2892
|
const run2 = await (ctx.shell.run ?? runShell)(command, {
|
|
3031
2893
|
cwd,
|
|
3032
2894
|
env,
|
|
@@ -3057,16 +2919,6 @@ async function runAndRecord(ctx, command, cwd, resolvedEnv) {
|
|
|
3057
2919
|
output: run2.output
|
|
3058
2920
|
};
|
|
3059
2921
|
}
|
|
3060
|
-
async function runReviewedCommand(ctx, command, cwd) {
|
|
3061
|
-
const approval = getReviewedCommandApproval(ctx, command, cwd);
|
|
3062
|
-
if (!approval) return void 0;
|
|
3063
|
-
const env = await resolveShellEnv(ctx, command);
|
|
3064
|
-
if (!await reviewedCommandApprovalIsCurrent(approval)) {
|
|
3065
|
-
return `Refused: ${relative5(ctx.root, approval.filePath)} changed after review. Call reviewScript again before running it.`;
|
|
3066
|
-
}
|
|
3067
|
-
clearReviewedCommandApproval(ctx);
|
|
3068
|
-
return runAndRecord(ctx, command, cwd, env);
|
|
3069
|
-
}
|
|
3070
2922
|
async function approveAndRun(ctx, command, cwd, explanation) {
|
|
3071
2923
|
const decision = await ctx.shell.approve({ command, cwd, explanation });
|
|
3072
2924
|
if (decision === "reject") {
|
|
@@ -3077,16 +2929,16 @@ async function approveAndRun(ctx, command, cwd, explanation) {
|
|
|
3077
2929
|
return runAndRecord(ctx, command, cwd);
|
|
3078
2930
|
}
|
|
3079
2931
|
function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
3080
|
-
return
|
|
2932
|
+
return tool8({
|
|
3081
2933
|
description: "Run a shell command in the project. Use this for anything the project needs done in its own ecosystem: installing dependencies, running a script you wrote, running the project's lint/typecheck/test commands. Do not use this to find or read files \u2014 use listFiles, searchFiles, and readFile instead of shell file-listing, reading, or search commands (ls/find/tree/cat/head/tail/grep/rg and similar). This tool refuses all of those outright: the dedicated tools enforce the project-root boundary and secret redaction that a raw shell read would bypass, and they won't count against this tool's command budget. The user approves any command that could change the project before it runs, so write a clear `explanation`. A command judged read-only (inspection, or running tests/typecheck/lint without an autofix flag, in any language) runs immediately without approval. If the user rejects a command, do not retry it \u2014 propose a different approach.",
|
|
3082
|
-
inputSchema:
|
|
3083
|
-
command:
|
|
2934
|
+
inputSchema: z15.object({
|
|
2935
|
+
command: z15.string().describe(
|
|
3084
2936
|
"The command to run, exactly as it would be typed in a shell. Pipes, && and redirects are allowed."
|
|
3085
2937
|
),
|
|
3086
|
-
cwd:
|
|
2938
|
+
cwd: z15.string().optional().describe(
|
|
3087
2939
|
"Directory to run in, relative to the project root. Defaults to the project root."
|
|
3088
2940
|
),
|
|
3089
|
-
explanation:
|
|
2941
|
+
explanation: z15.string().describe(
|
|
3090
2942
|
"One short line telling the user what this command does and why, including any side effect (e.g. writes records to Algolia). This is what they approve against."
|
|
3091
2943
|
)
|
|
3092
2944
|
}),
|
|
@@ -3095,22 +2947,16 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
3095
2947
|
return `Refused: command limit (${ctx.limits.shell}) reached. Stop running commands and report what you have.`;
|
|
3096
2948
|
}
|
|
3097
2949
|
const resolved2 = resolveInRoot(ctx, cwd ?? ".");
|
|
3098
|
-
if (resolved2.ok
|
|
2950
|
+
if (!resolved2.ok) return resolved2.error;
|
|
3099
2951
|
if (isFileIOCommand(command)) {
|
|
3100
2952
|
return "Refused: use listFiles or searchFiles to find files, and readFile to read one, instead of a shell file-listing, reading, or search command (ls/find/fd/tree/dir/locate/cat/head/tail/less/more/tac/nl/grep/egrep/fgrep/rg/ack/ag/xxd/hexdump/od/strings).";
|
|
3101
2953
|
}
|
|
3102
2954
|
logger.info({ command, cwd: resolved2.target }, "called runShell tool");
|
|
3103
|
-
const reviewed = await serializePrompt(
|
|
3104
|
-
() => runReviewedCommand(ctx, command, resolved2.target)
|
|
3105
|
-
);
|
|
3106
|
-
if (reviewed !== void 0) return reviewed;
|
|
3107
2955
|
const fast = fastPathSafety(command);
|
|
3108
2956
|
let isSafe = fast;
|
|
3109
|
-
let usedStoredApproval = false;
|
|
3110
2957
|
if (isSafe === void 0) {
|
|
3111
2958
|
const store = useWizard.getState();
|
|
3112
|
-
|
|
3113
|
-
isSafe = usedStoredApproval;
|
|
2959
|
+
isSafe = store.isCommandApproved(command, resolved2.target);
|
|
3114
2960
|
if (!isSafe) {
|
|
3115
2961
|
isSafe = await classifyCommandSafety(
|
|
3116
2962
|
createModel,
|
|
@@ -3121,18 +2967,54 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
3121
2967
|
);
|
|
3122
2968
|
}
|
|
3123
2969
|
}
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
ctx,
|
|
3127
|
-
command,
|
|
3128
|
-
resolved2.target
|
|
2970
|
+
if (isSafe) {
|
|
2971
|
+
return serializePrompt(
|
|
2972
|
+
() => runAndRecord(ctx, command, resolved2.target)
|
|
3129
2973
|
);
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
2974
|
+
}
|
|
2975
|
+
return serializePrompt(
|
|
2976
|
+
() => approveAndRun(ctx, command, resolved2.target, explanation)
|
|
2977
|
+
);
|
|
2978
|
+
}
|
|
2979
|
+
});
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
// src/lib/tools/reviewScript.ts
|
|
2983
|
+
import { tool as tool9 } from "ai";
|
|
2984
|
+
import z16 from "zod";
|
|
2985
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
2986
|
+
import { relative as relative5 } from "node:path";
|
|
2987
|
+
function reviewScriptTool(ctx) {
|
|
2988
|
+
return tool9({
|
|
2989
|
+
description: "Call this as soon as the ingestion script is finished and before you run it, so the user can review it.It shows the file path and returns once they have confirmed reviewing it.",
|
|
2990
|
+
inputSchema: z16.object({
|
|
2991
|
+
filePath: z16.string().describe(
|
|
2992
|
+
"Path to the script to review, relative to the project root."
|
|
2993
|
+
)
|
|
2994
|
+
}),
|
|
2995
|
+
execute: async ({ filePath }) => {
|
|
2996
|
+
logger.info({ filePath }, "called reviewScript tool");
|
|
2997
|
+
const resolved2 = resolveInRoot(ctx, filePath);
|
|
2998
|
+
if (resolved2.ok === false) return resolved2.error;
|
|
2999
|
+
const isFile = await stat2(resolved2.target).then(
|
|
3000
|
+
(s) => s.isFile(),
|
|
3001
|
+
() => false
|
|
3002
|
+
);
|
|
3003
|
+
if (!isFile) {
|
|
3004
|
+
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
3005
|
+
}
|
|
3006
|
+
return serializePrompt(async () => {
|
|
3007
|
+
await useWizard.getState().requestUserInput({
|
|
3008
|
+
prompt: "",
|
|
3009
|
+
promptType: "enterToContinue",
|
|
3010
|
+
options: [],
|
|
3011
|
+
messages: [
|
|
3012
|
+
`Please review ${relative5(ctx.root, resolved2.target)} before it runs:`,
|
|
3013
|
+
resolved2.target
|
|
3014
|
+
]
|
|
3015
|
+
});
|
|
3016
|
+
ctx.reviewed.push(resolved2.target);
|
|
3017
|
+
return "The user has reviewed the script. You may run it now.";
|
|
3136
3018
|
});
|
|
3137
3019
|
}
|
|
3138
3020
|
});
|
|
@@ -3627,7 +3509,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3627
3509
|
// package.json
|
|
3628
3510
|
var package_default = {
|
|
3629
3511
|
name: "@algolia/wizard",
|
|
3630
|
-
version: "0.46.0
|
|
3512
|
+
version: "0.46.0",
|
|
3631
3513
|
description: "Magically implement Algolia functionality in your codebase",
|
|
3632
3514
|
type: "module",
|
|
3633
3515
|
engines: {
|
|
@@ -4330,8 +4212,8 @@ function ingestionInstructions(input) {
|
|
|
4330
4212
|
...algoliaClientDoc(input),
|
|
4331
4213
|
"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.",
|
|
4332
4214
|
`If the script loads its env vars from a file (e.g. via dotenv or an equivalent for its language) rather than the process environment directly, decide that up front and call writeCredentials on that file before you finish the script \u2014 do not wait to discover the need for it by having a writeFile call refused.`,
|
|
4333
|
-
|
|
4334
|
-
'Then
|
|
4215
|
+
"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.",
|
|
4216
|
+
'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.',
|
|
4335
4217
|
"The summary should be extremely concise.",
|
|
4336
4218
|
...sourceSpecificInstructions(input)
|
|
4337
4219
|
] : []
|
|
@@ -4703,33 +4585,19 @@ ${detail}` : ""}`
|
|
|
4703
4585
|
product_area: "AI Wizard"
|
|
4704
4586
|
});
|
|
4705
4587
|
}
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
}
|
|
4719
|
-
const commandMessages = ingestCommand ? [`Ingestion command: ${ingestCommand}`] : [];
|
|
4720
|
-
await ctx.requestUserInput({
|
|
4721
|
-
prompt: "",
|
|
4722
|
-
promptType: "enterToContinue",
|
|
4723
|
-
options: [],
|
|
4724
|
-
// One message per line: Notices.tsx counts a message as one wrapped
|
|
4725
|
-
// line, so an embedded newline overflows the panel's height accounting.
|
|
4726
|
-
messages: [
|
|
4727
|
-
ingestOutcomeMessage,
|
|
4728
|
-
...ingestFailureDetail?.split("\n").filter((l) => l.trim()) ?? [],
|
|
4729
|
-
...commandMessages
|
|
4730
|
-
]
|
|
4731
|
-
});
|
|
4732
|
-
}
|
|
4588
|
+
const commandMessages = ingestCommand ? [`Ingestion command: ${ingestCommand}`] : [];
|
|
4589
|
+
await ctx.requestUserInput({
|
|
4590
|
+
prompt: "",
|
|
4591
|
+
promptType: "enterToContinue",
|
|
4592
|
+
options: [],
|
|
4593
|
+
// One message per line: Notices.tsx counts a message as one wrapped
|
|
4594
|
+
// line, so an embedded newline overflows the panel's height accounting.
|
|
4595
|
+
messages: [
|
|
4596
|
+
ingestOutcomeMessage,
|
|
4597
|
+
...ingestFailureDetail?.split("\n").filter((l) => l.trim()) ?? [],
|
|
4598
|
+
...commandMessages
|
|
4599
|
+
]
|
|
4600
|
+
});
|
|
4733
4601
|
}
|
|
4734
4602
|
let searchConfigFile;
|
|
4735
4603
|
if (useCases.includes("search")) {
|
|
@@ -5921,7 +5789,7 @@ function App() {
|
|
|
5921
5789
|
}
|
|
5922
5790
|
|
|
5923
5791
|
// src/lib/envAppId.ts
|
|
5924
|
-
import { readFile as
|
|
5792
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
5925
5793
|
import { join as join12 } from "node:path";
|
|
5926
5794
|
var ENV_FILES = [".env", ".env.local"];
|
|
5927
5795
|
var APP_ID_LINE = /^[ \t]*(?:export[ \t]+)?([A-Z0-9_]*ALGOLIA_APP(?:LICATION)?_ID)[ \t]*=[ \t]*(.*)$/gm;
|
|
@@ -5929,7 +5797,7 @@ async function findEnvApplicationId(root = process.cwd()) {
|
|
|
5929
5797
|
for (const file of ENV_FILES) {
|
|
5930
5798
|
let content;
|
|
5931
5799
|
try {
|
|
5932
|
-
content = await
|
|
5800
|
+
content = await readFile7(join12(root, file), "utf8");
|
|
5933
5801
|
} catch (err) {
|
|
5934
5802
|
if (err.code !== "ENOENT") {
|
|
5935
5803
|
logger.warn(
|