agent-web-interface 4.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 (395) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/src/browser/ensure-browser.d.ts +39 -0
  4. package/dist/src/browser/ensure-browser.d.ts.map +1 -0
  5. package/dist/src/browser/ensure-browser.js +65 -0
  6. package/dist/src/browser/ensure-browser.js.map +1 -0
  7. package/dist/src/browser/index.d.ts +8 -0
  8. package/dist/src/browser/index.d.ts.map +1 -0
  9. package/dist/src/browser/index.js +8 -0
  10. package/dist/src/browser/index.js.map +1 -0
  11. package/dist/src/browser/page-network-tracker.d.ts +96 -0
  12. package/dist/src/browser/page-network-tracker.d.ts.map +1 -0
  13. package/dist/src/browser/page-network-tracker.js +235 -0
  14. package/dist/src/browser/page-network-tracker.js.map +1 -0
  15. package/dist/src/browser/page-registry.d.ts +137 -0
  16. package/dist/src/browser/page-registry.d.ts.map +1 -0
  17. package/dist/src/browser/page-registry.js +194 -0
  18. package/dist/src/browser/page-registry.js.map +1 -0
  19. package/dist/src/browser/page-stabilization.d.ts +35 -0
  20. package/dist/src/browser/page-stabilization.d.ts.map +1 -0
  21. package/dist/src/browser/page-stabilization.js +42 -0
  22. package/dist/src/browser/page-stabilization.js.map +1 -0
  23. package/dist/src/browser/session-manager.d.ts +336 -0
  24. package/dist/src/browser/session-manager.d.ts.map +1 -0
  25. package/dist/src/browser/session-manager.js +964 -0
  26. package/dist/src/browser/session-manager.js.map +1 -0
  27. package/dist/src/cdp/cdp-client.interface.d.ts +193 -0
  28. package/dist/src/cdp/cdp-client.interface.d.ts.map +1 -0
  29. package/dist/src/cdp/cdp-client.interface.js +9 -0
  30. package/dist/src/cdp/cdp-client.interface.js.map +1 -0
  31. package/dist/src/cdp/index.d.ts +9 -0
  32. package/dist/src/cdp/index.d.ts.map +1 -0
  33. package/dist/src/cdp/index.js +8 -0
  34. package/dist/src/cdp/index.js.map +1 -0
  35. package/dist/src/cdp/puppeteer-cdp-client.d.ts +97 -0
  36. package/dist/src/cdp/puppeteer-cdp-client.d.ts.map +1 -0
  37. package/dist/src/cdp/puppeteer-cdp-client.js +273 -0
  38. package/dist/src/cdp/puppeteer-cdp-client.js.map +1 -0
  39. package/dist/src/cli/args.d.ts +35 -0
  40. package/dist/src/cli/args.d.ts.map +1 -0
  41. package/dist/src/cli/args.js +76 -0
  42. package/dist/src/cli/args.js.map +1 -0
  43. package/dist/src/delta/dom-stabilizer.d.ts +46 -0
  44. package/dist/src/delta/dom-stabilizer.d.ts.map +1 -0
  45. package/dist/src/delta/dom-stabilizer.js +121 -0
  46. package/dist/src/delta/dom-stabilizer.js.map +1 -0
  47. package/dist/src/delta/index.d.ts +8 -0
  48. package/dist/src/delta/index.d.ts.map +1 -0
  49. package/dist/src/delta/index.js +7 -0
  50. package/dist/src/delta/index.js.map +1 -0
  51. package/dist/src/factpack/action-selector.d.ts +36 -0
  52. package/dist/src/factpack/action-selector.d.ts.map +1 -0
  53. package/dist/src/factpack/action-selector.js +367 -0
  54. package/dist/src/factpack/action-selector.js.map +1 -0
  55. package/dist/src/factpack/dialog-detector.d.ts +19 -0
  56. package/dist/src/factpack/dialog-detector.d.ts.map +1 -0
  57. package/dist/src/factpack/dialog-detector.js +354 -0
  58. package/dist/src/factpack/dialog-detector.js.map +1 -0
  59. package/dist/src/factpack/form-detector.d.ts +28 -0
  60. package/dist/src/factpack/form-detector.d.ts.map +1 -0
  61. package/dist/src/factpack/form-detector.js +555 -0
  62. package/dist/src/factpack/form-detector.js.map +1 -0
  63. package/dist/src/factpack/index.d.ts +32 -0
  64. package/dist/src/factpack/index.d.ts.map +1 -0
  65. package/dist/src/factpack/index.js +73 -0
  66. package/dist/src/factpack/index.js.map +1 -0
  67. package/dist/src/factpack/page-classifier.d.ts +22 -0
  68. package/dist/src/factpack/page-classifier.d.ts.map +1 -0
  69. package/dist/src/factpack/page-classifier.js +526 -0
  70. package/dist/src/factpack/page-classifier.js.map +1 -0
  71. package/dist/src/factpack/types.d.ts +307 -0
  72. package/dist/src/factpack/types.d.ts.map +1 -0
  73. package/dist/src/factpack/types.js +12 -0
  74. package/dist/src/factpack/types.js.map +1 -0
  75. package/dist/src/form/dependency-tracker.d.ts +108 -0
  76. package/dist/src/form/dependency-tracker.d.ts.map +1 -0
  77. package/dist/src/form/dependency-tracker.js +298 -0
  78. package/dist/src/form/dependency-tracker.js.map +1 -0
  79. package/dist/src/form/field-extractor.d.ts +32 -0
  80. package/dist/src/form/field-extractor.d.ts.map +1 -0
  81. package/dist/src/form/field-extractor.js +544 -0
  82. package/dist/src/form/field-extractor.js.map +1 -0
  83. package/dist/src/form/form-detector.d.ts +103 -0
  84. package/dist/src/form/form-detector.d.ts.map +1 -0
  85. package/dist/src/form/form-detector.js +704 -0
  86. package/dist/src/form/form-detector.js.map +1 -0
  87. package/dist/src/form/form-state.d.ts +23 -0
  88. package/dist/src/form/form-state.d.ts.map +1 -0
  89. package/dist/src/form/form-state.js +39 -0
  90. package/dist/src/form/form-state.js.map +1 -0
  91. package/dist/src/form/index.d.ts +23 -0
  92. package/dist/src/form/index.d.ts.map +1 -0
  93. package/dist/src/form/index.js +27 -0
  94. package/dist/src/form/index.js.map +1 -0
  95. package/dist/src/form/runtime-value-reader.d.ts +72 -0
  96. package/dist/src/form/runtime-value-reader.d.ts.map +1 -0
  97. package/dist/src/form/runtime-value-reader.js +232 -0
  98. package/dist/src/form/runtime-value-reader.js.map +1 -0
  99. package/dist/src/form/types.d.ts +384 -0
  100. package/dist/src/form/types.d.ts.map +1 -0
  101. package/dist/src/form/types.js +17 -0
  102. package/dist/src/form/types.js.map +1 -0
  103. package/dist/src/index.d.ts +8 -0
  104. package/dist/src/index.d.ts.map +1 -0
  105. package/dist/src/index.js +212 -0
  106. package/dist/src/index.js.map +1 -0
  107. package/dist/src/lib/constants.d.ts +27 -0
  108. package/dist/src/lib/constants.d.ts.map +1 -0
  109. package/dist/src/lib/constants.js +63 -0
  110. package/dist/src/lib/constants.js.map +1 -0
  111. package/dist/src/lib/index.d.ts +12 -0
  112. package/dist/src/lib/index.d.ts.map +1 -0
  113. package/dist/src/lib/index.js +17 -0
  114. package/dist/src/lib/index.js.map +1 -0
  115. package/dist/src/lib/regions.d.ts +29 -0
  116. package/dist/src/lib/regions.d.ts.map +1 -0
  117. package/dist/src/lib/regions.js +93 -0
  118. package/dist/src/lib/regions.js.map +1 -0
  119. package/dist/src/lib/scoring.d.ts +47 -0
  120. package/dist/src/lib/scoring.d.ts.map +1 -0
  121. package/dist/src/lib/scoring.js +79 -0
  122. package/dist/src/lib/scoring.js.map +1 -0
  123. package/dist/src/lib/selectors.d.ts +42 -0
  124. package/dist/src/lib/selectors.d.ts.map +1 -0
  125. package/dist/src/lib/selectors.js +138 -0
  126. package/dist/src/lib/selectors.js.map +1 -0
  127. package/dist/src/lib/text-utils.d.ts +155 -0
  128. package/dist/src/lib/text-utils.d.ts.map +1 -0
  129. package/dist/src/lib/text-utils.js +391 -0
  130. package/dist/src/lib/text-utils.js.map +1 -0
  131. package/dist/src/observation/eid-linker.d.ts +104 -0
  132. package/dist/src/observation/eid-linker.d.ts.map +1 -0
  133. package/dist/src/observation/eid-linker.js +403 -0
  134. package/dist/src/observation/eid-linker.js.map +1 -0
  135. package/dist/src/observation/index.d.ts +12 -0
  136. package/dist/src/observation/index.d.ts.map +1 -0
  137. package/dist/src/observation/index.js +15 -0
  138. package/dist/src/observation/index.js.map +1 -0
  139. package/dist/src/observation/observation-accumulator.d.ts +58 -0
  140. package/dist/src/observation/observation-accumulator.d.ts.map +1 -0
  141. package/dist/src/observation/observation-accumulator.js +213 -0
  142. package/dist/src/observation/observation-accumulator.js.map +1 -0
  143. package/dist/src/observation/observation.types.d.ts +139 -0
  144. package/dist/src/observation/observation.types.d.ts.map +1 -0
  145. package/dist/src/observation/observation.types.js +59 -0
  146. package/dist/src/observation/observation.types.js.map +1 -0
  147. package/dist/src/observation/observer-script.d.ts +19 -0
  148. package/dist/src/observation/observer-script.d.ts.map +1 -0
  149. package/dist/src/observation/observer-script.js +569 -0
  150. package/dist/src/observation/observer-script.js.map +1 -0
  151. package/dist/src/query/index.d.ts +9 -0
  152. package/dist/src/query/index.d.ts.map +1 -0
  153. package/dist/src/query/index.js +10 -0
  154. package/dist/src/query/index.js.map +1 -0
  155. package/dist/src/query/query-engine.d.ts +111 -0
  156. package/dist/src/query/query-engine.d.ts.map +1 -0
  157. package/dist/src/query/query-engine.js +509 -0
  158. package/dist/src/query/query-engine.js.map +1 -0
  159. package/dist/src/query/types/index.d.ts +5 -0
  160. package/dist/src/query/types/index.d.ts.map +1 -0
  161. package/dist/src/query/types/index.js +5 -0
  162. package/dist/src/query/types/index.js.map +1 -0
  163. package/dist/src/query/types/query.types.d.ts +141 -0
  164. package/dist/src/query/types/query.types.d.ts.map +1 -0
  165. package/dist/src/query/types/query.types.js +19 -0
  166. package/dist/src/query/types/query.types.js.map +1 -0
  167. package/dist/src/renderer/budget-manager.d.ts +46 -0
  168. package/dist/src/renderer/budget-manager.d.ts.map +1 -0
  169. package/dist/src/renderer/budget-manager.js +133 -0
  170. package/dist/src/renderer/budget-manager.js.map +1 -0
  171. package/dist/src/renderer/constants.d.ts +38 -0
  172. package/dist/src/renderer/constants.d.ts.map +1 -0
  173. package/dist/src/renderer/constants.js +29 -0
  174. package/dist/src/renderer/constants.js.map +1 -0
  175. package/dist/src/renderer/index.d.ts +12 -0
  176. package/dist/src/renderer/index.d.ts.map +1 -0
  177. package/dist/src/renderer/index.js +16 -0
  178. package/dist/src/renderer/index.js.map +1 -0
  179. package/dist/src/renderer/section-renderers.d.ts +42 -0
  180. package/dist/src/renderer/section-renderers.d.ts.map +1 -0
  181. package/dist/src/renderer/section-renderers.js +252 -0
  182. package/dist/src/renderer/section-renderers.js.map +1 -0
  183. package/dist/src/renderer/token-counter.d.ts +45 -0
  184. package/dist/src/renderer/token-counter.d.ts.map +1 -0
  185. package/dist/src/renderer/token-counter.js +65 -0
  186. package/dist/src/renderer/token-counter.js.map +1 -0
  187. package/dist/src/renderer/types.d.ts +71 -0
  188. package/dist/src/renderer/types.d.ts.map +1 -0
  189. package/dist/src/renderer/types.js +7 -0
  190. package/dist/src/renderer/types.js.map +1 -0
  191. package/dist/src/renderer/xml-renderer.d.ts +42 -0
  192. package/dist/src/renderer/xml-renderer.d.ts.map +1 -0
  193. package/dist/src/renderer/xml-renderer.js +103 -0
  194. package/dist/src/renderer/xml-renderer.js.map +1 -0
  195. package/dist/src/server/index.d.ts +8 -0
  196. package/dist/src/server/index.d.ts.map +1 -0
  197. package/dist/src/server/index.js +8 -0
  198. package/dist/src/server/index.js.map +1 -0
  199. package/dist/src/server/mcp-server.d.ts +59 -0
  200. package/dist/src/server/mcp-server.d.ts.map +1 -0
  201. package/dist/src/server/mcp-server.js +140 -0
  202. package/dist/src/server/mcp-server.js.map +1 -0
  203. package/dist/src/server/server-config.d.ts +41 -0
  204. package/dist/src/server/server-config.d.ts.map +1 -0
  205. package/dist/src/server/server-config.js +80 -0
  206. package/dist/src/server/server-config.js.map +1 -0
  207. package/dist/src/server/session-store.d.ts +148 -0
  208. package/dist/src/server/session-store.d.ts.map +1 -0
  209. package/dist/src/server/session-store.js +224 -0
  210. package/dist/src/server/session-store.js.map +1 -0
  211. package/dist/src/shared/errors/browser-session.error.d.ts +102 -0
  212. package/dist/src/shared/errors/browser-session.error.d.ts.map +1 -0
  213. package/dist/src/shared/errors/browser-session.error.js +153 -0
  214. package/dist/src/shared/errors/browser-session.error.js.map +1 -0
  215. package/dist/src/shared/errors/index.d.ts +5 -0
  216. package/dist/src/shared/errors/index.d.ts.map +1 -0
  217. package/dist/src/shared/errors/index.js +5 -0
  218. package/dist/src/shared/errors/index.js.map +1 -0
  219. package/dist/src/shared/services/dom-transformer.service.d.ts +71 -0
  220. package/dist/src/shared/services/dom-transformer.service.d.ts.map +1 -0
  221. package/dist/src/shared/services/dom-transformer.service.js +190 -0
  222. package/dist/src/shared/services/dom-transformer.service.js.map +1 -0
  223. package/dist/src/shared/services/index.d.ts +7 -0
  224. package/dist/src/shared/services/index.d.ts.map +1 -0
  225. package/dist/src/shared/services/index.js +7 -0
  226. package/dist/src/shared/services/index.js.map +1 -0
  227. package/dist/src/shared/services/logging.service.d.ts +154 -0
  228. package/dist/src/shared/services/logging.service.d.ts.map +1 -0
  229. package/dist/src/shared/services/logging.service.js +267 -0
  230. package/dist/src/shared/services/logging.service.js.map +1 -0
  231. package/dist/src/shared/services/selector-builder.service.d.ts +53 -0
  232. package/dist/src/shared/services/selector-builder.service.d.ts.map +1 -0
  233. package/dist/src/shared/services/selector-builder.service.js +240 -0
  234. package/dist/src/shared/services/selector-builder.service.js.map +1 -0
  235. package/dist/src/shared/types/base.types.d.ts +45 -0
  236. package/dist/src/shared/types/base.types.d.ts.map +1 -0
  237. package/dist/src/shared/types/base.types.js +8 -0
  238. package/dist/src/shared/types/base.types.js.map +1 -0
  239. package/dist/src/shared/types/index.d.ts +5 -0
  240. package/dist/src/shared/types/index.d.ts.map +1 -0
  241. package/dist/src/shared/types/index.js +5 -0
  242. package/dist/src/shared/types/index.js.map +1 -0
  243. package/dist/src/snapshot/element-resolver.d.ts +102 -0
  244. package/dist/src/snapshot/element-resolver.d.ts.map +1 -0
  245. package/dist/src/snapshot/element-resolver.js +379 -0
  246. package/dist/src/snapshot/element-resolver.js.map +1 -0
  247. package/dist/src/snapshot/extractors/attribute-extractor.d.ts +40 -0
  248. package/dist/src/snapshot/extractors/attribute-extractor.d.ts.map +1 -0
  249. package/dist/src/snapshot/extractors/attribute-extractor.js +237 -0
  250. package/dist/src/snapshot/extractors/attribute-extractor.js.map +1 -0
  251. package/dist/src/snapshot/extractors/ax-extractor.d.ts +36 -0
  252. package/dist/src/snapshot/extractors/ax-extractor.d.ts.map +1 -0
  253. package/dist/src/snapshot/extractors/ax-extractor.js +144 -0
  254. package/dist/src/snapshot/extractors/ax-extractor.js.map +1 -0
  255. package/dist/src/snapshot/extractors/dom-extractor.d.ts +21 -0
  256. package/dist/src/snapshot/extractors/dom-extractor.d.ts.map +1 -0
  257. package/dist/src/snapshot/extractors/dom-extractor.js +137 -0
  258. package/dist/src/snapshot/extractors/dom-extractor.js.map +1 -0
  259. package/dist/src/snapshot/extractors/grouping-resolver.d.ts +39 -0
  260. package/dist/src/snapshot/extractors/grouping-resolver.d.ts.map +1 -0
  261. package/dist/src/snapshot/extractors/grouping-resolver.js +260 -0
  262. package/dist/src/snapshot/extractors/grouping-resolver.js.map +1 -0
  263. package/dist/src/snapshot/extractors/index.d.ts +19 -0
  264. package/dist/src/snapshot/extractors/index.d.ts.map +1 -0
  265. package/dist/src/snapshot/extractors/index.js +27 -0
  266. package/dist/src/snapshot/extractors/index.js.map +1 -0
  267. package/dist/src/snapshot/extractors/label-resolver.d.ts +44 -0
  268. package/dist/src/snapshot/extractors/label-resolver.d.ts.map +1 -0
  269. package/dist/src/snapshot/extractors/label-resolver.js +173 -0
  270. package/dist/src/snapshot/extractors/label-resolver.js.map +1 -0
  271. package/dist/src/snapshot/extractors/layout-extractor.d.ts +52 -0
  272. package/dist/src/snapshot/extractors/layout-extractor.d.ts.map +1 -0
  273. package/dist/src/snapshot/extractors/layout-extractor.js +382 -0
  274. package/dist/src/snapshot/extractors/layout-extractor.js.map +1 -0
  275. package/dist/src/snapshot/extractors/locator-builder.d.ts +27 -0
  276. package/dist/src/snapshot/extractors/locator-builder.d.ts.map +1 -0
  277. package/dist/src/snapshot/extractors/locator-builder.js +223 -0
  278. package/dist/src/snapshot/extractors/locator-builder.js.map +1 -0
  279. package/dist/src/snapshot/extractors/region-resolver.d.ts +31 -0
  280. package/dist/src/snapshot/extractors/region-resolver.d.ts.map +1 -0
  281. package/dist/src/snapshot/extractors/region-resolver.js +168 -0
  282. package/dist/src/snapshot/extractors/region-resolver.js.map +1 -0
  283. package/dist/src/snapshot/extractors/state-extractor.d.ts +30 -0
  284. package/dist/src/snapshot/extractors/state-extractor.d.ts.map +1 -0
  285. package/dist/src/snapshot/extractors/state-extractor.js +181 -0
  286. package/dist/src/snapshot/extractors/state-extractor.js.map +1 -0
  287. package/dist/src/snapshot/extractors/types.d.ts +213 -0
  288. package/dist/src/snapshot/extractors/types.d.ts.map +1 -0
  289. package/dist/src/snapshot/extractors/types.js +145 -0
  290. package/dist/src/snapshot/extractors/types.js.map +1 -0
  291. package/dist/src/snapshot/index.d.ts +14 -0
  292. package/dist/src/snapshot/index.d.ts.map +1 -0
  293. package/dist/src/snapshot/index.js +18 -0
  294. package/dist/src/snapshot/index.js.map +1 -0
  295. package/dist/src/snapshot/snapshot-compiler.d.ts +73 -0
  296. package/dist/src/snapshot/snapshot-compiler.d.ts.map +1 -0
  297. package/dist/src/snapshot/snapshot-compiler.js +763 -0
  298. package/dist/src/snapshot/snapshot-compiler.js.map +1 -0
  299. package/dist/src/snapshot/snapshot-health.d.ts +97 -0
  300. package/dist/src/snapshot/snapshot-health.d.ts.map +1 -0
  301. package/dist/src/snapshot/snapshot-health.js +214 -0
  302. package/dist/src/snapshot/snapshot-health.js.map +1 -0
  303. package/dist/src/snapshot/snapshot-store.d.ts +137 -0
  304. package/dist/src/snapshot/snapshot-store.d.ts.map +1 -0
  305. package/dist/src/snapshot/snapshot-store.js +202 -0
  306. package/dist/src/snapshot/snapshot-store.js.map +1 -0
  307. package/dist/src/snapshot/snapshot.types.d.ts +250 -0
  308. package/dist/src/snapshot/snapshot.types.d.ts.map +1 -0
  309. package/dist/src/snapshot/snapshot.types.js +54 -0
  310. package/dist/src/snapshot/snapshot.types.js.map +1 -0
  311. package/dist/src/state/actionables-filter.d.ts +47 -0
  312. package/dist/src/state/actionables-filter.d.ts.map +1 -0
  313. package/dist/src/state/actionables-filter.js +173 -0
  314. package/dist/src/state/actionables-filter.js.map +1 -0
  315. package/dist/src/state/atoms-extractor.d.ts +23 -0
  316. package/dist/src/state/atoms-extractor.d.ts.map +1 -0
  317. package/dist/src/state/atoms-extractor.js +160 -0
  318. package/dist/src/state/atoms-extractor.js.map +1 -0
  319. package/dist/src/state/constants.d.ts +125 -0
  320. package/dist/src/state/constants.d.ts.map +1 -0
  321. package/dist/src/state/constants.js +131 -0
  322. package/dist/src/state/constants.js.map +1 -0
  323. package/dist/src/state/diff-engine.d.ts +23 -0
  324. package/dist/src/state/diff-engine.d.ts.map +1 -0
  325. package/dist/src/state/diff-engine.js +475 -0
  326. package/dist/src/state/diff-engine.js.map +1 -0
  327. package/dist/src/state/element-identity.d.ts +75 -0
  328. package/dist/src/state/element-identity.d.ts.map +1 -0
  329. package/dist/src/state/element-identity.js +129 -0
  330. package/dist/src/state/element-identity.js.map +1 -0
  331. package/dist/src/state/element-ref.types.d.ts +135 -0
  332. package/dist/src/state/element-ref.types.d.ts.map +1 -0
  333. package/dist/src/state/element-ref.types.js +13 -0
  334. package/dist/src/state/element-ref.types.js.map +1 -0
  335. package/dist/src/state/element-registry.d.ts +118 -0
  336. package/dist/src/state/element-registry.d.ts.map +1 -0
  337. package/dist/src/state/element-registry.js +222 -0
  338. package/dist/src/state/element-registry.js.map +1 -0
  339. package/dist/src/state/health.types.d.ts +93 -0
  340. package/dist/src/state/health.types.d.ts.map +1 -0
  341. package/dist/src/state/health.types.js +56 -0
  342. package/dist/src/state/health.types.js.map +1 -0
  343. package/dist/src/state/layer-detector.d.ts +23 -0
  344. package/dist/src/state/layer-detector.d.ts.map +1 -0
  345. package/dist/src/state/layer-detector.js +368 -0
  346. package/dist/src/state/layer-detector.js.map +1 -0
  347. package/dist/src/state/locator-generator.d.ts +21 -0
  348. package/dist/src/state/locator-generator.d.ts.map +1 -0
  349. package/dist/src/state/locator-generator.js +137 -0
  350. package/dist/src/state/locator-generator.js.map +1 -0
  351. package/dist/src/state/state-manager.d.ts +104 -0
  352. package/dist/src/state/state-manager.d.ts.map +1 -0
  353. package/dist/src/state/state-manager.js +618 -0
  354. package/dist/src/state/state-manager.js.map +1 -0
  355. package/dist/src/state/state-renderer.d.ts +63 -0
  356. package/dist/src/state/state-renderer.d.ts.map +1 -0
  357. package/dist/src/state/state-renderer.js +340 -0
  358. package/dist/src/state/state-renderer.js.map +1 -0
  359. package/dist/src/state/types.d.ts +353 -0
  360. package/dist/src/state/types.d.ts.map +1 -0
  361. package/dist/src/state/types.js +8 -0
  362. package/dist/src/state/types.js.map +1 -0
  363. package/dist/src/tools/browser-tools.d.ts +140 -0
  364. package/dist/src/tools/browser-tools.d.ts.map +1 -0
  365. package/dist/src/tools/browser-tools.js +657 -0
  366. package/dist/src/tools/browser-tools.js.map +1 -0
  367. package/dist/src/tools/errors.d.ts +63 -0
  368. package/dist/src/tools/errors.d.ts.map +1 -0
  369. package/dist/src/tools/errors.js +86 -0
  370. package/dist/src/tools/errors.js.map +1 -0
  371. package/dist/src/tools/execute-action.d.ts +135 -0
  372. package/dist/src/tools/execute-action.d.ts.map +1 -0
  373. package/dist/src/tools/execute-action.js +579 -0
  374. package/dist/src/tools/execute-action.js.map +1 -0
  375. package/dist/src/tools/form-tools.d.ts +109 -0
  376. package/dist/src/tools/form-tools.d.ts.map +1 -0
  377. package/dist/src/tools/form-tools.js +434 -0
  378. package/dist/src/tools/form-tools.js.map +1 -0
  379. package/dist/src/tools/index.d.ts +11 -0
  380. package/dist/src/tools/index.d.ts.map +1 -0
  381. package/dist/src/tools/index.js +49 -0
  382. package/dist/src/tools/index.js.map +1 -0
  383. package/dist/src/tools/response-builder.d.ts +98 -0
  384. package/dist/src/tools/response-builder.d.ts.map +1 -0
  385. package/dist/src/tools/response-builder.js +219 -0
  386. package/dist/src/tools/response-builder.js.map +1 -0
  387. package/dist/src/tools/tool-schemas.d.ts +2482 -0
  388. package/dist/src/tools/tool-schemas.d.ts.map +1 -0
  389. package/dist/src/tools/tool-schemas.js +606 -0
  390. package/dist/src/tools/tool-schemas.js.map +1 -0
  391. package/dist/vitest.config.d.ts +3 -0
  392. package/dist/vitest.config.d.ts.map +1 -0
  393. package/dist/vitest.config.js +16 -0
  394. package/dist/vitest.config.js.map +1 -0
  395. package/package.json +76 -0
@@ -0,0 +1,379 @@
1
+ /**
2
+ * Element Resolver
3
+ *
4
+ * Resolves node_id from snapshot to actionable element.
5
+ * Provides CDP-based clicking using backendNodeId for guaranteed uniqueness.
6
+ */
7
+ /**
8
+ * Click an element using CDP's backendNodeId directly.
9
+ *
10
+ * This bypasses Playwright's locator system to avoid strict mode violations
11
+ * when multiple elements match the same selector. The backendNodeId is
12
+ * guaranteed unique per DOM element within a CDP session.
13
+ *
14
+ * @param cdp - CDP client instance
15
+ * @param backendNodeId - CDP backend node ID (stable within session)
16
+ * @throws Error if element not found, not visible, or click fails
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // Click using the unique backendNodeId from snapshot
21
+ * await clickByBackendNodeId(cdp, node.backend_node_id);
22
+ * ```
23
+ */
24
+ export async function clickByBackendNodeId(cdp, backendNodeId) {
25
+ // 1. Scroll element into view (ensures element is visible and clickable)
26
+ try {
27
+ await cdp.send('DOM.scrollIntoViewIfNeeded', { backendNodeId });
28
+ }
29
+ catch (error) {
30
+ const message = error instanceof Error ? error.message : String(error);
31
+ throw new Error(`Failed to scroll element into view (backendNodeId: ${backendNodeId}). ` +
32
+ `The element may have been removed from the DOM. ` +
33
+ `Try capturing a fresh snapshot. Original error: ${message}`);
34
+ }
35
+ // 2. Get element bounding box to calculate click coordinates
36
+ let model;
37
+ try {
38
+ const result = await cdp.send('DOM.getBoxModel', { backendNodeId });
39
+ model = result.model;
40
+ }
41
+ catch (error) {
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ throw new Error(`Failed to get element bounding box (backendNodeId: ${backendNodeId}). ` +
44
+ `The element may be hidden or have no layout. Original error: ${message}`);
45
+ }
46
+ // Validate we have a content box to click
47
+ if (!model?.content || model.content.length < 8) {
48
+ throw new Error(`Element has no clickable area (backendNodeId: ${backendNodeId}). ` +
49
+ `The element may be zero-sized or not rendered.`);
50
+ }
51
+ // The content quad is an array of 8 numbers: [x1,y1, x2,y2, x3,y3, x4,y4]
52
+ // representing the four corners of the content box in viewport coordinates.
53
+ // We click at the center of the content box.
54
+ const [x1, y1, x2, , , y3] = model.content;
55
+ const centerX = x1 + (x2 - x1) / 2;
56
+ const centerY = y1 + (y3 - y1) / 2;
57
+ // Validate coordinates are reasonable (not negative or extremely large)
58
+ if (centerX < 0 || centerY < 0 || !Number.isFinite(centerX) || !Number.isFinite(centerY)) {
59
+ throw new Error(`Invalid click coordinates (x: ${centerX}, y: ${centerY}) for backendNodeId: ${backendNodeId}. ` +
60
+ `The element may be positioned off-screen.`);
61
+ }
62
+ // 3. Click at the element's center using CDP Input domain
63
+ await cdp.send('Input.dispatchMouseEvent', {
64
+ type: 'mousePressed',
65
+ x: centerX,
66
+ y: centerY,
67
+ button: 'left',
68
+ clickCount: 1,
69
+ });
70
+ await cdp.send('Input.dispatchMouseEvent', {
71
+ type: 'mouseReleased',
72
+ x: centerX,
73
+ y: centerY,
74
+ button: 'left',
75
+ clickCount: 1,
76
+ });
77
+ }
78
+ // ============================================================================
79
+ // Modifier Bitmask Constants
80
+ // ============================================================================
81
+ /**
82
+ * CDP Input modifier bitmask values.
83
+ * These are ORed together for combined modifiers.
84
+ */
85
+ export const MODIFIER_ALT = 1;
86
+ export const MODIFIER_CTRL = 2;
87
+ export const MODIFIER_META = 4;
88
+ export const MODIFIER_SHIFT = 8;
89
+ // ============================================================================
90
+ // Key Code Mapping
91
+ // ============================================================================
92
+ /**
93
+ * Maps key names to their DOM key codes.
94
+ * Used for Input.dispatchKeyEvent CDP commands.
95
+ */
96
+ const KEY_DEFINITIONS = {
97
+ Enter: { code: 'Enter', keyCode: 13, key: 'Enter', text: '\r' },
98
+ Tab: { code: 'Tab', keyCode: 9, key: 'Tab' },
99
+ Escape: { code: 'Escape', keyCode: 27, key: 'Escape' },
100
+ Backspace: { code: 'Backspace', keyCode: 8, key: 'Backspace' },
101
+ Delete: { code: 'Delete', keyCode: 46, key: 'Delete' },
102
+ Space: { code: 'Space', keyCode: 32, key: ' ', text: ' ' },
103
+ ArrowUp: { code: 'ArrowUp', keyCode: 38, key: 'ArrowUp' },
104
+ ArrowDown: { code: 'ArrowDown', keyCode: 40, key: 'ArrowDown' },
105
+ ArrowLeft: { code: 'ArrowLeft', keyCode: 37, key: 'ArrowLeft' },
106
+ ArrowRight: { code: 'ArrowRight', keyCode: 39, key: 'ArrowRight' },
107
+ Home: { code: 'Home', keyCode: 36, key: 'Home' },
108
+ End: { code: 'End', keyCode: 35, key: 'End' },
109
+ PageUp: { code: 'PageUp', keyCode: 33, key: 'PageUp' },
110
+ PageDown: { code: 'PageDown', keyCode: 34, key: 'PageDown' },
111
+ };
112
+ /**
113
+ * Convert modifier names to CDP modifier bitmask.
114
+ */
115
+ function computeModifiers(modifiers) {
116
+ if (!modifiers)
117
+ return 0;
118
+ let bits = 0;
119
+ for (const mod of modifiers) {
120
+ switch (mod.toLowerCase()) {
121
+ case 'alt':
122
+ bits |= MODIFIER_ALT;
123
+ break;
124
+ case 'control':
125
+ case 'ctrl':
126
+ bits |= MODIFIER_CTRL;
127
+ break;
128
+ case 'meta':
129
+ case 'cmd':
130
+ case 'command':
131
+ bits |= MODIFIER_META;
132
+ break;
133
+ case 'shift':
134
+ bits |= MODIFIER_SHIFT;
135
+ break;
136
+ }
137
+ }
138
+ return bits;
139
+ }
140
+ // ============================================================================
141
+ // Helper: Get Element Center Coordinates
142
+ // ============================================================================
143
+ /**
144
+ * Get the center coordinates of an element by its backendNodeId.
145
+ * Scrolls the element into view first.
146
+ */
147
+ async function getElementCenter(cdp, backendNodeId) {
148
+ // Scroll into view
149
+ try {
150
+ await cdp.send('DOM.scrollIntoViewIfNeeded', { backendNodeId });
151
+ }
152
+ catch (error) {
153
+ const message = error instanceof Error ? error.message : String(error);
154
+ throw new Error(`Failed to scroll element into view (backendNodeId: ${backendNodeId}). ` +
155
+ `The element may have been removed from the DOM. Original error: ${message}`);
156
+ }
157
+ // Get bounding box
158
+ let model;
159
+ try {
160
+ const result = await cdp.send('DOM.getBoxModel', { backendNodeId });
161
+ model = result.model;
162
+ }
163
+ catch (error) {
164
+ const message = error instanceof Error ? error.message : String(error);
165
+ throw new Error(`Failed to get element bounding box (backendNodeId: ${backendNodeId}). ` +
166
+ `The element may be hidden or have no layout. Original error: ${message}`);
167
+ }
168
+ if (!model?.content || model.content.length < 8) {
169
+ throw new Error(`Element has no clickable area (backendNodeId: ${backendNodeId}). ` +
170
+ `The element may be zero-sized or not rendered.`);
171
+ }
172
+ const [x1, y1, x2, , , y3] = model.content;
173
+ const x = x1 + (x2 - x1) / 2;
174
+ const y = y1 + (y3 - y1) / 2;
175
+ if (x < 0 || y < 0 || !Number.isFinite(x) || !Number.isFinite(y)) {
176
+ throw new Error(`Invalid coordinates (x: ${x}, y: ${y}) for backendNodeId: ${backendNodeId}. ` +
177
+ `The element may be positioned off-screen.`);
178
+ }
179
+ return { x, y };
180
+ }
181
+ // ============================================================================
182
+ // Clear Text Helper
183
+ // ============================================================================
184
+ /**
185
+ * Clear text in the currently focused element using Ctrl+A then Delete.
186
+ *
187
+ * This helper is used by typeByBackendNodeId and can be used directly
188
+ * when typing into an already-focused element.
189
+ *
190
+ * @param cdp - CDP client instance
191
+ */
192
+ export async function clearFocusedText(cdp) {
193
+ // Select all (Ctrl+A)
194
+ await cdp.send('Input.dispatchKeyEvent', {
195
+ type: 'keyDown',
196
+ key: 'a',
197
+ code: 'KeyA',
198
+ modifiers: MODIFIER_CTRL,
199
+ windowsVirtualKeyCode: 65,
200
+ });
201
+ await cdp.send('Input.dispatchKeyEvent', {
202
+ type: 'keyUp',
203
+ key: 'a',
204
+ code: 'KeyA',
205
+ modifiers: MODIFIER_CTRL,
206
+ windowsVirtualKeyCode: 65,
207
+ });
208
+ // Delete selected text
209
+ await cdp.send('Input.dispatchKeyEvent', {
210
+ type: 'keyDown',
211
+ key: 'Delete',
212
+ code: 'Delete',
213
+ windowsVirtualKeyCode: 46,
214
+ });
215
+ await cdp.send('Input.dispatchKeyEvent', {
216
+ type: 'keyUp',
217
+ key: 'Delete',
218
+ code: 'Delete',
219
+ windowsVirtualKeyCode: 46,
220
+ });
221
+ }
222
+ // ============================================================================
223
+ // Type Text
224
+ // ============================================================================
225
+ /**
226
+ * Type text into an element using CDP.
227
+ *
228
+ * Focuses the element first (via click), optionally clears existing text,
229
+ * then inserts the new text.
230
+ *
231
+ * @param cdp - CDP client instance
232
+ * @param backendNodeId - Element to type into
233
+ * @param text - Text to type
234
+ * @param options.clear - If true, clears existing text first (Ctrl+A, Delete)
235
+ */
236
+ export async function typeByBackendNodeId(cdp, backendNodeId, text, options) {
237
+ // 1. Focus the element by clicking it
238
+ await clickByBackendNodeId(cdp, backendNodeId);
239
+ // 2. Clear existing text if requested
240
+ if (options?.clear) {
241
+ await clearFocusedText(cdp);
242
+ }
243
+ // 3. Insert text
244
+ await cdp.send('Input.insertText', { text });
245
+ }
246
+ // ============================================================================
247
+ // Press Key
248
+ // ============================================================================
249
+ /**
250
+ * Press a keyboard key using CDP.
251
+ *
252
+ * Sends keyDown and keyUp events for the specified key.
253
+ *
254
+ * @param cdp - CDP client instance
255
+ * @param key - Key name (e.g., 'Enter', 'Tab', 'Escape', 'ArrowDown')
256
+ * @param modifiers - Optional modifier keys ['Control', 'Shift', 'Alt', 'Meta']
257
+ */
258
+ export async function pressKey(cdp, key, modifiers) {
259
+ const keyDef = KEY_DEFINITIONS[key];
260
+ if (!keyDef) {
261
+ throw new Error(`Unknown key: "${key}". Supported keys: ${Object.keys(KEY_DEFINITIONS).join(', ')}`);
262
+ }
263
+ const modifierBits = computeModifiers(modifiers);
264
+ await cdp.send('Input.dispatchKeyEvent', {
265
+ type: 'keyDown',
266
+ key: keyDef.key,
267
+ code: keyDef.code,
268
+ windowsVirtualKeyCode: keyDef.keyCode,
269
+ modifiers: modifierBits,
270
+ text: keyDef.text,
271
+ });
272
+ await cdp.send('Input.dispatchKeyEvent', {
273
+ type: 'keyUp',
274
+ key: keyDef.key,
275
+ code: keyDef.code,
276
+ windowsVirtualKeyCode: keyDef.keyCode,
277
+ modifiers: modifierBits,
278
+ });
279
+ }
280
+ // ============================================================================
281
+ // Select Option
282
+ // ============================================================================
283
+ /**
284
+ * Select an option from a <select> element.
285
+ *
286
+ * Uses Runtime.callFunctionOn to set the select value and dispatch a change event.
287
+ *
288
+ * @param cdp - CDP client instance
289
+ * @param backendNodeId - The <select> element's backendNodeId
290
+ * @param value - Option value or visible text to select
291
+ * @returns The selected option's visible text
292
+ */
293
+ export async function selectOption(cdp, backendNodeId, value) {
294
+ // Resolve the backendNodeId to a Runtime object
295
+ const { object } = await cdp.send('DOM.resolveNode', { backendNodeId });
296
+ if (!object.objectId) {
297
+ throw new Error(`Failed to resolve element (backendNodeId: ${backendNodeId})`);
298
+ }
299
+ // Call a function on the element to select the option
300
+ const result = await cdp.send('Runtime.callFunctionOn', {
301
+ objectId: object.objectId,
302
+ functionDeclaration: `function(targetValue) {
303
+ if (this.tagName !== 'SELECT') {
304
+ throw new Error('Element is not a <select> element');
305
+ }
306
+ const options = Array.from(this.options);
307
+ const option = options.find(o =>
308
+ o.value === targetValue ||
309
+ o.text === targetValue ||
310
+ o.text.trim() === targetValue
311
+ );
312
+ if (!option) {
313
+ const available = options.map(o => o.text || o.value).join(', ');
314
+ throw new Error('Option not found: "' + targetValue + '". Available: ' + available);
315
+ }
316
+ this.value = option.value;
317
+ this.dispatchEvent(new Event('change', { bubbles: true }));
318
+ return option.text;
319
+ }`,
320
+ arguments: [{ value }],
321
+ returnByValue: true,
322
+ });
323
+ if (result.exceptionDetails) {
324
+ throw new Error(`Failed to select option: ${result.exceptionDetails.exception?.description ?? 'Unknown error'}`);
325
+ }
326
+ return result.result.value;
327
+ }
328
+ // ============================================================================
329
+ // Hover
330
+ // ============================================================================
331
+ /**
332
+ * Hover over an element using CDP.
333
+ *
334
+ * Scrolls the element into view and moves the mouse to its center.
335
+ *
336
+ * @param cdp - CDP client instance
337
+ * @param backendNodeId - Element to hover over
338
+ */
339
+ export async function hoverByBackendNodeId(cdp, backendNodeId) {
340
+ const { x, y } = await getElementCenter(cdp, backendNodeId);
341
+ await cdp.send('Input.dispatchMouseEvent', {
342
+ type: 'mouseMoved',
343
+ x,
344
+ y,
345
+ });
346
+ }
347
+ // ============================================================================
348
+ // Scroll
349
+ // ============================================================================
350
+ /**
351
+ * Scroll an element into view using CDP.
352
+ *
353
+ * @param cdp - CDP client instance
354
+ * @param backendNodeId - Element to scroll into view
355
+ */
356
+ export async function scrollIntoView(cdp, backendNodeId) {
357
+ try {
358
+ await cdp.send('DOM.scrollIntoViewIfNeeded', { backendNodeId });
359
+ }
360
+ catch (error) {
361
+ const message = error instanceof Error ? error.message : String(error);
362
+ throw new Error(`Failed to scroll element into view (backendNodeId: ${backendNodeId}). ` +
363
+ `Original error: ${message}`);
364
+ }
365
+ }
366
+ /**
367
+ * Scroll the page by a specified amount.
368
+ *
369
+ * @param cdp - CDP client instance
370
+ * @param direction - 'up' or 'down'
371
+ * @param amount - Pixels to scroll (default: 500)
372
+ */
373
+ export async function scrollPage(cdp, direction, amount = 500) {
374
+ const scrollY = direction === 'down' ? amount : -amount;
375
+ await cdp.send('Runtime.evaluate', {
376
+ expression: `window.scrollBy(0, ${scrollY})`,
377
+ });
378
+ }
379
+ //# sourceMappingURL=element-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element-resolver.js","sourceRoot":"","sources":["../../../src/snapshot/element-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Attribute Extractor
3
+ *
4
+ * Extracts element-specific attributes for the NodeAttributes field.
5
+ * Handles input type, placeholder, href, src, alt, heading level,
6
+ * form action/method, test IDs, and explicit role attributes.
7
+ *
8
+ * @module snapshot/extractors/attribute-extractor
9
+ */
10
+ import type { RawDomNode, RawAxNode } from './types.js';
11
+ import type { NodeKind, NodeAttributes } from '../snapshot.types.js';
12
+ /**
13
+ * Options for attribute extraction
14
+ */
15
+ export interface AttributeExtractionOptions {
16
+ /** Include input values (default: false for security) */
17
+ includeValues?: boolean;
18
+ /** Redact password field values (default: true) */
19
+ redactSensitive?: boolean;
20
+ /** Remove sensitive query params from URLs (default: true) */
21
+ sanitizeUrls?: boolean;
22
+ }
23
+ /**
24
+ * Sanitize a URL by removing sensitive query parameters.
25
+ *
26
+ * @param url - URL to sanitize
27
+ * @returns Sanitized URL
28
+ */
29
+ export declare function sanitizeUrl(url: string): string;
30
+ /**
31
+ * Extract element-specific attributes based on NodeKind.
32
+ *
33
+ * @param domNode - Raw DOM node (can be undefined)
34
+ * @param kind - Semantic node kind
35
+ * @param options - Extraction options
36
+ * @param axNode - Optional AX node for additional properties
37
+ * @returns NodeAttributes or undefined if no attributes
38
+ */
39
+ export declare function extractAttributes(domNode: RawDomNode | undefined, kind: NodeKind, options?: AttributeExtractionOptions, axNode?: RawAxNode): NodeAttributes | undefined;
40
+ //# sourceMappingURL=attribute-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribute-extractor.d.ts","sourceRoot":"","sources":["../../../../src/snapshot/extractors/attribute-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,yDAAyD;IACzD,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,mDAAmD;IACnD,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAyCD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA0B/C;AA2FD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,UAAU,GAAG,SAAS,EAC/B,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,0BAA+B,EACxC,MAAM,CAAC,EAAE,SAAS,GACjB,cAAc,GAAG,SAAS,CAgF5B"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Attribute Extractor
3
+ *
4
+ * Extracts element-specific attributes for the NodeAttributes field.
5
+ * Handles input type, placeholder, href, src, alt, heading level,
6
+ * form action/method, test IDs, and explicit role attributes.
7
+ *
8
+ * @module snapshot/extractors/attribute-extractor
9
+ */
10
+ /**
11
+ * Default extraction options
12
+ */
13
+ const DEFAULT_OPTIONS = {
14
+ includeValues: false,
15
+ redactSensitive: true,
16
+ sanitizeUrls: true,
17
+ };
18
+ /**
19
+ * Sensitive query parameter names to strip from URLs
20
+ */
21
+ const SENSITIVE_PARAMS = new Set([
22
+ 'token',
23
+ 'key',
24
+ 'api_key',
25
+ 'apikey',
26
+ 'auth',
27
+ 'password',
28
+ 'secret',
29
+ 'access_token',
30
+ 'refresh_token',
31
+ 'session',
32
+ 'sessionid',
33
+ 'session_id',
34
+ 'credential',
35
+ 'credentials',
36
+ ]);
37
+ /**
38
+ * Maximum URL length before truncation
39
+ */
40
+ const MAX_URL_LENGTH = 200;
41
+ /**
42
+ * Test ID attribute names in priority order
43
+ */
44
+ const TEST_ID_ATTRS = ['data-testid', 'data-test', 'data-cy', 'data-test-id'];
45
+ /**
46
+ * Sanitize a URL by removing sensitive query parameters.
47
+ *
48
+ * @param url - URL to sanitize
49
+ * @returns Sanitized URL
50
+ */
51
+ export function sanitizeUrl(url) {
52
+ // Handle relative URLs - just truncate if needed
53
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
54
+ return truncateUrl(url);
55
+ }
56
+ try {
57
+ const parsed = new URL(url);
58
+ // Remove sensitive params
59
+ const paramsToDelete = [];
60
+ for (const key of parsed.searchParams.keys()) {
61
+ const lowerKey = key.toLowerCase();
62
+ if (SENSITIVE_PARAMS.has(lowerKey)) {
63
+ paramsToDelete.push(key);
64
+ }
65
+ }
66
+ for (const key of paramsToDelete) {
67
+ parsed.searchParams.delete(key);
68
+ }
69
+ return truncateUrl(parsed.toString());
70
+ }
71
+ catch {
72
+ // Invalid URL, return as-is (truncated)
73
+ return truncateUrl(url);
74
+ }
75
+ }
76
+ /**
77
+ * Truncate a URL if it exceeds maximum length.
78
+ *
79
+ * @param url - URL to truncate
80
+ * @returns Truncated URL with '...' suffix if needed
81
+ */
82
+ function truncateUrl(url) {
83
+ if (url.length <= MAX_URL_LENGTH) {
84
+ return url;
85
+ }
86
+ return url.substring(0, MAX_URL_LENGTH) + '...';
87
+ }
88
+ /**
89
+ * Extract domain + path from an image src URL.
90
+ *
91
+ * @param src - Image source URL
92
+ * @returns Domain and path only (no query params)
93
+ */
94
+ function extractImageSrc(src) {
95
+ // Handle data URLs
96
+ if (src.startsWith('data:')) {
97
+ return '[data-url]';
98
+ }
99
+ // Handle relative URLs
100
+ if (!src.startsWith('http://') && !src.startsWith('https://')) {
101
+ return src;
102
+ }
103
+ try {
104
+ const parsed = new URL(src);
105
+ return `${parsed.host}${parsed.pathname}`;
106
+ }
107
+ catch {
108
+ return src;
109
+ }
110
+ }
111
+ /**
112
+ * Extract heading level from tag name.
113
+ *
114
+ * @param tagName - HTML tag name (e.g., 'H1', 'H2')
115
+ * @returns Heading level (1-6) or undefined
116
+ */
117
+ function getHeadingLevelFromTag(tagName) {
118
+ const match = /^H([1-6])$/.exec(tagName.toUpperCase());
119
+ if (match) {
120
+ return parseInt(match[1], 10);
121
+ }
122
+ return undefined;
123
+ }
124
+ /**
125
+ * Get heading level from AX node properties.
126
+ *
127
+ * @param axNode - Accessibility node
128
+ * @returns Heading level from AX properties or undefined
129
+ */
130
+ function getHeadingLevelFromAx(axNode) {
131
+ if (!axNode?.properties) {
132
+ return undefined;
133
+ }
134
+ const levelProp = axNode.properties.find((p) => p.name === 'level');
135
+ if (levelProp?.value?.value !== undefined) {
136
+ const level = Number(levelProp.value.value);
137
+ if (level >= 1 && level <= 6) {
138
+ return level;
139
+ }
140
+ }
141
+ return undefined;
142
+ }
143
+ /**
144
+ * Extract test ID from DOM attributes.
145
+ *
146
+ * @param attrs - DOM attributes
147
+ * @returns Test ID or undefined
148
+ */
149
+ function extractTestId(attrs) {
150
+ for (const attrName of TEST_ID_ATTRS) {
151
+ const value = attrs[attrName];
152
+ if (value) {
153
+ return value;
154
+ }
155
+ }
156
+ return undefined;
157
+ }
158
+ /**
159
+ * Extract element-specific attributes based on NodeKind.
160
+ *
161
+ * @param domNode - Raw DOM node (can be undefined)
162
+ * @param kind - Semantic node kind
163
+ * @param options - Extraction options
164
+ * @param axNode - Optional AX node for additional properties
165
+ * @returns NodeAttributes or undefined if no attributes
166
+ */
167
+ export function extractAttributes(domNode, kind, options = {}, axNode) {
168
+ if (!domNode) {
169
+ return undefined;
170
+ }
171
+ const opts = { ...DEFAULT_OPTIONS, ...options };
172
+ const attrs = {};
173
+ const domAttrs = domNode.attributes ?? {};
174
+ // Input type (for input and combobox kinds)
175
+ if ((kind === 'input' || kind === 'combobox') && domAttrs.type) {
176
+ attrs.input_type = domAttrs.type;
177
+ }
178
+ // Placeholder (any kind)
179
+ if (domAttrs.placeholder && domAttrs.placeholder.length > 0) {
180
+ attrs.placeholder = domAttrs.placeholder;
181
+ }
182
+ // Value extraction (with redaction)
183
+ if (opts.includeValues && domAttrs.value !== undefined) {
184
+ const isPassword = domAttrs.type?.toLowerCase() === 'password';
185
+ if (isPassword && opts.redactSensitive) {
186
+ attrs.value = '[REDACTED]';
187
+ }
188
+ else {
189
+ attrs.value = domAttrs.value;
190
+ }
191
+ }
192
+ // Link href (only for link kind)
193
+ if (kind === 'link' && domAttrs.href) {
194
+ attrs.href = opts.sanitizeUrls ? sanitizeUrl(domAttrs.href) : domAttrs.href;
195
+ }
196
+ // Image alt and src (only for image kind)
197
+ if (kind === 'image') {
198
+ if (domAttrs.alt) {
199
+ attrs.alt = domAttrs.alt;
200
+ }
201
+ if (domAttrs.src) {
202
+ attrs.src = extractImageSrc(domAttrs.src);
203
+ }
204
+ }
205
+ // Heading level (only for heading kind)
206
+ if (kind === 'heading') {
207
+ // AX tree level takes precedence (more accurate for ARIA headings)
208
+ const axLevel = getHeadingLevelFromAx(axNode);
209
+ const tagLevel = getHeadingLevelFromTag(domNode.nodeName);
210
+ attrs.heading_level = axLevel ?? tagLevel;
211
+ }
212
+ // Form action and method (only for form kind)
213
+ if (kind === 'form') {
214
+ if (domAttrs.action) {
215
+ attrs.action = domAttrs.action;
216
+ }
217
+ if (domAttrs.method) {
218
+ attrs.method = domAttrs.method;
219
+ }
220
+ }
221
+ // Autocomplete (for input/select/combobox kinds)
222
+ if (domAttrs.autocomplete) {
223
+ attrs.autocomplete = domAttrs.autocomplete;
224
+ }
225
+ // Test ID (any kind)
226
+ const testId = extractTestId(domAttrs);
227
+ if (testId) {
228
+ attrs.test_id = testId;
229
+ }
230
+ // Explicit role attribute (any kind)
231
+ if (domAttrs.role) {
232
+ attrs.role = domAttrs.role;
233
+ }
234
+ // Return undefined if no attributes were extracted
235
+ return Object.keys(attrs).length > 0 ? attrs : undefined;
236
+ }
237
+ //# sourceMappingURL=attribute-extractor.js.map