@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.
- package/LICENSE +21 -0
- package/README.md +1017 -0
- package/bin/dev +5 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +5 -0
- package/dist/commands/config/show.d.ts +34 -0
- package/dist/commands/config/show.js +108 -0
- package/dist/commands/config/validate.d.ts +29 -0
- package/dist/commands/config/validate.js +131 -0
- package/dist/commands/decompose.d.ts +79 -0
- package/dist/commands/decompose.js +327 -0
- package/dist/commands/demo.d.ts +18 -0
- package/dist/commands/demo.js +107 -0
- package/dist/commands/epics/create.d.ts +123 -0
- package/dist/commands/epics/create.js +459 -0
- package/dist/commands/epics/list.d.ts +120 -0
- package/dist/commands/epics/list.js +280 -0
- package/dist/commands/hello/index.d.ts +12 -0
- package/dist/commands/hello/index.js +34 -0
- package/dist/commands/hello/world.d.ts +8 -0
- package/dist/commands/hello/world.js +24 -0
- package/dist/commands/prd/fix.d.ts +39 -0
- package/dist/commands/prd/fix.js +140 -0
- package/dist/commands/prd/validate.d.ts +112 -0
- package/dist/commands/prd/validate.js +302 -0
- package/dist/commands/stories/create.d.ts +95 -0
- package/dist/commands/stories/create.js +431 -0
- package/dist/commands/stories/develop.d.ts +91 -0
- package/dist/commands/stories/develop.js +460 -0
- package/dist/commands/stories/list.d.ts +84 -0
- package/dist/commands/stories/list.js +291 -0
- package/dist/commands/stories/move.d.ts +66 -0
- package/dist/commands/stories/move.js +273 -0
- package/dist/commands/stories/qa.d.ts +99 -0
- package/dist/commands/stories/qa.js +530 -0
- package/dist/commands/workflow.d.ts +97 -0
- package/dist/commands/workflow.js +390 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models/agent-options.d.ts +50 -0
- package/dist/models/agent-options.js +1 -0
- package/dist/models/agent-result.d.ts +29 -0
- package/dist/models/agent-result.js +1 -0
- package/dist/models/index.d.ts +10 -0
- package/dist/models/index.js +10 -0
- package/dist/models/phase-result.d.ts +65 -0
- package/dist/models/phase-result.js +7 -0
- package/dist/models/provider.d.ts +28 -0
- package/dist/models/provider.js +18 -0
- package/dist/models/story.d.ts +154 -0
- package/dist/models/story.js +18 -0
- package/dist/models/workflow-config.d.ts +148 -0
- package/dist/models/workflow-config.js +1 -0
- package/dist/models/workflow-result.d.ts +164 -0
- package/dist/models/workflow-result.js +7 -0
- package/dist/services/agents/agent-runner-factory.d.ts +31 -0
- package/dist/services/agents/agent-runner-factory.js +44 -0
- package/dist/services/agents/agent-runner.d.ts +46 -0
- package/dist/services/agents/agent-runner.js +29 -0
- package/dist/services/agents/claude-agent-runner.d.ts +81 -0
- package/dist/services/agents/claude-agent-runner.js +332 -0
- package/dist/services/agents/gemini-agent-runner.d.ts +82 -0
- package/dist/services/agents/gemini-agent-runner.js +350 -0
- package/dist/services/agents/index.d.ts +7 -0
- package/dist/services/agents/index.js +7 -0
- package/dist/services/file-system/file-manager.d.ts +110 -0
- package/dist/services/file-system/file-manager.js +223 -0
- package/dist/services/file-system/glob-matcher.d.ts +75 -0
- package/dist/services/file-system/glob-matcher.js +126 -0
- package/dist/services/file-system/path-resolver.d.ts +183 -0
- package/dist/services/file-system/path-resolver.js +400 -0
- package/dist/services/logging/workflow-logger.d.ts +232 -0
- package/dist/services/logging/workflow-logger.js +552 -0
- package/dist/services/orchestration/batch-processor.d.ts +113 -0
- package/dist/services/orchestration/batch-processor.js +187 -0
- package/dist/services/orchestration/dependency-graph-executor.d.ts +60 -0
- package/dist/services/orchestration/dependency-graph-executor.js +447 -0
- package/dist/services/orchestration/index.d.ts +10 -0
- package/dist/services/orchestration/index.js +8 -0
- package/dist/services/orchestration/input-detector.d.ts +125 -0
- package/dist/services/orchestration/input-detector.js +381 -0
- package/dist/services/orchestration/story-queue.d.ts +94 -0
- package/dist/services/orchestration/story-queue.js +170 -0
- package/dist/services/orchestration/story-type-detector.d.ts +80 -0
- package/dist/services/orchestration/story-type-detector.js +258 -0
- package/dist/services/orchestration/task-decomposition-service.d.ts +67 -0
- package/dist/services/orchestration/task-decomposition-service.js +607 -0
- package/dist/services/orchestration/workflow-orchestrator.d.ts +659 -0
- package/dist/services/orchestration/workflow-orchestrator.js +2201 -0
- package/dist/services/parsers/epic-parser.d.ts +117 -0
- package/dist/services/parsers/epic-parser.js +264 -0
- package/dist/services/parsers/prd-fixer.d.ts +86 -0
- package/dist/services/parsers/prd-fixer.js +194 -0
- package/dist/services/parsers/prd-parser.d.ts +123 -0
- package/dist/services/parsers/prd-parser.js +286 -0
- package/dist/services/parsers/standalone-story-parser.d.ts +114 -0
- package/dist/services/parsers/standalone-story-parser.js +255 -0
- package/dist/services/parsers/story-parser-factory.d.ts +81 -0
- package/dist/services/parsers/story-parser-factory.js +108 -0
- package/dist/services/parsers/story-parser.d.ts +122 -0
- package/dist/services/parsers/story-parser.js +262 -0
- package/dist/services/scaffolding/decompose-session-scaffolder.d.ts +74 -0
- package/dist/services/scaffolding/decompose-session-scaffolder.js +315 -0
- package/dist/services/scaffolding/file-scaffolder.d.ts +94 -0
- package/dist/services/scaffolding/file-scaffolder.js +314 -0
- package/dist/services/validation/config-validator.d.ts +88 -0
- package/dist/services/validation/config-validator.js +167 -0
- package/dist/types/task-graph.d.ts +142 -0
- package/dist/types/task-graph.js +5 -0
- package/dist/utils/colors.d.ts +49 -0
- package/dist/utils/colors.js +50 -0
- package/dist/utils/error-formatter.d.ts +64 -0
- package/dist/utils/error-formatter.js +279 -0
- package/dist/utils/errors.d.ts +170 -0
- package/dist/utils/errors.js +233 -0
- package/dist/utils/formatters.d.ts +84 -0
- package/dist/utils/formatters.js +162 -0
- package/dist/utils/logger.d.ts +63 -0
- package/dist/utils/logger.js +78 -0
- package/dist/utils/progress.d.ts +104 -0
- package/dist/utils/progress.js +161 -0
- package/dist/utils/retry.d.ts +114 -0
- package/dist/utils/retry.js +160 -0
- package/dist/utils/shared-flags.d.ts +28 -0
- package/dist/utils/shared-flags.js +43 -0
- 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
|
+
}
|