driftdetect-mcp 0.3.0 → 0.4.2
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/bin/server.d.ts +12 -2
- package/dist/bin/server.d.ts.map +1 -1
- package/dist/bin/server.js +25 -5
- package/dist/bin/server.js.map +1 -1
- package/dist/enterprise-server.d.ts +78 -0
- package/dist/enterprise-server.d.ts.map +1 -0
- package/dist/enterprise-server.js +201 -0
- package/dist/enterprise-server.js.map +1 -0
- package/dist/index.d.ts +15 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/cache.d.ts +86 -0
- package/dist/infrastructure/cache.d.ts.map +1 -0
- package/dist/infrastructure/cache.js +271 -0
- package/dist/infrastructure/cache.js.map +1 -0
- package/dist/infrastructure/cursor-manager.d.ts +86 -0
- package/dist/infrastructure/cursor-manager.d.ts.map +1 -0
- package/dist/infrastructure/cursor-manager.js +175 -0
- package/dist/infrastructure/cursor-manager.js.map +1 -0
- package/dist/infrastructure/error-handler.d.ts +82 -0
- package/dist/infrastructure/error-handler.d.ts.map +1 -0
- package/dist/infrastructure/error-handler.js +226 -0
- package/dist/infrastructure/error-handler.js.map +1 -0
- package/dist/infrastructure/index.d.ts +19 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +26 -0
- package/dist/infrastructure/index.js.map +1 -0
- package/dist/infrastructure/metrics.d.ts +104 -0
- package/dist/infrastructure/metrics.d.ts.map +1 -0
- package/dist/infrastructure/metrics.js +291 -0
- package/dist/infrastructure/metrics.js.map +1 -0
- package/dist/infrastructure/rate-limiter.d.ts +59 -0
- package/dist/infrastructure/rate-limiter.d.ts.map +1 -0
- package/dist/infrastructure/rate-limiter.js +132 -0
- package/dist/infrastructure/rate-limiter.js.map +1 -0
- package/dist/infrastructure/response-builder.d.ts +104 -0
- package/dist/infrastructure/response-builder.d.ts.map +1 -0
- package/dist/infrastructure/response-builder.js +207 -0
- package/dist/infrastructure/response-builder.js.map +1 -0
- package/dist/infrastructure/token-estimator.d.ts +48 -0
- package/dist/infrastructure/token-estimator.d.ts.map +1 -0
- package/dist/infrastructure/token-estimator.js +131 -0
- package/dist/infrastructure/token-estimator.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1136 -18
- package/dist/server.js.map +1 -1
- package/dist/tools/detail/code-examples.d.ts +33 -0
- package/dist/tools/detail/code-examples.d.ts.map +1 -0
- package/dist/tools/detail/code-examples.js +126 -0
- package/dist/tools/detail/code-examples.js.map +1 -0
- package/dist/tools/detail/dna-check.d.ts +32 -0
- package/dist/tools/detail/dna-check.d.ts.map +1 -0
- package/dist/tools/detail/dna-check.js +231 -0
- package/dist/tools/detail/dna-check.js.map +1 -0
- package/dist/tools/detail/dna-profile.d.ts +37 -0
- package/dist/tools/detail/dna-profile.d.ts.map +1 -0
- package/dist/tools/detail/dna-profile.js +101 -0
- package/dist/tools/detail/dna-profile.js.map +1 -0
- package/dist/tools/detail/file-patterns.d.ts +39 -0
- package/dist/tools/detail/file-patterns.d.ts.map +1 -0
- package/dist/tools/detail/file-patterns.js +103 -0
- package/dist/tools/detail/file-patterns.js.map +1 -0
- package/dist/tools/detail/files-list.d.ts +30 -0
- package/dist/tools/detail/files-list.d.ts.map +1 -0
- package/dist/tools/detail/files-list.js +99 -0
- package/dist/tools/detail/files-list.js.map +1 -0
- package/dist/tools/detail/impact-analysis.d.ts +53 -0
- package/dist/tools/detail/impact-analysis.d.ts.map +1 -0
- package/dist/tools/detail/impact-analysis.js +130 -0
- package/dist/tools/detail/impact-analysis.js.map +1 -0
- package/dist/tools/detail/index.d.ts +23 -0
- package/dist/tools/detail/index.d.ts.map +1 -0
- package/dist/tools/detail/index.js +200 -0
- package/dist/tools/detail/index.js.map +1 -0
- package/dist/tools/detail/pattern-get.d.ts +45 -0
- package/dist/tools/detail/pattern-get.d.ts.map +1 -0
- package/dist/tools/detail/pattern-get.js +87 -0
- package/dist/tools/detail/pattern-get.js.map +1 -0
- package/dist/tools/detail/reachability.d.ts +60 -0
- package/dist/tools/detail/reachability.d.ts.map +1 -0
- package/dist/tools/detail/reachability.js +168 -0
- package/dist/tools/detail/reachability.js.map +1 -0
- package/dist/tools/discovery/capabilities.d.ts +28 -0
- package/dist/tools/discovery/capabilities.d.ts.map +1 -0
- package/dist/tools/discovery/capabilities.js +112 -0
- package/dist/tools/discovery/capabilities.js.map +1 -0
- package/dist/tools/discovery/index.d.ts +13 -0
- package/dist/tools/discovery/index.d.ts.map +1 -0
- package/dist/tools/discovery/index.js +30 -0
- package/dist/tools/discovery/index.js.map +1 -0
- package/dist/tools/discovery/projects.d.ts +26 -0
- package/dist/tools/discovery/projects.d.ts.map +1 -0
- package/dist/tools/discovery/projects.js +210 -0
- package/dist/tools/discovery/projects.js.map +1 -0
- package/dist/tools/discovery/status.d.ts +42 -0
- package/dist/tools/discovery/status.d.ts.map +1 -0
- package/dist/tools/discovery/status.js +157 -0
- package/dist/tools/discovery/status.js.map +1 -0
- package/dist/tools/exploration/contracts-list.d.ts +35 -0
- package/dist/tools/exploration/contracts-list.d.ts.map +1 -0
- package/dist/tools/exploration/contracts-list.js +106 -0
- package/dist/tools/exploration/contracts-list.js.map +1 -0
- package/dist/tools/exploration/files-list.d.ts +29 -0
- package/dist/tools/exploration/files-list.d.ts.map +1 -0
- package/dist/tools/exploration/files-list.js +94 -0
- package/dist/tools/exploration/files-list.js.map +1 -0
- package/dist/tools/exploration/index.d.ts +17 -0
- package/dist/tools/exploration/index.d.ts.map +1 -0
- package/dist/tools/exploration/index.js +126 -0
- package/dist/tools/exploration/index.js.map +1 -0
- package/dist/tools/exploration/patterns-list.d.ts +40 -0
- package/dist/tools/exploration/patterns-list.d.ts.map +1 -0
- package/dist/tools/exploration/patterns-list.js +172 -0
- package/dist/tools/exploration/patterns-list.js.map +1 -0
- package/dist/tools/exploration/security-summary.d.ts +49 -0
- package/dist/tools/exploration/security-summary.d.ts.map +1 -0
- package/dist/tools/exploration/security-summary.js +111 -0
- package/dist/tools/exploration/security-summary.js.map +1 -0
- package/dist/tools/exploration/trends.d.ts +49 -0
- package/dist/tools/exploration/trends.d.ts.map +1 -0
- package/dist/tools/exploration/trends.js +147 -0
- package/dist/tools/exploration/trends.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/orchestration/context.d.ts +72 -0
- package/dist/tools/orchestration/context.d.ts.map +1 -0
- package/dist/tools/orchestration/context.js +499 -0
- package/dist/tools/orchestration/context.js.map +1 -0
- package/dist/tools/orchestration/index.d.ts +11 -0
- package/dist/tools/orchestration/index.d.ts.map +1 -0
- package/dist/tools/orchestration/index.js +56 -0
- package/dist/tools/orchestration/index.js.map +1 -0
- package/dist/tools/registry.d.ts +41 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +64 -0
- package/dist/tools/registry.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_pattern_get - Full Pattern Details
|
|
3
|
+
*
|
|
4
|
+
* Detail tool that returns complete information for a specific pattern.
|
|
5
|
+
* Use pattern ID from drift_patterns_list.
|
|
6
|
+
*/
|
|
7
|
+
import { createResponseBuilder, Errors } from '../../infrastructure/index.js';
|
|
8
|
+
const DEFAULT_MAX_LOCATIONS = 20;
|
|
9
|
+
export async function handlePatternGet(store, args) {
|
|
10
|
+
const builder = createResponseBuilder();
|
|
11
|
+
if (!args.id) {
|
|
12
|
+
throw Errors.missingParameter('id');
|
|
13
|
+
}
|
|
14
|
+
await store.initialize();
|
|
15
|
+
const pattern = store.get(args.id);
|
|
16
|
+
if (!pattern) {
|
|
17
|
+
throw Errors.notFound('pattern', args.id);
|
|
18
|
+
}
|
|
19
|
+
const includeLocations = args.includeLocations !== false;
|
|
20
|
+
const includeOutliers = args.includeOutliers !== false;
|
|
21
|
+
const maxLocations = args.maxLocations ?? DEFAULT_MAX_LOCATIONS;
|
|
22
|
+
// Map locations
|
|
23
|
+
let locations = [];
|
|
24
|
+
if (includeLocations) {
|
|
25
|
+
locations = pattern.locations
|
|
26
|
+
.slice(0, maxLocations)
|
|
27
|
+
.map(loc => ({
|
|
28
|
+
file: loc.file,
|
|
29
|
+
line: loc.line,
|
|
30
|
+
column: loc.column,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
// Map outliers
|
|
34
|
+
let outliers = [];
|
|
35
|
+
if (includeOutliers) {
|
|
36
|
+
outliers = pattern.outliers.map(out => ({
|
|
37
|
+
file: out.file,
|
|
38
|
+
line: out.line,
|
|
39
|
+
reason: out.reason,
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
const data = {
|
|
43
|
+
id: pattern.id,
|
|
44
|
+
name: pattern.name,
|
|
45
|
+
description: pattern.description,
|
|
46
|
+
category: pattern.category,
|
|
47
|
+
subcategory: pattern.subcategory,
|
|
48
|
+
status: pattern.status,
|
|
49
|
+
confidence: {
|
|
50
|
+
score: Math.round(pattern.confidence.score * 100) / 100,
|
|
51
|
+
level: pattern.confidence.level,
|
|
52
|
+
},
|
|
53
|
+
locations,
|
|
54
|
+
outliers,
|
|
55
|
+
locationCount: pattern.locations.length,
|
|
56
|
+
outlierCount: pattern.outliers.length,
|
|
57
|
+
};
|
|
58
|
+
// Build summary
|
|
59
|
+
let summary = `${pattern.name} (${pattern.category}/${pattern.subcategory}). `;
|
|
60
|
+
summary += `Confidence: ${Math.round(pattern.confidence.score * 100)}% (${pattern.confidence.level}). `;
|
|
61
|
+
summary += `${pattern.locations.length} locations`;
|
|
62
|
+
if (pattern.outliers.length > 0) {
|
|
63
|
+
summary += `, ${pattern.outliers.length} outliers`;
|
|
64
|
+
}
|
|
65
|
+
summary += '.';
|
|
66
|
+
const hints = {
|
|
67
|
+
nextActions: [
|
|
68
|
+
'Use drift_code_examples to see implementations',
|
|
69
|
+
pattern.outliers.length > 0
|
|
70
|
+
? 'Review outliers to understand deviations'
|
|
71
|
+
: 'Use drift_patterns_list to explore more patterns',
|
|
72
|
+
],
|
|
73
|
+
relatedTools: ['drift_code_examples', 'drift_patterns_list'],
|
|
74
|
+
};
|
|
75
|
+
if (pattern.outliers.length > 5) {
|
|
76
|
+
hints.warnings = [`High outlier count (${pattern.outliers.length}) may indicate pattern drift`];
|
|
77
|
+
}
|
|
78
|
+
else if (pattern.confidence.score < 0.7) {
|
|
79
|
+
hints.warnings = ['Low confidence - pattern may need review'];
|
|
80
|
+
}
|
|
81
|
+
return builder
|
|
82
|
+
.withSummary(summary)
|
|
83
|
+
.withData(data)
|
|
84
|
+
.withHints(hints)
|
|
85
|
+
.buildContent();
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=pattern-get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern-get.js","sourceRoot":"","sources":["../../../src/tools/detail/pattern-get.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_reachability - Data Reachability Analysis
|
|
3
|
+
*
|
|
4
|
+
* Detail tool that answers "What data can this code access?" and
|
|
5
|
+
* "Who can access this data?" using call graph traversal.
|
|
6
|
+
*/
|
|
7
|
+
export interface ReachableData {
|
|
8
|
+
table: string;
|
|
9
|
+
fields: string[];
|
|
10
|
+
operation: string;
|
|
11
|
+
depth: number;
|
|
12
|
+
path: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface SensitiveField {
|
|
15
|
+
table: string;
|
|
16
|
+
field: string;
|
|
17
|
+
sensitivityType: string;
|
|
18
|
+
accessCount: number;
|
|
19
|
+
pathCount: number;
|
|
20
|
+
}
|
|
21
|
+
export interface ForwardReachabilityData {
|
|
22
|
+
direction: 'forward';
|
|
23
|
+
origin: string;
|
|
24
|
+
tables: string[];
|
|
25
|
+
sensitiveFields: SensitiveField[];
|
|
26
|
+
reachableData: ReachableData[];
|
|
27
|
+
functionsTraversed: number;
|
|
28
|
+
maxDepth: number;
|
|
29
|
+
}
|
|
30
|
+
export interface AccessPath {
|
|
31
|
+
entryPoint: string;
|
|
32
|
+
entryPointFile: string;
|
|
33
|
+
pathLength: number;
|
|
34
|
+
path: string[];
|
|
35
|
+
}
|
|
36
|
+
export interface InverseReachabilityData {
|
|
37
|
+
direction: 'inverse';
|
|
38
|
+
target: {
|
|
39
|
+
table: string;
|
|
40
|
+
field?: string;
|
|
41
|
+
};
|
|
42
|
+
totalAccessors: number;
|
|
43
|
+
entryPoints: string[];
|
|
44
|
+
accessPaths: AccessPath[];
|
|
45
|
+
}
|
|
46
|
+
export type ReachabilityData = ForwardReachabilityData | InverseReachabilityData;
|
|
47
|
+
export declare function handleReachability(projectRoot: string, args: {
|
|
48
|
+
direction?: 'forward' | 'inverse';
|
|
49
|
+
location?: string;
|
|
50
|
+
target?: string;
|
|
51
|
+
maxDepth?: number;
|
|
52
|
+
limit?: number;
|
|
53
|
+
sensitiveOnly?: boolean;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
content: Array<{
|
|
56
|
+
type: string;
|
|
57
|
+
text: string;
|
|
58
|
+
}>;
|
|
59
|
+
}>;
|
|
60
|
+
//# sourceMappingURL=reachability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reachability.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/reachability.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,aAAa,EAAE,aAAa,EAAE,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,GAAG,uBAAuB,CAAC;AAKjF,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IACJ,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA0B7D"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_reachability - Data Reachability Analysis
|
|
3
|
+
*
|
|
4
|
+
* Detail tool that answers "What data can this code access?" and
|
|
5
|
+
* "Who can access this data?" using call graph traversal.
|
|
6
|
+
*/
|
|
7
|
+
import { createCallGraphAnalyzer, } from 'driftdetect-core';
|
|
8
|
+
import { createResponseBuilder, Errors } from '../../infrastructure/index.js';
|
|
9
|
+
const DEFAULT_MAX_DEPTH = 10;
|
|
10
|
+
const DEFAULT_LIMIT = 15;
|
|
11
|
+
export async function handleReachability(projectRoot, args) {
|
|
12
|
+
const builder = createResponseBuilder();
|
|
13
|
+
const direction = args.direction ?? 'forward';
|
|
14
|
+
const maxDepth = args.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
15
|
+
const limit = args.limit ?? DEFAULT_LIMIT;
|
|
16
|
+
const sensitiveOnly = args.sensitiveOnly ?? false;
|
|
17
|
+
// Initialize call graph analyzer
|
|
18
|
+
const analyzer = createCallGraphAnalyzer({ rootDir: projectRoot });
|
|
19
|
+
await analyzer.initialize();
|
|
20
|
+
const graph = analyzer.getGraph();
|
|
21
|
+
if (!graph) {
|
|
22
|
+
throw Errors.custom('NO_CALL_GRAPH', 'No call graph found. Run drift_callgraph action="build" first.', ['drift_callgraph action="build"']);
|
|
23
|
+
}
|
|
24
|
+
if (direction === 'forward') {
|
|
25
|
+
return handleForwardReachability(analyzer, graph, args.location, sensitiveOnly, builder, maxDepth, limit);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return handleInverseReachability(analyzer, graph, args.target, builder, maxDepth, limit);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function handleForwardReachability(analyzer, graph, location, sensitiveOnly, builder, maxDepth, limit) {
|
|
32
|
+
if (!location) {
|
|
33
|
+
throw Errors.missingParameter('location');
|
|
34
|
+
}
|
|
35
|
+
let result;
|
|
36
|
+
// Parse location (file:line or function_name)
|
|
37
|
+
if (location.includes(':')) {
|
|
38
|
+
const [file, lineStr] = location.split(':');
|
|
39
|
+
const line = parseInt(lineStr ?? '0', 10);
|
|
40
|
+
if (!file || isNaN(line)) {
|
|
41
|
+
throw Errors.custom('INVALID_LOCATION', 'Location must be file:line or function_name');
|
|
42
|
+
}
|
|
43
|
+
result = analyzer.getReachableData(file, line, { maxDepth, sensitiveOnly });
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Find function by name
|
|
47
|
+
let funcId;
|
|
48
|
+
for (const [id, func] of graph.functions) {
|
|
49
|
+
if (func.name === location || func.qualifiedName === location) {
|
|
50
|
+
funcId = id;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (!funcId) {
|
|
55
|
+
throw Errors.notFound('function', location);
|
|
56
|
+
}
|
|
57
|
+
result = analyzer.getReachableDataFromFunction(funcId, { maxDepth, sensitiveOnly });
|
|
58
|
+
}
|
|
59
|
+
// Map reachable data
|
|
60
|
+
const reachableData = result.reachableAccess
|
|
61
|
+
.slice(0, limit)
|
|
62
|
+
.map(ra => ({
|
|
63
|
+
table: ra.access.table,
|
|
64
|
+
fields: ra.access.fields,
|
|
65
|
+
operation: ra.access.operation,
|
|
66
|
+
depth: ra.depth,
|
|
67
|
+
path: ra.path.map(p => p.functionName),
|
|
68
|
+
}));
|
|
69
|
+
// Map sensitive fields
|
|
70
|
+
const sensitiveFields = result.sensitiveFields.map(sf => ({
|
|
71
|
+
table: sf.field.table ?? 'unknown',
|
|
72
|
+
field: sf.field.field,
|
|
73
|
+
sensitivityType: sf.field.sensitivityType,
|
|
74
|
+
accessCount: sf.accessCount,
|
|
75
|
+
pathCount: sf.paths.length,
|
|
76
|
+
}));
|
|
77
|
+
const data = {
|
|
78
|
+
direction: 'forward',
|
|
79
|
+
origin: location,
|
|
80
|
+
tables: result.tables,
|
|
81
|
+
sensitiveFields,
|
|
82
|
+
reachableData,
|
|
83
|
+
functionsTraversed: result.functionsTraversed,
|
|
84
|
+
maxDepth: result.maxDepth,
|
|
85
|
+
};
|
|
86
|
+
// Build summary
|
|
87
|
+
let summary = `From ${location}: ${result.tables.length} tables reachable`;
|
|
88
|
+
if (sensitiveFields.length > 0) {
|
|
89
|
+
summary += `, ${sensitiveFields.length} sensitive fields`;
|
|
90
|
+
}
|
|
91
|
+
summary += `. Traversed ${result.functionsTraversed} functions (max depth ${result.maxDepth}).`;
|
|
92
|
+
const hints = {
|
|
93
|
+
nextActions: [
|
|
94
|
+
sensitiveFields.length > 0
|
|
95
|
+
? 'Review sensitive field access for security implications'
|
|
96
|
+
: 'Use drift_impact_analysis to see who calls this code',
|
|
97
|
+
],
|
|
98
|
+
relatedTools: ['drift_impact_analysis', 'drift_callgraph'],
|
|
99
|
+
};
|
|
100
|
+
if (sensitiveFields.length > 0) {
|
|
101
|
+
const credentialFields = sensitiveFields.filter(f => f.sensitivityType === 'credentials');
|
|
102
|
+
if (credentialFields.length > 0) {
|
|
103
|
+
hints.warnings = [`⚠️ ${credentialFields.length} credential field(s) accessible from this location`];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return builder
|
|
107
|
+
.withSummary(summary)
|
|
108
|
+
.withData(data)
|
|
109
|
+
.withHints(hints)
|
|
110
|
+
.buildContent();
|
|
111
|
+
}
|
|
112
|
+
async function handleInverseReachability(analyzer, graph, target, builder, maxDepth, limit) {
|
|
113
|
+
if (!target) {
|
|
114
|
+
throw Errors.missingParameter('target');
|
|
115
|
+
}
|
|
116
|
+
// Parse target (table or table.field)
|
|
117
|
+
const parts = target.split('.');
|
|
118
|
+
const table = parts[0] ?? '';
|
|
119
|
+
const field = parts.length > 1 ? parts.slice(1).join('.') : undefined;
|
|
120
|
+
const result = analyzer.getCodePathsToData(field ? { table, field, maxDepth } : { table, maxDepth });
|
|
121
|
+
// Map access paths
|
|
122
|
+
const accessPaths = result.accessPaths
|
|
123
|
+
.slice(0, limit)
|
|
124
|
+
.map(ap => {
|
|
125
|
+
const entryFunc = graph.functions.get(ap.entryPoint);
|
|
126
|
+
return {
|
|
127
|
+
entryPoint: entryFunc?.qualifiedName ?? ap.entryPoint,
|
|
128
|
+
entryPointFile: entryFunc?.file ?? '',
|
|
129
|
+
pathLength: ap.path.length,
|
|
130
|
+
path: ap.path.map(p => p.functionName),
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
// Get entry point names
|
|
134
|
+
const entryPointNames = result.entryPoints
|
|
135
|
+
.slice(0, limit)
|
|
136
|
+
.map(epId => {
|
|
137
|
+
const func = graph.functions.get(epId);
|
|
138
|
+
return func?.qualifiedName ?? epId;
|
|
139
|
+
});
|
|
140
|
+
const targetData = { table };
|
|
141
|
+
if (field) {
|
|
142
|
+
targetData.field = field;
|
|
143
|
+
}
|
|
144
|
+
const data = {
|
|
145
|
+
direction: 'inverse',
|
|
146
|
+
target: targetData,
|
|
147
|
+
totalAccessors: result.totalAccessors,
|
|
148
|
+
entryPoints: entryPointNames,
|
|
149
|
+
accessPaths,
|
|
150
|
+
};
|
|
151
|
+
// Build summary
|
|
152
|
+
let summary = `${target}: ${result.totalAccessors} direct accessor(s), `;
|
|
153
|
+
summary += `${result.entryPoints.length} entry point(s) can reach this data.`;
|
|
154
|
+
return builder
|
|
155
|
+
.withSummary(summary)
|
|
156
|
+
.withData(data)
|
|
157
|
+
.withHints({
|
|
158
|
+
nextActions: result.entryPoints.length > 0
|
|
159
|
+
? [
|
|
160
|
+
'Review entry points for proper authorization',
|
|
161
|
+
'Use drift_impact_analysis to understand change impact',
|
|
162
|
+
]
|
|
163
|
+
: ['No entry points can reach this data - may be dead code'],
|
|
164
|
+
relatedTools: ['drift_impact_analysis', 'drift_callgraph'],
|
|
165
|
+
})
|
|
166
|
+
.buildContent();
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=reachability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reachability.js","sourceRoot":"","sources":["../../../src/tools/detail/reachability.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_capabilities - Tool Guide
|
|
3
|
+
*
|
|
4
|
+
* Discovery tool that explains all available tools and when to use them.
|
|
5
|
+
* Helps AI agents understand the tool landscape.
|
|
6
|
+
*/
|
|
7
|
+
export interface CapabilitiesData {
|
|
8
|
+
layers: {
|
|
9
|
+
discovery: ToolInfo[];
|
|
10
|
+
exploration: ToolInfo[];
|
|
11
|
+
detail: ToolInfo[];
|
|
12
|
+
};
|
|
13
|
+
categories: string[];
|
|
14
|
+
quickStart: string[];
|
|
15
|
+
}
|
|
16
|
+
interface ToolInfo {
|
|
17
|
+
name: string;
|
|
18
|
+
purpose: string;
|
|
19
|
+
whenToUse: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function handleCapabilities(_args: Record<string, unknown>): Promise<{
|
|
22
|
+
content: Array<{
|
|
23
|
+
type: string;
|
|
24
|
+
text: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/tools/discovery/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE;QACN,SAAS,EAAE,QAAQ,EAAE,CAAC;QACtB,WAAW,EAAE,QAAQ,EAAE,CAAC;QACxB,MAAM,EAAE,QAAQ,EAAE,CAAC;KACpB,CAAC;IACF,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAsED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAuC7D"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_capabilities - Tool Guide
|
|
3
|
+
*
|
|
4
|
+
* Discovery tool that explains all available tools and when to use them.
|
|
5
|
+
* Helps AI agents understand the tool landscape.
|
|
6
|
+
*/
|
|
7
|
+
import { createResponseBuilder } from '../../infrastructure/index.js';
|
|
8
|
+
import { TOOL_CATEGORIES } from '../registry.js';
|
|
9
|
+
const TOOL_INFO = {
|
|
10
|
+
// Discovery
|
|
11
|
+
drift_status: {
|
|
12
|
+
name: 'drift_status',
|
|
13
|
+
purpose: 'Get codebase health snapshot',
|
|
14
|
+
whenToUse: 'First tool to call. Understand overall state before diving deeper.',
|
|
15
|
+
},
|
|
16
|
+
drift_capabilities: {
|
|
17
|
+
name: 'drift_capabilities',
|
|
18
|
+
purpose: 'List all tools and their purposes',
|
|
19
|
+
whenToUse: 'When unsure which tool to use for a task.',
|
|
20
|
+
},
|
|
21
|
+
// Exploration
|
|
22
|
+
drift_patterns_list: {
|
|
23
|
+
name: 'drift_patterns_list',
|
|
24
|
+
purpose: 'List patterns with summaries',
|
|
25
|
+
whenToUse: 'To find patterns by category, status, or confidence. Returns IDs for detail tools.',
|
|
26
|
+
},
|
|
27
|
+
drift_files_list: {
|
|
28
|
+
name: 'drift_files_list',
|
|
29
|
+
purpose: 'List files with pattern counts',
|
|
30
|
+
whenToUse: 'To find files relevant to a task or understand pattern distribution.',
|
|
31
|
+
},
|
|
32
|
+
drift_security_summary: {
|
|
33
|
+
name: 'drift_security_summary',
|
|
34
|
+
purpose: 'Security posture overview',
|
|
35
|
+
whenToUse: 'Before working on security-sensitive code or reviewing data access.',
|
|
36
|
+
},
|
|
37
|
+
drift_contracts_list: {
|
|
38
|
+
name: 'drift_contracts_list',
|
|
39
|
+
purpose: 'List API contracts and mismatches',
|
|
40
|
+
whenToUse: 'When working on API endpoints or debugging frontend/backend issues.',
|
|
41
|
+
},
|
|
42
|
+
drift_trends: {
|
|
43
|
+
name: 'drift_trends',
|
|
44
|
+
purpose: 'Pattern trend analysis',
|
|
45
|
+
whenToUse: 'To check if code quality is improving or declining over time.',
|
|
46
|
+
},
|
|
47
|
+
// Detail
|
|
48
|
+
drift_pattern_get: {
|
|
49
|
+
name: 'drift_pattern_get',
|
|
50
|
+
purpose: 'Full pattern details',
|
|
51
|
+
whenToUse: 'After finding a pattern ID from drift_patterns_list. Get complete info.',
|
|
52
|
+
},
|
|
53
|
+
drift_file_patterns: {
|
|
54
|
+
name: 'drift_file_patterns',
|
|
55
|
+
purpose: 'All patterns in a file',
|
|
56
|
+
whenToUse: 'Before modifying a file. Understand its patterns and conventions.',
|
|
57
|
+
},
|
|
58
|
+
drift_code_examples: {
|
|
59
|
+
name: 'drift_code_examples',
|
|
60
|
+
purpose: 'Real code snippets for patterns',
|
|
61
|
+
whenToUse: 'Before generating code. See how patterns are implemented in this codebase.',
|
|
62
|
+
},
|
|
63
|
+
drift_impact_analysis: {
|
|
64
|
+
name: 'drift_impact_analysis',
|
|
65
|
+
purpose: 'What breaks if you change X',
|
|
66
|
+
whenToUse: 'Before refactoring. Understand downstream effects of changes.',
|
|
67
|
+
},
|
|
68
|
+
drift_reachability: {
|
|
69
|
+
name: 'drift_reachability',
|
|
70
|
+
purpose: 'What data can code reach',
|
|
71
|
+
whenToUse: 'Security review. Understand data access from an entry point.',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
export async function handleCapabilities(_args) {
|
|
75
|
+
const builder = createResponseBuilder();
|
|
76
|
+
const data = {
|
|
77
|
+
layers: {
|
|
78
|
+
discovery: TOOL_CATEGORIES.discovery
|
|
79
|
+
.map(name => TOOL_INFO[name])
|
|
80
|
+
.filter((t) => t !== undefined),
|
|
81
|
+
exploration: TOOL_CATEGORIES.exploration
|
|
82
|
+
.map(name => TOOL_INFO[name])
|
|
83
|
+
.filter((t) => t !== undefined),
|
|
84
|
+
detail: TOOL_CATEGORIES.detail
|
|
85
|
+
.map(name => TOOL_INFO[name])
|
|
86
|
+
.filter((t) => t !== undefined),
|
|
87
|
+
},
|
|
88
|
+
categories: [
|
|
89
|
+
'api', 'auth', 'security', 'errors', 'logging',
|
|
90
|
+
'data-access', 'config', 'testing', 'performance',
|
|
91
|
+
'components', 'styling', 'structural', 'types',
|
|
92
|
+
'accessibility', 'documentation',
|
|
93
|
+
],
|
|
94
|
+
quickStart: [
|
|
95
|
+
'1. drift_status → Get health overview',
|
|
96
|
+
'2. drift_patterns_list → Find relevant patterns',
|
|
97
|
+
'3. drift_code_examples → See implementations',
|
|
98
|
+
'4. Generate code following the patterns',
|
|
99
|
+
],
|
|
100
|
+
};
|
|
101
|
+
return builder
|
|
102
|
+
.withSummary('Drift provides codebase intelligence through 3 tool layers: Discovery (status), Exploration (lists), and Detail (specifics).')
|
|
103
|
+
.withData(data)
|
|
104
|
+
.withHints({
|
|
105
|
+
nextActions: [
|
|
106
|
+
'Start with drift_status to see codebase health',
|
|
107
|
+
'Use drift_patterns_list to explore patterns by category',
|
|
108
|
+
],
|
|
109
|
+
})
|
|
110
|
+
.buildContent();
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/tools/discovery/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovery Tools
|
|
3
|
+
*
|
|
4
|
+
* Layer 1: Lightweight tools for understanding capabilities and status.
|
|
5
|
+
* These should always be fast and return minimal data.
|
|
6
|
+
*/
|
|
7
|
+
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
8
|
+
export declare const DISCOVERY_TOOLS: Tool[];
|
|
9
|
+
export { handleStatus } from './status.js';
|
|
10
|
+
export { handleCapabilities } from './capabilities.js';
|
|
11
|
+
export type { StatusData } from './status.js';
|
|
12
|
+
export type { CapabilitiesData } from './capabilities.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE/D,eAAO,MAAM,eAAe,EAAE,IAAI,EAmBjC,CAAC;AAGF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovery Tools
|
|
3
|
+
*
|
|
4
|
+
* Layer 1: Lightweight tools for understanding capabilities and status.
|
|
5
|
+
* These should always be fast and return minimal data.
|
|
6
|
+
*/
|
|
7
|
+
export const DISCOVERY_TOOLS = [
|
|
8
|
+
{
|
|
9
|
+
name: 'drift_status',
|
|
10
|
+
description: 'Get codebase health snapshot. Call this first to understand the current state. Returns pattern counts, health score, and critical issues. Always fast, always lightweight.',
|
|
11
|
+
inputSchema: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {},
|
|
14
|
+
required: [],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'drift_capabilities',
|
|
19
|
+
description: 'List all Drift capabilities and when to use each tool. Returns a guide to available tools organized by purpose. Use this when unsure which tool to use.',
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {},
|
|
23
|
+
required: [],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
// Handler exports
|
|
28
|
+
export { handleStatus } from './status.js';
|
|
29
|
+
export { handleCapabilities } from './capabilities.js';
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,MAAM,eAAe,GAAW;IACrC;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,4KAA4K;QACzL,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb;KACF;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,yJAAyJ;QACtK,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb;KACF;CACF,CAAC;AAEF,kBAAkB;AAClB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool: drift_projects
|
|
3
|
+
*
|
|
4
|
+
* List and manage registered drift projects.
|
|
5
|
+
* Enables AI agents to work across multiple codebases.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProjectsArgs {
|
|
8
|
+
/** Action to perform */
|
|
9
|
+
action?: 'list' | 'info' | 'switch' | 'recent';
|
|
10
|
+
/** Project name or ID (for info/switch) */
|
|
11
|
+
project?: string;
|
|
12
|
+
/** Filter by language */
|
|
13
|
+
language?: string;
|
|
14
|
+
/** Filter by framework */
|
|
15
|
+
framework?: string;
|
|
16
|
+
/** Limit results */
|
|
17
|
+
limit?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function handleProjects(args: ProjectsArgs): Promise<{
|
|
20
|
+
content: Array<{
|
|
21
|
+
type: string;
|
|
22
|
+
text: string;
|
|
23
|
+
}>;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/tools/discovery/projects.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC/C,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAiCD,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAkOhF"}
|