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,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* drift_test_topology - Test Topology Analysis
|
|
3
|
+
*
|
|
4
|
+
* Analysis tool for test-to-code mappings, mock patterns, and test quality.
|
|
5
|
+
* Answers: "Which tests cover this code?" and "What's the minimum test set?"
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { createTestTopologyAnalyzer, createCallGraphAnalyzer, } from 'driftdetect-core';
|
|
10
|
+
import { createResponseBuilder, Errors } from '../../infrastructure/index.js';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Constants
|
|
13
|
+
// ============================================================================
|
|
14
|
+
const DRIFT_DIR = '.drift';
|
|
15
|
+
const TEST_TOPOLOGY_DIR = 'test-topology';
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Handler
|
|
18
|
+
// ============================================================================
|
|
19
|
+
export async function handleTestTopology(projectRoot, args) {
|
|
20
|
+
const { action } = args;
|
|
21
|
+
switch (action) {
|
|
22
|
+
case 'status':
|
|
23
|
+
return handleStatus(projectRoot);
|
|
24
|
+
case 'coverage':
|
|
25
|
+
return handleCoverage(projectRoot, args.file);
|
|
26
|
+
case 'uncovered':
|
|
27
|
+
return handleUncovered(projectRoot, args.limit, args.minRisk);
|
|
28
|
+
case 'mocks':
|
|
29
|
+
return handleMocks(projectRoot);
|
|
30
|
+
case 'affected':
|
|
31
|
+
return handleAffected(projectRoot, args.files ?? []);
|
|
32
|
+
case 'quality':
|
|
33
|
+
return handleQuality(projectRoot, args.file);
|
|
34
|
+
default:
|
|
35
|
+
throw Errors.invalidArgument('action', `Invalid action: ${action}. Valid actions: status, coverage, uncovered, mocks, affected, quality`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Action Handlers
|
|
40
|
+
// ============================================================================
|
|
41
|
+
async function handleStatus(projectRoot) {
|
|
42
|
+
const builder = createResponseBuilder();
|
|
43
|
+
// Try to load cached data first
|
|
44
|
+
const summaryPath = path.join(projectRoot, DRIFT_DIR, TEST_TOPOLOGY_DIR, 'summary.json');
|
|
45
|
+
try {
|
|
46
|
+
const data = JSON.parse(await fs.readFile(summaryPath, 'utf-8'));
|
|
47
|
+
const { summary, mockAnalysis } = data;
|
|
48
|
+
let summaryText = `🧪 ${summary.testCases} tests in ${summary.testFiles} files. `;
|
|
49
|
+
summaryText += `Coverage: ${summary.functionCoveragePercent}% functions. `;
|
|
50
|
+
summaryText += `Quality: ${summary.avgQualityScore}/100.`;
|
|
51
|
+
const hints = {
|
|
52
|
+
nextActions: [
|
|
53
|
+
summary.functionCoveragePercent < 50
|
|
54
|
+
? 'Run drift_test_topology action="uncovered" to find gaps'
|
|
55
|
+
: 'Good coverage - consider drift_test_topology action="mocks" for quality',
|
|
56
|
+
],
|
|
57
|
+
relatedTools: ['drift_test_topology action="uncovered"', 'drift_test_topology action="mocks"'],
|
|
58
|
+
};
|
|
59
|
+
return builder
|
|
60
|
+
.withSummary(summaryText)
|
|
61
|
+
.withData({ summary, mockAnalysis, generatedAt: data.generatedAt })
|
|
62
|
+
.withHints(hints)
|
|
63
|
+
.buildContent();
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
throw Errors.custom('NO_TEST_TOPOLOGY', 'No test topology found. Build it first using the CLI: drift test-topology build', ['drift test-topology build']);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function handleCoverage(projectRoot, file) {
|
|
70
|
+
const builder = createResponseBuilder();
|
|
71
|
+
if (!file) {
|
|
72
|
+
throw Errors.missingParameter('file');
|
|
73
|
+
}
|
|
74
|
+
// Build analyzer on-demand
|
|
75
|
+
const analyzer = await buildAnalyzer(projectRoot);
|
|
76
|
+
const coverage = analyzer.getCoverage(file);
|
|
77
|
+
if (!coverage) {
|
|
78
|
+
throw Errors.custom('NO_COVERAGE_DATA', `No coverage data for ${file}. Ensure call graph is built.`, ['drift callgraph build']);
|
|
79
|
+
}
|
|
80
|
+
const coveredCount = coverage.functions.filter((f) => f.isCovered).length;
|
|
81
|
+
let summaryText = `📊 ${file}: ${coverage.coveragePercent}% coverage. `;
|
|
82
|
+
summaryText += `${coveredCount}/${coverage.functions.length} functions tested.`;
|
|
83
|
+
const uncoveredFunctions = coverage.functions
|
|
84
|
+
.filter((f) => !f.isCovered)
|
|
85
|
+
.map((f) => f.name);
|
|
86
|
+
const hints = {
|
|
87
|
+
nextActions: uncoveredFunctions.length > 0
|
|
88
|
+
? [`Add tests for: ${uncoveredFunctions.slice(0, 3).join(', ')}`]
|
|
89
|
+
: ['Full coverage achieved!'],
|
|
90
|
+
relatedTools: ['drift_test_topology action="uncovered"'],
|
|
91
|
+
};
|
|
92
|
+
return builder
|
|
93
|
+
.withSummary(summaryText)
|
|
94
|
+
.withData({ file, coverage })
|
|
95
|
+
.withHints(hints)
|
|
96
|
+
.buildContent();
|
|
97
|
+
}
|
|
98
|
+
async function handleUncovered(projectRoot, limit, minRisk) {
|
|
99
|
+
const builder = createResponseBuilder();
|
|
100
|
+
const analyzer = await buildAnalyzer(projectRoot);
|
|
101
|
+
const uncovered = analyzer.getUncoveredFunctions({
|
|
102
|
+
limit: limit ?? 20,
|
|
103
|
+
minRisk: minRisk ?? 'medium',
|
|
104
|
+
includeReasons: true,
|
|
105
|
+
});
|
|
106
|
+
const highRisk = uncovered.filter((f) => f.riskScore >= 60);
|
|
107
|
+
const mediumRisk = uncovered.filter((f) => f.riskScore >= 30 && f.riskScore < 60);
|
|
108
|
+
let summaryText = `🔍 ${uncovered.length} uncovered functions. `;
|
|
109
|
+
if (highRisk.length > 0) {
|
|
110
|
+
summaryText += `🔴 ${highRisk.length} high risk. `;
|
|
111
|
+
}
|
|
112
|
+
if (mediumRisk.length > 0) {
|
|
113
|
+
summaryText += `🟡 ${mediumRisk.length} medium risk.`;
|
|
114
|
+
}
|
|
115
|
+
const hints = {
|
|
116
|
+
nextActions: highRisk.length > 0
|
|
117
|
+
? [`Priority: Add tests for ${highRisk[0]?.qualifiedName ?? 'high-risk functions'}`]
|
|
118
|
+
: ['Consider adding tests for medium-risk functions'],
|
|
119
|
+
warnings: highRisk.filter((f) => f.accessesSensitiveData).length > 0
|
|
120
|
+
? ['Some uncovered functions access sensitive data']
|
|
121
|
+
: undefined,
|
|
122
|
+
relatedTools: ['drift_impact_analysis', 'drift_reachability'],
|
|
123
|
+
};
|
|
124
|
+
return builder
|
|
125
|
+
.withSummary(summaryText)
|
|
126
|
+
.withData({ uncovered, total: uncovered.length })
|
|
127
|
+
.withHints(hints)
|
|
128
|
+
.buildContent();
|
|
129
|
+
}
|
|
130
|
+
async function handleMocks(projectRoot) {
|
|
131
|
+
const builder = createResponseBuilder();
|
|
132
|
+
// Load cached data
|
|
133
|
+
const summaryPath = path.join(projectRoot, DRIFT_DIR, TEST_TOPOLOGY_DIR, 'summary.json');
|
|
134
|
+
try {
|
|
135
|
+
const data = JSON.parse(await fs.readFile(summaryPath, 'utf-8'));
|
|
136
|
+
const { mockAnalysis } = data;
|
|
137
|
+
const warnings = [];
|
|
138
|
+
if (mockAnalysis.internalPercent > 50) {
|
|
139
|
+
warnings.push('High internal mocking (>50%) may indicate tight coupling');
|
|
140
|
+
}
|
|
141
|
+
if (mockAnalysis.avgMockRatio > 0.7) {
|
|
142
|
+
warnings.push('High average mock ratio - tests may be brittle');
|
|
143
|
+
}
|
|
144
|
+
if (mockAnalysis.highMockRatioTests.length > 5) {
|
|
145
|
+
warnings.push(`${mockAnalysis.highMockRatioTests.length} tests have >70% mock ratio`);
|
|
146
|
+
}
|
|
147
|
+
let summaryText = `🎭 ${mockAnalysis.totalMocks} mocks. `;
|
|
148
|
+
summaryText += `${mockAnalysis.externalPercent}% external, ${mockAnalysis.internalPercent}% internal. `;
|
|
149
|
+
summaryText += `Avg ratio: ${Math.round(mockAnalysis.avgMockRatio * 100)}%.`;
|
|
150
|
+
const hints = {
|
|
151
|
+
nextActions: warnings.length > 0
|
|
152
|
+
? ['Review high-mock tests for potential refactoring']
|
|
153
|
+
: ['Mock patterns look healthy'],
|
|
154
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
155
|
+
relatedTools: ['drift_test_topology action="quality"'],
|
|
156
|
+
};
|
|
157
|
+
return builder
|
|
158
|
+
.withSummary(summaryText)
|
|
159
|
+
.withData({ analysis: mockAnalysis, warnings })
|
|
160
|
+
.withHints(hints)
|
|
161
|
+
.buildContent();
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
throw Errors.custom('NO_TEST_TOPOLOGY', 'No test topology found. Build it first.', ['drift test-topology build']);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function handleAffected(projectRoot, files) {
|
|
168
|
+
const builder = createResponseBuilder();
|
|
169
|
+
if (files.length === 0) {
|
|
170
|
+
throw Errors.missingParameter('files');
|
|
171
|
+
}
|
|
172
|
+
const analyzer = await buildAnalyzer(projectRoot);
|
|
173
|
+
const result = analyzer.getMinimumTestSet(files);
|
|
174
|
+
let summaryText = `🎯 ${result.selectedTests}/${result.totalTests} tests needed. `;
|
|
175
|
+
summaryText += `Coverage: ${result.changedCodeCoverage}%. `;
|
|
176
|
+
summaryText += `Time saved: ~${result.timeSaved}.`;
|
|
177
|
+
const hints = {
|
|
178
|
+
nextActions: result.tests.length > 0
|
|
179
|
+
? [`Run: ${result.tests.slice(0, 3).map((t) => t.name).join(', ')}`]
|
|
180
|
+
: ['No tests found for changed files - consider adding coverage'],
|
|
181
|
+
relatedTools: ['drift_test_topology action="uncovered"'],
|
|
182
|
+
};
|
|
183
|
+
return builder
|
|
184
|
+
.withSummary(summaryText)
|
|
185
|
+
.withData({ changedFiles: files, result })
|
|
186
|
+
.withHints(hints)
|
|
187
|
+
.buildContent();
|
|
188
|
+
}
|
|
189
|
+
async function handleQuality(projectRoot, file) {
|
|
190
|
+
const builder = createResponseBuilder();
|
|
191
|
+
// Load cached data
|
|
192
|
+
const summaryPath = path.join(projectRoot, DRIFT_DIR, TEST_TOPOLOGY_DIR, 'summary.json');
|
|
193
|
+
try {
|
|
194
|
+
const data = JSON.parse(await fs.readFile(summaryPath, 'utf-8'));
|
|
195
|
+
const { summary } = data;
|
|
196
|
+
let summaryText = `📈 Test Quality: ${summary.avgQualityScore}/100. `;
|
|
197
|
+
summaryText += `Mock ratio: ${Math.round(summary.avgMockRatio * 100)}%.`;
|
|
198
|
+
const hints = {
|
|
199
|
+
nextActions: summary.avgQualityScore < 50
|
|
200
|
+
? ['Improve test quality by adding assertions and error cases']
|
|
201
|
+
: ['Test quality is good'],
|
|
202
|
+
relatedTools: ['drift_test_topology action="mocks"'],
|
|
203
|
+
};
|
|
204
|
+
return builder
|
|
205
|
+
.withSummary(summaryText)
|
|
206
|
+
.withData({ file, summary })
|
|
207
|
+
.withHints(hints)
|
|
208
|
+
.buildContent();
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
throw Errors.custom('NO_TEST_TOPOLOGY', 'No test topology found. Build it first.', ['drift test-topology build']);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// ============================================================================
|
|
215
|
+
// Helpers
|
|
216
|
+
// ============================================================================
|
|
217
|
+
async function buildAnalyzer(projectRoot) {
|
|
218
|
+
const analyzer = createTestTopologyAnalyzer({});
|
|
219
|
+
// Load call graph
|
|
220
|
+
try {
|
|
221
|
+
const callGraphAnalyzer = createCallGraphAnalyzer({ rootDir: projectRoot });
|
|
222
|
+
await callGraphAnalyzer.initialize();
|
|
223
|
+
const graph = callGraphAnalyzer.getGraph();
|
|
224
|
+
if (graph) {
|
|
225
|
+
analyzer.setCallGraph(graph);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Continue without call graph
|
|
230
|
+
}
|
|
231
|
+
// Extract tests by walking directory
|
|
232
|
+
const testFiles = await findTestFiles(projectRoot);
|
|
233
|
+
for (const testFile of testFiles) {
|
|
234
|
+
try {
|
|
235
|
+
const content = await fs.readFile(path.join(projectRoot, testFile), 'utf-8');
|
|
236
|
+
analyzer.extractFromFile(content, testFile);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Skip files that can't be read
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
analyzer.buildMappings();
|
|
243
|
+
return analyzer;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Find test files by walking the directory tree
|
|
247
|
+
*/
|
|
248
|
+
async function findTestFiles(rootDir, subDir = '') {
|
|
249
|
+
const testFiles = [];
|
|
250
|
+
const currentDir = path.join(rootDir, subDir);
|
|
251
|
+
try {
|
|
252
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
253
|
+
for (const entry of entries) {
|
|
254
|
+
const relativePath = path.join(subDir, entry.name);
|
|
255
|
+
// Skip common non-source directories
|
|
256
|
+
if (entry.isDirectory()) {
|
|
257
|
+
if (['node_modules', 'vendor', 'dist', 'build', '.git', '.drift'].includes(entry.name)) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
// Recurse into subdirectories
|
|
261
|
+
const subFiles = await findTestFiles(rootDir, relativePath);
|
|
262
|
+
testFiles.push(...subFiles);
|
|
263
|
+
}
|
|
264
|
+
else if (entry.isFile()) {
|
|
265
|
+
// Check if it's a test file
|
|
266
|
+
if (isTestFile(entry.name)) {
|
|
267
|
+
testFiles.push(relativePath);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// Directory not readable, skip
|
|
274
|
+
}
|
|
275
|
+
return testFiles;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Check if a filename matches test file patterns
|
|
279
|
+
*/
|
|
280
|
+
function isTestFile(filename) {
|
|
281
|
+
const testPatterns = [
|
|
282
|
+
/\.test\.[jt]sx?$/,
|
|
283
|
+
/\.spec\.[jt]sx?$/,
|
|
284
|
+
/_test\.py$/,
|
|
285
|
+
/test_.*\.py$/,
|
|
286
|
+
/Test\.java$/,
|
|
287
|
+
/Tests\.java$/,
|
|
288
|
+
/Test\.cs$/,
|
|
289
|
+
/Tests\.cs$/,
|
|
290
|
+
/Test\.php$/,
|
|
291
|
+
];
|
|
292
|
+
return testPatterns.some(pattern => pattern.test(filename));
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=test-topology.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-topology.js","sourceRoot":"","sources":["../../../src/tools/analysis/test-topology.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that returns actual code snippets demonstrating patterns.
|
|
5
5
|
* Essential before generating new code to match codebase conventions.
|
|
6
|
+
*
|
|
7
|
+
* MIGRATION: Now supports both legacy PatternStore and new IPatternService.
|
|
8
|
+
* The service-based approach is preferred for new code.
|
|
6
9
|
*/
|
|
7
|
-
import type { PatternStore } from 'driftdetect-core';
|
|
10
|
+
import type { PatternStore, IPatternService } from 'driftdetect-core';
|
|
8
11
|
export interface CodeExample {
|
|
9
12
|
patternId: string;
|
|
10
13
|
patternName: string;
|
|
@@ -19,12 +22,26 @@ export interface CodeExamplesData {
|
|
|
19
22
|
patternsFound: number;
|
|
20
23
|
examplesReturned: number;
|
|
21
24
|
}
|
|
22
|
-
export
|
|
25
|
+
export interface CodeExamplesArgs {
|
|
23
26
|
categories?: string[];
|
|
24
27
|
pattern?: string;
|
|
25
28
|
maxExamples?: number;
|
|
26
29
|
contextLines?: number;
|
|
27
|
-
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Handle code examples using IPatternService (preferred)
|
|
33
|
+
*/
|
|
34
|
+
export declare function handleCodeExamplesWithService(service: IPatternService, projectRoot: string, args: CodeExamplesArgs): Promise<{
|
|
35
|
+
content: Array<{
|
|
36
|
+
type: string;
|
|
37
|
+
text: string;
|
|
38
|
+
}>;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Handle code examples using legacy PatternStore (backward compatibility)
|
|
42
|
+
* @deprecated Use handleCodeExamplesWithService instead
|
|
43
|
+
*/
|
|
44
|
+
export declare function handleCodeExamples(store: PatternStore, projectRoot: string, args: CodeExamplesArgs): Promise<{
|
|
28
45
|
content: Array<{
|
|
29
46
|
type: string;
|
|
30
47
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-examples.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/code-examples.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"code-examples.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/code-examples.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAmB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAKvF,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAYD;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA4G7D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,YAAY,EACnB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA0G7D"}
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that returns actual code snippets demonstrating patterns.
|
|
5
5
|
* Essential before generating new code to match codebase conventions.
|
|
6
|
+
*
|
|
7
|
+
* MIGRATION: Now supports both legacy PatternStore and new IPatternService.
|
|
8
|
+
* The service-based approach is preferred for new code.
|
|
6
9
|
*/
|
|
7
10
|
import { createResponseBuilder, Errors } from '../../infrastructure/index.js';
|
|
8
11
|
import * as fs from 'fs/promises';
|
|
@@ -15,6 +18,107 @@ const VALID_CATEGORIES = [
|
|
|
15
18
|
];
|
|
16
19
|
const DEFAULT_MAX_EXAMPLES = 3;
|
|
17
20
|
const DEFAULT_CONTEXT_LINES = 10;
|
|
21
|
+
/**
|
|
22
|
+
* Handle code examples using IPatternService (preferred)
|
|
23
|
+
*/
|
|
24
|
+
export async function handleCodeExamplesWithService(service, projectRoot, args) {
|
|
25
|
+
const builder = createResponseBuilder();
|
|
26
|
+
// Validate categories
|
|
27
|
+
if (args.categories) {
|
|
28
|
+
for (const cat of args.categories) {
|
|
29
|
+
if (!VALID_CATEGORIES.includes(cat)) {
|
|
30
|
+
throw Errors.invalidCategory(cat, VALID_CATEGORIES);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const maxExamples = args.maxExamples ?? DEFAULT_MAX_EXAMPLES;
|
|
35
|
+
const contextLines = args.contextLines ?? DEFAULT_CONTEXT_LINES;
|
|
36
|
+
// Get patterns to show examples for
|
|
37
|
+
const result = await service.query({
|
|
38
|
+
filter: {
|
|
39
|
+
categories: args.categories,
|
|
40
|
+
search: args.pattern,
|
|
41
|
+
},
|
|
42
|
+
sort: {
|
|
43
|
+
field: 'confidence',
|
|
44
|
+
direction: 'desc',
|
|
45
|
+
},
|
|
46
|
+
pagination: {
|
|
47
|
+
offset: 0,
|
|
48
|
+
limit: 10, // Limit patterns to process
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
let patterns = result.patterns;
|
|
52
|
+
// If searching by specific pattern ID, also check exact match
|
|
53
|
+
if (args.pattern && !patterns.some(p => p.id === args.pattern)) {
|
|
54
|
+
const exactMatch = await service.getPattern(args.pattern);
|
|
55
|
+
if (exactMatch) {
|
|
56
|
+
patterns = [exactMatch, ...patterns];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const examples = [];
|
|
60
|
+
for (const pattern of patterns) {
|
|
61
|
+
// Get best locations (highest confidence, not outliers)
|
|
62
|
+
const outlierFiles = new Set(pattern.outliers.map(o => `${o.file}:${o.line}`));
|
|
63
|
+
const goodLocations = pattern.locations
|
|
64
|
+
.filter(loc => !outlierFiles.has(`${loc.file}:${loc.line}`))
|
|
65
|
+
.slice(0, maxExamples);
|
|
66
|
+
for (const loc of goodLocations) {
|
|
67
|
+
try {
|
|
68
|
+
const code = await extractCodeSnippet(path.join(projectRoot, loc.file), loc.line, contextLines);
|
|
69
|
+
if (code) {
|
|
70
|
+
examples.push({
|
|
71
|
+
patternId: pattern.id,
|
|
72
|
+
patternName: pattern.name,
|
|
73
|
+
category: pattern.category,
|
|
74
|
+
file: loc.file,
|
|
75
|
+
line: loc.line,
|
|
76
|
+
code,
|
|
77
|
+
explanation: pattern.description,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Skip files that can't be read
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// Limit total examples
|
|
86
|
+
if (examples.length >= maxExamples * 5)
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
if (examples.length >= maxExamples * 5)
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
const data = {
|
|
93
|
+
examples,
|
|
94
|
+
patternsFound: patterns.length,
|
|
95
|
+
examplesReturned: examples.length,
|
|
96
|
+
};
|
|
97
|
+
// Build summary
|
|
98
|
+
let summary = `${examples.length} code examples from ${patterns.length} patterns.`;
|
|
99
|
+
if (args.categories?.length) {
|
|
100
|
+
summary = `${args.categories.join(', ')}: ${summary}`;
|
|
101
|
+
}
|
|
102
|
+
return builder
|
|
103
|
+
.withSummary(summary)
|
|
104
|
+
.withData(data)
|
|
105
|
+
.withHints({
|
|
106
|
+
nextActions: examples.length > 0
|
|
107
|
+
? [
|
|
108
|
+
'Use these examples as templates for new code',
|
|
109
|
+
'Use drift_pattern_get for more details on specific patterns',
|
|
110
|
+
]
|
|
111
|
+
: [
|
|
112
|
+
'Try different categories or run drift scan',
|
|
113
|
+
],
|
|
114
|
+
relatedTools: ['drift_pattern_get', 'drift_patterns_list'],
|
|
115
|
+
})
|
|
116
|
+
.buildContent();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Handle code examples using legacy PatternStore (backward compatibility)
|
|
120
|
+
* @deprecated Use handleCodeExamplesWithService instead
|
|
121
|
+
*/
|
|
18
122
|
export async function handleCodeExamples(store, projectRoot, args) {
|
|
19
123
|
const builder = createResponseBuilder();
|
|
20
124
|
// Validate categories
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-examples.js","sourceRoot":"","sources":["../../../src/tools/detail/code-examples.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"code-examples.js","sourceRoot":"","sources":["../../../src/tools/detail/code-examples.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that returns all patterns found in a specific file.
|
|
5
5
|
* Shows pattern details, locations within the file, and outliers.
|
|
6
|
+
*
|
|
7
|
+
* Uses IndexStore (by-file.json) for file-to-pattern mapping.
|
|
6
8
|
*/
|
|
7
|
-
import type { ManifestStore } from 'driftdetect-core';
|
|
8
9
|
export interface FilePatternLocation {
|
|
9
10
|
line: number;
|
|
10
11
|
column?: number;
|
|
@@ -27,7 +28,7 @@ export interface FilePatternData {
|
|
|
27
28
|
outlierCount: number;
|
|
28
29
|
categories: string[];
|
|
29
30
|
}
|
|
30
|
-
export declare function handleFilePatterns(
|
|
31
|
+
export declare function handleFilePatterns(projectRoot: string, args: {
|
|
31
32
|
file: string;
|
|
32
33
|
category?: string;
|
|
33
34
|
}): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-patterns.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"file-patterns.d.ts","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAsH7D"}
|
|
@@ -3,28 +3,36 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that returns all patterns found in a specific file.
|
|
5
5
|
* Shows pattern details, locations within the file, and outliers.
|
|
6
|
+
*
|
|
7
|
+
* Uses IndexStore (by-file.json) for file-to-pattern mapping.
|
|
6
8
|
*/
|
|
9
|
+
import { IndexStore, PatternStore } from 'driftdetect-core';
|
|
7
10
|
import { createResponseBuilder, Errors } from '../../infrastructure/index.js';
|
|
8
|
-
export async function handleFilePatterns(
|
|
11
|
+
export async function handleFilePatterns(projectRoot, args) {
|
|
9
12
|
const builder = createResponseBuilder();
|
|
10
13
|
if (!args.file) {
|
|
11
14
|
throw Errors.missingParameter('file');
|
|
12
15
|
}
|
|
13
|
-
|
|
14
|
-
const
|
|
16
|
+
// Use IndexStore for file-to-pattern mapping
|
|
17
|
+
const indexStore = new IndexStore({ rootDir: projectRoot });
|
|
18
|
+
await indexStore.initialize();
|
|
19
|
+
const fileIndex = await indexStore.getFileIndex();
|
|
15
20
|
// Normalize file path
|
|
16
21
|
const filePath = args.file.replace(/^\.\//, '');
|
|
17
|
-
// Check if file exists in
|
|
18
|
-
const
|
|
19
|
-
if (!
|
|
22
|
+
// Check if file exists in index
|
|
23
|
+
const patternIds = fileIndex?.patterns[filePath];
|
|
24
|
+
if (!patternIds || patternIds.length === 0) {
|
|
20
25
|
throw Errors.notFound('file', filePath);
|
|
21
26
|
}
|
|
27
|
+
// Load pattern store to get full pattern details
|
|
28
|
+
const patternStore = new PatternStore({ rootDir: projectRoot });
|
|
29
|
+
await patternStore.initialize();
|
|
22
30
|
// Get patterns for this file
|
|
23
31
|
const patterns = [];
|
|
24
32
|
const categories = new Set();
|
|
25
33
|
let outlierCount = 0;
|
|
26
|
-
for (const patternId of
|
|
27
|
-
const pattern =
|
|
34
|
+
for (const patternId of patternIds) {
|
|
35
|
+
const pattern = patternStore.get(patternId);
|
|
28
36
|
if (!pattern)
|
|
29
37
|
continue;
|
|
30
38
|
// Filter by category if specified
|
|
@@ -37,10 +45,10 @@ export async function handleFilePatterns(store, args) {
|
|
|
37
45
|
.filter(loc => loc.file === filePath)
|
|
38
46
|
.map(loc => {
|
|
39
47
|
const result = {
|
|
40
|
-
line: loc.
|
|
48
|
+
line: loc.line,
|
|
41
49
|
};
|
|
42
|
-
if (loc.
|
|
43
|
-
result.
|
|
50
|
+
if (loc.column) {
|
|
51
|
+
result.column = loc.column;
|
|
44
52
|
}
|
|
45
53
|
return result;
|
|
46
54
|
});
|
|
@@ -54,7 +62,7 @@ export async function handleFilePatterns(store, args) {
|
|
|
54
62
|
name: pattern.name,
|
|
55
63
|
category: pattern.category,
|
|
56
64
|
subcategory: pattern.subcategory ?? '',
|
|
57
|
-
confidence: Math.round(pattern.confidence * 100) / 100,
|
|
65
|
+
confidence: Math.round(pattern.confidence.score * 100) / 100,
|
|
58
66
|
locations: fileLocations,
|
|
59
67
|
isOutlier: !!outlier,
|
|
60
68
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-patterns.js","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"file-patterns.js","sourceRoot":"","sources":["../../../src/tools/detail/file-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Detail tool that lists files matching a glob pattern with their pattern counts.
|
|
5
5
|
* Supports pagination for large codebases.
|
|
6
|
+
*
|
|
7
|
+
* Uses IndexStore (by-file.json) for file-to-pattern mapping.
|
|
6
8
|
*/
|
|
7
|
-
import type { ManifestStore } from 'driftdetect-core';
|
|
8
9
|
export interface FileEntry {
|
|
9
10
|
file: string;
|
|
10
11
|
patternCount: number;
|
|
11
12
|
categories: string[];
|
|
12
|
-
lastScanned?: string;
|
|
13
13
|
}
|
|
14
14
|
export interface FilesListData {
|
|
15
15
|
files: FileEntry[];
|
|
16
16
|
totalFiles: number;
|
|
17
17
|
totalPatterns: number;
|
|
18
18
|
}
|
|
19
|
-
export declare function handleFilesList(
|
|
19
|
+
export declare function handleFilesList(projectRoot: string, args: {
|
|
20
20
|
path?: string;
|
|
21
21
|
category?: string;
|
|
22
22
|
limit?: number;
|