From abf7773c3d34a19559cd0911175280843cf47dec Mon Sep 17 00:00:00 2001 From: Abdul Wahab Date: Fri, 28 Aug 2026 00:52:12 +0500 Subject: [PATCH] Fix: stop the plugin subtree from running the project's skill copy (#523) The ./plugin subtree copied dist/claude-code output verbatim, so its 44 markdown instructions said `node .claude/skills/impeccable/scripts/...`, a path inside the user's project. A plugin-only install got MODULE_NOT_FOUND; a dual install silently ran the project's older skill copy with zero indication anything was wrong. The build now rewrites the plugin subtree's markdown after the copy: - Every script instruction takes the quoted `node "/ scripts/..."` form (quoted because the loaded plugin directory can contain spaces), resolving against the base directory the runtime reports, since no literal path works for plugins (CLAUDE_PLUGIN_ROOT is hook-only). - Setup step 1 loses its project-path fallback clause: a plugin install has no working project fallback, that path being the bug itself. - The `Bash(node .claude/skills/impeccable/scripts/*)` allowed-tools entry is dropped rather than widened: a wildcard such as `node */skills/impeccable/scripts/*` would auto-approve any same-shaped path anywhere on disk (per review), and frontmatter has no variable bound to the plugin root. Script runs go through the normal Bash confirmation. - A build-time guard fails build:release when SKILL.src.md's wording drifts past the rewrite, when a node pre-approval reappears, or when any project-relative scripts path survives in the plugin SKILL.md. Drafted with AI assistance, reviewed by a maintainer. Co-authored-by: Cursor --- plugin/agents/impeccable-asset-producer.md | 2 +- plugin/skills/impeccable/SKILL.md | 5 +- .../skills/impeccable/reference/critique.md | 10 +- .../reference/degraded/asset-producer.md | 2 +- plugin/skills/impeccable/reference/doctor.md | 4 +- plugin/skills/impeccable/reference/hooks.md | 12 +- plugin/skills/impeccable/reference/layout.md | 2 +- .../skills/impeccable/reference/live-setup.md | 2 +- plugin/skills/impeccable/reference/live.md | 26 +-- .../skills/impeccable/reference/new-work.md | 14 +- plugin/skills/impeccable/reference/polish.md | 2 +- plugin/skills/impeccable/reference/routing.md | 4 +- plugin/skills/impeccable/reference/typeset.md | 2 +- .../skills/impeccable/reference/visualize.md | 2 +- scripts/build.js | 9 + scripts/lib/plugin-paths.js | 118 +++++++++++ scripts/test-suites.mjs | 2 + tests/plugin-paths.test.js | 197 ++++++++++++++++++ 18 files changed, 370 insertions(+), 45 deletions(-) create mode 100644 scripts/lib/plugin-paths.js create mode 100644 tests/plugin-paths.test.js diff --git a/plugin/agents/impeccable-asset-producer.md b/plugin/agents/impeccable-asset-producer.md index 1cecdaa1e..1d7c4d626 100644 --- a/plugin/agents/impeccable-asset-producer.md +++ b/plugin/agents/impeccable-asset-producer.md @@ -56,7 +56,7 @@ Ask blockers once, globally. Missing source path/crops or output directory block 7. Remove baked-in UI text, navigation, buttons, body copy, and mock chrome unless the text is part of the asset. 8. Think through the final DOM/CSS representation before generating. If CSS will own radius, clipping, shadows, borders, perspective, responsive cropping, captions, or card frames, do not bake those into the bitmap. -9. Save outputs non-destructively in the requested project directory, and leave the intent with the file: after every generation, run `node .claude/skills/impeccable/scripts/embed-prompt.mjs --prompt ""` so the prompt lives inside the image itself. The build thread composes what you made and needs to know what it is looking at, and the embedding survives copies where sidecars get lost. +9. Save outputs non-destructively in the requested project directory, and leave the intent with the file: after every generation, run `node "/scripts/embed-prompt.mjs" --prompt ""` so the prompt lives inside the image itself. The build thread composes what you made and needs to know what it is looking at, and the embedding survives copies where sidecars get lost. 10. Compare each output against its source crop, opening every image by its workspace-relative path; sandboxed viewers reject absolute paths. If a review/QA tool is available, run it before the final manifest, then retry each major/fatal finding once before finalizing. Use `texture/pattern extraction` only when the source region is already clean enough to sample as texture. If UI, cards, labels, headings, body copy, or footer chrome must be removed first, classify it as crop-derived cleanup or clean-plate work. diff --git a/plugin/skills/impeccable/SKILL.md b/plugin/skills/impeccable/SKILL.md index 583d62a3d..61f7b8ecc 100644 --- a/plugin/skills/impeccable/SKILL.md +++ b/plugin/skills/impeccable/SKILL.md @@ -7,7 +7,6 @@ argument-hint: "[shape · audit|critique · animate|bolder|colorize|delight|layo license: Apache 2.0 allowed-tools: - Bash(npx impeccable *) - - Bash(node .claude/skills/impeccable/scripts/*) --- This skill gives you the tools and permission to create design that earns to be called out-of-distribution craft: Whereas before, your design work would have been safe, timid and measured, you now approach every design task as a award-winning design director with impeccable understanding for what makes exceptional design work: production-grade code, peak creativity, a clear POV, deep understanding of the needs of the client and users, and exceptional craft. @@ -19,7 +18,7 @@ Core principles: ## Setup -1. Run `node /scripts/context.mjs` once per session, where `` is the loaded base directory the runtime reports for this skill; keep cwd at the user's project. That base directory resolves every `node .claude/skills/impeccable/scripts/...` command in this skill and its references, and `.claude/skills/impeccable/scripts` is the fallback only when the runtime reports no base directory. Pass a named source file or route as `--target `. It loads PRODUCT.md, DESIGN.md, the matching surface brief, and native-platform guidance when applicable; follow its directives and do not rerun it. +1. Run `node "/scripts/context.mjs"` once per session, where `` is the loaded base directory the runtime reports for this skill; keep cwd at the user's project. Every `node "/scripts/..."` command in this skill and its references resolves against that base directory. Pass a named source file or route as `--target `. It loads PRODUCT.md, DESIGN.md, the matching surface brief, and native-platform guidance when applicable; follow its directives and do not rerun it. 2. Before acting, load the one playbook that owns the request: the Commands table's reference for an explicit or clearly implied sub-command, or [reference/new-work.md](reference/new-work.md) for a new surface or replacement visual world. Then inspect the target and at least one representative source of incumbent visual truth (tokens, theme, CSS, component, or asset) before editing. 3. After analysis and direction are resolved, load [reference/craft-floor.md](reference/craft-floor.md) immediately before editing UI. It carries the quality floor, the absolute bans, and the reflexes no detector catches. Do not load it for planning-only work. @@ -77,7 +76,7 @@ Routing: After init writes PRODUCT.md, resume without rerunning `context.mjs`; init loads the native platform reference itself when the platform it recorded is `ios`, `android`, or `adaptive`. -**Pin / Unpin:** `node .claude/skills/impeccable/scripts/pin.mjs ` creates or removes a standalone `/` shortcut. Report the script's result concisely; relay stderr verbatim on error. +**Pin / Unpin:** `node "/scripts/pin.mjs" ` creates or removes a standalone `/` shortcut. Report the script's result concisely; relay stderr verbatim on error. **Hooks:** `/impeccable hooks ` manages the design detector hook for this project (auto-runs the detector after UI file edits and surfaces findings). Load [reference/hooks.md](reference/hooks.md) when the user invokes it with any argument. diff --git a/plugin/skills/impeccable/reference/critique.md b/plugin/skills/impeccable/reference/critique.md index 637e73fca..d298da3eb 100644 --- a/plugin/skills/impeccable/reference/critique.md +++ b/plugin/skills/impeccable/reference/critique.md @@ -23,7 +23,7 @@ Resolve one stable target, run two independent assessments, synthesize a design - "this page" -> the current URL or source file 2. **Confirm the target slugs cleanly**: ```bash - node .claude/skills/impeccable/scripts/critique-storage.mjs slug "" + node "/scripts/critique-storage.mjs" slug "" ``` Every later command also accepts the resolved target directly and derives the same slug internally; never hand-write a slug. If this exits non-zero, skip persistence and trend for this run, but continue the critique. 3. **Read `.impeccable/critique/ignore.md`** if it exists. Drop matching findings silently; it is the only prior-run input critique consumes. @@ -59,7 +59,7 @@ Run the bundled detector and browser visualization evidence. Assessment B is man CLI scan: ```bash -node .claude/skills/impeccable/scripts/detect.mjs --json [target] +node "/scripts/detect.mjs" --json [target] ``` - Pass markup files/directories as `[target]`; do not pass CSS-only files. @@ -73,7 +73,7 @@ Browser visualization is required for a viewable target when browser automation 1. Create a fresh tab and navigate. Prefer the harness's native/browser-canvas screenshot path before hand-rolling a Playwright/Puppeteer script; only fall back to a custom script when no native browser tool is exposed. 2. Preflight mutable injection by setting `document.title` and appending a `