@12ui/design 0.2.48 → 0.2.49
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/SKILL.md +1 -1
- package/dist/branch-page-conversion.d.ts +4 -1
- package/dist/branch-page-conversion.d.ts.map +1 -1
- package/dist/branch-page-conversion.js +27 -17
- package/dist/branch-page-conversion.js.map +1 -1
- package/dist/branch-run-record.d.ts +2 -0
- package/dist/branch-run-record.d.ts.map +1 -1
- package/dist/branch-run-record.js.map +1 -1
- package/dist/cli-draft-command.d.ts +11 -5
- package/dist/cli-draft-command.d.ts.map +1 -1
- package/dist/cli-draft-command.js +37 -35
- package/dist/cli-draft-command.js.map +1 -1
- package/dist/cli-help/design.d.ts +10 -0
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +29 -0
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +11 -0
- package/dist/cli-help/index.d.ts.map +1 -1
- package/dist/cli-help/index.js +18 -2
- package/dist/cli-help/index.js.map +1 -1
- package/dist/cli-next-command.d.ts.map +1 -1
- package/dist/cli-next-command.js +26 -14
- package/dist/cli-next-command.js.map +1 -1
- package/dist/cli-progress.d.ts +2 -0
- package/dist/cli-progress.d.ts.map +1 -1
- package/dist/cli-progress.js +2 -0
- package/dist/cli-progress.js.map +1 -1
- package/dist/cli-redesign-command.d.ts +42 -0
- package/dist/cli-redesign-command.d.ts.map +1 -0
- package/dist/cli-redesign-command.js +520 -0
- package/dist/cli-redesign-command.js.map +1 -0
- package/dist/cli-run.d.ts.map +1 -1
- package/dist/cli-run.js +8 -0
- package/dist/cli-run.js.map +1 -1
- package/dist/cli-usage.d.ts.map +1 -1
- package/dist/cli-usage.js +8 -1
- package/dist/cli-usage.js.map +1 -1
- package/dist/draft-dispatch-attempt.d.ts +0 -7
- package/dist/draft-dispatch-attempt.d.ts.map +1 -1
- package/dist/draft-dispatch-attempt.js +1 -25
- package/dist/draft-dispatch-attempt.js.map +1 -1
- package/dist/draft-identity.d.ts +2 -0
- package/dist/draft-identity.d.ts.map +1 -1
- package/dist/draft-identity.js +1 -0
- package/dist/draft-identity.js.map +1 -1
- package/dist/draft-run.d.ts +2 -0
- package/dist/draft-run.d.ts.map +1 -1
- package/dist/draft-run.js +4 -3
- package/dist/draft-run.js.map +1 -1
- package/dist/package-client.d.ts +11 -0
- package/dist/package-client.d.ts.map +1 -1
- package/dist/package-client.js.map +1 -1
- package/dist/package-submission.d.ts +12 -0
- package/dist/package-submission.d.ts.map +1 -1
- package/dist/package-submission.js +5 -0
- package/dist/package-submission.js.map +1 -1
- package/dist/redesign-brand-asset-inventory.d.ts +71 -0
- package/dist/redesign-brand-asset-inventory.d.ts.map +1 -0
- package/dist/redesign-brand-asset-inventory.js +318 -0
- package/dist/redesign-brand-asset-inventory.js.map +1 -0
- package/dist/redesign-capture.d.ts +57 -0
- package/dist/redesign-capture.d.ts.map +1 -0
- package/dist/redesign-capture.js +181 -0
- package/dist/redesign-capture.js.map +1 -0
- package/dist/redesign-pinned-asset.d.ts +20 -0
- package/dist/redesign-pinned-asset.d.ts.map +1 -0
- package/dist/redesign-pinned-asset.js +35 -0
- package/dist/redesign-pinned-asset.js.map +1 -0
- package/dist/redesign-plan-client.d.ts +49 -0
- package/dist/redesign-plan-client.d.ts.map +1 -0
- package/dist/redesign-plan-client.js +90 -0
- package/dist/redesign-plan-client.js.map +1 -0
- package/dist/redesign-plan-identity.d.ts +8 -0
- package/dist/redesign-plan-identity.d.ts.map +1 -0
- package/dist/redesign-plan-identity.js +16 -0
- package/dist/redesign-plan-identity.js.map +1 -0
- package/dist/redesign-plan.d.ts +30 -0
- package/dist/redesign-plan.d.ts.map +1 -0
- package/dist/redesign-plan.js +99 -0
- package/dist/redesign-plan.js.map +1 -0
- package/dist/redesign-workspace.d.ts +142 -0
- package/dist/redesign-workspace.d.ts.map +1 -0
- package/dist/redesign-workspace.js +82 -0
- package/dist/redesign-workspace.js.map +1 -0
- package/dist/run-journal-commands.d.ts.map +1 -1
- package/dist/run-journal-commands.js +10 -0
- package/dist/run-journal-commands.js.map +1 -1
- package/open-design.json +2 -2
- package/package.json +2 -2
- package/prototype-kit/build.mjs +9 -3
- package/prototype-kit/lib/action-target.mjs +26 -0
- package/prototype-kit/lib/local-document.mjs +16 -0
- package/prototype-kit/lib/runtime-check.mjs +83 -19
- package/prototype-kit/lib/shell-runtime-equivalence.mjs +41 -0
- package/prototype-kit/polish/harm.mjs +27 -5
- package/prototype-kit/polish/measure.mjs +101 -5
- package/prototype-kit/polish/overrides.mjs +32 -3
- package/prototype-kit/polish/polish.mjs +23 -11
- package/prototype-kit/polish/rules/align.mjs +73 -3
- package/prototype-kit/polish/rules/left-rail.mjs +2 -3
- package/prototype-kit/polish/rules/section-breathing.mjs +0 -1
- package/prototype-kit/polish/tests/fixtures/align/expect.json +1 -1
- package/prototype-kit/polish/tests/fixtures/align/fire.html +4 -1
- package/prototype-kit/polish/tests/fixtures/align/silent.html +8 -0
- package/prototype-kit/polish/tests/fixtures/align/zoom-constrained.html +17 -0
- package/prototype-kit/polish/tests/fixtures/harm/left-rail-contained.html +16 -0
- package/prototype-kit/polish/tests/fixtures/harm/left-rail-overflow.html +16 -0
- package/prototype-kit/polish/tests/fixtures/harm/nested-actions.html +6 -0
- package/prototype-kit/polish/tests/fixtures/harm/unidentified-parent.html +3 -0
- package/prototype-kit/polish/tests/fixtures/shell-seam/fire.html +1 -1
- package/prototype-kit/polish/tests/harm-check.mjs +131 -2
- package/prototype-kit/polish/tests/rules-check.mjs +7 -2
- package/prototype-kit/runtime/proto.js +4 -1
- package/prototype-kit/tests/adversarial-runtime.mjs +3 -0
- package/prototype-kit/tests/align-rule-check.mjs +105 -0
- package/prototype-kit/tests/fixtures/interaction-runtime/review-bottom-action.html +8 -0
- package/prototype-kit/tests/offline-check.mjs +17 -1
- package/prototype-kit/tests/rules-check.mjs +67 -1
- package/prototype-kit/tests/shell-stitching-runtime.mjs +15 -8
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import sharp from 'sharp';
|
|
5
|
+
/**
|
|
6
|
+
* Brand assets are evidence collected while the original page is still open.
|
|
7
|
+
* They are deliberately local capture artifacts: no asset is guessed from a
|
|
8
|
+
* logo name, and no later stage has to revisit an already-captured site.
|
|
9
|
+
*/
|
|
10
|
+
export const REDESIGN_MAX_BRAND_ASSET_CANDIDATES = 24;
|
|
11
|
+
export const REDESIGN_MAX_NATIVE_BRAND_ASSET_BYTES = 5 * 1024 * 1024;
|
|
12
|
+
const hashBytes = (bytes) => createHash('sha256').update(bytes).digest('hex');
|
|
13
|
+
const dimensionsOf = async (bytes, fallback) => {
|
|
14
|
+
try {
|
|
15
|
+
const metadata = await sharp(bytes, { animated: false, failOn: 'warning' }).metadata();
|
|
16
|
+
if (metadata.width && metadata.height)
|
|
17
|
+
return { width: metadata.width, height: metadata.height };
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// A source can still be useful evidence even when its media parser does not know its canvas.
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
width: Math.max(1, Math.round(fallback[2])),
|
|
24
|
+
height: Math.max(1, Math.round(fallback[3])),
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
const mediaTypeFromUrl = (sourceUrl) => {
|
|
28
|
+
const pathname = (() => {
|
|
29
|
+
try {
|
|
30
|
+
return new URL(sourceUrl).pathname.toLowerCase();
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
})();
|
|
36
|
+
if (/\.svg$/u.test(pathname))
|
|
37
|
+
return 'image/svg+xml';
|
|
38
|
+
if (/\.png$/u.test(pathname))
|
|
39
|
+
return 'image/png';
|
|
40
|
+
if (/\.jpe?g$/u.test(pathname))
|
|
41
|
+
return 'image/jpeg';
|
|
42
|
+
if (/\.webp$/u.test(pathname))
|
|
43
|
+
return 'image/webp';
|
|
44
|
+
if (/\.gif$/u.test(pathname))
|
|
45
|
+
return 'image/gif';
|
|
46
|
+
if (/\.avif$/u.test(pathname))
|
|
47
|
+
return 'image/avif';
|
|
48
|
+
return 'application/octet-stream';
|
|
49
|
+
};
|
|
50
|
+
const fileExtensionFor = (mediaType) => {
|
|
51
|
+
const normalized = mediaType.toLowerCase().split(';', 1)[0];
|
|
52
|
+
if (normalized === 'image/svg+xml')
|
|
53
|
+
return 'svg';
|
|
54
|
+
if (normalized === 'image/png')
|
|
55
|
+
return 'png';
|
|
56
|
+
if (normalized === 'image/jpeg')
|
|
57
|
+
return 'jpg';
|
|
58
|
+
if (normalized === 'image/webp')
|
|
59
|
+
return 'webp';
|
|
60
|
+
if (normalized === 'image/gif')
|
|
61
|
+
return 'gif';
|
|
62
|
+
if (normalized === 'image/avif')
|
|
63
|
+
return 'avif';
|
|
64
|
+
return 'bin';
|
|
65
|
+
};
|
|
66
|
+
const isSameOriginFile = (documentUrl, sourceUrl) => {
|
|
67
|
+
try {
|
|
68
|
+
const document = new URL(documentUrl);
|
|
69
|
+
const source = new URL(sourceUrl);
|
|
70
|
+
if (document.protocol === 'file:' && source.protocol === 'file:')
|
|
71
|
+
return true;
|
|
72
|
+
return document.origin !== 'null' && document.origin === source.origin;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const candidatePath = (inventoryId, mediaType, directory) => (path.resolve(directory, `${inventoryId}.${fileExtensionFor(mediaType)}`));
|
|
79
|
+
/**
|
|
80
|
+
* Finds all potentially brand-bearing painted nodes in the site's own chrome.
|
|
81
|
+
* This runs in the already-open page so computed CSS and document-coordinate
|
|
82
|
+
* geometry are facts from the exact page captured in the screenshot.
|
|
83
|
+
*/
|
|
84
|
+
export const collectRedesignBrandAssetCandidates = async (page) => page.evaluate((maximum) => {
|
|
85
|
+
const isRootLink = (node) => {
|
|
86
|
+
const anchor = node.closest('a[href]');
|
|
87
|
+
const href = anchor?.getAttribute('href');
|
|
88
|
+
if (!href)
|
|
89
|
+
return false;
|
|
90
|
+
// `setContent()` fixtures have an opaque about:blank origin but still
|
|
91
|
+
// express the same root-link intent as a live document.
|
|
92
|
+
if (/^\/(?:[?#].*)?$/u.test(href.trim()))
|
|
93
|
+
return true;
|
|
94
|
+
try {
|
|
95
|
+
const url = new URL(href, location.href);
|
|
96
|
+
return url.origin === location.origin && url.pathname === '/';
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const isBrandScope = (node) => (node.closest('header, nav, [class*="logo" i]') !== null || isRootLink(node));
|
|
103
|
+
const domPath = (node) => {
|
|
104
|
+
const segments = [];
|
|
105
|
+
let current = node;
|
|
106
|
+
while (current && current !== document.documentElement) {
|
|
107
|
+
const tag = current.localName.toLowerCase();
|
|
108
|
+
if (current.id) {
|
|
109
|
+
segments.unshift(`${tag}#${current.id}`);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
let ordinal = 1;
|
|
113
|
+
let sibling = current.previousElementSibling;
|
|
114
|
+
while (sibling) {
|
|
115
|
+
if (sibling.localName === current.localName)
|
|
116
|
+
ordinal += 1;
|
|
117
|
+
sibling = sibling.previousElementSibling;
|
|
118
|
+
}
|
|
119
|
+
segments.unshift(`${tag}:nth-of-type(${ordinal})`);
|
|
120
|
+
current = current.parentElement;
|
|
121
|
+
}
|
|
122
|
+
return `html > ${segments.join(' > ')}`;
|
|
123
|
+
};
|
|
124
|
+
const sourceFromBackground = (backgroundImage) => {
|
|
125
|
+
const match = /url\(\s*(['"]?)(.*?)\1\s*\)/u.exec(backgroundImage);
|
|
126
|
+
if (!match?.[2])
|
|
127
|
+
return null;
|
|
128
|
+
try {
|
|
129
|
+
return new URL(match[2], location.href).href;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const scoped = new Set();
|
|
136
|
+
for (const node of Array.from(document.querySelectorAll('header, header *, nav, nav *, [class*="logo" i], [class*="logo" i] *, a, a *'))) {
|
|
137
|
+
if (isBrandScope(node))
|
|
138
|
+
scoped.add(node);
|
|
139
|
+
}
|
|
140
|
+
const result = [];
|
|
141
|
+
for (const node of scoped) {
|
|
142
|
+
if (result.length >= maximum)
|
|
143
|
+
break;
|
|
144
|
+
const rect = node.getBoundingClientRect();
|
|
145
|
+
if (rect.width < 1 || rect.height < 1)
|
|
146
|
+
continue;
|
|
147
|
+
const captureBox = [
|
|
148
|
+
rect.left + window.scrollX,
|
|
149
|
+
rect.top + window.scrollY,
|
|
150
|
+
rect.width,
|
|
151
|
+
rect.height,
|
|
152
|
+
];
|
|
153
|
+
const path = domPath(node);
|
|
154
|
+
if (node instanceof HTMLImageElement) {
|
|
155
|
+
const source = node.currentSrc || node.src;
|
|
156
|
+
result.push({
|
|
157
|
+
kind: 'img',
|
|
158
|
+
domPath: path,
|
|
159
|
+
captureBox,
|
|
160
|
+
documentUrl: location.href,
|
|
161
|
+
sourceUrl: source || null,
|
|
162
|
+
inlineSvg: null,
|
|
163
|
+
});
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (node instanceof SVGElement && !node.parentElement?.closest('svg')) {
|
|
167
|
+
result.push({
|
|
168
|
+
kind: 'inline-svg',
|
|
169
|
+
domPath: path,
|
|
170
|
+
captureBox,
|
|
171
|
+
documentUrl: location.href,
|
|
172
|
+
sourceUrl: null,
|
|
173
|
+
inlineSvg: new XMLSerializer().serializeToString(node),
|
|
174
|
+
});
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const backgroundImage = getComputedStyle(node).backgroundImage;
|
|
178
|
+
if (backgroundImage && backgroundImage !== 'none') {
|
|
179
|
+
result.push({
|
|
180
|
+
kind: 'css-background',
|
|
181
|
+
domPath: path,
|
|
182
|
+
captureBox,
|
|
183
|
+
documentUrl: location.href,
|
|
184
|
+
sourceUrl: sourceFromBackground(backgroundImage),
|
|
185
|
+
inlineSvg: null,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}, REDESIGN_MAX_BRAND_ASSET_CANDIDATES);
|
|
191
|
+
const fetchSameOriginAsset = async (page, sourceUrl) => page.evaluate(async (args) => {
|
|
192
|
+
try {
|
|
193
|
+
const response = await fetch(args.sourceUrl, { credentials: 'include' });
|
|
194
|
+
if (!response.ok)
|
|
195
|
+
return null;
|
|
196
|
+
const announcedLength = Number(response.headers.get('content-length'));
|
|
197
|
+
if (Number.isFinite(announcedLength) && announcedLength > args.maximumBytes)
|
|
198
|
+
return null;
|
|
199
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
200
|
+
if (bytes.byteLength > args.maximumBytes)
|
|
201
|
+
return null;
|
|
202
|
+
let binary = '';
|
|
203
|
+
for (let start = 0; start < bytes.length; start += 0x8000) {
|
|
204
|
+
binary += String.fromCharCode(...bytes.subarray(start, start + 0x8000));
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
bytesBase64: btoa(binary),
|
|
208
|
+
mediaType: response.headers.get('content-type'),
|
|
209
|
+
finalUrl: response.url,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
}, { sourceUrl, maximumBytes: REDESIGN_MAX_NATIVE_BRAND_ASSET_BYTES });
|
|
216
|
+
const captureFallbackCrop = async (args) => {
|
|
217
|
+
const bytesPath = candidatePath(args.inventoryId, 'image/png', args.assetsDir);
|
|
218
|
+
const capture = sharp(args.captureImagePath, { animated: false, failOn: 'warning' });
|
|
219
|
+
const metadata = await capture.metadata();
|
|
220
|
+
if (!metadata.width || !metadata.height) {
|
|
221
|
+
throw new Error(`Captured page ${args.captureImagePath} has no raster dimensions`);
|
|
222
|
+
}
|
|
223
|
+
const left = Math.max(0, Math.floor(args.candidate.captureBox[0]));
|
|
224
|
+
const top = Math.max(0, Math.floor(args.candidate.captureBox[1]));
|
|
225
|
+
const right = Math.min(metadata.width, Math.ceil(args.candidate.captureBox[0] + args.candidate.captureBox[2]));
|
|
226
|
+
const bottom = Math.min(metadata.height, Math.ceil(args.candidate.captureBox[1] + args.candidate.captureBox[3]));
|
|
227
|
+
if (right <= left || bottom <= top) {
|
|
228
|
+
throw new Error(`Brand candidate ${args.inventoryId} falls outside the captured page frame`);
|
|
229
|
+
}
|
|
230
|
+
const bytes = await sharp(args.captureImagePath, { animated: false, failOn: 'warning' })
|
|
231
|
+
.extract({ left, top, width: right - left, height: bottom - top })
|
|
232
|
+
.png()
|
|
233
|
+
.toBuffer();
|
|
234
|
+
await writeFile(bytesPath, bytes);
|
|
235
|
+
const dimensions = await dimensionsOf(bytes, args.candidate.captureBox);
|
|
236
|
+
return {
|
|
237
|
+
inventoryId: args.inventoryId,
|
|
238
|
+
pageId: args.pageId,
|
|
239
|
+
domPath: args.candidate.domPath,
|
|
240
|
+
captureBox: args.candidate.captureBox,
|
|
241
|
+
bytesPath,
|
|
242
|
+
sha256: hashBytes(bytes),
|
|
243
|
+
mediaType: 'image/png',
|
|
244
|
+
...dimensions,
|
|
245
|
+
sourceUrl: args.candidate.sourceUrl,
|
|
246
|
+
source: 'screenshot-crop',
|
|
247
|
+
inlineSvg: false,
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
/**
|
|
251
|
+
* Freezes a page's brand candidates before its browser closes. Same-origin
|
|
252
|
+
* files retain their original bytes; inline SVG retains markup; every painted
|
|
253
|
+
* asset that cannot safely be read natively becomes a PNG crop of the exact
|
|
254
|
+
* screenshot coordinates recorded in the inventory.
|
|
255
|
+
*/
|
|
256
|
+
export const captureRedesignBrandAssetInventory = async (args) => {
|
|
257
|
+
await mkdir(args.assetsDir, { recursive: true });
|
|
258
|
+
const candidates = args.candidates ?? await collectRedesignBrandAssetCandidates(args.page);
|
|
259
|
+
const entries = [];
|
|
260
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
261
|
+
const inventoryId = `${args.pageId}-brand-${String(index + 1).padStart(2, '0')}`;
|
|
262
|
+
if (candidate.kind === 'inline-svg' && candidate.inlineSvg) {
|
|
263
|
+
const bytes = Buffer.from(candidate.inlineSvg, 'utf8');
|
|
264
|
+
const bytesPath = candidatePath(inventoryId, 'image/svg+xml', args.assetsDir);
|
|
265
|
+
await writeFile(bytesPath, bytes);
|
|
266
|
+
const dimensions = await dimensionsOf(bytes, candidate.captureBox);
|
|
267
|
+
entries.push({
|
|
268
|
+
inventoryId,
|
|
269
|
+
pageId: args.pageId,
|
|
270
|
+
domPath: candidate.domPath,
|
|
271
|
+
captureBox: candidate.captureBox,
|
|
272
|
+
bytesPath,
|
|
273
|
+
sha256: hashBytes(bytes),
|
|
274
|
+
mediaType: 'image/svg+xml',
|
|
275
|
+
...dimensions,
|
|
276
|
+
sourceUrl: null,
|
|
277
|
+
source: 'inline-svg',
|
|
278
|
+
inlineSvg: true,
|
|
279
|
+
});
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (candidate.sourceUrl && isSameOriginFile(candidate.documentUrl, candidate.sourceUrl)) {
|
|
283
|
+
const fetched = await fetchSameOriginAsset(args.page, candidate.sourceUrl);
|
|
284
|
+
const finishedSameOrigin = fetched !== null && isSameOriginFile(candidate.documentUrl, fetched.finalUrl);
|
|
285
|
+
if (finishedSameOrigin && fetched) {
|
|
286
|
+
const bytes = Buffer.from(fetched.bytesBase64, 'base64');
|
|
287
|
+
const mediaType = fetched.mediaType?.split(';', 1)[0].trim() || mediaTypeFromUrl(candidate.sourceUrl);
|
|
288
|
+
const bytesPath = candidatePath(inventoryId, mediaType, args.assetsDir);
|
|
289
|
+
await writeFile(bytesPath, bytes);
|
|
290
|
+
const dimensions = await dimensionsOf(bytes, candidate.captureBox);
|
|
291
|
+
entries.push({
|
|
292
|
+
inventoryId,
|
|
293
|
+
pageId: args.pageId,
|
|
294
|
+
domPath: candidate.domPath,
|
|
295
|
+
captureBox: candidate.captureBox,
|
|
296
|
+
bytesPath,
|
|
297
|
+
sha256: hashBytes(bytes),
|
|
298
|
+
mediaType,
|
|
299
|
+
// Dimensions follow the frozen source bytes, not CSS density or layout size.
|
|
300
|
+
...dimensions,
|
|
301
|
+
sourceUrl: candidate.sourceUrl,
|
|
302
|
+
source: 'same-origin-file',
|
|
303
|
+
inlineSvg: false,
|
|
304
|
+
});
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
entries.push(await captureFallbackCrop({
|
|
309
|
+
candidate,
|
|
310
|
+
pageId: args.pageId,
|
|
311
|
+
inventoryId,
|
|
312
|
+
assetsDir: args.assetsDir,
|
|
313
|
+
captureImagePath: args.captureImagePath,
|
|
314
|
+
}));
|
|
315
|
+
}
|
|
316
|
+
return entries;
|
|
317
|
+
};
|
|
318
|
+
//# sourceMappingURL=redesign-brand-asset-inventory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redesign-brand-asset-inventory.js","sourceRoot":"","sources":["../src/redesign-brand-asset-inventory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type RedesignBrandAssetInventoryEntry } from './redesign-brand-asset-inventory.js';
|
|
2
|
+
import type { RedesignCapturedPageRecord } from './redesign-workspace.js';
|
|
3
|
+
/**
|
|
4
|
+
* Stage 1: full-height screenshots of a target site's key pages.
|
|
5
|
+
*
|
|
6
|
+
* Discovery reads one page's HTML over `fetch` and keeps same-origin links
|
|
7
|
+
* found in `nav`/`header`/`footer` (where a site states its own key pages),
|
|
8
|
+
* falling back to the whole document when none of those hold a link. It never
|
|
9
|
+
* launches a browser: link discovery is free and must stay that way so
|
|
10
|
+
* `--dry-run` can report a page count without paying for a screenshot.
|
|
11
|
+
*
|
|
12
|
+
* Screenshotting is the one real Playwright dependency in this package (every
|
|
13
|
+
* other stage buys through the hosted API). `capturePage` is injected so
|
|
14
|
+
* tests exercise the stage's plumbing — file layout, hashing, the record —
|
|
15
|
+
* without a real browser or network call; the default implementation is only
|
|
16
|
+
* reached in production.
|
|
17
|
+
*/
|
|
18
|
+
export declare const REDESIGN_DEFAULT_MAX_PAGES = 5;
|
|
19
|
+
/**
|
|
20
|
+
* Same-origin URLs a caller would call this site's key pages: the homepage
|
|
21
|
+
* first, then links found in navigational chrome, deduplicated by pathname
|
|
22
|
+
* and capped at `maxPages`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const discoverRedesignPageUrls: (args: {
|
|
25
|
+
url: string;
|
|
26
|
+
maxPages?: number;
|
|
27
|
+
fetchHtml?: (url: string) => Promise<string>;
|
|
28
|
+
}) => Promise<string[]>;
|
|
29
|
+
export type RedesignCapturePageResult = {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
/** Frozen while the page is open, before its browser context is discarded. */
|
|
33
|
+
brandAssetInventory?: RedesignBrandAssetInventoryEntry[];
|
|
34
|
+
};
|
|
35
|
+
/** Capture-stage page record. The workspace record can carry this subtype unchanged. */
|
|
36
|
+
export type RedesignCapturedPageWithBrandAssetInventory = RedesignCapturedPageRecord & {
|
|
37
|
+
brandAssetInventory: RedesignBrandAssetInventoryEntry[];
|
|
38
|
+
};
|
|
39
|
+
export type RedesignCaptureDependencies = {
|
|
40
|
+
/**
|
|
41
|
+
* Injectable browser boundary. Test callers can return a frozen inventory
|
|
42
|
+
* directly, so capture-stage record plumbing has no browser dependency.
|
|
43
|
+
*/
|
|
44
|
+
capturePage?: (args: {
|
|
45
|
+
url: string;
|
|
46
|
+
outFile: string;
|
|
47
|
+
pageId: string;
|
|
48
|
+
brandAssetInventoryDir: string;
|
|
49
|
+
}) => Promise<RedesignCapturePageResult>;
|
|
50
|
+
};
|
|
51
|
+
/** Full-height screenshots of every discovered URL, written into `outDir`. */
|
|
52
|
+
export declare const captureRedesignPages: (args: {
|
|
53
|
+
urls: readonly string[];
|
|
54
|
+
outDir: string;
|
|
55
|
+
dependencies?: RedesignCaptureDependencies;
|
|
56
|
+
}) => Promise<RedesignCapturedPageWithBrandAssetInventory[]>;
|
|
57
|
+
//# sourceMappingURL=redesign-capture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redesign-capture.d.ts","sourceRoot":"","sources":["../src/redesign-capture.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,gCAAgC,EAEtC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAE1E;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAyB5C;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAU,MAAM;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C,KAAG,OAAO,CAAC,MAAM,EAAE,CA6BnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,mBAAmB,CAAC,EAAE,gCAAgC,EAAE,CAAC;CAC1D,CAAC;AAEF,wFAAwF;AACxF,MAAM,MAAM,2CAA2C,GAAG,0BAA0B,GAAG;IACrF,mBAAmB,EAAE,gCAAgC,EAAE,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QACnB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,sBAAsB,EAAE,MAAM,CAAC;KAChC,KAAK,OAAO,CAAC,yBAAyB,CAAC,CAAC;CAC1C,CAAC;AA8DF,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,GAAU,MAAM;IAC/C,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,2BAA2B,CAAC;CAC5C,KAAG,OAAO,CAAC,2CAA2C,EAAE,CA0CxD,CAAC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { parseHTML } from 'linkedom';
|
|
5
|
+
import { resolvePrototypeBrowserProvisioning } from './prototype-browsers.js';
|
|
6
|
+
import { captureRedesignBrandAssetInventory, collectRedesignBrandAssetCandidates, } from './redesign-brand-asset-inventory.js';
|
|
7
|
+
/**
|
|
8
|
+
* Stage 1: full-height screenshots of a target site's key pages.
|
|
9
|
+
*
|
|
10
|
+
* Discovery reads one page's HTML over `fetch` and keeps same-origin links
|
|
11
|
+
* found in `nav`/`header`/`footer` (where a site states its own key pages),
|
|
12
|
+
* falling back to the whole document when none of those hold a link. It never
|
|
13
|
+
* launches a browser: link discovery is free and must stay that way so
|
|
14
|
+
* `--dry-run` can report a page count without paying for a screenshot.
|
|
15
|
+
*
|
|
16
|
+
* Screenshotting is the one real Playwright dependency in this package (every
|
|
17
|
+
* other stage buys through the hosted API). `capturePage` is injected so
|
|
18
|
+
* tests exercise the stage's plumbing — file layout, hashing, the record —
|
|
19
|
+
* without a real browser or network call; the default implementation is only
|
|
20
|
+
* reached in production.
|
|
21
|
+
*/
|
|
22
|
+
export const REDESIGN_DEFAULT_MAX_PAGES = 5;
|
|
23
|
+
const CAPTURE_VIEWPORT = { width: 1440, height: 900 };
|
|
24
|
+
const NAVIGATION_SELECTORS = ['nav', 'header', 'footer'];
|
|
25
|
+
const pageId = (url, index) => {
|
|
26
|
+
const pathname = (() => {
|
|
27
|
+
try {
|
|
28
|
+
return new URL(url).pathname;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return `page-${index}`;
|
|
32
|
+
}
|
|
33
|
+
})();
|
|
34
|
+
const slug = pathname
|
|
35
|
+
.toLowerCase()
|
|
36
|
+
.replace(/[^a-z0-9]+/gu, '-')
|
|
37
|
+
.replace(/^-+|-+$/gu, '');
|
|
38
|
+
return slug || 'home';
|
|
39
|
+
};
|
|
40
|
+
const defaultFetchHtml = async (url) => {
|
|
41
|
+
const response = await fetch(url, { redirect: 'follow' });
|
|
42
|
+
if (!response.ok)
|
|
43
|
+
throw new Error(`${url} returned HTTP ${response.status}`);
|
|
44
|
+
return response.text();
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Same-origin URLs a caller would call this site's key pages: the homepage
|
|
48
|
+
* first, then links found in navigational chrome, deduplicated by pathname
|
|
49
|
+
* and capped at `maxPages`.
|
|
50
|
+
*/
|
|
51
|
+
export const discoverRedesignPageUrls = async (args) => {
|
|
52
|
+
const maxPages = args.maxPages ?? REDESIGN_DEFAULT_MAX_PAGES;
|
|
53
|
+
const origin = new URL(args.url);
|
|
54
|
+
const html = await (args.fetchHtml ?? defaultFetchHtml)(args.url);
|
|
55
|
+
const { document } = parseHTML(html);
|
|
56
|
+
const scopes = NAVIGATION_SELECTORS
|
|
57
|
+
.flatMap((selector) => Array.from(document.querySelectorAll(selector)));
|
|
58
|
+
const anchors = (scopes.length > 0 ? scopes : [document])
|
|
59
|
+
.flatMap((scope) => Array.from(scope.querySelectorAll('a[href]')));
|
|
60
|
+
const seen = new Set([origin.pathname || '/']);
|
|
61
|
+
const urls = [origin.toString()];
|
|
62
|
+
for (const anchor of anchors) {
|
|
63
|
+
if (urls.length >= maxPages)
|
|
64
|
+
break;
|
|
65
|
+
const href = anchor.getAttribute('href');
|
|
66
|
+
if (!href || href.startsWith('#') || href.startsWith('mailto:') || href.startsWith('tel:'))
|
|
67
|
+
continue;
|
|
68
|
+
const resolved = (() => {
|
|
69
|
+
try {
|
|
70
|
+
return new URL(href, origin);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
if (!resolved || resolved.origin !== origin.origin)
|
|
77
|
+
continue;
|
|
78
|
+
const key = resolved.pathname || '/';
|
|
79
|
+
if (seen.has(key))
|
|
80
|
+
continue;
|
|
81
|
+
seen.add(key);
|
|
82
|
+
urls.push(resolved.toString());
|
|
83
|
+
}
|
|
84
|
+
return urls.slice(0, maxPages);
|
|
85
|
+
};
|
|
86
|
+
const validateBrandAssetInventory = async (args) => {
|
|
87
|
+
const resolvedAssetsDir = path.resolve(args.assetsDir);
|
|
88
|
+
for (const entry of args.inventory) {
|
|
89
|
+
if (entry.pageId !== args.pageId) {
|
|
90
|
+
throw new Error(`Brand asset ${entry.inventoryId} belongs to ${entry.pageId}, not capture page ${args.pageId}`);
|
|
91
|
+
}
|
|
92
|
+
if (!entry.inventoryId.startsWith(`${args.pageId}-`)) {
|
|
93
|
+
throw new Error(`Brand asset ${entry.inventoryId} must be namespaced by capture page ${args.pageId}`);
|
|
94
|
+
}
|
|
95
|
+
if (args.seenIds.has(entry.inventoryId)) {
|
|
96
|
+
throw new Error(`Duplicate brand asset inventoryId ${entry.inventoryId} in this redesign capture`);
|
|
97
|
+
}
|
|
98
|
+
const resolvedBytesPath = path.resolve(entry.bytesPath);
|
|
99
|
+
if (!path.isAbsolute(entry.bytesPath) || path.dirname(resolvedBytesPath) !== resolvedAssetsDir) {
|
|
100
|
+
throw new Error(`Brand asset ${entry.inventoryId} bytesPath must be directly inside ${resolvedAssetsDir}`);
|
|
101
|
+
}
|
|
102
|
+
const frozenBytes = await readFile(resolvedBytesPath);
|
|
103
|
+
if (createHash('sha256').update(frozenBytes).digest('hex') !== entry.sha256) {
|
|
104
|
+
throw new Error(`Brand asset ${entry.inventoryId} sha256 does not match its frozen bytes`);
|
|
105
|
+
}
|
|
106
|
+
args.seenIds.add(entry.inventoryId);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const realCapturePage = async (args) => {
|
|
110
|
+
const provisioning = await resolvePrototypeBrowserProvisioning();
|
|
111
|
+
process.env.PLAYWRIGHT_BROWSERS_PATH = provisioning.browsersPath;
|
|
112
|
+
const { chromium } = await import('@playwright/test');
|
|
113
|
+
const browser = await chromium.launch();
|
|
114
|
+
try {
|
|
115
|
+
const page = await browser.newPage({ viewport: CAPTURE_VIEWPORT });
|
|
116
|
+
await page.goto(args.url, { waitUntil: 'networkidle' });
|
|
117
|
+
const brandAssetCandidates = await collectRedesignBrandAssetCandidates(page);
|
|
118
|
+
await page.screenshot({ path: args.outFile, fullPage: true });
|
|
119
|
+
const dimensions = await page.evaluate(() => ({
|
|
120
|
+
width: document.documentElement.scrollWidth,
|
|
121
|
+
height: document.documentElement.scrollHeight,
|
|
122
|
+
}));
|
|
123
|
+
const brandAssetInventory = await captureRedesignBrandAssetInventory({
|
|
124
|
+
page: page,
|
|
125
|
+
pageId: args.pageId,
|
|
126
|
+
assetsDir: args.brandAssetInventoryDir,
|
|
127
|
+
candidates: brandAssetCandidates,
|
|
128
|
+
captureImagePath: args.outFile,
|
|
129
|
+
});
|
|
130
|
+
return { ...dimensions, brandAssetInventory };
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
await browser.close();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
/** Full-height screenshots of every discovered URL, written into `outDir`. */
|
|
137
|
+
export const captureRedesignPages = async (args) => {
|
|
138
|
+
await mkdir(args.outDir, { recursive: true });
|
|
139
|
+
const capture = args.dependencies?.capturePage ?? realCapturePage;
|
|
140
|
+
const used = new Set();
|
|
141
|
+
const usedBrandAssetIds = new Set();
|
|
142
|
+
const pages = [];
|
|
143
|
+
for (const [index, url] of args.urls.entries()) {
|
|
144
|
+
let id = pageId(url, index);
|
|
145
|
+
while (used.has(id))
|
|
146
|
+
id = `${id}-${index}`;
|
|
147
|
+
used.add(id);
|
|
148
|
+
const outFile = path.join(args.outDir, `${id}.png`);
|
|
149
|
+
const brandAssetInventoryDir = path.join(args.outDir, 'brand-assets');
|
|
150
|
+
// The injection boundary can freeze bytes itself, so make the durable
|
|
151
|
+
// assets directory available before handing control to either implementation.
|
|
152
|
+
await mkdir(brandAssetInventoryDir, { recursive: true });
|
|
153
|
+
const captureResult = await capture({
|
|
154
|
+
url,
|
|
155
|
+
outFile,
|
|
156
|
+
pageId: id,
|
|
157
|
+
brandAssetInventoryDir,
|
|
158
|
+
});
|
|
159
|
+
const brandAssetInventory = captureResult.brandAssetInventory ?? [];
|
|
160
|
+
await validateBrandAssetInventory({
|
|
161
|
+
pageId: id,
|
|
162
|
+
inventory: brandAssetInventory,
|
|
163
|
+
seenIds: usedBrandAssetIds,
|
|
164
|
+
assetsDir: brandAssetInventoryDir,
|
|
165
|
+
});
|
|
166
|
+
const bytes = await readFile(outFile);
|
|
167
|
+
const info = await stat(outFile);
|
|
168
|
+
pages.push({
|
|
169
|
+
id,
|
|
170
|
+
url,
|
|
171
|
+
path: outFile,
|
|
172
|
+
sha256: createHash('sha256').update(bytes).digest('hex'),
|
|
173
|
+
bytes: info.size,
|
|
174
|
+
width: captureResult.width,
|
|
175
|
+
height: captureResult.height,
|
|
176
|
+
brandAssetInventory,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return pages;
|
|
180
|
+
};
|
|
181
|
+
//# sourceMappingURL=redesign-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redesign-capture.js","sourceRoot":"","sources":["../src/redesign-capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RedesignBrandAssetInventoryEntry } from './redesign-brand-asset-inventory.js';
|
|
2
|
+
import type { RedesignPinnedAssetRecord } from './redesign-workspace.js';
|
|
3
|
+
export type RedesignCapturedAssetInventory = {
|
|
4
|
+
id: string;
|
|
5
|
+
/** Optional for records written before capture inventory existed. */
|
|
6
|
+
brandAssetInventory?: readonly RedesignBrandAssetInventoryEntry[];
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Converts a planner's durable choice into the exact capture evidence it
|
|
10
|
+
* named. There is deliberately no nearest-match fallback: an absent or
|
|
11
|
+
* ambiguous choice must not turn into a pin for another asset.
|
|
12
|
+
*/
|
|
13
|
+
export declare const resolveRedesignPinnedAsset: (args: {
|
|
14
|
+
pinnedAssetChoice: {
|
|
15
|
+
inventoryId: string;
|
|
16
|
+
reason: string;
|
|
17
|
+
} | null;
|
|
18
|
+
pages: readonly RedesignCapturedAssetInventory[];
|
|
19
|
+
}) => RedesignPinnedAssetRecord | null;
|
|
20
|
+
//# sourceMappingURL=redesign-pinned-asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redesign-pinned-asset.d.ts","sourceRoot":"","sources":["../src/redesign-pinned-asset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AAC5F,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,SAAS,gCAAgC,EAAE,CAAC;CACnE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,GAAI,MAAM;IAC/C,iBAAiB,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClE,KAAK,EAAE,SAAS,8BAA8B,EAAE,CAAC;CAClD,KAAG,yBAAyB,GAAG,IA2B/B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a planner's durable choice into the exact capture evidence it
|
|
3
|
+
* named. There is deliberately no nearest-match fallback: an absent or
|
|
4
|
+
* ambiguous choice must not turn into a pin for another asset.
|
|
5
|
+
*/
|
|
6
|
+
export const resolveRedesignPinnedAsset = (args) => {
|
|
7
|
+
const choice = args.pinnedAssetChoice;
|
|
8
|
+
if (choice === null)
|
|
9
|
+
return null;
|
|
10
|
+
const matches = args.pages.flatMap((page) => (page.brandAssetInventory ?? [])
|
|
11
|
+
.filter((asset) => asset.inventoryId === choice.inventoryId)
|
|
12
|
+
.map((asset) => ({ page, asset })));
|
|
13
|
+
if (matches.length !== 1) {
|
|
14
|
+
throw new Error(matches.length === 0
|
|
15
|
+
? `Hosted plan chose unknown brand asset ${choice.inventoryId}.`
|
|
16
|
+
: `Hosted plan chose ambiguous brand asset ${choice.inventoryId}.`);
|
|
17
|
+
}
|
|
18
|
+
const { page, asset } = matches[0];
|
|
19
|
+
if (asset.pageId !== page.id) {
|
|
20
|
+
throw new Error(`Captured brand asset ${asset.inventoryId} belongs to ${asset.pageId}, not ${page.id}.`);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
inventoryId: asset.inventoryId,
|
|
24
|
+
pageId: asset.pageId,
|
|
25
|
+
sourceUrl: asset.sourceUrl,
|
|
26
|
+
inlineSvg: asset.inlineSvg,
|
|
27
|
+
bytesPath: asset.bytesPath,
|
|
28
|
+
sha256: asset.sha256,
|
|
29
|
+
mediaType: asset.mediaType,
|
|
30
|
+
width: asset.width,
|
|
31
|
+
height: asset.height,
|
|
32
|
+
captureBox: [...asset.captureBox],
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=redesign-pinned-asset.js.map
|