difflens-cli 1.0.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/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # DiffLens
2
+
3
+ MCP server that gives AI coding agents "eyes" for UI work. It screenshots localhost pages before and after code changes, compares them visually, and returns structured diff reports with overlay images.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npm install -g difflens
9
+ cd your-project
10
+ difflens setup
11
+ # Restart Claude Code — DiffLens is now active
12
+ ```
13
+
14
+ Then ask Claude: *"take a snapshot of http://localhost:3000"*
15
+
16
+ ### Use without installing
17
+
18
+ Add to your project's `.mcp.json`:
19
+
20
+ ```json
21
+ {
22
+ "mcpServers": {
23
+ "difflens": {
24
+ "command": "npx",
25
+ "args": ["-y", "difflens"]
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ ## How It Works
32
+
33
+ 1. **Snapshot** a page to save a baseline screenshot
34
+ 2. Make changes to your code
35
+ 3. **Check** the page — DiffLens takes a new screenshot, runs a pixel-level diff against the baseline, clusters changed regions, and returns a report with an annotated overlay image
36
+
37
+ The overlay dims unchanged areas, highlights changed pixels in red, draws borders around detected regions, and includes a legend bar with the change percentage.
38
+
39
+ ## Install from Source
40
+
41
+ ```bash
42
+ git clone https://github.com/byzkhan/difflens.git
43
+ cd difflens
44
+ npm install
45
+ npm run build
46
+ ```
47
+
48
+ ## Tools
49
+
50
+ ### snapshot
51
+
52
+ Take a screenshot and save it as a baseline.
53
+
54
+ | Parameter | Type | Default | Description |
55
+ |-----------|------|---------|-------------|
56
+ | `url` | string | required | URL to screenshot |
57
+ | `width` | number | 1280 | Viewport width |
58
+ | `height` | number | 720 | Viewport height |
59
+ | `fullPage` | boolean | true | Capture full scrollable page |
60
+ | `waitForSelector` | string | — | CSS selector to wait for before capture |
61
+ | `waitForTimeout` | number | — | Extra wait time in ms |
62
+
63
+ ### check
64
+
65
+ Take a new screenshot and diff it against the latest baseline (or a specific snapshot). Returns a structured report and an overlay image.
66
+
67
+ | Parameter | Type | Default | Description |
68
+ |-----------|------|---------|-------------|
69
+ | `url` | string | required | URL to check |
70
+ | `baselineId` | string | latest | Specific snapshot ID to compare against |
71
+ | `width` | number | 1280 | Viewport width |
72
+ | `height` | number | 720 | Viewport height |
73
+ | `fullPage` | boolean | true | Capture full scrollable page |
74
+ | `waitForSelector` | string | — | CSS selector to wait for |
75
+ | `waitForTimeout` | number | — | Extra wait time in ms |
76
+
77
+ The report includes:
78
+ - **status**: `no_changes`, `minor` (<1%), `significant` (<10%), or `major` (>10%)
79
+ - **percentChanged**: exact pixel change percentage
80
+ - **regions**: list of changed areas with position descriptions and pixel counts
81
+ - **overlay image**: annotated composite showing exactly what changed
82
+
83
+ ### check_responsive
84
+
85
+ Run visual diffs at multiple viewport widths to catch responsive design regressions.
86
+
87
+ | Parameter | Type | Default | Description |
88
+ |-----------|------|---------|-------------|
89
+ | `url` | string | required | URL to check |
90
+ | `widths` | number[] | [375, 768, 1024, 1440] | Viewport widths to test |
91
+ | `height` | number | 720 | Viewport height |
92
+ | `fullPage` | boolean | true | Capture full scrollable page |
93
+ | `waitForSelector` | string | — | CSS selector to wait for |
94
+ | `waitForTimeout` | number | — | Extra wait time in ms |
95
+
96
+ ### snapshot_element
97
+
98
+ Screenshot a specific DOM element by CSS selector. Returns the image inline.
99
+
100
+ | Parameter | Type | Default | Description |
101
+ |-----------|------|---------|-------------|
102
+ | `url` | string | required | URL containing the element |
103
+ | `selector` | string | required | CSS selector to capture |
104
+ | `width` | number | 1280 | Viewport width |
105
+ | `height` | number | 720 | Viewport height |
106
+ | `waitForSelector` | string | — | CSS selector to wait for |
107
+ | `waitForTimeout` | number | — | Extra wait time in ms |
108
+
109
+ ### list_snapshots
110
+
111
+ List stored snapshots with optional filtering.
112
+
113
+ | Parameter | Type | Default | Description |
114
+ |-----------|------|---------|-------------|
115
+ | `url` | string | — | Filter by URL |
116
+ | `limit` | number | 20 | Max results |
117
+
118
+ ### cleanup
119
+
120
+ Delete old snapshots by age or count.
121
+
122
+ | Parameter | Type | Default | Description |
123
+ |-----------|------|---------|-------------|
124
+ | `maxAgeHours` | number | — | Delete snapshots older than this |
125
+ | `maxCount` | number | — | Keep at most this many (newest first) |
126
+ | `dryRun` | boolean | false | Preview without deleting |
127
+
128
+ ## Example Workflow
129
+
130
+ ```
131
+ You: Take a snapshot of http://localhost:3000
132
+ Agent: [calls snapshot] ✓ Saved baseline snapshot abc123
133
+
134
+ ... you edit some CSS ...
135
+
136
+ You: Check localhost:3000 for visual changes
137
+ Agent: [calls check] SIGNIFICANT: 4.2% pixels changed.
138
+ 2 changed region(s) detected:
139
+ 1. Top-left area (400x60px) — header color change
140
+ 2. Middle-center area (600x200px) — card layout shift
141
+ [shows overlay image]
142
+ ```
143
+
144
+ ## Storage
145
+
146
+ All data is stored locally in `.difflens/`:
147
+ - `.difflens/snapshots/` — PNG screenshots + JSON metadata
148
+ - `.difflens/diffs/` — diff images and overlay composites
149
+
150
+ Add `.difflens/` to your `.gitignore`.
151
+
152
+ ## Implementation Details
153
+
154
+ - **Browser reuse**: Playwright Chromium launches once and stays alive. Each screenshot creates an isolated `BrowserContext` (~200ms vs ~3s for a new browser).
155
+ - **Deterministic captures**: Anti-animation CSS is injected before page JS runs. Animations, transitions, and caret blink are disabled. Timezone is locked to UTC, locale to en-US.
156
+ - **Region clustering**: Changed pixels are grouped into a 10x10px grid, then nearby cells are merged within 50px proximity. This turns raw pixel noise into meaningful "the header changed" regions.
157
+ - **Atomic writes**: Snapshots are written to `.tmp` files then renamed, preventing corruption from concurrent access.
158
+ - **stdio-safe**: All logging goes to stderr. stdout is reserved for MCP protocol messages.
159
+
160
+ ## Tech Stack
161
+
162
+ - [Model Context Protocol SDK](https://github.com/modelcontextprotocol/typescript-sdk) — MCP server framework
163
+ - [Playwright](https://playwright.dev/) — headless browser automation
164
+ - [pixelmatch](https://github.com/mapbox/pixelmatch) — pixel-level image comparison
165
+ - [sharp](https://sharp.pixelplumbing.com/) — image compositing for overlays
166
+ - [pngjs](https://github.com/lukeapage/pngjs) — PNG encoding/decoding
167
+ - [Zod](https://zod.dev/) — input validation for tool schemas
168
+
169
+ ## License
170
+
171
+ MIT
@@ -0,0 +1,2 @@
1
+ import type { DiffResult } from './types.js';
2
+ export declare function computeDiff(beforeBuffer: Buffer, afterBuffer: Buffer, diffId: string): Promise<DiffResult>;
package/dist/differ.js ADDED
@@ -0,0 +1,293 @@
1
+ import pixelmatch from 'pixelmatch';
2
+ import { PNG } from 'pngjs';
3
+ import sharp from 'sharp';
4
+ import { join } from 'node:path';
5
+ import { getDiffsDir } from './storage.js';
6
+ const log = (msg) => process.stderr.write(`[difflens] ${msg}\n`);
7
+ function decodePng(buffer) {
8
+ return PNG.sync.read(buffer);
9
+ }
10
+ function normalizeDimensions(beforePng, afterPng) {
11
+ const width = Math.max(beforePng.width, afterPng.width);
12
+ const height = Math.max(beforePng.height, afterPng.height);
13
+ const padImage = (png, targetW, targetH) => {
14
+ if (png.width === targetW && png.height === targetH)
15
+ return png;
16
+ const padded = new PNG({ width: targetW, height: targetH, fill: true });
17
+ // Fill with transparent pixels
18
+ padded.data.fill(0);
19
+ // Copy original pixels
20
+ for (let y = 0; y < png.height; y++) {
21
+ for (let x = 0; x < png.width; x++) {
22
+ const srcIdx = (y * png.width + x) * 4;
23
+ const dstIdx = (y * targetW + x) * 4;
24
+ padded.data[srcIdx] !== undefined && padded.data.copy(padded.data, dstIdx, srcIdx, srcIdx); // noop placeholder
25
+ // Direct pixel copy
26
+ padded.data[dstIdx] = png.data[srcIdx];
27
+ padded.data[dstIdx + 1] = png.data[srcIdx + 1];
28
+ padded.data[dstIdx + 2] = png.data[srcIdx + 2];
29
+ padded.data[dstIdx + 3] = png.data[srcIdx + 3];
30
+ }
31
+ }
32
+ return padded;
33
+ };
34
+ return {
35
+ before: padImage(beforePng, width, height),
36
+ after: padImage(afterPng, width, height),
37
+ width,
38
+ height,
39
+ };
40
+ }
41
+ function clusterRegions(diffData, width, height) {
42
+ const CELL_SIZE = 10;
43
+ const MERGE_DISTANCE = 50;
44
+ const cols = Math.ceil(width / CELL_SIZE);
45
+ const rows = Math.ceil(height / CELL_SIZE);
46
+ // Count changed pixels per grid cell
47
+ // A pixel is "changed" if it's red in the diff output (R=255, G=0 or near 0)
48
+ const cellCounts = Array.from({ length: rows }, () => new Array(cols).fill(0));
49
+ for (let y = 0; y < height; y++) {
50
+ for (let x = 0; x < width; x++) {
51
+ const idx = (y * width + x) * 4;
52
+ const r = diffData[idx];
53
+ const g = diffData[idx + 1];
54
+ const b = diffData[idx + 2];
55
+ const a = diffData[idx + 3];
56
+ // pixelmatch marks diff pixels as red (255, 0, 0) with full alpha
57
+ if (r > 200 && g < 80 && b < 80 && a > 200) {
58
+ const col = Math.floor(x / CELL_SIZE);
59
+ const row = Math.floor(y / CELL_SIZE);
60
+ cellCounts[row][col]++;
61
+ }
62
+ }
63
+ }
64
+ let boxes = [];
65
+ for (let row = 0; row < rows; row++) {
66
+ for (let col = 0; col < cols; col++) {
67
+ if (cellCounts[row][col] > 0) {
68
+ boxes.push({
69
+ x1: col * CELL_SIZE,
70
+ y1: row * CELL_SIZE,
71
+ x2: Math.min((col + 1) * CELL_SIZE, width),
72
+ y2: Math.min((row + 1) * CELL_SIZE, height),
73
+ changedPixels: cellCounts[row][col],
74
+ });
75
+ }
76
+ }
77
+ }
78
+ // Iterative merge: merge boxes within proximity
79
+ let merged = true;
80
+ while (merged) {
81
+ merged = false;
82
+ const newBoxes = [];
83
+ const used = new Set();
84
+ for (let i = 0; i < boxes.length; i++) {
85
+ if (used.has(i))
86
+ continue;
87
+ let current = { ...boxes[i] };
88
+ for (let j = i + 1; j < boxes.length; j++) {
89
+ if (used.has(j))
90
+ continue;
91
+ const other = boxes[j];
92
+ // Check proximity
93
+ const dx = Math.max(0, Math.max(current.x1, other.x1) - Math.min(current.x2, other.x2));
94
+ const dy = Math.max(0, Math.max(current.y1, other.y1) - Math.min(current.y2, other.y2));
95
+ if (dx <= MERGE_DISTANCE && dy <= MERGE_DISTANCE) {
96
+ current = {
97
+ x1: Math.min(current.x1, other.x1),
98
+ y1: Math.min(current.y1, other.y1),
99
+ x2: Math.max(current.x2, other.x2),
100
+ y2: Math.max(current.y2, other.y2),
101
+ changedPixels: current.changedPixels + other.changedPixels,
102
+ };
103
+ used.add(j);
104
+ merged = true;
105
+ }
106
+ }
107
+ newBoxes.push(current);
108
+ }
109
+ boxes = newBoxes;
110
+ }
111
+ // Convert to DiffRegion[]
112
+ const totalPixels = width * height;
113
+ return boxes
114
+ .map((box) => {
115
+ const regionWidth = box.x2 - box.x1;
116
+ const regionHeight = box.y2 - box.y1;
117
+ const regionPixels = regionWidth * regionHeight;
118
+ return {
119
+ x: box.x1,
120
+ y: box.y1,
121
+ width: regionWidth,
122
+ height: regionHeight,
123
+ changedPixels: box.changedPixels,
124
+ percentChanged: (box.changedPixels / regionPixels) * 100,
125
+ description: describePosition(box.x1, box.y1, regionWidth, regionHeight, width, height),
126
+ };
127
+ })
128
+ .sort((a, b) => b.changedPixels - a.changedPixels);
129
+ }
130
+ function describePosition(x, y, w, h, imgW, imgH) {
131
+ const cx = x + w / 2;
132
+ const cy = y + h / 2;
133
+ const horizontal = cx < imgW / 3 ? 'Left' : cx > (imgW * 2) / 3 ? 'Right' : 'Center';
134
+ const vertical = cy < imgH / 3 ? 'Top' : cy > (imgH * 2) / 3 ? 'Bottom' : 'Middle';
135
+ return `${vertical}-${horizontal.toLowerCase()} area (${w}x${h}px)`;
136
+ }
137
+ async function createOverlay(afterBuffer, diffPng, regions, width, height, percentChanged) {
138
+ // Layer 1: Semi-transparent dark overlay for unchanged areas
139
+ const darkOverlay = Buffer.alloc(width * height * 4);
140
+ for (let i = 0; i < width * height; i++) {
141
+ const idx = i * 4;
142
+ const r = diffPng.data[idx];
143
+ const g = diffPng.data[idx + 1];
144
+ const b = diffPng.data[idx + 2];
145
+ const isChanged = r > 200 && g < 80 && b < 80;
146
+ if (!isChanged) {
147
+ // Darken unchanged areas
148
+ darkOverlay[idx] = 0;
149
+ darkOverlay[idx + 1] = 0;
150
+ darkOverlay[idx + 2] = 0;
151
+ darkOverlay[idx + 3] = 80; // semi-transparent black
152
+ }
153
+ else {
154
+ darkOverlay[idx] = 0;
155
+ darkOverlay[idx + 1] = 0;
156
+ darkOverlay[idx + 2] = 0;
157
+ darkOverlay[idx + 3] = 0; // transparent over changed areas
158
+ }
159
+ }
160
+ // Layer 2: Red highlight on changed pixels
161
+ const redHighlight = Buffer.alloc(width * height * 4);
162
+ for (let i = 0; i < width * height; i++) {
163
+ const idx = i * 4;
164
+ const r = diffPng.data[idx];
165
+ const g = diffPng.data[idx + 1];
166
+ const b = diffPng.data[idx + 2];
167
+ const isChanged = r > 200 && g < 80 && b < 80;
168
+ if (isChanged) {
169
+ redHighlight[idx] = 255;
170
+ redHighlight[idx + 1] = 0;
171
+ redHighlight[idx + 2] = 0;
172
+ redHighlight[idx + 3] = 100; // semi-transparent red
173
+ }
174
+ }
175
+ // Layer 3: Region borders (2px red)
176
+ const borders = Buffer.alloc(width * height * 4);
177
+ const BORDER_WIDTH = 2;
178
+ for (const region of regions) {
179
+ for (let px = region.x; px < region.x + region.width; px++) {
180
+ for (let bw = 0; bw < BORDER_WIDTH; bw++) {
181
+ // Top border
182
+ const topY = region.y + bw;
183
+ if (topY < height && px < width) {
184
+ const idx = (topY * width + px) * 4;
185
+ borders[idx] = 255;
186
+ borders[idx + 1] = 50;
187
+ borders[idx + 2] = 50;
188
+ borders[idx + 3] = 220;
189
+ }
190
+ // Bottom border
191
+ const botY = region.y + region.height - 1 - bw;
192
+ if (botY >= 0 && botY < height && px < width) {
193
+ const idx = (botY * width + px) * 4;
194
+ borders[idx] = 255;
195
+ borders[idx + 1] = 50;
196
+ borders[idx + 2] = 50;
197
+ borders[idx + 3] = 220;
198
+ }
199
+ }
200
+ }
201
+ for (let py = region.y; py < region.y + region.height; py++) {
202
+ for (let bw = 0; bw < BORDER_WIDTH; bw++) {
203
+ // Left border
204
+ const leftX = region.x + bw;
205
+ if (py < height && leftX < width) {
206
+ const idx = (py * width + leftX) * 4;
207
+ borders[idx] = 255;
208
+ borders[idx + 1] = 50;
209
+ borders[idx + 2] = 50;
210
+ borders[idx + 3] = 220;
211
+ }
212
+ // Right border
213
+ const rightX = region.x + region.width - 1 - bw;
214
+ if (py < height && rightX >= 0 && rightX < width) {
215
+ const idx = (py * width + rightX) * 4;
216
+ borders[idx] = 255;
217
+ borders[idx + 1] = 50;
218
+ borders[idx + 2] = 50;
219
+ borders[idx + 3] = 220;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ // Layer 4: Legend bar at bottom
225
+ const legendHeight = 40;
226
+ const totalHeight = height + legendHeight;
227
+ const statusText = percentChanged === 0 ? 'No changes' :
228
+ percentChanged < 1 ? 'Minor changes' :
229
+ percentChanged < 10 ? 'Significant changes' : 'Major changes';
230
+ const legendSvg = `<svg width="${width}" height="${legendHeight}">
231
+ <rect width="${width}" height="${legendHeight}" fill="#1a1a2e"/>
232
+ <rect x="10" y="10" width="20" height="20" fill="rgba(255,0,0,0.4)" stroke="#ff3232" stroke-width="2"/>
233
+ <text x="40" y="25" fill="white" font-family="Arial, sans-serif" font-size="14">
234
+ ${statusText} — ${percentChanged.toFixed(2)}% pixels changed — ${regions.length} region(s) detected
235
+ </text>
236
+ </svg>`;
237
+ // Composite all layers
238
+ const overlay = await sharp(afterBuffer)
239
+ .resize(width, height, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })
240
+ .ensureAlpha()
241
+ .composite([
242
+ { input: await sharp(darkOverlay, { raw: { width, height, channels: 4 } }).png().toBuffer(), blend: 'over' },
243
+ { input: await sharp(redHighlight, { raw: { width, height, channels: 4 } }).png().toBuffer(), blend: 'over' },
244
+ { input: await sharp(borders, { raw: { width, height, channels: 4 } }).png().toBuffer(), blend: 'over' },
245
+ ])
246
+ .png()
247
+ .toBuffer();
248
+ // Extend canvas and add legend
249
+ const final = await sharp(overlay)
250
+ .extend({ bottom: legendHeight, background: { r: 0, g: 0, b: 0, alpha: 255 } })
251
+ .composite([
252
+ { input: Buffer.from(legendSvg), top: height, left: 0 },
253
+ ])
254
+ .png()
255
+ .toBuffer();
256
+ return final;
257
+ }
258
+ export async function computeDiff(beforeBuffer, afterBuffer, diffId) {
259
+ log('Computing visual diff...');
260
+ const beforePng = decodePng(beforeBuffer);
261
+ const afterPng = decodePng(afterBuffer);
262
+ const beforeDims = { width: beforePng.width, height: beforePng.height };
263
+ const afterDims = { width: afterPng.width, height: afterPng.height };
264
+ const resized = beforeDims.width !== afterDims.width || beforeDims.height !== afterDims.height;
265
+ const { before, after, width, height } = normalizeDimensions(beforePng, afterPng);
266
+ // Run pixelmatch
267
+ const diffOutput = new PNG({ width, height });
268
+ const changedPixels = pixelmatch(before.data, after.data, diffOutput.data, width, height, { threshold: 0.1, includeAA: false, diffColor: [255, 0, 0] });
269
+ const totalPixels = width * height;
270
+ const percentChanged = (changedPixels / totalPixels) * 100;
271
+ log(`Diff: ${changedPixels}/${totalPixels} pixels changed (${percentChanged.toFixed(2)}%)`);
272
+ // Save raw diff image
273
+ const diffImagePath = join(getDiffsDir(), `${diffId}-diff.png`);
274
+ const diffBuffer = PNG.sync.write(diffOutput);
275
+ const { writeFile } = await import('node:fs/promises');
276
+ await writeFile(diffImagePath, diffBuffer);
277
+ // Cluster changed regions
278
+ const regions = clusterRegions(diffOutput.data, width, height);
279
+ // Create overlay
280
+ const overlayBuffer = await createOverlay(afterBuffer, diffOutput, regions, width, height, percentChanged);
281
+ const overlayImagePath = join(getDiffsDir(), `${diffId}-overlay.png`);
282
+ await writeFile(overlayImagePath, overlayBuffer);
283
+ return {
284
+ totalPixels,
285
+ changedPixels,
286
+ percentChanged,
287
+ dimensions: { before: beforeDims, after: afterDims, resized },
288
+ regions,
289
+ diffImagePath,
290
+ overlayImagePath,
291
+ };
292
+ }
293
+ //# sourceMappingURL=differ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"differ.js","sourceRoot":"","sources":["../src/differ.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};