edsger 0.2.1 → 0.2.3

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 (182) hide show
  1. package/dist/api/features/feature-utils.d.ts +13 -0
  2. package/dist/api/features/feature-utils.js +46 -0
  3. package/dist/api/features/get-feature.d.ts +5 -0
  4. package/dist/api/features/get-feature.js +19 -0
  5. package/dist/api/features/index.d.ts +7 -0
  6. package/dist/api/features/index.js +9 -0
  7. package/dist/api/features/status-updater.d.ts +27 -0
  8. package/dist/api/features/status-updater.js +64 -0
  9. package/dist/api/features/test-cases.d.ts +21 -0
  10. package/dist/api/features/test-cases.js +63 -0
  11. package/dist/api/features/update-feature.d.ts +13 -0
  12. package/dist/api/features/update-feature.js +31 -0
  13. package/dist/api/features/user-stories.d.ts +21 -0
  14. package/dist/api/features/user-stories.js +63 -0
  15. package/dist/api/features.d.ts +100 -0
  16. package/dist/api/features.js +219 -0
  17. package/dist/api/mcp-client.d.ts +18 -0
  18. package/dist/api/mcp-client.js +58 -0
  19. package/dist/api/products.d.ts +10 -0
  20. package/dist/api/products.js +22 -0
  21. package/dist/api/test-reports.d.ts +9 -0
  22. package/dist/api/test-reports.js +25 -0
  23. package/dist/cli/commands/code-implementation-command.d.ts +2 -0
  24. package/dist/cli/commands/code-implementation-command.js +36 -0
  25. package/dist/cli/commands/code-review-command.d.ts +2 -0
  26. package/dist/cli/commands/code-review-command.js +39 -0
  27. package/dist/cli/commands/feature-analysis-command.d.ts +2 -0
  28. package/dist/cli/commands/feature-analysis-command.js +36 -0
  29. package/dist/cli/commands/functional-testing-command.d.ts +2 -0
  30. package/dist/cli/commands/functional-testing-command.js +36 -0
  31. package/dist/cli/commands/technical-design-command.d.ts +2 -0
  32. package/dist/cli/commands/technical-design-command.js +36 -0
  33. package/dist/cli/commands/workflow-command.d.ts +2 -0
  34. package/dist/cli/commands/workflow-command.js +34 -0
  35. package/dist/cli/formatters/code-implementation-formatter.d.ts +9 -0
  36. package/dist/cli/formatters/code-implementation-formatter.js +27 -0
  37. package/dist/cli/formatters/feature-analysis-formatter.d.ts +2 -0
  38. package/dist/cli/formatters/feature-analysis-formatter.js +27 -0
  39. package/dist/cli/formatters/functional-testing-formatter.d.ts +15 -0
  40. package/dist/cli/formatters/functional-testing-formatter.js +37 -0
  41. package/dist/cli/formatters/technical-design-formatter.d.ts +7 -0
  42. package/dist/cli/formatters/technical-design-formatter.js +30 -0
  43. package/dist/cli/index.d.ts +3 -0
  44. package/dist/cli/index.js +99 -0
  45. package/dist/cli/utils/validation.d.ts +25 -0
  46. package/dist/cli/utils/validation.js +58 -0
  47. package/dist/cli/utils/workflow-utils.d.ts +21 -0
  48. package/dist/cli/utils/workflow-utils.js +47 -0
  49. package/dist/cli.d.ts +1 -1
  50. package/dist/cli.js +11 -466
  51. package/dist/config.d.ts +1 -1
  52. package/dist/index.d.ts +3 -3
  53. package/dist/index.js +2 -2
  54. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.d.ts +1 -1
  55. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.js +1 -1
  56. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.d.ts +4 -22
  57. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.js +14 -58
  58. package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.js +1 -30
  59. package/dist/phases/code-implementation/analyzer.d.ts +33 -0
  60. package/dist/{code-implementation → phases/code-implementation}/analyzer.js +178 -19
  61. package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
  62. package/dist/phases/code-implementation/context-fetcher.js +86 -0
  63. package/dist/{code-implementation → phases/code-implementation}/mcp-server.js +1 -30
  64. package/dist/{code-review → phases/code-review}/reviewer.d.ts +1 -1
  65. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.d.ts +3 -2
  66. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.js +35 -127
  67. package/dist/phases/feature-analysis/context-fetcher.d.ts +18 -0
  68. package/dist/phases/feature-analysis/context-fetcher.js +86 -0
  69. package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.js +1 -1
  70. package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.js +1 -24
  71. package/dist/{functional-testing → phases/functional-testing}/analyzer.d.ts +17 -2
  72. package/dist/{functional-testing → phases/functional-testing}/analyzer.js +225 -31
  73. package/dist/phases/functional-testing/context-fetcher.d.ts +16 -0
  74. package/dist/phases/functional-testing/context-fetcher.js +81 -0
  75. package/dist/{functional-testing → phases/functional-testing}/http-fallback.js +1 -1
  76. package/dist/{functional-testing → phases/functional-testing}/index.d.ts +1 -1
  77. package/dist/{functional-testing → phases/functional-testing}/index.js +1 -1
  78. package/dist/{functional-testing → phases/functional-testing}/mcp-server.js +1 -30
  79. package/dist/{functional-testing → phases/functional-testing}/test-report-creator.js +1 -1
  80. package/dist/phases/functional-testing/test-retry-handler.d.ts +16 -0
  81. package/dist/phases/functional-testing/test-retry-handler.js +75 -0
  82. package/dist/{pull-request → phases/pull-request}/creator.js +47 -6
  83. package/dist/phases/pull-request/handler.d.ts +16 -0
  84. package/dist/phases/pull-request/handler.js +60 -0
  85. package/dist/{technical-design → phases/technical-design}/analyzer.d.ts +7 -2
  86. package/dist/phases/technical-design/analyzer.js +424 -0
  87. package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
  88. package/dist/phases/technical-design/context-fetcher.js +39 -0
  89. package/dist/{technical-design → phases/technical-design}/http-fallback.js +1 -1
  90. package/dist/{technical-design → phases/technical-design}/mcp-server.js +1 -30
  91. package/dist/prompts/bug-fixing.d.ts +2 -0
  92. package/dist/prompts/bug-fixing.js +63 -0
  93. package/dist/prompts/code-implementation.d.ts +3 -0
  94. package/dist/prompts/code-implementation.js +132 -0
  95. package/dist/prompts/feature-analysis.d.ts +3 -0
  96. package/dist/prompts/feature-analysis.js +149 -0
  97. package/dist/prompts/formatters.d.ts +42 -0
  98. package/dist/prompts/formatters.js +168 -0
  99. package/dist/prompts/functional-testing.d.ts +3 -0
  100. package/dist/prompts/functional-testing.js +126 -0
  101. package/dist/prompts/index.d.ts +6 -0
  102. package/dist/prompts/index.js +7 -0
  103. package/dist/prompts/technical-design.d.ts +3 -0
  104. package/dist/prompts/technical-design.js +130 -0
  105. package/dist/services/checklist.d.ts +99 -0
  106. package/dist/services/checklist.js +337 -0
  107. package/dist/types/features.d.ts +29 -0
  108. package/dist/types/features.js +1 -0
  109. package/dist/types/index.d.ts +112 -0
  110. package/dist/types/index.js +1 -0
  111. package/dist/types/pipeline.d.ts +25 -0
  112. package/dist/types/pipeline.js +4 -0
  113. package/dist/utils/image-downloader.d.ts +32 -0
  114. package/dist/utils/image-downloader.js +144 -0
  115. package/dist/utils/image-processor.d.ts +5 -0
  116. package/dist/utils/image-processor.js +55 -0
  117. package/dist/utils/logger.d.ts +19 -0
  118. package/dist/utils/logger.js +52 -0
  119. package/dist/utils/pipeline-logger.d.ts +8 -0
  120. package/dist/utils/pipeline-logger.js +35 -0
  121. package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
  122. package/dist/workflow-runner/config/phase-configs.js +34 -0
  123. package/dist/workflow-runner/config/stage-configs.d.ts +5 -0
  124. package/dist/workflow-runner/config/stage-configs.js +34 -0
  125. package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
  126. package/dist/workflow-runner/core/feature-filter.js +46 -0
  127. package/dist/workflow-runner/core/feature-filter.test.d.ts +4 -0
  128. package/dist/workflow-runner/core/feature-filter.test.js +127 -0
  129. package/dist/workflow-runner/core/index.d.ts +8 -0
  130. package/dist/workflow-runner/core/index.js +12 -0
  131. package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
  132. package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
  133. package/dist/workflow-runner/core/state-manager.d.ts +24 -0
  134. package/dist/workflow-runner/core/state-manager.js +42 -0
  135. package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
  136. package/dist/workflow-runner/core/workflow-logger.js +65 -0
  137. package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
  138. package/dist/workflow-runner/executors/phase-executor.js +183 -0
  139. package/dist/workflow-runner/executors/stage-executor.d.ts +8 -0
  140. package/dist/workflow-runner/executors/stage-executor.js +49 -0
  141. package/dist/workflow-runner/feature-service.d.ts +17 -0
  142. package/dist/workflow-runner/feature-service.js +60 -0
  143. package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
  144. package/dist/workflow-runner/feature-workflow-runner.js +113 -0
  145. package/dist/workflow-runner/index.d.ts +0 -1
  146. package/dist/workflow-runner/index.js +0 -1
  147. package/dist/workflow-runner/pipeline-runner.d.ts +9 -19
  148. package/dist/workflow-runner/pipeline-runner.js +247 -256
  149. package/dist/workflow-runner/pipeline.d.ts +18 -0
  150. package/dist/workflow-runner/pipeline.js +197 -0
  151. package/dist/workflow-runner/processor.d.ts +40 -0
  152. package/dist/workflow-runner/processor.js +191 -0
  153. package/dist/workflow-runner/types.d.ts +48 -0
  154. package/dist/workflow-runner/types.js +4 -0
  155. package/dist/workflow-runner/workflow-processor.d.ts +6 -23
  156. package/dist/workflow-runner/workflow-processor.js +38 -100
  157. package/package.json +1 -1
  158. package/dist/code-implementation/analyzer.d.ts +0 -19
  159. package/dist/code-implementation/context-fetcher.d.ts +0 -38
  160. package/dist/code-implementation/context-fetcher.js +0 -147
  161. package/dist/feature-analysis/context-fetcher.d.ts +0 -54
  162. package/dist/feature-analysis/context-fetcher.js +0 -193
  163. package/dist/functional-testing/context-fetcher.d.ts +0 -47
  164. package/dist/functional-testing/context-fetcher.js +0 -192
  165. package/dist/technical-design/analyzer.js +0 -338
  166. package/dist/technical-design/context-fetcher.d.ts +0 -42
  167. package/dist/technical-design/context-fetcher.js +0 -170
  168. /package/dist/{bug-fixing → phases/bug-fixing}/index.d.ts +0 -0
  169. /package/dist/{bug-fixing → phases/bug-fixing}/index.js +0 -0
  170. /package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.d.ts +0 -0
  171. /package/dist/{code-implementation → phases/code-implementation}/mcp-server.d.ts +0 -0
  172. /package/dist/{code-review → phases/code-review}/reviewer.js +0 -0
  173. /package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.d.ts +0 -0
  174. /package/dist/{feature-analysis → phases/feature-analysis}/index.d.ts +0 -0
  175. /package/dist/{feature-analysis → phases/feature-analysis}/index.js +0 -0
  176. /package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.d.ts +0 -0
  177. /package/dist/{functional-testing → phases/functional-testing}/http-fallback.d.ts +0 -0
  178. /package/dist/{functional-testing → phases/functional-testing}/mcp-server.d.ts +0 -0
  179. /package/dist/{functional-testing → phases/functional-testing}/test-report-creator.d.ts +0 -0
  180. /package/dist/{pull-request → phases/pull-request}/creator.d.ts +0 -0
  181. /package/dist/{technical-design → phases/technical-design}/http-fallback.d.ts +0 -0
  182. /package/dist/{technical-design → phases/technical-design}/mcp-server.d.ts +0 -0
@@ -1,193 +0,0 @@
1
- import { logInfo, logError } from '../logger.js';
2
- // Helper function to make HTTP requests to the MCP server
3
- async function callMcpEndpoint(mcpServerUrl, mcpToken, method, params) {
4
- try {
5
- const response = await fetch(`${mcpServerUrl}/mcp`, {
6
- method: 'POST',
7
- headers: {
8
- 'Content-Type': 'application/json',
9
- Authorization: `Bearer ${mcpToken}`,
10
- },
11
- body: JSON.stringify({
12
- jsonrpc: '2.0',
13
- method,
14
- params,
15
- id: Math.random().toString(36).substring(7),
16
- }),
17
- });
18
- if (!response.ok) {
19
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
20
- }
21
- const data = await response.json();
22
- if (data.error) {
23
- throw new Error(data.error.message || 'MCP call failed');
24
- }
25
- return data.result;
26
- }
27
- catch (error) {
28
- console.error(`MCP call failed for ${method}:`, error instanceof Error ? error.message : String(error));
29
- throw error;
30
- }
31
- }
32
- /**
33
- * Fetch all feature analysis context information via MCP endpoints
34
- */
35
- export async function fetchFeatureAnalysisContext(mcpServerUrl, mcpToken, featureId, verbose) {
36
- try {
37
- if (verbose) {
38
- logInfo(`Fetching complete analysis context for feature: ${featureId}`);
39
- }
40
- // Step 1: Get feature details
41
- if (verbose) {
42
- logInfo('1/4 Fetching feature details...');
43
- }
44
- const featureResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/get', { feature_id: featureId }));
45
- if (!featureResult.features || featureResult.features.length === 0) {
46
- throw new Error(`Feature not found: ${featureId}`);
47
- }
48
- const feature = featureResult.features[0];
49
- // Step 2: Get product details
50
- if (verbose) {
51
- logInfo('2/4 Fetching product details...');
52
- }
53
- const productResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'resources/read', {
54
- uri: `product://${feature.product_id}`,
55
- }));
56
- const productText = productResult.contents?.[0]?.text || '{}';
57
- let product;
58
- try {
59
- product = JSON.parse(productText);
60
- }
61
- catch {
62
- product = {
63
- id: feature.product_id,
64
- name: 'Unknown Product',
65
- description: 'Product information could not be loaded',
66
- };
67
- }
68
- // Step 3: Get existing user stories
69
- if (verbose) {
70
- logInfo('3/4 Fetching existing user stories...');
71
- }
72
- const userStoriesResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/list', { feature_id: featureId }));
73
- const existing_user_stories = (userStoriesResult.user_stories ||
74
- []);
75
- // Step 4: Get existing test cases
76
- if (verbose) {
77
- logInfo('4/4 Fetching existing test cases...');
78
- }
79
- const testCasesResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/list', { feature_id: featureId }));
80
- const existing_test_cases = (testCasesResult.test_cases || []);
81
- // Log summary if verbose
82
- if (verbose) {
83
- logInfo(`✅ Context fetched successfully:`);
84
- logInfo(` Feature: ${feature.name}`);
85
- logInfo(` Product: ${product.name}`);
86
- logInfo(` Existing User Stories: ${existing_user_stories.length}`);
87
- logInfo(` Existing Test Cases: ${existing_test_cases.length} (${existing_test_cases.filter((tc) => tc.is_critical).length} critical)`);
88
- }
89
- return {
90
- feature,
91
- product,
92
- existing_user_stories,
93
- existing_test_cases,
94
- };
95
- }
96
- catch (error) {
97
- const errorMessage = error instanceof Error ? error.message : String(error);
98
- logError(`Failed to fetch feature analysis context: ${errorMessage}`);
99
- throw new Error(`Context fetch failed: ${errorMessage}`);
100
- }
101
- }
102
- /**
103
- * Create new user stories via MCP endpoint
104
- */
105
- export async function createUserStories(mcpServerUrl, mcpToken, featureId, userStories, verbose) {
106
- try {
107
- if (verbose) {
108
- logInfo(`Creating ${userStories.length} user stories...`);
109
- }
110
- await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/create', {
111
- feature_id: featureId,
112
- user_stories: userStories,
113
- });
114
- if (verbose) {
115
- logInfo(`✅ User stories created successfully`);
116
- }
117
- return true;
118
- }
119
- catch (error) {
120
- const errorMessage = error instanceof Error ? error.message : String(error);
121
- logError(`Failed to create user stories: ${errorMessage}`);
122
- return false;
123
- }
124
- }
125
- /**
126
- * Create new test cases via MCP endpoint
127
- */
128
- export async function createTestCases(mcpServerUrl, mcpToken, featureId, testCases, verbose) {
129
- try {
130
- if (verbose) {
131
- logInfo(`Creating ${testCases.length} test cases...`);
132
- }
133
- await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/create', {
134
- feature_id: featureId,
135
- test_cases: testCases,
136
- });
137
- if (verbose) {
138
- logInfo(`✅ Test cases created successfully`);
139
- }
140
- return true;
141
- }
142
- catch (error) {
143
- const errorMessage = error instanceof Error ? error.message : String(error);
144
- logError(`Failed to create test cases: ${errorMessage}`);
145
- return false;
146
- }
147
- }
148
- /**
149
- * Format the context into a readable string for Claude Code
150
- */
151
- export function formatContextForPrompt(context) {
152
- const formatUserStories = (stories) => {
153
- if (stories.length === 0)
154
- return 'No existing user stories found.';
155
- return stories
156
- .map((story, index) => `${index + 1}. **${story.title}** (Status: ${story.status})
157
- ${story.description}`)
158
- .join('\n\n');
159
- };
160
- const formatTestCases = (cases) => {
161
- if (cases.length === 0)
162
- return 'No existing test cases found.';
163
- return cases
164
- .map((testCase, index) => `${index + 1}. **${testCase.name}** ${testCase.is_critical ? '[CRITICAL]' : '[OPTIONAL]'}
165
- ${testCase.description}`)
166
- .join('\n\n');
167
- };
168
- return `# Feature Analysis Context
169
-
170
- ## Feature Information
171
- - **ID**: ${context.feature.id}
172
- - **Name**: ${context.feature.name}
173
- - **Description**: ${context.feature.description || 'No description provided'}
174
- - **Current Status**: ${context.feature.status}
175
-
176
- ## Product Information
177
- - **Product**: ${context.product.name}
178
- - **Product ID**: ${context.product.id}
179
- - **Description**: ${context.product.description || 'No product description'}
180
-
181
- ## Technical Design
182
- ${context.feature.technical_design || 'No technical design available'}
183
-
184
- ## Existing User Stories (${context.existing_user_stories.length})
185
- ${formatUserStories(context.existing_user_stories)}
186
-
187
- ## Existing Test Cases (${context.existing_test_cases.length})
188
- ${formatTestCases(context.existing_test_cases)}
189
-
190
- ---
191
-
192
- **Analysis Instructions**: Based on the above feature and product information, create comprehensive user stories and test cases. Avoid duplicating existing ones and focus on adding business value through new user perspectives and scenarios.`;
193
- }
@@ -1,47 +0,0 @@
1
- export interface FeatureTestingContext {
2
- feature: {
3
- id: string;
4
- name: string;
5
- description?: string;
6
- technical_design?: string;
7
- status: string;
8
- product_id: string;
9
- };
10
- product: {
11
- id: string;
12
- name: string;
13
- description?: string;
14
- [key: string]: any;
15
- };
16
- user_stories: Array<{
17
- id: string;
18
- title: string;
19
- description: string;
20
- status: string;
21
- [key: string]: any;
22
- }>;
23
- test_cases: Array<{
24
- id: string;
25
- name: string;
26
- description: string;
27
- is_critical: boolean;
28
- [key: string]: any;
29
- }>;
30
- environment_config: {
31
- environment: string;
32
- login_username: string;
33
- login_password: string;
34
- };
35
- }
36
- /**
37
- * Fetch all feature testing context information via MCP endpoints
38
- */
39
- export declare function fetchFeatureTestingContext(mcpServerUrl: string, mcpToken: string, featureId: string, verbose?: boolean): Promise<FeatureTestingContext>;
40
- /**
41
- * Update the test status of a feature via MCP endpoint
42
- */
43
- export declare function updateFeatureTestStatus(mcpServerUrl: string, mcpToken: string, featureId: string, testStatus: 'testing_in_progress' | 'testing_passed' | 'testing_failed', verbose?: boolean): Promise<boolean>;
44
- /**
45
- * Format the context into a readable string for Claude Code
46
- */
47
- export declare function formatContextForPrompt(context: FeatureTestingContext): string;
@@ -1,192 +0,0 @@
1
- import { logInfo, logError } from '../logger.js';
2
- // Helper function to make HTTP requests to the MCP server
3
- async function callMcpEndpoint(mcpServerUrl, mcpToken, method, params) {
4
- try {
5
- const response = await fetch(`${mcpServerUrl}/mcp`, {
6
- method: 'POST',
7
- headers: {
8
- 'Content-Type': 'application/json',
9
- Authorization: `Bearer ${mcpToken}`,
10
- },
11
- body: JSON.stringify({
12
- jsonrpc: '2.0',
13
- method,
14
- params,
15
- id: Math.random().toString(36).substring(7),
16
- }),
17
- });
18
- if (!response.ok) {
19
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
20
- }
21
- const data = await response.json();
22
- if (data.error) {
23
- throw new Error(data.error.message || 'MCP call failed');
24
- }
25
- return data.result;
26
- }
27
- catch (error) {
28
- console.error(`MCP call failed for ${method}:`, error instanceof Error ? error.message : String(error));
29
- throw error;
30
- }
31
- }
32
- /**
33
- * Fetch all feature testing context information via MCP endpoints
34
- */
35
- export async function fetchFeatureTestingContext(mcpServerUrl, mcpToken, featureId, verbose) {
36
- try {
37
- if (verbose) {
38
- logInfo(`Fetching complete testing context for feature: ${featureId}`);
39
- }
40
- // Step 1: Get feature details
41
- if (verbose) {
42
- logInfo('1/5 Fetching feature details...');
43
- }
44
- const featureResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/get', { feature_id: featureId }));
45
- if (!featureResult.features || featureResult.features.length === 0) {
46
- throw new Error(`Feature not found: ${featureId}`);
47
- }
48
- const feature = featureResult.features[0];
49
- // Step 2: Get product details
50
- if (verbose) {
51
- logInfo('2/5 Fetching product details...');
52
- }
53
- const productResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'resources/read', {
54
- uri: `product://${feature.product_id}`,
55
- }));
56
- const productText = productResult.contents?.[0]?.text || '{}';
57
- let product;
58
- try {
59
- product = JSON.parse(productText);
60
- }
61
- catch {
62
- product = {
63
- id: feature.product_id,
64
- name: 'Unknown Product',
65
- description: 'Product information could not be loaded',
66
- };
67
- }
68
- // Step 3: Get user stories
69
- if (verbose) {
70
- logInfo('3/5 Fetching user stories...');
71
- }
72
- const userStoriesResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/list', { feature_id: featureId }));
73
- const user_stories = (userStoriesResult.user_stories || []);
74
- // Step 4: Get test cases
75
- if (verbose) {
76
- logInfo('4/5 Fetching test cases...');
77
- }
78
- const testCasesResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/list', { feature_id: featureId }));
79
- const test_cases = (testCasesResult.test_cases || []);
80
- // Step 5: Get environment configuration
81
- if (verbose) {
82
- logInfo('5/5 Preparing environment configuration...');
83
- }
84
- const environment_config = {
85
- environment: 'testing',
86
- login_username: process.env.TESTING_LOGIN_USERNAME || '',
87
- login_password: process.env.TESTING_LOGIN_PASSWORD || '',
88
- };
89
- // Validate required credentials
90
- if (!environment_config.login_username ||
91
- !environment_config.login_password) {
92
- throw new Error('Testing credentials not configured. Set TESTING_LOGIN_USERNAME and TESTING_LOGIN_PASSWORD environment variables.');
93
- }
94
- // Log summary if verbose
95
- if (verbose) {
96
- logInfo(`✅ Context fetched successfully:`);
97
- logInfo(` Feature: ${feature.name}`);
98
- logInfo(` Product: ${product.name}`);
99
- logInfo(` User Stories: ${user_stories.length}`);
100
- logInfo(` Test Cases: ${test_cases.length} (${test_cases.filter((tc) => tc.is_critical).length} critical)`);
101
- logInfo(` Environment: ${environment_config.environment}`);
102
- logInfo(` Login: ${environment_config.login_username}`);
103
- }
104
- return {
105
- feature,
106
- product,
107
- user_stories,
108
- test_cases,
109
- environment_config,
110
- };
111
- }
112
- catch (error) {
113
- const errorMessage = error instanceof Error ? error.message : String(error);
114
- logError(`Failed to fetch feature testing context: ${errorMessage}`);
115
- throw new Error(`Context fetch failed: ${errorMessage}`);
116
- }
117
- }
118
- /**
119
- * Update the test status of a feature via MCP endpoint
120
- */
121
- export async function updateFeatureTestStatus(mcpServerUrl, mcpToken, featureId, testStatus, verbose) {
122
- try {
123
- if (verbose) {
124
- logInfo(`Updating test status to: ${testStatus}`);
125
- }
126
- // Only update the status field - test results are stored in test_reports table
127
- await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/update', {
128
- feature_id: featureId,
129
- status: testStatus,
130
- });
131
- if (verbose) {
132
- logInfo(`✅ Test status updated successfully`);
133
- }
134
- return true;
135
- }
136
- catch (error) {
137
- const errorMessage = error instanceof Error ? error.message : String(error);
138
- logError(`Failed to update test status: ${errorMessage}`);
139
- return false;
140
- }
141
- }
142
- /**
143
- * Format the context into a readable string for Claude Code
144
- */
145
- export function formatContextForPrompt(context) {
146
- const formatUserStories = (stories) => {
147
- if (stories.length === 0)
148
- return 'No user stories defined.';
149
- return stories
150
- .map((story, index) => `${index + 1}. **${story.title}** (Status: ${story.status})
151
- ${story.description}`)
152
- .join('\n\n');
153
- };
154
- const formatTestCases = (cases) => {
155
- if (cases.length === 0)
156
- return 'No test cases defined.';
157
- return cases
158
- .map((testCase, index) => `${index + 1}. **${testCase.name}** ${testCase.is_critical ? '[CRITICAL]' : '[OPTIONAL]'}
159
- ${testCase.description}`)
160
- .join('\n\n');
161
- };
162
- return `# Feature Testing Context
163
-
164
- ## Feature Information
165
- - **ID**: ${context.feature.id}
166
- - **Name**: ${context.feature.name}
167
- - **Description**: ${context.feature.description || 'No description provided'}
168
- - **Current Test Status**: ${context.feature.status}
169
-
170
- ## Product Information
171
- - **Product**: ${context.product.name}
172
- - **Product ID**: ${context.product.id}
173
- - **Description**: ${context.product.description || 'No product description'}
174
-
175
- ## User Stories (${context.user_stories.length})
176
- ${formatUserStories(context.user_stories)}
177
-
178
- ## Test Cases (${context.test_cases.length})
179
- ${formatTestCases(context.test_cases)}
180
-
181
- ## Technical Design
182
- ${context.feature.technical_design || 'No technical design available'}
183
-
184
- ## Environment Configuration
185
- - **Environment**: ${context.environment_config.environment}
186
- - **Login Username**: ${context.environment_config.login_username}
187
- - **Login Password**: ${context.environment_config.login_password}
188
-
189
- ---
190
-
191
- **Testing Instructions**: Use the above information to perform comprehensive functional testing. Focus on critical test cases and ensure all user stories are properly validated.`;
192
- }