hyperframes 0.7.41 → 0.7.43
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 +5 -2
- package/dist/cli.js +1808 -795
- package/dist/commands/contrast-audit.browser.js +51 -25
- package/dist/docker/Dockerfile.render +29 -23
- package/dist/hyperframe-runtime.js +26 -26
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +26 -26
- package/dist/skills/hyperframes/SKILL.md +19 -10
- package/dist/studio/assets/{index-DRrNf6k_.js → index-C-0DP25T.js} +3 -3
- package/dist/studio/assets/{index-BCG-TnJO.js → index-Dqugm4lQ.js} +1 -1
- package/dist/studio/assets/{index-rnqIbAs_.js → index-Drb3FuD6.js} +1 -1
- package/dist/studio/index.html +1 -1
- package/dist/templates/_shared/AGENTS.md +5 -2
- package/dist/templates/_shared/CLAUDE.md +5 -2
- package/package.json +2 -2
|
@@ -154,35 +154,61 @@ window.__contrastAudit = async function (imgBase64, time) {
|
|
|
154
154
|
var fg = parseColor(cs.color);
|
|
155
155
|
if (fg[3] <= 0.01) continue;
|
|
156
156
|
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
var
|
|
166
|
-
|
|
167
|
-
var
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
sample(x, y1);
|
|
175
|
-
}
|
|
176
|
-
for (var y = y0; y <= y1; y++) {
|
|
177
|
-
sample(x0, y);
|
|
178
|
-
sample(x1, y);
|
|
157
|
+
// Prefer an opaque own/ancestor background-color over the pixel ring. A
|
|
158
|
+
// caption/CTA that paints its OWN solid background (a pill, a button, a
|
|
159
|
+
// card) composites its text over THAT color, not over whatever surrounds
|
|
160
|
+
// the box. Sampling the ring there measured the text against the scene
|
|
161
|
+
// behind the element (often a dark photo) and reported false ~1:1 warnings
|
|
162
|
+
// for perfectly readable CTAs. Walk up until a fully-opaque background-color
|
|
163
|
+
// is found; stop and defer to the ring on the first background-image (text
|
|
164
|
+
// over real pixels). Keep this in sync with commands/contrast-bg.ts.
|
|
165
|
+
var ownBg = null;
|
|
166
|
+
for (var bn = el; bn && bn !== document.body; bn = bn.parentElement) {
|
|
167
|
+
var bcs = getComputedStyle(bn);
|
|
168
|
+
if (bcs.backgroundImage && bcs.backgroundImage !== "none") break;
|
|
169
|
+
var bc = parseColor(bcs.backgroundColor);
|
|
170
|
+
if (bc[3] >= 0.999) {
|
|
171
|
+
ownBg = [bc[0], bc[1], bc[2]];
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
179
174
|
}
|
|
180
175
|
|
|
181
|
-
|
|
176
|
+
var bgR, bgG, bgB;
|
|
177
|
+
if (ownBg) {
|
|
178
|
+
bgR = ownBg[0];
|
|
179
|
+
bgG = ownBg[1];
|
|
180
|
+
bgB = ownBg[2];
|
|
181
|
+
} else {
|
|
182
|
+
// Sample 4px ring outside bbox for background color
|
|
183
|
+
var rr = [],
|
|
184
|
+
gg = [],
|
|
185
|
+
bb = [];
|
|
186
|
+
var x0 = Math.max(0, Math.floor(rect.x) - 4);
|
|
187
|
+
var x1 = Math.min(w - 1, Math.ceil(rect.x + rect.width) + 4);
|
|
188
|
+
var y0 = Math.max(0, Math.floor(rect.y) - 4);
|
|
189
|
+
var y1 = Math.min(h - 1, Math.ceil(rect.y + rect.height) + 4);
|
|
190
|
+
var sample = function (sx, sy) {
|
|
191
|
+
if (sx < 0 || sx >= w || sy < 0 || sy >= h) return;
|
|
192
|
+
var idx = (sy * w + sx) * 4;
|
|
193
|
+
rr.push(px[idx]);
|
|
194
|
+
gg.push(px[idx + 1]);
|
|
195
|
+
bb.push(px[idx + 2]);
|
|
196
|
+
};
|
|
197
|
+
for (var x = x0; x <= x1; x++) {
|
|
198
|
+
sample(x, y0);
|
|
199
|
+
sample(x, y1);
|
|
200
|
+
}
|
|
201
|
+
for (var y = y0; y <= y1; y++) {
|
|
202
|
+
sample(x0, y);
|
|
203
|
+
sample(x1, y);
|
|
204
|
+
}
|
|
182
205
|
|
|
183
|
-
|
|
184
|
-
|
|
206
|
+
if (rr.length === 0) continue;
|
|
207
|
+
|
|
208
|
+
bgR = median(rr);
|
|
209
|
+
bgG = median(gg);
|
|
185
210
|
bgB = median(bb);
|
|
211
|
+
}
|
|
186
212
|
|
|
187
213
|
// Composite foreground alpha over measured background
|
|
188
214
|
var compR = Math.round(fg[0] * fg[3] + bgR * (1 - fg[3]));
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
FROM node:22-bookworm-slim
|
|
2
2
|
|
|
3
3
|
ARG HYPERFRAMES_VERSION=latest
|
|
4
|
-
# Set automatically by `docker build --platform` (BuildKit);
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# Set automatically by `docker build --platform` (BuildKit); selects the
|
|
5
|
+
# chrome-headless-shell source below (chrome-for-testing ships linux64 only,
|
|
6
|
+
# see https://googlechromelabs.github.io/chrome-for-testing/).
|
|
7
7
|
ARG TARGETARCH=amd64
|
|
8
|
+
# Pinned Playwright release used to fetch a known-good, arch-native
|
|
9
|
+
# chrome-headless-shell on arm64. chrome-for-testing publishes no linux-arm64
|
|
10
|
+
# build, so arm64 used to fall back to Debian's *unpinned, rolling* `chromium`
|
|
11
|
+
# package — whose bookworm arm64 build SIGTRAPs at startup (exit 133), breaking
|
|
12
|
+
# every containerized render (issue #2039). Playwright ships a pinned
|
|
13
|
+
# linux-arm64 headless-shell (Google's build, not Debian's). Bump deliberately.
|
|
14
|
+
ARG PLAYWRIGHT_VERSION=1.61.1
|
|
8
15
|
|
|
9
16
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
10
17
|
ca-certificates curl unzip ffmpeg chromium \
|
|
@@ -20,37 +27,36 @@ ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
|
|
20
27
|
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
|
|
21
28
|
ENV CONTAINER=true
|
|
22
29
|
|
|
23
|
-
# chrome-headless-shell unlocks BeginFrame-based deterministic capture
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
30
|
+
# chrome-headless-shell unlocks BeginFrame-based deterministic capture. Install
|
|
31
|
+
# it on both arches from a pinned source so a build can never silently pick up a
|
|
32
|
+
# broken browser update:
|
|
33
|
+
# amd64 -> chrome-for-testing (linux64) via @puppeteer/browsers
|
|
34
|
+
# arm64 -> Playwright's pinned linux-arm64 headless-shell (chrome-for-testing
|
|
35
|
+
# has no arm64 build; Debian's rolling `chromium` SIGTRAPs — #2039)
|
|
36
|
+
# The wrapper script below wires whichever binary landed into
|
|
37
|
+
# PRODUCER_HEADLESS_SHELL_PATH, or fails the build loudly if neither did.
|
|
28
38
|
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
|
29
39
|
npx --yes @puppeteer/browsers install chrome-headless-shell@stable \
|
|
30
40
|
--path /root/.cache/puppeteer; \
|
|
31
41
|
else \
|
|
32
|
-
|
|
42
|
+
npx --yes playwright-core@${PLAYWRIGHT_VERSION} install chromium-headless-shell; \
|
|
33
43
|
fi
|
|
34
44
|
|
|
35
45
|
RUN npm install -g hyperframes@${HYPERFRAMES_VERSION}
|
|
36
46
|
|
|
37
|
-
# Wrapper script: resolves chrome-headless-shell path
|
|
38
|
-
#
|
|
39
|
-
# chrome-headless-shell
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# golden-baseline regressions.
|
|
46
|
-
RUN SHELL_PATH=$(find /root/.cache/puppeteer/chrome-headless-shell -name "chrome-headless-shell" -type f 2>/dev/null | head -1); \
|
|
47
|
+
# Wrapper script: resolves the chrome-headless-shell path installed above and
|
|
48
|
+
# exports it as PRODUCER_HEADLESS_SHELL_PATH so the engine uses BeginFrame
|
|
49
|
+
# rendering. @puppeteer/browsers names the binary `chrome-headless-shell`;
|
|
50
|
+
# Playwright names it `headless_shell` — match either, in either cache dir.
|
|
51
|
+
# If neither is present the browser install step failed: fail the build loudly
|
|
52
|
+
# rather than silently downgrading to the (arm64-broken) Debian chromium.
|
|
53
|
+
RUN SHELL_PATH=$(find /root/.cache/puppeteer /root/.cache/ms-playwright \
|
|
54
|
+
\( -name "chrome-headless-shell" -o -name "headless_shell" \) -type f 2>/dev/null | head -1); \
|
|
47
55
|
if [ -n "$SHELL_PATH" ]; then \
|
|
48
56
|
printf '#!/bin/sh\nexport PRODUCER_HEADLESS_SHELL_PATH=%s\nexec hyperframes render "$@"\n' "$SHELL_PATH" > /usr/local/bin/hf-render; \
|
|
49
|
-
elif [ "$TARGETARCH" = "amd64" ]; then \
|
|
50
|
-
echo "ERROR: chrome-headless-shell binary not found on amd64 — @puppeteer/browsers install must have failed or moved its cache layout." >&2; \
|
|
51
|
-
exit 1; \
|
|
52
57
|
else \
|
|
53
|
-
|
|
58
|
+
echo "ERROR: chrome-headless-shell binary not found for ${TARGETARCH} — the browser install step above must have failed." >&2; \
|
|
59
|
+
exit 1; \
|
|
54
60
|
fi \
|
|
55
61
|
&& chmod +x /usr/local/bin/hf-render
|
|
56
62
|
|