@ytspar/sweetlink 1.17.0 → 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.
- package/dist/cli/sweetlink.js +268 -17
- package/dist/cli/sweetlink.js.map +1 -1
- package/dist/daemon/browser.d.ts +2 -0
- package/dist/daemon/browser.d.ts.map +1 -1
- package/dist/daemon/browser.js +5 -0
- package/dist/daemon/browser.js.map +1 -1
- package/dist/daemon/cursor.d.ts.map +1 -1
- package/dist/daemon/cursor.js +39 -8
- package/dist/daemon/cursor.js.map +1 -1
- package/dist/daemon/listeners.d.ts +6 -0
- package/dist/daemon/listeners.d.ts.map +1 -1
- package/dist/daemon/listeners.js +32 -1
- package/dist/daemon/listeners.js.map +1 -1
- package/dist/daemon/recording.d.ts +22 -2
- package/dist/daemon/recording.d.ts.map +1 -1
- package/dist/daemon/recording.js +79 -7
- package/dist/daemon/recording.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +204 -12
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/session.d.ts +2 -0
- package/dist/daemon/session.d.ts.map +1 -1
- package/dist/daemon/summary.d.ts.map +1 -1
- package/dist/daemon/summary.js +8 -4
- 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/visualDiff.d.ts +2 -0
- package/dist/daemon/visualDiff.d.ts.map +1 -1
- package/dist/daemon/visualDiff.js +61 -2
- package/dist/daemon/visualDiff.js.map +1 -1
- package/package.json +1 -1
|
@@ -36,13 +36,72 @@ export async function visualDiff(baseline, current, options) {
|
|
|
36
36
|
totalPixels: totalBytes,
|
|
37
37
|
pass,
|
|
38
38
|
};
|
|
39
|
-
//
|
|
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
|
|
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":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"visualDiff.js","sourceRoot":"","sources":["../../src/daemon/visualDiff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAgB7B,+EAA+E;AAC/E,uDAAuD;AACvD,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,QAAgB,EAChB,OAAe,EACf,OAGC;IAED,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,CAAC,CAAC;IAE1C,+BAA+B;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,SAAS,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC;IAC1B,MAAM,kBAAkB,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,kBAAkB,IAAI,SAAS,GAAG,GAAG,CAAC;IAEnD,MAAM,MAAM,GAAqB;QAC/B,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC,GAAG,GAAG;QAC9D,aAAa,EAAE,SAAS;QACxB,WAAW,EAAE,UAAU;QACvB,IAAI;KACL,CAAC;IAEF,uEAAuE;IACvE,qEAAqE;IACrE,yEAAyE;IACzE,yDAAyD;IACzD,IAAI,OAAO,EAAE,UAAU,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,mEAAmE;QACnE,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,CAAC,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;QAE1C,uDAAuD;QACvD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,YAAY,CAAC;QAC5E,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA4Ba,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;;;;6FAI2B,WAAW;2FACb,UAAU;;yDAE5C,WAAW,uDAAuD,UAAU;;;;;;;;;;;;;;eActH,CAAC;QACZ,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,cAAc,GAAG,UAAU,CAAC;IACrC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAmB,EACnB,UAAkB,EAClB,OAAgC;IAEhC,MAAM,OAAO,GAAsD,EAAE,CAAC;IACtE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS;QAE/D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC5D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,MAAM,EAAE;oBACN,kBAAkB,EAAE,GAAG;oBACvB,aAAa,EAAE,CAAC;oBAChB,WAAW,EAAE,CAAC;oBACd,IAAI,EAAE,KAAK;iBACZ;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ytspar/sweetlink",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.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",
|