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.
- package/CHANGELOG.md +30 -1
- package/README.md +4 -2
- package/package.json +1 -1
- package/readme-international/README.de.md +10 -2
- package/readme-international/README.es.md +32 -9
- package/readme-international/README.fr.md +29 -6
- package/src/bmad-plus/packs/pack-seo/bmad-skill-manifest.yaml +13 -0
- package/src/bmad-plus/packs/pack-shield/SKILL.md +82 -0
- package/tools/bmad-plus-npx.js +3 -5
- package/tools/cli/commands/autoconfig.js +16 -6
- package/tools/cli/commands/doctor.js +28 -31
- package/tools/cli/commands/install.js +37 -228
- package/tools/cli/commands/scan.js +37 -35
- package/tools/cli/commands/update.js +13 -71
- package/tools/cli/i18n.js +92 -10
- package/tools/cli/lib/memory-init.js +114 -0
- package/tools/cli/lib/pack-copy.js +84 -0
- package/tools/cli/lib/packs.js +114 -0
- package/src/bmad-plus/agents/pack-animated/animated-website-agent.md +0 -325
- package/src/bmad-plus/agents/pack-animated/templates/animated-website-workflow.md +0 -55
- package/src/bmad-plus/agents/pack-backup/backup-agent.md +0 -71
- package/src/bmad-plus/agents/pack-backup/templates/backup-workflow.md +0 -51
- package/src/bmad-plus/agents/pack-seo/SKILL.md +0 -171
- package/src/bmad-plus/agents/pack-seo/checklist.md +0 -140
- package/src/bmad-plus/agents/pack-seo/pagespeed-playbook.md +0 -320
- package/src/bmad-plus/agents/pack-seo/ref/audit-schema.json +0 -187
- package/src/bmad-plus/agents/pack-seo/ref/cwv-thresholds.md +0 -87
- package/src/bmad-plus/agents/pack-seo/ref/eeat-criteria.md +0 -123
- package/src/bmad-plus/agents/pack-seo/ref/geo-signals.md +0 -167
- package/src/bmad-plus/agents/pack-seo/ref/hreflang-rules.md +0 -153
- package/src/bmad-plus/agents/pack-seo/ref/quality-gates.md +0 -133
- package/src/bmad-plus/agents/pack-seo/ref/schema-catalog.md +0 -91
- package/src/bmad-plus/agents/pack-seo/ref/schema-templates.json +0 -356
- package/src/bmad-plus/agents/pack-seo/seo-chief.md +0 -294
- package/src/bmad-plus/agents/pack-seo/seo-judge.md +0 -241
- package/src/bmad-plus/agents/pack-seo/seo-scout.md +0 -171
- 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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 };
|