@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
|
@@ -24,7 +24,7 @@ const LOCK_MAX_WAIT_MS = 10_000;
|
|
|
24
24
|
/** Spin delay between lock checks (milliseconds). */
|
|
25
25
|
const LOCK_SPIN_MS = 50;
|
|
26
26
|
// =============================================================================
|
|
27
|
-
//
|
|
27
|
+
// ReviewStorageService
|
|
28
28
|
// =============================================================================
|
|
29
29
|
/**
|
|
30
30
|
* Manages the two-file storage format (plan.json + results.json) for deskcheck runs.
|
|
@@ -33,13 +33,13 @@ const LOCK_SPIN_MS = 50;
|
|
|
33
33
|
* directory. The plan file tracks tasks and coverage; the results file tracks
|
|
34
34
|
* findings and aggregations.
|
|
35
35
|
*/
|
|
36
|
-
export class
|
|
36
|
+
export class ReviewStorageService {
|
|
37
37
|
storageDir;
|
|
38
38
|
/** Tracks active lock file paths so they can be cleaned up on process exit. */
|
|
39
39
|
static activeLocks = new Set();
|
|
40
40
|
static {
|
|
41
41
|
const cleanup = () => {
|
|
42
|
-
for (const lockPath of
|
|
42
|
+
for (const lockPath of ReviewStorageService.activeLocks) {
|
|
43
43
|
try {
|
|
44
44
|
fs.unlinkSync(lockPath);
|
|
45
45
|
}
|
|
@@ -105,12 +105,12 @@ export class ReviewStorage {
|
|
|
105
105
|
throw err; // Unexpected error
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
-
|
|
108
|
+
ReviewStorageService.activeLocks.add(lockPath);
|
|
109
109
|
try {
|
|
110
110
|
return fn();
|
|
111
111
|
}
|
|
112
112
|
finally {
|
|
113
|
-
|
|
113
|
+
ReviewStorageService.activeLocks.delete(lockPath);
|
|
114
114
|
try {
|
|
115
115
|
fs.unlinkSync(lockPath);
|
|
116
116
|
}
|
|
@@ -311,7 +311,7 @@ export class ReviewStorage {
|
|
|
311
311
|
* results.json, and recomputes all aggregations (by_file, by_module,
|
|
312
312
|
* summary, completion).
|
|
313
313
|
*/
|
|
314
|
-
completeTask(planId, taskId,
|
|
314
|
+
completeTask(planId, taskId, issues, usage) {
|
|
315
315
|
this.withLock(planId, () => {
|
|
316
316
|
const now = new Date().toISOString();
|
|
317
317
|
// Update plan.json task status
|
|
@@ -335,7 +335,7 @@ export class ReviewStorage {
|
|
|
335
335
|
review_id: task.review_id,
|
|
336
336
|
files: task.files,
|
|
337
337
|
completed_at: now,
|
|
338
|
-
|
|
338
|
+
issues,
|
|
339
339
|
usage: usage ?? null,
|
|
340
340
|
};
|
|
341
341
|
const results = this.loadOrCreateResults(planId);
|
|
@@ -377,7 +377,7 @@ export class ReviewStorage {
|
|
|
377
377
|
review_id: task.review_id,
|
|
378
378
|
files: task.files,
|
|
379
379
|
completed_at: now,
|
|
380
|
-
|
|
380
|
+
issues: [],
|
|
381
381
|
usage: usage ?? null,
|
|
382
382
|
};
|
|
383
383
|
results.task_results[taskId] = taskResult;
|
|
@@ -502,32 +502,47 @@ export class ReviewStorage {
|
|
|
502
502
|
in_progress: tasks.filter((t) => t.status === "in_progress").length,
|
|
503
503
|
errored: tasks.filter((t) => t.status === "error").length,
|
|
504
504
|
};
|
|
505
|
-
// ----
|
|
505
|
+
// ---- Stamp issue_id on all issues ----
|
|
506
|
+
for (const taskResult of Object.values(results.task_results)) {
|
|
507
|
+
for (let i = 0; i < taskResult.issues.length; i++) {
|
|
508
|
+
taskResult.issues[i].issue_id = `${taskResult.task_id}:${i}`;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
// ---- Summary (aggregate issue counts) ----
|
|
506
512
|
const summary = { total: 0, critical: 0, warning: 0, info: 0 };
|
|
507
513
|
for (const taskResult of Object.values(results.task_results)) {
|
|
508
|
-
for (const
|
|
514
|
+
for (const issue of taskResult.issues) {
|
|
509
515
|
summary.total++;
|
|
510
|
-
summary[
|
|
516
|
+
summary[issue.severity]++;
|
|
511
517
|
}
|
|
512
518
|
}
|
|
513
519
|
results.summary = summary;
|
|
514
|
-
// ---- by_file (group
|
|
520
|
+
// ---- by_file (group issues by reference file paths) ----
|
|
521
|
+
// An issue can appear under multiple files if it has multiple references.
|
|
515
522
|
const byFile = {};
|
|
516
523
|
for (const taskResult of Object.values(results.task_results)) {
|
|
517
|
-
for (const
|
|
518
|
-
const
|
|
519
|
-
...
|
|
524
|
+
for (const issue of taskResult.issues) {
|
|
525
|
+
const fileIssue = {
|
|
526
|
+
...issue,
|
|
527
|
+
issue_id: issue.issue_id,
|
|
520
528
|
review_id: taskResult.review_id,
|
|
521
529
|
task_id: taskResult.task_id,
|
|
522
530
|
};
|
|
523
|
-
|
|
524
|
-
|
|
531
|
+
// Index under each referenced file path
|
|
532
|
+
const seenFiles = new Set();
|
|
533
|
+
for (const ref of issue.references) {
|
|
534
|
+
if (ref.file && !seenFiles.has(ref.file)) {
|
|
535
|
+
seenFiles.add(ref.file);
|
|
536
|
+
if (!byFile[ref.file]) {
|
|
537
|
+
byFile[ref.file] = [];
|
|
538
|
+
}
|
|
539
|
+
byFile[ref.file].push(fileIssue);
|
|
540
|
+
}
|
|
525
541
|
}
|
|
526
|
-
byFile[finding.file].push(fileFinding);
|
|
527
542
|
}
|
|
528
543
|
}
|
|
529
544
|
results.by_file = byFile;
|
|
530
|
-
// ---- by_module (group
|
|
545
|
+
// ---- by_module (group issues by criterion) ----
|
|
531
546
|
const byModule = {};
|
|
532
547
|
for (const taskResult of Object.values(results.task_results)) {
|
|
533
548
|
const reviewId = taskResult.review_id;
|
|
@@ -541,15 +556,15 @@ export class ReviewStorage {
|
|
|
541
556
|
task_count: moduleSummary?.task_count ?? 0,
|
|
542
557
|
completed: 0,
|
|
543
558
|
counts: { critical: 0, warning: 0, info: 0, total: 0 },
|
|
544
|
-
|
|
559
|
+
issues: [],
|
|
545
560
|
};
|
|
546
561
|
}
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
for (const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
562
|
+
const moduleIssues = byModule[reviewId];
|
|
563
|
+
moduleIssues.completed++;
|
|
564
|
+
for (const issue of taskResult.issues) {
|
|
565
|
+
moduleIssues.counts.total++;
|
|
566
|
+
moduleIssues.counts[issue.severity]++;
|
|
567
|
+
moduleIssues.issues.push(issue);
|
|
553
568
|
}
|
|
554
569
|
}
|
|
555
570
|
results.by_module = byModule;
|
|
@@ -587,4 +602,4 @@ export class ReviewStorage {
|
|
|
587
602
|
results.total_usage = totalUsage;
|
|
588
603
|
}
|
|
589
604
|
}
|
|
590
|
-
//# sourceMappingURL=
|
|
605
|
+
//# sourceMappingURL=ReviewStorageService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReviewStorageService.js","sourceRoot":"","sources":["../../../src/services/review/ReviewStorageService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAgB7B,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF,gFAAgF;AAChF,SAAS,eAAe,CAAC,IAAU;IACjC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/D,OAAO,CACL,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;QAC5E,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,CAChF,CAAC;AACJ,CAAC;AAED,kGAAkG;AAClG,SAAS,eAAe,CAAC,QAAgB;IACvC,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,qCAAqC;AACrC,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,yEAAyE;AACzE,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEzC,2DAA2D;AAC3D,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,qDAAqD;AACrD,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IACd,UAAU,CAAS;IAEpC,+EAA+E;IACvE,MAAM,CAAC,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/C;QACE,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,KAAK,MAAM,QAAQ,IAAI,oBAAoB,CAAC,WAAW,EAAE,CAAC;gBACxD,IAAI,CAAC;oBAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YACzD,CAAC;QACH,CAAC,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC5B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,YAAY,UAAkB;QAC5B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;;;;;;;OAQG;IACK,QAAQ,CAAI,MAAc,EAAE,EAAW;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,6CAA6C;QAC7C,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,EAAE,CAAC,aAAa,CACd,QAAQ,EACR,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,EAC3D,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;gBACF,MAAM,CAAC,gBAAgB;YACzB,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,uDAAuD;gBACvD,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACrD,iDAAiD;oBACjD,IAAI,CAAC;wBACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;wBAChE,IAAI,OAAO,QAAQ,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,GAAG,gBAAgB,EAAE,CAAC;4BACjG,sCAAsC;4BACtC,IAAI,CAAC;gCAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;4BAAC,CAAC;4BAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;4BACvD,SAAS;wBACX,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,gDAAgD;wBAChD,IAAI,CAAC;4BAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;wBAAC,CAAC;wBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;wBACvD,SAAS;oBACX,CAAC;oBAED,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,gBAAgB,EAAE,CAAC;wBAC1C,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,gBAAgB,QAAQ,EAAE,CAAC,CAAC;oBACrF,CAAC;oBAED,0DAA0D;oBAC1D,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;oBACtD,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;oBACvC,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,CAAC,CAAC,mBAAmB;YAChC,CAAC;QACH,CAAC;QAED,oBAAoB,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC;YACH,OAAO,EAAE,EAAE,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,oBAAoB,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,CAAC;gBAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,yCAAyC;IACjC,OAAO,CAAC,MAAc;QAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;;;;OAKG;IACH,UAAU,CAAC,IAAY,EAAE,MAAoB;QAC3C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAEnD,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,MAAM,IAAI,GAAe;YACvB,OAAO,EAAE,MAAM;YACf,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,UAAU;YAClB,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE;YAC7B,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,IAAI;YAChB,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,EAAE;YACjB,eAAe,EAAE,EAAE;YACnB,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,EAAE;SACZ,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8CAA8C;IAC9C,OAAO,CAAC,MAAc;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,eAAe;QACb,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,OAAO;aACrB,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,WAAW,EAAE;YACnB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CACrE;aACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;aAC1B,IAAI,EAAE,CAAC;QAEV,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,0CAA0C;IAC1C,SAAS;QAMP,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,MAAM,GAKP,EAAE,CAAC;QAER,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YAEnC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAC5B,IAAI,CAAC,UAAU,EACf,KAAK,CAAC,IAAI,EACV,WAAW,CACZ,CAAC;YACF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;gBAAE,SAAS;YAE3C,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;YAE3C,MAAM,CAAC,IAAI,CAAC;gBACV,MAAM,EAAE,IAAI,CAAC,OAAO;gBACpB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,UAAU;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACjE,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,MAAc;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAE7C,2BAA2B;YAC3B,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxD,aAAa,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CACzD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,aAAa,CAAC,SAAS,CACrD,CAAC,MAAM,CAAC;YACX,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;;;;;OAMG;IACH,OAAO,CACL,MAAc,EACd,IAWC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAElC,8DAA8D;YAC9D,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAC1D,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,CAC5B,CAAC,MAAM,CAAC;YACT,MAAM,MAAM,GAAG,GAAG,MAAM,IAAI,QAAQ,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,CAAC;YAE1D,MAAM,OAAO,GAAe;gBAC1B,OAAO,EAAE,MAAM;gBACf,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,SAAS;gBACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;gBAClB,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;gBAC9B,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;aACb,CAAC;YAEF,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC7B,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,SAAS,CACP,MAAc,EACd,MAAc,EACd,OAKC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,wBAAwB,MAAM,GAAG,CACjD,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC3C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;YACxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YAC/B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC;YACrC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAE7B,wCAAwC;YACxC,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;gBAClC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;YAC5B,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,MAAc;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrD,MAAM,OAAO,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC1D,OAAO,OAAO,GAAG,kBAAkB,CAAC;YACtC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,oBAAoB;IACpB,8EAA8E;IAE9E;;;;;;OAMG;IACH,YAAY,CACV,MAAc,EACd,MAAc,EACd,MAAe,EACf,KAAwB;QAExB,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;YACzB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAErC,+BAA+B;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,wBAAwB,MAAM,GAAG,CACjD,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;YACzB,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;YAExB,wEAAwE;YACxE,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CACvD,CAAC;YAEF,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;gBACzB,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;YAC1B,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAE7B,kCAAkC;YAClC,MAAM,UAAU,GAAe;gBAC7B,OAAO,EAAE,MAAM;gBACf,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,YAAY,EAAE,GAAG;gBACjB,MAAM;gBACN,KAAK,EAAE,KAAK,IAAI,IAAI;aACrB,CAAC;YAEF,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;YACjD,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;YAE1C,0CAA0C;YAC1C,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAE1C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAc,EAAE,MAAc,EAAE,YAAoB,EAAE,KAAwB;QACtF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;YACzB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,wBAAwB,MAAM,GAAG,CAAC,CAAC;YACpE,CAAC;YAED,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;YAExB,oDAAoD;YACpD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CACvD,CAAC;YAEF,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;gBACzB,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC;YAC1B,CAAC;YAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAE7B,kFAAkF;YAClF,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAEjD,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,UAAU,GAAe;oBAC7B,OAAO,EAAE,MAAM;oBACf,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,YAAY,EAAE,GAAG;oBACjB,MAAM,EAAE,EAAE;oBACV,KAAK,EAAE,KAAK,IAAI,IAAI;iBACrB,CAAC;gBACF,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;YAC5C,CAAC;YAED,gEAAgE;YAChE,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,iDAAiD;IACjD,UAAU,CAAC,MAAc;QACvB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,qDAAqD;YACrD,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAC1C,CAAC;IAED,8EAA8E;IAC9E,WAAW;IACX,8EAA8E;IAE9E,4DAA4D;IAC5D,eAAe,CACb,MAAc,EACd,OAAiB,EACjB,SAAmB;QAEnB,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;YAC7B,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;YACjC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gDAAgD;IAChD,UAAU,CACR,MAAc,EACd,OAAsC;QAEtC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAEtE,QAAQ,CAAC,MAAc;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACzD,CAAC;IAEO,WAAW,CAAC,MAAc;QAChC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5D,CAAC;IAEO,SAAS,CAAC,MAAc,EAAE,IAAgB;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC;QAC5B,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5D,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAEO,YAAY,CAAC,MAAc,EAAE,OAAsB;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC;QAC5B,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/D,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC;IAEO,kBAAkB,CAAC,MAAc;QACvC,OAAO;YACL,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,SAAS;YACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,UAAU,EAAE;gBACV,KAAK,EAAE,CAAC;gBACR,SAAS,EAAE,CAAC;gBACZ,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;aACX;YACD,OAAO,EAAE;gBACP,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,CAAC;gBACV,IAAI,EAAE,CAAC;aACR;YACD,YAAY,EAAE,EAAE;YAChB,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,EAAE;YACb,WAAW,EAAE;gBACX,YAAY,EAAE,CAAC;gBACf,aAAa,EAAE,CAAC;gBAChB,iBAAiB,EAAE,CAAC;gBACpB,qBAAqB,EAAE,CAAC;gBACxB,QAAQ,EAAE,CAAC;gBACX,WAAW,EAAE,CAAC;gBACd,eAAe,EAAE,CAAC;gBAClB,SAAS,EAAE,CAAC;aACb;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,MAAc;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE7C,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;QAC1C,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACK,qBAAqB,CAC3B,OAAsB,EACtB,IAAgB;QAEhB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC;QAEzB,uBAAuB;QACvB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,CAAC,UAAU,GAAG;YACnB,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,MAAM;YAC9D,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;YAC3D,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,MAAM;YACnE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM;SAC1D,CAAC;QAEF,yCAAyC;QACzC,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAClD,UAAU,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,QAAQ,GAAG,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;YAChE,CAAC;QACH,CAAC;QAED,6CAA6C;QAC7C,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAE/D,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7D,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;gBACtC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;QAE1B,2DAA2D;QAC3D,0EAA0E;QAC1E,MAAM,MAAM,GAAgC,EAAE,CAAC;QAE/C,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7D,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;gBACtC,MAAM,SAAS,GAAc;oBAC3B,GAAG,KAAK;oBACR,QAAQ,EAAE,KAAK,CAAC,QAAS;oBACzB,SAAS,EAAE,UAAU,CAAC,SAAS;oBAC/B,OAAO,EAAE,UAAU,CAAC,OAAO;iBAC5B,CAAC;gBAEF,wCAAwC;gBACxC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;gBACpC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBACnC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;wBACzC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;wBACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;4BACtB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;wBACxB,CAAC;wBACD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC;QAEzB,kDAAkD;QAClD,MAAM,QAAQ,GAAiC,EAAE,CAAC;QAElD,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7D,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC;YAEtC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACxB,wCAAwC;gBACxC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC7C,QAAQ,CAAC,QAAQ,CAAC,GAAG;oBACnB,SAAS,EAAE,QAAQ;oBACnB,WAAW,EAAE,aAAa,EAAE,WAAW,IAAI,EAAE;oBAC7C,QAAQ,EAAE,aAAa,EAAE,QAAQ,IAAI,QAAQ;oBAC7C,UAAU,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC;oBAC1C,SAAS,EAAE,CAAC;oBACZ,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;oBACtD,MAAM,EAAE,EAAE;iBACX,CAAC;YACJ,CAAC;YAED,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACxC,YAAY,CAAC,SAAS,EAAE,CAAC;YAEzB,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;gBACtC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC5B,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE7B,mBAAmB;QACnB,0EAA0E;QAC1E,kDAAkD;QAClD,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;QAChF,OAAO,CAAC,MAAM;YACZ,aAAa,KAAK,OAAO,CAAC,UAAU,CAAC,KAAK;gBACxC,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,SAAS,CAAC;QAEhB,wBAAwB;QACxB,MAAM,UAAU,GAAe;YAC7B,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,CAAC;YAChB,iBAAiB,EAAE,CAAC;YACpB,qBAAqB,EAAE,CAAC;YACxB,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,CAAC;YACd,eAAe,EAAE,CAAC;YAClB,SAAS,EAAE,CAAC;SACb,CAAC;QAEF,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7D,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;gBACrB,UAAU,CAAC,YAAY,IAAI,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC;gBACzD,UAAU,CAAC,aAAa,IAAI,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC;gBAC3D,UAAU,CAAC,iBAAiB,IAAI,UAAU,CAAC,KAAK,CAAC,iBAAiB,CAAC;gBACnE,UAAU,CAAC,qBAAqB,IAAI,UAAU,CAAC,KAAK,CAAC,qBAAqB,CAAC;gBAC3E,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC;gBACjD,UAAU,CAAC,WAAW,IAAI,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC;gBACvD,UAAU,CAAC,eAAe,IAAI,UAAU,CAAC,KAAK,CAAC,eAAe,CAAC;gBAC/D,UAAU,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;YACrD,CAAC;QACH,CAAC;QAED,OAAO,CAAC,WAAW,GAAG,UAAU,CAAC;IACnC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ReviewConfig } from "../../config/types.js";
|
|
2
|
+
import type { ReviewModule } from "../../types/criteria.js";
|
|
3
|
+
import type { Finding, TaskUsage } from "../../types/review.js";
|
|
4
|
+
import type { JudgeResult } from "../../types/testing.js";
|
|
5
|
+
/**
|
|
6
|
+
* Spawns a judge agent to evaluate executor findings against expected results.
|
|
7
|
+
*
|
|
8
|
+
* The judge is a pure reasoning agent (no tools, single turn) that compares
|
|
9
|
+
* findings to expectations and produces structured verdicts. Model is
|
|
10
|
+
* configurable via config.agents.judge.model (default: opus).
|
|
11
|
+
*/
|
|
12
|
+
export declare class JudgeService {
|
|
13
|
+
private readonly executorService;
|
|
14
|
+
private readonly judgeModel;
|
|
15
|
+
constructor(config: ReviewConfig, projectRoot: string);
|
|
16
|
+
/**
|
|
17
|
+
* Evaluate executor findings against expected results for a criterion.
|
|
18
|
+
*
|
|
19
|
+
* @param criterion - The criterion that was tested.
|
|
20
|
+
* @param expectedContent - Content of expected.md describing what should be found.
|
|
21
|
+
* @param findings - Findings produced by the executor agent.
|
|
22
|
+
* @param fixtureContent - Content of the fixture file that was reviewed.
|
|
23
|
+
* @returns Judge result with finding and expectation reviews, plus usage data.
|
|
24
|
+
*/
|
|
25
|
+
evaluate(criterion: ReviewModule, expectedContent: string, findings: Finding[], fixtureContent: string): Promise<{
|
|
26
|
+
result: JudgeResult;
|
|
27
|
+
usage: TaskUsage | null;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=JudgeService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JudgeService.d.ts","sourceRoot":"","sources":["../../../src/services/testing/JudgeService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1D;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;gBAE5B,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM;IAKrD;;;;;;;;OAQG;IACG,QAAQ,CACZ,SAAS,EAAE,YAAY,EACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,OAAO,EAAE,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC;CAkB7D"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { ExecutorService } from "../ExecutorService.js";
|
|
2
|
+
import { buildJudgePrompt } from "../../prompts/JudgePrompt.js";
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// JudgeService
|
|
5
|
+
// =============================================================================
|
|
6
|
+
/**
|
|
7
|
+
* Spawns a judge agent to evaluate executor findings against expected results.
|
|
8
|
+
*
|
|
9
|
+
* The judge is a pure reasoning agent (no tools, single turn) that compares
|
|
10
|
+
* findings to expectations and produces structured verdicts. Model is
|
|
11
|
+
* configurable via config.agents.judge.model (default: opus).
|
|
12
|
+
*/
|
|
13
|
+
export class JudgeService {
|
|
14
|
+
executorService;
|
|
15
|
+
judgeModel;
|
|
16
|
+
constructor(config, projectRoot) {
|
|
17
|
+
this.executorService = new ExecutorService(config, projectRoot);
|
|
18
|
+
this.judgeModel = config.agents.judge.model ?? "opus";
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Evaluate executor findings against expected results for a criterion.
|
|
22
|
+
*
|
|
23
|
+
* @param criterion - The criterion that was tested.
|
|
24
|
+
* @param expectedContent - Content of expected.md describing what should be found.
|
|
25
|
+
* @param findings - Findings produced by the executor agent.
|
|
26
|
+
* @param fixtureContent - Content of the fixture file that was reviewed.
|
|
27
|
+
* @returns Judge result with finding and expectation reviews, plus usage data.
|
|
28
|
+
*/
|
|
29
|
+
async evaluate(criterion, expectedContent, findings, fixtureContent) {
|
|
30
|
+
const prompt = buildJudgePrompt(criterion.prompt, expectedContent, findings, fixtureContent);
|
|
31
|
+
// Judge uses configured model (default opus), no tools, single turn
|
|
32
|
+
const executorResult = await this.executorService.execute(prompt, this.judgeModel, {
|
|
33
|
+
tools: [],
|
|
34
|
+
maxTurns: 1,
|
|
35
|
+
});
|
|
36
|
+
const result = parseJudgeOutput(executorResult.resultText);
|
|
37
|
+
return { result, usage: executorResult.usage };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// =============================================================================
|
|
41
|
+
// Parsing
|
|
42
|
+
// =============================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Parse the judge agent's output into a typed JudgeResult.
|
|
45
|
+
*
|
|
46
|
+
* Looks for a JSON object (not array) in the output, strips markdown fences,
|
|
47
|
+
* and validates the structure. Returns empty results rather than crashing on
|
|
48
|
+
* malformed output.
|
|
49
|
+
*/
|
|
50
|
+
function parseJudgeOutput(output) {
|
|
51
|
+
let jsonText = output.trim();
|
|
52
|
+
// Strip markdown code fences if present
|
|
53
|
+
const fencedMatch = jsonText.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
|
|
54
|
+
if (fencedMatch) {
|
|
55
|
+
jsonText = fencedMatch[1].trim();
|
|
56
|
+
}
|
|
57
|
+
// Find the JSON object boundaries
|
|
58
|
+
const startIdx = jsonText.indexOf("{");
|
|
59
|
+
const endIdx = jsonText.lastIndexOf("}");
|
|
60
|
+
if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) {
|
|
61
|
+
console.error(`[deskcheck] Warning: judge output did not contain a JSON object. Output: ${output.slice(0, 200)}`);
|
|
62
|
+
return emptyJudgeResult();
|
|
63
|
+
}
|
|
64
|
+
jsonText = jsonText.slice(startIdx, endIdx + 1);
|
|
65
|
+
let parsed;
|
|
66
|
+
try {
|
|
67
|
+
parsed = JSON.parse(jsonText);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error(`[deskcheck] Warning: failed to parse judge JSON output: ${error instanceof Error ? error.message : String(error)}. Output: ${jsonText.slice(0, 200)}`);
|
|
71
|
+
return emptyJudgeResult();
|
|
72
|
+
}
|
|
73
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
74
|
+
console.error(`[deskcheck] Warning: judge output parsed but was not an object. Type: ${typeof parsed}`);
|
|
75
|
+
return emptyJudgeResult();
|
|
76
|
+
}
|
|
77
|
+
const record = parsed;
|
|
78
|
+
// Validate structure
|
|
79
|
+
if (!Array.isArray(record.findings_review) || !Array.isArray(record.expectations_review)) {
|
|
80
|
+
console.error(`[deskcheck] Warning: judge output missing findings_review or expectations_review arrays.`);
|
|
81
|
+
return emptyJudgeResult();
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
findings_review: record.findings_review,
|
|
85
|
+
expectations_review: record.expectations_review,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Return an empty judge result for error cases. */
|
|
89
|
+
function emptyJudgeResult() {
|
|
90
|
+
return {
|
|
91
|
+
findings_review: [],
|
|
92
|
+
expectations_review: [],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=JudgeService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JudgeService.js","sourceRoot":"","sources":["../../../src/services/testing/JudgeService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAOhE,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACN,eAAe,CAAkB;IACjC,UAAU,CAAa;IAExC,YAAY,MAAoB,EAAE,WAAmB;QACnD,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAChE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC;IACxD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,QAAQ,CACZ,SAAuB,EACvB,eAAuB,EACvB,QAAmB,EACnB,cAAsB;QAEtB,MAAM,MAAM,GAAG,gBAAgB,CAC7B,SAAS,CAAC,MAAM,EAChB,eAAe,EACf,QAAQ,EACR,cAAc,CACf,CAAC;QAEF,oEAAoE;QACpE,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE;YACjF,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,gBAAgB,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAE3D,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,CAAC;IACjD,CAAC;CACF;AAED,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,MAAc;IACtC,IAAI,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAE7B,wCAAwC;IACxC,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC5E,IAAI,WAAW,EAAE,CAAC;QAChB,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IAED,kCAAkC;IAClC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC3D,OAAO,CAAC,KAAK,CACX,4EAA4E,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACnG,CAAC;QACF,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAED,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;IAEhD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,2DAA2D,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CACvJ,CAAC;QACF,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,CAAC,KAAK,CACX,yEAAyE,OAAO,MAAM,EAAE,CACzF,CAAC;QACF,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,MAAM,GAAG,MAAiC,CAAC;IAEjD,qBAAqB;IACrB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzF,OAAO,CAAC,KAAK,CACX,0FAA0F,CAC3F,CAAC;QACF,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO;QACL,eAAe,EAAE,MAAM,CAAC,eAAiD;QACzE,mBAAmB,EAAE,MAAM,CAAC,mBAAyD;KACtF,CAAC;AACJ,CAAC;AAED,oDAAoD;AACpD,SAAS,gBAAgB;IACvB,OAAO;QACL,eAAe,EAAE,EAAE;QACnB,mBAAmB,EAAE,EAAE;KACxB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TestCase } from "../../types/testing.js";
|
|
2
|
+
/**
|
|
3
|
+
* Discover test cases by scanning the tests directory.
|
|
4
|
+
*
|
|
5
|
+
* Test cases mirror the criteria directory structure:
|
|
6
|
+
* tests/{criterionId}/{testName}/
|
|
7
|
+
* - One fixture file (any extension except .md)
|
|
8
|
+
* - One expected.md describing expected findings
|
|
9
|
+
*
|
|
10
|
+
* @param testsDir - Path to the tests directory.
|
|
11
|
+
* @param criteriaDir - Path to the criteria directory.
|
|
12
|
+
* @param criterionFilter - Optional list of criterion name patterns to include.
|
|
13
|
+
* @returns Sorted array of discovered test cases.
|
|
14
|
+
*/
|
|
15
|
+
export declare function discoverTests(testsDir: string, criteriaDir: string, criterionFilter?: string[]): TestCase[];
|
|
16
|
+
//# sourceMappingURL=TestDiscoveryService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestDiscoveryService.d.ts","sourceRoot":"","sources":["../../../src/services/testing/TestDiscoveryService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,QAAQ,EAAE,CA4DZ"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { discoverCriteria, filterCriteria } from "../criteria/CriteriaService.js";
|
|
4
|
+
/**
|
|
5
|
+
* Discover test cases by scanning the tests directory.
|
|
6
|
+
*
|
|
7
|
+
* Test cases mirror the criteria directory structure:
|
|
8
|
+
* tests/{criterionId}/{testName}/
|
|
9
|
+
* - One fixture file (any extension except .md)
|
|
10
|
+
* - One expected.md describing expected findings
|
|
11
|
+
*
|
|
12
|
+
* @param testsDir - Path to the tests directory.
|
|
13
|
+
* @param criteriaDir - Path to the criteria directory.
|
|
14
|
+
* @param criterionFilter - Optional list of criterion name patterns to include.
|
|
15
|
+
* @returns Sorted array of discovered test cases.
|
|
16
|
+
*/
|
|
17
|
+
export function discoverTests(testsDir, criteriaDir, criterionFilter) {
|
|
18
|
+
const absoluteTestsDir = path.resolve(testsDir);
|
|
19
|
+
const absoluteCriteriaDir = path.resolve(criteriaDir);
|
|
20
|
+
// Discover all criteria, optionally filtered
|
|
21
|
+
let criteria = discoverCriteria(absoluteCriteriaDir);
|
|
22
|
+
if (criterionFilter && criterionFilter.length > 0) {
|
|
23
|
+
criteria = filterCriteria(criteria, criterionFilter);
|
|
24
|
+
}
|
|
25
|
+
const testCases = [];
|
|
26
|
+
for (const criterion of criteria) {
|
|
27
|
+
// Look for matching test directory: testsDir/{criterion.id}/
|
|
28
|
+
const criterionTestDir = path.join(absoluteTestsDir, criterion.id);
|
|
29
|
+
if (!fs.existsSync(criterionTestDir) || !fs.statSync(criterionTestDir).isDirectory()) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
// Each subdirectory is a test case
|
|
33
|
+
const entries = fs.readdirSync(criterionTestDir, { withFileTypes: true });
|
|
34
|
+
const testDirs = entries.filter((entry) => entry.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
|
|
35
|
+
for (const testDir of testDirs) {
|
|
36
|
+
const testPath = path.join(criterionTestDir, testDir.name);
|
|
37
|
+
const testFiles = fs.readdirSync(testPath);
|
|
38
|
+
// Find the fixture file (first non-.md file)
|
|
39
|
+
const fixtureFileName = testFiles
|
|
40
|
+
.filter((f) => !f.endsWith(".md"))
|
|
41
|
+
.sort()[0];
|
|
42
|
+
// Check for expected.md
|
|
43
|
+
const hasExpectedMd = testFiles.includes("expected.md");
|
|
44
|
+
if (!fixtureFileName || !hasExpectedMd) {
|
|
45
|
+
console.error(`[deskcheck] Warning: skipping test "${testDir.name}" for criterion "${criterion.id}": ` +
|
|
46
|
+
`missing ${!fixtureFileName ? "fixture file" : "expected.md"}`);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
testCases.push({
|
|
50
|
+
criterionId: criterion.id,
|
|
51
|
+
name: testDir.name,
|
|
52
|
+
criterionFile: criterion.file,
|
|
53
|
+
fixtureFile: path.join(testPath, fixtureFileName),
|
|
54
|
+
expectedFile: path.join(testPath, "expected.md"),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Sort by criterionId, then by name for deterministic ordering
|
|
59
|
+
return testCases.sort((a, b) => {
|
|
60
|
+
const idCompare = a.criterionId.localeCompare(b.criterionId);
|
|
61
|
+
if (idCompare !== 0)
|
|
62
|
+
return idCompare;
|
|
63
|
+
return a.name.localeCompare(b.name);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=TestDiscoveryService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestDiscoveryService.js","sourceRoot":"","sources":["../../../src/services/testing/TestDiscoveryService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAElF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,WAAmB,EACnB,eAA0B;IAE1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAEtD,6CAA6C;IAC7C,IAAI,QAAQ,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;IACrD,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;QACjC,6DAA6D;QAC7D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;QAEnE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACrF,SAAS;QACX,CAAC;QAED,mCAAmC;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,gBAAgB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAE7G,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YAC3D,MAAM,SAAS,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAE3C,6CAA6C;YAC7C,MAAM,eAAe,GAAG,SAAS;iBAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;iBACjC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAEb,wBAAwB;YACxB,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;YAExD,IAAI,CAAC,eAAe,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvC,OAAO,CAAC,KAAK,CACX,uCAAuC,OAAO,CAAC,IAAI,oBAAoB,SAAS,CAAC,EAAE,KAAK;oBACxF,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,CAC/D,CAAC;gBACF,SAAS;YACX,CAAC;YAED,SAAS,CAAC,IAAI,CAAC;gBACb,WAAW,EAAE,SAAS,CAAC,EAAE;gBACzB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,aAAa,EAAE,SAAS,CAAC,IAAI;gBAC7B,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC;gBACjD,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC;aACjD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7B,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,SAAS,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACtC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ReviewConfig } from "../../config/types.js";
|
|
2
|
+
import type { TestCase, TestCaseResult, TestRun } from "../../types/testing.js";
|
|
3
|
+
/** Options for controlling test run behavior. */
|
|
4
|
+
export interface TestRunOptions {
|
|
5
|
+
/** Called after each test case completes (or errors), for live progress reporting. */
|
|
6
|
+
onTestComplete?: (criterionId: string, testName: string, result: TestCaseResult) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Orchestrates the full test pipeline: executor -> judge -> scorer -> storage.
|
|
10
|
+
*
|
|
11
|
+
* Runs test cases sequentially (no concurrency). For each test case:
|
|
12
|
+
* 1. Execute the criterion against the fixture file
|
|
13
|
+
* 2. Judge the findings against expected results
|
|
14
|
+
* 3. Score the judge's verdicts
|
|
15
|
+
* 4. Persist everything to storage
|
|
16
|
+
*/
|
|
17
|
+
export declare class TestRunnerService {
|
|
18
|
+
private readonly config;
|
|
19
|
+
private readonly projectRoot;
|
|
20
|
+
constructor(config: ReviewConfig, projectRoot: string);
|
|
21
|
+
/**
|
|
22
|
+
* Run all test cases and return the completed test run.
|
|
23
|
+
*
|
|
24
|
+
* @param testCases - Discovered test cases to execute.
|
|
25
|
+
* @param storageDir - Directory where test run results are persisted.
|
|
26
|
+
* @param options - Optional callbacks for progress reporting.
|
|
27
|
+
* @returns The final TestRun with all results.
|
|
28
|
+
*/
|
|
29
|
+
run(testCases: TestCase[], storageDir: string, options?: TestRunOptions): Promise<TestRun>;
|
|
30
|
+
/**
|
|
31
|
+
* Execute a single test case through the full pipeline.
|
|
32
|
+
*/
|
|
33
|
+
private executeTestCase;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=TestRunnerService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestRunnerService.d.ts","sourceRoot":"","sources":["../../../src/services/testing/TestRunnerService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAchF,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,sFAAsF;IACtF,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC1F;AAMD;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM;IAKrD;;;;;;;OAOG;IACG,GAAG,CACP,SAAS,EAAE,QAAQ,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC;IAyDnB;;OAEG;YACW,eAAe;CA6E9B"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { ExecutorService } from "../ExecutorService.js";
|
|
4
|
+
import { buildExecutorPrompt } from "../../prompts/ExecutorPrompt.js";
|
|
5
|
+
import { parseFindings } from "../FindingsParserService.js";
|
|
6
|
+
import { parseCriterion } from "../criteria/CriteriaService.js";
|
|
7
|
+
import { TestStorageService } from "./TestStorageService.js";
|
|
8
|
+
import { JudgeService } from "./JudgeService.js";
|
|
9
|
+
import { calculateScores } from "./TestScorerService.js";
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// TestRunnerService
|
|
12
|
+
// =============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Orchestrates the full test pipeline: executor -> judge -> scorer -> storage.
|
|
15
|
+
*
|
|
16
|
+
* Runs test cases sequentially (no concurrency). For each test case:
|
|
17
|
+
* 1. Execute the criterion against the fixture file
|
|
18
|
+
* 2. Judge the findings against expected results
|
|
19
|
+
* 3. Score the judge's verdicts
|
|
20
|
+
* 4. Persist everything to storage
|
|
21
|
+
*/
|
|
22
|
+
export class TestRunnerService {
|
|
23
|
+
config;
|
|
24
|
+
projectRoot;
|
|
25
|
+
constructor(config, projectRoot) {
|
|
26
|
+
this.config = config;
|
|
27
|
+
this.projectRoot = projectRoot;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Run all test cases and return the completed test run.
|
|
31
|
+
*
|
|
32
|
+
* @param testCases - Discovered test cases to execute.
|
|
33
|
+
* @param storageDir - Directory where test run results are persisted.
|
|
34
|
+
* @param options - Optional callbacks for progress reporting.
|
|
35
|
+
* @returns The final TestRun with all results.
|
|
36
|
+
*/
|
|
37
|
+
async run(testCases, storageDir, options) {
|
|
38
|
+
const storage = new TestStorageService(storageDir);
|
|
39
|
+
const executorService = new ExecutorService(this.config, this.projectRoot);
|
|
40
|
+
const judgeService = new JudgeService(this.config, this.projectRoot);
|
|
41
|
+
// Initialize the run with all tests as "pending"
|
|
42
|
+
const run = storage.createRun(testCases);
|
|
43
|
+
const runId = run.run_id;
|
|
44
|
+
// Track which suites have been started
|
|
45
|
+
const startedSuites = new Set();
|
|
46
|
+
for (const testCase of testCases) {
|
|
47
|
+
// Mark suite as running if not yet started
|
|
48
|
+
if (!startedSuites.has(testCase.criterionId)) {
|
|
49
|
+
storage.updateSuiteStatus(runId, testCase.criterionId, "running");
|
|
50
|
+
startedSuites.add(testCase.criterionId);
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
await this.executeTestCase(testCase, runId, storage, executorService, judgeService);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// Catch unexpected errors and record them
|
|
57
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
58
|
+
storage.updateTestCase(runId, testCase.criterionId, testCase.name, {
|
|
59
|
+
status: "error",
|
|
60
|
+
error: errorMessage,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// Notify caller of test completion (whether success or error)
|
|
64
|
+
if (options?.onTestComplete) {
|
|
65
|
+
const currentRun = storage.getRun(runId);
|
|
66
|
+
const result = currentRun.suites[testCase.criterionId]?.tests[testCase.name];
|
|
67
|
+
if (result) {
|
|
68
|
+
options.onTestComplete(testCase.criterionId, testCase.name, result);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Update suite statuses to "complete"
|
|
73
|
+
for (const criterionId of startedSuites) {
|
|
74
|
+
storage.updateSuiteStatus(runId, criterionId, "complete");
|
|
75
|
+
}
|
|
76
|
+
// Complete the run
|
|
77
|
+
storage.completeRun(runId);
|
|
78
|
+
return storage.getRun(runId);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Execute a single test case through the full pipeline.
|
|
82
|
+
*/
|
|
83
|
+
async executeTestCase(testCase, runId, storage, executorService, judgeService) {
|
|
84
|
+
// Step 1: Update status to "executing"
|
|
85
|
+
storage.updateTestCase(runId, testCase.criterionId, testCase.name, {
|
|
86
|
+
status: "executing",
|
|
87
|
+
});
|
|
88
|
+
// Step 2: Read the fixture file
|
|
89
|
+
const fixtureContent = fs.readFileSync(testCase.fixtureFile, "utf-8");
|
|
90
|
+
// Step 3: Parse the criterion
|
|
91
|
+
// criterionFile is relative to the parent of the criteria dir (e.g. "criteria/backend/controller-conventions.md")
|
|
92
|
+
// The criteria dir config value is e.g. "deskcheck/criteria", so the parent is "deskcheck/"
|
|
93
|
+
// parseCriterion needs the absolute file path and the absolute criteria dir as base
|
|
94
|
+
const criteriaDir = path.resolve(this.projectRoot, this.config.modules_dir);
|
|
95
|
+
const absoluteCriterionFile = path.resolve(path.dirname(criteriaDir), testCase.criterionFile);
|
|
96
|
+
const criterion = parseCriterion(absoluteCriterionFile, criteriaDir);
|
|
97
|
+
// Step 4: Build a synthetic ReviewTask for the executor
|
|
98
|
+
const task = {
|
|
99
|
+
task_id: `test-${testCase.criterionId}-${testCase.name}`,
|
|
100
|
+
review_id: testCase.criterionId,
|
|
101
|
+
review_file: testCase.criterionFile,
|
|
102
|
+
files: [testCase.fixtureFile],
|
|
103
|
+
hint: null,
|
|
104
|
+
model: criterion.model,
|
|
105
|
+
status: "pending",
|
|
106
|
+
created_at: new Date().toISOString(),
|
|
107
|
+
started_at: null,
|
|
108
|
+
completed_at: null,
|
|
109
|
+
context_type: "file",
|
|
110
|
+
context: fixtureContent,
|
|
111
|
+
symbol: null,
|
|
112
|
+
prompt: criterion.prompt,
|
|
113
|
+
};
|
|
114
|
+
// Step 5: Build executor prompt and execute
|
|
115
|
+
const prompt = buildExecutorPrompt(task);
|
|
116
|
+
const executorResult = await executorService.execute(prompt, criterion.model);
|
|
117
|
+
// Step 6: Parse findings
|
|
118
|
+
const findings = parseFindings(executorResult.resultText);
|
|
119
|
+
// Step 7: Update storage with findings and executor usage, move to "judging"
|
|
120
|
+
storage.updateTestCase(runId, testCase.criterionId, testCase.name, {
|
|
121
|
+
status: "judging",
|
|
122
|
+
findings,
|
|
123
|
+
executor_usage: executorResult.usage,
|
|
124
|
+
});
|
|
125
|
+
// Step 8: Read expected.md
|
|
126
|
+
const expectedContent = fs.readFileSync(testCase.expectedFile, "utf-8");
|
|
127
|
+
// Step 9: Judge findings against expectations
|
|
128
|
+
const judgeOutput = await judgeService.evaluate(criterion, expectedContent, findings, fixtureContent);
|
|
129
|
+
// Step 10: Score the judge's verdicts
|
|
130
|
+
const scores = calculateScores(judgeOutput.result);
|
|
131
|
+
// Step 11: Update storage with judge result, scores, and judge usage
|
|
132
|
+
storage.updateTestCase(runId, testCase.criterionId, testCase.name, {
|
|
133
|
+
status: "complete",
|
|
134
|
+
judge: judgeOutput.result,
|
|
135
|
+
scores,
|
|
136
|
+
judge_usage: judgeOutput.usage,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=TestRunnerService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestRunnerService.js","sourceRoot":"","sources":["../../../src/services/testing/TestRunnerService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAYzD,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,OAAO,iBAAiB;IACX,MAAM,CAAe;IACrB,WAAW,CAAS;IAErC,YAAY,MAAoB,EAAE,WAAmB;QACnD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,GAAG,CACP,SAAqB,EACrB,UAAkB,EAClB,OAAwB;QAExB,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAErE,iDAAiD;QACjD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;QAEzB,uCAAuC;QACvC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QAExC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,2CAA2C;YAC3C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7C,OAAO,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;gBAClE,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC1C,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,eAAe,CACxB,QAAQ,EACR,KAAK,EACL,OAAO,EACP,eAAe,EACf,YAAY,CACb,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,0CAA0C;gBAC1C,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE;oBACjE,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,YAAY;iBACpB,CAAC,CAAC;YACL,CAAC;YAED,8DAA8D;YAC9D,IAAI,OAAO,EAAE,cAAc,EAAE,CAAC;gBAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACzC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC7E,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,KAAK,MAAM,WAAW,IAAI,aAAa,EAAE,CAAC;YACxC,OAAO,CAAC,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QAC5D,CAAC;QAED,mBAAmB;QACnB,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAE3B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAC3B,QAAkB,EAClB,KAAa,EACb,OAA2B,EAC3B,eAAgC,EAChC,YAA0B;QAE1B,uCAAuC;QACvC,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE;YACjE,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;QAEH,gCAAgC;QAChC,MAAM,cAAc,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAEtE,8BAA8B;QAC9B,kHAAkH;QAClH,4FAA4F;QAC5F,oFAAoF;QACpF,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5E,MAAM,qBAAqB,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,cAAc,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC;QAErE,wDAAwD;QACxD,MAAM,IAAI,GAAe;YACvB,OAAO,EAAE,QAAQ,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,IAAI,EAAE;YACxD,SAAS,EAAE,QAAQ,CAAC,WAAW;YAC/B,WAAW,EAAE,QAAQ,CAAC,aAAa;YACnC,KAAK,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC7B,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,MAAM,EAAE,SAAS;YACjB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,UAAU,EAAE,IAAI;YAChB,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,MAAM;YACpB,OAAO,EAAE,cAAc;YACvB,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,SAAS,CAAC,MAAM;SACzB,CAAC;QAEF,4CAA4C;QAC5C,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QAE9E,yBAAyB;QACzB,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAE1D,6EAA6E;QAC7E,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE;YACjE,MAAM,EAAE,SAAS;YACjB,QAAQ;YACR,cAAc,EAAE,cAAc,CAAC,KAAK;SACrC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAExE,8CAA8C;QAC9C,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,QAAQ,CAC7C,SAAS,EACT,eAAe,EACf,QAAQ,EACR,cAAc,CACf,CAAC;QAEF,sCAAsC;QACtC,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAEnD,qEAAqE;QACrE,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE;YACjE,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,WAAW,CAAC,MAAM;YACzB,MAAM;YACN,WAAW,EAAE,WAAW,CAAC,KAAK;SAC/B,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { JudgeResult, TestScores } from "../../types/testing.js";
|
|
2
|
+
/**
|
|
3
|
+
* Calculate test scores from judge verdicts.
|
|
4
|
+
*
|
|
5
|
+
* Pure math — no LLM, no I/O. Computes recall, precision, and scope
|
|
6
|
+
* compliance from the judge's finding and expectation reviews.
|
|
7
|
+
*/
|
|
8
|
+
export declare function calculateScores(judgeResult: JudgeResult): TestScores;
|
|
9
|
+
//# sourceMappingURL=TestScorerService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestScorerService.d.ts","sourceRoot":"","sources":["../../../src/services/testing/TestScorerService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEtE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,CA+BpE"}
|