ai-sdlc 0.2.0-alpha.6 → 0.2.0-alpha.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -1057
- package/dist/agents/implementation.d.ts +36 -1
- package/dist/agents/implementation.d.ts.map +1 -1
- package/dist/agents/implementation.js +259 -30
- package/dist/agents/implementation.js.map +1 -1
- package/dist/agents/index.d.ts +2 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/orchestrator.d.ts +61 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +443 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/planning.d.ts +1 -1
- package/dist/agents/planning.d.ts.map +1 -1
- package/dist/agents/planning.js +55 -4
- package/dist/agents/planning.js.map +1 -1
- package/dist/agents/refinement.d.ts.map +1 -1
- package/dist/agents/refinement.js +22 -3
- package/dist/agents/refinement.js.map +1 -1
- package/dist/agents/research.d.ts +85 -1
- package/dist/agents/research.d.ts.map +1 -1
- package/dist/agents/research.js +506 -16
- package/dist/agents/research.js.map +1 -1
- package/dist/agents/review.d.ts +116 -2
- package/dist/agents/review.d.ts.map +1 -1
- package/dist/agents/review.js +847 -93
- package/dist/agents/review.js.map +1 -1
- package/dist/agents/rework.d.ts.map +1 -1
- package/dist/agents/rework.js +25 -4
- package/dist/agents/rework.js.map +1 -1
- package/dist/agents/single-task.d.ts +41 -0
- package/dist/agents/single-task.d.ts.map +1 -0
- package/dist/agents/single-task.js +357 -0
- package/dist/agents/single-task.js.map +1 -0
- package/dist/agents/state-assessor.d.ts +3 -3
- package/dist/agents/state-assessor.d.ts.map +1 -1
- package/dist/agents/state-assessor.js +6 -6
- package/dist/agents/state-assessor.js.map +1 -1
- package/dist/agents/test-pattern-detector.d.ts +49 -0
- package/dist/agents/test-pattern-detector.d.ts.map +1 -0
- package/dist/agents/test-pattern-detector.js +273 -0
- package/dist/agents/test-pattern-detector.js.map +1 -0
- package/dist/agents/verification.d.ts +11 -0
- package/dist/agents/verification.d.ts.map +1 -1
- package/dist/agents/verification.js +99 -12
- package/dist/agents/verification.js.map +1 -1
- package/dist/cli/batch-processor.d.ts +64 -0
- package/dist/cli/batch-processor.d.ts.map +1 -0
- package/dist/cli/batch-processor.js +85 -0
- package/dist/cli/batch-processor.js.map +1 -0
- package/dist/cli/batch-validator.d.ts +80 -0
- package/dist/cli/batch-validator.d.ts.map +1 -0
- package/dist/cli/batch-validator.js +121 -0
- package/dist/cli/batch-validator.js.map +1 -0
- package/dist/cli/commands/migrate.js +1 -1
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands.d.ts +67 -3
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +1765 -198
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +25 -3
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/runner.d.ts.map +1 -1
- package/dist/cli/runner.js +35 -12
- package/dist/cli/runner.js.map +1 -1
- package/dist/core/auth.d.ts +43 -0
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +105 -1
- package/dist/core/auth.js.map +1 -1
- package/dist/core/client.d.ts +25 -1
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +247 -7
- package/dist/core/client.js.map +1 -1
- package/dist/core/config.d.ts +32 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +146 -3
- package/dist/core/config.js.map +1 -1
- package/dist/core/conflict-detector.d.ts +108 -0
- package/dist/core/conflict-detector.d.ts.map +1 -0
- package/dist/core/conflict-detector.js +413 -0
- package/dist/core/conflict-detector.js.map +1 -0
- package/dist/core/git-utils.d.ts +28 -0
- package/dist/core/git-utils.d.ts.map +1 -0
- package/dist/core/git-utils.js +146 -0
- package/dist/core/git-utils.js.map +1 -0
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +19 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/kanban.d.ts +1 -1
- package/dist/core/kanban.d.ts.map +1 -1
- package/dist/core/kanban.js +3 -3
- package/dist/core/kanban.js.map +1 -1
- package/dist/core/llm-utils.d.ts +103 -0
- package/dist/core/llm-utils.d.ts.map +1 -0
- package/dist/core/llm-utils.js +368 -0
- package/dist/core/llm-utils.js.map +1 -0
- package/dist/core/logger.d.ts +92 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +221 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/process-manager.d.ts +15 -0
- package/dist/core/process-manager.d.ts.map +1 -0
- package/dist/core/process-manager.js +132 -0
- package/dist/core/process-manager.js.map +1 -0
- package/dist/core/story-logger.d.ts +102 -0
- package/dist/core/story-logger.d.ts.map +1 -0
- package/dist/core/story-logger.js +265 -0
- package/dist/core/story-logger.js.map +1 -0
- package/dist/core/story.d.ts +113 -20
- package/dist/core/story.d.ts.map +1 -1
- package/dist/core/story.js +328 -40
- package/dist/core/story.js.map +1 -1
- package/dist/core/task-parser.d.ts +59 -0
- package/dist/core/task-parser.d.ts.map +1 -0
- package/dist/core/task-parser.js +235 -0
- package/dist/core/task-parser.js.map +1 -0
- package/dist/core/task-progress.d.ts +92 -0
- package/dist/core/task-progress.d.ts.map +1 -0
- package/dist/core/task-progress.js +280 -0
- package/dist/core/task-progress.js.map +1 -0
- package/dist/core/workflow-state.d.ts +45 -6
- package/dist/core/workflow-state.d.ts.map +1 -1
- package/dist/core/workflow-state.js +201 -12
- package/dist/core/workflow-state.js.map +1 -1
- package/dist/core/worktree.d.ts +186 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +554 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/index.js +146 -5
- package/dist/index.js.map +1 -1
- package/dist/services/error-classifier.d.ts +119 -0
- package/dist/services/error-classifier.d.ts.map +1 -0
- package/dist/services/error-classifier.js +182 -0
- package/dist/services/error-classifier.js.map +1 -0
- package/dist/types/index.d.ts +381 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +5 -2
- package/templates/story.md +5 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
/**
|
|
5
|
+
* Extract function names from file content using regex patterns
|
|
6
|
+
* Supports: function declarations, arrow functions, const functions
|
|
7
|
+
*
|
|
8
|
+
* @param fileContent - Source code to analyze
|
|
9
|
+
* @returns Array of function names found in the file
|
|
10
|
+
*/
|
|
11
|
+
export function extractFunctionNames(fileContent) {
|
|
12
|
+
const functionNames = [];
|
|
13
|
+
// Pattern 1: function declarations (function foo() {})
|
|
14
|
+
const functionDeclPattern = /function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g;
|
|
15
|
+
let match;
|
|
16
|
+
while ((match = functionDeclPattern.exec(fileContent)) !== null) {
|
|
17
|
+
functionNames.push(match[1]);
|
|
18
|
+
}
|
|
19
|
+
// Pattern 2: arrow functions (const foo = () => {})
|
|
20
|
+
const arrowFunctionPattern = /const\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=\s*\(/g;
|
|
21
|
+
while ((match = arrowFunctionPattern.exec(fileContent)) !== null) {
|
|
22
|
+
functionNames.push(match[1]);
|
|
23
|
+
}
|
|
24
|
+
// Pattern 3: function expressions (const foo = function() {})
|
|
25
|
+
const functionExprPattern = /const\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=\s*function/g;
|
|
26
|
+
while ((match = functionExprPattern.exec(fileContent)) !== null) {
|
|
27
|
+
functionNames.push(match[1]);
|
|
28
|
+
}
|
|
29
|
+
return functionNames;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if a function name matches legitimate test utility patterns
|
|
33
|
+
* Returns true if the function is a legitimate test helper (should NOT be flagged)
|
|
34
|
+
*
|
|
35
|
+
* Legitimate patterns:
|
|
36
|
+
* - Factory functions: create*, make*, build*, mock*, stub*, fake*
|
|
37
|
+
* - Setup/teardown: setup*, teardown*, before*, after*, cleanup*
|
|
38
|
+
* - Assertion helpers: assert*, expect*, verify*, check*, should*
|
|
39
|
+
* - Test data builders: with*, given*, having*
|
|
40
|
+
*
|
|
41
|
+
* @param functionName - Name of the function to check
|
|
42
|
+
* @returns true if legitimate test utility, false if potential anti-pattern
|
|
43
|
+
*/
|
|
44
|
+
export function isLegitimateTestUtility(functionName) {
|
|
45
|
+
const legitimatePatterns = [
|
|
46
|
+
// Factory functions
|
|
47
|
+
/^(create|make|build|mock|stub|fake)/i,
|
|
48
|
+
// Setup/teardown helpers
|
|
49
|
+
/^(setup|teardown|before|after|cleanup)/i,
|
|
50
|
+
// Assertion helpers
|
|
51
|
+
/^(assert|expect|verify|check|should)/i,
|
|
52
|
+
// Test data builders
|
|
53
|
+
/^(with|given|having)/i,
|
|
54
|
+
];
|
|
55
|
+
// Check if function matches any legitimate pattern
|
|
56
|
+
for (const pattern of legitimatePatterns) {
|
|
57
|
+
if (pattern.test(functionName)) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Check for anti-pattern indicators
|
|
62
|
+
const antiPatterns = [
|
|
63
|
+
/Test$/, // Ends with "Test"
|
|
64
|
+
/^test[A-Z]/, // Starts with "test" followed by capital letter
|
|
65
|
+
];
|
|
66
|
+
for (const pattern of antiPatterns) {
|
|
67
|
+
if (pattern.test(functionName)) {
|
|
68
|
+
return false; // This is a potential anti-pattern
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Default: consider it legitimate (avoid false positives)
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Find the corresponding production file for a test file
|
|
76
|
+
* Handles both colocated tests and centralized test directories
|
|
77
|
+
*
|
|
78
|
+
* @param testFilePath - Absolute path to test file
|
|
79
|
+
* @returns Absolute path to production file, or null if not found
|
|
80
|
+
*/
|
|
81
|
+
export function findProductionFile(testFilePath) {
|
|
82
|
+
// Remove .test.ts or .test.js extension
|
|
83
|
+
const withoutTestExt = testFilePath.replace(/\.test\.(ts|tsx|js|jsx)$/, '.$1');
|
|
84
|
+
// Case 1: Colocated test (src/core/story.test.ts -> src/core/story.ts)
|
|
85
|
+
if (fs.existsSync(withoutTestExt)) {
|
|
86
|
+
return withoutTestExt;
|
|
87
|
+
}
|
|
88
|
+
// Case 2: Test in tests/ directory (tests/integration/foo.test.ts -> src/integration/foo.ts)
|
|
89
|
+
if (testFilePath.includes('/tests/')) {
|
|
90
|
+
const relativePath = testFilePath.split('/tests/')[1];
|
|
91
|
+
const srcPath = testFilePath.split('/tests/')[0] + '/src/' + relativePath.replace(/\.test\.(ts|tsx|js|jsx)$/, '.$1');
|
|
92
|
+
if (fs.existsSync(srcPath)) {
|
|
93
|
+
return srcPath;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Case 3: Try replacing tests/ with src/ in path
|
|
97
|
+
const srcReplaced = testFilePath.replace('/tests/', '/src/').replace(/\.test\.(ts|tsx|js|jsx)$/, '.$1');
|
|
98
|
+
if (fs.existsSync(srcReplaced)) {
|
|
99
|
+
return srcReplaced;
|
|
100
|
+
}
|
|
101
|
+
// Fallback: return the properly transformed path even if it doesn't exist
|
|
102
|
+
// For tests/ directory files, return the src/ mapped path
|
|
103
|
+
// Caller can handle missing files
|
|
104
|
+
if (testFilePath.includes('/tests/')) {
|
|
105
|
+
const relativePath = testFilePath.split('/tests/')[1];
|
|
106
|
+
return testFilePath.split('/tests/')[0] + '/src/' + relativePath.replace(/\.test\.(ts|tsx|js|jsx)$/, '.$1');
|
|
107
|
+
}
|
|
108
|
+
return withoutTestExt;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get line number for a function in source code
|
|
112
|
+
*
|
|
113
|
+
* @param fileContent - Source code
|
|
114
|
+
* @param functionName - Function to find
|
|
115
|
+
* @returns Line number (1-indexed) or undefined if not found
|
|
116
|
+
*/
|
|
117
|
+
function getFunctionLineNumber(fileContent, functionName) {
|
|
118
|
+
const lines = fileContent.split('\n');
|
|
119
|
+
for (let i = 0; i < lines.length; i++) {
|
|
120
|
+
const line = lines[i];
|
|
121
|
+
// Match function declaration with the exact function name
|
|
122
|
+
if (line.includes(`function ${functionName}(`) ||
|
|
123
|
+
line.includes(`function ${functionName} (`) ||
|
|
124
|
+
line.includes(`const ${functionName} =`)) {
|
|
125
|
+
return i + 1; // 1-indexed
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Analyze a single test file for duplication patterns
|
|
132
|
+
*
|
|
133
|
+
* @param testFilePath - Absolute path to test file
|
|
134
|
+
* @param testFileContent - Content of the test file
|
|
135
|
+
* @param productionFileContent - Content of the corresponding production file
|
|
136
|
+
* @returns Array of ReviewIssue objects for detected anti-patterns
|
|
137
|
+
*/
|
|
138
|
+
export function analyzeTestFile(testFilePath, testFileContent, productionFileContent) {
|
|
139
|
+
const issues = [];
|
|
140
|
+
// Extract function names from test file
|
|
141
|
+
const testFunctions = extractFunctionNames(testFileContent);
|
|
142
|
+
// Extract exported functions from production file
|
|
143
|
+
const productionExports = extractProductionExports(productionFileContent);
|
|
144
|
+
// Check each test function for anti-patterns
|
|
145
|
+
for (const functionName of testFunctions) {
|
|
146
|
+
// Skip legitimate test utilities
|
|
147
|
+
if (isLegitimateTestUtility(functionName)) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// Check if this looks like a duplicated production function
|
|
151
|
+
const matchingExport = findMatchingProductionExport(functionName, productionExports);
|
|
152
|
+
if (matchingExport) {
|
|
153
|
+
const lineNumber = getFunctionLineNumber(testFileContent, functionName);
|
|
154
|
+
const productionFile = findProductionFile(testFilePath);
|
|
155
|
+
issues.push({
|
|
156
|
+
severity: 'major',
|
|
157
|
+
category: 'test_antipattern',
|
|
158
|
+
description: `Test helper function "${functionName}" appears to duplicate production logic. Tests should import actual functions instead of reimplementing them.`,
|
|
159
|
+
file: testFilePath,
|
|
160
|
+
line: lineNumber,
|
|
161
|
+
suggestedFix: productionFile
|
|
162
|
+
? `Export "${matchingExport}" from "${path.basename(productionFile)}" and import it in tests instead of duplicating the logic.`
|
|
163
|
+
: `Export the production version of "${matchingExport}" and import it in tests instead of duplicating the logic.`,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return issues;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Extract exported function names from production file content
|
|
171
|
+
*
|
|
172
|
+
* @param fileContent - Production file source code
|
|
173
|
+
* @returns Array of exported function names
|
|
174
|
+
*/
|
|
175
|
+
function extractProductionExports(fileContent) {
|
|
176
|
+
const exports = [];
|
|
177
|
+
// Pattern 1: export function foo() {}
|
|
178
|
+
const exportFunctionPattern = /export\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g;
|
|
179
|
+
let match;
|
|
180
|
+
while ((match = exportFunctionPattern.exec(fileContent)) !== null) {
|
|
181
|
+
exports.push(match[1]);
|
|
182
|
+
}
|
|
183
|
+
// Pattern 2: export const foo = () => {}
|
|
184
|
+
const exportConstPattern = /export\s+const\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/g;
|
|
185
|
+
while ((match = exportConstPattern.exec(fileContent)) !== null) {
|
|
186
|
+
exports.push(match[1]);
|
|
187
|
+
}
|
|
188
|
+
// Pattern 3: export { foo, bar }
|
|
189
|
+
const exportBlockPattern = /export\s*\{\s*([^}]+)\s*\}/g;
|
|
190
|
+
while ((match = exportBlockPattern.exec(fileContent)) !== null) {
|
|
191
|
+
const names = match[1].split(',').map(n => n.trim().split(/\s+as\s+/)[0].trim());
|
|
192
|
+
exports.push(...names);
|
|
193
|
+
}
|
|
194
|
+
return exports;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Find matching production export for a test function name
|
|
198
|
+
* Handles naming patterns: fooTest -> foo, testFoo -> foo
|
|
199
|
+
*
|
|
200
|
+
* @param testFunctionName - Name of test helper function
|
|
201
|
+
* @param productionExports - Array of exported function names from production
|
|
202
|
+
* @returns Matching export name or null
|
|
203
|
+
*/
|
|
204
|
+
function findMatchingProductionExport(testFunctionName, productionExports) {
|
|
205
|
+
// Pattern 1: fooTest -> foo
|
|
206
|
+
if (testFunctionName.endsWith('Test')) {
|
|
207
|
+
const baseName = testFunctionName.slice(0, -4); // Remove "Test" suffix
|
|
208
|
+
if (productionExports.includes(baseName)) {
|
|
209
|
+
return baseName;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Pattern 2: testFoo -> foo
|
|
213
|
+
if (testFunctionName.startsWith('test') && testFunctionName.length > 4) {
|
|
214
|
+
const baseName = testFunctionName.charAt(4).toLowerCase() + testFunctionName.slice(5);
|
|
215
|
+
if (productionExports.includes(baseName)) {
|
|
216
|
+
return baseName;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Detect test duplication patterns across all test files in working directory
|
|
223
|
+
* Main entry point for the detection system
|
|
224
|
+
*
|
|
225
|
+
* @param workingDir - Project root directory
|
|
226
|
+
* @returns Array of ReviewIssue objects for all detected anti-patterns
|
|
227
|
+
*/
|
|
228
|
+
export async function detectTestDuplicationPatterns(workingDir) {
|
|
229
|
+
const allIssues = [];
|
|
230
|
+
try {
|
|
231
|
+
// Find all test files using glob patterns
|
|
232
|
+
const testPatterns = ['**/*.test.ts', '**/*.test.tsx', '**/*.test.js', '**/*.test.jsx'];
|
|
233
|
+
const testFiles = [];
|
|
234
|
+
for (const pattern of testPatterns) {
|
|
235
|
+
const matches = await glob(pattern, {
|
|
236
|
+
cwd: workingDir,
|
|
237
|
+
absolute: true,
|
|
238
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**'],
|
|
239
|
+
});
|
|
240
|
+
testFiles.push(...matches);
|
|
241
|
+
}
|
|
242
|
+
// Analyze each test file
|
|
243
|
+
for (const testFilePath of testFiles) {
|
|
244
|
+
try {
|
|
245
|
+
// Read test file
|
|
246
|
+
const testFileContent = fs.readFileSync(testFilePath, 'utf-8');
|
|
247
|
+
// Find corresponding production file
|
|
248
|
+
const productionFilePath = findProductionFile(testFilePath);
|
|
249
|
+
if (!productionFilePath || !fs.existsSync(productionFilePath)) {
|
|
250
|
+
// No production file found - skip (might be integration test or test utilities)
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
// Read production file
|
|
254
|
+
const productionFileContent = fs.readFileSync(productionFilePath, 'utf-8');
|
|
255
|
+
// Analyze for anti-patterns
|
|
256
|
+
const issues = analyzeTestFile(testFilePath, testFileContent, productionFileContent);
|
|
257
|
+
allIssues.push(...issues);
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
// Skip files that can't be read (permissions, encoding issues, etc.)
|
|
261
|
+
console.debug(`Skipping test file ${testFilePath}: ${error}`);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
// If glob fails or directory doesn't exist, return empty array
|
|
268
|
+
console.debug(`Test pattern detection failed: ${error}`);
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
271
|
+
return allIssues;
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=test-pattern-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-pattern-detector.js","sourceRoot":"","sources":["../../src/agents/test-pattern-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,17 @@ export interface VerificationOptions {
|
|
|
16
16
|
output: string;
|
|
17
17
|
}>;
|
|
18
18
|
requirePassingTests?: boolean;
|
|
19
|
+
skipDependencyCheck?: boolean;
|
|
19
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Ensures dependencies are installed before running tests/build.
|
|
23
|
+
* Checks if node_modules exists and has packages. If not, runs the appropriate install command.
|
|
24
|
+
* @param workingDir - The directory to check for dependencies
|
|
25
|
+
* @returns Result indicating if install was needed and any error that occurred
|
|
26
|
+
*/
|
|
27
|
+
export declare function ensureDependenciesInstalled(workingDir: string): {
|
|
28
|
+
installed: boolean;
|
|
29
|
+
error?: string;
|
|
30
|
+
};
|
|
20
31
|
export declare function verifyImplementation(story: Story, workingDir: string, options?: VerificationOptions): Promise<VerificationResult>;
|
|
21
32
|
//# sourceMappingURL=verification.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../../src/agents/verification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../../src/agents/verification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAO1C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClG,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClG,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAWD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAkDtG;AA+ED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAiF7B"}
|
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
import { loadConfig } from '../core/config.js';
|
|
2
|
-
import { spawn } from 'child_process';
|
|
2
|
+
import { spawn, spawnSync } from 'child_process';
|
|
3
|
+
import { ProcessManager } from '../core/process-manager.js';
|
|
4
|
+
import { existsSync, readdirSync } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
/**
|
|
7
|
+
* Lock file to package manager mapping
|
|
8
|
+
*/
|
|
9
|
+
const LOCK_FILE_TO_PM = {
|
|
10
|
+
'package-lock.json': 'npm',
|
|
11
|
+
'yarn.lock': 'yarn',
|
|
12
|
+
'pnpm-lock.yaml': 'pnpm',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Ensures dependencies are installed before running tests/build.
|
|
16
|
+
* Checks if node_modules exists and has packages. If not, runs the appropriate install command.
|
|
17
|
+
* @param workingDir - The directory to check for dependencies
|
|
18
|
+
* @returns Result indicating if install was needed and any error that occurred
|
|
19
|
+
*/
|
|
20
|
+
export function ensureDependenciesInstalled(workingDir) {
|
|
21
|
+
const packageJsonPath = path.join(workingDir, 'package.json');
|
|
22
|
+
// Skip if not a Node.js project
|
|
23
|
+
if (!existsSync(packageJsonPath)) {
|
|
24
|
+
return { installed: false };
|
|
25
|
+
}
|
|
26
|
+
const nodeModulesPath = path.join(workingDir, 'node_modules');
|
|
27
|
+
// Check if node_modules exists and has contents
|
|
28
|
+
let hasNodeModules = false;
|
|
29
|
+
if (existsSync(nodeModulesPath)) {
|
|
30
|
+
try {
|
|
31
|
+
const contents = readdirSync(nodeModulesPath);
|
|
32
|
+
// node_modules should have more than just .bin to be considered populated
|
|
33
|
+
hasNodeModules = contents.length > 1 || (contents.length === 1 && contents[0] !== '.bin');
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
hasNodeModules = false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (hasNodeModules) {
|
|
40
|
+
return { installed: false };
|
|
41
|
+
}
|
|
42
|
+
// Detect package manager from lock file
|
|
43
|
+
let packageManager = 'npm';
|
|
44
|
+
for (const [lockFile, pm] of Object.entries(LOCK_FILE_TO_PM)) {
|
|
45
|
+
if (existsSync(path.join(workingDir, lockFile))) {
|
|
46
|
+
packageManager = pm;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Run install command
|
|
51
|
+
const result = spawnSync(packageManager, ['install'], {
|
|
52
|
+
cwd: workingDir,
|
|
53
|
+
encoding: 'utf-8',
|
|
54
|
+
shell: false,
|
|
55
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
56
|
+
timeout: 120000, // 2 minute timeout
|
|
57
|
+
});
|
|
58
|
+
if (result.status !== 0) {
|
|
59
|
+
const stderr = result.stderr?.toString() || '';
|
|
60
|
+
return { installed: false, error: `Failed to install dependencies: ${stderr}` };
|
|
61
|
+
}
|
|
62
|
+
return { installed: true };
|
|
63
|
+
}
|
|
3
64
|
async function runCommandAsync(command, workingDir, timeout) {
|
|
4
65
|
return new Promise((resolve) => {
|
|
5
66
|
const outputChunks = [];
|
|
@@ -11,6 +72,7 @@ async function runCommandAsync(command, workingDir, timeout) {
|
|
|
11
72
|
cwd: workingDir,
|
|
12
73
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
13
74
|
});
|
|
75
|
+
ProcessManager.getInstance().registerChild(child);
|
|
14
76
|
const timeoutId = setTimeout(() => {
|
|
15
77
|
killed = true;
|
|
16
78
|
child.kill('SIGTERM');
|
|
@@ -73,18 +135,20 @@ export async function verifyImplementation(story, workingDir, options = {}) {
|
|
|
73
135
|
let buildOutput = '';
|
|
74
136
|
let testsRan = false;
|
|
75
137
|
let buildRan = false;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
138
|
+
// Ensure dependencies are installed before running tests/build
|
|
139
|
+
if (!options.skipDependencyCheck) {
|
|
140
|
+
const depResult = ensureDependenciesInstalled(workingDir);
|
|
141
|
+
if (depResult.error) {
|
|
142
|
+
return {
|
|
143
|
+
passed: false,
|
|
144
|
+
failures: 0,
|
|
145
|
+
timestamp,
|
|
146
|
+
testsOutput: '',
|
|
147
|
+
buildOutput: depResult.error,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
87
150
|
}
|
|
151
|
+
// Run build first - tests require successful compilation
|
|
88
152
|
if (options.runBuild) {
|
|
89
153
|
buildRan = true;
|
|
90
154
|
const buildResult = await options.runBuild(workingDir, buildTimeout);
|
|
@@ -97,6 +161,29 @@ export async function verifyImplementation(story, workingDir, options = {}) {
|
|
|
97
161
|
buildPassed = buildResult.success;
|
|
98
162
|
buildOutput = buildResult.output;
|
|
99
163
|
}
|
|
164
|
+
// Short-circuit: Don't run tests if build failed
|
|
165
|
+
if (buildRan && !buildPassed) {
|
|
166
|
+
return {
|
|
167
|
+
passed: false,
|
|
168
|
+
failures: 0,
|
|
169
|
+
timestamp,
|
|
170
|
+
testsOutput: 'Build failed - skipping tests. Fix TypeScript errors first.',
|
|
171
|
+
buildOutput,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// Run tests only after successful build (or when no build command exists)
|
|
175
|
+
if (options.runTests) {
|
|
176
|
+
testsRan = true;
|
|
177
|
+
const testResult = await options.runTests(workingDir, testTimeout);
|
|
178
|
+
testsPassed = testResult.success;
|
|
179
|
+
testsOutput = testResult.output;
|
|
180
|
+
}
|
|
181
|
+
else if (config.testCommand) {
|
|
182
|
+
testsRan = true;
|
|
183
|
+
const testResult = await runCommandAsync(config.testCommand, workingDir, testTimeout);
|
|
184
|
+
testsPassed = testResult.success;
|
|
185
|
+
testsOutput = testResult.output;
|
|
186
|
+
}
|
|
100
187
|
const failures = testsPassed ? 0 : extractFailureCount(testsOutput);
|
|
101
188
|
let passed;
|
|
102
189
|
if (requirePassingTests) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/agents/verification.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/agents/verification.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Story } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result summary for batch processing operation
|
|
4
|
+
*/
|
|
5
|
+
export interface BatchResult {
|
|
6
|
+
/** Total number of stories in the batch */
|
|
7
|
+
total: number;
|
|
8
|
+
/** Number of stories that completed successfully */
|
|
9
|
+
succeeded: number;
|
|
10
|
+
/** Number of stories that failed during processing */
|
|
11
|
+
failed: number;
|
|
12
|
+
/** Number of stories that were skipped (e.g., already done) */
|
|
13
|
+
skipped: number;
|
|
14
|
+
/** List of errors encountered during batch processing */
|
|
15
|
+
errors: Array<{
|
|
16
|
+
storyId: string;
|
|
17
|
+
error: string;
|
|
18
|
+
}>;
|
|
19
|
+
/** Total execution time in milliseconds */
|
|
20
|
+
duration: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Options for batch processing
|
|
24
|
+
*/
|
|
25
|
+
export interface BatchOptions {
|
|
26
|
+
/** Preview actions without executing them */
|
|
27
|
+
dryRun?: boolean;
|
|
28
|
+
/** Create isolated git worktrees for each story */
|
|
29
|
+
worktree?: boolean;
|
|
30
|
+
/** Skip git validation and conflict checks */
|
|
31
|
+
force?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Internal progress tracking for batch processing
|
|
35
|
+
*/
|
|
36
|
+
export interface BatchProgress {
|
|
37
|
+
/** Current story index (0-based) */
|
|
38
|
+
currentIndex: number;
|
|
39
|
+
/** Total number of stories in batch */
|
|
40
|
+
total: number;
|
|
41
|
+
/** Current story being processed */
|
|
42
|
+
currentStory: Story | null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Format batch progress header for a story
|
|
46
|
+
* Example: [1/3] Processing: S-001 - Add user authentication
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatBatchProgress(progress: BatchProgress): string;
|
|
49
|
+
/**
|
|
50
|
+
* Format final batch summary
|
|
51
|
+
*/
|
|
52
|
+
export declare function formatBatchSummary(result: BatchResult): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Log completion message for an individual story
|
|
55
|
+
*/
|
|
56
|
+
export declare function logStoryCompletion(storyId: string, success: boolean, c: any): void;
|
|
57
|
+
/**
|
|
58
|
+
* Prompt user whether to continue after a story failure
|
|
59
|
+
* Returns true to continue, false to abort
|
|
60
|
+
*
|
|
61
|
+
* In non-interactive mode (no TTY), always returns false (abort)
|
|
62
|
+
*/
|
|
63
|
+
export declare function promptContinueOnError(storyId: string, c: any): Promise<boolean>;
|
|
64
|
+
//# sourceMappingURL=batch-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-processor.d.ts","sourceRoot":"","sources":["../../src/cli/batch-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,YAAY,EAAE,KAAK,GAAG,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAYnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAgChE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,GAAG,IAAI,CAMlF;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBrF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as readline from 'readline';
|
|
2
|
+
/**
|
|
3
|
+
* Format batch progress header for a story
|
|
4
|
+
* Example: [1/3] Processing: S-001 - Add user authentication
|
|
5
|
+
*/
|
|
6
|
+
export function formatBatchProgress(progress) {
|
|
7
|
+
const { currentIndex, total, currentStory } = progress;
|
|
8
|
+
const position = `[${currentIndex + 1}/${total}]`;
|
|
9
|
+
if (!currentStory) {
|
|
10
|
+
return `${position} Processing story...`;
|
|
11
|
+
}
|
|
12
|
+
const storyId = currentStory.frontmatter.id;
|
|
13
|
+
const title = currentStory.frontmatter.title;
|
|
14
|
+
return `${position} Processing: ${storyId} - ${title}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Format final batch summary
|
|
18
|
+
*/
|
|
19
|
+
export function formatBatchSummary(result) {
|
|
20
|
+
const lines = [];
|
|
21
|
+
const { total, succeeded, failed, skipped, duration } = result;
|
|
22
|
+
lines.push('');
|
|
23
|
+
lines.push('═══ Batch Processing Summary ═══');
|
|
24
|
+
lines.push('');
|
|
25
|
+
lines.push(`Total stories: ${total}`);
|
|
26
|
+
lines.push(`✓ Succeeded: ${succeeded}`);
|
|
27
|
+
if (failed > 0) {
|
|
28
|
+
lines.push(`✗ Failed: ${failed}`);
|
|
29
|
+
}
|
|
30
|
+
if (skipped > 0) {
|
|
31
|
+
lines.push(`⊘ Skipped: ${skipped}`);
|
|
32
|
+
}
|
|
33
|
+
const durationSec = (duration / 1000).toFixed(1);
|
|
34
|
+
lines.push(`⏱ Execution time: ${durationSec}s`);
|
|
35
|
+
if (result.errors.length > 0) {
|
|
36
|
+
lines.push('');
|
|
37
|
+
lines.push('Failed stories:');
|
|
38
|
+
for (const error of result.errors) {
|
|
39
|
+
lines.push(` - ${error.storyId}: ${error.error}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
lines.push('');
|
|
43
|
+
return lines;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Log completion message for an individual story
|
|
47
|
+
*/
|
|
48
|
+
export function logStoryCompletion(storyId, success, c) {
|
|
49
|
+
if (success) {
|
|
50
|
+
console.log(c.success(` ✓ Completed: ${storyId}`));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log(c.error(` ✗ Failed: ${storyId}`));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Prompt user whether to continue after a story failure
|
|
58
|
+
* Returns true to continue, false to abort
|
|
59
|
+
*
|
|
60
|
+
* In non-interactive mode (no TTY), always returns false (abort)
|
|
61
|
+
*/
|
|
62
|
+
export async function promptContinueOnError(storyId, c) {
|
|
63
|
+
// Non-interactive mode: always abort
|
|
64
|
+
if (!process.stdin.isTTY) {
|
|
65
|
+
console.log();
|
|
66
|
+
console.log(c.dim('Non-interactive mode: aborting batch processing'));
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
// Interactive mode: prompt user
|
|
70
|
+
console.log();
|
|
71
|
+
const rl = readline.createInterface({
|
|
72
|
+
input: process.stdin,
|
|
73
|
+
output: process.stdout,
|
|
74
|
+
});
|
|
75
|
+
const answer = await new Promise((resolve) => {
|
|
76
|
+
rl.question(c.dim(`Story ${storyId} failed. Continue to next story? [y/N]: `), (ans) => {
|
|
77
|
+
rl.close();
|
|
78
|
+
resolve(ans.toLowerCase().trim());
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
return answer === 'y' || answer === 'yes';
|
|
82
|
+
}
|
|
83
|
+
// Note: The main processBatch function has been moved to commands.ts
|
|
84
|
+
// to avoid circular dependencies. This module only exports utility functions.
|
|
85
|
+
//# sourceMappingURL=batch-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-processor.js","sourceRoot":"","sources":["../../src/cli/batch-processor.ts"],"names":[],"mappings":"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"}
|