@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,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD Validate Command
|
|
3
|
+
*
|
|
4
|
+
* Validates a PRD file and previews the epic/story extraction that would
|
|
5
|
+
* occur during a workflow run. This is a dry-run inspection tool that:
|
|
6
|
+
* - Parses the PRD to extract epic definitions
|
|
7
|
+
* - Checks for existing epic files
|
|
8
|
+
* - Counts stories in existing epic files
|
|
9
|
+
* - Reports what would be generated by the workflow command
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```bash
|
|
13
|
+
* # Validate PRD and show extraction preview
|
|
14
|
+
* bmad-workflow prd validate docs/PRD-feature.md
|
|
15
|
+
*
|
|
16
|
+
* # Output as JSON for scripting
|
|
17
|
+
* bmad-workflow prd validate docs/PRD-feature.md --json
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
21
|
+
import Table from 'cli-table3';
|
|
22
|
+
import { relative } from 'node:path';
|
|
23
|
+
import { FileManager } from '../../services/file-system/file-manager.js';
|
|
24
|
+
import { PathResolver } from '../../services/file-system/path-resolver.js';
|
|
25
|
+
import { EpicParser } from '../../services/parsers/epic-parser.js';
|
|
26
|
+
import { PrdParser } from '../../services/parsers/prd-parser.js';
|
|
27
|
+
import * as Colors from '../../utils/colors.js';
|
|
28
|
+
import { createLogger } from '../../utils/logger.js';
|
|
29
|
+
/**
|
|
30
|
+
* PRD Validate Command
|
|
31
|
+
*
|
|
32
|
+
* Parses a PRD file and reports what epics and stories would be
|
|
33
|
+
* extracted by the workflow command.
|
|
34
|
+
*/
|
|
35
|
+
export default class PrdValidate extends Command {
|
|
36
|
+
static args = {
|
|
37
|
+
prdFile: Args.string({
|
|
38
|
+
description: 'Path to PRD markdown file to validate',
|
|
39
|
+
required: true,
|
|
40
|
+
}),
|
|
41
|
+
};
|
|
42
|
+
static description = 'Validate PRD and preview epic/story extraction for workflow';
|
|
43
|
+
static examples = [
|
|
44
|
+
'<%= config.bin %> <%= command.id %> docs/PRD-feature.md',
|
|
45
|
+
'<%= config.bin %> <%= command.id %> docs/PRD-feature.md --json',
|
|
46
|
+
'<%= config.bin %> <%= command.id %> ./my-prd.md -j',
|
|
47
|
+
];
|
|
48
|
+
static flags = {
|
|
49
|
+
json: Flags.boolean({
|
|
50
|
+
char: 'j',
|
|
51
|
+
default: false,
|
|
52
|
+
description: 'Output validation results as JSON',
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* EpicParser instance for parsing story content
|
|
57
|
+
*/
|
|
58
|
+
epicParser;
|
|
59
|
+
/**
|
|
60
|
+
* FileManager instance for file operations
|
|
61
|
+
*/
|
|
62
|
+
fileManager;
|
|
63
|
+
/**
|
|
64
|
+
* Logger instance
|
|
65
|
+
*/
|
|
66
|
+
logger = createLogger({ namespace: 'bmad-workflow:commands:prd:validate' });
|
|
67
|
+
/**
|
|
68
|
+
* PathResolver instance for resolving paths
|
|
69
|
+
*/
|
|
70
|
+
pathResolver;
|
|
71
|
+
/**
|
|
72
|
+
* PrdParser instance for parsing PRD content
|
|
73
|
+
*/
|
|
74
|
+
prdParser;
|
|
75
|
+
/**
|
|
76
|
+
* Run the validation command
|
|
77
|
+
*/
|
|
78
|
+
async run() {
|
|
79
|
+
const { args, flags } = await this.parse(PrdValidate);
|
|
80
|
+
// Initialize services
|
|
81
|
+
this.initializeServices();
|
|
82
|
+
try {
|
|
83
|
+
// Step 1: Validate PRD file exists and read content
|
|
84
|
+
this.logger.info({ prdFile: args.prdFile }, 'Starting PRD validation');
|
|
85
|
+
const prdExists = await this.fileManager.fileExists(args.prdFile);
|
|
86
|
+
if (!prdExists) {
|
|
87
|
+
this.error(Colors.error(`PRD file not found: ${args.prdFile}`));
|
|
88
|
+
}
|
|
89
|
+
const prdContent = await this.fileManager.readFile(args.prdFile);
|
|
90
|
+
this.logger.debug({ contentLength: prdContent.length }, 'PRD content loaded');
|
|
91
|
+
// Step 2: Parse epics from PRD
|
|
92
|
+
let epics;
|
|
93
|
+
try {
|
|
94
|
+
epics = this.prdParser.parseEpics(prdContent, args.prdFile);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
const err = error;
|
|
98
|
+
this.logger.error({ error: err }, 'Failed to parse epics from PRD');
|
|
99
|
+
this.error(Colors.error(`Failed to parse PRD: ${err.message}`));
|
|
100
|
+
}
|
|
101
|
+
this.logger.info({ epicCount: epics.length }, 'Epics parsed from PRD');
|
|
102
|
+
// Step 3: Validate each epic (check for existing files, count stories)
|
|
103
|
+
const validationResults = await Promise.all(epics.map(async (epic) => this.validateEpic(epic)));
|
|
104
|
+
// Step 4: Calculate summary
|
|
105
|
+
const summary = this.calculateSummary(validationResults);
|
|
106
|
+
// Step 5: Build output
|
|
107
|
+
const output = {
|
|
108
|
+
epics: validationResults,
|
|
109
|
+
prdFile: relative(process.cwd(), args.prdFile) || args.prdFile,
|
|
110
|
+
summary,
|
|
111
|
+
};
|
|
112
|
+
// Step 6: Display results
|
|
113
|
+
if (flags.json) {
|
|
114
|
+
this.outputJson(output);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.outputTable(output);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
const err = error;
|
|
122
|
+
this.logger.error({ error: err }, 'PRD validation failed');
|
|
123
|
+
this.error(Colors.error(`Validation failed: ${err.message}`));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Calculate summary statistics from validation results
|
|
128
|
+
*
|
|
129
|
+
* @param results - Array of epic validation results
|
|
130
|
+
* @returns Summary statistics
|
|
131
|
+
*/
|
|
132
|
+
calculateSummary(results) {
|
|
133
|
+
const existingEpics = results.filter((r) => r.status === 'exists').length;
|
|
134
|
+
const pendingEpics = results.filter((r) => r.status === 'pending').length;
|
|
135
|
+
const totalStories = results.reduce((sum, r) => sum + r.stories, 0);
|
|
136
|
+
return {
|
|
137
|
+
existingEpics,
|
|
138
|
+
pendingEpics,
|
|
139
|
+
totalEpics: results.length,
|
|
140
|
+
totalStories,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Find epic file matching the epic number
|
|
145
|
+
*
|
|
146
|
+
* Searches the epics directory for files matching pattern:
|
|
147
|
+
* - epic-{N}-*.md
|
|
148
|
+
* - *-epic-{N}.md
|
|
149
|
+
* - *-epic-{N}-*.md
|
|
150
|
+
*
|
|
151
|
+
* @param epicNumber - Epic number to search for
|
|
152
|
+
* @returns Path to epic file if found, null otherwise
|
|
153
|
+
*/
|
|
154
|
+
async findEpicFile(epicNumber) {
|
|
155
|
+
try {
|
|
156
|
+
const epicDir = this.pathResolver.getEpicDir();
|
|
157
|
+
const files = await this.fileManager.listFiles(epicDir, '*.md');
|
|
158
|
+
// Look for files matching epic number patterns
|
|
159
|
+
const patterns = [
|
|
160
|
+
new RegExp(`^epic-${epicNumber}-`, 'i'),
|
|
161
|
+
new RegExp(`-epic-${epicNumber}\\.md$`, 'i'),
|
|
162
|
+
new RegExp(`-epic-${epicNumber}-`, 'i'),
|
|
163
|
+
];
|
|
164
|
+
for (const file of files) {
|
|
165
|
+
const filename = file.split('/').pop() || file;
|
|
166
|
+
for (const pattern of patterns) {
|
|
167
|
+
if (pattern.test(filename)) {
|
|
168
|
+
this.logger.debug({ epicNumber, file }, 'Epic file found');
|
|
169
|
+
return file;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
this.logger.debug({ epicNumber }, 'No epic file found');
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Directory might not exist yet
|
|
178
|
+
this.logger.debug({ epicNumber }, 'Epic directory not found or empty');
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Initialize service instances
|
|
184
|
+
*/
|
|
185
|
+
initializeServices() {
|
|
186
|
+
this.fileManager = new FileManager(this.logger);
|
|
187
|
+
this.pathResolver = new PathResolver(this.fileManager, this.logger);
|
|
188
|
+
this.prdParser = new PrdParser(this.logger);
|
|
189
|
+
this.epicParser = new EpicParser(this.logger);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Output validation results as JSON
|
|
193
|
+
*
|
|
194
|
+
* @param output - Complete validation output
|
|
195
|
+
*/
|
|
196
|
+
outputJson(output) {
|
|
197
|
+
this.log(JSON.stringify(output, null, 2));
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Output validation results as formatted table
|
|
201
|
+
*
|
|
202
|
+
* @param output - Complete validation output
|
|
203
|
+
*/
|
|
204
|
+
outputTable(output) {
|
|
205
|
+
// Header
|
|
206
|
+
this.log('');
|
|
207
|
+
this.log(Colors.bold('╔════════════════════════════════════════════════════════════════╗'));
|
|
208
|
+
this.log(Colors.bold('║ PRD Validation Summary ║'));
|
|
209
|
+
this.log(Colors.bold('╚════════════════════════════════════════════════════════════════╝'));
|
|
210
|
+
this.log('');
|
|
211
|
+
this.log(Colors.info(`PRD: ${output.prdFile}`));
|
|
212
|
+
this.log('');
|
|
213
|
+
// Create table
|
|
214
|
+
const table = new Table({
|
|
215
|
+
colWidths: [10, 40, 10, 30],
|
|
216
|
+
head: [
|
|
217
|
+
Colors.bold(Colors.highlight('Epic #')),
|
|
218
|
+
Colors.bold(Colors.highlight('Title')),
|
|
219
|
+
Colors.bold(Colors.highlight('Stories')),
|
|
220
|
+
Colors.bold(Colors.highlight('Status')),
|
|
221
|
+
],
|
|
222
|
+
wordWrap: true,
|
|
223
|
+
});
|
|
224
|
+
// Add rows
|
|
225
|
+
for (const epic of output.epics) {
|
|
226
|
+
const statusDisplay = epic.status === 'exists' ? Colors.success('✓ Exists') : Colors.warning('○ Pending');
|
|
227
|
+
const storiesDisplay = epic.status === 'exists' ? epic.stories.toString() : Colors.dim('-');
|
|
228
|
+
table.push([epic.number.toString(), this.truncateText(epic.title, 38), storiesDisplay, statusDisplay]);
|
|
229
|
+
}
|
|
230
|
+
this.log(table.toString());
|
|
231
|
+
this.log('');
|
|
232
|
+
// Summary section
|
|
233
|
+
this.log(Colors.bold('Summary:'));
|
|
234
|
+
this.log(` Epics: ${output.summary.totalEpics} total (${output.summary.existingEpics} existing, ${output.summary.pendingEpics} pending)`);
|
|
235
|
+
this.log(` Stories: ${output.summary.totalStories} found in existing epic files`);
|
|
236
|
+
this.log('');
|
|
237
|
+
// Warnings
|
|
238
|
+
if (output.summary.pendingEpics > 0) {
|
|
239
|
+
this.log(Colors.warning(`⚠ ${output.summary.pendingEpics} epic file(s) not found - would be created by workflow`));
|
|
240
|
+
}
|
|
241
|
+
// Success indicator
|
|
242
|
+
if (output.summary.pendingEpics === 0 && output.summary.totalStories > 0) {
|
|
243
|
+
this.log(Colors.success('✓ All epic files exist and contain stories'));
|
|
244
|
+
}
|
|
245
|
+
this.log('');
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Truncate text with ellipsis if too long
|
|
249
|
+
*
|
|
250
|
+
* @param text - Text to truncate
|
|
251
|
+
* @param maxLength - Maximum length
|
|
252
|
+
* @returns Truncated text
|
|
253
|
+
*/
|
|
254
|
+
truncateText(text, maxLength) {
|
|
255
|
+
if (text.length <= maxLength) {
|
|
256
|
+
return text;
|
|
257
|
+
}
|
|
258
|
+
return text.slice(0, maxLength - 3) + '...';
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Validate a single epic
|
|
262
|
+
*
|
|
263
|
+
* Checks if the epic file exists and counts stories if it does.
|
|
264
|
+
*
|
|
265
|
+
* @param epic - Epic information from PRD
|
|
266
|
+
* @returns Validation result for the epic
|
|
267
|
+
*/
|
|
268
|
+
async validateEpic(epic) {
|
|
269
|
+
this.logger.debug({ epic }, 'Validating epic');
|
|
270
|
+
// Try to find existing epic file
|
|
271
|
+
const epicFile = await this.findEpicFile(epic.number);
|
|
272
|
+
if (!epicFile) {
|
|
273
|
+
return {
|
|
274
|
+
epicFile: null,
|
|
275
|
+
number: epic.number,
|
|
276
|
+
status: 'pending',
|
|
277
|
+
stories: 0,
|
|
278
|
+
title: epic.title,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
// Epic file exists - try to count stories
|
|
282
|
+
let storyCount = 0;
|
|
283
|
+
try {
|
|
284
|
+
const epicContent = await this.fileManager.readFile(epicFile);
|
|
285
|
+
const stories = this.epicParser.parseStories(epicContent, epicFile);
|
|
286
|
+
storyCount = stories.length;
|
|
287
|
+
this.logger.debug({ epicFile, storyCount }, 'Stories counted in epic');
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
// Epic file exists but couldn't parse stories (maybe no Stories section yet)
|
|
291
|
+
this.logger.warn({ epicFile, error }, 'Could not parse stories from epic file');
|
|
292
|
+
storyCount = 0;
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
epicFile: relative(process.cwd(), epicFile) || epicFile,
|
|
296
|
+
number: epic.number,
|
|
297
|
+
status: 'exists',
|
|
298
|
+
stories: storyCount,
|
|
299
|
+
title: epic.title,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stories Create Command
|
|
3
|
+
*
|
|
4
|
+
* Automatically generates story markdown files from an epic using parallel Claude AI agent execution.
|
|
5
|
+
* Creates story files with configurable concurrency and batch processing.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```bash
|
|
9
|
+
* bmad-workflow stories create docs/epics/epic-1-foundation.md
|
|
10
|
+
* bmad-workflow stories create epic.md --parallel 10
|
|
11
|
+
* bmad-workflow stories create epic.md --start 3
|
|
12
|
+
* bmad-workflow stories create epic.md --reference docs/architecture.md
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
import { Command } from '@oclif/core';
|
|
16
|
+
/**
|
|
17
|
+
* Stories Create Command
|
|
18
|
+
*
|
|
19
|
+
* Creates story files from epic using Claude AI agents with parallel processing.
|
|
20
|
+
*/
|
|
21
|
+
export default class StoriesCreateCommand extends Command {
|
|
22
|
+
static args: {
|
|
23
|
+
'epic-path': import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
24
|
+
};
|
|
25
|
+
static description: string;
|
|
26
|
+
static examples: {
|
|
27
|
+
command: string;
|
|
28
|
+
description: string;
|
|
29
|
+
}[];
|
|
30
|
+
static flags: {
|
|
31
|
+
interval: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
32
|
+
parallel: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
33
|
+
prefix: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
34
|
+
reference: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
35
|
+
start: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
36
|
+
agent: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
37
|
+
cwd: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
38
|
+
provider: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
39
|
+
task: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
40
|
+
};
|
|
41
|
+
private agentRunner;
|
|
42
|
+
private batchProcessor;
|
|
43
|
+
private epicParser;
|
|
44
|
+
private fileManager;
|
|
45
|
+
private fileScaffolder;
|
|
46
|
+
private logger;
|
|
47
|
+
private pathResolver;
|
|
48
|
+
/**
|
|
49
|
+
* Run the command
|
|
50
|
+
*/
|
|
51
|
+
run(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Build Claude CLI prompt for story creation
|
|
54
|
+
*/
|
|
55
|
+
private buildClaudePrompt;
|
|
56
|
+
/**
|
|
57
|
+
* Check for existing story files across all story directories
|
|
58
|
+
*
|
|
59
|
+
* Checks docs/stories, docs/qa/stories, and docs/done/stories to prevent
|
|
60
|
+
* recreating stories that have been moved for QA or marked as done.
|
|
61
|
+
*/
|
|
62
|
+
private checkExistingStories;
|
|
63
|
+
/**
|
|
64
|
+
* Create stories in parallel batches
|
|
65
|
+
*/
|
|
66
|
+
private createStoriesInParallel;
|
|
67
|
+
/**
|
|
68
|
+
* Create a single story file
|
|
69
|
+
*/
|
|
70
|
+
private createStory;
|
|
71
|
+
/**
|
|
72
|
+
* Display summary report
|
|
73
|
+
*/
|
|
74
|
+
private displaySummaryReport;
|
|
75
|
+
/**
|
|
76
|
+
* Filter stories by start number
|
|
77
|
+
*/
|
|
78
|
+
private filterStoriesByStart;
|
|
79
|
+
/**
|
|
80
|
+
* Generate story filename from story metadata
|
|
81
|
+
*/
|
|
82
|
+
private generateStoryFilename;
|
|
83
|
+
/**
|
|
84
|
+
* Initialize service dependencies
|
|
85
|
+
*/
|
|
86
|
+
private initializeServices;
|
|
87
|
+
/**
|
|
88
|
+
* Parse epic file and extract stories
|
|
89
|
+
*/
|
|
90
|
+
private parseEpicStories;
|
|
91
|
+
/**
|
|
92
|
+
* Validate parallel flag value
|
|
93
|
+
*/
|
|
94
|
+
private validateParallelFlag;
|
|
95
|
+
}
|