aios-core 4.0.2 → 4.0.4

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 (145) hide show
  1. package/.aios-core/.session/current-session.json +14 -0
  2. package/.aios-core/core/registry/registry-schema.json +166 -166
  3. package/.aios-core/core/registry/service-registry.json +6585 -6585
  4. package/.aios-core/data/registry-update-log.jsonl +113 -0
  5. package/.aios-core/development/scripts/approval-workflow.js +642 -642
  6. package/.aios-core/development/scripts/backup-manager.js +606 -606
  7. package/.aios-core/development/scripts/branch-manager.js +389 -389
  8. package/.aios-core/development/scripts/code-quality-improver.js +1311 -1311
  9. package/.aios-core/development/scripts/commit-message-generator.js +849 -849
  10. package/.aios-core/development/scripts/conflict-resolver.js +674 -674
  11. package/.aios-core/development/scripts/dependency-analyzer.js +637 -637
  12. package/.aios-core/development/scripts/diff-generator.js +351 -351
  13. package/.aios-core/development/scripts/elicitation-engine.js +384 -384
  14. package/.aios-core/development/scripts/elicitation-session-manager.js +299 -299
  15. package/.aios-core/development/scripts/git-wrapper.js +461 -461
  16. package/.aios-core/development/scripts/manifest-preview.js +244 -244
  17. package/.aios-core/development/scripts/metrics-tracker.js +775 -775
  18. package/.aios-core/development/scripts/modification-validator.js +554 -554
  19. package/.aios-core/development/scripts/pattern-learner.js +1224 -1224
  20. package/.aios-core/development/scripts/performance-analyzer.js +757 -757
  21. package/.aios-core/development/scripts/refactoring-suggester.js +1138 -1138
  22. package/.aios-core/development/scripts/rollback-handler.js +530 -530
  23. package/.aios-core/development/scripts/security-checker.js +358 -358
  24. package/.aios-core/development/scripts/template-engine.js +239 -239
  25. package/.aios-core/development/scripts/template-validator.js +278 -278
  26. package/.aios-core/development/scripts/test-generator.js +843 -843
  27. package/.aios-core/development/scripts/transaction-manager.js +589 -589
  28. package/.aios-core/development/scripts/usage-tracker.js +673 -673
  29. package/.aios-core/development/scripts/validate-filenames.js +226 -226
  30. package/.aios-core/development/scripts/version-tracker.js +526 -526
  31. package/.aios-core/development/scripts/yaml-validator.js +396 -396
  32. package/.aios-core/development/templates/service-template/README.md.hbs +158 -158
  33. package/.aios-core/development/templates/service-template/__tests__/index.test.ts.hbs +237 -237
  34. package/.aios-core/development/templates/service-template/client.ts.hbs +403 -403
  35. package/.aios-core/development/templates/service-template/errors.ts.hbs +182 -182
  36. package/.aios-core/development/templates/service-template/index.ts.hbs +120 -120
  37. package/.aios-core/development/templates/service-template/package.json.hbs +87 -87
  38. package/.aios-core/development/templates/service-template/types.ts.hbs +145 -145
  39. package/.aios-core/development/templates/squad-template/LICENSE +21 -21
  40. package/.aios-core/docs/SHARD-TRANSLATION-GUIDE.md +335 -0
  41. package/.aios-core/docs/component-creation-guide.md +458 -0
  42. package/.aios-core/docs/session-update-pattern.md +307 -0
  43. package/.aios-core/docs/standards/AIOS-FRAMEWORK-MASTER.md +1963 -0
  44. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-SUMMARY.md +1190 -0
  45. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1.md +439 -0
  46. package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO.md +5398 -0
  47. package/.aios-core/docs/standards/V3-ARCHITECTURAL-DECISIONS.md +523 -0
  48. package/.aios-core/docs/template-syntax.md +267 -0
  49. package/.aios-core/docs/troubleshooting-guide.md +625 -0
  50. package/.aios-core/infrastructure/templates/aios-sync.yaml.template +193 -193
  51. package/.aios-core/infrastructure/templates/coderabbit.yaml.template +279 -279
  52. package/.aios-core/infrastructure/templates/github-workflows/ci.yml.template +169 -169
  53. package/.aios-core/infrastructure/templates/github-workflows/pr-automation.yml.template +330 -330
  54. package/.aios-core/infrastructure/templates/github-workflows/release.yml.template +196 -196
  55. package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -63
  56. package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -18
  57. package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -85
  58. package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -145
  59. package/.aios-core/infrastructure/tests/utilities-audit-results.json +501 -0
  60. package/.aios-core/install-manifest.yaml +97 -97
  61. package/.aios-core/local-config.yaml.template +68 -68
  62. package/.aios-core/manifests/agents.csv +1 -0
  63. package/.aios-core/manifests/schema/manifest-schema.json +190 -190
  64. package/.aios-core/manifests/tasks.csv +121 -0
  65. package/.aios-core/manifests/workers.csv +204 -0
  66. package/.aios-core/monitor/hooks/lib/__init__.py +1 -1
  67. package/.aios-core/monitor/hooks/lib/enrich.py +58 -58
  68. package/.aios-core/monitor/hooks/lib/send_event.py +47 -47
  69. package/.aios-core/monitor/hooks/notification.py +29 -29
  70. package/.aios-core/monitor/hooks/post_tool_use.py +45 -45
  71. package/.aios-core/monitor/hooks/pre_compact.py +29 -29
  72. package/.aios-core/monitor/hooks/pre_tool_use.py +40 -40
  73. package/.aios-core/monitor/hooks/stop.py +29 -29
  74. package/.aios-core/monitor/hooks/subagent_stop.py +29 -29
  75. package/.aios-core/monitor/hooks/user_prompt_submit.py +38 -38
  76. package/.aios-core/product/templates/adr.hbs +125 -125
  77. package/.aios-core/product/templates/component-react-tmpl.tsx +98 -98
  78. package/.aios-core/product/templates/dbdr.hbs +241 -241
  79. package/.aios-core/product/templates/engine/schemas/adr.schema.json +102 -102
  80. package/.aios-core/product/templates/engine/schemas/dbdr.schema.json +205 -205
  81. package/.aios-core/product/templates/engine/schemas/epic.schema.json +175 -175
  82. package/.aios-core/product/templates/engine/schemas/pmdr.schema.json +175 -175
  83. package/.aios-core/product/templates/engine/schemas/prd-v2.schema.json +300 -300
  84. package/.aios-core/product/templates/engine/schemas/prd.schema.json +152 -152
  85. package/.aios-core/product/templates/engine/schemas/story.schema.json +222 -222
  86. package/.aios-core/product/templates/engine/schemas/task.schema.json +154 -154
  87. package/.aios-core/product/templates/epic.hbs +212 -212
  88. package/.aios-core/product/templates/eslintrc-security.json +32 -32
  89. package/.aios-core/product/templates/github-actions-cd.yml +212 -212
  90. package/.aios-core/product/templates/github-actions-ci.yml +172 -172
  91. package/.aios-core/product/templates/pmdr.hbs +186 -186
  92. package/.aios-core/product/templates/prd-v2.0.hbs +216 -216
  93. package/.aios-core/product/templates/prd.hbs +201 -201
  94. package/.aios-core/product/templates/shock-report-tmpl.html +502 -502
  95. package/.aios-core/product/templates/story.hbs +263 -263
  96. package/.aios-core/product/templates/task.hbs +170 -170
  97. package/.aios-core/product/templates/tmpl-comment-on-examples.sql +158 -158
  98. package/.aios-core/product/templates/tmpl-migration-script.sql +91 -91
  99. package/.aios-core/product/templates/tmpl-rls-granular-policies.sql +104 -104
  100. package/.aios-core/product/templates/tmpl-rls-kiss-policy.sql +10 -10
  101. package/.aios-core/product/templates/tmpl-rls-roles.sql +135 -135
  102. package/.aios-core/product/templates/tmpl-rls-simple.sql +77 -77
  103. package/.aios-core/product/templates/tmpl-rls-tenant.sql +152 -152
  104. package/.aios-core/product/templates/tmpl-rollback-script.sql +77 -77
  105. package/.aios-core/product/templates/tmpl-seed-data.sql +140 -140
  106. package/.aios-core/product/templates/tmpl-smoke-test.sql +16 -16
  107. package/.aios-core/product/templates/tmpl-staging-copy-merge.sql +139 -139
  108. package/.aios-core/product/templates/tmpl-stored-proc.sql +140 -140
  109. package/.aios-core/product/templates/tmpl-trigger.sql +152 -152
  110. package/.aios-core/product/templates/tmpl-view-materialized.sql +133 -133
  111. package/.aios-core/product/templates/tmpl-view.sql +177 -177
  112. package/.aios-core/product/templates/token-exports-css-tmpl.css +240 -240
  113. package/.aios-core/quality/schemas/quality-metrics.schema.json +233 -233
  114. package/.aios-core/scripts/migrate-framework-docs.sh +300 -300
  115. package/.aios-core/scripts/pm.sh +0 -0
  116. package/.claude/hooks/enforce-architecture-first.py +196 -0
  117. package/.claude/hooks/install-hooks.sh +41 -0
  118. package/.claude/hooks/mind-clone-governance.py +192 -0
  119. package/.claude/hooks/pre-commit-mmos-guard.sh +99 -0
  120. package/.claude/hooks/pre-commit-version-check.sh +156 -0
  121. package/.claude/hooks/read-protection.py +151 -0
  122. package/.claude/hooks/slug-validation.py +176 -0
  123. package/.claude/hooks/sql-governance.py +182 -0
  124. package/.claude/hooks/write-path-validation.py +194 -0
  125. package/.claude/rules/agent-authority.md +105 -0
  126. package/.claude/rules/coderabbit-integration.md +93 -0
  127. package/.claude/rules/ids-principles.md +112 -0
  128. package/.claude/rules/story-lifecycle.md +139 -0
  129. package/.claude/rules/workflow-execution.md +150 -0
  130. package/LICENSE +48 -48
  131. package/README.md +30 -7
  132. package/bin/aios-minimal.js +0 -0
  133. package/bin/aios.js +15 -15
  134. package/package.json +2 -4
  135. package/packages/aios-install/bin/aios-install.js +0 -0
  136. package/packages/aios-install/bin/edmcp.js +0 -0
  137. package/packages/aios-pro-cli/bin/aios-pro.js +0 -0
  138. package/scripts/check-markdown-links.py +352 -352
  139. package/scripts/dashboard-parallel-dev.sh +0 -0
  140. package/scripts/dashboard-parallel-phase3.sh +0 -0
  141. package/scripts/dashboard-parallel-phase4.sh +0 -0
  142. package/scripts/glue/README.md +355 -0
  143. package/scripts/glue/compose-agent-prompt.cjs +362 -0
  144. package/scripts/install-monitor-hooks.sh +0 -0
  145. package/.aios-core/lib/build.json +0 -1
@@ -1,758 +1,758 @@
1
- const fs = require('fs').promises;
2
- const path = require('path');
3
- const chalk = require('chalk');
4
-
5
- /**
6
- * Performance bottleneck analyzer for AIOS-FULLSTACK framework
7
- * Identifies performance issues and optimization opportunities
8
- */
9
- class PerformanceAnalyzer {
10
- constructor(options = {}) {
11
- this.rootPath = options.rootPath || process.cwd();
12
- this.thresholds = {
13
- fileSize: 50 * 1024, // 50KB
14
- functionLength: 50, // lines
15
- cyclomaticComplexity: 10,
16
- nestingDepth: 5,
17
- importCount: 20,
18
- unusedCode: 0.1 // 10% unused code ratio
19
- };
20
- this.performancePatterns = {
21
- // Sync operations that should be async
22
- syncOperations: [
23
- /fs\.readFileSync/g,
24
- /fs\.writeFileSync/g,
25
- /fs\.existsSync/g,
26
- /JSON\.parse\(\s*fs\.readFileSync/g
27
- ],
28
- // Memory-intensive patterns
29
- memoryIssues: [
30
- /\.map\(\s*.*\.map\(/g, // Nested maps
31
- /new Array\(\d{4,}\)/g, // Large arrays
32
- /JSON\.stringify.*JSON\.parse/g, // Unnecessary serialization
33
- /require\(\s*['"`][^'"`]+\.json['"`]\s*\)/g // Large JSON imports
34
- ],
35
- // Performance anti-patterns
36
- antiPatterns: [
37
- /console\.log/g, // Console logs in production
38
- /debugger/g, // Debugger statements
39
- /setTimeout\(\s*.*,\s*0\s*\)/g, // Unnecessary setTimeout
40
- /setInterval\(\s*.*,\s*[0-9]{1,2}\s*\)/g // High-frequency intervals
41
- ],
42
- // Inefficient loops
43
- inefficientLoops: [
44
- /for\s*\(\s*.*\.length\s*;/g, // Length calculated in loop condition
45
- /while\s*\(\s*true\s*\)/g, // Infinite loops
46
- /forEach.*forEach/g // Nested forEach
47
- ]
48
- };
49
- }
50
-
51
- /**
52
- * Analyze performance across all components
53
- */
54
- async analyzePerformance(components) {
55
- const analysis = {
56
- timestamp: new Date().toISOString(),
57
- overall_score: 0,
58
- bottlenecks: [],
59
- optimization_opportunities: [],
60
- memory_issues: [],
61
- async_opportunities: [],
62
- code_quality_issues: [],
63
- file_size_issues: [],
64
- complexity_issues: [],
65
- recommendations: [],
66
- metrics: {
67
- total_files_analyzed: 0,
68
- total_issues_found: 0,
69
- critical_issues: 0,
70
- high_priority_issues: 0,
71
- medium_priority_issues: 0,
72
- low_priority_issues: 0
73
- }
74
- };
75
-
76
- try {
77
- console.log(chalk.blue('🔍 Analyzing performance bottlenecks...'));
78
-
79
- // Analyze each component
80
- for (const component of components) {
81
- const componentAnalysis = await this.analyzeComponentPerformance(component);
82
-
83
- // Aggregate results
84
- analysis.bottlenecks.push(...componentAnalysis.bottlenecks);
85
- analysis.optimization_opportunities.push(...componentAnalysis.optimizations);
86
- analysis.memory_issues.push(...componentAnalysis.memory_issues);
87
- analysis.async_opportunities.push(...componentAnalysis.async_opportunities);
88
- analysis.code_quality_issues.push(...componentAnalysis.quality_issues);
89
- analysis.file_size_issues.push(...componentAnalysis.file_size_issues);
90
- analysis.complexity_issues.push(...componentAnalysis.complexity_issues);
91
-
92
- analysis.metrics.total_files_analyzed++;
93
- }
94
-
95
- // Calculate overall metrics
96
- analysis.overall_score = this.calculateOverallScore(analysis);
97
- analysis.metrics.total_issues_found = this.countTotalIssues(analysis);
98
- analysis.metrics = this.calculateIssuePriorities(analysis);
99
- analysis.recommendations = this.generatePerformanceRecommendations(analysis);
100
-
101
- console.log(chalk.green(`✅ Performance analysis completed`));
102
- console.log(chalk.gray(` Files analyzed: ${analysis.metrics.total_files_analyzed}`));
103
- console.log(chalk.gray(` Issues found: ${analysis.metrics.total_issues_found}`));
104
- console.log(chalk.gray(` Overall score: ${analysis.overall_score}/10`));
105
-
106
- return analysis;
107
-
108
- } catch (error) {
109
- console.error(chalk.red(`Performance analysis failed: ${error.message}`));
110
- throw error;
111
- }
112
- }
113
-
114
- /**
115
- * Analyze performance for a single component
116
- */
117
- async analyzeComponentPerformance(component) {
118
- const analysis = {
119
- component_id: component.id,
120
- component_type: component.type,
121
- bottlenecks: [],
122
- optimizations: [],
123
- memory_issues: [],
124
- async_opportunities: [],
125
- quality_issues: [],
126
- file_size_issues: [],
127
- complexity_issues: []
128
- };
129
-
130
- try {
131
- // Only analyze JavaScript files and executable components
132
- if (!this.shouldAnalyzeComponent(component)) {
133
- return analysis;
134
- }
135
-
136
- const filePath = path.join(this.rootPath, component.file_path);
137
- const content = await fs.readFile(filePath, 'utf-8');
138
- const stats = await fs.stat(filePath);
139
-
140
- // File size analysis
141
- if (stats.size > this.thresholds.fileSize) {
142
- analysis.file_size_issues.push({
143
- component: component.id,
144
- issue: `Large file size: ${this.formatBytes(stats.size)}`,
145
- severity: stats.size > this.thresholds.fileSize * 2 ? 'high' : 'medium',
146
- recommendation: 'Consider breaking down into smaller modules',
147
- impact: 'high',
148
- effort: 'medium'
149
- });
150
- }
151
-
152
- // Synchronous operations analysis
153
- const syncIssues = this.findSyncOperations(content, component);
154
- analysis.async_opportunities.push(...syncIssues);
155
-
156
- // Memory usage analysis
157
- const memoryIssues = this.findMemoryIssues(content, component);
158
- analysis.memory_issues.push(...memoryIssues);
159
-
160
- // Performance anti-patterns
161
- const antiPatterns = this.findAntiPatterns(content, component);
162
- analysis.quality_issues.push(...antiPatterns);
163
-
164
- // Loop efficiency analysis
165
- const loopIssues = this.findLoopIssues(content, component);
166
- analysis.bottlenecks.push(...loopIssues);
167
-
168
- // Function complexity analysis
169
- const complexityIssues = this.analyzeComplexity(content, component);
170
- analysis.complexity_issues.push(...complexityIssues);
171
-
172
- // Import/require analysis
173
- const importIssues = this.analyzeImports(content, component);
174
- analysis.optimizations.push(...importIssues);
175
-
176
- // Dead code analysis
177
- const deadCodeIssues = await this.findDeadCode(content, component);
178
- analysis.optimizations.push(...deadCodeIssues);
179
-
180
- } catch (error) {
181
- console.warn(chalk.yellow(`Failed to analyze performance for ${component.id}: ${error.message}`));
182
- }
183
-
184
- return analysis;
185
- }
186
-
187
- /**
188
- * Find synchronous operations that should be async
189
- */
190
- findSyncOperations(content, component) {
191
- const issues = [];
192
- const lines = content.split('\n');
193
-
194
- this.performancePatterns.syncOperations.forEach(pattern => {
195
- lines.forEach((line, index) => {
196
- const matches = line.match(pattern);
197
- if (matches) {
198
- matches.forEach(match => {
199
- issues.push({
200
- component: component.id,
201
- issue: `Synchronous operation: ${match}`,
202
- line: index + 1,
203
- context: line.trim(),
204
- severity: 'high',
205
- recommendation: 'Convert to async equivalent',
206
- impact: 'high',
207
- effort: 'low'
208
- });
209
- });
210
- }
211
- });
212
- });
213
-
214
- return issues;
215
- }
216
-
217
- /**
218
- * Find memory-intensive patterns
219
- */
220
- findMemoryIssues(content, component) {
221
- const issues = [];
222
- const lines = content.split('\n');
223
-
224
- this.performancePatterns.memoryIssues.forEach(pattern => {
225
- lines.forEach((line, index) => {
226
- const matches = line.match(pattern);
227
- if (matches) {
228
- matches.forEach(match => {
229
- let severity = 'medium';
230
- let recommendation = 'Optimize memory usage';
231
-
232
- if (match.includes('new Array')) {
233
- severity = 'high';
234
- recommendation = 'Use array literals or streaming for large datasets';
235
- } else if (match.includes('JSON.stringify.*JSON.parse')) {
236
- recommendation = 'Use direct object assignment or deep clone utilities';
237
- } else if (match.includes('.map(.*map(')) {
238
- recommendation = 'Combine operations or use more efficient iteration';
239
- }
240
-
241
- issues.push({
242
- component: component.id,
243
- issue: `Memory-intensive pattern: ${match}`,
244
- line: index + 1,
245
- context: line.trim(),
246
- severity,
247
- recommendation,
248
- impact: 'medium',
249
- effort: 'medium'
250
- });
251
- });
252
- }
253
- });
254
- });
255
-
256
- return issues;
257
- }
258
-
259
- /**
260
- * Find performance anti-patterns
261
- */
262
- findAntiPatterns(content, component) {
263
- const issues = [];
264
- const lines = content.split('\n');
265
-
266
- this.performancePatterns.antiPatterns.forEach(pattern => {
267
- lines.forEach((line, index) => {
268
- const matches = line.match(pattern);
269
- if (matches) {
270
- matches.forEach(match => {
271
- let severity = 'low';
272
- let recommendation = 'Remove or optimize';
273
-
274
- if (match.includes('console.log')) {
275
- recommendation = 'Remove console.log statements from production code';
276
- } else if (match.includes('debugger')) {
277
- severity = 'medium';
278
- recommendation = 'Remove debugger statements';
279
- } else if (match.includes('setTimeout')) {
280
- recommendation = 'Use proper async/await or promises instead';
281
- }
282
-
283
- issues.push({
284
- component: component.id,
285
- issue: `Performance anti-pattern: ${match}`,
286
- line: index + 1,
287
- context: line.trim(),
288
- severity,
289
- recommendation,
290
- impact: 'low',
291
- effort: 'low'
292
- });
293
- });
294
- }
295
- });
296
- });
297
-
298
- return issues;
299
- }
300
-
301
- /**
302
- * Find inefficient loop patterns
303
- */
304
- findLoopIssues(content, component) {
305
- const issues = [];
306
- const lines = content.split('\n');
307
-
308
- this.performancePatterns.inefficientLoops.forEach(pattern => {
309
- lines.forEach((line, index) => {
310
- const matches = line.match(pattern);
311
- if (matches) {
312
- matches.forEach(match => {
313
- let severity = 'medium';
314
- let recommendation = 'Optimize loop structure';
315
-
316
- if (match.includes('.length')) {
317
- recommendation = 'Cache array length in variable before loop';
318
- } else if (match.includes('while(true)')) {
319
- severity = 'high';
320
- recommendation = 'Add proper exit condition to prevent infinite loops';
321
- } else if (match.includes('forEach.*forEach')) {
322
- recommendation = 'Consider using nested for loops or array methods like flatMap';
323
- }
324
-
325
- issues.push({
326
- component: component.id,
327
- issue: `Inefficient loop: ${match}`,
328
- line: index + 1,
329
- context: line.trim(),
330
- severity,
331
- recommendation,
332
- impact: 'medium',
333
- effort: 'low'
334
- });
335
- });
336
- }
337
- });
338
- });
339
-
340
- return issues;
341
- }
342
-
343
- /**
344
- * Analyze function complexity
345
- */
346
- analyzeComplexity(content, component) {
347
- const issues = [];
348
- const functions = this.extractFunctions(content);
349
-
350
- functions.forEach(func => {
351
- // Check function length
352
- if (func.lines > this.thresholds.functionLength) {
353
- issues.push({
354
- component: component.id,
355
- issue: `Long function: ${func.name} (${func.lines} lines)`,
356
- line: func.startLine,
357
- severity: func.lines > this.thresholds.functionLength * 2 ? 'high' : 'medium',
358
- recommendation: 'Break down into smaller functions',
359
- impact: 'medium',
360
- effort: 'medium'
361
- });
362
- }
363
-
364
- // Check cyclomatic complexity
365
- if (func.complexity > this.thresholds.cyclomaticComplexity) {
366
- issues.push({
367
- component: component.id,
368
- issue: `High complexity: ${func.name} (complexity: ${func.complexity})`,
369
- line: func.startLine,
370
- severity: func.complexity > this.thresholds.cyclomaticComplexity * 1.5 ? 'high' : 'medium',
371
- recommendation: 'Reduce conditional complexity',
372
- impact: 'high',
373
- effort: 'high'
374
- });
375
- }
376
-
377
- // Check nesting depth
378
- if (func.nestingDepth > this.thresholds.nestingDepth) {
379
- issues.push({
380
- component: component.id,
381
- issue: `Deep nesting: ${func.name} (depth: ${func.nestingDepth})`,
382
- line: func.startLine,
383
- severity: 'medium',
384
- recommendation: 'Reduce nesting depth using early returns or guard clauses',
385
- impact: 'medium',
386
- effort: 'medium'
387
- });
388
- }
389
- });
390
-
391
- return issues;
392
- }
393
-
394
- /**
395
- * Analyze imports and requires
396
- */
397
- analyzeImports(content, component) {
398
- const issues = [];
399
- const imports = this.extractImports(content);
400
-
401
- if (imports.length > this.thresholds.importCount) {
402
- issues.push({
403
- component: component.id,
404
- issue: `Too many imports: ${imports.length}`,
405
- severity: 'medium',
406
- recommendation: 'Consider breaking down module or using dynamic imports',
407
- impact: 'low',
408
- effort: 'medium'
409
- });
410
- }
411
-
412
- // Find unused imports (basic heuristic)
413
- const unusedImports = imports.filter(imp => {
414
- const usage = content.split(imp.name).length - 1;
415
- return usage <= 1; // Only appears in import statement
416
- });
417
-
418
- if (unusedImports.length > 0) {
419
- issues.push({
420
- component: component.id,
421
- issue: `Unused imports: ${unusedImports.map(i => i.name).join(', ')}`,
422
- severity: 'low',
423
- recommendation: 'Remove unused imports',
424
- impact: 'low',
425
- effort: 'low'
426
- });
427
- }
428
-
429
- return issues;
430
- }
431
-
432
- /**
433
- * Find dead code (unused functions, variables)
434
- */
435
- async findDeadCode(content, component) {
436
- const issues = [];
437
-
438
- // This is a simplified implementation
439
- // A full implementation would analyze the entire codebase for usage
440
- const functions = this.extractFunctions(content);
441
- const exports = this.extractExports(content);
442
-
443
- // Check for functions that are defined but never called within the file
444
- functions.forEach(func => {
445
- if (!func.name.startsWith('_') && !exports.includes(func.name)) {
446
- const usage = content.split(func.name).length - 1;
447
- if (usage <= 1) { // Only appears in definition
448
- issues.push({
449
- component: component.id,
450
- issue: `Potentially unused function: ${func.name}`,
451
- line: func.startLine,
452
- severity: 'low',
453
- recommendation: 'Remove if truly unused or export if needed elsewhere',
454
- impact: 'low',
455
- effort: 'low'
456
- });
457
- }
458
- }
459
- });
460
-
461
- return issues;
462
- }
463
-
464
- /**
465
- * Extract function information from code
466
- */
467
- extractFunctions(content) {
468
- const functions = [];
469
- const lines = content.split('\n');
470
- const functionRegex = /(?:function\s+(\w+)|(\w+)\s*[:=]\s*(?:async\s+)?function|(?:async\s+)?(\w+)\s*\([^)]*\)\s*(?:=>|{))/g;
471
-
472
- lines.forEach((line, index) => {
473
- const matches = [...line.matchAll(functionRegex)];
474
- matches.forEach(match => {
475
- const name = match[1] || match[2] || match[3] || 'anonymous';
476
-
477
- // Calculate function metrics (simplified)
478
- const funcInfo = {
479
- name,
480
- startLine: index + 1,
481
- lines: this.estimateFunctionLength(lines, index),
482
- complexity: this.estimateComplexity(lines, index),
483
- nestingDepth: this.estimateNestingDepth(lines, index)
484
- };
485
-
486
- functions.push(funcInfo);
487
- });
488
- });
489
-
490
- return functions;
491
- }
492
-
493
- /**
494
- * Extract import information
495
- */
496
- extractImports(content) {
497
- const imports = [];
498
- const importRegex = /(?:import\s+(?:(\w+)|\{([^}]+)\}|.*)\s+from\s+['"`]([^'"`]+)['"`]|const\s+(?:(\w+)|\{([^}]+)\})\s*=\s*require\(['"`]([^'"`]+)['"`]\))/g;
499
-
500
- const matches = [...content.matchAll(importRegex)];
501
- matches.forEach(match => {
502
- const defaultImport = match[1] || match[4];
503
- const namedImports = match[2] || match[5];
504
- const source = match[3] || match[6];
505
-
506
- if (defaultImport) {
507
- imports.push({ name: defaultImport, source, type: 'default' });
508
- }
509
-
510
- if (namedImports) {
511
- namedImports.split(',').forEach(name => {
512
- imports.push({ name: name.trim(), source, type: 'named' });
513
- });
514
- }
515
- });
516
-
517
- return imports;
518
- }
519
-
520
- /**
521
- * Extract export information
522
- */
523
- extractExports(content) {
524
- const exports = [];
525
- const exportRegex = /(?:export\s+(?:default\s+)?(?:function\s+(\w+)|class\s+(\w+)|(?:const|let|var)\s+(\w+))|module\.exports\s*=\s*(\w+))/g;
526
-
527
- const matches = [...content.matchAll(exportRegex)];
528
- matches.forEach(match => {
529
- const name = match[1] || match[2] || match[3] || match[4];
530
- if (name) exports.push(name);
531
- });
532
-
533
- return exports;
534
- }
535
-
536
- /**
537
- * Estimate function length (simplified)
538
- */
539
- estimateFunctionLength(lines, startIndex) {
540
- let braceCount = 0;
541
- let lineCount = 0;
542
- let inFunction = false;
543
-
544
- for (let i = startIndex; i < lines.length; i++) {
545
- const line = lines[i];
546
- lineCount++;
547
-
548
- // Count braces to find function end
549
- for (const char of line) {
550
- if (char === '{') {
551
- braceCount++;
552
- inFunction = true;
553
- } else if (char === '}') {
554
- braceCount--;
555
- if (inFunction && braceCount === 0) {
556
- return lineCount;
557
- }
558
- }
559
- }
560
-
561
- // Safety limit
562
- if (lineCount > 200) break;
563
- }
564
-
565
- return lineCount;
566
- }
567
-
568
- /**
569
- * Estimate cyclomatic complexity (simplified)
570
- */
571
- estimateComplexity(lines, startIndex) {
572
- let complexity = 1; // Base complexity
573
- const complexityKeywords = ['if', 'else', 'while', 'for', 'switch', 'case', 'catch', '&&', '||', '?'];
574
-
575
- const functionLines = lines.slice(startIndex, startIndex + this.estimateFunctionLength(lines, startIndex));
576
-
577
- functionLines.forEach(line => {
578
- complexityKeywords.forEach(keyword => {
579
- const matches = line.match(new RegExp(`\\b${keyword}\\b`, 'g'));
580
- if (matches) {
581
- complexity += matches.length;
582
- }
583
- });
584
- });
585
-
586
- return complexity;
587
- }
588
-
589
- /**
590
- * Estimate nesting depth (simplified)
591
- */
592
- estimateNestingDepth(lines, startIndex) {
593
- let maxDepth = 0;
594
- let currentDepth = 0;
595
-
596
- const functionLines = lines.slice(startIndex, startIndex + this.estimateFunctionLength(lines, startIndex));
597
-
598
- functionLines.forEach(line => {
599
- for (const char of line) {
600
- if (char === '{') {
601
- currentDepth++;
602
- maxDepth = Math.max(maxDepth, currentDepth);
603
- } else if (char === '}') {
604
- currentDepth--;
605
- }
606
- }
607
- });
608
-
609
- return maxDepth;
610
- }
611
-
612
- /**
613
- * Calculate overall performance score
614
- */
615
- calculateOverallScore(analysis) {
616
- let score = 10;
617
- const penalties = {
618
- critical: 2,
619
- high: 1,
620
- medium: 0.5,
621
- low: 0.1
622
- };
623
-
624
- // Apply penalties based on issue severity
625
- [...analysis.bottlenecks, ...analysis.memory_issues, ...analysis.async_opportunities,
626
- ...analysis.code_quality_issues, ...analysis.file_size_issues, ...analysis.complexity_issues]
627
- .forEach(issue => {
628
- score -= penalties[issue.severity] || 0.1;
629
- });
630
-
631
- return Math.max(0, Math.round(score * 10) / 10);
632
- }
633
-
634
- /**
635
- * Count total issues
636
- */
637
- countTotalIssues(analysis) {
638
- return analysis.bottlenecks.length +
639
- analysis.memory_issues.length +
640
- analysis.async_opportunities.length +
641
- analysis.code_quality_issues.length +
642
- analysis.file_size_issues.length +
643
- analysis.complexity_issues.length;
644
- }
645
-
646
- /**
647
- * Calculate issue priorities
648
- */
649
- calculateIssuePriorities(analysis) {
650
- const metrics = analysis.metrics;
651
- const allIssues = [
652
- ...analysis.bottlenecks,
653
- ...analysis.memory_issues,
654
- ...analysis.async_opportunities,
655
- ...analysis.code_quality_issues,
656
- ...analysis.file_size_issues,
657
- ...analysis.complexity_issues
658
- ];
659
-
660
- metrics.critical_issues = allIssues.filter(i => i.severity === 'critical').length;
661
- metrics.high_priority_issues = allIssues.filter(i => i.severity === 'high').length;
662
- metrics.medium_priority_issues = allIssues.filter(i => i.severity === 'medium').length;
663
- metrics.low_priority_issues = allIssues.filter(i => i.severity === 'low').length;
664
-
665
- return metrics;
666
- }
667
-
668
- /**
669
- * Generate performance recommendations
670
- */
671
- generatePerformanceRecommendations(analysis) {
672
- const recommendations = [];
673
-
674
- // Critical issues
675
- if (analysis.metrics.critical_issues > 0) {
676
- recommendations.push({
677
- priority: 'critical',
678
- category: 'immediate_action',
679
- message: `${analysis.metrics.critical_issues} critical performance issues require immediate attention`,
680
- action: 'Fix critical bottlenecks before deployment'
681
- });
682
- }
683
-
684
- // High severity issues
685
- if (analysis.metrics.high_priority_issues > 5) {
686
- recommendations.push({
687
- priority: 'high',
688
- category: 'performance',
689
- message: `${analysis.metrics.high_priority_issues} high-priority performance issues detected`,
690
- action: 'Address synchronous operations and complexity issues'
691
- });
692
- }
693
-
694
- // Memory issues
695
- if (analysis.memory_issues.length > 0) {
696
- recommendations.push({
697
- priority: 'medium',
698
- category: 'memory',
699
- message: `${analysis.memory_issues.length} memory optimization opportunities found`,
700
- action: 'Implement memory-efficient patterns and data structures'
701
- });
702
- }
703
-
704
- // File size issues
705
- if (analysis.file_size_issues.length > 0) {
706
- recommendations.push({
707
- priority: 'medium',
708
- category: 'modularity',
709
- message: `${analysis.file_size_issues.length} files are too large`,
710
- action: 'Break down large files into smaller, focused modules'
711
- });
712
- }
713
-
714
- // Overall score
715
- if (analysis.overall_score < 7) {
716
- recommendations.push({
717
- priority: 'high',
718
- category: 'general',
719
- message: `Overall performance score is ${analysis.overall_score}/10`,
720
- action: 'Comprehensive performance review and optimization needed'
721
- });
722
- }
723
-
724
- return recommendations;
725
- }
726
-
727
- /**
728
- * Check if component should be analyzed
729
- */
730
- shouldAnalyzeComponent(component) {
731
- const analyzableTypes = ['utility', 'task'];
732
- const analyzableExtensions = ['.js', '.mjs', '.ts'];
733
-
734
- if (!analyzableTypes.includes(component.type)) {
735
- return false;
736
- }
737
-
738
- if (component.file_path) {
739
- const ext = path.extname(component.file_path).toLowerCase();
740
- return analyzableExtensions.includes(ext);
741
- }
742
-
743
- return false;
744
- }
745
-
746
- /**
747
- * Format bytes for display
748
- */
749
- formatBytes(bytes) {
750
- if (bytes === 0) return '0 B';
751
- const k = 1024;
752
- const sizes = ['B', 'KB', 'MB', 'GB'];
753
- const i = Math.floor(Math.log(bytes) / Math.log(k));
754
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
755
- }
756
- }
757
-
1
+ const fs = require('fs').promises;
2
+ const path = require('path');
3
+ const chalk = require('chalk');
4
+
5
+ /**
6
+ * Performance bottleneck analyzer for AIOS-FULLSTACK framework
7
+ * Identifies performance issues and optimization opportunities
8
+ */
9
+ class PerformanceAnalyzer {
10
+ constructor(options = {}) {
11
+ this.rootPath = options.rootPath || process.cwd();
12
+ this.thresholds = {
13
+ fileSize: 50 * 1024, // 50KB
14
+ functionLength: 50, // lines
15
+ cyclomaticComplexity: 10,
16
+ nestingDepth: 5,
17
+ importCount: 20,
18
+ unusedCode: 0.1 // 10% unused code ratio
19
+ };
20
+ this.performancePatterns = {
21
+ // Sync operations that should be async
22
+ syncOperations: [
23
+ /fs\.readFileSync/g,
24
+ /fs\.writeFileSync/g,
25
+ /fs\.existsSync/g,
26
+ /JSON\.parse\(\s*fs\.readFileSync/g
27
+ ],
28
+ // Memory-intensive patterns
29
+ memoryIssues: [
30
+ /\.map\(\s*.*\.map\(/g, // Nested maps
31
+ /new Array\(\d{4,}\)/g, // Large arrays
32
+ /JSON\.stringify.*JSON\.parse/g, // Unnecessary serialization
33
+ /require\(\s*['"`][^'"`]+\.json['"`]\s*\)/g // Large JSON imports
34
+ ],
35
+ // Performance anti-patterns
36
+ antiPatterns: [
37
+ /console\.log/g, // Console logs in production
38
+ /debugger/g, // Debugger statements
39
+ /setTimeout\(\s*.*,\s*0\s*\)/g, // Unnecessary setTimeout
40
+ /setInterval\(\s*.*,\s*[0-9]{1,2}\s*\)/g // High-frequency intervals
41
+ ],
42
+ // Inefficient loops
43
+ inefficientLoops: [
44
+ /for\s*\(\s*.*\.length\s*;/g, // Length calculated in loop condition
45
+ /while\s*\(\s*true\s*\)/g, // Infinite loops
46
+ /forEach.*forEach/g // Nested forEach
47
+ ]
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Analyze performance across all components
53
+ */
54
+ async analyzePerformance(components) {
55
+ const analysis = {
56
+ timestamp: new Date().toISOString(),
57
+ overall_score: 0,
58
+ bottlenecks: [],
59
+ optimization_opportunities: [],
60
+ memory_issues: [],
61
+ async_opportunities: [],
62
+ code_quality_issues: [],
63
+ file_size_issues: [],
64
+ complexity_issues: [],
65
+ recommendations: [],
66
+ metrics: {
67
+ total_files_analyzed: 0,
68
+ total_issues_found: 0,
69
+ critical_issues: 0,
70
+ high_priority_issues: 0,
71
+ medium_priority_issues: 0,
72
+ low_priority_issues: 0
73
+ }
74
+ };
75
+
76
+ try {
77
+ console.log(chalk.blue('🔍 Analyzing performance bottlenecks...'));
78
+
79
+ // Analyze each component
80
+ for (const component of components) {
81
+ const componentAnalysis = await this.analyzeComponentPerformance(component);
82
+
83
+ // Aggregate results
84
+ analysis.bottlenecks.push(...componentAnalysis.bottlenecks);
85
+ analysis.optimization_opportunities.push(...componentAnalysis.optimizations);
86
+ analysis.memory_issues.push(...componentAnalysis.memory_issues);
87
+ analysis.async_opportunities.push(...componentAnalysis.async_opportunities);
88
+ analysis.code_quality_issues.push(...componentAnalysis.quality_issues);
89
+ analysis.file_size_issues.push(...componentAnalysis.file_size_issues);
90
+ analysis.complexity_issues.push(...componentAnalysis.complexity_issues);
91
+
92
+ analysis.metrics.total_files_analyzed++;
93
+ }
94
+
95
+ // Calculate overall metrics
96
+ analysis.overall_score = this.calculateOverallScore(analysis);
97
+ analysis.metrics.total_issues_found = this.countTotalIssues(analysis);
98
+ analysis.metrics = this.calculateIssuePriorities(analysis);
99
+ analysis.recommendations = this.generatePerformanceRecommendations(analysis);
100
+
101
+ console.log(chalk.green(`✅ Performance analysis completed`));
102
+ console.log(chalk.gray(` Files analyzed: ${analysis.metrics.total_files_analyzed}`));
103
+ console.log(chalk.gray(` Issues found: ${analysis.metrics.total_issues_found}`));
104
+ console.log(chalk.gray(` Overall score: ${analysis.overall_score}/10`));
105
+
106
+ return analysis;
107
+
108
+ } catch (error) {
109
+ console.error(chalk.red(`Performance analysis failed: ${error.message}`));
110
+ throw error;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Analyze performance for a single component
116
+ */
117
+ async analyzeComponentPerformance(component) {
118
+ const analysis = {
119
+ component_id: component.id,
120
+ component_type: component.type,
121
+ bottlenecks: [],
122
+ optimizations: [],
123
+ memory_issues: [],
124
+ async_opportunities: [],
125
+ quality_issues: [],
126
+ file_size_issues: [],
127
+ complexity_issues: []
128
+ };
129
+
130
+ try {
131
+ // Only analyze JavaScript files and executable components
132
+ if (!this.shouldAnalyzeComponent(component)) {
133
+ return analysis;
134
+ }
135
+
136
+ const filePath = path.join(this.rootPath, component.file_path);
137
+ const content = await fs.readFile(filePath, 'utf-8');
138
+ const stats = await fs.stat(filePath);
139
+
140
+ // File size analysis
141
+ if (stats.size > this.thresholds.fileSize) {
142
+ analysis.file_size_issues.push({
143
+ component: component.id,
144
+ issue: `Large file size: ${this.formatBytes(stats.size)}`,
145
+ severity: stats.size > this.thresholds.fileSize * 2 ? 'high' : 'medium',
146
+ recommendation: 'Consider breaking down into smaller modules',
147
+ impact: 'high',
148
+ effort: 'medium'
149
+ });
150
+ }
151
+
152
+ // Synchronous operations analysis
153
+ const syncIssues = this.findSyncOperations(content, component);
154
+ analysis.async_opportunities.push(...syncIssues);
155
+
156
+ // Memory usage analysis
157
+ const memoryIssues = this.findMemoryIssues(content, component);
158
+ analysis.memory_issues.push(...memoryIssues);
159
+
160
+ // Performance anti-patterns
161
+ const antiPatterns = this.findAntiPatterns(content, component);
162
+ analysis.quality_issues.push(...antiPatterns);
163
+
164
+ // Loop efficiency analysis
165
+ const loopIssues = this.findLoopIssues(content, component);
166
+ analysis.bottlenecks.push(...loopIssues);
167
+
168
+ // Function complexity analysis
169
+ const complexityIssues = this.analyzeComplexity(content, component);
170
+ analysis.complexity_issues.push(...complexityIssues);
171
+
172
+ // Import/require analysis
173
+ const importIssues = this.analyzeImports(content, component);
174
+ analysis.optimizations.push(...importIssues);
175
+
176
+ // Dead code analysis
177
+ const deadCodeIssues = await this.findDeadCode(content, component);
178
+ analysis.optimizations.push(...deadCodeIssues);
179
+
180
+ } catch (error) {
181
+ console.warn(chalk.yellow(`Failed to analyze performance for ${component.id}: ${error.message}`));
182
+ }
183
+
184
+ return analysis;
185
+ }
186
+
187
+ /**
188
+ * Find synchronous operations that should be async
189
+ */
190
+ findSyncOperations(content, component) {
191
+ const issues = [];
192
+ const lines = content.split('\n');
193
+
194
+ this.performancePatterns.syncOperations.forEach(pattern => {
195
+ lines.forEach((line, index) => {
196
+ const matches = line.match(pattern);
197
+ if (matches) {
198
+ matches.forEach(match => {
199
+ issues.push({
200
+ component: component.id,
201
+ issue: `Synchronous operation: ${match}`,
202
+ line: index + 1,
203
+ context: line.trim(),
204
+ severity: 'high',
205
+ recommendation: 'Convert to async equivalent',
206
+ impact: 'high',
207
+ effort: 'low'
208
+ });
209
+ });
210
+ }
211
+ });
212
+ });
213
+
214
+ return issues;
215
+ }
216
+
217
+ /**
218
+ * Find memory-intensive patterns
219
+ */
220
+ findMemoryIssues(content, component) {
221
+ const issues = [];
222
+ const lines = content.split('\n');
223
+
224
+ this.performancePatterns.memoryIssues.forEach(pattern => {
225
+ lines.forEach((line, index) => {
226
+ const matches = line.match(pattern);
227
+ if (matches) {
228
+ matches.forEach(match => {
229
+ let severity = 'medium';
230
+ let recommendation = 'Optimize memory usage';
231
+
232
+ if (match.includes('new Array')) {
233
+ severity = 'high';
234
+ recommendation = 'Use array literals or streaming for large datasets';
235
+ } else if (match.includes('JSON.stringify.*JSON.parse')) {
236
+ recommendation = 'Use direct object assignment or deep clone utilities';
237
+ } else if (match.includes('.map(.*map(')) {
238
+ recommendation = 'Combine operations or use more efficient iteration';
239
+ }
240
+
241
+ issues.push({
242
+ component: component.id,
243
+ issue: `Memory-intensive pattern: ${match}`,
244
+ line: index + 1,
245
+ context: line.trim(),
246
+ severity,
247
+ recommendation,
248
+ impact: 'medium',
249
+ effort: 'medium'
250
+ });
251
+ });
252
+ }
253
+ });
254
+ });
255
+
256
+ return issues;
257
+ }
258
+
259
+ /**
260
+ * Find performance anti-patterns
261
+ */
262
+ findAntiPatterns(content, component) {
263
+ const issues = [];
264
+ const lines = content.split('\n');
265
+
266
+ this.performancePatterns.antiPatterns.forEach(pattern => {
267
+ lines.forEach((line, index) => {
268
+ const matches = line.match(pattern);
269
+ if (matches) {
270
+ matches.forEach(match => {
271
+ let severity = 'low';
272
+ let recommendation = 'Remove or optimize';
273
+
274
+ if (match.includes('console.log')) {
275
+ recommendation = 'Remove console.log statements from production code';
276
+ } else if (match.includes('debugger')) {
277
+ severity = 'medium';
278
+ recommendation = 'Remove debugger statements';
279
+ } else if (match.includes('setTimeout')) {
280
+ recommendation = 'Use proper async/await or promises instead';
281
+ }
282
+
283
+ issues.push({
284
+ component: component.id,
285
+ issue: `Performance anti-pattern: ${match}`,
286
+ line: index + 1,
287
+ context: line.trim(),
288
+ severity,
289
+ recommendation,
290
+ impact: 'low',
291
+ effort: 'low'
292
+ });
293
+ });
294
+ }
295
+ });
296
+ });
297
+
298
+ return issues;
299
+ }
300
+
301
+ /**
302
+ * Find inefficient loop patterns
303
+ */
304
+ findLoopIssues(content, component) {
305
+ const issues = [];
306
+ const lines = content.split('\n');
307
+
308
+ this.performancePatterns.inefficientLoops.forEach(pattern => {
309
+ lines.forEach((line, index) => {
310
+ const matches = line.match(pattern);
311
+ if (matches) {
312
+ matches.forEach(match => {
313
+ let severity = 'medium';
314
+ let recommendation = 'Optimize loop structure';
315
+
316
+ if (match.includes('.length')) {
317
+ recommendation = 'Cache array length in variable before loop';
318
+ } else if (match.includes('while(true)')) {
319
+ severity = 'high';
320
+ recommendation = 'Add proper exit condition to prevent infinite loops';
321
+ } else if (match.includes('forEach.*forEach')) {
322
+ recommendation = 'Consider using nested for loops or array methods like flatMap';
323
+ }
324
+
325
+ issues.push({
326
+ component: component.id,
327
+ issue: `Inefficient loop: ${match}`,
328
+ line: index + 1,
329
+ context: line.trim(),
330
+ severity,
331
+ recommendation,
332
+ impact: 'medium',
333
+ effort: 'low'
334
+ });
335
+ });
336
+ }
337
+ });
338
+ });
339
+
340
+ return issues;
341
+ }
342
+
343
+ /**
344
+ * Analyze function complexity
345
+ */
346
+ analyzeComplexity(content, component) {
347
+ const issues = [];
348
+ const functions = this.extractFunctions(content);
349
+
350
+ functions.forEach(func => {
351
+ // Check function length
352
+ if (func.lines > this.thresholds.functionLength) {
353
+ issues.push({
354
+ component: component.id,
355
+ issue: `Long function: ${func.name} (${func.lines} lines)`,
356
+ line: func.startLine,
357
+ severity: func.lines > this.thresholds.functionLength * 2 ? 'high' : 'medium',
358
+ recommendation: 'Break down into smaller functions',
359
+ impact: 'medium',
360
+ effort: 'medium'
361
+ });
362
+ }
363
+
364
+ // Check cyclomatic complexity
365
+ if (func.complexity > this.thresholds.cyclomaticComplexity) {
366
+ issues.push({
367
+ component: component.id,
368
+ issue: `High complexity: ${func.name} (complexity: ${func.complexity})`,
369
+ line: func.startLine,
370
+ severity: func.complexity > this.thresholds.cyclomaticComplexity * 1.5 ? 'high' : 'medium',
371
+ recommendation: 'Reduce conditional complexity',
372
+ impact: 'high',
373
+ effort: 'high'
374
+ });
375
+ }
376
+
377
+ // Check nesting depth
378
+ if (func.nestingDepth > this.thresholds.nestingDepth) {
379
+ issues.push({
380
+ component: component.id,
381
+ issue: `Deep nesting: ${func.name} (depth: ${func.nestingDepth})`,
382
+ line: func.startLine,
383
+ severity: 'medium',
384
+ recommendation: 'Reduce nesting depth using early returns or guard clauses',
385
+ impact: 'medium',
386
+ effort: 'medium'
387
+ });
388
+ }
389
+ });
390
+
391
+ return issues;
392
+ }
393
+
394
+ /**
395
+ * Analyze imports and requires
396
+ */
397
+ analyzeImports(content, component) {
398
+ const issues = [];
399
+ const imports = this.extractImports(content);
400
+
401
+ if (imports.length > this.thresholds.importCount) {
402
+ issues.push({
403
+ component: component.id,
404
+ issue: `Too many imports: ${imports.length}`,
405
+ severity: 'medium',
406
+ recommendation: 'Consider breaking down module or using dynamic imports',
407
+ impact: 'low',
408
+ effort: 'medium'
409
+ });
410
+ }
411
+
412
+ // Find unused imports (basic heuristic)
413
+ const unusedImports = imports.filter(imp => {
414
+ const usage = content.split(imp.name).length - 1;
415
+ return usage <= 1; // Only appears in import statement
416
+ });
417
+
418
+ if (unusedImports.length > 0) {
419
+ issues.push({
420
+ component: component.id,
421
+ issue: `Unused imports: ${unusedImports.map(i => i.name).join(', ')}`,
422
+ severity: 'low',
423
+ recommendation: 'Remove unused imports',
424
+ impact: 'low',
425
+ effort: 'low'
426
+ });
427
+ }
428
+
429
+ return issues;
430
+ }
431
+
432
+ /**
433
+ * Find dead code (unused functions, variables)
434
+ */
435
+ async findDeadCode(content, component) {
436
+ const issues = [];
437
+
438
+ // This is a simplified implementation
439
+ // A full implementation would analyze the entire codebase for usage
440
+ const functions = this.extractFunctions(content);
441
+ const exports = this.extractExports(content);
442
+
443
+ // Check for functions that are defined but never called within the file
444
+ functions.forEach(func => {
445
+ if (!func.name.startsWith('_') && !exports.includes(func.name)) {
446
+ const usage = content.split(func.name).length - 1;
447
+ if (usage <= 1) { // Only appears in definition
448
+ issues.push({
449
+ component: component.id,
450
+ issue: `Potentially unused function: ${func.name}`,
451
+ line: func.startLine,
452
+ severity: 'low',
453
+ recommendation: 'Remove if truly unused or export if needed elsewhere',
454
+ impact: 'low',
455
+ effort: 'low'
456
+ });
457
+ }
458
+ }
459
+ });
460
+
461
+ return issues;
462
+ }
463
+
464
+ /**
465
+ * Extract function information from code
466
+ */
467
+ extractFunctions(content) {
468
+ const functions = [];
469
+ const lines = content.split('\n');
470
+ const functionRegex = /(?:function\s+(\w+)|(\w+)\s*[:=]\s*(?:async\s+)?function|(?:async\s+)?(\w+)\s*\([^)]*\)\s*(?:=>|{))/g;
471
+
472
+ lines.forEach((line, index) => {
473
+ const matches = [...line.matchAll(functionRegex)];
474
+ matches.forEach(match => {
475
+ const name = match[1] || match[2] || match[3] || 'anonymous';
476
+
477
+ // Calculate function metrics (simplified)
478
+ const funcInfo = {
479
+ name,
480
+ startLine: index + 1,
481
+ lines: this.estimateFunctionLength(lines, index),
482
+ complexity: this.estimateComplexity(lines, index),
483
+ nestingDepth: this.estimateNestingDepth(lines, index)
484
+ };
485
+
486
+ functions.push(funcInfo);
487
+ });
488
+ });
489
+
490
+ return functions;
491
+ }
492
+
493
+ /**
494
+ * Extract import information
495
+ */
496
+ extractImports(content) {
497
+ const imports = [];
498
+ const importRegex = /(?:import\s+(?:(\w+)|\{([^}]+)\}|.*)\s+from\s+['"`]([^'"`]+)['"`]|const\s+(?:(\w+)|\{([^}]+)\})\s*=\s*require\(['"`]([^'"`]+)['"`]\))/g;
499
+
500
+ const matches = [...content.matchAll(importRegex)];
501
+ matches.forEach(match => {
502
+ const defaultImport = match[1] || match[4];
503
+ const namedImports = match[2] || match[5];
504
+ const source = match[3] || match[6];
505
+
506
+ if (defaultImport) {
507
+ imports.push({ name: defaultImport, source, type: 'default' });
508
+ }
509
+
510
+ if (namedImports) {
511
+ namedImports.split(',').forEach(name => {
512
+ imports.push({ name: name.trim(), source, type: 'named' });
513
+ });
514
+ }
515
+ });
516
+
517
+ return imports;
518
+ }
519
+
520
+ /**
521
+ * Extract export information
522
+ */
523
+ extractExports(content) {
524
+ const exports = [];
525
+ const exportRegex = /(?:export\s+(?:default\s+)?(?:function\s+(\w+)|class\s+(\w+)|(?:const|let|var)\s+(\w+))|module\.exports\s*=\s*(\w+))/g;
526
+
527
+ const matches = [...content.matchAll(exportRegex)];
528
+ matches.forEach(match => {
529
+ const name = match[1] || match[2] || match[3] || match[4];
530
+ if (name) exports.push(name);
531
+ });
532
+
533
+ return exports;
534
+ }
535
+
536
+ /**
537
+ * Estimate function length (simplified)
538
+ */
539
+ estimateFunctionLength(lines, startIndex) {
540
+ let braceCount = 0;
541
+ let lineCount = 0;
542
+ let inFunction = false;
543
+
544
+ for (let i = startIndex; i < lines.length; i++) {
545
+ const line = lines[i];
546
+ lineCount++;
547
+
548
+ // Count braces to find function end
549
+ for (const char of line) {
550
+ if (char === '{') {
551
+ braceCount++;
552
+ inFunction = true;
553
+ } else if (char === '}') {
554
+ braceCount--;
555
+ if (inFunction && braceCount === 0) {
556
+ return lineCount;
557
+ }
558
+ }
559
+ }
560
+
561
+ // Safety limit
562
+ if (lineCount > 200) break;
563
+ }
564
+
565
+ return lineCount;
566
+ }
567
+
568
+ /**
569
+ * Estimate cyclomatic complexity (simplified)
570
+ */
571
+ estimateComplexity(lines, startIndex) {
572
+ let complexity = 1; // Base complexity
573
+ const complexityKeywords = ['if', 'else', 'while', 'for', 'switch', 'case', 'catch', '&&', '||', '?'];
574
+
575
+ const functionLines = lines.slice(startIndex, startIndex + this.estimateFunctionLength(lines, startIndex));
576
+
577
+ functionLines.forEach(line => {
578
+ complexityKeywords.forEach(keyword => {
579
+ const matches = line.match(new RegExp(`\\b${keyword}\\b`, 'g'));
580
+ if (matches) {
581
+ complexity += matches.length;
582
+ }
583
+ });
584
+ });
585
+
586
+ return complexity;
587
+ }
588
+
589
+ /**
590
+ * Estimate nesting depth (simplified)
591
+ */
592
+ estimateNestingDepth(lines, startIndex) {
593
+ let maxDepth = 0;
594
+ let currentDepth = 0;
595
+
596
+ const functionLines = lines.slice(startIndex, startIndex + this.estimateFunctionLength(lines, startIndex));
597
+
598
+ functionLines.forEach(line => {
599
+ for (const char of line) {
600
+ if (char === '{') {
601
+ currentDepth++;
602
+ maxDepth = Math.max(maxDepth, currentDepth);
603
+ } else if (char === '}') {
604
+ currentDepth--;
605
+ }
606
+ }
607
+ });
608
+
609
+ return maxDepth;
610
+ }
611
+
612
+ /**
613
+ * Calculate overall performance score
614
+ */
615
+ calculateOverallScore(analysis) {
616
+ let score = 10;
617
+ const penalties = {
618
+ critical: 2,
619
+ high: 1,
620
+ medium: 0.5,
621
+ low: 0.1
622
+ };
623
+
624
+ // Apply penalties based on issue severity
625
+ [...analysis.bottlenecks, ...analysis.memory_issues, ...analysis.async_opportunities,
626
+ ...analysis.code_quality_issues, ...analysis.file_size_issues, ...analysis.complexity_issues]
627
+ .forEach(issue => {
628
+ score -= penalties[issue.severity] || 0.1;
629
+ });
630
+
631
+ return Math.max(0, Math.round(score * 10) / 10);
632
+ }
633
+
634
+ /**
635
+ * Count total issues
636
+ */
637
+ countTotalIssues(analysis) {
638
+ return analysis.bottlenecks.length +
639
+ analysis.memory_issues.length +
640
+ analysis.async_opportunities.length +
641
+ analysis.code_quality_issues.length +
642
+ analysis.file_size_issues.length +
643
+ analysis.complexity_issues.length;
644
+ }
645
+
646
+ /**
647
+ * Calculate issue priorities
648
+ */
649
+ calculateIssuePriorities(analysis) {
650
+ const metrics = analysis.metrics;
651
+ const allIssues = [
652
+ ...analysis.bottlenecks,
653
+ ...analysis.memory_issues,
654
+ ...analysis.async_opportunities,
655
+ ...analysis.code_quality_issues,
656
+ ...analysis.file_size_issues,
657
+ ...analysis.complexity_issues
658
+ ];
659
+
660
+ metrics.critical_issues = allIssues.filter(i => i.severity === 'critical').length;
661
+ metrics.high_priority_issues = allIssues.filter(i => i.severity === 'high').length;
662
+ metrics.medium_priority_issues = allIssues.filter(i => i.severity === 'medium').length;
663
+ metrics.low_priority_issues = allIssues.filter(i => i.severity === 'low').length;
664
+
665
+ return metrics;
666
+ }
667
+
668
+ /**
669
+ * Generate performance recommendations
670
+ */
671
+ generatePerformanceRecommendations(analysis) {
672
+ const recommendations = [];
673
+
674
+ // Critical issues
675
+ if (analysis.metrics.critical_issues > 0) {
676
+ recommendations.push({
677
+ priority: 'critical',
678
+ category: 'immediate_action',
679
+ message: `${analysis.metrics.critical_issues} critical performance issues require immediate attention`,
680
+ action: 'Fix critical bottlenecks before deployment'
681
+ });
682
+ }
683
+
684
+ // High severity issues
685
+ if (analysis.metrics.high_priority_issues > 5) {
686
+ recommendations.push({
687
+ priority: 'high',
688
+ category: 'performance',
689
+ message: `${analysis.metrics.high_priority_issues} high-priority performance issues detected`,
690
+ action: 'Address synchronous operations and complexity issues'
691
+ });
692
+ }
693
+
694
+ // Memory issues
695
+ if (analysis.memory_issues.length > 0) {
696
+ recommendations.push({
697
+ priority: 'medium',
698
+ category: 'memory',
699
+ message: `${analysis.memory_issues.length} memory optimization opportunities found`,
700
+ action: 'Implement memory-efficient patterns and data structures'
701
+ });
702
+ }
703
+
704
+ // File size issues
705
+ if (analysis.file_size_issues.length > 0) {
706
+ recommendations.push({
707
+ priority: 'medium',
708
+ category: 'modularity',
709
+ message: `${analysis.file_size_issues.length} files are too large`,
710
+ action: 'Break down large files into smaller, focused modules'
711
+ });
712
+ }
713
+
714
+ // Overall score
715
+ if (analysis.overall_score < 7) {
716
+ recommendations.push({
717
+ priority: 'high',
718
+ category: 'general',
719
+ message: `Overall performance score is ${analysis.overall_score}/10`,
720
+ action: 'Comprehensive performance review and optimization needed'
721
+ });
722
+ }
723
+
724
+ return recommendations;
725
+ }
726
+
727
+ /**
728
+ * Check if component should be analyzed
729
+ */
730
+ shouldAnalyzeComponent(component) {
731
+ const analyzableTypes = ['utility', 'task'];
732
+ const analyzableExtensions = ['.js', '.mjs', '.ts'];
733
+
734
+ if (!analyzableTypes.includes(component.type)) {
735
+ return false;
736
+ }
737
+
738
+ if (component.file_path) {
739
+ const ext = path.extname(component.file_path).toLowerCase();
740
+ return analyzableExtensions.includes(ext);
741
+ }
742
+
743
+ return false;
744
+ }
745
+
746
+ /**
747
+ * Format bytes for display
748
+ */
749
+ formatBytes(bytes) {
750
+ if (bytes === 0) return '0 B';
751
+ const k = 1024;
752
+ const sizes = ['B', 'KB', 'MB', 'GB'];
753
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
754
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
755
+ }
756
+ }
757
+
758
758
  module.exports = PerformanceAnalyzer;