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
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MUSUBI Rust Migration Generator
|
|
3
|
+
*
|
|
4
|
+
* Analyzes C/C++ codebases and generates Rust migration plans:
|
|
5
|
+
* - Unsafe pattern detection
|
|
6
|
+
* - Security-critical component identification
|
|
7
|
+
* - Rust replacement priority scoring
|
|
8
|
+
* - Migration plan generation
|
|
9
|
+
*
|
|
10
|
+
* Based on GCC analysis: libssp, libbacktrace, libsanitizer, libvtv
|
|
11
|
+
*
|
|
12
|
+
* @version 5.5.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const fs = require('fs-extra');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { glob } = require('glob');
|
|
18
|
+
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Unsafe Pattern Categories
|
|
21
|
+
// ============================================================================
|
|
22
|
+
|
|
23
|
+
const UNSAFE_PATTERNS = {
|
|
24
|
+
memoryManagement: [
|
|
25
|
+
{ pattern: /\bmalloc\s*\(/g, risk: 'high', description: 'Manual memory allocation' },
|
|
26
|
+
{ pattern: /\bcalloc\s*\(/g, risk: 'high', description: 'Manual memory allocation' },
|
|
27
|
+
{ pattern: /\brealloc\s*\(/g, risk: 'high', description: 'Manual memory reallocation' },
|
|
28
|
+
{
|
|
29
|
+
pattern: /\bfree\s*\(/g,
|
|
30
|
+
risk: 'medium',
|
|
31
|
+
description: 'Manual memory deallocation (potential double-free)',
|
|
32
|
+
},
|
|
33
|
+
{ pattern: /\bnew\s+\w+\s*\[/g, risk: 'medium', description: 'Array new (prefer std::vector)' },
|
|
34
|
+
{ pattern: /\bdelete\s*\[/g, risk: 'medium', description: 'Array delete' },
|
|
35
|
+
],
|
|
36
|
+
bufferOverflow: [
|
|
37
|
+
{ pattern: /\bstrcpy\s*\(/g, risk: 'critical', description: 'Unbounded string copy' },
|
|
38
|
+
{ pattern: /\bstrcat\s*\(/g, risk: 'critical', description: 'Unbounded string concatenation' },
|
|
39
|
+
{ pattern: /\bsprintf\s*\(/g, risk: 'critical', description: 'Unbounded formatted output' },
|
|
40
|
+
{ pattern: /\bgets\s*\(/g, risk: 'critical', description: 'Unbounded input (deprecated)' },
|
|
41
|
+
{ pattern: /\bscanf\s*\([^,]*%s/g, risk: 'critical', description: 'Unbounded scanf string' },
|
|
42
|
+
{
|
|
43
|
+
pattern: /\bmemcpy\s*\(/g,
|
|
44
|
+
risk: 'medium',
|
|
45
|
+
description: 'Memory copy (needs size validation)',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
pattern: /\bmemmove\s*\(/g,
|
|
49
|
+
risk: 'medium',
|
|
50
|
+
description: 'Memory move (needs size validation)',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
pointerOperations: [
|
|
54
|
+
{ pattern: /\*\s*\(\s*\w+\s*\+/g, risk: 'high', description: 'Pointer arithmetic' },
|
|
55
|
+
{
|
|
56
|
+
pattern: /\[\s*-?\d+\s*\]/g,
|
|
57
|
+
risk: 'medium',
|
|
58
|
+
description: 'Array indexing (potential out-of-bounds)',
|
|
59
|
+
},
|
|
60
|
+
{ pattern: /reinterpret_cast/g, risk: 'high', description: 'Type-unsafe cast' },
|
|
61
|
+
{ pattern: /\(void\s*\*\)/g, risk: 'medium', description: 'Void pointer cast' },
|
|
62
|
+
{ pattern: /\*\*\w+/g, risk: 'medium', description: 'Double pointer' },
|
|
63
|
+
],
|
|
64
|
+
concurrency: [
|
|
65
|
+
{
|
|
66
|
+
pattern: /\bpthread_/g,
|
|
67
|
+
risk: 'medium',
|
|
68
|
+
description: 'POSIX threads (consider Rust std::thread)',
|
|
69
|
+
},
|
|
70
|
+
{ pattern: /\batomic_/g, risk: 'low', description: 'Atomic operations' },
|
|
71
|
+
{ pattern: /\bmutex/g, risk: 'low', description: 'Mutex usage' },
|
|
72
|
+
{
|
|
73
|
+
pattern: /\bvolatile\b/g,
|
|
74
|
+
risk: 'medium',
|
|
75
|
+
description: 'Volatile (often misused for concurrency)',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
formatString: [
|
|
79
|
+
{ pattern: /\bprintf\s*\(\s*\w+/g, risk: 'high', description: 'Format string from variable' },
|
|
80
|
+
{
|
|
81
|
+
pattern: /\bfprintf\s*\([^,]+,\s*\w+/g,
|
|
82
|
+
risk: 'high',
|
|
83
|
+
description: 'Format string from variable',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
pattern: /\bsyslog\s*\([^,]+,\s*\w+/g,
|
|
87
|
+
risk: 'high',
|
|
88
|
+
description: 'Syslog format string vulnerability',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
integerOverflow: [
|
|
92
|
+
{
|
|
93
|
+
pattern: /\+\+\w+\s*[<>=]/g,
|
|
94
|
+
risk: 'low',
|
|
95
|
+
description: 'Increment in comparison (potential overflow)',
|
|
96
|
+
},
|
|
97
|
+
{ pattern: /<<\s*\d{2,}/g, risk: 'medium', description: 'Large bit shift' },
|
|
98
|
+
{
|
|
99
|
+
pattern: /\bunsigned\s+\w+\s*-/g,
|
|
100
|
+
risk: 'medium',
|
|
101
|
+
description: 'Unsigned subtraction (potential underflow)',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// Security-Critical Component Patterns
|
|
108
|
+
// ============================================================================
|
|
109
|
+
|
|
110
|
+
const SECURITY_COMPONENTS = [
|
|
111
|
+
{ pattern: /ssp|stack.*smash|canary/i, component: 'Stack Protection', rustCrate: 'rust-ssp' },
|
|
112
|
+
{
|
|
113
|
+
pattern: /backtrace|stack.*trace|unwind/i,
|
|
114
|
+
component: 'Backtrace',
|
|
115
|
+
rustCrate: 'rust-backtrace',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
pattern: /sanitizer|asan|msan|tsan|ubsan/i,
|
|
119
|
+
component: 'Sanitizers',
|
|
120
|
+
rustCrate: 'rust-sanitizer',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
pattern: /vtv|vtable|virtual.*table/i,
|
|
124
|
+
component: 'VTable Verification',
|
|
125
|
+
rustCrate: 'rust-vtv',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
pattern: /crypt|encrypt|decrypt|cipher/i,
|
|
129
|
+
component: 'Cryptography',
|
|
130
|
+
rustCrate: 'ring or rustcrypto',
|
|
131
|
+
},
|
|
132
|
+
{ pattern: /auth|login|password|credential/i, component: 'Authentication', rustCrate: 'argon2' },
|
|
133
|
+
{ pattern: /parse|lexer|tokenize/i, component: 'Parser', rustCrate: 'nom or pest' },
|
|
134
|
+
{ pattern: /network|socket|tcp|udp|http/i, component: 'Networking', rustCrate: 'tokio' },
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// Rust Migration Generator
|
|
139
|
+
// ============================================================================
|
|
140
|
+
|
|
141
|
+
class RustMigrationGenerator {
|
|
142
|
+
constructor(workspaceRoot, options = {}) {
|
|
143
|
+
this.workspaceRoot = workspaceRoot;
|
|
144
|
+
this.options = {
|
|
145
|
+
excludePatterns: [
|
|
146
|
+
'node_modules/**',
|
|
147
|
+
'vendor/**',
|
|
148
|
+
'third_party/**',
|
|
149
|
+
'.git/**',
|
|
150
|
+
'build/**',
|
|
151
|
+
'test/**',
|
|
152
|
+
],
|
|
153
|
+
...options,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Analyze codebase for Rust migration candidates
|
|
159
|
+
*/
|
|
160
|
+
async analyze() {
|
|
161
|
+
const files = await this.findCppFiles();
|
|
162
|
+
|
|
163
|
+
console.log(`📊 Analyzing ${files.length} C/C++ files for Rust migration...`);
|
|
164
|
+
|
|
165
|
+
const analysis = {
|
|
166
|
+
timestamp: new Date().toISOString(),
|
|
167
|
+
totalFiles: files.length,
|
|
168
|
+
fileAnalyses: [],
|
|
169
|
+
unsafePatterns: [],
|
|
170
|
+
securityComponents: [],
|
|
171
|
+
priorities: [],
|
|
172
|
+
summary: {},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
for (const file of files) {
|
|
176
|
+
const fileAnalysis = await this.analyzeFile(file);
|
|
177
|
+
if (fileAnalysis) {
|
|
178
|
+
analysis.fileAnalyses.push(fileAnalysis);
|
|
179
|
+
analysis.unsafePatterns.push(...fileAnalysis.unsafePatterns);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Identify security-critical components
|
|
184
|
+
analysis.securityComponents = this.identifySecurityComponents(analysis.fileAnalyses);
|
|
185
|
+
|
|
186
|
+
// Calculate priorities
|
|
187
|
+
analysis.priorities = this.calculatePriorities(analysis.fileAnalyses);
|
|
188
|
+
|
|
189
|
+
// Generate summary
|
|
190
|
+
analysis.summary = this.generateSummary(analysis);
|
|
191
|
+
|
|
192
|
+
return analysis;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Find all C/C++ files
|
|
197
|
+
*/
|
|
198
|
+
async findCppFiles() {
|
|
199
|
+
const patterns = ['**/*.c', '**/*.cpp', '**/*.cc', '**/*.h', '**/*.hpp'];
|
|
200
|
+
let allFiles = [];
|
|
201
|
+
|
|
202
|
+
for (const pattern of patterns) {
|
|
203
|
+
const files = await glob(pattern, {
|
|
204
|
+
cwd: this.workspaceRoot,
|
|
205
|
+
ignore: this.options.excludePatterns,
|
|
206
|
+
nodir: true,
|
|
207
|
+
absolute: true,
|
|
208
|
+
});
|
|
209
|
+
allFiles = allFiles.concat(files);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return allFiles;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Analyze a single file
|
|
217
|
+
*/
|
|
218
|
+
async analyzeFile(filePath) {
|
|
219
|
+
try {
|
|
220
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
221
|
+
const relativePath = path.relative(this.workspaceRoot, filePath);
|
|
222
|
+
const lines = content.split('\n').length;
|
|
223
|
+
|
|
224
|
+
const analysis = {
|
|
225
|
+
path: relativePath,
|
|
226
|
+
absolutePath: filePath,
|
|
227
|
+
lines,
|
|
228
|
+
unsafePatterns: [],
|
|
229
|
+
riskScore: 0,
|
|
230
|
+
rustBenefit: 'low',
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// Check for unsafe patterns
|
|
234
|
+
for (const [category, patterns] of Object.entries(UNSAFE_PATTERNS)) {
|
|
235
|
+
for (const { pattern, risk, description } of patterns) {
|
|
236
|
+
const matches = content.match(pattern);
|
|
237
|
+
if (matches && matches.length > 0) {
|
|
238
|
+
analysis.unsafePatterns.push({
|
|
239
|
+
category,
|
|
240
|
+
pattern: pattern.source,
|
|
241
|
+
risk,
|
|
242
|
+
description,
|
|
243
|
+
occurrences: matches.length,
|
|
244
|
+
file: relativePath,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// Add to risk score
|
|
248
|
+
const riskWeights = { critical: 10, high: 5, medium: 2, low: 1 };
|
|
249
|
+
analysis.riskScore += (riskWeights[risk] || 1) * matches.length;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Calculate Rust benefit
|
|
255
|
+
if (analysis.riskScore >= 50) {
|
|
256
|
+
analysis.rustBenefit = 'critical';
|
|
257
|
+
} else if (analysis.riskScore >= 20) {
|
|
258
|
+
analysis.rustBenefit = 'high';
|
|
259
|
+
} else if (analysis.riskScore >= 10) {
|
|
260
|
+
analysis.rustBenefit = 'medium';
|
|
261
|
+
} else if (analysis.riskScore > 0) {
|
|
262
|
+
analysis.rustBenefit = 'low';
|
|
263
|
+
} else {
|
|
264
|
+
analysis.rustBenefit = 'minimal';
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return analysis;
|
|
268
|
+
} catch (error) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Identify security-critical components
|
|
275
|
+
*/
|
|
276
|
+
identifySecurityComponents(fileAnalyses) {
|
|
277
|
+
const components = [];
|
|
278
|
+
|
|
279
|
+
for (const analysis of fileAnalyses) {
|
|
280
|
+
for (const { pattern, component, rustCrate } of SECURITY_COMPONENTS) {
|
|
281
|
+
if (pattern.test(analysis.path)) {
|
|
282
|
+
const existing = components.find(c => c.component === component);
|
|
283
|
+
if (existing) {
|
|
284
|
+
existing.files.push(analysis.path);
|
|
285
|
+
existing.totalRiskScore += analysis.riskScore;
|
|
286
|
+
} else {
|
|
287
|
+
components.push({
|
|
288
|
+
component,
|
|
289
|
+
rustCrate,
|
|
290
|
+
files: [analysis.path],
|
|
291
|
+
totalRiskScore: analysis.riskScore,
|
|
292
|
+
priority: analysis.riskScore >= 20 ? 'high' : 'medium',
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return components.sort((a, b) => b.totalRiskScore - a.totalRiskScore);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Calculate migration priorities
|
|
304
|
+
*/
|
|
305
|
+
calculatePriorities(fileAnalyses) {
|
|
306
|
+
return fileAnalyses
|
|
307
|
+
.filter(f => f.riskScore > 0)
|
|
308
|
+
.sort((a, b) => b.riskScore - a.riskScore)
|
|
309
|
+
.slice(0, 50)
|
|
310
|
+
.map((f, index) => ({
|
|
311
|
+
rank: index + 1,
|
|
312
|
+
file: f.path,
|
|
313
|
+
riskScore: f.riskScore,
|
|
314
|
+
rustBenefit: f.rustBenefit,
|
|
315
|
+
unsafePatternCount: f.unsafePatterns.length,
|
|
316
|
+
topIssues: f.unsafePatterns
|
|
317
|
+
.sort((a, b) => {
|
|
318
|
+
const weights = { critical: 4, high: 3, medium: 2, low: 1 };
|
|
319
|
+
return weights[b.risk] - weights[a.risk];
|
|
320
|
+
})
|
|
321
|
+
.slice(0, 3)
|
|
322
|
+
.map(p => `${p.category}: ${p.description}`),
|
|
323
|
+
}));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Generate summary
|
|
328
|
+
*/
|
|
329
|
+
generateSummary(analysis) {
|
|
330
|
+
const riskDistribution = { critical: 0, high: 0, medium: 0, low: 0, minimal: 0 };
|
|
331
|
+
|
|
332
|
+
for (const file of analysis.fileAnalyses) {
|
|
333
|
+
riskDistribution[file.rustBenefit]++;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const patternDistribution = {};
|
|
337
|
+
for (const pattern of analysis.unsafePatterns) {
|
|
338
|
+
patternDistribution[pattern.category] =
|
|
339
|
+
(patternDistribution[pattern.category] || 0) + pattern.occurrences;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return {
|
|
343
|
+
totalFiles: analysis.totalFiles,
|
|
344
|
+
filesWithIssues: analysis.fileAnalyses.filter(f => f.riskScore > 0).length,
|
|
345
|
+
totalUnsafePatterns: analysis.unsafePatterns.reduce((sum, p) => sum + p.occurrences, 0),
|
|
346
|
+
riskDistribution,
|
|
347
|
+
patternDistribution,
|
|
348
|
+
securityComponentsFound: analysis.securityComponents.length,
|
|
349
|
+
estimatedMigrationEffort: this.estimateMigrationEffort(analysis),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Estimate migration effort
|
|
355
|
+
*/
|
|
356
|
+
estimateMigrationEffort(analysis) {
|
|
357
|
+
const highPriorityFiles = analysis.priorities.filter(
|
|
358
|
+
p => p.rustBenefit === 'critical' || p.rustBenefit === 'high'
|
|
359
|
+
).length;
|
|
360
|
+
const totalLines = analysis.fileAnalyses.reduce((sum, f) => sum + f.lines, 0);
|
|
361
|
+
|
|
362
|
+
// Rough estimation: 1 day per 500 lines for high-risk files
|
|
363
|
+
const days = Math.ceil(totalLines / 500);
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
estimatedDays: days,
|
|
367
|
+
highPriorityFiles,
|
|
368
|
+
recommendation:
|
|
369
|
+
highPriorityFiles > 10
|
|
370
|
+
? 'Consider phased migration starting with security-critical components'
|
|
371
|
+
: 'Direct migration feasible',
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Generate migration plan
|
|
377
|
+
*/
|
|
378
|
+
async generateMigrationPlan(analysis) {
|
|
379
|
+
const plan = {
|
|
380
|
+
title: 'Rust Migration Plan',
|
|
381
|
+
generatedAt: new Date().toISOString(),
|
|
382
|
+
phases: [],
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
// Phase 1: Security-critical components
|
|
386
|
+
if (analysis.securityComponents.length > 0) {
|
|
387
|
+
plan.phases.push({
|
|
388
|
+
phase: 1,
|
|
389
|
+
name: 'Security-Critical Components',
|
|
390
|
+
description: 'Migrate security-sensitive code first for immediate safety improvements',
|
|
391
|
+
components: analysis.securityComponents.map(c => ({
|
|
392
|
+
component: c.component,
|
|
393
|
+
suggestedCrate: c.rustCrate,
|
|
394
|
+
files: c.files.slice(0, 10),
|
|
395
|
+
priority: c.priority,
|
|
396
|
+
})),
|
|
397
|
+
estimatedEffort: '2-4 weeks',
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Phase 2: High-risk files
|
|
402
|
+
const highRisk = analysis.priorities.filter(p => p.rustBenefit === 'critical');
|
|
403
|
+
if (highRisk.length > 0) {
|
|
404
|
+
plan.phases.push({
|
|
405
|
+
phase: 2,
|
|
406
|
+
name: 'High-Risk File Migration',
|
|
407
|
+
description: 'Migrate files with critical unsafe patterns',
|
|
408
|
+
files: highRisk.slice(0, 20).map(f => ({
|
|
409
|
+
file: f.file,
|
|
410
|
+
riskScore: f.riskScore,
|
|
411
|
+
topIssues: f.topIssues,
|
|
412
|
+
})),
|
|
413
|
+
estimatedEffort: '4-8 weeks',
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Phase 3: Medium-risk files
|
|
418
|
+
const mediumRisk = analysis.priorities.filter(
|
|
419
|
+
p => p.rustBenefit === 'high' || p.rustBenefit === 'medium'
|
|
420
|
+
);
|
|
421
|
+
if (mediumRisk.length > 0) {
|
|
422
|
+
plan.phases.push({
|
|
423
|
+
phase: 3,
|
|
424
|
+
name: 'Medium-Risk File Migration',
|
|
425
|
+
description: 'Migrate remaining files with notable unsafe patterns',
|
|
426
|
+
fileCount: mediumRisk.length,
|
|
427
|
+
estimatedEffort: '8-16 weeks',
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Phase 4: Integration and testing
|
|
432
|
+
plan.phases.push({
|
|
433
|
+
phase: plan.phases.length + 1,
|
|
434
|
+
name: 'Integration and Testing',
|
|
435
|
+
description: 'Integrate Rust components with existing codebase via FFI',
|
|
436
|
+
tasks: [
|
|
437
|
+
'Create FFI bindings between Rust and C/C++',
|
|
438
|
+
'Write comprehensive test suites',
|
|
439
|
+
'Performance benchmarking',
|
|
440
|
+
'Gradual rollout with feature flags',
|
|
441
|
+
],
|
|
442
|
+
estimatedEffort: '2-4 weeks',
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
return plan;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Generate markdown report
|
|
450
|
+
*/
|
|
451
|
+
generateReport(analysis) {
|
|
452
|
+
let report = '# Rust Migration Analysis Report\n\n';
|
|
453
|
+
report += `**Generated**: ${analysis.timestamp}\n`;
|
|
454
|
+
report += `**Repository**: ${this.workspaceRoot}\n\n`;
|
|
455
|
+
|
|
456
|
+
report += '## Executive Summary\n\n';
|
|
457
|
+
report += `- **Total C/C++ Files**: ${analysis.summary.totalFiles.toLocaleString()}\n`;
|
|
458
|
+
report += `- **Files with Issues**: ${analysis.summary.filesWithIssues.toLocaleString()}\n`;
|
|
459
|
+
report += `- **Total Unsafe Patterns**: ${analysis.summary.totalUnsafePatterns.toLocaleString()}\n`;
|
|
460
|
+
report += `- **Security Components Found**: ${analysis.summary.securityComponentsFound}\n`;
|
|
461
|
+
report += `- **Estimated Migration Effort**: ${analysis.summary.estimatedMigrationEffort.estimatedDays} days\n\n`;
|
|
462
|
+
|
|
463
|
+
report += '## Risk Distribution\n\n';
|
|
464
|
+
report += '| Risk Level | File Count |\n|------------|------------|\n';
|
|
465
|
+
for (const [level, count] of Object.entries(analysis.summary.riskDistribution)) {
|
|
466
|
+
report += `| ${level} | ${count} |\n`;
|
|
467
|
+
}
|
|
468
|
+
report += '\n';
|
|
469
|
+
|
|
470
|
+
report += '## Unsafe Pattern Distribution\n\n';
|
|
471
|
+
report += '| Category | Occurrences |\n|----------|-------------|\n';
|
|
472
|
+
for (const [category, count] of Object.entries(analysis.summary.patternDistribution)) {
|
|
473
|
+
report += `| ${category} | ${count} |\n`;
|
|
474
|
+
}
|
|
475
|
+
report += '\n';
|
|
476
|
+
|
|
477
|
+
if (analysis.securityComponents.length > 0) {
|
|
478
|
+
report += '## Security-Critical Components\n\n';
|
|
479
|
+
report +=
|
|
480
|
+
'| Component | Suggested Rust Crate | Files | Risk Score |\n|-----------|---------------------|-------|------------|\n';
|
|
481
|
+
for (const comp of analysis.securityComponents) {
|
|
482
|
+
report += `| ${comp.component} | ${comp.rustCrate} | ${comp.files.length} | ${comp.totalRiskScore} |\n`;
|
|
483
|
+
}
|
|
484
|
+
report += '\n';
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
report += '## Top 20 Migration Priorities\n\n';
|
|
488
|
+
report +=
|
|
489
|
+
'| Rank | File | Risk Score | Rust Benefit | Top Issues |\n|------|------|------------|--------------|------------|\n';
|
|
490
|
+
for (const p of analysis.priorities.slice(0, 20)) {
|
|
491
|
+
const issues = p.topIssues.join('; ').substring(0, 50);
|
|
492
|
+
report += `| ${p.rank} | ${p.file} | ${p.riskScore} | ${p.rustBenefit} | ${issues}... |\n`;
|
|
493
|
+
}
|
|
494
|
+
report += '\n';
|
|
495
|
+
|
|
496
|
+
report += '## Recommendations\n\n';
|
|
497
|
+
report +=
|
|
498
|
+
'1. **Start with Security Components**: Migrate stack protection, sanitizers, and authentication code first\n';
|
|
499
|
+
report +=
|
|
500
|
+
'2. **Use Safe Abstractions**: Replace raw pointers with Rust references, Box, Rc, or Arc\n';
|
|
501
|
+
report +=
|
|
502
|
+
'3. **Leverage Rust Libraries**: Use well-tested crates like `ring` for crypto, `tokio` for async\n';
|
|
503
|
+
report +=
|
|
504
|
+
'4. **FFI Bridge**: Create a clean C-compatible interface between Rust and existing C++ code\n';
|
|
505
|
+
report +=
|
|
506
|
+
'5. **Incremental Migration**: Migrate one component at a time with thorough testing\n';
|
|
507
|
+
|
|
508
|
+
return report;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
module.exports = { RustMigrationGenerator, UNSAFE_PATTERNS, SECURITY_COMPONENTS };
|