neuronlayer 0.1.0 → 1.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 (78) hide show
  1. package/README.md +203 -123
  2. package/dist/index.js +635 -710
  3. package/dist/index.js.map +7 -0
  4. package/package.json +67 -63
  5. package/CONTRIBUTING.md +0 -127
  6. package/esbuild.config.js +0 -26
  7. package/src/cli/commands.ts +0 -382
  8. package/src/core/adr-exporter.ts +0 -253
  9. package/src/core/architecture/architecture-enforcement.ts +0 -228
  10. package/src/core/architecture/duplicate-detector.ts +0 -288
  11. package/src/core/architecture/index.ts +0 -6
  12. package/src/core/architecture/pattern-learner.ts +0 -306
  13. package/src/core/architecture/pattern-library.ts +0 -403
  14. package/src/core/architecture/pattern-validator.ts +0 -324
  15. package/src/core/change-intelligence/bug-correlator.ts +0 -444
  16. package/src/core/change-intelligence/change-intelligence.ts +0 -221
  17. package/src/core/change-intelligence/change-tracker.ts +0 -334
  18. package/src/core/change-intelligence/fix-suggester.ts +0 -340
  19. package/src/core/change-intelligence/index.ts +0 -5
  20. package/src/core/code-verifier.ts +0 -843
  21. package/src/core/confidence/confidence-scorer.ts +0 -251
  22. package/src/core/confidence/conflict-checker.ts +0 -289
  23. package/src/core/confidence/index.ts +0 -5
  24. package/src/core/confidence/source-tracker.ts +0 -263
  25. package/src/core/confidence/warning-detector.ts +0 -241
  26. package/src/core/context-rot/compaction.ts +0 -284
  27. package/src/core/context-rot/context-health.ts +0 -243
  28. package/src/core/context-rot/context-rot-prevention.ts +0 -213
  29. package/src/core/context-rot/critical-context.ts +0 -221
  30. package/src/core/context-rot/drift-detector.ts +0 -255
  31. package/src/core/context-rot/index.ts +0 -7
  32. package/src/core/context.ts +0 -263
  33. package/src/core/decision-extractor.ts +0 -339
  34. package/src/core/decisions.ts +0 -69
  35. package/src/core/deja-vu.ts +0 -421
  36. package/src/core/engine.ts +0 -1455
  37. package/src/core/feature-context.ts +0 -726
  38. package/src/core/ghost-mode.ts +0 -412
  39. package/src/core/learning.ts +0 -485
  40. package/src/core/living-docs/activity-tracker.ts +0 -296
  41. package/src/core/living-docs/architecture-generator.ts +0 -428
  42. package/src/core/living-docs/changelog-generator.ts +0 -348
  43. package/src/core/living-docs/component-generator.ts +0 -230
  44. package/src/core/living-docs/doc-engine.ts +0 -110
  45. package/src/core/living-docs/doc-validator.ts +0 -282
  46. package/src/core/living-docs/index.ts +0 -8
  47. package/src/core/project-manager.ts +0 -297
  48. package/src/core/summarizer.ts +0 -267
  49. package/src/core/test-awareness/change-validator.ts +0 -499
  50. package/src/core/test-awareness/index.ts +0 -5
  51. package/src/index.ts +0 -49
  52. package/src/indexing/ast.ts +0 -563
  53. package/src/indexing/embeddings.ts +0 -85
  54. package/src/indexing/indexer.ts +0 -245
  55. package/src/indexing/watcher.ts +0 -78
  56. package/src/server/gateways/aggregator.ts +0 -374
  57. package/src/server/gateways/index.ts +0 -473
  58. package/src/server/gateways/memory-ghost.ts +0 -343
  59. package/src/server/gateways/memory-query.ts +0 -452
  60. package/src/server/gateways/memory-record.ts +0 -346
  61. package/src/server/gateways/memory-review.ts +0 -410
  62. package/src/server/gateways/memory-status.ts +0 -517
  63. package/src/server/gateways/memory-verify.ts +0 -392
  64. package/src/server/gateways/router.ts +0 -434
  65. package/src/server/gateways/types.ts +0 -610
  66. package/src/server/mcp.ts +0 -154
  67. package/src/server/resources.ts +0 -85
  68. package/src/server/tools.ts +0 -2261
  69. package/src/storage/database.ts +0 -262
  70. package/src/storage/tier1.ts +0 -135
  71. package/src/storage/tier2.ts +0 -764
  72. package/src/storage/tier3.ts +0 -123
  73. package/src/types/documentation.ts +0 -619
  74. package/src/types/index.ts +0 -222
  75. package/src/utils/config.ts +0 -193
  76. package/src/utils/files.ts +0 -117
  77. package/src/utils/time.ts +0 -37
  78. package/src/utils/tokens.ts +0 -52
@@ -1,263 +0,0 @@
1
- import type { Tier2Storage } from '../../storage/tier2.js';
2
- import type { EmbeddingGenerator } from '../../indexing/embeddings.js';
3
- import type {
4
- ConfidenceSources,
5
- CodebaseMatch,
6
- DecisionMatch,
7
- PatternMatch
8
- } from '../../types/documentation.js';
9
-
10
- // Common code patterns to detect
11
- const CODE_PATTERNS = [
12
- { name: 'error-handling', regex: /try\s*\{[\s\S]*?\}\s*catch/i },
13
- { name: 'async-await', regex: /async\s+function|await\s+/i },
14
- { name: 'null-check', regex: /\?\.|!==?\s*null|===?\s*null/i },
15
- { name: 'array-methods', regex: /\.(map|filter|reduce|forEach|find)\s*\(/i },
16
- { name: 'destructuring', regex: /const\s+\{[\s\S]*?\}\s*=|const\s+\[[\s\S]*?\]\s*=/i },
17
- { name: 'arrow-function', regex: /=>\s*\{|=>\s*[^{]/i },
18
- { name: 'class-definition', regex: /class\s+\w+(\s+extends\s+\w+)?\s*\{/i },
19
- { name: 'interface-definition', regex: /interface\s+\w+\s*\{/i },
20
- { name: 'type-definition', regex: /type\s+\w+\s*=/i },
21
- { name: 'import-statement', regex: /import\s+.*\s+from\s+['"`]/i },
22
- { name: 'export-statement', regex: /export\s+(default\s+)?(class|function|const|interface|type)/i },
23
- { name: 'promise-handling', regex: /\.then\s*\(|\.catch\s*\(|Promise\./i },
24
- { name: 'validation', regex: /if\s*\(.*\)\s*(throw|return)/i },
25
- { name: 'logging', regex: /console\.(log|error|warn|info)/i },
26
- { name: 'event-handling', regex: /\.on\(|addEventListener|emit\(/i }
27
- ];
28
-
29
- export class SourceTracker {
30
- private tier2: Tier2Storage;
31
- private embeddingGenerator: EmbeddingGenerator;
32
-
33
- constructor(tier2: Tier2Storage, embeddingGenerator: EmbeddingGenerator) {
34
- this.tier2 = tier2;
35
- this.embeddingGenerator = embeddingGenerator;
36
- }
37
-
38
- async trackSources(code: string, context?: string): Promise<ConfidenceSources> {
39
- // Find similar code in codebase
40
- const codebaseMatches = await this.findSimilarCode(code, context);
41
-
42
- // Find related decisions
43
- const decisionMatches = await this.findRelatedDecisions(code, context);
44
-
45
- // Find matching patterns
46
- const patternMatches = this.findMatchingPatterns(code);
47
-
48
- // Determine if general knowledge was used
49
- const usedGeneralKnowledge = codebaseMatches.length === 0 && decisionMatches.length === 0;
50
-
51
- return {
52
- codebase: codebaseMatches,
53
- decisions: decisionMatches,
54
- patterns: patternMatches,
55
- usedGeneralKnowledge
56
- };
57
- }
58
-
59
- private async findSimilarCode(code: string, context?: string): Promise<CodebaseMatch[]> {
60
- const matches: CodebaseMatch[] = [];
61
-
62
- try {
63
- // Generate embedding for the code
64
- const textToEmbed = context ? `${context}\n${code}` : code;
65
- const embedding = await this.embeddingGenerator.embed(textToEmbed);
66
-
67
- // Search for similar code
68
- const results = this.tier2.search(embedding, 10);
69
-
70
- for (const result of results) {
71
- // Convert similarity to percentage (0-100)
72
- const similarity = Math.round(result.similarity * 100);
73
-
74
- if (similarity >= 30) { // Only include if at least 30% similar
75
- const file = this.tier2.getFile(result.path);
76
- const symbols = file ? this.tier2.getSymbolsByFile(file.id) : [];
77
- const dependents = this.tier2.getFileDependents(result.path);
78
-
79
- matches.push({
80
- file: result.path,
81
- similarity,
82
- snippet: result.preview,
83
- lastModified: file ? new Date(file.lastModified) : undefined,
84
- usageCount: dependents.length + 1,
85
- function: symbols.length > 0 ? symbols[0].name : undefined
86
- });
87
- }
88
- }
89
- } catch (error) {
90
- console.error('Error finding similar code:', error);
91
- }
92
-
93
- return matches.slice(0, 5); // Return top 5
94
- }
95
-
96
- private async findRelatedDecisions(code: string, context?: string): Promise<DecisionMatch[]> {
97
- const matches: DecisionMatch[] = [];
98
-
99
- try {
100
- // Generate embedding for decision search
101
- const textToEmbed = context ? `${context}\n${code}` : code;
102
- const embedding = await this.embeddingGenerator.embed(textToEmbed);
103
-
104
- // Search decisions
105
- const decisions = this.tier2.searchDecisions(embedding, 5);
106
-
107
- for (const decision of decisions) {
108
- // Calculate relevance based on similarity
109
- const relevance = Math.round(decision.similarity * 100);
110
-
111
- if (relevance >= 40) { // Only include if at least 40% relevant
112
- matches.push({
113
- id: decision.id,
114
- title: decision.title,
115
- date: decision.createdAt,
116
- relevance
117
- });
118
- }
119
- }
120
- } catch (error) {
121
- console.error('Error finding related decisions:', error);
122
- }
123
-
124
- return matches;
125
- }
126
-
127
- private findMatchingPatterns(code: string): PatternMatch[] {
128
- const matches: PatternMatch[] = [];
129
-
130
- for (const pattern of CODE_PATTERNS) {
131
- if (pattern.regex.test(code)) {
132
- // Calculate confidence based on how common the pattern is
133
- const confidence = this.calculatePatternConfidence(pattern.name, code);
134
-
135
- matches.push({
136
- pattern: pattern.name,
137
- confidence,
138
- examples: this.findPatternExamples(pattern.name)
139
- });
140
- }
141
- }
142
-
143
- // Sort by confidence
144
- matches.sort((a, b) => b.confidence - a.confidence);
145
-
146
- return matches.slice(0, 5); // Return top 5
147
- }
148
-
149
- private calculatePatternConfidence(patternName: string, code: string): number {
150
- // Base confidence for detecting a pattern
151
- let confidence = 60;
152
-
153
- // Boost for common patterns
154
- const commonPatterns = ['error-handling', 'async-await', 'null-check', 'validation'];
155
- if (commonPatterns.includes(patternName)) {
156
- confidence += 15;
157
- }
158
-
159
- // Check if pattern is used correctly (basic heuristics)
160
- switch (patternName) {
161
- case 'error-handling':
162
- if (/catch\s*\(\s*\w+\s*\)\s*\{[\s\S]*\}/.test(code)) confidence += 10;
163
- break;
164
- case 'async-await':
165
- if (/await\s+[^;]+;/.test(code) && /async\s+/.test(code)) confidence += 10;
166
- break;
167
- case 'null-check':
168
- if (/\?\.\w+/.test(code) || /!==?\s*null/.test(code)) confidence += 10;
169
- break;
170
- }
171
-
172
- return Math.min(95, confidence);
173
- }
174
-
175
- private findPatternExamples(patternName: string): string[] {
176
- // Get files that use this pattern
177
- const examples: string[] = [];
178
- const files = this.tier2.getAllFiles();
179
-
180
- for (const file of files.slice(0, 50)) { // Check first 50 files
181
- const preview = file.preview || '';
182
- const pattern = CODE_PATTERNS.find(p => p.name === patternName);
183
-
184
- if (pattern && pattern.regex.test(preview)) {
185
- examples.push(file.path);
186
- if (examples.length >= 3) break;
187
- }
188
- }
189
-
190
- return examples;
191
- }
192
-
193
- // Get detailed source tracking for display
194
- async getDetailedTracking(code: string, context?: string): Promise<{
195
- codebaseWeight: number;
196
- decisionWeight: number;
197
- patternWeight: number;
198
- sources: ConfidenceSources;
199
- formatted: string;
200
- }> {
201
- const sources = await this.trackSources(code, context);
202
-
203
- // Calculate weights based on what was found
204
- let codebaseWeight = 0.5;
205
- let decisionWeight = 0.3;
206
- let patternWeight = 0.2;
207
-
208
- // Adjust weights if sources are missing
209
- if (sources.codebase.length === 0) {
210
- codebaseWeight = 0;
211
- decisionWeight += 0.25;
212
- patternWeight += 0.25;
213
- }
214
-
215
- if (sources.decisions.length === 0) {
216
- decisionWeight = 0;
217
- codebaseWeight += 0.15;
218
- patternWeight += 0.15;
219
- }
220
-
221
- // Format for display
222
- const lines: string[] = [];
223
- lines.push('\u{1F4CA} Suggestion Sources\n');
224
-
225
- if (sources.codebase.length > 0) {
226
- lines.push(`Codebase (${Math.round(codebaseWeight * 100)}% weight):`);
227
- for (const match of sources.codebase) {
228
- lines.push(`\u251C\u2500\u2500 ${match.file}${match.line ? `:${match.line}` : ''} (${match.similarity}% similar)`);
229
- }
230
- lines.push('');
231
- }
232
-
233
- if (sources.decisions.length > 0) {
234
- lines.push(`Decisions (${Math.round(decisionWeight * 100)}% weight):`);
235
- for (const decision of sources.decisions) {
236
- lines.push(`\u2514\u2500\u2500 "${decision.title}" (${decision.relevance}% relevant)`);
237
- }
238
- lines.push('');
239
- }
240
-
241
- if (sources.patterns.length > 0) {
242
- lines.push(`Patterns (${Math.round(patternWeight * 100)}% weight):`);
243
- for (const pattern of sources.patterns) {
244
- lines.push(`\u2514\u2500\u2500 ${pattern.pattern} (${pattern.confidence}% confidence)`);
245
- }
246
- lines.push('');
247
- }
248
-
249
- if (sources.usedGeneralKnowledge) {
250
- lines.push('General Knowledge: Used (no codebase matches found)');
251
- } else {
252
- lines.push('General Knowledge: Not used');
253
- }
254
-
255
- return {
256
- codebaseWeight,
257
- decisionWeight,
258
- patternWeight,
259
- sources,
260
- formatted: lines.join('\n')
261
- };
262
- }
263
- }
@@ -1,241 +0,0 @@
1
- import type { Tier2Storage } from '../../storage/tier2.js';
2
- import type {
3
- ConfidenceSources,
4
- ConfidenceWarning,
5
- WarningType
6
- } from '../../types/documentation.js';
7
-
8
- // Security patterns to detect
9
- const SECURITY_PATTERNS = [
10
- { pattern: /eval\s*\(/, issue: 'eval() usage', suggestion: 'Avoid eval() - use safer alternatives' },
11
- { pattern: /innerHTML\s*=/, issue: 'innerHTML assignment', suggestion: 'Use textContent or sanitize input to prevent XSS' },
12
- { pattern: /document\.write\s*\(/, issue: 'document.write() usage', suggestion: 'Use DOM manipulation methods instead' },
13
- { pattern: /\$\{.*\}.*(?:SELECT|INSERT|UPDATE|DELETE)/i, issue: 'SQL injection risk', suggestion: 'Use parameterized queries' },
14
- { pattern: /exec\s*\(.*\$\{/, issue: 'Command injection risk', suggestion: 'Sanitize user input before shell execution' },
15
- { pattern: /password\s*[:=]\s*['"`][^'"`]+['"`]/, issue: 'Hardcoded password', suggestion: 'Use environment variables or secure vaults' },
16
- { pattern: /api[_-]?key\s*[:=]\s*['"`][^'"`]+['"`]/i, issue: 'Hardcoded API key', suggestion: 'Use environment variables' },
17
- { pattern: /\bhttp:\/\//, issue: 'Insecure HTTP', suggestion: 'Use HTTPS for secure communication' },
18
- { pattern: /dangerouslySetInnerHTML/, issue: 'React XSS risk', suggestion: 'Sanitize content before using dangerouslySetInnerHTML' }
19
- ];
20
-
21
- // Deprecated patterns to detect
22
- const DEPRECATED_PATTERNS = [
23
- { pattern: /var\s+\w+\s*=/, suggestion: 'Use const or let instead of var' },
24
- { pattern: /new\s+Buffer\s*\(/, suggestion: 'Use Buffer.from() or Buffer.alloc() instead' },
25
- { pattern: /\.substr\s*\(/, suggestion: 'Use .slice() or .substring() instead of .substr()' },
26
- { pattern: /__proto__/, suggestion: 'Use Object.getPrototypeOf() instead of __proto__' },
27
- { pattern: /arguments\s*\[/, suggestion: 'Use rest parameters (...args) instead of arguments' },
28
- { pattern: /\.bind\s*\(this\)/, suggestion: 'Consider using arrow functions instead of .bind(this)' }
29
- ];
30
-
31
- // Complexity indicators
32
- const COMPLEXITY_INDICATORS = [
33
- { pattern: /if\s*\([^)]*\)\s*{[^}]*if\s*\([^)]*\)\s*{[^}]*if/s, level: 'high' as const },
34
- { pattern: /\?\s*[^:]+\s*:\s*[^:]+\s*\?\s*[^:]+\s*:/s, level: 'high' as const },
35
- { pattern: /for\s*\([^)]*\)\s*{[^}]*for\s*\([^)]*\)\s*{/s, level: 'medium' as const },
36
- { pattern: /&&.*&&.*&&||\|\|.*\|\|.*\|\|/s, level: 'medium' as const }
37
- ];
38
-
39
- const WARNING_DEFINITIONS: Record<WarningType, { defaultMessage: string; defaultSeverity: 'info' | 'warning' | 'critical' }> = {
40
- 'no_similar_pattern': {
41
- defaultMessage: 'No similar pattern found in your codebase',
42
- defaultSeverity: 'warning'
43
- },
44
- 'conflicts_with_decision': {
45
- defaultMessage: 'This conflicts with a past decision',
46
- defaultSeverity: 'critical'
47
- },
48
- 'untested_approach': {
49
- defaultMessage: 'This approach has no tests in your codebase',
50
- defaultSeverity: 'info'
51
- },
52
- 'high_complexity': {
53
- defaultMessage: 'This is complex code',
54
- defaultSeverity: 'warning'
55
- },
56
- 'potential_security_issue': {
57
- defaultMessage: 'Potential security concern detected',
58
- defaultSeverity: 'critical'
59
- },
60
- 'deprecated_approach': {
61
- defaultMessage: 'This uses deprecated patterns',
62
- defaultSeverity: 'warning'
63
- }
64
- };
65
-
66
- export class WarningDetector {
67
- private tier2: Tier2Storage;
68
-
69
- constructor(tier2: Tier2Storage) {
70
- this.tier2 = tier2;
71
- }
72
-
73
- async detectWarnings(code: string, sources: ConfidenceSources): Promise<ConfidenceWarning[]> {
74
- const warnings: ConfidenceWarning[] = [];
75
-
76
- // 1. Check for no similar patterns
77
- if (sources.codebase.length === 0 && sources.patterns.length === 0) {
78
- warnings.push(this.createWarning(
79
- 'no_similar_pattern',
80
- 'No similar code or patterns found in your codebase',
81
- 'warning',
82
- 'Review carefully - this is new for your project'
83
- ));
84
- }
85
-
86
- // 2. Check for security issues
87
- const securityWarnings = this.detectSecurityIssues(code);
88
- warnings.push(...securityWarnings);
89
-
90
- // 3. Check for deprecated patterns
91
- const deprecationWarnings = this.detectDeprecatedPatterns(code);
92
- warnings.push(...deprecationWarnings);
93
-
94
- // 4. Check complexity
95
- const complexityWarning = this.detectComplexity(code);
96
- if (complexityWarning) {
97
- warnings.push(complexityWarning);
98
- }
99
-
100
- // 5. Check for untested approach
101
- const untestedWarning = await this.checkForTests(code, sources);
102
- if (untestedWarning) {
103
- warnings.push(untestedWarning);
104
- }
105
-
106
- // Sort by severity (critical first)
107
- warnings.sort((a, b) => {
108
- const severityOrder = { critical: 0, warning: 1, info: 2 };
109
- return severityOrder[a.severity] - severityOrder[b.severity];
110
- });
111
-
112
- return warnings;
113
- }
114
-
115
- private detectSecurityIssues(code: string): ConfidenceWarning[] {
116
- const warnings: ConfidenceWarning[] = [];
117
-
118
- for (const { pattern, issue, suggestion } of SECURITY_PATTERNS) {
119
- if (pattern.test(code)) {
120
- warnings.push(this.createWarning(
121
- 'potential_security_issue',
122
- `Security concern: ${issue}`,
123
- 'critical',
124
- suggestion
125
- ));
126
- }
127
- }
128
-
129
- return warnings;
130
- }
131
-
132
- private detectDeprecatedPatterns(code: string): ConfidenceWarning[] {
133
- const warnings: ConfidenceWarning[] = [];
134
-
135
- for (const { pattern, suggestion } of DEPRECATED_PATTERNS) {
136
- if (pattern.test(code)) {
137
- warnings.push(this.createWarning(
138
- 'deprecated_approach',
139
- 'Uses deprecated pattern',
140
- 'warning',
141
- suggestion
142
- ));
143
- }
144
- }
145
-
146
- return warnings;
147
- }
148
-
149
- private detectComplexity(code: string): ConfidenceWarning | null {
150
- for (const { pattern, level } of COMPLEXITY_INDICATORS) {
151
- if (pattern.test(code)) {
152
- const severity = level === 'high' ? 'warning' : 'info';
153
- return this.createWarning(
154
- 'high_complexity',
155
- `${level.charAt(0).toUpperCase() + level.slice(1)} complexity detected`,
156
- severity,
157
- 'Consider breaking this into smaller functions'
158
- );
159
- }
160
- }
161
-
162
- // Check line count and nesting
163
- const lines = code.split('\n');
164
- if (lines.length > 50) {
165
- return this.createWarning(
166
- 'high_complexity',
167
- 'Long code block (>50 lines)',
168
- 'info',
169
- 'Consider splitting into multiple functions'
170
- );
171
- }
172
-
173
- return null;
174
- }
175
-
176
- private async checkForTests(code: string, sources: ConfidenceSources): Promise<ConfidenceWarning | null> {
177
- // Check if any of the matched files have corresponding tests
178
- const hasTests = sources.codebase.some(match => {
179
- const testPath = match.file.replace(/\.ts$/, '.test.ts').replace(/\.js$/, '.test.js');
180
- const specPath = match.file.replace(/\.ts$/, '.spec.ts').replace(/\.js$/, '.spec.js');
181
-
182
- return this.tier2.getFile(testPath) !== null ||
183
- this.tier2.getFile(specPath) !== null ||
184
- match.file.includes('.test.') ||
185
- match.file.includes('.spec.') ||
186
- match.file.includes('__tests__');
187
- });
188
-
189
- if (!hasTests && sources.codebase.length > 0) {
190
- return this.createWarning(
191
- 'untested_approach',
192
- 'Similar code has no tests',
193
- 'info',
194
- 'Consider adding tests before using this approach'
195
- );
196
- }
197
-
198
- // Check if the code itself looks like test code
199
- const isTestCode = /describe\s*\(|it\s*\(|test\s*\(|expect\s*\(|assert\./i.test(code);
200
- if (!isTestCode && code.includes('function') && sources.codebase.length === 0) {
201
- return this.createWarning(
202
- 'untested_approach',
203
- 'New function without matching tests',
204
- 'info',
205
- 'Consider writing tests for this functionality'
206
- );
207
- }
208
-
209
- return null;
210
- }
211
-
212
- private createWarning(
213
- type: WarningType,
214
- message?: string,
215
- severity?: 'info' | 'warning' | 'critical',
216
- suggestion?: string
217
- ): ConfidenceWarning {
218
- const defaults = WARNING_DEFINITIONS[type];
219
- return {
220
- type,
221
- message: message || defaults.defaultMessage,
222
- severity: severity || defaults.defaultSeverity,
223
- suggestion
224
- };
225
- }
226
-
227
- // Check for specific warning types
228
- hasSecurityWarnings(code: string): boolean {
229
- return SECURITY_PATTERNS.some(({ pattern }) => pattern.test(code));
230
- }
231
-
232
- hasDeprecatedPatterns(code: string): boolean {
233
- return DEPRECATED_PATTERNS.some(({ pattern }) => pattern.test(code));
234
- }
235
-
236
- isHighComplexity(code: string): boolean {
237
- return COMPLEXITY_INDICATORS.some(({ pattern, level }) =>
238
- level === 'high' && pattern.test(code)
239
- );
240
- }
241
- }