edsger 0.2.0 → 0.2.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/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 +174 -15
- 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 +29 -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.d.ts +26 -0
- package/dist/{functional-testing → phases/functional-testing}/test-report-creator.js +87 -5
- 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 +418 -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 +29 -0
- package/dist/prompts/formatters.js +139 -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/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 +2 -2
- 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/{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,10 +1,10 @@
|
|
|
1
|
-
import { logInfo, logError } from '
|
|
1
|
+
import { logInfo, logError } from '../../utils/logger.js';
|
|
2
2
|
/**
|
|
3
3
|
* Create a test report via MCP endpoint
|
|
4
4
|
* Uses structured data generated by Claude Code
|
|
5
5
|
*/
|
|
6
6
|
export async function createTestReport(options) {
|
|
7
|
-
const { mcpServerUrl, mcpToken, featureId, testReportData, verbose } = options;
|
|
7
|
+
const { mcpServerUrl, mcpToken, featureId, testReportData, testResults, verbose, } = options;
|
|
8
8
|
if (verbose) {
|
|
9
9
|
logInfo(`Creating test report for feature: ${featureId}`);
|
|
10
10
|
}
|
|
@@ -53,6 +53,19 @@ export async function createTestReport(options) {
|
|
|
53
53
|
if (verbose) {
|
|
54
54
|
logInfo(`✅ Test report created via MCP: ${testReport.id}`);
|
|
55
55
|
}
|
|
56
|
+
// Create test report results if provided
|
|
57
|
+
if (testResults && testResults.length > 0) {
|
|
58
|
+
const resultsResponse = await createTestReportResults({
|
|
59
|
+
mcpServerUrl,
|
|
60
|
+
mcpToken,
|
|
61
|
+
testReportId: testReport.id,
|
|
62
|
+
testResults,
|
|
63
|
+
verbose,
|
|
64
|
+
});
|
|
65
|
+
if (verbose && resultsResponse.success) {
|
|
66
|
+
logInfo(`✅ Created ${resultsResponse.resultsCreated} test report results`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
56
69
|
return {
|
|
57
70
|
success: true,
|
|
58
71
|
testReport,
|
|
@@ -65,7 +78,7 @@ export async function createTestReport(options) {
|
|
|
65
78
|
logInfo('Claude Code MCP call may have failed, manually calling MCP endpoint...');
|
|
66
79
|
}
|
|
67
80
|
// Manual fallback: Call MCP endpoint with the structured data
|
|
68
|
-
const fallbackResult = await manualMcpTestReportCreation(mcpServerUrl, mcpToken, featureId, structuredReport, verbose);
|
|
81
|
+
const fallbackResult = await manualMcpTestReportCreation(mcpServerUrl, mcpToken, featureId, structuredReport, testResults, verbose);
|
|
69
82
|
return fallbackResult;
|
|
70
83
|
}
|
|
71
84
|
catch (error) {
|
|
@@ -74,14 +87,70 @@ export async function createTestReport(options) {
|
|
|
74
87
|
logError(`Test report creation failed: ${errorMessage}`);
|
|
75
88
|
}
|
|
76
89
|
// Manual fallback on any error
|
|
77
|
-
return manualMcpTestReportCreation(mcpServerUrl, mcpToken, featureId, structuredReport, verbose);
|
|
90
|
+
return manualMcpTestReportCreation(mcpServerUrl, mcpToken, featureId, structuredReport, testResults, verbose);
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
/**
|
|
81
94
|
* Manual fallback: Call MCP endpoint with structured data
|
|
82
95
|
* This is used when Claude Code fails to call MCP directly
|
|
83
96
|
*/
|
|
84
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Create test report results via MCP endpoint
|
|
99
|
+
*/
|
|
100
|
+
export async function createTestReportResults(options) {
|
|
101
|
+
const { mcpServerUrl, mcpToken, testReportId, testResults, verbose } = options;
|
|
102
|
+
if (verbose) {
|
|
103
|
+
logInfo(`Creating ${testResults.length} test report results for report: ${testReportId}`);
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const response = await fetch(`${mcpServerUrl}/mcp`, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
Authorization: `Bearer ${mcpToken}`,
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
jsonrpc: '2.0',
|
|
114
|
+
method: 'test_report_results/create',
|
|
115
|
+
params: {
|
|
116
|
+
test_report_id: testReportId,
|
|
117
|
+
test_results: testResults,
|
|
118
|
+
},
|
|
119
|
+
id: Math.random().toString(36).substring(7),
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
const data = await response.json();
|
|
123
|
+
if (response.ok && !data.error && data.result) {
|
|
124
|
+
const resultData = data.result;
|
|
125
|
+
if (verbose) {
|
|
126
|
+
logInfo(`✅ Created ${resultData.results_created} test report results`);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
resultsCreated: resultData.results_created,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const errorMessage = data.error?.message || 'Failed to create test report results';
|
|
134
|
+
if (verbose) {
|
|
135
|
+
logError(`Test report results creation failed: ${errorMessage}`);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
success: false,
|
|
139
|
+
error: errorMessage,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
144
|
+
if (verbose) {
|
|
145
|
+
logError(`Test report results creation failed: ${errorMessage}`);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
error: errorMessage,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function manualMcpTestReportCreation(mcpServerUrl, mcpToken, featureId, structuredReport, testResults, verbose) {
|
|
85
154
|
if (verbose) {
|
|
86
155
|
logInfo('Manually calling MCP test_reports/create endpoint with structured data');
|
|
87
156
|
}
|
|
@@ -114,6 +183,19 @@ async function manualMcpTestReportCreation(mcpServerUrl, mcpToken, featureId, st
|
|
|
114
183
|
if (verbose) {
|
|
115
184
|
logInfo(`✅ Test report created manually via MCP: ${testReport.id}`);
|
|
116
185
|
}
|
|
186
|
+
// Create test report results if provided
|
|
187
|
+
if (testResults && testResults.length > 0) {
|
|
188
|
+
const resultsResponse = await createTestReportResults({
|
|
189
|
+
mcpServerUrl,
|
|
190
|
+
mcpToken,
|
|
191
|
+
testReportId: testReport.id,
|
|
192
|
+
testResults,
|
|
193
|
+
verbose,
|
|
194
|
+
});
|
|
195
|
+
if (verbose && resultsResponse.success) {
|
|
196
|
+
logInfo(`✅ Created ${resultsResponse.resultsCreated} test report results`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
117
199
|
return {
|
|
118
200
|
success: true,
|
|
119
201
|
testReport,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test retry and bug fixing handler for pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
import { EdsgerConfig } from '../../types/index.js';
|
|
5
|
+
import { PipelinePhaseOptions, PipelineResult } from '../../types/pipeline.js';
|
|
6
|
+
export declare const MAX_FIX_ATTEMPTS = 3;
|
|
7
|
+
export interface TestRetryOptions {
|
|
8
|
+
options: PipelinePhaseOptions;
|
|
9
|
+
config: EdsgerConfig;
|
|
10
|
+
results: PipelineResult[];
|
|
11
|
+
verbose?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Handle test failures with automatic bug fixing and retry
|
|
15
|
+
*/
|
|
16
|
+
export declare function handleTestFailuresWithRetry({ options, config, results, verbose, }: TestRetryOptions): Promise<PipelineResult>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test retry and bug fixing handler for pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
import { fixTestFailures, checkBugFixingRequirements, } from '../bug-fixing/analyzer.js';
|
|
5
|
+
import { runFunctionalTestingPhase } from '../../workflow-runner/executors/phase-executor.js';
|
|
6
|
+
import { updateFeatureStatusForPhase } from '../../api/features/index.js';
|
|
7
|
+
import { logPhaseResult } from '../../utils/pipeline-logger.js';
|
|
8
|
+
export const MAX_FIX_ATTEMPTS = 3;
|
|
9
|
+
/**
|
|
10
|
+
* Handle test failures with automatic bug fixing and retry
|
|
11
|
+
*/
|
|
12
|
+
export async function handleTestFailuresWithRetry({ options, config, results, verbose, }) {
|
|
13
|
+
let testingResult;
|
|
14
|
+
let fixAttempt = 0;
|
|
15
|
+
do {
|
|
16
|
+
// Run functional testing
|
|
17
|
+
testingResult = await runFunctionalTestingPhase(options, config);
|
|
18
|
+
results.push(logPhaseResult(testingResult, verbose));
|
|
19
|
+
// If tests failed and we haven't exceeded max attempts, try to fix
|
|
20
|
+
if (testingResult.status === 'error' && fixAttempt < MAX_FIX_ATTEMPTS) {
|
|
21
|
+
fixAttempt++;
|
|
22
|
+
if (verbose) {
|
|
23
|
+
console.log(`🔧 Tests failed. Attempting to fix bugs (Attempt ${fixAttempt}/${MAX_FIX_ATTEMPTS})...`);
|
|
24
|
+
}
|
|
25
|
+
// Check if bug fixing requirements are met
|
|
26
|
+
const hasBugFixingReqs = await checkBugFixingRequirements();
|
|
27
|
+
if (!hasBugFixingReqs) {
|
|
28
|
+
if (verbose) {
|
|
29
|
+
console.log('⚠️ Bug fixing requirements not met. Skipping automatic fixes.');
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
// Extract test errors from the testing result
|
|
34
|
+
const testErrors = testingResult.data?.testResult || testingResult.message;
|
|
35
|
+
// Run bug fixing
|
|
36
|
+
const fixResult = await fixTestFailures({
|
|
37
|
+
featureId: options.featureId,
|
|
38
|
+
mcpServerUrl: options.mcpServerUrl,
|
|
39
|
+
mcpToken: options.mcpToken,
|
|
40
|
+
testErrors,
|
|
41
|
+
attemptNumber: fixAttempt,
|
|
42
|
+
verbose,
|
|
43
|
+
}, config);
|
|
44
|
+
if (fixResult.status === 'success') {
|
|
45
|
+
if (verbose) {
|
|
46
|
+
console.log(`✅ Bug fixes applied. Re-running tests...`);
|
|
47
|
+
if (fixResult.filesFixed && fixResult.filesFixed.length > 0) {
|
|
48
|
+
console.log(` Files fixed: ${fixResult.filesFixed.join(', ')}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Remove the previous failed test result from results
|
|
52
|
+
results.pop();
|
|
53
|
+
// Update status to indicate we're retrying tests
|
|
54
|
+
await updateFeatureStatusForPhase({ mcpServerUrl: options.mcpServerUrl, mcpToken: options.mcpToken }, options.featureId, 'functional-testing', verbose);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
if (verbose) {
|
|
58
|
+
console.log(`❌ Bug fixing failed: ${fixResult.message}`);
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Tests passed or max attempts reached
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
} while (fixAttempt <= MAX_FIX_ATTEMPTS);
|
|
68
|
+
// Log if max attempts reached
|
|
69
|
+
if (testingResult.status === 'error' &&
|
|
70
|
+
fixAttempt >= MAX_FIX_ATTEMPTS &&
|
|
71
|
+
verbose) {
|
|
72
|
+
console.log(`⚠️ Maximum fix attempts (${MAX_FIX_ATTEMPTS}) reached. Tests still failing.`);
|
|
73
|
+
}
|
|
74
|
+
return testingResult;
|
|
75
|
+
}
|
|
@@ -91,7 +91,7 @@ export async function createPullRequest(config, feature) {
|
|
|
91
91
|
const octokit = new Octokit({
|
|
92
92
|
auth: githubToken,
|
|
93
93
|
});
|
|
94
|
-
// Get current branch
|
|
94
|
+
// Get current branch (should be dev/feature-id)
|
|
95
95
|
const currentBranch = getCurrentBranch();
|
|
96
96
|
if (verbose) {
|
|
97
97
|
console.log(`🔍 Current branch: ${currentBranch}`);
|
|
@@ -103,22 +103,63 @@ export async function createPullRequest(config, feature) {
|
|
|
103
103
|
error: `Cannot create PR: already on ${baseBranch} branch`,
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
-
//
|
|
107
|
-
|
|
106
|
+
// Extract feature ID from current branch (dev/feature-id)
|
|
107
|
+
let targetBranch = baseBranch;
|
|
108
|
+
if (currentBranch.startsWith('dev/')) {
|
|
109
|
+
const featureId = currentBranch.replace('dev/', '');
|
|
110
|
+
targetBranch = `feat/${featureId}`;
|
|
111
|
+
// Create the feat/ branch from current dev/ branch
|
|
112
|
+
if (verbose) {
|
|
113
|
+
console.log(`📝 Creating target branch: ${targetBranch} from ${currentBranch}`);
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
// Push current branch to remote first
|
|
117
|
+
pushBranch(currentBranch, verbose);
|
|
118
|
+
// Get the current branch SHA
|
|
119
|
+
const { data: branchData } = await octokit.repos.getBranch({
|
|
120
|
+
owner,
|
|
121
|
+
repo,
|
|
122
|
+
branch: currentBranch,
|
|
123
|
+
});
|
|
124
|
+
// Create the feat/ branch
|
|
125
|
+
await octokit.git.createRef({
|
|
126
|
+
owner,
|
|
127
|
+
repo,
|
|
128
|
+
ref: `refs/heads/${targetBranch}`,
|
|
129
|
+
sha: branchData.commit.sha,
|
|
130
|
+
});
|
|
131
|
+
if (verbose) {
|
|
132
|
+
console.log(`✅ Created target branch: ${targetBranch}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
// If branch already exists, that's fine
|
|
137
|
+
if (!error.message?.includes('Reference already exists')) {
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
if (verbose) {
|
|
141
|
+
console.log(`ℹ️ Target branch ${targetBranch} already exists`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// If not a dev/ branch, push it normally
|
|
147
|
+
pushBranch(currentBranch, verbose);
|
|
148
|
+
}
|
|
108
149
|
// Generate PR title and body
|
|
109
150
|
const title = generatePRTitle(feature.name);
|
|
110
151
|
const body = generatePRBody(feature);
|
|
111
152
|
if (verbose) {
|
|
112
|
-
console.log(`📝 Creating pull request: ${title}`);
|
|
153
|
+
console.log(`📝 Creating pull request: ${title} from ${currentBranch} to ${targetBranch}`);
|
|
113
154
|
}
|
|
114
|
-
// Create the pull request
|
|
155
|
+
// Create the pull request from dev/ to feat/
|
|
115
156
|
const { data: pullRequest } = await octokit.pulls.create({
|
|
116
157
|
owner,
|
|
117
158
|
repo,
|
|
118
159
|
title,
|
|
119
160
|
body,
|
|
120
161
|
head: currentBranch,
|
|
121
|
-
base:
|
|
162
|
+
base: targetBranch,
|
|
122
163
|
draft: false,
|
|
123
164
|
});
|
|
124
165
|
if (verbose) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull request creation handler for pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
import { PipelineResult } from '../../types/pipeline.js';
|
|
5
|
+
export interface PullRequestHandlerOptions {
|
|
6
|
+
featureId: string;
|
|
7
|
+
mcpServerUrl: string;
|
|
8
|
+
mcpToken: string;
|
|
9
|
+
results: readonly PipelineResult[];
|
|
10
|
+
testingResult: PipelineResult;
|
|
11
|
+
verbose?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create pull request for successful feature implementation
|
|
15
|
+
*/
|
|
16
|
+
export declare function handlePullRequestCreation({ featureId, mcpServerUrl, mcpToken, results, testingResult, verbose, }: PullRequestHandlerOptions): Promise<void>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull request creation handler for pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
import { getFeature } from '../../api/features/index.js';
|
|
5
|
+
import { createPullRequest, updateFeatureWithPullRequest } from './creator.js';
|
|
6
|
+
/**
|
|
7
|
+
* Create pull request for successful feature implementation
|
|
8
|
+
*/
|
|
9
|
+
export async function handlePullRequestCreation({ featureId, mcpServerUrl, mcpToken, results, testingResult, verbose, }) {
|
|
10
|
+
if (verbose) {
|
|
11
|
+
console.log('🔄 Creating pull request for successful feature...');
|
|
12
|
+
}
|
|
13
|
+
// Get feature details for PR creation
|
|
14
|
+
const feature = await getFeature(mcpServerUrl, mcpToken, featureId, verbose);
|
|
15
|
+
if (!feature) {
|
|
16
|
+
if (verbose) {
|
|
17
|
+
console.log('⚠️ Could not fetch feature details for pull request creation');
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Get GitHub configuration from environment
|
|
22
|
+
const githubToken = process.env.GITHUB_TOKEN || process.env.GITHUB_ACCESS_TOKEN;
|
|
23
|
+
const githubOwner = process.env.GITHUB_OWNER;
|
|
24
|
+
const githubRepo = process.env.GITHUB_REPO;
|
|
25
|
+
if (!githubToken || !githubOwner || !githubRepo) {
|
|
26
|
+
if (verbose) {
|
|
27
|
+
console.log('⚠️ GitHub configuration not found. Skipping pull request creation.');
|
|
28
|
+
console.log(' Set GITHUB_TOKEN, GITHUB_OWNER, and GITHUB_REPO environment variables.');
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const prResult = await createPullRequest({
|
|
33
|
+
githubToken,
|
|
34
|
+
owner: githubOwner,
|
|
35
|
+
repo: githubRepo,
|
|
36
|
+
baseBranch: 'main',
|
|
37
|
+
verbose,
|
|
38
|
+
}, {
|
|
39
|
+
id: feature.id,
|
|
40
|
+
name: feature.name,
|
|
41
|
+
description: feature.description || '',
|
|
42
|
+
productId: feature.product_id,
|
|
43
|
+
// Get technical design and test result from previous phases
|
|
44
|
+
technicalDesign: results.find((r) => r.phase === 'technical-design')?.data?.technicalDesign,
|
|
45
|
+
testResult: testingResult.data?.testResult,
|
|
46
|
+
testReportUrl: testingResult.data?.testReport?.testReportUrl,
|
|
47
|
+
});
|
|
48
|
+
if (prResult.success && prResult.pullRequestUrl) {
|
|
49
|
+
// Update feature with PR URL and status
|
|
50
|
+
await updateFeatureWithPullRequest(mcpServerUrl, mcpToken, featureId, prResult.pullRequestUrl, verbose);
|
|
51
|
+
if (verbose) {
|
|
52
|
+
console.log(`✅ Pull request created and feature updated to ready_for_review`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (verbose) {
|
|
57
|
+
console.log(`⚠️ Pull request creation failed: ${prResult.error}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { EdsgerConfig } from '
|
|
1
|
+
import { EdsgerConfig } from '../../types/index.js';
|
|
2
|
+
import { ChecklistPhaseContext } from '../../services/checklist.js';
|
|
2
3
|
export interface TechnicalDesignOptions {
|
|
3
4
|
featureId: string;
|
|
4
5
|
mcpServerUrl: string;
|
|
@@ -11,6 +12,10 @@ export interface TechnicalDesignResult {
|
|
|
11
12
|
status: 'success' | 'error';
|
|
12
13
|
summary: string;
|
|
13
14
|
savedViaHttp?: boolean;
|
|
15
|
+
data?: {
|
|
16
|
+
checklist_item_results?: any[];
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
14
19
|
}
|
|
15
|
-
export declare const generateTechnicalDesign: (options: TechnicalDesignOptions, config: EdsgerConfig) => Promise<TechnicalDesignResult>;
|
|
20
|
+
export declare const generateTechnicalDesign: (options: TechnicalDesignOptions, config: EdsgerConfig, checklistContext?: ChecklistPhaseContext | null) => Promise<TechnicalDesignResult>;
|
|
16
21
|
export declare const checkTechnicalDesignRequirements: () => Promise<boolean>;
|