edsger 0.41.1 → 0.41.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/executors/phase-executor.js +1 -3
- package/dist/commands/workflow/phase-orchestrator.js +1 -3
- 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 +2 -2
- package/dist/phases/app-store-generation/index.js +1 -3
- package/dist/phases/branch-planning/index.js +1 -3
- package/dist/phases/bug-fixing/analyzer.js +1 -3
- 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/index.js +1 -3
- 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/index.js +1 -3
- 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/code-review/index.js +1 -3
- package/dist/phases/code-testing/analyzer.js +1 -3
- 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/index.js +1 -3
- 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/functional-testing/analyzer.js +1 -3
- package/dist/phases/growth-analysis/index.js +1 -3
- package/dist/phases/pr-execution/file-assigner.js +20 -12
- package/dist/phases/pr-execution/index.js +59 -1
- package/dist/phases/pr-resolve/prompts.js +2 -1
- package/dist/phases/pr-resolve/workspace.d.ts +1 -1
- package/dist/phases/pr-resolve/workspace.js +1 -1
- package/dist/phases/pr-review/__tests__/review-comments.test.js +4 -2
- package/dist/phases/pr-review/index.js +1 -3
- package/dist/phases/pr-shared/agent-utils.js +0 -1
- package/dist/phases/pr-shared/context.d.ts +1 -1
- package/dist/phases/pr-splitting/index.js +1 -3
- 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/index.js +1 -3
- 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/phases/test-cases-analysis/index.js +1 -3
- package/dist/phases/user-stories-analysis/index.js +1 -3
- 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,629 @@
|
|
|
1
|
+
import { query } from '@anthropic-ai/claude-code';
|
|
2
|
+
import { logInfo, logError } from '../../utils/logger.js';
|
|
3
|
+
import { formatChecklistsForContext, } from '../../services/checklist.js';
|
|
4
|
+
import { getFeedbacksForPhase, formatFeedbacksForContext, } from '../../services/feedbacks.js';
|
|
5
|
+
import { fetchCodeImplementationContext, formatContextForPrompt, } from './context-fetcher.js';
|
|
6
|
+
import { logFeaturePhaseEvent } from '../../services/audit-logs.js';
|
|
7
|
+
import { performVerificationCycle, buildImplementationResult, buildVerificationFailureResult, buildNoResultsError, } from './analyzer-helpers.js';
|
|
8
|
+
function userMessage(content) {
|
|
9
|
+
return {
|
|
10
|
+
type: 'user',
|
|
11
|
+
message: { role: 'user', content: content },
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async function* prompt(implementationPrompt) {
|
|
15
|
+
yield userMessage(implementationPrompt);
|
|
16
|
+
await new Promise((res) => setTimeout(res, 10000));
|
|
17
|
+
}
|
|
18
|
+
export const implementFeatureCode = async (options, config, checklistContext) => {
|
|
19
|
+
const { featureId, verbose, baseBranch = 'main' } = options;
|
|
20
|
+
if (verbose) {
|
|
21
|
+
logInfo(`Starting code implementation for feature ID: ${featureId}`);
|
|
22
|
+
logInfo(`Base branch: ${baseBranch}`);
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
// Fetch all required context information via MCP endpoints
|
|
26
|
+
if (verbose) {
|
|
27
|
+
logInfo('Fetching code implementation context via MCP endpoints...');
|
|
28
|
+
}
|
|
29
|
+
const context = await fetchCodeImplementationContext(featureId, verbose);
|
|
30
|
+
// Fetch feedbacks for code implementation phase
|
|
31
|
+
let feedbacksInfo;
|
|
32
|
+
try {
|
|
33
|
+
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'code_implementation');
|
|
34
|
+
if (feedbacksContext.feedbacks.length > 0) {
|
|
35
|
+
feedbacksInfo = formatFeedbacksForContext(feedbacksContext);
|
|
36
|
+
if (verbose) {
|
|
37
|
+
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to implementation context`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
// Don't fail if feedbacks fetch fails - just log and continue
|
|
43
|
+
if (verbose) {
|
|
44
|
+
logInfo(`Note: Could not fetch feedbacks (${error instanceof Error ? error.message : String(error)})`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const systemPrompt = createSystemPrompt(config, baseBranch, featureId);
|
|
48
|
+
const initialImplementationPrompt = createImplementationPromptWithContext(featureId, context, baseBranch, checklistContext, verbose, feedbacksInfo);
|
|
49
|
+
const maxIterations = options.maxVerificationIterations || 10;
|
|
50
|
+
let currentIteration = 0;
|
|
51
|
+
let currentPrompt = initialImplementationPrompt;
|
|
52
|
+
let structuredImplementationResult = null;
|
|
53
|
+
let verificationResult = null;
|
|
54
|
+
const branchName = `dev/${featureId}`;
|
|
55
|
+
if (verbose) {
|
|
56
|
+
logInfo('Starting Claude Code query with pre-fetched information...');
|
|
57
|
+
}
|
|
58
|
+
// Iterative improvement loop: implement → verify → improve → re-implement
|
|
59
|
+
while (currentIteration < maxIterations) {
|
|
60
|
+
currentIteration++;
|
|
61
|
+
if (verbose && currentIteration > 1) {
|
|
62
|
+
logInfo(`\n🔄 Iteration ${currentIteration}/${maxIterations}: Improving implementation based on code review feedback...`);
|
|
63
|
+
}
|
|
64
|
+
// Log iteration start (for iterations after the first)
|
|
65
|
+
if (currentIteration > 1) {
|
|
66
|
+
await logFeaturePhaseEvent({
|
|
67
|
+
featureId,
|
|
68
|
+
eventType: 'phase_started',
|
|
69
|
+
phase: 'code_implementation',
|
|
70
|
+
result: 'info',
|
|
71
|
+
metadata: {
|
|
72
|
+
iteration: currentIteration,
|
|
73
|
+
max_iterations: maxIterations,
|
|
74
|
+
re_implementation: true,
|
|
75
|
+
timestamp: new Date().toISOString(),
|
|
76
|
+
},
|
|
77
|
+
}, verbose);
|
|
78
|
+
}
|
|
79
|
+
let lastAssistantResponse = '';
|
|
80
|
+
let newImplementationResult = null;
|
|
81
|
+
// DEBUG: Log checklist context before query
|
|
82
|
+
console.log('=== DEBUG: Checklist Context Before Claude Query ===');
|
|
83
|
+
console.log('Has checklistContext:', !!checklistContext);
|
|
84
|
+
if (checklistContext) {
|
|
85
|
+
console.log('Number of checklists:', checklistContext.checklists.length);
|
|
86
|
+
const totalItems = checklistContext.checklists.reduce((sum, checklist) => sum + (checklist.items?.length || 0), 0);
|
|
87
|
+
console.log('Total checklist items:', totalItems);
|
|
88
|
+
}
|
|
89
|
+
console.log('Implementation prompt includes checklist:', currentPrompt.includes('checklist'));
|
|
90
|
+
console.log('System prompt includes checklist:', systemPrompt.includes('checklist'));
|
|
91
|
+
// Execute implementation query
|
|
92
|
+
for await (const message of query({
|
|
93
|
+
prompt: prompt(currentPrompt),
|
|
94
|
+
options: {
|
|
95
|
+
appendSystemPrompt: systemPrompt,
|
|
96
|
+
model: config.claude.model || 'sonnet',
|
|
97
|
+
maxTurns: 3000,
|
|
98
|
+
permissionMode: 'bypassPermissions',
|
|
99
|
+
},
|
|
100
|
+
})) {
|
|
101
|
+
if (verbose) {
|
|
102
|
+
logInfo(`Received message type: ${message.type}`);
|
|
103
|
+
}
|
|
104
|
+
// Stream the implementation process
|
|
105
|
+
if (message.type === 'assistant' && message.message?.content) {
|
|
106
|
+
for (const content of message.message.content) {
|
|
107
|
+
if (content.type === 'text') {
|
|
108
|
+
lastAssistantResponse += content.text + '\n';
|
|
109
|
+
if (verbose) {
|
|
110
|
+
console.log(`\n🤖 ${content.text}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (content.type === 'tool_use') {
|
|
114
|
+
if (verbose) {
|
|
115
|
+
console.log(`\n🔧 ${content.name}: ${content.input.description || 'Running...'}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (message.type === 'result') {
|
|
121
|
+
if (message.subtype === 'success') {
|
|
122
|
+
logInfo('\n💻 Code implementation completed, parsing results...');
|
|
123
|
+
try {
|
|
124
|
+
// Try to extract JSON from markdown code block or parse directly
|
|
125
|
+
const responseText = message.result || lastAssistantResponse;
|
|
126
|
+
let jsonResult = null;
|
|
127
|
+
// DEBUG: Log response text details and checklist content
|
|
128
|
+
console.log('=== DEBUG: Code Implementation Response Analysis ===');
|
|
129
|
+
console.log('message.result exists:', !!message.result);
|
|
130
|
+
console.log('lastAssistantResponse exists:', !!lastAssistantResponse);
|
|
131
|
+
console.log('responseText length:', responseText.length);
|
|
132
|
+
console.log('responseText first 200 chars:', JSON.stringify(responseText.substring(0, 200)));
|
|
133
|
+
console.log('responseText last 200 chars:', JSON.stringify(responseText.substring(responseText.length - 200)));
|
|
134
|
+
console.log('Contains ```json:', responseText.includes('```json'));
|
|
135
|
+
console.log('Contains implementation_result:', responseText.includes('"implementation_result"'));
|
|
136
|
+
console.log('=== DEBUG: Checklist Content in Response ===');
|
|
137
|
+
console.log('Contains "checklist":', responseText.toLowerCase().includes('checklist'));
|
|
138
|
+
console.log('Contains "checklist_item_results":', responseText.includes('checklist_item_results'));
|
|
139
|
+
console.log('Contains checklist_item_id:', responseText.includes('checklist_item_id'));
|
|
140
|
+
console.log('Contains is_passed:', responseText.includes('is_passed'));
|
|
141
|
+
// Count checklist-related occurrences
|
|
142
|
+
const checklistMatches = responseText.match(/checklist/gi) || [];
|
|
143
|
+
const checklistItemMatches = responseText.match(/checklist_item/gi) || [];
|
|
144
|
+
console.log('Total "checklist" mentions:', checklistMatches.length);
|
|
145
|
+
console.log('Total "checklist_item" mentions:', checklistItemMatches.length);
|
|
146
|
+
// First try to extract JSON from markdown code block
|
|
147
|
+
const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
|
|
148
|
+
console.log('=== DEBUG: Markdown Block Match ===');
|
|
149
|
+
console.log('jsonBlockMatch found:', !!jsonBlockMatch);
|
|
150
|
+
if (jsonBlockMatch) {
|
|
151
|
+
console.log('Matched JSON length:', jsonBlockMatch[1].length);
|
|
152
|
+
console.log('Matched JSON first 100 chars:', JSON.stringify(jsonBlockMatch[1].substring(0, 100)));
|
|
153
|
+
jsonResult = JSON.parse(jsonBlockMatch[1]);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.log('=== DEBUG: Trying direct JSON parse ===');
|
|
157
|
+
// Try to parse the entire response as JSON
|
|
158
|
+
jsonResult = JSON.parse(responseText);
|
|
159
|
+
}
|
|
160
|
+
console.log('=== DEBUG: Final Result Processing ===');
|
|
161
|
+
console.log('jsonResult exists:', !!jsonResult);
|
|
162
|
+
console.log('jsonResult has implementation_result:', !!(jsonResult && jsonResult.implementation_result));
|
|
163
|
+
if (jsonResult && jsonResult.implementation_result) {
|
|
164
|
+
const implResult = jsonResult.implementation_result;
|
|
165
|
+
console.log('=== DEBUG: Implementation Result Structure ===');
|
|
166
|
+
console.log('Keys in implementation_result:', Object.keys(implResult));
|
|
167
|
+
console.log('Has checklist_item_results field:', 'checklist_item_results' in implResult);
|
|
168
|
+
console.log('checklist_item_results value type:', typeof implResult.checklist_item_results);
|
|
169
|
+
console.log('checklist_item_results is array:', Array.isArray(implResult.checklist_item_results));
|
|
170
|
+
if (implResult.checklist_item_results) {
|
|
171
|
+
console.log('checklist_item_results length:', implResult.checklist_item_results.length);
|
|
172
|
+
if (implResult.checklist_item_results.length > 0) {
|
|
173
|
+
console.log('First checklist item keys:', Object.keys(implResult.checklist_item_results[0]));
|
|
174
|
+
console.log('First checklist item sample:', JSON.stringify(implResult.checklist_item_results[0], null, 2));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
console.log('checklist_item_results is null/undefined/empty');
|
|
179
|
+
}
|
|
180
|
+
newImplementationResult = jsonResult.implementation_result;
|
|
181
|
+
console.log('Successfully extracted implementation_result');
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.log('ERROR: Invalid JSON structure - missing implementation_result');
|
|
185
|
+
throw new Error('Invalid JSON structure');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
console.log('=== DEBUG: JSON Parsing Failed ===');
|
|
190
|
+
console.log('Error type:', error instanceof SyntaxError
|
|
191
|
+
? 'SyntaxError'
|
|
192
|
+
: error instanceof Error
|
|
193
|
+
? error.constructor.name
|
|
194
|
+
: 'Unknown');
|
|
195
|
+
console.log('Error message:', error instanceof Error ? error.message : String(error));
|
|
196
|
+
logError(`Failed to parse structured implementation result: ${error}`);
|
|
197
|
+
console.log('=== DEBUG: Using Fallback Parsing ===');
|
|
198
|
+
// Fallback parsing
|
|
199
|
+
const parsedResult = parseImplementationResponse(message.result || lastAssistantResponse, featureId);
|
|
200
|
+
console.log('Fallback parsed result:', {
|
|
201
|
+
branchName: parsedResult.branchName,
|
|
202
|
+
filesModifiedCount: parsedResult.filesModified?.length || 0,
|
|
203
|
+
hasSummary: !!parsedResult.summary,
|
|
204
|
+
commitHash: parsedResult.commitHash,
|
|
205
|
+
});
|
|
206
|
+
newImplementationResult = {
|
|
207
|
+
branch_name: parsedResult.branchName,
|
|
208
|
+
files_modified: parsedResult.filesModified,
|
|
209
|
+
commit_hash: parsedResult.commitHash,
|
|
210
|
+
summary: parsedResult.summary || 'Implementation completed',
|
|
211
|
+
tests_passed: true,
|
|
212
|
+
pre_commit_passed: true,
|
|
213
|
+
checklist_item_results: parsedResult.checklist_item_results || [],
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
logError(`\n⚠️ Code implementation incomplete: ${message.subtype}`);
|
|
219
|
+
if (message.subtype === 'error_max_turns') {
|
|
220
|
+
logError('💡 Try breaking down the feature into smaller tasks');
|
|
221
|
+
}
|
|
222
|
+
// Try to parse results from the last assistant response
|
|
223
|
+
if (lastAssistantResponse) {
|
|
224
|
+
console.log('=== DEBUG: Fallback for incomplete result ===');
|
|
225
|
+
console.log('message.subtype:', message.subtype);
|
|
226
|
+
try {
|
|
227
|
+
const responseText = lastAssistantResponse;
|
|
228
|
+
let jsonResult = null;
|
|
229
|
+
console.log('lastAssistantResponse length:', responseText.length);
|
|
230
|
+
console.log('lastAssistantResponse first 200 chars:', JSON.stringify(responseText.substring(0, 200)));
|
|
231
|
+
const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
|
|
232
|
+
console.log('jsonBlockMatch in fallback found:', !!jsonBlockMatch);
|
|
233
|
+
if (jsonBlockMatch) {
|
|
234
|
+
jsonResult = JSON.parse(jsonBlockMatch[1]);
|
|
235
|
+
if (jsonResult && jsonResult.implementation_result) {
|
|
236
|
+
newImplementationResult = jsonResult.implementation_result;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
logError(`Failed to parse assistant response: ${error}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Check if implementation produced results
|
|
248
|
+
if (!newImplementationResult) {
|
|
249
|
+
if (verbose) {
|
|
250
|
+
logError('⚠️ Implementation failed in this iteration');
|
|
251
|
+
}
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
// Update with new implementation result
|
|
255
|
+
structuredImplementationResult = newImplementationResult;
|
|
256
|
+
// Log implementation completion for this iteration
|
|
257
|
+
await logFeaturePhaseEvent({
|
|
258
|
+
featureId,
|
|
259
|
+
eventType: 'phase_completed',
|
|
260
|
+
phase: 'code_implementation',
|
|
261
|
+
result: 'success',
|
|
262
|
+
metadata: {
|
|
263
|
+
iteration: currentIteration,
|
|
264
|
+
max_iterations: maxIterations,
|
|
265
|
+
implementation_step: 'completed',
|
|
266
|
+
branch_name: structuredImplementationResult.branch_name,
|
|
267
|
+
files_modified: structuredImplementationResult.files_modified || [],
|
|
268
|
+
commit_hash: structuredImplementationResult.commit_hash || '',
|
|
269
|
+
timestamp: new Date().toISOString(),
|
|
270
|
+
},
|
|
271
|
+
}, verbose);
|
|
272
|
+
// Push code to remote after commit
|
|
273
|
+
if (verbose) {
|
|
274
|
+
logInfo(`📤 Pushing code to remote repository...`);
|
|
275
|
+
}
|
|
276
|
+
const pushResult = await pushToRemote(structuredImplementationResult.branch_name || branchName, verbose);
|
|
277
|
+
if (!pushResult.success && verbose) {
|
|
278
|
+
logError(`⚠️ Failed to push to remote: ${pushResult.error}`);
|
|
279
|
+
logInfo(' Code is committed locally and will be reviewed. Manual push may be needed.');
|
|
280
|
+
}
|
|
281
|
+
else if (verbose) {
|
|
282
|
+
logInfo('✅ Code pushed to remote successfully');
|
|
283
|
+
}
|
|
284
|
+
// Perform verification cycle
|
|
285
|
+
const verificationCycle = await performVerificationCycle(structuredImplementationResult.branch_name || branchName, baseBranch, checklistContext || null, featureId, context.feature.name, context.feature.description, config, currentIteration, maxIterations, verbose);
|
|
286
|
+
verificationResult = verificationCycle.verificationResult;
|
|
287
|
+
// If verification passed, exit
|
|
288
|
+
if (verificationCycle.passed) {
|
|
289
|
+
if (verbose) {
|
|
290
|
+
logInfo('✅ Verification passed! Code implementation complete.');
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
// Verification failed
|
|
295
|
+
if (currentIteration < maxIterations && verificationCycle.nextPrompt) {
|
|
296
|
+
// We have more iterations - retry with improvement prompt
|
|
297
|
+
if (verbose) {
|
|
298
|
+
logInfo(`🔄 Will improve implementation in next iteration (${maxIterations - currentIteration} attempts remaining)`);
|
|
299
|
+
}
|
|
300
|
+
currentPrompt = verificationCycle.nextPrompt;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
// Max iterations reached or no next prompt - exit loop
|
|
304
|
+
if (verbose) {
|
|
305
|
+
logInfo('⚠️ Max iterations reached. Last implementation committed.');
|
|
306
|
+
}
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// Handle results
|
|
311
|
+
if (!structuredImplementationResult) {
|
|
312
|
+
return buildNoResultsError(featureId, branchName);
|
|
313
|
+
}
|
|
314
|
+
const { branch_name, files_modified, commit_hash, summary, checklist_results, checklist_item_results, } = structuredImplementationResult;
|
|
315
|
+
// Check if verification failed after all iterations
|
|
316
|
+
if (verificationResult &&
|
|
317
|
+
verificationResult.rejected_count > 0 &&
|
|
318
|
+
checklistContext &&
|
|
319
|
+
checklistContext.checklists.length > 0) {
|
|
320
|
+
logError(`❌ Final result: Code verification FAILED after ${currentIteration} iterations`);
|
|
321
|
+
logError(` Code committed for manual review`);
|
|
322
|
+
return buildVerificationFailureResult(featureId, branch_name || branchName, summary || 'Implementation completed with verification failures', files_modified || [], commit_hash || '', verificationResult, currentIteration);
|
|
323
|
+
}
|
|
324
|
+
// Return success result
|
|
325
|
+
return buildImplementationResult(featureId, branch_name || branchName, summary || 'Implementation completed successfully', files_modified || [], commit_hash || '', currentIteration, checklist_results, checklist_item_results);
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
logError(`Code implementation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
329
|
+
return {
|
|
330
|
+
featureId,
|
|
331
|
+
branchName: `dev/${featureId}`,
|
|
332
|
+
implementationSummary: null,
|
|
333
|
+
status: 'error',
|
|
334
|
+
message: `Implementation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
const createSystemPrompt = (_config, baseBranch, mcpServerUrl, mcpToken, featureId) => {
|
|
339
|
+
let mcpInstructions = '';
|
|
340
|
+
if (mcpServerUrl && mcpToken && featureId) {
|
|
341
|
+
mcpInstructions = `
|
|
342
|
+
|
|
343
|
+
**MANDATORY Checklist Compliance**:
|
|
344
|
+
If you are provided with checklists in the context, you MUST satisfy ALL of them during your implementation work. Checklists are mandatory requirements that define quality standards and cannot be ignored or skipped.
|
|
345
|
+
|
|
346
|
+
- Review each checklist carefully and ensure your implementation addresses every requirement
|
|
347
|
+
- You MUST include ALL provided checklist item IDs in the "checklist_item_results" field of your JSON response
|
|
348
|
+
- CRITICAL: Use the exact UUID from the "ID:" field in each checklist ITEM, NOT the item title or description
|
|
349
|
+
- Set "is_passed": true for each checklist item you have completed successfully
|
|
350
|
+
- Provide appropriate "value" based on the item type (boolean: true/false, text: descriptive text, number: numeric value)
|
|
351
|
+
- If you cannot satisfy a checklist item requirement, set "is_passed": false and explain why in the "notes" field
|
|
352
|
+
- The system will validate that all checklists have been addressed - missing checklists will cause the pipeline to fail
|
|
353
|
+
|
|
354
|
+
CRITICAL: Checklists are not optional suggestions - they are mandatory quality gates that must be satisfied.`;
|
|
355
|
+
}
|
|
356
|
+
return `You are an expert full-stack developer implementing features based on specifications. Your task is to implement complete, production-ready code based on feature requirements, user stories, test cases, and technical design.
|
|
357
|
+
|
|
358
|
+
**Your Role**: Implement complete, working features based on provided specifications and requirements.
|
|
359
|
+
|
|
360
|
+
**Available Tools**:
|
|
361
|
+
- Bash: Git operations, running commands, tests, and builds
|
|
362
|
+
- Glob: Find files and understand project structure
|
|
363
|
+
- Read: Examine existing code, configuration, and documentation files
|
|
364
|
+
- Edit: Modify existing files
|
|
365
|
+
- Write: Create new files
|
|
366
|
+
- TodoWrite: Track implementation tasks (use proactively)${mcpInstructions}
|
|
367
|
+
|
|
368
|
+
**CRITICAL WORKFLOW - YOU MUST FOLLOW THESE STEPS IN ORDER**:
|
|
369
|
+
|
|
370
|
+
1. **GIT PULL REBASE**: First, ensure main branch is up to date with remote:
|
|
371
|
+
- git checkout ${baseBranch}
|
|
372
|
+
- git pull origin ${baseBranch} --rebase
|
|
373
|
+
2. **CREATE BRANCH**: Create a new feature branch from ${baseBranch}
|
|
374
|
+
3. **ANALYZE CODEBASE**: Use Glob and Read to understand the existing code structure
|
|
375
|
+
4. **IMPLEMENT CODE**: Write the actual implementation using Edit/Write tools
|
|
376
|
+
5. **FIX ISSUES**: Address any lint or build failures
|
|
377
|
+
6. **COMMIT**: Commit your changes with a descriptive message
|
|
378
|
+
7. **HANDLE PRE-COMMIT**: This project has strict pre-commit hooks - handle them properly:
|
|
379
|
+
- If lint-staged fails: Fix formatting and linting issues, then retry commit
|
|
380
|
+
- If AI code review fails: Either fix code quality issues or use SKIP_REVIEW=1
|
|
381
|
+
- If other issues persist: Only use --no-verify as last resort after confirming code quality
|
|
382
|
+
|
|
383
|
+
**Important Rules**:
|
|
384
|
+
1. **Git Workflow**:
|
|
385
|
+
- ALWAYS pull latest changes from main before creating branch: git pull origin ${baseBranch} --rebase
|
|
386
|
+
- ALWAYS create a new branch before making changes: git checkout -b dev/<feature-id>
|
|
387
|
+
- Use descriptive commit messages that explain what and why
|
|
388
|
+
- Handle pre-commit checks properly: fix issues first, use workarounds only when necessary
|
|
389
|
+
|
|
390
|
+
2. **Code Quality**:
|
|
391
|
+
- Follow existing code patterns and conventions in the repository
|
|
392
|
+
- Ensure proper TypeScript types and interfaces
|
|
393
|
+
- Add appropriate error handling and validation
|
|
394
|
+
- Write clean, maintainable code with proper comments where necessary
|
|
395
|
+
|
|
396
|
+
3. **Pre-commit Handling**:
|
|
397
|
+
- This project has strict pre-commit hooks including lint-staged, linting, and AI code review
|
|
398
|
+
- When pre-commit hooks fail, READ the error messages carefully
|
|
399
|
+
- Fix ALL issues reported (lint errors, type errors, formatting, code quality)
|
|
400
|
+
- Re-run the commit after fixing issues
|
|
401
|
+
- If you encounter persistent issues with AI code review or non-critical pre-commit failures:
|
|
402
|
+
* First attempt to fix the actual issues
|
|
403
|
+
* Only use --no-verify as a last resort if you are 100% confident your code is correct
|
|
404
|
+
* When using --no-verify, add a comment explaining why it was necessary
|
|
405
|
+
- IMPORTANT: AI code review can be skipped with SKIP_REVIEW=1 environment variable if needed
|
|
406
|
+
|
|
407
|
+
5. **File Modification**:
|
|
408
|
+
- Prefer modifying existing files over creating new ones
|
|
409
|
+
- Follow the existing file structure and naming conventions
|
|
410
|
+
- Use the appropriate tools (Edit for existing files, Write for new files)
|
|
411
|
+
|
|
412
|
+
**CRITICAL - Result Format**:
|
|
413
|
+
You MUST end your response with a JSON object containing the implementation results in this EXACT format:
|
|
414
|
+
|
|
415
|
+
\`\`\`json
|
|
416
|
+
{
|
|
417
|
+
"implementation_result": {
|
|
418
|
+
"feature_id": "FEATURE_ID_PLACEHOLDER",
|
|
419
|
+
"branch_name": "dev/FEATURE_ID",
|
|
420
|
+
"files_modified": ["file1.ts", "file2.tsx"],
|
|
421
|
+
"commit_hash": "abc123...",
|
|
422
|
+
"summary": "Brief description of what was implemented",
|
|
423
|
+
"tests_passed": true,
|
|
424
|
+
"pre_commit_passed": true,
|
|
425
|
+
"checklist_item_results": [
|
|
426
|
+
{
|
|
427
|
+
"checklist_item_id": "EXACT_CHECKLIST_ITEM_UUID_FROM_ID_FIELD",
|
|
428
|
+
"is_passed": true,
|
|
429
|
+
"value": "Result value based on item type (boolean, text, number, etc.)",
|
|
430
|
+
"notes": "Optional notes about this specific checklist item"
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
\`\`\`
|
|
436
|
+
|
|
437
|
+
MANDATORY: If checklists are provided in the context, you MUST include checklist_item_results for ALL checklist items. Every checklist item ID must be addressed - either passed or with explanation in notes why it cannot be satisfied. Missing any checklist item will cause the pipeline to fail.
|
|
438
|
+
|
|
439
|
+
IMPORTANT: In the checklist context, look for lines that say "ID: [UUID]" in the items list - use these exact UUIDs as checklist_item_id values. Do NOT use the item title or description as the checklist_item_id.
|
|
440
|
+
|
|
441
|
+
Remember: Quality over speed. It's better to implement correctly than to rush and create bugs.`;
|
|
442
|
+
};
|
|
443
|
+
const createImplementationPromptWithContext = (featureId, context, baseBranch, checklistContext, verbose, feedbacksInfo) => {
|
|
444
|
+
const contextInfo = formatContextForPrompt(context);
|
|
445
|
+
let finalContextInfo = contextInfo;
|
|
446
|
+
// Add feedbacks context to the implementation prompt
|
|
447
|
+
if (feedbacksInfo) {
|
|
448
|
+
finalContextInfo = finalContextInfo + '\n\n' + feedbacksInfo;
|
|
449
|
+
}
|
|
450
|
+
// Add checklist context to the implementation prompt
|
|
451
|
+
let checklistInstructions = '';
|
|
452
|
+
if (checklistContext && checklistContext.checklists.length > 0) {
|
|
453
|
+
const checklistInfo = formatChecklistsForContext(checklistContext);
|
|
454
|
+
finalContextInfo = finalContextInfo + '\n\n' + checklistInfo;
|
|
455
|
+
// DEBUG: Log checklist context details
|
|
456
|
+
console.log('=== DEBUG: Checklist Context for Code Implementation ===');
|
|
457
|
+
console.log('Number of checklists:', checklistContext.checklists.length);
|
|
458
|
+
console.log('Checklist info length:', checklistInfo.length);
|
|
459
|
+
console.log('Checklist info preview:', checklistInfo.substring(0, 300));
|
|
460
|
+
checklistContext.checklists.forEach((checklist, index) => {
|
|
461
|
+
console.log(`Checklist ${index + 1}:`, {
|
|
462
|
+
id: checklist.id,
|
|
463
|
+
name: checklist.name,
|
|
464
|
+
phase: checklist.phase,
|
|
465
|
+
role: checklist.role,
|
|
466
|
+
itemCount: checklist.items?.length || 0,
|
|
467
|
+
});
|
|
468
|
+
if (checklist.items) {
|
|
469
|
+
checklist.items.forEach((item, itemIndex) => {
|
|
470
|
+
console.log(` Item ${itemIndex + 1}:`, {
|
|
471
|
+
id: item.id,
|
|
472
|
+
title: item.title?.substring(0, 50) || 'No title',
|
|
473
|
+
description: item.description?.substring(0, 50) || 'No description',
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
// Add specific instructions for creating checklist results
|
|
479
|
+
checklistInstructions = `
|
|
480
|
+
|
|
481
|
+
## MANDATORY Checklist Compliance
|
|
482
|
+
|
|
483
|
+
**CRITICAL**: You MUST address ALL checklists provided in the context above. Checklists are mandatory quality requirements that cannot be ignored.
|
|
484
|
+
|
|
485
|
+
- Review each checklist carefully during your implementation
|
|
486
|
+
- Ensure your code and processes satisfy every checklist requirement
|
|
487
|
+
- Include ALL checklist item IDs in your final JSON response under "checklist_item_results" (use the exact UUID from "ID:" field in items list)
|
|
488
|
+
- Set "is_passed": true for completed checklist items, or explain in "notes" why a requirement cannot be met
|
|
489
|
+
- Missing any checklist will cause the entire pipeline to fail
|
|
490
|
+
|
|
491
|
+
Remember: Checklists are not suggestions - they are mandatory quality gates.`;
|
|
492
|
+
if (verbose) {
|
|
493
|
+
logInfo(`Added ${checklistContext.checklists.length} checklists to implementation context`);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return `Implement the complete feature for feature ID: ${featureId}
|
|
497
|
+
|
|
498
|
+
${finalContextInfo}
|
|
499
|
+
|
|
500
|
+
## Implementation Instructions
|
|
501
|
+
|
|
502
|
+
Follow this systematic approach:
|
|
503
|
+
|
|
504
|
+
1. **GIT PULL REBASE**: First ensure ${baseBranch} is up to date:
|
|
505
|
+
\`git checkout ${baseBranch}\`
|
|
506
|
+
\`git pull origin ${baseBranch} --rebase\`
|
|
507
|
+
|
|
508
|
+
2. **CREATE BRANCH**: Create a new git branch from ${baseBranch}:
|
|
509
|
+
\`git checkout -b dev/${featureId}\`
|
|
510
|
+
|
|
511
|
+
2. **ANALYZE CODEBASE**: Study the existing codebase structure to understand:
|
|
512
|
+
- Technology stack and architecture
|
|
513
|
+
- Existing patterns and conventions
|
|
514
|
+
- Where to place new components/files
|
|
515
|
+
- How to integrate with existing systems
|
|
516
|
+
|
|
517
|
+
3. **IMPLEMENT FEATURE**: Based on the context above, implement the feature by:
|
|
518
|
+
- Following the technical design (if available)
|
|
519
|
+
- Satisfying all user stories
|
|
520
|
+
- Creating components, services, APIs, database changes as needed
|
|
521
|
+
- Following existing code patterns and conventions
|
|
522
|
+
- Adding proper error handling and validation
|
|
523
|
+
|
|
524
|
+
4. **COMMIT CHANGES**: Commit your work with a descriptive message
|
|
525
|
+
- This project has strict pre-commit hooks (lint-staged, linting, AI code review)
|
|
526
|
+
- If hooks fail, try these approaches in order:
|
|
527
|
+
1. Fix the reported issues (preferred)
|
|
528
|
+
2. For AI code review issues: SKIP_REVIEW=1 git commit -m "message"
|
|
529
|
+
3. Last resort only: git commit --no-verify -m "message" (explain why in commit message)
|
|
530
|
+
|
|
531
|
+
## Important Notes
|
|
532
|
+
- Focus on implementing ALL user stories completely
|
|
533
|
+
- Follow the technical design if provided, or create your own approach
|
|
534
|
+
- Maintain existing code quality and patterns
|
|
535
|
+
- Never skip pre-commit checks - always fix the issues
|
|
536
|
+
- Focus on implementation only - automated tests will be written in a separate phase
|
|
537
|
+
|
|
538
|
+
${checklistInstructions}
|
|
539
|
+
|
|
540
|
+
Begin by creating a feature branch and analyzing the codebase structure.`;
|
|
541
|
+
};
|
|
542
|
+
const parseImplementationResponse = (response, featureId) => {
|
|
543
|
+
console.log('Parsing implementation response...');
|
|
544
|
+
try {
|
|
545
|
+
// Try to find JSON in the response
|
|
546
|
+
const jsonMatch = response.match(/```json\s*([\s\S]*?)\s*```/) ||
|
|
547
|
+
response.match(/\{[\s\S]*"implementation_result"[\s\S]*\}/);
|
|
548
|
+
if (jsonMatch) {
|
|
549
|
+
const jsonStr = jsonMatch[1] || jsonMatch[0];
|
|
550
|
+
const parsed = JSON.parse(jsonStr);
|
|
551
|
+
if (parsed.implementation_result) {
|
|
552
|
+
const result = parsed.implementation_result;
|
|
553
|
+
return {
|
|
554
|
+
branchName: result.branch_name || `dev/${featureId}`,
|
|
555
|
+
filesModified: result.files_modified || [],
|
|
556
|
+
commitHash: result.commit_hash || '',
|
|
557
|
+
summary: result.summary || '',
|
|
558
|
+
checklist_item_results: result.checklist_item_results || [],
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
// Fallback: try to extract information from the text
|
|
563
|
+
const branchMatch = response.match(/branch[:\s]+(\S+)/i);
|
|
564
|
+
const filesMatch = response.match(/files?[:\s]+([^\n]+)/i);
|
|
565
|
+
const commitMatch = response.match(/commit[:\s]+([a-f0-9]{7,})/i);
|
|
566
|
+
return {
|
|
567
|
+
branchName: branchMatch?.[1] || `dev/${featureId}`,
|
|
568
|
+
filesModified: filesMatch
|
|
569
|
+
? filesMatch[1].split(/[,\s]+/).filter((f) => f)
|
|
570
|
+
: [],
|
|
571
|
+
commitHash: commitMatch?.[1] || '',
|
|
572
|
+
summary: 'Implementation completed',
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
catch (error) {
|
|
576
|
+
console.log('Response parsing failed:', error);
|
|
577
|
+
return {
|
|
578
|
+
branchName: `dev/${featureId}`,
|
|
579
|
+
filesModified: [],
|
|
580
|
+
commitHash: '',
|
|
581
|
+
summary: 'Implementation completed',
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
/**
|
|
586
|
+
* Push branch to remote repository
|
|
587
|
+
*/
|
|
588
|
+
async function pushToRemote(branchName, verbose) {
|
|
589
|
+
try {
|
|
590
|
+
// Import exec from child_process
|
|
591
|
+
const { execSync } = await import('child_process');
|
|
592
|
+
if (verbose) {
|
|
593
|
+
logInfo(`Pushing branch ${branchName} to remote...`);
|
|
594
|
+
}
|
|
595
|
+
// Try to push with -u flag (sets upstream if not already set)
|
|
596
|
+
try {
|
|
597
|
+
execSync(`git push -u origin ${branchName}`, {
|
|
598
|
+
encoding: 'utf-8',
|
|
599
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
600
|
+
});
|
|
601
|
+
return { success: true };
|
|
602
|
+
}
|
|
603
|
+
catch (error) {
|
|
604
|
+
// If push fails, it might be because branch already has upstream
|
|
605
|
+
// Try without -u flag
|
|
606
|
+
try {
|
|
607
|
+
execSync(`git push origin ${branchName}`, {
|
|
608
|
+
encoding: 'utf-8',
|
|
609
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
610
|
+
});
|
|
611
|
+
return { success: true };
|
|
612
|
+
}
|
|
613
|
+
catch (retryError) {
|
|
614
|
+
const errorMessage = retryError instanceof Error ? retryError.message : String(retryError);
|
|
615
|
+
return {
|
|
616
|
+
success: false,
|
|
617
|
+
error: errorMessage,
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
624
|
+
return {
|
|
625
|
+
success: false,
|
|
626
|
+
error: errorMessage,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FeatureInfo, UserStory, TestCase } from '../../types/features.js';
|
|
2
|
+
import { type ProductInfo } from '../../api/products.js';
|
|
3
|
+
export interface CodeImplementationContext {
|
|
4
|
+
feature: FeatureInfo;
|
|
5
|
+
product: ProductInfo;
|
|
6
|
+
user_stories: UserStory[];
|
|
7
|
+
test_cases: TestCase[];
|
|
8
|
+
technical_design?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Fetch all code implementation context information via MCP endpoints
|
|
12
|
+
*/
|
|
13
|
+
export declare function fetchCodeImplementationContext(featureId: string, verbose?: boolean): Promise<CodeImplementationContext>;
|
|
14
|
+
/**
|
|
15
|
+
* Format the context into a readable string for Claude Code
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatContextForPrompt(context: CodeImplementationContext): string;
|