@prowi/deskcheck 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +266 -0
  3. package/build/agents/executor-prompt.d.ts +10 -0
  4. package/build/agents/executor-prompt.d.ts.map +1 -0
  5. package/build/agents/executor-prompt.js +65 -0
  6. package/build/agents/executor-prompt.js.map +1 -0
  7. package/build/agents/orchestrator.d.ts +52 -0
  8. package/build/agents/orchestrator.d.ts.map +1 -0
  9. package/build/agents/orchestrator.js +343 -0
  10. package/build/agents/orchestrator.js.map +1 -0
  11. package/build/agents/planner.d.ts +28 -0
  12. package/build/agents/planner.d.ts.map +1 -0
  13. package/build/agents/planner.js +138 -0
  14. package/build/agents/planner.js.map +1 -0
  15. package/build/cli.d.ts +3 -0
  16. package/build/cli.d.ts.map +1 -0
  17. package/build/cli.js +467 -0
  18. package/build/cli.js.map +1 -0
  19. package/build/core/config.d.ts +16 -0
  20. package/build/core/config.d.ts.map +1 -0
  21. package/build/core/config.js +81 -0
  22. package/build/core/config.js.map +1 -0
  23. package/build/core/context-extractor.d.ts +17 -0
  24. package/build/core/context-extractor.d.ts.map +1 -0
  25. package/build/core/context-extractor.js +69 -0
  26. package/build/core/context-extractor.js.map +1 -0
  27. package/build/core/glob-matcher.d.ts +32 -0
  28. package/build/core/glob-matcher.d.ts.map +1 -0
  29. package/build/core/glob-matcher.js +51 -0
  30. package/build/core/glob-matcher.js.map +1 -0
  31. package/build/core/module-parser.d.ts +26 -0
  32. package/build/core/module-parser.d.ts.map +1 -0
  33. package/build/core/module-parser.js +98 -0
  34. package/build/core/module-parser.js.map +1 -0
  35. package/build/core/plan-builder.d.ts +12 -0
  36. package/build/core/plan-builder.d.ts.map +1 -0
  37. package/build/core/plan-builder.js +66 -0
  38. package/build/core/plan-builder.js.map +1 -0
  39. package/build/core/storage.d.ts +118 -0
  40. package/build/core/storage.d.ts.map +1 -0
  41. package/build/core/storage.js +590 -0
  42. package/build/core/storage.js.map +1 -0
  43. package/build/core/types.d.ts +268 -0
  44. package/build/core/types.d.ts.map +1 -0
  45. package/build/core/types.js +5 -0
  46. package/build/core/types.js.map +1 -0
  47. package/build/mcp/tools.d.ts +10 -0
  48. package/build/mcp/tools.d.ts.map +1 -0
  49. package/build/mcp/tools.js +354 -0
  50. package/build/mcp/tools.js.map +1 -0
  51. package/build/mcp-server.d.ts +3 -0
  52. package/build/mcp-server.d.ts.map +1 -0
  53. package/build/mcp-server.js +15 -0
  54. package/build/mcp-server.js.map +1 -0
  55. package/build/renderers/json.d.ts +4 -0
  56. package/build/renderers/json.d.ts.map +1 -0
  57. package/build/renderers/json.js +5 -0
  58. package/build/renderers/json.js.map +1 -0
  59. package/build/renderers/markdown.d.ts +4 -0
  60. package/build/renderers/markdown.d.ts.map +1 -0
  61. package/build/renderers/markdown.js +36 -0
  62. package/build/renderers/markdown.js.map +1 -0
  63. package/build/renderers/shared.d.ts +23 -0
  64. package/build/renderers/shared.d.ts.map +1 -0
  65. package/build/renderers/shared.js +30 -0
  66. package/build/renderers/shared.js.map +1 -0
  67. package/build/renderers/terminal.d.ts +4 -0
  68. package/build/renderers/terminal.d.ts.map +1 -0
  69. package/build/renderers/terminal.js +88 -0
  70. package/build/renderers/terminal.js.map +1 -0
  71. package/build/renderers/watch.d.ts +4 -0
  72. package/build/renderers/watch.d.ts.map +1 -0
  73. package/build/renderers/watch.js +119 -0
  74. package/build/renderers/watch.js.map +1 -0
  75. package/build/serve.d.ts +9 -0
  76. package/build/serve.d.ts.map +1 -0
  77. package/build/serve.js +249 -0
  78. package/build/serve.js.map +1 -0
  79. package/package.json +41 -0
  80. package/ui/dist/index.html +92 -0
@@ -0,0 +1,590 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ // =============================================================================
4
+ // Helpers
5
+ // =============================================================================
6
+ /** Format a Date as YYYY-MM-DD_HHmmss for use as a plan ID / directory name. */
7
+ function formatTimestamp(date) {
8
+ const pad2 = (n) => String(n).padStart(2, "0");
9
+ return (`${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}` +
10
+ `_${pad2(date.getHours())}${pad2(date.getMinutes())}${pad2(date.getSeconds())}`);
11
+ }
12
+ /** Convert a review_id like "architecture/dto-enforcement" to "architecture--dto-enforcement". */
13
+ function flattenReviewId(reviewId) {
14
+ return reviewId.replace(/\//g, "--");
15
+ }
16
+ /** Zero-pad a number to 3 digits. */
17
+ function zeroPad3(n) {
18
+ return String(n).padStart(3, "0");
19
+ }
20
+ /** Stale threshold for in_progress tasks (5 minutes in milliseconds). */
21
+ const STALE_THRESHOLD_MS = 5 * 60 * 1000;
22
+ /** Maximum time to wait for a file lock (milliseconds). */
23
+ const LOCK_MAX_WAIT_MS = 10_000;
24
+ /** Spin delay between lock checks (milliseconds). */
25
+ const LOCK_SPIN_MS = 50;
26
+ // =============================================================================
27
+ // ReviewStorage
28
+ // =============================================================================
29
+ /**
30
+ * Manages the two-file storage format (plan.json + results.json) for deskcheck runs.
31
+ *
32
+ * Each deskcheck run lives in a timestamped directory under the configured storage
33
+ * directory. The plan file tracks tasks and coverage; the results file tracks
34
+ * findings and aggregations.
35
+ */
36
+ export class ReviewStorage {
37
+ storageDir;
38
+ /** Tracks active lock file paths so they can be cleaned up on process exit. */
39
+ static activeLocks = new Set();
40
+ static {
41
+ const cleanup = () => {
42
+ for (const lockPath of ReviewStorage.activeLocks) {
43
+ try {
44
+ fs.unlinkSync(lockPath);
45
+ }
46
+ catch { /* ignore */ }
47
+ }
48
+ };
49
+ process.on("exit", cleanup);
50
+ process.on("SIGINT", () => { cleanup(); process.exit(130); });
51
+ process.on("SIGTERM", () => { cleanup(); process.exit(143); });
52
+ }
53
+ constructor(storageDir) {
54
+ this.storageDir = storageDir;
55
+ }
56
+ /**
57
+ * Execute a function while holding a file-based lock for the given plan.
58
+ *
59
+ * Uses `{ flag: "wx" }` for atomic exclusive create — either the file is
60
+ * created (lock acquired) or it already exists (another holder). This
61
+ * eliminates the TOCTOU race of existsSync + writeFileSync.
62
+ *
63
+ * Stale locks are detected via a timestamp in the lock file body.
64
+ */
65
+ withLock(planId, fn) {
66
+ const lockPath = path.join(this.planDir(planId), ".lock");
67
+ const start = Date.now();
68
+ // Acquire lock using atomic exclusive create
69
+ while (true) {
70
+ try {
71
+ fs.writeFileSync(lockPath, JSON.stringify({ pid: process.pid, timestamp: Date.now() }), { flag: "wx" });
72
+ break; // Lock acquired
73
+ }
74
+ catch (err) {
75
+ // File already exists — another process holds the lock
76
+ if (err.code === "EEXIST") {
77
+ // Check for stale lock (holder may have crashed)
78
+ try {
79
+ const lockData = JSON.parse(fs.readFileSync(lockPath, "utf-8"));
80
+ if (typeof lockData.timestamp === "number" && Date.now() - lockData.timestamp > LOCK_MAX_WAIT_MS) {
81
+ // Stale lock — force remove and retry
82
+ try {
83
+ fs.unlinkSync(lockPath);
84
+ }
85
+ catch { /* ignore */ }
86
+ continue;
87
+ }
88
+ }
89
+ catch {
90
+ // Can't read lock file — force remove and retry
91
+ try {
92
+ fs.unlinkSync(lockPath);
93
+ }
94
+ catch { /* ignore */ }
95
+ continue;
96
+ }
97
+ if (Date.now() - start > LOCK_MAX_WAIT_MS) {
98
+ throw new Error(`Storage lock timeout for plan ${planId}. Lock file: ${lockPath}`);
99
+ }
100
+ // Non-blocking wait using Atomics.wait on a shared buffer
101
+ const wait = new Int32Array(new SharedArrayBuffer(4));
102
+ Atomics.wait(wait, 0, 0, LOCK_SPIN_MS);
103
+ continue;
104
+ }
105
+ throw err; // Unexpected error
106
+ }
107
+ }
108
+ ReviewStorage.activeLocks.add(lockPath);
109
+ try {
110
+ return fn();
111
+ }
112
+ finally {
113
+ ReviewStorage.activeLocks.delete(lockPath);
114
+ try {
115
+ fs.unlinkSync(lockPath);
116
+ }
117
+ catch { /* ignore */ }
118
+ }
119
+ }
120
+ /** Get the directory path for a plan. */
121
+ planDir(planId) {
122
+ return path.join(this.storageDir, planId);
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Plan Management
126
+ // ---------------------------------------------------------------------------
127
+ /**
128
+ * Create a new review plan with an empty task set.
129
+ *
130
+ * Creates the timestamped directory and writes an initial plan.json with
131
+ * status "planning" and empty collections.
132
+ */
133
+ createPlan(name, source) {
134
+ const now = new Date();
135
+ const planId = formatTimestamp(now);
136
+ const planDir = path.join(this.storageDir, planId);
137
+ fs.mkdirSync(planDir, { recursive: true });
138
+ const plan = {
139
+ plan_id: planId,
140
+ name,
141
+ source,
142
+ status: "planning",
143
+ created_at: now.toISOString(),
144
+ finalized_at: null,
145
+ started_at: null,
146
+ completed_at: null,
147
+ matched_files: [],
148
+ unmatched_files: [],
149
+ tasks: {},
150
+ modules: {},
151
+ };
152
+ this.writePlan(planId, plan);
153
+ return plan;
154
+ }
155
+ /** Read the plan.json for a given plan ID. */
156
+ getPlan(planId) {
157
+ const planPath = this.planPath(planId);
158
+ const raw = fs.readFileSync(planPath, "utf-8");
159
+ return JSON.parse(raw);
160
+ }
161
+ /**
162
+ * Return the most recent plan ID (latest timestamped directory), or null if
163
+ * no plans exist.
164
+ */
165
+ getLatestPlanId() {
166
+ if (!fs.existsSync(this.storageDir)) {
167
+ return null;
168
+ }
169
+ const entries = fs.readdirSync(this.storageDir, { withFileTypes: true });
170
+ const planDirs = entries
171
+ .filter((entry) => entry.isDirectory() &&
172
+ fs.existsSync(path.join(this.storageDir, entry.name, "plan.json")))
173
+ .map((entry) => entry.name)
174
+ .sort();
175
+ if (planDirs.length === 0) {
176
+ return null;
177
+ }
178
+ return planDirs[planDirs.length - 1];
179
+ }
180
+ /** List all plans with basic metadata. */
181
+ listPlans() {
182
+ if (!fs.existsSync(this.storageDir)) {
183
+ return [];
184
+ }
185
+ const entries = fs.readdirSync(this.storageDir, { withFileTypes: true });
186
+ const result = [];
187
+ for (const entry of entries) {
188
+ if (!entry.isDirectory())
189
+ continue;
190
+ const planJsonPath = path.join(this.storageDir, entry.name, "plan.json");
191
+ if (!fs.existsSync(planJsonPath))
192
+ continue;
193
+ const raw = fs.readFileSync(planJsonPath, "utf-8");
194
+ const plan = JSON.parse(raw);
195
+ result.push({
196
+ planId: plan.plan_id,
197
+ name: plan.name,
198
+ status: plan.status,
199
+ createdAt: plan.created_at,
200
+ });
201
+ }
202
+ return result.sort((a, b) => a.planId.localeCompare(b.planId));
203
+ }
204
+ /**
205
+ * Finalize a plan by setting its status to "ready" and updating task counts
206
+ * in module summaries.
207
+ */
208
+ finalizePlan(planId) {
209
+ return this.withLock(planId, () => {
210
+ const plan = this.getPlan(planId);
211
+ plan.status = "ready";
212
+ plan.finalized_at = new Date().toISOString();
213
+ // Recount tasks per module
214
+ for (const moduleSummary of Object.values(plan.modules)) {
215
+ moduleSummary.task_count = Object.values(plan.tasks).filter((task) => task.review_id === moduleSummary.review_id).length;
216
+ }
217
+ this.writePlan(planId, plan);
218
+ return plan;
219
+ });
220
+ }
221
+ // ---------------------------------------------------------------------------
222
+ // Task Management
223
+ // ---------------------------------------------------------------------------
224
+ /**
225
+ * Add a task to an existing plan.
226
+ *
227
+ * Auto-generates the task_id by flattening slashes in the review_id and
228
+ * appending a zero-padded incrementing suffix (e.g., "-001", "-002").
229
+ * The task is created with status "pending" and null context fields.
230
+ */
231
+ addTask(planId, task) {
232
+ return this.withLock(planId, () => {
233
+ const plan = this.getPlan(planId);
234
+ // Auto-generate task_id: flatten review_id and auto-increment
235
+ const prefix = flattenReviewId(task.review_id);
236
+ const existingCount = Object.keys(plan.tasks).filter((id) => id.startsWith(prefix + "-")).length;
237
+ const taskId = `${prefix}-${zeroPad3(existingCount + 1)}`;
238
+ const newTask = {
239
+ task_id: taskId,
240
+ review_id: task.review_id,
241
+ review_file: task.review_file,
242
+ files: task.files,
243
+ hint: task.hint,
244
+ model: task.model,
245
+ status: "pending",
246
+ created_at: new Date().toISOString(),
247
+ started_at: null,
248
+ completed_at: null,
249
+ context_type: plan.source.type,
250
+ context: null,
251
+ symbol: null,
252
+ prompt: null,
253
+ };
254
+ plan.tasks[taskId] = newTask;
255
+ this.writePlan(planId, plan);
256
+ return newTask;
257
+ });
258
+ }
259
+ /**
260
+ * Claim a pending task for execution.
261
+ *
262
+ * Sets the task status to "in_progress", fills in the context fields
263
+ * (context type, content, symbol, prompt), and records the start time.
264
+ */
265
+ claimTask(planId, taskId, context) {
266
+ return this.withLock(planId, () => {
267
+ const plan = this.getPlan(planId);
268
+ const task = plan.tasks[taskId];
269
+ if (!task) {
270
+ throw new Error(`Task "${taskId}" not found in plan "${planId}"`);
271
+ }
272
+ task.status = "in_progress";
273
+ task.started_at = new Date().toISOString();
274
+ task.context_type = context.contextType;
275
+ task.context = context.content;
276
+ task.symbol = context.symbol ?? null;
277
+ task.prompt = context.prompt;
278
+ // Set plan to executing if it was ready
279
+ if (plan.status === "ready") {
280
+ plan.started_at = task.started_at;
281
+ plan.status = "executing";
282
+ }
283
+ this.writePlan(planId, plan);
284
+ return task;
285
+ });
286
+ }
287
+ /**
288
+ * Return tasks eligible for execution: those with status "pending" or
289
+ * "in_progress" tasks that are stale (older than 5 minutes).
290
+ */
291
+ getPendingTasks(planId) {
292
+ const plan = this.getPlan(planId);
293
+ const now = Date.now();
294
+ return Object.values(plan.tasks).filter((task) => {
295
+ if (task.status === "pending")
296
+ return true;
297
+ if (task.status === "in_progress" && task.started_at) {
298
+ const elapsed = now - new Date(task.started_at).getTime();
299
+ return elapsed > STALE_THRESHOLD_MS;
300
+ }
301
+ return false;
302
+ });
303
+ }
304
+ // ---------------------------------------------------------------------------
305
+ // Result Management
306
+ // ---------------------------------------------------------------------------
307
+ /**
308
+ * Mark a task as complete and record its findings.
309
+ *
310
+ * Updates the task status in plan.json, adds a TaskResult entry to
311
+ * results.json, and recomputes all aggregations (by_file, by_module,
312
+ * summary, completion).
313
+ */
314
+ completeTask(planId, taskId, findings, usage) {
315
+ this.withLock(planId, () => {
316
+ const now = new Date().toISOString();
317
+ // Update plan.json task status
318
+ const plan = this.getPlan(planId);
319
+ const task = plan.tasks[taskId];
320
+ if (!task) {
321
+ throw new Error(`Task "${taskId}" not found in plan "${planId}"`);
322
+ }
323
+ task.status = "complete";
324
+ task.completed_at = now;
325
+ // Check if all tasks have reached a terminal status (complete or error)
326
+ const allDone = Object.values(plan.tasks).every((t) => t.status === "complete" || t.status === "error");
327
+ if (allDone) {
328
+ plan.status = "complete";
329
+ plan.completed_at = now;
330
+ }
331
+ this.writePlan(planId, plan);
332
+ // Add task result to results.json
333
+ const taskResult = {
334
+ task_id: taskId,
335
+ review_id: task.review_id,
336
+ files: task.files,
337
+ completed_at: now,
338
+ findings,
339
+ usage: usage ?? null,
340
+ };
341
+ const results = this.loadOrCreateResults(planId);
342
+ results.task_results[taskId] = taskResult;
343
+ // Recompute all aggregations from scratch
344
+ this.recomputeAggregations(results, plan);
345
+ this.writeResults(planId, results);
346
+ });
347
+ }
348
+ /**
349
+ * Mark a task as errored.
350
+ *
351
+ * Sets the task status to "error" without recording any findings.
352
+ * Updates plan.json and recomputes result aggregations so the error
353
+ * is reflected in completion counts.
354
+ */
355
+ errorTask(planId, taskId, errorMessage, usage) {
356
+ this.withLock(planId, () => {
357
+ const now = new Date().toISOString();
358
+ const plan = this.getPlan(planId);
359
+ const task = plan.tasks[taskId];
360
+ if (!task) {
361
+ throw new Error(`Task "${taskId}" not found in plan "${planId}"`);
362
+ }
363
+ task.status = "error";
364
+ task.completed_at = now;
365
+ // Check if all tasks have reached a terminal status
366
+ const allDone = Object.values(plan.tasks).every((t) => t.status === "complete" || t.status === "error");
367
+ if (allDone) {
368
+ plan.status = "complete";
369
+ plan.completed_at = now;
370
+ }
371
+ this.writePlan(planId, plan);
372
+ // Add task result to results.json (with empty findings but preserving usage data)
373
+ const results = this.loadOrCreateResults(planId);
374
+ if (usage) {
375
+ const taskResult = {
376
+ task_id: taskId,
377
+ review_id: task.review_id,
378
+ files: task.files,
379
+ completed_at: now,
380
+ findings: [],
381
+ usage: usage ?? null,
382
+ };
383
+ results.task_results[taskId] = taskResult;
384
+ }
385
+ // Recompute aggregations so completion counts reflect the error
386
+ this.recomputeAggregations(results, plan);
387
+ this.writeResults(planId, results);
388
+ });
389
+ }
390
+ /** Read the results.json for a given plan ID. */
391
+ getResults(planId) {
392
+ const resultsPath = this.resultsPath(planId);
393
+ if (!fs.existsSync(resultsPath)) {
394
+ // Return empty results if no results file exists yet
395
+ return this.createEmptyResults(planId);
396
+ }
397
+ const raw = fs.readFileSync(resultsPath, "utf-8");
398
+ return JSON.parse(raw);
399
+ }
400
+ // ---------------------------------------------------------------------------
401
+ // Coverage
402
+ // ---------------------------------------------------------------------------
403
+ /** Set the matched and unmatched file lists in the plan. */
404
+ setMatchedFiles(planId, matched, unmatched) {
405
+ this.withLock(planId, () => {
406
+ const plan = this.getPlan(planId);
407
+ plan.matched_files = matched;
408
+ plan.unmatched_files = unmatched;
409
+ this.writePlan(planId, plan);
410
+ });
411
+ }
412
+ /** Set the per-module summaries in the plan. */
413
+ setModules(planId, modules) {
414
+ this.withLock(planId, () => {
415
+ const plan = this.getPlan(planId);
416
+ plan.modules = modules;
417
+ this.writePlan(planId, plan);
418
+ });
419
+ }
420
+ // ---------------------------------------------------------------------------
421
+ // Private Helpers
422
+ // ---------------------------------------------------------------------------
423
+ planPath(planId) {
424
+ return path.join(this.storageDir, planId, "plan.json");
425
+ }
426
+ resultsPath(planId) {
427
+ return path.join(this.storageDir, planId, "results.json");
428
+ }
429
+ writePlan(planId, plan) {
430
+ const target = this.planPath(planId);
431
+ const tmp = target + ".tmp";
432
+ fs.writeFileSync(tmp, JSON.stringify(plan, null, 2) + "\n");
433
+ fs.renameSync(tmp, target);
434
+ }
435
+ writeResults(planId, results) {
436
+ const target = this.resultsPath(planId);
437
+ const tmp = target + ".tmp";
438
+ fs.writeFileSync(tmp, JSON.stringify(results, null, 2) + "\n");
439
+ fs.renameSync(tmp, target);
440
+ }
441
+ createEmptyResults(planId) {
442
+ return {
443
+ plan_id: planId,
444
+ status: "partial",
445
+ updated_at: new Date().toISOString(),
446
+ completion: {
447
+ total: 0,
448
+ completed: 0,
449
+ pending: 0,
450
+ in_progress: 0,
451
+ errored: 0,
452
+ },
453
+ summary: {
454
+ total: 0,
455
+ critical: 0,
456
+ warning: 0,
457
+ info: 0,
458
+ },
459
+ task_results: {},
460
+ by_file: {},
461
+ by_module: {},
462
+ total_usage: {
463
+ input_tokens: 0,
464
+ output_tokens: 0,
465
+ cache_read_tokens: 0,
466
+ cache_creation_tokens: 0,
467
+ cost_usd: 0,
468
+ duration_ms: 0,
469
+ duration_api_ms: 0,
470
+ num_turns: 0,
471
+ },
472
+ };
473
+ }
474
+ /**
475
+ * Load existing results.json or create a new empty structure.
476
+ */
477
+ loadOrCreateResults(planId) {
478
+ const resultsPath = this.resultsPath(planId);
479
+ if (fs.existsSync(resultsPath)) {
480
+ const raw = fs.readFileSync(resultsPath, "utf-8");
481
+ return JSON.parse(raw);
482
+ }
483
+ return this.createEmptyResults(planId);
484
+ }
485
+ /**
486
+ * Recompute all derived aggregations in results from the task_results
487
+ * and the current plan state.
488
+ *
489
+ * This rebuilds by_file, by_module, summary, and completion from scratch
490
+ * on every completeTask call. Since there is a single orchestrator process,
491
+ * this is safe and keeps the logic simple.
492
+ */
493
+ recomputeAggregations(results, plan) {
494
+ const now = new Date().toISOString();
495
+ results.updated_at = now;
496
+ // ---- Completion ----
497
+ const tasks = Object.values(plan.tasks);
498
+ results.completion = {
499
+ total: tasks.length,
500
+ completed: tasks.filter((t) => t.status === "complete").length,
501
+ pending: tasks.filter((t) => t.status === "pending").length,
502
+ in_progress: tasks.filter((t) => t.status === "in_progress").length,
503
+ errored: tasks.filter((t) => t.status === "error").length,
504
+ };
505
+ // ---- Summary (aggregate finding counts) ----
506
+ const summary = { total: 0, critical: 0, warning: 0, info: 0 };
507
+ for (const taskResult of Object.values(results.task_results)) {
508
+ for (const finding of taskResult.findings) {
509
+ summary.total++;
510
+ summary[finding.severity]++;
511
+ }
512
+ }
513
+ results.summary = summary;
514
+ // ---- by_file (group all findings by file path) ----
515
+ const byFile = {};
516
+ for (const taskResult of Object.values(results.task_results)) {
517
+ for (const finding of taskResult.findings) {
518
+ const fileFinding = {
519
+ ...finding,
520
+ review_id: taskResult.review_id,
521
+ task_id: taskResult.task_id,
522
+ };
523
+ if (!byFile[finding.file]) {
524
+ byFile[finding.file] = [];
525
+ }
526
+ byFile[finding.file].push(fileFinding);
527
+ }
528
+ }
529
+ results.by_file = byFile;
530
+ // ---- by_module (group findings by criterion) ----
531
+ const byModule = {};
532
+ for (const taskResult of Object.values(results.task_results)) {
533
+ const reviewId = taskResult.review_id;
534
+ if (!byModule[reviewId]) {
535
+ // Look up module metadata from the plan
536
+ const moduleSummary = plan.modules[reviewId];
537
+ byModule[reviewId] = {
538
+ review_id: reviewId,
539
+ description: moduleSummary?.description ?? "",
540
+ severity: moduleSummary?.severity ?? "medium",
541
+ task_count: moduleSummary?.task_count ?? 0,
542
+ completed: 0,
543
+ counts: { critical: 0, warning: 0, info: 0, total: 0 },
544
+ findings: [],
545
+ };
546
+ }
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);
553
+ }
554
+ }
555
+ results.by_module = byModule;
556
+ // ---- Status ----
557
+ // A result set is "complete" when all tasks have reached a terminal state
558
+ // (either completed successfully or errored out).
559
+ const terminalCount = results.completion.completed + results.completion.errored;
560
+ results.status =
561
+ terminalCount === results.completion.total
562
+ ? "complete"
563
+ : "partial";
564
+ // ---- Total Usage ----
565
+ const totalUsage = {
566
+ input_tokens: 0,
567
+ output_tokens: 0,
568
+ cache_read_tokens: 0,
569
+ cache_creation_tokens: 0,
570
+ cost_usd: 0,
571
+ duration_ms: 0,
572
+ duration_api_ms: 0,
573
+ num_turns: 0,
574
+ };
575
+ for (const taskResult of Object.values(results.task_results)) {
576
+ if (taskResult.usage) {
577
+ totalUsage.input_tokens += taskResult.usage.input_tokens;
578
+ totalUsage.output_tokens += taskResult.usage.output_tokens;
579
+ totalUsage.cache_read_tokens += taskResult.usage.cache_read_tokens;
580
+ totalUsage.cache_creation_tokens += taskResult.usage.cache_creation_tokens;
581
+ totalUsage.cost_usd += taskResult.usage.cost_usd;
582
+ totalUsage.duration_ms += taskResult.usage.duration_ms;
583
+ totalUsage.duration_api_ms += taskResult.usage.duration_api_ms;
584
+ totalUsage.num_turns += taskResult.usage.num_turns;
585
+ }
586
+ }
587
+ results.total_usage = totalUsage;
588
+ }
589
+ }
590
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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"}