bmad-plus 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/README.md +4 -2
  3. package/package.json +1 -1
  4. package/readme-international/README.de.md +10 -2
  5. package/readme-international/README.es.md +32 -9
  6. package/readme-international/README.fr.md +29 -6
  7. package/src/bmad-plus/packs/pack-seo/bmad-skill-manifest.yaml +13 -0
  8. package/src/bmad-plus/packs/pack-shield/SKILL.md +82 -0
  9. package/tools/bmad-plus-npx.js +3 -5
  10. package/tools/cli/commands/autoconfig.js +16 -6
  11. package/tools/cli/commands/doctor.js +28 -31
  12. package/tools/cli/commands/install.js +37 -228
  13. package/tools/cli/commands/scan.js +37 -35
  14. package/tools/cli/commands/update.js +13 -71
  15. package/tools/cli/i18n.js +92 -10
  16. package/tools/cli/lib/memory-init.js +114 -0
  17. package/tools/cli/lib/pack-copy.js +84 -0
  18. package/tools/cli/lib/packs.js +114 -0
  19. package/src/bmad-plus/agents/pack-animated/animated-website-agent.md +0 -325
  20. package/src/bmad-plus/agents/pack-animated/templates/animated-website-workflow.md +0 -55
  21. package/src/bmad-plus/agents/pack-backup/backup-agent.md +0 -71
  22. package/src/bmad-plus/agents/pack-backup/templates/backup-workflow.md +0 -51
  23. package/src/bmad-plus/agents/pack-seo/SKILL.md +0 -171
  24. package/src/bmad-plus/agents/pack-seo/checklist.md +0 -140
  25. package/src/bmad-plus/agents/pack-seo/pagespeed-playbook.md +0 -320
  26. package/src/bmad-plus/agents/pack-seo/ref/audit-schema.json +0 -187
  27. package/src/bmad-plus/agents/pack-seo/ref/cwv-thresholds.md +0 -87
  28. package/src/bmad-plus/agents/pack-seo/ref/eeat-criteria.md +0 -123
  29. package/src/bmad-plus/agents/pack-seo/ref/geo-signals.md +0 -167
  30. package/src/bmad-plus/agents/pack-seo/ref/hreflang-rules.md +0 -153
  31. package/src/bmad-plus/agents/pack-seo/ref/quality-gates.md +0 -133
  32. package/src/bmad-plus/agents/pack-seo/ref/schema-catalog.md +0 -91
  33. package/src/bmad-plus/agents/pack-seo/ref/schema-templates.json +0 -356
  34. package/src/bmad-plus/agents/pack-seo/seo-chief.md +0 -294
  35. package/src/bmad-plus/agents/pack-seo/seo-judge.md +0 -241
  36. package/src/bmad-plus/agents/pack-seo/seo-scout.md +0 -171
  37. package/src/bmad-plus/agents/pack-seo/templates/seo-audit-workflow.md +0 -241
package/tools/cli/i18n.js CHANGED
@@ -5,12 +5,14 @@
5
5
  * Author: Laurent Rochetta
6
6
  */
7
7
 
8
+ const VERSION = require('../../package.json').version;
9
+
8
10
  const LANGUAGES = {
9
11
  en: {
10
12
  flag: '🇬🇧',
11
13
  name: 'English',
12
14
  locale: 'en',
13
- installer_title: ' BMAD+ Installer v0.8.0 ',
15
+ installer_title: ` BMAD+ Installer v${VERSION} `,
14
16
  select_language: 'Select your language',
15
17
  installing_to: 'Installing to',
16
18
  select_packs: 'Which packs to install? (Core is always included)',
@@ -92,7 +94,7 @@ const LANGUAGES = {
92
94
  flag: '🇫🇷',
93
95
  name: 'Français',
94
96
  locale: 'fr',
95
- installer_title: ' BMAD+ Installeur v0.8.0 ',
97
+ installer_title: ` BMAD+ Installeur v${VERSION} `,
96
98
  select_language: 'Choisissez votre langue',
97
99
  installing_to: 'Installation dans',
98
100
  select_packs: 'Quels packs installer ? (Core est toujours inclus)',
@@ -172,7 +174,7 @@ const LANGUAGES = {
172
174
  flag: '🇪🇸',
173
175
  name: 'Español',
174
176
  locale: 'es',
175
- installer_title: ' BMAD+ Instalador v0.8.0 ',
177
+ installer_title: ` BMAD+ Instalador v${VERSION} `,
176
178
  select_language: 'Seleccione su idioma',
177
179
  installing_to: 'Instalando en',
178
180
  select_packs: '¿Qué packs instalar? (Core siempre está incluido)',
@@ -236,13 +238,23 @@ const LANGUAGES = {
236
238
  guide_example_backup: '🗂️ Backup: "/backup create" → ZIP con marca de tiempo',
237
239
  guide_example_animated: '🎬 Animado: "/animated build hero.mp4"',
238
240
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
241
+ guide_memory: '🧠 Cerebro persistente',
242
+ guide_dev_studio: '🏗️ Dev Studio',
243
+ guide_example_memory_1: '🧠 Memoria: "Zecher, escanea proyectos en D:\\DEV"',
244
+ guide_example_memory_2: '🧠 Memoria: "Zecher, ¿dónde estábamos?"',
245
+ guide_example_memory_3: '🧠 Memoria: "Zecher, consolida la memoria"',
246
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, haz una lluvia de ideas para una app de productividad"',
247
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, diseña la arquitectura"',
248
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, implementa la historia S1"',
249
+ brain_detected: 'Cerebro existente detectado',
250
+ brain_created: 'Cerebro global creado',
239
251
  },
240
252
 
241
253
  de: {
242
254
  flag: '🇩🇪',
243
255
  name: 'Deutsch',
244
256
  locale: 'de',
245
- installer_title: ' BMAD+ Installer v0.8.0 ',
257
+ installer_title: ` BMAD+ Installer v${VERSION} `,
246
258
  select_language: 'Wählen Sie Ihre Sprache',
247
259
  installing_to: 'Installiere in',
248
260
  select_packs: 'Welche Packs installieren? (Core ist immer enthalten)',
@@ -306,13 +318,23 @@ const LANGUAGES = {
306
318
  guide_example_backup: '🗂️ Backup: "/backup create" → ZIP mit Zeitstempel',
307
319
  guide_example_animated: '🎬 Animiert: "/animated build hero.mp4"',
308
320
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
321
+ guide_memory: '🧠 Beständiges Gehirn',
322
+ guide_dev_studio: '🏗️ Dev Studio',
323
+ guide_example_memory_1: '🧠 Gedächtnis: "Zecher, scanne Projekte in D:\\DEV"',
324
+ guide_example_memory_2: '🧠 Gedächtnis: "Zecher, wo waren wir?"',
325
+ guide_example_memory_3: '🧠 Gedächtnis: "Zecher, konsolidiere Gedächtnis"',
326
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, brainstorme eine Produktivitäts-App"',
327
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, entwirf die Architektur"',
328
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, implementiere Story S1"',
329
+ brain_detected: 'Vorhandenes Gehirn erkannt',
330
+ brain_created: 'Globales Gehirn erstellt',
309
331
  },
310
332
 
311
333
  'pt-br': {
312
334
  flag: '🇧🇷',
313
335
  name: 'Português (Brasil)',
314
336
  locale: 'pt-BR',
315
- installer_title: ' BMAD+ Instalador v0.8.0 ',
337
+ installer_title: ` BMAD+ Instalador v${VERSION} `,
316
338
  select_language: 'Selecione seu idioma',
317
339
  installing_to: 'Instalando em',
318
340
  select_packs: 'Quais packs instalar? (Core sempre está incluído)',
@@ -376,13 +398,23 @@ const LANGUAGES = {
376
398
  guide_example_backup: '🗂️ Backup: "/backup create" → ZIP com timestamp',
377
399
  guide_example_animated: '🎬 Animado: "/animated build hero.mp4"',
378
400
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
401
+ guide_memory: '🧠 Cérebro persistente',
402
+ guide_dev_studio: '🏗️ Dev Studio',
403
+ guide_example_memory_1: '🧠 Memória: "Zecher, escaneie projetos em D:\\DEV"',
404
+ guide_example_memory_2: '🧠 Memória: "Zecher, onde estávamos?"',
405
+ guide_example_memory_3: '🧠 Memória: "Zecher, consolide a memória"',
406
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, faça um brainstorm de um app de produtividade"',
407
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, projete a arquitetura"',
408
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, implemente a história S1"',
409
+ brain_detected: 'Cérebro existente detectado',
410
+ brain_created: 'Cérebro global criado',
379
411
  },
380
412
 
381
413
  ru: {
382
414
  flag: '🇷🇺',
383
415
  name: 'Русский',
384
416
  locale: 'ru',
385
- installer_title: ' BMAD+ Установщик v0.8.0 ',
417
+ installer_title: ` BMAD+ Установщик v${VERSION} `,
386
418
  select_language: 'Выберите язык',
387
419
  installing_to: 'Установка в',
388
420
  select_packs: 'Какие пакеты установить? (Core всегда включён)',
@@ -446,13 +478,23 @@ const LANGUAGES = {
446
478
  guide_example_backup: '🗂️ Бэкап: "/backup create" → ZIP',
447
479
  guide_example_animated: '🎬 Анимация: "/animated build hero.mp4"',
448
480
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
481
+ guide_memory: '🧠 Постоянный мозг',
482
+ guide_dev_studio: '🏗️ Dev Studio',
483
+ guide_example_memory_1: '🧠 Память: "Zecher, сканируй проекты в D:\\DEV"',
484
+ guide_example_memory_2: '🧠 Память: "Zecher, на чём мы остановились?"',
485
+ guide_example_memory_3: '🧠 Память: "Zecher, консолидируй память"',
486
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, проведи мозговой штурм приложения"',
487
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, спроектируй архитектуру"',
488
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, реализуй историю S1"',
489
+ brain_detected: 'Существующий мозг обнаружен',
490
+ brain_created: 'Глобальный мозг создан',
449
491
  },
450
492
 
451
493
  zh: {
452
494
  flag: '🇨🇳',
453
495
  name: '中文 (简体)',
454
496
  locale: 'zh-CN',
455
- installer_title: ' BMAD+ 安装程序 v0.8.0 ',
497
+ installer_title: ` BMAD+ 安装程序 v${VERSION} `,
456
498
  select_language: '选择您的语言',
457
499
  installing_to: '安装到',
458
500
  select_packs: '安装哪些包?(Core 始终包含)',
@@ -516,13 +558,23 @@ const LANGUAGES = {
516
558
  guide_example_backup: '🗂️ 备份: "/backup create" → ZIP',
517
559
  guide_example_animated: '🎬 动画: "/animated build hero.mp4"',
518
560
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
561
+ guide_memory: '🧠 持久记忆',
562
+ guide_dev_studio: '🏗️ Dev Studio',
563
+ guide_example_memory_1: '🧠 记忆: "Zecher, 扫描 D:\\DEV 中的项目"',
564
+ guide_example_memory_2: '🧠 记忆: "Zecher, 我们进行到哪里了?"',
565
+ guide_example_memory_3: '🧠 记忆: "Zecher, 整合记忆"',
566
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, 集思广益一个生产力应用"',
567
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, 设计架构"',
568
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, 实现故事 S1"',
569
+ brain_detected: '检测到现有大脑',
570
+ brain_created: '全局大脑已创建',
519
571
  },
520
572
 
521
573
  he: {
522
574
  flag: '🇮🇱',
523
575
  name: 'עברית',
524
576
  locale: 'he',
525
- installer_title: ' BMAD+ מתקין v0.8.0 ',
577
+ installer_title: ` BMAD+ מתקין v${VERSION} `,
526
578
  select_language: 'בחר את השפה שלך',
527
579
  installing_to: 'מתקין ב',
528
580
  select_packs: 'אילו חבילות להתקין? (Core תמיד כלול)',
@@ -586,13 +638,23 @@ const LANGUAGES = {
586
638
  guide_example_backup: '🗂️ גיבוי: "/backup create" → ZIP',
587
639
  guide_example_animated: '🎬 אנימציה: "/animated build hero.mp4"',
588
640
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
641
+ guide_memory: '🧠 זיכרון מתמשך',
642
+ guide_dev_studio: '🏗️ Dev Studio',
643
+ guide_example_memory_1: '🧠 זיכרון: "Zecher, סרוק פרויקטים ב-D:\\DEV"',
644
+ guide_example_memory_2: '🧠 זיכרון: "Zecher, איפה היינו?"',
645
+ guide_example_memory_3: '🧠 זיכרון: "Zecher, אחד זיכרון"',
646
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, עשה סיעור מוחות לאפליקציית פרודוקטיביות"',
647
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, תכנן את הארכיטקטורה"',
648
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, יישם את הסיפור S1"',
649
+ brain_detected: 'זוהה מוח קיים',
650
+ brain_created: 'מוח גלובלי נוצר',
589
651
  },
590
652
 
591
653
  ja: {
592
654
  flag: '🇯🇵',
593
655
  name: '日本語',
594
656
  locale: 'ja',
595
- installer_title: ' BMAD+ インストーラー v0.8.0 ',
657
+ installer_title: ` BMAD+ インストーラー v${VERSION} `,
596
658
  select_language: '言語を選択してください',
597
659
  installing_to: 'インストール先',
598
660
  select_packs: 'どのパックをインストールしますか?(Coreは常に含まれます)',
@@ -656,13 +718,23 @@ const LANGUAGES = {
656
718
  guide_example_backup: '🗂️ バックアップ: "/backup create" → ZIP',
657
719
  guide_example_animated: '🎬 アニメ: "/animated build hero.mp4"',
658
720
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
721
+ guide_memory: '🧠 永続的な脳',
722
+ guide_dev_studio: '🏗️ Dev Studio',
723
+ guide_example_memory_1: '🧠 記憶: "Zecher, D:\\DEV のプロジェクトをスキャン"',
724
+ guide_example_memory_2: '🧠 記憶: "Zecher, どこまで進んだ?"',
725
+ guide_example_memory_3: '🧠 記憶: "Zecher, 記憶を統合"',
726
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, 生産性アプリをブレインストーミング"',
727
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, アーキテクチャを設計"',
728
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, ストーリーS1を実装"',
729
+ brain_detected: '既存の脳を検出',
730
+ brain_created: 'グローバル脳を作成',
659
731
  },
660
732
 
661
733
  it: {
662
734
  flag: '🇮🇹',
663
735
  name: 'Italiano',
664
736
  locale: 'it',
665
- installer_title: ' BMAD+ Installatore v0.8.0 ',
737
+ installer_title: ` BMAD+ Installatore v${VERSION} `,
666
738
  select_language: 'Seleziona la tua lingua',
667
739
  installing_to: 'Installazione in',
668
740
  select_packs: 'Quali pack installare? (Core è sempre incluso)',
@@ -726,6 +798,16 @@ const LANGUAGES = {
726
798
  guide_example_backup: '🗂️ Backup: "/backup create" → ZIP con timestamp',
727
799
  guide_example_animated: '🎬 Animato: "/animated build hero.mp4"',
728
800
  guide_example_osint: '🔍 OSINT: "Shadow, investigate John Doe"',
801
+ guide_memory: '🧠 Memoria persistente',
802
+ guide_dev_studio: '🏗️ Dev Studio',
803
+ guide_example_memory_1: '🧠 Memoria: "Zecher, scansiona progetti in D:\\DEV"',
804
+ guide_example_memory_2: '🧠 Memoria: "Zecher, dove eravamo?"',
805
+ guide_example_memory_3: '🧠 Memoria: "Zecher, consolida la memoria"',
806
+ guide_example_dev_studio_1: '🏗️ Dev Studio: "Miriam, fai un brainstorming di un\'app di produttività"',
807
+ guide_example_dev_studio_2: '🏗️ Dev Studio: "Bezalel, progetta l\'architettura"',
808
+ guide_example_dev_studio_3: '🏗️ Dev Studio: "Oholiab, implementa la storia S1"',
809
+ brain_detected: 'Cervello esistente rilevato',
810
+ brain_created: 'Cervello globale creato',
729
811
  },
730
812
  };
731
813
 
@@ -0,0 +1,114 @@
1
+ /**
2
+ * BMAD+ Memory Initialization Module
3
+ * Extracted from install.js — initializes brain with existing brain detection.
4
+ *
5
+ * Author: Laurent Rochetta
6
+ */
7
+
8
+ const path = require('node:path');
9
+ const fs = require('node:fs');
10
+ const os = require('node:os');
11
+ const fsExtra = require('fs-extra');
12
+ const clack = require('@clack/prompts');
13
+ const pc = require('picocolors');
14
+
15
+ /**
16
+ * Initialize the memory pack: create project memory files, detect or create global brain.
17
+ *
18
+ * @param {object} opts
19
+ * @param {string} opts.projectDir - Target project directory
20
+ * @param {string} opts.bmadSrc - Path to src/bmad-plus/
21
+ * @param {string} opts.userName - User display name
22
+ * @param {string} opts.commLang - Communication language
23
+ * @param {string[]} opts.selectedPacks - Array of pack IDs being installed
24
+ * @param {object} opts.i - i18n translations object
25
+ * @returns {void}
26
+ */
27
+ function initMemory({ projectDir, bmadSrc, userName, commLang, selectedPacks }) {
28
+ const memoryDir = path.join(projectDir, '.agents', 'memory');
29
+ const sessionsDir = path.join(memoryDir, 'sessions');
30
+ const globalBrainDir = path.join(os.homedir(), '.bmad-plus', 'brain', 'projects');
31
+ const templateDir = path.join(bmadSrc, 'packs', 'pack-memory', 'templates');
32
+
33
+ // Create project memory (never overwrite existing)
34
+ fsExtra.ensureDirSync(sessionsDir);
35
+ const memoryFiles = ['decisions.md', 'lessons.md', 'patterns.md', 'context.md'];
36
+ for (const mf of memoryFiles) {
37
+ const dest = path.join(memoryDir, mf);
38
+ if (!fs.existsSync(dest)) {
39
+ const src = path.join(templateDir, mf);
40
+ if (fs.existsSync(src)) {
41
+ let content = fs.readFileSync(src, 'utf8');
42
+ content = content.replace(/\{\{date\}\}/g, new Date().toISOString().slice(0, 10));
43
+ content = content.replace(/\{\{project_name\}\}/g, path.basename(projectDir));
44
+ content = content.replace(/\{\{project_path\}\}/g, projectDir);
45
+ fs.writeFileSync(dest, content, 'utf8');
46
+ }
47
+ }
48
+ }
49
+
50
+ // Detect existing brain directories
51
+ const brainCandidates = [
52
+ path.join(os.homedir(), '.bmad-plus', 'brain'),
53
+ path.join(projectDir, '_brain'),
54
+ path.join(os.homedir(), '.claude', 'memory'),
55
+ ];
56
+ const existingBrain = brainCandidates.find(p => fs.existsSync(p));
57
+
58
+ if (existingBrain) {
59
+ clack.log.info(`🧠 Existing brain detected: ${existingBrain}`);
60
+ // Write brain link pointer
61
+ fs.writeFileSync(
62
+ path.join(memoryDir, '.brain-link'),
63
+ JSON.stringify({ linked_brain: existingBrain, linked_at: new Date().toISOString() }, null, 2),
64
+ 'utf8'
65
+ );
66
+ } else {
67
+ // Create fresh global brain
68
+ fsExtra.ensureDirSync(globalBrainDir);
69
+ const identitySrc = path.join(templateDir, 'identity.yaml');
70
+ const identityDest = path.join(os.homedir(), '.bmad-plus', 'brain', 'identity.yaml');
71
+ if (fs.existsSync(identitySrc) && !fs.existsSync(identityDest)) {
72
+ let content = fs.readFileSync(identitySrc, 'utf8');
73
+ content = content.replace(/\{\{user_name\}\}/g, userName);
74
+ content = content.replace(/\{\{language\}\}/g, commLang);
75
+ content = content.replace(/\{\{date\}\}/g, new Date().toISOString().slice(0, 10));
76
+ fs.writeFileSync(identityDest, content, 'utf8');
77
+ }
78
+ // Copy global memory templates
79
+ for (const gf of ['decisions.md', 'lessons.md', 'patterns.md']) {
80
+ const dest = path.join(os.homedir(), '.bmad-plus', 'brain', gf);
81
+ if (!fs.existsSync(dest)) {
82
+ const src = path.join(templateDir, gf);
83
+ if (fs.existsSync(src)) {
84
+ let content = fs.readFileSync(src, 'utf8');
85
+ content = content.replace(/\{\{date\}\}/g, new Date().toISOString().slice(0, 10));
86
+ content = content.replace(/\{\{project_name\}\}/g, 'Global Brain');
87
+ fs.writeFileSync(dest, content, 'utf8');
88
+ }
89
+ }
90
+ }
91
+ clack.log.info(`🧠 Global brain created: ${path.join(os.homedir(), '.bmad-plus', 'brain')}`);
92
+ }
93
+
94
+ // Index this project in global brain
95
+ const crypto = require('node:crypto');
96
+ const projHash = crypto.createHash('sha256').update(projectDir).digest('hex').slice(0, 8);
97
+ const projMeta = {
98
+ path: projectDir,
99
+ name: path.basename(projectDir),
100
+ hash: projHash,
101
+ status: 'active',
102
+ bmad_installed: true,
103
+ packs_installed: selectedPacks,
104
+ last_scanned: new Date().toISOString().slice(0, 10),
105
+ };
106
+ fsExtra.ensureDirSync(globalBrainDir);
107
+ fs.writeFileSync(
108
+ path.join(globalBrainDir, `${projHash}.yaml`),
109
+ Object.entries(projMeta).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join('\n'),
110
+ 'utf8'
111
+ );
112
+ }
113
+
114
+ module.exports = { initMemory };
@@ -0,0 +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 };
@@ -0,0 +1,114 @@
1
+ /**
2
+ * BMAD+ Shared PACKS Module
3
+ * Single source of truth for pack definitions, expected agents, and pack ordering.
4
+ *
5
+ * Author: Laurent Rochetta
6
+ */
7
+
8
+ const PACKS = {
9
+ core: {
10
+ name: 'Core',
11
+ icon: 'b',
12
+ agents: ['agent-strategist', 'agent-architect-dev', 'agent-quality', 'agent-orchestrator'],
13
+ skills: ['bmad-plus-autopilot', 'bmad-plus-parallel', 'bmad-plus-sync'],
14
+ data: ['role-triggers.yaml'],
15
+ packDir: 'pack-core',
16
+ packSrcDir: 'packs',
17
+ required: true,
18
+ desc: 'Core agents & skills',
19
+ },
20
+ osint: {
21
+ name: 'OSINT',
22
+ icon: 'j',
23
+ agents: ['agent-shadow'],
24
+ skills: [],
25
+ externalPackage: 'osint-agent-package',
26
+ packDir: 'pack-osint',
27
+ packSrcDir: 'packs',
28
+ desc: 'OSINT & investigation',
29
+ },
30
+ maker: {
31
+ name: 'Maker',
32
+ icon: 'f',
33
+ agents: ['agent-maker'],
34
+ skills: [],
35
+ data: [],
36
+ packDir: 'pack-maker',
37
+ packSrcDir: 'packs',
38
+ desc: 'Agent creation toolkit',
39
+ },
40
+ shield: {
41
+ name: 'Shield',
42
+ icon: 'm',
43
+ agents: ['shield-orchestrator'],
44
+ skills: [],
45
+ packDir: 'pack-shield',
46
+ packSrcDir: 'packs',
47
+ desc: 'GRC compliance (25+ frameworks)',
48
+ },
49
+ seo: {
50
+ name: 'SEO',
51
+ icon: 'k',
52
+ agents: ['seo-scout', 'seo-chief', 'seo-judge'],
53
+ skills: [],
54
+ packDir: 'pack-seo',
55
+ packSrcDir: 'packs',
56
+ desc: 'SEO audit & optimization',
57
+ },
58
+ memory: {
59
+ name: 'Memory',
60
+ icon: 'x',
61
+ agents: ['zecher'],
62
+ skills: [],
63
+ packDir: 'pack-memory',
64
+ packSrcDir: 'packs',
65
+ desc: 'Persistent cross-session memory',
66
+ },
67
+ 'dev-studio': {
68
+ name: 'Dev Studio',
69
+ icon: 'v',
70
+ agents: ['dev-studio-orchestrator'],
71
+ skills: ['dev-studio'],
72
+ packDir: 'pack-dev-studio',
73
+ packSrcDir: 'packs',
74
+ desc: 'SDLC automation (6 agents, 56+ skills)',
75
+ },
76
+ backup: {
77
+ name: 'Backup',
78
+ icon: 'y',
79
+ agents: ['backup-agent'],
80
+ skills: [],
81
+ packDir: 'pack-backup',
82
+ packSrcDir: 'packs',
83
+ desc: 'Backup & restore',
84
+ },
85
+ animated: {
86
+ name: 'Animated',
87
+ icon: 'z',
88
+ agents: ['animated-website-agent'],
89
+ skills: [],
90
+ packDir: 'pack-animated',
91
+ packSrcDir: 'packs',
92
+ desc: 'Animated website agents',
93
+ },
94
+ };
95
+
96
+ const PACK_ORDER = ['core', 'osint', 'maker', 'shield', 'seo', 'memory', 'dev-studio', 'backup', 'animated'];
97
+
98
+ /**
99
+ * Maps each pack to the list of directory names expected under .agents/skills/
100
+ * after installation. Each entry contains agent directory names AND/OR pack directory names.
101
+ */
102
+ const EXPECTED_AGENTS = {
103
+ core: { agents: ['agent-strategist', 'agent-architect-dev', 'agent-quality', 'agent-orchestrator'], packDir: null },
104
+ osint: { agents: ['agent-shadow'], packDir: null },
105
+ maker: { agents: ['agent-maker'], packDir: null },
106
+ shield: { agents: ['shield-orchestrator'], packDir: 'pack-shield' },
107
+ seo: { agents: ['seo-scout', 'seo-chief', 'seo-judge'], packDir: 'pack-seo' },
108
+ memory: { agents: ['zecher'], packDir: 'pack-memory' },
109
+ 'dev-studio': { agents: ['dev-studio-orchestrator'], packDir: 'pack-dev-studio' },
110
+ backup: { agents: ['backup-agent'], packDir: 'pack-backup' },
111
+ animated: { agents: ['animated-website-agent'], packDir: 'pack-animated' },
112
+ };
113
+
114
+ module.exports = { PACKS, PACK_ORDER, EXPECTED_AGENTS };