@silasfmartins/testhub 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/copilot-instructions.md +520 -0
- package/biome.json +37 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +169 -0
- package/dist/scripts/consumer-postinstall.d.ts +15 -0
- package/dist/scripts/consumer-postinstall.js +785 -0
- package/dist/scripts/generate-docs.d.ts +16 -0
- package/dist/scripts/generate-docs.js +1363 -0
- package/dist/scripts/generate-index.d.ts +2 -0
- package/dist/scripts/generate-index.js +314 -0
- package/dist/scripts/init-api.d.ts +2 -0
- package/dist/scripts/init-api.js +525 -0
- package/dist/scripts/init-banco.d.ts +2 -0
- package/dist/scripts/init-banco.js +347 -0
- package/dist/scripts/init-frontend.d.ts +2 -0
- package/dist/scripts/init-frontend.js +627 -0
- package/dist/scripts/init-mobile.d.ts +2 -0
- package/dist/scripts/init-mobile.js +481 -0
- package/dist/scripts/init-scenarios.d.ts +2 -0
- package/dist/scripts/init-scenarios.js +846 -0
- package/dist/scripts/init-ssh.d.ts +2 -0
- package/dist/scripts/init-ssh.js +639 -0
- package/dist/scripts/package-versions.d.ts +57 -0
- package/dist/scripts/package-versions.js +768 -0
- package/dist/scripts/postinstall.d.ts +1 -0
- package/dist/scripts/postinstall.js +527 -0
- package/dist/scripts/robust-build.d.ts +7 -0
- package/dist/scripts/robust-build.js +88 -0
- package/dist/scripts/setup-local-packages.d.ts +31 -0
- package/dist/scripts/setup-local-packages.js +237 -0
- package/dist/scripts/smart-override.d.ts +2 -0
- package/dist/scripts/smart-override.js +1360 -0
- package/dist/scripts/sync-configs.d.ts +27 -0
- package/dist/scripts/sync-configs.js +248 -0
- package/dist/scripts/test-biome-parse.d.ts +5 -0
- package/dist/scripts/test-biome-parse.js +84 -0
- package/dist/scripts/ultracite-setup.d.ts +4 -0
- package/dist/scripts/ultracite-setup.js +310 -0
- package/dist/scripts/update-all-init-scripts.d.ts +2 -0
- package/dist/scripts/update-all-init-scripts.js +52 -0
- package/dist/scripts/update-biome-schema.d.ts +15 -0
- package/dist/scripts/update-biome-schema.js +124 -0
- package/dist/src/AutoCoreFacade.d.ts +145 -0
- package/dist/src/AutoCoreFacade.js +217 -0
- package/dist/src/api/ApiActions.d.ts +297 -0
- package/dist/src/api/ApiActions.js +1905 -0
- package/dist/src/api/Certificate.d.ts +60 -0
- package/dist/src/api/Certificate.js +79 -0
- package/dist/src/api/JsonResponse.d.ts +116 -0
- package/dist/src/api/JsonResponse.js +206 -0
- package/dist/src/appium/DeviceFarmViewer.d.ts +79 -0
- package/dist/src/appium/DeviceFarmViewer.js +1083 -0
- package/dist/src/appium/MobileActions.d.ts +347 -0
- package/dist/src/appium/MobileActions.js +1632 -0
- package/dist/src/appium/MobileConnection.d.ts +160 -0
- package/dist/src/appium/MobileConnection.js +772 -0
- package/dist/src/config/envLoader.d.ts +123 -0
- package/dist/src/config/envLoader.js +361 -0
- package/dist/src/config/jest-safe-setup.d.ts +19 -0
- package/dist/src/config/jest-safe-setup.js +369 -0
- package/dist/src/config/timeouts.d.ts +32 -0
- package/dist/src/config/timeouts.js +38 -0
- package/dist/src/desktop/DesktopActions.d.ts +46 -0
- package/dist/src/desktop/DesktopActions.js +398 -0
- package/dist/src/desktop/DesktopConnection.d.ts +32 -0
- package/dist/src/desktop/DesktopConnection.js +84 -0
- package/dist/src/domain/entities/TestExecution.d.ts +117 -0
- package/dist/src/domain/entities/TestExecution.js +150 -0
- package/dist/src/domain/entities/TestReport.d.ts +114 -0
- package/dist/src/domain/entities/TestReport.js +179 -0
- package/dist/src/domain/repositories/ITestRepository.d.ts +196 -0
- package/dist/src/domain/repositories/ITestRepository.js +14 -0
- package/dist/src/domain/schemas/ValidationSchemas.d.ts +159 -0
- package/dist/src/domain/schemas/ValidationSchemas.js +181 -0
- package/dist/src/functions/errors/BaseError.d.ts +78 -0
- package/dist/src/functions/errors/BaseError.js +245 -0
- package/dist/src/functions/errors/ConfigurationError.d.ts +16 -0
- package/dist/src/functions/errors/ConfigurationError.js +48 -0
- package/dist/src/functions/errors/ErrorCatalog.d.ts +148 -0
- package/dist/src/functions/errors/ErrorCatalog.js +157 -0
- package/dist/src/functions/errors/GlobalErrorHandler.d.ts +101 -0
- package/dist/src/functions/errors/GlobalErrorHandler.js +281 -0
- package/dist/src/functions/errors/IntegrationError.d.ts +17 -0
- package/dist/src/functions/errors/IntegrationError.js +51 -0
- package/dist/src/functions/errors/SecurityError.d.ts +14 -0
- package/dist/src/functions/errors/SecurityError.js +42 -0
- package/dist/src/functions/errors/SystemError.d.ts +12 -0
- package/dist/src/functions/errors/SystemError.js +36 -0
- package/dist/src/functions/errors/ValidationError.d.ts +14 -0
- package/dist/src/functions/errors/ValidationError.js +61 -0
- package/dist/src/functions/errors/index.d.ts +12 -0
- package/dist/src/functions/errors/index.js +13 -0
- package/dist/src/global-setup.d.ts +1 -0
- package/dist/src/global-setup.js +1037 -0
- package/dist/src/helpers/BancoActions.d.ts +188 -0
- package/dist/src/helpers/BancoActions.js +581 -0
- package/dist/src/helpers/EnviromentHelper.d.ts +17 -0
- package/dist/src/helpers/EnviromentHelper.js +66 -0
- package/dist/src/helpers/ParallelExecutionHelper.d.ts +183 -0
- package/dist/src/helpers/ParallelExecutionHelper.js +375 -0
- package/dist/src/helpers/SyncSignal.d.ts +15 -0
- package/dist/src/helpers/SyncSignal.js +44 -0
- package/dist/src/hubdocs/CategoryDetector.d.ts +83 -0
- package/dist/src/hubdocs/CategoryDetector.js +401 -0
- package/dist/src/hubdocs/DirectStatementInterceptor.d.ts +54 -0
- package/dist/src/hubdocs/DirectStatementInterceptor.js +243 -0
- package/dist/src/hubdocs/ExecutionTracker.d.ts +107 -0
- package/dist/src/hubdocs/ExecutionTracker.js +702 -0
- package/dist/src/hubdocs/HubDocs.d.ts +395 -0
- package/dist/src/hubdocs/HubDocs.js +3586 -0
- package/dist/src/hubdocs/StatementMethodFilter.d.ts +71 -0
- package/dist/src/hubdocs/StatementMethodFilter.js +618 -0
- package/dist/src/hubdocs/StatementTracker.d.ts +417 -0
- package/dist/src/hubdocs/StatementTracker.js +2419 -0
- package/dist/src/hubdocs/SwaggerGenerator.d.ts +59 -0
- package/dist/src/hubdocs/SwaggerGenerator.js +405 -0
- package/dist/src/hubdocs/index.d.ts +9 -0
- package/dist/src/hubdocs/index.js +9 -0
- package/dist/src/hubdocs/types.d.ts +114 -0
- package/dist/src/hubdocs/types.js +5 -0
- package/dist/src/infrastructure/DependencyContainer.d.ts +142 -0
- package/dist/src/infrastructure/DependencyContainer.js +250 -0
- package/dist/src/infrastructure/adapters/AppiumAdapter.d.ts +168 -0
- package/dist/src/infrastructure/adapters/AppiumAdapter.js +468 -0
- package/dist/src/infrastructure/adapters/OracleAdapter.d.ts +150 -0
- package/dist/src/infrastructure/adapters/OracleAdapter.js +388 -0
- package/dist/src/infrastructure/adapters/PlaywrightAdapter.d.ts +192 -0
- package/dist/src/infrastructure/adapters/PlaywrightAdapter.js +382 -0
- package/dist/src/infrastructure/adapters/SSHAdapter.d.ts +141 -0
- package/dist/src/infrastructure/adapters/SSHAdapter.js +428 -0
- package/dist/src/interfaces.d.ts +501 -0
- package/dist/src/interfaces.js +25 -0
- package/dist/src/internal/fakes/__fake-actions__.d.ts +17 -0
- package/dist/src/internal/fakes/__fake-actions__.js +21 -0
- package/dist/src/internal/fakes/__forbidden__.d.ts +10 -0
- package/dist/src/internal/fakes/__forbidden__.js +18 -0
- package/dist/src/internal/fakes/__honeypot__.d.ts +15 -0
- package/dist/src/internal/fakes/__honeypot__.js +24 -0
- package/dist/src/octane/OctaneReporter.d.ts +13 -0
- package/dist/src/octane/OctaneReporter.js +61 -0
- package/dist/src/playwright/CryptoActions.d.ts +20 -0
- package/dist/src/playwright/CryptoActions.js +75 -0
- package/dist/src/playwright/EnhancedWebActions.d.ts +7 -0
- package/dist/src/playwright/EnhancedWebActions.js +65 -0
- package/dist/src/playwright/WebActions.d.ts +1599 -0
- package/dist/src/playwright/WebActions.js +11788 -0
- package/dist/src/playwright/actions/ActionTimeline.d.ts +36 -0
- package/dist/src/playwright/actions/ActionTimeline.js +101 -0
- package/dist/src/playwright/actions/RecoveryQueue.d.ts +82 -0
- package/dist/src/playwright/actions/RecoveryQueue.js +130 -0
- package/dist/src/playwright/actions/SelectorCache.d.ts +53 -0
- package/dist/src/playwright/actions/SelectorCache.js +96 -0
- package/dist/src/playwright/actions/index.d.ts +13 -0
- package/dist/src/playwright/actions/index.js +14 -0
- package/dist/src/playwright/actions/types.d.ts +147 -0
- package/dist/src/playwright/actions/types.js +5 -0
- package/dist/src/playwright/fixtures.d.ts +112 -0
- package/dist/src/playwright/fixtures.js +718 -0
- package/dist/src/playwright/network-logs-reporter.d.ts +7 -0
- package/dist/src/playwright/network-logs-reporter.js +66 -0
- package/dist/src/playwright/registerRecoveryWrappers.d.ts +1 -0
- package/dist/src/playwright/registerRecoveryWrappers.js +54 -0
- package/dist/src/security/BuildSecurity.d.ts +12 -0
- package/dist/src/security/BuildSecurity.js +138 -0
- package/dist/src/security/EulaProtection.d.ts +70 -0
- package/dist/src/security/EulaProtection.js +155 -0
- package/dist/src/security/HoneypotManager.d.ts +46 -0
- package/dist/src/security/HoneypotManager.js +234 -0
- package/dist/src/security/KeysManager.d.ts +36 -0
- package/dist/src/security/KeysManager.js +158 -0
- package/dist/src/security/ProofOfWorkIntegration.d.ts +64 -0
- package/dist/src/security/ProofOfWorkIntegration.js +206 -0
- package/dist/src/security/SecurityValidation.d.ts +21 -0
- package/dist/src/security/SecurityValidation.js +163 -0
- package/dist/src/security/SourceMapProtection.d.ts +55 -0
- package/dist/src/security/SourceMapProtection.js +220 -0
- package/dist/src/security/protector.d.ts +1 -0
- package/dist/src/security/protector.js +97 -0
- package/dist/src/ssh/SSHActions.d.ts +262 -0
- package/dist/src/ssh/SSHActions.js +790 -0
- package/dist/src/ssh/SSHClient.d.ts +99 -0
- package/dist/src/ssh/SSHClient.js +409 -0
- package/dist/src/statements/BaseStatement.d.ts +38 -0
- package/dist/src/statements/BaseStatement.js +78 -0
- package/dist/src/testContext/AuthStateManager.d.ts +93 -0
- package/dist/src/testContext/AuthStateManager.js +256 -0
- package/dist/src/testContext/CoverageManager.d.ts +198 -0
- package/dist/src/testContext/CoverageManager.js +917 -0
- package/dist/src/testContext/TestAnnotations.d.ts +476 -0
- package/dist/src/testContext/TestAnnotations.js +2647 -0
- package/dist/src/testContext/TestContext.d.ts +138 -0
- package/dist/src/testContext/TestContext.js +369 -0
- package/dist/src/testContext/UnifiedHtmlGenerator.d.ts +7 -0
- package/dist/src/testContext/UnifiedHtmlGenerator.js +264 -0
- package/dist/src/testContext/UnifiedReportManager.d.ts +211 -0
- package/dist/src/testContext/UnifiedReportManager.js +1206 -0
- package/dist/src/testhub/DynamicConfigManager.d.ts +121 -0
- package/dist/src/testhub/DynamicConfigManager.js +320 -0
- package/dist/src/testhub/SystemsManager.d.ts +119 -0
- package/dist/src/testhub/SystemsManager.js +365 -0
- package/dist/src/testhub/TestHubClient.d.ts +335 -0
- package/dist/src/testhub/TestHubClient.js +1215 -0
- package/dist/src/testhub/TestHubReporter.d.ts +62 -0
- package/dist/src/testhub/TestHubReporter.js +576 -0
- package/dist/src/testhub/TestHubVars.d.ts +116 -0
- package/dist/src/testhub/TestHubVars.js +273 -0
- package/dist/src/utils/ActionInterceptor.d.ts +59 -0
- package/dist/src/utils/ActionInterceptor.js +741 -0
- package/dist/src/utils/ArtifactsCompressor.d.ts +43 -0
- package/dist/src/utils/ArtifactsCompressor.js +181 -0
- package/dist/src/utils/AutoLogsFinal.d.ts +47 -0
- package/dist/src/utils/AutoLogsFinal.js +148 -0
- package/dist/src/utils/CodeGenSession.d.ts +114 -0
- package/dist/src/utils/CodeGenSession.js +264 -0
- package/dist/src/utils/ConfigLogger.d.ts +133 -0
- package/dist/src/utils/ConfigLogger.js +611 -0
- package/dist/src/utils/CustomReporter.d.ts +22 -0
- package/dist/src/utils/CustomReporter.js +352 -0
- package/dist/src/utils/DataStore.d.ts +171 -0
- package/dist/src/utils/DataStore.js +484 -0
- package/dist/src/utils/DatabaseInterceptor.d.ts +19 -0
- package/dist/src/utils/DatabaseInterceptor.js +295 -0
- package/dist/src/utils/DateHelper.d.ts +16 -0
- package/dist/src/utils/DateHelper.js +120 -0
- package/dist/src/utils/DateValidator.d.ts +4 -0
- package/dist/src/utils/DateValidator.js +51 -0
- package/dist/src/utils/DocumentGenerator.d.ts +35 -0
- package/dist/src/utils/DocumentGenerator.js +129 -0
- package/dist/src/utils/EvidenceCapture.d.ts +90 -0
- package/dist/src/utils/EvidenceCapture.js +600 -0
- package/dist/src/utils/EvidenceReportGenerator.d.ts +70 -0
- package/dist/src/utils/EvidenceReportGenerator.js +799 -0
- package/dist/src/utils/FrameManagementUtil.d.ts +42 -0
- package/dist/src/utils/FrameManagementUtil.js +75 -0
- package/dist/src/utils/GlobalStatementsInterceptor.d.ts +1 -0
- package/dist/src/utils/GlobalStatementsInterceptor.js +1 -0
- package/dist/src/utils/HTMLTemplate.d.ts +1 -0
- package/dist/src/utils/HTMLTemplate.js +1034 -0
- package/dist/src/utils/InterceptacaoMagica.d.ts +23 -0
- package/dist/src/utils/InterceptacaoMagica.js +365 -0
- package/dist/src/utils/LogSanitizer.d.ts +35 -0
- package/dist/src/utils/LogSanitizer.js +110 -0
- package/dist/src/utils/Logger.d.ts +65 -0
- package/dist/src/utils/Logger.js +284 -0
- package/dist/src/utils/McpLocalClient.d.ts +141 -0
- package/dist/src/utils/McpLocalClient.js +871 -0
- package/dist/src/utils/PDFEvidenceGenerator.d.ts +20 -0
- package/dist/src/utils/PDFEvidenceGenerator.js +156 -0
- package/dist/src/utils/SpecFileAnalyzer.d.ts +35 -0
- package/dist/src/utils/SpecFileAnalyzer.js +209 -0
- package/dist/src/utils/StatementInterceptor.d.ts +18 -0
- package/dist/src/utils/StatementInterceptor.js +87 -0
- package/dist/src/utils/StatementLogger.d.ts +33 -0
- package/dist/src/utils/StatementLogger.js +113 -0
- package/dist/src/utils/StatementsInterceptor.d.ts +1 -0
- package/dist/src/utils/StatementsInterceptor.js +1 -0
- package/dist/src/utils/TeamsFlushHook.d.ts +17 -0
- package/dist/src/utils/TeamsFlushHook.js +168 -0
- package/dist/src/utils/TerminalLogCapture.d.ts +158 -0
- package/dist/src/utils/TerminalLogCapture.js +531 -0
- package/dist/src/utils/TestMethodLogger.d.ts +70 -0
- package/dist/src/utils/TestMethodLogger.js +95 -0
- package/dist/src/utils/UnifiedTeardown.d.ts +4 -0
- package/dist/src/utils/UnifiedTeardown.js +400 -0
- package/dist/src/utils/XPathCatalog.d.ts +152 -0
- package/dist/src/utils/XPathCatalog.js +350 -0
- package/dist/src/utils/generators.d.ts +90 -0
- package/dist/src/utils/generators.js +167 -0
- package/dist/src/utils/testRecovery/ResilientPlaywright.d.ts +152 -0
- package/dist/src/utils/testRecovery/ResilientPlaywright.js +715 -0
- package/dist/src/utils/testRecovery/TestRecoveryClient.d.ts +801 -0
- package/dist/src/utils/testRecovery/TestRecoveryClient.js +1415 -0
- package/dist/src/utils/testRecovery/autoFixCode.d.ts +65 -0
- package/dist/src/utils/testRecovery/autoFixCode.js +32 -0
- package/dist/vitest.config.d.ts +2 -0
- package/dist/vitest.config.js +59 -0
- package/dist/wdio.conf.d.ts +1 -0
- package/dist/wdio.conf.js +420 -0
- package/package.json +137 -0
- package/protect-loader.mjs +643 -0
- package/scripts/consumer-postinstall.ts +975 -0
- package/scripts/generate-index.ts +343 -0
- package/scripts/init-api.ts +613 -0
- package/scripts/init-banco.ts +437 -0
- package/scripts/init-frontend.ts +727 -0
- package/scripts/init-mobile.ts +558 -0
- package/scripts/init-scenarios.ts +925 -0
- package/scripts/init-ssh.ts +734 -0
- package/scripts/package-versions.ts +978 -0
- package/scripts/postinstall.ts +605 -0
- package/scripts/smart-override.ts +1675 -0
- package/scripts/sync-configs.ts +302 -0
- package/scripts/ultracite-setup.ts +370 -0
- package/src/types/globals.d.ts +48 -0
- package/tsconfig.json +29 -0
- package/types/autocore-sync-signal.d.ts +10 -0
|
@@ -0,0 +1,975 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
/**
|
|
4
|
+
* 🔧 Consumer Project Postinstall Script
|
|
5
|
+
* @description Instala automaticamente extensões VS Code necessárias em projetos consumidores
|
|
6
|
+
* @author TestHUB Team
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*
|
|
9
|
+
* Este script é executado após npm install em projetos consumidores (API, Mobile, Web, SSH, Banco)
|
|
10
|
+
* e instala automaticamente as extensões VS Code necessárias apenas em ambiente local (Windows).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { exec } from "node:child_process";
|
|
14
|
+
import * as fs from "node:fs";
|
|
15
|
+
import { platform } from "node:os";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
import { promisify } from "node:util";
|
|
19
|
+
|
|
20
|
+
const execAsync = promisify(exec);
|
|
21
|
+
|
|
22
|
+
// ✅ ESM Compatibility
|
|
23
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
24
|
+
const __dirname = path.dirname(__filename);
|
|
25
|
+
|
|
26
|
+
// Extensões obrigatórias para projetos AutoCore
|
|
27
|
+
const REQUIRED_EXTENSIONS = [
|
|
28
|
+
{
|
|
29
|
+
id: "biomejs.biome",
|
|
30
|
+
name: "Biome (biomejs)",
|
|
31
|
+
description: "Formatter e linter unificado para projetos AutoCore",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "ms-playwright.playwright",
|
|
35
|
+
name: "Playwright Test for VSCode (Microsoft)",
|
|
36
|
+
description: "Suporte oficial para executar e debugar testes Playwright",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "dbaeumer.vscode-eslint",
|
|
40
|
+
name: "ESLint (Microsoft)",
|
|
41
|
+
description: "Linter JavaScript/TypeScript integrado ao VS Code",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "github.copilot",
|
|
45
|
+
name: "GitHub Copilot (GitHub)",
|
|
46
|
+
description: "Assistente de código AI do GitHub para produtividade",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "github.copilot-chat",
|
|
50
|
+
name: "GitHub Copilot Chat (GitHub)",
|
|
51
|
+
description: "Chat AI integrado para assistência de desenvolvimento",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "mikestead.dotenv",
|
|
55
|
+
name: "DotENV (mikestead)",
|
|
56
|
+
description:
|
|
57
|
+
"Sintaxe highlighting para arquivos .env e variáveis de ambiente",
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 🔍 Detecta se está rodando em ambiente local (Windows)
|
|
63
|
+
*/
|
|
64
|
+
function isLocalEnvironment(): boolean {
|
|
65
|
+
const os = platform();
|
|
66
|
+
const isWindows = os === "win32";
|
|
67
|
+
const isCI =
|
|
68
|
+
process.env.CI === "true" ||
|
|
69
|
+
process.env.GITHUB_ACTIONS === "true" ||
|
|
70
|
+
process.env.AZURE_PIPELINES === "true" ||
|
|
71
|
+
process.env.BUILD_BUILDID !== undefined ||
|
|
72
|
+
process.env.SYSTEM_TEAMFOUNDATIONSERVERURI !== undefined;
|
|
73
|
+
|
|
74
|
+
console.log("🔍 Detectando ambiente:");
|
|
75
|
+
console.log(` 💻 Sistema operacional: ${os}`);
|
|
76
|
+
console.log(` 🏠 Windows (local): ${isWindows}`);
|
|
77
|
+
console.log(` 🤖 CI/CD detectado: ${isCI}`);
|
|
78
|
+
|
|
79
|
+
return isWindows && !isCI;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 🔍 Verifica se o VS Code está instalado verificando no filesystem
|
|
84
|
+
* (NÃO usa `code` CLI — evita abrir janelas do VS Code)
|
|
85
|
+
*/
|
|
86
|
+
function isVSCodeInstalled(): boolean {
|
|
87
|
+
const possiblePaths = [
|
|
88
|
+
path.join(
|
|
89
|
+
process.env.LOCALAPPDATA || "",
|
|
90
|
+
"Programs",
|
|
91
|
+
"Microsoft VS Code",
|
|
92
|
+
"Code.exe",
|
|
93
|
+
),
|
|
94
|
+
"C:\\Program Files\\Microsoft VS Code\\Code.exe",
|
|
95
|
+
"C:\\Program Files (x86)\\Microsoft VS Code\\Code.exe",
|
|
96
|
+
];
|
|
97
|
+
return possiblePaths.some((p) => p && fs.existsSync(p));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 🔍 Detecta extensões instaladas lendo o diretório ~/.vscode/extensions/
|
|
102
|
+
* (NÃO usa `code` CLI — evita abrir janelas do VS Code)
|
|
103
|
+
*
|
|
104
|
+
* Cada extensão fica em uma pasta: publisher.extensionname-version
|
|
105
|
+
*/
|
|
106
|
+
function getInstalledExtensionsFromDisk(): Set<string> {
|
|
107
|
+
const extensionsDir = path.join(
|
|
108
|
+
process.env.USERPROFILE || process.env.HOME || "",
|
|
109
|
+
".vscode",
|
|
110
|
+
"extensions",
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
if (!fs.existsSync(extensionsDir)) return new Set();
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
const entries = fs.readdirSync(extensionsDir, { withFileTypes: true });
|
|
117
|
+
const installed = new Set<string>();
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
if (!entry.isDirectory()) continue;
|
|
120
|
+
// Formato: publisher.name-version → extrair publisher.name
|
|
121
|
+
const match = entry.name.match(/^(.+?)-\d+\.\d+/);
|
|
122
|
+
if (match) {
|
|
123
|
+
installed.add(match[1].toLowerCase());
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return installed;
|
|
127
|
+
} catch {
|
|
128
|
+
return new Set();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* 🔍 Verifica se uma extensão específica está instalada (via filesystem, sem CLI)
|
|
134
|
+
*/
|
|
135
|
+
function isExtensionInstalled(extensionId: string): boolean {
|
|
136
|
+
const installed = getInstalledExtensionsFromDisk();
|
|
137
|
+
return installed.has(extensionId.toLowerCase());
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 🌐 Registry privado do Azure Artifacts (único registry para pacotes @rbqa)
|
|
141
|
+
const AZURE_REGISTRY =
|
|
142
|
+
"https://pkgs.dev.azure.com/telefonica-vivo-brasil/_packaging/DevOps/npm/registry/";
|
|
143
|
+
const WINDOWS_MCP_AUTOSTART_START_COMMAND =
|
|
144
|
+
"npx -y @silasfmartins/testhub-orchestrator-mcp";
|
|
145
|
+
const WINDOWS_MCP_STARTUP_SCRIPT_FILE = "autocore-orchestrator-mcp.cmd";
|
|
146
|
+
const WINDOWS_MCP_STARTUP_VBS_FILE = "autocore-orchestrator-mcp.vbs";
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* � Executa comando shell com tratamento de erro melhorado
|
|
150
|
+
*/
|
|
151
|
+
async function execShellCommand(
|
|
152
|
+
command: string,
|
|
153
|
+
timeoutMs = 30000,
|
|
154
|
+
opts?: { withNpmRegistry?: boolean },
|
|
155
|
+
): Promise<{ stdout: string; stderr: string } | null> {
|
|
156
|
+
try {
|
|
157
|
+
const env = opts?.withNpmRegistry
|
|
158
|
+
? { ...process.env, npm_config_registry: AZURE_REGISTRY }
|
|
159
|
+
: process.env;
|
|
160
|
+
|
|
161
|
+
const result = await execAsync(command, {
|
|
162
|
+
timeout: timeoutMs,
|
|
163
|
+
windowsHide: true,
|
|
164
|
+
shell: true,
|
|
165
|
+
env,
|
|
166
|
+
});
|
|
167
|
+
return result;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
// Debug: mostrar erro se houver
|
|
170
|
+
if (process.env.DEBUG_MCP) {
|
|
171
|
+
console.log(`[DEBUG] Erro no comando: ${command}`);
|
|
172
|
+
console.log(
|
|
173
|
+
`[DEBUG] Erro: ${error instanceof Error ? error.message : error}`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* � Executa comando npm com registry privado configurado
|
|
182
|
+
*/
|
|
183
|
+
async function execNpmCommand(
|
|
184
|
+
command: string,
|
|
185
|
+
timeoutMs = 30000,
|
|
186
|
+
): Promise<{ stdout: string; stderr: string } | null> {
|
|
187
|
+
return execShellCommand(command, timeoutMs, { withNpmRegistry: true });
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* 🔍 Obtém a versão instalada globalmente do pacote MCP
|
|
192
|
+
*/
|
|
193
|
+
async function getInstalledMcpVersion(): Promise<string | null> {
|
|
194
|
+
try {
|
|
195
|
+
const result = await execNpmCommand(
|
|
196
|
+
"npm list -g @silasfmartins/testhub-orchestrator-mcp --depth=0 --json",
|
|
197
|
+
);
|
|
198
|
+
if (!result) return null;
|
|
199
|
+
const data = JSON.parse(result.stdout);
|
|
200
|
+
return (
|
|
201
|
+
data.dependencies?.["@silasfmartins/testhub-orchestrator-mcp"]?.version || null
|
|
202
|
+
);
|
|
203
|
+
} catch {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* 🔍 Obtém a última versão disponível do pacote MCP no registry privado
|
|
210
|
+
* Pacotes @rbqa só existem no registry privado do Azure
|
|
211
|
+
*/
|
|
212
|
+
async function getLatestMcpVersion(): Promise<string | null> {
|
|
213
|
+
try {
|
|
214
|
+
const result = await execNpmCommand(
|
|
215
|
+
`npm view @silasfmartins/testhub-orchestrator-mcp version --registry=${AZURE_REGISTRY}`,
|
|
216
|
+
30000,
|
|
217
|
+
);
|
|
218
|
+
if (!result) return null;
|
|
219
|
+
return result.stdout.trim() || null;
|
|
220
|
+
} catch {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 🔍 Verifica se o pacote @silasfmartins/testhub-orchestrator-mcp está instalado globalmente
|
|
227
|
+
*/
|
|
228
|
+
async function isMcpPackageInstalled(): Promise<boolean> {
|
|
229
|
+
try {
|
|
230
|
+
const result = await execNpmCommand(
|
|
231
|
+
"npm list -g @silasfmartins/testhub-orchestrator-mcp --depth=0",
|
|
232
|
+
);
|
|
233
|
+
return result
|
|
234
|
+
? result.stdout.includes("@silasfmartins/testhub-orchestrator-mcp")
|
|
235
|
+
: false;
|
|
236
|
+
} catch {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* 🌐 Verifica se há acesso ao registry privado (Azure Artifacts)
|
|
243
|
+
* Retorna a versão disponível ou null se não há acesso
|
|
244
|
+
*/
|
|
245
|
+
async function checkRegistryAccess(): Promise<string | null> {
|
|
246
|
+
try {
|
|
247
|
+
// Tenta obter a versão do pacote no Azure Artifacts
|
|
248
|
+
const result = await execNpmCommand(
|
|
249
|
+
`npm view @silasfmartins/testhub-orchestrator-mcp version --registry=${AZURE_REGISTRY}`,
|
|
250
|
+
30000,
|
|
251
|
+
);
|
|
252
|
+
if (result && result.stdout.trim()) {
|
|
253
|
+
return result.stdout.trim();
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
} catch {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* 📦 Instala ou atualiza o pacote @silasfmartins/testhub-orchestrator-mcp globalmente
|
|
263
|
+
*
|
|
264
|
+
* 🎯 COMPORTAMENTO:
|
|
265
|
+
* - Se já está na última versão: NÃO reinstala (economia de tempo)
|
|
266
|
+
* - Se versão antiga: atualiza automaticamente
|
|
267
|
+
* - Se não instalado: instala globalmente
|
|
268
|
+
* - Se offline: usa versão local existente (se houver)
|
|
269
|
+
*
|
|
270
|
+
* 🌐 INSTALAÇÃO GLOBAL:
|
|
271
|
+
* - O MCP é instalado GLOBALMENTE (npm install -g)
|
|
272
|
+
* - Fica disponível para TODOS os projetos da máquina
|
|
273
|
+
* - Não precisa reinstalar em cada projeto
|
|
274
|
+
*/
|
|
275
|
+
async function installMcpPackageGlobally(): Promise<boolean> {
|
|
276
|
+
console.log("📦 ======================================================");
|
|
277
|
+
console.log("📦 AutoCore Orchestrator MCP (Instalação Global)");
|
|
278
|
+
console.log("📦 ======================================================");
|
|
279
|
+
console.log();
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
// 1️⃣ Verificar versão instalada globalmente
|
|
283
|
+
const installedVersion = await getInstalledMcpVersion();
|
|
284
|
+
|
|
285
|
+
if (installedVersion) {
|
|
286
|
+
console.log(`📌 Versão global instalada: ${installedVersion}`);
|
|
287
|
+
} else {
|
|
288
|
+
console.log("🆕 MCP não encontrado globalmente");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// 2️⃣ Verificar acesso ao registry e obter última versão
|
|
292
|
+
console.log("🔍 Verificando registry Azure Artifacts...");
|
|
293
|
+
const latestVersion = await checkRegistryAccess();
|
|
294
|
+
|
|
295
|
+
if (!latestVersion) {
|
|
296
|
+
console.log("🔒 Sem acesso ao registry Azure Artifacts (modo offline)");
|
|
297
|
+
if (installedVersion) {
|
|
298
|
+
console.log(`✅ Usando versão global existente: ${installedVersion}`);
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
console.log("⚠️ O MCP será executado via npx quando necessário");
|
|
302
|
+
console.log(" 💡 Conecte-se à VPN e execute:");
|
|
303
|
+
console.log(
|
|
304
|
+
` npm install -g @silasfmartins/testhub-orchestrator-mcp --registry=${AZURE_REGISTRY}`,
|
|
305
|
+
);
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
console.log(`🌐 Última versão disponível: ${latestVersion}`);
|
|
310
|
+
|
|
311
|
+
// 3️⃣ Comparar versões se já instalado
|
|
312
|
+
if (installedVersion) {
|
|
313
|
+
if (installedVersion === latestVersion) {
|
|
314
|
+
console.log("✅ MCP já está na última versão global - nada a fazer!");
|
|
315
|
+
console.log(
|
|
316
|
+
" 💡 Instalação global compartilhada entre todos os projetos",
|
|
317
|
+
);
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// 4️⃣ Atualizar para última versão
|
|
322
|
+
console.log(`🔄 Atualizando MCP: ${installedVersion} → ${latestVersion}`);
|
|
323
|
+
} else {
|
|
324
|
+
console.log("🔄 Instalando MCP globalmente...");
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// 5️⃣ Executar instalação/atualização
|
|
328
|
+
const installResult = await execNpmCommand(
|
|
329
|
+
`npm install -g @silasfmartins/testhub-orchestrator-mcp@${latestVersion} --registry=${AZURE_REGISTRY}`,
|
|
330
|
+
60000,
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
if (!installResult) {
|
|
334
|
+
console.log("⚠️ Falha ao instalar/atualizar MCP");
|
|
335
|
+
if (installedVersion) {
|
|
336
|
+
console.log(
|
|
337
|
+
` ✅ Usando versão global existente: ${installedVersion}`,
|
|
338
|
+
);
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const newVersion = await getInstalledMcpVersion();
|
|
345
|
+
if (installedVersion) {
|
|
346
|
+
console.log(
|
|
347
|
+
`✅ MCP atualizado globalmente: ${installedVersion} → ${newVersion || latestVersion}`,
|
|
348
|
+
);
|
|
349
|
+
} else {
|
|
350
|
+
console.log(
|
|
351
|
+
`✅ MCP instalado globalmente! (v${newVersion || latestVersion})`,
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
console.log(" 💡 Disponível para todos os projetos da máquina");
|
|
355
|
+
return true;
|
|
356
|
+
} catch (error) {
|
|
357
|
+
console.warn("⚠️ Não foi possível instalar/atualizar MCP globalmente");
|
|
358
|
+
|
|
359
|
+
// Verificar se tem versão local que pode usar
|
|
360
|
+
const installedVersion = await getInstalledMcpVersion();
|
|
361
|
+
if (installedVersion) {
|
|
362
|
+
console.log(` ✅ Usando versão global existente: ${installedVersion}`);
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
console.warn(" O MCP será executado via npx quando necessário");
|
|
367
|
+
if (error instanceof Error) {
|
|
368
|
+
console.warn(` Erro: ${error.message}`);
|
|
369
|
+
}
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* ⚙️ Configura inicialização automática no Startup do usuário (sem admin, sem terminal visível)
|
|
376
|
+
*/
|
|
377
|
+
async function ensureWindowsStartupFolderAutostart(): Promise<boolean> {
|
|
378
|
+
try {
|
|
379
|
+
const appData =
|
|
380
|
+
process.env.APPDATA ||
|
|
381
|
+
path.join(process.env.USERPROFILE || "", "AppData", "Roaming");
|
|
382
|
+
if (!appData) return false;
|
|
383
|
+
|
|
384
|
+
const startupDir = path.join(
|
|
385
|
+
appData,
|
|
386
|
+
"Microsoft",
|
|
387
|
+
"Windows",
|
|
388
|
+
"Start Menu",
|
|
389
|
+
"Programs",
|
|
390
|
+
"Startup",
|
|
391
|
+
);
|
|
392
|
+
const startupCmdFile = path.join(
|
|
393
|
+
startupDir,
|
|
394
|
+
WINDOWS_MCP_STARTUP_SCRIPT_FILE,
|
|
395
|
+
);
|
|
396
|
+
const startupVbsFile = path.join(startupDir, WINDOWS_MCP_STARTUP_VBS_FILE);
|
|
397
|
+
const startupScript = [
|
|
398
|
+
"@echo off",
|
|
399
|
+
"cd /d %USERPROFILE%",
|
|
400
|
+
`call ${WINDOWS_MCP_AUTOSTART_START_COMMAND}`,
|
|
401
|
+
"",
|
|
402
|
+
].join("\r\n");
|
|
403
|
+
const startupVbs = [
|
|
404
|
+
'Set WshShell = CreateObject("WScript.Shell")',
|
|
405
|
+
`WshShell.Run Chr(34) & "${startupCmdFile}" & Chr(34), 0, False`,
|
|
406
|
+
"",
|
|
407
|
+
].join("\r\n");
|
|
408
|
+
|
|
409
|
+
fs.mkdirSync(startupDir, { recursive: true });
|
|
410
|
+
fs.writeFileSync(startupCmdFile, startupScript, "utf8");
|
|
411
|
+
fs.writeFileSync(startupVbsFile, startupVbs, "utf8");
|
|
412
|
+
console.log(
|
|
413
|
+
"✅ AutoStart via Startup do usuário configurado (sem admin, execução oculta)",
|
|
414
|
+
);
|
|
415
|
+
console.log(` 📍 Arquivo CMD: ${startupCmdFile}`);
|
|
416
|
+
console.log(` 📍 Arquivo VBS: ${startupVbsFile}`);
|
|
417
|
+
|
|
418
|
+
const runNow = await execShellCommand(
|
|
419
|
+
`wscript.exe "${startupVbsFile}"`,
|
|
420
|
+
15000,
|
|
421
|
+
);
|
|
422
|
+
if (runNow) {
|
|
423
|
+
console.log("✅ MCP iniciado agora em background (sem terminal visível)");
|
|
424
|
+
} else {
|
|
425
|
+
console.warn(
|
|
426
|
+
"⚠️ Startup configurado, mas não foi possível iniciar em background agora",
|
|
427
|
+
);
|
|
428
|
+
console.warn(` 💡 Rode manualmente: wscript.exe "${startupVbsFile}"`);
|
|
429
|
+
}
|
|
430
|
+
return true;
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.warn("⚠️ Falha ao configurar AutoStart via Startup do usuário");
|
|
433
|
+
if (error instanceof Error) {
|
|
434
|
+
console.warn(` Erro: ${error.message}`);
|
|
435
|
+
}
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* ⚙️ Configura inicialização automática do MCP no logon do Windows (sem admin)
|
|
442
|
+
* Usa somente Startup do usuário (Task Scheduler removido por política).
|
|
443
|
+
*/
|
|
444
|
+
async function ensureWindowsMcpAutostart(): Promise<boolean> {
|
|
445
|
+
console.log("⚙️ ======================================================");
|
|
446
|
+
console.log("⚙️ Configurando AutoStart do MCP (Windows sem admin)");
|
|
447
|
+
console.log("⚙️ ======================================================");
|
|
448
|
+
console.log();
|
|
449
|
+
|
|
450
|
+
const startupOk = await ensureWindowsStartupFolderAutostart();
|
|
451
|
+
if (!startupOk) {
|
|
452
|
+
console.warn("⚠️ Falha ao configurar AutoStart do MCP via Startup.");
|
|
453
|
+
}
|
|
454
|
+
console.log();
|
|
455
|
+
return startupOk;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* 🔧 Extrai user_hash de uma URL existente
|
|
460
|
+
*/
|
|
461
|
+
function extractUserHash(url: string): string {
|
|
462
|
+
const match = url.match(/user_hash=([a-zA-Z0-9]+)/);
|
|
463
|
+
return match ? match[1] : "";
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* 🔧 Cria ou atualiza o arquivo .vscode/mcp.json preservando hashes existentes
|
|
468
|
+
*/
|
|
469
|
+
async function ensureMcpConfig(): Promise<void> {
|
|
470
|
+
console.log("🔧 ======================================================");
|
|
471
|
+
console.log("🔧 Configurando MCP (Model Context Protocol)");
|
|
472
|
+
console.log("🔧 ======================================================");
|
|
473
|
+
console.log();
|
|
474
|
+
|
|
475
|
+
try {
|
|
476
|
+
const consumerProjectRoot = process.cwd();
|
|
477
|
+
const vscodeDir = path.join(consumerProjectRoot, ".vscode");
|
|
478
|
+
const mcpFile = path.join(vscodeDir, "mcp.json");
|
|
479
|
+
|
|
480
|
+
// Criar a pasta .vscode se não existir
|
|
481
|
+
if (!fs.existsSync(vscodeDir)) {
|
|
482
|
+
fs.mkdirSync(vscodeDir, { recursive: true });
|
|
483
|
+
console.log(`📁 Pasta .vscode criada em: ${vscodeDir}`);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// Configuração padrão (hashes vazios)
|
|
487
|
+
const defaultConfig = {
|
|
488
|
+
servers: {
|
|
489
|
+
"mcp-estimative": {
|
|
490
|
+
url: "http://brtlvlty0559pl:8080/estimative/mcp?user_hash=",
|
|
491
|
+
type: "http",
|
|
492
|
+
},
|
|
493
|
+
"autocore-orchestrator": {
|
|
494
|
+
command: "npx",
|
|
495
|
+
args: ["-y", "@silasfmartins/testhub-orchestrator-mcp"],
|
|
496
|
+
env: {
|
|
497
|
+
HUB_BACKEND_URL: "http://brtlvlty0559pl:3333",
|
|
498
|
+
},
|
|
499
|
+
type: "stdio",
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
inputs: [],
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
if (fs.existsSync(mcpFile)) {
|
|
506
|
+
// Arquivo existe - preservar hashes do usuário
|
|
507
|
+
const currentContent = JSON.parse(fs.readFileSync(mcpFile, "utf8"));
|
|
508
|
+
|
|
509
|
+
// Preservar hash do mcp-estimative
|
|
510
|
+
let existingEstimativeHash = "";
|
|
511
|
+
if (currentContent.servers?.["mcp-estimative"]?.url) {
|
|
512
|
+
existingEstimativeHash = extractUserHash(
|
|
513
|
+
currentContent.servers["mcp-estimative"].url,
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Construir configuração atualizada preservando hashes
|
|
518
|
+
const updatedConfig = {
|
|
519
|
+
servers: {
|
|
520
|
+
"mcp-estimative": {
|
|
521
|
+
url: `http://brtlvlty0559pl:8080/estimative/mcp?user_hash=${existingEstimativeHash}`,
|
|
522
|
+
type: "http",
|
|
523
|
+
},
|
|
524
|
+
"autocore-orchestrator": {
|
|
525
|
+
command: "npx",
|
|
526
|
+
args: ["-y", "@silasfmartins/testhub-orchestrator-mcp"],
|
|
527
|
+
env: {
|
|
528
|
+
HUB_BACKEND_URL: "http://brtlvlty0559pl:3333",
|
|
529
|
+
},
|
|
530
|
+
type: "stdio",
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
inputs: currentContent.inputs || [],
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
fs.writeFileSync(mcpFile, JSON.stringify(updatedConfig, null, 2));
|
|
537
|
+
|
|
538
|
+
if (existingEstimativeHash) {
|
|
539
|
+
console.log(
|
|
540
|
+
"✅ Arquivo mcp.json atualizado (hash mcp-estimative preservado)",
|
|
541
|
+
);
|
|
542
|
+
} else {
|
|
543
|
+
console.log("✅ Arquivo mcp.json atualizado");
|
|
544
|
+
}
|
|
545
|
+
} else {
|
|
546
|
+
// Criar novo arquivo com configuração padrão
|
|
547
|
+
fs.writeFileSync(mcpFile, JSON.stringify(defaultConfig, null, 2));
|
|
548
|
+
console.log("✅ Arquivo mcp.json criado");
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
console.log(` 📍 Local: ${mcpFile}`);
|
|
552
|
+
console.log();
|
|
553
|
+
console.log("🤖 MCP configurado para integração com AutoCore Hub!");
|
|
554
|
+
console.log(
|
|
555
|
+
" 🔹 autocore-orchestrator: Migração, geração de testes, documentação",
|
|
556
|
+
);
|
|
557
|
+
console.log(" 🔹 mcp-estimative: Estimativas de produtividade AI");
|
|
558
|
+
console.log();
|
|
559
|
+
console.log("🔑 Para usar o MCP, configure seu user_hash:");
|
|
560
|
+
console.log(
|
|
561
|
+
" 📌 mcp-estimative: Adicione seu hash na URL em .vscode/mcp.json",
|
|
562
|
+
);
|
|
563
|
+
console.log(" 📌 autocore-orchestrator:");
|
|
564
|
+
console.log(" No Windows: defina a variável de ambiente do usuário");
|
|
565
|
+
console.log(" HUB_MCP_USER_HASH com seu hash e reinicie o VS Code.");
|
|
566
|
+
console.log(" (Painel de Controle > Sistema > Variáveis de Ambiente)");
|
|
567
|
+
} catch (error) {
|
|
568
|
+
console.warn("⚠️ Aviso: Não foi possível configurar mcp.json");
|
|
569
|
+
if (error instanceof Error) {
|
|
570
|
+
console.warn(` Erro: ${error.message}`);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
console.log();
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* ✅ Verificar/Instalar browsers Playwright para projetos consumidores
|
|
579
|
+
*/
|
|
580
|
+
async function ensurePlaywrightForConsumer(): Promise<void> {
|
|
581
|
+
try {
|
|
582
|
+
const cwd = process.cwd();
|
|
583
|
+
const pkgFile = path.join(cwd, "package.json");
|
|
584
|
+
if (!fs.existsSync(pkgFile)) return;
|
|
585
|
+
|
|
586
|
+
const content = fs.readFileSync(pkgFile, "utf8");
|
|
587
|
+
const pkg = JSON.parse(content);
|
|
588
|
+
|
|
589
|
+
const hasPlaywright =
|
|
590
|
+
pkg.dependencies?.["@playwright/test"] ||
|
|
591
|
+
pkg.devDependencies?.["@playwright/test"];
|
|
592
|
+
if (!hasPlaywright) return;
|
|
593
|
+
|
|
594
|
+
// Respect pipeline/test-type overrides: if pipeline requests SSH tests, skip installing browsers
|
|
595
|
+
const pipelineTestType = (
|
|
596
|
+
process.env.FORCE_TEST_TYPE ||
|
|
597
|
+
process.env.TEST_TYPE ||
|
|
598
|
+
process.env.RUN_TEST_TYPE ||
|
|
599
|
+
""
|
|
600
|
+
).toUpperCase();
|
|
601
|
+
if (pipelineTestType === "SSH" || process.env.USE_SSH === "true") {
|
|
602
|
+
console.log(
|
|
603
|
+
"AutoCore Consumer: CI/pipeline indicates SSH tests - skipping Playwright browser installation",
|
|
604
|
+
);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// Only install browsers for Web/Frontend or Scenarios projects
|
|
609
|
+
const projectTypeEnv = (
|
|
610
|
+
process.env.PROJECT_TYPE ||
|
|
611
|
+
process.env.PROJECTTYPE ||
|
|
612
|
+
""
|
|
613
|
+
).toUpperCase();
|
|
614
|
+
const isProjectTypeWebOrScenarios =
|
|
615
|
+
projectTypeEnv === "WEB" ||
|
|
616
|
+
projectTypeEnv === "FRONTEND" ||
|
|
617
|
+
projectTypeEnv === "SCENARIOS";
|
|
618
|
+
|
|
619
|
+
const hasFrontendScripts =
|
|
620
|
+
!!pkg.scripts?.["test:preprod"]?.includes("playwright test") ||
|
|
621
|
+
!!pkg.scripts?.["ui:preprod"] ||
|
|
622
|
+
!!pkg.scripts?.["codegen:preprod"];
|
|
623
|
+
|
|
624
|
+
if (!(isProjectTypeWebOrScenarios || hasFrontendScripts)) {
|
|
625
|
+
console.log(
|
|
626
|
+
"AutoCore Consumer: Projeto não é Web/Cenários — pulando instalação de browsers Playwright",
|
|
627
|
+
);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
const possiblePaths = [
|
|
632
|
+
path.join(cwd, "node_modules", ".cache", "ms-playwright"),
|
|
633
|
+
path.join(cwd, "node_modules", "playwright-core", ".local-browsers"),
|
|
634
|
+
path.join(cwd, "node_modules", "playwright", ".local-browsers"),
|
|
635
|
+
];
|
|
636
|
+
|
|
637
|
+
const browsersInstalled = possiblePaths.some((p) => fs.existsSync(p));
|
|
638
|
+
if (browsersInstalled) {
|
|
639
|
+
console.log("AutoCore Consumer: Browsers Playwright já instalados ✓");
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
console.log(
|
|
644
|
+
"AutoCore Consumer: Instalando browsers Playwright (via npx)...",
|
|
645
|
+
);
|
|
646
|
+
try {
|
|
647
|
+
console.log(
|
|
648
|
+
" ⚠️ Ajustando NODE_TLS_REJECT_UNAUTHORIZED=0 para evitar erros TLS durante o download",
|
|
649
|
+
);
|
|
650
|
+
await execAsync("npx playwright install --with-deps", {
|
|
651
|
+
timeout: 120000,
|
|
652
|
+
windowsHide: true,
|
|
653
|
+
shell: true,
|
|
654
|
+
env: { ...process.env, NODE_TLS_REJECT_UNAUTHORIZED: "0" },
|
|
655
|
+
});
|
|
656
|
+
console.log("AutoCore Consumer: Browsers Playwright instalados ✓");
|
|
657
|
+
} catch (e) {
|
|
658
|
+
console.warn(
|
|
659
|
+
"AutoCore Consumer: Falha no install --with-deps, tentando fallback...",
|
|
660
|
+
);
|
|
661
|
+
try {
|
|
662
|
+
await execAsync("npx playwright install", {
|
|
663
|
+
timeout: 120000,
|
|
664
|
+
windowsHide: true,
|
|
665
|
+
shell: true,
|
|
666
|
+
env: { ...process.env, NODE_TLS_REJECT_UNAUTHORIZED: "0" },
|
|
667
|
+
});
|
|
668
|
+
console.log("AutoCore Consumer: Browsers Playwright instalados ✓");
|
|
669
|
+
} catch (err) {
|
|
670
|
+
console.warn(
|
|
671
|
+
"AutoCore Consumer: Não foi possível instalar browsers Playwright automaticamente. Rode: npx playwright install",
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
} catch (error) {
|
|
676
|
+
if (process.env.DEBUG_MCP)
|
|
677
|
+
console.warn("Erro ao verificar Playwright consumer:", error);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* 🚀 Função principal do postinstall
|
|
683
|
+
*/
|
|
684
|
+
async function main(): Promise<void> {
|
|
685
|
+
console.log("🎯 ======================================================");
|
|
686
|
+
console.log("🎯 AutoCore Consumer Project Postinstall");
|
|
687
|
+
console.log("🎯 ======================================================");
|
|
688
|
+
console.log();
|
|
689
|
+
|
|
690
|
+
// 1. Verificar se está em ambiente local
|
|
691
|
+
if (!isLocalEnvironment()) {
|
|
692
|
+
console.log("🤖 Ambiente CI/CD ou não-Windows detectado");
|
|
693
|
+
console.log();
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
console.log("🏠 Ambiente local Windows detectado");
|
|
698
|
+
console.log();
|
|
699
|
+
|
|
700
|
+
// 2. Verificar se VS Code está instalado
|
|
701
|
+
const vscodeInstalled = isVSCodeInstalled();
|
|
702
|
+
if (!vscodeInstalled) {
|
|
703
|
+
console.log("⚠️ VS Code não foi encontrado no sistema");
|
|
704
|
+
console.log(
|
|
705
|
+
"💡 Para aproveitar todas as funcionalidades do AutoCore, instale o VS Code:",
|
|
706
|
+
);
|
|
707
|
+
console.log(" https://code.visualstudio.com/");
|
|
708
|
+
console.log();
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
console.log("✅ VS Code encontrado no sistema");
|
|
713
|
+
console.log();
|
|
714
|
+
|
|
715
|
+
// 3. Verificar extensões recomendadas (NÃO instala automaticamente — evita abrir VS Code)
|
|
716
|
+
const missingExtensions: typeof REQUIRED_EXTENSIONS = [];
|
|
717
|
+
|
|
718
|
+
for (const extension of REQUIRED_EXTENSIONS) {
|
|
719
|
+
const isInstalled = isExtensionInstalled(extension.id);
|
|
720
|
+
if (isInstalled) {
|
|
721
|
+
console.log(`✅ ${extension.name}`);
|
|
722
|
+
} else {
|
|
723
|
+
missingExtensions.push(extension);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
console.log();
|
|
728
|
+
|
|
729
|
+
// 4. Resumo final
|
|
730
|
+
console.log("📊 ======================================================");
|
|
731
|
+
console.log("📊 Resumo da Instalação");
|
|
732
|
+
console.log("📊 ======================================================");
|
|
733
|
+
|
|
734
|
+
if (missingExtensions.length === 0) {
|
|
735
|
+
console.log("💡 Seu ambiente AutoCore está pronto para uso!");
|
|
736
|
+
} else {
|
|
737
|
+
console.log(
|
|
738
|
+
`⚠️ ${missingExtensions.length} extensão(ões) recomendada(s) não encontrada(s):`,
|
|
739
|
+
);
|
|
740
|
+
console.log();
|
|
741
|
+
for (const ext of missingExtensions) {
|
|
742
|
+
console.log(` 📦 ${ext.name} — ${ext.description}`);
|
|
743
|
+
console.log(` Instalar: code --install-extension ${ext.id}`);
|
|
744
|
+
}
|
|
745
|
+
console.log();
|
|
746
|
+
console.log("💡 Para instalar todas de uma vez, rode:");
|
|
747
|
+
const installCmd = missingExtensions
|
|
748
|
+
.map((e) => `code --install-extension ${e.id}`)
|
|
749
|
+
.join(" && ");
|
|
750
|
+
console.log(` ${installCmd}`);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
console.log();
|
|
754
|
+
console.log("🔧 Para mais informações sobre configuração do ambiente:");
|
|
755
|
+
console.log(
|
|
756
|
+
" Acesse o site com a VPN ativada: http://brtlvlty0559pl:3002/",
|
|
757
|
+
);
|
|
758
|
+
console.log(" 💬 Suporte: Equipe TestHUB");
|
|
759
|
+
console.log();
|
|
760
|
+
|
|
761
|
+
// 5. Instalar/Atualizar MCP globalmente
|
|
762
|
+
const mcpReady = await installMcpPackageGlobally();
|
|
763
|
+
console.log();
|
|
764
|
+
|
|
765
|
+
// 5.1 Configurar autostart local no logon do Windows
|
|
766
|
+
const autostartReady = await ensureWindowsMcpAutostart();
|
|
767
|
+
if (!mcpReady) {
|
|
768
|
+
console.log(
|
|
769
|
+
"⚠️ Instalação global do MCP não concluída; AutoStart usará npx no login do usuário",
|
|
770
|
+
);
|
|
771
|
+
console.log(
|
|
772
|
+
" 💡 Quando houver VPN/rede disponível, rode o postinstall novamente para atualizar via npm -g",
|
|
773
|
+
);
|
|
774
|
+
console.log();
|
|
775
|
+
}
|
|
776
|
+
if (!autostartReady) {
|
|
777
|
+
console.log("⚠️ AutoStart não pôde ser configurado automaticamente.");
|
|
778
|
+
console.log(
|
|
779
|
+
` 💡 Inicie manualmente em background: wscript.exe "%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\${WINDOWS_MCP_STARTUP_VBS_FILE}"`,
|
|
780
|
+
);
|
|
781
|
+
console.log(
|
|
782
|
+
` 💡 Inicie agora (temporário): ${WINDOWS_MCP_AUTOSTART_START_COMMAND}`,
|
|
783
|
+
);
|
|
784
|
+
console.log();
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// 6. Configurar arquivo .vscode/mcp.json
|
|
788
|
+
await ensureMcpConfig();
|
|
789
|
+
|
|
790
|
+
// 6.5 Verificar/Instalar Playwright para projetos consumidores
|
|
791
|
+
await ensurePlaywrightForConsumer();
|
|
792
|
+
|
|
793
|
+
// 7. Sincronizar configurações do AutoCore (biome.json e tsconfig.json)
|
|
794
|
+
console.log("🔄 ======================================================");
|
|
795
|
+
console.log("🔄 Sincronizando Configurações do AutoCore");
|
|
796
|
+
console.log("🔄 ======================================================");
|
|
797
|
+
console.log();
|
|
798
|
+
|
|
799
|
+
try {
|
|
800
|
+
// Executar sync-configs.ts via npx tsx (evita problemas de import/rootDir)
|
|
801
|
+
const syncConfigsPath = path.join(__dirname, "sync-configs.ts");
|
|
802
|
+
|
|
803
|
+
// 🎯 Tentar executar sync sem depender de pipeline Azure
|
|
804
|
+
// Funciona localmente e em qualquer ambiente
|
|
805
|
+
try {
|
|
806
|
+
await execAsync(`npx tsx "${syncConfigsPath}"`, {
|
|
807
|
+
timeout: 30000,
|
|
808
|
+
windowsHide: true,
|
|
809
|
+
shell: true,
|
|
810
|
+
});
|
|
811
|
+
console.log("✅ Configurações sincronizadas com sucesso!");
|
|
812
|
+
} catch (tsxError) {
|
|
813
|
+
// Fallback: tentar com ts-node se tsx falhar
|
|
814
|
+
try {
|
|
815
|
+
await execAsync(`npx ts-node "${syncConfigsPath}"`, {
|
|
816
|
+
timeout: 30000,
|
|
817
|
+
windowsHide: true,
|
|
818
|
+
shell: true,
|
|
819
|
+
});
|
|
820
|
+
console.log(
|
|
821
|
+
"✅ Configurações sincronizadas com sucesso! (via ts-node)",
|
|
822
|
+
);
|
|
823
|
+
} catch {
|
|
824
|
+
// Fallback final: tentar versão compilada JS
|
|
825
|
+
const syncConfigsJsPath = syncConfigsPath.replace(".ts", ".js");
|
|
826
|
+
if (fs.existsSync(syncConfigsJsPath)) {
|
|
827
|
+
await execAsync(`node "${syncConfigsJsPath}"`, {
|
|
828
|
+
timeout: 30000,
|
|
829
|
+
windowsHide: true,
|
|
830
|
+
shell: true,
|
|
831
|
+
});
|
|
832
|
+
console.log("✅ Configurações sincronizadas com sucesso! (via JS)");
|
|
833
|
+
} else {
|
|
834
|
+
throw tsxError;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
} catch (error) {
|
|
839
|
+
console.warn(
|
|
840
|
+
"⚠️ Aviso: Não foi possível sincronizar configurações automaticamente",
|
|
841
|
+
);
|
|
842
|
+
console.warn(
|
|
843
|
+
" 💡 Você pode sincronizá-las manualmente executando: npm run sync",
|
|
844
|
+
);
|
|
845
|
+
if (error instanceof Error && !error.message.includes("timeout")) {
|
|
846
|
+
console.warn(` Erro: ${error.message}`);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
console.log();
|
|
851
|
+
|
|
852
|
+
// 8. Sincronizar GitHub Copilot Instructions
|
|
853
|
+
await syncCopilotInstructions();
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* 🤖 Sincroniza o arquivo copilot-instructions.md para o projeto consumidor
|
|
858
|
+
* Garante que o GitHub Copilot entenda os padrões do AutoCore/TestHub
|
|
859
|
+
*/
|
|
860
|
+
async function syncCopilotInstructions(): Promise<void> {
|
|
861
|
+
console.log("🤖 ======================================================");
|
|
862
|
+
console.log("🤖 Sincronizando GitHub Copilot Instructions");
|
|
863
|
+
console.log("🤖 ======================================================");
|
|
864
|
+
console.log();
|
|
865
|
+
|
|
866
|
+
try {
|
|
867
|
+
// Caminho do arquivo fonte no AutoCore
|
|
868
|
+
// Se estiver em dist/scripts, subir dois níveis; senão, um nível
|
|
869
|
+
const isDist = __dirname.includes("dist");
|
|
870
|
+
const levelsUp = isDist ? "../.." : "..";
|
|
871
|
+
const sourceFile = path.join(
|
|
872
|
+
__dirname,
|
|
873
|
+
levelsUp,
|
|
874
|
+
".github",
|
|
875
|
+
"copilot-instructions.md",
|
|
876
|
+
);
|
|
877
|
+
|
|
878
|
+
// Caminho do projeto consumidor (onde o npm install foi executado)
|
|
879
|
+
const consumerProjectRoot = process.cwd();
|
|
880
|
+
const targetDir = path.join(consumerProjectRoot, ".github");
|
|
881
|
+
const targetFile = path.join(targetDir, "copilot-instructions.md");
|
|
882
|
+
|
|
883
|
+
console.log(`📂 Caminho fonte: ${sourceFile}`);
|
|
884
|
+
console.log(`📂 Caminho destino: ${targetFile}`);
|
|
885
|
+
console.log();
|
|
886
|
+
|
|
887
|
+
// Verificar se o arquivo fonte existe
|
|
888
|
+
if (!fs.existsSync(sourceFile)) {
|
|
889
|
+
console.warn(
|
|
890
|
+
"⚠️ Arquivo copilot-instructions.md não encontrado no AutoCore",
|
|
891
|
+
);
|
|
892
|
+
console.warn(` Caminho esperado: ${sourceFile}`);
|
|
893
|
+
console.warn(` __dirname: ${__dirname}`);
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Criar a pasta .github se não existir
|
|
898
|
+
if (!fs.existsSync(targetDir)) {
|
|
899
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
900
|
+
console.log(`📁 Pasta .github criada em: ${targetDir}`);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// Ler o conteúdo do arquivo fonte
|
|
904
|
+
const sourceContent = fs.readFileSync(sourceFile, "utf-8");
|
|
905
|
+
|
|
906
|
+
// Verificar se o arquivo já existe no destino
|
|
907
|
+
let shouldUpdate = true;
|
|
908
|
+
if (fs.existsSync(targetFile)) {
|
|
909
|
+
const targetContent = fs.readFileSync(targetFile, "utf-8");
|
|
910
|
+
|
|
911
|
+
// Comparar conteúdos
|
|
912
|
+
if (sourceContent === targetContent) {
|
|
913
|
+
console.log("✅ copilot-instructions.md já está atualizado");
|
|
914
|
+
shouldUpdate = false;
|
|
915
|
+
} else {
|
|
916
|
+
console.log(
|
|
917
|
+
"🔄 Atualizando copilot-instructions.md (nova versão disponível)",
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
} else {
|
|
921
|
+
console.log("📝 Criando copilot-instructions.md no projeto");
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// Copiar/Atualizar o arquivo se necessário
|
|
925
|
+
if (shouldUpdate) {
|
|
926
|
+
// Adicionar cabeçalho informando que é gerado automaticamente
|
|
927
|
+
const headerComment = `<!--
|
|
928
|
+
🤖 ARQUIVO GERADO AUTOMATICAMENTE PELO AUTOCORE
|
|
929
|
+
⚠️ NÃO EDITE MANUALMENTE - Será sobrescrito no próximo npm install
|
|
930
|
+
📅 Última atualização: ${new Date().toISOString()}
|
|
931
|
+
📦 Fonte: @silasfmartins/testhub
|
|
932
|
+
-->
|
|
933
|
+
|
|
934
|
+
`;
|
|
935
|
+
const finalContent = headerComment + sourceContent;
|
|
936
|
+
|
|
937
|
+
fs.writeFileSync(targetFile, finalContent, "utf-8");
|
|
938
|
+
console.log("✅ copilot-instructions.md sincronizado com sucesso!");
|
|
939
|
+
console.log(` 📍 Destino: ${targetFile}`);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
console.log();
|
|
943
|
+
console.log(
|
|
944
|
+
"💡 O GitHub Copilot agora entende os padrões do AutoCore/TestHub!",
|
|
945
|
+
);
|
|
946
|
+
console.log(" 🔹 Migração Java → TypeScript");
|
|
947
|
+
console.log(" 🔹 Geração de testes automatizados");
|
|
948
|
+
console.log(" 🔹 Padrões de Page Objects, Fixtures e Statements");
|
|
949
|
+
console.log(
|
|
950
|
+
" 🔹 Uso correto de TestHubVars, DataStore, WebActions, ApiActions, SSHActions",
|
|
951
|
+
);
|
|
952
|
+
} catch (error) {
|
|
953
|
+
console.warn(
|
|
954
|
+
"⚠️ Aviso: Não foi possível sincronizar copilot-instructions.md",
|
|
955
|
+
);
|
|
956
|
+
if (error instanceof Error) {
|
|
957
|
+
console.warn(` Erro: ${error.message}`);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
console.log();
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// Executar main() sempre que chamado diretamente via tsx/node
|
|
965
|
+
const isMainModule =
|
|
966
|
+
process.argv[1]?.endsWith("consumer-postinstall.ts") ||
|
|
967
|
+
process.argv[1]?.endsWith("consumer-postinstall.js");
|
|
968
|
+
if (isMainModule) {
|
|
969
|
+
main().catch((error) => {
|
|
970
|
+
console.error("💥 Erro durante o postinstall:", error);
|
|
971
|
+
process.exit(1);
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
export { main as consumerPostinstall };
|