@stackguide/mcp-server 2.4.0 → 3.1.0

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 (42) hide show
  1. package/README.md +82 -16
  2. package/dist/config/healthWeights.d.ts +87 -0
  3. package/dist/config/healthWeights.d.ts.map +1 -0
  4. package/dist/config/healthWeights.js +238 -0
  5. package/dist/config/healthWeights.js.map +1 -0
  6. package/dist/config/types.d.ts +150 -0
  7. package/dist/config/types.d.ts.map +1 -1
  8. package/dist/config/types.js.map +1 -1
  9. package/dist/handlers/generate.d.ts +6 -0
  10. package/dist/handlers/generate.d.ts.map +1 -1
  11. package/dist/handlers/generate.js +81 -5
  12. package/dist/handlers/generate.js.map +1 -1
  13. package/dist/handlers/health.d.ts +7 -0
  14. package/dist/handlers/health.d.ts.map +1 -1
  15. package/dist/handlers/health.js +151 -69
  16. package/dist/handlers/health.js.map +1 -1
  17. package/dist/handlers/review.d.ts +12 -0
  18. package/dist/handlers/review.d.ts.map +1 -1
  19. package/dist/handlers/review.js +220 -21
  20. package/dist/handlers/review.js.map +1 -1
  21. package/dist/services/analysisCache.d.ts +110 -0
  22. package/dist/services/analysisCache.d.ts.map +1 -0
  23. package/dist/services/analysisCache.js +233 -0
  24. package/dist/services/analysisCache.js.map +1 -0
  25. package/dist/services/astAnalyzer.d.ts +21 -0
  26. package/dist/services/astAnalyzer.d.ts.map +1 -0
  27. package/dist/services/astAnalyzer.js +593 -0
  28. package/dist/services/astAnalyzer.js.map +1 -0
  29. package/dist/services/codeAnalyzer.d.ts +109 -30
  30. package/dist/services/codeAnalyzer.d.ts.map +1 -1
  31. package/dist/services/codeAnalyzer.js +519 -36
  32. package/dist/services/codeAnalyzer.js.map +1 -1
  33. package/dist/services/conventionDetector.d.ts +40 -0
  34. package/dist/services/conventionDetector.d.ts.map +1 -0
  35. package/dist/services/conventionDetector.js +465 -0
  36. package/dist/services/conventionDetector.js.map +1 -0
  37. package/dist/services/cursorDirectory.d.ts +29 -2
  38. package/dist/services/cursorDirectory.d.ts.map +1 -1
  39. package/dist/services/cursorDirectory.js +260 -9
  40. package/dist/services/cursorDirectory.js.map +1 -1
  41. package/dist/utils/validation.d.ts +2 -2
  42. package/package.json +2 -1
@@ -0,0 +1,593 @@
1
+ /**
2
+ * AST Analyzer Service - Phase 2
3
+ * Provides semantic code analysis using ts-morph
4
+ */
5
+ import { Project, SourceFile, Node, SyntaxKind, ts } from 'ts-morph';
6
+ import { logger } from '../utils/logger.js';
7
+ // =============================================================================
8
+ // AST PROJECT MANAGEMENT
9
+ // =============================================================================
10
+ /**
11
+ * Cached ts-morph project for performance
12
+ * We use in-memory file system to avoid disk I/O
13
+ */
14
+ let cachedProject = null;
15
+ function getProject() {
16
+ if (!cachedProject) {
17
+ cachedProject = new Project({
18
+ useInMemoryFileSystem: true,
19
+ compilerOptions: {
20
+ target: ts.ScriptTarget.ESNext,
21
+ module: ts.ModuleKind.ESNext,
22
+ strict: false, // Be lenient for analysis
23
+ skipLibCheck: true,
24
+ noEmit: true,
25
+ },
26
+ });
27
+ logger.debug('Created new ts-morph project');
28
+ }
29
+ return cachedProject;
30
+ }
31
+ /**
32
+ * Clear the cached project (useful for testing or memory management)
33
+ */
34
+ export function clearASTCache() {
35
+ if (cachedProject) {
36
+ cachedProject.getSourceFiles().forEach(sf => cachedProject.removeSourceFile(sf));
37
+ }
38
+ cachedProject = null;
39
+ logger.debug('Cleared AST cache');
40
+ }
41
+ // =============================================================================
42
+ // AST ANALYSIS
43
+ // =============================================================================
44
+ /**
45
+ * Parse source code into a ts-morph SourceFile
46
+ */
47
+ export function parseCode(filePath, content) {
48
+ try {
49
+ const project = getProject();
50
+ // Check if file already exists and remove it
51
+ const existing = project.getSourceFile(filePath);
52
+ if (existing) {
53
+ project.removeSourceFile(existing);
54
+ }
55
+ // Create the source file
56
+ const sourceFile = project.createSourceFile(filePath, content, { overwrite: true });
57
+ return sourceFile;
58
+ }
59
+ catch (error) {
60
+ logger.warn('Failed to parse code for AST analysis', { filePath, error: String(error) });
61
+ return null;
62
+ }
63
+ }
64
+ /**
65
+ * Map string node type names to ts-morph SyntaxKind
66
+ */
67
+ const NODE_TYPE_MAP = {
68
+ // Declarations
69
+ 'FunctionDeclaration': SyntaxKind.FunctionDeclaration,
70
+ 'ClassDeclaration': SyntaxKind.ClassDeclaration,
71
+ 'VariableDeclaration': SyntaxKind.VariableDeclaration,
72
+ 'InterfaceDeclaration': SyntaxKind.InterfaceDeclaration,
73
+ 'TypeAliasDeclaration': SyntaxKind.TypeAliasDeclaration,
74
+ 'EnumDeclaration': SyntaxKind.EnumDeclaration,
75
+ 'MethodDeclaration': SyntaxKind.MethodDeclaration,
76
+ 'PropertyDeclaration': SyntaxKind.PropertyDeclaration,
77
+ 'Constructor': SyntaxKind.Constructor,
78
+ 'GetAccessor': SyntaxKind.GetAccessor,
79
+ 'SetAccessor': SyntaxKind.SetAccessor,
80
+ // Expressions
81
+ 'CallExpression': SyntaxKind.CallExpression,
82
+ 'NewExpression': SyntaxKind.NewExpression,
83
+ 'ArrowFunction': SyntaxKind.ArrowFunction,
84
+ 'FunctionExpression': SyntaxKind.FunctionExpression,
85
+ 'BinaryExpression': SyntaxKind.BinaryExpression,
86
+ 'ConditionalExpression': SyntaxKind.ConditionalExpression,
87
+ 'PropertyAccessExpression': SyntaxKind.PropertyAccessExpression,
88
+ 'ElementAccessExpression': SyntaxKind.ElementAccessExpression,
89
+ 'AwaitExpression': SyntaxKind.AwaitExpression,
90
+ // Statements
91
+ 'IfStatement': SyntaxKind.IfStatement,
92
+ 'ForStatement': SyntaxKind.ForStatement,
93
+ 'ForInStatement': SyntaxKind.ForInStatement,
94
+ 'ForOfStatement': SyntaxKind.ForOfStatement,
95
+ 'WhileStatement': SyntaxKind.WhileStatement,
96
+ 'DoStatement': SyntaxKind.DoStatement,
97
+ 'SwitchStatement': SyntaxKind.SwitchStatement,
98
+ 'TryStatement': SyntaxKind.TryStatement,
99
+ 'CatchClause': SyntaxKind.CatchClause,
100
+ 'ThrowStatement': SyntaxKind.ThrowStatement,
101
+ 'ReturnStatement': SyntaxKind.ReturnStatement,
102
+ // Imports/Exports
103
+ 'ImportDeclaration': SyntaxKind.ImportDeclaration,
104
+ 'ExportDeclaration': SyntaxKind.ExportDeclaration,
105
+ 'ExportAssignment': SyntaxKind.ExportAssignment,
106
+ // JSX
107
+ 'JsxElement': SyntaxKind.JsxElement,
108
+ 'JsxSelfClosingElement': SyntaxKind.JsxSelfClosingElement,
109
+ 'JsxFragment': SyntaxKind.JsxFragment,
110
+ // Other
111
+ 'Parameter': SyntaxKind.Parameter,
112
+ 'TypeReference': SyntaxKind.TypeReference,
113
+ 'AsExpression': SyntaxKind.AsExpression,
114
+ };
115
+ /**
116
+ * Create an ASTCheckContext for a node
117
+ */
118
+ function createCheckContext(node, sourceFile, filePath) {
119
+ return {
120
+ node,
121
+ sourceFile,
122
+ filePath,
123
+ sourceText: sourceFile.getFullText(),
124
+ getNodeText: () => node.getText(),
125
+ getStartLine: () => node.getStartLineNumber(),
126
+ getTypeText: () => {
127
+ try {
128
+ // Try to get type information if available
129
+ if ('getType' in node && typeof node.getType === 'function') {
130
+ return node.getType().getText();
131
+ }
132
+ return 'unknown';
133
+ }
134
+ catch {
135
+ return 'unknown';
136
+ }
137
+ },
138
+ };
139
+ }
140
+ /**
141
+ * Run AST rules against a source file
142
+ */
143
+ export function analyzeWithAST(filePath, content, rules) {
144
+ const issues = [];
145
+ // Only analyze TS/JS files
146
+ const ext = filePath.split('.').pop()?.toLowerCase();
147
+ if (!['ts', 'tsx', 'js', 'jsx', 'mts', 'mjs', 'cts', 'cjs'].includes(ext || '')) {
148
+ return issues;
149
+ }
150
+ const sourceFile = parseCode(filePath, content);
151
+ if (!sourceFile) {
152
+ return issues;
153
+ }
154
+ logger.debug('Running AST analysis', { filePath, ruleCount: rules.length });
155
+ for (const rule of rules) {
156
+ if (!rule.enabled)
157
+ continue;
158
+ // Get the SyntaxKind values for this rule
159
+ const syntaxKinds = rule.nodeTypes
160
+ .map(nt => NODE_TYPE_MAP[nt])
161
+ .filter((sk) => sk !== undefined);
162
+ if (syntaxKinds.length === 0) {
163
+ logger.warn('No valid node types for AST rule', { ruleId: rule.id, nodeTypes: rule.nodeTypes });
164
+ continue;
165
+ }
166
+ // Find all matching nodes
167
+ for (const syntaxKind of syntaxKinds) {
168
+ const nodes = sourceFile.getDescendantsOfKind(syntaxKind);
169
+ for (const node of nodes) {
170
+ try {
171
+ const context = createCheckContext(node, sourceFile, filePath);
172
+ const result = rule.check(context);
173
+ if (result && result.hasIssue) {
174
+ const quickFix = rule.quickFix ? rule.quickFix(context) : undefined;
175
+ issues.push({
176
+ severity: rule.severity,
177
+ rule: rule.id,
178
+ category: rule.category,
179
+ message: result.message || rule.message,
180
+ line: result.line || context.getStartLine(),
181
+ code: result.code || context.getNodeText().substring(0, 100),
182
+ suggestion: rule.suggestion,
183
+ quickFix,
184
+ source: rule.source,
185
+ });
186
+ }
187
+ }
188
+ catch (error) {
189
+ logger.warn('Error running AST rule check', {
190
+ ruleId: rule.id,
191
+ filePath,
192
+ error: String(error)
193
+ });
194
+ }
195
+ }
196
+ }
197
+ }
198
+ logger.debug('AST analysis complete', { filePath, issuesFound: issues.length });
199
+ return issues;
200
+ }
201
+ // =============================================================================
202
+ // BUILTIN AST RULES
203
+ // =============================================================================
204
+ export const BUILTIN_AST_RULES = [
205
+ // -------------------------------------------------------------------------
206
+ // UNUSED EXPORTS
207
+ // -------------------------------------------------------------------------
208
+ {
209
+ id: 'AST001',
210
+ type: 'ast',
211
+ category: 'coding-standards',
212
+ nodeTypes: ['FunctionDeclaration', 'ClassDeclaration', 'VariableDeclaration'],
213
+ severity: 'warning',
214
+ message: 'Exported item may be unused within this file',
215
+ suggestion: 'Verify this export is used by other modules or remove it',
216
+ enabled: true,
217
+ priority: 50,
218
+ source: 'builtin',
219
+ check: (ctx) => {
220
+ const node = ctx.node;
221
+ // Check if the node has export modifier
222
+ if (!('getModifiers' in node))
223
+ return null;
224
+ const modifiers = node.getModifiers?.() || [];
225
+ const isExported = modifiers.some((m) => m.getKind() === SyntaxKind.ExportKeyword);
226
+ if (!isExported)
227
+ return null;
228
+ // Get the name
229
+ let name = '';
230
+ if ('getName' in node && typeof node.getName === 'function') {
231
+ name = node.getName() || '';
232
+ }
233
+ if (!name)
234
+ return null;
235
+ // Check if this name is used elsewhere in the file (simple heuristic)
236
+ const sourceText = ctx.sourceText;
237
+ const usagePattern = new RegExp(`\\b${name}\\b`, 'g');
238
+ const matches = sourceText.match(usagePattern);
239
+ // If only 1-2 occurrences, it's likely just the declaration and export
240
+ // This is a heuristic - a proper check would trace references
241
+ if (matches && matches.length <= 2) {
242
+ return {
243
+ hasIssue: true,
244
+ message: `Export '${name}' appears to have no internal usage`,
245
+ code: name,
246
+ };
247
+ }
248
+ return null;
249
+ },
250
+ },
251
+ // -------------------------------------------------------------------------
252
+ // EMPTY FUNCTION
253
+ // -------------------------------------------------------------------------
254
+ {
255
+ id: 'AST002',
256
+ type: 'ast',
257
+ category: 'coding-standards',
258
+ nodeTypes: ['FunctionDeclaration', 'MethodDeclaration', 'ArrowFunction'],
259
+ severity: 'info',
260
+ message: 'Empty function body detected',
261
+ suggestion: 'Add implementation or a comment explaining why it is empty',
262
+ enabled: true,
263
+ priority: 25,
264
+ source: 'builtin',
265
+ check: (ctx) => {
266
+ const node = ctx.node;
267
+ // Get function body
268
+ if (!('getBody' in node))
269
+ return null;
270
+ const body = node.getBody?.();
271
+ if (!body)
272
+ return null;
273
+ // Check if body is empty (no statements, or only whitespace/comments)
274
+ const bodyText = body.getText?.() || '';
275
+ const cleanBody = bodyText.replace(/[{}\s]/g, '').replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
276
+ if (cleanBody.length === 0) {
277
+ let name = 'anonymous';
278
+ if ('getName' in node && typeof node.getName === 'function') {
279
+ name = node.getName() || 'anonymous';
280
+ }
281
+ return {
282
+ hasIssue: true,
283
+ message: `Function '${name}' has an empty body`,
284
+ code: ctx.getNodeText().substring(0, 50),
285
+ };
286
+ }
287
+ return null;
288
+ },
289
+ },
290
+ // -------------------------------------------------------------------------
291
+ // TOO MANY PARAMETERS
292
+ // -------------------------------------------------------------------------
293
+ {
294
+ id: 'AST003',
295
+ type: 'ast',
296
+ category: 'architecture',
297
+ nodeTypes: ['FunctionDeclaration', 'MethodDeclaration', 'ArrowFunction', 'Constructor'],
298
+ severity: 'warning',
299
+ message: 'Function has too many parameters',
300
+ suggestion: 'Consider using an options object or refactoring into smaller functions',
301
+ enabled: true,
302
+ priority: 50,
303
+ source: 'builtin',
304
+ check: (ctx) => {
305
+ const node = ctx.node;
306
+ if (!('getParameters' in node))
307
+ return null;
308
+ const params = node.getParameters?.() || [];
309
+ const MAX_PARAMS = 4;
310
+ if (params.length > MAX_PARAMS) {
311
+ let name = 'function';
312
+ if ('getName' in node && typeof node.getName === 'function') {
313
+ name = node.getName() || 'function';
314
+ }
315
+ return {
316
+ hasIssue: true,
317
+ message: `'${name}' has ${params.length} parameters (max recommended: ${MAX_PARAMS})`,
318
+ code: `${params.length} parameters`,
319
+ };
320
+ }
321
+ return null;
322
+ },
323
+ },
324
+ // -------------------------------------------------------------------------
325
+ // NESTED CALLBACKS (Callback Hell)
326
+ // -------------------------------------------------------------------------
327
+ {
328
+ id: 'AST004',
329
+ type: 'ast',
330
+ category: 'coding-standards',
331
+ nodeTypes: ['CallExpression'],
332
+ severity: 'warning',
333
+ message: 'Deeply nested callbacks detected (callback hell)',
334
+ suggestion: 'Refactor using async/await or Promise chaining',
335
+ enabled: true,
336
+ priority: 75,
337
+ source: 'builtin',
338
+ check: (ctx) => {
339
+ const node = ctx.node;
340
+ // Count callback nesting depth
341
+ let depth = 0;
342
+ let current = node;
343
+ while (current) {
344
+ if (current.getKind() === SyntaxKind.CallExpression) {
345
+ // Check if this call has a function argument
346
+ const args = current.getArguments?.() || [];
347
+ const hasFunctionArg = args.some((arg) => arg.getKind() === SyntaxKind.ArrowFunction ||
348
+ arg.getKind() === SyntaxKind.FunctionExpression);
349
+ if (hasFunctionArg) {
350
+ depth++;
351
+ }
352
+ }
353
+ current = current.getParent();
354
+ }
355
+ const MAX_CALLBACK_DEPTH = 3;
356
+ if (depth > MAX_CALLBACK_DEPTH) {
357
+ return {
358
+ hasIssue: true,
359
+ message: `Callback nesting depth: ${depth} (max: ${MAX_CALLBACK_DEPTH})`,
360
+ code: ctx.getNodeText().substring(0, 50),
361
+ };
362
+ }
363
+ return null;
364
+ },
365
+ },
366
+ // -------------------------------------------------------------------------
367
+ // COMPLEX CONDITIONAL
368
+ // -------------------------------------------------------------------------
369
+ {
370
+ id: 'AST005',
371
+ type: 'ast',
372
+ category: 'coding-standards',
373
+ nodeTypes: ['IfStatement', 'ConditionalExpression'],
374
+ severity: 'info',
375
+ message: 'Complex conditional expression',
376
+ suggestion: 'Consider extracting conditions into named variables for clarity',
377
+ enabled: true,
378
+ priority: 25,
379
+ source: 'builtin',
380
+ check: (ctx) => {
381
+ const node = ctx.node;
382
+ const text = ctx.getNodeText();
383
+ // Count logical operators
384
+ const andCount = (text.match(/&&/g) || []).length;
385
+ const orCount = (text.match(/\|\|/g) || []).length;
386
+ const totalOps = andCount + orCount;
387
+ const MAX_LOGICAL_OPS = 3;
388
+ if (totalOps > MAX_LOGICAL_OPS) {
389
+ return {
390
+ hasIssue: true,
391
+ message: `Conditional has ${totalOps} logical operators (max: ${MAX_LOGICAL_OPS})`,
392
+ code: text.substring(0, 80),
393
+ };
394
+ }
395
+ return null;
396
+ },
397
+ },
398
+ // -------------------------------------------------------------------------
399
+ // MISSING RETURN TYPE
400
+ // -------------------------------------------------------------------------
401
+ {
402
+ id: 'AST006',
403
+ type: 'ast',
404
+ category: 'best-practices',
405
+ nodeTypes: ['FunctionDeclaration', 'MethodDeclaration'],
406
+ severity: 'suggestion',
407
+ message: 'Function is missing explicit return type',
408
+ suggestion: 'Add return type annotation for better type safety',
409
+ languages: ['typescript', 'tsx'],
410
+ enabled: true,
411
+ priority: 25,
412
+ source: 'builtin',
413
+ check: (ctx) => {
414
+ // Only check TypeScript files
415
+ if (!ctx.filePath.endsWith('.ts') && !ctx.filePath.endsWith('.tsx')) {
416
+ return null;
417
+ }
418
+ const node = ctx.node;
419
+ if (!('getReturnTypeNode' in node))
420
+ return null;
421
+ const returnType = node.getReturnTypeNode?.();
422
+ // Skip if return type is present
423
+ if (returnType)
424
+ return null;
425
+ // Skip constructors
426
+ if (node.getKind() === SyntaxKind.Constructor)
427
+ return null;
428
+ let name = 'function';
429
+ if ('getName' in node && typeof node.getName === 'function') {
430
+ name = node.getName() || 'function';
431
+ }
432
+ // Skip private/protected methods and simple getters
433
+ const text = ctx.getNodeText();
434
+ if (text.startsWith('private ') || text.startsWith('protected ')) {
435
+ return null;
436
+ }
437
+ return {
438
+ hasIssue: true,
439
+ message: `Function '${name}' is missing explicit return type`,
440
+ code: name,
441
+ };
442
+ },
443
+ },
444
+ // -------------------------------------------------------------------------
445
+ // ANY TYPE USAGE
446
+ // -------------------------------------------------------------------------
447
+ {
448
+ id: 'AST007',
449
+ type: 'ast',
450
+ category: 'best-practices',
451
+ nodeTypes: ['Parameter', 'VariableDeclaration', 'PropertyDeclaration'],
452
+ severity: 'warning',
453
+ message: 'Explicit "any" type usage detected',
454
+ suggestion: 'Use a more specific type or "unknown" for truly unknown types',
455
+ languages: ['typescript', 'tsx'],
456
+ enabled: true,
457
+ priority: 75,
458
+ source: 'builtin',
459
+ check: (ctx) => {
460
+ // Only check TypeScript files
461
+ if (!ctx.filePath.endsWith('.ts') && !ctx.filePath.endsWith('.tsx')) {
462
+ return null;
463
+ }
464
+ const node = ctx.node;
465
+ // Get the type node
466
+ let typeNode;
467
+ if ('getTypeNode' in node) {
468
+ typeNode = node.getTypeNode?.();
469
+ }
470
+ if (!typeNode)
471
+ return null;
472
+ const typeText = typeNode.getText();
473
+ if (typeText === 'any') {
474
+ return {
475
+ hasIssue: true,
476
+ message: 'Explicit "any" type detected',
477
+ code: ctx.getNodeText().substring(0, 50),
478
+ };
479
+ }
480
+ return null;
481
+ },
482
+ },
483
+ // -------------------------------------------------------------------------
484
+ // REACT: MISSING KEY IN LIST
485
+ // -------------------------------------------------------------------------
486
+ {
487
+ id: 'AST008',
488
+ type: 'ast',
489
+ category: 'react',
490
+ nodeTypes: ['CallExpression'],
491
+ severity: 'error',
492
+ message: 'Missing "key" prop in list rendering',
493
+ suggestion: 'Add a unique "key" prop to each element in the array',
494
+ languages: ['javascript', 'typescript', 'jsx', 'tsx'],
495
+ enabled: true,
496
+ priority: 100,
497
+ source: 'builtin',
498
+ check: (ctx) => {
499
+ const node = ctx.node;
500
+ // Check if this is a .map() call
501
+ const expression = node.getExpression?.();
502
+ if (!expression)
503
+ return null;
504
+ const expressionText = expression.getText?.() || '';
505
+ if (!expressionText.endsWith('.map'))
506
+ return null;
507
+ // Get the callback argument
508
+ const args = node.getArguments?.() || [];
509
+ if (args.length === 0)
510
+ return null;
511
+ const callback = args[0];
512
+ const callbackText = callback.getText?.() || '';
513
+ // Look for JSX element without key prop
514
+ const hasJsxReturn = callbackText.includes('<') && callbackText.includes('>');
515
+ const hasKeyProp = callbackText.includes('key=') || callbackText.includes('key:');
516
+ if (hasJsxReturn && !hasKeyProp) {
517
+ return {
518
+ hasIssue: true,
519
+ message: 'Array.map() rendering JSX without "key" prop',
520
+ code: expressionText + '(...)',
521
+ };
522
+ }
523
+ return null;
524
+ },
525
+ },
526
+ // -------------------------------------------------------------------------
527
+ // LONG CLASS
528
+ // -------------------------------------------------------------------------
529
+ {
530
+ id: 'AST009',
531
+ type: 'ast',
532
+ category: 'architecture',
533
+ nodeTypes: ['ClassDeclaration'],
534
+ severity: 'warning',
535
+ message: 'Class has too many members',
536
+ suggestion: 'Consider splitting into smaller, focused classes (SRP)',
537
+ enabled: true,
538
+ priority: 50,
539
+ source: 'builtin',
540
+ check: (ctx) => {
541
+ const node = ctx.node;
542
+ const members = node.getMembers?.() || [];
543
+ const MAX_MEMBERS = 15;
544
+ if (members.length > MAX_MEMBERS) {
545
+ const name = node.getName?.() || 'Class';
546
+ return {
547
+ hasIssue: true,
548
+ message: `Class '${name}' has ${members.length} members (max: ${MAX_MEMBERS})`,
549
+ code: name,
550
+ };
551
+ }
552
+ return null;
553
+ },
554
+ },
555
+ // -------------------------------------------------------------------------
556
+ // MAGIC NUMBER
557
+ // -------------------------------------------------------------------------
558
+ {
559
+ id: 'AST010',
560
+ type: 'ast',
561
+ category: 'coding-standards',
562
+ nodeTypes: ['BinaryExpression', 'VariableDeclaration'],
563
+ severity: 'info',
564
+ message: 'Magic number detected',
565
+ suggestion: 'Extract to a named constant for clarity',
566
+ enabled: true,
567
+ priority: 25,
568
+ source: 'builtin',
569
+ check: (ctx) => {
570
+ const text = ctx.getNodeText();
571
+ // Look for numeric literals > 1 (skip 0, 1, -1 as common cases)
572
+ const magicNumbers = text.match(/(?<![a-zA-Z_])\b([2-9]|[1-9]\d{2,})\b(?![a-zA-Z_])/g);
573
+ if (magicNumbers && magicNumbers.length > 0) {
574
+ // Filter out common acceptable numbers
575
+ const acceptable = ['100', '1000', '60', '24', '365', '1024', '2048', '4096'];
576
+ const realMagic = magicNumbers.filter(n => !acceptable.includes(n) && parseInt(n) > 10);
577
+ if (realMagic.length > 0) {
578
+ return {
579
+ hasIssue: true,
580
+ message: `Magic number(s) detected: ${realMagic.slice(0, 3).join(', ')}`,
581
+ code: text.substring(0, 50),
582
+ };
583
+ }
584
+ }
585
+ return null;
586
+ },
587
+ },
588
+ ];
589
+ // =============================================================================
590
+ // EXPORTS
591
+ // =============================================================================
592
+ export { SyntaxKind, Node, SourceFile };
593
+ //# sourceMappingURL=astAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astAnalyzer.js","sourceRoot":"","sources":["../../src/services/astAnalyzer.ts"],"names":[],"mappings":"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"}