chore: update imports to Node.js prefix and add error handling improvements

## CHANGES

- Replace require('fs') with require('node:fs')
- Replace require('path') with require('node:path')
- Add debug logging for directory cleanup
- Add roomodes to VSCode dictionary
- Format README workflow guides section
- Improve error handling in installer
- Add fallback error message display
This commit is contained in:
Kayvan Sylvan 2025-06-15 00:00:42 -07:00
parent e753d02a4b
commit 0e07dbd789
4 changed files with 29 additions and 25 deletions

View File

@ -41,6 +41,7 @@
"rescope", "rescope",
"roadmaps", "roadmaps",
"roleplay", "roleplay",
"roomodes",
"runbooks", "runbooks",
"Serilog", "Serilog",
"shadcn", "shadcn",

View File

@ -254,6 +254,7 @@ npm install
## Documentation & Guides ## Documentation & Guides
### Workflow Guides ### Workflow Guides
- 📚 [Universal BMAD Workflow Guide](docs/bmad-workflow-guide.md) - Core workflow that applies to all IDEs - 📚 [Universal BMAD Workflow Guide](docs/bmad-workflow-guide.md) - Core workflow that applies to all IDEs
- 🎯 [Cursor Guide](docs/cursor-guide.md) - Complete workflow for Cursor users - 🎯 [Cursor Guide](docs/cursor-guide.md) - Complete workflow for Cursor users
- 🤖 [Claude Code Guide](docs/claude-code-guide.md) - Complete workflow for Claude Code users - 🤖 [Claude Code Guide](docs/claude-code-guide.md) - Complete workflow for Claude Code users

View File

@ -1,5 +1,5 @@
const fs = require('fs').promises; const fs = require('node:fs').promises;
const path = require('path'); const path = require('node:path');
const DependencyResolver = require('../lib/dependency-resolver'); const DependencyResolver = require('../lib/dependency-resolver');
class WebBuilder { class WebBuilder {
@ -19,6 +19,7 @@ class WebBuilder {
await fs.rm(dir, { recursive: true, force: true }); await fs.rm(dir, { recursive: true, force: true });
console.log(`Cleaned: ${path.relative(this.rootDir, dir)}`); console.log(`Cleaned: ${path.relative(this.rootDir, dir)}`);
} catch (error) { } catch (error) {
console.debug(`Failed to clean directory ${dir}:`, error.message);
// Directory might not exist, that's fine // Directory might not exist, that's fine
} }
} }
@ -26,11 +27,11 @@ class WebBuilder {
async buildAgents() { async buildAgents() {
const agents = await this.resolver.listAgents(); const agents = await this.resolver.listAgents();
for (const agentId of agents) { for (const agentId of agents) {
console.log(` Building agent: ${agentId}`); console.log(` Building agent: ${agentId}`);
const bundle = await this.buildAgentBundle(agentId); const bundle = await this.buildAgentBundle(agentId);
// Write to all output directories // Write to all output directories
for (const outputDir of this.outputDirs) { for (const outputDir of this.outputDirs) {
const outputPath = path.join(outputDir, 'agents'); const outputPath = path.join(outputDir, 'agents');
@ -45,11 +46,11 @@ class WebBuilder {
async buildTeams() { async buildTeams() {
const teams = await this.resolver.listTeams(); const teams = await this.resolver.listTeams();
for (const teamId of teams) { for (const teamId of teams) {
console.log(` Building team: ${teamId}`); console.log(` Building team: ${teamId}`);
const bundle = await this.buildTeamBundle(teamId); const bundle = await this.buildTeamBundle(teamId);
// Write to all output directories // Write to all output directories
for (const outputDir of this.outputDirs) { for (const outputDir of this.outputDirs) {
const outputPath = path.join(outputDir, 'teams'); const outputPath = path.join(outputDir, 'teams');
@ -65,39 +66,39 @@ class WebBuilder {
async buildAgentBundle(agentId) { async buildAgentBundle(agentId) {
const dependencies = await this.resolver.resolveAgentDependencies(agentId); const dependencies = await this.resolver.resolveAgentDependencies(agentId);
const template = await fs.readFile(this.templatePath, 'utf8'); const template = await fs.readFile(this.templatePath, 'utf8');
const sections = [template]; const sections = [template];
// Add agent configuration // Add agent configuration
sections.push(this.formatSection(dependencies.agent.path, dependencies.agent.content)); sections.push(this.formatSection(dependencies.agent.path, dependencies.agent.content));
// Add all dependencies // Add all dependencies
for (const resource of dependencies.resources) { for (const resource of dependencies.resources) {
sections.push(this.formatSection(resource.path, resource.content)); sections.push(this.formatSection(resource.path, resource.content));
} }
return sections.join('\n'); return sections.join('\n');
} }
async buildTeamBundle(teamId) { async buildTeamBundle(teamId) {
const dependencies = await this.resolver.resolveTeamDependencies(teamId); const dependencies = await this.resolver.resolveTeamDependencies(teamId);
const template = await fs.readFile(this.templatePath, 'utf8'); const template = await fs.readFile(this.templatePath, 'utf8');
const sections = [template]; const sections = [template];
// Add team configuration // Add team configuration
sections.push(this.formatSection(dependencies.team.path, dependencies.team.content)); sections.push(this.formatSection(dependencies.team.path, dependencies.team.content));
// Add all agents // Add all agents
for (const agent of dependencies.agents) { for (const agent of dependencies.agents) {
sections.push(this.formatSection(agent.path, agent.content)); sections.push(this.formatSection(agent.path, agent.content));
} }
// Add all deduplicated resources // Add all deduplicated resources
for (const resource of dependencies.resources) { for (const resource of dependencies.resources) {
sections.push(this.formatSection(resource.path, resource.content)); sections.push(this.formatSection(resource.path, resource.content));
} }
return sections.join('\n'); return sections.join('\n');
} }

View File

@ -3,16 +3,17 @@
const { program } = require('commander'); const { program } = require('commander');
const inquirer = require('inquirer'); const inquirer = require('inquirer');
const chalk = require('chalk'); const chalk = require('chalk');
const path = require('path');
// Handle both execution contexts (from root via npx or from installer directory) // Handle both execution contexts (from root via npx or from installer directory)
let version, installer; let version;
let installer;
try { try {
// Try installer context first (when run from tools/installer/) // Try installer context first (when run from tools/installer/)
version = require('../package.json').version; version = require('../package.json').version;
installer = require('../lib/installer'); installer = require('../lib/installer');
} catch (e) { } catch (e) {
// Fall back to root context (when run via npx from GitHub) // Fall back to root context (when run via npx from GitHub)
console.log(chalk.yellow(`Installer context not found (${e.message}), trying root context...`));
try { try {
version = require('../../../package.json').version; version = require('../../../package.json').version;
installer = require('../../../tools/installer/lib/installer'); installer = require('../../../tools/installer/lib/installer');
@ -42,7 +43,7 @@ program
try { try {
if (!options.full && !options.agent) { if (!options.full && !options.agent) {
// Interactive mode // Interactive mode
const answers = await promptInstallation(options); const answers = await promptInstallation();
await installer.install(answers); await installer.install(answers);
} else { } else {
// Direct mode // Direct mode
@ -98,11 +99,11 @@ program
} }
}); });
async function promptInstallation(options) { async function promptInstallation() {
console.log(chalk.bold.blue(`\nWelcome to BMAD Method Installer v${version}\n`)); console.log(chalk.bold.blue(`\nWelcome to BMAD Method Installer v${version}\n`));
const answers = {}; const answers = {};
// Ask for installation directory // Ask for installation directory
const { directory } = await inquirer.prompt([ const { directory } = await inquirer.prompt([
{ {
@ -113,7 +114,7 @@ async function promptInstallation(options) {
} }
]); ]);
answers.directory = directory; answers.directory = directory;
// Ask for installation type // Ask for installation type
const { installType } = await inquirer.prompt([ const { installType } = await inquirer.prompt([
{ {
@ -133,7 +134,7 @@ async function promptInstallation(options) {
} }
]); ]);
answers.installType = installType; answers.installType = installType;
// If single agent, ask which one // If single agent, ask which one
if (installType === 'single-agent') { if (installType === 'single-agent') {
const agents = await installer.getAvailableAgents(); const agents = await installer.getAvailableAgents();
@ -150,7 +151,7 @@ async function promptInstallation(options) {
]); ]);
answers.agent = agent; answers.agent = agent;
} }
// Ask for IDE configuration // Ask for IDE configuration
const { ide } = await inquirer.prompt([ const { ide } = await inquirer.prompt([
{ {
@ -167,7 +168,7 @@ async function promptInstallation(options) {
} }
]); ]);
answers.ide = ide; answers.ide = ide;
return answers; return answers;
} }