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.
Files changed (137) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +50 -0
  3. package/agents/test-engineer.md +74 -0
  4. package/bridge/cli.cjs +9335 -117
  5. package/dist/cli/index.js +201 -0
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/testing/analyzers/complexity.d.ts +18 -0
  8. package/dist/testing/analyzers/complexity.d.ts.map +1 -0
  9. package/dist/testing/analyzers/complexity.js +121 -0
  10. package/dist/testing/analyzers/complexity.js.map +1 -0
  11. package/dist/testing/analyzers/coverage.d.ts +13 -0
  12. package/dist/testing/analyzers/coverage.d.ts.map +1 -0
  13. package/dist/testing/analyzers/coverage.js +99 -0
  14. package/dist/testing/analyzers/coverage.js.map +1 -0
  15. package/dist/testing/analyzers/quality-scorer.d.ts +8 -0
  16. package/dist/testing/analyzers/quality-scorer.d.ts.map +1 -0
  17. package/dist/testing/analyzers/quality-scorer.js +128 -0
  18. package/dist/testing/analyzers/quality-scorer.js.map +1 -0
  19. package/dist/testing/analyzers/types.d.ts +56 -0
  20. package/dist/testing/analyzers/types.d.ts.map +1 -0
  21. package/dist/testing/analyzers/types.js +2 -0
  22. package/dist/testing/analyzers/types.js.map +1 -0
  23. package/dist/testing/cli/agent-integration.d.ts +20 -0
  24. package/dist/testing/cli/agent-integration.d.ts.map +1 -0
  25. package/dist/testing/cli/agent-integration.js +60 -0
  26. package/dist/testing/cli/agent-integration.js.map +1 -0
  27. package/dist/testing/cli/commands.d.ts +100 -0
  28. package/dist/testing/cli/commands.d.ts.map +1 -0
  29. package/dist/testing/cli/commands.js +250 -0
  30. package/dist/testing/cli/commands.js.map +1 -0
  31. package/dist/testing/cli/ultraqa-integration.d.ts +13 -0
  32. package/dist/testing/cli/ultraqa-integration.d.ts.map +1 -0
  33. package/dist/testing/cli/ultraqa-integration.js +68 -0
  34. package/dist/testing/cli/ultraqa-integration.js.map +1 -0
  35. package/dist/testing/detectors/go.d.ts +3 -0
  36. package/dist/testing/detectors/go.d.ts.map +1 -0
  37. package/dist/testing/detectors/go.js +38 -0
  38. package/dist/testing/detectors/go.js.map +1 -0
  39. package/dist/testing/detectors/index.d.ts +8 -0
  40. package/dist/testing/detectors/index.d.ts.map +1 -0
  41. package/dist/testing/detectors/index.js +46 -0
  42. package/dist/testing/detectors/index.js.map +1 -0
  43. package/dist/testing/detectors/package-json.d.ts +3 -0
  44. package/dist/testing/detectors/package-json.d.ts.map +1 -0
  45. package/dist/testing/detectors/package-json.js +52 -0
  46. package/dist/testing/detectors/package-json.js.map +1 -0
  47. package/dist/testing/detectors/python.d.ts +3 -0
  48. package/dist/testing/detectors/python.d.ts.map +1 -0
  49. package/dist/testing/detectors/python.js +37 -0
  50. package/dist/testing/detectors/python.js.map +1 -0
  51. package/dist/testing/detectors/rust.d.ts +3 -0
  52. package/dist/testing/detectors/rust.d.ts.map +1 -0
  53. package/dist/testing/detectors/rust.js +39 -0
  54. package/dist/testing/detectors/rust.js.map +1 -0
  55. package/dist/testing/generators/contract.d.ts +14 -0
  56. package/dist/testing/generators/contract.d.ts.map +1 -0
  57. package/dist/testing/generators/contract.js +163 -0
  58. package/dist/testing/generators/contract.js.map +1 -0
  59. package/dist/testing/generators/e2e.d.ts +34 -0
  60. package/dist/testing/generators/e2e.d.ts.map +1 -0
  61. package/dist/testing/generators/e2e.js +74 -0
  62. package/dist/testing/generators/e2e.js.map +1 -0
  63. package/dist/testing/generators/go.d.ts +12 -0
  64. package/dist/testing/generators/go.d.ts.map +1 -0
  65. package/dist/testing/generators/go.js +144 -0
  66. package/dist/testing/generators/go.js.map +1 -0
  67. package/dist/testing/generators/nodejs.d.ts +12 -0
  68. package/dist/testing/generators/nodejs.d.ts.map +1 -0
  69. package/dist/testing/generators/nodejs.js +37 -0
  70. package/dist/testing/generators/nodejs.js.map +1 -0
  71. package/dist/testing/generators/python.d.ts +12 -0
  72. package/dist/testing/generators/python.d.ts.map +1 -0
  73. package/dist/testing/generators/python.js +163 -0
  74. package/dist/testing/generators/python.js.map +1 -0
  75. package/dist/testing/generators/react.d.ts +12 -0
  76. package/dist/testing/generators/react.d.ts.map +1 -0
  77. package/dist/testing/generators/react.js +31 -0
  78. package/dist/testing/generators/react.js.map +1 -0
  79. package/dist/testing/generators/rust.d.ts +11 -0
  80. package/dist/testing/generators/rust.d.ts.map +1 -0
  81. package/dist/testing/generators/rust.js +138 -0
  82. package/dist/testing/generators/rust.js.map +1 -0
  83. package/dist/testing/index.d.ts +6 -0
  84. package/dist/testing/index.d.ts.map +1 -0
  85. package/dist/testing/index.js +11 -0
  86. package/dist/testing/index.js.map +1 -0
  87. package/dist/testing/integrations/autopilot.d.ts +42 -0
  88. package/dist/testing/integrations/autopilot.d.ts.map +1 -0
  89. package/dist/testing/integrations/autopilot.js +55 -0
  90. package/dist/testing/integrations/autopilot.js.map +1 -0
  91. package/dist/testing/integrations/cicd.d.ts +26 -0
  92. package/dist/testing/integrations/cicd.d.ts.map +1 -0
  93. package/dist/testing/integrations/cicd.js +162 -0
  94. package/dist/testing/integrations/cicd.js.map +1 -0
  95. package/dist/testing/integrations/giskard/behavioral-tests.d.ts +4 -0
  96. package/dist/testing/integrations/giskard/behavioral-tests.d.ts.map +1 -0
  97. package/dist/testing/integrations/giskard/behavioral-tests.js +66 -0
  98. package/dist/testing/integrations/giskard/behavioral-tests.js.map +1 -0
  99. package/dist/testing/integrations/giskard/types.d.ts +35 -0
  100. package/dist/testing/integrations/giskard/types.d.ts.map +1 -0
  101. package/dist/testing/integrations/giskard/types.js +2 -0
  102. package/dist/testing/integrations/giskard/types.js.map +1 -0
  103. package/dist/testing/integrations/promptfoo/config-generator.d.ts +5 -0
  104. package/dist/testing/integrations/promptfoo/config-generator.d.ts.map +1 -0
  105. package/dist/testing/integrations/promptfoo/config-generator.js +44 -0
  106. package/dist/testing/integrations/promptfoo/config-generator.js.map +1 -0
  107. package/dist/testing/integrations/promptfoo/types.d.ts +36 -0
  108. package/dist/testing/integrations/promptfoo/types.d.ts.map +1 -0
  109. package/dist/testing/integrations/promptfoo/types.js +2 -0
  110. package/dist/testing/integrations/promptfoo/types.js.map +1 -0
  111. package/dist/testing/integrations/ralph.d.ts +65 -0
  112. package/dist/testing/integrations/ralph.d.ts.map +1 -0
  113. package/dist/testing/integrations/ralph.js +69 -0
  114. package/dist/testing/integrations/ralph.js.map +1 -0
  115. package/dist/testing/performance/cache-manager.d.ts +16 -0
  116. package/dist/testing/performance/cache-manager.d.ts.map +1 -0
  117. package/dist/testing/performance/cache-manager.js +39 -0
  118. package/dist/testing/performance/cache-manager.js.map +1 -0
  119. package/dist/testing/performance/parallel-generator.d.ts +23 -0
  120. package/dist/testing/performance/parallel-generator.d.ts.map +1 -0
  121. package/dist/testing/performance/parallel-generator.js +31 -0
  122. package/dist/testing/performance/parallel-generator.js.map +1 -0
  123. package/dist/testing/types.d.ts +23 -0
  124. package/dist/testing/types.d.ts.map +1 -0
  125. package/dist/testing/types.js +2 -0
  126. package/dist/testing/types.js.map +1 -0
  127. package/docs/2026-03-06-llm-testing-system-phase1.md +0 -0
  128. package/docs/plans/2026-03-06-llm-testing-system-design.md +311 -0
  129. package/docs/plans/2026-03-06-llm-testing-system-phase1.md +1268 -0
  130. package/docs/plans/2026-03-06-llm-testing-system-phase2.md +3053 -0
  131. package/docs/plans/2026-03-06-llm-testing-system-phase3.md +1830 -0
  132. package/docs/testing/PHASE2.md +266 -0
  133. package/docs/testing/PHASE3.md +601 -0
  134. package/docs/testing/README.md +634 -0
  135. package/package.json +1 -1
  136. package/skills/test-gen/skill.md +531 -0
  137. 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":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAmB/D,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC;QAAE,OAAO,OAAO,CAAC;IACnD,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,YAAY,CAAC;IACjD,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC1D,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAErC,4DAA4D;QAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;QAE9D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,uBAAuB;aAC/B,CAAC;QACJ,CAAC;QAED,mBAAmB;QACnB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAElD,oBAAoB;QACpB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;QAEjD,wCAAwC;QACxC,IAAI,MAAM,CAAC;QACX,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,iBAAiB,GAAG,KAAK,CAAC,QAAQ,EAAE,aAAa,CAAC;gBACxD,MAAM,aAAa,GACjB,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACnD,MAAM,GAAG,MAAM,iBAAiB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBACpE,MAAM;YACR,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,iBAAiB,GAAG,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC;gBACvD,MAAM,aAAa,GACjB,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACnD,MAAM,GAAG,MAAM,kBAAkB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBACrE,MAAM;YACR,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,aAAa,GACjB,KAAK,CAAC,OAAO,EAAE,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACtE,MAAM,GAAG,MAAM,kBAAkB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBACrE,MAAM;YACR,CAAC;YACD,KAAK,IAAI,CAAC,CAAC,CAAC;gBACV,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC1D,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC/D,MAAM;YACR,CAAC;YACD,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpD,MAAM;YACR,CAAC;YACD;gBACE,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,uBAAuB;iBAC/B,CAAC;QACN,CAAC;QAED,kBAAkB;QAClB,MAAM,YAAY,GAAG,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC;QACnD,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE3D,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC;IACJ,CAAC;AACH,CAAC;AAUD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAA2B;IACtE,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACzD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,OAAsC;IACrF,OAAO,eAAe,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;AACL,CAAC;AAkBD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAA+B;IACvE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAElE,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;QACxC,IAAI,EAAE,QAAQ;QACd,SAAS;QACT,QAAQ;QACR,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY;KAClC,CAAC;AACJ,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAiC;IAC3E,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1D,OAAO,iBAAiB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;AACjE,CAAC;AAgBD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAgC;IACzE,IAAI,CAAC;QACH,MAAM,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,+CAA+C,CAAC,CAAC;QAEvH,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC;YAC3C,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,SAAS,EAAE,EAAE;YACb,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,sCAAsC;SACrE,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,IAAI,yBAAyB,CAAC;QAC/D,MAAM,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAE9C,OAAO;YACL,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,UAAU;SACvB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC;IACJ,CAAC;AACH,CAAC;AAiBD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAA0B;IAC7D,IAAI,CAAC;QACH,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAEtE,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;YACxC,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,uBAAuB;YACnD,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,gBAAgB;SAC/C,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,+BAA+B,CAAC;QACvE,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE3D,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC;IACJ,CAAC;AACH,CAAC;AAgBD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA8B;IACrE,IAAI,CAAC;QACH,MAAM,EAAE,yBAAyB,EAAE,GAAG,MAAM,MAAM,CAAC,6CAA6C,CAAC,CAAC;QAElG,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE1D,8BAA8B;QAC9B,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC;YAC7C,SAAS,EAAE;gBACT,EAAE,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE;aACtD;YACD,aAAa,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC;SAC/C,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,yCAAyC,CAAC;QACjF,MAAM,QAAQ,GAAG;;;;EAInB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,gBAAgB;mBACV,IAAI,CAAC,QAAQ;oBACZ,IAAI,CAAC,gBAAgB,MAAM,IAAI,CAAC,SAAS;;;CAG5D,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;CAEV,CAAC;QAEE,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEpD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC;IACJ,CAAC;AACH,CAAC;AAeD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA2B;IAC/D,IAAI,CAAC;QACH,MAAM,EAAE,6BAA6B,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QAElF,MAAM,QAAQ,GAAG,MAAM,6BAA6B,CAAC;YACnD,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ;YACtC,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,8BAA8B,CAAC;QACtE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEpD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC;IACJ,CAAC;AACH,CAAC;AAeD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA8B;IACrE,IAAI,CAAC;QACH,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;QAE5E,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;YACnC,QAAQ;YACR,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM;SACrC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE,IAAI;YACb,KAAK;SACN,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -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,3 @@
1
+ import type { TechStack } from '../types.js';
2
+ export declare function detectGoStack(projectRoot: string): Promise<Partial<TechStack>>;
3
+ //# sourceMappingURL=go.d.ts.map
@@ -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,3 @@
1
+ import type { TechStack } from '../types.js';
2
+ export declare function detectFromPackageJson(packageJson: any): Promise<TechStack>;
3
+ //# sourceMappingURL=package-json.d.ts.map
@@ -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,3 @@
1
+ import type { TechStack } from '../types.js';
2
+ export declare function detectPythonStack(projectRoot: string): Promise<Partial<TechStack>>;
3
+ //# sourceMappingURL=python.d.ts.map
@@ -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,3 @@
1
+ import type { TechStack } from '../types.js';
2
+ export declare function detectRustStack(projectRoot: string): Promise<Partial<TechStack>>;
3
+ //# sourceMappingURL=rust.d.ts.map
@@ -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"}