driftdetect-mcp 0.6.1 → 0.7.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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bin/server.js +0 -0
  3. package/dist/enterprise-server.d.ts +1 -0
  4. package/dist/enterprise-server.d.ts.map +1 -1
  5. package/dist/enterprise-server.js +8 -1
  6. package/dist/enterprise-server.js.map +1 -1
  7. package/dist/tools/analysis/constants.d.ts +99 -0
  8. package/dist/tools/analysis/constants.d.ts.map +1 -0
  9. package/dist/tools/analysis/constants.js +421 -0
  10. package/dist/tools/analysis/constants.js.map +1 -0
  11. package/dist/tools/analysis/index.d.ts +1 -0
  12. package/dist/tools/analysis/index.d.ts.map +1 -1
  13. package/dist/tools/analysis/index.js +70 -0
  14. package/dist/tools/analysis/index.js.map +1 -1
  15. package/dist/tools/exploration/env.d.ts +53 -0
  16. package/dist/tools/exploration/env.d.ts.map +1 -0
  17. package/dist/tools/exploration/env.js +283 -0
  18. package/dist/tools/exploration/env.js.map +1 -0
  19. package/dist/tools/exploration/index.d.ts +2 -0
  20. package/dist/tools/exploration/index.d.ts.map +1 -1
  21. package/dist/tools/exploration/index.js +32 -0
  22. package/dist/tools/exploration/index.js.map +1 -1
  23. package/dist/tools/index.d.ts +6 -1
  24. package/dist/tools/index.d.ts.map +1 -1
  25. package/dist/tools/index.js +6 -1
  26. package/dist/tools/index.js.map +1 -1
  27. package/dist/tools/registry.d.ts +7 -5
  28. package/dist/tools/registry.d.ts.map +1 -1
  29. package/dist/tools/registry.js +10 -4
  30. package/dist/tools/registry.js.map +1 -1
  31. package/dist/tools/surgical/callers.d.ts +85 -0
  32. package/dist/tools/surgical/callers.d.ts.map +1 -0
  33. package/dist/tools/surgical/callers.js +239 -0
  34. package/dist/tools/surgical/callers.js.map +1 -0
  35. package/dist/tools/surgical/dependencies.d.ts +96 -0
  36. package/dist/tools/surgical/dependencies.d.ts.map +1 -0
  37. package/dist/tools/surgical/dependencies.js +433 -0
  38. package/dist/tools/surgical/dependencies.js.map +1 -0
  39. package/dist/tools/surgical/errors.d.ts +88 -0
  40. package/dist/tools/surgical/errors.d.ts.map +1 -0
  41. package/dist/tools/surgical/errors.js +275 -0
  42. package/dist/tools/surgical/errors.js.map +1 -0
  43. package/dist/tools/surgical/hooks.d.ts +69 -0
  44. package/dist/tools/surgical/hooks.d.ts.map +1 -0
  45. package/dist/tools/surgical/hooks.js +247 -0
  46. package/dist/tools/surgical/hooks.js.map +1 -0
  47. package/dist/tools/surgical/imports.d.ts +61 -0
  48. package/dist/tools/surgical/imports.d.ts.map +1 -0
  49. package/dist/tools/surgical/imports.js +211 -0
  50. package/dist/tools/surgical/imports.js.map +1 -0
  51. package/dist/tools/surgical/index.d.ts +42 -0
  52. package/dist/tools/surgical/index.d.ts.map +1 -0
  53. package/dist/tools/surgical/index.js +66 -0
  54. package/dist/tools/surgical/index.js.map +1 -0
  55. package/dist/tools/surgical/middleware.d.ts +69 -0
  56. package/dist/tools/surgical/middleware.d.ts.map +1 -0
  57. package/dist/tools/surgical/middleware.js +237 -0
  58. package/dist/tools/surgical/middleware.js.map +1 -0
  59. package/dist/tools/surgical/prevalidate.d.ts +76 -0
  60. package/dist/tools/surgical/prevalidate.d.ts.map +1 -0
  61. package/dist/tools/surgical/prevalidate.js +303 -0
  62. package/dist/tools/surgical/prevalidate.js.map +1 -0
  63. package/dist/tools/surgical/recent.d.ts +66 -0
  64. package/dist/tools/surgical/recent.d.ts.map +1 -0
  65. package/dist/tools/surgical/recent.js +238 -0
  66. package/dist/tools/surgical/recent.js.map +1 -0
  67. package/dist/tools/surgical/signature.d.ts +73 -0
  68. package/dist/tools/surgical/signature.d.ts.map +1 -0
  69. package/dist/tools/surgical/signature.js +190 -0
  70. package/dist/tools/surgical/signature.js.map +1 -0
  71. package/dist/tools/surgical/similar.d.ts +77 -0
  72. package/dist/tools/surgical/similar.d.ts.map +1 -0
  73. package/dist/tools/surgical/similar.js +285 -0
  74. package/dist/tools/surgical/similar.js.map +1 -0
  75. package/dist/tools/surgical/test-template.d.ts +70 -0
  76. package/dist/tools/surgical/test-template.d.ts.map +1 -0
  77. package/dist/tools/surgical/test-template.js +298 -0
  78. package/dist/tools/surgical/test-template.js.map +1 -0
  79. package/dist/tools/surgical/type.d.ts +69 -0
  80. package/dist/tools/surgical/type.d.ts.map +1 -0
  81. package/dist/tools/surgical/type.js +289 -0
  82. package/dist/tools/surgical/type.js.map +1 -0
  83. package/package.json +11 -11
@@ -0,0 +1,275 @@
1
+ /**
2
+ * drift_errors - Error Types Lookup
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 300 target, 800 max
6
+ *
7
+ * Returns custom error classes and error handling patterns.
8
+ * Solves: AI needs to know existing error types when adding error handling.
9
+ */
10
+ import { createErrorHandlingAnalyzer } from 'driftdetect-core';
11
+ import { createResponseBuilder, Errors, metrics } from '../../infrastructure/index.js';
12
+ // ============================================================================
13
+ // Handler
14
+ // ============================================================================
15
+ export async function handleErrors(store, args, rootDir) {
16
+ const startTime = Date.now();
17
+ const builder = createResponseBuilder();
18
+ const action = args.action ?? 'types';
19
+ const severityFilter = args.severity ?? 'medium';
20
+ const limit = args.limit ?? 20;
21
+ // Initialize call graph
22
+ await store.initialize();
23
+ const graph = store.getGraph();
24
+ if (!graph) {
25
+ throw Errors.custom('CALLGRAPH_NOT_BUILT', 'Call graph has not been built. Run "drift callgraph build" first.', ['drift_status']);
26
+ }
27
+ // Create error handling analyzer
28
+ const analyzer = createErrorHandlingAnalyzer({ rootDir });
29
+ analyzer.setCallGraph(graph);
30
+ let data;
31
+ switch (action) {
32
+ case 'types':
33
+ data = await getErrorTypes(graph, limit);
34
+ break;
35
+ case 'gaps':
36
+ data = getErrorGaps(analyzer, severityFilter, limit);
37
+ break;
38
+ case 'boundaries':
39
+ data = getErrorBoundaries(analyzer, limit);
40
+ break;
41
+ default:
42
+ throw Errors.invalidArgument('action', `Unknown action: ${action}`, 'Use: types, gaps, or boundaries');
43
+ }
44
+ // Build summary based on action
45
+ let summary;
46
+ switch (action) {
47
+ case 'types':
48
+ summary = data.errorTypes?.length
49
+ ? `Found ${data.errorTypes.length} custom error types`
50
+ : 'No custom error types found';
51
+ break;
52
+ case 'gaps':
53
+ summary = data.gaps?.length
54
+ ? `Found ${data.gaps.length} error handling gaps (${data.stats.criticalGaps ?? 0} critical)`
55
+ : 'No error handling gaps found';
56
+ break;
57
+ case 'boundaries':
58
+ summary = data.boundaries?.length
59
+ ? `Found ${data.boundaries.length} error boundaries (avg coverage: ${data.stats.avgCoverage?.toFixed(0) ?? 0}%)`
60
+ : 'No error boundaries found';
61
+ break;
62
+ default:
63
+ summary = 'Error analysis complete';
64
+ }
65
+ // Record metrics
66
+ metrics.recordRequest('drift_errors', Date.now() - startTime, true, false);
67
+ return builder
68
+ .withSummary(summary)
69
+ .withData(data)
70
+ .withHints({
71
+ nextActions: getNextActions(action, data),
72
+ relatedTools: ['drift_error_handling', 'drift_signature', 'drift_imports'],
73
+ })
74
+ .buildContent();
75
+ }
76
+ // ============================================================================
77
+ // Action Handlers
78
+ // ============================================================================
79
+ async function getErrorTypes(graph, limit) {
80
+ const errorTypes = [];
81
+ // Find error classes from the call graph
82
+ // Look for classes that extend Error or have Error in name
83
+ for (const [, func] of graph.functions) {
84
+ // Check if this is a class constructor for an error
85
+ if (func.className && isErrorClass(func.className)) {
86
+ // Check if we already have this error type
87
+ if (!errorTypes.some(e => e.name === func.className)) {
88
+ errorTypes.push({
89
+ name: func.className,
90
+ file: func.file,
91
+ line: func.startLine,
92
+ extends: detectErrorBase(func),
93
+ properties: extractErrorProperties(func),
94
+ usages: countErrorUsages(graph, func.className),
95
+ });
96
+ }
97
+ }
98
+ // Also check for throw statements with custom errors
99
+ if (func.name === 'constructor' && func.className && isErrorClass(func.className)) {
100
+ if (!errorTypes.some(e => e.name === func.className)) {
101
+ errorTypes.push({
102
+ name: func.className,
103
+ file: func.file,
104
+ line: func.startLine,
105
+ extends: 'Error',
106
+ properties: extractErrorProperties(func),
107
+ usages: countErrorUsages(graph, func.className),
108
+ });
109
+ }
110
+ }
111
+ }
112
+ // Sort by usages
113
+ errorTypes.sort((a, b) => b.usages - a.usages);
114
+ return {
115
+ action: 'types',
116
+ errorTypes: errorTypes.slice(0, limit),
117
+ stats: {
118
+ totalTypes: errorTypes.length,
119
+ },
120
+ };
121
+ }
122
+ function getErrorGaps(analyzer, severity, limit) {
123
+ // Build topology first
124
+ try {
125
+ analyzer.build();
126
+ }
127
+ catch {
128
+ // Topology might already be built or graph issues
129
+ }
130
+ const gaps = analyzer.getGaps({
131
+ minSeverity: severity,
132
+ limit,
133
+ includeSuggestions: true,
134
+ });
135
+ const gapInfos = gaps.map((gap) => ({
136
+ function: gap.name,
137
+ file: gap.file,
138
+ line: gap.line,
139
+ gapType: gap.gapType,
140
+ severity: gap.severity,
141
+ suggestion: gap.suggestion,
142
+ }));
143
+ const criticalCount = gaps.filter((g) => g.severity === 'critical').length;
144
+ return {
145
+ action: 'gaps',
146
+ gaps: gapInfos,
147
+ stats: {
148
+ totalGaps: gaps.length,
149
+ criticalGaps: criticalCount,
150
+ },
151
+ };
152
+ }
153
+ function getErrorBoundaries(analyzer, limit) {
154
+ // Build topology first
155
+ try {
156
+ analyzer.build();
157
+ }
158
+ catch {
159
+ // Topology might already be built or graph issues
160
+ }
161
+ const boundaries = analyzer.getBoundaries({ includeFramework: true });
162
+ const boundaryInfos = boundaries.slice(0, limit).map((b) => ({
163
+ function: b.name,
164
+ file: b.file,
165
+ line: b.line,
166
+ handledTypes: b.handledTypes,
167
+ coverage: b.coverage,
168
+ isFramework: b.isFrameworkBoundary,
169
+ }));
170
+ const avgCoverage = boundaries.length > 0
171
+ ? boundaries.reduce((sum, b) => sum + b.coverage, 0) / boundaries.length
172
+ : 0;
173
+ return {
174
+ action: 'boundaries',
175
+ boundaries: boundaryInfos,
176
+ stats: {
177
+ totalBoundaries: boundaries.length,
178
+ avgCoverage,
179
+ },
180
+ };
181
+ }
182
+ // ============================================================================
183
+ // Helpers
184
+ // ============================================================================
185
+ function isErrorClass(name) {
186
+ const lower = name.toLowerCase();
187
+ return lower.includes('error') ||
188
+ lower.includes('exception') ||
189
+ lower.endsWith('err');
190
+ }
191
+ function detectErrorBase(func) {
192
+ // Try to detect what the error extends
193
+ if (func.extends)
194
+ return func.extends;
195
+ // Common patterns
196
+ const name = func.className?.toLowerCase() ?? '';
197
+ if (name.includes('http'))
198
+ return 'HttpError';
199
+ if (name.includes('validation'))
200
+ return 'ValidationError';
201
+ if (name.includes('auth'))
202
+ return 'AuthError';
203
+ if (name.includes('notfound'))
204
+ return 'NotFoundError';
205
+ return 'Error';
206
+ }
207
+ function extractErrorProperties(func) {
208
+ const props = [];
209
+ // Extract from parameters
210
+ if (func.parameters) {
211
+ for (const param of func.parameters) {
212
+ if (param !== 'message' && param !== 'options') {
213
+ props.push(param);
214
+ }
215
+ }
216
+ }
217
+ return props.slice(0, 5);
218
+ }
219
+ function countErrorUsages(graph, errorName) {
220
+ let count = 0;
221
+ for (const [, func] of graph.functions) {
222
+ // Check if function throws this error type
223
+ for (const call of func.calls ?? []) {
224
+ if (call.calleeName === errorName || call.calleeName?.includes(errorName)) {
225
+ count++;
226
+ }
227
+ }
228
+ }
229
+ return count;
230
+ }
231
+ function getNextActions(action, data) {
232
+ switch (action) {
233
+ case 'types':
234
+ return data.errorTypes?.length
235
+ ? ['Use existing error types instead of creating new ones', 'Check error hierarchy for consistency']
236
+ : ['Consider creating custom error types for better error handling'];
237
+ case 'gaps':
238
+ return data.gaps?.length
239
+ ? ['Address critical gaps first', 'Add try/catch blocks to unprotected functions']
240
+ : ['Error handling coverage looks good'];
241
+ case 'boundaries':
242
+ return data.boundaries?.length
243
+ ? ['Review boundary coverage', 'Ensure all entry points have error boundaries']
244
+ : ['Consider adding error boundaries at API entry points'];
245
+ default:
246
+ return [];
247
+ }
248
+ }
249
+ /**
250
+ * Tool definition for MCP registration
251
+ */
252
+ export const errorsToolDefinition = {
253
+ name: 'drift_errors',
254
+ description: 'Find custom error types, error handling gaps, and error boundaries. Use action="types" for error classes, action="gaps" for missing error handling, action="boundaries" for catch locations.',
255
+ inputSchema: {
256
+ type: 'object',
257
+ properties: {
258
+ action: {
259
+ type: 'string',
260
+ enum: ['types', 'gaps', 'boundaries'],
261
+ description: 'What to look up: types (error classes), gaps (missing handling), boundaries (catch locations). Default: types',
262
+ },
263
+ severity: {
264
+ type: 'string',
265
+ enum: ['critical', 'high', 'medium', 'low'],
266
+ description: 'Minimum severity for gaps (default: medium)',
267
+ },
268
+ limit: {
269
+ type: 'number',
270
+ description: 'Max results to return (default: 20)',
271
+ },
272
+ },
273
+ },
274
+ };
275
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/tools/surgical/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * drift_hooks - React/Vue Hooks Lookup
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 300 target, 800 max
6
+ *
7
+ * Returns custom hooks in the codebase.
8
+ * Solves: AI needs to know existing hooks before creating new ones.
9
+ */
10
+ export interface HooksArgs {
11
+ /** Filter by category: state, fetch, effect, form, auth, all */
12
+ category?: 'state' | 'fetch' | 'effect' | 'form' | 'auth' | 'all';
13
+ /** Search by name pattern */
14
+ search?: string;
15
+ /** Max results */
16
+ limit?: number;
17
+ }
18
+ export interface HookInfo {
19
+ name: string;
20
+ file: string;
21
+ line: number;
22
+ category: string;
23
+ usages: number;
24
+ dependencies: string[];
25
+ returnType?: string | undefined;
26
+ isAsync: boolean;
27
+ }
28
+ export interface HooksData {
29
+ hooks: HookInfo[];
30
+ byCategory: Record<string, number>;
31
+ stats: {
32
+ total: number;
33
+ customHooks: number;
34
+ mostUsed: string;
35
+ avgUsages: number;
36
+ };
37
+ }
38
+ export declare function handleHooks(args: HooksArgs, rootDir: string): Promise<{
39
+ content: Array<{
40
+ type: string;
41
+ text: string;
42
+ }>;
43
+ }>;
44
+ /**
45
+ * Tool definition for MCP registration
46
+ */
47
+ export declare const hooksToolDefinition: {
48
+ name: string;
49
+ description: string;
50
+ inputSchema: {
51
+ type: "object";
52
+ properties: {
53
+ category: {
54
+ type: string;
55
+ enum: string[];
56
+ description: string;
57
+ };
58
+ search: {
59
+ type: string;
60
+ description: string;
61
+ };
62
+ limit: {
63
+ type: string;
64
+ description: string;
65
+ };
66
+ };
67
+ };
68
+ };
69
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/tools/surgical/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,MAAM,WAAW,SAAS;IACxB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IAClE,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAMD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAiI7D;AAsHD;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * drift_hooks - React/Vue Hooks Lookup
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 300 target, 800 max
6
+ *
7
+ * Returns custom hooks in the codebase.
8
+ * Solves: AI needs to know existing hooks before creating new ones.
9
+ */
10
+ import { createWrapperScanner } from 'driftdetect-core/wrappers';
11
+ import { createResponseBuilder, metrics } from '../../infrastructure/index.js';
12
+ // ============================================================================
13
+ // Handler
14
+ // ============================================================================
15
+ export async function handleHooks(args, rootDir) {
16
+ const startTime = Date.now();
17
+ const builder = createResponseBuilder();
18
+ const categoryFilter = args.category ?? 'all';
19
+ const searchPattern = args.search?.toLowerCase();
20
+ const limit = args.limit ?? 20;
21
+ // Scan for wrappers
22
+ const scanner = createWrapperScanner({
23
+ rootDir,
24
+ includeTestFiles: false,
25
+ verbose: false,
26
+ });
27
+ const result = await scanner.scan({
28
+ minConfidence: 0.3,
29
+ minClusterSize: 1,
30
+ maxDepth: 5,
31
+ includeTestFiles: false,
32
+ });
33
+ // Find hooks from wrappers
34
+ const hooksList = [];
35
+ // Check clusters for hook-related categories
36
+ const hookClusters = result.analysis.clusters.filter(c => c.category === 'state-management' ||
37
+ c.category === 'data-fetching' ||
38
+ c.category === 'side-effects' ||
39
+ c.category === 'form-handling' ||
40
+ c.category === 'authentication');
41
+ for (const cluster of hookClusters) {
42
+ for (const wrapper of cluster.wrappers) {
43
+ if (isHook(wrapper)) {
44
+ const hookCategory = categorizeHook(wrapper, cluster.category);
45
+ if (categoryFilter !== 'all' && hookCategory !== categoryFilter) {
46
+ continue;
47
+ }
48
+ if (searchPattern && !wrapper.name.toLowerCase().includes(searchPattern)) {
49
+ continue;
50
+ }
51
+ hooksList.push({
52
+ name: wrapper.name,
53
+ file: wrapper.file,
54
+ line: wrapper.line,
55
+ category: hookCategory,
56
+ usages: wrapper.calledBy.length,
57
+ dependencies: extractHookDependencies(wrapper),
58
+ returnType: wrapper.returnType,
59
+ isAsync: wrapper.isAsync,
60
+ });
61
+ }
62
+ }
63
+ }
64
+ // Also scan all wrappers for hook patterns
65
+ for (const wrapper of result.analysis.wrappers) {
66
+ if (isHook(wrapper) && !hooksList.some(h => h.name === wrapper.name && h.file === wrapper.file)) {
67
+ const hookCategory = inferHookCategory(wrapper);
68
+ if (categoryFilter !== 'all' && hookCategory !== categoryFilter) {
69
+ continue;
70
+ }
71
+ if (searchPattern && !wrapper.name.toLowerCase().includes(searchPattern)) {
72
+ continue;
73
+ }
74
+ hooksList.push({
75
+ name: wrapper.name,
76
+ file: wrapper.file,
77
+ line: wrapper.line,
78
+ category: hookCategory,
79
+ usages: wrapper.calledBy.length,
80
+ dependencies: extractHookDependencies(wrapper),
81
+ returnType: wrapper.returnType,
82
+ isAsync: wrapper.isAsync,
83
+ });
84
+ }
85
+ }
86
+ // Sort by usages and limit
87
+ hooksList.sort((a, b) => b.usages - a.usages);
88
+ const limited = hooksList.slice(0, limit);
89
+ // Calculate stats
90
+ const byCategory = {};
91
+ for (const hook of hooksList) {
92
+ byCategory[hook.category] = (byCategory[hook.category] ?? 0) + 1;
93
+ }
94
+ const totalUsages = hooksList.reduce((sum, h) => sum + h.usages, 0);
95
+ const mostUsed = hooksList[0]?.name ?? 'N/A';
96
+ const data = {
97
+ hooks: limited,
98
+ byCategory,
99
+ stats: {
100
+ total: hooksList.length,
101
+ customHooks: hooksList.filter(h => h.name.startsWith('use')).length,
102
+ mostUsed,
103
+ avgUsages: hooksList.length > 0 ? Math.round(totalUsages / hooksList.length) : 0,
104
+ },
105
+ };
106
+ // Build summary
107
+ const summary = hooksList.length > 0
108
+ ? `Found ${hooksList.length} custom hooks. Most used: "${mostUsed}" (${hooksList[0]?.usages ?? 0} usages)`
109
+ : 'No custom hooks detected';
110
+ // Record metrics
111
+ metrics.recordRequest('drift_hooks', Date.now() - startTime, true, false);
112
+ return builder
113
+ .withSummary(summary)
114
+ .withData(data)
115
+ .withHints({
116
+ nextActions: hooksList.length > 0
117
+ ? ['Check existing hooks before creating new ones', 'Consider composing existing hooks']
118
+ : ['No custom hooks found - consider extracting reusable logic into hooks'],
119
+ relatedTools: ['drift_wrappers', 'drift_signature', 'drift_imports'],
120
+ })
121
+ .buildContent();
122
+ }
123
+ // ============================================================================
124
+ // Helpers
125
+ // ============================================================================
126
+ function isHook(wrapper) {
127
+ // React/Vue hook naming convention
128
+ if (wrapper.name.startsWith('use') && wrapper.name.length > 3) {
129
+ const charAfterUse = wrapper.name[3];
130
+ // Must be followed by uppercase letter (useEffect, useState, etc.)
131
+ if (charAfterUse && charAfterUse === charAfterUse.toUpperCase()) {
132
+ return true;
133
+ }
134
+ }
135
+ // Check if it uses React hooks
136
+ const primitives = wrapper.primitiveSignature.join(' ').toLowerCase();
137
+ if (primitives.includes('usestate') ||
138
+ primitives.includes('useeffect') ||
139
+ primitives.includes('usecontext') ||
140
+ primitives.includes('usememo') ||
141
+ primitives.includes('usecallback') ||
142
+ primitives.includes('useref') ||
143
+ primitives.includes('usereducer')) {
144
+ return true;
145
+ }
146
+ // Vue composables
147
+ if (primitives.includes('ref(') ||
148
+ primitives.includes('reactive(') ||
149
+ primitives.includes('computed(') ||
150
+ primitives.includes('watch(') ||
151
+ primitives.includes('onmounted')) {
152
+ return true;
153
+ }
154
+ return false;
155
+ }
156
+ function categorizeHook(wrapper, clusterCategory) {
157
+ // Map cluster category to hook category
158
+ switch (clusterCategory) {
159
+ case 'state-management':
160
+ return 'state';
161
+ case 'data-fetching':
162
+ return 'fetch';
163
+ case 'side-effects':
164
+ return 'effect';
165
+ case 'form-handling':
166
+ return 'form';
167
+ case 'authentication':
168
+ return 'auth';
169
+ default:
170
+ return inferHookCategory(wrapper);
171
+ }
172
+ }
173
+ function inferHookCategory(wrapper) {
174
+ const name = wrapper.name.toLowerCase();
175
+ const primitives = wrapper.primitiveSignature.join(' ').toLowerCase();
176
+ // State management
177
+ if (name.includes('state') || name.includes('store') || name.includes('reducer') ||
178
+ primitives.includes('usestate') || primitives.includes('usereducer') ||
179
+ primitives.includes('zustand') || primitives.includes('redux') || primitives.includes('recoil')) {
180
+ return 'state';
181
+ }
182
+ // Data fetching
183
+ if (name.includes('fetch') || name.includes('query') || name.includes('data') ||
184
+ name.includes('api') || name.includes('request') ||
185
+ primitives.includes('fetch') || primitives.includes('axios') ||
186
+ primitives.includes('swr') || primitives.includes('react-query') || primitives.includes('tanstack')) {
187
+ return 'fetch';
188
+ }
189
+ // Side effects
190
+ if (name.includes('effect') || name.includes('subscription') || name.includes('listener') ||
191
+ primitives.includes('useeffect') || primitives.includes('uselayouteffect')) {
192
+ return 'effect';
193
+ }
194
+ // Form handling
195
+ if (name.includes('form') || name.includes('input') || name.includes('field') ||
196
+ primitives.includes('useform') || primitives.includes('formik') || primitives.includes('react-hook-form')) {
197
+ return 'form';
198
+ }
199
+ // Auth
200
+ if (name.includes('auth') || name.includes('user') || name.includes('session') ||
201
+ name.includes('login') || name.includes('permission')) {
202
+ return 'auth';
203
+ }
204
+ return 'other';
205
+ }
206
+ function extractHookDependencies(wrapper) {
207
+ const deps = [];
208
+ // Extract React hooks from primitives
209
+ for (const prim of wrapper.primitiveSignature) {
210
+ if (prim.startsWith('use') || prim.includes('use')) {
211
+ deps.push(prim);
212
+ }
213
+ }
214
+ // Also check direct primitives
215
+ for (const prim of wrapper.directPrimitives) {
216
+ if (prim.startsWith('use') && !deps.includes(prim)) {
217
+ deps.push(prim);
218
+ }
219
+ }
220
+ return deps.slice(0, 5); // Limit to 5 dependencies
221
+ }
222
+ /**
223
+ * Tool definition for MCP registration
224
+ */
225
+ export const hooksToolDefinition = {
226
+ name: 'drift_hooks',
227
+ description: 'Find custom React/Vue hooks in the codebase. Returns hook names, categories, usage counts, and dependencies.',
228
+ inputSchema: {
229
+ type: 'object',
230
+ properties: {
231
+ category: {
232
+ type: 'string',
233
+ enum: ['state', 'fetch', 'effect', 'form', 'auth', 'all'],
234
+ description: 'Filter by hook category (default: all)',
235
+ },
236
+ search: {
237
+ type: 'string',
238
+ description: 'Search hooks by name pattern',
239
+ },
240
+ limit: {
241
+ type: 'number',
242
+ description: 'Max results to return (default: 20)',
243
+ },
244
+ },
245
+ },
246
+ };
247
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../src/tools/surgical/hooks.ts"],"names":[],"mappings":"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"}