@neonwatty/limner 0.1.1 → 0.1.2
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/README.md +25 -26
- package/dist/commands/compare-image-reference.d.ts +3 -0
- package/dist/commands/compare-image-reference.js +26 -3
- package/dist/commands/compare-image-reference.js.map +1 -1
- package/dist/commands/compare.d.ts +4 -1
- package/dist/commands/compare.js +72 -45
- package/dist/commands/compare.js.map +1 -1
- package/dist/core/agent-comparison-fingerprint.d.ts +12 -0
- package/dist/core/agent-comparison-fingerprint.js +27 -0
- package/dist/core/agent-comparison-fingerprint.js.map +1 -0
- package/dist/core/agent-comparison-pack.d.ts +30 -0
- package/dist/core/agent-comparison-pack.js +148 -0
- package/dist/core/agent-comparison-pack.js.map +1 -0
- package/dist/core/agent-comparison-profiles.d.ts +9 -0
- package/dist/core/agent-comparison-profiles.js +19 -0
- package/dist/core/agent-comparison-profiles.js.map +1 -0
- package/dist/core/agent-comparison-prompts.d.ts +22 -0
- package/dist/core/agent-comparison-prompts.js +84 -0
- package/dist/core/agent-comparison-prompts.js.map +1 -0
- package/dist/core/agent-comparison-report.d.ts +3 -0
- package/dist/core/agent-comparison-report.js +56 -0
- package/dist/core/agent-comparison-report.js.map +1 -0
- package/dist/core/agent-comparison-validation.d.ts +2 -0
- package/dist/core/agent-comparison-validation.js +8 -0
- package/dist/core/agent-comparison-validation.js.map +1 -0
- package/dist/core/playwright-capture.js +1 -1
- package/dist/core/playwright-capture.js.map +1 -1
- package/dist/core/report-writer.d.ts +7 -11
- package/dist/core/report-writer.js +20 -42
- package/dist/core/report-writer.js.map +1 -1
- package/dist/core/workspace.d.ts +1 -0
- package/dist/core/workspace.js +13 -2
- package/dist/core/workspace.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/schemas/comparison.d.ts +349 -0
- package/dist/schemas/comparison.js +211 -0
- package/dist/schemas/comparison.js.map +1 -0
- package/dist/schemas/visual-spec.d.ts +8 -8
- package/dist/schemas/visual-spec.js +2 -2
- package/dist/schemas/visual-spec.js.map +1 -1
- package/docs/agent-workflow.md +18 -31
- package/docs/superpowers/plans/2026-06-12-agent-comparison-scores.md +209 -0
- package/package.json +1 -1
- package/skills/limner/SKILL.md +15 -18
- package/templates/target/AGENT_GUIDE.md +12 -8
- package/dist/commands/compare-image-app.d.ts +0 -12
- package/dist/commands/compare-image-app.js +0 -45
- package/dist/commands/compare-image-app.js.map +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { agentComparisonBundleSchema, createAgentComparisonBundleExample, createAgentComparisonJsonSchema, } from '../schemas/comparison.js';
|
|
4
|
+
import { clearAgentComparisonOutputs, createInputFingerprint } from './agent-comparison-fingerprint.js';
|
|
5
|
+
import { buildAgentComparisonPrompt, buildClaudeAgentComparisonPrompt, buildCodexAgentComparisonPrompt, } from './agent-comparison-prompts.js';
|
|
6
|
+
import { validateFixTargets } from './agent-comparison-validation.js';
|
|
7
|
+
export async function writeAgentComparisonPack(input) {
|
|
8
|
+
const packDir = path.join(input.captureDir, 'agent-comparison');
|
|
9
|
+
const promptPath = path.join(packDir, 'agent-prompt.md');
|
|
10
|
+
const codexPromptPath = path.join(packDir, 'agent-prompt.codex.md');
|
|
11
|
+
const claudePromptPath = path.join(packDir, 'agent-prompt.claude.md');
|
|
12
|
+
const schemaPath = path.join(packDir, 'agent-response.schema.json');
|
|
13
|
+
const examplePath = path.join(packDir, 'agent-response.example.json');
|
|
14
|
+
const responsePath = path.join(packDir, 'agent-response.json');
|
|
15
|
+
const inputFingerprint = await createInputFingerprint(input);
|
|
16
|
+
const promptInput = { ...input, schemaPath, responsePath, inputFingerprint };
|
|
17
|
+
await mkdir(packDir, { recursive: true });
|
|
18
|
+
await clearAgentComparisonOutputs(input.captureDir);
|
|
19
|
+
await Promise.all([
|
|
20
|
+
writeJson(schemaPath, createAgentComparisonJsonSchema(input.structureInputs ? 'image-and-structure' : 'image-only')),
|
|
21
|
+
writeJson(examplePath, createExample(input, inputFingerprint)),
|
|
22
|
+
writeFile(promptPath, buildAgentComparisonPrompt(promptInput)),
|
|
23
|
+
writeFile(codexPromptPath, buildCodexAgentComparisonPrompt(promptInput)),
|
|
24
|
+
writeFile(claudePromptPath, buildClaudeAgentComparisonPrompt(promptInput)),
|
|
25
|
+
]);
|
|
26
|
+
const response = await readBundle(responsePath);
|
|
27
|
+
const base = { promptPath, codexPromptPath, claudePromptPath, schemaPath, examplePath, responsePath };
|
|
28
|
+
if (response.status === 'missing') {
|
|
29
|
+
return { ...base, status: 'awaiting-agent' };
|
|
30
|
+
}
|
|
31
|
+
if (response.status === 'invalid-json') {
|
|
32
|
+
return { ...base, status: 'invalid', validationErrors: ['agent-response.json: Invalid JSON.'] };
|
|
33
|
+
}
|
|
34
|
+
const parsed = agentComparisonBundleSchema.safeParse(response.value);
|
|
35
|
+
if (!parsed.success) {
|
|
36
|
+
return { ...base, status: 'invalid', validationErrors: parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`) };
|
|
37
|
+
}
|
|
38
|
+
const activeErrors = validateActiveComparison({ ...input, inputFingerprint }, parsed.data);
|
|
39
|
+
if (activeErrors.length > 0) {
|
|
40
|
+
return { ...base, status: 'invalid', validationErrors: activeErrors };
|
|
41
|
+
}
|
|
42
|
+
const imageComparisonPath = path.join(input.captureDir, 'image-comparison.json');
|
|
43
|
+
const structureComparisonPath = parsed.data.structureComparison ? path.join(input.captureDir, 'structure-comparison.json') : undefined;
|
|
44
|
+
const summaryPath = path.join(input.captureDir, 'comparison-summary.json');
|
|
45
|
+
await writeJson(imageComparisonPath, parsed.data.imageComparison);
|
|
46
|
+
if (parsed.data.structureComparison && structureComparisonPath) {
|
|
47
|
+
await writeJson(structureComparisonPath, parsed.data.structureComparison);
|
|
48
|
+
}
|
|
49
|
+
await writeJson(summaryPath, parsed.data);
|
|
50
|
+
return {
|
|
51
|
+
...base,
|
|
52
|
+
status: 'validated',
|
|
53
|
+
imageComparisonPath,
|
|
54
|
+
structureComparisonPath,
|
|
55
|
+
summaryPath,
|
|
56
|
+
scoreHighlights: [
|
|
57
|
+
`Agent image score: ${parsed.data.imageComparison.score.overall}`,
|
|
58
|
+
...(parsed.data.structureComparison ? [`Agent structure score: ${parsed.data.structureComparison.score.overall}`] : []),
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async function readBundle(filePath) {
|
|
63
|
+
try {
|
|
64
|
+
return { status: 'ok', value: JSON.parse(await readFile(filePath, 'utf8')) };
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
try {
|
|
68
|
+
await readFile(filePath, 'utf8');
|
|
69
|
+
return { status: 'invalid-json' };
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return { status: 'missing' };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function createExample(input, inputFingerprint) {
|
|
77
|
+
const example = createAgentComparisonBundleExample(input.structureInputs ? 'image-and-structure' : 'image-only', inputFingerprint);
|
|
78
|
+
example.profile = input.profile;
|
|
79
|
+
example.imageComparison.inputs = {
|
|
80
|
+
expectedImagePath: relative(input.workspaceRoot, input.imageInputs.expectedImagePath),
|
|
81
|
+
actualImagePath: relative(input.workspaceRoot, input.imageInputs.actualImagePath),
|
|
82
|
+
};
|
|
83
|
+
if (input.structureInputs && example.structureComparison) {
|
|
84
|
+
example.structureComparison.inputs = {
|
|
85
|
+
expectedStructurePath: relative(input.workspaceRoot, input.structureInputs.expectedStructurePath),
|
|
86
|
+
actualStructurePath: relative(input.workspaceRoot, input.structureInputs.actualStructurePath),
|
|
87
|
+
structureKind: input.structureInputs.structureKind,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return example;
|
|
91
|
+
}
|
|
92
|
+
function validateActiveComparison(input, bundle) {
|
|
93
|
+
const errors = [];
|
|
94
|
+
if (bundle.profile !== input.profile)
|
|
95
|
+
errors.push(`profile: Expected ${input.profile}.`);
|
|
96
|
+
const expectedSurface = input.profile === 'ideal-to-mockup' ? 'mockup' : 'implementation';
|
|
97
|
+
if (!matchesPath(input.workspaceRoot, input.imageInputs.expectedImagePath, bundle.imageComparison.inputs.expectedImagePath)) {
|
|
98
|
+
errors.push('imageComparison.inputs.expectedImagePath: Does not match the active expected image.');
|
|
99
|
+
}
|
|
100
|
+
if (!matchesPath(input.workspaceRoot, input.imageInputs.actualImagePath, bundle.imageComparison.inputs.actualImagePath)) {
|
|
101
|
+
errors.push('imageComparison.inputs.actualImagePath: Does not match the active actual image.');
|
|
102
|
+
}
|
|
103
|
+
if (bundle.inputFingerprint.expectedImageSha256 !== input.inputFingerprint.expectedImageSha256) {
|
|
104
|
+
errors.push('inputFingerprint.expectedImageSha256: Does not match the active expected image.');
|
|
105
|
+
}
|
|
106
|
+
if (bundle.inputFingerprint.actualImageSha256 !== input.inputFingerprint.actualImageSha256) {
|
|
107
|
+
errors.push('inputFingerprint.actualImageSha256: Does not match the active actual image.');
|
|
108
|
+
}
|
|
109
|
+
validateFixTargets(errors, 'imageComparison', bundle.imageComparison.majorDiffAreas, expectedSurface);
|
|
110
|
+
if (!input.structureInputs && bundle.structureComparison) {
|
|
111
|
+
errors.push('structureComparison: Not expected for this comparison.');
|
|
112
|
+
}
|
|
113
|
+
if (!input.structureInputs && (bundle.inputFingerprint.expectedStructureSha256 || bundle.inputFingerprint.actualStructureSha256)) {
|
|
114
|
+
errors.push('inputFingerprint: Structure hashes are not expected for this comparison.');
|
|
115
|
+
}
|
|
116
|
+
if (input.structureInputs && !bundle.structureComparison) {
|
|
117
|
+
errors.push('structureComparison: Required for this comparison.');
|
|
118
|
+
}
|
|
119
|
+
if (input.structureInputs && bundle.structureComparison) {
|
|
120
|
+
validateFixTargets(errors, 'structureComparison', bundle.structureComparison.majorDiffAreas, expectedSurface);
|
|
121
|
+
if (bundle.inputFingerprint.expectedStructureSha256 !== input.inputFingerprint.expectedStructureSha256) {
|
|
122
|
+
errors.push('inputFingerprint.expectedStructureSha256: Does not match the active expected structure.');
|
|
123
|
+
}
|
|
124
|
+
if (bundle.inputFingerprint.actualStructureSha256 !== input.inputFingerprint.actualStructureSha256) {
|
|
125
|
+
errors.push('inputFingerprint.actualStructureSha256: Does not match the active actual structure.');
|
|
126
|
+
}
|
|
127
|
+
if (!matchesPath(input.workspaceRoot, input.structureInputs.expectedStructurePath, bundle.structureComparison.inputs.expectedStructurePath)) {
|
|
128
|
+
errors.push('structureComparison.inputs.expectedStructurePath: Does not match the active expected structure.');
|
|
129
|
+
}
|
|
130
|
+
if (!matchesPath(input.workspaceRoot, input.structureInputs.actualStructurePath, bundle.structureComparison.inputs.actualStructurePath)) {
|
|
131
|
+
errors.push('structureComparison.inputs.actualStructurePath: Does not match the active actual structure.');
|
|
132
|
+
}
|
|
133
|
+
if (bundle.structureComparison.inputs.structureKind !== input.structureInputs.structureKind) {
|
|
134
|
+
errors.push(`structureComparison.inputs.structureKind: Expected ${input.structureInputs.structureKind}.`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return errors;
|
|
138
|
+
}
|
|
139
|
+
function matchesPath(root, expectedAbsolute, actual) {
|
|
140
|
+
return actual === expectedAbsolute || actual === relative(root, expectedAbsolute);
|
|
141
|
+
}
|
|
142
|
+
function relative(root, filePath) {
|
|
143
|
+
return path.relative(root, filePath);
|
|
144
|
+
}
|
|
145
|
+
async function writeJson(filePath, value) {
|
|
146
|
+
await writeFile(filePath, JSON.stringify(value, null, 2) + '\n');
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=agent-comparison-pack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-comparison-pack.js","sourceRoot":"","sources":["../../src/core/agent-comparison-pack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type AgentComparisonProfileName = 'ideal-to-mockup' | 'mockup-to-implementation';
|
|
2
|
+
export type AgentComparisonProfile = {
|
|
3
|
+
name: AgentComparisonProfileName;
|
|
4
|
+
expectedRole: string;
|
|
5
|
+
actualRole: string;
|
|
6
|
+
editableSurface: 'mockup' | 'implementation';
|
|
7
|
+
instruction: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function getAgentComparisonProfile(name: AgentComparisonProfileName): AgentComparisonProfile;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function getAgentComparisonProfile(name) {
|
|
2
|
+
if (name === 'ideal-to-mockup') {
|
|
3
|
+
return {
|
|
4
|
+
name,
|
|
5
|
+
expectedRole: 'ideal image',
|
|
6
|
+
actualRole: 'HTML mockup screenshot',
|
|
7
|
+
editableSurface: 'mockup',
|
|
8
|
+
instruction: 'Focus on changes to the HTML/CSS mockup that will make the next screenshot closer to the ideal.',
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
name,
|
|
13
|
+
expectedRole: 'approved HTML mockup screenshot',
|
|
14
|
+
actualRole: 'implementation screenshot',
|
|
15
|
+
editableSurface: 'implementation',
|
|
16
|
+
instruction: 'Treat the mockup as canonical and focus on implementation changes that will match it.',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=agent-comparison-profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-comparison-profiles.js","sourceRoot":"","sources":["../../src/core/agent-comparison-profiles.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,yBAAyB,CAAC,IAAgC;IACxE,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,OAAO;YACL,IAAI;YACJ,YAAY,EAAE,aAAa;YAC3B,UAAU,EAAE,wBAAwB;YACpC,eAAe,EAAE,QAAQ;YACzB,WAAW,EAAE,iGAAiG;SAC/G,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI;QACJ,YAAY,EAAE,iCAAiC;QAC/C,UAAU,EAAE,2BAA2B;QACvC,eAAe,EAAE,gBAAgB;QACjC,WAAW,EAAE,uFAAuF;KACrG,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AgentComparisonInputFingerprint } from '../schemas/comparison.js';
|
|
2
|
+
import { type AgentComparisonProfileName } from './agent-comparison-profiles.js';
|
|
3
|
+
type PromptInput = {
|
|
4
|
+
workspaceRoot: string;
|
|
5
|
+
profile: AgentComparisonProfileName;
|
|
6
|
+
responsePath: string;
|
|
7
|
+
schemaPath: string;
|
|
8
|
+
inputFingerprint: AgentComparisonInputFingerprint;
|
|
9
|
+
imageInputs: {
|
|
10
|
+
expectedImagePath: string;
|
|
11
|
+
actualImagePath: string;
|
|
12
|
+
};
|
|
13
|
+
structureInputs?: {
|
|
14
|
+
expectedStructurePath: string;
|
|
15
|
+
actualStructurePath: string;
|
|
16
|
+
structureKind: 'visual-spec' | 'dom-metrics' | 'html' | 'json-description';
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export declare function buildAgentComparisonPrompt(input: PromptInput): string;
|
|
20
|
+
export declare function buildCodexAgentComparisonPrompt(input: PromptInput): string;
|
|
21
|
+
export declare function buildClaudeAgentComparisonPrompt(input: PromptInput): string;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getAgentComparisonProfile } from './agent-comparison-profiles.js';
|
|
3
|
+
export function buildAgentComparisonPrompt(input) {
|
|
4
|
+
const profile = getAgentComparisonProfile(input.profile);
|
|
5
|
+
return `# Limner Agent UX Comparison
|
|
6
|
+
|
|
7
|
+
Profile: \`${profile.name}\`
|
|
8
|
+
Expected role: ${profile.expectedRole}
|
|
9
|
+
Actual role: ${profile.actualRole}
|
|
10
|
+
Editable surface: ${profile.editableSurface}
|
|
11
|
+
|
|
12
|
+
${profile.instruction}
|
|
13
|
+
|
|
14
|
+
## Image Inputs
|
|
15
|
+
|
|
16
|
+
- Expected image: \`${rel(input, input.imageInputs.expectedImagePath)}\`
|
|
17
|
+
- Actual image: \`${rel(input, input.imageInputs.actualImagePath)}\`
|
|
18
|
+
|
|
19
|
+
## Input Fingerprint
|
|
20
|
+
|
|
21
|
+
Copy these values exactly into \`inputFingerprint\`. Limner uses them to reject stale responses after screenshots or structure files change.
|
|
22
|
+
|
|
23
|
+
- \`expectedImageSha256\`: \`${input.inputFingerprint.expectedImageSha256}\`
|
|
24
|
+
- \`actualImageSha256\`: \`${input.inputFingerprint.actualImageSha256}\`
|
|
25
|
+
${formatStructureFingerprint(input.inputFingerprint)}
|
|
26
|
+
|
|
27
|
+
Inspect the expected and actual images separately before using side-by-side context.
|
|
28
|
+
Focus on the next implementation iteration, not exhaustive critique.
|
|
29
|
+
Name only high-signal UX diffs: layout, hierarchy, typography, color, spacing, component anatomy, copy/state, and attention flow.
|
|
30
|
+
${formatStructureSection(input)}
|
|
31
|
+
Use this JSON schema:
|
|
32
|
+
|
|
33
|
+
- \`${rel(input, input.schemaPath)}\`
|
|
34
|
+
|
|
35
|
+
Write valid JSON only to:
|
|
36
|
+
|
|
37
|
+
- \`${rel(input, input.responsePath)}\`
|
|
38
|
+
|
|
39
|
+
Rules:
|
|
40
|
+
|
|
41
|
+
- Scores are 0..1 estimates, not pass/fail judgments.
|
|
42
|
+
- Do not invent diffs when the artifacts match; empty \`majorDiffAreas\` and empty next steps are valid.
|
|
43
|
+
- Every diff must include evidence, impact, and a recommended change for the editable surface.
|
|
44
|
+
- Use \`systemFeedback\` only for issues with Limner inputs, missing context, or prompt/tooling quality.
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
export function buildCodexAgentComparisonPrompt(input) {
|
|
48
|
+
return `${buildAgentComparisonPrompt(input)}
|
|
49
|
+
## Codex Instructions
|
|
50
|
+
|
|
51
|
+
Read the local files directly. Create or overwrite \`${rel(input, input.responsePath)}\` with JSON matching the schema.
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
export function buildClaudeAgentComparisonPrompt(input) {
|
|
55
|
+
return `${buildAgentComparisonPrompt(input)}
|
|
56
|
+
## Claude Instructions
|
|
57
|
+
|
|
58
|
+
Attach the referenced images, inspect them separately, and return JSON matching the schema. Copy that JSON into \`${rel(input, input.responsePath)}\`.
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
function formatStructureFingerprint(fingerprint) {
|
|
62
|
+
if (!fingerprint.expectedStructureSha256 || !fingerprint.actualStructureSha256)
|
|
63
|
+
return '';
|
|
64
|
+
return `- \`expectedStructureSha256\`: \`${fingerprint.expectedStructureSha256}\`
|
|
65
|
+
- \`actualStructureSha256\`: \`${fingerprint.actualStructureSha256}\``;
|
|
66
|
+
}
|
|
67
|
+
function formatStructureSection(input) {
|
|
68
|
+
if (!input.structureInputs) {
|
|
69
|
+
return '';
|
|
70
|
+
}
|
|
71
|
+
return `
|
|
72
|
+
## Structure Inputs
|
|
73
|
+
|
|
74
|
+
- Expected structure: \`${rel(input, input.structureInputs.expectedStructurePath)}\`
|
|
75
|
+
- Actual structure: \`${rel(input, input.structureInputs.actualStructurePath)}\`
|
|
76
|
+
- Structure kind: \`${input.structureInputs.structureKind}\`
|
|
77
|
+
|
|
78
|
+
Use structure evidence to support image findings and to produce a structure-vs-structure comparison.
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
function rel(input, filePath) {
|
|
82
|
+
return path.relative(input.workspaceRoot, filePath);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=agent-comparison-prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-comparison-prompts.js","sourceRoot":"","sources":["../../src/core/agent-comparison-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,yBAAyB,EAAmC,MAAM,gCAAgC,CAAC;AAmB5G,MAAM,UAAU,0BAA0B,CAAC,KAAkB;IAC3D,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzD,OAAO;;aAEI,OAAO,CAAC,IAAI;iBACR,OAAO,CAAC,YAAY;eACtB,OAAO,CAAC,UAAU;oBACb,OAAO,CAAC,eAAe;;EAEzC,OAAO,CAAC,WAAW;;;;sBAIC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,iBAAiB,CAAC;oBACjD,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,eAAe,CAAC;;;;;;+BAMlC,KAAK,CAAC,gBAAgB,CAAC,mBAAmB;6BAC5C,KAAK,CAAC,gBAAgB,CAAC,iBAAiB;EACnE,0BAA0B,CAAC,KAAK,CAAC,gBAAgB,CAAC;;;;;EAKlD,sBAAsB,CAAC,KAAK,CAAC;;;MAGzB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC;;;;MAI5B,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC;;;;;;;;CAQnC,CAAC;AACF,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAkB;IAChE,OAAO,GAAG,0BAA0B,CAAC,KAAK,CAAC;;;uDAGU,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC;CACpF,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,KAAkB;IACjE,OAAO,GAAG,0BAA0B,CAAC,KAAK,CAAC;;;oHAGuE,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC;CACjJ,CAAC;AACF,CAAC;AAED,SAAS,0BAA0B,CAAC,WAA4C;IAC9E,IAAI,CAAC,WAAW,CAAC,uBAAuB,IAAI,CAAC,WAAW,CAAC,qBAAqB;QAAE,OAAO,EAAE,CAAC;IAC1F,OAAO,oCAAoC,WAAW,CAAC,uBAAuB;iCAC/C,WAAW,CAAC,qBAAqB,IAAI,CAAC;AACvE,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAkB;IAChD,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO;;;0BAGiB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC,qBAAqB,CAAC;wBACzD,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,eAAe,CAAC,mBAAmB,CAAC;sBACvD,KAAK,CAAC,eAAe,CAAC,aAAa;;;CAGxD,CAAC;AACF,CAAC;AAED,SAAS,GAAG,CAAC,KAAkB,EAAE,QAAgB;IAC/C,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AgentComparisonPackResult } from './agent-comparison-pack.js';
|
|
2
|
+
export declare function formatAgentComparisonArtifacts(root: string, agentComparison?: AgentComparisonPackResult): string;
|
|
3
|
+
export declare function formatAgentComparisonStatus(agentComparison?: AgentComparisonPackResult): string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
export function formatAgentComparisonArtifacts(root, agentComparison) {
|
|
3
|
+
if (!agentComparison) {
|
|
4
|
+
return '';
|
|
5
|
+
}
|
|
6
|
+
const lines = [
|
|
7
|
+
`- Agent comparison prompt: \`${relative(root, agentComparison.promptPath)}\``,
|
|
8
|
+
`- Codex comparison prompt: \`${relative(root, agentComparison.codexPromptPath)}\``,
|
|
9
|
+
`- Claude comparison prompt: \`${relative(root, agentComparison.claudePromptPath)}\``,
|
|
10
|
+
`- Agent comparison schema: \`${relative(root, agentComparison.schemaPath)}\``,
|
|
11
|
+
`- Agent comparison response: \`${relative(root, agentComparison.responsePath)}\``,
|
|
12
|
+
];
|
|
13
|
+
if (agentComparison.imageComparisonPath) {
|
|
14
|
+
lines.push(`- Image comparison: \`${relative(root, agentComparison.imageComparisonPath)}\``);
|
|
15
|
+
}
|
|
16
|
+
if (agentComparison.structureComparisonPath) {
|
|
17
|
+
lines.push(`- Structure comparison: \`${relative(root, agentComparison.structureComparisonPath)}\``);
|
|
18
|
+
}
|
|
19
|
+
if (agentComparison.summaryPath) {
|
|
20
|
+
lines.push(`- Comparison summary: \`${relative(root, agentComparison.summaryPath)}\``);
|
|
21
|
+
}
|
|
22
|
+
return `\n${lines.join('\n')}`;
|
|
23
|
+
}
|
|
24
|
+
export function formatAgentComparisonStatus(agentComparison) {
|
|
25
|
+
if (!agentComparison) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
if (agentComparison.status === 'awaiting-agent') {
|
|
29
|
+
return `
|
|
30
|
+
|
|
31
|
+
## Agent Comparison
|
|
32
|
+
|
|
33
|
+
- Status: awaiting agent response.
|
|
34
|
+
- Next step: have an agent inspect the comparison prompt, write \`${path.basename(agentComparison.responsePath)}\`, then rerun this compare command.`;
|
|
35
|
+
}
|
|
36
|
+
if (agentComparison.status === 'invalid') {
|
|
37
|
+
const errors = agentComparison.validationErrors?.map((error) => `- ${error}`).join('\n') ?? '- Unknown validation error.';
|
|
38
|
+
return `
|
|
39
|
+
|
|
40
|
+
## Agent Comparison
|
|
41
|
+
|
|
42
|
+
- Status: invalid agent response.
|
|
43
|
+
|
|
44
|
+
${errors}`;
|
|
45
|
+
}
|
|
46
|
+
return `
|
|
47
|
+
|
|
48
|
+
## Agent Comparison
|
|
49
|
+
|
|
50
|
+
- Status: validated.
|
|
51
|
+
${agentComparison.scoreHighlights?.map((highlight) => `- ${highlight}`).join('\n') ?? '- Agent comparison artifacts validated.'}`;
|
|
52
|
+
}
|
|
53
|
+
function relative(root, filePath) {
|
|
54
|
+
return path.relative(root, filePath);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=agent-comparison-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-comparison-report.js","sourceRoot":"","sources":["../../src/core/agent-comparison-report.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,UAAU,8BAA8B,CAAC,IAAY,EAAE,eAA2C;IACtG,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAG;QACZ,gCAAgC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,UAAU,CAAC,IAAI;QAC9E,gCAAgC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,eAAe,CAAC,IAAI;QACnF,iCAAiC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,gBAAgB,CAAC,IAAI;QACrF,gCAAgC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,UAAU,CAAC,IAAI;QAC9E,kCAAkC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,YAAY,CAAC,IAAI;KACnF,CAAC;IACF,IAAI,eAAe,CAAC,mBAAmB,EAAE,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,yBAAyB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,eAAe,CAAC,uBAAuB,EAAE,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,6BAA6B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACvG,CAAC;IACD,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,2BAA2B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,eAA2C;IACrF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,eAAe,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAChD,OAAO;;;;;oEAKyD,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,sCAAsC,CAAC;IACpJ,CAAC;IACD,IAAI,eAAe,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,eAAe,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,6BAA6B,CAAC;QAC1H,OAAO;;;;;;EAMT,MAAM,EAAE,CAAC;IACT,CAAC;IACD,OAAO;;;;;EAKP,eAAe,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,yCAAyC,EAAE,CAAC;AAClI,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,QAAgB;IAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { AgentComparisonBundle } from '../schemas/comparison.js';
|
|
2
|
+
export declare function validateFixTargets(errors: string[], comparisonPath: 'imageComparison' | 'structureComparison', diffAreas: AgentComparisonBundle['imageComparison']['majorDiffAreas'], expectedSurface: 'mockup' | 'implementation'): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function validateFixTargets(errors, comparisonPath, diffAreas, expectedSurface) {
|
|
2
|
+
diffAreas.forEach((diff, index) => {
|
|
3
|
+
if (diff.fixTarget && diff.fixTarget.surface !== expectedSurface && diff.fixTarget.surface !== 'unknown') {
|
|
4
|
+
errors.push(`${comparisonPath}.majorDiffAreas.${index}.fixTarget.surface: Expected ${expectedSurface} or unknown.`);
|
|
5
|
+
}
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=agent-comparison-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-comparison-validation.js","sourceRoot":"","sources":["../../src/core/agent-comparison-validation.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAChC,MAAgB,EAChB,cAAyD,EACzD,SAAqE,EACrE,eAA4C;IAE5C,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAChC,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,KAAK,eAAe,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACzG,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,mBAAmB,KAAK,gCAAgC,eAAe,cAAc,CAAC,CAAC;QACtH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -34,7 +34,7 @@ export async function capturePage(options) {
|
|
|
34
34
|
bodyText,
|
|
35
35
|
};
|
|
36
36
|
await writeFile(`${options.outputPath}.console.json`, JSON.stringify(consoleMessages, null, 2) + '\n');
|
|
37
|
-
if (
|
|
37
|
+
if (options.contract) {
|
|
38
38
|
await writeFile(`${options.outputPath}.metrics.json`, JSON.stringify(metrics, null, 2) + '\n');
|
|
39
39
|
}
|
|
40
40
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright-capture.js","sourceRoot":"","sources":["../../src/core/playwright-capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAuB,MAAM,YAAY,CAAC;AAG3D,OAAO,EAAE,oBAAoB,EAAsB,MAAM,kBAAkB,CAAC;AAsB5E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAuB;IACvD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACvC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;QAC1D,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,MAAM,eAAe,GAA0C,EAAE,CAAC;IAClE,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAuB,EAAE,EAAE;QAC7C,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YAC/D,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ;YAC9B,CAAC,CAAC,MAAM,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;YACjF,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;YACf,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE;YACzB,cAAc,EAAE,OAAO,CAAC,UAAU;YAClC,eAAe;YACf,OAAO;YACP,QAAQ;SACT,CAAC;QACF,MAAM,SAAS,CAAC,GAAG,OAAO,CAAC,UAAU,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACvG,IAAI,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"playwright-capture.js","sourceRoot":"","sources":["../../src/core/playwright-capture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAuB,MAAM,YAAY,CAAC;AAG3D,OAAO,EAAE,oBAAoB,EAAsB,MAAM,kBAAkB,CAAC;AAsB5E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAuB;IACvD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACvC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;QAC1D,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,MAAM,eAAe,GAA0C,EAAE,CAAC;IAClE,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAuB,EAAE,EAAE;QAC7C,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YAC/D,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ;YAC9B,CAAC,CAAC,MAAM,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;YACjF,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;YACf,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE;YACzB,cAAc,EAAE,OAAO,CAAC,UAAU;YAClC,eAAe;YACf,OAAO;YACP,QAAQ;SACT,CAAC;QACF,MAAM,SAAS,CAAC,GAAG,OAAO,CAAC,UAAU,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACvG,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,MAAM,SAAS,CAAC,GAAG,OAAO,CAAC,UAAU,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACjG,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgentComparisonPackResult } from './agent-comparison-pack.js';
|
|
1
2
|
import type { RegionMetrics } from './dom-metrics.js';
|
|
2
3
|
import type { TargetPaths } from './workspace.js';
|
|
3
4
|
export declare function writeImageReferenceReport(input: {
|
|
@@ -23,21 +24,16 @@ export declare function writeImageReferenceReport(input: {
|
|
|
23
24
|
status: 'awaiting-agent' | 'validated' | 'invalid';
|
|
24
25
|
validationErrors?: string[];
|
|
25
26
|
};
|
|
27
|
+
agentComparison?: AgentComparisonPackResult;
|
|
26
28
|
}): Promise<string>;
|
|
27
|
-
export declare function
|
|
29
|
+
export declare function writeReferenceImplementationReport(input: {
|
|
28
30
|
target: TargetPaths;
|
|
29
31
|
referencePath: string;
|
|
30
|
-
|
|
32
|
+
implementationPath: string;
|
|
31
33
|
sideBySidePath: string;
|
|
32
34
|
referenceMetrics: RegionMetrics[];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export declare function writeImageAppReport(input: {
|
|
37
|
-
target: TargetPaths;
|
|
38
|
-
idealPath: string;
|
|
39
|
-
appPath: string;
|
|
40
|
-
sideBySidePath: string;
|
|
41
|
-
appUrl: string;
|
|
35
|
+
implementationMetrics: RegionMetrics[];
|
|
36
|
+
implementationUrl: string;
|
|
37
|
+
agentComparison?: AgentComparisonPackResult;
|
|
42
38
|
}): Promise<string>;
|
|
43
39
|
export declare function writeTargetSummary(target: TargetPaths): Promise<string>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdir, readdir, stat, writeFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { formatAgentComparisonArtifacts, formatAgentComparisonStatus } from './agent-comparison-report.js';
|
|
3
4
|
export async function writeImageReferenceReport(input) {
|
|
4
5
|
const reportPath = path.join(input.target.reportsDir, 'image-reference.md');
|
|
5
6
|
await mkdir(path.dirname(reportPath), { recursive: true });
|
|
@@ -13,6 +14,7 @@ Target: \`${input.target.name}\`
|
|
|
13
14
|
- Reference screenshot: \`${relative(input.target.workspace.root, input.referencePath)}\`
|
|
14
15
|
- Side-by-side: \`${relative(input.target.workspace.root, input.sideBySidePath)}\`
|
|
15
16
|
${formatSpecArtifacts(input.target.workspace.root, input.specPaths, input.agentSpec)}
|
|
17
|
+
${formatAgentComparisonArtifacts(input.target.workspace.root, input.agentComparison)}
|
|
16
18
|
|
|
17
19
|
## Agent Critique
|
|
18
20
|
|
|
@@ -28,64 +30,40 @@ ${formatSpecArtifacts(input.target.workspace.root, input.specPaths, input.agentS
|
|
|
28
30
|
- Record the highest-value scoped fix here.
|
|
29
31
|
${formatAgentSpecStatus(input.agentSpec)}
|
|
30
32
|
${formatSpecHighlights(input.specHighlights)}
|
|
33
|
+
${formatAgentComparisonStatus(input.agentComparison)}
|
|
31
34
|
`);
|
|
32
35
|
return reportPath;
|
|
33
36
|
}
|
|
34
|
-
export async function
|
|
35
|
-
const reportPath = path.join(input.target.reportsDir, 'reference-
|
|
37
|
+
export async function writeReferenceImplementationReport(input) {
|
|
38
|
+
const reportPath = path.join(input.target.reportsDir, 'reference-implementation.md');
|
|
36
39
|
await mkdir(path.dirname(reportPath), { recursive: true });
|
|
37
|
-
await writeFile(reportPath, `# Reference To
|
|
40
|
+
await writeFile(reportPath, `# Reference To Implementation Report
|
|
38
41
|
|
|
39
42
|
Target: \`${input.target.name}\`
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
Implementation URL: ${input.implementationUrl}
|
|
42
45
|
|
|
43
46
|
## Artifacts
|
|
44
47
|
|
|
45
48
|
- Reference screenshot: \`${relative(input.target.workspace.root, input.referencePath)}\`
|
|
46
|
-
-
|
|
49
|
+
- Implementation screenshot: \`${relative(input.target.workspace.root, input.implementationPath)}\`
|
|
47
50
|
- Side-by-side: \`${relative(input.target.workspace.root, input.sideBySidePath)}\`
|
|
51
|
+
${formatAgentComparisonArtifacts(input.target.workspace.root, input.agentComparison)}
|
|
48
52
|
|
|
49
53
|
## Region Metrics
|
|
50
54
|
|
|
51
|
-
${formatMetrics(input.referenceMetrics, input.
|
|
55
|
+
${formatMetrics(input.referenceMetrics, input.implementationMetrics)}
|
|
52
56
|
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
- Highest mismatch:
|
|
56
|
-
- Evidence:
|
|
57
|
-
- Suggested app fix:
|
|
58
|
-
- Intentional deviations:
|
|
59
|
-
`);
|
|
60
|
-
return reportPath;
|
|
61
|
-
}
|
|
62
|
-
export async function writeImageAppReport(input) {
|
|
63
|
-
const reportPath = path.join(input.target.reportsDir, 'image-app.md');
|
|
64
|
-
await mkdir(path.dirname(reportPath), { recursive: true });
|
|
65
|
-
await writeFile(reportPath, `# Image To App Report
|
|
66
|
-
|
|
67
|
-
Target: \`${input.target.name}\`
|
|
68
|
-
|
|
69
|
-
App URL: ${input.appUrl}
|
|
70
|
-
|
|
71
|
-
## Artifacts
|
|
72
|
-
|
|
73
|
-
- Ideal image: \`${relative(input.target.workspace.root, input.idealPath)}\`
|
|
74
|
-
- App screenshot: \`${relative(input.target.workspace.root, input.appPath)}\`
|
|
75
|
-
- Side-by-side: \`${relative(input.target.workspace.root, input.sideBySidePath)}\`
|
|
76
|
-
|
|
77
|
-
## Agent Findings
|
|
57
|
+
## Next Fix
|
|
78
58
|
|
|
79
|
-
-
|
|
80
|
-
|
|
81
|
-
- Suggested app fix:
|
|
82
|
-
- Intentional deviations:
|
|
59
|
+
- Use the validated agent comparison to choose the highest-value implementation fix.
|
|
60
|
+
${formatAgentComparisonStatus(input.agentComparison)}
|
|
83
61
|
`);
|
|
84
62
|
return reportPath;
|
|
85
63
|
}
|
|
86
64
|
export async function writeTargetSummary(target) {
|
|
87
65
|
const lines = [`# Limner Target Summary`, '', `Target: \`${target.name}\``, ''];
|
|
88
|
-
for (const dir of ['captures/image-reference', 'captures/reference-
|
|
66
|
+
for (const dir of ['captures/image-reference', 'captures/reference-implementation', 'reports']) {
|
|
89
67
|
const absoluteDir = path.join(target.root, dir);
|
|
90
68
|
lines.push(`## ${dir}`, '');
|
|
91
69
|
try {
|
|
@@ -103,16 +81,16 @@ export async function writeTargetSummary(target) {
|
|
|
103
81
|
}
|
|
104
82
|
return lines.join('\n');
|
|
105
83
|
}
|
|
106
|
-
function formatMetrics(referenceMetrics,
|
|
107
|
-
const
|
|
84
|
+
function formatMetrics(referenceMetrics, implementationMetrics) {
|
|
85
|
+
const implementationById = new Map(implementationMetrics.map((metric) => [metric.id, metric]));
|
|
108
86
|
const rows = referenceMetrics.map((reference) => {
|
|
109
|
-
const
|
|
87
|
+
const implementation = implementationById.get(reference.id);
|
|
110
88
|
const referenceBounds = reference.bounds ? `${reference.bounds.width}x${reference.bounds.height}` : 'missing';
|
|
111
|
-
const
|
|
112
|
-
return `| ${reference.id} | ${reference.found ? 'yes' : 'no'} | ${
|
|
89
|
+
const implementationBounds = implementation?.bounds ? `${implementation.bounds.width}x${implementation.bounds.height}` : 'missing';
|
|
90
|
+
return `| ${reference.id} | ${reference.found ? 'yes' : 'no'} | ${implementation?.found ? 'yes' : 'no'} | ${referenceBounds} | ${implementationBounds} |`;
|
|
113
91
|
});
|
|
114
92
|
return [
|
|
115
|
-
'| Region | Reference Found |
|
|
93
|
+
'| Region | Reference Found | Implementation Found | Reference Bounds | Implementation Bounds |',
|
|
116
94
|
'| --- | --- | --- | --- | --- |',
|
|
117
95
|
...rows,
|
|
118
96
|
].join('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report-writer.js","sourceRoot":"","sources":["../../src/core/report-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"report-writer.js","sourceRoot":"","sources":["../../src/core/report-writer.ts"],"names":[],"mappings":"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"}
|
package/dist/core/workspace.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export type TargetPaths = {
|
|
|
24
24
|
export declare function resolveWorkspace(root?: string): WorkspacePaths;
|
|
25
25
|
export declare function validateTargetName(target: string): string;
|
|
26
26
|
export declare function resolveTarget(workspaceRoot: string, target: string, sourceFileName?: string): TargetPaths;
|
|
27
|
+
export declare function resolveTargetWithSource(workspaceRoot: string, target: string): Promise<TargetPaths>;
|
|
27
28
|
export declare function ensureWorkspace(workspace: WorkspacePaths): Promise<void>;
|
|
28
29
|
export declare function ensureTargetDirs(target: TargetPaths): Promise<void>;
|
|
29
30
|
export declare function writeIfMissing(filePath: string, contents: string, force?: boolean): Promise<'written' | 'skipped'>;
|