edsger 0.2.11 â 0.2.13
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.
|
@@ -168,20 +168,54 @@ async function prepareDesignContext(mcpServerUrl, mcpToken, featureId, checklist
|
|
|
168
168
|
}
|
|
169
169
|
// Add feedbacks context to the design prompt
|
|
170
170
|
try {
|
|
171
|
+
if (verbose) {
|
|
172
|
+
logInfo(`đ Fetching feedbacks from MCP: ${mcpServerUrl}/mcp (phase: technical-design)`);
|
|
173
|
+
}
|
|
171
174
|
feedbacksContext = await getFeedbacksForPhase({ featureId, mcpServerUrl, mcpToken, verbose }, 'technical-design');
|
|
175
|
+
if (verbose) {
|
|
176
|
+
logInfo(`đ Feedbacks fetched successfully: ${feedbacksContext.feedbacks.length} feedbacks found`);
|
|
177
|
+
if (feedbacksContext.feedbacks.length > 0) {
|
|
178
|
+
logInfo('đ Feedbacks details:');
|
|
179
|
+
feedbacksContext.feedbacks.forEach((fb, idx) => {
|
|
180
|
+
logInfo(` ${idx + 1}. [${fb.feedback_type}] ${fb.title} (priority: ${fb.priority}, resolved: ${fb.is_resolved || false})`);
|
|
181
|
+
logInfo(` Content: ${fb.content.substring(0, 150)}...`);
|
|
182
|
+
if (fb.reference_section) {
|
|
183
|
+
logInfo(` Section: ${fb.reference_section}`);
|
|
184
|
+
}
|
|
185
|
+
if (fb.reference_line_start) {
|
|
186
|
+
const lineInfo = fb.reference_line_end
|
|
187
|
+
? `Lines ${fb.reference_line_start}-${fb.reference_line_end}`
|
|
188
|
+
: `Line ${fb.reference_line_start}`;
|
|
189
|
+
logInfo(` Location: ${lineInfo}`);
|
|
190
|
+
}
|
|
191
|
+
if (fb.reference_content) {
|
|
192
|
+
logInfo(` Referenced: ${fb.reference_content.substring(0, 100)}...`);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
172
197
|
if (feedbacksContext.feedbacks.length > 0) {
|
|
173
198
|
hasFeedbacks = true;
|
|
174
199
|
const feedbacksInfo = formatFeedbacksForContext(feedbacksContext);
|
|
175
200
|
finalContextInfo = finalContextInfo + '\n\n' + feedbacksInfo;
|
|
176
201
|
if (verbose) {
|
|
177
|
-
logInfo(
|
|
202
|
+
logInfo(`â
Added ${feedbacksContext.feedbacks.length} human feedbacks to design context`);
|
|
203
|
+
logInfo(`đ Feedbacks section length: ${feedbacksInfo.length} characters`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
if (verbose) {
|
|
208
|
+
logInfo('âšī¸ No unresolved feedbacks found for this phase');
|
|
178
209
|
}
|
|
179
210
|
}
|
|
180
211
|
}
|
|
181
212
|
catch (error) {
|
|
182
213
|
// Don't fail if feedbacks fetch fails - just log and continue
|
|
183
214
|
if (verbose) {
|
|
184
|
-
|
|
215
|
+
logError(`â Failed to fetch feedbacks: ${error instanceof Error ? error.message : String(error)}`);
|
|
216
|
+
if (error instanceof Error && error.stack) {
|
|
217
|
+
logError(` Stack: ${error.stack}`);
|
|
218
|
+
}
|
|
185
219
|
}
|
|
186
220
|
}
|
|
187
221
|
// Add checklist context to the design prompt
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { PipelinePhaseOptions } from '../types/pipeline.js';
|
|
6
6
|
export type { PipelinePhaseOptions };
|
|
7
|
-
export type FeedbackType = 'requirement' | 'constraint' | 'preference' | 'context' | 'quality_criteria';
|
|
7
|
+
export type FeedbackType = 'requirement' | 'constraint' | 'preference' | 'context' | 'quality_criteria' | 'issue' | 'suggestion';
|
|
8
8
|
export interface Feedback {
|
|
9
9
|
id: string;
|
|
10
10
|
feature_id: string | null;
|
|
@@ -15,9 +15,16 @@ export interface Feedback {
|
|
|
15
15
|
content: string;
|
|
16
16
|
priority: number;
|
|
17
17
|
is_active: boolean;
|
|
18
|
+
is_resolved?: boolean;
|
|
19
|
+
resolved_at?: string | null;
|
|
20
|
+
resolved_by?: string | null;
|
|
18
21
|
created_by: string;
|
|
19
22
|
created_at: string;
|
|
20
23
|
updated_at: string;
|
|
24
|
+
reference_line_start?: number | null;
|
|
25
|
+
reference_line_end?: number | null;
|
|
26
|
+
reference_section?: string | null;
|
|
27
|
+
reference_content?: string | null;
|
|
21
28
|
}
|
|
22
29
|
export interface FeedbacksContext {
|
|
23
30
|
phase: string;
|
|
@@ -11,8 +11,19 @@ export async function getFeedbacksForPhase(options, phase) {
|
|
|
11
11
|
// Convert phase name from hyphen to underscore format for database compatibility
|
|
12
12
|
// e.g., 'feature-analysis' -> 'feature_analysis'
|
|
13
13
|
const dbPhase = phase.replace(/-/g, '_');
|
|
14
|
+
const requestBody = {
|
|
15
|
+
jsonrpc: '2.0',
|
|
16
|
+
id: 1,
|
|
17
|
+
method: 'feedbacks/get',
|
|
18
|
+
params: {
|
|
19
|
+
feature_id: featureId,
|
|
20
|
+
phase: dbPhase,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
14
23
|
if (verbose) {
|
|
15
24
|
console.log(`đ Fetching feedbacks: phase="${phase}" (db: "${dbPhase}"), feature_id="${featureId}"`);
|
|
25
|
+
console.log(`đĄ MCP URL: ${mcpServerUrl}/mcp`);
|
|
26
|
+
console.log(`đĻ Request body:`, JSON.stringify(requestBody, null, 2));
|
|
16
27
|
}
|
|
17
28
|
const response = await fetch(`${mcpServerUrl}/mcp`, {
|
|
18
29
|
method: 'POST',
|
|
@@ -20,32 +31,42 @@ export async function getFeedbacksForPhase(options, phase) {
|
|
|
20
31
|
'Content-Type': 'application/json',
|
|
21
32
|
Authorization: `Bearer ${mcpToken}`,
|
|
22
33
|
},
|
|
23
|
-
body: JSON.stringify(
|
|
24
|
-
jsonrpc: '2.0',
|
|
25
|
-
id: 1,
|
|
26
|
-
method: 'feedbacks/get',
|
|
27
|
-
params: {
|
|
28
|
-
feature_id: featureId,
|
|
29
|
-
phase: dbPhase,
|
|
30
|
-
},
|
|
31
|
-
}),
|
|
34
|
+
body: JSON.stringify(requestBody),
|
|
32
35
|
});
|
|
36
|
+
if (verbose) {
|
|
37
|
+
console.log(`đĨ Response status: ${response.status} ${response.statusText}`);
|
|
38
|
+
}
|
|
33
39
|
if (!response.ok) {
|
|
34
40
|
const errorText = await response.text();
|
|
41
|
+
if (verbose) {
|
|
42
|
+
console.log(`â Response error body:`, errorText);
|
|
43
|
+
}
|
|
35
44
|
throw new Error(`Failed to fetch feedbacks for phase "${phase}": ${response.status} ${response.statusText}. Response: ${errorText}`);
|
|
36
45
|
}
|
|
37
46
|
const data = await response.json();
|
|
47
|
+
if (verbose) {
|
|
48
|
+
console.log(`đ MCP response:`, JSON.stringify(data, null, 2));
|
|
49
|
+
}
|
|
38
50
|
if (data.error) {
|
|
51
|
+
if (verbose) {
|
|
52
|
+
console.log(`â MCP error:`, data.error);
|
|
53
|
+
}
|
|
39
54
|
throw new Error(`MCP Error for phase "${phase}": ${data.error.message || JSON.stringify(data.error)}`);
|
|
40
55
|
}
|
|
41
56
|
// Handle empty result gracefully
|
|
42
57
|
if (!data.result) {
|
|
58
|
+
if (verbose) {
|
|
59
|
+
console.log(`â ī¸ Empty result from MCP, returning empty feedbacks array`);
|
|
60
|
+
}
|
|
43
61
|
return {
|
|
44
62
|
phase,
|
|
45
63
|
feature_id: featureId,
|
|
46
64
|
feedbacks: [],
|
|
47
65
|
};
|
|
48
66
|
}
|
|
67
|
+
if (verbose) {
|
|
68
|
+
console.log(`â
Successfully fetched ${data.result.feedbacks?.length || 0} feedbacks`);
|
|
69
|
+
}
|
|
49
70
|
return data.result;
|
|
50
71
|
}
|
|
51
72
|
/**
|
|
@@ -78,6 +99,14 @@ export function formatFeedbacksForContext(context) {
|
|
|
78
99
|
if (grouped.quality_criteria && grouped.quality_criteria.length > 0) {
|
|
79
100
|
sections.push(`## â
Quality Criteria\n\n${formatFeedbacksList(grouped.quality_criteria)}`);
|
|
80
101
|
}
|
|
102
|
+
// Issues
|
|
103
|
+
if (grouped.issue && grouped.issue.length > 0) {
|
|
104
|
+
sections.push(`## đ Issues to Address\n\n${formatFeedbacksList(grouped.issue)}`);
|
|
105
|
+
}
|
|
106
|
+
// Suggestions
|
|
107
|
+
if (grouped.suggestion && grouped.suggestion.length > 0) {
|
|
108
|
+
sections.push(`## đ Suggestions\n\n${formatFeedbacksList(grouped.suggestion)}`);
|
|
109
|
+
}
|
|
81
110
|
const phaseDisplay = context.phase.replace(/_/g, '-');
|
|
82
111
|
return `
|
|
83
112
|
---
|
|
@@ -109,7 +138,21 @@ function formatFeedbacksList(feedbacks) {
|
|
|
109
138
|
return sorted
|
|
110
139
|
.map((feedback, idx) => {
|
|
111
140
|
const priorityBadge = getPriorityBadge(feedback.priority);
|
|
112
|
-
|
|
141
|
+
// Build reference info if available
|
|
142
|
+
let referenceInfo = '';
|
|
143
|
+
if (feedback.reference_section) {
|
|
144
|
+
referenceInfo += `\n**Reference Section**: ${feedback.reference_section}`;
|
|
145
|
+
}
|
|
146
|
+
if (feedback.reference_line_start) {
|
|
147
|
+
const lineRange = feedback.reference_line_end
|
|
148
|
+
? `Lines ${feedback.reference_line_start}-${feedback.reference_line_end}`
|
|
149
|
+
: `Line ${feedback.reference_line_start}`;
|
|
150
|
+
referenceInfo += `\n**Reference Location**: ${lineRange}`;
|
|
151
|
+
}
|
|
152
|
+
if (feedback.reference_content) {
|
|
153
|
+
referenceInfo += `\n**Referenced Content**:\n\`\`\`\n${feedback.reference_content}\n\`\`\``;
|
|
154
|
+
}
|
|
155
|
+
return `### ${idx + 1}. ${feedback.title} ${priorityBadge}\n\n${feedback.content}${referenceInfo}\n`;
|
|
113
156
|
})
|
|
114
157
|
.join('\n');
|
|
115
158
|
}
|