@prowi/deskcheck 0.1.0 → 0.3.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/README.md +67 -12
- package/build/cli.js +112 -24
- package/build/cli.js.map +1 -1
- package/build/{core/config.d.ts → config/loader.d.ts} +9 -1
- package/build/config/loader.d.ts.map +1 -0
- package/build/{core/config.js → config/loader.js} +4 -2
- package/build/config/loader.js.map +1 -0
- package/build/config/types.d.ts +45 -0
- package/build/config/types.d.ts.map +1 -0
- package/build/config/types.js +2 -0
- package/build/config/types.js.map +1 -0
- package/build/mcp/tools.d.ts +1 -1
- package/build/mcp/tools.d.ts.map +1 -1
- package/build/mcp/tools.js +35 -25
- package/build/mcp/tools.js.map +1 -1
- package/build/mcp-server.js +1 -1
- package/build/mcp-server.js.map +1 -1
- package/build/{agents/executor-prompt.d.ts → prompts/ExecutorPrompt.d.ts} +6 -2
- package/build/prompts/ExecutorPrompt.d.ts.map +1 -0
- package/build/prompts/ExecutorPrompt.js +111 -0
- package/build/prompts/ExecutorPrompt.js.map +1 -0
- package/build/prompts/JudgePrompt.d.ts +16 -0
- package/build/prompts/JudgePrompt.d.ts.map +1 -0
- package/build/prompts/JudgePrompt.js +57 -0
- package/build/prompts/JudgePrompt.js.map +1 -0
- package/build/prompts/PlannerPrompt.d.ts +12 -0
- package/build/prompts/PlannerPrompt.d.ts.map +1 -0
- package/build/prompts/PlannerPrompt.js +34 -0
- package/build/prompts/PlannerPrompt.js.map +1 -0
- package/build/renderers/{json.d.ts → review/JsonRenderer.d.ts} +2 -2
- package/build/renderers/review/JsonRenderer.d.ts.map +1 -0
- package/build/renderers/{json.js → review/JsonRenderer.js} +1 -1
- package/build/renderers/review/JsonRenderer.js.map +1 -0
- package/build/renderers/{markdown.d.ts → review/MarkdownRenderer.d.ts} +2 -2
- package/build/renderers/review/MarkdownRenderer.d.ts.map +1 -0
- package/build/renderers/review/MarkdownRenderer.js +52 -0
- package/build/renderers/review/MarkdownRenderer.js.map +1 -0
- package/build/renderers/{terminal.d.ts → review/TerminalRenderer.d.ts} +2 -2
- package/build/renderers/review/TerminalRenderer.d.ts.map +1 -0
- package/build/renderers/{terminal.js → review/TerminalRenderer.js} +36 -14
- package/build/renderers/review/TerminalRenderer.js.map +1 -0
- package/build/renderers/{watch.d.ts → review/WatchRenderer.d.ts} +2 -2
- package/build/renderers/review/WatchRenderer.d.ts.map +1 -0
- package/build/renderers/{watch.js → review/WatchRenderer.js} +3 -3
- package/build/renderers/review/WatchRenderer.js.map +1 -0
- package/build/renderers/shared.d.ts +11 -11
- package/build/renderers/shared.d.ts.map +1 -1
- package/build/renderers/shared.js +15 -15
- package/build/renderers/shared.js.map +1 -1
- package/build/renderers/test/TerminalRenderer.d.ts +14 -0
- package/build/renderers/test/TerminalRenderer.d.ts.map +1 -0
- package/build/renderers/test/TerminalRenderer.js +233 -0
- package/build/renderers/test/TerminalRenderer.js.map +1 -0
- package/build/server/controllers/ReviewController.d.ts +23 -0
- package/build/server/controllers/ReviewController.d.ts.map +1 -0
- package/build/server/controllers/ReviewController.js +90 -0
- package/build/server/controllers/ReviewController.js.map +1 -0
- package/build/server/controllers/TestController.d.ts +2 -0
- package/build/server/controllers/TestController.d.ts.map +1 -0
- package/build/server/controllers/TestController.js +3 -0
- package/build/server/controllers/TestController.js.map +1 -0
- package/build/server/middleware/cors.d.ts +9 -0
- package/build/server/middleware/cors.d.ts.map +1 -0
- package/build/server/middleware/cors.js +18 -0
- package/build/server/middleware/cors.js.map +1 -0
- package/build/{serve.d.ts → server/server.d.ts} +2 -2
- package/build/server/server.d.ts.map +1 -0
- package/build/server/server.js +102 -0
- package/build/server/server.js.map +1 -0
- package/build/server/sse/FileWatcherSSE.d.ts +10 -0
- package/build/server/sse/FileWatcherSSE.d.ts.map +1 -0
- package/build/server/sse/FileWatcherSSE.js +89 -0
- package/build/server/sse/FileWatcherSSE.js.map +1 -0
- package/build/services/ExecutorService.d.ts +51 -0
- package/build/services/ExecutorService.d.ts.map +1 -0
- package/build/services/ExecutorService.js +133 -0
- package/build/services/ExecutorService.js.map +1 -0
- package/build/services/FindingsParserService.d.ts +18 -0
- package/build/services/FindingsParserService.d.ts.map +1 -0
- package/build/services/FindingsParserService.js +119 -0
- package/build/services/FindingsParserService.js.map +1 -0
- package/build/services/criteria/CriteriaService.d.ts +10 -0
- package/build/services/criteria/CriteriaService.d.ts.map +1 -0
- package/build/services/criteria/CriteriaService.js +10 -0
- package/build/services/criteria/CriteriaService.js.map +1 -0
- package/build/{core → services/criteria}/glob-matcher.d.ts +1 -1
- package/build/services/criteria/glob-matcher.d.ts.map +1 -0
- package/build/services/criteria/glob-matcher.js.map +1 -0
- package/build/{core → services/criteria}/module-parser.d.ts +13 -1
- package/build/services/criteria/module-parser.d.ts.map +1 -0
- package/build/{core → services/criteria}/module-parser.js +38 -0
- package/build/services/criteria/module-parser.js.map +1 -0
- package/build/{core/context-extractor.d.ts → services/review/ReviewContextExtractorService.d.ts} +2 -2
- package/build/services/review/ReviewContextExtractorService.d.ts.map +1 -0
- package/build/{core/context-extractor.js → services/review/ReviewContextExtractorService.js} +1 -1
- package/build/services/review/ReviewContextExtractorService.js.map +1 -0
- package/build/{agents/orchestrator.d.ts → services/review/ReviewOrchestratorService.d.ts} +7 -5
- package/build/services/review/ReviewOrchestratorService.d.ts.map +1 -0
- package/build/services/review/ReviewOrchestratorService.js +187 -0
- package/build/services/review/ReviewOrchestratorService.js.map +1 -0
- package/build/{core/plan-builder.d.ts → services/review/ReviewPlanBuilderService.d.ts} +5 -4
- package/build/services/review/ReviewPlanBuilderService.d.ts.map +1 -0
- package/build/{core/plan-builder.js → services/review/ReviewPlanBuilderService.js} +2 -2
- package/build/services/review/ReviewPlanBuilderService.js.map +1 -0
- package/build/{agents/planner.d.ts → services/review/ReviewPlannerService.d.ts} +5 -4
- package/build/services/review/ReviewPlannerService.d.ts.map +1 -0
- package/build/{agents/planner.js → services/review/ReviewPlannerService.js} +13 -29
- package/build/services/review/ReviewPlannerService.js.map +1 -0
- package/build/{core/storage.d.ts → services/review/ReviewStorageService.d.ts} +4 -4
- package/build/services/review/ReviewStorageService.d.ts.map +1 -0
- package/build/{core/storage.js → services/review/ReviewStorageService.js} +42 -27
- package/build/services/review/ReviewStorageService.js.map +1 -0
- package/build/services/testing/JudgeService.d.ts +30 -0
- package/build/services/testing/JudgeService.d.ts.map +1 -0
- package/build/services/testing/JudgeService.js +95 -0
- package/build/services/testing/JudgeService.js.map +1 -0
- package/build/services/testing/TestDiscoveryService.d.ts +16 -0
- package/build/services/testing/TestDiscoveryService.d.ts.map +1 -0
- package/build/services/testing/TestDiscoveryService.js +66 -0
- package/build/services/testing/TestDiscoveryService.js.map +1 -0
- package/build/services/testing/TestRunnerService.d.ts +35 -0
- package/build/services/testing/TestRunnerService.d.ts.map +1 -0
- package/build/services/testing/TestRunnerService.js +140 -0
- package/build/services/testing/TestRunnerService.js.map +1 -0
- package/build/services/testing/TestScorerService.d.ts +9 -0
- package/build/services/testing/TestScorerService.d.ts.map +1 -0
- package/build/services/testing/TestScorerService.js +35 -0
- package/build/services/testing/TestScorerService.js.map +1 -0
- package/build/services/testing/TestStorageService.d.ts +39 -0
- package/build/services/testing/TestStorageService.d.ts.map +1 -0
- package/build/services/testing/TestStorageService.js +144 -0
- package/build/services/testing/TestStorageService.js.map +1 -0
- package/build/types/criteria.d.ts +24 -0
- package/build/types/criteria.d.ts.map +1 -0
- package/build/{core/types.js → types/criteria.js} +2 -2
- package/build/types/criteria.js.map +1 -0
- package/build/{core/types.d.ts → types/review.d.ts} +54 -88
- package/build/types/review.d.ts.map +1 -0
- package/build/types/review.js +2 -0
- package/build/types/review.js.map +1 -0
- package/build/types/testing.d.ts +109 -0
- package/build/types/testing.d.ts.map +1 -0
- package/build/types/testing.js +2 -0
- package/build/types/testing.js.map +1 -0
- package/package.json +1 -1
- package/ui/dist/index.html +34 -34
- package/build/agents/executor-prompt.d.ts.map +0 -1
- package/build/agents/executor-prompt.js +0 -65
- package/build/agents/executor-prompt.js.map +0 -1
- package/build/agents/orchestrator.d.ts.map +0 -1
- package/build/agents/orchestrator.js +0 -343
- package/build/agents/orchestrator.js.map +0 -1
- package/build/agents/planner.d.ts.map +0 -1
- package/build/agents/planner.js.map +0 -1
- package/build/core/config.d.ts.map +0 -1
- package/build/core/config.js.map +0 -1
- package/build/core/context-extractor.d.ts.map +0 -1
- package/build/core/context-extractor.js.map +0 -1
- package/build/core/glob-matcher.d.ts.map +0 -1
- package/build/core/glob-matcher.js.map +0 -1
- package/build/core/module-parser.d.ts.map +0 -1
- package/build/core/module-parser.js.map +0 -1
- package/build/core/plan-builder.d.ts.map +0 -1
- package/build/core/plan-builder.js.map +0 -1
- package/build/core/storage.d.ts.map +0 -1
- package/build/core/storage.js.map +0 -1
- package/build/core/types.d.ts.map +0 -1
- package/build/core/types.js.map +0 -1
- package/build/renderers/json.d.ts.map +0 -1
- package/build/renderers/json.js.map +0 -1
- package/build/renderers/markdown.d.ts.map +0 -1
- package/build/renderers/markdown.js +0 -36
- package/build/renderers/markdown.js.map +0 -1
- package/build/renderers/terminal.d.ts.map +0 -1
- package/build/renderers/terminal.js.map +0 -1
- package/build/renderers/watch.d.ts.map +0 -1
- package/build/renderers/watch.js.map +0 -1
- package/build/serve.d.ts.map +0 -1
- package/build/serve.js +0 -249
- package/build/serve.js.map +0 -1
- /package/build/{core → services/criteria}/glob-matcher.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAyCvD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAkEzF"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { URL } from "node:url";
|
|
5
|
+
import { ReviewStorageService } from "../services/review/ReviewStorageService.js";
|
|
6
|
+
import { handleCors } from "./middleware/cors.js";
|
|
7
|
+
import { handleGetRuns, handleGetPlan, handleGetResults } from "./controllers/ReviewController.js";
|
|
8
|
+
import { handleSSE } from "./sse/FileWatcherSSE.js";
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Response helpers
|
|
11
|
+
// =============================================================================
|
|
12
|
+
function sendJson(res, data, status = 200) {
|
|
13
|
+
const body = JSON.stringify(data);
|
|
14
|
+
res.writeHead(status, {
|
|
15
|
+
"Content-Type": "application/json",
|
|
16
|
+
"Access-Control-Allow-Origin": "*",
|
|
17
|
+
"Cache-Control": "no-cache",
|
|
18
|
+
});
|
|
19
|
+
res.end(body);
|
|
20
|
+
}
|
|
21
|
+
function sendHtml(res, html) {
|
|
22
|
+
res.writeHead(200, {
|
|
23
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
24
|
+
"Access-Control-Allow-Origin": "*",
|
|
25
|
+
});
|
|
26
|
+
res.end(html);
|
|
27
|
+
}
|
|
28
|
+
function sendError(res, status, message) {
|
|
29
|
+
sendJson(res, { error: message }, status);
|
|
30
|
+
}
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// URL parsing
|
|
33
|
+
// =============================================================================
|
|
34
|
+
/** Parse a URL path into segments, e.g. "/api/runs/abc/plan" -> ["api", "runs", "abc", "plan"]. */
|
|
35
|
+
function parseSegments(pathname) {
|
|
36
|
+
return pathname.split("/").filter((s) => s.length > 0);
|
|
37
|
+
}
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// Server
|
|
40
|
+
// =============================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Start the deskcheck web UI server.
|
|
43
|
+
*
|
|
44
|
+
* Serves a self-contained HTML dashboard at the root, a JSON API for run data,
|
|
45
|
+
* and SSE streams for live updates during execution.
|
|
46
|
+
*/
|
|
47
|
+
export function startServer(config, projectRoot, port) {
|
|
48
|
+
const storageDir = path.join(projectRoot, config.storage_dir);
|
|
49
|
+
const storage = new ReviewStorageService(storageDir);
|
|
50
|
+
const uiHtmlPath = path.resolve(path.dirname(new URL(import.meta.url).pathname), "../../ui/dist/index.html");
|
|
51
|
+
const server = http.createServer((req, res) => {
|
|
52
|
+
// Handle CORS preflight
|
|
53
|
+
if (handleCors(req, res))
|
|
54
|
+
return;
|
|
55
|
+
if (req.method !== "GET") {
|
|
56
|
+
sendError(res, 405, "Method not allowed");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const parsedUrl = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
60
|
+
const segments = parseSegments(parsedUrl.pathname);
|
|
61
|
+
// GET / -> dashboard HTML (re-read on each request so UI rebuilds are picked up without restart)
|
|
62
|
+
if (segments.length === 0) {
|
|
63
|
+
if (!fs.existsSync(uiHtmlPath)) {
|
|
64
|
+
sendHtml(res, "<html><body><p>UI not built yet. Run <code>cd ui && npm run build</code>, or use the Vite dev server at <code>http://localhost:5173</code>.</p></body></html>");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const dashboardHtml = fs.readFileSync(uiHtmlPath, "utf-8");
|
|
68
|
+
sendHtml(res, dashboardHtml);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// API routes all start with "api"
|
|
72
|
+
if (segments[0] !== "api") {
|
|
73
|
+
sendError(res, 404, "Not found");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// GET /api/runs
|
|
77
|
+
if (segments.length === 2 && segments[1] === "runs") {
|
|
78
|
+
handleGetRuns(storage, res);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// GET /api/runs/:id/plan
|
|
82
|
+
if (segments.length === 4 && segments[1] === "runs" && segments[3] === "plan") {
|
|
83
|
+
handleGetPlan(storage, res, decodeURIComponent(segments[2]));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// GET /api/runs/:id/results
|
|
87
|
+
if (segments.length === 4 && segments[1] === "runs" && segments[3] === "results") {
|
|
88
|
+
handleGetResults(storage, res, decodeURIComponent(segments[2]));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// GET /api/events/:id -> SSE stream
|
|
92
|
+
if (segments.length === 3 && segments[1] === "events") {
|
|
93
|
+
handleSSE(res, storageDir, decodeURIComponent(segments[2]));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
sendError(res, 404, "Not found");
|
|
97
|
+
});
|
|
98
|
+
server.listen(port, () => {
|
|
99
|
+
console.log(`Deskcheck UI: http://localhost:${port}`);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type http from "node:http";
|
|
2
|
+
/**
|
|
3
|
+
* Stream SSE events when JSON files change in a watched directory.
|
|
4
|
+
*
|
|
5
|
+
* Watches the given directory for changes to `.json` files and emits
|
|
6
|
+
* `data: {"type":"update"}` events to the connected client. Falls back
|
|
7
|
+
* to polling if `fs.watch` is unavailable.
|
|
8
|
+
*/
|
|
9
|
+
export declare function handleSSE(res: http.ServerResponse, storageDir: string, planId: string): void;
|
|
10
|
+
//# sourceMappingURL=FileWatcherSSE.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileWatcherSSE.d.ts","sourceRoot":"","sources":["../../../src/server/sse/FileWatcherSSE.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,IAAI,CAiFN"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Stream SSE events when JSON files change in a watched directory.
|
|
5
|
+
*
|
|
6
|
+
* Watches the given directory for changes to `.json` files and emits
|
|
7
|
+
* `data: {"type":"update"}` events to the connected client. Falls back
|
|
8
|
+
* to polling if `fs.watch` is unavailable.
|
|
9
|
+
*/
|
|
10
|
+
export function handleSSE(res, storageDir, planId) {
|
|
11
|
+
const planDir = path.join(storageDir, planId);
|
|
12
|
+
if (!fs.existsSync(planDir)) {
|
|
13
|
+
const body = JSON.stringify({ error: `Plan not found: ${planId}` });
|
|
14
|
+
res.writeHead(404, {
|
|
15
|
+
"Content-Type": "application/json",
|
|
16
|
+
"Access-Control-Allow-Origin": "*",
|
|
17
|
+
"Cache-Control": "no-cache",
|
|
18
|
+
});
|
|
19
|
+
res.end(body);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
res.writeHead(200, {
|
|
23
|
+
"Content-Type": "text/event-stream",
|
|
24
|
+
"Access-Control-Allow-Origin": "*",
|
|
25
|
+
"Cache-Control": "no-cache",
|
|
26
|
+
"Connection": "keep-alive",
|
|
27
|
+
});
|
|
28
|
+
// Send initial keepalive
|
|
29
|
+
res.write(": connected\n\n");
|
|
30
|
+
// Watch the plan directory for changes to plan.json or results.json
|
|
31
|
+
let debounceTimer = null;
|
|
32
|
+
let watcher = null;
|
|
33
|
+
try {
|
|
34
|
+
watcher = fs.watch(planDir, (_eventType, filename) => {
|
|
35
|
+
if (filename !== "plan.json" && filename !== "results.json")
|
|
36
|
+
return;
|
|
37
|
+
// Debounce: plan.json and results.json often update in quick succession
|
|
38
|
+
if (debounceTimer)
|
|
39
|
+
clearTimeout(debounceTimer);
|
|
40
|
+
debounceTimer = setTimeout(() => {
|
|
41
|
+
try {
|
|
42
|
+
res.write('data: {"type":"update"}\n\n');
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Client disconnected
|
|
46
|
+
cleanup();
|
|
47
|
+
}
|
|
48
|
+
}, 100);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// If fs.watch fails, fall back to polling
|
|
53
|
+
const pollInterval = setInterval(() => {
|
|
54
|
+
try {
|
|
55
|
+
res.write('data: {"type":"update"}\n\n');
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
clearInterval(pollInterval);
|
|
59
|
+
}
|
|
60
|
+
}, 2000);
|
|
61
|
+
res.on("close", () => {
|
|
62
|
+
clearInterval(pollInterval);
|
|
63
|
+
});
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
function cleanup() {
|
|
67
|
+
if (debounceTimer)
|
|
68
|
+
clearTimeout(debounceTimer);
|
|
69
|
+
if (watcher) {
|
|
70
|
+
watcher.close();
|
|
71
|
+
watcher = null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Keep-alive every 30s to prevent proxy timeouts
|
|
75
|
+
const keepalive = setInterval(() => {
|
|
76
|
+
try {
|
|
77
|
+
res.write(": keepalive\n\n");
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
cleanup();
|
|
81
|
+
clearInterval(keepalive);
|
|
82
|
+
}
|
|
83
|
+
}, 30_000);
|
|
84
|
+
res.on("close", () => {
|
|
85
|
+
cleanup();
|
|
86
|
+
clearInterval(keepalive);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=FileWatcherSSE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileWatcherSSE.js","sourceRoot":"","sources":["../../../src/server/sse/FileWatcherSSE.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { McpServerConfig as SdkMcpServerConfig, PermissionMode } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
import type { ReviewConfig } from "../config/types.js";
|
|
3
|
+
import type { AgentModel } from "../types/criteria.js";
|
|
4
|
+
import type { TaskUsage } from "../types/review.js";
|
|
5
|
+
/** The result returned by ExecutorService.execute(). */
|
|
6
|
+
export interface ExecutorResult {
|
|
7
|
+
resultText: string;
|
|
8
|
+
usage: TaskUsage | null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Build the merged MCP servers map for an executor agent.
|
|
12
|
+
*
|
|
13
|
+
* Combines shared MCP servers from config with any additional servers
|
|
14
|
+
* defined for the executor role.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildMcpServers(config: ReviewConfig): Record<string, SdkMcpServerConfig>;
|
|
17
|
+
/**
|
|
18
|
+
* Build the merged allowed tools list for an executor agent.
|
|
19
|
+
*
|
|
20
|
+
* Combines shared tools from config with any additional tools defined
|
|
21
|
+
* for the executor role.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildAllowedTools(config: ReviewConfig): string[];
|
|
24
|
+
/**
|
|
25
|
+
* Spawns a single executor agent via the Claude Agent SDK and returns
|
|
26
|
+
* the result text and usage data.
|
|
27
|
+
*
|
|
28
|
+
* Encapsulates the query() call, AbortController timeout, MCP server
|
|
29
|
+
* merging, and tool merging so callers don't need to know these details.
|
|
30
|
+
*/
|
|
31
|
+
export declare class ExecutorService {
|
|
32
|
+
private readonly config;
|
|
33
|
+
private readonly projectRoot;
|
|
34
|
+
constructor(config: ReviewConfig, projectRoot: string);
|
|
35
|
+
/**
|
|
36
|
+
* Execute an agent with the given prompt and model.
|
|
37
|
+
*
|
|
38
|
+
* @param prompt - The system prompt for the executor agent.
|
|
39
|
+
* @param model - The Claude model tier to use.
|
|
40
|
+
* @param options - Optional overrides for tools, MCP servers, max turns, timeout, and permission mode.
|
|
41
|
+
* @returns The result text and usage data from the agent run.
|
|
42
|
+
*/
|
|
43
|
+
execute(prompt: string, model: AgentModel, options?: {
|
|
44
|
+
maxTurns?: number;
|
|
45
|
+
timeoutMs?: number;
|
|
46
|
+
tools?: string[];
|
|
47
|
+
mcpServers?: Record<string, SdkMcpServerConfig>;
|
|
48
|
+
permissionMode?: PermissionMode;
|
|
49
|
+
}): Promise<ExecutorResult>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=ExecutorService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExecutorService.d.ts","sourceRoot":"","sources":["../../src/services/ExecutorService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,IAAI,kBAAkB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC5G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAMpD,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CA2BxF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAahE;AAMD;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM;IAKrD;;;;;;;OAOG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAChD,cAAc,CAAC,EAAE,cAAc,CAAC;KACjC,GAAG,OAAO,CAAC,cAAc,CAAC;CAwD5B"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Helpers
|
|
4
|
+
// =============================================================================
|
|
5
|
+
/**
|
|
6
|
+
* Build the merged MCP servers map for an executor agent.
|
|
7
|
+
*
|
|
8
|
+
* Combines shared MCP servers from config with any additional servers
|
|
9
|
+
* defined for the executor role.
|
|
10
|
+
*/
|
|
11
|
+
export function buildMcpServers(config) {
|
|
12
|
+
const servers = {};
|
|
13
|
+
// Add shared servers
|
|
14
|
+
for (const [name, serverConfig] of Object.entries(config.shared.mcp_servers)) {
|
|
15
|
+
servers[name] = {
|
|
16
|
+
type: "stdio",
|
|
17
|
+
command: serverConfig.command,
|
|
18
|
+
args: serverConfig.args,
|
|
19
|
+
env: serverConfig.env,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// Add executor-specific additional servers
|
|
23
|
+
const executorServers = config.agents.executor.additional_mcp_servers;
|
|
24
|
+
if (executorServers) {
|
|
25
|
+
for (const [name, serverConfig] of Object.entries(executorServers)) {
|
|
26
|
+
servers[name] = {
|
|
27
|
+
type: "stdio",
|
|
28
|
+
command: serverConfig.command,
|
|
29
|
+
args: serverConfig.args,
|
|
30
|
+
env: serverConfig.env,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return servers;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the merged allowed tools list for an executor agent.
|
|
38
|
+
*
|
|
39
|
+
* Combines shared tools from config with any additional tools defined
|
|
40
|
+
* for the executor role.
|
|
41
|
+
*/
|
|
42
|
+
export function buildAllowedTools(config) {
|
|
43
|
+
const tools = [...config.shared.allowed_tools];
|
|
44
|
+
const executorTools = config.agents.executor.additional_tools;
|
|
45
|
+
if (executorTools) {
|
|
46
|
+
for (const tool of executorTools) {
|
|
47
|
+
if (!tools.includes(tool)) {
|
|
48
|
+
tools.push(tool);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return tools;
|
|
53
|
+
}
|
|
54
|
+
// =============================================================================
|
|
55
|
+
// ExecutorService
|
|
56
|
+
// =============================================================================
|
|
57
|
+
/**
|
|
58
|
+
* Spawns a single executor agent via the Claude Agent SDK and returns
|
|
59
|
+
* the result text and usage data.
|
|
60
|
+
*
|
|
61
|
+
* Encapsulates the query() call, AbortController timeout, MCP server
|
|
62
|
+
* merging, and tool merging so callers don't need to know these details.
|
|
63
|
+
*/
|
|
64
|
+
export class ExecutorService {
|
|
65
|
+
config;
|
|
66
|
+
projectRoot;
|
|
67
|
+
constructor(config, projectRoot) {
|
|
68
|
+
this.config = config;
|
|
69
|
+
this.projectRoot = projectRoot;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Execute an agent with the given prompt and model.
|
|
73
|
+
*
|
|
74
|
+
* @param prompt - The system prompt for the executor agent.
|
|
75
|
+
* @param model - The Claude model tier to use.
|
|
76
|
+
* @param options - Optional overrides for tools, MCP servers, max turns, timeout, and permission mode.
|
|
77
|
+
* @returns The result text and usage data from the agent run.
|
|
78
|
+
*/
|
|
79
|
+
async execute(prompt, model, options) {
|
|
80
|
+
const allowedTools = options?.tools ?? buildAllowedTools(this.config);
|
|
81
|
+
const mcpServers = options?.mcpServers ?? buildMcpServers(this.config);
|
|
82
|
+
const maxTurns = options?.maxTurns ?? 25;
|
|
83
|
+
const timeoutMs = options?.timeoutMs ?? 5 * 60 * 1000;
|
|
84
|
+
const permissionMode = options?.permissionMode ?? "dontAsk";
|
|
85
|
+
const abortController = new AbortController();
|
|
86
|
+
const timeout = setTimeout(() => abortController.abort(), timeoutMs);
|
|
87
|
+
let resultText = "";
|
|
88
|
+
let taskUsage = null;
|
|
89
|
+
try {
|
|
90
|
+
for await (const message of query({
|
|
91
|
+
prompt,
|
|
92
|
+
options: {
|
|
93
|
+
model,
|
|
94
|
+
tools: allowedTools,
|
|
95
|
+
permissionMode,
|
|
96
|
+
maxTurns,
|
|
97
|
+
cwd: this.projectRoot,
|
|
98
|
+
persistSession: false,
|
|
99
|
+
abortController,
|
|
100
|
+
...(Object.keys(mcpServers).length > 0 ? { mcpServers } : {}),
|
|
101
|
+
},
|
|
102
|
+
})) {
|
|
103
|
+
if (message.type === "result") {
|
|
104
|
+
// Capture usage data from result (available on both success and error)
|
|
105
|
+
const msg = message;
|
|
106
|
+
const usage = msg.usage;
|
|
107
|
+
taskUsage = {
|
|
108
|
+
input_tokens: usage?.input_tokens ?? 0,
|
|
109
|
+
output_tokens: usage?.output_tokens ?? 0,
|
|
110
|
+
cache_read_tokens: usage?.cache_read_input_tokens ?? 0,
|
|
111
|
+
cache_creation_tokens: usage?.cache_creation_input_tokens ?? 0,
|
|
112
|
+
cost_usd: msg.total_cost_usd ?? 0,
|
|
113
|
+
duration_ms: msg.duration_ms ?? 0,
|
|
114
|
+
duration_api_ms: msg.duration_api_ms ?? 0,
|
|
115
|
+
num_turns: msg.num_turns ?? 0,
|
|
116
|
+
model,
|
|
117
|
+
};
|
|
118
|
+
if (message.subtype === "success") {
|
|
119
|
+
resultText = message.result;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
throw new Error(`Executor failed: ${message.errors.join(", ")}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
clearTimeout(timeout);
|
|
129
|
+
}
|
|
130
|
+
return { resultText, usage: taskUsage };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=ExecutorService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExecutorService.js","sourceRoot":"","sources":["../../src/services/ExecutorService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Issue, Reference, Finding } from "../types/review.js";
|
|
2
|
+
export type { Issue, Reference };
|
|
3
|
+
/**
|
|
4
|
+
* Parse executor output into a validated array of issues.
|
|
5
|
+
*
|
|
6
|
+
* Supports both the new Issue format (with `references` array) and the
|
|
7
|
+
* legacy Finding format (with `file` at top level). Legacy findings are
|
|
8
|
+
* automatically converted to Issues with a single Reference.
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseIssues(output: string): Issue[];
|
|
11
|
+
/**
|
|
12
|
+
* Parse executor output into validated findings (legacy format).
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Use parseIssues instead. This is kept for backwards compatibility
|
|
15
|
+
* with the testing system which still uses the Finding type.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseFindings(output: string): Finding[];
|
|
18
|
+
//# sourceMappingURL=FindingsParserService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FindingsParserService.d.ts","sourceRoot":"","sources":["../../src/services/FindingsParserService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAmB,MAAM,oBAAoB,CAAC;AAErF,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAmCjC;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,CAsEnD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CASvD"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const VALID_SEVERITIES = new Set([
|
|
2
|
+
"critical",
|
|
3
|
+
"warning",
|
|
4
|
+
"info",
|
|
5
|
+
]);
|
|
6
|
+
function parseReference(raw) {
|
|
7
|
+
return {
|
|
8
|
+
file: String(raw.file ?? ""),
|
|
9
|
+
symbol: typeof raw.symbol === "string" ? raw.symbol : null,
|
|
10
|
+
line: typeof raw.line === "number" ? raw.line : null,
|
|
11
|
+
code: typeof raw.code === "string" ? raw.code : null,
|
|
12
|
+
suggestedCode: typeof raw.suggestedCode === "string" ? raw.suggestedCode : null,
|
|
13
|
+
note: typeof raw.note === "string" ? raw.note : null,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function legacyFindingToIssue(record) {
|
|
17
|
+
return {
|
|
18
|
+
severity: String(record.severity ?? "info"),
|
|
19
|
+
description: String(record.description ?? ""),
|
|
20
|
+
suggestion: typeof record.suggestion === "string" ? record.suggestion : null,
|
|
21
|
+
references: [{
|
|
22
|
+
file: String(record.file ?? ""),
|
|
23
|
+
symbol: null,
|
|
24
|
+
line: typeof record.line === "number" ? record.line : null,
|
|
25
|
+
code: null,
|
|
26
|
+
suggestedCode: null,
|
|
27
|
+
note: null,
|
|
28
|
+
}],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse executor output into a validated array of issues.
|
|
33
|
+
*
|
|
34
|
+
* Supports both the new Issue format (with `references` array) and the
|
|
35
|
+
* legacy Finding format (with `file` at top level). Legacy findings are
|
|
36
|
+
* automatically converted to Issues with a single Reference.
|
|
37
|
+
*/
|
|
38
|
+
export function parseIssues(output) {
|
|
39
|
+
// Try to extract JSON array from the output
|
|
40
|
+
let jsonText = output.trim();
|
|
41
|
+
// Strip markdown code fences if present
|
|
42
|
+
const fencedMatch = jsonText.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
|
|
43
|
+
if (fencedMatch) {
|
|
44
|
+
jsonText = fencedMatch[1].trim();
|
|
45
|
+
}
|
|
46
|
+
// Find the JSON array boundaries
|
|
47
|
+
const startIdx = jsonText.indexOf("[");
|
|
48
|
+
const endIdx = jsonText.lastIndexOf("]");
|
|
49
|
+
if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) {
|
|
50
|
+
console.error(`[deskcheck] Warning: executor output did not contain a JSON array. Output: ${output.slice(0, 200)}`);
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
jsonText = jsonText.slice(startIdx, endIdx + 1);
|
|
54
|
+
let parsed;
|
|
55
|
+
try {
|
|
56
|
+
parsed = JSON.parse(jsonText);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(`[deskcheck] Warning: failed to parse executor JSON output: ${error instanceof Error ? error.message : String(error)}. Output: ${jsonText.slice(0, 200)}`);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
if (!Array.isArray(parsed)) {
|
|
63
|
+
console.error(`[deskcheck] Warning: executor output parsed but was not an array. Type: ${typeof parsed}`);
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
// Validate and normalize each item
|
|
67
|
+
const issues = [];
|
|
68
|
+
for (const item of parsed) {
|
|
69
|
+
if (typeof item !== "object" || item === null) {
|
|
70
|
+
console.error(`[deskcheck] Warning: skipping invalid item (not an object): ${JSON.stringify(item).slice(0, 100)}`);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const record = item;
|
|
74
|
+
const severity = String(record.severity ?? "info");
|
|
75
|
+
if (!VALID_SEVERITIES.has(severity)) {
|
|
76
|
+
console.error(`[deskcheck] Warning: skipping item with invalid severity "${severity}"`);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
// New Issue format: has `references` array
|
|
80
|
+
if (Array.isArray(record.references)) {
|
|
81
|
+
const references = [];
|
|
82
|
+
for (const ref of record.references) {
|
|
83
|
+
if (typeof ref === "object" && ref !== null) {
|
|
84
|
+
references.push(parseReference(ref));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (references.length === 0)
|
|
88
|
+
continue;
|
|
89
|
+
issues.push({
|
|
90
|
+
severity: severity,
|
|
91
|
+
description: String(record.description ?? ""),
|
|
92
|
+
suggestion: typeof record.suggestion === "string" ? record.suggestion : null,
|
|
93
|
+
references,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Legacy Finding format: has `file` at top level
|
|
98
|
+
issues.push(legacyFindingToIssue(record));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return issues;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Parse executor output into validated findings (legacy format).
|
|
105
|
+
*
|
|
106
|
+
* @deprecated Use parseIssues instead. This is kept for backwards compatibility
|
|
107
|
+
* with the testing system which still uses the Finding type.
|
|
108
|
+
*/
|
|
109
|
+
export function parseFindings(output) {
|
|
110
|
+
const issues = parseIssues(output);
|
|
111
|
+
return issues.map((issue) => ({
|
|
112
|
+
severity: issue.severity,
|
|
113
|
+
file: issue.references[0]?.file ?? "",
|
|
114
|
+
line: issue.references[0]?.line ?? null,
|
|
115
|
+
description: issue.description,
|
|
116
|
+
suggestion: issue.suggestion,
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=FindingsParserService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FindingsParserService.js","sourceRoot":"","sources":["../../src/services/FindingsParserService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facade for criteria discovery and file matching.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports functions from module-parser and glob-matcher so consumers
|
|
5
|
+
* can import from a single location. The underlying implementations stay
|
|
6
|
+
* in their current files for now.
|
|
7
|
+
*/
|
|
8
|
+
export { discoverModules as discoverCriteria, filterModules as filterCriteria, parseModule as parseCriterion, } from "./module-parser.js";
|
|
9
|
+
export { findMatchingModules as matchFiles, fileMatchesGlobs, } from "./glob-matcher.js";
|
|
10
|
+
//# sourceMappingURL=CriteriaService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CriteriaService.d.ts","sourceRoot":"","sources":["../../../src/services/criteria/CriteriaService.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,eAAe,IAAI,gBAAgB,EACnC,aAAa,IAAI,cAAc,EAC/B,WAAW,IAAI,cAAc,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,mBAAmB,IAAI,UAAU,EACjC,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facade for criteria discovery and file matching.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports functions from module-parser and glob-matcher so consumers
|
|
5
|
+
* can import from a single location. The underlying implementations stay
|
|
6
|
+
* in their current files for now.
|
|
7
|
+
*/
|
|
8
|
+
export { discoverModules as discoverCriteria, filterModules as filterCriteria, parseModule as parseCriterion, } from "./module-parser.js";
|
|
9
|
+
export { findMatchingModules as matchFiles, fileMatchesGlobs, } from "./glob-matcher.js";
|
|
10
|
+
//# sourceMappingURL=CriteriaService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CriteriaService.js","sourceRoot":"","sources":["../../../src/services/criteria/CriteriaService.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,eAAe,IAAI,gBAAgB,EACnC,aAAa,IAAI,cAAc,EAC/B,WAAW,IAAI,cAAc,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,mBAAmB,IAAI,UAAU,EACjC,gBAAgB,GACjB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob-matcher.d.ts","sourceRoot":"","sources":["../../../src/services/criteria/glob-matcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,qEAAqE;IACrE,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAyB3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,YAAY,EAAE,GACtB,WAAW,EAAE,CAcf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob-matcher.js","sourceRoot":"","sources":["../../../src/services/criteria/glob-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAWtC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,KAAe;IAChE,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACrD,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC7B,CAAC;IAEF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,gBAAgB,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACvD,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC7B,CAAC;IAEF,OAAO,CAAC,gBAAgB,CAAC;AAC3B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,YAAsB,EACtB,OAAuB;IAEvB,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAChD,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CACrC,CAAC;QAEF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReviewModule } from "
|
|
1
|
+
import type { ReviewModule } from "../../types/criteria.js";
|
|
2
2
|
/**
|
|
3
3
|
* Parse a single criterion markdown file into a ReviewModule object.
|
|
4
4
|
*
|
|
@@ -23,4 +23,16 @@ export declare function parseModule(filePath: string, basePath: string): ReviewM
|
|
|
23
23
|
* @throws {Error} If the directory does not exist or any criterion file has invalid frontmatter.
|
|
24
24
|
*/
|
|
25
25
|
export declare function discoverModules(modulesDir: string): ReviewModule[];
|
|
26
|
+
/**
|
|
27
|
+
* Filter modules by criteria name patterns.
|
|
28
|
+
*
|
|
29
|
+
* Each pattern is matched against the module ID. A match occurs if the
|
|
30
|
+
* pattern equals the full ID or the final segment (filename without path).
|
|
31
|
+
* For example, "dto-enforcement" matches "architecture/dto-enforcement".
|
|
32
|
+
*
|
|
33
|
+
* @param modules - All discovered modules.
|
|
34
|
+
* @param patterns - Criteria name patterns to include (e.g., ["dto-enforcement", "backend/controller-conventions"]).
|
|
35
|
+
* @returns Filtered modules. Throws if any pattern matched nothing.
|
|
36
|
+
*/
|
|
37
|
+
export declare function filterModules(modules: ReviewModule[], patterns: string[]): ReviewModule[];
|
|
26
38
|
//# sourceMappingURL=module-parser.d.ts.map
|