codeloop-mcp-server 0.1.4 → 0.1.6
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/usage_tracker.d.ts +1 -1
- package/dist/auth/usage_tracker.d.ts.map +1 -1
- package/dist/auth/usage_tracker.js.map +1 -1
- package/dist/index.js +978 -40
- package/dist/index.js.map +1 -1
- package/dist/project-discovery.d.ts +17 -0
- package/dist/project-discovery.d.ts.map +1 -0
- package/dist/project-discovery.js +109 -0
- package/dist/project-discovery.js.map +1 -0
- package/dist/runners/app_logger.d.ts +41 -0
- package/dist/runners/app_logger.d.ts.map +1 -0
- package/dist/runners/app_logger.js +276 -0
- package/dist/runners/app_logger.js.map +1 -0
- package/dist/runners/base.d.ts.map +1 -1
- package/dist/runners/base.js +4 -2
- package/dist/runners/base.js.map +1 -1
- package/dist/runners/browser_interaction.d.ts +27 -0
- package/dist/runners/browser_interaction.d.ts.map +1 -0
- package/dist/runners/browser_interaction.js +294 -0
- package/dist/runners/browser_interaction.js.map +1 -0
- package/dist/runners/flutter.d.ts +1 -0
- package/dist/runners/flutter.d.ts.map +1 -1
- package/dist/runners/flutter.js +29 -0
- package/dist/runners/flutter.js.map +1 -1
- package/dist/runners/maestro_generator.d.ts +11 -0
- package/dist/runners/maestro_generator.d.ts.map +1 -0
- package/dist/runners/maestro_generator.js +79 -0
- package/dist/runners/maestro_generator.js.map +1 -0
- package/dist/runners/platform_detect.d.ts +14 -0
- package/dist/runners/platform_detect.d.ts.map +1 -0
- package/dist/runners/platform_detect.js +102 -0
- package/dist/runners/platform_detect.js.map +1 -0
- package/dist/runners/screenshot.d.ts +3 -7
- package/dist/runners/screenshot.d.ts.map +1 -1
- package/dist/runners/screenshot.js +155 -28
- package/dist/runners/screenshot.js.map +1 -1
- package/dist/runners/video_recorder.d.ts +49 -0
- package/dist/runners/video_recorder.d.ts.map +1 -0
- package/dist/runners/video_recorder.js +489 -0
- package/dist/runners/video_recorder.js.map +1 -0
- package/dist/runners/video_validator.d.ts +16 -0
- package/dist/runners/video_validator.d.ts.map +1 -0
- package/dist/runners/video_validator.js +123 -0
- package/dist/runners/video_validator.js.map +1 -0
- package/dist/runners/win_accessibility.d.ts +12 -0
- package/dist/runners/win_accessibility.d.ts.map +1 -0
- package/dist/runners/win_accessibility.js +101 -0
- package/dist/runners/win_accessibility.js.map +1 -0
- package/dist/runners/window_manager.d.ts +81 -0
- package/dist/runners/window_manager.d.ts.map +1 -0
- package/dist/runners/window_manager.js +1010 -0
- package/dist/runners/window_manager.js.map +1 -0
- package/dist/tools/design_compare.d.ts +1 -1
- package/dist/tools/design_compare.d.ts.map +1 -1
- package/dist/tools/design_compare.js +1 -2
- package/dist/tools/design_compare.js.map +1 -1
- package/dist/tools/discover_screens.d.ts +3 -3
- package/dist/tools/discover_screens.d.ts.map +1 -1
- package/dist/tools/discover_screens.js +140 -157
- package/dist/tools/discover_screens.js.map +1 -1
- package/dist/tools/gate_check.d.ts.map +1 -1
- package/dist/tools/gate_check.js +100 -5
- package/dist/tools/gate_check.js.map +1 -1
- package/dist/tools/init-project.d.ts +15 -0
- package/dist/tools/init-project.d.ts.map +1 -0
- package/dist/tools/init-project.js +273 -0
- package/dist/tools/init-project.js.map +1 -0
- package/dist/tools/interaction_replay.d.ts +8 -1
- package/dist/tools/interaction_replay.d.ts.map +1 -1
- package/dist/tools/interaction_replay.js +78 -2
- package/dist/tools/interaction_replay.js.map +1 -1
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +204 -53
- package/dist/tools/verify.js.map +1 -1
- package/dist/tools/visual_review.d.ts +1 -1
- package/dist/tools/visual_review.d.ts.map +1 -1
- package/dist/tools/visual_review.js +1 -2
- package/dist/tools/visual_review.js.map +1 -1
- package/package.json +1 -1
package/dist/tools/gate_check.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { readFileSync, existsSync } from "fs";
|
|
1
|
+
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
2
3
|
import { DEFAULT_GATES } from "@codelooptech/shared";
|
|
3
|
-
import { loadRunMeta, getArtifactsBaseDir } from "../evidence/artifacts.js";
|
|
4
|
+
import { loadRunMeta, getArtifactsBaseDir, getRunDir } from "../evidence/artifacts.js";
|
|
4
5
|
export async function runGateCheck(input, config, cwd = process.cwd()) {
|
|
5
6
|
const baseDir = getArtifactsBaseDir(cwd);
|
|
6
7
|
const meta = loadRunMeta(input.run_id, baseDir);
|
|
@@ -20,6 +21,9 @@ export async function runGateCheck(input, config, cwd = process.cwd()) {
|
|
|
20
21
|
const specContent = safeReadFile(input.spec_path, cwd);
|
|
21
22
|
const acceptanceContent = safeReadFile(input.acceptance_path, cwd);
|
|
22
23
|
const evaluations = evaluateGates(meta, config, specContent, acceptanceContent);
|
|
24
|
+
// Add evidence gates for UI projects
|
|
25
|
+
const evidenceGates = evaluateEvidenceGates(input.run_id, cwd);
|
|
26
|
+
evaluations.push(...evidenceGates);
|
|
23
27
|
const passingGates = evaluations.filter((e) => e.passed).map((e) => e.gate.name);
|
|
24
28
|
const failingGates = evaluations.filter((e) => !e.passed).map((e) => e.gate.name);
|
|
25
29
|
const blockersFailing = evaluations.filter((e) => !e.passed && e.gate.severity_if_failed === "blocker");
|
|
@@ -44,7 +48,86 @@ export async function runGateCheck(input, config, cwd = process.cwd()) {
|
|
|
44
48
|
};
|
|
45
49
|
}
|
|
46
50
|
function evaluateGates(meta, config, specContent, acceptanceContent) {
|
|
47
|
-
return DEFAULT_GATES.map((gate) => evaluateGate(gate, meta, config, specContent, acceptanceContent));
|
|
51
|
+
return [...DEFAULT_GATES.map((gate) => evaluateGate(gate, meta, config, specContent, acceptanceContent))];
|
|
52
|
+
}
|
|
53
|
+
function isUIProject(cwd) {
|
|
54
|
+
try {
|
|
55
|
+
const { detectPlatform } = require("../tools/verify.js");
|
|
56
|
+
const platform = detectPlatform(cwd);
|
|
57
|
+
return ["flutter", "web", "xcode", "android"].includes(platform);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function evaluateEvidenceGates(runId, cwd) {
|
|
64
|
+
if (!isUIProject(cwd))
|
|
65
|
+
return [];
|
|
66
|
+
const baseDir = getArtifactsBaseDir(cwd);
|
|
67
|
+
const runDir = getRunDir(runId, baseDir);
|
|
68
|
+
const results = [];
|
|
69
|
+
const screenshotGate = {
|
|
70
|
+
name: "screenshot_evidence",
|
|
71
|
+
description: "Screenshots must exist for UI projects",
|
|
72
|
+
rule: "At least one screenshot captured",
|
|
73
|
+
input_artifacts: ["screenshots"],
|
|
74
|
+
pass_threshold: true,
|
|
75
|
+
severity_if_failed: "blocker",
|
|
76
|
+
retry_allowance: 3,
|
|
77
|
+
escalation_condition: "No screenshots after 3 attempts",
|
|
78
|
+
};
|
|
79
|
+
const screenshotsDir = join(runDir, "screenshots");
|
|
80
|
+
const screenshotCount = existsSync(screenshotsDir)
|
|
81
|
+
? readdirSync(screenshotsDir).filter(f => f.endsWith(".png")).length
|
|
82
|
+
: 0;
|
|
83
|
+
results.push({
|
|
84
|
+
gate: screenshotGate,
|
|
85
|
+
passed: screenshotCount > 0,
|
|
86
|
+
reason: screenshotCount > 0
|
|
87
|
+
? `${screenshotCount} screenshot(s) captured`
|
|
88
|
+
: "No screenshots found. Call codeloop_capture_screenshot for each page before gate check.",
|
|
89
|
+
});
|
|
90
|
+
const videoGate = {
|
|
91
|
+
name: "video_evidence",
|
|
92
|
+
description: "Video recording with active interaction must exist for UI projects",
|
|
93
|
+
rule: "At least one video file exists with non-static content",
|
|
94
|
+
input_artifacts: ["videos"],
|
|
95
|
+
pass_threshold: true,
|
|
96
|
+
severity_if_failed: "blocker",
|
|
97
|
+
retry_allowance: 3,
|
|
98
|
+
escalation_condition: "No video after 3 attempts",
|
|
99
|
+
};
|
|
100
|
+
const videosDir = join(runDir, "videos");
|
|
101
|
+
const videoCount = existsSync(videosDir)
|
|
102
|
+
? readdirSync(videosDir).filter(f => f.endsWith(".mp4") || f.endsWith(".mov") || f.endsWith(".webm")).length
|
|
103
|
+
: 0;
|
|
104
|
+
results.push({
|
|
105
|
+
gate: videoGate,
|
|
106
|
+
passed: videoCount > 0,
|
|
107
|
+
reason: videoCount > 0
|
|
108
|
+
? `${videoCount} video(s) recorded`
|
|
109
|
+
: "No video recordings found. Call codeloop_start_recording → codeloop_interact → codeloop_stop_recording before gate check.",
|
|
110
|
+
});
|
|
111
|
+
const replayGate = {
|
|
112
|
+
name: "interaction_replay_evidence",
|
|
113
|
+
description: "Interaction replay must have been performed for UI projects",
|
|
114
|
+
rule: "replay_frames directory exists with extracted frames",
|
|
115
|
+
input_artifacts: ["replay_frames"],
|
|
116
|
+
pass_threshold: true,
|
|
117
|
+
severity_if_failed: "blocker",
|
|
118
|
+
retry_allowance: 3,
|
|
119
|
+
escalation_condition: "No replay frames after 3 attempts",
|
|
120
|
+
};
|
|
121
|
+
const replayDir = join(baseDir, "replay_frames");
|
|
122
|
+
const hasReplayFrames = existsSync(replayDir) && readdirSync(replayDir).length > 0;
|
|
123
|
+
results.push({
|
|
124
|
+
gate: replayGate,
|
|
125
|
+
passed: hasReplayFrames,
|
|
126
|
+
reason: hasReplayFrames
|
|
127
|
+
? "Interaction replay frames exist"
|
|
128
|
+
: "No interaction replay performed. Call codeloop_interaction_replay after stopping the recording.",
|
|
129
|
+
});
|
|
130
|
+
return results;
|
|
48
131
|
}
|
|
49
132
|
function evaluateGate(gate, meta, config, specContent, acceptanceContent) {
|
|
50
133
|
switch (gate.name) {
|
|
@@ -107,7 +190,19 @@ function evaluateTestsGate(gate, meta) {
|
|
|
107
190
|
function evaluateVisualGate(gate, meta, config) {
|
|
108
191
|
const visual = meta.visual_deterministic_results;
|
|
109
192
|
if (!visual || !visual.diff_score) {
|
|
110
|
-
|
|
193
|
+
const screenshotCount = meta.screenshot_paths?.length ?? 0;
|
|
194
|
+
if (screenshotCount === 0) {
|
|
195
|
+
return {
|
|
196
|
+
gate,
|
|
197
|
+
passed: true,
|
|
198
|
+
reason: "No screenshots captured — run codeloop_capture_screenshot and codeloop_visual_review for UI projects before final gate check",
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
gate,
|
|
203
|
+
passed: true,
|
|
204
|
+
reason: `${screenshotCount} screenshot(s) captured but no baselines for diff — run codeloop_visual_review to analyze them`,
|
|
205
|
+
};
|
|
111
206
|
}
|
|
112
207
|
const diffScore = visual.diff_score;
|
|
113
208
|
const threshold = config.design_match_threshold;
|
|
@@ -181,7 +276,7 @@ function computeConfidenceScore(evaluations, meta) {
|
|
|
181
276
|
return Math.round(Math.min(100, gateScore + testScore + evidenceScore));
|
|
182
277
|
}
|
|
183
278
|
function computeRecommendation(confidenceScore, blockerCount) {
|
|
184
|
-
if (confidenceScore >=
|
|
279
|
+
if (confidenceScore >= 94 && blockerCount === 0)
|
|
185
280
|
return "ready_for_review";
|
|
186
281
|
if (confidenceScore >= 50)
|
|
187
282
|
return "continue_fixing";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate_check.js","sourceRoot":"","sources":["../../src/tools/gate_check.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gate_check.js","sourceRoot":"","sources":["../../src/tools/gate_check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface InitProjectInput {
|
|
2
|
+
project_dir: string;
|
|
3
|
+
project_type?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface InitProjectOutput {
|
|
6
|
+
initialized: boolean;
|
|
7
|
+
project_dir: string;
|
|
8
|
+
project_type: string;
|
|
9
|
+
ide_detected: "cursor" | "claude" | "both" | "unknown";
|
|
10
|
+
files_created: string[];
|
|
11
|
+
files_merged: string[];
|
|
12
|
+
message: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function runInitProject(input: InitProjectInput): Promise<InitProjectOutput>;
|
|
15
|
+
//# sourceMappingURL=init-project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-project.d.ts","sourceRoot":"","sources":["../../src/tools/init-project.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,cAAc,CAClC,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAkD5B"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync } from "fs";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
|
+
export async function runInitProject(input) {
|
|
4
|
+
const cwd = input.project_dir;
|
|
5
|
+
const projectType = input.project_type === "auto" || !input.project_type
|
|
6
|
+
? detectProjectType(cwd)
|
|
7
|
+
: input.project_type;
|
|
8
|
+
const ide = detectIDE(cwd);
|
|
9
|
+
const filesCreated = [];
|
|
10
|
+
const filesMerged = [];
|
|
11
|
+
// 1. Create .codeloop/config.json
|
|
12
|
+
const configPath = join(cwd, ".codeloop", "config.json");
|
|
13
|
+
if (!existsSync(configPath)) {
|
|
14
|
+
const apiKey = process.env.CODELOOP_API_KEY || "";
|
|
15
|
+
const config = createConfig(apiKey, projectType);
|
|
16
|
+
writeFileEnsureDir(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
17
|
+
filesCreated.push(".codeloop/config.json");
|
|
18
|
+
}
|
|
19
|
+
// 2. Create artifacts directory
|
|
20
|
+
const artifactsDir = join(cwd, "artifacts");
|
|
21
|
+
if (!existsSync(artifactsDir)) {
|
|
22
|
+
mkdirSync(artifactsDir, { recursive: true });
|
|
23
|
+
filesCreated.push("artifacts/");
|
|
24
|
+
}
|
|
25
|
+
// 3. IDE-specific setup
|
|
26
|
+
if (ide === "cursor" || ide === "both") {
|
|
27
|
+
setupCursorProject(cwd, projectType, filesCreated, filesMerged);
|
|
28
|
+
}
|
|
29
|
+
if (ide === "claude" || ide === "both") {
|
|
30
|
+
setupClaudeProject(cwd, projectType, filesCreated, filesMerged);
|
|
31
|
+
}
|
|
32
|
+
if (ide === "unknown") {
|
|
33
|
+
setupCursorProject(cwd, projectType, filesCreated, filesMerged);
|
|
34
|
+
setupClaudeProject(cwd, projectType, filesCreated, filesMerged);
|
|
35
|
+
}
|
|
36
|
+
// 4. Update .gitignore
|
|
37
|
+
updateGitignore(cwd, filesCreated);
|
|
38
|
+
return {
|
|
39
|
+
initialized: true,
|
|
40
|
+
project_dir: cwd,
|
|
41
|
+
project_type: projectType,
|
|
42
|
+
ide_detected: ide,
|
|
43
|
+
files_created: filesCreated,
|
|
44
|
+
files_merged: filesMerged,
|
|
45
|
+
message: `CodeLoop initialized for ${projectType} project. Created ${filesCreated.length} files, merged ${filesMerged.length} configs.`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function detectProjectType(cwd) {
|
|
49
|
+
if (existsSync(join(cwd, "pubspec.yaml")))
|
|
50
|
+
return "flutter";
|
|
51
|
+
if (existsSync(join(cwd, "playwright.config.ts")) ||
|
|
52
|
+
existsSync(join(cwd, "playwright.config.js")))
|
|
53
|
+
return "web";
|
|
54
|
+
if (existsSync(join(cwd, "package.json"))) {
|
|
55
|
+
try {
|
|
56
|
+
const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf-8"));
|
|
57
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
58
|
+
const webFrameworks = [
|
|
59
|
+
"react", "next", "vue", "nuxt", "svelte", "@sveltejs/kit",
|
|
60
|
+
"angular", "@angular/core", "gatsby", "remix", "astro", "vite",
|
|
61
|
+
"@playwright/test",
|
|
62
|
+
];
|
|
63
|
+
if (webFrameworks.some(fw => fw in deps))
|
|
64
|
+
return "web";
|
|
65
|
+
}
|
|
66
|
+
catch { /* fall through */ }
|
|
67
|
+
return "node";
|
|
68
|
+
}
|
|
69
|
+
if (hasFileWith(cwd, ".xcodeproj") || hasFileWith(cwd, ".xcworkspace"))
|
|
70
|
+
return "xcode";
|
|
71
|
+
if (existsSync(join(cwd, "build.gradle")) || existsSync(join(cwd, "build.gradle.kts")))
|
|
72
|
+
return "android";
|
|
73
|
+
if (hasFileWith(cwd, ".sln") || hasFileWith(cwd, ".csproj"))
|
|
74
|
+
return "dotnet";
|
|
75
|
+
return "unknown";
|
|
76
|
+
}
|
|
77
|
+
function hasFileWith(dir, ext) {
|
|
78
|
+
try {
|
|
79
|
+
return readdirSync(dir).some(f => f.endsWith(ext));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function detectIDE(cwd) {
|
|
86
|
+
const hasCursor = existsSync(join(cwd, ".cursor"));
|
|
87
|
+
const hasClaude = existsSync(join(cwd, ".claude")) || existsSync(join(cwd, "CLAUDE.md"));
|
|
88
|
+
if (hasCursor && hasClaude)
|
|
89
|
+
return "both";
|
|
90
|
+
if (hasCursor)
|
|
91
|
+
return "cursor";
|
|
92
|
+
if (hasClaude)
|
|
93
|
+
return "claude";
|
|
94
|
+
return "unknown";
|
|
95
|
+
}
|
|
96
|
+
function createConfig(apiKey, projectType) {
|
|
97
|
+
return {
|
|
98
|
+
api_key: apiKey,
|
|
99
|
+
vision_model: "auto",
|
|
100
|
+
platforms: projectType !== "unknown" ? [projectType] : ["auto"],
|
|
101
|
+
screenshot_viewports: ["375x812", "390x844", "1440x900"],
|
|
102
|
+
design_match_threshold: 0.85,
|
|
103
|
+
max_loop_iterations: 10,
|
|
104
|
+
auto_verify_on_complete: true,
|
|
105
|
+
auto_gate_check: true,
|
|
106
|
+
recommendations: {
|
|
107
|
+
enabled: true,
|
|
108
|
+
external_tools: true,
|
|
109
|
+
sponsored: false,
|
|
110
|
+
preferences: {
|
|
111
|
+
budget: "low",
|
|
112
|
+
self_hosted: false,
|
|
113
|
+
open_source_only: false,
|
|
114
|
+
gdpr_sensitive: false,
|
|
115
|
+
preferred_cloud: "",
|
|
116
|
+
region: "",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
evidence: {
|
|
120
|
+
capture_screenshots: true,
|
|
121
|
+
capture_traces: true,
|
|
122
|
+
capture_videos: true,
|
|
123
|
+
baseline_auto_update: false,
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function setupCursorProject(cwd, projectType, filesCreated, filesMerged) {
|
|
128
|
+
// Merge MCP config
|
|
129
|
+
const mcpPath = join(cwd, ".cursor", "mcp.json");
|
|
130
|
+
mergeMcpEntry(mcpPath);
|
|
131
|
+
filesMerged.push(".cursor/mcp.json");
|
|
132
|
+
// Create core rules
|
|
133
|
+
const rulesDir = join(cwd, ".cursor", "rules");
|
|
134
|
+
if (!existsSync(rulesDir))
|
|
135
|
+
mkdirSync(rulesDir, { recursive: true });
|
|
136
|
+
writeIfMissing(join(rulesDir, "core.mdc"), CORE_RULE, filesCreated, ".cursor/rules/core.mdc");
|
|
137
|
+
writeIfMissing(join(rulesDir, "loop.mdc"), LOOP_RULE, filesCreated, ".cursor/rules/loop.mdc");
|
|
138
|
+
if (projectType === "web") {
|
|
139
|
+
writeIfMissing(join(rulesDir, "web.mdc"), WEB_RULE, filesCreated, ".cursor/rules/web.mdc");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function setupClaudeProject(cwd, projectType, filesCreated, filesMerged) {
|
|
143
|
+
// Merge MCP config
|
|
144
|
+
const settingsPath = join(cwd, ".claude", "settings.local.json");
|
|
145
|
+
mergeMcpEntry(settingsPath);
|
|
146
|
+
filesMerged.push(".claude/settings.local.json");
|
|
147
|
+
// Create CLAUDE.md
|
|
148
|
+
const claudeMdPath = join(cwd, "CLAUDE.md");
|
|
149
|
+
const platformNote = projectType === "web"
|
|
150
|
+
? "\n- For web projects: run `codeloop_verify` with platform 'web' after UI changes"
|
|
151
|
+
: "";
|
|
152
|
+
writeIfMissing(claudeMdPath, CLAUDE_RULE(platformNote), filesCreated, "CLAUDE.md");
|
|
153
|
+
}
|
|
154
|
+
function mergeMcpEntry(filePath) {
|
|
155
|
+
const dir = dirname(filePath);
|
|
156
|
+
if (!existsSync(dir))
|
|
157
|
+
mkdirSync(dir, { recursive: true });
|
|
158
|
+
let existing = {};
|
|
159
|
+
if (existsSync(filePath)) {
|
|
160
|
+
try {
|
|
161
|
+
existing = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
162
|
+
}
|
|
163
|
+
catch { /* use empty */ }
|
|
164
|
+
}
|
|
165
|
+
const servers = (existing.mcpServers ?? {});
|
|
166
|
+
if (!servers.codeloop) {
|
|
167
|
+
servers.codeloop = {
|
|
168
|
+
command: "npx",
|
|
169
|
+
args: ["-y", "codeloop-mcp-server"],
|
|
170
|
+
env: { CODELOOP_API_KEY: "${CODELOOP_API_KEY}" },
|
|
171
|
+
};
|
|
172
|
+
existing.mcpServers = servers;
|
|
173
|
+
writeFileSync(filePath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function updateGitignore(cwd, filesCreated) {
|
|
177
|
+
const gitignorePath = join(cwd, ".gitignore");
|
|
178
|
+
const entries = [".codeloop/config.json", "artifacts/", ".env", ".env.*", "!.env.example"];
|
|
179
|
+
let content = "";
|
|
180
|
+
if (existsSync(gitignorePath)) {
|
|
181
|
+
content = readFileSync(gitignorePath, "utf-8");
|
|
182
|
+
}
|
|
183
|
+
const newEntries = entries.filter(e => !content.includes(e));
|
|
184
|
+
if (newEntries.length > 0) {
|
|
185
|
+
const addition = (content.endsWith("\n") ? "" : "\n") +
|
|
186
|
+
"\n# CodeLoop\n" + newEntries.join("\n") + "\n";
|
|
187
|
+
writeFileSync(gitignorePath, content + addition, "utf-8");
|
|
188
|
+
filesCreated.push(".gitignore");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function writeFileEnsureDir(filePath, content) {
|
|
192
|
+
const dir = dirname(filePath);
|
|
193
|
+
if (!existsSync(dir))
|
|
194
|
+
mkdirSync(dir, { recursive: true });
|
|
195
|
+
writeFileSync(filePath, content, "utf-8");
|
|
196
|
+
}
|
|
197
|
+
function writeIfMissing(filePath, content, filesCreated, displayPath) {
|
|
198
|
+
if (!existsSync(filePath)) {
|
|
199
|
+
writeFileEnsureDir(filePath, content);
|
|
200
|
+
filesCreated.push(displayPath);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Minimal rule templates — enough to activate CodeLoop's verification loop.
|
|
204
|
+
// Full templates are available via `npx codeloop init` (CLI package).
|
|
205
|
+
const CORE_RULE = `---
|
|
206
|
+
description: CodeLoop automated verification — core workflow
|
|
207
|
+
globs: "**/*"
|
|
208
|
+
alwaysApply: true
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
# CodeLoop Core Rules
|
|
212
|
+
|
|
213
|
+
## After every code change
|
|
214
|
+
|
|
215
|
+
1. Call \`codeloop_verify\` to run tests and static analysis
|
|
216
|
+
2. Call \`codeloop_capture_screenshot\` to capture visual evidence
|
|
217
|
+
3. If tests fail, call \`codeloop_diagnose\` and fix issues
|
|
218
|
+
4. Call \`codeloop_gate_check\` before marking complete
|
|
219
|
+
|
|
220
|
+
## Never
|
|
221
|
+
|
|
222
|
+
- Never skip verification after code changes
|
|
223
|
+
- Never mark a task complete without evidence
|
|
224
|
+
- Never ignore test failures
|
|
225
|
+
`;
|
|
226
|
+
const LOOP_RULE = `---
|
|
227
|
+
description: CodeLoop verify-diagnose-fix cycle
|
|
228
|
+
globs: "**/*"
|
|
229
|
+
alwaysApply: false
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
# CodeLoop Loop
|
|
233
|
+
|
|
234
|
+
When implementing features:
|
|
235
|
+
|
|
236
|
+
1. Make the code change
|
|
237
|
+
2. \`codeloop_verify\` — run tests
|
|
238
|
+
3. If failures → \`codeloop_diagnose\` → fix → goto 2
|
|
239
|
+
4. \`codeloop_capture_screenshot\` — visual evidence
|
|
240
|
+
5. \`codeloop_gate_check\` — final quality gate
|
|
241
|
+
`;
|
|
242
|
+
const WEB_RULE = `---
|
|
243
|
+
description: CodeLoop web project verification
|
|
244
|
+
globs: "**/*.{ts,tsx,js,jsx,html,css}"
|
|
245
|
+
alwaysApply: false
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
# CodeLoop Web Rules
|
|
249
|
+
|
|
250
|
+
## Verification for web projects
|
|
251
|
+
|
|
252
|
+
- Use platform "web" with \`codeloop_verify\`
|
|
253
|
+
- Playwright tests are the primary verification method
|
|
254
|
+
- Capture screenshots at key viewports (375, 390, 1440)
|
|
255
|
+
- Use \`codeloop_start_recording\` for interaction testing
|
|
256
|
+
- Interact with ALL elements during video capture
|
|
257
|
+
`;
|
|
258
|
+
function CLAUDE_RULE(platformNote) {
|
|
259
|
+
return `# CodeLoop Integration
|
|
260
|
+
|
|
261
|
+
This project uses CodeLoop for automated verification.
|
|
262
|
+
|
|
263
|
+
## After every code change
|
|
264
|
+
|
|
265
|
+
1. Call \`codeloop_verify\` to run tests and static analysis
|
|
266
|
+
2. Call \`codeloop_capture_screenshot\` for visual evidence
|
|
267
|
+
3. If tests fail, call \`codeloop_diagnose\` and fix issues
|
|
268
|
+
4. Call \`codeloop_gate_check\` before marking complete${platformNote}
|
|
269
|
+
|
|
270
|
+
## Never skip verification after code changes.
|
|
271
|
+
`;
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=init-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-project.js","sourceRoot":"","sources":["../../src/tools/init-project.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,16 +4,23 @@ export interface InteractionReplayInput {
|
|
|
4
4
|
run_id?: string;
|
|
5
5
|
expected_flow: string;
|
|
6
6
|
}
|
|
7
|
+
export interface FrameLogCorrelation {
|
|
8
|
+
frameIndex: number;
|
|
9
|
+
estimatedTimestamp: string;
|
|
10
|
+
logsNearFrame: string[];
|
|
11
|
+
}
|
|
7
12
|
export interface InteractionReplayOutput {
|
|
8
13
|
video_analyzed: string;
|
|
9
14
|
frame_count: number;
|
|
10
15
|
framePaths: string[];
|
|
11
16
|
expected_flow: string;
|
|
12
17
|
ffmpeg_available: boolean;
|
|
18
|
+
logExcerpt?: string;
|
|
19
|
+
frameLogCorrelations?: FrameLogCorrelation[];
|
|
13
20
|
}
|
|
14
21
|
/**
|
|
15
22
|
* Extracts key frames from a video recording and returns their paths
|
|
16
23
|
* for the AI agent to analyze via its own vision model.
|
|
17
24
|
*/
|
|
18
|
-
export declare function runInteractionReplay(input: InteractionReplayInput, _config: CodeLoopConfig): Promise<InteractionReplayOutput>;
|
|
25
|
+
export declare function runInteractionReplay(input: InteractionReplayInput, _config: CodeLoopConfig, cwd?: string): Promise<InteractionReplayOutput>;
|
|
19
26
|
//# sourceMappingURL=interaction_replay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interaction_replay.d.ts","sourceRoot":"","sources":["../../src/tools/interaction_replay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"interaction_replay.d.ts","sourceRoot":"","sources":["../../src/tools/interaction_replay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAO3D,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC9C;AAiFD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,sBAAsB,EAC7B,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,uBAAuB,CAAC,CAiFlC"}
|
|
@@ -2,6 +2,7 @@ import { existsSync, readdirSync, mkdirSync } from "fs";
|
|
|
2
2
|
import { join, resolve } from "path";
|
|
3
3
|
import { execFile } from "child_process";
|
|
4
4
|
import { getArtifactsBaseDir, getRunDir, listRuns } from "../evidence/artifacts.js";
|
|
5
|
+
import { readLogTail } from "../runners/app_logger.js";
|
|
5
6
|
function findVideoInRun(runId, cwd) {
|
|
6
7
|
const base = getArtifactsBaseDir(cwd);
|
|
7
8
|
const videosDir = join(getRunDir(runId, base), "videos");
|
|
@@ -13,6 +14,14 @@ function findVideoInRun(runId, cwd) {
|
|
|
13
14
|
});
|
|
14
15
|
return files.length > 0 ? join(videosDir, files[0]) : null;
|
|
15
16
|
}
|
|
17
|
+
function findLogInRun(runId, cwd) {
|
|
18
|
+
const base = getArtifactsBaseDir(cwd);
|
|
19
|
+
const logsDir = join(getRunDir(runId, base), "logs");
|
|
20
|
+
if (!existsSync(logsDir))
|
|
21
|
+
return null;
|
|
22
|
+
const files = readdirSync(logsDir).filter((f) => f.startsWith("app_log_") && f.endsWith(".txt"));
|
|
23
|
+
return files.length > 0 ? join(logsDir, files[0]) : null;
|
|
24
|
+
}
|
|
16
25
|
const MAX_FRAMES = 15;
|
|
17
26
|
function extractFrames(videoPath, outputDir, maxFrames) {
|
|
18
27
|
return new Promise((resolveP, reject) => {
|
|
@@ -63,8 +72,7 @@ function isFfmpegAvailable() {
|
|
|
63
72
|
* Extracts key frames from a video recording and returns their paths
|
|
64
73
|
* for the AI agent to analyze via its own vision model.
|
|
65
74
|
*/
|
|
66
|
-
export async function runInteractionReplay(input, _config) {
|
|
67
|
-
const cwd = process.cwd();
|
|
75
|
+
export async function runInteractionReplay(input, _config, cwd = process.cwd()) {
|
|
68
76
|
let videoPath = null;
|
|
69
77
|
if (input.video_path) {
|
|
70
78
|
videoPath = resolve(cwd, input.video_path);
|
|
@@ -78,6 +86,16 @@ export async function runInteractionReplay(input, _config) {
|
|
|
78
86
|
videoPath = findVideoInRun(runs[0], cwd);
|
|
79
87
|
}
|
|
80
88
|
}
|
|
89
|
+
// Find log file for this run (if available)
|
|
90
|
+
let logExcerpt;
|
|
91
|
+
if (input.run_id) {
|
|
92
|
+
const logPath = findLogInRun(input.run_id, cwd);
|
|
93
|
+
if (logPath) {
|
|
94
|
+
const content = readLogTail(logPath, 200);
|
|
95
|
+
if (content.trim())
|
|
96
|
+
logExcerpt = content;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
81
99
|
if (!videoPath || !existsSync(videoPath)) {
|
|
82
100
|
return {
|
|
83
101
|
video_analyzed: videoPath ?? "(none)",
|
|
@@ -85,6 +103,7 @@ export async function runInteractionReplay(input, _config) {
|
|
|
85
103
|
framePaths: [],
|
|
86
104
|
expected_flow: input.expected_flow,
|
|
87
105
|
ffmpeg_available: false,
|
|
106
|
+
logExcerpt,
|
|
88
107
|
};
|
|
89
108
|
}
|
|
90
109
|
const hasFfmpeg = await isFfmpegAvailable();
|
|
@@ -95,17 +114,25 @@ export async function runInteractionReplay(input, _config) {
|
|
|
95
114
|
framePaths: [],
|
|
96
115
|
expected_flow: input.expected_flow,
|
|
97
116
|
ffmpeg_available: false,
|
|
117
|
+
logExcerpt,
|
|
98
118
|
};
|
|
99
119
|
}
|
|
100
120
|
const framesDir = join(getArtifactsBaseDir(cwd), "replay_frames", `frames_${Date.now()}`);
|
|
101
121
|
try {
|
|
102
122
|
const framePaths = await extractFrames(videoPath, framesDir, MAX_FRAMES);
|
|
123
|
+
// Build frame-log correlations if we have both frames and logs
|
|
124
|
+
let frameLogCorrelations;
|
|
125
|
+
if (logExcerpt && framePaths.length > 0) {
|
|
126
|
+
frameLogCorrelations = correlateLogsToFrames(logExcerpt, framePaths.length);
|
|
127
|
+
}
|
|
103
128
|
return {
|
|
104
129
|
video_analyzed: videoPath,
|
|
105
130
|
frame_count: framePaths.length,
|
|
106
131
|
framePaths,
|
|
107
132
|
expected_flow: input.expected_flow,
|
|
108
133
|
ffmpeg_available: true,
|
|
134
|
+
logExcerpt,
|
|
135
|
+
frameLogCorrelations,
|
|
109
136
|
};
|
|
110
137
|
}
|
|
111
138
|
catch {
|
|
@@ -115,7 +142,56 @@ export async function runInteractionReplay(input, _config) {
|
|
|
115
142
|
framePaths: [],
|
|
116
143
|
expected_flow: input.expected_flow,
|
|
117
144
|
ffmpeg_available: true,
|
|
145
|
+
logExcerpt,
|
|
118
146
|
};
|
|
119
147
|
}
|
|
120
148
|
}
|
|
149
|
+
function correlateLogsToFrames(logContent, frameCount) {
|
|
150
|
+
const lines = logContent.split("\n").filter(l => l.trim());
|
|
151
|
+
const timestampedLines = [];
|
|
152
|
+
for (const line of lines) {
|
|
153
|
+
const ts = parseLogTimestamp(line);
|
|
154
|
+
if (ts)
|
|
155
|
+
timestampedLines.push({ ts, line });
|
|
156
|
+
}
|
|
157
|
+
if (timestampedLines.length === 0)
|
|
158
|
+
return [];
|
|
159
|
+
const logStart = timestampedLines[0].ts;
|
|
160
|
+
const logEnd = timestampedLines[timestampedLines.length - 1].ts;
|
|
161
|
+
const logDuration = Math.max(logEnd - logStart, 1000);
|
|
162
|
+
const correlations = [];
|
|
163
|
+
for (let i = 0; i < frameCount; i++) {
|
|
164
|
+
const frameTimeOffset = (i / Math.max(frameCount - 1, 1)) * logDuration;
|
|
165
|
+
const frameTs = logStart + frameTimeOffset;
|
|
166
|
+
const windowMs = 2000;
|
|
167
|
+
const nearbyLogs = timestampedLines
|
|
168
|
+
.filter(l => Math.abs(l.ts - frameTs) <= windowMs)
|
|
169
|
+
.map(l => l.line)
|
|
170
|
+
.slice(0, 10);
|
|
171
|
+
correlations.push({
|
|
172
|
+
frameIndex: i,
|
|
173
|
+
estimatedTimestamp: new Date(frameTs).toISOString(),
|
|
174
|
+
logsNearFrame: nearbyLogs,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return correlations;
|
|
178
|
+
}
|
|
179
|
+
function parseLogTimestamp(line) {
|
|
180
|
+
// ISO 8601: 2024-01-15T10:30:00.000Z or [2024-01-15T10:30:00.000Z]
|
|
181
|
+
const isoMatch = line.match(/\[?(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[.\d]*Z?)\]?/);
|
|
182
|
+
if (isoMatch) {
|
|
183
|
+
const ts = Date.parse(isoMatch[1]);
|
|
184
|
+
if (!isNaN(ts))
|
|
185
|
+
return ts;
|
|
186
|
+
}
|
|
187
|
+
// adb logcat format: 01-15 10:30:00.000
|
|
188
|
+
const logcatMatch = line.match(/(\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d+)/);
|
|
189
|
+
if (logcatMatch) {
|
|
190
|
+
const now = new Date();
|
|
191
|
+
const ts = Date.parse(`${now.getFullYear()}-${logcatMatch[1].replace(" ", "T")}`);
|
|
192
|
+
if (!isNaN(ts))
|
|
193
|
+
return ts;
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
121
197
|
//# sourceMappingURL=interaction_replay.js.map
|