@diegovelasquezweb/a11y-engine 0.11.20 → 0.11.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegovelasquezweb/a11y-engine",
3
- "version": "0.11.20",
3
+ "version": "0.11.22",
4
4
  "description": "WCAG 2.2 accessibility audit engine — scanner, analyzer, and report builders",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -249,8 +249,10 @@ async function callClaudeForPatch({ apiKey, model, aiInput }) {
249
249
  const system = [
250
250
  "You are an accessibility fix engine.",
251
251
  "Return JSON only.",
252
- "Generate deterministic text replacements for provided files.",
252
+ "Generate text replacements that fix the accessibility issue described in the finding.",
253
253
  "Do not create files. Do not modify paths outside provided filePath values.",
254
+ "CRITICAL: The 'replace' value MUST differ from the 'search' value — never return a no-op change.",
255
+ "CRITICAL: For missing attributes (e.g. alt, aria-label), you MUST add them with a descriptive value derived from context (filename, surrounding text, or role). Use empty string alt=\"\" only for purely decorative images.",
254
256
  "Schema:",
255
257
  "{\"changes\":[{\"filePath\":\"...\",\"search\":\"...\",\"replace\":\"...\"}],\"verifyRule\":\"...\",\"verifyRoute\":\"...\",\"notes\":\"...\"}",
256
258
  ].join("\n");
@@ -301,6 +303,7 @@ function validateAiPatchOutput(output, projectDir, fileSet) {
301
303
  const replace = typeof change.replace === "string" ? change.replace : "";
302
304
  if (!filePath || !search) return { ok: false, reason: "Change is missing filePath/search" };
303
305
  if (!fileSet.has(filePath)) return { ok: false, reason: `Change file not in candidate set: ${filePath}` };
306
+ if (search === replace) return { ok: false, reason: `AI generated a no-op patch for ${filePath} — search and replace are identical` };
304
307
 
305
308
  const abs = path.resolve(projectDir, filePath);
306
309
  if (!isWithin(projectDir, abs) && abs !== path.resolve(projectDir, filePath)) {