claudecode-omc 4.7.4 → 4.8.0
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/.claude-plugin/plugin.json +1 -1
- package/README.md +50 -0
- package/agents/test-engineer.md +74 -0
- package/bridge/cli.cjs +9335 -117
- package/dist/cli/index.js +201 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/testing/analyzers/complexity.d.ts +18 -0
- package/dist/testing/analyzers/complexity.d.ts.map +1 -0
- package/dist/testing/analyzers/complexity.js +121 -0
- package/dist/testing/analyzers/complexity.js.map +1 -0
- package/dist/testing/analyzers/coverage.d.ts +13 -0
- package/dist/testing/analyzers/coverage.d.ts.map +1 -0
- package/dist/testing/analyzers/coverage.js +99 -0
- package/dist/testing/analyzers/coverage.js.map +1 -0
- package/dist/testing/analyzers/quality-scorer.d.ts +8 -0
- package/dist/testing/analyzers/quality-scorer.d.ts.map +1 -0
- package/dist/testing/analyzers/quality-scorer.js +128 -0
- package/dist/testing/analyzers/quality-scorer.js.map +1 -0
- package/dist/testing/analyzers/types.d.ts +56 -0
- package/dist/testing/analyzers/types.d.ts.map +1 -0
- package/dist/testing/analyzers/types.js +2 -0
- package/dist/testing/analyzers/types.js.map +1 -0
- package/dist/testing/cli/agent-integration.d.ts +20 -0
- package/dist/testing/cli/agent-integration.d.ts.map +1 -0
- package/dist/testing/cli/agent-integration.js +60 -0
- package/dist/testing/cli/agent-integration.js.map +1 -0
- package/dist/testing/cli/commands.d.ts +100 -0
- package/dist/testing/cli/commands.d.ts.map +1 -0
- package/dist/testing/cli/commands.js +250 -0
- package/dist/testing/cli/commands.js.map +1 -0
- package/dist/testing/cli/ultraqa-integration.d.ts +13 -0
- package/dist/testing/cli/ultraqa-integration.d.ts.map +1 -0
- package/dist/testing/cli/ultraqa-integration.js +68 -0
- package/dist/testing/cli/ultraqa-integration.js.map +1 -0
- package/dist/testing/detectors/go.d.ts +3 -0
- package/dist/testing/detectors/go.d.ts.map +1 -0
- package/dist/testing/detectors/go.js +38 -0
- package/dist/testing/detectors/go.js.map +1 -0
- package/dist/testing/detectors/index.d.ts +8 -0
- package/dist/testing/detectors/index.d.ts.map +1 -0
- package/dist/testing/detectors/index.js +46 -0
- package/dist/testing/detectors/index.js.map +1 -0
- package/dist/testing/detectors/package-json.d.ts +3 -0
- package/dist/testing/detectors/package-json.d.ts.map +1 -0
- package/dist/testing/detectors/package-json.js +52 -0
- package/dist/testing/detectors/package-json.js.map +1 -0
- package/dist/testing/detectors/python.d.ts +3 -0
- package/dist/testing/detectors/python.d.ts.map +1 -0
- package/dist/testing/detectors/python.js +37 -0
- package/dist/testing/detectors/python.js.map +1 -0
- package/dist/testing/detectors/rust.d.ts +3 -0
- package/dist/testing/detectors/rust.d.ts.map +1 -0
- package/dist/testing/detectors/rust.js +39 -0
- package/dist/testing/detectors/rust.js.map +1 -0
- package/dist/testing/generators/contract.d.ts +14 -0
- package/dist/testing/generators/contract.d.ts.map +1 -0
- package/dist/testing/generators/contract.js +163 -0
- package/dist/testing/generators/contract.js.map +1 -0
- package/dist/testing/generators/e2e.d.ts +34 -0
- package/dist/testing/generators/e2e.d.ts.map +1 -0
- package/dist/testing/generators/e2e.js +74 -0
- package/dist/testing/generators/e2e.js.map +1 -0
- package/dist/testing/generators/go.d.ts +12 -0
- package/dist/testing/generators/go.d.ts.map +1 -0
- package/dist/testing/generators/go.js +144 -0
- package/dist/testing/generators/go.js.map +1 -0
- package/dist/testing/generators/nodejs.d.ts +12 -0
- package/dist/testing/generators/nodejs.d.ts.map +1 -0
- package/dist/testing/generators/nodejs.js +37 -0
- package/dist/testing/generators/nodejs.js.map +1 -0
- package/dist/testing/generators/python.d.ts +12 -0
- package/dist/testing/generators/python.d.ts.map +1 -0
- package/dist/testing/generators/python.js +163 -0
- package/dist/testing/generators/python.js.map +1 -0
- package/dist/testing/generators/react.d.ts +12 -0
- package/dist/testing/generators/react.d.ts.map +1 -0
- package/dist/testing/generators/react.js +31 -0
- package/dist/testing/generators/react.js.map +1 -0
- package/dist/testing/generators/rust.d.ts +11 -0
- package/dist/testing/generators/rust.d.ts.map +1 -0
- package/dist/testing/generators/rust.js +138 -0
- package/dist/testing/generators/rust.js.map +1 -0
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +11 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/integrations/autopilot.d.ts +42 -0
- package/dist/testing/integrations/autopilot.d.ts.map +1 -0
- package/dist/testing/integrations/autopilot.js +55 -0
- package/dist/testing/integrations/autopilot.js.map +1 -0
- package/dist/testing/integrations/cicd.d.ts +26 -0
- package/dist/testing/integrations/cicd.d.ts.map +1 -0
- package/dist/testing/integrations/cicd.js +162 -0
- package/dist/testing/integrations/cicd.js.map +1 -0
- package/dist/testing/integrations/giskard/behavioral-tests.d.ts +4 -0
- package/dist/testing/integrations/giskard/behavioral-tests.d.ts.map +1 -0
- package/dist/testing/integrations/giskard/behavioral-tests.js +66 -0
- package/dist/testing/integrations/giskard/behavioral-tests.js.map +1 -0
- package/dist/testing/integrations/giskard/types.d.ts +35 -0
- package/dist/testing/integrations/giskard/types.d.ts.map +1 -0
- package/dist/testing/integrations/giskard/types.js +2 -0
- package/dist/testing/integrations/giskard/types.js.map +1 -0
- package/dist/testing/integrations/promptfoo/config-generator.d.ts +5 -0
- package/dist/testing/integrations/promptfoo/config-generator.d.ts.map +1 -0
- package/dist/testing/integrations/promptfoo/config-generator.js +44 -0
- package/dist/testing/integrations/promptfoo/config-generator.js.map +1 -0
- package/dist/testing/integrations/promptfoo/types.d.ts +36 -0
- package/dist/testing/integrations/promptfoo/types.d.ts.map +1 -0
- package/dist/testing/integrations/promptfoo/types.js +2 -0
- package/dist/testing/integrations/promptfoo/types.js.map +1 -0
- package/dist/testing/integrations/ralph.d.ts +65 -0
- package/dist/testing/integrations/ralph.d.ts.map +1 -0
- package/dist/testing/integrations/ralph.js +69 -0
- package/dist/testing/integrations/ralph.js.map +1 -0
- package/dist/testing/performance/cache-manager.d.ts +16 -0
- package/dist/testing/performance/cache-manager.d.ts.map +1 -0
- package/dist/testing/performance/cache-manager.js +39 -0
- package/dist/testing/performance/cache-manager.js.map +1 -0
- package/dist/testing/performance/parallel-generator.d.ts +23 -0
- package/dist/testing/performance/parallel-generator.d.ts.map +1 -0
- package/dist/testing/performance/parallel-generator.js +31 -0
- package/dist/testing/performance/parallel-generator.js.map +1 -0
- package/dist/testing/types.d.ts +23 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing/types.js +2 -0
- package/dist/testing/types.js.map +1 -0
- package/docs/2026-03-06-llm-testing-system-phase1.md +0 -0
- package/docs/plans/2026-03-06-llm-testing-system-design.md +311 -0
- package/docs/plans/2026-03-06-llm-testing-system-phase1.md +1268 -0
- package/docs/plans/2026-03-06-llm-testing-system-phase2.md +3053 -0
- package/docs/plans/2026-03-06-llm-testing-system-phase3.md +1830 -0
- package/docs/testing/PHASE2.md +266 -0
- package/docs/testing/PHASE3.md +601 -0
- package/docs/testing/README.md +634 -0
- package/package.json +1 -1
- package/skills/test-gen/skill.md +531 -0
- package/skills/ultraqa.md +58 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { detectTechStack } from '../detectors/index.js';
|
|
4
|
+
import { generateReactTest } from '../generators/react.js';
|
|
5
|
+
import { generateNodeJsTest } from '../generators/nodejs.js';
|
|
6
|
+
import { generatePythonTest } from '../generators/python.js';
|
|
7
|
+
import { generateGoTest } from '../generators/go.js';
|
|
8
|
+
import { generateRustTest } from '../generators/rust.js';
|
|
9
|
+
import { generateContractTest } from '../generators/contract.js';
|
|
10
|
+
import { analyzeCoverage } from '../analyzers/coverage.js';
|
|
11
|
+
import { analyzeComplexity } from '../analyzers/complexity.js';
|
|
12
|
+
function detectLanguage(filePath) {
|
|
13
|
+
if (filePath.match(/\.(tsx|jsx)$/))
|
|
14
|
+
return 'react';
|
|
15
|
+
if (filePath.match(/\.ts$/))
|
|
16
|
+
return 'typescript';
|
|
17
|
+
if (filePath.match(/\.py$/))
|
|
18
|
+
return 'python';
|
|
19
|
+
if (filePath.match(/\.go$/))
|
|
20
|
+
return 'go';
|
|
21
|
+
if (filePath.match(/\.rs$/))
|
|
22
|
+
return 'rust';
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
export async function testGenCommand(options) {
|
|
26
|
+
try {
|
|
27
|
+
const { filePath, output } = options;
|
|
28
|
+
// Determine language from explicit option or file extension
|
|
29
|
+
const language = options.language || detectLanguage(filePath);
|
|
30
|
+
if (!language) {
|
|
31
|
+
return {
|
|
32
|
+
success: false,
|
|
33
|
+
error: 'Unsupported file type',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// Read source file
|
|
37
|
+
const code = await fs.readFile(filePath, 'utf-8');
|
|
38
|
+
// Detect tech stack
|
|
39
|
+
const projectRoot = process.cwd();
|
|
40
|
+
const stack = await detectTechStack(projectRoot);
|
|
41
|
+
// Determine generator based on language
|
|
42
|
+
let result;
|
|
43
|
+
switch (language) {
|
|
44
|
+
case 'react': {
|
|
45
|
+
const detectedFramework = stack.frontend?.testFramework;
|
|
46
|
+
const testFramework = detectedFramework === 'jest' ? 'jest' : 'vitest';
|
|
47
|
+
result = await generateReactTest({ filePath, code, testFramework });
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case 'typescript': {
|
|
51
|
+
const detectedFramework = stack.backend?.testFramework;
|
|
52
|
+
const testFramework = detectedFramework === 'jest' ? 'jest' : 'vitest';
|
|
53
|
+
result = await generateNodeJsTest({ filePath, code, testFramework });
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'python': {
|
|
57
|
+
const testFramework = stack.backend?.testFramework === 'unittest' ? 'unittest' : 'pytest';
|
|
58
|
+
result = await generatePythonTest({ filePath, code, testFramework });
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'go': {
|
|
62
|
+
const packageName = path.basename(path.dirname(filePath));
|
|
63
|
+
result = await generateGoTest({ filePath, code, packageName });
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'rust': {
|
|
67
|
+
result = await generateRustTest({ filePath, code });
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
default:
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
error: 'Unsupported file type',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Write test file
|
|
77
|
+
const testFilePath = output || result.testFilePath;
|
|
78
|
+
await fs.writeFile(testFilePath, result.testCode, 'utf-8');
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
testFilePath,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return {
|
|
86
|
+
success: false,
|
|
87
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export async function testDetectStackCommand(options) {
|
|
92
|
+
const stack = await detectTechStack(options.projectRoot);
|
|
93
|
+
return { stack };
|
|
94
|
+
}
|
|
95
|
+
export async function testAnalyzeCoverageCommand(options) {
|
|
96
|
+
return analyzeCoverage({
|
|
97
|
+
projectRoot: options.projectRoot,
|
|
98
|
+
coverageData: options.coverageData,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
export async function testContractCommand(options) {
|
|
102
|
+
const { spec, specPath, framework, consumer, provider } = options;
|
|
103
|
+
let specData = spec;
|
|
104
|
+
if (!specData) {
|
|
105
|
+
const content = await fs.readFile(specPath, 'utf-8');
|
|
106
|
+
specData = JSON.parse(content);
|
|
107
|
+
}
|
|
108
|
+
const result = await generateContractTest({
|
|
109
|
+
spec: specData,
|
|
110
|
+
framework,
|
|
111
|
+
consumer,
|
|
112
|
+
provider,
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
success: true,
|
|
116
|
+
testCode: result.testCode,
|
|
117
|
+
testFilePath: result.testFilePath,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export async function testComplexityCommand(options) {
|
|
121
|
+
const code = await fs.readFile(options.filePath, 'utf-8');
|
|
122
|
+
return analyzeComplexity({ code, filePath: options.filePath });
|
|
123
|
+
}
|
|
124
|
+
export async function testPromptfooCommand(options) {
|
|
125
|
+
try {
|
|
126
|
+
const { generatePromptfooConfig, savePromptfooConfig } = await import('../integrations/promptfoo/config-generator.js');
|
|
127
|
+
const config = await generatePromptfooConfig({
|
|
128
|
+
promptFile: options.promptFile,
|
|
129
|
+
testCases: [],
|
|
130
|
+
provider: options.provider || 'anthropic:claude-3-5-sonnet-20241022',
|
|
131
|
+
});
|
|
132
|
+
const outputPath = options.output || './promptfoo.config.yaml';
|
|
133
|
+
await savePromptfooConfig(config, outputPath);
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
configPath: outputPath,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
return {
|
|
141
|
+
success: false,
|
|
142
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export async function testE2ECommand(options) {
|
|
147
|
+
try {
|
|
148
|
+
const { generateFromUserFlow } = await import('../generators/e2e.js');
|
|
149
|
+
const result = await generateFromUserFlow({
|
|
150
|
+
flowDescription: options.flowDescription,
|
|
151
|
+
baseUrl: options.baseUrl || 'http://localhost:3000',
|
|
152
|
+
testName: options.testName || 'User flow test',
|
|
153
|
+
});
|
|
154
|
+
const testFilePath = options.output || './tests/e2e/user-flow.spec.ts';
|
|
155
|
+
await fs.writeFile(testFilePath, result.testCode, 'utf-8');
|
|
156
|
+
return {
|
|
157
|
+
success: true,
|
|
158
|
+
testFilePath,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
return {
|
|
163
|
+
success: false,
|
|
164
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export async function testGiskardCommand(options) {
|
|
169
|
+
try {
|
|
170
|
+
const { generatePerturbationTests } = await import('../integrations/giskard/behavioral-tests.js');
|
|
171
|
+
const code = await fs.readFile(options.filePath, 'utf-8');
|
|
172
|
+
// Generate perturbation tests
|
|
173
|
+
const result = await generatePerturbationTests({
|
|
174
|
+
testCases: [
|
|
175
|
+
{ input: 'sample input', expectedOutput: 'expected' }
|
|
176
|
+
],
|
|
177
|
+
perturbations: ['typo', 'negation', 'synonym'],
|
|
178
|
+
});
|
|
179
|
+
const testFilePath = options.output || './tests/behavioral/perturbation.test.ts';
|
|
180
|
+
const testCode = `// Generated Giskard behavioral tests
|
|
181
|
+
import { describe, it, expect } from 'vitest';
|
|
182
|
+
|
|
183
|
+
describe('Behavioral Tests', () => {
|
|
184
|
+
${result.tests.map(test => `
|
|
185
|
+
it('${test.expectedBehavior}', async () => {
|
|
186
|
+
// Original: ${test.original}
|
|
187
|
+
// Perturbed (${test.perturbationType}): ${test.perturbed}
|
|
188
|
+
// TODO: Add test implementation
|
|
189
|
+
});
|
|
190
|
+
`).join('')}
|
|
191
|
+
});
|
|
192
|
+
`;
|
|
193
|
+
await fs.writeFile(testFilePath, testCode, 'utf-8');
|
|
194
|
+
return {
|
|
195
|
+
success: true,
|
|
196
|
+
testFilePath,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
return {
|
|
201
|
+
success: false,
|
|
202
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
export async function testCICDCommand(options) {
|
|
207
|
+
try {
|
|
208
|
+
const { generateGitHubActionsWorkflow } = await import('../integrations/cicd.js');
|
|
209
|
+
const workflow = await generateGitHubActionsWorkflow({
|
|
210
|
+
language: options.language || 'nodejs',
|
|
211
|
+
coverage: true,
|
|
212
|
+
artifacts: true,
|
|
213
|
+
});
|
|
214
|
+
const workflowPath = options.output || './.github/workflows/test.yml';
|
|
215
|
+
const dir = path.dirname(workflowPath);
|
|
216
|
+
await fs.mkdir(dir, { recursive: true });
|
|
217
|
+
await fs.writeFile(workflowPath, workflow, 'utf-8');
|
|
218
|
+
return {
|
|
219
|
+
success: true,
|
|
220
|
+
workflowPath,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
return {
|
|
225
|
+
success: false,
|
|
226
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
export async function testQualityCommand(options) {
|
|
231
|
+
try {
|
|
232
|
+
const { scoreTestQuality } = await import('../analyzers/quality-scorer.js');
|
|
233
|
+
const testCode = await fs.readFile(options.testFilePath, 'utf-8');
|
|
234
|
+
const score = await scoreTestQuality({
|
|
235
|
+
testCode,
|
|
236
|
+
testType: options.testType || 'unit',
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
success: true,
|
|
240
|
+
score,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
return {
|
|
245
|
+
success: false,
|
|
246
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/testing/cli/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CoverageGap } from '../analyzers/types.js';
|
|
2
|
+
export interface UltraQAOptions {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
changedFiles?: string[];
|
|
5
|
+
coverageGaps?: CoverageGap[];
|
|
6
|
+
}
|
|
7
|
+
export interface UltraQAResult {
|
|
8
|
+
filesNeedingTests: string[];
|
|
9
|
+
coverageGaps?: CoverageGap[];
|
|
10
|
+
generatedTests: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function enhanceUltraQAWithTestGen(options: UltraQAOptions): Promise<UltraQAResult>;
|
|
13
|
+
//# sourceMappingURL=ultraqa-integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ultraqa-integration.d.ts","sourceRoot":"","sources":["../../../src/testing/cli/ultraqa-integration.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAuD/F"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { analyzeCoverage, identifyGaps } from '../analyzers/coverage.js';
|
|
4
|
+
import { testGenCommand } from './commands.js';
|
|
5
|
+
export async function enhanceUltraQAWithTestGen(options) {
|
|
6
|
+
const { projectRoot, changedFiles, coverageGaps } = options;
|
|
7
|
+
const filesNeedingTests = [];
|
|
8
|
+
const generatedTests = [];
|
|
9
|
+
// If changed files provided, check which ones need tests
|
|
10
|
+
if (changedFiles) {
|
|
11
|
+
for (const file of changedFiles) {
|
|
12
|
+
const needsTest = await checkIfNeedsTest(file, projectRoot);
|
|
13
|
+
if (needsTest) {
|
|
14
|
+
filesNeedingTests.push(file);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// If coverage gaps provided, generate tests for them
|
|
19
|
+
if (coverageGaps) {
|
|
20
|
+
for (const gap of coverageGaps) {
|
|
21
|
+
try {
|
|
22
|
+
const result = await testGenCommand({
|
|
23
|
+
filePath: path.join(projectRoot, gap.file),
|
|
24
|
+
});
|
|
25
|
+
if (result.success && result.testFilePath) {
|
|
26
|
+
generatedTests.push(result.testFilePath);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(`Failed to generate test for ${gap.file}:`, error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Analyze coverage if no gaps provided
|
|
35
|
+
let gaps;
|
|
36
|
+
if (!coverageGaps) {
|
|
37
|
+
try {
|
|
38
|
+
const coverageResult = await analyzeCoverage({ projectRoot });
|
|
39
|
+
if (coverageResult.totalCoverage < 80) {
|
|
40
|
+
const gapResult = await identifyGaps({
|
|
41
|
+
projectRoot,
|
|
42
|
+
uncoveredLines: {},
|
|
43
|
+
});
|
|
44
|
+
gaps = gapResult.gaps;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// Coverage not available
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
filesNeedingTests,
|
|
53
|
+
coverageGaps: gaps,
|
|
54
|
+
generatedTests,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function checkIfNeedsTest(filePath, projectRoot) {
|
|
58
|
+
const testFilePath = filePath.replace(/\.(ts|js|tsx|jsx)$/, '.test.$1');
|
|
59
|
+
const fullTestPath = path.join(projectRoot, testFilePath);
|
|
60
|
+
try {
|
|
61
|
+
await fs.access(fullTestPath);
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=ultraqa-integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ultraqa-integration.js","sourceRoot":"","sources":["../../../src/testing/cli/ultraqa-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAe/C,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAAuB;IACrE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAE5D,MAAM,iBAAiB,GAAa,EAAE,CAAC;IACvC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,yDAAyD;IACzD,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAChC,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAC5D,IAAI,SAAS,EAAE,CAAC;gBACd,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;oBAClC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC;iBAC3C,CAAC,CAAC;gBAEH,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;oBAC1C,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,IAA+B,CAAC;IACpC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;YAC9D,IAAI,cAAc,CAAC,aAAa,GAAG,EAAE,EAAE,CAAC;gBACtC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC;oBACnC,WAAW;oBACX,cAAc,EAAE,EAAE;iBACnB,CAAC,CAAC;gBACH,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;YACxB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yBAAyB;QAC3B,CAAC;IACH,CAAC;IAED,OAAO;QACL,iBAAiB;QACjB,YAAY,EAAE,IAAI;QAClB,cAAc;KACf,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAgB,EAAE,WAAmB;IACnE,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.d.ts","sourceRoot":"","sources":["../../../src/testing/detectors/go.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CA8BpF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export async function detectGoStack(projectRoot) {
|
|
4
|
+
const stack = {};
|
|
5
|
+
try {
|
|
6
|
+
const goModPath = path.join(projectRoot, 'go.mod');
|
|
7
|
+
const goMod = await fs.readFile(goModPath, 'utf-8');
|
|
8
|
+
stack.backend = {
|
|
9
|
+
language: 'go',
|
|
10
|
+
testFramework: 'testing',
|
|
11
|
+
};
|
|
12
|
+
// Check for databases
|
|
13
|
+
const databases = [];
|
|
14
|
+
if (goMod.includes('github.com/lib/pq') || goMod.includes('github.com/jackc/pgx'))
|
|
15
|
+
databases.push('postgresql');
|
|
16
|
+
if (goMod.includes('github.com/go-sql-driver/mysql'))
|
|
17
|
+
databases.push('mysql');
|
|
18
|
+
if (goMod.includes('go.mongodb.org/mongo-driver'))
|
|
19
|
+
databases.push('mongodb');
|
|
20
|
+
if (databases.length > 0)
|
|
21
|
+
stack.databases = databases;
|
|
22
|
+
// Check for API frameworks
|
|
23
|
+
const apis = [];
|
|
24
|
+
if (goMod.includes('github.com/gin-gonic/gin') || goMod.includes('github.com/gorilla/mux'))
|
|
25
|
+
apis.push('rest');
|
|
26
|
+
if (goMod.includes('github.com/graphql-go/graphql'))
|
|
27
|
+
apis.push('graphql');
|
|
28
|
+
if (goMod.includes('google.golang.org/grpc'))
|
|
29
|
+
apis.push('grpc');
|
|
30
|
+
if (apis.length > 0)
|
|
31
|
+
stack.apis = apis;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
// go.mod not found
|
|
35
|
+
}
|
|
36
|
+
return stack;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=go.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.js","sourceRoot":"","sources":["../../../src/testing/detectors/go.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB;IACrD,MAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEpD,KAAK,CAAC,OAAO,GAAG;YACd,QAAQ,EAAE,IAAI;YACd,aAAa,EAAE,SAAS;SACzB,CAAC;QAEF,sBAAsB;QACtB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChH,IAAI,KAAK,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9E,IAAI,KAAK,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7E,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAEtD,2BAA2B;QAC3B,MAAM,IAAI,GAAoC,EAAE,CAAC;QACjD,IAAI,KAAK,CAAC,QAAQ,CAAC,0BAA0B,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9G,IAAI,KAAK,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1E,IAAI,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mBAAmB;IACrB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { detectFromPackageJson } from './package-json.js';
|
|
2
|
+
import { detectPythonStack } from './python.js';
|
|
3
|
+
import { detectGoStack } from './go.js';
|
|
4
|
+
import { detectRustStack } from './rust.js';
|
|
5
|
+
import type { TechStack } from '../types.js';
|
|
6
|
+
export declare function detectTechStack(projectRoot: string): Promise<TechStack>;
|
|
7
|
+
export { detectFromPackageJson, detectPythonStack, detectGoStack, detectRustStack };
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/detectors/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAsC7E;AAED,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { detectFromPackageJson } from './package-json.js';
|
|
4
|
+
import { detectPythonStack } from './python.js';
|
|
5
|
+
import { detectGoStack } from './go.js';
|
|
6
|
+
import { detectRustStack } from './rust.js';
|
|
7
|
+
export async function detectTechStack(projectRoot) {
|
|
8
|
+
let stack = {};
|
|
9
|
+
// Try Node.js/JS detection
|
|
10
|
+
try {
|
|
11
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
12
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
13
|
+
const packageJson = JSON.parse(content);
|
|
14
|
+
stack = await detectFromPackageJson(packageJson);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
// package.json not found
|
|
18
|
+
}
|
|
19
|
+
// Try Python detection
|
|
20
|
+
try {
|
|
21
|
+
const pythonStack = await detectPythonStack(projectRoot);
|
|
22
|
+
stack = { ...stack, ...pythonStack };
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
// requirements.txt not found
|
|
26
|
+
}
|
|
27
|
+
// Try Go detection
|
|
28
|
+
try {
|
|
29
|
+
const goStack = await detectGoStack(projectRoot);
|
|
30
|
+
stack = { ...stack, ...goStack };
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
// go.mod not found
|
|
34
|
+
}
|
|
35
|
+
// Try Rust detection
|
|
36
|
+
try {
|
|
37
|
+
const rustStack = await detectRustStack(projectRoot);
|
|
38
|
+
stack = { ...stack, ...rustStack };
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
// Cargo.toml not found
|
|
42
|
+
}
|
|
43
|
+
return stack;
|
|
44
|
+
}
|
|
45
|
+
export { detectFromPackageJson, detectPythonStack, detectGoStack, detectRustStack };
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/detectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB;IACvD,IAAI,KAAK,GAAc,EAAE,CAAC;IAE1B,2BAA2B;IAC3B,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxC,KAAK,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yBAAyB;IAC3B,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACzD,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,EAAE,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6BAA6B;IAC/B,CAAC;IAED,mBAAmB;IACnB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,CAAC;QACjD,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mBAAmB;IACrB,CAAC;IAED,qBAAqB;IACrB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;QACrD,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,SAAS,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uBAAuB;IACzB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-json.d.ts","sourceRoot":"","sources":["../../../src/testing/detectors/package-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CA6ChF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export async function detectFromPackageJson(packageJson) {
|
|
2
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
3
|
+
const stack = {};
|
|
4
|
+
// Detect frontend framework
|
|
5
|
+
if (deps.react) {
|
|
6
|
+
stack.frontend = {
|
|
7
|
+
framework: 'react',
|
|
8
|
+
testFramework: deps.vitest ? 'vitest' : deps.jest ? 'jest' : 'none',
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
else if (deps.vue) {
|
|
12
|
+
stack.frontend = {
|
|
13
|
+
framework: 'vue',
|
|
14
|
+
testFramework: deps.vitest ? 'vitest' : 'none',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
else if (deps.svelte) {
|
|
18
|
+
stack.frontend = {
|
|
19
|
+
framework: 'svelte',
|
|
20
|
+
testFramework: deps.vitest ? 'vitest' : 'none',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// Detect backend
|
|
24
|
+
if (deps.express || deps.fastify || deps.koa) {
|
|
25
|
+
stack.backend = {
|
|
26
|
+
language: 'nodejs',
|
|
27
|
+
testFramework: deps.vitest ? 'vitest' : deps.jest ? 'jest' : undefined,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// Detect databases
|
|
31
|
+
const databases = [];
|
|
32
|
+
if (deps.pg || deps.postgres)
|
|
33
|
+
databases.push('postgresql');
|
|
34
|
+
if (deps.mysql || deps.mysql2)
|
|
35
|
+
databases.push('mysql');
|
|
36
|
+
if (deps.mongodb || deps.mongoose)
|
|
37
|
+
databases.push('mongodb');
|
|
38
|
+
if (databases.length > 0)
|
|
39
|
+
stack.databases = databases;
|
|
40
|
+
// Detect API types
|
|
41
|
+
const apis = [];
|
|
42
|
+
if (deps.express || deps.fastify)
|
|
43
|
+
apis.push('rest');
|
|
44
|
+
if (deps.graphql || deps['@apollo/server'])
|
|
45
|
+
apis.push('graphql');
|
|
46
|
+
if (deps['@grpc/grpc-js'])
|
|
47
|
+
apis.push('grpc');
|
|
48
|
+
if (apis.length > 0)
|
|
49
|
+
stack.apis = apis;
|
|
50
|
+
return stack;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=package-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-json.js","sourceRoot":"","sources":["../../../src/testing/detectors/package-json.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,WAAgB;IAC1D,MAAM,IAAI,GAAG,EAAE,GAAG,WAAW,CAAC,YAAY,EAAE,GAAG,WAAW,CAAC,eAAe,EAAE,CAAC;IAC7E,MAAM,KAAK,GAAc,EAAE,CAAC;IAE5B,4BAA4B;IAC5B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,KAAK,CAAC,QAAQ,GAAG;YACf,SAAS,EAAE,OAAO;YAClB,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;SACpE,CAAC;IACJ,CAAC;SAAM,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACpB,KAAK,CAAC,QAAQ,GAAG;YACf,SAAS,EAAE,KAAK;YAChB,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM;SAC/C,CAAC;IACJ,CAAC;SAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,KAAK,CAAC,QAAQ,GAAG;YACf,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM;SAC/C,CAAC;IACJ,CAAC;IAED,iBAAiB;IACjB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7C,KAAK,CAAC,OAAO,GAAG;YACd,QAAQ,EAAE,QAAQ;YAClB,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SACvE,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,QAAQ;QAAE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM;QAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ;QAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IAEtD,mBAAmB;IACnB,MAAM,IAAI,GAAoC,EAAE,CAAC;IACjD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,eAAe,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IAEvC,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../../src/testing/detectors/python.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CA8BxF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export async function detectPythonStack(projectRoot) {
|
|
4
|
+
const stack = {};
|
|
5
|
+
try {
|
|
6
|
+
// Check for requirements.txt
|
|
7
|
+
const requirementsPath = path.join(projectRoot, 'requirements.txt');
|
|
8
|
+
const requirements = await fs.readFile(requirementsPath, 'utf-8');
|
|
9
|
+
stack.backend = {
|
|
10
|
+
language: 'python',
|
|
11
|
+
testFramework: requirements.includes('pytest') ? 'pytest' : requirements.includes('unittest') ? 'unittest' : undefined,
|
|
12
|
+
};
|
|
13
|
+
// Check for databases
|
|
14
|
+
const databases = [];
|
|
15
|
+
if (requirements.includes('psycopg2') || requirements.includes('psycopg3'))
|
|
16
|
+
databases.push('postgresql');
|
|
17
|
+
if (requirements.includes('pymysql') || requirements.includes('mysql-connector'))
|
|
18
|
+
databases.push('mysql');
|
|
19
|
+
if (requirements.includes('pymongo'))
|
|
20
|
+
databases.push('mongodb');
|
|
21
|
+
if (databases.length > 0)
|
|
22
|
+
stack.databases = databases;
|
|
23
|
+
// Check for API frameworks
|
|
24
|
+
const apis = [];
|
|
25
|
+
if (requirements.includes('flask') || requirements.includes('fastapi') || requirements.includes('django'))
|
|
26
|
+
apis.push('rest');
|
|
27
|
+
if (requirements.includes('graphene') || requirements.includes('strawberry'))
|
|
28
|
+
apis.push('graphql');
|
|
29
|
+
if (apis.length > 0)
|
|
30
|
+
stack.apis = apis;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
// requirements.txt not found
|
|
34
|
+
}
|
|
35
|
+
return stack;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=python.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.js","sourceRoot":"","sources":["../../../src/testing/detectors/python.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAAmB;IACzD,MAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,6BAA6B;QAC7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;QACpE,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAElE,KAAK,CAAC,OAAO,GAAG;YACd,QAAQ,EAAE,QAAQ;YAClB,aAAa,EAAE,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;SACvH,CAAC;QAEF,sBAAsB;QACtB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzG,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1G,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAEtD,2BAA2B;QAC3B,MAAM,IAAI,GAA2B,EAAE,CAAC;QACxC,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7H,IAAI,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACnG,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6BAA6B;IAC/B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust.d.ts","sourceRoot":"","sources":["../../../src/testing/detectors/rust.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CA+BtF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export async function detectRustStack(projectRoot) {
|
|
4
|
+
const stack = {};
|
|
5
|
+
try {
|
|
6
|
+
// Check for Cargo.toml
|
|
7
|
+
const cargoTomlPath = path.join(projectRoot, 'Cargo.toml');
|
|
8
|
+
const cargoToml = await fs.readFile(cargoTomlPath, 'utf-8');
|
|
9
|
+
stack.backend = {
|
|
10
|
+
language: 'rust',
|
|
11
|
+
testFramework: 'cargo test', // Rust's built-in testing
|
|
12
|
+
};
|
|
13
|
+
// Check for databases
|
|
14
|
+
const databases = [];
|
|
15
|
+
if (cargoToml.includes('tokio-postgres') || cargoToml.includes('sqlx'))
|
|
16
|
+
databases.push('postgresql');
|
|
17
|
+
if (cargoToml.includes('mysql_async'))
|
|
18
|
+
databases.push('mysql');
|
|
19
|
+
if (cargoToml.includes('mongodb'))
|
|
20
|
+
databases.push('mongodb');
|
|
21
|
+
if (databases.length > 0)
|
|
22
|
+
stack.databases = databases;
|
|
23
|
+
// Check for API frameworks
|
|
24
|
+
const apis = [];
|
|
25
|
+
if (cargoToml.includes('actix-web') || cargoToml.includes('rocket') || cargoToml.includes('axum'))
|
|
26
|
+
apis.push('rest');
|
|
27
|
+
if (cargoToml.includes('async-graphql') || cargoToml.includes('juniper'))
|
|
28
|
+
apis.push('graphql');
|
|
29
|
+
if (cargoToml.includes('tonic'))
|
|
30
|
+
apis.push('grpc');
|
|
31
|
+
if (apis.length > 0)
|
|
32
|
+
stack.apis = apis;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
// Cargo.toml not found
|
|
36
|
+
}
|
|
37
|
+
return stack;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=rust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust.js","sourceRoot":"","sources":["../../../src/testing/detectors/rust.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB;IACvD,MAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,uBAAuB;QACvB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAE5D,KAAK,CAAC,OAAO,GAAG;YACd,QAAQ,EAAE,MAAM;YAChB,aAAa,EAAE,YAAY,EAAE,0BAA0B;SACxD,CAAC;QAEF,sBAAsB;QACtB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACrG,IAAI,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAEtD,2BAA2B;QAC3B,MAAM,IAAI,GAAoC,EAAE,CAAC;QACjD,IAAI,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrH,IAAI,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/F,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uBAAuB;IACzB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|