bmad-method 6.5.1-next.6 → 6.5.1-next.8

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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "bmad-method",
4
- "version": "6.5.1-next.6",
4
+ "version": "6.5.1-next.8",
5
5
  "description": "Breakthrough Method of Agile AI-driven Development",
6
6
  "keywords": [
7
7
  "agile",
@@ -227,37 +227,39 @@ Prepare the content to append to the document:
227
227
 
228
228
  ### Architecture Completeness Checklist
229
229
 
230
- **✅ Requirements Analysis**
230
+ Mark each item `[x]` only if validation confirms it; leave `[ ]` if it is missing, partial, or unverified. Any unchecked item must be reflected in the Gap Analysis above and in the Overall Status below.
231
231
 
232
- - [x] Project context thoroughly analyzed
233
- - [x] Scale and complexity assessed
234
- - [x] Technical constraints identified
235
- - [x] Cross-cutting concerns mapped
232
+ **Requirements Analysis**
236
233
 
237
- **✅ Architectural Decisions**
234
+ - [ ] Project context thoroughly analyzed
235
+ - [ ] Scale and complexity assessed
236
+ - [ ] Technical constraints identified
237
+ - [ ] Cross-cutting concerns mapped
238
238
 
239
- - [x] Critical decisions documented with versions
240
- - [x] Technology stack fully specified
241
- - [x] Integration patterns defined
242
- - [x] Performance considerations addressed
239
+ **Architectural Decisions**
243
240
 
244
- **✅ Implementation Patterns**
241
+ - [ ] Critical decisions documented with versions
242
+ - [ ] Technology stack fully specified
243
+ - [ ] Integration patterns defined
244
+ - [ ] Performance considerations addressed
245
245
 
246
- - [x] Naming conventions established
247
- - [x] Structure patterns defined
248
- - [x] Communication patterns specified
249
- - [x] Process patterns documented
246
+ **Implementation Patterns**
250
247
 
251
- **✅ Project Structure**
248
+ - [ ] Naming conventions established
249
+ - [ ] Structure patterns defined
250
+ - [ ] Communication patterns specified
251
+ - [ ] Process patterns documented
252
252
 
253
- - [x] Complete directory structure defined
254
- - [x] Component boundaries established
255
- - [x] Integration points mapped
256
- - [x] Requirements to structure mapping complete
253
+ **Project Structure**
254
+
255
+ - [ ] Complete directory structure defined
256
+ - [ ] Component boundaries established
257
+ - [ ] Integration points mapped
258
+ - [ ] Requirements to structure mapping complete
257
259
 
258
260
  ### Architecture Readiness Assessment
259
261
 
260
- **Overall Status:** READY FOR IMPLEMENTATION
262
+ **Overall Status:** {{READY FOR IMPLEMENTATION | READY WITH MINOR GAPS | NOT READY}} (choose READY FOR IMPLEMENTATION only when all 16 checklist items are `[x]` and no Critical Gaps remain; choose NOT READY when any Critical Gap is open or any Requirements Analysis or Architectural Decisions item is unchecked; otherwise READY WITH MINOR GAPS)
261
263
 
262
264
  **Confidence Level:** {{high/medium/low}} based on validation results
263
265
 
@@ -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"). Use "none" to skip tool configuration.',
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
  };
@@ -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
- if (options.tools) {
442
- if (options.tools.toLowerCase() === 'none') {
443
- await prompts.log.info('Skipping tool configuration (--tools none)');
444
- return { ides: [], skipIde: true };
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
- if (options.tools) {
527
- // Check for explicit "none" value to skip tool installation
528
- if (options.tools.toLowerCase() === 'none') {
529
- await prompts.log.info('Skipping tool configuration (--tools none)');
530
- return { ides: [], skipIde: true };
531
- } else {
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
- await prompts.log.info('Skipping tool configuration (--yes flag, no previous tools)');
548
- return { ides: [], skipIde: true };
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