codeloop-mcp-server 0.1.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 (101) hide show
  1. package/dist/auth/api_key.d.ts +6 -0
  2. package/dist/auth/api_key.d.ts.map +1 -0
  3. package/dist/auth/api_key.js +87 -0
  4. package/dist/auth/api_key.js.map +1 -0
  5. package/dist/auth/usage_tracker.d.ts +7 -0
  6. package/dist/auth/usage_tracker.d.ts.map +1 -0
  7. package/dist/auth/usage_tracker.js +71 -0
  8. package/dist/auth/usage_tracker.js.map +1 -0
  9. package/dist/config.d.ts +4 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +41 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/diagnosis/vision_reviewer.d.ts +27 -0
  14. package/dist/diagnosis/vision_reviewer.d.ts.map +1 -0
  15. package/dist/diagnosis/vision_reviewer.js +345 -0
  16. package/dist/diagnosis/vision_reviewer.js.map +1 -0
  17. package/dist/evidence/artifacts.d.ts +12 -0
  18. package/dist/evidence/artifacts.d.ts.map +1 -0
  19. package/dist/evidence/artifacts.js +60 -0
  20. package/dist/evidence/artifacts.js.map +1 -0
  21. package/dist/evidence/screenshot_diff.d.ts +30 -0
  22. package/dist/evidence/screenshot_diff.d.ts.map +1 -0
  23. package/dist/evidence/screenshot_diff.js +144 -0
  24. package/dist/evidence/screenshot_diff.js.map +1 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +276 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/recommendations/knowledge_base.d.ts +21 -0
  30. package/dist/recommendations/knowledge_base.d.ts.map +1 -0
  31. package/dist/recommendations/knowledge_base.js +839 -0
  32. package/dist/recommendations/knowledge_base.js.map +1 -0
  33. package/dist/recommendations/selector.d.ts +3 -0
  34. package/dist/recommendations/selector.d.ts.map +1 -0
  35. package/dist/recommendations/selector.js +305 -0
  36. package/dist/recommendations/selector.js.map +1 -0
  37. package/dist/runners/base.d.ts +21 -0
  38. package/dist/runners/base.d.ts.map +1 -0
  39. package/dist/runners/base.js +70 -0
  40. package/dist/runners/base.js.map +1 -0
  41. package/dist/runners/flutter.d.ts +4 -0
  42. package/dist/runners/flutter.d.ts.map +1 -0
  43. package/dist/runners/flutter.js +72 -0
  44. package/dist/runners/flutter.js.map +1 -0
  45. package/dist/runners/generic.d.ts +3 -0
  46. package/dist/runners/generic.d.ts.map +1 -0
  47. package/dist/runners/generic.js +65 -0
  48. package/dist/runners/generic.js.map +1 -0
  49. package/dist/runners/maestro.d.ts +12 -0
  50. package/dist/runners/maestro.d.ts.map +1 -0
  51. package/dist/runners/maestro.js +133 -0
  52. package/dist/runners/maestro.js.map +1 -0
  53. package/dist/runners/playwright.d.ts +3 -0
  54. package/dist/runners/playwright.d.ts.map +1 -0
  55. package/dist/runners/playwright.js +76 -0
  56. package/dist/runners/playwright.js.map +1 -0
  57. package/dist/state/section_registry.d.ts +27 -0
  58. package/dist/state/section_registry.d.ts.map +1 -0
  59. package/dist/state/section_registry.js +219 -0
  60. package/dist/state/section_registry.js.map +1 -0
  61. package/dist/tools/design_compare.d.ts +4 -0
  62. package/dist/tools/design_compare.d.ts.map +1 -0
  63. package/dist/tools/design_compare.js +73 -0
  64. package/dist/tools/design_compare.js.map +1 -0
  65. package/dist/tools/diagnose.d.ts +3 -0
  66. package/dist/tools/diagnose.d.ts.map +1 -0
  67. package/dist/tools/diagnose.js +236 -0
  68. package/dist/tools/diagnose.js.map +1 -0
  69. package/dist/tools/gate_check.d.ts +3 -0
  70. package/dist/tools/gate_check.d.ts.map +1 -0
  71. package/dist/tools/gate_check.js +201 -0
  72. package/dist/tools/gate_check.js.map +1 -0
  73. package/dist/tools/integration_check.d.ts +13 -0
  74. package/dist/tools/integration_check.d.ts.map +1 -0
  75. package/dist/tools/integration_check.js +70 -0
  76. package/dist/tools/integration_check.js.map +1 -0
  77. package/dist/tools/release_readiness.d.ts +3 -0
  78. package/dist/tools/release_readiness.d.ts.map +1 -0
  79. package/dist/tools/release_readiness.js +153 -0
  80. package/dist/tools/release_readiness.js.map +1 -0
  81. package/dist/tools/replan.d.ts +12 -0
  82. package/dist/tools/replan.d.ts.map +1 -0
  83. package/dist/tools/replan.js +118 -0
  84. package/dist/tools/replan.js.map +1 -0
  85. package/dist/tools/section_status.d.ts +24 -0
  86. package/dist/tools/section_status.d.ts.map +1 -0
  87. package/dist/tools/section_status.js +61 -0
  88. package/dist/tools/section_status.js.map +1 -0
  89. package/dist/tools/update_baseline.d.ts +11 -0
  90. package/dist/tools/update_baseline.d.ts.map +1 -0
  91. package/dist/tools/update_baseline.js +19 -0
  92. package/dist/tools/update_baseline.js.map +1 -0
  93. package/dist/tools/verify.d.ts +4 -0
  94. package/dist/tools/verify.d.ts.map +1 -0
  95. package/dist/tools/verify.js +136 -0
  96. package/dist/tools/verify.js.map +1 -0
  97. package/dist/tools/visual_review.d.ts +4 -0
  98. package/dist/tools/visual_review.d.ts.map +1 -0
  99. package/dist/tools/visual_review.js +142 -0
  100. package/dist/tools/visual_review.js.map +1 -0
  101. package/package.json +44 -0
@@ -0,0 +1,142 @@
1
+ import { reviewScreenshot } from "../diagnosis/vision_reviewer.js";
2
+ import { diffAllScreenshots } from "../evidence/screenshot_diff.js";
3
+ import { existsSync, readdirSync } from "fs";
4
+ import { join, resolve } from "path";
5
+ import { getArtifactsBaseDir, getRunDir, listRuns } from "../evidence/artifacts.js";
6
+ function listPngFiles(dir) {
7
+ if (!existsSync(dir)) {
8
+ return [];
9
+ }
10
+ return readdirSync(dir).filter((f) => f.toLowerCase().endsWith(".png"));
11
+ }
12
+ export async function runVisualReview(input, config) {
13
+ const cwd = process.cwd();
14
+ const base = getArtifactsBaseDir(cwd);
15
+ let screenshotsDir;
16
+ let runDir;
17
+ if (input.screenshots_dir) {
18
+ screenshotsDir = resolve(cwd, input.screenshots_dir);
19
+ }
20
+ else {
21
+ const runId = input.run_id ?? listRuns(base)[0];
22
+ if (!runId) {
23
+ return {
24
+ issues: [
25
+ {
26
+ issue: "No screenshots available",
27
+ severity: "low",
28
+ confidence: 100,
29
+ evidence: "Provide screenshots_dir or run_id, or run codeloop_verify to produce screenshots.",
30
+ fix_hint: "Set screenshots_dir to a folder of PNGs or pass run_id from a verification run.",
31
+ },
32
+ ],
33
+ visual_diff_score: 1,
34
+ layout_warnings: [],
35
+ accessibility_notes: [],
36
+ screenshots_taken: [],
37
+ };
38
+ }
39
+ runDir = getRunDir(runId, base);
40
+ screenshotsDir = join(runDir, "screenshots");
41
+ }
42
+ if (input.run_id && !runDir) {
43
+ runDir = getRunDir(input.run_id, base);
44
+ }
45
+ if (!screenshotsDir || !existsSync(screenshotsDir)) {
46
+ return {
47
+ issues: [
48
+ {
49
+ issue: "Screenshots directory not found",
50
+ severity: "low",
51
+ confidence: 100,
52
+ evidence: screenshotsDir ?? "(unset)",
53
+ fix_hint: "Verify screenshots_dir or run_id points to an existing run with a screenshots folder.",
54
+ },
55
+ ],
56
+ visual_diff_score: 1,
57
+ layout_warnings: [],
58
+ accessibility_notes: [],
59
+ screenshots_taken: [],
60
+ };
61
+ }
62
+ const pngs = listPngFiles(screenshotsDir);
63
+ const screenshotsTaken = pngs.map((f) => join(screenshotsDir, f));
64
+ if (pngs.length === 0) {
65
+ return {
66
+ issues: [
67
+ {
68
+ issue: "No PNG screenshots found",
69
+ severity: "low",
70
+ confidence: 100,
71
+ evidence: screenshotsDir,
72
+ fix_hint: "Add PNG screenshots to this directory or run verification to capture UI.",
73
+ },
74
+ ],
75
+ visual_diff_score: 1,
76
+ layout_warnings: [],
77
+ accessibility_notes: [],
78
+ screenshots_taken: [],
79
+ };
80
+ }
81
+ const issues = [];
82
+ const layoutWarnings = [];
83
+ let visualDiffScore = 1;
84
+ const baselineDir = input.baseline_dir
85
+ ? resolve(cwd, input.baseline_dir)
86
+ : runDir
87
+ ? join(runDir, "baselines")
88
+ : undefined;
89
+ if (baselineDir && existsSync(baselineDir)) {
90
+ const diffsDir = runDir
91
+ ? join(runDir, "diffs")
92
+ : join(screenshotsDir, "..", "diffs");
93
+ const summary = diffAllScreenshots(screenshotsDir, baselineDir, diffsDir);
94
+ const withBaseline = summary.results.filter((r) => r.baselineExists);
95
+ if (withBaseline.length > 0) {
96
+ const avgMatch = withBaseline.reduce((acc, r) => acc + (1 - r.diffScore), 0) /
97
+ withBaseline.length;
98
+ visualDiffScore = Math.max(0, Math.min(1, avgMatch));
99
+ }
100
+ for (const screen of summary.screensAboveThreshold) {
101
+ layoutWarnings.push(`Pixel diff above threshold for screen "${screen}"`);
102
+ const dr = summary.results.find((x) => x.screen === screen);
103
+ const diffScore = dr?.diffScore ?? 0;
104
+ issues.push({
105
+ issue: `Visual regression detected for "${screen}"`,
106
+ severity: "medium",
107
+ confidence: Math.round(Math.max(0, Math.min(100, (1 - diffScore) * 100))),
108
+ evidence: "Screenshot differs from baseline (pixel diff). See diffs output.",
109
+ fix_hint: "Review the diff image or update the baseline if the change is intentional.",
110
+ });
111
+ }
112
+ }
113
+ const uxPath = input.ux_checklist_path
114
+ ? resolve(cwd, input.ux_checklist_path)
115
+ : undefined;
116
+ let skipExtraVision = false;
117
+ for (const abs of screenshotsTaken) {
118
+ if (skipExtraVision) {
119
+ break;
120
+ }
121
+ const more = await reviewScreenshot({
122
+ imagePath: abs,
123
+ uxChecklistPath: uxPath,
124
+ }, config);
125
+ if (more.length === 1 &&
126
+ more[0].issue === "No vision model configured") {
127
+ issues.push(...more);
128
+ skipExtraVision = true;
129
+ continue;
130
+ }
131
+ issues.push(...more);
132
+ }
133
+ const accessibilityNotes = [];
134
+ return {
135
+ issues,
136
+ visual_diff_score: visualDiffScore,
137
+ layout_warnings: layoutWarnings,
138
+ accessibility_notes: accessibilityNotes,
139
+ screenshots_taken: screenshotsTaken,
140
+ };
141
+ }
142
+ //# sourceMappingURL=visual_review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual_review.js","sourceRoot":"","sources":["../../src/tools/visual_review.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "codeloop-mcp-server",
3
+ "version": "0.1.0",
4
+ "description": "CodeLoop MCP server - verification, self-repair, and recommendation layer for AI coding agents",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "codeloop-mcp-server": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/",
12
+ "README.md"
13
+ ],
14
+ "keywords": [
15
+ "mcp",
16
+ "cursor",
17
+ "claude-code",
18
+ "testing",
19
+ "verification",
20
+ "ai-coding"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "test": "vitest run",
25
+ "lint": "tsc --noEmit && eslint src/",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "dependencies": {
29
+ "@anthropic-ai/sdk": "^0.39.0",
30
+ "@codelooptech/shared": "0.1.0",
31
+ "@google/generative-ai": "^0.21.0",
32
+ "@modelcontextprotocol/sdk": "^1.12.0",
33
+ "openai": "^4.77.0",
34
+ "pixelmatch": "^7.1.0",
35
+ "pngjs": "^7.0.0",
36
+ "zod": "^3.24.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.0.0",
40
+ "@types/pngjs": "^6.0.5",
41
+ "typescript": "^5.8.0",
42
+ "vitest": "^3.1.0"
43
+ }
44
+ }