@hyperdrive.bot/bmad-workflow 1.0.2

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.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1017 -0
  3. package/bin/dev +5 -0
  4. package/bin/dev.cmd +3 -0
  5. package/bin/dev.js +5 -0
  6. package/bin/run +5 -0
  7. package/bin/run.cmd +3 -0
  8. package/bin/run.js +5 -0
  9. package/dist/commands/config/show.d.ts +34 -0
  10. package/dist/commands/config/show.js +108 -0
  11. package/dist/commands/config/validate.d.ts +29 -0
  12. package/dist/commands/config/validate.js +131 -0
  13. package/dist/commands/decompose.d.ts +79 -0
  14. package/dist/commands/decompose.js +327 -0
  15. package/dist/commands/demo.d.ts +18 -0
  16. package/dist/commands/demo.js +107 -0
  17. package/dist/commands/epics/create.d.ts +123 -0
  18. package/dist/commands/epics/create.js +459 -0
  19. package/dist/commands/epics/list.d.ts +120 -0
  20. package/dist/commands/epics/list.js +280 -0
  21. package/dist/commands/hello/index.d.ts +12 -0
  22. package/dist/commands/hello/index.js +34 -0
  23. package/dist/commands/hello/world.d.ts +8 -0
  24. package/dist/commands/hello/world.js +24 -0
  25. package/dist/commands/prd/fix.d.ts +39 -0
  26. package/dist/commands/prd/fix.js +140 -0
  27. package/dist/commands/prd/validate.d.ts +112 -0
  28. package/dist/commands/prd/validate.js +302 -0
  29. package/dist/commands/stories/create.d.ts +95 -0
  30. package/dist/commands/stories/create.js +431 -0
  31. package/dist/commands/stories/develop.d.ts +91 -0
  32. package/dist/commands/stories/develop.js +460 -0
  33. package/dist/commands/stories/list.d.ts +84 -0
  34. package/dist/commands/stories/list.js +291 -0
  35. package/dist/commands/stories/move.d.ts +66 -0
  36. package/dist/commands/stories/move.js +273 -0
  37. package/dist/commands/stories/qa.d.ts +99 -0
  38. package/dist/commands/stories/qa.js +530 -0
  39. package/dist/commands/workflow.d.ts +97 -0
  40. package/dist/commands/workflow.js +390 -0
  41. package/dist/index.d.ts +1 -0
  42. package/dist/index.js +1 -0
  43. package/dist/models/agent-options.d.ts +50 -0
  44. package/dist/models/agent-options.js +1 -0
  45. package/dist/models/agent-result.d.ts +29 -0
  46. package/dist/models/agent-result.js +1 -0
  47. package/dist/models/index.d.ts +10 -0
  48. package/dist/models/index.js +10 -0
  49. package/dist/models/phase-result.d.ts +65 -0
  50. package/dist/models/phase-result.js +7 -0
  51. package/dist/models/provider.d.ts +28 -0
  52. package/dist/models/provider.js +18 -0
  53. package/dist/models/story.d.ts +154 -0
  54. package/dist/models/story.js +18 -0
  55. package/dist/models/workflow-config.d.ts +148 -0
  56. package/dist/models/workflow-config.js +1 -0
  57. package/dist/models/workflow-result.d.ts +164 -0
  58. package/dist/models/workflow-result.js +7 -0
  59. package/dist/services/agents/agent-runner-factory.d.ts +31 -0
  60. package/dist/services/agents/agent-runner-factory.js +44 -0
  61. package/dist/services/agents/agent-runner.d.ts +46 -0
  62. package/dist/services/agents/agent-runner.js +29 -0
  63. package/dist/services/agents/claude-agent-runner.d.ts +81 -0
  64. package/dist/services/agents/claude-agent-runner.js +332 -0
  65. package/dist/services/agents/gemini-agent-runner.d.ts +82 -0
  66. package/dist/services/agents/gemini-agent-runner.js +350 -0
  67. package/dist/services/agents/index.d.ts +7 -0
  68. package/dist/services/agents/index.js +7 -0
  69. package/dist/services/file-system/file-manager.d.ts +110 -0
  70. package/dist/services/file-system/file-manager.js +223 -0
  71. package/dist/services/file-system/glob-matcher.d.ts +75 -0
  72. package/dist/services/file-system/glob-matcher.js +126 -0
  73. package/dist/services/file-system/path-resolver.d.ts +183 -0
  74. package/dist/services/file-system/path-resolver.js +400 -0
  75. package/dist/services/logging/workflow-logger.d.ts +232 -0
  76. package/dist/services/logging/workflow-logger.js +552 -0
  77. package/dist/services/orchestration/batch-processor.d.ts +113 -0
  78. package/dist/services/orchestration/batch-processor.js +187 -0
  79. package/dist/services/orchestration/dependency-graph-executor.d.ts +60 -0
  80. package/dist/services/orchestration/dependency-graph-executor.js +447 -0
  81. package/dist/services/orchestration/index.d.ts +10 -0
  82. package/dist/services/orchestration/index.js +8 -0
  83. package/dist/services/orchestration/input-detector.d.ts +125 -0
  84. package/dist/services/orchestration/input-detector.js +381 -0
  85. package/dist/services/orchestration/story-queue.d.ts +94 -0
  86. package/dist/services/orchestration/story-queue.js +170 -0
  87. package/dist/services/orchestration/story-type-detector.d.ts +80 -0
  88. package/dist/services/orchestration/story-type-detector.js +258 -0
  89. package/dist/services/orchestration/task-decomposition-service.d.ts +67 -0
  90. package/dist/services/orchestration/task-decomposition-service.js +607 -0
  91. package/dist/services/orchestration/workflow-orchestrator.d.ts +659 -0
  92. package/dist/services/orchestration/workflow-orchestrator.js +2201 -0
  93. package/dist/services/parsers/epic-parser.d.ts +117 -0
  94. package/dist/services/parsers/epic-parser.js +264 -0
  95. package/dist/services/parsers/prd-fixer.d.ts +86 -0
  96. package/dist/services/parsers/prd-fixer.js +194 -0
  97. package/dist/services/parsers/prd-parser.d.ts +123 -0
  98. package/dist/services/parsers/prd-parser.js +286 -0
  99. package/dist/services/parsers/standalone-story-parser.d.ts +114 -0
  100. package/dist/services/parsers/standalone-story-parser.js +255 -0
  101. package/dist/services/parsers/story-parser-factory.d.ts +81 -0
  102. package/dist/services/parsers/story-parser-factory.js +108 -0
  103. package/dist/services/parsers/story-parser.d.ts +122 -0
  104. package/dist/services/parsers/story-parser.js +262 -0
  105. package/dist/services/scaffolding/decompose-session-scaffolder.d.ts +74 -0
  106. package/dist/services/scaffolding/decompose-session-scaffolder.js +315 -0
  107. package/dist/services/scaffolding/file-scaffolder.d.ts +94 -0
  108. package/dist/services/scaffolding/file-scaffolder.js +314 -0
  109. package/dist/services/validation/config-validator.d.ts +88 -0
  110. package/dist/services/validation/config-validator.js +167 -0
  111. package/dist/types/task-graph.d.ts +142 -0
  112. package/dist/types/task-graph.js +5 -0
  113. package/dist/utils/colors.d.ts +49 -0
  114. package/dist/utils/colors.js +50 -0
  115. package/dist/utils/error-formatter.d.ts +64 -0
  116. package/dist/utils/error-formatter.js +279 -0
  117. package/dist/utils/errors.d.ts +170 -0
  118. package/dist/utils/errors.js +233 -0
  119. package/dist/utils/formatters.d.ts +84 -0
  120. package/dist/utils/formatters.js +162 -0
  121. package/dist/utils/logger.d.ts +63 -0
  122. package/dist/utils/logger.js +78 -0
  123. package/dist/utils/progress.d.ts +104 -0
  124. package/dist/utils/progress.js +161 -0
  125. package/dist/utils/retry.d.ts +114 -0
  126. package/dist/utils/retry.js +160 -0
  127. package/dist/utils/shared-flags.d.ts +28 -0
  128. package/dist/utils/shared-flags.js +43 -0
  129. package/package.json +119 -0
@@ -0,0 +1,659 @@
1
+ /**
2
+ * WorkflowOrchestrator Service
3
+ *
4
+ * Coordinates the complete PRD → Epic → Story → Dev workflow with automatic
5
+ * input detection, conditional phase execution, and comprehensive result tracking.
6
+ *
7
+ * Responsibilities:
8
+ * - Detect input type (PRD, epic, or story pattern)
9
+ * - Execute phases conditionally based on skip flags and input type
10
+ * - Coordinate between PrdParser, EpicParser, and ClaudeAgentRunner
11
+ * - Track phase results with success/failure counts and durations
12
+ * - Handle cross-phase errors gracefully (fail early if critical phase fails)
13
+ * - Aggregate results across all phases into WorkflowResult
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const logger = createLogger({ namespace: 'orchestrator' })
18
+ * const orchestrator = new WorkflowOrchestrator({
19
+ * inputDetector,
20
+ * prdParser,
21
+ * epicParser,
22
+ * agentRunner: claudeRunner,
23
+ * batchProcessor,
24
+ * fileManager,
25
+ * pathResolver,
26
+ * storyTypeDetector,
27
+ * logger,
28
+ * })
29
+ *
30
+ * const result = await orchestrator.execute({
31
+ * input: 'docs/PRD-feature.md',
32
+ * prdInterval: 60,
33
+ * epicInterval: 60,
34
+ * storyInterval: 60,
35
+ * parallel: 3,
36
+ * prefix: 'PROJ-123',
37
+ * references: [],
38
+ * skipEpics: false,
39
+ * skipStories: false,
40
+ * skipDev: false,
41
+ * dryRun: false,
42
+ * verbose: false
43
+ * })
44
+ * ```
45
+ */
46
+ import type pino from 'pino';
47
+ import type { InputDetectionResult, WorkflowConfig, WorkflowResult } from '../../models/index.js';
48
+ import type { AIProviderRunner } from '../agents/agent-runner.js';
49
+ import type { WorkflowLogger } from '../logging/workflow-logger.js';
50
+ import { FileManager } from '../file-system/file-manager.js';
51
+ import { PathResolver } from '../file-system/path-resolver.js';
52
+ import { EpicParser } from '../parsers/epic-parser.js';
53
+ import { PrdParser } from '../parsers/prd-parser.js';
54
+ import { BatchProcessor } from './batch-processor.js';
55
+ import { StoryTypeDetector } from './story-type-detector.js';
56
+ /**
57
+ * InputDetector interface (to be implemented in Story 4.2)
58
+ *
59
+ * Detects the type of input file (PRD, epic, or story pattern)
60
+ * to determine which phase the workflow should start from.
61
+ */
62
+ export interface InputDetector {
63
+ /**
64
+ * Detect the type of input file
65
+ *
66
+ * @param input - Input file path or pattern
67
+ * @returns Detection result with type, file path, and metadata
68
+ */
69
+ detect(input: string): Promise<InputDetectionResult>;
70
+ }
71
+ /**
72
+ * Configuration object for WorkflowOrchestrator constructor
73
+ *
74
+ * Groups all service dependencies into a single configuration object
75
+ * to reduce constructor parameter count and improve maintainability.
76
+ */
77
+ export interface WorkflowOrchestratorConfig {
78
+ /** Service to execute AI agents (Claude or Gemini) */
79
+ agentRunner: AIProviderRunner;
80
+ /** Service to handle parallel batch processing */
81
+ batchProcessor: BatchProcessor;
82
+ /** Service to parse epic files and extract stories */
83
+ epicParser: EpicParser;
84
+ /** Service for file system operations */
85
+ fileManager: FileManager;
86
+ /** Service to detect input file type (PRD, epic, or story pattern) */
87
+ inputDetector: InputDetector;
88
+ /** Logger instance for structured logging */
89
+ logger: pino.Logger;
90
+ /** Service to resolve file paths from config */
91
+ pathResolver: PathResolver;
92
+ /** Service to parse PRD files and extract epics */
93
+ prdParser: PrdParser;
94
+ /** Service to detect story type for auto-documentation */
95
+ storyTypeDetector: StoryTypeDetector;
96
+ /** Optional WorkflowLogger for pipeline progress tracking */
97
+ workflowLogger?: WorkflowLogger;
98
+ }
99
+ /**
100
+ * Options for building an epic creation prompt
101
+ */
102
+ export interface EpicPromptOptions {
103
+ /** Working directory (optional) */
104
+ cwd?: string;
105
+ /** Output file path */
106
+ outputPath: string;
107
+ /** Path to PRD file */
108
+ prdPath: string;
109
+ /** File name prefix */
110
+ prefix: string;
111
+ /** Reference file paths */
112
+ references: string[];
113
+ }
114
+ /**
115
+ * Options for building a story creation prompt
116
+ */
117
+ export interface StoryPromptOptions {
118
+ /** Working directory (optional) */
119
+ cwd?: string;
120
+ /** Path to epic file */
121
+ epicPath: string;
122
+ /** Output file path */
123
+ outputPath: string;
124
+ /** File name prefix */
125
+ prefix: string;
126
+ /** Reference file paths */
127
+ references: string[];
128
+ }
129
+ /**
130
+ * WorkflowOrchestrator service for coordinating multi-phase workflows
131
+ *
132
+ * Orchestrates the complete workflow from PRD to development, executing
133
+ * phases conditionally based on input type and skip flags. Tracks results
134
+ * and handles cross-phase errors gracefully.
135
+ */
136
+ export declare class WorkflowOrchestrator {
137
+ private readonly agentRunner;
138
+ private readonly batchProcessor;
139
+ private readonly epicParser;
140
+ private readonly fileManager;
141
+ private readonly fileScaffolder;
142
+ private readonly inputDetector;
143
+ private readonly logger;
144
+ private readonly pathResolver;
145
+ private readonly prdFixer;
146
+ private readonly prdParser;
147
+ private readonly storyTypeDetector;
148
+ private readonly workflowLogger?;
149
+ /**
150
+ * Create a new WorkflowOrchestrator instance
151
+ *
152
+ * @param config - Configuration object containing all service dependencies
153
+ */
154
+ constructor(config: WorkflowOrchestratorConfig);
155
+ /**
156
+ * Execute the complete workflow
157
+ *
158
+ * Detects input type, executes phases conditionally based on skip flags
159
+ * and input type, tracks results, and handles cross-phase errors.
160
+ *
161
+ * @param config - Workflow configuration
162
+ * @returns WorkflowResult with all phase results and aggregate metrics
163
+ * @throws {ValidationError} If configuration is invalid
164
+ */
165
+ execute(config: WorkflowConfig): Promise<WorkflowResult>;
166
+ /**
167
+ * Build prompt for epic creation
168
+ *
169
+ * @param epic - Epic to create
170
+ * @param options - Prompt configuration options
171
+ * @returns Agent prompt
172
+ * @private
173
+ */
174
+ private buildEpicPrompt;
175
+ /**
176
+ * Build failure result when epic phase fails completely
177
+ *
178
+ * @param startTime - Workflow start time
179
+ * @param epicPhase - Failed epic phase result
180
+ * @returns WorkflowResult
181
+ * @private
182
+ */
183
+ private buildFailureResult;
184
+ /**
185
+ * Build prompt for story creation
186
+ *
187
+ * @param story - Story to create
188
+ * @param options - Prompt configuration options
189
+ * @returns Agent prompt
190
+ * @private
191
+ */
192
+ private buildStoryPrompt;
193
+ /**
194
+ * Build success result with all phase results
195
+ *
196
+ * @param startTime - Workflow start time
197
+ * @param epicPhase - Epic phase result
198
+ * @param storyPhase - Story phase result
199
+ * @param devPhase - Dev phase result
200
+ * @param qaPhase - QA phase result
201
+ * @returns WorkflowResult
202
+ * @private
203
+ */
204
+ private buildSuccessResult;
205
+ /**
206
+ * Check which files already exist in a directory
207
+ *
208
+ * @param directory - Directory to check
209
+ * @param fileNames - List of file names to check
210
+ * @returns List of existing file names
211
+ * @private
212
+ */
213
+ private checkExistingFiles;
214
+ /**
215
+ * Check which story files already exist across all story directories
216
+ *
217
+ * Checks docs/stories, docs/qa/stories, and docs/done/stories to prevent
218
+ * recreating stories that have been moved for QA or marked as done.
219
+ *
220
+ * Stories found in docs/qa/stories or docs/done/stories are considered completed
221
+ * and are skipped, allowing the workflow to continue with the next story number
222
+ * in docs/stories.
223
+ *
224
+ * @param fileNames - List of story file names to check
225
+ * @returns List of existing file names that should be skipped
226
+ * @private
227
+ */
228
+ private checkExistingStoryFiles;
229
+ /**
230
+ * Check if epic files are properly populated (not just scaffolded)
231
+ *
232
+ * @param directory - Directory containing epic files
233
+ * @param fileNames - List of file names to check
234
+ * @returns List of properly populated file names
235
+ * @private
236
+ */
237
+ private checkProperlyPopulatedEpics;
238
+ /**
239
+ * Create a skipped phase result
240
+ *
241
+ * @param phaseName - Name of the phase
242
+ * @returns PhaseResult marked as skipped
243
+ * @private
244
+ */
245
+ private createSkippedPhaseResult;
246
+ /**
247
+ * Detect input type using InputDetector
248
+ *
249
+ * @param input - Input file path or pattern
250
+ * @returns Input detection result
251
+ * @throws {ValidationError} If input is invalid or cannot be detected
252
+ * @private
253
+ */
254
+ private detectInput;
255
+ /**
256
+ * Determine which phases should execute based on input type and skip flags
257
+ *
258
+ * @param detection - Input detection result
259
+ * @param config - Workflow configuration
260
+ * @returns Object with boolean flags for each phase
261
+ * @private
262
+ */
263
+ private determinePhaseExecution;
264
+ /**
265
+ * Individual worker function for processing stories from the queue
266
+ *
267
+ * Continuously dequeues stories and processes them until the queue is closed and empty.
268
+ * Handles errors gracefully without crashing the worker pool.
269
+ *
270
+ * @param workerId - Unique identifier for this worker (for logging)
271
+ * @param queue - StoryQueue to dequeue stories from
272
+ * @param config - Workflow configuration
273
+ * @returns Worker result with success count and failures
274
+ * @private
275
+ */
276
+ /**
277
+ * Dev worker that consumes stories from the queue and processes them concurrently.
278
+ *
279
+ * Worker loop algorithm:
280
+ * 1. Dequeue next story (blocks/waits if queue empty)
281
+ * 2. If null returned, queue is closed and empty → terminate worker
282
+ * 3. For each story:
283
+ * - Check if already in QA folder (skip if developed)
284
+ * - Update story status to InProgress
285
+ * - Execute dev agent with context
286
+ * - On success: Update status to Done, move to QA
287
+ * - On failure: Log error, continue to next story
288
+ * - Respect story interval delay
289
+ * 4. Return aggregate success count and failures
290
+ *
291
+ * @param workerId - Worker identifier for logging and tracking (0-based index)
292
+ * @param queue - StoryQueue to dequeue stories from
293
+ * @param config - Workflow configuration with intervals and references
294
+ * @returns Promise resolving to object with success count and failure array
295
+ * @private
296
+ */
297
+ private devWorker;
298
+ /**
299
+ * Enqueue existing stories sequentially for pipeline mode
300
+ *
301
+ * This method MUST process stories sequentially (not in parallel) to preserve
302
+ * story order in the queue. The development phase processes stories in order,
303
+ * so we must maintain that order when enqueuing existing stories.
304
+ *
305
+ * @param stories - List of stories to enqueue
306
+ * @param storyDir - Story directory path
307
+ * @param prefix - File name prefix
308
+ * @param onStoryComplete - Callback to enqueue each story
309
+ * @private
310
+ */
311
+ private enqueueExistingStoriesSequentially;
312
+ /**
313
+ * Execute development phase
314
+ *
315
+ * Executes story development sequentially using ClaudeAgentRunner.
316
+ * Updates story status and moves completed stories to QA folder.
317
+ *
318
+ * @param config - Workflow configuration
319
+ * @param stories - List of stories to develop
320
+ * @returns PhaseResult with success count, failures, and duration
321
+ * @private
322
+ */
323
+ private executeDevelopmentPhase;
324
+ /**
325
+ * Execute epic creation phase
326
+ *
327
+ * Parses PRD file, extracts epics, and creates epic markdown files
328
+ * using ClaudeAgentRunner and BatchProcessor.
329
+ *
330
+ * @param config - Workflow configuration
331
+ * @param prdFilePath - Path to PRD file
332
+ * @returns PhaseResult with success count, failures, and duration
333
+ * @private
334
+ */
335
+ private executeEpicPhase;
336
+ /**
337
+ * Execute epic phase if needed
338
+ *
339
+ * @param config - Workflow configuration
340
+ * @param detection - Input detection result
341
+ * @param shouldExecute - Whether to execute epic phase
342
+ * @returns Epic phase result or skipped result
343
+ * @private
344
+ */
345
+ private executeEpicPhaseIfNeeded;
346
+ /**
347
+ * Execute pipelined development phase
348
+ *
349
+ * Executes story development using concurrent workers that consume from a StoryQueue.
350
+ * Each worker dequeues stories, executes dev work, and updates story status independently.
351
+ * Workers terminate when the queue is closed and empty.
352
+ *
353
+ * @param queue - StoryQueue to consume stories from
354
+ * @param config - Workflow configuration
355
+ * @returns PhaseResult with aggregated success count, failures, and duration
356
+ * @private
357
+ */
358
+ /**
359
+ * Execute pipelined development phase with worker pool.
360
+ *
361
+ * Pipeline coordination algorithm:
362
+ * 1. Create worker pool of size config.parallel (default: 3 workers)
363
+ * 2. Each worker independently dequeues from StoryQueue
364
+ * 3. Workers run concurrently using Promise.all
365
+ * 4. Natural load balancing via FIFO queue
366
+ * 5. Workers terminate when queue closed and empty
367
+ * 6. Aggregate results from all workers
368
+ *
369
+ * Performance characteristics:
370
+ * - Concurrent story development (up to N workers processing simultaneously)
371
+ * - Queue-based coordination for thread-safe handoff
372
+ * - No worker starvation due to FIFO fairness
373
+ * - Graceful completion when story phase closes queue
374
+ *
375
+ * @param queue - StoryQueue for consuming completed stories
376
+ * @param config - Workflow configuration with worker count and intervals
377
+ * @returns PhaseResult with aggregate success/failure counts and duration
378
+ * @private
379
+ */
380
+ private executePipelinedDevPhase;
381
+ /**
382
+ * Execute pipelined workflow (story and dev phases in parallel)
383
+ *
384
+ * @param config - Workflow configuration
385
+ * @param detection - Input detection result
386
+ * @returns Story and dev phase results
387
+ * @private
388
+ */
389
+ private executePipelinedWorkflow;
390
+ /**
391
+ * Execute QA phase
392
+ *
393
+ * Runs QA workflow on all stories in the QA folder.
394
+ * Dynamically imports and delegates to StoriesQaCommand.
395
+ *
396
+ * @param config - Workflow configuration
397
+ * @returns PhaseResult with success count, failures, and duration
398
+ * @private
399
+ */
400
+ private executeQaPhase;
401
+ /**
402
+ * Execute QA phase if needed
403
+ *
404
+ * @param config - Workflow configuration
405
+ * @param devPhase - Dev phase result
406
+ * @param shouldExecute - Whether to execute QA phase
407
+ * @returns QA phase result
408
+ * @private
409
+ */
410
+ private executeQaPhaseIfNeeded;
411
+ /**
412
+ * Execute dev phase in sequential mode
413
+ *
414
+ * @param config - Workflow configuration
415
+ * @param detection - Input detection result
416
+ * @param shouldExecute - Whether to execute dev phase
417
+ * @returns Dev phase result
418
+ * @private
419
+ */
420
+ private executeSequentialDevPhase;
421
+ /**
422
+ * Execute story phase in sequential mode
423
+ *
424
+ * @param config - Workflow configuration
425
+ * @param detection - Input detection result
426
+ * @param epicPhase - Epic phase result
427
+ * @param startTime - Workflow start time
428
+ * @returns Story phase result
429
+ * @private
430
+ */
431
+ private executeSequentialStoryPhase;
432
+ /**
433
+ * Execute sequential workflow (phases one after another)
434
+ *
435
+ * @param config - Workflow configuration
436
+ * @param detection - Input detection result
437
+ * @param epicPhase - Epic phase result
438
+ * @param phaseFlags - Phase execution flags
439
+ * @param startTime - Workflow start time
440
+ * @returns Story and dev phase results
441
+ * @private
442
+ */
443
+ private executeSequentialWorkflow;
444
+ /**
445
+ * Execute story and dev phases (pipelined or sequential)
446
+ *
447
+ * @param config - Workflow configuration
448
+ * @param detection - Input detection result
449
+ * @param epicPhase - Epic phase result
450
+ * @param phaseFlags - Phase execution flags
451
+ * @param startTime - Workflow start time
452
+ * @returns Story and dev phase results
453
+ * @private
454
+ */
455
+ private executeStoryAndDevPhases;
456
+ /**
457
+ * Execute story creation phase
458
+ *
459
+ * Parses epic files, extracts stories, and creates story markdown files
460
+ * using ClaudeAgentRunner and BatchProcessor.
461
+ *
462
+ * @param config - Workflow configuration
463
+ * @param epics - List of epics to extract stories from
464
+ * @param onStoryComplete - Optional callback invoked after each story is successfully created
465
+ * @returns PhaseResult with success count, failures, and duration
466
+ * @private
467
+ */
468
+ private executeStoryPhase;
469
+ /**
470
+ * Execute story phase from a single epic file
471
+ *
472
+ * Parses stories from a specific epic file and creates story files.
473
+ *
474
+ * @param config - Workflow configuration
475
+ * @param epicFilePath - Path to the epic file
476
+ * @param onStoryComplete - Optional callback invoked after each story is successfully created
477
+ * @returns PhaseResult with success count, failures, and duration
478
+ * @private
479
+ */
480
+ private executeStoryPhaseFromEpicFile;
481
+ /**
482
+ * Execute story phase with queue integration for pipelined workflow
483
+ *
484
+ * Wraps story phase execution and enqueues completed stories to the provided queue.
485
+ * Closes queue after story phase completes to signal dev workers to terminate.
486
+ *
487
+ * @param config - Workflow configuration
488
+ * @param detection - Input detection result
489
+ * @param queue - StoryQueue instance to enqueue completed stories
490
+ * @returns PhaseResult from story phase
491
+ * @private
492
+ */
493
+ /**
494
+ * Execute story creation phase with queue integration for pipeline mode.
495
+ *
496
+ * Producer phase in pipelined architecture:
497
+ * 1. Parse epics from input (PRD or epic file)
498
+ * 2. Create stories using BatchProcessor with parallel execution
499
+ * 3. For each completed story, invoke onStoryComplete callback
500
+ * 4. onStoryComplete enqueues story to StoryQueue for dev workers
501
+ * 5. After all stories created, close queue to signal completion
502
+ * 6. Dev workers (running concurrently) consume from queue
503
+ *
504
+ * Queue closure semantics:
505
+ * - Queue.close() signals "no more stories will be added"
506
+ * - Dev workers terminate when queue returns null (closed + empty)
507
+ * - Ensures graceful pipeline completion
508
+ *
509
+ * Error handling:
510
+ * - Individual story creation failures logged but don't stop phase
511
+ * - Queue enqueueing failures logged but don't stop creation
512
+ * - Queue always closed in finally block to prevent worker deadlock
513
+ *
514
+ * @param config - Workflow configuration
515
+ * @param detection - Input detection result (PRD or epic file)
516
+ * @param queue - StoryQueue for enqueuing completed stories
517
+ * @returns PhaseResult with story creation metrics
518
+ * @private
519
+ */
520
+ private executeStoryPhaseWithQueue;
521
+ /**
522
+ * Extract epic number from file path
523
+ *
524
+ * @param filePath - Epic file path (e.g., 'docs/epics/epic-1.md')
525
+ * @returns Epic number
526
+ * @private
527
+ */
528
+ private extractEpicNumber;
529
+ /**
530
+ * Extract story from file path
531
+ *
532
+ * @param filePath - Story file path (e.g., 'docs/stories/USER-GROUPS-story-1.001.md')
533
+ * @returns Story object
534
+ * @private
535
+ */
536
+ private extractStoryFromFilePath;
537
+ /**
538
+ * Generate epic file name with prefix and padded number
539
+ *
540
+ * @param prefix - File name prefix
541
+ * @param epicNumber - Epic number
542
+ * @returns Formatted file name (e.g., "USER-GROUPS-epic-001.md")
543
+ * @private
544
+ */
545
+ private generateEpicFileName;
546
+ /**
547
+ * Generate prefix from epic file path
548
+ *
549
+ * Extracts meaningful name from epic filename and converts to uppercase
550
+ * Example: "docs/epics/epic-1-user-authentication.md" -> "USER-AUTHENTICATION"
551
+ *
552
+ * @param epicPath - Path to epic file
553
+ * @returns Generated prefix
554
+ * @private
555
+ */
556
+ private generatePrefixFromEpicPath;
557
+ /**
558
+ * Generate prefix from PRD file path
559
+ *
560
+ * Extracts the PRD name from the file path and converts it to uppercase
561
+ * Example: "docs/PRD-user-groups.md" -> "USER-GROUPS"
562
+ *
563
+ * @param prdPath - Path to PRD file
564
+ * @returns Generated prefix
565
+ * @private
566
+ */
567
+ private generatePrefixFromPrdPath;
568
+ /**
569
+ * Generate story file name with prefix
570
+ *
571
+ * @param prefix - File name prefix
572
+ * @param storyNumber - Story number (e.g., "1.1")
573
+ * @returns Formatted file name (e.g., "USER-GROUPS-story-1.001.md")
574
+ * @private
575
+ */
576
+ private generateStoryFileName;
577
+ /**
578
+ * Get epics for story phase execution
579
+ *
580
+ * @param config - Workflow configuration
581
+ * @param detection - Input detection result
582
+ * @returns Array of epics
583
+ * @private
584
+ */
585
+ private getEpicsForStoryPhase;
586
+ /**
587
+ * Get stories for dev phase execution
588
+ *
589
+ * @param config - Workflow configuration
590
+ * @param detection - Input detection result
591
+ * @returns Array of stories
592
+ * @private
593
+ */
594
+ private getStoriesForDevPhase;
595
+ /**
596
+ * Handle phase result from Promise.allSettled
597
+ *
598
+ * @param result - PromiseSettledResult
599
+ * @param phaseName - Phase name for error reporting
600
+ * @returns PhaseResult
601
+ * @private
602
+ */
603
+ private handlePhaseResult;
604
+ /**
605
+ * Log workflow start information
606
+ *
607
+ * @param config - Workflow configuration
608
+ * @private
609
+ */
610
+ private logWorkflowStart;
611
+ /**
612
+ * Resolve prefix for story file pattern
613
+ *
614
+ * @param config - Workflow configuration
615
+ * @param detection - Input detection result
616
+ * @returns Prefix string
617
+ * @private
618
+ */
619
+ private resolvePrefix;
620
+ /**
621
+ * Check if workflow should abort after epic phase failure
622
+ *
623
+ * @param epicPhase - Epic phase result
624
+ * @returns True if should abort
625
+ * @private
626
+ */
627
+ private shouldAbortAfterEpicFailure;
628
+ /**
629
+ * Check if workflow should abort after story phase failure
630
+ *
631
+ * @param storyPhase - Story phase result
632
+ * @returns True if should abort
633
+ * @private
634
+ */
635
+ private shouldAbortAfterStoryFailure;
636
+ /**
637
+ * Sleep for specified milliseconds
638
+ *
639
+ * @param ms - Milliseconds to sleep
640
+ * @private
641
+ */
642
+ private sleep;
643
+ /**
644
+ * Update story status in file
645
+ *
646
+ * @param storyFilePath - Path to story file
647
+ * @param status - New status
648
+ * @private
649
+ */
650
+ private updateStoryStatus;
651
+ /**
652
+ * Validate workflow configuration
653
+ *
654
+ * @param config - Workflow configuration to validate
655
+ * @throws {ValidationError} If configuration is invalid
656
+ * @private
657
+ */
658
+ private validateConfig;
659
+ }