@neonwatty/limner 0.1.0
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 +161 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/capture.d.ts +12 -0
- package/dist/commands/capture.js +66 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/compare-image-app.d.ts +12 -0
- package/dist/commands/compare-image-app.js +45 -0
- package/dist/commands/compare-image-app.js.map +1 -0
- package/dist/commands/compare-image-reference.d.ts +28 -0
- package/dist/commands/compare-image-reference.js +82 -0
- package/dist/commands/compare-image-reference.js.map +1 -0
- package/dist/commands/compare.d.ts +15 -0
- package/dist/commands/compare.js +168 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.js +65 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/preview.d.ts +2 -0
- package/dist/commands/preview.js +27 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/report.d.ts +2 -0
- package/dist/commands/report.js +14 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/runs.d.ts +2 -0
- package/dist/commands/runs.js +63 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/core/dom-metrics.d.ts +18 -0
- package/dist/core/dom-metrics.js +54 -0
- package/dist/core/dom-metrics.js.map +1 -0
- package/dist/core/playwright-capture.d.ts +27 -0
- package/dist/core/playwright-capture.js +46 -0
- package/dist/core/playwright-capture.js.map +1 -0
- package/dist/core/playwright-dom.d.ts +16 -0
- package/dist/core/playwright-dom.js +64 -0
- package/dist/core/playwright-dom.js.map +1 -0
- package/dist/core/reference-dom-facts.d.ts +65 -0
- package/dist/core/reference-dom-facts.js +71 -0
- package/dist/core/reference-dom-facts.js.map +1 -0
- package/dist/core/report-writer.d.ts +43 -0
- package/dist/core/report-writer.js +181 -0
- package/dist/core/report-writer.js.map +1 -0
- package/dist/core/run-logger.d.ts +22 -0
- package/dist/core/run-logger.js +67 -0
- package/dist/core/run-logger.js.map +1 -0
- package/dist/core/side-by-side.d.ts +8 -0
- package/dist/core/side-by-side.js +33 -0
- package/dist/core/side-by-side.js.map +1 -0
- package/dist/core/static-server.d.ts +6 -0
- package/dist/core/static-server.js +73 -0
- package/dist/core/static-server.js.map +1 -0
- package/dist/core/visual-spec-agent-pack.d.ts +27 -0
- package/dist/core/visual-spec-agent-pack.js +143 -0
- package/dist/core/visual-spec-agent-pack.js.map +1 -0
- package/dist/core/visual-spec-prompts.d.ts +32 -0
- package/dist/core/visual-spec-prompts.js +129 -0
- package/dist/core/visual-spec-prompts.js.map +1 -0
- package/dist/core/workspace.d.ts +31 -0
- package/dist/core/workspace.js +97 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/contract.d.ts +43 -0
- package/dist/schemas/contract.js +19 -0
- package/dist/schemas/contract.js.map +1 -0
- package/dist/schemas/events.d.ts +34 -0
- package/dist/schemas/events.js +29 -0
- package/dist/schemas/events.js.map +1 -0
- package/dist/schemas/visual-spec.d.ts +410 -0
- package/dist/schemas/visual-spec.js +201 -0
- package/dist/schemas/visual-spec.js.map +1 -0
- package/docs/agent-workflow.md +45 -0
- package/package.json +64 -0
- package/skills/limner/SKILL.md +51 -0
- package/templates/target/AGENT_GUIDE.md +24 -0
- package/templates/target/contract/acceptance.md +23 -0
- package/templates/target/contract/regions.json +11 -0
- package/templates/target/contract/tokens.json +21 -0
- package/templates/target/reference/index.html +22 -0
- package/templates/target/reference/styles.css +53 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TargetPaths } from './workspace.js';
|
|
2
|
+
export declare function buildSharedPrompt(input: {
|
|
3
|
+
target: TargetPaths;
|
|
4
|
+
referencePath: string;
|
|
5
|
+
sideBySidePath: string;
|
|
6
|
+
factsPath: string;
|
|
7
|
+
examplePath: string;
|
|
8
|
+
schemaPath: string;
|
|
9
|
+
responsePath: string;
|
|
10
|
+
instructionsPath: string;
|
|
11
|
+
customInstructions: string;
|
|
12
|
+
}): string;
|
|
13
|
+
export declare function buildCodexPrompt(input: {
|
|
14
|
+
target: TargetPaths;
|
|
15
|
+
promptPath: string;
|
|
16
|
+
referencePath: string;
|
|
17
|
+
sideBySidePath: string;
|
|
18
|
+
factsPath: string;
|
|
19
|
+
schemaPath: string;
|
|
20
|
+
responsePath: string;
|
|
21
|
+
instructionsPath: string;
|
|
22
|
+
}): string;
|
|
23
|
+
export declare function buildClaudePrompt(input: {
|
|
24
|
+
target: TargetPaths;
|
|
25
|
+
promptPath: string;
|
|
26
|
+
referencePath: string;
|
|
27
|
+
sideBySidePath: string;
|
|
28
|
+
factsPath: string;
|
|
29
|
+
schemaPath: string;
|
|
30
|
+
responsePath: string;
|
|
31
|
+
instructionsPath: string;
|
|
32
|
+
}): string;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
export function buildSharedPrompt(input) {
|
|
3
|
+
const rel = relativeToWorkspace(input.target);
|
|
4
|
+
return `# Visual Spec Extraction Prompt
|
|
5
|
+
|
|
6
|
+
This workflow requires an agent with image access. Limner does not auto-extract the spec.
|
|
7
|
+
|
|
8
|
+
## Goal
|
|
9
|
+
|
|
10
|
+
Inspect the ideal image and the rendered reference, then write a structured JSON response to:
|
|
11
|
+
|
|
12
|
+
\`${rel(input.responsePath)}\`
|
|
13
|
+
|
|
14
|
+
Match the structure shown in:
|
|
15
|
+
|
|
16
|
+
\`${rel(input.examplePath)}\`
|
|
17
|
+
|
|
18
|
+
Validate against:
|
|
19
|
+
|
|
20
|
+
\`${rel(input.schemaPath)}\`
|
|
21
|
+
|
|
22
|
+
## Required Inputs
|
|
23
|
+
|
|
24
|
+
- Ideal image: \`${rel(input.target.sourceImagePath)}\`
|
|
25
|
+
- Reference screenshot: \`${rel(input.referencePath)}\`
|
|
26
|
+
- Side-by-side: \`${rel(input.sideBySidePath)}\`
|
|
27
|
+
- Reference HTML: \`${rel(input.target.referenceHtmlPath)}\`
|
|
28
|
+
- Reference CSS: \`${rel(input.target.referenceCssPath)}\`
|
|
29
|
+
- Tokens: \`${rel(input.target.tokensPath)}\`
|
|
30
|
+
- Acceptance notes: \`${rel(input.target.acceptancePath)}\`
|
|
31
|
+
- DOM facts: \`${rel(input.factsPath)}\`
|
|
32
|
+
- JSON schema: \`${rel(input.schemaPath)}\`
|
|
33
|
+
- Custom instructions: \`${rel(input.instructionsPath)}\`
|
|
34
|
+
|
|
35
|
+
## Requirements
|
|
36
|
+
|
|
37
|
+
- Treat the separate ideal image and separate reference screenshot as primary visual evidence.
|
|
38
|
+
- Use the side-by-side image only as comparison context, not as a source for region bounds or image dimensions.
|
|
39
|
+
- Use the DOM facts only to support the reference-html spec.
|
|
40
|
+
- Do not use placeholders like "TODO" in the final response.
|
|
41
|
+
- Fill all narrative fields with concrete observations.
|
|
42
|
+
- Keep idealSpec.source as \`ideal-image\`.
|
|
43
|
+
- Keep referenceSpec.source as \`reference-html\`.
|
|
44
|
+
- Diff findings should focus on meaningful structural, typographic, or state mismatches.
|
|
45
|
+
|
|
46
|
+
## Custom Instructions
|
|
47
|
+
|
|
48
|
+
${input.customInstructions.trim() || 'No custom instructions supplied.'}
|
|
49
|
+
|
|
50
|
+
## Expected Output
|
|
51
|
+
|
|
52
|
+
Return one JSON object with:
|
|
53
|
+
|
|
54
|
+
- \`version\`
|
|
55
|
+
- \`generatedBy\`
|
|
56
|
+
- \`idealSpec\`
|
|
57
|
+
- \`referenceSpec\`
|
|
58
|
+
- \`diff\`
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
export function buildCodexPrompt(input) {
|
|
62
|
+
const rel = relativeToWorkspace(input.target);
|
|
63
|
+
return `# Codex Visual Spec Prompt
|
|
64
|
+
|
|
65
|
+
Use Codex when you want the agent to read local files and write the response directly into the workspace.
|
|
66
|
+
|
|
67
|
+
## Codex Instructions
|
|
68
|
+
|
|
69
|
+
1. Inspect these local artifacts:
|
|
70
|
+
- \`${rel(input.target.sourceImagePath)}\`
|
|
71
|
+
- \`${rel(input.referencePath)}\`
|
|
72
|
+
- \`${rel(input.sideBySidePath)}\`
|
|
73
|
+
- \`${rel(input.target.referenceHtmlPath)}\`
|
|
74
|
+
- \`${rel(input.target.referenceCssPath)}\`
|
|
75
|
+
- \`${rel(input.factsPath)}\`
|
|
76
|
+
- \`${rel(input.schemaPath)}\`
|
|
77
|
+
- \`${rel(input.instructionsPath)}\`
|
|
78
|
+
2. Produce one JSON object that conforms to the schema.
|
|
79
|
+
3. Write that JSON to:
|
|
80
|
+
- \`${rel(input.responsePath)}\`
|
|
81
|
+
4. Rerun:
|
|
82
|
+
- \`limn compare image-reference --target ${input.target.name} --spec\`
|
|
83
|
+
|
|
84
|
+
## Notes
|
|
85
|
+
|
|
86
|
+
- Do not return prose instead of JSON.
|
|
87
|
+
- Inspect the ideal image and reference screenshot separately before looking at the side-by-side.
|
|
88
|
+
- Use the side-by-side only as comparison context, not as the image to parse.
|
|
89
|
+
- Use DOM facts only to support the reference-html side, not to infer the ideal-image side.
|
|
90
|
+
- Start from the shared instructions in \`${rel(input.promptPath)}\`.
|
|
91
|
+
`;
|
|
92
|
+
}
|
|
93
|
+
export function buildClaudePrompt(input) {
|
|
94
|
+
const rel = relativeToWorkspace(input.target);
|
|
95
|
+
return `# Claude Visual Spec Prompt
|
|
96
|
+
|
|
97
|
+
Use Claude when you want a multimodal agent to compare the ideal image and the rendered reference with strict structured output.
|
|
98
|
+
|
|
99
|
+
## Claude Instructions
|
|
100
|
+
|
|
101
|
+
1. Attach these images when prompting Claude:
|
|
102
|
+
- \`${rel(input.target.sourceImagePath)}\`
|
|
103
|
+
- \`${rel(input.referencePath)}\`
|
|
104
|
+
- \`${rel(input.sideBySidePath)}\`
|
|
105
|
+
2. Also provide these text files:
|
|
106
|
+
- \`${rel(input.target.referenceHtmlPath)}\`
|
|
107
|
+
- \`${rel(input.target.referenceCssPath)}\`
|
|
108
|
+
- \`${rel(input.factsPath)}\`
|
|
109
|
+
- \`${rel(input.schemaPath)}\`
|
|
110
|
+
- \`${rel(input.instructionsPath)}\`
|
|
111
|
+
3. Ask Claude to return JSON matching the schema exactly.
|
|
112
|
+
4. Save Claude's JSON response to:
|
|
113
|
+
- \`${rel(input.responsePath)}\`
|
|
114
|
+
5. Rerun:
|
|
115
|
+
- \`limn compare image-reference --target ${input.target.name} --spec\`
|
|
116
|
+
|
|
117
|
+
## Notes
|
|
118
|
+
|
|
119
|
+
- Prefer Claude structured outputs or strict schema enforcement if available.
|
|
120
|
+
- Do not accept markdown fences or explanatory prose around the JSON.
|
|
121
|
+
- Treat the separate ideal image and reference screenshot as the primary visual evidence.
|
|
122
|
+
- Use the side-by-side only as comparison context, not as the image to parse.
|
|
123
|
+
- Start from the shared instructions in \`${rel(input.promptPath)}\`.
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
function relativeToWorkspace(target) {
|
|
127
|
+
return (filePath) => path.relative(target.workspace.root, filePath);
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=visual-spec-prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-spec-prompts.js","sourceRoot":"","sources":["../../src/core/visual-spec-prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type WorkspacePaths = {
|
|
2
|
+
root: string;
|
|
3
|
+
configPath: string;
|
|
4
|
+
targetsDir: string;
|
|
5
|
+
runsDir: string;
|
|
6
|
+
};
|
|
7
|
+
export type TargetPaths = {
|
|
8
|
+
workspace: WorkspacePaths;
|
|
9
|
+
name: string;
|
|
10
|
+
root: string;
|
|
11
|
+
sourceDir: string;
|
|
12
|
+
contractDir: string;
|
|
13
|
+
referenceDir: string;
|
|
14
|
+
capturesDir: string;
|
|
15
|
+
reportsDir: string;
|
|
16
|
+
agentGuidePath: string;
|
|
17
|
+
sourceImagePath: string;
|
|
18
|
+
regionsPath: string;
|
|
19
|
+
tokensPath: string;
|
|
20
|
+
acceptancePath: string;
|
|
21
|
+
referenceHtmlPath: string;
|
|
22
|
+
referenceCssPath: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function resolveWorkspace(root?: string): WorkspacePaths;
|
|
25
|
+
export declare function validateTargetName(target: string): string;
|
|
26
|
+
export declare function resolveTarget(workspaceRoot: string, target: string, sourceFileName?: string): TargetPaths;
|
|
27
|
+
export declare function ensureWorkspace(workspace: WorkspacePaths): Promise<void>;
|
|
28
|
+
export declare function ensureTargetDirs(target: TargetPaths): Promise<void>;
|
|
29
|
+
export declare function writeIfMissing(filePath: string, contents: string, force?: boolean): Promise<'written' | 'skipped'>;
|
|
30
|
+
export declare function copyIfMissing(sourcePath: string, destinationPath: string, force?: boolean): Promise<'written' | 'skipped'>;
|
|
31
|
+
export declare function readJsonFile<T>(filePath: string): Promise<T>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function resolveWorkspace(root = process.cwd()) {
|
|
4
|
+
const resolvedRoot = path.resolve(root);
|
|
5
|
+
return {
|
|
6
|
+
root: resolvedRoot,
|
|
7
|
+
configPath: path.join(resolvedRoot, 'limner.config.ts'),
|
|
8
|
+
targetsDir: path.join(resolvedRoot, 'targets'),
|
|
9
|
+
runsDir: path.join(resolvedRoot, '.limner', 'runs'),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function validateTargetName(target) {
|
|
13
|
+
if (!/^[a-z0-9][a-z0-9-_]*$/i.test(target)) {
|
|
14
|
+
throw new Error(`Invalid target "${target}". Use letters, numbers, dashes, and underscores.`);
|
|
15
|
+
}
|
|
16
|
+
return target;
|
|
17
|
+
}
|
|
18
|
+
export function resolveTarget(workspaceRoot, target, sourceFileName = 'ideal.png') {
|
|
19
|
+
const workspace = resolveWorkspace(workspaceRoot);
|
|
20
|
+
const name = validateTargetName(target);
|
|
21
|
+
const root = path.join(workspace.targetsDir, name);
|
|
22
|
+
const sourceDir = path.join(root, 'source');
|
|
23
|
+
const contractDir = path.join(root, 'contract');
|
|
24
|
+
const referenceDir = path.join(root, 'reference');
|
|
25
|
+
const capturesDir = path.join(root, 'captures');
|
|
26
|
+
const reportsDir = path.join(root, 'reports');
|
|
27
|
+
return {
|
|
28
|
+
workspace,
|
|
29
|
+
name,
|
|
30
|
+
root,
|
|
31
|
+
sourceDir,
|
|
32
|
+
contractDir,
|
|
33
|
+
referenceDir,
|
|
34
|
+
capturesDir,
|
|
35
|
+
reportsDir,
|
|
36
|
+
agentGuidePath: path.join(root, 'AGENT_GUIDE.md'),
|
|
37
|
+
sourceImagePath: path.join(sourceDir, sourceFileName),
|
|
38
|
+
regionsPath: path.join(contractDir, 'regions.json'),
|
|
39
|
+
tokensPath: path.join(contractDir, 'tokens.json'),
|
|
40
|
+
acceptancePath: path.join(contractDir, 'acceptance.md'),
|
|
41
|
+
referenceHtmlPath: path.join(referenceDir, 'index.html'),
|
|
42
|
+
referenceCssPath: path.join(referenceDir, 'styles.css'),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export async function ensureWorkspace(workspace) {
|
|
46
|
+
await mkdir(workspace.targetsDir, { recursive: true });
|
|
47
|
+
await mkdir(workspace.runsDir, { recursive: true });
|
|
48
|
+
await writeIfMissing(workspace.configPath, `export default {
|
|
49
|
+
viewport: { width: 1440, height: 900 },
|
|
50
|
+
targetsDir: 'targets',
|
|
51
|
+
} as const;
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
export async function ensureTargetDirs(target) {
|
|
55
|
+
await Promise.all([
|
|
56
|
+
mkdir(target.sourceDir, { recursive: true }),
|
|
57
|
+
mkdir(target.contractDir, { recursive: true }),
|
|
58
|
+
mkdir(path.join(target.referenceDir, 'assets'), { recursive: true }),
|
|
59
|
+
mkdir(path.join(target.capturesDir, 'image-reference'), { recursive: true }),
|
|
60
|
+
mkdir(path.join(target.capturesDir, 'reference-app'), { recursive: true }),
|
|
61
|
+
mkdir(path.join(target.capturesDir, 'reference'), { recursive: true }),
|
|
62
|
+
mkdir(target.reportsDir, { recursive: true }),
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
export async function writeIfMissing(filePath, contents, force = false) {
|
|
66
|
+
if (!force) {
|
|
67
|
+
try {
|
|
68
|
+
await readFile(filePath);
|
|
69
|
+
return 'skipped';
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Missing file is the expected write path.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
76
|
+
await writeFile(filePath, contents);
|
|
77
|
+
return 'written';
|
|
78
|
+
}
|
|
79
|
+
export async function copyIfMissing(sourcePath, destinationPath, force = false) {
|
|
80
|
+
if (!force) {
|
|
81
|
+
try {
|
|
82
|
+
await readFile(destinationPath);
|
|
83
|
+
return 'skipped';
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Missing file is the expected copy path.
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
await mkdir(path.dirname(destinationPath), { recursive: true });
|
|
90
|
+
await copyFile(sourcePath, destinationPath);
|
|
91
|
+
return 'written';
|
|
92
|
+
}
|
|
93
|
+
export async function readJsonFile(filePath) {
|
|
94
|
+
const raw = await readFile(filePath, 'utf8');
|
|
95
|
+
return JSON.parse(raw);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/core/workspace.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { limnerRegionCheckSchema, limnerRegionContractSchema, limnerRegionSchema, limnerTokensSchema, } from './schemas/contract.js';
|
|
2
|
+
export type { LimnerRegion, LimnerRegionCheck, LimnerRegionContract, LimnerTokens } from './schemas/contract.js';
|
|
3
|
+
export { limnerRunEventSchema, runManifestSchema } from './schemas/events.js';
|
|
4
|
+
export type { LimnerRunEvent, RunManifest } from './schemas/events.js';
|
|
5
|
+
export { visualSpecBundleSchema, visualSpecDiffSchema, visualSpecSchema, createVisualSpecBundleExample, createVisualSpecJsonSchema } from './schemas/visual-spec.js';
|
|
6
|
+
export type { VisualSpec, VisualSpecBundle, VisualSpecDiff } from './schemas/visual-spec.js';
|
|
7
|
+
export { initTarget } from './commands/init.js';
|
|
8
|
+
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 { createRunId, createRunLogger } from './core/run-logger.js';
|
|
12
|
+
export { resolveWorkspace, validateTargetName } from './core/workspace.js';
|
|
13
|
+
export { collectReferenceDomFacts } from './core/reference-dom-facts.js';
|
|
14
|
+
export { writeImageReferenceSpecPack } from './core/visual-spec-agent-pack.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { limnerRegionCheckSchema, limnerRegionContractSchema, limnerRegionSchema, limnerTokensSchema, } from './schemas/contract.js';
|
|
2
|
+
export { limnerRunEventSchema, runManifestSchema } from './schemas/events.js';
|
|
3
|
+
export { visualSpecBundleSchema, visualSpecDiffSchema, visualSpecSchema, createVisualSpecBundleExample, createVisualSpecJsonSchema } from './schemas/visual-spec.js';
|
|
4
|
+
export { initTarget } from './commands/init.js';
|
|
5
|
+
export { captureReference } from './commands/capture.js';
|
|
6
|
+
export { compareImageReference, compareReferenceApp } from './commands/compare.js';
|
|
7
|
+
export { compareImageApp } from './commands/compare-image-app.js';
|
|
8
|
+
export { createRunId, createRunLogger } from './core/run-logger.js';
|
|
9
|
+
export { resolveWorkspace, validateTargetName } from './core/workspace.js';
|
|
10
|
+
export { collectReferenceDomFacts } from './core/reference-dom-facts.js';
|
|
11
|
+
export { writeImageReferenceSpecPack } from './core/visual-spec-agent-pack.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const limnerRegionCheckSchema: z.ZodEnum<{
|
|
3
|
+
bounds: "bounds";
|
|
4
|
+
visible: "visible";
|
|
5
|
+
"computed-style": "computed-style";
|
|
6
|
+
text: "text";
|
|
7
|
+
}>;
|
|
8
|
+
export declare const limnerRegionSchema: z.ZodObject<{
|
|
9
|
+
id: z.ZodString;
|
|
10
|
+
label: z.ZodString;
|
|
11
|
+
referenceSelector: z.ZodString;
|
|
12
|
+
appSelector: z.ZodOptional<z.ZodString>;
|
|
13
|
+
checks: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
14
|
+
bounds: "bounds";
|
|
15
|
+
visible: "visible";
|
|
16
|
+
"computed-style": "computed-style";
|
|
17
|
+
text: "text";
|
|
18
|
+
}>>>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare const limnerRegionContractSchema: z.ZodObject<{
|
|
21
|
+
regions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
label: z.ZodString;
|
|
24
|
+
referenceSelector: z.ZodString;
|
|
25
|
+
appSelector: z.ZodOptional<z.ZodString>;
|
|
26
|
+
checks: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
27
|
+
bounds: "bounds";
|
|
28
|
+
visible: "visible";
|
|
29
|
+
"computed-style": "computed-style";
|
|
30
|
+
text: "text";
|
|
31
|
+
}>>>;
|
|
32
|
+
}, z.core.$strip>>>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export declare const limnerTokensSchema: z.ZodObject<{
|
|
35
|
+
colors: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
36
|
+
radii: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
37
|
+
typography: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
|
|
38
|
+
spacing: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export type LimnerRegionCheck = z.infer<typeof limnerRegionCheckSchema>;
|
|
41
|
+
export type LimnerRegion = z.infer<typeof limnerRegionSchema>;
|
|
42
|
+
export type LimnerRegionContract = z.infer<typeof limnerRegionContractSchema>;
|
|
43
|
+
export type LimnerTokens = z.infer<typeof limnerTokensSchema>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const limnerRegionCheckSchema = z.enum(['bounds', 'visible', 'computed-style', 'text']);
|
|
3
|
+
export const limnerRegionSchema = z.object({
|
|
4
|
+
id: z.string().min(1),
|
|
5
|
+
label: z.string().min(1),
|
|
6
|
+
referenceSelector: z.string().min(1),
|
|
7
|
+
appSelector: z.string().min(1).optional(),
|
|
8
|
+
checks: z.array(limnerRegionCheckSchema).default(['bounds', 'visible']),
|
|
9
|
+
});
|
|
10
|
+
export const limnerRegionContractSchema = z.object({
|
|
11
|
+
regions: z.array(limnerRegionSchema).default([]),
|
|
12
|
+
});
|
|
13
|
+
export const limnerTokensSchema = z.object({
|
|
14
|
+
colors: z.record(z.string(), z.string()).default({}),
|
|
15
|
+
radii: z.record(z.string(), z.number()).default({}),
|
|
16
|
+
typography: z.record(z.string(), z.union([z.string(), z.number()])).default({}),
|
|
17
|
+
spacing: z.record(z.string(), z.number()).default({}),
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/schemas/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;CACxE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACjD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACpD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACnD,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/E,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACtD,CAAC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const limnerRunEventSchema: z.ZodObject<{
|
|
3
|
+
type: z.ZodString;
|
|
4
|
+
ts: z.ZodString;
|
|
5
|
+
command: z.ZodOptional<z.ZodString>;
|
|
6
|
+
mode: z.ZodOptional<z.ZodString>;
|
|
7
|
+
target: z.ZodOptional<z.ZodString>;
|
|
8
|
+
path: z.ZodOptional<z.ZodString>;
|
|
9
|
+
kind: z.ZodOptional<z.ZodString>;
|
|
10
|
+
status: z.ZodOptional<z.ZodString>;
|
|
11
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
message: z.ZodOptional<z.ZodString>;
|
|
13
|
+
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
export declare const runManifestSchema: z.ZodObject<{
|
|
16
|
+
runId: z.ZodString;
|
|
17
|
+
command: z.ZodString;
|
|
18
|
+
target: z.ZodOptional<z.ZodString>;
|
|
19
|
+
mode: z.ZodOptional<z.ZodString>;
|
|
20
|
+
startedAt: z.ZodString;
|
|
21
|
+
completedAt: z.ZodOptional<z.ZodString>;
|
|
22
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
23
|
+
running: "running";
|
|
24
|
+
ok: "ok";
|
|
25
|
+
failed: "failed";
|
|
26
|
+
}>>;
|
|
27
|
+
artifacts: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
28
|
+
viewport: z.ZodOptional<z.ZodObject<{
|
|
29
|
+
width: z.ZodNumber;
|
|
30
|
+
height: z.ZodNumber;
|
|
31
|
+
}, z.core.$strip>>;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
export type LimnerRunEvent = z.infer<typeof limnerRunEventSchema>;
|
|
34
|
+
export type RunManifest = z.infer<typeof runManifestSchema>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const limnerRunEventSchema = z.object({
|
|
3
|
+
type: z.string().min(1),
|
|
4
|
+
ts: z.string().datetime(),
|
|
5
|
+
command: z.string().optional(),
|
|
6
|
+
mode: z.string().optional(),
|
|
7
|
+
target: z.string().optional(),
|
|
8
|
+
path: z.string().optional(),
|
|
9
|
+
kind: z.string().optional(),
|
|
10
|
+
status: z.string().optional(),
|
|
11
|
+
durationMs: z.number().optional(),
|
|
12
|
+
message: z.string().optional(),
|
|
13
|
+
data: z.record(z.string(), z.unknown()).optional(),
|
|
14
|
+
});
|
|
15
|
+
export const runManifestSchema = z.object({
|
|
16
|
+
runId: z.string().min(1),
|
|
17
|
+
command: z.string().min(1),
|
|
18
|
+
target: z.string().optional(),
|
|
19
|
+
mode: z.string().optional(),
|
|
20
|
+
startedAt: z.string().datetime(),
|
|
21
|
+
completedAt: z.string().datetime().optional(),
|
|
22
|
+
status: z.enum(['running', 'ok', 'failed']).default('running'),
|
|
23
|
+
artifacts: z.array(z.string()).default([]),
|
|
24
|
+
viewport: z.object({
|
|
25
|
+
width: z.number(),
|
|
26
|
+
height: z.number(),
|
|
27
|
+
}).optional(),
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/schemas/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC7C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC9D,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;QACjB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;KACnB,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC"}
|