@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
@@ -7,6 +7,77 @@
7
7
  */
8
8
  import { z } from 'zod';
9
9
  import { ValidationError } from '../../utils/errors.js';
10
+ /**
11
+ * Valid scanner identifiers for automated code review
12
+ */
13
+ const VALID_SCANNERS = ['ai', 'lint', 'coderabbit'];
14
+ /**
15
+ * Valid severity levels
16
+ */
17
+ const VALID_SEVERITIES = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'];
18
+ /**
19
+ * Zod schema for review.severity configuration
20
+ */
21
+ const severityArraySchema = z.array(z.enum(VALID_SEVERITIES, {
22
+ message: `Invalid severity level. Valid values: ${VALID_SEVERITIES.join(', ')}`,
23
+ }));
24
+ /**
25
+ * Zod schema for review.pathRules entries
26
+ */
27
+ const pathRuleSchema = z.object({
28
+ focus: z.string().min(1, { message: 'Path rule focus description is required' }),
29
+ pattern: z.string().min(1, { message: 'Path rule pattern is required' }),
30
+ });
31
+ /**
32
+ * Zod schema for review configuration section
33
+ *
34
+ * Defines scanners, severity thresholds, self-heal limits, and path rules
35
+ * for automated code review in the BMAD workflow pipeline.
36
+ */
37
+ export const reviewConfigSchema = z
38
+ .object({
39
+ enabled: z.boolean().default(false),
40
+ pathRules: z.array(pathRuleSchema).optional(),
41
+ scanners: z
42
+ .array(z.enum(VALID_SCANNERS, {
43
+ message: `Unknown scanner name. Valid values: ${VALID_SCANNERS.join(', ')}`,
44
+ }))
45
+ .default(['ai', 'lint']),
46
+ selfHeal: z
47
+ .object({
48
+ fixAgent: z.string().default('dev'),
49
+ fixTimeout: z.number().int().positive({ message: 'selfHeal.fixTimeout must be a positive integer' }).default(300_000),
50
+ maxIterations: z
51
+ .number()
52
+ .int()
53
+ .positive({ message: 'selfHeal.maxIterations must be a positive integer' })
54
+ .default(3),
55
+ })
56
+ .default(() => ({ fixAgent: 'dev', fixTimeout: 300_000, maxIterations: 3 })),
57
+ severity: z
58
+ .object({
59
+ blockOn: severityArraySchema.default(['CRITICAL', 'HIGH']),
60
+ documentOn: severityArraySchema.default(['MEDIUM']),
61
+ ignoreOn: severityArraySchema.default(['LOW']),
62
+ })
63
+ .default(() => ({
64
+ blockOn: ['CRITICAL', 'HIGH'],
65
+ documentOn: ['MEDIUM'],
66
+ ignoreOn: ['LOW'],
67
+ })),
68
+ })
69
+ .superRefine((data, ctx) => {
70
+ // Validate that blockOn and ignoreOn do not overlap
71
+ const blockSet = new Set(data.severity.blockOn);
72
+ const overlapping = data.severity.ignoreOn.filter((s) => blockSet.has(s));
73
+ if (overlapping.length > 0) {
74
+ ctx.addIssue({
75
+ code: z.ZodIssueCode.custom,
76
+ message: `severity.blockOn and severity.ignoreOn must not overlap. Overlapping: ${overlapping.join(', ')}`,
77
+ path: ['severity'],
78
+ });
79
+ }
80
+ });
10
81
  /**
11
82
  * Zod schema for core configuration
12
83
  *
@@ -25,6 +96,7 @@ const configSchema = z.object({
25
96
  qaLocation: z.string().optional(),
26
97
  })
27
98
  .optional(),
99
+ review: reviewConfigSchema.optional(),
28
100
  });
29
101
  /**
30
102
  * ConfigValidator service validates configuration files against schemas
@@ -105,11 +177,17 @@ export class ConfigValidator {
105
177
  devStoryLocation: 'docs/stories',
106
178
  'prd.prdFile': 'docs/prd.md',
107
179
  'qa.qaLocation': 'docs/qa',
180
+ 'review.scanners': '[ai, lint]',
181
+ 'review.severity.blockOn': '[CRITICAL, HIGH]',
182
+ 'review.selfHeal.maxIterations': '3',
108
183
  };
109
184
  const fieldDisplayNames = {
110
185
  devStoryLocation: 'Story directory path (devStoryLocation)',
111
186
  'prd.prdFile': 'PRD file path (prd.prdFile)',
112
187
  'qa.qaLocation': 'QA location path (qa.qaLocation)',
188
+ 'review.scanners': 'Review scanners (review.scanners)',
189
+ 'review.severity.blockOn': 'Review severity blockOn (review.severity.blockOn)',
190
+ 'review.selfHeal.maxIterations': 'Self-heal max iterations (review.selfHeal.maxIterations)',
113
191
  };
114
192
  const example = examples[fieldName] || 'path/to/directory';
115
193
  const displayName = fieldDisplayNames[fieldName] || fieldName;
@@ -1,36 +1,36 @@
1
1
  /**
2
- * Format a success message with green color and checkmark icon
2
+ * Format a success message with checkmark icon
3
3
  *
4
4
  * @param text - Message text to format
5
- * @returns Formatted string with ANSI color codes and ✓ icon
5
+ * @returns Formatted string with ✓ icon
6
6
  */
7
7
  export declare const success: (text: string) => string;
8
8
  /**
9
- * Format an error message with red color and X icon
9
+ * Format an error message with X icon
10
10
  *
11
11
  * @param text - Message text to format
12
- * @returns Formatted string with ANSI color codes and ✗ icon
12
+ * @returns Formatted string with ✗ icon
13
13
  */
14
14
  export declare const error: (text: string) => string;
15
15
  /**
16
- * Format a warning message with yellow color and warning icon
16
+ * Format a warning message with warning icon
17
17
  *
18
18
  * @param text - Message text to format
19
- * @returns Formatted string with ANSI color codes and ⚠ icon
19
+ * @returns Formatted string with ⚠ icon
20
20
  */
21
21
  export declare const warning: (text: string) => string;
22
22
  /**
23
- * Format an info message with blue color and info icon
23
+ * Format an info message with info icon
24
24
  *
25
25
  * @param text - Message text to format
26
- * @returns Formatted string with ANSI color codes and ℹ icon
26
+ * @returns Formatted string with ℹ icon
27
27
  */
28
28
  export declare const info: (text: string) => string;
29
29
  /**
30
- * Highlight text with cyan color for emphasis
30
+ * Highlight text for emphasis
31
31
  *
32
32
  * @param text - Text to highlight
33
- * @returns Formatted string with ANSI color codes
33
+ * @returns Formatted string with ANSI bold codes
34
34
  */
35
35
  export declare const highlight: (text: string) => string;
36
36
  /**
@@ -1,39 +1,39 @@
1
1
  import chalk from 'chalk';
2
2
  /**
3
- * Format a success message with green color and checkmark icon
3
+ * Format a success message with checkmark icon
4
4
  *
5
5
  * @param text - Message text to format
6
- * @returns Formatted string with ANSI color codes and ✓ icon
6
+ * @returns Formatted string with ✓ icon
7
7
  */
8
- export const success = (text) => chalk.green(`✓ ${text}`);
8
+ export const success = (text) => chalk.bold(`✓ ${text}`);
9
9
  /**
10
- * Format an error message with red color and X icon
10
+ * Format an error message with X icon
11
11
  *
12
12
  * @param text - Message text to format
13
- * @returns Formatted string with ANSI color codes and ✗ icon
13
+ * @returns Formatted string with ✗ icon
14
14
  */
15
- export const error = (text) => chalk.red(`✗ ${text}`);
15
+ export const error = (text) => chalk.bold(`✗ ${text}`);
16
16
  /**
17
- * Format a warning message with yellow color and warning icon
17
+ * Format a warning message with warning icon
18
18
  *
19
19
  * @param text - Message text to format
20
- * @returns Formatted string with ANSI color codes and ⚠ icon
20
+ * @returns Formatted string with ⚠ icon
21
21
  */
22
- export const warning = (text) => chalk.yellow(`⚠ ${text}`);
22
+ export const warning = (text) => chalk.bold(`⚠ ${text}`);
23
23
  /**
24
- * Format an info message with blue color and info icon
24
+ * Format an info message with info icon
25
25
  *
26
26
  * @param text - Message text to format
27
- * @returns Formatted string with ANSI color codes and ℹ icon
27
+ * @returns Formatted string with ℹ icon
28
28
  */
29
- export const info = (text) => chalk.blue(`ℹ ${text}`);
29
+ export const info = (text) => `ℹ ${text}`;
30
30
  /**
31
- * Highlight text with cyan color for emphasis
31
+ * Highlight text for emphasis
32
32
  *
33
33
  * @param text - Text to highlight
34
- * @returns Formatted string with ANSI color codes
34
+ * @returns Formatted string with ANSI bold codes
35
35
  */
36
- export const highlight = (text) => chalk.cyan(text);
36
+ export const highlight = (text) => chalk.bold(text);
37
37
  /**
38
38
  * Format text in bold style
39
39
  *
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Credential utility functions
3
+ *
4
+ * Shared helpers for credential display masking.
5
+ */
6
+ /**
7
+ * Mask a credential value for display.
8
+ * Shows first 3 chars + '***...***' + last 3 chars.
9
+ * For values shorter than 8 chars, mask entirely as '***'.
10
+ *
11
+ * @param value - The raw credential value
12
+ * @returns Masked string safe for display
13
+ */
14
+ export declare function maskValue(value: string): string;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Credential utility functions
3
+ *
4
+ * Shared helpers for credential display masking.
5
+ */
6
+ /**
7
+ * Mask a credential value for display.
8
+ * Shows first 3 chars + '***...***' + last 3 chars.
9
+ * For values shorter than 8 chars, mask entirely as '***'.
10
+ *
11
+ * @param value - The raw credential value
12
+ * @returns Masked string safe for display
13
+ */
14
+ export function maskValue(value) {
15
+ if (value.length < 8) {
16
+ return '***';
17
+ }
18
+ return `${value.slice(0, 3)}***...***${value.slice(-3)}`;
19
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Duration Parsing Utility
3
+ *
4
+ * Parses human-readable duration strings (e.g., "30s", "5m", "1h", "90m")
5
+ * into milliseconds. Also accepts raw millisecond numbers for backward
6
+ * compatibility with existing --timeout flag usage.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * parseDuration('30s') // 30_000
11
+ * parseDuration('5m') // 300_000
12
+ * parseDuration('45m') // 2_700_000
13
+ * parseDuration('1h') // 3_600_000
14
+ * parseDuration('1.5h') // 5_400_000
15
+ * parseDuration('2700000') // 2_700_000 (raw ms, backward compat)
16
+ * parseDuration(2700000) // 2_700_000 (numeric passthrough)
17
+ * ```
18
+ */
19
+ /**
20
+ * Parse a duration string or number into milliseconds.
21
+ *
22
+ * Accepted formats:
23
+ * - `"30s"` — seconds
24
+ * - `"5m"` — minutes
25
+ * - `"1h"` — hours
26
+ * - `"1.5h"` — fractional units
27
+ * - `"2700000"` — raw milliseconds (string)
28
+ * - `2700000` — raw milliseconds (number)
29
+ *
30
+ * @param input - Duration string or number
31
+ * @returns Duration in milliseconds
32
+ * @throws Error if the input format is invalid or value is non-positive
33
+ */
34
+ export declare function parseDuration(input: number | string): number;
35
+ /**
36
+ * Format a millisecond duration into a human-readable string.
37
+ *
38
+ * @param ms - Duration in milliseconds
39
+ * @returns Formatted string (e.g., "45m", "1.5h", "30s")
40
+ */
41
+ export declare function formatDuration(ms: number): string;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Duration Parsing Utility
3
+ *
4
+ * Parses human-readable duration strings (e.g., "30s", "5m", "1h", "90m")
5
+ * into milliseconds. Also accepts raw millisecond numbers for backward
6
+ * compatibility with existing --timeout flag usage.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * parseDuration('30s') // 30_000
11
+ * parseDuration('5m') // 300_000
12
+ * parseDuration('45m') // 2_700_000
13
+ * parseDuration('1h') // 3_600_000
14
+ * parseDuration('1.5h') // 5_400_000
15
+ * parseDuration('2700000') // 2_700_000 (raw ms, backward compat)
16
+ * parseDuration(2700000) // 2_700_000 (numeric passthrough)
17
+ * ```
18
+ */
19
+ /** Duration unit multipliers in milliseconds */
20
+ const UNIT_MS = {
21
+ h: 3_600_000,
22
+ m: 60_000,
23
+ s: 1_000,
24
+ };
25
+ /**
26
+ * Parse a duration string or number into milliseconds.
27
+ *
28
+ * Accepted formats:
29
+ * - `"30s"` — seconds
30
+ * - `"5m"` — minutes
31
+ * - `"1h"` — hours
32
+ * - `"1.5h"` — fractional units
33
+ * - `"2700000"` — raw milliseconds (string)
34
+ * - `2700000` — raw milliseconds (number)
35
+ *
36
+ * @param input - Duration string or number
37
+ * @returns Duration in milliseconds
38
+ * @throws Error if the input format is invalid or value is non-positive
39
+ */
40
+ export function parseDuration(input) {
41
+ // Numeric passthrough
42
+ if (typeof input === 'number') {
43
+ if (input <= 0 || !Number.isFinite(input)) {
44
+ throw new Error(`Invalid timeout value: ${input}. Must be a positive number.`);
45
+ }
46
+ return Math.round(input);
47
+ }
48
+ const trimmed = input.trim();
49
+ if (trimmed.length === 0) {
50
+ throw new Error('Timeout value cannot be empty.');
51
+ }
52
+ // Try matching duration pattern: number + unit suffix
53
+ const match = trimmed.match(/^(\d+(?:\.\d+)?)\s*(s|m|h)$/i);
54
+ if (match) {
55
+ const value = Number.parseFloat(match[1]);
56
+ const unit = match[2].toLowerCase();
57
+ const multiplier = UNIT_MS[unit];
58
+ const ms = Math.round(value * multiplier);
59
+ if (ms <= 0) {
60
+ throw new Error(`Invalid timeout value: ${trimmed}. Must result in a positive duration.`);
61
+ }
62
+ return ms;
63
+ }
64
+ // Try raw numeric string (milliseconds)
65
+ const numeric = Number(trimmed);
66
+ if (!Number.isNaN(numeric) && Number.isFinite(numeric) && numeric > 0) {
67
+ return Math.round(numeric);
68
+ }
69
+ throw new Error(`Invalid timeout format: "${trimmed}". ` +
70
+ `Expected a duration like "30s", "5m", "1h", "90m", or raw milliseconds like "2700000".`);
71
+ }
72
+ /**
73
+ * Format a millisecond duration into a human-readable string.
74
+ *
75
+ * @param ms - Duration in milliseconds
76
+ * @returns Formatted string (e.g., "45m", "1.5h", "30s")
77
+ */
78
+ export function formatDuration(ms) {
79
+ if (ms >= 3_600_000) {
80
+ const hours = ms / 3_600_000;
81
+ return Number.isInteger(hours) ? `${hours}h` : `${hours.toFixed(1)}h`;
82
+ }
83
+ if (ms >= 60_000) {
84
+ const minutes = ms / 60_000;
85
+ return Number.isInteger(minutes) ? `${minutes}m` : `${minutes.toFixed(1)}m`;
86
+ }
87
+ const seconds = ms / 1_000;
88
+ return Number.isInteger(seconds) ? `${seconds}s` : `${seconds.toFixed(1)}s`;
89
+ }
@@ -0,0 +1,216 @@
1
+ /**
2
+ * listr2 Helper Functions
3
+ *
4
+ * Utility functions for creating and managing listr2 task structures
5
+ * used by the WorkflowReporter for visualizing workflow progress.
6
+ */
7
+ /**
8
+ * Default terminal width constraint for output formatting
9
+ */
10
+ export declare const DEFAULT_TERMINAL_WIDTH = 80;
11
+ /**
12
+ * Regex pattern for detecting ANSI escape codes
13
+ */
14
+ export declare const ANSI_ESCAPE_PATTERN: RegExp;
15
+ /**
16
+ * Strip ANSI escape codes from text
17
+ *
18
+ * @param text - Text potentially containing ANSI codes
19
+ * @returns Clean text without ANSI escape sequences
20
+ */
21
+ export declare const stripAnsi: (text: string) => string;
22
+ /**
23
+ * Check if the current environment is a TTY
24
+ *
25
+ * @returns true if stdout is a TTY, false otherwise
26
+ */
27
+ export declare const isTTY: () => boolean;
28
+ /**
29
+ * Plain-text status indicators (no ANSI codes)
30
+ */
31
+ export declare const PLAIN_STATUS_INDICATORS: {
32
+ readonly completed: "[+]";
33
+ readonly failed: "[X]";
34
+ readonly queued: "[.]";
35
+ readonly running: "[*]";
36
+ };
37
+ /**
38
+ * Format a plain-text phase header for non-TTY output
39
+ *
40
+ * @param phaseName - Phase name (epic, story, dev, qa)
41
+ * @returns Plain-text header string (e.g., "=== Phase: Epic Generation ===")
42
+ */
43
+ export declare const formatPlainPhaseHeader: (phaseName: string) => string;
44
+ /**
45
+ * Format a plain-text spawn marker for non-TTY output
46
+ *
47
+ * @param itemId - Item identifier
48
+ * @param status - Spawn status (STARTED, COMPLETED, FAILED)
49
+ * @param durationMs - Optional duration in milliseconds
50
+ * @param error - Optional error message for failed spawns
51
+ * @returns Plain-text marker string (e.g., "[SPAWN] story-1.001 STARTED")
52
+ */
53
+ export declare const formatPlainSpawnMarker: (itemId: string, status: "COMPLETED" | "FAILED" | "STARTED", durationMs?: number, error?: string) => string;
54
+ /**
55
+ * Format a plain-text summary for non-TTY output
56
+ *
57
+ * @param totalSpawns - Total number of spawns
58
+ * @param passedCount - Number of passed spawns
59
+ * @param failedCount - Number of failed spawns
60
+ * @param durationMs - Total duration in milliseconds
61
+ * @returns Plain-text summary string
62
+ */
63
+ export declare const formatPlainSummary: (totalSpawns: number, passedCount: number, failedCount: number, durationMs: number) => string;
64
+ /**
65
+ * Format spawn output with visual delimiters for verbose mode
66
+ *
67
+ * @param spawnId - Spawn identifier
68
+ * @param output - Output content from the spawn
69
+ * @param maxWidth - Maximum line width (default: 80)
70
+ * @returns Formatted output with header/footer delimiters
71
+ */
72
+ export declare const formatVerboseSpawnOutput: (spawnId: string, output: string, maxWidth?: number) => string;
73
+ /**
74
+ * Wrap text lines to fit within a maximum width
75
+ *
76
+ * @param text - Text to wrap
77
+ * @param maxWidth - Maximum line width
78
+ * @returns Wrapped text
79
+ */
80
+ export declare const wrapLines: (text: string, maxWidth: number) => string;
81
+ /**
82
+ * Phase emoji mapping for visual consistency
83
+ */
84
+ export declare const PHASE_EMOJI: Record<string, string>;
85
+ /**
86
+ * Phase display names for titles
87
+ */
88
+ export declare const PHASE_TITLES: Record<string, string>;
89
+ /**
90
+ * Action verbs for spawn labels — maps phase to what the spawn is DOING (lowercase)
91
+ */
92
+ export declare const PHASE_ACTION_VERBS: Record<string, string>;
93
+ /**
94
+ * Get the action verb for a phase (e.g., "Creating" for story phase)
95
+ */
96
+ export declare const getPhaseActionVerb: (phaseName: string) => string;
97
+ /**
98
+ * Status indicators for spawn states
99
+ */
100
+ export declare const STATUS_INDICATORS: {
101
+ readonly completed: string;
102
+ readonly failed: string;
103
+ readonly queued: string;
104
+ readonly running: string;
105
+ };
106
+ /**
107
+ * Get emoji for a phase name
108
+ *
109
+ * @param phaseName - Phase name (epic, story, dev, qa)
110
+ * @returns Emoji string for the phase
111
+ */
112
+ export declare const getPhaseEmoji: (phaseName: string) => string;
113
+ /**
114
+ * Create a formatted phase title with emoji
115
+ *
116
+ * @param phaseName - Phase name (epic, story, dev, qa)
117
+ * @returns Formatted title string with emoji (e.g., "📋 Epic Phase")
118
+ */
119
+ export declare const createPhaseTitle: (phaseName: string) => string;
120
+ /**
121
+ * Create a phase task group configuration for listr2
122
+ *
123
+ * @param phaseName - Phase name (epic, story, dev, qa)
124
+ * @returns Object with title and phase metadata
125
+ */
126
+ export declare const createPhaseTaskGroup: (phaseName: string) => {
127
+ emoji: string;
128
+ phaseName: string;
129
+ title: string;
130
+ };
131
+ /**
132
+ * Create a layer task group configuration for listr2
133
+ *
134
+ * @param layerIndex - Zero-based layer index
135
+ * @param spawnCount - Number of spawns in the layer
136
+ * @param totalLayers - Total number of layers in the phase
137
+ * @returns Object with title and layer metadata
138
+ */
139
+ export declare const createLayerTaskGroup: (layerIndex: number, spawnCount: number, totalLayers: number) => {
140
+ layerIndex: number;
141
+ spawnCount: number;
142
+ title: string;
143
+ totalLayers: number;
144
+ };
145
+ /**
146
+ * Spawn status type
147
+ */
148
+ export type SpawnStatus = 'completed' | 'failed' | 'queued' | 'running';
149
+ /**
150
+ * Format spawn status for display
151
+ *
152
+ * @param status - Current spawn status
153
+ * @param durationMs - Duration in milliseconds (optional)
154
+ * @param itemCount - Number of items processed (optional, for completed status)
155
+ * @param errorMessage - Error message (optional, for failed status)
156
+ * @returns Formatted status string
157
+ */
158
+ export declare const formatSpawnStatus: (status: SpawnStatus, durationMs?: number, itemCount?: number, errorMessage?: string) => string;
159
+ /**
160
+ * Layer result summary
161
+ */
162
+ export interface LayerResult {
163
+ durationMs: number;
164
+ failureCount: number;
165
+ layerIndex: number;
166
+ spawnCount: number;
167
+ successCount: number;
168
+ }
169
+ /**
170
+ * Format a layer summary line for collapsed display
171
+ *
172
+ * @param result - Layer execution results
173
+ * @returns Formatted summary string
174
+ */
175
+ export declare const formatLayerSummary: (result: LayerResult) => string;
176
+ /**
177
+ * Phase result summary
178
+ */
179
+ export interface PhaseResult {
180
+ durationMs: number;
181
+ failureCount: number;
182
+ itemCount: number;
183
+ phaseName: string;
184
+ successCount: number;
185
+ }
186
+ /**
187
+ * Format a phase summary for completion display
188
+ *
189
+ * @param result - Phase execution results
190
+ * @returns Formatted summary string
191
+ */
192
+ export declare const formatPhaseSummary: (result: PhaseResult) => string;
193
+ /**
194
+ * Create a spawn task title
195
+ *
196
+ * @param itemId - Item identifier (epic number, story number, etc.)
197
+ * @param itemTitle - Optional item title/description
198
+ * @param agentType - Type of agent being spawned
199
+ * @returns Formatted spawn task title
200
+ */
201
+ export declare const createSpawnTitle: (itemId: string, itemTitle?: string, agentType?: string) => string;
202
+ /**
203
+ * Truncate a string to a maximum length with ellipsis
204
+ *
205
+ * @param text - Text to truncate
206
+ * @param maxLength - Maximum length (default: 60)
207
+ * @returns Truncated string with ellipsis if needed
208
+ */
209
+ export declare const truncateText: (text: string, maxLength?: number) => string;
210
+ /**
211
+ * Format elapsed time for running tasks (updates every second)
212
+ *
213
+ * @param startTime - Start timestamp in milliseconds
214
+ * @returns Formatted elapsed time string
215
+ */
216
+ export declare const formatElapsedTime: (startTime: number) => string;