devlens-mcp 0.1.0 → 0.1.1

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 (3) hide show
  1. package/SKILL.md +2 -2
  2. package/dist/index.js +16 -6
  3. package/package.json +16 -4
package/SKILL.md CHANGED
@@ -16,12 +16,12 @@ You have access to four visual inspection tools: `dl_warmup`, `dl_capture`, `dl_
16
16
  ## Rules — follow these automatically, no user prompting needed
17
17
 
18
18
  ### Rule 1: Warmup at session start
19
- The first time you are about to edit any file matching `apps/web/src/**`, call `dl_warmup` first.
19
+ The first time you are about to edit any frontend file (`.tsx`, `.ts`, `.css`, `.vue`, `.svelte`), call `dl_warmup` first.
20
20
  This pre-warms the browser so subsequent captures cost ~50ms instead of ~500ms.
21
21
  Only call it once per session.
22
22
 
23
23
  ### Rule 2: Capture after every frontend file write
24
- After every `Edit` or `Write` to a file matching `apps/web/src/**/*.tsx` or `apps/web/src/**/*.css`:
24
+ After every `Edit` or `Write` to a file matching `**/*.tsx`, `**/*.vue`, `**/*.svelte`, or `**/*.css`:
25
25
  1. Call `dl_capture` with either `route` (if you know it) or `filePath` (auto-resolved from devlens.config.ts)
26
26
  2. Add `selector` if you only changed a specific component (keeps the image small and fast)
27
27
  3. Look at the returned image — does it look right?
package/dist/index.js CHANGED
@@ -414,16 +414,24 @@ async function startServer() {
414
414
  ]
415
415
  }));
416
416
  server.setRequestHandler(CallToolRequestSchema, async (req) => {
417
- const { name, arguments: args } = req.params;
417
+ const { name } = req.params;
418
+ const args = req.params.arguments ?? {};
419
+ const str = (v) => typeof v === "string" ? v : void 0;
420
+ const num = (v) => typeof v === "number" ? v : void 0;
418
421
  try {
419
422
  if (name === "dl_warmup") {
420
- const result = await warmup(args.devServerUrl, config);
423
+ const result = await warmup(str(args.devServerUrl), config);
421
424
  return {
422
425
  content: [{ type: "text", text: `Warmed up in ${result.durationMs}ms \u2014 ${result.url}` }]
423
426
  };
424
427
  }
425
428
  if (name === "dl_capture") {
426
- const input = args;
429
+ const input = {
430
+ route: str(args.route),
431
+ filePath: str(args.filePath),
432
+ selector: str(args.selector),
433
+ waitMs: num(args.waitMs)
434
+ };
427
435
  const result = await capture(input, config);
428
436
  if ("error" in result) {
429
437
  return { content: [{ type: "text", text: `Error: ${result.error}` }] };
@@ -437,11 +445,12 @@ async function startServer() {
437
445
  return { content };
438
446
  }
439
447
  if (name === "dl_diff") {
440
- const { route, selector } = args;
448
+ const route = str(args.route) ?? "";
449
+ const selector = str(args.selector);
441
450
  const result = await diff(route, selector, diffStore, config);
442
451
  if ("error" in result) return { content: [{ type: "text", text: `Error: ${result.error}` }] };
443
452
  const content = [
444
- { type: "text", text: result.diff ? `Changed: ${result.diff.changedPercent}% (${result.diff.changedPixels} pixels)` : result.message ?? "Baseline set." }
453
+ { type: "text", text: result.diff ? `Changed: ${result.diff.changedPercent}% (${result.diff.changedPixels} pixels)` : "message" in result && typeof result.message === "string" ? result.message : "Baseline set." }
445
454
  ];
446
455
  if (result.diff?.diffImageBase64) {
447
456
  content.push({ type: "image", data: result.diff.diffImageBase64, mimeType: "image/png" });
@@ -449,7 +458,8 @@ async function startServer() {
449
458
  return { content };
450
459
  }
451
460
  if (name === "dl_snapshot") {
452
- const { route, selector } = args;
461
+ const route = str(args.route) ?? "";
462
+ const selector = str(args.selector);
453
463
  const result = await snapshot(route, selector, config);
454
464
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
455
465
  }
package/package.json CHANGED
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "devlens-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Real-time visual feedback plugin for Claude Code frontend development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
7
13
  "bin": {
8
14
  "devlens-mcp": "dist/index.js"
9
15
  },
@@ -26,19 +32,25 @@
26
32
  "dev": "tsup --watch",
27
33
  "test": "vitest run",
28
34
  "test:watch": "vitest",
29
- "start": "node dist/index.js"
35
+ "start": "node dist/index.js",
36
+ "lint": "eslint src --ext .ts",
37
+ "format": "prettier --write src"
30
38
  },
31
39
  "dependencies": {
32
40
  "@modelcontextprotocol/sdk": "^1.0.0",
33
41
  "minimatch": "^10.2.5",
34
42
  "pixelmatch": "^6.0.0",
35
43
  "playwright": "^1.45.0",
36
- "pngjs": "^7.0.0",
37
- "zod": "^3.22.0"
44
+ "pngjs": "^7.0.0"
38
45
  },
39
46
  "devDependencies": {
40
47
  "@types/node": "^20.0.0",
41
48
  "@types/pngjs": "^6.0.0",
49
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
50
+ "@typescript-eslint/parser": "^7.0.0",
51
+ "eslint": "^8.57.0",
52
+ "eslint-config-prettier": "^9.0.0",
53
+ "prettier": "^3.0.0",
42
54
  "tsup": "^8.0.0",
43
55
  "typescript": "^5.4.0",
44
56
  "vitest": "^1.6.0"