bmad-fh 6.0.0-alpha.23.66f19588 → 6.0.0-alpha.23.6874ced1
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/.husky/post-checkout +12 -0
- package/.husky/pre-commit +17 -2
- package/.husky/pre-push +10 -0
- package/README.md +13 -7
- package/docs/migration-guide.md +27 -7
- package/docs/multi-scope-guide.md +69 -33
- package/docs/plans/multi-scope-parallel-artifacts-plan.md +112 -91
- package/package.json +3 -2
- package/src/core/lib/scope/scope-context.js +13 -2
- package/src/core/lib/scope/scope-manager.js +1 -1
- package/src/core/lib/scope/scope-validator.js +6 -4
- package/test/test-cli-arguments.js +686 -0
- package/test/test-scope-cli.js +171 -2
- package/tools/bmad-npx-wrapper.js +12 -2
- package/tools/build-docs.js +1 -0
- package/tools/cli/commands/scope.js +37 -2
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Multi-Scope Parallel Artifacts System - Implementation Plan'
|
|
3
|
+
description: 'Implementation plan for the multi-scope parallel artifact system'
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Multi-Scope Parallel Artifacts System - Implementation Plan
|
|
2
7
|
|
|
3
8
|
> **Status:** Planning Complete
|
|
@@ -35,18 +40,18 @@ This plan outlines the implementation of a **multi-scope parallel artifact syste
|
|
|
35
40
|
|
|
36
41
|
## Key Design Decisions
|
|
37
42
|
|
|
38
|
-
| Decision
|
|
39
|
-
|
|
40
|
-
| **Sprint-status handling**
|
|
41
|
-
| **Project-context location** | Both (global + per-scope) | Global "bible" in `_shared/`, optional scope-specific that extends
|
|
42
|
-
| **Scope vs Module**
|
|
43
|
-
| **Cross-scope access**
|
|
44
|
-
| **Test directories**
|
|
45
|
-
| **Workflow updates**
|
|
46
|
-
| **File locking**
|
|
47
|
-
| **Git hooks**
|
|
48
|
-
| **Migration strategy**
|
|
49
|
-
| **Scope ID format**
|
|
43
|
+
| Decision | Choice | Rationale |
|
|
44
|
+
| ---------------------------- | ------------------------- | --------------------------------------------------------------------------------- |
|
|
45
|
+
| **Sprint-status handling** | Per-scope | Each scope has independent sprint planning, no parallel conflicts |
|
|
46
|
+
| **Project-context location** | Both (global + per-scope) | Global "bible" in `_shared/`, optional scope-specific that extends |
|
|
47
|
+
| **Scope vs Module** | Different concepts | Module = code organization (bmm/core), Scope = artifact isolation (auth/payments) |
|
|
48
|
+
| **Cross-scope access** | Read any, write own | Liberal reads for dependency awareness, strict writes for isolation |
|
|
49
|
+
| **Test directories** | Scoped | `{output_folder}/{scope}/tests` for full isolation |
|
|
50
|
+
| **Workflow updates** | Automated script | Handle 22+ workflow.yaml files programmatically |
|
|
51
|
+
| **File locking** | proper-lockfile npm | Battle-tested, cross-platform locking |
|
|
52
|
+
| **Git hooks** | This repo only | For contributor workflow, NOT installed with bmad |
|
|
53
|
+
| **Migration strategy** | Auto-migrate to 'default' | Existing artifacts move to default scope automatically |
|
|
54
|
+
| **Scope ID format** | Strict | Lowercase alphanumeric + hyphens only |
|
|
50
55
|
|
|
51
56
|
---
|
|
52
57
|
|
|
@@ -173,25 +178,26 @@ git remote add upstream git@github.com:bmad-code-org/BMAD-METHOD.git
|
|
|
173
178
|
version: 1
|
|
174
179
|
|
|
175
180
|
settings:
|
|
176
|
-
allow_adhoc_scopes: true
|
|
177
|
-
isolation_mode: strict
|
|
178
|
-
default_output_base:
|
|
179
|
-
default_shared_path:
|
|
181
|
+
allow_adhoc_scopes: true # Allow on-demand scope creation
|
|
182
|
+
isolation_mode: strict # strict | warn | permissive
|
|
183
|
+
default_output_base: '_bmad-output'
|
|
184
|
+
default_shared_path: '_bmad-output/_shared'
|
|
180
185
|
|
|
181
186
|
scopes:
|
|
182
187
|
auth:
|
|
183
|
-
id:
|
|
184
|
-
name:
|
|
185
|
-
description:
|
|
186
|
-
status: active
|
|
187
|
-
dependencies: []
|
|
188
|
-
created:
|
|
188
|
+
id: 'auth'
|
|
189
|
+
name: 'Authentication Service'
|
|
190
|
+
description: 'User authentication, SSO, authorization'
|
|
191
|
+
status: active # active | archived
|
|
192
|
+
dependencies: [] # Scopes this depends on
|
|
193
|
+
created: '2026-01-21T10:00:00Z'
|
|
189
194
|
_meta:
|
|
190
|
-
last_activity:
|
|
195
|
+
last_activity: '2026-01-21T15:30:00Z'
|
|
191
196
|
artifact_count: 12
|
|
192
197
|
```
|
|
193
198
|
|
|
194
199
|
**Validation Rules:**
|
|
200
|
+
|
|
195
201
|
- Scope ID: `^[a-z][a-z0-9-]*[a-z0-9]$` (2-50 chars)
|
|
196
202
|
- Reserved IDs: `_shared`, `_events`, `_config`, `global`
|
|
197
203
|
- Circular dependency detection required
|
|
@@ -208,15 +214,15 @@ class ScopeManager {
|
|
|
208
214
|
async createScope(scopeId, options)
|
|
209
215
|
async updateScope(scopeId, updates)
|
|
210
216
|
async removeScope(scopeId, options)
|
|
211
|
-
|
|
217
|
+
|
|
212
218
|
// Path Resolution
|
|
213
219
|
async getScopePaths(scopeId)
|
|
214
220
|
resolvePath(template, scopeId)
|
|
215
|
-
|
|
221
|
+
|
|
216
222
|
// Validation
|
|
217
223
|
validateScopeId(scopeId)
|
|
218
224
|
validateDependencies(scopeId, dependencies, allScopes)
|
|
219
|
-
|
|
225
|
+
|
|
220
226
|
// Dependencies
|
|
221
227
|
async getDependencyTree(scopeId)
|
|
222
228
|
findDependentScopes(scopeId, allScopes)
|
|
@@ -227,19 +233,20 @@ class ScopeManager {
|
|
|
227
233
|
|
|
228
234
|
**File:** `tools/cli/commands/scope.js`
|
|
229
235
|
|
|
230
|
-
| Command
|
|
231
|
-
|
|
232
|
-
| `bmad scope list`
|
|
233
|
-
| `bmad scope create <id>` | Create new scope interactively
|
|
234
|
-
| `bmad scope info <id>`
|
|
235
|
-
| `bmad scope remove <id>` | Remove scope
|
|
236
|
-
| `bmad scope migrate`
|
|
236
|
+
| Command | Description |
|
|
237
|
+
| ------------------------ | ------------------------------------ |
|
|
238
|
+
| `bmad scope list` | List all scopes |
|
|
239
|
+
| `bmad scope create <id>` | Create new scope interactively |
|
|
240
|
+
| `bmad scope info <id>` | Show scope details |
|
|
241
|
+
| `bmad scope remove <id>` | Remove scope |
|
|
242
|
+
| `bmad scope migrate` | Migrate existing to scoped structure |
|
|
237
243
|
|
|
238
244
|
### 1.4 Directory Structure Generator
|
|
239
245
|
|
|
240
246
|
**File:** `src/core/scope/scope-initializer.js`
|
|
241
247
|
|
|
242
248
|
Creates on scope creation:
|
|
249
|
+
|
|
243
250
|
```
|
|
244
251
|
_bmad-output/{scope}/
|
|
245
252
|
├── planning-artifacts/
|
|
@@ -249,6 +256,7 @@ _bmad-output/{scope}/
|
|
|
249
256
|
```
|
|
250
257
|
|
|
251
258
|
Creates on first scope (one-time):
|
|
259
|
+
|
|
252
260
|
```
|
|
253
261
|
_bmad-output/_shared/
|
|
254
262
|
├── project-context.md # Global project context template
|
|
@@ -265,6 +273,7 @@ _bmad/_events/
|
|
|
265
273
|
**File:** `src/core/scope/scope-migrator.js`
|
|
266
274
|
|
|
267
275
|
Steps:
|
|
276
|
+
|
|
268
277
|
1. Create backup of `_bmad-output/`
|
|
269
278
|
2. Initialize scope system
|
|
270
279
|
3. Create `default` scope
|
|
@@ -290,14 +299,14 @@ Add Step 0 before existing Step 1:
|
|
|
290
299
|
<action>Scan workflow.yaml for {scope} variable</action>
|
|
291
300
|
<action>If found → workflow requires scope</action>
|
|
292
301
|
</substep>
|
|
293
|
-
|
|
302
|
+
|
|
294
303
|
<substep n="0b" title="Resolve Scope">
|
|
295
304
|
<!-- Priority order: -->
|
|
296
305
|
<!-- 1. --scope argument from command -->
|
|
297
306
|
<!-- 2. Session context (if set) -->
|
|
298
307
|
<!-- 3. Prompt user to select/create -->
|
|
299
308
|
</substep>
|
|
300
|
-
|
|
309
|
+
|
|
301
310
|
<substep n="0c" title="Load Scope Context">
|
|
302
311
|
<action>Load scope config from scopes.yaml</action>
|
|
303
312
|
<action>Resolve scope paths</action>
|
|
@@ -333,6 +342,7 @@ implementation_artifacts:
|
|
|
333
342
|
**File:** `tools/cli/scripts/migrate-workflows.js`
|
|
334
343
|
|
|
335
344
|
Updates for 22+ workflow files:
|
|
345
|
+
|
|
336
346
|
1. Update `test_dir` variables to use `{output_folder}/{scope}/tests`
|
|
337
347
|
2. Handle variations in path definitions
|
|
338
348
|
3. Preserve `{config_source}:` references (they'll work via updated module.yaml)
|
|
@@ -357,6 +367,7 @@ Updates for 22+ workflow files:
|
|
|
357
367
|
**Modification to workflow.xml:**
|
|
358
368
|
|
|
359
369
|
When `<invoke-workflow>` is encountered:
|
|
370
|
+
|
|
360
371
|
1. Pass current `{scope}` as implicit parameter
|
|
361
372
|
2. Child workflow inherits scope from parent
|
|
362
373
|
3. Can be overridden with explicit `<param>scope: other</param>`
|
|
@@ -377,27 +388,27 @@ class ArtifactResolver {
|
|
|
377
388
|
this.currentScope = currentScope;
|
|
378
389
|
this.basePath = basePath;
|
|
379
390
|
}
|
|
380
|
-
|
|
391
|
+
|
|
381
392
|
// Read-any: Allow reading from any scope
|
|
382
393
|
canRead(path) {
|
|
383
394
|
return true; // All reads allowed
|
|
384
395
|
}
|
|
385
|
-
|
|
396
|
+
|
|
386
397
|
// Write-own: Only allow writing to current scope
|
|
387
398
|
canWrite(path) {
|
|
388
399
|
const targetScope = this.extractScopeFromPath(path);
|
|
389
|
-
|
|
400
|
+
|
|
390
401
|
if (targetScope === '_shared') {
|
|
391
402
|
throw new Error('Cannot write directly to _shared. Use: bmad scope sync-up');
|
|
392
403
|
}
|
|
393
|
-
|
|
404
|
+
|
|
394
405
|
if (targetScope !== this.currentScope) {
|
|
395
406
|
throw new Error(`Cannot write to scope '${targetScope}' while in scope '${this.currentScope}'`);
|
|
396
407
|
}
|
|
397
|
-
|
|
408
|
+
|
|
398
409
|
return true;
|
|
399
410
|
}
|
|
400
|
-
|
|
411
|
+
|
|
401
412
|
extractScopeFromPath(path) {
|
|
402
413
|
// Extract scope from path like _bmad-output/auth/...
|
|
403
414
|
}
|
|
@@ -414,27 +425,27 @@ const lockfile = require('proper-lockfile');
|
|
|
414
425
|
class StateLock {
|
|
415
426
|
async withLock(filePath, operation) {
|
|
416
427
|
const release = await lockfile.lock(filePath, {
|
|
417
|
-
stale: 30000,
|
|
418
|
-
retries: { retries: 10, minTimeout: 100, maxTimeout: 1000 }
|
|
428
|
+
stale: 30000, // 30s stale timeout
|
|
429
|
+
retries: { retries: 10, minTimeout: 100, maxTimeout: 1000 },
|
|
419
430
|
});
|
|
420
|
-
|
|
431
|
+
|
|
421
432
|
try {
|
|
422
433
|
return await operation();
|
|
423
434
|
} finally {
|
|
424
435
|
await release();
|
|
425
436
|
}
|
|
426
437
|
}
|
|
427
|
-
|
|
438
|
+
|
|
428
439
|
// Optimistic locking with version field
|
|
429
440
|
async updateYamlWithVersion(filePath, modifier) {
|
|
430
441
|
return this.withLock(filePath, async () => {
|
|
431
442
|
const data = await this.readYaml(filePath);
|
|
432
443
|
const currentVersion = data._version || 0;
|
|
433
|
-
|
|
444
|
+
|
|
434
445
|
const modified = await modifier(data);
|
|
435
446
|
modified._version = currentVersion + 1;
|
|
436
447
|
modified._lastModified = new Date().toISOString();
|
|
437
|
-
|
|
448
|
+
|
|
438
449
|
await this.writeYaml(filePath, modified);
|
|
439
450
|
return modified;
|
|
440
451
|
});
|
|
@@ -443,6 +454,7 @@ class StateLock {
|
|
|
443
454
|
```
|
|
444
455
|
|
|
445
456
|
**Files requiring locking:**
|
|
457
|
+
|
|
446
458
|
- `{scope}/implementation-artifacts/sprint-status.yaml`
|
|
447
459
|
- `{scope}/planning-artifacts/bmm-workflow-status.yaml`
|
|
448
460
|
- `_shared/` files during sync operations
|
|
@@ -451,6 +463,7 @@ class StateLock {
|
|
|
451
463
|
### 3.3 Package.json Update
|
|
452
464
|
|
|
453
465
|
Add dependency:
|
|
466
|
+
|
|
454
467
|
```json
|
|
455
468
|
{
|
|
456
469
|
"dependencies": {
|
|
@@ -470,16 +483,18 @@ Add dependency:
|
|
|
470
483
|
**Command:** `bmad scope sync-up <scope>`
|
|
471
484
|
|
|
472
485
|
**Logic:**
|
|
486
|
+
|
|
473
487
|
1. Identify promotable artifacts (configurable patterns)
|
|
474
488
|
2. Check for conflicts with existing shared files
|
|
475
489
|
3. Copy to `_shared/` with attribution metadata
|
|
476
490
|
4. Log event for dependent scope notification
|
|
477
491
|
|
|
478
492
|
**Metadata added to promoted files:**
|
|
493
|
+
|
|
479
494
|
```yaml
|
|
480
495
|
# _shared/architecture/auth-api.md.meta
|
|
481
496
|
source_scope: auth
|
|
482
|
-
promoted_at:
|
|
497
|
+
promoted_at: '2026-01-21T10:00:00Z'
|
|
483
498
|
original_hash: abc123
|
|
484
499
|
version: 1
|
|
485
500
|
```
|
|
@@ -489,6 +504,7 @@ version: 1
|
|
|
489
504
|
**Command:** `bmad scope sync-down <scope>`
|
|
490
505
|
|
|
491
506
|
**Logic:**
|
|
507
|
+
|
|
492
508
|
1. Find shared updates since last sync
|
|
493
509
|
2. Compare with local copies (if any)
|
|
494
510
|
3. Handle conflicts (prompt user for resolution)
|
|
@@ -498,6 +514,7 @@ version: 1
|
|
|
498
514
|
### 4.3 Conflict Resolution
|
|
499
515
|
|
|
500
516
|
**Options when conflict detected:**
|
|
517
|
+
|
|
501
518
|
1. Keep local (overwrite shared)
|
|
502
519
|
2. Keep shared (discard local)
|
|
503
520
|
3. Merge (3-way diff if possible)
|
|
@@ -520,14 +537,14 @@ events:
|
|
|
520
537
|
type: artifact_created
|
|
521
538
|
scope: auth
|
|
522
539
|
artifact: planning-artifacts/prd.md
|
|
523
|
-
timestamp:
|
|
524
|
-
|
|
540
|
+
timestamp: '2026-01-21T10:30:00Z'
|
|
541
|
+
|
|
525
542
|
- id: evt_002
|
|
526
543
|
type: artifact_promoted
|
|
527
544
|
scope: auth
|
|
528
545
|
artifact: architecture.md
|
|
529
546
|
shared_path: _shared/auth/architecture.md
|
|
530
|
-
timestamp:
|
|
547
|
+
timestamp: '2026-01-21T11:00:00Z'
|
|
531
548
|
```
|
|
532
549
|
|
|
533
550
|
### 5.2 Subscriptions
|
|
@@ -539,13 +556,14 @@ subscriptions:
|
|
|
539
556
|
payments:
|
|
540
557
|
watch:
|
|
541
558
|
- scope: auth
|
|
542
|
-
patterns: [
|
|
559
|
+
patterns: ['contracts/*', 'architecture.md']
|
|
543
560
|
notify: true
|
|
544
561
|
```
|
|
545
562
|
|
|
546
563
|
### 5.3 Notification on Activation
|
|
547
564
|
|
|
548
565
|
When agent/workflow activates with scope:
|
|
566
|
+
|
|
549
567
|
1. Check subscriptions for this scope
|
|
550
568
|
2. Find events since last activity
|
|
551
569
|
3. Display pending updates (if any)
|
|
@@ -562,6 +580,7 @@ When agent/workflow activates with scope:
|
|
|
562
580
|
**File:** `tools/cli/installers/lib/ide/shared/scope-aware-command.js`
|
|
563
581
|
|
|
564
582
|
Updates to workflow-command-template.md:
|
|
583
|
+
|
|
565
584
|
```markdown
|
|
566
585
|
### Scope Resolution
|
|
567
586
|
|
|
@@ -581,22 +600,24 @@ Store selected scope for session.
|
|
|
581
600
|
```yaml
|
|
582
601
|
# .bmad-scope (gitignored)
|
|
583
602
|
active_scope: auth
|
|
584
|
-
set_at:
|
|
603
|
+
set_at: '2026-01-21T10:00:00Z'
|
|
585
604
|
```
|
|
586
605
|
|
|
587
606
|
### 6.3 Agent Menu Updates
|
|
588
607
|
|
|
589
608
|
Add `scope_required` attribute:
|
|
609
|
+
|
|
590
610
|
```yaml
|
|
591
611
|
menu:
|
|
592
|
-
- trigger:
|
|
593
|
-
workflow:
|
|
594
|
-
scope_required: true
|
|
612
|
+
- trigger: 'prd'
|
|
613
|
+
workflow: '...'
|
|
614
|
+
scope_required: true # Enforce scope for this menu item
|
|
595
615
|
```
|
|
596
616
|
|
|
597
617
|
### 6.4 Documentation
|
|
598
618
|
|
|
599
619
|
Files to create:
|
|
620
|
+
|
|
600
621
|
1. `docs/multi-scope-guide.md` - User guide
|
|
601
622
|
2. `docs/migration-guide.md` - Upgrading existing installations
|
|
602
623
|
3. Update README with multi-scope overview
|
|
@@ -605,14 +626,14 @@ Files to create:
|
|
|
605
626
|
|
|
606
627
|
## Risk Mitigation
|
|
607
628
|
|
|
608
|
-
| Risk
|
|
609
|
-
|
|
610
|
-
| Breaking existing installations | Auto-migration with backup, rollback capability
|
|
611
|
-
| Parallel write conflicts
|
|
612
|
-
| Cross-scope data corruption
|
|
613
|
-
| Complex merge conflicts
|
|
614
|
-
| IDE compatibility
|
|
615
|
-
| Performance with many scopes
|
|
629
|
+
| Risk | Mitigation |
|
|
630
|
+
| ------------------------------- | ------------------------------------------------ |
|
|
631
|
+
| Breaking existing installations | Auto-migration with backup, rollback capability |
|
|
632
|
+
| Parallel write conflicts | File locking + optimistic versioning |
|
|
633
|
+
| Cross-scope data corruption | Write isolation enforcement in ArtifactResolver |
|
|
634
|
+
| Complex merge conflicts | Clear conflict resolution UI + skip option |
|
|
635
|
+
| IDE compatibility | Test with all supported IDEs, graceful fallbacks |
|
|
636
|
+
| Performance with many scopes | Lazy loading, scope caching |
|
|
616
637
|
|
|
617
638
|
---
|
|
618
639
|
|
|
@@ -660,36 +681,36 @@ MVP can be achieved with Phases 0-3 (isolation working, no sync/events yet).
|
|
|
660
681
|
|
|
661
682
|
### New Files
|
|
662
683
|
|
|
663
|
-
| Path
|
|
664
|
-
|
|
665
|
-
| `.githooks/pre-push`
|
|
666
|
-
| `.githooks/pre-commit`
|
|
667
|
-
| `.githooks/post-checkout`
|
|
668
|
-
| `src/core/scope/scope-manager.js`
|
|
669
|
-
| `src/core/scope/scope-initializer.js`
|
|
670
|
-
| `src/core/scope/scope-migrator.js`
|
|
671
|
-
| `src/core/scope/scope-context.js`
|
|
672
|
-
| `src/core/scope/artifact-resolver.js`
|
|
673
|
-
| `src/core/scope/state-lock.js`
|
|
674
|
-
| `src/core/scope/scope-sync.js`
|
|
675
|
-
| `src/core/scope/event-logger.js`
|
|
676
|
-
| `tools/cli/commands/scope.js`
|
|
677
|
-
| `tools/cli/scripts/migrate-workflows.js`
|
|
678
|
-
| `docs/plans/multi-scope-parallel-artifacts-plan.md` | This file
|
|
684
|
+
| Path | Purpose |
|
|
685
|
+
| --------------------------------------------------- | ----------------------------------- |
|
|
686
|
+
| `.githooks/pre-push` | Git hook for single-commit workflow |
|
|
687
|
+
| `.githooks/pre-commit` | Git hook to block main commits |
|
|
688
|
+
| `.githooks/post-checkout` | Git hook for sync reminders |
|
|
689
|
+
| `src/core/scope/scope-manager.js` | Scope CRUD operations |
|
|
690
|
+
| `src/core/scope/scope-initializer.js` | Directory creation |
|
|
691
|
+
| `src/core/scope/scope-migrator.js` | Migration logic |
|
|
692
|
+
| `src/core/scope/scope-context.js` | Session context |
|
|
693
|
+
| `src/core/scope/artifact-resolver.js` | Read/write enforcement |
|
|
694
|
+
| `src/core/scope/state-lock.js` | File locking utilities |
|
|
695
|
+
| `src/core/scope/scope-sync.js` | Sync-up/down logic |
|
|
696
|
+
| `src/core/scope/event-logger.js` | Event logging |
|
|
697
|
+
| `tools/cli/commands/scope.js` | CLI scope commands |
|
|
698
|
+
| `tools/cli/scripts/migrate-workflows.js` | Workflow update script |
|
|
699
|
+
| `docs/plans/multi-scope-parallel-artifacts-plan.md` | This file |
|
|
679
700
|
|
|
680
701
|
### Modified Files
|
|
681
702
|
|
|
682
|
-
| Path
|
|
683
|
-
|
|
684
|
-
| `src/core/tasks/workflow.xml`
|
|
685
|
-
| `src/core/module.yaml`
|
|
686
|
-
| `src/bmm/module.yaml`
|
|
687
|
-
| `src/utility/agent-components/activation-steps.txt` | Add scope loading
|
|
688
|
-
| `tools/cli/bmad-cli.js`
|
|
689
|
-
| `tools/cli/installers/lib/ide/templates/*`
|
|
690
|
-
| `package.json`
|
|
691
|
-
| `22+ workflow.yaml files`
|
|
703
|
+
| Path | Changes |
|
|
704
|
+
| --------------------------------------------------- | ---------------------------------- |
|
|
705
|
+
| `src/core/tasks/workflow.xml` | Add Step 0 for scope init |
|
|
706
|
+
| `src/core/module.yaml` | Add scope settings |
|
|
707
|
+
| `src/bmm/module.yaml` | Add {scope} to paths |
|
|
708
|
+
| `src/utility/agent-components/activation-steps.txt` | Add scope loading |
|
|
709
|
+
| `tools/cli/bmad-cli.js` | Register scope command |
|
|
710
|
+
| `tools/cli/installers/lib/ide/templates/*` | Scope-aware templates |
|
|
711
|
+
| `package.json` | Add proper-lockfile dependency |
|
|
712
|
+
| `22+ workflow.yaml files` | Update test_dir paths (via script) |
|
|
692
713
|
|
|
693
714
|
---
|
|
694
715
|
|
|
695
|
-
|
|
716
|
+
_End of Plan_
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "bmad-fh",
|
|
4
|
-
"version": "6.0.0-alpha.23.
|
|
4
|
+
"version": "6.0.0-alpha.23.6874ced1",
|
|
5
5
|
"description": "Breakthrough Method of Agile AI-driven Development",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"agile",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"release:minor": "gh workflow run \"Manual Release\" -f version_bump=minor",
|
|
45
45
|
"release:patch": "gh workflow run \"Manual Release\" -f version_bump=patch",
|
|
46
46
|
"release:watch": "gh run watch",
|
|
47
|
-
"test": "npm run test:schemas && npm run test:install && npm run validate:schemas && npm run lint && npm run lint:md && npm run format:check",
|
|
47
|
+
"test": "npm run test:schemas && npm run test:install && npm run test:cli-args && npm run validate:schemas && npm run lint && npm run lint:md && npm run format:check",
|
|
48
|
+
"test:cli-args": "node test/test-cli-arguments.js",
|
|
48
49
|
"test:coverage": "c8 --reporter=text --reporter=html npm run test:schemas",
|
|
49
50
|
"test:install": "node test/test-installation-components.js",
|
|
50
51
|
"test:schemas": "node test/test-agent-schema.js",
|
|
@@ -163,9 +163,11 @@ class ScopeContext {
|
|
|
163
163
|
* Priority: explicit > session > environment > prompt
|
|
164
164
|
* @param {string} explicitScope - Explicitly provided scope (highest priority)
|
|
165
165
|
* @param {boolean} promptIfMissing - Whether to throw if no scope found
|
|
166
|
+
* @param {object} options - Additional options
|
|
167
|
+
* @param {boolean} options.silent - Suppress warning when no scope found
|
|
166
168
|
* @returns {Promise<string|null>} Resolved scope ID
|
|
167
169
|
*/
|
|
168
|
-
async resolveScope(explicitScope = null, promptIfMissing = false) {
|
|
170
|
+
async resolveScope(explicitScope = null, promptIfMissing = false, options = {}) {
|
|
169
171
|
// 1. Explicit scope (from --scope flag or parameter)
|
|
170
172
|
if (explicitScope) {
|
|
171
173
|
return explicitScope;
|
|
@@ -185,7 +187,16 @@ class ScopeContext {
|
|
|
185
187
|
|
|
186
188
|
// 4. No scope found
|
|
187
189
|
if (promptIfMissing) {
|
|
188
|
-
throw new Error('No scope set. Use --scope flag or run: bmad scope
|
|
190
|
+
throw new Error('No scope set. Use --scope flag or run: npx bmad-fh scope set <id>');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Warn user about missing scope (unless silent mode)
|
|
194
|
+
if (!options.silent) {
|
|
195
|
+
console.warn(
|
|
196
|
+
'\u001B[33mNo scope set. Artifacts will go to root _bmad-output/ directory.\u001B[0m\n' +
|
|
197
|
+
' To use scoped artifacts, run: npx bmad-fh scope set <scope-id>\n' +
|
|
198
|
+
' Or set BMAD_SCOPE environment variable.\n',
|
|
199
|
+
);
|
|
189
200
|
}
|
|
190
201
|
|
|
191
202
|
return null;
|
|
@@ -385,7 +385,7 @@ class ScopeManager {
|
|
|
385
385
|
resolvePath(template, scopeId) {
|
|
386
386
|
return template
|
|
387
387
|
.replaceAll('{scope}', scopeId)
|
|
388
|
-
.replaceAll('{output_folder}', this.
|
|
388
|
+
.replaceAll('{output_folder}', this._config?.settings?.default_output_base || '_bmad-output');
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
/**
|
|
@@ -5,11 +5,14 @@ const yaml = require('yaml');
|
|
|
5
5
|
* @class ScopeValidator
|
|
6
6
|
*/
|
|
7
7
|
class ScopeValidator {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
// Scope ID validation pattern: lowercase alphanumeric + hyphens, 2-50 chars
|
|
9
|
+
// IMPORTANT: Must be defined as class field BEFORE constructor to be available in validateScopeId
|
|
10
|
+
scopeIdPattern = /^[a-z][a-z0-9-]*[a-z0-9]$/;
|
|
10
11
|
|
|
12
|
+
constructor() {
|
|
11
13
|
// Reserved scope IDs that cannot be used
|
|
12
|
-
|
|
14
|
+
// NOTE: 'default' removed from reserved list - it's valid for migration scenarios
|
|
15
|
+
this.reservedIds = ['_shared', '_events', '_config', '_backup', 'global'];
|
|
13
16
|
|
|
14
17
|
// Valid isolation modes
|
|
15
18
|
this.validIsolationModes = ['strict', 'warn', 'permissive'];
|
|
@@ -288,7 +291,6 @@ class ScopeValidator {
|
|
|
288
291
|
scopes: {},
|
|
289
292
|
};
|
|
290
293
|
}
|
|
291
|
-
scopeIdPattern = /^[a-z][a-z0-9-]*[a-z0-9]$/;
|
|
292
294
|
}
|
|
293
295
|
|
|
294
296
|
module.exports = { ScopeValidator };
|