@juangadm/pre-post 1.1.0 → 1.3.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.
Files changed (51) hide show
  1. package/README.md +123 -7
  2. package/dist/baseline.d.ts +183 -0
  3. package/dist/baseline.d.ts.map +1 -1
  4. package/dist/baseline.js +485 -16
  5. package/dist/baseline.js.map +1 -1
  6. package/dist/bin/cli.js +28 -2
  7. package/dist/bin/cli.js.map +1 -1
  8. package/dist/browser.d.ts +7 -2
  9. package/dist/browser.d.ts.map +1 -1
  10. package/dist/browser.js +66 -5
  11. package/dist/browser.js.map +1 -1
  12. package/dist/commands/doctor.d.ts.map +1 -1
  13. package/dist/commands/doctor.js +2 -3
  14. package/dist/commands/doctor.js.map +1 -1
  15. package/dist/commands/pr.d.ts +13 -1
  16. package/dist/commands/pr.d.ts.map +1 -1
  17. package/dist/commands/pr.js +158 -59
  18. package/dist/commands/pr.js.map +1 -1
  19. package/dist/comparison.d.ts +9 -0
  20. package/dist/comparison.d.ts.map +1 -1
  21. package/dist/comparison.js +44 -16
  22. package/dist/comparison.js.map +1 -1
  23. package/dist/errors.d.ts +7 -0
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +7 -0
  26. package/dist/errors.js.map +1 -1
  27. package/dist/github.d.ts +34 -3
  28. package/dist/github.d.ts.map +1 -1
  29. package/dist/github.js +102 -11
  30. package/dist/github.js.map +1 -1
  31. package/dist/report.d.ts +7 -0
  32. package/dist/report.d.ts.map +1 -1
  33. package/dist/report.js +41 -6
  34. package/dist/report.js.map +1 -1
  35. package/dist/run.d.ts.map +1 -1
  36. package/dist/run.js +12 -4
  37. package/dist/run.js.map +1 -1
  38. package/dist/sheet.d.ts +24 -0
  39. package/dist/sheet.d.ts.map +1 -0
  40. package/dist/sheet.js +94 -0
  41. package/dist/sheet.js.map +1 -0
  42. package/dist/timings.d.ts +46 -0
  43. package/dist/timings.d.ts.map +1 -0
  44. package/dist/timings.js +108 -0
  45. package/dist/timings.js.map +1 -0
  46. package/dist/types.d.ts +41 -0
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/types.js +17 -0
  49. package/dist/types.js.map +1 -1
  50. package/package.json +1 -1
  51. package/skill/SKILL.md +21 -6
@@ -0,0 +1,24 @@
1
+ /**
2
+ * One image of everything a run found changed: a row per route and viewport,
3
+ * Pre beside Post, labelled.
4
+ *
5
+ * The PR description is where a reviewer on GitHub looks. An agent's user is
6
+ * often somewhere else — watching the session from a phone — and a folder of
7
+ * crops named `home-desktop-before-crop.png` is not something they can read
8
+ * there. A single labelled picture is. It is drawn by the capture browser, so
9
+ * the labels are real text and no image library is needed.
10
+ */
11
+ import { RouteCaptureOutcome } from './types.js';
12
+ /** Wide enough to read both sides, narrow enough for a phone to show whole. */
13
+ export declare const SHEET_WIDTH = 1200;
14
+ /** Rows beyond this are counted, not drawn: the sheet is a summary, the files are the record. */
15
+ export declare const MAX_SHEET_ROWS = 12;
16
+ /** The outcomes worth a row: a change, or a page only one side has. */
17
+ export declare function sheetRows(outcomes: RouteCaptureOutcome[]): RouteCaptureOutcome[];
18
+ export declare function sheetHtml(rows: RouteCaptureOutcome[]): string;
19
+ /**
20
+ * Draw the sheet into `outputDir/sheet.png`, or return null when nothing
21
+ * changed. Needs the shared browser, so call it before the run closes it.
22
+ */
23
+ export declare function buildSheet(outcomes: RouteCaptureOutcome[], outputDir: string): Promise<string | null>;
24
+ //# sourceMappingURL=sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../src/sheet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,+EAA+E;AAC/E,eAAO,MAAM,WAAW,OAAO,CAAC;AAChC,iGAAiG;AACjG,eAAO,MAAM,cAAc,KAAK,CAAC;AAIjC,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,mBAAmB,EAAE,GAAG,mBAAmB,EAAE,CAEhF;AA+BD,wBAAgB,SAAS,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAoB7D;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,mBAAmB,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgB3G"}
package/dist/sheet.js ADDED
@@ -0,0 +1,94 @@
1
+ /**
2
+ * One image of everything a run found changed: a row per route and viewport,
3
+ * Pre beside Post, labelled.
4
+ *
5
+ * The PR description is where a reviewer on GitHub looks. An agent's user is
6
+ * often somewhere else — watching the session from a phone — and a folder of
7
+ * crops named `home-desktop-before-crop.png` is not something they can read
8
+ * there. A single labelled picture is. It is drawn by the capture browser, so
9
+ * the labels are real text and no image library is needed.
10
+ */
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+ import { getBrowser } from './browser.js';
14
+ /** Wide enough to read both sides, narrow enough for a phone to show whole. */
15
+ export const SHEET_WIDTH = 1200;
16
+ /** Rows beyond this are counted, not drawn: the sheet is a summary, the files are the record. */
17
+ export const MAX_SHEET_ROWS = 12;
18
+ /** A full-page side is cut off below this many CSS px, so one long page cannot swamp the rest. */
19
+ const MAX_SIDE_HEIGHT = 1400;
20
+ /** The outcomes worth a row: a change, or a page only one side has. */
21
+ export function sheetRows(outcomes) {
22
+ return outcomes.filter(o => (o.status === 'changed' || o.status === 'added' || o.status === 'removed') && o.files);
23
+ }
24
+ function escapeHtml(s) {
25
+ return s.replace(/[&<>"]/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' })[c]);
26
+ }
27
+ function dataUri(file) {
28
+ if (!file || !fs.existsSync(file))
29
+ return null;
30
+ return `data:image/png;base64,${fs.readFileSync(file).toString('base64')}`;
31
+ }
32
+ function side(label, file, missing) {
33
+ const src = dataUri(file);
34
+ const body = src ? `<div class="clip"><img src="${src}"></div>` : `<div class="missing">${missing}</div>`;
35
+ return `<div class="side"><div class="label">${label}</div>${body}</div>`;
36
+ }
37
+ function row(o) {
38
+ const files = o.files;
39
+ // The crops are what the PR shows first: the changed region, both sides cut
40
+ // to the same box. Without them (a page one side lacks) the full page is it.
41
+ const crops = Boolean(files.cropBefore && files.cropAfter);
42
+ const pre = crops ? files.cropBefore : files.before;
43
+ const post = crops ? files.cropAfter : files.after;
44
+ const tag = o.status === 'added' ? ' · new page' : o.status === 'removed' ? ' · removed' : '';
45
+ return `<section>
46
+ <h2>${escapeHtml(o.route)} <span>${escapeHtml(o.viewport)}${tag}</span></h2>
47
+ <div class="pair">${side('Pre', pre, 'No page on Pre')}${side('Post', post, 'No page on Post')}</div>
48
+ </section>`;
49
+ }
50
+ export function sheetHtml(rows) {
51
+ const shown = rows.slice(0, MAX_SHEET_ROWS);
52
+ const more = rows.length - shown.length;
53
+ return `<!doctype html><html><head><meta charset="utf-8"><style>
54
+ * { box-sizing: border-box; margin: 0; }
55
+ body { width: ${SHEET_WIDTH}px; padding: 16px; background: #fff; color: #111; font: 15px/1.4 -apple-system, "Segoe UI", Helvetica, Arial, sans-serif; }
56
+ section { padding: 12px 0 20px; border-bottom: 1px solid #e5e5e5; }
57
+ section:last-of-type { border-bottom: 0; }
58
+ h2 { font-size: 18px; font-weight: 600; margin-bottom: 8px; }
59
+ h2 span { font-weight: 400; color: #666; }
60
+ .pair { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
61
+ .label { font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: #555; margin-bottom: 4px; }
62
+ .clip { max-height: ${MAX_SIDE_HEIGHT}px; overflow: hidden; border: 1px solid #ddd; }
63
+ img { display: block; width: 100%; }
64
+ .missing { padding: 48px 0; text-align: center; color: #888; border: 1px dashed #ccc; }
65
+ footer { padding-top: 12px; color: #666; }
66
+ </style></head><body>
67
+ ${shown.map(row).join('\n')}
68
+ ${more > 0 ? `<footer>+${more} more not shown here; every image is in the run's folder.</footer>` : ''}
69
+ </body></html>`;
70
+ }
71
+ /**
72
+ * Draw the sheet into `outputDir/sheet.png`, or return null when nothing
73
+ * changed. Needs the shared browser, so call it before the run closes it.
74
+ */
75
+ export async function buildSheet(outcomes, outputDir) {
76
+ const rows = sheetRows(outcomes);
77
+ if (!rows.length)
78
+ return null;
79
+ const browser = await getBrowser();
80
+ // A full-page shot is never shorter than the viewport, so a short one keeps
81
+ // a one-row sheet from trailing a band of empty white.
82
+ const ctx = await browser.newContext({ viewport: { width: SHEET_WIDTH, height: 100 }, deviceScaleFactor: 1 });
83
+ try {
84
+ const page = await ctx.newPage();
85
+ await page.setContent(sheetHtml(rows), { waitUntil: 'load' });
86
+ const file = path.join(outputDir, 'sheet.png');
87
+ await page.screenshot({ path: file, fullPage: true });
88
+ return file;
89
+ }
90
+ finally {
91
+ await ctx.close();
92
+ }
93
+ }
94
+ //# sourceMappingURL=sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../src/sheet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Where a run's wall clock went, one named step at a time.
3
+ *
4
+ * A run is only "slow" in the aggregate until something says which step ate
5
+ * the time; this is that something. Steps come in three kinds, and the summary
6
+ * keeps them apart so its numbers add up:
7
+ *
8
+ * - main steps, one after another, which sum to the total;
9
+ * - dotted steps (`pre.boot`, `post.boot`), which ran inside a main step as
10
+ * side-by-side lanes, and so are part of that step's time, not extra to it;
11
+ * - background steps (the browser download), which overlapped the main line.
12
+ */
13
+ export interface StepOptions {
14
+ /** Ran alongside the main line rather than on it. */
15
+ background?: boolean;
16
+ /** Lane prefixes (`pre`, `post`) whose dotted steps ran inside this one. */
17
+ contains?: string[];
18
+ }
19
+ /**
20
+ * Each duration in tenths of a second, rounded so the tenths sum to the
21
+ * rounded total (largest remainder first).
22
+ */
23
+ export declare function sumPreservingTenths(ms: number[]): number[];
24
+ export declare class Stopwatch {
25
+ private readonly steps;
26
+ private readonly background;
27
+ /** Lane prefix → the main step it ran inside. */
28
+ private readonly parents;
29
+ /** Record `ms` against `name`, adding to anything already recorded there. */
30
+ add(name: string, ms: number, opts?: StepOptions): void;
31
+ /** Time a promise under `name`, whether it resolves or throws. */
32
+ time<T>(name: string, work: Promise<T> | (() => Promise<T>), opts?: StepOptions): Promise<T>;
33
+ toJSON(): Record<string, number>;
34
+ /**
35
+ * Lines for the log, e.g.
36
+ *
37
+ * Total 14.9s = github 0.3s + resolve 9.2s + capture 1.9s + other 3.5s
38
+ * inside resolve 9.2s, side by side: pre checkout 0.0s → boot 4.5s (4.5s) ‖ post boot 2.1s (2.1s)
39
+ * alongside: browser 0.6s
40
+ *
41
+ * With `totalMs`, the first line always sums to it: whatever no step
42
+ * recorded is shown as `other` rather than left for the reader to find.
43
+ */
44
+ summary(totalMs?: number): string[];
45
+ }
46
+ //# sourceMappingURL=timings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timings.d.ts","sourceRoot":"","sources":["../src/timings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAW1D;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD,6EAA6E;IAC7E,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,IAAI;IAM3D,kEAAkE;IAC5D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;IAStG,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIhC;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;CAwCpC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Where a run's wall clock went, one named step at a time.
3
+ *
4
+ * A run is only "slow" in the aggregate until something says which step ate
5
+ * the time; this is that something. Steps come in three kinds, and the summary
6
+ * keeps them apart so its numbers add up:
7
+ *
8
+ * - main steps, one after another, which sum to the total;
9
+ * - dotted steps (`pre.boot`, `post.boot`), which ran inside a main step as
10
+ * side-by-side lanes, and so are part of that step's time, not extra to it;
11
+ * - background steps (the browser download), which overlapped the main line.
12
+ */
13
+ const secs = (ms) => `${(ms / 1000).toFixed(1)}s`;
14
+ /**
15
+ * Each duration in tenths of a second, rounded so the tenths sum to the
16
+ * rounded total (largest remainder first).
17
+ */
18
+ export function sumPreservingTenths(ms) {
19
+ const exact = ms.map(m => m / 100);
20
+ const floors = exact.map(Math.floor);
21
+ let left = Math.round(exact.reduce((sum, e) => sum + e, 0)) - floors.reduce((sum, f) => sum + f, 0);
22
+ const order = exact.map((e, i) => i).sort((a, b) => (exact[b] - floors[b]) - (exact[a] - floors[a]));
23
+ for (const i of order) {
24
+ if (left <= 0)
25
+ break;
26
+ floors[i]++;
27
+ left--;
28
+ }
29
+ return floors;
30
+ }
31
+ export class Stopwatch {
32
+ steps = new Map();
33
+ background = new Set();
34
+ /** Lane prefix → the main step it ran inside. */
35
+ parents = new Map();
36
+ /** Record `ms` against `name`, adding to anything already recorded there. */
37
+ add(name, ms, opts = {}) {
38
+ this.steps.set(name, (this.steps.get(name) ?? 0) + Math.max(0, Math.round(ms)));
39
+ if (opts.background)
40
+ this.background.add(name);
41
+ for (const prefix of opts.contains ?? [])
42
+ this.parents.set(prefix, name);
43
+ }
44
+ /** Time a promise under `name`, whether it resolves or throws. */
45
+ async time(name, work, opts = {}) {
46
+ const start = Date.now();
47
+ try {
48
+ return await (typeof work === 'function' ? work() : work);
49
+ }
50
+ finally {
51
+ this.add(name, Date.now() - start, opts);
52
+ }
53
+ }
54
+ toJSON() {
55
+ return Object.fromEntries(this.steps);
56
+ }
57
+ /**
58
+ * Lines for the log, e.g.
59
+ *
60
+ * Total 14.9s = github 0.3s + resolve 9.2s + capture 1.9s + other 3.5s
61
+ * inside resolve 9.2s, side by side: pre checkout 0.0s → boot 4.5s (4.5s) ‖ post boot 2.1s (2.1s)
62
+ * alongside: browser 0.6s
63
+ *
64
+ * With `totalMs`, the first line always sums to it: whatever no step
65
+ * recorded is shown as `other` rather than left for the reader to find.
66
+ */
67
+ summary(totalMs) {
68
+ const entries = [...this.steps];
69
+ const main = entries.filter(([name]) => !name.includes('.') && !this.background.has(name));
70
+ const shown = new Map(main);
71
+ let first = main.map(([name, ms]) => `${name} ${secs(ms)}`).join(' + ');
72
+ if (totalMs !== undefined) {
73
+ const other = Math.max(0, totalMs - main.reduce((sum, [, ms]) => sum + ms, 0));
74
+ const items = [...main, ['other', other]];
75
+ // Rounded together, not one by one: three 349ms steps each read 0.3s and
76
+ // would sum to 0.9s under a 1.0s total, the mismatch this line exists to end.
77
+ const tenths = sumPreservingTenths(items.map(([, ms]) => ms));
78
+ const total = tenths.reduce((sum, t) => sum + t, 0);
79
+ items.forEach(([name], i) => shown.set(name, tenths[i] * 100));
80
+ first = `Total ${secs(total * 100)} = ${items.map(([name]) => `${name} ${secs(shown.get(name))}`).join(' + ')}`;
81
+ }
82
+ const lines = [first];
83
+ // Group dotted steps into lanes, and lanes under the step that held them.
84
+ const lanes = new Map();
85
+ for (const [name, ms] of entries) {
86
+ if (!name.includes('.'))
87
+ continue;
88
+ const prefix = name.slice(0, name.indexOf('.'));
89
+ lanes.set(prefix, [...(lanes.get(prefix) ?? []), [name.slice(prefix.length + 1), ms]]);
90
+ }
91
+ const byParent = new Map();
92
+ for (const [prefix, steps] of lanes) {
93
+ const parent = this.parents.get(prefix) ?? '';
94
+ const total = steps.reduce((sum, [, ms]) => sum + ms, 0);
95
+ const lane = `${prefix} ${steps.map(([name, ms]) => `${name} ${secs(ms)}`).join(' → ')} (${secs(total)})`;
96
+ byParent.set(parent, [...(byParent.get(parent) ?? []), lane]);
97
+ }
98
+ for (const [parent, laneTexts] of byParent) {
99
+ const held = parent && this.steps.has(parent) ? `inside ${parent} ${secs(shown.get(parent) ?? this.steps.get(parent))}, side by side` : 'nested';
100
+ lines.push(` ${held}: ${laneTexts.join(' ‖ ')}`);
101
+ }
102
+ const background = entries.filter(([name]) => this.background.has(name));
103
+ if (background.length)
104
+ lines.push(` alongside: ${background.map(([name, ms]) => `${name} ${secs(ms)}`).join(', ')}`);
105
+ return lines;
106
+ }
107
+ }
108
+ //# sourceMappingURL=timings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timings.js","sourceRoot":"","sources":["../src/timings.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -164,6 +164,12 @@ export interface PrePostConfig {
164
164
  assetsBranch?: string;
165
165
  /** Skip paths (glob-ish prefixes) from route detection */
166
166
  ignore?: string[];
167
+ /**
168
+ * Command run in the app directory between the install and the dev server
169
+ * when the baseline is built from source — a workspace build, a codegen
170
+ * step. Inferred for a turborepo when omitted.
171
+ */
172
+ baselineSetup?: string;
167
173
  }
168
174
  /** Pre, post, and (when there was a change) diff and crop images, as local paths or URLs. */
169
175
  export interface ArtifactSet {
@@ -176,6 +182,18 @@ export interface ArtifactSet {
176
182
  cropAfter?: string;
177
183
  }
178
184
  export declare const ARTIFACT_KINDS: readonly ["before", "after", "diff", "cropBefore", "cropAfter"];
185
+ export type ArtifactKind = typeof ARTIFACT_KINDS[number];
186
+ /**
187
+ * The filename segment for an artifact kind, e.g. `home-desktop-<segment>.png`.
188
+ *
189
+ * One mapping, because two of them is what went wrong: the capture wrote
190
+ * `-pre`/`-post` while the assets branch published `-before`/`-after`, so the
191
+ * file on disk and the image in the PR had different names for the same
192
+ * screenshot. Renaming the literals on one side would only have moved the
193
+ * seam — the crops would still have been `-before-crop` locally and
194
+ * `-cropBefore` published.
195
+ */
196
+ export declare function artifactSuffix(kind: ArtifactKind): string;
179
197
  export interface RouteCaptureOutcome {
180
198
  route: string;
181
199
  /** Route actually requested (after sample substitution) */
@@ -220,11 +238,15 @@ export interface RouteShift {
220
238
  px: number;
221
239
  /** Whether anything changed beyond the move, judged by the same rule as any other capture. */
222
240
  otherChange: boolean;
241
+ /** Changed share once the move is undone; `changedRatio` is the raw figure. */
242
+ residualRatio: number;
223
243
  }
224
244
  export interface PrRunResult {
225
245
  repo: string;
226
246
  prNumber?: number;
227
247
  commentUrl?: string;
248
+ /** Whether `commentUrl` points at the PR description or at a comment. */
249
+ commentKind?: 'description' | 'comment';
228
250
  beforeBase: string;
229
251
  afterBase: string;
230
252
  outcomes: RouteCaptureOutcome[];
@@ -233,5 +255,24 @@ export interface PrRunResult {
233
255
  markdown: string;
234
256
  /** Local directory holding every captured file */
235
257
  outputDir: string;
258
+ /** One labelled image of every change, Pre beside Post, when anything changed */
259
+ sheetPath?: string;
260
+ /** Milliseconds spent in each named step of the run; steps can overlap. */
261
+ timings?: Record<string, number>;
262
+ /** Whether GitHub took the result, and if not, the one sentence that would let it. */
263
+ delivery?: Delivery;
264
+ }
265
+ /**
266
+ * What happened to a run's result on GitHub.
267
+ *
268
+ * - `published`: GitHub accepted writes; `commentUrl` says whether a PR was updated.
269
+ * - `dry-run`: nothing was written, as asked.
270
+ * - `no-pr`: `--require-pr` found no open PR, so nothing was done.
271
+ * - `skipped`: the screenshots were taken but GitHub would not take them;
272
+ * `hint` is the one thing a human must do. The CLI exits 3 after printing.
273
+ */
274
+ export interface Delivery {
275
+ status: 'published' | 'dry-run' | 'skipped' | 'no-pr';
276
+ hint?: string;
236
277
  }
237
278
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -7,4 +7,21 @@ export const VIEWPORT_PRESETS = {
7
7
  mobile: { width: 375, height: 812 },
8
8
  };
9
9
  export const ARTIFACT_KINDS = ['before', 'after', 'diff', 'cropBefore', 'cropAfter'];
10
+ /**
11
+ * The filename segment for an artifact kind, e.g. `home-desktop-<segment>.png`.
12
+ *
13
+ * One mapping, because two of them is what went wrong: the capture wrote
14
+ * `-pre`/`-post` while the assets branch published `-before`/`-after`, so the
15
+ * file on disk and the image in the PR had different names for the same
16
+ * screenshot. Renaming the literals on one side would only have moved the
17
+ * seam — the crops would still have been `-before-crop` locally and
18
+ * `-cropBefore` published.
19
+ */
20
+ export function artifactSuffix(kind) {
21
+ switch (kind) {
22
+ case 'cropBefore': return 'before-crop';
23
+ case 'cropAfter': return 'after-crop';
24
+ default: return kind;
25
+ }
26
+ }
10
27
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,WAAW;AACX,+DAA+D;AAW/D,MAAM,CAAC,MAAM,gBAAgB,GAAyC;IACpE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IACrC,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IACpC,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;CACpC,CAAC;AAmMF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,CAAU,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,WAAW;AACX,+DAA+D;AAW/D,MAAM,CAAC,MAAM,gBAAgB,GAAyC;IACpE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IACrC,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IACpC,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;CACpC,CAAC;AAyMF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,CAAU,CAAC;AAI9F;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,IAAkB;IAC/C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,YAAY,CAAC,CAAC,OAAO,aAAa,CAAC;QACxC,KAAK,WAAW,CAAC,CAAC,OAAO,YAAY,CAAC;QACtC,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC;IACvB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juangadm/pre-post",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Before/after screenshots for pull requests: detect changed routes, capture, pixel-diff, and post a sticky PR comment",
5
5
  "author": "Juan Gabriel Delgado (forked from James Clements)",
6
6
  "license": "MIT",
package/skill/SKILL.md CHANGED
@@ -42,7 +42,9 @@ the Post side. Pass `--no-local-baseline` to turn it off.
42
42
  npx -y @juangadm/pre-post@latest pr
43
43
  ```
44
44
 
45
- Add `--routes /a,/b` when the user names pages explicitly. Add
45
+ If you have a folder the user can open from wherever they are following you (a scratchpad
46
+ or workspace directory in a hosted session), add `-o <that folder>/pre-post` so the images
47
+ land somewhere they can see. Add `--routes /a,/b` when the user names pages explicitly. Add
46
48
  `--before https://production-url` only if the run reports it cannot work out the baseline
47
49
  (it is then saved to `.pre-post.json` for next time).
48
50
 
@@ -53,16 +55,26 @@ re-runs replace in place — the author's own text is never touched. If the PR c
53
55
  edited (a fork, a read-only token) it falls back to a single sticky comment.
54
56
 
55
57
  Each changed route shows **Pre beside Post**, per viewport, full pages in a `<details>`. No
56
- overlay, no percentage. A page that moved says `Content shifted down 48px`; relay as written.
58
+ overlay, no percentage. A page that moved says `Content shifted down 48px`; relay as written. A pure move
59
+ ("Nothing else changed.") shows the full pages with no crop and no `<details>`, by design.
60
+
61
+ ## Show the user
62
+
63
+ When anything changed, the command prints `Sheet: <path>`: one image with Pre beside Post for
64
+ every change. If you can send files to the user, send that one file, even when the PR was
65
+ updated. Someone following you from a phone sees it there before they open GitHub.
57
66
 
58
67
  ## Rules
59
68
 
60
- - Run the command once. Do not open, read, or describe the screenshot files; the PR
61
- comment is the deliverable. Report the summary the command prints, plus the comment link.
69
+ - Run the command once. Do not open, read, or describe the screenshot files. The PR
70
+ comment is the deliverable, and the sheet is the one image you pass along. Report the
71
+ summary the command prints, plus the comment link.
62
72
  - Do not switch branches, start dev servers, or use a browser tool yourself. The command
63
73
  handles all three.
64
- - Exit code 3 means a human must do one thing (log in, start the dev server, pass
65
- `--before`). Relay that one sentence verbatim and stop.
74
+ - Exit code 3 means a human must do one thing (set a token, start the dev server, pass
75
+ `--before`). Relay that one sentence verbatim and stop. If GitHub refused the token, the
76
+ screenshots were still taken: send the sheet first, then relay the sentence. Never ask the
77
+ user to paste a token into the chat; the sentence names where it goes.
66
78
  - Do not use `--dry-run` unless the user asks to preview without posting.
67
79
  - If the summary lists routes that "need a sample URL", ask the user for one example URL per
68
80
  dynamic route and add it under `"samples"` in `.pre-post.json`, then re-run.
@@ -78,5 +90,8 @@ overlay, no percentage. A page that moved says `Content shifted down 48px`; rela
78
90
  | `--dry-run` | Preview locally, post nothing |
79
91
  | `--header k=v` / `--cookie k=v` | The site needs auth headers or cookies |
80
92
 
93
+ To run on every PR without anyone invoking it, point the user to the README's GitHub Action
94
+ section. It posts with GitHub's own token, which also covers work done in cloud sessions.
95
+
81
96
  Login-protected sites: `npx -y @juangadm/pre-post@latest login https://site` opens a browser
82
97
  once; the saved session is reused automatically.