@ytspar/sweetlink 1.13.0 → 1.14.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 (78) hide show
  1. package/README.md +91 -12
  2. package/claude-skills/screenshot/SKILL.md +121 -20
  3. package/dist/cli/outputSchemas.d.ts +16 -0
  4. package/dist/cli/outputSchemas.d.ts.map +1 -1
  5. package/dist/cli/outputSchemas.js +33 -0
  6. package/dist/cli/outputSchemas.js.map +1 -1
  7. package/dist/cli/sweetlink-dev.js +0 -0
  8. package/dist/cli/sweetlink.js +347 -11
  9. package/dist/cli/sweetlink.js.map +1 -1
  10. package/dist/daemon/browser.d.ts +51 -0
  11. package/dist/daemon/browser.d.ts.map +1 -0
  12. package/dist/daemon/browser.js +153 -0
  13. package/dist/daemon/browser.js.map +1 -0
  14. package/dist/daemon/client.d.ts +32 -0
  15. package/dist/daemon/client.d.ts.map +1 -0
  16. package/dist/daemon/client.js +133 -0
  17. package/dist/daemon/client.js.map +1 -0
  18. package/dist/daemon/cursor.d.ts +15 -0
  19. package/dist/daemon/cursor.d.ts.map +1 -0
  20. package/dist/daemon/cursor.js +76 -0
  21. package/dist/daemon/cursor.js.map +1 -0
  22. package/dist/daemon/devices.d.ts +39 -0
  23. package/dist/daemon/devices.d.ts.map +1 -0
  24. package/dist/daemon/devices.js +101 -0
  25. package/dist/daemon/devices.js.map +1 -0
  26. package/dist/daemon/diff.d.ts +20 -0
  27. package/dist/daemon/diff.d.ts.map +1 -0
  28. package/dist/daemon/diff.js +181 -0
  29. package/dist/daemon/diff.js.map +1 -0
  30. package/dist/daemon/evidence.d.ts +29 -0
  31. package/dist/daemon/evidence.d.ts.map +1 -0
  32. package/dist/daemon/evidence.js +130 -0
  33. package/dist/daemon/evidence.js.map +1 -0
  34. package/dist/daemon/index.d.ts +10 -0
  35. package/dist/daemon/index.d.ts.map +1 -0
  36. package/dist/daemon/index.js +90 -0
  37. package/dist/daemon/index.js.map +1 -0
  38. package/dist/daemon/listeners.d.ts +55 -0
  39. package/dist/daemon/listeners.d.ts.map +1 -0
  40. package/dist/daemon/listeners.js +129 -0
  41. package/dist/daemon/listeners.js.map +1 -0
  42. package/dist/daemon/recording.d.ts +44 -0
  43. package/dist/daemon/recording.d.ts.map +1 -0
  44. package/dist/daemon/recording.js +133 -0
  45. package/dist/daemon/recording.js.map +1 -0
  46. package/dist/daemon/refs.d.ts +70 -0
  47. package/dist/daemon/refs.d.ts.map +1 -0
  48. package/dist/daemon/refs.js +185 -0
  49. package/dist/daemon/refs.js.map +1 -0
  50. package/dist/daemon/ringBuffer.d.ts +26 -0
  51. package/dist/daemon/ringBuffer.d.ts.map +1 -0
  52. package/dist/daemon/ringBuffer.js +54 -0
  53. package/dist/daemon/ringBuffer.js.map +1 -0
  54. package/dist/daemon/server.d.ts +23 -0
  55. package/dist/daemon/server.d.ts.map +1 -0
  56. package/dist/daemon/server.js +508 -0
  57. package/dist/daemon/server.js.map +1 -0
  58. package/dist/daemon/session.d.ts +41 -0
  59. package/dist/daemon/session.d.ts.map +1 -0
  60. package/dist/daemon/session.js +8 -0
  61. package/dist/daemon/session.js.map +1 -0
  62. package/dist/daemon/stateFile.d.ts +49 -0
  63. package/dist/daemon/stateFile.d.ts.map +1 -0
  64. package/dist/daemon/stateFile.js +162 -0
  65. package/dist/daemon/stateFile.js.map +1 -0
  66. package/dist/daemon/types.d.ts +72 -0
  67. package/dist/daemon/types.d.ts.map +1 -0
  68. package/dist/daemon/types.js +28 -0
  69. package/dist/daemon/types.js.map +1 -0
  70. package/dist/daemon/viewer.d.ts +33 -0
  71. package/dist/daemon/viewer.d.ts.map +1 -0
  72. package/dist/daemon/viewer.js +226 -0
  73. package/dist/daemon/viewer.js.map +1 -0
  74. package/dist/daemon/visualDiff.d.ts +34 -0
  75. package/dist/daemon/visualDiff.d.ts.map +1 -0
  76. package/dist/daemon/visualDiff.js +80 -0
  77. package/dist/daemon/visualDiff.js.map +1 -0
  78. package/package.json +20 -12
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Visual Diff
3
+ *
4
+ * Pixel-by-pixel comparison of screenshots using a simple diff algorithm.
5
+ * Uses raw pixel comparison without external dependencies.
6
+ */
7
+ import { promises as fs } from 'fs';
8
+ import * as path from 'path';
9
+ // ============================================================================
10
+ // PNG Helpers (minimal decoder/encoder for comparison)
11
+ // ============================================================================
12
+ /**
13
+ * Simple visual diff using Playwright's built-in comparison.
14
+ * Takes two PNG buffers and returns mismatch info.
15
+ *
16
+ * For pixel-perfect comparison, we compare raw buffer bytes.
17
+ * For a production-grade solution, pixelmatch can be added as optional dep.
18
+ */
19
+ export async function visualDiff(baseline, current, options) {
20
+ const threshold = options?.threshold ?? 0;
21
+ // Simple byte-level comparison
22
+ const minLen = Math.min(baseline.length, current.length);
23
+ const maxLen = Math.max(baseline.length, current.length);
24
+ let diffBytes = Math.abs(baseline.length - current.length);
25
+ for (let i = 0; i < minLen; i++) {
26
+ if (baseline[i] !== current[i]) {
27
+ diffBytes++;
28
+ }
29
+ }
30
+ const totalBytes = maxLen;
31
+ const mismatchPercentage = totalBytes > 0 ? (diffBytes / totalBytes) * 100 : 0;
32
+ const pass = mismatchPercentage <= threshold * 100;
33
+ const result = {
34
+ mismatchPercentage: Math.round(mismatchPercentage * 100) / 100,
35
+ mismatchCount: diffBytes,
36
+ totalPixels: totalBytes,
37
+ pass,
38
+ };
39
+ // If output path is specified and there are differences, save the current as "diff"
40
+ if (options?.outputPath && !pass) {
41
+ const dir = path.dirname(options.outputPath);
42
+ await fs.mkdir(dir, { recursive: true });
43
+ // Save the current screenshot as the diff reference
44
+ await fs.writeFile(options.outputPath, current);
45
+ result.diffImagePath = options.outputPath;
46
+ }
47
+ return result;
48
+ }
49
+ /**
50
+ * Compare screenshots from a directory against baselines.
51
+ */
52
+ export async function diffDirectory(baselineDir, currentDir, options) {
53
+ const results = [];
54
+ const files = await fs.readdir(currentDir);
55
+ for (const file of files) {
56
+ if (!file.endsWith('.png') && !file.endsWith('.jpg'))
57
+ continue;
58
+ const currentPath = path.join(currentDir, file);
59
+ const baselinePath = path.join(baselineDir, file);
60
+ try {
61
+ const current = await fs.readFile(currentPath);
62
+ const baseline = await fs.readFile(baselinePath);
63
+ const result = await visualDiff(baseline, current, options);
64
+ results.push({ file, result });
65
+ }
66
+ catch {
67
+ results.push({
68
+ file,
69
+ result: {
70
+ mismatchPercentage: 100,
71
+ mismatchCount: 0,
72
+ totalPixels: 0,
73
+ pass: false,
74
+ },
75
+ });
76
+ }
77
+ }
78
+ return results;
79
+ }
80
+ //# sourceMappingURL=visualDiff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualDiff.js","sourceRoot":"","sources":["../../src/daemon/visualDiff.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.13.0",
3
+ "version": "1.14.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",
@@ -84,11 +84,20 @@
84
84
  "./next": {
85
85
  "types": "./dist/next.d.ts",
86
86
  "import": "./dist/next.js"
87
+ },
88
+ "./daemon": {
89
+ "types": "./dist/daemon/types.d.ts",
90
+ "import": "./dist/daemon/types.js"
91
+ },
92
+ "./daemon/client": {
93
+ "types": "./dist/daemon/client.d.ts",
94
+ "import": "./dist/daemon/client.js"
87
95
  }
88
96
  },
89
97
  "bin": {
90
98
  "sweetlink": "./dist/cli/sweetlink.js",
91
- "sweetlink-dev": "./dist/cli/sweetlink-dev.js"
99
+ "sweetlink-dev": "./dist/cli/sweetlink-dev.js",
100
+ "sweetlink-daemon": "./dist/daemon/index.js"
92
101
  },
93
102
  "files": [
94
103
  "dist",
@@ -104,14 +113,6 @@
104
113
  "node": ">=20.0.0"
105
114
  },
106
115
  "private": false,
107
- "scripts": {
108
- "prepublishOnly": "node ../../scripts/check-release-notes.mjs && rm -rf dist && tsc",
109
- "build": "rm -rf dist && tsc",
110
- "test": "vitest run",
111
- "dev": "node dist/cli/sweetlink-dev.js",
112
- "typecheck": "tsc --noEmit",
113
- "clean": "rm -rf dist claude-context"
114
- },
115
116
  "peerDependencies": {
116
117
  "axe-core": "^4.0.0",
117
118
  "html2canvas-pro": "^2.0.0",
@@ -158,5 +159,12 @@
158
159
  "bugs": {
159
160
  "url": "https://github.com/ytspar/devbar/issues"
160
161
  },
161
- "homepage": "https://github.com/ytspar/devbar/tree/main/packages/sweetlink#readme"
162
- }
162
+ "homepage": "https://github.com/ytspar/devbar/tree/main/packages/sweetlink#readme",
163
+ "scripts": {
164
+ "build": "rm -rf dist && tsc",
165
+ "test": "vitest run",
166
+ "dev": "node dist/cli/sweetlink-dev.js",
167
+ "typecheck": "tsc --noEmit",
168
+ "clean": "rm -rf dist claude-context"
169
+ }
170
+ }