bmad-method 6.5.1-next.6 → 6.5.1-next.7
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/package.json
CHANGED
|
@@ -15,8 +15,9 @@ module.exports = {
|
|
|
15
15
|
['--modules <modules>', 'Comma-separated list of module IDs to install (e.g., "bmm,bmb")'],
|
|
16
16
|
[
|
|
17
17
|
'--tools <tools>',
|
|
18
|
-
'Comma-separated list of tool/IDE IDs to configure (e.g., "claude-code,cursor").
|
|
18
|
+
'Comma-separated list of tool/IDE IDs to configure (e.g., "claude-code,cursor"). Required for fresh non-interactive (--yes) installs. Run with --list-tools to see all valid IDs.',
|
|
19
19
|
],
|
|
20
|
+
['--list-tools', 'Print all supported tool/IDE IDs (with target directories) and exit.'],
|
|
20
21
|
['--action <type>', 'Action type for existing installations: install, update, or quick-update'],
|
|
21
22
|
['--user-name <name>', 'Name for agents to use (default: system username)'],
|
|
22
23
|
['--communication-language <lang>', 'Language for agent communication (default: English)'],
|
|
@@ -40,6 +41,12 @@ module.exports = {
|
|
|
40
41
|
],
|
|
41
42
|
action: async (options) => {
|
|
42
43
|
try {
|
|
44
|
+
if (options.listTools) {
|
|
45
|
+
const { formatPlatformList } = require('../ide/platform-codes');
|
|
46
|
+
process.stdout.write((await formatPlatformList()) + '\n');
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
43
50
|
// Set debug flag as environment variable for all components
|
|
44
51
|
if (options.debug) {
|
|
45
52
|
process.env.BMAD_DEBUG_MANIFEST = 'true';
|
|
@@ -81,7 +88,7 @@ module.exports = {
|
|
|
81
88
|
} else {
|
|
82
89
|
await prompts.log.error(`Installation failed: ${error.message}`);
|
|
83
90
|
}
|
|
84
|
-
if (error.stack) {
|
|
91
|
+
if (error.stack && !error.expected) {
|
|
85
92
|
await prompts.log.message(error.stack);
|
|
86
93
|
}
|
|
87
94
|
} catch {
|
|
@@ -31,7 +31,50 @@ function clearCache() {
|
|
|
31
31
|
_cachedPlatformCodes = null;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Format the installable platform list for human-readable output (used by --list-tools).
|
|
36
|
+
* Sourced from IdeManager so this view matches what --tools accepts at install time
|
|
37
|
+
* (suspended platforms excluded).
|
|
38
|
+
* @returns {Promise<string>} Formatted multi-line string with id, name, target_dir, preferred flag.
|
|
39
|
+
*/
|
|
40
|
+
async function formatPlatformList() {
|
|
41
|
+
const { IdeManager } = require('./manager');
|
|
42
|
+
const ideManager = new IdeManager();
|
|
43
|
+
await ideManager.ensureInitialized();
|
|
44
|
+
|
|
45
|
+
const entries = ideManager.getAvailableIdes().map((ide) => {
|
|
46
|
+
const handler = ideManager.handlers.get(ide.value);
|
|
47
|
+
return {
|
|
48
|
+
id: ide.value,
|
|
49
|
+
name: ide.name,
|
|
50
|
+
targetDir: handler?.installerConfig?.target_dir || '',
|
|
51
|
+
preferred: ide.preferred,
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const idWidth = Math.max(...entries.map((e) => e.id.length), 'ID'.length);
|
|
56
|
+
const nameWidth = Math.max(...entries.map((e) => e.name.length), 'Name'.length);
|
|
57
|
+
|
|
58
|
+
const pad = (s, w) => s + ' '.repeat(Math.max(0, w - s.length));
|
|
59
|
+
const lines = [
|
|
60
|
+
`Supported tool IDs (pass via --tools <id>[,<id>...]):`,
|
|
61
|
+
'',
|
|
62
|
+
` ${pad('ID', idWidth)} ${pad('Name', nameWidth)} Target dir`,
|
|
63
|
+
` ${pad('-'.repeat(idWidth), idWidth)} ${pad('-'.repeat(nameWidth), nameWidth)} ${'-'.repeat(10)}`,
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
for (const e of entries) {
|
|
67
|
+
const star = e.preferred ? ' *' : ' ';
|
|
68
|
+
lines.push(`${star}${pad(e.id, idWidth)} ${pad(e.name, nameWidth)} ${e.targetDir}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
lines.push('', '* = recommended / preferred', '', 'Example: bmad-method install --modules bmm --tools claude-code');
|
|
72
|
+
|
|
73
|
+
return lines.join('\n');
|
|
74
|
+
}
|
|
75
|
+
|
|
34
76
|
module.exports = {
|
|
35
77
|
loadPlatformCodes,
|
|
36
78
|
clearCache,
|
|
79
|
+
formatPlatformList,
|
|
37
80
|
};
|
package/tools/installer/ui.js
CHANGED
|
@@ -404,6 +404,37 @@ class UI {
|
|
|
404
404
|
* @param {Object} options - Command-line options
|
|
405
405
|
* @returns {Object} Tool configuration
|
|
406
406
|
*/
|
|
407
|
+
_parseToolsFlag(toolsArg, allKnownValues) {
|
|
408
|
+
const selectedIdes = toolsArg
|
|
409
|
+
.split(',')
|
|
410
|
+
.map((t) => t.trim())
|
|
411
|
+
.filter(Boolean);
|
|
412
|
+
|
|
413
|
+
if (selectedIdes.length === 0) {
|
|
414
|
+
const err = new Error(
|
|
415
|
+
'--tools was passed empty. Provide at least one tool ID (e.g. --tools claude-code) or run with --list-tools to see valid IDs.',
|
|
416
|
+
);
|
|
417
|
+
err.expected = true;
|
|
418
|
+
throw err;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const unknown = selectedIdes.filter((id) => !allKnownValues.has(id));
|
|
422
|
+
if (unknown.length > 0) {
|
|
423
|
+
const err = new Error(
|
|
424
|
+
[
|
|
425
|
+
`Unknown tool ID${unknown.length === 1 ? '' : 's'}: ${unknown.join(', ')}`,
|
|
426
|
+
'',
|
|
427
|
+
'Run with --list-tools to see all valid IDs.',
|
|
428
|
+
'Common: claude-code, cursor, copilot, windsurf, cline',
|
|
429
|
+
].join('\n'),
|
|
430
|
+
);
|
|
431
|
+
err.expected = true;
|
|
432
|
+
throw err;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return selectedIdes;
|
|
436
|
+
}
|
|
437
|
+
|
|
407
438
|
async promptToolSelection(projectDir, options = {}) {
|
|
408
439
|
const { ExistingInstall } = require('./core/existing-install');
|
|
409
440
|
const { Installer } = require('./core/installer');
|
|
@@ -438,15 +469,10 @@ class UI {
|
|
|
438
469
|
const allTools = [...preferredIdes, ...otherIdes];
|
|
439
470
|
|
|
440
471
|
// Non-interactive: handle --tools and --yes flags before interactive prompt
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
const selectedIdes = options.tools
|
|
447
|
-
.split(',')
|
|
448
|
-
.map((t) => t.trim())
|
|
449
|
-
.filter(Boolean);
|
|
472
|
+
// Use !== undefined so an explicit --tools "" falls through to _parseToolsFlag and
|
|
473
|
+
// gets a specific "passed empty" error instead of being silently ignored.
|
|
474
|
+
if (options.tools !== undefined) {
|
|
475
|
+
const selectedIdes = this._parseToolsFlag(options.tools, allKnownValues);
|
|
450
476
|
await prompts.log.info(`Using tools from command-line: ${selectedIdes.join(', ')}`);
|
|
451
477
|
await this.displaySelectedTools(selectedIdes, preferredIdes, allTools);
|
|
452
478
|
return { ides: selectedIdes, skipIde: false };
|
|
@@ -522,21 +548,13 @@ class UI {
|
|
|
522
548
|
|
|
523
549
|
let selectedIdes = [];
|
|
524
550
|
|
|
525
|
-
// Check if tools are provided via command-line
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
selectedIdes = options.tools
|
|
533
|
-
.split(',')
|
|
534
|
-
.map((t) => t.trim())
|
|
535
|
-
.filter(Boolean);
|
|
536
|
-
await prompts.log.info(`Using tools from command-line: ${selectedIdes.join(', ')}`);
|
|
537
|
-
await this.displaySelectedTools(selectedIdes, preferredIdes, allTools);
|
|
538
|
-
return { ides: selectedIdes, skipIde: false };
|
|
539
|
-
}
|
|
551
|
+
// Check if tools are provided via command-line.
|
|
552
|
+
// Use !== undefined so an explicit --tools "" still hits _parseToolsFlag's empty-value error.
|
|
553
|
+
if (options.tools !== undefined) {
|
|
554
|
+
selectedIdes = this._parseToolsFlag(options.tools, allKnownValues);
|
|
555
|
+
await prompts.log.info(`Using tools from command-line: ${selectedIdes.join(', ')}`);
|
|
556
|
+
await this.displaySelectedTools(selectedIdes, preferredIdes, allTools);
|
|
557
|
+
return { ides: selectedIdes, skipIde: false };
|
|
540
558
|
} else if (options.yes) {
|
|
541
559
|
// If --yes flag is set, skip tool prompt and use previously configured tools or empty
|
|
542
560
|
if (configuredIdes.length > 0) {
|
|
@@ -544,8 +562,18 @@ class UI {
|
|
|
544
562
|
await this.displaySelectedTools(configuredIdes, preferredIdes, allTools);
|
|
545
563
|
return { ides: configuredIdes, skipIde: false };
|
|
546
564
|
} else {
|
|
547
|
-
|
|
548
|
-
|
|
565
|
+
const err = new Error(
|
|
566
|
+
[
|
|
567
|
+
'--tools is required for non-interactive install (--yes / -y) when no tools are previously configured.',
|
|
568
|
+
'',
|
|
569
|
+
'Common: claude-code, cursor, copilot, windsurf, cline',
|
|
570
|
+
'See all supported tools: bmad-method install --list-tools',
|
|
571
|
+
'',
|
|
572
|
+
'Example: bmad-method install --modules bmm --tools claude-code -y',
|
|
573
|
+
].join('\n'),
|
|
574
|
+
);
|
|
575
|
+
err.expected = true;
|
|
576
|
+
throw err;
|
|
549
577
|
}
|
|
550
578
|
}
|
|
551
579
|
|