From 3b96bd5090cd7dc7a8355edee7c53f094548ccce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Aug 2026 21:01:41 +0000 Subject: [PATCH] Sync generated provider output --- .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .pi/skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ .../detector/engines/regex/detect-text.mjs | 19 +++--- .../skills/impeccable/scripts/live-accept.mjs | 60 +++++++------------ 32 files changed, 528 insertions(+), 736 deletions(-) diff --git a/.agents/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.agents/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.agents/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.agents/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.agents/skills/impeccable/scripts/live-accept.mjs b/.agents/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.agents/skills/impeccable/scripts/live-accept.mjs +++ b/.agents/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.claude/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.claude/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.claude/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.claude/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.claude/skills/impeccable/scripts/live-accept.mjs b/.claude/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.claude/skills/impeccable/scripts/live-accept.mjs +++ b/.claude/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.cursor/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.cursor/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.cursor/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.cursor/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.cursor/skills/impeccable/scripts/live-accept.mjs b/.cursor/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.cursor/skills/impeccable/scripts/live-accept.mjs +++ b/.cursor/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.gemini/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.gemini/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.gemini/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.gemini/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.gemini/skills/impeccable/scripts/live-accept.mjs b/.gemini/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.gemini/skills/impeccable/scripts/live-accept.mjs +++ b/.gemini/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.github/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.github/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.github/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.github/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.github/skills/impeccable/scripts/live-accept.mjs b/.github/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.github/skills/impeccable/scripts/live-accept.mjs +++ b/.github/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.grok/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.grok/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.grok/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.grok/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.grok/skills/impeccable/scripts/live-accept.mjs b/.grok/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.grok/skills/impeccable/scripts/live-accept.mjs +++ b/.grok/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.hermes/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.hermes/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.hermes/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.hermes/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.hermes/skills/impeccable/scripts/live-accept.mjs b/.hermes/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.hermes/skills/impeccable/scripts/live-accept.mjs +++ b/.hermes/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.kiro/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.kiro/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.kiro/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.kiro/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.kiro/skills/impeccable/scripts/live-accept.mjs b/.kiro/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.kiro/skills/impeccable/scripts/live-accept.mjs +++ b/.kiro/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.opencode/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.opencode/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.opencode/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.opencode/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.opencode/skills/impeccable/scripts/live-accept.mjs b/.opencode/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.opencode/skills/impeccable/scripts/live-accept.mjs +++ b/.opencode/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.pi/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.pi/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.pi/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.pi/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.pi/skills/impeccable/scripts/live-accept.mjs b/.pi/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.pi/skills/impeccable/scripts/live-accept.mjs +++ b/.pi/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.qoder/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.qoder/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.qoder/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.qoder/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.qoder/skills/impeccable/scripts/live-accept.mjs b/.qoder/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.qoder/skills/impeccable/scripts/live-accept.mjs +++ b/.qoder/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.rovodev/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.rovodev/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.rovodev/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.rovodev/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.rovodev/skills/impeccable/scripts/live-accept.mjs b/.rovodev/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.rovodev/skills/impeccable/scripts/live-accept.mjs +++ b/.rovodev/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.trae-cn/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.trae-cn/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.trae-cn/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.trae-cn/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.trae-cn/skills/impeccable/scripts/live-accept.mjs b/.trae-cn/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.trae-cn/skills/impeccable/scripts/live-accept.mjs +++ b/.trae-cn/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.trae/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.trae/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.trae/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.trae/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.trae/skills/impeccable/scripts/live-accept.mjs b/.trae/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.trae/skills/impeccable/scripts/live-accept.mjs +++ b/.trae/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/.vibe/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/.vibe/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/.vibe/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/.vibe/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/.vibe/skills/impeccable/scripts/live-accept.mjs b/.vibe/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/.vibe/skills/impeccable/scripts/live-accept.mjs +++ b/.vibe/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".'; diff --git a/plugin/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs b/plugin/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs index 0b88cdb63..8bce32525 100644 --- a/plugin/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +++ b/plugin/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs @@ -425,25 +425,28 @@ const REGEX_MATCHERS = [ }, fmt: (m) => `cubic-bezier(${m[1]}, ${m[2]}, ${m[3]}, ${m[4]})` }, // --- Layout property transition --- - { id: 'layout-transition', regex: /transition\s*:\s*([^;{}]+)/gi, + // JSX inline style objects use comma-delimited quoted values, not semicolons (issue #548). + { id: 'layout-transition', regex: /transition\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition: ${found ? found.join(', ') : raw.trim()}`; } }, - { id: 'layout-transition', regex: /transition-property\s*:\s*([^;{}]+)/gi, + { id: 'layout-transition', regex: /transition-property\s*:\s*(?:(['"])((?:(?!\1)[^\\]|\\.)*)\1|([^;{}]+))/gi, test: (m) => { - const val = m[1].toLowerCase(); + const val = (m[2] ?? m[3] ?? '').toLowerCase(); if (/\ball\b/.test(val)) return false; return /\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding\b|\bmargin\b/.test(val); }, fmt: (m) => { - const found = m[1].match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); - return `transition-property: ${found ? found.join(', ') : m[1].trim()}`; + const raw = m[2] ?? m[3] ?? ''; + const found = raw.match(/\b(?:(?:max|min)-)?(?:width|height)\b|\bpadding(?:-(?:top|right|bottom|left))?\b|\bmargin(?:-(?:top|right|bottom|left))?\b/gi); + return `transition-property: ${found ? found.join(', ') : raw.trim()}`; } }, // --- Broken image: src="" or src="#" or src=" " --- { id: 'broken-image', regex: /]*?\bsrc\s*=\s*(?:""|''|"\s+"|'\s+'|"#"|'#')/gi, diff --git a/plugin/skills/impeccable/scripts/live-accept.mjs b/plugin/skills/impeccable/scripts/live-accept.mjs index 507418ea3..2a34dc12a 100644 --- a/plugin/skills/impeccable/scripts/live-accept.mjs +++ b/plugin/skills/impeccable/scripts/live-accept.mjs @@ -170,51 +170,35 @@ Output (JSON): } if (svelteComponentManifest) { - if (isDiscard) { - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'discard:' + id, - () => { - removeSvelteComponentSession(id, process.cwd()); - return { handled: true }; - }, - { waitMs: ACCEPT_LOCK_WAIT_MS }, - ); - } catch (err) { - result = operationFailure(err); - } - emitResult({ - ...result, - file: svelteComponentManifest.sourceFile, - carbonize: false, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); - return; - } - - let result; - try { - result = withSourceLockSync( - path.resolve(process.cwd(), svelteComponentManifest.sourceFile), - 'accept:' + id, - () => inlineSvelteComponentAccept( + const { sourceFile, componentDir } = svelteComponentManifest; + const resultContext = { + file: sourceFile, + ...(isDiscard ? { carbonize: false } : { sourceFile }), + previewMode: 'svelte-component', + componentDir, + }; + const runOperation = isDiscard + ? () => { + removeSvelteComponentSession(id, process.cwd()); + return { handled: true, ...resultContext }; + } + : () => inlineSvelteComponentAccept( svelteComponentManifest, variantNum, paramValues, process.cwd(), - ), + ); + + let result; + try { + result = withSourceLockSync( + path.resolve(process.cwd(), sourceFile), + requestedOperation + ':' + id, + runOperation, { waitMs: ACCEPT_LOCK_WAIT_MS }, ); } catch (err) { - result = operationFailure(err, { - file: svelteComponentManifest.sourceFile, - sourceFile: svelteComponentManifest.sourceFile, - previewMode: 'svelte-component', - componentDir: svelteComponentManifest.componentDir, - }); + result = operationFailure(err, resultContext); } if (result.carbonize) { result.todo = 'REQUIRED before next poll: carbonize cleanup in ' + result.file + '. See reference/live.md "Required after accept".';