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.
- package/README.ja.md +106 -48
- package/README.md +110 -32
- package/bin/musubi-analyze.js +74 -67
- package/bin/musubi-browser.js +27 -26
- package/bin/musubi-change.js +48 -47
- package/bin/musubi-checkpoint.js +10 -7
- package/bin/musubi-convert.js +25 -25
- package/bin/musubi-costs.js +27 -10
- package/bin/musubi-gui.js +52 -46
- package/bin/musubi-init.js +1952 -10
- package/bin/musubi-orchestrate.js +327 -239
- package/bin/musubi-remember.js +69 -56
- package/bin/musubi-resolve.js +53 -45
- package/bin/musubi-trace.js +51 -22
- package/bin/musubi-validate.js +39 -30
- package/bin/musubi-workflow.js +33 -34
- package/bin/musubi.js +39 -2
- package/package.json +1 -1
- package/src/agents/agent-loop.js +94 -95
- package/src/agents/agentic/code-generator.js +119 -109
- package/src/agents/agentic/code-reviewer.js +105 -108
- package/src/agents/agentic/index.js +4 -4
- package/src/agents/browser/action-executor.js +13 -13
- package/src/agents/browser/ai-comparator.js +11 -10
- package/src/agents/browser/context-manager.js +6 -6
- package/src/agents/browser/index.js +5 -5
- package/src/agents/browser/nl-parser.js +31 -46
- package/src/agents/browser/screenshot.js +2 -2
- package/src/agents/browser/test-generator.js +6 -4
- package/src/agents/function-tool.js +71 -65
- package/src/agents/index.js +7 -7
- package/src/agents/schema-generator.js +98 -94
- package/src/analyzers/ast-extractor.js +164 -145
- package/src/analyzers/codegraph-auto-update.js +858 -0
- package/src/analyzers/complexity-analyzer.js +536 -0
- package/src/analyzers/context-optimizer.js +247 -125
- package/src/analyzers/impact-analyzer.js +1 -1
- package/src/analyzers/large-project-analyzer.js +766 -0
- package/src/analyzers/repository-map.js +83 -80
- package/src/analyzers/security-analyzer.js +19 -11
- package/src/analyzers/stuck-detector.js +19 -17
- package/src/converters/index.js +78 -57
- package/src/converters/ir/types.js +12 -12
- package/src/converters/parsers/musubi-parser.js +134 -126
- package/src/converters/parsers/openapi-parser.js +70 -53
- package/src/converters/parsers/speckit-parser.js +239 -175
- package/src/converters/writers/musubi-writer.js +123 -118
- package/src/converters/writers/speckit-writer.js +124 -113
- package/src/generators/rust-migration-generator.js +512 -0
- package/src/gui/public/index.html +1365 -1211
- package/src/gui/server.js +41 -40
- package/src/gui/services/file-watcher.js +23 -8
- package/src/gui/services/project-scanner.js +26 -20
- package/src/gui/services/replanning-service.js +27 -23
- package/src/gui/services/traceability-service.js +8 -8
- package/src/gui/services/workflow-service.js +14 -7
- package/src/index.js +151 -0
- package/src/integrations/cicd.js +90 -104
- package/src/integrations/codegraph-mcp.js +643 -0
- package/src/integrations/documentation.js +142 -103
- package/src/integrations/examples.js +95 -80
- package/src/integrations/github-client.js +17 -17
- package/src/integrations/index.js +5 -5
- package/src/integrations/mcp/index.js +21 -21
- package/src/integrations/mcp/mcp-context-provider.js +76 -78
- package/src/integrations/mcp/mcp-discovery.js +74 -72
- package/src/integrations/mcp/mcp-tool-registry.js +99 -94
- package/src/integrations/mcp-connector.js +70 -66
- package/src/integrations/platforms.js +50 -49
- package/src/integrations/tool-discovery.js +37 -31
- package/src/llm-providers/anthropic-provider.js +11 -11
- package/src/llm-providers/base-provider.js +16 -18
- package/src/llm-providers/copilot-provider.js +22 -19
- package/src/llm-providers/index.js +26 -25
- package/src/llm-providers/ollama-provider.js +11 -11
- package/src/llm-providers/openai-provider.js +12 -12
- package/src/managers/agent-memory.js +36 -24
- package/src/managers/checkpoint-manager.js +4 -8
- package/src/managers/delta-spec.js +19 -19
- package/src/managers/index.js +13 -4
- package/src/managers/memory-condenser.js +35 -45
- package/src/managers/repo-skill-manager.js +57 -31
- package/src/managers/skill-loader.js +25 -22
- package/src/managers/skill-tools.js +36 -72
- package/src/managers/workflow.js +30 -22
- package/src/monitoring/cost-tracker.js +53 -44
- package/src/monitoring/incident-manager.js +123 -103
- package/src/monitoring/index.js +144 -134
- package/src/monitoring/observability.js +82 -59
- package/src/monitoring/quality-dashboard.js +51 -39
- package/src/monitoring/release-manager.js +70 -50
- package/src/orchestration/agent-skill-binding.js +39 -47
- package/src/orchestration/error-handler.js +65 -107
- package/src/orchestration/guardrails/base-guardrail.js +26 -24
- package/src/orchestration/guardrails/guardrail-rules.js +50 -64
- package/src/orchestration/guardrails/index.js +5 -5
- package/src/orchestration/guardrails/input-guardrail.js +58 -45
- package/src/orchestration/guardrails/output-guardrail.js +104 -81
- package/src/orchestration/guardrails/safety-check.js +79 -79
- package/src/orchestration/index.js +38 -55
- package/src/orchestration/mcp-tool-adapters.js +96 -99
- package/src/orchestration/orchestration-engine.js +21 -21
- package/src/orchestration/pattern-registry.js +60 -45
- package/src/orchestration/patterns/auto.js +34 -47
- package/src/orchestration/patterns/group-chat.js +59 -65
- package/src/orchestration/patterns/handoff.js +67 -65
- package/src/orchestration/patterns/human-in-loop.js +51 -72
- package/src/orchestration/patterns/nested.js +25 -40
- package/src/orchestration/patterns/sequential.js +35 -34
- package/src/orchestration/patterns/swarm.js +63 -56
- package/src/orchestration/patterns/triage.js +150 -109
- package/src/orchestration/reasoning/index.js +9 -9
- package/src/orchestration/reasoning/planning-engine.js +143 -140
- package/src/orchestration/reasoning/reasoning-engine.js +206 -144
- package/src/orchestration/reasoning/self-correction.js +121 -128
- package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
- package/src/orchestration/replanning/alternative-generator.js +37 -42
- package/src/orchestration/replanning/config.js +63 -59
- package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
- package/src/orchestration/replanning/index.js +24 -20
- package/src/orchestration/replanning/plan-evaluator.js +49 -50
- package/src/orchestration/replanning/plan-monitor.js +32 -28
- package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
- package/src/orchestration/replanning/replan-history.js +33 -26
- package/src/orchestration/replanning/replanning-engine.js +106 -108
- package/src/orchestration/skill-executor.js +107 -109
- package/src/orchestration/skill-registry.js +85 -89
- package/src/orchestration/workflow-examples.js +228 -231
- package/src/orchestration/workflow-executor.js +65 -68
- package/src/orchestration/workflow-orchestrator.js +72 -73
- package/src/phase4-integration.js +47 -40
- package/src/phase5-integration.js +89 -30
- package/src/reporters/coverage-report.js +82 -30
- package/src/reporters/hierarchical-reporter.js +498 -0
- package/src/reporters/traceability-matrix-report.js +29 -20
- package/src/resolvers/issue-resolver.js +43 -31
- package/src/steering/advanced-validation.js +133 -124
- package/src/steering/auto-updater.js +60 -73
- package/src/steering/index.js +6 -6
- package/src/steering/quality-metrics.js +41 -35
- package/src/steering/steering-auto-update.js +83 -86
- package/src/steering/steering-validator.js +98 -106
- package/src/steering/template-constraints.js +53 -54
- package/src/templates/agents/claude-code/CLAUDE.md +32 -32
- package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
- package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
- package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
- package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
- package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
- package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
- package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
- package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
- package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
- package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
- package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
- package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
- package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
- package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
- package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
- package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
- package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
- package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
- package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
- package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
- package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
- package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
- package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
- package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
- package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
- package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
- package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
- package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
- package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
- package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
- package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
- package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
- package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
- package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
- package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
- package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
- package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
- package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
- package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
- package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
- package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
- package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
- package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
- package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
- package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
- package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
- package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
- package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
- package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
- package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
- package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
- package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
- package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
- package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
- package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
- package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
- package/src/templates/agents/codex/AGENTS.md +74 -42
- package/src/templates/agents/cursor/AGENTS.md +74 -42
- package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
- package/src/templates/agents/github-copilot/AGENTS.md +83 -51
- package/src/templates/agents/qwen-code/QWEN.md +74 -42
- package/src/templates/agents/windsurf/AGENTS.md +74 -42
- package/src/templates/architectures/README.md +41 -0
- package/src/templates/architectures/clean-architecture/README.md +113 -0
- package/src/templates/architectures/event-driven/README.md +162 -0
- package/src/templates/architectures/hexagonal/README.md +130 -0
- package/src/templates/index.js +6 -1
- package/src/templates/locale-manager.js +16 -16
- package/src/templates/shared/delta-spec-template.md +20 -13
- package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
- package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
- package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
- package/src/templates/shared/steering/structure.md +95 -0
- package/src/templates/skills/browser-agent.md +21 -16
- package/src/templates/skills/web-gui.md +8 -0
- package/src/templates/template-constraints.js +50 -53
- package/src/validators/advanced-validation.js +30 -36
- package/src/validators/constitutional-validator.js +77 -73
- package/src/validators/critic-system.js +49 -59
- package/src/validators/delta-format.js +59 -55
- package/src/validators/traceability-validator.js +7 -11
|
@@ -17,7 +17,7 @@ const SEVERITY = {
|
|
|
17
17
|
INFO: 'info',
|
|
18
18
|
WARNING: 'warning',
|
|
19
19
|
ERROR: 'error',
|
|
20
|
-
CRITICAL: 'critical'
|
|
20
|
+
CRITICAL: 'critical',
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -32,7 +32,7 @@ const CATEGORY = {
|
|
|
32
32
|
MAINTAINABILITY: 'maintainability',
|
|
33
33
|
BEST_PRACTICE: 'best-practice',
|
|
34
34
|
ERROR_HANDLING: 'error-handling',
|
|
35
|
-
DOCUMENTATION: 'documentation'
|
|
35
|
+
DOCUMENTATION: 'documentation',
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -78,7 +78,7 @@ const DEFAULT_RULES = {
|
|
|
78
78
|
category: CATEGORY.BEST_PRACTICE,
|
|
79
79
|
severity: SEVERITY.WARNING,
|
|
80
80
|
message: 'Use const or let instead of var',
|
|
81
|
-
suggestion: 'Replace var with const or let'
|
|
81
|
+
suggestion: 'Replace var with const or let',
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
id: 'js-console-log',
|
|
@@ -86,7 +86,7 @@ const DEFAULT_RULES = {
|
|
|
86
86
|
category: CATEGORY.BEST_PRACTICE,
|
|
87
87
|
severity: SEVERITY.INFO,
|
|
88
88
|
message: 'Console statements should be removed in production',
|
|
89
|
-
suggestion: 'Remove or replace with proper logging'
|
|
89
|
+
suggestion: 'Remove or replace with proper logging',
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
id: 'js-eval',
|
|
@@ -94,7 +94,7 @@ const DEFAULT_RULES = {
|
|
|
94
94
|
category: CATEGORY.SECURITY,
|
|
95
95
|
severity: SEVERITY.CRITICAL,
|
|
96
96
|
message: 'eval() is dangerous and should be avoided',
|
|
97
|
-
suggestion: 'Use safer alternatives to eval()'
|
|
97
|
+
suggestion: 'Use safer alternatives to eval()',
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
id: 'js-todo',
|
|
@@ -102,7 +102,7 @@ const DEFAULT_RULES = {
|
|
|
102
102
|
category: CATEGORY.MAINTAINABILITY,
|
|
103
103
|
severity: SEVERITY.INFO,
|
|
104
104
|
message: 'TODO comment found',
|
|
105
|
-
suggestion: 'Complete or track the TODO item'
|
|
105
|
+
suggestion: 'Complete or track the TODO item',
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
108
|
id: 'js-empty-catch',
|
|
@@ -110,7 +110,7 @@ const DEFAULT_RULES = {
|
|
|
110
110
|
category: CATEGORY.ERROR_HANDLING,
|
|
111
111
|
severity: SEVERITY.ERROR,
|
|
112
112
|
message: 'Empty catch block swallows errors',
|
|
113
|
-
suggestion: 'Handle or log the caught error'
|
|
113
|
+
suggestion: 'Handle or log the caught error',
|
|
114
114
|
},
|
|
115
115
|
{
|
|
116
116
|
id: 'js-magic-number',
|
|
@@ -118,7 +118,7 @@ const DEFAULT_RULES = {
|
|
|
118
118
|
category: CATEGORY.MAINTAINABILITY,
|
|
119
119
|
severity: SEVERITY.INFO,
|
|
120
120
|
message: 'Magic number should be extracted to a named constant',
|
|
121
|
-
suggestion: 'Define a constant with a descriptive name'
|
|
121
|
+
suggestion: 'Define a constant with a descriptive name',
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
id: 'js-long-function',
|
|
@@ -127,7 +127,7 @@ const DEFAULT_RULES = {
|
|
|
127
127
|
severity: SEVERITY.WARNING,
|
|
128
128
|
message: 'Function may be too long',
|
|
129
129
|
checkLength: true,
|
|
130
|
-
maxLength: 50
|
|
130
|
+
maxLength: 50,
|
|
131
131
|
},
|
|
132
132
|
{
|
|
133
133
|
id: 'js-no-strict',
|
|
@@ -136,10 +136,10 @@ const DEFAULT_RULES = {
|
|
|
136
136
|
category: CATEGORY.BEST_PRACTICE,
|
|
137
137
|
severity: SEVERITY.WARNING,
|
|
138
138
|
message: 'Consider adding "use strict"',
|
|
139
|
-
condition:
|
|
140
|
-
}
|
|
139
|
+
condition: code => !code.includes("'use strict'") && !code.includes('"use strict"'),
|
|
140
|
+
},
|
|
141
141
|
],
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
python: [
|
|
144
144
|
{
|
|
145
145
|
id: 'py-except-bare',
|
|
@@ -147,7 +147,7 @@ const DEFAULT_RULES = {
|
|
|
147
147
|
category: CATEGORY.ERROR_HANDLING,
|
|
148
148
|
severity: SEVERITY.WARNING,
|
|
149
149
|
message: 'Bare except catches all exceptions',
|
|
150
|
-
suggestion: 'Specify the exception type to catch'
|
|
150
|
+
suggestion: 'Specify the exception type to catch',
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
153
|
id: 'py-print',
|
|
@@ -155,7 +155,7 @@ const DEFAULT_RULES = {
|
|
|
155
155
|
category: CATEGORY.BEST_PRACTICE,
|
|
156
156
|
severity: SEVERITY.INFO,
|
|
157
157
|
message: 'Print statements should use logging in production',
|
|
158
|
-
suggestion: 'Use logging module instead'
|
|
158
|
+
suggestion: 'Use logging module instead',
|
|
159
159
|
},
|
|
160
160
|
{
|
|
161
161
|
id: 'py-todo',
|
|
@@ -163,7 +163,7 @@ const DEFAULT_RULES = {
|
|
|
163
163
|
category: CATEGORY.MAINTAINABILITY,
|
|
164
164
|
severity: SEVERITY.INFO,
|
|
165
165
|
message: 'TODO comment found',
|
|
166
|
-
suggestion: 'Complete or track the TODO item'
|
|
166
|
+
suggestion: 'Complete or track the TODO item',
|
|
167
167
|
},
|
|
168
168
|
{
|
|
169
169
|
id: 'py-global',
|
|
@@ -171,10 +171,10 @@ const DEFAULT_RULES = {
|
|
|
171
171
|
category: CATEGORY.BEST_PRACTICE,
|
|
172
172
|
severity: SEVERITY.WARNING,
|
|
173
173
|
message: 'Global variables should be avoided',
|
|
174
|
-
suggestion: 'Consider using class or function parameters'
|
|
175
|
-
}
|
|
174
|
+
suggestion: 'Consider using class or function parameters',
|
|
175
|
+
},
|
|
176
176
|
],
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
common: [
|
|
179
179
|
{
|
|
180
180
|
id: 'common-fixme',
|
|
@@ -182,7 +182,7 @@ const DEFAULT_RULES = {
|
|
|
182
182
|
category: CATEGORY.MAINTAINABILITY,
|
|
183
183
|
severity: SEVERITY.WARNING,
|
|
184
184
|
message: 'FIXME comment found - needs attention',
|
|
185
|
-
suggestion: 'Address the FIXME issue'
|
|
185
|
+
suggestion: 'Address the FIXME issue',
|
|
186
186
|
},
|
|
187
187
|
{
|
|
188
188
|
id: 'common-hack',
|
|
@@ -190,7 +190,7 @@ const DEFAULT_RULES = {
|
|
|
190
190
|
category: CATEGORY.MAINTAINABILITY,
|
|
191
191
|
severity: SEVERITY.WARNING,
|
|
192
192
|
message: 'HACK comment found - technical debt',
|
|
193
|
-
suggestion: 'Refactor the hack'
|
|
193
|
+
suggestion: 'Refactor the hack',
|
|
194
194
|
},
|
|
195
195
|
{
|
|
196
196
|
id: 'common-password',
|
|
@@ -198,7 +198,7 @@ const DEFAULT_RULES = {
|
|
|
198
198
|
category: CATEGORY.SECURITY,
|
|
199
199
|
severity: SEVERITY.CRITICAL,
|
|
200
200
|
message: 'Hardcoded password detected',
|
|
201
|
-
suggestion: 'Use environment variables or secure vault'
|
|
201
|
+
suggestion: 'Use environment variables or secure vault',
|
|
202
202
|
},
|
|
203
203
|
{
|
|
204
204
|
id: 'common-api-key',
|
|
@@ -206,9 +206,9 @@ const DEFAULT_RULES = {
|
|
|
206
206
|
category: CATEGORY.SECURITY,
|
|
207
207
|
severity: SEVERITY.CRITICAL,
|
|
208
208
|
message: 'Hardcoded API key detected',
|
|
209
|
-
suggestion: 'Use environment variables'
|
|
210
|
-
}
|
|
211
|
-
]
|
|
209
|
+
suggestion: 'Use environment variables',
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
/**
|
|
@@ -222,24 +222,24 @@ class CodeReviewer extends EventEmitter {
|
|
|
222
222
|
*/
|
|
223
223
|
constructor(options = {}) {
|
|
224
224
|
super();
|
|
225
|
-
|
|
225
|
+
|
|
226
226
|
this.rules = this.mergeRules(DEFAULT_RULES, options.rules || {});
|
|
227
227
|
this.enabledCategories = options.enabledCategories || Object.values(CATEGORY);
|
|
228
228
|
this.minScore = options.minScore ?? 70;
|
|
229
229
|
this.strictMode = options.strictMode ?? false;
|
|
230
|
-
|
|
230
|
+
|
|
231
231
|
// State
|
|
232
232
|
this.reviews = new Map();
|
|
233
233
|
this.reviewCounter = 0;
|
|
234
234
|
}
|
|
235
|
-
|
|
235
|
+
|
|
236
236
|
/**
|
|
237
237
|
* Merge custom rules with defaults
|
|
238
238
|
* @private
|
|
239
239
|
*/
|
|
240
240
|
mergeRules(defaults, custom) {
|
|
241
241
|
const merged = { ...defaults };
|
|
242
|
-
|
|
242
|
+
|
|
243
243
|
for (const [lang, rules] of Object.entries(custom)) {
|
|
244
244
|
if (merged[lang]) {
|
|
245
245
|
merged[lang] = [...merged[lang], ...rules];
|
|
@@ -247,10 +247,10 @@ class CodeReviewer extends EventEmitter {
|
|
|
247
247
|
merged[lang] = rules;
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
|
-
|
|
250
|
+
|
|
251
251
|
return merged;
|
|
252
252
|
}
|
|
253
|
-
|
|
253
|
+
|
|
254
254
|
/**
|
|
255
255
|
* Review code
|
|
256
256
|
* @param {string} code - Code to review
|
|
@@ -261,34 +261,31 @@ class CodeReviewer extends EventEmitter {
|
|
|
261
261
|
const id = this.generateId();
|
|
262
262
|
const language = options.language || this.detectLanguage(code, options.filePath);
|
|
263
263
|
const filePath = options.filePath || 'unknown';
|
|
264
|
-
|
|
264
|
+
|
|
265
265
|
this.emit('review:start', { id, filePath, language });
|
|
266
|
-
|
|
266
|
+
|
|
267
267
|
const issues = [];
|
|
268
|
-
|
|
268
|
+
|
|
269
269
|
// Get applicable rules
|
|
270
|
-
const rules = [
|
|
271
|
-
|
|
272
|
-
...(this.rules.common || [])
|
|
273
|
-
];
|
|
274
|
-
|
|
270
|
+
const rules = [...(this.rules[language] || []), ...(this.rules.common || [])];
|
|
271
|
+
|
|
275
272
|
// Apply each rule
|
|
276
273
|
for (const rule of rules) {
|
|
277
274
|
// Check if category is enabled
|
|
278
275
|
if (!this.enabledCategories.includes(rule.category)) continue;
|
|
279
|
-
|
|
276
|
+
|
|
280
277
|
// Apply rule
|
|
281
278
|
const ruleIssues = this.applyRule(rule, code, language);
|
|
282
279
|
issues.push(...ruleIssues);
|
|
283
280
|
}
|
|
284
|
-
|
|
281
|
+
|
|
285
282
|
// Run additional checks
|
|
286
283
|
const structuralIssues = this.checkStructure(code, language);
|
|
287
284
|
issues.push(...structuralIssues);
|
|
288
|
-
|
|
285
|
+
|
|
289
286
|
// Calculate score
|
|
290
287
|
const score = this.calculateScore(issues);
|
|
291
|
-
|
|
288
|
+
|
|
292
289
|
// Create result
|
|
293
290
|
const result = {
|
|
294
291
|
id,
|
|
@@ -297,24 +294,24 @@ class CodeReviewer extends EventEmitter {
|
|
|
297
294
|
issues,
|
|
298
295
|
score,
|
|
299
296
|
summary: this.createSummary(issues, score),
|
|
300
|
-
timestamp: Date.now()
|
|
297
|
+
timestamp: Date.now(),
|
|
301
298
|
};
|
|
302
|
-
|
|
299
|
+
|
|
303
300
|
// Store review
|
|
304
301
|
this.reviews.set(id, result);
|
|
305
|
-
|
|
302
|
+
|
|
306
303
|
this.emit('review:complete', { result });
|
|
307
|
-
|
|
304
|
+
|
|
308
305
|
return result;
|
|
309
306
|
}
|
|
310
|
-
|
|
307
|
+
|
|
311
308
|
/**
|
|
312
309
|
* Apply a single rule
|
|
313
310
|
* @private
|
|
314
311
|
*/
|
|
315
|
-
applyRule(rule, code,
|
|
312
|
+
applyRule(rule, code, _language) {
|
|
316
313
|
const issues = [];
|
|
317
|
-
|
|
314
|
+
|
|
318
315
|
// Handle condition-based rules
|
|
319
316
|
if (rule.condition) {
|
|
320
317
|
if (rule.condition(code)) {
|
|
@@ -322,33 +319,33 @@ class CodeReviewer extends EventEmitter {
|
|
|
322
319
|
}
|
|
323
320
|
return issues;
|
|
324
321
|
}
|
|
325
|
-
|
|
322
|
+
|
|
326
323
|
// Handle pattern-based rules
|
|
327
324
|
if (!rule.pattern) return issues;
|
|
328
|
-
|
|
329
|
-
const
|
|
325
|
+
|
|
326
|
+
const _lines = code.split('\n');
|
|
330
327
|
let match;
|
|
331
|
-
|
|
328
|
+
|
|
332
329
|
// Reset regex
|
|
333
330
|
rule.pattern.lastIndex = 0;
|
|
334
|
-
|
|
331
|
+
|
|
335
332
|
while ((match = rule.pattern.exec(code)) !== null) {
|
|
336
333
|
const line = this.getLineNumber(code, match.index);
|
|
337
334
|
const column = match.index - this.getLineStart(code, line);
|
|
338
|
-
|
|
335
|
+
|
|
339
336
|
// Skip if checking length and within limit
|
|
340
337
|
if (rule.checkLength) {
|
|
341
338
|
const funcEnd = this.findFunctionEnd(code, match.index);
|
|
342
339
|
const funcLines = code.substring(match.index, funcEnd).split('\n').length;
|
|
343
340
|
if (funcLines <= rule.maxLength) continue;
|
|
344
341
|
}
|
|
345
|
-
|
|
342
|
+
|
|
346
343
|
issues.push(this.createIssue(rule, line, column, match[0]));
|
|
347
344
|
}
|
|
348
|
-
|
|
345
|
+
|
|
349
346
|
return issues;
|
|
350
347
|
}
|
|
351
|
-
|
|
348
|
+
|
|
352
349
|
/**
|
|
353
350
|
* Create an issue object
|
|
354
351
|
* @private
|
|
@@ -363,10 +360,10 @@ class CodeReviewer extends EventEmitter {
|
|
|
363
360
|
column,
|
|
364
361
|
code,
|
|
365
362
|
suggestion: rule.suggestion,
|
|
366
|
-
rule: rule.id
|
|
363
|
+
rule: rule.id,
|
|
367
364
|
};
|
|
368
365
|
}
|
|
369
|
-
|
|
366
|
+
|
|
370
367
|
/**
|
|
371
368
|
* Check code structure
|
|
372
369
|
* @private
|
|
@@ -374,7 +371,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
374
371
|
checkStructure(code, language) {
|
|
375
372
|
const issues = [];
|
|
376
373
|
const lines = code.split('\n');
|
|
377
|
-
|
|
374
|
+
|
|
378
375
|
// Check line length
|
|
379
376
|
lines.forEach((line, index) => {
|
|
380
377
|
if (line.length > 120) {
|
|
@@ -384,11 +381,11 @@ class CodeReviewer extends EventEmitter {
|
|
|
384
381
|
category: CATEGORY.STYLE,
|
|
385
382
|
message: `Line exceeds 120 characters (${line.length})`,
|
|
386
383
|
line: index + 1,
|
|
387
|
-
suggestion: 'Break long lines for better readability'
|
|
384
|
+
suggestion: 'Break long lines for better readability',
|
|
388
385
|
});
|
|
389
386
|
}
|
|
390
387
|
});
|
|
391
|
-
|
|
388
|
+
|
|
392
389
|
// Check for missing documentation
|
|
393
390
|
if (language === 'javascript' || language === 'typescript') {
|
|
394
391
|
if (!code.includes('/**') && !code.includes('//')) {
|
|
@@ -397,11 +394,11 @@ class CodeReviewer extends EventEmitter {
|
|
|
397
394
|
severity: SEVERITY.INFO,
|
|
398
395
|
category: CATEGORY.DOCUMENTATION,
|
|
399
396
|
message: 'Code lacks documentation comments',
|
|
400
|
-
suggestion: 'Add JSDoc comments to functions and classes'
|
|
397
|
+
suggestion: 'Add JSDoc comments to functions and classes',
|
|
401
398
|
});
|
|
402
399
|
}
|
|
403
400
|
}
|
|
404
|
-
|
|
401
|
+
|
|
405
402
|
// Check nesting depth
|
|
406
403
|
const maxNesting = this.checkNestingDepth(code);
|
|
407
404
|
if (maxNesting > 4) {
|
|
@@ -410,13 +407,13 @@ class CodeReviewer extends EventEmitter {
|
|
|
410
407
|
severity: SEVERITY.WARNING,
|
|
411
408
|
category: CATEGORY.MAINTAINABILITY,
|
|
412
409
|
message: `Deep nesting detected (depth: ${maxNesting})`,
|
|
413
|
-
suggestion: 'Consider extracting nested code into separate functions'
|
|
410
|
+
suggestion: 'Consider extracting nested code into separate functions',
|
|
414
411
|
});
|
|
415
412
|
}
|
|
416
|
-
|
|
413
|
+
|
|
417
414
|
return issues;
|
|
418
415
|
}
|
|
419
|
-
|
|
416
|
+
|
|
420
417
|
/**
|
|
421
418
|
* Check nesting depth
|
|
422
419
|
* @private
|
|
@@ -424,7 +421,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
424
421
|
checkNestingDepth(code) {
|
|
425
422
|
let maxDepth = 0;
|
|
426
423
|
let currentDepth = 0;
|
|
427
|
-
|
|
424
|
+
|
|
428
425
|
for (const char of code) {
|
|
429
426
|
if (char === '{') {
|
|
430
427
|
currentDepth++;
|
|
@@ -433,31 +430,31 @@ class CodeReviewer extends EventEmitter {
|
|
|
433
430
|
currentDepth = Math.max(0, currentDepth - 1);
|
|
434
431
|
}
|
|
435
432
|
}
|
|
436
|
-
|
|
433
|
+
|
|
437
434
|
return maxDepth;
|
|
438
435
|
}
|
|
439
|
-
|
|
436
|
+
|
|
440
437
|
/**
|
|
441
438
|
* Calculate review score
|
|
442
439
|
* @private
|
|
443
440
|
*/
|
|
444
441
|
calculateScore(issues) {
|
|
445
442
|
let score = 100;
|
|
446
|
-
|
|
443
|
+
|
|
447
444
|
const penalties = {
|
|
448
445
|
[SEVERITY.INFO]: 1,
|
|
449
446
|
[SEVERITY.WARNING]: 3,
|
|
450
447
|
[SEVERITY.ERROR]: 10,
|
|
451
|
-
[SEVERITY.CRITICAL]: 25
|
|
448
|
+
[SEVERITY.CRITICAL]: 25,
|
|
452
449
|
};
|
|
453
|
-
|
|
450
|
+
|
|
454
451
|
for (const issue of issues) {
|
|
455
452
|
score -= penalties[issue.severity] || 0;
|
|
456
453
|
}
|
|
457
|
-
|
|
454
|
+
|
|
458
455
|
return Math.max(0, score);
|
|
459
456
|
}
|
|
460
|
-
|
|
457
|
+
|
|
461
458
|
/**
|
|
462
459
|
* Create review summary
|
|
463
460
|
* @private
|
|
@@ -465,34 +462,34 @@ class CodeReviewer extends EventEmitter {
|
|
|
465
462
|
createSummary(issues, score) {
|
|
466
463
|
const bySeverity = {};
|
|
467
464
|
const byCategory = {};
|
|
468
|
-
|
|
465
|
+
|
|
469
466
|
for (const issue of issues) {
|
|
470
467
|
bySeverity[issue.severity] = (bySeverity[issue.severity] || 0) + 1;
|
|
471
468
|
byCategory[issue.category] = (byCategory[issue.category] || 0) + 1;
|
|
472
469
|
}
|
|
473
|
-
|
|
470
|
+
|
|
474
471
|
return {
|
|
475
472
|
totalIssues: issues.length,
|
|
476
473
|
bySeverity,
|
|
477
474
|
byCategory,
|
|
478
475
|
score,
|
|
479
476
|
passed: score >= this.minScore,
|
|
480
|
-
recommendation: this.getRecommendation(score, issues)
|
|
477
|
+
recommendation: this.getRecommendation(score, issues),
|
|
481
478
|
};
|
|
482
479
|
}
|
|
483
|
-
|
|
480
|
+
|
|
484
481
|
/**
|
|
485
482
|
* Get recommendation based on score
|
|
486
483
|
* @private
|
|
487
484
|
*/
|
|
488
|
-
getRecommendation(score,
|
|
485
|
+
getRecommendation(score, _issues) {
|
|
489
486
|
if (score >= 90) return 'Excellent! Code quality is high.';
|
|
490
487
|
if (score >= 80) return 'Good. Minor improvements recommended.';
|
|
491
488
|
if (score >= 70) return 'Acceptable. Several issues should be addressed.';
|
|
492
489
|
if (score >= 50) return 'Needs work. Significant improvements required.';
|
|
493
490
|
return 'Critical issues detected. Immediate attention required.';
|
|
494
491
|
}
|
|
495
|
-
|
|
492
|
+
|
|
496
493
|
/**
|
|
497
494
|
* Get line number from position
|
|
498
495
|
* @private
|
|
@@ -500,7 +497,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
500
497
|
getLineNumber(code, position) {
|
|
501
498
|
return code.substring(0, position).split('\n').length;
|
|
502
499
|
}
|
|
503
|
-
|
|
500
|
+
|
|
504
501
|
/**
|
|
505
502
|
* Get line start position
|
|
506
503
|
* @private
|
|
@@ -513,7 +510,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
513
510
|
}
|
|
514
511
|
return start;
|
|
515
512
|
}
|
|
516
|
-
|
|
513
|
+
|
|
517
514
|
/**
|
|
518
515
|
* Find function end position
|
|
519
516
|
* @private
|
|
@@ -521,7 +518,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
521
518
|
findFunctionEnd(code, start) {
|
|
522
519
|
let depth = 0;
|
|
523
520
|
let inFunction = false;
|
|
524
|
-
|
|
521
|
+
|
|
525
522
|
for (let i = start; i < code.length; i++) {
|
|
526
523
|
if (code[i] === '{') {
|
|
527
524
|
depth++;
|
|
@@ -533,10 +530,10 @@ class CodeReviewer extends EventEmitter {
|
|
|
533
530
|
}
|
|
534
531
|
}
|
|
535
532
|
}
|
|
536
|
-
|
|
533
|
+
|
|
537
534
|
return code.length;
|
|
538
535
|
}
|
|
539
|
-
|
|
536
|
+
|
|
540
537
|
/**
|
|
541
538
|
* Detect language
|
|
542
539
|
* @private
|
|
@@ -549,19 +546,19 @@ class CodeReviewer extends EventEmitter {
|
|
|
549
546
|
'.ts': 'typescript',
|
|
550
547
|
'.py': 'python',
|
|
551
548
|
'.jsx': 'javascript',
|
|
552
|
-
'.tsx': 'typescript'
|
|
549
|
+
'.tsx': 'typescript',
|
|
553
550
|
};
|
|
554
551
|
return langMap[ext] || 'javascript';
|
|
555
552
|
}
|
|
556
|
-
|
|
553
|
+
|
|
557
554
|
// Detect from content
|
|
558
|
-
if (code.includes('def ') || code.includes('import ') && !code.includes(
|
|
555
|
+
if (code.includes('def ') || (code.includes('import ') && !code.includes("from '"))) {
|
|
559
556
|
return 'python';
|
|
560
557
|
}
|
|
561
|
-
|
|
558
|
+
|
|
562
559
|
return 'javascript';
|
|
563
560
|
}
|
|
564
|
-
|
|
561
|
+
|
|
565
562
|
/**
|
|
566
563
|
* Generate unique ID
|
|
567
564
|
* @private
|
|
@@ -569,7 +566,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
569
566
|
generateId() {
|
|
570
567
|
return `review-${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 6)}`;
|
|
571
568
|
}
|
|
572
|
-
|
|
569
|
+
|
|
573
570
|
/**
|
|
574
571
|
* Get review by ID
|
|
575
572
|
* @param {string} reviewId - Review identifier
|
|
@@ -578,7 +575,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
578
575
|
getReview(reviewId) {
|
|
579
576
|
return this.reviews.get(reviewId) || null;
|
|
580
577
|
}
|
|
581
|
-
|
|
578
|
+
|
|
582
579
|
/**
|
|
583
580
|
* Get all reviews
|
|
584
581
|
* @returns {ReviewResult[]}
|
|
@@ -586,7 +583,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
586
583
|
getAllReviews() {
|
|
587
584
|
return Array.from(this.reviews.values());
|
|
588
585
|
}
|
|
589
|
-
|
|
586
|
+
|
|
590
587
|
/**
|
|
591
588
|
* Get statistics
|
|
592
589
|
* @returns {Object}
|
|
@@ -594,16 +591,16 @@ class CodeReviewer extends EventEmitter {
|
|
|
594
591
|
getStats() {
|
|
595
592
|
const reviews = this.getAllReviews();
|
|
596
593
|
const scores = reviews.map(r => r.score);
|
|
597
|
-
|
|
594
|
+
|
|
598
595
|
return {
|
|
599
596
|
totalReviews: reviews.length,
|
|
600
597
|
averageScore: scores.length > 0 ? scores.reduce((a, b) => a + b, 0) / scores.length : 0,
|
|
601
598
|
passed: reviews.filter(r => r.summary.passed).length,
|
|
602
599
|
failed: reviews.filter(r => !r.summary.passed).length,
|
|
603
|
-
totalIssues: reviews.reduce((sum, r) => sum + r.issues.length, 0)
|
|
600
|
+
totalIssues: reviews.reduce((sum, r) => sum + r.issues.length, 0),
|
|
604
601
|
};
|
|
605
602
|
}
|
|
606
|
-
|
|
603
|
+
|
|
607
604
|
/**
|
|
608
605
|
* Add custom rule
|
|
609
606
|
* @param {string} language - Language
|
|
@@ -615,14 +612,14 @@ class CodeReviewer extends EventEmitter {
|
|
|
615
612
|
}
|
|
616
613
|
this.rules[language].push(rule);
|
|
617
614
|
}
|
|
618
|
-
|
|
615
|
+
|
|
619
616
|
/**
|
|
620
617
|
* Clear reviews
|
|
621
618
|
*/
|
|
622
619
|
clearReviews() {
|
|
623
620
|
this.reviews.clear();
|
|
624
621
|
}
|
|
625
|
-
|
|
622
|
+
|
|
626
623
|
/**
|
|
627
624
|
* Export review to markdown
|
|
628
625
|
* @param {string} reviewId - Review identifier
|
|
@@ -631,30 +628,30 @@ class CodeReviewer extends EventEmitter {
|
|
|
631
628
|
exportToMarkdown(reviewId) {
|
|
632
629
|
const review = this.getReview(reviewId);
|
|
633
630
|
if (!review) return '';
|
|
634
|
-
|
|
631
|
+
|
|
635
632
|
let md = `# Code Review Report\n\n`;
|
|
636
633
|
md += `**File:** ${review.filePath}\n`;
|
|
637
634
|
md += `**Language:** ${review.language}\n`;
|
|
638
635
|
md += `**Score:** ${review.score}/100 ${review.summary.passed ? '✅' : '❌'}\n\n`;
|
|
639
|
-
|
|
636
|
+
|
|
640
637
|
md += `## Summary\n\n`;
|
|
641
638
|
md += `${review.summary.recommendation}\n\n`;
|
|
642
639
|
md += `- Total Issues: ${review.issues.length}\n`;
|
|
643
640
|
for (const [severity, count] of Object.entries(review.summary.bySeverity)) {
|
|
644
641
|
md += `- ${severity}: ${count}\n`;
|
|
645
642
|
}
|
|
646
|
-
|
|
643
|
+
|
|
647
644
|
if (review.issues.length > 0) {
|
|
648
645
|
md += `\n## Issues\n\n`;
|
|
649
|
-
|
|
646
|
+
|
|
650
647
|
for (const issue of review.issues) {
|
|
651
648
|
const icon = {
|
|
652
649
|
[SEVERITY.INFO]: 'ℹ️',
|
|
653
650
|
[SEVERITY.WARNING]: '⚠️',
|
|
654
651
|
[SEVERITY.ERROR]: '❌',
|
|
655
|
-
[SEVERITY.CRITICAL]: '🚨'
|
|
652
|
+
[SEVERITY.CRITICAL]: '🚨',
|
|
656
653
|
}[issue.severity];
|
|
657
|
-
|
|
654
|
+
|
|
658
655
|
md += `### ${icon} ${issue.message}\n\n`;
|
|
659
656
|
md += `- **Severity:** ${issue.severity}\n`;
|
|
660
657
|
md += `- **Category:** ${issue.category}\n`;
|
|
@@ -663,7 +660,7 @@ class CodeReviewer extends EventEmitter {
|
|
|
663
660
|
md += `\n`;
|
|
664
661
|
}
|
|
665
662
|
}
|
|
666
|
-
|
|
663
|
+
|
|
667
664
|
return md;
|
|
668
665
|
}
|
|
669
666
|
}
|
|
@@ -694,5 +691,5 @@ module.exports = {
|
|
|
694
691
|
reviewCode,
|
|
695
692
|
SEVERITY,
|
|
696
693
|
CATEGORY,
|
|
697
|
-
DEFAULT_RULES
|
|
694
|
+
DEFAULT_RULES,
|
|
698
695
|
};
|
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
generateCode,
|
|
13
13
|
GEN_MODE,
|
|
14
14
|
LANGUAGE,
|
|
15
|
-
TEMPLATES
|
|
15
|
+
TEMPLATES,
|
|
16
16
|
} = require('./code-generator');
|
|
17
17
|
|
|
18
18
|
const {
|
|
@@ -21,7 +21,7 @@ const {
|
|
|
21
21
|
reviewCode,
|
|
22
22
|
SEVERITY,
|
|
23
23
|
CATEGORY,
|
|
24
|
-
DEFAULT_RULES
|
|
24
|
+
DEFAULT_RULES,
|
|
25
25
|
} = require('./code-reviewer');
|
|
26
26
|
|
|
27
27
|
module.exports = {
|
|
@@ -32,12 +32,12 @@ module.exports = {
|
|
|
32
32
|
GEN_MODE,
|
|
33
33
|
LANGUAGE,
|
|
34
34
|
TEMPLATES,
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
// Code Reviewer
|
|
37
37
|
CodeReviewer,
|
|
38
38
|
createCodeReviewer,
|
|
39
39
|
reviewCode,
|
|
40
40
|
SEVERITY,
|
|
41
41
|
CATEGORY,
|
|
42
|
-
DEFAULT_RULES
|
|
42
|
+
DEFAULT_RULES,
|
|
43
43
|
};
|