driftdetect-mcp 0.4.6 → 0.5.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/dist/enterprise-server.d.ts +7 -0
- package/dist/enterprise-server.d.ts.map +1 -1
- package/dist/enterprise-server.js +79 -9
- 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/file-patterns.d.ts +3 -2
- package/dist/tools/detail/file-patterns.d.ts.map +1 -1
- package/dist/tools/detail/file-patterns.js +20 -12
- package/dist/tools/detail/file-patterns.js.map +1 -1
- package/dist/tools/detail/files-list.d.ts +3 -3
- package/dist/tools/detail/files-list.d.ts.map +1 -1
- package/dist/tools/detail/files-list.js +33 -16
- package/dist/tools/detail/files-list.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,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_explain - Comprehensive Code Explanation
|
|
3
|
+
* Uses LEARNED DATA from Drift's pattern detection and boundary analysis
|
|
4
|
+
*
|
|
5
|
+
* This tool leverages what Drift has already learned about the codebase:
|
|
6
|
+
* - PatternStore: Patterns discovered through semantic clustering
|
|
7
|
+
* - BoundaryStore: Data access points learned from scanning
|
|
8
|
+
* - CallGraphStore: Call relationships and reachability
|
|
9
|
+
*/
|
|
10
|
+
import { PatternStore, ManifestStore, BoundaryStore, CallGraphStore } from 'driftdetect-core';
|
|
11
|
+
export type ExplanationDepth = 'summary' | 'detailed' | 'comprehensive';
|
|
12
|
+
export type ExplanationFocus = 'security' | 'performance' | 'architecture' | 'testing';
|
|
13
|
+
export interface ExplainArgs {
|
|
14
|
+
target: string;
|
|
15
|
+
depth?: ExplanationDepth;
|
|
16
|
+
focus?: ExplanationFocus;
|
|
17
|
+
}
|
|
18
|
+
export interface CodeExplanation {
|
|
19
|
+
summary: string;
|
|
20
|
+
purpose: string;
|
|
21
|
+
context: {
|
|
22
|
+
module: string;
|
|
23
|
+
role: string;
|
|
24
|
+
importance: 'critical' | 'high' | 'medium' | 'low';
|
|
25
|
+
};
|
|
26
|
+
patterns: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
category: string;
|
|
29
|
+
compliance: 'follows' | 'partial' | 'deviates';
|
|
30
|
+
note: string;
|
|
31
|
+
}>;
|
|
32
|
+
dependencies: {
|
|
33
|
+
imports: string[];
|
|
34
|
+
usedBy: string[];
|
|
35
|
+
calls: string[];
|
|
36
|
+
dataAccess: Array<{
|
|
37
|
+
table: string;
|
|
38
|
+
operation: string;
|
|
39
|
+
fields: string[];
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
42
|
+
security?: {
|
|
43
|
+
sensitiveData: string[];
|
|
44
|
+
accessLevel: string;
|
|
45
|
+
concerns: string[];
|
|
46
|
+
reachableSensitiveFields?: string[];
|
|
47
|
+
};
|
|
48
|
+
semantics?: {
|
|
49
|
+
functions: number;
|
|
50
|
+
asyncFunctions: number;
|
|
51
|
+
exportedFunctions: number;
|
|
52
|
+
dataAccessPoints: number;
|
|
53
|
+
frameworks: string[];
|
|
54
|
+
};
|
|
55
|
+
insights: string[];
|
|
56
|
+
nextSteps: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface ExplainData {
|
|
59
|
+
target: string;
|
|
60
|
+
depth: ExplanationDepth;
|
|
61
|
+
focus?: ExplanationFocus | undefined;
|
|
62
|
+
explanation: CodeExplanation;
|
|
63
|
+
}
|
|
64
|
+
export declare function handleExplain(stores: {
|
|
65
|
+
pattern: PatternStore;
|
|
66
|
+
manifest: ManifestStore;
|
|
67
|
+
boundary: BoundaryStore;
|
|
68
|
+
callGraph: CallGraphStore;
|
|
69
|
+
}, projectRoot: string, args: ExplainArgs): Promise<{
|
|
70
|
+
content: Array<{
|
|
71
|
+
type: string;
|
|
72
|
+
text: string;
|
|
73
|
+
}>;
|
|
74
|
+
}>;
|
|
75
|
+
//# sourceMappingURL=explain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/tools/generation/explain.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAG3D,MAAM,kBAAkB,CAAC;AAK1B,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,eAAe,CAAC;AACxE,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,aAAa,GAAG,cAAc,GAAG,SAAS,CAAC;AAEvF,MAAM,WAAW,WAAW;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAAE;AAEpG,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;KAAE,CAAC;IAC9F,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClH,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IAClJ,QAAQ,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACrH,SAAS,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACrI,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,KAAK,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAAC,WAAW,EAAE,eAAe,CAAC;CAAE;AAE7I,wBAAsB,aAAa,CACjC,MAAM,EAAE;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,EAC9G,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GACrC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA2C7D"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_explain - Comprehensive Code Explanation
|
|
3
|
+
* Uses LEARNED DATA from Drift's pattern detection and boundary analysis
|
|
4
|
+
*
|
|
5
|
+
* This tool leverages what Drift has already learned about the codebase:
|
|
6
|
+
* - PatternStore: Patterns discovered through semantic clustering
|
|
7
|
+
* - BoundaryStore: Data access points learned from scanning
|
|
8
|
+
* - CallGraphStore: Call relationships and reachability
|
|
9
|
+
*/
|
|
10
|
+
import { PatternStore, ManifestStore, BoundaryStore, CallGraphStore, createCallGraphAnalyzer, } from 'driftdetect-core';
|
|
11
|
+
import { createResponseBuilder } from '../../infrastructure/index.js';
|
|
12
|
+
import * as fs from 'fs/promises';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
export async function handleExplain(stores, projectRoot, args) {
|
|
15
|
+
const builder = createResponseBuilder();
|
|
16
|
+
const { target, depth = 'detailed', focus } = args;
|
|
17
|
+
await stores.pattern.initialize();
|
|
18
|
+
await stores.manifest.load();
|
|
19
|
+
const isFile = target.includes('/') || target.includes('.');
|
|
20
|
+
const relativePath = isFile ? (target.startsWith('/') ? path.relative(projectRoot, target) : target) : null;
|
|
21
|
+
let fileContent = null;
|
|
22
|
+
if (relativePath) {
|
|
23
|
+
try {
|
|
24
|
+
fileContent = await fs.readFile(path.join(projectRoot, relativePath), 'utf-8');
|
|
25
|
+
}
|
|
26
|
+
catch { /* not found */ }
|
|
27
|
+
}
|
|
28
|
+
if (!fileContent && !relativePath) {
|
|
29
|
+
return builder.withSummary(`Symbol search not yet implemented for: ${target}`)
|
|
30
|
+
.withData({ target, depth, focus, explanation: {
|
|
31
|
+
summary: `Could not find target: ${target}`, purpose: 'Unknown',
|
|
32
|
+
context: { module: 'unknown', role: 'unknown', importance: 'low' },
|
|
33
|
+
patterns: [], dependencies: { imports: [], usedBy: [], calls: [], dataAccess: [] },
|
|
34
|
+
insights: ['Target not found - try providing a file path'], nextSteps: ['Use drift_files_list to find relevant files'],
|
|
35
|
+
} }).buildContent();
|
|
36
|
+
}
|
|
37
|
+
// Use LEARNED data from BoundaryStore instead of re-extracting
|
|
38
|
+
await stores.boundary.initialize();
|
|
39
|
+
const fileAccessInfo = stores.boundary.getFileAccess(relativePath || '');
|
|
40
|
+
let dataAccessPoints = [];
|
|
41
|
+
// Get data access points that Drift has already learned for this file
|
|
42
|
+
if (fileAccessInfo.length > 0 && fileAccessInfo[0]) {
|
|
43
|
+
dataAccessPoints = fileAccessInfo[0].accessPoints;
|
|
44
|
+
}
|
|
45
|
+
const allPatterns = stores.pattern.getAll();
|
|
46
|
+
const filePatterns = relativePath ? allPatterns.filter(p => p.locations.some(l => l.file === relativePath) || p.outliers.some(o => o.file === relativePath)) : [];
|
|
47
|
+
const explanation = await analyzeCode(relativePath || target, fileContent || '', filePatterns, dataAccessPoints, projectRoot, depth, focus);
|
|
48
|
+
return builder.withSummary(explanation.summary)
|
|
49
|
+
.withData({ target: relativePath || target, depth, focus, explanation })
|
|
50
|
+
.withHints({ nextActions: explanation.nextSteps.slice(0, 3), relatedTools: ['drift_impact_analysis', 'drift_reachability', 'drift_code_examples'] })
|
|
51
|
+
.buildContent();
|
|
52
|
+
}
|
|
53
|
+
async function analyzeCode(file, _content, patterns, dataAccessPoints, projectRoot, depth, focus) {
|
|
54
|
+
const purpose = inferPurpose(file, dataAccessPoints);
|
|
55
|
+
const context = inferContext(file, patterns, dataAccessPoints);
|
|
56
|
+
const patternAnalysis = analyzePatterns(patterns, file);
|
|
57
|
+
const dependencies = await extractDependencies(dataAccessPoints, file, projectRoot);
|
|
58
|
+
let security;
|
|
59
|
+
if (depth !== 'summary' || focus === 'security') {
|
|
60
|
+
security = await analyzeSecurityContext(file, dataAccessPoints, projectRoot);
|
|
61
|
+
}
|
|
62
|
+
let semantics;
|
|
63
|
+
if (dataAccessPoints.length > 0) {
|
|
64
|
+
semantics = { functions: 0, asyncFunctions: 0, exportedFunctions: 0, dataAccessPoints: dataAccessPoints.length, frameworks: detectFrameworks(dataAccessPoints) };
|
|
65
|
+
}
|
|
66
|
+
const insights = generateInsights(file, patterns, dependencies, security, dataAccessPoints, focus);
|
|
67
|
+
const nextSteps = generateNextSteps(file, patterns, security, dataAccessPoints, focus);
|
|
68
|
+
const summary = buildSummary(file, purpose, context, patternAnalysis, security, semantics);
|
|
69
|
+
const result = { summary, purpose, context, patterns: patternAnalysis, dependencies, insights, nextSteps };
|
|
70
|
+
if (security)
|
|
71
|
+
result.security = security;
|
|
72
|
+
if (semantics)
|
|
73
|
+
result.semantics = semantics;
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
function inferPurpose(file, dataAccessPoints) {
|
|
77
|
+
const fileName = path.basename(file, path.extname(file));
|
|
78
|
+
if (dataAccessPoints.length > 0) {
|
|
79
|
+
const tables = [...new Set(dataAccessPoints.map(a => a.table))];
|
|
80
|
+
const operations = [...new Set(dataAccessPoints.map(a => a.operation))];
|
|
81
|
+
return `Data access layer for ${tables.join(', ')} (${operations.join(', ')})`;
|
|
82
|
+
}
|
|
83
|
+
if (/controller/i.test(fileName))
|
|
84
|
+
return 'HTTP request handler';
|
|
85
|
+
if (/service/i.test(fileName))
|
|
86
|
+
return 'Business logic service';
|
|
87
|
+
if (/repository/i.test(fileName))
|
|
88
|
+
return 'Data access layer';
|
|
89
|
+
if (/middleware/i.test(fileName))
|
|
90
|
+
return 'Request/response interceptor';
|
|
91
|
+
return 'Module providing specific functionality';
|
|
92
|
+
}
|
|
93
|
+
function inferContext(file, patterns, dataAccessPoints) {
|
|
94
|
+
const parts = file.split('/');
|
|
95
|
+
const module = parts.length > 1 ? parts[parts.length - 2] ?? 'root' : 'root';
|
|
96
|
+
let role = 'utility';
|
|
97
|
+
if (dataAccessPoints.length > 0)
|
|
98
|
+
role = 'data layer';
|
|
99
|
+
else if (patterns.some(p => p.category === 'api'))
|
|
100
|
+
role = 'API layer';
|
|
101
|
+
else if (patterns.some(p => p.category === 'data-access'))
|
|
102
|
+
role = 'data layer';
|
|
103
|
+
let importance = 'medium';
|
|
104
|
+
const sensitivePatterns = ['password', 'secret', 'token', 'api_key', 'ssn'];
|
|
105
|
+
if (dataAccessPoints.some(a => a.fields.some(f => sensitivePatterns.some(p => f.toLowerCase().includes(p)))))
|
|
106
|
+
importance = 'critical';
|
|
107
|
+
else if (dataAccessPoints.length > 0)
|
|
108
|
+
importance = 'high';
|
|
109
|
+
return { module, role, importance };
|
|
110
|
+
}
|
|
111
|
+
function analyzePatterns(patterns, file) {
|
|
112
|
+
return patterns.slice(0, 5).map(p => {
|
|
113
|
+
const isOutlier = p.outliers.some(o => o.file === file);
|
|
114
|
+
const isLocation = p.locations.some(l => l.file === file);
|
|
115
|
+
return {
|
|
116
|
+
name: p.name, category: p.category,
|
|
117
|
+
compliance: isOutlier ? 'deviates' : isLocation ? 'follows' : 'partial',
|
|
118
|
+
note: isOutlier ? `Deviates from ${p.locations.length} implementations` : `Consistent with ${p.locations.length} implementations`,
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async function extractDependencies(dataAccessPoints, file, projectRoot) {
|
|
123
|
+
const imports = [];
|
|
124
|
+
const usedBy = [];
|
|
125
|
+
const dataAccess = [];
|
|
126
|
+
for (const access of dataAccessPoints) {
|
|
127
|
+
dataAccess.push({ table: access.table, operation: access.operation, fields: access.fields });
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const analyzer = createCallGraphAnalyzer({ rootDir: projectRoot });
|
|
131
|
+
await analyzer.initialize();
|
|
132
|
+
const graph = analyzer.getGraph();
|
|
133
|
+
if (graph) {
|
|
134
|
+
for (const func of analyzer.getFunctionsInFile(file)) {
|
|
135
|
+
for (const caller of func.calledBy) {
|
|
136
|
+
const callerFunc = graph.functions.get(caller.callerId);
|
|
137
|
+
if (callerFunc && !usedBy.includes(callerFunc.qualifiedName))
|
|
138
|
+
usedBy.push(callerFunc.qualifiedName);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch { /* Call graph not available */ }
|
|
144
|
+
return { imports: imports.slice(0, 10), usedBy: usedBy.slice(0, 10), calls: [], dataAccess };
|
|
145
|
+
}
|
|
146
|
+
async function analyzeSecurityContext(file, dataAccessPoints, projectRoot) {
|
|
147
|
+
const sensitiveData = [];
|
|
148
|
+
const concerns = [];
|
|
149
|
+
const reachableSensitiveFields = [];
|
|
150
|
+
const sensitivePatterns = ['password', 'secret', 'token', 'api_key', 'ssn'];
|
|
151
|
+
for (const access of dataAccessPoints) {
|
|
152
|
+
for (const field of access.fields) {
|
|
153
|
+
if (sensitivePatterns.some(p => field.toLowerCase().includes(p)) && !sensitiveData.includes(field))
|
|
154
|
+
sensitiveData.push(field);
|
|
155
|
+
}
|
|
156
|
+
if (access.isRawSql)
|
|
157
|
+
concerns.push(`Raw SQL at line ${access.line}`);
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
const analyzer = createCallGraphAnalyzer({ rootDir: projectRoot });
|
|
161
|
+
await analyzer.initialize();
|
|
162
|
+
const graph = analyzer.getGraph();
|
|
163
|
+
if (graph) {
|
|
164
|
+
for (const func of analyzer.getFunctionsInFile(file)) {
|
|
165
|
+
const reachable = analyzer.getReachableDataFromFunction(`${file}:${func.name}`, { sensitiveOnly: true, maxDepth: 5 });
|
|
166
|
+
for (const sf of reachable.sensitiveFields) {
|
|
167
|
+
const fieldName = `${sf.field.table}.${sf.field.field}`;
|
|
168
|
+
if (!reachableSensitiveFields.includes(fieldName))
|
|
169
|
+
reachableSensitiveFields.push(fieldName);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch { /* Call graph not available */ }
|
|
175
|
+
if (!sensitiveData.length && !concerns.length && !reachableSensitiveFields.length)
|
|
176
|
+
return undefined;
|
|
177
|
+
const accessLevel = file.includes('admin') ? 'admin-only' : file.includes('api') ? 'public' : 'internal';
|
|
178
|
+
const result = { sensitiveData, accessLevel, concerns };
|
|
179
|
+
if (reachableSensitiveFields.length > 0)
|
|
180
|
+
result.reachableSensitiveFields = reachableSensitiveFields;
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
function detectFrameworks(dataAccessPoints) {
|
|
184
|
+
const frameworks = new Set();
|
|
185
|
+
const frameworkNames = {
|
|
186
|
+
'supabase': 'Supabase', 'prisma': 'Prisma', 'typeorm': 'TypeORM', 'sequelize': 'Sequelize',
|
|
187
|
+
'mongoose': 'Mongoose', 'django': 'Django', 'sqlalchemy': 'SQLAlchemy', 'efcore': 'Entity Framework',
|
|
188
|
+
'eloquent': 'Laravel/Eloquent', 'spring-data': 'Spring Data JPA', 'hibernate': 'Hibernate',
|
|
189
|
+
'drizzle': 'Drizzle', 'knex': 'Knex', 'doctrine': 'Doctrine',
|
|
190
|
+
};
|
|
191
|
+
for (const access of dataAccessPoints) {
|
|
192
|
+
if (access.framework)
|
|
193
|
+
frameworks.add(frameworkNames[access.framework] || access.framework);
|
|
194
|
+
}
|
|
195
|
+
return Array.from(frameworks);
|
|
196
|
+
}
|
|
197
|
+
function generateInsights(_file, patterns, _deps, security, dataAccessPoints, _focus) {
|
|
198
|
+
const insights = [];
|
|
199
|
+
if (dataAccessPoints.length > 0) {
|
|
200
|
+
const tables = [...new Set(dataAccessPoints.map(a => a.table))];
|
|
201
|
+
insights.push(`Accesses ${dataAccessPoints.length} data point(s) across ${tables.length} table(s)`);
|
|
202
|
+
}
|
|
203
|
+
if (patterns.length)
|
|
204
|
+
insights.push(`Participates in ${patterns.length} pattern(s)`);
|
|
205
|
+
if (security?.concerns.length)
|
|
206
|
+
insights.push(`⚠️ ${security.concerns.length} security concern(s)`);
|
|
207
|
+
if (security?.reachableSensitiveFields?.length)
|
|
208
|
+
insights.push(`🔒 Can reach ${security.reachableSensitiveFields.length} sensitive field(s)`);
|
|
209
|
+
return insights;
|
|
210
|
+
}
|
|
211
|
+
function generateNextSteps(file, patterns, security, dataAccessPoints, _focus) {
|
|
212
|
+
const steps = [];
|
|
213
|
+
if (security?.concerns.length)
|
|
214
|
+
steps.push('Run drift_suggest_changes with issue="security"');
|
|
215
|
+
if (security?.reachableSensitiveFields?.length)
|
|
216
|
+
steps.push('Use drift_reachability to trace sensitive data');
|
|
217
|
+
const outliers = patterns.filter(p => p.outliers.some(o => o.file === file));
|
|
218
|
+
if (outliers.length && outliers[0])
|
|
219
|
+
steps.push(`Review pattern "${outliers[0].name}" with drift_pattern_get`);
|
|
220
|
+
if (dataAccessPoints.some(a => a.isRawSql))
|
|
221
|
+
steps.push('Review raw SQL queries for injection vulnerabilities');
|
|
222
|
+
if (!steps.length)
|
|
223
|
+
steps.push('Use drift_code_examples to see similar implementations');
|
|
224
|
+
return steps;
|
|
225
|
+
}
|
|
226
|
+
function buildSummary(file, purpose, context, patterns, security, semantics) {
|
|
227
|
+
const fileName = path.basename(file);
|
|
228
|
+
let summary = `**${fileName}** is a ${context.importance}-importance ${context.role} file. ${purpose}. `;
|
|
229
|
+
if (semantics)
|
|
230
|
+
summary += `${semantics.dataAccessPoints} data access point(s). `;
|
|
231
|
+
const deviates = patterns.filter(p => p.compliance === 'deviates').length;
|
|
232
|
+
if (deviates)
|
|
233
|
+
summary += `⚠️ Deviates from ${deviates} pattern(s). `;
|
|
234
|
+
if (security?.concerns.length)
|
|
235
|
+
summary += `🔒 ${security.concerns.length} security concern(s).`;
|
|
236
|
+
return summary;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=explain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../../src/tools/generation/explain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Tools
|
|
3
|
+
*
|
|
4
|
+
* AI-powered tools for code generation, validation, and explanation.
|
|
5
|
+
* These tools close the loop between understanding and action.
|
|
6
|
+
*/
|
|
7
|
+
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
8
|
+
export declare const GENERATION_TOOLS: Tool[];
|
|
9
|
+
export { handleSuggestChanges } from './suggest-changes.js';
|
|
10
|
+
export { handleValidateChange } from './validate-change.js';
|
|
11
|
+
export { handleExplain } from './explain.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/generation/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAK/D,eAAO,MAAM,gBAAgB,EAAE,IAAI,EA6ElC,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Tools
|
|
3
|
+
*
|
|
4
|
+
* AI-powered tools for code generation, validation, and explanation.
|
|
5
|
+
* These tools close the loop between understanding and action.
|
|
6
|
+
*/
|
|
7
|
+
const ISSUE_TYPES = ['outlier', 'security', 'coupling', 'error-handling', 'test-coverage', 'pattern-violation'];
|
|
8
|
+
const EXPLANATION_DEPTHS = ['summary', 'detailed', 'comprehensive'];
|
|
9
|
+
export const GENERATION_TOOLS = [
|
|
10
|
+
{
|
|
11
|
+
name: 'drift_suggest_changes',
|
|
12
|
+
description: 'Get AI-guided suggestions for fixing pattern violations, security issues, or code quality problems. Returns specific code changes with before/after examples and rationale.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
target: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
description: 'File path or function name to analyze',
|
|
19
|
+
},
|
|
20
|
+
issue: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
enum: ISSUE_TYPES,
|
|
23
|
+
description: 'Type of issue to address: outlier (pattern violation), security, coupling, error-handling, test-coverage, pattern-violation',
|
|
24
|
+
},
|
|
25
|
+
patternId: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'Specific pattern ID if addressing an outlier (from drift_patterns_list)',
|
|
28
|
+
},
|
|
29
|
+
maxSuggestions: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
description: 'Maximum suggestions to return (default: 3)',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
required: ['target'],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'drift_validate_change',
|
|
39
|
+
description: 'Validate proposed code changes against codebase patterns. Returns compliance score, violations, and suggestions. Use before committing changes to ensure consistency.',
|
|
40
|
+
inputSchema: {
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
file: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
description: 'File path where the change will be made',
|
|
46
|
+
},
|
|
47
|
+
content: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: 'The proposed code content to validate',
|
|
50
|
+
},
|
|
51
|
+
diff: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
description: 'Alternative: unified diff format of the change',
|
|
54
|
+
},
|
|
55
|
+
strictMode: {
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
description: 'Fail on any pattern violation (default: false)',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
required: ['file'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'drift_explain',
|
|
65
|
+
description: 'Get a comprehensive explanation of code in context of the codebase. Combines pattern analysis, call graph, security implications, and dependencies into a coherent narrative.',
|
|
66
|
+
inputSchema: {
|
|
67
|
+
type: 'object',
|
|
68
|
+
properties: {
|
|
69
|
+
target: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
description: 'File path, function name, or code symbol to explain',
|
|
72
|
+
},
|
|
73
|
+
depth: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
enum: EXPLANATION_DEPTHS,
|
|
76
|
+
description: 'Level of detail: summary (quick overview), detailed (patterns + dependencies), comprehensive (full analysis)',
|
|
77
|
+
},
|
|
78
|
+
focus: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
description: 'Optional focus area: security, performance, architecture, testing',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
required: ['target'],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
export { handleSuggestChanges } from './suggest-changes.js';
|
|
88
|
+
export { handleValidateChange } from './validate-change.js';
|
|
89
|
+
export { handleExplain } from './explain.js';
|
|
90
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/generation/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC;AAChH,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;AAEpE,MAAM,CAAC,MAAM,gBAAgB,GAAW;IACtC;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,6KAA6K;QAC1L,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uCAAuC;iBACrD;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,WAAW;oBACjB,WAAW,EAAE,6HAA6H;iBAC3I;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yEAAyE;iBACvF;gBACD,cAAc,EAAE;oBACd,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,4CAA4C;iBAC1D;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,uKAAuK;QACpL,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yCAAyC;iBACvD;gBACD,OAAO,EAAE;oBACP,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uCAAuC;iBACrD;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gDAAgD;iBAC9D;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,gDAAgD;iBAC9D;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD;QACE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,+KAA+K;QAC5L,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,qDAAqD;iBACnE;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,kBAAkB;oBACxB,WAAW,EAAE,8GAA8G;iBAC5H;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,mEAAmE;iBACjF;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;KACF;CACF,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
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 } from 'driftdetect-core';
|
|
15
|
+
export type IssueType = 'outlier' | 'security' | 'coupling' | 'error-handling' | 'test-coverage' | 'pattern-violation';
|
|
16
|
+
export interface SuggestChangesArgs {
|
|
17
|
+
target: string;
|
|
18
|
+
issue?: IssueType;
|
|
19
|
+
patternId?: string;
|
|
20
|
+
maxSuggestions?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface CodeSuggestion {
|
|
23
|
+
id: string;
|
|
24
|
+
title: string;
|
|
25
|
+
description: string;
|
|
26
|
+
priority: 'critical' | 'high' | 'medium' | 'low';
|
|
27
|
+
category: IssueType;
|
|
28
|
+
location: {
|
|
29
|
+
file: string;
|
|
30
|
+
startLine: number;
|
|
31
|
+
endLine: number;
|
|
32
|
+
};
|
|
33
|
+
before: string;
|
|
34
|
+
after: string;
|
|
35
|
+
rationale: string;
|
|
36
|
+
relatedPattern?: {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
confidence: number;
|
|
40
|
+
};
|
|
41
|
+
effort: 'trivial' | 'small' | 'medium' | 'large';
|
|
42
|
+
impact: string;
|
|
43
|
+
}
|
|
44
|
+
export interface SuggestChangesData {
|
|
45
|
+
summary: string;
|
|
46
|
+
target: string;
|
|
47
|
+
issueType: IssueType | 'all';
|
|
48
|
+
suggestions: CodeSuggestion[];
|
|
49
|
+
stats: {
|
|
50
|
+
totalIssues: number;
|
|
51
|
+
bySeverity: Record<string, number>;
|
|
52
|
+
estimatedEffort: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export declare function handleSuggestChanges(stores: {
|
|
56
|
+
pattern: PatternStore;
|
|
57
|
+
boundary: BoundaryStore;
|
|
58
|
+
}, projectRoot: string, args: SuggestChangesArgs): Promise<{
|
|
59
|
+
content: Array<{
|
|
60
|
+
type: string;
|
|
61
|
+
text: string;
|
|
62
|
+
}>;
|
|
63
|
+
}>;
|
|
64
|
+
//# sourceMappingURL=suggest-changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-changes.d.ts","sourceRoot":"","sources":["../../../src/tools/generation/suggest-changes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,YAAY,EACZ,aAAa,EAMd,MAAM,kBAAkB,CAAC;AAS1B,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,UAAU,GACV,UAAU,GACV,gBAAgB,GAChB,eAAe,GACf,mBAAmB,CAAC;AAExB,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACjD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,KAAK,CAAC;IAC7B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAMD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE;IACN,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,aAAa,CAAC;CACzB,EACD,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,CA+H7D"}
|