edsger 0.2.2 → 0.2.4

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 (87) hide show
  1. package/README.md +17 -0
  2. package/dist/api/features/batch-operations.d.ts +16 -0
  3. package/dist/api/features/batch-operations.js +100 -0
  4. package/dist/api/features/index.d.ts +1 -0
  5. package/dist/api/features/index.js +1 -0
  6. package/dist/api/features/test-cases.d.ts +8 -0
  7. package/dist/api/features/test-cases.js +45 -0
  8. package/dist/api/features/user-stories.d.ts +8 -0
  9. package/dist/api/features/user-stories.js +45 -0
  10. package/dist/cli/commands/refactor-command.d.ts +2 -0
  11. package/dist/cli/commands/refactor-command.js +107 -0
  12. package/dist/cli/index.js +7 -0
  13. package/dist/cli.d.ts +2 -2
  14. package/dist/cli.js +4 -99
  15. package/dist/phases/code-implementation/analyzer-helpers.d.ts +28 -0
  16. package/dist/phases/code-implementation/analyzer-helpers.js +177 -0
  17. package/dist/phases/code-implementation/analyzer.d.ts +2 -0
  18. package/dist/phases/code-implementation/analyzer.js +308 -179
  19. package/dist/phases/code-implementation-verification/index.d.ts +1 -0
  20. package/dist/phases/code-implementation-verification/index.js +1 -0
  21. package/dist/phases/code-implementation-verification/verifier.d.ts +31 -0
  22. package/dist/phases/code-implementation-verification/verifier.js +196 -0
  23. package/dist/phases/feature-analysis/analyzer-helpers.d.ts +62 -0
  24. package/dist/phases/feature-analysis/analyzer-helpers.js +450 -0
  25. package/dist/phases/feature-analysis/analyzer.d.ts +1 -0
  26. package/dist/phases/feature-analysis/analyzer.js +132 -213
  27. package/dist/phases/feature-analysis-verification/index.d.ts +1 -0
  28. package/dist/phases/feature-analysis-verification/index.js +1 -0
  29. package/dist/phases/feature-analysis-verification/verifier.d.ts +37 -0
  30. package/dist/phases/feature-analysis-verification/verifier.js +147 -0
  31. package/dist/phases/pull-request/creator.js +10 -9
  32. package/dist/phases/technical-design/analyzer-helpers.d.ts +37 -0
  33. package/dist/phases/technical-design/analyzer-helpers.js +144 -0
  34. package/dist/phases/technical-design/analyzer.d.ts +3 -0
  35. package/dist/phases/technical-design/analyzer.js +282 -312
  36. package/dist/phases/technical-design-verification/index.d.ts +1 -0
  37. package/dist/phases/technical-design-verification/index.js +1 -0
  38. package/dist/phases/technical-design-verification/verifier.d.ts +36 -0
  39. package/dist/phases/technical-design-verification/verifier.js +147 -0
  40. package/dist/prompts/checklist-verification.d.ts +11 -0
  41. package/dist/prompts/checklist-verification.js +153 -0
  42. package/dist/prompts/code-implementation-improvement.d.ts +5 -0
  43. package/dist/prompts/code-implementation-improvement.js +108 -0
  44. package/dist/prompts/code-implementation-verification.d.ts +3 -0
  45. package/dist/prompts/code-implementation-verification.js +176 -0
  46. package/dist/prompts/feature-analysis-improvement.d.ts +8 -0
  47. package/dist/prompts/feature-analysis-improvement.js +109 -0
  48. package/dist/prompts/feature-analysis.js +1 -1
  49. package/dist/prompts/formatters.d.ts +17 -4
  50. package/dist/prompts/formatters.js +41 -12
  51. package/dist/prompts/technical-design-improvement.d.ts +5 -0
  52. package/dist/prompts/technical-design-improvement.js +93 -0
  53. package/dist/prompts/technical-design-verification.d.ts +11 -0
  54. package/dist/prompts/technical-design-verification.js +134 -0
  55. package/dist/prompts/technical-design.js +1 -1
  56. package/dist/services/audit-logs.d.ts +60 -0
  57. package/dist/services/audit-logs.js +115 -0
  58. package/dist/services/checklist.d.ts +1 -0
  59. package/dist/types/index.d.ts +19 -0
  60. package/dist/utils/image-downloader.d.ts +32 -0
  61. package/dist/utils/image-downloader.js +144 -0
  62. package/dist/workflow-runner/executors/phase-executor.js +56 -12
  63. package/package.json +1 -1
  64. package/dist/api/features.d.ts +0 -100
  65. package/dist/api/features.js +0 -219
  66. package/dist/logger.d.ts +0 -19
  67. package/dist/logger.js +0 -52
  68. package/dist/types.d.ts +0 -99
  69. package/dist/types.js +0 -1
  70. package/dist/workflow-runner/config/stage-configs.d.ts +0 -5
  71. package/dist/workflow-runner/config/stage-configs.js +0 -34
  72. package/dist/workflow-runner/core/feature-filter.test.d.ts +0 -4
  73. package/dist/workflow-runner/core/feature-filter.test.js +0 -127
  74. package/dist/workflow-runner/executors/stage-executor.d.ts +0 -8
  75. package/dist/workflow-runner/executors/stage-executor.js +0 -49
  76. package/dist/workflow-runner/feature-fetcher.d.ts +0 -41
  77. package/dist/workflow-runner/feature-fetcher.js +0 -121
  78. package/dist/workflow-runner/feature-service.d.ts +0 -17
  79. package/dist/workflow-runner/feature-service.js +0 -60
  80. package/dist/workflow-runner/pipeline.d.ts +0 -18
  81. package/dist/workflow-runner/pipeline.js +0 -197
  82. package/dist/workflow-runner/processor.d.ts +0 -40
  83. package/dist/workflow-runner/processor.js +0 -191
  84. package/dist/workflow-runner/status-updater.d.ts +0 -27
  85. package/dist/workflow-runner/status-updater.js +0 -80
  86. package/dist/workflow-runner/types.d.ts +0 -48
  87. package/dist/workflow-runner/types.js +0 -4
@@ -0,0 +1,450 @@
1
+ /**
2
+ * Helper functions for feature analysis
3
+ * Extracted from analyzer.ts to improve modularity and testability
4
+ */
5
+ import { query } from '@anthropic-ai/claude-code';
6
+ import { logInfo, logError } from '../../utils/logger.js';
7
+ import { saveDataViaHttp } from './http-fallback.js';
8
+ import { createUserStories, createTestCases, batchUpdateUserStoryStatus, batchUpdateTestCaseStatus, batchDeleteUserStories, batchDeleteTestCases, } from '../../api/features/index.js';
9
+ import { callMcpEndpoint } from '../../api/mcp-client.js';
10
+ import { verifyChecklistCompliance, } from '../feature-analysis-verification/index.js';
11
+ import { createImprovementPrompt } from '../../prompts/feature-analysis-improvement.js';
12
+ import { logFeatureVerificationEvent } from '../../services/audit-logs.js';
13
+ function userMessage(content) {
14
+ return {
15
+ type: 'user',
16
+ message: { role: 'user', content: content },
17
+ };
18
+ }
19
+ async function* prompt(analysisPrompt) {
20
+ yield userMessage(analysisPrompt);
21
+ }
22
+ /**
23
+ * Parse JSON result from Claude Code response
24
+ */
25
+ export function parseAnalysisResult(responseText) {
26
+ try {
27
+ let jsonResult = null;
28
+ // First try to extract JSON from markdown code block
29
+ const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
30
+ if (jsonBlockMatch) {
31
+ jsonResult = JSON.parse(jsonBlockMatch[1]);
32
+ }
33
+ else {
34
+ // Try to parse the entire response as JSON
35
+ jsonResult = JSON.parse(responseText);
36
+ }
37
+ if (jsonResult && jsonResult.analysis) {
38
+ return { analysis: jsonResult.analysis };
39
+ }
40
+ else {
41
+ return { error: 'Invalid JSON structure' };
42
+ }
43
+ }
44
+ catch (error) {
45
+ return {
46
+ error: `JSON parsing failed: ${error instanceof Error ? error.message : String(error)}`,
47
+ };
48
+ }
49
+ }
50
+ /**
51
+ * Execute a single analysis query
52
+ */
53
+ export async function executeAnalysisQuery(currentPrompt, systemPrompt, config, verbose) {
54
+ let lastAssistantResponse = '';
55
+ let structuredAnalysisResult = null;
56
+ for await (const message of query({
57
+ prompt: prompt(currentPrompt),
58
+ options: {
59
+ appendSystemPrompt: systemPrompt,
60
+ model: config.claude.model || 'sonnet',
61
+ maxTurns: 1000,
62
+ permissionMode: 'bypassPermissions',
63
+ },
64
+ })) {
65
+ if (verbose) {
66
+ logInfo(`Received message type: ${message.type}`);
67
+ }
68
+ // Stream the analysis process and capture assistant responses
69
+ if (message.type === 'assistant' && message.message?.content) {
70
+ for (const content of message.message.content) {
71
+ if (content.type === 'text') {
72
+ lastAssistantResponse += content.text + '\n';
73
+ if (verbose) {
74
+ console.log(`\n🤖 ${content.text}`);
75
+ }
76
+ }
77
+ else if (content.type === 'tool_use') {
78
+ if (verbose) {
79
+ console.log(`\n🔧 ${content.name}: ${content.input.description || 'Running...'}`);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ if (message.type === 'result') {
85
+ if (message.subtype === 'success') {
86
+ logInfo('\n📊 Feature analysis completed, parsing results...');
87
+ const responseText = message.result || lastAssistantResponse;
88
+ const parsed = parseAnalysisResult(responseText);
89
+ if (parsed.error) {
90
+ logError(`Failed to parse structured analysis result: ${parsed.error}`);
91
+ structuredAnalysisResult = {
92
+ status: 'error',
93
+ summary: 'Failed to parse analysis results from Claude Code response',
94
+ created_user_stories: [],
95
+ created_test_cases: [],
96
+ };
97
+ }
98
+ else {
99
+ structuredAnalysisResult = parsed.analysis;
100
+ }
101
+ }
102
+ else {
103
+ logError(`\n⚠️ Analysis incomplete: ${message.subtype}`);
104
+ if (message.subtype === 'error_max_turns') {
105
+ logError('💡 Try increasing timeout or reducing complexity');
106
+ }
107
+ // Try to parse results from the last assistant response
108
+ if (lastAssistantResponse) {
109
+ const parsed = parseAnalysisResult(lastAssistantResponse);
110
+ if (!parsed.error) {
111
+ structuredAnalysisResult = parsed.analysis;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ return structuredAnalysisResult;
118
+ }
119
+ /**
120
+ * Perform verification and determine if iteration should continue
121
+ * This function only verifies - it does NOT manage artifacts (save/delete/update)
122
+ */
123
+ export async function performVerificationCycle(structuredAnalysisResult, checklistContext, context, config, currentIteration, maxIterations, mcpServerUrl, mcpToken, featureId, verbose) {
124
+ // No verification needed if no checklist context
125
+ if (!checklistContext || checklistContext.checklists.length === 0) {
126
+ return { passed: true, verificationResult: null };
127
+ }
128
+ const { created_user_stories, created_test_cases } = structuredAnalysisResult;
129
+ if (verbose) {
130
+ logInfo('🔍 Starting checklist verification...');
131
+ }
132
+ const verificationResult = await verifyChecklistCompliance({
133
+ checklistContext,
134
+ analysisContext: context,
135
+ createdUserStories: created_user_stories || [],
136
+ createdTestCases: created_test_cases || [],
137
+ verbose,
138
+ }, config);
139
+ // Verification passed
140
+ if (verificationResult.rejected_count === 0) {
141
+ if (verbose) {
142
+ logInfo(`✅ Checklist verification passed: ${verificationResult.confirmed_count} confirmed, ${verificationResult.uncertain_count} uncertain`);
143
+ }
144
+ // Log verification success
145
+ await logFeatureVerificationEvent(mcpServerUrl, mcpToken, {
146
+ featureId,
147
+ phase: 'feature_analysis',
148
+ iteration: currentIteration,
149
+ result: 'success',
150
+ verificationData: {
151
+ confirmed_count: verificationResult.confirmed_count,
152
+ rejected_count: verificationResult.rejected_count,
153
+ uncertain_count: verificationResult.uncertain_count,
154
+ summary: verificationResult.summary,
155
+ },
156
+ }, verbose);
157
+ return { passed: true, verificationResult };
158
+ }
159
+ // Verification failed
160
+ logError(`❌ Iteration ${currentIteration}: Checklist verification FAILED - ${verificationResult.rejected_count} items rejected, ${verificationResult.uncertain_count} uncertain`);
161
+ // Log verification failure with improvement suggestions
162
+ await logFeatureVerificationEvent(mcpServerUrl, mcpToken, {
163
+ featureId,
164
+ phase: 'feature_analysis',
165
+ iteration: currentIteration,
166
+ result: 'error',
167
+ verificationData: {
168
+ confirmed_count: verificationResult.confirmed_count,
169
+ rejected_count: verificationResult.rejected_count,
170
+ uncertain_count: verificationResult.uncertain_count,
171
+ rejected_items: verificationResult.item_verifications
172
+ .filter((item) => item.verification_status === 'rejected')
173
+ .map((item) => ({
174
+ checklist_item_id: item.checklist_item_id,
175
+ reason: item.verification_reason || 'No reason provided',
176
+ concerns: item.concerns || [],
177
+ improvement_suggestions: item.improvement_suggestions || [],
178
+ })),
179
+ uncertain_items: verificationResult.item_verifications
180
+ .filter((item) => item.verification_status === 'uncertain')
181
+ .map((item) => ({
182
+ checklist_item_id: item.checklist_item_id,
183
+ reason: item.verification_reason || 'No reason provided',
184
+ concerns: item.concerns || [],
185
+ improvement_suggestions: item.improvement_suggestions || [],
186
+ })),
187
+ summary: verificationResult.summary,
188
+ overall_suggestions: verificationResult.overall_suggestions || [],
189
+ },
190
+ }, verbose);
191
+ // Check if we can iterate again
192
+ if (currentIteration < maxIterations) {
193
+ if (verbose) {
194
+ logInfo(` Will retry with improvement feedback (${maxIterations - currentIteration} attempts remaining)`);
195
+ }
196
+ // Create improvement prompt for next iteration
197
+ const nextPrompt = createImprovementPrompt(verificationResult, {
198
+ created_user_stories: created_user_stories || [],
199
+ created_test_cases: created_test_cases || [],
200
+ });
201
+ return { passed: false, verificationResult, nextPrompt };
202
+ }
203
+ // Max iterations reached
204
+ logError(`❌ Maximum iterations (${maxIterations}) reached. Checklist verification still failing.`);
205
+ return { passed: false, verificationResult };
206
+ }
207
+ /**
208
+ * Save analysis artifacts as draft and return their IDs
209
+ */
210
+ export async function saveAnalysisArtifactsAsDraft(mcpServerUrl, mcpToken, featureId, created_user_stories, created_test_cases, verbose) {
211
+ const userStoryIds = [];
212
+ const testCaseIds = [];
213
+ // Save user stories as draft
214
+ if (created_user_stories && created_user_stories.length > 0) {
215
+ if (verbose) {
216
+ logInfo(`Saving ${created_user_stories.length} user stories as draft...`);
217
+ }
218
+ try {
219
+ const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/create', {
220
+ feature_id: featureId,
221
+ user_stories: created_user_stories.map((story) => ({
222
+ title: story.title,
223
+ description: story.description,
224
+ status: 'draft',
225
+ })),
226
+ }));
227
+ if (result.created_user_stories) {
228
+ userStoryIds.push(...result.created_user_stories.map((story) => story.id));
229
+ if (verbose) {
230
+ logInfo(`✅ Saved ${userStoryIds.length} user stories as draft`);
231
+ }
232
+ }
233
+ }
234
+ catch (error) {
235
+ logError(`Failed to save user stories: ${error instanceof Error ? error.message : String(error)}`);
236
+ }
237
+ }
238
+ // Save test cases as draft
239
+ if (created_test_cases && created_test_cases.length > 0) {
240
+ if (verbose) {
241
+ logInfo(`Saving ${created_test_cases.length} test cases as draft...`);
242
+ }
243
+ try {
244
+ const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/create', {
245
+ feature_id: featureId,
246
+ test_cases: created_test_cases.map((testCase) => ({
247
+ name: testCase.name,
248
+ description: testCase.description,
249
+ is_critical: testCase.is_critical || false,
250
+ status: 'draft',
251
+ })),
252
+ }));
253
+ if (result.created_test_cases) {
254
+ testCaseIds.push(...result.created_test_cases.map((testCase) => testCase.id));
255
+ if (verbose) {
256
+ logInfo(`✅ Saved ${testCaseIds.length} test cases as draft`);
257
+ }
258
+ }
259
+ }
260
+ catch (error) {
261
+ logError(`Failed to save test cases: ${error instanceof Error ? error.message : String(error)}`);
262
+ }
263
+ }
264
+ return { userStoryIds, testCaseIds };
265
+ }
266
+ /**
267
+ * Update artifacts to ready status after successful verification
268
+ */
269
+ export async function updateArtifactsToReady(mcpServerUrl, mcpToken, userStoryIds, testCaseIds, verbose) {
270
+ if (userStoryIds.length > 0) {
271
+ if (verbose) {
272
+ logInfo(`Updating ${userStoryIds.length} user stories from draft to ready...`);
273
+ }
274
+ await batchUpdateUserStoryStatus(mcpServerUrl, mcpToken, userStoryIds, 'ready', verbose);
275
+ }
276
+ if (testCaseIds.length > 0) {
277
+ if (verbose) {
278
+ logInfo(`Updating ${testCaseIds.length} test cases from draft to ready...`);
279
+ }
280
+ await batchUpdateTestCaseStatus(mcpServerUrl, mcpToken, testCaseIds, 'ready', verbose);
281
+ }
282
+ }
283
+ /**
284
+ * Delete artifacts after verification failure
285
+ */
286
+ export async function deleteArtifacts(mcpServerUrl, mcpToken, userStoryIds, testCaseIds, verbose) {
287
+ if (userStoryIds.length > 0) {
288
+ if (verbose) {
289
+ logInfo(`Deleting ${userStoryIds.length} user stories due to verification failure...`);
290
+ }
291
+ await batchDeleteUserStories(mcpServerUrl, mcpToken, userStoryIds, verbose);
292
+ }
293
+ if (testCaseIds.length > 0) {
294
+ if (verbose) {
295
+ logInfo(`Deleting ${testCaseIds.length} test cases due to verification failure...`);
296
+ }
297
+ await batchDeleteTestCases(mcpServerUrl, mcpToken, testCaseIds, verbose);
298
+ }
299
+ }
300
+ /**
301
+ * Save analysis artifacts (user stories and test cases) - Legacy function for non-verification flows
302
+ */
303
+ export async function saveAnalysisArtifacts(mcpServerUrl, mcpToken, featureId, created_user_stories, created_test_cases, status, verbose) {
304
+ if (created_user_stories && created_user_stories.length > 0) {
305
+ if (verbose) {
306
+ logInfo('Saving created user stories...');
307
+ }
308
+ const userStoriesCreated = await createUserStories(mcpServerUrl, mcpToken, featureId, created_user_stories, verbose);
309
+ if (!userStoriesCreated && verbose) {
310
+ logError('⚠️ Failed to save user stories');
311
+ }
312
+ }
313
+ if (created_test_cases && created_test_cases.length > 0) {
314
+ if (verbose) {
315
+ logInfo('Saving created test cases...');
316
+ }
317
+ const testCasesCreated = await createTestCases(mcpServerUrl, mcpToken, featureId, created_test_cases, verbose);
318
+ if (!testCasesCreated && verbose) {
319
+ logError('⚠️ Failed to save test cases');
320
+ }
321
+ }
322
+ // Try HTTP fallback if direct save failed
323
+ if (status === 'error' &&
324
+ (created_user_stories?.length > 0 || created_test_cases?.length > 0)) {
325
+ if (verbose) {
326
+ logInfo('Direct save failed, trying HTTP fallback...');
327
+ }
328
+ const httpSuccess = await saveDataViaHttp({
329
+ mcpServerUrl,
330
+ mcpToken,
331
+ featureId,
332
+ userStories: created_user_stories || [],
333
+ testCases: created_test_cases || [],
334
+ verbose,
335
+ });
336
+ if (httpSuccess) {
337
+ logInfo('✅ Successfully saved data via HTTP fallback');
338
+ }
339
+ else if (verbose) {
340
+ logError('❌ HTTP fallback also failed');
341
+ }
342
+ }
343
+ }
344
+ /**
345
+ * Build the final analysis result object
346
+ */
347
+ export function buildAnalysisResult(featureId, context, structuredAnalysisResult, currentIteration) {
348
+ const { created_user_stories, created_test_cases, checklist_results, checklist_item_results, } = structuredAnalysisResult;
349
+ return {
350
+ featureId,
351
+ productInfo: context.product,
352
+ featureInfo: context.feature,
353
+ existingUserStories: context.existing_user_stories.map((story) => ({
354
+ ...story,
355
+ status: story.status,
356
+ created_at: story.created_at || new Date().toISOString(),
357
+ updated_at: story.updated_at || new Date().toISOString(),
358
+ })),
359
+ existingTestCases: context.existing_test_cases.map((testCase) => ({
360
+ ...testCase,
361
+ created_at: testCase.created_at || new Date().toISOString(),
362
+ updated_at: testCase.updated_at || new Date().toISOString(),
363
+ })),
364
+ createdUserStories: (created_user_stories || []).map((story) => ({
365
+ id: '',
366
+ title: story.title,
367
+ description: story.description,
368
+ status: story.status || 'draft',
369
+ created_at: new Date().toISOString(),
370
+ updated_at: new Date().toISOString(),
371
+ })),
372
+ createdTestCases: (created_test_cases || []).map((testCase) => ({
373
+ id: '',
374
+ name: testCase.name,
375
+ description: testCase.description,
376
+ is_critical: testCase.is_critical || false,
377
+ created_at: new Date().toISOString(),
378
+ updated_at: new Date().toISOString(),
379
+ })),
380
+ summary: structuredAnalysisResult.summary ||
381
+ `Analysis completed${currentIteration > 1 ? ` after ${currentIteration} iterations` : ''}`,
382
+ status: structuredAnalysisResult.status === 'success' ? 'success' : 'error',
383
+ data: {
384
+ checklist_results,
385
+ checklist_item_results,
386
+ verification_result: structuredAnalysisResult.verification_result,
387
+ iterations: currentIteration,
388
+ },
389
+ };
390
+ }
391
+ /**
392
+ * Build error result when verification fails after all iterations
393
+ */
394
+ export function buildVerificationFailureResult(featureId, context, verificationResult, checklist_results, checklist_item_results, currentIteration) {
395
+ return {
396
+ featureId,
397
+ productInfo: context.product,
398
+ featureInfo: context.feature,
399
+ existingUserStories: context.existing_user_stories.map((story) => ({
400
+ ...story,
401
+ status: story.status,
402
+ created_at: story.created_at || new Date().toISOString(),
403
+ updated_at: story.updated_at || new Date().toISOString(),
404
+ })),
405
+ existingTestCases: context.existing_test_cases.map((testCase) => ({
406
+ ...testCase,
407
+ created_at: testCase.created_at || new Date().toISOString(),
408
+ updated_at: testCase.updated_at || new Date().toISOString(),
409
+ })),
410
+ createdUserStories: [],
411
+ createdTestCases: [],
412
+ summary: `Checklist verification failed after ${currentIteration} iterations: ${verificationResult.summary}`,
413
+ status: 'error',
414
+ data: {
415
+ checklist_results,
416
+ checklist_item_results,
417
+ verification_result: verificationResult,
418
+ iterations: currentIteration,
419
+ },
420
+ };
421
+ }
422
+ /**
423
+ * Build error result when no analysis results are received
424
+ */
425
+ export function buildNoResultsError(featureId, context) {
426
+ return {
427
+ featureId,
428
+ productInfo: context.product,
429
+ featureInfo: context.feature,
430
+ existingUserStories: context.existing_user_stories.map((story) => ({
431
+ ...story,
432
+ status: story.status,
433
+ created_at: story.created_at || new Date().toISOString(),
434
+ updated_at: story.updated_at || new Date().toISOString(),
435
+ })),
436
+ existingTestCases: context.existing_test_cases.map((testCase) => ({
437
+ ...testCase,
438
+ created_at: testCase.created_at || new Date().toISOString(),
439
+ updated_at: testCase.updated_at || new Date().toISOString(),
440
+ })),
441
+ createdUserStories: [],
442
+ createdTestCases: [],
443
+ summary: 'No analysis results received',
444
+ status: 'error',
445
+ data: {
446
+ checklist_results: undefined,
447
+ checklist_item_results: undefined,
448
+ },
449
+ };
450
+ }
@@ -5,6 +5,7 @@ export interface FeatureAnalysisOptions {
5
5
  mcpServerUrl: string;
6
6
  mcpToken: string;
7
7
  verbose?: boolean;
8
+ maxVerificationIterations?: number;
8
9
  }
9
10
  export declare const analyzeFeatureWithMCP: (options: FeatureAnalysisOptions, config: EdsgerConfig, checklistContext?: ChecklistPhaseContext | null) => Promise<FeatureAnalysisResult>;
10
11
  export declare const checkFeatureAnalysisRequirements: () => Promise<boolean>;