bmad-method 6.12.1 → 6.12.2
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/.claude-plugin/marketplace.json +1 -1
- package/bmad-modules.yaml +5 -0
- package/package.json +1 -1
- package/src/bmm-skills/plan/bmad-architecture/scripts/lint_spine.py +4 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/sprint_plan.py +4 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/git_evidence.py +4 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/sprint_status.py +4 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/bmad-customize/scripts/list_customizable_skills.py +4 -0
- package/src/core-skills/bmad-deep-recon/scripts/recon_kit.py +4 -0
- package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
- package/src/scripts/memlog.py +4 -0
- package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
- package/tools/installer/core/installer.js +3 -0
- package/tools/installer/install-messages.yaml +13 -6
- package/tools/installer/modules/channel-plan.js +6 -1
- package/tools/installer/modules/external-manager.js +2 -0
- package/tools/installer/ui.js +13 -3
- package/tools/tests/__pycache__/test_validate_skills.cpython-311.pyc +0 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"displayName": "BMad Method Analyze Plan Build",
|
|
15
15
|
"source": "./",
|
|
16
16
|
"description": "Full-lifecycle AI development framework — agents and workflows for product analysis, planning, architecture, and implementation.",
|
|
17
|
-
"version": "6.12.
|
|
17
|
+
"version": "6.12.2",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "Brian (BMad) Madison"
|
|
20
20
|
},
|
package/bmad-modules.yaml
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
# override with --channel/--pin/--next. Valid values: stable | next.
|
|
9
9
|
# Omit to inherit the installer's hardcoded default (stable).
|
|
10
10
|
#
|
|
11
|
+
# pin (optional) — a git tag to install instead of the channel. Use it when
|
|
12
|
+
# newer releases no longer work with this installer. Only --pin overrides it.
|
|
13
|
+
#
|
|
11
14
|
# deprecated (optional, default false) — when true, the module is hidden from
|
|
12
15
|
# the installer picker UNLESS it is already installed (so existing users can
|
|
13
16
|
# still see/manage it, but new users are not offered it).
|
|
@@ -55,6 +58,7 @@ modules:
|
|
|
55
58
|
type: bmad-org
|
|
56
59
|
npmPackage: bmad-creative-intelligence-suite
|
|
57
60
|
default_channel: stable
|
|
61
|
+
pin: v0.3.2
|
|
58
62
|
|
|
59
63
|
bmad-method-test-architecture-enterprise:
|
|
60
64
|
url: https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise
|
|
@@ -66,6 +70,7 @@ modules:
|
|
|
66
70
|
type: bmad-org
|
|
67
71
|
npmPackage: bmad-method-test-architecture-enterprise
|
|
68
72
|
default_channel: stable
|
|
73
|
+
pin: v1.27.2
|
|
69
74
|
|
|
70
75
|
bmad-loop:
|
|
71
76
|
url: https://github.com/bmad-code-org/bmad-loop
|
package/package.json
CHANGED
|
@@ -254,4 +254,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
254
254
|
|
|
255
255
|
|
|
256
256
|
if __name__ == "__main__":
|
|
257
|
+
if sys.platform == "win32":
|
|
258
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
259
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
260
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
257
261
|
sys.exit(main())
|
package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc
CHANGED
|
Binary file
|
|
@@ -694,4 +694,8 @@ def main(argv=None):
|
|
|
694
694
|
|
|
695
695
|
|
|
696
696
|
if __name__ == "__main__":
|
|
697
|
+
if sys.platform == "win32":
|
|
698
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
699
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
700
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
697
701
|
main()
|
|
Binary file
|
package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc
CHANGED
|
Binary file
|
|
@@ -301,4 +301,8 @@ def main(argv=None):
|
|
|
301
301
|
|
|
302
302
|
|
|
303
303
|
if __name__ == "__main__":
|
|
304
|
+
if sys.platform == "win32":
|
|
305
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
306
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
307
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
304
308
|
main()
|
|
@@ -743,4 +743,8 @@ def main(argv=None):
|
|
|
743
743
|
|
|
744
744
|
|
|
745
745
|
if __name__ == "__main__":
|
|
746
|
+
if sys.platform == "win32":
|
|
747
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
748
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
749
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
746
750
|
main()
|
|
Binary file
|
|
Binary file
|
|
@@ -228,4 +228,8 @@ def main(argv: list[str]) -> int:
|
|
|
228
228
|
|
|
229
229
|
|
|
230
230
|
if __name__ == "__main__":
|
|
231
|
+
if sys.platform == "win32":
|
|
232
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
233
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
234
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
231
235
|
sys.exit(main(sys.argv[1:]))
|
|
@@ -319,4 +319,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
319
319
|
|
|
320
320
|
|
|
321
321
|
if __name__ == "__main__":
|
|
322
|
+
if sys.platform == "win32":
|
|
323
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
324
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
325
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
322
326
|
sys.exit(main())
|
|
Binary file
|
package/src/scripts/memlog.py
CHANGED
|
@@ -221,4 +221,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
221
221
|
|
|
222
222
|
|
|
223
223
|
if __name__ == "__main__":
|
|
224
|
+
if sys.platform == "win32":
|
|
225
|
+
# Piped output on Windows defaults to a legacy code page, not UTF-8.
|
|
226
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
227
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
224
228
|
sys.exit(main())
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -6,16 +6,19 @@
|
|
|
6
6
|
startMessage: |
|
|
7
7
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
8
8
|
|
|
9
|
-
Agile AI-Driven Development. Powered by BMad Core and a growing module ecosystem.
|
|
9
|
+
The Breakthrough Method of Agile AI-Driven Development - the original and best AI SDLC. Powered by BMad Core and a growing module ecosystem.
|
|
10
10
|
Install official and community modules during setup to customize your experience.
|
|
11
11
|
|
|
12
12
|
🌟 100% free. 100% open source. Always.
|
|
13
13
|
No paywalls. No gated content. Knowledge shared, not sold.
|
|
14
14
|
|
|
15
|
+
🚀 BMad v7 is close, and you can preview and test it now:
|
|
16
|
+
npx skills add bmad-code-org/BMAD-METHOD
|
|
17
|
+
then ask your agent for `bmad setup`. After setup, `bmad migrate`
|
|
18
|
+
tests the v6 to v7 migration (still in beta).
|
|
19
|
+
|
|
15
20
|
🐍 REQUIRED: uv (https://docs.astral.sh/uv/) runs the Python scripts BMAD
|
|
16
|
-
skills rely on
|
|
17
|
-
Without it, bmad-build and bmad-build-auto halt on activation.
|
|
18
|
-
If it's not set up yet, ask your AI agent to "install and set up uv for me".
|
|
21
|
+
skills rely on. If it's not set up yet, ask your AI agent to "install and set up uv for me".
|
|
19
22
|
|
|
20
23
|
🌐 CONNECT:
|
|
21
24
|
Website: https://bmadcode.com/
|
|
@@ -33,5 +36,9 @@ startMessage: |
|
|
|
33
36
|
|
|
34
37
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
35
38
|
|
|
36
|
-
#
|
|
37
|
-
endMessage:
|
|
39
|
+
# Display at the END of installation (after the install summary)
|
|
40
|
+
endMessage: |
|
|
41
|
+
🚀 BMad v7 is close, and you can preview and test it now:
|
|
42
|
+
npx skills add bmad-code-org/BMAD-METHOD
|
|
43
|
+
then ask your agent for `bmad setup`. After setup, `bmad migrate`
|
|
44
|
+
tests the v6 to v7 migration (still in beta).
|
|
@@ -104,15 +104,19 @@ function parsePinSpec(spec) {
|
|
|
104
104
|
* @param {string} args.code
|
|
105
105
|
* @param {Object} args.channelOptions - from parseChannelOptions
|
|
106
106
|
* @param {string} [args.registryDefault] - module's default_channel, if any
|
|
107
|
+
* @param {string} [args.registryPin] - module's registry pin, if any
|
|
107
108
|
* @returns {{channel: 'stable'|'next'|'pinned', pin?: string, source: string}}
|
|
108
109
|
* source describes where the decision came from, for logging / debugging.
|
|
109
110
|
*/
|
|
110
|
-
function decideChannelForModule({ code, channelOptions, registryDefault }) {
|
|
111
|
+
function decideChannelForModule({ code, channelOptions, registryDefault, registryPin }) {
|
|
111
112
|
const { global, nextSet, pins } = channelOptions || { nextSet: new Set(), pins: new Map() };
|
|
112
113
|
|
|
113
114
|
if (pins && pins.has(code)) {
|
|
114
115
|
return { channel: 'pinned', pin: pins.get(code), source: 'flag:--pin' };
|
|
115
116
|
}
|
|
117
|
+
if (registryPin) {
|
|
118
|
+
return { channel: 'pinned', pin: registryPin, source: 'registry:pin' };
|
|
119
|
+
}
|
|
116
120
|
if (nextSet && nextSet.has(code)) {
|
|
117
121
|
return { channel: 'next', source: 'flag:--next' };
|
|
118
122
|
}
|
|
@@ -144,6 +148,7 @@ function buildPlan({ modules, channelOptions }) {
|
|
|
144
148
|
code: mod.code,
|
|
145
149
|
channelOptions,
|
|
146
150
|
registryDefault: mod.defaultChannel,
|
|
151
|
+
registryPin: mod.pin,
|
|
147
152
|
}),
|
|
148
153
|
);
|
|
149
154
|
}
|
|
@@ -130,6 +130,7 @@ class ExternalModuleManager {
|
|
|
130
130
|
npmPackage: mod.npm_package || mod.npmPackage || null,
|
|
131
131
|
pluginName: mod.plugin_name || mod.pluginName || null,
|
|
132
132
|
defaultChannel: normalizeChannelName(mod.default_channel || mod.defaultChannel) || 'stable',
|
|
133
|
+
pin: mod.pin || null,
|
|
133
134
|
deprecated: mod.deprecated === true,
|
|
134
135
|
deprecationMessage: mod.deprecation_message || mod['deprecation-message'] || mod.deprecationMessage || null,
|
|
135
136
|
marketplacePlugin: mod.marketplace_plugin === true || mod['marketplace-plugin'] === true || mod.marketplacePlugin === true,
|
|
@@ -273,6 +274,7 @@ class ExternalModuleManager {
|
|
|
273
274
|
code: moduleCode,
|
|
274
275
|
channelOptions: options.channelOptions,
|
|
275
276
|
registryDefault: moduleInfo.defaultChannel,
|
|
277
|
+
registryPin: moduleInfo.pin,
|
|
276
278
|
});
|
|
277
279
|
|
|
278
280
|
// Same-plan short-circuit: a single install calls cloneExternalModule
|
package/tools/installer/ui.js
CHANGED
|
@@ -70,15 +70,17 @@ function buildModuleLabel(name, latestVersion, installedVersion = '') {
|
|
|
70
70
|
* @param {Object} options
|
|
71
71
|
* @param {string|null} [options.repoUrl] - Module repository URL for tag resolution
|
|
72
72
|
* @param {string|null} [options.registryDefault] - Registry default channel
|
|
73
|
+
* @param {string|null} [options.registryPin] - Registry pinned tag
|
|
73
74
|
* @param {Object|null} [options.channelOptions] - Parsed installer channel options
|
|
74
75
|
* @returns {Promise<{version: string, lookupAttempted: boolean, lookupSucceeded: boolean}>}
|
|
75
76
|
*/
|
|
76
|
-
async function getModuleVersion(moduleCode, { repoUrl = null, registryDefault = null, channelOptions = null } = {}) {
|
|
77
|
+
async function getModuleVersion(moduleCode, { repoUrl = null, registryDefault = null, registryPin = null, channelOptions = null } = {}) {
|
|
77
78
|
if (repoUrl) {
|
|
78
79
|
const plan = decideChannelForModule({
|
|
79
80
|
code: moduleCode,
|
|
80
81
|
channelOptions,
|
|
81
82
|
registryDefault,
|
|
83
|
+
registryPin,
|
|
82
84
|
});
|
|
83
85
|
|
|
84
86
|
try {
|
|
@@ -291,6 +293,13 @@ class UI {
|
|
|
291
293
|
}
|
|
292
294
|
confirmedDirectory = expandedDir;
|
|
293
295
|
await prompts.log.info(`Using directory from command-line: ${confirmedDirectory}`);
|
|
296
|
+
} else if (options.yes) {
|
|
297
|
+
confirmedDirectory = process.cwd();
|
|
298
|
+
const validation = this.validateDirectorySync(confirmedDirectory);
|
|
299
|
+
if (validation) {
|
|
300
|
+
throw new Error(`Invalid directory: ${validation}`);
|
|
301
|
+
}
|
|
302
|
+
await prompts.log.info(`Using current directory: ${confirmedDirectory}`);
|
|
294
303
|
} else {
|
|
295
304
|
confirmedDirectory = await this.getConfirmedDirectory();
|
|
296
305
|
}
|
|
@@ -1058,10 +1067,10 @@ class UI {
|
|
|
1058
1067
|
const allOptions = [];
|
|
1059
1068
|
const initialValues = [];
|
|
1060
1069
|
|
|
1061
|
-
const buildModuleEntry = async (code, name, description, isDefault, repoUrl = null, registryDefault = null) => {
|
|
1070
|
+
const buildModuleEntry = async (code, name, description, isDefault, repoUrl = null, registryDefault = null, registryPin = null) => {
|
|
1062
1071
|
const isInstalled = installedModuleIds.has(code);
|
|
1063
1072
|
const installedVersion = installedModuleVersions.get(code) || '';
|
|
1064
|
-
const versionState = await getModuleVersion(code, { repoUrl, registryDefault, channelOptions });
|
|
1073
|
+
const versionState = await getModuleVersion(code, { repoUrl, registryDefault, registryPin, channelOptions });
|
|
1065
1074
|
const label = buildModuleLabel(name, versionState.version, installedVersion);
|
|
1066
1075
|
return {
|
|
1067
1076
|
label,
|
|
@@ -1109,6 +1118,7 @@ class UI {
|
|
|
1109
1118
|
mod.defaultSelected,
|
|
1110
1119
|
mod.url || null,
|
|
1111
1120
|
mod.defaultChannel || null,
|
|
1121
|
+
mod.pin || null,
|
|
1112
1122
|
);
|
|
1113
1123
|
if (mod.deprecated && mod.deprecationMessage) {
|
|
1114
1124
|
entry.hint = entry.hint ? `${entry.hint} — ${mod.deprecationMessage}` : mod.deprecationMessage;
|
|
Binary file
|