@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.
Files changed (50) hide show
  1. package/README.md +25 -26
  2. package/dist/commands/compare-image-reference.d.ts +3 -0
  3. package/dist/commands/compare-image-reference.js +26 -3
  4. package/dist/commands/compare-image-reference.js.map +1 -1
  5. package/dist/commands/compare.d.ts +4 -1
  6. package/dist/commands/compare.js +72 -45
  7. package/dist/commands/compare.js.map +1 -1
  8. package/dist/core/agent-comparison-fingerprint.d.ts +12 -0
  9. package/dist/core/agent-comparison-fingerprint.js +27 -0
  10. package/dist/core/agent-comparison-fingerprint.js.map +1 -0
  11. package/dist/core/agent-comparison-pack.d.ts +30 -0
  12. package/dist/core/agent-comparison-pack.js +148 -0
  13. package/dist/core/agent-comparison-pack.js.map +1 -0
  14. package/dist/core/agent-comparison-profiles.d.ts +9 -0
  15. package/dist/core/agent-comparison-profiles.js +19 -0
  16. package/dist/core/agent-comparison-profiles.js.map +1 -0
  17. package/dist/core/agent-comparison-prompts.d.ts +22 -0
  18. package/dist/core/agent-comparison-prompts.js +84 -0
  19. package/dist/core/agent-comparison-prompts.js.map +1 -0
  20. package/dist/core/agent-comparison-report.d.ts +3 -0
  21. package/dist/core/agent-comparison-report.js +56 -0
  22. package/dist/core/agent-comparison-report.js.map +1 -0
  23. package/dist/core/agent-comparison-validation.d.ts +2 -0
  24. package/dist/core/agent-comparison-validation.js +8 -0
  25. package/dist/core/agent-comparison-validation.js.map +1 -0
  26. package/dist/core/playwright-capture.js +1 -1
  27. package/dist/core/playwright-capture.js.map +1 -1
  28. package/dist/core/report-writer.d.ts +7 -11
  29. package/dist/core/report-writer.js +20 -42
  30. package/dist/core/report-writer.js.map +1 -1
  31. package/dist/core/workspace.d.ts +1 -0
  32. package/dist/core/workspace.js +13 -2
  33. package/dist/core/workspace.js.map +1 -1
  34. package/dist/index.d.ts +4 -2
  35. package/dist/index.js +3 -2
  36. package/dist/index.js.map +1 -1
  37. package/dist/schemas/comparison.d.ts +349 -0
  38. package/dist/schemas/comparison.js +211 -0
  39. package/dist/schemas/comparison.js.map +1 -0
  40. package/dist/schemas/visual-spec.d.ts +8 -8
  41. package/dist/schemas/visual-spec.js +2 -2
  42. package/dist/schemas/visual-spec.js.map +1 -1
  43. package/docs/agent-workflow.md +18 -31
  44. package/docs/superpowers/plans/2026-06-12-agent-comparison-scores.md +209 -0
  45. package/package.json +1 -1
  46. package/skills/limner/SKILL.md +15 -18
  47. package/templates/target/AGENT_GUIDE.md +12 -8
  48. package/dist/commands/compare-image-app.d.ts +0 -12
  49. package/dist/commands/compare-image-app.js +0 -45
  50. package/dist/commands/compare-image-app.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises';
1
+ import { copyFile, mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  export function resolveWorkspace(root = process.cwd()) {
4
4
  const resolvedRoot = path.resolve(root);
@@ -42,6 +42,17 @@ export function resolveTarget(workspaceRoot, target, sourceFileName = 'ideal.png
42
42
  referenceCssPath: path.join(referenceDir, 'styles.css'),
43
43
  };
44
44
  }
45
+ export async function resolveTargetWithSource(workspaceRoot, target) {
46
+ const resolved = resolveTarget(workspaceRoot, target);
47
+ try {
48
+ const entries = await readdir(resolved.sourceDir);
49
+ const sourceFile = entries.find((entry) => /\.(avif|gif|jpe?g|png|svg|webp)$/i.test(entry));
50
+ return sourceFile ? resolveTarget(workspaceRoot, target, sourceFile) : resolved;
51
+ }
52
+ catch {
53
+ return resolved;
54
+ }
55
+ }
45
56
  export async function ensureWorkspace(workspace) {
46
57
  await mkdir(workspace.targetsDir, { recursive: true });
47
58
  await mkdir(workspace.runsDir, { recursive: true });
@@ -57,7 +68,7 @@ export async function ensureTargetDirs(target) {
57
68
  mkdir(target.contractDir, { recursive: true }),
58
69
  mkdir(path.join(target.referenceDir, 'assets'), { recursive: true }),
59
70
  mkdir(path.join(target.capturesDir, 'image-reference'), { recursive: true }),
60
- mkdir(path.join(target.capturesDir, 'reference-app'), { recursive: true }),
71
+ mkdir(path.join(target.capturesDir, 'reference-implementation'), { recursive: true }),
61
72
  mkdir(path.join(target.capturesDir, 'reference'), { recursive: true }),
62
73
  mkdir(target.reportsDir, { recursive: true }),
63
74
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/core/workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/core/workspace.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,11 +4,13 @@ export { limnerRunEventSchema, runManifestSchema } from './schemas/events.js';
4
4
  export type { LimnerRunEvent, RunManifest } from './schemas/events.js';
5
5
  export { visualSpecBundleSchema, visualSpecDiffSchema, visualSpecSchema, createVisualSpecBundleExample, createVisualSpecJsonSchema } from './schemas/visual-spec.js';
6
6
  export type { VisualSpec, VisualSpecBundle, VisualSpecDiff } from './schemas/visual-spec.js';
7
+ export { agentComparisonBundleSchema, imageComparisonSchema, structureComparisonSchema, createAgentComparisonBundleExample, createAgentComparisonJsonSchema, } from './schemas/comparison.js';
8
+ export type { AgentComparisonBundle, ImageComparison, StructureComparison } from './schemas/comparison.js';
7
9
  export { initTarget } from './commands/init.js';
8
10
  export { captureReference } from './commands/capture.js';
9
- export { compareImageReference, compareReferenceApp } from './commands/compare.js';
10
- export { compareImageApp } from './commands/compare-image-app.js';
11
+ export { compareImageReference, compareReferenceImplementation } from './commands/compare.js';
11
12
  export { createRunId, createRunLogger } from './core/run-logger.js';
12
13
  export { resolveWorkspace, validateTargetName } from './core/workspace.js';
13
14
  export { collectReferenceDomFacts } from './core/reference-dom-facts.js';
14
15
  export { writeImageReferenceSpecPack } from './core/visual-spec-agent-pack.js';
16
+ export { writeAgentComparisonPack } from './core/agent-comparison-pack.js';
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  export { limnerRegionCheckSchema, limnerRegionContractSchema, limnerRegionSchema, limnerTokensSchema, } from './schemas/contract.js';
2
2
  export { limnerRunEventSchema, runManifestSchema } from './schemas/events.js';
3
3
  export { visualSpecBundleSchema, visualSpecDiffSchema, visualSpecSchema, createVisualSpecBundleExample, createVisualSpecJsonSchema } from './schemas/visual-spec.js';
4
+ export { agentComparisonBundleSchema, imageComparisonSchema, structureComparisonSchema, createAgentComparisonBundleExample, createAgentComparisonJsonSchema, } from './schemas/comparison.js';
4
5
  export { initTarget } from './commands/init.js';
5
6
  export { captureReference } from './commands/capture.js';
6
- export { compareImageReference, compareReferenceApp } from './commands/compare.js';
7
- export { compareImageApp } from './commands/compare-image-app.js';
7
+ export { compareImageReference, compareReferenceImplementation } from './commands/compare.js';
8
8
  export { createRunId, createRunLogger } from './core/run-logger.js';
9
9
  export { resolveWorkspace, validateTargetName } from './core/workspace.js';
10
10
  export { collectReferenceDomFacts } from './core/reference-dom-facts.js';
11
11
  export { writeImageReferenceSpecPack } from './core/visual-spec-agent-pack.js';
12
+ export { writeAgentComparisonPack } from './core/agent-comparison-pack.js';
12
13
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAErK,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAErK,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,EACzB,kCAAkC,EAClC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC"}
@@ -0,0 +1,349 @@
1
+ import { z } from 'zod';
2
+ declare const inputFingerprintSchema: z.ZodObject<{
3
+ expectedImageSha256: z.ZodString;
4
+ actualImageSha256: z.ZodString;
5
+ expectedStructureSha256: z.ZodOptional<z.ZodString>;
6
+ actualStructureSha256: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>;
8
+ export declare const imageComparisonSchema: z.ZodObject<{
9
+ summary: z.ZodString;
10
+ score: z.ZodObject<{
11
+ overall: z.ZodNumber;
12
+ layout: z.ZodOptional<z.ZodNumber>;
13
+ hierarchy: z.ZodOptional<z.ZodNumber>;
14
+ typography: z.ZodOptional<z.ZodNumber>;
15
+ color: z.ZodOptional<z.ZodNumber>;
16
+ spacing: z.ZodOptional<z.ZodNumber>;
17
+ structure: z.ZodOptional<z.ZodNumber>;
18
+ semantics: z.ZodOptional<z.ZodNumber>;
19
+ }, z.core.$strip>;
20
+ confidence: z.ZodNumber;
21
+ majorDiffAreas: z.ZodArray<z.ZodObject<{
22
+ id: z.ZodString;
23
+ title: z.ZodString;
24
+ category: z.ZodEnum<{
25
+ typography: "typography";
26
+ spacing: "spacing";
27
+ color: "color";
28
+ layout: "layout";
29
+ hierarchy: "hierarchy";
30
+ "component-anatomy": "component-anatomy";
31
+ "copy-state": "copy-state";
32
+ "attention-flow": "attention-flow";
33
+ other: "other";
34
+ }>;
35
+ severity: z.ZodEnum<{
36
+ high: "high";
37
+ medium: "medium";
38
+ low: "low";
39
+ }>;
40
+ priority: z.ZodNumber;
41
+ expected: z.ZodString;
42
+ actual: z.ZodString;
43
+ impact: z.ZodString;
44
+ evidence: z.ZodArray<z.ZodObject<{
45
+ source: z.ZodString;
46
+ observation: z.ZodString;
47
+ }, z.core.$strip>>;
48
+ fixTarget: z.ZodOptional<z.ZodObject<{
49
+ surface: z.ZodEnum<{
50
+ unknown: "unknown";
51
+ mockup: "mockup";
52
+ implementation: "implementation";
53
+ }>;
54
+ region: z.ZodOptional<z.ZodString>;
55
+ likelyFiles: z.ZodDefault<z.ZodArray<z.ZodString>>;
56
+ selectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
57
+ }, z.core.$strip>>;
58
+ recommendedChange: z.ZodString;
59
+ }, z.core.$strip>>;
60
+ matches: z.ZodArray<z.ZodString>;
61
+ remarks: z.ZodObject<{
62
+ matches: z.ZodArray<z.ZodString>;
63
+ uncertainties: z.ZodDefault<z.ZodArray<z.ZodString>>;
64
+ possibleIntentionalDeviations: z.ZodDefault<z.ZodArray<z.ZodString>>;
65
+ }, z.core.$strip>;
66
+ systemFeedback: z.ZodObject<{
67
+ inputQuality: z.ZodArray<z.ZodString>;
68
+ missingContext: z.ZodDefault<z.ZodArray<z.ZodString>>;
69
+ suggestedLimnerImprovements: z.ZodDefault<z.ZodArray<z.ZodString>>;
70
+ }, z.core.$strip>;
71
+ nextIteration: z.ZodObject<{
72
+ focus: z.ZodString;
73
+ steps: z.ZodArray<z.ZodString>;
74
+ avoidForNow: z.ZodDefault<z.ZodArray<z.ZodString>>;
75
+ expectedImprovement: z.ZodOptional<z.ZodString>;
76
+ }, z.core.$strip>;
77
+ rationale: z.ZodString;
78
+ kind: z.ZodLiteral<"image-vs-image">;
79
+ inputs: z.ZodObject<{
80
+ expectedImagePath: z.ZodString;
81
+ actualImagePath: z.ZodString;
82
+ }, z.core.$strip>;
83
+ }, z.core.$strip>;
84
+ export declare const structureComparisonSchema: z.ZodObject<{
85
+ summary: z.ZodString;
86
+ score: z.ZodObject<{
87
+ overall: z.ZodNumber;
88
+ layout: z.ZodOptional<z.ZodNumber>;
89
+ hierarchy: z.ZodOptional<z.ZodNumber>;
90
+ typography: z.ZodOptional<z.ZodNumber>;
91
+ color: z.ZodOptional<z.ZodNumber>;
92
+ spacing: z.ZodOptional<z.ZodNumber>;
93
+ structure: z.ZodOptional<z.ZodNumber>;
94
+ semantics: z.ZodOptional<z.ZodNumber>;
95
+ }, z.core.$strip>;
96
+ confidence: z.ZodNumber;
97
+ majorDiffAreas: z.ZodArray<z.ZodObject<{
98
+ id: z.ZodString;
99
+ title: z.ZodString;
100
+ category: z.ZodEnum<{
101
+ typography: "typography";
102
+ spacing: "spacing";
103
+ color: "color";
104
+ layout: "layout";
105
+ hierarchy: "hierarchy";
106
+ "component-anatomy": "component-anatomy";
107
+ "copy-state": "copy-state";
108
+ "attention-flow": "attention-flow";
109
+ other: "other";
110
+ }>;
111
+ severity: z.ZodEnum<{
112
+ high: "high";
113
+ medium: "medium";
114
+ low: "low";
115
+ }>;
116
+ priority: z.ZodNumber;
117
+ expected: z.ZodString;
118
+ actual: z.ZodString;
119
+ impact: z.ZodString;
120
+ evidence: z.ZodArray<z.ZodObject<{
121
+ source: z.ZodString;
122
+ observation: z.ZodString;
123
+ }, z.core.$strip>>;
124
+ fixTarget: z.ZodOptional<z.ZodObject<{
125
+ surface: z.ZodEnum<{
126
+ unknown: "unknown";
127
+ mockup: "mockup";
128
+ implementation: "implementation";
129
+ }>;
130
+ region: z.ZodOptional<z.ZodString>;
131
+ likelyFiles: z.ZodDefault<z.ZodArray<z.ZodString>>;
132
+ selectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
133
+ }, z.core.$strip>>;
134
+ recommendedChange: z.ZodString;
135
+ }, z.core.$strip>>;
136
+ matches: z.ZodArray<z.ZodString>;
137
+ remarks: z.ZodObject<{
138
+ matches: z.ZodArray<z.ZodString>;
139
+ uncertainties: z.ZodDefault<z.ZodArray<z.ZodString>>;
140
+ possibleIntentionalDeviations: z.ZodDefault<z.ZodArray<z.ZodString>>;
141
+ }, z.core.$strip>;
142
+ systemFeedback: z.ZodObject<{
143
+ inputQuality: z.ZodArray<z.ZodString>;
144
+ missingContext: z.ZodDefault<z.ZodArray<z.ZodString>>;
145
+ suggestedLimnerImprovements: z.ZodDefault<z.ZodArray<z.ZodString>>;
146
+ }, z.core.$strip>;
147
+ nextIteration: z.ZodObject<{
148
+ focus: z.ZodString;
149
+ steps: z.ZodArray<z.ZodString>;
150
+ avoidForNow: z.ZodDefault<z.ZodArray<z.ZodString>>;
151
+ expectedImprovement: z.ZodOptional<z.ZodString>;
152
+ }, z.core.$strip>;
153
+ rationale: z.ZodString;
154
+ kind: z.ZodLiteral<"structure-vs-structure">;
155
+ inputs: z.ZodObject<{
156
+ expectedStructurePath: z.ZodString;
157
+ actualStructurePath: z.ZodString;
158
+ structureKind: z.ZodEnum<{
159
+ "dom-metrics": "dom-metrics";
160
+ "visual-spec": "visual-spec";
161
+ html: "html";
162
+ "json-description": "json-description";
163
+ }>;
164
+ }, z.core.$strip>;
165
+ }, z.core.$strip>;
166
+ export declare const agentComparisonBundleSchema: z.ZodObject<{
167
+ version: z.ZodLiteral<1>;
168
+ generatedBy: z.ZodLiteral<"agent">;
169
+ profile: z.ZodEnum<{
170
+ "ideal-to-mockup": "ideal-to-mockup";
171
+ "mockup-to-implementation": "mockup-to-implementation";
172
+ }>;
173
+ inputFingerprint: z.ZodObject<{
174
+ expectedImageSha256: z.ZodString;
175
+ actualImageSha256: z.ZodString;
176
+ expectedStructureSha256: z.ZodOptional<z.ZodString>;
177
+ actualStructureSha256: z.ZodOptional<z.ZodString>;
178
+ }, z.core.$strip>;
179
+ imageComparison: z.ZodObject<{
180
+ summary: z.ZodString;
181
+ score: z.ZodObject<{
182
+ overall: z.ZodNumber;
183
+ layout: z.ZodOptional<z.ZodNumber>;
184
+ hierarchy: z.ZodOptional<z.ZodNumber>;
185
+ typography: z.ZodOptional<z.ZodNumber>;
186
+ color: z.ZodOptional<z.ZodNumber>;
187
+ spacing: z.ZodOptional<z.ZodNumber>;
188
+ structure: z.ZodOptional<z.ZodNumber>;
189
+ semantics: z.ZodOptional<z.ZodNumber>;
190
+ }, z.core.$strip>;
191
+ confidence: z.ZodNumber;
192
+ majorDiffAreas: z.ZodArray<z.ZodObject<{
193
+ id: z.ZodString;
194
+ title: z.ZodString;
195
+ category: z.ZodEnum<{
196
+ typography: "typography";
197
+ spacing: "spacing";
198
+ color: "color";
199
+ layout: "layout";
200
+ hierarchy: "hierarchy";
201
+ "component-anatomy": "component-anatomy";
202
+ "copy-state": "copy-state";
203
+ "attention-flow": "attention-flow";
204
+ other: "other";
205
+ }>;
206
+ severity: z.ZodEnum<{
207
+ high: "high";
208
+ medium: "medium";
209
+ low: "low";
210
+ }>;
211
+ priority: z.ZodNumber;
212
+ expected: z.ZodString;
213
+ actual: z.ZodString;
214
+ impact: z.ZodString;
215
+ evidence: z.ZodArray<z.ZodObject<{
216
+ source: z.ZodString;
217
+ observation: z.ZodString;
218
+ }, z.core.$strip>>;
219
+ fixTarget: z.ZodOptional<z.ZodObject<{
220
+ surface: z.ZodEnum<{
221
+ unknown: "unknown";
222
+ mockup: "mockup";
223
+ implementation: "implementation";
224
+ }>;
225
+ region: z.ZodOptional<z.ZodString>;
226
+ likelyFiles: z.ZodDefault<z.ZodArray<z.ZodString>>;
227
+ selectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
228
+ }, z.core.$strip>>;
229
+ recommendedChange: z.ZodString;
230
+ }, z.core.$strip>>;
231
+ matches: z.ZodArray<z.ZodString>;
232
+ remarks: z.ZodObject<{
233
+ matches: z.ZodArray<z.ZodString>;
234
+ uncertainties: z.ZodDefault<z.ZodArray<z.ZodString>>;
235
+ possibleIntentionalDeviations: z.ZodDefault<z.ZodArray<z.ZodString>>;
236
+ }, z.core.$strip>;
237
+ systemFeedback: z.ZodObject<{
238
+ inputQuality: z.ZodArray<z.ZodString>;
239
+ missingContext: z.ZodDefault<z.ZodArray<z.ZodString>>;
240
+ suggestedLimnerImprovements: z.ZodDefault<z.ZodArray<z.ZodString>>;
241
+ }, z.core.$strip>;
242
+ nextIteration: z.ZodObject<{
243
+ focus: z.ZodString;
244
+ steps: z.ZodArray<z.ZodString>;
245
+ avoidForNow: z.ZodDefault<z.ZodArray<z.ZodString>>;
246
+ expectedImprovement: z.ZodOptional<z.ZodString>;
247
+ }, z.core.$strip>;
248
+ rationale: z.ZodString;
249
+ kind: z.ZodLiteral<"image-vs-image">;
250
+ inputs: z.ZodObject<{
251
+ expectedImagePath: z.ZodString;
252
+ actualImagePath: z.ZodString;
253
+ }, z.core.$strip>;
254
+ }, z.core.$strip>;
255
+ structureComparison: z.ZodOptional<z.ZodObject<{
256
+ summary: z.ZodString;
257
+ score: z.ZodObject<{
258
+ overall: z.ZodNumber;
259
+ layout: z.ZodOptional<z.ZodNumber>;
260
+ hierarchy: z.ZodOptional<z.ZodNumber>;
261
+ typography: z.ZodOptional<z.ZodNumber>;
262
+ color: z.ZodOptional<z.ZodNumber>;
263
+ spacing: z.ZodOptional<z.ZodNumber>;
264
+ structure: z.ZodOptional<z.ZodNumber>;
265
+ semantics: z.ZodOptional<z.ZodNumber>;
266
+ }, z.core.$strip>;
267
+ confidence: z.ZodNumber;
268
+ majorDiffAreas: z.ZodArray<z.ZodObject<{
269
+ id: z.ZodString;
270
+ title: z.ZodString;
271
+ category: z.ZodEnum<{
272
+ typography: "typography";
273
+ spacing: "spacing";
274
+ color: "color";
275
+ layout: "layout";
276
+ hierarchy: "hierarchy";
277
+ "component-anatomy": "component-anatomy";
278
+ "copy-state": "copy-state";
279
+ "attention-flow": "attention-flow";
280
+ other: "other";
281
+ }>;
282
+ severity: z.ZodEnum<{
283
+ high: "high";
284
+ medium: "medium";
285
+ low: "low";
286
+ }>;
287
+ priority: z.ZodNumber;
288
+ expected: z.ZodString;
289
+ actual: z.ZodString;
290
+ impact: z.ZodString;
291
+ evidence: z.ZodArray<z.ZodObject<{
292
+ source: z.ZodString;
293
+ observation: z.ZodString;
294
+ }, z.core.$strip>>;
295
+ fixTarget: z.ZodOptional<z.ZodObject<{
296
+ surface: z.ZodEnum<{
297
+ unknown: "unknown";
298
+ mockup: "mockup";
299
+ implementation: "implementation";
300
+ }>;
301
+ region: z.ZodOptional<z.ZodString>;
302
+ likelyFiles: z.ZodDefault<z.ZodArray<z.ZodString>>;
303
+ selectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
304
+ }, z.core.$strip>>;
305
+ recommendedChange: z.ZodString;
306
+ }, z.core.$strip>>;
307
+ matches: z.ZodArray<z.ZodString>;
308
+ remarks: z.ZodObject<{
309
+ matches: z.ZodArray<z.ZodString>;
310
+ uncertainties: z.ZodDefault<z.ZodArray<z.ZodString>>;
311
+ possibleIntentionalDeviations: z.ZodDefault<z.ZodArray<z.ZodString>>;
312
+ }, z.core.$strip>;
313
+ systemFeedback: z.ZodObject<{
314
+ inputQuality: z.ZodArray<z.ZodString>;
315
+ missingContext: z.ZodDefault<z.ZodArray<z.ZodString>>;
316
+ suggestedLimnerImprovements: z.ZodDefault<z.ZodArray<z.ZodString>>;
317
+ }, z.core.$strip>;
318
+ nextIteration: z.ZodObject<{
319
+ focus: z.ZodString;
320
+ steps: z.ZodArray<z.ZodString>;
321
+ avoidForNow: z.ZodDefault<z.ZodArray<z.ZodString>>;
322
+ expectedImprovement: z.ZodOptional<z.ZodString>;
323
+ }, z.core.$strip>;
324
+ rationale: z.ZodString;
325
+ kind: z.ZodLiteral<"structure-vs-structure">;
326
+ inputs: z.ZodObject<{
327
+ expectedStructurePath: z.ZodString;
328
+ actualStructurePath: z.ZodString;
329
+ structureKind: z.ZodEnum<{
330
+ "dom-metrics": "dom-metrics";
331
+ "visual-spec": "visual-spec";
332
+ html: "html";
333
+ "json-description": "json-description";
334
+ }>;
335
+ }, z.core.$strip>;
336
+ }, z.core.$strip>>;
337
+ recommendation: z.ZodDefault<z.ZodObject<{
338
+ topFix: z.ZodOptional<z.ZodString>;
339
+ why: z.ZodOptional<z.ZodString>;
340
+ expectedScoreLift: z.ZodOptional<z.ZodNumber>;
341
+ }, z.core.$strip>>;
342
+ }, z.core.$strip>;
343
+ export type ImageComparison = z.infer<typeof imageComparisonSchema>;
344
+ export type StructureComparison = z.infer<typeof structureComparisonSchema>;
345
+ export type AgentComparisonBundle = z.infer<typeof agentComparisonBundleSchema>;
346
+ export type AgentComparisonInputFingerprint = z.infer<typeof inputFingerprintSchema>;
347
+ export declare function createAgentComparisonBundleExample(mode: 'image-only' | 'image-and-structure', inputFingerprint?: AgentComparisonInputFingerprint): AgentComparisonBundle;
348
+ export declare function createAgentComparisonJsonSchema(mode?: 'any' | 'image-only' | 'image-and-structure'): unknown;
349
+ export {};
@@ -0,0 +1,211 @@
1
+ import { z } from 'zod';
2
+ const score01Schema = z.number().min(0).max(1);
3
+ const comparisonScoreSchema = z.object({
4
+ overall: score01Schema,
5
+ layout: score01Schema.optional(),
6
+ hierarchy: score01Schema.optional(),
7
+ typography: score01Schema.optional(),
8
+ color: score01Schema.optional(),
9
+ spacing: score01Schema.optional(),
10
+ structure: score01Schema.optional(),
11
+ semantics: score01Schema.optional(),
12
+ });
13
+ const hashSchema = z.string().regex(/^[a-f0-9]{64}$/);
14
+ const inputFingerprintSchema = z.object({
15
+ expectedImageSha256: hashSchema,
16
+ actualImageSha256: hashSchema,
17
+ expectedStructureSha256: hashSchema.optional(),
18
+ actualStructureSha256: hashSchema.optional(),
19
+ });
20
+ const evidenceSchema = z.object({
21
+ source: z.string().min(1),
22
+ observation: z.string().min(1),
23
+ });
24
+ const fixTargetSchema = z.object({
25
+ surface: z.enum(['mockup', 'implementation', 'unknown']),
26
+ region: z.string().min(1).optional(),
27
+ likelyFiles: z.array(z.string()).default([]),
28
+ selectors: z.array(z.string()).default([]),
29
+ });
30
+ const diffAreaSchema = z.object({
31
+ id: z.string().min(1),
32
+ title: z.string().min(1),
33
+ category: z.enum(['layout', 'hierarchy', 'typography', 'color', 'spacing', 'component-anatomy', 'copy-state', 'attention-flow', 'other']),
34
+ severity: z.enum(['high', 'medium', 'low']),
35
+ priority: z.number().int().positive(),
36
+ expected: z.string().min(1),
37
+ actual: z.string().min(1),
38
+ impact: z.string().min(1),
39
+ evidence: z.array(evidenceSchema).min(1),
40
+ fixTarget: fixTargetSchema.optional(),
41
+ recommendedChange: z.string().min(1),
42
+ });
43
+ const nextIterationSchema = z.object({
44
+ focus: z.string().min(1),
45
+ steps: z.array(z.string()),
46
+ avoidForNow: z.array(z.string()).default([]),
47
+ expectedImprovement: z.string().min(1).optional(),
48
+ });
49
+ const remarksSchema = z.object({
50
+ matches: z.array(z.string()),
51
+ uncertainties: z.array(z.string()).default([]),
52
+ possibleIntentionalDeviations: z.array(z.string()).default([]),
53
+ });
54
+ const systemFeedbackSchema = z.object({
55
+ inputQuality: z.array(z.string()),
56
+ missingContext: z.array(z.string()).default([]),
57
+ suggestedLimnerImprovements: z.array(z.string()).default([]),
58
+ });
59
+ const baseComparisonSchema = z.object({
60
+ summary: z.string().min(1),
61
+ score: comparisonScoreSchema,
62
+ confidence: score01Schema,
63
+ majorDiffAreas: z.array(diffAreaSchema),
64
+ matches: z.array(z.string()),
65
+ remarks: remarksSchema,
66
+ systemFeedback: systemFeedbackSchema,
67
+ nextIteration: nextIterationSchema,
68
+ rationale: z.string().min(1),
69
+ });
70
+ export const imageComparisonSchema = baseComparisonSchema.extend({
71
+ kind: z.literal('image-vs-image'),
72
+ inputs: z.object({
73
+ expectedImagePath: z.string().min(1),
74
+ actualImagePath: z.string().min(1),
75
+ }),
76
+ });
77
+ export const structureComparisonSchema = baseComparisonSchema.extend({
78
+ kind: z.literal('structure-vs-structure'),
79
+ inputs: z.object({
80
+ expectedStructurePath: z.string().min(1),
81
+ actualStructurePath: z.string().min(1),
82
+ structureKind: z.enum(['visual-spec', 'dom-metrics', 'html', 'json-description']),
83
+ }),
84
+ });
85
+ export const agentComparisonBundleSchema = z.object({
86
+ version: z.literal(1),
87
+ generatedBy: z.literal('agent'),
88
+ profile: z.enum(['ideal-to-mockup', 'mockup-to-implementation']),
89
+ inputFingerprint: inputFingerprintSchema,
90
+ imageComparison: imageComparisonSchema,
91
+ structureComparison: structureComparisonSchema.optional(),
92
+ recommendation: z.object({
93
+ topFix: z.string().min(1).optional(),
94
+ why: z.string().min(1).optional(),
95
+ expectedScoreLift: score01Schema.optional(),
96
+ }).default({}),
97
+ });
98
+ export function createAgentComparisonBundleExample(mode, inputFingerprint = exampleFingerprint(mode)) {
99
+ const imageComparison = {
100
+ kind: 'image-vs-image',
101
+ inputs: {
102
+ expectedImagePath: 'targets/demo/source/ideal.png',
103
+ actualImagePath: 'targets/demo/captures/image-reference/reference.png',
104
+ },
105
+ summary: 'The screens preserve the same overall layout, with hierarchy and typography drift.',
106
+ score: { overall: 0.82, layout: 0.9, hierarchy: 0.74, typography: 0.76, color: 0.85, spacing: 0.8 },
107
+ confidence: 0.78,
108
+ majorDiffAreas: [exampleDiff('hero-heading', 'Hero heading lacks visual dominance', 'mockup')],
109
+ matches: ['Primary content appears in the same broad region.'],
110
+ remarks: {
111
+ matches: ['Overall single-column composition is similar.'],
112
+ uncertainties: ['Exact font family cannot be determined from screenshots alone.'],
113
+ possibleIntentionalDeviations: [],
114
+ },
115
+ systemFeedback: {
116
+ inputQuality: ['Both screenshots are readable and appear to use the same viewport.'],
117
+ missingContext: [],
118
+ suggestedLimnerImprovements: ['Include computed font metrics for the hero region when available.'],
119
+ },
120
+ nextIteration: {
121
+ focus: 'Tune the hero heading size, weight, and contrast.',
122
+ steps: ['Increase heading font size by one scale step.', 'Use a heavier font weight.'],
123
+ avoidForNow: ['Do not spend the next iteration on tiny border-radius differences.'],
124
+ expectedImprovement: 'This should improve hierarchy more than small spacing changes.',
125
+ },
126
+ rationale: 'The composition is close, but visual priority differs enough to warrant another iteration.',
127
+ };
128
+ if (mode === 'image-only') {
129
+ return { version: 1, generatedBy: 'agent', profile: 'ideal-to-mockup', inputFingerprint, imageComparison, recommendation: {} };
130
+ }
131
+ imageComparison.inputs = {
132
+ expectedImagePath: 'targets/demo/captures/reference-implementation/reference.png',
133
+ actualImagePath: 'targets/demo/captures/reference-implementation/implementation.png',
134
+ };
135
+ imageComparison.summary = 'The implementation preserves the mockup layout, with hierarchy and typography drift.';
136
+ imageComparison.majorDiffAreas = [exampleDiff('hero-heading', 'Hero heading lacks visual dominance', 'implementation')];
137
+ imageComparison.nextIteration = {
138
+ focus: 'Tune the implementation hero heading size, weight, and contrast.',
139
+ steps: ['Increase implementation heading font size by one scale step.', 'Use a heavier font weight.'],
140
+ avoidForNow: ['Do not spend the next iteration on tiny border-radius differences.'],
141
+ expectedImprovement: 'This should improve implementation hierarchy more than small spacing changes.',
142
+ };
143
+ return {
144
+ version: 1,
145
+ generatedBy: 'agent',
146
+ profile: 'mockup-to-implementation',
147
+ inputFingerprint,
148
+ imageComparison,
149
+ structureComparison: {
150
+ kind: 'structure-vs-structure',
151
+ inputs: {
152
+ expectedStructurePath: 'targets/demo/captures/reference-implementation/reference.png.metrics.json',
153
+ actualStructurePath: 'targets/demo/captures/reference-implementation/implementation.png.metrics.json',
154
+ structureKind: 'dom-metrics',
155
+ },
156
+ summary: 'The region structure is mostly preserved, but the heading style differs.',
157
+ score: { overall: 0.86, structure: 0.92, typography: 0.72, color: 0.84, semantics: 0.9 },
158
+ confidence: 0.82,
159
+ majorDiffAreas: [exampleDiff('heading-weight', 'Heading weight differs in computed metrics', 'implementation')],
160
+ matches: ['Both structures include the main content and CTA regions.'],
161
+ remarks: { matches: ['Major regions are present.'], uncertainties: [], possibleIntentionalDeviations: [] },
162
+ systemFeedback: { inputQuality: ['DOM metrics were available for both sides.'], missingContext: [], suggestedLimnerImprovements: [] },
163
+ nextIteration: { focus: 'Align implementation heading typography.', steps: ['Increase implementation heading font weight.'], avoidForNow: [] },
164
+ rationale: 'The structure matches well, but computed typography still diverges.',
165
+ },
166
+ recommendation: {
167
+ topFix: 'Tune the hero heading typography.',
168
+ why: 'Both visual and structural comparisons identify this as the highest-impact mismatch.',
169
+ expectedScoreLift: 0.06,
170
+ },
171
+ };
172
+ }
173
+ export function createAgentComparisonJsonSchema(mode = 'any') {
174
+ const schema = z.toJSONSchema(agentComparisonBundleSchema);
175
+ if (mode === 'image-and-structure') {
176
+ schema.required = [...new Set([...(schema.required ?? []), 'structureComparison'])];
177
+ }
178
+ if (mode === 'image-only') {
179
+ schema.not = { required: ['structureComparison'] };
180
+ }
181
+ return schema;
182
+ }
183
+ function exampleDiff(id, title, surface) {
184
+ return {
185
+ id,
186
+ title,
187
+ category: 'typography',
188
+ severity: 'medium',
189
+ priority: 1,
190
+ expected: 'Large, bold, visually dominant heading.',
191
+ actual: 'Slightly smaller heading with weaker emphasis.',
192
+ impact: 'The primary hierarchy is less forceful.',
193
+ evidence: [{ source: 'expected-image', observation: 'Heading is the strongest element in the upper content region.' }],
194
+ fixTarget: { surface, region: 'hero', likelyFiles: [], selectors: [] },
195
+ recommendedChange: 'Increase heading size and weight, then compare again.',
196
+ };
197
+ }
198
+ function exampleFingerprint(mode) {
199
+ const image = {
200
+ expectedImageSha256: '0'.repeat(64),
201
+ actualImageSha256: '1'.repeat(64),
202
+ };
203
+ if (mode === 'image-only')
204
+ return image;
205
+ return {
206
+ ...image,
207
+ expectedStructureSha256: '2'.repeat(64),
208
+ actualStructureSha256: '3'.repeat(64),
209
+ };
210
+ }
211
+ //# sourceMappingURL=comparison.js.map