@hyperdrive.bot/bmad-workflow 1.0.21 → 1.0.23
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/assets/agents/dev-barry.md +69 -0
- package/assets/agents/dev.md +323 -0
- package/assets/agents/qa.md +92 -0
- package/assets/agents/sm-bob.md +65 -0
- package/assets/agents/sm.md +296 -0
- package/assets/config/default-config.yaml +6 -0
- package/assets/templates/epic-tmpl.yaml +277 -0
- package/assets/templates/prd-tmpl.yaml +261 -0
- package/assets/templates/qa-gate-tmpl.yaml +103 -0
- package/assets/templates/story-tmpl.yaml +138 -0
- package/dist/commands/eject.d.ts +76 -0
- package/dist/commands/eject.js +232 -0
- package/dist/commands/init.d.ts +47 -0
- package/dist/commands/init.js +265 -0
- package/dist/commands/stories/develop.js +1 -0
- package/dist/commands/stories/qa.d.ts +1 -0
- package/dist/commands/stories/qa.js +7 -0
- package/dist/commands/workflow.d.ts +6 -3
- package/dist/commands/workflow.js +106 -26
- package/dist/models/bmad-config-schema.d.ts +51 -0
- package/dist/models/bmad-config-schema.js +53 -0
- package/dist/services/agents/gemini-agent-runner.js +7 -2
- package/dist/services/agents/opencode-agent-runner.js +7 -2
- package/dist/services/file-system/asset-resolver.d.ts +117 -0
- package/dist/services/file-system/asset-resolver.js +234 -0
- package/dist/services/file-system/file-manager.d.ts +13 -0
- package/dist/services/file-system/file-manager.js +32 -0
- package/dist/services/file-system/path-resolver.d.ts +22 -1
- package/dist/services/file-system/path-resolver.js +36 -9
- package/dist/services/orchestration/dependency-graph-executor.js +1 -0
- package/dist/services/orchestration/workflow-orchestrator.d.ts +11 -0
- package/dist/services/orchestration/workflow-orchestrator.js +79 -10
- package/dist/utils/config-merge.d.ts +60 -0
- package/dist/utils/config-merge.js +52 -0
- package/package.json +4 -2
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
import { isEpicStory } from '../../models/story.js';
|
|
47
47
|
import { ParserError, ValidationError } from '../../utils/errors.js';
|
|
48
48
|
import { runAgentWithRetry } from '../../utils/retry.js';
|
|
49
|
+
import { AssetResolver } from '../file-system/asset-resolver.js';
|
|
49
50
|
import { PrdFixer } from '../parsers/prd-fixer.js';
|
|
50
51
|
import { FileScaffolder } from '../scaffolding/file-scaffolder.js';
|
|
51
52
|
import { BatchProcessor } from './batch-processor.js';
|
|
@@ -60,6 +61,7 @@ import { ReviewQueue } from '../review/review-queue.js';
|
|
|
60
61
|
*/
|
|
61
62
|
export class WorkflowOrchestrator {
|
|
62
63
|
agentRunner;
|
|
64
|
+
assetResolver;
|
|
63
65
|
batchProcessor;
|
|
64
66
|
callbacks;
|
|
65
67
|
epicParser;
|
|
@@ -80,6 +82,7 @@ export class WorkflowOrchestrator {
|
|
|
80
82
|
* @param config - Configuration object containing all service dependencies
|
|
81
83
|
*/
|
|
82
84
|
constructor(config) {
|
|
85
|
+
this.assetResolver = config.assetResolver ?? new AssetResolver({});
|
|
83
86
|
this.inputDetector = config.inputDetector;
|
|
84
87
|
this.prdParser = config.prdParser;
|
|
85
88
|
this.epicParser = config.epicParser;
|
|
@@ -173,7 +176,9 @@ export class WorkflowOrchestrator {
|
|
|
173
176
|
const { cwd, outputPath, prdPath, references, smAgent } = options;
|
|
174
177
|
const referencesText = references.length > 0 ? `\nReferences: ${references.join(', ')}` : '';
|
|
175
178
|
const cwdText = cwd ? `\n\nWorking directory: ${cwd}` : '';
|
|
176
|
-
const
|
|
179
|
+
const resolved = this.assetResolver.resolveAgent('sm', smAgent);
|
|
180
|
+
const agentRef = `@${resolved.path}`;
|
|
181
|
+
const templateResolved = this.assetResolver.resolveTemplate('epic-tmpl.yaml');
|
|
177
182
|
return `${agentRef}${cwdText}
|
|
178
183
|
|
|
179
184
|
Create epic '${epic.number}: ${epic.title}' for PRD '${prdPath}'.${referencesText}.
|
|
@@ -182,7 +187,7 @@ IMPORTANT: The file at '${outputPath}' has been pre-scaffolded with structure an
|
|
|
182
187
|
- DO NOT modify the Epic Header section (Epic ID, Status: Draft, Created date are already set)
|
|
183
188
|
- DO NOT change the document structure or section headers
|
|
184
189
|
- ONLY populate the empty content sections marked with [AI Agent will populate]
|
|
185
|
-
- Follow the template structure at
|
|
190
|
+
- Follow the template structure at @${templateResolved.path} for content guidance
|
|
186
191
|
|
|
187
192
|
Write output to: '${outputPath}'`;
|
|
188
193
|
}
|
|
@@ -220,7 +225,9 @@ Write output to: '${outputPath}'`;
|
|
|
220
225
|
const { cwd, epicPath, outputPath, references, smAgent } = options;
|
|
221
226
|
const referencesText = references.length > 0 ? `\nReferences: ${references.join(', ')}` : '';
|
|
222
227
|
const cwdText = cwd ? `\n\nWorking directory: ${cwd}` : '';
|
|
223
|
-
const
|
|
228
|
+
const resolved = this.assetResolver.resolveAgent('sm', smAgent);
|
|
229
|
+
const agentRef = `@${resolved.path}`;
|
|
230
|
+
const templateResolved = this.assetResolver.resolveTemplate('story-tmpl.yaml');
|
|
224
231
|
return `${agentRef}${cwdText}
|
|
225
232
|
|
|
226
233
|
Create story '${story.fullNumber}: ${story.title}' for epic '${epicPath}'. ${referencesText}
|
|
@@ -230,7 +237,7 @@ IMPORTANT: The file at '${outputPath}' has been pre-scaffolded with structure an
|
|
|
230
237
|
- DO NOT modify the Created date in Change Log
|
|
231
238
|
- DO NOT change the document structure or section headers
|
|
232
239
|
- ONLY populate the empty content sections marked with [AI Agent will populate]
|
|
233
|
-
- Follow the template structure at
|
|
240
|
+
- Follow the template structure at @${templateResolved.path} for content guidance
|
|
234
241
|
|
|
235
242
|
Write output to: ${outputPath}`;
|
|
236
243
|
}
|
|
@@ -626,14 +633,17 @@ Write output to: ${outputPath}`;
|
|
|
626
633
|
// Build prompt with auto-detected references
|
|
627
634
|
const mcpPrefix = await this.getMcpPromptPrefix('dev', 'dev', config);
|
|
628
635
|
let prompt = mcpPrefix ? `${mcpPrefix}\n\n` : '';
|
|
629
|
-
|
|
636
|
+
const devResolved = this.assetResolver.resolveAgent('dev', config.devAgent);
|
|
637
|
+
prompt += `@${devResolved.path}\n\n`;
|
|
630
638
|
// Add working directory instruction if specified
|
|
631
639
|
if (config.cwd) {
|
|
632
640
|
prompt += `Working directory: ${config.cwd}\n\n`;
|
|
633
641
|
}
|
|
634
642
|
prompt += `*develop-story ${storyFilePath}\n\n`;
|
|
635
|
-
//
|
|
636
|
-
const
|
|
643
|
+
// Parse Dev Context section for sidecars and deploy target
|
|
644
|
+
const devContext = this.parseDevContext(storyContent);
|
|
645
|
+
// Combine auto-detected references with user-provided references and sidecars
|
|
646
|
+
const allReferences = [...autoReferences, ...(config.references || []), ...devContext.sidecarRefs];
|
|
637
647
|
if (allReferences.length > 0) {
|
|
638
648
|
prompt += 'References:\n';
|
|
639
649
|
for (const ref of allReferences) {
|
|
@@ -641,6 +651,10 @@ Write output to: ${outputPath}`;
|
|
|
641
651
|
}
|
|
642
652
|
prompt += '\n';
|
|
643
653
|
}
|
|
654
|
+
// Add deploy target context if specified in story
|
|
655
|
+
if (devContext.deployTarget) {
|
|
656
|
+
prompt += `Deploy target: ${devContext.deployTarget}\n\n`;
|
|
657
|
+
}
|
|
644
658
|
prompt += '*yolo mode*\n';
|
|
645
659
|
// Generate unique spawn ID
|
|
646
660
|
const spawnId = `dev-${story.fullNumber}-${storyStartTime}`;
|
|
@@ -659,6 +673,7 @@ Write output to: ${outputPath}`;
|
|
|
659
673
|
// Execute dev agent with retry on timeout/killed
|
|
660
674
|
const result = await runAgentWithRetry(this.agentRunner, prompt, {
|
|
661
675
|
agentType: 'dev',
|
|
676
|
+
cwd: config.cwd,
|
|
662
677
|
references: config.references,
|
|
663
678
|
timeout: config.timeout ?? 2_700_000,
|
|
664
679
|
}, {
|
|
@@ -901,14 +916,17 @@ Write output to: ${outputPath}`;
|
|
|
901
916
|
// Build prompt with auto-detected references
|
|
902
917
|
const mcpPrefix = await this.getMcpPromptPrefix('dev', 'dev', config);
|
|
903
918
|
let prompt = mcpPrefix ? `${mcpPrefix}\n\n` : '';
|
|
904
|
-
|
|
919
|
+
const devResolved = this.assetResolver.resolveAgent('dev', config.devAgent);
|
|
920
|
+
prompt += `@${devResolved.path}\n\n`;
|
|
905
921
|
// Add working directory instruction if specified
|
|
906
922
|
if (config.cwd) {
|
|
907
923
|
prompt += `Working directory: ${config.cwd}\n\n`;
|
|
908
924
|
}
|
|
909
925
|
prompt += `Implement story: ${storyFilePath}\n\n`;
|
|
910
|
-
//
|
|
911
|
-
const
|
|
926
|
+
// Parse Dev Context section for sidecars and deploy target
|
|
927
|
+
const devContext = this.parseDevContext(storyContent);
|
|
928
|
+
// Combine auto-detected references with user-provided references and sidecars
|
|
929
|
+
const allReferences = [...autoReferences, ...(config.references || []), ...devContext.sidecarRefs];
|
|
912
930
|
if (allReferences.length > 0) {
|
|
913
931
|
prompt += 'References:\n';
|
|
914
932
|
for (const ref of allReferences) {
|
|
@@ -916,6 +934,10 @@ Write output to: ${outputPath}`;
|
|
|
916
934
|
}
|
|
917
935
|
prompt += '\n';
|
|
918
936
|
}
|
|
937
|
+
// Add deploy target context if specified in story
|
|
938
|
+
if (devContext.deployTarget) {
|
|
939
|
+
prompt += `Deploy target: ${devContext.deployTarget}\n\n`;
|
|
940
|
+
}
|
|
919
941
|
prompt += '*yolo mode*\n';
|
|
920
942
|
// Generate unique spawn ID and timestamp
|
|
921
943
|
const spawnStartTime = Date.now();
|
|
@@ -933,6 +955,7 @@ Write output to: ${outputPath}`;
|
|
|
933
955
|
});
|
|
934
956
|
const result = await runAgentWithRetry(this.agentRunner, prompt, {
|
|
935
957
|
agentType: 'dev',
|
|
958
|
+
cwd: config.cwd,
|
|
936
959
|
references: config.references,
|
|
937
960
|
timeout: config.timeout ?? 2_700_000,
|
|
938
961
|
}, {
|
|
@@ -1258,6 +1281,7 @@ Write output to: ${outputPath}`;
|
|
|
1258
1281
|
// Step 3: Run Claude agent to populate content sections
|
|
1259
1282
|
const result = await runAgentWithRetry(this.agentRunner, prompt, {
|
|
1260
1283
|
agentType: 'architect',
|
|
1284
|
+
cwd: config.cwd,
|
|
1261
1285
|
references: config.references,
|
|
1262
1286
|
timeout: config.timeout ?? 2_700_000,
|
|
1263
1287
|
}, {
|
|
@@ -2250,6 +2274,7 @@ Write output to: ${outputPath}`;
|
|
|
2250
2274
|
// Step 4: Run Claude agent to populate content sections
|
|
2251
2275
|
const result = await runAgentWithRetry(this.agentRunner, prompt, {
|
|
2252
2276
|
agentType: 'sm',
|
|
2277
|
+
cwd: config.cwd,
|
|
2253
2278
|
references: config.references,
|
|
2254
2279
|
timeout: config.timeout ?? 2_700_000,
|
|
2255
2280
|
}, {
|
|
@@ -2576,6 +2601,7 @@ Write output to: ${outputPath}`;
|
|
|
2576
2601
|
// Step 4: Run Claude agent to populate content sections
|
|
2577
2602
|
const result = await runAgentWithRetry(this.agentRunner, prompt, {
|
|
2578
2603
|
agentType: 'sm',
|
|
2604
|
+
cwd: config.cwd,
|
|
2579
2605
|
references: config.references,
|
|
2580
2606
|
timeout: config.timeout ?? 2_700_000,
|
|
2581
2607
|
}, {
|
|
@@ -3085,6 +3111,49 @@ Write output to: ${outputPath}`;
|
|
|
3085
3111
|
async sleep(ms) {
|
|
3086
3112
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
3087
3113
|
}
|
|
3114
|
+
/**
|
|
3115
|
+
* Parse the `### Dev Context` section from a story file's content.
|
|
3116
|
+
*
|
|
3117
|
+
* Returns sidecar reference paths and an optional deploy target string.
|
|
3118
|
+
* If the section is missing or empty, returns empty arrays / undefined (backward compatible).
|
|
3119
|
+
*/
|
|
3120
|
+
parseDevContext(storyContent) {
|
|
3121
|
+
const sidecarRefs = [];
|
|
3122
|
+
let deployTarget;
|
|
3123
|
+
// Find the ### Dev Context section
|
|
3124
|
+
const devCtxMatch = storyContent.match(/^### Dev Context\s*$/m);
|
|
3125
|
+
if (!devCtxMatch || devCtxMatch.index === undefined) {
|
|
3126
|
+
return { deployTarget, sidecarRefs };
|
|
3127
|
+
}
|
|
3128
|
+
// Extract section content up to the next heading or end of file
|
|
3129
|
+
const sectionStart = devCtxMatch.index + devCtxMatch[0].length;
|
|
3130
|
+
const nextHeadingMatch = storyContent.slice(sectionStart).match(/^#{1,3} /m);
|
|
3131
|
+
const sectionEnd = nextHeadingMatch?.index !== undefined ? sectionStart + nextHeadingMatch.index : storyContent.length;
|
|
3132
|
+
const sectionContent = storyContent.slice(sectionStart, sectionEnd);
|
|
3133
|
+
// Parse Sidecars line — supports "- **Sidecars:**" or "- Sidecars:" (flexible)
|
|
3134
|
+
const sidecarsMatch = sectionContent.match(/^-\s+\*{0,2}Sidecars:?\*{0,2}\s*(.+)$/im);
|
|
3135
|
+
if (sidecarsMatch?.[1]) {
|
|
3136
|
+
const raw = sidecarsMatch[1].trim();
|
|
3137
|
+
for (const part of raw.split(',')) {
|
|
3138
|
+
const name = part.trim();
|
|
3139
|
+
if (name.length === 0)
|
|
3140
|
+
continue;
|
|
3141
|
+
// If already a path, use as-is; otherwise prefix with _bmad/bmm/agents/
|
|
3142
|
+
if (name.includes('/')) {
|
|
3143
|
+
sidecarRefs.push(name);
|
|
3144
|
+
}
|
|
3145
|
+
else {
|
|
3146
|
+
sidecarRefs.push(`_bmad/bmm/agents/${name}`);
|
|
3147
|
+
}
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
// Parse Deploy target line
|
|
3151
|
+
const deployMatch = sectionContent.match(/^-\s+\*{0,2}Deploy target:?\*{0,2}\s*(.+)$/im);
|
|
3152
|
+
if (deployMatch?.[1]) {
|
|
3153
|
+
deployTarget = deployMatch[1].trim();
|
|
3154
|
+
}
|
|
3155
|
+
return { deployTarget, sidecarRefs };
|
|
3156
|
+
}
|
|
3088
3157
|
/**
|
|
3089
3158
|
* Update story status in file
|
|
3090
3159
|
*
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Merge Utility
|
|
3
|
+
*
|
|
4
|
+
* Implements three-layer merge for execution config:
|
|
5
|
+
* CLI flags (highest) → .bmad-workflow.yaml → hardcoded defaults (lowest)
|
|
6
|
+
*
|
|
7
|
+
* Pure function — no side effects, easy to test.
|
|
8
|
+
*/
|
|
9
|
+
import type { ConfigExecutionDefaults } from '../services/file-system/asset-resolver.js';
|
|
10
|
+
/**
|
|
11
|
+
* Merged execution config with all fields resolved
|
|
12
|
+
*/
|
|
13
|
+
export interface MergedExecutionConfig {
|
|
14
|
+
epicInterval: number;
|
|
15
|
+
maxRetries: number;
|
|
16
|
+
model: string | undefined;
|
|
17
|
+
parallel: number;
|
|
18
|
+
pipeline: boolean;
|
|
19
|
+
prdInterval: number;
|
|
20
|
+
provider: 'claude' | 'gemini' | 'opencode';
|
|
21
|
+
qa: boolean;
|
|
22
|
+
retryBackoffMs: number;
|
|
23
|
+
storyInterval: number;
|
|
24
|
+
timeout: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* CLI flags that may be undefined when user didn't pass them.
|
|
28
|
+
* Only fields explicitly passed by the user should be present.
|
|
29
|
+
*/
|
|
30
|
+
export interface CliExecutionFlags {
|
|
31
|
+
epicInterval?: number;
|
|
32
|
+
maxRetries?: number;
|
|
33
|
+
model?: string;
|
|
34
|
+
parallel?: number;
|
|
35
|
+
pipeline?: boolean;
|
|
36
|
+
prdInterval?: number;
|
|
37
|
+
provider?: string;
|
|
38
|
+
qa?: boolean;
|
|
39
|
+
retryBackoffMs?: number;
|
|
40
|
+
storyInterval?: number;
|
|
41
|
+
timeout?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Hardcoded defaults — final fallback when neither CLI nor config provides a value
|
|
45
|
+
*/
|
|
46
|
+
export declare const EXECUTION_DEFAULTS: MergedExecutionConfig;
|
|
47
|
+
/**
|
|
48
|
+
* Merge execution config from three layers: CLI flags → config file → hardcoded defaults.
|
|
49
|
+
*
|
|
50
|
+
* For each field, the first defined value wins (left to right):
|
|
51
|
+
* 1. CLI flag (explicit user input)
|
|
52
|
+
* 2. Config file value (from .bmad-workflow.yaml)
|
|
53
|
+
* 3. Hardcoded default
|
|
54
|
+
*
|
|
55
|
+
* @param cliFlags - Flags explicitly passed via CLI (undefined = not passed)
|
|
56
|
+
* @param configFile - Execution defaults from .bmad-workflow.yaml
|
|
57
|
+
* @param defaults - Hardcoded fallback values
|
|
58
|
+
* @returns Fully resolved execution config
|
|
59
|
+
*/
|
|
60
|
+
export declare function mergeExecutionConfig(cliFlags: CliExecutionFlags, configFile: ConfigExecutionDefaults, defaults?: MergedExecutionConfig): MergedExecutionConfig;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Merge Utility
|
|
3
|
+
*
|
|
4
|
+
* Implements three-layer merge for execution config:
|
|
5
|
+
* CLI flags (highest) → .bmad-workflow.yaml → hardcoded defaults (lowest)
|
|
6
|
+
*
|
|
7
|
+
* Pure function — no side effects, easy to test.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Hardcoded defaults — final fallback when neither CLI nor config provides a value
|
|
11
|
+
*/
|
|
12
|
+
export const EXECUTION_DEFAULTS = {
|
|
13
|
+
epicInterval: 60,
|
|
14
|
+
maxRetries: 0,
|
|
15
|
+
model: undefined,
|
|
16
|
+
parallel: 3,
|
|
17
|
+
pipeline: true,
|
|
18
|
+
prdInterval: 60,
|
|
19
|
+
provider: 'claude',
|
|
20
|
+
qa: false,
|
|
21
|
+
retryBackoffMs: 5000,
|
|
22
|
+
storyInterval: 60,
|
|
23
|
+
timeout: 2_700_000,
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Merge execution config from three layers: CLI flags → config file → hardcoded defaults.
|
|
27
|
+
*
|
|
28
|
+
* For each field, the first defined value wins (left to right):
|
|
29
|
+
* 1. CLI flag (explicit user input)
|
|
30
|
+
* 2. Config file value (from .bmad-workflow.yaml)
|
|
31
|
+
* 3. Hardcoded default
|
|
32
|
+
*
|
|
33
|
+
* @param cliFlags - Flags explicitly passed via CLI (undefined = not passed)
|
|
34
|
+
* @param configFile - Execution defaults from .bmad-workflow.yaml
|
|
35
|
+
* @param defaults - Hardcoded fallback values
|
|
36
|
+
* @returns Fully resolved execution config
|
|
37
|
+
*/
|
|
38
|
+
export function mergeExecutionConfig(cliFlags, configFile, defaults = EXECUTION_DEFAULTS) {
|
|
39
|
+
return {
|
|
40
|
+
epicInterval: cliFlags.epicInterval ?? defaults.epicInterval,
|
|
41
|
+
maxRetries: cliFlags.maxRetries ?? defaults.maxRetries,
|
|
42
|
+
model: cliFlags.model ?? configFile.model ?? defaults.model,
|
|
43
|
+
parallel: cliFlags.parallel ?? configFile.parallel ?? defaults.parallel,
|
|
44
|
+
pipeline: cliFlags.pipeline ?? configFile.pipeline ?? defaults.pipeline,
|
|
45
|
+
prdInterval: cliFlags.prdInterval ?? defaults.prdInterval,
|
|
46
|
+
provider: cliFlags.provider ?? configFile.provider ?? defaults.provider,
|
|
47
|
+
qa: cliFlags.qa ?? configFile.qa_enabled ?? defaults.qa,
|
|
48
|
+
retryBackoffMs: cliFlags.retryBackoffMs ?? defaults.retryBackoffMs,
|
|
49
|
+
storyInterval: cliFlags.storyInterval ?? defaults.storyInterval,
|
|
50
|
+
timeout: cliFlags.timeout ?? configFile.timeout ?? defaults.timeout,
|
|
51
|
+
};
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperdrive.bot/bmad-workflow",
|
|
3
3
|
"description": "AI-driven development workflow orchestration CLI for BMAD projects",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.23",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "DevSquad",
|
|
7
7
|
"email": "marcelo@devsquad.email",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@hyperdrive.bot/plugin-telemetry": "file:../telemetry-plugin",
|
|
18
|
+
"@inquirer/prompts": "^8.3.2",
|
|
18
19
|
"@oclif/core": "^4",
|
|
19
20
|
"@oclif/plugin-help": "^6",
|
|
20
21
|
"bcrypt": "^6.0.0",
|
|
@@ -71,7 +72,8 @@
|
|
|
71
72
|
"dist/",
|
|
72
73
|
"oclif.manifest.json",
|
|
73
74
|
"README.md",
|
|
74
|
-
"LICENSE"
|
|
75
|
+
"LICENSE",
|
|
76
|
+
"assets/"
|
|
75
77
|
],
|
|
76
78
|
"homepage": "https://gitlab.com/dev_squad/repo/cli/bmad-orchestrator#readme",
|
|
77
79
|
"keywords": [
|