@j0hanz/code-review-analyst-mcp 1.5.3 → 1.6.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/dist/index.js +1 -35
- package/dist/lib/cli.d.ts +1 -0
- package/dist/lib/cli.js +35 -0
- package/dist/lib/context-budget.js +3 -3
- package/dist/lib/diff-budget.js +3 -6
- package/dist/lib/diff-cleaner.js +36 -15
- package/dist/lib/diff-parser.js +37 -50
- package/dist/lib/diff-store.js +21 -11
- package/dist/lib/env-config.js +4 -3
- package/dist/lib/errors.js +7 -5
- package/dist/lib/gemini-schema.js +2 -0
- package/dist/lib/gemini.js +106 -96
- package/dist/lib/model-config.js +2 -4
- package/dist/lib/tool-contracts.d.ts +10 -3
- package/dist/lib/tool-contracts.js +16 -2
- package/dist/lib/tool-factory.d.ts +31 -0
- package/dist/lib/tool-factory.js +181 -125
- package/dist/lib/tool-response.js +5 -8
- package/dist/prompts/index.js +16 -24
- package/dist/resources/index.js +8 -4
- package/dist/resources/instructions.js +25 -25
- package/dist/resources/tool-info.js +4 -11
- package/dist/schemas/inputs.js +8 -8
- package/dist/schemas/outputs.js +42 -66
- package/dist/server.js +13 -26
- package/dist/tools/analyze-complexity.js +8 -15
- package/dist/tools/analyze-pr-impact.js +7 -15
- package/dist/tools/detect-api-breaking.js +9 -16
- package/dist/tools/generate-diff.js +17 -4
- package/dist/tools/generate-review-summary.js +7 -14
- package/dist/tools/generate-test-plan.js +8 -15
- package/dist/tools/index.js +1 -4
- package/dist/tools/inspect-code-quality.js +19 -26
- package/dist/tools/suggest-search-replace.js +8 -15
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { validateContextBudget } from '../lib/context-budget.js';
|
|
2
2
|
import { computeDiffStatsAndSummaryFromFiles } from '../lib/diff-parser.js';
|
|
3
|
-
import { requireToolContract } from '../lib/tool-contracts.js';
|
|
3
|
+
import { buildStructuredToolRuntimeOptions, requireToolContract, } from '../lib/tool-contracts.js';
|
|
4
4
|
import { registerStructuredToolTask } from '../lib/tool-factory.js';
|
|
5
5
|
import { InspectCodeQualityInputSchema } from '../schemas/inputs.js';
|
|
6
6
|
import { CodeQualityOutputSchema, CodeQualityResultSchema, } from '../schemas/outputs.js';
|
|
@@ -10,12 +10,16 @@ const PATH_ESCAPE_REPLACEMENTS = {
|
|
|
10
10
|
'"': '\\"',
|
|
11
11
|
'\n': ' ',
|
|
12
12
|
'\r': ' ',
|
|
13
|
+
'<': '<',
|
|
14
|
+
'>': '>',
|
|
13
15
|
};
|
|
14
|
-
const PATH_ESCAPE_PATTERN = /["\n\r]/g;
|
|
16
|
+
const PATH_ESCAPE_PATTERN = /["\n\r<>]/g;
|
|
15
17
|
const SYSTEM_INSTRUCTION = `
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
Principal Engineer Code Review.
|
|
19
|
+
Source: Unified diff (primary), File excerpts (supplementary context).
|
|
20
|
+
Goal: Identify bugs, security, performance, maintainability.
|
|
21
|
+
Ignore style. Prioritize correctness/failure modes.
|
|
22
|
+
Return strict JSON.
|
|
19
23
|
`;
|
|
20
24
|
const TOOL_CONTRACT = requireToolContract('inspect_code_quality');
|
|
21
25
|
export function sanitizePath(path) {
|
|
@@ -38,21 +42,20 @@ function formatFileContext(files) {
|
|
|
38
42
|
if (!files || files.length === 0) {
|
|
39
43
|
return '';
|
|
40
44
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
return (FILE_CONTEXT_HEADING +
|
|
46
|
+
files
|
|
47
|
+
.map((file) => `
|
|
44
48
|
<<FILE path="${sanitizePath(file.path)}">>
|
|
45
49
|
${sanitizeContent(file.content)}
|
|
46
50
|
<<END_FILE>>
|
|
47
|
-
`)
|
|
48
|
-
|
|
49
|
-
return `${FILE_CONTEXT_HEADING}${fileBlocks.join('\n')}`;
|
|
51
|
+
`)
|
|
52
|
+
.join('\n'));
|
|
50
53
|
}
|
|
51
54
|
export function registerInspectCodeQualityTool(server) {
|
|
52
55
|
registerStructuredToolTask(server, {
|
|
53
56
|
name: 'inspect_code_quality',
|
|
54
57
|
title: 'Inspect Code Quality',
|
|
55
|
-
description: 'Deep code review. Prerequisite: generate_diff. Auto-infer repo/language/focus.
|
|
58
|
+
description: 'Deep code review. Prerequisite: generate_diff. Auto-infer repo/language/focus. Operates primarily on the diff; files are optional supplementary excerpts only.',
|
|
56
59
|
inputSchema: InspectCodeQualityInputSchema,
|
|
57
60
|
fullInputSchema: InspectCodeQualityInputSchema,
|
|
58
61
|
resultSchema: CodeQualityOutputSchema,
|
|
@@ -61,15 +64,7 @@ export function registerInspectCodeQualityTool(server) {
|
|
|
61
64
|
model: TOOL_CONTRACT.model,
|
|
62
65
|
timeoutMs: TOOL_CONTRACT.timeoutMs,
|
|
63
66
|
maxOutputTokens: TOOL_CONTRACT.maxOutputTokens,
|
|
64
|
-
...(TOOL_CONTRACT
|
|
65
|
-
? { thinkingLevel: TOOL_CONTRACT.thinkingLevel }
|
|
66
|
-
: undefined),
|
|
67
|
-
...(TOOL_CONTRACT.temperature !== undefined
|
|
68
|
-
? { temperature: TOOL_CONTRACT.temperature }
|
|
69
|
-
: undefined),
|
|
70
|
-
...(TOOL_CONTRACT.deterministicJson !== undefined
|
|
71
|
-
? { deterministicJson: TOOL_CONTRACT.deterministicJson }
|
|
72
|
-
: undefined),
|
|
67
|
+
...buildStructuredToolRuntimeOptions(TOOL_CONTRACT),
|
|
73
68
|
progressContext: (input) => {
|
|
74
69
|
const fileCount = input.files?.length;
|
|
75
70
|
return fileCount ? `+${fileCount} files` : '';
|
|
@@ -83,10 +78,8 @@ export function registerInspectCodeQualityTool(server) {
|
|
|
83
78
|
formatOutput: (result) => {
|
|
84
79
|
const count = result.findings.length;
|
|
85
80
|
const total = result.totalFindings ?? count;
|
|
86
|
-
const findingsSuffix = count < total
|
|
87
|
-
|
|
88
|
-
: `${count} findings reported.`;
|
|
89
|
-
return `Code Quality Inspection: ${result.summary}\n${findingsSuffix}`;
|
|
81
|
+
const findingsSuffix = count < total ? `${count} of ${total} findings.` : `${count} findings.`;
|
|
82
|
+
return `${result.summary}\n${findingsSuffix}`;
|
|
90
83
|
},
|
|
91
84
|
transformResult: (input, result) => {
|
|
92
85
|
const totalFindings = result.findings.length;
|
|
@@ -101,7 +94,7 @@ export function registerInspectCodeQualityTool(server) {
|
|
|
101
94
|
const languageLine = formatOptionalLine('Language', input.language);
|
|
102
95
|
const maxFindingsLine = formatOptionalLine('Max Findings', input.maxFindings);
|
|
103
96
|
const noFilesNote = !input.files?.length
|
|
104
|
-
? '\nNote: No file
|
|
97
|
+
? '\nNote: No file excerpts provided. Review based on diff only; leave contextualInsights empty.'
|
|
105
98
|
: '';
|
|
106
99
|
return {
|
|
107
100
|
systemInstruction: SYSTEM_INSTRUCTION,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { extractChangedPathsFromFiles } from '../lib/diff-parser.js';
|
|
2
|
-
import { requireToolContract } from '../lib/tool-contracts.js';
|
|
2
|
+
import { buildStructuredToolRuntimeOptions, requireToolContract, } from '../lib/tool-contracts.js';
|
|
3
3
|
import { registerStructuredToolTask } from '../lib/tool-factory.js';
|
|
4
4
|
import { SuggestSearchReplaceInputSchema } from '../schemas/inputs.js';
|
|
5
5
|
import { SearchReplaceResultSchema } from '../schemas/outputs.js';
|
|
6
6
|
const SYSTEM_INSTRUCTION = `
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
Code Remediation Expert.
|
|
8
|
+
Generate minimal search/replace blocks for described issue.
|
|
9
|
+
CRITICAL: 'search' must be verbatim (exact whitespace/indentation).
|
|
10
|
+
No out-of-scope changes. Omit if imprecise.
|
|
11
|
+
Return strict JSON.
|
|
11
12
|
`;
|
|
12
13
|
const TOOL_CONTRACT = requireToolContract('suggest_search_replace');
|
|
13
14
|
function formatPatchCount(count) {
|
|
@@ -25,21 +26,13 @@ export function registerSuggestSearchReplaceTool(server) {
|
|
|
25
26
|
model: TOOL_CONTRACT.model,
|
|
26
27
|
timeoutMs: TOOL_CONTRACT.timeoutMs,
|
|
27
28
|
maxOutputTokens: TOOL_CONTRACT.maxOutputTokens,
|
|
28
|
-
...(TOOL_CONTRACT
|
|
29
|
-
? { thinkingLevel: TOOL_CONTRACT.thinkingLevel }
|
|
30
|
-
: undefined),
|
|
31
|
-
...(TOOL_CONTRACT.temperature !== undefined
|
|
32
|
-
? { temperature: TOOL_CONTRACT.temperature }
|
|
33
|
-
: undefined),
|
|
34
|
-
...(TOOL_CONTRACT.deterministicJson !== undefined
|
|
35
|
-
? { deterministicJson: TOOL_CONTRACT.deterministicJson }
|
|
36
|
-
: undefined),
|
|
29
|
+
...buildStructuredToolRuntimeOptions(TOOL_CONTRACT),
|
|
37
30
|
requiresDiff: true,
|
|
38
31
|
formatOutcome: (result) => formatPatchCount(result.blocks.length),
|
|
39
32
|
formatOutput: (result) => {
|
|
40
33
|
const count = result.blocks.length;
|
|
41
34
|
const patches = formatPatchCount(count);
|
|
42
|
-
return `${result.summary}\n${patches} •
|
|
35
|
+
return `${result.summary}\n${patches} • ${result.validationChecklist.join(' | ')}`;
|
|
43
36
|
},
|
|
44
37
|
buildPrompt: (input, ctx) => {
|
|
45
38
|
const diff = ctx.diffSlot?.diff ?? '';
|