@hyperdrive.bot/bmad-workflow 1.0.17 → 1.0.19

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 (110) hide show
  1. package/dist/commands/config/show.js +8 -2
  2. package/dist/commands/decompose.js +26 -5
  3. package/dist/commands/epics/create.d.ts +1 -0
  4. package/dist/commands/mcp/add.d.ts +16 -0
  5. package/dist/commands/mcp/add.js +77 -0
  6. package/dist/commands/mcp/credential/get.d.ts +14 -0
  7. package/dist/commands/mcp/credential/get.js +35 -0
  8. package/dist/commands/mcp/credential/list.d.ts +17 -0
  9. package/dist/commands/mcp/credential/list.js +67 -0
  10. package/dist/commands/mcp/credential/remove.d.ts +18 -0
  11. package/dist/commands/mcp/credential/remove.js +84 -0
  12. package/dist/commands/mcp/credential/set.d.ts +16 -0
  13. package/dist/commands/mcp/credential/set.js +41 -0
  14. package/dist/commands/mcp/credential/validate.d.ts +12 -0
  15. package/dist/commands/mcp/credential/validate.js +150 -0
  16. package/dist/commands/mcp/list.d.ts +17 -0
  17. package/dist/commands/mcp/list.js +80 -0
  18. package/dist/commands/mcp/logs.d.ts +15 -0
  19. package/dist/commands/mcp/logs.js +64 -0
  20. package/dist/commands/mcp/preset.d.ts +15 -0
  21. package/dist/commands/mcp/preset.js +84 -0
  22. package/dist/commands/mcp/remove.d.ts +14 -0
  23. package/dist/commands/mcp/remove.js +36 -0
  24. package/dist/commands/mcp/start.d.ts +12 -0
  25. package/dist/commands/mcp/start.js +80 -0
  26. package/dist/commands/mcp/status.d.ts +30 -0
  27. package/dist/commands/mcp/status.js +180 -0
  28. package/dist/commands/mcp/stop.d.ts +12 -0
  29. package/dist/commands/mcp/stop.js +47 -0
  30. package/dist/commands/stories/create.d.ts +1 -0
  31. package/dist/commands/stories/develop.d.ts +1 -0
  32. package/dist/commands/stories/qa.js +34 -75
  33. package/dist/commands/stories/review.d.ts +124 -0
  34. package/dist/commands/stories/review.js +516 -0
  35. package/dist/commands/workflow.d.ts +89 -0
  36. package/dist/commands/workflow.js +487 -14
  37. package/dist/mcp/types.d.ts +99 -0
  38. package/dist/mcp/types.js +7 -0
  39. package/dist/mcp/utils/docker-utils.d.ts +56 -0
  40. package/dist/mcp/utils/docker-utils.js +108 -0
  41. package/dist/mcp/utils/template-loader.d.ts +21 -0
  42. package/dist/mcp/utils/template-loader.js +60 -0
  43. package/dist/models/agent-options.d.ts +10 -1
  44. package/dist/models/index.d.ts +1 -0
  45. package/dist/models/index.js +1 -0
  46. package/dist/models/workflow-callbacks.d.ts +251 -0
  47. package/dist/models/workflow-callbacks.js +10 -0
  48. package/dist/models/workflow-config.d.ts +77 -0
  49. package/dist/models/workflow-result.d.ts +7 -0
  50. package/dist/services/WorkflowReporter.d.ts +165 -0
  51. package/dist/services/WorkflowReporter.js +691 -0
  52. package/dist/services/agents/claude-agent-runner.js +25 -4
  53. package/dist/services/file-system/path-resolver.d.ts +10 -0
  54. package/dist/services/file-system/path-resolver.js +12 -0
  55. package/dist/services/mcp/mcp-config-manager.d.ts +54 -0
  56. package/dist/services/mcp/mcp-config-manager.js +146 -0
  57. package/dist/services/mcp/mcp-context-injector.d.ts +92 -0
  58. package/dist/services/mcp/mcp-context-injector.js +168 -0
  59. package/dist/services/mcp/mcp-credential-manager.d.ts +48 -0
  60. package/dist/services/mcp/mcp-credential-manager.js +124 -0
  61. package/dist/services/mcp/mcp-health-checker.d.ts +56 -0
  62. package/dist/services/mcp/mcp-health-checker.js +162 -0
  63. package/dist/services/mcp/types/health-types.d.ts +31 -0
  64. package/dist/services/mcp/types/health-types.js +7 -0
  65. package/dist/services/orchestration/dependency-graph-executor.js +1 -1
  66. package/dist/services/orchestration/task-decomposition-service.d.ts +2 -1
  67. package/dist/services/orchestration/task-decomposition-service.js +90 -36
  68. package/dist/services/orchestration/workflow-orchestrator.d.ts +87 -3
  69. package/dist/services/orchestration/workflow-orchestrator.js +1169 -289
  70. package/dist/services/review/ai-review-scanner.d.ts +66 -0
  71. package/dist/services/review/ai-review-scanner.js +142 -0
  72. package/dist/services/review/coderabbit-scanner.d.ts +25 -0
  73. package/dist/services/review/coderabbit-scanner.js +31 -0
  74. package/dist/services/review/index.d.ts +20 -0
  75. package/dist/services/review/index.js +15 -0
  76. package/dist/services/review/lint-scanner.d.ts +46 -0
  77. package/dist/services/review/lint-scanner.js +172 -0
  78. package/dist/services/review/review-config.d.ts +62 -0
  79. package/dist/services/review/review-config.js +91 -0
  80. package/dist/services/review/review-phase-executor.d.ts +69 -0
  81. package/dist/services/review/review-phase-executor.js +152 -0
  82. package/dist/services/review/review-queue.d.ts +98 -0
  83. package/dist/services/review/review-queue.js +174 -0
  84. package/dist/services/review/review-reporter.d.ts +94 -0
  85. package/dist/services/review/review-reporter.js +386 -0
  86. package/dist/services/review/scanner-factory.d.ts +42 -0
  87. package/dist/services/review/scanner-factory.js +60 -0
  88. package/dist/services/review/self-heal-loop.d.ts +58 -0
  89. package/dist/services/review/self-heal-loop.js +132 -0
  90. package/dist/services/review/severity-classifier.d.ts +17 -0
  91. package/dist/services/review/severity-classifier.js +314 -0
  92. package/dist/services/review/tech-debt-tracker.d.ts +52 -0
  93. package/dist/services/review/tech-debt-tracker.js +245 -0
  94. package/dist/services/review/types.d.ts +93 -0
  95. package/dist/services/review/types.js +23 -0
  96. package/dist/services/scaffolding/workflow-session-scaffolder.d.ts +182 -0
  97. package/dist/services/scaffolding/workflow-session-scaffolder.js +236 -0
  98. package/dist/services/validation/config-validator.d.ts +84 -0
  99. package/dist/services/validation/config-validator.js +78 -0
  100. package/dist/utils/colors.d.ts +10 -10
  101. package/dist/utils/colors.js +15 -15
  102. package/dist/utils/credential-utils.d.ts +14 -0
  103. package/dist/utils/credential-utils.js +19 -0
  104. package/dist/utils/duration.d.ts +41 -0
  105. package/dist/utils/duration.js +89 -0
  106. package/dist/utils/listr2-helpers.d.ts +216 -0
  107. package/dist/utils/listr2-helpers.js +334 -0
  108. package/dist/utils/shared-flags.d.ts +1 -0
  109. package/dist/utils/shared-flags.js +11 -2
  110. package/package.json +6 -3
@@ -0,0 +1,99 @@
1
+ /**
2
+ * MCP Gateway Type Definitions
3
+ *
4
+ * Shared interfaces for MCP gateway services (health checker, config manager, credential manager).
5
+ * These types define the contracts that Story 2.4 and Epic 1 services will implement.
6
+ */
7
+ /**
8
+ * Health status of a single component
9
+ */
10
+ export type HealthStatus = 'disabled' | 'healthy' | 'offline' | 'unhealthy';
11
+ /**
12
+ * Health status for an individual MCP server
13
+ */
14
+ export interface ServerHealthStatus {
15
+ error: null | string;
16
+ latency: null | number;
17
+ name: string;
18
+ status: HealthStatus;
19
+ useCase?: string;
20
+ }
21
+ /**
22
+ * Gateway-level health status
23
+ */
24
+ export interface GatewayHealthStatus {
25
+ latency: null | number;
26
+ status: HealthStatus;
27
+ url: string;
28
+ }
29
+ /**
30
+ * Complete health report for the MCP gateway and all servers
31
+ */
32
+ export interface HealthReport {
33
+ gateway: GatewayHealthStatus;
34
+ servers: ServerHealthStatus[];
35
+ }
36
+ /**
37
+ * Credential entry with masked value
38
+ */
39
+ export interface CredentialEntry {
40
+ configured: boolean;
41
+ key: string;
42
+ requiredByPreset: boolean;
43
+ }
44
+ /**
45
+ * MCP server configuration entry
46
+ */
47
+ export interface McpServerConfig {
48
+ apiKeyRequired?: boolean;
49
+ enabled: boolean;
50
+ name: string;
51
+ useCase?: string;
52
+ }
53
+ /**
54
+ * Server template as defined in server-templates/*.yaml
55
+ */
56
+ export interface ServerTemplate {
57
+ api_key_required: boolean;
58
+ args?: string[];
59
+ command?: string;
60
+ enabled: boolean;
61
+ env?: Record<string, string>;
62
+ health_check: {
63
+ command: string;
64
+ method: 'http' | 'tool_call';
65
+ timeout: number;
66
+ };
67
+ layer?: 'direct' | 'gateway';
68
+ name: string;
69
+ transport: 'sse' | 'stdio';
70
+ url?: string;
71
+ use_case: string;
72
+ }
73
+ /**
74
+ * Interface contract for McpHealthChecker (Story 2.4)
75
+ */
76
+ export interface IHealthChecker {
77
+ checkAll(): Promise<HealthReport>;
78
+ }
79
+ /**
80
+ * Interface contract for McpConfigManager (Epic 1)
81
+ */
82
+ export interface IConfigManager {
83
+ addServer(template: ServerTemplate): void;
84
+ applyPreset(presetName: string): void;
85
+ getEnabledServers(): McpServerConfig[];
86
+ getGatewayUrl(): string;
87
+ getPresetName(): string;
88
+ removeServer(name: string): boolean;
89
+ }
90
+ /**
91
+ * Interface contract for McpCredentialManager (Epic 1)
92
+ */
93
+ export interface ICredentialManager {
94
+ get(key: string): string | null;
95
+ list(): CredentialEntry[];
96
+ remove(key: string): boolean;
97
+ resolve(key: string): string | null;
98
+ set(key: string, value: string): void;
99
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP Gateway Type Definitions
3
+ *
4
+ * Shared interfaces for MCP gateway services (health checker, config manager, credential manager).
5
+ * These types define the contracts that Story 2.4 and Epic 1 services will implement.
6
+ */
7
+ export {};
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Docker Availability Detection Utilities
3
+ *
4
+ * Provides functions to check Docker availability, resolve the gateway
5
+ * compose file path, and format Docker errors into user-friendly messages.
6
+ */
7
+ /**
8
+ * Result of Docker availability check
9
+ */
10
+ export interface DockerAvailabilityResult {
11
+ available: boolean;
12
+ error?: string;
13
+ reason?: 'daemon-not-running' | 'not-installed';
14
+ }
15
+ /**
16
+ * Check if Docker is available and the daemon is running
17
+ *
18
+ * Executes `docker info` to verify both installation and daemon status.
19
+ *
20
+ * @returns DockerAvailabilityResult with availability status and error details
21
+ */
22
+ export declare function isDockerAvailable(): DockerAvailabilityResult;
23
+ /**
24
+ * Resolve the path to the Docker Compose gateway file
25
+ *
26
+ * The compose file is expected at src/mcp/infrastructure/docker-compose.gateway.yml
27
+ * relative to the CLI package root.
28
+ *
29
+ * @returns Absolute path to docker-compose.gateway.yml
30
+ */
31
+ export declare function getDockerComposeFilePath(): string;
32
+ /**
33
+ * Check if the Docker Compose gateway file exists
34
+ *
35
+ * @returns true if the compose file exists at the expected path
36
+ */
37
+ export declare function dockerComposeFileExists(): boolean;
38
+ /**
39
+ * Format a Docker error into a user-friendly message with troubleshooting hints
40
+ *
41
+ * @param result - Docker availability check result
42
+ * @returns Formatted error message string
43
+ */
44
+ export declare function formatDockerError(result: DockerAvailabilityResult): string;
45
+ /**
46
+ * Default gateway health endpoint URL
47
+ */
48
+ export declare const DEFAULT_GATEWAY_URL = "http://localhost:8080";
49
+ /**
50
+ * Default health check poll interval in milliseconds
51
+ */
52
+ export declare const HEALTH_CHECK_INTERVAL_MS = 2000;
53
+ /**
54
+ * Default health check timeout in milliseconds
55
+ */
56
+ export declare const HEALTH_CHECK_TIMEOUT_MS = 30000;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Docker Availability Detection Utilities
3
+ *
4
+ * Provides functions to check Docker availability, resolve the gateway
5
+ * compose file path, and format Docker errors into user-friendly messages.
6
+ */
7
+ import { execSync } from 'node:child_process';
8
+ import { existsSync } from 'node:fs';
9
+ import { dirname, resolve } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { createLogger } from '../../utils/logger.js';
12
+ const logger = createLogger({ namespace: 'mcp:utils:docker' });
13
+ /**
14
+ * Check if Docker is available and the daemon is running
15
+ *
16
+ * Executes `docker info` to verify both installation and daemon status.
17
+ *
18
+ * @returns DockerAvailabilityResult with availability status and error details
19
+ */
20
+ export function isDockerAvailable() {
21
+ try {
22
+ execSync('docker info', { stdio: 'pipe', timeout: 10_000 });
23
+ logger.debug('Docker is available');
24
+ return { available: true };
25
+ }
26
+ catch (error) {
27
+ const err = error;
28
+ const stderr = err.stderr ? err.stderr.toString() : err.message;
29
+ if (stderr.includes('command not found') || stderr.includes('not recognized') || stderr.includes('ENOENT')) {
30
+ logger.warn('Docker is not installed');
31
+ return {
32
+ available: false,
33
+ error: stderr,
34
+ reason: 'not-installed',
35
+ };
36
+ }
37
+ logger.warn('Docker daemon is not running');
38
+ return {
39
+ available: false,
40
+ error: stderr,
41
+ reason: 'daemon-not-running',
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * Resolve the path to the Docker Compose gateway file
47
+ *
48
+ * The compose file is expected at src/mcp/infrastructure/docker-compose.gateway.yml
49
+ * relative to the CLI package root.
50
+ *
51
+ * @returns Absolute path to docker-compose.gateway.yml
52
+ */
53
+ export function getDockerComposeFilePath() {
54
+ const currentDir = dirname(fileURLToPath(import.meta.url));
55
+ // From src/mcp/utils/ → src/mcp/infrastructure/
56
+ const composePath = resolve(currentDir, '..', 'infrastructure', 'docker-compose.gateway.yml');
57
+ logger.debug('Resolved Docker Compose file path: %s', composePath);
58
+ return composePath;
59
+ }
60
+ /**
61
+ * Check if the Docker Compose gateway file exists
62
+ *
63
+ * @returns true if the compose file exists at the expected path
64
+ */
65
+ export function dockerComposeFileExists() {
66
+ const composePath = getDockerComposeFilePath();
67
+ return existsSync(composePath);
68
+ }
69
+ /**
70
+ * Format a Docker error into a user-friendly message with troubleshooting hints
71
+ *
72
+ * @param result - Docker availability check result
73
+ * @returns Formatted error message string
74
+ */
75
+ export function formatDockerError(result) {
76
+ if (result.reason === 'not-installed') {
77
+ return [
78
+ 'Docker is not installed on this system.',
79
+ '',
80
+ 'To install Docker:',
81
+ ' macOS: brew install --cask docker',
82
+ ' Linux: https://docs.docker.com/engine/install/',
83
+ ' Windows: https://docs.docker.com/desktop/install/windows-install/',
84
+ ].join('\n');
85
+ }
86
+ if (result.reason === 'daemon-not-running') {
87
+ return [
88
+ 'Docker daemon is not running.',
89
+ '',
90
+ 'To start Docker:',
91
+ ' macOS/Windows: Open the Docker Desktop application',
92
+ ' Linux: sudo systemctl start docker',
93
+ ].join('\n');
94
+ }
95
+ return `Docker error: ${result.error || 'Unknown error'}`;
96
+ }
97
+ /**
98
+ * Default gateway health endpoint URL
99
+ */
100
+ export const DEFAULT_GATEWAY_URL = 'http://localhost:8080';
101
+ /**
102
+ * Default health check poll interval in milliseconds
103
+ */
104
+ export const HEALTH_CHECK_INTERVAL_MS = 2000;
105
+ /**
106
+ * Default health check timeout in milliseconds
107
+ */
108
+ export const HEALTH_CHECK_TIMEOUT_MS = 30_000;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Server Template Loader
3
+ *
4
+ * Loads and validates MCP server template YAML files from the
5
+ * src/mcp/server-templates/ directory.
6
+ */
7
+ import type { ServerTemplate } from '../types.js';
8
+ /**
9
+ * List all available server template names by scanning the server-templates directory
10
+ *
11
+ * @returns Array of template names (without .yaml extension)
12
+ */
13
+ export declare function listAvailableTemplates(): string[];
14
+ /**
15
+ * Load and parse a server template by name
16
+ *
17
+ * @param name - Server template name (e.g., 'context7', 'exa')
18
+ * @returns Parsed ServerTemplate object
19
+ * @throws Error if template not found, with available templates listed
20
+ */
21
+ export declare function loadServerTemplate(name: string): ServerTemplate;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Server Template Loader
3
+ *
4
+ * Loads and validates MCP server template YAML files from the
5
+ * src/mcp/server-templates/ directory.
6
+ */
7
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
8
+ import { dirname, resolve } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ import yaml from 'js-yaml';
11
+ import { createLogger } from '../../utils/logger.js';
12
+ const logger = createLogger({ namespace: 'mcp:utils:template-loader' });
13
+ /**
14
+ * Resolve the absolute path to the server-templates directory
15
+ */
16
+ function getTemplatesDir() {
17
+ const currentDir = dirname(fileURLToPath(import.meta.url));
18
+ return resolve(currentDir, '..', 'server-templates');
19
+ }
20
+ /**
21
+ * List all available server template names by scanning the server-templates directory
22
+ *
23
+ * @returns Array of template names (without .yaml extension)
24
+ */
25
+ export function listAvailableTemplates() {
26
+ const templatesDir = getTemplatesDir();
27
+ logger.debug('Scanning templates directory: %s', templatesDir);
28
+ if (!existsSync(templatesDir)) {
29
+ logger.warn('Templates directory not found: %s', templatesDir);
30
+ return [];
31
+ }
32
+ const files = readdirSync(templatesDir);
33
+ return files
34
+ .filter((f) => f.endsWith('.yaml') && !f.startsWith('__'))
35
+ .map((f) => f.replace('.yaml', ''))
36
+ .sort();
37
+ }
38
+ /**
39
+ * Load and parse a server template by name
40
+ *
41
+ * @param name - Server template name (e.g., 'context7', 'exa')
42
+ * @returns Parsed ServerTemplate object
43
+ * @throws Error if template not found, with available templates listed
44
+ */
45
+ export function loadServerTemplate(name) {
46
+ const templatesDir = getTemplatesDir();
47
+ const templatePath = resolve(templatesDir, `${name}.yaml`);
48
+ logger.debug('Loading template: %s from %s', name, templatePath);
49
+ if (!existsSync(templatePath)) {
50
+ const available = listAvailableTemplates();
51
+ throw new Error(`Server template '${name}' not found. Available templates: ${available.join(', ')}`);
52
+ }
53
+ const content = readFileSync(templatePath, 'utf8');
54
+ const parsed = yaml.load(content);
55
+ if (!parsed || typeof parsed !== 'object' || !parsed.name) {
56
+ throw new Error(`Invalid server template format in '${name}.yaml': missing required 'name' field`);
57
+ }
58
+ logger.info('Loaded template: %s (transport=%s, api_key_required=%s)', parsed.name, parsed.transport, parsed.api_key_required);
59
+ return parsed;
60
+ }
@@ -2,7 +2,7 @@ import type { AgentResult } from './agent-result.js';
2
2
  /**
3
3
  * Available BMAD agent types
4
4
  */
5
- export type AgentType = 'analyst' | 'architect' | 'dev' | 'pm' | 'prd-fixer' | 'quick-flow-solo-dev' | 'sm' | 'tea' | 'tech-writer' | 'ux-designer';
5
+ export type AgentType = 'analyst' | 'architect' | 'dev' | 'pm' | 'prd-fixer' | 'qa' | 'quick-flow-solo-dev' | 'sm' | 'tea' | 'tech-writer' | 'ux-designer';
6
6
  /**
7
7
  * Agent options without prompt and callbacks (used internally)
8
8
  */
@@ -23,6 +23,10 @@ export interface AgentOptions {
23
23
  * The type of agent to execute
24
24
  */
25
25
  agentType: AgentType;
26
+ /**
27
+ * Working directory for the agent process
28
+ */
29
+ cwd?: string;
26
30
  /**
27
31
  * Additional CLI flags to pass to the Claude executable
28
32
  */
@@ -50,6 +54,11 @@ export interface AgentOptions {
50
54
  * File references to include in the agent execution
51
55
  */
52
56
  references?: string[];
57
+ /**
58
+ * System prompt to append via --append-system-prompt (Claude only).
59
+ * Used to enforce output format constraints (e.g., YAML-only output).
60
+ */
61
+ systemPrompt?: string;
53
62
  /**
54
63
  * Timeout in milliseconds (default: 1800000ms = 30 minutes)
55
64
  */
@@ -6,5 +6,6 @@ export * from './agent-result.js';
6
6
  export * from './phase-result.js';
7
7
  export * from './provider.js';
8
8
  export * from './story.js';
9
+ export * from './workflow-callbacks.js';
9
10
  export * from './workflow-config.js';
10
11
  export * from './workflow-result.js';
@@ -6,5 +6,6 @@ export * from './agent-result.js';
6
6
  export * from './phase-result.js';
7
7
  export * from './provider.js';
8
8
  export * from './story.js';
9
+ export * from './workflow-callbacks.js';
9
10
  export * from './workflow-config.js';
10
11
  export * from './workflow-result.js';
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Workflow Callbacks
3
+ *
4
+ * Interfaces for lifecycle event callbacks that consumers can register
5
+ * to observe workflow execution without coupling to orchestration internals.
6
+ *
7
+ * Callbacks are fire-and-forget (synchronous but non-blocking) and errors
8
+ * in callbacks do not interrupt workflow execution.
9
+ */
10
+ /**
11
+ * Context for phase lifecycle events
12
+ *
13
+ * Provided when a workflow phase (epic, story, dev, qa) starts or completes.
14
+ */
15
+ export interface PhaseContext {
16
+ /**
17
+ * Phase name: 'epic' | 'story' | 'dev' | 'qa'
18
+ */
19
+ phaseName: string;
20
+ /**
21
+ * Phase start timestamp (epoch ms)
22
+ */
23
+ startTime: number;
24
+ /**
25
+ * Phase end timestamp (epoch ms, only in onPhaseComplete)
26
+ */
27
+ endTime?: number;
28
+ /**
29
+ * Phase duration in milliseconds (only in onPhaseComplete)
30
+ */
31
+ duration?: number;
32
+ /**
33
+ * Total items to process in this phase
34
+ */
35
+ itemCount: number;
36
+ /**
37
+ * Number of successfully processed items (only in onPhaseComplete)
38
+ */
39
+ successCount?: number;
40
+ /**
41
+ * Number of failed items (only in onPhaseComplete)
42
+ */
43
+ failureCount?: number;
44
+ /**
45
+ * Whether the phase was skipped
46
+ */
47
+ skipped?: boolean;
48
+ /**
49
+ * Additional metadata specific to the phase
50
+ */
51
+ metadata?: Record<string, unknown>;
52
+ }
53
+ /**
54
+ * Context for layer/batch lifecycle events
55
+ *
56
+ * Provided when a batch of items starts or completes processing.
57
+ * Layers represent groups of items processed in parallel.
58
+ */
59
+ export interface LayerContext {
60
+ /**
61
+ * Phase this layer belongs to
62
+ */
63
+ phaseName: string;
64
+ /**
65
+ * Zero-based layer index within the phase
66
+ */
67
+ layerIndex: number;
68
+ /**
69
+ * Total number of layers in the phase
70
+ */
71
+ totalLayers: number;
72
+ /**
73
+ * Number of items (spawns) in this layer
74
+ */
75
+ spawnCount: number;
76
+ /**
77
+ * Whether items in this layer are processed in parallel
78
+ */
79
+ parallel: boolean;
80
+ /**
81
+ * Layer start timestamp (epoch ms)
82
+ */
83
+ startTime: number;
84
+ /**
85
+ * Layer end timestamp (epoch ms, only in onLayerComplete)
86
+ */
87
+ endTime?: number;
88
+ /**
89
+ * Layer duration in milliseconds (only in onLayerComplete)
90
+ */
91
+ duration?: number;
92
+ /**
93
+ * Number of successful spawns (only in onLayerComplete)
94
+ */
95
+ successCount?: number;
96
+ /**
97
+ * Number of failed spawns (only in onLayerComplete)
98
+ */
99
+ failureCount?: number;
100
+ }
101
+ /**
102
+ * Context for spawn (agent execution) lifecycle events
103
+ *
104
+ * Provided when an individual agent execution starts, completes, or produces output.
105
+ */
106
+ export interface SpawnContext {
107
+ /**
108
+ * Unique identifier for this spawn
109
+ */
110
+ spawnId: string;
111
+ /**
112
+ * Phase this spawn belongs to
113
+ */
114
+ phaseName: string;
115
+ /**
116
+ * Type of agent being spawned: 'architect' | 'sm' | 'dev' | 'qa'
117
+ */
118
+ agentType: string;
119
+ /**
120
+ * Item identifier (epic number, story number, etc.)
121
+ */
122
+ itemId: string;
123
+ /**
124
+ * Item title or description
125
+ */
126
+ itemTitle?: string;
127
+ /**
128
+ * Output file path (if applicable)
129
+ */
130
+ outputPath?: string;
131
+ /**
132
+ * The prompt sent to the agent
133
+ */
134
+ prompt?: string;
135
+ /**
136
+ * Spawn start timestamp (epoch ms)
137
+ */
138
+ startTime: number;
139
+ /**
140
+ * Spawn end timestamp (epoch ms, only in onSpawnComplete)
141
+ */
142
+ endTime?: number;
143
+ /**
144
+ * Spawn duration in milliseconds (only in onSpawnComplete)
145
+ */
146
+ duration?: number;
147
+ /**
148
+ * Whether the spawn succeeded (only in onSpawnComplete)
149
+ */
150
+ success?: boolean;
151
+ /**
152
+ * Agent output text (only in onSpawnComplete or onSpawnOutput)
153
+ */
154
+ output?: string;
155
+ /**
156
+ * Error message if spawn failed (only in onSpawnComplete)
157
+ */
158
+ error?: string;
159
+ /**
160
+ * Worker ID for pipelined execution
161
+ */
162
+ workerId?: number;
163
+ /**
164
+ * Additional metadata
165
+ */
166
+ metadata?: Record<string, unknown>;
167
+ }
168
+ /**
169
+ * Context for error events
170
+ *
171
+ * Provided when an error occurs during workflow execution.
172
+ */
173
+ export interface ErrorContext {
174
+ /**
175
+ * Error message
176
+ */
177
+ message: string;
178
+ /**
179
+ * Phase where the error occurred (if applicable)
180
+ */
181
+ phaseName?: string;
182
+ /**
183
+ * Spawn ID where the error occurred (if applicable)
184
+ */
185
+ spawnId?: string;
186
+ /**
187
+ * Item identifier related to the error (if applicable)
188
+ */
189
+ itemId?: string;
190
+ /**
191
+ * Error stack trace (if available)
192
+ */
193
+ stack?: string;
194
+ /**
195
+ * Original error object
196
+ */
197
+ error?: Error;
198
+ /**
199
+ * Timestamp when error occurred (epoch ms)
200
+ */
201
+ timestamp: number;
202
+ /**
203
+ * Whether the error is recoverable (workflow can continue)
204
+ */
205
+ recoverable: boolean;
206
+ /**
207
+ * Additional context about the error
208
+ */
209
+ metadata?: Record<string, unknown>;
210
+ }
211
+ /**
212
+ * Workflow lifecycle callbacks
213
+ *
214
+ * Optional callback functions that consumers can register to observe
215
+ * workflow execution events. All callbacks are wrapped in try-catch
216
+ * to prevent errors from interrupting workflow execution.
217
+ */
218
+ export interface WorkflowCallbacks {
219
+ /**
220
+ * Called when a phase starts execution
221
+ */
222
+ onPhaseStart?: (context: PhaseContext) => void;
223
+ /**
224
+ * Called when a phase completes execution
225
+ */
226
+ onPhaseComplete?: (context: PhaseContext) => void;
227
+ /**
228
+ * Called when a batch/layer starts processing
229
+ */
230
+ onLayerStart?: (context: LayerContext) => void;
231
+ /**
232
+ * Called when a batch/layer completes processing
233
+ */
234
+ onLayerComplete?: (context: LayerContext) => void;
235
+ /**
236
+ * Called when an agent spawn starts
237
+ */
238
+ onSpawnStart?: (context: SpawnContext) => void;
239
+ /**
240
+ * Called when an agent spawn completes
241
+ */
242
+ onSpawnComplete?: (context: SpawnContext) => void;
243
+ /**
244
+ * Called when an agent produces streaming output
245
+ */
246
+ onSpawnOutput?: (context: SpawnContext, output: string) => void;
247
+ /**
248
+ * Called when an error occurs
249
+ */
250
+ onError?: (context: ErrorContext) => void;
251
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Workflow Callbacks
3
+ *
4
+ * Interfaces for lifecycle event callbacks that consumers can register
5
+ * to observe workflow execution without coupling to orchestration internals.
6
+ *
7
+ * Callbacks are fire-and-forget (synchronous but non-blocking) and errors
8
+ * in callbacks do not interrupt workflow execution.
9
+ */
10
+ export {};