Files
BMAD-METHOD/tools/cli/bmad-cli.js
Davor Racic 5cb5606ba3 fix(cli): replace inquirer with @clack/prompts for Windows compatibility (#1316)
* fix(cli): replace inquirer with @clack/prompts for Windows compatibility

- Add new prompts.js wrapper around @clack/prompts to fix Windows arrow
  key navigation issues (libuv #852)
- Fix validation logic in github-copilot.js that always returned true
- Add support for primitive choice values (string/number) in select/multiselect
- Add 'when' property support for conditional questions in prompt()
- Update all IDE installers to use new prompts module

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(cli): address code review feedback for prompts migration

- Move @clack/prompts from devDependencies to dependencies (critical)
- Remove unused inquirer dependency
- Fix potential crash in multiselect when initialValues is undefined
- Add async validator detection with explicit error message
- Extract validateCustomContentPathSync method in ui.js
- Extract promptInstallLocation methods in claude-code.js and antigravity.js
- Fix moduleId -> missing.id in installer.js remove flow
- Update multiselect to support native clack API (options/initialValues)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: update comments to reference @clack/prompts instead of inquirer

- Update bmad-cli.js comment about CLI prompts
- Update config-collector.js JSDoc comments
- Rename inquirer variable to choiceUtils in ui.js
- Update JSDoc returns and calls documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(cli): add spacing between prompts and installation progress

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(cli): add multiselect usage hints for inexperienced users

Add inline navigation hints to all multiselect prompts showing
(↑/↓ navigate, SPACE select, ENTER confirm) to help users
unfamiliar with terminal multiselect controls.

Also restore detailed warning when no tools are selected,
explaining that SPACE must be pressed to select items.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(cli): restore IDE grouping using groupMultiselect

Replace flat multiselect with native @clack/prompts groupMultiselect
component to restore visual grouping of IDE/tool options:
- "Previously Configured" - pre-selected IDEs from existing install
- "Recommended Tools" - starred preferred options
- "Additional Tools" - other available options

This restores the grouped UX that was lost during the Inquirer.js
to @clack/prompts migration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 16:25:35 -06:00

59 lines
1.7 KiB
JavaScript
Executable File

const { program } = require('commander');
const path = require('node:path');
const fs = require('node:fs');
// Fix for stdin issues when running through npm on Windows
// Ensures keyboard interaction works properly with CLI prompts
if (process.stdin.isTTY) {
try {
process.stdin.resume();
process.stdin.setEncoding('utf8');
// On Windows, explicitly reference the stdin stream to ensure it's properly initialized
if (process.platform === 'win32') {
process.stdin.on('error', () => {
// Ignore stdin errors - they can occur when the terminal is closing
});
}
} catch {
// Silently ignore - some environments may not support these operations
}
}
// Load package.json from root for version info
const packageJson = require('../../package.json');
// Load all command modules
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith('.js'));
const commands = {};
for (const file of commandFiles) {
const command = require(path.join(commandsPath, file));
commands[command.command] = command;
}
// Set up main program
program.version(packageJson.version).description('BMAD Core CLI - Universal AI agent framework');
// Register all commands
for (const [name, cmd] of Object.entries(commands)) {
const command = program.command(name).description(cmd.description);
// Add options
for (const option of cmd.options || []) {
command.option(...option);
}
// Set action
command.action(cmd.action);
}
// Parse arguments
program.parse(process.argv);
// Show help if no command provided
if (process.argv.slice(2).length === 0) {
program.outputHelp();
}