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,66 @@
1
+ /**
2
+ * drift_recent - Show Recent Changes
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 400 target, 800 max
6
+ * Cache TTL: 1 minute (changes frequently)
7
+ * Invalidation Keys: git, decisions
8
+ *
9
+ * Shows what changed recently in a specific area.
10
+ * Solves: AI writes code using OLD patterns because it read an old file.
11
+ */
12
+ export interface RecentArgs {
13
+ /** Directory or file to check */
14
+ area: string;
15
+ /** How far back to look (default: 7) */
16
+ days?: number;
17
+ /** Filter by change type */
18
+ type?: 'feat' | 'fix' | 'refactor' | 'all';
19
+ }
20
+ export interface RecentChange {
21
+ file: string;
22
+ type: 'added' | 'modified' | 'deleted';
23
+ commitType: string;
24
+ summary: string;
25
+ date: string;
26
+ author: string;
27
+ }
28
+ export interface RecentData {
29
+ changes: RecentChange[];
30
+ patternsChanged: string[];
31
+ newConventions: string[];
32
+ preferFiles: string[];
33
+ }
34
+ export declare function handleRecent(args: RecentArgs, projectRoot: string): Promise<{
35
+ content: Array<{
36
+ type: string;
37
+ text: string;
38
+ }>;
39
+ }>;
40
+ /**
41
+ * Tool definition for MCP registration
42
+ */
43
+ export declare const recentToolDefinition: {
44
+ name: string;
45
+ description: string;
46
+ inputSchema: {
47
+ type: "object";
48
+ properties: {
49
+ area: {
50
+ type: string;
51
+ description: string;
52
+ };
53
+ days: {
54
+ type: string;
55
+ description: string;
56
+ };
57
+ type: {
58
+ type: string;
59
+ enum: string[];
60
+ description: string;
61
+ };
62
+ };
63
+ required: string[];
64
+ };
65
+ };
66
+ //# sourceMappingURL=recent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recent.d.ts","sourceRoot":"","sources":["../../../src/tools/surgical/recent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,KAAK,CAAC;CAC5C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAMD,wBAAsB,YAAY,CAChC,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAqJ7D;AAkFD;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;CAsBhC,CAAC"}
@@ -0,0 +1,238 @@
1
+ /**
2
+ * drift_recent - Show Recent Changes
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 400 target, 800 max
6
+ * Cache TTL: 1 minute (changes frequently)
7
+ * Invalidation Keys: git, decisions
8
+ *
9
+ * Shows what changed recently in a specific area.
10
+ * Solves: AI writes code using OLD patterns because it read an old file.
11
+ */
12
+ import { createResponseBuilder, Errors, metrics } from '../../infrastructure/index.js';
13
+ import { exec } from 'node:child_process';
14
+ import { promisify } from 'node:util';
15
+ const execAsync = promisify(exec);
16
+ // ============================================================================
17
+ // Handler
18
+ // ============================================================================
19
+ export async function handleRecent(args, projectRoot) {
20
+ const startTime = Date.now();
21
+ const builder = createResponseBuilder();
22
+ // Validate input
23
+ if (!args.area || args.area.trim() === '') {
24
+ throw Errors.missingParameter('area');
25
+ }
26
+ const area = args.area.trim();
27
+ const days = Math.min(args.days ?? 7, 30);
28
+ const typeFilter = args.type ?? 'all';
29
+ // Get git log for the area
30
+ const since = `${days}.days.ago`;
31
+ try {
32
+ // Get commits affecting the area
33
+ const { stdout: logOutput } = await execAsync(`git log --since="${since}" --pretty=format:"%H|%s|%an|%ai" --name-status -- "${area}"`, { cwd: projectRoot, maxBuffer: 1024 * 1024 });
34
+ if (!logOutput.trim()) {
35
+ const data = {
36
+ changes: [],
37
+ patternsChanged: [],
38
+ newConventions: [],
39
+ preferFiles: [],
40
+ };
41
+ return builder
42
+ .withSummary(`No changes in "${area}" in the last ${days} days`)
43
+ .withData(data)
44
+ .withHints({
45
+ nextActions: ['Area is stable - existing code is current', 'Use drift_similar to find examples'],
46
+ relatedTools: ['drift_similar', 'drift_code_examples'],
47
+ })
48
+ .buildContent();
49
+ }
50
+ // Parse git log output
51
+ const changes = [];
52
+ const lines = logOutput.split('\n');
53
+ let currentCommit = null;
54
+ for (const line of lines) {
55
+ if (line.includes('|')) {
56
+ // Commit line
57
+ const [hash, message, author, date] = line.split('|');
58
+ currentCommit = {
59
+ hash: hash ?? '',
60
+ message: message ?? '',
61
+ author: author ?? '',
62
+ date: date?.split(' ')[0] ?? '',
63
+ };
64
+ }
65
+ else if (line.trim() && currentCommit) {
66
+ // File change line (A/M/D followed by filename)
67
+ const match = line.match(/^([AMD])\t(.+)$/);
68
+ if (match) {
69
+ const [, status, file] = match;
70
+ // Parse conventional commit type
71
+ const commitType = parseCommitType(currentCommit.message);
72
+ // Apply type filter
73
+ if (typeFilter !== 'all' && commitType !== typeFilter) {
74
+ continue;
75
+ }
76
+ changes.push({
77
+ file: file ?? '',
78
+ type: status === 'A' ? 'added' : status === 'D' ? 'deleted' : 'modified',
79
+ commitType,
80
+ summary: currentCommit.message.slice(0, 80),
81
+ date: currentCommit.date,
82
+ author: currentCommit.author,
83
+ });
84
+ }
85
+ }
86
+ }
87
+ // Deduplicate by file (keep most recent)
88
+ const byFile = new Map();
89
+ for (const change of changes) {
90
+ if (!byFile.has(change.file)) {
91
+ byFile.set(change.file, change);
92
+ }
93
+ }
94
+ const uniqueChanges = Array.from(byFile.values()).slice(0, 15);
95
+ // Analyze patterns changed
96
+ const patternsChanged = analyzePatternChanges(uniqueChanges);
97
+ // Detect new conventions
98
+ const newConventions = detectNewConventions(uniqueChanges);
99
+ // Files to prefer (recently modified = more current)
100
+ const preferFiles = uniqueChanges
101
+ .filter(c => c.type === 'modified' && c.commitType !== 'fix')
102
+ .map(c => c.file)
103
+ .slice(0, 5);
104
+ const data = {
105
+ changes: uniqueChanges,
106
+ patternsChanged,
107
+ newConventions,
108
+ preferFiles,
109
+ };
110
+ // Build summary
111
+ const summary = `${uniqueChanges.length} change${uniqueChanges.length !== 1 ? 's' : ''} in "${area}" over last ${days} days. ${preferFiles.length} files recommended as current examples.`;
112
+ // Build hints
113
+ const hints = {
114
+ nextActions: preferFiles.length > 0
115
+ ? [
116
+ `Use "${preferFiles[0]}" as a reference - it's recently updated`,
117
+ 'Check patternsChanged for any migration notes',
118
+ ]
119
+ : [
120
+ 'No recent modifications - existing patterns are stable',
121
+ 'Use drift_similar to find examples',
122
+ ],
123
+ relatedTools: ['drift_similar', 'drift_signature', 'drift_code_examples'],
124
+ };
125
+ if (patternsChanged.length > 0) {
126
+ hints.warnings = [`Patterns changed recently: ${patternsChanged.join(', ')}`];
127
+ }
128
+ // Record metrics
129
+ metrics.recordRequest('drift_recent', Date.now() - startTime, true, false);
130
+ return builder
131
+ .withSummary(summary)
132
+ .withData(data)
133
+ .withHints(hints)
134
+ .buildContent();
135
+ }
136
+ catch (error) {
137
+ // Git command failed - might not be a git repo
138
+ throw Errors.custom('GIT_ERROR', 'Failed to read git history. Ensure this is a git repository.', ['drift_status']);
139
+ }
140
+ }
141
+ // ============================================================================
142
+ // Helpers
143
+ // ============================================================================
144
+ /**
145
+ * Parse conventional commit type from message
146
+ */
147
+ function parseCommitType(message) {
148
+ const match = message.match(/^(feat|fix|refactor|chore|docs|test|style|perf|ci|build)(\(.+\))?:/i);
149
+ if (match) {
150
+ return match[1].toLowerCase();
151
+ }
152
+ // Fallback heuristics
153
+ const lower = message.toLowerCase();
154
+ if (lower.includes('fix') || lower.includes('bug'))
155
+ return 'fix';
156
+ if (lower.includes('add') || lower.includes('new') || lower.includes('implement'))
157
+ return 'feat';
158
+ if (lower.includes('refactor') || lower.includes('clean') || lower.includes('improve'))
159
+ return 'refactor';
160
+ return 'other';
161
+ }
162
+ /**
163
+ * Analyze which patterns might have changed
164
+ */
165
+ function analyzePatternChanges(changes) {
166
+ const patterns = [];
167
+ for (const change of changes) {
168
+ const msg = change.summary.toLowerCase();
169
+ // Look for pattern-related keywords
170
+ if (msg.includes('error') || msg.includes('exception')) {
171
+ patterns.push('error-handling');
172
+ }
173
+ if (msg.includes('auth') || msg.includes('permission')) {
174
+ patterns.push('auth');
175
+ }
176
+ if (msg.includes('api') || msg.includes('endpoint')) {
177
+ patterns.push('api');
178
+ }
179
+ if (msg.includes('test')) {
180
+ patterns.push('testing');
181
+ }
182
+ if (msg.includes('style') || msg.includes('css') || msg.includes('theme')) {
183
+ patterns.push('styling');
184
+ }
185
+ if (msg.includes('migrat') || msg.includes('deprecat')) {
186
+ patterns.push('migration');
187
+ }
188
+ }
189
+ // Deduplicate
190
+ return [...new Set(patterns)];
191
+ }
192
+ /**
193
+ * Detect new conventions from commit messages
194
+ */
195
+ function detectNewConventions(changes) {
196
+ const conventions = [];
197
+ for (const change of changes) {
198
+ const msg = change.summary.toLowerCase();
199
+ // Look for convention-related keywords
200
+ if (msg.includes('migrat') && msg.includes('to')) {
201
+ conventions.push(change.summary);
202
+ }
203
+ if (msg.includes('switch') || msg.includes('replace')) {
204
+ conventions.push(change.summary);
205
+ }
206
+ if (msg.includes('new pattern') || msg.includes('introduce')) {
207
+ conventions.push(change.summary);
208
+ }
209
+ }
210
+ return conventions.slice(0, 3);
211
+ }
212
+ /**
213
+ * Tool definition for MCP registration
214
+ */
215
+ export const recentToolDefinition = {
216
+ name: 'drift_recent',
217
+ description: 'Show what changed recently in a specific area. Returns recent commits, pattern changes, and files to prefer as current examples. Use to avoid writing code based on outdated patterns.',
218
+ inputSchema: {
219
+ type: 'object',
220
+ properties: {
221
+ area: {
222
+ type: 'string',
223
+ description: 'Directory or file to check (e.g., "src/api/", "src/services/user.ts")',
224
+ },
225
+ days: {
226
+ type: 'number',
227
+ description: 'How far back to look (default: 7, max: 30)',
228
+ },
229
+ type: {
230
+ type: 'string',
231
+ enum: ['feat', 'fix', 'refactor', 'all'],
232
+ description: 'Filter by commit type (default: all)',
233
+ },
234
+ },
235
+ required: ['area'],
236
+ },
237
+ };
238
+ //# sourceMappingURL=recent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recent.js","sourceRoot":"","sources":["../../../src/tools/surgical/recent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * drift_signature - Get Function/Class Signatures
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 200 target, 500 max
6
+ * Cache TTL: 5 minutes
7
+ * Invalidation Keys: callgraph, file:{path}
8
+ *
9
+ * Returns just the signature without reading entire files.
10
+ * Solves: AI reads 500-line files just to see a 1-line signature.
11
+ */
12
+ import type { CallGraphStore } from 'driftdetect-core';
13
+ export interface SignatureArgs {
14
+ /** Symbol to look up (function, method, class name) */
15
+ symbol: string;
16
+ /** Optional: specific file to search in */
17
+ file?: string;
18
+ /** Include JSDoc/docstring? (default: true) */
19
+ includeDocs?: boolean;
20
+ }
21
+ export interface SignatureInfo {
22
+ file: string;
23
+ line: number;
24
+ kind: 'function' | 'method' | 'class' | 'interface' | 'type';
25
+ signature: string;
26
+ parameters?: Array<{
27
+ name: string;
28
+ type: string;
29
+ required: boolean;
30
+ default?: string | undefined;
31
+ }>;
32
+ returnType?: string | undefined;
33
+ docs?: string | undefined;
34
+ exported: boolean;
35
+ className?: string | undefined;
36
+ decorators?: string[] | undefined;
37
+ }
38
+ export interface SignatureData {
39
+ found: boolean;
40
+ signatures: SignatureInfo[];
41
+ }
42
+ export declare function handleSignature(store: CallGraphStore, args: SignatureArgs): Promise<{
43
+ content: Array<{
44
+ type: string;
45
+ text: string;
46
+ }>;
47
+ }>;
48
+ /**
49
+ * Tool definition for MCP registration
50
+ */
51
+ export declare const signatureToolDefinition: {
52
+ name: string;
53
+ description: string;
54
+ inputSchema: {
55
+ type: "object";
56
+ properties: {
57
+ symbol: {
58
+ type: string;
59
+ description: string;
60
+ };
61
+ file: {
62
+ type: string;
63
+ description: string;
64
+ };
65
+ includeDocs: {
66
+ type: string;
67
+ description: string;
68
+ };
69
+ };
70
+ required: string[];
71
+ };
72
+ };
73
+ //# sourceMappingURL=signature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../../../src/tools/surgical/signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,kBAAkB,CAAC;AAOrE,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAC9B,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAMD,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA4H7D;AAwDD;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;CAqBnC,CAAC"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * drift_signature - Get Function/Class Signatures
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 200 target, 500 max
6
+ * Cache TTL: 5 minutes
7
+ * Invalidation Keys: callgraph, file:{path}
8
+ *
9
+ * Returns just the signature without reading entire files.
10
+ * Solves: AI reads 500-line files just to see a 1-line signature.
11
+ */
12
+ import { createResponseBuilder, Errors, metrics } from '../../infrastructure/index.js';
13
+ // ============================================================================
14
+ // Handler
15
+ // ============================================================================
16
+ export async function handleSignature(store, args) {
17
+ const startTime = Date.now();
18
+ const builder = createResponseBuilder();
19
+ // Validate input
20
+ if (!args.symbol || args.symbol.trim() === '') {
21
+ throw Errors.missingParameter('symbol');
22
+ }
23
+ const symbol = args.symbol.trim();
24
+ // includeDocs reserved for future use
25
+ // const includeDocs = args.includeDocs !== false;
26
+ // Load call graph
27
+ await store.initialize();
28
+ const graph = store.getGraph();
29
+ if (!graph) {
30
+ throw Errors.custom('CALLGRAPH_NOT_BUILT', 'Call graph has not been built. Run "drift callgraph build" first.', ['drift_status']);
31
+ }
32
+ // Find matching functions
33
+ const matches = [];
34
+ for (const [, func] of graph.functions) {
35
+ // Match by name or qualified name
36
+ const nameMatch = func.name === symbol ||
37
+ func.qualifiedName === symbol ||
38
+ func.qualifiedName.endsWith(`.${symbol}`);
39
+ // If file specified, filter by file
40
+ const fileMatch = !args.file ||
41
+ func.file === args.file ||
42
+ func.file.endsWith(args.file);
43
+ if (nameMatch && fileMatch) {
44
+ matches.push(func);
45
+ }
46
+ }
47
+ // Build signatures
48
+ const signatures = matches.map(func => {
49
+ const sig = buildSignature(func);
50
+ return {
51
+ file: func.file,
52
+ line: func.startLine,
53
+ kind: func.className ? 'method' : 'function',
54
+ signature: sig,
55
+ parameters: func.parameters.map(p => ({
56
+ name: p.name,
57
+ type: p.type || 'unknown',
58
+ required: !p.hasDefault,
59
+ default: p.hasDefault ? '...' : undefined,
60
+ })),
61
+ returnType: func.returnType,
62
+ exported: func.isExported,
63
+ className: func.className,
64
+ decorators: func.decorators.length > 0 ? func.decorators : undefined,
65
+ };
66
+ });
67
+ // Sort by relevance: exact name match first, then exported, then by file
68
+ signatures.sort((a, b) => {
69
+ // Exact name match
70
+ const aExact = a.signature.includes(` ${symbol}(`) ? 0 : 1;
71
+ const bExact = b.signature.includes(` ${symbol}(`) ? 0 : 1;
72
+ if (aExact !== bExact)
73
+ return aExact - bExact;
74
+ // Exported first
75
+ if (a.exported !== b.exported)
76
+ return a.exported ? -1 : 1;
77
+ // Alphabetical by file
78
+ return a.file.localeCompare(b.file);
79
+ });
80
+ // Limit results
81
+ const limitedSignatures = signatures.slice(0, 5);
82
+ const data = {
83
+ found: limitedSignatures.length > 0,
84
+ signatures: limitedSignatures,
85
+ };
86
+ // Build summary
87
+ let summary;
88
+ if (limitedSignatures.length === 0) {
89
+ summary = `No signature found for "${symbol}"`;
90
+ }
91
+ else if (limitedSignatures.length === 1) {
92
+ const sig = limitedSignatures[0];
93
+ summary = `Found ${sig.kind} "${symbol}" in ${sig.file}:${sig.line}`;
94
+ }
95
+ else {
96
+ summary = `Found ${limitedSignatures.length} matches for "${symbol}"`;
97
+ }
98
+ // Build hints
99
+ const hints = {
100
+ nextActions: limitedSignatures.length > 0
101
+ ? [
102
+ `Use drift_callers to see who calls "${symbol}"`,
103
+ `Use drift_imports to get correct import statement`,
104
+ ]
105
+ : [
106
+ 'Check spelling or try a partial name',
107
+ 'Use drift_files_list to find relevant files',
108
+ ],
109
+ relatedTools: ['drift_callers', 'drift_imports', 'drift_type'],
110
+ };
111
+ if (signatures.length > 5) {
112
+ hints.warnings = [`${signatures.length - 5} additional matches not shown. Specify file to narrow results.`];
113
+ }
114
+ // Record metrics
115
+ metrics.recordRequest('drift_signature', Date.now() - startTime, true, false);
116
+ return builder
117
+ .withSummary(summary)
118
+ .withData(data)
119
+ .withHints(hints)
120
+ .buildContent();
121
+ }
122
+ // ============================================================================
123
+ // Helpers
124
+ // ============================================================================
125
+ /**
126
+ * Build a human-readable signature string
127
+ */
128
+ function buildSignature(func) {
129
+ const parts = [];
130
+ // Decorators (first one only for brevity)
131
+ if (func.decorators.length > 0) {
132
+ parts.push(`@${func.decorators[0]}`);
133
+ }
134
+ // Export keyword
135
+ if (func.isExported) {
136
+ parts.push('export');
137
+ }
138
+ // Async keyword
139
+ if (func.isAsync) {
140
+ parts.push('async');
141
+ }
142
+ // Function keyword
143
+ parts.push('function');
144
+ // Name
145
+ parts.push(func.name);
146
+ // Parameters
147
+ const params = func.parameters.map(p => {
148
+ let param = p.name;
149
+ if (p.type) {
150
+ param += `: ${p.type}`;
151
+ }
152
+ if (p.hasDefault) {
153
+ param += ' = ...';
154
+ }
155
+ return param;
156
+ }).join(', ');
157
+ // Build signature
158
+ let sig = parts.join(' ') + `(${params})`;
159
+ // Return type
160
+ if (func.returnType) {
161
+ sig += `: ${func.returnType}`;
162
+ }
163
+ return sig;
164
+ }
165
+ /**
166
+ * Tool definition for MCP registration
167
+ */
168
+ export const signatureToolDefinition = {
169
+ name: 'drift_signature',
170
+ description: 'Get function/class signature without reading entire files. Returns signature, parameters, return type, and location. Use when you need to know a function\'s interface.',
171
+ inputSchema: {
172
+ type: 'object',
173
+ properties: {
174
+ symbol: {
175
+ type: 'string',
176
+ description: 'Function, method, or class name to look up',
177
+ },
178
+ file: {
179
+ type: 'string',
180
+ description: 'Optional: specific file to search in (relative path)',
181
+ },
182
+ includeDocs: {
183
+ type: 'boolean',
184
+ description: 'Include JSDoc/docstring (default: true)',
185
+ },
186
+ },
187
+ required: ['symbol'],
188
+ },
189
+ };
190
+ //# sourceMappingURL=signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.js","sourceRoot":"","sources":["../../../src/tools/surgical/signature.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * drift_similar - Find Semantically Similar Code
3
+ *
4
+ * Layer: Surgical
5
+ * Token Budget: 500 target, 1000 max
6
+ * Cache TTL: 5 minutes
7
+ * Invalidation Keys: patterns, callgraph
8
+ *
9
+ * Finds code semantically similar to what the AI is about to write.
10
+ * Solves: AI needs to see an example but there are 50 options. Which is most relevant?
11
+ */
12
+ import type { CallGraphStore, PatternStore } from 'driftdetect-core';
13
+ export interface SimilarArgs {
14
+ /** What kind of code are you writing? */
15
+ intent: 'api_endpoint' | 'service' | 'component' | 'hook' | 'utility' | 'test' | 'middleware';
16
+ /** Natural language description */
17
+ description: string;
18
+ /** Optional: limit to specific directory */
19
+ scope?: string;
20
+ /** Max results (default: 3) */
21
+ limit?: number;
22
+ }
23
+ export interface SimilarMatch {
24
+ file: string;
25
+ function?: string | undefined;
26
+ class?: string | undefined;
27
+ similarity: number;
28
+ reason: string;
29
+ preview: string;
30
+ patterns: string[];
31
+ }
32
+ export interface SimilarConventions {
33
+ naming: string;
34
+ errorHandling: string;
35
+ imports: string;
36
+ }
37
+ export interface SimilarData {
38
+ matches: SimilarMatch[];
39
+ conventions: SimilarConventions;
40
+ }
41
+ export declare function handleSimilar(callGraphStore: CallGraphStore, patternStore: PatternStore, args: SimilarArgs): Promise<{
42
+ content: Array<{
43
+ type: string;
44
+ text: string;
45
+ }>;
46
+ }>;
47
+ /**
48
+ * Tool definition for MCP registration
49
+ */
50
+ export declare const similarToolDefinition: {
51
+ name: string;
52
+ description: string;
53
+ inputSchema: {
54
+ type: "object";
55
+ properties: {
56
+ intent: {
57
+ type: string;
58
+ enum: string[];
59
+ description: string;
60
+ };
61
+ description: {
62
+ type: string;
63
+ description: string;
64
+ };
65
+ scope: {
66
+ type: string;
67
+ description: string;
68
+ };
69
+ limit: {
70
+ type: string;
71
+ description: string;
72
+ };
73
+ };
74
+ required: string[];
75
+ };
76
+ };
77
+ //# sourceMappingURL=similar.d.ts.map