{"_id":"@appliqation/heal-selector","_rev":"4-2e083ad14c41143fdd38f61a3608dd8d","name":"@appliqation/heal-selector","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@appliqation/heal-selector","version":"0.1.0","license":"MIT","_id":"@appliqation/heal-selector@0.1.0","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"homepage":"https://github.com/appliqation/heal-selector#readme","bugs":{"url":"https://github.com/appliqation/heal-selector/issues"},"bin":{"appliqation-heal-selector":"dist/cli/index.js"},"dist":{"shasum":"2cb3763f955a1729cc36fc21e7c66637936404fc","tarball":"https://registry.npmjs.org/@appliqation/heal-selector/-/heal-selector-0.1.0.tgz","fileCount":21,"integrity":"sha512-5X/Yaq455Rhq5GajqAYNSSEnLKJpBaMTWAv3vEVBinw/KNUiPBonHo2A9Jak1XwTQgrIwCe+e1ps0L/MNFJ/Yw==","signatures":[{"sig":"MEUCIEUj8EAApKWhSDGJVYhWwfJO3Hwa6UMEZmtqMklzvyPrAiEAnPfO424235yeioLBWsTwHL8JKsWoIs7mk9DZOQohFys=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70645},"type":"module","engines":{"node":">=20"},"gitHead":"fd1259542a29e23c172e8ef28b1c96e9b670e2bc","scripts":{"dev":"tsx src/cli/index.ts","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest"},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"repository":{"url":"git+https://github.com/appliqation/heal-selector.git","type":"git"},"_npmVersion":"11.7.0","description":"Standalone agent that heals one broken Playwright selector in an existing script — narrow and token-efficient, never a full regenerate. Verifies a healed selector targets the same semantic element (accessibility role + name, the test case's own expected_r","directories":{},"_nodeVersion":"23.10.0","dependencies":{"dotenv":"^16.4.7","commander":"^13.1.0","playwright":"^1.51.0","@appliqation/agent-core":"^0.1.5"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","eslint":"^9.39.5","vitest":"^3.2.7","@eslint/js":"^9.39.5","typescript":"^5.8.2","@types/node":"^22.13.10","typescript-eslint":"^8.67.0"},"_npmOperationalInternal":{"tmp":"tmp/heal-selector_0.1.0_1788163944840_0.9186749381667865","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@appliqation/heal-selector","version":"0.1.1","license":"MIT","_id":"@appliqation/heal-selector@0.1.1","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"homepage":"https://github.com/appliqation/heal-selector#readme","bugs":{"url":"https://github.com/appliqation/heal-selector/issues"},"bin":{"appliqation-heal-selector":"dist/cli/index.js"},"dist":{"shasum":"88ebe00adf5748a267acb840348d9ea23601ca7f","tarball":"https://registry.npmjs.org/@appliqation/heal-selector/-/heal-selector-0.1.1.tgz","fileCount":21,"integrity":"sha512-JjsOhSe6duitoV1d+3OBO8wkPM0rwyTvs0wATS9T65c0cUYncVJJjpQVcVzCdjUQZeNr1/iwXVm8Rvovl7AAPg==","signatures":[{"sig":"MEUCIAunYkov5KKENwYHO9ZNk+2+Ac96WTRhRTa2g/Zo3lIqAiEA5VZvyd4/T2z0w4R57WCuI3w8zLqWg5/MwR96d+Q4ta4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70601},"type":"module","engines":{"node":">=20"},"gitHead":"54367d3037a6f9f9d99481d538caef902d36d5a5","scripts":{"dev":"tsx src/cli/index.ts","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest"},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"repository":{"url":"git+https://github.com/appliqation/heal-selector.git","type":"git"},"_npmVersion":"11.7.0","description":"Standalone agent that heals one broken Playwright selector in an existing script: narrow and token-efficient, never a full regenerate. Verifies a healed selector targets the same semantic element (accessibility role + name, the test case's own expected_re","directories":{},"_nodeVersion":"23.10.0","dependencies":{"dotenv":"^16.4.7","commander":"^13.1.0","playwright":"^1.51.0","@appliqation/agent-core":"^0.1.5"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","eslint":"^9.39.5","vitest":"^3.2.7","@eslint/js":"^9.39.5","typescript":"^5.8.2","@types/node":"^22.13.10","typescript-eslint":"^8.67.0"},"_npmOperationalInternal":{"tmp":"tmp/heal-selector_0.1.1_1788165395108_0.8660682887186564","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@appliqation/heal-selector","version":"0.1.2","license":"MIT","_id":"@appliqation/heal-selector@0.1.2","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"homepage":"https://github.com/appliqation/heal-selector#readme","bugs":{"url":"https://github.com/appliqation/heal-selector/issues"},"bin":{"appliqation-heal-selector":"dist/cli/index.js"},"dist":{"shasum":"4e406e26462773c6fe3fa7b94f7b8b345ddd39f9","tarball":"https://registry.npmjs.org/@appliqation/heal-selector/-/heal-selector-0.1.2.tgz","fileCount":21,"integrity":"sha512-K+9wFbnHpKFGql1S2g8MbjFAnOx0oYNhZWh+hf1J6gGpo2zUJpjwmNl0rw/cwCSvi0pQeja7o6UyS8weINorFg==","signatures":[{"sig":"MEUCIQCAahjrYOsvjZahmLa4DZY8ljg43KqIBATzfzEybT6OZgIgGEI952akekAkV8ZFqzOQKD6TmhEscItC3PNU/aZ2BRw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73377},"type":"module","engines":{"node":">=20"},"gitHead":"5bb1e5ac308d83cf4e8b7649608fc3bcd3619a2b","scripts":{"dev":"tsx src/cli/index.ts","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc -p tsconfig.json --noEmit","test:watch":"vitest"},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"repository":{"url":"git+https://github.com/appliqation/heal-selector.git","type":"git"},"_npmVersion":"11.7.0","description":"Standalone agent that heals one broken Playwright selector in an existing script: narrow and token-efficient, never a full regenerate. Verifies a healed selector targets the same semantic element (accessibility role + name, the test case's own expected_re","directories":{},"_nodeVersion":"23.10.0","dependencies":{"dotenv":"^16.4.7","commander":"^13.1.0","playwright":"^1.51.0","@appliqation/agent-core":"^0.1.7"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.3","eslint":"^9.39.5","vitest":"^3.2.7","@eslint/js":"^9.39.5","typescript":"^5.8.2","@types/node":"^22.13.10","typescript-eslint":"^8.67.0"},"_npmOperationalInternal":{"tmp":"tmp/heal-selector_0.1.2_1788433863715_0.8050608575043288","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@appliqation/heal-selector","version":"0.1.3","description":"Standalone agent that heals one broken Playwright selector in an existing script: narrow and token-efficient, never a full regenerate. Verifies a healed selector targets the same semantic element (accessibility role + name, the test case's own expected_re","license":"MIT","repository":{"type":"git","url":"git+https://github.com/appliqation/heal-selector.git"},"homepage":"https://github.com/appliqation/heal-selector#readme","bugs":{"url":"https://github.com/appliqation/heal-selector/issues"},"type":"module","bin":{"appliqation-heal-selector":"dist/cli/index.js"},"engines":{"node":">=20"},"scripts":{"build":"tsc -p tsconfig.build.json","dev":"tsx src/cli/index.ts","typecheck":"tsc -p tsconfig.json --noEmit","lint":"eslint src --ext .ts","test":"vitest run","test:watch":"vitest"},"dependencies":{"@appliqation/agent-core":"^0.1.7","commander":"^13.1.0","dotenv":"^16.4.7","playwright":"^1.51.0"},"devDependencies":{"@eslint/js":"^9.39.5","@types/node":"^22.13.10","eslint":"^9.39.5","tsx":"^4.19.3","typescript":"^5.8.2","typescript-eslint":"^8.67.0","vitest":"^3.2.7"},"gitHead":"e764e1aab97f0a09f1fee443a030c72532de2bfb","_id":"@appliqation/heal-selector@0.1.3","_nodeVersion":"23.10.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-vjJTkck+HQSq34B5ltdoYyLK76eSt6edJMCuv6V8qRcjET1ldRSCZxSn2yczY64YlVCtiLTu/vDlFLKb1y6WvA==","shasum":"62ff53f3b81925d1fe8a65098a62861384df3c7e","tarball":"https://registry.npmjs.org/@appliqation/heal-selector/-/heal-selector-0.1.3.tgz","fileCount":21,"unpackedSize":74516,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCZH6xK7fOzepIQ8Agzl26mg7bMT76WGdHzQoxqx19h4AIhALkux9loRohmb3l6iU5ZzaqhTWGXX1FZ6X4oMFxapnoG"}]},"_npmUser":{"name":"archana6","email":"accounts@appliqation.io"},"directories":{},"maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/heal-selector_0.1.3_1788494070481_0.9408312707910291"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T08:12:24.598Z","modified":"2026-09-04T03:54:30.789Z","0.1.0":"2026-08-31T08:12:24.984Z","0.1.1":"2026-08-31T08:36:35.260Z","0.1.2":"2026-09-03T11:11:03.842Z","0.1.3":"2026-09-04T03:54:30.653Z"},"bugs":{"url":"https://github.com/appliqation/heal-selector/issues"},"license":"MIT","homepage":"https://github.com/appliqation/heal-selector#readme","repository":{"type":"git","url":"git+https://github.com/appliqation/heal-selector.git"},"description":"Standalone agent that heals one broken Playwright selector in an existing script: narrow and token-efficient, never a full regenerate. Verifies a healed selector targets the same semantic element (accessibility role + name, the test case's own expected_re","maintainers":[{"name":"archana6","email":"accounts@appliqation.io"}],"readme":"# Appliqation Heal-Selector\n\n**Heals one broken Playwright selector in an existing, already-working script: narrow and token-efficient, never a full regenerate.**\n\nPoint it at a script, the selector that's failing, and why. It decides whether that's genuine selector staleness (heal it) or a real behaviour change (decline, not a healing case), verifies its answer against the live page's own accessibility tree, and only ever patches the one line, only after a real `npx playwright test` run confirms the fix actually works.\n\n## Why this exists\n\nA test-set regression run naturally sorts into three buckets: canonical scripts that still pass (nothing to do), test cases with no canonical script at all (a job for [`appliqation-scriptgen`](https://github.com/appliqation/scriptgen)), and canonical scripts that just started failing. That third bucket is ambiguous by nature: did the *app* regress, or did the *script* just go stale (a renamed id, a restructured DOM, the same element findable a different way)? Regenerating the whole script from scratch to answer that is wasteful when the real fix is one selector. This agent is built specifically for that bucket.\n\n## The one rule that matters more than anything else here\n\n**This agent must never \"heal\" a selector by finding one that merely makes the assertion pass again.** That's worse than leaving it broken: it fails silently and looks like success. A heal only happens once the model has established, from real evidence, that the new selector targets the *same semantic element* the original one did:\n\n- **Accessibility role + accessible name**, read from the live page itself (the primary signal, always available).\n- **The test case's own expected-result text**, from Appliqation, cross-checked against any candidate element.\n- **Recorded session data**, when a caller happens to have it (a bonus signal, never required).\n\nNo confident match means no heal. It reports a clear decline instead, touches nothing, and hands off to a human or [`appliqation-defect-fix`](https://github.com/appliqation/defect-fix).\n\n## Quick start\n\n```bash\nnpm install -g @appliqation/heal-selector\nnpx playwright install chromium\n```\n\nCreate a `.env` file (in whatever directory you'll run it from) with:\n\n```\nAPPQ_API_KEY=your-appliqation-api-key   # read-only is enough\nANTHROPIC_API_KEY=your-anthropic-key    # or OPENAI_API_KEY (pick one)\n```\n\n```bash\nappliqation-heal-selector heal \\\n  --test-case-uuid 2424-8e61a1f0-4bba-4b7b-8fe5-f8ae19e65026 \\\n  --script-path tests/appliqation/scenario-2424/8e61a1f0.spec.ts \\\n  --failure \"Locator #subscribe-btn not found, likely renamed or restructured\" \\\n  --environment Stage \\\n  --repo-path /path/to/your/checkout\n```\n\nAdd `--json`/`--ci` for a structured summary. The exit code is 0 only when a patch was written *and* independently verified by a real, post-patch test run. A decline, or an unverified attempt, both exit non-zero; the JSON summary's `declined` field tells them apart.\n\n## CLI reference\n\n`appliqation-heal-selector heal [options]`\n\n**Required:**\n\n| Option | Description |\n|---|---|\n| `--test-case-uuid <uuid>` | Test case this failing selector belongs to. |\n| `--script-path <path>` | The script file containing the broken selector, relative to `--repo-path`. |\n| `--failure <text>` | Free-text description of what is failing and why: a step name, the selector, an error message. Whatever the caller already knows. |\n| `--environment <name>` | Environment name — its URL (from `get_project_settings`) is what the browser navigates to. |\n\n**Optional:**\n\n| Option | Description |\n|---|---|\n| `--defect-id <id>` | A defect linked to this failure, if known — offered as extra diagnostic context. |\n| `--repo-path <path>` | Target repo root every file/command tool call is scoped to. Defaults to the current working directory. |\n| `--max-turns <n>` | Override `BUDGET_MAX_TURNS` for this run. |\n| `--json` | Print a single structured JSON summary on stdout instead of a human-readable report. |\n| `--ci` | Shorthand for `--json`; exit code already reflects the real, `execFile`-verified outcome either way. |\n\n## Configuration\n\nCopy `.env.example` to `.env`. Requires `APPQ_API_KEY` (read-only access is sufficient; this agent never calls an appq write tool) and one of `ANTHROPIC_API_KEY`/`OPENAI_API_KEY`.\n\n## Running this safely\n\nThis agent has real filesystem write access (scoped to `--repo-path`, path-escape and symlink protected), a real shell (allowlisted to a targeted `npx playwright test` and nothing else; no package installation, no bootstrap commands), and a real browser. It never calls an Appliqation write tool and never touches git. A separate agent ([`appliqation-pr-raise`](https://github.com/appliqation/pr-raise)) is responsible for committing and pushing whatever this one patches.\n\n**Run this inside a container with an egress allowlist**, same as every agent in this family. This process only ever legitimately needs to reach:\n\n- your LLM provider (`api.anthropic.com` or `api.openai.com`)\n- your configured `APPQ_ORIGIN` (`appq.appliqation.io` by default)\n- the site under test (whatever `--environment` resolves to)\n\nAnything else this process tries to reach is unexpected and worth investigating.\n\n## Development\n\n```bash\ngit clone https://github.com/appliqation/heal-selector.git\ncd heal-selector\nnpm install\ncp .env.example .env   # fill in APPQ_API_KEY (read-only) and an LLM key\nnpm run dev -- heal --test-case-uuid <uuid> --script-path <path> --failure \"<text>\" --environment <name> --repo-path <path>\nnpm run typecheck\nnpm test\n```\n\nSee `CLAUDE.md` for a map of this repo if you're working in it with an AI coding assistant.\n\n## License\n\nMIT. See [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}