edsger 0.41.0 → 0.41.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.
- package/.claude/settings.local.json +23 -3
- package/.env.local +12 -0
- package/dist/api/features/__tests__/regression-prevention.test.d.ts +5 -0
- package/dist/api/features/__tests__/regression-prevention.test.js +338 -0
- package/dist/api/features/__tests__/status-updater.integration.test.d.ts +5 -0
- package/dist/api/features/__tests__/status-updater.integration.test.js +497 -0
- package/dist/commands/workflow/pipeline-runner.d.ts +17 -0
- package/dist/commands/workflow/pipeline-runner.js +393 -0
- package/dist/commands/workflow/runner.d.ts +26 -0
- package/dist/commands/workflow/runner.js +119 -0
- package/dist/commands/workflow/workflow-runner.d.ts +26 -0
- package/dist/commands/workflow/workflow-runner.js +119 -0
- package/dist/index.js +0 -0
- package/dist/phases/code-implementation/analyzer-helpers.d.ts +28 -0
- package/dist/phases/code-implementation/analyzer-helpers.js +177 -0
- package/dist/phases/code-implementation/analyzer.d.ts +32 -0
- package/dist/phases/code-implementation/analyzer.js +629 -0
- package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
- package/dist/phases/code-implementation/context-fetcher.js +86 -0
- package/dist/phases/code-implementation/mcp-server.d.ts +1 -0
- package/dist/phases/code-implementation/mcp-server.js +93 -0
- package/dist/phases/code-implementation/prompts-improvement.d.ts +5 -0
- package/dist/phases/code-implementation/prompts-improvement.js +108 -0
- package/dist/phases/code-implementation-verification/verifier.d.ts +31 -0
- package/dist/phases/code-implementation-verification/verifier.js +196 -0
- package/dist/phases/code-refine/analyzer.d.ts +41 -0
- package/dist/phases/code-refine/analyzer.js +561 -0
- package/dist/phases/code-refine/context-fetcher.d.ts +94 -0
- package/dist/phases/code-refine/context-fetcher.js +423 -0
- package/dist/phases/code-refine-verification/analysis/llm-analyzer.d.ts +22 -0
- package/dist/phases/code-refine-verification/analysis/llm-analyzer.js +134 -0
- package/dist/phases/code-refine-verification/verifier.d.ts +47 -0
- package/dist/phases/code-refine-verification/verifier.js +597 -0
- package/dist/phases/code-review/analyzer.d.ts +29 -0
- package/dist/phases/code-review/analyzer.js +363 -0
- package/dist/phases/code-review/context-fetcher.d.ts +92 -0
- package/dist/phases/code-review/context-fetcher.js +296 -0
- package/dist/phases/feature-analysis/analyzer-helpers.d.ts +10 -0
- package/dist/phases/feature-analysis/analyzer-helpers.js +47 -0
- package/dist/phases/feature-analysis/analyzer.d.ts +11 -0
- package/dist/phases/feature-analysis/analyzer.js +208 -0
- package/dist/phases/feature-analysis/context-fetcher.d.ts +26 -0
- package/dist/phases/feature-analysis/context-fetcher.js +134 -0
- package/dist/phases/feature-analysis/http-fallback.d.ts +20 -0
- package/dist/phases/feature-analysis/http-fallback.js +95 -0
- package/dist/phases/feature-analysis/mcp-server.d.ts +1 -0
- package/dist/phases/feature-analysis/mcp-server.js +144 -0
- package/dist/phases/feature-analysis/prompts-improvement.d.ts +8 -0
- package/dist/phases/feature-analysis/prompts-improvement.js +109 -0
- package/dist/phases/feature-analysis-verification/verifier.d.ts +37 -0
- package/dist/phases/feature-analysis-verification/verifier.js +147 -0
- package/dist/phases/pr-execution/file-assigner.js +20 -12
- package/dist/phases/technical-design/analyzer-helpers.d.ts +25 -0
- package/dist/phases/technical-design/analyzer-helpers.js +39 -0
- package/dist/phases/technical-design/analyzer.d.ts +21 -0
- package/dist/phases/technical-design/analyzer.js +461 -0
- package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
- package/dist/phases/technical-design/context-fetcher.js +39 -0
- package/dist/phases/technical-design/http-fallback.d.ts +17 -0
- package/dist/phases/technical-design/http-fallback.js +151 -0
- package/dist/phases/technical-design/mcp-server.d.ts +1 -0
- package/dist/phases/technical-design/mcp-server.js +157 -0
- package/dist/phases/technical-design/prompts-improvement.d.ts +5 -0
- package/dist/phases/technical-design/prompts-improvement.js +93 -0
- package/dist/phases/technical-design-verification/verifier.d.ts +53 -0
- package/dist/phases/technical-design-verification/verifier.js +170 -0
- package/dist/services/feature-branches.d.ts +77 -0
- package/dist/services/feature-branches.js +205 -0
- package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
- package/dist/workflow-runner/config/phase-configs.js +120 -0
- package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
- package/dist/workflow-runner/core/feature-filter.js +46 -0
- package/dist/workflow-runner/core/index.d.ts +8 -0
- package/dist/workflow-runner/core/index.js +12 -0
- package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
- package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
- package/dist/workflow-runner/core/state-manager.d.ts +24 -0
- package/dist/workflow-runner/core/state-manager.js +42 -0
- package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
- package/dist/workflow-runner/core/workflow-logger.js +65 -0
- package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
- package/dist/workflow-runner/executors/phase-executor.js +248 -0
- package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
- package/dist/workflow-runner/feature-workflow-runner.js +119 -0
- package/dist/workflow-runner/index.d.ts +2 -0
- package/dist/workflow-runner/index.js +2 -0
- package/dist/workflow-runner/pipeline-runner.d.ts +17 -0
- package/dist/workflow-runner/pipeline-runner.js +393 -0
- package/dist/workflow-runner/workflow-processor.d.ts +54 -0
- package/dist/workflow-runner/workflow-processor.js +170 -0
- package/package.json +1 -1
- package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.d.ts +0 -4
- package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.js +0 -133
- package/dist/services/lifecycle-agent/__tests__/transition-rules.test.d.ts +0 -4
- package/dist/services/lifecycle-agent/__tests__/transition-rules.test.js +0 -336
- package/dist/services/lifecycle-agent/index.d.ts +0 -24
- package/dist/services/lifecycle-agent/index.js +0 -25
- package/dist/services/lifecycle-agent/phase-criteria.d.ts +0 -57
- package/dist/services/lifecycle-agent/phase-criteria.js +0 -335
- package/dist/services/lifecycle-agent/transition-rules.d.ts +0 -60
- package/dist/services/lifecycle-agent/transition-rules.js +0 -184
- package/dist/services/lifecycle-agent/types.d.ts +0 -190
- 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
|
+
}
|
package/dist/index.js
CHANGED
|
File without changes
|