skill: merge orphan reference files into command sub-skills + inline S-tier invariants

Two related restructurings:

1. SKILL.md now carries the cross-domain invariants that catch defects in any
   project (contrast/placeholder/gray-on-color, similar-font pairing, text-wrap,
   tabular-nums, centered-stack default, Flex/Grid choice, auto-fit grids,
   semantic z-index, reduced motion, stagger vs section-fade, premium motion
   materials, focus-visible, placeholders-aren't-labels, dropdown overflow trap,
   button/link copy). Greenfield-only rules (theme picking, color strategy,
   tinted neutrals) live under "New projects only".

2. Reference files merged into their command counterparts:
   - spatial-design.md  -> layout.md
   - motion-design.md   -> animate.md
   - color-and-contrast.md -> colorize.md
   - responsive-design.md  -> adapt.md
   - ux-writing.md         -> clarify.md
   - typography.md         -> typeset.md (bolder.md redirected)
   - cognitive-load.md + heuristics-scoring.md + personas.md -> critique.md

   craft.md and shape.md "load references" lists updated to new file homes.
   interaction-design.md stays standalone (no 1:1 command verb).

Net: 36 -> 27 reference files. Same content, fewer files, no orphaned
reference loaded only from craft.md.

Also extends the routing rules: if the user's first word doesn't match a
command but the intent clearly maps to one, load that command's reference
and proceed as if invoked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-05-20 22:09:42 -07:00
co-authored by Claude Opus 4.7
parent 33467e5f0f
commit 4edde64768
504 changed files with 19067 additions and 22013 deletions
+45 -31
View File
@@ -1841,45 +1841,54 @@
fetch(url)
.then(r => { if (!r.ok) throw new Error(r.status); return r.text(); })
.then(html => {
// Parse the raw source HTML
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const srcWrapper = doc.querySelector('[data-impeccable-variants="' + sessionId + '"]');
let srcWrapper = null;
// Full-file parse works for HTML/JSX; Astro/Vue sources need marker extraction.
const startMark = '<!-- impeccable-variants-start ' + sessionId + ' -->';
const endMark = '<!-- impeccable-variants-end ' + sessionId + ' -->';
const startIdx = html.indexOf(startMark);
const endIdx = html.indexOf(endMark);
const block = startIdx !== -1 && endIdx !== -1 && endIdx > startIdx
? html.slice(startIdx + startMark.length, endIdx).trim()
: html;
const doc = parser.parseFromString(block, 'text/html');
srcWrapper = doc.querySelector('[data-impeccable-variants="' + sessionId + '"]');
if (!srcWrapper) {
console.error('[impeccable] Variant wrapper not found in source file.');
return;
}
// Find the original element in the live DOM.
// The original is inside the wrapper in the source. We find the
// corresponding element in the live DOM by matching the first child's
// tag + classes from the original snapshot.
const origContent = srcWrapper.querySelector('[data-impeccable-variant="original"] > :first-child');
if (!origContent) return;
const tag = origContent.tagName.toLowerCase();
const cls = origContent.className;
let liveEl = null;
if (origContent.id) {
liveEl = document.getElementById(origContent.id);
} else if (cls) {
// Find by tag + exact class match
const candidates = document.querySelectorAll(tag + '.' + cls.split(' ')[0]);
for (const c of candidates) {
if (c.className === cls && !own(c)) { liveEl = c; break; }
}
}
if (!liveEl) {
console.error('[impeccable] Could not find original element in live DOM.');
return;
}
const previousVisibleVariant = currentSessionId === sessionId ? visibleVariant : 0;
// Replace the live element with the full wrapper from source
const wrapper = srcWrapper.cloneNode(true);
liveEl.parentElement.replaceChild(wrapper, liveEl);
// Wrapper already in DOM (wrap HMR landed, variant insert did not).
const existingWrapper = document.querySelector('[data-impeccable-variants="' + sessionId + '"]');
if (existingWrapper) {
existingWrapper.parentElement.replaceChild(wrapper, existingWrapper);
} else {
const origContent = srcWrapper.querySelector('[data-impeccable-variant="original"] > :first-child');
if (!origContent) return;
const tag = origContent.tagName.toLowerCase();
const cls = origContent.className;
let liveEl = null;
if (origContent.id) {
liveEl = document.getElementById(origContent.id);
} else if (cls) {
const candidates = document.querySelectorAll(tag + '.' + cls.split(' ')[0]);
for (const c of candidates) {
if (c.className === cls && !own(c)) { liveEl = c; break; }
}
}
if (!liveEl) {
console.error('[impeccable] Could not find original element in live DOM.');
return;
}
liveEl.parentElement.replaceChild(wrapper, liveEl);
}
// Update state: count variants, preserving the user's current variant
// when a late HMR/source reinjection lands after they have cycled.
@@ -2221,6 +2230,11 @@
}
break;
}
// Source fallback when HMR did not land variants in this tab.
if (msg.file && msg.id && state === 'GENERATING' && msg.id === currentSessionId) {
injectVariantsFromSource(msg.file, msg.id);
break;
}
// Variants are in source but not in the DOM yet. Common when the
// picked element lived inside conditional render (closed modal,
// hidden tab, a route the user navigated away from). The variant
+3
View File
@@ -370,11 +370,14 @@ function buildCssAuthoring(styleMode, count) {
selectorExamples: variantNumbers.map((n) => `[data-impeccable-variant="${n}"] > .variant-class`),
requirements: [
'Use the styleTag exactly; the is:inline attribute is required for this file.',
'Put raw CSS directly between the styleTag opening and a plain </style> close.',
'Prefix every preview selector with the matching [data-impeccable-variant="N"] selector.',
'Keep selectors anchored to the generated variant wrapper; do not rely on component CSS scoping for preview rules.',
],
forbidden: [
'Do not use @scope for this styleMode.',
'Do not wrap style content in a JSX/TSX template literal ({` ... `}); that syntax is for .tsx/.jsx only.',
'Do not put { immediately after the style opening tag; Astro parses { as expression syntax.',
],
};
}