driftdetect-mcp 0.6.0 → 0.7.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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bin/server.js +0 -0
  3. package/dist/enterprise-server.d.ts +1 -0
  4. package/dist/enterprise-server.d.ts.map +1 -1
  5. package/dist/enterprise-server.js +8 -1
  6. package/dist/enterprise-server.js.map +1 -1
  7. package/dist/tools/analysis/constants.d.ts +99 -0
  8. package/dist/tools/analysis/constants.d.ts.map +1 -0
  9. package/dist/tools/analysis/constants.js +421 -0
  10. package/dist/tools/analysis/constants.js.map +1 -0
  11. package/dist/tools/analysis/index.d.ts +1 -0
  12. package/dist/tools/analysis/index.d.ts.map +1 -1
  13. package/dist/tools/analysis/index.js +70 -0
  14. package/dist/tools/analysis/index.js.map +1 -1
  15. package/dist/tools/exploration/env.d.ts +53 -0
  16. package/dist/tools/exploration/env.d.ts.map +1 -0
  17. package/dist/tools/exploration/env.js +283 -0
  18. package/dist/tools/exploration/env.js.map +1 -0
  19. package/dist/tools/exploration/index.d.ts +2 -0
  20. package/dist/tools/exploration/index.d.ts.map +1 -1
  21. package/dist/tools/exploration/index.js +32 -0
  22. package/dist/tools/exploration/index.js.map +1 -1
  23. package/dist/tools/index.d.ts +6 -1
  24. package/dist/tools/index.d.ts.map +1 -1
  25. package/dist/tools/index.js +6 -1
  26. package/dist/tools/index.js.map +1 -1
  27. package/dist/tools/registry.d.ts +7 -5
  28. package/dist/tools/registry.d.ts.map +1 -1
  29. package/dist/tools/registry.js +10 -4
  30. package/dist/tools/registry.js.map +1 -1
  31. package/dist/tools/surgical/callers.d.ts +85 -0
  32. package/dist/tools/surgical/callers.d.ts.map +1 -0
  33. package/dist/tools/surgical/callers.js +239 -0
  34. package/dist/tools/surgical/callers.js.map +1 -0
  35. package/dist/tools/surgical/dependencies.d.ts +96 -0
  36. package/dist/tools/surgical/dependencies.d.ts.map +1 -0
  37. package/dist/tools/surgical/dependencies.js +433 -0
  38. package/dist/tools/surgical/dependencies.js.map +1 -0
  39. package/dist/tools/surgical/errors.d.ts +88 -0
  40. package/dist/tools/surgical/errors.d.ts.map +1 -0
  41. package/dist/tools/surgical/errors.js +275 -0
  42. package/dist/tools/surgical/errors.js.map +1 -0
  43. package/dist/tools/surgical/hooks.d.ts +69 -0
  44. package/dist/tools/surgical/hooks.d.ts.map +1 -0
  45. package/dist/tools/surgical/hooks.js +247 -0
  46. package/dist/tools/surgical/hooks.js.map +1 -0
  47. package/dist/tools/surgical/imports.d.ts +61 -0
  48. package/dist/tools/surgical/imports.d.ts.map +1 -0
  49. package/dist/tools/surgical/imports.js +211 -0
  50. package/dist/tools/surgical/imports.js.map +1 -0
  51. package/dist/tools/surgical/index.d.ts +42 -0
  52. package/dist/tools/surgical/index.d.ts.map +1 -0
  53. package/dist/tools/surgical/index.js +66 -0
  54. package/dist/tools/surgical/index.js.map +1 -0
  55. package/dist/tools/surgical/middleware.d.ts +69 -0
  56. package/dist/tools/surgical/middleware.d.ts.map +1 -0
  57. package/dist/tools/surgical/middleware.js +237 -0
  58. package/dist/tools/surgical/middleware.js.map +1 -0
  59. package/dist/tools/surgical/prevalidate.d.ts +76 -0
  60. package/dist/tools/surgical/prevalidate.d.ts.map +1 -0
  61. package/dist/tools/surgical/prevalidate.js +303 -0
  62. package/dist/tools/surgical/prevalidate.js.map +1 -0
  63. package/dist/tools/surgical/recent.d.ts +66 -0
  64. package/dist/tools/surgical/recent.d.ts.map +1 -0
  65. package/dist/tools/surgical/recent.js +238 -0
  66. package/dist/tools/surgical/recent.js.map +1 -0
  67. package/dist/tools/surgical/signature.d.ts +73 -0
  68. package/dist/tools/surgical/signature.d.ts.map +1 -0
  69. package/dist/tools/surgical/signature.js +190 -0
  70. package/dist/tools/surgical/signature.js.map +1 -0
  71. package/dist/tools/surgical/similar.d.ts +77 -0
  72. package/dist/tools/surgical/similar.d.ts.map +1 -0
  73. package/dist/tools/surgical/similar.js +285 -0
  74. package/dist/tools/surgical/similar.js.map +1 -0
  75. package/dist/tools/surgical/test-template.d.ts +70 -0
  76. package/dist/tools/surgical/test-template.d.ts.map +1 -0
  77. package/dist/tools/surgical/test-template.js +298 -0
  78. package/dist/tools/surgical/test-template.js.map +1 -0
  79. package/dist/tools/surgical/type.d.ts +69 -0
  80. package/dist/tools/surgical/type.d.ts.map +1 -0
  81. package/dist/tools/surgical/type.js +289 -0
  82. package/dist/tools/surgical/type.js.map +1 -0
  83. package/package.json +11 -11
@@ -0,0 +1,237 @@
1
+ /**
2
+ * drift_middleware - Middleware Pattern Lookup
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 300 target, 800 max
6
+ *
7
+ * Returns middleware patterns in the codebase.
8
+ * Solves: AI needs to know existing middleware when adding auth/logging/etc.
9
+ */
10
+ import { createWrapperScanner, } from 'driftdetect-core/wrappers';
11
+ import { createResponseBuilder, metrics } from '../../infrastructure/index.js';
12
+ // ============================================================================
13
+ // Handler
14
+ // ============================================================================
15
+ export async function handleMiddleware(args, rootDir) {
16
+ const startTime = Date.now();
17
+ const builder = createResponseBuilder();
18
+ const typeFilter = args.type ?? 'all';
19
+ const frameworkFilter = args.framework?.toLowerCase();
20
+ const limit = args.limit ?? 20;
21
+ // Scan for wrappers with middleware category
22
+ const scanner = createWrapperScanner({
23
+ rootDir,
24
+ includeTestFiles: false,
25
+ verbose: false,
26
+ });
27
+ const result = await scanner.scan({
28
+ minConfidence: 0.3,
29
+ minClusterSize: 1,
30
+ maxDepth: 5,
31
+ includeTestFiles: false,
32
+ });
33
+ // Filter to middleware-related clusters
34
+ const middlewareClusters = result.analysis.clusters.filter(c => c.category === 'middleware' ||
35
+ c.category === 'authentication' ||
36
+ c.category === 'authorization' ||
37
+ c.category === 'validation' ||
38
+ c.category === 'logging' ||
39
+ c.category === 'error-handling');
40
+ // Extract middleware functions
41
+ const middlewareList = [];
42
+ for (const cluster of middlewareClusters) {
43
+ const middlewareType = categorizeMiddleware(cluster);
44
+ // Apply type filter
45
+ if (typeFilter !== 'all' && middlewareType !== typeFilter) {
46
+ continue;
47
+ }
48
+ for (const wrapper of cluster.wrappers) {
49
+ // Apply framework filter
50
+ const detectedFramework = detectFramework(wrapper);
51
+ if (frameworkFilter && detectedFramework?.toLowerCase() !== frameworkFilter) {
52
+ continue;
53
+ }
54
+ middlewareList.push({
55
+ name: wrapper.name,
56
+ file: wrapper.file,
57
+ line: wrapper.line,
58
+ type: middlewareType,
59
+ framework: detectedFramework,
60
+ usages: wrapper.calledBy.length,
61
+ parameters: wrapper.parameterSignature,
62
+ });
63
+ }
64
+ }
65
+ // Also check for common middleware patterns in wrappers
66
+ for (const wrapper of result.analysis.wrappers) {
67
+ if (isMiddlewarePattern(wrapper) && !middlewareList.some(m => m.name === wrapper.name)) {
68
+ const middlewareType = inferMiddlewareType(wrapper);
69
+ if (typeFilter !== 'all' && middlewareType !== typeFilter) {
70
+ continue;
71
+ }
72
+ const detectedFramework = detectFramework(wrapper);
73
+ if (frameworkFilter && detectedFramework?.toLowerCase() !== frameworkFilter) {
74
+ continue;
75
+ }
76
+ middlewareList.push({
77
+ name: wrapper.name,
78
+ file: wrapper.file,
79
+ line: wrapper.line,
80
+ type: middlewareType,
81
+ framework: detectedFramework,
82
+ usages: wrapper.calledBy.length,
83
+ parameters: wrapper.parameterSignature,
84
+ });
85
+ }
86
+ }
87
+ // Sort by usages and limit
88
+ middlewareList.sort((a, b) => b.usages - a.usages);
89
+ const limited = middlewareList.slice(0, limit);
90
+ // Calculate stats
91
+ const byType = {};
92
+ let authCount = 0;
93
+ let loggingCount = 0;
94
+ let validationCount = 0;
95
+ let errorCount = 0;
96
+ for (const mw of middlewareList) {
97
+ byType[mw.type] = (byType[mw.type] ?? 0) + 1;
98
+ if (mw.type === 'auth')
99
+ authCount++;
100
+ if (mw.type === 'logging')
101
+ loggingCount++;
102
+ if (mw.type === 'validation')
103
+ validationCount++;
104
+ if (mw.type === 'error')
105
+ errorCount++;
106
+ }
107
+ const data = {
108
+ middleware: limited,
109
+ byType,
110
+ stats: {
111
+ total: middlewareList.length,
112
+ authCount,
113
+ loggingCount,
114
+ validationCount,
115
+ errorCount,
116
+ },
117
+ };
118
+ // Build summary
119
+ const summary = middlewareList.length > 0
120
+ ? `Found ${middlewareList.length} middleware: ${authCount} auth, ${loggingCount} logging, ${validationCount} validation, ${errorCount} error handling`
121
+ : 'No middleware patterns detected';
122
+ // Record metrics
123
+ metrics.recordRequest('drift_middleware', Date.now() - startTime, true, false);
124
+ return builder
125
+ .withSummary(summary)
126
+ .withData(data)
127
+ .withHints({
128
+ nextActions: middlewareList.length > 0
129
+ ? ['Review existing middleware before adding new ones', 'Check middleware order in routes']
130
+ : ['Consider adding middleware for cross-cutting concerns'],
131
+ relatedTools: ['drift_wrappers', 'drift_signature', 'drift_imports'],
132
+ })
133
+ .buildContent();
134
+ }
135
+ // ============================================================================
136
+ // Helpers
137
+ // ============================================================================
138
+ function categorizeMiddleware(cluster) {
139
+ switch (cluster.category) {
140
+ case 'authentication':
141
+ case 'authorization':
142
+ return 'auth';
143
+ case 'logging':
144
+ return 'logging';
145
+ case 'validation':
146
+ return 'validation';
147
+ case 'error-handling':
148
+ return 'error';
149
+ default:
150
+ return 'other';
151
+ }
152
+ }
153
+ function detectFramework(wrapper) {
154
+ const primitives = wrapper.primitiveSignature.join(' ').toLowerCase();
155
+ const name = wrapper.name.toLowerCase();
156
+ if (primitives.includes('express') || name.includes('express'))
157
+ return 'express';
158
+ if (primitives.includes('koa'))
159
+ return 'koa';
160
+ if (primitives.includes('fastify'))
161
+ return 'fastify';
162
+ if (primitives.includes('nestjs') || primitives.includes('@nestjs'))
163
+ return 'nestjs';
164
+ if (primitives.includes('laravel') || primitives.includes('illuminate'))
165
+ return 'laravel';
166
+ if (primitives.includes('spring') || primitives.includes('@controller'))
167
+ return 'spring';
168
+ if (primitives.includes('gin') || primitives.includes('echo') || primitives.includes('fiber'))
169
+ return 'go';
170
+ return undefined;
171
+ }
172
+ function isMiddlewarePattern(wrapper) {
173
+ const name = wrapper.name.toLowerCase();
174
+ const params = wrapper.parameterSignature?.join(' ').toLowerCase() ?? '';
175
+ // Common middleware naming patterns
176
+ if (name.includes('middleware'))
177
+ return true;
178
+ if (name.includes('interceptor'))
179
+ return true;
180
+ if (name.includes('guard'))
181
+ return true;
182
+ if (name.includes('filter'))
183
+ return true;
184
+ // Express-style (req, res, next)
185
+ if (params.includes('req') && params.includes('res') && params.includes('next'))
186
+ return true;
187
+ // Koa-style (ctx, next)
188
+ if (params.includes('ctx') && params.includes('next'))
189
+ return true;
190
+ return false;
191
+ }
192
+ function inferMiddlewareType(wrapper) {
193
+ const name = wrapper.name.toLowerCase();
194
+ const primitives = wrapper.primitiveSignature.join(' ').toLowerCase();
195
+ if (name.includes('auth') || name.includes('jwt') || name.includes('session') ||
196
+ primitives.includes('auth') || primitives.includes('jwt')) {
197
+ return 'auth';
198
+ }
199
+ if (name.includes('log') || name.includes('morgan') || name.includes('winston') ||
200
+ primitives.includes('log')) {
201
+ return 'logging';
202
+ }
203
+ if (name.includes('valid') || name.includes('sanitize') || name.includes('schema') ||
204
+ primitives.includes('joi') || primitives.includes('zod') || primitives.includes('yup')) {
205
+ return 'validation';
206
+ }
207
+ if (name.includes('error') || name.includes('exception') || name.includes('catch')) {
208
+ return 'error';
209
+ }
210
+ return 'other';
211
+ }
212
+ /**
213
+ * Tool definition for MCP registration
214
+ */
215
+ export const middlewareToolDefinition = {
216
+ name: 'drift_middleware',
217
+ description: 'Find middleware patterns in the codebase. Returns auth, logging, validation, and error handling middleware with their locations and usage counts.',
218
+ inputSchema: {
219
+ type: 'object',
220
+ properties: {
221
+ type: {
222
+ type: 'string',
223
+ enum: ['auth', 'logging', 'validation', 'error', 'all'],
224
+ description: 'Filter by middleware type (default: all)',
225
+ },
226
+ framework: {
227
+ type: 'string',
228
+ description: 'Filter by framework: express, koa, fastify, nestjs, laravel, spring',
229
+ },
230
+ limit: {
231
+ type: 'number',
232
+ description: 'Max results to return (default: 20)',
233
+ },
234
+ },
235
+ },
236
+ };
237
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/tools/surgical/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * drift_prevalidate - Validate Code Before Writing
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 400 target, 1000 max
6
+ * Cache TTL: 1 minute (short - code changes frequently)
7
+ * Invalidation Keys: patterns, category:{cat}
8
+ *
9
+ * Validates proposed code BEFORE writing it to disk.
10
+ * Solves: AI writes code, saves it, THEN finds out it violates patterns.
11
+ */
12
+ import type { PatternStore, IPatternService } from 'driftdetect-core';
13
+ export interface PrevalidateArgs {
14
+ /** The code to validate */
15
+ code: string;
16
+ /** Where it will be written */
17
+ targetFile: string;
18
+ /** What kind of code is this? */
19
+ kind?: 'function' | 'class' | 'component' | 'test' | 'full-file';
20
+ }
21
+ export interface Violation {
22
+ rule: string;
23
+ severity: 'error' | 'warning' | 'info';
24
+ message: string;
25
+ suggestion?: string;
26
+ line?: number;
27
+ }
28
+ export interface PrevalidateData {
29
+ valid: boolean;
30
+ score: number;
31
+ violations: Violation[];
32
+ expectedPatterns: string[];
33
+ suggestions: string[];
34
+ }
35
+ export declare function handlePrevalidate(store: PatternStore, args: PrevalidateArgs): Promise<{
36
+ content: Array<{
37
+ type: string;
38
+ text: string;
39
+ }>;
40
+ }>;
41
+ /**
42
+ * Handler using IPatternService (preferred)
43
+ */
44
+ export declare function handlePrevalidateWithService(service: IPatternService, args: PrevalidateArgs): Promise<{
45
+ content: Array<{
46
+ type: string;
47
+ text: string;
48
+ }>;
49
+ }>;
50
+ /**
51
+ * Tool definition for MCP registration
52
+ */
53
+ export declare const prevalidateToolDefinition: {
54
+ name: string;
55
+ description: string;
56
+ inputSchema: {
57
+ type: "object";
58
+ properties: {
59
+ code: {
60
+ type: string;
61
+ description: string;
62
+ };
63
+ targetFile: {
64
+ type: string;
65
+ description: string;
66
+ };
67
+ kind: {
68
+ type: string;
69
+ enum: string[];
70
+ description: string;
71
+ };
72
+ };
73
+ required: string[];
74
+ };
75
+ };
76
+ //# sourceMappingURL=prevalidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prevalidate.d.ts","sourceRoot":"","sources":["../../../src/tools/surgical/prevalidate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOtE,MAAM,WAAW,eAAe;IAC9B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;CAClE;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAMD,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA6E7D;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA8F7D;AAiJD;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;CAsBrC,CAAC"}
@@ -0,0 +1,303 @@
1
+ /**
2
+ * drift_prevalidate - Validate Code Before Writing
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 400 target, 1000 max
6
+ * Cache TTL: 1 minute (short - code changes frequently)
7
+ * Invalidation Keys: patterns, category:{cat}
8
+ *
9
+ * Validates proposed code BEFORE writing it to disk.
10
+ * Solves: AI writes code, saves it, THEN finds out it violates patterns.
11
+ */
12
+ import { createResponseBuilder, Errors, metrics } from '../../infrastructure/index.js';
13
+ // ============================================================================
14
+ // Handler
15
+ // ============================================================================
16
+ export async function handlePrevalidate(store, args) {
17
+ const startTime = Date.now();
18
+ const builder = createResponseBuilder();
19
+ // Validate input
20
+ if (!args.code || args.code.trim() === '') {
21
+ throw Errors.missingParameter('code');
22
+ }
23
+ if (!args.targetFile) {
24
+ throw Errors.missingParameter('targetFile');
25
+ }
26
+ const code = args.code;
27
+ const targetFile = args.targetFile;
28
+ const kind = args.kind ?? 'function';
29
+ // Initialize pattern store
30
+ await store.initialize();
31
+ // Get patterns for the target directory
32
+ const targetDir = targetFile.substring(0, targetFile.lastIndexOf('/'));
33
+ const relevantPatterns = findRelevantPatterns(store, targetDir, kind);
34
+ // Analyze the proposed code
35
+ const violations = [];
36
+ const suggestions = [];
37
+ // Check for common issues based on patterns
38
+ analyzeCode(code, relevantPatterns, violations, suggestions);
39
+ // Calculate score (100 - penalties)
40
+ let score = 100;
41
+ for (const v of violations) {
42
+ if (v.severity === 'error')
43
+ score -= 20;
44
+ else if (v.severity === 'warning')
45
+ score -= 10;
46
+ else
47
+ score -= 5;
48
+ }
49
+ score = Math.max(0, score);
50
+ const data = {
51
+ valid: violations.filter(v => v.severity === 'error').length === 0,
52
+ score,
53
+ violations,
54
+ expectedPatterns: relevantPatterns.map(p => p.name),
55
+ suggestions,
56
+ };
57
+ // Build summary
58
+ let summary;
59
+ if (violations.length === 0) {
60
+ summary = `Code looks good! Score: ${score}/100. Matches expected patterns.`;
61
+ }
62
+ else {
63
+ const errorCount = violations.filter(v => v.severity === 'error').length;
64
+ const warningCount = violations.filter(v => v.severity === 'warning').length;
65
+ summary = `Score: ${score}/100. Found ${errorCount} error${errorCount !== 1 ? 's' : ''}, ${warningCount} warning${warningCount !== 1 ? 's' : ''}.`;
66
+ }
67
+ // Build hints
68
+ const hints = {
69
+ nextActions: violations.length > 0
70
+ ? ['Fix violations before writing code', 'Use drift_code_examples to see correct patterns']
71
+ : ['Code is ready to write', 'Use drift_imports to add correct imports'],
72
+ relatedTools: ['drift_code_examples', 'drift_imports', 'drift_similar'],
73
+ };
74
+ if (violations.some(v => v.severity === 'error')) {
75
+ hints.warnings = ['Code has errors that should be fixed before writing'];
76
+ }
77
+ // Record metrics
78
+ metrics.recordRequest('drift_prevalidate', Date.now() - startTime, true, false);
79
+ return builder
80
+ .withSummary(summary)
81
+ .withData(data)
82
+ .withHints(hints)
83
+ .buildContent();
84
+ }
85
+ /**
86
+ * Handler using IPatternService (preferred)
87
+ */
88
+ export async function handlePrevalidateWithService(service, args) {
89
+ const startTime = Date.now();
90
+ const builder = createResponseBuilder();
91
+ // Validate input
92
+ if (!args.code || args.code.trim() === '') {
93
+ throw Errors.missingParameter('code');
94
+ }
95
+ if (!args.targetFile) {
96
+ throw Errors.missingParameter('targetFile');
97
+ }
98
+ const code = args.code;
99
+ const targetFile = args.targetFile;
100
+ // kind reserved for future use
101
+ // const kind = args.kind ?? 'function';
102
+ // Get patterns - for prevalidation we use all patterns since PatternSummary
103
+ // doesn't include location data. The validation logic checks code content.
104
+ const patternsResult = await service.listPatterns();
105
+ const allPatterns = patternsResult.items ?? [];
106
+ // Map to pattern-like objects for analysis
107
+ const relevantPatterns = allPatterns.map(p => ({
108
+ name: p.name,
109
+ category: p.category,
110
+ subcategory: p.subcategory,
111
+ }));
112
+ // Analyze the proposed code
113
+ const violations = [];
114
+ const suggestions = [];
115
+ // Check for common issues
116
+ analyzeCodeWithPatterns(code, relevantPatterns, violations, suggestions);
117
+ // Calculate score
118
+ let score = 100;
119
+ for (const v of violations) {
120
+ if (v.severity === 'error')
121
+ score -= 20;
122
+ else if (v.severity === 'warning')
123
+ score -= 10;
124
+ else
125
+ score -= 5;
126
+ }
127
+ score = Math.max(0, score);
128
+ // Filter to patterns that might be relevant based on target file path
129
+ const targetDir = targetFile.substring(0, targetFile.lastIndexOf('/'));
130
+ const expectedPatterns = relevantPatterns
131
+ .filter(p => {
132
+ // Include patterns that match common directory conventions
133
+ if (targetDir.includes('api') && p.category === 'api')
134
+ return true;
135
+ if (targetDir.includes('auth') && p.category === 'auth')
136
+ return true;
137
+ if (targetDir.includes('test') && p.category === 'testing')
138
+ return true;
139
+ if (targetDir.includes('component') && p.category === 'components')
140
+ return true;
141
+ return false;
142
+ })
143
+ .map(p => p.name);
144
+ const data = {
145
+ valid: violations.filter(v => v.severity === 'error').length === 0,
146
+ score,
147
+ violations,
148
+ expectedPatterns: expectedPatterns.length > 0 ? expectedPatterns : relevantPatterns.slice(0, 5).map(p => p.name),
149
+ suggestions,
150
+ };
151
+ // Build summary
152
+ let summary;
153
+ if (violations.length === 0) {
154
+ summary = `Code looks good! Score: ${score}/100. Matches expected patterns.`;
155
+ }
156
+ else {
157
+ const errorCount = violations.filter(v => v.severity === 'error').length;
158
+ const warningCount = violations.filter(v => v.severity === 'warning').length;
159
+ summary = `Score: ${score}/100. Found ${errorCount} error${errorCount !== 1 ? 's' : ''}, ${warningCount} warning${warningCount !== 1 ? 's' : ''}.`;
160
+ }
161
+ const hints = {
162
+ nextActions: violations.length > 0
163
+ ? ['Fix violations before writing code', 'Use drift_code_examples to see correct patterns']
164
+ : ['Code is ready to write', 'Use drift_imports to add correct imports'],
165
+ relatedTools: ['drift_code_examples', 'drift_imports', 'drift_similar'],
166
+ };
167
+ if (violations.some(v => v.severity === 'error')) {
168
+ hints.warnings = ['Code has errors that should be fixed before writing'];
169
+ }
170
+ metrics.recordRequest('drift_prevalidate', Date.now() - startTime, true, false);
171
+ return builder
172
+ .withSummary(summary)
173
+ .withData(data)
174
+ .withHints(hints)
175
+ .buildContent();
176
+ }
177
+ /**
178
+ * Find patterns relevant to a directory
179
+ */
180
+ function findRelevantPatterns(store, targetDir, kind) {
181
+ const patterns = [];
182
+ // Get all patterns
183
+ const allPatterns = store.getAll();
184
+ for (const pattern of allPatterns) {
185
+ // Check if pattern has locations in target directory
186
+ const hasLocation = pattern.locations.some(loc => loc.file.startsWith(targetDir) || loc.file.includes(targetDir));
187
+ if (hasLocation) {
188
+ patterns.push({
189
+ name: pattern.name,
190
+ category: pattern.category,
191
+ subcategory: pattern.subcategory,
192
+ });
193
+ }
194
+ }
195
+ // Also add patterns based on kind
196
+ if (kind === 'test') {
197
+ patterns.push({ name: 'testing-pattern', category: 'testing', subcategory: 'unit' });
198
+ }
199
+ else if (kind === 'component') {
200
+ patterns.push({ name: 'component-pattern', category: 'components', subcategory: 'react' });
201
+ }
202
+ return patterns;
203
+ }
204
+ /**
205
+ * Analyze code for common issues
206
+ */
207
+ function analyzeCode(code, patterns, violations, suggestions) {
208
+ // Check for error handling patterns
209
+ const hasErrorPattern = patterns.some(p => p.category === 'errors' || p.name.includes('error') || p.name.includes('result'));
210
+ if (hasErrorPattern) {
211
+ // Check if code has try/catch or Result pattern
212
+ if (!code.includes('try') && !code.includes('catch') &&
213
+ !code.includes('Result') && !code.includes('.ok(') && !code.includes('.err(')) {
214
+ if (code.includes('async') || code.includes('await') || code.includes('Promise')) {
215
+ violations.push({
216
+ rule: 'error-handling',
217
+ severity: 'warning',
218
+ message: 'Async code without error handling - this codebase uses structured error handling',
219
+ suggestion: 'Add try/catch or use Result<T> pattern',
220
+ });
221
+ suggestions.push('Wrap async operations in try/catch');
222
+ }
223
+ }
224
+ }
225
+ // Check for raw SQL (if data-access patterns exist)
226
+ const hasDataPattern = patterns.some(p => p.category === 'data-access' || p.name.includes('prisma') || p.name.includes('orm'));
227
+ if (hasDataPattern) {
228
+ if (code.includes('SELECT') || code.includes('INSERT') ||
229
+ code.includes('UPDATE') || code.includes('DELETE')) {
230
+ violations.push({
231
+ rule: 'data-access',
232
+ severity: 'warning',
233
+ message: 'Raw SQL detected - this codebase uses an ORM',
234
+ suggestion: 'Use the ORM methods instead of raw SQL',
235
+ });
236
+ suggestions.push('Replace raw SQL with ORM calls');
237
+ }
238
+ }
239
+ // Check for console.log in non-test code
240
+ if (code.includes('console.log') && !patterns.some(p => p.category === 'testing')) {
241
+ violations.push({
242
+ rule: 'logging',
243
+ severity: 'info',
244
+ message: 'console.log detected - consider using structured logging',
245
+ suggestion: 'Use logger.info() or similar',
246
+ });
247
+ }
248
+ // Check for any type
249
+ if (code.includes(': any') || code.includes('<any>')) {
250
+ violations.push({
251
+ rule: 'typing',
252
+ severity: 'warning',
253
+ message: 'Using "any" type reduces type safety',
254
+ suggestion: 'Use a specific type or "unknown"',
255
+ });
256
+ suggestions.push('Replace "any" with specific types');
257
+ }
258
+ // Check for hardcoded strings that look like config
259
+ const configPatterns = /['"](?:http|https):\/\/|['"](?:localhost|127\.0\.0\.1)|['"](?:api|secret|key|token)/i;
260
+ if (configPatterns.test(code)) {
261
+ violations.push({
262
+ rule: 'config',
263
+ severity: 'warning',
264
+ message: 'Hardcoded configuration detected',
265
+ suggestion: 'Use environment variables or config files',
266
+ });
267
+ suggestions.push('Move hardcoded values to configuration');
268
+ }
269
+ }
270
+ /**
271
+ * Analyze code with IPatternService patterns
272
+ */
273
+ function analyzeCodeWithPatterns(code, patterns, violations, suggestions) {
274
+ // Reuse the same analysis logic
275
+ analyzeCode(code, patterns, violations, suggestions);
276
+ }
277
+ /**
278
+ * Tool definition for MCP registration
279
+ */
280
+ export const prevalidateToolDefinition = {
281
+ name: 'drift_prevalidate',
282
+ description: 'Validate proposed code BEFORE writing it. Returns violations, score, and suggestions. Use to catch pattern violations before they happen.',
283
+ inputSchema: {
284
+ type: 'object',
285
+ properties: {
286
+ code: {
287
+ type: 'string',
288
+ description: 'The code to validate',
289
+ },
290
+ targetFile: {
291
+ type: 'string',
292
+ description: 'Where the code will be written (relative path)',
293
+ },
294
+ kind: {
295
+ type: 'string',
296
+ enum: ['function', 'class', 'component', 'test', 'full-file'],
297
+ description: 'What kind of code is this (default: function)',
298
+ },
299
+ },
300
+ required: ['code', 'targetFile'],
301
+ },
302
+ };
303
+ //# sourceMappingURL=prevalidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prevalidate.js","sourceRoot":"","sources":["../../../src/tools/surgical/prevalidate.ts"],"names":[],"mappings":"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"}