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
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { logInfo, logError } from '../logger.js';
|
|
2
|
+
import { callMcpEndpoint } from './mcp-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get feature details by ID
|
|
5
|
+
*/
|
|
6
|
+
export async function getFeature(mcpServerUrl, mcpToken, featureId, verbose) {
|
|
7
|
+
if (verbose) {
|
|
8
|
+
logInfo(`Fetching feature details for: ${featureId}`);
|
|
9
|
+
}
|
|
10
|
+
const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/get', { feature_id: featureId }));
|
|
11
|
+
if (!result.features || result.features.length === 0) {
|
|
12
|
+
throw new Error(`Feature not found: ${featureId}`);
|
|
13
|
+
}
|
|
14
|
+
return result.features[0];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Update feature with new data
|
|
18
|
+
*/
|
|
19
|
+
export async function updateFeature(mcpServerUrl, mcpToken, featureId, updates, verbose) {
|
|
20
|
+
try {
|
|
21
|
+
if (verbose) {
|
|
22
|
+
logInfo(`Updating feature: ${featureId}`);
|
|
23
|
+
}
|
|
24
|
+
await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/update', {
|
|
25
|
+
feature_id: featureId,
|
|
26
|
+
...updates,
|
|
27
|
+
});
|
|
28
|
+
if (verbose) {
|
|
29
|
+
logInfo('✅ Feature updated successfully');
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
35
|
+
logError(`Failed to update feature: ${errorMessage}`);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Update technical design for a feature
|
|
41
|
+
*/
|
|
42
|
+
export async function updateTechnicalDesign(mcpServerUrl, mcpToken, featureId, technicalDesign, verbose) {
|
|
43
|
+
return updateFeature(mcpServerUrl, mcpToken, featureId, { technical_design: technicalDesign }, verbose);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Update feature status
|
|
47
|
+
*/
|
|
48
|
+
export async function updateFeatureStatus(mcpServerUrl, mcpToken, featureId, status, verbose) {
|
|
49
|
+
return updateFeature(mcpServerUrl, mcpToken, featureId, { status }, verbose);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get user stories for a feature
|
|
53
|
+
*/
|
|
54
|
+
export async function getUserStories(mcpServerUrl, mcpToken, featureId, verbose) {
|
|
55
|
+
if (verbose) {
|
|
56
|
+
logInfo(`Fetching user stories for feature: ${featureId}`);
|
|
57
|
+
}
|
|
58
|
+
const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/list', { feature_id: featureId }));
|
|
59
|
+
return (result.user_stories || []);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create a new user story for a feature
|
|
63
|
+
*/
|
|
64
|
+
export async function createUserStory(mcpServerUrl, mcpToken, featureId, userStory, verbose) {
|
|
65
|
+
try {
|
|
66
|
+
if (verbose) {
|
|
67
|
+
logInfo(`Creating user story for feature: ${featureId}`);
|
|
68
|
+
}
|
|
69
|
+
await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/create', {
|
|
70
|
+
feature_id: featureId,
|
|
71
|
+
user_stories: [
|
|
72
|
+
{
|
|
73
|
+
title: userStory.title,
|
|
74
|
+
description: userStory.description,
|
|
75
|
+
status: userStory.status || 'draft',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
if (verbose) {
|
|
80
|
+
logInfo('✅ User story created successfully');
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
86
|
+
logError(`Failed to create user story: ${errorMessage}`);
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create multiple user stories for a feature
|
|
92
|
+
*/
|
|
93
|
+
export async function createUserStories(mcpServerUrl, mcpToken, featureId, userStories, verbose) {
|
|
94
|
+
try {
|
|
95
|
+
if (verbose) {
|
|
96
|
+
logInfo(`Creating ${userStories.length} user stories for feature: ${featureId}`);
|
|
97
|
+
}
|
|
98
|
+
for (const story of userStories) {
|
|
99
|
+
await createUserStory(mcpServerUrl, mcpToken, featureId, story, false);
|
|
100
|
+
}
|
|
101
|
+
if (verbose) {
|
|
102
|
+
logInfo('✅ All user stories created successfully');
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
108
|
+
logError(`Failed to create user stories: ${errorMessage}`);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get test cases for a feature
|
|
114
|
+
*/
|
|
115
|
+
export async function getTestCases(mcpServerUrl, mcpToken, featureId, verbose) {
|
|
116
|
+
if (verbose) {
|
|
117
|
+
logInfo(`Fetching test cases for feature: ${featureId}`);
|
|
118
|
+
}
|
|
119
|
+
const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/list', { feature_id: featureId }));
|
|
120
|
+
return (result.test_cases || []);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create a new test case for a feature
|
|
124
|
+
*/
|
|
125
|
+
export async function createTestCase(mcpServerUrl, mcpToken, featureId, testCase, verbose) {
|
|
126
|
+
try {
|
|
127
|
+
if (verbose) {
|
|
128
|
+
logInfo(`Creating test case for feature: ${featureId}`);
|
|
129
|
+
}
|
|
130
|
+
await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/create', {
|
|
131
|
+
feature_id: featureId,
|
|
132
|
+
test_cases: [
|
|
133
|
+
{
|
|
134
|
+
name: testCase.name,
|
|
135
|
+
description: testCase.description,
|
|
136
|
+
is_critical: testCase.is_critical || false,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
if (verbose) {
|
|
141
|
+
logInfo('✅ Test case created successfully');
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
147
|
+
logError(`Failed to create test case: ${errorMessage}`);
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Create multiple test cases for a feature
|
|
153
|
+
*/
|
|
154
|
+
export async function createTestCases(mcpServerUrl, mcpToken, featureId, testCases, verbose) {
|
|
155
|
+
try {
|
|
156
|
+
if (verbose) {
|
|
157
|
+
logInfo(`Creating ${testCases.length} test cases for feature: ${featureId}`);
|
|
158
|
+
}
|
|
159
|
+
for (const testCase of testCases) {
|
|
160
|
+
await createTestCase(mcpServerUrl, mcpToken, featureId, testCase, false);
|
|
161
|
+
}
|
|
162
|
+
if (verbose) {
|
|
163
|
+
logInfo('✅ All test cases created successfully');
|
|
164
|
+
}
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
169
|
+
logError(`Failed to create test cases: ${errorMessage}`);
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// FEATURE UTILITY FUNCTIONS
|
|
175
|
+
// ============================================================================
|
|
176
|
+
/**
|
|
177
|
+
* Filter features by status
|
|
178
|
+
*/
|
|
179
|
+
export function filterFeaturesByStatus(features, status) {
|
|
180
|
+
return features.filter(feature => feature.status === status);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Sort features by updated_at (most recent first)
|
|
184
|
+
*/
|
|
185
|
+
export function sortFeaturesByUpdatedAt(features) {
|
|
186
|
+
return [...features].sort((a, b) => {
|
|
187
|
+
const dateA = new Date(a.updated_at || 0).getTime();
|
|
188
|
+
const dateB = new Date(b.updated_at || 0).getTime();
|
|
189
|
+
return dateB - dateA;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get features with ready_for_dev status for a product
|
|
194
|
+
*/
|
|
195
|
+
export async function getReadyForDevFeatures(mcpServerUrl, mcpToken, productId, verbose) {
|
|
196
|
+
if (verbose) {
|
|
197
|
+
logInfo(`Fetching ready_for_dev features for product: ${productId}`);
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
const result = await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/list', {
|
|
201
|
+
product_id: productId,
|
|
202
|
+
status: 'ready_for_dev',
|
|
203
|
+
});
|
|
204
|
+
const features = result.features || [];
|
|
205
|
+
const sortedFeatures = sortFeaturesByUpdatedAt(features);
|
|
206
|
+
if (verbose) {
|
|
207
|
+
logInfo(`✅ Found ${sortedFeatures.length} ready_for_dev features`);
|
|
208
|
+
sortedFeatures.forEach((feature, index) => {
|
|
209
|
+
logInfo(` ${index + 1}. ${feature.name} (updated: ${feature.updated_at})`);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return sortedFeatures;
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
216
|
+
logError(`Failed to fetch ready_for_dev features: ${errorMessage}`);
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common MCP client utilities for making HTTP requests to MCP servers
|
|
3
|
+
*/
|
|
4
|
+
export interface McpRequestOptions {
|
|
5
|
+
mcpServerUrl: string;
|
|
6
|
+
mcpToken: string;
|
|
7
|
+
method: string;
|
|
8
|
+
params: unknown;
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Helper function to make HTTP requests to the MCP server
|
|
13
|
+
*/
|
|
14
|
+
export declare function callMcpEndpoint(mcpServerUrl: string, mcpToken: string, method: string, params: unknown): Promise<unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* Wrapper for making MCP requests with standardized error handling
|
|
17
|
+
*/
|
|
18
|
+
export declare function makeMcpRequest(options: McpRequestOptions): Promise<unknown>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common MCP client utilities for making HTTP requests to MCP servers
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Helper function to make HTTP requests to the MCP server
|
|
6
|
+
*/
|
|
7
|
+
export async function callMcpEndpoint(mcpServerUrl, mcpToken, method, params) {
|
|
8
|
+
try {
|
|
9
|
+
const response = await fetch(`${mcpServerUrl}/mcp`, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
Authorization: `Bearer ${mcpToken}`,
|
|
14
|
+
},
|
|
15
|
+
body: JSON.stringify({
|
|
16
|
+
jsonrpc: '2.0',
|
|
17
|
+
method,
|
|
18
|
+
params,
|
|
19
|
+
id: Math.random().toString(36).substring(7),
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const data = await response.json();
|
|
26
|
+
if (data.error) {
|
|
27
|
+
throw new Error(data.error.message || 'MCP call failed');
|
|
28
|
+
}
|
|
29
|
+
return data.result;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error(`MCP call failed for ${method}:`, error instanceof Error ? error.message : String(error));
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Wrapper for making MCP requests with standardized error handling
|
|
38
|
+
*/
|
|
39
|
+
export async function makeMcpRequest(options) {
|
|
40
|
+
const { mcpServerUrl, mcpToken, method, params, verbose } = options;
|
|
41
|
+
if (verbose) {
|
|
42
|
+
console.log(`Making MCP request: ${method}`);
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const result = await callMcpEndpoint(mcpServerUrl, mcpToken, method, params);
|
|
46
|
+
if (verbose) {
|
|
47
|
+
console.log(`MCP request successful: ${method}`);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
53
|
+
if (verbose) {
|
|
54
|
+
console.error(`MCP request failed: ${method} - ${errorMessage}`);
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ProductInfo {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Get product details by ID
|
|
9
|
+
*/
|
|
10
|
+
export declare function getProduct(mcpServerUrl: string, mcpToken: string, productId: string, verbose?: boolean): Promise<ProductInfo>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { logInfo } from '../utils/logger.js';
|
|
2
|
+
import { callMcpEndpoint } from './mcp-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get product details by ID
|
|
5
|
+
*/
|
|
6
|
+
export async function getProduct(mcpServerUrl, mcpToken, productId, verbose) {
|
|
7
|
+
if (verbose) {
|
|
8
|
+
logInfo(`Fetching product details for: ${productId}`);
|
|
9
|
+
}
|
|
10
|
+
const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'resources/read', { uri: `product://${productId}` }));
|
|
11
|
+
const productText = result.contents?.[0]?.text || '{}';
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(productText);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return {
|
|
17
|
+
id: productId,
|
|
18
|
+
name: 'Unknown Product',
|
|
19
|
+
description: 'Product information could not be loaded',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create test report for a feature
|
|
3
|
+
*/
|
|
4
|
+
export declare function createTestReport(mcpServerUrl: string, mcpToken: string, featureId: string, reportData: {
|
|
5
|
+
test_type: string;
|
|
6
|
+
status: 'passed' | 'failed' | 'error';
|
|
7
|
+
summary: string;
|
|
8
|
+
details?: any;
|
|
9
|
+
}, verbose?: boolean): Promise<boolean>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { logInfo, logError } from '../utils/logger.js';
|
|
2
|
+
import { callMcpEndpoint } from './mcp-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create test report for a feature
|
|
5
|
+
*/
|
|
6
|
+
export async function createTestReport(mcpServerUrl, mcpToken, featureId, reportData, verbose) {
|
|
7
|
+
try {
|
|
8
|
+
if (verbose) {
|
|
9
|
+
logInfo(`Creating test report for feature: ${featureId}`);
|
|
10
|
+
}
|
|
11
|
+
await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_reports/create', {
|
|
12
|
+
feature_id: featureId,
|
|
13
|
+
...reportData,
|
|
14
|
+
});
|
|
15
|
+
if (verbose) {
|
|
16
|
+
logInfo('✅ Test report created successfully');
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
22
|
+
logError(`Failed to create test report: ${errorMessage}`);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { implementFeatureCode, checkCodeImplementationRequirements, } from '../../phases/code-implementation/analyzer.js';
|
|
2
|
+
import { logInfo, logError, logSuccess } from '../../utils/logger.js';
|
|
3
|
+
import { logCodeImplementationResults } from '../formatters/code-implementation-formatter.js';
|
|
4
|
+
import { validateCommandEnvironment, validateRequirements, } from '../utils/validation.js';
|
|
5
|
+
export const runCodeImplementation = async (options) => {
|
|
6
|
+
// Check requirements
|
|
7
|
+
await validateRequirements(checkCodeImplementationRequirements, 'Code implementation requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
|
|
8
|
+
// Validate configuration and MCP environment
|
|
9
|
+
const { config, mcpServerUrl, mcpToken } = validateCommandEnvironment(options);
|
|
10
|
+
if (options.verbose) {
|
|
11
|
+
logInfo(`Starting code implementation for feature: ${options.implement}`);
|
|
12
|
+
}
|
|
13
|
+
logInfo('Starting code implementation...');
|
|
14
|
+
try {
|
|
15
|
+
const implementationResult = await implementFeatureCode({
|
|
16
|
+
featureId: options.implement,
|
|
17
|
+
mcpServerUrl,
|
|
18
|
+
mcpToken,
|
|
19
|
+
verbose: options.verbose,
|
|
20
|
+
}, config);
|
|
21
|
+
// Display results
|
|
22
|
+
logCodeImplementationResults(implementationResult, options.verbose);
|
|
23
|
+
if (implementationResult.status === 'success') {
|
|
24
|
+
logSuccess('Code implementation completed successfully');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
logError('Code implementation failed');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
logError(`Code implementation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { reviewWithClaudeSDK, checkClaudeCodeSDK, } from '../../phases/code-review/reviewer.js';
|
|
2
|
+
import { logInfo, logError, logSuccess, logResults, } from '../../utils/logger.js';
|
|
3
|
+
import { validateConfiguration, validateRequirements, } from '../utils/validation.js';
|
|
4
|
+
export const runCodeReview = async (options) => {
|
|
5
|
+
// Check Claude Code SDK availability
|
|
6
|
+
await validateRequirements(checkClaudeCodeSDK, 'Claude Code SDK not found. Install with: npm install @anthropic-ai/claude-code');
|
|
7
|
+
// Load and validate configuration
|
|
8
|
+
const config = validateConfiguration(options);
|
|
9
|
+
if (options.verbose) {
|
|
10
|
+
logInfo(`Using Claude Code SDK for ${options.staged ? 'staged' : 'all'} changes`);
|
|
11
|
+
}
|
|
12
|
+
logInfo('Starting Claude Code review...');
|
|
13
|
+
try {
|
|
14
|
+
// Use Claude Code SDK to review changes
|
|
15
|
+
const results = await reviewWithClaudeSDK(config, options.staged || false, options.files);
|
|
16
|
+
// Display results
|
|
17
|
+
logResults(results, options.verbose);
|
|
18
|
+
// Determine exit code
|
|
19
|
+
const hasBlockingIssues = results.some((r) => r.status === 'BLOCK');
|
|
20
|
+
const hasWarnings = results.some((r) => r.status === 'WARN');
|
|
21
|
+
const exitCode = hasBlockingIssues || (hasWarnings && config.severity === 'error') ? 1 : 0;
|
|
22
|
+
if (exitCode === 0) {
|
|
23
|
+
logSuccess('Review completed successfully');
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (hasBlockingIssues) {
|
|
27
|
+
logError('Review failed with blocking issues');
|
|
28
|
+
}
|
|
29
|
+
else if (hasWarnings) {
|
|
30
|
+
logError('Review failed with warnings');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
process.exit(exitCode);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
logError(`Review failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { analyzeFeatureWithMCP, checkFeatureAnalysisRequirements, } from '../../phases/feature-analysis/analyzer.js';
|
|
2
|
+
import { logInfo, logError, logSuccess } from '../../utils/logger.js';
|
|
3
|
+
import { logFeatureAnalysisResults } from '../formatters/feature-analysis-formatter.js';
|
|
4
|
+
import { validateCommandEnvironment, validateRequirements, } from '../utils/validation.js';
|
|
5
|
+
export const runFeatureAnalysis = async (options) => {
|
|
6
|
+
// Check requirements
|
|
7
|
+
await validateRequirements(checkFeatureAnalysisRequirements, 'Feature analysis requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
|
|
8
|
+
// Validate configuration and MCP environment
|
|
9
|
+
const { config, mcpServerUrl, mcpToken } = validateCommandEnvironment(options);
|
|
10
|
+
if (options.verbose) {
|
|
11
|
+
logInfo(`Analyzing feature: ${options.featureAnalysis}`);
|
|
12
|
+
}
|
|
13
|
+
logInfo('Starting feature analysis...');
|
|
14
|
+
try {
|
|
15
|
+
const analysisResult = await analyzeFeatureWithMCP({
|
|
16
|
+
featureId: options.featureAnalysis,
|
|
17
|
+
mcpServerUrl,
|
|
18
|
+
mcpToken,
|
|
19
|
+
verbose: options.verbose,
|
|
20
|
+
}, config);
|
|
21
|
+
// Display results
|
|
22
|
+
logFeatureAnalysisResults(analysisResult, options.verbose);
|
|
23
|
+
if (analysisResult.status === 'success') {
|
|
24
|
+
logSuccess('Feature analysis completed successfully');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
logError('Feature analysis failed');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
logError(`Feature analysis failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { runFunctionalTesting, checkFunctionalTestingRequirements, } from '../../phases/functional-testing/analyzer.js';
|
|
2
|
+
import { logInfo, logError, logSuccess } from '../../utils/logger.js';
|
|
3
|
+
import { logFunctionalTestingResults } from '../formatters/functional-testing-formatter.js';
|
|
4
|
+
import { validateCommandEnvironment, validateRequirements, } from '../utils/validation.js';
|
|
5
|
+
export const runFunctionalTestingCommand = async (options) => {
|
|
6
|
+
// Check requirements
|
|
7
|
+
await validateRequirements(checkFunctionalTestingRequirements, 'Functional testing requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
|
|
8
|
+
// Validate configuration and MCP environment
|
|
9
|
+
const { config, mcpServerUrl, mcpToken } = validateCommandEnvironment(options);
|
|
10
|
+
if (options.verbose) {
|
|
11
|
+
logInfo(`Starting functional testing for feature: ${options.test}`);
|
|
12
|
+
}
|
|
13
|
+
logInfo('Starting functional testing...');
|
|
14
|
+
try {
|
|
15
|
+
const testResult = await runFunctionalTesting({
|
|
16
|
+
featureId: options.test,
|
|
17
|
+
mcpServerUrl,
|
|
18
|
+
mcpToken,
|
|
19
|
+
verbose: options.verbose,
|
|
20
|
+
}, config);
|
|
21
|
+
// Display results
|
|
22
|
+
logFunctionalTestingResults(testResult, options.verbose);
|
|
23
|
+
if (testResult.status === 'success') {
|
|
24
|
+
logSuccess('Functional testing completed successfully');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
logError('Functional testing failed');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
logError(`Functional testing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { generateTechnicalDesign, checkTechnicalDesignRequirements, } from '../../phases/technical-design/analyzer.js';
|
|
2
|
+
import { logInfo, logError, logSuccess } from '../../utils/logger.js';
|
|
3
|
+
import { logTechnicalDesignResults } from '../formatters/technical-design-formatter.js';
|
|
4
|
+
import { validateCommandEnvironment, validateRequirements, } from '../utils/validation.js';
|
|
5
|
+
export const runTechnicalDesign = async (options) => {
|
|
6
|
+
// Check requirements
|
|
7
|
+
await validateRequirements(checkTechnicalDesignRequirements, 'Technical design requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
|
|
8
|
+
// Validate configuration and MCP environment
|
|
9
|
+
const { config, mcpServerUrl, mcpToken } = validateCommandEnvironment(options);
|
|
10
|
+
if (options.verbose) {
|
|
11
|
+
logInfo(`Generating technical design for feature: ${options.technicalDesign}`);
|
|
12
|
+
}
|
|
13
|
+
logInfo('Starting technical design generation...');
|
|
14
|
+
try {
|
|
15
|
+
const designResult = await generateTechnicalDesign({
|
|
16
|
+
featureId: options.technicalDesign,
|
|
17
|
+
mcpServerUrl,
|
|
18
|
+
mcpToken,
|
|
19
|
+
verbose: options.verbose,
|
|
20
|
+
}, config);
|
|
21
|
+
// Display results
|
|
22
|
+
logTechnicalDesignResults(designResult, options.verbose);
|
|
23
|
+
if (designResult.status === 'success') {
|
|
24
|
+
logSuccess('Technical design generation completed successfully');
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
logError('Technical design generation failed');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
logError(`Technical design generation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { startWorkflowProcessor } from '../../workflow-runner/workflow-processor.js';
|
|
2
|
+
import { logInfo, logError, logSuccess } from '../../utils/logger.js';
|
|
3
|
+
import { setupWorkflowProcessor } from '../utils/workflow-utils.js';
|
|
4
|
+
export const runWorkflow = async (options) => {
|
|
5
|
+
const { config, params } = setupWorkflowProcessor(options);
|
|
6
|
+
try {
|
|
7
|
+
// Start workflow processor using functional composition
|
|
8
|
+
const startProcessor = startWorkflowProcessor(params, config);
|
|
9
|
+
const processor = await startProcessor();
|
|
10
|
+
// Handle graceful shutdown
|
|
11
|
+
const cleanup = () => {
|
|
12
|
+
logInfo('\n⏹️ Received shutdown signal, stopping workflow processor...');
|
|
13
|
+
processor.stop();
|
|
14
|
+
// Show final stats
|
|
15
|
+
const stats = processor.getStats();
|
|
16
|
+
logInfo('📊 Final Statistics:');
|
|
17
|
+
logInfo(` Total processed: ${stats.totalProcessed}`);
|
|
18
|
+
logInfo(` Completed: ${stats.completed}`);
|
|
19
|
+
logInfo(` Failed: ${stats.failed}`);
|
|
20
|
+
logInfo(` Processing: ${stats.processing}`);
|
|
21
|
+
logSuccess('Workflow processor stopped gracefully');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
};
|
|
24
|
+
// Set up signal handlers for graceful shutdown
|
|
25
|
+
process.on('SIGINT', cleanup);
|
|
26
|
+
process.on('SIGTERM', cleanup);
|
|
27
|
+
// Keep the process running
|
|
28
|
+
process.stdin.resume();
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
logError(`Workflow processor failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const logCodeImplementationResults: (result: {
|
|
2
|
+
featureId: string;
|
|
3
|
+
branchName: string;
|
|
4
|
+
implementationSummary: string | null;
|
|
5
|
+
status: "success" | "error";
|
|
6
|
+
message: string;
|
|
7
|
+
filesModified?: string[];
|
|
8
|
+
commitHash?: string;
|
|
9
|
+
}, verbose?: boolean) => void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const logCodeImplementationResults = (result, verbose) => {
|
|
2
|
+
console.log('\n' + '='.repeat(60));
|
|
3
|
+
console.log('💻 Code Implementation Results');
|
|
4
|
+
console.log('='.repeat(60));
|
|
5
|
+
console.log(`\n📋 Feature ID: ${result.featureId}`);
|
|
6
|
+
console.log(`🌿 Branch: ${result.branchName}`);
|
|
7
|
+
console.log(`📊 Status: ${result.status === 'success' ? '✅ Success' : '❌ Failed'}`);
|
|
8
|
+
if (result.message) {
|
|
9
|
+
console.log(`\n📝 Message: ${result.message}`);
|
|
10
|
+
}
|
|
11
|
+
if (result.implementationSummary) {
|
|
12
|
+
console.log(`\n📄 Implementation Summary:`);
|
|
13
|
+
console.log(result.implementationSummary);
|
|
14
|
+
}
|
|
15
|
+
if (result.filesModified && result.filesModified.length > 0) {
|
|
16
|
+
console.log(`\n📁 Files Modified: ${result.filesModified.length}`);
|
|
17
|
+
if (verbose) {
|
|
18
|
+
result.filesModified.forEach((file) => {
|
|
19
|
+
console.log(` - ${file}`);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (result.commitHash) {
|
|
24
|
+
console.log(`\n🔖 Commit: ${result.commitHash}`);
|
|
25
|
+
}
|
|
26
|
+
console.log('\n' + '='.repeat(60));
|
|
27
|
+
};
|