agent-web-interface 4.4.0 → 4.5.1

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 (334) hide show
  1. package/README.md +35 -34
  2. package/dist/src/browser/browser-session-config.d.ts +33 -0
  3. package/dist/src/browser/browser-session-config.d.ts.map +1 -0
  4. package/dist/src/browser/browser-session-config.js +25 -0
  5. package/dist/src/browser/browser-session-config.js.map +1 -0
  6. package/dist/src/browser/ensure-browser.d.ts +12 -27
  7. package/dist/src/browser/ensure-browser.d.ts.map +1 -1
  8. package/dist/src/browser/ensure-browser.js +131 -39
  9. package/dist/src/browser/ensure-browser.js.map +1 -1
  10. package/dist/src/browser/index.d.ts +2 -1
  11. package/dist/src/browser/index.d.ts.map +1 -1
  12. package/dist/src/browser/index.js +1 -0
  13. package/dist/src/browser/index.js.map +1 -1
  14. package/dist/src/browser/page-network-recorder.d.ts +95 -0
  15. package/dist/src/browser/page-network-recorder.d.ts.map +1 -0
  16. package/dist/src/browser/page-network-recorder.js +306 -0
  17. package/dist/src/browser/page-network-recorder.js.map +1 -0
  18. package/dist/src/browser/session-manager.d.ts +20 -0
  19. package/dist/src/browser/session-manager.d.ts.map +1 -1
  20. package/dist/src/browser/session-manager.js +169 -20
  21. package/dist/src/browser/session-manager.js.map +1 -1
  22. package/dist/src/browser/session-manager.types.d.ts +14 -2
  23. package/dist/src/browser/session-manager.types.d.ts.map +1 -1
  24. package/dist/src/browser/session-manager.types.js +5 -1
  25. package/dist/src/browser/session-manager.types.js.map +1 -1
  26. package/dist/src/cli/args.d.ts +12 -18
  27. package/dist/src/cli/args.d.ts.map +1 -1
  28. package/dist/src/cli/args.js +35 -40
  29. package/dist/src/cli/args.js.map +1 -1
  30. package/dist/src/form/constraint-extraction.d.ts +5 -0
  31. package/dist/src/form/constraint-extraction.d.ts.map +1 -1
  32. package/dist/src/form/constraint-extraction.js +13 -6
  33. package/dist/src/form/constraint-extraction.js.map +1 -1
  34. package/dist/src/form/field-extractor.d.ts.map +1 -1
  35. package/dist/src/form/field-extractor.js +14 -7
  36. package/dist/src/form/field-extractor.js.map +1 -1
  37. package/dist/src/form/form-state.d.ts.map +1 -1
  38. package/dist/src/form/form-state.js +16 -4
  39. package/dist/src/form/form-state.js.map +1 -1
  40. package/dist/src/gateway/http-gateway.d.ts +56 -0
  41. package/dist/src/gateway/http-gateway.d.ts.map +1 -0
  42. package/dist/src/gateway/http-gateway.js +229 -0
  43. package/dist/src/gateway/http-gateway.js.map +1 -0
  44. package/dist/src/gateway/json-rpc-errors.d.ts +6 -0
  45. package/dist/src/gateway/json-rpc-errors.d.ts.map +1 -0
  46. package/dist/src/gateway/json-rpc-errors.js +11 -0
  47. package/dist/src/gateway/json-rpc-errors.js.map +1 -0
  48. package/dist/src/gateway/session-router.d.ts +80 -0
  49. package/dist/src/gateway/session-router.d.ts.map +1 -0
  50. package/dist/src/gateway/session-router.js +177 -0
  51. package/dist/src/gateway/session-router.js.map +1 -0
  52. package/dist/src/http-entry.d.ts +20 -0
  53. package/dist/src/http-entry.d.ts.map +1 -0
  54. package/dist/src/http-entry.js +112 -0
  55. package/dist/src/http-entry.js.map +1 -0
  56. package/dist/src/index.d.ts +1 -10
  57. package/dist/src/index.d.ts.map +1 -1
  58. package/dist/src/index.js +25 -232
  59. package/dist/src/index.js.map +1 -1
  60. package/dist/src/lib/text-utils.d.ts +0 -24
  61. package/dist/src/lib/text-utils.d.ts.map +1 -1
  62. package/dist/src/lib/text-utils.js +2 -38
  63. package/dist/src/lib/text-utils.js.map +1 -1
  64. package/dist/src/observation/eid-linker.d.ts.map +1 -1
  65. package/dist/src/observation/eid-linker.js +1 -21
  66. package/dist/src/observation/eid-linker.js.map +1 -1
  67. package/dist/src/server/index.d.ts +0 -1
  68. package/dist/src/server/index.d.ts.map +1 -1
  69. package/dist/src/server/index.js +0 -1
  70. package/dist/src/server/index.js.map +1 -1
  71. package/dist/src/server/mcp-server.d.ts +6 -2
  72. package/dist/src/server/mcp-server.d.ts.map +1 -1
  73. package/dist/src/server/mcp-server.js +3 -91
  74. package/dist/src/server/mcp-server.js.map +1 -1
  75. package/dist/src/server/server-config.d.ts +4 -20
  76. package/dist/src/server/server-config.d.ts.map +1 -1
  77. package/dist/src/server/server-config.js +6 -50
  78. package/dist/src/server/server-config.js.map +1 -1
  79. package/dist/src/server/tool-registrar.types.d.ts +25 -0
  80. package/dist/src/server/tool-registrar.types.d.ts.map +1 -0
  81. package/dist/src/server/tool-registrar.types.js +10 -0
  82. package/dist/src/server/tool-registrar.types.js.map +1 -0
  83. package/dist/src/server/tool-result-handler.d.ts +61 -0
  84. package/dist/src/server/tool-result-handler.d.ts.map +1 -0
  85. package/dist/src/server/tool-result-handler.js +155 -0
  86. package/dist/src/server/tool-result-handler.js.map +1 -0
  87. package/dist/src/session/session-controller.d.ts +124 -0
  88. package/dist/src/session/session-controller.d.ts.map +1 -0
  89. package/dist/src/session/session-controller.js +276 -0
  90. package/dist/src/session/session-controller.js.map +1 -0
  91. package/dist/src/shared/services/index.d.ts +0 -2
  92. package/dist/src/shared/services/index.d.ts.map +1 -1
  93. package/dist/src/shared/services/index.js +0 -2
  94. package/dist/src/shared/services/index.js.map +1 -1
  95. package/dist/src/shared/version.d.ts +10 -0
  96. package/dist/src/shared/version.d.ts.map +1 -0
  97. package/dist/src/shared/version.js +32 -0
  98. package/dist/src/shared/version.js.map +1 -0
  99. package/dist/src/snapshot/element-resolver.d.ts +3 -2
  100. package/dist/src/snapshot/element-resolver.d.ts.map +1 -1
  101. package/dist/src/snapshot/element-resolver.js +83 -8
  102. package/dist/src/snapshot/element-resolver.js.map +1 -1
  103. package/dist/src/snapshot/extractors/attribute-extractor.d.ts.map +1 -1
  104. package/dist/src/snapshot/extractors/attribute-extractor.js +4 -0
  105. package/dist/src/snapshot/extractors/attribute-extractor.js.map +1 -1
  106. package/dist/src/snapshot/extractors/layout-extractor.d.ts +9 -7
  107. package/dist/src/snapshot/extractors/layout-extractor.d.ts.map +1 -1
  108. package/dist/src/snapshot/extractors/layout-extractor.js +34 -19
  109. package/dist/src/snapshot/extractors/layout-extractor.js.map +1 -1
  110. package/dist/src/snapshot/extractors/state-extractor.d.ts +2 -2
  111. package/dist/src/snapshot/extractors/state-extractor.d.ts.map +1 -1
  112. package/dist/src/snapshot/extractors/state-extractor.js +22 -2
  113. package/dist/src/snapshot/extractors/state-extractor.js.map +1 -1
  114. package/dist/src/snapshot/extractors/types.d.ts +6 -0
  115. package/dist/src/snapshot/extractors/types.d.ts.map +1 -1
  116. package/dist/src/snapshot/extractors/types.js.map +1 -1
  117. package/dist/src/snapshot/snapshot-compiler.d.ts.map +1 -1
  118. package/dist/src/snapshot/snapshot-compiler.js +15 -2
  119. package/dist/src/snapshot/snapshot-compiler.js.map +1 -1
  120. package/dist/src/snapshot/snapshot.types.d.ts +10 -1
  121. package/dist/src/snapshot/snapshot.types.d.ts.map +1 -1
  122. package/dist/src/snapshot/snapshot.types.js.map +1 -1
  123. package/dist/src/state/actionables-filter.d.ts.map +1 -1
  124. package/dist/src/state/actionables-filter.js +7 -3
  125. package/dist/src/state/actionables-filter.js.map +1 -1
  126. package/dist/src/state/atoms-extractor.d.ts.map +1 -1
  127. package/dist/src/state/atoms-extractor.js +3 -23
  128. package/dist/src/state/atoms-extractor.js.map +1 -1
  129. package/dist/src/state/diff-engine.d.ts.map +1 -1
  130. package/dist/src/state/diff-engine.js +6 -33
  131. package/dist/src/state/diff-engine.js.map +1 -1
  132. package/dist/src/state/element-identity.d.ts +3 -6
  133. package/dist/src/state/element-identity.d.ts.map +1 -1
  134. package/dist/src/state/element-identity.js +10 -7
  135. package/dist/src/state/element-identity.js.map +1 -1
  136. package/dist/src/state/element-ref.types.d.ts +5 -27
  137. package/dist/src/state/element-ref.types.d.ts.map +1 -1
  138. package/dist/src/state/state-manager.d.ts.map +1 -1
  139. package/dist/src/state/state-manager.js +3 -1
  140. package/dist/src/state/state-manager.js.map +1 -1
  141. package/dist/src/state/state-renderer.d.ts.map +1 -1
  142. package/dist/src/state/state-renderer.js +3 -1
  143. package/dist/src/state/state-renderer.js.map +1 -1
  144. package/dist/src/state/types.d.ts +2 -1
  145. package/dist/src/state/types.d.ts.map +1 -1
  146. package/dist/src/state/url-sanitization.d.ts +1 -1
  147. package/dist/src/state/url-sanitization.d.ts.map +1 -1
  148. package/dist/src/state/url-sanitization.js +29 -13
  149. package/dist/src/state/url-sanitization.js.map +1 -1
  150. package/dist/src/tools/action-context.d.ts +6 -11
  151. package/dist/src/tools/action-context.d.ts.map +1 -1
  152. package/dist/src/tools/action-context.js +10 -19
  153. package/dist/src/tools/action-context.js.map +1 -1
  154. package/dist/src/tools/action-stabilization.d.ts.map +1 -1
  155. package/dist/src/tools/action-stabilization.js +6 -0
  156. package/dist/src/tools/action-stabilization.js.map +1 -1
  157. package/dist/src/tools/browser-tools.d.ts +4 -2
  158. package/dist/src/tools/browser-tools.d.ts.map +1 -1
  159. package/dist/src/tools/browser-tools.js +7 -3
  160. package/dist/src/tools/browser-tools.js.map +1 -1
  161. package/dist/src/tools/canvas-tools.d.ts +2 -1
  162. package/dist/src/tools/canvas-tools.d.ts.map +1 -1
  163. package/dist/src/tools/canvas-tools.js +5 -7
  164. package/dist/src/tools/canvas-tools.js.map +1 -1
  165. package/dist/src/tools/errors.d.ts +2 -34
  166. package/dist/src/tools/errors.d.ts.map +1 -1
  167. package/dist/src/tools/errors.js +1 -44
  168. package/dist/src/tools/errors.js.map +1 -1
  169. package/dist/src/tools/execute-action.d.ts +4 -3
  170. package/dist/src/tools/execute-action.d.ts.map +1 -1
  171. package/dist/src/tools/execute-action.js +32 -23
  172. package/dist/src/tools/execute-action.js.map +1 -1
  173. package/dist/src/tools/form-tools.d.ts +3 -8
  174. package/dist/src/tools/form-tools.d.ts.map +1 -1
  175. package/dist/src/tools/form-tools.js +38 -18
  176. package/dist/src/tools/form-tools.js.map +1 -1
  177. package/dist/src/tools/index.d.ts +8 -6
  178. package/dist/src/tools/index.d.ts.map +1 -1
  179. package/dist/src/tools/index.js +10 -10
  180. package/dist/src/tools/index.js.map +1 -1
  181. package/dist/src/tools/interaction-tools.d.ts +6 -5
  182. package/dist/src/tools/interaction-tools.d.ts.map +1 -1
  183. package/dist/src/tools/interaction-tools.js +29 -32
  184. package/dist/src/tools/interaction-tools.js.map +1 -1
  185. package/dist/src/tools/navigation-tools.d.ts +7 -13
  186. package/dist/src/tools/navigation-tools.d.ts.map +1 -1
  187. package/dist/src/tools/navigation-tools.js +57 -59
  188. package/dist/src/tools/navigation-tools.js.map +1 -1
  189. package/dist/src/tools/network-tools.d.ts +10 -0
  190. package/dist/src/tools/network-tools.d.ts.map +1 -0
  191. package/dist/src/tools/network-tools.js +117 -0
  192. package/dist/src/tools/network-tools.js.map +1 -0
  193. package/dist/src/tools/observation-tools.d.ts +6 -5
  194. package/dist/src/tools/observation-tools.d.ts.map +1 -1
  195. package/dist/src/tools/observation-tools.js +30 -34
  196. package/dist/src/tools/observation-tools.js.map +1 -1
  197. package/dist/src/tools/readability-tools.d.ts +16 -0
  198. package/dist/src/tools/readability-tools.d.ts.map +1 -0
  199. package/dist/src/tools/readability-tools.js +45 -0
  200. package/dist/src/tools/readability-tools.js.map +1 -0
  201. package/dist/src/tools/response-builder.d.ts +20 -32
  202. package/dist/src/tools/response-builder.d.ts.map +1 -1
  203. package/dist/src/tools/response-builder.js +31 -47
  204. package/dist/src/tools/response-builder.js.map +1 -1
  205. package/dist/src/tools/stale-element-retry.d.ts.map +1 -1
  206. package/dist/src/tools/stale-element-retry.js +37 -2
  207. package/dist/src/tools/stale-element-retry.js.map +1 -1
  208. package/dist/src/tools/tool-context.d.ts +4 -36
  209. package/dist/src/tools/tool-context.d.ts.map +1 -1
  210. package/dist/src/tools/tool-context.js +6 -75
  211. package/dist/src/tools/tool-context.js.map +1 -1
  212. package/dist/src/tools/tool-context.types.d.ts +147 -0
  213. package/dist/src/tools/tool-context.types.d.ts.map +1 -0
  214. package/dist/src/tools/tool-context.types.js +11 -0
  215. package/dist/src/tools/tool-context.types.js.map +1 -0
  216. package/dist/src/tools/tool-registration.d.ts +25 -0
  217. package/dist/src/tools/tool-registration.d.ts.map +1 -0
  218. package/dist/src/tools/tool-registration.js +195 -0
  219. package/dist/src/tools/tool-registration.js.map +1 -0
  220. package/dist/src/tools/tool-schemas.d.ts +178 -1947
  221. package/dist/src/tools/tool-schemas.d.ts.map +1 -1
  222. package/dist/src/tools/tool-schemas.js +130 -302
  223. package/dist/src/tools/tool-schemas.js.map +1 -1
  224. package/dist/src/tools/viewport-tools.d.ts +4 -3
  225. package/dist/src/tools/viewport-tools.d.ts.map +1 -1
  226. package/dist/src/tools/viewport-tools.js +17 -21
  227. package/dist/src/tools/viewport-tools.js.map +1 -1
  228. package/dist/src/worker/chrome-worker-process.d.ts +4 -0
  229. package/dist/src/worker/chrome-worker-process.d.ts.map +1 -1
  230. package/dist/src/worker/chrome-worker-process.js +1 -1
  231. package/dist/src/worker/chrome-worker-process.js.map +1 -1
  232. package/dist/vitest.config.js +1 -1
  233. package/dist/vitest.config.js.map +1 -1
  234. package/dist/vitest.integration.config.d.ts +3 -0
  235. package/dist/vitest.integration.config.d.ts.map +1 -0
  236. package/dist/vitest.integration.config.js +11 -0
  237. package/dist/vitest.integration.config.js.map +1 -0
  238. package/package.json +20 -5
  239. package/dist/src/factpack/action-selector.d.ts +0 -36
  240. package/dist/src/factpack/action-selector.d.ts.map +0 -1
  241. package/dist/src/factpack/action-selector.js +0 -367
  242. package/dist/src/factpack/action-selector.js.map +0 -1
  243. package/dist/src/factpack/dialog-detector.d.ts +0 -19
  244. package/dist/src/factpack/dialog-detector.d.ts.map +0 -1
  245. package/dist/src/factpack/dialog-detector.js +0 -354
  246. package/dist/src/factpack/dialog-detector.js.map +0 -1
  247. package/dist/src/factpack/form-detector.d.ts +0 -28
  248. package/dist/src/factpack/form-detector.d.ts.map +0 -1
  249. package/dist/src/factpack/form-detector.js +0 -555
  250. package/dist/src/factpack/form-detector.js.map +0 -1
  251. package/dist/src/factpack/index.d.ts +0 -32
  252. package/dist/src/factpack/index.d.ts.map +0 -1
  253. package/dist/src/factpack/index.js +0 -73
  254. package/dist/src/factpack/index.js.map +0 -1
  255. package/dist/src/factpack/page-classifier.d.ts +0 -22
  256. package/dist/src/factpack/page-classifier.d.ts.map +0 -1
  257. package/dist/src/factpack/page-classifier.js +0 -526
  258. package/dist/src/factpack/page-classifier.js.map +0 -1
  259. package/dist/src/factpack/types.d.ts +0 -307
  260. package/dist/src/factpack/types.d.ts.map +0 -1
  261. package/dist/src/factpack/types.js +0 -12
  262. package/dist/src/factpack/types.js.map +0 -1
  263. package/dist/src/lib/constants.d.ts +0 -27
  264. package/dist/src/lib/constants.d.ts.map +0 -1
  265. package/dist/src/lib/constants.js +0 -63
  266. package/dist/src/lib/constants.js.map +0 -1
  267. package/dist/src/lib/index.d.ts +0 -12
  268. package/dist/src/lib/index.d.ts.map +0 -1
  269. package/dist/src/lib/index.js +0 -17
  270. package/dist/src/lib/index.js.map +0 -1
  271. package/dist/src/lib/regions.d.ts +0 -29
  272. package/dist/src/lib/regions.d.ts.map +0 -1
  273. package/dist/src/lib/regions.js +0 -93
  274. package/dist/src/lib/regions.js.map +0 -1
  275. package/dist/src/lib/scoring.d.ts +0 -47
  276. package/dist/src/lib/scoring.d.ts.map +0 -1
  277. package/dist/src/lib/scoring.js +0 -79
  278. package/dist/src/lib/scoring.js.map +0 -1
  279. package/dist/src/lib/selectors.d.ts +0 -42
  280. package/dist/src/lib/selectors.d.ts.map +0 -1
  281. package/dist/src/lib/selectors.js +0 -138
  282. package/dist/src/lib/selectors.js.map +0 -1
  283. package/dist/src/renderer/budget-manager.d.ts +0 -46
  284. package/dist/src/renderer/budget-manager.d.ts.map +0 -1
  285. package/dist/src/renderer/budget-manager.js +0 -133
  286. package/dist/src/renderer/budget-manager.js.map +0 -1
  287. package/dist/src/renderer/constants.d.ts +0 -38
  288. package/dist/src/renderer/constants.d.ts.map +0 -1
  289. package/dist/src/renderer/constants.js +0 -29
  290. package/dist/src/renderer/constants.js.map +0 -1
  291. package/dist/src/renderer/index.d.ts +0 -12
  292. package/dist/src/renderer/index.d.ts.map +0 -1
  293. package/dist/src/renderer/index.js +0 -16
  294. package/dist/src/renderer/index.js.map +0 -1
  295. package/dist/src/renderer/section-renderers.d.ts +0 -42
  296. package/dist/src/renderer/section-renderers.d.ts.map +0 -1
  297. package/dist/src/renderer/section-renderers.js +0 -252
  298. package/dist/src/renderer/section-renderers.js.map +0 -1
  299. package/dist/src/renderer/token-counter.d.ts +0 -45
  300. package/dist/src/renderer/token-counter.d.ts.map +0 -1
  301. package/dist/src/renderer/token-counter.js +0 -65
  302. package/dist/src/renderer/token-counter.js.map +0 -1
  303. package/dist/src/renderer/types.d.ts +0 -71
  304. package/dist/src/renderer/types.d.ts.map +0 -1
  305. package/dist/src/renderer/types.js +0 -7
  306. package/dist/src/renderer/types.js.map +0 -1
  307. package/dist/src/renderer/xml-renderer.d.ts +0 -42
  308. package/dist/src/renderer/xml-renderer.d.ts.map +0 -1
  309. package/dist/src/renderer/xml-renderer.js +0 -103
  310. package/dist/src/renderer/xml-renderer.js.map +0 -1
  311. package/dist/src/server/session-store.d.ts +0 -163
  312. package/dist/src/server/session-store.d.ts.map +0 -1
  313. package/dist/src/server/session-store.js +0 -248
  314. package/dist/src/server/session-store.js.map +0 -1
  315. package/dist/src/session/session-worker-binding.d.ts +0 -57
  316. package/dist/src/session/session-worker-binding.d.ts.map +0 -1
  317. package/dist/src/session/session-worker-binding.js +0 -109
  318. package/dist/src/session/session-worker-binding.js.map +0 -1
  319. package/dist/src/shared/services/dom-transformer.service.d.ts +0 -71
  320. package/dist/src/shared/services/dom-transformer.service.d.ts.map +0 -1
  321. package/dist/src/shared/services/dom-transformer.service.js +0 -190
  322. package/dist/src/shared/services/dom-transformer.service.js.map +0 -1
  323. package/dist/src/shared/services/selector-builder.service.d.ts +0 -53
  324. package/dist/src/shared/services/selector-builder.service.d.ts.map +0 -1
  325. package/dist/src/shared/services/selector-builder.service.js +0 -240
  326. package/dist/src/shared/services/selector-builder.service.js.map +0 -1
  327. package/dist/src/state/constants.d.ts +0 -125
  328. package/dist/src/state/constants.d.ts.map +0 -1
  329. package/dist/src/state/constants.js +0 -131
  330. package/dist/src/state/constants.js.map +0 -1
  331. package/dist/src/tools/state-manager-registry.d.ts +0 -26
  332. package/dist/src/tools/state-manager-registry.d.ts.map +0 -1
  333. package/dist/src/tools/state-manager-registry.js +0 -39
  334. package/dist/src/tools/state-manager-registry.js.map +0 -1
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Session Controller
3
+ *
4
+ * Per-tenant state container that implements ToolContext.
5
+ * Each agent/session gets its own SessionController instance
6
+ * with isolated pages, snapshots, state managers, and registries.
7
+ *
8
+ * Each session owns its own SessionManager and browser lifecycle,
9
+ * configured independently via BrowserSessionConfig.
10
+ *
11
+ * @module session/session-controller
12
+ */
13
+ import type { BaseSnapshot, ReadableNode } from '../snapshot/snapshot.types.js';
14
+ import { SessionManager } from '../browser/session-manager.js';
15
+ import { SnapshotStore } from '../snapshot/snapshot-store.js';
16
+ import { StateManager } from '../state/state-manager.js';
17
+ import { DependencyTracker } from '../form/dependency-tracker.js';
18
+ import { ObservationAccumulator } from '../observation/observation-accumulator.js';
19
+ import type { ToolContext, CdpSessionResult, SnapshotCaptureResult } from '../tools/tool-context.types.js';
20
+ import { type BrowserSessionConfig } from '../browser/browser-session-config.js';
21
+ import type { PageHandle } from '../browser/page-registry.js';
22
+ /**
23
+ * Session state machine.
24
+ */
25
+ export type SessionState = 'initializing' | 'active' | 'closing' | 'closed';
26
+ /**
27
+ * SessionController configuration.
28
+ */
29
+ export interface SessionControllerOptions {
30
+ /** Unique session identifier */
31
+ sessionId: string;
32
+ /** Optional browser configuration for this session */
33
+ browserConfig?: BrowserSessionConfig;
34
+ }
35
+ /**
36
+ * Per-tenant session controller implementing ToolContext.
37
+ *
38
+ * Owns all per-session state:
39
+ * - SessionManager (per-session browser lifecycle)
40
+ * - SnapshotStore (per-session snapshot cache)
41
+ * - StateManagers (one per page)
42
+ * - DependencyTracker (per-session form dependencies)
43
+ * - ObservationAccumulator (per-session DOM mutation tracking)
44
+ */
45
+ export declare class SessionController implements ToolContext {
46
+ readonly sessionId: string;
47
+ private _sessionManager;
48
+ private _browserConfig;
49
+ private readonly _snapshotStore;
50
+ private readonly _stateManagers;
51
+ private readonly _dependencyTracker;
52
+ private readonly _observationAccumulator;
53
+ /** Deduplication promise for concurrent ensureBrowser() calls */
54
+ private _ensureBrowserPromise;
55
+ /** Unsubscribe from SessionManager state changes (cleanup in close()) */
56
+ private _unsubStateChange;
57
+ private _state;
58
+ private _lastActivity;
59
+ constructor(options: SessionControllerOptions);
60
+ /** Get the current session state. */
61
+ get state(): SessionState;
62
+ /** Touch the session to update last activity timestamp. */
63
+ touch(): void;
64
+ /** Get the time of last activity. */
65
+ get lastActivity(): number;
66
+ /**
67
+ * Close the session and clean up all resources, including the owned browser.
68
+ */
69
+ close(): Promise<void>;
70
+ /**
71
+ * Check if browser configuration can be changed.
72
+ * Returns true when no browser is running (before first launch or after crash).
73
+ */
74
+ canReconfigure(): boolean;
75
+ /**
76
+ * Shut down the current browser and clear session state so the browser
77
+ * can be reconfigured (e.g., switch from a launched browser to auto_connect).
78
+ */
79
+ resetBrowser(): Promise<void>;
80
+ /**
81
+ * Set the browser configuration for this session.
82
+ *
83
+ * Must be called before the browser is launched/connected (i.e., before
84
+ * the first browser-touching tool call). Throws if browser is already running.
85
+ */
86
+ setBrowserConfig(config: BrowserSessionConfig): void;
87
+ getBrowserConfig(): BrowserSessionConfig;
88
+ /**
89
+ * Ensure the session's browser is ready.
90
+ *
91
+ * Lazily creates a SessionManager and launches/connects based on
92
+ * the session's BrowserSessionConfig. Idempotent — returns immediately
93
+ * if the browser is already running. Concurrent calls are deduplicated.
94
+ */
95
+ ensureBrowser(): Promise<void>;
96
+ resolvePage(pageId?: string): PageHandle | undefined;
97
+ resolvePageOrCreate(pageId?: string): Promise<PageHandle>;
98
+ resolveExistingPage(pageId?: string): PageHandle;
99
+ touchPage(pageId: string): void;
100
+ closePage(pageId: string): Promise<boolean>;
101
+ syncPages(): Promise<PageHandle[]>;
102
+ navigateTo(pageId: string, url: string): Promise<void>;
103
+ getSessionManager(): SessionManager;
104
+ getSnapshotStore(): SnapshotStore;
105
+ getStateManager(pageId: string): StateManager;
106
+ removeStateManager(pageId: string): void;
107
+ clearAllStateManagers(): void;
108
+ getDependencyTracker(): DependencyTracker;
109
+ getObservationAccumulator(): ObservationAccumulator;
110
+ ensureCdpSession(handle: PageHandle): Promise<CdpSessionResult>;
111
+ captureSnapshotWithRecovery(handle: PageHandle, pageId: string): Promise<SnapshotCaptureResult>;
112
+ requireSnapshot(pageId: string): BaseSnapshot;
113
+ resolveElementByEid(pageId: string, eid: string, snapshot: BaseSnapshot): ReadableNode;
114
+ /**
115
+ * Get or lazily create the session's own SessionManager.
116
+ */
117
+ private getOrCreateSessionManager;
118
+ /**
119
+ * Clear stale per-page state (snapshots, state managers, dependencies).
120
+ * Called when the browser crashes or disconnects unexpectedly.
121
+ */
122
+ private clearSessionState;
123
+ }
124
+ //# sourceMappingURL=session-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../../src/session/session-controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Session Controller
3
+ *
4
+ * Per-tenant state container that implements ToolContext.
5
+ * Each agent/session gets its own SessionController instance
6
+ * with isolated pages, snapshots, state managers, and registries.
7
+ *
8
+ * Each session owns its own SessionManager and browser lifecycle,
9
+ * configured independently via BrowserSessionConfig.
10
+ *
11
+ * @module session/session-controller
12
+ */
13
+ import { SessionManager } from '../browser/session-manager.js';
14
+ import { SnapshotStore } from '../snapshot/snapshot-store.js';
15
+ import { StateManager } from '../state/state-manager.js';
16
+ import { DependencyTracker } from '../form/dependency-tracker.js';
17
+ import { ObservationAccumulator } from '../observation/observation-accumulator.js';
18
+ import { ensureCdpSession as ensureCdpSessionImpl, resolveExistingPage as resolveExistingPageImpl, } from '../tools/tool-context.js';
19
+ import { captureSnapshotWithRecovery as captureSnapshotWithRecoveryImpl } from '../tools/action-context.js';
20
+ import { ElementNotFoundError, StaleElementError, SnapshotRequiredError } from '../tools/errors.js';
21
+ import { defaultBrowserConfig, } from '../browser/browser-session-config.js';
22
+ import { ensureBrowserReady } from '../browser/ensure-browser.js';
23
+ import { getLogger } from '../shared/services/logging.service.js';
24
+ const logger = getLogger();
25
+ /**
26
+ * Per-tenant session controller implementing ToolContext.
27
+ *
28
+ * Owns all per-session state:
29
+ * - SessionManager (per-session browser lifecycle)
30
+ * - SnapshotStore (per-session snapshot cache)
31
+ * - StateManagers (one per page)
32
+ * - DependencyTracker (per-session form dependencies)
33
+ * - ObservationAccumulator (per-session DOM mutation tracking)
34
+ */
35
+ export class SessionController {
36
+ sessionId;
37
+ _sessionManager = null;
38
+ _browserConfig;
39
+ _snapshotStore;
40
+ _stateManagers = new Map();
41
+ _dependencyTracker;
42
+ _observationAccumulator;
43
+ /** Deduplication promise for concurrent ensureBrowser() calls */
44
+ _ensureBrowserPromise = null;
45
+ /** Unsubscribe from SessionManager state changes (cleanup in close()) */
46
+ _unsubStateChange = null;
47
+ _state = 'initializing';
48
+ _lastActivity = Date.now();
49
+ constructor(options) {
50
+ this.sessionId = options.sessionId;
51
+ this._browserConfig = options.browserConfig ?? defaultBrowserConfig();
52
+ this._snapshotStore = new SnapshotStore();
53
+ this._dependencyTracker = new DependencyTracker();
54
+ this._observationAccumulator = new ObservationAccumulator();
55
+ this._state = 'active';
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // Session lifecycle
59
+ // ---------------------------------------------------------------------------
60
+ /** Get the current session state. */
61
+ get state() {
62
+ return this._state;
63
+ }
64
+ /** Touch the session to update last activity timestamp. */
65
+ touch() {
66
+ this._lastActivity = Date.now();
67
+ }
68
+ /** Get the time of last activity. */
69
+ get lastActivity() {
70
+ return this._lastActivity;
71
+ }
72
+ /**
73
+ * Close the session and clean up all resources, including the owned browser.
74
+ */
75
+ async close() {
76
+ if (this._state === 'closing' || this._state === 'closed')
77
+ return;
78
+ this._state = 'closing';
79
+ this._unsubStateChange?.();
80
+ this._unsubStateChange = null;
81
+ this._snapshotStore.destroy();
82
+ this._stateManagers.clear();
83
+ this._dependencyTracker.clearAll();
84
+ // Shut down the owned browser
85
+ if (this._sessionManager) {
86
+ try {
87
+ await this._sessionManager.shutdown();
88
+ }
89
+ catch (err) {
90
+ logger.error('Error shutting down session browser', err instanceof Error ? err : undefined, { sessionId: this.sessionId });
91
+ }
92
+ this._sessionManager = null;
93
+ }
94
+ this._state = 'closed';
95
+ }
96
+ // ---------------------------------------------------------------------------
97
+ // Browser lifecycle (ToolContext implementation)
98
+ // ---------------------------------------------------------------------------
99
+ /**
100
+ * Check if browser configuration can be changed.
101
+ * Returns true when no browser is running (before first launch or after crash).
102
+ */
103
+ canReconfigure() {
104
+ if (this._ensureBrowserPromise)
105
+ return false;
106
+ return !(this._sessionManager?.isRunning() ?? false);
107
+ }
108
+ /**
109
+ * Shut down the current browser and clear session state so the browser
110
+ * can be reconfigured (e.g., switch from a launched browser to auto_connect).
111
+ */
112
+ async resetBrowser() {
113
+ if (this._sessionManager) {
114
+ await this._sessionManager.shutdown();
115
+ }
116
+ this.clearSessionState();
117
+ }
118
+ /**
119
+ * Set the browser configuration for this session.
120
+ *
121
+ * Must be called before the browser is launched/connected (i.e., before
122
+ * the first browser-touching tool call). Throws if browser is already running.
123
+ */
124
+ setBrowserConfig(config) {
125
+ if (!this.canReconfigure()) {
126
+ throw new Error('Cannot change browser configuration while the browser is running.');
127
+ }
128
+ const overrides = Object.fromEntries(Object.entries(config).filter(([, v]) => v !== undefined));
129
+ this._browserConfig = { ...this._browserConfig, ...overrides };
130
+ }
131
+ getBrowserConfig() {
132
+ return { ...this._browserConfig };
133
+ }
134
+ /**
135
+ * Ensure the session's browser is ready.
136
+ *
137
+ * Lazily creates a SessionManager and launches/connects based on
138
+ * the session's BrowserSessionConfig. Idempotent — returns immediately
139
+ * if the browser is already running. Concurrent calls are deduplicated.
140
+ */
141
+ async ensureBrowser() {
142
+ // Deduplicate concurrent calls — all callers await the same promise
143
+ if (this._ensureBrowserPromise) {
144
+ await this._ensureBrowserPromise;
145
+ return;
146
+ }
147
+ const session = this.getOrCreateSessionManager();
148
+ // ensureBrowserReady handles the isRunning() fast-path internally
149
+ this._ensureBrowserPromise = ensureBrowserReady(session, this._browserConfig);
150
+ try {
151
+ await this._ensureBrowserPromise;
152
+ }
153
+ finally {
154
+ this._ensureBrowserPromise = null;
155
+ }
156
+ }
157
+ // ---------------------------------------------------------------------------
158
+ // Page lifecycle (ToolContext implementation)
159
+ // ---------------------------------------------------------------------------
160
+ resolvePage(pageId) {
161
+ this.touch();
162
+ return this.getSessionManager().resolvePage(pageId);
163
+ }
164
+ async resolvePageOrCreate(pageId) {
165
+ this.touch();
166
+ return this.getSessionManager().resolvePageOrCreate(pageId);
167
+ }
168
+ resolveExistingPage(pageId) {
169
+ this.touch();
170
+ return resolveExistingPageImpl(this.getSessionManager(), pageId);
171
+ }
172
+ touchPage(pageId) {
173
+ this.getSessionManager().touchPage(pageId);
174
+ }
175
+ async closePage(pageId) {
176
+ return this.getSessionManager().closePage(pageId);
177
+ }
178
+ async syncPages() {
179
+ return this.getSessionManager().syncPages();
180
+ }
181
+ async navigateTo(pageId, url) {
182
+ await this.getSessionManager().navigateTo(pageId, url);
183
+ }
184
+ // ---------------------------------------------------------------------------
185
+ // State access (ToolContext implementation)
186
+ // ---------------------------------------------------------------------------
187
+ getSessionManager() {
188
+ return this.getOrCreateSessionManager();
189
+ }
190
+ getSnapshotStore() {
191
+ return this._snapshotStore;
192
+ }
193
+ getStateManager(pageId) {
194
+ if (!this._stateManagers.has(pageId)) {
195
+ this._stateManagers.set(pageId, new StateManager({ pageId }));
196
+ }
197
+ return this._stateManagers.get(pageId);
198
+ }
199
+ removeStateManager(pageId) {
200
+ this._stateManagers.delete(pageId);
201
+ }
202
+ clearAllStateManagers() {
203
+ this._stateManagers.clear();
204
+ }
205
+ getDependencyTracker() {
206
+ return this._dependencyTracker;
207
+ }
208
+ getObservationAccumulator() {
209
+ return this._observationAccumulator;
210
+ }
211
+ // ---------------------------------------------------------------------------
212
+ // CDP health (ToolContext implementation)
213
+ // ---------------------------------------------------------------------------
214
+ async ensureCdpSession(handle) {
215
+ return ensureCdpSessionImpl(this.getSessionManager(), handle);
216
+ }
217
+ // ---------------------------------------------------------------------------
218
+ // Snapshot capture (ToolContext implementation)
219
+ // ---------------------------------------------------------------------------
220
+ async captureSnapshotWithRecovery(handle, pageId) {
221
+ return captureSnapshotWithRecoveryImpl(this, handle, pageId);
222
+ }
223
+ // ---------------------------------------------------------------------------
224
+ // Element resolution (ToolContext implementation)
225
+ // ---------------------------------------------------------------------------
226
+ requireSnapshot(pageId) {
227
+ const snap = this._snapshotStore.getByPageId(pageId);
228
+ if (!snap) {
229
+ throw new SnapshotRequiredError(pageId);
230
+ }
231
+ return snap;
232
+ }
233
+ resolveElementByEid(pageId, eid, snapshot) {
234
+ const stateManager = this.getStateManager(pageId);
235
+ const registry = stateManager.getElementRegistry();
236
+ const elementRef = registry.getByEid(eid);
237
+ if (!elementRef) {
238
+ throw new ElementNotFoundError(eid);
239
+ }
240
+ if (registry.isStale(eid)) {
241
+ throw new StaleElementError(eid);
242
+ }
243
+ const node = snapshot.nodes.find((n) => n.backend_node_id === elementRef.ref.backend_node_id);
244
+ if (!node) {
245
+ throw new StaleElementError(eid);
246
+ }
247
+ return node;
248
+ }
249
+ // ---------------------------------------------------------------------------
250
+ // Private helpers
251
+ // ---------------------------------------------------------------------------
252
+ /**
253
+ * Get or lazily create the session's own SessionManager.
254
+ */
255
+ getOrCreateSessionManager() {
256
+ if (!this._sessionManager) {
257
+ this._sessionManager = new SessionManager();
258
+ this._unsubStateChange = this._sessionManager.onStateChange((event) => {
259
+ if (event.currentState === 'failed') {
260
+ this.clearSessionState();
261
+ }
262
+ });
263
+ }
264
+ return this._sessionManager;
265
+ }
266
+ /**
267
+ * Clear stale per-page state (snapshots, state managers, dependencies).
268
+ * Called when the browser crashes or disconnects unexpectedly.
269
+ */
270
+ clearSessionState() {
271
+ this._snapshotStore.clear();
272
+ this._stateManagers.clear();
273
+ this._dependencyTracker.clearAll();
274
+ }
275
+ }
276
+ //# sourceMappingURL=session-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-controller.js","sourceRoot":"","sources":["../../../src/session/session-controller.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,5 @@
1
1
  /**
2
2
  * Shared services re-exports
3
3
  */
4
- export * from './selector-builder.service.js';
5
- export * from './dom-transformer.service.js';
6
4
  export * from './logging.service.js';
7
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/shared/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/shared/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,sBAAsB,CAAC"}
@@ -1,7 +1,5 @@
1
1
  /**
2
2
  * Shared services re-exports
3
3
  */
4
- export * from './selector-builder.service.js';
5
- export * from './dom-transformer.service.js';
6
4
  export * from './logging.service.js';
7
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/shared/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/shared/services/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Package version constant.
3
+ *
4
+ * Reads the version from package.json at build time via createRequire,
5
+ * providing a single source of truth for all entry points.
6
+ *
7
+ * @module shared/version
8
+ */
9
+ export declare const VERSION: string;
10
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/shared/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH,eAAO,MAAM,OAAO,QAAuB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Package version constant.
3
+ *
4
+ * Reads the version from package.json at build time via createRequire,
5
+ * providing a single source of truth for all entry points.
6
+ *
7
+ * @module shared/version
8
+ */
9
+ import { readFileSync } from 'node:fs';
10
+ import { dirname, resolve } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ /**
14
+ * Walk up from the current file to find package.json.
15
+ * Works from both src/ (dev) and dist/src/ (built) locations.
16
+ */
17
+ function findPackageVersion() {
18
+ let dir = __dirname;
19
+ for (let i = 0; i < 5; i++) {
20
+ try {
21
+ const pkg = JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf-8'));
22
+ return pkg.version;
23
+ }
24
+ catch {
25
+ dir = dirname(dir);
26
+ }
27
+ }
28
+ console.warn('Warning: Could not find package.json to read version — defaulting to 0.0.0');
29
+ return '0.0.0';
30
+ }
31
+ export const VERSION = findPackageVersion();
32
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/shared/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D;;;GAGG;AACH,SAAS,kBAAkB;IACzB,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAEzE,CAAC;YACF,OAAO,GAAG,CAAC,OAAO,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IAC3F,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC"}
@@ -24,8 +24,9 @@ export declare function getElementTopLeft(cdp: CdpClient, backendNodeId: number)
24
24
  /**
25
25
  * Click an element at its center using CDP's backendNodeId.
26
26
  *
27
- * Bypasses Playwright's locator system to avoid strict mode violations
28
- * when multiple elements match the same selector.
27
+ * If the element is tiny (< 5x5 px), searches for a larger clickable
28
+ * ancestor (label, parent wrapper) to click instead — common for hidden
29
+ * radio/checkbox inputs with custom visual wrappers.
29
30
  */
30
31
  export declare function clickByBackendNodeId(cdp: CdpClient, backendNodeId: number, modifiers?: string[]): Promise<void>;
31
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"element-resolver.d.ts","sourceRoot":"","sources":["../../../src/snapshot/element-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"element-resolver.d.ts","sourceRoot":"","sources":["../../../src/snapshot/element-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAMhE;;;GAGG;AACH,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,cAAc,IAAI,CAAC;AAqGhC;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,SAAS,EACd,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAGnC;AAsFD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,SAAS,EACd,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,SAAS,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,SAAS,EACd,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,CAGf;AAMD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BpE;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,SAAS,EACd,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAWf;AAMD;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B/F;AAMD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,SAAS,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAMD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ/F;AAMD;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzF;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,SAAS,EACd,SAAS,EAAE,IAAI,GAAG,MAAM,EACxB,MAAM,SAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAMf;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,SAAK,EACV,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,CAmDf;AAMD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,SAAS,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -109,11 +109,9 @@ export async function getElementTopLeft(cdp, backendNodeId) {
109
109
  return { x: content[0], y: content[1] };
110
110
  }
111
111
  /**
112
- * Get the center coordinates of an element by its backendNodeId.
113
- * Scrolls the element into view first.
112
+ * Compute center point from a content quad, with validation.
114
113
  */
115
- async function getElementCenter(cdp, backendNodeId) {
116
- const content = await scrollAndGetContentQuad(cdp, backendNodeId);
114
+ function centerFromContentQuad(content, backendNodeId) {
117
115
  const [x1, y1, x2, , , y3] = content;
118
116
  const x = x1 + (x2 - x1) / 2;
119
117
  const y = y1 + (y3 - y1) / 2;
@@ -123,17 +121,86 @@ async function getElementCenter(cdp, backendNodeId) {
123
121
  }
124
122
  return { x, y };
125
123
  }
124
+ /**
125
+ * Get the center coordinates of an element by its backendNodeId.
126
+ * Scrolls the element into view first.
127
+ */
128
+ async function getElementCenter(cdp, backendNodeId) {
129
+ const content = await scrollAndGetContentQuad(cdp, backendNodeId);
130
+ return centerFromContentQuad(content, backendNodeId);
131
+ }
126
132
  // ============================================================================
127
133
  // Click Operations
128
134
  // ============================================================================
135
+ /**
136
+ * Minimum element dimension (px) below which we search for a larger clickable ancestor.
137
+ * Hidden radio/checkbox inputs are commonly 1x1 or 0x0 with a visible label wrapper.
138
+ */
139
+ const MIN_CLICKABLE_SIZE = 5;
140
+ /**
141
+ * Find a clickable ancestor when the target element is too small to reliably click.
142
+ * Walks up the DOM looking for a parent/label with a reasonable bounding box.
143
+ *
144
+ * @returns backendNodeId of a better click target, or the original if none found
145
+ */
146
+ async function findClickableAncestor(cdp, backendNodeId) {
147
+ try {
148
+ const { object } = await cdp.send('DOM.resolveNode', { backendNodeId });
149
+ if (!object.objectId)
150
+ return backendNodeId;
151
+ const result = await cdp.send('Runtime.callFunctionOn', {
152
+ objectId: object.objectId,
153
+ functionDeclaration: `function() {
154
+ var MIN = ${MIN_CLICKABLE_SIZE};
155
+ var el = this;
156
+ if (el.id) {
157
+ var label = document.querySelector('label[for="' + CSS.escape(el.id) + '"]');
158
+ if (label && label.offsetWidth > MIN && label.offsetHeight > MIN) return label;
159
+ }
160
+ var current = el.parentElement;
161
+ for (var i = 0; i < 5 && current; i++) {
162
+ if (current.offsetWidth > MIN && current.offsetHeight > MIN) return current;
163
+ current = current.parentElement;
164
+ }
165
+ return null;
166
+ }`,
167
+ returnByValue: false,
168
+ });
169
+ if (result.result?.objectId) {
170
+ const desc = await cdp.send('DOM.describeNode', {
171
+ objectId: result.result.objectId,
172
+ });
173
+ if (desc.node?.backendNodeId) {
174
+ return desc.node.backendNodeId;
175
+ }
176
+ }
177
+ }
178
+ catch {
179
+ // Non-critical — ancestor lookup can fail for detached nodes
180
+ }
181
+ return backendNodeId;
182
+ }
129
183
  /**
130
184
  * Click an element at its center using CDP's backendNodeId.
131
185
  *
132
- * Bypasses Playwright's locator system to avoid strict mode violations
133
- * when multiple elements match the same selector.
186
+ * If the element is tiny (< 5x5 px), searches for a larger clickable
187
+ * ancestor (label, parent wrapper) to click instead — common for hidden
188
+ * radio/checkbox inputs with custom visual wrappers.
134
189
  */
135
190
  export async function clickByBackendNodeId(cdp, backendNodeId, modifiers) {
136
- const { x, y } = await getElementCenter(cdp, backendNodeId);
191
+ const content = await scrollAndGetContentQuad(cdp, backendNodeId);
192
+ const [x1, y1, x2, , , y3] = content;
193
+ const width = x2 - x1;
194
+ const height = y3 - y1;
195
+ if (width < MIN_CLICKABLE_SIZE && height < MIN_CLICKABLE_SIZE) {
196
+ const ancestor = await findClickableAncestor(cdp, backendNodeId);
197
+ if (ancestor !== backendNodeId) {
198
+ const center = await getElementCenter(cdp, ancestor);
199
+ await clickAtCoordinates(cdp, center.x, center.y, modifiers);
200
+ return;
201
+ }
202
+ }
203
+ const { x, y } = centerFromContentQuad(content, backendNodeId);
137
204
  await clickAtCoordinates(cdp, x, y, modifiers);
138
205
  }
139
206
  /**
@@ -144,6 +211,12 @@ export async function clickAtCoordinates(cdp, x, y, modifiers) {
144
211
  throw new Error(`Invalid click coordinates (x: ${x}, y: ${y}). Coordinates must be non-negative finite numbers.`);
145
212
  }
146
213
  const modifierBits = computeModifiers(modifiers);
214
+ await cdp.send('Input.dispatchMouseEvent', {
215
+ type: 'mouseMoved',
216
+ x,
217
+ y,
218
+ modifiers: modifierBits,
219
+ });
147
220
  await cdp.send('Input.dispatchMouseEvent', {
148
221
  type: 'mousePressed',
149
222
  x,
@@ -304,7 +377,9 @@ export async function selectOption(cdp, backendNodeId, value) {
304
377
  const available = options.map(o => o.text || o.value).join(', ');
305
378
  throw new Error('Option not found: "' + targetValue + '". Available: ' + available);
306
379
  }
307
- this.value = option.value;
380
+ var nativeSetter = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, 'value').set;
381
+ nativeSetter.call(this, option.value);
382
+ this.dispatchEvent(new Event('input', { bubbles: true }));
308
383
  this.dispatchEvent(new Event('change', { bubbles: true }));
309
384
  return option.text;
310
385
  }`,