@prowi/deskcheck 0.3.0 → 0.4.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 (93) hide show
  1. package/README.md +78 -84
  2. package/build/cli.js +129 -23
  3. package/build/cli.js.map +1 -1
  4. package/build/config/loader.d.ts.map +1 -1
  5. package/build/config/loader.js +2 -1
  6. package/build/config/loader.js.map +1 -1
  7. package/build/config/types.d.ts +2 -1
  8. package/build/config/types.d.ts.map +1 -1
  9. package/build/mcp/tools.d.ts.map +1 -1
  10. package/build/mcp/tools.js +25 -49
  11. package/build/mcp/tools.js.map +1 -1
  12. package/build/prompts/ExecutorPrompt.d.ts +4 -2
  13. package/build/prompts/ExecutorPrompt.d.ts.map +1 -1
  14. package/build/prompts/ExecutorPrompt.js +40 -33
  15. package/build/prompts/ExecutorPrompt.js.map +1 -1
  16. package/build/prompts/PartitionerPrompt.d.ts +12 -0
  17. package/build/prompts/PartitionerPrompt.d.ts.map +1 -0
  18. package/build/prompts/PartitionerPrompt.js +54 -0
  19. package/build/prompts/PartitionerPrompt.js.map +1 -0
  20. package/build/prompts/ResolverPrompt.d.ts +11 -0
  21. package/build/prompts/ResolverPrompt.d.ts.map +1 -0
  22. package/build/prompts/ResolverPrompt.js +45 -0
  23. package/build/prompts/ResolverPrompt.js.map +1 -0
  24. package/build/renderers/review/MarkdownRenderer.js +5 -2
  25. package/build/renderers/review/MarkdownRenderer.js.map +1 -1
  26. package/build/renderers/review/TerminalRenderer.js +5 -2
  27. package/build/renderers/review/TerminalRenderer.js.map +1 -1
  28. package/build/renderers/review/WatchRenderer.d.ts.map +1 -1
  29. package/build/renderers/review/WatchRenderer.js +10 -1
  30. package/build/renderers/review/WatchRenderer.js.map +1 -1
  31. package/build/server/controllers/ReviewController.d.ts +12 -3
  32. package/build/server/controllers/ReviewController.d.ts.map +1 -1
  33. package/build/server/controllers/ReviewController.js +50 -6
  34. package/build/server/controllers/ReviewController.js.map +1 -1
  35. package/build/server/server.d.ts.map +1 -1
  36. package/build/server/server.js +22 -1
  37. package/build/server/server.js.map +1 -1
  38. package/build/services/ExecutorService.d.ts +17 -2
  39. package/build/services/ExecutorService.d.ts.map +1 -1
  40. package/build/services/ExecutorService.js +37 -5
  41. package/build/services/ExecutorService.js.map +1 -1
  42. package/build/services/FindingsParserService.d.ts +1 -8
  43. package/build/services/FindingsParserService.d.ts.map +1 -1
  44. package/build/services/FindingsParserService.js +20 -45
  45. package/build/services/FindingsParserService.js.map +1 -1
  46. package/build/services/criteria/module-parser.d.ts +1 -1
  47. package/build/services/criteria/module-parser.d.ts.map +1 -1
  48. package/build/services/criteria/module-parser.js +20 -16
  49. package/build/services/criteria/module-parser.js.map +1 -1
  50. package/build/services/review/CodeSnippetService.d.ts +10 -0
  51. package/build/services/review/CodeSnippetService.d.ts.map +1 -0
  52. package/build/services/review/CodeSnippetService.js +54 -0
  53. package/build/services/review/CodeSnippetService.js.map +1 -0
  54. package/build/services/review/ReviewInputResolverService.d.ts +25 -0
  55. package/build/services/review/ReviewInputResolverService.d.ts.map +1 -0
  56. package/build/services/review/ReviewInputResolverService.js +106 -0
  57. package/build/services/review/ReviewInputResolverService.js.map +1 -0
  58. package/build/services/review/ReviewOrchestratorService.d.ts.map +1 -1
  59. package/build/services/review/ReviewOrchestratorService.js +21 -20
  60. package/build/services/review/ReviewOrchestratorService.js.map +1 -1
  61. package/build/services/review/ReviewPartitionerService.d.ts +46 -0
  62. package/build/services/review/ReviewPartitionerService.d.ts.map +1 -0
  63. package/build/services/review/ReviewPartitionerService.js +208 -0
  64. package/build/services/review/ReviewPartitionerService.js.map +1 -0
  65. package/build/services/review/ReviewPlanBuilderService.d.ts +25 -7
  66. package/build/services/review/ReviewPlanBuilderService.d.ts.map +1 -1
  67. package/build/services/review/ReviewPlanBuilderService.js +88 -30
  68. package/build/services/review/ReviewPlanBuilderService.js.map +1 -1
  69. package/build/services/review/ReviewStorageService.d.ts +34 -10
  70. package/build/services/review/ReviewStorageService.d.ts.map +1 -1
  71. package/build/services/review/ReviewStorageService.js +100 -14
  72. package/build/services/review/ReviewStorageService.js.map +1 -1
  73. package/build/services/testing/TestRunnerService.d.ts.map +1 -1
  74. package/build/services/testing/TestRunnerService.js +10 -8
  75. package/build/services/testing/TestRunnerService.js.map +1 -1
  76. package/build/types/criteria.d.ts +8 -6
  77. package/build/types/criteria.d.ts.map +1 -1
  78. package/build/types/review.d.ts +123 -28
  79. package/build/types/review.d.ts.map +1 -1
  80. package/package.json +3 -1
  81. package/ui/dist/index.html +12 -63
  82. package/build/prompts/PlannerPrompt.d.ts +0 -12
  83. package/build/prompts/PlannerPrompt.d.ts.map +0 -1
  84. package/build/prompts/PlannerPrompt.js +0 -34
  85. package/build/prompts/PlannerPrompt.js.map +0 -1
  86. package/build/services/review/ReviewContextExtractorService.d.ts +0 -17
  87. package/build/services/review/ReviewContextExtractorService.d.ts.map +0 -1
  88. package/build/services/review/ReviewContextExtractorService.js +0 -69
  89. package/build/services/review/ReviewContextExtractorService.js.map +0 -1
  90. package/build/services/review/ReviewPlannerService.d.ts +0 -29
  91. package/build/services/review/ReviewPlannerService.d.ts.map +0 -1
  92. package/build/services/review/ReviewPlannerService.js +0 -122
  93. package/build/services/review/ReviewPlannerService.js.map +0 -1
@@ -0,0 +1,208 @@
1
+ import { query, createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
2
+ import { z } from "zod";
3
+ import { buildPartitionerPrompt } from "../../prompts/PartitionerPrompt.js";
4
+ // =============================================================================
5
+ // Errors
6
+ // =============================================================================
7
+ /** Thrown when the partitioner agent fails or produces invalid output. */
8
+ export class PartitionerError extends Error {
9
+ /** The criterion id this failure was scoped to. */
10
+ reviewId;
11
+ constructor(reviewId, message) {
12
+ super(`Partitioner failed for criterion "${reviewId}": ${message}`);
13
+ this.name = "PartitionerError";
14
+ this.reviewId = reviewId;
15
+ }
16
+ }
17
+ // =============================================================================
18
+ // ReviewPartitionerService
19
+ // =============================================================================
20
+ /**
21
+ * Spawns one fresh Claude agent per criterion to decide how to split the
22
+ * matched files into reviewer subtasks. The agent reads the criterion's
23
+ * `partition` instruction (natural language) and uses built-in tools
24
+ * (Read, Grep, Glob, Bash) to inspect files when grouping requires it.
25
+ *
26
+ * Output is delivered via an in-process MCP tool `submit_partition`. If the
27
+ * agent never calls the tool, or calls it with invalid output (e.g. drops a
28
+ * file), this service throws — partitioner failures fail the whole run.
29
+ */
30
+ export class ReviewPartitionerService {
31
+ config;
32
+ projectRoot;
33
+ constructor(config, projectRoot) {
34
+ this.config = config;
35
+ this.projectRoot = projectRoot;
36
+ }
37
+ /**
38
+ * Run the partitioner for one criterion. Returns the validated partition
39
+ * result, or throws on failure.
40
+ */
41
+ async partition(criterion, matchedFiles, scope) {
42
+ if (matchedFiles.length === 0) {
43
+ throw new PartitionerError(criterion.id, "matchedFiles is empty");
44
+ }
45
+ let captured = null;
46
+ let captureError = null;
47
+ const inputFileSet = new Set(matchedFiles);
48
+ // In-process MCP tool the partitioner agent calls to deliver its output.
49
+ const partitionerServer = createSdkMcpServer({
50
+ name: "deskcheck-partitioner",
51
+ version: "0.1.0",
52
+ tools: [
53
+ tool("submit_partition", "Submit the final partition for this criterion. Call exactly once.", {
54
+ reasoning: z
55
+ .string()
56
+ .describe("Short overall explanation of how you split the files."),
57
+ subtasks: z
58
+ .array(z.object({
59
+ files: z
60
+ .array(z.string())
61
+ .describe("Files assigned to this subtask. At least one."),
62
+ focus: z
63
+ .string()
64
+ .nullable()
65
+ .optional()
66
+ .describe("Optional sub-file narrowing (method name, class name, region). Null if the whole file is the unit."),
67
+ hint: z
68
+ .string()
69
+ .nullable()
70
+ .optional()
71
+ .describe("One short sentence explaining why these files belong together."),
72
+ }))
73
+ .min(1)
74
+ .describe("Non-empty list of subtasks."),
75
+ }, async (args) => {
76
+ // Validate locally so we can return a useful error to the agent
77
+ // (and abort with a clear message if it never recovers).
78
+ const normalized = args.subtasks.map((s) => ({
79
+ files: s.files,
80
+ focus: s.focus ?? null,
81
+ hint: s.hint ?? null,
82
+ }));
83
+ const validationError = validatePartition(normalized, inputFileSet);
84
+ if (validationError) {
85
+ captureError = validationError;
86
+ return {
87
+ content: [{
88
+ type: "text",
89
+ text: `Error: ${validationError}. Please call submit_partition again with a corrected partition.`,
90
+ }],
91
+ isError: true,
92
+ };
93
+ }
94
+ captured = { reasoning: args.reasoning, subtasks: normalized };
95
+ captureError = null;
96
+ return {
97
+ content: [{
98
+ type: "text",
99
+ text: `Accepted: ${normalized.length} subtask(s).`,
100
+ }],
101
+ };
102
+ }),
103
+ ],
104
+ });
105
+ const partitionerModel = this.config.agents.partitioner.model ?? "haiku";
106
+ const systemPrompt = buildPartitionerPrompt(criterion, matchedFiles, scope);
107
+ const abortController = new AbortController();
108
+ const timeout = setTimeout(() => abortController.abort(), 5 * 60 * 1000);
109
+ let usage = null;
110
+ const messages = [];
111
+ try {
112
+ for await (const message of query({
113
+ prompt: `Partition the files for criterion ${criterion.id}.`,
114
+ options: {
115
+ model: partitionerModel,
116
+ systemPrompt,
117
+ tools: [
118
+ "Read",
119
+ "Grep",
120
+ "Glob",
121
+ "Bash",
122
+ "mcp__deskcheck-partitioner__*",
123
+ ],
124
+ permissionMode: "bypassPermissions",
125
+ maxTurns: 15,
126
+ cwd: this.projectRoot,
127
+ persistSession: false,
128
+ abortController,
129
+ mcpServers: {
130
+ "deskcheck-partitioner": partitionerServer,
131
+ },
132
+ },
133
+ })) {
134
+ messages.push(message);
135
+ if (message.type === "result") {
136
+ const msg = message;
137
+ const u = msg.usage;
138
+ usage = {
139
+ input_tokens: u?.input_tokens ?? 0,
140
+ output_tokens: u?.output_tokens ?? 0,
141
+ cache_read_tokens: u?.cache_read_input_tokens ?? 0,
142
+ cache_creation_tokens: u?.cache_creation_input_tokens ?? 0,
143
+ cost_usd: msg.total_cost_usd ?? 0,
144
+ duration_ms: msg.duration_ms ?? 0,
145
+ duration_api_ms: msg.duration_api_ms ?? 0,
146
+ num_turns: msg.num_turns ?? 0,
147
+ model: partitionerModel,
148
+ };
149
+ if (message.subtype !== "success") {
150
+ throw new PartitionerError(criterion.id, `agent ended with subtype "${message.subtype}"`);
151
+ }
152
+ }
153
+ }
154
+ }
155
+ finally {
156
+ clearTimeout(timeout);
157
+ }
158
+ // TS narrows `captured` to `never` because all assignments happen inside
159
+ // the MCP tool handler closure — control-flow analysis doesn't follow
160
+ // those. Cast through unknown to read the runtime value.
161
+ const finalCaptured = captured;
162
+ if (!finalCaptured) {
163
+ const detail = captureError
164
+ ? `agent never produced a valid partition. Last validation error: ${captureError}`
165
+ : "agent did not call submit_partition";
166
+ throw new PartitionerError(criterion.id, detail);
167
+ }
168
+ return {
169
+ reasoning: finalCaptured.reasoning,
170
+ subtasks: finalCaptured.subtasks,
171
+ model: partitionerModel,
172
+ usage,
173
+ messages,
174
+ };
175
+ }
176
+ }
177
+ // =============================================================================
178
+ // Validation
179
+ // =============================================================================
180
+ /**
181
+ * Verify a candidate partition covers every input file at least once and
182
+ * has well-formed subtasks. Returns a human-readable error string or null
183
+ * if the partition is valid.
184
+ */
185
+ export function validatePartition(subtasks, inputFiles) {
186
+ if (subtasks.length === 0) {
187
+ return "subtasks must be non-empty";
188
+ }
189
+ const seen = new Set();
190
+ for (let i = 0; i < subtasks.length; i++) {
191
+ const sub = subtasks[i];
192
+ if (!Array.isArray(sub.files) || sub.files.length === 0) {
193
+ return `subtask ${i} has no files`;
194
+ }
195
+ for (const file of sub.files) {
196
+ if (!inputFiles.has(file)) {
197
+ return `subtask ${i} references file "${file}" which is not in the input list`;
198
+ }
199
+ seen.add(file);
200
+ }
201
+ }
202
+ const missing = [...inputFiles].filter((f) => !seen.has(f));
203
+ if (missing.length > 0) {
204
+ return `${missing.length} input file(s) missing from partition: ${missing.slice(0, 5).join(", ")}${missing.length > 5 ? "…" : ""}`;
205
+ }
206
+ return null;
207
+ }
208
+ //# sourceMappingURL=ReviewPartitionerService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReviewPartitionerService.js","sourceRoot":"","sources":["../../../src/services/review/ReviewPartitionerService.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,31 @@
1
1
  import { ReviewStorageService } from "./ReviewStorageService.js";
2
+ import { ReviewPartitionerService } from "./ReviewPartitionerService.js";
2
3
  import type { ReviewModule } from "../../types/criteria.js";
3
- import type { ReviewPlan, ReviewSource } from "../../types/review.js";
4
+ import type { PartitionDecision, PlanInvocation, ReviewPlan, Scope } from "../../types/review.js";
4
5
  /**
5
- * Build a complete review plan: create the plan, match files to modules,
6
- * generate tasks, and finalize.
6
+ * Hooks called as the plan builder progresses through its steps. Used by
7
+ * the CLI to print live status. Optional.
8
+ */
9
+ export interface PartitionProgressEvents {
10
+ /** Fires once after glob matching, before partitioning starts. */
11
+ onMatchingComplete?: (matchedCriteria: number, matchedFiles: number) => void;
12
+ /** Fires when each per-criterion partitioner starts. */
13
+ onPartitionStarted?: (reviewId: string, fileCount: number) => void;
14
+ /** Fires when each per-criterion partitioner finishes successfully. */
15
+ onPartitionCompleted?: (decision: PartitionDecision) => void;
16
+ }
17
+ /**
18
+ * Build a complete review plan: create the plan, glob-match files to
19
+ * criteria, run one partitioner agent per matched criterion to produce
20
+ * subtasks, write everything to storage, and finalize.
21
+ *
22
+ * Partitioners run concurrently with `Promise.all`. ALL partitioners must
23
+ * complete before any tasks are added — this is a deliberate barrier so
24
+ * that downstream reviewers see a fully-partitioned plan and so that the
25
+ * partitioning step can be inspected as a unit (e.g. via `--dry-run`).
7
26
  *
8
- * This is the single authoritative implementation of plan+task creation,
9
- * shared by both the planner agent's in-process MCP tool and any other
10
- * entry point that needs to create a plan from a file list.
27
+ * If any partitioner throws, the error propagates and the plan is left in
28
+ * its pre-finalized state. Per design, partitioner failures fail the run.
11
29
  */
12
- export declare function buildPlanWithTasks(storage: ReviewStorageService, name: string, source: ReviewSource, files: string[], modules: ReviewModule[]): ReviewPlan;
30
+ export declare function buildPlanWithTasks(storage: ReviewStorageService, partitioner: ReviewPartitionerService, name: string, scope: Scope, invocation: PlanInvocation, files: string[], modules: ReviewModule[], events?: PartitionProgressEvents): Promise<ReviewPlan>;
13
31
  //# sourceMappingURL=ReviewPlanBuilderService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReviewPlanBuilderService.d.ts","sourceRoot":"","sources":["../../../src/services/review/ReviewPlanBuilderService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAEV,UAAU,EACV,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,YAAY,EAAE,GACtB,UAAU,CA6DZ"}
1
+ {"version":3,"file":"ReviewPlanBuilderService.d.ts","sourceRoot":"","sources":["../../../src/services/review/ReviewPlanBuilderService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAoB,MAAM,+BAA+B,CAAC;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAEV,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,KAAK,EACN,MAAM,uBAAuB,CAAC;AAE/B;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7E,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC9D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,oBAAoB,EAC7B,WAAW,EAAE,wBAAwB,EACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,cAAc,EAC1B,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,YAAY,EAAE,EACvB,MAAM,CAAC,EAAE,uBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CA8HrB"}
@@ -1,17 +1,24 @@
1
1
  import { findMatchingModules } from "../criteria/glob-matcher.js";
2
+ import { PartitionerError } from "./ReviewPartitionerService.js";
2
3
  /**
3
- * Build a complete review plan: create the plan, match files to modules,
4
- * generate tasks, and finalize.
4
+ * Build a complete review plan: create the plan, glob-match files to
5
+ * criteria, run one partitioner agent per matched criterion to produce
6
+ * subtasks, write everything to storage, and finalize.
5
7
  *
6
- * This is the single authoritative implementation of plan+task creation,
7
- * shared by both the planner agent's in-process MCP tool and any other
8
- * entry point that needs to create a plan from a file list.
8
+ * Partitioners run concurrently with `Promise.all`. ALL partitioners must
9
+ * complete before any tasks are added this is a deliberate barrier so
10
+ * that downstream reviewers see a fully-partitioned plan and so that the
11
+ * partitioning step can be inspected as a unit (e.g. via `--dry-run`).
12
+ *
13
+ * If any partitioner throws, the error propagates and the plan is left in
14
+ * its pre-finalized state. Per design, partitioner failures fail the run.
9
15
  */
10
- export function buildPlanWithTasks(storage, name, source, files, modules) {
11
- // Create the plan shell
12
- const plan = storage.createPlan(name, source);
13
- // Match files against criteria
16
+ export async function buildPlanWithTasks(storage, partitioner, name, scope, invocation, files, modules, events) {
17
+ // Create the plan shell — already at step "matching" by default.
18
+ const plan = storage.createPlan(name, scope, invocation);
19
+ // Match files against criteria (programmatic, no LLM)
14
20
  const matches = findMatchingModules(files, modules);
21
+ events?.onMatchingComplete?.(matches.length, new Set(matches.flatMap((m) => m.matchedFiles)).size);
15
22
  // Track coverage
16
23
  const matchedFileSet = new Set();
17
24
  for (const match of matches) {
@@ -28,39 +35,90 @@ export function buildPlanWithTasks(storage, name, source, files, modules) {
28
35
  moduleSummaries[match.module.id] = {
29
36
  review_id: match.module.id,
30
37
  description: match.module.description,
31
- severity: match.module.severity,
32
38
  model: match.module.model,
39
+ partition: match.module.partition,
33
40
  task_count: 0,
34
41
  matched_files: match.matchedFiles,
35
42
  };
36
43
  }
37
44
  storage.setModules(plan.plan_id, moduleSummaries);
38
- // Create tasks based on module mode
39
- for (const match of matches) {
40
- const isGrouped = match.module.mode.toLowerCase().includes("grouped") ||
41
- match.module.mode.toLowerCase().includes("all files");
42
- if (isGrouped) {
45
+ // ---------------------------------------------------------------------------
46
+ // Partition step one fresh agent per matched criterion, all in parallel.
47
+ // Must complete entirely before any tasks are added. If anything throws,
48
+ // we stamp the failure on the plan so the UI can render it before
49
+ // re-raising for the CLI to surface.
50
+ // ---------------------------------------------------------------------------
51
+ storage.setStep(plan.plan_id, "partitioning");
52
+ let decisions;
53
+ try {
54
+ decisions = await Promise.all(matches.map(async (match) => {
55
+ events?.onPartitionStarted?.(match.module.id, match.matchedFiles.length);
56
+ const result = await partitioner.partition(match.module, match.matchedFiles, scope);
57
+ // Persist the partitioner's full SDK transcript as a side-file.
58
+ try {
59
+ storage.writePartitionerLog(plan.plan_id, match.module.id, result.messages);
60
+ }
61
+ catch (logErr) {
62
+ console.error(`[deskcheck] Warning: failed to write partitioner log for ${match.module.id}: ${logErr instanceof Error ? logErr.message : String(logErr)}`);
63
+ }
64
+ const decision = {
65
+ review_id: match.module.id,
66
+ matched_files: match.matchedFiles,
67
+ reasoning: result.reasoning,
68
+ subtasks: result.subtasks,
69
+ completed_at: new Date().toISOString(),
70
+ model: result.model,
71
+ usage: result.usage,
72
+ };
73
+ storage.setPartitionDecision(plan.plan_id, decision);
74
+ events?.onPartitionCompleted?.(decision);
75
+ return decision;
76
+ }));
77
+ }
78
+ catch (err) {
79
+ const message = err instanceof Error ? err.message : String(err);
80
+ const reviewId = err instanceof PartitionerError ? err.reviewId : null;
81
+ storage.setFailure(plan.plan_id, {
82
+ step: "partitioning",
83
+ review_id: reviewId,
84
+ message,
85
+ });
86
+ throw err;
87
+ }
88
+ // ---------------------------------------------------------------------------
89
+ // Materialize partitioner output as ReviewTasks. We do this after all
90
+ // partitioners finish so storage writes are batched and the plan is never
91
+ // half-partitioned on disk.
92
+ // ---------------------------------------------------------------------------
93
+ for (let i = 0; i < matches.length; i++) {
94
+ const match = matches[i];
95
+ const decision = decisions[i];
96
+ for (const subtask of decision.subtasks) {
43
97
  storage.addTask(plan.plan_id, {
44
98
  review_id: match.module.id,
45
99
  review_file: match.module.file,
46
- files: match.matchedFiles,
47
- hint: null,
100
+ files: subtask.files,
101
+ focus: subtask.focus,
102
+ hint: subtask.hint,
48
103
  model: match.module.model,
104
+ tools: match.module.tools,
105
+ prompt: match.module.prompt,
49
106
  });
50
107
  }
51
- else {
52
- for (const file of match.matchedFiles) {
53
- storage.addTask(plan.plan_id, {
54
- review_id: match.module.id,
55
- review_file: match.module.file,
56
- files: [file],
57
- hint: null,
58
- model: match.module.model,
59
- });
60
- }
61
- }
62
108
  }
63
- // Finalize the plan (sets status to "ready", recounts tasks per module)
64
- return storage.finalizePlan(plan.plan_id);
109
+ // Finalize the plan (sets status to "ready", recounts tasks per module).
110
+ // After finalize, the orchestrator takes over — it flips step to "complete"
111
+ // when all tasks reach a terminal state. We set "reviewing" here as the
112
+ // intermediate so the UI sees the transition immediately on plan load.
113
+ const finalized = storage.finalizePlan(plan.plan_id);
114
+ if (Object.keys(finalized.tasks).length > 0) {
115
+ storage.setStep(plan.plan_id, "reviewing");
116
+ }
117
+ else {
118
+ // No tasks (no criteria matched, or all partitioners produced empty
119
+ // sets — though the validator forbids the latter). Mark complete.
120
+ storage.setStep(plan.plan_id, "complete");
121
+ }
122
+ return storage.getPlan(plan.plan_id);
65
123
  }
66
124
  //# sourceMappingURL=ReviewPlanBuilderService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReviewPlanBuilderService.js","sourceRoot":"","sources":["../../../src/services/review/ReviewPlanBuilderService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ReviewPlanBuilderService.js","sourceRoot":"","sources":["../../../src/services/review/ReviewPlanBuilderService.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ContextType, Issue, ModuleSummary, ReviewPlan, ReviewResults, ReviewSource, ReviewTask, TaskUsage } from "../../types/review.js";
1
+ import type { Issue, ModuleSummary, PartitionDecision, PipelineStep, PlanFailure, PlanInvocation, ReviewPlan, ReviewResults, ReviewTask, Scope, TaskUsage } from "../../types/review.js";
2
2
  /**
3
3
  * Manages the two-file storage format (plan.json + results.json) for deskcheck runs.
4
4
  *
@@ -29,7 +29,7 @@ export declare class ReviewStorageService {
29
29
  * Creates the timestamped directory and writes an initial plan.json with
30
30
  * status "planning" and empty collections.
31
31
  */
32
- createPlan(name: string, source: ReviewSource): ReviewPlan;
32
+ createPlan(name: string, scope: Scope, invocation: PlanInvocation): ReviewPlan;
33
33
  /** Read the plan.json for a given plan ID. */
34
34
  getPlan(planId: string): ReviewPlan;
35
35
  /**
@@ -56,18 +56,42 @@ export declare class ReviewStorageService {
56
56
  * appending a zero-padded incrementing suffix (e.g., "-001", "-002").
57
57
  * The task is created with status "pending" and null context fields.
58
58
  */
59
- addTask(planId: string, task: Omit<ReviewTask, "task_id" | "status" | "created_at" | "started_at" | "completed_at" | "context" | "context_type" | "symbol" | "prompt">): ReviewTask;
59
+ addTask(planId: string, task: Omit<ReviewTask, "task_id" | "status" | "created_at" | "started_at" | "completed_at" | "scope" | "focus" | "tools" | "error" | "prompt"> & {
60
+ focus?: string | null;
61
+ tools?: string[];
62
+ prompt?: string | null;
63
+ }): ReviewTask;
64
+ /** Record a partitioner decision for one criterion. */
65
+ setPartitionDecision(planId: string, decision: PartitionDecision): void;
66
+ /**
67
+ * Update the pipeline step the plan is currently in. When transitioning
68
+ * to a terminal step (`complete`/`failed`), also promotes `status` to the
69
+ * matching terminal value and stamps `completed_at` if not already set —
70
+ * this keeps the invariant `step terminal ⟺ status terminal`.
71
+ */
72
+ setStep(planId: string, step: PipelineStep): void;
73
+ /**
74
+ * Mark the plan as failed at a specific step. Sets `status = "failed"`,
75
+ * `step = "failed"`, and stamps the failure details. Idempotent — if the
76
+ * plan is already failed, the new failure overwrites the old.
77
+ */
78
+ setFailure(planId: string, failure: PlanFailure): void;
79
+ /** Persist the full SDK message stream from one reviewer's run. */
80
+ writeTaskLog(planId: string, taskId: string, messages: unknown[]): void;
81
+ /** Read a previously persisted reviewer transcript. */
82
+ getTaskLog(planId: string, taskId: string): unknown[];
83
+ /** Persist the full SDK message stream from one partitioner's run. */
84
+ writePartitionerLog(planId: string, reviewId: string, messages: unknown[]): void;
85
+ /** Read a previously persisted partitioner transcript. */
86
+ getPartitionerLog(planId: string, reviewId: string): unknown[];
60
87
  /**
61
88
  * Claim a pending task for execution.
62
89
  *
63
- * Sets the task status to "in_progress", fills in the context fields
64
- * (context type, content, symbol, prompt), and records the start time.
90
+ * Sets the task status to "in_progress", records the start time, and
91
+ * optionally stores the criterion prompt for later inspection.
65
92
  */
66
- claimTask(planId: string, taskId: string, context: {
67
- contextType: ContextType;
68
- content: string;
69
- symbol?: string;
70
- prompt: string;
93
+ claimTask(planId: string, taskId: string, options?: {
94
+ prompt?: string;
71
95
  }): ReviewTask;
72
96
  /**
73
97
  * Return tasks eligible for execution: those with status "pending" or
@@ -1 +1 @@
1
- {"version":3,"file":"ReviewStorageService.d.ts","sourceRoot":"","sources":["../../../src/services/review/ReviewStorageService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,KAAK,EAGL,aAAa,EACb,UAAU,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EAEV,SAAS,EAEV,MAAM,uBAAuB,CAAC;AAsC/B;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,+EAA+E;IAC/E,OAAO,CAAC,MAAM,CAAC,WAAW,CAAqB;gBAanC,UAAU,EAAE,MAAM;IAI9B;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ;IAoDhB,yCAAyC;IACzC,OAAO,CAAC,OAAO;IAQf;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,UAAU;IA0B1D,8CAA8C;IAC9C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU;IAMnC;;;OAGG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI;IAsBhC,0CAA0C;IAC1C,SAAS,IAAI,KAAK,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAqCF;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU;IAsBxC;;;;;;OAMG;IACH,OAAO,CACL,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,IAAI,CACR,UAAU,EACR,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,SAAS,GACT,cAAc,GACd,QAAQ,GACR,QAAQ,CACX,GACA,UAAU;IAkCb;;;;;OAKG;IACH,SAAS,CACP,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QACP,WAAW,EAAE,WAAW,CAAC;QACzB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,GACA,UAAU;IA6Bb;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;IAkB7C;;;;;;OAMG;IACH,YAAY,CACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,GACvB,IAAI;IAiDP;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;IA8C/F,iDAAiD;IACjD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa;IAgBzC,4DAA4D;IAC5D,eAAe,CACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EAAE,GAClB,IAAI;IASP,gDAAgD;IAChD,UAAU,CACR,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GACrC,IAAI;IAYP,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;CAkI9B"}
1
+ {"version":3,"file":"ReviewStorageService.d.ts","sourceRoot":"","sources":["../../../src/services/review/ReviewStorageService.ts"],"names":[],"mappings":"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"}