bmad-fh 6.0.0-alpha.23.50b728f9 → 6.0.0-alpha.23.599980af

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.
@@ -214,9 +214,9 @@ async function testParallelScopeWorkflow() {
214
214
  projectRoot: tmpDir,
215
215
  });
216
216
 
217
- // Payments scope can read auth scope
217
+ // Payments scope can read auth scope - canRead returns {allowed, reason}
218
218
  assertTrue(
219
- resolver.canRead(path.join(tmpDir, '_bmad-output', 'auth', 'planning-artifacts', 'prd.md')),
219
+ resolver.canRead(path.join(tmpDir, '_bmad-output', 'auth', 'planning-artifacts', 'prd.md')).allowed,
220
220
  'Should allow cross-scope read',
221
221
  );
222
222
  });
@@ -229,9 +229,9 @@ async function testParallelScopeWorkflow() {
229
229
  isolationMode: 'strict',
230
230
  });
231
231
 
232
- // Payments scope cannot write to auth scope
232
+ // Payments scope cannot write to auth scope - canWrite returns {allowed, reason, warning}
233
233
  assertFalse(
234
- resolver.canWrite(path.join(tmpDir, '_bmad-output', 'auth', 'planning-artifacts', 'new.md')),
234
+ resolver.canWrite(path.join(tmpDir, '_bmad-output', 'auth', 'planning-artifacts', 'new.md')).allowed,
235
235
  'Should block cross-scope write',
236
236
  );
237
237
  });
@@ -262,19 +262,16 @@ async function testParallelScopeWorkflow() {
262
262
  await asyncTest('Sync-up promotes artifacts to shared layer', async () => {
263
263
  const sync = new ScopeSync({ projectRoot: tmpDir });
264
264
 
265
- // Create a promotable artifact (architecture.md)
266
- const archPath = path.join(tmpDir, '_bmad-output', 'auth', 'planning-artifacts', 'architecture.md');
265
+ // Create a promotable artifact matching pattern 'architecture/*.md'
266
+ const archPath = path.join(tmpDir, '_bmad-output', 'auth', 'architecture', 'overview.md');
267
267
  fs.mkdirSync(path.dirname(archPath), { recursive: true });
268
268
  fs.writeFileSync(archPath, '# Auth Architecture\n\nShared auth patterns...');
269
269
 
270
- // Create architecture directory in shared
271
- fs.mkdirSync(path.join(tmpDir, '_bmad-output', '_shared', 'auth'), { recursive: true });
272
-
273
270
  await sync.syncUp('auth');
274
271
 
275
- // Check artifact was promoted
272
+ // Check artifact was promoted to _shared/auth/architecture/overview.md
276
273
  assertFileExists(
277
- path.join(tmpDir, '_bmad-output', '_shared', 'auth', 'architecture.md'),
274
+ path.join(tmpDir, '_bmad-output', '_shared', 'auth', 'architecture', 'overview.md'),
278
275
  'Architecture should be promoted to shared',
279
276
  );
280
277
  });
@@ -284,14 +281,13 @@ async function testParallelScopeWorkflow() {
284
281
  // ========================================
285
282
  await asyncTest('Events are logged', async () => {
286
283
  const eventLogger = new EventLogger({ projectRoot: tmpDir });
284
+ await eventLogger.initialize();
287
285
 
288
- await eventLogger.log({
289
- type: 'artifact_created',
290
- scope: 'auth',
291
- artifact: 'prd.md',
292
- });
286
+ // EventLogger uses logEvent(type, scopeId, data) not log({...})
287
+ await eventLogger.logEvent('artifact_created', 'auth', { artifact: 'prd.md' });
293
288
 
294
- const events = await eventLogger.getEvents({ scope: 'auth' });
289
+ // getEvents takes (scopeId, options) not ({scope})
290
+ const events = await eventLogger.getEvents('auth');
295
291
  assertTrue(events.length > 0, 'Should have logged events');
296
292
  assertEqual(events[0].type, 'artifact_created');
297
293
  });
@@ -32,10 +32,10 @@ let passCount = 0;
32
32
  let failCount = 0;
33
33
  const failures = [];
34
34
 
35
- function test(name, fn) {
35
+ async function test(name, fn) {
36
36
  testCount++;
37
37
  try {
38
- fn();
38
+ await fn();
39
39
  passCount++;
40
40
  console.log(` ${colors.green}✓${colors.reset} ${name}`);
41
41
  } catch (error) {
@@ -102,103 +102,122 @@ function cleanupTempDir(tmpDir) {
102
102
  // ScopeValidator Tests
103
103
  // ============================================================================
104
104
 
105
- function testScopeValidator() {
105
+ async function testScopeValidator() {
106
106
  console.log(`\n${colors.blue}ScopeValidator Tests${colors.reset}`);
107
107
 
108
108
  const { ScopeValidator } = require('../src/core/lib/scope/scope-validator');
109
109
  const validator = new ScopeValidator();
110
110
 
111
- // Valid scope IDs
112
- test('validates simple scope ID', () => {
113
- assertTrue(validator.isValidScopeId('auth'), 'auth should be valid');
111
+ // Valid scope IDs - using validateScopeId which returns {valid, error}
112
+ await test('validates simple scope ID', () => {
113
+ const result = validator.validateScopeId('auth');
114
+ assertTrue(result.valid, 'auth should be valid');
114
115
  });
115
116
 
116
- test('validates hyphenated scope ID', () => {
117
- assertTrue(validator.isValidScopeId('user-service'), 'user-service should be valid');
117
+ await test('validates hyphenated scope ID', () => {
118
+ const result = validator.validateScopeId('user-service');
119
+ assertTrue(result.valid, 'user-service should be valid');
118
120
  });
119
121
 
120
- test('validates scope ID with numbers', () => {
121
- assertTrue(validator.isValidScopeId('api-v2'), 'api-v2 should be valid');
122
+ await test('validates scope ID with numbers', () => {
123
+ const result = validator.validateScopeId('api-v2');
124
+ assertTrue(result.valid, 'api-v2 should be valid');
122
125
  });
123
126
 
124
- test('validates minimum length scope ID', () => {
125
- assertTrue(validator.isValidScopeId('ab'), 'ab (2 chars) should be valid');
127
+ await test('validates minimum length scope ID', () => {
128
+ const result = validator.validateScopeId('ab');
129
+ assertTrue(result.valid, 'ab (2 chars) should be valid');
126
130
  });
127
131
 
128
132
  // Invalid scope IDs
129
- test('rejects single character scope ID', () => {
130
- assertFalse(validator.isValidScopeId('a'), 'single char should be invalid');
133
+ await test('rejects single character scope ID', () => {
134
+ const result = validator.validateScopeId('a');
135
+ assertFalse(result.valid, 'single char should be invalid');
131
136
  });
132
137
 
133
- test('rejects scope ID starting with number', () => {
134
- assertFalse(validator.isValidScopeId('1auth'), 'starting with number should be invalid');
138
+ await test('rejects scope ID starting with number', () => {
139
+ const result = validator.validateScopeId('1auth');
140
+ assertFalse(result.valid, 'starting with number should be invalid');
135
141
  });
136
142
 
137
- test('rejects scope ID with uppercase', () => {
138
- assertFalse(validator.isValidScopeId('Auth'), 'uppercase should be invalid');
143
+ await test('rejects scope ID with uppercase', () => {
144
+ const result = validator.validateScopeId('Auth');
145
+ assertFalse(result.valid, 'uppercase should be invalid');
139
146
  });
140
147
 
141
- test('rejects scope ID with underscore', () => {
142
- assertFalse(validator.isValidScopeId('user_service'), 'underscore should be invalid');
148
+ await test('rejects scope ID with underscore', () => {
149
+ const result = validator.validateScopeId('user_service');
150
+ assertFalse(result.valid, 'underscore should be invalid');
143
151
  });
144
152
 
145
- test('rejects scope ID ending with hyphen', () => {
146
- assertFalse(validator.isValidScopeId('auth-'), 'ending with hyphen should be invalid');
153
+ await test('rejects scope ID ending with hyphen', () => {
154
+ const result = validator.validateScopeId('auth-');
155
+ assertFalse(result.valid, 'ending with hyphen should be invalid');
147
156
  });
148
157
 
149
- test('rejects scope ID starting with hyphen', () => {
150
- assertFalse(validator.isValidScopeId('-auth'), 'starting with hyphen should be invalid');
158
+ await test('rejects scope ID starting with hyphen', () => {
159
+ const result = validator.validateScopeId('-auth');
160
+ assertFalse(result.valid, 'starting with hyphen should be invalid');
151
161
  });
152
162
 
153
- test('rejects scope ID with spaces', () => {
154
- assertFalse(validator.isValidScopeId('auth service'), 'spaces should be invalid');
163
+ await test('rejects scope ID with spaces', () => {
164
+ const result = validator.validateScopeId('auth service');
165
+ assertFalse(result.valid, 'spaces should be invalid');
155
166
  });
156
167
 
157
- // Reserved IDs
158
- test('rejects reserved ID _shared', () => {
159
- assertFalse(validator.isValidScopeId('_shared'), '_shared is reserved');
168
+ // Reserved IDs - note: reserved IDs like _shared start with _ which fails pattern before reserved check
169
+ await test('rejects reserved ID _shared', () => {
170
+ const result = validator.validateScopeId('_shared');
171
+ assertFalse(result.valid, '_shared should be invalid (pattern or reserved)');
160
172
  });
161
173
 
162
- test('rejects reserved ID _events', () => {
163
- assertFalse(validator.isValidScopeId('_events'), '_events is reserved');
174
+ await test('rejects reserved ID _events', () => {
175
+ const result = validator.validateScopeId('_events');
176
+ assertFalse(result.valid, '_events should be invalid (pattern or reserved)');
164
177
  });
165
178
 
166
- test('rejects reserved ID _config', () => {
167
- assertFalse(validator.isValidScopeId('_config'), '_config is reserved');
179
+ await test('rejects reserved ID _config', () => {
180
+ const result = validator.validateScopeId('_config');
181
+ assertFalse(result.valid, '_config should be invalid (pattern or reserved)');
168
182
  });
169
183
 
170
- test('rejects reserved ID global', () => {
171
- assertFalse(validator.isValidScopeId('global'), 'global is reserved');
184
+ await test('rejects reserved ID global', () => {
185
+ const result = validator.validateScopeId('global');
186
+ // 'global' matches pattern but is reserved
187
+ assertFalse(result.valid, 'global is reserved');
172
188
  });
173
189
 
174
190
  // Circular dependency detection
175
- test('detects direct circular dependency', () => {
191
+ // Note: detectCircularDependencies takes (scopeId, dependencies, allScopes) and returns {hasCircular, chain}
192
+ await test('detects direct circular dependency', () => {
176
193
  const scopes = {
177
- auth: { dependencies: ['payments'] },
178
- payments: { dependencies: ['auth'] },
194
+ auth: { id: 'auth', dependencies: ['payments'] },
195
+ payments: { id: 'payments', dependencies: ['auth'] },
179
196
  };
180
- const result = validator.detectCircularDependencies(scopes);
197
+ // Check from payments perspective - it depends on auth, which depends on payments
198
+ const result = validator.detectCircularDependencies('payments', ['auth'], scopes);
181
199
  assertTrue(result.hasCircular, 'Should detect circular dependency');
182
- assertTrue(result.cycles.length > 0, 'Should report cycles');
183
200
  });
184
201
 
185
- test('detects indirect circular dependency', () => {
202
+ await test('detects indirect circular dependency', () => {
186
203
  const scopes = {
187
- aa: { dependencies: ['bb'] },
188
- bb: { dependencies: ['cc'] },
189
- cc: { dependencies: ['aa'] },
204
+ aa: { id: 'aa', dependencies: ['bb'] },
205
+ bb: { id: 'bb', dependencies: ['cc'] },
206
+ cc: { id: 'cc', dependencies: ['aa'] },
190
207
  };
191
- const result = validator.detectCircularDependencies(scopes);
208
+ // Check from cc perspective - it depends on aa, which eventually leads back to cc
209
+ const result = validator.detectCircularDependencies('cc', ['aa'], scopes);
192
210
  assertTrue(result.hasCircular, 'Should detect indirect circular dependency');
193
211
  });
194
212
 
195
- test('accepts valid dependency graph', () => {
213
+ await test('accepts valid dependency graph', () => {
196
214
  const scopes = {
197
- auth: { dependencies: [] },
198
- payments: { dependencies: ['auth'] },
199
- orders: { dependencies: ['auth', 'payments'] },
215
+ auth: { id: 'auth', dependencies: [] },
216
+ payments: { id: 'payments', dependencies: ['auth'] },
217
+ orders: { id: 'orders', dependencies: ['auth', 'payments'] },
200
218
  };
201
- const result = validator.detectCircularDependencies(scopes);
219
+ // Check from orders perspective - no circular deps
220
+ const result = validator.detectCircularDependencies('orders', ['auth', 'payments'], scopes);
202
221
  assertFalse(result.hasCircular, 'Should not detect circular dependency');
203
222
  });
204
223
  }
@@ -207,7 +226,7 @@ function testScopeValidator() {
207
226
  // ScopeManager Tests
208
227
  // ============================================================================
209
228
 
210
- function testScopeManager() {
229
+ async function testScopeManager() {
211
230
  console.log(`\n${colors.blue}ScopeManager Tests${colors.reset}`);
212
231
 
213
232
  const { ScopeManager } = require('../src/core/lib/scope/scope-manager');
@@ -230,7 +249,7 @@ function testScopeManager() {
230
249
  }
231
250
 
232
251
  // Test initialization
233
- test('initializes scope system', async () => {
252
+ await test('initializes scope system', async () => {
234
253
  const manager = setup();
235
254
  try {
236
255
  await manager.initialize();
@@ -242,7 +261,7 @@ function testScopeManager() {
242
261
  });
243
262
 
244
263
  // Test scope creation
245
- test('creates new scope', async () => {
264
+ await test('creates new scope', async () => {
246
265
  const manager = setup();
247
266
  try {
248
267
  await manager.initialize();
@@ -255,7 +274,7 @@ function testScopeManager() {
255
274
  }
256
275
  });
257
276
 
258
- test('creates scope directory structure', async () => {
277
+ await test('creates scope directory structure', async () => {
259
278
  const manager = setup();
260
279
  try {
261
280
  await manager.initialize();
@@ -271,7 +290,7 @@ function testScopeManager() {
271
290
  }
272
291
  });
273
292
 
274
- test('rejects invalid scope ID on create', async () => {
293
+ await test('rejects invalid scope ID on create', async () => {
275
294
  const manager = setup();
276
295
  try {
277
296
  await manager.initialize();
@@ -287,7 +306,7 @@ function testScopeManager() {
287
306
  }
288
307
  });
289
308
 
290
- test('rejects duplicate scope ID', async () => {
309
+ await test('rejects duplicate scope ID', async () => {
291
310
  const manager = setup();
292
311
  try {
293
312
  await manager.initialize();
@@ -305,7 +324,7 @@ function testScopeManager() {
305
324
  });
306
325
 
307
326
  // Test scope retrieval
308
- test('retrieves scope by ID', async () => {
327
+ await test('retrieves scope by ID', async () => {
309
328
  const manager = setup();
310
329
  try {
311
330
  await manager.initialize();
@@ -320,7 +339,7 @@ function testScopeManager() {
320
339
  }
321
340
  });
322
341
 
323
- test('returns null for non-existent scope', async () => {
342
+ await test('returns null for non-existent scope', async () => {
324
343
  const manager = setup();
325
344
  try {
326
345
  await manager.initialize();
@@ -332,7 +351,7 @@ function testScopeManager() {
332
351
  });
333
352
 
334
353
  // Test scope listing
335
- test('lists all scopes', async () => {
354
+ await test('lists all scopes', async () => {
336
355
  const manager = setup();
337
356
  try {
338
357
  await manager.initialize();
@@ -346,7 +365,7 @@ function testScopeManager() {
346
365
  }
347
366
  });
348
367
 
349
- test('filters scopes by status', async () => {
368
+ await test('filters scopes by status', async () => {
350
369
  const manager = setup();
351
370
  try {
352
371
  await manager.initialize();
@@ -363,7 +382,7 @@ function testScopeManager() {
363
382
  });
364
383
 
365
384
  // Test scope update
366
- test('updates scope properties', async () => {
385
+ await test('updates scope properties', async () => {
367
386
  const manager = setup();
368
387
  try {
369
388
  await manager.initialize();
@@ -379,7 +398,7 @@ function testScopeManager() {
379
398
  });
380
399
 
381
400
  // Test scope archive/activate
382
- test('archives scope', async () => {
401
+ await test('archives scope', async () => {
383
402
  const manager = setup();
384
403
  try {
385
404
  await manager.initialize();
@@ -394,7 +413,7 @@ function testScopeManager() {
394
413
  }
395
414
  });
396
415
 
397
- test('activates archived scope', async () => {
416
+ await test('activates archived scope', async () => {
398
417
  const manager = setup();
399
418
  try {
400
419
  await manager.initialize();
@@ -411,7 +430,7 @@ function testScopeManager() {
411
430
  });
412
431
 
413
432
  // Test path resolution
414
- test('resolves scope paths', async () => {
433
+ await test('resolves scope paths', async () => {
415
434
  const manager = setup();
416
435
  try {
417
436
  await manager.initialize();
@@ -428,7 +447,7 @@ function testScopeManager() {
428
447
  });
429
448
 
430
449
  // Test dependency management
431
- test('tracks scope dependencies', async () => {
450
+ await test('tracks scope dependencies', async () => {
432
451
  const manager = setup();
433
452
  try {
434
453
  await manager.initialize();
@@ -442,7 +461,7 @@ function testScopeManager() {
442
461
  }
443
462
  });
444
463
 
445
- test('finds dependent scopes', async () => {
464
+ await test('finds dependent scopes', async () => {
446
465
  const manager = setup();
447
466
  try {
448
467
  await manager.initialize();
@@ -464,51 +483,52 @@ function testScopeManager() {
464
483
  // ArtifactResolver Tests
465
484
  // ============================================================================
466
485
 
467
- function testArtifactResolver() {
486
+ async function testArtifactResolver() {
468
487
  console.log(`\n${colors.blue}ArtifactResolver Tests${colors.reset}`);
469
488
 
470
489
  const { ArtifactResolver } = require('../src/core/lib/scope/artifact-resolver');
471
490
 
472
- test('allows read from any scope', () => {
491
+ // Note: canRead() and canWrite() return {allowed: boolean, reason: string, warning?: string}
492
+ await test('allows read from any scope', () => {
473
493
  const resolver = new ArtifactResolver({
474
494
  currentScope: 'auth',
475
495
  basePath: '_bmad-output',
476
496
  });
477
497
 
478
- assertTrue(resolver.canRead('_bmad-output/payments/planning-artifacts/prd.md'), 'Should allow cross-scope read');
479
- assertTrue(resolver.canRead('_bmad-output/auth/planning-artifacts/prd.md'), 'Should allow own-scope read');
480
- assertTrue(resolver.canRead('_bmad-output/_shared/project-context.md'), 'Should allow shared read');
498
+ assertTrue(resolver.canRead('_bmad-output/payments/planning-artifacts/prd.md').allowed, 'Should allow cross-scope read');
499
+ assertTrue(resolver.canRead('_bmad-output/auth/planning-artifacts/prd.md').allowed, 'Should allow own-scope read');
500
+ assertTrue(resolver.canRead('_bmad-output/_shared/project-context.md').allowed, 'Should allow shared read');
481
501
  });
482
502
 
483
- test('allows write to own scope', () => {
503
+ await test('allows write to own scope', () => {
484
504
  const resolver = new ArtifactResolver({
485
505
  currentScope: 'auth',
486
506
  basePath: '_bmad-output',
487
507
  });
488
508
 
489
- assertTrue(resolver.canWrite('_bmad-output/auth/planning-artifacts/prd.md'), 'Should allow own-scope write');
509
+ assertTrue(resolver.canWrite('_bmad-output/auth/planning-artifacts/prd.md').allowed, 'Should allow own-scope write');
490
510
  });
491
511
 
492
- test('blocks write to other scope in strict mode', () => {
512
+ await test('blocks write to other scope in strict mode', () => {
493
513
  const resolver = new ArtifactResolver({
494
514
  currentScope: 'auth',
495
515
  basePath: '_bmad-output',
496
516
  isolationMode: 'strict',
497
517
  });
498
518
 
499
- assertFalse(resolver.canWrite('_bmad-output/payments/planning-artifacts/prd.md'), 'Should block cross-scope write');
519
+ assertFalse(resolver.canWrite('_bmad-output/payments/planning-artifacts/prd.md').allowed, 'Should block cross-scope write');
500
520
  });
501
521
 
502
- test('blocks direct write to _shared', () => {
522
+ await test('blocks direct write to _shared', () => {
503
523
  const resolver = new ArtifactResolver({
504
524
  currentScope: 'auth',
505
525
  basePath: '_bmad-output',
506
526
  });
507
527
 
508
- assertFalse(resolver.canWrite('_bmad-output/_shared/project-context.md'), 'Should block _shared write');
528
+ assertFalse(resolver.canWrite('_bmad-output/_shared/project-context.md').allowed, 'Should block _shared write');
509
529
  });
510
530
 
511
- test('extracts scope from path', () => {
531
+ await test('extracts scope from path', () => {
512
532
  const resolver = new ArtifactResolver({
513
533
  currentScope: 'auth',
514
534
  basePath: '_bmad-output',
@@ -519,7 +539,7 @@ function testArtifactResolver() {
519
539
  assertEqual(resolver.extractScopeFromPath('_bmad-output/_shared/context.md'), '_shared');
520
540
  });
521
541
 
522
- test('throws on cross-scope write validation in strict mode', () => {
542
+ await test('throws on cross-scope write validation in strict mode', () => {
523
543
  const resolver = new ArtifactResolver({
524
544
  currentScope: 'auth',
525
545
  basePath: '_bmad-output',
@@ -529,17 +549,17 @@ function testArtifactResolver() {
529
549
  assertThrows(() => resolver.validateWrite('_bmad-output/payments/prd.md'), 'Cannot write to scope');
530
550
  });
531
551
 
532
- test('warns on cross-scope write in warn mode', () => {
552
+ await test('warns on cross-scope write in warn mode', () => {
533
553
  const resolver = new ArtifactResolver({
534
554
  currentScope: 'auth',
535
555
  basePath: '_bmad-output',
536
556
  isolationMode: 'warn',
537
557
  });
538
558
 
539
- // Should not throw in warn mode
559
+ // In warn mode, allowed should be true but warning should be set
540
560
  const result = resolver.canWrite('_bmad-output/payments/prd.md');
541
- // In warn mode, it may return true but log a warning
542
- // The exact behavior depends on implementation
561
+ assertTrue(result.allowed, 'Should allow write in warn mode');
562
+ assertTrue(result.warning !== null, 'Should have a warning message');
543
563
  });
544
564
  }
545
565
 
@@ -547,7 +567,7 @@ function testArtifactResolver() {
547
567
  // StateLock Tests
548
568
  // ============================================================================
549
569
 
550
- function testStateLock() {
570
+ async function testStateLock() {
551
571
  console.log(`\n${colors.blue}StateLock Tests${colors.reset}`);
552
572
 
553
573
  const { StateLock } = require('../src/core/lib/scope/state-lock');
@@ -565,7 +585,7 @@ function testStateLock() {
565
585
  }
566
586
  }
567
587
 
568
- test('acquires and releases lock', async () => {
588
+ await test('acquires and releases lock', async () => {
569
589
  const lock = setup();
570
590
  try {
571
591
  const lockPath = path.join(tmpDir, 'test.lock');
@@ -580,7 +600,7 @@ function testStateLock() {
580
600
  }
581
601
  });
582
602
 
583
- test('prevents concurrent access', async () => {
603
+ await test('prevents concurrent access', async () => {
584
604
  const lock = setup();
585
605
  try {
586
606
  const lockPath = path.join(tmpDir, 'test.lock');
@@ -610,7 +630,7 @@ function testStateLock() {
610
630
  }
611
631
  });
612
632
 
613
- test('detects stale locks', async () => {
633
+ await test('detects stale locks', async () => {
614
634
  const lock = setup();
615
635
  try {
616
636
  const lockPath = path.join(tmpDir, 'test.lock');
@@ -637,7 +657,7 @@ function testStateLock() {
637
657
  // ScopeContext Tests
638
658
  // ============================================================================
639
659
 
640
- function testScopeContext() {
660
+ async function testScopeContext() {
641
661
  console.log(`\n${colors.blue}ScopeContext Tests${colors.reset}`);
642
662
 
643
663
  const { ScopeContext } = require('../src/core/lib/scope/scope-context');
@@ -658,7 +678,7 @@ function testScopeContext() {
658
678
  }
659
679
  }
660
680
 
661
- test('sets session scope', async () => {
681
+ await test('sets session scope', async () => {
662
682
  const context = setup();
663
683
  try {
664
684
  // Initialize scope system first
@@ -675,7 +695,7 @@ function testScopeContext() {
675
695
  }
676
696
  });
677
697
 
678
- test('gets current scope from session', async () => {
698
+ await test('gets current scope from session', async () => {
679
699
  const context = setup();
680
700
  try {
681
701
  // Initialize scope system first
@@ -692,7 +712,7 @@ function testScopeContext() {
692
712
  }
693
713
  });
694
714
 
695
- test('clears session scope', async () => {
715
+ await test('clears session scope', async () => {
696
716
  const context = setup();
697
717
  try {
698
718
  const manager = new ScopeManager({ projectRoot: tmpDir });
@@ -709,7 +729,7 @@ function testScopeContext() {
709
729
  }
710
730
  });
711
731
 
712
- test('loads merged project context', async () => {
732
+ await test('loads merged project context', async () => {
713
733
  const context = setup();
714
734
  try {
715
735
  const manager = new ScopeManager({ projectRoot: tmpDir });
@@ -723,10 +743,10 @@ function testScopeContext() {
723
743
  fs.mkdirSync(path.join(tmpDir, '_bmad-output', 'auth'), { recursive: true });
724
744
  fs.writeFileSync(path.join(tmpDir, '_bmad-output', 'auth', 'project-context.md'), '# Auth Scope\n\nScope-specific content.');
725
745
 
726
- const merged = await context.loadProjectContext('auth');
746
+ const result = await context.loadProjectContext('auth');
727
747
 
728
- assertTrue(merged.includes('Global content'), 'Should include global content');
729
- assertTrue(merged.includes('Scope-specific content'), 'Should include scope content');
748
+ assertTrue(result.merged.includes('Global content'), 'Should include global content');
749
+ assertTrue(result.merged.includes('Scope-specific content'), 'Should include scope content');
730
750
  } finally {
731
751
  teardown();
732
752
  }