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,213 @@
1
+ /**
2
+ * Manages persistent DOM observation for a page.
3
+ *
4
+ * Lifecycle:
5
+ * - inject() on page creation
6
+ * - ensureInjected() after navigation (document context changes)
7
+ * - getObservations() to retrieve significant mutations
8
+ */
9
+ import { OBSERVATION_OBSERVER_SCRIPT } from './observer-script.js';
10
+ import { SIGNIFICANCE_THRESHOLD } from './observation.types.js';
11
+ /**
12
+ * Manages persistent DOM observation for a page.
13
+ */
14
+ export class ObservationAccumulator {
15
+ /**
16
+ * Inject the persistent observer into the page.
17
+ * Safe to call multiple times - checks for existing injection.
18
+ */
19
+ async inject(page) {
20
+ try {
21
+ await page.evaluate(OBSERVATION_OBSERVER_SCRIPT);
22
+ }
23
+ catch (err) {
24
+ // Page may be navigating or closed - log but don't throw
25
+ console.warn('[ObservationAccumulator] Injection failed:', err);
26
+ }
27
+ }
28
+ /**
29
+ * Ensure observer is injected and valid (re-inject if needed after navigation).
30
+ *
31
+ * After navigation or page content changes, the observer might be stale
32
+ * (observing a detached body). We check if the observer's body reference
33
+ * matches the current document.body and only re-inject if stale.
34
+ *
35
+ * This preserves accumulated observations when the observer is still valid.
36
+ */
37
+ async ensureInjected(page) {
38
+ const needsReinjection = await page
39
+ .evaluate(() => {
40
+ // Browser context code - globalThis access is intentional
41
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */
42
+ const acc = globalThis.__observationAccumulator;
43
+ // No accumulator - need to inject
44
+ if (!acc)
45
+ return true;
46
+ // Check if observer is stale (observing a different/detached body)
47
+ // This happens after setContent() or navigation that replaces the body
48
+ const currentBody = globalThis.document?.body;
49
+ if (acc.observedBody !== currentBody) {
50
+ // Observer is stale - disconnect and remove so we can re-inject
51
+ acc.observer?.disconnect();
52
+ delete globalThis.__observationAccumulator;
53
+ return true;
54
+ }
55
+ // Observer is still valid - no need to re-inject
56
+ return false;
57
+ })
58
+ .catch(() => {
59
+ // Error checking - assume we need to inject
60
+ return true;
61
+ });
62
+ if (needsReinjection) {
63
+ await this.inject(page);
64
+ }
65
+ }
66
+ /**
67
+ * Get observations for an action.
68
+ * Returns both action-scoped and unreported accumulated observations.
69
+ */
70
+ async getObservations(page, actionStartTime) {
71
+ try {
72
+ // Browser context code - uses injected __observationAccumulator
73
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */
74
+ const result = await page.evaluate((since) => {
75
+ const acc = globalThis.__observationAccumulator;
76
+ if (!acc)
77
+ return {
78
+ duringAction: [],
79
+ sincePrevious: [],
80
+ };
81
+ // Get observations during this action
82
+ const duringAction = acc.getSignificant(since, undefined);
83
+ // Get unreported observations from before this action
84
+ const allUnreported = acc.getUnreported();
85
+ const sincePrevious = allUnreported.filter((e) => e.timestamp < since);
86
+ // Mark all as reported
87
+ acc.markReported();
88
+ return { duringAction, sincePrevious };
89
+ }, actionStartTime);
90
+ // Convert raw entries to DOMObservation format
91
+ return {
92
+ duringAction: result.duringAction.map((e) => this.rawToObservation(e)),
93
+ sincePrevious: result.sincePrevious.map((e) => ({
94
+ ...this.rawToObservation(e),
95
+ ageMs: Date.now() - e.timestamp,
96
+ })),
97
+ };
98
+ }
99
+ catch {
100
+ return { duringAction: [], sincePrevious: [] };
101
+ }
102
+ }
103
+ /**
104
+ * Get accumulated observations without action context.
105
+ * Used by capture_snapshot to report accumulated changes.
106
+ */
107
+ async getAccumulatedObservations(page) {
108
+ try {
109
+ // Browser context code - uses injected __observationAccumulator
110
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */
111
+ const result = await page.evaluate(() => {
112
+ const acc = globalThis.__observationAccumulator;
113
+ if (!acc)
114
+ return { sincePrevious: [] };
115
+ // Get all unreported observations
116
+ const sincePrevious = acc.getUnreported();
117
+ // Mark all as reported
118
+ acc.markReported();
119
+ return { sincePrevious };
120
+ });
121
+ return {
122
+ duringAction: [],
123
+ sincePrevious: result.sincePrevious.map((e) => ({
124
+ ...this.rawToObservation(e),
125
+ ageMs: Date.now() - e.timestamp,
126
+ })),
127
+ };
128
+ }
129
+ catch {
130
+ return { duringAction: [], sincePrevious: [] };
131
+ }
132
+ }
133
+ /**
134
+ * Convert raw mutation entry to DOMObservation.
135
+ */
136
+ rawToObservation(entry) {
137
+ const signals = {
138
+ hasAlertRole: ['alert', 'status', 'log', 'alertdialog'].includes(entry.role ?? ''),
139
+ hasAriaLive: entry.ariaLive === 'polite' || entry.ariaLive === 'assertive',
140
+ isDialog: entry.role === 'dialog' || entry.tag === 'dialog' || entry.ariaModal === 'true',
141
+ isFixedOrSticky: entry.isFixedOrSticky,
142
+ hasHighZIndex: entry.zIndex > 1000,
143
+ coversSignificantViewport: entry.viewportCoverage.widthPct > 50 || entry.viewportCoverage.heightPct > 30,
144
+ isBodyDirectChild: entry.isBodyDirectChild,
145
+ containsInteractiveElements: entry.hasInteractives,
146
+ isVisibleInViewport: entry.isVisibleInViewport ?? false,
147
+ hasNonTrivialText: entry.hasNonTrivialText ?? false,
148
+ appearedAfterDelay: entry.appearedAfterDelay ?? false,
149
+ wasShortLived: false, // Computed when we see removal
150
+ };
151
+ return {
152
+ type: entry.type === 'added' ? 'appeared' : 'disappeared',
153
+ significance: entry.significance,
154
+ signals,
155
+ content: {
156
+ tag: entry.tag,
157
+ role: entry.role,
158
+ ariaLabel: entry.ariaLabel,
159
+ text: entry.text,
160
+ hasInteractives: entry.hasInteractives,
161
+ },
162
+ timestamp: entry.timestamp,
163
+ reported: false,
164
+ // Include shadow path if present (for shadow DOM observations)
165
+ shadowPath: entry.shadowPath,
166
+ };
167
+ }
168
+ /**
169
+ * Reset observation log (call after navigation).
170
+ */
171
+ async reset(page) {
172
+ try {
173
+ // Browser context code - uses injected __observationAccumulator
174
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */
175
+ await page.evaluate(() => {
176
+ globalThis.__observationAccumulator?.reset();
177
+ });
178
+ }
179
+ catch {
180
+ // Ignore - page may be navigating
181
+ }
182
+ }
183
+ /**
184
+ * Check if there are any unreported observations.
185
+ */
186
+ async hasUnreported(page) {
187
+ try {
188
+ // Browser context code - uses injected __observationAccumulator
189
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */
190
+ return await page.evaluate(() => {
191
+ const acc = globalThis.__observationAccumulator;
192
+ if (!acc)
193
+ return false;
194
+ return acc.getUnreported().length > 0;
195
+ });
196
+ }
197
+ catch {
198
+ return false;
199
+ }
200
+ }
201
+ /**
202
+ * Filter observations by significance threshold.
203
+ */
204
+ filterBySignificance(observations, threshold = SIGNIFICANCE_THRESHOLD) {
205
+ return {
206
+ duringAction: observations.duringAction.filter((o) => o.significance >= threshold),
207
+ sincePrevious: observations.sincePrevious.filter((o) => o.significance >= threshold),
208
+ };
209
+ }
210
+ }
211
+ // Singleton instance
212
+ export const observationAccumulator = new ObservationAccumulator();
213
+ //# sourceMappingURL=observation-accumulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation-accumulator.js","sourceRoot":"","sources":["../../../src/observation/observation-accumulator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACjC;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,IAAU;QACrB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,yDAAyD;YACzD,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,GAAG,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,cAAc,CAAC,IAAU;QAC7B,MAAM,gBAAgB,GAAG,MAAM,IAAI;aAChC,QAAQ,CAAC,GAAG,EAAE;YACb,0DAA0D;YAC1D,+KAA+K;YAC/K,MAAM,GAAG,GAAI,UAAkB,CAAC,wBAAwB,CAAC;YAEzD,kCAAkC;YAClC,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YAEtB,mEAAmE;YACnE,uEAAuE;YACvE,MAAM,WAAW,GAAI,UAAkB,CAAC,QAAQ,EAAE,IAAI,CAAC;YACvD,IAAI,GAAG,CAAC,YAAY,KAAK,WAAW,EAAE,CAAC;gBACrC,gEAAgE;gBAChE,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC;gBAC3B,OAAQ,UAAkB,CAAC,wBAAwB,CAAC;gBACpD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,iDAAiD;YACjD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,4CAA4C;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEL,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,IAAU,EAAE,eAAuB;QACvD,IAAI,CAAC;YACH,gEAAgE;YAChE,+KAA+K;YAC/K,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAa,EAAE,EAAE;gBACnD,MAAM,GAAG,GAAI,UAAkB,CAAC,wBAAwB,CAAC;gBACzD,IAAI,CAAC,GAAG;oBACN,OAAO;wBACL,YAAY,EAAE,EAAwB;wBACtC,aAAa,EAAE,EAAwB;qBACxC,CAAC;gBAEJ,sCAAsC;gBACtC,MAAM,YAAY,GAAG,GAAG,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,CAAuB,CAAC;gBAEhF,sDAAsD;gBACtD,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,EAAwB,CAAC;gBAChE,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;gBAEzF,uBAAuB;gBACvB,GAAG,CAAC,YAAY,EAAE,CAAC;gBAEnB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;YACzC,CAAC,EAAE,eAAe,CAAC,CAAC;YAEpB,+CAA+C;YAC/C,OAAO;gBACL,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;gBACxF,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC;oBAChE,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAC3B,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS;iBAChC,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;QACjD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,0BAA0B,CAAC,IAAU;QACzC,IAAI,CAAC;YACH,gEAAgE;YAChE,+KAA+K;YAC/K,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACtC,MAAM,GAAG,GAAI,UAAkB,CAAC,wBAAwB,CAAC;gBACzD,IAAI,CAAC,GAAG;oBAAE,OAAO,EAAE,aAAa,EAAE,EAAwB,EAAE,CAAC;gBAE7D,kCAAkC;gBAClC,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,EAAwB,CAAC;gBAEhE,uBAAuB;gBACvB,GAAG,CAAC,YAAY,EAAE,CAAC;gBAEnB,OAAO,EAAE,aAAa,EAAE,CAAC;YAC3B,CAAC,CAAC,CAAC;YAEH,OAAO;gBACL,YAAY,EAAE,EAAE;gBAChB,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC;oBAChE,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAC3B,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS;iBAChC,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;QACjD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,KAAuB;QAC9C,MAAM,OAAO,GAAwB;YACnC,YAAY,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;YAClF,WAAW,EAAE,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,KAAK,WAAW;YAC1E,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,MAAM;YACzF,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,aAAa,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI;YAClC,yBAAyB,EACvB,KAAK,CAAC,gBAAgB,CAAC,QAAQ,GAAG,EAAE,IAAI,KAAK,CAAC,gBAAgB,CAAC,SAAS,GAAG,EAAE;YAC/E,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,2BAA2B,EAAE,KAAK,CAAC,eAAe;YAClD,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,IAAI,KAAK;YACvD,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,IAAI,KAAK;YACnD,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,IAAI,KAAK;YACrD,aAAa,EAAE,KAAK,EAAE,+BAA+B;SACtD,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa;YACzD,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,OAAO;YACP,OAAO,EAAE;gBACP,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,eAAe,EAAE,KAAK,CAAC,eAAe;aACvC;YACD,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,QAAQ,EAAE,KAAK;YACf,+DAA+D;YAC/D,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,IAAU;QACpB,IAAI,CAAC;YACH,gEAAgE;YAChE,sIAAsI;YACtI,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACtB,UAAkB,CAAC,wBAAwB,EAAE,KAAK,EAAE,CAAC;YACxD,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,IAAU;QAC5B,IAAI,CAAC;YACH,gEAAgE;YAChE,+KAA+K;YAC/K,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;gBAC9B,MAAM,GAAG,GAAI,UAAkB,CAAC,wBAAwB,CAAC;gBACzD,IAAI,CAAC,GAAG;oBAAE,OAAO,KAAK,CAAC;gBACvB,OAAO,GAAG,CAAC,aAAa,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,oBAAoB,CAClB,YAA+B,EAC/B,YAAoB,sBAAsB;QAE1C,OAAO;YACL,YAAY,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,CAAC;YAClF,aAAa,EAAE,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,CAAC;SACrF,CAAC;IACJ,CAAC;CACF;AAED,qBAAqB;AACrB,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Types and interfaces for DOM observation capture.
3
+ *
4
+ * DOM Observations capture significant mutations (toasts, dialogs, banners, overlays)
5
+ * that appear during or between actions. These are integrated as "observations" in
6
+ * the snapshot response.
7
+ */
8
+ /**
9
+ * Signals used to compute significance of a DOM mutation.
10
+ * All signals are derived from universal web standards - no hardcoded patterns.
11
+ */
12
+ export interface SignificanceSignals {
13
+ hasAlertRole: boolean;
14
+ hasAriaLive: boolean;
15
+ isDialog: boolean;
16
+ isFixedOrSticky: boolean;
17
+ hasHighZIndex: boolean;
18
+ coversSignificantViewport: boolean;
19
+ isBodyDirectChild: boolean;
20
+ containsInteractiveElements: boolean;
21
+ isVisibleInViewport: boolean;
22
+ hasNonTrivialText: boolean;
23
+ appearedAfterDelay: boolean;
24
+ wasShortLived: boolean;
25
+ }
26
+ /**
27
+ * Significance scoring weights.
28
+ * Total score >= SIGNIFICANCE_THRESHOLD to be included in observations.
29
+ */
30
+ export declare const SIGNIFICANCE_WEIGHTS: Record<keyof SignificanceSignals, number>;
31
+ export declare const SIGNIFICANCE_THRESHOLD = 4;
32
+ /**
33
+ * Higher threshold for attaching observations to tool responses.
34
+ *
35
+ * Two-Tier Filtering Strategy:
36
+ * ----------------------------
37
+ * Tier 1 (Browser-side, threshold=4): SIGNIFICANCE_THRESHOLD
38
+ * - Applied in observer-script.ts during DOM mutation capture
39
+ * - Filters out clearly insignificant mutations at capture time
40
+ *
41
+ * Tier 2 (Attachment-time, threshold=5): ATTACHMENT_SIGNIFICANCE_THRESHOLD
42
+ * - Applied when attaching observations to snapshot responses
43
+ * - Requires semantic signal (ARIA role) + visual/structural signals
44
+ * - Reduces response verbosity for the LLM
45
+ */
46
+ export declare const ATTACHMENT_SIGNIFICANCE_THRESHOLD = 5;
47
+ /**
48
+ * Compute significance score from signals.
49
+ */
50
+ export declare function computeSignificance(signals: SignificanceSignals): number;
51
+ /**
52
+ * Content captured from an observed element.
53
+ */
54
+ export interface ObservedContent {
55
+ tag: string;
56
+ role?: string;
57
+ ariaLabel?: string;
58
+ text: string;
59
+ hasInteractives: boolean;
60
+ }
61
+ /**
62
+ * Child element within an observation.
63
+ * Represents actionable or notable elements inside an observed container.
64
+ */
65
+ export interface ObservationChild {
66
+ /** Element type: 'button', 'link', 'heading', 'text', etc. */
67
+ tag: string;
68
+ /** Element identifier for targeting (if available) */
69
+ eid?: string;
70
+ /** Visible text content */
71
+ text: string;
72
+ }
73
+ /**
74
+ * A single DOM observation - an element that appeared or disappeared.
75
+ */
76
+ export interface DOMObservation {
77
+ type: 'appeared' | 'disappeared';
78
+ /** Computed significance score */
79
+ significance: number;
80
+ /** Signals that contributed to the score */
81
+ signals: SignificanceSignals;
82
+ /** Element content */
83
+ content: ObservedContent;
84
+ /** If element still exists in snapshot, its eid for targeting */
85
+ eid?: string;
86
+ /** When the mutation occurred (epoch ms) */
87
+ timestamp: number;
88
+ /** For 'disappeared': how long element was visible (ms) */
89
+ durationMs?: number;
90
+ /** For unreported observations: time since observation (ms) */
91
+ ageMs?: number;
92
+ /** Has this observation been included in a response? */
93
+ reported: boolean;
94
+ /** Shadow DOM path - identifiers of shadow host ancestors (for shadow DOM observations) */
95
+ shadowPath?: string[];
96
+ /** Interactive/notable children within this observation (for appeared elements) */
97
+ children?: ObservationChild[];
98
+ /** Delay in ms from action start to when this element appeared */
99
+ delayMs?: number;
100
+ }
101
+ /**
102
+ * Raw mutation entry captured by the persistent observer.
103
+ * Lives in browser context (window.__observationAccumulator).
104
+ */
105
+ export interface RawMutationEntry {
106
+ type: 'added' | 'removed';
107
+ timestamp: number;
108
+ tag: string;
109
+ id?: string;
110
+ role?: string;
111
+ ariaLive?: string;
112
+ ariaLabel?: string;
113
+ ariaModal?: string;
114
+ text: string;
115
+ hasInteractives: boolean;
116
+ isFixedOrSticky: boolean;
117
+ zIndex: number;
118
+ viewportCoverage: {
119
+ widthPct: number;
120
+ heightPct: number;
121
+ };
122
+ isBodyDirectChild: boolean;
123
+ isVisibleInViewport?: boolean;
124
+ hasNonTrivialText?: boolean;
125
+ appearedAfterDelay?: boolean;
126
+ /** Shadow path - identifiers of shadow host ancestors (for shadow DOM observations) */
127
+ shadowPath?: string[];
128
+ significance: number;
129
+ }
130
+ /**
131
+ * Observations grouped by when they occurred.
132
+ */
133
+ export interface ObservationGroups {
134
+ /** Observations from the current action's time window */
135
+ duringAction: DOMObservation[];
136
+ /** Accumulated observations since previous tool call */
137
+ sincePrevious: DOMObservation[];
138
+ }
139
+ //# sourceMappingURL=observation.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation.types.d.ts","sourceRoot":"","sources":["../../../src/observation/observation.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Types and interfaces for DOM observation capture.
3
+ *
4
+ * DOM Observations capture significant mutations (toasts, dialogs, banners, overlays)
5
+ * that appear during or between actions. These are integrated as "observations" in
6
+ * the snapshot response.
7
+ */
8
+ /**
9
+ * Significance scoring weights.
10
+ * Total score >= SIGNIFICANCE_THRESHOLD to be included in observations.
11
+ */
12
+ export const SIGNIFICANCE_WEIGHTS = {
13
+ // Semantic (strongest signals)
14
+ hasAlertRole: 3,
15
+ hasAriaLive: 3,
16
+ isDialog: 3,
17
+ // Visual signals
18
+ isFixedOrSticky: 2,
19
+ hasHighZIndex: 1,
20
+ coversSignificantViewport: 2,
21
+ // Structural signals
22
+ isBodyDirectChild: 1,
23
+ containsInteractiveElements: 1,
24
+ // Universal signals (work without ARIA)
25
+ isVisibleInViewport: 2,
26
+ hasNonTrivialText: 1,
27
+ // Temporal signals
28
+ appearedAfterDelay: 2,
29
+ wasShortLived: 2,
30
+ };
31
+ export const SIGNIFICANCE_THRESHOLD = 4;
32
+ /**
33
+ * Higher threshold for attaching observations to tool responses.
34
+ *
35
+ * Two-Tier Filtering Strategy:
36
+ * ----------------------------
37
+ * Tier 1 (Browser-side, threshold=4): SIGNIFICANCE_THRESHOLD
38
+ * - Applied in observer-script.ts during DOM mutation capture
39
+ * - Filters out clearly insignificant mutations at capture time
40
+ *
41
+ * Tier 2 (Attachment-time, threshold=5): ATTACHMENT_SIGNIFICANCE_THRESHOLD
42
+ * - Applied when attaching observations to snapshot responses
43
+ * - Requires semantic signal (ARIA role) + visual/structural signals
44
+ * - Reduces response verbosity for the LLM
45
+ */
46
+ export const ATTACHMENT_SIGNIFICANCE_THRESHOLD = 5;
47
+ /**
48
+ * Compute significance score from signals.
49
+ */
50
+ export function computeSignificance(signals) {
51
+ let score = 0;
52
+ for (const [key, weight] of Object.entries(SIGNIFICANCE_WEIGHTS)) {
53
+ if (signals[key]) {
54
+ score += weight;
55
+ }
56
+ }
57
+ return score;
58
+ }
59
+ //# sourceMappingURL=observation.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation.types.js","sourceRoot":"","sources":["../../../src/observation/observation.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA8BH;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA8C;IAC7E,+BAA+B;IAC/B,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC;IAEX,iBAAiB;IACjB,eAAe,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC;IAChB,yBAAyB,EAAE,CAAC;IAE5B,qBAAqB;IACrB,iBAAiB,EAAE,CAAC;IACpB,2BAA2B,EAAE,CAAC;IAE9B,wCAAwC;IACxC,mBAAmB,EAAE,CAAC;IACtB,iBAAiB,EAAE,CAAC;IAEpB,mBAAmB;IACnB,kBAAkB,EAAE,CAAC;IACrB,aAAa,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA4B;IAC9D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACjE,IAAI,OAAO,CAAC,GAAgC,CAAC,EAAE,CAAC;YAC9C,KAAK,IAAI,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Browser-side script for DOM observation.
3
+ *
4
+ * This script is injected into the browser context and runs continuously to capture
5
+ * significant DOM mutations. It uses universal web standards for significance detection -
6
+ * NO hardcoded text/class patterns.
7
+ *
8
+ * Shadow DOM Support:
9
+ * - Detects shadow hosts when elements are added
10
+ * - Attaches MutationObservers to open shadow roots
11
+ * - Tracks shadow path context for observations
12
+ * - Cleans up observers when shadow hosts are removed
13
+ *
14
+ * Note: Closed shadow roots cannot be observed (browser security).
15
+ *
16
+ * The script is returned as a string for page.evaluate().
17
+ */
18
+ export declare const OBSERVATION_OBSERVER_SCRIPT = "\n(function() {\n // Prevent double-injection\n if (window.__observationAccumulator) return;\n\n const MAX_ENTRIES = 500;\n const MAX_TEXT_LENGTH = 200;\n const MAX_SHADOW_OBSERVERS = 50; // Limit to prevent performance issues\n // IMPORTANT: Must match SIGNIFICANCE_THRESHOLD in observation.types.ts\n const SIGNIFICANCE_THRESHOLD = 4;\n // Node type constant for shadow root parent check\n const DOCUMENT_FRAGMENT_NODE = 11;\n\n // Significance weights (must match server-side observation.types.ts)\n const WEIGHTS = {\n // Semantic signals (strongest)\n hasAlertRole: 3,\n hasAriaLive: 3,\n isDialog: 3,\n\n // Visual signals\n isFixedOrSticky: 2,\n hasHighZIndex: 1,\n coversSignificantViewport: 2,\n\n // Structural signals\n isBodyDirectChild: 1,\n containsInteractiveElements: 1,\n\n // New universal signals - work without ARIA\n isVisibleInViewport: 2, // Element is visible in viewport\n hasNonTrivialText: 1, // Has meaningful text content\n // Temporal signals computed later\n };\n\n // Shadow DOM tracking\n // Map: shadowRoot -> { observer, hostPath }\n const shadowObservers = new Map();\n\n // Track processed elements to avoid duplicate observations\n // WeakSet allows garbage collection of removed elements\n let processedElements = new WeakSet();\n\n /**\n * Generate a stable identifier for an element (for shadow path tracking).\n * Format: TAG#id or TAG.className or TAG[index]\n */\n function getElementIdentifier(el) {\n const tag = el.tagName.toLowerCase();\n if (el.id) {\n return tag + '#' + el.id;\n }\n // For custom elements, use the tag name (usually descriptive like 'my-toast')\n if (tag.includes('-')) {\n return tag;\n }\n // Fallback: use first class or just tag\n const className = el.className && typeof el.className === 'string'\n ? el.className.split(' ')[0]\n : '';\n if (className) {\n return tag + '.' + className;\n }\n return tag;\n }\n\n // Tags whose text content should be excluded from extraction\n const EXCLUDED_TEXT_TAGS = new Set(['STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE', 'SVG']);\n\n /**\n * Get clean text content from an element, excluding CSS/JS content.\n * Uses TreeWalker to iterate only text nodes, skipping those inside\n * excluded tags (STYLE, SCRIPT, NOSCRIPT, TEMPLATE, SVG).\n *\n * @param {Element} el - The DOM element to extract text from\n * @param {number} maxLength - Maximum text length (truncates result)\n * @returns {string} Clean text content, space-joined, truncated to maxLength\n */\n function getCleanTextContent(el, maxLength) {\n // If element itself is an excluded tag, return empty\n if (EXCLUDED_TEXT_TAGS.has(el.tagName.toUpperCase())) {\n return '';\n }\n\n const walker = document.createTreeWalker(el, 4, { // NodeFilter.SHOW_TEXT = 4\n acceptNode: function(node) {\n let parent = node.parentElement;\n while (parent && parent !== el) {\n if (EXCLUDED_TEXT_TAGS.has(parent.tagName.toUpperCase())) {\n return 2; // FILTER_REJECT\n }\n parent = parent.parentElement;\n }\n return 1; // FILTER_ACCEPT\n }\n });\n\n const textParts = [];\n let totalLength = 0;\n let node;\n\n while ((node = walker.nextNode()) && totalLength < maxLength) {\n const text = node.nodeValue;\n if (text) {\n const trimmed = text.trim();\n if (trimmed) {\n textParts.push(trimmed);\n totalLength += trimmed.length;\n }\n }\n }\n\n return textParts.join(' ').substring(0, maxLength);\n }\n\n /**\n * Compute significance signals from element.\n * Uses universal web standards (ARIA, CSS positioning, DOM structure, visibility).\n */\n function computeSignals(el, shadowPath) {\n const role = el.getAttribute('role');\n const ariaLive = el.getAttribute('aria-live');\n const ariaModal = el.getAttribute('aria-modal');\n const tagName = el.tagName.toLowerCase();\n\n // Get computed style (may fail for detached elements)\n let style = null;\n let rect = null;\n try {\n style = getComputedStyle(el);\n rect = el.getBoundingClientRect();\n } catch (e) {\n // Element may be detached\n }\n\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n // Check if element is visible in viewport\n const isVisibleInViewport = rect && style &&\n rect.width > 0 && rect.height > 0 &&\n rect.bottom > 0 && rect.top < vh &&\n rect.right > 0 && rect.left < vw &&\n style.display !== 'none' &&\n style.visibility !== 'hidden' &&\n style.opacity !== '0';\n\n // Check for non-trivial text (at least 3 chars, not just whitespace)\n // Use short sample for signal check - excludes style/script content\n const text = getCleanTextContent(el, 100);\n const hasNonTrivialText = text.length >= 3;\n\n // For shadow DOM elements, isBodyDirectChild is false but we still want to capture them\n // Check if parent is a shadow root (which indicates top-level in shadow DOM)\n const isTopLevelInShadow = shadowPath && shadowPath.length > 0 &&\n el.parentNode && el.parentNode.nodeType === DOCUMENT_FRAGMENT_NODE;\n\n return {\n // Semantic signals\n hasAlertRole: ['alert', 'status', 'log', 'alertdialog'].includes(role),\n hasAriaLive: ariaLive === 'polite' || ariaLive === 'assertive',\n isDialog: role === 'dialog' || tagName === 'dialog' || ariaModal === 'true',\n\n // Visual signals\n isFixedOrSticky: style && (style.position === 'fixed' || style.position === 'sticky'),\n // Note: parseInt returns NaN for non-numeric values like \"auto\", which correctly fails the > 1000 check\n hasHighZIndex: style && parseInt(style.zIndex, 10) > 1000,\n coversSignificantViewport: rect && ((rect.width > vw * 0.5) || (rect.height > vh * 0.3)),\n\n // Structural signals - consider top-level shadow DOM elements as equivalent to body children\n isBodyDirectChild: el.parentElement === document.body || isTopLevelInShadow,\n containsInteractiveElements: el.querySelector('button, a, input, select, textarea') !== null,\n\n // Universal signals (work without ARIA)\n isVisibleInViewport: !!isVisibleInViewport,\n hasNonTrivialText: hasNonTrivialText,\n\n // Temporal signals (set by accumulator later)\n appearedAfterDelay: false,\n wasShortLived: false,\n };\n }\n\n /**\n * Calculate significance score from signals using weighted sum.\n * @param signals - The computed significance signals for an element\n * @returns The total significance score\n */\n function computeSignificance(signals) {\n let score = 0;\n for (const [key, weight] of Object.entries(WEIGHTS)) {\n if (signals[key]) score += weight;\n }\n return score;\n }\n\n /**\n * Capture a mutation entry from an element.\n * @param node - The DOM node\n * @param type - 'added' or 'removed'\n * @param shadowPath - Optional array of shadow host identifiers\n */\n function captureEntry(node, type, shadowPath) {\n if (node.nodeType !== 1) return null; // Element nodes only\n\n const el = node;\n const signals = computeSignals(el, shadowPath);\n const significance = computeSignificance(signals);\n\n // Only capture if meets threshold\n if (significance < SIGNIFICANCE_THRESHOLD) return null;\n\n // Capture content - excludes style/script content\n const text = getCleanTextContent(el, MAX_TEXT_LENGTH);\n const hasInteractives = signals.containsInteractiveElements;\n\n // Get viewport coverage for later analysis\n let viewportCoverage = { widthPct: 0, heightPct: 0 };\n try {\n const rect = el.getBoundingClientRect();\n viewportCoverage = {\n widthPct: Math.round((rect.width / window.innerWidth) * 100),\n heightPct: Math.round((rect.height / window.innerHeight) * 100),\n };\n } catch (e) {\n // Element may be detached\n }\n\n // Get z-index\n let zIndex = 0;\n try {\n zIndex = parseInt(getComputedStyle(el).zIndex, 10) || 0;\n } catch (e) {\n // Element may be detached\n }\n\n const entry = {\n type: type,\n timestamp: Date.now(),\n tag: el.tagName.toLowerCase(),\n id: el.id || undefined,\n\n // Semantic attributes\n role: el.getAttribute('role') || undefined,\n ariaLive: el.getAttribute('aria-live') || undefined,\n ariaLabel: el.getAttribute('aria-label') || undefined,\n ariaModal: el.getAttribute('aria-modal') || undefined,\n\n // Content\n text: text,\n hasInteractives: hasInteractives,\n\n // Visual signals\n isFixedOrSticky: signals.isFixedOrSticky,\n zIndex: zIndex,\n viewportCoverage: viewportCoverage,\n\n // Structural\n isBodyDirectChild: signals.isBodyDirectChild,\n\n // Universal signals\n isVisibleInViewport: signals.isVisibleInViewport,\n hasNonTrivialText: signals.hasNonTrivialText,\n\n // Shadow DOM context\n shadowPath: shadowPath && shadowPath.length > 0 ? shadowPath : undefined,\n\n // Significance\n significance: significance,\n };\n\n return entry;\n }\n\n const log = [];\n const pageLoadTime = Date.now();\n\n /**\n * Process added nodes - capture entries and check for shadow roots.\n * @param node - The added node\n * @param shadowPath - Current shadow path context\n */\n function processAddedNode(node, shadowPath) {\n // Skip if already processed (prevents duplicates from nested shadow DOM)\n if (node.nodeType === 1 && processedElements.has(node)) {\n return;\n }\n\n const entry = captureEntry(node, 'added', shadowPath);\n if (entry) {\n entry.appearedAfterDelay = (entry.timestamp - pageLoadTime) > 100;\n log.push(entry);\n // Mark as processed\n if (node.nodeType === 1) {\n processedElements.add(node);\n }\n }\n\n // Check significant children - both ARIA-attributed and visible text elements\n if (node.nodeType === 1) {\n // First: ARIA-attributed elements (high confidence)\n const ariaChildren = node.querySelectorAll(\n '[role=\"alert\"], [role=\"status\"], [role=\"dialog\"], [role=\"alertdialog\"], [aria-live], [aria-modal], dialog'\n );\n for (const child of ariaChildren) {\n // Skip if already processed\n if (processedElements.has(child)) continue;\n\n const childEntry = captureEntry(child, 'added', shadowPath);\n if (childEntry) {\n childEntry.appearedAfterDelay = (childEntry.timestamp - pageLoadTime) > 100;\n log.push(childEntry);\n processedElements.add(child);\n }\n }\n\n // Second: Any visible element with text (broader capture for sites without ARIA)\n const textChildren = node.querySelectorAll('span, div, p, small, strong, em, label, li');\n for (const child of textChildren) {\n // Skip if already processed\n if (processedElements.has(child)) continue;\n\n // Skip if already captured via ARIA query\n if (child.hasAttribute('role') || child.hasAttribute('aria-live')) continue;\n\n // Only capture leaf-ish elements (minimal nested structure)\n const hasDeepNesting = child.querySelector('div, p, ul, ol, table');\n if (hasDeepNesting) continue;\n\n const childEntry = captureEntry(child, 'added', shadowPath);\n if (childEntry) {\n childEntry.appearedAfterDelay = (childEntry.timestamp - pageLoadTime) > 100;\n log.push(childEntry);\n processedElements.add(child);\n }\n }\n\n // Check for shadow roots in this element and its descendants\n checkAndObserveShadowRoots(node, shadowPath || []);\n }\n }\n\n /**\n * Process removed nodes - capture entries and cleanup shadow observers.\n * @param node - The removed node\n * @param shadowPath - Current shadow path context\n */\n function processRemovedNode(node, shadowPath) {\n const entry = captureEntry(node, 'removed', shadowPath);\n if (entry) {\n log.push(entry);\n }\n\n // Cleanup shadow observers for removed elements\n if (node.nodeType === 1) {\n cleanupShadowObservers(node);\n }\n }\n\n /**\n * Create a mutation callback for observing a specific context (main DOM or shadow root).\n * @param shadowPath - The shadow path context for this observer\n */\n function createMutationCallback(shadowPath) {\n return function(mutations) {\n for (const m of mutations) {\n // Capture added nodes\n for (const node of m.addedNodes) {\n processAddedNode(node, shadowPath);\n }\n\n // Capture removed nodes\n for (const node of m.removedNodes) {\n processRemovedNode(node, shadowPath);\n }\n }\n\n // Trim if over limit (FIFO)\n if (log.length > MAX_ENTRIES) {\n const excess = log.length - MAX_ENTRIES;\n log.splice(0, excess);\n }\n };\n }\n\n /**\n * Observe a shadow root for mutations.\n * @param shadowRoot - The shadow root to observe\n * @param shadowPath - The path of shadow host identifiers leading to this shadow root\n */\n function observeShadowRoot(shadowRoot, shadowPath) {\n // Already observing this shadow root\n if (shadowObservers.has(shadowRoot)) return;\n\n // Limit number of shadow observers for performance\n if (shadowObservers.size >= MAX_SHADOW_OBSERVERS) {\n console.warn('[ObservationAccumulator] Max shadow observers reached, skipping:', shadowPath);\n return;\n }\n\n const observer = new MutationObserver(createMutationCallback(shadowPath));\n observer.observe(shadowRoot, {\n childList: true,\n subtree: true,\n });\n\n shadowObservers.set(shadowRoot, { observer, hostPath: shadowPath });\n }\n\n /**\n * Recursively check element and descendants for open shadow roots.\n * @param element - The element to check\n * @param currentShadowPath - The current shadow path context\n * @param visited - Set of already-visited elements to prevent infinite recursion\n */\n function checkAndObserveShadowRoots(element, currentShadowPath, visited) {\n if (!element || element.nodeType !== 1) return;\n\n // Initialize visited set on first call\n if (!visited) {\n visited = new Set();\n }\n\n // Prevent infinite recursion from circular references\n if (visited.has(element)) return;\n visited.add(element);\n\n // Check if this element has an open shadow root\n if (element.shadowRoot) {\n const newPath = [...currentShadowPath, getElementIdentifier(element)];\n observeShadowRoot(element.shadowRoot, newPath);\n\n // Check shadow root's children for nested shadow roots\n const shadowChildren = element.shadowRoot.querySelectorAll('*');\n for (const child of shadowChildren) {\n if (child.shadowRoot) {\n checkAndObserveShadowRoots(child, newPath, visited);\n }\n }\n }\n\n // Check light DOM children for shadow roots\n const children = element.querySelectorAll('*');\n for (const child of children) {\n if (child.shadowRoot) {\n checkAndObserveShadowRoots(child, currentShadowPath, visited);\n }\n }\n }\n\n /**\n * Cleanup shadow observers for a removed element and its descendants.\n * @param element - The element being removed\n */\n function cleanupShadowObservers(element) {\n if (!element || element.nodeType !== 1) return;\n\n // If element is a shadow host, cleanup its observer\n if (element.shadowRoot && shadowObservers.has(element.shadowRoot)) {\n const { observer } = shadowObservers.get(element.shadowRoot);\n observer.disconnect();\n shadowObservers.delete(element.shadowRoot);\n }\n\n // Recursively cleanup descendant shadow hosts\n try {\n const descendants = element.querySelectorAll('*');\n for (const child of descendants) {\n if (child.shadowRoot && shadowObservers.has(child.shadowRoot)) {\n const { observer } = shadowObservers.get(child.shadowRoot);\n observer.disconnect();\n shadowObservers.delete(child.shadowRoot);\n }\n }\n } catch (e) {\n // Element may be detached, ignore errors\n }\n }\n\n // Create main observer for document.body\n const observer = new MutationObserver(createMutationCallback(null));\n\n // Start observing\n if (document.body) {\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n // Initial scan for existing shadow roots in the DOM\n checkAndObserveShadowRoots(document.body, []);\n }\n\n window.__observationAccumulator = {\n log: log,\n observer: observer,\n shadowObservers: shadowObservers, // Expose for debugging/testing\n observedBody: document.body, // Track which body we're observing for staleness detection\n pageLoadTime: pageLoadTime,\n lastReportedIndex: 0, // Track what's been reported\n\n // Get all entries since timestamp\n getSince: function(timestamp) {\n return this.log.filter(e => e.timestamp >= timestamp);\n },\n\n // Get significant entries since timestamp\n getSignificant: function(timestamp, threshold) {\n threshold = threshold || SIGNIFICANCE_THRESHOLD;\n return this.log.filter(e => e.timestamp >= timestamp && e.significance >= threshold);\n },\n\n // Get unreported entries (for accumulation between tool calls)\n getUnreported: function() {\n const unreported = this.log.slice(this.lastReportedIndex);\n return unreported.filter(e => e.significance >= SIGNIFICANCE_THRESHOLD);\n },\n\n // Mark entries as reported\n markReported: function() {\n this.lastReportedIndex = this.log.length;\n },\n\n // Reset on navigation\n reset: function() {\n this.log.length = 0;\n this.lastReportedIndex = 0;\n this.pageLoadTime = Date.now();\n // Cleanup all shadow observers\n for (const [shadowRoot, { observer }] of this.shadowObservers) {\n observer.disconnect();\n }\n this.shadowObservers.clear();\n // Clear processed elements tracking (create fresh WeakSet)\n processedElements = new WeakSet();\n },\n\n // Re-scan for shadow roots (useful after dynamic content load)\n rescanShadowRoots: function() {\n if (document.body) {\n checkAndObserveShadowRoots(document.body, []);\n }\n },\n\n // Get shadow observer count (for debugging)\n getShadowObserverCount: function() {\n return this.shadowObservers.size;\n },\n };\n})();\n";
19
+ //# sourceMappingURL=observer-script.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer-script.d.ts","sourceRoot":"","sources":["../../../src/observation/observer-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,eAAO,MAAM,2BAA2B,s4kBAsiBvC,CAAC"}