bmad-plus 0.23.0 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +34 -24
  3. package/osint-agent-package/agents/osint-investigator.md +3 -3
  4. package/osint-agent-package/skills/bmad-osint-investigate/osint/SKILL.md +51 -51
  5. package/osint-agent-package/skills/bmad-osint-investigate/osint/references/content-extraction.md +7 -7
  6. package/osint-agent-package/skills/bmad-osint-investigate/osint/references/platforms.md +2 -2
  7. package/osint-agent-package/skills/bmad-osint-investigate/osint/references/tools.md +31 -41
  8. package/package.json +21 -5
  9. package/readme-international/README.de.md +34 -24
  10. package/readme-international/README.es.md +35 -25
  11. package/readme-international/README.fr.md +34 -24
  12. package/src/bmad-plus/agents/agent-maker/SKILL.md +39 -14
  13. package/src/bmad-plus/module.yaml +5 -4
  14. package/src/bmad-plus/packs/pack-animated/animated-website-agent.md +40 -14
  15. package/src/bmad-plus/packs/pack-animated/templates/animated-website-workflow.md +15 -12
  16. package/src/bmad-plus/packs/pack-backup/backup-agent.md +2 -1
  17. package/src/bmad-plus/packs/pack-backup/templates/backup-workflow.md +2 -0
  18. package/src/bmad-plus/packs/pack-memory/zecher-agent.md +1 -1
  19. package/src/bmad-plus/packs/pack-shield/README.md +1 -1
  20. package/src/bmad-plus/packs/pack-shield/SKILL.md +3 -3
  21. package/src/bmad-plus/packs/pack-shield/categories/industry-compliance/pci-dss-agent.md +1 -1
  22. package/src/bmad-plus/packs/pack-shield/shield-orchestrator.md +2 -2
  23. package/src/bmad-plus/skills/bmad-plus-parallel/SKILL.md +1 -1
  24. package/src/bmad-plus/skills/bmad-plus-swarm/SKILL.md +1 -1
  25. package/tools/build/adapters.config.js +1 -1
  26. package/tools/build/generate-adapters.js +1 -1
  27. package/tools/cli/commands/install.js +18 -11
  28. package/tools/cli/commands/nexus.js +2 -1
  29. package/tools/cli/commands/review.js +1 -1
  30. package/tools/cli/commands/update.js +30 -1
  31. package/tools/cli/i18n.js +30 -30
  32. package/tools/cli/lib/packs.js +6 -6
  33. package/tools/cli/lib/review.js +2 -1
  34. package/tools/cli/lib/update-dispatch.js +10 -2
  35. package/tools/cli/lib/update-transaction.js +1 -2
@@ -135,20 +135,33 @@ pack: {pack-name}
135
135
  ```
136
136
 
137
137
  #### 3. `pack-definition.yaml`
138
- A ready-to-merge snippet for `module.yaml`:
138
+ A ready-to-merge snippet for the `packs:` mapping of `registry.yaml`, the single source of truth
139
+ for packs and agents. `order` must be an integer no other pack uses, `cli.icon` a non-empty
140
+ string, and `summary` must not hard-code a count of agents, skills or workflows (the build
141
+ derives those):
139
142
 
140
143
  ```yaml
141
144
  {pack-name}:
142
- name: "{Pack Display Name}"
143
- icon: "{icon}"
144
- description: "{description}"
145
+ order: {next free integer}
146
+ display_name: "{Pack Display Name}"
147
+ icon_emoji: "{icon}"
148
+ cli: { name: "{Short CLI name}", icon: "{one letter}", desc: "{CLI description}" }
145
149
  required: false
146
- agents:
147
- - agent-{name}
150
+ runtime: [node]
151
+ summary: "{one sentence, no counts}"
152
+ agents: [agent-{name}]
153
+ personas:
154
+ - { id: agent-{name}, name: {PersonaName}, role: {Title}, description: "{description}" }
148
155
  skills: []
149
- required_keys: [] # if any API keys needed
156
+ install_layout: loose
157
+ compliance_tags: []
158
+ required_keys: [] # only if API keys are needed
150
159
  ```
151
160
 
161
+ `install_layout: loose` copies the agent directory `agents/agent-{name}/` into the project. A
162
+ pack that ships its files in one folder uses `install_layout: packaged` with `pack_dir`,
163
+ `pack_src_dir` and `doctor.pack_agents` instead: see the existing `backup` entry.
164
+
152
165
  #### 4. `INTEGRATION.md`
153
166
  Instructions for integrating the agent into BMAD+:
154
167
 
@@ -158,14 +171,26 @@ Instructions for integrating the agent into BMAD+:
158
171
  ## Files to copy
159
172
  - `agents/agent-{name}/` → `src/bmad-plus/agents/agent-{name}/`
160
173
 
161
- ## module.yaml update
162
- Add the pack definition from `pack-definition.yaml` to the `packs:` section.
174
+ ## Register the pack (registry first)
175
+ `registry.yaml` is the single source of truth. Never edit the files generated from it
176
+ (`tools/cli/lib/packs.js`, the pack metadata of `src/bmad-plus/module.yaml`, `AGENTS.md` and the
177
+ other adapters).
178
+ - New pack: add the entry from `pack-definition.yaml` under `packs:` in `registry.yaml`.
179
+ - New agent in an existing pack: add its id to that pack's `agents:` list and a line to its
180
+ `personas:` list (and to `doctor.pack_agents` when the pack uses the packaged layout).
163
181
 
164
182
  ## module-help.csv update
165
- Add: bmad-plus-agent-{name},"{help text}"
166
-
167
- ## installer update
168
- Add pack to `PACKS` object in `tools/cli/commands/install.js`
183
+ This file is maintained by hand. Add to `src/bmad-plus/module-help.csv`:
184
+ bmad-plus-agent-{name},"{help text}"
185
+
186
+ ## Regenerate and check
187
+ From the repository root, in this order:
188
+ 1. `npm run build` regenerates `tools/cli/lib/packs.js` and `src/bmad-plus/module.yaml`.
189
+ 2. `node tools/build/generate-adapters.js --adopt` regenerates `AGENTS.md` and the tool adapters
190
+ (`CLAUDE.md`, `GEMINI.md`, ...) with the new roster.
191
+ 3. `npm run build:check`, `node tools/build/generate-adapters.js --check --adopt` and
192
+ `npm run check:counts` must report no drift; `npm run check:triggers` too if you added
193
+ role triggers to `src/bmad-plus/data/role-triggers.yaml`.
169
194
 
170
195
  ## Test
171
196
  Run `npx bmad-plus install --packs {pack-name}` in a test project.
@@ -175,7 +200,7 @@ Run `npx bmad-plus install --packs {pack-name}` in a test project.
175
200
  After generating, run a self-check:
176
201
  - [ ] SKILL.md follows v6 format
177
202
  - [ ] Manifest has all required fields
178
- - [ ] Pack definition is valid YAML
203
+ - [ ] Pack definition is a valid `registry.yaml` pack entry (unique `order`, `cli`, `personas`)
179
204
  - [ ] Capabilities have unique 2-letter codes
180
205
  - [ ] Integration guide is complete
181
206
 
@@ -22,7 +22,7 @@ install_packs:
22
22
  - value: maker
23
23
  label: 🧬 Agent Creator — Design, build, validate, and package new BMAD+-compatible agents.
24
24
  - value: shield
25
- label: 🛡️ Shield — GRC Compliance — 27 compliance agents + 11 workflows across 26+ frameworks.
25
+ label: 🛡️ Shield — GRC Compliance — 27 compliance agents + 11 workflows across 27+ frameworks.
26
26
  - value: seo
27
27
  label: 🔍 SEO Audit 360 — 3 agents (Scout, Chief, Judge) + 6-phase audit + PageSpeed loop.
28
28
  - value: memory
@@ -136,13 +136,14 @@ packs:
136
136
  - agent-shadow
137
137
  skills: []
138
138
  external_package: osint-agent-package
139
- required_keys:
140
- - APIFY_API_TOKEN
141
139
  optional_keys:
140
+ - APIFY_API_TOKEN
142
141
  - PERPLEXITY_API_KEY
143
142
  - EXA_API_KEY
144
143
  - TAVILY_API_KEY
145
144
  - JINA_API_KEY
145
+ - PARALLEL_API_KEY
146
+ - BRIGHTDATA_MCP_URL
146
147
  maker:
147
148
  name: Agent Creator
148
149
  icon: 🧬
@@ -155,7 +156,7 @@ packs:
155
156
  shield:
156
157
  name: Shield — GRC Compliance
157
158
  icon: 🛡️
158
- description: 27 compliance agents + 11 workflows across 26+ frameworks.
159
+ description: 27 compliance agents + 11 workflows across 27+ frameworks.
159
160
  required: false
160
161
  agents:
161
162
  - shield-orchestrator
@@ -7,10 +7,12 @@ Tu es un expert en création de sites web animés de luxe. Tu convertis des vid
7
7
  Déclenché par les requêtes contenant : "animated website", "scroll animation", "video to website", "Apple-style page", "scroll-driven site", "frame animation", "convert video to website", "luxury website from video", "site animé", "animation scroll".
8
8
 
9
9
  ## Pré-requis
10
- - FFmpeg + FFprobe installés
11
- - Python 3
10
+ - FFmpeg + FFprobe installés, avec l'encodeur `libwebp` (vérification : `ffmpeg -hide_banner -encoders`, la liste doit contenir `libwebp`)
11
+ - Python 3 (uniquement pour l'aperçu local de l'étape 5 ; tout autre serveur de fichiers statiques convient)
12
12
  - Fichier vidéo MP4 source
13
13
 
14
+ Ce pack ne livre aucun script d'extraction : les frames s'extraient avec les commandes FFmpeg de l'étape 2.
15
+
14
16
  ---
15
17
 
16
18
  ## Processus Complet
@@ -44,24 +46,38 @@ Recommander le nombre de frames :
44
46
 
45
47
  ### Étape 2 — Extraire et optimiser les frames
46
48
 
47
- Utiliser le script `extract_frames.py` :
49
+ Deux commandes FFmpeg suffisent (aucun script à installer). Soit `D` la durée en secondes relevée à l'étape 1 et `N` le nombre de frames confirmé par l'utilisateur ; le filtre `fps=N/D` échantillonne la vidéo à intervalles réguliers et `-frames:v N` plafonne la sortie à `N` images. Créer d'abord les dossiers de sortie, FFmpeg ne les crée pas.
50
+
51
+ Durée de la vidéo, si elle n'a pas été relevée :
52
+ ```bash
53
+ ffprobe -v error -show_entries format=duration -of csv=p=0 "/path/to/video.mp4"
54
+ ```
48
55
 
49
- **Windows :**
56
+ **Windows (PowerShell) :**
50
57
  ```powershell
51
- python scripts/extract_frames.py --input "C:/path/to/video.mp4" --output "output/frames" --frames 120 --quality 80
58
+ New-Item -ItemType Directory -Force "output/frames/desktop", "output/frames/mobile"
59
+ ffmpeg -i "C:/path/to/video.mp4" -vf "fps=120/12.4,scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080" -c:v libwebp -quality 80 -compression_level 6 -frames:v 120 -start_number 0 "output/frames/desktop/frame-%04d.webp"
60
+ ffmpeg -i "C:/path/to/video.mp4" -vf "fps=120/12.4,scale=960:540:force_original_aspect_ratio=increase,crop=960:540" -c:v libwebp -quality 80 -compression_level 6 -frames:v 120 -start_number 0 "output/frames/mobile/frame-%04d.webp"
52
61
  ```
53
62
 
54
63
  **Mac/Linux :**
55
64
  ```bash
56
- python3 scripts/extract_frames.py --input "/path/to/video.mp4" --output "output/frames" --frames 120 --quality 80
65
+ mkdir -p output/frames/desktop output/frames/mobile
66
+ ffmpeg -i "/path/to/video.mp4" -vf "fps=120/12.4,scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080" -c:v libwebp -quality 80 -compression_level 6 -frames:v 120 -start_number 0 "output/frames/desktop/frame-%04d.webp"
67
+ ffmpeg -i "/path/to/video.mp4" -vf "fps=120/12.4,scale=960:540:force_original_aspect_ratio=increase,crop=960:540" -c:v libwebp -quality 80 -compression_level 6 -frames:v 120 -start_number 0 "output/frames/mobile/frame-%04d.webp"
57
68
  ```
58
69
 
59
- Le script produit :
60
- - `frames/desktop/` — WebP 1920x1080
61
- - `frames/mobile/` — WebP 960x540
62
- - `frames/manifest.json` — métadonnées
70
+ Les exemples supposent `N = 120` et `D = 12.4` : remplacer `120/12.4` et `-frames:v 120` par les valeurs réelles. `-quality 80` est la qualité WebP (1-100).
71
+
72
+ Résultat :
73
+ - `frames/desktop/` — WebP 1920x1080, `frame-0000.webp` à `frame-<N-1>.webp`
74
+ - `frames/mobile/` — WebP 960x540, même numérotation
75
+
76
+ `scale=…:force_original_aspect_ratio=increase,crop=…` remplit le cadre 16:9 et rogne les bords d'une source qui n'est pas en 16:9 ; pour une source verticale, demander à l'utilisateur quel cadrage il veut avant d'extraire.
63
77
 
64
- **Budget payload :** Desktop < 10MB, Mobile < 5MB.
78
+ Écrire ensuite `frames/manifest.json` avec le nombre de frames et le motif de nom (par exemple `{"count":120,"pattern":"frame-%04d.webp","desktop":"1920x1080","mobile":"960x540"}`) : c'est la valeur `FRAME_COUNT` du site généré. Vérifier que le nombre de fichiers de chaque dossier est égal à `N`.
79
+
80
+ **Budget payload :** Desktop < 10MB, Mobile < 5MB. Mesurer la taille des deux dossiers (`du -sh output/frames/desktop output/frames/mobile`, ou la somme des tailles de fichiers sous PowerShell) avant de continuer.
65
81
 
66
82
  ### Étape 3 — Contenu des 6 sections
67
83
 
@@ -126,6 +142,16 @@ python3 -m http.server 8080
126
142
  - **Labels :** DM Sans, 8-9px, weight 500, uppercase, letter-spacing 0.25-0.35em
127
143
  - **Hero :** `clamp(42px, 5.5vw, 76px)` — grand mais light
128
144
 
145
+ #### Chargement des polices : un choix à faire avec l'utilisateur
146
+
147
+ Playfair Display et DM Sans ne sont pas embarquées par BMAD+. Avant de générer le site, demander laquelle de ces options l'utilisateur veut (la première si aucune réponse) :
148
+
149
+ 1. **Polices système (défaut).** Ne rien charger : les piles de `--heading` et `--body` ci-dessus retombent sur Georgia et sur la police système. Aucune requête externe.
150
+ 2. **Polices auto-hébergées.** L'utilisateur fournit les fichiers `.woff2` (Playfair Display et DM Sans sont sous licence SIL Open Font ; il vérifie la licence de toute autre police), à placer dans le dossier du site et à déclarer avec `@font-face`. Aucune requête vers un tiers.
151
+ 3. **Google Fonts.** À n'utiliser que sur demande explicite, après avoir prévenu l'utilisateur que le navigateur de **chaque visiteur du site généré** contactera fonts.googleapis.com et fonts.gstatic.com (son adresse IP est donc transmise à Google) et que cela peut exiger une mention dans la politique de confidentialité du site. Cette requête est une propriété du site généré, pas de BMAD+ : BMAD+ lui-même n'envoie rien à Google.
152
+
153
+ Balise à insérer uniquement pour l'option 3 :
154
+
129
155
  ```html
130
156
  <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400&family=Playfair+Display:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&display=swap" rel="stylesheet">
131
157
  ```
@@ -213,7 +239,7 @@ Fichier HTML unique. Ordre structurel :
213
239
 
214
240
  ```
215
241
  HTML :
216
- 1. Google Fonts link
242
+ 1. Chargement des polices (option choisie : système, auto-hébergée ou lien Google Fonts)
217
243
  2. <style> — tout le CSS
218
244
  3. Cursor custom divs (#cursor-dot, #cursor-ring)
219
245
  4. Film grain overlay
@@ -316,8 +342,8 @@ Avant livraison, vérifier :
316
342
  | Problème | Solution |
317
343
  |---------|---------|
318
344
  | FFmpeg non trouvé | `winget install FFmpeg` (Win), `brew install ffmpeg` (Mac) |
319
- | Pas de libwebp | Reinstaller FFmpeg ou installer Pillow |
320
- | Frames trop lourdes (>10MB) | `--quality 60` ou `--frames 90` |
345
+ | Pas de libwebp | Installer une build de FFmpeg qui inclut `libwebp` (`ffmpeg -hide_banner -encoders` doit le lister) |
346
+ | Frames trop lourdes (>10MB) | `-quality 60` ou `-frames:v 90` (avec `fps=90/D`) |
321
347
  | Animation saccadée | Réduire frames, vérifier DPR cap à 2, réduire particules |
322
348
  | Flash blanc entre frames | Vérifier extraction, fallback nearest-frame |
323
349
  | Canvas blanc sur mobile | Vérifier existence des frames mobile, chemin FRAME_DIR |
@@ -8,32 +8,33 @@ Converts an MP4 video into a luxury scroll-driven animated website with canvas f
8
8
 
9
9
  ## Pre-requisites
10
10
 
11
- 1. FFmpeg installed (`winget install FFmpeg` on Windows, `brew install ffmpeg` on Mac)
12
- 2. Python 3 installed
11
+ 1. FFmpeg installed, with the `libwebp` encoder (`winget install FFmpeg` on Windows, `brew install ffmpeg` on Mac; `ffmpeg -hide_banner -encoders` must list `libwebp`)
12
+ 2. Python 3 installed (only for the local preview in step 6; any static file server works)
13
13
  3. Source MP4 video file
14
14
 
15
+ This pack ships no extraction script: the frames are extracted with the FFmpeg commands of step 3.
16
+
15
17
  ## Steps
16
18
 
17
19
  1. Ask the user for:
18
20
  - Path to the MP4 video file
19
21
  - Website concept (product, real estate, portfolio, etc.)
20
22
  - Optional: brand colors, section content, target frame count
23
+ - How fonts are loaded in the generated site (see step 5)
21
24
 
22
25
  2. Analyze the video:
23
26
  ```bash
24
27
  ffprobe -v quiet -print_format json -show_format -show_streams "VIDEO_PATH"
25
28
  ```
26
29
 
27
- 3. Extract frames using the script:
30
+ 3. Extract the frames with FFmpeg. `DURATION` is the video length in seconds from step 2; create the two output folders first (`mkdir -p OUTPUT_DIR/frames/desktop OUTPUT_DIR/frames/mobile`):
28
31
  ```bash
29
- python3 scripts/extract_frames.py \
30
- --input "VIDEO_PATH" \
31
- --output "OUTPUT_DIR/frames" \
32
- --frames FRAME_COUNT \
33
- --quality 80
32
+ ffmpeg -i "VIDEO_PATH" -vf "fps=FRAME_COUNT/DURATION,scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080" -c:v libwebp -quality 80 -compression_level 6 -frames:v FRAME_COUNT -start_number 0 "OUTPUT_DIR/frames/desktop/frame-%04d.webp"
33
+ ffmpeg -i "VIDEO_PATH" -vf "fps=FRAME_COUNT/DURATION,scale=960:540:force_original_aspect_ratio=increase,crop=960:540" -c:v libwebp -quality 80 -compression_level 6 -frames:v FRAME_COUNT -start_number 0 "OUTPUT_DIR/frames/mobile/frame-%04d.webp"
34
34
  ```
35
+ Then write `OUTPUT_DIR/frames/manifest.json` with the frame count and the file name pattern, and check that each folder holds `FRAME_COUNT` files and stays under the payload budget (desktop under 10 MB, mobile under 5 MB).
35
36
 
36
- 4. Generate the complete index.html following the design system in `agent/animated-website-agent.md`:
37
+ 4. Generate the complete index.html following the design system in `animated-website-agent.md` (the agent file of this pack):
37
38
  - Canvas frame-by-frame scroll animation
38
39
  - Scroll dwell engine with Gaussian density
39
40
  - 6 overlay sections (Hero, Vision, Details, Grid, Context, CTA)
@@ -42,14 +43,16 @@ python3 scripts/extract_frames.py \
42
43
  - Custom cursor, chapter markers, branded loader
43
44
  - Gallery with parallax
44
45
 
45
- 5. Serve and preview:
46
+ 5. Fonts. Use system fonts by default. Self-hosted `.woff2` files are the alternative that sends nothing to a third party. Use Google Fonts only when the user explicitly asks for it, after telling them that each visitor's browser will then contact Google's font servers (this concerns the generated site, not BMAD+).
47
+
48
+ 6. Serve and preview:
46
49
  ```bash
47
50
  cd OUTPUT_DIR
48
51
  python3 -m http.server 8080
49
52
  ```
50
53
 
51
- 6. Iterate based on user feedback (scroll speed, colors, content, etc.)
54
+ 7. Iterate based on user feedback (scroll speed, colors, content, etc.)
52
55
 
53
56
  ## Reference
54
57
 
55
- See `agent/animated-website-agent.md` for the complete design system, code architecture, and quality checklist.
58
+ See `animated-website-agent.md` for the complete design system, code architecture, and quality checklist.
@@ -35,7 +35,8 @@ PROJECT_NAME=$(basename "$PROJECT_ROOT")
35
35
  mkdir -p "$PROJECT_ROOT/backups"
36
36
  cd "$PROJECT_ROOT" && zip -r "backups/${PROJECT_NAME}_backup_$TIMESTAMP.zip" . \
37
37
  -x "backups/*" "node_modules/*" ".git/*" "vendor/*" "__pycache__/*" "*.backup_*"
38
- echo "✅ Backup: ${PROJECT_NAME}_backup_$TIMESTAMP.zip"
38
+ SIZE=$(du -h "backups/${PROJECT_NAME}_backup_$TIMESTAMP.zip" | cut -f1)
39
+ echo "✅ Backup: ${PROJECT_NAME}_backup_$TIMESTAMP.zip ($SIZE)"
39
40
  ```
40
41
 
41
42
  ### 2. `/backup-list` — Lister les backups
@@ -40,6 +40,8 @@ PROJECT_NAME=$(basename "$PROJECT_ROOT")
40
40
  mkdir -p "$PROJECT_ROOT/backups"
41
41
  cd "$PROJECT_ROOT" && zip -r "backups/${PROJECT_NAME}_backup_$TIMESTAMP.zip" . \
42
42
  -x "backups/*" "node_modules/*" ".git/*" "vendor/*" "__pycache__/*" "*.backup_*"
43
+ SIZE=$(du -h "backups/${PROJECT_NAME}_backup_$TIMESTAMP.zip" | cut -f1)
44
+ echo "Backup: ${PROJECT_NAME}_backup_$TIMESTAMP.zip ($SIZE)"
43
45
  ```
44
46
 
45
47
  2. Confirm the backup was created and report the file name and size.
@@ -101,7 +101,7 @@ You are NOT an orchestrator. You are a **utility agent** — called upon by othe
101
101
  Recursively walk the target path
102
102
  Identify project roots by marker files (package.json, .git, Cargo.toml, etc.)
103
103
  Skip: node_modules, .git internals, vendor, __pycache__, dist, build
104
- Depth limit: configurable (default 3 levels)
104
+ Depth limit: configurable with `bmad-plus scan --depth <n>` (default 4 levels below the scanned directory)
105
105
  </step>
106
106
  <step n="2" goal="Analyze each project">
107
107
  For each discovered project root:
@@ -41,7 +41,7 @@ Pack Shield transforms BMAD+ into a comprehensive GRC (Governance, Risk & Compli
41
41
  | Agent | Framework | Jurisdiction |
42
42
  |-------|-----------|-------------|
43
43
  | `soc2-agent` | SOC 2 Type I/II | US/Global |
44
- | `pci-dss-agent` | PCI DSS v4.0 | International |
44
+ | `pci-dss-agent` | PCI DSS v4.0.1 | International |
45
45
  | `hipaa-agent` | HIPAA | US Healthcare |
46
46
  | `swift-csp-agent` | SWIFT CSP | Intl. Banking |
47
47
  | `dora-agent` | DORA | EU Financial |
@@ -8,7 +8,7 @@
8
8
 
9
9
  ## Overview
10
10
 
11
- Shield transforms BMAD+ into a comprehensive GRC (Governance, Risk & Compliance) assistant. It serves as an intelligent orchestrator for 27 compliance agents across 6 categories, plus 11 GDPR & AI Act workflows, covering 25+ regulatory frameworks. Route requests to the appropriate specialist agent, combine insights for cross-framework analysis, and provide consolidated compliance reports.
11
+ Shield transforms BMAD+ into a comprehensive GRC (Governance, Risk & Compliance) assistant. It serves as an intelligent orchestrator for 27 compliance agents across 6 categories, plus 11 GDPR & AI Act workflows, covering 27 regulatory frameworks. Route requests to the appropriate specialist agent, combine insights for cross-framework analysis, and provide consolidated compliance reports.
12
12
 
13
13
  ## Capabilities
14
14
 
@@ -29,7 +29,7 @@ Shield transforms BMAD+ into a comprehensive GRC (Governance, Risk & Compliance)
29
29
 
30
30
  ### Industry Compliance (6 frameworks)
31
31
  - **SOC 2 Type I/II** — Service Organization Controls
32
- - **PCI DSS v4.0** — Payment Card Industry
32
+ - **PCI DSS v4.0.1** — Payment Card Industry
33
33
  - **HIPAA** — Healthcare Privacy & Security
34
34
  - **SWIFT CSP** — Banking Security
35
35
  - **DORA** — EU Digital Operational Resilience
@@ -66,7 +66,7 @@ Shield transforms BMAD+ into a comprehensive GRC (Governance, Risk & Compliance)
66
66
  To use Shield, include this pack in your BMAD+ installation:
67
67
 
68
68
  ```bash
69
- npx bmad-plus install --pack shield
69
+ npx bmad-plus install --packs shield
70
70
  ```
71
71
 
72
72
  Then invoke the orchestrator from any conversation:
@@ -1,7 +1,7 @@
1
1
  # PCI DSS Compliance Agent
2
2
 
3
3
  > **Pack:** Shield (GRC Audit) -- Industry Compliance
4
- > **Framework:** PCI DSS v4.0
4
+ > **Framework:** PCI DSS v4.0.1
5
5
  > **Version:** 1.0.0
6
6
  > **Based on:** Claude Skills for GRC by Hemant Naik (Sushegaad) -- MIT License
7
7
  > **Upstream:** https://github.com/Sushegaad/Claude-Skills-Governance-Risk-and-Compliance
@@ -11,7 +11,7 @@
11
11
 
12
12
  ## Persona
13
13
 
14
- You are **Shield**, an expert GRC (Governance, Risk & Compliance) orchestrator. You serve as the intelligent entry point for regulatory and compliance queries. You understand 25+ compliance frameworks and 11 workflow agents. You route requests to the appropriate specialist agent, combine insights from multiple agents for cross-framework analysis, and provide consolidated compliance reports.
14
+ You are **Shield**, an expert GRC (Governance, Risk & Compliance) orchestrator. You serve as the intelligent entry point for regulatory and compliance queries. You understand 27 compliance frameworks and 11 workflow agents. You route requests to the appropriate specialist agent, combine insights from multiple agents for cross-framework analysis, and provide consolidated compliance reports.
15
15
 
16
16
  ---
17
17
 
@@ -40,7 +40,7 @@ You are **Shield**, an expert GRC (Governance, Risk & Compliance) orchestrator.
40
40
  | Agent | Framework | Jurisdiction |
41
41
  |-------|-----------|-------------|
42
42
  | `soc2-agent` | SOC 2 Type I/II | US (global use) |
43
- | `pci-dss-agent` | PCI DSS v4.0 | International |
43
+ | `pci-dss-agent` | PCI DSS v4.0.1 | International |
44
44
  | `hipaa-agent` | HIPAA Privacy & Security | US Healthcare |
45
45
  | `swift-csp-agent` | SWIFT CSP | International Banking |
46
46
  | `dora-agent` | DORA (EU 2022/2554) | EU Financial |
@@ -109,7 +109,7 @@ This skill is automatically invoked by the Autopilot when `{parallel_execution}`
109
109
  ## Swarms
110
110
 
111
111
  Parallel stories share one goal and differ in content; a **swarm** repeats one kind of work
112
- across many units. Four kinds, one runtime (`bmad-plus swarm`), one moderator skill
112
+ across many units. Three kinds, one runtime (`bmad-plus swarm`), one moderator skill
113
113
  (`bmad-plus-swarm`):
114
114
 
115
115
  | Kind | Units | Substrate |
@@ -22,7 +22,7 @@ definition + profile|list|units ─► init ─► cards.json ─► briefs ─
22
22
 
23
23
  Read `ref/definition.md` for the four file contracts with one example each.
24
24
 
25
- ## The four kinds
25
+ ## The three kinds
26
26
 
27
27
  | Kind | Units come from | Typical use | Tally |
28
28
  |---|---|---|---|
@@ -72,7 +72,7 @@ const UPDATE_INSTRUCTIONS = [
72
72
  '## Framework updates',
73
73
  '',
74
74
  'Once per session, check the installed framework before starting project work. If this is the BMAD+ source checkout, use `node tools/cli/bmad-plus-cli.js update-check --json`; otherwise use `npx --no-install bmad-plus update-check --json` from the project root.',
75
- 'If the command is unavailable or the result is off, unknown, offline or stale, continue the user task. Do not install a CLI just to perform this check or claim that an offline version is current.',
75
+ 'If the command is unavailable (for example npx cannot find `bmad-plus` because the project has no local copy of the package), or the result is off, unknown, offline or stale, continue the user task without mentioning the check. Do not install a CLI just to perform this check or claim that an offline version is current.',
76
76
  'When `updateAvailable` is true and `canAutoApply` is true, run the same CLI with `update --latest --auto`. This follows the project update policy; it does not grant permission to expand that policy.',
77
77
  'When an update is available but automatic application is not eligible, explain the version and reason. An explicit request to update can be fulfilled with `update --latest --yes`; do not change the policy, overwrite customized files, or resolve conflicts without the user request covering that action.',
78
78
  'After a successful update, reread the project spine and relevant installed skills, or start a fresh session if the client cannot reload them. Respect preserved local instructions. Check only once even when several adapters include this section.',
@@ -468,7 +468,7 @@ function userMarkerLines() {
468
468
  return [
469
469
  '<!-- ' + GENERATED_MARKER + ' — DO NOT EDIT. -->',
470
470
  '<!-- ' + USER_CONFIG_MARKER + ' -->',
471
- '<!-- Refresh installed adapters with: npx bmad-plus update -->',
471
+ '<!-- Refresh installed adapters with: npx bmad-plus@latest update -->',
472
472
  ];
473
473
  }
474
474
 
@@ -561,15 +561,15 @@ module.exports = {
561
561
  }
562
562
 
563
563
  if (selectedPacks.includes('seo')) {
564
- agentGuide.push(` ${i.guide_seo.padEnd(28)} → "/seo audit <url>"`);
564
+ agentGuide.push(` ${i.guide_seo.padEnd(28)} → "/seo full <url>"`);
565
565
  }
566
566
 
567
567
  if (selectedPacks.includes('backup')) {
568
- agentGuide.push(` ${i.guide_backup.padEnd(28)} → "/backup create"`);
568
+ agentGuide.push(` ${i.guide_backup.padEnd(28)} → "/backup"`);
569
569
  }
570
570
 
571
571
  if (selectedPacks.includes('animated')) {
572
- agentGuide.push(` ${i.guide_animated.padEnd(28)} → "/animated build <video>"`);
572
+ agentGuide.push(` ${i.guide_animated.padEnd(28)} → "animated website from <video.mp4>"`);
573
573
  }
574
574
 
575
575
  if (selectedPacks.includes('design')) {
@@ -609,7 +609,7 @@ module.exports = {
609
609
  '',
610
610
  `📦 ${i.guide_cli_title || 'CLI Commands'}:`,
611
611
  ` npx bmad-plus install ${i.guide_cli_install || '— Install agents & skills'}`,
612
- ` npx bmad-plus update ${i.guide_cli_update || '— Update agents (keeps config)'}`,
612
+ ` npx bmad-plus@latest update ${i.guide_cli_update || '— Update agents (keeps config)'}`,
613
613
  ` npx bmad-plus doctor ${i.guide_cli_doctor || '— Check installation health'}`,
614
614
  ` npx bmad-plus uninstall ${i.guide_cli_uninstall || '— Remove BMAD+ from project'}`
615
615
  );
@@ -617,15 +617,15 @@ module.exports = {
617
617
  // Add pack-specific examples
618
618
  const examples = [];
619
619
  if (selectedPacks.includes('seo')) {
620
- examples.push(` ${i.guide_example_seo || '🔍 SEO: "/seo audit https://example.com"'}`);
620
+ examples.push(` ${i.guide_example_seo || '🔍 SEO: "/seo full https://example.com"'}`);
621
621
  }
622
622
  if (selectedPacks.includes('backup')) {
623
- examples.push(
624
- ` ${i.guide_example_backup || '🗂️ Backup: "/backup create" → ZIP timestamped'}`
625
- );
623
+ examples.push(` ${i.guide_example_backup || '🗂️ Backup: "/backup" → ZIP timestamped'}`);
626
624
  }
627
625
  if (selectedPacks.includes('animated')) {
628
- examples.push(` ${i.guide_example_animated || '🎬 Animated: "/animated build hero.mp4"'}`);
626
+ examples.push(
627
+ ` ${i.guide_example_animated || '🎬 Animated: "animated website from hero.mp4"'}`
628
+ );
629
629
  }
630
630
  if (selectedPacks.includes('design')) {
631
631
  examples.push(
@@ -786,6 +786,13 @@ function mergeSettings(existing, defaults, explicit) {
786
786
  return merged;
787
787
  }
788
788
 
789
+ /**
790
+ * Plain YAML under every supported js-yaml: forceQuotes is avoided because 5.2.x
791
+ * tags forced scalars (`!!bool 'true'`, `!!int '3'`) while 5.5 does not. Strings that
792
+ * would read as another type are still quoted by the dumper.
793
+ */
794
+ const CONFIG_DUMP = { lineWidth: -1, quotingType: '"' };
795
+
789
796
  /** Returns null when the existing file is not a YAML mapping (left untouched). */
790
797
  function mergeConfigYaml(existingText, generatedText, explicit = {}) {
791
798
  let existing;
@@ -801,7 +808,7 @@ function mergeConfigYaml(existingText, generatedText, explicit = {}) {
801
808
  changed: true,
802
809
  content:
803
810
  '# BMAD+ Project Configuration\n# Generated by bmad-plus install; existing settings preserved\n\n' +
804
- yaml.dump(merged, { lineWidth: -1, forceQuotes: true, quotingType: '"' }),
811
+ yaml.dump(merged, CONFIG_DUMP),
805
812
  };
806
813
  }
807
814
 
@@ -847,7 +854,7 @@ function generateConfigYaml(
847
854
  // never covered by a budget, the host always asks.
848
855
  swarm: { ...SWARM_DEFAULTS },
849
856
  },
850
- { lineWidth: -1, forceQuotes: true, quotingType: '"' }
857
+ CONFIG_DUMP
851
858
  )
852
859
  );
853
860
  }
@@ -105,7 +105,8 @@ module.exports = {
105
105
  process.exitCode = 1;
106
106
  if (options.json)
107
107
  console.log(JSON.stringify({ schemaVersion: 1, status: 'error', error: error.message }));
108
- else console.error('Nexus: ' + error.message);
108
+ else
109
+ console.error(/^Nexus: /.test(error.message) ? error.message : 'Nexus: ' + error.message);
109
110
  }
110
111
  },
111
112
  };
@@ -205,7 +205,7 @@ module.exports = {
205
205
  options: [
206
206
  ['-d, --directory <path>', 'Project directory'],
207
207
  ['--dir <path>', 'Review folder inside the project', review.DEFAULT_DIR],
208
- ['--base <ref>', 'Base commit or branch (default HEAD~1)'],
208
+ ['--base <ref>', 'Base commit or branch (default HEAD~1, HEAD with --workspace)'],
209
209
  ['--head <ref>', 'Head commit or branch (default HEAD)'],
210
210
  ['--workspace', 'Review the working tree, untracked files included, against the base'],
211
211
  ['--include <glob>', 'Only review matching paths (repeatable)', (v, all) => [...all, v], []],
@@ -20,7 +20,33 @@ const { planUpdate, applyPlan, restoreUpdate, MANIFEST } = require('../lib/updat
20
20
  function authorizeAuto(projectDir, version) {
21
21
  const { readUpdatePolicy, authorizeTarget } = require('../lib/update-policy');
22
22
  const decision = authorizeTarget(readUpdatePolicy(projectDir), version);
23
- if (!decision.allowed) throw new Error('Automatic update refused: ' + decision.reason);
23
+ if (!decision.allowed) throw require('../lib/update-dispatch').autoRefusal(decision.reason);
24
+ }
25
+
26
+ // npx runs a cached or project-local copy of the package before it asks the registry, so a plain
27
+ // `update` can install an older release than the published one. Say so instead of staying silent.
28
+ async function warnIfBehindRegistry(projectDir, version) {
29
+ let check;
30
+ try {
31
+ check = await require('../lib/update-check').checkForUpdate({
32
+ projectDir,
33
+ runningVersion: version,
34
+ });
35
+ } catch {
36
+ return;
37
+ }
38
+ const latest = check.latestVersion;
39
+ if (!isExactVersion(latest) || !semver.gt(latest, version)) return;
40
+ clack.log.warn(
41
+ 'This copy of BMAD+ is v' +
42
+ version +
43
+ ' but v' +
44
+ latest +
45
+ ' is published (npx reuses a cached copy). Stop and run `npx bmad-plus@latest update`, or ' +
46
+ '`npx bmad-plus update --latest`, to install v' +
47
+ latest +
48
+ '.'
49
+ );
24
50
  }
25
51
 
26
52
  async function confirmAction(options, message, lang = 'en') {
@@ -118,6 +144,9 @@ module.exports = {
118
144
  throw new Error('Downgrade refused: ' + manifest.version + ' -> ' + version);
119
145
  const lang = options.lang || manifest.uiLanguage || 'en';
120
146
  clack.log.info('Installed: v' + manifest.version + ' -> Executing package: v' + version);
147
+ if (!options.auto && !options.expectedVersion) {
148
+ await warnIfBehindRegistry(projectDir, version);
149
+ }
121
150
  if (manifest.version === version) {
122
151
  clack.log.success(
123
152
  'The installed version matches this executing package. Use --latest to check the registry.'