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.
- package/README.md +20 -10
- package/lib/agents.js +7 -7
- package/lib/bmad-cache/bmb/.claude-plugin/marketplace.json +4 -3
- package/lib/bmad-cache/bmb/_git_preserved/index +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/logs/HEAD +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/logs/refs/heads/main +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/logs/refs/remotes/origin/HEAD +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.idx +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/{pack-5e915049d8459481e4aa7be8d5959643fa68a981.pack → pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.pack} +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-4b395d030ca386fc5748f1b670dcf8c0ef41c94c.rev +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/packed-refs +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/refs/heads/main +1 -1
- package/lib/bmad-cache/bmb/_git_preserved/shallow +1 -1
- package/lib/bmad-cache/bmb/samples/sample-module-setup/assets/module-help.csv +16 -0
- package/lib/bmad-cache/bmb/samples/sample-module-setup/assets/module.yaml +13 -0
- package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/cleanup-legacy.py +259 -0
- package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-config.py +408 -0
- package/lib/bmad-cache/bmb/samples/sample-module-setup/scripts/merge-help-csv.py +218 -0
- package/lib/bmad-cache/cache-manifest.json +3 -3
- package/lib/bmad-extension/module-help.csv +0 -1
- package/lib/bmad-extension/skills/bmad-ma-agent-sqa/SKILL.md +24 -11
- package/lib/bmad-extension/skills/bmad-ma-agent-sqa/bmad-skill-manifest.yaml +6 -6
- package/lib/skill-authoring.js +2 -2
- package/package.json +1 -1
- package/test/agent-injection-strategy.test.js +1 -1
- package/test/bmad-extension.test.js +2 -2
- package/test/convert-agents-to-skills.test.js +8 -8
- package/test/extension-module-restructure.test.js +6 -6
- package/test/migration-validation.test.js +20 -16
- package/test/skill-customize-agent.test.js +2 -2
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-5e915049d8459481e4aa7be8d5959643fa68a981.idx +0 -0
- package/lib/bmad-cache/bmb/_git_preserved/objects/pack/pack-5e915049d8459481e4aa7be8d5959643fa68a981.rev +0 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-mil498/.gitkeep +0 -0
- package/lib/bmad-extension/skills/bmad-ma-agent-mil498/SKILL.md +0 -54
- 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 (
|
|
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 (
|
|
196
|
-
| `
|
|
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. **
|
|
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-
|
|
277
|
-
name: '
|
|
278
|
-
version: '
|
|
276
|
+
id: 'bmm-qa',
|
|
277
|
+
name: 'SQA & Standards Expert (Gad)',
|
|
278
|
+
version: '1.0.0',
|
|
279
279
|
category: 'bmad',
|
|
280
|
-
description: 'MIL-STD-498
|
|
281
|
-
skillsDir: '_bmad/skills/
|
|
282
|
-
getProjectPath: () => path.join(process.cwd(), '_bmad', 'skills', '
|
|
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/
|
|
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": "./
|
|
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": "./
|
|
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": {
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0000000000000000000000000000000000000000
|
|
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
|
|
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
|
|
1
|
+
0000000000000000000000000000000000000000 605e07656f9f633b5e429297388e1db9687d1996 Alon Mayaffit <alon.mayafit@gmail.com> 1775729260 +0300 clone: from https://github.com/bmad-code-org/bmad-builder
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# pack-refs with: peeled fully-peeled sorted
|
|
2
|
-
|
|
2
|
+
605e07656f9f633b5e429297388e1db9687d1996 refs/remotes/origin/main
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
605e07656f9f633b5e429297388e1db9687d1996
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
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()
|