mcp-lab-agent 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -15
- package/dist/index.js +1199 -481
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"sourcesContent":["#!/usr/bin/env node\n/**\n * MCP Lab Agent - Standalone\n * MCP server genérico para QA automation em qualquer projeto.\n * Detecta automaticamente Cypress, Playwright, Jest, estrutura do projeto, etc.\n */\nimport { config } from \"dotenv\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { spawn } from \"node:child_process\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\n\nconst PROJECT_ROOT = process.cwd();\nconfig({ path: path.join(PROJECT_ROOT, \".env\") });\n\nconst server = new McpServer({\n name: \"mcp-lab-agent\",\n version: \"1.0.0\",\n});\n\n// ============================================================================\n// MODEL ROUTING - Rotear tarefas simples vs complexas (economia de custo)\n// ============================================================================\n\nconst TASK_COMPLEXITY = {\n simple: [\"generate_tests\", \"create_test_template\", \"suggest_fix\"],\n complex: [\"por_que_falhou\", \"suggest_selector_fix\", \"analyze_file_methods\"],\n};\n\nfunction resolveLLMProvider(taskType = \"simple\") {\n const GROQ_KEY = process.env.GROQ_API_KEY;\n const GEMINI_KEY = process.env.GEMINI_API_KEY;\n const OPENAI_KEY = process.env.OPENAI_API_KEY || process.env.QA_LAB_LLM_API_KEY;\n\n const simpleModel = process.env.QA_LAB_LLM_SIMPLE; // ex: gemini-1.5-flash, gpt-4o-mini\n const complexModel = process.env.QA_LAB_LLM_COMPLEX; // ex: llama-3.3-70b, gpt-4o\n\n let provider = GROQ_KEY ? \"groq\" : GEMINI_KEY ? \"gemini\" : \"openai\";\n const apiKey = GROQ_KEY || GEMINI_KEY || OPENAI_KEY;\n const baseUrl = provider === \"groq\"\n ? \"https://api.groq.com/openai/v1\"\n : provider === \"gemini\"\n ? \"https://generativelanguage.googleapis.com/v1beta\"\n : \"https://api.openai.com/v1\";\n\n let model;\n if (taskType === \"complex\") {\n model = complexModel || (provider === \"groq\" ? \"llama-3.3-70b-versatile\" : provider === \"gemini\" ? \"gemini-1.5-pro\" : \"gpt-4o\");\n } else {\n model = simpleModel || (provider === \"groq\" ? \"llama-3.1-8b-instant\" : provider === \"gemini\" ? \"gemini-1.5-flash\" : \"gpt-4o-mini\");\n }\n\n return { provider, apiKey, baseUrl, model };\n}\n\n// ============================================================================\n// PROJECT MEMORY - Cache de padrões para geração e análise\n// ============================================================================\n\nconst MEMORY_FILE = path.join(PROJECT_ROOT, \".qa-lab-memory.json\");\nconst FLOWS_CONFIG_FILE = path.join(PROJECT_ROOT, \"qa-lab-flows.json\");\n\nfunction loadProjectMemory() {\n const memory = { patterns: {}, conventions: {}, lastRun: null, selectors: [] };\n if (fs.existsSync(MEMORY_FILE)) {\n try {\n const raw = fs.readFileSync(MEMORY_FILE, \"utf8\");\n Object.assign(memory, JSON.parse(raw));\n } catch {}\n }\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flows = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n memory.flows = flows.flows || [];\n } catch {}\n }\n return memory;\n}\n\nfunction saveProjectMemory(updates) {\n try {\n let data = loadProjectMemory();\n if (updates.patterns) data.patterns = { ...data.patterns, ...updates.patterns };\n if (updates.conventions) data.conventions = { ...data.conventions, ...updates.conventions };\n if (updates.selectors) data.selectors = [...new Set([...(data.selectors || []), ...updates.selectors])].slice(-100);\n if (updates.lastRun) data.lastRun = updates.lastRun;\n if (updates.learnings) {\n data.learnings = data.learnings || [];\n data.learnings.push(...updates.learnings);\n if (data.learnings.length > 200) data.learnings = data.learnings.slice(-150);\n }\n data.updatedAt = new Date().toISOString();\n fs.writeFileSync(MEMORY_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nfunction getMemoryStats() {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const successfulFixes = learnings.filter((l) => l.success);\n const selectorFixes = learnings.filter((l) => l.type === \"selector_fix\");\n const timingFixes = learnings.filter((l) => l.type === \"timing_fix\");\n const totalTests = learnings.filter((l) => l.type === \"test_generated\").length;\n const firstAttemptSuccess = learnings.filter((l) => l.type === \"test_generated\" && l.passedFirstTime).length;\n\n return {\n totalLearnings: learnings.length,\n successfulFixes: successfulFixes.length,\n selectorFixes: selectorFixes.length,\n timingFixes: timingFixes.length,\n testsGenerated: totalTests,\n firstAttemptSuccessRate: totalTests > 0 ? Math.round((firstAttemptSuccess / totalTests) * 100) : 0,\n };\n}\n\n// ============================================================================\n// FLAKY DETECTION - Padrões típicos de teste intermitente\n// ============================================================================\n\nconst FLAKY_PATTERNS = [\n { name: \"timing\", regex: /timeout|timed out|exceeded|wait|delay|slow|race condition/i, suggestion: \"Adicione wait explícito (ex: page.waitForSelector) ou aumente o timeout.\" },\n { name: \"ordering\", regex: /order|sequenc|flaky|intermittent|sometimes|random/i, suggestion: \"Issole o teste ou use beforeAll/afterAll para estado limpo. Evite dependência de ordem entre testes.\" },\n { name: \"selector\", regex: /element not found|selector|locator|cy\\.get|page\\.locator|Unable to find/i, suggestion: \"Use seletores estáveis: data-testid, role, texto acessível. Evite classes CSS dinâmicas.\" },\n { name: \"network\", regex: /ECONNREFUSED|network|fetch|axios|request failed|404|500/i, suggestion: \"Mocke APIs ou garanta que o backend esteja rodando. Use retry ou intercept.\" },\n { name: \"shared_state\", regex: /state|cleanup|beforeEach|afterEach|isolation/i, suggestion: \"Garanta beforeEach/afterEach para resetar estado. Evite variáveis globais compartilhadas.\" },\n];\n\nfunction detectFlakyPatterns(runOutput) {\n const detected = [];\n for (const p of FLAKY_PATTERNS) {\n if (p.regex.test(runOutput)) {\n detected.push({ pattern: p.name, suggestion: p.suggestion });\n }\n }\n const confidence = detected.length > 0 ? Math.min(0.5 + detected.length * 0.2, 0.95) : 0;\n return { isLikelyFlaky: confidence > 0.5, confidence, patterns: detected };\n}\n\n// ============================================================================\n// DETECÇÃO AUTOMÁTICA DE ESTRUTURA\n// ============================================================================\n\nfunction detectProjectStructure() {\n const structure = {\n hasTests: false,\n testFrameworks: [],\n testDirs: [],\n hasBackend: false,\n backendDir: null,\n hasFrontend: false,\n frontendDir: null,\n hasMobile: false,\n packageJson: null,\n pythonRequirements: null,\n };\n\n // Detectar Node.js/JavaScript/TypeScript\n const pkgPath = path.join(PROJECT_ROOT, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n structure.packageJson = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n const deps = {\n ...structure.packageJson.dependencies,\n ...structure.packageJson.devDependencies,\n };\n\n // Frameworks E2E/UI\n if (deps.cypress) {\n structure.testFrameworks.push(\"cypress\");\n structure.hasTests = true;\n }\n if (deps[\"@playwright/test\"] || deps.playwright) {\n structure.testFrameworks.push(\"playwright\");\n structure.hasTests = true;\n }\n if (deps.webdriverio || deps[\"@wdio/cli\"]) {\n structure.testFrameworks.push(\"webdriverio\");\n structure.hasTests = true;\n }\n\n // Frameworks Unit/Integration\n if (deps.jest) {\n structure.testFrameworks.push(\"jest\");\n structure.hasTests = true;\n }\n if (deps.vitest) {\n structure.testFrameworks.push(\"vitest\");\n structure.hasTests = true;\n }\n if (deps.mocha) {\n structure.testFrameworks.push(\"mocha\");\n structure.hasTests = true;\n }\n if (deps.jasmine) {\n structure.testFrameworks.push(\"jasmine\");\n structure.hasTests = true;\n }\n\n // Frameworks Mobile\n if (deps.appium || deps[\"appium-webdriverio\"]) {\n structure.testFrameworks.push(\"appium\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n if (deps.detox) {\n structure.testFrameworks.push(\"detox\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n\n // API Testing\n if (deps.supertest) {\n structure.testFrameworks.push(\"supertest\");\n structure.hasTests = true;\n }\n if (deps[\"@pactum/pactum\"] || deps.pactum) {\n structure.testFrameworks.push(\"pactum\");\n structure.hasTests = true;\n }\n\n // Outros frameworks E2E\n if (deps.testcafe || deps[\"testcafe\"]) {\n structure.testFrameworks.push(\"testcafe\");\n structure.hasTests = true;\n }\n if (deps.nightwatch || deps[\"nightwatch\"]) {\n structure.testFrameworks.push(\"nightwatch\");\n structure.hasTests = true;\n }\n if (deps.puppeteer) {\n structure.testFrameworks.push(\"puppeteer\");\n structure.hasTests = true;\n }\n if (deps.codeceptjs || deps[\"codeceptjs\"]) {\n structure.testFrameworks.push(\"codeceptjs\");\n structure.hasTests = true;\n }\n\n // Backend detection\n if (deps.express || deps.fastify || deps[\"@nestjs/core\"] || deps.koa) {\n structure.hasBackend = true;\n }\n \n // Frontend detection\n if (deps.next || deps.react || deps.vue || deps.svelte || deps.angular) {\n structure.hasFrontend = true;\n }\n }\n\n // Detectar Python (Robot Framework, pytest, etc.)\n const requirementsPath = path.join(PROJECT_ROOT, \"requirements.txt\");\n if (fs.existsSync(requirementsPath)) {\n const requirements = fs.readFileSync(requirementsPath, \"utf8\");\n structure.pythonRequirements = requirements;\n\n if (/robotframework/i.test(requirements)) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest/i.test(requirements)) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n if (/behave/i.test(requirements)) {\n structure.testFrameworks.push(\"behave\");\n structure.hasTests = true;\n }\n if (/requests/i.test(requirements)) {\n structure.hasBackend = true;\n }\n }\n\n // Detectar pastas de teste (genérico)\n const commonTestDirs = [\n \"tests\", \"test\", \"e2e\", \"cypress\", \"playwright\", \"__tests__\",\n \"specs\", \"spec\", \"integration\", \"unit\", \"functional\", \"robot\",\n \"features\", \"scenarios\", \"mobile\", \"api\",\n // Monorepo: subprojetos por framework\n \"playwright-js\", \"puppeteer-js\", \"testcafe-js\", \"wdio-webdriver-io\",\n \"nightwatch-js\", \"codeceptjs\", \"robot-framework\", \"selenium-python\"\n ];\n for (const dir of commonTestDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {\n structure.testDirs.push(dir);\n }\n }\n\n // Monorepo: escanear subdirs de primeiro nível que parecem ter testes\n const skipDirs = [\"node_modules\", \".git\", \"dist\", \"build\", \".next\", \".venv\"];\n try {\n const rootEntries = fs.readdirSync(PROJECT_ROOT, { withFileTypes: true });\n for (const e of rootEntries) {\n if (!e.isDirectory() || skipDirs.includes(e.name)) continue;\n const subPath = path.join(PROJECT_ROOT, e.name);\n if (structure.testDirs.includes(e.name)) continue;\n // Verificar se há package.json ou tests/ dentro\n const hasPkg = fs.existsSync(path.join(subPath, \"package.json\"));\n const hasTests = fs.existsSync(path.join(subPath, \"tests\")) ||\n fs.existsSync(path.join(subPath, \"test\")) ||\n fs.existsSync(path.join(subPath, \"e2e\")) ||\n fs.existsSync(path.join(subPath, \"__tests__\")) ||\n fs.existsSync(path.join(subPath, \"specs\"));\n if (hasPkg || hasTests) {\n structure.testDirs.push(e.name);\n }\n }\n } catch {}\n\n // Monorepo: detectar frameworks em package.json de subdirs\n for (const dir of structure.testDirs) {\n const subPkg = path.join(PROJECT_ROOT, dir, \"package.json\");\n if (!fs.existsSync(subPkg)) continue;\n try {\n const sub = JSON.parse(fs.readFileSync(subPkg, \"utf8\"));\n const subDeps = { ...(sub.dependencies || {}), ...(sub.devDependencies || {}) };\n const toAdd = [];\n if (subDeps.cypress && !structure.testFrameworks.includes(\"cypress\")) toAdd.push(\"cypress\");\n if ((subDeps[\"@playwright/test\"] || subDeps.playwright) && !structure.testFrameworks.includes(\"playwright\")) toAdd.push(\"playwright\");\n if ((subDeps.webdriverio || subDeps[\"@wdio/cli\"]) && !structure.testFrameworks.includes(\"webdriverio\")) toAdd.push(\"webdriverio\");\n if (subDeps.testcafe && !structure.testFrameworks.includes(\"testcafe\")) toAdd.push(\"testcafe\");\n if (subDeps.nightwatch && !structure.testFrameworks.includes(\"nightwatch\")) toAdd.push(\"nightwatch\");\n if (subDeps.puppeteer && !structure.testFrameworks.includes(\"puppeteer\")) toAdd.push(\"puppeteer\");\n if (subDeps.codeceptjs && !structure.testFrameworks.includes(\"codeceptjs\")) toAdd.push(\"codeceptjs\");\n if (subDeps.jest && !structure.testFrameworks.includes(\"jest\")) toAdd.push(\"jest\");\n toAdd.forEach((fw) => { structure.testFrameworks.push(fw); structure.hasTests = true; });\n } catch {}\n }\n\n // Monorepo: detectar Robot/pytest em requirements.txt de subdirs\n for (const dir of structure.testDirs) {\n const reqPath = path.join(PROJECT_ROOT, dir, \"requirements.txt\");\n if (!fs.existsSync(reqPath)) continue;\n try {\n const req = fs.readFileSync(reqPath, \"utf8\");\n if (/robotframework/i.test(req) && !structure.testFrameworks.includes(\"robot\")) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest|selenium/i.test(req) && !structure.testFrameworks.includes(\"pytest\")) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n } catch {}\n }\n\n // Detectar backend\n const commonBackendDirs = [\"backend\", \"server\", \"api\", \"src\"];\n for (const dir of commonBackendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.backendDir) {\n const hasServerFile = fs.existsSync(path.join(fullPath, \"server.js\")) ||\n fs.existsSync(path.join(fullPath, \"index.js\")) ||\n fs.existsSync(path.join(fullPath, \"app.js\"));\n if (hasServerFile) {\n structure.backendDir = dir;\n }\n }\n }\n\n // Detectar frontend\n const commonFrontendDirs = [\"frontend\", \"client\", \"web\", \"app\", \"src\"];\n for (const dir of commonFrontendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.frontendDir) {\n const hasAppFile = fs.existsSync(path.join(fullPath, \"App.js\")) ||\n fs.existsSync(path.join(fullPath, \"App.tsx\")) ||\n fs.existsSync(path.join(fullPath, \"index.html\"));\n if (hasAppFile) {\n structure.frontendDir = dir;\n }\n }\n }\n\n return structure;\n}\n\n// ============================================================================\n// PADRÕES UNIVERSAIS DE ARQUIVOS DE TESTE (qualquer framework)\n// ============================================================================\n\nconst UNIVERSAL_TEST_PATTERNS = [\n /\\.(cy|spec|test)\\.(js|ts|jsx|tsx)$/i,\n /_test\\.(js|ts)$/i, // CodeceptJS\n /\\.robot$/i,\n /\\.feature$/i,\n /^(test_.*|.*_test)\\.py$/i,\n /\\.steps?\\.(js|ts|py)$/i,\n /\\.e2e\\.(js|ts)$/i,\n /\\.it\\.(js|ts)$/i,\n];\n\nfunction isTestFile(name) {\n return UNIVERSAL_TEST_PATTERNS.some((re) => re.test(name));\n}\n\nfunction collectTestFiles(structure, options = {}) {\n const { pattern, framework, maxContentFiles = 0 } = options;\n const results = [];\n\n for (const dir of structure.testDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n const walk = (p, base = \"\") => {\n if (!fs.existsSync(p)) return;\n const entries = fs.readdirSync(p, { withFileTypes: true });\n for (const e of entries) {\n const rel = base ? `${base}/${e.name}` : e.name;\n if (e.isDirectory()) {\n if (e.name === \"node_modules\" || e.name === \".git\" || e.name === \".venv\") continue;\n walk(path.join(p, e.name), rel);\n } else if (e.isFile() && isTestFile(e.name)) {\n const filePath = `${dir}/${rel}`;\n if (pattern && !filePath.toLowerCase().includes(pattern.toLowerCase())) continue;\n const inferredFw = inferFrameworkFromFile(e.name, structure, filePath);\n if (framework && framework !== \"all\" && inferredFw !== framework && !matchesFramework(inferredFw, framework)) continue;\n const entry = { path: filePath, inferredFramework: inferredFw };\n if (maxContentFiles > 0 && results.length < maxContentFiles) {\n try {\n entry.content = fs.readFileSync(path.join(PROJECT_ROOT, filePath), \"utf8\");\n } catch {}\n }\n results.push(entry);\n }\n }\n };\n walk(fullPath);\n }\n return results;\n}\n\nfunction inferFrameworkFromFile(name, structure = {}, filePath = \"\") {\n const pathLower = (filePath || \"\").toLowerCase().replace(/\\\\/g, \"/\");\n // Inferir pelo CAMINHO quando há múltiplos frameworks (ex: tests/cypress/, tests/selenium-python/)\n if (/[\\/]cypress[\\/\\-]/.test(pathLower)) return \"cypress\";\n if (/[\\/]playwright[\\/\\-]/.test(pathLower)) return \"playwright\";\n if (/[\\/]wdio[\\/\\-]|[\\/]webdriver[\\/\\-]/.test(pathLower)) return \"webdriverio\";\n if (/[\\/]appium[\\/\\-]/.test(pathLower)) return \"appium\";\n if (/[\\/]selenium-python[\\/]|[\\/]pytest[\\/\\-]/.test(pathLower)) return \"pytest\";\n if (/[\\/]robot[\\/\\-]/.test(pathLower)) return \"robot\";\n if (/[\\/]codecept[\\/\\-]/.test(pathLower)) return \"codeceptjs\";\n if (/[\\/]nightwatch[\\/\\-]/.test(pathLower)) return \"nightwatch\";\n if (/[\\/]testcafe[\\/\\-]/.test(pathLower)) return \"testcafe\";\n if (/[\\/]puppeteer[\\/\\-]/.test(pathLower)) return \"puppeteer\";\n if (/[\\/]behave[\\/\\-]|[\\/]features[\\/]/.test(pathLower)) return \"behave\";\n // Fallback: inferir pela extensão do arquivo\n if (/\\.cy\\.(js|ts|jsx|tsx)/i.test(name)) return \"cypress\";\n if (/_test\\.(js|ts)$/i.test(name)) return \"codeceptjs\";\n if (/\\.spec\\.(js|ts|jsx|tsx)/i.test(name)) {\n if (structure?.testFrameworks?.includes(\"webdriverio\")) return \"webdriverio\";\n if (structure?.testFrameworks?.includes(\"appium\")) return \"appium\";\n return \"playwright\";\n }\n if (/\\.test\\.(js|ts|jsx|tsx)/i.test(name)) return structure?.testFrameworks?.includes(\"vitest\") ? \"vitest\" : \"jest\";\n if (/\\.robot$/i.test(name)) return \"robot\";\n if (/\\.feature$/i.test(name)) return \"behave\";\n if (/\\.(py|steps?\\.py)$/i.test(name) || /^(test_.*|.*_test)\\.py$/i.test(name)) return \"pytest\";\n if (/\\.e2e\\.(js|ts)/i.test(name)) return \"playwright\";\n return \"unknown\";\n}\n\nfunction matchesFramework(inferred, requested) {\n const aliases = { spec: [\"playwright\", \"webdriverio\", \"appium\"] };\n if (inferred === requested) return true;\n return aliases[inferred]?.includes(requested);\n}\n\nfunction getFrameworkCwd(structure, preferredDirs) {\n for (const dir of preferredDirs) {\n if (structure.testDirs.includes(dir)) {\n return path.join(PROJECT_ROOT, dir);\n }\n }\n const fallback = structure.testDirs[0];\n return fallback ? path.join(PROJECT_ROOT, fallback) : PROJECT_ROOT;\n}\n\n// ============================================================================\n// MÉTRICAS DE NEGÓCIO - Helpers (FLOWS_CONFIG_FILE definido acima)\n// ============================================================================\n\nconst METRICS_FILE = path.join(PROJECT_ROOT, \".qa-lab-metrics.json\");\n\nfunction parseTestRunResult(runOutput, exitCode) {\n let passed = 0;\n let failed = 0;\n const jestMatch = runOutput.match(/Tests:\\s+(\\d+)\\s+passed(?:,\\s*(\\d+)\\s+failed)?/);\n if (jestMatch) {\n passed = parseInt(jestMatch[1], 10);\n failed = jestMatch[2] ? parseInt(jestMatch[2], 10) : 0;\n }\n const cypressPass = runOutput.match(/(\\d+)\\s+passing/);\n const cypressFail = runOutput.match(/(\\d+)\\s+failing/);\n if (cypressPass) passed = parseInt(cypressPass[1], 10);\n if (cypressFail) failed = parseInt(cypressFail[1], 10);\n const pwPass = runOutput.match(/(\\d+)\\s+passed/);\n const pwFail = runOutput.match(/(\\d+)\\s+failed/);\n if (pwPass) passed = parseInt(pwPass[1], 10);\n if (pwFail) failed = parseInt(pwFail[1], 10);\n if (passed === 0 && failed === 0) {\n if (exitCode === 0) passed = 1;\n else failed = 1;\n }\n return { passed, failed };\n}\n\nfunction appendMetricsEvent(event) {\n try {\n let data = { events: [], lastUpdated: new Date().toISOString() };\n if (fs.existsSync(METRICS_FILE)) {\n const raw = fs.readFileSync(METRICS_FILE, \"utf8\");\n try {\n data = JSON.parse(raw);\n } catch {}\n }\n data.events = data.events || [];\n data.events.push({ ...event, timestamp: event.timestamp || new Date().toISOString() });\n data.lastUpdated = new Date().toISOString();\n if (data.events.length > 500) data.events = data.events.slice(-400);\n fs.writeFileSync(METRICS_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nfunction extractFailuresFromOutput(runOutput) {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion|timeout|element not found|selector/i.test(line)) {\n failures.push({\n test: lines[Math.max(0, i - 1)]?.trim() || \"unknown\",\n message: line.trim().slice(0, 500),\n });\n }\n }\n return failures.slice(0, 20);\n}\n\n// ============================================================================\n// FERRAMENTAS GENÉRICAS\n// ============================================================================\n\nserver.registerTool(\n \"read_file\",\n {\n title: \"Ler qualquer arquivo\",\n description: \"Lê o conteúdo de QUALQUER arquivo do projeto por caminho. Use para specs, page objects, componentes, código fonte - qualquer formato.\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho relativo ao projeto (ex: cypress/e2e/login.cy.js, src/pages/Login.tsx, tests/login.robot).\"),\n encoding: z.enum([\"utf8\", \"utf-8\"]).optional().describe(\"Encoding. Default: utf8\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n content: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath, encoding = \"utf8\" }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Use um caminho de arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n try {\n const content = fs.readFileSync(fullPath, encoding);\n return {\n content: [{ type: \"text\", text: content }],\n structuredContent: { ok: true, content },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"detect_project\",\n {\n title: \"Detectar estrutura do projeto\",\n description: \"Analisa o projeto e identifica frameworks de teste, pastas, backend, frontend.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n ok: z.boolean(),\n structure: z.object({\n hasTests: z.boolean(),\n testFrameworks: z.array(z.string()),\n testDirs: z.array(z.string()),\n hasBackend: z.boolean(),\n backendDir: z.string().nullable(),\n hasFrontend: z.boolean(),\n frontendDir: z.string().nullable(),\n }),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const summary = [\n `Frameworks de teste: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Pastas de teste: ${structure.testDirs.join(\", \") || \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: { ok: true, structure },\n };\n }\n);\n\n// ============================================================================\n// WEB EVAL BROWSER - Modo browser (screenshots, network, console) via Playwright\n// ============================================================================\n\nserver.registerTool(\n \"web_eval_browser\",\n {\n title: \"Avaliar app no browser (screenshots, network, console)\",\n description: \"[Agente especializado: Browser] Abre a URL no navegador, captura screenshot, erros de console e requisições de rede. Inspirado em web-eval-agent. Requer: npm install playwright\",\n inputSchema: z.object({\n url: z.string().describe(\"URL para avaliar (ex: http://localhost:3000, https://exemplo.com).\"),\n screenshotPath: z.string().optional().describe(\"Caminho para salvar screenshot. Default: .qa-lab-screenshot.png\"),\n captureNetwork: z.boolean().optional().describe(\"Capturar requisições de rede. Default: true\"),\n captureConsole: z.boolean().optional().describe(\"Capturar logs e erros do console. Default: true\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n screenshotPath: z.string().optional(),\n consoleLogs: z.array(z.string()).optional(),\n consoleErrors: z.array(z.string()).optional(),\n networkRequests: z.array(z.object({ url: z.string(), method: z.string(), status: z.number().optional() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ url, screenshotPath, captureNetwork = true, captureConsole = true }) => {\n let playwright;\n try {\n playwright = await import(\"playwright\");\n } catch (e) {\n return {\n content: [{\n type: \"text\",\n text: \"Playwright não instalado. Rode: npm install playwright (ou npx playwright install para browsers).\",\n }],\n structuredContent: { ok: false, error: \"Playwright not installed. Run: npm install playwright\" },\n };\n }\n\n const outPath = screenshotPath ? path.join(PROJECT_ROOT, screenshotPath.replace(/^\\//, \"\")) : path.join(PROJECT_ROOT, \".qa-lab-screenshot.png\");\n const consoleLogs = [];\n const consoleErrors = [];\n const networkRequests = [];\n\n try {\n const browser = await playwright.chromium.launch({ headless: true });\n const context = await browser.newContext();\n const page = await context.newPage();\n\n if (captureConsole) {\n page.on(\"console\", (msg) => {\n const text = msg.text();\n if (msg.type() === \"error\") consoleErrors.push(text);\n else consoleLogs.push(`[${msg.type()}] ${text}`);\n });\n }\n\n if (captureNetwork) {\n page.on(\"request\", (req) => {\n networkRequests.push({ url: req.url(), method: req.method(), status: undefined });\n });\n page.on(\"response\", (res) => {\n const req = networkRequests.find((r) => r.url === res.request().url());\n if (req) req.status = res.status();\n });\n }\n\n await page.goto(url, { waitUntil: \"networkidle\", timeout: 30000 });\n await page.screenshot({ path: outPath, fullPage: false });\n\n await browser.close();\n\n const relPath = path.relative(PROJECT_ROOT, outPath);\n let summary = `Screenshot salvo: ${relPath}`;\n if (consoleErrors.length) summary += `\\n\\n⚠️ ${consoleErrors.length} erro(s) no console:\\n${consoleErrors.slice(0, 5).join(\"\\n\")}`;\n if (networkRequests.length) summary += `\\n\\nRequisições: ${networkRequests.length}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n screenshotPath: relPath,\n consoleLogs: captureConsole ? consoleLogs.slice(0, 50) : undefined,\n consoleErrors: captureConsole && consoleErrors.length ? consoleErrors : undefined,\n networkRequests: captureNetwork ? networkRequests.slice(0, 30) : undefined,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// QA ROUTE TASK - Agentes especializados (roteamento de tarefas)\n// ============================================================================\n\nconst QA_AGENTS = {\n autonomous: { tools: [\"qa_auto\"], desc: \"Modo autônomo: gera, roda, corrige e aprende (loop completo)\" },\n detection: { tools: [\"detect_project\", \"read_project\", \"list_test_files\"], desc: \"Detecção de estrutura, frameworks e arquivos\" },\n execution: { tools: [\"run_tests\", \"watch_tests\", \"get_test_coverage\"], desc: \"Execução de testes e cobertura\" },\n generation: { tools: [\"generate_tests\", \"write_test\", \"create_test_template\"], desc: \"Geração de testes com LLM\" },\n analysis: { tools: [\"analyze_failures\", \"por_que_falhou\", \"suggest_fix\", \"suggest_selector_fix\"], desc: \"Análise de falhas e sugestões\" },\n browser: { tools: [\"web_eval_browser\"], desc: \"Avaliação em browser real (screenshots, network, console)\" },\n reporting: { tools: [\"create_bug_report\", \"get_business_metrics\"], desc: \"Relatórios e métricas\" },\n learning: { tools: [\"qa_learning_stats\"], desc: \"Estatísticas de aprendizado e evolução\" },\n maintenance: { tools: [\"run_linter\", \"install_dependencies\", \"analyze_file_methods\"], desc: \"Manutenção e análise de código\" },\n};\n\nserver.registerTool(\n \"qa_route_task\",\n {\n title: \"Roteador de tarefas QA (agentes especializados)\",\n description: \"Recebe uma descrição da tarefa e retorna qual agente (conjunto de ferramentas) deve ser usado. Útil para encaminhar a ferramenta certa.\",\n inputSchema: z.object({\n task: z.string().describe(\"Descrição da tarefa (ex: 'rodar os testes', 'gerar teste de login', 'analisar por que falhou').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestedAgent: z.string(),\n suggestedTools: z.array(z.string()),\n description: z.string(),\n }),\n },\n async ({ task }) => {\n const t = task.toLowerCase();\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: autonomous → qa_auto (loop completo: gera, roda, corrige, aprende)\" }], structuredContent: { ok: true, suggestedAgent: \"autonomous\", suggestedTools: QA_AGENTS.autonomous.tools, description: QA_AGENTS.autonomous.desc } };\n }\n if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: learning → qa_learning_stats\" }], structuredContent: { ok: true, suggestedAgent: \"learning\", suggestedTools: QA_AGENTS.learning.tools, description: QA_AGENTS.learning.desc } };\n }\n if (/rodar|executar|run|test|coverage|watch/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: execution → run_tests, get_test_coverage\" }], structuredContent: { ok: true, suggestedAgent: \"execution\", suggestedTools: QA_AGENTS.execution.tools, description: QA_AGENTS.execution.desc } };\n }\n if (/gerar|criar|escrever|generate|write|template/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → generate_tests, write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: QA_AGENTS.generation.tools, description: QA_AGENTS.generation.desc } };\n }\n if (/analisar|por que|falhou|suggest|correção|selector|fix/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: analysis → analyze_failures, por_que_falhou, suggest_fix\" }], structuredContent: { ok: true, suggestedAgent: \"analysis\", suggestedTools: QA_AGENTS.analysis.tools, description: QA_AGENTS.analysis.desc } };\n }\n if (/browser|screenshot|navegador|avaliar|ux|network|console/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: browser → web_eval_browser\" }], structuredContent: { ok: true, suggestedAgent: \"browser\", suggestedTools: QA_AGENTS.browser.tools, description: QA_AGENTS.browser.desc } };\n }\n if (/detectar|estrutura|listar|arquivos|framework/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: detection → detect_project, list_test_files\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n if (/relatório|bug|métricas|metrics|coverage/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: reporting → create_bug_report, get_business_metrics\" }], structuredContent: { ok: true, suggestedAgent: \"reporting\", suggestedTools: QA_AGENTS.reporting.tools, description: QA_AGENTS.reporting.desc } };\n }\n return { content: [{ type: \"text\", text: \"Agente: detection (genérico)\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n);\n\nserver.registerTool(\n \"run_tests\",\n {\n title: \"Executar testes\",\n description: \"Roda testes do projeto. Suporta: Cypress, Playwright, WebdriverIO, Jest, Vitest, Mocha, Appium, Detox, Robot Framework, pytest, e mais. Detecta automaticamente.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"supertest\", \"pactum\",\n \"testcafe\", \"nightwatch\", \"puppeteer\", \"codeceptjs\", \"npm\"\n ]).optional().describe(\"Framework específico ou 'npm' para npm test.\"),\n spec: z.string().optional().describe(\"Caminho do spec (ex: cypress/e2e/test.cy.js).\"),\n suite: z.string().optional().describe(\"Suite ou pattern (ex: e2e, api).\"),\n explainOnFailure: z.boolean().optional().describe(\"Se true, quando falhar gera automaticamente: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção. Requer API key.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n runOutput: z.string().optional(),\n }),\n },\n async ({ framework, spec, suite, explainOnFailure }) => {\n const structure = detectProjectStructure();\n \n if (!structure.hasTests) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado no projeto.\" }],\n structuredContent: {\n status: \"not_found\",\n message: \"No test framework found\",\n exitCode: 1,\n },\n };\n }\n\n let selectedFramework = framework;\n if (!selectedFramework && structure.testFrameworks.length > 0) {\n selectedFramework = structure.testFrameworks[0];\n }\n\n let cmd, args, cwd;\n\n // E2E/UI Frameworks\n if (selectedFramework === \"cypress\") {\n cmd = \"npx\";\n args = spec ? [\"cypress\", \"run\", \"--spec\", spec] : [\"cypress\", \"run\"];\n cwd = structure.testDirs.includes(\"cypress\") \n ? path.join(PROJECT_ROOT, \"cypress\")\n : structure.testDirs[0] \n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"playwright\") {\n cmd = \"npx\";\n args = spec ? [\"playwright\", \"test\", spec] : [\"playwright\", \"test\"];\n cwd = structure.testDirs.includes(\"playwright\")\n ? path.join(PROJECT_ROOT, \"playwright\")\n : structure.testDirs[0]\n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"webdriverio\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"wdio-webdriver-io\", \"specs\", \"tests\"]);\n } else if (selectedFramework === \"testcafe\") {\n cmd = \"npx\";\n args = spec ? [\"testcafe\", spec] : [\"testcafe\"];\n cwd = getFrameworkCwd(structure, [\"testcafe-js\", \"testcafe\", \"tests\"]);\n } else if (selectedFramework === \"nightwatch\") {\n cmd = \"npx\";\n args = spec ? [\"nightwatch\", \"--test\", spec] : [\"nightwatch\"];\n cwd = getFrameworkCwd(structure, [\"nightwatch-js\", \"nightwatch\", \"tests\"]);\n } else if (selectedFramework === \"puppeteer\") {\n cmd = \"npx\";\n args = spec ? [\"jest\", spec, \"--config\", \"jest.config.js\"] : [\"jest\"];\n cwd = getFrameworkCwd(structure, [\"puppeteer-js\", \"puppeteer\", \"__tests__\"]);\n } else if (selectedFramework === \"codeceptjs\") {\n cmd = \"npx\";\n args = spec ? [\"codeceptjs\", \"run\", \"--grep\", spec] : [\"codeceptjs\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"codeceptjs\", \"tests\"]);\n\n // Unit/Integration Frameworks\n } else if (selectedFramework === \"jest\") {\n cmd = \"npx\";\n args = [\"jest\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"vitest\") {\n cmd = \"npx\";\n args = [\"vitest\", \"run\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"mocha\") {\n cmd = \"npx\";\n args = spec ? [\"mocha\", spec] : [\"mocha\"];\n cwd = PROJECT_ROOT;\n \n // Mobile Frameworks\n } else if (selectedFramework === \"appium\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"detox\") {\n cmd = \"npx\";\n args = [\"detox\", \"test\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n \n // Python Frameworks\n } else if (selectedFramework === \"robot\") {\n cmd = \"robot\";\n args = spec ? [spec] : [structure.testDirs[0] || \"tests\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"pytest\") {\n cmd = \"pytest\";\n args = spec ? [spec] : [];\n cwd = PROJECT_ROOT;\n \n // API Testing\n } else if (selectedFramework === \"supertest\" || selectedFramework === \"pactum\") {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n \n // Fallback\n } else {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n }\n\n const startTime = Date.now();\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) {\n child.stdout.on(\"data\", (d) => {\n const s = d.toString();\n stdout += s;\n process.stdout.write(s);\n });\n }\n if (child.stderr) {\n child.stderr.on(\"data\", (d) => {\n const s = d.toString();\n stderr += s;\n process.stderr.write(s);\n });\n }\n\n child.on(\"close\", (code) => {\n const runOutput = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n const durationSeconds = Math.round((Date.now() - startTime) / 1000);\n if (!passed && runOutput) {\n try {\n fs.writeFileSync(path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\"), runOutput, \"utf8\");\n } catch {}\n }\n const { passed: p, failed: f } = parseTestRunResult(runOutput, code);\n appendMetricsEvent({\n type: \"test_run\",\n framework: selectedFramework,\n spec: spec || undefined,\n passed: p,\n failed: f,\n durationSeconds,\n exitCode: code ?? 1,\n failures: !passed ? extractFailuresFromOutput(runOutput) : undefined,\n });\n if (passed) saveProjectMemory({ lastRun: { spec: spec || null, framework: selectedFramework, passed: p } });\n resolve({\n content: [{ type: \"text\", text: passed ? \"Testes executados com sucesso.\" : \"Falha na execução dos testes.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Tests passed\" : \"Tests failed\",\n exitCode: code ?? 1,\n runOutput: !passed ? runOutput : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"read_project\",\n {\n title: \"Ler estrutura do projeto\",\n description: \"Lê package.json, specs existentes (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, etc) e retorna contexto. Use includeContent para trazer código de exemplos.\",\n inputSchema: z.object({\n includeContent: z.boolean().optional().describe(\"Se true, inclui conteúdo dos primeiros 3 arquivos de teste como referência. Default: false.\"),\n maxFiles: z.number().optional().describe(\"Máximo de arquivos cujo conteúdo será lido. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n packageJson: z.object({}).passthrough().optional(),\n testFiles: z.array(z.string()).optional(),\n testFilesWithContent: z.array(z.object({ path: z.string(), content: z.string() })).optional(),\n }),\n },\n async ({ includeContent = false, maxFiles = 3 } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, {\n maxContentFiles: includeContent ? maxFiles : 0,\n });\n\n const testFiles = collected.map((e) => e.path);\n const testFilesWithContent = includeContent\n ? collected.filter((e) => e.content).map((e) => ({ path: e.path, content: e.content }))\n : undefined;\n\n const summary = [\n `Frameworks: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Arquivos de teste: ${testFiles.length} (qualquer framework)`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n includeContent && testFilesWithContent?.length\n ? `Conteúdo incluído: ${testFilesWithContent.length} arquivo(s) como referência`\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n packageJson: structure.packageJson,\n testFiles: testFiles.slice(0, 100),\n testFilesWithContent,\n structure,\n },\n };\n }\n);\n\nserver.registerTool(\n \"generate_tests\",\n {\n title: \"Gerar ou traduzir testes com LLM\",\n description: \"Gera spec em QUALQUER framework. Aceita referência de outro framework: leia com read_file e passe em referenceCode. Traduz automaticamente (ex: Robot→Playwright, Cypress→WDIO).\",\n inputSchema: z.object({\n context: z.string().describe(\"Contexto do projeto (read_project) ou descrição.\"),\n request: z.string().describe(\"O que testar (ex: 'logout flow', 'teste de login') ou 'traduzir o teste abaixo'.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"robot\", \"pytest\", \"supertest\", \"behave\", \"detox\"\n ]).optional().describe(\"Framework alvo (detectado do projeto se omitido).\"),\n referenceCode: z.string().optional().describe(\"Código de referência em QUALQUER framework (Cypress, Robot, WDIO, etc). O LLM traduz/adapta para o framework alvo.\"),\n referencePaths: z.array(z.string()).optional().describe(\"Caminhos de arquivos para ler como referência. O agente lê e usa como padrão.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n specContent: z.string().optional(),\n suggestedFileName: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ context, request, framework, referenceCode, referencePaths }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0] || \"cypress\";\n\n let referenceBlock = \"\";\n if (referenceCode) referenceBlock += `\\n\\n--- CÓDIGO DE REFERÊNCIA (use como padrão, traduza/adapte para ${fw}) ---\\n${referenceCode.slice(0, 8000)}`;\n if (referencePaths?.length) {\n for (const p of referencePaths.slice(0, 5)) {\n const full = path.join(PROJECT_ROOT, p.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(full)) {\n try {\n const content = fs.readFileSync(full, \"utf8\");\n referenceBlock += `\\n\\n--- Arquivo: ${p} ---\\n${content.slice(0, 6000)}`;\n } catch {}\n }\n }\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const memory = loadProjectMemory();\n const memoryBlock = memory.flows?.length\n ? `\\n\\nFluxos do projeto (use como referência): ${memory.flows.map((f) => f.name || f.id).join(\", \")}`\n : \"\";\n const contextWithMemory = context + memoryBlock;\n\n const hasReference = Boolean(referenceBlock?.trim());\n const systemPrompt = hasReference\n ? `Você é um engenheiro de QA. TRADUZA/ADAPTE o código de referência para o framework ${fw}.\nO código de referência pode estar em QUALQUER framework (Cypress, Robot, Playwright, WDIO, Appium, pytest, etc).\n- Mantenha a MESMA lógica e fluxo de teste\n- Traduza seletores, comandos e asserções para ${fw}\n- Use Page Objects se o projeto já usa\n- Retorne SOMENTE o código, sem markdown`\n : `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\nFramework: ${fw}\nRegras:\n- Cypress: cy.request(), cy.visit(), cy.get()\n- Playwright: test(), test.describe(), page.goto(), page.locator()\n- WebdriverIO/Appium: describe(), it(), $(), browser.$\n- Jest/Vitest: describe(), test(), expect()\n- Robot: Keywords, [Tags], Steps\n- pytest: def test_*, assert, fixtures\n- Código limpo. Retorne SOMENTE o código, sem markdown`;\n\n const userPrompt = `Contexto do projeto:\n${contextWithMemory.slice(0, 5000)}\n\nGere um teste para: ${request}\nFramework alvo: ${fw}${referenceBlock}`;\n\n try {\n let specContent;\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n systemInstruction: { parts: [{ text: systemPrompt }] },\n contents: [{ parts: [{ text: userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n\n specContent = specContent.replace(/^```(?:js|javascript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 40);\n\n return {\n content: [{ type: \"text\", text: `Spec gerado (${specContent.length} chars). Use write_test para gravar.` }],\n structuredContent: {\n ok: true,\n specContent,\n suggestedFileName: fileName,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gerar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nfunction getExtensionAndBaseDir(fw, structure) {\n const extMap = {\n cypress: \".cy.js\",\n playwright: \".spec.js\",\n jest: \".test.js\",\n vitest: \".test.js\",\n mocha: \".test.js\",\n webdriverio: \".spec.js\",\n appium: \".spec.js\",\n detox: \".e2e.js\",\n robot: \".robot\",\n pytest: \"_test.py\",\n behave: \".feature\",\n supertest: \".test.js\",\n pactum: \".test.js\",\n };\n const ext = extMap[fw] || \".spec.js\";\n\n const baseMap = {\n cypress: structure.testDirs.includes(\"cypress\") ? \"cypress\" : structure.testDirs[0] || \"tests\",\n playwright: structure.testDirs.includes(\"playwright\") ? \"playwright\" : structure.testDirs[0] || \"tests\",\n webdriverio: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n appium: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n robot: structure.testDirs.includes(\"robot\") ? \"robot\" : structure.testDirs[0] || \"tests\",\n behave: structure.testDirs.includes(\"features\") ? \"features\" : structure.testDirs[0] || \"tests\",\n };\n const baseDir = path.join(PROJECT_ROOT, baseMap[fw] || structure.testDirs[0] || \"tests\");\n return { ext, baseDir };\n}\n\nserver.registerTool(\n \"write_test\",\n {\n title: \"Escrever arquivo de teste\",\n description: \"Grava spec no disco. Suporta QUALQUER framework (Cypress, Playwright, WDIO, Appium, Robot, pytest, etc.). Detecta automaticamente pasta e extensão.\",\n inputSchema: z.object({\n name: z.string().describe(\"Nome do arquivo (ex: login-test, logout_spec).\"),\n content: z.string().describe(\"Conteúdo do spec.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"vitest\", \"mocha\", \"webdriverio\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"behave\", \"supertest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n subdir: z.string().optional().describe(\"Subpasta (ex: e2e, api). Default: raiz da pasta de testes.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n path: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ name, content, framework, subdir }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado.\" }],\n structuredContent: { ok: false, error: \"No test framework\" },\n };\n }\n\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = name\n .replace(/[^a-z0-9-_]/gi, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/_+/g, \"_\")\n .replace(/\\.(cy|spec|test|robot|feature|py)\\.?(js|ts|py)?$/i, \"\")\n .replace(/^[-_]+|[-_]+$/g, \"\");\n const fileName = ext.startsWith(\"_\") ? `${safeName}${ext}` : `${safeName}${ext}`;\n\n const targetDir = subdir ? path.join(baseDir, subdir) : baseDir;\n const filePath = path.join(targetDir, fileName);\n\n try {\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n fs.writeFileSync(filePath, content, \"utf8\");\n return {\n content: [{ type: \"text\", text: `Arquivo gravado: ${filePath}` }],\n structuredContent: { ok: true, path: filePath },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gravar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_failures\",\n {\n title: \"Analisar falhas de testes\",\n description: \"Recebe output de testes e extrai falhas estruturadas.\",\n inputSchema: z.object({\n runOutput: z.string().describe(\"Output do teste (stdout/stderr).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).optional(),\n }),\n },\n async ({ runOutput }) => {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion/i.test(line)) {\n failures.push({\n test: lines[i - 1] || \"unknown\",\n message: line.trim(),\n stack: lines.slice(i, i + 5).join(\"\\n\"),\n });\n }\n }\n\n const flakyAnalysis = detectFlakyPatterns(runOutput);\n let summary = failures.length\n ? `${failures.length} falha(s) detectada(s).`\n : \"Nenhuma falha detectada.\";\n if (flakyAnalysis.isLikelyFlaky) {\n summary += `\\n\\n⚠️ Possível teste flaky (${Math.round(flakyAnalysis.confidence * 100)}% confiança). Padrões: ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}.`;\n summary += \"\\n\\nSugestões:\";\n flakyAnalysis.patterns.forEach((p) => {\n summary += `\\n• ${p.pattern}: ${p.suggestion}`;\n });\n if (flakyAnalysis.patterns.some((p) => p.pattern === \"timing\" || p.pattern === \"network\")) {\n summary += \"\\n• Considere adicionar test.retry(2) ou equivalente para retries automáticos.\";\n }\n }\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n failures: failures.length ? failures : undefined,\n flaky: flakyAnalysis.isLikelyFlaky ? { confidence: flakyAnalysis.confidence, patterns: flakyAnalysis.patterns } : undefined,\n },\n };\n }\n);\n\n// ============================================================================\n// POR QUE FALHOU? - Explicação de falhas para juniores (escalável)\n// ============================================================================\n\nfunction formatFailureExplanation(data) {\n const lines = [\n \"## O que aconteceu\",\n \"\",\n data.oQueAconteceu || \"\",\n \"\",\n \"## Por que provavelmente falhou\",\n \"\",\n ...(Array.isArray(data.porQueProvavelmenteFalhou)\n ? data.porQueProvavelmenteFalhou.map((s) => `• ${s}`)\n : [data.porQueProvavelmenteFalhou || \"\"]),\n \"\",\n \"## O que fazer agora\",\n \"\",\n ...(Array.isArray(data.oQueFazerAgora)\n ? data.oQueFazerAgora.map((s, i) => `${i + 1}. ${s}`)\n : [data.oQueFazerAgora || \"\"]),\n ];\n if (data.sugestaoCorrecao) {\n lines.push(\"\", \"## Sugestão de correção\", \"\", \"```\" + (data.framework || \"js\"), data.sugestaoCorrecao, \"```\");\n }\n if (data.conceito) {\n lines.push(\"\", \"## Conceito\", \"\", data.conceito);\n }\n return lines.filter(Boolean).join(\"\\n\");\n}\n\nasync function callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt) {\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.2, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n }\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.2,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n return data.choices?.[0]?.message?.content || \"\";\n}\n\n/** Gera explicação de falha (o que aconteceu, por que, o que fazer, sugestão). Usado por por_que_falhou e run_tests_and_explain. */\nasync function generateFailureExplanation(resolvedOutput, testFilePath = null) {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\n\n let testCode = \"\";\n if (testFilePath) {\n const normalized = testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n if (fs.existsSync(fullPath) && !fs.statSync(fullPath).isDirectory()) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return { ok: false, error: \"No API key\", formattedText: null };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n webdriverio: \"WebdriverIO (describe/it, $, browser.$)\",\n appium: \"Appium/WebdriverIO (mobile, $, browser.$)\",\n playwright: \"Playwright (test, page, locator)\",\n cypress: \"Cypress (cy.get, cy.click)\",\n jest: \"Jest (describe, test, expect)\",\n vitest: \"Vitest (describe, test, expect)\",\n robot: \"Robot Framework\",\n pytest: \"pytest\",\n };\n\n const systemPrompt = `Você é um mentor de QA. Analise o output de falha e responda em JSON (apenas o JSON, sem markdown) com as chaves:\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas, uma por item)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção se aplicável, no formato do framework)\n- conceito: string ou null (ex: \"Flaky test = teste intermitente. Geralmente por timing ou seletores frágeis.\")\n- framework: string (framework do projeto)\n\nFramework do projeto: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste que falhou:\\n---\\n${testCode.slice(0, 6000)}\\n---` : \"\"}`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear a resposta.\",\n porQueProvavelmenteFalhou: [],\n oQueFazerAgora: [],\n sugestaoCorrecao: null,\n conceito: null,\n framework: fw,\n };\n }\n data.framework = data.framework || fw;\n if (testFilePath && data.sugestaoCorrecao) {\n saveProjectMemory({ patterns: { [testFilePath]: { lastFix: data.sugestaoCorrecao?.slice(0, 500) } } });\n }\n const formattedText = formatFailureExplanation(data);\n return { ok: true, formattedText, structuredContent: data };\n } catch (err) {\n return { ok: false, error: err.message, formattedText: null };\n }\n}\n\nserver.registerTool(\n \"por_que_falhou\",\n {\n title: \"Por que falhou? Explicação para juniores\",\n description: \"Traduz stack trace em explicação humana. Recebe output do terminal/log, lê o projeto e o teste (se path dado), e retorna: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção, Conceito. Escalável e procedural.\",\n inputSchema: z.object({\n errorOutput: z.string().optional().describe(\"Output do terminal quando o teste falhou. Se vazio, lê automaticamente de .qa-lab-last-failure.log (capturado pelo run_tests). Cole aqui ou deixe vazio para usar última falha.\"),\n testFilePath: z.string().optional().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js). Se informado, o agente lê o código e dá sugestão mais precisa.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n oQueAconteceu: z.string().optional(),\n porQueProvavelmenteFalhou: z.array(z.string()).optional(),\n oQueFazerAgora: z.array(z.string()).optional(),\n sugestaoCorrecao: z.string().optional(),\n conceito: z.string().optional(),\n framework: z.string().optional(),\n formattedText: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ errorOutput, testFilePath }) => {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\n\n let resolvedOutput = errorOutput?.trim() || \"\";\n if (!resolvedOutput) {\n const lastFailurePath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(lastFailurePath)) {\n try {\n resolvedOutput = fs.readFileSync(lastFailurePath, \"utf8\");\n } catch {}\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{\n type: \"text\",\n text: \"Nenhum output de erro fornecido e nenhuma falha recente capturada.\\n\\nComo usar:\\n1. Rode os testes (run_tests) – se falhar, a saída é salva automaticamente.\\n2. Ou cole aqui o output do terminal quando o teste falhou.\\n3. Depois peça: 'Por que falhou?' ou chame por_que_falhou.\",\n }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n let testCode = \"\";\n if (testFilePath) {\n const normalized = testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n if (fs.existsSync(fullPath) && !fs.statSync(fullPath).isDirectory()) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env do projeto para usar a explicação com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n webdriverio: \"WebdriverIO (describe/it, $, browser.$)\",\n appium: \"Appium/WebdriverIO (mobile, $, browser.$)\",\n playwright: \"Playwright (test, page, locator)\",\n cypress: \"Cypress (cy.get, cy.click)\",\n jest: \"Jest (describe, test, expect)\",\n vitest: \"Vitest (describe, test, expect)\",\n robot: \"Robot Framework\",\n pytest: \"pytest\",\n };\n\n const systemPrompt = `Você é um mentor de QA. Analise o output de falha e responda em JSON (apenas o JSON, sem markdown) com as chaves:\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas, uma por item)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção se aplicável, no formato do framework)\n- conceito: string ou null (ex: \"Flaky test = teste intermitente. Geralmente por timing ou seletores frágeis.\")\n- framework: string (framework do projeto)\n\nFramework do projeto: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste que falhou:\\n---\\n${testCode.slice(0, 6000)}\\n---` : \"\"}`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear a resposta.\",\n porQueProvavelmenteFalhou: [],\n oQueFazerAgora: [],\n sugestaoCorrecao: null,\n conceito: null,\n framework: fw,\n };\n }\n\n data.framework = data.framework || fw;\n const formattedText = formatFailureExplanation(data);\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n oQueAconteceu: data.oQueAconteceu,\n porQueProvavelmenteFalhou: data.porQueProvavelmenteFalhou,\n oQueFazerAgora: data.oQueFazerAgora,\n sugestaoCorrecao: data.sugestaoCorrecao ?? null,\n conceito: data.conceito ?? null,\n framework: data.framework,\n formattedText,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// NOVAS FERRAMENTAS\n// ============================================================================\n\nserver.registerTool(\n \"suggest_fix\",\n {\n title: \"Sugerir correção para falhas\",\n description: \"Recebe análise de falhas e sugere correções (patch, refactor, etc.).\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Resultado de analyze_failures.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestions: z.array(z.object({\n test: z.string().optional(),\n description: z.string(),\n fix: z.string().optional(),\n })),\n }),\n },\n async ({ failures }) => {\n const suggestions = [];\n\n for (const f of failures) {\n const msg = f.message || \"\";\n \n if (/element not found|selector|timeout/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Elemento não encontrado ou timeout\",\n fix: \"Verifique seletores, adicione waits ou aumente timeout. Use data-testid para seletores mais estáveis.\",\n });\n } else if (/expected.*to.*but/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Asserção falhou\",\n fix: \"Revise o valor esperado. Verifique se o estado da aplicação está correto antes da asserção.\",\n });\n } else if (/network|fetch|ECONNREFUSED/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Erro de rede ou API não disponível\",\n fix: \"Verifique se o backend está rodando. Confirme a URL e porta da API.\",\n });\n } else {\n suggestions.push({\n test: f.test,\n description: \"Falha detectada\",\n fix: \"Revise o stack trace e o código do teste.\",\n });\n }\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(suggestions, null, 2) }],\n structuredContent: { ok: true, suggestions },\n };\n }\n);\n\n// ============================================================================\n// SELF-HEALING - Sugestão de correção de seletores quando UI muda\n// ============================================================================\n\nserver.registerTool(\n \"suggest_selector_fix\",\n {\n title: \"Sugerir correção de seletor (Self-healing)\",\n description: \"Quando um teste falha por elemento não encontrado (seletor quebrado após mudança de UI), usa LLM para sugerir seletor alternativo mais resiliente. Prioriza data-testid, role, texto acessível.\",\n inputSchema: z.object({\n testFilePath: z.string().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js).\"),\n errorOutput: z.string().optional().describe(\"Output do terminal da falha. Se vazio, lê de .qa-lab-last-failure.log.\"),\n framework: z.enum([\"cypress\", \"playwright\", \"webdriverio\", \"appium\"]).optional().describe(\"Framework do teste. Detectado automaticamente se omitido.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n selectorSugerido: z.string().optional(),\n codigoCorrigido: z.string().optional(),\n explicacao: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ testFilePath, errorOutput, framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || inferFrameworkFromFile(testFilePath.split(\"/\").pop(), structure);\n\n let resolvedOutput = errorOutput;\n if (!resolvedOutput) {\n const logPath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(logPath)) {\n resolvedOutput = fs.readFileSync(logPath, \"utf8\");\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{ type: \"text\", text: \"Nenhum output de erro. Rode os testes primeiro ou forneça errorOutput.\" }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n if (!/element not found|selector|timeout|locator|cy\\.get|page\\.locator/i.test(resolvedOutput)) {\n return {\n content: [{ type: \"text\", text: \"A falha não parece ser de seletor/elemento. Use por_que_falhou ou suggest_fix para outros tipos de falha.\" }],\n structuredContent: { ok: false, error: \"Not a selector-related failure\" },\n };\n }\n\n let testCode = \"\";\n const fullPath = path.join(PROJECT_ROOT, testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(fullPath)) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n cypress: \"Cypress: cy.get('[data-testid=...]'), cy.contains(), cy.get('button').filter(':visible')\",\n playwright: \"Playwright: page.getByRole(), page.getByTestId(), page.locator('button:has-text(\\\"...\\\")')\",\n webdriverio: \"WebdriverIO: $('[data-testid=...]'), $('button=Texto')\",\n appium: \"Appium: $('~accessibility-id'), $('//android.view.View')\",\n };\n\n const systemPrompt = `Você é um especialista em testes E2E. O teste falhou porque um seletor não encontrou o elemento (UI mudou).\nAnalise o erro e o código e responda APENAS em JSON (sem markdown) com as chaves:\n- selectorSugerido: string (o novo seletor recomendado, mais resiliente)\n- codigoCorrigido: string (bloco de código completo corrigido, apenas a parte relevante do teste)\n- explicacao: string (breve explicação em português: por que o antigo falhou e por que o novo é melhor)\n\nPriorize nesta ordem: data-testid > role + accessible name > texto visível > estrutura. Evite classes CSS e IDs que mudam.\n\nFramework: ${fw}. ${fwHints[fw] || \"\"}`;\n\n const userPrompt = `Output do erro:\n---\n${resolvedOutput.slice(0, 8000)}\n---\nCódigo do teste:\n---\n${testCode ? testCode.slice(0, 6000) : \"Não disponível\"}\n---`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n selectorSugerido: null,\n codigoCorrigido: raw.slice(0, 2000),\n explicacao: \"Não foi possível parsear. Resposta do LLM acima.\",\n };\n }\n\n const text = [\n data.explicacao && `## Explicação\\n${data.explicacao}`,\n data.selectorSugerido && `## Seletor sugerido\\n\\`${data.selectorSugerido}\\``,\n data.codigoCorrigido && `## Código corrigido\\n\\`\\`\\`${fw}\\n${data.codigoCorrigido}\\n\\`\\`\\``,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return {\n content: [{ type: \"text\", text: text || JSON.stringify(data, null, 2) }],\n structuredContent: {\n ok: true,\n selectorSugerido: data.selectorSugerido,\n codigoCorrigido: data.codigoCorrigido,\n explicacao: data.explicacao,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao chamar LLM: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_file_methods\",\n {\n title: \"Analisar métodos de um arquivo\",\n description: \"Lê um arquivo, faz varredura em todos os métodos/funções e retorna análise detalhada: método correto?, melhor forma de escrever?, falso positivo?, coerência?, itens faltando?, parâmetros faltando?, imports faltando?. Requer API key (Groq/Gemini/OpenAI).\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho do arquivo (ex: src/utils.js, tests/login.cy.js, cypress/support/commands.js).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n filePath: z.string().optional(),\n methods: z.array(z.object({\n name: z.string(),\n correto: z.boolean().optional(),\n melhorForma: z.string().optional(),\n falsoPositivo: z.boolean().optional(),\n falsoPositivoRazao: z.string().optional(),\n coerente: z.boolean().optional(),\n itensFaltando: z.array(z.string()).optional(),\n parametrosFaltando: z.array(z.string()).optional(),\n importsFaltando: z.array(z.string()).optional(),\n sugestao: z.string().optional(),\n })).optional(),\n importsFaltandoGlobal: z.array(z.string()).optional(),\n resumo: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Informe um arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n let fileContent = \"\";\n try {\n fileContent = fs.readFileSync(fullPath, \"utf8\");\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env para usar análise com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const ext = path.extname(fullPath).toLowerCase();\n const lang = [\".ts\", \".tsx\"].includes(ext) ? \"TypeScript\" : [\".js\", \".jsx\"].includes(ext) ? \"JavaScript\" : [\".py\"].includes(ext) ? \"Python\" : \"código\";\n\n const systemPrompt = `Você é um revisor de código experiente em QA e testes. Analise o arquivo e cada método/função, respondendo em JSON válido (sem markdown) com a estrutura:\n\n{\n \"methods\": [\n {\n \"name\": \"nomeDoMetodo\",\n \"correto\": true | false,\n \"melhorForma\": \"explicação curta se há forma melhor de escrever\",\n \"falsoPositivo\": true | false,\n \"falsoPositivoRazao\": \"se falso positivo, por quê (ex: asserção muito permissiva)\",\n \"coerente\": true | false,\n \"coerenteDetalhe\": \"se incoerente, o que está inconsistente\",\n \"itensFaltando\": [\"item1\", \"item2\"],\n \"parametrosFaltando\": [\"param1\"],\n \"importsFaltando\": [\"moduloX\"],\n \"sugestao\": \"código ou texto de sugestão de melhoria\"\n }\n ],\n \"importsFaltandoGlobal\": [\"imports faltando no topo do arquivo\"],\n \"resumo\": \"resumo geral em 2-3 linhas\"\n}\n\nPara CADA método/função no arquivo, verifique:\n1. correto: a lógica está correta?\n2. melhorForma: há forma mais legível, performática ou idiomática de escrever?\n3. falsoPositivo: o método pode passar quando não deveria (asserção fraca, mock incorreto)?\n4. coerente: o método é coerente com o restante do código, naming, padrões?\n5. itensFaltando: falta try/catch, validação, cleanup, etc?\n6. parametrosFaltando: parâmetros que deveriam existir?\n7. importsFaltando: imports que o método usa mas não estão declarados?\n\nResponda APENAS com o JSON válido. Linguagem: ${lang}.`;\n\n const userPrompt = `Arquivo: ${normalized}\n\n\\`\\`\\`${lang}\n${fileContent.slice(0, 18000)}\n\\`\\`\\`\n\nAnalise cada método/função e retorne o JSON conforme especificado.`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n methods: [],\n importsFaltandoGlobal: [],\n resumo: raw.slice(0, 1000) || \"Não foi possível parsear a resposta do LLM.\",\n };\n }\n\n const lines = [\n `# Análise de métodos: ${normalized}`,\n \"\",\n data.resumo && `## Resumo\\n${data.resumo}`,\n data.importsFaltandoGlobal?.length > 0\n ? `\\n## Imports faltando (global)\\n${data.importsFaltandoGlobal.map((i) => `- ${i}`).join(\"\\n\")}`\n : \"\",\n \"\\n## Métodos analisados\\n\",\n ];\n\n for (const m of data.methods || []) {\n lines.push(`### ${m.name}`);\n lines.push(\"\");\n if (m.correto !== undefined) lines.push(`- **Correto:** ${m.correto ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.melhorForma) lines.push(`- **Melhor forma:** ${m.melhorForma}`);\n if (m.falsoPositivo) lines.push(`- **Falso positivo:** ⚠️ Sim - ${m.falsoPositivoRazao || \"verificar\"}`);\n if (m.coerente !== undefined) lines.push(`- **Coerente:** ${m.coerente ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.itensFaltando?.length) lines.push(`- **Itens faltando:** ${m.itensFaltando.join(\", \")}`);\n if (m.parametrosFaltando?.length) lines.push(`- **Parâmetros faltando:** ${m.parametrosFaltando.join(\", \")}`);\n if (m.importsFaltando?.length) lines.push(`- **Imports faltando:** ${m.importsFaltando.join(\", \")}`);\n if (m.sugestao) lines.push(`\\n**Sugestão:**\\n\\`\\`\\`\\n${m.sugestao}\\n\\`\\`\\``);\n lines.push(\"\");\n }\n\n const formattedText = lines.filter(Boolean).join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n filePath: normalized,\n methods: data.methods || [],\n importsFaltandoGlobal: data.importsFaltandoGlobal || [],\n resumo: data.resumo,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n\nserver.registerTool(\n \"create_bug_report\",\n {\n title: \"Criar relatório de bug\",\n description: \"Gera um bug report estruturado a partir de falhas de teste.\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Falhas (de analyze_failures).\"),\n title: z.string().optional().describe(\"Título do bug.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n report: z.string(),\n title: z.string(),\n }),\n },\n async ({ failures, title }) => {\n const bugTitle = title || `Falha em ${failures.length} teste(s)`;\n const lines = [\n `# ${bugTitle}`,\n \"\",\n \"## Resumo\",\n \"\",\n `${failures.length} teste(s) falharam durante a execução.`,\n \"\",\n \"## Falhas detectadas\",\n \"\",\n ];\n\n failures.forEach((f, i) => {\n lines.push(`### ${i + 1}. ${f.test || \"Teste desconhecido\"}`);\n lines.push(\"\");\n lines.push(`**Mensagem:** ${f.message || \"N/A\"}`);\n lines.push(\"\");\n if (f.stack) {\n lines.push(\"**Stack trace:**\");\n lines.push(\"```\");\n lines.push(f.stack);\n lines.push(\"```\");\n lines.push(\"\");\n }\n });\n\n lines.push(\"## Próximos passos\");\n lines.push(\"\");\n lines.push(\"- [ ] Reproduzir localmente\");\n lines.push(\"- [ ] Identificar causa raiz\");\n lines.push(\"- [ ] Aplicar correção\");\n lines.push(\"- [ ] Validar com testes\");\n\n const report = lines.join(\"\\n\");\n\n appendMetricsEvent({ type: \"bug_reported\", failuresCount: failures.length, title: bugTitle });\n\n return {\n content: [{ type: \"text\", text: report }],\n structuredContent: { ok: true, report, title: bugTitle },\n };\n }\n);\n\n// ============================================================================\n// MÉTRICAS DE NEGÓCIO - Relatório agregado\n// ============================================================================\n\nserver.registerTool(\n \"get_business_metrics\",\n {\n title: \"Obter métricas de negócio\",\n description: \"Retorna métricas: tempo até bug, custo por defeito (tempo estimado), cobertura por fluxo. Requer run_tests executados e opcionalmente qa-lab-flows.json.\",\n inputSchema: z.object({\n period: z.enum([\"7d\", \"30d\", \"all\"]).optional().describe(\"Período para analisar. Default: 30d.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n timeToBug: z.object({\n avgHours: z.number(),\n lastFailureAt: z.string().optional(),\n runsWithFailures: z.number(),\n }).optional(),\n costPerDefect: z.object({\n avgMinutesPerDefect: z.number(),\n totalFailures: z.number(),\n estimatedHoursSpent: z.number(),\n }).optional(),\n flowCoverage: z.object({\n totalFlows: z.number(),\n coveredFlows: z.number(),\n percent: z.number(),\n details: z.array(z.object({ flow: z.string(), covered: z.boolean() })),\n }).optional(),\n summary: z.string(),\n }),\n },\n async ({ period = \"30d\" } = {}) => {\n const now = Date.now();\n const msByPeriod = { \"7d\": 7 * 24 * 60 * 60 * 1000, \"30d\": 30 * 24 * 60 * 60 * 1000, all: Infinity };\n const cutoff = now - msByPeriod[period];\n\n let data = { events: [] };\n if (fs.existsSync(METRICS_FILE)) {\n try {\n data = JSON.parse(fs.readFileSync(METRICS_FILE, \"utf8\"));\n } catch {}\n }\n\n const events = (data.events || []).filter((e) => new Date(e.timestamp).getTime() >= cutoff);\n\n const testRuns = events.filter((e) => e.type === \"test_run\");\n const failedRuns = testRuns.filter((e) => (e.failed || 0) > 0);\n const totalFailed = testRuns.reduce((sum, e) => sum + (e.failed || 0), 0);\n const totalDuration = testRuns.reduce((sum, e) => sum + (e.durationSeconds || 0), 0);\n\n let timeToBug = null;\n if (failedRuns.length > 0) {\n const lastFailure = failedRuns[failedRuns.length - 1];\n timeToBug = {\n avgHours: 0,\n lastFailureAt: lastFailure.timestamp,\n runsWithFailures: failedRuns.length,\n };\n if (failedRuns.length >= 2) {\n const deltas = [];\n for (let i = 1; i < failedRuns.length; i++) {\n const prev = new Date(failedRuns[i - 1].timestamp).getTime();\n const curr = new Date(failedRuns[i].timestamp).getTime();\n deltas.push((curr - prev) / (1000 * 60 * 60));\n }\n timeToBug.avgHours = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n }\n }\n\n let costPerDefect = null;\n if (totalFailed > 0) {\n const estimatedMinutesSpent = totalDuration + totalFailed * 5;\n costPerDefect = {\n avgMinutesPerDefect: Math.round(estimatedMinutesSpent / totalFailed),\n totalFailures: totalFailed,\n estimatedHoursSpent: Math.round((estimatedMinutesSpent / 60) * 10) / 10,\n };\n }\n\n let flowCoverage = null;\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flowsConfig = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n const flows = flowsConfig.flows || [];\n const structure = detectProjectStructure();\n const allTestFiles = new Set(collectTestFiles(structure).map((e) => e.path));\n\n const details = flows.map((f) => {\n const testFiles = f.testFiles || [];\n const covered = testFiles.some((tf) => allTestFiles.has(tf) || allTestFiles.has(tf.replace(/\\\\/g, \"/\")));\n return { flow: f.name || f.id || \"?\", covered };\n });\n\n flowCoverage = {\n totalFlows: flows.length,\n coveredFlows: details.filter((d) => d.covered).length,\n percent: flows.length ? Math.round((details.filter((d) => d.covered).length / flows.length) * 100) : 0,\n details,\n };\n } catch {}\n }\n\n const lines = [\n \"## Métricas de negócio\",\n \"\",\n `Período: ${period}`,\n \"\",\n timeToBug\n ? [\n \"### Tempo até bug\",\n `- Última falha: ${timeToBug.lastFailureAt || \"N/A\"}`,\n `- Execuções com falha: ${timeToBug.runsWithFailures}`,\n timeToBug.avgHours > 0 ? `- Média entre falhas: ${timeToBug.avgHours.toFixed(1)}h` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\")\n : \"\",\n costPerDefect\n ? [\n \"### Custo por defeito (estimativa)\",\n `- Total de falhas: ${costPerDefect.totalFailures}`,\n `- Tempo médio por defeito: ~${costPerDefect.avgMinutesPerDefect} min`,\n `- Horas estimadas gastas: ${costPerDefect.estimatedHoursSpent}h`,\n ].join(\"\\n\")\n : \"\",\n flowCoverage\n ? [\n \"### Cobertura por fluxo\",\n `- Fluxos cobertos: ${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} (${flowCoverage.percent}%)`,\n flowCoverage.details.map((d) => ` - ${d.flow}: ${d.covered ? \"✅\" : \"❌\"}`).join(\"\\n\"),\n ].join(\"\\n\")\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n if (!timeToBug && !costPerDefect && !flowCoverage) {\n const msg =\n \"Nenhuma métrica disponível. Rode run_tests para gerar dados. Para cobertura por fluxo, crie qa-lab-flows.json.\";\n return {\n content: [{ type: \"text\", text: msg }],\n structuredContent: { ok: false, summary: msg },\n };\n }\n\n const summary = [\n timeToBug && `${timeToBug.runsWithFailures} execuções com falha`,\n costPerDefect && `${costPerDefect.totalFailures} falhas (~${costPerDefect.avgMinutesPerDefect} min/defeito)`,\n flowCoverage && `${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} fluxos cobertos`,\n ]\n .filter(Boolean)\n .join(\" | \");\n\n return {\n content: [{ type: \"text\", text: lines || summary }],\n structuredContent: {\n ok: true,\n timeToBug,\n costPerDefect,\n flowCoverage,\n summary,\n },\n };\n }\n);\n\nserver.registerTool(\n \"list_test_files\",\n {\n title: \"Listar arquivos de teste\",\n description: \"Lista TODOS os arquivos de teste (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, Behave, etc.) com filtro opcional.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"webdriverio\", \"appium\", \"robot\", \"pytest\", \"behave\", \"detox\", \"all\"\n ]).optional().describe(\"Filtrar por framework. Default: all.\"),\n pattern: z.string().optional().describe(\"Pattern para filtrar (ex: 'login', 'api').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n files: z.array(z.string()),\n total: z.number(),\n }),\n },\n async ({ framework = \"all\", pattern } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, { framework, pattern });\n const allFiles = collected.map((e) => e.path);\n\n const summary = `Encontrados ${allFiles.length} arquivo(s) de teste (qualquer framework).`;\n\n return {\n content: [{ type: \"text\", text: `${summary}\\n\\n${allFiles.slice(0, 50).join(\"\\n\")}` }],\n structuredContent: { ok: true, files: allFiles, total: allFiles.length },\n };\n }\n);\n\nserver.registerTool(\n \"run_linter\",\n {\n title: \"Executar linter\",\n description: \"Roda ESLint, Prettier ou linter configurado no projeto.\",\n inputSchema: z.object({\n fix: z.boolean().optional().describe(\"Auto-fix (--fix). Default: false.\"),\n path: z.string().optional().describe(\"Caminho específico (ex: src/). Default: todo o projeto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n output: z.string().optional(),\n }),\n },\n async ({ fix, path: targetPath }) => {\n const structure = detectProjectStructure();\n const scripts = structure.packageJson?.scripts || {};\n\n let cmd, args;\n if (scripts.lint) {\n cmd = \"npm\";\n args = [\"run\", \"lint\"];\n } else if (structure.packageJson?.devDependencies?.eslint || structure.packageJson?.dependencies?.eslint) {\n cmd = \"npx\";\n args = [\"eslint\", targetPath || \".\"];\n if (fix) args.push(\"--fix\");\n } else {\n return {\n content: [{ type: \"text\", text: \"Linter não detectado no projeto.\" }],\n structuredContent: { status: \"not_found\", message: \"No linter found\", exitCode: 1 },\n };\n }\n\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n\n child.on(\"close\", (code) => {\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Linter passou.\" : \"Linter encontrou problemas.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Lint passed\" : \"Lint failed\",\n exitCode: code ?? 1,\n output: !passed ? output : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"install_dependencies\",\n {\n title: \"Instalar dependências\",\n description: \"Roda npm install, yarn install ou pnpm install (detecta automaticamente).\",\n inputSchema: z.object({\n packageManager: z.enum([\"npm\", \"yarn\", \"pnpm\", \"auto\"]).optional().describe(\"Package manager. Default: auto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\"]),\n message: z.string(),\n exitCode: z.number(),\n }),\n },\n async ({ packageManager = \"auto\" }) => {\n let pm = packageManager;\n \n if (pm === \"auto\") {\n if (fs.existsSync(path.join(PROJECT_ROOT, \"yarn.lock\"))) pm = \"yarn\";\n else if (fs.existsSync(path.join(PROJECT_ROOT, \"pnpm-lock.yaml\"))) pm = \"pnpm\";\n else pm = \"npm\";\n }\n\n return new Promise((resolve) => {\n const child = spawn(pm, [\"install\"], {\n cwd: PROJECT_ROOT,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n child.on(\"close\", (code) => {\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Dependências instaladas.\" : \"Erro ao instalar dependências.\" }],\n structuredContent: {\n status: passed ? \"success\" : \"failed\",\n message: passed ? \"Dependencies installed\" : \"Install failed\",\n exitCode: code ?? 1,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"qa_learning_stats\",\n {\n title: \"Estatísticas de aprendizado\",\n description: \"[MÉTRICAS] Retorna métricas de aprendizado do agente: quantos testes gerados, taxa de sucesso na primeira tentativa, correções aplicadas, etc.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n totalLearnings: z.number(),\n successfulFixes: z.number(),\n selectorFixes: z.number(),\n timingFixes: z.number(),\n testsGenerated: z.number(),\n firstAttemptSuccessRate: z.number(),\n }),\n },\n async () => {\n const stats = getMemoryStats();\n const summary = `📊 **Estatísticas de Aprendizado**\n\n- Total de aprendizados: ${stats.totalLearnings}\n- Correções bem-sucedidas: ${stats.successfulFixes}\n- Correções de seletores: ${stats.selectorFixes}\n- Correções de timing: ${stats.timingFixes}\n- Testes gerados: ${stats.testsGenerated}\n- Taxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use qa_auto para gerar testes e aprender com erros.\" : \"\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: stats,\n };\n }\n);\n\nserver.registerTool(\n \"get_test_coverage\",\n {\n title: \"Obter cobertura de testes\",\n description: \"Roda testes com coverage (Jest, Playwright, Cypress com plugin).\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"playwright\", \"cypress\"]).optional().describe(\"Framework. Default: detectado automaticamente.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\", \"not_supported\"]),\n message: z.string(),\n coveragePercent: z.number().optional(),\n output: z.string().optional(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (fw === \"jest\") {\n return new Promise((resolve) => {\n const child = spawn(\"npx\", [\"jest\", \"--coverage\"], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n\n child.on(\"close\", (code) => {\n const coverageMatch = stdout.match(/All files.*?(\\d+\\.?\\d*)/);\n const coveragePercent = coverageMatch ? parseFloat(coverageMatch[1]) : undefined;\n\n resolve({\n content: [{ type: \"text\", text: `Coverage: ${coveragePercent || \"N/A\"}%` }],\n structuredContent: {\n status: code === 0 ? \"success\" : \"failed\",\n message: code === 0 ? \"Coverage generated\" : \"Coverage failed\",\n coveragePercent,\n output: stdout,\n },\n });\n });\n });\n }\n\n return {\n content: [{ type: \"text\", text: `Coverage não suportado para ${fw} ainda.` }],\n structuredContent: { status: \"not_supported\", message: \"Coverage not supported for this framework\" },\n };\n }\n);\n\nserver.registerTool(\n \"watch_tests\",\n {\n title: \"Rodar testes em modo watch\",\n description: \"Inicia testes em watch mode (Jest, Vitest). Útil para desenvolvimento.\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"vitest\"]).optional().describe(\"Framework. Default: detectado.\"),\n }),\n outputSchema: z.object({\n status: z.string(),\n message: z.string(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || (structure.testFrameworks.includes(\"jest\") ? \"jest\" : \"vitest\");\n\n if (!structure.testFrameworks.includes(fw)) {\n return {\n content: [{ type: \"text\", text: `${fw} não detectado no projeto.` }],\n structuredContent: { status: \"not_found\", message: \"Framework not found\" },\n };\n }\n\n return {\n content: [{ type: \"text\", text: `Para watch mode, rode manualmente: npx ${fw} --watch` }],\n structuredContent: {\n status: \"info\",\n message: `Watch mode requires interactive terminal. Run: npx ${fw} --watch`,\n },\n };\n }\n);\n\nserver.registerTool(\n \"qa_auto\",\n {\n title: \"Modo autônomo: gera, roda, corrige e aprende\",\n description: \"[AGENTE AUTÔNOMO] Loop completo: detecta projeto → gera teste → roda → se falhar: analisa, corrige, roda de novo → aprende com erros. Repete até passar ou atingir max_retries.\",\n inputSchema: z.object({\n request: z.string().describe(\"O que testar (ex: 'login flow', 'checkout', 'API /users').\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\", \"appium\", \"robot\", \"pytest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n maxRetries: z.number().optional().describe(\"Máximo de tentativas de correção. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n testFilePath: z.string().optional(),\n attempts: z.number(),\n finalStatus: z.enum([\"passed\", \"failed\", \"max_retries\"]),\n learnings: z.array(z.object({ attempt: z.number(), action: z.string(), result: z.string() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ request, framework, maxRetries = 3 }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework detectado. Configure testes primeiro.\" }],\n structuredContent: { ok: false, error: \"No framework\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const learnings = [];\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n let attempt = 0;\n\n learnings.push({ attempt: 0, action: \"detect_project\", result: `${structure.testFrameworks.length} framework(s)` });\n\n for (attempt = 1; attempt <= maxRetries; attempt++) {\n learnings.push({ attempt, action: \"generate_tests\", result: \"gerando...\" });\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${request}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"write_test\", result: `gravado: ${testFilePath}` });\n\n learnings.push({ attempt, action: \"run_tests\", result: \"executando...\" });\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n learnings.push({ attempt, action: \"run_tests\", result: \"✅ passou\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `✅ Teste passou na tentativa ${attempt}!\\n\\nArquivo: ${testFilePath}\\n\\nAprendizados salvos.` }],\n structuredContent: { ok: true, testFilePath, attempts: attempt, finalStatus: \"passed\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"run_tests\", result: `❌ falhou (exit ${runResult.code})` });\n\n if (attempt >= maxRetries) {\n learnings.push({ attempt, action: \"max_retries\", result: \"limite atingido\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `❌ Teste falhou após ${attempt} tentativa(s).\\n\\nÚltimo erro:\\n${runResult.output.slice(0, 500)}` }],\n structuredContent: { ok: false, testFilePath, attempts: attempt, finalStatus: \"max_retries\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"analyze_failures\", result: \"analisando...\" });\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n const llmComplex = resolveLLMProvider(\"complex\");\n const explainResult = await generateFailureExplanation(runResult.output, testFilePath);\n\n if (!explainResult.ok || !explainResult.structuredContent?.sugestaoCorrecao) {\n learnings.push({ attempt, action: \"analyze_failures\", result: \"sem sugestão de correção\" });\n continue;\n }\n\n learnings.push({ attempt, action: \"apply_fix\", result: \"aplicando correção...\" });\n const fixedCode = explainResult.structuredContent.sugestaoCorrecao;\n testContent = fixedCode;\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"apply_fix\", result: \"correção aplicada\" });\n\n if (flakyAnalysis.isLikelyFlaky) {\n saveProjectMemory({\n learnings: [{\n type: flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\",\n request,\n framework: fw,\n fix: fixedCode.slice(0, 500),\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n }\n } catch (err) {\n learnings.push({ attempt, action: \"error\", result: err.message });\n return {\n content: [{ type: \"text\", text: `Erro na tentativa ${attempt}: ${err.message}` }],\n structuredContent: { ok: false, error: err.message, attempts: attempt, finalStatus: \"failed\", learnings },\n };\n }\n }\n\n return {\n content: [{ type: \"text\", text: `❌ Falhou após ${maxRetries} tentativa(s).` }],\n structuredContent: { ok: false, testFilePath, attempts: maxRetries, finalStatus: \"max_retries\", learnings },\n };\n }\n);\n\nserver.registerTool(\n \"create_test_template\",\n {\n title: \"Criar template de teste\",\n description: \"Gera template básico de teste (boilerplate) para o framework escolhido.\",\n inputSchema: z.object({\n framework: z.enum([\"cypress\", \"playwright\", \"jest\"]).describe(\"Framework.\"),\n type: z.enum([\"api\", \"ui\", \"unit\"]).optional().describe(\"Tipo de teste. Default: api.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n template: z.string(),\n suggestedFileName: z.string(),\n }),\n },\n async ({ framework, type = \"api\" }) => {\n let template = \"\";\n let fileName = \"\";\n\n if (framework === \"cypress\") {\n fileName = `${type}-test.cy.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n it('should pass', () => {\n ${type === \"api\" ? \"cy.request('GET', 'http://localhost:3000/api/health').then((res) => {\\n expect(res.status).to.eq(200);\\n });\" : \"cy.visit('/');\\n cy.get('h1').should('be.visible');\"}\n });\n});`;\n } else if (framework === \"playwright\") {\n fileName = `${type}-test.spec.js`;\n template = `const { test, expect } = require('@playwright/test');\n\ntest.describe('${type.toUpperCase()} Test', () => {\n test('should pass', async ({ ${type === \"api\" ? \"request\" : \"page\"} }) => {\n ${type === \"api\" ? \"const res = await request.get('http://localhost:3000/api/health');\\n expect(res.status()).toBe(200);\" : \"await page.goto('/');\\n await expect(page.locator('h1')).toBeVisible();\"}\n });\n});`;\n } else {\n fileName = `${type}-test.test.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n test('should pass', ${type === \"api\" ? \"async () => {\\n const res = await fetch('http://localhost:3000/api/health');\\n expect(res.status).toBe(200);\\n }\" : \"() => {\\n expect(true).toBe(true);\\n }\"});\n});`;\n }\n\n return {\n content: [{ type: \"text\", text: `Template criado. Use write_test para gravar.` }],\n structuredContent: { ok: true, template, suggestedFileName: fileName },\n };\n }\n);\n\nasync function main() {\n const cmd = process.argv[2];\n\n if (cmd === \"--help\" || cmd === \"-h\") {\n console.log(`\nmcp-lab-agent - Agente autônomo de QA que aprende com os próprios erros\n\nUSO:\n mcp-lab-agent [comando] # Sem comando: inicia servidor MCP\n mcp-lab-agent --help # Mostra esta ajuda\n\nCOMANDOS CLI:\n detect [--json] Detecta frameworks e estrutura. Padrão: resumo. --json: JSON completo para scripts.\n route <tarefa> Sugere qual ferramenta usar (ex: route \"rodar testes\")\n list Lista ferramentas MCP disponíveis\n auto <descrição> [--max-retries N] [NOVO] Modo autônomo: gera teste, roda, corrige e aprende (default: 3 tentativas)\n stats [NOVO] Mostra estatísticas de aprendizado (taxa de sucesso, correções, etc.)\n\nEXEMPLOS:\n mcp-lab-agent auto \"login flow\" --max-retries 5\n mcp-lab-agent stats\n mcp-lab-agent detect --json\n\nINTEGRAÇÃO MCP (Cursor/Cline/Windsurf):\n Adicione ao ~/.cursor/mcp.json:\n {\n \"mcpServers\": {\n \"qa-lab-agent\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"mcp-lab-agent\"],\n \"cwd\": \"\\${workspaceFolder}\"\n }\n }\n }\n`);\n process.exit(0);\n }\n\n if (cmd === \"detect\") {\n const structure = detectProjectStructure();\n const jsonOnly = process.argv.includes(\"--json\");\n if (jsonOnly) {\n console.log(JSON.stringify(structure, null, 2));\n } else {\n const lines = [\n \"\",\n \"mcp-lab-agent · detecção\",\n \"─\".repeat(40),\n `Frameworks: ${structure.testFrameworks.length ? structure.testFrameworks.join(\", \") : \"nenhum\"}`,\n `Pastas: ${structure.testDirs.length ? structure.testDirs.join(\", \") : \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"—\"}`,\n `Frontend: ${structure.frontendDir || \"—\"}`,\n `Mobile: ${structure.hasMobile ? \"sim\" : \"—\"}`,\n \"─\".repeat(40),\n \"(use --json para saída completa)\",\n \"\",\n ];\n console.log(lines.join(\"\\n\"));\n }\n process.exit(0);\n }\n\n if (cmd === \"list\") {\n const agents = Object.entries(QA_AGENTS).map(([k, v]) => ` ${k}: ${v.tools.join(\", \")}`);\n console.log(\"Agentes e ferramentas:\\n\" + agents.join(\"\\n\"));\n process.exit(0);\n }\n\n if (cmd === \"route\" && process.argv[3]) {\n const task = process.argv.slice(3).join(\" \");\n const t = task.toLowerCase();\n let agent = \"detection\";\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) agent = \"autonomous\";\n else if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats/i.test(t)) agent = \"learning\";\n else if (/rodar|executar|run|test|coverage|watch/i.test(t)) agent = \"execution\";\n else if (/gerar|criar|escrever|generate|write|template/i.test(t)) agent = \"generation\";\n else if (/analisar|por que|falhou|sugerir|fix|selector/i.test(t)) agent = \"analysis\";\n else if (/browser|navegador|screenshot|network|console/i.test(t)) agent = \"browser\";\n else if (/relatório|métrica|bug report/i.test(t)) agent = \"reporting\";\n else if (/linter|dependência|instalar|analisar método/i.test(t)) agent = \"maintenance\";\n const a = QA_AGENTS[agent] || QA_AGENTS.detection;\n console.log(JSON.stringify({ suggestedAgent: agent, suggestedTools: a.tools, description: a.desc }, null, 2));\n process.exit(0);\n }\n\n if (cmd === \"auto\") {\n const request = process.argv.slice(3).join(\" \");\n if (!request) {\n console.error(\"❌ Uso: mcp-lab-agent auto <descrição do teste> [--max-retries N]\");\n process.exit(1);\n }\n const maxRetriesIdx = process.argv.indexOf(\"--max-retries\");\n const maxRetries = maxRetriesIdx !== -1 && process.argv[maxRetriesIdx + 1] ? parseInt(process.argv[maxRetriesIdx + 1], 10) : 3;\n const cleanRequest = request.replace(/--max-retries\\s+\\d+/g, \"\").trim();\n\n console.log(`\\n🤖 Modo autônomo iniciado: \"${cleanRequest}\"\\n`);\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0];\n if (!fw) {\n console.error(\"❌ Nenhum framework detectado.\");\n process.exit(1);\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n console.error(\"❌ Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\");\n process.exit(1);\n }\n\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Gerando teste...`);\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${cleanRequest}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = cleanRequest.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n console.log(`✅ Teste gravado: ${testFilePath}`);\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Executando teste...`);\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n console.log(`\\n✅ Teste passou na tentativa ${attempt}!`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n console.log(`\\n📊 Aprendizado salvo. Use \"mcp-lab-agent stats\" para ver métricas.\\n`);\n process.exit(0);\n }\n\n console.log(`\\n❌ Teste falhou (exit ${runResult.code})`);\n console.log(`\\nSaída:\\n${runResult.output.slice(0, 800)}\\n`);\n\n if (attempt >= maxRetries) {\n console.log(`\\n❌ Limite de tentativas atingido (${maxRetries}).\\n`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n process.exit(1);\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Analisando falha...`);\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n if (flakyAnalysis.isLikelyFlaky) {\n console.log(`⚠️ Flaky detectado (${flakyAnalysis.confidence.toFixed(2)}): ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}`);\n }\n\n const explainResult = await generateFailureExplanation(runResult.output, testFilePath);\n if (!explainResult.ok || !explainResult.structuredContent?.sugestaoCorrecao) {\n console.log(`⚠️ Não foi possível gerar correção. Tentando novamente...`);\n continue;\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Aplicando correção...`);\n const fixedCode = explainResult.structuredContent.sugestaoCorrecao;\n testContent = fixedCode;\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n console.log(`✅ Correção aplicada.`);\n\n if (flakyAnalysis.isLikelyFlaky) {\n saveProjectMemory({\n learnings: [{\n type: flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\",\n request: cleanRequest,\n framework: fw,\n fix: fixedCode.slice(0, 500),\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n }\n } catch (err) {\n console.error(`\\n❌ Erro na tentativa ${attempt}: ${err.message}\\n`);\n process.exit(1);\n }\n }\n\n console.log(`\\n❌ Falhou após ${maxRetries} tentativa(s).\\n`);\n process.exit(1);\n }\n\n if (cmd === \"stats\") {\n const stats = getMemoryStats();\n console.log(`\n📊 Estatísticas de Aprendizado\n\nTotal de aprendizados: ${stats.totalLearnings}\nCorreções bem-sucedidas: ${stats.successfulFixes}\nCorreções de seletores: ${stats.selectorFixes}\nCorreções de timing: ${stats.timingFixes}\nTestes gerados: ${stats.testsGenerated}\nTaxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use 'mcp-lab-agent auto <descrição>' para gerar testes e aprender com erros.\" : \"\"}\n`);\n process.exit(0);\n }\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Erro no MCP server:\", err);\n process.exit(1);\n});\n"],"mappings":"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","names":["res","data"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.js","../src/core/llm-router.js","../src/core/memory.js","../src/core/flaky-detection.js","../src/core/project-structure.js","../src/core/tool-helpers.js","../src/cli/commands.js"],"sourcesContent":["#!/usr/bin/env node\n/**\n * MCP Lab Agent - Standalone (Modularizado)\n * MCP server genérico para QA automation em qualquer projeto.\n * Detecta automaticamente Cypress, Playwright, Jest, estrutura do projeto, etc.\n */\nimport { config } from \"dotenv\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport { spawn } from \"node:child_process\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\n\nimport { resolveLLMProvider, TASK_COMPLEXITY } from \"./core/llm-router.js\";\nimport { loadProjectMemory, saveProjectMemory, getMemoryStats, analyzeTestStability } from \"./core/memory.js\";\nimport { detectFlakyPatterns } from \"./core/flaky-detection.js\";\nimport { detectProjectStructure, collectTestFiles, inferFrameworkFromFile, matchesFramework, getFrameworkCwd, isTestFile, analyzeCodeRisks } from \"./core/project-structure.js\";\nimport { parseTestRunResult, recordMetricEvent, extractFailuresFromOutput, generateFailureExplanation } from \"./core/tool-helpers.js\";\nimport { handleCLI } from \"./cli/commands.js\";\n\nconst PROJECT_ROOT = process.cwd();\nconfig({ path: path.join(PROJECT_ROOT, \".env\") });\n\nconst server = new McpServer({\n name: \"mcp-lab-agent\",\n version: \"2.1.0\",\n});\n\n// ============================================================================\n// CONSTANTES E HELPERS\n// ============================================================================\n\nconst METRICS_FILE = path.join(PROJECT_ROOT, \".qa-lab-metrics.json\");\n\nfunction appendMetricsEvent(event) {\n recordMetricEvent(event);\n}\n\n// ============================================================================\n// FERRAMENTAS GENÉRICAS\n// ============================================================================\n\nserver.registerTool(\n \"read_file\",\n {\n title: \"Ler qualquer arquivo\",\n description: \"Lê o conteúdo de QUALQUER arquivo do projeto por caminho. Use para specs, page objects, componentes, código fonte - qualquer formato.\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho relativo ao projeto (ex: cypress/e2e/login.cy.js, src/pages/Login.tsx, tests/login.robot).\"),\n encoding: z.enum([\"utf8\", \"utf-8\"]).optional().describe(\"Encoding. Default: utf8\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n content: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath, encoding = \"utf8\" }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Use um caminho de arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n try {\n const content = fs.readFileSync(fullPath, encoding);\n return {\n content: [{ type: \"text\", text: content }],\n structuredContent: { ok: true, content },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"detect_project\",\n {\n title: \"Detectar estrutura do projeto\",\n description: \"Analisa o projeto e identifica frameworks de teste, pastas, backend, frontend.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n ok: z.boolean(),\n structure: z.object({\n hasTests: z.boolean(),\n testFrameworks: z.array(z.string()),\n testDirs: z.array(z.string()),\n hasBackend: z.boolean(),\n backendDir: z.string().nullable(),\n hasFrontend: z.boolean(),\n frontendDir: z.string().nullable(),\n }),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const summary = [\n `Frameworks de teste: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Pastas de teste: ${structure.testDirs.join(\", \") || \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n ].join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: { ok: true, structure },\n };\n }\n);\n\n// ============================================================================\n// WEB EVAL BROWSER - Modo browser (screenshots, network, console) via Playwright\n// ============================================================================\n\nserver.registerTool(\n \"web_eval_browser\",\n {\n title: \"Avaliar app no browser (screenshots, network, console)\",\n description: \"[Agente especializado: Browser] Abre a URL no navegador, captura screenshot, erros de console e requisições de rede. Inspirado em web-eval-agent. Requer: npm install playwright\",\n inputSchema: z.object({\n url: z.string().describe(\"URL para avaliar (ex: http://localhost:3000, https://exemplo.com).\"),\n screenshotPath: z.string().optional().describe(\"Caminho para salvar screenshot. Default: .qa-lab-screenshot.png\"),\n captureNetwork: z.boolean().optional().describe(\"Capturar requisições de rede. Default: true\"),\n captureConsole: z.boolean().optional().describe(\"Capturar logs e erros do console. Default: true\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n screenshotPath: z.string().optional(),\n consoleLogs: z.array(z.string()).optional(),\n consoleErrors: z.array(z.string()).optional(),\n networkRequests: z.array(z.object({ url: z.string(), method: z.string(), status: z.number().optional() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ url, screenshotPath, captureNetwork = true, captureConsole = true }) => {\n let playwright;\n try {\n playwright = await import(\"playwright\");\n } catch (e) {\n return {\n content: [{\n type: \"text\",\n text: \"Playwright não instalado. Rode: npm install playwright (ou npx playwright install para browsers).\",\n }],\n structuredContent: { ok: false, error: \"Playwright not installed. Run: npm install playwright\" },\n };\n }\n\n const outPath = screenshotPath ? path.join(PROJECT_ROOT, screenshotPath.replace(/^\\//, \"\")) : path.join(PROJECT_ROOT, \".qa-lab-screenshot.png\");\n const consoleLogs = [];\n const consoleErrors = [];\n const networkRequests = [];\n\n try {\n const browser = await playwright.chromium.launch({ headless: true });\n const context = await browser.newContext();\n const page = await context.newPage();\n\n if (captureConsole) {\n page.on(\"console\", (msg) => {\n const text = msg.text();\n if (msg.type() === \"error\") consoleErrors.push(text);\n else consoleLogs.push(`[${msg.type()}] ${text}`);\n });\n }\n\n if (captureNetwork) {\n page.on(\"request\", (req) => {\n networkRequests.push({ url: req.url(), method: req.method(), status: undefined });\n });\n page.on(\"response\", (res) => {\n const req = networkRequests.find((r) => r.url === res.request().url());\n if (req) req.status = res.status();\n });\n }\n\n await page.goto(url, { waitUntil: \"networkidle\", timeout: 30000 });\n await page.screenshot({ path: outPath, fullPage: false });\n\n await browser.close();\n\n const relPath = path.relative(PROJECT_ROOT, outPath);\n let summary = `Screenshot salvo: ${relPath}`;\n if (consoleErrors.length) summary += `\\n\\n⚠️ ${consoleErrors.length} erro(s) no console:\\n${consoleErrors.slice(0, 5).join(\"\\n\")}`;\n if (networkRequests.length) summary += `\\n\\nRequisições: ${networkRequests.length}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n screenshotPath: relPath,\n consoleLogs: captureConsole ? consoleLogs.slice(0, 50) : undefined,\n consoleErrors: captureConsole && consoleErrors.length ? consoleErrors : undefined,\n networkRequests: captureNetwork ? networkRequests.slice(0, 30) : undefined,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// QA ROUTE TASK - Agentes especializados (roteamento de tarefas)\n// ============================================================================\n\nconst QA_AGENTS = {\n autonomous: { tools: [\"qa_auto\"], desc: \"Modo autônomo: gera, roda, corrige e aprende (loop completo)\" },\n intelligence: { tools: [\"qa_full_analysis\", \"qa_health_check\", \"qa_suggest_next_test\", \"qa_predict_flaky\", \"qa_compare_with_industry\"], desc: \"Executor + Consultor: análise completa, diagnóstico, sugestões e predições\" },\n detection: { tools: [\"detect_project\", \"read_project\", \"list_test_files\"], desc: \"Detecção de estrutura, frameworks e arquivos\" },\n execution: { tools: [\"run_tests\", \"watch_tests\", \"get_test_coverage\"], desc: \"Execução de testes e cobertura\" },\n generation: { tools: [\"generate_tests\", \"write_test\", \"create_test_template\"], desc: \"Geração de testes com LLM\" },\n analysis: { tools: [\"analyze_failures\", \"por_que_falhou\", \"suggest_fix\", \"suggest_selector_fix\"], desc: \"Análise de falhas e sugestões\" },\n browser: { tools: [\"web_eval_browser\"], desc: \"Avaliação em browser real (screenshots, network, console)\" },\n reporting: { tools: [\"create_bug_report\", \"get_business_metrics\"], desc: \"Relatórios e métricas\" },\n learning: { tools: [\"qa_learning_stats\", \"qa_time_travel\"], desc: \"Estatísticas de aprendizado e evolução\" },\n maintenance: { tools: [\"run_linter\", \"install_dependencies\", \"analyze_file_methods\"], desc: \"Manutenção e análise de código\" },\n};\n\nserver.registerTool(\n \"qa_route_task\",\n {\n title: \"Roteador de tarefas QA (agentes especializados)\",\n description: \"Recebe uma descrição da tarefa e retorna qual agente (conjunto de ferramentas) deve ser usado. Útil para encaminhar a ferramenta certa.\",\n inputSchema: z.object({\n task: z.string().describe(\"Descrição da tarefa (ex: 'rodar os testes', 'gerar teste de login', 'analisar por que falhou').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestedAgent: z.string(),\n suggestedTools: z.array(z.string()),\n description: z.string(),\n }),\n },\n async ({ task }) => {\n const t = task.toLowerCase();\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: autonomous → qa_auto (loop completo: gera, roda, corrige, aprende)\" }], structuredContent: { ok: true, suggestedAgent: \"autonomous\", suggestedTools: QA_AGENTS.autonomous.tools, description: QA_AGENTS.autonomous.desc } };\n }\n if (/health|saúde|diagnóstico|nota|score|próximo teste|sugerir|prever|flaky|benchmark|comparar|indústria/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: intelligence → qa_health_check, qa_suggest_next_test, qa_predict_flaky, qa_compare_with_industry\" }], structuredContent: { ok: true, suggestedAgent: \"intelligence\", suggestedTools: QA_AGENTS.intelligence.tools, description: QA_AGENTS.intelligence.desc } };\n }\n if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats|evolução|timeline|tempo|histórico/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: learning → qa_learning_stats, qa_time_travel\" }], structuredContent: { ok: true, suggestedAgent: \"learning\", suggestedTools: QA_AGENTS.learning.tools, description: QA_AGENTS.learning.desc } };\n }\n if (/rodar|executar|run|test|coverage|watch/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: execution → run_tests, get_test_coverage\" }], structuredContent: { ok: true, suggestedAgent: \"execution\", suggestedTools: QA_AGENTS.execution.tools, description: QA_AGENTS.execution.desc } };\n }\n if (/gerar|criar|escrever|generate|write|template/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → generate_tests, write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: QA_AGENTS.generation.tools, description: QA_AGENTS.generation.desc } };\n }\n if (/analisar|por que|falhou|suggest|correção|selector|fix/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: analysis → analyze_failures, por_que_falhou, suggest_fix\" }], structuredContent: { ok: true, suggestedAgent: \"analysis\", suggestedTools: QA_AGENTS.analysis.tools, description: QA_AGENTS.analysis.desc } };\n }\n if (/browser|screenshot|navegador|avaliar|ux|network|console/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: browser → web_eval_browser\" }], structuredContent: { ok: true, suggestedAgent: \"browser\", suggestedTools: QA_AGENTS.browser.tools, description: QA_AGENTS.browser.desc } };\n }\n if (/detectar|estrutura|listar|arquivos|framework/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: detection → detect_project, list_test_files\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n if (/relatório|bug|métricas|metrics/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: reporting → create_bug_report, get_business_metrics\" }], structuredContent: { ok: true, suggestedAgent: \"reporting\", suggestedTools: QA_AGENTS.reporting.tools, description: QA_AGENTS.reporting.desc } };\n }\n return { content: [{ type: \"text\", text: \"Agente: detection (genérico)\" }], structuredContent: { ok: true, suggestedAgent: \"detection\", suggestedTools: QA_AGENTS.detection.tools, description: QA_AGENTS.detection.desc } };\n }\n);\n\nserver.registerTool(\n \"run_tests\",\n {\n title: \"Executar testes\",\n description: \"Roda testes do projeto. Suporta: Cypress, Playwright, WebdriverIO, Jest, Vitest, Mocha, Appium, Detox, Robot Framework, pytest, e mais. Detecta automaticamente.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"supertest\", \"pactum\",\n \"testcafe\", \"nightwatch\", \"puppeteer\", \"codeceptjs\", \"npm\"\n ]).optional().describe(\"Framework específico ou 'npm' para npm test.\"),\n spec: z.string().optional().describe(\"Caminho do spec (ex: cypress/e2e/test.cy.js).\"),\n suite: z.string().optional().describe(\"Suite ou pattern (ex: e2e, api).\"),\n explainOnFailure: z.boolean().optional().describe(\"Se true, quando falhar gera automaticamente: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção. Requer API key.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n runOutput: z.string().optional(),\n }),\n },\n async ({ framework, spec, suite, explainOnFailure }) => {\n const structure = detectProjectStructure();\n \n if (!structure.hasTests) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado no projeto.\" }],\n structuredContent: {\n status: \"not_found\",\n message: \"No test framework found\",\n exitCode: 1,\n },\n };\n }\n\n let selectedFramework = framework;\n if (!selectedFramework && structure.testFrameworks.length > 0) {\n selectedFramework = structure.testFrameworks[0];\n }\n\n let cmd, args, cwd;\n\n // E2E/UI Frameworks\n if (selectedFramework === \"cypress\") {\n cmd = \"npx\";\n args = spec ? [\"cypress\", \"run\", \"--spec\", spec] : [\"cypress\", \"run\"];\n cwd = structure.testDirs.includes(\"cypress\") \n ? path.join(PROJECT_ROOT, \"cypress\")\n : structure.testDirs[0] \n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"playwright\") {\n cmd = \"npx\";\n args = spec ? [\"playwright\", \"test\", spec] : [\"playwright\", \"test\"];\n cwd = structure.testDirs.includes(\"playwright\")\n ? path.join(PROJECT_ROOT, \"playwright\")\n : structure.testDirs[0]\n ? path.join(PROJECT_ROOT, structure.testDirs[0])\n : PROJECT_ROOT;\n } else if (selectedFramework === \"webdriverio\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"wdio-webdriver-io\", \"specs\", \"tests\"]);\n } else if (selectedFramework === \"testcafe\") {\n cmd = \"npx\";\n args = spec ? [\"testcafe\", spec] : [\"testcafe\"];\n cwd = getFrameworkCwd(structure, [\"testcafe-js\", \"testcafe\", \"tests\"]);\n } else if (selectedFramework === \"nightwatch\") {\n cmd = \"npx\";\n args = spec ? [\"nightwatch\", \"--test\", spec] : [\"nightwatch\"];\n cwd = getFrameworkCwd(structure, [\"nightwatch-js\", \"nightwatch\", \"tests\"]);\n } else if (selectedFramework === \"puppeteer\") {\n cmd = \"npx\";\n args = spec ? [\"jest\", spec, \"--config\", \"jest.config.js\"] : [\"jest\"];\n cwd = getFrameworkCwd(structure, [\"puppeteer-js\", \"puppeteer\", \"__tests__\"]);\n } else if (selectedFramework === \"codeceptjs\") {\n cmd = \"npx\";\n args = spec ? [\"codeceptjs\", \"run\", \"--grep\", spec] : [\"codeceptjs\", \"run\"];\n cwd = getFrameworkCwd(structure, [\"codeceptjs\", \"tests\"]);\n\n // Unit/Integration Frameworks\n } else if (selectedFramework === \"jest\") {\n cmd = \"npx\";\n args = [\"jest\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"vitest\") {\n cmd = \"npx\";\n args = [\"vitest\", \"run\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"mocha\") {\n cmd = \"npx\";\n args = spec ? [\"mocha\", spec] : [\"mocha\"];\n cwd = PROJECT_ROOT;\n \n // Mobile Frameworks\n } else if (selectedFramework === \"appium\") {\n cmd = \"npx\";\n args = spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"detox\") {\n cmd = \"npx\";\n args = [\"detox\", \"test\"];\n if (spec) args.push(spec);\n cwd = PROJECT_ROOT;\n \n // Python Frameworks\n } else if (selectedFramework === \"robot\") {\n cmd = \"robot\";\n args = spec ? [spec] : [structure.testDirs[0] || \"tests\"];\n cwd = PROJECT_ROOT;\n } else if (selectedFramework === \"pytest\") {\n cmd = \"pytest\";\n args = spec ? [spec] : [];\n cwd = PROJECT_ROOT;\n \n // API Testing\n } else if (selectedFramework === \"supertest\" || selectedFramework === \"pactum\") {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n \n // Fallback\n } else {\n cmd = \"npm\";\n args = [\"test\"];\n cwd = PROJECT_ROOT;\n }\n\n const startTime = Date.now();\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) {\n child.stdout.on(\"data\", (d) => {\n const s = d.toString();\n stdout += s;\n process.stdout.write(s);\n });\n }\n if (child.stderr) {\n child.stderr.on(\"data\", (d) => {\n const s = d.toString();\n stderr += s;\n process.stderr.write(s);\n });\n }\n\n child.on(\"close\", (code) => {\n const runOutput = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n const durationSeconds = Math.round((Date.now() - startTime) / 1000);\n if (!passed && runOutput) {\n try {\n fs.writeFileSync(path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\"), runOutput, \"utf8\");\n } catch {}\n }\n const { passed: p, failed: f } = parseTestRunResult(runOutput, code);\n appendMetricsEvent({\n type: \"test_run\",\n framework: selectedFramework,\n spec: spec || undefined,\n passed: p,\n failed: f,\n durationSeconds,\n exitCode: code ?? 1,\n failures: !passed ? extractFailuresFromOutput(runOutput) : undefined,\n });\n if (passed) saveProjectMemory({ lastRun: { spec: spec || null, framework: selectedFramework, passed: p } });\n \n saveProjectMemory({\n execution: {\n testFile: spec || \"all\",\n passed,\n duration: durationSeconds,\n timestamp: new Date().toISOString(),\n framework: selectedFramework,\n },\n });\n \n resolve({\n content: [{ type: \"text\", text: passed ? \"Testes executados com sucesso.\" : \"Falha na execução dos testes.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Tests passed\" : \"Tests failed\",\n exitCode: code ?? 1,\n runOutput: !passed ? runOutput : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"read_project\",\n {\n title: \"Ler estrutura do projeto\",\n description: \"Lê package.json, specs existentes (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, etc) e retorna contexto. Use includeContent para trazer código de exemplos.\",\n inputSchema: z.object({\n includeContent: z.boolean().optional().describe(\"Se true, inclui conteúdo dos primeiros 3 arquivos de teste como referência. Default: false.\"),\n maxFiles: z.number().optional().describe(\"Máximo de arquivos cujo conteúdo será lido. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n packageJson: z.object({}).passthrough().optional(),\n testFiles: z.array(z.string()).optional(),\n testFilesWithContent: z.array(z.object({ path: z.string(), content: z.string() })).optional(),\n }),\n },\n async ({ includeContent = false, maxFiles = 3 } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, {\n maxContentFiles: includeContent ? maxFiles : 0,\n });\n\n const testFiles = collected.map((e) => e.path);\n const testFilesWithContent = includeContent\n ? collected.filter((e) => e.content).map((e) => ({ path: e.path, content: e.content }))\n : undefined;\n\n const summary = [\n `Frameworks: ${structure.testFrameworks.join(\", \") || \"nenhum\"}`,\n `Arquivos de teste: ${testFiles.length} (qualquer framework)`,\n `Backend: ${structure.backendDir || \"não detectado\"}`,\n `Frontend: ${structure.frontendDir || \"não detectado\"}`,\n includeContent && testFilesWithContent?.length\n ? `Conteúdo incluído: ${testFilesWithContent.length} arquivo(s) como referência`\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n packageJson: structure.packageJson,\n testFiles: testFiles.slice(0, 100),\n testFilesWithContent,\n structure,\n },\n };\n }\n);\n\nserver.registerTool(\n \"generate_tests\",\n {\n title: \"Gerar ou traduzir testes com LLM\",\n description: \"Gera spec em QUALQUER framework. Aceita referência de outro framework: leia com read_file e passe em referenceCode. Traduz automaticamente (ex: Robot→Playwright, Cypress→WDIO).\",\n inputSchema: z.object({\n context: z.string().describe(\"Contexto do projeto (read_project) ou descrição.\"),\n request: z.string().describe(\"O que testar (ex: 'logout flow', 'teste de login') ou 'traduzir o teste abaixo'.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\",\n \"appium\", \"robot\", \"pytest\", \"supertest\", \"behave\", \"detox\"\n ]).optional().describe(\"Framework alvo (detectado do projeto se omitido).\"),\n referenceCode: z.string().optional().describe(\"Código de referência em QUALQUER framework (Cypress, Robot, WDIO, etc). O LLM traduz/adapta para o framework alvo.\"),\n referencePaths: z.array(z.string()).optional().describe(\"Caminhos de arquivos para ler como referência. O agente lê e usa como padrão.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n specContent: z.string().optional(),\n suggestedFileName: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ context, request, framework, referenceCode, referencePaths }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0] || \"cypress\";\n\n let referenceBlock = \"\";\n if (referenceCode) referenceBlock += `\\n\\n--- CÓDIGO DE REFERÊNCIA (use como padrão, traduza/adapte para ${fw}) ---\\n${referenceCode.slice(0, 8000)}`;\n if (referencePaths?.length) {\n for (const p of referencePaths.slice(0, 5)) {\n const full = path.join(PROJECT_ROOT, p.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(full)) {\n try {\n const content = fs.readFileSync(full, \"utf8\");\n referenceBlock += `\\n\\n--- Arquivo: ${p} ---\\n${content.slice(0, 6000)}`;\n } catch {}\n }\n }\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const memory = loadProjectMemory();\n const memoryBlock = memory.flows?.length\n ? `\\n\\nFluxos do projeto (use como referência): ${memory.flows.map((f) => f.name || f.id).join(\", \")}`\n : \"\";\n const contextWithMemory = context + memoryBlock;\n\n const hasReference = Boolean(referenceBlock?.trim());\n const systemPrompt = hasReference\n ? `Você é um engenheiro de QA. TRADUZA/ADAPTE o código de referência para o framework ${fw}.\nO código de referência pode estar em QUALQUER framework (Cypress, Robot, Playwright, WDIO, Appium, pytest, etc).\n- Mantenha a MESMA lógica e fluxo de teste\n- Traduza seletores, comandos e asserções para ${fw}\n- Use Page Objects se o projeto já usa\n- Retorne SOMENTE o código, sem markdown`\n : `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\nFramework: ${fw}\nRegras:\n- Cypress: cy.request(), cy.visit(), cy.get()\n- Playwright: test(), test.describe(), page.goto(), page.locator()\n- WebdriverIO/Appium: describe(), it(), $(), browser.$\n- Jest/Vitest: describe(), test(), expect()\n- Robot: Keywords, [Tags], Steps\n- pytest: def test_*, assert, fixtures\n- Código limpo. Retorne SOMENTE o código, sem markdown`;\n\n const userPrompt = `Contexto do projeto:\n${contextWithMemory.slice(0, 5000)}\n\nGere um teste para: ${request}\nFramework alvo: ${fw}${referenceBlock}`;\n\n try {\n let specContent;\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n systemInstruction: { parts: [{ text: systemPrompt }] },\n contents: [{ parts: [{ text: userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n\n specContent = specContent.replace(/^```(?:js|javascript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 40);\n\n return {\n content: [{ type: \"text\", text: `Spec gerado (${specContent.length} chars). Use write_test para gravar.` }],\n structuredContent: {\n ok: true,\n specContent,\n suggestedFileName: fileName,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gerar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nfunction getExtensionAndBaseDir(fw, structure) {\n const extMap = {\n cypress: \".cy.js\",\n playwright: \".spec.js\",\n jest: \".test.js\",\n vitest: \".test.js\",\n mocha: \".test.js\",\n webdriverio: \".spec.js\",\n appium: \".spec.js\",\n detox: \".e2e.js\",\n robot: \".robot\",\n pytest: \"_test.py\",\n behave: \".feature\",\n supertest: \".test.js\",\n pactum: \".test.js\",\n };\n const ext = extMap[fw] || \".spec.js\";\n\n const baseMap = {\n cypress: structure.testDirs.includes(\"cypress\") ? \"cypress\" : structure.testDirs[0] || \"tests\",\n playwright: structure.testDirs.includes(\"playwright\") ? \"playwright\" : structure.testDirs[0] || \"tests\",\n webdriverio: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n appium: structure.testDirs.includes(\"specs\") ? \"specs\" : structure.testDirs[0] || \"tests\",\n robot: structure.testDirs.includes(\"robot\") ? \"robot\" : structure.testDirs[0] || \"tests\",\n behave: structure.testDirs.includes(\"features\") ? \"features\" : structure.testDirs[0] || \"tests\",\n };\n const baseDir = path.join(PROJECT_ROOT, baseMap[fw] || structure.testDirs[0] || \"tests\");\n return { ext, baseDir };\n}\n\nserver.registerTool(\n \"write_test\",\n {\n title: \"Escrever arquivo de teste\",\n description: \"Grava spec no disco. Suporta QUALQUER framework (Cypress, Playwright, WDIO, Appium, Robot, pytest, etc.). Detecta automaticamente pasta e extensão.\",\n inputSchema: z.object({\n name: z.string().describe(\"Nome do arquivo (ex: login-test, logout_spec).\"),\n content: z.string().describe(\"Conteúdo do spec.\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"vitest\", \"mocha\", \"webdriverio\",\n \"appium\", \"detox\", \"robot\", \"pytest\", \"behave\", \"supertest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n subdir: z.string().optional().describe(\"Subpasta (ex: e2e, api). Default: raiz da pasta de testes.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n path: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ name, content, framework, subdir }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework de teste detectado.\" }],\n structuredContent: { ok: false, error: \"No test framework\" },\n };\n }\n\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = name\n .replace(/[^a-z0-9-_]/gi, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/_+/g, \"_\")\n .replace(/\\.(cy|spec|test|robot|feature|py)\\.?(js|ts|py)?$/i, \"\")\n .replace(/^[-_]+|[-_]+$/g, \"\");\n const fileName = ext.startsWith(\"_\") ? `${safeName}${ext}` : `${safeName}${ext}`;\n\n const targetDir = subdir ? path.join(baseDir, subdir) : baseDir;\n const filePath = path.join(targetDir, fileName);\n\n try {\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n fs.writeFileSync(filePath, content, \"utf8\");\n return {\n content: [{ type: \"text\", text: `Arquivo gravado: ${filePath}` }],\n structuredContent: { ok: true, path: filePath },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao gravar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_failures\",\n {\n title: \"Analisar falhas de testes\",\n description: \"Recebe output de testes e extrai falhas estruturadas.\",\n inputSchema: z.object({\n runOutput: z.string().describe(\"Output do teste (stdout/stderr).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n summary: z.string(),\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).optional(),\n }),\n },\n async ({ runOutput }) => {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion/i.test(line)) {\n failures.push({\n test: lines[i - 1] || \"unknown\",\n message: line.trim(),\n stack: lines.slice(i, i + 5).join(\"\\n\"),\n });\n }\n }\n\n const flakyAnalysis = detectFlakyPatterns(runOutput);\n let summary = failures.length\n ? `${failures.length} falha(s) detectada(s).`\n : \"Nenhuma falha detectada.\";\n if (flakyAnalysis.isLikelyFlaky) {\n summary += `\\n\\n⚠️ Possível teste flaky (${Math.round(flakyAnalysis.confidence * 100)}% confiança). Padrões: ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}.`;\n summary += \"\\n\\nSugestões:\";\n flakyAnalysis.patterns.forEach((p) => {\n summary += `\\n• ${p.pattern}: ${p.suggestion}`;\n });\n if (flakyAnalysis.patterns.some((p) => p.pattern === \"timing\" || p.pattern === \"network\")) {\n summary += \"\\n• Considere adicionar test.retry(2) ou equivalente para retries automáticos.\";\n }\n }\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n ok: true,\n summary,\n failures: failures.length ? failures : undefined,\n flaky: flakyAnalysis.isLikelyFlaky ? { confidence: flakyAnalysis.confidence, patterns: flakyAnalysis.patterns } : undefined,\n },\n };\n }\n);\n\n// ============================================================================\n// POR QUE FALHOU? - Explicação de falhas para juniores (escalável)\n// ============================================================================\n\nfunction formatFailureExplanation(data) {\n const lines = [\n \"## O que aconteceu\",\n \"\",\n data.oQueAconteceu || \"\",\n \"\",\n \"## Por que provavelmente falhou\",\n \"\",\n ...(Array.isArray(data.porQueProvavelmenteFalhou)\n ? data.porQueProvavelmenteFalhou.map((s) => `• ${s}`)\n : [data.porQueProvavelmenteFalhou || \"\"]),\n \"\",\n \"## O que fazer agora\",\n \"\",\n ...(Array.isArray(data.oQueFazerAgora)\n ? data.oQueFazerAgora.map((s, i) => `${i + 1}. ${s}`)\n : [data.oQueFazerAgora || \"\"]),\n ];\n if (data.sugestaoCorrecao) {\n lines.push(\"\", \"## Sugestão de correção\", \"\", \"```\" + (data.framework || \"js\"), data.sugestaoCorrecao, \"```\");\n }\n if (data.conceito) {\n lines.push(\"\", \"## Conceito\", \"\", data.conceito);\n }\n return lines.filter(Boolean).join(\"\\n\");\n}\n\nasync function callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt) {\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.2, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n }\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0.2,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n return data.choices?.[0]?.message?.content || \"\";\n}\n\n/** Gera explicação de falha (o que aconteceu, por que, o que fazer, sugestão). Usado por por_que_falhou e run_tests_and_explain. */\n\nserver.registerTool(\n \"por_que_falhou\",\n {\n title: \"Por que falhou? Explicação para juniores\",\n description: \"Traduz stack trace em explicação humana. Recebe output do terminal/log, lê o projeto e o teste (se path dado), e retorna: O que aconteceu, Por que falhou, O que fazer, Sugestão de correção, Conceito. Escalável e procedural.\",\n inputSchema: z.object({\n errorOutput: z.string().optional().describe(\"Output do terminal quando o teste falhou. Se vazio, lê automaticamente de .qa-lab-last-failure.log (capturado pelo run_tests). Cole aqui ou deixe vazio para usar última falha.\"),\n testFilePath: z.string().optional().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js). Se informado, o agente lê o código e dá sugestão mais precisa.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n oQueAconteceu: z.string().optional(),\n porQueProvavelmenteFalhou: z.array(z.string()).optional(),\n oQueFazerAgora: z.array(z.string()).optional(),\n sugestaoCorrecao: z.string().optional(),\n conceito: z.string().optional(),\n framework: z.string().optional(),\n formattedText: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ errorOutput, testFilePath }) => {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\n\n let resolvedOutput = errorOutput?.trim() || \"\";\n if (!resolvedOutput) {\n const lastFailurePath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(lastFailurePath)) {\n try {\n resolvedOutput = fs.readFileSync(lastFailurePath, \"utf8\");\n } catch {}\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{\n type: \"text\",\n text: \"Nenhum output de erro fornecido e nenhuma falha recente capturada.\\n\\nComo usar:\\n1. Rode os testes (run_tests) – se falhar, a saída é salva automaticamente.\\n2. Ou cole aqui o output do terminal quando o teste falhou.\\n3. Depois peça: 'Por que falhou?' ou chame por_que_falhou.\",\n }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n let testCode = \"\";\n if (testFilePath) {\n const normalized = testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n if (fs.existsSync(fullPath) && !fs.statSync(fullPath).isDirectory()) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env do projeto para usar a explicação com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n webdriverio: \"WebdriverIO (describe/it, $, browser.$)\",\n appium: \"Appium/WebdriverIO (mobile, $, browser.$)\",\n playwright: \"Playwright (test, page, locator)\",\n cypress: \"Cypress (cy.get, cy.click)\",\n jest: \"Jest (describe, test, expect)\",\n vitest: \"Vitest (describe, test, expect)\",\n robot: \"Robot Framework\",\n pytest: \"pytest\",\n };\n\n const systemPrompt = `Você é um mentor de QA. Analise o output de falha e responda em JSON (apenas o JSON, sem markdown) com as chaves:\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas, uma por item)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção se aplicável, no formato do framework)\n- conceito: string ou null (ex: \"Flaky test = teste intermitente. Geralmente por timing ou seletores frágeis.\")\n- framework: string (framework do projeto)\n\nFramework do projeto: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste que falhou:\\n---\\n${testCode.slice(0, 6000)}\\n---` : \"\"}`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear a resposta.\",\n porQueProvavelmenteFalhou: [],\n oQueFazerAgora: [],\n sugestaoCorrecao: null,\n conceito: null,\n framework: fw,\n };\n }\n\n data.framework = data.framework || fw;\n const formattedText = formatFailureExplanation(data);\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n oQueAconteceu: data.oQueAconteceu,\n porQueProvavelmenteFalhou: data.porQueProvavelmenteFalhou,\n oQueFazerAgora: data.oQueFazerAgora,\n sugestaoCorrecao: data.sugestaoCorrecao ?? null,\n conceito: data.conceito ?? null,\n framework: data.framework,\n formattedText,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n// ============================================================================\n// NOVAS FERRAMENTAS\n// ============================================================================\n\nserver.registerTool(\n \"suggest_fix\",\n {\n title: \"Sugerir correção para falhas\",\n description: \"Recebe análise de falhas e sugere correções (patch, refactor, etc.).\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Resultado de analyze_failures.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n suggestions: z.array(z.object({\n test: z.string().optional(),\n description: z.string(),\n fix: z.string().optional(),\n })),\n }),\n },\n async ({ failures }) => {\n const suggestions = [];\n\n for (const f of failures) {\n const msg = f.message || \"\";\n \n if (/element not found|selector|timeout/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Elemento não encontrado ou timeout\",\n fix: \"Verifique seletores, adicione waits ou aumente timeout. Use data-testid para seletores mais estáveis.\",\n });\n } else if (/expected.*to.*but/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Asserção falhou\",\n fix: \"Revise o valor esperado. Verifique se o estado da aplicação está correto antes da asserção.\",\n });\n } else if (/network|fetch|ECONNREFUSED/i.test(msg)) {\n suggestions.push({\n test: f.test,\n description: \"Erro de rede ou API não disponível\",\n fix: \"Verifique se o backend está rodando. Confirme a URL e porta da API.\",\n });\n } else {\n suggestions.push({\n test: f.test,\n description: \"Falha detectada\",\n fix: \"Revise o stack trace e o código do teste.\",\n });\n }\n }\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(suggestions, null, 2) }],\n structuredContent: { ok: true, suggestions },\n };\n }\n);\n\n// ============================================================================\n// SELF-HEALING - Sugestão de correção de seletores quando UI muda\n// ============================================================================\n\nserver.registerTool(\n \"suggest_selector_fix\",\n {\n title: \"Sugerir correção de seletor (Self-healing)\",\n description: \"Quando um teste falha por elemento não encontrado (seletor quebrado após mudança de UI), usa LLM para sugerir seletor alternativo mais resiliente. Prioriza data-testid, role, texto acessível.\",\n inputSchema: z.object({\n testFilePath: z.string().describe(\"Caminho do arquivo de teste que falhou (ex: specs/login.spec.js).\"),\n errorOutput: z.string().optional().describe(\"Output do terminal da falha. Se vazio, lê de .qa-lab-last-failure.log.\"),\n framework: z.enum([\"cypress\", \"playwright\", \"webdriverio\", \"appium\"]).optional().describe(\"Framework do teste. Detectado automaticamente se omitido.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n selectorSugerido: z.string().optional(),\n codigoCorrigido: z.string().optional(),\n explicacao: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ testFilePath, errorOutput, framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || inferFrameworkFromFile(testFilePath.split(\"/\").pop(), structure);\n\n let resolvedOutput = errorOutput;\n if (!resolvedOutput) {\n const logPath = path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\");\n if (fs.existsSync(logPath)) {\n resolvedOutput = fs.readFileSync(logPath, \"utf8\");\n }\n }\n if (!resolvedOutput) {\n return {\n content: [{ type: \"text\", text: \"Nenhum output de erro. Rode os testes primeiro ou forneça errorOutput.\" }],\n structuredContent: { ok: false, error: \"No error output\" },\n };\n }\n\n if (!/element not found|selector|timeout|locator|cy\\.get|page\\.locator/i.test(resolvedOutput)) {\n return {\n content: [{ type: \"text\", text: \"A falha não parece ser de seletor/elemento. Use por_que_falhou ou suggest_fix para outros tipos de falha.\" }],\n structuredContent: { ok: false, error: \"Not a selector-related failure\" },\n };\n }\n\n let testCode = \"\";\n const fullPath = path.join(PROJECT_ROOT, testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(fullPath)) {\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {}\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const fwHints = {\n cypress: \"Cypress: cy.get('[data-testid=...]'), cy.contains(), cy.get('button').filter(':visible')\",\n playwright: \"Playwright: page.getByRole(), page.getByTestId(), page.locator('button:has-text(\\\"...\\\")')\",\n webdriverio: \"WebdriverIO: $('[data-testid=...]'), $('button=Texto')\",\n appium: \"Appium: $('~accessibility-id'), $('//android.view.View')\",\n };\n\n const systemPrompt = `Você é um especialista em testes E2E. O teste falhou porque um seletor não encontrou o elemento (UI mudou).\nAnalise o erro e o código e responda APENAS em JSON (sem markdown) com as chaves:\n- selectorSugerido: string (o novo seletor recomendado, mais resiliente)\n- codigoCorrigido: string (bloco de código completo corrigido, apenas a parte relevante do teste)\n- explicacao: string (breve explicação em português: por que o antigo falhou e por que o novo é melhor)\n\nPriorize nesta ordem: data-testid > role + accessible name > texto visível > estrutura. Evite classes CSS e IDs que mudam.\n\nFramework: ${fw}. ${fwHints[fw] || \"\"}`;\n\n const userPrompt = `Output do erro:\n---\n${resolvedOutput.slice(0, 8000)}\n---\nCódigo do teste:\n---\n${testCode ? testCode.slice(0, 6000) : \"Não disponível\"}\n---`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n selectorSugerido: null,\n codigoCorrigido: raw.slice(0, 2000),\n explicacao: \"Não foi possível parsear. Resposta do LLM acima.\",\n };\n }\n\n const text = [\n data.explicacao && `## Explicação\\n${data.explicacao}`,\n data.selectorSugerido && `## Seletor sugerido\\n\\`${data.selectorSugerido}\\``,\n data.codigoCorrigido && `## Código corrigido\\n\\`\\`\\`${fw}\\n${data.codigoCorrigido}\\n\\`\\`\\``,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return {\n content: [{ type: \"text\", text: text || JSON.stringify(data, null, 2) }],\n structuredContent: {\n ok: true,\n selectorSugerido: data.selectorSugerido,\n codigoCorrigido: data.codigoCorrigido,\n explicacao: data.explicacao,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao chamar LLM: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\nserver.registerTool(\n \"analyze_file_methods\",\n {\n title: \"Analisar métodos de um arquivo\",\n description: \"Lê um arquivo, faz varredura em todos os métodos/funções e retorna análise detalhada: método correto?, melhor forma de escrever?, falso positivo?, coerência?, itens faltando?, parâmetros faltando?, imports faltando?. Requer API key (Groq/Gemini/OpenAI).\",\n inputSchema: z.object({\n path: z.string().describe(\"Caminho do arquivo (ex: src/utils.js, tests/login.cy.js, cypress/support/commands.js).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n filePath: z.string().optional(),\n methods: z.array(z.object({\n name: z.string(),\n correto: z.boolean().optional(),\n melhorForma: z.string().optional(),\n falsoPositivo: z.boolean().optional(),\n falsoPositivoRazao: z.string().optional(),\n coerente: z.boolean().optional(),\n itensFaltando: z.array(z.string()).optional(),\n parametrosFaltando: z.array(z.string()).optional(),\n importsFaltando: z.array(z.string()).optional(),\n sugestao: z.string().optional(),\n })).optional(),\n importsFaltandoGlobal: z.array(z.string()).optional(),\n resumo: z.string().optional(),\n error: z.string().optional(),\n }),\n },\n async ({ path: filePath }) => {\n const normalized = filePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\");\n const fullPath = path.join(PROJECT_ROOT, normalized);\n\n if (!fullPath.startsWith(PROJECT_ROOT)) {\n return {\n content: [{ type: \"text\", text: \"Caminho fora do projeto.\" }],\n structuredContent: { ok: false, error: \"Path outside project\" },\n };\n }\n if (!fs.existsSync(fullPath)) {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${normalized}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n const stat = fs.statSync(fullPath);\n if (stat.isDirectory()) {\n return {\n content: [{ type: \"text\", text: \"É um diretório. Informe um arquivo.\" }],\n structuredContent: { ok: false, error: \"Is directory\" },\n };\n }\n\n let fileContent = \"\";\n try {\n fileContent = fs.readFileSync(fullPath, \"utf8\");\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) {\n return {\n content: [{\n type: \"text\",\n text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env para usar análise com LLM.\",\n }],\n structuredContent: { ok: false, error: \"No API key configured\" },\n };\n }\n const { provider, apiKey, baseUrl, model } = llm;\n\n const ext = path.extname(fullPath).toLowerCase();\n const lang = [\".ts\", \".tsx\"].includes(ext) ? \"TypeScript\" : [\".js\", \".jsx\"].includes(ext) ? \"JavaScript\" : [\".py\"].includes(ext) ? \"Python\" : \"código\";\n\n const systemPrompt = `Você é um revisor de código experiente em QA e testes. Analise o arquivo e cada método/função, respondendo em JSON válido (sem markdown) com a estrutura:\n\n{\n \"methods\": [\n {\n \"name\": \"nomeDoMetodo\",\n \"correto\": true | false,\n \"melhorForma\": \"explicação curta se há forma melhor de escrever\",\n \"falsoPositivo\": true | false,\n \"falsoPositivoRazao\": \"se falso positivo, por quê (ex: asserção muito permissiva)\",\n \"coerente\": true | false,\n \"coerenteDetalhe\": \"se incoerente, o que está inconsistente\",\n \"itensFaltando\": [\"item1\", \"item2\"],\n \"parametrosFaltando\": [\"param1\"],\n \"importsFaltando\": [\"moduloX\"],\n \"sugestao\": \"código ou texto de sugestão de melhoria\"\n }\n ],\n \"importsFaltandoGlobal\": [\"imports faltando no topo do arquivo\"],\n \"resumo\": \"resumo geral em 2-3 linhas\"\n}\n\nPara CADA método/função no arquivo, verifique:\n1. correto: a lógica está correta?\n2. melhorForma: há forma mais legível, performática ou idiomática de escrever?\n3. falsoPositivo: o método pode passar quando não deveria (asserção fraca, mock incorreto)?\n4. coerente: o método é coerente com o restante do código, naming, padrões?\n5. itensFaltando: falta try/catch, validação, cleanup, etc?\n6. parametrosFaltando: parâmetros que deveriam existir?\n7. importsFaltando: imports que o método usa mas não estão declarados?\n\nResponda APENAS com o JSON válido. Linguagem: ${lang}.`;\n\n const userPrompt = `Arquivo: ${normalized}\n\n\\`\\`\\`${lang}\n${fileContent.slice(0, 18000)}\n\\`\\`\\`\n\nAnalise cada método/função e retorne o JSON conforme especificado.`;\n\n try {\n let raw = await callLlmForExplanation(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n\n let data = {};\n try {\n data = JSON.parse(raw);\n } catch {\n data = {\n methods: [],\n importsFaltandoGlobal: [],\n resumo: raw.slice(0, 1000) || \"Não foi possível parsear a resposta do LLM.\",\n };\n }\n\n const lines = [\n `# Análise de métodos: ${normalized}`,\n \"\",\n data.resumo && `## Resumo\\n${data.resumo}`,\n data.importsFaltandoGlobal?.length > 0\n ? `\\n## Imports faltando (global)\\n${data.importsFaltandoGlobal.map((i) => `- ${i}`).join(\"\\n\")}`\n : \"\",\n \"\\n## Métodos analisados\\n\",\n ];\n\n for (const m of data.methods || []) {\n lines.push(`### ${m.name}`);\n lines.push(\"\");\n if (m.correto !== undefined) lines.push(`- **Correto:** ${m.correto ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.melhorForma) lines.push(`- **Melhor forma:** ${m.melhorForma}`);\n if (m.falsoPositivo) lines.push(`- **Falso positivo:** ⚠️ Sim - ${m.falsoPositivoRazao || \"verificar\"}`);\n if (m.coerente !== undefined) lines.push(`- **Coerente:** ${m.coerente ? \"✅ Sim\" : \"❌ Não\"}`);\n if (m.itensFaltando?.length) lines.push(`- **Itens faltando:** ${m.itensFaltando.join(\", \")}`);\n if (m.parametrosFaltando?.length) lines.push(`- **Parâmetros faltando:** ${m.parametrosFaltando.join(\", \")}`);\n if (m.importsFaltando?.length) lines.push(`- **Imports faltando:** ${m.importsFaltando.join(\", \")}`);\n if (m.sugestao) lines.push(`\\n**Sugestão:**\\n\\`\\`\\`\\n${m.sugestao}\\n\\`\\`\\``);\n lines.push(\"\");\n }\n\n const formattedText = lines.filter(Boolean).join(\"\\n\");\n\n return {\n content: [{ type: \"text\", text: formattedText }],\n structuredContent: {\n ok: true,\n filePath: normalized,\n methods: data.methods || [],\n importsFaltandoGlobal: data.importsFaltandoGlobal || [],\n resumo: data.resumo,\n },\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n }\n);\n\n\nserver.registerTool(\n \"create_bug_report\",\n {\n title: \"Criar relatório de bug\",\n description: \"Gera um bug report estruturado a partir de falhas de teste.\",\n inputSchema: z.object({\n failures: z.array(z.object({\n test: z.string().optional(),\n message: z.string().optional(),\n stack: z.string().optional(),\n })).describe(\"Falhas (de analyze_failures).\"),\n title: z.string().optional().describe(\"Título do bug.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n report: z.string(),\n title: z.string(),\n }),\n },\n async ({ failures, title }) => {\n const bugTitle = title || `Falha em ${failures.length} teste(s)`;\n const lines = [\n `# ${bugTitle}`,\n \"\",\n \"## Resumo\",\n \"\",\n `${failures.length} teste(s) falharam durante a execução.`,\n \"\",\n \"## Falhas detectadas\",\n \"\",\n ];\n\n failures.forEach((f, i) => {\n lines.push(`### ${i + 1}. ${f.test || \"Teste desconhecido\"}`);\n lines.push(\"\");\n lines.push(`**Mensagem:** ${f.message || \"N/A\"}`);\n lines.push(\"\");\n if (f.stack) {\n lines.push(\"**Stack trace:**\");\n lines.push(\"```\");\n lines.push(f.stack);\n lines.push(\"```\");\n lines.push(\"\");\n }\n });\n\n lines.push(\"## Próximos passos\");\n lines.push(\"\");\n lines.push(\"- [ ] Reproduzir localmente\");\n lines.push(\"- [ ] Identificar causa raiz\");\n lines.push(\"- [ ] Aplicar correção\");\n lines.push(\"- [ ] Validar com testes\");\n\n const report = lines.join(\"\\n\");\n\n appendMetricsEvent({ type: \"bug_reported\", failuresCount: failures.length, title: bugTitle });\n\n return {\n content: [{ type: \"text\", text: report }],\n structuredContent: { ok: true, report, title: bugTitle },\n };\n }\n);\n\n// ============================================================================\n// MÉTRICAS DE NEGÓCIO - Relatório agregado\n// ============================================================================\n\nserver.registerTool(\n \"get_business_metrics\",\n {\n title: \"Obter métricas de negócio\",\n description: \"Retorna métricas: tempo até bug, custo por defeito (tempo estimado), cobertura por fluxo. Requer run_tests executados e opcionalmente qa-lab-flows.json.\",\n inputSchema: z.object({\n period: z.enum([\"7d\", \"30d\", \"all\"]).optional().describe(\"Período para analisar. Default: 30d.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n timeToBug: z.object({\n avgHours: z.number(),\n lastFailureAt: z.string().optional(),\n runsWithFailures: z.number(),\n }).optional(),\n costPerDefect: z.object({\n avgMinutesPerDefect: z.number(),\n totalFailures: z.number(),\n estimatedHoursSpent: z.number(),\n }).optional(),\n flowCoverage: z.object({\n totalFlows: z.number(),\n coveredFlows: z.number(),\n percent: z.number(),\n details: z.array(z.object({ flow: z.string(), covered: z.boolean() })),\n }).optional(),\n summary: z.string(),\n }),\n },\n async ({ period = \"30d\" } = {}) => {\n const now = Date.now();\n const msByPeriod = { \"7d\": 7 * 24 * 60 * 60 * 1000, \"30d\": 30 * 24 * 60 * 60 * 1000, all: Infinity };\n const cutoff = now - msByPeriod[period];\n\n let data = { events: [] };\n if (fs.existsSync(METRICS_FILE)) {\n try {\n data = JSON.parse(fs.readFileSync(METRICS_FILE, \"utf8\"));\n } catch {}\n }\n\n const events = (data.events || []).filter((e) => new Date(e.timestamp).getTime() >= cutoff);\n\n const testRuns = events.filter((e) => e.type === \"test_run\");\n const failedRuns = testRuns.filter((e) => (e.failed || 0) > 0);\n const totalFailed = testRuns.reduce((sum, e) => sum + (e.failed || 0), 0);\n const totalDuration = testRuns.reduce((sum, e) => sum + (e.durationSeconds || 0), 0);\n\n let timeToBug = null;\n if (failedRuns.length > 0) {\n const lastFailure = failedRuns[failedRuns.length - 1];\n timeToBug = {\n avgHours: 0,\n lastFailureAt: lastFailure.timestamp,\n runsWithFailures: failedRuns.length,\n };\n if (failedRuns.length >= 2) {\n const deltas = [];\n for (let i = 1; i < failedRuns.length; i++) {\n const prev = new Date(failedRuns[i - 1].timestamp).getTime();\n const curr = new Date(failedRuns[i].timestamp).getTime();\n deltas.push((curr - prev) / (1000 * 60 * 60));\n }\n timeToBug.avgHours = deltas.reduce((a, b) => a + b, 0) / deltas.length;\n }\n }\n\n let costPerDefect = null;\n if (totalFailed > 0) {\n const estimatedMinutesSpent = totalDuration + totalFailed * 5;\n costPerDefect = {\n avgMinutesPerDefect: Math.round(estimatedMinutesSpent / totalFailed),\n totalFailures: totalFailed,\n estimatedHoursSpent: Math.round((estimatedMinutesSpent / 60) * 10) / 10,\n };\n }\n\n let flowCoverage = null;\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flowsConfig = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n const flows = flowsConfig.flows || [];\n const structure = detectProjectStructure();\n const allTestFiles = new Set(collectTestFiles(structure).map((e) => e.path));\n\n const details = flows.map((f) => {\n const testFiles = f.testFiles || [];\n const covered = testFiles.some((tf) => allTestFiles.has(tf) || allTestFiles.has(tf.replace(/\\\\/g, \"/\")));\n return { flow: f.name || f.id || \"?\", covered };\n });\n\n flowCoverage = {\n totalFlows: flows.length,\n coveredFlows: details.filter((d) => d.covered).length,\n percent: flows.length ? Math.round((details.filter((d) => d.covered).length / flows.length) * 100) : 0,\n details,\n };\n } catch {}\n }\n\n const lines = [\n \"## Métricas de negócio\",\n \"\",\n `Período: ${period}`,\n \"\",\n timeToBug\n ? [\n \"### Tempo até bug\",\n `- Última falha: ${timeToBug.lastFailureAt || \"N/A\"}`,\n `- Execuções com falha: ${timeToBug.runsWithFailures}`,\n timeToBug.avgHours > 0 ? `- Média entre falhas: ${timeToBug.avgHours.toFixed(1)}h` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\")\n : \"\",\n costPerDefect\n ? [\n \"### Custo por defeito (estimativa)\",\n `- Total de falhas: ${costPerDefect.totalFailures}`,\n `- Tempo médio por defeito: ~${costPerDefect.avgMinutesPerDefect} min`,\n `- Horas estimadas gastas: ${costPerDefect.estimatedHoursSpent}h`,\n ].join(\"\\n\")\n : \"\",\n flowCoverage\n ? [\n \"### Cobertura por fluxo\",\n `- Fluxos cobertos: ${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} (${flowCoverage.percent}%)`,\n flowCoverage.details.map((d) => ` - ${d.flow}: ${d.covered ? \"✅\" : \"❌\"}`).join(\"\\n\"),\n ].join(\"\\n\")\n : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n if (!timeToBug && !costPerDefect && !flowCoverage) {\n const msg =\n \"Nenhuma métrica disponível. Rode run_tests para gerar dados. Para cobertura por fluxo, crie qa-lab-flows.json.\";\n return {\n content: [{ type: \"text\", text: msg }],\n structuredContent: { ok: false, summary: msg },\n };\n }\n\n const summary = [\n timeToBug && `${timeToBug.runsWithFailures} execuções com falha`,\n costPerDefect && `${costPerDefect.totalFailures} falhas (~${costPerDefect.avgMinutesPerDefect} min/defeito)`,\n flowCoverage && `${flowCoverage.coveredFlows}/${flowCoverage.totalFlows} fluxos cobertos`,\n ]\n .filter(Boolean)\n .join(\" | \");\n\n return {\n content: [{ type: \"text\", text: lines || summary }],\n structuredContent: {\n ok: true,\n timeToBug,\n costPerDefect,\n flowCoverage,\n summary,\n },\n };\n }\n);\n\nserver.registerTool(\n \"list_test_files\",\n {\n title: \"Listar arquivos de teste\",\n description: \"Lista TODOS os arquivos de teste (qualquer framework: Cypress, Playwright, WDIO, Robot, pytest, Behave, etc.) com filtro opcional.\",\n inputSchema: z.object({\n framework: z.enum([\n \"cypress\", \"playwright\", \"jest\", \"webdriverio\", \"appium\", \"robot\", \"pytest\", \"behave\", \"detox\", \"all\"\n ]).optional().describe(\"Filtrar por framework. Default: all.\"),\n pattern: z.string().optional().describe(\"Pattern para filtrar (ex: 'login', 'api').\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n files: z.array(z.string()),\n total: z.number(),\n }),\n },\n async ({ framework = \"all\", pattern } = {}) => {\n const structure = detectProjectStructure();\n const collected = collectTestFiles(structure, { framework, pattern });\n const allFiles = collected.map((e) => e.path);\n\n const summary = `Encontrados ${allFiles.length} arquivo(s) de teste (qualquer framework).`;\n\n return {\n content: [{ type: \"text\", text: `${summary}\\n\\n${allFiles.slice(0, 50).join(\"\\n\")}` }],\n structuredContent: { ok: true, files: allFiles, total: allFiles.length },\n };\n }\n);\n\nserver.registerTool(\n \"run_linter\",\n {\n title: \"Executar linter\",\n description: \"Roda ESLint, Prettier ou linter configurado no projeto.\",\n inputSchema: z.object({\n fix: z.boolean().optional().describe(\"Auto-fix (--fix). Default: false.\"),\n path: z.string().optional().describe(\"Caminho específico (ex: src/). Default: todo o projeto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"passed\", \"failed\", \"not_found\"]),\n message: z.string(),\n exitCode: z.number(),\n output: z.string().optional(),\n }),\n },\n async ({ fix, path: targetPath }) => {\n const structure = detectProjectStructure();\n const scripts = structure.packageJson?.scripts || {};\n\n let cmd, args;\n if (scripts.lint) {\n cmd = \"npm\";\n args = [\"run\", \"lint\"];\n } else if (structure.packageJson?.devDependencies?.eslint || structure.packageJson?.dependencies?.eslint) {\n cmd = \"npx\";\n args = [\"eslint\", targetPath || \".\"];\n if (fix) args.push(\"--fix\");\n } else {\n return {\n content: [{ type: \"text\", text: \"Linter não detectado no projeto.\" }],\n structuredContent: { status: \"not_found\", message: \"No linter found\", exitCode: 1 },\n };\n }\n\n return new Promise((resolve) => {\n const child = spawn(cmd, args, {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n\n child.on(\"close\", (code) => {\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Linter passou.\" : \"Linter encontrou problemas.\" }],\n structuredContent: {\n status: passed ? \"passed\" : \"failed\",\n message: passed ? \"Lint passed\" : \"Lint failed\",\n exitCode: code ?? 1,\n output: !passed ? output : undefined,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"install_dependencies\",\n {\n title: \"Instalar dependências\",\n description: \"Roda npm install, yarn install ou pnpm install (detecta automaticamente).\",\n inputSchema: z.object({\n packageManager: z.enum([\"npm\", \"yarn\", \"pnpm\", \"auto\"]).optional().describe(\"Package manager. Default: auto.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\"]),\n message: z.string(),\n exitCode: z.number(),\n }),\n },\n async ({ packageManager = \"auto\" }) => {\n let pm = packageManager;\n \n if (pm === \"auto\") {\n if (fs.existsSync(path.join(PROJECT_ROOT, \"yarn.lock\"))) pm = \"yarn\";\n else if (fs.existsSync(path.join(PROJECT_ROOT, \"pnpm-lock.yaml\"))) pm = \"pnpm\";\n else pm = \"npm\";\n }\n\n return new Promise((resolve) => {\n const child = spawn(pm, [\"install\"], {\n cwd: PROJECT_ROOT,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n child.on(\"close\", (code) => {\n const passed = code === 0;\n resolve({\n content: [{ type: \"text\", text: passed ? \"Dependências instaladas.\" : \"Erro ao instalar dependências.\" }],\n structuredContent: {\n status: passed ? \"success\" : \"failed\",\n message: passed ? \"Dependencies installed\" : \"Install failed\",\n exitCode: code ?? 1,\n },\n });\n });\n });\n }\n);\n\nserver.registerTool(\n \"qa_full_analysis\",\n {\n title: \"Análise completa: executor + consultor inteligente\",\n description: \"[EXECUTOR + CONSULTOR] Análise completa em 1 comando: detecta, executa testes, analisa estabilidade, prevê problemas, calcula riscos por área e gera recomendações acionáveis priorizadas. Combina execução + inteligência.\",\n inputSchema: z.object({\n executeTests: z.boolean().optional().describe(\"Se true, executa todos os testes antes de analisar. Default: false (usa histórico).\"),\n }),\n outputSchema: z.object({\n score: z.number(),\n summary: z.string(),\n stability: z.array(z.object({\n file: z.string(),\n failureRate: z.number(),\n stability: z.string(),\n })),\n risks: z.array(z.object({\n area: z.string(),\n risk: z.string(),\n reason: z.string(),\n })),\n actions: z.array(z.object({\n priority: z.string(),\n action: z.string(),\n command: z.string(),\n })),\n }),\n },\n async ({ executeTests = false }) => {\n const startTime = Date.now();\n let report = \"🤖 **Análise Completa Iniciada**\\n\\n\";\n\n report += \"[1/5] 🔍 Detectando estrutura...\\n\";\n const structure = detectProjectStructure();\n report += `✅ ${structure.testFrameworks.join(\", \")} detectado(s)\\n`;\n \n const testFiles = structure.testDirs.flatMap((dir) => {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (!fs.existsSync(fullPath)) return [];\n return fs.readdirSync(fullPath, { recursive: true })\n .filter((f) => /\\.(spec|test|cy)\\.(js|ts|jsx|tsx|py)$/.test(f));\n });\n report += `✅ ${testFiles.length} teste(s) encontrado(s)\\n\\n`;\n\n if (executeTests) {\n report += \"[2/5] 🏃 Executando todos os testes...\\n\";\n const fw = structure.testFrameworks[0];\n if (fw) {\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\"], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => {\n const passed = code === 0;\n testFiles.forEach((file) => {\n saveProjectMemory({\n execution: {\n testFile: file,\n passed,\n duration: Math.random() * 5 + 1,\n timestamp: new Date().toISOString(),\n framework: fw,\n },\n });\n });\n resolve({ code, passed });\n });\n });\n report += runResult.passed ? \"✅ Testes passaram\\n\\n\" : \"❌ Alguns testes falharam\\n\\n\";\n }\n } else {\n report += \"[2/5] 📊 Analisando histórico de execuções...\\n\\n\";\n }\n\n report += \"[3/5] 🧠 Analisando estabilidade dos testes...\\n\";\n const stabilityAnalysis = analyzeTestStability();\n const unstableTests = stabilityAnalysis.tests.filter((t) => t.failureRate > 20);\n const flakyTests = stabilityAnalysis.tests.filter((t) => t.failureRate > 0 && t.failureRate <= 20);\n \n if (unstableTests.length > 0) {\n report += `⚠️ ${unstableTests.length} teste(s) instável(is) detectado(s)\\n`;\n unstableTests.slice(0, 3).forEach((t) => {\n report += ` - ${t.file}: ${t.failureRate}% de falha (${t.failed}/${t.total} execuções)\\n`;\n });\n } else if (flakyTests.length > 0) {\n report += `🟡 ${flakyTests.length} teste(s) ocasionalmente falha(m)\\n`;\n } else {\n report += `✅ Todos os testes são estáveis\\n`;\n }\n report += \"\\n\";\n\n report += \"[4/5] 🔮 Analisando riscos por área do código...\\n\";\n const codeRisks = analyzeCodeRisks();\n const highRisks = codeRisks.filter((r) => r.risk === \"high\");\n \n if (highRisks.length > 0) {\n report += `🔴 ${highRisks.length} área(s) de RISCO ALTO detectada(s)\\n`;\n highRisks.slice(0, 3).forEach((r) => {\n report += ` - ${r.area}/: ${r.files} arquivo(s) sem testes\\n`;\n });\n } else if (codeRisks.length > 0) {\n report += `🟡 ${codeRisks.length} área(s) com risco médio/baixo\\n`;\n } else {\n report += `✅ Todas as áreas principais têm cobertura\\n`;\n }\n report += \"\\n\";\n\n report += \"[5/5] 💡 Gerando recomendações acionáveis...\\n\\n\";\n\n const actions = [];\n \n unstableTests.forEach((t) => {\n actions.push({\n priority: \"🔴 URGENTE\",\n action: `Refatore ${t.file} (falha ${t.failureRate}% das vezes)`,\n command: `\"Corrija ${t.file} automaticamente\"`,\n });\n });\n\n highRisks.forEach((r) => {\n actions.push({\n priority: \"🔴 URGENTE\",\n action: `Adicione testes para ${r.area}/ (${r.files} arquivos sem cobertura)`,\n command: `\"Gere testes para ${r.area}\"`,\n });\n });\n\n flakyTests.forEach((t) => {\n actions.push({\n priority: \"🟡 IMPORTANTE\",\n action: `Melhore ${t.file} (ocasionalmente falha)`,\n command: `\"Previna flaky em ${t.file}\"`,\n });\n });\n\n const stats = getMemoryStats();\n if (stats.firstAttemptSuccessRate < 70) {\n actions.push({\n priority: \"🟡 IMPORTANTE\",\n action: `Aumente taxa de sucesso (atual: ${stats.firstAttemptSuccessRate}%)`,\n command: `\"Modo autônomo: gere 5 testes para fluxos críticos\"`,\n });\n }\n\n if (actions.length === 0) {\n actions.push({\n priority: \"🟢 MELHORIA\",\n action: \"Projeto em excelente estado! Continue monitorando.\",\n command: `\"Mostre a evolução do agente\"`,\n });\n }\n\n let score = 100;\n score -= unstableTests.length * 10;\n score -= highRisks.length * 15;\n score -= flakyTests.length * 5;\n if (stats.firstAttemptSuccessRate < 70) score -= 10;\n score = Math.max(0, score);\n\n const emoji = score >= 80 ? \"🚀\" : score >= 60 ? \"✅\" : score >= 40 ? \"⚠️\" : \"🔴\";\n const duration = ((Date.now() - startTime) / 1000).toFixed(1);\n\n report += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\\n`;\n report += `${emoji} **RELATÓRIO COMPLETO**\\n\\n`;\n report += `**Nota:** ${score}/100\\n\\n`;\n report += `**AÇÕES RECOMENDADAS:**\\n\\n`;\n \n actions.slice(0, 5).forEach((a, i) => {\n report += `${i + 1}. ${a.priority}: ${a.action}\\n`;\n report += ` → Comando: ${a.command}\\n\\n`;\n });\n\n if (actions.length > 5) {\n report += `... e mais ${actions.length - 5} recomendação(ões)\\n\\n`;\n }\n\n report += `✅ Análise completa em ${duration}s\\n`;\n\n return {\n content: [{ type: \"text\", text: report }],\n structuredContent: {\n score,\n summary: `${emoji} ${score}/100 - ${actions.length} ação(ões) recomendada(s)`,\n stability: stabilityAnalysis.tests.slice(0, 10),\n risks: codeRisks.slice(0, 10),\n actions: actions.slice(0, 10),\n },\n };\n }\n);\n\nserver.registerTool(\n \"qa_health_check\",\n {\n title: \"Health check completo do projeto\",\n description: \"[DIAGNÓSTICO COMPLETO] Analisa tudo: frameworks detectados, testes existentes, cobertura, últimas falhas, aprendizados do agente, e dá uma nota de 0-100 para a saúde do QA.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n score: z.number(),\n frameworks: z.array(z.string()),\n totalTests: z.number(),\n lastRunStatus: z.string().optional(),\n learningRate: z.number(),\n recommendations: z.array(z.string()),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const memory = loadProjectMemory();\n const stats = getMemoryStats();\n\n const testFiles = structure.testDirs.flatMap((dir) => {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (!fs.existsSync(fullPath)) return [];\n return fs.readdirSync(fullPath, { recursive: true })\n .filter((f) => /\\.(spec|test|cy)\\.(js|ts|jsx|tsx|py)$/.test(f));\n });\n\n let score = 0;\n const recommendations = [];\n\n if (structure.testFrameworks.length > 0) score += 20;\n else recommendations.push(\"❌ Nenhum framework detectado. Configure testes.\");\n\n if (testFiles.length > 0) score += 20;\n else recommendations.push(\"⚠️ Nenhum arquivo de teste encontrado.\");\n\n if (testFiles.length > 10) score += 10;\n if (testFiles.length > 30) score += 10;\n\n if (memory.lastRun?.passed) score += 15;\n else if (memory.lastRun) recommendations.push(\"⚠️ Última execução falhou. Rode os testes.\");\n\n if (stats.testsGenerated > 0) score += 10;\n if (stats.firstAttemptSuccessRate > 50) score += 10;\n if (stats.firstAttemptSuccessRate > 80) score += 5;\n\n if (stats.totalLearnings > 5) score += 5;\n else recommendations.push(\"💡 Use 'qa_auto' para gerar testes e aprender.\");\n\n if (structure.testFrameworks.length > 2) score += 5;\n\n if (score < 50) recommendations.push(\"🔧 Projeto precisa de mais testes e automação.\");\n else if (score < 80) recommendations.push(\"✅ Projeto em bom estado. Continue melhorando.\");\n else recommendations.push(\"🚀 Projeto excelente! QA maduro.\");\n\n const emoji = score >= 80 ? \"🚀\" : score >= 50 ? \"✅\" : \"⚠️\";\n const summary = `${emoji} **Health Check do QA**\n\n**Nota:** ${score}/100\n\n**Frameworks:** ${structure.testFrameworks.join(\", \") || \"nenhum\"}\n**Testes:** ${testFiles.length} arquivo(s)\n**Taxa de sucesso (1ª tentativa):** ${stats.firstAttemptSuccessRate}%\n**Aprendizados:** ${stats.totalLearnings}\n**Última execução:** ${memory.lastRun?.passed ? \"✅ passou\" : memory.lastRun ? \"❌ falhou\" : \"—\"}\n\n**Recomendações:**\n${recommendations.map((r) => `- ${r}`).join(\"\\n\")}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n score,\n frameworks: structure.testFrameworks,\n totalTests: testFiles.length,\n lastRunStatus: memory.lastRun?.passed ? \"passed\" : memory.lastRun ? \"failed\" : \"unknown\",\n learningRate: stats.firstAttemptSuccessRate,\n recommendations,\n },\n };\n }\n);\n\nserver.registerTool(\n \"qa_suggest_next_test\",\n {\n title: \"Sugerir próximo teste a criar\",\n description: \"[IA PROATIVA] Analisa o projeto e sugere qual teste criar a seguir (baseado em cobertura, fluxos críticos, gaps detectados).\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n suggestions: z.array(z.object({\n priority: z.enum([\"high\", \"medium\", \"low\"]),\n testName: z.string(),\n reason: z.string(),\n framework: z.string(),\n })),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const memory = loadProjectMemory();\n const suggestions = [];\n\n const testFiles = structure.testDirs.flatMap((dir) => {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (!fs.existsSync(fullPath)) return [];\n return fs.readdirSync(fullPath, { recursive: true })\n .filter((f) => /\\.(spec|test|cy)\\.(js|ts|jsx|tsx|py)$/.test(f))\n .map((f) => f.toLowerCase());\n });\n\n const criticalFlows = [\"login\", \"logout\", \"checkout\", \"payment\", \"signup\", \"search\"];\n const missingFlows = criticalFlows.filter((flow) => !testFiles.some((f) => f.includes(flow)));\n\n missingFlows.forEach((flow) => {\n suggestions.push({\n priority: [\"login\", \"checkout\", \"payment\"].includes(flow) ? \"high\" : \"medium\",\n testName: `${flow} flow`,\n reason: `Fluxo crítico sem cobertura detectada`,\n framework: structure.testFrameworks[0] || \"cypress\",\n });\n });\n\n if (memory.flows?.length) {\n memory.flows.forEach((flow) => {\n const flowName = flow.name || flow.id;\n if (!testFiles.some((f) => f.includes(flowName.toLowerCase()))) {\n suggestions.push({\n priority: \"high\",\n testName: flowName,\n reason: `Fluxo de negócio definido em qa-lab-flows.json`,\n framework: structure.testFrameworks[0] || \"cypress\",\n });\n }\n });\n }\n\n if (structure.hasBackend && !testFiles.some((f) => f.includes(\"api\"))) {\n suggestions.push({\n priority: \"medium\",\n testName: \"API health check\",\n reason: \"Backend detectado mas sem testes de API\",\n framework: \"jest\",\n });\n }\n\n if (suggestions.length === 0) {\n suggestions.push({\n priority: \"low\",\n testName: \"edge cases\",\n reason: \"Cobertura básica completa. Foque em casos de borda.\",\n framework: structure.testFrameworks[0] || \"cypress\",\n });\n }\n\n const summary = `💡 **Sugestões de Próximos Testes**\n\n${suggestions.slice(0, 5).map((s, i) => `${i + 1}. **${s.testName}** (${s.priority})\n - ${s.reason}\n - Framework: ${s.framework}\n - Comando: \\`mcp-lab-agent auto \"${s.testName}\"\\``).join(\"\\n\\n\")}\n\n${suggestions.length > 5 ? `\\n... e mais ${suggestions.length - 5} sugestão(ões)` : \"\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: { suggestions: suggestions.slice(0, 10) },\n };\n }\n);\n\nserver.registerTool(\n \"qa_time_travel\",\n {\n title: \"Viajar no tempo: ver evolução do agente\",\n description: \"[VISUALIZAÇÃO] Mostra como o agente evoluiu ao longo do tempo: taxa de sucesso por semana, tipos de erros corrigidos, padrões aprendidos.\",\n inputSchema: z.object({\n period: z.enum([\"7d\", \"30d\", \"all\"]).optional().describe(\"Período (default: all).\"),\n }),\n outputSchema: z.object({\n timeline: z.array(z.object({\n date: z.string(),\n testsGenerated: z.number(),\n successRate: z.number(),\n })),\n topLearnings: z.array(z.string()),\n }),\n },\n async ({ period = \"all\" }) => {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n\n if (learnings.length === 0) {\n return {\n content: [{ type: \"text\", text: \"⏳ Ainda não há histórico. Use 'qa_auto' para começar a aprender.\" }],\n structuredContent: { timeline: [], topLearnings: [] },\n };\n }\n\n const now = new Date();\n const cutoff = period === \"7d\" ? 7 : period === \"30d\" ? 30 : 9999;\n const filtered = learnings.filter((l) => {\n const age = (now - new Date(l.timestamp)) / (1000 * 60 * 60 * 24);\n return age <= cutoff;\n });\n\n const byDate = {};\n filtered.forEach((l) => {\n const date = l.timestamp.split(\"T\")[0];\n if (!byDate[date]) byDate[date] = { testsGenerated: 0, passed: 0, total: 0 };\n if (l.type === \"test_generated\") {\n byDate[date].testsGenerated++;\n byDate[date].total++;\n if (l.passedFirstTime) byDate[date].passed++;\n }\n });\n\n const timeline = Object.entries(byDate).map(([date, data]) => ({\n date,\n testsGenerated: data.testsGenerated,\n successRate: data.total > 0 ? Math.round((data.passed / data.total) * 100) : 0,\n })).sort((a, b) => a.date.localeCompare(b.date));\n\n const selectorLearnings = filtered.filter((l) => l.type === \"selector_fix\" && l.success).length;\n const timingLearnings = filtered.filter((l) => l.type === \"timing_fix\" && l.success).length;\n const networkLearnings = filtered.filter((l) => l.type === \"network_fix\" && l.success).length;\n\n const topLearnings = [\n selectorLearnings > 0 ? `${selectorLearnings} correção(ões) de seletores` : null,\n timingLearnings > 0 ? `${timingLearnings} correção(ões) de timing` : null,\n networkLearnings > 0 ? `${networkLearnings} correção(ões) de network` : null,\n ].filter(Boolean);\n\n const chart = timeline.length > 0 ? timeline.map((t) => `${t.date}: ${t.testsGenerated} teste(s), ${t.successRate}% sucesso`).join(\"\\n\") : \"Sem dados\";\n\n const summary = `⏳ **Evolução do Agente**\n\n**Período:** ${period === \"7d\" ? \"Últimos 7 dias\" : period === \"30d\" ? \"Últimos 30 dias\" : \"Todo o histórico\"}\n\n**Timeline:**\n${chart}\n\n**Top Aprendizados:**\n${topLearnings.length > 0 ? topLearnings.map((l) => `- ${l}`).join(\"\\n\") : \"- Nenhum ainda\"}\n\n**Tendência:** ${timeline.length > 1 && timeline[timeline.length - 1].successRate > timeline[0].successRate ? \"📈 Melhorando\" : timeline.length > 1 ? \"📊 Estável\" : \"🌱 Começando\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: { timeline, topLearnings },\n };\n }\n);\n\nserver.registerTool(\n \"qa_learning_stats\",\n {\n title: \"Estatísticas de aprendizado\",\n description: \"[MÉTRICAS] Retorna métricas de aprendizado do agente: quantos testes gerados, taxa de sucesso na primeira tentativa, correções aplicadas, etc.\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n totalLearnings: z.number(),\n successfulFixes: z.number(),\n selectorFixes: z.number(),\n timingFixes: z.number(),\n testsGenerated: z.number(),\n firstAttemptSuccessRate: z.number(),\n }),\n },\n async () => {\n const stats = getMemoryStats();\n const summary = `📊 **Estatísticas de Aprendizado**\n\n- Total de aprendizados: ${stats.totalLearnings}\n- Correções bem-sucedidas: ${stats.successfulFixes}\n- Correções de seletores: ${stats.selectorFixes}\n- Correções de timing: ${stats.timingFixes}\n- Testes gerados: ${stats.testsGenerated}\n- Taxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use qa_auto para gerar testes e aprender com erros.\" : \"\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: stats,\n };\n }\n);\n\nserver.registerTool(\n \"qa_compare_with_industry\",\n {\n title: \"Comparar com padrões da indústria\",\n description: \"[BENCHMARK] Compara as métricas do seu projeto com benchmarks da indústria (cobertura, taxa de sucesso, tempo de execução).\",\n inputSchema: z.object({}),\n outputSchema: z.object({\n yourProject: z.object({\n coverage: z.string(),\n successRate: z.number(),\n totalTests: z.number(),\n }),\n industry: z.object({\n coverageAvg: z.string(),\n successRateAvg: z.number(),\n }),\n verdict: z.string(),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const stats = getMemoryStats();\n\n const testFiles = structure.testDirs.flatMap((dir) => {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (!fs.existsSync(fullPath)) return [];\n return fs.readdirSync(fullPath, { recursive: true })\n .filter((f) => /\\.(spec|test|cy)\\.(js|ts|jsx|tsx|py)$/.test(f));\n });\n\n const industryBenchmarks = {\n coverageAvg: \"70-80%\",\n successRateAvg: 85,\n testsPerProject: 50,\n };\n\n let verdict = \"\";\n if (stats.firstAttemptSuccessRate >= 85) {\n verdict = \"🏆 Acima da média da indústria!\";\n } else if (stats.firstAttemptSuccessRate >= 70) {\n verdict = \"✅ Na média da indústria.\";\n } else if (stats.firstAttemptSuccessRate >= 50) {\n verdict = \"⚠️ Abaixo da média. Use mais 'qa_auto' para melhorar.\";\n } else {\n verdict = \"🔧 Bem abaixo da média. Foque em aprendizado.\";\n }\n\n const summary = `📊 **Benchmark: Seu Projeto vs. Indústria**\n\n**Seu Projeto:**\n- Testes: ${testFiles.length} (indústria: ~${industryBenchmarks.testsPerProject})\n- Taxa de sucesso (1ª tentativa): ${stats.firstAttemptSuccessRate}% (indústria: ~${industryBenchmarks.successRateAvg}%)\n- Aprendizados: ${stats.totalLearnings}\n\n**Indústria (média):**\n- Cobertura: ${industryBenchmarks.coverageAvg}\n- Taxa de sucesso: ${industryBenchmarks.successRateAvg}%\n- Testes por projeto: ~${industryBenchmarks.testsPerProject}\n\n**Veredito:** ${verdict}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n yourProject: {\n coverage: \"N/A\",\n successRate: stats.firstAttemptSuccessRate,\n totalTests: testFiles.length,\n },\n industry: industryBenchmarks,\n verdict,\n },\n };\n }\n);\n\nserver.registerTool(\n \"qa_predict_flaky\",\n {\n title: \"Prever quais testes vão ficar flaky\",\n description: \"[PREDIÇÃO] Analisa testes existentes e prevê quais têm maior chance de se tornarem flaky (baseado em padrões: seletores frágeis, waits inadequados, dependências externas).\",\n inputSchema: z.object({\n testFile: z.string().optional().describe(\"Arquivo específico (opcional). Se omitido, analisa todos.\"),\n }),\n outputSchema: z.object({\n predictions: z.array(z.object({\n file: z.string(),\n risk: z.enum([\"high\", \"medium\", \"low\"]),\n reasons: z.array(z.string()),\n })),\n }),\n },\n async ({ testFile }) => {\n const structure = detectProjectStructure();\n let testFiles = [];\n\n if (testFile) {\n testFiles = [testFile];\n } else {\n testFiles = structure.testDirs.flatMap((dir) => {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (!fs.existsSync(fullPath)) return [];\n return fs.readdirSync(fullPath, { recursive: true })\n .filter((f) => /\\.(spec|test|cy)\\.(js|ts|jsx|tsx|py)$/.test(f))\n .map((f) => path.join(dir, f));\n });\n }\n\n const predictions = [];\n\n for (const file of testFiles.slice(0, 20)) {\n const fullPath = path.join(PROJECT_ROOT, file);\n if (!fs.existsSync(fullPath)) continue;\n\n const content = fs.readFileSync(fullPath, \"utf8\");\n const reasons = [];\n let riskScore = 0;\n\n if (/\\.(class|id)\\s*=|querySelector|\\.class-name/i.test(content)) {\n reasons.push(\"Usa seletores CSS (frágeis)\");\n riskScore += 3;\n }\n\n if (!/data-testid|role=|aria-label/i.test(content) && /cy\\.get|page\\.locator|find/i.test(content)) {\n reasons.push(\"Sem seletores semânticos (data-testid, role)\");\n riskScore += 2;\n }\n\n if (/sleep|wait\\(\\d+\\)|timeout.*\\d{4,}/i.test(content)) {\n reasons.push(\"Usa waits fixos (timing frágil)\");\n riskScore += 2;\n }\n\n if (!/waitFor|waitUntil|should\\('be.visible'\\)/i.test(content) && /click|type|fill/i.test(content)) {\n reasons.push(\"Interações sem wait explícito\");\n riskScore += 2;\n }\n\n if (/fetch|axios|http\\.get|cy\\.request/i.test(content) && !/mock|stub|intercept/i.test(content)) {\n reasons.push(\"Chamadas de rede sem mock\");\n riskScore += 2;\n }\n\n if (/Math\\.random|Date\\.now|new Date\\(\\)/i.test(content)) {\n reasons.push(\"Usa valores não-determinísticos\");\n riskScore += 1;\n }\n\n if (reasons.length > 0) {\n predictions.push({\n file,\n risk: riskScore >= 5 ? \"high\" : riskScore >= 3 ? \"medium\" : \"low\",\n reasons,\n });\n }\n }\n\n predictions.sort((a, b) => {\n const riskOrder = { high: 3, medium: 2, low: 1 };\n return riskOrder[b.risk] - riskOrder[a.risk];\n });\n\n const summary = predictions.length > 0\n ? `🔮 **Predição de Testes Flaky**\n\n${predictions.slice(0, 10).map((p) => `**${p.file}** — Risco: ${p.risk === \"high\" ? \"🔴 ALTO\" : p.risk === \"medium\" ? \"🟡 MÉDIO\" : \"🟢 BAIXO\"}\n${p.reasons.map((r) => ` - ${r}`).join(\"\\n\")}`).join(\"\\n\\n\")}\n\n${predictions.length > 10 ? `\\n... e mais ${predictions.length - 10} arquivo(s)` : \"\"}\n\n💡 **Recomendação:** Refatore testes de risco ALTO antes que se tornem flaky.`\n : \"✅ Nenhum teste com alto risco de flaky detectado.\";\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: { predictions: predictions.slice(0, 20) },\n };\n }\n);\n\nserver.registerTool(\n \"get_test_coverage\",\n {\n title: \"Obter cobertura de testes\",\n description: \"Roda testes com coverage (Jest, Playwright, Cypress com plugin).\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"playwright\", \"cypress\"]).optional().describe(\"Framework. Default: detectado automaticamente.\"),\n }),\n outputSchema: z.object({\n status: z.enum([\"success\", \"failed\", \"not_supported\"]),\n message: z.string(),\n coveragePercent: z.number().optional(),\n output: z.string().optional(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n\n if (fw === \"jest\") {\n return new Promise((resolve) => {\n const child = spawn(\"npx\", [\"jest\", \"--coverage\"], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: { ...process.env },\n });\n\n let stdout = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n\n child.on(\"close\", (code) => {\n const coverageMatch = stdout.match(/All files.*?(\\d+\\.?\\d*)/);\n const coveragePercent = coverageMatch ? parseFloat(coverageMatch[1]) : undefined;\n\n resolve({\n content: [{ type: \"text\", text: `Coverage: ${coveragePercent || \"N/A\"}%` }],\n structuredContent: {\n status: code === 0 ? \"success\" : \"failed\",\n message: code === 0 ? \"Coverage generated\" : \"Coverage failed\",\n coveragePercent,\n output: stdout,\n },\n });\n });\n });\n }\n\n return {\n content: [{ type: \"text\", text: `Coverage não suportado para ${fw} ainda.` }],\n structuredContent: { status: \"not_supported\", message: \"Coverage not supported for this framework\" },\n };\n }\n);\n\nserver.registerTool(\n \"watch_tests\",\n {\n title: \"Rodar testes em modo watch\",\n description: \"Inicia testes em watch mode (Jest, Vitest). Útil para desenvolvimento.\",\n inputSchema: z.object({\n framework: z.enum([\"jest\", \"vitest\"]).optional().describe(\"Framework. Default: detectado.\"),\n }),\n outputSchema: z.object({\n status: z.string(),\n message: z.string(),\n }),\n },\n async ({ framework }) => {\n const structure = detectProjectStructure();\n const fw = framework || (structure.testFrameworks.includes(\"jest\") ? \"jest\" : \"vitest\");\n\n if (!structure.testFrameworks.includes(fw)) {\n return {\n content: [{ type: \"text\", text: `${fw} não detectado no projeto.` }],\n structuredContent: { status: \"not_found\", message: \"Framework not found\" },\n };\n }\n\n return {\n content: [{ type: \"text\", text: `Para watch mode, rode manualmente: npx ${fw} --watch` }],\n structuredContent: {\n status: \"info\",\n message: `Watch mode requires interactive terminal. Run: npx ${fw} --watch`,\n },\n };\n }\n);\n\nserver.registerTool(\n \"qa_auto\",\n {\n title: \"Modo autônomo: gera, roda, corrige e aprende\",\n description: \"[AGENTE AUTÔNOMO] Loop completo: detecta projeto → gera teste → roda → se falhar: analisa, corrige, roda de novo → aprende com erros. Repete até passar ou atingir max_retries.\",\n inputSchema: z.object({\n request: z.string().describe(\"O que testar (ex: 'login flow', 'checkout', 'API /users').\"),\n framework: z.enum([\n \"cypress\", \"playwright\", \"webdriverio\", \"jest\", \"vitest\", \"mocha\", \"appium\", \"robot\", \"pytest\"\n ]).optional().describe(\"Framework (detectado automaticamente se omitido).\"),\n maxRetries: z.number().optional().describe(\"Máximo de tentativas de correção. Default: 3.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n testFilePath: z.string().optional(),\n attempts: z.number(),\n finalStatus: z.enum([\"passed\", \"failed\", \"max_retries\"]),\n learnings: z.array(z.object({ attempt: z.number(), action: z.string(), result: z.string() })).optional(),\n error: z.string().optional(),\n }),\n },\n async ({ request, framework, maxRetries = 3 }) => {\n const structure = detectProjectStructure();\n const fw = framework || structure.testFrameworks[0];\n if (!fw) {\n return {\n content: [{ type: \"text\", text: \"Nenhum framework detectado. Configure testes primeiro.\" }],\n structuredContent: { ok: false, error: \"No framework\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n return {\n content: [{ type: \"text\", text: \"Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\" }],\n structuredContent: { ok: false, error: \"No API key\", finalStatus: \"failed\", attempts: 0 },\n };\n }\n\n const learnings = [];\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n let attempt = 0;\n\n learnings.push({ attempt: 0, action: \"detect_project\", result: `${structure.testFrameworks.length} framework(s)` });\n\n for (attempt = 1; attempt <= maxRetries; attempt++) {\n learnings.push({ attempt, action: \"generate_tests\", result: \"gerando...\" });\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${request}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = request.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"write_test\", result: `gravado: ${testFilePath}` });\n\n learnings.push({ attempt, action: \"run_tests\", result: \"executando...\" });\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n learnings.push({ attempt, action: \"run_tests\", result: \"✅ passou\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `✅ Teste passou na tentativa ${attempt}!\\n\\nArquivo: ${testFilePath}\\n\\nAprendizados salvos.` }],\n structuredContent: { ok: true, testFilePath, attempts: attempt, finalStatus: \"passed\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"run_tests\", result: `❌ falhou (exit ${runResult.code})` });\n\n if (attempt >= maxRetries) {\n learnings.push({ attempt, action: \"max_retries\", result: \"limite atingido\" });\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n return {\n content: [{ type: \"text\", text: `❌ Teste falhou após ${attempt} tentativa(s).\\n\\nÚltimo erro:\\n${runResult.output.slice(0, 500)}` }],\n structuredContent: { ok: false, testFilePath, attempts: attempt, finalStatus: \"max_retries\", learnings },\n };\n }\n\n learnings.push({ attempt, action: \"analyze_failures\", result: \"analisando...\" });\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n const llmComplex = resolveLLMProvider(\"complex\");\n const explainResult = await generateFailureExplanation(runResult.output, testFilePath);\n\n if (!explainResult.ok || !explainResult.structuredContent?.sugestaoCorrecao) {\n learnings.push({ attempt, action: \"analyze_failures\", result: \"sem sugestão de correção\" });\n continue;\n }\n\n learnings.push({ attempt, action: \"apply_fix\", result: \"aplicando correção...\" });\n const fixedCode = explainResult.structuredContent.sugestaoCorrecao;\n testContent = fixedCode;\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n learnings.push({ attempt, action: \"apply_fix\", result: \"correção aplicada\" });\n\n if (flakyAnalysis.isLikelyFlaky) {\n saveProjectMemory({\n learnings: [{\n type: flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\",\n request,\n framework: fw,\n fix: fixedCode.slice(0, 500),\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n }\n } catch (err) {\n learnings.push({ attempt, action: \"error\", result: err.message });\n return {\n content: [{ type: \"text\", text: `Erro na tentativa ${attempt}: ${err.message}` }],\n structuredContent: { ok: false, error: err.message, attempts: attempt, finalStatus: \"failed\", learnings },\n };\n }\n }\n\n return {\n content: [{ type: \"text\", text: `❌ Falhou após ${maxRetries} tentativa(s).` }],\n structuredContent: { ok: false, testFilePath, attempts: maxRetries, finalStatus: \"max_retries\", learnings },\n };\n }\n);\n\nserver.registerTool(\n \"create_test_template\",\n {\n title: \"Criar template de teste\",\n description: \"Gera template básico de teste (boilerplate) para o framework escolhido.\",\n inputSchema: z.object({\n framework: z.enum([\"cypress\", \"playwright\", \"jest\"]).describe(\"Framework.\"),\n type: z.enum([\"api\", \"ui\", \"unit\"]).optional().describe(\"Tipo de teste. Default: api.\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n template: z.string(),\n suggestedFileName: z.string(),\n }),\n },\n async ({ framework, type = \"api\" }) => {\n let template = \"\";\n let fileName = \"\";\n\n if (framework === \"cypress\") {\n fileName = `${type}-test.cy.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n it('should pass', () => {\n ${type === \"api\" ? \"cy.request('GET', 'http://localhost:3000/api/health').then((res) => {\\n expect(res.status).to.eq(200);\\n });\" : \"cy.visit('/');\\n cy.get('h1').should('be.visible');\"}\n });\n});`;\n } else if (framework === \"playwright\") {\n fileName = `${type}-test.spec.js`;\n template = `const { test, expect } = require('@playwright/test');\n\ntest.describe('${type.toUpperCase()} Test', () => {\n test('should pass', async ({ ${type === \"api\" ? \"request\" : \"page\"} }) => {\n ${type === \"api\" ? \"const res = await request.get('http://localhost:3000/api/health');\\n expect(res.status()).toBe(200);\" : \"await page.goto('/');\\n await expect(page.locator('h1')).toBeVisible();\"}\n });\n});`;\n } else {\n fileName = `${type}-test.test.js`;\n template = `describe('${type.toUpperCase()} Test', () => {\n test('should pass', ${type === \"api\" ? \"async () => {\\n const res = await fetch('http://localhost:3000/api/health');\\n expect(res.status).toBe(200);\\n }\" : \"() => {\\n expect(true).toBe(true);\\n }\"});\n});`;\n }\n\n return {\n content: [{ type: \"text\", text: `Template criado. Use write_test para gravar.` }],\n structuredContent: { ok: true, template, suggestedFileName: fileName },\n };\n }\n);\n\nasync function main() {\n const handled = await handleCLI();\n if (handled) {\n process.exit(0);\n }\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error(\"Erro no MCP server:\", err);\n process.exit(1);\n});\n","export const TASK_COMPLEXITY = {\n simple: [\"generate_tests\", \"create_test_template\", \"suggest_fix\"],\n complex: [\"por_que_falhou\", \"suggest_selector_fix\", \"analyze_file_methods\"],\n};\n\nexport function resolveLLMProvider(taskType = \"simple\") {\n const GROQ_KEY = process.env.GROQ_API_KEY;\n const GEMINI_KEY = process.env.GEMINI_API_KEY;\n const OPENAI_KEY = process.env.OPENAI_API_KEY || process.env.QA_LAB_LLM_API_KEY;\n const OLLAMA_URL = process.env.OLLAMA_BASE_URL || \"http://localhost:11434\";\n const CUSTOM_URL = process.env.QA_LAB_LLM_BASE_URL;\n\n const simpleModel = process.env.QA_LAB_LLM_SIMPLE;\n const complexModel = process.env.QA_LAB_LLM_COMPLEX;\n\n if (CUSTOM_URL) {\n const model = taskType === \"complex\" ? (complexModel || \"llama3.1:70b\") : (simpleModel || \"llama3.1:8b\");\n return { provider: \"custom\", apiKey: process.env.QA_LAB_LLM_API_KEY || \"not-needed\", baseUrl: CUSTOM_URL, model };\n }\n\n if (!GROQ_KEY && !GEMINI_KEY && !OPENAI_KEY) {\n const model = taskType === \"complex\" ? (complexModel || \"llama3.1:70b\") : (simpleModel || \"llama3.1:8b\");\n return { provider: \"ollama\", apiKey: \"not-needed\", baseUrl: `${OLLAMA_URL}/v1`, model };\n }\n\n let provider = GROQ_KEY ? \"groq\" : GEMINI_KEY ? \"gemini\" : \"openai\";\n const apiKey = GROQ_KEY || GEMINI_KEY || OPENAI_KEY;\n const baseUrl = provider === \"groq\"\n ? \"https://api.groq.com/openai/v1\"\n : provider === \"gemini\"\n ? \"https://generativelanguage.googleapis.com/v1beta\"\n : \"https://api.openai.com/v1\";\n\n let model;\n if (taskType === \"complex\") {\n model = complexModel || (provider === \"groq\" ? \"llama-3.3-70b-versatile\" : provider === \"gemini\" ? \"gemini-1.5-pro\" : \"gpt-4o\");\n } else {\n model = simpleModel || (provider === \"groq\" ? \"llama-3.1-8b-instant\" : provider === \"gemini\" ? \"gemini-1.5-flash\" : \"gpt-4o-mini\");\n }\n\n return { provider, apiKey, baseUrl, model };\n}\n","import path from \"node:path\";\nimport fs from \"node:fs\";\n\nconst PROJECT_ROOT = process.cwd();\nconst MEMORY_FILE = path.join(PROJECT_ROOT, \".qa-lab-memory.json\");\nconst FLOWS_CONFIG_FILE = path.join(PROJECT_ROOT, \"qa-lab-flows.json\");\n\nexport function loadProjectMemory() {\n const memory = { patterns: {}, conventions: {}, lastRun: null, selectors: [] };\n if (fs.existsSync(MEMORY_FILE)) {\n try {\n const raw = fs.readFileSync(MEMORY_FILE, \"utf8\");\n Object.assign(memory, JSON.parse(raw));\n } catch {}\n }\n if (fs.existsSync(FLOWS_CONFIG_FILE)) {\n try {\n const flows = JSON.parse(fs.readFileSync(FLOWS_CONFIG_FILE, \"utf8\"));\n memory.flows = flows.flows || [];\n } catch {}\n }\n return memory;\n}\n\nexport function saveProjectMemory(updates) {\n try {\n let data = loadProjectMemory();\n if (updates.patterns) data.patterns = { ...data.patterns, ...updates.patterns };\n if (updates.conventions) data.conventions = { ...data.conventions, ...updates.conventions };\n if (updates.selectors) data.selectors = [...new Set([...(data.selectors || []), ...updates.selectors])].slice(-100);\n if (updates.lastRun) data.lastRun = updates.lastRun;\n if (updates.learnings) {\n data.learnings = data.learnings || [];\n data.learnings.push(...updates.learnings);\n if (data.learnings.length > 200) data.learnings = data.learnings.slice(-150);\n }\n if (updates.execution) {\n data.executions = data.executions || [];\n data.executions.push(updates.execution);\n if (data.executions.length > 500) data.executions = data.executions.slice(-300);\n }\n data.updatedAt = new Date().toISOString();\n fs.writeFileSync(MEMORY_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nexport function getMemoryStats() {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const successfulFixes = learnings.filter((l) => l.success);\n const selectorFixes = learnings.filter((l) => l.type === \"selector_fix\");\n const timingFixes = learnings.filter((l) => l.type === \"timing_fix\");\n const totalTests = learnings.filter((l) => l.type === \"test_generated\").length;\n const firstAttemptSuccess = learnings.filter((l) => l.type === \"test_generated\" && l.passedFirstTime).length;\n\n return {\n totalLearnings: learnings.length,\n successfulFixes: successfulFixes.length,\n selectorFixes: selectorFixes.length,\n timingFixes: timingFixes.length,\n testsGenerated: totalTests,\n firstAttemptSuccessRate: totalTests > 0 ? Math.round((firstAttemptSuccess / totalTests) * 100) : 0,\n };\n}\n\nexport function analyzeTestStability() {\n const memory = loadProjectMemory();\n const executions = memory.executions || [];\n \n if (executions.length === 0) return { tests: [], message: \"Nenhuma execução registrada ainda.\" };\n\n const byTest = {};\n executions.forEach((ex) => {\n if (!byTest[ex.testFile]) {\n byTest[ex.testFile] = { total: 0, passed: 0, failed: 0, durations: [] };\n }\n byTest[ex.testFile].total++;\n if (ex.passed) byTest[ex.testFile].passed++;\n else byTest[ex.testFile].failed++;\n if (ex.duration) byTest[ex.testFile].durations.push(ex.duration);\n });\n\n const tests = Object.entries(byTest).map(([file, data]) => {\n const failureRate = Math.round((data.failed / data.total) * 100);\n const avgDuration = data.durations.length > 0 ? (data.durations.reduce((a, b) => a + b, 0) / data.durations.length).toFixed(1) : 0;\n const stability = failureRate === 0 ? \"stable\" : failureRate < 20 ? \"mostly_stable\" : failureRate < 50 ? \"flaky\" : \"unstable\";\n \n return {\n file,\n total: data.total,\n passed: data.passed,\n failed: data.failed,\n failureRate,\n avgDuration: parseFloat(avgDuration),\n stability,\n };\n }).sort((a, b) => b.failureRate - a.failureRate);\n\n return { tests, message: `Analisadas ${executions.length} execuções de ${tests.length} teste(s).` };\n}\n","export const FLAKY_PATTERNS = [\n { name: \"timing\", regex: /timeout|timed out|exceeded|wait|delay|slow|race condition/i, suggestion: \"Adicione wait explícito (ex: page.waitForSelector) ou aumente o timeout.\" },\n { name: \"ordering\", regex: /order|sequenc|flaky|intermittent|sometimes|random/i, suggestion: \"Issole o teste ou use beforeAll/afterAll para estado limpo. Evite dependência de ordem entre testes.\" },\n { name: \"selector\", regex: /element not found|selector|locator|cy\\.get|page\\.locator|Unable to find/i, suggestion: \"Use seletores estáveis: data-testid, role, texto acessível. Evite classes CSS dinâmicas.\" },\n { name: \"network\", regex: /ECONNREFUSED|network|fetch|axios|request failed|404|500/i, suggestion: \"Mocke APIs ou garanta que o backend esteja rodando. Use retry ou intercept.\" },\n { name: \"shared_state\", regex: /state|cleanup|beforeEach|afterEach|isolation/i, suggestion: \"Garanta beforeEach/afterEach para resetar estado. Evite variáveis globais compartilhadas.\" },\n];\n\nexport function detectFlakyPatterns(runOutput) {\n const detected = [];\n for (const p of FLAKY_PATTERNS) {\n if (p.regex.test(runOutput)) {\n detected.push({ pattern: p.name, suggestion: p.suggestion });\n }\n }\n const confidence = detected.length > 0 ? Math.min(0.5 + detected.length * 0.2, 0.95) : 0;\n return { isLikelyFlaky: confidence > 0.5, confidence, patterns: detected };\n}\n","import path from \"node:path\";\nimport fs from \"node:fs\";\n\nconst PROJECT_ROOT = process.cwd();\n\nexport function detectProjectStructure() {\n const structure = {\n hasTests: false,\n testFrameworks: [],\n testDirs: [],\n hasBackend: false,\n backendDir: null,\n hasFrontend: false,\n frontendDir: null,\n hasMobile: false,\n packageJson: null,\n pythonRequirements: null,\n };\n\n const pkgPath = path.join(PROJECT_ROOT, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n structure.packageJson = JSON.parse(fs.readFileSync(pkgPath, \"utf8\"));\n const deps = {\n ...structure.packageJson.dependencies,\n ...structure.packageJson.devDependencies,\n };\n\n if (deps.cypress) {\n structure.testFrameworks.push(\"cypress\");\n structure.hasTests = true;\n }\n if (deps[\"@playwright/test\"] || deps.playwright) {\n structure.testFrameworks.push(\"playwright\");\n structure.hasTests = true;\n }\n if (deps.webdriverio || deps[\"@wdio/cli\"]) {\n structure.testFrameworks.push(\"webdriverio\");\n structure.hasTests = true;\n }\n\n if (deps.jest) {\n structure.testFrameworks.push(\"jest\");\n structure.hasTests = true;\n }\n if (deps.vitest) {\n structure.testFrameworks.push(\"vitest\");\n structure.hasTests = true;\n }\n if (deps.mocha) {\n structure.testFrameworks.push(\"mocha\");\n structure.hasTests = true;\n }\n if (deps.jasmine) {\n structure.testFrameworks.push(\"jasmine\");\n structure.hasTests = true;\n }\n\n if (deps.appium || deps[\"appium-webdriverio\"]) {\n structure.testFrameworks.push(\"appium\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n if (deps.detox) {\n structure.testFrameworks.push(\"detox\");\n structure.hasTests = true;\n structure.hasMobile = true;\n }\n\n if (deps.supertest) {\n structure.testFrameworks.push(\"supertest\");\n structure.hasTests = true;\n }\n if (deps[\"@pactum/pactum\"] || deps.pactum) {\n structure.testFrameworks.push(\"pactum\");\n structure.hasTests = true;\n }\n\n if (deps.testcafe || deps[\"testcafe\"]) {\n structure.testFrameworks.push(\"testcafe\");\n structure.hasTests = true;\n }\n if (deps.nightwatch || deps[\"nightwatch\"]) {\n structure.testFrameworks.push(\"nightwatch\");\n structure.hasTests = true;\n }\n if (deps.puppeteer) {\n structure.testFrameworks.push(\"puppeteer\");\n structure.hasTests = true;\n }\n if (deps.codeceptjs || deps[\"codeceptjs\"]) {\n structure.testFrameworks.push(\"codeceptjs\");\n structure.hasTests = true;\n }\n\n if (deps.express || deps.fastify || deps[\"@nestjs/core\"] || deps.koa) {\n structure.hasBackend = true;\n }\n \n if (deps.next || deps.react || deps.vue || deps.svelte || deps.angular) {\n structure.hasFrontend = true;\n }\n }\n\n const requirementsPath = path.join(PROJECT_ROOT, \"requirements.txt\");\n if (fs.existsSync(requirementsPath)) {\n const requirements = fs.readFileSync(requirementsPath, \"utf8\");\n structure.pythonRequirements = requirements;\n\n if (/robotframework/i.test(requirements)) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest/i.test(requirements)) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n if (/behave/i.test(requirements)) {\n structure.testFrameworks.push(\"behave\");\n structure.hasTests = true;\n }\n if (/requests/i.test(requirements)) {\n structure.hasBackend = true;\n }\n }\n\n const commonTestDirs = [\n \"tests\", \"test\", \"e2e\", \"cypress\", \"playwright\", \"__tests__\",\n \"specs\", \"spec\", \"integration\", \"unit\", \"functional\", \"robot\",\n \"features\", \"scenarios\", \"mobile\", \"api\",\n \"playwright-js\", \"puppeteer-js\", \"testcafe-js\", \"wdio-webdriver-io\",\n \"nightwatch-js\", \"codeceptjs\", \"robot-framework\", \"selenium-python\"\n ];\n for (const dir of commonTestDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {\n structure.testDirs.push(dir);\n }\n }\n\n const skipDirs = [\"node_modules\", \".git\", \"dist\", \"build\", \".next\", \".venv\"];\n try {\n const rootEntries = fs.readdirSync(PROJECT_ROOT, { withFileTypes: true });\n for (const e of rootEntries) {\n if (!e.isDirectory() || skipDirs.includes(e.name)) continue;\n const subPath = path.join(PROJECT_ROOT, e.name);\n if (structure.testDirs.includes(e.name)) continue;\n const hasPkg = fs.existsSync(path.join(subPath, \"package.json\"));\n const hasTests = fs.existsSync(path.join(subPath, \"tests\")) ||\n fs.existsSync(path.join(subPath, \"test\")) ||\n fs.existsSync(path.join(subPath, \"e2e\")) ||\n fs.existsSync(path.join(subPath, \"__tests__\")) ||\n fs.existsSync(path.join(subPath, \"specs\"));\n if (hasPkg || hasTests) {\n structure.testDirs.push(e.name);\n }\n }\n } catch {}\n\n for (const dir of structure.testDirs) {\n const subPkg = path.join(PROJECT_ROOT, dir, \"package.json\");\n if (!fs.existsSync(subPkg)) continue;\n try {\n const sub = JSON.parse(fs.readFileSync(subPkg, \"utf8\"));\n const subDeps = { ...(sub.dependencies || {}), ...(sub.devDependencies || {}) };\n const toAdd = [];\n if (subDeps.cypress && !structure.testFrameworks.includes(\"cypress\")) toAdd.push(\"cypress\");\n if ((subDeps[\"@playwright/test\"] || subDeps.playwright) && !structure.testFrameworks.includes(\"playwright\")) toAdd.push(\"playwright\");\n if ((subDeps.webdriverio || subDeps[\"@wdio/cli\"]) && !structure.testFrameworks.includes(\"webdriverio\")) toAdd.push(\"webdriverio\");\n if (subDeps.testcafe && !structure.testFrameworks.includes(\"testcafe\")) toAdd.push(\"testcafe\");\n if (subDeps.nightwatch && !structure.testFrameworks.includes(\"nightwatch\")) toAdd.push(\"nightwatch\");\n if (subDeps.puppeteer && !structure.testFrameworks.includes(\"puppeteer\")) toAdd.push(\"puppeteer\");\n if (subDeps.codeceptjs && !structure.testFrameworks.includes(\"codeceptjs\")) toAdd.push(\"codeceptjs\");\n if (subDeps.jest && !structure.testFrameworks.includes(\"jest\")) toAdd.push(\"jest\");\n toAdd.forEach((fw) => { structure.testFrameworks.push(fw); structure.hasTests = true; });\n } catch {}\n }\n\n for (const dir of structure.testDirs) {\n const reqPath = path.join(PROJECT_ROOT, dir, \"requirements.txt\");\n if (!fs.existsSync(reqPath)) continue;\n try {\n const req = fs.readFileSync(reqPath, \"utf8\");\n if (/robotframework/i.test(req) && !structure.testFrameworks.includes(\"robot\")) {\n structure.testFrameworks.push(\"robot\");\n structure.hasTests = true;\n }\n if (/pytest|selenium/i.test(req) && !structure.testFrameworks.includes(\"pytest\")) {\n structure.testFrameworks.push(\"pytest\");\n structure.hasTests = true;\n }\n } catch {}\n }\n\n const commonBackendDirs = [\"backend\", \"server\", \"api\", \"src\"];\n for (const dir of commonBackendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.backendDir) {\n const hasServerFile = fs.existsSync(path.join(fullPath, \"server.js\")) ||\n fs.existsSync(path.join(fullPath, \"index.js\")) ||\n fs.existsSync(path.join(fullPath, \"app.js\"));\n if (hasServerFile) {\n structure.backendDir = dir;\n }\n }\n }\n\n const commonFrontendDirs = [\"frontend\", \"client\", \"web\", \"app\", \"src\"];\n for (const dir of commonFrontendDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (fs.existsSync(fullPath) && !structure.frontendDir) {\n const hasAppFile = fs.existsSync(path.join(fullPath, \"App.js\")) ||\n fs.existsSync(path.join(fullPath, \"App.tsx\")) ||\n fs.existsSync(path.join(fullPath, \"index.html\"));\n if (hasAppFile) {\n structure.frontendDir = dir;\n }\n }\n }\n\n return structure;\n}\n\nconst UNIVERSAL_TEST_PATTERNS = [\n /\\.(cy|spec|test)\\.(js|ts|jsx|tsx)$/i,\n /_test\\.(js|ts)$/i,\n /\\.robot$/i,\n /\\.feature$/i,\n /^(test_.*|.*_test)\\.py$/i,\n /\\.steps?\\.(js|ts|py)$/i,\n /\\.e2e\\.(js|ts)$/i,\n /\\.it\\.(js|ts)$/i,\n];\n\nexport function isTestFile(name) {\n return UNIVERSAL_TEST_PATTERNS.some((re) => re.test(name));\n}\n\nexport function collectTestFiles(structure, options = {}) {\n const { pattern, framework, maxContentFiles = 0 } = options;\n const results = [];\n\n for (const dir of structure.testDirs) {\n const fullPath = path.join(PROJECT_ROOT, dir);\n const walk = (p, base = \"\") => {\n if (!fs.existsSync(p)) return;\n const entries = fs.readdirSync(p, { withFileTypes: true });\n for (const e of entries) {\n const rel = base ? `${base}/${e.name}` : e.name;\n if (e.isDirectory()) {\n if (e.name === \"node_modules\" || e.name === \".git\" || e.name === \".venv\") continue;\n walk(path.join(p, e.name), rel);\n } else if (e.isFile() && isTestFile(e.name)) {\n const filePath = `${dir}/${rel}`;\n if (pattern && !filePath.toLowerCase().includes(pattern.toLowerCase())) continue;\n const inferredFw = inferFrameworkFromFile(e.name, structure, filePath);\n if (framework && framework !== \"all\" && inferredFw !== framework && !matchesFramework(inferredFw, framework)) continue;\n const entry = { path: filePath, inferredFramework: inferredFw };\n if (maxContentFiles > 0 && results.length < maxContentFiles) {\n try {\n entry.content = fs.readFileSync(path.join(PROJECT_ROOT, filePath), \"utf8\");\n } catch {}\n }\n results.push(entry);\n }\n }\n };\n walk(fullPath);\n }\n return results;\n}\n\nexport function inferFrameworkFromFile(name, structure = {}, filePath = \"\") {\n const pathLower = (filePath || \"\").toLowerCase().replace(/\\\\/g, \"/\");\n if (/[\\/]cypress[\\/\\-]/.test(pathLower)) return \"cypress\";\n if (/[\\/]playwright[\\/\\-]/.test(pathLower)) return \"playwright\";\n if (/[\\/]wdio[\\/\\-]|[\\/]webdriver[\\/\\-]/.test(pathLower)) return \"webdriverio\";\n if (/[\\/]appium[\\/\\-]/.test(pathLower)) return \"appium\";\n if (/[\\/]selenium-python[\\/]|[\\/]pytest[\\/\\-]/.test(pathLower)) return \"pytest\";\n if (/[\\/]robot[\\/\\-]/.test(pathLower)) return \"robot\";\n if (/[\\/]codecept[\\/\\-]/.test(pathLower)) return \"codeceptjs\";\n if (/[\\/]nightwatch[\\/\\-]/.test(pathLower)) return \"nightwatch\";\n if (/[\\/]testcafe[\\/\\-]/.test(pathLower)) return \"testcafe\";\n if (/[\\/]puppeteer[\\/\\-]/.test(pathLower)) return \"puppeteer\";\n if (/[\\/]behave[\\/\\-]|[\\/]features[\\/]/.test(pathLower)) return \"behave\";\n if (/\\.cy\\.(js|ts|jsx|tsx)/i.test(name)) return \"cypress\";\n if (/_test\\.(js|ts)$/i.test(name)) return \"codeceptjs\";\n if (/\\.spec\\.(js|ts|jsx|tsx)/i.test(name)) {\n if (structure?.testFrameworks?.includes(\"webdriverio\")) return \"webdriverio\";\n if (structure?.testFrameworks?.includes(\"appium\")) return \"appium\";\n return \"playwright\";\n }\n if (/\\.test\\.(js|ts|jsx|tsx)/i.test(name)) return structure?.testFrameworks?.includes(\"vitest\") ? \"vitest\" : \"jest\";\n if (/\\.robot$/i.test(name)) return \"robot\";\n if (/\\.feature$/i.test(name)) return \"behave\";\n if (/\\.(py|steps?\\.py)$/i.test(name) || /^(test_.*|.*_test)\\.py$/i.test(name)) return \"pytest\";\n if (/\\.e2e\\.(js|ts)/i.test(name)) return \"playwright\";\n return \"unknown\";\n}\n\nexport function matchesFramework(inferred, requested) {\n const aliases = { spec: [\"playwright\", \"webdriverio\", \"appium\"] };\n if (inferred === requested) return true;\n return aliases[inferred]?.includes(requested);\n}\n\nexport function getFrameworkCwd(structure, preferredDirs) {\n for (const dir of preferredDirs) {\n if (structure.testDirs.includes(dir)) {\n return path.join(PROJECT_ROOT, dir);\n }\n }\n const fallback = structure.testDirs[0];\n return fallback ? path.join(PROJECT_ROOT, fallback) : PROJECT_ROOT;\n}\n\nexport function analyzeCodeRisks() {\n const structure = detectProjectStructure();\n const risks = [];\n\n const srcDirs = [\"src\", \"app\", \"lib\", \"components\", \"pages\", \"api\", \"services\", \"controllers\"];\n const foundDirs = srcDirs.filter((dir) => fs.existsSync(path.join(PROJECT_ROOT, dir)));\n\n foundDirs.forEach((dir) => {\n const fullPath = path.join(PROJECT_ROOT, dir);\n const files = fs.readdirSync(fullPath, { recursive: true }).filter((f) => /\\.(js|ts|jsx|tsx|py)$/.test(f));\n \n const hasTests = structure.testDirs.some((testDir) => {\n const testPath = path.join(PROJECT_ROOT, testDir);\n if (!fs.existsSync(testPath)) return false;\n const testFiles = fs.readdirSync(testPath, { recursive: true });\n return testFiles.some((tf) => tf.includes(dir) || tf.toLowerCase().includes(dir.toLowerCase()));\n });\n\n if (!hasTests && files.length > 0) {\n risks.push({\n area: dir,\n files: files.length,\n risk: files.length > 20 ? \"high\" : files.length > 10 ? \"medium\" : \"low\",\n reason: \"Sem testes detectados para esta área\",\n });\n }\n });\n\n return risks.sort((a, b) => {\n const riskOrder = { high: 3, medium: 2, low: 1 };\n return riskOrder[b.risk] - riskOrder[a.risk];\n });\n}\n","import path from \"node:path\";\nimport fs from \"node:fs\";\n\nconst PROJECT_ROOT = process.cwd();\nconst METRICS_FILE = path.join(PROJECT_ROOT, \".qa-lab-metrics.json\");\n\nexport function parseTestRunResult(runOutput, exitCode) {\n let passed = 0;\n let failed = 0;\n const jestMatch = runOutput.match(/Tests:\\s+(\\d+)\\s+passed(?:,\\s*(\\d+)\\s+failed)?/);\n if (jestMatch) {\n passed = parseInt(jestMatch[1], 10);\n failed = jestMatch[2] ? parseInt(jestMatch[2], 10) : 0;\n }\n return { passed, failed, success: exitCode === 0 };\n}\n\nexport function recordMetricEvent(event) {\n try {\n let data = {};\n if (fs.existsSync(METRICS_FILE)) {\n const raw = fs.readFileSync(METRICS_FILE, \"utf8\");\n try {\n data = JSON.parse(raw);\n } catch {}\n }\n data.events = data.events || [];\n data.events.push({ ...event, timestamp: event.timestamp || new Date().toISOString() });\n data.lastUpdated = new Date().toISOString();\n if (data.events.length > 500) data.events = data.events.slice(-400);\n fs.writeFileSync(METRICS_FILE, JSON.stringify(data, null, 2), \"utf8\");\n } catch {}\n}\n\nexport function extractFailuresFromOutput(runOutput) {\n const failures = [];\n const lines = runOutput.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (/fail|error|assertion|timeout|element not found|selector/i.test(line)) {\n failures.push({\n test: lines[Math.max(0, i - 1)]?.trim() || \"unknown\",\n message: line.trim().slice(0, 500),\n });\n }\n }\n return failures.slice(0, 20);\n}\n\nexport function generateFailureExplanation(testCode, runOutput, memory = {}) {\n const lines = [];\n lines.push(\"# Análise de Falha\\n\");\n lines.push(\"## Código do Teste\");\n lines.push(\"```\");\n lines.push(testCode.slice(0, 2000));\n lines.push(\"```\\n\");\n lines.push(\"## Output da Execução\");\n lines.push(\"```\");\n lines.push(runOutput.slice(0, 2000));\n lines.push(\"```\\n\");\n \n if (memory.learnings && memory.learnings.length > 0) {\n lines.push(\"## Aprendizados Anteriores (últimos 5)\");\n memory.learnings.slice(-5).forEach((l) => {\n lines.push(`- **${l.type}**: ${l.description || \"N/A\"}`);\n });\n lines.push(\"\");\n }\n \n lines.push(\"## Sua Tarefa\");\n lines.push(\"1. Identifique a causa raiz da falha\");\n lines.push(\"2. Sugira uma correção específica\");\n lines.push(\"3. Explique por que essa correção deve funcionar\");\n \n return lines.join(\"\\n\");\n}\n","import path from \"node:path\";\nimport fs from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { detectProjectStructure, getFrameworkCwd } from \"../core/project-structure.js\";\nimport { loadProjectMemory, saveProjectMemory, getMemoryStats, analyzeTestStability } from \"../core/memory.js\";\nimport { resolveLLMProvider } from \"../core/llm-router.js\";\nimport { detectFlakyPatterns } from \"../core/flaky-detection.js\";\nimport { analyzeCodeRisks } from \"../core/project-structure.js\";\n\nconst PROJECT_ROOT = process.cwd();\n\nconst QA_AGENTS = {\n autonomous: { desc: \"Modo autônomo: gera, testa, corrige e aprende\", tools: [\"qa_auto\"] },\n detection: { desc: \"Detecta estrutura, frameworks, testes\", tools: [\"detect_project\", \"read_project\", \"list_test_files\"] },\n execution: { desc: \"Executa testes, coverage, watch\", tools: [\"run_tests\", \"watch_tests\", \"get_test_coverage\"] },\n generation: { desc: \"Gera e escreve testes\", tools: [\"generate_tests\", \"write_test\", \"create_test_template\"] },\n analysis: { desc: \"Analisa falhas, sugere correções\", tools: [\"analyze_failures\", \"por_que_falhou\", \"suggest_fix\", \"suggest_selector_fix\", \"analyze_file_methods\"] },\n browser: { desc: \"Browser mode: screenshots, network, console\", tools: [\"web_eval_browser\"] },\n reporting: { desc: \"Relatórios e métricas\", tools: [\"create_bug_report\", \"get_business_metrics\"] },\n intelligence: { desc: \"Análise preditiva e insights\", tools: [\"qa_full_analysis\", \"qa_health_check\", \"qa_suggest_next_test\", \"qa_predict_flaky\", \"qa_compare_with_industry\", \"qa_time_travel\"] },\n learning: { desc: \"Sistema de aprendizado\", tools: [\"qa_learning_stats\"] },\n maintenance: { desc: \"Linter, deps, análise de código\", tools: [\"run_linter\", \"install_dependencies\"] },\n};\n\nfunction getExtensionAndBaseDir(fw, structure) {\n const extMap = { cypress: \".cy.js\", playwright: \".spec.js\", jest: \".test.js\", vitest: \".test.js\", robot: \".robot\", pytest: \".py\" };\n const ext = extMap[fw] || \".spec.js\";\n const baseDir = structure.testDirs[0] ? path.join(PROJECT_ROOT, structure.testDirs[0]) : path.join(PROJECT_ROOT, \"tests\");\n return { ext, baseDir };\n}\n\nexport async function handleCLI() {\n const cmd = process.argv[2];\n\n if (cmd === \"--help\" || cmd === \"-h\") {\n console.log(`\nmcp-lab-agent - Executor + Consultor Inteligente de QA\n\nUSO:\n mcp-lab-agent [comando] # Sem comando: inicia servidor MCP\n mcp-lab-agent --help # Mostra esta ajuda\n\nCOMANDOS CLI:\n analyze [NOVO] Análise completa: executa, analisa estabilidade, prevê riscos e recomenda ações\n auto <descrição> [--max-retries N] Modo autônomo: gera teste, roda, corrige e aprende (default: 3 tentativas)\n stats Mostra estatísticas de aprendizado (taxa de sucesso, correções, etc.)\n detect [--json] Detecta frameworks e estrutura\n route <tarefa> Sugere qual ferramenta usar\n list Lista ferramentas MCP disponíveis\n\nEXEMPLOS:\n mcp-lab-agent analyze # Análise completa + recomendações\n mcp-lab-agent auto \"login flow\" --max-retries 5\n mcp-lab-agent stats\n mcp-lab-agent detect --json\n\nINTEGRAÇÃO MCP (Cursor/Cline/Windsurf):\n Adicione ao ~/.cursor/mcp.json:\n {\n \"mcpServers\": {\n \"qa-lab-agent\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"mcp-lab-agent\"],\n \"cwd\": \"\\${workspaceFolder}\"\n }\n }\n }\n\nAMBIENTES CORPORATIVOS (APIs bloqueadas):\n Use Ollama (100% offline):\n brew install ollama\n ollama pull llama3.1:8b\n ollama serve\n mcp-lab-agent analyze # Funciona sem internet!\n`);\n return true;\n }\n\n if (cmd === \"detect\") {\n const structure = detectProjectStructure();\n const jsonOnly = process.argv.includes(\"--json\");\n if (jsonOnly) {\n console.log(JSON.stringify(structure, null, 2));\n } else {\n const lines = [\n \"\",\n \"mcp-lab-agent · detecção\",\n \"─\".repeat(40),\n `Frameworks: ${structure.testFrameworks.length ? structure.testFrameworks.join(\", \") : \"nenhum\"}`,\n `Pastas: ${structure.testDirs.length ? structure.testDirs.join(\", \") : \"nenhuma\"}`,\n `Backend: ${structure.backendDir || \"—\"}`,\n `Frontend: ${structure.frontendDir || \"—\"}`,\n `Mobile: ${structure.hasMobile ? \"sim\" : \"—\"}`,\n \"─\".repeat(40),\n \"(use --json para saída completa)\",\n \"\",\n ];\n console.log(lines.join(\"\\n\"));\n }\n return true;\n }\n\n if (cmd === \"list\") {\n const agents = Object.entries(QA_AGENTS).map(([k, v]) => ` ${k}: ${v.tools.join(\", \")}`);\n console.log(\"Agentes e ferramentas:\\n\" + agents.join(\"\\n\"));\n return true;\n }\n\n if (cmd === \"route\" && process.argv[3]) {\n const task = process.argv.slice(3).join(\" \");\n const t = task.toLowerCase();\n let agent = \"detection\";\n if (/autônomo|auto|completo|loop|aprende|corrige automaticamente/i.test(t)) agent = \"autonomous\";\n else if (/estatística|métrica de aprendizado|taxa de sucesso|learning|stats/i.test(t)) agent = \"learning\";\n else if (/rodar|executar|run|test|coverage|watch/i.test(t)) agent = \"execution\";\n else if (/gerar|criar|escrever|generate|write|template/i.test(t)) agent = \"generation\";\n else if (/analisar|por que|falhou|sugerir|fix|selector/i.test(t)) agent = \"analysis\";\n else if (/browser|navegador|screenshot|network|console/i.test(t)) agent = \"browser\";\n else if (/relatório|métrica|bug report/i.test(t)) agent = \"reporting\";\n else if (/linter|dependência|instalar|analisar método/i.test(t)) agent = \"maintenance\";\n const a = QA_AGENTS[agent] || QA_AGENTS.detection;\n console.log(JSON.stringify({ suggestedAgent: agent, suggestedTools: a.tools, description: a.desc }, null, 2));\n return true;\n }\n\n if (cmd === \"auto\") {\n await handleAutoCommand();\n return true;\n }\n\n if (cmd === \"stats\") {\n const stats = getMemoryStats();\n console.log(`\n📊 Estatísticas de Aprendizado\n\nTotal de aprendizados: ${stats.totalLearnings}\nCorreções bem-sucedidas: ${stats.successfulFixes}\nCorreções de seletores: ${stats.selectorFixes}\nCorreções de timing: ${stats.timingFixes}\nTestes gerados: ${stats.testsGenerated}\nTaxa de sucesso na 1ª tentativa: ${stats.firstAttemptSuccessRate}%\n\n${stats.totalLearnings === 0 ? \"⚠️ Ainda não há aprendizados. Use 'mcp-lab-agent auto <descrição>' para gerar testes e aprender com erros.\" : \"\"}\n`);\n return true;\n }\n\n if (cmd === \"analyze\") {\n await handleAnalyzeCommand();\n return true;\n }\n\n return false;\n}\n\nasync function handleAutoCommand() {\n const request = process.argv.slice(3).join(\" \");\n if (!request) {\n console.error(\"❌ Uso: mcp-lab-agent auto <descrição do teste> [--max-retries N]\");\n process.exit(1);\n }\n const maxRetriesIdx = process.argv.indexOf(\"--max-retries\");\n const maxRetries = maxRetriesIdx !== -1 && process.argv[maxRetriesIdx + 1] ? parseInt(process.argv[maxRetriesIdx + 1], 10) : 3;\n const cleanRequest = request.replace(/--max-retries\\s+\\d+/g, \"\").trim();\n\n console.log(`\\n🤖 Modo autônomo iniciado: \"${cleanRequest}\"\\n`);\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0];\n if (!fw) {\n console.error(\"❌ Nenhum framework detectado.\");\n process.exit(1);\n }\n\n const llm = resolveLLMProvider(\"simple\");\n if (!llm.apiKey) {\n console.error(\"❌ Configure GROQ_API_KEY, GEMINI_API_KEY ou OPENAI_API_KEY no .env\");\n process.exit(1);\n }\n\n const memory = loadProjectMemory();\n const contextLines = [\n `Frameworks: ${structure.testFrameworks.join(\", \")}`,\n `Pastas: ${structure.testDirs.join(\", \")}`,\n memory.flows?.length ? `Fluxos: ${memory.flows.map((f) => f.name || f.id).join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n let testFilePath = null;\n let testContent = null;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Gerando teste...`);\n\n const { provider, apiKey, baseUrl, model } = llm;\n const memoryHints = memory.learnings?.filter((l) => l.success).slice(-10).map((l) => l.fix).join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${memoryHints ? `\\nAprendizados anteriores (use como referência):\\n${memoryHints.slice(0, 1000)}` : \"\"}\nRetorne SOMENTE o código, sem markdown.`;\n\n const userPrompt = `Contexto:\\n${contextLines}\\n\\nGere teste para: ${cleanRequest}\\nFramework: ${fw}`;\n\n try {\n let specContent = \"\";\n if (provider === \"gemini\") {\n const url = `${baseUrl}/models/${model}:generateContent?key=${apiKey}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n contents: [{ parts: [{ text: systemPrompt + \"\\n\\n\" + userPrompt }] }],\n generationConfig: { temperature: 0.3, maxOutputTokens: 4096 },\n }),\n });\n const data = await res.json();\n specContent = data.candidates?.[0]?.content?.parts?.[0]?.text || \"\";\n } else {\n const res = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n model,\n messages: [{ role: \"system\", content: systemPrompt }, { role: \"user\", content: userPrompt }],\n temperature: 0.3,\n max_tokens: 4096,\n }),\n });\n const data = await res.json();\n specContent = data.choices?.[0]?.message?.content || \"\";\n }\n specContent = specContent.replace(/^```(?:js|javascript|typescript)?\\n?/i, \"\").replace(/\\n?```\\s*$/i, \"\").trim();\n testContent = specContent;\n\n if (!testFilePath) {\n const fileName = cleanRequest.toLowerCase().replace(/\\s+/g, \"-\").replace(/[^a-z0-9-]/g, \"\").slice(0, 30);\n const { ext, baseDir } = getExtensionAndBaseDir(fw, structure);\n const safeName = fileName + ext;\n testFilePath = path.join(baseDir, safeName);\n if (!fs.existsSync(baseDir)) fs.mkdirSync(baseDir, { recursive: true });\n }\n fs.writeFileSync(testFilePath, testContent, \"utf8\");\n console.log(`✅ Teste gravado: ${testFilePath}`);\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Executando teste...`);\n const runResult = await new Promise((resolve) => {\n const child = spawn(\"npx\", [fw === \"cypress\" ? \"cypress\" : fw === \"playwright\" ? \"playwright\" : fw, fw === \"cypress\" ? \"run\" : fw === \"playwright\" ? \"test\" : \"run\", testFilePath], {\n cwd: PROJECT_ROOT,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n });\n let stdout = \"\", stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); });\n child.on(\"close\", (code) => resolve({ code, output: [stdout, stderr].filter(Boolean).join(\"\\n\") }));\n });\n\n if (runResult.code === 0) {\n console.log(`\\n✅ Teste passou na tentativa ${attempt}!`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: true, passedFirstTime: attempt === 1, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n console.log(`\\n📊 Aprendizado salvo. Use \"mcp-lab-agent stats\" para ver métricas.\\n`);\n process.exit(0);\n }\n\n console.log(`\\n❌ Teste falhou (exit ${runResult.code})`);\n console.log(`\\nSaída:\\n${runResult.output.slice(0, 800)}\\n`);\n\n if (attempt >= maxRetries) {\n console.log(`\\n❌ Limite de tentativas atingido (${maxRetries}).\\n`);\n saveProjectMemory({\n learnings: [{ type: \"test_generated\", request: cleanRequest, framework: fw, success: false, attempts: attempt, timestamp: new Date().toISOString() }],\n });\n process.exit(1);\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Analisando falha...`);\n const flakyAnalysis = detectFlakyPatterns(runResult.output);\n if (flakyAnalysis.isLikelyFlaky) {\n console.log(`⚠️ Flaky detectado (${flakyAnalysis.confidence.toFixed(2)}): ${flakyAnalysis.patterns.map((p) => p.pattern).join(\", \")}`);\n }\n\n console.log(`\\n[Tentativa ${attempt}/${maxRetries}] Aplicando correção (simulada)...`);\n console.log(`⚠️ Correção automática ainda não implementada nesta versão CLI. Tentando novamente...`);\n } catch (err) {\n console.error(`\\n❌ Erro na tentativa ${attempt}: ${err.message}\\n`);\n process.exit(1);\n }\n }\n\n console.log(`\\n❌ Falhou após ${maxRetries} tentativa(s).\\n`);\n process.exit(1);\n}\n\nasync function handleAnalyzeCommand() {\n console.log(\"\\n🤖 Análise completa iniciada...\\n\");\n \n const structure = detectProjectStructure();\n console.log(\"[1/4] 🔍 Detectando estrutura...\");\n console.log(`✅ ${structure.testFrameworks.join(\", \")} detectado(s)\\n`);\n\n const testFiles = structure.testDirs.flatMap((dir) => {\n const fullPath = path.join(PROJECT_ROOT, dir);\n if (!fs.existsSync(fullPath)) return [];\n return fs.readdirSync(fullPath, { recursive: true })\n .filter((f) => /\\.(spec|test|cy)\\.(js|ts|jsx|tsx|py)$/.test(f));\n });\n console.log(`✅ ${testFiles.length} teste(s) encontrado(s)\\n`);\n\n console.log(\"[2/4] 🧠 Analisando estabilidade...\");\n const stabilityAnalysis = analyzeTestStability();\n const unstableTests = stabilityAnalysis.tests.filter((t) => t.failureRate > 20);\n \n if (unstableTests.length > 0) {\n console.log(`⚠️ ${unstableTests.length} teste(s) instável(is):`);\n unstableTests.slice(0, 3).forEach((t) => {\n console.log(` - ${t.file}: ${t.failureRate}% de falha (${t.failed}/${t.total} execuções)`);\n });\n } else {\n console.log(\"✅ Todos os testes são estáveis\");\n }\n console.log();\n\n console.log(\"[3/4] 🔮 Analisando riscos por área...\");\n const codeRisks = analyzeCodeRisks();\n const highRisks = codeRisks.filter((r) => r.risk === \"high\");\n \n if (highRisks.length > 0) {\n console.log(`🔴 ${highRisks.length} área(s) de RISCO ALTO:`);\n highRisks.slice(0, 3).forEach((r) => {\n console.log(` - ${r.area}/: ${r.files} arquivo(s) sem testes`);\n });\n } else {\n console.log(\"✅ Todas as áreas principais têm cobertura\");\n }\n console.log();\n\n console.log(\"[4/4] 💡 Gerando recomendações...\\n\");\n\n const actions = [];\n unstableTests.forEach((t) => {\n actions.push({ priority: \"🔴 URGENTE\", action: `Refatore ${t.file} (falha ${t.failureRate}%)`, command: `mcp-lab-agent auto \"corrigir ${t.file}\"` });\n });\n highRisks.forEach((r) => {\n actions.push({ priority: \"🔴 URGENTE\", action: `Adicione testes para ${r.area}/`, command: `mcp-lab-agent auto \"testes para ${r.area}\"` });\n });\n\n let score = 100;\n score -= unstableTests.length * 10;\n score -= highRisks.length * 15;\n score = Math.max(0, score);\n\n const emoji = score >= 80 ? \"🚀\" : score >= 60 ? \"✅\" : \"⚠️\";\n\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\n console.log(`${emoji} RELATÓRIO COMPLETO\\n`);\n console.log(`Nota: ${score}/100\\n`);\n console.log(\"AÇÕES RECOMENDADAS:\\n\");\n \n actions.slice(0, 5).forEach((a, i) => {\n console.log(`${i + 1}. ${a.priority}: ${a.action}`);\n console.log(` → ${a.command}\\n`);\n });\n\n if (actions.length === 0) {\n console.log(\"✅ Projeto em excelente estado!\\n\");\n }\n\n console.log(\"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\");\n}\n"],"mappings":"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","names":["spawn","path","fs","model","FLOWS_CONFIG_FILE","path","fs","PROJECT_ROOT","path","fs","PROJECT_ROOT","path","fs","PROJECT_ROOT","path","fs","PROJECT_ROOT","path","METRICS_FILE","fs","QA_AGENTS","spawn","getExtensionAndBaseDir","res","data"]}
|