@algolia/wizard 0.99.0 → 0.101.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 CHANGED
@@ -2447,7 +2447,7 @@ async function ensureApplication(resumeAppId) {
2447
2447
  // package.json
2448
2448
  var package_default = {
2449
2449
  name: "@algolia/wizard",
2450
- version: "0.99.0",
2450
+ version: "0.101.0",
2451
2451
  description: "Magically implement Algolia functionality in your codebase",
2452
2452
  type: "module",
2453
2453
  engines: {
@@ -3167,6 +3167,22 @@ function resolveInRoot(ctx, path) {
3167
3167
  }
3168
3168
  return { ok: true, target };
3169
3169
  }
3170
+ function isPackageManifest(parts) {
3171
+ if (parts.at(-1) !== "package.json") return false;
3172
+ return parts.length === 2 || parts.length === 3 && parts[0].startsWith("@");
3173
+ }
3174
+ var DEPENDENCY_INTERNALS_REFUSAL = "Refused: do not explore node_modules. Use the Algolia SDK reference and the type checker output. To check an installed version, read node_modules/<package>/package.json.";
3175
+ function dependencyInternalsRefusal(ctx, target) {
3176
+ if (!ctx.dependencyManifestsOnly) return null;
3177
+ const parts = relative(ctx.root, target).split(sep);
3178
+ const index = parts.lastIndexOf("node_modules");
3179
+ if (index === -1 || isPackageManifest(parts.slice(index + 1))) return null;
3180
+ return DEPENDENCY_INTERNALS_REFUSAL;
3181
+ }
3182
+ var DEPENDENCY_INTERNALS_PATH = /node_modules\/(?!\.bin\/|(?:@[^/\s'"`]+\/)?[^/\s'"`]+\/package\.json\b)/;
3183
+ function commandNamesDependencyInternals(ctx, command) {
3184
+ return Boolean(ctx.dependencyManifestsOnly) && DEPENDENCY_INTERNALS_PATH.test(command);
3185
+ }
3170
3186
  async function hasSymlinkParent(ctx, target) {
3171
3187
  let current = ctx.root;
3172
3188
  const parts = relative(ctx.root, dirname2(target)).split(sep).filter(Boolean);
@@ -3230,6 +3246,8 @@ function listFilesTool(ctx) {
3230
3246
  }
3231
3247
  const resolved2 = resolveInRoot(ctx, path);
3232
3248
  if (!resolved2.ok) return resolved2.error;
3249
+ const refusal = dependencyInternalsRefusal(ctx, resolved2.target);
3250
+ if (refusal) return refusal;
3233
3251
  try {
3234
3252
  const entries = await readdir(resolved2.target, { withFileTypes: true });
3235
3253
  return entries.map((e) => e.isDirectory() ? `${e.name}/` : e.name).join("\n");
@@ -3379,6 +3397,8 @@ function readFileTool(ctx) {
3379
3397
  logger.info({ filePath, readLines }, "called readFile tool");
3380
3398
  const resolved2 = resolveInRoot(ctx, filePath);
3381
3399
  if (resolved2.ok === false) return resolved2.error;
3400
+ const refusal = dependencyInternalsRefusal(ctx, resolved2.target);
3401
+ if (refusal) return refusal;
3382
3402
  try {
3383
3403
  const content = await readFile4(resolved2.target, "utf8");
3384
3404
  const safeContent = isEnvFile(resolved2.target) ? redactEnvValues(content) : content;
@@ -4323,6 +4343,8 @@ function searchFilesTool(ctx) {
4323
4343
  }
4324
4344
  const resolved2 = resolveInRoot(ctx, path);
4325
4345
  if (!resolved2.ok) return resolved2.error;
4346
+ const refusal = dependencyInternalsRefusal(ctx, resolved2.target);
4347
+ if (refusal) return refusal;
4326
4348
  try {
4327
4349
  await stat2(resolved2.target);
4328
4350
  } catch (err) {
@@ -4347,7 +4369,9 @@ function searchFilesTool(ctx) {
4347
4369
  let workerFailed = false;
4348
4370
  try {
4349
4371
  try {
4350
- const files = await searchableFiles(ctx.root, resolved2.target);
4372
+ const files = (await searchableFiles(ctx.root, resolved2.target)).filter(
4373
+ (file) => !dependencyInternalsRefusal(ctx, file)
4374
+ );
4351
4375
  const rootPath = await realpath(ctx.root);
4352
4376
  for (const [fileIndex, file] of files.entries()) {
4353
4377
  const moreFilesRemain = fileIndex < files.length - LINE_NUMBER_OFFSET;
@@ -5132,6 +5156,9 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
5132
5156
  if (isFileIOCommand(command)) {
5133
5157
  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).";
5134
5158
  }
5159
+ if (commandNamesDependencyInternals(ctx, command)) {
5160
+ return DEPENDENCY_INTERNALS_REFUSAL;
5161
+ }
5135
5162
  logger.info({ command, cwd: resolved2.target }, "called runShell tool");
5136
5163
  const reviewed = await serializePrompt(
5137
5164
  () => runReviewedCommand(ctx, command, resolved2.target)
@@ -6633,7 +6660,8 @@ function searchInstructions(input) {
6633
6660
  "Style the search surfaces through the widget's class and CSS-variable overrides (or, when hand-built, the app's existing theme tokens): give the results panel and the element that actually draws the input's border and background \u2014 for a widget, the form or wrapper it renders around the bare input \u2014 non-transparent surfaces, keep that frame distinguishable from the background behind it in every supported theme, and never assume a light surface or reuse the surrounding page's colors unchanged inside the panel.",
6634
6661
  "The panel takes its width from the input by default, so a small input makes it unreadably narrow: give it `min-width: min(320px, calc(100vw - 2rem))` independent of the input, cap its maximum width to the viewport, and anchor it to the input edge it opens from so widening does not push it off-screen.",
6635
6662
  "Match the application styles closely, including light, dark, and high-contrast themes the project already supports.",
6636
- "Before reporting, mount the component. Do not run a type check, build, or test command: the validation pass runs the type check, after the developer agrees to it. If a tool limit is reached or an error remains unresolved, keep the implementation, report status=success, and name the remaining issue in the summary so validation can drive the next pass. Report status=fail only when no search implementation can be written, with the concrete blocker as the reason.",
6663
+ "When you add UI text to a localized dictionary or message file, add the same keys, translated, to every locale the project supports.",
6664
+ "Before reporting, mount the component. Do not run a type check, build, or test command unless a later instruction allows it: the validation pass runs the type check, after the developer agrees to it. If a tool limit is reached or an error remains unresolved, keep the implementation, report status=success, and name the remaining issue in the summary so validation can drive the next pass. Report status=fail only when no search implementation can be written, with the concrete blocker as the reason.",
6637
6665
  "The summary should be extremely concise; do not mention manual testing steps."
6638
6666
  ];
6639
6667
  }
@@ -6994,7 +7022,8 @@ function ingestionRetryInstruction(reason, detail) {
6994
7022
  }
6995
7023
  function validationRetryInstructions(validation) {
6996
7024
  return [
6997
- `Implementation insufficient. Address these findings before reporting completion: ${validation.additionalInstructions ?? validation.summary}`
7025
+ `Implementation insufficient. Address these findings before reporting completion: ${validation.additionalInstructions ?? validation.summary}`,
7026
+ "Apply these fixes first, with the fewest edits. When a finding names a fix, apply that fix instead of studying the API again."
6998
7027
  ];
6999
7028
  }
7000
7029
  async function pathExists(path) {
@@ -7059,10 +7088,16 @@ function validationRunInstructions(plan, attempt) {
7059
7088
  "The developer approved the optional build checks.",
7060
7089
  ...installCheckInstructions(plan, attempt),
7061
7090
  "Do not use npx, dlx, or another package runner that can download an undeclared tool.",
7062
- "Run the type check once with the project's existing command, when one is available.",
7091
+ "Run the type check once with the project's existing command, when one is available. Run it even when you already found other failures, and put every type error that the changes cause in additionalInstructions, so the next pass can fix them all at once.",
7063
7092
  "Do not use an autofix option during validation."
7064
7093
  ];
7065
7094
  }
7095
+ function retryTypeCheckInstructions(plan) {
7096
+ if (!plan.run) return [];
7097
+ return [
7098
+ "The developer approved the type check. Run it once with the project's existing command right after you apply the fixes, before other work. Do not install dependencies, use npx, dlx, or another package runner, or use an autofix option. Fix the errors that your changes cause, and name any error that remains in the summary."
7099
+ ];
7100
+ }
7066
7101
  async function resolveIngestionSource(ctx, repoRoot) {
7067
7102
  let error = void 0;
7068
7103
  for (; ; ) {
@@ -7231,7 +7266,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
7231
7266
  async function runImplementationUseCase(currentUseCase, extraInstructions = [], isRetry = false) {
7232
7267
  if (agentRuns > 0) ctx.recordStepExecution();
7233
7268
  agentRuns += 1;
7234
- const toolContext = currentUseCase === "ingestion" ? ingestionTools : makeToolContext(repoRoot);
7269
+ const toolContext = currentUseCase === "ingestion" ? ingestionTools : { ...makeToolContext(repoRoot), dependencyManifestsOnly: true };
7235
7270
  try {
7236
7271
  return await runAgent({
7237
7272
  operation: `${currentUseCase}-implementation`,
@@ -7276,7 +7311,7 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
7276
7311
  tools: toolsForUseCase("validation"),
7277
7312
  outputSchema: validationOutputSchema,
7278
7313
  modelProfile: "validation" /* validation */,
7279
- toolContext: makeToolContext(repoRoot)
7314
+ toolContext: { ...makeToolContext(repoRoot), dependencyManifestsOnly: true }
7280
7315
  });
7281
7316
  }
7282
7317
  if (useCases.includes("ingestion")) {
@@ -7598,6 +7633,7 @@ ${detail}` : ""}`
7598
7633
  `The developer asked you to investigate this check failure: ${validation.unrelatedFailure}`
7599
7634
  );
7600
7635
  }
7636
+ extraInstructions.push(...retryTypeCheckInstructions(buildCheckPlan));
7601
7637
  }
7602
7638
  if (searchConfigFile) {
7603
7639
  const ignoreStatus = await gitIgnoreStatus(
@@ -10016,7 +10052,7 @@ async function resetProjectState() {
10016
10052
  // package.json with { type: 'json' }
10017
10053
  var package_default2 = {
10018
10054
  name: "@algolia/wizard",
10019
- version: "0.99.0",
10055
+ version: "0.101.0",
10020
10056
  description: "Magically implement Algolia functionality in your codebase",
10021
10057
  type: "module",
10022
10058
  engines: {
@@ -95,6 +95,8 @@ Ensure the attributes you map into the component match the entity. 'title' above
95
95
  - The `item` template renders content only: **no `<a>`, no `href`, no click handler of
96
96
  your own, never `stopPropagation`.** The widget's `<li>` owns the click — it sends the
97
97
  Insights `click`, closes the panel, clears the active option.
98
+ - Do not pass a top-level `onSelect` to `autocomplete()` to navigate. `getURL` already
99
+ navigates.
98
100
  - `getSearchPageURL` sends Enter with nothing highlighted to a full results page; pass it
99
101
  only if the app has one. `.getQuery` is optional.
100
102
  - TypeScript: type records through the generic, not casts inside templates —
@@ -87,6 +87,9 @@ Ensure the attributes you map into the component match the entity. 'title' above
87
87
  - `itemComponent` renders content only: **no `<a>`, no `href`, no `onClick` beyond the
88
88
  `onSelect` it is handed, never `stopPropagation`.** The widget's `<li>` owns the click —
89
89
  it sends the Insights `click`, closes the panel, clears the active option.
90
+ - Do not pass a top-level `onSelect` to `<Autocomplete>` (for example to call
91
+ `router.push`). `getURL` already navigates. The top-level callback can receive a
92
+ `SyntheticEvent` instead of `{ item }`, so reading `item` from it fails the type check.
90
93
  - `getSearchPageURL` sends Enter with nothing highlighted to a full results page; pass it
91
94
  only if the app has one. `.getQuery` is optional.
92
95
  - TypeScript: type records through the generic, not casts inside `itemComponent` —
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algolia/wizard",
3
- "version": "0.99.0",
3
+ "version": "0.101.0",
4
4
  "description": "Magically implement Algolia functionality in your codebase",
5
5
  "type": "module",
6
6
  "engines": {