tabwright 1.0.0 → 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 (568) hide show
  1. package/dist/agent-skills/tabwright/SKILL.md +3 -0
  2. package/dist/aria-snapshot.d.ts +0 -1
  3. package/dist/aria-snapshot.js +9 -1
  4. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.d.ts +0 -1
  5. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.js +0 -1
  6. package/dist/bippy.js +5 -5
  7. package/dist/browser-config.d.ts +0 -1
  8. package/dist/browser-config.js +0 -1
  9. package/dist/browser-install.d.ts +0 -1
  10. package/dist/browser-install.js +0 -1
  11. package/dist/browser-launch.d.ts +0 -1
  12. package/dist/browser-launch.js +0 -1
  13. package/dist/capability-agent-skill.d.ts +0 -1
  14. package/dist/capability-agent-skill.js +0 -1
  15. package/dist/capability-auth-state.d.ts +0 -1
  16. package/dist/capability-auth-state.js +0 -1
  17. package/dist/capability-auth.d.ts +0 -1
  18. package/dist/capability-auth.js +0 -1
  19. package/dist/capability-options.d.ts +0 -1
  20. package/dist/capability-options.js +0 -1
  21. package/dist/capability-package.d.ts +0 -1
  22. package/dist/capability-package.js +47 -2
  23. package/dist/capability-registry.d.ts +0 -1
  24. package/dist/capability-registry.js +0 -1
  25. package/dist/capability-runner.d.ts +0 -1
  26. package/dist/capability-runner.js +0 -1
  27. package/dist/capability-studio.d.ts +0 -1
  28. package/dist/capability-studio.js +0 -1
  29. package/dist/cdp-log.d.ts +0 -1
  30. package/dist/cdp-log.js +0 -1
  31. package/dist/cdp-relay.d.ts +0 -1
  32. package/dist/cdp-relay.js +0 -1
  33. package/dist/cdp-session.d.ts +0 -1
  34. package/dist/cdp-session.js +0 -1
  35. package/dist/cdp-types.d.ts +0 -1
  36. package/dist/cdp-types.js +0 -1
  37. package/dist/chrome-discovery.d.ts +0 -1
  38. package/dist/chrome-discovery.js +0 -1
  39. package/dist/clean-html.d.ts +0 -1
  40. package/dist/clean-html.js +0 -1
  41. package/dist/cli.d.ts +0 -1
  42. package/dist/cli.js +10 -56
  43. package/dist/cloud-client.d.ts +0 -1
  44. package/dist/cloud-client.js +0 -1
  45. package/dist/create-logger.d.ts +0 -1
  46. package/dist/create-logger.js +0 -1
  47. package/dist/debugger-examples-types.d.ts +0 -1
  48. package/dist/debugger-examples-types.js +0 -1
  49. package/dist/debugger-examples.d.ts +0 -1
  50. package/dist/debugger-examples.js +0 -1
  51. package/dist/debugger.d.ts +0 -1
  52. package/dist/debugger.js +0 -1
  53. package/dist/diff-utils.d.ts +0 -1
  54. package/dist/diff-utils.js +0 -1
  55. package/dist/doctor.d.ts +0 -1
  56. package/dist/doctor.js +5 -7
  57. package/dist/editor-examples.d.ts +0 -1
  58. package/dist/editor-examples.js +0 -1
  59. package/dist/editor.d.ts +0 -1
  60. package/dist/editor.js +0 -1
  61. package/dist/env-compat.d.ts +0 -1
  62. package/dist/env-compat.js +0 -1
  63. package/dist/executor.d.ts +0 -1
  64. package/dist/executor.js +1 -2
  65. package/dist/extension/background.js +10 -6
  66. package/dist/extension/manifest.json +1 -1
  67. package/dist/extension/options.js +1 -1
  68. package/dist/extension/rrweb-recorder.js +1 -1
  69. package/dist/ghost-browser.d.ts +0 -1
  70. package/dist/ghost-browser.js +0 -1
  71. package/dist/ghost-cursor-controller.d.ts +0 -1
  72. package/dist/ghost-cursor-controller.js +0 -1
  73. package/dist/ghost-cursor.d.ts +0 -1
  74. package/dist/ghost-cursor.js +0 -1
  75. package/dist/htmlrewrite.d.ts +0 -1
  76. package/dist/htmlrewrite.js +0 -1
  77. package/dist/index.d.ts +0 -1
  78. package/dist/index.js +0 -1
  79. package/dist/kill-port.d.ts +0 -1
  80. package/dist/kill-port.js +0 -1
  81. package/dist/kitty-graphics.d.ts +0 -1
  82. package/dist/kitty-graphics.js +0 -1
  83. package/dist/mcp.d.ts +0 -1
  84. package/dist/mcp.js +0 -1
  85. package/dist/package-paths.d.ts +0 -1
  86. package/dist/package-paths.js +0 -1
  87. package/dist/page-markdown.d.ts +0 -1
  88. package/dist/page-markdown.js +0 -1
  89. package/dist/performance-examples.d.ts +0 -1
  90. package/dist/performance-examples.js +0 -1
  91. package/dist/playwright-import.d.ts +0 -1
  92. package/dist/playwright-import.js +0 -1
  93. package/dist/product-paths.d.ts +0 -1
  94. package/dist/product-paths.js +0 -1
  95. package/dist/protocol.d.ts +0 -1
  96. package/dist/protocol.js +0 -1
  97. package/dist/react-source.d.ts +0 -1
  98. package/dist/react-source.js +0 -1
  99. package/dist/readability.js +4 -4
  100. package/dist/relay-client.d.ts +0 -1
  101. package/dist/relay-client.js +0 -1
  102. package/dist/relay-state.d.ts +0 -1
  103. package/dist/relay-state.js +0 -1
  104. package/dist/replay-ai-index.d.ts +0 -1
  105. package/dist/replay-ai-index.js +0 -1
  106. package/dist/replay-eval.d.ts +0 -1
  107. package/dist/replay-eval.js +0 -1
  108. package/dist/replay-handoff.d.ts +0 -1
  109. package/dist/replay-handoff.js +0 -1
  110. package/dist/replay-workflow-compiler.d.ts +0 -1
  111. package/dist/replay-workflow-compiler.js +0 -1
  112. package/dist/rrweb-recording-relay.d.ts +0 -1
  113. package/dist/rrweb-recording-relay.js +0 -1
  114. package/dist/rrweb-recording.d.ts +0 -1
  115. package/dist/rrweb-recording.js +0 -1
  116. package/dist/scoped-fs.d.ts +0 -1
  117. package/dist/scoped-fs.js +0 -1
  118. package/dist/selector-generator.js +2 -2
  119. package/dist/start-relay-server.d.ts +0 -1
  120. package/dist/start-relay-server.js +0 -1
  121. package/dist/styles-examples.d.ts +0 -1
  122. package/dist/styles-examples.js +0 -1
  123. package/dist/styles.d.ts +0 -1
  124. package/dist/styles.js +0 -1
  125. package/dist/tabwright-agent-skill.d.ts +0 -1
  126. package/dist/tabwright-agent-skill.js +0 -1
  127. package/dist/test-declarations.d.ts +0 -1
  128. package/dist/test-declarations.js +0 -1
  129. package/dist/utils.d.ts +0 -1
  130. package/dist/utils.js +2 -2
  131. package/dist/wait-for-page-load.d.ts +0 -1
  132. package/dist/wait-for-page-load.js +0 -1
  133. package/dist/workflow-capability.d.ts +0 -1
  134. package/dist/workflow-capability.js +0 -1
  135. package/package.json +8 -4
  136. package/readme.md +43 -0
  137. package/src/skill.md +5 -2
  138. package/dist/aria-snapshot.d.ts.map +0 -1
  139. package/dist/aria-snapshot.js.map +0 -1
  140. package/dist/aria-snapshot.test.d.ts +0 -2
  141. package/dist/aria-snapshot.test.d.ts.map +0 -1
  142. package/dist/aria-snapshot.test.js +0 -270
  143. package/dist/aria-snapshot.test.js.map +0 -1
  144. package/dist/aria-snapshot.unit.test.d.ts +0 -2
  145. package/dist/aria-snapshot.unit.test.d.ts.map +0 -1
  146. package/dist/aria-snapshot.unit.test.js +0 -542
  147. package/dist/aria-snapshot.unit.test.js.map +0 -1
  148. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.d.ts.map +0 -1
  149. package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.js.map +0 -1
  150. package/dist/browser-config.d.ts.map +0 -1
  151. package/dist/browser-config.js.map +0 -1
  152. package/dist/browser-install.d.ts.map +0 -1
  153. package/dist/browser-install.js.map +0 -1
  154. package/dist/browser-launch.d.ts.map +0 -1
  155. package/dist/browser-launch.js.map +0 -1
  156. package/dist/builtin-capabilities.d.ts +0 -28
  157. package/dist/builtin-capabilities.d.ts.map +0 -1
  158. package/dist/builtin-capabilities.js +0 -2673
  159. package/dist/builtin-capabilities.js.map +0 -1
  160. package/dist/capability-agent-skill.d.ts.map +0 -1
  161. package/dist/capability-agent-skill.js.map +0 -1
  162. package/dist/capability-auth-state.d.ts.map +0 -1
  163. package/dist/capability-auth-state.js.map +0 -1
  164. package/dist/capability-auth.d.ts.map +0 -1
  165. package/dist/capability-auth.js.map +0 -1
  166. package/dist/capability-cli-confirmation.test.d.ts +0 -2
  167. package/dist/capability-cli-confirmation.test.d.ts.map +0 -1
  168. package/dist/capability-cli-confirmation.test.js +0 -79
  169. package/dist/capability-cli-confirmation.test.js.map +0 -1
  170. package/dist/capability-options.d.ts.map +0 -1
  171. package/dist/capability-options.js.map +0 -1
  172. package/dist/capability-options.test.d.ts +0 -2
  173. package/dist/capability-options.test.d.ts.map +0 -1
  174. package/dist/capability-options.test.js +0 -81
  175. package/dist/capability-options.test.js.map +0 -1
  176. package/dist/capability-package.d.ts.map +0 -1
  177. package/dist/capability-package.js.map +0 -1
  178. package/dist/capability-package.test.d.ts +0 -2
  179. package/dist/capability-package.test.d.ts.map +0 -1
  180. package/dist/capability-package.test.js +0 -179
  181. package/dist/capability-package.test.js.map +0 -1
  182. package/dist/capability-registry.d.ts.map +0 -1
  183. package/dist/capability-registry.js.map +0 -1
  184. package/dist/capability-registry.test.d.ts +0 -2
  185. package/dist/capability-registry.test.d.ts.map +0 -1
  186. package/dist/capability-registry.test.js +0 -1683
  187. package/dist/capability-registry.test.js.map +0 -1
  188. package/dist/capability-runner.d.ts.map +0 -1
  189. package/dist/capability-runner.js.map +0 -1
  190. package/dist/capability-search-relevance.test.d.ts +0 -2
  191. package/dist/capability-search-relevance.test.d.ts.map +0 -1
  192. package/dist/capability-search-relevance.test.js +0 -67
  193. package/dist/capability-search-relevance.test.js.map +0 -1
  194. package/dist/capability-studio.d.ts.map +0 -1
  195. package/dist/capability-studio.js.map +0 -1
  196. package/dist/capability-studio.test.d.ts +0 -2
  197. package/dist/capability-studio.test.d.ts.map +0 -1
  198. package/dist/capability-studio.test.js +0 -41
  199. package/dist/capability-studio.test.js.map +0 -1
  200. package/dist/cdp-log.d.ts.map +0 -1
  201. package/dist/cdp-log.js.map +0 -1
  202. package/dist/cdp-log.test.d.ts +0 -2
  203. package/dist/cdp-log.test.d.ts.map +0 -1
  204. package/dist/cdp-log.test.js +0 -109
  205. package/dist/cdp-log.test.js.map +0 -1
  206. package/dist/cdp-relay.d.ts.map +0 -1
  207. package/dist/cdp-relay.js.map +0 -1
  208. package/dist/cdp-session.d.ts.map +0 -1
  209. package/dist/cdp-session.js.map +0 -1
  210. package/dist/cdp-types.d.ts.map +0 -1
  211. package/dist/cdp-types.js.map +0 -1
  212. package/dist/channel-owner-inspect.test.d.ts +0 -2
  213. package/dist/channel-owner-inspect.test.d.ts.map +0 -1
  214. package/dist/channel-owner-inspect.test.js +0 -75
  215. package/dist/channel-owner-inspect.test.js.map +0 -1
  216. package/dist/chrome-discovery.d.ts.map +0 -1
  217. package/dist/chrome-discovery.js.map +0 -1
  218. package/dist/chrome-discovery.test.d.ts +0 -2
  219. package/dist/chrome-discovery.test.d.ts.map +0 -1
  220. package/dist/chrome-discovery.test.js +0 -41
  221. package/dist/chrome-discovery.test.js.map +0 -1
  222. package/dist/clean-html.d.ts.map +0 -1
  223. package/dist/clean-html.js.map +0 -1
  224. package/dist/cli-help.test.d.ts +0 -2
  225. package/dist/cli-help.test.d.ts.map +0 -1
  226. package/dist/cli-help.test.js +0 -98
  227. package/dist/cli-help.test.js.map +0 -1
  228. package/dist/cli.d.ts.map +0 -1
  229. package/dist/cli.js.map +0 -1
  230. package/dist/cloud-client.d.ts.map +0 -1
  231. package/dist/cloud-client.js.map +0 -1
  232. package/dist/create-logger.d.ts.map +0 -1
  233. package/dist/create-logger.js.map +0 -1
  234. package/dist/debugger-examples-types.d.ts.map +0 -1
  235. package/dist/debugger-examples-types.js.map +0 -1
  236. package/dist/debugger-examples.d.ts.map +0 -1
  237. package/dist/debugger-examples.js.map +0 -1
  238. package/dist/debugger.d.ts.map +0 -1
  239. package/dist/debugger.js.map +0 -1
  240. package/dist/diff-utils.d.ts.map +0 -1
  241. package/dist/diff-utils.js.map +0 -1
  242. package/dist/diff-utils.test.d.ts +0 -2
  243. package/dist/diff-utils.test.d.ts.map +0 -1
  244. package/dist/diff-utils.test.js +0 -137
  245. package/dist/diff-utils.test.js.map +0 -1
  246. package/dist/doctor.d.ts.map +0 -1
  247. package/dist/doctor.js.map +0 -1
  248. package/dist/doctor.test.d.ts +0 -2
  249. package/dist/doctor.test.d.ts.map +0 -1
  250. package/dist/doctor.test.js +0 -208
  251. package/dist/doctor.test.js.map +0 -1
  252. package/dist/editor-examples.d.ts.map +0 -1
  253. package/dist/editor-examples.js.map +0 -1
  254. package/dist/editor.d.ts.map +0 -1
  255. package/dist/editor.js.map +0 -1
  256. package/dist/env-compat.d.ts.map +0 -1
  257. package/dist/env-compat.js.map +0 -1
  258. package/dist/executor.d.ts.map +0 -1
  259. package/dist/executor.js.map +0 -1
  260. package/dist/executor.unit.test.d.ts +0 -2
  261. package/dist/executor.unit.test.d.ts.map +0 -1
  262. package/dist/executor.unit.test.js +0 -143
  263. package/dist/executor.unit.test.js.map +0 -1
  264. package/dist/extension-connection.test.d.ts +0 -2
  265. package/dist/extension-connection.test.d.ts.map +0 -1
  266. package/dist/extension-connection.test.js +0 -708
  267. package/dist/extension-connection.test.js.map +0 -1
  268. package/dist/extension-icon-warning.test.d.ts +0 -2
  269. package/dist/extension-icon-warning.test.d.ts.map +0 -1
  270. package/dist/extension-icon-warning.test.js +0 -33
  271. package/dist/extension-icon-warning.test.js.map +0 -1
  272. package/dist/ghost-browser.d.ts.map +0 -1
  273. package/dist/ghost-browser.js.map +0 -1
  274. package/dist/ghost-cursor-controller.d.ts.map +0 -1
  275. package/dist/ghost-cursor-controller.js.map +0 -1
  276. package/dist/ghost-cursor.d.ts.map +0 -1
  277. package/dist/ghost-cursor.js.map +0 -1
  278. package/dist/htmlrewrite.d.ts.map +0 -1
  279. package/dist/htmlrewrite.js.map +0 -1
  280. package/dist/htmlrewrite.test.d.ts +0 -2
  281. package/dist/htmlrewrite.test.d.ts.map +0 -1
  282. package/dist/htmlrewrite.test.js +0 -7975
  283. package/dist/htmlrewrite.test.js.map +0 -1
  284. package/dist/index.d.ts.map +0 -1
  285. package/dist/index.js.map +0 -1
  286. package/dist/kill-port.d.ts.map +0 -1
  287. package/dist/kill-port.js.map +0 -1
  288. package/dist/kitty-graphics.d.ts.map +0 -1
  289. package/dist/kitty-graphics.js.map +0 -1
  290. package/dist/kitty-graphics.test.d.ts +0 -2
  291. package/dist/kitty-graphics.test.d.ts.map +0 -1
  292. package/dist/kitty-graphics.test.js +0 -125
  293. package/dist/kitty-graphics.test.js.map +0 -1
  294. package/dist/locator-selector.test.d.ts +0 -2
  295. package/dist/locator-selector.test.d.ts.map +0 -1
  296. package/dist/locator-selector.test.js +0 -98
  297. package/dist/locator-selector.test.js.map +0 -1
  298. package/dist/mcp-client.d.ts +0 -20
  299. package/dist/mcp-client.d.ts.map +0 -1
  300. package/dist/mcp-client.js +0 -56
  301. package/dist/mcp-client.js.map +0 -1
  302. package/dist/mcp.d.ts.map +0 -1
  303. package/dist/mcp.js.map +0 -1
  304. package/dist/on-mouse-action.test.d.ts +0 -2
  305. package/dist/on-mouse-action.test.d.ts.map +0 -1
  306. package/dist/on-mouse-action.test.js +0 -180
  307. package/dist/on-mouse-action.test.js.map +0 -1
  308. package/dist/options-page.test.d.ts +0 -2
  309. package/dist/options-page.test.d.ts.map +0 -1
  310. package/dist/options-page.test.js +0 -773
  311. package/dist/options-page.test.js.map +0 -1
  312. package/dist/package-paths.d.ts.map +0 -1
  313. package/dist/package-paths.js.map +0 -1
  314. package/dist/page-markdown.d.ts.map +0 -1
  315. package/dist/page-markdown.js.map +0 -1
  316. package/dist/performance-examples.d.ts.map +0 -1
  317. package/dist/performance-examples.js.map +0 -1
  318. package/dist/playwright-import.d.ts.map +0 -1
  319. package/dist/playwright-import.js.map +0 -1
  320. package/dist/popup-relocation.test.d.ts +0 -7
  321. package/dist/popup-relocation.test.d.ts.map +0 -1
  322. package/dist/popup-relocation.test.js +0 -139
  323. package/dist/popup-relocation.test.js.map +0 -1
  324. package/dist/product-paths.d.ts.map +0 -1
  325. package/dist/product-paths.js.map +0 -1
  326. package/dist/product-paths.test.d.ts +0 -2
  327. package/dist/product-paths.test.d.ts.map +0 -1
  328. package/dist/product-paths.test.js +0 -39
  329. package/dist/product-paths.test.js.map +0 -1
  330. package/dist/protocol.d.ts.map +0 -1
  331. package/dist/protocol.js.map +0 -1
  332. package/dist/protocol.test.d.ts +0 -2
  333. package/dist/protocol.test.d.ts.map +0 -1
  334. package/dist/protocol.test.js +0 -31
  335. package/dist/protocol.test.js.map +0 -1
  336. package/dist/react-source.d.ts.map +0 -1
  337. package/dist/react-source.js.map +0 -1
  338. package/dist/relay-client.d.ts.map +0 -1
  339. package/dist/relay-client.js.map +0 -1
  340. package/dist/relay-client.test.d.ts +0 -2
  341. package/dist/relay-client.test.d.ts.map +0 -1
  342. package/dist/relay-client.test.js +0 -305
  343. package/dist/relay-client.test.js.map +0 -1
  344. package/dist/relay-core.test.d.ts +0 -2
  345. package/dist/relay-core.test.d.ts.map +0 -1
  346. package/dist/relay-core.test.js +0 -1427
  347. package/dist/relay-core.test.js.map +0 -1
  348. package/dist/relay-navigation.test.d.ts +0 -2
  349. package/dist/relay-navigation.test.d.ts.map +0 -1
  350. package/dist/relay-navigation.test.js +0 -661
  351. package/dist/relay-navigation.test.js.map +0 -1
  352. package/dist/relay-session.test.d.ts +0 -2
  353. package/dist/relay-session.test.d.ts.map +0 -1
  354. package/dist/relay-session.test.js +0 -1121
  355. package/dist/relay-session.test.js.map +0 -1
  356. package/dist/relay-state.d.ts.map +0 -1
  357. package/dist/relay-state.js.map +0 -1
  358. package/dist/relay-state.test.d.ts +0 -2
  359. package/dist/relay-state.test.d.ts.map +0 -1
  360. package/dist/relay-state.test.js +0 -594
  361. package/dist/relay-state.test.js.map +0 -1
  362. package/dist/replay-ai-index.d.ts.map +0 -1
  363. package/dist/replay-ai-index.js.map +0 -1
  364. package/dist/replay-ai-index.test.d.ts +0 -2
  365. package/dist/replay-ai-index.test.d.ts.map +0 -1
  366. package/dist/replay-ai-index.test.js +0 -255
  367. package/dist/replay-ai-index.test.js.map +0 -1
  368. package/dist/replay-cli.test.d.ts +0 -2
  369. package/dist/replay-cli.test.d.ts.map +0 -1
  370. package/dist/replay-cli.test.js +0 -275
  371. package/dist/replay-cli.test.js.map +0 -1
  372. package/dist/replay-eval.d.ts.map +0 -1
  373. package/dist/replay-eval.js.map +0 -1
  374. package/dist/replay-handoff.d.ts.map +0 -1
  375. package/dist/replay-handoff.js.map +0 -1
  376. package/dist/replay-handoff.test.d.ts +0 -2
  377. package/dist/replay-handoff.test.d.ts.map +0 -1
  378. package/dist/replay-handoff.test.js +0 -123
  379. package/dist/replay-handoff.test.js.map +0 -1
  380. package/dist/replay-workflow-compiler.d.ts.map +0 -1
  381. package/dist/replay-workflow-compiler.js.map +0 -1
  382. package/dist/replay-workflow-compiler.test.d.ts +0 -2
  383. package/dist/replay-workflow-compiler.test.d.ts.map +0 -1
  384. package/dist/replay-workflow-compiler.test.js +0 -223
  385. package/dist/replay-workflow-compiler.test.js.map +0 -1
  386. package/dist/rrweb-recording-relay.d.ts.map +0 -1
  387. package/dist/rrweb-recording-relay.js.map +0 -1
  388. package/dist/rrweb-recording-relay.test.d.ts +0 -2
  389. package/dist/rrweb-recording-relay.test.d.ts.map +0 -1
  390. package/dist/rrweb-recording-relay.test.js +0 -85
  391. package/dist/rrweb-recording-relay.test.js.map +0 -1
  392. package/dist/rrweb-recording.d.ts.map +0 -1
  393. package/dist/rrweb-recording.js.map +0 -1
  394. package/dist/scoped-fs.d.ts.map +0 -1
  395. package/dist/scoped-fs.js.map +0 -1
  396. package/dist/scoped-fs.test.d.ts +0 -5
  397. package/dist/scoped-fs.test.d.ts.map +0 -1
  398. package/dist/scoped-fs.test.js +0 -73
  399. package/dist/scoped-fs.test.js.map +0 -1
  400. package/dist/skill-stub.test.d.ts +0 -2
  401. package/dist/skill-stub.test.d.ts.map +0 -1
  402. package/dist/skill-stub.test.js +0 -22
  403. package/dist/skill-stub.test.js.map +0 -1
  404. package/dist/snapshot-tools.test.d.ts +0 -2
  405. package/dist/snapshot-tools.test.d.ts.map +0 -1
  406. package/dist/snapshot-tools.test.js +0 -856
  407. package/dist/snapshot-tools.test.js.map +0 -1
  408. package/dist/start-relay-server.d.ts.map +0 -1
  409. package/dist/start-relay-server.js.map +0 -1
  410. package/dist/styles-examples.d.ts.map +0 -1
  411. package/dist/styles-examples.js.map +0 -1
  412. package/dist/styles.d.ts.map +0 -1
  413. package/dist/styles.js.map +0 -1
  414. package/dist/tabwright-agent-skill.d.ts.map +0 -1
  415. package/dist/tabwright-agent-skill.js.map +0 -1
  416. package/dist/tabwright-agent-skill.test.d.ts +0 -2
  417. package/dist/tabwright-agent-skill.test.d.ts.map +0 -1
  418. package/dist/tabwright-agent-skill.test.js +0 -51
  419. package/dist/tabwright-agent-skill.test.js.map +0 -1
  420. package/dist/test-declarations.d.ts.map +0 -1
  421. package/dist/test-declarations.js.map +0 -1
  422. package/dist/test-utils.d.ts +0 -69
  423. package/dist/test-utils.d.ts.map +0 -1
  424. package/dist/test-utils.js +0 -448
  425. package/dist/test-utils.js.map +0 -1
  426. package/dist/test-utils.test.d.ts +0 -2
  427. package/dist/test-utils.test.d.ts.map +0 -1
  428. package/dist/test-utils.test.js +0 -55
  429. package/dist/test-utils.test.js.map +0 -1
  430. package/dist/utils.d.ts.map +0 -1
  431. package/dist/utils.js.map +0 -1
  432. package/dist/wait-for-page-load.d.ts.map +0 -1
  433. package/dist/wait-for-page-load.js.map +0 -1
  434. package/dist/workflow-capability.d.ts.map +0 -1
  435. package/dist/workflow-capability.js.map +0 -1
  436. package/dist/workflow-script-flow.test.d.ts +0 -2
  437. package/dist/workflow-script-flow.test.d.ts.map +0 -1
  438. package/dist/workflow-script-flow.test.js +0 -285
  439. package/dist/workflow-script-flow.test.js.map +0 -1
  440. package/src/__snapshots__/x.com.processed.html +0 -1003
  441. package/src/__snapshots__/x.com.processed.withStyles.html +0 -2720
  442. package/src/a11y-client.ts +0 -241
  443. package/src/agent-skills/conan-config/SKILL.md +0 -141
  444. package/src/agent-skills/conan-config/agents/openai.yaml +0 -4
  445. package/src/aria-snapshot.test.ts +0 -311
  446. package/src/aria-snapshot.ts +0 -1681
  447. package/src/aria-snapshot.unit.test.ts +0 -615
  448. package/src/aria-snapshots/github-interactive.txt +0 -193
  449. package/src/aria-snapshots/github-raw.txt +0 -309
  450. package/src/aria-snapshots/hackernews-interactive.txt +0 -477
  451. package/src/aria-snapshots/hackernews-raw.txt +0 -428
  452. package/src/aria-snapshots/prosemirror-interactive.txt +0 -66
  453. package/src/aria-snapshots/prosemirror-raw.txt +0 -145
  454. package/src/assets/aria-labels-hacker-news.png +0 -0
  455. package/src/assets/aria-labels-old-reddit.png +0 -0
  456. package/src/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.ts +0 -5
  457. package/src/assets/cursors/screen-studio/pointer-macos-tahoe.svg +0 -18
  458. package/src/assets/x.com.html +0 -32946
  459. package/src/browser-config.ts +0 -179
  460. package/src/browser-install.ts +0 -284
  461. package/src/browser-launch.ts +0 -75
  462. package/src/builtin-capabilities.ts +0 -2765
  463. package/src/capability-agent-skill.ts +0 -305
  464. package/src/capability-auth-state.ts +0 -197
  465. package/src/capability-auth.ts +0 -249
  466. package/src/capability-cli-confirmation.test.ts +0 -90
  467. package/src/capability-options.test.ts +0 -89
  468. package/src/capability-options.ts +0 -57
  469. package/src/capability-package.test.ts +0 -204
  470. package/src/capability-package.ts +0 -555
  471. package/src/capability-registry.test.ts +0 -1905
  472. package/src/capability-registry.ts +0 -1234
  473. package/src/capability-runner.ts +0 -801
  474. package/src/capability-search-relevance.test.ts +0 -73
  475. package/src/capability-studio.test.ts +0 -45
  476. package/src/capability-studio.ts +0 -641
  477. package/src/cdp-log.test.ts +0 -131
  478. package/src/cdp-log.ts +0 -112
  479. package/src/cdp-relay.ts +0 -2944
  480. package/src/cdp-session.ts +0 -77
  481. package/src/cdp-types.ts +0 -158
  482. package/src/channel-owner-inspect.test.ts +0 -94
  483. package/src/chrome-discovery.test.ts +0 -50
  484. package/src/chrome-discovery.ts +0 -220
  485. package/src/clean-html.ts +0 -141
  486. package/src/cli-help.test.ts +0 -123
  487. package/src/cli.ts +0 -3181
  488. package/src/cloud-client.ts +0 -179
  489. package/src/create-logger.ts +0 -38
  490. package/src/debugger-examples-types.ts +0 -16
  491. package/src/debugger-examples.ts +0 -66
  492. package/src/debugger.ts +0 -708
  493. package/src/diff-utils.test.ts +0 -152
  494. package/src/diff-utils.ts +0 -70
  495. package/src/doctor.test.ts +0 -244
  496. package/src/doctor.ts +0 -321
  497. package/src/editor-examples.ts +0 -158
  498. package/src/editor.ts +0 -426
  499. package/src/env-compat.ts +0 -28
  500. package/src/executor.ts +0 -1824
  501. package/src/executor.unit.test.ts +0 -168
  502. package/src/extension-connection.test.ts +0 -855
  503. package/src/extension-icon-warning.test.ts +0 -45
  504. package/src/ghost-browser.ts +0 -149
  505. package/src/ghost-cursor-client.ts +0 -494
  506. package/src/ghost-cursor-controller.ts +0 -129
  507. package/src/ghost-cursor.ts +0 -123
  508. package/src/htmlrewrite.test.ts +0 -8008
  509. package/src/htmlrewrite.ts +0 -390
  510. package/src/index.ts +0 -53
  511. package/src/kill-port.ts +0 -219
  512. package/src/kitty-graphics.test.ts +0 -139
  513. package/src/kitty-graphics.ts +0 -79
  514. package/src/locator-selector.test.ts +0 -119
  515. package/src/mcp-client.ts +0 -78
  516. package/src/mcp.ts +0 -629
  517. package/src/on-mouse-action.test.ts +0 -226
  518. package/src/options-page.test.ts +0 -839
  519. package/src/package-paths.ts +0 -38
  520. package/src/page-markdown.ts +0 -240
  521. package/src/performance-examples.ts +0 -186
  522. package/src/playwright-import.ts +0 -59
  523. package/src/popup-relocation.test.ts +0 -163
  524. package/src/product-paths.test.ts +0 -47
  525. package/src/product-paths.ts +0 -28
  526. package/src/protocol.test.ts +0 -52
  527. package/src/protocol.ts +0 -351
  528. package/src/react-source.ts +0 -379
  529. package/src/relay-client.test.ts +0 -375
  530. package/src/relay-client.ts +0 -572
  531. package/src/relay-core.test.ts +0 -1603
  532. package/src/relay-navigation.test.ts +0 -790
  533. package/src/relay-session.test.ts +0 -1375
  534. package/src/relay-state.test.ts +0 -729
  535. package/src/relay-state.ts +0 -561
  536. package/src/replay-ai-index.test.ts +0 -278
  537. package/src/replay-ai-index.ts +0 -872
  538. package/src/replay-cli.test.ts +0 -325
  539. package/src/replay-eval.ts +0 -1039
  540. package/src/replay-handoff.test.ts +0 -163
  541. package/src/replay-handoff.ts +0 -109
  542. package/src/replay-workflow-compiler.test.ts +0 -250
  543. package/src/replay-workflow-compiler.ts +0 -700
  544. package/src/resource.md +0 -409
  545. package/src/rrweb-recording-relay.test.ts +0 -99
  546. package/src/rrweb-recording-relay.ts +0 -400
  547. package/src/rrweb-recording.ts +0 -322
  548. package/src/scoped-fs.test.ts +0 -80
  549. package/src/scoped-fs.ts +0 -420
  550. package/src/skill-stub.test.ts +0 -24
  551. package/src/snapshot-tools.test.ts +0 -1017
  552. package/src/snapshots/hacker-news-accessibility-full.md +0 -81
  553. package/src/snapshots/hacker-news-accessibility-interactive.md +0 -43
  554. package/src/snapshots/page-markdown-output.txt +0 -16
  555. package/src/snapshots/shadcn-ui-accessibility-full.md +0 -201
  556. package/src/snapshots/shadcn-ui-accessibility-interactive.md +0 -109
  557. package/src/start-relay-server.ts +0 -69
  558. package/src/styles-examples.ts +0 -84
  559. package/src/styles.ts +0 -343
  560. package/src/tabwright-agent-skill.test.ts +0 -61
  561. package/src/tabwright-agent-skill.ts +0 -105
  562. package/src/test-declarations.ts +0 -13
  563. package/src/test-utils.test.ts +0 -70
  564. package/src/test-utils.ts +0 -566
  565. package/src/utils.ts +0 -78
  566. package/src/wait-for-page-load.ts +0 -198
  567. package/src/workflow-capability.ts +0 -417
  568. package/src/workflow-script-flow.test.ts +0 -388
package/src/test-utils.ts DELETED
@@ -1,566 +0,0 @@
1
- import { exec } from 'node:child_process'
2
- import { promisify } from 'node:util'
3
- import http from 'node:http'
4
- import net from 'node:net'
5
- import { chromium, type BrowserContext } from '@xmorse/playwright-core'
6
- import path from 'node:path'
7
- import fs from 'node:fs'
8
- import os from 'node:os'
9
- import { startTabwrightCDPRelayServer, type RelayServer } from './cdp-relay.js'
10
- import { createFileLogger } from './create-logger.js'
11
- import { killPortProcess } from './kill-port.js'
12
-
13
- const execAsync = promisify(exec)
14
- const extensionBuildQueues: Map<string, Promise<void>> = new Map()
15
- const EXTENSION_SERVICE_WORKER_TIMEOUT_MS = 15_000
16
-
17
- export function getLocalChromeExecutable(): string | undefined {
18
- const candidates = [
19
- process.env.PLAYWRIGHT_CHROME_EXECUTABLE,
20
- '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
21
- '/Applications/Chromium.app/Contents/MacOS/Chromium',
22
- '/usr/bin/google-chrome',
23
- '/usr/bin/google-chrome-stable',
24
- '/usr/bin/chromium',
25
- '/usr/bin/chromium-browser',
26
- 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
27
- 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
28
- ].filter((candidate): candidate is string => {
29
- return Boolean(candidate)
30
- })
31
-
32
- return candidates.find((candidate) => {
33
- return fs.existsSync(candidate)
34
- })
35
- }
36
-
37
- export function getLegacyExtensionLaunchArgs({ extensionPaths }: { extensionPaths: string[] }): string[] {
38
- const resolvedExtensionPaths = extensionPaths.map((extensionPath) => {
39
- return path.resolve(extensionPath)
40
- })
41
- const legacyExtensionPaths = resolvedExtensionPaths.join(',')
42
-
43
- return [
44
- `--disable-extensions-except=${legacyExtensionPaths}`,
45
- `--load-extension=${legacyExtensionPaths}`,
46
- ]
47
- }
48
-
49
- export function isExtensionLoadUnavailableError(error: unknown): boolean {
50
- const message = error instanceof Error ? error.message : String(error)
51
- return (
52
- message.includes('Method not found') ||
53
- message.includes("'Extensions.loadUnpacked' wasn't found") ||
54
- message.includes('-32601')
55
- )
56
- }
57
-
58
- async function loadUnpackedExtensionsThroughCdp({
59
- browserContext,
60
- extensionPaths,
61
- }: {
62
- browserContext: BrowserContext
63
- extensionPaths: string[]
64
- }): Promise<void> {
65
- const browser = browserContext.browser()
66
- if (!browser) {
67
- throw new Error('Persistent browser context has no browser connection')
68
- }
69
-
70
- const session = await browser.newBrowserCDPSession()
71
- try {
72
- await Promise.all(
73
- extensionPaths.map(async (extensionPath) => {
74
- await session.send('Extensions.loadUnpacked', { path: path.resolve(extensionPath) })
75
- }),
76
- )
77
- } finally {
78
- await session.detach().catch((error: unknown) => {
79
- console.error('Failed to detach test extension CDP session:', error)
80
- })
81
- }
82
- }
83
-
84
- async function launchTestBrowser({
85
- userDataDir,
86
- args,
87
- }: {
88
- userDataDir: string
89
- args: string[]
90
- }): Promise<BrowserContext> {
91
- const chromeExecutable = getLocalChromeExecutable()
92
- return await chromium.launchPersistentContext(userDataDir, {
93
- ...(chromeExecutable ? { executablePath: chromeExecutable } : { channel: 'chromium' }),
94
- headless: !process.env.HEADFUL,
95
- colorScheme: 'dark',
96
- ignoreDefaultArgs: ['--disable-extensions'],
97
- args,
98
- })
99
- }
100
-
101
- export async function launchPersistentContextWithExtensions({
102
- userDataDir,
103
- extensionPaths,
104
- }: {
105
- userDataDir: string
106
- extensionPaths: string[]
107
- }): Promise<BrowserContext> {
108
- const browserContext = await launchTestBrowser({
109
- userDataDir,
110
- // Chrome 137+ ignores --load-extension for branded builds. Its supported
111
- // Extensions.loadUnpacked replacement requires this opt-in switch.
112
- args: ['--enable-unsafe-extension-debugging'],
113
- })
114
-
115
- try {
116
- await loadUnpackedExtensionsThroughCdp({ browserContext, extensionPaths })
117
- return browserContext
118
- } catch (error: unknown) {
119
- await browserContext.close()
120
- if (!isExtensionLoadUnavailableError(error)) {
121
- throw new Error(`Failed to load unpacked test extensions: ${extensionPaths.join(', ')}`, { cause: error })
122
- }
123
-
124
- // Older Chrome/Chromium does not expose Extensions.loadUnpacked. Relaunch
125
- // the same isolated profile with the legacy flags it still supports.
126
- return await launchTestBrowser({
127
- userDataDir,
128
- args: getLegacyExtensionLaunchArgs({ extensionPaths }),
129
- })
130
- }
131
- }
132
-
133
- async function buildExtension({ port, distDir }: { port: number; distDir: string }): Promise<void> {
134
- const previous = extensionBuildQueues.get(distDir) || Promise.resolve()
135
- const buildPromise = previous
136
- .catch((error) => {
137
- console.error('Previous extension build failed:', error)
138
- })
139
- .then(async () => {
140
- // Build into a per-port dist to avoid parallel test runs overwriting each other.
141
- await execAsync(`TESTING=1 TABWRIGHT_PORT=${port} TABWRIGHT_EXTENSION_DIST=${distDir} pnpm build`, {
142
- cwd: '../extension',
143
- })
144
- })
145
-
146
- extensionBuildQueues.set(
147
- distDir,
148
- buildPromise.finally(() => {}),
149
- )
150
- await buildPromise
151
- }
152
-
153
- export async function getExtensionServiceWorker(context: BrowserContext) {
154
- const serviceWorkers = context.serviceWorkers().filter((sw) => sw.url().startsWith('chrome-extension://'))
155
- if (serviceWorkers.length === 0) {
156
- await context
157
- .waitForEvent('serviceworker', {
158
- predicate: (sw) => sw.url().startsWith('chrome-extension://'),
159
- timeout: EXTENSION_SERVICE_WORKER_TIMEOUT_MS,
160
- })
161
- .catch((error: unknown) => {
162
- throw new Error(
163
- `No extension service worker appeared within ${EXTENSION_SERVICE_WORKER_TIMEOUT_MS}ms`,
164
- { cause: error },
165
- )
166
- })
167
- }
168
-
169
- // Check all chrome-extension service workers for the Tabwright one (the one
170
- // that exposes toggleExtensionForActiveTab). This handles cases where
171
- // additional test fixture extensions are loaded alongside Tabwright.
172
- for (let i = 0; i < 50; i++) {
173
- const allSws = context.serviceWorkers().filter((sw) => sw.url().startsWith('chrome-extension://'))
174
- for (const sw of allSws) {
175
- try {
176
- const isReady = await sw.evaluate(() => {
177
- // @ts-ignore
178
- return typeof globalThis.toggleExtensionForActiveTab === 'function'
179
- })
180
- if (isReady) {
181
- return sw
182
- }
183
- } catch {
184
- // Service worker might not be ready yet
185
- }
186
- }
187
- await new Promise((r) => setTimeout(r, 100))
188
- }
189
-
190
- const extensionWorkerUrls = context
191
- .serviceWorkers()
192
- .filter((sw) => {
193
- return sw.url().startsWith('chrome-extension://')
194
- })
195
- .map((sw) => {
196
- return sw.url()
197
- })
198
- throw new Error(
199
- `Tabwright extension service worker did not become ready within ${EXTENSION_SERVICE_WORKER_TIMEOUT_MS}ms. Visible extension workers: ${extensionWorkerUrls.join(', ') || 'none'}`,
200
- )
201
- }
202
-
203
- export interface TestContext {
204
- browserContext: BrowserContext
205
- userDataDir: string
206
- relayServer: RelayServer
207
- }
208
-
209
- export async function setupTestContext({
210
- port,
211
- tempDirPrefix,
212
- toggleExtension = false,
213
- additionalExtensions = [],
214
- }: {
215
- port: number
216
- tempDirPrefix: string
217
- /** Create initial page and toggle extension on it */
218
- toggleExtension?: boolean
219
- /** Additional extension paths to load alongside the main Tabwright extension */
220
- additionalExtensions?: string[]
221
- }): Promise<TestContext> {
222
- await killPortProcess({ port }).catch(() => {})
223
-
224
- // Use a port-scoped dist folder so parallel tests don't replace each other's extension builds.
225
- const distDir = `dist-${port}`
226
-
227
- console.log('Building extension...')
228
- await buildExtension({ port, distDir })
229
- console.log('Extension built')
230
-
231
- const localLogPath = path.join(process.cwd(), 'relay-server.log')
232
- const logger = createFileLogger({ logFilePath: localLogPath })
233
- const relayServer = await startTabwrightCDPRelayServer({ port, logger })
234
-
235
- const userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), tempDirPrefix))
236
- const extensionPath = path.resolve('../extension', distDir)
237
- try {
238
- const browserContext = await launchPersistentContextWithExtensions({
239
- userDataDir,
240
- extensionPaths: [extensionPath, ...additionalExtensions],
241
- })
242
-
243
- try {
244
- if (toggleExtension) {
245
- const serviceWorker = await getExtensionServiceWorker(browserContext)
246
- const page = await browserContext.newPage()
247
- await page.goto('about:blank')
248
- await serviceWorker.evaluate(async () => {
249
- await (globalThis as any).toggleExtensionForActiveTab()
250
- })
251
- }
252
-
253
- return { browserContext, userDataDir, relayServer }
254
- } catch (error) {
255
- await browserContext.close().catch((closeError: unknown) => {
256
- console.error('Failed to close browser after test setup error:', closeError)
257
- })
258
- throw error
259
- }
260
- } catch (error) {
261
- relayServer.close()
262
- try {
263
- fs.rmSync(userDataDir, { recursive: true, force: true })
264
- } catch (cleanupError) {
265
- console.error('Failed to clean test profile after setup error:', cleanupError)
266
- }
267
- throw error
268
- }
269
- }
270
-
271
- export async function cleanupTestContext(
272
- ctx: TestContext | null,
273
- cleanup?: (() => Promise<void>) | null,
274
- ): Promise<void> {
275
- if (ctx?.browserContext) {
276
- await ctx.browserContext.close()
277
- }
278
- if (ctx?.relayServer) {
279
- ctx.relayServer.close()
280
- }
281
-
282
- if (ctx?.userDataDir) {
283
- try {
284
- fs.rmSync(ctx.userDataDir, { recursive: true, force: true })
285
- } catch (e) {
286
- console.error('Failed to cleanup user data dir:', e)
287
- }
288
- }
289
- if (cleanup) {
290
- await cleanup()
291
- }
292
- }
293
-
294
- export type SseServerState = {
295
- connected: boolean
296
- finished: boolean
297
- writeCount: number
298
- closed: boolean
299
- }
300
-
301
- export type SseServer = {
302
- baseUrl: string
303
- getState: () => SseServerState
304
- close: () => Promise<void>
305
- }
306
-
307
- export async function createSseServer(): Promise<SseServer> {
308
- let sseResponse: http.ServerResponse | null = null
309
- let sseFinished = false
310
- let sseClosed = false
311
- let sseWriteCount = 0
312
- let sseInterval: NodeJS.Timeout | null = null
313
- const openResponses: Set<http.ServerResponse> = new Set()
314
- const openSockets: Set<net.Socket> = new Set()
315
-
316
- const server = http.createServer((req, res) => {
317
- if (req.url === '/') {
318
- res.writeHead(200, { 'Content-Type': 'text/html' })
319
- res.end(`<!doctype html>
320
- <html>
321
- <head>
322
- <meta charset="utf-8" />
323
- <title>SSE Test</title>
324
- </head>
325
- <body>
326
- <script>
327
- window.__sseMessages = [];
328
- window.__sseOpen = false;
329
- window.__sseError = null;
330
- window.startSse = function () {
331
- const source = new EventSource('/sse');
332
- window.__sseSource = source;
333
- source.onopen = function () {
334
- window.__sseOpen = true;
335
- };
336
- source.onmessage = function (event) {
337
- window.__sseMessages.push(event.data);
338
- };
339
- source.onerror = function () {
340
- window.__sseError = 'SSE error';
341
- };
342
- return true;
343
- };
344
- window.stopSse = function () {
345
- if (window.__sseSource) {
346
- window.__sseSource.close();
347
- }
348
- };
349
- </script>
350
- </body>
351
- </html>`)
352
- return
353
- }
354
-
355
- if (req.url === '/sse') {
356
- res.writeHead(200, {
357
- 'Content-Type': 'text/event-stream',
358
- 'Cache-Control': 'no-cache, no-transform',
359
- Connection: 'keep-alive',
360
- })
361
- res.write('retry: 1000\n\n')
362
- res.write('data: hello\n\n')
363
- sseResponse = res
364
- sseWriteCount += 1
365
- openResponses.add(res)
366
-
367
- res.on('finish', () => {
368
- sseFinished = true
369
- })
370
- res.on('close', () => {
371
- sseClosed = true
372
- openResponses.delete(res)
373
- if (sseInterval) {
374
- clearInterval(sseInterval)
375
- sseInterval = null
376
- }
377
- })
378
-
379
- sseInterval = setInterval(() => {
380
- res.write('data: ping\n\n')
381
- sseWriteCount += 1
382
- }, 200)
383
- return
384
- }
385
-
386
- res.writeHead(404)
387
- res.end('Not found')
388
- })
389
-
390
- server.on('connection', (socket) => {
391
- openSockets.add(socket)
392
- socket.on('close', () => {
393
- openSockets.delete(socket)
394
- })
395
- })
396
-
397
- await new Promise<void>((resolve) => {
398
- server.listen(0, '127.0.0.1', () => {
399
- resolve()
400
- })
401
- })
402
-
403
- const address = server.address()
404
- if (!address || typeof address === 'string') {
405
- throw new Error('Failed to bind SSE server')
406
- }
407
-
408
- return {
409
- baseUrl: `http://127.0.0.1:${address.port}`,
410
- getState: () => ({
411
- connected: sseResponse !== null,
412
- finished: sseFinished,
413
- closed: sseClosed,
414
- writeCount: sseWriteCount,
415
- }),
416
- close: async () => {
417
- for (const response of openResponses) {
418
- response.destroy()
419
- }
420
- for (const socket of openSockets) {
421
- socket.destroy()
422
- }
423
- if (sseInterval) {
424
- clearInterval(sseInterval)
425
- sseInterval = null
426
- }
427
- await new Promise<void>((resolve, reject) => {
428
- server.close((error) => {
429
- if (error) {
430
- reject(error)
431
- return
432
- }
433
- resolve()
434
- })
435
- })
436
- },
437
- }
438
- }
439
-
440
- export async function withTimeout<T>({
441
- promise,
442
- timeoutMs,
443
- errorMessage,
444
- }: {
445
- promise: Promise<T>
446
- timeoutMs: number
447
- errorMessage: string
448
- }): Promise<T> {
449
- return await new Promise<T>((resolve, reject) => {
450
- const timeoutId = setTimeout(() => {
451
- reject(new Error(errorMessage))
452
- }, timeoutMs)
453
-
454
- promise
455
- .then((value) => {
456
- clearTimeout(timeoutId)
457
- resolve(value)
458
- })
459
- .catch((error) => {
460
- clearTimeout(timeoutId)
461
- reject(error)
462
- })
463
- })
464
- }
465
-
466
- /** Tagged template for inline JS code strings used in MCP execute calls */
467
- export function js(strings: TemplateStringsArray, ...values: unknown[]): string {
468
- return strings.reduce((result, str, i) => result + str + (values[i] || ''), '')
469
- }
470
-
471
- export function tryJsonParse(str: string) {
472
- try {
473
- return JSON.parse(str)
474
- } catch {
475
- return str
476
- }
477
- }
478
-
479
- /**
480
- * Safely close a browser connected via connectOverCDP.
481
- *
482
- * Playwright's CRConnection uses async message handling (messageWrap) that can cause
483
- * a race condition where _onClose() runs before all pending _onMessage() handlers complete.
484
- * This results in "Assertion error" from crConnection.js when a CDP response arrives
485
- * after callbacks were cleared by dispose().
486
- *
487
- * This helper waits for the message queue to drain before closing, avoiding the race.
488
- *
489
- * @param browser - Browser instance from chromium.connectOverCDP()
490
- * @param drainDelayMs - Time to wait for pending messages to be processed (default: 50ms)
491
- */
492
- export async function safeCloseCDPBrowser(
493
- browser: Awaited<ReturnType<typeof import('@xmorse/playwright-core').chromium.connectOverCDP>>,
494
- drainDelayMs = 50,
495
- ): Promise<void> {
496
- // Wait for any queued message handlers to run
497
- // This gives Playwright's messageWrap time to process pending CDP responses
498
- await new Promise((r) => setTimeout(r, drainDelayMs))
499
- await browser.close()
500
- }
501
-
502
- export type SimpleServer = {
503
- baseUrl: string
504
- close: () => Promise<void>
505
- }
506
-
507
- /** Minimal local HTTP server for tests that need cross-origin iframes or custom routes */
508
- export async function createSimpleServer({ routes }: { routes: Record<string, string> }): Promise<SimpleServer> {
509
- const openSockets: Set<net.Socket> = new Set()
510
- const server = http.createServer((req, res) => {
511
- const url = req.url || '/'
512
- const body = routes[url]
513
- if (!body) {
514
- res.writeHead(404, { 'Content-Type': 'text/plain' })
515
- res.end('not found')
516
- return
517
- }
518
- res.writeHead(200, { 'Content-Type': 'text/html' })
519
- res.end(body)
520
- })
521
-
522
- server.on('connection', (socket) => {
523
- openSockets.add(socket)
524
- socket.on('close', () => {
525
- openSockets.delete(socket)
526
- })
527
- })
528
-
529
- await new Promise<void>((resolve) => {
530
- server.listen(0, '127.0.0.1', () => {
531
- resolve()
532
- })
533
- })
534
-
535
- const address = server.address()
536
- if (!address || typeof address === 'string') {
537
- await new Promise<void>((resolve, reject) => {
538
- server.close((error) => {
539
- if (error) {
540
- reject(error)
541
- return
542
- }
543
- resolve()
544
- })
545
- })
546
- throw new Error('Failed to start test server')
547
- }
548
-
549
- return {
550
- baseUrl: `http://127.0.0.1:${address.port}`,
551
- close: async () => {
552
- for (const socket of openSockets) {
553
- socket.destroy()
554
- }
555
- await new Promise<void>((resolve, reject) => {
556
- server.close((error) => {
557
- if (error) {
558
- reject(error)
559
- return
560
- }
561
- resolve()
562
- })
563
- })
564
- },
565
- }
566
- }
package/src/utils.ts DELETED
@@ -1,78 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
- import { fileURLToPath } from 'node:url'
4
- import './env-compat.js'
5
- import { getTabwrightUserDataDir } from './product-paths.js'
6
-
7
- // Tabwright extension IDs - used for validation and Chrome flag commands
8
- export const EXTENSION_IDS = [
9
- 'jfeammnjpkecdekppnclgkkffahnhfhe', // Production (Chrome Web Store)
10
- 'pebbngnfojnignonigcnkdilknapkgid', // Dev extension (stable ID from manifest key)
11
- ]
12
-
13
- /**
14
- * Parse a relay host string into HTTP and WebSocket base URLs.
15
- * Supports both plain hostnames (appends port) and full URLs (uses as-is).
16
- *
17
- * Examples:
18
- * "192.168.1.10" → http://192.168.1.10:19988, ws://192.168.1.10:19988
19
- * "https://my-machine-tunnel.traforo.dev" → https://my-machine-tunnel.traforo.dev, wss://my-machine-tunnel.traforo.dev
20
- */
21
- export function parseRelayHost(host: string, port: number = 19988): { httpBaseUrl: string; wsBaseUrl: string } {
22
- if (host.startsWith('https://') || host.startsWith('http://')) {
23
- const url = new URL(host)
24
- const httpBaseUrl = url.origin
25
- const wsProtocol = url.protocol === 'https:' ? 'wss:' : 'ws:'
26
- const wsBaseUrl = `${wsProtocol}//${url.host}`
27
- return { httpBaseUrl, wsBaseUrl }
28
- }
29
- return {
30
- httpBaseUrl: `http://${host}:${port}`,
31
- wsBaseUrl: `ws://${host}:${port}`,
32
- }
33
- }
34
-
35
- export function getCdpUrl({
36
- port = 19988,
37
- host = '127.0.0.1',
38
- token,
39
- extensionId,
40
- }: {
41
- port?: number
42
- host?: string
43
- token?: string
44
- extensionId?: string | null
45
- } = {}) {
46
- const id = `${Math.random().toString(36).substring(2, 15)}_${Date.now()}`
47
- const params = new URLSearchParams()
48
- if (token) {
49
- params.set('token', token)
50
- }
51
- if (extensionId) {
52
- params.set('extensionId', extensionId)
53
- }
54
- const queryString = params.toString()
55
- const suffix = queryString ? `?${queryString}` : ''
56
- const { wsBaseUrl } = parseRelayHost(host, port)
57
- return `${wsBaseUrl}/cdp/${id}${suffix}`
58
- }
59
-
60
- export function shouldAutoEnableTabwright(): boolean {
61
- return (process.env.TABWRIGHT_AUTO_ENABLE || process.env.PLAYWRITER_AUTO_ENABLE)?.toLowerCase() !== 'false'
62
- }
63
-
64
- // Existing installations continue using their legacy data directory until users migrate it.
65
- const LOG_BASE_DIR = getTabwrightUserDataDir()
66
- export const LOG_FILE_PATH =
67
- process.env.TABWRIGHT_LOG_FILE_PATH || process.env.PLAYWRITER_LOG_FILE_PATH || path.join(LOG_BASE_DIR, 'relay-server.log')
68
- export const LOG_CDP_FILE_PATH =
69
- process.env.TABWRIGHT_CDP_LOG_FILE_PATH ||
70
- process.env.PLAYWRITER_CDP_LOG_FILE_PATH ||
71
- path.join(path.dirname(LOG_FILE_PATH), 'cdp.jsonl')
72
-
73
- const packageJsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')
74
- export const VERSION = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')).version as string
75
-
76
- export function sleep(ms: number): Promise<void> {
77
- return new Promise((resolve) => setTimeout(resolve, ms))
78
- }