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,536 @@
1
+ /**
2
+ * MUSUBI Complexity Analyzer (Enhanced)
3
+ *
4
+ * Advanced complexity detection including:
5
+ * - Giant function detection (100/500/1000+ lines)
6
+ * - Cyclomatic complexity with severity levels
7
+ * - Cognitive complexity calculation
8
+ * - Dependency complexity
9
+ * - Split recommendations
10
+ *
11
+ * Based on GCC analysis where 95 functions exceeded 1000 lines
12
+ *
13
+ * @version 5.5.0
14
+ */
15
+
16
+ const fs = require('fs-extra');
17
+ const path = require('path');
18
+
19
+ // ============================================================================
20
+ // Thresholds
21
+ // ============================================================================
22
+
23
+ const THRESHOLDS = {
24
+ functionLines: {
25
+ ideal: 50,
26
+ warning: 100,
27
+ critical: 500,
28
+ extreme: 1000,
29
+ },
30
+ cyclomaticComplexity: {
31
+ ideal: 5,
32
+ warning: 10,
33
+ critical: 25,
34
+ extreme: 50,
35
+ },
36
+ cognitiveComplexity: {
37
+ ideal: 8,
38
+ warning: 15,
39
+ critical: 30,
40
+ extreme: 60,
41
+ },
42
+ dependencies: {
43
+ ideal: 5,
44
+ warning: 10,
45
+ critical: 30,
46
+ extreme: 100,
47
+ },
48
+ fileLines: {
49
+ ideal: 300,
50
+ warning: 500,
51
+ critical: 1000,
52
+ extreme: 2000,
53
+ },
54
+ };
55
+
56
+ // ============================================================================
57
+ // Complexity Analyzer
58
+ // ============================================================================
59
+
60
+ class ComplexityAnalyzer {
61
+ constructor(options = {}) {
62
+ this.options = {
63
+ thresholds: { ...THRESHOLDS, ...options.thresholds },
64
+ includeRecommendations: true,
65
+ ...options,
66
+ };
67
+ }
68
+
69
+ /**
70
+ * Analyze a file for complexity issues
71
+ */
72
+ async analyzeFile(filePath) {
73
+ const content = await fs.readFile(filePath, 'utf8');
74
+ const lines = content.split('\n');
75
+ const language = this.detectLanguage(filePath);
76
+
77
+ const analysis = {
78
+ path: filePath,
79
+ language,
80
+ totalLines: lines.length,
81
+ codeLines: this.countCodeLines(lines),
82
+ functions: [],
83
+ issues: [],
84
+ metrics: {
85
+ cyclomaticComplexity: 0,
86
+ cognitiveComplexity: 0,
87
+ maintainabilityIndex: 0,
88
+ },
89
+ };
90
+
91
+ // Extract and analyze functions
92
+ analysis.functions = await this.extractFunctions(content, language, lines);
93
+
94
+ // Calculate file-level metrics
95
+ analysis.metrics.cyclomaticComplexity = this.calculateCyclomaticComplexity(content);
96
+ analysis.metrics.cognitiveComplexity = this.calculateCognitiveComplexity(content, language);
97
+ analysis.metrics.maintainabilityIndex = this.calculateMaintainabilityIndex(
98
+ analysis.codeLines,
99
+ analysis.metrics.cyclomaticComplexity
100
+ );
101
+
102
+ // Detect issues
103
+ analysis.issues = this.detectIssues(analysis);
104
+
105
+ return analysis;
106
+ }
107
+
108
+ /**
109
+ * Detect language from file extension
110
+ */
111
+ detectLanguage(filePath) {
112
+ const ext = path.extname(filePath).toLowerCase();
113
+ const langMap = {
114
+ '.js': 'javascript',
115
+ '.ts': 'typescript',
116
+ '.jsx': 'javascript',
117
+ '.tsx': 'typescript',
118
+ '.c': 'c',
119
+ '.h': 'c',
120
+ '.cpp': 'cpp',
121
+ '.cc': 'cpp',
122
+ '.hpp': 'cpp',
123
+ '.py': 'python',
124
+ '.rs': 'rust',
125
+ '.go': 'go',
126
+ '.java': 'java',
127
+ };
128
+ return langMap[ext] || 'unknown';
129
+ }
130
+
131
+ /**
132
+ * Count non-empty, non-comment lines
133
+ */
134
+ countCodeLines(lines) {
135
+ return lines.filter(line => {
136
+ const trimmed = line.trim();
137
+ return (
138
+ trimmed.length > 0 &&
139
+ !trimmed.startsWith('//') &&
140
+ !trimmed.startsWith('/*') &&
141
+ !trimmed.startsWith('*') &&
142
+ !trimmed.startsWith('#')
143
+ );
144
+ }).length;
145
+ }
146
+
147
+ /**
148
+ * Extract functions from code
149
+ */
150
+ async extractFunctions(content, language, lines) {
151
+ const functions = [];
152
+ const patterns = this.getFunctionPatterns(language);
153
+
154
+ for (const pattern of patterns) {
155
+ let match;
156
+ while ((match = pattern.exec(content)) !== null) {
157
+ const name = match[1] || match[2] || 'anonymous';
158
+ const startIndex = match.index;
159
+ const startLine = content.substring(0, startIndex).split('\n').length;
160
+ const endLine = this.findFunctionEnd(lines, startLine - 1, language);
161
+ const functionLines = endLine - startLine + 1;
162
+
163
+ const functionContent = lines.slice(startLine - 1, endLine).join('\n');
164
+
165
+ functions.push({
166
+ name,
167
+ startLine,
168
+ endLine,
169
+ lines: functionLines,
170
+ cyclomaticComplexity: this.calculateCyclomaticComplexity(functionContent),
171
+ cognitiveComplexity: this.calculateCognitiveComplexity(functionContent, language),
172
+ severity: this.getSeverity(functionLines, 'functionLines'),
173
+ issues: [],
174
+ recommendations: [],
175
+ });
176
+ }
177
+ }
178
+
179
+ // Add issues and recommendations to each function
180
+ for (const func of functions) {
181
+ func.issues = this.detectFunctionIssues(func);
182
+ if (this.options.includeRecommendations && func.issues.length > 0) {
183
+ func.recommendations = this.generateRecommendations(func);
184
+ }
185
+ }
186
+
187
+ return functions;
188
+ }
189
+
190
+ /**
191
+ * Get function detection patterns for language
192
+ */
193
+ getFunctionPatterns(language) {
194
+ const patterns = {
195
+ javascript: [
196
+ /function\s+(\w+)\s*\(/g,
197
+ /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?function/g,
198
+ /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*=>/g,
199
+ /(\w+)\s*:\s*(?:async\s+)?function/g,
200
+ ],
201
+ typescript: [
202
+ /function\s+(\w+)\s*[<(]/g,
203
+ /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?function/g,
204
+ /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*=>/g,
205
+ /(\w+)\s*\([^)]*\)\s*:\s*\w+\s*\{/g,
206
+ ],
207
+ c: [/(?:static\s+)?(?:inline\s+)?(?:\w+\s+)+(\w+)\s*\([^)]*\)\s*\{/g],
208
+ cpp: [
209
+ /(?:static\s+)?(?:inline\s+)?(?:virtual\s+)?(?:\w+\s+)+(\w+)\s*\([^)]*\)(?:\s*const)?\s*(?:override)?\s*\{/g,
210
+ /(\w+)::(\w+)\s*\([^)]*\)\s*\{/g,
211
+ ],
212
+ python: [/def\s+(\w+)\s*\(/g, /async\s+def\s+(\w+)\s*\(/g],
213
+ rust: [/(?:pub\s+)?(?:async\s+)?fn\s+(\w+)/g],
214
+ go: [/func\s+(?:\([^)]+\)\s+)?(\w+)/g],
215
+ java: [
216
+ /(?:public|private|protected)?\s*(?:static)?\s*(?:\w+)\s+(\w+)\s*\([^)]*\)\s*(?:throws\s+[\w,\s]+)?\s*\{/g,
217
+ ],
218
+ };
219
+ return patterns[language] || patterns.javascript;
220
+ }
221
+
222
+ /**
223
+ * Find end of function
224
+ */
225
+ findFunctionEnd(lines, startLine, _language) {
226
+ if (_language === 'python') {
227
+ const startIndent = lines[startLine]?.match(/^\s*/)?.[0].length || 0;
228
+ for (let i = startLine + 1; i < lines.length; i++) {
229
+ const line = lines[i];
230
+ if (line.trim() && line.match(/^\s*/)[0].length <= startIndent) {
231
+ return i;
232
+ }
233
+ }
234
+ return lines.length;
235
+ }
236
+
237
+ let braceCount = 0;
238
+ let started = false;
239
+
240
+ for (let i = startLine; i < lines.length; i++) {
241
+ const line = lines[i];
242
+ for (const char of line) {
243
+ if (char === '{') {
244
+ braceCount++;
245
+ started = true;
246
+ } else if (char === '}') {
247
+ braceCount--;
248
+ if (started && braceCount === 0) {
249
+ return i + 1;
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ return Math.min(startLine + 100, lines.length);
256
+ }
257
+
258
+ /**
259
+ * Calculate cyclomatic complexity
260
+ */
261
+ calculateCyclomaticComplexity(code) {
262
+ let complexity = 1;
263
+
264
+ const patterns = [
265
+ /\bif\b/g,
266
+ /\belse\s+if\b/g,
267
+ /\bfor\b/g,
268
+ /\bwhile\b/g,
269
+ /\bcase\b/g,
270
+ /\bcatch\b/g,
271
+ /&&/g,
272
+ /\|\|/g,
273
+ /\?[^:]*:/g,
274
+ ];
275
+
276
+ patterns.forEach(pattern => {
277
+ const matches = code.match(pattern);
278
+ if (matches) complexity += matches.length;
279
+ });
280
+
281
+ return complexity;
282
+ }
283
+
284
+ /**
285
+ * Calculate cognitive complexity (SonarSource method)
286
+ */
287
+ calculateCognitiveComplexity(code, _language) {
288
+ let complexity = 0;
289
+ let nestingLevel = 0;
290
+
291
+ const lines = code.split('\n');
292
+
293
+ for (const line of lines) {
294
+ const trimmed = line.trim();
295
+
296
+ // Nesting increases
297
+ if (/\{$/.test(trimmed)) {
298
+ nestingLevel++;
299
+ }
300
+ if (/^\}/.test(trimmed)) {
301
+ nestingLevel = Math.max(0, nestingLevel - 1);
302
+ }
303
+
304
+ // Control flow structures add complexity + nesting penalty
305
+ if (/\b(if|else\s+if|elif)\b/.test(trimmed)) {
306
+ complexity += 1 + nestingLevel;
307
+ }
308
+ if (/\b(for|while|do)\b/.test(trimmed)) {
309
+ complexity += 1 + nestingLevel;
310
+ }
311
+ if (/\b(catch|except)\b/.test(trimmed)) {
312
+ complexity += 1 + nestingLevel;
313
+ }
314
+
315
+ // Switch/match statements
316
+ if (/\b(switch|match)\b/.test(trimmed)) {
317
+ complexity += 1;
318
+ }
319
+
320
+ // Logical operators
321
+ const andOr = (trimmed.match(/&&|\|\|/g) || []).length;
322
+ complexity += andOr;
323
+
324
+ // Recursion (function calls to self)
325
+ // This is simplified - would need function name context
326
+
327
+ // Break/continue with labels
328
+ if (/\b(break|continue)\s+\w+/.test(trimmed)) {
329
+ complexity += 1;
330
+ }
331
+
332
+ // Nested ternary
333
+ const ternaries = (trimmed.match(/\?[^:]*:/g) || []).length;
334
+ if (ternaries > 1) {
335
+ complexity += ternaries; // Nested ternaries are especially hard to read
336
+ }
337
+ }
338
+
339
+ return complexity;
340
+ }
341
+
342
+ /**
343
+ * Calculate maintainability index
344
+ */
345
+ calculateMaintainabilityIndex(codeLines, complexity) {
346
+ // Simplified Maintainability Index formula
347
+ // MI = 171 - 5.2 * ln(Halstead Volume) - 0.23 * (Cyclomatic Complexity) - 16.2 * ln(Lines of Code)
348
+ // We use a simplified version
349
+
350
+ const volumeScore = Math.max(0, 100 - Math.log2(codeLines + 1) * 10);
351
+ const complexityScore = Math.max(0, 100 - complexity * 2);
352
+
353
+ return Math.round(volumeScore * 0.5 + complexityScore * 0.5);
354
+ }
355
+
356
+ /**
357
+ * Get severity level based on threshold
358
+ */
359
+ getSeverity(value, metricType) {
360
+ const thresholds = this.options.thresholds[metricType];
361
+ if (!thresholds) return 'unknown';
362
+
363
+ if (value >= thresholds.extreme) return 'extreme';
364
+ if (value >= thresholds.critical) return 'critical';
365
+ if (value >= thresholds.warning) return 'warning';
366
+ if (value > thresholds.ideal) return 'minor';
367
+ return 'ok';
368
+ }
369
+
370
+ /**
371
+ * Detect issues in function
372
+ */
373
+ detectFunctionIssues(func) {
374
+ const issues = [];
375
+
376
+ // Function size
377
+ if (func.lines >= THRESHOLDS.functionLines.extreme) {
378
+ issues.push({
379
+ type: 'giant-function',
380
+ severity: 'extreme',
381
+ metric: 'lines',
382
+ value: func.lines,
383
+ threshold: THRESHOLDS.functionLines.extreme,
384
+ message: `Function "${func.name}" has ${func.lines} lines (extreme: >${THRESHOLDS.functionLines.extreme})`,
385
+ });
386
+ } else if (func.lines >= THRESHOLDS.functionLines.critical) {
387
+ issues.push({
388
+ type: 'very-large-function',
389
+ severity: 'critical',
390
+ metric: 'lines',
391
+ value: func.lines,
392
+ threshold: THRESHOLDS.functionLines.critical,
393
+ message: `Function "${func.name}" has ${func.lines} lines (critical: >${THRESHOLDS.functionLines.critical})`,
394
+ });
395
+ } else if (func.lines >= THRESHOLDS.functionLines.warning) {
396
+ issues.push({
397
+ type: 'large-function',
398
+ severity: 'warning',
399
+ metric: 'lines',
400
+ value: func.lines,
401
+ threshold: THRESHOLDS.functionLines.warning,
402
+ message: `Function "${func.name}" has ${func.lines} lines (warning: >${THRESHOLDS.functionLines.warning})`,
403
+ });
404
+ }
405
+
406
+ // Cyclomatic complexity
407
+ if (func.cyclomaticComplexity >= THRESHOLDS.cyclomaticComplexity.extreme) {
408
+ issues.push({
409
+ type: 'extreme-complexity',
410
+ severity: 'extreme',
411
+ metric: 'cyclomatic',
412
+ value: func.cyclomaticComplexity,
413
+ threshold: THRESHOLDS.cyclomaticComplexity.extreme,
414
+ message: `Function "${func.name}" has cyclomatic complexity ${func.cyclomaticComplexity} (extreme: >${THRESHOLDS.cyclomaticComplexity.extreme})`,
415
+ });
416
+ } else if (func.cyclomaticComplexity >= THRESHOLDS.cyclomaticComplexity.critical) {
417
+ issues.push({
418
+ type: 'high-complexity',
419
+ severity: 'critical',
420
+ metric: 'cyclomatic',
421
+ value: func.cyclomaticComplexity,
422
+ threshold: THRESHOLDS.cyclomaticComplexity.critical,
423
+ message: `Function "${func.name}" has cyclomatic complexity ${func.cyclomaticComplexity} (critical: >${THRESHOLDS.cyclomaticComplexity.critical})`,
424
+ });
425
+ }
426
+
427
+ // Cognitive complexity
428
+ if (func.cognitiveComplexity >= THRESHOLDS.cognitiveComplexity.extreme) {
429
+ issues.push({
430
+ type: 'extreme-cognitive-complexity',
431
+ severity: 'extreme',
432
+ metric: 'cognitive',
433
+ value: func.cognitiveComplexity,
434
+ threshold: THRESHOLDS.cognitiveComplexity.extreme,
435
+ message: `Function "${func.name}" has cognitive complexity ${func.cognitiveComplexity} (extreme: >${THRESHOLDS.cognitiveComplexity.extreme})`,
436
+ });
437
+ }
438
+
439
+ return issues;
440
+ }
441
+
442
+ /**
443
+ * Detect file-level issues
444
+ */
445
+ detectIssues(analysis) {
446
+ const issues = [];
447
+
448
+ // File size
449
+ if (analysis.codeLines >= THRESHOLDS.fileLines.extreme) {
450
+ issues.push({
451
+ type: 'giant-file',
452
+ severity: 'extreme',
453
+ message: `File has ${analysis.codeLines} code lines (extreme: >${THRESHOLDS.fileLines.extreme})`,
454
+ });
455
+ }
456
+
457
+ // Aggregate function issues
458
+ const giantFunctions = analysis.functions.filter(
459
+ f => f.lines >= THRESHOLDS.functionLines.extreme
460
+ );
461
+ if (giantFunctions.length > 0) {
462
+ issues.push({
463
+ type: 'contains-giant-functions',
464
+ severity: 'extreme',
465
+ message: `File contains ${giantFunctions.length} giant functions (>${THRESHOLDS.functionLines.extreme} lines)`,
466
+ functions: giantFunctions.map(f => f.name),
467
+ });
468
+ }
469
+
470
+ return issues;
471
+ }
472
+
473
+ /**
474
+ * Generate recommendations for a complex function
475
+ */
476
+ generateRecommendations(func) {
477
+ const recommendations = [];
478
+
479
+ // Size-based recommendations
480
+ if (func.lines >= THRESHOLDS.functionLines.warning) {
481
+ const targetCount = Math.ceil(func.lines / 50);
482
+ recommendations.push({
483
+ type: 'split-function',
484
+ priority: func.lines >= THRESHOLDS.functionLines.extreme ? 'P0' : 'P1',
485
+ title: 'Split into smaller functions',
486
+ description: `Break "${func.name}" into approximately ${targetCount} smaller functions (~50 lines each)`,
487
+ actions: [
488
+ 'Identify distinct logical sections within the function',
489
+ 'Extract each section into a helper function',
490
+ 'Use descriptive names that explain what each helper does',
491
+ 'Consider using the "Extract Method" refactoring pattern',
492
+ ],
493
+ });
494
+ }
495
+
496
+ // Complexity-based recommendations
497
+ if (func.cyclomaticComplexity >= THRESHOLDS.cyclomaticComplexity.warning) {
498
+ recommendations.push({
499
+ type: 'reduce-complexity',
500
+ priority:
501
+ func.cyclomaticComplexity >= THRESHOLDS.cyclomaticComplexity.extreme ? 'P0' : 'P1',
502
+ title: 'Reduce cyclomatic complexity',
503
+ description: `Current complexity: ${func.cyclomaticComplexity}, target: <${THRESHOLDS.cyclomaticComplexity.warning}`,
504
+ actions: [
505
+ 'Replace nested conditionals with early returns',
506
+ 'Use polymorphism instead of type-checking switches',
507
+ 'Extract complex conditions into well-named boolean functions',
508
+ 'Consider using the Strategy pattern for complex branching',
509
+ ],
510
+ });
511
+ }
512
+
513
+ // Cognitive complexity recommendations
514
+ if (func.cognitiveComplexity >= THRESHOLDS.cognitiveComplexity.warning) {
515
+ recommendations.push({
516
+ type: 'improve-readability',
517
+ priority: 'P2',
518
+ title: 'Improve cognitive readability',
519
+ description: `Cognitive complexity: ${func.cognitiveComplexity}`,
520
+ actions: [
521
+ 'Reduce nesting depth by inverting conditions',
522
+ 'Avoid nested ternary operators',
523
+ 'Break long chains of && and || into named variables',
524
+ 'Consider using guard clauses instead of nested if-else',
525
+ ],
526
+ });
527
+ }
528
+
529
+ return recommendations;
530
+ }
531
+ }
532
+
533
+ module.exports = {
534
+ ComplexityAnalyzer,
535
+ THRESHOLDS,
536
+ };