@ytspar/sweetlink 1.16.1 → 1.17.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.
- package/claude-skills/screenshot/SKILL.md +2 -0
- package/dist/cli/sweetlink-dev.js +0 -0
- package/dist/cli/sweetlink.js +70 -12
- package/dist/cli/sweetlink.js.map +1 -1
- package/dist/daemon/browser.d.ts +10 -0
- package/dist/daemon/browser.d.ts.map +1 -1
- package/dist/daemon/browser.js +57 -12
- package/dist/daemon/browser.js.map +1 -1
- package/dist/daemon/devices.d.ts +9 -4
- package/dist/daemon/devices.d.ts.map +1 -1
- package/dist/daemon/devices.js +25 -4
- package/dist/daemon/devices.js.map +1 -1
- package/dist/daemon/diff.d.ts +6 -0
- package/dist/daemon/diff.d.ts.map +1 -1
- package/dist/daemon/diff.js +46 -26
- package/dist/daemon/diff.js.map +1 -1
- package/dist/daemon/index.js +0 -0
- package/dist/daemon/listeners.d.ts +2 -2
- package/dist/daemon/listeners.d.ts.map +1 -1
- package/dist/daemon/listeners.js +7 -5
- package/dist/daemon/listeners.js.map +1 -1
- package/dist/daemon/recording.d.ts +6 -1
- package/dist/daemon/recording.d.ts.map +1 -1
- package/dist/daemon/recording.js +81 -11
- package/dist/daemon/recording.js.map +1 -1
- package/dist/daemon/refs.d.ts.map +1 -1
- package/dist/daemon/refs.js +7 -2
- package/dist/daemon/refs.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +127 -12
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/summary.d.ts.map +1 -1
- package/dist/daemon/summary.js +52 -10
- package/dist/daemon/summary.js.map +1 -1
- package/dist/daemon/types.d.ts +1 -1
- package/dist/daemon/types.d.ts.map +1 -1
- package/dist/daemon/types.js.map +1 -1
- package/dist/daemon/viewer.d.ts +7 -0
- package/dist/daemon/viewer.d.ts.map +1 -1
- package/dist/daemon/viewer.js +12 -4
- package/dist/daemon/viewer.js.map +1 -1
- package/dist/ruler.d.ts +1 -1
- package/dist/ruler.d.ts.map +1 -1
- package/dist/ruler.js +53 -32
- package/dist/ruler.js.map +1 -1
- package/package.json +10 -11
package/dist/daemon/summary.js
CHANGED
|
@@ -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 =
|
|
17
|
-
const day =
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
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
|
|
33
|
-
|
|
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
|
|
@@ -52,6 +88,11 @@ function renderMetadata(options) {
|
|
|
52
88
|
const commit = gitCommit ? ` @ ${gitCommit.slice(0, 7)}` : '';
|
|
53
89
|
lines.push(`**Git:** ${branch}${commit} `);
|
|
54
90
|
}
|
|
91
|
+
else {
|
|
92
|
+
// Surface the absence of git context — silently dropping it makes
|
|
93
|
+
// the session look reproducible when it isn't.
|
|
94
|
+
lines.push('**Git:** (not in a repository) ');
|
|
95
|
+
}
|
|
55
96
|
return lines.join('\n');
|
|
56
97
|
}
|
|
57
98
|
function renderStatus(options) {
|
|
@@ -79,13 +120,14 @@ function renderTimeline(manifest) {
|
|
|
79
120
|
const lines = [
|
|
80
121
|
'## Action Timeline',
|
|
81
122
|
'',
|
|
82
|
-
'| Time | Action |
|
|
83
|
-
'
|
|
123
|
+
'| Time | Action | Target | Screenshot |',
|
|
124
|
+
'|------|--------|--------|------------|',
|
|
84
125
|
];
|
|
85
126
|
for (const cmd of manifest.commands) {
|
|
86
127
|
const time = formatTimestamp(cmd.timestamp);
|
|
87
128
|
const details = formatActionDetails(cmd);
|
|
88
|
-
|
|
129
|
+
const shot = cmd.screenshot ? `[\`${cmd.screenshot}\`](${cmd.screenshot})` : '—';
|
|
130
|
+
lines.push(`| ${time} | ${cmd.action} | ${details} | ${shot} |`);
|
|
89
131
|
}
|
|
90
132
|
return lines.join('\n');
|
|
91
133
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/daemon/summary.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0BH,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E,SAAS,eAAe,CAAC,OAAe;IACtC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AAClC,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/daemon/summary.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon/types.d.ts
CHANGED
|
@@ -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' | '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,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"}
|
package/dist/daemon/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/daemon/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgGH,+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"}
|
package/dist/daemon/viewer.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/daemon/viewer.js
CHANGED
|
@@ -24,13 +24,19 @@ function escapeHtml(str) {
|
|
|
24
24
|
.replace(/'/g, ''');
|
|
25
25
|
}
|
|
26
26
|
export async function generateViewer(manifest, options) {
|
|
27
|
-
//
|
|
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
|
-
|
|
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 =
|
|
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
|
-
?
|
|
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":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"viewer.js","sourceRoot":"","sources":["../../src/daemon/viewer.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 //
|
|
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
|
*/
|
package/dist/ruler.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
-
//
|
|
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',
|
|
118
|
-
labelBg.setAttribute('y',
|
|
119
|
-
labelBg.setAttribute('width',
|
|
120
|
-
labelBg.setAttribute('height',
|
|
121
|
-
labelBg.setAttribute('fill',
|
|
122
|
-
labelBg.setAttribute('rx', '
|
|
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',
|
|
128
|
-
dimText.setAttribute('y',
|
|
129
|
-
dimText.setAttribute('fill',
|
|
130
|
-
dimText.setAttribute('font-family', '
|
|
131
|
-
dimText.setAttribute('font-size', '
|
|
132
|
-
dimText.setAttribute('font-weight', '
|
|
133
|
-
dimText.
|
|
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
|
-
|
|
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', '
|
|
144
|
-
posText.setAttribute('font-size', '
|
|
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 -
|
|
179
|
-
offsetBg.setAttribute('y', midY -
|
|
180
|
-
offsetBg.setAttribute('width',
|
|
181
|
-
offsetBg.setAttribute('height',
|
|
182
|
-
offsetBg.setAttribute('fill', 'rgba(
|
|
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 +
|
|
201
|
+
offsetText.setAttribute('y', midY + 6);
|
|
189
202
|
offsetText.setAttribute('fill', '#ffffff');
|
|
190
|
-
offsetText.setAttribute('font-family', '
|
|
191
|
-
offsetText.setAttribute('font-size', '
|
|
192
|
-
offsetText.setAttribute('font-weight', '
|
|
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 =
|
|
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
|
-
|
|
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":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAyC7C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG
|
|
1
|
+
{"version":3,"file":"ruler.js","sourceRoot":"","sources":["../src/ruler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ytspar/sweetlink",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Autonomous development toolkit for AI agents - screenshots, DOM queries, console logs, and JavaScript execution via WebSocket and Chrome DevTools Protocol",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"autonomous-development",
|
|
@@ -133,14 +133,6 @@
|
|
|
133
133
|
"node": ">=20.0.0"
|
|
134
134
|
},
|
|
135
135
|
"private": false,
|
|
136
|
-
"scripts": {
|
|
137
|
-
"prepublishOnly": "node ../../scripts/check-release-notes.mjs && rm -rf dist && tsc",
|
|
138
|
-
"build": "rm -rf dist && tsc",
|
|
139
|
-
"test": "vitest run",
|
|
140
|
-
"dev": "node dist/cli/sweetlink-dev.js",
|
|
141
|
-
"typecheck": "tsc --noEmit",
|
|
142
|
-
"clean": "rm -rf dist claude-context"
|
|
143
|
-
},
|
|
144
136
|
"peerDependencies": {
|
|
145
137
|
"axe-core": "^4.0.0",
|
|
146
138
|
"html2canvas-pro": "^2.0.0",
|
|
@@ -187,5 +179,12 @@
|
|
|
187
179
|
"bugs": {
|
|
188
180
|
"url": "https://github.com/ytspar/devbar/issues"
|
|
189
181
|
},
|
|
190
|
-
"homepage": "https://github.com/ytspar/devbar/tree/main/packages/sweetlink#readme"
|
|
191
|
-
|
|
182
|
+
"homepage": "https://github.com/ytspar/devbar/tree/main/packages/sweetlink#readme",
|
|
183
|
+
"scripts": {
|
|
184
|
+
"build": "rm -rf dist && tsc",
|
|
185
|
+
"test": "vitest run",
|
|
186
|
+
"dev": "node dist/cli/sweetlink-dev.js",
|
|
187
|
+
"typecheck": "tsc --noEmit",
|
|
188
|
+
"clean": "rm -rf dist claude-context"
|
|
189
|
+
}
|
|
190
|
+
}
|