@letterstory/cli 0.176.77 → 0.176.78
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/lib/cli.mjs +1 -1
- package/lib/commands/replicate.mjs +24 -0
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -85,7 +85,7 @@ import {
|
|
|
85
85
|
import { fetchParkedSections, withoutParked } from "./parked.mjs";
|
|
86
86
|
|
|
87
87
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
88
|
-
export const VERSION = "0.176.
|
|
88
|
+
export const VERSION = "0.176.78";
|
|
89
89
|
|
|
90
90
|
/** The exit code for a gate refusal (CARD_REQUIRED, PAYMENT_FAILED, OUT_OF_TOKENS): 1 is a plain error. */
|
|
91
91
|
export const EXIT_PAYMENT_REQUIRED = 3;
|
|
@@ -107,6 +107,7 @@ function headline(x) {
|
|
|
107
107
|
` ${x.summary.replicated} of ${x.summary.pages} pages replicated; ${x.summary.passing} match the original at every width (mean ${pct(x.summary.meanPixel)})`,
|
|
108
108
|
]
|
|
109
109
|
: []),
|
|
110
|
+
...motionLines(x.motion),
|
|
110
111
|
...(x.agent_pass
|
|
111
112
|
? [
|
|
112
113
|
` Agent pass: ${x.agent_pass.model}, $${x.agent_pass.cost_usd.toFixed(2)} of $${x.agent_pass.budget_usd.toFixed(2)} spent`,
|
|
@@ -134,6 +135,24 @@ function headline(x) {
|
|
|
134
135
|
];
|
|
135
136
|
}
|
|
136
137
|
|
|
138
|
+
const TRIGGERS = ["load", "scroll", "hover", "loop"];
|
|
139
|
+
|
|
140
|
+
// Motion: what moves on the original against the replica, beside the still scores (never the bar).
|
|
141
|
+
function motionLines(m) {
|
|
142
|
+
if (!m) return [];
|
|
143
|
+
const found = TRIGGERS.reduce((s, t) => s + m.found[t], 0);
|
|
144
|
+
const reproduced = TRIGGERS.reduce((s, t) => s + m.reproduced[t], 0);
|
|
145
|
+
return [
|
|
146
|
+
` Motion ${reproduced} of ${found} animations reproduced (${TRIGGERS.map((t) => `${t} ${m.reproduced[t]}/${m.found[t]}`).join(", ")})${m.mean_score !== null ? `, frames ${pct(m.mean_score)}` : ""}${m.not_measured ? `; ${m.not_measured} page(s) not measured` : ""}`,
|
|
147
|
+
...m.gaps
|
|
148
|
+
.slice(0, 8)
|
|
149
|
+
.map(
|
|
150
|
+
(g) =>
|
|
151
|
+
` ${g.issue}: ${g.trigger} "${g.element}" (${g.what}) on ${g.pages} page${g.pages === 1 ? "" : "s"}, e.g. ${g.example}`
|
|
152
|
+
),
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
|
|
137
156
|
// The staging link: the replica live on a Letter domain, to share before (or without) a repo.
|
|
138
157
|
function previewLines(x) {
|
|
139
158
|
if (x.staging_url)
|
|
@@ -175,6 +194,11 @@ function replicationDetail(ctx, result) {
|
|
|
175
194
|
lines.push(` ${s.viewport}: "${worst.label}" ${pct(worst.pixel)}`);
|
|
176
195
|
}
|
|
177
196
|
if (p.refined) lines.push(` changed by the agent pass: ${p.refined}`);
|
|
197
|
+
if (p.motion?.error) lines.push(` motion not measured: ${p.motion.error}`);
|
|
198
|
+
for (const g of p.motion?.gaps ?? [])
|
|
199
|
+
lines.push(
|
|
200
|
+
` motion ${g.viewport} ${g.trigger} ${g.issue}: "${g.element}" ${g.what}${g.score !== null ? ` (${pct(g.score)})` : ""}`
|
|
201
|
+
);
|
|
178
202
|
}
|
|
179
203
|
}
|
|
180
204
|
if (r.dropped?.length)
|