edsger 0.30.0 → 0.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.claude/settings.local.json +28 -0
  2. package/.env.local +12 -0
  3. package/dist/api/features/__tests__/regression-prevention.test.d.ts +5 -0
  4. package/dist/api/features/__tests__/regression-prevention.test.js +338 -0
  5. package/dist/api/features/__tests__/status-updater.integration.test.d.ts +5 -0
  6. package/dist/api/features/__tests__/status-updater.integration.test.js +497 -0
  7. package/dist/commands/workflow/pipeline-runner.d.ts +17 -0
  8. package/dist/commands/workflow/pipeline-runner.js +393 -0
  9. package/dist/commands/workflow/runner.d.ts +26 -0
  10. package/dist/commands/workflow/runner.js +119 -0
  11. package/dist/commands/workflow/workflow-runner.d.ts +26 -0
  12. package/dist/commands/workflow/workflow-runner.js +119 -0
  13. package/dist/index.js +0 -0
  14. package/dist/phases/autonomous/index.js +9 -56
  15. package/dist/phases/code-implementation/analyzer-helpers.d.ts +28 -0
  16. package/dist/phases/code-implementation/analyzer-helpers.js +177 -0
  17. package/dist/phases/code-implementation/analyzer.d.ts +32 -0
  18. package/dist/phases/code-implementation/analyzer.js +629 -0
  19. package/dist/phases/code-implementation/branch-pr-creator.js +2 -58
  20. package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
  21. package/dist/phases/code-implementation/context-fetcher.js +86 -0
  22. package/dist/phases/code-implementation/index.js +9 -67
  23. package/dist/phases/code-implementation/mcp-server.d.ts +1 -0
  24. package/dist/phases/code-implementation/mcp-server.js +93 -0
  25. package/dist/phases/code-implementation/prompts-improvement.d.ts +5 -0
  26. package/dist/phases/code-implementation/prompts-improvement.js +108 -0
  27. package/dist/phases/code-implementation-verification/verifier.d.ts +31 -0
  28. package/dist/phases/code-implementation-verification/verifier.js +196 -0
  29. package/dist/phases/code-refine/analyzer.d.ts +41 -0
  30. package/dist/phases/code-refine/analyzer.js +561 -0
  31. package/dist/phases/code-refine/context-fetcher.d.ts +94 -0
  32. package/dist/phases/code-refine/context-fetcher.js +423 -0
  33. package/dist/phases/code-refine/index.js +6 -37
  34. package/dist/phases/code-refine-verification/analysis/llm-analyzer.d.ts +22 -0
  35. package/dist/phases/code-refine-verification/analysis/llm-analyzer.js +134 -0
  36. package/dist/phases/code-refine-verification/verifier.d.ts +47 -0
  37. package/dist/phases/code-refine-verification/verifier.js +597 -0
  38. package/dist/phases/code-review/analyzer.d.ts +29 -0
  39. package/dist/phases/code-review/analyzer.js +363 -0
  40. package/dist/phases/code-review/context-fetcher.d.ts +92 -0
  41. package/dist/phases/code-review/context-fetcher.js +296 -0
  42. package/dist/phases/code-review/index.js +1 -0
  43. package/dist/phases/feature-analysis/analyzer-helpers.d.ts +10 -0
  44. package/dist/phases/feature-analysis/analyzer-helpers.js +47 -0
  45. package/dist/phases/feature-analysis/analyzer.d.ts +11 -0
  46. package/dist/phases/feature-analysis/analyzer.js +208 -0
  47. package/dist/phases/feature-analysis/context-fetcher.d.ts +26 -0
  48. package/dist/phases/feature-analysis/context-fetcher.js +134 -0
  49. package/dist/phases/feature-analysis/http-fallback.d.ts +20 -0
  50. package/dist/phases/feature-analysis/http-fallback.js +95 -0
  51. package/dist/phases/feature-analysis/mcp-server.d.ts +1 -0
  52. package/dist/phases/feature-analysis/mcp-server.js +144 -0
  53. package/dist/phases/feature-analysis/prompts-improvement.d.ts +8 -0
  54. package/dist/phases/feature-analysis/prompts-improvement.js +109 -0
  55. package/dist/phases/feature-analysis-verification/verifier.d.ts +37 -0
  56. package/dist/phases/feature-analysis-verification/verifier.js +147 -0
  57. package/dist/phases/pr-execution/index.js +1 -0
  58. package/dist/phases/pr-execution/pr-executor.d.ts +2 -1
  59. package/dist/phases/pr-execution/pr-executor.js +9 -38
  60. package/dist/phases/pull-request/creator.js +9 -35
  61. package/dist/phases/technical-design/analyzer-helpers.d.ts +25 -0
  62. package/dist/phases/technical-design/analyzer-helpers.js +39 -0
  63. package/dist/phases/technical-design/analyzer.d.ts +21 -0
  64. package/dist/phases/technical-design/analyzer.js +461 -0
  65. package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
  66. package/dist/phases/technical-design/context-fetcher.js +39 -0
  67. package/dist/phases/technical-design/http-fallback.d.ts +17 -0
  68. package/dist/phases/technical-design/http-fallback.js +151 -0
  69. package/dist/phases/technical-design/mcp-server.d.ts +1 -0
  70. package/dist/phases/technical-design/mcp-server.js +157 -0
  71. package/dist/phases/technical-design/prompts-improvement.d.ts +5 -0
  72. package/dist/phases/technical-design/prompts-improvement.js +93 -0
  73. package/dist/phases/technical-design-verification/verifier.d.ts +53 -0
  74. package/dist/phases/technical-design-verification/verifier.js +170 -0
  75. package/dist/services/feature-branches.d.ts +77 -0
  76. package/dist/services/feature-branches.js +205 -0
  77. package/dist/utils/git-branch-manager.d.ts +2 -0
  78. package/dist/utils/git-branch-manager.js +8 -35
  79. package/dist/utils/git-push.d.ts +43 -0
  80. package/dist/utils/git-push.js +127 -0
  81. package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
  82. package/dist/workflow-runner/config/phase-configs.js +120 -0
  83. package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
  84. package/dist/workflow-runner/core/feature-filter.js +46 -0
  85. package/dist/workflow-runner/core/index.d.ts +8 -0
  86. package/dist/workflow-runner/core/index.js +12 -0
  87. package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
  88. package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
  89. package/dist/workflow-runner/core/state-manager.d.ts +24 -0
  90. package/dist/workflow-runner/core/state-manager.js +42 -0
  91. package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
  92. package/dist/workflow-runner/core/workflow-logger.js +65 -0
  93. package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
  94. package/dist/workflow-runner/executors/phase-executor.js +248 -0
  95. package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
  96. package/dist/workflow-runner/feature-workflow-runner.js +119 -0
  97. package/dist/workflow-runner/index.d.ts +2 -0
  98. package/dist/workflow-runner/index.js +2 -0
  99. package/dist/workflow-runner/pipeline-runner.d.ts +17 -0
  100. package/dist/workflow-runner/pipeline-runner.js +393 -0
  101. package/dist/workflow-runner/workflow-processor.d.ts +54 -0
  102. package/dist/workflow-runner/workflow-processor.js +170 -0
  103. package/dist/workspace/workspace-manager.js +5 -3
  104. package/package.json +1 -1
  105. package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.d.ts +0 -4
  106. package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.js +0 -133
  107. package/dist/services/lifecycle-agent/__tests__/transition-rules.test.d.ts +0 -4
  108. package/dist/services/lifecycle-agent/__tests__/transition-rules.test.js +0 -336
  109. package/dist/services/lifecycle-agent/index.d.ts +0 -24
  110. package/dist/services/lifecycle-agent/index.js +0 -25
  111. package/dist/services/lifecycle-agent/phase-criteria.d.ts +0 -57
  112. package/dist/services/lifecycle-agent/phase-criteria.js +0 -335
  113. package/dist/services/lifecycle-agent/transition-rules.d.ts +0 -60
  114. package/dist/services/lifecycle-agent/transition-rules.js +0 -184
  115. package/dist/services/lifecycle-agent/types.d.ts +0 -190
  116. package/dist/services/lifecycle-agent/types.js +0 -12
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Pipeline result evaluation utilities for workflow processor
3
+ * Pure functions for evaluating pipeline execution results
4
+ */
5
+ import type { PipelineResult } from '../../types/pipeline.js';
6
+ export declare const evaluatePipelineResults: (results: readonly PipelineResult[]) => boolean;
7
+ export declare const hasAnyPipelineFailures: (results: readonly PipelineResult[]) => boolean;
8
+ export declare const countSuccessfulPhases: (results: readonly PipelineResult[]) => number;
9
+ export declare const countFailedPhases: (results: readonly PipelineResult[]) => number;
10
+ export declare const getFailedPhases: (results: readonly PipelineResult[]) => PipelineResult[];
11
+ export declare const getSuccessfulPhases: (results: readonly PipelineResult[]) => PipelineResult[];
12
+ export declare const getFirstFailure: (results: readonly PipelineResult[]) => PipelineResult | undefined;
13
+ export declare const getLastPhaseResult: (results: readonly PipelineResult[]) => PipelineResult | undefined;
14
+ export declare const isPipelineFullySuccessful: (results: readonly PipelineResult[]) => boolean;
15
+ export declare const isPipelinePartiallySuccessful: (results: readonly PipelineResult[]) => boolean;
16
+ export declare const isPipelineCompleteFailure: (results: readonly PipelineResult[]) => boolean;
17
+ export declare const isPipelineEmpty: (results: readonly PipelineResult[]) => boolean;
18
+ export interface PipelineStats {
19
+ readonly total: number;
20
+ readonly successful: number;
21
+ readonly failed: number;
22
+ readonly successRate: number;
23
+ }
24
+ export declare const calculatePipelineStats: (results: readonly PipelineResult[]) => PipelineStats;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Pipeline result evaluation utilities for workflow processor
3
+ * Pure functions for evaluating pipeline execution results
4
+ */
5
+ // Pipeline result evaluation (pure)
6
+ export const evaluatePipelineResults = (results) => results.every((result) => result.status === 'success');
7
+ export const hasAnyPipelineFailures = (results) => results.some((result) => result.status !== 'success');
8
+ export const countSuccessfulPhases = (results) => results.filter((result) => result.status === 'success').length;
9
+ export const countFailedPhases = (results) => results.filter((result) => result.status !== 'success').length;
10
+ export const getFailedPhases = (results) => results.filter((result) => result.status !== 'success');
11
+ export const getSuccessfulPhases = (results) => results.filter((result) => result.status === 'success');
12
+ export const getFirstFailure = (results) => results.find((result) => result.status !== 'success');
13
+ export const getLastPhaseResult = (results) => results.length > 0 ? results[results.length - 1] : undefined;
14
+ // Pipeline completion status
15
+ export const isPipelineFullySuccessful = (results) => results.length > 0 && evaluatePipelineResults(results);
16
+ export const isPipelinePartiallySuccessful = (results) => results.length > 0 &&
17
+ countSuccessfulPhases(results) > 0 &&
18
+ hasAnyPipelineFailures(results);
19
+ export const isPipelineCompleteFailure = (results) => results.length > 0 && countSuccessfulPhases(results) === 0;
20
+ export const isPipelineEmpty = (results) => results.length === 0;
21
+ export const calculatePipelineStats = (results) => {
22
+ const total = results.length;
23
+ const successful = countSuccessfulPhases(results);
24
+ const failed = countFailedPhases(results);
25
+ const successRate = total > 0 ? successful / total : 0;
26
+ return {
27
+ total,
28
+ successful,
29
+ failed,
30
+ successRate,
31
+ };
32
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * State management utilities for workflow processor
3
+ * Pure functions for handling feature processing states
4
+ */
5
+ export interface FeatureProcessingState {
6
+ readonly featureId: string;
7
+ readonly retryCount: number;
8
+ readonly lastAttempt: Date;
9
+ readonly status: 'processing' | 'completed' | 'failed';
10
+ readonly featureUpdatedAt?: string;
11
+ }
12
+ export interface WorkflowStats {
13
+ readonly totalProcessed: number;
14
+ readonly completed: number;
15
+ readonly failed: number;
16
+ readonly processing: number;
17
+ readonly isRunning: boolean;
18
+ }
19
+ export declare const createInitialState: () => Map<string, FeatureProcessingState>;
20
+ export declare const createProcessingState: (featureId: string, currentState?: FeatureProcessingState) => FeatureProcessingState;
21
+ export declare const createCompletedState: (featureId: string, currentState?: FeatureProcessingState) => FeatureProcessingState;
22
+ export declare const createFailedState: (featureId: string, currentState?: FeatureProcessingState) => FeatureProcessingState;
23
+ export declare const updateFeatureState: (states: Map<string, FeatureProcessingState>, featureId: string, updateFn: (currentState?: FeatureProcessingState) => FeatureProcessingState) => Map<string, FeatureProcessingState>;
24
+ export declare const calculateStats: (states: Map<string, FeatureProcessingState>, isRunning: boolean) => WorkflowStats;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * State management utilities for workflow processor
3
+ * Pure functions for handling feature processing states
4
+ */
5
+ // State creation functions (pure)
6
+ export const createInitialState = () => new Map();
7
+ export const createProcessingState = (featureId, currentState) => ({
8
+ featureId,
9
+ retryCount: currentState ? currentState.retryCount + 1 : 1,
10
+ lastAttempt: new Date(),
11
+ status: 'processing',
12
+ });
13
+ export const createCompletedState = (featureId, currentState) => ({
14
+ featureId,
15
+ retryCount: currentState ? currentState.retryCount : 1,
16
+ lastAttempt: new Date(),
17
+ status: 'completed',
18
+ });
19
+ export const createFailedState = (featureId, currentState) => ({
20
+ featureId,
21
+ retryCount: currentState ? currentState.retryCount : 1,
22
+ lastAttempt: new Date(),
23
+ status: 'failed',
24
+ });
25
+ // State update function (pure)
26
+ export const updateFeatureState = (states, featureId, updateFn) => {
27
+ const newStates = new Map(states);
28
+ const currentState = newStates.get(featureId);
29
+ newStates.set(featureId, updateFn(currentState));
30
+ return newStates;
31
+ };
32
+ // Statistics calculation (pure)
33
+ export const calculateStats = (states, isRunning) => {
34
+ const stateArray = Array.from(states.values());
35
+ return {
36
+ totalProcessed: stateArray.length,
37
+ completed: stateArray.filter((s) => s.status === 'completed').length,
38
+ failed: stateArray.filter((s) => s.status === 'failed').length,
39
+ processing: stateArray.filter((s) => s.status === 'processing').length,
40
+ isRunning,
41
+ };
42
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Logging utilities for workflow processor
3
+ * Centralized logging functions for workflow operations
4
+ */
5
+ import type { FeatureInfo } from '../../types/features.js';
6
+ import type { PipelineResult } from '../../types/pipeline.js';
7
+ export declare const logProcessingStart: (feature: FeatureInfo, verbose?: boolean) => void;
8
+ export declare const logRetryInfo: (featureName: string, retryCount: number, maxRetries: number) => void;
9
+ export declare const logPipelineResults: (results: readonly PipelineResult[]) => void;
10
+ export declare const logProcessorStart: (productId: string, pollInterval: number) => void;
11
+ export declare const logProcessorReady: () => void;
12
+ export declare const logProcessorStop: () => void;
13
+ export declare const logFeatureSuccess: (featureName: string) => void;
14
+ export declare const logFeatureFailed: (featureName: string) => void;
15
+ export declare const logFeatureError: (featureName: string, error: unknown) => void;
16
+ export declare const logNoFeaturesFound: () => void;
17
+ export declare const logAllFeaturesProcessed: () => void;
18
+ export declare const logSkippingProcessing: (processingCount: number) => void;
19
+ export declare const logPollingError: (error: unknown) => void;
20
+ export declare const logProcessNextFeatureError: (error: unknown) => void;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Logging utilities for workflow processor
3
+ * Centralized logging functions for workflow operations
4
+ */
5
+ import { logInfo, logError, logSuccess } from '../../utils/logger.js';
6
+ export const logProcessingStart = (feature, verbose) => {
7
+ logInfo(`🎯 Processing feature: ${feature.name} (${feature.id})`);
8
+ if (verbose) {
9
+ logInfo(` Description: ${feature.description}`);
10
+ logInfo(` Last updated: ${feature.updated_at}`);
11
+ }
12
+ };
13
+ export const logRetryInfo = (featureName, retryCount, maxRetries) => {
14
+ if (retryCount < maxRetries) {
15
+ logInfo(`🔄 Will retry feature ${featureName} (attempt ${retryCount + 1}/${maxRetries})`);
16
+ }
17
+ else {
18
+ logError(`⛔ Max retries reached for feature ${featureName}, marking as permanently failed`);
19
+ }
20
+ };
21
+ export const logPipelineResults = (results) => {
22
+ console.log('\n' + '='.repeat(60));
23
+ console.log('📊 Pipeline Results Summary');
24
+ console.log('='.repeat(60));
25
+ results.forEach((result, index) => {
26
+ const statusIcon = result.status === 'success' ? '✅' : '❌';
27
+ console.log(`${index + 1}. ${statusIcon} ${result.phase}: ${result.message}`);
28
+ });
29
+ console.log('='.repeat(60) + '\n');
30
+ };
31
+ export const logProcessorStart = (productId, pollInterval) => {
32
+ logInfo('🚀 Starting workflow processor...');
33
+ logInfo(`📋 Product ID: ${productId}`);
34
+ logInfo(`🔄 Poll interval: ${pollInterval}ms`);
35
+ };
36
+ export const logProcessorReady = () => {
37
+ logInfo('✅ Workflow processor started and monitoring for new features');
38
+ };
39
+ export const logProcessorStop = () => {
40
+ logInfo('⏹️ Workflow processor stopped');
41
+ };
42
+ export const logFeatureSuccess = (featureName) => {
43
+ logSuccess(`✅ Feature ${featureName} completed successfully!`);
44
+ };
45
+ export const logFeatureFailed = (featureName) => {
46
+ logError(`❌ Feature ${featureName} failed in pipeline`);
47
+ };
48
+ export const logFeatureError = (featureName, error) => {
49
+ logError(`❌ Error processing feature ${featureName}: ${error instanceof Error ? error.message : String(error)}`);
50
+ };
51
+ export const logNoFeaturesFound = () => {
52
+ logInfo('🔍 No ready_for_dev features found, continuing to monitor...');
53
+ };
54
+ export const logAllFeaturesProcessed = () => {
55
+ logInfo('🔄 All current features are processed or being processed, continuing to monitor...');
56
+ };
57
+ export const logSkippingProcessing = (processingCount) => {
58
+ logInfo(`⏳ Skipping feature fetching as ${processingCount} feature(s) are currently being processed`);
59
+ };
60
+ export const logPollingError = (error) => {
61
+ logError(`Error in polling cycle: ${error instanceof Error ? error.message : String(error)}`);
62
+ };
63
+ export const logProcessNextFeatureError = (error) => {
64
+ logError(`Error in processNextFeature: ${error instanceof Error ? error.message : String(error)}`);
65
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Phase execution logic for pipeline runner
3
+ */
4
+ import { EdsgerConfig } from '../../types/index.js';
5
+ import { PipelinePhaseOptions, PipelineResult, PhaseConfig } from '../../types/pipeline.js';
6
+ export declare const createPhaseRunner: (phaseConfig: PhaseConfig) => (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>;
7
+ declare const runFeatureAnalysisPhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>, runTechnicalDesignPhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeImplementationPhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>, runFunctionalTestingPhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeTestingPhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeRefinePhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeRefineVerificationPhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeReviewPhase: (options: PipelinePhaseOptions, config: EdsgerConfig) => Promise<PipelineResult>;
8
+ export { runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, runCodeTestingPhase, runCodeRefinePhase, runCodeRefineVerificationPhase, runCodeReviewPhase, };
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Phase execution logic for pipeline runner
3
+ */
4
+ import { updateFeatureStatusForPhase } from '../../api/features/index.js';
5
+ import { phaseConfigs } from '../config/phase-configs.js';
6
+ import { getChecklistsForPhase, validateChecklistsForPhase, validateRequiredChecklistResults, processChecklistResultsFromResponse, processChecklistItemResultsFromResponse, } from '../../services/checklist.js';
7
+ import { logFeaturePhaseEvent } from '../../services/audit-logs.js';
8
+ // Higher-order function for phase execution
9
+ export const createPhaseRunner = (phaseConfig) => async (options, config) => {
10
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
11
+ const { name, checkRequirements, execute, requirementsError } = phaseConfig;
12
+ // Track phase duration for logging
13
+ const phaseStartTime = Date.now();
14
+ try {
15
+ // Check requirements
16
+ const hasRequirements = await checkRequirements();
17
+ if (!hasRequirements) {
18
+ return {
19
+ featureId,
20
+ phase: name,
21
+ status: 'error',
22
+ message: requirementsError,
23
+ };
24
+ }
25
+ // Update feature status to reflect current phase
26
+ await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, name, verbose);
27
+ if (verbose) {
28
+ console.log(`🎯 Starting ${name} for: ${featureId}`);
29
+ }
30
+ // Log phase start
31
+ await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
32
+ featureId,
33
+ eventType: 'phase_started',
34
+ phase: name.replace(/-/g, '_'),
35
+ result: 'info',
36
+ metadata: {
37
+ timestamp: new Date().toISOString(),
38
+ },
39
+ }, verbose);
40
+ // Fetch checklists for this phase as context
41
+ let checklistContext = null;
42
+ try {
43
+ checklistContext = await getChecklistsForPhase(options, name);
44
+ if (verbose && checklistContext.checklists.length > 0) {
45
+ console.log(`📋 Found ${checklistContext.checklists.length} checklists for ${name} phase`);
46
+ }
47
+ }
48
+ catch (checklistError) {
49
+ // Always log checklist fetch errors, not just in verbose mode
50
+ console.log(`⚠️ Failed to fetch checklists for ${name} phase: ${checklistError instanceof Error ? checklistError.message : String(checklistError)}`);
51
+ // Log more details in verbose mode
52
+ if (verbose && checklistError instanceof Error) {
53
+ console.log(` Details: ${checklistError.stack}`);
54
+ }
55
+ }
56
+ // Execute the phase with checklist context
57
+ const result = await execute(options, config, checklistContext);
58
+ // Process checklist results from phase response if phase was successful
59
+ if (result.status === 'success') {
60
+ try {
61
+ // Extract checklist_item_results from result data if available (new format)
62
+ const checklistItemResults = result.data?.checklist_item_results;
63
+ if (checklistItemResults && Array.isArray(checklistItemResults)) {
64
+ const processResult = await processChecklistItemResultsFromResponse(options, name, checklistItemResults, verbose);
65
+ if (verbose) {
66
+ if (processResult.created > 0) {
67
+ console.log(`📋 Processed ${processResult.created} checklist item results from ${name} phase`);
68
+ }
69
+ if (processResult.errors.length > 0) {
70
+ console.log(`⚠️ ${processResult.errors.length} errors processing checklist item results`);
71
+ processResult.errors.forEach((error) => console.log(` - ${error}`));
72
+ }
73
+ }
74
+ }
75
+ else {
76
+ // Fallback to old format for backward compatibility
77
+ const checklistResults = result.data?.checklist_results;
78
+ if (checklistResults && Array.isArray(checklistResults)) {
79
+ const processResult = await processChecklistResultsFromResponse(options, checklistResults, verbose);
80
+ if (verbose) {
81
+ if (processResult.created > 0) {
82
+ console.log(`📋 Processed ${processResult.created} checklist results from ${name} phase (legacy format)`);
83
+ }
84
+ if (processResult.errors.length > 0) {
85
+ console.log(`⚠️ ${processResult.errors.length} errors processing checklist results`);
86
+ processResult.errors.forEach((error) => console.log(` - ${error}`));
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ catch (processError) {
93
+ if (verbose) {
94
+ console.log(`⚠️ Failed to process checklist results from ${name} phase: ${processError instanceof Error ? processError.message : String(processError)}`);
95
+ }
96
+ }
97
+ }
98
+ // Strictly validate checklist results after phase execution
99
+ let checklistValidation = null;
100
+ if (result.status === 'success') {
101
+ try {
102
+ // First perform strict validation - this will fail if checklists exist but have no results
103
+ const strictValidation = await validateRequiredChecklistResults(options, name, verbose);
104
+ if (!strictValidation.success) {
105
+ // If validation fails, return error immediately - don't continue pipeline
106
+ return {
107
+ featureId,
108
+ phase: name,
109
+ status: 'error',
110
+ message: `Checklist validation failed: ${strictValidation.error}`,
111
+ data: {
112
+ ...result,
113
+ checklist_context: checklistContext,
114
+ checklist_validation_error: strictValidation.error,
115
+ missing_checklists: strictValidation.missingChecklists,
116
+ },
117
+ };
118
+ }
119
+ // If strict validation passes, get detailed validation info for logging
120
+ checklistValidation = await validateChecklistsForPhase(options, name);
121
+ if (verbose) {
122
+ console.log(`📋 Checklist validation: ${checklistValidation.summary}`);
123
+ }
124
+ // Log completion status
125
+ if (checklistValidation.checklists_validation.length > 0) {
126
+ const completedCount = checklistValidation.checklists_validation.filter((v) => v.is_completed).length;
127
+ const totalCount = checklistValidation.checklists_validation.length;
128
+ if (verbose) {
129
+ console.log(`📋 Checklist results status: ${completedCount}/${totalCount} checklists have results`);
130
+ }
131
+ // Log any incomplete checklists
132
+ if (!checklistValidation.all_completed) {
133
+ checklistValidation.checklists_validation.forEach((validation) => {
134
+ if (!validation.is_completed) {
135
+ console.log(` - ${validation.checklist_name} (${validation.role}): ${validation.status}`);
136
+ }
137
+ });
138
+ }
139
+ }
140
+ }
141
+ catch (validationError) {
142
+ // If validation itself fails, treat as error and stop pipeline
143
+ return {
144
+ featureId,
145
+ phase: name,
146
+ status: 'error',
147
+ message: `Checklist validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`,
148
+ data: {
149
+ ...result,
150
+ checklist_context: checklistContext,
151
+ checklist_validation_error: validationError instanceof Error
152
+ ? validationError.message
153
+ : String(validationError),
154
+ },
155
+ };
156
+ }
157
+ }
158
+ // Log phase completion
159
+ const phaseEndTime = Date.now();
160
+ const phaseDuration = phaseEndTime - phaseStartTime;
161
+ if (result.status === 'success') {
162
+ await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
163
+ featureId,
164
+ eventType: 'phase_completed',
165
+ phase: name.replace(/-/g, '_'),
166
+ result: 'success',
167
+ metadata: {
168
+ duration_ms: phaseDuration,
169
+ iterations: result.data?.iterations,
170
+ artifacts: result.data,
171
+ checklist_validation: checklistValidation,
172
+ },
173
+ }, verbose);
174
+ }
175
+ else {
176
+ // Extract additional failure details from result data
177
+ const failureMetadata = {
178
+ duration_ms: phaseDuration,
179
+ };
180
+ // For verification phases, include suggestions and details
181
+ if (name.includes('verification') &&
182
+ result.data &&
183
+ typeof result.data === 'object') {
184
+ const data = result.data;
185
+ if (data.suggestions) {
186
+ failureMetadata.suggestions = data.suggestions;
187
+ }
188
+ if (data.unresolvedCommentDetails ||
189
+ data.unresolved_comment_details) {
190
+ failureMetadata.unresolved_comment_details =
191
+ data.unresolvedCommentDetails || data.unresolved_comment_details;
192
+ }
193
+ if (data.unresolvedComments !== undefined ||
194
+ data.unresolved_comments !== undefined) {
195
+ failureMetadata.unresolved_comments =
196
+ data.unresolvedComments ?? data.unresolved_comments;
197
+ }
198
+ }
199
+ await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
200
+ featureId,
201
+ eventType: 'phase_failed',
202
+ phase: name.replace(/-/g, '_'),
203
+ result: 'error',
204
+ metadata: failureMetadata,
205
+ errorMessage: result.summary || result.message || 'Phase execution failed',
206
+ }, verbose);
207
+ }
208
+ return {
209
+ featureId,
210
+ phase: name,
211
+ status: result.status === 'success' ? 'success' : 'error',
212
+ message: result.status === 'success'
213
+ ? `${name.replace('-', ' ')} completed successfully`
214
+ : `${name.replace('-', ' ')} failed`,
215
+ data: {
216
+ ...result,
217
+ checklist_context: checklistContext,
218
+ checklist_validation: checklistValidation,
219
+ },
220
+ };
221
+ }
222
+ catch (error) {
223
+ // Log phase failure for exceptions
224
+ const phaseEndTime = Date.now();
225
+ const phaseDuration = phaseEndTime - phaseStartTime;
226
+ await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
227
+ featureId,
228
+ eventType: 'phase_failed',
229
+ phase: name.replace(/-/g, '_'),
230
+ result: 'error',
231
+ metadata: {
232
+ duration_ms: phaseDuration,
233
+ error_type: 'exception',
234
+ },
235
+ errorMessage: error instanceof Error ? error.message : String(error),
236
+ }, verbose);
237
+ return {
238
+ featureId,
239
+ phase: name,
240
+ status: 'error',
241
+ message: `${name.replace('-', ' ')} failed: ${error instanceof Error ? error.message : String(error)}`,
242
+ };
243
+ }
244
+ };
245
+ // Create phase runners using the configuration
246
+ const [runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, runCodeTestingPhase, runCodeRefinePhase, runCodeRefineVerificationPhase, runCodeReviewPhase,] = phaseConfigs.map(createPhaseRunner);
247
+ // Export individual phase runners for granular control
248
+ export { runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, runCodeTestingPhase, runCodeRefinePhase, runCodeRefineVerificationPhase, runCodeReviewPhase, };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Feature workflow runner with execution mode support
3
+ * Main entry point for running workflow pipelines with different execution modes
4
+ */
5
+ import { EdsgerConfig } from '../types/index.js';
6
+ import { PipelinePhaseOptions, PipelineResult, ExecutionMode } from '../types/pipeline.js';
7
+ /**
8
+ * Run workflow for a feature based on its execution_mode configuration
9
+ */
10
+ export declare function runFeatureWorkflow(options: PipelinePhaseOptions, config: EdsgerConfig): Promise<readonly PipelineResult[]>;
11
+ /**
12
+ * Run workflow for a feature with explicit execution mode override
13
+ */
14
+ export declare function runFeatureWorkflowWithMode(options: PipelinePhaseOptions, config: EdsgerConfig, executionMode: ExecutionMode): Promise<readonly PipelineResult[]>;
15
+ /**
16
+ * Get available execution modes
17
+ */
18
+ export declare function getAvailableExecutionModes(): ExecutionMode[];
19
+ /**
20
+ * Validate execution mode
21
+ */
22
+ export declare function isValidExecutionMode(mode: string): mode is ExecutionMode;
23
+ /**
24
+ * Get execution mode description
25
+ */
26
+ export declare function getExecutionModeDescription(mode: ExecutionMode): string;
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Feature workflow runner with execution mode support
3
+ * Main entry point for running workflow pipelines with different execution modes
4
+ */
5
+ import { runPipelineByMode } from './pipeline-runner.js';
6
+ import { getFeature } from '../api/features/get-feature.js';
7
+ import { logError, logInfo } from '../utils/logger.js';
8
+ /**
9
+ * Run workflow for a feature based on its execution_mode configuration
10
+ */
11
+ export async function runFeatureWorkflow(options, config) {
12
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
13
+ try {
14
+ // 1. Get feature details to check execution_mode
15
+ if (verbose) {
16
+ logInfo(`🔍 Fetching feature configuration for: ${featureId}`);
17
+ }
18
+ const feature = await getFeature(mcpServerUrl, mcpToken, featureId, verbose);
19
+ // Debug log raw feature data
20
+ if (verbose) {
21
+ logInfo(`🔍 Feature data from API:`);
22
+ logInfo(` - execution_mode (raw): ${feature.execution_mode}`);
23
+ logInfo(` - execution_mode (type): ${typeof feature.execution_mode}`);
24
+ logInfo(` - is valid: ${isValidExecutionMode(feature.execution_mode || '')}`);
25
+ }
26
+ // 2. Determine execution mode (default to full_pipeline if not set)
27
+ const executionMode = isValidExecutionMode(feature.execution_mode || '')
28
+ ? feature.execution_mode
29
+ : 'full_pipeline';
30
+ if (verbose) {
31
+ logInfo(`📋 Selected execution mode: ${executionMode}`);
32
+ logInfo(`📋 Mode description: ${getExecutionModeDescription(executionMode)}`);
33
+ }
34
+ // 3. Run pipeline based on execution mode
35
+ return await runPipelineByMode(options, config, executionMode);
36
+ }
37
+ catch (error) {
38
+ const errorMessage = error instanceof Error ? error.message : String(error);
39
+ logError(`Failed to run feature workflow: ${errorMessage}`);
40
+ // Return error result
41
+ return [
42
+ {
43
+ featureId,
44
+ phase: 'workflow-initialization',
45
+ status: 'error',
46
+ message: `Workflow initialization failed: ${errorMessage}`,
47
+ },
48
+ ];
49
+ }
50
+ }
51
+ /**
52
+ * Run workflow for a feature with explicit execution mode override
53
+ */
54
+ export async function runFeatureWorkflowWithMode(options, config, executionMode) {
55
+ const { featureId, verbose } = options;
56
+ if (verbose) {
57
+ logInfo(`🚀 Running workflow with explicit mode: ${executionMode} for feature: ${featureId}`);
58
+ }
59
+ try {
60
+ return await runPipelineByMode(options, config, executionMode);
61
+ }
62
+ catch (error) {
63
+ const errorMessage = error instanceof Error ? error.message : String(error);
64
+ logError(`Failed to run feature workflow with mode ${executionMode}: ${errorMessage}`);
65
+ return [
66
+ {
67
+ featureId,
68
+ phase: 'workflow-execution',
69
+ status: 'error',
70
+ message: `Workflow execution failed: ${errorMessage}`,
71
+ },
72
+ ];
73
+ }
74
+ }
75
+ /**
76
+ * Get available execution modes
77
+ */
78
+ export function getAvailableExecutionModes() {
79
+ return [
80
+ 'full_pipeline',
81
+ 'only_feature_analysis',
82
+ 'only_technical_design',
83
+ 'only_code_implementation',
84
+ 'only_functional_testing',
85
+ 'only_code_refine',
86
+ 'only_code_review',
87
+ 'from_feature_analysis',
88
+ 'from_technical_design',
89
+ 'from_code_implementation',
90
+ 'from_functional_testing',
91
+ 'from_code_review',
92
+ ];
93
+ }
94
+ /**
95
+ * Validate execution mode
96
+ */
97
+ export function isValidExecutionMode(mode) {
98
+ return getAvailableExecutionModes().includes(mode);
99
+ }
100
+ /**
101
+ * Get execution mode description
102
+ */
103
+ export function getExecutionModeDescription(mode) {
104
+ const descriptions = {
105
+ full_pipeline: 'Execute complete workflow: analysis → design → implementation → testing',
106
+ only_feature_analysis: 'Execute only: feature analysis',
107
+ only_technical_design: 'Execute only: technical design',
108
+ only_code_implementation: 'Execute only: code implementation',
109
+ only_functional_testing: 'Execute only: functional testing',
110
+ only_code_refine: 'Execute only: code refine (address PR review feedback and verify resolution)',
111
+ only_code_review: 'Execute only: code review (review PR code and create review comments)',
112
+ from_feature_analysis: 'Execute from feature analysis to end: analysis → design → implementation → testing',
113
+ from_technical_design: 'Execute from technical design to end: design → implementation → testing',
114
+ from_code_implementation: 'Execute from code implementation to end: implementation → testing',
115
+ from_functional_testing: 'Execute from functional testing to end: testing',
116
+ from_code_review: 'Execute from code review to end: code-review → code-refine → code-refine-verification',
117
+ };
118
+ return descriptions[mode] || 'Unknown execution mode';
119
+ }
@@ -0,0 +1,2 @@
1
+ export * from './workflow-processor.js';
2
+ export * from './pipeline-runner.js';
@@ -0,0 +1,2 @@
1
+ export * from './workflow-processor.js';
2
+ export * from './pipeline-runner.js';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Pipeline runner for executing development workflow phases
3
+ * Complete pipeline flow:
4
+ * feature-analysis → technical-design → code-implementation →
5
+ * functional-testing → pull-request → code-review → code-refine → code-refine-verification
6
+ * Uses functional programming principles
7
+ */
8
+ import { EdsgerConfig } from '../types/index.js';
9
+ import { PipelinePhaseOptions, PipelineResult, ExecutionMode } from '../types/pipeline.js';
10
+ /**
11
+ * Run pipeline based on execution mode
12
+ */
13
+ export declare const runPipelineByMode: (options: PipelinePhaseOptions, config: EdsgerConfig, executionMode: ExecutionMode) => Promise<readonly PipelineResult[]>;
14
+ /**
15
+ * Run complete pipeline for a feature using functional composition (legacy)
16
+ */
17
+ export declare const runCompletePipeline: (options: PipelinePhaseOptions, config: EdsgerConfig) => () => Promise<readonly PipelineResult[]>;