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,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase execution logic for pipeline runner
|
|
3
|
+
*/
|
|
4
|
+
import { updateFeatureStatusForPhase } from '../../api/features/index.js';
|
|
5
|
+
import { phaseConfigs } from '../config/phase-configs.js';
|
|
6
|
+
import { getChecklistsForPhase, validateChecklistsForPhase, validateRequiredChecklistResults, processChecklistResultsFromResponse, processChecklistItemResultsFromResponse, } from '../../services/checklist.js';
|
|
7
|
+
import { logFeaturePhaseEvent } from '../../services/audit-logs.js';
|
|
8
|
+
// Higher-order function for phase execution
|
|
9
|
+
export const createPhaseRunner = (phaseConfig) => async (options, config) => {
|
|
10
|
+
const { featureId, mcpServerUrl, mcpToken, verbose } = options;
|
|
11
|
+
const { name, checkRequirements, execute, requirementsError } = phaseConfig;
|
|
12
|
+
// Track phase duration for logging
|
|
13
|
+
const phaseStartTime = Date.now();
|
|
14
|
+
try {
|
|
15
|
+
// Check requirements
|
|
16
|
+
const hasRequirements = await checkRequirements();
|
|
17
|
+
if (!hasRequirements) {
|
|
18
|
+
return {
|
|
19
|
+
featureId,
|
|
20
|
+
phase: name,
|
|
21
|
+
status: 'error',
|
|
22
|
+
message: requirementsError,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
// Update feature status to reflect current phase
|
|
26
|
+
await updateFeatureStatusForPhase({ mcpServerUrl, mcpToken }, featureId, name, verbose);
|
|
27
|
+
if (verbose) {
|
|
28
|
+
console.log(`🎯 Starting ${name} for: ${featureId}`);
|
|
29
|
+
}
|
|
30
|
+
// Log phase start
|
|
31
|
+
await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
|
|
32
|
+
featureId,
|
|
33
|
+
eventType: 'phase_started',
|
|
34
|
+
phase: name.replace(/-/g, '_'),
|
|
35
|
+
result: 'info',
|
|
36
|
+
metadata: {
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
},
|
|
39
|
+
}, verbose);
|
|
40
|
+
// Fetch checklists for this phase as context
|
|
41
|
+
let checklistContext = null;
|
|
42
|
+
try {
|
|
43
|
+
checklistContext = await getChecklistsForPhase(options, name);
|
|
44
|
+
if (verbose && checklistContext.checklists.length > 0) {
|
|
45
|
+
console.log(`📋 Found ${checklistContext.checklists.length} checklists for ${name} phase`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (checklistError) {
|
|
49
|
+
// Always log checklist fetch errors, not just in verbose mode
|
|
50
|
+
console.log(`⚠️ Failed to fetch checklists for ${name} phase: ${checklistError instanceof Error ? checklistError.message : String(checklistError)}`);
|
|
51
|
+
// Log more details in verbose mode
|
|
52
|
+
if (verbose && checklistError instanceof Error) {
|
|
53
|
+
console.log(` Details: ${checklistError.stack}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Execute the phase with checklist context
|
|
57
|
+
const result = await execute(options, config, checklistContext);
|
|
58
|
+
// Process checklist results from phase response if phase was successful
|
|
59
|
+
if (result.status === 'success') {
|
|
60
|
+
try {
|
|
61
|
+
// Extract checklist_item_results from result data if available (new format)
|
|
62
|
+
const checklistItemResults = result.data?.checklist_item_results;
|
|
63
|
+
if (checklistItemResults && Array.isArray(checklistItemResults)) {
|
|
64
|
+
const processResult = await processChecklistItemResultsFromResponse(options, name, checklistItemResults, verbose);
|
|
65
|
+
if (verbose) {
|
|
66
|
+
if (processResult.created > 0) {
|
|
67
|
+
console.log(`📋 Processed ${processResult.created} checklist item results from ${name} phase`);
|
|
68
|
+
}
|
|
69
|
+
if (processResult.errors.length > 0) {
|
|
70
|
+
console.log(`⚠️ ${processResult.errors.length} errors processing checklist item results`);
|
|
71
|
+
processResult.errors.forEach((error) => console.log(` - ${error}`));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Fallback to old format for backward compatibility
|
|
77
|
+
const checklistResults = result.data?.checklist_results;
|
|
78
|
+
if (checklistResults && Array.isArray(checklistResults)) {
|
|
79
|
+
const processResult = await processChecklistResultsFromResponse(options, checklistResults, verbose);
|
|
80
|
+
if (verbose) {
|
|
81
|
+
if (processResult.created > 0) {
|
|
82
|
+
console.log(`📋 Processed ${processResult.created} checklist results from ${name} phase (legacy format)`);
|
|
83
|
+
}
|
|
84
|
+
if (processResult.errors.length > 0) {
|
|
85
|
+
console.log(`⚠️ ${processResult.errors.length} errors processing checklist results`);
|
|
86
|
+
processResult.errors.forEach((error) => console.log(` - ${error}`));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (processError) {
|
|
93
|
+
if (verbose) {
|
|
94
|
+
console.log(`⚠️ Failed to process checklist results from ${name} phase: ${processError instanceof Error ? processError.message : String(processError)}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Strictly validate checklist results after phase execution
|
|
99
|
+
let checklistValidation = null;
|
|
100
|
+
if (result.status === 'success') {
|
|
101
|
+
try {
|
|
102
|
+
// First perform strict validation - this will fail if checklists exist but have no results
|
|
103
|
+
const strictValidation = await validateRequiredChecklistResults(options, name, verbose);
|
|
104
|
+
if (!strictValidation.success) {
|
|
105
|
+
// If validation fails, return error immediately - don't continue pipeline
|
|
106
|
+
return {
|
|
107
|
+
featureId,
|
|
108
|
+
phase: name,
|
|
109
|
+
status: 'error',
|
|
110
|
+
message: `Checklist validation failed: ${strictValidation.error}`,
|
|
111
|
+
data: {
|
|
112
|
+
...result,
|
|
113
|
+
checklist_context: checklistContext,
|
|
114
|
+
checklist_validation_error: strictValidation.error,
|
|
115
|
+
missing_checklists: strictValidation.missingChecklists,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// If strict validation passes, get detailed validation info for logging
|
|
120
|
+
checklistValidation = await validateChecklistsForPhase(options, name);
|
|
121
|
+
if (verbose) {
|
|
122
|
+
console.log(`📋 Checklist validation: ${checklistValidation.summary}`);
|
|
123
|
+
}
|
|
124
|
+
// Log completion status
|
|
125
|
+
if (checklistValidation.checklists_validation.length > 0) {
|
|
126
|
+
const completedCount = checklistValidation.checklists_validation.filter((v) => v.is_completed).length;
|
|
127
|
+
const totalCount = checklistValidation.checklists_validation.length;
|
|
128
|
+
if (verbose) {
|
|
129
|
+
console.log(`📋 Checklist results status: ${completedCount}/${totalCount} checklists have results`);
|
|
130
|
+
}
|
|
131
|
+
// Log any incomplete checklists
|
|
132
|
+
if (!checklistValidation.all_completed) {
|
|
133
|
+
checklistValidation.checklists_validation.forEach((validation) => {
|
|
134
|
+
if (!validation.is_completed) {
|
|
135
|
+
console.log(` - ${validation.checklist_name} (${validation.role}): ${validation.status}`);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (validationError) {
|
|
142
|
+
// If validation itself fails, treat as error and stop pipeline
|
|
143
|
+
return {
|
|
144
|
+
featureId,
|
|
145
|
+
phase: name,
|
|
146
|
+
status: 'error',
|
|
147
|
+
message: `Checklist validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}`,
|
|
148
|
+
data: {
|
|
149
|
+
...result,
|
|
150
|
+
checklist_context: checklistContext,
|
|
151
|
+
checklist_validation_error: validationError instanceof Error
|
|
152
|
+
? validationError.message
|
|
153
|
+
: String(validationError),
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Log phase completion
|
|
159
|
+
const phaseEndTime = Date.now();
|
|
160
|
+
const phaseDuration = phaseEndTime - phaseStartTime;
|
|
161
|
+
if (result.status === 'success') {
|
|
162
|
+
await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
|
|
163
|
+
featureId,
|
|
164
|
+
eventType: 'phase_completed',
|
|
165
|
+
phase: name.replace(/-/g, '_'),
|
|
166
|
+
result: 'success',
|
|
167
|
+
metadata: {
|
|
168
|
+
duration_ms: phaseDuration,
|
|
169
|
+
iterations: result.data?.iterations,
|
|
170
|
+
artifacts: result.data,
|
|
171
|
+
checklist_validation: checklistValidation,
|
|
172
|
+
},
|
|
173
|
+
}, verbose);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
// Extract additional failure details from result data
|
|
177
|
+
const failureMetadata = {
|
|
178
|
+
duration_ms: phaseDuration,
|
|
179
|
+
};
|
|
180
|
+
// For verification phases, include suggestions and details
|
|
181
|
+
if (name.includes('verification') &&
|
|
182
|
+
result.data &&
|
|
183
|
+
typeof result.data === 'object') {
|
|
184
|
+
const data = result.data;
|
|
185
|
+
if (data.suggestions) {
|
|
186
|
+
failureMetadata.suggestions = data.suggestions;
|
|
187
|
+
}
|
|
188
|
+
if (data.unresolvedCommentDetails ||
|
|
189
|
+
data.unresolved_comment_details) {
|
|
190
|
+
failureMetadata.unresolved_comment_details =
|
|
191
|
+
data.unresolvedCommentDetails || data.unresolved_comment_details;
|
|
192
|
+
}
|
|
193
|
+
if (data.unresolvedComments !== undefined ||
|
|
194
|
+
data.unresolved_comments !== undefined) {
|
|
195
|
+
failureMetadata.unresolved_comments =
|
|
196
|
+
data.unresolvedComments ?? data.unresolved_comments;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
|
|
200
|
+
featureId,
|
|
201
|
+
eventType: 'phase_failed',
|
|
202
|
+
phase: name.replace(/-/g, '_'),
|
|
203
|
+
result: 'error',
|
|
204
|
+
metadata: failureMetadata,
|
|
205
|
+
errorMessage: result.summary || result.message || 'Phase execution failed',
|
|
206
|
+
}, verbose);
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
featureId,
|
|
210
|
+
phase: name,
|
|
211
|
+
status: result.status === 'success' ? 'success' : 'error',
|
|
212
|
+
message: result.status === 'success'
|
|
213
|
+
? `${name.replace('-', ' ')} completed successfully`
|
|
214
|
+
: `${name.replace('-', ' ')} failed`,
|
|
215
|
+
data: {
|
|
216
|
+
...result,
|
|
217
|
+
checklist_context: checklistContext,
|
|
218
|
+
checklist_validation: checklistValidation,
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
// Log phase failure for exceptions
|
|
224
|
+
const phaseEndTime = Date.now();
|
|
225
|
+
const phaseDuration = phaseEndTime - phaseStartTime;
|
|
226
|
+
await logFeaturePhaseEvent(mcpServerUrl, mcpToken, {
|
|
227
|
+
featureId,
|
|
228
|
+
eventType: 'phase_failed',
|
|
229
|
+
phase: name.replace(/-/g, '_'),
|
|
230
|
+
result: 'error',
|
|
231
|
+
metadata: {
|
|
232
|
+
duration_ms: phaseDuration,
|
|
233
|
+
error_type: 'exception',
|
|
234
|
+
},
|
|
235
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
236
|
+
}, verbose);
|
|
237
|
+
return {
|
|
238
|
+
featureId,
|
|
239
|
+
phase: name,
|
|
240
|
+
status: 'error',
|
|
241
|
+
message: `${name.replace('-', ' ')} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
// Create phase runners using the configuration
|
|
246
|
+
const [runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, runCodeTestingPhase, runCodeRefinePhase, runCodeRefineVerificationPhase, runCodeReviewPhase,] = phaseConfigs.map(createPhaseRunner);
|
|
247
|
+
// Export individual phase runners for granular control
|
|
248
|
+
export { runFeatureAnalysisPhase, runTechnicalDesignPhase, runCodeImplementationPhase, runFunctionalTestingPhase, runCodeTestingPhase, runCodeRefinePhase, runCodeRefineVerificationPhase, runCodeReviewPhase, };
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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 { EdsgerConfig } from '../types/index.js';
|
|
9
|
+
import { PipelinePhaseOptions, PipelineResult, ExecutionMode } from '../types/pipeline.js';
|
|
10
|
+
/**
|
|
11
|
+
* Run pipeline based on execution mode
|
|
12
|
+
*/
|
|
13
|
+
export declare const runPipelineByMode: (options: PipelinePhaseOptions, config: EdsgerConfig, executionMode: ExecutionMode) => Promise<readonly PipelineResult[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Run complete pipeline for a feature using functional composition (legacy)
|
|
16
|
+
*/
|
|
17
|
+
export declare const runCompletePipeline: (options: PipelinePhaseOptions, config: EdsgerConfig) => () => Promise<readonly PipelineResult[]>;
|