edsger 0.2.1 → 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.
- package/dist/api/features/feature-utils.d.ts +13 -0
- package/dist/api/features/feature-utils.js +46 -0
- package/dist/api/features/get-feature.d.ts +5 -0
- package/dist/api/features/get-feature.js +19 -0
- package/dist/api/features/index.d.ts +7 -0
- package/dist/api/features/index.js +9 -0
- package/dist/api/features/status-updater.d.ts +27 -0
- package/dist/api/features/status-updater.js +64 -0
- package/dist/api/features/test-cases.d.ts +21 -0
- package/dist/api/features/test-cases.js +63 -0
- package/dist/api/features/update-feature.d.ts +13 -0
- package/dist/api/features/update-feature.js +31 -0
- package/dist/api/features/user-stories.d.ts +21 -0
- package/dist/api/features/user-stories.js +63 -0
- package/dist/api/features.d.ts +100 -0
- package/dist/api/features.js +219 -0
- package/dist/api/mcp-client.d.ts +18 -0
- package/dist/api/mcp-client.js +58 -0
- package/dist/api/products.d.ts +10 -0
- package/dist/api/products.js +22 -0
- package/dist/api/test-reports.d.ts +9 -0
- package/dist/api/test-reports.js +25 -0
- package/dist/cli/commands/code-implementation-command.d.ts +2 -0
- package/dist/cli/commands/code-implementation-command.js +36 -0
- package/dist/cli/commands/code-review-command.d.ts +2 -0
- package/dist/cli/commands/code-review-command.js +39 -0
- package/dist/cli/commands/feature-analysis-command.d.ts +2 -0
- package/dist/cli/commands/feature-analysis-command.js +36 -0
- package/dist/cli/commands/functional-testing-command.d.ts +2 -0
- package/dist/cli/commands/functional-testing-command.js +36 -0
- package/dist/cli/commands/technical-design-command.d.ts +2 -0
- package/dist/cli/commands/technical-design-command.js +36 -0
- package/dist/cli/commands/workflow-command.d.ts +2 -0
- package/dist/cli/commands/workflow-command.js +34 -0
- package/dist/cli/formatters/code-implementation-formatter.d.ts +9 -0
- package/dist/cli/formatters/code-implementation-formatter.js +27 -0
- package/dist/cli/formatters/feature-analysis-formatter.d.ts +2 -0
- package/dist/cli/formatters/feature-analysis-formatter.js +27 -0
- package/dist/cli/formatters/functional-testing-formatter.d.ts +15 -0
- package/dist/cli/formatters/functional-testing-formatter.js +37 -0
- package/dist/cli/formatters/technical-design-formatter.d.ts +7 -0
- package/dist/cli/formatters/technical-design-formatter.js +30 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/utils/validation.d.ts +25 -0
- package/dist/cli/utils/validation.js +58 -0
- package/dist/cli/utils/workflow-utils.d.ts +21 -0
- package/dist/cli/utils/workflow-utils.js +47 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +11 -466
- package/dist/config.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{bug-fixing → phases/bug-fixing}/analyzer.d.ts +1 -1
- package/dist/{bug-fixing → phases/bug-fixing}/analyzer.js +1 -1
- package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.d.ts +4 -22
- package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.js +14 -58
- package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.js +1 -30
- package/dist/phases/code-implementation/analyzer.d.ts +33 -0
- package/dist/{code-implementation → phases/code-implementation}/analyzer.js +174 -15
- package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
- package/dist/phases/code-implementation/context-fetcher.js +86 -0
- package/dist/{code-implementation → phases/code-implementation}/mcp-server.js +1 -30
- package/dist/{code-review → phases/code-review}/reviewer.d.ts +1 -1
- package/dist/{feature-analysis → phases/feature-analysis}/analyzer.d.ts +3 -2
- package/dist/{feature-analysis → phases/feature-analysis}/analyzer.js +29 -127
- package/dist/phases/feature-analysis/context-fetcher.d.ts +18 -0
- package/dist/phases/feature-analysis/context-fetcher.js +86 -0
- package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.js +1 -1
- package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.js +1 -24
- package/dist/{functional-testing → phases/functional-testing}/analyzer.d.ts +17 -2
- package/dist/{functional-testing → phases/functional-testing}/analyzer.js +225 -31
- package/dist/phases/functional-testing/context-fetcher.d.ts +16 -0
- package/dist/phases/functional-testing/context-fetcher.js +81 -0
- package/dist/{functional-testing → phases/functional-testing}/http-fallback.js +1 -1
- package/dist/{functional-testing → phases/functional-testing}/index.d.ts +1 -1
- package/dist/{functional-testing → phases/functional-testing}/index.js +1 -1
- package/dist/{functional-testing → phases/functional-testing}/mcp-server.js +1 -30
- package/dist/{functional-testing → phases/functional-testing}/test-report-creator.js +1 -1
- package/dist/phases/functional-testing/test-retry-handler.d.ts +16 -0
- package/dist/phases/functional-testing/test-retry-handler.js +75 -0
- package/dist/{pull-request → phases/pull-request}/creator.js +47 -6
- package/dist/phases/pull-request/handler.d.ts +16 -0
- package/dist/phases/pull-request/handler.js +60 -0
- package/dist/{technical-design → phases/technical-design}/analyzer.d.ts +7 -2
- package/dist/phases/technical-design/analyzer.js +418 -0
- package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
- package/dist/phases/technical-design/context-fetcher.js +39 -0
- package/dist/{technical-design → phases/technical-design}/http-fallback.js +1 -1
- package/dist/{technical-design → phases/technical-design}/mcp-server.js +1 -30
- package/dist/prompts/bug-fixing.d.ts +2 -0
- package/dist/prompts/bug-fixing.js +63 -0
- package/dist/prompts/code-implementation.d.ts +3 -0
- package/dist/prompts/code-implementation.js +132 -0
- package/dist/prompts/feature-analysis.d.ts +3 -0
- package/dist/prompts/feature-analysis.js +149 -0
- package/dist/prompts/formatters.d.ts +29 -0
- package/dist/prompts/formatters.js +139 -0
- package/dist/prompts/functional-testing.d.ts +3 -0
- package/dist/prompts/functional-testing.js +126 -0
- package/dist/prompts/index.d.ts +6 -0
- package/dist/prompts/index.js +7 -0
- package/dist/prompts/technical-design.d.ts +3 -0
- package/dist/prompts/technical-design.js +130 -0
- package/dist/services/checklist.d.ts +99 -0
- package/dist/services/checklist.js +337 -0
- package/dist/types/features.d.ts +29 -0
- package/dist/types/features.js +1 -0
- package/dist/types/index.d.ts +112 -0
- package/dist/types/index.js +1 -0
- package/dist/types/pipeline.d.ts +25 -0
- package/dist/types/pipeline.js +4 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/pipeline-logger.d.ts +8 -0
- package/dist/utils/pipeline-logger.js +35 -0
- package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
- package/dist/workflow-runner/config/phase-configs.js +34 -0
- package/dist/workflow-runner/config/stage-configs.d.ts +5 -0
- package/dist/workflow-runner/config/stage-configs.js +34 -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/feature-filter.test.d.ts +4 -0
- package/dist/workflow-runner/core/feature-filter.test.js +127 -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 +183 -0
- package/dist/workflow-runner/executors/stage-executor.d.ts +8 -0
- package/dist/workflow-runner/executors/stage-executor.js +49 -0
- package/dist/workflow-runner/feature-service.d.ts +17 -0
- package/dist/workflow-runner/feature-service.js +60 -0
- package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
- package/dist/workflow-runner/feature-workflow-runner.js +113 -0
- package/dist/workflow-runner/index.d.ts +0 -1
- package/dist/workflow-runner/index.js +0 -1
- package/dist/workflow-runner/pipeline-runner.d.ts +9 -19
- package/dist/workflow-runner/pipeline-runner.js +247 -256
- package/dist/workflow-runner/pipeline.d.ts +18 -0
- package/dist/workflow-runner/pipeline.js +197 -0
- package/dist/workflow-runner/processor.d.ts +40 -0
- package/dist/workflow-runner/processor.js +191 -0
- package/dist/workflow-runner/types.d.ts +48 -0
- package/dist/workflow-runner/types.js +4 -0
- package/dist/workflow-runner/workflow-processor.d.ts +6 -23
- package/dist/workflow-runner/workflow-processor.js +38 -100
- package/package.json +1 -1
- package/dist/code-implementation/analyzer.d.ts +0 -19
- package/dist/code-implementation/context-fetcher.d.ts +0 -38
- package/dist/code-implementation/context-fetcher.js +0 -147
- package/dist/feature-analysis/context-fetcher.d.ts +0 -54
- package/dist/feature-analysis/context-fetcher.js +0 -193
- package/dist/functional-testing/context-fetcher.d.ts +0 -47
- package/dist/functional-testing/context-fetcher.js +0 -192
- package/dist/technical-design/analyzer.js +0 -338
- package/dist/technical-design/context-fetcher.d.ts +0 -42
- package/dist/technical-design/context-fetcher.js +0 -170
- /package/dist/{bug-fixing → phases/bug-fixing}/index.d.ts +0 -0
- /package/dist/{bug-fixing → phases/bug-fixing}/index.js +0 -0
- /package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.d.ts +0 -0
- /package/dist/{code-implementation → phases/code-implementation}/mcp-server.d.ts +0 -0
- /package/dist/{code-review → phases/code-review}/reviewer.js +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.d.ts +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/index.d.ts +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/index.js +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/http-fallback.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/mcp-server.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/test-report-creator.d.ts +0 -0
- /package/dist/{pull-request → phases/pull-request}/creator.d.ts +0 -0
- /package/dist/{technical-design → phases/technical-design}/http-fallback.d.ts +0 -0
- /package/dist/{technical-design → phases/technical-design}/mcp-server.d.ts +0 -0
|
@@ -1,35 +1,6 @@
|
|
|
1
1
|
import { createSdkMcpServer, tool } from '@anthropic-ai/claude-code';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
|
|
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 bug fixing
|
|
34
5
|
export const createBugFixingMcpServer = (mcpServerUrl, mcpToken) => {
|
|
35
6
|
return createSdkMcpServer({
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { EdsgerConfig } from '../../types/index.js';
|
|
2
|
+
import { ChecklistPhaseContext } from '../../services/checklist.js';
|
|
3
|
+
export interface CodeImplementationOptions {
|
|
4
|
+
featureId: string;
|
|
5
|
+
mcpServerUrl: string;
|
|
6
|
+
mcpToken: string;
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
baseBranch?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CodeImplementationResult {
|
|
11
|
+
featureId: string;
|
|
12
|
+
branchName: string;
|
|
13
|
+
implementationSummary: string | null;
|
|
14
|
+
status: 'success' | 'error';
|
|
15
|
+
message: string;
|
|
16
|
+
filesModified?: string[];
|
|
17
|
+
commitHash?: string;
|
|
18
|
+
data?: {
|
|
19
|
+
checklist_results?: Array<{
|
|
20
|
+
checklist_id: string;
|
|
21
|
+
satisfied: boolean;
|
|
22
|
+
notes?: string;
|
|
23
|
+
}>;
|
|
24
|
+
checklist_item_results?: Array<{
|
|
25
|
+
checklist_item_id: string;
|
|
26
|
+
is_passed: boolean;
|
|
27
|
+
value?: any;
|
|
28
|
+
notes?: string;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export declare const implementFeatureCode: (options: CodeImplementationOptions, config: EdsgerConfig, checklistContext?: ChecklistPhaseContext | null) => Promise<CodeImplementationResult>;
|
|
33
|
+
export declare const checkCodeImplementationRequirements: () => Promise<boolean>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { query } from '@anthropic-ai/claude-code';
|
|
2
|
-
import { logInfo, logError } from '
|
|
2
|
+
import { logInfo, logError } from '../../utils/logger.js';
|
|
3
|
+
import { formatChecklistsForContext, } from '../../services/checklist.js';
|
|
3
4
|
import { fetchCodeImplementationContext, formatContextForPrompt, } from './context-fetcher.js';
|
|
4
5
|
function userMessage(content) {
|
|
5
6
|
return {
|
|
@@ -11,7 +12,7 @@ async function* prompt(implementationPrompt) {
|
|
|
11
12
|
yield userMessage(implementationPrompt);
|
|
12
13
|
await new Promise((res) => setTimeout(res, 10000));
|
|
13
14
|
}
|
|
14
|
-
export const implementFeatureCode = async (options, config) => {
|
|
15
|
+
export const implementFeatureCode = async (options, config, checklistContext) => {
|
|
15
16
|
const { featureId, mcpServerUrl, mcpToken, verbose, baseBranch = 'main', } = options;
|
|
16
17
|
if (verbose) {
|
|
17
18
|
logInfo(`Starting code implementation for feature ID: ${featureId}`);
|
|
@@ -24,13 +25,23 @@ export const implementFeatureCode = async (options, config) => {
|
|
|
24
25
|
logInfo('Fetching code implementation context via MCP endpoints...');
|
|
25
26
|
}
|
|
26
27
|
const context = await fetchCodeImplementationContext(mcpServerUrl, mcpToken, featureId, verbose);
|
|
27
|
-
const systemPrompt = createSystemPrompt(config, baseBranch);
|
|
28
|
-
const implementationPrompt = createImplementationPromptWithContext(featureId, context, baseBranch);
|
|
28
|
+
const systemPrompt = createSystemPrompt(config, baseBranch, mcpServerUrl, mcpToken, featureId);
|
|
29
|
+
const implementationPrompt = createImplementationPromptWithContext(featureId, context, baseBranch, checklistContext, verbose);
|
|
29
30
|
let lastAssistantResponse = '';
|
|
30
31
|
let structuredImplementationResult = null;
|
|
31
32
|
if (verbose) {
|
|
32
33
|
logInfo('Starting Claude Code query with pre-fetched information...');
|
|
33
34
|
}
|
|
35
|
+
// DEBUG: Log checklist context before query
|
|
36
|
+
console.log('=== DEBUG: Checklist Context Before Claude Query ===');
|
|
37
|
+
console.log('Has checklistContext:', !!checklistContext);
|
|
38
|
+
if (checklistContext) {
|
|
39
|
+
console.log('Number of checklists:', checklistContext.checklists.length);
|
|
40
|
+
const totalItems = checklistContext.checklists.reduce((sum, checklist) => sum + (checklist.items?.length || 0), 0);
|
|
41
|
+
console.log('Total checklist items:', totalItems);
|
|
42
|
+
}
|
|
43
|
+
console.log('Implementation prompt includes checklist:', implementationPrompt.includes('checklist'));
|
|
44
|
+
console.log('System prompt includes checklist:', systemPrompt.includes('checklist'));
|
|
34
45
|
// Use Claude Code SDK without MCP servers - all info is pre-fetched
|
|
35
46
|
for await (const message of query({
|
|
36
47
|
prompt: prompt(implementationPrompt),
|
|
@@ -67,26 +78,85 @@ export const implementFeatureCode = async (options, config) => {
|
|
|
67
78
|
// Try to extract JSON from markdown code block or parse directly
|
|
68
79
|
const responseText = message.result || lastAssistantResponse;
|
|
69
80
|
let jsonResult = null;
|
|
81
|
+
// DEBUG: Log response text details and checklist content
|
|
82
|
+
console.log('=== DEBUG: Code Implementation Response Analysis ===');
|
|
83
|
+
console.log('message.result exists:', !!message.result);
|
|
84
|
+
console.log('lastAssistantResponse exists:', !!lastAssistantResponse);
|
|
85
|
+
console.log('responseText length:', responseText.length);
|
|
86
|
+
console.log('responseText first 200 chars:', JSON.stringify(responseText.substring(0, 200)));
|
|
87
|
+
console.log('responseText last 200 chars:', JSON.stringify(responseText.substring(responseText.length - 200)));
|
|
88
|
+
console.log('Contains ```json:', responseText.includes('```json'));
|
|
89
|
+
console.log('Contains implementation_result:', responseText.includes('"implementation_result"'));
|
|
90
|
+
console.log('=== DEBUG: Checklist Content in Response ===');
|
|
91
|
+
console.log('Contains "checklist":', responseText.toLowerCase().includes('checklist'));
|
|
92
|
+
console.log('Contains "checklist_item_results":', responseText.includes('checklist_item_results'));
|
|
93
|
+
console.log('Contains checklist_item_id:', responseText.includes('checklist_item_id'));
|
|
94
|
+
console.log('Contains is_passed:', responseText.includes('is_passed'));
|
|
95
|
+
// Count checklist-related occurrences
|
|
96
|
+
const checklistMatches = responseText.match(/checklist/gi) || [];
|
|
97
|
+
const checklistItemMatches = responseText.match(/checklist_item/gi) || [];
|
|
98
|
+
console.log('Total "checklist" mentions:', checklistMatches.length);
|
|
99
|
+
console.log('Total "checklist_item" mentions:', checklistItemMatches.length);
|
|
70
100
|
// First try to extract JSON from markdown code block
|
|
71
101
|
const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
|
|
102
|
+
console.log('=== DEBUG: Markdown Block Match ===');
|
|
103
|
+
console.log('jsonBlockMatch found:', !!jsonBlockMatch);
|
|
72
104
|
if (jsonBlockMatch) {
|
|
105
|
+
console.log('Matched JSON length:', jsonBlockMatch[1].length);
|
|
106
|
+
console.log('Matched JSON first 100 chars:', JSON.stringify(jsonBlockMatch[1].substring(0, 100)));
|
|
73
107
|
jsonResult = JSON.parse(jsonBlockMatch[1]);
|
|
74
108
|
}
|
|
75
109
|
else {
|
|
110
|
+
console.log('=== DEBUG: Trying direct JSON parse ===');
|
|
76
111
|
// Try to parse the entire response as JSON
|
|
77
112
|
jsonResult = JSON.parse(responseText);
|
|
78
113
|
}
|
|
114
|
+
console.log('=== DEBUG: Final Result Processing ===');
|
|
115
|
+
console.log('jsonResult exists:', !!jsonResult);
|
|
116
|
+
console.log('jsonResult has implementation_result:', !!(jsonResult && jsonResult.implementation_result));
|
|
79
117
|
if (jsonResult && jsonResult.implementation_result) {
|
|
118
|
+
const implResult = jsonResult.implementation_result;
|
|
119
|
+
console.log('=== DEBUG: Implementation Result Structure ===');
|
|
120
|
+
console.log('Keys in implementation_result:', Object.keys(implResult));
|
|
121
|
+
console.log('Has checklist_item_results field:', 'checklist_item_results' in implResult);
|
|
122
|
+
console.log('checklist_item_results value type:', typeof implResult.checklist_item_results);
|
|
123
|
+
console.log('checklist_item_results is array:', Array.isArray(implResult.checklist_item_results));
|
|
124
|
+
if (implResult.checklist_item_results) {
|
|
125
|
+
console.log('checklist_item_results length:', implResult.checklist_item_results.length);
|
|
126
|
+
if (implResult.checklist_item_results.length > 0) {
|
|
127
|
+
console.log('First checklist item keys:', Object.keys(implResult.checklist_item_results[0]));
|
|
128
|
+
console.log('First checklist item sample:', JSON.stringify(implResult.checklist_item_results[0], null, 2));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
console.log('checklist_item_results is null/undefined/empty');
|
|
133
|
+
}
|
|
80
134
|
structuredImplementationResult = jsonResult.implementation_result;
|
|
135
|
+
console.log('Successfully extracted implementation_result');
|
|
81
136
|
}
|
|
82
137
|
else {
|
|
138
|
+
console.log('ERROR: Invalid JSON structure - missing implementation_result');
|
|
83
139
|
throw new Error('Invalid JSON structure');
|
|
84
140
|
}
|
|
85
141
|
}
|
|
86
142
|
catch (error) {
|
|
143
|
+
console.log('=== DEBUG: JSON Parsing Failed ===');
|
|
144
|
+
console.log('Error type:', error instanceof SyntaxError
|
|
145
|
+
? 'SyntaxError'
|
|
146
|
+
: error instanceof Error
|
|
147
|
+
? error.constructor.name
|
|
148
|
+
: 'Unknown');
|
|
149
|
+
console.log('Error message:', error instanceof Error ? error.message : String(error));
|
|
87
150
|
logError(`Failed to parse structured implementation result: ${error}`);
|
|
151
|
+
console.log('=== DEBUG: Using Fallback Parsing ===');
|
|
88
152
|
// Fallback parsing
|
|
89
153
|
const parsedResult = parseImplementationResponse(message.result || lastAssistantResponse, featureId);
|
|
154
|
+
console.log('Fallback parsed result:', {
|
|
155
|
+
branchName: parsedResult.branchName,
|
|
156
|
+
filesModifiedCount: parsedResult.filesModified?.length || 0,
|
|
157
|
+
hasSummary: !!parsedResult.summary,
|
|
158
|
+
commitHash: parsedResult.commitHash,
|
|
159
|
+
});
|
|
90
160
|
structuredImplementationResult = {
|
|
91
161
|
branch_name: parsedResult.branchName,
|
|
92
162
|
files_modified: parsedResult.filesModified,
|
|
@@ -94,6 +164,7 @@ export const implementFeatureCode = async (options, config) => {
|
|
|
94
164
|
summary: parsedResult.summary || 'Implementation completed',
|
|
95
165
|
tests_passed: true,
|
|
96
166
|
pre_commit_passed: true,
|
|
167
|
+
checklist_item_results: parsedResult.checklist_item_results || [],
|
|
97
168
|
};
|
|
98
169
|
}
|
|
99
170
|
}
|
|
@@ -104,10 +175,15 @@ export const implementFeatureCode = async (options, config) => {
|
|
|
104
175
|
}
|
|
105
176
|
// Try to parse results from the last assistant response
|
|
106
177
|
if (lastAssistantResponse) {
|
|
178
|
+
console.log('=== DEBUG: Fallback for incomplete result ===');
|
|
179
|
+
console.log('message.subtype:', message.subtype);
|
|
107
180
|
try {
|
|
108
181
|
const responseText = lastAssistantResponse;
|
|
109
182
|
let jsonResult = null;
|
|
183
|
+
console.log('lastAssistantResponse length:', responseText.length);
|
|
184
|
+
console.log('lastAssistantResponse first 200 chars:', JSON.stringify(responseText.substring(0, 200)));
|
|
110
185
|
const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
|
|
186
|
+
console.log('jsonBlockMatch in fallback found:', !!jsonBlockMatch);
|
|
111
187
|
if (jsonBlockMatch) {
|
|
112
188
|
jsonResult = JSON.parse(jsonBlockMatch[1]);
|
|
113
189
|
if (jsonResult && jsonResult.implementation_result) {
|
|
@@ -124,21 +200,25 @@ export const implementFeatureCode = async (options, config) => {
|
|
|
124
200
|
}
|
|
125
201
|
}
|
|
126
202
|
if (structuredImplementationResult) {
|
|
127
|
-
const { branch_name, files_modified, commit_hash, summary } = structuredImplementationResult;
|
|
203
|
+
const { branch_name, files_modified, commit_hash, summary, checklist_results, checklist_item_results, } = structuredImplementationResult;
|
|
128
204
|
return {
|
|
129
205
|
featureId,
|
|
130
|
-
branchName: branch_name || `
|
|
206
|
+
branchName: branch_name || `dev/${featureId}`,
|
|
131
207
|
implementationSummary: summary || 'Implementation completed',
|
|
132
208
|
status: 'success',
|
|
133
209
|
message: 'Code implementation completed successfully',
|
|
134
210
|
filesModified: files_modified || [],
|
|
135
211
|
commitHash: commit_hash || '',
|
|
212
|
+
data: {
|
|
213
|
+
checklist_results,
|
|
214
|
+
checklist_item_results,
|
|
215
|
+
},
|
|
136
216
|
};
|
|
137
217
|
}
|
|
138
218
|
else {
|
|
139
219
|
return {
|
|
140
220
|
featureId,
|
|
141
|
-
branchName: `
|
|
221
|
+
branchName: `dev/${featureId}`,
|
|
142
222
|
implementationSummary: null,
|
|
143
223
|
status: 'error',
|
|
144
224
|
message: 'Code implementation failed or incomplete',
|
|
@@ -149,14 +229,31 @@ export const implementFeatureCode = async (options, config) => {
|
|
|
149
229
|
logError(`Code implementation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
150
230
|
return {
|
|
151
231
|
featureId,
|
|
152
|
-
branchName: `
|
|
232
|
+
branchName: `dev/${featureId}`,
|
|
153
233
|
implementationSummary: null,
|
|
154
234
|
status: 'error',
|
|
155
235
|
message: `Implementation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
156
236
|
};
|
|
157
237
|
}
|
|
158
238
|
};
|
|
159
|
-
const createSystemPrompt = (_config, baseBranch) => {
|
|
239
|
+
const createSystemPrompt = (_config, baseBranch, mcpServerUrl, mcpToken, featureId) => {
|
|
240
|
+
let mcpInstructions = '';
|
|
241
|
+
if (mcpServerUrl && mcpToken && featureId) {
|
|
242
|
+
mcpInstructions = `
|
|
243
|
+
|
|
244
|
+
**MANDATORY Checklist Compliance**:
|
|
245
|
+
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.
|
|
246
|
+
|
|
247
|
+
- Review each checklist carefully and ensure your implementation addresses every requirement
|
|
248
|
+
- You MUST include ALL provided checklist item IDs in the "checklist_item_results" field of your JSON response
|
|
249
|
+
- CRITICAL: Use the exact UUID from the "ID:" field in each checklist ITEM, NOT the item title or description
|
|
250
|
+
- Set "is_passed": true for each checklist item you have completed successfully
|
|
251
|
+
- Provide appropriate "value" based on the item type (boolean: true/false, text: descriptive text, number: numeric value)
|
|
252
|
+
- If you cannot satisfy a checklist item requirement, set "is_passed": false and explain why in the "notes" field
|
|
253
|
+
- The system will validate that all checklists have been addressed - missing checklists will cause the pipeline to fail
|
|
254
|
+
|
|
255
|
+
CRITICAL: Checklists are not optional suggestions - they are mandatory quality gates that must be satisfied.`;
|
|
256
|
+
}
|
|
160
257
|
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.
|
|
161
258
|
|
|
162
259
|
**Your Role**: Implement complete, working features based on provided specifications and requirements.
|
|
@@ -167,7 +264,7 @@ const createSystemPrompt = (_config, baseBranch) => {
|
|
|
167
264
|
- Read: Examine existing code, configuration, and documentation files
|
|
168
265
|
- Edit: Modify existing files
|
|
169
266
|
- Write: Create new files
|
|
170
|
-
- TodoWrite: Track implementation tasks (use proactively)
|
|
267
|
+
- TodoWrite: Track implementation tasks (use proactively)${mcpInstructions}
|
|
171
268
|
|
|
172
269
|
**CRITICAL WORKFLOW - YOU MUST FOLLOW THESE STEPS IN ORDER**:
|
|
173
270
|
|
|
@@ -231,18 +328,77 @@ You MUST end your response with a JSON object containing the implementation resu
|
|
|
231
328
|
"commit_hash": "abc123...",
|
|
232
329
|
"summary": "Brief description of what was implemented",
|
|
233
330
|
"tests_passed": true,
|
|
234
|
-
"pre_commit_passed": true
|
|
331
|
+
"pre_commit_passed": true,
|
|
332
|
+
"checklist_item_results": [
|
|
333
|
+
{
|
|
334
|
+
"checklist_item_id": "EXACT_CHECKLIST_ITEM_UUID_FROM_ID_FIELD",
|
|
335
|
+
"is_passed": true,
|
|
336
|
+
"value": "Result value based on item type (boolean, text, number, etc.)",
|
|
337
|
+
"notes": "Optional notes about this specific checklist item"
|
|
338
|
+
}
|
|
339
|
+
]
|
|
235
340
|
}
|
|
236
341
|
}
|
|
237
342
|
\`\`\`
|
|
238
343
|
|
|
344
|
+
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.
|
|
345
|
+
|
|
346
|
+
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.
|
|
347
|
+
|
|
239
348
|
Remember: Quality over speed. It's better to implement correctly than to rush and create bugs.`;
|
|
240
349
|
};
|
|
241
|
-
const createImplementationPromptWithContext = (featureId, context, baseBranch) => {
|
|
350
|
+
const createImplementationPromptWithContext = (featureId, context, baseBranch, checklistContext, verbose) => {
|
|
242
351
|
const contextInfo = formatContextForPrompt(context);
|
|
352
|
+
// Add checklist context to the implementation prompt
|
|
353
|
+
let finalContextInfo = contextInfo;
|
|
354
|
+
let checklistInstructions = '';
|
|
355
|
+
if (checklistContext && checklistContext.checklists.length > 0) {
|
|
356
|
+
const checklistInfo = formatChecklistsForContext(checklistContext);
|
|
357
|
+
finalContextInfo = contextInfo + '\n\n' + checklistInfo;
|
|
358
|
+
// DEBUG: Log checklist context details
|
|
359
|
+
console.log('=== DEBUG: Checklist Context for Code Implementation ===');
|
|
360
|
+
console.log('Number of checklists:', checklistContext.checklists.length);
|
|
361
|
+
console.log('Checklist info length:', checklistInfo.length);
|
|
362
|
+
console.log('Checklist info preview:', checklistInfo.substring(0, 300));
|
|
363
|
+
checklistContext.checklists.forEach((checklist, index) => {
|
|
364
|
+
console.log(`Checklist ${index + 1}:`, {
|
|
365
|
+
id: checklist.id,
|
|
366
|
+
name: checklist.name,
|
|
367
|
+
phase: checklist.phase,
|
|
368
|
+
role: checklist.role,
|
|
369
|
+
itemCount: checklist.items?.length || 0,
|
|
370
|
+
});
|
|
371
|
+
if (checklist.items) {
|
|
372
|
+
checklist.items.forEach((item, itemIndex) => {
|
|
373
|
+
console.log(` Item ${itemIndex + 1}:`, {
|
|
374
|
+
id: item.id,
|
|
375
|
+
title: item.title?.substring(0, 50) || 'No title',
|
|
376
|
+
description: item.description?.substring(0, 50) || 'No description',
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
// Add specific instructions for creating checklist results
|
|
382
|
+
checklistInstructions = `
|
|
383
|
+
|
|
384
|
+
## MANDATORY Checklist Compliance
|
|
385
|
+
|
|
386
|
+
**CRITICAL**: You MUST address ALL checklists provided in the context above. Checklists are mandatory quality requirements that cannot be ignored.
|
|
387
|
+
|
|
388
|
+
- Review each checklist carefully during your implementation
|
|
389
|
+
- Ensure your code and processes satisfy every checklist requirement
|
|
390
|
+
- Include ALL checklist item IDs in your final JSON response under "checklist_item_results" (use the exact UUID from "ID:" field in items list)
|
|
391
|
+
- Set "is_passed": true for completed checklist items, or explain in "notes" why a requirement cannot be met
|
|
392
|
+
- Missing any checklist will cause the entire pipeline to fail
|
|
393
|
+
|
|
394
|
+
Remember: Checklists are not suggestions - they are mandatory quality gates.`;
|
|
395
|
+
if (verbose) {
|
|
396
|
+
logInfo(`Added ${checklistContext.checklists.length} checklists to implementation context`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
243
399
|
return `Implement the complete feature for feature ID: ${featureId}
|
|
244
400
|
|
|
245
|
-
${
|
|
401
|
+
${finalContextInfo}
|
|
246
402
|
|
|
247
403
|
## Implementation Instructions
|
|
248
404
|
|
|
@@ -287,6 +443,8 @@ Follow this systematic approach:
|
|
|
287
443
|
- Maintain existing code quality and patterns
|
|
288
444
|
- Never skip pre-commit checks - always fix the issues
|
|
289
445
|
|
|
446
|
+
${checklistInstructions}
|
|
447
|
+
|
|
290
448
|
Begin by creating a feature branch and analyzing the codebase structure.`;
|
|
291
449
|
};
|
|
292
450
|
const parseImplementationResponse = (response, featureId) => {
|
|
@@ -305,6 +463,7 @@ const parseImplementationResponse = (response, featureId) => {
|
|
|
305
463
|
filesModified: result.files_modified || [],
|
|
306
464
|
commitHash: result.commit_hash || '',
|
|
307
465
|
summary: result.summary || '',
|
|
466
|
+
checklist_item_results: result.checklist_item_results || [],
|
|
308
467
|
};
|
|
309
468
|
}
|
|
310
469
|
}
|
|
@@ -313,7 +472,7 @@ const parseImplementationResponse = (response, featureId) => {
|
|
|
313
472
|
const filesMatch = response.match(/files?[:\s]+([^\n]+)/i);
|
|
314
473
|
const commitMatch = response.match(/commit[:\s]+([a-f0-9]{7,})/i);
|
|
315
474
|
return {
|
|
316
|
-
branchName: branchMatch?.[1] || `
|
|
475
|
+
branchName: branchMatch?.[1] || `dev/${featureId}`,
|
|
317
476
|
filesModified: filesMatch
|
|
318
477
|
? filesMatch[1].split(/[,\s]+/).filter((f) => f)
|
|
319
478
|
: [],
|
|
@@ -324,7 +483,7 @@ const parseImplementationResponse = (response, featureId) => {
|
|
|
324
483
|
catch (error) {
|
|
325
484
|
console.log('Response parsing failed:', error);
|
|
326
485
|
return {
|
|
327
|
-
branchName: `
|
|
486
|
+
branchName: `dev/${featureId}`,
|
|
328
487
|
filesModified: [],
|
|
329
488
|
commitHash: '',
|
|
330
489
|
summary: 'Implementation completed',
|
|
@@ -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(mcpServerUrl: string, mcpToken: string, 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;
|
|
@@ -0,0 +1,86 @@
|
|
|
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 code implementation context information via MCP endpoints
|
|
6
|
+
*/
|
|
7
|
+
export async function fetchCodeImplementationContext(mcpServerUrl, mcpToken, featureId, verbose) {
|
|
8
|
+
try {
|
|
9
|
+
if (verbose) {
|
|
10
|
+
logInfo(`Fetching complete code implementation 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(`✅ Code implementation 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}`);
|
|
25
|
+
logInfo(` Technical Design: ${feature.technical_design ? 'Available' : 'Not available'}`);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
feature,
|
|
29
|
+
product,
|
|
30
|
+
user_stories,
|
|
31
|
+
test_cases,
|
|
32
|
+
technical_design: feature.technical_design,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
37
|
+
logError(`Failed to fetch code implementation context: ${errorMessage}`);
|
|
38
|
+
throw new Error(`Context fetch failed: ${errorMessage}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Format the context into a readable string for Claude Code
|
|
43
|
+
*/
|
|
44
|
+
export function formatContextForPrompt(context) {
|
|
45
|
+
const formatUserStories = (stories) => {
|
|
46
|
+
if (stories.length === 0)
|
|
47
|
+
return 'No user stories defined.';
|
|
48
|
+
return stories
|
|
49
|
+
.map((story, index) => `${index + 1}. **${story.title}** (Status: ${story.status})
|
|
50
|
+
${story.description}`)
|
|
51
|
+
.join('\n\n');
|
|
52
|
+
};
|
|
53
|
+
const formatTestCases = (cases) => {
|
|
54
|
+
if (cases.length === 0)
|
|
55
|
+
return 'No test cases defined.';
|
|
56
|
+
return cases
|
|
57
|
+
.map((testCase, index) => `${index + 1}. **${testCase.name}** ${testCase.is_critical ? '[CRITICAL]' : '[OPTIONAL]'}
|
|
58
|
+
${testCase.description}`)
|
|
59
|
+
.join('\n\n');
|
|
60
|
+
};
|
|
61
|
+
return `# Code Implementation Context
|
|
62
|
+
|
|
63
|
+
## Feature Information
|
|
64
|
+
- **ID**: ${context.feature.id}
|
|
65
|
+
- **Name**: ${context.feature.name}
|
|
66
|
+
- **Description**: ${context.feature.description || 'No description provided'}
|
|
67
|
+
- **Current Status**: ${context.feature.status}
|
|
68
|
+
|
|
69
|
+
## Product Information
|
|
70
|
+
- **Product**: ${context.product.name}
|
|
71
|
+
- **Product ID**: ${context.product.id}
|
|
72
|
+
- **Description**: ${context.product.description || 'No product description'}
|
|
73
|
+
|
|
74
|
+
## User Stories to Implement (${context.user_stories.length})
|
|
75
|
+
${formatUserStories(context.user_stories)}
|
|
76
|
+
|
|
77
|
+
## Test Cases to Satisfy (${context.test_cases.length})
|
|
78
|
+
${formatTestCases(context.test_cases)}
|
|
79
|
+
|
|
80
|
+
## Technical Design
|
|
81
|
+
${context.technical_design || 'No technical design available - implement based on user stories and test cases'}
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
**Implementation Instructions**: Based on the above requirements, user stories, test cases, and technical design, implement the complete feature functionality. Ensure all user stories are implemented and all test cases can pass.`;
|
|
86
|
+
}
|
|
@@ -1,35 +1,6 @@
|
|
|
1
1
|
import { createSdkMcpServer, tool } from '@anthropic-ai/claude-code';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
|
|
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 code implementation
|
|
34
5
|
export const createCodeImplementationMcpServer = (mcpServerUrl, mcpToken) => {
|
|
35
6
|
return createSdkMcpServer({
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { EdsgerConfig, ReviewResult } from '
|
|
1
|
+
import { EdsgerConfig, ReviewResult } from '../../types/index.js';
|
|
2
2
|
export declare const reviewWithClaudeSDK: (config: EdsgerConfig, staged?: boolean, filePatterns?: string[]) => Promise<ReviewResult[]>;
|
|
3
3
|
export declare const checkClaudeCodeSDK: () => Promise<boolean>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { EdsgerConfig, FeatureAnalysisResult } from '
|
|
1
|
+
import { EdsgerConfig, FeatureAnalysisResult } from '../../types/index.js';
|
|
2
|
+
import { ChecklistPhaseContext } from '../../services/checklist.js';
|
|
2
3
|
export interface FeatureAnalysisOptions {
|
|
3
4
|
featureId: string;
|
|
4
5
|
mcpServerUrl: string;
|
|
5
6
|
mcpToken: string;
|
|
6
7
|
verbose?: boolean;
|
|
7
8
|
}
|
|
8
|
-
export declare const analyzeFeatureWithMCP: (options: FeatureAnalysisOptions, config: EdsgerConfig) => Promise<FeatureAnalysisResult>;
|
|
9
|
+
export declare const analyzeFeatureWithMCP: (options: FeatureAnalysisOptions, config: EdsgerConfig, checklistContext?: ChecklistPhaseContext | null) => Promise<FeatureAnalysisResult>;
|
|
9
10
|
export declare const checkFeatureAnalysisRequirements: () => Promise<boolean>;
|