driftdetect-mcp 0.4.6 → 0.5.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/enterprise-server.d.ts +7 -0
- package/dist/enterprise-server.d.ts.map +1 -1
- package/dist/enterprise-server.js +77 -7
- package/dist/enterprise-server.js.map +1 -1
- package/dist/tools/analysis/coupling.d.ts +56 -0
- package/dist/tools/analysis/coupling.d.ts.map +1 -0
- package/dist/tools/analysis/coupling.js +248 -0
- package/dist/tools/analysis/coupling.js.map +1 -0
- package/dist/tools/analysis/error-handling.d.ts +45 -0
- package/dist/tools/analysis/error-handling.d.ts.map +1 -0
- package/dist/tools/analysis/error-handling.js +220 -0
- package/dist/tools/analysis/error-handling.js.map +1 -0
- package/dist/tools/analysis/index.d.ts +11 -0
- package/dist/tools/analysis/index.d.ts.map +1 -0
- package/dist/tools/analysis/index.js +111 -0
- package/dist/tools/analysis/index.js.map +1 -0
- package/dist/tools/analysis/test-topology.d.ts +43 -0
- package/dist/tools/analysis/test-topology.d.ts.map +1 -0
- package/dist/tools/analysis/test-topology.js +294 -0
- package/dist/tools/analysis/test-topology.js.map +1 -0
- package/dist/tools/detail/code-examples.d.ts +20 -3
- package/dist/tools/detail/code-examples.d.ts.map +1 -1
- package/dist/tools/detail/code-examples.js +104 -0
- package/dist/tools/detail/code-examples.js.map +1 -1
- package/dist/tools/detail/index.d.ts +6 -4
- package/dist/tools/detail/index.d.ts.map +1 -1
- package/dist/tools/detail/index.js +44 -2
- package/dist/tools/detail/index.js.map +1 -1
- package/dist/tools/detail/pattern-get.d.ts +20 -3
- package/dist/tools/detail/pattern-get.d.ts.map +1 -1
- package/dist/tools/detail/pattern-get.js +87 -0
- package/dist/tools/detail/pattern-get.js.map +1 -1
- package/dist/tools/detail/wrappers.d.ts +97 -0
- package/dist/tools/detail/wrappers.d.ts.map +1 -0
- package/dist/tools/detail/wrappers.js +124 -0
- package/dist/tools/detail/wrappers.js.map +1 -0
- package/dist/tools/discovery/index.d.ts +3 -1
- package/dist/tools/discovery/index.d.ts.map +1 -1
- package/dist/tools/discovery/index.js +36 -1
- package/dist/tools/discovery/index.js.map +1 -1
- package/dist/tools/discovery/status.d.ts +16 -3
- package/dist/tools/discovery/status.d.ts.map +1 -1
- package/dist/tools/discovery/status.js +83 -1
- package/dist/tools/discovery/status.js.map +1 -1
- package/dist/tools/exploration/index.d.ts +2 -2
- package/dist/tools/exploration/index.d.ts.map +1 -1
- package/dist/tools/exploration/index.js +1 -1
- package/dist/tools/exploration/index.js.map +1 -1
- package/dist/tools/exploration/patterns-list.d.ts +21 -4
- package/dist/tools/exploration/patterns-list.d.ts.map +1 -1
- package/dist/tools/exploration/patterns-list.js +70 -0
- package/dist/tools/exploration/patterns-list.js.map +1 -1
- package/dist/tools/generation/__tests__/generation-tools.test.d.ts +6 -0
- package/dist/tools/generation/__tests__/generation-tools.test.d.ts.map +1 -0
- package/dist/tools/generation/__tests__/generation-tools.test.js +119 -0
- package/dist/tools/generation/__tests__/generation-tools.test.js.map +1 -0
- package/dist/tools/generation/explain.d.ts +75 -0
- package/dist/tools/generation/explain.d.ts.map +1 -0
- package/dist/tools/generation/explain.js +238 -0
- package/dist/tools/generation/explain.js.map +1 -0
- package/dist/tools/generation/index.d.ts +12 -0
- package/dist/tools/generation/index.d.ts.map +1 -0
- package/dist/tools/generation/index.js +90 -0
- package/dist/tools/generation/index.js.map +1 -0
- package/dist/tools/generation/suggest-changes.d.ts +64 -0
- package/dist/tools/generation/suggest-changes.d.ts.map +1 -0
- package/dist/tools/generation/suggest-changes.js +342 -0
- package/dist/tools/generation/suggest-changes.js.map +1 -0
- package/dist/tools/generation/validate-change.d.ts +76 -0
- package/dist/tools/generation/validate-change.d.ts.map +1 -0
- package/dist/tools/generation/validate-change.js +415 -0
- package/dist/tools/generation/validate-change.js.map +1 -0
- package/dist/tools/registry.d.ts +5 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +12 -0
- package/dist/tools/registry.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_suggest_changes - AI-Guided Refactoring Suggestions
|
|
3
|
+
*
|
|
4
|
+
* Analyzes code issues using LEARNED DATA from Drift's semantic analysis
|
|
5
|
+
* and provides specific, actionable suggestions for fixing pattern violations,
|
|
6
|
+
* security issues, or quality problems.
|
|
7
|
+
*
|
|
8
|
+
* Uses:
|
|
9
|
+
* - PatternStore: Patterns learned through semantic clustering
|
|
10
|
+
* - BoundaryStore: Data access points learned from scanning
|
|
11
|
+
* - ErrorHandlingAnalyzer: Error handling gaps
|
|
12
|
+
* - CallGraphAnalyzer: Security and reachability analysis
|
|
13
|
+
*/
|
|
14
|
+
import { PatternStore, BoundaryStore, createCallGraphAnalyzer, createErrorHandlingAnalyzer, } from 'driftdetect-core';
|
|
15
|
+
import { createResponseBuilder } from '../../infrastructure/index.js';
|
|
16
|
+
import * as fs from 'fs/promises';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Handler
|
|
20
|
+
// =============================================================================
|
|
21
|
+
export async function handleSuggestChanges(stores, projectRoot, args) {
|
|
22
|
+
const builder = createResponseBuilder();
|
|
23
|
+
const { target, issue, patternId, maxSuggestions = 5 } = args;
|
|
24
|
+
// Initialize stores
|
|
25
|
+
await stores.pattern.initialize();
|
|
26
|
+
// Resolve target file
|
|
27
|
+
const targetPath = path.isAbsolute(target)
|
|
28
|
+
? target
|
|
29
|
+
: path.join(projectRoot, target);
|
|
30
|
+
let fileContent;
|
|
31
|
+
try {
|
|
32
|
+
fileContent = await fs.readFile(targetPath, 'utf-8');
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return builder
|
|
36
|
+
.withSummary(`File not found: ${target}`)
|
|
37
|
+
.withData({
|
|
38
|
+
summary: `File not found: ${target}`,
|
|
39
|
+
target,
|
|
40
|
+
issueType: issue || 'all',
|
|
41
|
+
suggestions: [],
|
|
42
|
+
stats: { totalIssues: 0, bySeverity: {}, estimatedEffort: 'none' },
|
|
43
|
+
})
|
|
44
|
+
.withHints({
|
|
45
|
+
nextActions: ['Check the file path and try again'],
|
|
46
|
+
warnings: [`Could not read file: ${target}`],
|
|
47
|
+
})
|
|
48
|
+
.buildContent();
|
|
49
|
+
}
|
|
50
|
+
const suggestions = [];
|
|
51
|
+
const relativePath = path.relative(projectRoot, targetPath);
|
|
52
|
+
// Get all patterns to find outliers in this file
|
|
53
|
+
const allPatterns = stores.pattern.getAll();
|
|
54
|
+
const filePatterns = allPatterns.filter(p => p.locations.some(l => l.file === relativePath) ||
|
|
55
|
+
p.outliers.some(o => o.file === relativePath));
|
|
56
|
+
// ==========================================================================
|
|
57
|
+
// Use LEARNED data from BoundaryStore instead of re-extracting
|
|
58
|
+
// ==========================================================================
|
|
59
|
+
await stores.boundary.initialize();
|
|
60
|
+
const fileAccessInfo = stores.boundary.getFileAccess(relativePath);
|
|
61
|
+
let dataAccessPoints = [];
|
|
62
|
+
// Get data access points that Drift has already learned for this file
|
|
63
|
+
if (fileAccessInfo.length > 0 && fileAccessInfo[0]) {
|
|
64
|
+
dataAccessPoints = fileAccessInfo[0].accessPoints;
|
|
65
|
+
}
|
|
66
|
+
// Analyze based on issue type
|
|
67
|
+
if (!issue || issue === 'outlier' || issue === 'pattern-violation') {
|
|
68
|
+
const outlierSuggestions = analyzeOutliers(filePatterns, relativePath, fileContent, patternId);
|
|
69
|
+
suggestions.push(...outlierSuggestions);
|
|
70
|
+
}
|
|
71
|
+
if (!issue || issue === 'security') {
|
|
72
|
+
const securitySuggestions = await analyzeSecurityIssues(stores.boundary, relativePath, fileContent, dataAccessPoints, projectRoot);
|
|
73
|
+
suggestions.push(...securitySuggestions);
|
|
74
|
+
}
|
|
75
|
+
if (!issue || issue === 'error-handling') {
|
|
76
|
+
const errorSuggestions = await analyzeErrorHandlingGaps(relativePath, projectRoot);
|
|
77
|
+
suggestions.push(...errorSuggestions);
|
|
78
|
+
}
|
|
79
|
+
// Sort by priority and limit
|
|
80
|
+
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
81
|
+
suggestions.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
|
|
82
|
+
const limitedSuggestions = suggestions.slice(0, maxSuggestions);
|
|
83
|
+
// Calculate stats
|
|
84
|
+
const bySeverity = {};
|
|
85
|
+
for (const s of suggestions) {
|
|
86
|
+
bySeverity[s.priority] = (bySeverity[s.priority] || 0) + 1;
|
|
87
|
+
}
|
|
88
|
+
const effortMap = { trivial: 1, small: 2, medium: 4, large: 8 };
|
|
89
|
+
const totalEffort = limitedSuggestions.reduce((sum, s) => sum + effortMap[s.effort], 0);
|
|
90
|
+
const estimatedEffort = totalEffort <= 2 ? 'minimal' : totalEffort <= 6 ? 'moderate' : 'significant';
|
|
91
|
+
const summary = suggestions.length === 0
|
|
92
|
+
? `No issues found in ${relativePath}`
|
|
93
|
+
: `Found ${suggestions.length} issue(s) in ${relativePath}. ${limitedSuggestions.length} suggestion(s) provided.`;
|
|
94
|
+
return builder
|
|
95
|
+
.withSummary(summary)
|
|
96
|
+
.withData({
|
|
97
|
+
summary,
|
|
98
|
+
target: relativePath,
|
|
99
|
+
issueType: issue || 'all',
|
|
100
|
+
suggestions: limitedSuggestions,
|
|
101
|
+
stats: {
|
|
102
|
+
totalIssues: suggestions.length,
|
|
103
|
+
bySeverity,
|
|
104
|
+
estimatedEffort,
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
.withHints({
|
|
108
|
+
nextActions: limitedSuggestions.length > 0
|
|
109
|
+
? [
|
|
110
|
+
'Review suggestions and apply changes',
|
|
111
|
+
'Use drift_validate_change to verify fixes',
|
|
112
|
+
]
|
|
113
|
+
: ['File looks good! Consider running drift_test_topology to check test coverage'],
|
|
114
|
+
relatedTools: ['drift_validate_change', 'drift_code_examples', 'drift_impact_analysis'],
|
|
115
|
+
})
|
|
116
|
+
.buildContent();
|
|
117
|
+
}
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// Analysis Functions - Using SEMANTIC Analysis
|
|
120
|
+
// =============================================================================
|
|
121
|
+
function analyzeOutliers(patterns, file, content, specificPatternId) {
|
|
122
|
+
const suggestions = [];
|
|
123
|
+
const lines = content.split('\n');
|
|
124
|
+
for (const pattern of patterns) {
|
|
125
|
+
// Skip if looking for specific pattern and this isn't it
|
|
126
|
+
if (specificPatternId && pattern.id !== specificPatternId)
|
|
127
|
+
continue;
|
|
128
|
+
// Find outliers in this file
|
|
129
|
+
const fileOutliers = pattern.outliers.filter(o => o.file === file);
|
|
130
|
+
for (const outlier of fileOutliers) {
|
|
131
|
+
// Get the outlier code context
|
|
132
|
+
const startLine = Math.max(0, outlier.line - 1);
|
|
133
|
+
const endLine = Math.min(lines.length, outlier.line + 5);
|
|
134
|
+
const outlierCode = lines.slice(startLine, endLine).join('\n');
|
|
135
|
+
// Find a good example from the pattern
|
|
136
|
+
const goodExample = pattern.locations[0];
|
|
137
|
+
let exampleCode = '// Follow the established pattern';
|
|
138
|
+
if (goodExample) {
|
|
139
|
+
exampleCode = `// See ${goodExample.file}:${goodExample.line} for the correct pattern`;
|
|
140
|
+
}
|
|
141
|
+
suggestions.push({
|
|
142
|
+
id: `outlier-${pattern.id}-${outlier.line}`,
|
|
143
|
+
title: `Pattern violation: ${pattern.name}`,
|
|
144
|
+
description: `This code deviates from the established "${pattern.name}" pattern used ${pattern.locations.length} times in the codebase.`,
|
|
145
|
+
priority: pattern.confidence.score > 0.8 ? 'high' : 'medium',
|
|
146
|
+
category: 'outlier',
|
|
147
|
+
location: {
|
|
148
|
+
file,
|
|
149
|
+
startLine: outlier.line,
|
|
150
|
+
endLine: outlier.line + 5,
|
|
151
|
+
},
|
|
152
|
+
before: outlierCode,
|
|
153
|
+
after: exampleCode,
|
|
154
|
+
rationale: `The "${pattern.name}" pattern has ${pattern.locations.length} consistent implementations with ${Math.round(pattern.confidence.score * 100)}% confidence. This outlier should be refactored to match.`,
|
|
155
|
+
relatedPattern: {
|
|
156
|
+
id: pattern.id,
|
|
157
|
+
name: pattern.name,
|
|
158
|
+
confidence: pattern.confidence.score,
|
|
159
|
+
},
|
|
160
|
+
effort: 'small',
|
|
161
|
+
impact: `Improves consistency and maintainability`,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return suggestions;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Analyze security issues using LEARNED data access from BoundaryStore
|
|
169
|
+
*/
|
|
170
|
+
async function analyzeSecurityIssues(_boundaryStore, file, content, dataAccessPoints, projectRoot) {
|
|
171
|
+
const suggestions = [];
|
|
172
|
+
const lines = content.split('\n');
|
|
173
|
+
// Use LEARNED data access points from BoundaryStore
|
|
174
|
+
if (dataAccessPoints.length > 0) {
|
|
175
|
+
for (const access of dataAccessPoints) {
|
|
176
|
+
// Check for sensitive data access patterns
|
|
177
|
+
const sensitivePatterns = ['password', 'secret', 'token', 'api_key', 'apikey', 'ssn', 'credit_card'];
|
|
178
|
+
const sensitiveFields = access.fields.filter(f => sensitivePatterns.some(p => f.toLowerCase().includes(p)));
|
|
179
|
+
if (sensitiveFields.length > 0) {
|
|
180
|
+
suggestions.push({
|
|
181
|
+
id: `security-sensitive-data-${access.line}`,
|
|
182
|
+
title: `Sensitive data access: ${sensitiveFields.join(', ')}`,
|
|
183
|
+
description: `This code accesses sensitive fields (${sensitiveFields.join(', ')}) from table "${access.table}". Ensure proper authorization and audit logging.`,
|
|
184
|
+
priority: 'high',
|
|
185
|
+
category: 'security',
|
|
186
|
+
location: {
|
|
187
|
+
file,
|
|
188
|
+
startLine: access.line,
|
|
189
|
+
endLine: access.line,
|
|
190
|
+
},
|
|
191
|
+
before: access.context,
|
|
192
|
+
after: `// Ensure authorization check before accessing: ${sensitiveFields.join(', ')}\n// Add audit logging for sensitive data access`,
|
|
193
|
+
rationale: 'Sensitive data access should be protected by authorization checks and logged for audit purposes.',
|
|
194
|
+
effort: 'medium',
|
|
195
|
+
impact: 'Prevents unauthorized access to sensitive data',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
// Check for raw SQL (potential injection)
|
|
199
|
+
if (access.isRawSql) {
|
|
200
|
+
suggestions.push({
|
|
201
|
+
id: `security-raw-sql-${access.line}`,
|
|
202
|
+
title: 'Raw SQL detected - potential injection risk',
|
|
203
|
+
description: `Raw SQL query detected at line ${access.line}. Consider using parameterized queries or ORM methods.`,
|
|
204
|
+
priority: 'critical',
|
|
205
|
+
category: 'security',
|
|
206
|
+
location: {
|
|
207
|
+
file,
|
|
208
|
+
startLine: access.line,
|
|
209
|
+
endLine: access.line,
|
|
210
|
+
},
|
|
211
|
+
before: access.context,
|
|
212
|
+
after: `// Use parameterized queries:\n// db.query('SELECT * FROM ${access.table} WHERE id = ?', [id])`,
|
|
213
|
+
rationale: 'Raw SQL queries are vulnerable to SQL injection attacks. Use parameterized queries or ORM methods.',
|
|
214
|
+
effort: 'small',
|
|
215
|
+
impact: 'Prevents SQL injection vulnerabilities',
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Use call graph for reachability-based security analysis
|
|
221
|
+
try {
|
|
222
|
+
const callGraphAnalyzer = createCallGraphAnalyzer({ rootDir: projectRoot });
|
|
223
|
+
await callGraphAnalyzer.initialize();
|
|
224
|
+
const graph = callGraphAnalyzer.getGraph();
|
|
225
|
+
if (graph) {
|
|
226
|
+
// Find functions in this file that can reach sensitive data
|
|
227
|
+
const fileFunctions = callGraphAnalyzer.getFunctionsInFile(file);
|
|
228
|
+
for (const func of fileFunctions) {
|
|
229
|
+
const reachable = callGraphAnalyzer.getReachableDataFromFunction(`${file}:${func.name}`, { sensitiveOnly: true, maxDepth: 5 });
|
|
230
|
+
if (reachable.sensitiveFields.length > 0) {
|
|
231
|
+
const sensitiveFieldNames = reachable.sensitiveFields
|
|
232
|
+
.map(sf => `${sf.field.table}.${sf.field.field}`)
|
|
233
|
+
.slice(0, 3);
|
|
234
|
+
// Check if function has proper authorization
|
|
235
|
+
const hasAuthCheck = func.calls.some(c => {
|
|
236
|
+
const calleeId = c.calleeId || '';
|
|
237
|
+
return calleeId.toLowerCase().includes('auth') ||
|
|
238
|
+
calleeId.toLowerCase().includes('permission') ||
|
|
239
|
+
calleeId.toLowerCase().includes('authorize');
|
|
240
|
+
});
|
|
241
|
+
if (!hasAuthCheck && reachable.sensitiveFields.length > 0) {
|
|
242
|
+
suggestions.push({
|
|
243
|
+
id: `security-unprotected-sensitive-${func.startLine}`,
|
|
244
|
+
title: `Function "${func.name}" accesses sensitive data without auth check`,
|
|
245
|
+
description: `This function can reach sensitive fields (${sensitiveFieldNames.join(', ')}) but has no visible authorization check.`,
|
|
246
|
+
priority: 'high',
|
|
247
|
+
category: 'security',
|
|
248
|
+
location: {
|
|
249
|
+
file,
|
|
250
|
+
startLine: func.startLine,
|
|
251
|
+
endLine: func.endLine,
|
|
252
|
+
},
|
|
253
|
+
before: lines.slice(func.startLine - 1, func.startLine + 2).join('\n'),
|
|
254
|
+
after: `// Add authorization check:\n// if (!await authorize(user, 'read:sensitive')) throw new UnauthorizedError();`,
|
|
255
|
+
rationale: 'Functions that access sensitive data should verify authorization before proceeding.',
|
|
256
|
+
effort: 'medium',
|
|
257
|
+
impact: 'Ensures proper access control for sensitive data',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// Call graph not available - skip reachability analysis
|
|
266
|
+
}
|
|
267
|
+
return suggestions;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Analyze error handling gaps using ErrorHandlingAnalyzer
|
|
271
|
+
*/
|
|
272
|
+
async function analyzeErrorHandlingGaps(file, projectRoot) {
|
|
273
|
+
const suggestions = [];
|
|
274
|
+
try {
|
|
275
|
+
// Initialize call graph (required for error handling analysis)
|
|
276
|
+
const callGraphAnalyzer = createCallGraphAnalyzer({ rootDir: projectRoot });
|
|
277
|
+
await callGraphAnalyzer.initialize();
|
|
278
|
+
const callGraph = callGraphAnalyzer.getGraph();
|
|
279
|
+
if (!callGraph) {
|
|
280
|
+
return suggestions; // No call graph available
|
|
281
|
+
}
|
|
282
|
+
// Create error handling analyzer
|
|
283
|
+
const errorAnalyzer = createErrorHandlingAnalyzer({ rootDir: projectRoot });
|
|
284
|
+
errorAnalyzer.setCallGraph(callGraph);
|
|
285
|
+
errorAnalyzer.build();
|
|
286
|
+
// Get gaps for this specific file
|
|
287
|
+
const gaps = errorAnalyzer.getGaps({
|
|
288
|
+
files: [file],
|
|
289
|
+
minSeverity: 'medium',
|
|
290
|
+
limit: 10,
|
|
291
|
+
includeSuggestions: true,
|
|
292
|
+
});
|
|
293
|
+
for (const gap of gaps) {
|
|
294
|
+
suggestions.push(convertGapToSuggestion(gap, file));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
// Error handling analysis not available
|
|
299
|
+
}
|
|
300
|
+
return suggestions;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Convert an ErrorHandlingGap to a CodeSuggestion
|
|
304
|
+
*/
|
|
305
|
+
function convertGapToSuggestion(gap, file) {
|
|
306
|
+
const priorityMap = {
|
|
307
|
+
critical: 'critical',
|
|
308
|
+
high: 'high',
|
|
309
|
+
medium: 'medium',
|
|
310
|
+
low: 'low',
|
|
311
|
+
};
|
|
312
|
+
const effortMap = {
|
|
313
|
+
'no-try-catch': 'small',
|
|
314
|
+
'swallowed-error': 'trivial',
|
|
315
|
+
'unhandled-async': 'small',
|
|
316
|
+
'bare-catch': 'trivial',
|
|
317
|
+
};
|
|
318
|
+
const afterCodeMap = {
|
|
319
|
+
'no-try-catch': `try {\n // existing code\n} catch (error) {\n logger.error('Operation failed', { error });\n throw error;\n}`,
|
|
320
|
+
'swallowed-error': `catch (error) {\n logger.error('Error occurred', { error });\n // Handle or rethrow\n throw error;\n}`,
|
|
321
|
+
'unhandled-async': `try {\n await asyncOperation();\n} catch (error) {\n logger.error('Async operation failed', { error });\n throw error;\n}`,
|
|
322
|
+
'bare-catch': `catch (error) {\n if (error instanceof ValidationError) {\n // Handle validation error\n } else {\n throw error;\n }\n}`,
|
|
323
|
+
};
|
|
324
|
+
return {
|
|
325
|
+
id: `error-${gap.gapType}-${gap.line}`,
|
|
326
|
+
title: `Error handling gap: ${gap.gapType.replace(/-/g, ' ')}`,
|
|
327
|
+
description: gap.description,
|
|
328
|
+
priority: priorityMap[gap.severity] || 'medium',
|
|
329
|
+
category: 'error-handling',
|
|
330
|
+
location: {
|
|
331
|
+
file,
|
|
332
|
+
startLine: gap.line,
|
|
333
|
+
endLine: gap.line + 3,
|
|
334
|
+
},
|
|
335
|
+
before: `// ${gap.name} at line ${gap.line}`,
|
|
336
|
+
after: afterCodeMap[gap.gapType] || gap.suggestion,
|
|
337
|
+
rationale: gap.suggestion || 'Proper error handling improves reliability and debuggability.',
|
|
338
|
+
effort: effortMap[gap.gapType] || 'small',
|
|
339
|
+
impact: 'Improves error visibility and application reliability',
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=suggest-changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-changes.js","sourceRoot":"","sources":["../../../src/tools/generation/suggest-changes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_validate_change - Pre-Commit Pattern Validation
|
|
3
|
+
*
|
|
4
|
+
* Validates proposed code changes against established codebase patterns
|
|
5
|
+
* using SEMANTIC ANALYSIS (not regex!).
|
|
6
|
+
*
|
|
7
|
+
* Uses:
|
|
8
|
+
* - UnifiedLanguageProvider for cross-language semantic extraction
|
|
9
|
+
* - Pattern matchers for ORM/framework validation
|
|
10
|
+
* - LanguageIntelligence for semantic normalization
|
|
11
|
+
*
|
|
12
|
+
* Returns compliance score, violations, and suggestions for improvement.
|
|
13
|
+
*/
|
|
14
|
+
import { PatternStore } from 'driftdetect-core';
|
|
15
|
+
export interface ValidateChangeArgs {
|
|
16
|
+
file: string;
|
|
17
|
+
content?: string;
|
|
18
|
+
diff?: string;
|
|
19
|
+
strictMode?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface PatternViolation {
|
|
22
|
+
patternId: string;
|
|
23
|
+
patternName: string;
|
|
24
|
+
severity: 'error' | 'warning' | 'info';
|
|
25
|
+
message: string;
|
|
26
|
+
line?: number | undefined;
|
|
27
|
+
suggestion: string;
|
|
28
|
+
confidence: number;
|
|
29
|
+
}
|
|
30
|
+
export interface PatternCompliance {
|
|
31
|
+
patternId: string;
|
|
32
|
+
patternName: string;
|
|
33
|
+
status: 'compliant' | 'partial' | 'missing';
|
|
34
|
+
score: number;
|
|
35
|
+
details: string;
|
|
36
|
+
}
|
|
37
|
+
export interface SemanticValidation {
|
|
38
|
+
functions: {
|
|
39
|
+
total: number;
|
|
40
|
+
withErrorHandling: number;
|
|
41
|
+
async: number;
|
|
42
|
+
exported: number;
|
|
43
|
+
};
|
|
44
|
+
dataAccess: {
|
|
45
|
+
total: number;
|
|
46
|
+
rawSql: number;
|
|
47
|
+
sensitiveFields: number;
|
|
48
|
+
};
|
|
49
|
+
imports: {
|
|
50
|
+
total: number;
|
|
51
|
+
external: number;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export interface ValidateChangeData {
|
|
55
|
+
summary: string;
|
|
56
|
+
file: string;
|
|
57
|
+
overallScore: number;
|
|
58
|
+
status: 'pass' | 'warn' | 'fail';
|
|
59
|
+
violations: PatternViolation[];
|
|
60
|
+
compliance: PatternCompliance[];
|
|
61
|
+
semanticValidation: SemanticValidation;
|
|
62
|
+
suggestions: string[];
|
|
63
|
+
stats: {
|
|
64
|
+
patternsChecked: number;
|
|
65
|
+
compliant: number;
|
|
66
|
+
violations: number;
|
|
67
|
+
warnings: number;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export declare function handleValidateChange(patternStore: PatternStore, projectRoot: string, args: ValidateChangeArgs): Promise<{
|
|
71
|
+
content: Array<{
|
|
72
|
+
type: string;
|
|
73
|
+
text: string;
|
|
74
|
+
}>;
|
|
75
|
+
}>;
|
|
76
|
+
//# sourceMappingURL=validate-change.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-change.d.ts","sourceRoot":"","sources":["../../../src/tools/generation/validate-change.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,YAAY,EAIb,MAAM,kBAAkB,CAAC;AAS1B,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,iBAAiB,EAAE,MAAM,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE;QACL,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAMD,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA6J7D"}
|