mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-14 23:26:39 +03:00
fix: sixth review round (verify precision, base-path @fs fallback)
cursor[bot]: - verifyAcceptedSource anchors its param patterns to the exact shapes live mode writes (data-p-x= / [data-p-x] attributes, var(--p-x, ...) references) instead of bare prefixes, shrinking the false-positive class near the completion gate. Note: the reported examples (data-page, var(--primary)) did not actually match the previous hyphenated substrings; the tightening removes the residual class (e.g. a user's own data-p-* attribute) regardless. - With a non-root Vite base, the /@fs/ fallback is tried both under the base and at the server root, covering Vite versions that serve @fs at either location. This work was produced with AI assistance (Claude Code). Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Code
parent
e5f6d27a9c
commit
f1d450e6ab
@@ -5214,7 +5214,11 @@
|
||||
const candidates = [new URL(base + rel, location.origin).href];
|
||||
if (base !== '/') candidates.push(new URL('/' + rel, location.origin).href);
|
||||
if (absPath) {
|
||||
candidates.push(new URL(base + '@fs/' + String(absPath).replace(/^\/+/, ''), location.origin).href);
|
||||
const fsRel = '@fs/' + String(absPath).replace(/^\/+/, '');
|
||||
candidates.push(new URL(base + fsRel, location.origin).href);
|
||||
// Vite versions differ on whether @fs is served under base or at the
|
||||
// server root; with a non-root base, try both.
|
||||
if (base !== '/') candidates.push(new URL('/' + fsRel, location.origin).href);
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
* mechanical Svelte accept runs it on its own output as a self-check.
|
||||
*/
|
||||
|
||||
// Param patterns are anchored to the exact shapes live mode writes
|
||||
// (attribute-with-value / selector forms, var() references), not bare
|
||||
// substrings, so user tokens that merely share the prefix cannot trip the
|
||||
// completion gate.
|
||||
const FORBIDDEN = [
|
||||
{ marker: 'impeccable-variants-start', why: 'variant wrapper comment left in source' },
|
||||
{ marker: 'impeccable-variants-end', why: 'variant wrapper comment left in source' },
|
||||
@@ -15,8 +19,8 @@ const FORBIDDEN = [
|
||||
{ marker: 'impeccable-carbonize-end', why: 'carbonize block not rewritten into permanent form' },
|
||||
{ marker: 'impeccable-param-values', why: 'param-values comment not baked and removed' },
|
||||
{ marker: 'data-impeccable-', why: 'live-mode plumbing attribute left on markup' },
|
||||
{ marker: 'data-p-', why: 'preview parameter attribute left on markup' },
|
||||
{ marker: 'var(--p-', why: 'preview parameter variable not baked to a literal' },
|
||||
{ marker: /\bdata-p-[A-Za-z0-9_-]+\s*(?:=|\])/, label: 'data-p-*', why: 'preview parameter attribute left on markup' },
|
||||
{ marker: /var\(\s*--p-[A-Za-z0-9_-]+\s*[,)]/, label: 'var(--p-*)', why: 'preview parameter variable not baked to a literal' },
|
||||
{ marker: '--impeccable-variant-ready', why: 'preview readiness sentinel left in CSS' },
|
||||
];
|
||||
|
||||
@@ -29,10 +33,11 @@ export function verifyAcceptedSource(text) {
|
||||
const lines = String(text || '').split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
for (const { marker, why } of FORBIDDEN) {
|
||||
if (line.includes(marker)) {
|
||||
for (const { marker, label, why } of FORBIDDEN) {
|
||||
const hit = marker instanceof RegExp ? marker.test(line) : line.includes(marker);
|
||||
if (hit) {
|
||||
findings.push({
|
||||
marker,
|
||||
marker: label || String(marker),
|
||||
line: i + 1,
|
||||
excerpt: line.trim().slice(0, 120),
|
||||
why,
|
||||
|
||||
@@ -209,3 +209,24 @@ describe('review regressions: toggle branch truth', () => {
|
||||
assert.equal(stripParamSelector('[data-p-flag] .a', 'flag', 'toggle', false), null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('review regressions: verify precision', () => {
|
||||
it('does not flag user tokens that merely share the p- prefix', () => {
|
||||
const clean = [
|
||||
'<div data-page="3" data-p-count-like data-photo="x">ok</div>',
|
||||
'.a { color: var(--primary); padding: var(--padding, 4px); }',
|
||||
].join('\n');
|
||||
assert.equal(verifyAcceptedSource(clean).clean, true, JSON.stringify(verifyAcceptedSource(clean).findings));
|
||||
});
|
||||
|
||||
it('still flags the exact shapes live mode writes', () => {
|
||||
const dirty = [
|
||||
'<div data-p-density="snug">x</div>',
|
||||
'.a { gap: var(--p-depth, 4px); }',
|
||||
'.b[data-p-flag] { color: red; }',
|
||||
].join('\n');
|
||||
const { clean, findings } = verifyAcceptedSource(dirty);
|
||||
assert.equal(clean, false);
|
||||
assert.equal(findings.length >= 3, true);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user