@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.
- package/dist/commands/config/show.js +8 -2
- package/dist/commands/decompose.js +26 -5
- package/dist/commands/epics/create.d.ts +1 -0
- package/dist/commands/mcp/add.d.ts +16 -0
- package/dist/commands/mcp/add.js +77 -0
- package/dist/commands/mcp/credential/get.d.ts +14 -0
- package/dist/commands/mcp/credential/get.js +35 -0
- package/dist/commands/mcp/credential/list.d.ts +17 -0
- package/dist/commands/mcp/credential/list.js +67 -0
- package/dist/commands/mcp/credential/remove.d.ts +18 -0
- package/dist/commands/mcp/credential/remove.js +84 -0
- package/dist/commands/mcp/credential/set.d.ts +16 -0
- package/dist/commands/mcp/credential/set.js +41 -0
- package/dist/commands/mcp/credential/validate.d.ts +12 -0
- package/dist/commands/mcp/credential/validate.js +150 -0
- package/dist/commands/mcp/list.d.ts +17 -0
- package/dist/commands/mcp/list.js +80 -0
- package/dist/commands/mcp/logs.d.ts +15 -0
- package/dist/commands/mcp/logs.js +64 -0
- package/dist/commands/mcp/preset.d.ts +15 -0
- package/dist/commands/mcp/preset.js +84 -0
- package/dist/commands/mcp/remove.d.ts +14 -0
- package/dist/commands/mcp/remove.js +36 -0
- package/dist/commands/mcp/start.d.ts +12 -0
- package/dist/commands/mcp/start.js +80 -0
- package/dist/commands/mcp/status.d.ts +30 -0
- package/dist/commands/mcp/status.js +180 -0
- package/dist/commands/mcp/stop.d.ts +12 -0
- package/dist/commands/mcp/stop.js +47 -0
- package/dist/commands/stories/create.d.ts +1 -0
- package/dist/commands/stories/develop.d.ts +1 -0
- package/dist/commands/stories/qa.js +34 -75
- package/dist/commands/stories/review.d.ts +124 -0
- package/dist/commands/stories/review.js +516 -0
- package/dist/commands/workflow.d.ts +89 -0
- package/dist/commands/workflow.js +487 -14
- package/dist/mcp/types.d.ts +99 -0
- package/dist/mcp/types.js +7 -0
- package/dist/mcp/utils/docker-utils.d.ts +56 -0
- package/dist/mcp/utils/docker-utils.js +108 -0
- package/dist/mcp/utils/template-loader.d.ts +21 -0
- package/dist/mcp/utils/template-loader.js +60 -0
- package/dist/models/agent-options.d.ts +10 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.js +1 -0
- package/dist/models/workflow-callbacks.d.ts +251 -0
- package/dist/models/workflow-callbacks.js +10 -0
- package/dist/models/workflow-config.d.ts +77 -0
- package/dist/models/workflow-result.d.ts +7 -0
- package/dist/services/WorkflowReporter.d.ts +165 -0
- package/dist/services/WorkflowReporter.js +691 -0
- package/dist/services/agents/claude-agent-runner.js +25 -4
- package/dist/services/file-system/path-resolver.d.ts +10 -0
- package/dist/services/file-system/path-resolver.js +12 -0
- package/dist/services/mcp/mcp-config-manager.d.ts +54 -0
- package/dist/services/mcp/mcp-config-manager.js +146 -0
- package/dist/services/mcp/mcp-context-injector.d.ts +92 -0
- package/dist/services/mcp/mcp-context-injector.js +168 -0
- package/dist/services/mcp/mcp-credential-manager.d.ts +48 -0
- package/dist/services/mcp/mcp-credential-manager.js +124 -0
- package/dist/services/mcp/mcp-health-checker.d.ts +56 -0
- package/dist/services/mcp/mcp-health-checker.js +162 -0
- package/dist/services/mcp/types/health-types.d.ts +31 -0
- package/dist/services/mcp/types/health-types.js +7 -0
- package/dist/services/orchestration/dependency-graph-executor.js +1 -1
- package/dist/services/orchestration/task-decomposition-service.d.ts +2 -1
- package/dist/services/orchestration/task-decomposition-service.js +90 -36
- package/dist/services/orchestration/workflow-orchestrator.d.ts +87 -3
- package/dist/services/orchestration/workflow-orchestrator.js +1169 -289
- package/dist/services/review/ai-review-scanner.d.ts +66 -0
- package/dist/services/review/ai-review-scanner.js +142 -0
- package/dist/services/review/coderabbit-scanner.d.ts +25 -0
- package/dist/services/review/coderabbit-scanner.js +31 -0
- package/dist/services/review/index.d.ts +20 -0
- package/dist/services/review/index.js +15 -0
- package/dist/services/review/lint-scanner.d.ts +46 -0
- package/dist/services/review/lint-scanner.js +172 -0
- package/dist/services/review/review-config.d.ts +62 -0
- package/dist/services/review/review-config.js +91 -0
- package/dist/services/review/review-phase-executor.d.ts +69 -0
- package/dist/services/review/review-phase-executor.js +152 -0
- package/dist/services/review/review-queue.d.ts +98 -0
- package/dist/services/review/review-queue.js +174 -0
- package/dist/services/review/review-reporter.d.ts +94 -0
- package/dist/services/review/review-reporter.js +386 -0
- package/dist/services/review/scanner-factory.d.ts +42 -0
- package/dist/services/review/scanner-factory.js +60 -0
- package/dist/services/review/self-heal-loop.d.ts +58 -0
- package/dist/services/review/self-heal-loop.js +132 -0
- package/dist/services/review/severity-classifier.d.ts +17 -0
- package/dist/services/review/severity-classifier.js +314 -0
- package/dist/services/review/tech-debt-tracker.d.ts +52 -0
- package/dist/services/review/tech-debt-tracker.js +245 -0
- package/dist/services/review/types.d.ts +93 -0
- package/dist/services/review/types.js +23 -0
- package/dist/services/scaffolding/workflow-session-scaffolder.d.ts +182 -0
- package/dist/services/scaffolding/workflow-session-scaffolder.js +236 -0
- package/dist/services/validation/config-validator.d.ts +84 -0
- package/dist/services/validation/config-validator.js +78 -0
- package/dist/utils/colors.d.ts +10 -10
- package/dist/utils/colors.js +15 -15
- package/dist/utils/credential-utils.d.ts +14 -0
- package/dist/utils/credential-utils.js +19 -0
- package/dist/utils/duration.d.ts +41 -0
- package/dist/utils/duration.js +89 -0
- package/dist/utils/listr2-helpers.d.ts +216 -0
- package/dist/utils/listr2-helpers.js +334 -0
- package/dist/utils/shared-flags.d.ts +1 -0
- package/dist/utils/shared-flags.js +11 -2
- 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,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
|
*/
|
package/dist/models/index.d.ts
CHANGED
package/dist/models/index.js
CHANGED
|
@@ -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 {};
|