@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.
Files changed (296) hide show
  1. package/.github/copilot-instructions.md +520 -0
  2. package/biome.json +37 -0
  3. package/dist/index.d.ts +45 -0
  4. package/dist/index.js +169 -0
  5. package/dist/scripts/consumer-postinstall.d.ts +15 -0
  6. package/dist/scripts/consumer-postinstall.js +785 -0
  7. package/dist/scripts/generate-docs.d.ts +16 -0
  8. package/dist/scripts/generate-docs.js +1363 -0
  9. package/dist/scripts/generate-index.d.ts +2 -0
  10. package/dist/scripts/generate-index.js +314 -0
  11. package/dist/scripts/init-api.d.ts +2 -0
  12. package/dist/scripts/init-api.js +525 -0
  13. package/dist/scripts/init-banco.d.ts +2 -0
  14. package/dist/scripts/init-banco.js +347 -0
  15. package/dist/scripts/init-frontend.d.ts +2 -0
  16. package/dist/scripts/init-frontend.js +627 -0
  17. package/dist/scripts/init-mobile.d.ts +2 -0
  18. package/dist/scripts/init-mobile.js +481 -0
  19. package/dist/scripts/init-scenarios.d.ts +2 -0
  20. package/dist/scripts/init-scenarios.js +846 -0
  21. package/dist/scripts/init-ssh.d.ts +2 -0
  22. package/dist/scripts/init-ssh.js +639 -0
  23. package/dist/scripts/package-versions.d.ts +57 -0
  24. package/dist/scripts/package-versions.js +768 -0
  25. package/dist/scripts/postinstall.d.ts +1 -0
  26. package/dist/scripts/postinstall.js +527 -0
  27. package/dist/scripts/robust-build.d.ts +7 -0
  28. package/dist/scripts/robust-build.js +88 -0
  29. package/dist/scripts/setup-local-packages.d.ts +31 -0
  30. package/dist/scripts/setup-local-packages.js +237 -0
  31. package/dist/scripts/smart-override.d.ts +2 -0
  32. package/dist/scripts/smart-override.js +1360 -0
  33. package/dist/scripts/sync-configs.d.ts +27 -0
  34. package/dist/scripts/sync-configs.js +248 -0
  35. package/dist/scripts/test-biome-parse.d.ts +5 -0
  36. package/dist/scripts/test-biome-parse.js +84 -0
  37. package/dist/scripts/ultracite-setup.d.ts +4 -0
  38. package/dist/scripts/ultracite-setup.js +310 -0
  39. package/dist/scripts/update-all-init-scripts.d.ts +2 -0
  40. package/dist/scripts/update-all-init-scripts.js +52 -0
  41. package/dist/scripts/update-biome-schema.d.ts +15 -0
  42. package/dist/scripts/update-biome-schema.js +124 -0
  43. package/dist/src/AutoCoreFacade.d.ts +145 -0
  44. package/dist/src/AutoCoreFacade.js +217 -0
  45. package/dist/src/api/ApiActions.d.ts +297 -0
  46. package/dist/src/api/ApiActions.js +1905 -0
  47. package/dist/src/api/Certificate.d.ts +60 -0
  48. package/dist/src/api/Certificate.js +79 -0
  49. package/dist/src/api/JsonResponse.d.ts +116 -0
  50. package/dist/src/api/JsonResponse.js +206 -0
  51. package/dist/src/appium/DeviceFarmViewer.d.ts +79 -0
  52. package/dist/src/appium/DeviceFarmViewer.js +1083 -0
  53. package/dist/src/appium/MobileActions.d.ts +347 -0
  54. package/dist/src/appium/MobileActions.js +1632 -0
  55. package/dist/src/appium/MobileConnection.d.ts +160 -0
  56. package/dist/src/appium/MobileConnection.js +772 -0
  57. package/dist/src/config/envLoader.d.ts +123 -0
  58. package/dist/src/config/envLoader.js +361 -0
  59. package/dist/src/config/jest-safe-setup.d.ts +19 -0
  60. package/dist/src/config/jest-safe-setup.js +369 -0
  61. package/dist/src/config/timeouts.d.ts +32 -0
  62. package/dist/src/config/timeouts.js +38 -0
  63. package/dist/src/desktop/DesktopActions.d.ts +46 -0
  64. package/dist/src/desktop/DesktopActions.js +398 -0
  65. package/dist/src/desktop/DesktopConnection.d.ts +32 -0
  66. package/dist/src/desktop/DesktopConnection.js +84 -0
  67. package/dist/src/domain/entities/TestExecution.d.ts +117 -0
  68. package/dist/src/domain/entities/TestExecution.js +150 -0
  69. package/dist/src/domain/entities/TestReport.d.ts +114 -0
  70. package/dist/src/domain/entities/TestReport.js +179 -0
  71. package/dist/src/domain/repositories/ITestRepository.d.ts +196 -0
  72. package/dist/src/domain/repositories/ITestRepository.js +14 -0
  73. package/dist/src/domain/schemas/ValidationSchemas.d.ts +159 -0
  74. package/dist/src/domain/schemas/ValidationSchemas.js +181 -0
  75. package/dist/src/functions/errors/BaseError.d.ts +78 -0
  76. package/dist/src/functions/errors/BaseError.js +245 -0
  77. package/dist/src/functions/errors/ConfigurationError.d.ts +16 -0
  78. package/dist/src/functions/errors/ConfigurationError.js +48 -0
  79. package/dist/src/functions/errors/ErrorCatalog.d.ts +148 -0
  80. package/dist/src/functions/errors/ErrorCatalog.js +157 -0
  81. package/dist/src/functions/errors/GlobalErrorHandler.d.ts +101 -0
  82. package/dist/src/functions/errors/GlobalErrorHandler.js +281 -0
  83. package/dist/src/functions/errors/IntegrationError.d.ts +17 -0
  84. package/dist/src/functions/errors/IntegrationError.js +51 -0
  85. package/dist/src/functions/errors/SecurityError.d.ts +14 -0
  86. package/dist/src/functions/errors/SecurityError.js +42 -0
  87. package/dist/src/functions/errors/SystemError.d.ts +12 -0
  88. package/dist/src/functions/errors/SystemError.js +36 -0
  89. package/dist/src/functions/errors/ValidationError.d.ts +14 -0
  90. package/dist/src/functions/errors/ValidationError.js +61 -0
  91. package/dist/src/functions/errors/index.d.ts +12 -0
  92. package/dist/src/functions/errors/index.js +13 -0
  93. package/dist/src/global-setup.d.ts +1 -0
  94. package/dist/src/global-setup.js +1037 -0
  95. package/dist/src/helpers/BancoActions.d.ts +188 -0
  96. package/dist/src/helpers/BancoActions.js +581 -0
  97. package/dist/src/helpers/EnviromentHelper.d.ts +17 -0
  98. package/dist/src/helpers/EnviromentHelper.js +66 -0
  99. package/dist/src/helpers/ParallelExecutionHelper.d.ts +183 -0
  100. package/dist/src/helpers/ParallelExecutionHelper.js +375 -0
  101. package/dist/src/helpers/SyncSignal.d.ts +15 -0
  102. package/dist/src/helpers/SyncSignal.js +44 -0
  103. package/dist/src/hubdocs/CategoryDetector.d.ts +83 -0
  104. package/dist/src/hubdocs/CategoryDetector.js +401 -0
  105. package/dist/src/hubdocs/DirectStatementInterceptor.d.ts +54 -0
  106. package/dist/src/hubdocs/DirectStatementInterceptor.js +243 -0
  107. package/dist/src/hubdocs/ExecutionTracker.d.ts +107 -0
  108. package/dist/src/hubdocs/ExecutionTracker.js +702 -0
  109. package/dist/src/hubdocs/HubDocs.d.ts +395 -0
  110. package/dist/src/hubdocs/HubDocs.js +3586 -0
  111. package/dist/src/hubdocs/StatementMethodFilter.d.ts +71 -0
  112. package/dist/src/hubdocs/StatementMethodFilter.js +618 -0
  113. package/dist/src/hubdocs/StatementTracker.d.ts +417 -0
  114. package/dist/src/hubdocs/StatementTracker.js +2419 -0
  115. package/dist/src/hubdocs/SwaggerGenerator.d.ts +59 -0
  116. package/dist/src/hubdocs/SwaggerGenerator.js +405 -0
  117. package/dist/src/hubdocs/index.d.ts +9 -0
  118. package/dist/src/hubdocs/index.js +9 -0
  119. package/dist/src/hubdocs/types.d.ts +114 -0
  120. package/dist/src/hubdocs/types.js +5 -0
  121. package/dist/src/infrastructure/DependencyContainer.d.ts +142 -0
  122. package/dist/src/infrastructure/DependencyContainer.js +250 -0
  123. package/dist/src/infrastructure/adapters/AppiumAdapter.d.ts +168 -0
  124. package/dist/src/infrastructure/adapters/AppiumAdapter.js +468 -0
  125. package/dist/src/infrastructure/adapters/OracleAdapter.d.ts +150 -0
  126. package/dist/src/infrastructure/adapters/OracleAdapter.js +388 -0
  127. package/dist/src/infrastructure/adapters/PlaywrightAdapter.d.ts +192 -0
  128. package/dist/src/infrastructure/adapters/PlaywrightAdapter.js +382 -0
  129. package/dist/src/infrastructure/adapters/SSHAdapter.d.ts +141 -0
  130. package/dist/src/infrastructure/adapters/SSHAdapter.js +428 -0
  131. package/dist/src/interfaces.d.ts +501 -0
  132. package/dist/src/interfaces.js +25 -0
  133. package/dist/src/internal/fakes/__fake-actions__.d.ts +17 -0
  134. package/dist/src/internal/fakes/__fake-actions__.js +21 -0
  135. package/dist/src/internal/fakes/__forbidden__.d.ts +10 -0
  136. package/dist/src/internal/fakes/__forbidden__.js +18 -0
  137. package/dist/src/internal/fakes/__honeypot__.d.ts +15 -0
  138. package/dist/src/internal/fakes/__honeypot__.js +24 -0
  139. package/dist/src/octane/OctaneReporter.d.ts +13 -0
  140. package/dist/src/octane/OctaneReporter.js +61 -0
  141. package/dist/src/playwright/CryptoActions.d.ts +20 -0
  142. package/dist/src/playwright/CryptoActions.js +75 -0
  143. package/dist/src/playwright/EnhancedWebActions.d.ts +7 -0
  144. package/dist/src/playwright/EnhancedWebActions.js +65 -0
  145. package/dist/src/playwright/WebActions.d.ts +1599 -0
  146. package/dist/src/playwright/WebActions.js +11788 -0
  147. package/dist/src/playwright/actions/ActionTimeline.d.ts +36 -0
  148. package/dist/src/playwright/actions/ActionTimeline.js +101 -0
  149. package/dist/src/playwright/actions/RecoveryQueue.d.ts +82 -0
  150. package/dist/src/playwright/actions/RecoveryQueue.js +130 -0
  151. package/dist/src/playwright/actions/SelectorCache.d.ts +53 -0
  152. package/dist/src/playwright/actions/SelectorCache.js +96 -0
  153. package/dist/src/playwright/actions/index.d.ts +13 -0
  154. package/dist/src/playwright/actions/index.js +14 -0
  155. package/dist/src/playwright/actions/types.d.ts +147 -0
  156. package/dist/src/playwright/actions/types.js +5 -0
  157. package/dist/src/playwright/fixtures.d.ts +112 -0
  158. package/dist/src/playwright/fixtures.js +718 -0
  159. package/dist/src/playwright/network-logs-reporter.d.ts +7 -0
  160. package/dist/src/playwright/network-logs-reporter.js +66 -0
  161. package/dist/src/playwright/registerRecoveryWrappers.d.ts +1 -0
  162. package/dist/src/playwright/registerRecoveryWrappers.js +54 -0
  163. package/dist/src/security/BuildSecurity.d.ts +12 -0
  164. package/dist/src/security/BuildSecurity.js +138 -0
  165. package/dist/src/security/EulaProtection.d.ts +70 -0
  166. package/dist/src/security/EulaProtection.js +155 -0
  167. package/dist/src/security/HoneypotManager.d.ts +46 -0
  168. package/dist/src/security/HoneypotManager.js +234 -0
  169. package/dist/src/security/KeysManager.d.ts +36 -0
  170. package/dist/src/security/KeysManager.js +158 -0
  171. package/dist/src/security/ProofOfWorkIntegration.d.ts +64 -0
  172. package/dist/src/security/ProofOfWorkIntegration.js +206 -0
  173. package/dist/src/security/SecurityValidation.d.ts +21 -0
  174. package/dist/src/security/SecurityValidation.js +163 -0
  175. package/dist/src/security/SourceMapProtection.d.ts +55 -0
  176. package/dist/src/security/SourceMapProtection.js +220 -0
  177. package/dist/src/security/protector.d.ts +1 -0
  178. package/dist/src/security/protector.js +97 -0
  179. package/dist/src/ssh/SSHActions.d.ts +262 -0
  180. package/dist/src/ssh/SSHActions.js +790 -0
  181. package/dist/src/ssh/SSHClient.d.ts +99 -0
  182. package/dist/src/ssh/SSHClient.js +409 -0
  183. package/dist/src/statements/BaseStatement.d.ts +38 -0
  184. package/dist/src/statements/BaseStatement.js +78 -0
  185. package/dist/src/testContext/AuthStateManager.d.ts +93 -0
  186. package/dist/src/testContext/AuthStateManager.js +256 -0
  187. package/dist/src/testContext/CoverageManager.d.ts +198 -0
  188. package/dist/src/testContext/CoverageManager.js +917 -0
  189. package/dist/src/testContext/TestAnnotations.d.ts +476 -0
  190. package/dist/src/testContext/TestAnnotations.js +2647 -0
  191. package/dist/src/testContext/TestContext.d.ts +138 -0
  192. package/dist/src/testContext/TestContext.js +369 -0
  193. package/dist/src/testContext/UnifiedHtmlGenerator.d.ts +7 -0
  194. package/dist/src/testContext/UnifiedHtmlGenerator.js +264 -0
  195. package/dist/src/testContext/UnifiedReportManager.d.ts +211 -0
  196. package/dist/src/testContext/UnifiedReportManager.js +1206 -0
  197. package/dist/src/testhub/DynamicConfigManager.d.ts +121 -0
  198. package/dist/src/testhub/DynamicConfigManager.js +320 -0
  199. package/dist/src/testhub/SystemsManager.d.ts +119 -0
  200. package/dist/src/testhub/SystemsManager.js +365 -0
  201. package/dist/src/testhub/TestHubClient.d.ts +335 -0
  202. package/dist/src/testhub/TestHubClient.js +1215 -0
  203. package/dist/src/testhub/TestHubReporter.d.ts +62 -0
  204. package/dist/src/testhub/TestHubReporter.js +576 -0
  205. package/dist/src/testhub/TestHubVars.d.ts +116 -0
  206. package/dist/src/testhub/TestHubVars.js +273 -0
  207. package/dist/src/utils/ActionInterceptor.d.ts +59 -0
  208. package/dist/src/utils/ActionInterceptor.js +741 -0
  209. package/dist/src/utils/ArtifactsCompressor.d.ts +43 -0
  210. package/dist/src/utils/ArtifactsCompressor.js +181 -0
  211. package/dist/src/utils/AutoLogsFinal.d.ts +47 -0
  212. package/dist/src/utils/AutoLogsFinal.js +148 -0
  213. package/dist/src/utils/CodeGenSession.d.ts +114 -0
  214. package/dist/src/utils/CodeGenSession.js +264 -0
  215. package/dist/src/utils/ConfigLogger.d.ts +133 -0
  216. package/dist/src/utils/ConfigLogger.js +611 -0
  217. package/dist/src/utils/CustomReporter.d.ts +22 -0
  218. package/dist/src/utils/CustomReporter.js +352 -0
  219. package/dist/src/utils/DataStore.d.ts +171 -0
  220. package/dist/src/utils/DataStore.js +484 -0
  221. package/dist/src/utils/DatabaseInterceptor.d.ts +19 -0
  222. package/dist/src/utils/DatabaseInterceptor.js +295 -0
  223. package/dist/src/utils/DateHelper.d.ts +16 -0
  224. package/dist/src/utils/DateHelper.js +120 -0
  225. package/dist/src/utils/DateValidator.d.ts +4 -0
  226. package/dist/src/utils/DateValidator.js +51 -0
  227. package/dist/src/utils/DocumentGenerator.d.ts +35 -0
  228. package/dist/src/utils/DocumentGenerator.js +129 -0
  229. package/dist/src/utils/EvidenceCapture.d.ts +90 -0
  230. package/dist/src/utils/EvidenceCapture.js +600 -0
  231. package/dist/src/utils/EvidenceReportGenerator.d.ts +70 -0
  232. package/dist/src/utils/EvidenceReportGenerator.js +799 -0
  233. package/dist/src/utils/FrameManagementUtil.d.ts +42 -0
  234. package/dist/src/utils/FrameManagementUtil.js +75 -0
  235. package/dist/src/utils/GlobalStatementsInterceptor.d.ts +1 -0
  236. package/dist/src/utils/GlobalStatementsInterceptor.js +1 -0
  237. package/dist/src/utils/HTMLTemplate.d.ts +1 -0
  238. package/dist/src/utils/HTMLTemplate.js +1034 -0
  239. package/dist/src/utils/InterceptacaoMagica.d.ts +23 -0
  240. package/dist/src/utils/InterceptacaoMagica.js +365 -0
  241. package/dist/src/utils/LogSanitizer.d.ts +35 -0
  242. package/dist/src/utils/LogSanitizer.js +110 -0
  243. package/dist/src/utils/Logger.d.ts +65 -0
  244. package/dist/src/utils/Logger.js +284 -0
  245. package/dist/src/utils/McpLocalClient.d.ts +141 -0
  246. package/dist/src/utils/McpLocalClient.js +871 -0
  247. package/dist/src/utils/PDFEvidenceGenerator.d.ts +20 -0
  248. package/dist/src/utils/PDFEvidenceGenerator.js +156 -0
  249. package/dist/src/utils/SpecFileAnalyzer.d.ts +35 -0
  250. package/dist/src/utils/SpecFileAnalyzer.js +209 -0
  251. package/dist/src/utils/StatementInterceptor.d.ts +18 -0
  252. package/dist/src/utils/StatementInterceptor.js +87 -0
  253. package/dist/src/utils/StatementLogger.d.ts +33 -0
  254. package/dist/src/utils/StatementLogger.js +113 -0
  255. package/dist/src/utils/StatementsInterceptor.d.ts +1 -0
  256. package/dist/src/utils/StatementsInterceptor.js +1 -0
  257. package/dist/src/utils/TeamsFlushHook.d.ts +17 -0
  258. package/dist/src/utils/TeamsFlushHook.js +168 -0
  259. package/dist/src/utils/TerminalLogCapture.d.ts +158 -0
  260. package/dist/src/utils/TerminalLogCapture.js +531 -0
  261. package/dist/src/utils/TestMethodLogger.d.ts +70 -0
  262. package/dist/src/utils/TestMethodLogger.js +95 -0
  263. package/dist/src/utils/UnifiedTeardown.d.ts +4 -0
  264. package/dist/src/utils/UnifiedTeardown.js +400 -0
  265. package/dist/src/utils/XPathCatalog.d.ts +152 -0
  266. package/dist/src/utils/XPathCatalog.js +350 -0
  267. package/dist/src/utils/generators.d.ts +90 -0
  268. package/dist/src/utils/generators.js +167 -0
  269. package/dist/src/utils/testRecovery/ResilientPlaywright.d.ts +152 -0
  270. package/dist/src/utils/testRecovery/ResilientPlaywright.js +715 -0
  271. package/dist/src/utils/testRecovery/TestRecoveryClient.d.ts +801 -0
  272. package/dist/src/utils/testRecovery/TestRecoveryClient.js +1415 -0
  273. package/dist/src/utils/testRecovery/autoFixCode.d.ts +65 -0
  274. package/dist/src/utils/testRecovery/autoFixCode.js +32 -0
  275. package/dist/vitest.config.d.ts +2 -0
  276. package/dist/vitest.config.js +59 -0
  277. package/dist/wdio.conf.d.ts +1 -0
  278. package/dist/wdio.conf.js +420 -0
  279. package/package.json +137 -0
  280. package/protect-loader.mjs +643 -0
  281. package/scripts/consumer-postinstall.ts +975 -0
  282. package/scripts/generate-index.ts +343 -0
  283. package/scripts/init-api.ts +613 -0
  284. package/scripts/init-banco.ts +437 -0
  285. package/scripts/init-frontend.ts +727 -0
  286. package/scripts/init-mobile.ts +558 -0
  287. package/scripts/init-scenarios.ts +925 -0
  288. package/scripts/init-ssh.ts +734 -0
  289. package/scripts/package-versions.ts +978 -0
  290. package/scripts/postinstall.ts +605 -0
  291. package/scripts/smart-override.ts +1675 -0
  292. package/scripts/sync-configs.ts +302 -0
  293. package/scripts/ultracite-setup.ts +370 -0
  294. package/src/types/globals.d.ts +48 -0
  295. package/tsconfig.json +29 -0
  296. 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 };