bmad-plus 0.9.0 → 0.9.2
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/CHANGELOG.md +36 -0
- package/LICENSE +21 -21
- package/README.md +106 -86
- package/osint-agent-package/README.md +88 -88
- package/osint-agent-package/SETUP_KEYS.md +108 -108
- package/osint-agent-package/agents/osint-investigator.md +80 -80
- package/osint-agent-package/install.ps1 +87 -87
- package/osint-agent-package/install.sh +76 -76
- package/osint-agent-package/skills/bmad-osint-investigate/SKILL.md +147 -147
- package/osint-agent-package/skills/bmad-osint-investigate/osint/references/enrichment-databases-fr.md +148 -148
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/_http.py +101 -101
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/apify.py +266 -266
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/brightdata.py +101 -101
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/diagnose.py +141 -141
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/exa.py +79 -79
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/jina.py +71 -71
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/parallel.py +85 -85
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/perplexity.py +102 -102
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/tavily.py +72 -72
- package/osint-agent-package/skills/bmad-osint-investigate/osint/scripts/volley.py +208 -208
- package/osint-agent-package/skills/bmad-osint-investigator/SKILL.md +15 -15
- package/package.json +30 -3
- package/readme-international/README.de.md +8 -3
- package/readme-international/README.es.md +8 -3
- package/readme-international/README.fr.md +8 -3
- package/src/bmad-plus/agents/agent-architect-dev/SKILL.md +96 -96
- package/src/bmad-plus/agents/agent-architect-dev/bmad-skill-manifest.yaml +13 -13
- package/src/bmad-plus/agents/agent-maker/SKILL.md +201 -201
- package/src/bmad-plus/agents/agent-maker/bmad-skill-manifest.yaml +13 -13
- package/src/bmad-plus/agents/agent-orchestrator/SKILL.md +137 -137
- package/src/bmad-plus/agents/agent-orchestrator/bmad-skill-manifest.yaml +13 -13
- package/src/bmad-plus/agents/agent-quality/SKILL.md +83 -83
- package/src/bmad-plus/agents/agent-quality/bmad-skill-manifest.yaml +13 -13
- package/src/bmad-plus/agents/agent-shadow/SKILL.md +71 -71
- package/src/bmad-plus/agents/agent-shadow/bmad-skill-manifest.yaml +13 -13
- package/src/bmad-plus/agents/agent-strategist/SKILL.md +80 -80
- package/src/bmad-plus/agents/agent-strategist/bmad-skill-manifest.yaml +13 -13
- package/src/bmad-plus/data/role-triggers.yaml +209 -209
- package/src/bmad-plus/module-help.csv +10 -10
- package/src/bmad-plus/packs/pack-memory/README.md +106 -106
- package/src/bmad-plus/packs/pack-memory/memory-orchestrator.md +79 -79
- package/src/bmad-plus/packs/pack-memory/shared/karpathy-guardrails.md +86 -86
- package/src/bmad-plus/packs/pack-memory/shared/memory-protocol.md +143 -143
- package/src/bmad-plus/packs/pack-memory/templates/context.md +39 -39
- package/src/bmad-plus/packs/pack-memory/templates/decisions.md +25 -25
- package/src/bmad-plus/packs/pack-memory/templates/identity.yaml +39 -39
- package/src/bmad-plus/packs/pack-memory/templates/lessons.md +31 -31
- package/src/bmad-plus/packs/pack-memory/templates/patterns.md +24 -24
- package/src/bmad-plus/packs/pack-memory/templates/session-handoff.md +25 -25
- package/src/bmad-plus/packs/pack-memory/zecher-agent.md +157 -157
- package/src/bmad-plus/packs/pack-seo/bmad-skill-manifest.yaml +13 -13
- package/src/bmad-plus/packs/pack-shield/README.md +110 -110
- package/src/bmad-plus/packs/pack-shield/SKILL.md +82 -82
- package/src/bmad-plus/packs/pack-shield/categories/accessibility-esg/csrd-agent.md +251 -251
- package/src/bmad-plus/packs/pack-shield/categories/accessibility-esg/section508-agent.md +168 -168
- package/src/bmad-plus/packs/pack-shield/categories/accessibility-esg/wcag-agent.md +190 -190
- package/src/bmad-plus/packs/pack-shield/categories/ai-governance/eu-ai-act-agent.md +86 -86
- package/src/bmad-plus/packs/pack-shield/categories/ai-governance/iso42001-agent.md +240 -240
- package/src/bmad-plus/packs/pack-shield/categories/ai-governance/nist-ai-rmf-agent.md +122 -122
- package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/cis-controls-agent.md +210 -210
- package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/ism-agent.md +139 -139
- package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/iso27001-agent.md +156 -156
- package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/nis2-agent.md +72 -72
- package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/nist-800-53-agent.md +239 -239
- package/src/bmad-plus/packs/pack-shield/categories/cybersecurity/nist-csf-agent.md +207 -207
- package/src/bmad-plus/packs/pack-shield/categories/data-privacy/ccpa-agent.md +94 -94
- package/src/bmad-plus/packs/pack-shield/categories/data-privacy/dpdpa-agent.md +136 -136
- package/src/bmad-plus/packs/pack-shield/categories/data-privacy/gdpr-agent.md +296 -296
- package/src/bmad-plus/packs/pack-shield/categories/data-privacy/iso27701-agent.md +134 -134
- package/src/bmad-plus/packs/pack-shield/categories/data-privacy/lgpd-agent.md +129 -129
- package/src/bmad-plus/packs/pack-shield/categories/defense-export/cmmc-agent.md +116 -116
- package/src/bmad-plus/packs/pack-shield/categories/defense-export/ear-agent.md +261 -261
- package/src/bmad-plus/packs/pack-shield/categories/defense-export/itar-agent.md +191 -191
- package/src/bmad-plus/packs/pack-shield/categories/defense-export/tsa-agent.md +356 -356
- package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/dora-agent.md +499 -499
- package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/fedramp-agent.md +236 -236
- package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/hipaa-agent.md +162 -162
- package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/pci-dss-agent.md +228 -228
- package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/soc2-agent.md +255 -255
- package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/swift-csp-agent.md +153 -153
- package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-classifier.md +131 -131
- package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-fria.md +155 -155
- package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-incidents.md +187 -187
- package/src/bmad-plus/packs/pack-shield/categories/workflows/ai-act-roles.md +113 -113
- package/src/bmad-plus/packs/pack-shield/categories/workflows/breach-sentinel.md +197 -197
- package/src/bmad-plus/packs/pack-shield/categories/workflows/cookie-policy-gen.md +180 -180
- package/src/bmad-plus/packs/pack-shield/categories/workflows/dpia-sentinel.md +235 -235
- package/src/bmad-plus/packs/pack-shield/categories/workflows/legitimate-interest.md +159 -159
- package/src/bmad-plus/packs/pack-shield/categories/workflows/privacy-advisor.md +133 -133
- package/src/bmad-plus/packs/pack-shield/categories/workflows/privacy-notice-gen.md +160 -160
- package/src/bmad-plus/packs/pack-shield/categories/workflows/privacy-policy-gen.md +135 -135
- package/src/bmad-plus/packs/pack-shield/references/ccpa/ccpa-gdpr-comparison.md +117 -117
- package/src/bmad-plus/packs/pack-shield/references/ccpa/consumer-rights-workflows.md +177 -177
- package/src/bmad-plus/packs/pack-shield/references/cis-controls/framework-mappings.md +162 -162
- package/src/bmad-plus/packs/pack-shield/references/cis-controls/implementation-guidance.md +235 -235
- package/src/bmad-plus/packs/pack-shield/references/cis-controls/safeguards-detail.md +252 -252
- package/src/bmad-plus/packs/pack-shield/references/cmmc/cmmc-assessment.md +170 -170
- package/src/bmad-plus/packs/pack-shield/references/cmmc/cmmc-levels.md +113 -113
- package/src/bmad-plus/packs/pack-shield/references/cmmc/cmmc-practices.md +211 -211
- package/src/bmad-plus/packs/pack-shield/references/csrd/compliance-program.md +281 -281
- package/src/bmad-plus/packs/pack-shield/references/csrd/double-materiality.md +253 -253
- package/src/bmad-plus/packs/pack-shield/references/csrd/esrs-standards.md +401 -401
- package/src/bmad-plus/packs/pack-shield/references/dora/article-reference.md +441 -441
- package/src/bmad-plus/packs/pack-shield/references/dora/incident-classification.md +297 -297
- package/src/bmad-plus/packs/pack-shield/references/dora/rts-its-guide.md +306 -306
- package/src/bmad-plus/packs/pack-shield/references/dora/third-party-risk.md +349 -349
- package/src/bmad-plus/packs/pack-shield/references/dpdpa/gdpr-comparison.md +173 -173
- package/src/bmad-plus/packs/pack-shield/references/dpdpa/rights-and-obligations.md +426 -426
- package/src/bmad-plus/packs/pack-shield/references/dpdpa/rules-2025.md +599 -599
- package/src/bmad-plus/packs/pack-shield/references/dpdpa/sections-reference.md +319 -319
- package/src/bmad-plus/packs/pack-shield/references/ear/ccl-eccn-guide.md +250 -250
- package/src/bmad-plus/packs/pack-shield/references/ear/compliance-program.md +280 -280
- package/src/bmad-plus/packs/pack-shield/references/ear/license-exceptions.md +207 -207
- package/src/bmad-plus/packs/pack-shield/references/eu-ai-act/gpai-governance.md +267 -267
- package/src/bmad-plus/packs/pack-shield/references/eu-ai-act/obligations-high-risk.md +287 -287
- package/src/bmad-plus/packs/pack-shield/references/eu-ai-act/risk-classification.md +182 -182
- package/src/bmad-plus/packs/pack-shield/references/fedramp/appendices-guide.md +209 -209
- package/src/bmad-plus/packs/pack-shield/references/fedramp/control-families.md +281 -281
- package/src/bmad-plus/packs/pack-shield/references/fedramp/poam-guide.md +93 -93
- package/src/bmad-plus/packs/pack-shield/references/fedramp/readiness-checklist.md +134 -134
- package/src/bmad-plus/packs/pack-shield/references/fedramp/sap-sar-guide.md +86 -86
- package/src/bmad-plus/packs/pack-shield/references/fedramp/ssp-guide.md +129 -129
- package/src/bmad-plus/packs/pack-shield/references/gdpr-compliance/documents.md +192 -192
- package/src/bmad-plus/packs/pack-shield/references/gdpr-compliance/dpa-template.md +121 -121
- package/src/bmad-plus/packs/pack-shield/references/gdpr-compliance/privacy-notice.md +87 -87
- package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/breach-notification.md +293 -293
- package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/privacy-rule.md +276 -276
- package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/security-rule.md +299 -299
- package/src/bmad-plus/packs/pack-shield/references/hipaa-compliance/templates.md +568 -568
- package/src/bmad-plus/packs/pack-shield/references/ism/control-applicability.md +181 -181
- package/src/bmad-plus/packs/pack-shield/references/ism/guidelines-overview.md +183 -183
- package/src/bmad-plus/packs/pack-shield/references/iso27001/annex-a-2013.md +203 -203
- package/src/bmad-plus/packs/pack-shield/references/iso27001/annex-a-2022.md +132 -132
- package/src/bmad-plus/packs/pack-shield/references/iso27001/control-mapping.md +153 -153
- package/src/bmad-plus/packs/pack-shield/references/iso27701/annex-a-controls.md +195 -195
- package/src/bmad-plus/packs/pack-shield/references/iso27701/regulatory-mapping.md +229 -229
- package/src/bmad-plus/packs/pack-shield/references/iso27701/transition-guide.md +219 -219
- package/src/bmad-plus/packs/pack-shield/references/iso42001/iso42001-ai-risk-assessment.md +258 -258
- package/src/bmad-plus/packs/pack-shield/references/iso42001/iso42001-clauses-requirements.md +279 -279
- package/src/bmad-plus/packs/pack-shield/references/iso42001/iso42001-controls-annex-a.md +155 -155
- package/src/bmad-plus/packs/pack-shield/references/itar/compliance-program.md +174 -174
- package/src/bmad-plus/packs/pack-shield/references/itar/licensing-guide.md +146 -146
- package/src/bmad-plus/packs/pack-shield/references/itar/usml-categories.md +93 -93
- package/src/bmad-plus/packs/pack-shield/references/lgpd/anpd-enforcement.md +147 -147
- package/src/bmad-plus/packs/pack-shield/references/lgpd/compliance-program.md +272 -272
- package/src/bmad-plus/packs/pack-shield/references/lgpd/lgpd-articles.md +271 -271
- package/src/bmad-plus/packs/pack-shield/references/nis2/article-21-measures.md +153 -153
- package/src/bmad-plus/packs/pack-shield/references/nis2/iso27001-nis2-mapping.md +68 -68
- package/src/bmad-plus/packs/pack-shield/references/nist-800-53/assessment-rmf.md +349 -349
- package/src/bmad-plus/packs/pack-shield/references/nist-800-53/baselines-tailoring.md +277 -277
- package/src/bmad-plus/packs/pack-shield/references/nist-800-53/control-families.md +450 -450
- package/src/bmad-plus/packs/pack-shield/references/nist-ai-rmf/rmf-core.md +361 -361
- package/src/bmad-plus/packs/pack-shield/references/nist-ai-rmf/rmf-profiles.md +192 -192
- package/src/bmad-plus/packs/pack-shield/references/nist-csf/csf-10-to-20-mapping.md +143 -143
- package/src/bmad-plus/packs/pack-shield/references/nist-csf/csf-20-functions-categories.md +278 -278
- package/src/bmad-plus/packs/pack-shield/references/nist-csf/csf-implementation-tiers.md +135 -135
- package/src/bmad-plus/packs/pack-shield/references/pci-compliance/pci-dss-requirements.md +366 -366
- package/src/bmad-plus/packs/pack-shield/references/pci-compliance/pci-dss-saq-guide.md +217 -217
- package/src/bmad-plus/packs/pack-shield/references/pci-compliance/pci-dss-v4-changes.md +190 -190
- package/src/bmad-plus/packs/pack-shield/references/section-508/wcag-mapping.md +160 -160
- package/src/bmad-plus/packs/pack-shield/references/soc2/controls.md +241 -241
- package/src/bmad-plus/packs/pack-shield/references/soc2/evidence.md +236 -236
- package/src/bmad-plus/packs/pack-shield/references/soc2/policies.md +254 -254
- package/src/bmad-plus/packs/pack-shield/references/soc2/vendor.md +276 -276
- package/src/bmad-plus/packs/pack-shield/references/swift-csp/swift-assessment.md +202 -202
- package/src/bmad-plus/packs/pack-shield/references/swift-csp/swift-controls.md +545 -545
- package/src/bmad-plus/packs/pack-shield/references/tsa-compliance/tsa-crmp-requirements.md +359 -359
- package/src/bmad-plus/packs/pack-shield/references/tsa-compliance/tsa-directives-overview.md +187 -187
- package/src/bmad-plus/packs/pack-shield/references/tsa-compliance/tsa-incident-reporting.md +187 -187
- package/src/bmad-plus/packs/pack-shield/references/wcag/criteria-detail.md +510 -510
- package/src/bmad-plus/packs/pack-shield/shared/audit-report-template.md +103 -103
- package/src/bmad-plus/packs/pack-shield/shared/cross-framework-mapper.md +103 -103
- package/src/bmad-plus/packs/pack-shield/shared/gap-analysis-template.md +83 -83
- package/src/bmad-plus/packs/pack-shield/shield-orchestrator.md +229 -229
- package/src/bmad-plus/packs/pack-shield/upstream-sync.yaml +68 -68
- package/src/bmad-plus/skills/bmad-plus-autopilot/SKILL.md +99 -99
- package/src/bmad-plus/skills/bmad-plus-parallel/SKILL.md +93 -93
- package/src/bmad-plus/skills/bmad-plus-sync/SKILL.md +69 -69
- package/tools/cli/bmad-plus-cli.js +5 -3
- package/tools/cli/commands/autoconfig.js +23 -59
- package/tools/cli/commands/doctor.js +14 -0
- package/tools/cli/commands/install.js +29 -128
- package/tools/cli/commands/memory.js +1 -0
- package/tools/cli/commands/scan.js +44 -42
- package/tools/cli/commands/uninstall.js +10 -5
- package/tools/cli/commands/update.js +21 -3
- package/tools/cli/lib/ide-config.js +259 -0
- package/tools/cli/lib/memory-init.js +0 -1
- package/tools/cli/lib/pack-copy.js +84 -84
- package/tools/cli/lib/packs.js +16 -8
- package/tools/cli/lib/stack-detect.js +102 -0
- package/tools/cli/lib/validate.js +50 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD+ IDE Configuration Generator
|
|
3
|
+
* Extracted from install.js for modularity.
|
|
4
|
+
* Generates CLAUDE.md, GEMINI.md, AGENTS.md content with pack-aware agent filtering.
|
|
5
|
+
*
|
|
6
|
+
* Author: Laurent Rochetta
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// ── IDE Configurations ──
|
|
10
|
+
|
|
11
|
+
const IDE_CONFIGS = {
|
|
12
|
+
'claude-code': {
|
|
13
|
+
name: 'Claude Code',
|
|
14
|
+
detect: ['.claude'],
|
|
15
|
+
configFile: 'CLAUDE.md',
|
|
16
|
+
},
|
|
17
|
+
'gemini-cli': {
|
|
18
|
+
name: 'Gemini CLI',
|
|
19
|
+
detect: ['.gemini'],
|
|
20
|
+
configFile: 'GEMINI.md',
|
|
21
|
+
},
|
|
22
|
+
'codex-cli': {
|
|
23
|
+
name: 'Codex CLI / OpenCode',
|
|
24
|
+
detect: ['.codex', '.opencode'],
|
|
25
|
+
configFile: 'AGENTS.md',
|
|
26
|
+
},
|
|
27
|
+
'antigravity': {
|
|
28
|
+
name: 'Antigravity',
|
|
29
|
+
detect: ['.gemini/antigravity'],
|
|
30
|
+
configFile: 'GEMINI.md',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// All 14 BMAD+ agents — always included in templates
|
|
35
|
+
const AGENT_LIST = [
|
|
36
|
+
'- **Atlas** (Strategist) — Business analysis + Product management',
|
|
37
|
+
'- **Forge** (Architect-Dev) — Architecture + Development + Documentation',
|
|
38
|
+
'- **Sentinel** (Quality) — QA + UX review',
|
|
39
|
+
'- **Nexus** (Orchestrator) — Sprint management + Autopilot + Parallel execution',
|
|
40
|
+
'- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling',
|
|
41
|
+
'- **Shield** (GRC) — 38 compliance agents (GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2...)',
|
|
42
|
+
'- **Miriam** (מרים) — Business Analyst — Strategic analysis, research, product briefs',
|
|
43
|
+
'- **Huldah** (חולדה) — Technical Writer — Documentation, diagrams, editorial review',
|
|
44
|
+
'- **Yosef** (יוסף) — Product Manager — PRD, requirements, feature prioritization',
|
|
45
|
+
'- **Rachel** (רחל) — UX Designer — User experience, wireframes, empathy mapping',
|
|
46
|
+
'- **Bezalel** (בצלאל) — System Architect — Architecture, ADRs, epics & stories',
|
|
47
|
+
'- **Oholiab** (אהליאב) — Senior Engineer — TDD, sprint, code review, implementation',
|
|
48
|
+
'- **Zecher** (זכר) — Memory Archivist — Consolidation, project scanning, context recall',
|
|
49
|
+
'- **Maker** (Creator) — Custom agent builder — Create new agents from description',
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Filter agents based on installed packs.
|
|
54
|
+
* Core agents are always included; others depend on pack selection.
|
|
55
|
+
*
|
|
56
|
+
* @param {string[]} packs - List of installed pack IDs
|
|
57
|
+
* @returns {string[]} Agent description lines
|
|
58
|
+
*/
|
|
59
|
+
function getAgentsByPacks(packs) {
|
|
60
|
+
const agents = [
|
|
61
|
+
'- **Atlas** (Strategist) — Business analysis + Product management',
|
|
62
|
+
'- **Forge** (Architect-Dev) — Architecture + Development + Documentation',
|
|
63
|
+
'- **Sentinel** (Quality) — QA + UX review',
|
|
64
|
+
'- **Nexus** (Orchestrator) — Sprint management + Autopilot + Parallel execution',
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
if (packs.includes('osint')) {
|
|
68
|
+
agents.push('- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (packs.includes('shield')) {
|
|
72
|
+
agents.push('- **Shield** (GRC) — 38 compliance agents (GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2...)');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (packs.includes('maker')) {
|
|
76
|
+
agents.push('- **Maker** (Creator) — Custom agent builder — Create new agents from description');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (packs.includes('dev-studio')) {
|
|
80
|
+
agents.push('- **Miriam** (מרים) — Business Analyst — Strategic analysis, research, product briefs');
|
|
81
|
+
agents.push('- **Huldah** (חולדה) — Technical Writer — Documentation, diagrams, editorial review');
|
|
82
|
+
agents.push('- **Yosef** (יוסף) — Product Manager — PRD, requirements, feature prioritization');
|
|
83
|
+
agents.push('- **Rachel** (רחל) — UX Designer — User experience, wireframes, empathy mapping');
|
|
84
|
+
agents.push('- **Bezalel** (בצלאל) — System Architecture — Architecture, ADRs, epics & stories');
|
|
85
|
+
agents.push('- **Oholiab** (אהליאב) — Senior Engineer — TDD, sprint, code review, implementation');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (packs.includes('memory')) {
|
|
89
|
+
agents.push('- **Zecher** (זכר) — Memory Archivist — Consolidation, project scanning, context recall');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return agents;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Build the Memory Protocol section if the memory pack is installed.
|
|
97
|
+
*
|
|
98
|
+
* @param {string[]} packs - List of installed pack IDs
|
|
99
|
+
* @returns {string} Memory section markdown (empty string if no memory pack)
|
|
100
|
+
*/
|
|
101
|
+
function getMemorySection(packs) {
|
|
102
|
+
if (!packs.includes('memory')) return '';
|
|
103
|
+
return [
|
|
104
|
+
'',
|
|
105
|
+
'## Memory Protocol (Karpathy Guardrails)',
|
|
106
|
+
'',
|
|
107
|
+
'Agents MUST follow these behavioral principles:',
|
|
108
|
+
'',
|
|
109
|
+
'### G1 — Think Before Coding',
|
|
110
|
+
'- State assumptions explicitly. If uncertain, ask.',
|
|
111
|
+
'- Check `.agents/memory/decisions.md` for prior decisions before re-deciding.',
|
|
112
|
+
'',
|
|
113
|
+
'### G2 — Simplicity First',
|
|
114
|
+
'- Minimum code that solves the problem. Nothing speculative.',
|
|
115
|
+
'- Check `.agents/memory/patterns.md` for existing solutions.',
|
|
116
|
+
'',
|
|
117
|
+
'### G3 — Surgical Changes',
|
|
118
|
+
'- Touch only what you must. Match existing style.',
|
|
119
|
+
'- Log surprises in `.agents/memory/lessons.md`.',
|
|
120
|
+
'',
|
|
121
|
+
'### G4 — Goal-Driven Execution',
|
|
122
|
+
'- Define success criteria before implementing.',
|
|
123
|
+
'- Log non-obvious decisions in `.agents/memory/decisions.md`.',
|
|
124
|
+
'',
|
|
125
|
+
'### Memory Files',
|
|
126
|
+
'- `.agents/memory/decisions.md` — Read at session start, write when making decisions',
|
|
127
|
+
'- `.agents/memory/lessons.md` — Write when something unexpected happens',
|
|
128
|
+
'- `.agents/memory/patterns.md` — Write when a reusable pattern is validated',
|
|
129
|
+
'- `.agents/memory/context.md` — Update at session end with project state',
|
|
130
|
+
].join('\n');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Generate IDE config content with pack-aware agent filtering.
|
|
135
|
+
*
|
|
136
|
+
* @param {string} userName - The user's display name
|
|
137
|
+
* @param {string} language - User-facing communication language
|
|
138
|
+
* @param {string[]} packs - List of installed pack IDs
|
|
139
|
+
* @returns {string} Complete Markdown template
|
|
140
|
+
*/
|
|
141
|
+
function generateIDEConfig(userName, language, packs) {
|
|
142
|
+
const agents = getAgentsByPacks(packs);
|
|
143
|
+
const memorySection = getMemorySection(packs);
|
|
144
|
+
|
|
145
|
+
return `# BMAD+ — AI Agent Configuration
|
|
146
|
+
|
|
147
|
+
## Project Context
|
|
148
|
+
This project uses BMAD+, an augmented AI-driven development framework.
|
|
149
|
+
Based on BMAD-METHOD v6.6.0 with multi-role agents, autopilot mode, and parallel execution.
|
|
150
|
+
|
|
151
|
+
## Agents
|
|
152
|
+
To activate an agent, say its name or persona:
|
|
153
|
+
${agents.join('\n')}
|
|
154
|
+
|
|
155
|
+
## Skills
|
|
156
|
+
- Load skills from \`.agents/skills/\`
|
|
157
|
+
- Each agent has a SKILL.md with capabilities, activation protocol, and role-switching rules
|
|
158
|
+
- Auto-activation triggers: \`.agents/data/role-triggers.yaml\`
|
|
159
|
+
|
|
160
|
+
## Key Commands
|
|
161
|
+
- \`bmad-help\` — Show all available agents and skills
|
|
162
|
+
- \`autopilot\` — Launch Nexus in full pipeline mode
|
|
163
|
+
- \`parallel\` — Enable parallel multi-agent execution
|
|
164
|
+
|
|
165
|
+
## Communication
|
|
166
|
+
- User name: ${userName}
|
|
167
|
+
- Default language: ${language} for user-facing content, English for code and technical docs.
|
|
168
|
+
${memorySection}`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Generate a complete CLAUDE.md / GEMINI.md / AGENTS.md config file
|
|
173
|
+
* (all agents, no filtering — backward compatible)
|
|
174
|
+
*
|
|
175
|
+
* @param {string} userName - The user's display name
|
|
176
|
+
* @param {string} language - User-facing communication language
|
|
177
|
+
* @returns {string} Complete Markdown template
|
|
178
|
+
*/
|
|
179
|
+
function generateBaseConfig(userName, language) {
|
|
180
|
+
return `# BMAD+ — AI Agent Configuration
|
|
181
|
+
|
|
182
|
+
## Project Context
|
|
183
|
+
This project uses BMAD+, an augmented AI-driven development framework.
|
|
184
|
+
Based on BMAD-METHOD v6.6.0 with multi-role agents, autopilot mode, and parallel execution.
|
|
185
|
+
|
|
186
|
+
## Agents
|
|
187
|
+
To activate an agent, say its name or persona:
|
|
188
|
+
${AGENT_LIST.join('\n')}
|
|
189
|
+
|
|
190
|
+
## Skills
|
|
191
|
+
- Load skills from \`.agents/skills/\`
|
|
192
|
+
- Each agent has a SKILL.md with capabilities, activation protocol, and role-switching rules
|
|
193
|
+
- Auto-activation triggers: \`.agents/data/role-triggers.yaml\`
|
|
194
|
+
|
|
195
|
+
## Key Commands
|
|
196
|
+
- \`bmad-help\` — Show all available agents and skills
|
|
197
|
+
- \`autopilot\` — Launch Nexus in full pipeline mode
|
|
198
|
+
- \`parallel\` — Enable parallel multi-agent execution
|
|
199
|
+
|
|
200
|
+
## Communication
|
|
201
|
+
- User name: ${userName}
|
|
202
|
+
- Default language: ${language} for user-facing content, English for code and technical docs.
|
|
203
|
+
|
|
204
|
+
## Memory Protocol (Karpathy Guardrails)
|
|
205
|
+
|
|
206
|
+
Agents MUST follow these behavioral principles:
|
|
207
|
+
|
|
208
|
+
### G1 — Think Before Coding
|
|
209
|
+
- State assumptions explicitly. If uncertain, ask.
|
|
210
|
+
- Check \`.agents/memory/decisions.md\` for prior decisions before re-deciding.
|
|
211
|
+
|
|
212
|
+
### G2 — Simplicity First
|
|
213
|
+
- Minimum code that solves the problem. Nothing speculative.
|
|
214
|
+
- Check \`.agents/memory/patterns.md\` for existing solutions.
|
|
215
|
+
|
|
216
|
+
### G3 — Surgical Changes
|
|
217
|
+
- Touch only what you must. Match existing style.
|
|
218
|
+
- Log surprises in \`.agents/memory/lessons.md\`.
|
|
219
|
+
|
|
220
|
+
### G4 — Goal-Driven Execution
|
|
221
|
+
- Define success criteria before implementing.
|
|
222
|
+
- Log non-obvious decisions in \`.agents/memory/decisions.md\`.
|
|
223
|
+
|
|
224
|
+
### Memory Files
|
|
225
|
+
- \`.agents/memory/decisions.md\` — Read at session start, write when making decisions
|
|
226
|
+
- \`.agents/memory/lessons.md\` — Write when something unexpected happens
|
|
227
|
+
- \`.agents/memory/patterns.md\` — Write when a reusable pattern is validated
|
|
228
|
+
- \`.agents/memory/context.md\` — Update at session end with project state`;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
module.exports = {
|
|
232
|
+
IDE_CONFIGS,
|
|
233
|
+
generateIDEConfig,
|
|
234
|
+
getAgentsByPacks,
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Generate CLAUDE.md config for Claude Code
|
|
238
|
+
* @param {string} userName
|
|
239
|
+
* @param {string} language
|
|
240
|
+
* @returns {string}
|
|
241
|
+
*/
|
|
242
|
+
generateClaudeMD: generateBaseConfig,
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Generate GEMINI.md config for Gemini CLI / Antigravity
|
|
246
|
+
* @param {string} userName
|
|
247
|
+
* @param {string} language
|
|
248
|
+
* @returns {string}
|
|
249
|
+
*/
|
|
250
|
+
generateGeminiMD: generateBaseConfig,
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Generate AGENTS.md config for Codex CLI / OpenCode
|
|
254
|
+
* @param {string} userName
|
|
255
|
+
* @param {string} language
|
|
256
|
+
* @returns {string}
|
|
257
|
+
*/
|
|
258
|
+
generateAgentsMD: generateBaseConfig,
|
|
259
|
+
};
|
|
@@ -10,7 +10,6 @@ const fs = require('node:fs');
|
|
|
10
10
|
const os = require('node:os');
|
|
11
11
|
const fsExtra = require('fs-extra');
|
|
12
12
|
const clack = require('@clack/prompts');
|
|
13
|
-
const pc = require('picocolors');
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Initialize the memory pack: create project memory files, detect or create global brain.
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BMAD+ Shared Pack-Copy Module
|
|
3
|
-
* Extracted duplicate file-copy loops from install.js and update.js.
|
|
4
|
-
*
|
|
5
|
-
* Author: Laurent Rochetta
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const path = require('node:path');
|
|
9
|
-
const fs = require('node:fs');
|
|
10
|
-
const fsExtra = require('fs-extra');
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Copy files for a single pack definition into the target directories.
|
|
14
|
-
*
|
|
15
|
-
* @param {object} opts
|
|
16
|
-
* @param {string} opts.bmadSrc - Path to src/bmad-plus/
|
|
17
|
-
* @param {string} opts.targetAgentsDir - Destination for agents / skills
|
|
18
|
-
* @param {string} opts.targetDataDir - Destination for data files
|
|
19
|
-
* @param {string} opts.projectRoot - Project root (for external package resolution)
|
|
20
|
-
* @param {object} opts.pack - Pack definition from PACKS
|
|
21
|
-
* @returns {{ copiedAgents: number, copiedSkills: number, copiedFiles: number }}
|
|
22
|
-
*/
|
|
23
|
-
function copyPackFiles({ bmadSrc, targetAgentsDir, targetDataDir, projectRoot, pack }) {
|
|
24
|
-
let copiedAgents = 0;
|
|
25
|
-
let copiedSkills = 0;
|
|
26
|
-
let copiedFiles = 0;
|
|
27
|
-
|
|
28
|
-
if (!pack) return { copiedAgents, copiedSkills, copiedFiles };
|
|
29
|
-
|
|
30
|
-
// Copy agents
|
|
31
|
-
for (const agent of (pack.agents || [])) {
|
|
32
|
-
const src = path.join(bmadSrc, 'agents', agent);
|
|
33
|
-
const dest = path.join(targetAgentsDir, agent);
|
|
34
|
-
if (fs.existsSync(src)) {
|
|
35
|
-
fsExtra.copySync(src, dest, { overwrite: true });
|
|
36
|
-
copiedAgents++;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Copy skills
|
|
41
|
-
for (const skill of (pack.skills || [])) {
|
|
42
|
-
const src = path.join(bmadSrc, 'skills', skill);
|
|
43
|
-
const dest = path.join(targetAgentsDir, skill);
|
|
44
|
-
if (fs.existsSync(src)) {
|
|
45
|
-
fsExtra.copySync(src, dest, { overwrite: true });
|
|
46
|
-
copiedSkills++;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Copy data files
|
|
51
|
-
for (const dataFile of (pack.data || [])) {
|
|
52
|
-
const src = path.join(bmadSrc, 'data', dataFile);
|
|
53
|
-
const dest = path.join(targetDataDir, dataFile);
|
|
54
|
-
if (fs.existsSync(src)) {
|
|
55
|
-
fsExtra.copySync(src, dest, { overwrite: true });
|
|
56
|
-
copiedFiles++;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Copy external package (e.g. OSINT)
|
|
61
|
-
if (pack.externalPackage) {
|
|
62
|
-
const extSrc = path.join(projectRoot, pack.externalPackage, 'skills');
|
|
63
|
-
if (fs.existsSync(extSrc)) {
|
|
64
|
-
fsExtra.copySync(extSrc, targetAgentsDir, { overwrite: true });
|
|
65
|
-
copiedSkills++;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Copy pack directory (SEO, Backup, Animated, Shield, etc.)
|
|
70
|
-
if (pack.packDir) {
|
|
71
|
-
const srcParent = pack.packSrcDir || 'agents';
|
|
72
|
-
const packSrc = path.join(bmadSrc, srcParent, pack.packDir);
|
|
73
|
-
const packDest = path.join(targetAgentsDir, pack.packDir);
|
|
74
|
-
if (fs.existsSync(packSrc)) {
|
|
75
|
-
fsExtra.copySync(packSrc, packDest, { overwrite: true });
|
|
76
|
-
copiedAgents++;
|
|
77
|
-
copiedFiles++;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return { copiedAgents, copiedSkills, copiedFiles };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
module.exports = { copyPackFiles };
|
|
1
|
+
/**
|
|
2
|
+
* BMAD+ Shared Pack-Copy Module
|
|
3
|
+
* Extracted duplicate file-copy loops from install.js and update.js.
|
|
4
|
+
*
|
|
5
|
+
* Author: Laurent Rochetta
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
const fs = require('node:fs');
|
|
10
|
+
const fsExtra = require('fs-extra');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Copy files for a single pack definition into the target directories.
|
|
14
|
+
*
|
|
15
|
+
* @param {object} opts
|
|
16
|
+
* @param {string} opts.bmadSrc - Path to src/bmad-plus/
|
|
17
|
+
* @param {string} opts.targetAgentsDir - Destination for agents / skills
|
|
18
|
+
* @param {string} opts.targetDataDir - Destination for data files
|
|
19
|
+
* @param {string} opts.projectRoot - Project root (for external package resolution)
|
|
20
|
+
* @param {object} opts.pack - Pack definition from PACKS
|
|
21
|
+
* @returns {{ copiedAgents: number, copiedSkills: number, copiedFiles: number }}
|
|
22
|
+
*/
|
|
23
|
+
function copyPackFiles({ bmadSrc, targetAgentsDir, targetDataDir, projectRoot, pack }) {
|
|
24
|
+
let copiedAgents = 0;
|
|
25
|
+
let copiedSkills = 0;
|
|
26
|
+
let copiedFiles = 0;
|
|
27
|
+
|
|
28
|
+
if (!pack) return { copiedAgents, copiedSkills, copiedFiles };
|
|
29
|
+
|
|
30
|
+
// Copy agents
|
|
31
|
+
for (const agent of (pack.agents || [])) {
|
|
32
|
+
const src = path.join(bmadSrc, 'agents', agent);
|
|
33
|
+
const dest = path.join(targetAgentsDir, agent);
|
|
34
|
+
if (fs.existsSync(src)) {
|
|
35
|
+
fsExtra.copySync(src, dest, { overwrite: true });
|
|
36
|
+
copiedAgents++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Copy skills
|
|
41
|
+
for (const skill of (pack.skills || [])) {
|
|
42
|
+
const src = path.join(bmadSrc, 'skills', skill);
|
|
43
|
+
const dest = path.join(targetAgentsDir, skill);
|
|
44
|
+
if (fs.existsSync(src)) {
|
|
45
|
+
fsExtra.copySync(src, dest, { overwrite: true });
|
|
46
|
+
copiedSkills++;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Copy data files
|
|
51
|
+
for (const dataFile of (pack.data || [])) {
|
|
52
|
+
const src = path.join(bmadSrc, 'data', dataFile);
|
|
53
|
+
const dest = path.join(targetDataDir, dataFile);
|
|
54
|
+
if (fs.existsSync(src)) {
|
|
55
|
+
fsExtra.copySync(src, dest, { overwrite: true });
|
|
56
|
+
copiedFiles++;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Copy external package (e.g. OSINT)
|
|
61
|
+
if (pack.externalPackage) {
|
|
62
|
+
const extSrc = path.join(projectRoot, pack.externalPackage, 'skills');
|
|
63
|
+
if (fs.existsSync(extSrc)) {
|
|
64
|
+
fsExtra.copySync(extSrc, targetAgentsDir, { overwrite: true });
|
|
65
|
+
copiedSkills++;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Copy pack directory (SEO, Backup, Animated, Shield, etc.)
|
|
70
|
+
if (pack.packDir) {
|
|
71
|
+
const srcParent = pack.packSrcDir || 'agents';
|
|
72
|
+
const packSrc = path.join(bmadSrc, srcParent, pack.packDir);
|
|
73
|
+
const packDest = path.join(targetAgentsDir, pack.packDir);
|
|
74
|
+
if (fs.existsSync(packSrc)) {
|
|
75
|
+
fsExtra.copySync(packSrc, packDest, { overwrite: true });
|
|
76
|
+
copiedAgents++;
|
|
77
|
+
copiedFiles++;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { copiedAgents, copiedSkills, copiedFiles };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = { copyPackFiles };
|
package/tools/cli/lib/packs.js
CHANGED
|
@@ -96,19 +96,27 @@ const PACKS = {
|
|
|
96
96
|
const PACK_ORDER = ['core', 'osint', 'maker', 'shield', 'seo', 'memory', 'dev-studio', 'backup', 'animated'];
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* Maps each pack to
|
|
100
|
-
* after installation.
|
|
99
|
+
* Maps each pack to what `bmad-plus doctor` should expect under .agents/skills/
|
|
100
|
+
* after installation.
|
|
101
|
+
*
|
|
102
|
+
* - `agents` — loose agent DIRECTORIES copied straight into .agents/skills/
|
|
103
|
+
* (only core/osint/maker ship their agents this way).
|
|
104
|
+
* - `packDir` — the pack DIRECTORY copied into .agents/skills/ (null when none).
|
|
105
|
+
* - `packAgents`— agent FILES that live INSIDE `packDir` (shield/seo/memory/
|
|
106
|
+
* dev-studio/backup/animated bundle their agents this way, so they
|
|
107
|
+
* must not be checked as loose directories — doing so produced
|
|
108
|
+
* false "Missing agent" warnings on every healthy install).
|
|
101
109
|
*/
|
|
102
110
|
const EXPECTED_AGENTS = {
|
|
103
111
|
core: { agents: ['agent-strategist', 'agent-architect-dev', 'agent-quality', 'agent-orchestrator'], packDir: null },
|
|
104
112
|
osint: { agents: ['agent-shadow'], packDir: null },
|
|
105
113
|
maker: { agents: ['agent-maker'], packDir: null },
|
|
106
|
-
shield: { agents: [
|
|
107
|
-
seo: { agents: ['seo-scout', 'seo-chief', 'seo-judge']
|
|
108
|
-
memory: { agents: [
|
|
109
|
-
'dev-studio':
|
|
110
|
-
backup: { agents: [
|
|
111
|
-
animated: { agents: [
|
|
114
|
+
shield: { agents: [], packDir: 'pack-shield', packAgents: ['shield-orchestrator.md'] },
|
|
115
|
+
seo: { agents: [], packDir: 'pack-seo', packAgents: ['seo-scout.md', 'seo-chief.md', 'seo-judge.md'] },
|
|
116
|
+
memory: { agents: [], packDir: 'pack-memory', packAgents: ['zecher-agent.md', 'memory-orchestrator.md'] },
|
|
117
|
+
'dev-studio': { agents: [], packDir: 'pack-dev-studio', packAgents: ['dev-studio-orchestrator.md'] },
|
|
118
|
+
backup: { agents: [], packDir: 'pack-backup', packAgents: ['backup-agent.md'] },
|
|
119
|
+
animated: { agents: [], packDir: 'pack-animated', packAgents: ['animated-website-agent.md'] },
|
|
112
120
|
};
|
|
113
121
|
|
|
114
122
|
module.exports = { PACKS, PACK_ORDER, EXPECTED_AGENTS };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD+ Stack Detection — Shared Module
|
|
3
|
+
* Unified project stack detection for autoconfig and scan commands.
|
|
4
|
+
* Merges patterns from both original implementations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
const fs = require('node:fs');
|
|
9
|
+
|
|
10
|
+
// ── Project Detection Markers (for scan.js) ──
|
|
11
|
+
|
|
12
|
+
const PROJECT_MARKERS = [
|
|
13
|
+
{ file: 'package.json', stack: 'Node.js', detect: (dir) => {
|
|
14
|
+
try {
|
|
15
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));
|
|
16
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
17
|
+
if (deps['next']) return 'Next.js';
|
|
18
|
+
if (deps['nuxt']) return 'Nuxt';
|
|
19
|
+
if (deps['react']) return 'React';
|
|
20
|
+
if (deps['vue']) return 'Vue.js';
|
|
21
|
+
if (deps['svelte']) return 'Svelte';
|
|
22
|
+
if (deps['express']) return 'Express';
|
|
23
|
+
if (deps['fastify']) return 'Fastify';
|
|
24
|
+
if (deps['electron']) return 'Electron';
|
|
25
|
+
if (deps['tauri']) return 'Tauri';
|
|
26
|
+
return 'Node.js';
|
|
27
|
+
} catch {
|
|
28
|
+
return 'Node.js';
|
|
29
|
+
}
|
|
30
|
+
}},
|
|
31
|
+
{ file: 'Cargo.toml', stack: 'Rust' },
|
|
32
|
+
{ file: 'pyproject.toml', stack: 'Python' },
|
|
33
|
+
{ file: 'requirements.txt', stack: 'Python' },
|
|
34
|
+
{ file: 'go.mod', stack: 'Go' },
|
|
35
|
+
{ file: 'composer.json', stack: 'PHP' },
|
|
36
|
+
{ file: 'Gemfile', stack: 'Ruby' },
|
|
37
|
+
{ file: 'pom.xml', stack: 'Java' },
|
|
38
|
+
{ file: 'build.gradle', stack: 'Java/Kotlin' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
// ── Full Stack Detection (for autoconfig.js) ──
|
|
42
|
+
|
|
43
|
+
function detectStack(dir) {
|
|
44
|
+
const result = {
|
|
45
|
+
language: null,
|
|
46
|
+
framework: null,
|
|
47
|
+
runtime: null,
|
|
48
|
+
packageManager: null,
|
|
49
|
+
hasTypeScript: false,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Package.json analysis
|
|
53
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
54
|
+
if (fs.existsSync(pkgPath)) {
|
|
55
|
+
try {
|
|
56
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
57
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
58
|
+
result.runtime = 'Node.js';
|
|
59
|
+
result.language = deps['typescript'] || fs.existsSync(path.join(dir, 'tsconfig.json')) ? 'TypeScript' : 'JavaScript';
|
|
60
|
+
result.hasTypeScript = result.language === 'TypeScript';
|
|
61
|
+
|
|
62
|
+
// Framework detection
|
|
63
|
+
if (deps['next']) result.framework = 'Next.js';
|
|
64
|
+
else if (deps['nuxt']) result.framework = 'Nuxt';
|
|
65
|
+
else if (deps['@angular/core']) result.framework = 'Angular';
|
|
66
|
+
else if (deps['react']) result.framework = 'React';
|
|
67
|
+
else if (deps['vue']) result.framework = 'Vue.js';
|
|
68
|
+
else if (deps['svelte']) result.framework = 'Svelte';
|
|
69
|
+
else if (deps['express']) result.framework = 'Express';
|
|
70
|
+
else if (deps['fastify']) result.framework = 'Fastify';
|
|
71
|
+
else if (deps['hono']) result.framework = 'Hono';
|
|
72
|
+
else if (deps['electron']) result.framework = 'Electron';
|
|
73
|
+
else if (deps['tauri']) result.framework = 'Tauri';
|
|
74
|
+
else if (deps['react-native']) result.framework = 'React Native';
|
|
75
|
+
|
|
76
|
+
// Package manager
|
|
77
|
+
if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml'))) result.packageManager = 'pnpm';
|
|
78
|
+
else if (fs.existsSync(path.join(dir, 'yarn.lock'))) result.packageManager = 'yarn';
|
|
79
|
+
else if (fs.existsSync(path.join(dir, 'bun.lockb'))) result.packageManager = 'bun';
|
|
80
|
+
else result.packageManager = 'npm';
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.warn('stack-detect: Failed to parse package.json in detectStack', e.message);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Other languages
|
|
87
|
+
if (!result.runtime) {
|
|
88
|
+
if (fs.existsSync(path.join(dir, 'Cargo.toml'))) { result.language = 'Rust'; result.runtime = 'Rust'; }
|
|
89
|
+
else if (fs.existsSync(path.join(dir, 'pyproject.toml')) || fs.existsSync(path.join(dir, 'requirements.txt'))) { result.language = 'Python'; result.runtime = 'Python'; }
|
|
90
|
+
else if (fs.existsSync(path.join(dir, 'go.mod'))) { result.language = 'Go'; result.runtime = 'Go'; }
|
|
91
|
+
else if (fs.existsSync(path.join(dir, 'composer.json'))) { result.language = 'PHP'; result.runtime = 'PHP'; }
|
|
92
|
+
else if (fs.existsSync(path.join(dir, 'Gemfile'))) { result.language = 'Ruby'; result.runtime = 'Ruby'; }
|
|
93
|
+
else if (fs.existsSync(path.join(dir, 'pom.xml')) || fs.existsSync(path.join(dir, 'build.gradle'))) { result.language = 'Java'; result.runtime = 'JVM'; }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
detectStack,
|
|
101
|
+
PROJECT_MARKERS,
|
|
102
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BMAD+ User Input Validation Utilities
|
|
3
|
+
* Extracted from install.js for modularity and reuse.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Shell/quote metacharacters that are dangerous in user-provided names.
|
|
7
|
+
// Includes single/double quotes so a name cannot break out of a quoted context.
|
|
8
|
+
const SHELL_META = /[;&|`$(){}[\]!#~<>*?\\'"\n\r]/;
|
|
9
|
+
// Global variant used to strip EVERY occurrence during sanitization.
|
|
10
|
+
// (A non-global regex in String.replace only removes the first match.)
|
|
11
|
+
const SHELL_META_GLOBAL = /[;&|`$(){}[\]!#~<>*?\\'"\n\r]/g;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Validate and sanitize a user name.
|
|
15
|
+
* Rules:
|
|
16
|
+
* - Must not be empty
|
|
17
|
+
* - Must not exceed 100 characters
|
|
18
|
+
* - Must not contain shell metacharacters
|
|
19
|
+
*
|
|
20
|
+
* @param {string} rawName - Raw user-provided name
|
|
21
|
+
* @param {string} fallback - Fallback name if validation fails
|
|
22
|
+
* @returns {{ name: string, warnings: string[] }} Sanitized name and any warnings
|
|
23
|
+
*/
|
|
24
|
+
function validateUserName(rawName, fallback) {
|
|
25
|
+
const warnings = [];
|
|
26
|
+
|
|
27
|
+
if (!rawName || rawName.trim().length === 0) {
|
|
28
|
+
warnings.push('Name cannot be empty. Using default.');
|
|
29
|
+
return { name: fallback, warnings };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (rawName.length > 100) {
|
|
33
|
+
warnings.push('Name too long (>100 chars). Truncating.');
|
|
34
|
+
return { name: rawName.slice(0, 100), warnings };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (SHELL_META.test(rawName)) {
|
|
38
|
+
const sanitized = rawName.replace(SHELL_META_GLOBAL, '').trim() || 'Developer';
|
|
39
|
+
warnings.push('Name contains shell metacharacters. Using sanitized version.');
|
|
40
|
+
return { name: sanitized, warnings };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { name: rawName, warnings };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
validateUserName,
|
|
48
|
+
SHELL_META,
|
|
49
|
+
SHELL_META_GLOBAL,
|
|
50
|
+
};
|