bmad-method 4.5.1 → 4.6.1
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/CHANGELOG.md +19 -0
- package/bmad-core/agents/bmad-orchestrator.md +55 -66
- package/bmad-core/agents/pm.md +0 -1
- package/bmad-core/tasks/doc-migration-task.md +9 -9
- package/bmad-core/tasks/index-docs.md +3 -7
- package/bmad-core/templates/architecture-tmpl.md +2 -0
- package/bmad-core/templates/brownfield-architecture-tmpl.md +2 -0
- package/bmad-core/templates/brownfield-prd-tmpl.md +2 -0
- package/bmad-core/templates/competitor-analysis-tmpl.md +2 -0
- package/bmad-core/templates/front-end-architecture-tmpl.md +2 -0
- package/bmad-core/templates/front-end-spec-tmpl.md +3 -1
- package/bmad-core/templates/fullstack-architecture-tmpl.md +62 -60
- package/bmad-core/templates/market-research-tmpl.md +2 -0
- package/bmad-core/templates/prd-tmpl.md +4 -2
- package/bmad-core/templates/project-brief-tmpl.md +2 -0
- package/bmad-core/workflows/brownfield-fullstack.yml +19 -58
- package/bmad-core/workflows/brownfield-service.yml +19 -58
- package/bmad-core/workflows/brownfield-ui.yml +20 -59
- package/bmad-core/workflows/greenfield-fullstack.yml +31 -77
- package/bmad-core/workflows/greenfield-service.yml +22 -68
- package/bmad-core/workflows/greenfield-ui.yml +30 -76
- package/dist/agents/architect.txt +60 -60
- package/dist/agents/bmad-master.txt +66 -70
- package/dist/agents/bmad-orchestrator.txt +55 -66
- package/dist/agents/pm.txt +2 -467
- package/dist/agents/ux-expert.txt +1 -1
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +481 -0
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +100 -0
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +100 -0
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +4757 -2941
- package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +35 -0
- package/dist/expansion-packs/expansion-creator/agents/bmad-the-creator.txt +438 -32
- package/dist/teams/team-all.txt +368 -1099
- package/dist/teams/team-fullstack.txt +286 -1017
- package/dist/teams/team-ide-minimal.txt +55 -66
- package/dist/teams/team-no-ui.txt +224 -785
- package/docs/versioning-and-releases.md +6 -6
- package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/phaser-2d-nodejs-game-team.yml +1 -0
- package/expansion-packs/expansion-creator/tasks/generate-expansion-pack.md +17 -13
- package/package.json +1 -1
- package/tools/builders/web-builder.js +189 -20
- package/tools/installer/package.json +1 -1
- package/bmad-core/templates/simple-project-prd-tmpl.md +0 -461
|
@@ -8,11 +8,11 @@ The easiest way to release new versions is through **automatic semantic releases
|
|
|
8
8
|
|
|
9
9
|
Use these prefixes to control what type of release happens:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
```bash
|
|
12
12
|
fix: resolve CLI argument parsing bug # → patch release (4.1.0 → 4.1.1)
|
|
13
13
|
feat: add new agent orchestration mode # → minor release (4.1.0 → 4.2.0)
|
|
14
14
|
feat!: redesign CLI interface # → major release (4.1.0 → 5.0.0)
|
|
15
|
-
```
|
|
15
|
+
```
|
|
16
16
|
|
|
17
17
|
### What Happens Automatically
|
|
18
18
|
|
|
@@ -35,24 +35,24 @@ git push
|
|
|
35
35
|
|
|
36
36
|
# That's it! Release happens automatically 🎉
|
|
37
37
|
# Users can now run: npx bmad-method (and get the new version)
|
|
38
|
-
|
|
38
|
+
```
|
|
39
39
|
|
|
40
40
|
### Commits That DON'T Trigger Releases
|
|
41
41
|
|
|
42
42
|
These commit types won't create releases (use them for maintenance):
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
```bash
|
|
45
45
|
chore: update dependencies # No release
|
|
46
46
|
docs: fix typo in readme # No release
|
|
47
47
|
style: format code # No release
|
|
48
48
|
test: add unit tests # No release
|
|
49
|
-
```
|
|
49
|
+
```
|
|
50
50
|
|
|
51
51
|
### Test Your Setup
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
54
|
npm run release:test # Safe to run locally - tests the config
|
|
55
|
-
|
|
55
|
+
```
|
|
56
56
|
|
|
57
57
|
---
|
|
58
58
|
|
|
@@ -70,7 +70,7 @@ IMPORTANT: STOP HERE AND CREATE PLAN FIRST
|
|
|
70
70
|
|
|
71
71
|
Create `expansion-packs/{pack-name}/plan.md` with:
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
```markdown
|
|
74
74
|
# {Pack Name} Expansion Pack Plan
|
|
75
75
|
|
|
76
76
|
## Overview
|
|
@@ -149,8 +149,7 @@ Create `expansion-packs/{pack-name}/plan.md` with:
|
|
|
149
149
|
## Approval
|
|
150
150
|
|
|
151
151
|
User approval received: [ ] Yes
|
|
152
|
-
|
|
153
|
-
```text
|
|
152
|
+
```
|
|
154
153
|
|
|
155
154
|
Important: Wait for user approval before proceeding to Phase 2
|
|
156
155
|
|
|
@@ -281,8 +280,8 @@ For each checklist, implement comprehensive validation frameworks:
|
|
|
281
280
|
IMPORTANT: Only proceed after plan.md is approved
|
|
282
281
|
|
|
283
282
|
#### 3.1 Create Directory Structure
|
|
283
|
+
|
|
284
284
|
```
|
|
285
|
-
````
|
|
286
285
|
|
|
287
286
|
expansion-packs/
|
|
288
287
|
└── {pack-name}/
|
|
@@ -312,7 +311,7 @@ expansion-packs/
|
|
|
312
311
|
└── agent-teams/
|
|
313
312
|
└── {domain}-team.yml (REQUIRED if multiple agents)
|
|
314
313
|
|
|
315
|
-
|
|
314
|
+
```
|
|
316
315
|
|
|
317
316
|
#### 3.2 Create Manifest
|
|
318
317
|
|
|
@@ -415,7 +414,7 @@ post_install_message: |
|
|
|
415
414
|
- Domain best practices and terminology
|
|
416
415
|
- Quality standards and validation criteria
|
|
417
416
|
- Workflow orchestration with handoff protocols
|
|
418
|
-
|
|
417
|
+
```
|
|
419
418
|
|
|
420
419
|
### Phase 4: Content Creation
|
|
421
420
|
|
|
@@ -439,7 +438,7 @@ IMPORTANT: Work through plan.md checklist systematically!
|
|
|
439
438
|
|
|
440
439
|
Before proceeding, copy these essential files from bmad-core:
|
|
441
440
|
|
|
442
|
-
|
|
441
|
+
```bash
|
|
443
442
|
# Copy core task utilities
|
|
444
443
|
cp bmad-core/tasks/create-doc.md expansion-packs/{pack-name}/tasks/
|
|
445
444
|
cp bmad-core/tasks/execute-checklist.md expansion-packs/{pack-name}/tasks/
|
|
@@ -448,7 +447,7 @@ cp bmad-core/tasks/execute-checklist.md expansion-packs/{pack-name}/tasks/
|
|
|
448
447
|
mkdir -p expansion-packs/{pack-name}/utils
|
|
449
448
|
cp bmad-core/utils/template-format.md expansion-packs/{pack-name}/utils/
|
|
450
449
|
cp bmad-core/utils/workflow-management.md expansion-packs/{pack-name}/utils/
|
|
451
|
-
```
|
|
450
|
+
```
|
|
452
451
|
|
|
453
452
|
**Step 3: Technical Implementation**
|
|
454
453
|
|
|
@@ -488,7 +487,7 @@ cp bmad-core/utils/workflow-management.md expansion-packs/{pack-name}/utils/
|
|
|
488
487
|
tasks: {required task list}
|
|
489
488
|
templates: {required template list}
|
|
490
489
|
checklists: {quality checklist list}
|
|
491
|
-
|
|
490
|
+
```
|
|
492
491
|
|
|
493
492
|
**Step 4: Workflow and Team Integration**
|
|
494
493
|
|
|
@@ -698,10 +697,10 @@ _{Professional background and expertise}_
|
|
|
698
697
|
- `{file2}.{ext}` - {description}
|
|
699
698
|
|
|
700
699
|
2. **Launch Orchestrator**:
|
|
700
|
+
|
|
701
701
|
```bash
|
|
702
702
|
npm run agent {pack-name}-orchestrator
|
|
703
703
|
```
|
|
704
|
-
````
|
|
705
704
|
|
|
706
705
|
3. **Follow Numbered Options**: {Character Name} will present numbered choices for each decision
|
|
707
706
|
|
|
@@ -731,14 +730,12 @@ _{Professional background and expertise}_
|
|
|
731
730
|
### Knowledge Base
|
|
732
731
|
|
|
733
732
|
[Embedded domain expertise]
|
|
734
|
-
|
|
735
733
|
````
|
|
736
734
|
|
|
737
735
|
#### 6.3 Advanced Data File Documentation with Validation
|
|
738
736
|
|
|
739
737
|
For each required data file, provide comprehensive guidance:
|
|
740
738
|
|
|
741
|
-
```markdown
|
|
742
739
|
## Required User Data Files
|
|
743
740
|
|
|
744
741
|
### {filename}.{ext}
|
|
@@ -748,7 +745,6 @@ For each required data file, provide comprehensive guidance:
|
|
|
748
745
|
- **Location**: Place in `bmad-core/data/`
|
|
749
746
|
- **Validation**: {how agents will verify the file is correct}
|
|
750
747
|
- **Example Structure**:
|
|
751
|
-
````
|
|
752
748
|
|
|
753
749
|
{sample content showing exact format}
|
|
754
750
|
|
|
@@ -1024,3 +1020,11 @@ Embedded knowledge (automatic):
|
|
|
1024
1020
|
- [ ] Template conditional content tested with different scenarios
|
|
1025
1021
|
- [ ] Workflow decision trees validated with sample use cases
|
|
1026
1022
|
- [ ] Character interactions tested for consistency and professional authenticity
|
|
1023
|
+
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
```
|
package/package.json
CHANGED
|
@@ -12,6 +12,11 @@ class WebBuilder {
|
|
|
12
12
|
this.templatePath = path.join(this.rootDir, 'bmad-core', 'templates', 'web-agent-startup-instructions-template.md');
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
parseYaml(content) {
|
|
16
|
+
const yaml = require('js-yaml');
|
|
17
|
+
return yaml.load(content);
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
async cleanOutputDirs() {
|
|
16
21
|
for (const dir of this.outputDirs) {
|
|
17
22
|
try {
|
|
@@ -232,7 +237,7 @@ class WebBuilder {
|
|
|
232
237
|
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
233
238
|
sections.push(this.formatSection(`agents#${agentName}`, agentContent));
|
|
234
239
|
|
|
235
|
-
// Resolve and add agent dependencies
|
|
240
|
+
// Resolve and add agent dependencies
|
|
236
241
|
const agentYaml = agentContent.match(/```yaml\n([\s\S]*?)\n```/);
|
|
237
242
|
if (agentYaml) {
|
|
238
243
|
try {
|
|
@@ -240,16 +245,43 @@ class WebBuilder {
|
|
|
240
245
|
const agentConfig = yaml.load(agentYaml[1]);
|
|
241
246
|
|
|
242
247
|
if (agentConfig.dependencies) {
|
|
243
|
-
// Add resources
|
|
248
|
+
// Add resources, first try expansion pack, then core
|
|
244
249
|
for (const [resourceType, resources] of Object.entries(agentConfig.dependencies)) {
|
|
245
250
|
if (Array.isArray(resources)) {
|
|
246
251
|
for (const resourceName of resources) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
252
|
+
let found = false;
|
|
253
|
+
const extensions = ['.md', '.yml', '.yaml'];
|
|
254
|
+
|
|
255
|
+
// Try expansion pack first
|
|
256
|
+
for (const ext of extensions) {
|
|
257
|
+
const resourcePath = path.join(packDir, resourceType, `${resourceName}${ext}`);
|
|
258
|
+
try {
|
|
259
|
+
const resourceContent = await fs.readFile(resourcePath, 'utf8');
|
|
260
|
+
sections.push(this.formatSection(`${resourceType}#${resourceName}`, resourceContent));
|
|
261
|
+
found = true;
|
|
262
|
+
break;
|
|
263
|
+
} catch (error) {
|
|
264
|
+
// Not in expansion pack, continue
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// If not found in expansion pack, try core
|
|
269
|
+
if (!found) {
|
|
270
|
+
for (const ext of extensions) {
|
|
271
|
+
const corePath = path.join(this.rootDir, 'bmad-core', resourceType, `${resourceName}${ext}`);
|
|
272
|
+
try {
|
|
273
|
+
const coreContent = await fs.readFile(corePath, 'utf8');
|
|
274
|
+
sections.push(this.formatSection(`${resourceType}#${resourceName}`, coreContent));
|
|
275
|
+
found = true;
|
|
276
|
+
break;
|
|
277
|
+
} catch (error) {
|
|
278
|
+
// Not in core either, continue
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (!found) {
|
|
284
|
+
console.warn(` ⚠ Dependency ${resourceType}#${resourceName} not found in expansion pack or core`);
|
|
253
285
|
}
|
|
254
286
|
}
|
|
255
287
|
}
|
|
@@ -268,32 +300,164 @@ class WebBuilder {
|
|
|
268
300
|
|
|
269
301
|
const sections = [template];
|
|
270
302
|
|
|
271
|
-
// Add team configuration
|
|
303
|
+
// Add team configuration and parse to get agent list
|
|
272
304
|
const teamContent = await fs.readFile(teamConfigPath, 'utf8');
|
|
273
305
|
const teamFileName = path.basename(teamConfigPath, '.yml');
|
|
306
|
+
const teamConfig = this.parseYaml(teamContent);
|
|
274
307
|
sections.push(this.formatSection(`agent-teams#${teamFileName}`, teamContent));
|
|
275
308
|
|
|
276
|
-
//
|
|
277
|
-
const
|
|
278
|
-
const orchestratorContent = await fs.readFile(orchestratorPath, 'utf8');
|
|
279
|
-
sections.push(this.formatSection('agents#bmad-orchestrator', orchestratorContent));
|
|
280
|
-
|
|
281
|
-
// Add expansion pack agents
|
|
309
|
+
// Get list of expansion pack agents
|
|
310
|
+
const expansionAgents = new Set();
|
|
282
311
|
const agentsDir = path.join(packDir, 'agents');
|
|
283
312
|
try {
|
|
284
313
|
const agentFiles = await fs.readdir(agentsDir);
|
|
285
314
|
for (const agentFile of agentFiles.filter(f => f.endsWith('.md'))) {
|
|
286
|
-
const agentPath = path.join(agentsDir, agentFile);
|
|
287
|
-
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
288
315
|
const agentName = agentFile.replace('.md', '');
|
|
289
|
-
|
|
316
|
+
expansionAgents.add(agentName);
|
|
290
317
|
}
|
|
291
318
|
} catch (error) {
|
|
292
319
|
console.warn(` ⚠ No agents directory found in ${packName}`);
|
|
293
320
|
}
|
|
294
321
|
|
|
295
|
-
//
|
|
322
|
+
// Build a map of all available expansion pack resources for override checking
|
|
323
|
+
const expansionResources = new Map();
|
|
296
324
|
const resourceDirs = ['templates', 'tasks', 'checklists', 'workflows', 'data'];
|
|
325
|
+
for (const resourceDir of resourceDirs) {
|
|
326
|
+
const resourcePath = path.join(packDir, resourceDir);
|
|
327
|
+
try {
|
|
328
|
+
const resourceFiles = await fs.readdir(resourcePath);
|
|
329
|
+
for (const resourceFile of resourceFiles.filter(f => f.endsWith('.md') || f.endsWith('.yml'))) {
|
|
330
|
+
const fileName = resourceFile.replace(/\.(md|yml)$/, '');
|
|
331
|
+
expansionResources.set(`${resourceDir}#${fileName}`, true);
|
|
332
|
+
}
|
|
333
|
+
} catch (error) {
|
|
334
|
+
// Directory might not exist, that's fine
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Process all agents listed in team configuration
|
|
339
|
+
const agentsToProcess = teamConfig.agents || [];
|
|
340
|
+
|
|
341
|
+
// Ensure bmad-orchestrator is always included for teams
|
|
342
|
+
if (!agentsToProcess.includes('bmad-orchestrator')) {
|
|
343
|
+
console.warn(` ⚠ Team ${teamFileName} missing bmad-orchestrator, adding automatically`);
|
|
344
|
+
agentsToProcess.unshift('bmad-orchestrator');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Track all dependencies from all agents (deduplicated)
|
|
348
|
+
const allDependencies = new Map();
|
|
349
|
+
|
|
350
|
+
for (const agentId of agentsToProcess) {
|
|
351
|
+
|
|
352
|
+
if (expansionAgents.has(agentId)) {
|
|
353
|
+
// Use expansion pack version (override)
|
|
354
|
+
const agentPath = path.join(agentsDir, `${agentId}.md`);
|
|
355
|
+
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
356
|
+
sections.push(this.formatSection(`agents#${agentId}`, agentContent));
|
|
357
|
+
|
|
358
|
+
// Parse and collect dependencies from expansion agent
|
|
359
|
+
const agentYaml = agentContent.match(/```yaml\n([\s\S]*?)\n```/);
|
|
360
|
+
if (agentYaml) {
|
|
361
|
+
try {
|
|
362
|
+
const agentConfig = this.parseYaml(agentYaml[1]);
|
|
363
|
+
if (agentConfig.dependencies) {
|
|
364
|
+
for (const [resourceType, resources] of Object.entries(agentConfig.dependencies)) {
|
|
365
|
+
if (Array.isArray(resources)) {
|
|
366
|
+
for (const resourceName of resources) {
|
|
367
|
+
const key = `${resourceType}#${resourceName}`;
|
|
368
|
+
if (!allDependencies.has(key)) {
|
|
369
|
+
allDependencies.set(key, { type: resourceType, name: resourceName });
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
} catch (error) {
|
|
376
|
+
console.debug(`Failed to parse agent YAML for ${agentId}:`, error.message);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
} else {
|
|
380
|
+
// Use core BMAD version
|
|
381
|
+
try {
|
|
382
|
+
const coreAgentPath = path.join(this.rootDir, 'bmad-core', 'agents', `${agentId}.md`);
|
|
383
|
+
const coreAgentContent = await fs.readFile(coreAgentPath, 'utf8');
|
|
384
|
+
sections.push(this.formatSection(`agents#${agentId}`, coreAgentContent));
|
|
385
|
+
|
|
386
|
+
// Parse and collect dependencies from core agent
|
|
387
|
+
const agentYaml = coreAgentContent.match(/```yaml\n([\s\S]*?)\n```/);
|
|
388
|
+
if (agentYaml) {
|
|
389
|
+
try {
|
|
390
|
+
// Clean up the YAML to handle command descriptions after dashes
|
|
391
|
+
let yamlContent = agentYaml[1];
|
|
392
|
+
yamlContent = yamlContent.replace(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, '$1$2');
|
|
393
|
+
|
|
394
|
+
const agentConfig = this.parseYaml(yamlContent);
|
|
395
|
+
if (agentConfig.dependencies) {
|
|
396
|
+
for (const [resourceType, resources] of Object.entries(agentConfig.dependencies)) {
|
|
397
|
+
if (Array.isArray(resources)) {
|
|
398
|
+
for (const resourceName of resources) {
|
|
399
|
+
const key = `${resourceType}#${resourceName}`;
|
|
400
|
+
if (!allDependencies.has(key)) {
|
|
401
|
+
allDependencies.set(key, { type: resourceType, name: resourceName });
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
} catch (error) {
|
|
408
|
+
console.debug(`Failed to parse agent YAML for ${agentId}:`, error.message);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
} catch (error) {
|
|
412
|
+
console.warn(` ⚠ Agent ${agentId} not found in core or expansion pack`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Add all collected dependencies from agents
|
|
418
|
+
// Always prefer expansion pack versions if they exist
|
|
419
|
+
for (const [key, dep] of allDependencies) {
|
|
420
|
+
let found = false;
|
|
421
|
+
const extensions = ['.md', '.yml', '.yaml'];
|
|
422
|
+
|
|
423
|
+
// Always check expansion pack first, even if the dependency came from a core agent
|
|
424
|
+
if (expansionResources.has(key)) {
|
|
425
|
+
// We know it exists in expansion pack, find and load it
|
|
426
|
+
for (const ext of extensions) {
|
|
427
|
+
const expansionPath = path.join(packDir, dep.type, `${dep.name}${ext}`);
|
|
428
|
+
try {
|
|
429
|
+
const content = await fs.readFile(expansionPath, 'utf8');
|
|
430
|
+
sections.push(this.formatSection(key, content));
|
|
431
|
+
console.log(` ✓ Using expansion override for ${key}`);
|
|
432
|
+
found = true;
|
|
433
|
+
break;
|
|
434
|
+
} catch (error) {
|
|
435
|
+
// Try next extension
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// If not found in expansion pack (or doesn't exist there), try core
|
|
441
|
+
if (!found) {
|
|
442
|
+
for (const ext of extensions) {
|
|
443
|
+
const corePath = path.join(this.rootDir, 'bmad-core', dep.type, `${dep.name}${ext}`);
|
|
444
|
+
try {
|
|
445
|
+
const content = await fs.readFile(corePath, 'utf8');
|
|
446
|
+
sections.push(this.formatSection(key, content));
|
|
447
|
+
found = true;
|
|
448
|
+
break;
|
|
449
|
+
} catch (error) {
|
|
450
|
+
// Not in core either, continue
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (!found) {
|
|
456
|
+
console.warn(` ⚠ Dependency ${key} not found in expansion pack or core`);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Add remaining expansion pack resources not already included as dependencies
|
|
297
461
|
for (const resourceDir of resourceDirs) {
|
|
298
462
|
const resourcePath = path.join(packDir, resourceDir);
|
|
299
463
|
try {
|
|
@@ -302,7 +466,12 @@ class WebBuilder {
|
|
|
302
466
|
const filePath = path.join(resourcePath, resourceFile);
|
|
303
467
|
const fileContent = await fs.readFile(filePath, 'utf8');
|
|
304
468
|
const fileName = resourceFile.replace(/\.(md|yml)$/, '');
|
|
305
|
-
|
|
469
|
+
|
|
470
|
+
// Only add if not already included as a dependency
|
|
471
|
+
const resourceKey = `${resourceDir}#${fileName}`;
|
|
472
|
+
if (!allDependencies.has(resourceKey)) {
|
|
473
|
+
sections.push(this.formatSection(resourceKey, fileContent));
|
|
474
|
+
}
|
|
306
475
|
}
|
|
307
476
|
} catch (error) {
|
|
308
477
|
// Directory might not exist, that's fine
|