@reticlehq/server 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (483) hide show
  1. package/LICENSE +105 -0
  2. package/README.md +17 -0
  3. package/dist/bridge-security.d.ts +23 -0
  4. package/dist/bridge-security.d.ts.map +1 -0
  5. package/dist/bridge-security.js +44 -0
  6. package/dist/bridge-security.js.map +1 -0
  7. package/dist/bridge.d.ts +42 -0
  8. package/dist/bridge.d.ts.map +1 -0
  9. package/dist/bridge.js +281 -0
  10. package/dist/bridge.js.map +1 -0
  11. package/dist/bridge.test-harness.d.ts +42 -0
  12. package/dist/bridge.test-harness.d.ts.map +1 -0
  13. package/dist/bridge.test-harness.js +192 -0
  14. package/dist/bridge.test-harness.js.map +1 -0
  15. package/dist/cli-launch.d.ts +53 -0
  16. package/dist/cli-launch.d.ts.map +1 -0
  17. package/dist/cli-launch.js +109 -0
  18. package/dist/cli-launch.js.map +1 -0
  19. package/dist/cli-parse.d.ts +74 -0
  20. package/dist/cli-parse.d.ts.map +1 -0
  21. package/dist/cli-parse.js +321 -0
  22. package/dist/cli-parse.js.map +1 -0
  23. package/dist/cli-port.d.ts +26 -0
  24. package/dist/cli-port.d.ts.map +1 -0
  25. package/dist/cli-port.js +57 -0
  26. package/dist/cli-port.js.map +1 -0
  27. package/dist/cli-verify.d.ts +46 -0
  28. package/dist/cli-verify.d.ts.map +1 -0
  29. package/dist/cli-verify.js +181 -0
  30. package/dist/cli-verify.js.map +1 -0
  31. package/dist/cli.d.ts +6 -0
  32. package/dist/cli.d.ts.map +1 -0
  33. package/dist/cli.js +337 -0
  34. package/dist/cli.js.map +1 -0
  35. package/dist/cloud/cloud-sync.d.ts +50 -0
  36. package/dist/cloud/cloud-sync.d.ts.map +1 -0
  37. package/dist/cloud/cloud-sync.js +47 -0
  38. package/dist/cloud/cloud-sync.js.map +1 -0
  39. package/dist/crawl/crawl-tools.d.ts +8 -0
  40. package/dist/crawl/crawl-tools.d.ts.map +1 -0
  41. package/dist/crawl/crawl-tools.js +61 -0
  42. package/dist/crawl/crawl-tools.js.map +1 -0
  43. package/dist/crawl/crawl.d.ts +45 -0
  44. package/dist/crawl/crawl.d.ts.map +1 -0
  45. package/dist/crawl/crawl.js +106 -0
  46. package/dist/crawl/crawl.js.map +1 -0
  47. package/dist/daemon-resilience.d.ts +17 -0
  48. package/dist/daemon-resilience.d.ts.map +1 -0
  49. package/dist/daemon-resilience.js +23 -0
  50. package/dist/daemon-resilience.js.map +1 -0
  51. package/dist/daemon.d.ts +26 -0
  52. package/dist/daemon.d.ts.map +1 -0
  53. package/dist/daemon.js +122 -0
  54. package/dist/daemon.js.map +1 -0
  55. package/dist/domain/domain-model.d.ts +64 -0
  56. package/dist/domain/domain-model.d.ts.map +1 -0
  57. package/dist/domain/domain-model.js +127 -0
  58. package/dist/domain/domain-model.js.map +1 -0
  59. package/dist/domain/domain-tools.d.ts +9 -0
  60. package/dist/domain/domain-tools.d.ts.map +1 -0
  61. package/dist/domain/domain-tools.js +66 -0
  62. package/dist/domain/domain-tools.js.map +1 -0
  63. package/dist/domain/flow-risk.d.ts +34 -0
  64. package/dist/domain/flow-risk.d.ts.map +1 -0
  65. package/dist/domain/flow-risk.js +81 -0
  66. package/dist/domain/flow-risk.js.map +1 -0
  67. package/dist/ee/audit-log.d.ts +15 -0
  68. package/dist/ee/audit-log.d.ts.map +1 -0
  69. package/dist/ee/audit-log.js +12 -0
  70. package/dist/ee/audit-log.js.map +1 -0
  71. package/dist/events/event-filters.d.ts +65 -0
  72. package/dist/events/event-filters.d.ts.map +1 -0
  73. package/dist/events/event-filters.js +98 -0
  74. package/dist/events/event-filters.js.map +1 -0
  75. package/dist/events/predicate-eval.d.ts +91 -0
  76. package/dist/events/predicate-eval.d.ts.map +1 -0
  77. package/dist/events/predicate-eval.js +299 -0
  78. package/dist/events/predicate-eval.js.map +1 -0
  79. package/dist/events/predicate.d.ts +19 -0
  80. package/dist/events/predicate.d.ts.map +1 -0
  81. package/dist/events/predicate.js +188 -0
  82. package/dist/events/predicate.js.map +1 -0
  83. package/dist/events/reaction.d.ts +34 -0
  84. package/dist/events/reaction.d.ts.map +1 -0
  85. package/dist/events/reaction.js +60 -0
  86. package/dist/events/reaction.js.map +1 -0
  87. package/dist/events/ring-buffer.d.ts +32 -0
  88. package/dist/events/ring-buffer.d.ts.map +1 -0
  89. package/dist/events/ring-buffer.js +75 -0
  90. package/dist/events/ring-buffer.js.map +1 -0
  91. package/dist/flows/annotate-tools.d.ts +16 -0
  92. package/dist/flows/annotate-tools.d.ts.map +1 -0
  93. package/dist/flows/annotate-tools.js +136 -0
  94. package/dist/flows/annotate-tools.js.map +1 -0
  95. package/dist/flows/annotate.d.ts +22 -0
  96. package/dist/flows/annotate.d.ts.map +1 -0
  97. package/dist/flows/annotate.js +134 -0
  98. package/dist/flows/annotate.js.map +1 -0
  99. package/dist/flows/annotation-store.d.ts +23 -0
  100. package/dist/flows/annotation-store.d.ts.map +1 -0
  101. package/dist/flows/annotation-store.js +51 -0
  102. package/dist/flows/annotation-store.js.map +1 -0
  103. package/dist/flows/decision.d.ts +13 -0
  104. package/dist/flows/decision.d.ts.map +1 -0
  105. package/dist/flows/decision.js +111 -0
  106. package/dist/flows/decision.js.map +1 -0
  107. package/dist/flows/flow-classify.d.ts +52 -0
  108. package/dist/flows/flow-classify.d.ts.map +1 -0
  109. package/dist/flows/flow-classify.js +99 -0
  110. package/dist/flows/flow-classify.js.map +1 -0
  111. package/dist/flows/flow-replay-run.d.ts +15 -0
  112. package/dist/flows/flow-replay-run.d.ts.map +1 -0
  113. package/dist/flows/flow-replay-run.js +120 -0
  114. package/dist/flows/flow-replay-run.js.map +1 -0
  115. package/dist/flows/flow-replay.d.ts +49 -0
  116. package/dist/flows/flow-replay.d.ts.map +1 -0
  117. package/dist/flows/flow-replay.js +391 -0
  118. package/dist/flows/flow-replay.js.map +1 -0
  119. package/dist/flows/flow-report.d.ts +23 -0
  120. package/dist/flows/flow-report.d.ts.map +1 -0
  121. package/dist/flows/flow-report.js +106 -0
  122. package/dist/flows/flow-report.js.map +1 -0
  123. package/dist/flows/flow-scope.d.ts +25 -0
  124. package/dist/flows/flow-scope.d.ts.map +1 -0
  125. package/dist/flows/flow-scope.js +32 -0
  126. package/dist/flows/flow-scope.js.map +1 -0
  127. package/dist/flows/flow-success.d.ts +33 -0
  128. package/dist/flows/flow-success.d.ts.map +1 -0
  129. package/dist/flows/flow-success.js +131 -0
  130. package/dist/flows/flow-success.js.map +1 -0
  131. package/dist/flows/flow-tools.d.ts +4 -0
  132. package/dist/flows/flow-tools.d.ts.map +1 -0
  133. package/dist/flows/flow-tools.js +460 -0
  134. package/dist/flows/flow-tools.js.map +1 -0
  135. package/dist/flows/flows.d.ts +86 -0
  136. package/dist/flows/flows.d.ts.map +1 -0
  137. package/dist/flows/flows.js +319 -0
  138. package/dist/flows/flows.js.map +1 -0
  139. package/dist/flows/heal.d.ts +43 -0
  140. package/dist/flows/heal.d.ts.map +1 -0
  141. package/dist/flows/heal.js +98 -0
  142. package/dist/flows/heal.js.map +1 -0
  143. package/dist/flows/recordings.d.ts +46 -0
  144. package/dist/flows/recordings.d.ts.map +1 -0
  145. package/dist/flows/recordings.js +43 -0
  146. package/dist/flows/recordings.js.map +1 -0
  147. package/dist/flows/replay.d.ts +23 -0
  148. package/dist/flows/replay.d.ts.map +1 -0
  149. package/dist/flows/replay.js +160 -0
  150. package/dist/flows/replay.js.map +1 -0
  151. package/dist/http-server.d.ts +39 -0
  152. package/dist/http-server.d.ts.map +1 -0
  153. package/dist/http-server.js +145 -0
  154. package/dist/http-server.js.map +1 -0
  155. package/dist/idle-shutdown.d.ts +34 -0
  156. package/dist/idle-shutdown.d.ts.map +1 -0
  157. package/dist/idle-shutdown.js +68 -0
  158. package/dist/idle-shutdown.js.map +1 -0
  159. package/dist/index.d.ts +135 -0
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +371 -0
  162. package/dist/index.js.map +1 -0
  163. package/dist/init/cursor.d.ts +25 -0
  164. package/dist/init/cursor.d.ts.map +1 -0
  165. package/dist/init/cursor.js +49 -0
  166. package/dist/init/cursor.js.map +1 -0
  167. package/dist/init/detect.d.ts +49 -0
  168. package/dist/init/detect.d.ts.map +1 -0
  169. package/dist/init/detect.js +84 -0
  170. package/dist/init/detect.js.map +1 -0
  171. package/dist/init/mcp.d.ts +40 -0
  172. package/dist/init/mcp.d.ts.map +1 -0
  173. package/dist/init/mcp.js +55 -0
  174. package/dist/init/mcp.js.map +1 -0
  175. package/dist/init/node-io.d.ts +8 -0
  176. package/dist/init/node-io.d.ts.map +1 -0
  177. package/dist/init/node-io.js +57 -0
  178. package/dist/init/node-io.js.map +1 -0
  179. package/dist/init/plan.d.ts +72 -0
  180. package/dist/init/plan.d.ts.map +1 -0
  181. package/dist/init/plan.js +280 -0
  182. package/dist/init/plan.js.map +1 -0
  183. package/dist/init/project-id.d.ts +17 -0
  184. package/dist/init/project-id.d.ts.map +1 -0
  185. package/dist/init/project-id.js +38 -0
  186. package/dist/init/project-id.js.map +1 -0
  187. package/dist/init/run.d.ts +42 -0
  188. package/dist/init/run.d.ts.map +1 -0
  189. package/dist/init/run.js +171 -0
  190. package/dist/init/run.js.map +1 -0
  191. package/dist/init/snippets.d.ts +33 -0
  192. package/dist/init/snippets.d.ts.map +1 -0
  193. package/dist/init/snippets.js +117 -0
  194. package/dist/init/snippets.js.map +1 -0
  195. package/dist/init/vite-config.d.ts +25 -0
  196. package/dist/init/vite-config.d.ts.map +1 -0
  197. package/dist/init/vite-config.js +45 -0
  198. package/dist/init/vite-config.js.map +1 -0
  199. package/dist/input/network-mock-tools.d.ts +3 -0
  200. package/dist/input/network-mock-tools.d.ts.map +1 -0
  201. package/dist/input/network-mock-tools.js +94 -0
  202. package/dist/input/network-mock-tools.js.map +1 -0
  203. package/dist/input/network-mock.d.ts +55 -0
  204. package/dist/input/network-mock.d.ts.map +1 -0
  205. package/dist/input/network-mock.js +62 -0
  206. package/dist/input/network-mock.js.map +1 -0
  207. package/dist/input/real-input.d.ts +174 -0
  208. package/dist/input/real-input.d.ts.map +1 -0
  209. package/dist/input/real-input.js +289 -0
  210. package/dist/input/real-input.js.map +1 -0
  211. package/dist/input/scroll-find.d.ts +41 -0
  212. package/dist/input/scroll-find.d.ts.map +1 -0
  213. package/dist/input/scroll-find.js +59 -0
  214. package/dist/input/scroll-find.js.map +1 -0
  215. package/dist/input/scroll-tools.d.ts +8 -0
  216. package/dist/input/scroll-tools.d.ts.map +1 -0
  217. package/dist/input/scroll-tools.js +68 -0
  218. package/dist/input/scroll-tools.js.map +1 -0
  219. package/dist/input/viewport-tools.d.ts +3 -0
  220. package/dist/input/viewport-tools.d.ts.map +1 -0
  221. package/dist/input/viewport-tools.js +65 -0
  222. package/dist/input/viewport-tools.js.map +1 -0
  223. package/dist/license/license.d.ts +108 -0
  224. package/dist/license/license.d.ts.map +1 -0
  225. package/dist/license/license.js +203 -0
  226. package/dist/license/license.js.map +1 -0
  227. package/dist/log.d.ts +6 -0
  228. package/dist/log.d.ts.map +1 -0
  229. package/dist/log.js +9 -0
  230. package/dist/log.js.map +1 -0
  231. package/dist/mcp-proxy.d.ts +16 -0
  232. package/dist/mcp-proxy.d.ts.map +1 -0
  233. package/dist/mcp-proxy.js +168 -0
  234. package/dist/mcp-proxy.js.map +1 -0
  235. package/dist/mcp.d.ts +14 -0
  236. package/dist/mcp.d.ts.map +1 -0
  237. package/dist/mcp.js +101 -0
  238. package/dist/mcp.js.map +1 -0
  239. package/dist/pairing-token.d.ts +28 -0
  240. package/dist/pairing-token.d.ts.map +1 -0
  241. package/dist/pairing-token.js +62 -0
  242. package/dist/pairing-token.js.map +1 -0
  243. package/dist/pool/browser-pool.d.ts +90 -0
  244. package/dist/pool/browser-pool.d.ts.map +1 -0
  245. package/dist/pool/browser-pool.js +221 -0
  246. package/dist/pool/browser-pool.js.map +1 -0
  247. package/dist/pool/lease-reaper.d.ts +16 -0
  248. package/dist/pool/lease-reaper.d.ts.map +1 -0
  249. package/dist/pool/lease-reaper.js +41 -0
  250. package/dist/pool/lease-reaper.js.map +1 -0
  251. package/dist/pool/playwright-launcher.d.ts +19 -0
  252. package/dist/pool/playwright-launcher.d.ts.map +1 -0
  253. package/dist/pool/playwright-launcher.js +51 -0
  254. package/dist/pool/playwright-launcher.js.map +1 -0
  255. package/dist/project/baselines.d.ts +22 -0
  256. package/dist/project/baselines.d.ts.map +1 -0
  257. package/dist/project/baselines.js +45 -0
  258. package/dist/project/baselines.js.map +1 -0
  259. package/dist/project/fs-port.d.ts +27 -0
  260. package/dist/project/fs-port.d.ts.map +1 -0
  261. package/dist/project/fs-port.js +32 -0
  262. package/dist/project/fs-port.js.map +1 -0
  263. package/dist/project/project-store.d.ts +32 -0
  264. package/dist/project/project-store.d.ts.map +1 -0
  265. package/dist/project/project-store.js +127 -0
  266. package/dist/project/project-store.js.map +1 -0
  267. package/dist/project/project-tools.d.ts +9 -0
  268. package/dist/project/project-tools.d.ts.map +1 -0
  269. package/dist/project/project-tools.js +118 -0
  270. package/dist/project/project-tools.js.map +1 -0
  271. package/dist/project/reticle-dir.d.ts +61 -0
  272. package/dist/project/reticle-dir.d.ts.map +1 -0
  273. package/dist/project/reticle-dir.js +144 -0
  274. package/dist/project/reticle-dir.js.map +1 -0
  275. package/dist/runs/build-verification-run.d.ts +30 -0
  276. package/dist/runs/build-verification-run.d.ts.map +1 -0
  277. package/dist/runs/build-verification-run.js +71 -0
  278. package/dist/runs/build-verification-run.js.map +1 -0
  279. package/dist/runs/profile-redact.d.ts +16 -0
  280. package/dist/runs/profile-redact.d.ts.map +1 -0
  281. package/dist/runs/profile-redact.js +32 -0
  282. package/dist/runs/profile-redact.js.map +1 -0
  283. package/dist/runs/render-report.d.ts +9 -0
  284. package/dist/runs/render-report.d.ts.map +1 -0
  285. package/dist/runs/render-report.js +70 -0
  286. package/dist/runs/render-report.js.map +1 -0
  287. package/dist/runs/repair-prompt.d.ts +15 -0
  288. package/dist/runs/repair-prompt.d.ts.map +1 -0
  289. package/dist/runs/repair-prompt.js +59 -0
  290. package/dist/runs/repair-prompt.js.map +1 -0
  291. package/dist/runs/replay-mapping.d.ts +12 -0
  292. package/dist/runs/replay-mapping.d.ts.map +1 -0
  293. package/dist/runs/replay-mapping.js +35 -0
  294. package/dist/runs/replay-mapping.js.map +1 -0
  295. package/dist/runs/reticle-runner.d.ts +48 -0
  296. package/dist/runs/reticle-runner.d.ts.map +1 -0
  297. package/dist/runs/reticle-runner.js +56 -0
  298. package/dist/runs/reticle-runner.js.map +1 -0
  299. package/dist/runs/risk-classify.d.ts +27 -0
  300. package/dist/runs/risk-classify.d.ts.map +1 -0
  301. package/dist/runs/risk-classify.js +76 -0
  302. package/dist/runs/risk-classify.js.map +1 -0
  303. package/dist/runs/run-store.d.ts +40 -0
  304. package/dist/runs/run-store.d.ts.map +1 -0
  305. package/dist/runs/run-store.js +118 -0
  306. package/dist/runs/run-store.js.map +1 -0
  307. package/dist/runs/run-tools.d.ts +10 -0
  308. package/dist/runs/run-tools.d.ts.map +1 -0
  309. package/dist/runs/run-tools.js +69 -0
  310. package/dist/runs/run-tools.js.map +1 -0
  311. package/dist/runs/runner-port.d.ts +14 -0
  312. package/dist/runs/runner-port.d.ts.map +1 -0
  313. package/dist/runs/runner-port.js +23 -0
  314. package/dist/runs/runner-port.js.map +1 -0
  315. package/dist/runs/verify-http.d.ts +34 -0
  316. package/dist/runs/verify-http.d.ts.map +1 -0
  317. package/dist/runs/verify-http.js +102 -0
  318. package/dist/runs/verify-http.js.map +1 -0
  319. package/dist/runs/verify-server.d.ts +26 -0
  320. package/dist/runs/verify-server.d.ts.map +1 -0
  321. package/dist/runs/verify-server.js +99 -0
  322. package/dist/runs/verify-server.js.map +1 -0
  323. package/dist/server-version.d.ts +3 -0
  324. package/dist/server-version.d.ts.map +1 -0
  325. package/dist/server-version.js +5 -0
  326. package/dist/server-version.js.map +1 -0
  327. package/dist/session/control-envelope.d.ts +49 -0
  328. package/dist/session/control-envelope.d.ts.map +1 -0
  329. package/dist/session/control-envelope.js +44 -0
  330. package/dist/session/control-envelope.js.map +1 -0
  331. package/dist/session/live-control-tools.d.ts +16 -0
  332. package/dist/session/live-control-tools.d.ts.map +1 -0
  333. package/dist/session/live-control-tools.js +204 -0
  334. package/dist/session/live-control-tools.js.map +1 -0
  335. package/dist/session/output-budget.d.ts +41 -0
  336. package/dist/session/output-budget.d.ts.map +1 -0
  337. package/dist/session/output-budget.js +54 -0
  338. package/dist/session/output-budget.js.map +1 -0
  339. package/dist/session/presenter-args.d.ts +8 -0
  340. package/dist/session/presenter-args.d.ts.map +1 -0
  341. package/dist/session/presenter-args.js +15 -0
  342. package/dist/session/presenter-args.js.map +1 -0
  343. package/dist/session/review-store.d.ts +40 -0
  344. package/dist/session/review-store.d.ts.map +1 -0
  345. package/dist/session/review-store.js +61 -0
  346. package/dist/session/review-store.js.map +1 -0
  347. package/dist/session/session-health.d.ts +22 -0
  348. package/dist/session/session-health.d.ts.map +1 -0
  349. package/dist/session/session-health.js +26 -0
  350. package/dist/session/session-health.js.map +1 -0
  351. package/dist/session/session-manager.d.ts +43 -0
  352. package/dist/session/session-manager.d.ts.map +1 -0
  353. package/dist/session/session-manager.js +155 -0
  354. package/dist/session/session-manager.js.map +1 -0
  355. package/dist/session/session-readiness.d.ts +35 -0
  356. package/dist/session/session-readiness.d.ts.map +1 -0
  357. package/dist/session/session-readiness.js +32 -0
  358. package/dist/session/session-readiness.js.map +1 -0
  359. package/dist/session/session-reaper.d.ts +37 -0
  360. package/dist/session/session-reaper.d.ts.map +1 -0
  361. package/dist/session/session-reaper.js +94 -0
  362. package/dist/session/session-reaper.js.map +1 -0
  363. package/dist/session/session-recommendation.d.ts +18 -0
  364. package/dist/session/session-recommendation.d.ts.map +1 -0
  365. package/dist/session/session-recommendation.js +14 -0
  366. package/dist/session/session-recommendation.js.map +1 -0
  367. package/dist/session/session-tools.d.ts +9 -0
  368. package/dist/session/session-tools.d.ts.map +1 -0
  369. package/dist/session/session-tools.js +43 -0
  370. package/dist/session/session-tools.js.map +1 -0
  371. package/dist/session/session.d.ts +166 -0
  372. package/dist/session/session.d.ts.map +1 -0
  373. package/dist/session/session.js +408 -0
  374. package/dist/session/session.js.map +1 -0
  375. package/dist/session/state-select.d.ts +8 -0
  376. package/dist/session/state-select.d.ts.map +1 -0
  377. package/dist/session/state-select.js +8 -0
  378. package/dist/session/state-select.js.map +1 -0
  379. package/dist/token-auth.d.ts +24 -0
  380. package/dist/token-auth.d.ts.map +1 -0
  381. package/dist/token-auth.js +71 -0
  382. package/dist/token-auth.js.map +1 -0
  383. package/dist/tools/act-tools.d.ts +3 -0
  384. package/dist/tools/act-tools.d.ts.map +1 -0
  385. package/dist/tools/act-tools.js +327 -0
  386. package/dist/tools/act-tools.js.map +1 -0
  387. package/dist/tools/act-view.d.ts +19 -0
  388. package/dist/tools/act-view.d.ts.map +1 -0
  389. package/dist/tools/act-view.js +46 -0
  390. package/dist/tools/act-view.js.map +1 -0
  391. package/dist/tools/assert-grade.d.ts +21 -0
  392. package/dist/tools/assert-grade.d.ts.map +1 -0
  393. package/dist/tools/assert-grade.js +52 -0
  394. package/dist/tools/assert-grade.js.map +1 -0
  395. package/dist/tools/browser-tools.d.ts +3 -0
  396. package/dist/tools/browser-tools.d.ts.map +1 -0
  397. package/dist/tools/browser-tools.js +52 -0
  398. package/dist/tools/browser-tools.js.map +1 -0
  399. package/dist/tools/contract-tools.d.ts +8 -0
  400. package/dist/tools/contract-tools.d.ts.map +1 -0
  401. package/dist/tools/contract-tools.js +62 -0
  402. package/dist/tools/contract-tools.js.map +1 -0
  403. package/dist/tools/dynamic-tools.d.ts +7 -0
  404. package/dist/tools/dynamic-tools.d.ts.map +1 -0
  405. package/dist/tools/dynamic-tools.js +103 -0
  406. package/dist/tools/dynamic-tools.js.map +1 -0
  407. package/dist/tools/error-recovery.d.ts +31 -0
  408. package/dist/tools/error-recovery.d.ts.map +1 -0
  409. package/dist/tools/error-recovery.js +52 -0
  410. package/dist/tools/error-recovery.js.map +1 -0
  411. package/dist/tools/invoke-tool.d.ts +23 -0
  412. package/dist/tools/invoke-tool.d.ts.map +1 -0
  413. package/dist/tools/invoke-tool.js +99 -0
  414. package/dist/tools/invoke-tool.js.map +1 -0
  415. package/dist/tools/lease-tools.d.ts +31 -0
  416. package/dist/tools/lease-tools.d.ts.map +1 -0
  417. package/dist/tools/lease-tools.js +164 -0
  418. package/dist/tools/lease-tools.js.map +1 -0
  419. package/dist/tools/observe-tools.d.ts +3 -0
  420. package/dist/tools/observe-tools.d.ts.map +1 -0
  421. package/dist/tools/observe-tools.js +259 -0
  422. package/dist/tools/observe-tools.js.map +1 -0
  423. package/dist/tools/profiles.d.ts +33 -0
  424. package/dist/tools/profiles.d.ts.map +1 -0
  425. package/dist/tools/profiles.js +105 -0
  426. package/dist/tools/profiles.js.map +1 -0
  427. package/dist/tools/query-paginate.d.ts +15 -0
  428. package/dist/tools/query-paginate.d.ts.map +1 -0
  429. package/dist/tools/query-paginate.js +31 -0
  430. package/dist/tools/query-paginate.js.map +1 -0
  431. package/dist/tools/read-tools.d.ts +3 -0
  432. package/dist/tools/read-tools.d.ts.map +1 -0
  433. package/dist/tools/read-tools.js +329 -0
  434. package/dist/tools/read-tools.js.map +1 -0
  435. package/dist/tools/snapshot-delta.d.ts +59 -0
  436. package/dist/tools/snapshot-delta.d.ts.map +1 -0
  437. package/dist/tools/snapshot-delta.js +0 -0
  438. package/dist/tools/snapshot-delta.js.map +1 -0
  439. package/dist/tools/tool-invoker.d.ts +15 -0
  440. package/dist/tools/tool-invoker.d.ts.map +1 -0
  441. package/dist/tools/tool-invoker.js +20 -0
  442. package/dist/tools/tool-invoker.js.map +1 -0
  443. package/dist/tools/tool-kit.d.ts +60 -0
  444. package/dist/tools/tool-kit.d.ts.map +1 -0
  445. package/dist/tools/tool-kit.js +33 -0
  446. package/dist/tools/tool-kit.js.map +1 -0
  447. package/dist/tools/tool-names.d.ts +89 -0
  448. package/dist/tools/tool-names.d.ts.map +1 -0
  449. package/dist/tools/tool-names.js +88 -0
  450. package/dist/tools/tool-names.js.map +1 -0
  451. package/dist/tools/tools-helpers.d.ts +12 -0
  452. package/dist/tools/tools-helpers.d.ts.map +1 -0
  453. package/dist/tools/tools-helpers.js +22 -0
  454. package/dist/tools/tools-helpers.js.map +1 -0
  455. package/dist/tools/tools.d.ts +4 -0
  456. package/dist/tools/tools.d.ts.map +1 -0
  457. package/dist/tools/tools.js +268 -0
  458. package/dist/tools/tools.js.map +1 -0
  459. package/dist/update/update-checker.d.ts +20 -0
  460. package/dist/update/update-checker.d.ts.map +1 -0
  461. package/dist/update/update-checker.js +94 -0
  462. package/dist/update/update-checker.js.map +1 -0
  463. package/dist/update/update-tools.d.ts +3 -0
  464. package/dist/update/update-tools.d.ts.map +1 -0
  465. package/dist/update/update-tools.js +94 -0
  466. package/dist/update/update-tools.js.map +1 -0
  467. package/dist/update/updater.d.ts +31 -0
  468. package/dist/update/updater.d.ts.map +1 -0
  469. package/dist/update/updater.js +120 -0
  470. package/dist/update/updater.js.map +1 -0
  471. package/dist/visual/visual-diff.d.ts +46 -0
  472. package/dist/visual/visual-diff.d.ts.map +1 -0
  473. package/dist/visual/visual-diff.js +100 -0
  474. package/dist/visual/visual-diff.js.map +1 -0
  475. package/dist/visual/visual-store.d.ts +22 -0
  476. package/dist/visual/visual-store.d.ts.map +1 -0
  477. package/dist/visual/visual-store.js +60 -0
  478. package/dist/visual/visual-store.js.map +1 -0
  479. package/dist/visual/visual-tools.d.ts +9 -0
  480. package/dist/visual/visual-tools.d.ts.map +1 -0
  481. package/dist/visual/visual-tools.js +182 -0
  482. package/dist/visual/visual-tools.js.map +1 -0
  483. package/package.json +68 -0
@@ -0,0 +1,289 @@
1
+ import { ActionType, DriveErrorCode, DRIVE_PLAYWRIGHT_MISSING_MSG } from '@reticlehq/core';
2
+ import { installNetworkMocks } from './network-mock.js';
3
+ /** Structured, code-tagged failure so callers branch on cause, not message text. */
4
+ export class DriveError extends Error {
5
+ code;
6
+ constructor(code, message) {
7
+ super(message);
8
+ this.code = code;
9
+ this.name = 'DriveError';
10
+ }
11
+ }
12
+ /** Center of a viewport box in CSS px. Pure — unit-tested directly. */
13
+ export function boxCenter(box) {
14
+ return { cx: box.x + box.width / 2, cy: box.y + box.height / 2 };
15
+ }
16
+ /**
17
+ * Which actions are driven by native pointer input. fill/type stay synthetic unless a
18
+ * provider explicitly runs them.
19
+ */
20
+ export function isPointerAction(action) {
21
+ return (action === ActionType.HOVER ||
22
+ action === ActionType.CLICK ||
23
+ action === ActionType.DBLCLICK ||
24
+ action === ActionType.DRAG);
25
+ }
26
+ /** Settle delay after a native gesture so the reaction can begin to flush (named, not free). */
27
+ const REAL_INPUT_SETTLE_MS = 16;
28
+ /** Default number of interpolation steps for a native drag. */
29
+ const DEFAULT_DRAG_STEPS = 8;
30
+ /**
31
+ * Shared gesture executor: drive a native gesture on an already-resolved Page. Used by both the
32
+ * CDP-attached and the launched (drive) providers so the pointer logic lives in one place.
33
+ */
34
+ export async function performGesture(page, action, box, args, sleep) {
35
+ const center = boxCenter(box);
36
+ const { cx, cy } = center;
37
+ if (action === ActionType.HOVER) {
38
+ await page.mouse.move(cx, cy);
39
+ await page.mouse.move(cx + 1, cy);
40
+ await page.mouse.move(cx, cy);
41
+ await sleep(REAL_INPUT_SETTLE_MS);
42
+ return { performed: true, center };
43
+ }
44
+ if (action === ActionType.CLICK) {
45
+ await page.mouse.move(cx, cy);
46
+ await page.mouse.click(cx, cy);
47
+ return { performed: true, center };
48
+ }
49
+ if (action === ActionType.DBLCLICK) {
50
+ await page.mouse.move(cx, cy);
51
+ await page.mouse.dblclick(cx, cy);
52
+ return { performed: true, center };
53
+ }
54
+ if (action === ActionType.DRAG) {
55
+ if (args.toBox === undefined)
56
+ return { performed: false, center };
57
+ const dst = boxCenter(args.toBox);
58
+ const steps = args.steps ?? DEFAULT_DRAG_STEPS;
59
+ await page.mouse.move(cx, cy);
60
+ await page.mouse.down();
61
+ for (let i = 1; i <= steps; i += 1) {
62
+ const px = cx + ((dst.cx - cx) * i) / steps;
63
+ const py = cy + ((dst.cy - cy) * i) / steps;
64
+ await page.mouse.move(px, py, { steps: 1 });
65
+ }
66
+ await page.mouse.up();
67
+ return { performed: true, center };
68
+ }
69
+ if (action === ActionType.FILL || action === ActionType.TYPE) {
70
+ await page.mouse.click(cx, cy);
71
+ await page.keyboard.type(args.value ?? args.text ?? '');
72
+ return { performed: true, center };
73
+ }
74
+ return { performed: false, center };
75
+ }
76
+ /**
77
+ * Reticle paints its own dev overlay (presenter HUD + border glow) into the page. That chrome is
78
+ * time-varying — the activity log and border state change with every command — so capturing it
79
+ * makes a fresh screenshot of an unchanged page differ from its baseline. Hide it during capture
80
+ * (Playwright applies this stylesheet only for the shot, then reverts) so visual baselines reflect
81
+ * the app, not Reticle. Disabling animations settles any remaining transitions for determinism.
82
+ */
83
+ const HIDE_RETICLE_CHROME_CSS = '[data-reticle-overlay]{display:none !important}';
84
+ const SCREENSHOT_DETERMINISM = { style: HIDE_RETICLE_CHROME_CSS, animations: 'disabled' };
85
+ /**
86
+ * Capture a PNG from a Playwright page. Shared by the CDP + launched providers so the
87
+ * screenshot path lives in one place (mirrors performGesture). Returns the raw PNG bytes.
88
+ */
89
+ export async function capturePage(page, opts) {
90
+ const buf = await page.screenshot(opts.clip !== undefined
91
+ ? { ...SCREENSHOT_DETERMINISM, clip: opts.clip }
92
+ : opts.fullPage === true
93
+ ? { ...SCREENSHOT_DETERMINISM, fullPage: true }
94
+ : { ...SCREENSHOT_DETERMINISM });
95
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
96
+ }
97
+ const nodeSleep = (ms) => new Promise((resolve) => {
98
+ setTimeout(resolve, ms);
99
+ });
100
+ const cdpConnect = async (url) => {
101
+ const { chromium } = await import('playwright');
102
+ return chromium.connectOverCDP(url);
103
+ };
104
+ /** CDP-backed real-input provider. Lazily connects on first availability check / perform. */
105
+ export class CdpRealInputProvider {
106
+ #cdpUrl;
107
+ #sleep;
108
+ #connect;
109
+ #browser;
110
+ constructor(options) {
111
+ this.#cdpUrl = options.cdpUrl;
112
+ this.#sleep = options.sleep ?? nodeSleep;
113
+ this.#connect = options.connect ?? cdpConnect;
114
+ }
115
+ async #ensureBrowser() {
116
+ if (this.#browser !== undefined)
117
+ return this.#browser;
118
+ try {
119
+ this.#browser = await this.#connect(this.#cdpUrl);
120
+ return this.#browser;
121
+ }
122
+ catch {
123
+ return undefined;
124
+ }
125
+ }
126
+ async #pageFor(sessionUrl) {
127
+ const browser = await this.#ensureBrowser();
128
+ if (browser === undefined)
129
+ return undefined;
130
+ const pages = browser.contexts().flatMap((c) => c.pages());
131
+ const exact = pages.find((p) => p.url() === sessionUrl);
132
+ if (exact !== undefined)
133
+ return exact;
134
+ const target = stripVolatile(sessionUrl);
135
+ return pages.find((p) => stripVolatile(p.url()) === target);
136
+ }
137
+ async isAvailableFor(sessionUrl) {
138
+ try {
139
+ return (await this.#pageFor(sessionUrl)) !== undefined;
140
+ }
141
+ catch {
142
+ return false;
143
+ }
144
+ }
145
+ async perform(sessionUrl, action, box, args) {
146
+ const page = await this.#pageFor(sessionUrl);
147
+ if (page === undefined)
148
+ return { performed: false, center: boxCenter(box) };
149
+ return performGesture(page, action, box, args, this.#sleep);
150
+ }
151
+ /** PNG of the correlated page, or undefined if none matches. */
152
+ async screenshot(sessionUrl, opts) {
153
+ const page = await this.#pageFor(sessionUrl);
154
+ if (page === undefined)
155
+ return undefined;
156
+ return capturePage(page, opts);
157
+ }
158
+ /** Apply network-mock rules to the correlated page; false when no driven page matches. */
159
+ async setMocks(sessionUrl, rules) {
160
+ const page = await this.#pageFor(sessionUrl);
161
+ if (page === undefined)
162
+ return false;
163
+ await installNetworkMocks(page, rules);
164
+ return true;
165
+ }
166
+ /** Pin the correlated page's viewport to fixed dimensions; false when no driven page matches. */
167
+ async setViewport(sessionUrl, size) {
168
+ const page = await this.#pageFor(sessionUrl);
169
+ if (page === undefined)
170
+ return false;
171
+ await page.setViewportSize({ width: size.width, height: size.height });
172
+ return true;
173
+ }
174
+ /** Best-effort cleanup; idempotent. */
175
+ async dispose() {
176
+ const browser = this.#browser;
177
+ this.#browser = undefined;
178
+ if (browser !== undefined)
179
+ await browser.close();
180
+ }
181
+ }
182
+ const INJECT_CONNECT_WAIT_MS = 8_000;
183
+ /** The only place the dynamic value import of Playwright lives for the launched (drive) path. */
184
+ const launchedChromium = async (headless) => {
185
+ let mod;
186
+ try {
187
+ mod = await import('playwright');
188
+ }
189
+ catch {
190
+ throw new DriveError(DriveErrorCode.PLAYWRIGHT_MISSING, DRIVE_PLAYWRIGHT_MISSING_MSG);
191
+ }
192
+ try {
193
+ return await mod.chromium.launch({ headless });
194
+ }
195
+ catch (e) {
196
+ throw new DriveError(DriveErrorCode.LAUNCH_FAILED, e instanceof Error ? e.message : String(e));
197
+ }
198
+ };
199
+ /**
200
+ * Launches and OWNS a Playwright Chromium, navigates it to `driveUrl`, then drives native
201
+ * input on that page. Headless-capable so @reticlehq/test / CI can run hover/drag unattended.
202
+ */
203
+ export class LaunchedRealInputProvider {
204
+ #driveUrl;
205
+ #headless;
206
+ #sleep;
207
+ #launch;
208
+ #injectConnect;
209
+ #storageState;
210
+ #browser;
211
+ #page;
212
+ constructor(options) {
213
+ this.#driveUrl = options.driveUrl;
214
+ this.#headless = options.headless;
215
+ this.#sleep = options.sleep ?? nodeSleep;
216
+ this.#launch = options.launch ?? launchedChromium;
217
+ this.#injectConnect = options.injectConnect;
218
+ this.#storageState = options.storageState;
219
+ }
220
+ async navigate() {
221
+ this.#browser = await this.#launch(this.#headless);
222
+ const page = await this.#browser.newPage(this.#storageState !== undefined ? { storageState: this.#storageState } : undefined);
223
+ this.#page = page;
224
+ try {
225
+ await page.goto(this.#driveUrl);
226
+ }
227
+ catch (e) {
228
+ throw new DriveError(DriveErrorCode.NAVIGATE_FAILED, e instanceof Error ? e.message : String(e));
229
+ }
230
+ await this.#tryInjectConnect(page);
231
+ }
232
+ /**
233
+ * Wait for the page's Reticle singleton to exist, then re-invoke connect() with our token + loopback
234
+ * URL so a hosted (non-localhost) preview pairs to our bridge without the app being reconfigured.
235
+ * Best-effort: a page with no SDK simply never exposes the global, and we move on.
236
+ */
237
+ async #tryInjectConnect(page) {
238
+ const opts = this.#injectConnect;
239
+ if (opts === undefined)
240
+ return;
241
+ try {
242
+ await page.waitForFunction('!!globalThis.__reticleInstance', {
243
+ timeout: INJECT_CONNECT_WAIT_MS,
244
+ });
245
+ const arg = JSON.stringify({ allowNonLocalhost: true, token: opts.token, url: opts.url });
246
+ await page.evaluate(`globalThis.__reticleInstance.connect(${arg})`);
247
+ }
248
+ catch {
249
+ // No SDK on the page (or it connected already) — the no-session guard in verify reports it.
250
+ }
251
+ }
252
+ isAvailableFor(sessionUrl) {
253
+ const page = this.#page;
254
+ if (page === undefined)
255
+ return Promise.resolve(false);
256
+ if (page.url() === sessionUrl)
257
+ return Promise.resolve(true);
258
+ return Promise.resolve(stripVolatile(page.url()) === stripVolatile(sessionUrl));
259
+ }
260
+ perform(_sessionUrl, action, box, args) {
261
+ const page = this.#page;
262
+ if (page === undefined)
263
+ return Promise.resolve({ performed: false, center: boxCenter(box) });
264
+ return performGesture(page, action, box, args, this.#sleep);
265
+ }
266
+ /** PNG of the owned page, or undefined before navigate / after dispose. */
267
+ screenshot(_sessionUrl, opts) {
268
+ const page = this.#page;
269
+ if (page === undefined)
270
+ return Promise.resolve(undefined);
271
+ return capturePage(page, opts);
272
+ }
273
+ /** Close the owned browser once. Idempotent and safe before navigate. */
274
+ async dispose() {
275
+ const browser = this.#browser;
276
+ this.#browser = undefined;
277
+ this.#page = undefined;
278
+ if (browser !== undefined)
279
+ await browser.close();
280
+ }
281
+ }
282
+ /** Drop hash/query so a page whose URL drifted by fragment still correlates to the session. */
283
+ function stripVolatile(url) {
284
+ const hash = url.indexOf('#');
285
+ const base = hash >= 0 ? url.slice(0, hash) : url;
286
+ const query = base.indexOf('?');
287
+ return query >= 0 ? base.slice(0, query) : base;
288
+ }
289
+ //# sourceMappingURL=real-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"real-input.js","sourceRoot":"","sources":["../../src/input/real-input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type CommandResult } from '@reticlehq/core';
2
+ /** The slice of Session scroll-to-find needs — so tests inject a fake without a live browser. */
3
+ export interface ScrollFindSession {
4
+ command(name: string, args?: Record<string, unknown>): Promise<CommandResult>;
5
+ }
6
+ export interface ScrollFindQuery {
7
+ by: string;
8
+ value: string;
9
+ name?: string;
10
+ /** Ref of the scrollable list container; omit to scroll the document. */
11
+ container?: string;
12
+ /**
13
+ * Known index of the target row in the list. When combined with totalCount, enables bisection:
14
+ * one jump to the estimated scroll offset rather than 20 sequential viewport scrolls.
15
+ */
16
+ targetIndex?: number;
17
+ /** Total item count in the list (required for bisection). */
18
+ totalCount?: number;
19
+ }
20
+ export interface ScrollFindResult {
21
+ found: boolean;
22
+ /** The first matching element descriptor (when found). */
23
+ element?: Record<string, unknown>;
24
+ /** How many viewport scrolls were performed. */
25
+ scrolls: number;
26
+ /**
27
+ * true ⇒ stopped because the list reached its end / could not scroll (raising maxScrolls won't
28
+ * help). false ⇒ stopped at the maxScrolls budget (more rows may exist further down).
29
+ */
30
+ exhausted: boolean;
31
+ }
32
+ /**
33
+ * Reveal an element that a windowed/virtualized list has not mounted yet. Queries
34
+ * once (it may already be visible), then scrolls the container ~one viewport at a time, re-querying
35
+ * after each, until the element appears, the list ends, or the maxScrolls budget is spent. Pure
36
+ * orchestration over the session command seam — fully unit-testable with a fake.
37
+ */
38
+ export declare function scrollToFind(session: ScrollFindSession, q: ScrollFindQuery, opts?: {
39
+ maxScrolls?: number;
40
+ }): Promise<ScrollFindResult>;
41
+ //# sourceMappingURL=scroll-find.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-find.d.ts","sourceRoot":"","sources":["../../src/input/scroll-find.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG3F,iGAAiG;AACjG,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAiBD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,iBAAiB,EAC1B,CAAC,EAAE,eAAe,EAClB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA0C3B"}
@@ -0,0 +1,59 @@
1
+ import { ReticleCommand, SCROLL_FIND_DEFAULTS } from '@reticlehq/core';
2
+ import { asRecord } from '../tools/tools-helpers.js';
3
+ /** One query for the target; returns the first matching element descriptor or undefined. */
4
+ async function queryFirst(session, q) {
5
+ const res = await session.command(ReticleCommand.QUERY, {
6
+ by: q.by,
7
+ value: q.value,
8
+ ...(q.name !== undefined ? { name: q.name } : {}),
9
+ });
10
+ const elements = asRecord(res.result)['elements'];
11
+ if (Array.isArray(elements) && elements.length > 0)
12
+ return asRecord(elements[0]);
13
+ return undefined;
14
+ }
15
+ /**
16
+ * Reveal an element that a windowed/virtualized list has not mounted yet. Queries
17
+ * once (it may already be visible), then scrolls the container ~one viewport at a time, re-querying
18
+ * after each, until the element appears, the list ends, or the maxScrolls budget is spent. Pure
19
+ * orchestration over the session command seam — fully unit-testable with a fake.
20
+ */
21
+ export async function scrollToFind(session, q, opts = {}) {
22
+ const max = opts.maxScrolls ?? SCROLL_FIND_DEFAULTS.MAX_SCROLLS;
23
+ const first = await queryFirst(session, q);
24
+ if (first !== undefined)
25
+ return { found: true, element: first, scrolls: 0, exhausted: false };
26
+ // Bisection: if the caller knows the target index and list size, jump to the estimated offset
27
+ // in one scroll command rather than stepping a viewport at a time. Then refine linearly.
28
+ let scrolls = 0;
29
+ if (q.targetIndex !== undefined && q.totalCount !== undefined && q.totalCount > 1) {
30
+ const fraction = Math.min(1, Math.max(0, q.targetIndex / q.totalCount));
31
+ const sr = await session.command(ReticleCommand.SCROLL, {
32
+ ...(q.container !== undefined ? { ref: q.container } : {}),
33
+ fraction,
34
+ });
35
+ scrolls += 1;
36
+ const hit = await queryFirst(session, q);
37
+ if (hit !== undefined)
38
+ return { found: true, element: hit, scrolls, exhausted: false };
39
+ // Fall through to linear refinement from current position (already near the target).
40
+ const data = asRecord(sr.result);
41
+ if (data['atEnd'] === true || data['scrolled'] === false) {
42
+ return { found: false, scrolls, exhausted: true };
43
+ }
44
+ }
45
+ for (let i = 0; i < max; i += 1) {
46
+ const sr = await session.command(ReticleCommand.SCROLL, q.container !== undefined ? { ref: q.container } : {});
47
+ scrolls += 1;
48
+ const data = asRecord(sr.result);
49
+ const hit = await queryFirst(session, q);
50
+ if (hit !== undefined)
51
+ return { found: true, element: hit, scrolls, exhausted: false };
52
+ // Reached the bottom or the container would not move — no more rows to reveal.
53
+ if (data['atEnd'] === true || data['scrolled'] === false) {
54
+ return { found: false, scrolls, exhausted: true };
55
+ }
56
+ }
57
+ return { found: false, scrolls, exhausted: false }; // spent the budget; more may lie further down
58
+ }
59
+ //# sourceMappingURL=scroll-find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-find.js","sourceRoot":"","sources":["../../src/input/scroll-find.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ToolDef } from '../tools/tools.js';
2
+ /**
3
+ * reticle_scroll_to — the windowed/virtualized-list escape hatch. A plain reticle_query
4
+ * only sees rendered nodes, so an off-screen row in a react-window/react-virtualized list returns
5
+ * nothing. This scrolls the container until the row mounts, then returns its ref.
6
+ */
7
+ export declare const SCROLL_TOOLS: ToolDef[];
8
+ //# sourceMappingURL=scroll-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-tools.d.ts","sourceRoot":"","sources":["../../src/input/scroll-tools.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AAE3D;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,EAkEjC,CAAC"}
@@ -0,0 +1,68 @@
1
+ import { z } from 'zod';
2
+ import { ReticleTool } from '../tools/tool-names.js';
3
+ import { asNumber, asString } from '../tools/tools-helpers.js';
4
+ import { scrollToFind } from './scroll-find.js';
5
+ /**
6
+ * reticle_scroll_to — the windowed/virtualized-list escape hatch. A plain reticle_query
7
+ * only sees rendered nodes, so an off-screen row in a react-window/react-virtualized list returns
8
+ * nothing. This scrolls the container until the row mounts, then returns its ref.
9
+ */
10
+ export const SCROLL_TOOLS = [
11
+ {
12
+ name: ReticleTool.SCROLL_TO,
13
+ description: 'Find an element in a VIRTUALIZED list that has not rendered yet. Pass `by` (role|text|testid|label|placeholder|alt) and `value` (query string) to identify the target row. Scrolls the container until the row mounts, the list ends, or maxScrolls (default 20) is spent. Pass targetIndex + totalCount for bisection — jumps directly to the estimated offset in one scroll (e.g. targetIndex:800 totalCount:1000 jumps to 80% of scrollHeight). Returns { found, element?, scrolls, exhausted }.',
14
+ inputSchema: {
15
+ by: z
16
+ .string()
17
+ .describe('Query strategy for finding the target: role | text | testid | label | placeholder | alt'),
18
+ value: z
19
+ .string()
20
+ .describe('Query value for the selected strategy (the element to scroll into view).'),
21
+ name: z.string().optional().describe('Optional accessible name filter when using by=role.'),
22
+ container: z
23
+ .string()
24
+ .optional()
25
+ .describe('Element ref for the scrollable container. Omit to scroll the document.'),
26
+ maxScrolls: z
27
+ .number()
28
+ .optional()
29
+ .describe('Maximum number of scroll steps before giving up. Default: 20.'),
30
+ targetIndex: z
31
+ .number()
32
+ .optional()
33
+ .describe('Known row index of the target in the list. Combine with totalCount for bisection — jumps directly to the estimated offset.'),
34
+ totalCount: z
35
+ .number()
36
+ .optional()
37
+ .describe('Total item count in the virtualized list. Required for bisection with targetIndex.'),
38
+ sessionId: z
39
+ .string()
40
+ .optional()
41
+ .describe('Active session ID from reticle_sessions. Omit when only one browser session is open.'),
42
+ },
43
+ outputSchema: {
44
+ found: z.boolean(),
45
+ element: z.object({ ref: z.string(), role: z.string(), name: z.string() }).optional(),
46
+ scrolls: z.number(),
47
+ exhausted: z.boolean(),
48
+ },
49
+ handler: (deps, args) => {
50
+ const session = deps.sessions.resolve(asString(args['sessionId']));
51
+ const name = asString(args['name']);
52
+ const container = asString(args['container']);
53
+ const targetIndex = asNumber(args['targetIndex']);
54
+ const totalCount = asNumber(args['totalCount']);
55
+ const q = {
56
+ by: asString(args['by']) ?? '',
57
+ value: asString(args['value']) ?? '',
58
+ ...(name !== undefined ? { name } : {}),
59
+ ...(container !== undefined ? { container } : {}),
60
+ ...(targetIndex !== undefined ? { targetIndex } : {}),
61
+ ...(totalCount !== undefined ? { totalCount } : {}),
62
+ };
63
+ const maxScrolls = asNumber(args['maxScrolls']);
64
+ return scrollToFind(session, q, maxScrolls !== undefined ? { maxScrolls } : {});
65
+ },
66
+ },
67
+ ];
68
+ //# sourceMappingURL=scroll-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-tools.js","sourceRoot":"","sources":["../../src/input/scroll-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAwB,MAAM,kBAAkB,CAAC;AAGtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAc;IACrC;QACE,IAAI,EAAE,WAAW,CAAC,SAAS;QAC3B,WAAW,EACT,qeAAqe;QACve,WAAW,EAAE;YACX,EAAE,EAAE,CAAC;iBACF,MAAM,EAAE;iBACR,QAAQ,CACP,yFAAyF,CAC1F;YACH,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,CAAC,0EAA0E,CAAC;YACvF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;YAC3F,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,wEAAwE,CAAC;YACrF,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,+DAA+D,CAAC;YAC5E,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,4HAA4H,CAC7H;YACH,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,oFAAoF,CACrF;YACH,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,sFAAsF,CACvF;SACJ;QACD,YAAY,EAAE;YACZ,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;YAClB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;YACrF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;YACnB,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;SACvB;QACD,OAAO,EAAE,CAAC,IAAc,EAAE,IAAI,EAAE,EAAE;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAC9C,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YAChD,MAAM,CAAC,GAAoB;gBACzB,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE;gBAC9B,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE;gBACpC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpD,CAAC;YACF,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YAChD,OAAO,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClF,CAAC;KACF;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDef } from '../tools/tools.js';
2
+ export declare const VIEWPORT_TOOLS: ToolDef[];
3
+ //# sourceMappingURL=viewport-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport-tools.d.ts","sourceRoot":"","sources":["../../src/input/viewport-tools.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AA2B3D,eAAO,MAAM,cAAc,EAAE,OAAO,EAwCnC,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod';
2
+ import { VISUAL_NO_PROVIDER_RECOMMENDATION, VisualReason } from '@reticlehq/core';
3
+ import { ReticleTool } from '../tools/tool-names.js';
4
+ import { asString } from '../tools/tools-helpers.js';
5
+ const sessionIdShape = {
6
+ sessionId: z
7
+ .string()
8
+ .optional()
9
+ .describe('Active session ID from reticle_sessions. Omit when only one browser session is open.'),
10
+ };
11
+ /** Bounds so a viewport request stays sane (and a typo can't ask for a 1px or 100k-px window). */
12
+ const MIN_DIM = 64;
13
+ const MAX_DIM = 10000;
14
+ function viewportProvider(deps) {
15
+ const p = deps.realInput;
16
+ return p !== undefined && typeof p.setViewport === 'function'
17
+ ? p
18
+ : undefined;
19
+ }
20
+ export const VIEWPORT_TOOLS = [
21
+ {
22
+ name: ReticleTool.VIEWPORT,
23
+ description: 'Pin the DRIVEN page (needs `reticle drive`) to a fixed viewport size so a screenshot baseline is ' +
24
+ 'reproducible across machines — the missing piece of CI-stable visual regression, alongside ' +
25
+ 'reticle_visual_diff `masks` and a frozen clock (reticle_clock). Set it once before reticle_screenshot / ' +
26
+ 'reticle_visual_diff. Returns { applied, width, height } or the no-provider recommendation.',
27
+ inputSchema: {
28
+ width: z.number().int().describe('Viewport width in CSS px (e.g. 1280).'),
29
+ height: z.number().int().describe('Viewport height in CSS px (e.g. 800).'),
30
+ ...sessionIdShape,
31
+ },
32
+ outputSchema: {
33
+ applied: z.boolean(),
34
+ width: z.number(),
35
+ height: z.number(),
36
+ ok: z.boolean().optional(),
37
+ reason: z.string().optional(),
38
+ recommendation: z.string().optional(),
39
+ },
40
+ handler: async (deps, args) => {
41
+ const provider = viewportProvider(deps);
42
+ if (provider === undefined) {
43
+ return {
44
+ applied: false,
45
+ width: 0,
46
+ height: 0,
47
+ ok: false,
48
+ reason: VisualReason.NO_PROVIDER,
49
+ recommendation: VISUAL_NO_PROVIDER_RECOMMENDATION,
50
+ };
51
+ }
52
+ const width = clampDim(args['width']);
53
+ const height = clampDim(args['height']);
54
+ const session = deps.sessions.resolve(asString(args['sessionId']));
55
+ const applied = await provider.setViewport(session.url, { width, height });
56
+ return { applied, width, height };
57
+ },
58
+ },
59
+ ];
60
+ /** Clamp a requested dimension into [MIN_DIM, MAX_DIM]; a missing/NaN value falls back to MIN_DIM. */
61
+ function clampDim(value) {
62
+ const n = typeof value === 'number' && Number.isFinite(value) ? Math.round(value) : MIN_DIM;
63
+ return Math.max(MIN_DIM, Math.min(n, MAX_DIM));
64
+ }
65
+ //# sourceMappingURL=viewport-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport-tools.js","sourceRoot":"","sources":["../../src/input/viewport-tools.ts"],"names":[],"mappings":"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"}