Compare commits
8 Commits
a2b14a53db
...
7e99c36f76
| Author | SHA1 | Date |
|---|---|---|
|
|
7e99c36f76 | |
|
|
1c13305f9f | |
|
|
6198add5bd | |
|
|
6caca55e43 | |
|
|
2c3285f47e | |
|
|
c46453259f | |
|
|
83ed3a978d | |
|
|
3dd05b0584 |
6
.npmrc
6
.npmrc
|
|
@ -1 +1,5 @@
|
||||||
registry=https://registry.npmjs.org
|
# Prevent peer dependency warnings during installation
|
||||||
|
legacy-peer-deps=true
|
||||||
|
|
||||||
|
# Improve install performance
|
||||||
|
prefer-offline=true
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -88,7 +88,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/sitemap": "^3.6.0",
|
"@astrojs/sitemap": "^3.6.0",
|
||||||
"@astrojs/starlight": "^0.37.0",
|
"@astrojs/starlight": "^0.37.5",
|
||||||
"@eslint/js": "^9.33.0",
|
"@eslint/js": "^9.33.0",
|
||||||
"archiver": "^7.0.1",
|
"archiver": "^7.0.1",
|
||||||
"astro": "^5.16.0",
|
"astro": "^5.16.0",
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,10 @@ const ui = new UI();
|
||||||
module.exports = {
|
module.exports = {
|
||||||
command: 'install',
|
command: 'install',
|
||||||
description: 'Install BMAD Core agents and tools',
|
description: 'Install BMAD Core agents and tools',
|
||||||
options: [['-d, --debug', 'Enable debug output for manifest generation']],
|
options: [
|
||||||
|
['-d, --debug', 'Enable debug output for manifest generation'],
|
||||||
|
['-D, --directory <path>', 'Target project directory (skips interactive prompt)'],
|
||||||
|
],
|
||||||
action: async (options) => {
|
action: async (options) => {
|
||||||
try {
|
try {
|
||||||
// Set debug flag as environment variable for all components
|
// Set debug flag as environment variable for all components
|
||||||
|
|
@ -18,7 +21,7 @@ module.exports = {
|
||||||
console.log(chalk.cyan('Debug mode enabled\n'));
|
console.log(chalk.cyan('Debug mode enabled\n'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = await ui.promptInstall();
|
const config = await ui.promptInstall(options);
|
||||||
|
|
||||||
// Handle cancel
|
// Handle cancel
|
||||||
if (config.actionType === 'cancel') {
|
if (config.actionType === 'cancel') {
|
||||||
|
|
|
||||||
|
|
@ -416,7 +416,7 @@ class ModuleManager {
|
||||||
if (needsDependencyInstall || wasNewClone || nodeModulesMissing) {
|
if (needsDependencyInstall || wasNewClone || nodeModulesMissing) {
|
||||||
const installSpinner = ora(`Installing dependencies for ${moduleInfo.name}...`).start();
|
const installSpinner = ora(`Installing dependencies for ${moduleInfo.name}...`).start();
|
||||||
try {
|
try {
|
||||||
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress', {
|
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress --legacy-peer-deps', {
|
||||||
cwd: moduleCacheDir,
|
cwd: moduleCacheDir,
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
timeout: 120_000, // 2 minute timeout
|
timeout: 120_000, // 2 minute timeout
|
||||||
|
|
@ -441,7 +441,7 @@ class ModuleManager {
|
||||||
if (packageJsonNewer) {
|
if (packageJsonNewer) {
|
||||||
const installSpinner = ora(`Installing dependencies for ${moduleInfo.name}...`).start();
|
const installSpinner = ora(`Installing dependencies for ${moduleInfo.name}...`).start();
|
||||||
try {
|
try {
|
||||||
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress', {
|
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress --legacy-peer-deps', {
|
||||||
cwd: moduleCacheDir,
|
cwd: moduleCacheDir,
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
timeout: 120_000, // 2 minute timeout
|
timeout: 120_000, // 2 minute timeout
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,10 @@ const choiceUtils = { Separator };
|
||||||
class UI {
|
class UI {
|
||||||
/**
|
/**
|
||||||
* Prompt for installation configuration
|
* Prompt for installation configuration
|
||||||
|
* @param {Object} options - CLI options object (may contain directory property)
|
||||||
* @returns {Object} Installation configuration
|
* @returns {Object} Installation configuration
|
||||||
*/
|
*/
|
||||||
async promptInstall() {
|
async promptInstall(options = {}) {
|
||||||
CLIUtils.displayLogo();
|
CLIUtils.displayLogo();
|
||||||
|
|
||||||
// Display version-specific start message from install-messages.yaml
|
// Display version-specific start message from install-messages.yaml
|
||||||
|
|
@ -36,7 +37,7 @@ class UI {
|
||||||
const messageLoader = new MessageLoader();
|
const messageLoader = new MessageLoader();
|
||||||
messageLoader.displayStartMessage();
|
messageLoader.displayStartMessage();
|
||||||
|
|
||||||
const confirmedDirectory = await this.getConfirmedDirectory();
|
const confirmedDirectory = await this.getConfirmedDirectory(options);
|
||||||
|
|
||||||
// Preflight: Check for legacy BMAD v4 footprints immediately after getting directory
|
// Preflight: Check for legacy BMAD v4 footprints immediately after getting directory
|
||||||
const { Detector } = require('../installers/lib/core/detector');
|
const { Detector } = require('../installers/lib/core/detector');
|
||||||
|
|
@ -506,9 +507,23 @@ class UI {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get confirmed directory from user
|
* Get confirmed directory from user
|
||||||
|
* @param {Object} options - CLI options object (may contain directory property)
|
||||||
* @returns {string} Confirmed directory path
|
* @returns {string} Confirmed directory path
|
||||||
*/
|
*/
|
||||||
async getConfirmedDirectory() {
|
async getConfirmedDirectory(options = {}) {
|
||||||
|
// If directory provided via CLI, validate and return it
|
||||||
|
if (options.directory) {
|
||||||
|
const expandedPath = this.expandUserPath(options.directory);
|
||||||
|
const validationError = this.validateDirectorySync(expandedPath);
|
||||||
|
if (validationError) {
|
||||||
|
throw new Error(`Invalid directory: ${validationError}`);
|
||||||
|
}
|
||||||
|
await this.displayDirectoryInfo(expandedPath);
|
||||||
|
// Skip confirmation for CLI-provided directories
|
||||||
|
return expandedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing interactive prompt logic
|
||||||
let confirmedDirectory = null;
|
let confirmedDirectory = null;
|
||||||
while (!confirmedDirectory) {
|
while (!confirmedDirectory) {
|
||||||
const directoryAnswer = await this.promptForDirectory();
|
const directoryAnswer = await this.promptForDirectory();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue