musubi-sdd 5.0.0 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.ja.md +106 -48
  2. package/README.md +110 -32
  3. package/bin/musubi-analyze.js +74 -67
  4. package/bin/musubi-browser.js +27 -26
  5. package/bin/musubi-change.js +48 -47
  6. package/bin/musubi-checkpoint.js +10 -7
  7. package/bin/musubi-convert.js +25 -25
  8. package/bin/musubi-costs.js +27 -10
  9. package/bin/musubi-gui.js +52 -46
  10. package/bin/musubi-init.js +1952 -10
  11. package/bin/musubi-orchestrate.js +327 -239
  12. package/bin/musubi-remember.js +69 -56
  13. package/bin/musubi-resolve.js +53 -45
  14. package/bin/musubi-trace.js +51 -22
  15. package/bin/musubi-validate.js +39 -30
  16. package/bin/musubi-workflow.js +33 -34
  17. package/bin/musubi.js +39 -2
  18. package/package.json +1 -1
  19. package/src/agents/agent-loop.js +94 -95
  20. package/src/agents/agentic/code-generator.js +119 -109
  21. package/src/agents/agentic/code-reviewer.js +105 -108
  22. package/src/agents/agentic/index.js +4 -4
  23. package/src/agents/browser/action-executor.js +13 -13
  24. package/src/agents/browser/ai-comparator.js +11 -10
  25. package/src/agents/browser/context-manager.js +6 -6
  26. package/src/agents/browser/index.js +5 -5
  27. package/src/agents/browser/nl-parser.js +31 -46
  28. package/src/agents/browser/screenshot.js +2 -2
  29. package/src/agents/browser/test-generator.js +6 -4
  30. package/src/agents/function-tool.js +71 -65
  31. package/src/agents/index.js +7 -7
  32. package/src/agents/schema-generator.js +98 -94
  33. package/src/analyzers/ast-extractor.js +164 -145
  34. package/src/analyzers/codegraph-auto-update.js +858 -0
  35. package/src/analyzers/complexity-analyzer.js +536 -0
  36. package/src/analyzers/context-optimizer.js +247 -125
  37. package/src/analyzers/impact-analyzer.js +1 -1
  38. package/src/analyzers/large-project-analyzer.js +766 -0
  39. package/src/analyzers/repository-map.js +83 -80
  40. package/src/analyzers/security-analyzer.js +19 -11
  41. package/src/analyzers/stuck-detector.js +19 -17
  42. package/src/converters/index.js +78 -57
  43. package/src/converters/ir/types.js +12 -12
  44. package/src/converters/parsers/musubi-parser.js +134 -126
  45. package/src/converters/parsers/openapi-parser.js +70 -53
  46. package/src/converters/parsers/speckit-parser.js +239 -175
  47. package/src/converters/writers/musubi-writer.js +123 -118
  48. package/src/converters/writers/speckit-writer.js +124 -113
  49. package/src/generators/rust-migration-generator.js +512 -0
  50. package/src/gui/public/index.html +1365 -1211
  51. package/src/gui/server.js +41 -40
  52. package/src/gui/services/file-watcher.js +23 -8
  53. package/src/gui/services/project-scanner.js +26 -20
  54. package/src/gui/services/replanning-service.js +27 -23
  55. package/src/gui/services/traceability-service.js +8 -8
  56. package/src/gui/services/workflow-service.js +14 -7
  57. package/src/index.js +151 -0
  58. package/src/integrations/cicd.js +90 -104
  59. package/src/integrations/codegraph-mcp.js +643 -0
  60. package/src/integrations/documentation.js +142 -103
  61. package/src/integrations/examples.js +95 -80
  62. package/src/integrations/github-client.js +17 -17
  63. package/src/integrations/index.js +5 -5
  64. package/src/integrations/mcp/index.js +21 -21
  65. package/src/integrations/mcp/mcp-context-provider.js +76 -78
  66. package/src/integrations/mcp/mcp-discovery.js +74 -72
  67. package/src/integrations/mcp/mcp-tool-registry.js +99 -94
  68. package/src/integrations/mcp-connector.js +70 -66
  69. package/src/integrations/platforms.js +50 -49
  70. package/src/integrations/tool-discovery.js +37 -31
  71. package/src/llm-providers/anthropic-provider.js +11 -11
  72. package/src/llm-providers/base-provider.js +16 -18
  73. package/src/llm-providers/copilot-provider.js +22 -19
  74. package/src/llm-providers/index.js +26 -25
  75. package/src/llm-providers/ollama-provider.js +11 -11
  76. package/src/llm-providers/openai-provider.js +12 -12
  77. package/src/managers/agent-memory.js +36 -24
  78. package/src/managers/checkpoint-manager.js +4 -8
  79. package/src/managers/delta-spec.js +19 -19
  80. package/src/managers/index.js +13 -4
  81. package/src/managers/memory-condenser.js +35 -45
  82. package/src/managers/repo-skill-manager.js +57 -31
  83. package/src/managers/skill-loader.js +25 -22
  84. package/src/managers/skill-tools.js +36 -72
  85. package/src/managers/workflow.js +30 -22
  86. package/src/monitoring/cost-tracker.js +53 -44
  87. package/src/monitoring/incident-manager.js +123 -103
  88. package/src/monitoring/index.js +144 -134
  89. package/src/monitoring/observability.js +82 -59
  90. package/src/monitoring/quality-dashboard.js +51 -39
  91. package/src/monitoring/release-manager.js +70 -50
  92. package/src/orchestration/agent-skill-binding.js +39 -47
  93. package/src/orchestration/error-handler.js +65 -107
  94. package/src/orchestration/guardrails/base-guardrail.js +26 -24
  95. package/src/orchestration/guardrails/guardrail-rules.js +50 -64
  96. package/src/orchestration/guardrails/index.js +5 -5
  97. package/src/orchestration/guardrails/input-guardrail.js +58 -45
  98. package/src/orchestration/guardrails/output-guardrail.js +104 -81
  99. package/src/orchestration/guardrails/safety-check.js +79 -79
  100. package/src/orchestration/index.js +38 -55
  101. package/src/orchestration/mcp-tool-adapters.js +96 -99
  102. package/src/orchestration/orchestration-engine.js +21 -21
  103. package/src/orchestration/pattern-registry.js +60 -45
  104. package/src/orchestration/patterns/auto.js +34 -47
  105. package/src/orchestration/patterns/group-chat.js +59 -65
  106. package/src/orchestration/patterns/handoff.js +67 -65
  107. package/src/orchestration/patterns/human-in-loop.js +51 -72
  108. package/src/orchestration/patterns/nested.js +25 -40
  109. package/src/orchestration/patterns/sequential.js +35 -34
  110. package/src/orchestration/patterns/swarm.js +63 -56
  111. package/src/orchestration/patterns/triage.js +150 -109
  112. package/src/orchestration/reasoning/index.js +9 -9
  113. package/src/orchestration/reasoning/planning-engine.js +143 -140
  114. package/src/orchestration/reasoning/reasoning-engine.js +206 -144
  115. package/src/orchestration/reasoning/self-correction.js +121 -128
  116. package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
  117. package/src/orchestration/replanning/alternative-generator.js +37 -42
  118. package/src/orchestration/replanning/config.js +63 -59
  119. package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
  120. package/src/orchestration/replanning/index.js +24 -20
  121. package/src/orchestration/replanning/plan-evaluator.js +49 -50
  122. package/src/orchestration/replanning/plan-monitor.js +32 -28
  123. package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
  124. package/src/orchestration/replanning/replan-history.js +33 -26
  125. package/src/orchestration/replanning/replanning-engine.js +106 -108
  126. package/src/orchestration/skill-executor.js +107 -109
  127. package/src/orchestration/skill-registry.js +85 -89
  128. package/src/orchestration/workflow-examples.js +228 -231
  129. package/src/orchestration/workflow-executor.js +65 -68
  130. package/src/orchestration/workflow-orchestrator.js +72 -73
  131. package/src/phase4-integration.js +47 -40
  132. package/src/phase5-integration.js +89 -30
  133. package/src/reporters/coverage-report.js +82 -30
  134. package/src/reporters/hierarchical-reporter.js +498 -0
  135. package/src/reporters/traceability-matrix-report.js +29 -20
  136. package/src/resolvers/issue-resolver.js +43 -31
  137. package/src/steering/advanced-validation.js +133 -124
  138. package/src/steering/auto-updater.js +60 -73
  139. package/src/steering/index.js +6 -6
  140. package/src/steering/quality-metrics.js +41 -35
  141. package/src/steering/steering-auto-update.js +83 -86
  142. package/src/steering/steering-validator.js +98 -106
  143. package/src/steering/template-constraints.js +53 -54
  144. package/src/templates/agents/claude-code/CLAUDE.md +32 -32
  145. package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
  146. package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
  147. package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
  148. package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
  149. package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
  150. package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
  151. package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
  152. package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
  153. package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
  154. package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
  155. package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
  156. package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
  157. package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
  158. package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
  159. package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
  160. package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
  161. package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
  162. package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
  163. package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
  164. package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
  165. package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
  166. package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
  167. package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
  168. package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
  169. package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
  170. package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
  171. package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
  172. package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
  173. package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
  174. package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
  175. package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
  176. package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
  177. package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
  178. package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
  179. package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
  180. package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
  181. package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
  182. package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
  183. package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
  184. package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
  185. package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
  186. package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
  187. package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
  188. package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
  189. package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
  190. package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
  191. package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
  192. package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
  193. package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
  194. package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
  195. package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
  196. package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
  197. package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
  198. package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
  199. package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
  200. package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
  201. package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
  202. package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
  203. package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
  204. package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
  205. package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
  206. package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
  207. package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
  208. package/src/templates/agents/codex/AGENTS.md +74 -42
  209. package/src/templates/agents/cursor/AGENTS.md +74 -42
  210. package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
  211. package/src/templates/agents/github-copilot/AGENTS.md +83 -51
  212. package/src/templates/agents/qwen-code/QWEN.md +74 -42
  213. package/src/templates/agents/windsurf/AGENTS.md +74 -42
  214. package/src/templates/architectures/README.md +41 -0
  215. package/src/templates/architectures/clean-architecture/README.md +113 -0
  216. package/src/templates/architectures/event-driven/README.md +162 -0
  217. package/src/templates/architectures/hexagonal/README.md +130 -0
  218. package/src/templates/index.js +6 -1
  219. package/src/templates/locale-manager.js +16 -16
  220. package/src/templates/shared/delta-spec-template.md +20 -13
  221. package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
  222. package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
  223. package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
  224. package/src/templates/shared/steering/structure.md +95 -0
  225. package/src/templates/skills/browser-agent.md +21 -16
  226. package/src/templates/skills/web-gui.md +8 -0
  227. package/src/templates/template-constraints.js +50 -53
  228. package/src/validators/advanced-validation.js +30 -36
  229. package/src/validators/constitutional-validator.js +77 -73
  230. package/src/validators/critic-system.js +49 -59
  231. package/src/validators/delta-format.js +59 -55
  232. package/src/validators/traceability-validator.js +7 -11
@@ -0,0 +1,766 @@
1
+ /**
2
+ * MUSUBI Large Project Analyzer
3
+ *
4
+ * Streaming analysis for large-scale projects (10,000+ files)
5
+ * Designed based on analysis of GCC codebase (1,000万+ lines)
6
+ *
7
+ * Features:
8
+ * - Chunk-based file processing
9
+ * - Memory-efficient streaming
10
+ * - Progress tracking
11
+ * - Parallel processing with worker threads
12
+ *
13
+ * @version 5.5.0
14
+ */
15
+
16
+ const fs = require('fs-extra');
17
+ const path = require('path');
18
+ const { glob } = require('glob');
19
+ // Worker threads reserved for future parallel processing
20
+ // const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
21
+ const os = require('os');
22
+
23
+ // ============================================================================
24
+ // Configuration
25
+ // ============================================================================
26
+
27
+ const THRESHOLDS = {
28
+ // File count thresholds
29
+ smallProject: 100,
30
+ mediumProject: 1000,
31
+ largeProject: 10000,
32
+ massiveProject: 100000,
33
+
34
+ // Function size thresholds (lines)
35
+ functionLines: {
36
+ warning: 100,
37
+ critical: 500,
38
+ extreme: 1000,
39
+ },
40
+
41
+ // Cyclomatic complexity thresholds
42
+ cyclomaticComplexity: {
43
+ warning: 10,
44
+ critical: 25,
45
+ extreme: 50,
46
+ },
47
+
48
+ // Dependency count thresholds
49
+ dependencies: {
50
+ warning: 10,
51
+ critical: 30,
52
+ extreme: 100,
53
+ },
54
+ };
55
+
56
+ const CHUNK_SIZE = {
57
+ small: 100,
58
+ medium: 500,
59
+ large: 1000,
60
+ streaming: 2000,
61
+ };
62
+
63
+ // ============================================================================
64
+ // Large Project Analyzer
65
+ // ============================================================================
66
+
67
+ class LargeProjectAnalyzer {
68
+ constructor(workspaceRoot, options = {}) {
69
+ this.workspaceRoot = workspaceRoot;
70
+ this.options = {
71
+ chunkSize: CHUNK_SIZE.large,
72
+ parallel: true,
73
+ workerCount: Math.max(1, os.cpus().length - 1),
74
+ progressCallback: null,
75
+ memoryLimit: 2 * 1024 * 1024 * 1024, // 2GB default
76
+ excludePatterns: [
77
+ 'node_modules/**',
78
+ 'dist/**',
79
+ 'build/**',
80
+ '.git/**',
81
+ 'coverage/**',
82
+ '*.min.js',
83
+ '*.bundle.js',
84
+ 'vendor/**',
85
+ 'third_party/**',
86
+ ],
87
+ ...options,
88
+ };
89
+
90
+ this.stats = {
91
+ totalFiles: 0,
92
+ processedFiles: 0,
93
+ skippedFiles: 0,
94
+ errorFiles: 0,
95
+ startTime: null,
96
+ endTime: null,
97
+ peakMemory: 0,
98
+ chunks: 0,
99
+ };
100
+
101
+ this.results = {
102
+ files: [],
103
+ giantFunctions: [],
104
+ hotspots: [],
105
+ summary: null,
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Analyze project with automatic scaling based on size
111
+ */
112
+ async analyze() {
113
+ this.stats.startTime = Date.now();
114
+
115
+ // Discover all files
116
+ const files = await this.discoverFiles();
117
+ this.stats.totalFiles = files.length;
118
+
119
+ // Determine project scale and strategy
120
+ const scale = this.determineScale(files.length);
121
+ console.log(`📊 Project scale: ${scale.name} (${files.length.toLocaleString()} files)`);
122
+
123
+ // Choose analysis strategy
124
+ let results;
125
+ switch (scale.strategy) {
126
+ case 'batch':
127
+ results = await this.batchAnalyze(files);
128
+ break;
129
+ case 'chunked':
130
+ results = await this.chunkedAnalyze(files);
131
+ break;
132
+ case 'streaming':
133
+ results = await this.streamingAnalyze(files);
134
+ break;
135
+ default:
136
+ results = await this.batchAnalyze(files);
137
+ }
138
+
139
+ this.stats.endTime = Date.now();
140
+ this.generateSummary(results);
141
+
142
+ return {
143
+ stats: this.stats,
144
+ results: this.results,
145
+ recommendations: this.generateRecommendations(),
146
+ };
147
+ }
148
+
149
+ /**
150
+ * Discover all analyzable files
151
+ */
152
+ async discoverFiles() {
153
+ const patterns = [
154
+ '**/*.js',
155
+ '**/*.ts',
156
+ '**/*.jsx',
157
+ '**/*.tsx',
158
+ '**/*.c',
159
+ '**/*.cpp',
160
+ '**/*.cc',
161
+ '**/*.h',
162
+ '**/*.hpp',
163
+ '**/*.py',
164
+ '**/*.rs',
165
+ '**/*.go',
166
+ '**/*.java',
167
+ ];
168
+
169
+ let allFiles = [];
170
+
171
+ for (const pattern of patterns) {
172
+ try {
173
+ const files = await glob(pattern, {
174
+ cwd: this.workspaceRoot,
175
+ ignore: this.options.excludePatterns,
176
+ nodir: true,
177
+ absolute: true,
178
+ });
179
+ allFiles = allFiles.concat(files);
180
+ } catch (error) {
181
+ console.warn(`Pattern ${pattern} failed: ${error.message}`);
182
+ }
183
+ }
184
+
185
+ return allFiles;
186
+ }
187
+
188
+ /**
189
+ * Determine project scale and analysis strategy
190
+ */
191
+ determineScale(fileCount) {
192
+ if (fileCount <= THRESHOLDS.smallProject) {
193
+ return {
194
+ name: 'Small',
195
+ strategy: 'batch',
196
+ chunkSize: CHUNK_SIZE.small,
197
+ };
198
+ }
199
+ if (fileCount <= THRESHOLDS.mediumProject) {
200
+ return {
201
+ name: 'Medium',
202
+ strategy: 'batch',
203
+ chunkSize: CHUNK_SIZE.medium,
204
+ };
205
+ }
206
+ if (fileCount <= THRESHOLDS.largeProject) {
207
+ return {
208
+ name: 'Large',
209
+ strategy: 'chunked',
210
+ chunkSize: CHUNK_SIZE.large,
211
+ };
212
+ }
213
+ return {
214
+ name: 'Massive',
215
+ strategy: 'streaming',
216
+ chunkSize: CHUNK_SIZE.streaming,
217
+ };
218
+ }
219
+
220
+ /**
221
+ * Batch analysis for small/medium projects
222
+ */
223
+ async batchAnalyze(files) {
224
+ const results = [];
225
+
226
+ for (const file of files) {
227
+ const analysis = await this.analyzeFile(file);
228
+ if (analysis) {
229
+ results.push(analysis);
230
+ }
231
+ this.stats.processedFiles++;
232
+ this.updateProgress();
233
+ }
234
+
235
+ return results;
236
+ }
237
+
238
+ /**
239
+ * Chunked analysis for large projects
240
+ */
241
+ async chunkedAnalyze(files) {
242
+ const chunkSize = this.options.chunkSize;
243
+ const results = [];
244
+
245
+ for (let i = 0; i < files.length; i += chunkSize) {
246
+ const chunk = files.slice(i, i + chunkSize);
247
+ this.stats.chunks++;
248
+
249
+ const chunkResults = await Promise.all(chunk.map(file => this.analyzeFile(file)));
250
+
251
+ results.push(...chunkResults.filter(r => r !== null));
252
+ this.stats.processedFiles += chunk.length;
253
+
254
+ // Memory management
255
+ this.checkMemory();
256
+ this.updateProgress();
257
+ }
258
+
259
+ return results;
260
+ }
261
+
262
+ /**
263
+ * Streaming analysis for massive projects
264
+ * Uses worker threads for parallel processing
265
+ */
266
+ async streamingAnalyze(files) {
267
+ const chunkSize = this.options.chunkSize;
268
+ const results = [];
269
+
270
+ console.log(
271
+ `🚀 Streaming mode: Processing ${files.length.toLocaleString()} files in chunks of ${chunkSize}`
272
+ );
273
+
274
+ for (let i = 0; i < files.length; i += chunkSize) {
275
+ const chunk = files.slice(i, i + chunkSize);
276
+ this.stats.chunks++;
277
+
278
+ // Process chunk with incremental aggregation
279
+ const chunkResults = await this.processChunk(chunk);
280
+
281
+ // Aggregate results incrementally to manage memory
282
+ this.aggregateResults(chunkResults);
283
+ this.stats.processedFiles += chunk.length;
284
+
285
+ // Force garbage collection if available
286
+ if (global.gc) {
287
+ global.gc();
288
+ }
289
+
290
+ this.checkMemory();
291
+ this.updateProgress();
292
+
293
+ // Log progress every 10 chunks
294
+ if (this.stats.chunks % 10 === 0) {
295
+ const percent = Math.round((this.stats.processedFiles / files.length) * 100);
296
+ const elapsed = ((Date.now() - this.stats.startTime) / 1000).toFixed(1);
297
+ console.log(` 📦 Chunk ${this.stats.chunks}: ${percent}% complete (${elapsed}s elapsed)`);
298
+ }
299
+ }
300
+
301
+ return results;
302
+ }
303
+
304
+ /**
305
+ * Process a chunk of files
306
+ */
307
+ async processChunk(files) {
308
+ const results = [];
309
+
310
+ for (const file of files) {
311
+ try {
312
+ const analysis = await this.analyzeFile(file);
313
+ if (analysis) {
314
+ results.push(analysis);
315
+ }
316
+ } catch (error) {
317
+ this.stats.errorFiles++;
318
+ }
319
+ }
320
+
321
+ return results;
322
+ }
323
+
324
+ /**
325
+ * Analyze a single file
326
+ */
327
+ async analyzeFile(filePath) {
328
+ try {
329
+ const content = await fs.readFile(filePath, 'utf8');
330
+ const stats = await fs.stat(filePath);
331
+ const lines = content.split('\n');
332
+ const language = this.detectLanguage(filePath);
333
+
334
+ const analysis = {
335
+ path: path.relative(this.workspaceRoot, filePath),
336
+ absolutePath: filePath,
337
+ language,
338
+ lines: lines.length,
339
+ size: stats.size,
340
+ complexity: this.calculateComplexity(content, language),
341
+ maintainability: 0,
342
+ functions: this.extractFunctions(content, language),
343
+ issues: [],
344
+ };
345
+
346
+ // Calculate maintainability
347
+ analysis.maintainability = this.calculateMaintainability(content, analysis.complexity);
348
+
349
+ // Detect issues
350
+ analysis.issues = this.detectIssues(analysis);
351
+
352
+ return analysis;
353
+ } catch (error) {
354
+ this.stats.errorFiles++;
355
+ return null;
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Detect programming language from file extension
361
+ */
362
+ detectLanguage(filePath) {
363
+ const ext = path.extname(filePath).toLowerCase();
364
+ const langMap = {
365
+ '.js': 'javascript',
366
+ '.ts': 'typescript',
367
+ '.jsx': 'javascript',
368
+ '.tsx': 'typescript',
369
+ '.c': 'c',
370
+ '.h': 'c',
371
+ '.cpp': 'cpp',
372
+ '.cc': 'cpp',
373
+ '.hpp': 'cpp',
374
+ '.py': 'python',
375
+ '.rs': 'rust',
376
+ '.go': 'go',
377
+ '.java': 'java',
378
+ };
379
+ return langMap[ext] || 'unknown';
380
+ }
381
+
382
+ /**
383
+ * Calculate cyclomatic complexity
384
+ */
385
+ calculateComplexity(code, language) {
386
+ let complexity = 1;
387
+
388
+ // Common decision point patterns
389
+ const patterns = [
390
+ /\bif\b/g,
391
+ /\belse\s+if\b/g,
392
+ /\bfor\b/g,
393
+ /\bwhile\b/g,
394
+ /\bcase\b/g,
395
+ /\bcatch\b/g,
396
+ /&&/g,
397
+ /\|\|/g,
398
+ /\?[^:]*:/g, // Ternary
399
+ ];
400
+
401
+ // Language-specific patterns
402
+ if (language === 'rust') {
403
+ patterns.push(/\bmatch\b/g, /\b=>\b/g);
404
+ }
405
+ if (language === 'python') {
406
+ patterns.push(/\belif\b/g, /\bexcept\b/g);
407
+ }
408
+
409
+ patterns.forEach(pattern => {
410
+ const matches = code.match(pattern);
411
+ if (matches) complexity += matches.length;
412
+ });
413
+
414
+ return complexity;
415
+ }
416
+
417
+ /**
418
+ * Calculate maintainability index
419
+ */
420
+ calculateMaintainability(code, complexity) {
421
+ const lines = code.split('\n');
422
+ const codeLines = lines.filter(line => {
423
+ const trimmed = line.trim();
424
+ return (
425
+ trimmed.length > 0 &&
426
+ !trimmed.startsWith('//') &&
427
+ !trimmed.startsWith('/*') &&
428
+ !trimmed.startsWith('#')
429
+ );
430
+ }).length;
431
+
432
+ const commentLines = lines.filter(line => {
433
+ const trimmed = line.trim();
434
+ return (
435
+ trimmed.startsWith('//') ||
436
+ trimmed.startsWith('/*') ||
437
+ trimmed.startsWith('*') ||
438
+ trimmed.startsWith('#')
439
+ );
440
+ }).length;
441
+
442
+ const commentRatio = codeLines > 0 ? commentLines / codeLines : 0;
443
+
444
+ const volumeScore = Math.max(0, 100 - Math.log2(codeLines + 1) * 5);
445
+ const complexityScore = Math.max(0, 100 - complexity * 2);
446
+ const commentScore = Math.min(100, commentRatio * 100);
447
+
448
+ return Math.round(volumeScore * 0.4 + complexityScore * 0.4 + commentScore * 0.2);
449
+ }
450
+
451
+ /**
452
+ * Extract functions from code
453
+ */
454
+ extractFunctions(code, language) {
455
+ const functions = [];
456
+ const lines = code.split('\n');
457
+
458
+ // Simple function detection patterns
459
+ const patterns = {
460
+ javascript:
461
+ /(?:function\s+(\w+)|(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>))/g,
462
+ typescript:
463
+ /(?:function\s+(\w+)|(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>))/g,
464
+ c: /(?:static\s+)?(?:inline\s+)?(?:\w+\s+)+(\w+)\s*\([^)]*\)\s*\{/g,
465
+ cpp: /(?:static\s+)?(?:inline\s+)?(?:virtual\s+)?(?:\w+\s+)+(\w+)\s*\([^)]*\)(?:\s*const)?\s*(?:override)?\s*\{/g,
466
+ python: /def\s+(\w+)\s*\(/g,
467
+ rust: /(?:pub\s+)?(?:async\s+)?fn\s+(\w+)/g,
468
+ go: /func\s+(?:\([^)]+\)\s+)?(\w+)/g,
469
+ java: /(?:public|private|protected)?\s*(?:static)?\s*(?:\w+)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+\w+(?:,\s*\w+)*)?\s*\{/g,
470
+ };
471
+
472
+ const pattern = patterns[language];
473
+ if (!pattern) return functions;
474
+
475
+ let match;
476
+ while ((match = pattern.exec(code)) !== null) {
477
+ const name = match[1] || match[2];
478
+ if (name) {
479
+ // Estimate function size (simple heuristic)
480
+ const startIndex = match.index;
481
+ const startLine = code.substring(0, startIndex).split('\n').length;
482
+ const endLine = this.findFunctionEnd(lines, startLine - 1, language);
483
+
484
+ functions.push({
485
+ name,
486
+ startLine,
487
+ endLine,
488
+ lines: endLine - startLine + 1,
489
+ });
490
+ }
491
+ }
492
+
493
+ return functions;
494
+ }
495
+
496
+ /**
497
+ * Find the end of a function (simplified)
498
+ */
499
+ findFunctionEnd(lines, startLine, language) {
500
+ if (language === 'python') {
501
+ // Python: find next line with same or less indentation
502
+ const startIndent = lines[startLine]?.match(/^\s*/)?.[0].length || 0;
503
+ for (let i = startLine + 1; i < lines.length; i++) {
504
+ const line = lines[i];
505
+ if (line.trim() && line.match(/^\s*/)[0].length <= startIndent) {
506
+ return i;
507
+ }
508
+ }
509
+ return lines.length;
510
+ }
511
+
512
+ // Brace-based languages
513
+ let braceCount = 0;
514
+ let started = false;
515
+
516
+ for (let i = startLine; i < lines.length; i++) {
517
+ const line = lines[i];
518
+ for (const char of line) {
519
+ if (char === '{') {
520
+ braceCount++;
521
+ started = true;
522
+ } else if (char === '}') {
523
+ braceCount--;
524
+ if (started && braceCount === 0) {
525
+ return i + 1;
526
+ }
527
+ }
528
+ }
529
+ }
530
+
531
+ return Math.min(startLine + 100, lines.length);
532
+ }
533
+
534
+ /**
535
+ * Detect issues in analyzed file
536
+ */
537
+ detectIssues(analysis) {
538
+ const issues = [];
539
+
540
+ // Giant functions
541
+ for (const func of analysis.functions) {
542
+ if (func.lines >= THRESHOLDS.functionLines.extreme) {
543
+ issues.push({
544
+ type: 'giant-function',
545
+ severity: 'extreme',
546
+ message: `Function "${func.name}" has ${func.lines} lines (threshold: ${THRESHOLDS.functionLines.extreme})`,
547
+ function: func.name,
548
+ lines: func.lines,
549
+ recommendations: this.generateFunctionSplitRecommendations(func),
550
+ });
551
+ this.results.giantFunctions.push({
552
+ file: analysis.path,
553
+ ...func,
554
+ });
555
+ } else if (func.lines >= THRESHOLDS.functionLines.critical) {
556
+ issues.push({
557
+ type: 'large-function',
558
+ severity: 'critical',
559
+ message: `Function "${func.name}" has ${func.lines} lines (threshold: ${THRESHOLDS.functionLines.critical})`,
560
+ function: func.name,
561
+ lines: func.lines,
562
+ });
563
+ } else if (func.lines >= THRESHOLDS.functionLines.warning) {
564
+ issues.push({
565
+ type: 'long-function',
566
+ severity: 'warning',
567
+ message: `Function "${func.name}" has ${func.lines} lines (threshold: ${THRESHOLDS.functionLines.warning})`,
568
+ function: func.name,
569
+ lines: func.lines,
570
+ });
571
+ }
572
+ }
573
+
574
+ // High file complexity
575
+ if (analysis.complexity >= THRESHOLDS.cyclomaticComplexity.extreme) {
576
+ issues.push({
577
+ type: 'extreme-complexity',
578
+ severity: 'extreme',
579
+ message: `File complexity is ${analysis.complexity} (threshold: ${THRESHOLDS.cyclomaticComplexity.extreme})`,
580
+ });
581
+ this.results.hotspots.push({
582
+ file: analysis.path,
583
+ complexity: analysis.complexity,
584
+ reason: 'extreme-complexity',
585
+ });
586
+ } else if (analysis.complexity >= THRESHOLDS.cyclomaticComplexity.critical) {
587
+ issues.push({
588
+ type: 'high-complexity',
589
+ severity: 'critical',
590
+ message: `File complexity is ${analysis.complexity} (threshold: ${THRESHOLDS.cyclomaticComplexity.critical})`,
591
+ });
592
+ }
593
+
594
+ // Low maintainability
595
+ if (analysis.maintainability < 20) {
596
+ issues.push({
597
+ type: 'low-maintainability',
598
+ severity: 'critical',
599
+ message: `Maintainability index is ${analysis.maintainability} (very poor)`,
600
+ });
601
+ }
602
+
603
+ return issues;
604
+ }
605
+
606
+ /**
607
+ * Generate recommendations for splitting a giant function
608
+ */
609
+ generateFunctionSplitRecommendations(func) {
610
+ const targetCount = Math.ceil(func.lines / 50);
611
+ return [
612
+ `Split "${func.name}" into ${targetCount} smaller functions (target: ~50 lines each)`,
613
+ 'Extract helper functions for repeated logic',
614
+ 'Consider using the Extract Method refactoring pattern',
615
+ 'Group related operations into separate functions by responsibility',
616
+ ];
617
+ }
618
+
619
+ /**
620
+ * Aggregate results incrementally for memory efficiency
621
+ */
622
+ aggregateResults(chunkResults) {
623
+ for (const result of chunkResults) {
624
+ // Keep only essential data for summary
625
+ this.results.files.push({
626
+ path: result.path,
627
+ language: result.language,
628
+ lines: result.lines,
629
+ complexity: result.complexity,
630
+ maintainability: result.maintainability,
631
+ issueCount: result.issues.length,
632
+ });
633
+ }
634
+ }
635
+
636
+ /**
637
+ * Check memory usage and warn if approaching limit
638
+ */
639
+ checkMemory() {
640
+ const used = process.memoryUsage();
641
+ const heapUsed = used.heapUsed;
642
+
643
+ if (heapUsed > this.stats.peakMemory) {
644
+ this.stats.peakMemory = heapUsed;
645
+ }
646
+
647
+ if (heapUsed > this.options.memoryLimit * 0.9) {
648
+ console.warn(`⚠️ Memory usage high: ${Math.round(heapUsed / 1024 / 1024)}MB`);
649
+ }
650
+ }
651
+
652
+ /**
653
+ * Update progress
654
+ */
655
+ updateProgress() {
656
+ if (this.options.progressCallback) {
657
+ const percent = Math.round((this.stats.processedFiles / this.stats.totalFiles) * 100);
658
+ this.options.progressCallback({
659
+ processed: this.stats.processedFiles,
660
+ total: this.stats.totalFiles,
661
+ percent,
662
+ chunks: this.stats.chunks,
663
+ });
664
+ }
665
+ }
666
+
667
+ /**
668
+ * Generate summary from results
669
+ */
670
+ generateSummary(_results) {
671
+ const files = this.results.files;
672
+
673
+ this.results.summary = {
674
+ totalFiles: files.length,
675
+ totalLines: files.reduce((sum, f) => sum + f.lines, 0),
676
+ averageComplexity:
677
+ files.length > 0
678
+ ? Math.round(files.reduce((sum, f) => sum + f.complexity, 0) / files.length)
679
+ : 0,
680
+ averageMaintainability:
681
+ files.length > 0
682
+ ? Math.round(files.reduce((sum, f) => sum + f.maintainability, 0) / files.length)
683
+ : 0,
684
+ giantFunctions: this.results.giantFunctions.length,
685
+ hotspots: this.results.hotspots.length,
686
+ languageDistribution: this.calculateLanguageDistribution(files),
687
+ processingTime: this.stats.endTime - this.stats.startTime,
688
+ peakMemoryMB: Math.round(this.stats.peakMemory / 1024 / 1024),
689
+ };
690
+ }
691
+
692
+ /**
693
+ * Calculate language distribution
694
+ */
695
+ calculateLanguageDistribution(files) {
696
+ const distribution = {};
697
+ for (const file of files) {
698
+ distribution[file.language] = (distribution[file.language] || 0) + 1;
699
+ }
700
+ return distribution;
701
+ }
702
+
703
+ /**
704
+ * Generate overall recommendations
705
+ */
706
+ generateRecommendations() {
707
+ const recommendations = [];
708
+ const summary = this.results.summary;
709
+
710
+ if (!summary) return recommendations;
711
+
712
+ // Giant functions
713
+ if (this.results.giantFunctions.length > 0) {
714
+ recommendations.push({
715
+ priority: 'P0',
716
+ type: 'refactoring',
717
+ title: 'Split Giant Functions',
718
+ message: `${this.results.giantFunctions.length} functions exceed 1000 lines. These require immediate refactoring.`,
719
+ items: this.results.giantFunctions
720
+ .slice(0, 5)
721
+ .map(f => `${f.file}:${f.name} (${f.lines} lines)`),
722
+ });
723
+ }
724
+
725
+ // Hotspots
726
+ if (this.results.hotspots.length > 0) {
727
+ recommendations.push({
728
+ priority: 'P1',
729
+ type: 'complexity',
730
+ title: 'Address Complexity Hotspots',
731
+ message: `${this.results.hotspots.length} files have extreme complexity. Consider breaking them down.`,
732
+ items: this.results.hotspots
733
+ .slice(0, 5)
734
+ .map(h => `${h.file} (complexity: ${h.complexity})`),
735
+ });
736
+ }
737
+
738
+ // Low maintainability
739
+ if (summary.averageMaintainability < 40) {
740
+ recommendations.push({
741
+ priority: 'P2',
742
+ type: 'maintainability',
743
+ title: 'Improve Code Maintainability',
744
+ message: `Average maintainability is ${summary.averageMaintainability}. Consider adding comments and simplifying logic.`,
745
+ });
746
+ }
747
+
748
+ // Large project recommendations
749
+ if (summary.totalFiles > THRESHOLDS.largeProject) {
750
+ recommendations.push({
751
+ priority: 'P2',
752
+ type: 'architecture',
753
+ title: 'Consider Modular Architecture',
754
+ message: `With ${summary.totalFiles.toLocaleString()} files, consider splitting into modules or microservices.`,
755
+ });
756
+ }
757
+
758
+ return recommendations;
759
+ }
760
+ }
761
+
762
+ module.exports = {
763
+ LargeProjectAnalyzer,
764
+ THRESHOLDS,
765
+ CHUNK_SIZE,
766
+ };