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.
Files changed (178) hide show
  1. package/dist/api/features/feature-utils.d.ts +13 -0
  2. package/dist/api/features/feature-utils.js +46 -0
  3. package/dist/api/features/get-feature.d.ts +5 -0
  4. package/dist/api/features/get-feature.js +19 -0
  5. package/dist/api/features/index.d.ts +7 -0
  6. package/dist/api/features/index.js +9 -0
  7. package/dist/api/features/status-updater.d.ts +27 -0
  8. package/dist/api/features/status-updater.js +64 -0
  9. package/dist/api/features/test-cases.d.ts +21 -0
  10. package/dist/api/features/test-cases.js +63 -0
  11. package/dist/api/features/update-feature.d.ts +13 -0
  12. package/dist/api/features/update-feature.js +31 -0
  13. package/dist/api/features/user-stories.d.ts +21 -0
  14. package/dist/api/features/user-stories.js +63 -0
  15. package/dist/api/features.d.ts +100 -0
  16. package/dist/api/features.js +219 -0
  17. package/dist/api/mcp-client.d.ts +18 -0
  18. package/dist/api/mcp-client.js +58 -0
  19. package/dist/api/products.d.ts +10 -0
  20. package/dist/api/products.js +22 -0
  21. package/dist/api/test-reports.d.ts +9 -0
  22. package/dist/api/test-reports.js +25 -0
  23. package/dist/cli/commands/code-implementation-command.d.ts +2 -0
  24. package/dist/cli/commands/code-implementation-command.js +36 -0
  25. package/dist/cli/commands/code-review-command.d.ts +2 -0
  26. package/dist/cli/commands/code-review-command.js +39 -0
  27. package/dist/cli/commands/feature-analysis-command.d.ts +2 -0
  28. package/dist/cli/commands/feature-analysis-command.js +36 -0
  29. package/dist/cli/commands/functional-testing-command.d.ts +2 -0
  30. package/dist/cli/commands/functional-testing-command.js +36 -0
  31. package/dist/cli/commands/technical-design-command.d.ts +2 -0
  32. package/dist/cli/commands/technical-design-command.js +36 -0
  33. package/dist/cli/commands/workflow-command.d.ts +2 -0
  34. package/dist/cli/commands/workflow-command.js +34 -0
  35. package/dist/cli/formatters/code-implementation-formatter.d.ts +9 -0
  36. package/dist/cli/formatters/code-implementation-formatter.js +27 -0
  37. package/dist/cli/formatters/feature-analysis-formatter.d.ts +2 -0
  38. package/dist/cli/formatters/feature-analysis-formatter.js +27 -0
  39. package/dist/cli/formatters/functional-testing-formatter.d.ts +15 -0
  40. package/dist/cli/formatters/functional-testing-formatter.js +37 -0
  41. package/dist/cli/formatters/technical-design-formatter.d.ts +7 -0
  42. package/dist/cli/formatters/technical-design-formatter.js +30 -0
  43. package/dist/cli/index.d.ts +3 -0
  44. package/dist/cli/index.js +99 -0
  45. package/dist/cli/utils/validation.d.ts +25 -0
  46. package/dist/cli/utils/validation.js +58 -0
  47. package/dist/cli/utils/workflow-utils.d.ts +21 -0
  48. package/dist/cli/utils/workflow-utils.js +47 -0
  49. package/dist/cli.d.ts +1 -1
  50. package/dist/cli.js +11 -466
  51. package/dist/config.d.ts +1 -1
  52. package/dist/index.d.ts +3 -3
  53. package/dist/index.js +2 -2
  54. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.d.ts +1 -1
  55. package/dist/{bug-fixing → phases/bug-fixing}/analyzer.js +1 -1
  56. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.d.ts +4 -22
  57. package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.js +14 -58
  58. package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.js +1 -30
  59. package/dist/phases/code-implementation/analyzer.d.ts +33 -0
  60. package/dist/{code-implementation → phases/code-implementation}/analyzer.js +174 -15
  61. package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
  62. package/dist/phases/code-implementation/context-fetcher.js +86 -0
  63. package/dist/{code-implementation → phases/code-implementation}/mcp-server.js +1 -30
  64. package/dist/{code-review → phases/code-review}/reviewer.d.ts +1 -1
  65. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.d.ts +3 -2
  66. package/dist/{feature-analysis → phases/feature-analysis}/analyzer.js +29 -127
  67. package/dist/phases/feature-analysis/context-fetcher.d.ts +18 -0
  68. package/dist/phases/feature-analysis/context-fetcher.js +86 -0
  69. package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.js +1 -1
  70. package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.js +1 -24
  71. package/dist/{functional-testing → phases/functional-testing}/analyzer.d.ts +17 -2
  72. package/dist/{functional-testing → phases/functional-testing}/analyzer.js +225 -31
  73. package/dist/phases/functional-testing/context-fetcher.d.ts +16 -0
  74. package/dist/phases/functional-testing/context-fetcher.js +81 -0
  75. package/dist/{functional-testing → phases/functional-testing}/http-fallback.js +1 -1
  76. package/dist/{functional-testing → phases/functional-testing}/index.d.ts +1 -1
  77. package/dist/{functional-testing → phases/functional-testing}/index.js +1 -1
  78. package/dist/{functional-testing → phases/functional-testing}/mcp-server.js +1 -30
  79. package/dist/{functional-testing → phases/functional-testing}/test-report-creator.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 +418 -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 +29 -0
  98. package/dist/prompts/formatters.js +139 -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/logger.d.ts +19 -0
  114. package/dist/utils/logger.js +52 -0
  115. package/dist/utils/pipeline-logger.d.ts +8 -0
  116. package/dist/utils/pipeline-logger.js +35 -0
  117. package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
  118. package/dist/workflow-runner/config/phase-configs.js +34 -0
  119. package/dist/workflow-runner/config/stage-configs.d.ts +5 -0
  120. package/dist/workflow-runner/config/stage-configs.js +34 -0
  121. package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
  122. package/dist/workflow-runner/core/feature-filter.js +46 -0
  123. package/dist/workflow-runner/core/feature-filter.test.d.ts +4 -0
  124. package/dist/workflow-runner/core/feature-filter.test.js +127 -0
  125. package/dist/workflow-runner/core/index.d.ts +8 -0
  126. package/dist/workflow-runner/core/index.js +12 -0
  127. package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
  128. package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
  129. package/dist/workflow-runner/core/state-manager.d.ts +24 -0
  130. package/dist/workflow-runner/core/state-manager.js +42 -0
  131. package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
  132. package/dist/workflow-runner/core/workflow-logger.js +65 -0
  133. package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
  134. package/dist/workflow-runner/executors/phase-executor.js +183 -0
  135. package/dist/workflow-runner/executors/stage-executor.d.ts +8 -0
  136. package/dist/workflow-runner/executors/stage-executor.js +49 -0
  137. package/dist/workflow-runner/feature-service.d.ts +17 -0
  138. package/dist/workflow-runner/feature-service.js +60 -0
  139. package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
  140. package/dist/workflow-runner/feature-workflow-runner.js +113 -0
  141. package/dist/workflow-runner/index.d.ts +0 -1
  142. package/dist/workflow-runner/index.js +0 -1
  143. package/dist/workflow-runner/pipeline-runner.d.ts +9 -19
  144. package/dist/workflow-runner/pipeline-runner.js +247 -256
  145. package/dist/workflow-runner/pipeline.d.ts +18 -0
  146. package/dist/workflow-runner/pipeline.js +197 -0
  147. package/dist/workflow-runner/processor.d.ts +40 -0
  148. package/dist/workflow-runner/processor.js +191 -0
  149. package/dist/workflow-runner/types.d.ts +48 -0
  150. package/dist/workflow-runner/types.js +4 -0
  151. package/dist/workflow-runner/workflow-processor.d.ts +6 -23
  152. package/dist/workflow-runner/workflow-processor.js +38 -100
  153. package/package.json +1 -1
  154. package/dist/code-implementation/analyzer.d.ts +0 -19
  155. package/dist/code-implementation/context-fetcher.d.ts +0 -38
  156. package/dist/code-implementation/context-fetcher.js +0 -147
  157. package/dist/feature-analysis/context-fetcher.d.ts +0 -54
  158. package/dist/feature-analysis/context-fetcher.js +0 -193
  159. package/dist/functional-testing/context-fetcher.d.ts +0 -47
  160. package/dist/functional-testing/context-fetcher.js +0 -192
  161. package/dist/technical-design/analyzer.js +0 -338
  162. package/dist/technical-design/context-fetcher.d.ts +0 -42
  163. package/dist/technical-design/context-fetcher.js +0 -170
  164. /package/dist/{bug-fixing → phases/bug-fixing}/index.d.ts +0 -0
  165. /package/dist/{bug-fixing → phases/bug-fixing}/index.js +0 -0
  166. /package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.d.ts +0 -0
  167. /package/dist/{code-implementation → phases/code-implementation}/mcp-server.d.ts +0 -0
  168. /package/dist/{code-review → phases/code-review}/reviewer.js +0 -0
  169. /package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.d.ts +0 -0
  170. /package/dist/{feature-analysis → phases/feature-analysis}/index.d.ts +0 -0
  171. /package/dist/{feature-analysis → phases/feature-analysis}/index.js +0 -0
  172. /package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.d.ts +0 -0
  173. /package/dist/{functional-testing → phases/functional-testing}/http-fallback.d.ts +0 -0
  174. /package/dist/{functional-testing → phases/functional-testing}/mcp-server.d.ts +0 -0
  175. /package/dist/{functional-testing → phases/functional-testing}/test-report-creator.d.ts +0 -0
  176. /package/dist/{pull-request → phases/pull-request}/creator.d.ts +0 -0
  177. /package/dist/{technical-design → phases/technical-design}/http-fallback.d.ts +0 -0
  178. /package/dist/{technical-design → phases/technical-design}/mcp-server.d.ts +0 -0
package/dist/cli.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ var _a, _b, _c;
2
3
  import { Command } from 'commander';
3
4
  import { readFileSync } from 'fs';
4
5
  import { join, dirname } from 'path';
5
6
  import { fileURLToPath } from 'url';
6
7
  import { config as dotenvConfig } from 'dotenv';
7
- import { loadConfig, validateConfig } from './config.js';
8
- import { reviewWithClaudeSDK, checkClaudeCodeSDK, } from './code-review/reviewer.js';
9
- import { analyzeFeatureWithMCP, checkFeatureAnalysisRequirements, } from './feature-analysis/analyzer.js';
10
- import { generateTechnicalDesign, checkTechnicalDesignRequirements, } from './technical-design/analyzer.js';
11
- import { implementFeatureCode, checkCodeImplementationRequirements, } from './code-implementation/analyzer.js';
12
- import { runFunctionalTesting, checkFunctionalTestingRequirements, } from './functional-testing/analyzer.js';
13
- import { startWorkflowProcessor } from './workflow-runner/workflow-processor.js';
14
- import { logInfo, logError, logSuccess, logResults } from './logger.js';
8
+ import { logError } from './utils/logger.js';
9
+ import { runWorkflow } from './cli/commands/workflow-command.js';
10
+ import { runFeatureAnalysis } from './cli/commands/feature-analysis-command.js';
11
+ import { runTechnicalDesign } from './cli/commands/technical-design-command.js';
12
+ import { runCodeImplementation } from './cli/commands/code-implementation-command.js';
13
+ import { runFunctionalTestingCommand } from './cli/commands/functional-testing-command.js';
14
+ import { runCodeReview } from './cli/commands/code-review-command.js';
15
15
  // Get package.json version dynamically
16
16
  const __filename = fileURLToPath(import.meta.url);
17
17
  const __dirname = dirname(__filename);
@@ -89,467 +89,12 @@ export const runEdsger = async (options) => {
89
89
  await runCodeReview(options);
90
90
  }
91
91
  };
92
- const runWorkflow = async (options) => {
93
- // Load configuration
94
- const config = loadConfig(options.config);
95
- const configErrors = validateConfig(config);
96
- if (configErrors.length > 0) {
97
- throw new Error(`Configuration errors:\n${configErrors.map((e) => ` - ${e}`).join('\n')}`);
98
- }
99
- if (options.verbose) {
100
- logInfo('Configuration loaded successfully');
101
- logInfo('Starting workflow processor mode...');
102
- }
103
- // Get environment variables
104
- const productId = process.env.EDSGER_PRODUCT_ID;
105
- const mcpServerUrl = process.env.EDSGER_MCP_SERVER_URL;
106
- const mcpToken = process.env.EDSGER_MCP_TOKEN;
107
- if (!productId) {
108
- throw new Error('Product ID is required. Set EDSGER_PRODUCT_ID environment variable.');
109
- }
110
- if (!mcpServerUrl) {
111
- throw new Error('MCP server URL is required. Set EDSGER_MCP_SERVER_URL environment variable.');
112
- }
113
- if (!mcpToken) {
114
- throw new Error('MCP token is required. Set EDSGER_MCP_TOKEN environment variable.');
115
- }
116
- // Validate MCP server URL format
117
- try {
118
- new URL(mcpServerUrl);
119
- }
120
- catch {
121
- throw new Error('Invalid MCP server URL format. Use http:// or https://');
122
- }
123
- logInfo('🚀 Starting workflow processor...');
124
- try {
125
- // Start workflow processor using functional composition
126
- const startProcessor = startWorkflowProcessor({
127
- productId,
128
- mcpServerUrl,
129
- mcpToken,
130
- verbose: options.verbose,
131
- }, config);
132
- const processor = await startProcessor();
133
- // Handle graceful shutdown
134
- const cleanup = () => {
135
- logInfo('\n⏹️ Received shutdown signal, stopping workflow processor...');
136
- processor.stop();
137
- // Show final stats
138
- const stats = processor.getStats();
139
- logInfo('📊 Final Statistics:');
140
- logInfo(` Total processed: ${stats.totalProcessed}`);
141
- logInfo(` Completed: ${stats.completed}`);
142
- logInfo(` Failed: ${stats.failed}`);
143
- logInfo(` Processing: ${stats.processing}`);
144
- logSuccess('Workflow processor stopped gracefully');
145
- process.exit(0);
146
- };
147
- // Set up signal handlers for graceful shutdown
148
- process.on('SIGINT', cleanup);
149
- process.on('SIGTERM', cleanup);
150
- // Keep the process running
151
- process.stdin.resume();
152
- }
153
- catch (error) {
154
- logError(`Workflow processor failed: ${error instanceof Error ? error.message : String(error)}`);
155
- process.exit(1);
156
- }
157
- };
158
- const runFeatureAnalysis = async (options) => {
159
- // Check requirements
160
- const hasRequirements = await checkFeatureAnalysisRequirements();
161
- if (!hasRequirements) {
162
- throw new Error('Feature analysis requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
163
- }
164
- // Load configuration
165
- const config = loadConfig(options.config);
166
- const configErrors = validateConfig(config);
167
- if (configErrors.length > 0) {
168
- throw new Error(`Configuration errors:\n${configErrors.map((e) => ` - ${e}`).join('\n')}`);
169
- }
170
- if (options.verbose) {
171
- logInfo('Configuration loaded successfully');
172
- logInfo(`Analyzing feature: ${options.featureAnalysis}`);
173
- }
174
- // Get MCP configuration from environment or config
175
- const mcpServerUrl = process.env.EDSGER_MCP_SERVER_URL;
176
- const mcpToken = process.env.EDSGER_MCP_TOKEN;
177
- if (!mcpServerUrl) {
178
- throw new Error('MCP server URL is required. Set EDSGER_MCP_SERVER_URL environment variable.');
179
- }
180
- if (!mcpToken) {
181
- throw new Error('MCP token is required. Set EDSGER_MCP_TOKEN environment variable.');
182
- }
183
- // Validate MCP server URL format
184
- try {
185
- new URL(mcpServerUrl);
186
- }
187
- catch {
188
- throw new Error('Invalid MCP server URL format. Use http:// or https://');
189
- }
190
- logInfo('Starting feature analysis...');
191
- try {
192
- const analysisResult = await analyzeFeatureWithMCP({
193
- featureId: options.featureAnalysis,
194
- mcpServerUrl,
195
- mcpToken,
196
- verbose: options.verbose,
197
- }, config);
198
- // Display results
199
- logFeatureAnalysisResults(analysisResult, options.verbose);
200
- if (analysisResult.status === 'success') {
201
- logSuccess('Feature analysis completed successfully');
202
- process.exit(0);
203
- }
204
- else {
205
- logError('Feature analysis failed');
206
- process.exit(1);
207
- }
208
- }
209
- catch (error) {
210
- logError(`Feature analysis failed: ${error instanceof Error ? error.message : String(error)}`);
211
- process.exit(1);
212
- }
213
- };
214
- const runCodeImplementation = async (options) => {
215
- // Check requirements
216
- const hasRequirements = await checkCodeImplementationRequirements();
217
- if (!hasRequirements) {
218
- throw new Error('Code implementation requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
219
- }
220
- // Load configuration
221
- const config = loadConfig(options.config);
222
- const configErrors = validateConfig(config);
223
- if (configErrors.length > 0) {
224
- throw new Error(`Configuration errors:\n${configErrors.map((e) => ` - ${e}`).join('\n')}`);
225
- }
226
- if (options.verbose) {
227
- logInfo('Configuration loaded successfully');
228
- logInfo(`Starting code implementation for feature: ${options.implement}`);
229
- }
230
- // Get MCP configuration from environment or config
231
- const mcpServerUrl = process.env.EDSGER_MCP_SERVER_URL;
232
- const mcpToken = process.env.EDSGER_MCP_TOKEN;
233
- if (!mcpServerUrl) {
234
- throw new Error('MCP server URL is required. Set EDSGER_MCP_SERVER_URL environment variable.');
235
- }
236
- if (!mcpToken) {
237
- throw new Error('MCP token is required. Set EDSGER_MCP_TOKEN environment variable.');
238
- }
239
- // Validate MCP server URL format
240
- try {
241
- new URL(mcpServerUrl);
242
- }
243
- catch {
244
- throw new Error('Invalid MCP server URL format. Use http:// or https://');
245
- }
246
- logInfo('Starting code implementation...');
247
- try {
248
- const implementationResult = await implementFeatureCode({
249
- featureId: options.implement,
250
- mcpServerUrl,
251
- mcpToken,
252
- verbose: options.verbose,
253
- }, config);
254
- // Display results
255
- logCodeImplementationResults(implementationResult, options.verbose);
256
- if (implementationResult.status === 'success') {
257
- logSuccess('Code implementation completed successfully');
258
- process.exit(0);
259
- }
260
- else {
261
- logError('Code implementation failed');
262
- process.exit(1);
263
- }
264
- }
265
- catch (error) {
266
- logError(`Code implementation failed: ${error instanceof Error ? error.message : String(error)}`);
267
- process.exit(1);
268
- }
269
- };
270
- const runTechnicalDesign = async (options) => {
271
- // Check requirements
272
- const hasRequirements = await checkTechnicalDesignRequirements();
273
- if (!hasRequirements) {
274
- throw new Error('Technical design requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
275
- }
276
- // Load configuration
277
- const config = loadConfig(options.config);
278
- const configErrors = validateConfig(config);
279
- if (configErrors.length > 0) {
280
- throw new Error(`Configuration errors:\n${configErrors.map((e) => ` - ${e}`).join('\n')}`);
281
- }
282
- if (options.verbose) {
283
- logInfo('Configuration loaded successfully');
284
- logInfo(`Generating technical design for feature: ${options.technicalDesign}`);
285
- }
286
- // Get MCP configuration from environment or config
287
- const mcpServerUrl = process.env.EDSGER_MCP_SERVER_URL;
288
- const mcpToken = process.env.EDSGER_MCP_TOKEN;
289
- if (!mcpServerUrl) {
290
- throw new Error('MCP server URL is required. Set EDSGER_MCP_SERVER_URL environment variable.');
291
- }
292
- if (!mcpToken) {
293
- throw new Error('MCP token is required. Set EDSGER_MCP_TOKEN environment variable.');
294
- }
295
- // Validate MCP server URL format
296
- try {
297
- new URL(mcpServerUrl);
298
- }
299
- catch {
300
- throw new Error('Invalid MCP server URL format. Use http:// or https://');
301
- }
302
- logInfo('Starting technical design generation...');
303
- try {
304
- const designResult = await generateTechnicalDesign({
305
- featureId: options.technicalDesign,
306
- mcpServerUrl,
307
- mcpToken,
308
- verbose: options.verbose,
309
- }, config);
310
- // Display results
311
- logTechnicalDesignResults(designResult, options.verbose);
312
- if (designResult.status === 'success') {
313
- logSuccess('Technical design generation completed successfully');
314
- process.exit(0);
315
- }
316
- else {
317
- logError('Technical design generation failed');
318
- process.exit(1);
319
- }
320
- }
321
- catch (error) {
322
- logError(`Technical design generation failed: ${error instanceof Error ? error.message : String(error)}`);
323
- process.exit(1);
324
- }
325
- };
326
- const runCodeReview = async (options) => {
327
- // Check Claude Code SDK availability
328
- const hasSDK = await checkClaudeCodeSDK();
329
- if (!hasSDK) {
330
- throw new Error('Claude Code SDK not found. Install with: npm install @anthropic-ai/claude-code');
331
- }
332
- // Load and validate configuration
333
- const config = loadConfig(options.config);
334
- const configErrors = validateConfig(config);
335
- if (configErrors.length > 0) {
336
- throw new Error(`Configuration errors:\n${configErrors.map((e) => ` - ${e}`).join('\n')}`);
337
- }
338
- if (options.verbose) {
339
- logInfo('Configuration loaded successfully');
340
- logInfo(`Using Claude Code SDK for ${options.staged ? 'staged' : 'all'} changes`);
341
- }
342
- logInfo('Starting Claude Code review...');
343
- try {
344
- // Use Claude Code SDK to review changes
345
- const results = await reviewWithClaudeSDK(config, options.staged || false, options.files);
346
- // Display results
347
- logResults(results, options.verbose);
348
- // Determine exit code
349
- const hasBlockingIssues = results.some((r) => r.status === 'BLOCK');
350
- const hasWarnings = results.some((r) => r.status === 'WARN');
351
- const exitCode = hasBlockingIssues || (hasWarnings && config.severity === 'error') ? 1 : 0;
352
- if (exitCode === 0) {
353
- logSuccess('Review completed successfully');
354
- }
355
- else {
356
- if (hasBlockingIssues) {
357
- logError('Review failed with blocking issues');
358
- }
359
- else if (hasWarnings) {
360
- logError('Review failed with warnings');
361
- }
362
- }
363
- process.exit(exitCode);
364
- }
365
- catch (error) {
366
- logError(`Review failed: ${error instanceof Error ? error.message : String(error)}`);
367
- process.exit(1);
368
- }
369
- };
370
- const logFeatureAnalysisResults = (result, verbose) => {
371
- console.log('\n' + '='.repeat(60));
372
- console.log('🎯 Feature Analysis Results');
373
- console.log('='.repeat(60));
374
- console.log(`\n📋 Feature ID: ${result.featureId}`);
375
- console.log(`📊 Status: ${result.status === 'success' ? '✅ Success' : '❌ Failed'}`);
376
- if (result.summary) {
377
- console.log(`\n📝 Summary:\n${result.summary}`);
378
- }
379
- if (result.createdUserStories && result.createdUserStories.length > 0) {
380
- console.log(`\n✨ Created ${result.createdUserStories.length} user stories`);
381
- if (verbose) {
382
- result.createdUserStories.forEach((story, index) => {
383
- console.log(` ${index + 1}. ${story.title}`);
384
- });
385
- }
386
- }
387
- if (result.createdTestCases && result.createdTestCases.length > 0) {
388
- console.log(`\n🧪 Created ${result.createdTestCases.length} test cases`);
389
- if (verbose) {
390
- result.createdTestCases.forEach((testCase, index) => {
391
- console.log(` ${index + 1}. ${testCase.name} ${testCase.is_critical ? '[CRITICAL]' : ''}`);
392
- });
393
- }
394
- }
395
- console.log('\n' + '='.repeat(60));
396
- };
397
- const logCodeImplementationResults = (result, verbose) => {
398
- console.log('\n' + '='.repeat(60));
399
- console.log('💻 Code Implementation Results');
400
- console.log('='.repeat(60));
401
- console.log(`\n📋 Feature ID: ${result.featureId}`);
402
- console.log(`🌿 Branch: ${result.branchName}`);
403
- console.log(`📊 Status: ${result.status === 'success' ? '✅ Success' : '❌ Failed'}`);
404
- if (result.message) {
405
- console.log(`\n📝 Message: ${result.message}`);
406
- }
407
- if (result.implementationSummary) {
408
- console.log(`\n📄 Implementation Summary:`);
409
- console.log(result.implementationSummary);
410
- }
411
- if (result.filesModified && result.filesModified.length > 0) {
412
- console.log(`\n📁 Files Modified: ${result.filesModified.length}`);
413
- if (verbose) {
414
- result.filesModified.forEach((file) => {
415
- console.log(` - ${file}`);
416
- });
417
- }
418
- }
419
- if (result.commitHash) {
420
- console.log(`\n🔖 Commit: ${result.commitHash}`);
421
- }
422
- console.log('\n' + '='.repeat(60));
423
- };
424
- const runFunctionalTestingCommand = async (options) => {
425
- // Check requirements
426
- const hasRequirements = await checkFunctionalTestingRequirements();
427
- if (!hasRequirements) {
428
- throw new Error('Functional testing requirements not met. Install with: npm install @anthropic-ai/claude-code zod');
429
- }
430
- // Load configuration
431
- const config = loadConfig(options.config);
432
- const configErrors = validateConfig(config);
433
- if (configErrors.length > 0) {
434
- throw new Error(`Configuration errors:\n${configErrors.map((e) => ` - ${e}`).join('\n')}`);
435
- }
436
- if (options.verbose) {
437
- logInfo('Configuration loaded successfully');
438
- logInfo(`Starting functional testing for feature: ${options.test}`);
439
- }
440
- // Get MCP configuration from environment or config
441
- const mcpServerUrl = process.env.EDSGER_MCP_SERVER_URL;
442
- const mcpToken = process.env.EDSGER_MCP_TOKEN;
443
- if (!mcpServerUrl) {
444
- throw new Error('MCP server URL is required. Set EDSGER_MCP_SERVER_URL environment variable.');
445
- }
446
- if (!mcpToken) {
447
- throw new Error('MCP token is required. Set EDSGER_MCP_TOKEN environment variable.');
448
- }
449
- // Validate MCP server URL format
450
- try {
451
- new URL(mcpServerUrl);
452
- }
453
- catch {
454
- throw new Error('Invalid MCP server URL format. Use http:// or https://');
455
- }
456
- logInfo('Starting functional testing...');
457
- try {
458
- const testResult = await runFunctionalTesting({
459
- featureId: options.test,
460
- mcpServerUrl,
461
- mcpToken,
462
- verbose: options.verbose,
463
- }, config);
464
- // Display results
465
- logFunctionalTestingResults(testResult, options.verbose);
466
- if (testResult.status === 'success') {
467
- logSuccess('Functional testing completed successfully');
468
- process.exit(0);
469
- }
470
- else {
471
- logError('Functional testing failed');
472
- process.exit(1);
473
- }
474
- }
475
- catch (error) {
476
- logError(`Functional testing failed: ${error instanceof Error ? error.message : String(error)}`);
477
- process.exit(1);
478
- }
479
- };
480
- const logFunctionalTestingResults = (result, verbose) => {
481
- console.log('\n' + '='.repeat(60));
482
- console.log('🎭 Functional Testing Results');
483
- console.log('='.repeat(60));
484
- console.log(`\n📋 Feature ID: ${result.featureId}`);
485
- console.log(`📊 Status: ${result.status === 'success' ? '✅ Success' : '❌ Failed'}`);
486
- console.log(`🧪 Test Status: ${result.testStatus === 'testing_passed' ? '✅ Passed' : '❌ Failed'}`);
487
- if (result.message) {
488
- console.log(`\n📝 Message: ${result.message}`);
489
- }
490
- if (result.structuredTestResult && verbose) {
491
- console.log(`\n🔍 Test Results:`);
492
- console.log('─'.repeat(40));
493
- console.log(` Title: ${result.structuredTestResult.title}`);
494
- console.log(` Summary: ${result.structuredTestResult.summary}`);
495
- console.log(` Total Tests: ${result.structuredTestResult.total_test_cases}`);
496
- console.log(` Passed: ${result.structuredTestResult.passed_test_cases}`);
497
- console.log(` Failed: ${result.structuredTestResult.failed_test_cases}`);
498
- if (result.structuredTestResult.execution_details) {
499
- console.log(`\n Execution Details:`);
500
- const lines = result.structuredTestResult.execution_details.split('\n');
501
- const previewLines = lines.slice(0, 20);
502
- previewLines.forEach((line) => {
503
- console.log(` ${line}`);
504
- });
505
- if (lines.length > 20) {
506
- console.log(` ... (${lines.length - 20} more lines)`);
507
- }
508
- console.log('─'.repeat(40));
509
- }
510
- }
511
- else if (result.structuredTestResult &&
512
- result.structuredTestResult.execution_details) {
513
- console.log(`\n🔍 Test Results: Available (${result.structuredTestResult.execution_details.length} characters)`);
514
- }
515
- console.log('\n' + '='.repeat(60));
516
- };
517
- const logTechnicalDesignResults = (result, verbose) => {
518
- console.log('\n' + '='.repeat(60));
519
- console.log('🎨 Technical Design Results');
520
- console.log('='.repeat(60));
521
- console.log(`\n📋 Feature ID: ${result.featureId}`);
522
- console.log(`📊 Status: ${result.status === 'success' ? '✅ Success' : '❌ Failed'}`);
523
- if (result.summary) {
524
- console.log(`\n📝 Summary:\n${result.summary}`);
525
- }
526
- if (result.savedViaHttp) {
527
- console.log(`\n🔄 Saved via HTTP fallback`);
528
- }
529
- if (result.technicalDesign && verbose) {
530
- console.log(`\n🏗️ Technical Design:`);
531
- console.log('─'.repeat(40));
532
- const lines = result.technicalDesign.split('\n');
533
- const previewLines = lines.slice(0, 10);
534
- previewLines.forEach((line) => {
535
- console.log(` ${line}`);
536
- });
537
- if (lines.length > 10) {
538
- console.log(` ... (${lines.length - 10} more lines)`);
539
- }
540
- console.log('─'.repeat(40));
541
- }
542
- else if (result.technicalDesign) {
543
- console.log(`\n🏗️ Technical Design: Generated (${result.technicalDesign.length} characters)`);
544
- }
545
- console.log('\n' + '='.repeat(60));
546
- };
547
92
  // Only parse when this file is run directly (not imported as module)
548
93
  // Check if this is the main module being executed
549
94
  const isMainModule = import.meta.url === `file://${process.argv[1]}` ||
550
- process.argv[1]?.endsWith('/edsger') ||
551
- process.argv[1]?.endsWith('\\edsger') ||
552
- process.argv[1]?.endsWith('cli.js');
95
+ ((_a = process.argv[1]) === null || _a === void 0 ? void 0 : _a.endsWith('/edsger')) ||
96
+ ((_b = process.argv[1]) === null || _b === void 0 ? void 0 : _b.endsWith('\\edsger')) ||
97
+ ((_c = process.argv[1]) === null || _c === void 0 ? void 0 : _c.endsWith('cli.js'));
553
98
  if (isMainModule) {
554
99
  program.parse();
555
100
  }
package/dist/config.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { EdsgerConfig } from './types.js';
1
+ import { EdsgerConfig } from './types/index.js';
2
2
  export declare const loadConfig: (configPath?: string) => EdsgerConfig;
3
3
  export declare const validateConfig: (config: EdsgerConfig) => string[];
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { runEdsger } from './cli.js';
1
+ export { runEdsger } from './cli/index.js';
2
2
  export { loadConfig, validateConfig } from './config.js';
3
- export { reviewWithClaudeSDK, checkClaudeCodeSDK } from './code-review/reviewer.js';
4
- export type { EdsgerConfig, ReviewResult, CliOptions } from './types.js';
3
+ export { reviewWithClaudeSDK, checkClaudeCodeSDK, } from './phases/code-review/reviewer.js';
4
+ export type { EdsgerConfig, ReviewResult, CliOptions } from './types/index.js';
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { runEdsger } from './cli.js';
1
+ export { runEdsger } from './cli/index.js';
2
2
  export { loadConfig, validateConfig } from './config.js';
3
- export { reviewWithClaudeSDK, checkClaudeCodeSDK } from './code-review/reviewer.js';
3
+ export { reviewWithClaudeSDK, checkClaudeCodeSDK, } from './phases/code-review/reviewer.js';
@@ -1,4 +1,4 @@
1
- import { EdsgerConfig } from '../types.js';
1
+ import { EdsgerConfig } from '../../types/index.js';
2
2
  export interface BugFixingOptions {
3
3
  featureId: string;
4
4
  mcpServerUrl: string;
@@ -1,5 +1,5 @@
1
1
  import { query } from '@anthropic-ai/claude-code';
2
- import { logInfo, logError } from '../logger.js';
2
+ import { logInfo, logError } from '../../utils/logger.js';
3
3
  import { fetchBugFixingContext, formatContextForPrompt, } from './context-fetcher.js';
4
4
  function userMessage(content) {
5
5
  return {
@@ -1,26 +1,8 @@
1
+ import type { FeatureInfo, UserStory, TestCase } from '../../types/features.js';
1
2
  export interface BugFixingContext {
2
- feature: {
3
- id: string;
4
- name: string;
5
- description?: string;
6
- technical_design?: string;
7
- status: string;
8
- product_id: string;
9
- };
10
- user_stories: Array<{
11
- id: string;
12
- title: string;
13
- description: string;
14
- status: string;
15
- [key: string]: any;
16
- }>;
17
- test_cases: Array<{
18
- id: string;
19
- name: string;
20
- description: string;
21
- is_critical: boolean;
22
- [key: string]: any;
23
- }>;
3
+ feature: FeatureInfo;
4
+ user_stories: UserStory[];
5
+ test_cases: TestCase[];
24
6
  latest_test_report?: {
25
7
  id: string;
26
8
  title: string;
@@ -1,34 +1,6 @@
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
- }
1
+ import { logInfo, logError } from '../../utils/logger.js';
2
+ import { getFeature, getUserStories, getTestCases, } from '../../api/features/index.js';
3
+ import { callMcpEndpoint } from '../../api/mcp-client.js';
32
4
  /**
33
5
  * Fetch all bug fixing context information via MCP endpoints
34
6
  */
@@ -37,33 +9,18 @@ export async function fetchBugFixingContext(mcpServerUrl, mcpToken, featureId, v
37
9
  if (verbose) {
38
10
  logInfo(`Fetching complete bug fixing context for feature: ${featureId}`);
39
11
  }
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 user stories to understand requirements
50
- if (verbose) {
51
- logInfo('2/4 Fetching user stories...');
52
- }
53
- const userStoriesResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/list', { feature_id: featureId }));
54
- const user_stories = (userStoriesResult.user_stories || []);
55
- // Step 3: Get test cases to understand what needs to pass
56
- if (verbose) {
57
- logInfo('3/4 Fetching test cases...');
58
- }
59
- const testCasesResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/list', { feature_id: featureId }));
60
- const test_cases = (testCasesResult.test_cases || []);
61
- // Step 4: Get latest test report to understand what has been tested
62
- if (verbose) {
63
- logInfo('4/4 Fetching latest test report...');
64
- }
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
+ // Get latest test report to understand what has been tested
65
19
  let latest_test_report = null;
66
20
  try {
21
+ if (verbose) {
22
+ logInfo('Fetching latest test report...');
23
+ }
67
24
  const testReportResult = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_reports/latest', { feature_id: featureId }));
68
25
  if (testReportResult.test_report) {
69
26
  latest_test_report = testReportResult.test_report;
@@ -74,9 +31,8 @@ export async function fetchBugFixingContext(mcpServerUrl, mcpToken, featureId, v
74
31
  logInfo(`No test report found or failed to fetch: ${error}`);
75
32
  }
76
33
  }
77
- // Log summary if verbose
78
34
  if (verbose) {
79
- logInfo(`✅ Context fetched successfully:`);
35
+ logInfo(`✅ Bug fixing context fetched successfully:`);
80
36
  logInfo(` Feature: ${feature.name}`);
81
37
  logInfo(` User Stories: ${user_stories.length}`);
82
38
  logInfo(` Test Cases: ${test_cases.length} (${test_cases.filter((tc) => tc.is_critical).length} critical)`);