bmad-plus 0.12.2 → 0.14.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 +47 -0
- package/README.md +96 -461
- package/package.json +12 -5
- package/readme-international/README.de.md +42 -9
- package/readme-international/README.es.md +43 -10
- package/readme-international/README.fr.md +42 -9
- package/src/bmad-plus/agents/agent-orchestrator/SKILL.md +5 -3
- package/src/bmad-plus/module.yaml +270 -220
- package/src/bmad-plus/packs/pack-dev-studio/README.md +133 -141
- package/src/bmad-plus/packs/pack-dev-studio/SKILL.md +49 -0
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/analyst-agent.md +35 -60
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/document-project.md +59 -59
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/domain-research.md +55 -93
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/market-research.md +58 -93
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/prfaq.md +55 -132
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/product-brief.md +63 -78
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/tech-writer-agent.md +54 -69
- package/src/bmad-plus/packs/pack-dev-studio/categories/analysis/technical-research.md +54 -93
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/architect-agent.md +32 -60
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/create-architecture.md +67 -71
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/create-epics-stories.md +61 -90
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/generate-project-context.md +56 -78
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/implementation-readiness.md +55 -88
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-01-init.md +20 -153
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-01b-continue.md +20 -173
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-02-context.md +14 -220
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-03-starter.md +20 -329
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-04-decisions.md +15 -314
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-05-patterns.md +15 -355
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-06-structure.md +15 -375
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-07-validation.md +14 -357
- package/src/bmad-plus/packs/pack-dev-studio/categories/architecture/steps/step-08-complete.md +13 -78
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/checkpoint-preview.md +52 -65
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/code-review-steps/step-01-gather-context.md +14 -81
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/code-review-steps/step-02-review.md +14 -31
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/code-review-steps/step-03-triage.md +14 -45
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/code-review-steps/step-04-present.md +13 -128
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/code-review.md +61 -87
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/correct-course.md +55 -298
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/create-story.md +52 -426
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/dev-agent.md +48 -69
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/dev-story-checklist.md +22 -80
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/dev-story.md +60 -482
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/investigate.md +50 -184
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/qa-e2e-tests.md +57 -173
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/quick-dev.md +56 -108
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/retrospective.md +54 -1509
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/sprint-planning.md +54 -296
- package/src/bmad-plus/packs/pack-dev-studio/categories/implementation/sprint-status.md +41 -283
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/create-prd.md +58 -18
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/create-ux-design.md +103 -72
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/edit-prd.md +55 -27
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/pm-agent.md +34 -60
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/prd.md +46 -87
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/steps/step-01-init.md +10 -0
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/ux-designer-agent.md +30 -60
- package/src/bmad-plus/packs/pack-dev-studio/categories/planning/validate-prd.md +57 -27
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/advanced-elicitation.md +47 -138
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/adversarial-review.md +48 -34
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/bmad-help.md +51 -68
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/brainstorming.md +46 -3
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/customize.md +68 -109
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/distillator.md +53 -174
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/edge-case-hunter.md +39 -53
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/editorial-review-prose.md +45 -83
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/editorial-review-structure.md +45 -176
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/index-docs.md +45 -63
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/party-mode.md +53 -124
- package/src/bmad-plus/packs/pack-dev-studio/categories/utilities/shard-doc.md +44 -100
- package/src/bmad-plus/packs/pack-dev-studio/dev-studio-orchestrator.md +56 -116
- package/src/bmad-plus/packs/pack-dev-studio/shared/architecture-decision-template.md +49 -12
- package/src/bmad-plus/packs/pack-dev-studio/shared/bwml-spec.md +51 -328
- package/src/bmad-plus/packs/pack-dev-studio/shared/catalog.json +489 -0
- package/src/bmad-plus/packs/pack-dev-studio/shared/execution.md +69 -0
- package/src/bmad-plus/packs/pack-dev-studio/shared/module-help.csv +39 -32
- package/src/bmad-plus/packs/pack-dev-studio/upstream-sync.yaml +85 -14
- package/src/bmad-plus/packs/pack-memory/README.md +6 -0
- package/src/bmad-plus/packs/pack-memory/memory-orchestrator.md +12 -5
- package/src/bmad-plus/packs/pack-seo/SKILL.md +27 -1
- package/src/bmad-plus/packs/pack-seo/scripts/seo_apis.py +8 -8
- package/src/bmad-plus/packs/pack-seo/scripts/seo_fetch.py +1 -2
- package/src/bmad-plus/packs/pack-seo/scripts/seo_report.py +0 -1
- package/src/bmad-plus/packs/pack-seo/seo-chief.md +16 -1
- package/src/bmad-plus/packs/pack-seo/seo-judge.md +12 -0
- package/src/bmad-plus/packs/pack-seo/seo-scout.md +12 -0
- package/src/bmad-plus/skills/bmad-plus-autopilot/SKILL.md +4 -4
- package/src/bmad-plus/skills/bmad-plus-sync/SKILL.md +5 -3
- package/src/bmad-plus/skills/dev-studio/SKILL.md +19 -0
- package/tools/bmad-plus-npx.js +4 -2
- package/tools/build/adapters.config.js +60 -51
- package/tools/build/check-counts.js +52 -54
- package/tools/build/check-install-contract.js +450 -0
- package/tools/build/generate-adapters.js +252 -56
- package/tools/build/generate.js +364 -14
- package/tools/build/generated-adapters/.codex/AGENTS.md +20 -7
- package/tools/build/generated-adapters/.cursor/rules/bmad-plus.mdc +20 -7
- package/tools/build/generated-adapters/.opencode/AGENTS.md +20 -7
- package/tools/build/generated-adapters/AGENTS.md +20 -7
- package/tools/build/generated-adapters/CLAUDE.md +20 -7
- package/tools/build/generated-adapters/CONVENTIONS.md +20 -7
- package/tools/build/generated-adapters/GEMINI.md +20 -7
- package/tools/build/module.template.yaml +82 -0
- package/tools/build/pack-delivery.js +78 -0
- package/tools/cli/bmad-plus-cli.js +16 -1
- package/tools/cli/commands/doctor.js +49 -217
- package/tools/cli/commands/install.js +109 -164
- package/tools/cli/commands/studio.js +68 -0
- package/tools/cli/commands/uninstall.js +173 -65
- package/tools/cli/commands/update-check.js +31 -0
- package/tools/cli/commands/update-policy.js +39 -0
- package/tools/cli/commands/update.js +102 -113
- package/tools/cli/i18n.js +60 -0
- package/tools/cli/lib/ide-config.js +4 -261
- package/tools/cli/lib/install-manifest.js +17 -0
- package/tools/cli/lib/installation-health.js +360 -0
- package/tools/cli/lib/installed-adapters.js +89 -0
- package/tools/cli/lib/npm-runner.js +177 -0
- package/tools/cli/lib/pack-copy.js +62 -66
- package/tools/cli/lib/packs.js +546 -3
- package/tools/cli/lib/python-health.js +233 -0
- package/tools/cli/lib/python-provision.js +2 -2
- package/tools/cli/lib/studio.js +310 -0
- package/tools/cli/lib/update-check.js +153 -0
- package/tools/cli/lib/update-dispatch.js +182 -0
- package/tools/cli/lib/update-policy.js +90 -0
- package/tools/cli/lib/update-transaction.js +334 -0
- package/tools/release/publication-content.js +901 -0
package/tools/build/generate.js
CHANGED
|
@@ -3,17 +3,19 @@
|
|
|
3
3
|
* BMAD+ Build — registry.yaml → pack artifacts generator (Pillar 1)
|
|
4
4
|
*
|
|
5
5
|
* Reads the root registry.yaml (the single source of truth) and generates the
|
|
6
|
-
* pack data
|
|
6
|
+
* pack data in tools/cli/lib/packs.js and src/bmad-plus/module.yaml:
|
|
7
7
|
* - PACKS (CLI pack definitions)
|
|
8
8
|
* - PACK_ORDER (install/display order)
|
|
9
9
|
* - EXPECTED_AGENTS (what `bmad-plus doctor` verifies after install)
|
|
10
|
+
* - DERIVED (counts, display metadata, targets, Python provisioning)
|
|
10
11
|
*
|
|
11
12
|
* Usage:
|
|
12
13
|
* node tools/build/generate.js # print generated packs module source
|
|
13
|
-
* node tools/build/generate.js --json # print
|
|
14
|
+
* node tools/build/generate.js --json # print all generated data as JSON
|
|
14
15
|
* node tools/build/generate.js --out <file> # write generated module source to <file>
|
|
16
|
+
* --module-out <yaml> # also write generated module.yaml
|
|
15
17
|
* node tools/build/generate.js --check # verify registry.yaml reproduces the live
|
|
16
|
-
* #
|
|
18
|
+
* # packs.js and module.yaml (exit 1 on drift)
|
|
17
19
|
*
|
|
18
20
|
* Author: Laurent Rochetta
|
|
19
21
|
*/
|
|
@@ -28,9 +30,65 @@ const yaml = require('js-yaml');
|
|
|
28
30
|
const REPO_ROOT = path.join(__dirname, '..', '..');
|
|
29
31
|
const DEFAULT_REGISTRY_PATH = path.join(REPO_ROOT, 'registry.yaml');
|
|
30
32
|
const DEFAULT_PACKS_MODULE_PATH = path.join(REPO_ROOT, 'tools', 'cli', 'lib', 'packs.js');
|
|
33
|
+
const DEFAULT_MODULE_PATH = path.join(REPO_ROOT, 'src', 'bmad-plus', 'module.yaml');
|
|
34
|
+
const MODULE_TEMPLATE_PATH = path.join(__dirname, 'module.template.yaml');
|
|
31
35
|
const PACKAGE_JSON_PATH = path.join(REPO_ROOT, 'package.json');
|
|
32
36
|
|
|
33
37
|
const INSTALL_LAYOUTS = ['loose', 'packaged'];
|
|
38
|
+
const OWNED_COUNT_RE =
|
|
39
|
+
/(?<![\w.-])\d+\+?[\s-]+(?:[A-Za-zÀ-ÿ-]+\s+){0,6}(?:agents?|skills?|workflows?|packs?|frameworks?|languages?|reference files)\b/gi;
|
|
40
|
+
const STANDARD_PREFIX_RE =
|
|
41
|
+
/\b(?:ISO(?:\/IEC)?|IEC|SOC|NIST(?: SP)?|PCI(?: DSS)?|WCAG|Section)\s*$/i;
|
|
42
|
+
|
|
43
|
+
function hasOwnedCount(value) {
|
|
44
|
+
return [...value.matchAll(OWNED_COUNT_RE)].some(
|
|
45
|
+
(match) => !STANDARD_PREFIX_RE.test(value.slice(0, match.index))
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function assertResourcePath(file, where) {
|
|
50
|
+
if (
|
|
51
|
+
typeof file !== 'string' ||
|
|
52
|
+
!file ||
|
|
53
|
+
/[\\:\0]/.test(file) ||
|
|
54
|
+
file.split('/').some((part) => !part || part === '.' || part === '..')
|
|
55
|
+
) {
|
|
56
|
+
throw new Error(`${where}: required resource must be a portable relative file path`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Installed entry points, derived from the same layout used by pack-copy.js. */
|
|
61
|
+
function buildRequiredResources(pack) {
|
|
62
|
+
const where = `registry.yaml: pack "${pack.pack_dir}"`;
|
|
63
|
+
for (const file of [
|
|
64
|
+
...pack.agents,
|
|
65
|
+
...(pack.skills || []),
|
|
66
|
+
...(pack.data || []),
|
|
67
|
+
...((pack.doctor || {}).pack_agents || []),
|
|
68
|
+
...((pack.doctor || {}).required_resources || []),
|
|
69
|
+
...(pack.python_entry ? [pack.python_entry] : []),
|
|
70
|
+
]) {
|
|
71
|
+
assertResourcePath(file, where);
|
|
72
|
+
}
|
|
73
|
+
const resources = [];
|
|
74
|
+
if (pack.install_layout === 'loose') {
|
|
75
|
+
resources.push(...pack.agents.map((id) => `.agents/skills/${id}/SKILL.md`));
|
|
76
|
+
} else {
|
|
77
|
+
resources.push(
|
|
78
|
+
...pack.doctor.pack_agents.map((file) => `.agents/skills/${pack.pack_dir}/${file}`)
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
resources.push(...(pack.skills || []).map((id) => `.agents/skills/${id}/SKILL.md`));
|
|
82
|
+
resources.push(...(pack.data || []).map((file) => `.agents/data/${file}`));
|
|
83
|
+
resources.push(
|
|
84
|
+
...((pack.doctor || {}).required_resources || []).map(
|
|
85
|
+
(file) => `.agents/skills/${pack.pack_dir}/${file}`
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
if (pack.python_entry) resources.push(`.agents/skills/${pack.pack_dir}/${pack.python_entry}`);
|
|
89
|
+
for (const file of resources) assertResourcePath(file, where);
|
|
90
|
+
return [...new Set(resources)];
|
|
91
|
+
}
|
|
34
92
|
|
|
35
93
|
/**
|
|
36
94
|
* Validate the minimal contract the generator relies on.
|
|
@@ -53,11 +111,26 @@ function validateRegistry(registry) {
|
|
|
53
111
|
seenOrders.add(pack.order);
|
|
54
112
|
|
|
55
113
|
if (!pack.cli || typeof pack.cli !== 'object') throw new Error(`${where}: missing "cli" block`);
|
|
56
|
-
for (const field of ['name', 'icon'
|
|
114
|
+
for (const field of ['name', 'icon']) {
|
|
57
115
|
if (typeof pack.cli[field] !== 'string' || pack.cli[field] === '') {
|
|
58
116
|
throw new Error(`${where}: missing cli.${field}`);
|
|
59
117
|
}
|
|
60
118
|
}
|
|
119
|
+
if (!pack.cli.desc && !pack.cli.desc_template) {
|
|
120
|
+
throw new Error(`${where}: missing cli.desc or cli.desc_template`);
|
|
121
|
+
}
|
|
122
|
+
for (const [field, value] of Object.entries({
|
|
123
|
+
'cli.desc': pack.cli.desc,
|
|
124
|
+
'cli.desc_template': pack.cli.desc_template,
|
|
125
|
+
summary: pack.summary,
|
|
126
|
+
summary_template: pack.summary_template,
|
|
127
|
+
})) {
|
|
128
|
+
if (value !== undefined && (typeof value !== 'string' || hasOwnedCount(value))) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`${where}: ${field} must use derived placeholders for owned count dimensions`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
61
134
|
if (!Array.isArray(pack.agents)) throw new Error(`${where}: "agents" must be a list`);
|
|
62
135
|
if (pack.skills !== undefined && !Array.isArray(pack.skills)) {
|
|
63
136
|
throw new Error(`${where}: "skills" must be a list`);
|
|
@@ -71,6 +144,66 @@ function validateRegistry(registry) {
|
|
|
71
144
|
if (pack.install_layout === 'packaged' && !Array.isArray((pack.doctor || {}).pack_agents)) {
|
|
72
145
|
throw new Error(`${where}: packaged layout requires "doctor.pack_agents" list`);
|
|
73
146
|
}
|
|
147
|
+
if (
|
|
148
|
+
pack.doctor?.required_resources !== undefined &&
|
|
149
|
+
!Array.isArray(pack.doctor.required_resources)
|
|
150
|
+
) {
|
|
151
|
+
throw new Error(`${where}: doctor.required_resources must be a list`);
|
|
152
|
+
}
|
|
153
|
+
if (
|
|
154
|
+
!Array.isArray(pack.runtime) ||
|
|
155
|
+
pack.runtime.length === 0 ||
|
|
156
|
+
pack.runtime.some((runtime) => !Object.hasOwn(registry.runtimes || {}, runtime))
|
|
157
|
+
) {
|
|
158
|
+
throw new Error(`${where}: runtime must declare known runtimes`);
|
|
159
|
+
}
|
|
160
|
+
buildRequiredResources(pack);
|
|
161
|
+
if (pack.personas !== undefined) {
|
|
162
|
+
if (!Array.isArray(pack.personas)) throw new Error(`${where}: personas must be a list`);
|
|
163
|
+
const roster = new Set([...pack.agents, ...(pack.sub_agents || [])]);
|
|
164
|
+
const ids = new Set();
|
|
165
|
+
for (const persona of pack.personas) {
|
|
166
|
+
if (
|
|
167
|
+
!persona ||
|
|
168
|
+
['id', 'name', 'role', 'description'].some(
|
|
169
|
+
(key) => typeof persona[key] !== 'string' || !persona[key].trim()
|
|
170
|
+
)
|
|
171
|
+
) {
|
|
172
|
+
throw new Error(`${where}: each persona needs id, name, role and description`);
|
|
173
|
+
}
|
|
174
|
+
if (!roster.has(persona.id) || ids.has(persona.id)) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
`${where}: persona ${persona.id} is absent from its roster or duplicated`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
ids.add(persona.id);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const integration = registry.targets?.integration;
|
|
184
|
+
if (
|
|
185
|
+
integration?.execution !== 'host-managed' ||
|
|
186
|
+
integration?.lifecycle_events !== 'not-integrated'
|
|
187
|
+
) {
|
|
188
|
+
throw new Error(
|
|
189
|
+
'registry.yaml: targets.integration must declare the delivered instruction integration'
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
for (const [runtime, config] of Object.entries(registry.runtimes || {})) {
|
|
193
|
+
if (
|
|
194
|
+
typeof config?.min_version !== 'string' ||
|
|
195
|
+
!/^\d+\.\d+(?:\.\d+)?$/.test(config.min_version)
|
|
196
|
+
) {
|
|
197
|
+
throw new Error(`registry.yaml: runtime "${runtime}" needs a numeric min_version`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const tools = new Set();
|
|
201
|
+
for (const adapter of registry.targets.adapters || []) {
|
|
202
|
+
if (!adapter || typeof adapter.tool !== 'string' || !adapter.tool || tools.has(adapter.tool)) {
|
|
203
|
+
throw new Error('registry.yaml: adapter tool names must be nonempty and unique');
|
|
204
|
+
}
|
|
205
|
+
tools.add(adapter.tool);
|
|
206
|
+
assertResourcePath(adapter.file, `registry.yaml: adapter "${adapter.tool}"`);
|
|
74
207
|
}
|
|
75
208
|
return registry;
|
|
76
209
|
}
|
|
@@ -99,6 +232,7 @@ function buildPackOrder(registry) {
|
|
|
99
232
|
* - `required` only when true (other packs omit the key entirely)
|
|
100
233
|
*/
|
|
101
234
|
function buildPacks(registry) {
|
|
235
|
+
const derived = buildDerived(registry);
|
|
102
236
|
const packs = {};
|
|
103
237
|
for (const [id, p] of sortedPackEntries(registry)) {
|
|
104
238
|
const entry = {
|
|
@@ -112,12 +246,192 @@ function buildPacks(registry) {
|
|
|
112
246
|
entry.packDir = p.pack_dir;
|
|
113
247
|
entry.packSrcDir = p.pack_src_dir || 'packs';
|
|
114
248
|
if (p.required === true) entry.required = true;
|
|
115
|
-
entry.desc =
|
|
249
|
+
entry.desc = derived.packs[id].desc;
|
|
116
250
|
packs[id] = entry;
|
|
117
251
|
}
|
|
118
252
|
return packs;
|
|
119
253
|
}
|
|
120
254
|
|
|
255
|
+
/** Recursively count reference files; sourceRoot is injectable for fixture trees. */
|
|
256
|
+
function countMarkdownFiles(dir) {
|
|
257
|
+
if (!fs.existsSync(dir)) return 0;
|
|
258
|
+
return fs.readdirSync(dir, { withFileTypes: true }).reduce((count, entry) => {
|
|
259
|
+
if (entry.isDirectory()) return count + countMarkdownFiles(path.join(dir, entry.name));
|
|
260
|
+
return count + Number(entry.isFile() && entry.name.endsWith('.md'));
|
|
261
|
+
}, 0);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function renderSummary(pack, derived, field = 'summary') {
|
|
265
|
+
const template = field === 'summary' ? pack.summary_template : pack.cli.desc_template;
|
|
266
|
+
const fallback = field === 'summary' ? pack.summary : pack.cli.desc;
|
|
267
|
+
if (!template) return fallback || '';
|
|
268
|
+
const values = {
|
|
269
|
+
agent_count: derived.agentCount,
|
|
270
|
+
installer_agent_count: derived.installerAgentCount,
|
|
271
|
+
sub_agent_count: derived.subAgentCount,
|
|
272
|
+
workflow_count: derived.workflowCount,
|
|
273
|
+
framework_count: derived.frameworkCount,
|
|
274
|
+
category_count: derived.categoryCount,
|
|
275
|
+
skill_count: derived.skillCount,
|
|
276
|
+
reference_file_count: derived.referenceFiles,
|
|
277
|
+
};
|
|
278
|
+
return template.replace(/\{([a-z_]+)\}/g, (_match, key) => {
|
|
279
|
+
if (!(key in values)) throw new Error(`Unknown derived summary placeholder: ${key}`);
|
|
280
|
+
return String(values[key]);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** The one derivation engine; its JSON result is shipped for runtime consumers. */
|
|
285
|
+
function buildDerived(registry, { sourceRoot = path.join(REPO_ROOT, 'src', 'bmad-plus') } = {}) {
|
|
286
|
+
const packs = {};
|
|
287
|
+
const pythonPacks = {};
|
|
288
|
+
let installerAgents = 0;
|
|
289
|
+
let totalAgents = 0;
|
|
290
|
+
for (const [id, pack] of sortedPackEntries(registry)) {
|
|
291
|
+
const categories = pack.categories || [];
|
|
292
|
+
const categoryAgentCounts = categories.map((category) => (category.agents || []).length);
|
|
293
|
+
const categoryAgentCount = categoryAgentCounts.reduce((sum, count) => sum + count, 0);
|
|
294
|
+
const installerAgentCount = pack.agents.length;
|
|
295
|
+
const subAgentCount = (pack.sub_agents || []).length;
|
|
296
|
+
const facts = {
|
|
297
|
+
id,
|
|
298
|
+
order: pack.order,
|
|
299
|
+
name: pack.cli.name,
|
|
300
|
+
displayName: pack.display_name || pack.cli.name,
|
|
301
|
+
required: pack.required === true,
|
|
302
|
+
installerAgentCount,
|
|
303
|
+
categoryAgentCount,
|
|
304
|
+
agentCount: categoryAgentCount || subAgentCount || installerAgentCount,
|
|
305
|
+
subAgentCount,
|
|
306
|
+
workflowCount:
|
|
307
|
+
(pack.workflows || []).length +
|
|
308
|
+
categories.reduce((sum, c) => sum + (c.workflows || []).length, 0),
|
|
309
|
+
frameworkCount: (pack.compliance_tags || []).length,
|
|
310
|
+
categoryCount: categories.length,
|
|
311
|
+
skillCount: (pack.skills || []).length,
|
|
312
|
+
referenceFiles: countMarkdownFiles(
|
|
313
|
+
path.join(sourceRoot, pack.pack_src_dir || 'packs', pack.pack_dir, 'references')
|
|
314
|
+
),
|
|
315
|
+
categoryAgentCounts,
|
|
316
|
+
runtimes: [...pack.runtime],
|
|
317
|
+
requiredResources: buildRequiredResources(pack),
|
|
318
|
+
personas: (pack.personas || []).map(({ id, name, role, description, alias }) => ({
|
|
319
|
+
id,
|
|
320
|
+
name,
|
|
321
|
+
role,
|
|
322
|
+
description,
|
|
323
|
+
...(alias ? { alias } : {}),
|
|
324
|
+
})),
|
|
325
|
+
};
|
|
326
|
+
facts.summary = renderSummary(pack, facts);
|
|
327
|
+
facts.desc = renderSummary(pack, facts, 'description');
|
|
328
|
+
facts.description = facts.desc;
|
|
329
|
+
packs[id] = facts;
|
|
330
|
+
installerAgents += installerAgentCount;
|
|
331
|
+
totalAgents += new Set([
|
|
332
|
+
...pack.agents,
|
|
333
|
+
...(pack.sub_agents || []),
|
|
334
|
+
...categories.flatMap((c) => c.agents || []),
|
|
335
|
+
]).size;
|
|
336
|
+
if ((pack.runtime || []).includes('python')) {
|
|
337
|
+
const packagePath =
|
|
338
|
+
pack.python_package || `src/bmad-plus/${pack.pack_src_dir || 'packs'}/${pack.pack_dir}`;
|
|
339
|
+
pythonPacks[id] = {
|
|
340
|
+
requirements: [...packagePath.split(/[\\/]/), 'requirements.txt'],
|
|
341
|
+
verifyModules: [...(pack.python_verify_modules || [])],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const { LANGUAGES } = require('../cli/i18n');
|
|
346
|
+
return {
|
|
347
|
+
product: {
|
|
348
|
+
code: registry.product.code,
|
|
349
|
+
displayName: registry.product.display_name,
|
|
350
|
+
version: registry.product.version,
|
|
351
|
+
derivedFrom: registry.product.derived_from,
|
|
352
|
+
},
|
|
353
|
+
packOrder: buildPackOrder(registry),
|
|
354
|
+
packCount: Object.keys(packs).length,
|
|
355
|
+
installerAgents,
|
|
356
|
+
totalAgents,
|
|
357
|
+
languages: Object.keys(LANGUAGES),
|
|
358
|
+
packs,
|
|
359
|
+
pythonPacks,
|
|
360
|
+
diagnostics: {
|
|
361
|
+
schemaVersion: 1,
|
|
362
|
+
runtimeMinimums: Object.fromEntries(
|
|
363
|
+
Object.entries(registry.runtimes).map(([id, runtime]) => [id, runtime.min_version])
|
|
364
|
+
),
|
|
365
|
+
integrations: Object.fromEntries(
|
|
366
|
+
registry.targets.adapters.map(({ tool, file }) => [
|
|
367
|
+
tool,
|
|
368
|
+
{
|
|
369
|
+
instructionFile: file,
|
|
370
|
+
execution: registry.targets.integration.execution,
|
|
371
|
+
lifecycleEvents: registry.targets.integration.lifecycle_events,
|
|
372
|
+
},
|
|
373
|
+
])
|
|
374
|
+
),
|
|
375
|
+
},
|
|
376
|
+
targets: {
|
|
377
|
+
spine: registry.targets.spine,
|
|
378
|
+
adapters: registry.targets.adapters.map(({ tool, file }) => ({ tool, file })),
|
|
379
|
+
models_supported: [...registry.targets.models_supported],
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Preserve project questions/compatibility separately from generated pack facts. */
|
|
385
|
+
function generateModuleSource(registry, templatePath = MODULE_TEMPLATE_PATH) {
|
|
386
|
+
const moduleConfig = yaml.load(fs.readFileSync(templatePath, 'utf8'));
|
|
387
|
+
const derived = buildDerived(registry);
|
|
388
|
+
moduleConfig.code = registry.product.code;
|
|
389
|
+
moduleConfig.packs = {};
|
|
390
|
+
for (const [id, pack] of sortedPackEntries(registry)) {
|
|
391
|
+
const facts = derived.packs[id];
|
|
392
|
+
const entry = {
|
|
393
|
+
name: facts.displayName,
|
|
394
|
+
icon: pack.icon_emoji,
|
|
395
|
+
description: facts.summary || facts.desc,
|
|
396
|
+
required: facts.required,
|
|
397
|
+
agents: [...pack.agents],
|
|
398
|
+
skills: [...(pack.skills || [])],
|
|
399
|
+
};
|
|
400
|
+
for (const key of [
|
|
401
|
+
'data',
|
|
402
|
+
'external_package',
|
|
403
|
+
'orchestrator',
|
|
404
|
+
'categories',
|
|
405
|
+
'workflows',
|
|
406
|
+
'sub_agents',
|
|
407
|
+
'required_keys',
|
|
408
|
+
'optional_keys',
|
|
409
|
+
'cohabitation_warning',
|
|
410
|
+
]) {
|
|
411
|
+
if (key in pack) entry[key] = JSON.parse(JSON.stringify(pack[key]));
|
|
412
|
+
}
|
|
413
|
+
if (pack.install_layout === 'packaged') {
|
|
414
|
+
entry.packDir = pack.pack_dir;
|
|
415
|
+
entry.packSrcDir = pack.pack_src_dir || 'packs';
|
|
416
|
+
}
|
|
417
|
+
moduleConfig.packs[id] = entry;
|
|
418
|
+
}
|
|
419
|
+
moduleConfig.install_packs['multi-select'] = [
|
|
420
|
+
...derived.packOrder
|
|
421
|
+
.filter((id) => !derived.packs[id].required)
|
|
422
|
+
.map((id) => ({
|
|
423
|
+
value: id,
|
|
424
|
+
label: `${registry.packs[id].icon_emoji} ${derived.packs[id].displayName} — ${derived.packs[id].summary || derived.packs[id].desc}`,
|
|
425
|
+
})),
|
|
426
|
+
{ value: 'all', label: 'Tout installer' },
|
|
427
|
+
{ value: 'none', label: 'Aucun — Core uniquement' },
|
|
428
|
+
];
|
|
429
|
+
return (
|
|
430
|
+
'# AUTO-GENERATED from registry.yaml + tools/build/module.template.yaml — DO NOT EDIT.\n' +
|
|
431
|
+
yaml.dump(moduleConfig, { lineWidth: 110, noRefs: true })
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
|
|
121
435
|
/**
|
|
122
436
|
* Generate EXPECTED_AGENTS (consumed by `bmad-plus doctor`).
|
|
123
437
|
* - loose packs → agent DIRECTORIES checked under .agents/skills/
|
|
@@ -135,12 +449,13 @@ function buildExpectedAgents(registry) {
|
|
|
135
449
|
return expected;
|
|
136
450
|
}
|
|
137
451
|
|
|
138
|
-
/** Convenience: all
|
|
452
|
+
/** Convenience: all runtime artifacts at once. */
|
|
139
453
|
function buildAll(registry) {
|
|
140
454
|
return {
|
|
141
455
|
PACKS: buildPacks(registry),
|
|
142
456
|
PACK_ORDER: buildPackOrder(registry),
|
|
143
457
|
EXPECTED_AGENTS: buildExpectedAgents(registry),
|
|
458
|
+
DERIVED: buildDerived(registry),
|
|
144
459
|
};
|
|
145
460
|
}
|
|
146
461
|
|
|
@@ -149,7 +464,7 @@ function buildAll(registry) {
|
|
|
149
464
|
* Evaluating this source yields exports deep-equal to the hand-written module.
|
|
150
465
|
*/
|
|
151
466
|
function generatePacksModuleSource(registry) {
|
|
152
|
-
const { PACKS, PACK_ORDER, EXPECTED_AGENTS } = buildAll(registry);
|
|
467
|
+
const { PACKS, PACK_ORDER, EXPECTED_AGENTS, DERIVED } = buildAll(registry);
|
|
153
468
|
const j = (value) => JSON.stringify(value, null, 2);
|
|
154
469
|
return [
|
|
155
470
|
'/**',
|
|
@@ -166,13 +481,17 @@ function generatePacksModuleSource(registry) {
|
|
|
166
481
|
'',
|
|
167
482
|
`const EXPECTED_AGENTS = ${j(EXPECTED_AGENTS)};`,
|
|
168
483
|
'',
|
|
169
|
-
|
|
484
|
+
`const DERIVED = ${j(DERIVED)};`,
|
|
485
|
+
'',
|
|
486
|
+
'module.exports = { PACKS, PACK_ORDER, EXPECTED_AGENTS, DERIVED };',
|
|
170
487
|
'',
|
|
171
488
|
].join('\n');
|
|
172
489
|
}
|
|
173
490
|
|
|
174
491
|
/** Human-readable drill-down for a mismatching keyed object. */
|
|
175
492
|
function describeDiff(label, generated, current, mismatches) {
|
|
493
|
+
generated = generated || {};
|
|
494
|
+
current = current || {};
|
|
176
495
|
if (Array.isArray(generated) || Array.isArray(current)) {
|
|
177
496
|
mismatches.push(
|
|
178
497
|
`${label}: generated ${JSON.stringify(generated)} != current ${JSON.stringify(current)}`
|
|
@@ -202,13 +521,25 @@ function check({
|
|
|
202
521
|
registryPath = DEFAULT_REGISTRY_PATH,
|
|
203
522
|
packsModulePath = DEFAULT_PACKS_MODULE_PATH,
|
|
204
523
|
packageJsonPath = PACKAGE_JSON_PATH,
|
|
524
|
+
modulePath = DEFAULT_MODULE_PATH,
|
|
205
525
|
} = {}) {
|
|
206
526
|
const registry = loadRegistry(registryPath);
|
|
527
|
+
delete require.cache[require.resolve(packsModulePath)];
|
|
207
528
|
const current = require(packsModulePath);
|
|
208
529
|
const generated = buildAll(registry);
|
|
209
530
|
const mismatches = [];
|
|
210
531
|
|
|
211
532
|
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
533
|
+
const { checkPythonDelivery } = require('./pack-delivery');
|
|
534
|
+
mismatches.push(...checkPythonDelivery(registry, { packageRoot: REPO_ROOT, packageJson: pkg }));
|
|
535
|
+
try {
|
|
536
|
+
require('../cli/lib/studio').validatePack(
|
|
537
|
+
path.join(REPO_ROOT, 'src/bmad-plus/packs/pack-dev-studio'),
|
|
538
|
+
registry.packs['dev-studio']
|
|
539
|
+
);
|
|
540
|
+
} catch (error) {
|
|
541
|
+
mismatches.push('Dev Studio: ' + error.message);
|
|
542
|
+
}
|
|
212
543
|
if (!registry.product || registry.product.version !== pkg.version) {
|
|
213
544
|
const declared = registry.product ? registry.product.version : undefined;
|
|
214
545
|
mismatches.push(
|
|
@@ -216,11 +547,16 @@ function check({
|
|
|
216
547
|
);
|
|
217
548
|
}
|
|
218
549
|
|
|
219
|
-
for (const key of ['PACKS', 'PACK_ORDER', 'EXPECTED_AGENTS']) {
|
|
550
|
+
for (const key of ['PACKS', 'PACK_ORDER', 'EXPECTED_AGENTS', 'DERIVED']) {
|
|
220
551
|
if (!isDeepStrictEqual(generated[key], current[key])) {
|
|
221
552
|
describeDiff(key, generated[key], current[key], mismatches);
|
|
222
553
|
}
|
|
223
554
|
}
|
|
555
|
+
if (
|
|
556
|
+
fs.readFileSync(modulePath, 'utf8').replace(/\r\n/g, '\n') !== generateModuleSource(registry)
|
|
557
|
+
) {
|
|
558
|
+
mismatches.push('module.yaml: generated pack metadata differs from registry.yaml');
|
|
559
|
+
}
|
|
224
560
|
|
|
225
561
|
return { ok: mismatches.length === 0, mismatches };
|
|
226
562
|
}
|
|
@@ -233,7 +569,7 @@ function main(argv) {
|
|
|
233
569
|
if (args.includes('--check')) {
|
|
234
570
|
const result = check();
|
|
235
571
|
if (result.ok) {
|
|
236
|
-
console.log('OK — registry.yaml reproduces
|
|
572
|
+
console.log('OK — registry.yaml reproduces packs.js and module.yaml (no drift).');
|
|
237
573
|
return 0;
|
|
238
574
|
}
|
|
239
575
|
console.error('DRIFT DETECTED between registry.yaml and tools/cli/lib/packs.js:');
|
|
@@ -257,6 +593,15 @@ function main(argv) {
|
|
|
257
593
|
return 1;
|
|
258
594
|
}
|
|
259
595
|
fs.writeFileSync(path.resolve(outPath), source, 'utf8');
|
|
596
|
+
const moduleOutIdx = args.indexOf('--module-out');
|
|
597
|
+
if (moduleOutIdx !== -1) {
|
|
598
|
+
if (!args[moduleOutIdx + 1]) throw new Error('--module-out requires a file path');
|
|
599
|
+
fs.writeFileSync(
|
|
600
|
+
path.resolve(args[moduleOutIdx + 1]),
|
|
601
|
+
generateModuleSource(registry),
|
|
602
|
+
'utf8'
|
|
603
|
+
);
|
|
604
|
+
}
|
|
260
605
|
console.log(`Generated ${path.resolve(outPath)} from registry.yaml`);
|
|
261
606
|
return 0;
|
|
262
607
|
}
|
|
@@ -265,20 +610,25 @@ function main(argv) {
|
|
|
265
610
|
return 0;
|
|
266
611
|
}
|
|
267
612
|
|
|
268
|
-
if (require.main === module) {
|
|
269
|
-
process.exitCode = main(process.argv);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
613
|
module.exports = {
|
|
273
614
|
DEFAULT_REGISTRY_PATH,
|
|
274
615
|
DEFAULT_PACKS_MODULE_PATH,
|
|
616
|
+
DEFAULT_MODULE_PATH,
|
|
617
|
+
MODULE_TEMPLATE_PATH,
|
|
275
618
|
loadRegistry,
|
|
276
619
|
validateRegistry,
|
|
277
620
|
buildPacks,
|
|
278
621
|
buildPackOrder,
|
|
279
622
|
buildExpectedAgents,
|
|
280
623
|
buildAll,
|
|
624
|
+
buildDerived,
|
|
625
|
+
renderSummary,
|
|
626
|
+
generateModuleSource,
|
|
281
627
|
generatePacksModuleSource,
|
|
282
628
|
check,
|
|
283
629
|
main,
|
|
284
630
|
};
|
|
631
|
+
|
|
632
|
+
if (require.main === module) {
|
|
633
|
+
process.exitCode = main(process.argv);
|
|
634
|
+
}
|
|
@@ -28,16 +28,21 @@ To activate an agent, say its name or persona:
|
|
|
28
28
|
- **Forge** (Architect-Dev) — Architecture + Development + Documentation
|
|
29
29
|
- **Sentinel** (Quality) — QA + UX review
|
|
30
30
|
- **Nexus** (Orchestrator) — Sprint management + Autopilot + Parallel execution
|
|
31
|
-
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (
|
|
32
|
-
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents
|
|
33
|
-
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (
|
|
31
|
+
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (OSINT)
|
|
32
|
+
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents (Maker)
|
|
33
|
+
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (Shield)
|
|
34
|
+
- **SEO Scout** (Technical Scanner) — Crawling + technical inspection + performance (SEO)
|
|
35
|
+
- **SEO Chief** (Strategist & Reporter) — Scoring + strategy + reporting (SEO)
|
|
36
|
+
- **SEO Judge** (Content & AI Analyst) — Content quality + structured data + GEO analysis (SEO)
|
|
37
|
+
- **Zecher** (זכר, Memory Guardian) — Memory Archivist — Persistent cross-session memory, consolidation, project scanning, context recall, session handoffs (Memory)
|
|
34
38
|
- **Miriam** (מרים) — Business Analyst — Strategic analysis, research, product briefs (Dev Studio)
|
|
35
39
|
- **Huldah** (חולדה) — Technical Writer — Documentation, diagrams, editorial review (Dev Studio)
|
|
36
40
|
- **Yosef** (יוסף) — Product Manager — PRD, requirements, feature prioritization (Dev Studio)
|
|
37
41
|
- **Rachel** (רחל) — UX Designer — User experience, wireframes, empathy mapping (Dev Studio)
|
|
38
42
|
- **Bezalel** (בצלאל) — System Architect — Architecture, ADRs, epics & stories (Dev Studio)
|
|
39
43
|
- **Oholiab** (אהליאב) — Senior Engineer — TDD, sprint, code review, implementation (Dev Studio)
|
|
40
|
-
- **
|
|
44
|
+
- **Backup Manager** (Backup & Restore) — Timestamped backups, restoration, and rotation (Backup)
|
|
45
|
+
- **Animated Website Creator** (Website Builder) — Video-driven scrolling websites (Animated)
|
|
41
46
|
|
|
42
47
|
## Skills
|
|
43
48
|
|
|
@@ -98,19 +103,27 @@ Agents MUST follow these behavioral principles:
|
|
|
98
103
|
- `.agents/memory/patterns.md` — Write when a reusable pattern is validated
|
|
99
104
|
- `.agents/memory/context.md` — Update at session end with project state
|
|
100
105
|
|
|
106
|
+
## Framework updates
|
|
107
|
+
|
|
108
|
+
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.
|
|
109
|
+
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.
|
|
110
|
+
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.
|
|
111
|
+
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.
|
|
112
|
+
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.
|
|
113
|
+
|
|
101
114
|
## Registry facts (computed from registry.yaml — never hand-typed)
|
|
102
115
|
|
|
103
|
-
- Product: BMAD+ v0.
|
|
116
|
+
- Product: BMAD+ v0.14.0 (derived from BMAD-METHOD v6.6.0)
|
|
104
117
|
- Models supported: claude, gpt, gemini, local (model-agnostic by contract)
|
|
105
118
|
- Packs (9): Core, OSINT, Maker, Shield, SEO, Memory, Dev Studio, Backup, Animated
|
|
106
119
|
- Installer agents (14 across all packs):
|
|
107
120
|
- Core (required): 4 installer agents — Core agents & skills
|
|
108
121
|
- OSINT: 1 installer agent — OSINT & investigation — 2 compliance frameworks
|
|
109
122
|
- Maker: 1 installer agent — Agent creation toolkit
|
|
110
|
-
- Shield: 1 installer agent — GRC compliance (
|
|
123
|
+
- Shield: 1 installer agent — GRC compliance (26 frameworks) — 27 specialized agents, 11 workflows, 26 compliance frameworks
|
|
111
124
|
- SEO: 3 installer agents — SEO audit & optimization — 1 compliance frameworks
|
|
112
125
|
- Memory: 1 installer agent — Persistent cross-session memory
|
|
113
|
-
- Dev Studio: 1 installer agent — SDLC automation (6 agents,
|
|
126
|
+
- Dev Studio: 1 installer agent — SDLC automation (6 agents, specialized workflows) — 6 sub-agents, 38 workflows
|
|
114
127
|
- Backup: 1 installer agent — Backup & restore
|
|
115
128
|
- Animated: 1 installer agent — Animated website agents
|
|
116
129
|
|
|
@@ -33,16 +33,21 @@ To activate an agent, say its name or persona:
|
|
|
33
33
|
- **Forge** (Architect-Dev) — Architecture + Development + Documentation
|
|
34
34
|
- **Sentinel** (Quality) — QA + UX review
|
|
35
35
|
- **Nexus** (Orchestrator) — Sprint management + Autopilot + Parallel execution
|
|
36
|
-
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (
|
|
37
|
-
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents
|
|
38
|
-
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (
|
|
36
|
+
- **Shadow** (OSINT) — Investigation + Scraping + Psychoprofiling (OSINT)
|
|
37
|
+
- **Maker** (Agent Creator) — Design, build, validate, and package new BMAD+ agents (Maker)
|
|
38
|
+
- **Shield** (GRC) — Compliance agents for GDPR, ISO 27001, SOC 2, HIPAA, EU AI Act, DORA, NIS2 and more (Shield)
|
|
39
|
+
- **SEO Scout** (Technical Scanner) — Crawling + technical inspection + performance (SEO)
|
|
40
|
+
- **SEO Chief** (Strategist & Reporter) — Scoring + strategy + reporting (SEO)
|
|
41
|
+
- **SEO Judge** (Content & AI Analyst) — Content quality + structured data + GEO analysis (SEO)
|
|
42
|
+
- **Zecher** (זכר, Memory Guardian) — Memory Archivist — Persistent cross-session memory, consolidation, project scanning, context recall, session handoffs (Memory)
|
|
39
43
|
- **Miriam** (מרים) — Business Analyst — Strategic analysis, research, product briefs (Dev Studio)
|
|
40
44
|
- **Huldah** (חולדה) — Technical Writer — Documentation, diagrams, editorial review (Dev Studio)
|
|
41
45
|
- **Yosef** (יוסף) — Product Manager — PRD, requirements, feature prioritization (Dev Studio)
|
|
42
46
|
- **Rachel** (רחל) — UX Designer — User experience, wireframes, empathy mapping (Dev Studio)
|
|
43
47
|
- **Bezalel** (בצלאל) — System Architect — Architecture, ADRs, epics & stories (Dev Studio)
|
|
44
48
|
- **Oholiab** (אהליאב) — Senior Engineer — TDD, sprint, code review, implementation (Dev Studio)
|
|
45
|
-
- **
|
|
49
|
+
- **Backup Manager** (Backup & Restore) — Timestamped backups, restoration, and rotation (Backup)
|
|
50
|
+
- **Animated Website Creator** (Website Builder) — Video-driven scrolling websites (Animated)
|
|
46
51
|
|
|
47
52
|
## Skills
|
|
48
53
|
|
|
@@ -103,19 +108,27 @@ Agents MUST follow these behavioral principles:
|
|
|
103
108
|
- `.agents/memory/patterns.md` — Write when a reusable pattern is validated
|
|
104
109
|
- `.agents/memory/context.md` — Update at session end with project state
|
|
105
110
|
|
|
111
|
+
## Framework updates
|
|
112
|
+
|
|
113
|
+
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.
|
|
114
|
+
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.
|
|
115
|
+
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.
|
|
116
|
+
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.
|
|
117
|
+
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.
|
|
118
|
+
|
|
106
119
|
## Registry facts (computed from registry.yaml — never hand-typed)
|
|
107
120
|
|
|
108
|
-
- Product: BMAD+ v0.
|
|
121
|
+
- Product: BMAD+ v0.14.0 (derived from BMAD-METHOD v6.6.0)
|
|
109
122
|
- Models supported: claude, gpt, gemini, local (model-agnostic by contract)
|
|
110
123
|
- Packs (9): Core, OSINT, Maker, Shield, SEO, Memory, Dev Studio, Backup, Animated
|
|
111
124
|
- Installer agents (14 across all packs):
|
|
112
125
|
- Core (required): 4 installer agents — Core agents & skills
|
|
113
126
|
- OSINT: 1 installer agent — OSINT & investigation — 2 compliance frameworks
|
|
114
127
|
- Maker: 1 installer agent — Agent creation toolkit
|
|
115
|
-
- Shield: 1 installer agent — GRC compliance (
|
|
128
|
+
- Shield: 1 installer agent — GRC compliance (26 frameworks) — 27 specialized agents, 11 workflows, 26 compliance frameworks
|
|
116
129
|
- SEO: 3 installer agents — SEO audit & optimization — 1 compliance frameworks
|
|
117
130
|
- Memory: 1 installer agent — Persistent cross-session memory
|
|
118
|
-
- Dev Studio: 1 installer agent — SDLC automation (6 agents,
|
|
131
|
+
- Dev Studio: 1 installer agent — SDLC automation (6 agents, specialized workflows) — 6 sub-agents, 38 workflows
|
|
119
132
|
- Backup: 1 installer agent — Backup & restore
|
|
120
133
|
- Animated: 1 installer agent — Animated website agents
|
|
121
134
|
|