@amit641/testpilot-ai 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/analyzer/index.ts","../src/analyzer/context.ts","../src/prompt/index.ts","../src/llm/index.ts","../src/writer/index.ts","../src/verify/runner.ts","../src/verify/fixer.ts","../src/verify/index.ts","../src/generate.ts","../src/frameworks/index.ts","../src/types.ts","../src/config/index.ts","../src/coverage/index.ts"],"names":["exports","readFileSync","extname","response","existsSync","dirname","basename","parseTestOutput","resolve","ai","writeFileSync"],"mappings":"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","file":"index.js","sourcesContent":["import * as ts from 'typescript';\nimport { readFileSync } from 'node:fs';\nimport { basename, extname } from 'node:path';\nimport type {\n AnalyzedFile,\n ExportedSymbol,\n ImportStatement,\n ParameterInfo,\n SymbolKind,\n} from '../types.js';\n\n/**\n * Analyze a source file and extract its exported symbols, imports, and structure.\n * Uses the TypeScript compiler API for accurate parsing.\n */\nexport function analyzeFile(filePath: string): AnalyzedFile {\n const sourceCode = readFileSync(filePath, 'utf-8');\n const ext = extname(filePath);\n const language = ext === '.ts' || ext === '.tsx' ? 'typescript' : 'javascript';\n\n const sourceFile = ts.createSourceFile(\n filePath,\n sourceCode,\n ts.ScriptTarget.Latest,\n true,\n ext === '.tsx' || ext === '.jsx' ? ts.ScriptKind.TSX : ts.ScriptKind.TS,\n );\n\n const exports: ExportedSymbol[] = [];\n const imports: ImportStatement[] = [];\n\n visitNode(sourceFile, sourceFile, exports, imports);\n\n const dependencies = imports\n .filter((i) => !i.isRelative)\n .map((i) => i.source);\n\n return {\n filePath,\n fileName: basename(filePath),\n language,\n sourceCode,\n exports,\n imports,\n dependencies,\n };\n}\n\nfunction visitNode(\n node: ts.Node,\n sourceFile: ts.SourceFile,\n exports: ExportedSymbol[],\n imports: ImportStatement[],\n): void {\n // Import declarations\n if (ts.isImportDeclaration(node) && node.moduleSpecifier) {\n const source = (node.moduleSpecifier as ts.StringLiteral).text;\n const specifiers: string[] = [];\n\n if (node.importClause) {\n if (node.importClause.name) {\n specifiers.push(node.importClause.name.text);\n }\n if (node.importClause.namedBindings) {\n if (ts.isNamedImports(node.importClause.namedBindings)) {\n for (const el of node.importClause.namedBindings.elements) {\n specifiers.push(el.name.text);\n }\n } else if (ts.isNamespaceImport(node.importClause.namedBindings)) {\n specifiers.push(`* as ${node.importClause.namedBindings.name.text}`);\n }\n }\n }\n\n imports.push({\n source,\n specifiers,\n isRelative: source.startsWith('.'),\n });\n }\n\n // Exported function declarations\n if (ts.isFunctionDeclaration(node) && hasExportModifier(node)) {\n const name = node.name?.text ?? 'default';\n exports.push({\n name,\n kind: 'function',\n signature: getSignatureText(node, sourceFile),\n jsDoc: getJSDoc(node, sourceFile),\n isAsync: hasAsyncModifier(node),\n isDefault: hasDefaultModifier(node),\n lineNumber: getLineNumber(node, sourceFile),\n parameters: getParameters(node.parameters, sourceFile),\n returnType: node.type ? node.type.getText(sourceFile) : undefined,\n });\n }\n\n // Exported class declarations\n if (ts.isClassDeclaration(node) && hasExportModifier(node)) {\n const name = node.name?.text ?? 'default';\n exports.push({\n name,\n kind: 'class',\n signature: getClassSignature(node, sourceFile),\n jsDoc: getJSDoc(node, sourceFile),\n isAsync: false,\n isDefault: hasDefaultModifier(node),\n lineNumber: getLineNumber(node, sourceFile),\n });\n }\n\n // Exported variable declarations (including arrow functions)\n if (ts.isVariableStatement(node) && hasExportModifier(node)) {\n for (const decl of node.declarationList.declarations) {\n if (!ts.isIdentifier(decl.name)) continue;\n const name = decl.name.text;\n\n const isArrow = decl.initializer && ts.isArrowFunction(decl.initializer);\n const isFuncExpr = decl.initializer && ts.isFunctionExpression(decl.initializer);\n\n if (isArrow || isFuncExpr) {\n const func = decl.initializer as ts.ArrowFunction | ts.FunctionExpression;\n exports.push({\n name,\n kind: 'arrow-function',\n signature: getSignatureText(node, sourceFile),\n jsDoc: getJSDoc(node, sourceFile),\n isAsync: hasAsyncModifier(func),\n isDefault: false,\n lineNumber: getLineNumber(node, sourceFile),\n parameters: getParameters(func.parameters, sourceFile),\n returnType: func.type ? func.type.getText(sourceFile) : undefined,\n });\n } else {\n exports.push({\n name,\n kind: 'variable',\n signature: decl.getText(sourceFile),\n jsDoc: getJSDoc(node, sourceFile),\n isAsync: false,\n isDefault: false,\n lineNumber: getLineNumber(node, sourceFile),\n });\n }\n }\n }\n\n // Exported interfaces and types\n if (ts.isInterfaceDeclaration(node) && hasExportModifier(node)) {\n exports.push({\n name: node.name.text,\n kind: 'interface',\n signature: node.getText(sourceFile),\n isAsync: false,\n isDefault: false,\n lineNumber: getLineNumber(node, sourceFile),\n });\n }\n\n if (ts.isTypeAliasDeclaration(node) && hasExportModifier(node)) {\n exports.push({\n name: node.name.text,\n kind: 'type',\n signature: node.getText(sourceFile),\n isAsync: false,\n isDefault: false,\n lineNumber: getLineNumber(node, sourceFile),\n });\n }\n\n if (ts.isEnumDeclaration(node) && hasExportModifier(node)) {\n exports.push({\n name: node.name.text,\n kind: 'enum',\n signature: node.getText(sourceFile),\n isAsync: false,\n isDefault: false,\n lineNumber: getLineNumber(node, sourceFile),\n });\n }\n\n ts.forEachChild(node, (child) => visitNode(child, sourceFile, exports, imports));\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction hasExportModifier(node: ts.Node): boolean {\n const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;\n return modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;\n}\n\nfunction hasDefaultModifier(node: ts.Node): boolean {\n const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;\n return modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) ?? false;\n}\n\nfunction hasAsyncModifier(node: ts.Node): boolean {\n const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;\n return modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false;\n}\n\nfunction getLineNumber(node: ts.Node, sourceFile: ts.SourceFile): number {\n return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;\n}\n\nfunction getSignatureText(node: ts.Node, sourceFile: ts.SourceFile): string {\n const fullText = node.getText(sourceFile);\n const bodyStart = fullText.indexOf('{');\n if (bodyStart === -1) return fullText;\n return fullText.slice(0, bodyStart).trim();\n}\n\nfunction getClassSignature(node: ts.ClassDeclaration, sourceFile: ts.SourceFile): string {\n const lines = node.getText(sourceFile).split('\\n');\n const sigLines: string[] = [];\n for (const line of lines) {\n sigLines.push(line);\n if (line.includes('{')) break;\n }\n let sig = sigLines.join('\\n');\n const methods = node.members\n .filter((m): m is ts.MethodDeclaration => ts.isMethodDeclaration(m))\n .map((m) => {\n const methodSig = getSignatureText(m, sourceFile);\n return ` ${methodSig}`;\n });\n\n if (methods.length > 0) {\n sig += '\\n' + methods.join('\\n') + '\\n}';\n }\n return sig;\n}\n\nfunction getJSDoc(node: ts.Node, sourceFile: ts.SourceFile): string | undefined {\n const fullText = sourceFile.getFullText();\n const ranges = ts.getLeadingCommentRanges(fullText, node.getFullStart());\n if (!ranges) return undefined;\n\n for (const range of ranges) {\n const comment = fullText.slice(range.pos, range.end);\n if (comment.startsWith('/**')) {\n return comment;\n }\n }\n return undefined;\n}\n\nfunction getParameters(\n params: ts.NodeArray<ts.ParameterDeclaration>,\n sourceFile: ts.SourceFile,\n): ParameterInfo[] {\n return params.map((p) => ({\n name: p.name.getText(sourceFile),\n type: p.type ? p.type.getText(sourceFile) : undefined,\n optional: !!p.questionToken,\n defaultValue: p.initializer ? p.initializer.getText(sourceFile) : undefined,\n }));\n}\n","import { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname, extname } from 'node:path';\nimport type { AnalyzedFile } from '../types.js';\n\n/**\n * Follow relative imports from the analyzed file and collect their source code\n * as additional context for the LLM.\n */\nexport function gatherImportContext(\n analysis: AnalyzedFile,\n maxFiles: number = 5,\n maxCharsPerFile: number = 3000,\n): ImportContext[] {\n const contexts: ImportContext[] = [];\n const seen = new Set<string>();\n\n for (const imp of analysis.imports) {\n if (!imp.isRelative) continue;\n if (contexts.length >= maxFiles) break;\n\n const resolvedPath = resolveImportPath(analysis.filePath, imp.source);\n if (!resolvedPath || seen.has(resolvedPath)) continue;\n seen.add(resolvedPath);\n\n try {\n let content = readFileSync(resolvedPath, 'utf-8');\n if (content.length > maxCharsPerFile) {\n content = content.slice(0, maxCharsPerFile) + '\\n// ... (truncated)';\n }\n\n contexts.push({\n importPath: imp.source,\n resolvedPath,\n specifiers: imp.specifiers,\n content,\n });\n } catch {\n // File not readable, skip\n }\n }\n\n return contexts;\n}\n\nexport interface ImportContext {\n importPath: string;\n resolvedPath: string;\n specifiers: string[];\n content: string;\n}\n\n/**\n * Resolve a relative import to an absolute file path,\n * trying common extensions.\n */\nfunction resolveImportPath(fromFile: string, importSource: string): string | null {\n const dir = dirname(fromFile);\n const base = resolve(dir, importSource);\n const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js'];\n\n // Direct match (already has extension)\n if (existsSync(base) && extname(base)) return base;\n\n for (const ext of extensions) {\n const candidate = base + ext;\n if (existsSync(candidate)) return candidate;\n }\n\n return null;\n}\n","import type { AnalyzedFile, AutotestConfig, ExportedSymbol } from '../types.js';\nimport type { ImportContext } from '../analyzer/context.js';\n\n/**\n * Build a system prompt for the LLM that establishes the test-generation role.\n */\nexport function buildSystemPrompt(config: AutotestConfig): string {\n const framework = config.framework;\n\n const frameworkRules: Record<string, string> = {\n vitest: `- ALWAYS start with: import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';\n- Use vi.fn() for mocking, vi.spyOn for spying`,\n jest: `- Jest globals (describe, it, expect, jest) are available — do not import them\n- Use jest.fn() for mocking, jest.spyOn for spying`,\n mocha: `- ALWAYS start with: import { describe, it } from 'mocha'; import { expect } from 'chai';\n- Use sinon for mocking if needed`,\n node: `- ALWAYS start with: import { describe, it } from 'node:test'; import assert from 'node:assert/strict';\n- Use assert.strictEqual, assert.throws, assert.deepStrictEqual\n- Use t.mock for mocking`,\n };\n\n return `You are an expert test engineer. You write comprehensive, production-quality ${framework} tests.\n\nRules:\n- Use ${framework} syntax and conventions\n${frameworkRules[framework] ?? frameworkRules['vitest']}\n- Write ONLY the test code — no explanations, no markdown fences, no commentary\n- Use descriptive test names that explain the expected behavior\n- Group related tests in describe blocks\n- Test both happy paths and edge cases\n- Test error conditions and boundary values\n- Import the module under test using the EXACT relative path provided\n- Ensure all tests are independent and can run in any order\n${config.instructions ? `\\nAdditional instructions: ${config.instructions}` : ''}`;\n}\n\n/**\n * Build the user prompt with the actual source code and analysis.\n */\nexport function buildUserPrompt(\n analysis: AnalyzedFile,\n config: AutotestConfig,\n importContexts?: ImportContext[],\n): string {\n const testableExports = analysis.exports.filter(\n (e) => e.kind !== 'type' && e.kind !== 'interface',\n );\n\n if (testableExports.length === 0) {\n return buildSimplePrompt(analysis);\n }\n\n const sections: string[] = [];\n\n sections.push(`Generate comprehensive ${config.framework} tests for the following file.`);\n sections.push(`\\nFile: ${analysis.fileName}`);\n sections.push(`Language: ${analysis.language}`);\n\n // Describe what to test\n sections.push('\\n## Exported Symbols to Test\\n');\n for (const sym of testableExports) {\n sections.push(formatSymbolForPrompt(sym));\n }\n\n // Build the exact import line the LLM should use\n const importPath = `./${analysis.fileName.replace(/\\.(ts|tsx|js|jsx)$/, '')}`;\n const exportNames = testableExports.map((e) => e.isDefault ? `default as ${e.name}` : e.name);\n const importLine = `import { ${exportNames.join(', ')} } from '${importPath}';`;\n\n // Requirements\n sections.push('\\n## Requirements\\n');\n sections.push(`- Your test file MUST start with this exact import:\\n ${importLine}`);\n sections.push(`- Import each function/class by name — do NOT use side-effect imports like \\`import '${importPath}'\\``);\n\n if (config.edgeCases) {\n sections.push('- Include edge case tests for boundary values (empty strings, 0, negative numbers, large inputs)');\n sections.push('- Only test null/undefined if the source code explicitly handles them — JavaScript coerces null/undefined in arithmetic, so do NOT assume they throw');\n }\n if (config.errorHandling) {\n sections.push('- Include error handling tests ONLY for errors explicitly thrown in the source code');\n sections.push('- Read the source code carefully — only use toThrow/toThrowError for functions that actually have throw statements');\n }\n\n const asyncExports = testableExports.filter((e) => e.isAsync);\n if (asyncExports.length > 0) {\n sections.push(`- Use async/await for testing: ${asyncExports.map((e) => e.name).join(', ')}`);\n }\n\n // Full source code as context\n sections.push('\\n## Full Source Code\\n');\n sections.push('```' + analysis.language);\n sections.push(analysis.sourceCode);\n sections.push('```');\n\n // Import context — related files for better understanding\n if (importContexts && importContexts.length > 0) {\n sections.push('\\n## Related Files (for context only — do NOT test these)\\n');\n for (const ctx of importContexts) {\n sections.push(`### ${ctx.importPath} (imports: ${ctx.specifiers.join(', ')})\\n`);\n sections.push('```' + analysis.language);\n sections.push(ctx.content);\n sections.push('```\\n');\n }\n }\n\n sections.push('\\nGenerate the test file now. Output ONLY valid test code, nothing else.');\n\n return sections.join('\\n');\n}\n\nfunction buildSimplePrompt(analysis: AnalyzedFile): string {\n return `Generate comprehensive tests for the following ${analysis.language} file.\n\nFile: ${analysis.fileName}\nImport from: './${analysis.fileName.replace(/\\.(ts|tsx|js|jsx)$/, '')}'\n\n\\`\\`\\`${analysis.language}\n${analysis.sourceCode}\n\\`\\`\\`\n\nGenerate the test file now. Output ONLY valid test code, nothing else.`;\n}\n\nfunction formatSymbolForPrompt(sym: ExportedSymbol): string {\n const parts: string[] = [];\n const prefix = sym.isDefault ? '(default export) ' : '';\n\n switch (sym.kind) {\n case 'function':\n case 'arrow-function': {\n parts.push(`### ${prefix}\\`${sym.name}\\` (${sym.isAsync ? 'async ' : ''}function)`);\n if (sym.parameters?.length) {\n const params = sym.parameters\n .map((p) => ` - \\`${p.name}\\`: ${p.type ?? 'any'}${p.optional ? ' (optional)' : ''}${p.defaultValue ? ` = ${p.defaultValue}` : ''}`)\n .join('\\n');\n parts.push(`Parameters:\\n${params}`);\n }\n if (sym.returnType) {\n parts.push(`Returns: \\`${sym.returnType}\\``);\n }\n break;\n }\n case 'class': {\n parts.push(`### ${prefix}\\`${sym.name}\\` (class)`);\n parts.push(`Signature:\\n\\`\\`\\`\\n${sym.signature}\\n\\`\\`\\``);\n break;\n }\n case 'variable': {\n parts.push(`### \\`${sym.name}\\` (exported variable)`);\n break;\n }\n case 'enum': {\n parts.push(`### \\`${sym.name}\\` (enum)`);\n break;\n }\n }\n\n if (sym.jsDoc) {\n parts.push(`Documentation: ${sym.jsDoc}`);\n }\n\n return parts.join('\\n') + '\\n';\n}\n","import { ai } from 'aiclientjs';\nimport type { AutotestConfig } from '../types.js';\n\nexport interface LLMResult {\n text: string;\n tokensUsed: number;\n}\n\n/**\n * Call the LLM with the system and user prompts.\n * Streams output to stdout for real-time feedback.\n */\nexport async function generateWithLLM(\n systemPrompt: string,\n userPrompt: string,\n config: AutotestConfig,\n onChunk?: (text: string) => void,\n): Promise<LLMResult> {\n if (onChunk) {\n const stream = await ai(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n provider: config.provider,\n model: config.model,\n apiKey: config.apiKey,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n stream: true,\n },\n );\n\n let fullText = '';\n for await (const chunk of stream) {\n fullText += chunk;\n onChunk(chunk);\n }\n\n const response = await stream.response();\n return {\n text: fullText,\n tokensUsed: response.usage.totalTokens,\n };\n }\n\n const response = await ai(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n provider: config.provider,\n model: config.model,\n apiKey: config.apiKey,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n },\n );\n\n return {\n text: response.text,\n tokensUsed: response.usage.totalTokens,\n };\n}\n","import { writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { dirname, basename, join, extname } from 'node:path';\nimport type { GeneratedTest, TestCategory, AutotestConfig } from '../types.js';\n\n/**\n * Parse raw LLM output into clean test code.\n * Strips markdown fences, extracts test count, and categorizes tests.\n */\nexport function parseTestOutput(\n raw: string,\n sourceFile: string,\n config: AutotestConfig,\n): GeneratedTest {\n let code = raw.trim();\n\n // Extract code from markdown fences — handles preamble text before fences\n const fenceStart = code.indexOf('```');\n if (fenceStart !== -1) {\n code = code.slice(fenceStart);\n const firstNewline = code.indexOf('\\n');\n code = code.slice(firstNewline + 1);\n const lastFence = code.lastIndexOf('```');\n if (lastFence !== -1) {\n code = code.slice(0, lastFence);\n }\n code = code.trim();\n }\n\n // Count tests\n const itMatches = code.match(/\\bit\\s*\\(/g) || [];\n const testMatches = code.match(/\\btest\\s*\\(/g) || [];\n const testCount = itMatches.length + testMatches.length;\n\n // Categorize tests by describe blocks\n const categories = extractCategories(code);\n\n const testFile = getTestFilePath(sourceFile, config);\n\n return {\n sourceFile,\n testFile,\n testCode: code,\n testCount,\n categories,\n };\n}\n\n/**\n * Write the generated test file to disk.\n */\nexport function writeTestFile(\n test: GeneratedTest,\n config: AutotestConfig,\n): void {\n if (existsSync(test.testFile) && !config.overwrite) {\n throw new Error(\n `Test file already exists: ${test.testFile}. Use --overwrite to replace it.`,\n );\n }\n\n const dir = dirname(test.testFile);\n mkdirSync(dir, { recursive: true });\n\n writeFileSync(test.testFile, test.testCode + '\\n', 'utf-8');\n}\n\n/**\n * Determine the test file path from the source file.\n */\nexport function getTestFilePath(\n sourceFile: string,\n config: AutotestConfig,\n): string {\n const ext = extname(sourceFile);\n const base = basename(sourceFile, ext);\n const dir = config.outDir ?? dirname(sourceFile);\n\n return join(dir, `${base}.test${ext}`);\n}\n\nfunction extractCategories(code: string): TestCategory[] {\n const categories: TestCategory[] = [];\n const describeRegex = /describe\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]/g;\n\n let match;\n while ((match = describeRegex.exec(code)) !== null) {\n const name = match[1]!;\n // Count it() calls within this describe block (approximate)\n const startIdx = match.index;\n const nextDescribe = code.indexOf('describe(', startIdx + 1);\n const block = nextDescribe === -1\n ? code.slice(startIdx)\n : code.slice(startIdx, nextDescribe);\n\n const itCount = (block.match(/\\bit\\s*\\(/g) || []).length +\n (block.match(/\\btest\\s*\\(/g) || []).length;\n\n categories.push({ name, count: itCount });\n }\n\n return categories;\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { resolve, dirname } from 'node:path';\nimport type { TestFramework } from '../types.js';\n\nexport interface TestRunResult {\n passed: boolean;\n output: string;\n failures: TestFailure[];\n totalTests: number;\n passedTests: number;\n failedTests: number;\n}\n\nexport interface TestFailure {\n testName: string;\n error: string;\n expected?: string;\n received?: string;\n}\n\n/**\n * Run a test file and collect results.\n */\nexport function runTestFile(\n testFile: string,\n framework: TestFramework,\n cwd?: string,\n): TestRunResult {\n const resolvedCwd = cwd ?? findProjectRoot(testFile);\n const cmd = buildRunCommand(framework, testFile);\n\n try {\n const output = execSync(cmd, {\n cwd: resolvedCwd,\n encoding: 'utf-8',\n timeout: 60_000,\n env: { ...process.env, FORCE_COLOR: '0', NO_COLOR: '1' },\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Exit code 0 means all tests passed\n return parseTestOutput(output, framework, true);\n } catch (err: unknown) {\n const execErr = err as { stdout?: string; stderr?: string; status?: number };\n const output = (execErr.stdout ?? '') + '\\n' + (execErr.stderr ?? '');\n return parseTestOutput(output, framework, false);\n }\n}\n\nfunction buildRunCommand(framework: TestFramework, testFile: string): string {\n switch (framework) {\n case 'vitest':\n return `npx vitest run \"${testFile}\" --reporter=verbose 2>&1`;\n case 'jest':\n return `npx jest \"${testFile}\" --verbose --no-coverage 2>&1`;\n case 'mocha':\n return `npx mocha \"${testFile}\" --reporter spec 2>&1`;\n case 'node':\n return `node --test \"${testFile}\" 2>&1`;\n }\n}\n\nfunction parseTestOutput(output: string, framework: TestFramework, exitedClean: boolean): TestRunResult {\n const failures = extractFailures(output, framework);\n const counts = extractCounts(output, framework);\n\n // A test run passes if: exit code was 0, OR no failures found and some tests ran\n const passed = exitedClean || (failures.length === 0 && counts.total > 0);\n\n return {\n passed,\n output,\n failures,\n totalTests: counts.total,\n passedTests: counts.passed,\n failedTests: counts.failed,\n };\n}\n\nfunction extractFailures(output: string, _framework: TestFramework): TestFailure[] {\n const failures: TestFailure[] = [];\n\n // Universal: match FAIL lines followed by error details\n const failPattern = /(?:FAIL|×|✕|✗|✖)\\s+(.+?)(?:\\n|\\r\\n)([\\s\\S]*?)(?=(?:FAIL|×|✕|✗|✖)\\s|\\n\\s*(?:Tests|Test Files|Test Suites)|\\n\\s*$)/gi;\n let match;\n\n while ((match = failPattern.exec(output)) !== null) {\n const testName = match[1]?.trim() ?? 'unknown';\n const errorBlock = match[2]?.trim() ?? '';\n\n const expectedMatch = errorBlock.match(/Expected:?\\s*(.+)/i);\n const receivedMatch = errorBlock.match(/Received:?\\s*(.+)/i);\n\n failures.push({\n testName,\n error: errorBlock.slice(0, 500),\n expected: expectedMatch?.[1]?.trim(),\n received: receivedMatch?.[1]?.trim(),\n });\n }\n\n // Fallback: look for AssertionError / Error lines\n if (failures.length === 0 && output.includes('FAIL')) {\n const errorLines = output.match(/(?:AssertionError|Error|ReferenceError|TypeError):.*$/gm);\n if (errorLines) {\n for (const line of errorLines) {\n failures.push({\n testName: 'unknown',\n error: line.trim(),\n });\n }\n }\n }\n\n // Fallback: syntax/compilation errors\n if (failures.length === 0) {\n const syntaxErr = output.match(/(?:SyntaxError|ERROR):\\s*(.+)/);\n if (syntaxErr) {\n failures.push({\n testName: 'compilation',\n error: syntaxErr[0]!.trim(),\n });\n }\n }\n\n return failures;\n}\n\nfunction extractCounts(\n output: string,\n _framework: TestFramework,\n): { total: number; passed: number; failed: number } {\n // Vitest: \"Tests 5 failed | 12 passed (17)\" or \"Tests 1 passed (1)\"\n const vitestMatch = output.match(/Tests\\s+(?:(\\d+)\\s+failed\\s*\\|?\\s*)?(?:(\\d+)\\s+passed\\s*)?\\((\\d+)\\)/);\n if (vitestMatch) {\n const failed = parseInt(vitestMatch[1] ?? '0', 10);\n const passed = parseInt(vitestMatch[2] ?? '0', 10);\n const total = parseInt(vitestMatch[3]!, 10);\n return { total, passed, failed: failed || (total - passed) };\n }\n\n // Vitest alternate: \"N failed | M passed\" without parens\n const vitestAlt = output.match(/(\\d+)\\s+failed\\s*\\|\\s*(\\d+)\\s+passed/);\n if (vitestAlt) {\n const failed = parseInt(vitestAlt[1]!, 10);\n const passed = parseInt(vitestAlt[2]!, 10);\n return { total: failed + passed, passed, failed };\n }\n\n // Jest: \"Tests: 2 failed, 5 passed, 7 total\"\n const jestMatch = output.match(/Tests:\\s+(?:(\\d+)\\s+failed,\\s+)?(\\d+)\\s+passed,\\s+(\\d+)\\s+total/);\n if (jestMatch) {\n const failed = parseInt(jestMatch[1] ?? '0', 10);\n const passed = parseInt(jestMatch[2]!, 10);\n const total = parseInt(jestMatch[3]!, 10);\n return { total, passed, failed };\n }\n\n // \"Test Files 1 passed\" / \"Test Files 1 failed\" (vitest file-level summary)\n const filesPass = output.match(/Test Files\\s+(\\d+)\\s+passed/);\n const filesFail = output.match(/Test Files\\s+(\\d+)\\s+failed/);\n if (filesPass || filesFail) {\n // Try to get individual test counts from the output\n const passMarkers = (output.match(/✓|✔|√/g) || []).length;\n const failMarkers = (output.match(/×|✕|✗|✖|❯/g) || []).length;\n if (passMarkers + failMarkers > 0) {\n return { total: passMarkers + failMarkers, passed: passMarkers, failed: failMarkers };\n }\n }\n\n // Count from pass/fail markers\n const passCount = (output.match(/✓|✔|√/g) || []).length;\n const failCount = (output.match(/×|✕|✗|✖/g) || []).length;\n\n return {\n total: passCount + failCount,\n passed: passCount,\n failed: failCount,\n };\n}\n\nfunction findProjectRoot(fromFile: string): string {\n let dir = dirname(resolve(fromFile));\n for (let i = 0; i < 10; i++) {\n if (existsSync(resolve(dir, 'package.json'))) return dir;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return dirname(resolve(fromFile));\n}\n","import { ai } from 'aiclientjs';\nimport type { AutotestConfig } from '../types.js';\nimport type { TestFailure } from './runner.js';\n\n/**\n * Send failing tests back to the LLM for auto-fix.\n */\nexport async function fixFailingTests(\n sourceCode: string,\n testCode: string,\n failures: TestFailure[],\n config: AutotestConfig,\n onChunk?: (text: string) => void,\n): Promise<string> {\n const systemPrompt = buildFixSystemPrompt(config);\n const userPrompt = buildFixUserPrompt(sourceCode, testCode, failures);\n\n if (onChunk) {\n const stream = await ai(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n provider: config.provider,\n model: config.model,\n apiKey: config.apiKey,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n stream: true,\n },\n );\n\n let fullText = '';\n for await (const chunk of stream) {\n fullText += chunk;\n onChunk(chunk);\n }\n return fullText;\n }\n\n const response = await ai(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n provider: config.provider,\n model: config.model,\n apiKey: config.apiKey,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n },\n );\n\n return response.text;\n}\n\nfunction buildFixSystemPrompt(config: AutotestConfig): string {\n return `You are an expert test engineer fixing failing ${config.framework} tests.\n\nRules:\n- Output ONLY the complete, corrected test file — no explanations, no markdown fences\n- Fix every failing test based on the actual error messages\n- If a test expected a function to throw but it doesn't, remove or rewrite the test to match actual behavior\n- If the expected value is wrong, correct it to match the actual source code behavior\n- Do NOT remove passing tests\n- Do NOT add new tests — only fix the broken ones\n- Keep all imports and structure intact\n- Read the source code carefully to understand what each function actually does`;\n}\n\nfunction buildFixUserPrompt(\n sourceCode: string,\n testCode: string,\n failures: TestFailure[],\n): string {\n const failureDetails = failures\n .map((f, i) => {\n let detail = `${i + 1}. **${f.testName}**\\n Error: ${f.error}`;\n if (f.expected) detail += `\\n Expected: ${f.expected}`;\n if (f.received) detail += `\\n Received: ${f.received}`;\n return detail;\n })\n .join('\\n\\n');\n\n return `Fix the failing tests below. The source code is the truth — adjust the tests to match it.\n\n## Source Code (DO NOT MODIFY)\n\n\\`\\`\\`\n${sourceCode}\n\\`\\`\\`\n\n## Current Test File (FIX THIS)\n\n\\`\\`\\`\n${testCode}\n\\`\\`\\`\n\n## Failures (${failures.length})\n\n${failureDetails}\n\nOutput the COMPLETE fixed test file. Every test must pass.`;\n}\n","import { readFileSync, writeFileSync } from 'node:fs';\nimport pc from 'picocolors';\nimport { runTestFile } from './runner.js';\nimport { fixFailingTests } from './fixer.js';\nimport { parseTestOutput } from '../writer/index.js';\nimport type { AutotestConfig } from '../types.js';\n\nexport { runTestFile, type TestRunResult, type TestFailure } from './runner.js';\nexport { fixFailingTests } from './fixer.js';\n\nexport interface VerifyResult {\n passed: boolean;\n iterations: number;\n totalTests: number;\n passedTests: number;\n failedTests: number;\n finalTestCode: string;\n}\n\n/**\n * Verify & auto-fix loop:\n * 1. Run the generated tests\n * 2. If failures, send them to the LLM for fixing\n * 3. Write the fixed tests\n * 4. Repeat until all pass or maxIterations reached\n */\nexport async function verifyAndFix(\n sourceFile: string,\n testFile: string,\n config: AutotestConfig,\n options?: {\n maxIterations?: number;\n onChunk?: (text: string) => void;\n onStatus?: (msg: string) => void;\n },\n): Promise<VerifyResult> {\n const maxIterations = options?.maxIterations ?? 3;\n const log = options?.onStatus ?? (() => {});\n const sourceCode = readFileSync(sourceFile, 'utf-8');\n\n for (let iteration = 1; iteration <= maxIterations; iteration++) {\n log(`\\n${pc.cyan('▶')} Verify iteration ${iteration}/${maxIterations}...`);\n\n const result = runTestFile(testFile, config.framework);\n\n if (result.passed) {\n log(`${pc.green('✔')} All ${result.totalTests} tests pass!`);\n return {\n passed: true,\n iterations: iteration,\n totalTests: result.totalTests,\n passedTests: result.passedTests,\n failedTests: 0,\n finalTestCode: readFileSync(testFile, 'utf-8'),\n };\n }\n\n log(\n `${pc.yellow('⚠')} ${result.failedTests}/${result.totalTests} tests failed` +\n (iteration < maxIterations ? ' — sending to LLM for auto-fix...' : ''),\n );\n\n if (iteration >= maxIterations) {\n return {\n passed: false,\n iterations: iteration,\n totalTests: result.totalTests,\n passedTests: result.passedTests,\n failedTests: result.failedTests,\n finalTestCode: readFileSync(testFile, 'utf-8'),\n };\n }\n\n const currentTestCode = readFileSync(testFile, 'utf-8');\n\n if (options?.onChunk) options.onChunk('\\n');\n const fixedRaw = await fixFailingTests(\n sourceCode,\n currentTestCode,\n result.failures,\n config,\n options?.onChunk,\n );\n if (options?.onChunk) options.onChunk('\\n');\n\n const parsed = parseTestOutput(fixedRaw, sourceFile, config);\n writeFileSync(testFile, parsed.testCode + '\\n', 'utf-8');\n log(`${pc.dim(' Wrote fixed tests to')} ${testFile}`);\n }\n\n // Should not reach here\n return {\n passed: false,\n iterations: maxIterations,\n totalTests: 0,\n passedTests: 0,\n failedTests: 0,\n finalTestCode: readFileSync(testFile, 'utf-8'),\n };\n}\n","import { analyzeFile } from './analyzer/index.js';\nimport { gatherImportContext } from './analyzer/context.js';\nimport { buildSystemPrompt, buildUserPrompt } from './prompt/index.js';\nimport { generateWithLLM } from './llm/index.js';\nimport { parseTestOutput, writeTestFile } from './writer/index.js';\nimport { verifyAndFix } from './verify/index.js';\nimport type { AutotestConfig, AutotestResult } from './types.js';\n\n/**\n * Main orchestrator: analyze → prompt → generate → write → (verify → fix).\n */\nexport async function generateTests(\n sourceFile: string,\n config: AutotestConfig,\n options?: {\n onChunk?: (text: string) => void;\n onStatus?: (msg: string) => void;\n dryRun?: boolean;\n verify?: boolean;\n maxFixIterations?: number;\n },\n): Promise<AutotestResult> {\n const start = Date.now();\n\n // 1. Analyze\n const analysis = analyzeFile(sourceFile);\n\n // 2. Gather import context\n const importContexts = gatherImportContext(analysis);\n\n // 3. Build prompts\n const systemPrompt = buildSystemPrompt(config);\n const userPrompt = buildUserPrompt(analysis, config, importContexts);\n\n // 4. Generate via LLM\n const llmResult = await generateWithLLM(\n systemPrompt,\n userPrompt,\n config,\n options?.onChunk,\n );\n\n // 5. Parse & write\n const generatedTest = parseTestOutput(llmResult.text, sourceFile, config);\n\n if (!options?.dryRun) {\n writeTestFile(generatedTest, config);\n }\n\n const result: AutotestResult = {\n sourceFile: generatedTest.sourceFile,\n testFile: generatedTest.testFile,\n testCount: generatedTest.testCount,\n categories: generatedTest.categories,\n duration: Date.now() - start,\n tokensUsed: llmResult.tokensUsed,\n };\n\n // 6. Verify & auto-fix if requested\n if (options?.verify && !options?.dryRun) {\n const verifyResult = await verifyAndFix(\n sourceFile,\n generatedTest.testFile,\n config,\n {\n maxIterations: options.maxFixIterations ?? 3,\n onChunk: options.onChunk,\n onStatus: options.onStatus,\n },\n );\n\n result.verified = verifyResult.passed;\n result.verifyIterations = verifyResult.iterations;\n result.testCount = verifyResult.totalTests;\n result.duration = Date.now() - start;\n }\n\n return result;\n}\n","import type { TestFramework } from '../types.js';\n\nexport interface FrameworkInfo {\n name: TestFramework;\n imports: string;\n runCommand: string;\n filePattern: string;\n coverageCommand: string;\n}\n\nconst FRAMEWORKS: Record<TestFramework, FrameworkInfo> = {\n vitest: {\n name: 'vitest',\n imports: \"import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';\",\n runCommand: 'npx vitest run',\n filePattern: '**/*.test.{ts,tsx,js,jsx}',\n coverageCommand: 'npx vitest run --coverage --reporter=lcov',\n },\n jest: {\n name: 'jest',\n imports: '// Jest globals available',\n runCommand: 'npx jest',\n filePattern: '**/*.test.{ts,tsx,js,jsx}',\n coverageCommand: 'npx jest --coverage --coverageReporters=lcov',\n },\n mocha: {\n name: 'mocha',\n imports: \"import { describe, it, before, after, beforeEach, afterEach } from 'mocha';\\nimport { expect } from 'chai';\",\n runCommand: 'npx mocha',\n filePattern: '**/*.test.{ts,tsx,js,jsx}',\n coverageCommand: 'npx c8 mocha',\n },\n node: {\n name: 'node',\n imports: \"import { describe, it, before, after, beforeEach, afterEach } from 'node:test';\\nimport assert from 'node:assert/strict';\",\n runCommand: 'node --test',\n filePattern: '**/*.test.{ts,tsx,js,jsx}',\n coverageCommand: 'node --test --experimental-test-coverage',\n },\n};\n\nexport function getFrameworkInfo(framework: TestFramework): FrameworkInfo {\n return FRAMEWORKS[framework];\n}\n\n/**\n * Detect which test framework the project uses by checking package.json.\n */\nexport function detectFramework(packageJson: Record<string, unknown>): TestFramework {\n const deps = {\n ...(packageJson['devDependencies'] as Record<string, string> | undefined),\n ...(packageJson['dependencies'] as Record<string, string> | undefined),\n };\n\n if (deps['vitest']) return 'vitest';\n if (deps['jest'] || deps['@jest/core']) return 'jest';\n if (deps['mocha']) return 'mocha';\n\n // Check scripts\n const scripts = packageJson['scripts'] as Record<string, string> | undefined;\n if (scripts) {\n const testScript = scripts['test'] ?? '';\n if (testScript.includes('vitest')) return 'vitest';\n if (testScript.includes('jest')) return 'jest';\n if (testScript.includes('mocha')) return 'mocha';\n if (testScript.includes('node --test')) return 'node';\n }\n\n return 'vitest';\n}\n","// ---------------------------------------------------------------------------\n// Configuration\n// ---------------------------------------------------------------------------\n\nexport interface AutotestConfig {\n /** LLM provider: 'openai' | 'anthropic' | 'google' | 'ollama' */\n provider: string;\n /** Model to use, e.g. 'gpt-4o', 'claude-sonnet-4-20250514' */\n model?: string;\n /** API key (or use env var) */\n apiKey?: string;\n /** Test framework: 'vitest' | 'jest' | 'mocha' | 'node' */\n framework: TestFramework;\n /** Output directory for test files (default: same dir as source) */\n outDir?: string;\n /** Overwrite existing test files */\n overwrite: boolean;\n /** Include edge case tests */\n edgeCases: boolean;\n /** Include error handling tests */\n errorHandling: boolean;\n /** Additional context/instructions for the LLM */\n instructions?: string;\n /** Max tokens for LLM response */\n maxTokens: number;\n /** Temperature for LLM */\n temperature: number;\n}\n\nexport type TestFramework = 'vitest' | 'jest' | 'mocha' | 'node';\n\nexport const DEFAULT_CONFIG: AutotestConfig = {\n provider: 'openai',\n framework: 'vitest',\n overwrite: false,\n edgeCases: true,\n errorHandling: true,\n maxTokens: 4096,\n temperature: 0.2,\n};\n\n// ---------------------------------------------------------------------------\n// Code Analysis\n// ---------------------------------------------------------------------------\n\nexport interface AnalyzedFile {\n filePath: string;\n fileName: string;\n language: 'typescript' | 'javascript';\n sourceCode: string;\n exports: ExportedSymbol[];\n imports: ImportStatement[];\n dependencies: string[];\n}\n\nexport interface ExportedSymbol {\n name: string;\n kind: SymbolKind;\n signature: string;\n jsDoc?: string;\n isAsync: boolean;\n isDefault: boolean;\n lineNumber: number;\n parameters?: ParameterInfo[];\n returnType?: string;\n}\n\nexport type SymbolKind =\n | 'function'\n | 'class'\n | 'variable'\n | 'type'\n | 'interface'\n | 'enum'\n | 'arrow-function';\n\nexport interface ParameterInfo {\n name: string;\n type?: string;\n optional: boolean;\n defaultValue?: string;\n}\n\nexport interface ImportStatement {\n source: string;\n specifiers: string[];\n isRelative: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Test Generation\n// ---------------------------------------------------------------------------\n\nexport interface GeneratedTest {\n sourceFile: string;\n testFile: string;\n testCode: string;\n testCount: number;\n categories: TestCategory[];\n}\n\nexport interface TestCategory {\n name: string;\n count: number;\n}\n\n// ---------------------------------------------------------------------------\n// Generation Result\n// ---------------------------------------------------------------------------\n\nexport interface AutotestResult {\n sourceFile: string;\n testFile: string;\n testCount: number;\n categories: TestCategory[];\n duration: number;\n tokensUsed: number;\n verified?: boolean;\n verifyIterations?: number;\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { detectFramework } from '../frameworks/index.js';\nimport { DEFAULT_CONFIG, type AutotestConfig } from '../types.js';\n\nconst CONFIG_FILES = [\n 'autotest.config.json',\n '.autotestrc',\n '.autotestrc.json',\n];\n\n/**\n * Resolve the final config by merging: defaults < config file < CLI flags.\n */\nexport function resolveConfig(\n cliFlags: Partial<AutotestConfig>,\n cwd: string = process.cwd(),\n): AutotestConfig {\n const fileConfig = loadConfigFile(cwd);\n const pkgConfig = loadFromPackageJson(cwd);\n const detectedFramework = detectFrameworkFromProject(cwd);\n\n return {\n ...DEFAULT_CONFIG,\n ...(detectedFramework && { framework: detectedFramework }),\n ...pkgConfig,\n ...fileConfig,\n ...stripUndefined(cliFlags),\n };\n}\n\nfunction loadConfigFile(cwd: string): Partial<AutotestConfig> {\n for (const fileName of CONFIG_FILES) {\n const filePath = resolve(cwd, fileName);\n if (existsSync(filePath)) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content);\n } catch {\n // Ignore invalid config files\n }\n }\n }\n return {};\n}\n\nfunction loadFromPackageJson(cwd: string): Partial<AutotestConfig> {\n const pkgPath = resolve(cwd, 'package.json');\n if (!existsSync(pkgPath)) return {};\n\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return (pkg['autotest'] as Partial<AutotestConfig>) ?? {};\n } catch {\n return {};\n }\n}\n\nfunction detectFrameworkFromProject(cwd: string): AutotestConfig['framework'] | undefined {\n const pkgPath = resolve(cwd, 'package.json');\n if (!existsSync(pkgPath)) return undefined;\n\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n return detectFramework(pkg);\n } catch {\n return undefined;\n }\n}\n\nfunction stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {\n const result: Partial<T> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== undefined) {\n (result as Record<string, unknown>)[key] = value;\n }\n }\n return result;\n}\n","import { readFileSync, existsSync } from 'node:fs';\nimport { resolve, relative, basename } from 'node:path';\n\nexport interface CoverageData {\n files: CoverageFile[];\n totalLines: number;\n coveredLines: number;\n overallRate: number;\n}\n\nexport interface CoverageFile {\n filePath: string;\n relativePath: string;\n lineRate: number;\n branchRate: number;\n uncoveredLines: number[];\n totalLines: number;\n coveredLines: number;\n hasTests: boolean;\n}\n\n/**\n * Parse LCOV format coverage data.\n */\nexport function parseLcov(lcovPath: string, cwd: string): CoverageData {\n const content = readFileSync(lcovPath, 'utf-8');\n const files: CoverageFile[] = [];\n\n let currentFile: string | null = null;\n let linesHit = 0;\n let linesFound = 0;\n let branchesHit = 0;\n let branchesFound = 0;\n const uncoveredLines: number[] = [];\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('SF:')) {\n currentFile = trimmed.slice(3);\n linesHit = 0;\n linesFound = 0;\n branchesHit = 0;\n branchesFound = 0;\n uncoveredLines.length = 0;\n } else if (trimmed.startsWith('DA:')) {\n const parts = trimmed.slice(3).split(',');\n const lineNum = parseInt(parts[0]!, 10);\n const hits = parseInt(parts[1]!, 10);\n linesFound++;\n if (hits > 0) {\n linesHit++;\n } else {\n uncoveredLines.push(lineNum);\n }\n } else if (trimmed.startsWith('BRF:')) {\n branchesFound = parseInt(trimmed.slice(4), 10);\n } else if (trimmed.startsWith('BRH:')) {\n branchesHit = parseInt(trimmed.slice(4), 10);\n } else if (trimmed === 'end_of_record' && currentFile) {\n const filePath = resolve(currentFile);\n const relPath = relative(cwd, filePath);\n\n // Check if test file exists\n const ext = filePath.match(/\\.(ts|tsx|js|jsx)$/)?.[0] ?? '.ts';\n const base = basename(filePath, ext);\n const testFile = filePath.replace(\n new RegExp(`${base.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}${ext.replace('.', '\\\\.')}$`),\n `${base}.test${ext}`,\n );\n\n files.push({\n filePath,\n relativePath: relPath,\n lineRate: linesFound > 0 ? linesHit / linesFound : 0,\n branchRate: branchesFound > 0 ? branchesHit / branchesFound : 0,\n uncoveredLines: [...uncoveredLines],\n totalLines: linesFound,\n coveredLines: linesHit,\n hasTests: existsSync(testFile),\n });\n currentFile = null;\n }\n }\n\n const totalLines = files.reduce((s, f) => s + f.totalLines, 0);\n const coveredLines = files.reduce((s, f) => s + f.coveredLines, 0);\n\n return {\n files,\n totalLines,\n coveredLines,\n overallRate: totalLines > 0 ? coveredLines / totalLines : 0,\n };\n}\n\n/**\n * Parse Cobertura XML coverage data.\n */\nexport function parseCobertura(xmlPath: string, cwd: string): CoverageData {\n const content = readFileSync(xmlPath, 'utf-8');\n const files: CoverageFile[] = [];\n\n // Simple XML parsing for <class> elements\n const classRegex = /<class\\s[^>]*filename=\"([^\"]+)\"[^>]*line-rate=\"([^\"]+)\"[^>]*branch-rate=\"([^\"]+)\"[^>]*>/g;\n let match;\n\n while ((match = classRegex.exec(content)) !== null) {\n const filename = match[1]!;\n const lineRate = parseFloat(match[2]!);\n const branchRate = parseFloat(match[3]!);\n const filePath = resolve(cwd, filename);\n const relPath = relative(cwd, filePath);\n\n // Extract uncovered lines\n const uncoveredLines: number[] = [];\n const fileSection = content.slice(match.index, content.indexOf('</class>', match.index));\n const lineRegex = /<line\\s+number=\"(\\d+)\"\\s+hits=\"(\\d+)\"/g;\n let lineMatch;\n let total = 0;\n let covered = 0;\n\n while ((lineMatch = lineRegex.exec(fileSection)) !== null) {\n total++;\n const lineNum = parseInt(lineMatch[1]!, 10);\n const hits = parseInt(lineMatch[2]!, 10);\n if (hits > 0) {\n covered++;\n } else {\n uncoveredLines.push(lineNum);\n }\n }\n\n const ext = filePath.match(/\\.(ts|tsx|js|jsx)$/)?.[0] ?? '.ts';\n const base = basename(filePath, ext);\n const testFile = filePath.replace(\n new RegExp(`${base.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}${ext.replace('.', '\\\\.')}$`),\n `${base}.test${ext}`,\n );\n\n files.push({\n filePath,\n relativePath: relPath,\n lineRate,\n branchRate,\n uncoveredLines,\n totalLines: total || Math.round(1 / (1 - lineRate + 0.001)),\n coveredLines: covered || Math.round(lineRate * (total || 10)),\n hasTests: existsSync(testFile),\n });\n }\n\n const totalLines = files.reduce((s, f) => s + f.totalLines, 0);\n const coveredLines = files.reduce((s, f) => s + f.coveredLines, 0);\n\n return {\n files,\n totalLines,\n coveredLines,\n overallRate: totalLines > 0 ? coveredLines / totalLines : 0,\n };\n}\n\n/**\n * Auto-detect and parse coverage data from common locations.\n */\nexport function loadCoverage(cwd: string): CoverageData | null {\n const lcovPaths = [\n 'coverage/lcov.info',\n 'coverage/lcov/lcov.info',\n ];\n\n for (const p of lcovPaths) {\n const fullPath = resolve(cwd, p);\n if (existsSync(fullPath)) return parseLcov(fullPath, cwd);\n }\n\n const coberturaPaths = [\n 'coverage/cobertura-coverage.xml',\n 'coverage/cobertura.xml',\n ];\n\n for (const p of coberturaPaths) {\n const fullPath = resolve(cwd, p);\n if (existsSync(fullPath)) return parseCobertura(fullPath, cwd);\n }\n\n return null;\n}\n\n/**\n * Get files that need test generation, sorted by lowest coverage first.\n */\nexport function getUncoveredFiles(\n coverage: CoverageData,\n targetRate: number = 0.8,\n): CoverageFile[] {\n return coverage.files\n .filter((f) => f.lineRate < targetRate)\n .filter((f) => !f.relativePath.includes('.test.') && !f.relativePath.includes('.spec.'))\n .filter((f) => !f.relativePath.includes('node_modules'))\n .sort((a, b) => a.lineRate - b.lineRate);\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@amit641/testpilot-ai",
3
+ "version": "0.1.0",
4
+ "description": "AI-powered test generation that actually works. Generate, verify, and auto-fix tests with any LLM.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "testpilot": "./dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "dev": "tsup --watch",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest",
29
+ "lint": "tsc --noEmit",
30
+ "prepublishOnly": "npm run build"
31
+ },
32
+ "keywords": [
33
+ "test",
34
+ "testing",
35
+ "ai",
36
+ "llm",
37
+ "test-generation",
38
+ "vitest",
39
+ "jest",
40
+ "mocha",
41
+ "typescript",
42
+ "unit-test",
43
+ "automation",
44
+ "openai",
45
+ "anthropic",
46
+ "claude",
47
+ "gpt",
48
+ "coverage",
49
+ "self-healing",
50
+ "auto-fix",
51
+ "verify"
52
+ ],
53
+ "author": "",
54
+ "license": "MIT",
55
+ "homepage": "https://amit641.github.io/autotest/",
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "https://github.com/amit641/autotest.git"
59
+ },
60
+ "bugs": {
61
+ "url": "https://github.com/amit641/autotest/issues"
62
+ },
63
+ "engines": {
64
+ "node": ">=18.0.0"
65
+ },
66
+ "dependencies": {
67
+ "aiclientjs": "^0.1.4",
68
+ "commander": "^12.0.0",
69
+ "picocolors": "^1.0.0",
70
+ "typescript": "^5.5.0"
71
+ },
72
+ "devDependencies": {
73
+ "@types/node": "^22.0.0",
74
+ "tsup": "^8.0.0",
75
+ "vitest": "^2.0.0"
76
+ }
77
+ }