@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,702 @@
1
+ /**
2
+ * 🔍 ExecutionTracker - Interceptador Principal
3
+ * @silasfmartins/testhub - Auto Documentation System
4
+ */
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { createRequire } from 'module';
8
+ const require = createRequire(import.meta.url);
9
+ export class ExecutionTracker {
10
+ // 🛡️ CRITICAL: Proteção contra recursão infinita
11
+ static isExecutingInternal = false;
12
+ /**
13
+ * 🔗 HOOK: Notificar StatementTracker sobre ações executadas
14
+ */
15
+ static notifyStatementTracker(actionType, description, success, duration) {
16
+ try {
17
+ // Import dinâmico para evitar dependência circular
18
+ const { StatementTracker } = require('./StatementTracker.js');
19
+ StatementTracker.recordAction(actionType, description, success, duration);
20
+ }
21
+ catch (error) {
22
+ // Silencioso - StatementTracker pode não estar disponível
23
+ }
24
+ }
25
+ /**
26
+ * ✅ NOVO: Obter versão atual do AutoCore (com proteção contra recursão)
27
+ */
28
+ static getAutoCoreVersion() {
29
+ // 🛡️ Evita recursão infinita durante interceptação
30
+ if (ExecutionTracker.isExecutingInternal) {
31
+ return '1.1.X'; // Fallback seguro
32
+ }
33
+ ExecutionTracker.isExecutingInternal = true;
34
+ try {
35
+ const packageJsonPath = path.resolve(process.cwd(), 'package.json');
36
+ if (fs.existsSync(packageJsonPath)) {
37
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
38
+ return (packageJson.dependencies?.['@silasfmartins/testhub'] ||
39
+ packageJson.devDependencies?.['@silasfmartins/testhub'] ||
40
+ '1.1.X');
41
+ }
42
+ }
43
+ catch (error) {
44
+ console.warn(`⚠️ Erro ao ler versão do AutoCore: ${error}`);
45
+ }
46
+ finally {
47
+ ExecutionTracker.isExecutingInternal = false;
48
+ }
49
+ return '1.1.X';
50
+ }
51
+ static data = {
52
+ apis: [],
53
+ ssh: [],
54
+ db: [],
55
+ ui: [],
56
+ mobile: [],
57
+ metadata: {
58
+ startTime: new Date().toISOString(),
59
+ endTime: '',
60
+ environment: process.env.NODE_ENV || 'development',
61
+ totalTests: 0,
62
+ passedTests: 0,
63
+ failedTests: 0,
64
+ framework: 'TestHub',
65
+ version: '1.1.X', // ✅ FIXO INICIALMENTE - será atualizado no initialize()
66
+ projectName: 'TestHub Project',
67
+ projectType: 'Mixed',
68
+ duration: 0,
69
+ },
70
+ };
71
+ static config = {
72
+ enabled: true,
73
+ categories: ['api', 'ssh', 'db', 'ui', 'mobile'],
74
+ outputDir: './docs',
75
+ includeRequestBody: true,
76
+ includeResponseBody: true,
77
+ generateSwagger: true,
78
+ includeScreenshots: false,
79
+ maxRequestSize: 10_000, // 10KB
80
+ maxResponseSize: 50_000, // 50KB
81
+ };
82
+ static tempDir = path.resolve(process.cwd(), '.rbqa');
83
+ static dataFile = path.join(this.tempDir, 'execution-data.json');
84
+ /**
85
+ * ✅ Inicializar o tracker
86
+ */
87
+ static initialize(projectName, projectType) {
88
+ // ✅ ATUALIZAR: Versão dinâmica sempre
89
+ ExecutionTracker.data.metadata.version =
90
+ ExecutionTracker.getAutoCoreVersion();
91
+ // ✅ NOVA: Detecção inteligente do nome do projeto
92
+ const detectedProjectName = projectName ||
93
+ process.env.npm_package_name ||
94
+ ExecutionTracker.detectProjectNameFromPath() ||
95
+ 'AutoCore Project';
96
+ // ✅ NOVA: Detecção inteligente do tipo de projeto
97
+ const detectedProjectType = projectType || ExecutionTracker.detectProjectType() || 'API';
98
+ ExecutionTracker.data.metadata.projectName = detectedProjectName;
99
+ ExecutionTracker.data.metadata.projectType = detectedProjectType;
100
+ ExecutionTracker.data.metadata.startTime = new Date().toISOString();
101
+ // Criar diretório temporário
102
+ if (!fs.existsSync(ExecutionTracker.tempDir)) {
103
+ fs.mkdirSync(ExecutionTracker.tempDir, { recursive: true });
104
+ }
105
+ }
106
+ /**
107
+ * ✅ NOVO: Detectar nome do projeto a partir do caminho
108
+ */
109
+ static detectProjectNameFromPath() {
110
+ try {
111
+ const cwd = process.cwd();
112
+ const projectName = path.basename(cwd);
113
+ // Se contém indicadores de projeto de teste API
114
+ if (projectName.includes('test') ||
115
+ projectName.includes('api') ||
116
+ projectName.includes('oss')) {
117
+ return projectName;
118
+ }
119
+ return null;
120
+ }
121
+ catch {
122
+ return null;
123
+ }
124
+ }
125
+ /**
126
+ * ✅ NOVO: Detectar tipo de projeto automaticamente
127
+ */
128
+ static detectProjectType() {
129
+ try {
130
+ const cwd = process.cwd();
131
+ const projectName = path.basename(cwd).toLowerCase();
132
+ const packageName = process.env.npm_package_name?.toLowerCase() || '';
133
+ // Verificar indicadores de API
134
+ const apiIndicators = [
135
+ 'api',
136
+ 'test-oss-api',
137
+ 'oss-api',
138
+ 'autocore',
139
+ 'rest',
140
+ 'service',
141
+ ];
142
+ if (apiIndicators.some((indicator) => projectName.includes(indicator) || packageName.includes(indicator))) {
143
+ return 'API';
144
+ }
145
+ // Verificar indicadores Mobile
146
+ const mobileIndicators = ['mobile', 'appium', 'android', 'ios'];
147
+ if (mobileIndicators.some((indicator) => projectName.includes(indicator) || packageName.includes(indicator))) {
148
+ return 'Mobile';
149
+ }
150
+ // Verificar indicadores Frontend
151
+ const frontendIndicators = ['frontend', 'web', 'ui', 'playwright'];
152
+ if (frontendIndicators.some((indicator) => projectName.includes(indicator) || packageName.includes(indicator))) {
153
+ return 'Frontend';
154
+ }
155
+ // Padrão para projetos com "test" no nome
156
+ if (projectName.includes('test') || packageName.includes('test')) {
157
+ return 'API'; // Assumir API como padrão para projetos de teste
158
+ }
159
+ return 'Mixed';
160
+ }
161
+ catch {
162
+ return 'Mixed';
163
+ }
164
+ }
165
+ /**
166
+ * 🌐 Rastrear chamada de API
167
+ */
168
+ static trackAPI(call) {
169
+ // ✅ CRÍTICO: Auto-inicializar se necessário
170
+ if (!fs.existsSync(ExecutionTracker.tempDir)) {
171
+ ExecutionTracker.initialize();
172
+ }
173
+ if (!(ExecutionTracker.config.enabled &&
174
+ ExecutionTracker.config.categories.includes('api')))
175
+ return;
176
+ // Limitar tamanho de payload/response se configurado
177
+ if (call.payload &&
178
+ JSON.stringify(call.payload).length >
179
+ ExecutionTracker.config.maxRequestSize) {
180
+ call.payload = {
181
+ __truncated: true,
182
+ size: JSON.stringify(call.payload).length,
183
+ };
184
+ }
185
+ if (call.response &&
186
+ JSON.stringify(call.response).length >
187
+ ExecutionTracker.config.maxResponseSize) {
188
+ call.response = {
189
+ __truncated: true,
190
+ size: JSON.stringify(call.response).length,
191
+ };
192
+ }
193
+ ExecutionTracker.data.apis.push(call);
194
+ ExecutionTracker.saveToFile();
195
+ // 🔗 HOOK: Notificar StatementTracker
196
+ ExecutionTracker.notifyStatementTracker('API', `${call.method} ${call.url}`, call.success, call.duration);
197
+ }
198
+ /**
199
+ * 🔄 Atualizar resultado de API específica
200
+ */
201
+ static updateAPIResult(docId, response, statusCode, error) {
202
+ if (!(ExecutionTracker.config.enabled &&
203
+ ExecutionTracker.config.categories.includes('api')))
204
+ return;
205
+ try {
206
+ // Encontrar a API pelo ID
207
+ const apiIndex = ExecutionTracker.data.apis.findIndex((api) => api.id === docId);
208
+ if (apiIndex !== -1) {
209
+ // Atualizar dados da API
210
+ ExecutionTracker.data.apis[apiIndex].success =
211
+ !error && statusCode !== undefined && statusCode < 400;
212
+ ExecutionTracker.data.apis[apiIndex].statusCode =
213
+ statusCode || (error ? 500 : 200);
214
+ ExecutionTracker.data.apis[apiIndex].error = error
215
+ ? String(error)
216
+ : null;
217
+ // Adicionar response se fornecido
218
+ if (response) {
219
+ ExecutionTracker.data.apis[apiIndex].response = response;
220
+ }
221
+ // Calcular duração se possível
222
+ const startTime = new Date(ExecutionTracker.data.apis[apiIndex].timestamp).getTime();
223
+ ExecutionTracker.data.apis[apiIndex].duration = Date.now() - startTime;
224
+ ExecutionTracker.saveToFile();
225
+ }
226
+ else {
227
+ console.warn(`📚 ExecutionTracker: API com ID ${docId} não encontrada para atualização`);
228
+ }
229
+ }
230
+ catch (error) {
231
+ console.error(`❌ ExecutionTracker.updateAPIResult erro crítico: ${error}`);
232
+ // ✅ NOVO: Mesmo com erro, tentar salvar o que já existe
233
+ try {
234
+ ExecutionTracker.saveToFile();
235
+ }
236
+ catch (saveError) {
237
+ console.error(`❌ ExecutionTracker: Falha crítica ao salvar após erro: ${saveError}`);
238
+ }
239
+ }
240
+ }
241
+ /**
242
+ * 🖥️ Rastrear comando SSH
243
+ */
244
+ static trackSSH(command) {
245
+ if (!(ExecutionTracker.config.enabled &&
246
+ ExecutionTracker.config.categories.includes('ssh')))
247
+ return;
248
+ ExecutionTracker.data.ssh.push(command);
249
+ ExecutionTracker.saveToFile();
250
+ // 🔗 HOOK: Notificar StatementTracker
251
+ ExecutionTracker.notifyStatementTracker('SSH', command.command, command.success, command.duration);
252
+ }
253
+ /**
254
+ * 🔄 Atualizar resultado de comando SSH específico
255
+ */
256
+ static updateSSHResult(command, timestamp, success, duration, exitCode, error) {
257
+ if (!(ExecutionTracker.config.enabled &&
258
+ ExecutionTracker.config.categories.includes('ssh')))
259
+ return;
260
+ try {
261
+ // Encontrar o comando SSH pelo command e timestamp (mais preciso)
262
+ const sshIndex = ExecutionTracker.data.ssh.findIndex((ssh) => ssh.command === command &&
263
+ Math.abs(new Date(ssh.timestamp).getTime() - new Date(timestamp).getTime()) < 5000);
264
+ if (sshIndex !== -1) {
265
+ // Atualizar dados do comando SSH
266
+ ExecutionTracker.data.ssh[sshIndex].success = success;
267
+ ExecutionTracker.data.ssh[sshIndex].duration = duration;
268
+ ExecutionTracker.data.ssh[sshIndex].error = error || undefined;
269
+ // Atualizar exitCode se fornecido
270
+ if (exitCode !== undefined) {
271
+ ExecutionTracker.data.ssh[sshIndex].exitCode = exitCode;
272
+ }
273
+ ExecutionTracker.saveToFile();
274
+ }
275
+ else {
276
+ console.warn('📊 ExecutionTracker: Comando SSH não encontrado para atualização');
277
+ }
278
+ }
279
+ catch (error) {
280
+ console.error(`❌ ExecutionTracker.updateSSHResult erro crítico: ${error}`);
281
+ try {
282
+ ExecutionTracker.saveToFile();
283
+ }
284
+ catch (saveError) {
285
+ console.error(`❌ ExecutionTracker: Falha crítica ao salvar após erro: ${saveError}`);
286
+ }
287
+ }
288
+ }
289
+ /**
290
+ * 🗄️ Rastrear query de banco
291
+ */
292
+ static trackDB(query) {
293
+ if (!(ExecutionTracker.config.enabled &&
294
+ ExecutionTracker.config.categories.includes('db')))
295
+ return;
296
+ ExecutionTracker.data.db.push(query);
297
+ ExecutionTracker.saveToFile();
298
+ // 🔗 HOOK: Notificar StatementTracker
299
+ ExecutionTracker.notifyStatementTracker('DB', query.query.substring(0, 50) + '...', query.success, query.duration);
300
+ }
301
+ /**
302
+ * 🔄 Atualizar resultado de query de banco específica
303
+ */
304
+ static updateDBResult(query, timestamp, success, duration, error, resultCount) {
305
+ if (!(ExecutionTracker.config.enabled &&
306
+ ExecutionTracker.config.categories.includes('db')))
307
+ return;
308
+ try {
309
+ console.log(`🔄 [ExecutionTracker] Tentando atualizar query: ${query.substring(0, 50)}... (success: ${success})`);
310
+ // Encontrar a query pelo SQL e timestamp (mais preciso)
311
+ const dbIndex = ExecutionTracker.data.db.findIndex((db) => db.query === query &&
312
+ Math.abs(new Date(db.timestamp).getTime() - new Date(timestamp).getTime()) < 5000);
313
+ if (dbIndex !== -1) {
314
+ console.log(`✅ [ExecutionTracker] Query encontrada no índice ${dbIndex}, atualizando...`);
315
+ // Atualizar dados da query
316
+ ExecutionTracker.data.db[dbIndex].success = success;
317
+ ExecutionTracker.data.db[dbIndex].duration = duration;
318
+ ExecutionTracker.data.db[dbIndex].error = error || undefined;
319
+ // Adicionar contagem de resultados se fornecida
320
+ if (resultCount !== undefined) {
321
+ ;
322
+ ExecutionTracker.data.db[dbIndex].resultCount = resultCount;
323
+ console.log(`📊 [ExecutionTracker] Resultados: ${resultCount} registros`);
324
+ }
325
+ ExecutionTracker.saveToFile();
326
+ }
327
+ else {
328
+ console.warn('📊 ExecutionTracker: Query de banco não encontrada para atualização');
329
+ console.warn(`📊 Queries disponíveis: ${ExecutionTracker.data.db.length}`);
330
+ if (ExecutionTracker.data.db.length > 0) {
331
+ console.warn(`📊 Primeira query: ${ExecutionTracker.data.db[0].query.substring(0, 50)}...`);
332
+ console.warn(`📊 Timestamp procurado: ${timestamp}`);
333
+ console.warn(`📊 Timestamp primeira: ${ExecutionTracker.data.db[0].timestamp}`);
334
+ }
335
+ }
336
+ }
337
+ catch (error) {
338
+ console.error(`❌ ExecutionTracker.updateDBResult erro crítico: ${error}`);
339
+ try {
340
+ ExecutionTracker.saveToFile();
341
+ }
342
+ catch (saveError) {
343
+ console.error(`❌ ExecutionTracker: Falha crítica ao salvar após erro: ${saveError}`);
344
+ }
345
+ }
346
+ }
347
+ /**
348
+ * 🎨 Rastrear ação de UI
349
+ */
350
+ static trackUI(action) {
351
+ if (!(ExecutionTracker.config.enabled &&
352
+ ExecutionTracker.config.categories.includes('ui')))
353
+ return;
354
+ ExecutionTracker.data.ui.push(action);
355
+ ExecutionTracker.saveToFile();
356
+ // 🔗 HOOK: Notificar StatementTracker
357
+ ExecutionTracker.notifyStatementTracker('UI', `${action.action} ${action.element || ''}`, action.success, action.duration);
358
+ }
359
+ /**
360
+ * 📱 Rastrear ação mobile
361
+ */
362
+ static trackMobile(action) {
363
+ if (!(ExecutionTracker.config.enabled &&
364
+ ExecutionTracker.config.categories.includes('mobile')))
365
+ return;
366
+ ExecutionTracker.data.mobile.push(action);
367
+ ExecutionTracker.saveToFile();
368
+ // 🔗 HOOK: Notificar StatementTracker
369
+ ExecutionTracker.notifyStatementTracker('MOBILE', `${action.action} ${action.element || ''}`, undefined, undefined);
370
+ }
371
+ /**
372
+ * 📊 Atualizar estatísticas de testes
373
+ */
374
+ static updateTestStats(total, passed, failed) {
375
+ ExecutionTracker.data.metadata.totalTests = total;
376
+ ExecutionTracker.data.metadata.passedTests = passed;
377
+ ExecutionTracker.data.metadata.failedTests = failed;
378
+ ExecutionTracker.saveToFile();
379
+ }
380
+ /**
381
+ * 💾 Salvar dados em arquivo temporário (COM PROTEÇÃO CONTRA PERDA)
382
+ */
383
+ static saveToFile() {
384
+ // 🛡️ CRITICAL: Proteção total contra recursão infinita
385
+ if (ExecutionTracker.isExecutingInternal) {
386
+ return; // Sair silenciosamente se já executando
387
+ }
388
+ try {
389
+ // Marcar como executando para evitar recursão
390
+ ExecutionTracker.isExecutingInternal = true;
391
+ // Garantir que o diretório existe
392
+ if (!fs.existsSync(ExecutionTracker.tempDir)) {
393
+ fs.mkdirSync(ExecutionTracker.tempDir, { recursive: true });
394
+ }
395
+ // ✅ PROTEÇÃO: Verificar se há dados antes de salvar
396
+ const totalItems = ExecutionTracker.data.apis.length +
397
+ ExecutionTracker.data.ssh.length +
398
+ ExecutionTracker.data.db.length +
399
+ ExecutionTracker.data.ui.length +
400
+ ExecutionTracker.data.mobile.length;
401
+ // ✅ CRÍTICO: Se arquivo existe e tem dados, mas memória está vazia, CARREGAR do arquivo
402
+ if (totalItems === 0 && fs.existsSync(ExecutionTracker.dataFile)) {
403
+ const fileData = ExecutionTracker.loadFromFile();
404
+ if (fileData &&
405
+ (fileData.apis.length > 0 ||
406
+ fileData.ssh.length > 0 ||
407
+ fileData.db.length > 0 ||
408
+ fileData.ui.length > 0 ||
409
+ fileData.mobile.length > 0)) {
410
+ ExecutionTracker.data = {
411
+ ...fileData,
412
+ metadata: {
413
+ ...fileData.metadata,
414
+ // Manter metadados atualizados mas preservar dados
415
+ endTime: ExecutionTracker.data.metadata.endTime ||
416
+ fileData.metadata.endTime,
417
+ duration: ExecutionTracker.data.metadata.duration ||
418
+ fileData.metadata.duration,
419
+ },
420
+ };
421
+ }
422
+ }
423
+ // ✅ NOVO: Detectar versão atual do AutoCore (com proteção)
424
+ if (!ExecutionTracker.isExecutingInternal) {
425
+ ExecutionTracker.data.metadata.version =
426
+ ExecutionTracker.getAutoCoreVersion();
427
+ }
428
+ // ✅ MELHORAR: Detectar tipo de projeto baseado nos dados coletados
429
+ if (ExecutionTracker.data.apis.length > 0 &&
430
+ ExecutionTracker.data.ui.length === 0 &&
431
+ ExecutionTracker.data.mobile.length === 0) {
432
+ ExecutionTracker.data.metadata.projectType = 'API';
433
+ }
434
+ else if (ExecutionTracker.data.ui.length > 0 &&
435
+ ExecutionTracker.data.mobile.length === 0) {
436
+ ExecutionTracker.data.metadata.projectType = 'Frontend';
437
+ }
438
+ else if (ExecutionTracker.data.mobile.length > 0) {
439
+ ExecutionTracker.data.metadata.projectType = 'Mobile';
440
+ }
441
+ else if (ExecutionTracker.data.ssh.length > 0) {
442
+ ExecutionTracker.data.metadata.projectType = 'SSH';
443
+ }
444
+ else if (ExecutionTracker.data.db.length > 0) {
445
+ ExecutionTracker.data.metadata.projectType = 'Database';
446
+ }
447
+ else if (ExecutionTracker.data.apis.length > 0 &&
448
+ (ExecutionTracker.data.ui.length > 0 ||
449
+ ExecutionTracker.data.mobile.length > 0 ||
450
+ ExecutionTracker.data.ssh.length > 0 ||
451
+ ExecutionTracker.data.db.length > 0)) {
452
+ ExecutionTracker.data.metadata.projectType = 'Mixed';
453
+ }
454
+ // ✅ NOVO: Atualizar estatísticas em tempo real
455
+ ExecutionTracker.data.metadata.endTime = new Date().toISOString();
456
+ ExecutionTracker.data.metadata.duration =
457
+ new Date().getTime() -
458
+ new Date(ExecutionTracker.data.metadata.startTime).getTime();
459
+ // ✅ PROTEÇÃO MELHORADA: Backup seguro com retry
460
+ const backupFile = ExecutionTracker.dataFile + '.backup';
461
+ let backupSuccess = false;
462
+ // Tentar fazer backup com retry para arquivo ocupado
463
+ if (fs.existsSync(ExecutionTracker.dataFile)) {
464
+ for (let retry = 0; retry < 3; retry++) {
465
+ try {
466
+ // Se backup existe, remover primeiro
467
+ if (fs.existsSync(backupFile)) {
468
+ fs.unlinkSync(backupFile);
469
+ }
470
+ // Fazer backup
471
+ fs.copyFileSync(ExecutionTracker.dataFile, backupFile);
472
+ backupSuccess = true;
473
+ break;
474
+ }
475
+ catch (error) {
476
+ if (error.code === 'EBUSY' && retry < 2) {
477
+ // Esperar um pouco e tentar novamente (sem async/await para evitar problemas)
478
+ const start = Date.now();
479
+ while (Date.now() - start < 100) {
480
+ // Busy wait for 100ms
481
+ }
482
+ continue;
483
+ }
484
+ // Ignorar erros de backup - não é crítico
485
+ break;
486
+ }
487
+ }
488
+ }
489
+ fs.writeFileSync(ExecutionTracker.dataFile, JSON.stringify(ExecutionTracker.data, null, 2));
490
+ // Log de debug detalhado
491
+ const stats = `APIs: ${ExecutionTracker.data.apis.length}, SSH: ${ExecutionTracker.data.ssh.length}, DB: ${ExecutionTracker.data.db.length}, UI: ${ExecutionTracker.data.ui.length}, Mobile: ${ExecutionTracker.data.mobile.length}`;
492
+ // ✅ VERIFICAÇÃO: Confirmar que arquivo foi salvo corretamente
493
+ if (fs.existsSync(ExecutionTracker.dataFile)) {
494
+ const savedSize = fs.statSync(ExecutionTracker.dataFile).size;
495
+ if (savedSize > 10) {
496
+ // Arquivo deve ter pelo menos estrutura mínima
497
+ // Remover backup após confirmação
498
+ if (fs.existsSync(backupFile)) {
499
+ fs.unlinkSync(backupFile);
500
+ }
501
+ }
502
+ else {
503
+ console.warn(`⚠️ ExecutionTracker: Arquivo muito pequeno (${savedSize} bytes), possível problema`);
504
+ // Restaurar backup se houver
505
+ if (fs.existsSync(backupFile)) {
506
+ fs.copyFileSync(backupFile, ExecutionTracker.dataFile);
507
+ console.log('🔄 ExecutionTracker: Backup restaurado');
508
+ }
509
+ }
510
+ }
511
+ }
512
+ catch (error) {
513
+ console.warn(' ⚠️ AutoDocs: Erro ao salvar dados temporários:', error);
514
+ }
515
+ finally {
516
+ // SEMPRE resetar flag de execução
517
+ ExecutionTracker.isExecutingInternal = false;
518
+ }
519
+ }
520
+ /**
521
+ * 📖 Recuperar dados do arquivo
522
+ */
523
+ static loadFromFile() {
524
+ try {
525
+ if (fs.existsSync(ExecutionTracker.dataFile)) {
526
+ const fileData = fs.readFileSync(ExecutionTracker.dataFile, 'utf8');
527
+ const parsedData = JSON.parse(fileData);
528
+ const stats = `APIs: ${parsedData.apis?.length || 0}, SSH: ${parsedData.ssh?.length || 0}, DB: ${parsedData.db?.length || 0}, UI: ${parsedData.ui?.length || 0}, Mobile: ${parsedData.mobile?.length || 0}`;
529
+ return parsedData;
530
+ }
531
+ console.log('📊 ExecutionTracker.loadFromFile: Arquivo não existe');
532
+ }
533
+ catch (error) {
534
+ console.warn(`⚠️ ExecutionTracker.loadFromFile: Erro ao carregar dados: ${error}`);
535
+ }
536
+ return null;
537
+ }
538
+ /**
539
+ * 📋 Obter dados atuais (COM PROTEÇÃO CONTRA PERDA)
540
+ */
541
+ static getData() {
542
+ // ✅ PROTEÇÃO: Verificar se dados em memória estão vazios mas arquivo existe
543
+ const memoryTotal = ExecutionTracker.data.apis.length +
544
+ ExecutionTracker.data.ssh.length +
545
+ ExecutionTracker.data.db.length +
546
+ ExecutionTracker.data.ui.length +
547
+ ExecutionTracker.data.mobile.length;
548
+ // Tentar carregar do arquivo primeiro
549
+ const fileData = ExecutionTracker.loadFromFile();
550
+ if (fileData) {
551
+ const fileTotal = fileData.apis.length +
552
+ fileData.ssh.length +
553
+ fileData.db.length +
554
+ fileData.ui.length +
555
+ fileData.mobile.length;
556
+ // ✅ CRÍTICO: Se arquivo tem dados mas memória está vazia, usar arquivo
557
+ if (fileTotal > 0 && memoryTotal === 0) {
558
+ ExecutionTracker.data = fileData;
559
+ return fileData;
560
+ }
561
+ // ✅ NOVO: Se arquivo tem mais dados que memória, usar arquivo
562
+ if (fileTotal > memoryTotal) {
563
+ ExecutionTracker.data = fileData;
564
+ return fileData;
565
+ }
566
+ // ✅ MESCLAR: Se ambos têm dados, mesclar preservando o que for maior
567
+ if (fileTotal > 0 && memoryTotal > 0) {
568
+ // Usar o que tiver mais dados para cada categoria
569
+ const mergedData = {
570
+ apis: fileData.apis.length >= ExecutionTracker.data.apis.length
571
+ ? fileData.apis
572
+ : ExecutionTracker.data.apis,
573
+ ssh: fileData.ssh.length >= ExecutionTracker.data.ssh.length
574
+ ? fileData.ssh
575
+ : ExecutionTracker.data.ssh,
576
+ db: fileData.db.length >= ExecutionTracker.data.db.length
577
+ ? fileData.db
578
+ : ExecutionTracker.data.db,
579
+ ui: fileData.ui.length >= ExecutionTracker.data.ui.length
580
+ ? fileData.ui
581
+ : ExecutionTracker.data.ui,
582
+ mobile: fileData.mobile.length >= ExecutionTracker.data.mobile.length
583
+ ? fileData.mobile
584
+ : ExecutionTracker.data.mobile,
585
+ metadata: {
586
+ ...ExecutionTracker.data.metadata,
587
+ ...fileData.metadata,
588
+ // Preservar contadores mais altos
589
+ totalTests: Math.max(ExecutionTracker.data.metadata.totalTests, fileData.metadata.totalTests),
590
+ passedTests: Math.max(ExecutionTracker.data.metadata.passedTests, fileData.metadata.passedTests),
591
+ failedTests: Math.max(ExecutionTracker.data.metadata.failedTests, fileData.metadata.failedTests),
592
+ },
593
+ };
594
+ ExecutionTracker.data = mergedData;
595
+ ExecutionTracker.saveToFile(); // Salvar dados mesclados
596
+ return mergedData;
597
+ }
598
+ return fileData;
599
+ }
600
+ // ✅ IMPORTANTE: Sempre salvar antes de retornar
601
+ if (memoryTotal > 0) {
602
+ ExecutionTracker.saveToFile();
603
+ }
604
+ return ExecutionTracker.data;
605
+ }
606
+ /**
607
+ * 🏁 Finalizar execução (PRESERVA TODOS OS DADOS)
608
+ */
609
+ static finalize() {
610
+ // Preservar dados atuais antes de qualquer alteração
611
+ const currentData = { ...ExecutionTracker.data };
612
+ // Apenas atualizar metadados de finalização
613
+ ExecutionTracker.data.metadata.endTime = new Date().toISOString();
614
+ ExecutionTracker.data.metadata.duration =
615
+ new Date(ExecutionTracker.data.metadata.endTime).getTime() -
616
+ new Date(ExecutionTracker.data.metadata.startTime).getTime();
617
+ // ✅ SALVAR: Forçar salvamento com dados preservados
618
+ ExecutionTracker.saveToFile();
619
+ }
620
+ /**
621
+ * 🧹 Limpar dados (APENAS EM DESENVOLVIMENTO - NUNCA EM PRODUÇÃO)
622
+ */
623
+ static reset() {
624
+ // ✅ PROTEÇÃO: Só permitir reset em desenvolvimento ou com confirmação explícita
625
+ const isProduction = process.env.NODE_ENV === 'production';
626
+ const forceReset = process.env.FORCE_EXECUTION_TRACKER_RESET === 'true';
627
+ if (isProduction && !forceReset) {
628
+ console.warn('⚠️ ExecutionTracker.reset: Ignorado em produção. Use FORCE_EXECUTION_TRACKER_RESET=true se necessário');
629
+ return;
630
+ }
631
+ console.log('⚠️ ExecutionTracker.reset: LIMPANDO TODOS OS DADOS - Esta ação é irreversível!');
632
+ // Backup antes de resetar
633
+ if (fs.existsSync(ExecutionTracker.dataFile)) {
634
+ const backupFile = ExecutionTracker.dataFile + '.reset-backup-' + Date.now();
635
+ try {
636
+ fs.copyFileSync(ExecutionTracker.dataFile, backupFile);
637
+ console.log(`💾 ExecutionTracker.reset: Backup criado em ${backupFile}`);
638
+ }
639
+ catch (error) {
640
+ console.warn(`⚠️ ExecutionTracker.reset: Falha ao criar backup: ${error}`);
641
+ }
642
+ }
643
+ ExecutionTracker.data = {
644
+ apis: [],
645
+ ssh: [],
646
+ db: [],
647
+ ui: [],
648
+ mobile: [],
649
+ metadata: {
650
+ startTime: new Date().toISOString(),
651
+ endTime: '',
652
+ environment: process.env.NODE_ENV || 'development',
653
+ totalTests: 0,
654
+ passedTests: 0,
655
+ failedTests: 0,
656
+ framework: '@silasfmartins/testhub',
657
+ version: ExecutionTracker.getAutoCoreVersion(),
658
+ projectName: 'AutoCore Project',
659
+ projectType: 'Mixed',
660
+ duration: 0,
661
+ },
662
+ };
663
+ // Remover arquivo temporário
664
+ if (fs.existsSync(ExecutionTracker.dataFile)) {
665
+ fs.unlinkSync(ExecutionTracker.dataFile);
666
+ }
667
+ console.log('🧹 ExecutionTracker.reset: Reset concluído');
668
+ }
669
+ /**
670
+ * ⚙️ Configurar opções
671
+ */
672
+ static configure(config) {
673
+ ExecutionTracker.config = { ...ExecutionTracker.config, ...config };
674
+ }
675
+ /**
676
+ * 📊 Obter configuração atual
677
+ */
678
+ static getConfig() {
679
+ return ExecutionTracker.config;
680
+ }
681
+ /**
682
+ * 📈 Obter estatísticas rápidas
683
+ */
684
+ static getStats() {
685
+ const data = ExecutionTracker.getData();
686
+ return {
687
+ totalActions: data.apis.length +
688
+ data.ssh.length +
689
+ data.db.length +
690
+ data.ui.length +
691
+ data.mobile.length,
692
+ categories: [
693
+ { name: 'API', count: data.apis.length },
694
+ { name: 'SSH', count: data.ssh.length },
695
+ { name: 'Database', count: data.db.length },
696
+ { name: 'UI', count: data.ui.length },
697
+ { name: 'Mobile', count: data.mobile.length },
698
+ ].filter((cat) => cat.count > 0),
699
+ duration: data.metadata.duration,
700
+ };
701
+ }
702
+ }