@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.
Files changed (181) hide show
  1. package/README.md +67 -12
  2. package/build/cli.js +112 -24
  3. package/build/cli.js.map +1 -1
  4. package/build/{core/config.d.ts → config/loader.d.ts} +9 -1
  5. package/build/config/loader.d.ts.map +1 -0
  6. package/build/{core/config.js → config/loader.js} +4 -2
  7. package/build/config/loader.js.map +1 -0
  8. package/build/config/types.d.ts +45 -0
  9. package/build/config/types.d.ts.map +1 -0
  10. package/build/config/types.js +2 -0
  11. package/build/config/types.js.map +1 -0
  12. package/build/mcp/tools.d.ts +1 -1
  13. package/build/mcp/tools.d.ts.map +1 -1
  14. package/build/mcp/tools.js +35 -25
  15. package/build/mcp/tools.js.map +1 -1
  16. package/build/mcp-server.js +1 -1
  17. package/build/mcp-server.js.map +1 -1
  18. package/build/{agents/executor-prompt.d.ts → prompts/ExecutorPrompt.d.ts} +6 -2
  19. package/build/prompts/ExecutorPrompt.d.ts.map +1 -0
  20. package/build/prompts/ExecutorPrompt.js +111 -0
  21. package/build/prompts/ExecutorPrompt.js.map +1 -0
  22. package/build/prompts/JudgePrompt.d.ts +16 -0
  23. package/build/prompts/JudgePrompt.d.ts.map +1 -0
  24. package/build/prompts/JudgePrompt.js +57 -0
  25. package/build/prompts/JudgePrompt.js.map +1 -0
  26. package/build/prompts/PlannerPrompt.d.ts +12 -0
  27. package/build/prompts/PlannerPrompt.d.ts.map +1 -0
  28. package/build/prompts/PlannerPrompt.js +34 -0
  29. package/build/prompts/PlannerPrompt.js.map +1 -0
  30. package/build/renderers/{json.d.ts → review/JsonRenderer.d.ts} +2 -2
  31. package/build/renderers/review/JsonRenderer.d.ts.map +1 -0
  32. package/build/renderers/{json.js → review/JsonRenderer.js} +1 -1
  33. package/build/renderers/review/JsonRenderer.js.map +1 -0
  34. package/build/renderers/{markdown.d.ts → review/MarkdownRenderer.d.ts} +2 -2
  35. package/build/renderers/review/MarkdownRenderer.d.ts.map +1 -0
  36. package/build/renderers/review/MarkdownRenderer.js +52 -0
  37. package/build/renderers/review/MarkdownRenderer.js.map +1 -0
  38. package/build/renderers/{terminal.d.ts → review/TerminalRenderer.d.ts} +2 -2
  39. package/build/renderers/review/TerminalRenderer.d.ts.map +1 -0
  40. package/build/renderers/{terminal.js → review/TerminalRenderer.js} +36 -14
  41. package/build/renderers/review/TerminalRenderer.js.map +1 -0
  42. package/build/renderers/{watch.d.ts → review/WatchRenderer.d.ts} +2 -2
  43. package/build/renderers/review/WatchRenderer.d.ts.map +1 -0
  44. package/build/renderers/{watch.js → review/WatchRenderer.js} +3 -3
  45. package/build/renderers/review/WatchRenderer.js.map +1 -0
  46. package/build/renderers/shared.d.ts +11 -11
  47. package/build/renderers/shared.d.ts.map +1 -1
  48. package/build/renderers/shared.js +15 -15
  49. package/build/renderers/shared.js.map +1 -1
  50. package/build/renderers/test/TerminalRenderer.d.ts +14 -0
  51. package/build/renderers/test/TerminalRenderer.d.ts.map +1 -0
  52. package/build/renderers/test/TerminalRenderer.js +233 -0
  53. package/build/renderers/test/TerminalRenderer.js.map +1 -0
  54. package/build/server/controllers/ReviewController.d.ts +23 -0
  55. package/build/server/controllers/ReviewController.d.ts.map +1 -0
  56. package/build/server/controllers/ReviewController.js +90 -0
  57. package/build/server/controllers/ReviewController.js.map +1 -0
  58. package/build/server/controllers/TestController.d.ts +2 -0
  59. package/build/server/controllers/TestController.d.ts.map +1 -0
  60. package/build/server/controllers/TestController.js +3 -0
  61. package/build/server/controllers/TestController.js.map +1 -0
  62. package/build/server/middleware/cors.d.ts +9 -0
  63. package/build/server/middleware/cors.d.ts.map +1 -0
  64. package/build/server/middleware/cors.js +18 -0
  65. package/build/server/middleware/cors.js.map +1 -0
  66. package/build/{serve.d.ts → server/server.d.ts} +2 -2
  67. package/build/server/server.d.ts.map +1 -0
  68. package/build/server/server.js +102 -0
  69. package/build/server/server.js.map +1 -0
  70. package/build/server/sse/FileWatcherSSE.d.ts +10 -0
  71. package/build/server/sse/FileWatcherSSE.d.ts.map +1 -0
  72. package/build/server/sse/FileWatcherSSE.js +89 -0
  73. package/build/server/sse/FileWatcherSSE.js.map +1 -0
  74. package/build/services/ExecutorService.d.ts +51 -0
  75. package/build/services/ExecutorService.d.ts.map +1 -0
  76. package/build/services/ExecutorService.js +133 -0
  77. package/build/services/ExecutorService.js.map +1 -0
  78. package/build/services/FindingsParserService.d.ts +18 -0
  79. package/build/services/FindingsParserService.d.ts.map +1 -0
  80. package/build/services/FindingsParserService.js +119 -0
  81. package/build/services/FindingsParserService.js.map +1 -0
  82. package/build/services/criteria/CriteriaService.d.ts +10 -0
  83. package/build/services/criteria/CriteriaService.d.ts.map +1 -0
  84. package/build/services/criteria/CriteriaService.js +10 -0
  85. package/build/services/criteria/CriteriaService.js.map +1 -0
  86. package/build/{core → services/criteria}/glob-matcher.d.ts +1 -1
  87. package/build/services/criteria/glob-matcher.d.ts.map +1 -0
  88. package/build/services/criteria/glob-matcher.js.map +1 -0
  89. package/build/{core → services/criteria}/module-parser.d.ts +13 -1
  90. package/build/services/criteria/module-parser.d.ts.map +1 -0
  91. package/build/{core → services/criteria}/module-parser.js +38 -0
  92. package/build/services/criteria/module-parser.js.map +1 -0
  93. package/build/{core/context-extractor.d.ts → services/review/ReviewContextExtractorService.d.ts} +2 -2
  94. package/build/services/review/ReviewContextExtractorService.d.ts.map +1 -0
  95. package/build/{core/context-extractor.js → services/review/ReviewContextExtractorService.js} +1 -1
  96. package/build/services/review/ReviewContextExtractorService.js.map +1 -0
  97. package/build/{agents/orchestrator.d.ts → services/review/ReviewOrchestratorService.d.ts} +7 -5
  98. package/build/services/review/ReviewOrchestratorService.d.ts.map +1 -0
  99. package/build/services/review/ReviewOrchestratorService.js +187 -0
  100. package/build/services/review/ReviewOrchestratorService.js.map +1 -0
  101. package/build/{core/plan-builder.d.ts → services/review/ReviewPlanBuilderService.d.ts} +5 -4
  102. package/build/services/review/ReviewPlanBuilderService.d.ts.map +1 -0
  103. package/build/{core/plan-builder.js → services/review/ReviewPlanBuilderService.js} +2 -2
  104. package/build/services/review/ReviewPlanBuilderService.js.map +1 -0
  105. package/build/{agents/planner.d.ts → services/review/ReviewPlannerService.d.ts} +5 -4
  106. package/build/services/review/ReviewPlannerService.d.ts.map +1 -0
  107. package/build/{agents/planner.js → services/review/ReviewPlannerService.js} +13 -29
  108. package/build/services/review/ReviewPlannerService.js.map +1 -0
  109. package/build/{core/storage.d.ts → services/review/ReviewStorageService.d.ts} +4 -4
  110. package/build/services/review/ReviewStorageService.d.ts.map +1 -0
  111. package/build/{core/storage.js → services/review/ReviewStorageService.js} +42 -27
  112. package/build/services/review/ReviewStorageService.js.map +1 -0
  113. package/build/services/testing/JudgeService.d.ts +30 -0
  114. package/build/services/testing/JudgeService.d.ts.map +1 -0
  115. package/build/services/testing/JudgeService.js +95 -0
  116. package/build/services/testing/JudgeService.js.map +1 -0
  117. package/build/services/testing/TestDiscoveryService.d.ts +16 -0
  118. package/build/services/testing/TestDiscoveryService.d.ts.map +1 -0
  119. package/build/services/testing/TestDiscoveryService.js +66 -0
  120. package/build/services/testing/TestDiscoveryService.js.map +1 -0
  121. package/build/services/testing/TestRunnerService.d.ts +35 -0
  122. package/build/services/testing/TestRunnerService.d.ts.map +1 -0
  123. package/build/services/testing/TestRunnerService.js +140 -0
  124. package/build/services/testing/TestRunnerService.js.map +1 -0
  125. package/build/services/testing/TestScorerService.d.ts +9 -0
  126. package/build/services/testing/TestScorerService.d.ts.map +1 -0
  127. package/build/services/testing/TestScorerService.js +35 -0
  128. package/build/services/testing/TestScorerService.js.map +1 -0
  129. package/build/services/testing/TestStorageService.d.ts +39 -0
  130. package/build/services/testing/TestStorageService.d.ts.map +1 -0
  131. package/build/services/testing/TestStorageService.js +144 -0
  132. package/build/services/testing/TestStorageService.js.map +1 -0
  133. package/build/types/criteria.d.ts +24 -0
  134. package/build/types/criteria.d.ts.map +1 -0
  135. package/build/{core/types.js → types/criteria.js} +2 -2
  136. package/build/types/criteria.js.map +1 -0
  137. package/build/{core/types.d.ts → types/review.d.ts} +54 -88
  138. package/build/types/review.d.ts.map +1 -0
  139. package/build/types/review.js +2 -0
  140. package/build/types/review.js.map +1 -0
  141. package/build/types/testing.d.ts +109 -0
  142. package/build/types/testing.d.ts.map +1 -0
  143. package/build/types/testing.js +2 -0
  144. package/build/types/testing.js.map +1 -0
  145. package/package.json +1 -1
  146. package/ui/dist/index.html +34 -34
  147. package/build/agents/executor-prompt.d.ts.map +0 -1
  148. package/build/agents/executor-prompt.js +0 -65
  149. package/build/agents/executor-prompt.js.map +0 -1
  150. package/build/agents/orchestrator.d.ts.map +0 -1
  151. package/build/agents/orchestrator.js +0 -343
  152. package/build/agents/orchestrator.js.map +0 -1
  153. package/build/agents/planner.d.ts.map +0 -1
  154. package/build/agents/planner.js.map +0 -1
  155. package/build/core/config.d.ts.map +0 -1
  156. package/build/core/config.js.map +0 -1
  157. package/build/core/context-extractor.d.ts.map +0 -1
  158. package/build/core/context-extractor.js.map +0 -1
  159. package/build/core/glob-matcher.d.ts.map +0 -1
  160. package/build/core/glob-matcher.js.map +0 -1
  161. package/build/core/module-parser.d.ts.map +0 -1
  162. package/build/core/module-parser.js.map +0 -1
  163. package/build/core/plan-builder.d.ts.map +0 -1
  164. package/build/core/plan-builder.js.map +0 -1
  165. package/build/core/storage.d.ts.map +0 -1
  166. package/build/core/storage.js.map +0 -1
  167. package/build/core/types.d.ts.map +0 -1
  168. package/build/core/types.js.map +0 -1
  169. package/build/renderers/json.d.ts.map +0 -1
  170. package/build/renderers/json.js.map +0 -1
  171. package/build/renderers/markdown.d.ts.map +0 -1
  172. package/build/renderers/markdown.js +0 -36
  173. package/build/renderers/markdown.js.map +0 -1
  174. package/build/renderers/terminal.d.ts.map +0 -1
  175. package/build/renderers/terminal.js.map +0 -1
  176. package/build/renderers/watch.d.ts.map +0 -1
  177. package/build/renderers/watch.js.map +0 -1
  178. package/build/serve.d.ts.map +0 -1
  179. package/build/serve.js +0 -249
  180. package/build/serve.js.map +0 -1
  181. /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
- // ReviewStorage
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 ReviewStorage {
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 ReviewStorage.activeLocks) {
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
- ReviewStorage.activeLocks.add(lockPath);
108
+ ReviewStorageService.activeLocks.add(lockPath);
109
109
  try {
110
110
  return fn();
111
111
  }
112
112
  finally {
113
- ReviewStorage.activeLocks.delete(lockPath);
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, findings, usage) {
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
- findings,
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
- findings: [],
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
- // ---- Summary (aggregate finding counts) ----
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 finding of taskResult.findings) {
514
+ for (const issue of taskResult.issues) {
509
515
  summary.total++;
510
- summary[finding.severity]++;
516
+ summary[issue.severity]++;
511
517
  }
512
518
  }
513
519
  results.summary = summary;
514
- // ---- by_file (group all findings by file path) ----
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 finding of taskResult.findings) {
518
- const fileFinding = {
519
- ...finding,
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
- if (!byFile[finding.file]) {
524
- byFile[finding.file] = [];
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 findings by criterion) ----
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
- findings: [],
559
+ issues: [],
545
560
  };
546
561
  }
547
- const moduleFindings = byModule[reviewId];
548
- moduleFindings.completed++;
549
- for (const finding of taskResult.findings) {
550
- moduleFindings.counts.total++;
551
- moduleFindings.counts[finding.severity]++;
552
- moduleFindings.findings.push(finding);
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=storage.js.map
605
+ //# sourceMappingURL=ReviewStorageService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReviewStorageService.js","sourceRoot":"","sources":["../../../src/services/review/ReviewStorageService.ts"],"names":[],"mappings":"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"}
@@ -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":"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"}
@@ -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":"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"}
@@ -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":"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"}
@@ -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"}