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.
- package/dist/auth/api_key.d.ts +6 -0
- package/dist/auth/api_key.d.ts.map +1 -0
- package/dist/auth/api_key.js +87 -0
- package/dist/auth/api_key.js.map +1 -0
- package/dist/auth/usage_tracker.d.ts +7 -0
- package/dist/auth/usage_tracker.d.ts.map +1 -0
- package/dist/auth/usage_tracker.js +71 -0
- package/dist/auth/usage_tracker.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +41 -0
- package/dist/config.js.map +1 -0
- package/dist/diagnosis/vision_reviewer.d.ts +27 -0
- package/dist/diagnosis/vision_reviewer.d.ts.map +1 -0
- package/dist/diagnosis/vision_reviewer.js +345 -0
- package/dist/diagnosis/vision_reviewer.js.map +1 -0
- package/dist/evidence/artifacts.d.ts +12 -0
- package/dist/evidence/artifacts.d.ts.map +1 -0
- package/dist/evidence/artifacts.js +60 -0
- package/dist/evidence/artifacts.js.map +1 -0
- package/dist/evidence/screenshot_diff.d.ts +30 -0
- package/dist/evidence/screenshot_diff.d.ts.map +1 -0
- package/dist/evidence/screenshot_diff.js +144 -0
- package/dist/evidence/screenshot_diff.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +276 -0
- package/dist/index.js.map +1 -0
- package/dist/recommendations/knowledge_base.d.ts +21 -0
- package/dist/recommendations/knowledge_base.d.ts.map +1 -0
- package/dist/recommendations/knowledge_base.js +839 -0
- package/dist/recommendations/knowledge_base.js.map +1 -0
- package/dist/recommendations/selector.d.ts +3 -0
- package/dist/recommendations/selector.d.ts.map +1 -0
- package/dist/recommendations/selector.js +305 -0
- package/dist/recommendations/selector.js.map +1 -0
- package/dist/runners/base.d.ts +21 -0
- package/dist/runners/base.d.ts.map +1 -0
- package/dist/runners/base.js +70 -0
- package/dist/runners/base.js.map +1 -0
- package/dist/runners/flutter.d.ts +4 -0
- package/dist/runners/flutter.d.ts.map +1 -0
- package/dist/runners/flutter.js +72 -0
- package/dist/runners/flutter.js.map +1 -0
- package/dist/runners/generic.d.ts +3 -0
- package/dist/runners/generic.d.ts.map +1 -0
- package/dist/runners/generic.js +65 -0
- package/dist/runners/generic.js.map +1 -0
- package/dist/runners/maestro.d.ts +12 -0
- package/dist/runners/maestro.d.ts.map +1 -0
- package/dist/runners/maestro.js +133 -0
- package/dist/runners/maestro.js.map +1 -0
- package/dist/runners/playwright.d.ts +3 -0
- package/dist/runners/playwright.d.ts.map +1 -0
- package/dist/runners/playwright.js +76 -0
- package/dist/runners/playwright.js.map +1 -0
- package/dist/state/section_registry.d.ts +27 -0
- package/dist/state/section_registry.d.ts.map +1 -0
- package/dist/state/section_registry.js +219 -0
- package/dist/state/section_registry.js.map +1 -0
- package/dist/tools/design_compare.d.ts +4 -0
- package/dist/tools/design_compare.d.ts.map +1 -0
- package/dist/tools/design_compare.js +73 -0
- package/dist/tools/design_compare.js.map +1 -0
- package/dist/tools/diagnose.d.ts +3 -0
- package/dist/tools/diagnose.d.ts.map +1 -0
- package/dist/tools/diagnose.js +236 -0
- package/dist/tools/diagnose.js.map +1 -0
- package/dist/tools/gate_check.d.ts +3 -0
- package/dist/tools/gate_check.d.ts.map +1 -0
- package/dist/tools/gate_check.js +201 -0
- package/dist/tools/gate_check.js.map +1 -0
- package/dist/tools/integration_check.d.ts +13 -0
- package/dist/tools/integration_check.d.ts.map +1 -0
- package/dist/tools/integration_check.js +70 -0
- package/dist/tools/integration_check.js.map +1 -0
- package/dist/tools/release_readiness.d.ts +3 -0
- package/dist/tools/release_readiness.d.ts.map +1 -0
- package/dist/tools/release_readiness.js +153 -0
- package/dist/tools/release_readiness.js.map +1 -0
- package/dist/tools/replan.d.ts +12 -0
- package/dist/tools/replan.d.ts.map +1 -0
- package/dist/tools/replan.js +118 -0
- package/dist/tools/replan.js.map +1 -0
- package/dist/tools/section_status.d.ts +24 -0
- package/dist/tools/section_status.d.ts.map +1 -0
- package/dist/tools/section_status.js +61 -0
- package/dist/tools/section_status.js.map +1 -0
- package/dist/tools/update_baseline.d.ts +11 -0
- package/dist/tools/update_baseline.d.ts.map +1 -0
- package/dist/tools/update_baseline.js +19 -0
- package/dist/tools/update_baseline.js.map +1 -0
- package/dist/tools/verify.d.ts +4 -0
- package/dist/tools/verify.d.ts.map +1 -0
- package/dist/tools/verify.js +136 -0
- package/dist/tools/verify.js.map +1 -0
- package/dist/tools/visual_review.d.ts +4 -0
- package/dist/tools/visual_review.d.ts.map +1 -0
- package/dist/tools/visual_review.js +142 -0
- package/dist/tools/visual_review.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/evidence/artifacts.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIxD,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAEvE;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAWnC;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,GACzB,IAAI,CAGN;AAED,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAmB7B;AAED,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAWnD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAGjE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync, readFileSync, existsSync, readdirSync, } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
const RUN_SUBDIRS = ["logs", "screenshots", "baselines", "diffs", "traces", "videos"];
|
|
4
|
+
export function generateRunId() {
|
|
5
|
+
const timestamp = Date.now();
|
|
6
|
+
const random = Math.random().toString(36).slice(2, 8);
|
|
7
|
+
return `run_${timestamp}_${random}`;
|
|
8
|
+
}
|
|
9
|
+
export function getArtifactsBaseDir(cwd = process.cwd()) {
|
|
10
|
+
return join(cwd, "artifacts", "runs");
|
|
11
|
+
}
|
|
12
|
+
export function createRunDir(runId, baseDir) {
|
|
13
|
+
const id = runId || generateRunId();
|
|
14
|
+
const base = baseDir || getArtifactsBaseDir();
|
|
15
|
+
const runDir = join(base, id);
|
|
16
|
+
mkdirSync(runDir, { recursive: true });
|
|
17
|
+
for (const subdir of RUN_SUBDIRS) {
|
|
18
|
+
mkdirSync(join(runDir, subdir), { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
return { runId: id, runDir };
|
|
21
|
+
}
|
|
22
|
+
export function saveRunMeta(runDir, meta) {
|
|
23
|
+
const metaPath = join(runDir, "meta.json");
|
|
24
|
+
writeFileSync(metaPath, JSON.stringify(meta, null, 2));
|
|
25
|
+
}
|
|
26
|
+
export function loadRunMeta(runIdOrDir, baseDir) {
|
|
27
|
+
let metaPath;
|
|
28
|
+
if (existsSync(join(runIdOrDir, "meta.json"))) {
|
|
29
|
+
metaPath = join(runIdOrDir, "meta.json");
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const base = baseDir || getArtifactsBaseDir();
|
|
33
|
+
metaPath = join(base, runIdOrDir, "meta.json");
|
|
34
|
+
}
|
|
35
|
+
if (!existsSync(metaPath)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(readFileSync(metaPath, "utf-8"));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function listRuns(baseDir) {
|
|
46
|
+
const base = baseDir || getArtifactsBaseDir();
|
|
47
|
+
if (!existsSync(base)) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
return readdirSync(base, { withFileTypes: true })
|
|
51
|
+
.filter((d) => d.isDirectory() && d.name.startsWith("run_"))
|
|
52
|
+
.map((d) => d.name)
|
|
53
|
+
.sort()
|
|
54
|
+
.reverse();
|
|
55
|
+
}
|
|
56
|
+
export function getRunDir(runId, baseDir) {
|
|
57
|
+
const base = baseDir || getArtifactsBaseDir();
|
|
58
|
+
return join(base, runId);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/evidence/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface DiffResult {
|
|
2
|
+
screen: string;
|
|
3
|
+
diffScore: number;
|
|
4
|
+
diffPixels: number;
|
|
5
|
+
totalPixels: number;
|
|
6
|
+
diffImagePath: string | null;
|
|
7
|
+
baselineExists: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ScreenshotDiffSummary {
|
|
10
|
+
results: DiffResult[];
|
|
11
|
+
screenshotsCompared: number;
|
|
12
|
+
baselineExists: boolean;
|
|
13
|
+
screensAboveThreshold: string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compare two PNG images pixel-by-pixel.
|
|
17
|
+
* Size mismatches are handled by padding both images to the larger width and height (white fill), then comparing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function compareScreenshot(screenshotPath: string, baselinePath: string, diffOutputPath: string, threshold?: number): DiffResult;
|
|
20
|
+
/**
|
|
21
|
+
* Compare every PNG in `screenshotsDir` to the same filename under `baselinesDir`.
|
|
22
|
+
* Writes diff images to `diffsDir` using the same base filename.
|
|
23
|
+
*/
|
|
24
|
+
export declare function diffAllScreenshots(screenshotsDir: string, baselinesDir: string, diffsDir: string, threshold?: number): ScreenshotDiffSummary;
|
|
25
|
+
/**
|
|
26
|
+
* Copy current screenshots into `baselinesDir` (creates the directory if needed).
|
|
27
|
+
* If `screens` is set, only those screen names (without `.png`) are updated; otherwise all PNGs are copied.
|
|
28
|
+
*/
|
|
29
|
+
export declare function updateBaselines(screenshotsDir: string, baselinesDir: string, screens?: string[]): string[];
|
|
30
|
+
//# sourceMappingURL=screenshot_diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot_diff.d.ts","sourceRoot":"","sources":["../../src/evidence/screenshot_diff.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC;AAqDD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,SAAS,GAAE,MAA0B,GACpC,UAAU,CAmCZ;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAA0B,GACpC,qBAAqB,CA+CvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,MAAM,EAAE,CAwBV"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import pixelmatch from "pixelmatch";
|
|
2
|
+
import { PNG } from "pngjs";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, } from "fs";
|
|
4
|
+
import { join, basename, dirname } from "path";
|
|
5
|
+
const DEFAULT_THRESHOLD = 0.1;
|
|
6
|
+
function screenNameFromPath(filePath) {
|
|
7
|
+
const base = basename(filePath);
|
|
8
|
+
return base.replace(/\.png$/i, "") || base;
|
|
9
|
+
}
|
|
10
|
+
function listPngFiles(dir) {
|
|
11
|
+
if (!existsSync(dir)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
return readdirSync(dir).filter((f) => f.toLowerCase().endsWith(".png"));
|
|
15
|
+
}
|
|
16
|
+
function readPng(path) {
|
|
17
|
+
return PNG.sync.read(readFileSync(path));
|
|
18
|
+
}
|
|
19
|
+
/** Pads image data to `width` x `height` (top-left aligned, white background). */
|
|
20
|
+
function rgbaToCanvas(data, srcW, srcH, width, height) {
|
|
21
|
+
const out = Buffer.alloc(width * height * 4);
|
|
22
|
+
out.fill(255);
|
|
23
|
+
for (let y = 0; y < srcH; y++) {
|
|
24
|
+
for (let x = 0; x < srcW; x++) {
|
|
25
|
+
const si = (y * srcW + x) * 4;
|
|
26
|
+
const di = (y * width + x) * 4;
|
|
27
|
+
data.copy(out, di, si, si + 4);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
function prepareCompareBuffers(a, b) {
|
|
33
|
+
const width = Math.max(a.width, b.width);
|
|
34
|
+
const height = Math.max(a.height, b.height);
|
|
35
|
+
if (a.width === width && a.height === height && b.width === width && b.height === height) {
|
|
36
|
+
return { width, height, buf1: a.data, buf2: b.data };
|
|
37
|
+
}
|
|
38
|
+
const buf1 = a.width === width && a.height === height ? a.data : rgbaToCanvas(a.data, a.width, a.height, width, height);
|
|
39
|
+
const buf2 = b.width === width && b.height === height ? b.data : rgbaToCanvas(b.data, b.width, b.height, width, height);
|
|
40
|
+
return { width, height, buf1, buf2 };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compare two PNG images pixel-by-pixel.
|
|
44
|
+
* Size mismatches are handled by padding both images to the larger width and height (white fill), then comparing.
|
|
45
|
+
*/
|
|
46
|
+
export function compareScreenshot(screenshotPath, baselinePath, diffOutputPath, threshold = DEFAULT_THRESHOLD) {
|
|
47
|
+
const screen = screenNameFromPath(screenshotPath);
|
|
48
|
+
if (!existsSync(screenshotPath) || !existsSync(baselinePath)) {
|
|
49
|
+
throw new Error(`compareScreenshot: missing file(s) — screenshot: ${screenshotPath}, baseline: ${baselinePath}`);
|
|
50
|
+
}
|
|
51
|
+
const img1 = readPng(screenshotPath);
|
|
52
|
+
const img2 = readPng(baselinePath);
|
|
53
|
+
const { width, height, buf1, buf2 } = prepareCompareBuffers(img1, img2);
|
|
54
|
+
const totalPixels = width * height;
|
|
55
|
+
mkdirSync(dirname(diffOutputPath), { recursive: true });
|
|
56
|
+
const diff = Buffer.alloc(totalPixels * 4);
|
|
57
|
+
const diffPixels = pixelmatch(buf1, buf2, diff, width, height, {
|
|
58
|
+
threshold,
|
|
59
|
+
});
|
|
60
|
+
const outPng = new PNG({ width, height });
|
|
61
|
+
diff.copy(outPng.data);
|
|
62
|
+
writeFileSync(diffOutputPath, PNG.sync.write(outPng));
|
|
63
|
+
const diffScore = totalPixels === 0 ? 0 : diffPixels / totalPixels;
|
|
64
|
+
return {
|
|
65
|
+
screen,
|
|
66
|
+
diffScore,
|
|
67
|
+
diffPixels,
|
|
68
|
+
totalPixels,
|
|
69
|
+
diffImagePath: diffOutputPath,
|
|
70
|
+
baselineExists: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Compare every PNG in `screenshotsDir` to the same filename under `baselinesDir`.
|
|
75
|
+
* Writes diff images to `diffsDir` using the same base filename.
|
|
76
|
+
*/
|
|
77
|
+
export function diffAllScreenshots(screenshotsDir, baselinesDir, diffsDir, threshold = DEFAULT_THRESHOLD) {
|
|
78
|
+
const pngFiles = listPngFiles(screenshotsDir);
|
|
79
|
+
const results = [];
|
|
80
|
+
let allHaveBaselines = true;
|
|
81
|
+
mkdirSync(diffsDir, { recursive: true });
|
|
82
|
+
for (const file of pngFiles) {
|
|
83
|
+
const screenshotPath = join(screenshotsDir, file);
|
|
84
|
+
const baselinePath = join(baselinesDir, file);
|
|
85
|
+
const screen = screenNameFromPath(file);
|
|
86
|
+
if (!existsSync(baselinePath)) {
|
|
87
|
+
allHaveBaselines = false;
|
|
88
|
+
let totalPixels = 0;
|
|
89
|
+
try {
|
|
90
|
+
const png = readPng(screenshotPath);
|
|
91
|
+
totalPixels = png.width * png.height;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
totalPixels = 0;
|
|
95
|
+
}
|
|
96
|
+
results.push({
|
|
97
|
+
screen,
|
|
98
|
+
diffScore: 0,
|
|
99
|
+
diffPixels: 0,
|
|
100
|
+
totalPixels,
|
|
101
|
+
diffImagePath: null,
|
|
102
|
+
baselineExists: false,
|
|
103
|
+
});
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const diffOutputPath = join(diffsDir, file);
|
|
107
|
+
const result = compareScreenshot(screenshotPath, baselinePath, diffOutputPath, threshold);
|
|
108
|
+
results.push(result);
|
|
109
|
+
}
|
|
110
|
+
const screensAboveThreshold = results
|
|
111
|
+
.filter((r) => r.baselineExists && r.diffScore > threshold)
|
|
112
|
+
.map((r) => r.screen);
|
|
113
|
+
return {
|
|
114
|
+
results,
|
|
115
|
+
screenshotsCompared: results.length,
|
|
116
|
+
baselineExists: allHaveBaselines,
|
|
117
|
+
screensAboveThreshold,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Copy current screenshots into `baselinesDir` (creates the directory if needed).
|
|
122
|
+
* If `screens` is set, only those screen names (without `.png`) are updated; otherwise all PNGs are copied.
|
|
123
|
+
*/
|
|
124
|
+
export function updateBaselines(screenshotsDir, baselinesDir, screens) {
|
|
125
|
+
if (!existsSync(screenshotsDir)) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
mkdirSync(baselinesDir, { recursive: true });
|
|
129
|
+
const files = screens?.length
|
|
130
|
+
? screens.map((s) => (s.toLowerCase().endsWith(".png") ? s : `${s}.png`))
|
|
131
|
+
: listPngFiles(screenshotsDir);
|
|
132
|
+
const updated = [];
|
|
133
|
+
for (const file of files) {
|
|
134
|
+
const src = join(screenshotsDir, file);
|
|
135
|
+
if (!existsSync(src) || !file.toLowerCase().endsWith(".png")) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const dest = join(baselinesDir, file);
|
|
139
|
+
writeFileSync(dest, readFileSync(src));
|
|
140
|
+
updated.push(dest);
|
|
141
|
+
}
|
|
142
|
+
return updated;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=screenshot_diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot_diff.js","sourceRoot":"","sources":["../../src/evidence/screenshot_diff.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { loadConfig } from "./config.js";
|
|
6
|
+
import { validateApiKey, isActivationRequired } from "./auth/api_key.js";
|
|
7
|
+
import { trackUsage } from "./auth/usage_tracker.js";
|
|
8
|
+
const config = loadConfig();
|
|
9
|
+
const apiKey = process.env.CODELOOP_API_KEY || config.api_key;
|
|
10
|
+
const server = new McpServer({
|
|
11
|
+
name: "codeloop",
|
|
12
|
+
version: "0.1.0",
|
|
13
|
+
});
|
|
14
|
+
async function withAuth(fn) {
|
|
15
|
+
const result = await validateApiKey(apiKey);
|
|
16
|
+
if (isActivationRequired(result)) {
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
if (!result.valid) {
|
|
20
|
+
return {
|
|
21
|
+
error: true,
|
|
22
|
+
status: result.status,
|
|
23
|
+
message: result.message || "API key is invalid or expired.",
|
|
24
|
+
upgrade_url: "https://codeloop.tech/dashboard/billing",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return fn();
|
|
28
|
+
}
|
|
29
|
+
function stubResponse(toolName) {
|
|
30
|
+
return {
|
|
31
|
+
status: "not_implemented",
|
|
32
|
+
tool: toolName,
|
|
33
|
+
message: `${toolName} is registered but not yet implemented. It will be available in a future release.`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// ── Implemented Tools ────────────────────────────────────────────
|
|
37
|
+
server.tool("codeloop_verify", `Run the CodeLoop verification suite on the current project. Use this tool when:
|
|
38
|
+
- You have implemented or modified code and need to check if it works correctly
|
|
39
|
+
- You want to run all tests, linters, and checks before marking a task complete
|
|
40
|
+
- Tests are failing and you need structured output to understand failures
|
|
41
|
+
Returns: structured report with pass/fail counts, artifact paths, and next-step suggestion.`, {
|
|
42
|
+
scope: z.enum(["full", "affected"]).default("full"),
|
|
43
|
+
platform: z.enum(["flutter", "web", "mobile", "auto"]).default("auto"),
|
|
44
|
+
}, async (params) => {
|
|
45
|
+
const result = await withAuth(async () => {
|
|
46
|
+
const { runVerify } = await import("./tools/verify.js");
|
|
47
|
+
const input = {
|
|
48
|
+
scope: params.scope,
|
|
49
|
+
platform: params.platform,
|
|
50
|
+
};
|
|
51
|
+
const output = await runVerify(input, config);
|
|
52
|
+
await trackUsage(apiKey, "verification_run");
|
|
53
|
+
return output;
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
server.tool("codeloop_diagnose", `Classify failures from a CodeLoop verification run into structured categories with repair tasks. Use this tool when:
|
|
60
|
+
- codeloop_verify reported failures and you need to understand what went wrong
|
|
61
|
+
- You have been attempting to fix an issue multiple times without success
|
|
62
|
+
- You need structured failure analysis instead of guessing from raw output
|
|
63
|
+
Returns: categorized issues with severity, evidence, root cause, and actionable repair tasks.`, {
|
|
64
|
+
run_id: z.string(),
|
|
65
|
+
focus_files: z.array(z.string()).optional(),
|
|
66
|
+
}, async (params) => {
|
|
67
|
+
const result = await withAuth(async () => {
|
|
68
|
+
const { runDiagnose } = await import("./tools/diagnose.js");
|
|
69
|
+
const input = {
|
|
70
|
+
run_id: params.run_id,
|
|
71
|
+
focus_files: params.focus_files,
|
|
72
|
+
};
|
|
73
|
+
const output = await runDiagnose(input, config);
|
|
74
|
+
await trackUsage(apiKey, "verification_run");
|
|
75
|
+
return output;
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
server.tool("codeloop_gate_check", `Evaluate whether a section or feature meets all quality gates for completion. Use this tool when:
|
|
82
|
+
- You believe a feature is complete and want evidence-based confirmation
|
|
83
|
+
- You need to check if all acceptance criteria are met before moving to the next section
|
|
84
|
+
- You want a confidence score to decide whether to continue fixing or stop
|
|
85
|
+
Returns: pass/fail for each gate, overall confidence score, and recommendation.`, {
|
|
86
|
+
run_id: z.string(),
|
|
87
|
+
spec_path: z.string(),
|
|
88
|
+
acceptance_path: z.string(),
|
|
89
|
+
}, async (params) => {
|
|
90
|
+
const result = await withAuth(async () => {
|
|
91
|
+
const { runGateCheck } = await import("./tools/gate_check.js");
|
|
92
|
+
const input = {
|
|
93
|
+
run_id: params.run_id,
|
|
94
|
+
spec_path: params.spec_path,
|
|
95
|
+
acceptance_path: params.acceptance_path,
|
|
96
|
+
};
|
|
97
|
+
const output = await runGateCheck(input, config);
|
|
98
|
+
await trackUsage(apiKey, "verification_run");
|
|
99
|
+
return output;
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
// ── Stub Tools (registered for discovery, implemented in later phases) ──
|
|
106
|
+
server.tool("codeloop_visual_review", `Capture and analyze screenshots of the current UI for visual issues. Use this tool when:
|
|
107
|
+
- You have made UI changes and want to check for visual regressions
|
|
108
|
+
- You want a vision-model review of screenshots against a UX checklist
|
|
109
|
+
- You need to compare the current UI against baseline screenshots
|
|
110
|
+
Returns: visual issues with severity, diff scores against baselines, and layout warnings.`, {
|
|
111
|
+
run_id: z.string().optional(),
|
|
112
|
+
screenshots_dir: z.string().optional(),
|
|
113
|
+
baseline_dir: z.string().optional(),
|
|
114
|
+
ux_checklist_path: z.string().optional(),
|
|
115
|
+
viewport_sizes: z.array(z.string()).optional(),
|
|
116
|
+
}, async (params) => {
|
|
117
|
+
const result = await withAuth(async () => {
|
|
118
|
+
const { runVisualReview } = await import("./tools/visual_review.js");
|
|
119
|
+
const input = {
|
|
120
|
+
run_id: params.run_id,
|
|
121
|
+
screenshots_dir: params.screenshots_dir,
|
|
122
|
+
baseline_dir: params.baseline_dir,
|
|
123
|
+
ux_checklist_path: params.ux_checklist_path,
|
|
124
|
+
viewport_sizes: params.viewport_sizes,
|
|
125
|
+
};
|
|
126
|
+
const output = await runVisualReview(input, config);
|
|
127
|
+
await trackUsage(apiKey, "visual_review");
|
|
128
|
+
return output;
|
|
129
|
+
});
|
|
130
|
+
return {
|
|
131
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
server.tool("codeloop_design_compare", `Compare a reference design image against the actual coded UI. Use this tool when:
|
|
135
|
+
- The user has provided a Figma mockup, screenshot, or design reference
|
|
136
|
+
- You want to measure how closely the coded UI matches the intended design
|
|
137
|
+
- You need structured differences to fix specific design mismatches
|
|
138
|
+
Returns: match score, list of differences with fix hints, and comparison screenshots.`, {
|
|
139
|
+
reference_image_path: z.string(),
|
|
140
|
+
screen_name: z.string(),
|
|
141
|
+
platform: z.string(),
|
|
142
|
+
viewport_sizes: z.array(z.string()).optional(),
|
|
143
|
+
ux_checklist_path: z.string().optional(),
|
|
144
|
+
}, async (params) => {
|
|
145
|
+
const result = await withAuth(async () => {
|
|
146
|
+
const { runDesignCompare } = await import("./tools/design_compare.js");
|
|
147
|
+
const input = {
|
|
148
|
+
reference_image_path: params.reference_image_path,
|
|
149
|
+
screen_name: params.screen_name,
|
|
150
|
+
platform: params.platform,
|
|
151
|
+
viewport_sizes: params.viewport_sizes ?? [],
|
|
152
|
+
ux_checklist_path: params.ux_checklist_path,
|
|
153
|
+
};
|
|
154
|
+
const output = await runDesignCompare(input, config);
|
|
155
|
+
await trackUsage(apiKey, "visual_review");
|
|
156
|
+
return output;
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
server.tool("codeloop_section_status", `Check the progress of multi-section app development. Use this tool when:
|
|
163
|
+
- A master spec exists and you need to know which section to work on next
|
|
164
|
+
- You have completed a section and need to proceed to the next one
|
|
165
|
+
- You need to check if an integration checkpoint is due
|
|
166
|
+
Returns: section states, dependencies, confidence scores, and next action instruction.`, {
|
|
167
|
+
master_spec_path: z.string().default("docs/specs/_master.md"),
|
|
168
|
+
}, async (params) => {
|
|
169
|
+
const result = await withAuth(async () => {
|
|
170
|
+
const { getSectionStatus } = await import("./tools/section_status.js");
|
|
171
|
+
return getSectionStatus({ master_spec_path: params.master_spec_path }, config);
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
175
|
+
};
|
|
176
|
+
});
|
|
177
|
+
server.tool("codeloop_release_readiness", `Generate a comprehensive release readiness report. Use this tool when:
|
|
178
|
+
- All sections are complete and you need a final quality assessment
|
|
179
|
+
- You want to produce evidence that the app is ready for human UAT
|
|
180
|
+
Returns: overall readiness score, blockers, warnings, and full evidence summary.`, {
|
|
181
|
+
run_id: z.string(),
|
|
182
|
+
spec_path: z.string(),
|
|
183
|
+
include: z.array(z.string()).optional(),
|
|
184
|
+
}, async (params) => {
|
|
185
|
+
const result = await withAuth(async () => {
|
|
186
|
+
const { runReleaseReadiness } = await import("./tools/release_readiness.js");
|
|
187
|
+
const output = await runReleaseReadiness({ run_id: params.run_id, spec_path: params.spec_path, include: params.include }, config);
|
|
188
|
+
await trackUsage(apiKey, "verification_run");
|
|
189
|
+
return output;
|
|
190
|
+
});
|
|
191
|
+
return {
|
|
192
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
server.tool("codeloop_recommend_tool", `Recommend third-party tools and services based on the project stack and constraints. Use this tool when:
|
|
196
|
+
- The user asks about hosting, email services, analytics, auth providers, or other infrastructure
|
|
197
|
+
- You need evidence-based tool comparisons with tradeoffs and pricing
|
|
198
|
+
Returns: ranked recommendations with reasoning, integration complexity, and starter tasks.`, {
|
|
199
|
+
category: z.string(),
|
|
200
|
+
stack: z.record(z.string()).optional(),
|
|
201
|
+
budget: z.enum(["free", "low", "medium", "enterprise"]).default("low"),
|
|
202
|
+
constraints: z.record(z.unknown()).optional(),
|
|
203
|
+
}, async (params) => {
|
|
204
|
+
const result = await withAuth(async () => {
|
|
205
|
+
const { selectRecommendations } = await import("./recommendations/selector.js");
|
|
206
|
+
const output = selectRecommendations({
|
|
207
|
+
category: params.category,
|
|
208
|
+
stack: params.stack || {},
|
|
209
|
+
budget: params.budget,
|
|
210
|
+
constraints: params.constraints || {},
|
|
211
|
+
}, config);
|
|
212
|
+
await trackUsage(apiKey, "verification_run");
|
|
213
|
+
return output;
|
|
214
|
+
});
|
|
215
|
+
return {
|
|
216
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
server.tool("codeloop_integration_check", `Run cross-section integration verification on a multi-section project. Use this tool when:
|
|
220
|
+
- Multiple sections have been completed individually and you need to check they work together
|
|
221
|
+
- A later section may have introduced regressions in earlier sections
|
|
222
|
+
- An integration checkpoint is due according to the development plan
|
|
223
|
+
Returns: integration test results, regression list, and section-level confidence updates.`, {
|
|
224
|
+
master_spec_path: z.string().default("docs/specs/_master.md"),
|
|
225
|
+
sections: z.array(z.string()).optional(),
|
|
226
|
+
}, async (params) => {
|
|
227
|
+
const result = await withAuth(async () => {
|
|
228
|
+
const { runIntegrationCheck } = await import("./tools/integration_check.js");
|
|
229
|
+
return runIntegrationCheck({
|
|
230
|
+
master_spec_path: params.master_spec_path,
|
|
231
|
+
sections: params.sections,
|
|
232
|
+
}, config);
|
|
233
|
+
});
|
|
234
|
+
return {
|
|
235
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
server.tool("codeloop_update_baseline", `Accept current screenshots as the new visual baseline for regression testing. Use this tool when:
|
|
239
|
+
- Visual changes are intentional and the current screenshots should become the new reference
|
|
240
|
+
- A design has been approved and you want to lock in the current state
|
|
241
|
+
- Baseline screenshots are missing and need to be established for the first time
|
|
242
|
+
Returns: list of updated baseline files with before/after paths.`, {
|
|
243
|
+
run_id: z.string(),
|
|
244
|
+
screens: z.array(z.string()).optional(),
|
|
245
|
+
}, async (params) => {
|
|
246
|
+
const result = await withAuth(async () => {
|
|
247
|
+
const { runUpdateBaseline } = await import("./tools/update_baseline.js");
|
|
248
|
+
return runUpdateBaseline({ run_id: params.run_id, screens: params.screens }, config);
|
|
249
|
+
});
|
|
250
|
+
return {
|
|
251
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
252
|
+
};
|
|
253
|
+
});
|
|
254
|
+
server.tool("codeloop_replan", `Detect scope changes in the project spec and update section states accordingly. Use this tool when:
|
|
255
|
+
- The master spec has been modified and sections need to be re-evaluated
|
|
256
|
+
- New requirements have been added that affect completed sections
|
|
257
|
+
- You need to determine which sections require rework after a spec change
|
|
258
|
+
Returns: list of affected sections, new states, and recommended next actions.`, {
|
|
259
|
+
master_spec_path: z.string().default("docs/specs/_master.md"),
|
|
260
|
+
change_summary: z.string().optional(),
|
|
261
|
+
}, async (params) => {
|
|
262
|
+
const result = await withAuth(async () => {
|
|
263
|
+
const { runReplan } = await import("./tools/replan.js");
|
|
264
|
+
return runReplan({
|
|
265
|
+
master_spec_path: params.master_spec_path,
|
|
266
|
+
change_summary: params.change_summary,
|
|
267
|
+
}, config);
|
|
268
|
+
});
|
|
269
|
+
return {
|
|
270
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
271
|
+
};
|
|
272
|
+
});
|
|
273
|
+
// ── Start Server ─────────────────────────────────────────────────
|
|
274
|
+
const transport = new StdioServerTransport();
|
|
275
|
+
await server.connect(transport);
|
|
276
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ToolEntry {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
website: string;
|
|
5
|
+
category: string;
|
|
6
|
+
bestFor: string;
|
|
7
|
+
pricingTier: string;
|
|
8
|
+
freeTier: boolean;
|
|
9
|
+
selfHosted: boolean;
|
|
10
|
+
openSource: boolean;
|
|
11
|
+
complianceNotes: string;
|
|
12
|
+
integrationComplexity: "trivial" | "moderate" | "complex";
|
|
13
|
+
supportedStacks: string[];
|
|
14
|
+
strengths: string[];
|
|
15
|
+
weaknesses: string[];
|
|
16
|
+
tradeoffs: string;
|
|
17
|
+
starterTasks: string[];
|
|
18
|
+
recommendationType: "neutral" | "sponsored";
|
|
19
|
+
}
|
|
20
|
+
export declare const KNOWLEDGE_BASE: ToolEntry[];
|
|
21
|
+
//# sourceMappingURL=knowledge_base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge_base.d.ts","sourceRoot":"","sources":["../../src/recommendations/knowledge_base.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1D,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kBAAkB,EAAE,SAAS,GAAG,WAAW,CAAC;CAC7C;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,EAk3BrC,CAAC"}
|