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 @@
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/runners/generic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface MaestroResult {
2
+ passed: boolean;
3
+ totalFlows: number;
4
+ passedFlows: number;
5
+ failedFlows: number;
6
+ screenshotPaths: string[];
7
+ logPath: string;
8
+ }
9
+ export declare function isMaestroInstalled(): Promise<boolean>;
10
+ export declare function findMaestroFlows(cwd: string): string[];
11
+ export declare function runMaestroTests(cwd: string, logDir: string): Promise<MaestroResult>;
12
+ //# sourceMappingURL=maestro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maestro.d.ts","sourceRoot":"","sources":["../../src/runners/maestro.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAG3D;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAQtD;AAuGD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAiCzF"}
@@ -0,0 +1,133 @@
1
+ import { runCommand } from "./base.js";
2
+ import { existsSync, mkdirSync, readdirSync } from "fs";
3
+ import { join } from "path";
4
+ const MAESTRO_FLOW_REL_DIRS = ["tests/maestro", ".maestro", "maestro"];
5
+ export async function isMaestroInstalled() {
6
+ const result = await runCommand("maestro", ["--version"], process.cwd());
7
+ return result.exit_code === 0;
8
+ }
9
+ export function findMaestroFlows(cwd) {
10
+ const flows = [];
11
+ for (const rel of MAESTRO_FLOW_REL_DIRS) {
12
+ const dir = join(cwd, rel);
13
+ if (!existsSync(dir))
14
+ continue;
15
+ collectYamlFlows(dir, flows);
16
+ }
17
+ return [...new Set(flows)].sort();
18
+ }
19
+ function collectYamlFlows(dir, out) {
20
+ const entries = readdirSync(dir, { withFileTypes: true });
21
+ for (const e of entries) {
22
+ const p = join(dir, e.name);
23
+ if (e.isDirectory()) {
24
+ collectYamlFlows(p, out);
25
+ }
26
+ else if (e.isFile() && /\.(ya?ml)$/i.test(e.name)) {
27
+ out.push(p);
28
+ }
29
+ }
30
+ }
31
+ function emptyMaestroResult(logPath = "") {
32
+ return {
33
+ passed: false,
34
+ totalFlows: 0,
35
+ passedFlows: 0,
36
+ failedFlows: 0,
37
+ screenshotPaths: [],
38
+ logPath,
39
+ };
40
+ }
41
+ function stripAnsi(s) {
42
+ // Strip ANSI color codes from CLI output before parsing.
43
+ // eslint-disable-next-line no-control-regex -- ESC prefix in CSI SGR sequences
44
+ return s.replace(/\u001b\[[0-9;]*m/g, "");
45
+ }
46
+ function parseMaestroSummary(output, flowCount, exitCode) {
47
+ const text = stripAnsi(output);
48
+ const frac = text.match(/(\d+)\s*\/\s*(\d+)\s+flows?\s+passed/i);
49
+ if (frac) {
50
+ const passedFlows = parseInt(frac[1], 10);
51
+ const totalFlows = parseInt(frac[2], 10);
52
+ return {
53
+ totalFlows,
54
+ passedFlows,
55
+ failedFlows: Math.max(0, totalFlows - passedFlows),
56
+ };
57
+ }
58
+ let passedFlows = 0;
59
+ let failedFlows = 0;
60
+ const flowsPassed = text.match(/(\d+)\s+flows?\s+passed/i);
61
+ const flowsFailed = text.match(/(\d+)\s+flows?\s+failed/i);
62
+ if (flowsPassed || flowsFailed) {
63
+ passedFlows = flowsPassed ? parseInt(flowsPassed[1], 10) : 0;
64
+ failedFlows = flowsFailed ? parseInt(flowsFailed[1], 10) : 0;
65
+ const total = passedFlows + failedFlows;
66
+ if (total > 0) {
67
+ return { totalFlows: total, passedFlows, failedFlows };
68
+ }
69
+ }
70
+ const passed = text.match(/(\d+)\s+passed\b/i);
71
+ const failed = text.match(/(\d+)\s+failed/i);
72
+ if (passed || failed) {
73
+ passedFlows = passed ? parseInt(passed[1], 10) : 0;
74
+ failedFlows = failed ? parseInt(failed[1], 10) : 0;
75
+ const total = passedFlows + failedFlows;
76
+ if (total > 0) {
77
+ return { totalFlows: total, passedFlows, failedFlows };
78
+ }
79
+ }
80
+ if (flowCount > 0) {
81
+ if (exitCode === 0) {
82
+ return { totalFlows: flowCount, passedFlows: flowCount, failedFlows: 0 };
83
+ }
84
+ return { totalFlows: flowCount, passedFlows: 0, failedFlows: flowCount };
85
+ }
86
+ return { totalFlows: 0, passedFlows: 0, failedFlows: 0 };
87
+ }
88
+ function collectScreenshotPaths(root) {
89
+ if (!existsSync(root))
90
+ return [];
91
+ const paths = [];
92
+ function walk(dir) {
93
+ for (const e of readdirSync(dir, { withFileTypes: true })) {
94
+ const p = join(dir, e.name);
95
+ if (e.isDirectory()) {
96
+ walk(p);
97
+ }
98
+ else if (/\.(png|jpe?g|webp)$/i.test(e.name)) {
99
+ paths.push(p);
100
+ }
101
+ }
102
+ }
103
+ walk(root);
104
+ return paths.sort();
105
+ }
106
+ export async function runMaestroTests(cwd, logDir) {
107
+ if (!(await isMaestroInstalled())) {
108
+ return emptyMaestroResult();
109
+ }
110
+ const flows = findMaestroFlows(cwd);
111
+ if (flows.length === 0) {
112
+ return emptyMaestroResult();
113
+ }
114
+ const logPath = join(logDir, "maestro-test.log");
115
+ const testOutputDir = join(logDir, "maestro-output");
116
+ mkdirSync(logDir, { recursive: true });
117
+ mkdirSync(testOutputDir, { recursive: true });
118
+ const args = ["test", "--test-output-dir", testOutputDir, ...flows];
119
+ const result = await runCommand("maestro", args, cwd, logPath);
120
+ const combined = result.stdout + result.stderr;
121
+ const parsed = parseMaestroSummary(combined, flows.length, result.exit_code);
122
+ const screenshotPaths = collectScreenshotPaths(testOutputDir);
123
+ const passed = result.exit_code === 0;
124
+ return {
125
+ passed,
126
+ totalFlows: parsed.totalFlows,
127
+ passedFlows: parsed.passedFlows,
128
+ failedFlows: parsed.failedFlows,
129
+ screenshotPaths,
130
+ logPath,
131
+ };
132
+ }
133
+ //# sourceMappingURL=maestro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maestro.js","sourceRoot":"","sources":["../../src/runners/maestro.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { RunnerResult } from "./base.js";
2
+ export declare function runPlaywrightTests(cwd: string, logPath: string, jsonReportPath?: string): Promise<RunnerResult>;
3
+ //# sourceMappingURL=playwright.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/runners/playwright.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAI9C,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,YAAY,CAAC,CAuCvB"}
@@ -0,0 +1,76 @@
1
+ import { runCommand, checkToolAvailable, makeSkippedResult } from "./base.js";
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { join } from "path";
4
+ export async function runPlaywrightTests(cwd, logPath, jsonReportPath) {
5
+ // Check for playwright config
6
+ const hasConfig = existsSync(join(cwd, "playwright.config.ts")) ||
7
+ existsSync(join(cwd, "playwright.config.js"));
8
+ if (!hasConfig) {
9
+ return makeSkippedResult("playwright", "No playwright config found");
10
+ }
11
+ if (!(await checkToolAvailable("npx"))) {
12
+ return makeSkippedResult("playwright", "npx not found on PATH");
13
+ }
14
+ const reportPath = jsonReportPath || join(cwd, "playwright-report.json");
15
+ const result = await runCommand("npx", ["playwright", "test", "--reporter=json"], cwd, logPath);
16
+ const { passed, failed, skipped } = parsePlaywrightOutput(result.stdout, reportPath);
17
+ return {
18
+ runner_name: "playwright",
19
+ available: true,
20
+ exit_code: result.exit_code,
21
+ passed,
22
+ failed,
23
+ skipped,
24
+ log_path: logPath,
25
+ duration_ms: result.duration_ms,
26
+ stdout: result.stdout,
27
+ stderr: result.stderr,
28
+ };
29
+ }
30
+ function parsePlaywrightOutput(stdout, reportPath) {
31
+ // Try JSON report first
32
+ try {
33
+ if (existsSync(reportPath)) {
34
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
35
+ if (report.stats) {
36
+ return {
37
+ passed: report.stats.expected || 0,
38
+ failed: (report.stats.unexpected || 0) + (report.stats.flaky || 0),
39
+ skipped: report.stats.skipped || 0,
40
+ };
41
+ }
42
+ }
43
+ }
44
+ catch {
45
+ // Fall through to stdout parsing
46
+ }
47
+ // Parse JSON from stdout (playwright --reporter=json writes to stdout)
48
+ try {
49
+ const jsonReport = JSON.parse(stdout);
50
+ if (jsonReport.stats) {
51
+ return {
52
+ passed: jsonReport.stats.expected || 0,
53
+ failed: (jsonReport.stats.unexpected || 0) + (jsonReport.stats.flaky || 0),
54
+ skipped: jsonReport.stats.skipped || 0,
55
+ };
56
+ }
57
+ }
58
+ catch {
59
+ // Fall through to regex parsing
60
+ }
61
+ // Regex fallback: "X passed", "X failed", "X skipped"
62
+ let passed = 0;
63
+ let failed = 0;
64
+ let skipped = 0;
65
+ const passMatch = stdout.match(/(\d+)\s+passed/);
66
+ if (passMatch)
67
+ passed = parseInt(passMatch[1], 10);
68
+ const failMatch = stdout.match(/(\d+)\s+failed/);
69
+ if (failMatch)
70
+ failed = parseInt(failMatch[1], 10);
71
+ const skipMatch = stdout.match(/(\d+)\s+skipped/);
72
+ if (skipMatch)
73
+ skipped = parseInt(skipMatch[1], 10);
74
+ return { passed, failed, skipped };
75
+ }
76
+ //# sourceMappingURL=playwright.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright.js","sourceRoot":"","sources":["../../src/runners/playwright.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { SectionStateRecord, SectionState } from "@codelooptech/shared";
2
+ export interface SectionRegistry {
3
+ sections: SectionStateRecord[];
4
+ updated_at: string;
5
+ }
6
+ export interface ParsedSpecSection {
7
+ section_id: string;
8
+ section_name: string;
9
+ dependencies: string[];
10
+ }
11
+ export declare function resolveProjectPath(cwd: string, p: string): string;
12
+ export declare function loadRegistry(cwd: string): SectionRegistry;
13
+ export declare function saveRegistry(cwd: string, registry: SectionRegistry): void;
14
+ export declare function getSection(registry: SectionRegistry, sectionId: string): SectionStateRecord | undefined;
15
+ export declare function updateSectionState(registry: SectionRegistry, sectionId: string, newState: SectionState, reason: string, runId?: string): SectionRegistry;
16
+ export declare function getNextSection(registry: SectionRegistry): SectionStateRecord | null;
17
+ /**
18
+ * Returns true when at least `checkpointInterval` sections are in `internally_verified`
19
+ * (verified locally and waiting to be batched into integration).
20
+ */
21
+ export declare function isIntegrationDue(registry: SectionRegistry, checkpointInterval: number): boolean;
22
+ /**
23
+ * Extracts section headings and optional dependency lists from a master spec (markdown).
24
+ */
25
+ export declare function parseMasterSpecMarkdown(markdown: string): ParsedSpecSection[];
26
+ export declare function initRegistryFromSpec(cwd: string, masterSpecPath: string): SectionRegistry;
27
+ //# sourceMappingURL=section_registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section_registry.d.ts","sourceRoot":"","sources":["../../src/state/section_registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EAEb,MAAM,sBAAsB,CAAC;AAW9B,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjE;AAWD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAkBzD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAQzE;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,MAAM,GAChB,kBAAkB,GAAG,SAAS,CAEhC;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,eAAe,CAiCjB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,kBAAkB,GAAG,IAAI,CAmBnF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,eAAe,EACzB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAQT;AA6CD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GACf,iBAAiB,EAAE,CA+CrB;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,GACrB,eAAe,CA0CjB"}
@@ -0,0 +1,219 @@
1
+ import { isSectionTransitionValid, createSectionTransition, DEFAULT_MAX_REPAIR_ATTEMPTS, } from "@codelooptech/shared";
2
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
3
+ import { join, dirname, isAbsolute, resolve, relative } from "path";
4
+ const REGISTRY_FILE = ".codeloop/sections.json";
5
+ export function resolveProjectPath(cwd, p) {
6
+ return isAbsolute(p) ? p : resolve(cwd, p);
7
+ }
8
+ function registryPath(cwd) {
9
+ return join(cwd, REGISTRY_FILE);
10
+ }
11
+ const EMPTY_REGISTRY = () => ({
12
+ sections: [],
13
+ updated_at: new Date().toISOString(),
14
+ });
15
+ export function loadRegistry(cwd) {
16
+ const path = registryPath(cwd);
17
+ if (!existsSync(path)) {
18
+ return EMPTY_REGISTRY();
19
+ }
20
+ try {
21
+ const raw = readFileSync(path, "utf-8");
22
+ const parsed = JSON.parse(raw);
23
+ if (!Array.isArray(parsed.sections)) {
24
+ return EMPTY_REGISTRY();
25
+ }
26
+ return {
27
+ sections: parsed.sections,
28
+ updated_at: parsed.updated_at ?? new Date().toISOString(),
29
+ };
30
+ }
31
+ catch {
32
+ return EMPTY_REGISTRY();
33
+ }
34
+ }
35
+ export function saveRegistry(cwd, registry) {
36
+ const path = registryPath(cwd);
37
+ mkdirSync(dirname(path), { recursive: true });
38
+ const out = {
39
+ ...registry,
40
+ updated_at: new Date().toISOString(),
41
+ };
42
+ writeFileSync(path, JSON.stringify(out, null, 2), "utf-8");
43
+ }
44
+ export function getSection(registry, sectionId) {
45
+ return registry.sections.find((s) => s.section_id === sectionId);
46
+ }
47
+ export function updateSectionState(registry, sectionId, newState, reason, runId) {
48
+ const idx = registry.sections.findIndex((s) => s.section_id === sectionId);
49
+ if (idx === -1) {
50
+ throw new Error(`Section not found: ${sectionId}`);
51
+ }
52
+ const current = registry.sections[idx];
53
+ if (current.state === newState) {
54
+ return registry;
55
+ }
56
+ if (!isSectionTransitionValid(current.state, newState)) {
57
+ throw new Error(`Invalid section transition: ${current.state} → ${newState} for ${sectionId}`);
58
+ }
59
+ const transition = createSectionTransition(current.state, newState, reason, runId ?? null);
60
+ const updated = {
61
+ ...current,
62
+ state: newState,
63
+ history: [...current.history, transition],
64
+ updated_at: new Date().toISOString(),
65
+ last_run_id: runId ?? current.last_run_id,
66
+ };
67
+ const sections = [...registry.sections];
68
+ sections[idx] = updated;
69
+ return {
70
+ sections,
71
+ updated_at: new Date().toISOString(),
72
+ };
73
+ }
74
+ export function getNextSection(registry) {
75
+ const byId = new Map(registry.sections.map((s) => [s.section_id, s]));
76
+ const candidates = registry.sections.filter((s) => s.state === "ready_to_build" || s.state === "planned");
77
+ const ordered = [
78
+ ...candidates.filter((s) => s.state === "ready_to_build"),
79
+ ...candidates.filter((s) => s.state === "planned"),
80
+ ];
81
+ for (const s of ordered) {
82
+ const depsOk = s.dependencies.every((depId) => {
83
+ const dep = byId.get(depId);
84
+ return dep !== undefined && dep.state === "done";
85
+ });
86
+ if (depsOk) {
87
+ return s;
88
+ }
89
+ }
90
+ return null;
91
+ }
92
+ /**
93
+ * Returns true when at least `checkpointInterval` sections are in `internally_verified`
94
+ * (verified locally and waiting to be batched into integration).
95
+ */
96
+ export function isIntegrationDue(registry, checkpointInterval) {
97
+ if (checkpointInterval <= 0) {
98
+ return false;
99
+ }
100
+ const verified = registry.sections.filter((s) => s.state === "internally_verified").length;
101
+ return verified >= checkpointInterval;
102
+ }
103
+ function slugify(title, used) {
104
+ const base = title
105
+ .toLowerCase()
106
+ .replace(/[^a-z0-9]+/g, "-")
107
+ .replace(/^-|-$/g, "") || "section";
108
+ let id = base;
109
+ let n = 2;
110
+ while (used.has(id)) {
111
+ id = `${base}-${n}`;
112
+ n += 1;
113
+ }
114
+ used.add(id);
115
+ return id;
116
+ }
117
+ function parseDependenciesFromBlock(block) {
118
+ const deps = [];
119
+ const depHeader = block.match(/\*\*Dependencies:\*\*([\s\S]*?)(?=\n#{1,6}\s|\n?$)/i);
120
+ const region = depHeader ? depHeader[1] : block;
121
+ const lines = region.split("\n");
122
+ for (const line of lines) {
123
+ const m = line.match(/^\s*[-*]\s+(?:`([^`]+)`|([a-zA-Z][a-zA-Z0-9_-]*))/);
124
+ if (m) {
125
+ deps.push((m[1] ?? m[2]).trim());
126
+ }
127
+ }
128
+ const inline = block.match(/(?:depends on|dependencies)\s*:\s*([^\n]+)/i);
129
+ if (inline) {
130
+ for (const part of inline[1].split(/[,;]/)) {
131
+ const t = part.trim().replace(/^`|`$/g, "");
132
+ if (t.length > 0) {
133
+ deps.push(t);
134
+ }
135
+ }
136
+ }
137
+ return [...new Set(deps)];
138
+ }
139
+ /**
140
+ * Extracts section headings and optional dependency lists from a master spec (markdown).
141
+ */
142
+ export function parseMasterSpecMarkdown(markdown) {
143
+ const lines = markdown.split(/\r?\n/);
144
+ const sections = [];
145
+ const usedIds = new Set();
146
+ for (let i = 0; i < lines.length; i++) {
147
+ const line = lines[i];
148
+ const hm = line.match(/^(#{2,6})\s+(.+)$/);
149
+ if (!hm) {
150
+ continue;
151
+ }
152
+ const title = hm[2].trim();
153
+ let sectionId;
154
+ const numbered = title.match(/^(?:section\s*)?(\d+(?:\.\d+)?)\s*[—\-:]\s*(.+)$/i);
155
+ if (numbered) {
156
+ const baseId = `section-${numbered[1].replace(/\./g, "-")}`;
157
+ sectionId = baseId;
158
+ let n = 2;
159
+ while (usedIds.has(sectionId)) {
160
+ sectionId = `${baseId}-${n}`;
161
+ n += 1;
162
+ }
163
+ usedIds.add(sectionId);
164
+ }
165
+ else {
166
+ sectionId = slugify(title, usedIds);
167
+ }
168
+ const blockLines = [];
169
+ for (let j = i + 1; j < lines.length; j++) {
170
+ if (/^#{1,6}\s/.test(lines[j])) {
171
+ break;
172
+ }
173
+ blockLines.push(lines[j]);
174
+ }
175
+ const block = blockLines.join("\n");
176
+ const dependencies = parseDependenciesFromBlock(block);
177
+ sections.push({
178
+ section_id: sectionId,
179
+ section_name: title,
180
+ dependencies,
181
+ });
182
+ }
183
+ return sections;
184
+ }
185
+ export function initRegistryFromSpec(cwd, masterSpecPath) {
186
+ const abs = resolveProjectPath(cwd, masterSpecPath);
187
+ if (!existsSync(abs)) {
188
+ throw new Error(`Master spec not found: ${abs}`);
189
+ }
190
+ const markdown = readFileSync(abs, "utf-8");
191
+ const parsed = parseMasterSpecMarkdown(markdown);
192
+ const specDir = dirname(abs);
193
+ const now = new Date().toISOString();
194
+ const sections = parsed.map((p) => {
195
+ const specRel = relative(cwd, join(specDir, `${p.section_id}.md`)).replace(/\\/g, "/");
196
+ const acceptRel = relative(cwd, join(specDir, "acceptance", `${p.section_id}.md`)).replace(/\\/g, "/");
197
+ const record = {
198
+ section_id: p.section_id,
199
+ section_name: p.section_name,
200
+ state: "planned",
201
+ confidence: 0,
202
+ spec_path: specRel,
203
+ acceptance_path: acceptRel,
204
+ dependencies: p.dependencies,
205
+ last_run_id: null,
206
+ last_gate_result: null,
207
+ repair_attempts: 0,
208
+ max_repair_attempts: DEFAULT_MAX_REPAIR_ATTEMPTS,
209
+ history: [],
210
+ updated_at: now,
211
+ };
212
+ return record;
213
+ });
214
+ return {
215
+ sections,
216
+ updated_at: now,
217
+ };
218
+ }
219
+ //# sourceMappingURL=section_registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section_registry.js","sourceRoot":"","sources":["../../src/state/section_registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { DesignCompareInput, DesignCompareOutput } from "@codelooptech/shared";
2
+ import type { CodeLoopConfig } from "@codelooptech/shared";
3
+ export declare function runDesignCompare(input: DesignCompareInput, config: CodeLoopConfig): Promise<DesignCompareOutput>;
4
+ //# sourceMappingURL=design_compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design_compare.d.ts","sourceRoot":"","sources":["../../src/tools/design_compare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAc3D,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,mBAAmB,CAAC,CAwE9B"}
@@ -0,0 +1,73 @@
1
+ import { compareDesign } from "../diagnosis/vision_reviewer.js";
2
+ import { existsSync } from "fs";
3
+ import { join, resolve } from "path";
4
+ import { getArtifactsBaseDir, getRunDir, listRuns } from "../evidence/artifacts.js";
5
+ function screenFileName(screenName) {
6
+ const s = screenName.trim();
7
+ if (s.toLowerCase().endsWith(".png")) {
8
+ return s;
9
+ }
10
+ return `${s}.png`;
11
+ }
12
+ export async function runDesignCompare(input, config) {
13
+ const cwd = process.cwd();
14
+ const refPath = resolve(cwd, input.reference_image_path);
15
+ if (!existsSync(refPath)) {
16
+ return {
17
+ match_score: 0,
18
+ differences: [
19
+ {
20
+ area: "reference",
21
+ description: `Reference image not found: ${input.reference_image_path}`,
22
+ severity: "high",
23
+ fix_hint: "Provide a valid reference_image_path.",
24
+ },
25
+ ],
26
+ screenshots: [],
27
+ recommendation: "Add the design reference image and retry.",
28
+ };
29
+ }
30
+ const base = getArtifactsBaseDir(cwd);
31
+ const runs = listRuns(base);
32
+ const latestRun = runs[0];
33
+ const actualPath = latestRun
34
+ ? join(getRunDir(latestRun, base), "screenshots", screenFileName(input.screen_name))
35
+ : "";
36
+ if (!actualPath || !existsSync(actualPath)) {
37
+ return {
38
+ match_score: 0,
39
+ differences: [
40
+ {
41
+ area: "screenshot",
42
+ description: latestRun
43
+ ? `No screenshot found for "${input.screen_name}" in the latest run (${latestRun}).`
44
+ : "No verification runs found; cannot locate an actual screenshot.",
45
+ severity: "high",
46
+ fix_hint: "Run codeloop_verify to capture screenshots, or ensure the screen name matches a PNG in artifacts/runs/<run>/screenshots/.",
47
+ },
48
+ ],
49
+ screenshots: [refPath],
50
+ recommendation: "Capture the UI first, then compare.",
51
+ };
52
+ }
53
+ const uxPath = input.ux_checklist_path
54
+ ? resolve(cwd, input.ux_checklist_path)
55
+ : undefined;
56
+ const result = await compareDesign({
57
+ referencePath: refPath,
58
+ actualPath,
59
+ screenName: input.screen_name,
60
+ uxChecklistPath: uxPath,
61
+ }, config);
62
+ const threshold = config.design_match_threshold ?? 0.8;
63
+ const recommendation = result.matchScore >= threshold
64
+ ? "The implementation is close enough to the reference design for the configured threshold."
65
+ : "Review the listed differences and adjust the UI to match the reference.";
66
+ return {
67
+ match_score: result.matchScore,
68
+ differences: result.differences,
69
+ screenshots: [refPath, actualPath],
70
+ recommendation,
71
+ };
72
+ }
73
+ //# sourceMappingURL=design_compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design_compare.js","sourceRoot":"","sources":["../../src/tools/design_compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DiagnoseInput, DiagnoseOutput, CodeLoopConfig } from "@codelooptech/shared";
2
+ export declare function runDiagnose(input: DiagnoseInput, config: CodeLoopConfig, cwd?: string): Promise<DiagnoseOutput>;
3
+ //# sourceMappingURL=diagnose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../../src/tools/diagnose.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAKd,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAmG9B,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,cAAc,EACtB,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAqDzB"}