edsger 0.41.1 → 0.41.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 (127) hide show
  1. package/.claude/settings.local.json +23 -3
  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/executors/phase-executor.js +1 -3
  8. package/dist/commands/workflow/phase-orchestrator.js +1 -3
  9. package/dist/commands/workflow/pipeline-runner.d.ts +17 -0
  10. package/dist/commands/workflow/pipeline-runner.js +393 -0
  11. package/dist/commands/workflow/runner.d.ts +26 -0
  12. package/dist/commands/workflow/runner.js +119 -0
  13. package/dist/commands/workflow/workflow-runner.d.ts +26 -0
  14. package/dist/commands/workflow/workflow-runner.js +119 -0
  15. package/dist/index.js +2 -2
  16. package/dist/phases/app-store-generation/index.js +1 -3
  17. package/dist/phases/branch-planning/index.js +1 -3
  18. package/dist/phases/bug-fixing/analyzer.js +1 -3
  19. package/dist/phases/code-implementation/analyzer-helpers.d.ts +28 -0
  20. package/dist/phases/code-implementation/analyzer-helpers.js +177 -0
  21. package/dist/phases/code-implementation/analyzer.d.ts +32 -0
  22. package/dist/phases/code-implementation/analyzer.js +629 -0
  23. package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
  24. package/dist/phases/code-implementation/context-fetcher.js +86 -0
  25. package/dist/phases/code-implementation/index.js +1 -3
  26. package/dist/phases/code-implementation/mcp-server.d.ts +1 -0
  27. package/dist/phases/code-implementation/mcp-server.js +93 -0
  28. package/dist/phases/code-implementation/prompts-improvement.d.ts +5 -0
  29. package/dist/phases/code-implementation/prompts-improvement.js +108 -0
  30. package/dist/phases/code-implementation-verification/verifier.d.ts +31 -0
  31. package/dist/phases/code-implementation-verification/verifier.js +196 -0
  32. package/dist/phases/code-refine/analyzer.d.ts +41 -0
  33. package/dist/phases/code-refine/analyzer.js +561 -0
  34. package/dist/phases/code-refine/context-fetcher.d.ts +94 -0
  35. package/dist/phases/code-refine/context-fetcher.js +423 -0
  36. package/dist/phases/code-refine/index.js +1 -3
  37. package/dist/phases/code-refine-verification/analysis/llm-analyzer.d.ts +22 -0
  38. package/dist/phases/code-refine-verification/analysis/llm-analyzer.js +134 -0
  39. package/dist/phases/code-refine-verification/verifier.d.ts +47 -0
  40. package/dist/phases/code-refine-verification/verifier.js +597 -0
  41. package/dist/phases/code-review/analyzer.d.ts +29 -0
  42. package/dist/phases/code-review/analyzer.js +363 -0
  43. package/dist/phases/code-review/context-fetcher.d.ts +92 -0
  44. package/dist/phases/code-review/context-fetcher.js +296 -0
  45. package/dist/phases/code-review/index.js +1 -3
  46. package/dist/phases/code-testing/analyzer.js +1 -3
  47. package/dist/phases/feature-analysis/analyzer-helpers.d.ts +10 -0
  48. package/dist/phases/feature-analysis/analyzer-helpers.js +47 -0
  49. package/dist/phases/feature-analysis/analyzer.d.ts +11 -0
  50. package/dist/phases/feature-analysis/analyzer.js +208 -0
  51. package/dist/phases/feature-analysis/context-fetcher.d.ts +26 -0
  52. package/dist/phases/feature-analysis/context-fetcher.js +134 -0
  53. package/dist/phases/feature-analysis/http-fallback.d.ts +20 -0
  54. package/dist/phases/feature-analysis/http-fallback.js +95 -0
  55. package/dist/phases/feature-analysis/index.js +1 -3
  56. package/dist/phases/feature-analysis/mcp-server.d.ts +1 -0
  57. package/dist/phases/feature-analysis/mcp-server.js +144 -0
  58. package/dist/phases/feature-analysis/prompts-improvement.d.ts +8 -0
  59. package/dist/phases/feature-analysis/prompts-improvement.js +109 -0
  60. package/dist/phases/feature-analysis-verification/verifier.d.ts +37 -0
  61. package/dist/phases/feature-analysis-verification/verifier.js +147 -0
  62. package/dist/phases/functional-testing/analyzer.js +1 -3
  63. package/dist/phases/growth-analysis/index.js +1 -3
  64. package/dist/phases/pr-execution/file-assigner.js +20 -12
  65. package/dist/phases/pr-execution/index.js +59 -1
  66. package/dist/phases/pr-resolve/prompts.js +2 -1
  67. package/dist/phases/pr-resolve/workspace.d.ts +1 -1
  68. package/dist/phases/pr-resolve/workspace.js +1 -1
  69. package/dist/phases/pr-review/__tests__/review-comments.test.js +4 -2
  70. package/dist/phases/pr-review/index.js +1 -3
  71. package/dist/phases/pr-shared/agent-utils.js +0 -1
  72. package/dist/phases/pr-shared/context.d.ts +1 -1
  73. package/dist/phases/pr-splitting/index.js +1 -3
  74. package/dist/phases/technical-design/analyzer-helpers.d.ts +25 -0
  75. package/dist/phases/technical-design/analyzer-helpers.js +39 -0
  76. package/dist/phases/technical-design/analyzer.d.ts +21 -0
  77. package/dist/phases/technical-design/analyzer.js +461 -0
  78. package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
  79. package/dist/phases/technical-design/context-fetcher.js +39 -0
  80. package/dist/phases/technical-design/http-fallback.d.ts +17 -0
  81. package/dist/phases/technical-design/http-fallback.js +151 -0
  82. package/dist/phases/technical-design/index.js +1 -3
  83. package/dist/phases/technical-design/mcp-server.d.ts +1 -0
  84. package/dist/phases/technical-design/mcp-server.js +157 -0
  85. package/dist/phases/technical-design/prompts-improvement.d.ts +5 -0
  86. package/dist/phases/technical-design/prompts-improvement.js +93 -0
  87. package/dist/phases/technical-design-verification/verifier.d.ts +53 -0
  88. package/dist/phases/technical-design-verification/verifier.js +170 -0
  89. package/dist/phases/test-cases-analysis/index.js +1 -3
  90. package/dist/phases/user-stories-analysis/index.js +1 -3
  91. package/dist/services/feature-branches.d.ts +77 -0
  92. package/dist/services/feature-branches.js +205 -0
  93. package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
  94. package/dist/workflow-runner/config/phase-configs.js +120 -0
  95. package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
  96. package/dist/workflow-runner/core/feature-filter.js +46 -0
  97. package/dist/workflow-runner/core/index.d.ts +8 -0
  98. package/dist/workflow-runner/core/index.js +12 -0
  99. package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
  100. package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
  101. package/dist/workflow-runner/core/state-manager.d.ts +24 -0
  102. package/dist/workflow-runner/core/state-manager.js +42 -0
  103. package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
  104. package/dist/workflow-runner/core/workflow-logger.js +65 -0
  105. package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
  106. package/dist/workflow-runner/executors/phase-executor.js +248 -0
  107. package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
  108. package/dist/workflow-runner/feature-workflow-runner.js +119 -0
  109. package/dist/workflow-runner/index.d.ts +2 -0
  110. package/dist/workflow-runner/index.js +2 -0
  111. package/dist/workflow-runner/pipeline-runner.d.ts +17 -0
  112. package/dist/workflow-runner/pipeline-runner.js +393 -0
  113. package/dist/workflow-runner/workflow-processor.d.ts +54 -0
  114. package/dist/workflow-runner/workflow-processor.js +170 -0
  115. package/package.json +1 -1
  116. package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.d.ts +0 -4
  117. package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.js +0 -133
  118. package/dist/services/lifecycle-agent/__tests__/transition-rules.test.d.ts +0 -4
  119. package/dist/services/lifecycle-agent/__tests__/transition-rules.test.js +0 -336
  120. package/dist/services/lifecycle-agent/index.d.ts +0 -24
  121. package/dist/services/lifecycle-agent/index.js +0 -25
  122. package/dist/services/lifecycle-agent/phase-criteria.d.ts +0 -57
  123. package/dist/services/lifecycle-agent/phase-criteria.js +0 -335
  124. package/dist/services/lifecycle-agent/transition-rules.d.ts +0 -60
  125. package/dist/services/lifecycle-agent/transition-rules.js +0 -184
  126. package/dist/services/lifecycle-agent/types.d.ts +0 -190
  127. package/dist/services/lifecycle-agent/types.js +0 -12
@@ -0,0 +1,393 @@
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 { updateFeatureStatusForPhase } from '../../api/features/index.js';
9
+ import { runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, runCodeTestingPhase, runCodeReviewPhase, } from './executors/phase-executor.js';
10
+ import { logPipelineStart, logPhaseResult, logPipelineComplete, shouldContinuePipeline, } from '../../utils/pipeline-logger.js';
11
+ import { handleTestFailuresWithRetry } from '../../phases/functional-testing/test-retry-handler.js';
12
+ import { handleCodeRefineWithRetry } from '../../phases/code-refine/retry-handler.js';
13
+ import { handlePullRequestCreation } from '../../phases/pull-request/handler.js';
14
+ /**
15
+ * Run pipeline based on execution mode
16
+ */
17
+ export const runPipelineByMode = async (options, config, executionMode) => {
18
+ const { featureId, verbose } = options;
19
+ if (verbose) {
20
+ console.log(`🚀 Starting pipeline with mode: ${executionMode} for feature: ${featureId}`);
21
+ console.log(`📋 Execution mode details:`);
22
+ console.log(` - Mode value: "${executionMode}"`);
23
+ console.log(` - Mode type: ${typeof executionMode}`);
24
+ console.log(` - Mode === 'only_feature_analysis': ${executionMode === 'only_feature_analysis'}`);
25
+ }
26
+ switch (executionMode) {
27
+ // Complete pipeline
28
+ case 'full_pipeline':
29
+ case 'from_feature_analysis':
30
+ if (verbose) {
31
+ console.log(` ➡️ Matched: full_pipeline or from_feature_analysis - running complete pipeline`);
32
+ }
33
+ return await runFromFeatureAnalysis(options, config);
34
+ // Feature Analysis
35
+ case 'only_feature_analysis':
36
+ if (verbose) {
37
+ console.log(` ➡️ Matched: only_feature_analysis - running analysis only`);
38
+ }
39
+ return await runOnlyFeatureAnalysis(options, config);
40
+ // Technical Design
41
+ case 'only_technical_design':
42
+ return await runOnlyTechnicalDesign(options, config);
43
+ case 'from_technical_design':
44
+ return await runFromTechnicalDesign(options, config);
45
+ // Code Implementation
46
+ case 'only_code_implementation':
47
+ return await runOnlyCodeImplementation(options, config);
48
+ case 'from_code_implementation':
49
+ return await runFromCodeImplementation(options, config);
50
+ // Functional Testing
51
+ case 'only_functional_testing':
52
+ return await runOnlyFunctionalTesting(options, config);
53
+ case 'from_functional_testing':
54
+ return await runFromFunctionalTesting(options, config);
55
+ // Code Refine
56
+ case 'only_code_refine':
57
+ return await runOnlyCodeRefine(options, config);
58
+ // Code Review
59
+ case 'only_code_review':
60
+ return await runOnlyCodeReview(options, config);
61
+ case 'from_code_review':
62
+ return await runFromCodeReview(options, config);
63
+ default:
64
+ throw new Error(`Unsupported execution mode: ${executionMode}`);
65
+ }
66
+ };
67
+ /**
68
+ * Run complete pipeline for a feature using functional composition (legacy)
69
+ */
70
+ export const runCompletePipeline = (options, config) => {
71
+ return async () => {
72
+ return await runFromFeatureAnalysis(options, config);
73
+ };
74
+ };
75
+ // Helper functions for different execution patterns
76
+ /**
77
+ * Run only feature analysis phase
78
+ */
79
+ const runOnlyFeatureAnalysis = async (options, config) => {
80
+ const { featureId, verbose } = options;
81
+ logPipelineStart(featureId, verbose);
82
+ const results = [];
83
+ const analysisResult = await runFeatureAnalysisPhase(options, config);
84
+ results.push(logPhaseResult(analysisResult, verbose));
85
+ return logPipelineComplete(results, verbose);
86
+ };
87
+ /**
88
+ * Run only technical design phase
89
+ */
90
+ const runOnlyTechnicalDesign = async (options, config) => {
91
+ const { featureId, verbose } = options;
92
+ logPipelineStart(featureId, verbose);
93
+ const results = [];
94
+ const designResult = await runTechnicalDesignPhase(options, config);
95
+ results.push(logPhaseResult(designResult, verbose));
96
+ return logPipelineComplete(results, verbose);
97
+ };
98
+ /**
99
+ * Run only code implementation phase
100
+ */
101
+ const runOnlyCodeImplementation = async (options, config) => {
102
+ const { featureId, verbose } = options;
103
+ logPipelineStart(featureId, verbose);
104
+ const results = [];
105
+ const implementationResult = await runCodeImplementationPhase(options, config);
106
+ results.push(logPhaseResult(implementationResult, verbose));
107
+ return logPipelineComplete(results, verbose);
108
+ };
109
+ /**
110
+ * Run only functional testing phase
111
+ */
112
+ const runOnlyFunctionalTesting = async (options, config) => {
113
+ const { featureId, verbose } = options;
114
+ logPipelineStart(featureId, verbose);
115
+ const results = [];
116
+ const testingResult = await runFunctionalTestingPhase(options, config);
117
+ results.push(logPhaseResult(testingResult, verbose));
118
+ return logPipelineComplete(results, verbose);
119
+ };
120
+ /**
121
+ * Run from feature analysis to end
122
+ */
123
+ const runFromFeatureAnalysis = async (options, config) => {
124
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
125
+ logPipelineStart(featureId, verbose);
126
+ const results = [];
127
+ // 1. Feature Analysis
128
+ const analysisResult = await runFeatureAnalysisPhase(options, config);
129
+ results.push(logPhaseResult(analysisResult, verbose));
130
+ if (!shouldContinuePipeline(results)) {
131
+ return logPipelineComplete(results, verbose);
132
+ }
133
+ // 2. Technical Design
134
+ const designResult = await runTechnicalDesignPhase(options, config);
135
+ results.push(logPhaseResult(designResult, verbose));
136
+ if (!shouldContinuePipeline(results)) {
137
+ return logPipelineComplete(results, verbose);
138
+ }
139
+ // 3. Code Implementation
140
+ const implementationResult = await runCodeImplementationPhase(options, config);
141
+ results.push(logPhaseResult(implementationResult, verbose));
142
+ if (!shouldContinuePipeline(results)) {
143
+ return logPipelineComplete(results, verbose);
144
+ }
145
+ // 4. Functional Testing with retry loop for bug fixes
146
+ const testingResult = await handleTestFailuresWithRetry({
147
+ options,
148
+ config,
149
+ results,
150
+ verbose,
151
+ });
152
+ // Update final status based on functional testing result
153
+ const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
154
+ await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
155
+ // Create pull request if tests passed
156
+ if (testingResult.status === 'success') {
157
+ const prCreated = await handlePullRequestCreation({
158
+ featureId,
159
+ mcpServerUrl,
160
+ mcpToken,
161
+ results,
162
+ testingResult,
163
+ verbose,
164
+ });
165
+ // Continue with code review and refine workflow only if PR was created
166
+ if (prCreated) {
167
+ await continueWithCodeReviewAndRefine(options, config, results, verbose);
168
+ }
169
+ else {
170
+ if (verbose) {
171
+ console.log('⚠️ Skipping code review and refine workflow: pull request creation failed');
172
+ }
173
+ }
174
+ }
175
+ return logPipelineComplete(results, verbose);
176
+ };
177
+ /**
178
+ * Run from technical design to end
179
+ */
180
+ const runFromTechnicalDesign = async (options, config) => {
181
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
182
+ logPipelineStart(featureId, verbose);
183
+ const results = [];
184
+ // 1. Technical Design
185
+ const designResult = await runTechnicalDesignPhase(options, config);
186
+ results.push(logPhaseResult(designResult, verbose));
187
+ if (!shouldContinuePipeline(results)) {
188
+ return logPipelineComplete(results, verbose);
189
+ }
190
+ // 2. Code Implementation
191
+ const implementationResult = await runCodeImplementationPhase(options, config);
192
+ results.push(logPhaseResult(implementationResult, verbose));
193
+ if (!shouldContinuePipeline(results)) {
194
+ return logPipelineComplete(results, verbose);
195
+ }
196
+ // 3. Functional Testing with retry loop for bug fixes
197
+ const testingResult = await handleTestFailuresWithRetry({
198
+ options,
199
+ config,
200
+ results,
201
+ verbose,
202
+ });
203
+ // Update final status based on functional testing result
204
+ const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
205
+ await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
206
+ // Create pull request if tests passed
207
+ if (testingResult.status === 'success') {
208
+ const prCreated = await handlePullRequestCreation({
209
+ featureId,
210
+ mcpServerUrl,
211
+ mcpToken,
212
+ results,
213
+ testingResult,
214
+ verbose,
215
+ });
216
+ // Continue with code review and refine workflow only if PR was created
217
+ if (prCreated) {
218
+ await continueWithCodeReviewAndRefine(options, config, results, verbose);
219
+ }
220
+ else {
221
+ if (verbose) {
222
+ console.log('⚠️ Skipping code review and refine workflow: pull request creation failed');
223
+ }
224
+ }
225
+ }
226
+ return logPipelineComplete(results, verbose);
227
+ };
228
+ /**
229
+ * Run from code implementation to end
230
+ */
231
+ const runFromCodeImplementation = async (options, config) => {
232
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
233
+ logPipelineStart(featureId, verbose);
234
+ const results = [];
235
+ // 1. Code Implementation
236
+ const implementationResult = await runCodeImplementationPhase(options, config);
237
+ results.push(logPhaseResult(implementationResult, verbose));
238
+ if (!shouldContinuePipeline(results)) {
239
+ return logPipelineComplete(results, verbose);
240
+ }
241
+ // 2. Functional Testing with retry loop for bug fixes
242
+ const testingResult = await handleTestFailuresWithRetry({
243
+ options,
244
+ config,
245
+ results,
246
+ verbose,
247
+ });
248
+ // Update final status based on functional testing result
249
+ const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
250
+ await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
251
+ // Create pull request if tests passed
252
+ if (testingResult.status === 'success') {
253
+ const prCreated = await handlePullRequestCreation({
254
+ featureId,
255
+ mcpServerUrl,
256
+ mcpToken,
257
+ results,
258
+ testingResult,
259
+ verbose,
260
+ });
261
+ // Continue with code review and refine workflow only if PR was created
262
+ if (prCreated) {
263
+ await continueWithCodeReviewAndRefine(options, config, results, verbose);
264
+ }
265
+ else {
266
+ if (verbose) {
267
+ console.log('⚠️ Skipping code review and refine workflow: pull request creation failed');
268
+ }
269
+ }
270
+ }
271
+ return logPipelineComplete(results, verbose);
272
+ };
273
+ /**
274
+ * Run from functional testing to end
275
+ */
276
+ const runFromFunctionalTesting = async (options, config) => {
277
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
278
+ logPipelineStart(featureId, verbose);
279
+ const results = [];
280
+ // 1. Functional Testing with retry loop for bug fixes
281
+ const testingResult = await handleTestFailuresWithRetry({
282
+ options,
283
+ config,
284
+ results,
285
+ verbose,
286
+ });
287
+ // Update final status based on functional testing result
288
+ const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
289
+ await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
290
+ // Create pull request if tests passed
291
+ if (testingResult.status === 'success') {
292
+ const prCreated = await handlePullRequestCreation({
293
+ featureId,
294
+ mcpServerUrl,
295
+ mcpToken,
296
+ results,
297
+ testingResult,
298
+ verbose,
299
+ });
300
+ // Continue with code review and refine workflow only if PR was created
301
+ if (prCreated) {
302
+ await continueWithCodeReviewAndRefine(options, config, results, verbose);
303
+ }
304
+ else {
305
+ if (verbose) {
306
+ console.log('⚠️ Skipping code review and refine workflow: pull request creation failed');
307
+ }
308
+ }
309
+ }
310
+ return logPipelineComplete(results, verbose);
311
+ };
312
+ /**
313
+ * Run only code refine phase (refine code based on PR feedback)
314
+ * Includes automatic retry loop for verification failures
315
+ */
316
+ const runOnlyCodeRefine = async (options, config) => {
317
+ const { featureId, verbose } = options;
318
+ logPipelineStart(featureId, verbose);
319
+ const results = [];
320
+ // Code Refine with automatic retry for verification failures
321
+ await handleCodeRefineWithRetry({
322
+ options,
323
+ config,
324
+ results,
325
+ verbose,
326
+ });
327
+ return logPipelineComplete(results, verbose);
328
+ };
329
+ /**
330
+ * Run only code review phase (review PR and create review comments)
331
+ */
332
+ const runOnlyCodeReview = async (options, config) => {
333
+ const { featureId, verbose } = options;
334
+ logPipelineStart(featureId, verbose);
335
+ const results = [];
336
+ // Code Review - analyze PR and create review comments
337
+ const reviewResult = await runCodeReviewPhase(options, config);
338
+ results.push(logPhaseResult(reviewResult, verbose));
339
+ return logPipelineComplete(results, verbose);
340
+ };
341
+ /**
342
+ * Run from code review to end (code-review → code-refine → code-refine-verification)
343
+ */
344
+ const runFromCodeReview = async (options, config) => {
345
+ const { featureId, verbose } = options;
346
+ logPipelineStart(featureId, verbose);
347
+ const results = [];
348
+ // 1. Code Review - analyze PR and create review comments
349
+ const reviewResult = await runCodeReviewPhase(options, config);
350
+ results.push(logPhaseResult(reviewResult, verbose));
351
+ if (!shouldContinuePipeline(results)) {
352
+ return logPipelineComplete(results, verbose);
353
+ }
354
+ // 2. Code Refine with automatic retry for verification failures
355
+ await handleCodeRefineWithRetry({
356
+ options,
357
+ config,
358
+ results,
359
+ verbose,
360
+ });
361
+ return logPipelineComplete(results, verbose);
362
+ };
363
+ /**
364
+ * Continue with code review and refine after PR creation
365
+ * This is the post-PR workflow: code-review → code-refine → code-refine-verification → code-testing
366
+ */
367
+ const continueWithCodeReviewAndRefine = async (options, config, results, verbose) => {
368
+ if (verbose) {
369
+ console.log('\n🔄 Continuing with code review and refine workflow...');
370
+ }
371
+ // 1. Code Review - analyze PR and create review comments
372
+ const reviewResult = await runCodeReviewPhase(options, config);
373
+ results.push(logPhaseResult(reviewResult, verbose));
374
+ if (!shouldContinuePipeline(results)) {
375
+ return;
376
+ }
377
+ // 2. Code Refine with automatic retry for verification failures
378
+ await handleCodeRefineWithRetry({
379
+ options,
380
+ config,
381
+ results,
382
+ verbose,
383
+ });
384
+ if (!shouldContinuePipeline(results)) {
385
+ return;
386
+ }
387
+ // 3. Code Testing - write automated tests for the implemented code
388
+ if (verbose) {
389
+ console.log('\n📝 Starting code testing phase...');
390
+ }
391
+ const testingResult = await runCodeTestingPhase(options, config);
392
+ results.push(logPhaseResult(testingResult, verbose));
393
+ };
@@ -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 '../../workflow-runner/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,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
+ }