feat(open-claude-design)!: discovery, init, reference discovery, live QA - #1470
Conversation
…erence discovery, live QA Rework the builtin open-claude-design workflow around the accessible impeccable skill (/skill:impeccable ...): - Add a discovery interview stage (/skill:impeccable shape) that confirms the brief, output type, and references; user references take precedence over DESIGN.md/PRODUCT.md. - Always run a project-context init stage (/skill:impeccable init) that creates missing PRODUCT.md/DESIGN.md and reconciles existing files without clobbering. - Combine onboarding, gated gallery reference-discovery, and reference import into one concurrent context fan-out, then synthesize the design system; reference-discovery clicks into standout work and records a scroll-through video (full-page screenshot fallback) of the real design pages plus their destination URLs. - Drive /skill:impeccable live from the preview-display stages for in-browser variant QA; thread accepted variants (live_changes) through the refinement feedback. - Factor new logic into open-claude-design-setup.ts; add discoveryDecisionSchema/REFERENCE_PRECEDENCE to utils; update docs, changelogs, spec, and tests. BREAKING CHANGE: removed the open-claude-design inputs reference, output_type, and design_system; the discovery stage now asks for the output type and references. Remaining inputs: prompt, discover_references, max_refinements. Assistant-model: Claude Opus 4.8
Sync the vendored impeccable skill that was already modified in the working tree: SKILL.md (v3.8.0), reference/ docs, and the detector/live-mode scripts. Reorganizes live-mode helpers under scripts/live/ and scripts/lib/, adds detector/design-system.mjs plus detector inline-ignore support, and drops deprecated standalone script files. Bundled here alongside the open-claude-design workflow changes per request. Assistant-model: Claude Opus 4.8
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Review: feat(open-claude-design)!: discovery-first restructure + live QA Reviewed the authored workflow logic (open-claude-design-*.ts), the new tests, and the input/output contract. I scoped the bundled impeccable-skill refresh out of the detailed pass (see PR-hygiene note). Overall this is a clean, well-structured change — nicely modularized to stay under the 500-line gate, strong graceful-degradation discipline, and good test coverage for the issue-1464 feedback-threading guardrail. A few things worth addressing before merge. 🐞 Potential bugs
🧹 Code quality / maintainability
⚙️ Security & runtime notes (non-blocking)
✅ Things that are good
📦 PR hygiene Nice work overall — items 1 and 2 are the only ones I would consider blocking. Automated review via Claude Code. |
Address the CodeQL alerts on PR #1470, all in the vendored impeccable skill scripts: make the HTML strip regexes whitespace-tolerant (match `</script >`/`</style >`) and strip script/style/comment blocks to a fixpoint so partial overlaps cannot survive one pass (Bad HTML filtering regexp + Incomplete multi-character sanitization in svelte-component.mjs and detector/shared/page.mjs); drop the redundant `String(stack || '')` fallback now that `stack` is guaranteed truthy by the earlier `!stack` guard (detector/browser/injected/index.mjs and detect-antipatterns-browser.js); and remove the unused `outputLines` variable and `attrEscapeDouble` function (live-wrap.mjs). Assistant-model: Claude Opus 4.8
…, sanitization) Make script/style end-tag regexes tolerate junk before `>` (`</script bar>`) by using `[^>]*>` instead of `\s*>`, which clears both the js/bad-tag-filter alerts and the dependent js/incomplete-multi-character-sanitization alerts (an unmatched closer left `<script`/`<style` in the string) across svelte-component.mjs, detect-text.mjs, checks.mjs, detect-antipatterns-browser.js, live-accept.mjs, live-browser.js, and sveltekit-adapter.mjs. Also: fix the no-op `-ms-` vendor-prefix replacement (`/^ms-/` -> `-ms-`; js/identity-replacement), escape backslashes before quotes when building the variant selector (js/incomplete-sanitization), and run `git check-ignore` via execFileSync with an argv array instead of a shell string (js/shell-command-injection-from-environment). Assistant-model: Claude Opus 4.8
Code Review — PR #1470:
|
…-adapter Revert the over-broad `<script\b[^>]*>...<\/script[^>]*>` form back to the original literal `<script></script>` match: this line only removes Svelte's empty-script compiler artifact, and the broader pattern made CodeQL's js/bad-tag-filter treat it as a (bad) general script-tag filter. Assistant-model: Claude Opus 4.8
Code Review —
|
…PR review Address the code review on #1470: - Medium (blocker): the refinement loop's early `break` on ready_for_export bypassed assertUserAnnotationsThreaded, re-opening #1464 at the gate. Add a deterministic guard (unappliedMeaningfulFeedback) that refuses an immediate export approval while the latest preview captured meaningful, unaddressed annotations, forcing one apply pass (which threads them) first. Covered by a new gate test plus a no-annotations fast-path test. - Low: assertUserAnnotationsThreaded now also enforces liveChanges threading, not just userNotes, matching the stated contract (with a unit test). - Nit: drop `a`/`n` from the placeholder-token set so a one-character real note survives. - Nit: fix the `staff design enginer` prompt typo. Assistant-model: Claude Opus 4.8
|
Thanks for the thorough review — addressed in 🟠 Medium (the blocker) — early-break export gate. Fixed deterministically. 🟡 Low — guardrail vs 🔵 Nits
Deliberately left as-is (flagging the rationale):
Full suite green locally: typecheck, lint, |
Code Review —
|
…ic early exit Address the second code review on #1470: - #1 (residual #1464): annotations captured on the FINAL preview-display iteration were orphaned (never threaded, never exported). The final iteration's preview-display and the post-export final-display are now read-only — they no longer solicit user_notes/live_changes they cannot apply and instead point the user at re-running — via a new `final` mode on buildLivePreviewDisplayPrompt; the loop skips capture on the terminal iteration. - #2: final-display no longer asks for (then discards) user_notes/annotated_snapshot. - Per the maintainer note, added a deterministic browser-centric early exit: when the playwright-cli browser is unavailable, the run calls ctx.exit() up front (surfacing the would-be artifact paths + install instructions) instead of generating a design no one can review. Gated via shouldEarlyExitForBrowser so NODE_ENV=test and runtimes without ctx.exit run to completion. - #3: reworded ds-analyzer/ds-patterns objectives so each clearly does its own independent scan (the fan-out is parallel, not a pipeline). - #4: copyAnnotationArtifacts now refuses to copy a model-supplied snapshot path resolving outside the project/artifact dir. - Added tests for the final-mode prompt, the early-exit predicate, and snapshot containment; updated docs + changelogs. Assistant-model: Claude Opus 4.8
|
Thanks — addressed in 🟠 1 — terminal-iteration annotations dropped (residual #1464). Fixed. 🟠 2 — Browser-centric early exit (per the maintainer's note that 🟡 3 — parallel onboarding prompts implied a pipeline. Reworded the 🟡 4 — 🔵 Nits. The New tests cover the read-only final prompt, the early-exit predicate, and the snapshot-containment check; docs and both changelogs updated. Full suite green locally: typecheck, lint, |
Code Review — PR #1470:
|
… QA (#1470) * feat(open-claude-design)!: discovery-first restructure with init, reference discovery, live QA Rework the builtin open-claude-design workflow around the accessible impeccable skill (/skill:impeccable ...): - Add a discovery interview stage (/skill:impeccable shape) that confirms the brief, output type, and references; user references take precedence over DESIGN.md/PRODUCT.md. - Always run a project-context init stage (/skill:impeccable init) that creates missing PRODUCT.md/DESIGN.md and reconciles existing files without clobbering. - Combine onboarding, gated gallery reference-discovery, and reference import into one concurrent context fan-out, then synthesize the design system; reference-discovery clicks into standout work and records a scroll-through video (full-page screenshot fallback) of the real design pages plus their destination URLs. - Drive /skill:impeccable live from the preview-display stages for in-browser variant QA; thread accepted variants (live_changes) through the refinement feedback. - Factor new logic into open-claude-design-setup.ts; add discoveryDecisionSchema/REFERENCE_PRECEDENCE to utils; update docs, changelogs, spec, and tests. BREAKING CHANGE: removed the open-claude-design inputs reference, output_type, and design_system; the discovery stage now asks for the output type and references. Remaining inputs: prompt, discover_references, max_refinements. Assistant-model: Claude Opus 4.8 * chore(impeccable): refresh bundled impeccable skill assets Sync the vendored impeccable skill that was already modified in the working tree: SKILL.md (v3.8.0), reference/ docs, and the detector/live-mode scripts. Reorganizes live-mode helpers under scripts/live/ and scripts/lib/, adds detector/design-system.mjs plus detector inline-ignore support, and drops deprecated standalone script files. Bundled here alongside the open-claude-design workflow changes per request. Assistant-model: Claude Opus 4.8 * fix(impeccable): resolve CodeQL findings in bundled skill scripts Address the CodeQL alerts on PR #1470, all in the vendored impeccable skill scripts: make the HTML strip regexes whitespace-tolerant (match `</script >`/`</style >`) and strip script/style/comment blocks to a fixpoint so partial overlaps cannot survive one pass (Bad HTML filtering regexp + Incomplete multi-character sanitization in svelte-component.mjs and detector/shared/page.mjs); drop the redundant `String(stack || '')` fallback now that `stack` is guaranteed truthy by the earlier `!stack` guard (detector/browser/injected/index.mjs and detect-antipatterns-browser.js); and remove the unused `outputLines` variable and `attrEscapeDouble` function (live-wrap.mjs). Assistant-model: Claude Opus 4.8 * fix(impeccable): harden HTML-strip regexes for CodeQL (bad-tag-filter, sanitization) Make script/style end-tag regexes tolerate junk before `>` (`</script bar>`) by using `[^>]*>` instead of `\s*>`, which clears both the js/bad-tag-filter alerts and the dependent js/incomplete-multi-character-sanitization alerts (an unmatched closer left `<script`/`<style` in the string) across svelte-component.mjs, detect-text.mjs, checks.mjs, detect-antipatterns-browser.js, live-accept.mjs, live-browser.js, and sveltekit-adapter.mjs. Also: fix the no-op `-ms-` vendor-prefix replacement (`/^ms-/` -> `-ms-`; js/identity-replacement), escape backslashes before quotes when building the variant selector (js/incomplete-sanitization), and run `git check-ignore` via execFileSync with an argv array instead of a shell string (js/shell-command-injection-from-environment). Assistant-model: Claude Opus 4.8 * fix(impeccable): keep the literal empty-<script> cleanup in sveltekit-adapter Revert the over-broad `<script\b[^>]*>...<\/script[^>]*>` form back to the original literal `<script></script>` match: this line only removes Svelte's empty-script compiler artifact, and the broader pattern made CodeQL's js/bad-tag-filter treat it as a (bad) general script-tag filter. Assistant-model: Claude Opus 4.8 * fix(open-claude-design): close export-gate annotation-drop + address PR review Address the code review on #1470: - Medium (blocker): the refinement loop's early `break` on ready_for_export bypassed assertUserAnnotationsThreaded, re-opening #1464 at the gate. Add a deterministic guard (unappliedMeaningfulFeedback) that refuses an immediate export approval while the latest preview captured meaningful, unaddressed annotations, forcing one apply pass (which threads them) first. Covered by a new gate test plus a no-annotations fast-path test. - Low: assertUserAnnotationsThreaded now also enforces liveChanges threading, not just userNotes, matching the stated contract (with a unit test). - Nit: drop `a`/`n` from the placeholder-token set so a one-character real note survives. - Nit: fix the `staff design enginer` prompt typo. Assistant-model: Claude Opus 4.8 * fix(open-claude-design): close terminal-feedback drop + browser-centric early exit Address the second code review on #1470: - #1 (residual #1464): annotations captured on the FINAL preview-display iteration were orphaned (never threaded, never exported). The final iteration's preview-display and the post-export final-display are now read-only — they no longer solicit user_notes/live_changes they cannot apply and instead point the user at re-running — via a new `final` mode on buildLivePreviewDisplayPrompt; the loop skips capture on the terminal iteration. - #2: final-display no longer asks for (then discards) user_notes/annotated_snapshot. - Per the maintainer note, added a deterministic browser-centric early exit: when the playwright-cli browser is unavailable, the run calls ctx.exit() up front (surfacing the would-be artifact paths + install instructions) instead of generating a design no one can review. Gated via shouldEarlyExitForBrowser so NODE_ENV=test and runtimes without ctx.exit run to completion. - #3: reworded ds-analyzer/ds-patterns objectives so each clearly does its own independent scan (the fan-out is parallel, not a pipeline). - #4: copyAnnotationArtifacts now refuses to copy a model-supplied snapshot path resolving outside the project/artifact dir. - Added tests for the final-mode prompt, the early-exit predicate, and snapshot containment; updated docs + changelogs. Assistant-model: Claude Opus 4.8
Summary
Restructures the builtin
open-claude-designworkflow around the accessibleimpeccableskill (/skill:impeccable …). The workflow now opens with a discovery interview, always bootstraps project design context viainit, runs design-system onboarding + gallery reference discovery + reference import in a single concurrent context phase, and usesimpeccable livefor in-browser element-level QA. Also fixes annotation feedback being silently dropped between preview and refinement stages, and bundles a pending impeccable skill v3.8.0 refresh.Breaking Changes
Three top-level inputs are removed; the discovery stage now gathers them interactively.
referencepromptor answer the discovery interviewoutput_typeprototype/wireframe/page/component/theme/tokens)design_systeminitstageRemaining inputs:
prompt,discover_references(defaulttrue),max_refinements.Migration: drop
reference=…,output_type=…,design_system=…from existing invocations, or fold them intoprompt. The discovery interview will ask for anything it can't infer.Key Changes
open-claude-designworkflow — new phase orderDiscovery (
/skill:impeccable shape): new first stage interviews the user for a confirmed brief, output type, and references via the structured question tool, returning{ brief, output_type, references }. User-supplied references take precedence overDESIGN.md/PRODUCT.md(DESIGN.md fills gaps; PRODUCT.md governs register/voice). AREFERENCE_PRECEDENCEnote threads into the import, generator, and apply-changes prompts. Headless runs infer a defensible brief without blocking.Init (always runs) (
/skill:impeccable init): detectsPRODUCT.md/DESIGN.md(root,.agents/context/, ordocs/, case-insensitive), creates whichever is missing, and reconciles existing files against the discovery brief without clobbering them. Reuses discovery answers so nothing is asked twice. Best-effort; never blocks the run.Combined context phase (single concurrent fan-out): design-system onboarding (
ds-locator→ds-analyzer→ds-patterns), gated gallery reference-discovery (Awwwards, recent.design, Dribbble, Monet, Motionsites —playwright-cliclicks into standout work, records a scroll-through video for animation fidelity, falls back to full-page screenshot + real URL, persists to<artifact_dir>/references.md; web-search fallback if browser is unavailable), and per-reference import (web-capture-<n>/file-parser-<n>) all run in onectx.parallelfan-out beforedesign-system-buildersynthesizes the design system. Setdiscover_references=falseto skip the gallery pass.Generation → 5. Live QA → 6. Export gate
Live QA (
/skill:impeccable live)preview-display-*stages drive/skill:impeccable liveagainst the staticpreview.html— pick elements in the browser, annotate them, compare three on-brand variants, accept one that is written back in place. Degrades toplaywright-cli show --annotate, then a manual file path.New modules
open-claude-design-setup.ts:runDiscovery,detectDesignContextFiles,ensureProjectDesignContext,buildReferenceDiscoveryPrompt,persistReferencesBrief,buildLivePreviewDisplayPromptopen-claude-design-feedback.ts: feedback parser, merged-brief builder, guardraildiscoveryDecisionSchema/discoveryDecisionFromResult/REFERENCE_PRECEDENCEadded to utilsNew unit tests
Added coverage for: discovery schema/parse, always-run init + reconcile + discovery-context threading, combined context fan-out, reference-discovery prompt/persist, live-QA prompt, trimmed input contract, full-run init path,
live_changescapture/threading/persistence, feedback parser, merged-brief ordering, guardrail, and artifact persistence.Bug Fixes
Annotation feedback dropped between preview and refinement (#1464)
preview-display-*results were awaited-and-discarded, so a user could annotate a preview and watch the next iteration apply only internal critique while the design stayed visually unchanged.Fix: Captured annotations are now parsed (tolerant of heading/bullet/bold/backtick label styles and placeholder values), carried through the loop as
previewFeedbackHistory, written to<artifact_dir>/feedback/iteration-<n>.md/.json, and ordered above reviewer decisions and impeccable critique in the merged refinement brief.user-feedback-*receives them in a dedicated<user_annotations>block and will not approve export while honest feedback is unaddressed. A guardrail asserts annotation threading before each apply stage and fails loudly if it's missing.Artifact dir pollution in test runs
prepareArtifactDirnow writes to the OS tmpdir whenNODE_ENV=test, preventing per-run folders from appearing inspecs/design/.Export gate + terminal annotation hardening
ready_for_exportwhile unaddressed annotations exist (forces an apply pass viaassertUserAnnotationsThreaded)final-displayare read-only (no longer solicituser_notes/live_changesthey cannot apply)assertUserAnnotationsThreadednow also enforces acceptedlive_changesthreadingplaywright-cliis unavailable the run callsctx.exit()with install instructions instead of generating a design no one can reviewcopyAnnotationArtifactsrefuses to copy a model-supplied snapshot path that resolves outside the project/artifact dirBundled impeccable skill v3.8.0 refresh
scripts/live/and shared utilities underscripts/lib/detector/design-system.mjs(design-system detection) and inline-ignore support (scripts/detector/shared/inline-ignores.mjs)cleanup-deprecated.mjs,impeccable-paths.mjs)live-browser.js,live-server.mjs,scripts/context.mjs, and detector rulesscripts/live/modules:manual-apply.mjs,manual-edit-routes.mjs,svelte-component.mjs,sveltekit-adapter.mjs,ui-core.mjs,vocabulary.mjsNotes
typecheck,lint,check:file-length,test:unit(2546 pass / 0 fail), pre-commit/pre-push hooks.specs/2026-06-21-open-claude-design-init-references-live-qa.md.