edsger 0.2.1 → 0.2.3

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 (182) hide show
  1. package/dist/api/features/feature-utils.d.ts +13 -0
  2. package/dist/api/features/feature-utils.js +46 -0
  3. package/dist/api/features/get-feature.d.ts +5 -0
  4. package/dist/api/features/get-feature.js +19 -0
  5. package/dist/api/features/index.d.ts +7 -0
  6. package/dist/api/features/index.js +9 -0
  7. package/dist/api/features/status-updater.d.ts +27 -0
  8. package/dist/api/features/status-updater.js +64 -0
  9. package/dist/api/features/test-cases.d.ts +21 -0
  10. package/dist/api/features/test-cases.js +63 -0
  11. package/dist/api/features/update-feature.d.ts +13 -0
  12. package/dist/api/features/update-feature.js +31 -0
  13. package/dist/api/features/user-stories.d.ts +21 -0
  14. package/dist/api/features/user-stories.js +63 -0
  15. package/dist/api/features.d.ts +100 -0
  16. package/dist/api/features.js +219 -0
  17. package/dist/api/mcp-client.d.ts +18 -0
  18. package/dist/api/mcp-client.js +58 -0
  19. package/dist/api/products.d.ts +10 -0
  20. package/dist/api/products.js +22 -0
  21. package/dist/api/test-reports.d.ts +9 -0
  22. package/dist/api/test-reports.js +25 -0
  23. package/dist/cli/commands/code-implementation-command.d.ts +2 -0
  24. package/dist/cli/commands/code-implementation-command.js +36 -0
  25. package/dist/cli/commands/code-review-command.d.ts +2 -0
  26. package/dist/cli/commands/code-review-command.js +39 -0
  27. package/dist/cli/commands/feature-analysis-command.d.ts +2 -0
  28. package/dist/cli/commands/feature-analysis-command.js +36 -0
  29. package/dist/cli/commands/functional-testing-command.d.ts +2 -0
  30. package/dist/cli/commands/functional-testing-command.js +36 -0
  31. package/dist/cli/commands/technical-design-command.d.ts +2 -0
  32. package/dist/cli/commands/technical-design-command.js +36 -0
  33. package/dist/cli/commands/workflow-command.d.ts +2 -0
  34. package/dist/cli/commands/workflow-command.js +34 -0
  35. package/dist/cli/formatters/code-implementation-formatter.d.ts +9 -0
  36. package/dist/cli/formatters/code-implementation-formatter.js +27 -0
  37. package/dist/cli/formatters/feature-analysis-formatter.d.ts +2 -0
  38. package/dist/cli/formatters/feature-analysis-formatter.js +27 -0
  39. package/dist/cli/formatters/functional-testing-formatter.d.ts +15 -0
  40. package/dist/cli/formatters/functional-testing-formatter.js +37 -0
  41. package/dist/cli/formatters/technical-design-formatter.d.ts +7 -0
  42. package/dist/cli/formatters/technical-design-formatter.js +30 -0
  43. package/dist/cli/index.d.ts +3 -0
  44. package/dist/cli/index.js +99 -0
  45. package/dist/cli/utils/validation.d.ts +25 -0
  46. package/dist/cli/utils/validation.js +58 -0
  47. package/dist/cli/utils/workflow-utils.d.ts +21 -0
  48. package/dist/cli/utils/workflow-utils.js +47 -0
  49. package/dist/cli.d.ts +1 -1
  50. package/dist/cli.js +11 -466
  51. package/dist/config.d.ts +1 -1
  52. package/dist/index.d.ts +3 -3
  53. package/dist/index.js +2 -2
  54. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.d.ts +1 -1
  55. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.js +1 -1
  56. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.d.ts +4 -22
  57. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.js +14 -58
  58. package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.js +1 -30
  59. package/dist/phases/code-implementation/analyzer.d.ts +33 -0
  60. package/dist/{code-implementation → phases/code-implementation}/analyzer.js +178 -19
  61. package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
  62. package/dist/phases/code-implementation/context-fetcher.js +86 -0
  63. package/dist/{code-implementation → phases/code-implementation}/mcp-server.js +1 -30
  64. package/dist/{code-review → phases/code-review}/reviewer.d.ts +1 -1
  65. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.d.ts +3 -2
  66. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.js +35 -127
  67. package/dist/phases/feature-analysis/context-fetcher.d.ts +18 -0
  68. package/dist/phases/feature-analysis/context-fetcher.js +86 -0
  69. package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.js +1 -1
  70. package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.js +1 -24
  71. package/dist/{functional-testing → phases/functional-testing}/analyzer.d.ts +17 -2
  72. package/dist/{functional-testing → phases/functional-testing}/analyzer.js +225 -31
  73. package/dist/phases/functional-testing/context-fetcher.d.ts +16 -0
  74. package/dist/phases/functional-testing/context-fetcher.js +81 -0
  75. package/dist/{functional-testing → phases/functional-testing}/http-fallback.js +1 -1
  76. package/dist/{functional-testing → phases/functional-testing}/index.d.ts +1 -1
  77. package/dist/{functional-testing → phases/functional-testing}/index.js +1 -1
  78. package/dist/{functional-testing → phases/functional-testing}/mcp-server.js +1 -30
  79. package/dist/{functional-testing → phases/functional-testing}/test-report-creator.js +1 -1
  80. package/dist/phases/functional-testing/test-retry-handler.d.ts +16 -0
  81. package/dist/phases/functional-testing/test-retry-handler.js +75 -0
  82. package/dist/{pull-request → phases/pull-request}/creator.js +47 -6
  83. package/dist/phases/pull-request/handler.d.ts +16 -0
  84. package/dist/phases/pull-request/handler.js +60 -0
  85. package/dist/{technical-design → phases/technical-design}/analyzer.d.ts +7 -2
  86. package/dist/phases/technical-design/analyzer.js +424 -0
  87. package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
  88. package/dist/phases/technical-design/context-fetcher.js +39 -0
  89. package/dist/{technical-design → phases/technical-design}/http-fallback.js +1 -1
  90. package/dist/{technical-design → phases/technical-design}/mcp-server.js +1 -30
  91. package/dist/prompts/bug-fixing.d.ts +2 -0
  92. package/dist/prompts/bug-fixing.js +63 -0
  93. package/dist/prompts/code-implementation.d.ts +3 -0
  94. package/dist/prompts/code-implementation.js +132 -0
  95. package/dist/prompts/feature-analysis.d.ts +3 -0
  96. package/dist/prompts/feature-analysis.js +149 -0
  97. package/dist/prompts/formatters.d.ts +42 -0
  98. package/dist/prompts/formatters.js +168 -0
  99. package/dist/prompts/functional-testing.d.ts +3 -0
  100. package/dist/prompts/functional-testing.js +126 -0
  101. package/dist/prompts/index.d.ts +6 -0
  102. package/dist/prompts/index.js +7 -0
  103. package/dist/prompts/technical-design.d.ts +3 -0
  104. package/dist/prompts/technical-design.js +130 -0
  105. package/dist/services/checklist.d.ts +99 -0
  106. package/dist/services/checklist.js +337 -0
  107. package/dist/types/features.d.ts +29 -0
  108. package/dist/types/features.js +1 -0
  109. package/dist/types/index.d.ts +112 -0
  110. package/dist/types/index.js +1 -0
  111. package/dist/types/pipeline.d.ts +25 -0
  112. package/dist/types/pipeline.js +4 -0
  113. package/dist/utils/image-downloader.d.ts +32 -0
  114. package/dist/utils/image-downloader.js +144 -0
  115. package/dist/utils/image-processor.d.ts +5 -0
  116. package/dist/utils/image-processor.js +55 -0
  117. package/dist/utils/logger.d.ts +19 -0
  118. package/dist/utils/logger.js +52 -0
  119. package/dist/utils/pipeline-logger.d.ts +8 -0
  120. package/dist/utils/pipeline-logger.js +35 -0
  121. package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
  122. package/dist/workflow-runner/config/phase-configs.js +34 -0
  123. package/dist/workflow-runner/config/stage-configs.d.ts +5 -0
  124. package/dist/workflow-runner/config/stage-configs.js +34 -0
  125. package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
  126. package/dist/workflow-runner/core/feature-filter.js +46 -0
  127. package/dist/workflow-runner/core/feature-filter.test.d.ts +4 -0
  128. package/dist/workflow-runner/core/feature-filter.test.js +127 -0
  129. package/dist/workflow-runner/core/index.d.ts +8 -0
  130. package/dist/workflow-runner/core/index.js +12 -0
  131. package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
  132. package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
  133. package/dist/workflow-runner/core/state-manager.d.ts +24 -0
  134. package/dist/workflow-runner/core/state-manager.js +42 -0
  135. package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
  136. package/dist/workflow-runner/core/workflow-logger.js +65 -0
  137. package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
  138. package/dist/workflow-runner/executors/phase-executor.js +183 -0
  139. package/dist/workflow-runner/executors/stage-executor.d.ts +8 -0
  140. package/dist/workflow-runner/executors/stage-executor.js +49 -0
  141. package/dist/workflow-runner/feature-service.d.ts +17 -0
  142. package/dist/workflow-runner/feature-service.js +60 -0
  143. package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
  144. package/dist/workflow-runner/feature-workflow-runner.js +113 -0
  145. package/dist/workflow-runner/index.d.ts +0 -1
  146. package/dist/workflow-runner/index.js +0 -1
  147. package/dist/workflow-runner/pipeline-runner.d.ts +9 -19
  148. package/dist/workflow-runner/pipeline-runner.js +247 -256
  149. package/dist/workflow-runner/pipeline.d.ts +18 -0
  150. package/dist/workflow-runner/pipeline.js +197 -0
  151. package/dist/workflow-runner/processor.d.ts +40 -0
  152. package/dist/workflow-runner/processor.js +191 -0
  153. package/dist/workflow-runner/types.d.ts +48 -0
  154. package/dist/workflow-runner/types.js +4 -0
  155. package/dist/workflow-runner/workflow-processor.d.ts +6 -23
  156. package/dist/workflow-runner/workflow-processor.js +38 -100
  157. package/package.json +1 -1
  158. package/dist/code-implementation/analyzer.d.ts +0 -19
  159. package/dist/code-implementation/context-fetcher.d.ts +0 -38
  160. package/dist/code-implementation/context-fetcher.js +0 -147
  161. package/dist/feature-analysis/context-fetcher.d.ts +0 -54
  162. package/dist/feature-analysis/context-fetcher.js +0 -193
  163. package/dist/functional-testing/context-fetcher.d.ts +0 -47
  164. package/dist/functional-testing/context-fetcher.js +0 -192
  165. package/dist/technical-design/analyzer.js +0 -338
  166. package/dist/technical-design/context-fetcher.d.ts +0 -42
  167. package/dist/technical-design/context-fetcher.js +0 -170
  168. /package/dist/{bug-fixing → phases/bug-fixing}/index.d.ts +0 -0
  169. /package/dist/{bug-fixing → phases/bug-fixing}/index.js +0 -0
  170. /package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.d.ts +0 -0
  171. /package/dist/{code-implementation → phases/code-implementation}/mcp-server.d.ts +0 -0
  172. /package/dist/{code-review → phases/code-review}/reviewer.js +0 -0
  173. /package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.d.ts +0 -0
  174. /package/dist/{feature-analysis → phases/feature-analysis}/index.d.ts +0 -0
  175. /package/dist/{feature-analysis → phases/feature-analysis}/index.js +0 -0
  176. /package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.d.ts +0 -0
  177. /package/dist/{functional-testing → phases/functional-testing}/http-fallback.d.ts +0 -0
  178. /package/dist/{functional-testing → phases/functional-testing}/mcp-server.d.ts +0 -0
  179. /package/dist/{functional-testing → phases/functional-testing}/test-report-creator.d.ts +0 -0
  180. /package/dist/{pull-request → phases/pull-request}/creator.d.ts +0 -0
  181. /package/dist/{technical-design → phases/technical-design}/http-fallback.d.ts +0 -0
  182. /package/dist/{technical-design → phases/technical-design}/mcp-server.d.ts +0 -0
@@ -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>;
8
+ export { runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, };
@@ -0,0 +1,183 @@
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
+ // Higher-order function for phase execution
8
+ export const createPhaseRunner = (phaseConfig) => async (options, config) => {
9
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
10
+ const { name, checkRequirements, execute, requirementsError } = phaseConfig;
11
+ try {
12
+ // Check requirements
13
+ const hasRequirements = await checkRequirements();
14
+ if (!hasRequirements) {
15
+ return {
16
+ featureId,
17
+ phase: name,
18
+ status: 'error',
19
+ message: requirementsError,
20
+ };
21
+ }
22
+ // Update feature status to reflect current phase
23
+ await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, name, verbose);
24
+ if (verbose) {
25
+ console.log(`🎯 Starting ${name} for: ${featureId}`);
26
+ }
27
+ // Fetch checklists for this phase as context
28
+ let checklistContext = null;
29
+ try {
30
+ checklistContext = await getChecklistsForPhase(options, name);
31
+ if (verbose && checklistContext.checklists.length > 0) {
32
+ console.log(`📋 Found ${checklistContext.checklists.length} checklists for ${name} phase`);
33
+ }
34
+ }
35
+ catch (checklistError) {
36
+ // Always log checklist fetch errors, not just in verbose mode
37
+ console.log(`⚠️ Failed to fetch checklists for ${name} phase: ${checklistError instanceof Error ? checklistError.message : String(checklistError)}`);
38
+ // Log more details in verbose mode
39
+ if (verbose && checklistError instanceof Error) {
40
+ console.log(` Details: ${checklistError.stack}`);
41
+ }
42
+ }
43
+ // Execute the phase with checklist context
44
+ const result = await execute(options, config, checklistContext);
45
+ console.log({
46
+ result,
47
+ });
48
+ console.log({
49
+ status: result.status,
50
+ });
51
+ console.log({
52
+ data: result.data,
53
+ });
54
+ console.log({
55
+ checklist_item_results: result.data?.checklist_item_results,
56
+ });
57
+ // Process checklist results from phase response if phase was successful
58
+ if (result.status === 'success') {
59
+ try {
60
+ // Extract checklist_item_results from result data if available (new format)
61
+ const checklistItemResults = result.data?.checklist_item_results;
62
+ if (checklistItemResults && Array.isArray(checklistItemResults)) {
63
+ const processResult = await processChecklistItemResultsFromResponse(options, name, checklistItemResults, verbose);
64
+ if (verbose) {
65
+ if (processResult.created > 0) {
66
+ console.log(`📋 Processed ${processResult.created} checklist item results from ${name} phase`);
67
+ }
68
+ if (processResult.errors.length > 0) {
69
+ console.log(`⚠️ ${processResult.errors.length} errors processing checklist item results`);
70
+ processResult.errors.forEach((error) => console.log(` - ${error}`));
71
+ }
72
+ }
73
+ }
74
+ else {
75
+ // Fallback to old format for backward compatibility
76
+ const checklistResults = result.data?.checklist_results;
77
+ if (checklistResults && Array.isArray(checklistResults)) {
78
+ const processResult = await processChecklistResultsFromResponse(options, checklistResults, verbose);
79
+ if (verbose) {
80
+ if (processResult.created > 0) {
81
+ console.log(`📋 Processed ${processResult.created} checklist results from ${name} phase (legacy format)`);
82
+ }
83
+ if (processResult.errors.length > 0) {
84
+ console.log(`⚠️ ${processResult.errors.length} errors processing checklist results`);
85
+ processResult.errors.forEach((error) => console.log(` - ${error}`));
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ catch (processError) {
92
+ if (verbose) {
93
+ console.log(`⚠️ Failed to process checklist results from ${name} phase: ${processError instanceof Error ? processError.message : String(processError)}`);
94
+ }
95
+ }
96
+ }
97
+ // Strictly validate checklist results after phase execution
98
+ let checklistValidation = null;
99
+ if (result.status === 'success') {
100
+ try {
101
+ // First perform strict validation - this will fail if checklists exist but have no results
102
+ const strictValidation = await validateRequiredChecklistResults(options, name, verbose);
103
+ if (!strictValidation.success) {
104
+ // If validation fails, return error immediately - don't continue pipeline
105
+ return {
106
+ featureId,
107
+ phase: name,
108
+ status: 'error',
109
+ message: `Checklist validation failed: ${strictValidation.error}`,
110
+ data: {
111
+ ...result,
112
+ checklist_context: checklistContext,
113
+ checklist_validation_error: strictValidation.error,
114
+ missing_checklists: strictValidation.missingChecklists,
115
+ },
116
+ };
117
+ }
118
+ // If strict validation passes, get detailed validation info for logging
119
+ checklistValidation = await validateChecklistsForPhase(options, name);
120
+ if (verbose) {
121
+ console.log(`📋 Checklist validation: ${checklistValidation.summary}`);
122
+ }
123
+ // Log completion status
124
+ if (checklistValidation.checklists_validation.length > 0) {
125
+ const completedCount = checklistValidation.checklists_validation.filter((v) => v.is_completed).length;
126
+ const totalCount = checklistValidation.checklists_validation.length;
127
+ if (verbose) {
128
+ console.log(`📋 Checklist results status: ${completedCount}/${totalCount} checklists have results`);
129
+ }
130
+ // Log any incomplete checklists
131
+ if (!checklistValidation.all_completed) {
132
+ checklistValidation.checklists_validation.forEach((validation) => {
133
+ if (!validation.is_completed) {
134
+ console.log(` - ${validation.checklist_name} (${validation.role}): ${validation.status}`);
135
+ }
136
+ });
137
+ }
138
+ }
139
+ }
140
+ catch (validationError) {
141
+ // If validation itself fails, treat as error and stop pipeline
142
+ return {
143
+ featureId,
144
+ phase: name,
145
+ status: 'error',
146
+ message: `Checklist validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`,
147
+ data: {
148
+ ...result,
149
+ checklist_context: checklistContext,
150
+ checklist_validation_error: validationError instanceof Error
151
+ ? validationError.message
152
+ : String(validationError),
153
+ },
154
+ };
155
+ }
156
+ }
157
+ return {
158
+ featureId,
159
+ phase: name,
160
+ status: result.status === 'success' ? 'success' : 'error',
161
+ message: result.status === 'success'
162
+ ? `${name.replace('-', ' ')} completed successfully`
163
+ : `${name.replace('-', ' ')} failed`,
164
+ data: {
165
+ ...result,
166
+ checklist_context: checklistContext,
167
+ checklist_validation: checklistValidation,
168
+ },
169
+ };
170
+ }
171
+ catch (error) {
172
+ return {
173
+ featureId,
174
+ phase: name,
175
+ status: 'error',
176
+ message: `${name.replace('-', ' ')} failed: ${error instanceof Error ? error.message : String(error)}`,
177
+ };
178
+ }
179
+ };
180
+ // Create phase runners using the configuration
181
+ const [runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase,] = phaseConfigs.map(createPhaseRunner);
182
+ // Export individual phase runners for granular control
183
+ export { runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Stage execution logic for pipeline runner
3
+ */
4
+ import { EdsgerConfig } from '../../types/index.js';
5
+ import { PipelineStageOptions, PipelineResult, StageConfig } from '../../types/pipeline.js';
6
+ export declare const createStageRunner: (stageConfig: StageConfig) => (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>;
7
+ declare const runFeatureAnalysisStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runTechnicalDesignStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeImplementationStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runFunctionalTestingStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>;
8
+ export { runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage, };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Stage execution logic for pipeline runner
3
+ */
4
+ import { updateFeatureStatusForStage } from '../../api/features/index.js';
5
+ import { stageConfigs } from '../config/stage-configs.js';
6
+ // Higher-order function for stage execution
7
+ export const createStageRunner = (stageConfig) => async (options, config) => {
8
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
9
+ const { name, checkRequirements, execute, requirementsError } = stageConfig;
10
+ try {
11
+ // Check requirements
12
+ const hasRequirements = await checkRequirements();
13
+ if (!hasRequirements) {
14
+ return {
15
+ featureId,
16
+ stage: name,
17
+ status: 'error',
18
+ message: requirementsError,
19
+ };
20
+ }
21
+ // Update feature status to reflect current stage
22
+ await updateFeatureStatusForStage({ mcpServerUrl, mcpToken }, featureId, name, verbose);
23
+ if (verbose) {
24
+ console.log(`🎯 Starting ${name} for: ${featureId}`);
25
+ }
26
+ const result = await execute(options, config);
27
+ return {
28
+ featureId,
29
+ stage: name,
30
+ status: result.status === 'success' ? 'success' : 'error',
31
+ message: result.status === 'success'
32
+ ? `${name.replace('-', ' ')} completed successfully`
33
+ : `${name.replace('-', ' ')} failed`,
34
+ data: result,
35
+ };
36
+ }
37
+ catch (error) {
38
+ return {
39
+ featureId,
40
+ stage: name,
41
+ status: 'error',
42
+ message: `${name.replace('-', ' ')} failed: ${error instanceof Error ? error.message : String(error)}`,
43
+ };
44
+ }
45
+ };
46
+ // Create stage runners using the configuration
47
+ const [runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage,] = stageConfigs.map(createStageRunner);
48
+ // Export individual stage runners for granular control
49
+ export { runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage, };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Feature fetching and status management service
3
+ */
4
+ import { FeatureStatus } from '../types.js';
5
+ import { type FeatureInfo } from '../api/features.js';
6
+ /**
7
+ * Fetch features with ready_for_dev status for a product
8
+ */
9
+ export declare function fetchReadyForDevFeatures(mcpServerUrl: string, mcpToken: string, productId: string, verbose?: boolean): Promise<FeatureInfo[]>;
10
+ /**
11
+ * Map pipeline stage to feature status
12
+ */
13
+ export declare function getStatusForStage(stage: string): FeatureStatus;
14
+ /**
15
+ * Update feature status based on pipeline stage
16
+ */
17
+ export declare function updateFeatureStatusForStage(mcpServerUrl: string, mcpToken: string, featureId: string, stage: string, verbose?: boolean): Promise<boolean>;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Feature fetching and status management service
3
+ */
4
+ import { logInfo, logError } from '../logger.js';
5
+ import { updateFeatureStatus, } from '../api/features.js';
6
+ import { callMcpEndpoint } from '../api/mcp-client.js';
7
+ /**
8
+ * Fetch features with ready_for_dev status for a product
9
+ */
10
+ export async function fetchReadyForDevFeatures(mcpServerUrl, mcpToken, productId, verbose) {
11
+ try {
12
+ if (verbose) {
13
+ logInfo(`📋 Fetching ready_for_dev features for product: ${productId}`);
14
+ }
15
+ const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/list', {
16
+ product_id: productId,
17
+ status: 'ready_for_dev',
18
+ }));
19
+ const features = result?.features || [];
20
+ if (verbose) {
21
+ logInfo(`✅ Found ${features.length} ready_for_dev features`);
22
+ features.forEach((feature, index) => {
23
+ logInfo(` ${index + 1}. ${feature.name} (${feature.id})`);
24
+ });
25
+ }
26
+ return features;
27
+ }
28
+ catch (error) {
29
+ logError(`❌ Error fetching features: ${error}`);
30
+ throw error;
31
+ }
32
+ }
33
+ /**
34
+ * Map pipeline stage to feature status
35
+ */
36
+ export function getStatusForStage(stage) {
37
+ switch (stage) {
38
+ case 'feature-analysis':
39
+ return 'feature_analysis';
40
+ case 'technical-design':
41
+ return 'technical_design';
42
+ case 'code-implementation':
43
+ return 'code_implementation';
44
+ case 'functional-testing':
45
+ return 'testing_in_progress';
46
+ case 'testing-passed':
47
+ return 'testing_passed';
48
+ case 'testing-failed':
49
+ return 'testing_failed';
50
+ default:
51
+ return 'backlog';
52
+ }
53
+ }
54
+ /**
55
+ * Update feature status based on pipeline stage
56
+ */
57
+ export async function updateFeatureStatusForStage(mcpServerUrl, mcpToken, featureId, stage, verbose) {
58
+ const status = getStatusForStage(stage);
59
+ return await updateFeatureStatus(mcpServerUrl, mcpToken, featureId, status, verbose);
60
+ }
@@ -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,113 @@
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
+ 'from_feature_analysis',
86
+ 'from_technical_design',
87
+ 'from_code_implementation',
88
+ 'from_functional_testing',
89
+ ];
90
+ }
91
+ /**
92
+ * Validate execution mode
93
+ */
94
+ export function isValidExecutionMode(mode) {
95
+ return getAvailableExecutionModes().includes(mode);
96
+ }
97
+ /**
98
+ * Get execution mode description
99
+ */
100
+ export function getExecutionModeDescription(mode) {
101
+ const descriptions = {
102
+ full_pipeline: 'Execute complete workflow: analysis → design → implementation → testing',
103
+ only_feature_analysis: 'Execute only: feature analysis',
104
+ only_technical_design: 'Execute only: technical design',
105
+ only_code_implementation: 'Execute only: code implementation',
106
+ only_functional_testing: 'Execute only: functional testing',
107
+ from_feature_analysis: 'Execute from feature analysis to end: analysis → design → implementation → testing',
108
+ from_technical_design: 'Execute from technical design to end: design → implementation → testing',
109
+ from_code_implementation: 'Execute from code implementation to end: implementation → testing',
110
+ from_functional_testing: 'Execute from functional testing to end: testing',
111
+ };
112
+ return descriptions[mode] || 'Unknown execution mode';
113
+ }
@@ -1,3 +1,2 @@
1
1
  export * from './workflow-processor.js';
2
- export * from './feature-fetcher.js';
3
2
  export * from './pipeline-runner.js';
@@ -1,3 +1,2 @@
1
1
  export * from './workflow-processor.js';
2
- export * from './feature-fetcher.js';
3
2
  export * from './pipeline-runner.js';
@@ -1,25 +1,15 @@
1
1
  /**
2
- * Pipeline runner for executing development workflow stages
2
+ * Pipeline runner for executing development workflow phases
3
3
  * Coordinates feature-analysis -> technical-design -> code-implementation -> functional-testing
4
4
  * Uses functional programming principles
5
5
  */
6
- import { EdsgerConfig } from '../types.js';
7
- export interface PipelineStageOptions {
8
- readonly featureId: string;
9
- readonly mcpServerUrl: string;
10
- readonly mcpToken: string;
11
- readonly verbose?: boolean;
12
- }
13
- export interface PipelineResult {
14
- readonly featureId: string;
15
- readonly stage: string;
16
- readonly status: 'success' | 'error';
17
- readonly message: string;
18
- readonly data?: unknown;
19
- }
20
- declare const runFeatureAnalysisStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runTechnicalDesignStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeImplementationStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runFunctionalTestingStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>;
6
+ import { EdsgerConfig } from '../types/index.js';
7
+ import { PipelinePhaseOptions, PipelineResult, ExecutionMode } from '../types/pipeline.js';
21
8
  /**
22
- * Run complete pipeline for a feature using functional composition
9
+ * Run pipeline based on execution mode
23
10
  */
24
- export declare const runCompletePipeline: (options: PipelineStageOptions, config: EdsgerConfig) => () => Promise<readonly PipelineResult[]>;
25
- export { runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage, };
11
+ export declare const runPipelineByMode: (options: PipelinePhaseOptions, config: EdsgerConfig, executionMode: ExecutionMode) => Promise<readonly PipelineResult[]>;
12
+ /**
13
+ * Run complete pipeline for a feature using functional composition (legacy)
14
+ */
15
+ export declare const runCompletePipeline: (options: PipelinePhaseOptions, config: EdsgerConfig) => () => Promise<readonly PipelineResult[]>;