ma-agents 3.5.1 → 3.5.3

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/README.md +20 -10
  2. package/lib/agents.js +7 -7
  3. package/lib/bmad-cache/bmb/.claude-plugin/marketplace.json +4 -3
  4. package/lib/bmad-cache/bmb/_git_preserved/index +0 -0
  5. package/lib/bmad-cache/bmb/_git_preserved/logs/HEAD +1 -1
  6. package/lib/bmad-cache/bmb/_git_preserved/logs/refs/heads/main +1 -1
  7. package/lib/bmad-cache/bmb/_git_preserved/logs/refs/remotes/origin/HEAD +1 -1
  8. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.idx +0 -0
  9. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/{pack-5e915049d8459481e4aa7be8d5959643fa68a981.pack → pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.pack} +0 -0
  10. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.rev +0 -0
  11. package/lib/bmad-cache/bmb/_git_preserved/packed-refs +1 -1
  12. package/lib/bmad-cache/bmb/_git_preserved/refs/heads/main +1 -1
  13. package/lib/bmad-cache/bmb/_git_preserved/shallow +1 -1
  14. package/lib/bmad-cache/bmb/samples/sample-module-setup/assets/module-help.csv +16 -0
  15. package/lib/bmad-cache/bmb/samples/sample-module-setup/assets/module.yaml +13 -0
  16. package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/cleanup-legacy.py +259 -0
  17. package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-config.py +408 -0
  18. package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-help-csv.py +218 -0
  19. package/lib/bmad-cache/cache-manifest.json +3 -3
  20. package/lib/bmad-extension/module-help.csv +0 -1
  21. package/lib/bmad-extension/skills/bmad-ma-agent-sqa/SKILL.md +24 -11
  22. package/lib/bmad-extension/skills/bmad-ma-agent-sqa/bmad-skill-manifest.yaml +6 -6
  23. package/lib/skill-authoring.js +2 -2
  24. package/package.json +1 -1
  25. package/test/agent-injection-strategy.test.js +1 -1
  26. package/test/bmad-extension.test.js +2 -2
  27. package/test/convert-agents-to-skills.test.js +8 -8
  28. package/test/extension-module-restructure.test.js +6 -6
  29. package/test/migration-validation.test.js +20 -16
  30. package/test/skill-customize-agent.test.js +2 -2
  31. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-5e915049d8459481e4aa7be8d5959643fa68a981.idx +0 -0
  32. package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-5e915049d8459481e4aa7be8d5959643fa68a981.rev +0 -0
  33. package/lib/bmad-extension/skills/bmad-ma-agent-mil498/.gitkeep +0 -0
  34. package/lib/bmad-extension/skills/bmad-ma-agent-mil498/SKILL.md +0 -54
  35. package/lib/bmad-extension/skills/bmad-ma-agent-mil498/bmad-skill-manifest.yaml +0 -11
package/README.md CHANGED
@@ -128,8 +128,8 @@ These domain-expert agents are installed alongside BMAD-METHOD and provide guide
128
128
  | SRE Agent | Alex | `_bmad/skills/sre/` | `_bmad/bmm/agents/sre.md` |
129
129
  | DevOps Agent | Amit | `_bmad/skills/devops/` | `_bmad/bmm/agents/devops.md` |
130
130
  | Cyber Analyst | Yael | `_bmad/skills/cyber/` | `_bmad/bmm/agents/cyber.md` |
131
- | MIL-STD-498 Expert | Joseph | `_bmad/skills/mil498/` | `_bmad/bmm/agents/mil498.md` |
132
131
  | ML Scientist | Demerzel | `_bmad/skills/demerzel/` | `_bmad/bmm/agents/demerzel.md` |
132
+ | SQA & Standards Expert | Gad | `_bmad/skills/sqa/` | `_bmad/bmm/agents/qa.md` |
133
133
 
134
134
  ## Available Skills
135
135
 
@@ -173,7 +173,7 @@ These skills are installed into your coding tool of choice and provide reusable
173
173
  | `docker-image-signing` | Security | Automated cryptographic signing for Docker images |
174
174
  | `docker-hardening-verification` | Security | Audits images for least-privilege and OpenShift compatibility |
175
175
 
176
- ### Agent Workflows (24)
176
+ ### Agent Workflows (34)
177
177
 
178
178
  These workflows are installed as part of the BMAD agent system and are invoked through the agent's menu (not installed individually):
179
179
 
@@ -192,8 +192,18 @@ These workflows are installed as part of the BMAD agent system and are invoked t
192
192
  | `ml-revision` | ML Scientist | Amend hypothesis and requirements based on experiment findings |
193
193
  | `ml-advise` | ML Scientist | Search past experiments, surface findings and failure warnings |
194
194
  | `ml-retrospective` | ML Scientist | Capture session learnings and update project context |
195
- | **MIL-STD-498 (Joseph)** | | |
196
- | `mil498-requirement-quality` | MIL-STD-498 Expert | Evaluate requirements against 14 quality criteria produces per-requirement audit table, Missing Elements report, and Overall Quality Score |
195
+ | **SQA & MIL-STD-498 (Gad)** | | |
196
+ | `sqa-audit` | SQA & Standards Expert | Multi-dimensional project quality audit: code↔story traceability, stories↔architecture/PRD alignment, process compliance, sprint health, release state — saves audit report and optional remediation plan |
197
+ | `sqa-ieee12207` | SQA & Standards Expert | IEEE/ISO/IEC 12207:2017 compliance assessment across 23 process areas in 4 groups — produces compliance matrix, gap analysis, and optional remediation plan |
198
+ | `sqa-requirements-quality` | SQA & Standards Expert | Requirements quality audit against 14 criteria with scope selection (PRD FRs, NFRs, epics, stories) — per-requirement audit table, critical-fail detection, Overall Quality Score, and optional remediation plan |
199
+ | `mil498-srs` | SQA & Standards Expert | Generate Software Requirements Specification (SRS) per MIL-STD-498 DID |
200
+ | `mil498-sdd` | SQA & Standards Expert | Generate Software Design Description (SDD) per MIL-STD-498 DID |
201
+ | `mil498-sdp` | SQA & Standards Expert | Generate Software Development Plan (SDP) per MIL-STD-498 DID |
202
+ | `mil498-ocd` | SQA & Standards Expert | Generate Operational Concept Description (OCD) per MIL-STD-498 DID |
203
+ | `mil498-sss` | SQA & Standards Expert | Generate System/Subsystem Specification (SSS) per MIL-STD-498 DID |
204
+ | `mil498-std` | SQA & Standards Expert | Generate Software Test Description (STD) per MIL-STD-498 DID |
205
+ | `mil498-ssdd` | SQA & Standards Expert | Generate System/Subsystem Design Description (SSDD) per MIL-STD-498 DID |
206
+ | `mil498-requirement-quality` | SQA & Standards Expert | Evaluate requirements against 14 quality criteria — per-requirement audit table, Missing Elements report, and Overall Quality Score (MIL-STD-498 context) |
197
207
  | **Sprint Management** | | |
198
208
  | `bmad-sprint-planning` | Scrum Master | Bootstrap or refresh the unified `sprint-status.yaml` from epics and bug stories |
199
209
  | `generate-backlog` | Scrum Master | Generate or refresh the `backlog` section of `sprint-status.yaml` from epics |
@@ -283,15 +293,15 @@ npx ma-agents install --yes # fully offline BMAD install — no network neede
283
293
  - **Focus**: Cyber immunity, security auditing, and vulnerability management.
284
294
  - **Capabilities**: Immunity estimation (scoring), Vault secret management, and PKI automation.
285
295
  - **Integration**: Orchestrates ma-agents security skills for deep scans.
286
- 4. **Joseph (MIL-STD-498)**:
287
- - **Focus**: Technical standards compliance and military document generation.
288
- - **Capabilities**: Document Data Descriptions (DIDs), requirements traceability, and complex specification writing.
289
- - **Workflows**: SRS, SSS, and SSDD generation with strict structural validation.
290
- - **Requirements QA**: Built-in `mil498-requirement-quality` skill — evaluates every requirement against 14 quality criteria (Clarity, Single Verb, Sentence Structure, Glossary Presence, Necessity, Implementation-Independence, Unambiguity, Completeness, Feasibility, Testability, Stakeholder Alignment, Convention Conformance, Understandability, Precision). Produces a per-requirement audit table, a Missing Elements report, and an Overall Quality Score. Applies to MIL-STD-498 documents, PRDs, and Epics/Stories.
291
- 5. **Demerzel (ML Scientist)**:
296
+ 4. **Demerzel (ML Scientist)**:
292
297
  - **Focus**: Hypothesis-driven machine learning lifecycle with scientific rigor.
293
298
  - **Capabilities**: EDA, architecture design, locked TechSpec contracts, experiment execution, failure-cost analysis.
294
299
  - **Workflows**: 12-stage ML lifecycle from ideation through retrospective, with mandatory review gates.
300
+ 5. **Gad (SQA & Standards Expert)**:
301
+ - **Focus**: Software quality assurance and defense documentation standards — a unified persona covering SQA auditing and MIL-STD-498 document generation.
302
+ - **SQA Capabilities**: Multi-dimensional project quality audits, IEEE/ISO/IEC 12207:2017 compliance assessments (23 process areas, 4 groups), requirements evaluation against 14 established quality criteria (scope-selectable: PRD FRs, NFRs, epics, stories).
303
+ - **MIL-STD-498 Capabilities**: Full Data Item Description (DID) generation for SRS, SDD, SDP, OCD, SSS, STD, and SSDD. Requirements quality review tailored to MIL-STD-498 structure and military-standard terminology (CSCI, HWCI, IRS).
304
+ - **Remediation**: All audit and compliance workflows offer an optional remediation plan (`sqa-remediation-plan-{date}.md`) and per-finding `create-bug-story` integration for critical gaps.
295
305
 
296
306
  #### Operational Workflows
297
307
  The integration includes a suite of specialized playbooks:
package/lib/agents.js CHANGED
@@ -273,17 +273,17 @@ const agents = [
273
273
  injectionStrategy: { position: 'top', skipPatterns: ['---'] }
274
274
  },
275
275
  {
276
- id: 'bmm-mil498',
277
- name: 'MIL-STD-498 Expert',
278
- version: '2.0.0',
276
+ id: 'bmm-qa',
277
+ name: 'SQA & Standards Expert (Gad)',
278
+ version: '1.0.0',
279
279
  category: 'bmad',
280
- description: 'MIL-STD-498 Documentation Expert',
281
- skillsDir: '_bmad/skills/mil498',
282
- getProjectPath: () => path.join(process.cwd(), '_bmad', 'skills', 'mil498'),
280
+ description: 'Software Quality Assurance and MIL-STD-498 Standards Expert (Gad)',
281
+ skillsDir: '_bmad/skills/sqa',
282
+ getProjectPath: () => path.join(process.cwd(), '_bmad', 'skills', 'sqa'),
283
283
  getGlobalPath: () => null,
284
284
  fileExtension: '.md',
285
285
  template: 'generic',
286
- instructionFiles: ['_bmad/bmm/agents/mil498.md'],
286
+ instructionFiles: ['_bmad/bmm/agents/qa.md'],
287
287
  injectionStrategy: { position: 'top', skipPatterns: ['---'] }
288
288
  },
289
289
  {
@@ -25,7 +25,7 @@
25
25
  },
26
26
  {
27
27
  "name": "sample-plugins",
28
- "source": "./samples",
28
+ "source": "./",
29
29
  "description": "Sample plugins demonstrating how to build BMad agents and skills. Includes a code coach, creative muse, diagram reviewer, dream weaver, sentinel, and excalidraw generator.",
30
30
  "version": "1.0.0",
31
31
  "author": {
@@ -37,12 +37,13 @@
37
37
  "./samples/bmad-agent-diagram-reviewer",
38
38
  "./samples/bmad-agent-dream-weaver",
39
39
  "./samples/bmad-agent-sentinel",
40
- "./samples/bmad-excalidraw"
40
+ "./samples/bmad-excalidraw",
41
+ "./samples/sample-module-setup"
41
42
  ]
42
43
  },
43
44
  {
44
45
  "name": "bmad-dream-weaver-agent",
45
- "source": "./samples/bmad-agent-dream-weaver",
46
+ "source": "./",
46
47
  "description": "Dream journaling and interpretation agent with lucid dreaming coaching, pattern discovery, symbol analysis, and recall training.",
47
48
  "version": "1.0.0",
48
49
  "author": {
@@ -1 +1 @@
1
- 0000000000000000000000000000000000000000 a873b7f0b30be65e1525e4e08ff046ae07c724af Alon Mayaffit <alon.mayafit@gmail.com> 1775683158 +0300 clone: from https://github.com/bmad-code-org/bmad-builder
1
+ 0000000000000000000000000000000000000000 605e07656f9f633b5e429297388e1db9687d1996 Alon Mayaffit <alon.mayafit@gmail.com> 1775729260 +0300 clone: from https://github.com/bmad-code-org/bmad-builder
@@ -1 +1 @@
1
- 0000000000000000000000000000000000000000 a873b7f0b30be65e1525e4e08ff046ae07c724af Alon Mayaffit <alon.mayafit@gmail.com> 1775683158 +0300 clone: from https://github.com/bmad-code-org/bmad-builder
1
+ 0000000000000000000000000000000000000000 605e07656f9f633b5e429297388e1db9687d1996 Alon Mayaffit <alon.mayafit@gmail.com> 1775729260 +0300 clone: from https://github.com/bmad-code-org/bmad-builder
@@ -1 +1 @@
1
- 0000000000000000000000000000000000000000 a873b7f0b30be65e1525e4e08ff046ae07c724af Alon Mayaffit <alon.mayafit@gmail.com> 1775683158 +0300 clone: from https://github.com/bmad-code-org/bmad-builder
1
+ 0000000000000000000000000000000000000000 605e07656f9f633b5e429297388e1db9687d1996 Alon Mayaffit <alon.mayafit@gmail.com> 1775729260 +0300 clone: from https://github.com/bmad-code-org/bmad-builder
@@ -1,2 +1,2 @@
1
1
  # pack-refs with: peeled fully-peeled sorted
2
- a873b7f0b30be65e1525e4e08ff046ae07c724af refs/remotes/origin/main
2
+ 605e07656f9f633b5e429297388e1db9687d1996 refs/remotes/origin/main
@@ -1 +1 @@
1
- a873b7f0b30be65e1525e4e08ff046ae07c724af
1
+ 605e07656f9f633b5e429297388e1db9687d1996
@@ -1 +1 @@
1
- a873b7f0b30be65e1525e4e08ff046ae07c724af
1
+ 605e07656f9f633b5e429297388e1db9687d1996
@@ -0,0 +1,16 @@
1
+ module,skill,display-name,menu-code,description,action,args,phase,after,before,required,output-location,outputs
2
+ BMad Samples,sample-module-setup,Setup Samples Module,SS,"Install or update BMad Samples module config and help entries.",configure,"{-H: headless mode}|{inline values: skip prompts with provided values}",anytime,,,false,{project-root}/_bmad,config.yaml and config.user.yaml
3
+ BMad Samples,bmad-agent-code-coach,Code Coaching,TC,"Personal coding coaching and mentoring — code review, pair programming, and learning paths.",activate,,anytime,,,false,,coaching session
4
+ BMad Samples,bmad-agent-creative-muse,Creative Muse,TM,"Creative brainstorming, problem-solving, and storytelling companion.",activate,,anytime,,,false,,creative session
5
+ BMad Samples,bmad-agent-diagram-reviewer,Diagram Review,DR,"Review architecture diagrams for gaps, ambiguities, and missing connections.",diagram-review,,anytime,,,false,,review findings
6
+ BMad Samples,bmad-agent-dream-weaver,Dream Capture,DL,"Capture and log a dream through guided conversation.",dream-log,,anytime,,,false,,journal entry
7
+ BMad Samples,bmad-agent-dream-weaver,Dream Interpretation,DI,"Analyze a dream for symbolism, meaning, and personal connections.",dream-interpret,,anytime,sam:dream-log,,false,,interpretation
8
+ BMad Samples,bmad-agent-dream-weaver,Recall Training,RT,"Dream recall exercises and progress tracking.",recall-training,,anytime,,,false,,coaching updates
9
+ BMad Samples,bmad-agent-dream-weaver,Lucid Coaching,LC,"Progressive lucid dreaming training and milestone tracking.",lucid-coach,,anytime,sam:recall-training,,false,,coaching updates
10
+ BMad Samples,bmad-agent-dream-weaver,Dream Seeding,DS,"Pre-sleep dream incubation — plant themes and intentions.",dream-seed,,anytime,,,false,,seed log entry
11
+ BMad Samples,bmad-agent-dream-weaver,Pattern Discovery,PD,"Surface recurring themes, symbols, and emotional patterns across dreams.",pattern-discovery,,anytime,sam:dream-log,,false,,pattern analysis
12
+ BMad Samples,bmad-agent-dream-weaver,Dream Query,DQ,"Search dream history by symbol, emotion, date, or keyword.",dream-query,,anytime,sam:dream-log,,false,,search results
13
+ BMad Samples,bmad-agent-dream-weaver,Save Memory,SM,"Save current session context to memory.",save-memory,,anytime,,,false,,memory checkpoint
14
+ BMad Samples,bmad-agent-sentinel,Sentinel Coaching,TS,"Strategic coaching — risk radar, decision stress-testing, and execution accountability.",activate,,anytime,,,false,,coaching session
15
+ BMad Samples,bmad-excalidraw,Create Diagram,XD,"Create Excalidraw diagrams through guided or autonomous workflows.",diagram-generation,"{-H: headless mode}|{--yolo: quick generation}",anytime,,,false,sample_output_folder,excalidraw file
16
+ BMad Samples,bmad-excalidraw,Validate Diagram,XV,"Validate an Excalidraw file's structure and report issues.",validate,,anytime,sam:diagram-generation,,false,,validation report
@@ -0,0 +1,13 @@
1
+ code: sam
2
+ name: "BMad Samples"
3
+ description: "Demo module showcasing sample BMad agents, workflows, and skills"
4
+ module_version: 1.0.0
5
+ default_selected: false
6
+ module_greeting: >
7
+ The BMad Samples module is ready! Explore the sample agents and skills to see what's possible with BMad.
8
+ For questions, suggestions and support - check us on Discord at https://discord.gg/gk8jAdXWmj
9
+
10
+ sample_output_folder:
11
+ prompt: "Where should sample output (diagrams, reports) be saved?"
12
+ default: "{project-root}/_bmad-output"
13
+ result: "{project-root}/{value}"
@@ -0,0 +1,259 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # requires-python = ">=3.9"
4
+ # dependencies = []
5
+ # ///
6
+ """Remove legacy module directories from _bmad/ after config migration.
7
+
8
+ After merge-config.py and merge-help-csv.py have migrated config data and
9
+ deleted individual legacy files, this script removes the now-redundant
10
+ directory trees. These directories contain skill files that are already
11
+ installed at .claude/skills/ (or equivalent) — only the config files at
12
+ _bmad/ root need to persist.
13
+
14
+ When --skills-dir is provided, the script verifies that every skill found
15
+ in the legacy directories exists at the installed location before removing
16
+ anything. Directories without skills (like _config/) are removed directly.
17
+
18
+ Exit codes: 0=success (including nothing to remove), 1=validation error, 2=runtime error
19
+ """
20
+
21
+ import argparse
22
+ import json
23
+ import shutil
24
+ import sys
25
+ from pathlib import Path
26
+
27
+
28
+ def parse_args():
29
+ parser = argparse.ArgumentParser(
30
+ description="Remove legacy module directories from _bmad/ after config migration."
31
+ )
32
+ parser.add_argument(
33
+ "--bmad-dir",
34
+ required=True,
35
+ help="Path to the _bmad/ directory",
36
+ )
37
+ parser.add_argument(
38
+ "--module-code",
39
+ required=True,
40
+ help="Module code being cleaned up (e.g. 'bmb')",
41
+ )
42
+ parser.add_argument(
43
+ "--also-remove",
44
+ action="append",
45
+ default=[],
46
+ help="Additional directory names under _bmad/ to remove (repeatable)",
47
+ )
48
+ parser.add_argument(
49
+ "--skills-dir",
50
+ help="Path to .claude/skills/ — enables safety verification that skills "
51
+ "are installed before removing legacy copies",
52
+ )
53
+ parser.add_argument(
54
+ "--verbose",
55
+ action="store_true",
56
+ help="Print detailed progress to stderr",
57
+ )
58
+ return parser.parse_args()
59
+
60
+
61
+ def find_skill_dirs(base_path: str) -> list:
62
+ """Find directories that contain a SKILL.md file.
63
+
64
+ Walks the directory tree and returns the leaf directory name for each
65
+ directory containing a SKILL.md. These are considered skill directories.
66
+
67
+ Returns:
68
+ List of skill directory names (e.g. ['bmad-agent-builder', 'bmad-builder-setup'])
69
+ """
70
+ skills = []
71
+ root = Path(base_path)
72
+ if not root.exists():
73
+ return skills
74
+ for skill_md in root.rglob("SKILL.md"):
75
+ skills.append(skill_md.parent.name)
76
+ return sorted(set(skills))
77
+
78
+
79
+ def verify_skills_installed(
80
+ bmad_dir: str, dirs_to_check: list, skills_dir: str, verbose: bool = False
81
+ ) -> list:
82
+ """Verify that skills in legacy directories exist at the installed location.
83
+
84
+ Scans each directory in dirs_to_check for skill folders (containing SKILL.md),
85
+ then checks that a matching directory exists under skills_dir. Directories
86
+ that contain no skills (like _config/) are silently skipped.
87
+
88
+ Returns:
89
+ List of verified skill names.
90
+
91
+ Raises SystemExit(1) if any skills are missing from skills_dir.
92
+ """
93
+ all_verified = []
94
+ missing = []
95
+
96
+ for dirname in dirs_to_check:
97
+ legacy_path = Path(bmad_dir) / dirname
98
+ if not legacy_path.exists():
99
+ continue
100
+
101
+ skill_names = find_skill_dirs(str(legacy_path))
102
+ if not skill_names:
103
+ if verbose:
104
+ print(
105
+ f"No skills found in {dirname}/ — skipping verification",
106
+ file=sys.stderr,
107
+ )
108
+ continue
109
+
110
+ for skill_name in skill_names:
111
+ installed_path = Path(skills_dir) / skill_name
112
+ if installed_path.is_dir():
113
+ all_verified.append(skill_name)
114
+ if verbose:
115
+ print(
116
+ f"Verified: {skill_name} exists at {installed_path}",
117
+ file=sys.stderr,
118
+ )
119
+ else:
120
+ missing.append(skill_name)
121
+ if verbose:
122
+ print(
123
+ f"MISSING: {skill_name} not found at {installed_path}",
124
+ file=sys.stderr,
125
+ )
126
+
127
+ if missing:
128
+ error_result = {
129
+ "status": "error",
130
+ "error": "Skills not found at installed location",
131
+ "missing_skills": missing,
132
+ "skills_dir": str(Path(skills_dir).resolve()),
133
+ }
134
+ print(json.dumps(error_result, indent=2))
135
+ sys.exit(1)
136
+
137
+ return sorted(set(all_verified))
138
+
139
+
140
+ def count_files(path: Path) -> int:
141
+ """Count all files recursively in a directory."""
142
+ count = 0
143
+ for item in path.rglob("*"):
144
+ if item.is_file():
145
+ count += 1
146
+ return count
147
+
148
+
149
+ def cleanup_directories(
150
+ bmad_dir: str, dirs_to_remove: list, verbose: bool = False
151
+ ) -> tuple:
152
+ """Remove specified directories under bmad_dir.
153
+
154
+ Returns:
155
+ (removed, not_found, total_files_removed) tuple
156
+ """
157
+ removed = []
158
+ not_found = []
159
+ total_files = 0
160
+
161
+ for dirname in dirs_to_remove:
162
+ target = Path(bmad_dir) / dirname
163
+ if not target.exists():
164
+ not_found.append(dirname)
165
+ if verbose:
166
+ print(f"Not found (skipping): {target}", file=sys.stderr)
167
+ continue
168
+
169
+ if not target.is_dir():
170
+ if verbose:
171
+ print(f"Not a directory (skipping): {target}", file=sys.stderr)
172
+ not_found.append(dirname)
173
+ continue
174
+
175
+ file_count = count_files(target)
176
+ if verbose:
177
+ print(
178
+ f"Removing {target} ({file_count} files)",
179
+ file=sys.stderr,
180
+ )
181
+
182
+ try:
183
+ shutil.rmtree(target)
184
+ except OSError as e:
185
+ error_result = {
186
+ "status": "error",
187
+ "error": f"Failed to remove {target}: {e}",
188
+ "directories_removed": removed,
189
+ "directories_failed": dirname,
190
+ }
191
+ print(json.dumps(error_result, indent=2))
192
+ sys.exit(2)
193
+
194
+ removed.append(dirname)
195
+ total_files += file_count
196
+
197
+ return removed, not_found, total_files
198
+
199
+
200
+ def main():
201
+ args = parse_args()
202
+
203
+ bmad_dir = args.bmad_dir
204
+ module_code = args.module_code
205
+
206
+ # Build the list of directories to remove
207
+ dirs_to_remove = [module_code, "core"] + args.also_remove
208
+ # Deduplicate while preserving order
209
+ seen = set()
210
+ unique_dirs = []
211
+ for d in dirs_to_remove:
212
+ if d not in seen:
213
+ seen.add(d)
214
+ unique_dirs.append(d)
215
+ dirs_to_remove = unique_dirs
216
+
217
+ if args.verbose:
218
+ print(f"Directories to remove: {dirs_to_remove}", file=sys.stderr)
219
+
220
+ # Safety check: verify skills are installed before removing
221
+ verified_skills = None
222
+ if args.skills_dir:
223
+ if args.verbose:
224
+ print(
225
+ f"Verifying skills installed at {args.skills_dir}",
226
+ file=sys.stderr,
227
+ )
228
+ verified_skills = verify_skills_installed(
229
+ bmad_dir, dirs_to_remove, args.skills_dir, args.verbose
230
+ )
231
+
232
+ # Remove directories
233
+ removed, not_found, total_files = cleanup_directories(
234
+ bmad_dir, dirs_to_remove, args.verbose
235
+ )
236
+
237
+ # Build result
238
+ result = {
239
+ "status": "success",
240
+ "bmad_dir": str(Path(bmad_dir).resolve()),
241
+ "directories_removed": removed,
242
+ "directories_not_found": not_found,
243
+ "files_removed_count": total_files,
244
+ }
245
+
246
+ if args.skills_dir:
247
+ result["safety_checks"] = {
248
+ "skills_verified": True,
249
+ "skills_dir": str(Path(args.skills_dir).resolve()),
250
+ "verified_skills": verified_skills,
251
+ }
252
+ else:
253
+ result["safety_checks"] = None
254
+
255
+ print(json.dumps(result, indent=2))
256
+
257
+
258
+ if __name__ == "__main__":
259
+ main()