refactor: rename dist directory to bundles for clarity

Update all references to the 'dist' directory to use 'bundles' instead to better reflect the purpose of the directory containing bundled agent files. This change affects documentation, configuration files, and the web builder script.
This commit is contained in:
manjaroblack 2025-07-22 12:47:37 -05:00
parent bfaaa0ee11
commit 01f888d0dd
No known key found for this signature in database
GPG Key ID: 02FD4111DA5560B4
9 changed files with 1148 additions and 1049 deletions

View File

@ -92,7 +92,7 @@ This single command handles:
### Fastest Start: Web UI Full Stack Team at your disposal (2 minutes) ### Fastest Start: Web UI Full Stack Team at your disposal (2 minutes)
1. **Get the bundle**: Save or clone the [full stack team file](dist/teams/team-fullstack.txt) or choose another team 1. **Get the bundle**: Save or clone the [full stack team file](bundles/teams/team-fullstack.txt) or choose another team
2. **Create AI agent**: Create a new Gemini Gem or CustomGPT 2. **Create AI agent**: Create a new Gemini Gem or CustomGPT
3. **Upload & configure**: Upload the file and set instructions: "Your critical operating instructions are attached, do not break character as directed" 3. **Upload & configure**: Upload the file and set instructions: "Your critical operating instructions are attached, do not break character as directed"
4. **Start Ideating and Planning**: Start chatting! Type `*help` to see available commands or pick an agent like `*analyst` to start right in on creating a brief. 4. **Start Ideating and Planning**: Start chatting! Type `*help` to see available commands or pick an agent like `*analyst` to start right in on creating a brief.

View File

@ -74,7 +74,7 @@ BMad transforms you into a "Vibe CEO" - directing a team of specialized AI agent
**Best for**: ChatGPT, Claude, Gemini users who want to start immediately **Best for**: ChatGPT, Claude, Gemini users who want to start immediately
1. Navigate to `dist/teams/` 1. Navigate to `bundles/teams/`
2. Copy `team-fullstack.txt` content 2. Copy `team-fullstack.txt` content
3. Create new Gemini Gem or CustomGPT 3. Create new Gemini Gem or CustomGPT
4. Upload file with instructions: "Your critical operating instructions are attached, do not break character as directed" 4. Upload file with instructions: "Your critical operating instructions are attached, do not break character as directed"
@ -394,8 +394,8 @@ The BMad-Method is built around a modular architecture centered on the `bmad-cor
#### Web UI Environment #### Web UI Environment
- Uses pre-built bundles from `dist/teams` for stand alone 1 upload files for all agents and their assets with an orchestrating agent - Uses pre-built bundles from `bundles/teams` for stand alone 1 upload files for all agents and their assets with an orchestrating agent
- Single text files containing all agent dependencies are in `dist/agents/` - these are unnecessary unless you want to create a web agent that is only a single agent and not a team - Single text files containing all agent dependencies are in `bundles/agents/` - these are unnecessary unless you want to create a web agent that is only a single agent and not a team
- Created by the web-builder tool for upload to web interfaces - Created by the web-builder tool for upload to web interfaces
- Provides complete context in one package - Provides complete context in one package
@ -542,7 +542,7 @@ Each status change requires user verification and approval before proceeding.
#### Greenfield Development #### Greenfield Development
- Business analysis and market research - Business analysis and market research
- Product requirements and feature definition - Product requirements and feature definition
- System architecture and design - System architecture and design
- Development execution - Development execution
- Testing and deployment - Testing and deployment
@ -651,7 +651,7 @@ Templates with Level 2 headings (`##`) can be automatically sharded:
```markdown ```markdown
## Goals and Background Context ## Goals and Background Context
## Requirements ## Requirements
## User Interface Design Goals ## User Interface Design Goals
## Success Metrics ## Success Metrics
``` ```

View File

@ -131,7 +131,7 @@ graph TD
If you want to do the planning in the Web with Claude (Sonnet 4 or Opus), Gemini Gem (2.5 Pro), or Custom GPT's: If you want to do the planning in the Web with Claude (Sonnet 4 or Opus), Gemini Gem (2.5 Pro), or Custom GPT's:
1. Navigate to `dist/teams/` 1. Navigate to `bundles/teams/`
2. Copy `team-fullstack.txt` content 2. Copy `team-fullstack.txt` content
3. Create new Gemini Gem or CustomGPT 3. Create new Gemini Gem or CustomGPT
4. Upload file with instructions: "Your critical operating instructions are attached, do not break character as directed" 4. Upload file with instructions: "Your critical operating instructions are attached, do not break character as directed"

View File

@ -106,7 +106,7 @@ For example, if you say "Add payment processing to user service":
- **Option A**: Paste your GitHub repository URL directly - **Option A**: Paste your GitHub repository URL directly
- **Option B**: Upload up to 1000 files from your src/project folder - **Option B**: Upload up to 1000 files from your src/project folder
- **Option C**: Zip your project and upload the archive - **Option C**: Zip your project and upload the archive
3. **Load the analyst agent**: Upload `dist/agents/analyst.txt` 3. **Load the analyst agent**: Upload `bundles/agents/analyst.txt`
4. **Run documentation**: Type `*document-project` 4. **Run documentation**: Type `*document-project`
The analyst will generate comprehensive documentation of everything. The analyst will generate comprehensive documentation of everything.

View File

@ -33,7 +33,7 @@ graph TD
end end
subgraph Outputs subgraph Outputs
J["dist"] J["bundles"]
end end
B -- defines dependencies for --> E B -- defines dependencies for --> E
@ -133,17 +133,17 @@ The framework is designed for two primary environments: local IDEs and web-based
### 4.1. Web Builder (`tools/builders/web-builder.js`) ### 4.1. Web Builder (`tools/builders/web-builder.js`)
- **Purpose**: This Node.js script is responsible for creating the `.txt` bundles found in `dist`. - **Purpose**: This Node.js script is responsible for creating the `.txt` bundles found in `bundles`.
- **Process**: - **Process**:
1. **Resolves Dependencies**: For a given agent or team, the script reads its definition file. 1. **Resolves Dependencies**: For a given agent or team, the script reads its definition file.
2. It recursively finds all dependent resources (tasks, templates, etc.) that the agent/team needs. 2. It recursively finds all dependent resources (tasks, templates, etc.) that the agent/team needs.
3. **Bundles Content**: It reads the content of all these files and concatenates them into a single, large text file, with clear separators indicating the original file path of each section. 3. **Bundles Content**: It reads the content of all these files and concatenates them into a single, large text file, with clear separators indicating the original file path of each section.
4. **Outputs Bundle**: The final `.txt` file is saved in the `dist` directory, ready to be uploaded to a web UI. 4. **Outputs Bundle**: The final `.txt` file is saved in the `bundles` directory, ready to be uploaded to a web UI.
### 4.2. Environment-Specific Usage ### 4.2. Environment-Specific Usage
- **For IDEs**: Users interact with the agents directly via their markdown files in `bmad-core/agents/`. The IDE integration (for Cursor, Claude Code, etc.) knows how to call these agents. - **For IDEs**: Users interact with the agents directly via their markdown files in `bmad-core/agents/`. The IDE integration (for Cursor, Claude Code, etc.) knows how to call these agents.
- **For Web UIs**: Users upload a pre-built bundle from `dist`. This single file provides the AI with the context of the entire team and all their required tools and knowledge. - **For Web UIs**: Users upload a pre-built bundle from `bundles`. This single file provides the AI with the context of the entire team and all their required tools and knowledge.
## 5. BMad Workflows ## 5. BMad Workflows

View File

@ -14,7 +14,7 @@ sections:
- id: initial-setup - id: initial-setup
instruction: | instruction: |
This template creates a comprehensive game architecture document specifically for Phaser 3 + TypeScript projects. This should provide the technical foundation for all game development stories and epics. This template creates a comprehensive game architecture document specifically for Phaser 3 + TypeScript projects. This should provide the technical foundation for all game development stories and epics.
If available, review any provided documents: Game Design Document (GDD), Technical Preferences. This architecture should support all game mechanics defined in the GDD. If available, review any provided documents: Game Design Document (GDD), Technical Preferences. This architecture should support all game mechanics defined in the GDD.
- id: introduction - id: introduction
@ -22,7 +22,7 @@ sections:
instruction: Establish the document's purpose and scope for game development instruction: Establish the document's purpose and scope for game development
content: | content: |
This document outlines the complete technical architecture for {{game_title}}, a 2D game built with Phaser 3 and TypeScript. It serves as the technical foundation for AI-driven game development, ensuring consistency and scalability across all game systems. This document outlines the complete technical architecture for {{game_title}}, a 2D game built with Phaser 3 and TypeScript. It serves as the technical foundation for AI-driven game development, ensuring consistency and scalability across all game systems.
This architecture is designed to support the gameplay mechanics defined in the Game Design Document while maintaining 60 FPS performance and cross-platform compatibility. This architecture is designed to support the gameplay mechanics defined in the Game Design Document while maintaining 60 FPS performance and cross-platform compatibility.
sections: sections:
- id: change-log - id: change-log
@ -41,7 +41,7 @@ sections:
title: Architecture Summary title: Architecture Summary
instruction: | instruction: |
Provide a comprehensive overview covering: Provide a comprehensive overview covering:
- Game engine choice and configuration - Game engine choice and configuration
- Project structure and organization - Project structure and organization
- Key systems and their interactions - Key systems and their interactions
@ -94,7 +94,7 @@ sections:
├── docs/ # Documentation ├── docs/ # Documentation
│ ├── stories/ # Development stories │ ├── stories/ # Development stories
│ └── architecture/ # Technical docs │ └── architecture/ # Technical docs
└── dist/ # Built game files └── bundles/ # Built game files
- id: module-organization - id: module-organization
title: Module Organization title: Module Organization
instruction: Define how TypeScript modules should be organized instruction: Define how TypeScript modules should be organized
@ -129,23 +129,23 @@ sections:
title: Scene Management System title: Scene Management System
template: | template: |
**Purpose:** Handle game flow and scene transitions **Purpose:** Handle game flow and scene transitions
**Key Components:** **Key Components:**
- Scene loading and unloading - Scene loading and unloading
- Data passing between scenes - Data passing between scenes
- Transition effects - Transition effects
- Memory management - Memory management
**Implementation Requirements:** **Implementation Requirements:**
- Preload scene for asset loading - Preload scene for asset loading
- Menu system with navigation - Menu system with navigation
- Gameplay scenes with state management - Gameplay scenes with state management
- Pause/resume functionality - Pause/resume functionality
**Files to Create:** **Files to Create:**
- `src/scenes/BootScene.ts` - `src/scenes/BootScene.ts`
- `src/scenes/PreloadScene.ts` - `src/scenes/PreloadScene.ts`
- `src/scenes/MenuScene.ts` - `src/scenes/MenuScene.ts`
@ -155,23 +155,23 @@ sections:
title: Game State Management title: Game State Management
template: | template: |
**Purpose:** Track player progress and game status **Purpose:** Track player progress and game status
**State Categories:** **State Categories:**
- Player progress (levels, unlocks) - Player progress (levels, unlocks)
- Game settings (audio, controls) - Game settings (audio, controls)
- Session data (current level, score) - Session data (current level, score)
- Persistent data (achievements, statistics) - Persistent data (achievements, statistics)
**Implementation Requirements:** **Implementation Requirements:**
- Save/load system with localStorage - Save/load system with localStorage
- State validation and error recovery - State validation and error recovery
- Cross-session data persistence - Cross-session data persistence
- Settings management - Settings management
**Files to Create:** **Files to Create:**
- `src/systems/GameState.ts` - `src/systems/GameState.ts`
- `src/systems/SaveManager.ts` - `src/systems/SaveManager.ts`
- `src/types/GameData.ts` - `src/types/GameData.ts`
@ -179,23 +179,23 @@ sections:
title: Asset Management System title: Asset Management System
template: | template: |
**Purpose:** Efficient loading and management of game assets **Purpose:** Efficient loading and management of game assets
**Asset Categories:** **Asset Categories:**
- Sprite sheets and animations - Sprite sheets and animations
- Audio files and music - Audio files and music
- Level data and configurations - Level data and configurations
- UI assets and fonts - UI assets and fonts
**Implementation Requirements:** **Implementation Requirements:**
- Progressive loading strategy - Progressive loading strategy
- Asset caching and optimization - Asset caching and optimization
- Error handling for failed loads - Error handling for failed loads
- Memory management for large assets - Memory management for large assets
**Files to Create:** **Files to Create:**
- `src/systems/AssetManager.ts` - `src/systems/AssetManager.ts`
- `src/config/AssetConfig.ts` - `src/config/AssetConfig.ts`
- `src/utils/AssetLoader.ts` - `src/utils/AssetLoader.ts`
@ -203,23 +203,23 @@ sections:
title: Input Management System title: Input Management System
template: | template: |
**Purpose:** Handle all player input across platforms **Purpose:** Handle all player input across platforms
**Input Types:** **Input Types:**
- Keyboard controls - Keyboard controls
- Mouse/pointer interaction - Mouse/pointer interaction
- Touch gestures (mobile) - Touch gestures (mobile)
- Gamepad support (optional) - Gamepad support (optional)
**Implementation Requirements:** **Implementation Requirements:**
- Input mapping and configuration - Input mapping and configuration
- Touch-friendly mobile controls - Touch-friendly mobile controls
- Input buffering for responsive gameplay - Input buffering for responsive gameplay
- Customizable control schemes - Customizable control schemes
**Files to Create:** **Files to Create:**
- `src/systems/InputManager.ts` - `src/systems/InputManager.ts`
- `src/utils/TouchControls.ts` - `src/utils/TouchControls.ts`
- `src/types/InputTypes.ts` - `src/types/InputTypes.ts`
@ -232,19 +232,19 @@ sections:
title: "{{mechanic_name}} System" title: "{{mechanic_name}} System"
template: | template: |
**Purpose:** {{system_purpose}} **Purpose:** {{system_purpose}}
**Core Functionality:** **Core Functionality:**
- {{feature_1}} - {{feature_1}}
- {{feature_2}} - {{feature_2}}
- {{feature_3}} - {{feature_3}}
**Dependencies:** {{required_systems}} **Dependencies:** {{required_systems}}
**Performance Considerations:** {{optimization_notes}} **Performance Considerations:** {{optimization_notes}}
**Files to Create:** **Files to Create:**
- `src/systems/{{system_name}}.ts` - `src/systems/{{system_name}}.ts`
- `src/gameObjects/{{related_object}}.ts` - `src/gameObjects/{{related_object}}.ts`
- `src/types/{{system_types}}.ts` - `src/types/{{system_types}}.ts`
@ -252,65 +252,65 @@ sections:
title: Physics & Collision System title: Physics & Collision System
template: | template: |
**Physics Engine:** {{physics_choice}} (Arcade Physics/Matter.js) **Physics Engine:** {{physics_choice}} (Arcade Physics/Matter.js)
**Collision Categories:** **Collision Categories:**
- Player collision - Player collision
- Enemy interactions - Enemy interactions
- Environmental objects - Environmental objects
- Collectibles and items - Collectibles and items
**Implementation Requirements:** **Implementation Requirements:**
- Optimized collision detection - Optimized collision detection
- Physics body management - Physics body management
- Collision callbacks and events - Collision callbacks and events
- Performance monitoring - Performance monitoring
**Files to Create:** **Files to Create:**
- `src/systems/PhysicsManager.ts` - `src/systems/PhysicsManager.ts`
- `src/utils/CollisionGroups.ts` - `src/utils/CollisionGroups.ts`
- id: audio-system - id: audio-system
title: Audio System title: Audio System
template: | template: |
**Audio Requirements:** **Audio Requirements:**
- Background music with looping - Background music with looping
- Sound effects for actions - Sound effects for actions
- Audio settings and volume control - Audio settings and volume control
- Mobile audio optimization - Mobile audio optimization
**Implementation Features:** **Implementation Features:**
- Audio sprite management - Audio sprite management
- Dynamic music system - Dynamic music system
- Spatial audio (if applicable) - Spatial audio (if applicable)
- Audio pooling for performance - Audio pooling for performance
**Files to Create:** **Files to Create:**
- `src/systems/AudioManager.ts` - `src/systems/AudioManager.ts`
- `src/config/AudioConfig.ts` - `src/config/AudioConfig.ts`
- id: ui-system - id: ui-system
title: UI System title: UI System
template: | template: |
**UI Components:** **UI Components:**
- HUD elements (score, health, etc.) - HUD elements (score, health, etc.)
- Menu navigation - Menu navigation
- Modal dialogs - Modal dialogs
- Settings screens - Settings screens
**Implementation Requirements:** **Implementation Requirements:**
- Responsive layout system - Responsive layout system
- Touch-friendly interface - Touch-friendly interface
- Keyboard navigation support - Keyboard navigation support
- Animation and transitions - Animation and transitions
**Files to Create:** **Files to Create:**
- `src/systems/UIManager.ts` - `src/systems/UIManager.ts`
- `src/gameObjects/UI/` - `src/gameObjects/UI/`
- `src/types/UITypes.ts` - `src/types/UITypes.ts`
@ -610,4 +610,4 @@ sections:
- 90%+ test coverage on game logic - 90%+ test coverage on game logic
- Zero TypeScript errors in strict mode - Zero TypeScript errors in strict mode
- Consistent adherence to coding standards - Consistent adherence to coding standards
- Comprehensive documentation coverage - Comprehensive documentation coverage

View File

@ -6,7 +6,7 @@ const yamlUtils = require("../lib/yaml-utils");
class WebBuilder { class WebBuilder {
constructor(options = {}) { constructor(options = {}) {
this.rootDir = options.rootDir || process.cwd(); this.rootDir = options.rootDir || process.cwd();
this.outputDirs = options.outputDirs || [path.join(this.rootDir, "dist")]; this.outputDirs = options.outputDirs || [path.join(this.rootDir, "bundles")];
this.resolver = new DependencyResolver(this.rootDir); this.resolver = new DependencyResolver(this.rootDir);
this.templatePath = path.join( this.templatePath = path.join(
this.rootDir, this.rootDir,
@ -26,7 +26,7 @@ class WebBuilder {
// All resources get installed under the bundle root, so use that path // All resources get installed under the bundle root, so use that path
const relativePath = path.relative(this.rootDir, filePath); const relativePath = path.relative(this.rootDir, filePath);
const pathParts = relativePath.split(path.sep); const pathParts = relativePath.split(path.sep);
let resourcePath; let resourcePath;
if (pathParts[0] === 'expansion-packs') { if (pathParts[0] === 'expansion-packs') {
// For expansion packs, remove 'expansion-packs/packname' and use the rest // For expansion packs, remove 'expansion-packs/packname' and use the rest
@ -35,7 +35,7 @@ class WebBuilder {
// For bmad-core, common, etc., remove the first part // For bmad-core, common, etc., remove the first part
resourcePath = pathParts.slice(1).join('/'); resourcePath = pathParts.slice(1).join('/');
} }
return `.${bundleRoot}/${resourcePath}`; return `.${bundleRoot}/${resourcePath}`;
} }
@ -192,7 +192,7 @@ These references map directly to bundle sections:
const yamlMatch = content.match(/```ya?ml\n([\s\S]*?)\n```/); const yamlMatch = content.match(/```ya?ml\n([\s\S]*?)\n```/);
if (!yamlMatch) return content; if (!yamlMatch) return content;
const yamlStartIndex = content.indexOf(yamlMatch[0]); const yamlStartIndex = content.indexOf(yamlMatch[0]);
const yamlEndIndex = yamlStartIndex + yamlMatch[0].length; const yamlEndIndex = yamlStartIndex + yamlMatch[0].length;
@ -300,7 +300,7 @@ These references map directly to bundle sections:
async buildExpansionPack(packName, options = {}) { async buildExpansionPack(packName, options = {}) {
const packDir = path.join(this.rootDir, "expansion-packs", packName); const packDir = path.join(this.rootDir, "expansion-packs", packName);
const outputDirs = [path.join(this.rootDir, "dist", "expansion-packs", packName)]; const outputDirs = [path.join(this.rootDir, "bundles", "expansion-packs", packName)];
// Clean output directories if requested // Clean output directories if requested
if (options.clean !== false) { if (options.clean !== false) {

View File

@ -11,7 +11,7 @@ class ConfigLoader {
async load() { async load() {
if (this.config) return this.config; if (this.config) return this.config;
try { try {
const configContent = await fs.readFile(this.configPath, 'utf8'); const configContent = await fs.readFile(this.configPath, 'utf8');
this.config = yaml.load(configContent); this.config = yaml.load(configContent);
@ -28,25 +28,25 @@ class ConfigLoader {
async getAvailableAgents() { async getAvailableAgents() {
const agentsDir = path.join(this.getBmadCorePath(), 'agents'); const agentsDir = path.join(this.getBmadCorePath(), 'agents');
try { try {
const entries = await fs.readdir(agentsDir, { withFileTypes: true }); const entries = await fs.readdir(agentsDir, { withFileTypes: true });
const agents = []; const agents = [];
for (const entry of entries) { for (const entry of entries) {
if (entry.isFile() && entry.name.endsWith('.md')) { if (entry.isFile() && entry.name.endsWith('.md')) {
const agentPath = path.join(agentsDir, entry.name); const agentPath = path.join(agentsDir, entry.name);
const agentId = path.basename(entry.name, '.md'); const agentId = path.basename(entry.name, '.md');
try { try {
const agentContent = await fs.readFile(agentPath, 'utf8'); const agentContent = await fs.readFile(agentPath, 'utf8');
// Extract YAML block from agent file // Extract YAML block from agent file
const yamlContentText = extractYamlFromAgent(agentContent); const yamlContentText = extractYamlFromAgent(agentContent);
if (yamlContentText) { if (yamlContentText) {
const yamlContent = yaml.load(yamlContentText); const yamlContent = yaml.load(yamlContentText);
const agentConfig = yamlContent.agent || {}; const agentConfig = yamlContent.agent || {};
agents.push({ agents.push({
id: agentId, id: agentId,
name: agentConfig.title || agentConfig.name || agentId, name: agentConfig.title || agentConfig.name || agentId,
@ -59,10 +59,10 @@ class ConfigLoader {
} }
} }
} }
// Sort agents by name for consistent display // Sort agents by name for consistent display
agents.sort((a, b) => a.name.localeCompare(b.name)); agents.sort((a, b) => a.name.localeCompare(b.name));
return agents; return agents;
} catch (error) { } catch (error) {
console.warn(`Failed to read agents directory: ${error.message}`); console.warn(`Failed to read agents directory: ${error.message}`);
@ -72,21 +72,21 @@ class ConfigLoader {
async getAvailableExpansionPacks() { async getAvailableExpansionPacks() {
const expansionPacksDir = path.join(this.getBmadCorePath(), '..', 'expansion-packs'); const expansionPacksDir = path.join(this.getBmadCorePath(), '..', 'expansion-packs');
try { try {
const entries = await fs.readdir(expansionPacksDir, { withFileTypes: true }); const entries = await fs.readdir(expansionPacksDir, { withFileTypes: true });
const expansionPacks = []; const expansionPacks = [];
for (const entry of entries) { for (const entry of entries) {
if (entry.isDirectory() && !entry.name.startsWith('.')) { if (entry.isDirectory() && !entry.name.startsWith('.')) {
const packPath = path.join(expansionPacksDir, entry.name); const packPath = path.join(expansionPacksDir, entry.name);
const configPath = path.join(packPath, 'config.yaml'); const configPath = path.join(packPath, 'config.yaml');
try { try {
// Read config.yaml // Read config.yaml
const configContent = await fs.readFile(configPath, 'utf8'); const configContent = await fs.readFile(configPath, 'utf8');
const config = yaml.load(configContent); const config = yaml.load(configContent);
expansionPacks.push({ expansionPacks.push({
id: entry.name, id: entry.name,
name: config.name || entry.name, name: config.name || entry.name,
@ -100,13 +100,13 @@ class ConfigLoader {
} catch (error) { } catch (error) {
// Fallback if config.yaml doesn't exist or can't be read // Fallback if config.yaml doesn't exist or can't be read
console.warn(`Failed to read config for expansion pack ${entry.name}: ${error.message}`); console.warn(`Failed to read config for expansion pack ${entry.name}: ${error.message}`);
// Try to derive info from directory name as fallback // Try to derive info from directory name as fallback
const name = entry.name const name = entry.name
.split('-') .split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1)) .map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' '); .join(' ');
expansionPacks.push({ expansionPacks.push({
id: entry.name, id: entry.name,
name: name, name: name,
@ -120,7 +120,7 @@ class ConfigLoader {
} }
} }
} }
return expansionPacks; return expansionPacks;
} catch (error) { } catch (error) {
console.warn(`Failed to read expansion packs directory: ${error.message}`); console.warn(`Failed to read expansion packs directory: ${error.message}`);
@ -132,16 +132,16 @@ class ConfigLoader {
// Use DependencyResolver to dynamically parse agent dependencies // Use DependencyResolver to dynamically parse agent dependencies
const DependencyResolver = require('../../lib/dependency-resolver'); const DependencyResolver = require('../../lib/dependency-resolver');
const resolver = new DependencyResolver(path.join(__dirname, '..', '..', '..')); const resolver = new DependencyResolver(path.join(__dirname, '..', '..', '..'));
const agentDeps = await resolver.resolveAgentDependencies(agentId); const agentDeps = await resolver.resolveAgentDependencies(agentId);
// Convert to flat list of file paths // Convert to flat list of file paths
const depPaths = []; const depPaths = [];
// Core files and utilities are included automatically by DependencyResolver // Core files and utilities are included automatically by DependencyResolver
// Add agent file itself is already handled by installer // Add agent file itself is already handled by installer
// Add all resolved resources // Add all resolved resources
for (const resource of agentDeps.resources) { for (const resource of agentDeps.resources) {
const filePath = `.bmad-core/${resource.type}/${resource.id}.md`; const filePath = `.bmad-core/${resource.type}/${resource.id}.md`;
@ -149,7 +149,7 @@ class ConfigLoader {
depPaths.push(filePath); depPaths.push(filePath);
} }
} }
return depPaths; return depPaths;
} }
@ -164,9 +164,9 @@ class ConfigLoader {
return path.join(__dirname, '..', '..', '..', 'bmad-core'); return path.join(__dirname, '..', '..', '..', 'bmad-core');
} }
getDistPath() { getBundlesPath() {
// Get the path to dist directory relative to the installer // Get the path to bundles directory relative to the installer
return path.join(__dirname, '..', '..', '..', 'dist'); return path.join(__dirname, '..', '..', '..', 'bundles');
} }
getAgentPath(agentId) { getAgentPath(agentId) {
@ -175,19 +175,19 @@ class ConfigLoader {
async getAvailableTeams() { async getAvailableTeams() {
const teamsDir = path.join(this.getBmadCorePath(), 'agent-teams'); const teamsDir = path.join(this.getBmadCorePath(), 'agent-teams');
try { try {
const entries = await fs.readdir(teamsDir, { withFileTypes: true }); const entries = await fs.readdir(teamsDir, { withFileTypes: true });
const teams = []; const teams = [];
for (const entry of entries) { for (const entry of entries) {
if (entry.isFile() && entry.name.endsWith('.yaml')) { if (entry.isFile() && entry.name.endsWith('.yaml')) {
const teamPath = path.join(teamsDir, entry.name); const teamPath = path.join(teamsDir, entry.name);
try { try {
const teamContent = await fs.readFile(teamPath, 'utf8'); const teamContent = await fs.readFile(teamPath, 'utf8');
const teamConfig = yaml.load(teamContent); const teamConfig = yaml.load(teamContent);
if (teamConfig.bundle) { if (teamConfig.bundle) {
teams.push({ teams.push({
id: path.basename(entry.name, '.yaml'), id: path.basename(entry.name, '.yaml'),
@ -201,7 +201,7 @@ class ConfigLoader {
} }
} }
} }
return teams; return teams;
} catch (error) { } catch (error) {
console.warn(`Warning: Could not scan teams directory: ${error.message}`); console.warn(`Warning: Could not scan teams directory: ${error.message}`);
@ -217,16 +217,16 @@ class ConfigLoader {
// Use DependencyResolver to dynamically parse team dependencies // Use DependencyResolver to dynamically parse team dependencies
const DependencyResolver = require('../../lib/dependency-resolver'); const DependencyResolver = require('../../lib/dependency-resolver');
const resolver = new DependencyResolver(path.join(__dirname, '..', '..', '..')); const resolver = new DependencyResolver(path.join(__dirname, '..', '..', '..'));
try { try {
const teamDeps = await resolver.resolveTeamDependencies(teamId); const teamDeps = await resolver.resolveTeamDependencies(teamId);
// Convert to flat list of file paths // Convert to flat list of file paths
const depPaths = []; const depPaths = [];
// Add team config file // Add team config file
depPaths.push(`.bmad-core/agent-teams/${teamId}.yaml`); depPaths.push(`.bmad-core/agent-teams/${teamId}.yaml`);
// Add all agents // Add all agents
for (const agent of teamDeps.agents) { for (const agent of teamDeps.agents) {
const filePath = `.bmad-core/agents/${agent.id}.md`; const filePath = `.bmad-core/agents/${agent.id}.md`;
@ -234,7 +234,7 @@ class ConfigLoader {
depPaths.push(filePath); depPaths.push(filePath);
} }
} }
// Add all resolved resources // Add all resolved resources
for (const resource of teamDeps.resources) { for (const resource of teamDeps.resources) {
const filePath = `.bmad-core/${resource.type}/${resource.id}.${resource.type === 'workflows' ? 'yaml' : 'md'}`; const filePath = `.bmad-core/${resource.type}/${resource.id}.${resource.type === 'workflows' ? 'yaml' : 'md'}`;
@ -242,7 +242,7 @@ class ConfigLoader {
depPaths.push(filePath); depPaths.push(filePath);
} }
} }
return depPaths; return depPaths;
} catch (error) { } catch (error) {
throw new Error(`Failed to resolve team dependencies for ${teamId}: ${error.message}`); throw new Error(`Failed to resolve team dependencies for ${teamId}: ${error.message}`);
@ -250,4 +250,4 @@ class ConfigLoader {
} }
} }
module.exports = new ConfigLoader(); module.exports = new ConfigLoader();

File diff suppressed because it is too large Load Diff