@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.
- package/README.md +78 -84
- package/build/cli.js +129 -23
- package/build/cli.js.map +1 -1
- package/build/config/loader.d.ts.map +1 -1
- package/build/config/loader.js +2 -1
- package/build/config/loader.js.map +1 -1
- package/build/config/types.d.ts +2 -1
- package/build/config/types.d.ts.map +1 -1
- package/build/mcp/tools.d.ts.map +1 -1
- package/build/mcp/tools.js +25 -49
- package/build/mcp/tools.js.map +1 -1
- package/build/prompts/ExecutorPrompt.d.ts +4 -2
- package/build/prompts/ExecutorPrompt.d.ts.map +1 -1
- package/build/prompts/ExecutorPrompt.js +40 -33
- package/build/prompts/ExecutorPrompt.js.map +1 -1
- package/build/prompts/PartitionerPrompt.d.ts +12 -0
- package/build/prompts/PartitionerPrompt.d.ts.map +1 -0
- package/build/prompts/PartitionerPrompt.js +54 -0
- package/build/prompts/PartitionerPrompt.js.map +1 -0
- package/build/prompts/ResolverPrompt.d.ts +11 -0
- package/build/prompts/ResolverPrompt.d.ts.map +1 -0
- package/build/prompts/ResolverPrompt.js +45 -0
- package/build/prompts/ResolverPrompt.js.map +1 -0
- package/build/renderers/review/MarkdownRenderer.js +5 -2
- package/build/renderers/review/MarkdownRenderer.js.map +1 -1
- package/build/renderers/review/TerminalRenderer.js +5 -2
- package/build/renderers/review/TerminalRenderer.js.map +1 -1
- package/build/renderers/review/WatchRenderer.d.ts.map +1 -1
- package/build/renderers/review/WatchRenderer.js +10 -1
- package/build/renderers/review/WatchRenderer.js.map +1 -1
- package/build/server/controllers/ReviewController.d.ts +12 -3
- package/build/server/controllers/ReviewController.d.ts.map +1 -1
- package/build/server/controllers/ReviewController.js +50 -6
- package/build/server/controllers/ReviewController.js.map +1 -1
- package/build/server/server.d.ts.map +1 -1
- package/build/server/server.js +22 -1
- package/build/server/server.js.map +1 -1
- package/build/services/ExecutorService.d.ts +17 -2
- package/build/services/ExecutorService.d.ts.map +1 -1
- package/build/services/ExecutorService.js +37 -5
- package/build/services/ExecutorService.js.map +1 -1
- package/build/services/FindingsParserService.d.ts +1 -8
- package/build/services/FindingsParserService.d.ts.map +1 -1
- package/build/services/FindingsParserService.js +20 -45
- package/build/services/FindingsParserService.js.map +1 -1
- package/build/services/criteria/module-parser.d.ts +1 -1
- package/build/services/criteria/module-parser.d.ts.map +1 -1
- package/build/services/criteria/module-parser.js +20 -16
- package/build/services/criteria/module-parser.js.map +1 -1
- package/build/services/review/CodeSnippetService.d.ts +10 -0
- package/build/services/review/CodeSnippetService.d.ts.map +1 -0
- package/build/services/review/CodeSnippetService.js +54 -0
- package/build/services/review/CodeSnippetService.js.map +1 -0
- package/build/services/review/ReviewInputResolverService.d.ts +25 -0
- package/build/services/review/ReviewInputResolverService.d.ts.map +1 -0
- package/build/services/review/ReviewInputResolverService.js +106 -0
- package/build/services/review/ReviewInputResolverService.js.map +1 -0
- package/build/services/review/ReviewOrchestratorService.d.ts.map +1 -1
- package/build/services/review/ReviewOrchestratorService.js +21 -20
- package/build/services/review/ReviewOrchestratorService.js.map +1 -1
- package/build/services/review/ReviewPartitionerService.d.ts +46 -0
- package/build/services/review/ReviewPartitionerService.d.ts.map +1 -0
- package/build/services/review/ReviewPartitionerService.js +208 -0
- package/build/services/review/ReviewPartitionerService.js.map +1 -0
- package/build/services/review/ReviewPlanBuilderService.d.ts +25 -7
- package/build/services/review/ReviewPlanBuilderService.d.ts.map +1 -1
- package/build/services/review/ReviewPlanBuilderService.js +88 -30
- package/build/services/review/ReviewPlanBuilderService.js.map +1 -1
- package/build/services/review/ReviewStorageService.d.ts +34 -10
- package/build/services/review/ReviewStorageService.d.ts.map +1 -1
- package/build/services/review/ReviewStorageService.js +100 -14
- package/build/services/review/ReviewStorageService.js.map +1 -1
- package/build/services/testing/TestRunnerService.d.ts.map +1 -1
- package/build/services/testing/TestRunnerService.js +10 -8
- package/build/services/testing/TestRunnerService.js.map +1 -1
- package/build/types/criteria.d.ts +8 -6
- package/build/types/criteria.d.ts.map +1 -1
- package/build/types/review.d.ts +123 -28
- package/build/types/review.d.ts.map +1 -1
- package/package.json +3 -1
- package/ui/dist/index.html +12 -63
- package/build/prompts/PlannerPrompt.d.ts +0 -12
- package/build/prompts/PlannerPrompt.d.ts.map +0 -1
- package/build/prompts/PlannerPrompt.js +0 -34
- package/build/prompts/PlannerPrompt.js.map +0 -1
- package/build/services/review/ReviewContextExtractorService.d.ts +0 -17
- package/build/services/review/ReviewContextExtractorService.d.ts.map +0 -1
- package/build/services/review/ReviewContextExtractorService.js +0 -69
- package/build/services/review/ReviewContextExtractorService.js.map +0 -1
- package/build/services/review/ReviewPlannerService.d.ts +0 -29
- package/build/services/review/ReviewPlannerService.d.ts.map +0 -1
- package/build/services/review/ReviewPlannerService.js +0 -122
- package/build/services/review/ReviewPlannerService.js.map +0 -1
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Build the system prompt for the planner agent.
|
|
3
|
-
*
|
|
4
|
-
* The planner agent interprets the user's natural language intent, uses
|
|
5
|
-
* git/filesystem tools to discover which files to review, and calls the
|
|
6
|
-
* create_plan MCP tool to create the plan.
|
|
7
|
-
*
|
|
8
|
-
* @param moduleDescriptions - Pre-formatted string listing available criteria.
|
|
9
|
-
* @returns The full system prompt for the planner agent.
|
|
10
|
-
*/
|
|
11
|
-
export declare function buildPlannerPrompt(moduleDescriptions: string): string;
|
|
12
|
-
//# sourceMappingURL=PlannerPrompt.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PlannerPrompt.d.ts","sourceRoot":"","sources":["../../src/prompts/PlannerPrompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAsBrE"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Build the system prompt for the planner agent.
|
|
3
|
-
*
|
|
4
|
-
* The planner agent interprets the user's natural language intent, uses
|
|
5
|
-
* git/filesystem tools to discover which files to review, and calls the
|
|
6
|
-
* create_plan MCP tool to create the plan.
|
|
7
|
-
*
|
|
8
|
-
* @param moduleDescriptions - Pre-formatted string listing available criteria.
|
|
9
|
-
* @returns The full system prompt for the planner agent.
|
|
10
|
-
*/
|
|
11
|
-
export function buildPlannerPrompt(moduleDescriptions) {
|
|
12
|
-
return `You are a deskcheck planner. The user will tell you what they want to check. Your job is to figure out which files are involved and call the create_plan tool.
|
|
13
|
-
|
|
14
|
-
## Available Criteria
|
|
15
|
-
|
|
16
|
-
${moduleDescriptions}
|
|
17
|
-
|
|
18
|
-
## How to Determine Files
|
|
19
|
-
|
|
20
|
-
- If the user mentions a **directory** (e.g., "everything in app/Services/"): use Bash to list all files recursively: \`find <path> -type f -name "*.php" -o -name "*.ts" -o -name "*.vue"\` or similar. Then pass ALL those file paths to create_plan.
|
|
21
|
-
- If the user mentions a **branch** or "changes" or "diff": run \`git diff <branch> --name-only\` to get changed files.
|
|
22
|
-
- If the user mentions a **specific file**: use that file path directly.
|
|
23
|
-
- If the user mentions a **function/method name** and a file: use the file path, set source_type to "symbol".
|
|
24
|
-
- If the user is vague: use Bash to explore the filesystem and figure out what files are relevant.
|
|
25
|
-
|
|
26
|
-
## What to Do
|
|
27
|
-
|
|
28
|
-
1. Figure out which files to check (use Bash to run commands like find, ls, git diff)
|
|
29
|
-
2. Call the create_plan tool with the file list and appropriate source type (use "file" for directory/file reviews, "diff" for branch comparisons)
|
|
30
|
-
3. Report what you created
|
|
31
|
-
|
|
32
|
-
You MUST call the create_plan tool. Do NOT review code yourself. Your only job is to determine the file list and call create_plan.`;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=PlannerPrompt.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PlannerPrompt.js","sourceRoot":"","sources":["../../src/prompts/PlannerPrompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,kBAA0B;IAC3D,OAAO;;;;EAIP,kBAAkB;;;;;;;;;;;;;;;;mIAgB+G,CAAC;AACpI,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { ContextType } from "../../types/review.js";
|
|
2
|
-
/** The result of extracting review context for a task. */
|
|
3
|
-
export interface ExtractedContext {
|
|
4
|
-
contextType: ContextType;
|
|
5
|
-
content: string;
|
|
6
|
-
symbol: string | null;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Extract review context based on the source type.
|
|
10
|
-
*
|
|
11
|
-
* - diff: runs `git diff` for the given files against the source target
|
|
12
|
-
* - file: reads each file's content from disk
|
|
13
|
-
* - symbol: reads the file containing the symbol (symbol identification
|
|
14
|
-
* is left to the executor agent which has Read/Grep tools)
|
|
15
|
-
*/
|
|
16
|
-
export declare function extractContext(sourceType: ContextType, sourceTarget: string, files: string[], projectRoot: string, symbol?: string): ExtractedContext;
|
|
17
|
-
//# sourceMappingURL=ReviewContextExtractorService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewContextExtractorService.d.ts","sourceRoot":"","sources":["../../../src/services/review/ReviewContextExtractorService.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,WAAW,EACvB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,gBAAgB,CAsBlB"}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { execFileSync } from "node:child_process";
|
|
4
|
-
/**
|
|
5
|
-
* Extract review context based on the source type.
|
|
6
|
-
*
|
|
7
|
-
* - diff: runs `git diff` for the given files against the source target
|
|
8
|
-
* - file: reads each file's content from disk
|
|
9
|
-
* - symbol: reads the file containing the symbol (symbol identification
|
|
10
|
-
* is left to the executor agent which has Read/Grep tools)
|
|
11
|
-
*/
|
|
12
|
-
export function extractContext(sourceType, sourceTarget, files, projectRoot, symbol) {
|
|
13
|
-
let content;
|
|
14
|
-
switch (sourceType) {
|
|
15
|
-
case "diff":
|
|
16
|
-
content = extractDiffContext(sourceTarget, files, projectRoot);
|
|
17
|
-
break;
|
|
18
|
-
case "file":
|
|
19
|
-
content = extractFileContext(files, projectRoot);
|
|
20
|
-
break;
|
|
21
|
-
case "symbol":
|
|
22
|
-
content = extractFileContext(files, projectRoot);
|
|
23
|
-
break;
|
|
24
|
-
default:
|
|
25
|
-
throw new Error(`Unknown source type: ${sourceType}`);
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
contextType: sourceType,
|
|
29
|
-
content,
|
|
30
|
-
symbol: symbol ?? null,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
/** Run git diff for each file and concatenate results. */
|
|
34
|
-
function extractDiffContext(target, files, projectRoot) {
|
|
35
|
-
const parts = [];
|
|
36
|
-
for (const file of files) {
|
|
37
|
-
try {
|
|
38
|
-
const diff = execFileSync("git", ["diff", target, "--", file], {
|
|
39
|
-
cwd: projectRoot,
|
|
40
|
-
encoding: "utf-8",
|
|
41
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
42
|
-
timeout: 30_000,
|
|
43
|
-
});
|
|
44
|
-
if (diff.trim().length > 0) {
|
|
45
|
-
parts.push(diff);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
console.error(`Warning: git diff failed for ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return parts.join("\n");
|
|
53
|
-
}
|
|
54
|
-
/** Read each file's content and concatenate with file path headers. */
|
|
55
|
-
function extractFileContext(files, projectRoot) {
|
|
56
|
-
const parts = [];
|
|
57
|
-
for (const file of files) {
|
|
58
|
-
try {
|
|
59
|
-
const absolutePath = path.resolve(projectRoot, file);
|
|
60
|
-
const content = fs.readFileSync(absolutePath, "utf-8");
|
|
61
|
-
parts.push(`--- ${file} ---\n${content}`);
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
console.error(`Warning: could not read ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return parts.join("\n\n");
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=ReviewContextExtractorService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewContextExtractorService.js","sourceRoot":"","sources":["../../../src/services/review/ReviewContextExtractorService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAUlD;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,UAAuB,EACvB,YAAoB,EACpB,KAAe,EACf,WAAmB,EACnB,MAAe;IAEf,IAAI,OAAe,CAAC;IAEpB,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,GAAG,kBAAkB,CAAC,YAAY,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,MAAM;YACT,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACjD,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACjD,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,WAAW,EAAE,UAAU;QACvB,OAAO;QACP,MAAM,EAAE,MAAM,IAAI,IAAI;KACvB,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,SAAS,kBAAkB,CACzB,MAAc,EACd,KAAe,EACf,WAAmB;IAEnB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;gBAC7D,GAAG,EAAE,WAAW;gBAChB,QAAQ,EAAE,OAAO;gBACjB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;gBAC3B,OAAO,EAAE,MAAM;aAChB,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,gCAAgC,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAClG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,uEAAuE;AACvE,SAAS,kBAAkB,CACzB,KAAe,EACf,WAAmB;IAEnB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO,EAAE,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,2BAA2B,IAAI,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { ReviewConfig } from "../../config/types.js";
|
|
2
|
-
import type { ReviewPlan } from "../../types/review.js";
|
|
3
|
-
/**
|
|
4
|
-
* Plans review tasks by delegating intent detection to an Agent SDK agent.
|
|
5
|
-
*
|
|
6
|
-
* Instead of parsing user intent with regex heuristics, the planner spawns
|
|
7
|
-
* a Claude agent that has access to git, the filesystem, and review planning
|
|
8
|
-
* tools. The agent interprets what the user wants to review and creates the
|
|
9
|
-
* plan accordingly.
|
|
10
|
-
*/
|
|
11
|
-
export declare class ReviewPlannerService {
|
|
12
|
-
private readonly config;
|
|
13
|
-
private readonly projectRoot;
|
|
14
|
-
constructor(config: ReviewConfig, projectRoot: string);
|
|
15
|
-
/**
|
|
16
|
-
* Create a review plan from natural language input.
|
|
17
|
-
*
|
|
18
|
-
* Spawns a planner agent that:
|
|
19
|
-
* 1. Interprets the user's intent (what files/branch/symbol to review)
|
|
20
|
-
* 2. Uses git/filesystem to get the list of files
|
|
21
|
-
* 3. Calls the planning MCP tools to create the plan
|
|
22
|
-
*
|
|
23
|
-
* The planner agent has access to an in-process MCP server with tools
|
|
24
|
-
* for creating plans and tasks, plus standard git/read tools for
|
|
25
|
-
* discovering what to review.
|
|
26
|
-
*/
|
|
27
|
-
plan(input: string, criteriaFilter?: string[]): Promise<ReviewPlan>;
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=ReviewPlannerService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewPlannerService.d.ts","sourceRoot":"","sources":["../../../src/services/review/ReviewPlannerService.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;;GAOG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM;IAKrD;;;;;;;;;;;OAWG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;CAwG1E"}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
5
|
-
import { discoverModules, filterModules } from "../criteria/module-parser.js";
|
|
6
|
-
import { buildPlanWithTasks } from "./ReviewPlanBuilderService.js";
|
|
7
|
-
import { ReviewStorageService } from "./ReviewStorageService.js";
|
|
8
|
-
import { buildPlannerPrompt } from "../../prompts/PlannerPrompt.js";
|
|
9
|
-
/**
|
|
10
|
-
* Plans review tasks by delegating intent detection to an Agent SDK agent.
|
|
11
|
-
*
|
|
12
|
-
* Instead of parsing user intent with regex heuristics, the planner spawns
|
|
13
|
-
* a Claude agent that has access to git, the filesystem, and review planning
|
|
14
|
-
* tools. The agent interprets what the user wants to review and creates the
|
|
15
|
-
* plan accordingly.
|
|
16
|
-
*/
|
|
17
|
-
export class ReviewPlannerService {
|
|
18
|
-
config;
|
|
19
|
-
projectRoot;
|
|
20
|
-
constructor(config, projectRoot) {
|
|
21
|
-
this.config = config;
|
|
22
|
-
this.projectRoot = projectRoot;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Create a review plan from natural language input.
|
|
26
|
-
*
|
|
27
|
-
* Spawns a planner agent that:
|
|
28
|
-
* 1. Interprets the user's intent (what files/branch/symbol to review)
|
|
29
|
-
* 2. Uses git/filesystem to get the list of files
|
|
30
|
-
* 3. Calls the planning MCP tools to create the plan
|
|
31
|
-
*
|
|
32
|
-
* The planner agent has access to an in-process MCP server with tools
|
|
33
|
-
* for creating plans and tasks, plus standard git/read tools for
|
|
34
|
-
* discovering what to review.
|
|
35
|
-
*/
|
|
36
|
-
async plan(input, criteriaFilter) {
|
|
37
|
-
const storageDir = path.resolve(this.projectRoot, this.config.storage_dir);
|
|
38
|
-
const storage = new ReviewStorageService(storageDir);
|
|
39
|
-
const modulesDir = path.resolve(this.projectRoot, this.config.modules_dir);
|
|
40
|
-
let modules = discoverModules(modulesDir);
|
|
41
|
-
if (criteriaFilter && criteriaFilter.length > 0) {
|
|
42
|
-
modules = filterModules(modules, criteriaFilter);
|
|
43
|
-
}
|
|
44
|
-
// Build the module summary for the agent's context
|
|
45
|
-
const moduleDescriptions = modules.map((m) => `- ${m.id} (severity: ${m.severity}, model: ${m.model})\n Globs: ${m.globs.join(", ")}\n Mode: ${m.mode}`).join("\n");
|
|
46
|
-
// Track the plan ID created by the agent
|
|
47
|
-
let createdPlanId = null;
|
|
48
|
-
// Create an in-process MCP server with planning tools
|
|
49
|
-
const plannerServer = createSdkMcpServer({
|
|
50
|
-
name: "deskcheck-planner",
|
|
51
|
-
version: "0.1.0",
|
|
52
|
-
tools: [
|
|
53
|
-
tool("create_plan", "Create a review plan and tasks. Call this once you know what files to review.", {
|
|
54
|
-
name: z.string().describe("Human-readable name for this review, e.g. 'changes against develop' or 'full review: Commission.php'"),
|
|
55
|
-
source_type: z.enum(["diff", "file", "symbol"]).describe("Type of review: diff (branch comparison), file (full file), symbol (specific function/method)"),
|
|
56
|
-
source_target: z.string().describe("The target: branch name for diff, file path for file, symbol name for symbol"),
|
|
57
|
-
source_file: z.string().optional().describe("For symbol mode only: the file containing the symbol"),
|
|
58
|
-
files: z.array(z.string()).describe("List of file paths to review"),
|
|
59
|
-
}, async (args) => {
|
|
60
|
-
const source = {
|
|
61
|
-
type: args.source_type,
|
|
62
|
-
target: args.source_target,
|
|
63
|
-
...(args.source_file ? { file: args.source_file } : {}),
|
|
64
|
-
};
|
|
65
|
-
const finalPlan = buildPlanWithTasks(storage, args.name, source, args.files, modules);
|
|
66
|
-
createdPlanId = finalPlan.plan_id;
|
|
67
|
-
const taskCount = Object.keys(finalPlan.tasks).length;
|
|
68
|
-
const moduleCount = Object.keys(finalPlan.modules).length;
|
|
69
|
-
return {
|
|
70
|
-
content: [{
|
|
71
|
-
type: "text",
|
|
72
|
-
text: `Plan created: ${finalPlan.plan_id}\n${taskCount} tasks across ${moduleCount} modules\n${finalPlan.matched_files.length} files matched, ${finalPlan.unmatched_files.length} not covered`,
|
|
73
|
-
}],
|
|
74
|
-
};
|
|
75
|
-
}),
|
|
76
|
-
],
|
|
77
|
-
});
|
|
78
|
-
// Build planner model — use short names (haiku/sonnet/opus)
|
|
79
|
-
// The Agent SDK resolves these to full model IDs internally
|
|
80
|
-
const plannerModel = this.config.agents.planner.model ?? "haiku";
|
|
81
|
-
const systemPrompt = buildPlannerPrompt(moduleDescriptions);
|
|
82
|
-
// Spawn the planner agent with a 5-minute timeout
|
|
83
|
-
const abortController = new AbortController();
|
|
84
|
-
const timeout = setTimeout(() => abortController.abort(), 5 * 60 * 1000);
|
|
85
|
-
try {
|
|
86
|
-
for await (const message of query({
|
|
87
|
-
prompt: input,
|
|
88
|
-
options: {
|
|
89
|
-
model: plannerModel,
|
|
90
|
-
systemPrompt,
|
|
91
|
-
tools: [
|
|
92
|
-
"Bash",
|
|
93
|
-
"Read",
|
|
94
|
-
"Glob",
|
|
95
|
-
"Grep",
|
|
96
|
-
"mcp__deskcheck-planner__*",
|
|
97
|
-
],
|
|
98
|
-
permissionMode: "bypassPermissions",
|
|
99
|
-
maxTurns: 15,
|
|
100
|
-
cwd: this.projectRoot,
|
|
101
|
-
persistSession: false,
|
|
102
|
-
abortController,
|
|
103
|
-
mcpServers: {
|
|
104
|
-
"deskcheck-planner": plannerServer,
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
})) {
|
|
108
|
-
if (message.type === "result" && message.subtype !== "success") {
|
|
109
|
-
throw new Error(`Planner agent failed: ${JSON.stringify(message)}`);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
finally {
|
|
114
|
-
clearTimeout(timeout);
|
|
115
|
-
}
|
|
116
|
-
if (!createdPlanId) {
|
|
117
|
-
throw new Error("Planner agent did not create a plan. It may not have understood the request.");
|
|
118
|
-
}
|
|
119
|
-
return storage.getPlan(createdPlanId);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
//# sourceMappingURL=ReviewPlannerService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ReviewPlannerService.js","sourceRoot":"","sources":["../../../src/services/review/ReviewPlannerService.ts"],"names":[],"mappings":"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"}
|