@ytspar/sweetlink 1.16.1 → 1.18.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 (55) hide show
  1. package/claude-skills/screenshot/SKILL.md +2 -0
  2. package/dist/cli/sweetlink-dev.js +0 -0
  3. package/dist/cli/sweetlink.js +338 -29
  4. package/dist/cli/sweetlink.js.map +1 -1
  5. package/dist/daemon/browser.d.ts +12 -0
  6. package/dist/daemon/browser.d.ts.map +1 -1
  7. package/dist/daemon/browser.js +62 -12
  8. package/dist/daemon/browser.js.map +1 -1
  9. package/dist/daemon/cursor.d.ts.map +1 -1
  10. package/dist/daemon/cursor.js +39 -8
  11. package/dist/daemon/cursor.js.map +1 -1
  12. package/dist/daemon/devices.d.ts +9 -4
  13. package/dist/daemon/devices.d.ts.map +1 -1
  14. package/dist/daemon/devices.js +25 -4
  15. package/dist/daemon/devices.js.map +1 -1
  16. package/dist/daemon/diff.d.ts +6 -0
  17. package/dist/daemon/diff.d.ts.map +1 -1
  18. package/dist/daemon/diff.js +46 -26
  19. package/dist/daemon/diff.js.map +1 -1
  20. package/dist/daemon/index.js +0 -0
  21. package/dist/daemon/listeners.d.ts +8 -2
  22. package/dist/daemon/listeners.d.ts.map +1 -1
  23. package/dist/daemon/listeners.js +39 -6
  24. package/dist/daemon/listeners.js.map +1 -1
  25. package/dist/daemon/recording.d.ts +28 -3
  26. package/dist/daemon/recording.d.ts.map +1 -1
  27. package/dist/daemon/recording.js +159 -17
  28. package/dist/daemon/recording.js.map +1 -1
  29. package/dist/daemon/refs.d.ts.map +1 -1
  30. package/dist/daemon/refs.js +7 -2
  31. package/dist/daemon/refs.js.map +1 -1
  32. package/dist/daemon/server.d.ts.map +1 -1
  33. package/dist/daemon/server.js +326 -19
  34. package/dist/daemon/server.js.map +1 -1
  35. package/dist/daemon/session.d.ts +2 -0
  36. package/dist/daemon/session.d.ts.map +1 -1
  37. package/dist/daemon/summary.d.ts.map +1 -1
  38. package/dist/daemon/summary.js +57 -11
  39. package/dist/daemon/summary.js.map +1 -1
  40. package/dist/daemon/types.d.ts +1 -1
  41. package/dist/daemon/types.d.ts.map +1 -1
  42. package/dist/daemon/types.js.map +1 -1
  43. package/dist/daemon/viewer.d.ts +7 -0
  44. package/dist/daemon/viewer.d.ts.map +1 -1
  45. package/dist/daemon/viewer.js +12 -4
  46. package/dist/daemon/viewer.js.map +1 -1
  47. package/dist/daemon/visualDiff.d.ts +2 -0
  48. package/dist/daemon/visualDiff.d.ts.map +1 -1
  49. package/dist/daemon/visualDiff.js +61 -2
  50. package/dist/daemon/visualDiff.js.map +1 -1
  51. package/dist/ruler.d.ts +1 -1
  52. package/dist/ruler.d.ts.map +1 -1
  53. package/dist/ruler.js +53 -32
  54. package/dist/ruler.js.map +1 -1
  55. package/package.json +10 -11
@@ -11,13 +11,21 @@ function formatTimestamp(seconds) {
11
11
  return `${seconds.toFixed(1)}s`;
12
12
  }
13
13
  function formatDate(iso) {
14
+ // Emit ISO 8601 with timezone so the report is unambiguous when shared
15
+ // across machines/timezones. e.g. `2026-04-26T18:57:00-07:00`.
14
16
  const d = new Date(iso);
17
+ const pad = (n, w = 2) => String(n).padStart(w, '0');
15
18
  const year = d.getFullYear();
16
- const month = String(d.getMonth() + 1).padStart(2, '0');
17
- const day = String(d.getDate()).padStart(2, '0');
18
- const hours = String(d.getHours()).padStart(2, '0');
19
- const minutes = String(d.getMinutes()).padStart(2, '0');
20
- return `${year}-${month}-${day} ${hours}:${minutes}`;
19
+ const month = pad(d.getMonth() + 1);
20
+ const day = pad(d.getDate());
21
+ const hh = pad(d.getHours());
22
+ const mm = pad(d.getMinutes());
23
+ const ss = pad(d.getSeconds());
24
+ const tzMin = -d.getTimezoneOffset();
25
+ const tzSign = tzMin >= 0 ? '+' : '-';
26
+ const tzAbs = Math.abs(tzMin);
27
+ const tz = `${tzSign}${pad(Math.floor(tzAbs / 60))}:${pad(tzAbs % 60)}`;
28
+ return `${year}-${month}-${day}T${hh}:${mm}:${ss}${tz}`;
21
29
  }
22
30
  function statusCell(count, label) {
23
31
  if (count === 0)
@@ -28,9 +36,37 @@ function statusCell(count, label) {
28
36
  function escapeMarkdown(text) {
29
37
  return text.replace(/\|/g, '\\|').replace(/\n/g, ' ');
30
38
  }
39
+ /**
40
+ * Render the action arguments as a human-friendly description.
41
+ * - Ref-based actions (click @e2): show "@e2"
42
+ * - CSS-selector actions (click --selector=#cta): show "#cta"
43
+ * - Text-search actions (click --text=Submit): show ‟Submit"
44
+ * - Fill actions: show "@e2 ← \"value\""
45
+ */
31
46
  function formatActionDetails(entry) {
32
- const args = entry.args.map((a) => `"${a}"`).join(' ');
33
- return escapeMarkdown(args);
47
+ const args = entry.args;
48
+ if (args.length === 0)
49
+ return '';
50
+ // Ref form: ['@e2', value?]
51
+ const refArg = args.find((a) => /^@e\d+$/.test(a));
52
+ if (refArg) {
53
+ if (entry.action === 'fill' && args.length >= 2) {
54
+ const val = args[args.indexOf(refArg) + 1] ?? '';
55
+ return escapeMarkdown(`${refArg} ← "${val}"`);
56
+ }
57
+ return escapeMarkdown(refArg);
58
+ }
59
+ // CLI-flag form: ['--selector=#cta', '--full-page', ...]
60
+ const selectorFlag = args.find((a) => a.startsWith('--selector='));
61
+ if (selectorFlag) {
62
+ return escapeMarkdown(selectorFlag.slice('--selector='.length));
63
+ }
64
+ const textFlag = args.find((a) => a.startsWith('--text='));
65
+ if (textFlag) {
66
+ return escapeMarkdown(`"${textFlag.slice('--text='.length)}"`);
67
+ }
68
+ // Fallback: quote everything.
69
+ return escapeMarkdown(args.map((a) => `"${a}"`).join(' '));
34
70
  }
35
71
  // ============================================================================
36
72
  // Report Sections
@@ -38,12 +74,15 @@ function formatActionDetails(entry) {
38
74
  function renderMetadata(options) {
39
75
  const { manifest, gitBranch, gitCommit } = options;
40
76
  const lines = [
41
- '# Session Report',
77
+ `# Session Report${manifest.label ? `: ${manifest.label}` : ''}`,
42
78
  '',
43
79
  `**Date:** ${formatDate(manifest.startedAt)} `,
44
80
  `**Session:** ${manifest.sessionId} `,
45
81
  `**Duration:** ${formatTimestamp(manifest.duration)} `,
46
82
  ];
83
+ if (manifest.label) {
84
+ lines.push(`**Label:** ${manifest.label} `);
85
+ }
47
86
  if (manifest.url) {
48
87
  lines.push(`**URL:** ${manifest.url} `);
49
88
  }
@@ -52,6 +91,11 @@ function renderMetadata(options) {
52
91
  const commit = gitCommit ? ` @ ${gitCommit.slice(0, 7)}` : '';
53
92
  lines.push(`**Git:** ${branch}${commit} `);
54
93
  }
94
+ else {
95
+ // Surface the absence of git context — silently dropping it makes
96
+ // the session look reproducible when it isn't.
97
+ lines.push('**Git:** (not in a repository) ');
98
+ }
55
99
  return lines.join('\n');
56
100
  }
57
101
  function renderStatus(options) {
@@ -79,13 +123,15 @@ function renderTimeline(manifest) {
79
123
  const lines = [
80
124
  '## Action Timeline',
81
125
  '',
82
- '| Time | Action | Details |',
83
- '|------|--------|---------|',
126
+ '| Time | Action | Target | Took | Screenshot |',
127
+ '|------|--------|--------|------|------------|',
84
128
  ];
85
129
  for (const cmd of manifest.commands) {
86
130
  const time = formatTimestamp(cmd.timestamp);
87
131
  const details = formatActionDetails(cmd);
88
- lines.push(`| ${time} | ${cmd.action} | ${details} |`);
132
+ const took = cmd.duration > 0 ? `${cmd.duration}ms` : '—';
133
+ const shot = cmd.screenshot ? `[\`${cmd.screenshot}\`](${cmd.screenshot})` : '—';
134
+ lines.push(`| ${time} | ${cmd.action} | ${details} | ${took} | ${shot} |`);
89
135
  }
90
136
  return lines.join('\n');
91
137
  }
@@ -1 +1 @@
1
- {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/daemon/summary.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/daemon/summary.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,7 @@ export interface DaemonState {
14
14
  lastActivity: string;
15
15
  }
16
16
  /** Actions the daemon HTTP server handles */
17
- export type DaemonAction = 'ping' | 'shutdown' | 'screenshot' | 'screenshot-responsive' | 'snapshot' | 'click-ref' | 'fill-ref' | 'hover-ref' | 'press-key' | 'console-read' | 'network-read' | 'dialog-read' | 'screenshot-devices' | 'visual-diff' | 'record-start' | 'record-stop' | 'record-status' | 'generate-viewer' | 'demo-init' | 'demo-note' | 'demo-exec' | 'demo-screenshot' | 'demo-snapshot' | 'demo-pop' | 'demo-verify' | 'demo-status';
17
+ export type DaemonAction = 'ping' | 'shutdown' | 'screenshot' | 'screenshot-responsive' | 'snapshot' | 'click-ref' | 'click-css' | 'fill-ref' | 'hover-ref' | 'press-key' | 'console-read' | 'network-read' | 'dialog-read' | 'screenshot-devices' | 'visual-diff' | 'record-start' | 'record-stop' | 'record-status' | 'record-pause' | 'record-resume' | 'sessions-list' | 'generate-viewer' | 'demo-init' | 'demo-note' | 'demo-exec' | 'demo-screenshot' | 'demo-snapshot' | 'demo-pop' | 'demo-verify' | 'demo-status';
18
18
  /** Request body for daemon HTTP POST */
19
19
  export interface DaemonRequest {
20
20
  action: DaemonAction;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,UAAU,GACV,YAAY,GACZ,uBAAuB,GACvB,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,GACX,WAAW,GACX,cAAc,GACd,cAAc,GACd,aAAa,GACb,oBAAoB,GACpB,aAAa,GACb,cAAc,GACd,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,WAAW,GACX,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,eAAe,GACf,UAAU,GACV,aAAa,GACb,aAAa,CAAC;AAElB,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,KAAK,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAMD,0CAA0C;AAC1C,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,0CAA0C;AAC1C,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AAErD,gDAAgD;AAChD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,4DAA4D;AAC5D,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,2BAA2B;AAC3B,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C,sBAAsB;AACtB,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C,qBAAqB;AACrB,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C,mCAAmC;AACnC,eAAO,MAAM,4BAA4B,UAAmB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,UAAU,GACV,YAAY,GACZ,uBAAuB,GACvB,UAAU,GACV,WAAW,GACX,WAAW,GACX,UAAU,GACV,WAAW,GACX,WAAW,GACX,cAAc,GACd,cAAc,GACd,aAAa,GACb,oBAAoB,GACpB,aAAa,GACb,cAAc,GACd,aAAa,GACb,eAAe,GACf,cAAc,GACd,eAAe,GACf,eAAe,GACf,iBAAiB,GACjB,WAAW,GACX,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,eAAe,GACf,UAAU,GACV,aAAa,GACb,aAAa,CAAC;AAElB,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,KAAK,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAMD,0CAA0C;AAC1C,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,0CAA0C;AAC1C,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,iDAAiD;AACjD,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AAErD,gDAAgD;AAChD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,4DAA4D;AAC5D,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,2BAA2B;AAC3B,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C,sBAAsB;AACtB,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAE/C,qBAAqB;AACrB,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C,mCAAmC;AACnC,eAAO,MAAM,4BAA4B,UAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+FH,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAEnE,gDAAgD;AAChD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C,2BAA2B;AAC3B,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C,sBAAsB;AACtB,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE/C,qBAAqB;AACrB,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE9C,mCAAmC;AACnC,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmGH,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,iDAAiD;AACjD,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAEnE,gDAAgD;AAChD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C,2BAA2B;AAC3B,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C,sBAAsB;AACtB,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE/C,qBAAqB;AACrB,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE9C,mCAAmC;AACnC,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC"}
@@ -19,6 +19,13 @@ export interface ViewerOptions {
19
19
  outputPath?: string;
20
20
  consoleEntries?: ConsoleEntry[];
21
21
  networkEntries?: NetworkEntry[];
22
+ /**
23
+ * If true, embed the video as a base64 data URL — produces a single
24
+ * portable HTML file (good for emailing/sharing). Defaults to false:
25
+ * the viewer references `session.webm` in the same directory, which
26
+ * keeps the HTML ~280× smaller for typical session lengths.
27
+ */
28
+ inlineVideo?: boolean;
22
29
  }
23
30
  export declare function generateViewer(manifest: SessionManifest, options: ViewerOptions): Promise<string>;
24
31
  //# sourceMappingURL=viewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGjE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;CACjC;AAWD,wBAAsB,cAAc,CAClC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAkiBjB"}
1
+ {"version":3,"file":"viewer.d.ts","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGjE,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAWD,wBAAsB,cAAc,CAClC,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAyiBjB"}
@@ -24,13 +24,19 @@ function escapeHtml(str) {
24
24
  .replace(/'/g, '&#39;');
25
25
  }
26
26
  export async function generateViewer(manifest, options) {
27
- // Load video as base64 if available
27
+ // The viewer can reference the WebM by relative path (default: keeps
28
+ // the HTML small; reader needs both files) OR inline as base64 (for
29
+ // a single-file shareable artifact).
30
+ const wantInline = options.inlineVideo === true;
28
31
  let videoBase64 = null;
32
+ let videoExists = false;
29
33
  if (manifest.video) {
30
34
  const videoPath = path.join(options.sessionDir, manifest.video);
31
35
  try {
32
36
  const buffer = await fs.readFile(videoPath);
33
- videoBase64 = buffer.toString('base64');
37
+ videoExists = true;
38
+ if (wantInline)
39
+ videoBase64 = buffer.toString('base64');
34
40
  }
35
41
  catch { /* video file may not exist */ }
36
42
  }
@@ -69,7 +75,7 @@ export async function generateViewer(manifest, options) {
69
75
  <span class="action-pos">${escapeHtml(bbInfo)}</span>
70
76
  </div>`;
71
77
  }).join('\n');
72
- const hasVideo = videoBase64 !== null;
78
+ const hasVideo = videoExists;
73
79
  // Generate summary markdown for clipboard copy
74
80
  const summaryMd = generateSummary({
75
81
  manifest,
@@ -184,7 +190,9 @@ export async function generateViewer(manifest, options) {
184
190
  <div class="video-pane">
185
191
  <div class="video-container" id="video-container">
186
192
  ${hasVideo
187
- ? `<video id="player" src="data:video/webm;base64,${videoBase64}" preload="auto"></video>`
193
+ ? videoBase64
194
+ ? `<video id="player" src="data:video/webm;base64,${videoBase64}" preload="auto"></video>`
195
+ : `<video id="player" src="${escapeHtml(manifest.video)}" preload="auto"></video>`
188
196
  : screenshots.length > 0
189
197
  ? `<img id="screenshot-img" src="data:image/png;base64,${screenshots[0].data}" />`
190
198
  : '<div class="empty">No video or screenshots</div>'}
@@ -1 +1 @@
1
- {"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/daemon/viewer.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,8 @@ export interface VisualDiffResult {
9
9
  mismatchCount: number;
10
10
  totalPixels: number;
11
11
  diffImagePath?: string;
12
+ /** Path to the interactive HTML viewer with side-by-side + overlay views. */
13
+ diffViewerPath?: string;
12
14
  pass: boolean;
13
15
  }
14
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"visualDiff.d.ts","sourceRoot":"","sources":["../../src/daemon/visualDiff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;CACf;AAMD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC,gBAAgB,CAAC,CAmC3B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,CAAC,CA6B5D"}
1
+ {"version":3,"file":"visualDiff.d.ts","sourceRoot":"","sources":["../../src/daemon/visualDiff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;CACf;AAMD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC,gBAAgB,CAAC,CA+F3B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,CAAC,CA6B5D"}
@@ -36,13 +36,72 @@ export async function visualDiff(baseline, current, options) {
36
36
  totalPixels: totalBytes,
37
37
  pass,
38
38
  };
39
- // If output path is specified and there are differences, save the current as "diff"
39
+ // When an output path is requested OR there's a real mismatch, write a
40
+ // side-by-side HTML viewer that embeds both screenshots and supports
41
+ // toggling between baseline/current/overlay (CSS difference blend mode).
42
+ // This is far more actionable than the percentage alone.
40
43
  if (options?.outputPath && !pass) {
41
44
  const dir = path.dirname(options.outputPath);
42
45
  await fs.mkdir(dir, { recursive: true });
43
- // Save the current screenshot as the diff reference
46
+ // Save the current PNG as the primary diff artifact (back-compat).
44
47
  await fs.writeFile(options.outputPath, current);
45
48
  result.diffImagePath = options.outputPath;
49
+ // Write a sibling .html viewer with toggle/overlay UI.
50
+ const viewerPath = options.outputPath.replace(/\.png$/i, '') + '.diff.html';
51
+ const baselineB64 = baseline.toString('base64');
52
+ const currentB64 = current.toString('base64');
53
+ const html = `<!DOCTYPE html>
54
+ <html><head><title>Visual Diff</title>
55
+ <style>
56
+ body{margin:0;font-family:system-ui;background:#0f172a;color:#e2e8f0}
57
+ header{padding:12px 20px;background:#1e293b;display:flex;align-items:center;gap:16px}
58
+ header h1{font-size:16px;font-weight:600;margin:0}
59
+ header .stat{margin-left:auto;font-variant-numeric:tabular-nums}
60
+ header .pill{padding:2px 8px;border-radius:10px;font-weight:600}
61
+ .pill.fail{background:#7f1d1d;color:#fca5a5}
62
+ button{background:#334155;color:#e2e8f0;border:0;padding:6px 12px;border-radius:4px;cursor:pointer;font:inherit}
63
+ button.active{background:#0ea5e9;color:#000}
64
+ main{display:flex;gap:8px;padding:8px;flex-wrap:wrap;justify-content:center}
65
+ figure{margin:0;flex:1;min-width:300px;max-width:700px}
66
+ figcaption{font-size:13px;color:#94a3b8;padding:4px 0 8px}
67
+ img{display:block;max-width:100%;border:1px solid #334155}
68
+ .stack{position:relative;display:inline-block;max-width:100%}
69
+ .stack img{position:absolute;top:0;left:0}
70
+ .stack img:first-child{position:relative}
71
+ .stack img.overlay{mix-blend-mode:difference;filter:invert(1)}
72
+ </style></head>
73
+ <body>
74
+ <header>
75
+ <h1>Visual Diff</h1>
76
+ <button class="active" data-view="side">Side by side</button>
77
+ <button data-view="overlay">Overlay diff</button>
78
+ <button data-view="baseline">Baseline only</button>
79
+ <button data-view="current">Current only</button>
80
+ <div class="stat">
81
+ <span class="pill fail">${result.mismatchPercentage.toFixed(2)}% mismatch</span>
82
+ </div>
83
+ </header>
84
+ <main id="m">
85
+ <figure id="f-baseline"><figcaption>Baseline</figcaption><img src="data:image/png;base64,${baselineB64}" /></figure>
86
+ <figure id="f-current"><figcaption>Current</figcaption><img src="data:image/png;base64,${currentB64}" /></figure>
87
+ <figure id="f-overlay" hidden><figcaption>Overlay (CSS difference blend)</figcaption>
88
+ <div class="stack"><img src="data:image/png;base64,${baselineB64}" /><img class="overlay" src="data:image/png;base64,${currentB64}" /></div>
89
+ </figure>
90
+ </main>
91
+ <script>
92
+ const buttons = document.querySelectorAll('header button');
93
+ const figs = { baseline: document.getElementById('f-baseline'), current: document.getElementById('f-current'), overlay: document.getElementById('f-overlay') };
94
+ buttons.forEach(b => b.addEventListener('click', () => {
95
+ buttons.forEach(x => x.classList.toggle('active', x === b));
96
+ const v = b.dataset.view;
97
+ figs.baseline.hidden = v === 'overlay' || v === 'current';
98
+ figs.current.hidden = v === 'overlay' || v === 'baseline';
99
+ figs.overlay.hidden = v !== 'overlay';
100
+ }));
101
+ </script>
102
+ </body></html>`;
103
+ await fs.writeFile(viewerPath, html);
104
+ result.diffViewerPath = viewerPath;
46
105
  }
47
106
  return result;
48
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"visualDiff.js","sourceRoot":"","sources":["../../src/daemon/visualDiff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"visualDiff.js","sourceRoot":"","sources":["../../src/daemon/visualDiff.ts"],"names":[],"mappings":"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"}
package/dist/ruler.d.ts CHANGED
@@ -50,7 +50,7 @@ export interface RulerOutput {
50
50
  * JavaScript function to inject into the page.
51
51
  * Creates visual measurement overlays on elements.
52
52
  */
53
- export declare const measureElementsScript = "\n(function(options) {\n const {\n selectors = [],\n showCenterLines = true,\n showDimensions = true,\n showPosition = false,\n colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],\n limit = 5,\n showAlignment = true\n } = options || {};\n\n // Remove any existing measurement overlay\n const existingOverlay = document.getElementById('pixel-ruler-overlay');\n if (existingOverlay) existingOverlay.remove();\n\n // Create SVG overlay\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.id = 'pixel-ruler-overlay';\n svg.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 999999;\n `;\n document.body.appendChild(svg);\n\n const results = [];\n let allRects = [];\n\n // Process each selector\n selectors.forEach((selector, selectorIndex) => {\n const color = colors[selectorIndex % colors.length];\n const elements = document.querySelectorAll(selector);\n const selectorResult = { selector, elements: [] };\n\n Array.from(elements).slice(0, limit).forEach((element, elementIndex) => {\n const rect = element.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n selectorResult.elements.push({\n index: elementIndex,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n centerX,\n centerY\n });\n\n allRects.push({ rect, centerX, centerY, color, selector, elementIndex });\n\n // Draw bounding box\n const box = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n box.setAttribute('x', rect.left);\n box.setAttribute('y', rect.top);\n box.setAttribute('width', rect.width);\n box.setAttribute('height', rect.height);\n box.setAttribute('fill', 'none');\n box.setAttribute('stroke', color);\n box.setAttribute('stroke-width', '2');\n box.setAttribute('stroke-dasharray', '4,2');\n svg.appendChild(box);\n\n // Draw center lines\n if (showCenterLines) {\n // Horizontal center line\n const hLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n hLine.setAttribute('x1', rect.left);\n hLine.setAttribute('y1', centerY);\n hLine.setAttribute('x2', rect.left + rect.width);\n hLine.setAttribute('y2', centerY);\n hLine.setAttribute('stroke', color);\n hLine.setAttribute('stroke-width', '1');\n hLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(hLine);\n\n // Vertical center line\n const vLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n vLine.setAttribute('x1', centerX);\n vLine.setAttribute('y1', rect.top);\n vLine.setAttribute('x2', centerX);\n vLine.setAttribute('y2', rect.top + rect.height);\n vLine.setAttribute('stroke', color);\n vLine.setAttribute('stroke-width', '1');\n vLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(vLine);\n\n // Center point\n const centerDot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n centerDot.setAttribute('cx', centerX);\n centerDot.setAttribute('cy', centerY);\n centerDot.setAttribute('r', '4');\n centerDot.setAttribute('fill', color);\n svg.appendChild(centerDot);\n }\n\n // Draw dimension labels\n if (showDimensions) {\n // Background for label\n const labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n labelBg.setAttribute('x', rect.left);\n labelBg.setAttribute('y', rect.top - 20);\n labelBg.setAttribute('width', '100');\n labelBg.setAttribute('height', '18');\n labelBg.setAttribute('fill', 'rgba(0,0,0,0.8)');\n labelBg.setAttribute('rx', '2');\n svg.appendChild(labelBg);\n\n // Dimension text\n const dimText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n dimText.setAttribute('x', rect.left + 4);\n dimText.setAttribute('y', rect.top - 6);\n dimText.setAttribute('fill', color);\n dimText.setAttribute('font-family', 'monospace');\n dimText.setAttribute('font-size', '12');\n dimText.setAttribute('font-weight', 'bold');\n dimText.textContent = `${Math.round(rect.width)}\u00D7${Math.round(rect.height)}`;\n svg.appendChild(dimText);\n }\n\n // Draw position labels\n if (showPosition) {\n const posText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n posText.setAttribute('x', rect.left + 4);\n posText.setAttribute('y', rect.top + 14);\n posText.setAttribute('fill', color);\n posText.setAttribute('font-family', 'monospace');\n posText.setAttribute('font-size', '10');\n posText.textContent = `(${Math.round(rect.left)}, ${Math.round(rect.top)})`;\n svg.appendChild(posText);\n }\n });\n\n results.push(selectorResult);\n });\n\n // Show alignment comparison between elements\n let alignment = null;\n if (showAlignment && allRects.length >= 2) {\n const first = allRects[0];\n const second = allRects[1];\n\n // Draw alignment line between centers\n const alignLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n alignLine.setAttribute('x1', first.centerX);\n alignLine.setAttribute('y1', first.centerY);\n alignLine.setAttribute('x2', second.centerX);\n alignLine.setAttribute('y2', second.centerY);\n alignLine.setAttribute('stroke', '#ffffff');\n alignLine.setAttribute('stroke-width', '2');\n svg.appendChild(alignLine);\n\n // Calculate vertical offset\n const verticalOffset = Math.round(first.centerY - second.centerY);\n const horizontalOffset = Math.round(first.centerX - second.centerX);\n\n // Offset label\n const midX = (first.centerX + second.centerX) / 2;\n const midY = (first.centerY + second.centerY) / 2;\n\n const offsetBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n offsetBg.setAttribute('x', midX - 50);\n offsetBg.setAttribute('y', midY - 12);\n offsetBg.setAttribute('width', '100');\n offsetBg.setAttribute('height', '24');\n offsetBg.setAttribute('fill', 'rgba(0,0,0,0.9)');\n offsetBg.setAttribute('rx', '4');\n svg.appendChild(offsetBg);\n\n const offsetText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n offsetText.setAttribute('x', midX);\n offsetText.setAttribute('y', midY + 5);\n offsetText.setAttribute('fill', '#ffffff');\n offsetText.setAttribute('font-family', 'monospace');\n offsetText.setAttribute('font-size', '12');\n offsetText.setAttribute('font-weight', 'bold');\n offsetText.setAttribute('text-anchor', 'middle');\n offsetText.textContent = `\u0394y:${verticalOffset}px \u0394x:${horizontalOffset}px`;\n svg.appendChild(offsetText);\n\n alignment = {\n verticalOffset,\n horizontalOffset,\n aligned: Math.abs(verticalOffset) <= 2 && Math.abs(horizontalOffset) <= 2\n };\n }\n\n return {\n results,\n summary: results.map(r => `${r.selector}: ${r.elements.length} elements`).join(', '),\n alignment\n };\n})\n";
53
+ export declare const measureElementsScript = "\n(function(options) {\n const {\n selectors = [],\n showCenterLines = true,\n showDimensions = true,\n showPosition = false,\n colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'],\n limit = 5,\n showAlignment = true\n } = options || {};\n\n // Remove any existing measurement overlay\n const existingOverlay = document.getElementById('pixel-ruler-overlay');\n if (existingOverlay) existingOverlay.remove();\n\n // Create SVG overlay\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.id = 'pixel-ruler-overlay';\n svg.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n pointer-events: none;\n z-index: 999999;\n `;\n document.body.appendChild(svg);\n\n const results = [];\n let allRects = [];\n\n // Process each selector\n selectors.forEach((selector, selectorIndex) => {\n const color = colors[selectorIndex % colors.length];\n const elements = document.querySelectorAll(selector);\n const selectorResult = { selector, elements: [] };\n\n Array.from(elements).slice(0, limit).forEach((element, elementIndex) => {\n const rect = element.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n selectorResult.elements.push({\n index: elementIndex,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n centerX,\n centerY\n });\n\n allRects.push({ rect, centerX, centerY, color, selector, elementIndex });\n\n // Draw bounding box\n const box = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n box.setAttribute('x', rect.left);\n box.setAttribute('y', rect.top);\n box.setAttribute('width', rect.width);\n box.setAttribute('height', rect.height);\n box.setAttribute('fill', 'none');\n box.setAttribute('stroke', color);\n box.setAttribute('stroke-width', '2');\n box.setAttribute('stroke-dasharray', '4,2');\n svg.appendChild(box);\n\n // Draw center lines\n if (showCenterLines) {\n // Horizontal center line\n const hLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n hLine.setAttribute('x1', rect.left);\n hLine.setAttribute('y1', centerY);\n hLine.setAttribute('x2', rect.left + rect.width);\n hLine.setAttribute('y2', centerY);\n hLine.setAttribute('stroke', color);\n hLine.setAttribute('stroke-width', '1');\n hLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(hLine);\n\n // Vertical center line\n const vLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n vLine.setAttribute('x1', centerX);\n vLine.setAttribute('y1', rect.top);\n vLine.setAttribute('x2', centerX);\n vLine.setAttribute('y2', rect.top + rect.height);\n vLine.setAttribute('stroke', color);\n vLine.setAttribute('stroke-width', '1');\n vLine.setAttribute('stroke-dasharray', '2,2');\n svg.appendChild(vLine);\n\n // Center point\n const centerDot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n centerDot.setAttribute('cx', centerX);\n centerDot.setAttribute('cy', centerY);\n centerDot.setAttribute('r', '4');\n centerDot.setAttribute('fill', color);\n svg.appendChild(centerDot);\n }\n\n // Draw dimension labels\n if (showDimensions) {\n // Position the label OUTSIDE the bbox so it doesn't overlap\n // page content. Default: above the bbox (top); fall back below\n // when the element is at the very top of the page.\n const dimLabel = `${Math.round(rect.width)}\u00D7${Math.round(rect.height)}`;\n const labelHeight = 22;\n const labelW = Math.max(70, dimLabel.length * 9);\n const goAbove = rect.top >= labelHeight + 4;\n const ly = goAbove ? rect.top - labelHeight - 2 : rect.top + rect.height + 2;\n const lx = rect.left;\n\n const labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n labelBg.setAttribute('x', lx);\n labelBg.setAttribute('y', ly);\n labelBg.setAttribute('width', String(labelW));\n labelBg.setAttribute('height', String(labelHeight));\n labelBg.setAttribute('fill', color);\n labelBg.setAttribute('rx', '3');\n svg.appendChild(labelBg);\n\n const dimText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n dimText.setAttribute('x', lx + labelW / 2);\n dimText.setAttribute('y', ly + 15);\n dimText.setAttribute('fill', '#ffffff');\n dimText.setAttribute('font-family', 'system-ui, sans-serif');\n dimText.setAttribute('font-size', '13');\n dimText.setAttribute('font-weight', '700');\n dimText.setAttribute('text-anchor', 'middle');\n dimText.textContent = dimLabel;\n svg.appendChild(dimText);\n }\n\n // Draw position labels (separate, opposite side of dim label)\n if (showPosition) {\n const posText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n // Position label below-right outside the bbox.\n posText.setAttribute('x', rect.left + rect.width + 4);\n posText.setAttribute('y', rect.top + 14);\n posText.setAttribute('fill', color);\n posText.setAttribute('font-family', 'system-ui, sans-serif');\n posText.setAttribute('font-size', '12');\n posText.textContent = `(${Math.round(rect.left)}, ${Math.round(rect.top)})`;\n svg.appendChild(posText);\n }\n });\n\n results.push(selectorResult);\n });\n\n // Show alignment comparison between elements\n let alignment = null;\n if (showAlignment && allRects.length >= 2) {\n const first = allRects[0];\n const second = allRects[1];\n\n // Draw alignment line between centers\n const alignLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n alignLine.setAttribute('x1', first.centerX);\n alignLine.setAttribute('y1', first.centerY);\n alignLine.setAttribute('x2', second.centerX);\n alignLine.setAttribute('y2', second.centerY);\n alignLine.setAttribute('stroke', '#ffffff');\n alignLine.setAttribute('stroke-width', '2');\n svg.appendChild(alignLine);\n\n // Calculate vertical offset\n const verticalOffset = Math.round(first.centerY - second.centerY);\n const horizontalOffset = Math.round(first.centerX - second.centerX);\n\n // Offset label\n const midX = (first.centerX + second.centerX) / 2;\n const midY = (first.centerY + second.centerY) / 2;\n\n const offsetLabel = `\u0394y=${verticalOffset}px \u0394x=${horizontalOffset}px`;\n const offsetW = Math.max(140, offsetLabel.length * 9);\n const offsetH = 28;\n const offsetBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n offsetBg.setAttribute('x', midX - offsetW / 2);\n offsetBg.setAttribute('y', midY - offsetH / 2);\n offsetBg.setAttribute('width', String(offsetW));\n offsetBg.setAttribute('height', String(offsetH));\n offsetBg.setAttribute('fill', 'rgba(20,20,20,0.95)');\n offsetBg.setAttribute('rx', '4');\n svg.appendChild(offsetBg);\n\n const offsetText = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n offsetText.setAttribute('x', midX);\n offsetText.setAttribute('y', midY + 6);\n offsetText.setAttribute('fill', '#ffffff');\n offsetText.setAttribute('font-family', 'system-ui, sans-serif');\n offsetText.setAttribute('font-size', '14');\n offsetText.setAttribute('font-weight', '700');\n offsetText.setAttribute('text-anchor', 'middle');\n offsetText.textContent = offsetLabel;\n svg.appendChild(offsetText);\n\n alignment = {\n verticalOffset,\n horizontalOffset,\n aligned: Math.abs(verticalOffset) <= 2 && Math.abs(horizontalOffset) <= 2\n };\n }\n\n return {\n results,\n summary: results.map(r => `${r.selector}: ${r.elements.length} elements`).join(', '),\n alignment\n };\n})\n";
54
54
  /**
55
55
  * Measure elements and inject visual overlay using Playwright
56
56
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ruler.d.ts","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uCAAuC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,sxOAmMjC,CAAC;AAEF;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAkDrD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,CAWxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,CAQxD"}
1
+ {"version":3,"file":"ruler.d.ts","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uCAAuC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,6jQAgNjC,CAAC;AAEF;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA+DrD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,CAWxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,CAQxD"}
package/dist/ruler.js CHANGED
@@ -112,36 +112,46 @@ export const measureElementsScript = `
112
112
 
113
113
  // Draw dimension labels
114
114
  if (showDimensions) {
115
- // Background for label
115
+ // Position the label OUTSIDE the bbox so it doesn't overlap
116
+ // page content. Default: above the bbox (top); fall back below
117
+ // when the element is at the very top of the page.
118
+ const dimLabel = \`\${Math.round(rect.width)}×\${Math.round(rect.height)}\`;
119
+ const labelHeight = 22;
120
+ const labelW = Math.max(70, dimLabel.length * 9);
121
+ const goAbove = rect.top >= labelHeight + 4;
122
+ const ly = goAbove ? rect.top - labelHeight - 2 : rect.top + rect.height + 2;
123
+ const lx = rect.left;
124
+
116
125
  const labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
117
- labelBg.setAttribute('x', rect.left);
118
- labelBg.setAttribute('y', rect.top - 20);
119
- labelBg.setAttribute('width', '100');
120
- labelBg.setAttribute('height', '18');
121
- labelBg.setAttribute('fill', 'rgba(0,0,0,0.8)');
122
- labelBg.setAttribute('rx', '2');
126
+ labelBg.setAttribute('x', lx);
127
+ labelBg.setAttribute('y', ly);
128
+ labelBg.setAttribute('width', String(labelW));
129
+ labelBg.setAttribute('height', String(labelHeight));
130
+ labelBg.setAttribute('fill', color);
131
+ labelBg.setAttribute('rx', '3');
123
132
  svg.appendChild(labelBg);
124
133
 
125
- // Dimension text
126
134
  const dimText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
127
- dimText.setAttribute('x', rect.left + 4);
128
- dimText.setAttribute('y', rect.top - 6);
129
- dimText.setAttribute('fill', color);
130
- dimText.setAttribute('font-family', 'monospace');
131
- dimText.setAttribute('font-size', '12');
132
- dimText.setAttribute('font-weight', 'bold');
133
- dimText.textContent = \`\${Math.round(rect.width)}×\${Math.round(rect.height)}\`;
135
+ dimText.setAttribute('x', lx + labelW / 2);
136
+ dimText.setAttribute('y', ly + 15);
137
+ dimText.setAttribute('fill', '#ffffff');
138
+ dimText.setAttribute('font-family', 'system-ui, sans-serif');
139
+ dimText.setAttribute('font-size', '13');
140
+ dimText.setAttribute('font-weight', '700');
141
+ dimText.setAttribute('text-anchor', 'middle');
142
+ dimText.textContent = dimLabel;
134
143
  svg.appendChild(dimText);
135
144
  }
136
145
 
137
- // Draw position labels
146
+ // Draw position labels (separate, opposite side of dim label)
138
147
  if (showPosition) {
139
148
  const posText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
140
- posText.setAttribute('x', rect.left + 4);
149
+ // Position label below-right outside the bbox.
150
+ posText.setAttribute('x', rect.left + rect.width + 4);
141
151
  posText.setAttribute('y', rect.top + 14);
142
152
  posText.setAttribute('fill', color);
143
- posText.setAttribute('font-family', 'monospace');
144
- posText.setAttribute('font-size', '10');
153
+ posText.setAttribute('font-family', 'system-ui, sans-serif');
154
+ posText.setAttribute('font-size', '12');
145
155
  posText.textContent = \`(\${Math.round(rect.left)}, \${Math.round(rect.top)})\`;
146
156
  svg.appendChild(posText);
147
157
  }
@@ -174,24 +184,27 @@ export const measureElementsScript = `
174
184
  const midX = (first.centerX + second.centerX) / 2;
175
185
  const midY = (first.centerY + second.centerY) / 2;
176
186
 
187
+ const offsetLabel = \`Δy=\${verticalOffset}px Δx=\${horizontalOffset}px\`;
188
+ const offsetW = Math.max(140, offsetLabel.length * 9);
189
+ const offsetH = 28;
177
190
  const offsetBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
178
- offsetBg.setAttribute('x', midX - 50);
179
- offsetBg.setAttribute('y', midY - 12);
180
- offsetBg.setAttribute('width', '100');
181
- offsetBg.setAttribute('height', '24');
182
- offsetBg.setAttribute('fill', 'rgba(0,0,0,0.9)');
191
+ offsetBg.setAttribute('x', midX - offsetW / 2);
192
+ offsetBg.setAttribute('y', midY - offsetH / 2);
193
+ offsetBg.setAttribute('width', String(offsetW));
194
+ offsetBg.setAttribute('height', String(offsetH));
195
+ offsetBg.setAttribute('fill', 'rgba(20,20,20,0.95)');
183
196
  offsetBg.setAttribute('rx', '4');
184
197
  svg.appendChild(offsetBg);
185
198
 
186
199
  const offsetText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
187
200
  offsetText.setAttribute('x', midX);
188
- offsetText.setAttribute('y', midY + 5);
201
+ offsetText.setAttribute('y', midY + 6);
189
202
  offsetText.setAttribute('fill', '#ffffff');
190
- offsetText.setAttribute('font-family', 'monospace');
191
- offsetText.setAttribute('font-size', '12');
192
- offsetText.setAttribute('font-weight', 'bold');
203
+ offsetText.setAttribute('font-family', 'system-ui, sans-serif');
204
+ offsetText.setAttribute('font-size', '14');
205
+ offsetText.setAttribute('font-weight', '700');
193
206
  offsetText.setAttribute('text-anchor', 'middle');
194
- offsetText.textContent = \`Δy:\${verticalOffset}px Δx:\${horizontalOffset}px\`;
207
+ offsetText.textContent = offsetLabel;
195
208
  svg.appendChild(offsetText);
196
209
 
197
210
  alignment = {
@@ -242,10 +255,18 @@ export async function measureViaPlaywright(options) {
242
255
  if (dir && !fs.existsSync(dir)) {
243
256
  fs.mkdirSync(dir, { recursive: true });
244
257
  }
245
- await page.screenshot({ path: options.output, fullPage: false });
258
+ // If any measured element extends below the viewport, capture the
259
+ // full page so all overlays are visible — otherwise users see
260
+ // half their highlights cut off. (page.viewportSize is missing
261
+ // from some test doubles, hence the typeof guard.)
262
+ const vp = typeof page.viewportSize === 'function' ? page.viewportSize() : null;
263
+ const extendsBelow = vp ? result.results.some((r) => r.elements.some((e) => e.rect.top + e.rect.height > vp.height)) : false;
264
+ await page.screenshot({ path: options.output, fullPage: extendsBelow });
246
265
  screenshotPath = options.output;
247
- if (options.verbose)
248
- console.log(`[Sweetlink Ruler] Screenshot saved to: ${options.output}`);
266
+ if (options.verbose) {
267
+ console.log(`[Sweetlink Ruler] Screenshot saved to: ${options.output}` +
268
+ (extendsBelow ? ' (full page — measured elements extend below viewport)' : ''));
269
+ }
249
270
  }
250
271
  return { ...result, screenshotPath };
251
272
  }
package/dist/ruler.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ruler.js","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ruler.js","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"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"}