@algolia/wizard 0.33.0-rc.126.239 → 0.33.0-rc.126.240
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 +23 -6
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -3637,7 +3637,13 @@ function defaultCreateModel() {
|
|
|
3637
3637
|
fetch: proxyFetch
|
|
3638
3638
|
});
|
|
3639
3639
|
}
|
|
3640
|
-
|
|
3640
|
+
function approvedCommandHistory(approvedCommands) {
|
|
3641
|
+
return Array.from(approvedCommands).map((entry) => {
|
|
3642
|
+
const sep2 = entry.indexOf("\0");
|
|
3643
|
+
return { cwd: entry.slice(0, sep2), command: entry.slice(sep2 + 1) };
|
|
3644
|
+
});
|
|
3645
|
+
}
|
|
3646
|
+
async function classifyCommandSafety(createModel, command, cwd, explanation, approvedHistory) {
|
|
3641
3647
|
try {
|
|
3642
3648
|
const anthropic = createModel();
|
|
3643
3649
|
const { output } = await generateText({
|
|
@@ -3650,9 +3656,14 @@ async function classifyCommandSafety(createModel, command, cwd, explanation) {
|
|
|
3650
3656
|
"Three broad categories are safe, and most commands you will see fall into one of them:",
|
|
3651
3657
|
"(1) Reporting or listing existing state, with no side effect \u2014 e.g. `git status`, `npm ls`, `npm outdated`, `pip show`, `pip freeze`, `cargo tree`, `docker ps`, `docker images`, `kubectl get pods`, `terraform state list`. This includes a read-only GET-style query to a remote registry or API that only fetches public metadata and changes nothing remote (e.g. `npm view <package>`, `pip index versions <package>`, `curl` with no -X/--request other than GET and no -d/--data) \u2014 safe because nothing changes, not because it stays local.",
|
|
3652
3658
|
'(2) A "preview" or "check" mode that reports what a change WOULD do, or reports a problem, without making the change. This is a general pattern, not a fixed list \u2014 ANY command that takes a dry-run/check/plan/validate/diff/list-only flag is safe when that flag is present, regardless of whether the same flag would normally appear on a "safe" kind of command: `terraform plan`, `terraform validate`, `terraform fmt -check`, `black --check`, `prettier --check`, `isort --check`, `gofmt -l` (list-only), `stylelint` with no `--fix`, and equally `git push --dry-run`, `npm publish --dry-run`, `kubectl apply --dry-run=client` \u2014 these last three are otherwise-unsafe operations (push, publish, cluster changes) that the dry-run flag turns into a report. The corresponding command WITHOUT that flag (e.g. `terraform apply`, `black .`, `gofmt -w`, `git push`) is a different, unsafe command \u2014 the flag is what makes the difference, for any tool, not just the ones named here. This cuts both ways, so do not assume a bare invocation is the safe one: `cargo fmt`, `black`, `prettier`, `isort`, `rustfmt`, and `terraform fmt` all REWRITE FILES by default and need an explicit check/diff/dry-run flag to become safe, while `gofmt`, `eslint`, `stylelint`, `rubocop`, and `ruff check` default to a safe check-only mode and need an explicit fix/write flag to become unsafe \u2014 the same-looking bare command is safe for one group and unsafe for the other, so judge each by what its own flags actually say, not by resemblance to a tool you already judged.',
|
|
3653
|
-
"(3) Running the project's own tests, type checker, or
|
|
3659
|
+
"(3) Running the project's own tests, type checker, linter, or build/compile step (e.g. `npm run build`, `yarn build`, `vite build`, `webpack`, `tsc`, `cargo build`, `go build`, `mvn compile`), as long as it is not passed an autofix/write/update flag (e.g. --fix, -u, --write, rubocop -a) \u2014 this holds even though the point of a build step is to write compiled output to a build/dist/target directory inside the project (e.g. a target/, build/, dist/, or __pycache__ directory): writing that output does not make the command unsafe. It stops being safe the moment the command chain goes past building \u2014 a step that also deploys, publishes, uploads, or pushes the build (e.g. `next build && vercel deploy`, `npm run build && npm publish`) is unsafe for that later segment even though the build segment itself is fine; judge each chained segment on its own, same as elsewhere in this list.",
|
|
3654
3660
|
"Deleting or removing anything is unsafe, even something in a cache or build directory (e.g. `rm -rf __pycache__`, `cargo clean`, `git clean`), and even if the command otherwise fits one of the three categories above. Installing, uninstalling, or upgrading a dependency, changing a database schema, or writing to a path outside the project is also unsafe. A command chained with && or ; is only safe if every part of the chain is safe on its own.",
|
|
3655
3661
|
"One specific, narrow exception to all of the above: when the command literally invokes one of these runner programs BY NAME as the leading command \u2014 npx, bunx, pnpm dlx, yarn dlx, pipx run, uvx \u2014 it is unsafe regardless of what it then runs, even something that looks like a harmless test/lint/typecheck command (e.g. `npx tsc --noEmit`, `uvx ruff check .`), because that runner can fetch and execute a different, unreviewed version of a package from a registry each time. This exception is about that specific syntax, not a general doubt about whether a tool is installed: a plain `ruff check .`, `pytest`, or any other bare command name is NOT this exception merely because you cannot verify from the string alone that it is installed \u2014 judge those the same as any other already-installed project tool, per the categories above. If you are unsure, judge it unsafe.",
|
|
3662
|
+
...approvedHistory.length > 0 ? [
|
|
3663
|
+
"The user has already explicitly approved these exact commands earlier in this session (working directory in parentheses, then the command):",
|
|
3664
|
+
approvedHistory.map((h) => `- (${h.cwd}) ${h.command}`).join("\n"),
|
|
3665
|
+
"If the new command performs the same action and side-effect profile as one of these \u2014 differing only in a trivial way, such as a different file path, package name, or argument value that does not change what kind of action it is \u2014 judge it SAFE on that precedent, even if it would not otherwise fit categories (1)-(3) above. Do not stretch this to a command that merely shares a binary name, or superficially resembles one on the list while doing something riskier or of a different kind (e.g. an approved `rm build/tmp.log` does not license a new `rm -rf src/`, and an approved `git push origin feature-x` does not license `git push --force`)."
|
|
3666
|
+
] : [],
|
|
3656
3667
|
`Command: ${command}`,
|
|
3657
3668
|
`Working directory: ${cwd}`,
|
|
3658
3669
|
`Stated purpose: ${explanation}`
|
|
@@ -3745,13 +3756,15 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
3745
3756
|
const fast = fastPathSafety(command);
|
|
3746
3757
|
let isSafe = fast;
|
|
3747
3758
|
if (isSafe === void 0) {
|
|
3748
|
-
|
|
3759
|
+
const store = useWizard.getState();
|
|
3760
|
+
isSafe = store.isCommandApproved(command, resolved2.target);
|
|
3749
3761
|
if (!isSafe) {
|
|
3750
3762
|
isSafe = await classifyCommandSafety(
|
|
3751
3763
|
createModel,
|
|
3752
3764
|
command,
|
|
3753
3765
|
resolved2.target,
|
|
3754
|
-
explanation
|
|
3766
|
+
explanation,
|
|
3767
|
+
approvedCommandHistory(store.approvedCommands)
|
|
3755
3768
|
);
|
|
3756
3769
|
}
|
|
3757
3770
|
}
|
|
@@ -4239,7 +4252,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
4239
4252
|
// package.json
|
|
4240
4253
|
var package_default = {
|
|
4241
4254
|
name: "@algolia/wizard",
|
|
4242
|
-
version: "0.33.0-rc.126.
|
|
4255
|
+
version: "0.33.0-rc.126.240",
|
|
4243
4256
|
description: "Magically implement Algolia functionality in your codebase",
|
|
4244
4257
|
type: "module",
|
|
4245
4258
|
engines: {
|
|
@@ -4645,6 +4658,7 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
|
|
|
4645
4658
|
|
|
4646
4659
|
// src/actions/implement.ts
|
|
4647
4660
|
import z29 from "zod";
|
|
4661
|
+
import { mkdir as mkdir7 } from "node:fs/promises";
|
|
4648
4662
|
import { join as join12, relative as relative6 } from "node:path";
|
|
4649
4663
|
|
|
4650
4664
|
// src/lib/git.ts
|
|
@@ -4934,7 +4948,7 @@ function algoliaClientDoc(input) {
|
|
|
4934
4948
|
function ingestionInstructions(input) {
|
|
4935
4949
|
return [
|
|
4936
4950
|
...input.confirmed && input.confirmed.length ? [
|
|
4937
|
-
`Create an ingestion script under "${input.ingestDir}/" at the repo root.`,
|
|
4951
|
+
`Create an ingestion script under "${input.ingestDir}/" at the repo root. That directory already exists \u2014 writeFile creates any nested path itself, so never run a shell command just to create a directory.`,
|
|
4938
4952
|
`Ingest only the confirmed entity (name, source paths, attributes): ${JSON.stringify(input.confirmed)}.`,
|
|
4939
4953
|
`Ingesting writes to Algolia, so the script needs a write API key and App ID \u2014 read them from the ${API_KEY_VAR} and ${APP_ID_VAR} environment variables rather than hardcoding them. The wizard sets these when it runs the script.`,
|
|
4940
4954
|
`Read the index name from the ${INDEX_NAME_VAR} environment variable, which the wizard sets to "${input.targetIndex}". Never hardcode an index name or derive one from the project, file, or entity name \u2014 the write key only works for that exact index. Exit with an error if ${INDEX_NAME_VAR} is unset.`,
|
|
@@ -5169,6 +5183,9 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
5169
5183
|
const targetIndex = selected?.selection;
|
|
5170
5184
|
useWizard.getState().setTargetIndex(targetIndex ?? null);
|
|
5171
5185
|
await assertGitRepoWithHead(repoRoot);
|
|
5186
|
+
if (useCases.includes("ingestion")) {
|
|
5187
|
+
await mkdir7(join12(repoRoot, INGEST_DIR), { recursive: true });
|
|
5188
|
+
}
|
|
5172
5189
|
const normalized = normalizeFindingPaths(findings);
|
|
5173
5190
|
const confirmed2 = normalized.confirmedEntities;
|
|
5174
5191
|
const searchLocation = normalized.searchImplementationAnalysis;
|