mcp-lab-agent 2.1.6 → 2.1.10

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js","../src/core/llm-router.js","../src/core/memory.js","../src/core/hub-client.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\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\n\nimport { resolveLLMProvider, TASK_COMPLEXITY } from \"./core/llm-router.js\";\nimport { loadProjectMemory, saveProjectMemory, getMemoryStats, analyzeTestStability } from \"./core/memory.js\";\nimport { detectFlakyPatterns, detectMobileMappingInvisible, formatLearnedMessageForUser, MOBILE_MAPPING_LESSON, inferFailurePattern, UNIVERSAL_TEST_PRACTICES } 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, ambiente (web/mobile) e hints para geração de testes.\",\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 hasMobile: z.boolean().optional(),\n environment: z.string().optional(),\n environmentHints: z.array(z.string()).optional(),\n }),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const envLine = structure.environment\n ? `Ambiente: ${structure.environment}${structure.environmentHints?.length ? ` (${structure.environmentHints.join(\", \")})` : \"\"}`\n : \"\";\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 ...(envLine ? [envLine] : []),\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\", \"map_mobile_elements\"], 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\", \"get_learning_report\", \"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 (/mapear|elementos mobile|deep link|deeplink|app package|bundle.?id|appium inspector/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → map_mobile_elements (mapear elementos), depois generate_tests + write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: [\"map_mobile_elements\", \"generate_tests\", \"write_test\"], description: QA_AGENTS.generation.desc } };\n }\n if (/mapear|elementos mobile|deep link|deeplink|app package|bundle.?id/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → map_mobile_elements (mapear elementos), depois generate_tests + write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: [\"map_mobile_elements\", \"generate_tests\", \"write_test\"], description: \"Mapeamento de elementos mobile + geração de testes\" } };\n }\n if (/mobile|deeplink|deep link|elementos|mapear.*app|appium|detox/i.test(t) && !/rodar|run|executar/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → map_mobile_elements, generate_tests, write_test (mobile)\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: QA_AGENTS.generation.tools, description: QA_AGENTS.generation.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, map_mobile_elements\" }], 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\n${UNIVERSAL_TEST_PRACTICES}\n${(fw === \"appium\" || fw === \"detox\") ? `\\nIMPORTANTE: ${MOBILE_MAPPING_LESSON}` : \"\"}`\n : `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\nFramework: ${fw}\n\n${UNIVERSAL_TEST_PRACTICES}\n\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${(fw === \"appium\" || fw === \"detox\") ? `\\n\\nIMPORTANTE (Appium/Detox): ${MOBILE_MAPPING_LESSON}` : \"\"}`;\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 \"map_mobile_elements\",\n {\n title: \"Mapear elementos mobile (estrutura para testes)\",\n description: \"Gera estrutura/template de elementos para testes mobile. Aceita deep link, appPackage/appActivity (Android) ou bundleId (iOS). Retorna instruções para mapear elementos (Appium Inspector, uiautomator) e template para usar em generate_tests. Se elementsJsonPath fornecido, lê arquivo e formata para contexto.\",\n inputSchema: z.object({\n deepLink: z.string().optional().describe(\"Deep link do app (ex: meuapp://login). Indica ambiente mobile.\"),\n appPackage: z.string().optional().describe(\"Android: package do app (ex: com.example.app).\"),\n appActivity: z.string().optional().describe(\"Android: activity principal (ex: .MainActivity).\"),\n bundleId: z.string().optional().describe(\"iOS: bundle identifier do app.\"),\n elementsJsonPath: z.string().optional().describe(\"Caminho para arquivo JSON com elementos mapeados (id, text, accessibilityId, xpath).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n environment: z.string().optional(),\n elements: z.array(z.object({\n id: z.string().optional(),\n text: z.string().optional(),\n accessibilityId: z.string().optional(),\n xpath: z.string().optional(),\n resourceId: z.string().optional(),\n className: z.string().optional(),\n })).optional(),\n instructions: z.string().optional(),\n contextForGenerate: z.string().optional().describe(\"Texto formatado para passar em generate_tests como contexto.\"),\n error: z.string().optional(),\n }),\n },\n async ({ deepLink, appPackage, appActivity, bundleId, elementsJsonPath }) => {\n const hasMobileContext = deepLink || appPackage || bundleId;\n const elements = [];\n let instructions = \"\";\n let contextForGenerate = \"\";\n\n if (elementsJsonPath) {\n const fullPath = path.join(PROJECT_ROOT, elementsJsonPath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(fullPath)) {\n try {\n const raw = fs.readFileSync(fullPath, \"utf8\");\n const parsed = JSON.parse(raw);\n const arr = Array.isArray(parsed) ? parsed : (parsed.elements || parsed.items || []);\n arr.forEach((el) => {\n elements.push({\n id: el.id || el.resourceId,\n text: el.text || el.label,\n accessibilityId: el.accessibilityId || el[\"content-desc\"] || el.contentDesc,\n xpath: el.xpath,\n resourceId: el.resourceId || el.id,\n className: el.className || el.class,\n });\n });\n contextForGenerate = `\\nElementos mapeados da tela (use para seletores estáveis em Appium/WDIO):\\n${JSON.stringify(elements, null, 2)}\\n`;\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler ${elementsJsonPath}: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n } else {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${elementsJsonPath}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n }\n\n if (hasMobileContext || elementsJsonPath) {\n instructions = [\n \"## Como mapear elementos do app mobile\",\n \"\",\n \"**Android (Appium):**\",\n \"- Use Appium Inspector (appium.io) com appPackage/appActivity\",\n \"- Ou: `adb shell uiautomator dump` → analise o XML exportado\",\n \"- Priorize: accessibility-id > resource-id > xpath relativo\",\n \"\",\n \"**iOS (Appium):**\",\n \"- Appium Inspector com bundleId\",\n \"- Xcode Accessibility Inspector\",\n \"- Priorize: accessibility-id > name\",\n \"\",\n \"**Formato esperado (elements.json):**\",\n \"```json\",\n '[{\"accessibilityId\": \"login_btn\", \"text\": \"Entrar\", \"resourceId\": \"com.app:id/btn\"}]',\n \"```\",\n \"\",\n \"Salve em um arquivo e passe em `elementsJsonPath` na próxima chamada.\",\n ].join(\"\\n\");\n }\n\n const env = deepLink ? \"mobile\" : (appPackage || bundleId) ? \"mobile\" : elements.length ? \"mobile\" : \"unknown\";\n const text = [\n contextForGenerate && `## Contexto para generate_tests\\n${contextForGenerate}`,\n instructions && `## Instruções\\n${instructions}`,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return {\n content: [{ type: \"text\", text: text || (hasMobileContext ? `Ambiente: ${env}. ${instructions}` : \"Informe deepLink, appPackage ou elementsJsonPath.\") }],\n structuredContent: {\n ok: true,\n environment: env,\n elements: elements.length ? elements : undefined,\n instructions: instructions || undefined,\n contextForGenerate: contextForGenerate || undefined,\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 \"get_learning_report\",\n {\n title: \"Relatório de evolução e aprendizado\",\n description: \"Gera relatório de evolução dos aprendizados: resumo por tipo, evolução no tempo e recomendações para aprimorar o código.\",\n inputSchema: z.object({\n format: z.enum([\"summary\", \"full\"]).optional().describe(\"summary = resumo executivo, full = relatório completo com recomendações. Default: summary\"),\n }),\n outputSchema: z.object({\n summary: z.string(),\n byType: z.record(z.number()),\n evolution: z.array(z.object({ date: z.string(), type: z.string(), framework: z.string() })).optional(),\n recommendations: z.array(z.string()).optional(),\n }),\n },\n async ({ format = \"summary\" }) => {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const stats = getMemoryStats();\n\n const byType = stats.byLearningType || {};\n const evolution = format === \"full\" && learnings.length > 0\n ? learnings.slice(-30).map((l) => ({\n date: (l.timestamp || \"\").slice(0, 10),\n type: l.type || \"unknown\",\n framework: l.framework || \"-\",\n }))\n : [];\n\n const recommendations = [];\n if (byType.element_not_rendered > 0 || byType.element_not_visible > 0) {\n recommendations.push(\"Use waits explícitos (waitForSelector, waitForDisplayed) ANTES de interagir com elementos.\");\n }\n if (byType.timing_fix > 0 || byType.element_stale > 0) {\n recommendations.push(\"Aumente timeouts e use re-localização de elementos em listas dinâmicas.\");\n }\n if (byType.selector_fix > 0 || byType.mobile_mapping_invisible > 0) {\n recommendations.push(\"Priorize data-testid, role e seletores estáveis; em mobile, use mapeamento visível no topo do spec.\");\n }\n if (stats.firstAttemptSuccessRate < 70 && stats.testsGenerated > 0) {\n recommendations.push(\"Aplique UNIVERSAL_TEST_PRACTICES em cada teste gerado: waits inteligentes + assert final.\");\n }\n if (recommendations.length === 0 && learnings.length > 0) {\n recommendations.push(\"Continue aplicando as práticas aprendidas em novos testes.\");\n }\n\n const summary = `📈 **Relatório de Evolução e Aprendizado**\n\n**Resumo por tipo:**\n${Object.entries(byType).filter(([, v]) => v > 0).map(([t, v]) => `- ${t}: ${v}`).join(\"\\n\") || \"- Nenhum aprendizado por tipo ainda\"}\n\n**Métricas gerais:**\n- Total de aprendizados: ${stats.totalLearnings}\n- Taxa de sucesso (1ª tentativa): ${stats.firstAttemptSuccessRate}%\n- Testes gerados: ${stats.testsGenerated}\n\n${format === \"full\" && recommendations.length > 0 ? `**Recomendações para aprimorar o código:**\\n${recommendations.map((r) => `• ${r}`).join(\"\\n\")}` : \"\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n summary: summary.trim(),\n byType,\n evolution: format === \"full\" ? evolution : undefined,\n recommendations: format === \"full\" ? recommendations : undefined,\n },\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 let appliedLearningFix = false;\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\n ?.filter((l) => l.fix)\n .slice(-10)\n .map((l) => l.fix)\n .join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${UNIVERSAL_TEST_PRACTICES}\n\n${memoryHints ? `Aprendizados 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 const learnedAppendix = appliedLearningFix ? `\\n\\n${formatLearnedMessageForUser({ runOutput: runResult?.output, fixSummary: \"Ajustei o código aplicando waits e validação correta.\", framework: fw })}` : \"\";\n return {\n content: [{ type: \"text\", text: `✅ Teste passou na tentativa ${attempt}!\\n\\nArquivo: ${testFilePath}\\n\\nAprendizados salvos.${learnedAppendix}` }],\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 const learnedAppendix = appliedLearningFix\n ? `\\n\\n${formatLearnedMessageForUser({ runOutput: runResult.output, framework: fw, fixSummary: \"Tentei corrigir. Nas próximas execuções usarei esse aprendizado desde o início.\" })}`\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)}${learnedAppendix}` }],\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 const inferredPattern = inferFailurePattern(runResult.output, fw);\n const learningType = inferredPattern?.learningType || (flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\");\n const learningFix = inferredPattern?.lesson || fixedCode.slice(0, 500);\n saveProjectMemory({\n learnings: [{\n type: learningType,\n request,\n framework: fw,\n fix: learningFix,\n pattern: inferredPattern?.name,\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n appliedLearningFix = true;\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 const learnedAppendix = appliedLearningFix\n ? `\\n\\n${formatLearnedMessageForUser({ fixSummary: \"Tentei corrigir. Nas próximas execuções usarei esse aprendizado desde o início.\" })}`\n : \"\";\n return {\n content: [{ type: \"text\", text: `❌ Falhou após ${maxRetries} tentativa(s).${learnedAppendix}` }],\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 if (cmd === \"learning-hub\") {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const hubPath = path.join(__dirname, \"..\", \"learning-hub\", \"src\", \"server.js\");\n const hubUrl = pathToFileURL(hubPath).href;\n await import(hubUrl);\n return;\n }\n if (cmd === \"slack-bot\") {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const slackBotPath = path.join(__dirname, \"..\", \"slack-bot\", \"src\", \"index.js\");\n const slackBotUrl = pathToFileURL(slackBotPath).href;\n await import(slackBotUrl);\n return; // never reached (slack-bot runs until exit)\n }\n\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\";\nimport { syncLearningsToHub } from \"./hub-client.js\";\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 syncLearningsToHub(updates.learnings).catch(() => {});\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\nconst LEARNING_TYPES = [\"selector_fix\", \"timing_fix\", \"element_not_rendered\", \"element_not_visible\", \"element_stale\", \"mobile_mapping_invisible\"];\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 byLearningType = {};\n for (const t of LEARNING_TYPES) {\n byLearningType[t] = learnings.filter((l) => l.type === t).length;\n }\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 byLearningType,\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","/**\n * Cliente para o Learning Hub - envia learnings de forma assíncrona.\n * Se LEARNING_HUB_URL estiver configurado, saveProjectMemory envia para o Hub.\n */\n\nlet hubUrl = null;\n\nexport function setHubUrl(url) {\n hubUrl = (url || \"\").replace(/\\/$/, \"\");\n}\n\nexport function getHubUrl() {\n if (hubUrl) return hubUrl;\n const env = process.env.LEARNING_HUB_URL || process.env.QA_LAB_LEARNING_HUB_URL;\n if (env) {\n hubUrl = env.replace(/\\/$/, \"\");\n return hubUrl;\n }\n return null;\n}\n\nexport function isHubEnabled() {\n return !!getHubUrl();\n}\n\n/**\n * Envia learnings para o Hub. Assíncrono, não bloqueia.\n * Adiciona projectId (cwd ou env) para rastreamento.\n */\nexport async function syncLearningsToHub(learnings) {\n const baseUrl = getHubUrl();\n if (!baseUrl) return;\n\n const entries = Array.isArray(learnings) ? learnings : [learnings];\n if (entries.length === 0) return;\n\n const projectId = process.env.LEARNING_HUB_PROJECT_ID || process.cwd().split(\"/\").pop() || \"default\";\n\n const payload = entries.map((e) => ({\n ...e,\n projectId,\n }));\n\n try {\n const res = await fetch(`${baseUrl}/learning`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ learnings: payload }),\n });\n if (!res.ok) {\n const txt = await res.text();\n console.warn(`[learning-hub] POST /learning failed ${res.status}: ${txt}`);\n }\n } catch (err) {\n console.warn(\"[learning-hub] sync failed:\", err.message);\n }\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\n/**\n * Padrões de falha com mensagem adaptada e lição específica.\n * Ordem importa: o primeiro que bater é usado.\n */\nexport const FAILURE_ANALYSIS_PATTERNS = [\n {\n name: \"element_not_rendered\",\n regex: /timeout|not found|element not found|no such element|element.*not.*in.*dom|waiting for/i,\n oQueAconteceu: \"O elemento ainda não foi renderizado no DOM quando o teste tentou interagir. Pode ser carregamento assíncrono, lazy load ou animação.\",\n lesson: `Espere o elemento estar disponível ANTES de interagir:\n- Playwright: await element.waitFor({ state: 'attached' }) ou waitForSelector\n- Cypress: cy.get(sel).should('exist') antes de clicar\n- WDIO/Appium: $(sel).waitForDisplayed() ou waitForExist({ timeout: 10000 })\n- Use waits inteligentes: waitForDisplayed, waitForClickable, waitForExist`,\n learningType: \"element_not_rendered\",\n },\n {\n name: \"element_not_visible\",\n regex: /element.*not.*visible|not visible|is not visible|element is not displayed|hidden|display.*none|off.?screen/i,\n oQueAconteceu: \"O elemento existe no DOM mas não está visível (display:none, off-screen, opacity:0 ou ainda carregando).\",\n lesson: `Verifique visibilidade antes de interagir:\n- Playwright: waitFor({ state: 'visible' })\n- Cypress: .should('be.visible') antes de click\n- Appium/WDIO: waitForDisplayed() ou isDisplayed()\n- Adicione wait explícito: elemento pode estar em animação ou carregando`,\n learningType: \"element_not_visible\",\n },\n {\n name: \"element_stale\",\n regex: /stale element|stale element reference|element.*no longer attached/i,\n oQueAconteceu: \"O elemento foi encontrado mas a página/DOM mudou antes da interação (elemento ficou obsoleto).\",\n lesson: `Re-localize o elemento antes de cada ação:\n- Evite guardar referência: busque novamente antes de clicar\n- Use waits que revalidam: cy.get().first().click() com retry\n- Em listas dinâmicas: espere estabilização antes de interagir`,\n learningType: \"element_stale\",\n },\n {\n name: \"mobile_mapping_invisible\",\n regex: /element not found|selector|Unable to find|no such element/i,\n oQueAconteceu: \"Em mobile: o mapeamento ficou invisível ou os seletores não estão estruturados. Pode ser estrutura do código ou seletor incorreto.\",\n lesson: `Em testes mobile (Appium/Detox), SEMPRE:\n- Mapeamento VISÍVEL: const ELEMENTS = { btn: '~id' }; $(ELEMENTS.btn).click()\n- Antes de clicar: $(sel).waitForDisplayed({ timeout: 10000 })\n- Ao final: expect(await $(sel).isDisplayed()).toBe(true) — validação explícita para o usuário entender que houve validação`,\n learningType: \"mobile_mapping_invisible\",\n mobileOnly: true,\n },\n {\n name: \"selector\",\n regex: /selector|locator|element not found|Unable to find/i,\n oQueAconteceu: \"O seletor não encontrou o elemento. Pode ser seletor incorreto, mudança de UI ou elemento em outro contexto (iframe, shadow DOM).\",\n lesson: \"Use seletores estáveis: data-testid, role+name, accessibility-id. Evite classes CSS dinâmicas. Priorize: data-testid > role > texto visível.\",\n learningType: \"selector_fix\",\n },\n {\n name: \"timing\",\n regex: /timeout|timed out|exceeded|slow/i,\n oQueAconteceu: \"O teste excedeu o tempo de espera. O elemento pode demorar para aparecer ou há race condition.\",\n lesson: \"Adicione wait explícito antes de interagir. Aumente timeout se necessário. Use waitForDisplayed/waitForSelector.\",\n learningType: \"timing_fix\",\n },\n];\n\n/** Detecta qual padrão de falha melhor se aplica. Retorna o primeiro que bater. */\nexport function inferFailurePattern(runOutput, framework = \"\") {\n const output = (runOutput || \"\").toLowerCase();\n for (const p of FAILURE_ANALYSIS_PATTERNS) {\n if (p.mobileOnly && !/appium|detox/i.test(framework)) continue;\n if (p.regex.test(output)) return p;\n }\n return null;\n}\n\n/** Detecta se falha é por mapeamento invisível em mobile (retrocompatível). */\nexport function detectMobileMappingInvisible(runOutput, framework = \"\") {\n const p = inferFailurePattern(runOutput, framework);\n return p?.name === \"mobile_mapping_invisible\" || (p?.name === \"selector\" && /appium|detox/i.test(framework));\n}\n\nexport const MOBILE_MAPPING_LESSON = `Em testes mobile (Appium/Detox), SEMPRE inclua o mapeamento de elementos de forma VISÍVEL e estruturada no código:\n- Use constantes ou Page Object no TOPO do spec: const ELEMENTS = { loginBtn: '~btn_login', ... };\n- No teste: $(ELEMENTS.loginBtn).click();\n- Nunca deixe seletores \"invisíveis\" (hardcoded inline repetidos). Isso dificulta manutenção e causa falhas.`;\n\n/** Regras universais para TODOS os testes gerados. */\nexport const UNIVERSAL_TEST_PRACTICES = `PRÁTICAS OBRIGATÓRIAS em todo teste gerado:\n1. Esperas inteligentes: ANTES de interagir, verifique que o elemento está disponível (waitForDisplayed, waitForExist, waitForSelector)\n2. Validação no final: SEMPRE adicione um expect/assert ao final para o usuário entender que houve validação (ex: expect(element).toBeVisible() ou cy.get(sel).should('be.visible'))\n3. Não assuma que o elemento está pronto: elemento pode não estar renderizado, visível ou disponível — use waits explícitos`;\n\n/** Mensagem adaptada ao tipo de erro detectado. */\nexport function formatLearnedMessageForUser({ pattern, fixSummary, runOutput, framework }) {\n const p = pattern || (runOutput ? inferFailurePattern(runOutput, framework) : null);\n const oQueAconteceu = p?.oQueAconteceu || \"O teste falhou por um problema de elemento ou timing.\";\n const oQueFiz = fixSummary || (p ? `Apliquei a correção para esse tipo de falha: ${p.name}.` : \"Ajustei o código.\");\n return `**Entendi o erro e apliquei a correção**\n\n**O que aconteceu:** ${oQueAconteceu}\n\n**O que fiz:** ${oQueFiz}\n\n**O que aprendi:** Salvei esse cenário no meu histórico. Nas próximas gerações, vou aplicar as práticas corretas (waits inteligentes, validação final) desde o início.\n\nUse \\`mcp-lab-agent stats\\` ou \\`get_learning_report\\` para ver a evolução dos aprendizados.`;\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 if (deps[\"react-native\"]) {\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 // Ambiente inferido (web/mobile) e hints para guiar geração de testes\n const hints = [];\n if (structure.hasMobile) hints.push(\"mobile\");\n if (structure.testFrameworks.includes(\"appium\")) hints.push(\"appium\");\n if (structure.testFrameworks.includes(\"detox\")) hints.push(\"detox\");\n const pkg = structure.packageJson || {};\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n if (allDeps[\"react-native\"]) hints.push(\"react-native\");\n\n const webFrameworks = [\"cypress\", \"playwright\", \"webdriverio\", \"selenium\", \"puppeteer\", \"testcafe\"];\n const hasWebFrameworks = structure.testFrameworks.some((f) => webFrameworks.includes(f));\n if (hasWebFrameworks) hints.push(\"web\");\n\n if (structure.testDirs.includes(\"mobile\")) hints.push(\"mobile-dir\");\n\n let environment = \"web\";\n if (structure.hasMobile && !hasWebFrameworks) environment = \"mobile\";\n else if (structure.hasMobile && hasWebFrameworks) environment = \"both\";\n\n structure.environment = environment;\n structure.environmentHints = [...new Set(hints)];\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\", \"get_learning_report\"] },\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 slack-bot Inicia o Slack Bot (QA via @mention)\n learning-hub Inicia o Learning Hub (API + Dashboard em http://localhost:3847)\n analyze 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 Estatísticas de aprendizado (taxa de sucesso, correções, etc.)\n report [--full] Relatório de evolução e aprendizado (--full = completo com recomendações)\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 slack-bot # Slack Bot\n mcp-lab-agent learning-hub # Learning Hub (API + Dashboard)\n npx mcp-lab-agent slack-bot # Usar sem instalar (sem clonar o projeto)\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 const byType = stats.byLearningType || {};\n const byTypeLines = Object.entries(byType).filter(([, v]) => v > 0).map(([t, v]) => ` ${t}: ${v}`).join(\"\\n\");\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${byTypeLines ? `\\nPor tipo:\\n${byTypeLines}` : \"\"}\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 === \"report\") {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const stats = getMemoryStats();\n const byType = stats.byLearningType || {};\n const format = process.argv.includes(\"--full\") ? \"full\" : \"summary\";\n const recommendations = [];\n if (byType.element_not_rendered > 0 || byType.element_not_visible > 0) {\n recommendations.push(\"Use waits explícitos (waitForSelector, waitForDisplayed) ANTES de interagir com elementos.\");\n }\n if (byType.timing_fix > 0 || byType.element_stale > 0) {\n recommendations.push(\"Aumente timeouts e use re-localização de elementos em listas dinâmicas.\");\n }\n if (byType.selector_fix > 0 || byType.mobile_mapping_invisible > 0) {\n recommendations.push(\"Priorize data-testid, role e seletores estáveis; em mobile, use mapeamento visível no topo do spec.\");\n }\n if (stats.firstAttemptSuccessRate < 70 && stats.testsGenerated > 0) {\n recommendations.push(\"Aplique waits inteligentes + assert final em cada teste gerado.\");\n }\n const byTypeStr = Object.entries(byType).filter(([, v]) => v > 0).map(([t, v]) => ` - ${t}: ${v}`).join(\"\\n\");\n console.log(`\n📈 Relatório de Evolução e Aprendizado\n\nResumo por tipo:\n${byTypeStr || \" Nenhum aprendizado por tipo ainda\"}\n\nMétricas gerais:\n Total de aprendizados: ${stats.totalLearnings}\n Taxa de sucesso (1ª tentativa): ${stats.firstAttemptSuccessRate}%\n Testes gerados: ${stats.testsGenerated}\n${format === \"full\" && recommendations.length > 0 ? `\\nRecomendações para aprimorar o código:\\n${recommendations.map((r) => ` • ${r}`).join(\"\\n\")}` : \"\"}\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","learnedAppendix","__dirname","hubUrl"]}
1
+ {"version":3,"sources":["../src/index.js","../src/core/llm-router.js","../src/core/memory.js","../src/core/hub-client.js","../src/core/flaky-detection.js","../src/core/project-structure.js","../src/core/llm-call.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\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\n\nimport { resolveLLMProvider, TASK_COMPLEXITY } from \"./core/llm-router.js\";\nimport { loadProjectMemory, saveProjectMemory, getMemoryStats, analyzeTestStability } from \"./core/memory.js\";\nimport { detectFlakyPatterns, detectMobileMappingInvisible, formatLearnedMessageForUser, inferFailurePattern, MOBILE_MAPPING_LESSON, MOBILE_SELECTOR_HIERARCHY, oneLineFailureSummary, UNIVERSAL_TEST_PRACTICES } from \"./core/flaky-detection.js\";\nimport { collectTestFiles, detectDeviceConfig, detectProjectStructure, getFrameworkCwd, inferFrameworkFromFile, isTestFile, matchesFramework, analyzeCodeRisks } from \"./core/project-structure.js\";\nimport { applySelectorFixAndRetry } from \"./core/llm-call.js\";\nimport { parseTestRunResult, recordMetricEvent, extractFailuresFromOutput } 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.9\",\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, ambiente (web/mobile) e hints para geração de testes.\",\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 hasMobile: z.boolean().optional(),\n environment: z.string().optional(),\n environmentHints: z.array(z.string()).optional(),\n }),\n }),\n },\n async () => {\n const structure = detectProjectStructure();\n const envLine = structure.environment\n ? `Ambiente: ${structure.environment}${structure.environmentHints?.length ? ` (${structure.environmentHints.join(\", \")})` : \"\"}`\n : \"\";\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 ...(envLine ? [envLine] : []),\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\", \"map_mobile_elements\"], 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\", \"get_learning_report\", \"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 (/mapear|elementos mobile|deep link|deeplink|app package|bundle.?id|appium inspector/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → map_mobile_elements (mapear elementos), depois generate_tests + write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: [\"map_mobile_elements\", \"generate_tests\", \"write_test\"], description: QA_AGENTS.generation.desc } };\n }\n if (/mapear|elementos mobile|deep link|deeplink|app package|bundle.?id/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → map_mobile_elements (mapear elementos), depois generate_tests + write_test\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: [\"map_mobile_elements\", \"generate_tests\", \"write_test\"], description: \"Mapeamento de elementos mobile + geração de testes\" } };\n }\n if (/mobile|deeplink|deep link|elementos|mapear.*app|appium|detox/i.test(t) && !/rodar|run|executar/i.test(t)) {\n return { content: [{ type: \"text\", text: \"Agente: generation → map_mobile_elements, generate_tests, write_test (mobile)\" }], structuredContent: { ok: true, suggestedAgent: \"generation\", suggestedTools: QA_AGENTS.generation.tools, description: QA_AGENTS.generation.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, map_mobile_elements\" }], 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 device: z.string().optional().describe(\"Device/configuration para mobile. Se vazio, detecta de qa-lab-agent.config.json, wdio.conf ou .detoxrc.\"),\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 autoFixSelector: z.boolean().optional().describe(\"Se true e falhar por seletor, aplica correção automaticamente e tenta novamente. Requer spec e API key. Default: true para mobile.\"),\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, device, autoFixSelector }) => {\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 const deviceConfig = structure.hasMobile ? detectDeviceConfig(structure) : {};\n const useDevice = device || deviceConfig.configuration || deviceConfig.device;\n const doAutoFixSelector = autoFixSelector ?? (structure.hasMobile && !!spec);\n\n let runEnv = { ...process.env };\n if (useDevice && Object.keys(deviceConfig.envOverrides || {}).length) {\n runEnv = { ...runEnv, ...deviceConfig.envOverrides };\n }\n if (device) {\n if (selectedFramework === \"detox\") runEnv.DETOX_CONFIGURATION = device;\n else if (selectedFramework === \"appium\") runEnv.APPIUM_DEVICE_NAME = device;\n } else if (deviceConfig.configuration && selectedFramework === \"detox\") {\n runEnv.DETOX_CONFIGURATION = deviceConfig.configuration;\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 (useDevice) args.push(\"--configuration\", useDevice);\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 runTestsOnce = () =>\n new Promise((resolve) => {\n const startTime = Date.now();\n const child = spawn(cmd, args, {\n cwd,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n env: runEnv,\n });\n let stdout = \"\";\n let stderr = \"\";\n if (child.stdout) child.stdout.on(\"data\", (d) => { stdout += d.toString(); process.stdout.write(d); });\n if (child.stderr) child.stderr.on(\"data\", (d) => { stderr += d.toString(); process.stderr.write(d); });\n child.on(\"close\", (code) => {\n const runOutput = [stdout, stderr].filter(Boolean).join(\"\\n\").trim();\n resolve({\n passed: code === 0,\n exitCode: code ?? 1,\n runOutput,\n durationSeconds: Math.round((Date.now() - startTime) / 1000),\n });\n });\n });\n\n const isSelectorFailure = (out) => /element not found|selector|timeout|locator|cy\\.get|page\\.locator|Unable to find/i.test(out || \"\");\n\n let result = await runTestsOnce();\n let autoFixed = false;\n\n if (!result.passed && doAutoFixSelector && spec && isSelectorFailure(result.runOutput) && resolveLLMProvider(\"complex\").apiKey) {\n const fixResult = await applySelectorFixAndRetry(spec, result.runOutput, selectedFramework);\n if (fixResult.applied) {\n autoFixed = true;\n result = await runTestsOnce();\n }\n }\n\n if (!result.passed && result.runOutput) {\n try {\n fs.writeFileSync(path.join(PROJECT_ROOT, \".qa-lab-last-failure.log\"), result.runOutput, \"utf8\");\n } catch {}\n }\n\n const { passed: p, failed: f } = parseTestRunResult(result.runOutput, result.exitCode);\n appendMetricsEvent({\n type: \"test_run\",\n framework: selectedFramework,\n spec: spec || undefined,\n passed: p,\n failed: f,\n durationSeconds: result.durationSeconds,\n exitCode: result.exitCode,\n failures: !result.passed ? extractFailuresFromOutput(result.runOutput) : undefined,\n });\n if (result.passed) saveProjectMemory({ lastRun: { spec: spec || null, framework: selectedFramework, passed: p } });\n saveProjectMemory({\n execution: {\n testFile: spec || \"all\",\n passed: result.passed,\n duration: result.durationSeconds,\n timestamp: new Date().toISOString(),\n framework: selectedFramework,\n },\n });\n\n const baseMsg = result.passed\n ? (autoFixed ? \"Testes executados com sucesso (após correção automática de seletor).\" : \"Testes executados com sucesso.\")\n : \"Falha na execução dos testes.\";\n const structured = {\n status: result.passed ? \"passed\" : \"failed\",\n message: result.passed ? \"Tests passed\" : \"Tests failed\",\n exitCode: result.exitCode,\n runOutput: !result.passed ? result.runOutput : undefined,\n autoFixed: autoFixed || undefined,\n };\n\n if (!result.passed && explainOnFailure && result.runOutput) {\n const explainResult = await generateFailureExplanation(result.runOutput, spec || undefined);\n if (explainResult.ok && explainResult.structuredContent) {\n const oneLine =\n explainResult.structuredContent.resumoEmUmaFrase ||\n oneLineFailureSummary(result.runOutput, selectedFramework, explainResult.structuredContent.oQueAconteceu, explainResult.structuredContent.sugestaoCorrecao);\n structured.explanation = explainResult.structuredContent.formattedText;\n structured.resumoEmUmaFrase = oneLine;\n return {\n content: [{ type: \"text\", text: `${baseMsg}\\n\\n**${oneLine}**\\n\\n---\\n\\n${explainResult.structuredContent.formattedText}` }],\n structuredContent: structured,\n };\n }\n }\n\n return {\n content: [{ type: \"text\", text: baseMsg }],\n structuredContent: structured,\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\n${UNIVERSAL_TEST_PRACTICES}\n${(fw === \"appium\" || fw === \"detox\") ? `\\nIMPORTANTE: ${MOBILE_MAPPING_LESSON}\\n\\nHIERARQUIA DE SELETORES: ${MOBILE_SELECTOR_HIERARCHY}` : \"\"}`\n : `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\nFramework: ${fw}\n\n${UNIVERSAL_TEST_PRACTICES}\n\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${(fw === \"appium\" || fw === \"detox\") ? `\\n\\nIMPORTANTE (Appium/Detox): ${MOBILE_MAPPING_LESSON}\\n\\nHIERARQUIA: ${MOBILE_SELECTOR_HIERARCHY}` : \"\"}`;\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, oneLine = null) {\n const summary = oneLine || data.resumoEmUmaFrase || \"\";\n const lines = summary ? [`**${summary}**`, \"\", \"---\", \"\"] : [];\n lines.push(\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 via LLM. Usado por por_que_falhou e qa_auto. Retorna { ok, structuredContent }. */\nasync function generateFailureExplanation(resolvedOutput, testFilePath = null) {\n const structure = detectProjectStructure();\n const fw = structure.testFrameworks[0] || \"unknown\";\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 const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) return { ok: false, structuredContent: null };\n const { provider, apiKey, baseUrl, model } = llm;\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 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- resumoEmUmaFrase: string (OBRIGATÓRIO - uma frase: \"Falhou porque X. Solução: Y.\")\n- oQueAconteceu: string (explicação em português do que aconteceu, simples)\n- porQueProvavelmenteFalhou: array de strings (lista de possíveis causas)\n- oQueFazerAgora: array de strings (passos numerados do que fazer)\n- sugestaoCorrecao: string ou null (código de correção no formato do framework)\n- conceito: string ou null\n- framework: string (framework do projeto)\n\nFramework: ${fw}. ${fwHints[fw] || \"\"}\nResponda APENAS com o JSON válido, sem texto antes ou depois.`;\n const userPrompt = `Output do terminal/log (teste falhou):\n---\n${resolvedOutput.slice(0, 12000)}\n---\n${testCode ? `\\nCódigo do teste:\\n---\\n${testCode.slice(0, 6000)}\\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 = { oQueAconteceu: raw.slice(0, 500) || \"Não foi possível parsear.\", porQueProvavelmenteFalhou: [], oQueFazerAgora: [], sugestaoCorrecao: null, conceito: null, framework: fw };\n }\n data.framework = data.framework || fw;\n const oneLine = oneLineFailureSummary(resolvedOutput, fw, data.oQueAconteceu, data.sugestaoCorrecao);\n const formattedText = formatFailureExplanation(data, data.resumoEmUmaFrase || oneLine);\n return { ok: true, formattedText, structuredContent: { ...data, formattedText } };\n } catch (err) {\n return { ok: false, error: err.message, structuredContent: null };\n }\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 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 const explainResult = await generateFailureExplanation(resolvedOutput, testFilePath);\n if (!explainResult.ok) {\n if (!resolveLLMProvider(\"complex\").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 return {\n content: [{ type: \"text\", text: `Erro ao analisar: ${explainResult.error || \"erro desconhecido\"}` }],\n structuredContent: { ok: false, error: explainResult.error },\n };\n }\n const sc = explainResult.structuredContent;\n return {\n content: [{ type: \"text\", text: sc.formattedText }],\n structuredContent: {\n ok: true,\n oQueAconteceu: sc.oQueAconteceu,\n porQueProvavelmenteFalhou: sc.porQueProvavelmenteFalhou,\n oQueFazerAgora: sc.oQueFazerAgora,\n sugestaoCorrecao: sc.sugestaoCorrecao ?? null,\n conceito: sc.conceito ?? null,\n framework: sc.framework,\n formattedText: sc.formattedText,\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\", \"detox\"]).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 (HIERARQUIA ÚNICA): 1) id: $('~accessibility-id') ou $('~content-desc'). 2) XPath relacional: âncora estável + eixos + TIPO ESPECÍFICO (android.widget.Button, XCUIElementTypeButton). NUNCA use * em XPath — quebra por timing e múltiplos matches. Ex: //android.widget.LinearLayout[@resource-id='login_form']/descendant::android.widget.Button[@text='Entrar']. 3) resource-id. Explique a hierarquia.`,\n detox: `Detox: testID > accessibilityLabel > text. Explique por que é mais estável.`,\n };\n\n const mobileRules = (fw === \"appium\" || fw === \"detox\")\n ? \"\\n\\nMOBILE: 1) id. 2) XPath relacional: âncora + eixos + TIPO ESPECÍFICO (android.widget.Button, XCUIElementTypeButton). NUNCA use * — quebra por timing. Ex: //android.widget.LinearLayout[@resource-id='login_form']/descendant::android.widget.Button[@text='Entrar']. 3) resource-id. Explique por que o seletor é forte.\"\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. Em mobile: mencione a hierarquia de estabilidade)\n\nPriorize nesta ordem: data-testid > role + accessible name > texto visível > estrutura. Evite classes CSS e IDs que mudam.\n${mobileRules}\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 \"map_mobile_elements\",\n {\n title: \"Mapear elementos mobile (estrutura para testes)\",\n description: \"Gera estrutura/template de elementos para testes mobile. Aceita deep link, appPackage/appActivity (Android) ou bundleId (iOS). Retorna instruções para mapear elementos (Appium Inspector, uiautomator) e template para usar em generate_tests. Se elementsJsonPath fornecido, lê arquivo e formata para contexto.\",\n inputSchema: z.object({\n deepLink: z.string().optional().describe(\"Deep link do app (ex: meuapp://login). Indica ambiente mobile.\"),\n appPackage: z.string().optional().describe(\"Android: package do app (ex: com.example.app).\"),\n appActivity: z.string().optional().describe(\"Android: activity principal (ex: .MainActivity).\"),\n bundleId: z.string().optional().describe(\"iOS: bundle identifier do app.\"),\n elementsJsonPath: z.string().optional().describe(\"Caminho para arquivo JSON com elementos mapeados (id, text, accessibilityId, xpath).\"),\n }),\n outputSchema: z.object({\n ok: z.boolean(),\n environment: z.string().optional(),\n elements: z.array(z.object({\n id: z.string().optional(),\n text: z.string().optional(),\n accessibilityId: z.string().optional(),\n xpath: z.string().optional(),\n resourceId: z.string().optional(),\n className: z.string().optional(),\n })).optional(),\n instructions: z.string().optional(),\n contextForGenerate: z.string().optional().describe(\"Texto formatado para passar em generate_tests como contexto.\"),\n error: z.string().optional(),\n }),\n },\n async ({ deepLink, appPackage, appActivity, bundleId, elementsJsonPath }) => {\n const hasMobileContext = deepLink || appPackage || bundleId;\n const elements = [];\n let instructions = \"\";\n let contextForGenerate = \"\";\n\n if (elementsJsonPath) {\n const fullPath = path.join(PROJECT_ROOT, elementsJsonPath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (fs.existsSync(fullPath)) {\n try {\n const raw = fs.readFileSync(fullPath, \"utf8\");\n const parsed = JSON.parse(raw);\n const arr = Array.isArray(parsed) ? parsed : (parsed.elements || parsed.items || []);\n arr.forEach((el) => {\n elements.push({\n id: el.id || el.resourceId,\n text: el.text || el.label,\n accessibilityId: el.accessibilityId || el[\"content-desc\"] || el.contentDesc,\n xpath: el.xpath,\n resourceId: el.resourceId || el.id,\n className: el.className || el.class,\n });\n });\n contextForGenerate = `\\nElementos mapeados da tela (use para seletores estáveis em Appium/WDIO):\\n${JSON.stringify(elements, null, 2)}\\n`;\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Erro ao ler ${elementsJsonPath}: ${err.message}` }],\n structuredContent: { ok: false, error: err.message },\n };\n }\n } else {\n return {\n content: [{ type: \"text\", text: `Arquivo não encontrado: ${elementsJsonPath}` }],\n structuredContent: { ok: false, error: \"File not found\" },\n };\n }\n }\n\n if (hasMobileContext || elementsJsonPath) {\n instructions = [\n \"## Como mapear elementos do app mobile\",\n \"\",\n \"**Android (Appium):**\",\n \"- Use Appium Inspector (appium.io) com appPackage/appActivity\",\n \"- Ou: `adb shell uiautomator dump` → analise o XML exportado\",\n \"- Priorize: accessibility-id > resource-id > xpath relativo\",\n \"\",\n \"**iOS (Appium):**\",\n \"- Appium Inspector com bundleId\",\n \"- Xcode Accessibility Inspector\",\n \"- Priorize: accessibility-id > name\",\n \"\",\n \"**Formato esperado (elements.json):**\",\n \"```json\",\n '[{\"accessibilityId\": \"login_btn\", \"text\": \"Entrar\", \"resourceId\": \"com.app:id/btn\"}]',\n \"```\",\n \"\",\n \"Salve em um arquivo e passe em `elementsJsonPath` na próxima chamada.\",\n ].join(\"\\n\");\n }\n\n const env = deepLink ? \"mobile\" : (appPackage || bundleId) ? \"mobile\" : elements.length ? \"mobile\" : \"unknown\";\n const text = [\n contextForGenerate && `## Contexto para generate_tests\\n${contextForGenerate}`,\n instructions && `## Instruções\\n${instructions}`,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n return {\n content: [{ type: \"text\", text: text || (hasMobileContext ? `Ambiente: ${env}. ${instructions}` : \"Informe deepLink, appPackage ou elementsJsonPath.\") }],\n structuredContent: {\n ok: true,\n environment: env,\n elements: elements.length ? elements : undefined,\n instructions: instructions || undefined,\n contextForGenerate: contextForGenerate || undefined,\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 \"get_learning_report\",\n {\n title: \"Relatório de evolução e aprendizado\",\n description: \"Gera relatório de evolução dos aprendizados: resumo por tipo, evolução no tempo e recomendações para aprimorar o código.\",\n inputSchema: z.object({\n format: z.enum([\"summary\", \"full\"]).optional().describe(\"summary = resumo executivo, full = relatório completo com recomendações. Default: summary\"),\n }),\n outputSchema: z.object({\n summary: z.string(),\n byType: z.record(z.number()),\n evolution: z.array(z.object({ date: z.string(), type: z.string(), framework: z.string() })).optional(),\n recommendations: z.array(z.string()).optional(),\n }),\n },\n async ({ format = \"summary\" }) => {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const stats = getMemoryStats();\n\n const byType = stats.byLearningType || {};\n const evolution = format === \"full\" && learnings.length > 0\n ? learnings.slice(-30).map((l) => ({\n date: (l.timestamp || \"\").slice(0, 10),\n type: l.type || \"unknown\",\n framework: l.framework || \"-\",\n }))\n : [];\n\n const recommendations = [];\n if (byType.element_not_rendered > 0 || byType.element_not_visible > 0) {\n recommendations.push(\"Use waits explícitos (waitForSelector, waitForDisplayed) ANTES de interagir com elementos.\");\n }\n if (byType.timing_fix > 0 || byType.element_stale > 0) {\n recommendations.push(\"Aumente timeouts e use re-localização de elementos em listas dinâmicas.\");\n }\n if (byType.selector_fix > 0 || byType.mobile_mapping_invisible > 0) {\n recommendations.push(\"Priorize data-testid, role e seletores estáveis; em mobile, use mapeamento visível no topo do spec.\");\n }\n if (stats.firstAttemptSuccessRate < 70 && stats.testsGenerated > 0) {\n recommendations.push(\"Aplique UNIVERSAL_TEST_PRACTICES em cada teste gerado: waits inteligentes + assert final.\");\n }\n if (recommendations.length === 0 && learnings.length > 0) {\n recommendations.push(\"Continue aplicando as práticas aprendidas em novos testes.\");\n }\n\n const summary = `📈 **Relatório de Evolução e Aprendizado**\n\n**Resumo por tipo:**\n${Object.entries(byType).filter(([, v]) => v > 0).map(([t, v]) => `- ${t}: ${v}`).join(\"\\n\") || \"- Nenhum aprendizado por tipo ainda\"}\n\n**Métricas gerais:**\n- Total de aprendizados: ${stats.totalLearnings}\n- Taxa de sucesso (1ª tentativa): ${stats.firstAttemptSuccessRate}%\n- Testes gerados: ${stats.testsGenerated}\n\n${format === \"full\" && recommendations.length > 0 ? `**Recomendações para aprimorar o código:**\\n${recommendations.map((r) => `• ${r}`).join(\"\\n\")}` : \"\"}`;\n\n return {\n content: [{ type: \"text\", text: summary }],\n structuredContent: {\n summary: summary.trim(),\n byType,\n evolution: format === \"full\" ? evolution : undefined,\n recommendations: format === \"full\" ? recommendations : undefined,\n },\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 let appliedLearningFix = false;\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\n ?.filter((l) => l.fix)\n .slice(-10)\n .map((l) => l.fix)\n .join(\"\\n\") || \"\";\n const systemPrompt = `Você é um engenheiro de QA especializado em ${fw}. Gere APENAS o código do spec, sem explicações.\n${UNIVERSAL_TEST_PRACTICES}\n\n${memoryHints ? `Aprendizados 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 const learnedAppendix = appliedLearningFix ? `\\n\\n${formatLearnedMessageForUser({ runOutput: runResult?.output, fixSummary: \"Ajustei o código aplicando waits e validação correta.\", framework: fw })}` : \"\";\n return {\n content: [{ type: \"text\", text: `✅ Teste passou na tentativa ${attempt}!\\n\\nArquivo: ${testFilePath}\\n\\nAprendizados salvos.${learnedAppendix}` }],\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 const learnedAppendix = appliedLearningFix\n ? `\\n\\n${formatLearnedMessageForUser({ runOutput: runResult.output, framework: fw, fixSummary: \"Tentei corrigir. Nas próximas execuções usarei esse aprendizado desde o início.\" })}`\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)}${learnedAppendix}` }],\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 const inferredPattern = inferFailurePattern(runResult.output, fw);\n const learningType = inferredPattern?.learningType || (flakyAnalysis.patterns[0]?.pattern === \"selector\" ? \"selector_fix\" : \"timing_fix\");\n const learningFix = inferredPattern?.lesson || fixedCode.slice(0, 500);\n saveProjectMemory({\n learnings: [{\n type: learningType,\n request,\n framework: fw,\n fix: learningFix,\n pattern: inferredPattern?.name,\n success: false,\n timestamp: new Date().toISOString(),\n }],\n });\n appliedLearningFix = true;\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 const learnedAppendix = appliedLearningFix\n ? `\\n\\n${formatLearnedMessageForUser({ fixSummary: \"Tentei corrigir. Nas próximas execuções usarei esse aprendizado desde o início.\" })}`\n : \"\";\n return {\n content: [{ type: \"text\", text: `❌ Falhou após ${maxRetries} tentativa(s).${learnedAppendix}` }],\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 if (cmd === \"learning-hub\") {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const hubPath = path.join(__dirname, \"..\", \"learning-hub\", \"src\", \"server.js\");\n const hubUrl = pathToFileURL(hubPath).href;\n await import(hubUrl);\n return;\n }\n if (cmd === \"slack-bot\") {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const slackBotPath = path.join(__dirname, \"..\", \"slack-bot\", \"src\", \"index.js\");\n const slackBotUrl = pathToFileURL(slackBotPath).href;\n await import(slackBotUrl);\n return; // never reached (slack-bot runs until exit)\n }\n\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\";\nimport { syncLearningsToHub } from \"./hub-client.js\";\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 syncLearningsToHub(updates.learnings).catch(() => {});\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\nconst LEARNING_TYPES = [\"selector_fix\", \"timing_fix\", \"element_not_rendered\", \"element_not_visible\", \"element_stale\", \"mobile_mapping_invisible\"];\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 byLearningType = {};\n for (const t of LEARNING_TYPES) {\n byLearningType[t] = learnings.filter((l) => l.type === t).length;\n }\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 byLearningType,\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","/**\n * Cliente para o Learning Hub - envia learnings de forma assíncrona.\n * Se LEARNING_HUB_URL estiver configurado, saveProjectMemory envia para o Hub.\n */\n\nlet hubUrl = null;\n\nexport function setHubUrl(url) {\n hubUrl = (url || \"\").replace(/\\/$/, \"\");\n}\n\nexport function getHubUrl() {\n if (hubUrl) return hubUrl;\n const env = process.env.LEARNING_HUB_URL || process.env.QA_LAB_LEARNING_HUB_URL;\n if (env) {\n hubUrl = env.replace(/\\/$/, \"\");\n return hubUrl;\n }\n return null;\n}\n\nexport function isHubEnabled() {\n return !!getHubUrl();\n}\n\n/**\n * Envia learnings para o Hub. Assíncrono, não bloqueia.\n * Adiciona projectId (cwd ou env) para rastreamento.\n */\nexport async function syncLearningsToHub(learnings) {\n const baseUrl = getHubUrl();\n if (!baseUrl) return;\n\n const entries = Array.isArray(learnings) ? learnings : [learnings];\n if (entries.length === 0) return;\n\n const projectId = process.env.LEARNING_HUB_PROJECT_ID || process.cwd().split(\"/\").pop() || \"default\";\n\n const payload = entries.map((e) => ({\n ...e,\n projectId,\n }));\n\n try {\n const res = await fetch(`${baseUrl}/learning`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ learnings: payload }),\n });\n if (!res.ok) {\n const txt = await res.text();\n console.warn(`[learning-hub] POST /learning failed ${res.status}: ${txt}`);\n }\n } catch (err) {\n console.warn(\"[learning-hub] sync failed:\", err.message);\n }\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\n/**\n * Padrões de falha com mensagem adaptada e lição específica.\n * Ordem importa: o primeiro que bater é usado.\n */\nexport const FAILURE_ANALYSIS_PATTERNS = [\n {\n name: \"element_not_rendered\",\n regex: /timeout|not found|element not found|no such element|element.*not.*in.*dom|waiting for/i,\n oQueAconteceu: \"O elemento ainda não foi renderizado no DOM quando o teste tentou interagir. Pode ser carregamento assíncrono, lazy load ou animação.\",\n lesson: `Espere o elemento estar disponível ANTES de interagir:\n- Playwright: await element.waitFor({ state: 'attached' }) ou waitForSelector\n- Cypress: cy.get(sel).should('exist') antes de clicar\n- WDIO/Appium: $(sel).waitForDisplayed() ou waitForExist({ timeout: 10000 })\n- Use waits inteligentes: waitForDisplayed, waitForClickable, waitForExist`,\n learningType: \"element_not_rendered\",\n },\n {\n name: \"element_not_visible\",\n regex: /element.*not.*visible|not visible|is not visible|element is not displayed|hidden|display.*none|off.?screen/i,\n oQueAconteceu: \"O elemento existe no DOM mas não está visível (display:none, off-screen, opacity:0 ou ainda carregando).\",\n lesson: `Verifique visibilidade antes de interagir:\n- Playwright: waitFor({ state: 'visible' })\n- Cypress: .should('be.visible') antes de click\n- Appium/WDIO: waitForDisplayed() ou isDisplayed()\n- Adicione wait explícito: elemento pode estar em animação ou carregando`,\n learningType: \"element_not_visible\",\n },\n {\n name: \"element_stale\",\n regex: /stale element|stale element reference|element.*no longer attached/i,\n oQueAconteceu: \"O elemento foi encontrado mas a página/DOM mudou antes da interação (elemento ficou obsoleto).\",\n lesson: `Re-localize o elemento antes de cada ação:\n- Evite guardar referência: busque novamente antes de clicar\n- Use waits que revalidam: cy.get().first().click() com retry\n- Em listas dinâmicas: espere estabilização antes de interagir`,\n learningType: \"element_stale\",\n },\n {\n name: \"mobile_mapping_invisible\",\n regex: /element not found|selector|Unable to find|no such element/i,\n oQueAconteceu: \"Em mobile: o mapeamento ficou invisível ou os seletores não estão estruturados. Pode ser estrutura do código ou seletor incorreto.\",\n lesson: `Em testes mobile (Appium/Detox), SEMPRE:\n- Mapeamento VISÍVEL: const ELEMENTS = { btn: '~id' }; $(ELEMENTS.btn).click()\n- Antes de clicar: $(sel).waitForDisplayed({ timeout: 10000 })\n- Ao final: expect(await $(sel).isDisplayed()).toBe(true) — validação explícita para o usuário entender que houve validação`,\n learningType: \"mobile_mapping_invisible\",\n mobileOnly: true,\n },\n {\n name: \"selector\",\n regex: /selector|locator|element not found|Unable to find/i,\n oQueAconteceu: \"O seletor não encontrou o elemento. Pode ser seletor incorreto, mudança de UI ou elemento em outro contexto (iframe, shadow DOM).\",\n lesson: \"Use seletores estáveis: data-testid, role+name, accessibility-id. Evite classes CSS dinâmicas. Priorize: data-testid > role > texto visível.\",\n learningType: \"selector_fix\",\n },\n {\n name: \"timing\",\n regex: /timeout|timed out|exceeded|slow/i,\n oQueAconteceu: \"O teste excedeu o tempo de espera. O elemento pode demorar para aparecer ou há race condition.\",\n lesson: \"Adicione wait explícito antes de interagir. Aumente timeout se necessário. Use waitForDisplayed/waitForSelector.\",\n learningType: \"timing_fix\",\n },\n];\n\n/** Gera resumo em 1 frase para o usuário (Top 3: \"por que falhou?\"). */\nexport function oneLineFailureSummary(runOutput, framework = \"\", oQueAconteceu = \"\", sugestaoCorrecao = \"\") {\n const p = inferFailurePattern(runOutput, framework);\n const causa = oQueAconteceu || p?.oQueAconteceu || \"erro desconhecido\";\n const solucao = sugestaoCorrecao || (p ? p.lesson.split(\"\\n\")[0].replace(/^-\\s*/, \"\") : \"\");\n const tipo = p?.name || \"geral\";\n if (solucao) {\n return `Falhou porque ${causa.slice(0, 80)}${causa.length > 80 ? \"…\" : \"\"} (${tipo}). Solução: ${solucao.slice(0, 100)}${solucao.length > 100 ? \"…\" : \"\"}`;\n }\n return `Falhou porque ${causa.slice(0, 120)}${causa.length > 120 ? \"…\" : \"\"} (${tipo}).`;\n}\n\n/** Detecta qual padrão de falha melhor se aplica. Retorna o primeiro que bater. */\nexport function inferFailurePattern(runOutput, framework = \"\") {\n const output = (runOutput || \"\").toLowerCase();\n for (const p of FAILURE_ANALYSIS_PATTERNS) {\n if (p.mobileOnly && !/appium|detox/i.test(framework)) continue;\n if (p.regex.test(output)) return p;\n }\n return null;\n}\n\n/** Detecta se falha é por mapeamento invisível em mobile (retrocompatível). */\nexport function detectMobileMappingInvisible(runOutput, framework = \"\") {\n const p = inferFailurePattern(runOutput, framework);\n return p?.name === \"mobile_mapping_invisible\" || (p?.name === \"selector\" && /appium|detox/i.test(framework));\n}\n\n/** Hierarquia única e inovadora de seletores mobile: id → XPath relacional → resource-id. */\nexport const MOBILE_SELECTOR_HIERARCHY = `HIERARQUIA DE SELETORES MOBILE (única e inovadora):\n1. id: ~accessibility-id, testID — prioridade máxima, semântico e estável\n2. XPath relacional: âncora estável + eixos + TIPO ESPECÍFICO (android.widget.Button, XCUIElementTypeButton). NUNCA use * — quebra por timing e múltiplos matches. Ex: //android.widget.LinearLayout[@resource-id='login_form']/descendant::android.widget.Button[@text='Entrar']. Evite XPath por índice (//Button[3])\n3. resource-id: id=com.app:id/btn — fallback`;\n\nexport const MOBILE_MAPPING_LESSON = `Em testes mobile (Appium/Detox), SEMPRE inclua o mapeamento de elementos de forma VISÍVEL e estruturada no código:\n- Use constantes ou Page Object no TOPO do spec: const ELEMENTS = { loginBtn: '~btn_login', ... };\n- No teste: $(ELEMENTS.loginBtn).click();\n- Nunca deixe seletores \"invisíveis\" (hardcoded inline repetidos). Isso dificulta manutenção e causa falhas.\n- Hierarquia: id > XPath relacional (âncora + eixos + tipo específico: android.widget.Button) > resource-id. Evite * e índice.`;\n\n/** Regras universais para TODOS os testes gerados. */\nexport const UNIVERSAL_TEST_PRACTICES = `PRÁTICAS OBRIGATÓRIAS em todo teste gerado:\n1. Esperas inteligentes: ANTES de interagir, verifique que o elemento está disponível (waitForDisplayed, waitForExist, waitForSelector)\n2. Validação no final: SEMPRE adicione um expect/assert ao final para o usuário entender que houve validação (ex: expect(element).toBeVisible() ou cy.get(sel).should('be.visible'))\n3. Não assuma que o elemento está pronto: elemento pode não estar renderizado, visível ou disponível — use waits explícitos`;\n\n/** Mensagem adaptada ao tipo de erro detectado. */\nexport function formatLearnedMessageForUser({ pattern, fixSummary, runOutput, framework }) {\n const p = pattern || (runOutput ? inferFailurePattern(runOutput, framework) : null);\n const oQueAconteceu = p?.oQueAconteceu || \"O teste falhou por um problema de elemento ou timing.\";\n const oQueFiz = fixSummary || (p ? `Apliquei a correção para esse tipo de falha: ${p.name}.` : \"Ajustei o código.\");\n return `**Entendi o erro e apliquei a correção**\n\n**O que aconteceu:** ${oQueAconteceu}\n\n**O que fiz:** ${oQueFiz}\n\n**O que aprendi:** Salvei esse cenário no meu histórico. Nas próximas gerações, vou aplicar as práticas corretas (waits inteligentes, validação final) desde o início.\n\nUse \\`mcp-lab-agent stats\\` ou \\`get_learning_report\\` para ver a evolução dos aprendizados.`;\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 if (deps[\"react-native\"]) {\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 // Ambiente inferido (web/mobile) e hints para guiar geração de testes\n const hints = [];\n if (structure.hasMobile) hints.push(\"mobile\");\n if (structure.testFrameworks.includes(\"appium\")) hints.push(\"appium\");\n if (structure.testFrameworks.includes(\"detox\")) hints.push(\"detox\");\n const pkg = structure.packageJson || {};\n const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };\n if (allDeps[\"react-native\"]) hints.push(\"react-native\");\n\n const webFrameworks = [\"cypress\", \"playwright\", \"webdriverio\", \"selenium\", \"puppeteer\", \"testcafe\"];\n const hasWebFrameworks = structure.testFrameworks.some((f) => webFrameworks.includes(f));\n if (hasWebFrameworks) hints.push(\"web\");\n\n if (structure.testDirs.includes(\"mobile\")) hints.push(\"mobile-dir\");\n\n // testDirs custom no qa-lab-agent.config.json (override ou complemento)\n const configPath = path.join(PROJECT_ROOT, \"qa-lab-agent.config.json\");\n if (fs.existsSync(configPath)) {\n try {\n const cfg = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n const customDirs = cfg.testDirs || cfg.qa?.testDirs;\n if (Array.isArray(customDirs)) {\n for (const dir of customDirs) {\n const d = String(dir).trim();\n if (d && !structure.testDirs.includes(d)) {\n const fullPath = path.join(PROJECT_ROOT, d);\n if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {\n structure.testDirs.push(d);\n }\n }\n }\n }\n } catch {}\n }\n\n let environment = \"web\";\n if (structure.hasMobile && !hasWebFrameworks) environment = \"mobile\";\n else if (structure.hasMobile && hasWebFrameworks) environment = \"both\";\n\n structure.environment = environment;\n structure.environmentHints = [...new Set(hints)];\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\n/**\n * Detecta device/config para testes mobile a partir de arquivos de config e env.\n * Retorna { device, configuration, platform, envOverrides } para Appium/Detox.\n */\nexport function detectDeviceConfig(structure) {\n const result = { device: null, configuration: null, platform: null, envOverrides: {} };\n\n if (!structure.hasMobile) return result;\n\n const configPath = path.join(PROJECT_ROOT, \"qa-lab-agent.config.json\");\n if (fs.existsSync(configPath)) {\n try {\n const cfg = JSON.parse(fs.readFileSync(configPath, \"utf8\"));\n const deviceCfg = cfg.device || cfg.mobile || cfg.appium || cfg.detox;\n if (deviceCfg) {\n result.device = deviceCfg.deviceName || deviceCfg.device || deviceCfg.udid;\n result.configuration = deviceCfg.configuration || deviceCfg.config;\n result.platform = deviceCfg.platformName || deviceCfg.platform;\n if (deviceCfg.udid) result.envOverrides.APPIUM_UDID = deviceCfg.udid;\n if (deviceCfg.deviceName) result.envOverrides.APPIUM_DEVICE_NAME = deviceCfg.deviceName;\n }\n } catch {}\n }\n\n if (process.env.DETOX_CONFIGURATION) result.configuration = process.env.DETOX_CONFIGURATION;\n if (process.env.APPIUM_UDID) result.envOverrides.APPIUM_UDID = process.env.APPIUM_UDID;\n if (process.env.APPIUM_DEVICE_NAME) result.envOverrides.APPIUM_DEVICE_NAME = process.env.APPIUM_DEVICE_NAME;\n\n const detoxPath = path.join(PROJECT_ROOT, \".detoxrc.js\");\n if (fs.existsSync(detoxPath) && !result.configuration) {\n try {\n const content = fs.readFileSync(detoxPath, \"utf8\");\n const configMatch = content.match(/configurations:\\s*\\{([^}]+)\\}/s);\n if (configMatch) {\n const firstConfig = configMatch[1].match(/\"([^\"]+)\":\\s*\\{/);\n if (firstConfig) result.configuration = firstConfig[1];\n }\n } catch {}\n }\n\n const wdioPaths = [\"wdio.conf.js\", \"wdio.conf.cjs\", \"wdio.conf.mjs\", \"wdio.conf.ts\"];\n for (const name of wdioPaths) {\n const wdioPath = path.join(PROJECT_ROOT, name);\n if (fs.existsSync(wdioPath) && !result.device) {\n try {\n const content = fs.readFileSync(wdioPath, \"utf8\");\n const capMatch = content.match(/capabilities:\\s*\\[([\\s\\S]*?)\\]/);\n if (capMatch) {\n const deviceMatch = capMatch[1].match(/deviceName:\\s*['\"]([^'\"]+)['\"]/);\n const udidMatch = capMatch[1].match(/udid:\\s*['\"]([^'\"]+)['\"]/);\n const platformMatch = capMatch[1].match(/platformName:\\s*['\"]([^'\"]+)['\"]/);\n if (deviceMatch) result.device = deviceMatch[1];\n if (udidMatch) result.envOverrides.APPIUM_UDID = udidMatch[1];\n if (platformMatch) result.platform = platformMatch[1];\n }\n } catch {}\n break;\n }\n }\n\n return result;\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\";\nimport { resolveLLMProvider } from \"./llm-router.js\";\nimport { detectProjectStructure, inferFrameworkFromFile } from \"./project-structure.js\";\n\nconst PROJECT_ROOT = process.cwd();\n\nexport async function callLlm(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\nexport async function applySelectorFixAndRetry(testFilePath, errorOutput, framework) {\n const structure = detectProjectStructure();\n const fw = framework || inferFrameworkFromFile(testFilePath.split(\"/\").pop(), structure);\n const fullPath = path.join(PROJECT_ROOT, testFilePath.replace(/^\\//, \"\").replace(/\\\\/g, \"/\"));\n if (!fs.existsSync(fullPath)) return { applied: false };\n\n let testCode = \"\";\n try {\n testCode = fs.readFileSync(fullPath, \"utf8\");\n } catch {\n return { applied: false };\n }\n\n const llm = resolveLLMProvider(\"complex\");\n if (!llm.apiKey) return { applied: false };\n const { provider, apiKey, baseUrl, model } = llm;\n\n const systemPrompt = `Você é um especialista em testes E2E. O teste falhou porque um seletor não encontrou o elemento.\nRetorne APENAS em JSON (sem markdown) com a chave:\n- codigoCorrigido: string (o ARQUIVO COMPLETO do teste corrigido, com imports e toda a estrutura. Substitua o seletor quebrado por um mais resiliente: data-testid, role, ~accessibility-id, ou XPath relacional com tipo específico.)\n\nFramework: ${fw}. Priorize seletores estáveis.`;\n\n const userPrompt = `Output do erro:\\n---\\n${(errorOutput || \"\").slice(0, 8000)}\\n---\\n\\nCódigo atual:\\n---\\n${testCode.slice(0, 6000)}\\n---`;\n\n try {\n let raw = await callLlm(provider, apiKey, baseUrl, model, systemPrompt, userPrompt);\n raw = raw.replace(/^```(?:json)?\\s*/i, \"\").replace(/\\s*```\\s*$/i, \"\").trim();\n const data = JSON.parse(raw);\n const fixed = (data.codigoCorrigido || \"\").trim();\n if (fixed.length > 50 && (/describe|it\\(|test\\(|cy\\.|page\\.|\\$\\(/.test(fixed))) {\n fs.writeFileSync(fullPath, fixed, \"utf8\");\n return { applied: true };\n }\n } catch {}\n return { applied: false };\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 { detectDeviceConfig, detectProjectStructure, getFrameworkCwd } from \"../core/project-structure.js\";\nimport { loadProjectMemory, saveProjectMemory, getMemoryStats, analyzeTestStability } from \"../core/memory.js\";\nimport { resolveLLMProvider } from \"../core/llm-router.js\";\nimport { applySelectorFixAndRetry } from \"../core/llm-call.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\", \"get_learning_report\"] },\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 slack-bot Inicia o Slack Bot (QA via @mention)\n learning-hub Inicia o Learning Hub (API + Dashboard em http://localhost:3847)\n analyze 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 Estatísticas de aprendizado (taxa de sucesso, correções, etc.)\n report [--full] Relatório de evolução e aprendizado (--full = completo com recomendações)\n metrics-report [--json] [--output FILE] [path1 path2 ...] Relatório de métricas (método, resultado). Sem paths = projeto atual.\n flaky-report [--runs N] [--spec FILE] [--output FILE] Detecta testes flaky: roda N vezes (default 3), identifica intermitência e causa provável\n run [spec] [--device NAME] [--no-auto-fix] Roda testes: detecta device, executa e aplica auto-fix de seletor se falhar\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 slack-bot # Slack Bot\n mcp-lab-agent learning-hub # Learning Hub (API + Dashboard)\n npx mcp-lab-agent slack-bot # Usar sem instalar (sem clonar o projeto)\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 flaky-report --runs 5 --output flaky.md\n mcp-lab-agent run specs/login.spec.js\n mcp-lab-agent run specs/login.spec.js --device iPhone_15\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 const byType = stats.byLearningType || {};\n const byTypeLines = Object.entries(byType).filter(([, v]) => v > 0).map(([t, v]) => ` ${t}: ${v}`).join(\"\\n\");\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${byTypeLines ? `\\nPor tipo:\\n${byTypeLines}` : \"\"}\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 === \"report\") {\n const memory = loadProjectMemory();\n const learnings = memory.learnings || [];\n const stats = getMemoryStats();\n const byType = stats.byLearningType || {};\n const format = process.argv.includes(\"--full\") ? \"full\" : \"summary\";\n const recommendations = [];\n if (byType.element_not_rendered > 0 || byType.element_not_visible > 0) {\n recommendations.push(\"Use waits explícitos (waitForSelector, waitForDisplayed) ANTES de interagir com elementos.\");\n }\n if (byType.timing_fix > 0 || byType.element_stale > 0) {\n recommendations.push(\"Aumente timeouts e use re-localização de elementos em listas dinâmicas.\");\n }\n if (byType.selector_fix > 0 || byType.mobile_mapping_invisible > 0) {\n recommendations.push(\"Priorize data-testid, role e seletores estáveis; em mobile, use mapeamento visível no topo do spec.\");\n }\n if (stats.firstAttemptSuccessRate < 70 && stats.testsGenerated > 0) {\n recommendations.push(\"Aplique waits inteligentes + assert final em cada teste gerado.\");\n }\n const byTypeStr = Object.entries(byType).filter(([, v]) => v > 0).map(([t, v]) => ` - ${t}: ${v}`).join(\"\\n\");\n console.log(`\n📈 Relatório de Evolução e Aprendizado\n\nResumo por tipo:\n${byTypeStr || \" Nenhum aprendizado por tipo ainda\"}\n\nMétricas gerais:\n Total de aprendizados: ${stats.totalLearnings}\n Taxa de sucesso (1ª tentativa): ${stats.firstAttemptSuccessRate}%\n Testes gerados: ${stats.testsGenerated}\n${format === \"full\" && recommendations.length > 0 ? `\\nRecomendações para aprimorar o código:\\n${recommendations.map((r) => ` • ${r}`).join(\"\\n\")}` : \"\"}\n`);\n return true;\n }\n\n if (cmd === \"analyze\") {\n await handleAnalyzeCommand();\n return true;\n }\n\n if (cmd === \"metrics-report\") {\n await handleMetricsReportCommand();\n return true;\n }\n\n if (cmd === \"flaky-report\") {\n await handleFlakyReportCommand();\n return true;\n }\n\n if (cmd === \"run\") {\n await handleRunCommand();\n return true;\n }\n\n return false;\n}\n\n/**\n * Gera relatório de métricas a partir de .qa-lab-memory.json e .qa-lab-metrics.json.\n * Suporta múltiplos projetos: mcp-lab-agent metrics-report /path/proj1 /path/proj2\n */\nasync function handleMetricsReportCommand() {\n const argv = process.argv.slice(2);\n const jsonOnly = argv.includes(\"--json\");\n const outputIdx = argv.indexOf(\"--output\");\n const outputFile = outputIdx !== -1 && argv[outputIdx + 1] ? argv[outputIdx + 1] : null;\n const paths = argv.filter((a) => {\n if (a.startsWith(\"--\") || a === \"metrics-report\") return false;\n if (outputIdx !== -1 && a === argv[outputIdx + 1]) return false; // exclui valor de --output\n return true;\n });\n\n const projectDirs = paths.length > 0 ? paths : [PROJECT_ROOT];\n\n const reports = [];\n for (const dir of projectDirs) {\n const resolved = path.resolve(dir);\n if (!fs.existsSync(resolved)) {\n console.warn(`⚠️ Diretório não encontrado: ${dir}`);\n continue;\n }\n const memoryPath = path.join(resolved, \".qa-lab-memory.json\");\n const metricsPath = path.join(resolved, \".qa-lab-metrics.json\");\n\n let memory = {};\n let metrics = { events: [] };\n if (fs.existsSync(memoryPath)) {\n try {\n memory = JSON.parse(fs.readFileSync(memoryPath, \"utf8\"));\n } catch {}\n }\n if (fs.existsSync(metricsPath)) {\n try {\n metrics = JSON.parse(fs.readFileSync(metricsPath, \"utf8\"));\n } catch {}\n }\n\n const events = metrics.events || [];\n const executions = memory.executions || [];\n const learnings = memory.learnings || [];\n\n const byEventType = {};\n events.forEach((e) => {\n const t = e.type || \"unknown\";\n byEventType[t] = (byEventType[t] || 0) + 1;\n });\n\n const testRuns = events.filter((e) => e.type === \"test_run\");\n const testRunPassed = testRuns.filter((e) => e.exitCode === 0).length;\n const testRunFailed = testRuns.filter((e) => e.exitCode !== 0).length;\n const byFramework = {};\n testRuns.forEach((e) => {\n const f = e.framework || \"unknown\";\n byFramework[f] = (byFramework[f] || { total: 0, passed: 0, failed: 0 });\n byFramework[f].total++;\n if (e.exitCode === 0) byFramework[f].passed++;\n else byFramework[f].failed++;\n });\n\n const byLearningType = {};\n learnings.forEach((l) => {\n const t = l.type || \"unknown\";\n byLearningType[t] = (byLearningType[t] || { total: 0, success: 0 });\n byLearningType[t].total++;\n if (l.success) byLearningType[t].success++;\n });\n\n const execByFramework = {};\n executions.forEach((e) => {\n const f = e.framework || \"unknown\";\n execByFramework[f] = (execByFramework[f] || { total: 0, passed: 0 });\n execByFramework[f].total++;\n if (e.passed) execByFramework[f].passed++;\n });\n\n const projectName = path.basename(resolved);\n reports.push({\n project: projectName,\n path: resolved,\n summary: {\n eventsTotal: events.length,\n eventTypes: byEventType,\n testRuns: { total: testRuns.length, passed: testRunPassed, failed: testRunFailed },\n byFramework,\n executions: { total: executions.length, byFramework: execByFramework },\n learnings: { total: learnings.length, byType: byLearningType },\n lastUpdated: metrics.lastUpdated || memory.updatedAt,\n },\n recentEvents: events.slice(-20).map((e) => ({\n type: e.type,\n timestamp: e.timestamp,\n framework: e.framework,\n spec: e.spec,\n passed: e.passed,\n failed: e.failed,\n exitCode: e.exitCode,\n durationSeconds: e.durationSeconds,\n })),\n });\n }\n\n if (jsonOnly) {\n const out = JSON.stringify({ projects: reports, generatedAt: new Date().toISOString() }, null, 2);\n if (outputFile) fs.writeFileSync(outputFile, out, \"utf8\");\n else console.log(out);\n return;\n }\n\n let report = `# Relatório de Métricas — mcp-lab-agent\\n\\n`;\n report += `Gerado em: ${new Date().toISOString()}\\n`;\n report += `Projetos: ${reports.length}\\n\\n`;\n report += `---\\n\\n`;\n\n for (const r of reports) {\n report += `## ${r.project}\\n\\n`;\n report += `**Caminho:** \\`${r.path}\\`\\n\\n`;\n\n const s = r.summary;\n report += `### Eventos (.qa-lab-metrics.json)\\n\\n`;\n report += `| Método/Tipo | Total | Descrição |\\n`;\n report += `|-------------|-------|\\n`;\n for (const [t, count] of Object.entries(s.eventTypes || {})) {\n let desc = \"\";\n if (t === \"test_run\") desc = `Execução de testes (passed/failed por framework abaixo)`;\n else if (t === \"bug_reported\") desc = \"Bug report gerado\";\n else desc = t;\n report += `| ${t} | ${count} | ${desc} |\\n`;\n }\n if (Object.keys(s.eventTypes || {}).length === 0) {\n report += `| — | 0 | Nenhum evento registrado |\\n`;\n }\n report += `\\n`;\n\n if (s.testRuns?.total > 0) {\n report += `### Resultado de Execuções (run_tests)\\n\\n`;\n report += `| Framework | Total | Passed | Failed | Taxa sucesso |\\n`;\n report += `|-----------|-------|--------|--------|---------------|\\n`;\n for (const [fw, data] of Object.entries(s.byFramework || {})) {\n const rate = data.total > 0 ? Math.round((data.passed / data.total) * 100) : 0;\n report += `| ${fw} | ${data.total} | ${data.passed} | ${data.failed} | ${rate}% |\\n`;\n }\n report += `\\n`;\n report += `**Resumo:** ${s.testRuns.passed} passed, ${s.testRuns.failed} failed (total: ${s.testRuns.total})\\n\\n`;\n }\n\n if (s.executions?.total > 0) {\n report += `### Histórico de Execuções (memory)\\n\\n`;\n report += `| Framework | Total | Passed | Taxa |\\n`;\n report += `|-----------|-------|--------|------|\\n`;\n for (const [fw, data] of Object.entries(s.executions.byFramework || {})) {\n const rate = data.total > 0 ? Math.round((data.passed / data.total) * 100) : 0;\n report += `| ${fw} | ${data.total} | ${data.passed} | ${rate}% |\\n`;\n }\n report += `\\n`;\n }\n\n if (s.learnings?.total > 0) {\n report += `### Aprendizados (.qa-lab-memory.json)\\n\\n`;\n report += `| Tipo | Total | Sucesso | Taxa |\\n`;\n report += `|------|-------|---------|------|\\n`;\n for (const [t, data] of Object.entries(s.learnings.byType || {})) {\n const rate = data.total > 0 ? Math.round((data.success / data.total) * 100) : 0;\n report += `| ${t} | ${data.total} | ${data.success} | ${rate}% |\\n`;\n }\n report += `\\n`;\n }\n\n if (r.recentEvents?.length > 0) {\n report += `### Últimos 20 eventos\\n\\n`;\n report += `| Data | Tipo | Framework | Spec | Passed | Failed | Exit | Duração(s) |\\n`;\n report += `|------|------|-----------|------|--------|--------|------|------------|\\n`;\n for (const e of r.recentEvents.slice(-10)) {\n const ts = e.timestamp ? new Date(e.timestamp).toLocaleString() : \"—\";\n report += `| ${ts} | ${e.type || \"—\"} | ${e.framework || \"—\"} | ${(e.spec || \"—\").slice(0, 20)} | ${e.passed ?? \"—\"} | ${e.failed ?? \"—\"} | ${e.exitCode ?? \"—\"} | ${e.durationSeconds ?? \"—\"} |\\n`;\n }\n report += `\\n`;\n }\n\n if (s.lastUpdated) {\n report += `*Última atualização: ${s.lastUpdated}*\\n\\n`;\n }\n report += `---\\n\\n`;\n }\n\n if (outputFile) {\n fs.writeFileSync(outputFile, report, \"utf8\");\n console.log(`\\n📄 Relatório salvo em: ${outputFile}\\n`);\n } else {\n console.log(report);\n }\n}\n\n/**\n * Detecta testes flaky: roda suite N vezes, identifica intermitência e causa provável.\n * Uso: mcp-lab-agent flaky-report [--runs N] [--spec FILE] [--output FILE]\n */\nasync function handleFlakyReportCommand() {\n const argv = process.argv.slice(2);\n const runsIdx = argv.indexOf(\"--runs\");\n const runs = runsIdx !== -1 && argv[runsIdx + 1] ? parseInt(argv[runsIdx + 1], 10) : 3;\n const specIdx = argv.indexOf(\"--spec\");\n const spec = specIdx !== -1 && argv[specIdx + 1] ? argv[specIdx + 1] : null;\n const outputIdx = argv.indexOf(\"--output\");\n const outputFile = outputIdx !== -1 && argv[outputIdx + 1] ? argv[outputIdx + 1] : null;\n\n const structure = detectProjectStructure();\n if (!structure.hasTests) {\n console.error(\"❌ Nenhum framework de teste detectado.\");\n process.exit(1);\n }\n\n const fw = structure.testFrameworks[0];\n const { cmd, args, cwd } = getRunCommand(structure, fw, spec);\n\n console.log(`\\n🔬 Relatório de testes flaky\\n`);\n console.log(`Framework: ${fw}`);\n console.log(`Execuções: ${runs}`);\n if (spec) console.log(`Spec: ${spec}`);\n console.log(`\\nRodando testes ${runs}x...\\n`);\n\n const results = [];\n for (let i = 0; i < runs; i++) {\n process.stdout.write(` [${i + 1}/${runs}] `);\n const result = await runTestsOnce(cmd, args, cwd);\n results.push(result);\n process.stdout.write(result.passed ? \"✅ passou\\n\" : \"❌ falhou\\n\");\n }\n\n const passed = results.filter((r) => r.passed).length;\n const failed = results.filter((r) => !r.passed).length;\n const isFlaky = passed > 0 && failed > 0;\n const failureOutput = results.find((r) => !r.passed)?.output || \"\";\n\n const flakyAnalysis = failureOutput ? detectFlakyPatterns(failureOutput) : null;\n const probableCause = flakyAnalysis?.isLikelyFlaky\n ? flakyAnalysis.patterns.map((p) => `${p.pattern}: ${p.suggestion}`).join(\"; \")\n : \"Não foi possível inferir (rode com explainOnFailure para análise detalhada)\";\n\n let report = `# Relatório de testes flaky — mcp-lab-agent\\n\\n`;\n report += `Gerado em: ${new Date().toISOString()}\\n`;\n report += `Framework: ${fw}\\n`;\n report += `Execuções: ${runs}\\n`;\n if (spec) report += `Spec: ${spec}\\n`;\n report += `\\n---\\n\\n`;\n\n report += `## Resultado\\n\\n`;\n report += `| Métrica | Valor |\\n`;\n report += `|---------|-------|\\n`;\n report += `| Passou | ${passed}/${runs} |\\n`;\n report += `| Falhou | ${failed}/${runs} |\\n`;\n report += `| Taxa de falha | ${Math.round((failed / runs) * 100)}% |\\n`;\n report += `| **Flaky?** | ${isFlaky ? \"⚠️ SIM\" : failed === runs ? \"❌ Falha consistente\" : \"✅ Estável\"} |\\n\\n`;\n\n if (isFlaky) {\n report += `## Causa provável\\n\\n`;\n report += `${probableCause}\\n\\n`;\n if (flakyAnalysis?.patterns?.length) {\n report += `### Sugestões\\n\\n`;\n flakyAnalysis.patterns.forEach((p) => {\n report += `- **${p.pattern}:** ${p.suggestion}\\n`;\n });\n report += `\\n`;\n }\n }\n\n if (failed > 0 && failureOutput) {\n report += `## Última saída de falha (trecho)\\n\\n`;\n report += \"```\\n\";\n report += failureOutput.slice(0, 1500).trim();\n if (failureOutput.length > 1500) report += \"\\n...\";\n report += \"\\n```\\n\\n\";\n }\n\n report += `---\\n\\n`;\n report += `*Use \\`mcp-lab-agent por_que_falhou\\` (via MCP) ou \\`run_tests\\` com \\`explainOnFailure: true\\` para análise detalhada.*\\n`;\n\n if (outputFile) {\n fs.writeFileSync(outputFile, report, \"utf8\");\n console.log(`\\n📄 Relatório salvo em: ${outputFile}\\n`);\n } else {\n console.log(\"\\n\" + report);\n }\n\n process.exit(isFlaky ? 1 : 0);\n}\n\nfunction getRunCommand(structure, fw, spec) {\n const cwdMap = {\n cypress: structure.testDirs.includes(\"cypress\") ? path.join(PROJECT_ROOT, \"cypress\") : structure.testDirs[0] ? path.join(PROJECT_ROOT, structure.testDirs[0]) : PROJECT_ROOT,\n playwright: structure.testDirs.includes(\"playwright\") ? path.join(PROJECT_ROOT, \"playwright\") : structure.testDirs[0] ? path.join(PROJECT_ROOT, structure.testDirs[0]) : PROJECT_ROOT,\n };\n const cwd = cwdMap[fw] || getFrameworkCwd(structure, [\"specs\", \"tests\", \"e2e\"]) || PROJECT_ROOT;\n\n if (fw === \"cypress\") {\n return { cmd: \"npx\", args: spec ? [\"cypress\", \"run\", \"--spec\", spec] : [\"cypress\", \"run\"], cwd };\n }\n if (fw === \"playwright\") {\n return { cmd: \"npx\", args: spec ? [\"playwright\", \"test\", spec] : [\"playwright\", \"test\"], cwd };\n }\n if (fw === \"webdriverio\" || fw === \"appium\") {\n return { cmd: \"npx\", args: spec ? [\"wdio\", \"run\", spec] : [\"wdio\", \"run\"], cwd: PROJECT_ROOT };\n }\n if (fw === \"jest\") {\n return { cmd: \"npx\", args: spec ? [\"jest\", spec] : [\"jest\"], cwd: PROJECT_ROOT };\n }\n if (fw === \"vitest\") {\n return { cmd: \"npx\", args: [\"vitest\", \"run\", ...(spec ? [spec] : [])], cwd: PROJECT_ROOT };\n }\n if (fw === \"mocha\") {\n return { cmd: \"npx\", args: spec ? [\"mocha\", spec] : [\"mocha\"], cwd: PROJECT_ROOT };\n }\n if (fw === \"pytest\") {\n return { cmd: \"pytest\", args: spec ? [spec] : [], cwd: PROJECT_ROOT };\n }\n if (fw === \"robot\") {\n return { cmd: \"robot\", args: spec ? [spec] : [structure.testDirs[0] || \"tests\"], cwd: PROJECT_ROOT };\n }\n return { cmd: \"npm\", args: [\"test\"], cwd: PROJECT_ROOT };\n}\n\nasync function handleRunCommand() {\n const argv = process.argv.slice(2);\n const deviceIdx = argv.indexOf(\"--device\");\n const device = deviceIdx !== -1 && argv[deviceIdx + 1] ? argv[deviceIdx + 1] : null;\n const noAutoFix = argv.includes(\"--no-auto-fix\");\n const spec = argv.filter((a) => !a.startsWith(\"--\") && a !== \"run\")[0] || null;\n\n const structure = detectProjectStructure();\n if (!structure.hasTests) {\n console.error(\"❌ Nenhum framework de teste detectado.\");\n process.exit(1);\n }\n\n const fw = structure.testFrameworks[0];\n const deviceConfig = structure.hasMobile ? detectDeviceConfig(structure) : {};\n const useDevice = device || deviceConfig.configuration || deviceConfig.device;\n const doAutoFix = !noAutoFix && structure.hasMobile && !!spec;\n\n let runEnv = { ...process.env };\n if (Object.keys(deviceConfig.envOverrides || {}).length) {\n runEnv = { ...runEnv, ...deviceConfig.envOverrides };\n }\n if (device) {\n if (fw === \"detox\") runEnv.DETOX_CONFIGURATION = device;\n else if (fw === \"appium\") runEnv.APPIUM_DEVICE_NAME = device;\n } else if (deviceConfig.configuration && fw === \"detox\") {\n runEnv.DETOX_CONFIGURATION = deviceConfig.configuration;\n }\n\n let { cmd, args, cwd } = getRunCommand(structure, fw, spec);\n if (fw === \"detox\" && useDevice) {\n args = [...args.slice(0, 2), \"--configuration\", useDevice, ...args.slice(2)];\n }\n\n const isSelectorFailure = (out) => /element not found|selector|timeout|locator|cy\\.get|page\\.locator|Unable to find/i.test(out || \"\");\n\n console.log(`\\n▶️ Rodando testes${spec ? `: ${spec}` : \"\"}\\n`);\n if (useDevice) console.log(` Device: ${useDevice}\\n`);\n\n let result = await runTestsOnce(cmd, args, cwd, runEnv);\n let autoFixed = false;\n\n if (!result.passed && doAutoFix && isSelectorFailure(result.runOutput) && resolveLLMProvider(\"complex\").apiKey) {\n console.log(\"\\n⚠️ Falha por seletor. Aplicando correção automática...\\n\");\n const fixResult = await applySelectorFixAndRetry(spec, result.runOutput, fw);\n if (fixResult.applied) {\n autoFixed = true;\n result = await runTestsOnce(cmd, args, cwd, runEnv);\n }\n }\n\n if (result.passed) {\n console.log(`\\n✅ Testes passaram${autoFixed ? \" (após correção de seletor)\" : \"\"}.\\n`);\n } else {\n console.log(`\\n❌ Testes falharam.\\n`);\n if (result.runOutput) console.log(result.runOutput.slice(0, 800) + (result.runOutput.length > 800 ? \"\\n...\" : \"\"));\n }\n\n process.exit(result.passed ? 0 : 1);\n}\n\nfunction runTestsOnce(cmd, args, cwd, env = process.env) {\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, ...env },\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 child.on(\"close\", (code) => {\n const output = [stdout, stderr].filter(Boolean).join(\"\\n\");\n resolve({ passed: code === 0, code: code ?? 1, output });\n });\n });\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","res","data","path","fs","path","fs","PROJECT_ROOT","path","fs","PROJECT_ROOT","path","fs","PROJECT_ROOT","path","METRICS_FILE","fs","QA_AGENTS","runTestsOnce","spawn","getExtensionAndBaseDir","res","data","learnedAppendix","__dirname","hubUrl"]}