@j0hanz/code-review-analyst-mcp 1.1.0 → 1.2.1
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 +203 -193
- package/dist/index.js +18 -15
- package/dist/instructions.md +83 -58
- package/dist/lib/context-budget.d.ts +8 -0
- package/dist/lib/context-budget.js +30 -0
- package/dist/lib/diff-budget.d.ts +3 -1
- package/dist/lib/diff-budget.js +16 -19
- package/dist/lib/diff-parser.d.ts +34 -0
- package/dist/lib/diff-parser.js +114 -0
- package/dist/lib/env-config.d.ts +5 -0
- package/dist/lib/env-config.js +24 -0
- package/dist/lib/errors.d.ts +1 -0
- package/dist/lib/errors.js +9 -6
- package/dist/lib/gemini-schema.d.ts +3 -1
- package/dist/lib/gemini-schema.js +18 -17
- package/dist/lib/gemini.d.ts +1 -0
- package/dist/lib/gemini.js +220 -112
- package/dist/lib/model-config.d.ts +17 -0
- package/dist/lib/model-config.js +19 -0
- package/dist/lib/tool-factory.d.ts +22 -8
- package/dist/lib/tool-factory.js +302 -67
- package/dist/lib/tool-response.d.ts +9 -2
- package/dist/lib/tool-response.js +29 -14
- package/dist/lib/types.d.ts +8 -3
- package/dist/prompts/index.js +35 -15
- package/dist/resources/index.js +10 -9
- package/dist/schemas/inputs.d.ts +27 -15
- package/dist/schemas/inputs.js +59 -21
- package/dist/schemas/outputs.d.ts +130 -7
- package/dist/schemas/outputs.js +170 -40
- package/dist/server.d.ts +5 -1
- package/dist/server.js +32 -24
- package/dist/tools/analyze-pr-impact.d.ts +2 -0
- package/dist/tools/analyze-pr-impact.js +46 -0
- package/dist/tools/generate-review-summary.d.ts +2 -0
- package/dist/tools/generate-review-summary.js +67 -0
- package/dist/tools/generate-test-plan.d.ts +2 -0
- package/dist/tools/generate-test-plan.js +56 -0
- package/dist/tools/index.js +10 -6
- package/dist/tools/inspect-code-quality.d.ts +4 -0
- package/dist/tools/inspect-code-quality.js +111 -0
- package/dist/tools/suggest-search-replace.d.ts +2 -0
- package/dist/tools/suggest-search-replace.js +49 -0
- package/package.json +3 -2
- package/dist/tools/review-diff.d.ts +0 -2
- package/dist/tools/review-diff.js +0 -42
- package/dist/tools/risk-score.d.ts +0 -2
- package/dist/tools/risk-score.js +0 -34
- package/dist/tools/suggest-patch.d.ts +0 -2
- package/dist/tools/suggest-patch.js +0 -35
package/dist/schemas/inputs.d.ts
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const FileContextSchema: z.ZodObject<{
|
|
3
|
+
path: z.ZodString;
|
|
4
|
+
content: z.ZodString;
|
|
5
|
+
}, z.core.$strict>;
|
|
6
|
+
export declare const AnalyzePrImpactInputSchema: z.ZodObject<{
|
|
3
7
|
diff: z.ZodString;
|
|
4
8
|
repository: z.ZodString;
|
|
5
9
|
language: z.ZodOptional<z.ZodString>;
|
|
6
|
-
focusAreas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
7
|
-
maxFindings: z.ZodOptional<z.ZodNumber>;
|
|
8
10
|
}, z.core.$strict>;
|
|
9
|
-
export declare const
|
|
11
|
+
export declare const GenerateReviewSummaryInputSchema: z.ZodObject<{
|
|
10
12
|
diff: z.ZodString;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
medium: "medium";
|
|
14
|
-
high: "high";
|
|
15
|
-
}>>;
|
|
13
|
+
repository: z.ZodString;
|
|
14
|
+
language: z.ZodOptional<z.ZodString>;
|
|
16
15
|
}, z.core.$strict>;
|
|
17
|
-
export declare const
|
|
16
|
+
export declare const InspectCodeQualityInputSchema: z.ZodObject<{
|
|
17
|
+
diff: z.ZodString;
|
|
18
|
+
repository: z.ZodString;
|
|
19
|
+
language: z.ZodOptional<z.ZodString>;
|
|
20
|
+
focusAreas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
|
+
maxFindings: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
files: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
23
|
+
path: z.ZodString;
|
|
24
|
+
content: z.ZodString;
|
|
25
|
+
}, z.core.$strict>>>;
|
|
26
|
+
}, z.core.$strict>;
|
|
27
|
+
export declare const SuggestSearchReplaceInputSchema: z.ZodObject<{
|
|
18
28
|
diff: z.ZodString;
|
|
19
29
|
findingTitle: z.ZodString;
|
|
20
30
|
findingDetails: z.ZodString;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
export declare const GenerateTestPlanInputSchema: z.ZodObject<{
|
|
33
|
+
diff: z.ZodString;
|
|
34
|
+
repository: z.ZodString;
|
|
35
|
+
language: z.ZodOptional<z.ZodString>;
|
|
36
|
+
testFramework: z.ZodOptional<z.ZodString>;
|
|
37
|
+
maxTestCases: z.ZodOptional<z.ZodNumber>;
|
|
26
38
|
}, z.core.$strict>;
|
package/dist/schemas/inputs.js
CHANGED
|
@@ -1,50 +1,88 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
const INPUT_LIMITS = {
|
|
3
|
-
diff: { min: 10
|
|
3
|
+
diff: { min: 10 },
|
|
4
4
|
repository: { min: 1, max: 200 },
|
|
5
5
|
language: { min: 2, max: 32 },
|
|
6
|
+
fileContext: {
|
|
7
|
+
path: { min: 1, max: 500 },
|
|
8
|
+
content: { min: 0, max: 100_000 },
|
|
9
|
+
maxItems: 20,
|
|
10
|
+
},
|
|
6
11
|
focusArea: { min: 2, max: 80, maxItems: 12 },
|
|
7
12
|
maxFindings: { min: 1, max: 25 },
|
|
8
13
|
findingTitle: { min: 3, max: 160 },
|
|
9
14
|
findingDetails: { min: 10, max: 3_000 },
|
|
15
|
+
testFramework: { min: 1, max: 50 },
|
|
16
|
+
maxTestCases: { min: 1, max: 30 },
|
|
10
17
|
};
|
|
11
18
|
function createBoundedString(min, max, description) {
|
|
12
19
|
return z.string().min(min).max(max).describe(description);
|
|
13
20
|
}
|
|
21
|
+
function createOptionalBoundedString(min, max, description) {
|
|
22
|
+
return createBoundedString(min, max, description).optional();
|
|
23
|
+
}
|
|
24
|
+
function createLanguageSchema(description) {
|
|
25
|
+
return createOptionalBoundedString(INPUT_LIMITS.language.min, INPUT_LIMITS.language.max, description);
|
|
26
|
+
}
|
|
14
27
|
function createDiffSchema(description) {
|
|
15
|
-
return
|
|
28
|
+
return z
|
|
29
|
+
.string()
|
|
30
|
+
.min(INPUT_LIMITS.diff.min)
|
|
31
|
+
.describe(`${description} Budget is enforced at runtime via MAX_DIFF_CHARS (default 120,000 chars).`);
|
|
16
32
|
}
|
|
17
|
-
export const
|
|
33
|
+
export const FileContextSchema = z.strictObject({
|
|
34
|
+
path: createBoundedString(INPUT_LIMITS.fileContext.path.min, INPUT_LIMITS.fileContext.path.max, 'File path relative to repo root.'),
|
|
35
|
+
content: createBoundedString(INPUT_LIMITS.fileContext.content.min, INPUT_LIMITS.fileContext.content.max, 'Full file content.'),
|
|
36
|
+
});
|
|
37
|
+
export const AnalyzePrImpactInputSchema = z.strictObject({
|
|
38
|
+
diff: createDiffSchema('Unified diff text for the PR or commit.'),
|
|
39
|
+
repository: createBoundedString(INPUT_LIMITS.repository.min, INPUT_LIMITS.repository.max, 'Repository identifier, e.g. org/repo.'),
|
|
40
|
+
language: createLanguageSchema('Primary language to bias analysis.'),
|
|
41
|
+
});
|
|
42
|
+
export const GenerateReviewSummaryInputSchema = z.strictObject({
|
|
18
43
|
diff: createDiffSchema('Unified diff text for one PR or commit.'),
|
|
19
|
-
repository: createBoundedString(INPUT_LIMITS.repository.min, INPUT_LIMITS.repository.max, 'Repository identifier,
|
|
20
|
-
language:
|
|
44
|
+
repository: createBoundedString(INPUT_LIMITS.repository.min, INPUT_LIMITS.repository.max, 'Repository identifier, e.g. org/repo.'),
|
|
45
|
+
language: createLanguageSchema('Primary implementation language.'),
|
|
46
|
+
});
|
|
47
|
+
export const InspectCodeQualityInputSchema = z.strictObject({
|
|
48
|
+
diff: createDiffSchema('Unified diff text for in-depth analysis.'),
|
|
49
|
+
repository: createBoundedString(INPUT_LIMITS.repository.min, INPUT_LIMITS.repository.max, 'Repository identifier, e.g. org/repo.'),
|
|
50
|
+
language: createLanguageSchema('Primary language.'),
|
|
21
51
|
focusAreas: z
|
|
22
|
-
.array(createBoundedString(INPUT_LIMITS.focusArea.min, INPUT_LIMITS.focusArea.max, '
|
|
52
|
+
.array(createBoundedString(INPUT_LIMITS.focusArea.min, INPUT_LIMITS.focusArea.max, 'Focus area tag value.'))
|
|
23
53
|
.min(1)
|
|
24
54
|
.max(INPUT_LIMITS.focusArea.maxItems)
|
|
25
55
|
.optional()
|
|
26
|
-
.describe('
|
|
56
|
+
.describe('Specific areas to inspect: security, correctness, etc.'),
|
|
27
57
|
maxFindings: z
|
|
28
58
|
.number()
|
|
29
59
|
.int()
|
|
30
|
-
.min(
|
|
31
|
-
.max(
|
|
60
|
+
.min(1)
|
|
61
|
+
.max(25)
|
|
32
62
|
.optional()
|
|
33
63
|
.describe('Maximum number of findings to return.'),
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.enum(['low', 'medium', 'high'])
|
|
64
|
+
files: z
|
|
65
|
+
.array(FileContextSchema)
|
|
66
|
+
.min(1)
|
|
67
|
+
.max(INPUT_LIMITS.fileContext.maxItems)
|
|
39
68
|
.optional()
|
|
40
|
-
.describe('
|
|
69
|
+
.describe('Full file contents for context-aware analysis. Provide the files changed in the diff for best results.'),
|
|
41
70
|
});
|
|
42
|
-
export const
|
|
43
|
-
diff: createDiffSchema('Unified diff
|
|
44
|
-
findingTitle: createBoundedString(INPUT_LIMITS.findingTitle.min, INPUT_LIMITS.findingTitle.max, 'Short title of the finding
|
|
71
|
+
export const SuggestSearchReplaceInputSchema = z.strictObject({
|
|
72
|
+
diff: createDiffSchema('Unified diff that contains the issue to fix.'),
|
|
73
|
+
findingTitle: createBoundedString(INPUT_LIMITS.findingTitle.min, INPUT_LIMITS.findingTitle.max, 'Short title of the finding to fix.'),
|
|
45
74
|
findingDetails: createBoundedString(INPUT_LIMITS.findingDetails.min, INPUT_LIMITS.findingDetails.max, 'Detailed explanation of the bug or risk.'),
|
|
46
|
-
|
|
47
|
-
|
|
75
|
+
});
|
|
76
|
+
export const GenerateTestPlanInputSchema = z.strictObject({
|
|
77
|
+
diff: createDiffSchema('Unified diff to generate tests for.'),
|
|
78
|
+
repository: createBoundedString(INPUT_LIMITS.repository.min, INPUT_LIMITS.repository.max, 'Repository identifier, e.g. org/repo.'),
|
|
79
|
+
language: createLanguageSchema('Primary language.'),
|
|
80
|
+
testFramework: createOptionalBoundedString(INPUT_LIMITS.testFramework.min, INPUT_LIMITS.testFramework.max, 'Test framework to use, e.g. jest, vitest, pytest, node:test.'),
|
|
81
|
+
maxTestCases: z
|
|
82
|
+
.number()
|
|
83
|
+
.int()
|
|
84
|
+
.min(INPUT_LIMITS.maxTestCases.min)
|
|
85
|
+
.max(INPUT_LIMITS.maxTestCases.max)
|
|
48
86
|
.optional()
|
|
49
|
-
.describe('
|
|
87
|
+
.describe('Maximum number of test cases to return.'),
|
|
50
88
|
});
|
|
@@ -5,6 +5,15 @@ export declare const DefaultOutputSchema: z.ZodObject<{
|
|
|
5
5
|
error: z.ZodOptional<z.ZodObject<{
|
|
6
6
|
code: z.ZodString;
|
|
7
7
|
message: z.ZodString;
|
|
8
|
+
retryable: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
10
|
+
validation: "validation";
|
|
11
|
+
budget: "budget";
|
|
12
|
+
upstream: "upstream";
|
|
13
|
+
timeout: "timeout";
|
|
14
|
+
cancelled: "cancelled";
|
|
15
|
+
internal: "internal";
|
|
16
|
+
}>>;
|
|
8
17
|
}, z.core.$strict>>;
|
|
9
18
|
}, z.core.$strict>;
|
|
10
19
|
export declare const ReviewFindingSchema: z.ZodObject<{
|
|
@@ -20,13 +29,58 @@ export declare const ReviewFindingSchema: z.ZodObject<{
|
|
|
20
29
|
explanation: z.ZodString;
|
|
21
30
|
recommendation: z.ZodString;
|
|
22
31
|
}, z.core.$strict>;
|
|
23
|
-
export declare const
|
|
32
|
+
export declare const PrImpactResultSchema: z.ZodObject<{
|
|
33
|
+
severity: z.ZodEnum<{
|
|
34
|
+
low: "low";
|
|
35
|
+
medium: "medium";
|
|
36
|
+
high: "high";
|
|
37
|
+
critical: "critical";
|
|
38
|
+
}>;
|
|
39
|
+
categories: z.ZodArray<z.ZodEnum<{
|
|
40
|
+
breaking_change: "breaking_change";
|
|
41
|
+
api_change: "api_change";
|
|
42
|
+
schema_change: "schema_change";
|
|
43
|
+
config_change: "config_change";
|
|
44
|
+
dependency_update: "dependency_update";
|
|
45
|
+
security_fix: "security_fix";
|
|
46
|
+
deprecation: "deprecation";
|
|
47
|
+
performance_change: "performance_change";
|
|
48
|
+
bug_fix: "bug_fix";
|
|
49
|
+
feature_addition: "feature_addition";
|
|
50
|
+
}>>;
|
|
51
|
+
summary: z.ZodString;
|
|
52
|
+
breakingChanges: z.ZodArray<z.ZodString>;
|
|
53
|
+
affectedAreas: z.ZodArray<z.ZodString>;
|
|
54
|
+
rollbackComplexity: z.ZodEnum<{
|
|
55
|
+
trivial: "trivial";
|
|
56
|
+
moderate: "moderate";
|
|
57
|
+
complex: "complex";
|
|
58
|
+
irreversible: "irreversible";
|
|
59
|
+
}>;
|
|
60
|
+
}, z.core.$strict>;
|
|
61
|
+
export declare const ReviewSummaryResultSchema: z.ZodObject<{
|
|
24
62
|
summary: z.ZodString;
|
|
25
63
|
overallRisk: z.ZodEnum<{
|
|
26
64
|
low: "low";
|
|
27
65
|
medium: "medium";
|
|
28
66
|
high: "high";
|
|
29
67
|
}>;
|
|
68
|
+
keyChanges: z.ZodArray<z.ZodString>;
|
|
69
|
+
recommendation: z.ZodString;
|
|
70
|
+
stats: z.ZodObject<{
|
|
71
|
+
filesChanged: z.ZodNumber;
|
|
72
|
+
linesAdded: z.ZodNumber;
|
|
73
|
+
linesRemoved: z.ZodNumber;
|
|
74
|
+
}, z.core.$strict>;
|
|
75
|
+
}, z.core.$strict>;
|
|
76
|
+
export declare const CodeQualityResultSchema: z.ZodObject<{
|
|
77
|
+
summary: z.ZodString;
|
|
78
|
+
overallRisk: z.ZodEnum<{
|
|
79
|
+
low: "low";
|
|
80
|
+
medium: "medium";
|
|
81
|
+
high: "high";
|
|
82
|
+
critical: "critical";
|
|
83
|
+
}>;
|
|
30
84
|
findings: z.ZodArray<z.ZodObject<{
|
|
31
85
|
severity: z.ZodEnum<{
|
|
32
86
|
low: "low";
|
|
@@ -41,19 +95,88 @@ export declare const ReviewDiffResultSchema: z.ZodObject<{
|
|
|
41
95
|
recommendation: z.ZodString;
|
|
42
96
|
}, z.core.$strict>>;
|
|
43
97
|
testsNeeded: z.ZodArray<z.ZodString>;
|
|
98
|
+
contextualInsights: z.ZodArray<z.ZodString>;
|
|
44
99
|
}, z.core.$strict>;
|
|
45
|
-
export declare const
|
|
46
|
-
|
|
47
|
-
|
|
100
|
+
export declare const CodeQualityOutputSchema: z.ZodObject<{
|
|
101
|
+
summary: z.ZodString;
|
|
102
|
+
overallRisk: z.ZodEnum<{
|
|
48
103
|
low: "low";
|
|
49
104
|
medium: "medium";
|
|
50
105
|
high: "high";
|
|
51
106
|
critical: "critical";
|
|
52
107
|
}>;
|
|
53
|
-
|
|
108
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
109
|
+
severity: z.ZodEnum<{
|
|
110
|
+
low: "low";
|
|
111
|
+
medium: "medium";
|
|
112
|
+
high: "high";
|
|
113
|
+
critical: "critical";
|
|
114
|
+
}>;
|
|
115
|
+
file: z.ZodString;
|
|
116
|
+
line: z.ZodNullable<z.ZodNumber>;
|
|
117
|
+
title: z.ZodString;
|
|
118
|
+
explanation: z.ZodString;
|
|
119
|
+
recommendation: z.ZodString;
|
|
120
|
+
}, z.core.$strict>>;
|
|
121
|
+
testsNeeded: z.ZodArray<z.ZodString>;
|
|
122
|
+
contextualInsights: z.ZodArray<z.ZodString>;
|
|
123
|
+
totalFindings: z.ZodOptional<z.ZodNumber>;
|
|
124
|
+
}, z.core.$strip>;
|
|
125
|
+
export declare const SearchReplaceBlockSchema: z.ZodObject<{
|
|
126
|
+
file: z.ZodString;
|
|
127
|
+
search: z.ZodString;
|
|
128
|
+
replace: z.ZodString;
|
|
129
|
+
explanation: z.ZodString;
|
|
54
130
|
}, z.core.$strict>;
|
|
55
|
-
export declare const
|
|
131
|
+
export declare const SearchReplaceResultSchema: z.ZodObject<{
|
|
56
132
|
summary: z.ZodString;
|
|
57
|
-
|
|
133
|
+
blocks: z.ZodArray<z.ZodObject<{
|
|
134
|
+
file: z.ZodString;
|
|
135
|
+
search: z.ZodString;
|
|
136
|
+
replace: z.ZodString;
|
|
137
|
+
explanation: z.ZodString;
|
|
138
|
+
}, z.core.$strict>>;
|
|
58
139
|
validationChecklist: z.ZodArray<z.ZodString>;
|
|
59
140
|
}, z.core.$strict>;
|
|
141
|
+
export declare const TestCaseSchema: z.ZodObject<{
|
|
142
|
+
name: z.ZodString;
|
|
143
|
+
type: z.ZodEnum<{
|
|
144
|
+
security: "security";
|
|
145
|
+
performance: "performance";
|
|
146
|
+
unit: "unit";
|
|
147
|
+
integration: "integration";
|
|
148
|
+
e2e: "e2e";
|
|
149
|
+
regression: "regression";
|
|
150
|
+
}>;
|
|
151
|
+
file: z.ZodString;
|
|
152
|
+
description: z.ZodString;
|
|
153
|
+
pseudoCode: z.ZodString;
|
|
154
|
+
priority: z.ZodEnum<{
|
|
155
|
+
must_have: "must_have";
|
|
156
|
+
should_have: "should_have";
|
|
157
|
+
nice_to_have: "nice_to_have";
|
|
158
|
+
}>;
|
|
159
|
+
}, z.core.$strict>;
|
|
160
|
+
export declare const TestPlanResultSchema: z.ZodObject<{
|
|
161
|
+
summary: z.ZodString;
|
|
162
|
+
testCases: z.ZodArray<z.ZodObject<{
|
|
163
|
+
name: z.ZodString;
|
|
164
|
+
type: z.ZodEnum<{
|
|
165
|
+
security: "security";
|
|
166
|
+
performance: "performance";
|
|
167
|
+
unit: "unit";
|
|
168
|
+
integration: "integration";
|
|
169
|
+
e2e: "e2e";
|
|
170
|
+
regression: "regression";
|
|
171
|
+
}>;
|
|
172
|
+
file: z.ZodString;
|
|
173
|
+
description: z.ZodString;
|
|
174
|
+
pseudoCode: z.ZodString;
|
|
175
|
+
priority: z.ZodEnum<{
|
|
176
|
+
must_have: "must_have";
|
|
177
|
+
should_have: "should_have";
|
|
178
|
+
nice_to_have: "nice_to_have";
|
|
179
|
+
}>;
|
|
180
|
+
}, z.core.$strict>>;
|
|
181
|
+
coverageSummary: z.ZodString;
|
|
182
|
+
}, z.core.$strict>;
|
package/dist/schemas/outputs.js
CHANGED
|
@@ -5,26 +5,33 @@ const OUTPUT_LIMITS = {
|
|
|
5
5
|
lineMin: 1,
|
|
6
6
|
lineMax: 1_000_000,
|
|
7
7
|
title: { min: 3, max: 160 },
|
|
8
|
-
text: { min:
|
|
8
|
+
text: { min: 1, max: 2_000 },
|
|
9
9
|
},
|
|
10
10
|
reviewDiffResult: {
|
|
11
|
-
summary: { min:
|
|
12
|
-
findingsMax:
|
|
13
|
-
testsNeeded: { minItems: 0, maxItems:
|
|
11
|
+
summary: { min: 1, max: 2_000 },
|
|
12
|
+
findingsMax: 50,
|
|
13
|
+
testsNeeded: { minItems: 0, maxItems: 20, itemMin: 1, itemMax: 300 },
|
|
14
14
|
},
|
|
15
15
|
riskScoreResult: {
|
|
16
16
|
score: { min: 0, max: 100 },
|
|
17
|
-
rationale: { minItems: 1, maxItems:
|
|
17
|
+
rationale: { minItems: 1, maxItems: 20, itemMin: 1, itemMax: 500 },
|
|
18
18
|
},
|
|
19
19
|
patchSuggestionResult: {
|
|
20
|
-
summary: { min:
|
|
21
|
-
patch: { min:
|
|
22
|
-
checklist: { minItems: 1, maxItems:
|
|
20
|
+
summary: { min: 1, max: 1_000 },
|
|
21
|
+
patch: { min: 1, max: 60_000 },
|
|
22
|
+
checklist: { minItems: 1, maxItems: 20, itemMin: 1, itemMax: 300 },
|
|
23
23
|
},
|
|
24
24
|
};
|
|
25
25
|
function createBoundedString(min, max, description) {
|
|
26
26
|
return z.string().min(min).max(max).describe(description);
|
|
27
27
|
}
|
|
28
|
+
function createBoundedStringArray(itemMin, itemMax, minItems, maxItems, description) {
|
|
29
|
+
return z
|
|
30
|
+
.array(z.string().min(itemMin).max(itemMax))
|
|
31
|
+
.min(minItems)
|
|
32
|
+
.max(maxItems)
|
|
33
|
+
.describe(description);
|
|
34
|
+
}
|
|
28
35
|
export const DefaultOutputSchema = z.strictObject({
|
|
29
36
|
ok: z.boolean().describe('Whether the tool completed successfully.'),
|
|
30
37
|
result: z.unknown().optional().describe('Successful result payload.'),
|
|
@@ -32,6 +39,21 @@ export const DefaultOutputSchema = z.strictObject({
|
|
|
32
39
|
.strictObject({
|
|
33
40
|
code: z.string().describe('Stable error code for callers.'),
|
|
34
41
|
message: z.string().describe('Human readable error details.'),
|
|
42
|
+
retryable: z
|
|
43
|
+
.boolean()
|
|
44
|
+
.optional()
|
|
45
|
+
.describe('Whether the client should retry this request.'),
|
|
46
|
+
kind: z
|
|
47
|
+
.enum([
|
|
48
|
+
'validation',
|
|
49
|
+
'budget',
|
|
50
|
+
'upstream',
|
|
51
|
+
'timeout',
|
|
52
|
+
'cancelled',
|
|
53
|
+
'internal',
|
|
54
|
+
])
|
|
55
|
+
.optional()
|
|
56
|
+
.describe('Machine-readable error category.'),
|
|
35
57
|
})
|
|
36
58
|
.optional()
|
|
37
59
|
.describe('Error payload when ok is false.'),
|
|
@@ -56,44 +78,152 @@ export const ReviewFindingSchema = z.strictObject({
|
|
|
56
78
|
explanation: createBoundedString(OUTPUT_LIMITS.reviewFinding.text.min, OUTPUT_LIMITS.reviewFinding.text.max, 'Why this issue matters.'),
|
|
57
79
|
recommendation: createBoundedString(OUTPUT_LIMITS.reviewFinding.text.min, OUTPUT_LIMITS.reviewFinding.text.max, 'Concrete fix recommendation.'),
|
|
58
80
|
});
|
|
59
|
-
export const
|
|
60
|
-
|
|
81
|
+
export const PrImpactResultSchema = z.strictObject({
|
|
82
|
+
severity: z
|
|
83
|
+
.enum(['low', 'medium', 'high', 'critical'])
|
|
84
|
+
.describe('Overall impact severity.'),
|
|
85
|
+
categories: z
|
|
86
|
+
.array(z.enum([
|
|
87
|
+
'breaking_change',
|
|
88
|
+
'api_change',
|
|
89
|
+
'schema_change',
|
|
90
|
+
'config_change',
|
|
91
|
+
'dependency_update',
|
|
92
|
+
'security_fix',
|
|
93
|
+
'deprecation',
|
|
94
|
+
'performance_change',
|
|
95
|
+
'bug_fix',
|
|
96
|
+
'feature_addition',
|
|
97
|
+
]))
|
|
98
|
+
.min(0)
|
|
99
|
+
.max(10)
|
|
100
|
+
.describe('Impact categories detected in the diff.'),
|
|
101
|
+
summary: z.string().min(1).max(1000).describe('Concise impact summary.'),
|
|
102
|
+
breakingChanges: createBoundedStringArray(1, 500, 0, 10, 'Specific breaking changes identified.'),
|
|
103
|
+
affectedAreas: createBoundedStringArray(1, 200, 0, 20, 'Subsystems or files impacted.'),
|
|
104
|
+
rollbackComplexity: z
|
|
105
|
+
.enum(['trivial', 'moderate', 'complex', 'irreversible'])
|
|
106
|
+
.describe('Estimated difficulty to revert this change.'),
|
|
107
|
+
});
|
|
108
|
+
export const ReviewSummaryResultSchema = z.strictObject({
|
|
109
|
+
summary: z.string().min(1).max(2000).describe('Human-readable PR summary.'),
|
|
61
110
|
overallRisk: z
|
|
62
111
|
.enum(['low', 'medium', 'high'])
|
|
63
|
-
.describe('
|
|
112
|
+
.describe('High-level merge risk.'),
|
|
113
|
+
keyChanges: createBoundedStringArray(1, 300, 1, 15, 'Most important changes, ordered by significance.'),
|
|
114
|
+
recommendation: z
|
|
115
|
+
.string()
|
|
116
|
+
.min(1)
|
|
117
|
+
.max(500)
|
|
118
|
+
.describe('Merge readiness recommendation.'),
|
|
119
|
+
stats: z
|
|
120
|
+
.strictObject({
|
|
121
|
+
filesChanged: z
|
|
122
|
+
.number()
|
|
123
|
+
.int()
|
|
124
|
+
.min(0)
|
|
125
|
+
.describe('Number of files changed.'),
|
|
126
|
+
linesAdded: z.number().int().min(0).describe('Total lines added.'),
|
|
127
|
+
linesRemoved: z.number().int().min(0).describe('Total lines removed.'),
|
|
128
|
+
})
|
|
129
|
+
.describe('Change statistics (computed from diff before Gemini call).'),
|
|
130
|
+
});
|
|
131
|
+
export const CodeQualityResultSchema = z.strictObject({
|
|
132
|
+
summary: z.string().min(1).max(2000).describe('Deep-dive review summary.'),
|
|
133
|
+
overallRisk: z
|
|
134
|
+
.enum(['low', 'medium', 'high', 'critical'])
|
|
135
|
+
.describe('Overall risk with full context.'),
|
|
64
136
|
findings: z
|
|
65
|
-
.array(ReviewFindingSchema
|
|
137
|
+
.array(ReviewFindingSchema)
|
|
66
138
|
.min(0)
|
|
67
|
-
.max(
|
|
68
|
-
.describe('
|
|
69
|
-
testsNeeded:
|
|
70
|
-
|
|
71
|
-
.min(OUTPUT_LIMITS.reviewDiffResult.testsNeeded.minItems)
|
|
72
|
-
.max(OUTPUT_LIMITS.reviewDiffResult.testsNeeded.maxItems)
|
|
73
|
-
.describe('Targeted tests to add before merge.'),
|
|
139
|
+
.max(30)
|
|
140
|
+
.describe('Findings ordered by severity, highest first.'),
|
|
141
|
+
testsNeeded: createBoundedStringArray(1, 300, 0, 12, 'Test cases needed to validate this change.'),
|
|
142
|
+
contextualInsights: createBoundedStringArray(1, 500, 0, 5, 'Insights only possible with full file context that diff alone cannot reveal.'),
|
|
74
143
|
});
|
|
75
|
-
export const
|
|
76
|
-
|
|
144
|
+
export const CodeQualityOutputSchema = z.object({
|
|
145
|
+
summary: z.string().min(1).max(2000).describe('Deep-dive review summary.'),
|
|
146
|
+
overallRisk: z
|
|
147
|
+
.enum(['low', 'medium', 'high', 'critical'])
|
|
148
|
+
.describe('Overall risk with full context.'),
|
|
149
|
+
findings: z
|
|
150
|
+
.array(ReviewFindingSchema)
|
|
151
|
+
.min(0)
|
|
152
|
+
.max(30)
|
|
153
|
+
.describe('Findings ordered by severity, highest first.'),
|
|
154
|
+
testsNeeded: createBoundedStringArray(1, 300, 0, 12, 'Test cases needed to validate this change.'),
|
|
155
|
+
contextualInsights: createBoundedStringArray(1, 500, 0, 5, 'Insights only possible with full file context that diff alone cannot reveal.'),
|
|
156
|
+
totalFindings: z
|
|
77
157
|
.number()
|
|
78
158
|
.int()
|
|
79
|
-
.min(
|
|
80
|
-
.
|
|
81
|
-
.describe('
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
.
|
|
87
|
-
.min(
|
|
88
|
-
.max(
|
|
89
|
-
.describe('
|
|
159
|
+
.min(0)
|
|
160
|
+
.optional()
|
|
161
|
+
.describe('Total findings returned by Gemini before maxFindings capping was applied.'),
|
|
162
|
+
});
|
|
163
|
+
export const SearchReplaceBlockSchema = z.strictObject({
|
|
164
|
+
file: z.string().min(1).max(500).describe('File path to modify.'),
|
|
165
|
+
search: z
|
|
166
|
+
.string()
|
|
167
|
+
.min(1)
|
|
168
|
+
.max(5000)
|
|
169
|
+
.describe('Exact verbatim text to find in the file.'),
|
|
170
|
+
replace: z
|
|
171
|
+
.string()
|
|
172
|
+
.min(0)
|
|
173
|
+
.max(5000)
|
|
174
|
+
.describe('Replacement text (empty string = deletion).'),
|
|
175
|
+
explanation: z
|
|
176
|
+
.string()
|
|
177
|
+
.min(1)
|
|
178
|
+
.max(500)
|
|
179
|
+
.describe('Why this change fixes the finding.'),
|
|
180
|
+
});
|
|
181
|
+
export const SearchReplaceResultSchema = z.strictObject({
|
|
182
|
+
summary: z.string().min(1).max(1000).describe('What the fix accomplishes.'),
|
|
183
|
+
blocks: z
|
|
184
|
+
.array(SearchReplaceBlockSchema)
|
|
185
|
+
.min(1)
|
|
186
|
+
.max(10)
|
|
187
|
+
.describe('Search/replace operations to apply, in order.'),
|
|
188
|
+
validationChecklist: createBoundedStringArray(1, 300, 1, 12, 'Steps to validate the fix after applying.'),
|
|
90
189
|
});
|
|
91
|
-
export const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
.
|
|
96
|
-
.
|
|
97
|
-
|
|
98
|
-
.
|
|
190
|
+
export const TestCaseSchema = z.strictObject({
|
|
191
|
+
name: z
|
|
192
|
+
.string()
|
|
193
|
+
.min(1)
|
|
194
|
+
.max(200)
|
|
195
|
+
.describe('Test case name or describe/it string.'),
|
|
196
|
+
type: z
|
|
197
|
+
.enum([
|
|
198
|
+
'unit',
|
|
199
|
+
'integration',
|
|
200
|
+
'e2e',
|
|
201
|
+
'regression',
|
|
202
|
+
'security',
|
|
203
|
+
'performance',
|
|
204
|
+
])
|
|
205
|
+
.describe('Category of test.'),
|
|
206
|
+
file: z.string().min(1).max(500).describe('Suggested test file path.'),
|
|
207
|
+
description: z.string().min(1).max(1000).describe('What this test verifies.'),
|
|
208
|
+
pseudoCode: z
|
|
209
|
+
.string()
|
|
210
|
+
.min(1)
|
|
211
|
+
.max(2000)
|
|
212
|
+
.describe('Pseudocode or starter implementation.'),
|
|
213
|
+
priority: z
|
|
214
|
+
.enum(['must_have', 'should_have', 'nice_to_have'])
|
|
215
|
+
.describe('Priority relative to merge readiness.'),
|
|
216
|
+
});
|
|
217
|
+
export const TestPlanResultSchema = z.strictObject({
|
|
218
|
+
summary: z.string().min(1).max(1000).describe('Test plan overview.'),
|
|
219
|
+
testCases: z
|
|
220
|
+
.array(TestCaseSchema)
|
|
221
|
+
.min(1)
|
|
222
|
+
.max(30)
|
|
223
|
+
.describe('Ordered test cases, must_have first.'),
|
|
224
|
+
coverageSummary: z
|
|
225
|
+
.string()
|
|
226
|
+
.min(1)
|
|
227
|
+
.max(500)
|
|
228
|
+
.describe('Summary of coverage gaps this plan addresses.'),
|
|
99
229
|
});
|
package/dist/server.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
export
|
|
2
|
+
export interface ServerHandle {
|
|
3
|
+
server: McpServer;
|
|
4
|
+
shutdown: () => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export declare function createServer(): ServerHandle;
|