bmad-fh 6.0.0-alpha.23 → 6.0.0-alpha.23.3b00cb36

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.
@@ -6,12 +6,12 @@ const { StateLock } = require('./state-lock');
6
6
  /**
7
7
  * Logs and tracks events across scopes
8
8
  * Handles event logging and subscription notifications
9
- *
9
+ *
10
10
  * @class EventLogger
11
11
  * @requires fs-extra
12
12
  * @requires yaml
13
13
  * @requires StateLock
14
- *
14
+ *
15
15
  * @example
16
16
  * const logger = new EventLogger({ projectRoot: '/path/to/project' });
17
17
  * await logger.logEvent('artifact_created', 'auth', { artifact: 'prd.md' });
@@ -47,19 +47,19 @@ class EventLogger {
47
47
  await fs.ensureDir(this.eventsPath);
48
48
 
49
49
  // Create event-log.yaml if not exists
50
- if (!await fs.pathExists(this.eventLogPath)) {
50
+ if (!(await fs.pathExists(this.eventLogPath))) {
51
51
  const eventLog = {
52
52
  version: 1,
53
- events: []
53
+ events: [],
54
54
  };
55
55
  await fs.writeFile(this.eventLogPath, yaml.stringify(eventLog), 'utf8');
56
56
  }
57
57
 
58
58
  // Create subscriptions.yaml if not exists
59
- if (!await fs.pathExists(this.subscriptionsPath)) {
59
+ if (!(await fs.pathExists(this.subscriptionsPath))) {
60
60
  const subscriptions = {
61
61
  version: 1,
62
- subscriptions: {}
62
+ subscriptions: {},
63
63
  };
64
64
  await fs.writeFile(this.subscriptionsPath, yaml.stringify(subscriptions), 'utf8');
65
65
  }
@@ -88,7 +88,7 @@ class EventLogger {
88
88
  type,
89
89
  scope: scopeId,
90
90
  timestamp: new Date().toISOString(),
91
- data
91
+ data,
92
92
  };
93
93
 
94
94
  return this.stateLock.withLock(this.eventLogPath, async () => {
@@ -123,23 +123,23 @@ class EventLogger {
123
123
 
124
124
  // Filter by scope
125
125
  if (scopeId) {
126
- events = events.filter(e => e.scope === scopeId);
126
+ events = events.filter((e) => e.scope === scopeId);
127
127
  }
128
128
 
129
129
  // Filter by type
130
130
  if (options.type) {
131
- events = events.filter(e => e.type === options.type);
131
+ events = events.filter((e) => e.type === options.type);
132
132
  }
133
133
 
134
134
  // Filter by time range
135
135
  if (options.since) {
136
136
  const sinceDate = new Date(options.since);
137
- events = events.filter(e => new Date(e.timestamp) >= sinceDate);
137
+ events = events.filter((e) => new Date(e.timestamp) >= sinceDate);
138
138
  }
139
139
 
140
140
  if (options.until) {
141
141
  const untilDate = new Date(options.until);
142
- events = events.filter(e => new Date(e.timestamp) <= untilDate);
142
+ events = events.filter((e) => new Date(e.timestamp) <= untilDate);
143
143
  }
144
144
 
145
145
  // Limit results
@@ -169,21 +169,19 @@ class EventLogger {
169
169
  if (!subs.subscriptions[subscriberScope]) {
170
170
  subs.subscriptions[subscriberScope] = {
171
171
  watch: [],
172
- notify: true
172
+ notify: true,
173
173
  };
174
174
  }
175
175
 
176
176
  // Add or update watch entry
177
- const existingWatch = subs.subscriptions[subscriberScope].watch.find(
178
- w => w.scope === watchScope
179
- );
177
+ const existingWatch = subs.subscriptions[subscriberScope].watch.find((w) => w.scope === watchScope);
180
178
 
181
179
  if (existingWatch) {
182
180
  existingWatch.patterns = patterns;
183
181
  } else {
184
182
  subs.subscriptions[subscriberScope].watch.push({
185
183
  scope: watchScope,
186
- patterns
184
+ patterns,
187
185
  });
188
186
  }
189
187
 
@@ -206,8 +204,7 @@ class EventLogger {
206
204
  const subs = yaml.parse(content);
207
205
 
208
206
  if (subs.subscriptions[subscriberScope]) {
209
- subs.subscriptions[subscriberScope].watch =
210
- subs.subscriptions[subscriberScope].watch.filter(w => w.scope !== watchScope);
207
+ subs.subscriptions[subscriberScope].watch = subs.subscriptions[subscriberScope].watch.filter((w) => w.scope !== watchScope);
211
208
  }
212
209
 
213
210
  await fs.writeFile(this.subscriptionsPath, yaml.stringify(subs), 'utf8');
@@ -239,38 +236,34 @@ class EventLogger {
239
236
  async getPendingNotifications(scopeId, since = null) {
240
237
  try {
241
238
  const subs = await this.getSubscriptions(scopeId);
242
-
239
+
243
240
  if (!subs.notify || subs.watch.length === 0) {
244
241
  return [];
245
242
  }
246
243
 
247
244
  const notifications = [];
248
-
245
+
249
246
  for (const watch of subs.watch) {
250
247
  const events = await this.getEvents(watch.scope, {
251
- since: since || new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString() // Last 24h default
248
+ since: since || new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), // Last 24h default
252
249
  });
253
250
 
254
251
  for (const event of events) {
255
252
  // Check if event matches any pattern
256
- const matches = watch.patterns.some(pattern =>
257
- this.matchesPattern(event.data?.artifact, pattern)
258
- );
253
+ const matches = watch.patterns.some((pattern) => this.matchesPattern(event.data?.artifact, pattern));
259
254
 
260
255
  if (matches || watch.patterns.includes('*')) {
261
256
  notifications.push({
262
257
  ...event,
263
258
  watchedBy: scopeId,
264
- pattern: watch.patterns
259
+ pattern: watch.patterns,
265
260
  });
266
261
  }
267
262
  }
268
263
  }
269
264
 
270
265
  // Sort by timestamp
271
- notifications.sort((a, b) =>
272
- new Date(a.timestamp) - new Date(b.timestamp)
273
- );
266
+ notifications.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
274
267
 
275
268
  return notifications;
276
269
  } catch {
@@ -287,10 +280,8 @@ class EventLogger {
287
280
  matchesPattern(artifact, pattern) {
288
281
  if (!artifact) return false;
289
282
  if (pattern === '*') return true;
290
-
291
- const regexPattern = pattern
292
- .replaceAll('.', String.raw`\.`)
293
- .replaceAll('*', '.*');
283
+
284
+ const regexPattern = pattern.replaceAll('.', String.raw`\.`).replaceAll('*', '.*');
294
285
  const regex = new RegExp(regexPattern);
295
286
  return regex.test(artifact);
296
287
  }
@@ -309,7 +300,7 @@ class EventLogger {
309
300
  SYNC_UP: 'sync_up',
310
301
  SYNC_DOWN: 'sync_down',
311
302
  WORKFLOW_STARTED: 'workflow_started',
312
- WORKFLOW_COMPLETED: 'workflow_completed'
303
+ WORKFLOW_COMPLETED: 'workflow_completed',
313
304
  };
314
305
 
315
306
  /**
@@ -321,7 +312,7 @@ class EventLogger {
321
312
  async logArtifactCreated(scopeId, artifact, metadata = {}) {
322
313
  return this.logEvent(EventLogger.EventTypes.ARTIFACT_CREATED, scopeId, {
323
314
  artifact,
324
- ...metadata
315
+ ...metadata,
325
316
  });
326
317
  }
327
318
 
@@ -334,7 +325,7 @@ class EventLogger {
334
325
  async logArtifactUpdated(scopeId, artifact, metadata = {}) {
335
326
  return this.logEvent(EventLogger.EventTypes.ARTIFACT_UPDATED, scopeId, {
336
327
  artifact,
337
- ...metadata
328
+ ...metadata,
338
329
  });
339
330
  }
340
331
 
@@ -347,7 +338,7 @@ class EventLogger {
347
338
  async logArtifactPromoted(scopeId, artifact, sharedPath) {
348
339
  return this.logEvent(EventLogger.EventTypes.ARTIFACT_PROMOTED, scopeId, {
349
340
  artifact,
350
- shared_path: sharedPath
341
+ shared_path: sharedPath,
351
342
  });
352
343
  }
353
344
 
@@ -358,14 +349,12 @@ class EventLogger {
358
349
  * @param {object} result - Sync result
359
350
  */
360
351
  async logSync(type, scopeId, result) {
361
- const eventType = type === 'up'
362
- ? EventLogger.EventTypes.SYNC_UP
363
- : EventLogger.EventTypes.SYNC_DOWN;
364
-
352
+ const eventType = type === 'up' ? EventLogger.EventTypes.SYNC_UP : EventLogger.EventTypes.SYNC_DOWN;
353
+
365
354
  return this.logEvent(eventType, scopeId, {
366
355
  files_count: result.promoted?.length || result.pulled?.length || 0,
367
356
  conflicts_count: result.conflicts?.length || 0,
368
- errors_count: result.errors?.length || 0
357
+ errors_count: result.errors?.length || 0,
369
358
  });
370
359
  }
371
360
 
@@ -376,13 +365,13 @@ class EventLogger {
376
365
  */
377
366
  async getStats(scopeId = null) {
378
367
  const events = await this.getEvents(scopeId);
379
-
368
+
380
369
  const stats = {
381
370
  total: events.length,
382
371
  byType: {},
383
372
  byScope: {},
384
373
  last24h: 0,
385
- lastEvent: null
374
+ lastEvent: null,
386
375
  };
387
376
 
388
377
  const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
@@ -390,10 +379,10 @@ class EventLogger {
390
379
  for (const event of events) {
391
380
  // Count by type
392
381
  stats.byType[event.type] = (stats.byType[event.type] || 0) + 1;
393
-
382
+
394
383
  // Count by scope
395
384
  stats.byScope[event.scope] = (stats.byScope[event.scope] || 0) + 1;
396
-
385
+
397
386
  // Count recent
398
387
  if (new Date(event.timestamp) >= oneDayAgo) {
399
388
  stats.last24h++;
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Scope Management Module
3
- *
3
+ *
4
4
  * Provides multi-scope parallel artifact system functionality
5
5
  * for isolated development workflows.
6
- *
6
+ *
7
7
  * @module scope
8
8
  */
9
9
 
@@ -26,5 +26,5 @@ module.exports = {
26
26
  ArtifactResolver,
27
27
  StateLock,
28
28
  ScopeSync,
29
- EventLogger
29
+ EventLogger,
30
30
  };
@@ -5,11 +5,11 @@ const yaml = require('yaml');
5
5
  /**
6
6
  * Manages session-sticky scope context
7
7
  * Tracks the current active scope for workflows and agents
8
- *
8
+ *
9
9
  * @class ScopeContext
10
10
  * @requires fs-extra
11
11
  * @requires yaml
12
- *
12
+ *
13
13
  * @example
14
14
  * const context = new ScopeContext({ projectRoot: '/path/to/project' });
15
15
  * await context.setScope('auth');
@@ -40,13 +40,13 @@ class ScopeContext {
40
40
  */
41
41
  async getCurrentScope() {
42
42
  try {
43
- if (!await fs.pathExists(this.contextFilePath)) {
43
+ if (!(await fs.pathExists(this.contextFilePath))) {
44
44
  return null;
45
45
  }
46
46
 
47
47
  const content = await fs.readFile(this.contextFilePath, 'utf8');
48
48
  const context = yaml.parse(content);
49
-
49
+
50
50
  return context?.active_scope || null;
51
51
  } catch {
52
52
  return null;
@@ -63,7 +63,7 @@ class ScopeContext {
63
63
  const context = {
64
64
  active_scope: scopeId,
65
65
  set_at: new Date().toISOString(),
66
- set_by: process.env.USER || 'unknown'
66
+ set_by: process.env.USER || 'unknown',
67
67
  };
68
68
 
69
69
  await fs.writeFile(this.contextFilePath, yaml.stringify(context), 'utf8');
@@ -94,7 +94,7 @@ class ScopeContext {
94
94
  */
95
95
  async getContext() {
96
96
  try {
97
- if (!await fs.pathExists(this.contextFilePath)) {
97
+ if (!(await fs.pathExists(this.contextFilePath))) {
98
98
  return null;
99
99
  }
100
100
 
@@ -121,11 +121,11 @@ class ScopeContext {
121
121
  * @returns {Promise<object>} Merged context object
122
122
  */
123
123
  async loadProjectContext(scopeId = null) {
124
- const scope = scopeId || await this.getCurrentScope();
124
+ const scope = scopeId || (await this.getCurrentScope());
125
125
  const context = {
126
126
  global: null,
127
127
  scope: null,
128
- merged: ''
128
+ merged: '',
129
129
  };
130
130
 
131
131
  try {
@@ -137,12 +137,7 @@ class ScopeContext {
137
137
 
138
138
  // Load scope-specific context if scope is set
139
139
  if (scope) {
140
- const scopeContextPath = path.join(
141
- this.projectRoot,
142
- this.outputBase,
143
- scope,
144
- 'project-context.md'
145
- );
140
+ const scopeContextPath = path.join(this.projectRoot, this.outputBase, scope, 'project-context.md');
146
141
  if (await fs.pathExists(scopeContextPath)) {
147
142
  context.scope = await fs.readFile(scopeContextPath, 'utf8');
148
143
  }
@@ -156,7 +151,6 @@ class ScopeContext {
156
151
  } else if (context.scope) {
157
152
  context.merged = context.scope;
158
153
  }
159
-
160
154
  } catch (error) {
161
155
  throw new Error(`Failed to load project context: ${error.message}`);
162
156
  }
@@ -204,26 +198,26 @@ class ScopeContext {
204
198
  * @returns {Promise<object>} Variables object
205
199
  */
206
200
  async getScopeVariables(scopeId) {
207
- const scope = scopeId || await this.getCurrentScope();
208
-
201
+ const scope = scopeId || (await this.getCurrentScope());
202
+
209
203
  if (!scope) {
210
204
  return {
211
205
  scope: '',
212
206
  scope_path: '',
213
207
  scope_planning: '',
214
208
  scope_implementation: '',
215
- scope_tests: ''
209
+ scope_tests: '',
216
210
  };
217
211
  }
218
212
 
219
213
  const basePath = path.join(this.outputBase, scope);
220
-
214
+
221
215
  return {
222
216
  scope: scope,
223
217
  scope_path: basePath,
224
218
  scope_planning: path.join(basePath, 'planning-artifacts'),
225
219
  scope_implementation: path.join(basePath, 'implementation-artifacts'),
226
- scope_tests: path.join(basePath, 'tests')
220
+ scope_tests: path.join(basePath, 'tests'),
227
221
  };
228
222
  }
229
223
 
@@ -234,8 +228,8 @@ class ScopeContext {
234
228
  * @returns {Promise<string>} Context snippet
235
229
  */
236
230
  async createContextSnippet(scopeId) {
237
- const scope = scopeId || await this.getCurrentScope();
238
-
231
+ const scope = scopeId || (await this.getCurrentScope());
232
+
239
233
  if (!scope) {
240
234
  return '<!-- No scope context active -->';
241
235
  }
@@ -264,14 +258,14 @@ ${context.merged || 'No project context loaded.'}
264
258
  * @returns {Promise<string>} Shell export statements
265
259
  */
266
260
  async exportForShell(scopeId) {
267
- const scope = scopeId || await this.getCurrentScope();
268
-
261
+ const scope = scopeId || (await this.getCurrentScope());
262
+
269
263
  if (!scope) {
270
264
  return '# No scope set';
271
265
  }
272
266
 
273
267
  const vars = await this.getScopeVariables(scope);
274
-
268
+
275
269
  return `
276
270
  export BMAD_SCOPE="${vars.scope}"
277
271
  export BMAD_SCOPE_PATH="${vars.scope_path}"
@@ -288,12 +282,12 @@ export BMAD_SCOPE_TESTS="${vars.scope_tests}"
288
282
  */
289
283
  async updateMetadata(metadata) {
290
284
  try {
291
- const context = await this.getContext() || {};
292
-
285
+ const context = (await this.getContext()) || {};
286
+
293
287
  const updated = {
294
288
  ...context,
295
289
  ...metadata,
296
- updated_at: new Date().toISOString()
290
+ updated_at: new Date().toISOString(),
297
291
  };
298
292
 
299
293
  await fs.writeFile(this.contextFilePath, yaml.stringify(updated), 'utf8');
@@ -5,11 +5,11 @@ const yaml = require('yaml');
5
5
  /**
6
6
  * Initializes directory structure for scopes
7
7
  * Creates scope directories, shared layer, and event system
8
- *
8
+ *
9
9
  * @class ScopeInitializer
10
10
  * @requires fs-extra
11
11
  * @requires yaml
12
- *
12
+ *
13
13
  * @example
14
14
  * const initializer = new ScopeInitializer({ projectRoot: '/path/to/project' });
15
15
  * await initializer.initializeScope('auth');
@@ -70,14 +70,14 @@ class ScopeInitializer {
70
70
 
71
71
  // Create README in shared directory
72
72
  const sharedReadmePath = path.join(this.sharedPath, 'README.md');
73
- if (!await fs.pathExists(sharedReadmePath)) {
73
+ if (!(await fs.pathExists(sharedReadmePath))) {
74
74
  const readmeContent = this.generateSharedReadme();
75
75
  await fs.writeFile(sharedReadmePath, readmeContent, 'utf8');
76
76
  }
77
77
 
78
78
  // Create global project-context.md template
79
79
  const contextPath = path.join(this.sharedPath, 'project-context.md');
80
- if (!await fs.pathExists(contextPath)) {
80
+ if (!(await fs.pathExists(contextPath))) {
81
81
  const contextContent = this.generateGlobalContextTemplate();
82
82
  await fs.writeFile(contextPath, contextContent, 'utf8');
83
83
  }
@@ -100,20 +100,20 @@ class ScopeInitializer {
100
100
 
101
101
  // Create event-log.yaml
102
102
  const eventLogPath = path.join(this.eventsPath, 'event-log.yaml');
103
- if (!await fs.pathExists(eventLogPath)) {
103
+ if (!(await fs.pathExists(eventLogPath))) {
104
104
  const eventLog = {
105
105
  version: 1,
106
- events: []
106
+ events: [],
107
107
  };
108
108
  await fs.writeFile(eventLogPath, yaml.stringify(eventLog), 'utf8');
109
109
  }
110
110
 
111
111
  // Create subscriptions.yaml
112
112
  const subscriptionsPath = path.join(this.eventsPath, 'subscriptions.yaml');
113
- if (!await fs.pathExists(subscriptionsPath)) {
113
+ if (!(await fs.pathExists(subscriptionsPath))) {
114
114
  const subscriptions = {
115
115
  version: 1,
116
- subscriptions: {}
116
+ subscriptions: {},
117
117
  };
118
118
  await fs.writeFile(subscriptionsPath, yaml.stringify(subscriptions), 'utf8');
119
119
  }
@@ -135,10 +135,8 @@ class ScopeInitializer {
135
135
  const scopePath = path.join(this.outputPath, scopeId);
136
136
 
137
137
  // Check if scope directory already exists
138
- if (await fs.pathExists(scopePath)) {
139
- if (!options.force) {
140
- throw new Error(`Scope directory '${scopeId}' already exists. Use force option to recreate.`);
141
- }
138
+ if ((await fs.pathExists(scopePath)) && !options.force) {
139
+ throw new Error(`Scope directory '${scopeId}' already exists. Use force option to recreate.`);
142
140
  }
143
141
 
144
142
  // Create scope directory structure
@@ -147,7 +145,7 @@ class ScopeInitializer {
147
145
  planning: path.join(scopePath, 'planning-artifacts'),
148
146
  implementation: path.join(scopePath, 'implementation-artifacts'),
149
147
  tests: path.join(scopePath, 'tests'),
150
- meta: path.join(scopePath, '.scope-meta.yaml')
148
+ meta: path.join(scopePath, '.scope-meta.yaml'),
151
149
  };
152
150
 
153
151
  // Create directories
@@ -163,14 +161,14 @@ class ScopeInitializer {
163
161
  structure: {
164
162
  planning_artifacts: 'planning-artifacts/',
165
163
  implementation_artifacts: 'implementation-artifacts/',
166
- tests: 'tests/'
167
- }
164
+ tests: 'tests/',
165
+ },
168
166
  };
169
167
  await fs.writeFile(paths.meta, yaml.stringify(metadata), 'utf8');
170
168
 
171
169
  // Create README in scope directory
172
170
  const readmePath = path.join(scopePath, 'README.md');
173
- if (!await fs.pathExists(readmePath)) {
171
+ if (!(await fs.pathExists(readmePath))) {
174
172
  const readmeContent = this.generateScopeReadme(scopeId, options);
175
173
  await fs.writeFile(readmePath, readmeContent, 'utf8');
176
174
  }
@@ -199,7 +197,7 @@ class ScopeInitializer {
199
197
  const scopePath = path.join(this.outputPath, scopeId);
200
198
 
201
199
  // Check if scope exists
202
- if (!await fs.pathExists(scopePath)) {
200
+ if (!(await fs.pathExists(scopePath))) {
203
201
  throw new Error(`Scope directory '${scopeId}' does not exist`);
204
202
  }
205
203
 
@@ -251,7 +249,7 @@ class ScopeInitializer {
251
249
  implementation: path.join(scopePath, 'implementation-artifacts'),
252
250
  tests: path.join(scopePath, 'tests'),
253
251
  meta: path.join(scopePath, '.scope-meta.yaml'),
254
- context: path.join(scopePath, 'project-context.md')
252
+ context: path.join(scopePath, 'project-context.md'),
255
253
  };
256
254
  }
257
255
 
@@ -281,9 +279,9 @@ The shared layer enables:
281
279
 
282
280
  ## Usage
283
281
 
284
- 1. **Reading**: All scopes can read from \\`_shared/\\`
285
- 2. **Writing**: Use \\`bmad scope sync-up <scope>\\` to promote artifacts
286
- 3. **Syncing**: Use \\`bmad scope sync-down <scope>\\` to pull updates
282
+ 1. **Reading**: All scopes can read from \`_shared/\`
283
+ 2. **Writing**: Use \`bmad scope sync-up <scope>\` to promote artifacts
284
+ 3. **Syncing**: Use \`bmad scope sync-down <scope>\` to pull updates
287
285
 
288
286
  ## Best Practices
289
287
 
@@ -368,16 +366,14 @@ ${description}
368
366
 
369
367
  ## Scope Information
370
368
 
371
- - **ID:** \\`${scopeId}\\`
369
+ - **ID:** ${scopeId}
372
370
  - **Name:** ${scopeName}
373
371
  - **Status:** ${options.status || 'active'}
374
372
  - **Created:** ${new Date().toISOString().split('T')[0]}
375
373
 
376
374
  ## Dependencies
377
375
 
378
- ${options.dependencies && options.dependencies.length > 0
379
- ? options.dependencies.map(dep => `- \\`${dep}\\``).join('\n')
380
- : 'No dependencies'}
376
+ ${options.dependencies && options.dependencies.length > 0 ? options.dependencies.map((dep) => `- ${dep}`).join('\n') : 'No dependencies'}
381
377
 
382
378
  ## Usage
383
379
 
@@ -403,8 +399,8 @@ bmad scope sync-down ${scopeId}
403
399
 
404
400
  ## Related Documentation
405
401
 
406
- - Global context: \\`../_shared/project-context.md\\`
407
- - Contracts: \\`../_shared/contracts/\\`
402
+ - Global context: ../_shared/project-context.md
403
+ - Contracts: ../_shared/contracts/
408
404
  `;
409
405
  }
410
406
 
@@ -419,7 +415,7 @@ bmad scope sync-down ${scopeId}
419
415
 
420
416
  return `# Scope Context: ${scopeName}
421
417
 
422
- > This context extends the global project context in \\`../_shared/project-context.md\\`
418
+ > This context extends the global project context in ../_shared/project-context.md
423
419
 
424
420
  ## Scope Purpose
425
421
 
@@ -436,9 +432,11 @@ bmad scope sync-down ${scopeId}
436
432
  ## Integration Points
437
433
 
438
434
  ### Dependencies
439
- ${options.dependencies && options.dependencies.length > 0
440
- ? options.dependencies.map(dep => `- **${dep}**: [Describe dependency relationship]`).join('\n')
441
- : 'No dependencies'}
435
+ ${
436
+ options.dependencies && options.dependencies.length > 0
437
+ ? options.dependencies.map((dep) => `- **${dep}**: [Describe dependency relationship]`).join('\n')
438
+ : 'No dependencies'
439
+ }
442
440
 
443
441
  ### Provides
444
442
  [What this scope provides to other scopes]