@zelari/core 0.7.11 → 0.7.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/councilApi.d.ts +135 -0
- package/dist/agents/councilApi.d.ts.map +1 -1
- package/dist/agents/councilApi.js +520 -7
- package/dist/agents/councilApi.js.map +1 -1
- package/dist/agents/roles.d.ts.map +1 -1
- package/dist/agents/roles.js +11 -3
- package/dist/agents/roles.js.map +1 -1
- package/dist/agents/toolSchemas.d.ts.map +1 -1
- package/dist/agents/toolSchemas.js +32 -3
- package/dist/agents/toolSchemas.js.map +1 -1
- package/dist/core/AgentHarness.d.ts +21 -0
- package/dist/core/AgentHarness.d.ts.map +1 -1
- package/dist/core/AgentHarness.js +177 -8
- package/dist/core/AgentHarness.js.map +1 -1
- package/dist/core/tools/builtin/filesystem.d.ts.map +1 -1
- package/dist/core/tools/builtin/filesystem.js +4 -2
- package/dist/core/tools/builtin/filesystem.js.map +1 -1
- package/dist/council/completion/buildCompletion.d.ts +23 -0
- package/dist/council/completion/buildCompletion.d.ts.map +1 -0
- package/dist/council/completion/buildCompletion.js +75 -0
- package/dist/council/completion/buildCompletion.js.map +1 -0
- package/dist/council/completion/index.d.ts +3 -0
- package/dist/council/completion/index.d.ts.map +1 -0
- package/dist/council/completion/index.js +3 -0
- package/dist/council/completion/index.js.map +1 -0
- package/dist/council/completion/types.d.ts +38 -0
- package/dist/council/completion/types.d.ts.map +1 -0
- package/dist/council/completion/types.js +2 -0
- package/dist/council/completion/types.js.map +1 -0
- package/dist/council/index.d.ts +4 -0
- package/dist/council/index.d.ts.map +1 -1
- package/dist/council/index.js +4 -0
- package/dist/council/index.js.map +1 -1
- package/dist/council/lessons/index.d.ts +7 -0
- package/dist/council/lessons/index.d.ts.map +1 -0
- package/dist/council/lessons/index.js +7 -0
- package/dist/council/lessons/index.js.map +1 -0
- package/dist/council/lessons/io.d.ts +5 -0
- package/dist/council/lessons/io.d.ts.map +1 -0
- package/dist/council/lessons/io.js +30 -0
- package/dist/council/lessons/io.js.map +1 -0
- package/dist/council/lessons/isAnswerLeak.d.ts +7 -0
- package/dist/council/lessons/isAnswerLeak.d.ts.map +1 -0
- package/dist/council/lessons/isAnswerLeak.js +26 -0
- package/dist/council/lessons/isAnswerLeak.js.map +1 -0
- package/dist/council/lessons/recallLessons.d.ts +8 -0
- package/dist/council/lessons/recallLessons.d.ts.map +1 -0
- package/dist/council/lessons/recallLessons.js +56 -0
- package/dist/council/lessons/recallLessons.js.map +1 -0
- package/dist/council/lessons/recordFailure.d.ts +7 -0
- package/dist/council/lessons/recordFailure.d.ts.map +1 -0
- package/dist/council/lessons/recordFailure.js +86 -0
- package/dist/council/lessons/recordFailure.js.map +1 -0
- package/dist/council/lessons/signatures.d.ts +6 -0
- package/dist/council/lessons/signatures.d.ts.map +1 -0
- package/dist/council/lessons/signatures.js +31 -0
- package/dist/council/lessons/signatures.js.map +1 -0
- package/dist/council/lessons/types.d.ts +27 -0
- package/dist/council/lessons/types.d.ts.map +1 -0
- package/dist/council/lessons/types.js +2 -0
- package/dist/council/lessons/types.js.map +1 -0
- package/dist/council/modeBanners.d.ts +24 -1
- package/dist/council/modeBanners.d.ts.map +1 -1
- package/dist/council/modeBanners.js +31 -4
- package/dist/council/modeBanners.js.map +1 -1
- package/dist/council/scope/extractTaskScope.d.ts +35 -0
- package/dist/council/scope/extractTaskScope.d.ts.map +1 -0
- package/dist/council/scope/extractTaskScope.js +174 -0
- package/dist/council/scope/extractTaskScope.js.map +1 -0
- package/dist/council/scope/index.d.ts +3 -0
- package/dist/council/scope/index.d.ts.map +1 -0
- package/dist/council/scope/index.js +3 -0
- package/dist/council/scope/index.js.map +1 -0
- package/dist/council/scope/nfrSpecWarn.d.ts +6 -0
- package/dist/council/scope/nfrSpecWarn.d.ts.map +1 -0
- package/dist/council/scope/nfrSpecWarn.js +21 -0
- package/dist/council/scope/nfrSpecWarn.js.map +1 -0
- package/dist/council/verification/autofix.d.ts +12 -0
- package/dist/council/verification/autofix.d.ts.map +1 -0
- package/dist/council/verification/autofix.js +41 -0
- package/dist/council/verification/autofix.js.map +1 -0
- package/dist/council/verification/citeVerify.d.ts +13 -0
- package/dist/council/verification/citeVerify.d.ts.map +1 -0
- package/dist/council/verification/citeVerify.js +73 -0
- package/dist/council/verification/citeVerify.js.map +1 -0
- package/dist/council/verification/completion.d.ts +19 -0
- package/dist/council/verification/completion.d.ts.map +1 -0
- package/dist/council/verification/completion.js +50 -0
- package/dist/council/verification/completion.js.map +1 -0
- package/dist/council/verification/degraded.d.ts +26 -0
- package/dist/council/verification/degraded.d.ts.map +1 -0
- package/dist/council/verification/degraded.js +35 -0
- package/dist/council/verification/degraded.js.map +1 -0
- package/dist/council/verification/honesty.d.ts +6 -0
- package/dist/council/verification/honesty.d.ts.map +1 -0
- package/dist/council/verification/honesty.js +28 -0
- package/dist/council/verification/honesty.js.map +1 -0
- package/dist/council/verification/implementationDelivery.d.ts +26 -0
- package/dist/council/verification/implementationDelivery.d.ts.map +1 -0
- package/dist/council/verification/implementationDelivery.js +70 -0
- package/dist/council/verification/implementationDelivery.js.map +1 -0
- package/dist/council/verification/index.d.ts +15 -0
- package/dist/council/verification/index.d.ts.map +1 -0
- package/dist/council/verification/index.js +15 -0
- package/dist/council/verification/index.js.map +1 -0
- package/dist/council/verification/inlineJsAutofix.d.ts +8 -0
- package/dist/council/verification/inlineJsAutofix.d.ts.map +1 -0
- package/dist/council/verification/inlineJsAutofix.js +85 -0
- package/dist/council/verification/inlineJsAutofix.js.map +1 -0
- package/dist/council/verification/microGate.d.ts +18 -0
- package/dist/council/verification/microGate.d.ts.map +1 -0
- package/dist/council/verification/microGate.js +81 -0
- package/dist/council/verification/microGate.js.map +1 -0
- package/dist/council/verification/motionAutofix.d.ts +8 -0
- package/dist/council/verification/motionAutofix.d.ts.map +1 -0
- package/dist/council/verification/motionAutofix.js +160 -0
- package/dist/council/verification/motionAutofix.js.map +1 -0
- package/dist/council/verification/parseCssMotion.d.ts +22 -0
- package/dist/council/verification/parseCssMotion.d.ts.map +1 -0
- package/dist/council/verification/parseCssMotion.js +142 -0
- package/dist/council/verification/parseCssMotion.js.map +1 -0
- package/dist/council/verification/runChecks.d.ts +10 -0
- package/dist/council/verification/runChecks.d.ts.map +1 -0
- package/dist/council/verification/runChecks.js +254 -0
- package/dist/council/verification/runChecks.js.map +1 -0
- package/dist/council/verification/synthesisAudit.d.ts +14 -0
- package/dist/council/verification/synthesisAudit.d.ts.map +1 -0
- package/dist/council/verification/synthesisAudit.js +106 -0
- package/dist/council/verification/synthesisAudit.js.map +1 -0
- package/dist/council/verification/tiers.d.ts +8 -0
- package/dist/council/verification/tiers.d.ts.map +1 -0
- package/dist/council/verification/tiers.js +46 -0
- package/dist/council/verification/tiers.js.map +1 -0
- package/dist/council/verification/types.d.ts +53 -0
- package/dist/council/verification/types.d.ts.map +1 -0
- package/dist/council/verification/types.js +5 -0
- package/dist/council/verification/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const WRITE_TOOLS = new Set(['write_file', 'edit_file']);
|
|
2
|
+
/** Lucifero must emit at least one mutating tool in implementation mode. */
|
|
3
|
+
export const IMPLEMENTATION_WRITE_REQUIREMENTS = [
|
|
4
|
+
{ name: 'write_file', min: 1 },
|
|
5
|
+
{ name: 'edit_file', min: 1 },
|
|
6
|
+
];
|
|
7
|
+
/**
|
|
8
|
+
* True when at least one write_file/edit_file succeeded (not merely emitted).
|
|
9
|
+
* edit_file counts only when occurrencesReplaced > 0.
|
|
10
|
+
*/
|
|
11
|
+
export function checkImplementationDelivery(successfulWriteCount, emittedWriteTools) {
|
|
12
|
+
if (successfulWriteCount > 0) {
|
|
13
|
+
return { ok: true, missing: [] };
|
|
14
|
+
}
|
|
15
|
+
if (emittedWriteTools > 0) {
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
missing: ['edit_file'],
|
|
19
|
+
reason: 'write_file/edit_file ran but no file changed (oldString mismatch or empty write)',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
missing: ['write_file', 'edit_file'],
|
|
25
|
+
reason: 'Implementation mode requires at least one successful write_file or edit_file',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Blocking verify failures the chairman can fix on disk (exclude synthesis meta). */
|
|
29
|
+
export function filterDeliveryBlockingFails(results) {
|
|
30
|
+
return results.filter((r) => !r.ok &&
|
|
31
|
+
r.severity === 'error' &&
|
|
32
|
+
!r.id.startsWith('synthesis.'));
|
|
33
|
+
}
|
|
34
|
+
export function buildImplementationWriteRetryPrompt(userMessage) {
|
|
35
|
+
const goal = userMessage.trim().slice(0, 500);
|
|
36
|
+
return (`IMPLEMENTATION INCOMPLETE — no file was successfully modified on disk.\n` +
|
|
37
|
+
`User goal: ${goal || '(see council context)'}\n\n` +
|
|
38
|
+
`You MUST implement the requested changes NOW using write_file or edit_file.\n` +
|
|
39
|
+
`Rules:\n` +
|
|
40
|
+
`- read_file the target before edit_file if oldString might have drifted\n` +
|
|
41
|
+
`- Use native tool_call (preferred) or a valid ---TOOLS--- JSON block\n` +
|
|
42
|
+
`- No prose, no verification table — only tool calls until a write succeeds\n` +
|
|
43
|
+
`- Motion: animate ONLY transform and opacity in @keyframes/transitions`);
|
|
44
|
+
}
|
|
45
|
+
/** Imperative fix prompt from deterministic verify FAILs (post-write delivery loop). */
|
|
46
|
+
export function buildDeliveryFixPrompt(blocking, userMessage) {
|
|
47
|
+
const lines = blocking.map((r) => {
|
|
48
|
+
const file = r.file ? ` (${r.file})` : '';
|
|
49
|
+
return ` - ${r.id}${file}: ${r.message}`;
|
|
50
|
+
});
|
|
51
|
+
const goal = userMessage.trim().slice(0, 300);
|
|
52
|
+
const hints = [];
|
|
53
|
+
if (blocking.some((r) => r.id === 'inline-js.budget')) {
|
|
54
|
+
hints.push('inline-js.budget: trim the inline <script> by ~1.5KB — remove verbose comments, ' +
|
|
55
|
+
'drop optional JS (tilt/aurora cursor), shorten selectors; keep reveal IO + nav spy');
|
|
56
|
+
}
|
|
57
|
+
if (blocking.some((r) => r.id.startsWith('motion.'))) {
|
|
58
|
+
hints.push('motion.*: @keyframes and transition may use ONLY transform and opacity — ' +
|
|
59
|
+
'grep forbidden props and replace with compositor-safe equivalents');
|
|
60
|
+
}
|
|
61
|
+
return (`Deterministic verification still FAILs after your implementation turn. ` +
|
|
62
|
+
`Fix ONLY these blocking issues — do not add features:\n${lines.join('\n')}\n\n` +
|
|
63
|
+
(goal ? `Original user goal (context): ${goal}\n\n` : '') +
|
|
64
|
+
(hints.length > 0 ? `Hints:\n${hints.map((h) => `- ${h}`).join('\n')}\n\n` : '') +
|
|
65
|
+
`Use read_file then edit_file on the listed files. No verification table — tool calls only.`);
|
|
66
|
+
}
|
|
67
|
+
export function countEmittedWriteTools(emittedToolNames) {
|
|
68
|
+
return emittedToolNames.filter((t) => WRITE_TOOLS.has(t)).length;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=implementationDelivery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"implementationDelivery.js","sourceRoot":"","sources":["../../../src/council/verification/implementationDelivery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './runChecks.js';
|
|
3
|
+
export * from './honesty.js';
|
|
4
|
+
export * from './parseCssMotion.js';
|
|
5
|
+
export * from './tiers.js';
|
|
6
|
+
export * from './citeVerify.js';
|
|
7
|
+
export * from './synthesisAudit.js';
|
|
8
|
+
export * from './microGate.js';
|
|
9
|
+
export * from './completion.js';
|
|
10
|
+
export * from './implementationDelivery.js';
|
|
11
|
+
export * from './degraded.js';
|
|
12
|
+
export * from './autofix.js';
|
|
13
|
+
export * from './motionAutofix.js';
|
|
14
|
+
export * from './inlineJsAutofix.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/council/verification/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './runChecks.js';
|
|
3
|
+
export * from './honesty.js';
|
|
4
|
+
export * from './parseCssMotion.js';
|
|
5
|
+
export * from './tiers.js';
|
|
6
|
+
export * from './citeVerify.js';
|
|
7
|
+
export * from './synthesisAudit.js';
|
|
8
|
+
export * from './microGate.js';
|
|
9
|
+
export * from './completion.js';
|
|
10
|
+
export * from './implementationDelivery.js';
|
|
11
|
+
export * from './degraded.js';
|
|
12
|
+
export * from './autofix.js';
|
|
13
|
+
export * from './motionAutofix.js';
|
|
14
|
+
export * from './inlineJsAutofix.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/council/verification/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { VerificationReport } from './types.js';
|
|
2
|
+
/** Deterministic inline <script> budget fix when LLM delivery fails. */
|
|
3
|
+
export declare function applyInlineJsAutofix(projectRoot: string, report: VerificationReport): {
|
|
4
|
+
applied: boolean;
|
|
5
|
+
filesChanged: string[];
|
|
6
|
+
fixes: string[];
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=inlineJsAutofix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inlineJsAutofix.d.ts","sourceRoot":"","sources":["../../../src/council/verification/inlineJsAutofix.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA6DrD,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GACzB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAsC/D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { DEFAULT_NFR_SPEC } from './runChecks.js';
|
|
4
|
+
const SCRIPT_RE = /<script[^>]*>([\s\S]*?)<\/script>/i;
|
|
5
|
+
/** Strip comments and excess whitespace from inline script bodies. */
|
|
6
|
+
function minifyInlineJs(js) {
|
|
7
|
+
let out = js.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
8
|
+
out = out
|
|
9
|
+
.split('\n')
|
|
10
|
+
.map((line) => line.replace(/\/\/.*$/, '').trimEnd())
|
|
11
|
+
.filter((line) => line.trim().length > 0)
|
|
12
|
+
.join('\n');
|
|
13
|
+
return out.replace(/\n{2,}/g, '\n');
|
|
14
|
+
}
|
|
15
|
+
/** Drop optional v0.4 interaction blocks when budget still exceeded. */
|
|
16
|
+
function dropOptionalJsBlocks(js) {
|
|
17
|
+
return js
|
|
18
|
+
.replace(/\/\*\s*={3,}[^*]*v0\.4[^*]*\*\/[\s\S]*?(?=\/\*\s*={3,}|const openAllFaq|window\.addEventListener\('beforeprint')/i, '')
|
|
19
|
+
.replace(/if\s*\(\s*!reduceMotion\s*\)\s*\{[\s\S]*?tiltEls\.forEach[\s\S]*?\}\s*\}/, '')
|
|
20
|
+
.replace(/const hero = document\.querySelector\('\.hero'\);[\s\S]*?aurora\.style\.transition = ''[\s\S]*?\}\s*,\s*600\);\s*\}/, '')
|
|
21
|
+
.replace(/const flowObserver = new IntersectionObserver[\s\S]*?flowObserver\.observe\(flowEl\);\s*/, '');
|
|
22
|
+
}
|
|
23
|
+
function dropPaddingLiterals(js) {
|
|
24
|
+
return js.replace(/const\s+\w+\s*=\s*["'][^"']{400,}["']\s*;?/g, '');
|
|
25
|
+
}
|
|
26
|
+
function trimScriptBlock(js, maxBytes) {
|
|
27
|
+
const original = js;
|
|
28
|
+
let next = js;
|
|
29
|
+
for (let pass = 0; pass < 4; pass++) {
|
|
30
|
+
let step = minifyInlineJs(next);
|
|
31
|
+
if (Buffer.byteLength(step, 'utf8') > maxBytes) {
|
|
32
|
+
step = dropOptionalJsBlocks(step);
|
|
33
|
+
step = minifyInlineJs(step);
|
|
34
|
+
}
|
|
35
|
+
if (Buffer.byteLength(step, 'utf8') > maxBytes) {
|
|
36
|
+
step = dropPaddingLiterals(step);
|
|
37
|
+
step = minifyInlineJs(step);
|
|
38
|
+
}
|
|
39
|
+
if (step === next)
|
|
40
|
+
break;
|
|
41
|
+
next = step;
|
|
42
|
+
if (Buffer.byteLength(next, 'utf8') <= maxBytes)
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
return { js: next, changed: next !== original };
|
|
46
|
+
}
|
|
47
|
+
/** Deterministic inline <script> budget fix when LLM delivery fails. */
|
|
48
|
+
export function applyInlineJsAutofix(projectRoot, report) {
|
|
49
|
+
const fails = report.results.filter((r) => !r.ok && r.id === 'inline-js.budget' && r.file);
|
|
50
|
+
if (fails.length === 0) {
|
|
51
|
+
return { applied: false, filesChanged: [], fixes: [] };
|
|
52
|
+
}
|
|
53
|
+
const maxBytes = DEFAULT_NFR_SPEC.inlineJs?.maxBytes ?? 5120;
|
|
54
|
+
const filesChanged = [];
|
|
55
|
+
const fixes = [];
|
|
56
|
+
for (const r of fails) {
|
|
57
|
+
const rel = r.file ?? 'index.html';
|
|
58
|
+
const abs = join(projectRoot, rel);
|
|
59
|
+
let html;
|
|
60
|
+
try {
|
|
61
|
+
html = readFileSync(abs, 'utf8');
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const m = SCRIPT_RE.exec(html);
|
|
67
|
+
if (!m)
|
|
68
|
+
continue;
|
|
69
|
+
const before = m[1] ?? '';
|
|
70
|
+
const { js: after, changed } = trimScriptBlock(before, maxBytes);
|
|
71
|
+
const afterBytes = Buffer.byteLength(after, 'utf8');
|
|
72
|
+
if (!changed || afterBytes > maxBytes)
|
|
73
|
+
continue;
|
|
74
|
+
const nextHtml = html.replace(SCRIPT_RE, `<script>${after}</script>`);
|
|
75
|
+
writeFileSync(abs, nextHtml, 'utf8');
|
|
76
|
+
filesChanged.push(rel);
|
|
77
|
+
fixes.push(`${rel}: trimmed inline script ${Buffer.byteLength(before, 'utf8')}→${afterBytes} bytes`);
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
applied: filesChanged.length > 0,
|
|
81
|
+
filesChanged,
|
|
82
|
+
fixes,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=inlineJsAutofix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inlineJsAutofix.js","sourceRoot":"","sources":["../../../src/council/verification/inlineJsAutofix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface MicroGateWarning {
|
|
2
|
+
id: string;
|
|
3
|
+
message: string;
|
|
4
|
+
file: string;
|
|
5
|
+
line?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Quick subset of Gate A on a single file (HTML). Used for inline WARN after writes.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runMicroVerificationOnFile(projectRoot: string, relPath: string, zelariRoot?: string): MicroGateWarning[];
|
|
11
|
+
export declare function parseProjectRootFromWorkspaceContext(ctx: string): string | null;
|
|
12
|
+
/** Run micro-gate when Lucifero writes a target HTML file. */
|
|
13
|
+
export declare function runChairmanMicroGate(input: {
|
|
14
|
+
projectRoot: string;
|
|
15
|
+
relPath: string;
|
|
16
|
+
zelariRoot?: string;
|
|
17
|
+
}): MicroGateWarning[];
|
|
18
|
+
//# sourceMappingURL=microGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microGate.d.ts","sourceRoot":"","sources":["../../../src/council/verification/microGate.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA8BD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,gBAAgB,EAAE,CAgCpB;AAED,wBAAgB,oCAAoC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG/E;AAED,8DAA8D;AAC9D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,gBAAgB,EAAE,CAQrB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { scanKeyframesViolations, scanTransitionViolations } from './parseCssMotion.js';
|
|
4
|
+
import { loadNfrSpec, DEFAULT_NFR_SPEC } from './runChecks.js';
|
|
5
|
+
function checkDeadHooksInHtml(html) {
|
|
6
|
+
const warnings = [];
|
|
7
|
+
const scripts = [];
|
|
8
|
+
const scriptRe = /<script[^>]*>([\s\S]*?)<\/script>/gi;
|
|
9
|
+
let sm;
|
|
10
|
+
while ((sm = scriptRe.exec(html)) !== null)
|
|
11
|
+
scripts.push(sm[1] ?? '');
|
|
12
|
+
const styleText = (html.match(/<style[^>]*>([\s\S]*?)<\/style>/gi) ?? []).join('\n');
|
|
13
|
+
const addRe = /classList\.add\(\s*['"]([\w-]+)['"]\s*\)/g;
|
|
14
|
+
for (const script of scripts) {
|
|
15
|
+
let am;
|
|
16
|
+
addRe.lastIndex = 0;
|
|
17
|
+
while ((am = addRe.exec(script)) !== null) {
|
|
18
|
+
const cls = am[1] ?? '';
|
|
19
|
+
const hasRule = new RegExp(`\\.${cls}\\b`).test(styleText) ||
|
|
20
|
+
new RegExp(`html\\.${cls}\\b`).test(styleText);
|
|
21
|
+
if (!hasRule) {
|
|
22
|
+
warnings.push({
|
|
23
|
+
id: 'css.dead-hook',
|
|
24
|
+
message: `classList.add('${cls}') has no CSS rule (.${cls})`,
|
|
25
|
+
file: '',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return warnings;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Quick subset of Gate A on a single file (HTML). Used for inline WARN after writes.
|
|
34
|
+
*/
|
|
35
|
+
export function runMicroVerificationOnFile(projectRoot, relPath, zelariRoot) {
|
|
36
|
+
const abs = join(projectRoot, relPath);
|
|
37
|
+
if (!existsSync(abs) || !/\.html?$/i.test(relPath))
|
|
38
|
+
return [];
|
|
39
|
+
const spec = (zelariRoot ? loadNfrSpec(zelariRoot) : null) ?? DEFAULT_NFR_SPEC;
|
|
40
|
+
const anim = spec.animation ?? { compositorOnly: true, forbidLayoutProps: true };
|
|
41
|
+
const scanOpts = {
|
|
42
|
+
compositorOnly: anim.compositorOnly ?? true,
|
|
43
|
+
forbidLayoutProps: anim.forbidLayoutProps ?? true,
|
|
44
|
+
};
|
|
45
|
+
const html = readFileSync(abs, 'utf8');
|
|
46
|
+
const warnings = [];
|
|
47
|
+
for (const v of scanKeyframesViolations(html, scanOpts)) {
|
|
48
|
+
warnings.push({
|
|
49
|
+
id: 'motion.keyframes',
|
|
50
|
+
message: `@keyframes uses non-allowed property "${v.property}"`,
|
|
51
|
+
file: relPath,
|
|
52
|
+
line: v.line,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
for (const v of scanTransitionViolations(html, scanOpts)) {
|
|
56
|
+
warnings.push({
|
|
57
|
+
id: 'motion.transitions',
|
|
58
|
+
message: `transition uses non-allowed property "${v.property}"`,
|
|
59
|
+
file: relPath,
|
|
60
|
+
line: v.line,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
for (const w of checkDeadHooksInHtml(html)) {
|
|
64
|
+
warnings.push({ ...w, file: relPath });
|
|
65
|
+
}
|
|
66
|
+
return warnings;
|
|
67
|
+
}
|
|
68
|
+
export function parseProjectRootFromWorkspaceContext(ctx) {
|
|
69
|
+
const m = ctx.match(/Working directory:\s*(.+)/m);
|
|
70
|
+
return m?.[1]?.trim() ?? null;
|
|
71
|
+
}
|
|
72
|
+
/** Run micro-gate when Lucifero writes a target HTML file. */
|
|
73
|
+
export function runChairmanMicroGate(input) {
|
|
74
|
+
const normalized = input.relPath.replace(/\\/g, '/');
|
|
75
|
+
const spec = (input.zelariRoot ? loadNfrSpec(input.zelariRoot) : null) ?? DEFAULT_NFR_SPEC;
|
|
76
|
+
const inTarget = spec.targets.some((t) => normalized === t || normalized.endsWith(`/${t}`));
|
|
77
|
+
if (!inTarget && !/\.html?$/i.test(normalized))
|
|
78
|
+
return [];
|
|
79
|
+
return runMicroVerificationOnFile(input.projectRoot, normalized, input.zelariRoot);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=microGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microGate.js","sourceRoot":"","sources":["../../../src/council/verification/microGate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { VerificationReport } from './types.js';
|
|
2
|
+
/** Apply deterministic motion + .rm CSS fixes to HTML targets from a verify report. */
|
|
3
|
+
export declare function applyMotionAutofix(projectRoot: string, report: VerificationReport): {
|
|
4
|
+
applied: boolean;
|
|
5
|
+
filesChanged: string[];
|
|
6
|
+
fixes: string[];
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=motionAutofix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motionAutofix.d.ts","sourceRoot":"","sources":["../../../src/council/verification/motionAutofix.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAkGrD,uFAAuF;AACvF,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GACzB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAiE/D"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { COMPOSITOR_ONLY_PROPS, LAYOUT_MOTION_PROPS, scanKeyframesViolations, scanTransitionViolations, } from './parseCssMotion.js';
|
|
4
|
+
import { DEFAULT_NFR_SPEC } from './runChecks.js';
|
|
5
|
+
const FORBIDDEN_ANIM_PROPS = new Set([
|
|
6
|
+
...LAYOUT_MOTION_PROPS,
|
|
7
|
+
'box-shadow',
|
|
8
|
+
'background',
|
|
9
|
+
'background-color',
|
|
10
|
+
'background-position',
|
|
11
|
+
'color',
|
|
12
|
+
'border-color',
|
|
13
|
+
'filter',
|
|
14
|
+
'all',
|
|
15
|
+
]);
|
|
16
|
+
const RM_CSS = `
|
|
17
|
+
.rm *, .rm *::before, .rm *::after {
|
|
18
|
+
animation-duration: 0.001ms !important;
|
|
19
|
+
animation-iteration-count: 1 !important;
|
|
20
|
+
transition-duration: 0.001ms !important;
|
|
21
|
+
scroll-behavior: auto !important;
|
|
22
|
+
}
|
|
23
|
+
.rm .reveal { opacity: 1 !important; transform: none !important; }
|
|
24
|
+
.rm .section-title h2::after { transform: scaleX(1) !important; }
|
|
25
|
+
.rm .aurora { display: none; }
|
|
26
|
+
`;
|
|
27
|
+
function isForbiddenAnimProp(prop) {
|
|
28
|
+
const p = prop.toLowerCase();
|
|
29
|
+
if (COMPOSITOR_ONLY_PROPS.has(p))
|
|
30
|
+
return false;
|
|
31
|
+
return FORBIDDEN_ANIM_PROPS.has(p);
|
|
32
|
+
}
|
|
33
|
+
/** Keep only transform/opacity tokens in a transition shorthand fragment. */
|
|
34
|
+
function sanitizeTransitionPart(part) {
|
|
35
|
+
const tokens = part.trim().split(/\s+/);
|
|
36
|
+
if (tokens.length === 0)
|
|
37
|
+
return null;
|
|
38
|
+
const prop = tokens[0].toLowerCase();
|
|
39
|
+
if (prop === 'transform' || prop === 'opacity')
|
|
40
|
+
return part.trim();
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
function sanitizeTransitionValue(value) {
|
|
44
|
+
const parts = value.split(',').map((p) => p.trim()).filter(Boolean);
|
|
45
|
+
const kept = parts
|
|
46
|
+
.map(sanitizeTransitionPart)
|
|
47
|
+
.filter((p) => p !== null);
|
|
48
|
+
return kept.length > 0 ? kept.join(', ') : 'none';
|
|
49
|
+
}
|
|
50
|
+
const TRANSITION_DECL_RE = /(transition(?:-property)?)\s*:\s*([^;{}]+)/gi;
|
|
51
|
+
function sanitizeTransitionsInCss(css) {
|
|
52
|
+
return css.replace(TRANSITION_DECL_RE, (full, prop, value) => {
|
|
53
|
+
const next = sanitizeTransitionValue(value);
|
|
54
|
+
if (next === value.trim())
|
|
55
|
+
return full;
|
|
56
|
+
return `${prop}: ${next}`;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const FORBIDDEN_DECL_RE = /\s*(?:box-shadow|background-position|background-color|background|color|border-color|filter|height|width|padding(?:-top|-bottom)?|margin(?:-top|-bottom)?|grid-template-rows|grid-template-columns)\s*:[^;{}]+;?/gi;
|
|
60
|
+
function sanitizeKeyframeBlock(block) {
|
|
61
|
+
return block.replace(/\{([^{}]*)\}/g, (_m, body) => {
|
|
62
|
+
const cleaned = body.replace(FORBIDDEN_DECL_RE, '');
|
|
63
|
+
return `{${cleaned}}`;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const KEYFRAMES_BLOCK_RE = /@keyframes\s+[\w-]+\s*\{([^}]*(\{[^}]*\}[^}]*)*)\}/gs;
|
|
67
|
+
function sanitizeKeyframesInCss(css) {
|
|
68
|
+
KEYFRAMES_BLOCK_RE.lastIndex = 0;
|
|
69
|
+
return css.replace(KEYFRAMES_BLOCK_RE, (block) => sanitizeKeyframeBlock(block));
|
|
70
|
+
}
|
|
71
|
+
function injectRmCss(html) {
|
|
72
|
+
if (/\.\brm\b/.test(html) && /\.rm\s*\*/.test(html))
|
|
73
|
+
return html;
|
|
74
|
+
const styleClose = html.lastIndexOf('</style>');
|
|
75
|
+
if (styleClose < 0)
|
|
76
|
+
return html;
|
|
77
|
+
return html.slice(0, styleClose) + RM_CSS + html.slice(styleClose);
|
|
78
|
+
}
|
|
79
|
+
function sanitizeHtmlMotion(html) {
|
|
80
|
+
const styleRe = /(<style[^>]*>)([\s\S]*?)(<\/style>)/gi;
|
|
81
|
+
let changed = false;
|
|
82
|
+
const out = html.replace(styleRe, (_full, open, css, close) => {
|
|
83
|
+
let next = sanitizeTransitionsInCss(css);
|
|
84
|
+
next = sanitizeKeyframesInCss(next);
|
|
85
|
+
if (next !== css)
|
|
86
|
+
changed = true;
|
|
87
|
+
return open + next + close;
|
|
88
|
+
});
|
|
89
|
+
const withRm = injectRmCss(out);
|
|
90
|
+
if (withRm !== out)
|
|
91
|
+
changed = true;
|
|
92
|
+
return { html: withRm, changed };
|
|
93
|
+
}
|
|
94
|
+
/** Apply deterministic motion + .rm CSS fixes to HTML targets from a verify report. */
|
|
95
|
+
export function applyMotionAutofix(projectRoot, report) {
|
|
96
|
+
const motionFails = report.results.filter((r) => !r.ok &&
|
|
97
|
+
r.file &&
|
|
98
|
+
(r.id === 'motion.keyframes' ||
|
|
99
|
+
r.id === 'motion.transitions' ||
|
|
100
|
+
r.id === 'css.dead-hook'));
|
|
101
|
+
if (motionFails.length === 0) {
|
|
102
|
+
return { applied: false, filesChanged: [], fixes: [] };
|
|
103
|
+
}
|
|
104
|
+
const targets = new Set();
|
|
105
|
+
for (const r of motionFails) {
|
|
106
|
+
if (r.file)
|
|
107
|
+
targets.add(r.file);
|
|
108
|
+
}
|
|
109
|
+
if (targets.size === 0)
|
|
110
|
+
targets.add('index.html');
|
|
111
|
+
const filesChanged = [];
|
|
112
|
+
const fixes = [];
|
|
113
|
+
const scanOpts = {
|
|
114
|
+
compositorOnly: DEFAULT_NFR_SPEC.animation?.compositorOnly ?? true,
|
|
115
|
+
forbidLayoutProps: DEFAULT_NFR_SPEC.animation?.forbidLayoutProps ?? true,
|
|
116
|
+
};
|
|
117
|
+
for (const rel of targets) {
|
|
118
|
+
const abs = join(projectRoot, rel);
|
|
119
|
+
let html;
|
|
120
|
+
try {
|
|
121
|
+
html = readFileSync(abs, 'utf8');
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const beforeK = scanKeyframesViolations(html, scanOpts).length;
|
|
127
|
+
const beforeT = scanTransitionViolations(html, scanOpts).length;
|
|
128
|
+
const needsRm = motionFails.some((r) => r.id === 'css.dead-hook' && r.file === rel && r.evidence?.includes("'rm'"));
|
|
129
|
+
const { html: next, changed: motionChanged } = sanitizeHtmlMotion(html);
|
|
130
|
+
let final = next;
|
|
131
|
+
if (needsRm && !/\.\brm\s*\*/.test(final)) {
|
|
132
|
+
final = injectRmCss(final);
|
|
133
|
+
}
|
|
134
|
+
const afterK = scanKeyframesViolations(final, scanOpts).length;
|
|
135
|
+
const afterT = scanTransitionViolations(final, scanOpts).length;
|
|
136
|
+
if (final !== html || beforeK > afterK || beforeT > afterT) {
|
|
137
|
+
writeFileSync(abs, final, 'utf8');
|
|
138
|
+
filesChanged.push(rel);
|
|
139
|
+
if (beforeK > afterK)
|
|
140
|
+
fixes.push(`${rel}: sanitized ${beforeK - afterK} keyframe violation(s)`);
|
|
141
|
+
if (beforeT > afterT)
|
|
142
|
+
fixes.push(`${rel}: sanitized ${beforeT - afterT} transition violation(s)`);
|
|
143
|
+
if (needsRm && /\.\brm\s*\*/.test(final))
|
|
144
|
+
fixes.push(`${rel}: added .rm reduced-motion CSS`);
|
|
145
|
+
if (!fixes.some((f) => f.startsWith(rel)))
|
|
146
|
+
fixes.push(`${rel}: motion CSS sanitized`);
|
|
147
|
+
}
|
|
148
|
+
else if (motionChanged) {
|
|
149
|
+
writeFileSync(abs, final, 'utf8');
|
|
150
|
+
filesChanged.push(rel);
|
|
151
|
+
fixes.push(`${rel}: motion CSS sanitized`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
applied: filesChanged.length > 0,
|
|
156
|
+
filesChanged,
|
|
157
|
+
fixes,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=motionAutofix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motionAutofix.js","sourceRoot":"","sources":["../../../src/council/verification/motionAutofix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,GAAG,mBAAmB;IACtB,YAAY;IACZ,YAAY;IACZ,kBAAkB;IAClB,qBAAqB;IACrB,OAAO;IACP,cAAc;IACd,QAAQ;IACR,KAAK;CACN,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG;;;;;;;;;;CAUd,CAAC;AAEF,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,IAAI,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,6EAA6E;AAC7E,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;IACnE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAa;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,KAAK;SACf,GAAG,CAAC,sBAAsB,CAAC;SAC3B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACpD,CAAC;AAED,MAAM,kBAAkB,GAAG,8CAA8C,CAAC;AAE1E,SAAS,wBAAwB,CAAC,GAAW;IAC3C,OAAO,GAAG,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,IAAI,EAAE,IAAY,EAAE,KAAa,EAAE,EAAE;QAC3E,MAAM,IAAI,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,iBAAiB,GACrB,mNAAmN,CAAC;AAEtN,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,IAAY,EAAE,EAAE;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QACpD,OAAO,IAAI,OAAO,GAAG,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,kBAAkB,GAAG,sDAAsD,CAAC;AAElF,SAAS,sBAAsB,CAAC,GAAW;IACzC,kBAAkB,CAAC,SAAS,GAAG,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,uCAAuC,CAAC;IACxD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,GAAW,EAAE,KAAa,EAAE,EAAE;QACpF,IAAI,IAAI,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,IAAI,KAAK,GAAG;YAAE,OAAO,GAAG,IAAI,CAAC;QACjC,OAAO,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACnC,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,kBAAkB,CAChC,WAAmB,EACnB,MAA0B;IAE1B,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CACvC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,CAAC,EAAE;QACL,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,EAAE,KAAK,kBAAkB;YAC1B,CAAC,CAAC,EAAE,KAAK,oBAAoB;YAC7B,CAAC,CAAC,EAAE,KAAK,eAAe,CAAC,CAC9B,CAAC;IACF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAElD,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG;QACf,cAAc,EAAE,gBAAgB,CAAC,SAAS,EAAE,cAAc,IAAI,IAAI;QAClE,iBAAiB,EAAE,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,IAAI,IAAI;KACzE,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACnC,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;QAC/D,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;QAChE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,eAAe,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAClF,CAAC;QACF,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACxE,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;QAC/D,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;QAChE,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,GAAG,MAAM,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC;YAC3D,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAClC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,OAAO,GAAG,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,eAAe,OAAO,GAAG,MAAM,wBAAwB,CAAC,CAAC;YAChG,IAAI,OAAO,GAAG,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,eAAe,OAAO,GAAG,MAAM,0BAA0B,CAAC,CAAC;YAClG,IAAI,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,gCAAgC,CAAC,CAAC;YAC7F,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,wBAAwB,CAAC,CAAC;QACxF,CAAC;aAAM,IAAI,aAAa,EAAE,CAAC;YACzB,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAClC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,wBAAwB,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;QAChC,YAAY;QACZ,KAAK;KACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight CSS motion scanner — @keyframes and transition declarations.
|
|
3
|
+
* No full CSS parser; conservative regex over `<style>` blocks and inline CSS.
|
|
4
|
+
*/
|
|
5
|
+
/** Properties always treated as non-compositor. */
|
|
6
|
+
export declare const LAYOUT_MOTION_PROPS: Set<string>;
|
|
7
|
+
export declare const COMPOSITOR_ONLY_PROPS: Set<string>;
|
|
8
|
+
export interface CssMotionViolation {
|
|
9
|
+
kind: 'keyframes' | 'transition';
|
|
10
|
+
property: string;
|
|
11
|
+
line: number;
|
|
12
|
+
snippet: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function scanKeyframesViolations(html: string, opts: {
|
|
15
|
+
compositorOnly: boolean;
|
|
16
|
+
forbidLayoutProps: boolean;
|
|
17
|
+
}): CssMotionViolation[];
|
|
18
|
+
export declare function scanTransitionViolations(html: string, opts: {
|
|
19
|
+
compositorOnly: boolean;
|
|
20
|
+
forbidLayoutProps: boolean;
|
|
21
|
+
}): CssMotionViolation[];
|
|
22
|
+
//# sourceMappingURL=parseCssMotion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseCssMotion.d.ts","sourceRoot":"","sources":["../../../src/council/verification/parseCssMotion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,mDAAmD;AACnD,eAAO,MAAM,mBAAmB,aAM9B,CAAC;AAEH,eAAO,MAAM,qBAAqB,aAAoC,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,WAAW,GAAG,YAAY,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAqCD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE,GAC5D,kBAAkB,EAAE,CA2BtB;AAgCD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE,GAC5D,kBAAkB,EAAE,CAoCtB"}
|