edsger 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +17 -0
  2. package/dist/api/features/batch-operations.d.ts +16 -0
  3. package/dist/api/features/batch-operations.js +100 -0
  4. package/dist/api/features/index.d.ts +1 -0
  5. package/dist/api/features/index.js +1 -0
  6. package/dist/api/features/test-cases.d.ts +8 -0
  7. package/dist/api/features/test-cases.js +45 -0
  8. package/dist/api/features/user-stories.d.ts +8 -0
  9. package/dist/api/features/user-stories.js +45 -0
  10. package/dist/cli/commands/refactor-command.d.ts +2 -0
  11. package/dist/cli/commands/refactor-command.js +107 -0
  12. package/dist/cli/index.js +7 -0
  13. package/dist/cli.d.ts +2 -2
  14. package/dist/cli.js +4 -99
  15. package/dist/phases/code-implementation/analyzer-helpers.d.ts +28 -0
  16. package/dist/phases/code-implementation/analyzer-helpers.js +177 -0
  17. package/dist/phases/code-implementation/analyzer.d.ts +2 -0
  18. package/dist/phases/code-implementation/analyzer.js +308 -179
  19. package/dist/phases/code-implementation-verification/index.d.ts +1 -0
  20. package/dist/phases/code-implementation-verification/index.js +1 -0
  21. package/dist/phases/code-implementation-verification/verifier.d.ts +31 -0
  22. package/dist/phases/code-implementation-verification/verifier.js +196 -0
  23. package/dist/phases/feature-analysis/analyzer-helpers.d.ts +62 -0
  24. package/dist/phases/feature-analysis/analyzer-helpers.js +450 -0
  25. package/dist/phases/feature-analysis/analyzer.d.ts +1 -0
  26. package/dist/phases/feature-analysis/analyzer.js +132 -213
  27. package/dist/phases/feature-analysis-verification/index.d.ts +1 -0
  28. package/dist/phases/feature-analysis-verification/index.js +1 -0
  29. package/dist/phases/feature-analysis-verification/verifier.d.ts +37 -0
  30. package/dist/phases/feature-analysis-verification/verifier.js +147 -0
  31. package/dist/phases/pull-request/creator.js +10 -9
  32. package/dist/phases/technical-design/analyzer-helpers.d.ts +37 -0
  33. package/dist/phases/technical-design/analyzer-helpers.js +144 -0
  34. package/dist/phases/technical-design/analyzer.d.ts +3 -0
  35. package/dist/phases/technical-design/analyzer.js +282 -312
  36. package/dist/phases/technical-design-verification/index.d.ts +1 -0
  37. package/dist/phases/technical-design-verification/index.js +1 -0
  38. package/dist/phases/technical-design-verification/verifier.d.ts +36 -0
  39. package/dist/phases/technical-design-verification/verifier.js +147 -0
  40. package/dist/prompts/checklist-verification.d.ts +11 -0
  41. package/dist/prompts/checklist-verification.js +153 -0
  42. package/dist/prompts/code-implementation-improvement.d.ts +5 -0
  43. package/dist/prompts/code-implementation-improvement.js +108 -0
  44. package/dist/prompts/code-implementation-verification.d.ts +3 -0
  45. package/dist/prompts/code-implementation-verification.js +176 -0
  46. package/dist/prompts/feature-analysis-improvement.d.ts +8 -0
  47. package/dist/prompts/feature-analysis-improvement.js +109 -0
  48. package/dist/prompts/feature-analysis.js +1 -1
  49. package/dist/prompts/formatters.d.ts +17 -4
  50. package/dist/prompts/formatters.js +41 -12
  51. package/dist/prompts/technical-design-improvement.d.ts +5 -0
  52. package/dist/prompts/technical-design-improvement.js +93 -0
  53. package/dist/prompts/technical-design-verification.d.ts +11 -0
  54. package/dist/prompts/technical-design-verification.js +134 -0
  55. package/dist/prompts/technical-design.js +1 -1
  56. package/dist/services/audit-logs.d.ts +60 -0
  57. package/dist/services/audit-logs.js +115 -0
  58. package/dist/services/checklist.d.ts +1 -0
  59. package/dist/types/index.d.ts +19 -0
  60. package/dist/utils/image-downloader.d.ts +32 -0
  61. package/dist/utils/image-downloader.js +144 -0
  62. package/dist/workflow-runner/executors/phase-executor.js +56 -12
  63. package/package.json +1 -1
  64. package/dist/api/features.d.ts +0 -100
  65. package/dist/api/features.js +0 -219
  66. package/dist/logger.d.ts +0 -19
  67. package/dist/logger.js +0 -52
  68. package/dist/types.d.ts +0 -99
  69. package/dist/types.js +0 -1
  70. package/dist/workflow-runner/config/stage-configs.d.ts +0 -5
  71. package/dist/workflow-runner/config/stage-configs.js +0 -34
  72. package/dist/workflow-runner/core/feature-filter.test.d.ts +0 -4
  73. package/dist/workflow-runner/core/feature-filter.test.js +0 -127
  74. package/dist/workflow-runner/executors/stage-executor.d.ts +0 -8
  75. package/dist/workflow-runner/executors/stage-executor.js +0 -49
  76. package/dist/workflow-runner/feature-fetcher.d.ts +0 -41
  77. package/dist/workflow-runner/feature-fetcher.js +0 -121
  78. package/dist/workflow-runner/feature-service.d.ts +0 -17
  79. package/dist/workflow-runner/feature-service.js +0 -60
  80. package/dist/workflow-runner/pipeline.d.ts +0 -18
  81. package/dist/workflow-runner/pipeline.js +0 -197
  82. package/dist/workflow-runner/processor.d.ts +0 -40
  83. package/dist/workflow-runner/processor.js +0 -191
  84. package/dist/workflow-runner/status-updater.d.ts +0 -27
  85. package/dist/workflow-runner/status-updater.js +0 -80
  86. package/dist/workflow-runner/types.d.ts +0 -48
  87. package/dist/workflow-runner/types.js +0 -4
package/README.md CHANGED
@@ -12,6 +12,13 @@ AI-powered software development CLI tool with comprehensive feature management,
12
12
  - **Hook-Friendly**: Designed for pre-commit hooks and CI/CD automation
13
13
  - **Detailed Output**: Clear feedback with blocking/warning/passing results
14
14
 
15
+ ### 🔧 Code Refactoring
16
+
17
+ - **Intelligent Analysis**: AI-powered code quality and refactoring analysis
18
+ - **Pattern Detection**: Identifies code smells, duplication, and technical debt
19
+ - **Improvement Suggestions**: Provides prioritized recommendations for code improvement
20
+ - **Interactive Mode**: Ask for confirmation before applying refactoring changes
21
+
15
22
  ### 🎯 Feature Analysis
16
23
 
17
24
  - **MCP Integration**: Analyze features using Model Context Protocol
@@ -68,6 +75,16 @@ edsger --review --files "**/*.ts" "**/*.js"
68
75
  edsger --review --verbose
69
76
  ```
70
77
 
78
+ ### Code Refactoring
79
+
80
+ ```bash
81
+ # Analyze and refactor code in current directory
82
+ edsger --refactor
83
+
84
+ # Verbose refactoring output
85
+ edsger --refactor --verbose
86
+ ```
87
+
71
88
  ### Feature Analysis
72
89
 
73
90
  ```bash
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Batch update user story statuses
3
+ */
4
+ export declare function batchUpdateUserStoryStatus(mcpServerUrl: string, mcpToken: string, userStoryIds: string[], status: 'draft' | 'ready' | 'in_progress' | 'done' | 'cancelled', verbose?: boolean): Promise<boolean>;
5
+ /**
6
+ * Batch update test case statuses
7
+ */
8
+ export declare function batchUpdateTestCaseStatus(mcpServerUrl: string, mcpToken: string, testCaseIds: string[], status: 'draft' | 'ready' | 'in_progress' | 'done' | 'cancelled', verbose?: boolean): Promise<boolean>;
9
+ /**
10
+ * Batch delete user stories
11
+ */
12
+ export declare function batchDeleteUserStories(mcpServerUrl: string, mcpToken: string, userStoryIds: string[], verbose?: boolean): Promise<boolean>;
13
+ /**
14
+ * Batch delete test cases
15
+ */
16
+ export declare function batchDeleteTestCases(mcpServerUrl: string, mcpToken: string, testCaseIds: string[], verbose?: boolean): Promise<boolean>;
@@ -0,0 +1,100 @@
1
+ import { logInfo, logError } from '../../utils/logger.js';
2
+ import { callMcpEndpoint } from '../mcp-client.js';
3
+ /**
4
+ * Batch update user story statuses
5
+ */
6
+ export async function batchUpdateUserStoryStatus(mcpServerUrl, mcpToken, userStoryIds, status, verbose) {
7
+ try {
8
+ if (verbose) {
9
+ logInfo(`Batch updating ${userStoryIds.length} user stories to status: ${status}`);
10
+ }
11
+ for (const id of userStoryIds) {
12
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/update_status', {
13
+ user_story_id: id,
14
+ status,
15
+ });
16
+ }
17
+ if (verbose) {
18
+ logInfo('✅ Batch user story status update completed');
19
+ }
20
+ return true;
21
+ }
22
+ catch (error) {
23
+ const errorMessage = error instanceof Error ? error.message : String(error);
24
+ logError(`Failed to batch update user story statuses: ${errorMessage}`);
25
+ return false;
26
+ }
27
+ }
28
+ /**
29
+ * Batch update test case statuses
30
+ */
31
+ export async function batchUpdateTestCaseStatus(mcpServerUrl, mcpToken, testCaseIds, status, verbose) {
32
+ try {
33
+ if (verbose) {
34
+ logInfo(`Batch updating ${testCaseIds.length} test cases to status: ${status}`);
35
+ }
36
+ for (const id of testCaseIds) {
37
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/update_status', {
38
+ test_case_id: id,
39
+ status,
40
+ });
41
+ }
42
+ if (verbose) {
43
+ logInfo('✅ Batch test case status update completed');
44
+ }
45
+ return true;
46
+ }
47
+ catch (error) {
48
+ const errorMessage = error instanceof Error ? error.message : String(error);
49
+ logError(`Failed to batch update test case statuses: ${errorMessage}`);
50
+ return false;
51
+ }
52
+ }
53
+ /**
54
+ * Batch delete user stories
55
+ */
56
+ export async function batchDeleteUserStories(mcpServerUrl, mcpToken, userStoryIds, verbose) {
57
+ try {
58
+ if (verbose) {
59
+ logInfo(`Batch deleting ${userStoryIds.length} user stories`);
60
+ }
61
+ for (const id of userStoryIds) {
62
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/delete', {
63
+ user_story_id: id,
64
+ });
65
+ }
66
+ if (verbose) {
67
+ logInfo('✅ Batch user story deletion completed');
68
+ }
69
+ return true;
70
+ }
71
+ catch (error) {
72
+ const errorMessage = error instanceof Error ? error.message : String(error);
73
+ logError(`Failed to batch delete user stories: ${errorMessage}`);
74
+ return false;
75
+ }
76
+ }
77
+ /**
78
+ * Batch delete test cases
79
+ */
80
+ export async function batchDeleteTestCases(mcpServerUrl, mcpToken, testCaseIds, verbose) {
81
+ try {
82
+ if (verbose) {
83
+ logInfo(`Batch deleting ${testCaseIds.length} test cases`);
84
+ }
85
+ for (const id of testCaseIds) {
86
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/delete', {
87
+ test_case_id: id,
88
+ });
89
+ }
90
+ if (verbose) {
91
+ logInfo('✅ Batch test case deletion completed');
92
+ }
93
+ return true;
94
+ }
95
+ catch (error) {
96
+ const errorMessage = error instanceof Error ? error.message : String(error);
97
+ logError(`Failed to batch delete test cases: ${errorMessage}`);
98
+ return false;
99
+ }
100
+ }
@@ -4,4 +4,5 @@ export * from './user-stories.js';
4
4
  export * from './test-cases.js';
5
5
  export * from './feature-utils.js';
6
6
  export * from './status-updater.js';
7
+ export * from './batch-operations.js';
7
8
  export * from '../../types/features.js';
@@ -5,5 +5,6 @@ export * from './user-stories.js';
5
5
  export * from './test-cases.js';
6
6
  export * from './feature-utils.js';
7
7
  export * from './status-updater.js';
8
+ export * from './batch-operations.js';
8
9
  // Re-export types
9
10
  export * from '../../types/features.js';
@@ -19,3 +19,11 @@ export declare function createTestCases(mcpServerUrl: string, mcpToken: string,
19
19
  description: string;
20
20
  is_critical?: boolean;
21
21
  }>, verbose?: boolean): Promise<boolean>;
22
+ /**
23
+ * Delete a test case
24
+ */
25
+ export declare function deleteTestCase(mcpServerUrl: string, mcpToken: string, testCaseId: string, verbose?: boolean): Promise<boolean>;
26
+ /**
27
+ * Update test case status
28
+ */
29
+ export declare function updateTestCaseStatus(mcpServerUrl: string, mcpToken: string, testCaseId: string, status: 'draft' | 'ready' | 'in_progress' | 'done' | 'cancelled', verbose?: boolean): Promise<boolean>;
@@ -61,3 +61,48 @@ export async function createTestCases(mcpServerUrl, mcpToken, featureId, testCas
61
61
  return false;
62
62
  }
63
63
  }
64
+ /**
65
+ * Delete a test case
66
+ */
67
+ export async function deleteTestCase(mcpServerUrl, mcpToken, testCaseId, verbose) {
68
+ try {
69
+ if (verbose) {
70
+ logInfo(`Deleting test case: ${testCaseId}`);
71
+ }
72
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/delete', {
73
+ test_case_id: testCaseId,
74
+ });
75
+ if (verbose) {
76
+ logInfo('✅ Test case deleted successfully');
77
+ }
78
+ return true;
79
+ }
80
+ catch (error) {
81
+ const errorMessage = error instanceof Error ? error.message : String(error);
82
+ logError(`Failed to delete test case: ${errorMessage}`);
83
+ return false;
84
+ }
85
+ }
86
+ /**
87
+ * Update test case status
88
+ */
89
+ export async function updateTestCaseStatus(mcpServerUrl, mcpToken, testCaseId, status, verbose) {
90
+ try {
91
+ if (verbose) {
92
+ logInfo(`Updating test case ${testCaseId} status to: ${status}`);
93
+ }
94
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'test_cases/update_status', {
95
+ test_case_id: testCaseId,
96
+ status,
97
+ });
98
+ if (verbose) {
99
+ logInfo('✅ Test case status updated successfully');
100
+ }
101
+ return true;
102
+ }
103
+ catch (error) {
104
+ const errorMessage = error instanceof Error ? error.message : String(error);
105
+ logError(`Failed to update test case status: ${errorMessage}`);
106
+ return false;
107
+ }
108
+ }
@@ -19,3 +19,11 @@ export declare function createUserStories(mcpServerUrl: string, mcpToken: string
19
19
  description: string;
20
20
  status?: string;
21
21
  }>, verbose?: boolean): Promise<boolean>;
22
+ /**
23
+ * Delete a user story
24
+ */
25
+ export declare function deleteUserStory(mcpServerUrl: string, mcpToken: string, userStoryId: string, verbose?: boolean): Promise<boolean>;
26
+ /**
27
+ * Update user story status
28
+ */
29
+ export declare function updateUserStoryStatus(mcpServerUrl: string, mcpToken: string, userStoryId: string, status: 'draft' | 'ready' | 'in_progress' | 'done' | 'cancelled', verbose?: boolean): Promise<boolean>;
@@ -61,3 +61,48 @@ export async function createUserStories(mcpServerUrl, mcpToken, featureId, userS
61
61
  return false;
62
62
  }
63
63
  }
64
+ /**
65
+ * Delete a user story
66
+ */
67
+ export async function deleteUserStory(mcpServerUrl, mcpToken, userStoryId, verbose) {
68
+ try {
69
+ if (verbose) {
70
+ logInfo(`Deleting user story: ${userStoryId}`);
71
+ }
72
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/delete', {
73
+ user_story_id: userStoryId,
74
+ });
75
+ if (verbose) {
76
+ logInfo('✅ User story deleted successfully');
77
+ }
78
+ return true;
79
+ }
80
+ catch (error) {
81
+ const errorMessage = error instanceof Error ? error.message : String(error);
82
+ logError(`Failed to delete user story: ${errorMessage}`);
83
+ return false;
84
+ }
85
+ }
86
+ /**
87
+ * Update user story status
88
+ */
89
+ export async function updateUserStoryStatus(mcpServerUrl, mcpToken, userStoryId, status, verbose) {
90
+ try {
91
+ if (verbose) {
92
+ logInfo(`Updating user story ${userStoryId} status to: ${status}`);
93
+ }
94
+ await callMcpEndpoint(mcpServerUrl, mcpToken, 'user_stories/update_status', {
95
+ user_story_id: userStoryId,
96
+ status,
97
+ });
98
+ if (verbose) {
99
+ logInfo('✅ User story status updated successfully');
100
+ }
101
+ return true;
102
+ }
103
+ catch (error) {
104
+ const errorMessage = error instanceof Error ? error.message : String(error);
105
+ logError(`Failed to update user story status: ${errorMessage}`);
106
+ return false;
107
+ }
108
+ }
@@ -0,0 +1,2 @@
1
+ import { CliOptions } from '../../types/index.js';
2
+ export declare const runRefactor: (options: CliOptions) => Promise<void>;
@@ -0,0 +1,107 @@
1
+ import { query } from '@anthropic-ai/claude-code';
2
+ import { logInfo, logError, logSuccess } from '../../utils/logger.js';
3
+ import { validateConfiguration } from '../utils/validation.js';
4
+ export const runRefactor = async (options) => {
5
+ // Load and validate configuration
6
+ const config = validateConfiguration(options);
7
+ if (options.verbose) {
8
+ logInfo('Starting code refactoring for current directory...');
9
+ }
10
+ logInfo('Analyzing code for refactoring opportunities...');
11
+ try {
12
+ const refactorPrompt = createRefactorPrompt(config);
13
+ const systemPrompt = createSystemPrompt();
14
+ let hasCompleted = false;
15
+ for await (const message of query({
16
+ prompt: refactorPrompt,
17
+ options: {
18
+ appendSystemPrompt: systemPrompt,
19
+ model: config.claude.model || 'sonnet',
20
+ },
21
+ })) {
22
+ // Stream the refactoring process
23
+ if (message.type === 'assistant' && message.message?.content) {
24
+ for (const content of message.message.content) {
25
+ if (content.type === 'text') {
26
+ console.log(`\n🤖 ${content.text}`);
27
+ }
28
+ else if (content.type === 'tool_use') {
29
+ console.log(`\n🔧 ${content.name}: ${content.input.description || content.input.command || 'Running...'}`);
30
+ }
31
+ }
32
+ }
33
+ if (message.type === 'result') {
34
+ hasCompleted = true;
35
+ if (message.subtype === 'success') {
36
+ logSuccess('Refactoring analysis completed successfully');
37
+ process.exit(0);
38
+ }
39
+ else {
40
+ logError(`Refactoring incomplete: ${message.subtype}`);
41
+ if (message.subtype === 'error_max_turns') {
42
+ console.log('💡 Try simplifying the codebase or increase timeout');
43
+ }
44
+ process.exit(1);
45
+ }
46
+ }
47
+ }
48
+ if (!hasCompleted) {
49
+ logError('Refactoring process did not complete');
50
+ process.exit(1);
51
+ }
52
+ }
53
+ catch (error) {
54
+ logError(`Refactoring failed: ${error instanceof Error ? error.message : String(error)}`);
55
+ process.exit(1);
56
+ }
57
+ };
58
+ const createSystemPrompt = () => {
59
+ return `You are an expert code refactoring assistant using Claude Code. Your task is to analyze code in the current directory and suggest or perform refactoring improvements.
60
+
61
+ IMPORTANT INSTRUCTIONS:
62
+ 1. Use the Bash tool to explore the project structure (ls, find, etc.)
63
+ 2. Use the Read tool to examine file contents
64
+ 3. Use the Grep tool to search for patterns, code smells, or duplications
65
+ 4. Use the Edit tool to apply refactoring changes when appropriate
66
+ 5. Analyze code quality, identify technical debt, and suggest improvements
67
+
68
+ REFACTORING FOCUS AREAS:
69
+ - Code duplication and DRY violations
70
+ - Complex functions that need simplification
71
+ - Poor naming conventions
72
+ - Missing type annotations (TypeScript)
73
+ - Inefficient algorithms or data structures
74
+ - Code organization and structure
75
+ - Missing or inadequate error handling
76
+ - Opportunities for better abstraction
77
+ - Performance improvements
78
+
79
+ WORKFLOW:
80
+ 1. First, explore the project structure to understand the codebase
81
+ 2. Identify files that would benefit from refactoring
82
+ 3. Analyze specific issues and patterns
83
+ 4. Suggest improvements with clear explanations
84
+ 5. Ask for user confirmation before making significant changes
85
+ 6. Apply changes using the Edit tool if approved
86
+
87
+ Be thorough but focused. Prioritize high-impact refactorings that improve code maintainability and quality.`;
88
+ };
89
+ const createRefactorPrompt = (config) => {
90
+ return `Please analyze the code in the current directory for refactoring opportunities.
91
+
92
+ Steps to follow:
93
+ 1. Start by running "ls -la" to see the project structure
94
+ 2. Identify key source files (focus on patterns: ${config.patterns.join(', ')})
95
+ 3. Read and analyze relevant source files
96
+ 4. Look for:
97
+ - Code duplication
98
+ - Complex or long functions
99
+ - Poor naming
100
+ - Missing types or documentation
101
+ - Error handling issues
102
+ - Performance bottlenecks
103
+ 5. Provide a summary of findings with prioritized recommendations
104
+ 6. Ask if I'd like you to proceed with any specific refactoring
105
+
106
+ Start by exploring the current directory structure.`;
107
+ };
package/dist/cli/index.js CHANGED
@@ -11,6 +11,7 @@ import { runTechnicalDesign } from './commands/technical-design-command.js';
11
11
  import { runCodeImplementation } from './commands/code-implementation-command.js';
12
12
  import { runFunctionalTestingCommand } from './commands/functional-testing-command.js';
13
13
  import { runCodeReview } from './commands/code-review-command.js';
14
+ import { runRefactor } from './commands/refactor-command.js';
14
15
  // Get package.json version dynamically
15
16
  const __filename = fileURLToPath(import.meta.url);
16
17
  const __dirname = dirname(__filename);
@@ -28,6 +29,7 @@ program
28
29
  .option('-r, --review', 'Review code changes')
29
30
  .option('-s, --staged', 'Review only staged changes')
30
31
  .option('-f, --files <patterns...>', 'Review specific file patterns')
32
+ .option('--refactor', 'Refactor code in current directory')
31
33
  .option('--feature-analysis <featureId>', 'Analyze feature and generate user stories/test cases')
32
34
  .option('--technical-design <featureId>', 'Generate technical design for a feature')
33
35
  .option('--implement <featureId>', 'Implement code for a feature based on its specifications')
@@ -70,6 +72,11 @@ export const runEdsger = async (options) => {
70
72
  await runFunctionalTestingCommand(options);
71
73
  return;
72
74
  }
75
+ // Handle refactor mode
76
+ if (options.refactor) {
77
+ await runRefactor(options);
78
+ return;
79
+ }
73
80
  // Handle code review mode (explicit --review flag or as fallback)
74
81
  if (options.review || options.staged || options.files) {
75
82
  await runCodeReview(options);
package/dist/cli.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { CliOptions } from './types/index.js';
3
- export declare const runEdsger: (options: CliOptions) => Promise<void>;
2
+ export * from './cli/index.js';
3
+ import './cli/index.js';
package/dist/cli.js CHANGED
@@ -1,100 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var _a, _b, _c;
3
- import { Command } from 'commander';
4
- import { readFileSync } from 'fs';
5
- import { join, dirname } from 'path';
6
- import { fileURLToPath } from 'url';
7
- import { config as dotenvConfig } from 'dotenv';
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
- // Get package.json version dynamically
16
- const __filename = fileURLToPath(import.meta.url);
17
- const __dirname = dirname(__filename);
18
- const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
19
- const version = packageJson.version;
20
- // Load environment variables from .env file
21
- // Load from current working directory (where the command is run)
22
- dotenvConfig({ path: join(process.cwd(), '.env') });
23
- const program = new Command();
24
- program
25
- .name('edsger')
26
- .description('AI-powered code review CLI tool using Claude Code SDK')
27
- .version(version);
28
- program
29
- .option('-r, --review', 'Review code changes')
30
- .option('-s, --staged', 'Review only staged changes')
31
- .option('-f, --files <patterns...>', 'Review specific file patterns')
32
- .option('--feature-analysis <featureId>', 'Analyze feature and generate user stories/test cases')
33
- .option('--technical-design <featureId>', 'Generate technical design for a feature')
34
- .option('--implement <featureId>', 'Implement code for a feature based on its specifications')
35
- .option('--test <featureId>', 'Run functional tests for a feature using Playwright')
36
- .option('--workflow', 'Run continuous workflow processor to handle ready_for_dev features')
37
- .option('-c, --config <path>', 'Path to config file')
38
- .option('-v, --verbose', 'Verbose output');
39
- program.action(async (options) => {
40
- try {
41
- await runEdsger(options);
42
- }
43
- catch (error) {
44
- logError(error instanceof Error ? error.message : String(error));
45
- process.exit(1);
46
- }
47
- });
48
- export const runEdsger = async (options) => {
49
- // Handle workflow mode
50
- if (options.workflow) {
51
- await runWorkflow(options);
52
- return;
53
- }
54
- // Handle feature analysis mode
55
- if (options.featureAnalysis) {
56
- await runFeatureAnalysis(options);
57
- return;
58
- }
59
- // Handle technical design mode
60
- if (options.technicalDesign) {
61
- await runTechnicalDesign(options);
62
- return;
63
- }
64
- // Handle code implementation mode
65
- if (options.implement) {
66
- await runCodeImplementation(options);
67
- return;
68
- }
69
- // Handle functional testing mode
70
- if (options.test) {
71
- await runFunctionalTestingCommand(options);
72
- return;
73
- }
74
- // Handle code review mode (explicit --review flag or as fallback)
75
- if (options.review || options.staged || options.files) {
76
- await runCodeReview(options);
77
- return;
78
- }
79
- // Default to workflow mode if environment is configured, otherwise code review
80
- const productId = process.env.EDSGER_PRODUCT_ID;
81
- const mcpToken = process.env.EDSGER_MCP_TOKEN;
82
- if (productId && mcpToken) {
83
- // Environment is configured for workflow, use that as default
84
- options.workflow = true;
85
- await runWorkflow(options);
86
- }
87
- else {
88
- // Default to code review mode
89
- await runCodeReview(options);
90
- }
91
- };
92
- // Only parse when this file is run directly (not imported as module)
93
- // Check if this is the main module being executed
94
- const isMainModule = import.meta.url === `file://${process.argv[1]}` ||
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'));
98
- if (isMainModule) {
99
- program.parse();
100
- }
2
+ // Re-export the CLI module
3
+ export * from './cli/index.js';
4
+ // Import and trigger the CLI parsing if this file is run directly
5
+ import './cli/index.js';
@@ -0,0 +1,28 @@
1
+ import { EdsgerConfig } from '../../types/index.js';
2
+ import { ChecklistPhaseContext } from '../../services/checklist.js';
3
+ import { ChecklistVerificationResult } from '../code-implementation-verification/index.js';
4
+ import { CodeImplementationResult } from './analyzer.js';
5
+ export interface VerificationCycleResult {
6
+ passed: boolean;
7
+ verificationResult: ChecklistVerificationResult | null;
8
+ nextPrompt: string | null;
9
+ }
10
+ /**
11
+ * Perform a complete verification cycle:
12
+ * 1. Verify code implementation against checklist
13
+ * 2. Log results to audit logs
14
+ * 3. Create improvement prompt if verification failed
15
+ */
16
+ export declare function performVerificationCycle(branchName: string, baseBranch: string, checklistContext: ChecklistPhaseContext | null, featureId: string, featureName: string, featureDescription: string | undefined, config: EdsgerConfig, currentIteration: number, maxIterations: number, mcpServerUrl: string, mcpToken: string, verbose?: boolean): Promise<VerificationCycleResult>;
17
+ /**
18
+ * Build successful implementation result
19
+ */
20
+ export declare function buildImplementationResult(featureId: string, branchName: string, implementationSummary: string, filesModified: string[], commitHash: string, iterations: number, checklistResults?: any[], checklistItemResults?: any[]): CodeImplementationResult;
21
+ /**
22
+ * Build verification failure result
23
+ */
24
+ export declare function buildVerificationFailureResult(featureId: string, branchName: string, implementationSummary: string, filesModified: string[], commitHash: string, verificationResult: ChecklistVerificationResult, iterations: number): CodeImplementationResult;
25
+ /**
26
+ * Build error result for no implementation
27
+ */
28
+ export declare function buildNoResultsError(featureId: string, branchName: string): CodeImplementationResult;