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.
Files changed (178) hide show
  1. package/dist/api/features/feature-utils.d.ts +13 -0
  2. package/dist/api/features/feature-utils.js +46 -0
  3. package/dist/api/features/get-feature.d.ts +5 -0
  4. package/dist/api/features/get-feature.js +19 -0
  5. package/dist/api/features/index.d.ts +7 -0
  6. package/dist/api/features/index.js +9 -0
  7. package/dist/api/features/status-updater.d.ts +27 -0
  8. package/dist/api/features/status-updater.js +64 -0
  9. package/dist/api/features/test-cases.d.ts +21 -0
  10. package/dist/api/features/test-cases.js +63 -0
  11. package/dist/api/features/update-feature.d.ts +13 -0
  12. package/dist/api/features/update-feature.js +31 -0
  13. package/dist/api/features/user-stories.d.ts +21 -0
  14. package/dist/api/features/user-stories.js +63 -0
  15. package/dist/api/features.d.ts +100 -0
  16. package/dist/api/features.js +219 -0
  17. package/dist/api/mcp-client.d.ts +18 -0
  18. package/dist/api/mcp-client.js +58 -0
  19. package/dist/api/products.d.ts +10 -0
  20. package/dist/api/products.js +22 -0
  21. package/dist/api/test-reports.d.ts +9 -0
  22. package/dist/api/test-reports.js +25 -0
  23. package/dist/cli/commands/code-implementation-command.d.ts +2 -0
  24. package/dist/cli/commands/code-implementation-command.js +36 -0
  25. package/dist/cli/commands/code-review-command.d.ts +2 -0
  26. package/dist/cli/commands/code-review-command.js +39 -0
  27. package/dist/cli/commands/feature-analysis-command.d.ts +2 -0
  28. package/dist/cli/commands/feature-analysis-command.js +36 -0
  29. package/dist/cli/commands/functional-testing-command.d.ts +2 -0
  30. package/dist/cli/commands/functional-testing-command.js +36 -0
  31. package/dist/cli/commands/technical-design-command.d.ts +2 -0
  32. package/dist/cli/commands/technical-design-command.js +36 -0
  33. package/dist/cli/commands/workflow-command.d.ts +2 -0
  34. package/dist/cli/commands/workflow-command.js +34 -0
  35. package/dist/cli/formatters/code-implementation-formatter.d.ts +9 -0
  36. package/dist/cli/formatters/code-implementation-formatter.js +27 -0
  37. package/dist/cli/formatters/feature-analysis-formatter.d.ts +2 -0
  38. package/dist/cli/formatters/feature-analysis-formatter.js +27 -0
  39. package/dist/cli/formatters/functional-testing-formatter.d.ts +15 -0
  40. package/dist/cli/formatters/functional-testing-formatter.js +37 -0
  41. package/dist/cli/formatters/technical-design-formatter.d.ts +7 -0
  42. package/dist/cli/formatters/technical-design-formatter.js +30 -0
  43. package/dist/cli/index.d.ts +3 -0
  44. package/dist/cli/index.js +99 -0
  45. package/dist/cli/utils/validation.d.ts +25 -0
  46. package/dist/cli/utils/validation.js +58 -0
  47. package/dist/cli/utils/workflow-utils.d.ts +21 -0
  48. package/dist/cli/utils/workflow-utils.js +47 -0
  49. package/dist/cli.d.ts +1 -1
  50. package/dist/cli.js +11 -466
  51. package/dist/config.d.ts +1 -1
  52. package/dist/index.d.ts +3 -3
  53. package/dist/index.js +2 -2
  54. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.d.ts +1 -1
  55. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.js +1 -1
  56. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.d.ts +4 -22
  57. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.js +14 -58
  58. package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.js +1 -30
  59. package/dist/phases/code-implementation/analyzer.d.ts +33 -0
  60. package/dist/{code-implementation → phases/code-implementation}/analyzer.js +174 -15
  61. package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
  62. package/dist/phases/code-implementation/context-fetcher.js +86 -0
  63. package/dist/{code-implementation → phases/code-implementation}/mcp-server.js +1 -30
  64. package/dist/{code-review → phases/code-review}/reviewer.d.ts +1 -1
  65. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.d.ts +3 -2
  66. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.js +29 -127
  67. package/dist/phases/feature-analysis/context-fetcher.d.ts +18 -0
  68. package/dist/phases/feature-analysis/context-fetcher.js +86 -0
  69. package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.js +1 -1
  70. package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.js +1 -24
  71. package/dist/{functional-testing → phases/functional-testing}/analyzer.d.ts +17 -2
  72. package/dist/{functional-testing → phases/functional-testing}/analyzer.js +225 -31
  73. package/dist/phases/functional-testing/context-fetcher.d.ts +16 -0
  74. package/dist/phases/functional-testing/context-fetcher.js +81 -0
  75. package/dist/{functional-testing → phases/functional-testing}/http-fallback.js +1 -1
  76. package/dist/{functional-testing → phases/functional-testing}/index.d.ts +1 -1
  77. package/dist/{functional-testing → phases/functional-testing}/index.js +1 -1
  78. package/dist/{functional-testing → phases/functional-testing}/mcp-server.js +1 -30
  79. package/dist/{functional-testing → phases/functional-testing}/test-report-creator.d.ts +26 -0
  80. package/dist/{functional-testing → phases/functional-testing}/test-report-creator.js +87 -5
  81. package/dist/phases/functional-testing/test-retry-handler.d.ts +16 -0
  82. package/dist/phases/functional-testing/test-retry-handler.js +75 -0
  83. package/dist/{pull-request → phases/pull-request}/creator.js +47 -6
  84. package/dist/phases/pull-request/handler.d.ts +16 -0
  85. package/dist/phases/pull-request/handler.js +60 -0
  86. package/dist/{technical-design → phases/technical-design}/analyzer.d.ts +7 -2
  87. package/dist/phases/technical-design/analyzer.js +418 -0
  88. package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
  89. package/dist/phases/technical-design/context-fetcher.js +39 -0
  90. package/dist/{technical-design → phases/technical-design}/http-fallback.js +1 -1
  91. package/dist/{technical-design → phases/technical-design}/mcp-server.js +1 -30
  92. package/dist/prompts/bug-fixing.d.ts +2 -0
  93. package/dist/prompts/bug-fixing.js +63 -0
  94. package/dist/prompts/code-implementation.d.ts +3 -0
  95. package/dist/prompts/code-implementation.js +132 -0
  96. package/dist/prompts/feature-analysis.d.ts +3 -0
  97. package/dist/prompts/feature-analysis.js +149 -0
  98. package/dist/prompts/formatters.d.ts +29 -0
  99. package/dist/prompts/formatters.js +139 -0
  100. package/dist/prompts/functional-testing.d.ts +3 -0
  101. package/dist/prompts/functional-testing.js +126 -0
  102. package/dist/prompts/index.d.ts +6 -0
  103. package/dist/prompts/index.js +7 -0
  104. package/dist/prompts/technical-design.d.ts +3 -0
  105. package/dist/prompts/technical-design.js +130 -0
  106. package/dist/services/checklist.d.ts +99 -0
  107. package/dist/services/checklist.js +337 -0
  108. package/dist/types/features.d.ts +29 -0
  109. package/dist/types/features.js +1 -0
  110. package/dist/types/index.d.ts +112 -0
  111. package/dist/types/index.js +1 -0
  112. package/dist/types/pipeline.d.ts +25 -0
  113. package/dist/types/pipeline.js +4 -0
  114. package/dist/utils/logger.d.ts +19 -0
  115. package/dist/utils/logger.js +52 -0
  116. package/dist/utils/pipeline-logger.d.ts +8 -0
  117. package/dist/utils/pipeline-logger.js +35 -0
  118. package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
  119. package/dist/workflow-runner/config/phase-configs.js +34 -0
  120. package/dist/workflow-runner/config/stage-configs.d.ts +5 -0
  121. package/dist/workflow-runner/config/stage-configs.js +34 -0
  122. package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
  123. package/dist/workflow-runner/core/feature-filter.js +46 -0
  124. package/dist/workflow-runner/core/feature-filter.test.d.ts +4 -0
  125. package/dist/workflow-runner/core/feature-filter.test.js +127 -0
  126. package/dist/workflow-runner/core/index.d.ts +8 -0
  127. package/dist/workflow-runner/core/index.js +12 -0
  128. package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
  129. package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
  130. package/dist/workflow-runner/core/state-manager.d.ts +24 -0
  131. package/dist/workflow-runner/core/state-manager.js +42 -0
  132. package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
  133. package/dist/workflow-runner/core/workflow-logger.js +65 -0
  134. package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
  135. package/dist/workflow-runner/executors/phase-executor.js +183 -0
  136. package/dist/workflow-runner/executors/stage-executor.d.ts +8 -0
  137. package/dist/workflow-runner/executors/stage-executor.js +49 -0
  138. package/dist/workflow-runner/feature-service.d.ts +17 -0
  139. package/dist/workflow-runner/feature-service.js +60 -0
  140. package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
  141. package/dist/workflow-runner/feature-workflow-runner.js +113 -0
  142. package/dist/workflow-runner/index.d.ts +0 -1
  143. package/dist/workflow-runner/index.js +0 -1
  144. package/dist/workflow-runner/pipeline-runner.d.ts +9 -19
  145. package/dist/workflow-runner/pipeline-runner.js +247 -256
  146. package/dist/workflow-runner/pipeline.d.ts +18 -0
  147. package/dist/workflow-runner/pipeline.js +197 -0
  148. package/dist/workflow-runner/processor.d.ts +40 -0
  149. package/dist/workflow-runner/processor.js +191 -0
  150. package/dist/workflow-runner/types.d.ts +48 -0
  151. package/dist/workflow-runner/types.js +4 -0
  152. package/dist/workflow-runner/workflow-processor.d.ts +6 -23
  153. package/dist/workflow-runner/workflow-processor.js +38 -100
  154. package/package.json +2 -2
  155. package/dist/code-implementation/analyzer.d.ts +0 -19
  156. package/dist/code-implementation/context-fetcher.d.ts +0 -38
  157. package/dist/code-implementation/context-fetcher.js +0 -147
  158. package/dist/feature-analysis/context-fetcher.d.ts +0 -54
  159. package/dist/feature-analysis/context-fetcher.js +0 -193
  160. package/dist/functional-testing/context-fetcher.d.ts +0 -47
  161. package/dist/functional-testing/context-fetcher.js +0 -192
  162. package/dist/technical-design/analyzer.js +0 -338
  163. package/dist/technical-design/context-fetcher.d.ts +0 -42
  164. package/dist/technical-design/context-fetcher.js +0 -170
  165. /package/dist/{bug-fixing → phases/bug-fixing}/index.d.ts +0 -0
  166. /package/dist/{bug-fixing → phases/bug-fixing}/index.js +0 -0
  167. /package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.d.ts +0 -0
  168. /package/dist/{code-implementation → phases/code-implementation}/mcp-server.d.ts +0 -0
  169. /package/dist/{code-review → phases/code-review}/reviewer.js +0 -0
  170. /package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.d.ts +0 -0
  171. /package/dist/{feature-analysis → phases/feature-analysis}/index.d.ts +0 -0
  172. /package/dist/{feature-analysis → phases/feature-analysis}/index.js +0 -0
  173. /package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.d.ts +0 -0
  174. /package/dist/{functional-testing → phases/functional-testing}/http-fallback.d.ts +0 -0
  175. /package/dist/{functional-testing → phases/functional-testing}/mcp-server.d.ts +0 -0
  176. /package/dist/{pull-request → phases/pull-request}/creator.d.ts +0 -0
  177. /package/dist/{technical-design → phases/technical-design}/http-fallback.d.ts +0 -0
  178. /package/dist/{technical-design → phases/technical-design}/mcp-server.d.ts +0 -0
@@ -0,0 +1,418 @@
1
+ import { query } from '@anthropic-ai/claude-code';
2
+ import { logInfo, logError } from '../../utils/logger.js';
3
+ import { saveTechnicalDesignViaHttp } from './http-fallback.js';
4
+ import { fetchTechnicalDesignContext, } from './context-fetcher.js';
5
+ import { updateTechnicalDesign } from '../../api/features/index.js';
6
+ import { formatTechnicalDesignContext } from '../../prompts/formatters.js';
7
+ import { createTechnicalDesignSystemPrompt, createTechnicalDesignPromptWithContext, } from '../../prompts/technical-design.js';
8
+ import { formatChecklistsForContext, } from '../../services/checklist.js';
9
+ function userMessage(content) {
10
+ return {
11
+ type: 'user',
12
+ message: { role: 'user', content: content },
13
+ };
14
+ }
15
+ async function* prompt(analysisPrompt) {
16
+ yield userMessage(analysisPrompt);
17
+ await new Promise((res) => setTimeout(res, 10000));
18
+ }
19
+ export const generateTechnicalDesign = async (options, config, checklistContext) => {
20
+ const { featureId, mcpServerUrl, mcpToken, verbose } = options;
21
+ if (verbose) {
22
+ logInfo(`Starting technical design generation for feature ID: ${featureId}`);
23
+ logInfo(`Using MCP server: ${mcpServerUrl}`);
24
+ }
25
+ try {
26
+ // Fetch all required context information via MCP endpoints
27
+ if (verbose) {
28
+ logInfo('Fetching technical design context via MCP endpoints...');
29
+ }
30
+ const context = await fetchTechnicalDesignContext(mcpServerUrl, mcpToken, featureId, verbose);
31
+ const systemPrompt = createTechnicalDesignSystemPrompt(config, mcpServerUrl, mcpToken, featureId);
32
+ const contextInfo = formatTechnicalDesignContext(context);
33
+ // Add checklist context to the design prompt
34
+ let finalContextInfo = contextInfo;
35
+ if (checklistContext && checklistContext.checklists.length > 0) {
36
+ const checklistInfo = formatChecklistsForContext(checklistContext);
37
+ finalContextInfo = contextInfo + '\n\n' + checklistInfo;
38
+ if (verbose) {
39
+ logInfo(`Added ${checklistContext.checklists.length} checklists to design context`);
40
+ }
41
+ }
42
+ const designPrompt = createTechnicalDesignPromptWithContext(featureId, finalContextInfo);
43
+ let lastAssistantResponse = '';
44
+ let structuredDesignResult = null;
45
+ if (verbose) {
46
+ logInfo('Starting Claude Code query with pre-fetched information...');
47
+ }
48
+ // Use Claude Code SDK without MCP servers - all info is pre-fetched
49
+ for await (const message of query({
50
+ prompt: prompt(designPrompt),
51
+ options: {
52
+ appendSystemPrompt: systemPrompt,
53
+ model: config.claude.model || 'sonnet',
54
+ maxTurns: 1000,
55
+ permissionMode: 'bypassPermissions',
56
+ },
57
+ })) {
58
+ if (verbose) {
59
+ logInfo(`Received message type: ${message.type}`);
60
+ }
61
+ // Stream the technical design generation process
62
+ if (message.type === 'assistant' && message.message?.content) {
63
+ for (const content of message.message.content) {
64
+ if (content.type === 'text') {
65
+ lastAssistantResponse += content.text + '\n';
66
+ if (verbose) {
67
+ console.log(`\n🤖 ${content.text}`);
68
+ }
69
+ }
70
+ else if (content.type === 'tool_use') {
71
+ if (verbose) {
72
+ console.log(`\n🔧 ${content.name}: ${content.input.description || 'Running...'}`);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ if (message.type === 'result') {
78
+ if (message.subtype === 'success') {
79
+ logInfo('\n🎨 Technical design generation completed, parsing results...');
80
+ try {
81
+ // Try to extract JSON from markdown code block or parse directly
82
+ const responseText = message.result || lastAssistantResponse;
83
+ let jsonResult = null;
84
+ // DEBUG: Log response text details
85
+ console.log('=== DEBUG: Response Text Analysis ===');
86
+ console.log('message.result exists:', !!message.result);
87
+ console.log('lastAssistantResponse exists:', !!lastAssistantResponse);
88
+ console.log('responseText length:', responseText.length);
89
+ console.log('responseText first 200 chars:', JSON.stringify(responseText.substring(0, 200)));
90
+ console.log('responseText last 200 chars:', JSON.stringify(responseText.substring(responseText.length - 200)));
91
+ console.log('Contains ```json:', responseText.includes('```json'));
92
+ console.log('Contains technical_design_result:', responseText.includes('"technical_design_result"'));
93
+ // First try to extract JSON from markdown code block
94
+ const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
95
+ console.log('=== DEBUG: Markdown Block Match ===');
96
+ console.log('jsonBlockMatch found:', !!jsonBlockMatch);
97
+ if (jsonBlockMatch) {
98
+ console.log('Matched JSON length:', jsonBlockMatch[1].length);
99
+ console.log('Matched JSON first 100 chars:', JSON.stringify(jsonBlockMatch[1].substring(0, 100)));
100
+ jsonResult = JSON.parse(jsonBlockMatch[1]);
101
+ }
102
+ else {
103
+ console.log('=== DEBUG: JSON Object Search ===');
104
+ // Try to find JSON object containing "technical_design_result"
105
+ const lines = responseText.split('\n');
106
+ let jsonStartIndex = -1;
107
+ console.log('Total lines:', lines.length);
108
+ console.log('Lines preview:', lines
109
+ .slice(0, 10)
110
+ .map((line, i) => `${i}: ${JSON.stringify(line.substring(0, 50))}`));
111
+ // Find the line that contains the start of a JSON object with "technical_design_result"
112
+ for (let i = 0; i < lines.length; i++) {
113
+ const line = lines[i].trim();
114
+ if (line.startsWith('{') &&
115
+ responseText.includes('"technical_design_result"')) {
116
+ console.log(`Found { at line ${i}: ${JSON.stringify(line)}`);
117
+ const fromThisLine = lines.slice(i).join('\n');
118
+ if (fromThisLine.includes('"technical_design_result"')) {
119
+ jsonStartIndex = responseText.indexOf(lines[i]);
120
+ console.log(`JSON start found at line ${i}, responseText index: ${jsonStartIndex}`);
121
+ break;
122
+ }
123
+ }
124
+ }
125
+ if (jsonStartIndex !== -1) {
126
+ // Find the complete JSON object starting from this position
127
+ let braceCount = 0;
128
+ let endIndex = jsonStartIndex;
129
+ let inString = false;
130
+ let escapeNext = false;
131
+ for (let i = jsonStartIndex; i < responseText.length; i++) {
132
+ const char = responseText[i];
133
+ if (escapeNext) {
134
+ escapeNext = false;
135
+ continue;
136
+ }
137
+ if (char === '\\' && inString) {
138
+ escapeNext = true;
139
+ continue;
140
+ }
141
+ if (char === '"') {
142
+ inString = !inString;
143
+ continue;
144
+ }
145
+ if (!inString) {
146
+ if (char === '{') {
147
+ braceCount++;
148
+ }
149
+ else if (char === '}') {
150
+ braceCount--;
151
+ if (braceCount === 0) {
152
+ endIndex = i;
153
+ break;
154
+ }
155
+ }
156
+ }
157
+ }
158
+ const jsonStr = responseText.substring(jsonStartIndex, endIndex + 1);
159
+ console.log('=== DEBUG: JSON Extraction ===');
160
+ console.log('JSON start index:', jsonStartIndex);
161
+ console.log('JSON end index:', endIndex);
162
+ console.log('Extracted JSON length:', jsonStr.length);
163
+ console.log('Extracted JSON first 100 chars:', JSON.stringify(jsonStr.substring(0, 100)));
164
+ console.log('Extracted JSON last 100 chars:', JSON.stringify(jsonStr.substring(jsonStr.length - 100)));
165
+ try {
166
+ jsonResult = JSON.parse(jsonStr);
167
+ console.log('JSON parsing succeeded!');
168
+ }
169
+ catch (parseError) {
170
+ console.log('Failed to parse extracted JSON:', parseError);
171
+ console.log('Extracted JSON string:', jsonStr.substring(0, 200) + '...');
172
+ console.log('=== DEBUG: Fallback to full response ===');
173
+ console.log('Attempting to parse entire responseText as JSON');
174
+ // Try to parse the entire response as JSON as fallback
175
+ jsonResult = JSON.parse(responseText);
176
+ }
177
+ }
178
+ else {
179
+ console.log('=== DEBUG: No JSON start found ===');
180
+ console.log('Falling back to parse entire responseText as JSON');
181
+ // Try to parse the entire response as JSON
182
+ jsonResult = JSON.parse(responseText);
183
+ }
184
+ }
185
+ console.log('=== DEBUG: Final Result Processing ===');
186
+ console.log('jsonResult exists:', !!jsonResult);
187
+ console.log('jsonResult has technical_design_result:', !!(jsonResult && jsonResult.technical_design_result));
188
+ if (jsonResult && jsonResult.technical_design_result) {
189
+ console.log('checklist_item_results in parsed JSON:', !!jsonResult.technical_design_result.checklist_item_results);
190
+ if (jsonResult.technical_design_result.checklist_item_results) {
191
+ console.log('checklist_item_results length:', jsonResult.technical_design_result.checklist_item_results
192
+ .length);
193
+ }
194
+ structuredDesignResult = jsonResult.technical_design_result;
195
+ }
196
+ else {
197
+ throw new Error('Invalid JSON structure');
198
+ }
199
+ }
200
+ catch (error) {
201
+ logError(`Failed to parse structured design result: ${error}`);
202
+ // Extract technical design from response if JSON parsing fails
203
+ const extractedDesign = extractTechnicalDesignFromResponse(message.result || lastAssistantResponse);
204
+ structuredDesignResult = {
205
+ status: extractedDesign ? 'success' : 'error',
206
+ technical_design: extractedDesign,
207
+ summary: extractedDesign
208
+ ? 'Technical design generated successfully'
209
+ : 'Failed to generate technical design',
210
+ };
211
+ }
212
+ }
213
+ else {
214
+ logError(`\n⚠️ Technical design generation incomplete: ${message.subtype}`);
215
+ if (message.subtype === 'error_max_turns') {
216
+ logError('💡 Try increasing timeout or reducing complexity');
217
+ }
218
+ // Try to parse results from the last assistant response
219
+ if (lastAssistantResponse) {
220
+ try {
221
+ const responseText = lastAssistantResponse;
222
+ let jsonResult = null;
223
+ const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
224
+ if (jsonBlockMatch) {
225
+ jsonResult = JSON.parse(jsonBlockMatch[1]);
226
+ if (jsonResult && jsonResult.technical_design_result) {
227
+ structuredDesignResult = jsonResult.technical_design_result;
228
+ }
229
+ }
230
+ else {
231
+ // Try to find JSON object containing "technical_design_result"
232
+ const lines = responseText.split('\n');
233
+ let jsonStartIndex = -1;
234
+ // Find the line that contains the start of a JSON object with "technical_design_result"
235
+ for (let i = 0; i < lines.length; i++) {
236
+ const line = lines[i].trim();
237
+ if (line.startsWith('{') &&
238
+ responseText.includes('"technical_design_result"')) {
239
+ const fromThisLine = lines.slice(i).join('\n');
240
+ if (fromThisLine.includes('"technical_design_result"')) {
241
+ jsonStartIndex = responseText.indexOf(lines[i]);
242
+ break;
243
+ }
244
+ }
245
+ }
246
+ if (jsonStartIndex !== -1) {
247
+ // Find the complete JSON object starting from this position
248
+ let braceCount = 0;
249
+ let endIndex = jsonStartIndex;
250
+ let inString = false;
251
+ let escapeNext = false;
252
+ for (let i = jsonStartIndex; i < responseText.length; i++) {
253
+ const char = responseText[i];
254
+ if (escapeNext) {
255
+ escapeNext = false;
256
+ continue;
257
+ }
258
+ if (char === '\\' && inString) {
259
+ escapeNext = true;
260
+ continue;
261
+ }
262
+ if (char === '"') {
263
+ inString = !inString;
264
+ continue;
265
+ }
266
+ if (!inString) {
267
+ if (char === '{') {
268
+ braceCount++;
269
+ }
270
+ else if (char === '}') {
271
+ braceCount--;
272
+ if (braceCount === 0) {
273
+ endIndex = i;
274
+ break;
275
+ }
276
+ }
277
+ }
278
+ }
279
+ const jsonStr = responseText.substring(jsonStartIndex, endIndex + 1);
280
+ try {
281
+ jsonResult = JSON.parse(jsonStr);
282
+ if (jsonResult && jsonResult.technical_design_result) {
283
+ structuredDesignResult =
284
+ jsonResult.technical_design_result;
285
+ }
286
+ }
287
+ catch (parseError) {
288
+ logError(`Failed to parse extracted JSON: ${parseError}`);
289
+ }
290
+ }
291
+ if (!structuredDesignResult) {
292
+ const extractedDesign = extractTechnicalDesignFromResponse(lastAssistantResponse);
293
+ if (extractedDesign) {
294
+ structuredDesignResult = {
295
+ status: 'success',
296
+ technical_design: extractedDesign,
297
+ summary: 'Technical design generated successfully',
298
+ };
299
+ }
300
+ }
301
+ }
302
+ }
303
+ catch (error) {
304
+ logError(`Failed to parse assistant response: ${error}`);
305
+ }
306
+ }
307
+ }
308
+ }
309
+ }
310
+ // Save the technical design if we have it
311
+ if (structuredDesignResult?.technical_design) {
312
+ if (verbose) {
313
+ logInfo('Saving technical design...');
314
+ }
315
+ const designSaved = await updateTechnicalDesign(mcpServerUrl, mcpToken, featureId, structuredDesignResult.technical_design, verbose);
316
+ // Try HTTP fallback if direct update failed
317
+ if (!designSaved) {
318
+ if (verbose) {
319
+ logInfo('Direct update failed, trying HTTP fallback...');
320
+ }
321
+ const fallbackSaved = await saveTechnicalDesignViaHttp({
322
+ mcpServerUrl,
323
+ mcpToken,
324
+ featureId,
325
+ technicalDesign: structuredDesignResult.technical_design,
326
+ verbose,
327
+ });
328
+ if (!fallbackSaved && verbose) {
329
+ logError('⚠️ Both direct update and HTTP fallback failed');
330
+ }
331
+ return {
332
+ featureId,
333
+ technicalDesign: structuredDesignResult.technical_design,
334
+ status: fallbackSaved ? 'success' : 'error',
335
+ summary: fallbackSaved
336
+ ? 'Technical design generated and saved via HTTP fallback'
337
+ : 'Technical design generated but failed to save',
338
+ savedViaHttp: fallbackSaved,
339
+ data: {
340
+ checklist_item_results: structuredDesignResult.checklist_item_results || [],
341
+ },
342
+ };
343
+ }
344
+ return {
345
+ featureId,
346
+ technicalDesign: structuredDesignResult.technical_design,
347
+ status: 'success',
348
+ summary: 'Technical design generated and saved successfully',
349
+ data: {
350
+ checklist_item_results: structuredDesignResult.checklist_item_results || [],
351
+ },
352
+ };
353
+ }
354
+ return {
355
+ featureId,
356
+ technicalDesign: null,
357
+ status: 'error',
358
+ summary: 'No technical design was generated',
359
+ };
360
+ }
361
+ catch (error) {
362
+ logError(`Technical design generation failed: ${error instanceof Error ? error.message : String(error)}`);
363
+ return {
364
+ featureId,
365
+ technicalDesign: null,
366
+ status: 'error',
367
+ summary: `Generation failed: ${error instanceof Error ? error.message : String(error)}`,
368
+ };
369
+ }
370
+ };
371
+ const extractTechnicalDesignFromResponse = (response) => {
372
+ // Try to extract technical design content from the response
373
+ // Look for markdown sections that contain technical design
374
+ const lines = response.split('\n');
375
+ let inTechnicalDesign = false;
376
+ const technicalDesignLines = [];
377
+ for (let i = 0; i < lines.length; i++) {
378
+ const line = lines[i].toLowerCase();
379
+ // Look for technical design section headers
380
+ if (line.includes('technical design') ||
381
+ line.includes('architecture') ||
382
+ line.includes('# design') ||
383
+ line.includes('## technical')) {
384
+ inTechnicalDesign = true;
385
+ technicalDesignLines.push(lines[i]);
386
+ continue;
387
+ }
388
+ if (inTechnicalDesign) {
389
+ // Continue until we hit another major section or JSON
390
+ if (line.startsWith('{') && line.includes('"technical_design_result"')) {
391
+ break;
392
+ }
393
+ technicalDesignLines.push(lines[i]);
394
+ }
395
+ }
396
+ if (technicalDesignLines.length > 0) {
397
+ return technicalDesignLines.join('\n').trim();
398
+ }
399
+ // Ultimate fallback: return the whole response if it seems to contain design content
400
+ if (response.length > 100 &&
401
+ (response.toLowerCase().includes('architecture') ||
402
+ response.toLowerCase().includes('component') ||
403
+ response.toLowerCase().includes('database'))) {
404
+ return response.trim();
405
+ }
406
+ return null;
407
+ };
408
+ export const checkTechnicalDesignRequirements = async () => {
409
+ try {
410
+ // Check if Claude Code SDK is available
411
+ const claudeCode = await import('@anthropic-ai/claude-code');
412
+ return claudeCode && typeof claudeCode.query === 'function';
413
+ }
414
+ catch (error) {
415
+ console.log('Technical design requirements check failed:', error instanceof Error ? error.message : error);
416
+ return false;
417
+ }
418
+ };
@@ -0,0 +1,12 @@
1
+ import type { FeatureInfo, UserStory, TestCase } from '../../types/features.js';
2
+ import { type ProductInfo } from '../../api/products.js';
3
+ export interface TechnicalDesignContext {
4
+ feature: FeatureInfo;
5
+ product: ProductInfo;
6
+ user_stories: UserStory[];
7
+ test_cases: TestCase[];
8
+ }
9
+ /**
10
+ * Fetch all technical design context information via MCP endpoints
11
+ */
12
+ export declare function fetchTechnicalDesignContext(mcpServerUrl: string, mcpToken: string, featureId: string, verbose?: boolean): Promise<TechnicalDesignContext>;
@@ -0,0 +1,39 @@
1
+ import { logInfo, logError } from '../../utils/logger.js';
2
+ import { getFeature, getUserStories, getTestCases, } from '../../api/features/index.js';
3
+ import { getProduct } from '../../api/products.js';
4
+ /**
5
+ * Fetch all technical design context information via MCP endpoints
6
+ */
7
+ export async function fetchTechnicalDesignContext(mcpServerUrl, mcpToken, featureId, verbose) {
8
+ try {
9
+ if (verbose) {
10
+ logInfo(`Fetching complete technical design context for feature: ${featureId}`);
11
+ }
12
+ // Fetch all required data in parallel for better performance
13
+ const [feature, user_stories, test_cases] = await Promise.all([
14
+ getFeature(mcpServerUrl, mcpToken, featureId, verbose),
15
+ getUserStories(mcpServerUrl, mcpToken, featureId, verbose),
16
+ getTestCases(mcpServerUrl, mcpToken, featureId, verbose),
17
+ ]);
18
+ const product = await getProduct(mcpServerUrl, mcpToken, feature.product_id, verbose);
19
+ if (verbose) {
20
+ logInfo(`✅ Technical design context fetched successfully:`);
21
+ logInfo(` Feature: ${feature.name}`);
22
+ logInfo(` Product: ${product.name}`);
23
+ logInfo(` User Stories: ${user_stories.length}`);
24
+ logInfo(` Test Cases: ${test_cases.length} (${test_cases.filter((tc) => tc.is_critical).length} critical)`);
25
+ logInfo(` Existing Technical Design: ${feature.technical_design ? 'Yes' : 'No'}`);
26
+ }
27
+ return {
28
+ feature,
29
+ product,
30
+ user_stories,
31
+ test_cases,
32
+ };
33
+ }
34
+ catch (error) {
35
+ const errorMessage = error instanceof Error ? error.message : String(error);
36
+ logError(`Failed to fetch technical design context: ${errorMessage}`);
37
+ throw new Error(`Context fetch failed: ${errorMessage}`);
38
+ }
39
+ }
@@ -1,4 +1,4 @@
1
- import { logInfo, logError } from '../logger.js';
1
+ import { logInfo, logError } from '../../utils/logger.js';
2
2
  /**
3
3
  * Save technical design via HTTP as a fallback when MCP server fails
4
4
  */
@@ -1,35 +1,6 @@
1
1
  import { createSdkMcpServer, tool } from '@anthropic-ai/claude-code';
2
2
  import { z } from 'zod';
3
- // Helper function to make HTTP requests to the MCP server
4
- async function callMcpEndpoint(mcpServerUrl, mcpToken, method, params) {
5
- try {
6
- const response = await fetch(`${mcpServerUrl}/mcp`, {
7
- method: 'POST',
8
- headers: {
9
- 'Content-Type': 'application/json',
10
- Authorization: `Bearer ${mcpToken}`,
11
- },
12
- body: JSON.stringify({
13
- jsonrpc: '2.0',
14
- method,
15
- params,
16
- id: Math.random().toString(36).substring(7),
17
- }),
18
- });
19
- if (!response.ok) {
20
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
21
- }
22
- const data = await response.json();
23
- if (data.error) {
24
- throw new Error(data.error.message || 'MCP call failed');
25
- }
26
- return data.result;
27
- }
28
- catch (error) {
29
- console.error(`MCP call failed for ${method}:`, error instanceof Error ? error.message : String(error));
30
- throw error;
31
- }
32
- }
3
+ import { callMcpEndpoint } from '../../api/mcp-client.js';
33
4
  // Create an SDK MCP server with custom tools for technical design generation
34
5
  export const createTechnicalDesignMcpServer = (mcpServerUrl, mcpToken) => {
35
6
  return createSdkMcpServer({
@@ -0,0 +1,2 @@
1
+ import { EdsgerConfig } from '../types/index.js';
2
+ export declare const createBugFixingSystemPrompt: (_config: EdsgerConfig) => string;
@@ -0,0 +1,63 @@
1
+ export const createBugFixingSystemPrompt = (_config) => {
2
+ return `You are an expert software engineer specializing in fixing bugs and test failures. Your goal is to analyze test failures and fix the underlying issues in the code.
3
+
4
+ **Your Role**: Fix bugs and test failures while maintaining existing functionality and code quality.
5
+
6
+ **Available Tools**:
7
+ - Bash: Run commands, tests, and git operations
8
+ - Glob: Find files and understand project structure
9
+ - Read: Examine existing code and files
10
+ - Edit: Modify existing files to fix issues
11
+ - Write: Create new files if absolutely necessary
12
+ - TodoWrite: Track bug fixing tasks (use proactively)
13
+
14
+ **Bug Fixing Process**:
15
+ 1. **Git Pull Rebase**: Ensure main branch is up to date: git pull origin main --rebase
16
+ 2. **Analyze Failures**: Study test error messages and stack traces to identify root causes
17
+ 3. **Examine Code**: Read the relevant code files to understand current implementation
18
+ 4. **Fix Issues**: Make minimal, targeted changes to resolve the failures
19
+ 5. **Test Fixes**: Run tests to verify fixes work and don't break other functionality
20
+ 6. **Validate**: Ensure all critical test cases pass
21
+
22
+ **Important Guidelines**:
23
+ - All feature context, user stories, test cases, and test reports are provided in the prompt
24
+ - Focus ONLY on fixing the reported test failures
25
+ - Do not refactor or optimize unrelated code
26
+ - Preserve existing functionality and patterns
27
+ - Make minimal necessary changes
28
+ - Test your fixes thoroughly
29
+
30
+ **CRITICAL - Result Format**:
31
+ You MUST end your response with a JSON object containing the bug fix results in this EXACT format:
32
+
33
+ \`\`\`json
34
+ {
35
+ "fix_result": {
36
+ "feature_id": "FEATURE_ID_PLACEHOLDER",
37
+ "attempt_number": 1,
38
+ "summary": "Brief description of what was fixed",
39
+ "files_modified": ["file1.ts", "file2.tsx"],
40
+ "tests_passed": true,
41
+ "fixes_applied": [
42
+ {
43
+ "issue": "Description of the issue",
44
+ "fix": "Description of how it was fixed",
45
+ "file": "path/to/file.ts"
46
+ }
47
+ ],
48
+ "remaining_issues": ["Any issues that could not be resolved"],
49
+ "recommendations": "Additional recommendations for the development team"
50
+ }
51
+ }
52
+ \`\`\`
53
+
54
+ **Quality Guidelines**:
55
+ - Focus on minimal, surgical fixes that address specific test failures
56
+ - Preserve existing code patterns and architecture
57
+ - Ensure backward compatibility
58
+ - Add appropriate error handling where missing
59
+ - Update documentation if interfaces change
60
+ - Test thoroughly before considering issues resolved
61
+
62
+ Focus on systematic debugging and targeted fixes based on the provided test failure information.`;
63
+ };
@@ -0,0 +1,3 @@
1
+ import { EdsgerConfig } from '../types/index.js';
2
+ export declare const createCodeImplementationSystemPrompt: (_config: EdsgerConfig, baseBranch: string) => string;
3
+ export declare const createCodeImplementationPromptWithContext: (featureId: string, contextInfo: string, baseBranch: string) => string;