playwright-intelligence-engine 0.0.0-stage → 2.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 (353) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +229 -3
  3. package/bin/pw-intel.js +37 -0
  4. package/dist/authoring/author.d.ts +83 -0
  5. package/dist/authoring/author.d.ts.map +1 -0
  6. package/dist/authoring/generation-contract.d.ts +90 -0
  7. package/dist/authoring/generation-contract.d.ts.map +1 -0
  8. package/dist/authoring/hybrid-author.d.ts +6 -0
  9. package/dist/authoring/hybrid-author.d.ts.map +1 -0
  10. package/dist/authoring/index.d.ts +7 -0
  11. package/dist/authoring/index.d.ts.map +1 -0
  12. package/dist/authoring/llm-author.d.ts +28 -0
  13. package/dist/authoring/llm-author.d.ts.map +1 -0
  14. package/dist/authoring/naming/index.d.ts +4 -0
  15. package/dist/authoring/naming/index.d.ts.map +1 -0
  16. package/dist/authoring/naming/name-plan.d.ts +45 -0
  17. package/dist/authoring/naming/name-plan.d.ts.map +1 -0
  18. package/dist/authoring/naming/name-planner.d.ts +25 -0
  19. package/dist/authoring/naming/name-planner.d.ts.map +1 -0
  20. package/dist/authoring/naming/naming-linter.d.ts +20 -0
  21. package/dist/authoring/naming/naming-linter.d.ts.map +1 -0
  22. package/dist/authoring/template-author.d.ts +6 -0
  23. package/dist/authoring/template-author.d.ts.map +1 -0
  24. package/dist/cli/index.d.ts +2 -0
  25. package/dist/cli/index.d.ts.map +1 -0
  26. package/dist/collectors/collector-interface.d.ts +7 -0
  27. package/dist/collectors/collector-interface.d.ts.map +1 -0
  28. package/dist/collectors/environment-collector.d.ts +12 -0
  29. package/dist/collectors/environment-collector.d.ts.map +1 -0
  30. package/dist/collectors/error-collector.d.ts +18 -0
  31. package/dist/collectors/error-collector.d.ts.map +1 -0
  32. package/dist/collectors/git-diff-collector.d.ts +20 -0
  33. package/dist/collectors/git-diff-collector.d.ts.map +1 -0
  34. package/dist/collectors/live-browser-collector.d.ts +45 -0
  35. package/dist/collectors/live-browser-collector.d.ts.map +1 -0
  36. package/dist/collectors/network-collector.d.ts +28 -0
  37. package/dist/collectors/network-collector.d.ts.map +1 -0
  38. package/dist/collectors/static-ast-collector.d.ts +32 -0
  39. package/dist/collectors/static-ast-collector.d.ts.map +1 -0
  40. package/dist/collectors/trace-collector.d.ts +12 -0
  41. package/dist/collectors/trace-collector.d.ts.map +1 -0
  42. package/dist/config/project-config.d.ts +33 -0
  43. package/dist/config/project-config.d.ts.map +1 -0
  44. package/dist/core/errors/engine-errors.d.ts +34 -0
  45. package/dist/core/errors/engine-errors.d.ts.map +1 -0
  46. package/dist/core/types/diagnostic-context.d.ts +151 -0
  47. package/dist/core/types/diagnostic-context.d.ts.map +1 -0
  48. package/dist/core/types/repair-evidence.d.ts +56 -0
  49. package/dist/core/types/repair-evidence.d.ts.map +1 -0
  50. package/dist/core/version.d.ts +13 -0
  51. package/dist/core/version.d.ts.map +1 -0
  52. package/dist/diagnostics/diagnostic-contract.d.ts +52 -0
  53. package/dist/diagnostics/diagnostic-contract.d.ts.map +1 -0
  54. package/dist/diagnostics/diagnostic-report.d.ts +11 -0
  55. package/dist/diagnostics/diagnostic-report.d.ts.map +1 -0
  56. package/dist/diagnostics/evidence-correlator.d.ts +22 -0
  57. package/dist/diagnostics/evidence-correlator.d.ts.map +1 -0
  58. package/dist/diagnostics/external-failure-evidence.d.ts +18 -0
  59. package/dist/diagnostics/external-failure-evidence.d.ts.map +1 -0
  60. package/dist/diagnostics/failure-category.d.ts +4 -0
  61. package/dist/diagnostics/failure-category.d.ts.map +1 -0
  62. package/dist/diagnostics/failure-classifier.d.ts +58 -0
  63. package/dist/diagnostics/failure-classifier.d.ts.map +1 -0
  64. package/dist/evaluation/evaluation-scorecard.d.ts +72 -0
  65. package/dist/evaluation/evaluation-scorecard.d.ts.map +1 -0
  66. package/dist/evaluation/repository-inspector.d.ts +21 -0
  67. package/dist/evaluation/repository-inspector.d.ts.map +1 -0
  68. package/dist/evaluation/repository-runner.d.ts +24 -0
  69. package/dist/evaluation/repository-runner.d.ts.map +1 -0
  70. package/dist/evidence/evidence-model.d.ts +88 -0
  71. package/dist/evidence/evidence-model.d.ts.map +1 -0
  72. package/dist/evidence/evidence-normalizer.d.ts +19 -0
  73. package/dist/evidence/evidence-normalizer.d.ts.map +1 -0
  74. package/dist/evidence/evidence-redactor.d.ts +37 -0
  75. package/dist/evidence/evidence-redactor.d.ts.map +1 -0
  76. package/dist/framework/config-adapter.d.ts +28 -0
  77. package/dist/framework/config-adapter.d.ts.map +1 -0
  78. package/dist/gate/index.d.ts +21 -0
  79. package/dist/gate/index.d.ts.map +1 -0
  80. package/dist/gate/oracle.d.ts +26 -0
  81. package/dist/gate/oracle.d.ts.map +1 -0
  82. package/dist/gate/quality.d.ts +27 -0
  83. package/dist/gate/quality.d.ts.map +1 -0
  84. package/dist/gate/safety.d.ts +28 -0
  85. package/dist/gate/safety.d.ts.map +1 -0
  86. package/dist/generator/architecture-generator.d.ts +55 -0
  87. package/dist/generator/architecture-generator.d.ts.map +1 -0
  88. package/dist/generator/assertion-quality-gate.d.ts +18 -0
  89. package/dist/generator/assertion-quality-gate.d.ts.map +1 -0
  90. package/dist/generator/candidate-writer.d.ts +34 -0
  91. package/dist/generator/candidate-writer.d.ts.map +1 -0
  92. package/dist/generator/test-generator.d.ts +26 -0
  93. package/dist/generator/test-generator.d.ts.map +1 -0
  94. package/dist/governance/audit-log.d.ts +23 -0
  95. package/dist/governance/audit-log.d.ts.map +1 -0
  96. package/dist/governance/governance-policy.d.ts +24 -0
  97. package/dist/governance/governance-policy.d.ts.map +1 -0
  98. package/dist/governance/team-dashboard.d.ts +51 -0
  99. package/dist/governance/team-dashboard.d.ts.map +1 -0
  100. package/dist/governance/workflow-audit.d.ts +13 -0
  101. package/dist/governance/workflow-audit.d.ts.map +1 -0
  102. package/dist/index.d.ts +90 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +20318 -0
  105. package/dist/integrations/ci-summary.d.ts +14 -0
  106. package/dist/integrations/ci-summary.d.ts.map +1 -0
  107. package/dist/integrations/playwright-report-adapter.d.ts +22 -0
  108. package/dist/integrations/playwright-report-adapter.d.ts.map +1 -0
  109. package/dist/integrations/quality-gate.d.ts +35 -0
  110. package/dist/integrations/quality-gate.d.ts.map +1 -0
  111. package/dist/integrations/sarif-report.d.ts +48 -0
  112. package/dist/integrations/sarif-report.d.ts.map +1 -0
  113. package/dist/intelligence/autonomous-repair-workflow.d.ts +31 -0
  114. package/dist/intelligence/autonomous-repair-workflow.d.ts.map +1 -0
  115. package/dist/intelligence/business-intent.d.ts +58 -0
  116. package/dist/intelligence/business-intent.d.ts.map +1 -0
  117. package/dist/intelligence/evidence-bundle.d.ts +364 -0
  118. package/dist/intelligence/evidence-bundle.d.ts.map +1 -0
  119. package/dist/intelligence/failure-clustering.d.ts +38 -0
  120. package/dist/intelligence/failure-clustering.d.ts.map +1 -0
  121. package/dist/intelligence/generation-agent.d.ts +120 -0
  122. package/dist/intelligence/generation-agent.d.ts.map +1 -0
  123. package/dist/intelligence/generation-verifier.d.ts +151 -0
  124. package/dist/intelligence/generation-verifier.d.ts.map +1 -0
  125. package/dist/intelligence/llm-proposal.d.ts +377 -0
  126. package/dist/intelligence/llm-proposal.d.ts.map +1 -0
  127. package/dist/intelligence/locator-disambiguation-engine.d.ts +38 -0
  128. package/dist/intelligence/locator-disambiguation-engine.d.ts.map +1 -0
  129. package/dist/intelligence/model-contract.d.ts +86 -0
  130. package/dist/intelligence/model-contract.d.ts.map +1 -0
  131. package/dist/intelligence/model-provider.d.ts +75 -0
  132. package/dist/intelligence/model-provider.d.ts.map +1 -0
  133. package/dist/intelligence/project-intelligence.d.ts +22 -0
  134. package/dist/intelligence/project-intelligence.d.ts.map +1 -0
  135. package/dist/intelligence/repair-agent.d.ts +46 -0
  136. package/dist/intelligence/repair-agent.d.ts.map +1 -0
  137. package/dist/intelligence/repository-profile.d.ts +131 -0
  138. package/dist/intelligence/repository-profile.d.ts.map +1 -0
  139. package/dist/intelligence/suite-intelligence.d.ts +59 -0
  140. package/dist/intelligence/suite-intelligence.d.ts.map +1 -0
  141. package/dist/intelligence/test-intelligence.d.ts +44 -0
  142. package/dist/intelligence/test-intelligence.d.ts.map +1 -0
  143. package/dist/intelligence/trace-proposal-workflow.d.ts +30 -0
  144. package/dist/intelligence/trace-proposal-workflow.d.ts.map +1 -0
  145. package/dist/intelligence/verified-llm-repair-workflow.d.ts +21 -0
  146. package/dist/intelligence/verified-llm-repair-workflow.d.ts.map +1 -0
  147. package/dist/intelligence/workflow-planner.d.ts +278 -0
  148. package/dist/intelligence/workflow-planner.d.ts.map +1 -0
  149. package/dist/mcp/server.d.ts +32 -0
  150. package/dist/mcp/server.d.ts.map +1 -0
  151. package/dist/memory/stability-ledger.d.ts +46 -0
  152. package/dist/memory/stability-ledger.d.ts.map +1 -0
  153. package/dist/perception/app-model.d.ts +55 -0
  154. package/dist/perception/app-model.d.ts.map +1 -0
  155. package/dist/perception/crawler.d.ts +18 -0
  156. package/dist/perception/crawler.d.ts.map +1 -0
  157. package/dist/perception/index.d.ts +3 -0
  158. package/dist/perception/index.d.ts.map +1 -0
  159. package/dist/repair/approval-service.d.ts +139 -0
  160. package/dist/repair/approval-service.d.ts.map +1 -0
  161. package/dist/repair/assertion-hasher.d.ts +62 -0
  162. package/dist/repair/assertion-hasher.d.ts.map +1 -0
  163. package/dist/repair/ast-patcher.d.ts +36 -0
  164. package/dist/repair/ast-patcher.d.ts.map +1 -0
  165. package/dist/repair/browser-operation-executor.d.ts +27 -0
  166. package/dist/repair/browser-operation-executor.d.ts.map +1 -0
  167. package/dist/repair/diff-allowlist.d.ts +74 -0
  168. package/dist/repair/diff-allowlist.d.ts.map +1 -0
  169. package/dist/repair/intent-validator.d.ts +157 -0
  170. package/dist/repair/intent-validator.d.ts.map +1 -0
  171. package/dist/repair/repair-operations.d.ts +40 -0
  172. package/dist/repair/repair-operations.d.ts.map +1 -0
  173. package/dist/repair/repair-planner.d.ts +98 -0
  174. package/dist/repair/repair-planner.d.ts.map +1 -0
  175. package/dist/repair/repair-workflow.d.ts +42 -0
  176. package/dist/repair/repair-workflow.d.ts.map +1 -0
  177. package/dist/repair/safe-operation-compiler.d.ts +15 -0
  178. package/dist/repair/safe-operation-compiler.d.ts.map +1 -0
  179. package/dist/repair/source-mapper.d.ts +19 -0
  180. package/dist/repair/source-mapper.d.ts.map +1 -0
  181. package/dist/repair/statement-patcher.d.ts +75 -0
  182. package/dist/repair/statement-patcher.d.ts.map +1 -0
  183. package/dist/repair/verification-gates.d.ts +25 -0
  184. package/dist/repair/verification-gates.d.ts.map +1 -0
  185. package/dist/repair/workflow-plan.d.ts +35 -0
  186. package/dist/repair/workflow-plan.d.ts.map +1 -0
  187. package/dist/repair/workspace-promoter.d.ts +43 -0
  188. package/dist/repair/workspace-promoter.d.ts.map +1 -0
  189. package/dist/reproduce/diagnostic-rerunner.d.ts +40 -0
  190. package/dist/reproduce/diagnostic-rerunner.d.ts.map +1 -0
  191. package/dist/reproduce/direct-browser-investigator.d.ts +41 -0
  192. package/dist/reproduce/direct-browser-investigator.d.ts.map +1 -0
  193. package/dist/reproduce/interactive-workflow-runner.d.ts +43 -0
  194. package/dist/reproduce/interactive-workflow-runner.d.ts.map +1 -0
  195. package/dist/sandbox/dependency-strategy.d.ts +45 -0
  196. package/dist/sandbox/dependency-strategy.d.ts.map +1 -0
  197. package/dist/sandbox/execution-runner.d.ts +81 -0
  198. package/dist/sandbox/execution-runner.d.ts.map +1 -0
  199. package/dist/sandbox/worktree-manager.d.ts +51 -0
  200. package/dist/sandbox/worktree-manager.d.ts.map +1 -0
  201. package/dist/selector/abstention-policy.d.ts +34 -0
  202. package/dist/selector/abstention-policy.d.ts.map +1 -0
  203. package/dist/selector/candidate-extractor.d.ts +71 -0
  204. package/dist/selector/candidate-extractor.d.ts.map +1 -0
  205. package/dist/selector/live-locator-verifier.d.ts +28 -0
  206. package/dist/selector/live-locator-verifier.d.ts.map +1 -0
  207. package/dist/selector/repair-candidate-ranker.d.ts +10 -0
  208. package/dist/selector/repair-candidate-ranker.d.ts.map +1 -0
  209. package/dist/selector/selector-scorer.d.ts +43 -0
  210. package/dist/selector/selector-scorer.d.ts.map +1 -0
  211. package/dist/trace/adapters/adapter-registry.d.ts +18 -0
  212. package/dist/trace/adapters/adapter-registry.d.ts.map +1 -0
  213. package/dist/trace/adapters/trace-adapter.d.ts +21 -0
  214. package/dist/trace/adapters/trace-adapter.d.ts.map +1 -0
  215. package/dist/trace/adapters/unknown-adapter.d.ts +10 -0
  216. package/dist/trace/adapters/unknown-adapter.d.ts.map +1 -0
  217. package/dist/trace/adapters/v10-adapter.d.ts +10 -0
  218. package/dist/trace/adapters/v10-adapter.d.ts.map +1 -0
  219. package/dist/trace/adapters/v4-adapter.d.ts +11 -0
  220. package/dist/trace/adapters/v4-adapter.d.ts.map +1 -0
  221. package/dist/trace/adapters/v8-adapter.d.ts +10 -0
  222. package/dist/trace/adapters/v8-adapter.d.ts.map +1 -0
  223. package/dist/trace/adapters/v9-adapter.d.ts +10 -0
  224. package/dist/trace/adapters/v9-adapter.d.ts.map +1 -0
  225. package/dist/trace/archive-reader.d.ts +44 -0
  226. package/dist/trace/archive-reader.d.ts.map +1 -0
  227. package/dist/trace/snapshot-resolver.d.ts +55 -0
  228. package/dist/trace/snapshot-resolver.d.ts.map +1 -0
  229. package/dist/trace/trace-parser.d.ts +50 -0
  230. package/dist/trace/trace-parser.d.ts.map +1 -0
  231. package/dist/trace/version-detector.d.ts +20 -0
  232. package/dist/trace/version-detector.d.ts.map +1 -0
  233. package/package.json +76 -6
  234. package/skills/README.md +20 -0
  235. package/skills/pie-failure-investigation/SKILL.md +16 -0
  236. package/skills/pie-quality-engineer/SKILL.md +66 -0
  237. package/skills/pie-release-readiness/SKILL.md +22 -0
  238. package/skills/pie-repair-review/SKILL.md +21 -0
  239. package/skills/pie-trace-to-repair/SKILL.md +35 -0
  240. package/src/authoring/author.ts +81 -0
  241. package/src/authoring/generation-contract.ts +283 -0
  242. package/src/authoring/hybrid-author.ts +115 -0
  243. package/src/authoring/index.ts +7 -0
  244. package/src/authoring/llm-author.ts +282 -0
  245. package/src/authoring/naming/index.ts +4 -0
  246. package/src/authoring/naming/name-plan.ts +28 -0
  247. package/src/authoring/naming/name-planner.ts +339 -0
  248. package/src/authoring/naming/naming-linter.ts +292 -0
  249. package/src/authoring/template-author.ts +39 -0
  250. package/src/cli/index.ts +1172 -0
  251. package/src/collectors/collector-interface.ts +8 -0
  252. package/src/collectors/environment-collector.ts +103 -0
  253. package/src/collectors/error-collector.ts +177 -0
  254. package/src/collectors/git-diff-collector.ts +190 -0
  255. package/src/collectors/live-browser-collector.ts +412 -0
  256. package/src/collectors/network-collector.ts +90 -0
  257. package/src/collectors/static-ast-collector.ts +226 -0
  258. package/src/collectors/trace-collector.ts +66 -0
  259. package/src/config/project-config.ts +114 -0
  260. package/src/core/errors/engine-errors.ts +90 -0
  261. package/src/core/types/diagnostic-context.ts +94 -0
  262. package/src/core/types/repair-evidence.ts +45 -0
  263. package/src/core/version.ts +25 -0
  264. package/src/diagnostics/diagnostic-contract.ts +79 -0
  265. package/src/diagnostics/diagnostic-report.ts +204 -0
  266. package/src/diagnostics/evidence-correlator.ts +117 -0
  267. package/src/diagnostics/external-failure-evidence.ts +72 -0
  268. package/src/diagnostics/failure-category.ts +40 -0
  269. package/src/diagnostics/failure-classifier.ts +701 -0
  270. package/src/evaluation/evaluation-scorecard.ts +198 -0
  271. package/src/evaluation/repository-inspector.ts +143 -0
  272. package/src/evaluation/repository-runner.ts +197 -0
  273. package/src/evidence/evidence-model.ts +76 -0
  274. package/src/evidence/evidence-normalizer.ts +322 -0
  275. package/src/evidence/evidence-redactor.ts +218 -0
  276. package/src/framework/config-adapter.ts +131 -0
  277. package/src/gate/index.ts +43 -0
  278. package/src/gate/oracle.ts +69 -0
  279. package/src/gate/quality.ts +101 -0
  280. package/src/gate/safety.ts +94 -0
  281. package/src/generator/architecture-generator.ts +582 -0
  282. package/src/generator/assertion-quality-gate.ts +88 -0
  283. package/src/generator/candidate-writer.ts +288 -0
  284. package/src/generator/test-generator.ts +52 -0
  285. package/src/governance/audit-log.ts +115 -0
  286. package/src/governance/governance-policy.ts +72 -0
  287. package/src/governance/team-dashboard.ts +189 -0
  288. package/src/governance/workflow-audit.ts +72 -0
  289. package/src/index.ts +107 -0
  290. package/src/integrations/ci-summary.ts +37 -0
  291. package/src/integrations/playwright-report-adapter.ts +173 -0
  292. package/src/integrations/quality-gate.ts +95 -0
  293. package/src/integrations/sarif-report.ts +110 -0
  294. package/src/intelligence/autonomous-repair-workflow.ts +139 -0
  295. package/src/intelligence/business-intent.ts +163 -0
  296. package/src/intelligence/evidence-bundle.ts +300 -0
  297. package/src/intelligence/failure-clustering.ts +134 -0
  298. package/src/intelligence/generation-agent.ts +561 -0
  299. package/src/intelligence/generation-verifier.ts +1115 -0
  300. package/src/intelligence/llm-proposal.ts +519 -0
  301. package/src/intelligence/locator-disambiguation-engine.ts +331 -0
  302. package/src/intelligence/model-contract.ts +205 -0
  303. package/src/intelligence/model-provider.ts +348 -0
  304. package/src/intelligence/project-intelligence.ts +140 -0
  305. package/src/intelligence/repair-agent.ts +297 -0
  306. package/src/intelligence/repository-profile.ts +796 -0
  307. package/src/intelligence/suite-intelligence.ts +305 -0
  308. package/src/intelligence/test-intelligence.ts +136 -0
  309. package/src/intelligence/trace-proposal-workflow.ts +318 -0
  310. package/src/intelligence/verified-llm-repair-workflow.ts +48 -0
  311. package/src/intelligence/workflow-planner.ts +966 -0
  312. package/src/mcp/server.ts +970 -0
  313. package/src/memory/stability-ledger.ts +243 -0
  314. package/src/perception/app-model.ts +32 -0
  315. package/src/perception/crawler.ts +263 -0
  316. package/src/perception/index.ts +3 -0
  317. package/src/repair/approval-service.ts +541 -0
  318. package/src/repair/assertion-hasher.ts +386 -0
  319. package/src/repair/ast-patcher.ts +223 -0
  320. package/src/repair/browser-operation-executor.ts +263 -0
  321. package/src/repair/diff-allowlist.ts +612 -0
  322. package/src/repair/intent-validator.ts +761 -0
  323. package/src/repair/repair-operations.ts +65 -0
  324. package/src/repair/repair-planner.ts +467 -0
  325. package/src/repair/repair-workflow.ts +241 -0
  326. package/src/repair/safe-operation-compiler.ts +68 -0
  327. package/src/repair/source-mapper.ts +156 -0
  328. package/src/repair/statement-patcher.ts +544 -0
  329. package/src/repair/verification-gates.ts +46 -0
  330. package/src/repair/workflow-plan.ts +59 -0
  331. package/src/repair/workspace-promoter.ts +313 -0
  332. package/src/reproduce/diagnostic-rerunner.ts +287 -0
  333. package/src/reproduce/direct-browser-investigator.ts +208 -0
  334. package/src/reproduce/interactive-workflow-runner.ts +828 -0
  335. package/src/sandbox/dependency-strategy.ts +215 -0
  336. package/src/sandbox/execution-runner.ts +408 -0
  337. package/src/sandbox/worktree-manager.ts +287 -0
  338. package/src/selector/abstention-policy.ts +175 -0
  339. package/src/selector/candidate-extractor.ts +343 -0
  340. package/src/selector/live-locator-verifier.ts +139 -0
  341. package/src/selector/repair-candidate-ranker.ts +92 -0
  342. package/src/selector/selector-scorer.ts +344 -0
  343. package/src/trace/adapters/adapter-registry.ts +49 -0
  344. package/src/trace/adapters/trace-adapter.ts +28 -0
  345. package/src/trace/adapters/unknown-adapter.ts +50 -0
  346. package/src/trace/adapters/v10-adapter.ts +39 -0
  347. package/src/trace/adapters/v4-adapter.ts +31 -0
  348. package/src/trace/adapters/v8-adapter.ts +42 -0
  349. package/src/trace/adapters/v9-adapter.ts +39 -0
  350. package/src/trace/archive-reader.ts +246 -0
  351. package/src/trace/snapshot-resolver.ts +308 -0
  352. package/src/trace/trace-parser.ts +467 -0
  353. package/src/trace/version-detector.ts +81 -0
@@ -0,0 +1,344 @@
1
+ import { ResolvedElement } from '../trace/snapshot-resolver.js';
2
+
3
+ export interface ScorerWeights {
4
+ wU: number; // Uniqueness
5
+ wI: number; // Identity Match
6
+ wM: number; // Semantic Match (Role/Label over raw CSS)
7
+ wA: number; // Actionability (visible/enabled)
8
+ wH: number; // Historical Execution Reliability
9
+ wD: number; // Volatile Implementation Dependence penalty
10
+ }
11
+
12
+ export interface ScoreBreakdown {
13
+ score: number;
14
+ transformedScore: number;
15
+ calibratedProbability: number; // Retained as alias for transformedScore
16
+ uniqueness: number;
17
+ matchCount: number;
18
+ identityMatch: number;
19
+ semanticMatch: number;
20
+ actionability: number;
21
+ historicalReliability: number;
22
+ historicalExecutionReliability: number;
23
+ volatilePenalty: number;
24
+ conventionAlignment?: number;
25
+ explanation: string[];
26
+ }
27
+
28
+ export interface SelectorProjectContext {
29
+ preferredLocator?: 'getByRole' | 'getByTestId' | 'getByLabel' | 'getByText' | 'locator' | 'unknown';
30
+ /** Observed locator counts from the repository profile. */
31
+ locatorUsage?: Partial<Record<'getByRole' | 'getByTestId' | 'getByLabel' | 'getByText' | 'locator', number>>;
32
+ }
33
+
34
+ const SEMANTIC_INTENT_GROUPS: string[][] = [
35
+ ['login', 'log in', 'signin', 'sign in', 'authenticate'],
36
+ ['logout', 'log out', 'signout', 'sign out'],
37
+ ['submit', 'save', 'confirm', 'send', 'apply'],
38
+ ['cancel', 'close', 'dismiss', 'abort'],
39
+ ['checkout', 'pay', 'payment', 'order'],
40
+ ];
41
+
42
+ function semanticIntentGroup(value: string): string[] | undefined {
43
+ return SEMANTIC_INTENT_GROUPS.find((group) => group.some((term) => value.includes(term)));
44
+ }
45
+
46
+ export class SelectorScorer {
47
+ public static readonly DEFAULT_WEIGHTS: ScorerWeights = {
48
+ wU: 0.25,
49
+ wI: 0.25,
50
+ wM: 0.20,
51
+ wA: 0.15,
52
+ wH: 0.10,
53
+ wD: 0.20,
54
+ };
55
+
56
+ /**
57
+ * Scores a candidate element against the multi-factor formula:
58
+ * S(L) = w1*U + w2*I + w3*M + w4*A + w5*H - w6*D
59
+ *
60
+ * Uniqueness evaluates whether the proposed locator resolves to exactly one element.
61
+ * Identity requires affirmative token overlap and rejects contradictory semantics.
62
+ * Actionability verifies enabled state and non-hidden status.
63
+ * Produces a transformed score (sigmoid scaling), not an overclaimed empirical probability.
64
+ */
65
+ public static score(
66
+ candidate: ResolvedElement,
67
+ allCandidates: ResolvedElement[],
68
+ originalSelector?: string,
69
+ historicalScore?: number,
70
+ weights = SelectorScorer.DEFAULT_WEIGHTS,
71
+ projectContext?: SelectorProjectContext,
72
+ ): ScoreBreakdown {
73
+ const explanation: string[] = [];
74
+
75
+ // 1. Uniqueness U: Evaluated on actual candidate identifying attributes
76
+ const matchingCount = allCandidates.filter((c) => {
77
+ // If role + name exists, check match on role + name
78
+ if (candidate.role && candidate.accessibleName) {
79
+ return c.role === candidate.role && c.accessibleName === candidate.accessibleName;
80
+ }
81
+ // If testid exists, check match on testid
82
+ const candTestId = candidate.attributes?.['data-testid'] ?? candidate.attributes?.['data-test'];
83
+ if (candTestId) {
84
+ const cTestId = c.attributes?.['data-testid'] ?? c.attributes?.['data-test'];
85
+ return cTestId === candTestId;
86
+ }
87
+ // If id exists, check match on id
88
+ if (candidate.attributes?.['id']) {
89
+ return c.attributes?.['id'] === candidate.attributes?.['id'];
90
+ }
91
+ return c.tag === candidate.tag && c.role === candidate.role && c.accessibleName === candidate.accessibleName;
92
+ }).length;
93
+
94
+ const uniqueness = matchingCount === 1 ? 1.0 : matchingCount > 1 ? parseFloat((1 / matchingCount).toFixed(3)) : 0.0;
95
+ explanation.push(`Uniqueness U: ${uniqueness} (${matchingCount} matching element(s) in scope)`);
96
+
97
+ // 2. Identity Match I: Entity identity and affirmative token overlap
98
+ let identityMatch = candidate.accessibleName ? (originalSelector ? 0.3 : 0.8) : 0.3;
99
+ if (candidate.accessibleName) {
100
+ if (originalSelector) {
101
+ const origNorm = originalSelector.toLowerCase().replace(/[-_]/g, ' ');
102
+ const nameNorm = candidate.accessibleName.toLowerCase().replace(/[-_]/g, ' ');
103
+ const exactIdentityMatch = origNorm.includes(nameNorm) || nameNorm.includes(origNorm);
104
+
105
+ const originalIntent = semanticIntentGroup(origNorm);
106
+ const candidateIntent = semanticIntentGroup(nameNorm);
107
+ if (exactIdentityMatch) {
108
+ identityMatch = 1.0;
109
+ explanation.push('Identity Match I: 1.0 (Exact identity text match detected)');
110
+ } else if (originalIntent && candidateIntent && originalIntent === candidateIntent) {
111
+ identityMatch = 0.98;
112
+ explanation.push('Identity Match I: 0.98 (Equivalent semantic action intent detected)');
113
+ } else if (originalIntent && candidateIntent && originalIntent !== candidateIntent) {
114
+ const negativeIntents = new Set(['logout', 'log out', 'signout', 'sign out', 'cancel', 'close', 'dismiss', 'abort']);
115
+ const originalIsNegative = originalIntent.some((term) => negativeIntents.has(term));
116
+ const candidateIsNegative = candidateIntent.some((term) => negativeIntents.has(term));
117
+ if (originalIsNegative !== candidateIsNegative) {
118
+ identityMatch = 0.0;
119
+ explanation.push('Identity Match I: 0.0 (Conflicting semantic action intent detected)');
120
+ }
121
+ }
122
+
123
+ // Hard check: Contradictory semantics (submit vs cancel)
124
+ const positiveWords = ['submit', 'login', 'checkout', 'save', 'confirm', 'proceed', 'pay', 'order'];
125
+ const negativeWords = ['cancel', 'close', 'reset', 'abort', 'back', 'dismiss', 'delete'];
126
+
127
+ const origIsPositive = positiveWords.some((t) => origNorm.includes(t));
128
+ const candIsNegative = negativeWords.some((t) => nameNorm.includes(t));
129
+ const origIsNegative = negativeWords.some((t) => origNorm.includes(t));
130
+ const candIsPositive = positiveWords.some((t) => nameNorm.includes(t));
131
+
132
+ // Differentiating action token conflicts (e.g. continue shopping vs continue checkout)
133
+ const distinguishingPairs: Array<[string, string]> = [
134
+ ['shopping', 'checkout'],
135
+ ['cart', 'checkout'],
136
+ ['prev', 'next'],
137
+ ['previous', 'next'],
138
+ ['first', 'last'],
139
+ ['left', 'right'],
140
+ ['up', 'down'],
141
+ ['yes', 'no'],
142
+ ['approve', 'reject'],
143
+ ['accept', 'decline'],
144
+ ['enable', 'disable'],
145
+ ['open', 'close'],
146
+ ['edit', 'delete'],
147
+ ['create', 'delete'],
148
+ ['add', 'delete'],
149
+ ['remove', 'edit'],
150
+ ['modify', 'delete'],
151
+ ];
152
+
153
+ let hasDistinguishingConflict = false;
154
+ for (const [w1, w2] of distinguishingPairs) {
155
+ const origHasW1 = origNorm.includes(w1);
156
+ const origHasW2 = origNorm.includes(w2);
157
+ const candHasW1 = nameNorm.includes(w1);
158
+ const candHasW2 = nameNorm.includes(w2);
159
+ if (
160
+ (origHasW1 && !origHasW2 && candHasW2 && !candHasW1) ||
161
+ (origHasW2 && !origHasW1 && candHasW1 && !candHasW2)
162
+ ) {
163
+ hasDistinguishingConflict = true;
164
+ break;
165
+ }
166
+ }
167
+
168
+ if (identityMatch === 0.98 || identityMatch === 0.0) {
169
+ // Preserve the stronger semantic intent result above.
170
+ } else if (hasDistinguishingConflict) {
171
+ identityMatch = 0.1;
172
+ explanation.push(`Identity Match I: 0.1 (Conflicting action token intent detected)`);
173
+ } else if ((origIsPositive && candIsNegative) || (origIsNegative && candIsPositive)) {
174
+ identityMatch = 0.0;
175
+ explanation.push(`Identity Match I: 0.0 (Hard contradiction: target has opposing confirmation/cancellation semantics)`);
176
+ } else if (exactIdentityMatch) {
177
+ identityMatch = 1.0;
178
+ } else {
179
+ // Token overlap evaluating composite candidate identity (accessibleName, text, testid, id)
180
+ const candCompositeText = [
181
+ candidate.accessibleName ?? '',
182
+ candidate.text ?? '',
183
+ candidate.attributes['data-testid'] ?? candidate.attributes['data-test'] ?? '',
184
+ candidate.attributes['id'] ?? '',
185
+ ].join(' ').toLowerCase().replace(/[-_]/g, ' ');
186
+
187
+ const origWords = new Set(origNorm.split(/[^a-z0-9]+/).filter((w) => w.length > 2));
188
+ const candWords = new Set(candCompositeText.split(/[^a-z0-9]+/).filter((w) => w.length > 2));
189
+ if (origWords.size > 0 && candWords.size > 0) {
190
+ const intersection = [...origWords].filter((w) => candWords.has(w));
191
+ const overlap = intersection.length / Math.min(origWords.size, candWords.size);
192
+ if (overlap >= 0.5) {
193
+ identityMatch = 0.95;
194
+ } else if (overlap > 0) {
195
+ identityMatch = 0.85;
196
+ } else {
197
+ identityMatch = 0.0;
198
+ explanation.push(`Identity Match I: 0.0 (Zero token overlap or semantic correspondence with original selector)`);
199
+ }
200
+ } else {
201
+ identityMatch = 0.2;
202
+ explanation.push(`Identity Match I: 0.2 (Insufficient token information to prove identity)`);
203
+ }
204
+ }
205
+
206
+ // Semantic Role Alignment: If original explicitly specifies button vs link
207
+ const origWantsButton = /\bbutton\b/i.test(originalSelector) || /getByRole\(\s*['"]button['"]/i.test(originalSelector) || /#btn-/i.test(originalSelector);
208
+ const origWantsLink = /\b(link|a)\b/i.test(originalSelector) || /getByRole\(\s*['"]link['"]/i.test(originalSelector);
209
+
210
+ if (origWantsButton && (candidate.role === 'link' || candidate.tag === 'a') && candidate.role !== 'button') {
211
+ identityMatch = Math.max(0, identityMatch - 0.25);
212
+ explanation.push('Role Mismatch Penalty: -0.25 (Original selector requires button, candidate is link/anchor)');
213
+ } else if (origWantsLink && candidate.role === 'button' && candidate.tag !== 'a') {
214
+ identityMatch = Math.max(0, identityMatch - 0.25);
215
+ explanation.push('Role Mismatch Penalty: -0.25 (Original selector requires link, candidate is button)');
216
+ }
217
+ }
218
+ }
219
+ explanation.push(`Identity Match I: ${identityMatch}`);
220
+
221
+ // 3. Semantic Match M: getByRole / getByLabel priority over raw CSS
222
+ let semanticMatch = 0.4; // Base for raw HTML tag
223
+ if (candidate.role && candidate.accessibleName) {
224
+ semanticMatch = 1.0; // Priority: Role + Accessible Name
225
+ } else if (candidate.attributes['data-testid'] || candidate.attributes['data-test']) {
226
+ semanticMatch = 0.9; // Dedicated Test ID
227
+ } else if (candidate.attributes['placeholder'] || candidate.attributes['aria-label']) {
228
+ semanticMatch = 0.85;
229
+ }
230
+ explanation.push(`Semantic Match M: ${semanticMatch} (Role: ${candidate.role ?? 'none'})`);
231
+
232
+ // 4. Actionability A: Element is enabled and visible
233
+ const isDisabled = Boolean(candidate.attributes['disabled']) || candidate.attributes['aria-disabled'] === 'true';
234
+ const isHidden = candidate.attributes['hidden'] === 'true' || candidate.attributes['aria-hidden'] === 'true';
235
+ const actionability = isDisabled || isHidden ? 0.0 : 1.0;
236
+ explanation.push(`Actionability A: ${actionability} (Disabled: ${isDisabled}, Hidden: ${isHidden})`);
237
+
238
+ // 5. Historical Execution Reliability H: Neutral 0.5 baseline if unrecorded
239
+ const historicalReliability = historicalScore !== undefined
240
+ ? Math.max(0, Math.min(1.0, historicalScore))
241
+ : 0.5;
242
+ explanation.push(`Historical Execution Reliability H: ${historicalReliability}`);
243
+
244
+ // 6. Volatile Implementation Dependence D (Penalizes hashed classes and dynamic IDs)
245
+ let volatilePenalty = 0.0;
246
+ const id = candidate.attributes['id'] ?? '';
247
+ const classAttr = candidate.attributes['class'] ?? '';
248
+
249
+ // Check for random hex/hash IDs e.g. "id-a1b2c3d4", React useId ":r1:", or component IDs
250
+ if (
251
+ /^[0-9a-f]{8,}$/i.test(id) ||
252
+ /^[a-z]+-[0-9a-f]{4,}$/i.test(id) ||
253
+ /^:r[0-9a-z]+:$/i.test(id) ||
254
+ /^(ember|chakra|radix)-\d+/i.test(id)
255
+ ) {
256
+ volatilePenalty += 0.5;
257
+ }
258
+
259
+ // Check for CSS-in-JS hashed classes e.g. "css-1a2b3c" or "sc-xyz123"
260
+ if (/css-[a-z0-9]+/i.test(classAttr) || /sc-[a-z0-9]+/i.test(classAttr)) {
261
+ volatilePenalty += 0.4;
262
+ }
263
+
264
+ volatilePenalty = Math.min(1.0, volatilePenalty);
265
+ explanation.push(`Volatile Penalty D: ${volatilePenalty}`);
266
+
267
+ const candidateKind = candidate.role && candidate.accessibleName
268
+ ? 'getByRole'
269
+ : candidate.attributes['data-testid'] || candidate.attributes['data-test']
270
+ ? 'getByTestId'
271
+ : candidate.attributes['placeholder'] || candidate.attributes['aria-label']
272
+ ? 'getByLabel'
273
+ : candidate.text
274
+ ? 'getByText'
275
+ : 'locator';
276
+ const locatorUsage = projectContext?.locatorUsage;
277
+ const usageTotal = locatorUsage
278
+ ? Object.values(locatorUsage).reduce((sum, count) => sum + (typeof count === 'number' && count > 0 ? count : 0), 0)
279
+ : 0;
280
+ const conventionAlignment = usageTotal > 0
281
+ ? Math.max(0, Math.min(1, (locatorUsage?.[candidateKind] ?? 0) / usageTotal))
282
+ : projectContext?.preferredLocator && projectContext.preferredLocator !== 'unknown'
283
+ ? projectContext.preferredLocator === candidateKind ? 1 : 0
284
+ : 0.5;
285
+ // Keep convention influence deliberately small: observed project style can
286
+ // break a close tie, but never compensate for weak identity or uniqueness.
287
+ const conventionBonus = usageTotal > 0 || (projectContext?.preferredLocator && projectContext.preferredLocator !== 'unknown')
288
+ ? (conventionAlignment - 0.5) * 0.04
289
+ : 0;
290
+ explanation.push(`Project Convention C: ${conventionAlignment.toFixed(3)} (${candidateKind}${projectContext?.preferredLocator ? `; preferred ${projectContext.preferredLocator}` : ''}${usageTotal > 0 ? `; observed ${usageTotal}` : ''})`);
291
+
292
+ // Calculate final composite score S(L)
293
+ const rawScore =
294
+ weights.wU * uniqueness +
295
+ weights.wI * identityMatch +
296
+ weights.wM * semanticMatch +
297
+ weights.wA * actionability +
298
+ weights.wH * historicalReliability -
299
+ weights.wD * volatilePenalty +
300
+ conventionBonus;
301
+
302
+ const finalScore = Math.max(0, Math.min(1.0, parseFloat(rawScore.toFixed(3))));
303
+
304
+ // Intent Gate: If candidate has no token overlap or conflicting identity,
305
+ // cap the transformed score to strictly prevent false repairs on missing/unrelated actions.
306
+ if (identityMatch <= 0.1) {
307
+ explanation.push('Intent Gated: Zero/conflicting identity match caps transformed confidence to 0.05');
308
+ return {
309
+ score: Math.min(0.15, finalScore),
310
+ transformedScore: 0.05,
311
+ calibratedProbability: 0.05,
312
+ uniqueness,
313
+ matchCount: matchingCount,
314
+ identityMatch,
315
+ semanticMatch,
316
+ actionability,
317
+ historicalReliability,
318
+ historicalExecutionReliability: historicalReliability,
319
+ volatilePenalty,
320
+ conventionAlignment,
321
+ explanation,
322
+ };
323
+ }
324
+
325
+ // Transformed confidence score via logistic sigmoid scaling
326
+ const transformedScore = parseFloat((1 / (1 + Math.exp(-6 * (finalScore - 0.65)))).toFixed(3));
327
+
328
+ return {
329
+ score: finalScore,
330
+ transformedScore,
331
+ calibratedProbability: transformedScore, // Backward compatibility alias
332
+ uniqueness,
333
+ matchCount: matchingCount,
334
+ identityMatch,
335
+ semanticMatch,
336
+ actionability,
337
+ historicalReliability,
338
+ historicalExecutionReliability: historicalReliability,
339
+ volatilePenalty,
340
+ conventionAlignment,
341
+ explanation,
342
+ };
343
+ }
344
+ }
@@ -0,0 +1,49 @@
1
+ import { TraceAdapter, ArchiveManifest } from './trace-adapter.js';
2
+ import { V8TraceAdapter } from './v8-adapter.js';
3
+ import { V4TraceAdapter } from './v4-adapter.js';
4
+ import { V9TraceAdapter } from './v9-adapter.js';
5
+ import { V10TraceAdapter } from './v10-adapter.js';
6
+ import { UnknownTraceAdapter } from './unknown-adapter.js';
7
+
8
+ export class TraceAdapterRegistry {
9
+ private static adapters: TraceAdapter[] = [
10
+ new V10TraceAdapter(),
11
+ new V9TraceAdapter(),
12
+ new V8TraceAdapter(),
13
+ new V4TraceAdapter(),
14
+ ];
15
+
16
+ private static fallbackAdapter = new UnknownTraceAdapter();
17
+
18
+ /**
19
+ * Registers a custom or extended trace adapter.
20
+ */
21
+ public static registerAdapter(adapter: TraceAdapter): void {
22
+ TraceAdapterRegistry.adapters.unshift(adapter);
23
+ }
24
+
25
+ /**
26
+ * Resolves the matching TraceAdapter for a given trace format version.
27
+ */
28
+ public static getAdapter(version: number): TraceAdapter {
29
+ for (const adapter of TraceAdapterRegistry.adapters) {
30
+ if (adapter.supportedFormatVersions.includes(version)) {
31
+ return adapter;
32
+ }
33
+ }
34
+ return TraceAdapterRegistry.fallbackAdapter;
35
+ }
36
+
37
+ /**
38
+ * Resolves the matching TraceAdapter for a given trace archive and sample lines.
39
+ */
40
+ public static resolveAdapter(manifest: ArchiveManifest, sampleLines: string[]): TraceAdapter {
41
+ for (const adapter of TraceAdapterRegistry.adapters) {
42
+ if (adapter.canParse(manifest, sampleLines)) {
43
+ return adapter;
44
+ }
45
+ }
46
+ return TraceAdapterRegistry.fallbackAdapter;
47
+ }
48
+ }
49
+
@@ -0,0 +1,28 @@
1
+ import { DiagnosticContext } from '../../core/types/diagnostic-context.js';
2
+
3
+ export interface ArchiveManifest {
4
+ archivePath: string;
5
+ entryNames: string[];
6
+ traceEntryName?: string | undefined;
7
+ networkEntryName?: string | undefined;
8
+ stacksEntryName?: string | undefined;
9
+ }
10
+
11
+ export interface AdapterValidationResult {
12
+ isValid: boolean;
13
+ errors: string[];
14
+ warnings: string[];
15
+ }
16
+
17
+ export interface TraceAdapter {
18
+ readonly adapterVersion: string;
19
+ readonly supportedFormatVersions: number[];
20
+ canParse(manifest: ArchiveManifest, sampleLines: string[]): boolean;
21
+ parse(
22
+ manifest: ArchiveManifest,
23
+ traceLines: string[],
24
+ networkLines: string[]
25
+ ): Promise<DiagnosticContext>;
26
+ validate(context: DiagnosticContext): AdapterValidationResult;
27
+ }
28
+
@@ -0,0 +1,50 @@
1
+ import { TraceAdapter, ArchiveManifest, AdapterValidationResult } from './trace-adapter.js';
2
+ import { DiagnosticContext } from '../../core/types/diagnostic-context.js';
3
+ import { VersionDetector } from '../version-detector.js';
4
+
5
+ export class UnknownTraceAdapter implements TraceAdapter {
6
+ public readonly adapterVersion = '1.0.0-unsupported';
7
+ public readonly supportedFormatVersions: number[] = [];
8
+
9
+ public canParse(_manifest: ArchiveManifest, _sampleLines: string[]): boolean {
10
+ return true; // Catch-all fallback
11
+ }
12
+
13
+ public async parse(
14
+ _manifest: ArchiveManifest,
15
+ traceLines: string[],
16
+ _networkLines: string[]
17
+ ): Promise<DiagnosticContext> {
18
+ const versionInfo = VersionDetector.detectFromLines(traceLines);
19
+
20
+ return {
21
+ playwrightVersion: versionInfo.playwrightVersion ?? 'unknown',
22
+ traceFormatVersion: versionInfo.traceFormatVersion,
23
+ failedAction: {
24
+ callId: 'unknown',
25
+ action: 'unknown',
26
+ errorMessage: `Unsupported trace format version: ${versionInfo.traceFormatVersion}`,
27
+ },
28
+ snapshots: {},
29
+ networkEvents: [],
30
+ consoleEvents: [],
31
+ failureCategory: 'UNSUPPORTED_TRACE_FORMAT',
32
+ evidenceCompleteness: {
33
+ domAvailable: false,
34
+ networkAvailable: false,
35
+ sourceAvailable: false,
36
+ },
37
+ };
38
+ }
39
+
40
+ public validate(context: DiagnosticContext): AdapterValidationResult {
41
+ return {
42
+ isValid: false,
43
+ errors: [
44
+ `UNSUPPORTED_TRACE_FORMAT: Trace format version ${context.traceFormatVersion} is not supported by any active trace adapter. Engine strictly abstains from inventing unverified diagnostics.`,
45
+ ],
46
+ warnings: [],
47
+ };
48
+ }
49
+ }
50
+
@@ -0,0 +1,39 @@
1
+ import { TraceAdapter, ArchiveManifest, AdapterValidationResult } from './trace-adapter.js';
2
+ import { DiagnosticContext } from '../../core/types/diagnostic-context.js';
3
+ import { TraceParser } from '../trace-parser.js';
4
+ import { VersionDetector } from '../version-detector.js';
5
+
6
+ export class V10TraceAdapter implements TraceAdapter {
7
+ public readonly adapterVersion = '1.0.0-v10';
8
+ public readonly supportedFormatVersions = [10];
9
+
10
+ public canParse(_manifest: ArchiveManifest, sampleLines: string[]): boolean {
11
+ const versionInfo = VersionDetector.detectFromLines(sampleLines);
12
+ return this.supportedFormatVersions.includes(versionInfo.traceFormatVersion);
13
+ }
14
+
15
+ public async parse(
16
+ _manifest: ArchiveManifest,
17
+ traceLines: string[],
18
+ networkLines: string[]
19
+ ): Promise<DiagnosticContext> {
20
+ const context = TraceParser.assembleDiagnosticContext(traceLines, networkLines);
21
+ return context;
22
+ }
23
+
24
+ public validate(context: DiagnosticContext): AdapterValidationResult {
25
+ const errors: string[] = [];
26
+ const warnings: string[] = [];
27
+
28
+ if (!context.failedAction.callId || context.failedAction.callId === 'unknown') {
29
+ warnings.push('Action callId could not be definitively extracted from modern v10 trace');
30
+ }
31
+
32
+ return {
33
+ isValid: errors.length === 0,
34
+ errors,
35
+ warnings,
36
+ };
37
+ }
38
+ }
39
+
@@ -0,0 +1,31 @@
1
+ import { TraceAdapter, ArchiveManifest, AdapterValidationResult } from './trace-adapter.js';
2
+ import { DiagnosticContext } from '../../core/types/diagnostic-context.js';
3
+ import { TraceParser } from '../trace-parser.js';
4
+ import { VersionDetector } from '../version-detector.js';
5
+
6
+ /** Compatibility adapter for Playwright 1.32-era trace format v4. */
7
+ export class V4TraceAdapter implements TraceAdapter {
8
+ public readonly adapterVersion = '1.0.0-v4';
9
+ public readonly supportedFormatVersions = [4];
10
+
11
+ public canParse(_manifest: ArchiveManifest, sampleLines: string[]): boolean {
12
+ const versionInfo = VersionDetector.detectFromLines(sampleLines);
13
+ return this.supportedFormatVersions.includes(versionInfo.traceFormatVersion);
14
+ }
15
+
16
+ public async parse(
17
+ _manifest: ArchiveManifest,
18
+ traceLines: string[],
19
+ networkLines: string[],
20
+ ): Promise<DiagnosticContext> {
21
+ return TraceParser.assembleDiagnosticContext(traceLines, networkLines);
22
+ }
23
+
24
+ public validate(context: DiagnosticContext): AdapterValidationResult {
25
+ const warnings: string[] = [];
26
+ if (!context.failedAction.callId || context.failedAction.callId === 'unknown') {
27
+ warnings.push('Action callId could not be definitively extracted from legacy v4 trace');
28
+ }
29
+ return { isValid: true, errors: [], warnings };
30
+ }
31
+ }
@@ -0,0 +1,42 @@
1
+ import { TraceAdapter, ArchiveManifest, AdapterValidationResult } from './trace-adapter.js';
2
+ import { DiagnosticContext } from '../../core/types/diagnostic-context.js';
3
+ import { TraceParser } from '../trace-parser.js';
4
+ import { VersionDetector } from '../version-detector.js';
5
+
6
+ export class V8TraceAdapter implements TraceAdapter {
7
+ public readonly adapterVersion = '1.0.0-v8';
8
+ public readonly supportedFormatVersions = [7, 8];
9
+
10
+ public canParse(_manifest: ArchiveManifest, sampleLines: string[]): boolean {
11
+ const versionInfo = VersionDetector.detectFromLines(sampleLines);
12
+ return this.supportedFormatVersions.includes(versionInfo.traceFormatVersion);
13
+ }
14
+
15
+ public async parse(
16
+ _manifest: ArchiveManifest,
17
+ traceLines: string[],
18
+ networkLines: string[]
19
+ ): Promise<DiagnosticContext> {
20
+ const context = TraceParser.assembleDiagnosticContext(traceLines, networkLines);
21
+ context.traceFormatVersion = 8;
22
+ return context;
23
+ }
24
+
25
+ public validate(context: DiagnosticContext): AdapterValidationResult {
26
+ const errors: string[] = [];
27
+ const warnings: string[] = [];
28
+
29
+ if (!context.failedAction.callId || context.failedAction.callId === 'unknown') {
30
+ warnings.push('Action callId could not be definitively extracted from v8 trace');
31
+ }
32
+ if (context.networkEvents.length === 0) {
33
+ warnings.push('No network events parsed from v8 network stream');
34
+ }
35
+
36
+ return {
37
+ isValid: errors.length === 0,
38
+ errors,
39
+ warnings,
40
+ };
41
+ }
42
+ }
@@ -0,0 +1,39 @@
1
+ import { TraceAdapter, ArchiveManifest, AdapterValidationResult } from './trace-adapter.js';
2
+ import { DiagnosticContext } from '../../core/types/diagnostic-context.js';
3
+ import { TraceParser } from '../trace-parser.js';
4
+ import { VersionDetector } from '../version-detector.js';
5
+
6
+ export class V9TraceAdapter implements TraceAdapter {
7
+ public readonly adapterVersion = '1.0.0-v9';
8
+ public readonly supportedFormatVersions = [9];
9
+
10
+ public canParse(_manifest: ArchiveManifest, sampleLines: string[]): boolean {
11
+ const versionInfo = VersionDetector.detectFromLines(sampleLines);
12
+ return this.supportedFormatVersions.includes(versionInfo.traceFormatVersion);
13
+ }
14
+
15
+ public async parse(
16
+ _manifest: ArchiveManifest,
17
+ traceLines: string[],
18
+ networkLines: string[]
19
+ ): Promise<DiagnosticContext> {
20
+ const context = TraceParser.assembleDiagnosticContext(traceLines, networkLines);
21
+ return context;
22
+ }
23
+
24
+ public validate(context: DiagnosticContext): AdapterValidationResult {
25
+ const errors: string[] = [];
26
+ const warnings: string[] = [];
27
+
28
+ if (!context.failedAction.action || context.failedAction.action === 'unknown') {
29
+ warnings.push('Action name was unknown in v9 format stream');
30
+ }
31
+
32
+ return {
33
+ isValid: errors.length === 0,
34
+ errors,
35
+ warnings,
36
+ };
37
+ }
38
+ }
39
+