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.
- package/dist/api/features/feature-utils.d.ts +13 -0
- package/dist/api/features/feature-utils.js +46 -0
- package/dist/api/features/get-feature.d.ts +5 -0
- package/dist/api/features/get-feature.js +19 -0
- package/dist/api/features/index.d.ts +7 -0
- package/dist/api/features/index.js +9 -0
- package/dist/api/features/status-updater.d.ts +27 -0
- package/dist/api/features/status-updater.js +64 -0
- package/dist/api/features/test-cases.d.ts +21 -0
- package/dist/api/features/test-cases.js +63 -0
- package/dist/api/features/update-feature.d.ts +13 -0
- package/dist/api/features/update-feature.js +31 -0
- package/dist/api/features/user-stories.d.ts +21 -0
- package/dist/api/features/user-stories.js +63 -0
- package/dist/api/features.d.ts +100 -0
- package/dist/api/features.js +219 -0
- package/dist/api/mcp-client.d.ts +18 -0
- package/dist/api/mcp-client.js +58 -0
- package/dist/api/products.d.ts +10 -0
- package/dist/api/products.js +22 -0
- package/dist/api/test-reports.d.ts +9 -0
- package/dist/api/test-reports.js +25 -0
- package/dist/cli/commands/code-implementation-command.d.ts +2 -0
- package/dist/cli/commands/code-implementation-command.js +36 -0
- package/dist/cli/commands/code-review-command.d.ts +2 -0
- package/dist/cli/commands/code-review-command.js +39 -0
- package/dist/cli/commands/feature-analysis-command.d.ts +2 -0
- package/dist/cli/commands/feature-analysis-command.js +36 -0
- package/dist/cli/commands/functional-testing-command.d.ts +2 -0
- package/dist/cli/commands/functional-testing-command.js +36 -0
- package/dist/cli/commands/technical-design-command.d.ts +2 -0
- package/dist/cli/commands/technical-design-command.js +36 -0
- package/dist/cli/commands/workflow-command.d.ts +2 -0
- package/dist/cli/commands/workflow-command.js +34 -0
- package/dist/cli/formatters/code-implementation-formatter.d.ts +9 -0
- package/dist/cli/formatters/code-implementation-formatter.js +27 -0
- package/dist/cli/formatters/feature-analysis-formatter.d.ts +2 -0
- package/dist/cli/formatters/feature-analysis-formatter.js +27 -0
- package/dist/cli/formatters/functional-testing-formatter.d.ts +15 -0
- package/dist/cli/formatters/functional-testing-formatter.js +37 -0
- package/dist/cli/formatters/technical-design-formatter.d.ts +7 -0
- package/dist/cli/formatters/technical-design-formatter.js +30 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/utils/validation.d.ts +25 -0
- package/dist/cli/utils/validation.js +58 -0
- package/dist/cli/utils/workflow-utils.d.ts +21 -0
- package/dist/cli/utils/workflow-utils.js +47 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +11 -466
- package/dist/config.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{bug-fixing → phases/bug-fixing}/analyzer.d.ts +1 -1
- package/dist/{bug-fixing → phases/bug-fixing}/analyzer.js +1 -1
- package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.d.ts +4 -22
- package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.js +14 -58
- package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.js +1 -30
- package/dist/phases/code-implementation/analyzer.d.ts +33 -0
- package/dist/{code-implementation → phases/code-implementation}/analyzer.js +178 -19
- package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
- package/dist/phases/code-implementation/context-fetcher.js +86 -0
- package/dist/{code-implementation → phases/code-implementation}/mcp-server.js +1 -30
- package/dist/{code-review → phases/code-review}/reviewer.d.ts +1 -1
- package/dist/{feature-analysis → phases/feature-analysis}/analyzer.d.ts +3 -2
- package/dist/{feature-analysis → phases/feature-analysis}/analyzer.js +35 -127
- package/dist/phases/feature-analysis/context-fetcher.d.ts +18 -0
- package/dist/phases/feature-analysis/context-fetcher.js +86 -0
- package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.js +1 -1
- package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.js +1 -24
- package/dist/{functional-testing → phases/functional-testing}/analyzer.d.ts +17 -2
- package/dist/{functional-testing → phases/functional-testing}/analyzer.js +225 -31
- package/dist/phases/functional-testing/context-fetcher.d.ts +16 -0
- package/dist/phases/functional-testing/context-fetcher.js +81 -0
- package/dist/{functional-testing → phases/functional-testing}/http-fallback.js +1 -1
- package/dist/{functional-testing → phases/functional-testing}/index.d.ts +1 -1
- package/dist/{functional-testing → phases/functional-testing}/index.js +1 -1
- package/dist/{functional-testing → phases/functional-testing}/mcp-server.js +1 -30
- package/dist/{functional-testing → phases/functional-testing}/test-report-creator.js +1 -1
- package/dist/phases/functional-testing/test-retry-handler.d.ts +16 -0
- package/dist/phases/functional-testing/test-retry-handler.js +75 -0
- package/dist/{pull-request → phases/pull-request}/creator.js +47 -6
- package/dist/phases/pull-request/handler.d.ts +16 -0
- package/dist/phases/pull-request/handler.js +60 -0
- package/dist/{technical-design → phases/technical-design}/analyzer.d.ts +7 -2
- package/dist/phases/technical-design/analyzer.js +424 -0
- package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
- package/dist/phases/technical-design/context-fetcher.js +39 -0
- package/dist/{technical-design → phases/technical-design}/http-fallback.js +1 -1
- package/dist/{technical-design → phases/technical-design}/mcp-server.js +1 -30
- package/dist/prompts/bug-fixing.d.ts +2 -0
- package/dist/prompts/bug-fixing.js +63 -0
- package/dist/prompts/code-implementation.d.ts +3 -0
- package/dist/prompts/code-implementation.js +132 -0
- package/dist/prompts/feature-analysis.d.ts +3 -0
- package/dist/prompts/feature-analysis.js +149 -0
- package/dist/prompts/formatters.d.ts +42 -0
- package/dist/prompts/formatters.js +168 -0
- package/dist/prompts/functional-testing.d.ts +3 -0
- package/dist/prompts/functional-testing.js +126 -0
- package/dist/prompts/index.d.ts +6 -0
- package/dist/prompts/index.js +7 -0
- package/dist/prompts/technical-design.d.ts +3 -0
- package/dist/prompts/technical-design.js +130 -0
- package/dist/services/checklist.d.ts +99 -0
- package/dist/services/checklist.js +337 -0
- package/dist/types/features.d.ts +29 -0
- package/dist/types/features.js +1 -0
- package/dist/types/index.d.ts +112 -0
- package/dist/types/index.js +1 -0
- package/dist/types/pipeline.d.ts +25 -0
- package/dist/types/pipeline.js +4 -0
- package/dist/utils/image-downloader.d.ts +32 -0
- package/dist/utils/image-downloader.js +144 -0
- package/dist/utils/image-processor.d.ts +5 -0
- package/dist/utils/image-processor.js +55 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/pipeline-logger.d.ts +8 -0
- package/dist/utils/pipeline-logger.js +35 -0
- package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
- package/dist/workflow-runner/config/phase-configs.js +34 -0
- package/dist/workflow-runner/config/stage-configs.d.ts +5 -0
- package/dist/workflow-runner/config/stage-configs.js +34 -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/feature-filter.test.d.ts +4 -0
- package/dist/workflow-runner/core/feature-filter.test.js +127 -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 +183 -0
- package/dist/workflow-runner/executors/stage-executor.d.ts +8 -0
- package/dist/workflow-runner/executors/stage-executor.js +49 -0
- package/dist/workflow-runner/feature-service.d.ts +17 -0
- package/dist/workflow-runner/feature-service.js +60 -0
- package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
- package/dist/workflow-runner/feature-workflow-runner.js +113 -0
- package/dist/workflow-runner/index.d.ts +0 -1
- package/dist/workflow-runner/index.js +0 -1
- package/dist/workflow-runner/pipeline-runner.d.ts +9 -19
- package/dist/workflow-runner/pipeline-runner.js +247 -256
- package/dist/workflow-runner/pipeline.d.ts +18 -0
- package/dist/workflow-runner/pipeline.js +197 -0
- package/dist/workflow-runner/processor.d.ts +40 -0
- package/dist/workflow-runner/processor.js +191 -0
- package/dist/workflow-runner/types.d.ts +48 -0
- package/dist/workflow-runner/types.js +4 -0
- package/dist/workflow-runner/workflow-processor.d.ts +6 -23
- package/dist/workflow-runner/workflow-processor.js +38 -100
- package/package.json +1 -1
- package/dist/code-implementation/analyzer.d.ts +0 -19
- package/dist/code-implementation/context-fetcher.d.ts +0 -38
- package/dist/code-implementation/context-fetcher.js +0 -147
- package/dist/feature-analysis/context-fetcher.d.ts +0 -54
- package/dist/feature-analysis/context-fetcher.js +0 -193
- package/dist/functional-testing/context-fetcher.d.ts +0 -47
- package/dist/functional-testing/context-fetcher.js +0 -192
- package/dist/technical-design/analyzer.js +0 -338
- package/dist/technical-design/context-fetcher.d.ts +0 -42
- package/dist/technical-design/context-fetcher.js +0 -170
- /package/dist/{bug-fixing → phases/bug-fixing}/index.d.ts +0 -0
- /package/dist/{bug-fixing → phases/bug-fixing}/index.js +0 -0
- /package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.d.ts +0 -0
- /package/dist/{code-implementation → phases/code-implementation}/mcp-server.d.ts +0 -0
- /package/dist/{code-review → phases/code-review}/reviewer.js +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.d.ts +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/index.d.ts +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/index.js +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/http-fallback.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/mcp-server.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/test-report-creator.d.ts +0 -0
- /package/dist/{pull-request → phases/pull-request}/creator.d.ts +0 -0
- /package/dist/{technical-design → phases/technical-design}/http-fallback.d.ts +0 -0
- /package/dist/{technical-design → phases/technical-design}/mcp-server.d.ts +0 -0
|
@@ -1,273 +1,264 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pipeline runner for executing development workflow
|
|
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 {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
6
|
+
import { updateFeatureStatusForPhase } from '../api/features/index.js';
|
|
7
|
+
import { runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, } from './executors/phase-executor.js';
|
|
8
|
+
import { logPipelineStart, logPhaseResult, logPipelineComplete, shouldContinuePipeline, } from '../utils/pipeline-logger.js';
|
|
9
|
+
import { handleTestFailuresWithRetry } from '../phases/functional-testing/test-retry-handler.js';
|
|
10
|
+
import { handlePullRequestCreation } from '../phases/pull-request/handler.js';
|
|
11
|
+
/**
|
|
12
|
+
* Run pipeline based on execution mode
|
|
13
|
+
*/
|
|
14
|
+
export const runPipelineByMode = async (options, config, executionMode) => {
|
|
15
|
+
const { featureId, verbose } = options;
|
|
16
|
+
if (verbose) {
|
|
17
|
+
console.log(`🚀 Starting pipeline with mode: ${executionMode} for feature: ${featureId}`);
|
|
18
|
+
console.log(`📋 Execution mode details:`);
|
|
19
|
+
console.log(` - Mode value: "${executionMode}"`);
|
|
20
|
+
console.log(` - Mode type: ${typeof executionMode}`);
|
|
21
|
+
console.log(` - Mode === 'only_feature_analysis': ${executionMode === 'only_feature_analysis'}`);
|
|
22
|
+
}
|
|
23
|
+
switch (executionMode) {
|
|
24
|
+
// Complete pipeline
|
|
25
|
+
case 'full_pipeline':
|
|
26
|
+
case 'from_feature_analysis':
|
|
27
|
+
if (verbose) {
|
|
28
|
+
console.log(` ➡️ Matched: full_pipeline or from_feature_analysis - running complete pipeline`);
|
|
29
|
+
}
|
|
30
|
+
return await runFromFeatureAnalysis(options, config);
|
|
31
|
+
// Feature Analysis
|
|
32
|
+
case 'only_feature_analysis':
|
|
33
|
+
if (verbose) {
|
|
34
|
+
console.log(` ➡️ Matched: only_feature_analysis - running analysis only`);
|
|
35
|
+
}
|
|
36
|
+
return await runOnlyFeatureAnalysis(options, config);
|
|
37
|
+
// Technical Design
|
|
38
|
+
case 'only_technical_design':
|
|
39
|
+
return await runOnlyTechnicalDesign(options, config);
|
|
40
|
+
case 'from_technical_design':
|
|
41
|
+
return await runFromTechnicalDesign(options, config);
|
|
42
|
+
// Code Implementation
|
|
43
|
+
case 'only_code_implementation':
|
|
44
|
+
return await runOnlyCodeImplementation(options, config);
|
|
45
|
+
case 'from_code_implementation':
|
|
46
|
+
return await runFromCodeImplementation(options, config);
|
|
47
|
+
// Functional Testing
|
|
48
|
+
case 'only_functional_testing':
|
|
49
|
+
return await runOnlyFunctionalTesting(options, config);
|
|
50
|
+
case 'from_functional_testing':
|
|
51
|
+
return await runFromFunctionalTesting(options, config);
|
|
52
|
+
default:
|
|
53
|
+
throw new Error(`Unsupported execution mode: ${executionMode}`);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Run complete pipeline for a feature using functional composition (legacy)
|
|
58
|
+
*/
|
|
59
|
+
export const runCompletePipeline = (options, config) => {
|
|
60
|
+
return async () => {
|
|
61
|
+
return await runFromFeatureAnalysis(options, config);
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
// Helper functions for different execution patterns
|
|
65
|
+
/**
|
|
66
|
+
* Run only feature analysis phase
|
|
67
|
+
*/
|
|
68
|
+
const runOnlyFeatureAnalysis = async (options, config) => {
|
|
69
|
+
const { featureId, verbose } = options;
|
|
70
|
+
logPipelineStart(featureId, verbose);
|
|
71
|
+
const results = [];
|
|
72
|
+
const analysisResult = await runFeatureAnalysisPhase(options, config);
|
|
73
|
+
results.push(logPhaseResult(analysisResult, verbose));
|
|
74
|
+
return logPipelineComplete(results, verbose);
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Run only technical design phase
|
|
78
|
+
*/
|
|
79
|
+
const runOnlyTechnicalDesign = async (options, config) => {
|
|
80
|
+
const { featureId, verbose } = options;
|
|
81
|
+
logPipelineStart(featureId, verbose);
|
|
82
|
+
const results = [];
|
|
83
|
+
const designResult = await runTechnicalDesignPhase(options, config);
|
|
84
|
+
results.push(logPhaseResult(designResult, verbose));
|
|
85
|
+
return logPipelineComplete(results, verbose);
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Run only code implementation phase
|
|
89
|
+
*/
|
|
90
|
+
const runOnlyCodeImplementation = async (options, config) => {
|
|
91
|
+
const { featureId, verbose } = options;
|
|
92
|
+
logPipelineStart(featureId, verbose);
|
|
93
|
+
const results = [];
|
|
94
|
+
const implementationResult = await runCodeImplementationPhase(options, config);
|
|
95
|
+
results.push(logPhaseResult(implementationResult, verbose));
|
|
96
|
+
return logPipelineComplete(results, verbose);
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Run only functional testing phase
|
|
100
|
+
*/
|
|
101
|
+
const runOnlyFunctionalTesting = async (options, config) => {
|
|
102
|
+
const { featureId, verbose } = options;
|
|
103
|
+
logPipelineStart(featureId, verbose);
|
|
104
|
+
const results = [];
|
|
105
|
+
const testingResult = await runFunctionalTestingPhase(options, config);
|
|
106
|
+
results.push(logPhaseResult(testingResult, verbose));
|
|
107
|
+
return logPipelineComplete(results, verbose);
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Run from feature analysis to end
|
|
111
|
+
*/
|
|
112
|
+
const runFromFeatureAnalysis = async (options, config) => {
|
|
43
113
|
const { featureId, mcpServerUrl, mcpToken, verbose } = options;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
stage: name,
|
|
52
|
-
status: 'error',
|
|
53
|
-
message: requirementsError,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
// Update feature status to reflect current stage
|
|
57
|
-
await updateFeatureStatusForStage({ mcpServerUrl, mcpToken }, featureId, name, verbose);
|
|
58
|
-
if (verbose) {
|
|
59
|
-
console.log(`🎯 Starting ${name} for: ${featureId}`);
|
|
60
|
-
}
|
|
61
|
-
const result = await execute(options, config);
|
|
62
|
-
return {
|
|
63
|
-
featureId,
|
|
64
|
-
stage: name,
|
|
65
|
-
status: result.status === 'success' ? 'success' : 'error',
|
|
66
|
-
message: result.status === 'success'
|
|
67
|
-
? `${name.replace('-', ' ')} completed successfully`
|
|
68
|
-
: `${name.replace('-', ' ')} failed`,
|
|
69
|
-
data: result,
|
|
70
|
-
};
|
|
114
|
+
logPipelineStart(featureId, verbose);
|
|
115
|
+
const results = [];
|
|
116
|
+
// 1. Feature Analysis
|
|
117
|
+
const analysisResult = await runFeatureAnalysisPhase(options, config);
|
|
118
|
+
results.push(logPhaseResult(analysisResult, verbose));
|
|
119
|
+
if (!shouldContinuePipeline(results)) {
|
|
120
|
+
return logPipelineComplete(results, verbose);
|
|
71
121
|
}
|
|
72
|
-
|
|
73
|
-
|
|
122
|
+
// 2. Technical Design
|
|
123
|
+
const designResult = await runTechnicalDesignPhase(options, config);
|
|
124
|
+
results.push(logPhaseResult(designResult, verbose));
|
|
125
|
+
if (!shouldContinuePipeline(results)) {
|
|
126
|
+
return logPipelineComplete(results, verbose);
|
|
127
|
+
}
|
|
128
|
+
// 3. Code Implementation
|
|
129
|
+
const implementationResult = await runCodeImplementationPhase(options, config);
|
|
130
|
+
results.push(logPhaseResult(implementationResult, verbose));
|
|
131
|
+
if (!shouldContinuePipeline(results)) {
|
|
132
|
+
return logPipelineComplete(results, verbose);
|
|
133
|
+
}
|
|
134
|
+
// 4. Functional Testing with retry loop for bug fixes
|
|
135
|
+
const testingResult = await handleTestFailuresWithRetry({
|
|
136
|
+
options,
|
|
137
|
+
config,
|
|
138
|
+
results,
|
|
139
|
+
verbose,
|
|
140
|
+
});
|
|
141
|
+
// Update final status based on functional testing result
|
|
142
|
+
const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
|
|
143
|
+
await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
|
|
144
|
+
// Create pull request if tests passed
|
|
145
|
+
if (testingResult.status === 'success') {
|
|
146
|
+
await handlePullRequestCreation({
|
|
74
147
|
featureId,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
148
|
+
mcpServerUrl,
|
|
149
|
+
mcpToken,
|
|
150
|
+
results,
|
|
151
|
+
testingResult,
|
|
152
|
+
verbose,
|
|
153
|
+
});
|
|
79
154
|
}
|
|
155
|
+
return logPipelineComplete(results, verbose);
|
|
80
156
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Run from technical design to end
|
|
159
|
+
*/
|
|
160
|
+
const runFromTechnicalDesign = async (options, config) => {
|
|
161
|
+
const { featureId, mcpServerUrl, mcpToken, verbose } = options;
|
|
162
|
+
logPipelineStart(featureId, verbose);
|
|
163
|
+
const results = [];
|
|
164
|
+
// 1. Technical Design
|
|
165
|
+
const designResult = await runTechnicalDesignPhase(options, config);
|
|
166
|
+
results.push(logPhaseResult(designResult, verbose));
|
|
167
|
+
if (!shouldContinuePipeline(results)) {
|
|
168
|
+
return logPipelineComplete(results, verbose);
|
|
88
169
|
}
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
170
|
+
// 2. Code Implementation
|
|
171
|
+
const implementationResult = await runCodeImplementationPhase(options, config);
|
|
172
|
+
results.push(logPhaseResult(implementationResult, verbose));
|
|
173
|
+
if (!shouldContinuePipeline(results)) {
|
|
174
|
+
return logPipelineComplete(results, verbose);
|
|
94
175
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
176
|
+
// 3. Functional Testing with retry loop for bug fixes
|
|
177
|
+
const testingResult = await handleTestFailuresWithRetry({
|
|
178
|
+
options,
|
|
179
|
+
config,
|
|
180
|
+
results,
|
|
181
|
+
verbose,
|
|
182
|
+
});
|
|
183
|
+
// Update final status based on functional testing result
|
|
184
|
+
const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
|
|
185
|
+
await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
|
|
186
|
+
// Create pull request if tests passed
|
|
187
|
+
if (testingResult.status === 'success') {
|
|
188
|
+
await handlePullRequestCreation({
|
|
189
|
+
featureId,
|
|
190
|
+
mcpServerUrl,
|
|
191
|
+
mcpToken,
|
|
192
|
+
results,
|
|
193
|
+
testingResult,
|
|
194
|
+
verbose,
|
|
195
|
+
});
|
|
107
196
|
}
|
|
108
|
-
return results;
|
|
109
|
-
};
|
|
110
|
-
// Pure function to check if pipeline should continue
|
|
111
|
-
const shouldContinuePipeline = (results) => {
|
|
112
|
-
const lastResult = results[results.length - 1];
|
|
113
|
-
return lastResult?.status === 'success';
|
|
197
|
+
return logPipelineComplete(results, verbose);
|
|
114
198
|
};
|
|
115
199
|
/**
|
|
116
|
-
* Run
|
|
200
|
+
* Run from code implementation to end
|
|
117
201
|
*/
|
|
118
|
-
|
|
119
|
-
const { featureId, verbose } = options;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!shouldContinuePipeline(results)) {
|
|
127
|
-
return logPipelineComplete(results, verbose);
|
|
128
|
-
}
|
|
129
|
-
// Technical Design
|
|
130
|
-
const designResult = await runTechnicalDesignStage(options, config);
|
|
131
|
-
results.push(logStageResult(designResult, verbose));
|
|
132
|
-
if (!shouldContinuePipeline(results)) {
|
|
133
|
-
return logPipelineComplete(results, verbose);
|
|
134
|
-
}
|
|
135
|
-
// Code Implementation
|
|
136
|
-
const implementationResult = await runCodeImplementationStage(options, config);
|
|
137
|
-
results.push(logStageResult(implementationResult, verbose));
|
|
138
|
-
if (!shouldContinuePipeline(results)) {
|
|
139
|
-
return logPipelineComplete(results, verbose);
|
|
140
|
-
}
|
|
141
|
-
// Functional Testing with retry loop for bug fixes
|
|
142
|
-
const MAX_FIX_ATTEMPTS = 3;
|
|
143
|
-
let testingResult;
|
|
144
|
-
let fixAttempt = 0;
|
|
145
|
-
do {
|
|
146
|
-
// Run functional testing
|
|
147
|
-
testingResult = await runFunctionalTestingStage(options, config);
|
|
148
|
-
results.push(logStageResult(testingResult, verbose));
|
|
149
|
-
// If tests failed and we haven't exceeded max attempts, try to fix
|
|
150
|
-
if (testingResult.status === 'error' && fixAttempt < MAX_FIX_ATTEMPTS) {
|
|
151
|
-
fixAttempt++;
|
|
152
|
-
if (verbose) {
|
|
153
|
-
console.log(`🔧 Tests failed. Attempting to fix bugs (Attempt ${fixAttempt}/${MAX_FIX_ATTEMPTS})...`);
|
|
154
|
-
}
|
|
155
|
-
// Check if bug fixing requirements are met
|
|
156
|
-
const hasBugFixingReqs = await checkBugFixingRequirements();
|
|
157
|
-
if (!hasBugFixingReqs) {
|
|
158
|
-
if (verbose) {
|
|
159
|
-
console.log('⚠️ Bug fixing requirements not met. Skipping automatic fixes.');
|
|
160
|
-
}
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
// Extract test errors from the testing result
|
|
164
|
-
const testErrors = testingResult.data?.testResult || testingResult.message;
|
|
165
|
-
// Run bug fixing
|
|
166
|
-
const fixResult = await fixTestFailures({
|
|
167
|
-
featureId,
|
|
168
|
-
mcpServerUrl: options.mcpServerUrl,
|
|
169
|
-
mcpToken: options.mcpToken,
|
|
170
|
-
testErrors,
|
|
171
|
-
attemptNumber: fixAttempt,
|
|
172
|
-
verbose,
|
|
173
|
-
}, config);
|
|
174
|
-
if (fixResult.status === 'success') {
|
|
175
|
-
if (verbose) {
|
|
176
|
-
console.log(`✅ Bug fixes applied. Re-running tests...`);
|
|
177
|
-
if (fixResult.filesFixed && fixResult.filesFixed.length > 0) {
|
|
178
|
-
console.log(` Files fixed: ${fixResult.filesFixed.join(', ')}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
// Remove the previous failed test result from results
|
|
182
|
-
results.pop();
|
|
183
|
-
// Update status to indicate we're retrying tests
|
|
184
|
-
await updateFeatureStatusForStage({ mcpServerUrl: options.mcpServerUrl, mcpToken: options.mcpToken }, featureId, 'functional-testing', verbose);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
if (verbose) {
|
|
188
|
-
console.log(`❌ Bug fixing failed: ${fixResult.message}`);
|
|
189
|
-
}
|
|
190
|
-
break;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
// Tests passed or max attempts reached
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
} while (fixAttempt <= MAX_FIX_ATTEMPTS);
|
|
198
|
-
// Log if max attempts reached
|
|
199
|
-
if (testingResult.status === 'error' &&
|
|
200
|
-
fixAttempt >= MAX_FIX_ATTEMPTS &&
|
|
201
|
-
verbose) {
|
|
202
|
-
console.log(`⚠️ Maximum fix attempts (${MAX_FIX_ATTEMPTS}) reached. Tests still failing.`);
|
|
203
|
-
}
|
|
204
|
-
// Update final status based on functional testing result
|
|
205
|
-
const { mcpServerUrl, mcpToken } = options;
|
|
206
|
-
const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
|
|
207
|
-
await updateFeatureStatusForStage({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
|
|
208
|
-
// Create pull request if tests passed
|
|
209
|
-
if (testingResult.status === 'success') {
|
|
210
|
-
if (verbose) {
|
|
211
|
-
console.log('🔄 Creating pull request for successful feature...');
|
|
212
|
-
}
|
|
213
|
-
// Get feature details for PR creation
|
|
214
|
-
const getFeature = getFeatureDetails(featureId, {
|
|
215
|
-
mcpServerUrl,
|
|
216
|
-
mcpToken,
|
|
217
|
-
verbose,
|
|
218
|
-
});
|
|
219
|
-
const feature = await getFeature();
|
|
220
|
-
if (feature) {
|
|
221
|
-
// Get GitHub configuration from environment
|
|
222
|
-
const githubToken = process.env.GITHUB_TOKEN || process.env.GITHUB_ACCESS_TOKEN;
|
|
223
|
-
const githubOwner = process.env.GITHUB_OWNER;
|
|
224
|
-
const githubRepo = process.env.GITHUB_REPO;
|
|
225
|
-
if (githubToken && githubOwner && githubRepo) {
|
|
226
|
-
const prResult = await createPullRequest({
|
|
227
|
-
githubToken,
|
|
228
|
-
owner: githubOwner,
|
|
229
|
-
repo: githubRepo,
|
|
230
|
-
baseBranch: 'main',
|
|
231
|
-
verbose,
|
|
232
|
-
}, {
|
|
233
|
-
id: feature.id,
|
|
234
|
-
name: feature.name,
|
|
235
|
-
description: feature.description,
|
|
236
|
-
productId: feature.product_id,
|
|
237
|
-
// Get technical design and test result from previous stages
|
|
238
|
-
technicalDesign: results.find((r) => r.stage === 'technical-design')?.data?.technicalDesign,
|
|
239
|
-
testResult: testingResult.data?.testResult,
|
|
240
|
-
testReportUrl: testingResult.data?.testReport
|
|
241
|
-
?.testReportUrl,
|
|
242
|
-
});
|
|
243
|
-
if (prResult.success && prResult.pullRequestUrl) {
|
|
244
|
-
// Update feature with PR URL and status
|
|
245
|
-
await updateFeatureWithPullRequest(mcpServerUrl, mcpToken, featureId, prResult.pullRequestUrl, verbose);
|
|
246
|
-
if (verbose) {
|
|
247
|
-
console.log(`✅ Pull request created and feature updated to ready_for_review`);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
else {
|
|
251
|
-
if (verbose) {
|
|
252
|
-
console.log(`⚠️ Pull request creation failed: ${prResult.error}`);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
if (verbose) {
|
|
258
|
-
console.log('⚠️ GitHub configuration not found. Skipping pull request creation.');
|
|
259
|
-
console.log(' Set GITHUB_TOKEN, GITHUB_OWNER, and GITHUB_REPO environment variables.');
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
if (verbose) {
|
|
265
|
-
console.log('⚠️ Could not fetch feature details for pull request creation');
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
202
|
+
const runFromCodeImplementation = async (options, config) => {
|
|
203
|
+
const { featureId, mcpServerUrl, mcpToken, verbose } = options;
|
|
204
|
+
logPipelineStart(featureId, verbose);
|
|
205
|
+
const results = [];
|
|
206
|
+
// 1. Code Implementation
|
|
207
|
+
const implementationResult = await runCodeImplementationPhase(options, config);
|
|
208
|
+
results.push(logPhaseResult(implementationResult, verbose));
|
|
209
|
+
if (!shouldContinuePipeline(results)) {
|
|
269
210
|
return logPipelineComplete(results, verbose);
|
|
270
|
-
}
|
|
211
|
+
}
|
|
212
|
+
// 2. Functional Testing with retry loop for bug fixes
|
|
213
|
+
const testingResult = await handleTestFailuresWithRetry({
|
|
214
|
+
options,
|
|
215
|
+
config,
|
|
216
|
+
results,
|
|
217
|
+
verbose,
|
|
218
|
+
});
|
|
219
|
+
// Update final status based on functional testing result
|
|
220
|
+
const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
|
|
221
|
+
await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
|
|
222
|
+
// Create pull request if tests passed
|
|
223
|
+
if (testingResult.status === 'success') {
|
|
224
|
+
await handlePullRequestCreation({
|
|
225
|
+
featureId,
|
|
226
|
+
mcpServerUrl,
|
|
227
|
+
mcpToken,
|
|
228
|
+
results,
|
|
229
|
+
testingResult,
|
|
230
|
+
verbose,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return logPipelineComplete(results, verbose);
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Run from functional testing to end
|
|
237
|
+
*/
|
|
238
|
+
const runFromFunctionalTesting = async (options, config) => {
|
|
239
|
+
const { featureId, mcpServerUrl, mcpToken, verbose } = options;
|
|
240
|
+
logPipelineStart(featureId, verbose);
|
|
241
|
+
const results = [];
|
|
242
|
+
// 1. Functional Testing with retry loop for bug fixes
|
|
243
|
+
const testingResult = await handleTestFailuresWithRetry({
|
|
244
|
+
options,
|
|
245
|
+
config,
|
|
246
|
+
results,
|
|
247
|
+
verbose,
|
|
248
|
+
});
|
|
249
|
+
// Update final status based on functional testing result
|
|
250
|
+
const finalStatus = testingResult.status === 'success' ? 'testing_passed' : 'testing_failed';
|
|
251
|
+
await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, finalStatus === 'testing_passed' ? 'testing-passed' : 'testing-failed', verbose);
|
|
252
|
+
// Create pull request if tests passed
|
|
253
|
+
if (testingResult.status === 'success') {
|
|
254
|
+
await handlePullRequestCreation({
|
|
255
|
+
featureId,
|
|
256
|
+
mcpServerUrl,
|
|
257
|
+
mcpToken,
|
|
258
|
+
results,
|
|
259
|
+
testingResult,
|
|
260
|
+
verbose,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return logPipelineComplete(results, verbose);
|
|
271
264
|
};
|
|
272
|
-
// Export individual stage runners for granular control
|
|
273
|
-
export { runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage, };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline execution logic for feature development workflow
|
|
3
|
+
*/
|
|
4
|
+
import { EdsgerConfig } from '../types.js';
|
|
5
|
+
import { PipelineStageOptions, PipelineResult } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Run the complete pipeline for a feature
|
|
8
|
+
*/
|
|
9
|
+
export declare function runCompletePipeline(options: PipelineStageOptions, config: EdsgerConfig, githubConfig?: {
|
|
10
|
+
githubToken: string;
|
|
11
|
+
githubOwner: string;
|
|
12
|
+
githubRepo: string;
|
|
13
|
+
githubBaseBranch?: string;
|
|
14
|
+
}): Promise<PipelineResult[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Log pipeline results summary
|
|
17
|
+
*/
|
|
18
|
+
export declare function logPipelineResults(results: readonly PipelineResult[]): void;
|