bmad-enhanced 1.5.2 → 1.6.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 +104 -6
- package/INSTALLATION.md +93 -245
- package/README.md +121 -1110
- package/UPDATE-GUIDE.md +70 -265
- package/_bmad/_config/agent-manifest.csv +0 -2
- package/_bmad/bme/_vortex/README.md +150 -0
- package/_bmad/bme/_vortex/agents/hypothesis-engineer.md +117 -0
- package/_bmad/bme/_vortex/agents/production-intelligence-specialist.md +117 -0
- package/_bmad/bme/_vortex/agents/research-convergence-specialist.md +117 -0
- package/_bmad/bme/_vortex/compass-routing-reference.md +312 -0
- package/_bmad/bme/_vortex/config.yaml +1 -1
- package/_bmad/bme/_vortex/contracts/hc1-empathy-artifacts.md +152 -0
- package/_bmad/bme/_vortex/contracts/hc2-problem-definition.md +125 -0
- package/_bmad/bme/_vortex/contracts/hc3-hypothesis-contract.md +112 -0
- package/_bmad/bme/_vortex/contracts/hc4-experiment-context.md +140 -0
- package/_bmad/bme/_vortex/contracts/hc5-signal-report.md +130 -0
- package/_bmad/bme/_vortex/examples/hc2-example-problem-definition.md +85 -0
- package/_bmad/bme/_vortex/examples/hc3-example-hypothesis-contract.md +103 -0
- package/_bmad/bme/_vortex/examples/hc5-example-signal-report.md +76 -0
- package/_bmad/bme/_vortex/guides/LIAM-USER-GUIDE.md +260 -0
- package/_bmad/bme/_vortex/guides/MILA-USER-GUIDE.md +240 -0
- package/_bmad/bme/_vortex/guides/NOAH-USER-GUIDE.md +263 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-01-setup.md +66 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-02-context.md +93 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-03-risk-mapping.md +103 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/steps/step-04-synthesize.md +101 -0
- package/_bmad/bme/_vortex/workflows/assumption-mapping/workflow.md +49 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-01-setup.md +81 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-02-context.md +67 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-03-classification.md +98 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-04-evidence.md +100 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/steps/step-05-synthesize.md +174 -0
- package/_bmad/bme/_vortex/workflows/behavior-analysis/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/contextualize-scope/contextualize-scope.template.md +1 -1
- package/_bmad/bme/_vortex/workflows/empathy-map/steps/step-06-synthesize.md +4 -1
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-01-setup.md +66 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-02-context.md +77 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-03-design.md +114 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/steps/step-04-synthesize.md +128 -0
- package/_bmad/bme/_vortex/workflows/experiment-design/workflow.md +51 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-01-setup.md +66 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-02-context.md +80 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-03-brainwriting.md +79 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-04-assumption-mapping.md +102 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/steps/step-05-synthesize.md +130 -0
- package/_bmad/bme/_vortex/workflows/hypothesis-engineering/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/lean-experiment/steps/step-06.md +4 -1
- package/_bmad/bme/_vortex/workflows/lean-persona/lean-persona.template.md +1 -1
- package/_bmad/bme/_vortex/workflows/learning-card/learning-card.template.md +1 -1
- package/_bmad/bme/_vortex/workflows/learning-card/steps/step-06-synthesize.md +4 -1
- package/_bmad/bme/_vortex/workflows/mvp/mvp.template.md +1 -1
- package/_bmad/bme/_vortex/workflows/mvp/steps/step-06-synthesize.md +3 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-01-setup.md +102 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-02-context.md +81 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-03-pattern-identification.md +88 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-04-theme-clustering.md +100 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/steps/step-05-synthesize.md +135 -0
- package/_bmad/bme/_vortex/workflows/pattern-mapping/workflow.md +58 -0
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/pivot-patch-persevere.template.md +1 -1
- package/_bmad/bme/_vortex/workflows/pivot-patch-persevere/steps/step-06-action-plan.md +5 -2
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-01-setup.md +97 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-02-context.md +86 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-03-jtbd-reframing.md +88 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-04-pains-gains-revision.md +76 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/steps/step-05-synthesize.md +158 -0
- package/_bmad/bme/_vortex/workflows/pivot-resynthesis/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/product-vision/product-vision.template.md +1 -1
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-01-setup.md +84 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-02-context.md +66 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-03-monitoring.md +74 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-04-prioritization.md +97 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/steps/step-05-synthesize.md +183 -0
- package/_bmad/bme/_vortex/workflows/production-monitoring/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/proof-of-concept/steps/step-06.md +3 -0
- package/_bmad/bme/_vortex/workflows/proof-of-value/steps/step-06.md +3 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-01-setup.md +69 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-02-context.md +70 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-03-jtbd-framing.md +81 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-04-pains-gains.md +77 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/steps/step-05-synthesize.md +147 -0
- package/_bmad/bme/_vortex/workflows/research-convergence/workflow.md +50 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-01-setup.md +68 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-02-context.md +67 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-03-signal-analysis.md +85 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-04-anomaly-detection.md +93 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/steps/step-05-synthesize.md +163 -0
- package/_bmad/bme/_vortex/workflows/signal-interpretation/workflow.md +52 -0
- package/_bmad/bme/_vortex/workflows/user-discovery/steps/step-06-synthesize.md +4 -1
- package/_bmad/bme/_vortex/workflows/user-interview/steps/step-06-synthesize.md +4 -1
- package/_bmad/bme/_vortex/workflows/user-interview/user-interview.template.md +1 -1
- package/_bmad/bme/_vortex/workflows/user-interview/validate.md +1 -1
- package/_bmad-output/implementation-artifacts/1-1-expand-agent-registry-to-7-agents.md +190 -0
- package/_bmad-output/implementation-artifacts/1-2-update-validator-config-merger-doctor-for-7-agents.md +184 -0
- package/_bmad-output/implementation-artifacts/1-3-create-migration-delta-installer-updates.md +270 -0
- package/_bmad-output/implementation-artifacts/1-4-define-handoff-contract-schemas-hc1-hc5.md +292 -0
- package/_bmad-output/implementation-artifacts/1-5-create-compass-routing-reference-document.md +324 -0
- package/_bmad-output/implementation-artifacts/2-1-design-milas-agent-definition-persona.md +270 -0
- package/_bmad-output/implementation-artifacts/2-2-create-research-convergence-workflow.md +429 -0
- package/_bmad-output/implementation-artifacts/2-3-create-pivot-resynthesis-workflow.md +411 -0
- package/_bmad-output/implementation-artifacts/2-4-create-pattern-mapping-workflow.md +397 -0
- package/_bmad-output/implementation-artifacts/2-5-create-mila-user-guide-example-artifacts.md +243 -0
- package/_bmad-output/implementation-artifacts/3-1-design-liams-agent-definition-persona.md +301 -0
- package/_bmad-output/implementation-artifacts/3-2-create-hypothesis-engineering-workflow.md +403 -0
- package/_bmad-output/implementation-artifacts/3-3-create-assumption-mapping-workflow.md +373 -0
- package/_bmad-output/implementation-artifacts/3-4-create-experiment-design-workflow.md +359 -0
- package/_bmad-output/implementation-artifacts/3-5-create-liam-user-guide-example-artifacts.md +258 -0
- package/_bmad-output/implementation-artifacts/4-1-design-noahs-agent-definition-persona.md +191 -0
- package/_bmad-output/implementation-artifacts/4-2-create-signal-interpretation-workflow.md +352 -0
- package/_bmad-output/implementation-artifacts/4-3-create-behavior-analysis-workflow.md +406 -0
- package/_bmad-output/implementation-artifacts/4-4-create-production-monitoring-workflow.md +430 -0
- package/_bmad-output/implementation-artifacts/4-5-create-noah-user-guide-example-artifacts.md +342 -0
- package/_bmad-output/implementation-artifacts/5-1-update-islas-compass-routes-to-mila.md +210 -0
- package/_bmad-output/implementation-artifacts/5-2-update-wades-maxs-compass-routes.md +260 -0
- package/_bmad-output/implementation-artifacts/5-3-update-documentation-for-complete-7-agent-vortex.md +268 -0
- package/_bmad-output/implementation-artifacts/5-4-add-ci-dead-end-detection-final-version-bump.md +206 -0
- package/_bmad-output/implementation-artifacts/epic-1-retro-2026-02-24.md +90 -0
- package/_bmad-output/implementation-artifacts/epic-2-retro-2026-02-25.md +104 -0
- package/_bmad-output/implementation-artifacts/epic-3-retro-2026-02-25.md +126 -0
- package/_bmad-output/implementation-artifacts/epic-4-retro-2026-02-26.md +151 -0
- package/_bmad-output/implementation-artifacts/epic-5-retro-2026-02-26.md +168 -0
- package/_bmad-output/implementation-artifacts/sprint-status.yaml +85 -0
- package/_bmad-output/planning-artifacts/architecture.md +607 -0
- package/_bmad-output/planning-artifacts/epics.md +826 -0
- package/_bmad-output/planning-artifacts/implementation-readiness-report-2026-02-23.md +156 -0
- package/_bmad-output/planning-artifacts/prd.md +498 -0
- package/_bmad-output/planning-artifacts/product-brief-BMAD-Enhanced-2026-02-22.md +262 -0
- package/_bmad-output/vortex-artifacts/EMMA-USER-GUIDE.md +10 -10
- package/_bmad-output/vortex-artifacts/ISLA-USER-GUIDE.md +4 -4
- package/_bmad-output/vortex-artifacts/MAX-USER-GUIDE.md +4 -4
- package/_bmad-output/vortex-artifacts/WADE-USER-GUIDE.md +10 -10
- package/index.js +6 -5
- package/package.json +2 -6
- package/scripts/bmad-doctor.js +3 -7
- package/scripts/install-vortex-agents.js +23 -18
- package/scripts/postinstall.js +5 -10
- package/scripts/update/bmad-update.js +136 -87
- package/scripts/update/lib/agent-registry.js +144 -0
- package/scripts/update/lib/config-merger.js +67 -43
- package/scripts/update/lib/migration-runner.js +2 -1
- package/scripts/update/lib/refresh-installation.js +4 -37
- package/scripts/update/lib/validator.js +69 -21
- package/scripts/update/migrations/1.5.x-to-1.6.0.js +95 -0
- package/scripts/update/migrations/registry.js +7 -0
- package/scripts/install-emma.js +0 -14
- package/scripts/install-wade.js +0 -14
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs-extra');
|
|
4
4
|
const yaml = require('js-yaml');
|
|
5
|
+
const { AGENT_IDS, WORKFLOW_NAMES } = require('./agent-registry');
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Config Merger for BMAD-Enhanced
|
|
@@ -22,7 +23,8 @@ async function mergeConfig(currentConfigPath, newVersion, updates = {}) {
|
|
|
22
23
|
if (fs.existsSync(currentConfigPath)) {
|
|
23
24
|
try {
|
|
24
25
|
const currentContent = fs.readFileSync(currentConfigPath, 'utf8');
|
|
25
|
-
|
|
26
|
+
const parsed = yaml.load(currentContent);
|
|
27
|
+
current = (parsed && typeof parsed === 'object') ? parsed : {};
|
|
26
28
|
} catch (_error) {
|
|
27
29
|
console.warn('Warning: Could not parse current config.yaml, using defaults');
|
|
28
30
|
current = {};
|
|
@@ -35,9 +37,11 @@ async function mergeConfig(currentConfigPath, newVersion, updates = {}) {
|
|
|
35
37
|
// Seed with required structural defaults for fresh installs
|
|
36
38
|
const defaults = {
|
|
37
39
|
submodule_name: '_vortex',
|
|
38
|
-
description: 'Vortex
|
|
40
|
+
description: 'Vortex Pattern - Contextualize, Empathize, Synthesize, Hypothesize, Externalize, Sensitize, and Systematize streams',
|
|
39
41
|
module: 'bme',
|
|
40
|
-
output_folder: '{project-root}/_bmad-output/vortex-artifacts'
|
|
42
|
+
output_folder: '{project-root}/_bmad-output/vortex-artifacts',
|
|
43
|
+
agents: [...AGENT_IDS],
|
|
44
|
+
workflows: [...WORKFLOW_NAMES]
|
|
41
45
|
};
|
|
42
46
|
|
|
43
47
|
// Start with defaults, overlay current config (preserves existing values)
|
|
@@ -79,7 +83,7 @@ function extractUserPreferences(config) {
|
|
|
79
83
|
prefs.user_name = config.user_name;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
|
-
if (config.communication_language
|
|
86
|
+
if (config.communication_language) {
|
|
83
87
|
prefs.communication_language = config.communication_language;
|
|
84
88
|
}
|
|
85
89
|
|
|
@@ -98,6 +102,34 @@ function extractUserPreferences(config) {
|
|
|
98
102
|
return prefs;
|
|
99
103
|
}
|
|
100
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Declarative config schema.
|
|
107
|
+
* Each entry declares a field's type, whether it's required, and an optional
|
|
108
|
+
* validation function that receives the value and returns an error string or null.
|
|
109
|
+
*/
|
|
110
|
+
const CONFIG_SCHEMA = [
|
|
111
|
+
{ field: 'submodule_name', type: 'string', required: true },
|
|
112
|
+
{ field: 'description', type: 'string', required: true },
|
|
113
|
+
{ field: 'module', type: 'string', required: true },
|
|
114
|
+
{ field: 'version', type: 'string', required: true,
|
|
115
|
+
validate: v => /^\d+\.\d+\.\d+$/.test(v) ? null : `Invalid version format: ${v} (expected x.x.x)` },
|
|
116
|
+
{ field: 'output_folder', type: 'string', required: true },
|
|
117
|
+
{ field: 'agents', type: 'array', required: true, items: 'string' },
|
|
118
|
+
{ field: 'workflows', type: 'array', required: true, items: 'string' },
|
|
119
|
+
{ field: 'communication_language', type: 'string', required: false },
|
|
120
|
+
{ field: 'party_mode_enabled', type: 'boolean', required: false },
|
|
121
|
+
{ field: 'migration_history', type: 'array', required: false,
|
|
122
|
+
validate: (arr) => {
|
|
123
|
+
for (let i = 0; i < arr.length; i++) {
|
|
124
|
+
const e = arr[i];
|
|
125
|
+
if (!e.timestamp || !e.from_version || !e.to_version) {
|
|
126
|
+
return `migration_history[${i}] missing required fields`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}},
|
|
131
|
+
];
|
|
132
|
+
|
|
101
133
|
/**
|
|
102
134
|
* Validate merged config structure
|
|
103
135
|
* @param {object} config - Config to validate
|
|
@@ -106,48 +138,39 @@ function extractUserPreferences(config) {
|
|
|
106
138
|
function validateConfig(config) {
|
|
107
139
|
const errors = [];
|
|
108
140
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
'submodule_name',
|
|
112
|
-
'description',
|
|
113
|
-
'module',
|
|
114
|
-
'version',
|
|
115
|
-
'output_folder',
|
|
116
|
-
'agents',
|
|
117
|
-
'workflows'
|
|
118
|
-
];
|
|
119
|
-
|
|
120
|
-
for (const field of requiredFields) {
|
|
121
|
-
if (!Object.prototype.hasOwnProperty.call(config, field)) {
|
|
122
|
-
errors.push(`Missing required field: ${field}`);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Validate version format (x.x.x)
|
|
127
|
-
if (config.version && !/^\d+\.\d+\.\d+$/.test(config.version)) {
|
|
128
|
-
errors.push(`Invalid version format: ${config.version} (expected x.x.x)`);
|
|
129
|
-
}
|
|
141
|
+
for (const rule of CONFIG_SCHEMA) {
|
|
142
|
+
const has = Object.prototype.hasOwnProperty.call(config, rule.field);
|
|
130
143
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// Validate workflows is array
|
|
137
|
-
if (config.workflows && !Array.isArray(config.workflows)) {
|
|
138
|
-
errors.push('workflows must be an array');
|
|
139
|
-
}
|
|
144
|
+
if (!has) {
|
|
145
|
+
if (rule.required) errors.push(`Missing required field: ${rule.field}`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
140
148
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
const value = config[rule.field];
|
|
150
|
+
|
|
151
|
+
// Type check
|
|
152
|
+
if (rule.type === 'array') {
|
|
153
|
+
if (!Array.isArray(value)) {
|
|
154
|
+
errors.push(`${rule.field} must be an array`);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
// Item type check
|
|
158
|
+
if (rule.items) {
|
|
159
|
+
for (let i = 0; i < value.length; i++) {
|
|
160
|
+
if (typeof value[i] !== rule.items) {
|
|
161
|
+
errors.push(`${rule.field}[${i}] must be a ${rule.items}`);
|
|
162
|
+
}
|
|
149
163
|
}
|
|
150
|
-
}
|
|
164
|
+
}
|
|
165
|
+
} else if (typeof value !== rule.type) {
|
|
166
|
+
errors.push(`${rule.field} must be a ${rule.type}`);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Custom validation
|
|
171
|
+
if (rule.validate) {
|
|
172
|
+
const err = rule.validate(value);
|
|
173
|
+
if (err) errors.push(err);
|
|
151
174
|
}
|
|
152
175
|
}
|
|
153
176
|
|
|
@@ -197,6 +220,7 @@ function addMigrationHistory(config, fromVersion, toVersion, migrationsApplied)
|
|
|
197
220
|
}
|
|
198
221
|
|
|
199
222
|
module.exports = {
|
|
223
|
+
CONFIG_SCHEMA,
|
|
200
224
|
mergeConfig,
|
|
201
225
|
extractUserPreferences,
|
|
202
226
|
validateConfig,
|
|
@@ -10,6 +10,7 @@ const configMerger = require('./config-merger');
|
|
|
10
10
|
const validator = require('./validator');
|
|
11
11
|
const { refreshInstallation } = require('./refresh-installation');
|
|
12
12
|
const registry = require('../migrations/registry');
|
|
13
|
+
const { WORKFLOW_NAMES } = require('./agent-registry');
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Migration Runner for BMAD-Enhanced
|
|
@@ -216,7 +217,7 @@ async function previewMigrations(migrations) {
|
|
|
216
217
|
console.log('');
|
|
217
218
|
console.log(chalk.white('After deltas, installation will be refreshed:'));
|
|
218
219
|
console.log(chalk.gray(' - Refresh agent files'));
|
|
219
|
-
console.log(chalk.gray(
|
|
220
|
+
console.log(chalk.gray(` - Refresh ${WORKFLOW_NAMES.length} workflow directories`));
|
|
220
221
|
console.log(chalk.gray(' - Update config.yaml (preserving user preferences)'));
|
|
221
222
|
console.log(chalk.gray(' - Update user guides (with .bak backup)'));
|
|
222
223
|
console.log('');
|
|
@@ -4,6 +4,7 @@ const fs = require('fs-extra');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { getPackageVersion } = require('./utils');
|
|
6
6
|
const configMerger = require('./config-merger');
|
|
7
|
+
const { AGENT_FILES, AGENT_IDS, WORKFLOW_NAMES, USER_GUIDES } = require('./agent-registry');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Refresh Installation for BMAD-Enhanced
|
|
@@ -13,40 +14,6 @@ const configMerger = require('./config-merger');
|
|
|
13
14
|
* or directly by the install script.
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
|
-
const AGENT_FILES = [
|
|
17
|
-
'contextualization-expert.md',
|
|
18
|
-
'lean-experiments-specialist.md',
|
|
19
|
-
'discovery-empathy-expert.md',
|
|
20
|
-
'learning-decision-expert.md'
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const WORKFLOWS = [
|
|
24
|
-
// Emma — Contextualize Stream
|
|
25
|
-
'lean-persona',
|
|
26
|
-
'product-vision',
|
|
27
|
-
'contextualize-scope',
|
|
28
|
-
// Wade — Externalize Stream
|
|
29
|
-
'mvp',
|
|
30
|
-
'lean-experiment',
|
|
31
|
-
'proof-of-concept',
|
|
32
|
-
'proof-of-value',
|
|
33
|
-
// Isla — Empathize Stream
|
|
34
|
-
'empathy-map',
|
|
35
|
-
'user-interview',
|
|
36
|
-
'user-discovery',
|
|
37
|
-
// Max — Systematize Stream
|
|
38
|
-
'learning-card',
|
|
39
|
-
'pivot-patch-persevere',
|
|
40
|
-
'vortex-navigation'
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
const USER_GUIDES = [
|
|
44
|
-
'EMMA-USER-GUIDE.md',
|
|
45
|
-
'WADE-USER-GUIDE.md',
|
|
46
|
-
'ISLA-USER-GUIDE.md',
|
|
47
|
-
'MAX-USER-GUIDE.md'
|
|
48
|
-
];
|
|
49
|
-
|
|
50
17
|
/**
|
|
51
18
|
* Refresh all installation files from the package to the project.
|
|
52
19
|
*
|
|
@@ -94,7 +61,7 @@ async function refreshInstallation(projectRoot, options = {}) {
|
|
|
94
61
|
const workflowsTarget = path.join(targetVortex, 'workflows');
|
|
95
62
|
await fs.ensureDir(workflowsTarget);
|
|
96
63
|
|
|
97
|
-
for (const wf of
|
|
64
|
+
for (const wf of WORKFLOW_NAMES) {
|
|
98
65
|
const src = path.join(workflowsSource, wf);
|
|
99
66
|
if (fs.existsSync(src)) {
|
|
100
67
|
await fs.copy(src, path.join(workflowsTarget, wf), { overwrite: true });
|
|
@@ -108,8 +75,8 @@ async function refreshInstallation(projectRoot, options = {}) {
|
|
|
108
75
|
await fs.ensureDir(path.dirname(configPath));
|
|
109
76
|
|
|
110
77
|
const updates = {
|
|
111
|
-
agents:
|
|
112
|
-
workflows:
|
|
78
|
+
agents: AGENT_IDS,
|
|
79
|
+
workflows: WORKFLOW_NAMES
|
|
113
80
|
};
|
|
114
81
|
|
|
115
82
|
const merged = await configMerger.mergeConfig(configPath, version, updates);
|
|
@@ -5,6 +5,7 @@ const path = require('path');
|
|
|
5
5
|
const yaml = require('js-yaml');
|
|
6
6
|
const configMerger = require('./config-merger');
|
|
7
7
|
const { countUserDataFiles } = require('./utils');
|
|
8
|
+
const { AGENT_FILES, AGENT_IDS, WORKFLOW_NAMES, WAVE3_WORKFLOW_NAMES } = require('./agent-registry');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Validator for BMAD-Enhanced
|
|
@@ -40,6 +41,9 @@ async function validateInstallation(preMigrationData = {}, projectRoot) {
|
|
|
40
41
|
// 6. Deprecated workflows validation (if applicable)
|
|
41
42
|
checks.push(await validateDeprecatedWorkflows(projectRoot));
|
|
42
43
|
|
|
44
|
+
// 7. Workflow step structure validation (P17 count + P20 filenames)
|
|
45
|
+
checks.push(await validateWorkflowStepStructure(projectRoot));
|
|
46
|
+
|
|
43
47
|
const allPassed = checks.every(c => c.passed);
|
|
44
48
|
|
|
45
49
|
return {
|
|
@@ -101,12 +105,7 @@ async function validateAgentFiles(projectRoot) {
|
|
|
101
105
|
|
|
102
106
|
try {
|
|
103
107
|
const agentsDir = path.join(projectRoot, '_bmad/bme/_vortex/agents');
|
|
104
|
-
const requiredAgents =
|
|
105
|
-
'contextualization-expert.md',
|
|
106
|
-
'lean-experiments-specialist.md',
|
|
107
|
-
'discovery-empathy-expert.md',
|
|
108
|
-
'learning-decision-expert.md'
|
|
109
|
-
];
|
|
108
|
+
const requiredAgents = AGENT_FILES;
|
|
110
109
|
|
|
111
110
|
if (!fs.existsSync(agentsDir)) {
|
|
112
111
|
check.error = 'agents/ directory not found';
|
|
@@ -148,15 +147,7 @@ async function validateWorkflows(projectRoot) {
|
|
|
148
147
|
|
|
149
148
|
try {
|
|
150
149
|
const workflowsDir = path.join(projectRoot, '_bmad/bme/_vortex/workflows');
|
|
151
|
-
const requiredWorkflows =
|
|
152
|
-
'lean-persona',
|
|
153
|
-
'product-vision',
|
|
154
|
-
'contextualize-scope',
|
|
155
|
-
'mvp',
|
|
156
|
-
'lean-experiment',
|
|
157
|
-
'proof-of-concept',
|
|
158
|
-
'proof-of-value'
|
|
159
|
-
];
|
|
150
|
+
const requiredWorkflows = WORKFLOW_NAMES;
|
|
160
151
|
|
|
161
152
|
if (!fs.existsSync(workflowsDir)) {
|
|
162
153
|
check.error = 'workflows/ directory not found';
|
|
@@ -208,12 +199,11 @@ async function validateManifest(projectRoot) {
|
|
|
208
199
|
|
|
209
200
|
const manifestContent = fs.readFileSync(manifestPath, 'utf8');
|
|
210
201
|
|
|
211
|
-
// Check for BMAD-Enhanced agents
|
|
212
|
-
const
|
|
213
|
-
const hasWade = manifestContent.includes('lean-experiments-specialist');
|
|
202
|
+
// Check for all BMAD-Enhanced agents
|
|
203
|
+
const missingFromManifest = AGENT_IDS.filter(id => !manifestContent.includes(id));
|
|
214
204
|
|
|
215
|
-
if (
|
|
216
|
-
check.error =
|
|
205
|
+
if (missingFromManifest.length > 0) {
|
|
206
|
+
check.error = `Agent manifest missing: ${missingFromManifest.join(', ')}`;
|
|
217
207
|
return check;
|
|
218
208
|
}
|
|
219
209
|
|
|
@@ -301,6 +291,63 @@ async function validateDeprecatedWorkflows(projectRoot) {
|
|
|
301
291
|
return check;
|
|
302
292
|
}
|
|
303
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Validate workflow step structure (P17 count + P20 filenames)
|
|
296
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
297
|
+
* @returns {Promise<object>} Validation check result
|
|
298
|
+
*/
|
|
299
|
+
async function validateWorkflowStepStructure(projectRoot) {
|
|
300
|
+
const check = {
|
|
301
|
+
name: 'Workflow step structure',
|
|
302
|
+
passed: true,
|
|
303
|
+
error: null
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
try {
|
|
307
|
+
const workflowsDir = path.join(projectRoot, '_bmad/bme/_vortex/workflows');
|
|
308
|
+
const issues = [];
|
|
309
|
+
|
|
310
|
+
for (const workflow of WORKFLOW_NAMES) {
|
|
311
|
+
const stepsDir = path.join(workflowsDir, workflow, 'steps');
|
|
312
|
+
|
|
313
|
+
if (!fs.existsSync(stepsDir)) {
|
|
314
|
+
continue; // Placeholder workflows without steps/ are valid
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const files = fs.readdirSync(stepsDir).filter(f => f.endsWith('.md'));
|
|
318
|
+
|
|
319
|
+
// P17: step count must be 4-6
|
|
320
|
+
if (files.length < 4 || files.length > 6) {
|
|
321
|
+
issues.push(`${workflow}: ${files.length} step files (expected 4-6)`);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// P20: standardized filenames (Wave 3 workflows only)
|
|
326
|
+
if (WAVE3_WORKFLOW_NAMES.has(workflow)) {
|
|
327
|
+
if (!files.includes('step-01-setup.md')) {
|
|
328
|
+
issues.push(`${workflow}: missing step-01-setup.md`);
|
|
329
|
+
}
|
|
330
|
+
if (!files.includes('step-02-context.md')) {
|
|
331
|
+
issues.push(`${workflow}: missing step-02-context.md`);
|
|
332
|
+
}
|
|
333
|
+
if (!files.some(f => f.endsWith('-synthesize.md'))) {
|
|
334
|
+
issues.push(`${workflow}: missing *-synthesize.md final step`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (issues.length > 0) {
|
|
340
|
+
check.passed = false;
|
|
341
|
+
check.error = `Step structure issues: ${issues.join('; ')}`;
|
|
342
|
+
}
|
|
343
|
+
} catch (error) {
|
|
344
|
+
check.error = error.message;
|
|
345
|
+
check.passed = false;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return check;
|
|
349
|
+
}
|
|
350
|
+
|
|
304
351
|
module.exports = {
|
|
305
352
|
validateInstallation,
|
|
306
353
|
validateConfigStructure,
|
|
@@ -308,5 +355,6 @@ module.exports = {
|
|
|
308
355
|
validateWorkflows,
|
|
309
356
|
validateManifest,
|
|
310
357
|
validateUserDataIntegrity,
|
|
311
|
-
validateDeprecatedWorkflows
|
|
358
|
+
validateDeprecatedWorkflows,
|
|
359
|
+
validateWorkflowStepStructure
|
|
312
360
|
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const yaml = require('js-yaml');
|
|
4
|
+
const { AGENTS, AGENT_IDS, WAVE3_WORKFLOW_NAMES } = require('../lib/agent-registry');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Migration: 1.5.x → current version (v1.6.0)
|
|
8
|
+
* Appends Wave 3 agents and workflows to existing config.
|
|
9
|
+
* refreshInstallation() handles file copying (agents, workflows, guides).
|
|
10
|
+
*
|
|
11
|
+
* Wave 3 agents: Mila (Synthesize), Liam (Hypothesize), Noah (Sensitize)
|
|
12
|
+
* Wave 3 workflows: 9 new workflows (3 per agent)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// Wave 1/2 agent IDs (pre-1.6.0)
|
|
16
|
+
const WAVE12_AGENT_IDS = new Set([
|
|
17
|
+
'contextualization-expert',
|
|
18
|
+
'discovery-empathy-expert',
|
|
19
|
+
'lean-experiments-specialist',
|
|
20
|
+
'learning-decision-expert'
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
// Wave 3 agent IDs derived from registry; workflow names from WAVE3_WORKFLOW_NAMES set
|
|
24
|
+
const WAVE3_AGENT_IDS = AGENT_IDS.filter(id => !WAVE12_AGENT_IDS.has(id));
|
|
25
|
+
const WAVE3_WORKFLOWS = [...WAVE3_WORKFLOW_NAMES];
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
name: '1.5.x-to-1.6.0',
|
|
29
|
+
fromVersion: '1.5.x',
|
|
30
|
+
breaking: false,
|
|
31
|
+
|
|
32
|
+
async preview() {
|
|
33
|
+
const wave3Agents = AGENTS.filter(a => WAVE3_AGENT_IDS.includes(a.id));
|
|
34
|
+
const agentDesc = wave3Agents.map(a => `${a.name} (${a.id})`).join(', ');
|
|
35
|
+
return {
|
|
36
|
+
actions: [
|
|
37
|
+
`Append Wave 3 agents to config: ${agentDesc}`,
|
|
38
|
+
`Append ${WAVE3_WORKFLOWS.length} Wave 3 workflows to config: ${WAVE3_WORKFLOWS.join(', ')}`,
|
|
39
|
+
'File copying handled by refreshInstallation()'
|
|
40
|
+
]
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Apply migration: append Wave 3 agents and workflows to config.
|
|
46
|
+
* Idempotent — skips entries already present.
|
|
47
|
+
* @param {string} projectRoot - Absolute path to project root
|
|
48
|
+
* @returns {Promise<Array<string>>} List of changes made
|
|
49
|
+
*/
|
|
50
|
+
async apply(projectRoot) {
|
|
51
|
+
const changes = [];
|
|
52
|
+
const configPath = path.join(projectRoot, '_bmad', 'bme', '_vortex', 'config.yaml');
|
|
53
|
+
|
|
54
|
+
if (!await fs.pathExists(configPath)) {
|
|
55
|
+
changes.push('No config.yaml found — refreshInstallation will create it');
|
|
56
|
+
return changes;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
60
|
+
const config = yaml.load(configContent) || {};
|
|
61
|
+
|
|
62
|
+
// Ensure arrays exist
|
|
63
|
+
if (!Array.isArray(config.agents)) {
|
|
64
|
+
config.agents = [];
|
|
65
|
+
}
|
|
66
|
+
if (!Array.isArray(config.workflows)) {
|
|
67
|
+
config.workflows = [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Append missing Wave 3 agents (idempotent)
|
|
71
|
+
const newAgents = WAVE3_AGENT_IDS.filter(id => !config.agents.includes(id));
|
|
72
|
+
if (newAgents.length > 0) {
|
|
73
|
+
config.agents.push(...newAgents);
|
|
74
|
+
changes.push(`Appended ${newAgents.length} Wave 3 agent(s): ${newAgents.join(', ')}`);
|
|
75
|
+
} else {
|
|
76
|
+
changes.push('Wave 3 agents already present in config');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Append missing Wave 3 workflows (idempotent)
|
|
80
|
+
const newWorkflows = WAVE3_WORKFLOWS.filter(name => !config.workflows.includes(name));
|
|
81
|
+
if (newWorkflows.length > 0) {
|
|
82
|
+
config.workflows.push(...newWorkflows);
|
|
83
|
+
changes.push(`Appended ${newWorkflows.length} Wave 3 workflow(s): ${newWorkflows.join(', ')}`);
|
|
84
|
+
} else {
|
|
85
|
+
changes.push('Wave 3 workflows already present in config');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Write updated config back
|
|
89
|
+
if (newAgents.length > 0 || newWorkflows.length > 0) {
|
|
90
|
+
await fs.writeFile(configPath, yaml.dump(config, { indent: 2, lineWidth: -1, noRefs: true }), 'utf8');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return changes;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
@@ -46,6 +46,13 @@ const MIGRATIONS = [
|
|
|
46
46
|
breaking: false,
|
|
47
47
|
description: 'No-op delta (refresh handles Wave 2 agents and workflows)',
|
|
48
48
|
module: null
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: '1.5.x-to-1.6.0',
|
|
52
|
+
fromVersion: '1.5.x',
|
|
53
|
+
breaking: false,
|
|
54
|
+
description: 'Add Wave 3 agents (Mila, Liam, Noah) and 9 workflows to config',
|
|
55
|
+
module: null
|
|
49
56
|
}
|
|
50
57
|
// Future migrations: append here. Only add delta logic for version-specific changes.
|
|
51
58
|
];
|
package/scripts/install-emma.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* bmad-install-emma — Deprecated. Use bmad-install-vortex-agents instead.
|
|
5
|
-
*/
|
|
6
|
-
const YELLOW = '\x1b[33m';
|
|
7
|
-
const RESET = '\x1b[0m';
|
|
8
|
-
|
|
9
|
-
console.log('');
|
|
10
|
-
console.log(`${YELLOW}⚠ bmad-install-emma is deprecated as of v1.5.0.${RESET}`);
|
|
11
|
-
console.log(`${YELLOW} Use: npx bmad-install-vortex-agents${RESET}`);
|
|
12
|
-
console.log('');
|
|
13
|
-
|
|
14
|
-
require('./install-vortex-agents.js');
|
package/scripts/install-wade.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* bmad-install-wade — Deprecated. Use bmad-install-vortex-agents instead.
|
|
5
|
-
*/
|
|
6
|
-
const YELLOW = '\x1b[33m';
|
|
7
|
-
const RESET = '\x1b[0m';
|
|
8
|
-
|
|
9
|
-
console.log('');
|
|
10
|
-
console.log(`${YELLOW}⚠ bmad-install-wade is deprecated as of v1.5.0.${RESET}`);
|
|
11
|
-
console.log(`${YELLOW} Use: npx bmad-install-vortex-agents${RESET}`);
|
|
12
|
-
console.log('');
|
|
13
|
-
|
|
14
|
-
require('./install-vortex-agents.js');
|