@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,15 @@
1
+ import { PresenterTone, SessionState } from '@reticlehq/core';
2
+ /**
3
+ * Build the args for a PRESENTER push. An ended session can carry a `tone` so the panel tells apart
4
+ * how the agent stopped — waiting (turn done), ask (needs you), warn (crashed) — from a calm "done".
5
+ * Tone only rides an ended push; live transitions (active/paused) never carry one. Pure.
6
+ */
7
+ export function buildPresenterArgs(state, text, tone) {
8
+ const carriesTone = state === SessionState.ENDED && tone !== undefined && tone !== PresenterTone.CALM;
9
+ return {
10
+ state,
11
+ ...(text !== undefined ? { text } : {}),
12
+ ...(carriesTone ? { tone } : {}),
13
+ };
14
+ }
15
+ //# sourceMappingURL=presenter-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter-args.js","sourceRoot":"","sources":["../../src/session/presenter-args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAmB,EACnB,IAAwB,EACxB,IAA+B;IAE/B,MAAM,WAAW,GACf,KAAK,KAAK,YAAY,CAAC,KAAK,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,aAAa,CAAC,IAAI,CAAC;IACpF,OAAO;QACL,KAAK;QACL,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { MarkStatus, type HumanMarkData, type MarkAnchorStrategy } from '@reticlehq/core';
2
+ /**
3
+ * One human review mark: a mistake a human flagged on the running page, pinned to an element, ready
4
+ * for the agent to drain and fix. The wire payload (HumanMarkData) plus a server-assigned id, the
5
+ * session-relative time it landed, and its lifecycle status.
6
+ */
7
+ export interface ReviewMark {
8
+ id: string;
9
+ note: string;
10
+ /** Re-resolvable element anchor (auto-anchor string). */
11
+ anchor: string;
12
+ strategy: MarkAnchorStrategy;
13
+ label?: string;
14
+ /** Source file:line the agent should open to fix it, when the framework stamped one. */
15
+ source?: {
16
+ file: string;
17
+ line: number;
18
+ };
19
+ route?: string;
20
+ /** Session-relative ms the mark was made (injected clock at the call site — never read here). */
21
+ at: number;
22
+ status: MarkStatus;
23
+ }
24
+ export declare class ReviewStore {
25
+ #private;
26
+ /** Store a new mark (status pending) stamped with the caller-supplied session-relative time. */
27
+ add(data: HumanMarkData, at: number): ReviewMark;
28
+ /** All marks still awaiting a fix, oldest first. Reading never consumes — resolve() retires a mark. */
29
+ pending(): ReviewMark[];
30
+ /** Count of pending marks, for the panel badge / diagnostics. */
31
+ pendingCount(): number;
32
+ /** Full history (pending + resolved), oldest first. */
33
+ all(): ReviewMark[];
34
+ /**
35
+ * Retire a mark the agent has fixed. Returns true on a genuine pending → resolved transition,
36
+ * false for an unknown id or an already-resolved mark (so resolve is idempotent).
37
+ */
38
+ resolve(id: string): boolean;
39
+ }
40
+ //# sourceMappingURL=review-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-store.d.ts","sourceRoot":"","sources":["../../src/session/review-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1F;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;CACpB;AAeD,qBAAa,WAAW;;IAItB,gGAAgG;IAChG,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU;IAiBhD,uGAAuG;IACvG,OAAO,IAAI,UAAU,EAAE;IAIvB,iEAAiE;IACjE,YAAY,IAAI,MAAM;IAItB,uDAAuD;IACvD,GAAG,IAAI,UAAU,EAAE;IAInB;;;OAGG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAM7B"}
@@ -0,0 +1,61 @@
1
+ import { MarkStatus } from '@reticlehq/core';
2
+ /**
3
+ * Per-session store of human review marks (the "annotate the bug where you see it" inbox). A mark is
4
+ * added when a HUMAN_MARK event arrives, listed by the agent via reticle_review, and retired with
5
+ * resolve() when the agent claims the fix — distinct from the live-control inbox, which is drained
6
+ * (delivered-once) on read. Marks persist (read does not consume) so the agent can list, fix, and
7
+ * THEN resolve, and a fix can be verified against the same mark.
8
+ *
9
+ * Pure in-memory state: no IO, no clock. The id is a monotonic counter (m1, m2, …) so it is
10
+ * deterministic and never depends on Math.random/Date.now; the timestamp is passed in by the caller.
11
+ */
12
+ /** Prefix on review-mark ids (m1, m2, …) — distinguishes them from command ids. */
13
+ const MARK_ID_PREFIX = 'm';
14
+ export class ReviewStore {
15
+ #marks = [];
16
+ #seq = 0;
17
+ /** Store a new mark (status pending) stamped with the caller-supplied session-relative time. */
18
+ add(data, at) {
19
+ this.#seq += 1;
20
+ const mark = {
21
+ id: `${MARK_ID_PREFIX}${String(this.#seq)}`,
22
+ note: data.note,
23
+ anchor: data.anchor,
24
+ strategy: data.strategy,
25
+ at,
26
+ status: MarkStatus.PENDING,
27
+ };
28
+ if (data.label !== undefined)
29
+ mark.label = data.label;
30
+ if (data.source !== undefined)
31
+ mark.source = data.source;
32
+ if (data.route !== undefined)
33
+ mark.route = data.route;
34
+ this.#marks.push(mark);
35
+ return mark;
36
+ }
37
+ /** All marks still awaiting a fix, oldest first. Reading never consumes — resolve() retires a mark. */
38
+ pending() {
39
+ return this.#marks.filter((m) => m.status === MarkStatus.PENDING).map((m) => ({ ...m }));
40
+ }
41
+ /** Count of pending marks, for the panel badge / diagnostics. */
42
+ pendingCount() {
43
+ return this.#marks.reduce((n, m) => (m.status === MarkStatus.PENDING ? n + 1 : n), 0);
44
+ }
45
+ /** Full history (pending + resolved), oldest first. */
46
+ all() {
47
+ return this.#marks.map((m) => ({ ...m }));
48
+ }
49
+ /**
50
+ * Retire a mark the agent has fixed. Returns true on a genuine pending → resolved transition,
51
+ * false for an unknown id or an already-resolved mark (so resolve is idempotent).
52
+ */
53
+ resolve(id) {
54
+ const mark = this.#marks.find((m) => m.id === id);
55
+ if (mark === undefined || mark.status === MarkStatus.RESOLVED)
56
+ return false;
57
+ mark.status = MarkStatus.RESOLVED;
58
+ return true;
59
+ }
60
+ }
61
+ //# sourceMappingURL=review-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-store.js","sourceRoot":"","sources":["../../src/session/review-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA+C,MAAM,iBAAiB,CAAC;AAsB1F;;;;;;;;;GASG;AACH,mFAAmF;AACnF,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,MAAM,OAAO,WAAW;IACb,MAAM,GAAiB,EAAE,CAAC;IACnC,IAAI,GAAG,CAAC,CAAC;IAET,gGAAgG;IAChG,GAAG,CAAC,IAAmB,EAAE,EAAU;QACjC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QACf,MAAM,IAAI,GAAe;YACvB,EAAE,EAAE,GAAG,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC3C,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,EAAE;YACF,MAAM,EAAE,UAAU,CAAC,OAAO;SAC3B,CAAC;QACF,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACtD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACzD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uGAAuG;IACvG,OAAO;QACL,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,iEAAiE;IACjE,YAAY;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,uDAAuD;IACvD,GAAG;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,EAAU;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5E,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ import type { Session, SessionHealth } from './session.js';
2
+ /** The `session` (and optional throttled `warning`) block spliced onto act/assert results. */
3
+ interface HealthEnvelope {
4
+ session?: SessionHealth;
5
+ warning?: string;
6
+ }
7
+ /**
8
+ * Build the health envelope for a tool result. When the session is **nominal** (focused, not
9
+ * throttled, no escape-hatch recommendation) the block is OMITTED entirely — a healthy session
10
+ * conveys nothing actionable, and emitting it on every act/observe/assert call is pure token
11
+ * overhead. The block (and a throttled `warning`) appears only when something is actually wrong,
12
+ * so no health signal is lost — absence means healthy.
13
+ */
14
+ export declare function healthEnvelope(session: Session): HealthEnvelope;
15
+ /**
16
+ * Opt-in hard stop. When `refuseWhenThrottled` is true and the tab is throttled, throw so the
17
+ * agent does not drive a tab where timers/rAF/pointer gestures may silently no-op. Default is
18
+ * warn-only so background testing never breaks.
19
+ */
20
+ export declare function refuseIfThrottled(session: Session, refuse: unknown): void;
21
+ export {};
22
+ //# sourceMappingURL=session-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-health.d.ts","sourceRoot":"","sources":["../../src/session/session-health.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D,8FAA8F;AAC9F,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAK/D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAIzE"}
@@ -0,0 +1,26 @@
1
+ import { THROTTLED_WARNING } from '@reticlehq/core';
2
+ /**
3
+ * Build the health envelope for a tool result. When the session is **nominal** (focused, not
4
+ * throttled, no escape-hatch recommendation) the block is OMITTED entirely — a healthy session
5
+ * conveys nothing actionable, and emitting it on every act/observe/assert call is pure token
6
+ * overhead. The block (and a throttled `warning`) appears only when something is actually wrong,
7
+ * so no health signal is lost — absence means healthy.
8
+ */
9
+ export function healthEnvelope(session) {
10
+ const health = session.health();
11
+ const nominal = !health.throttled && health.focused && health.recommendation === undefined;
12
+ if (nominal)
13
+ return {};
14
+ return health.throttled ? { session: health, warning: THROTTLED_WARNING } : { session: health };
15
+ }
16
+ /**
17
+ * Opt-in hard stop. When `refuseWhenThrottled` is true and the tab is throttled, throw so the
18
+ * agent does not drive a tab where timers/rAF/pointer gestures may silently no-op. Default is
19
+ * warn-only so background testing never breaks.
20
+ */
21
+ export function refuseIfThrottled(session, refuse) {
22
+ if (refuse === true && session.throttled()) {
23
+ throw new Error(`refusing to act: ${THROTTLED_WARNING}`);
24
+ }
25
+ }
26
+ //# sourceMappingURL=session-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-health.js","sourceRoot":"","sources":["../../src/session/session-health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AASpD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,cAAc,KAAK,SAAS,CAAC;IAC3F,IAAI,OAAO;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAClG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB,EAAE,MAAe;IACjE,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,oBAAoB,iBAAiB,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { Session, type SessionInfo } from './session.js';
2
+ /**
3
+ * The agent's active project, used to scope auto-selection. `projectId` is the stable build-stamped
4
+ * identity (authoritative when present); `url` is the app origin, a fallback hint for older SDKs that
5
+ * don't stamp a projectId. Both optional — an empty scope means "no project filter" (legacy behavior).
6
+ */
7
+ interface ResolveScope {
8
+ projectId?: string;
9
+ url?: string;
10
+ }
11
+ /**
12
+ * Owns the set of connected browser sessions and the smart auto-selection that resolves which one a
13
+ * tool targets when the agent omits an explicit sessionId. Extracted from session.ts so each file
14
+ * stays one cohesive unit (Session = one tab; SessionManager = the registry over all tabs).
15
+ */
16
+ export declare class SessionManager {
17
+ #private;
18
+ /** Set the active project's default resolve scope (called once at daemon wiring). */
19
+ setDefaultScope(scope: ResolveScope | undefined): void;
20
+ add(session: Session): Session | undefined;
21
+ remove(session: Session): boolean;
22
+ get(sessionId: string): Session | undefined;
23
+ list(): SessionInfo[];
24
+ /** Every connected session — used by the liveness reaper to sweep for idle/disconnected ones. */
25
+ all(): Session[];
26
+ count(): number;
27
+ /**
28
+ * Resolve the target session. With an explicit id, returns it. With none and exactly
29
+ * one connected, returns that.
30
+ *
31
+ * With none and multiple connected, applies smart auto-selection:
32
+ * 1. Prefer non-throttled sessions (not hidden + recently heard from).
33
+ * 2. Within each tier, prefer lowest lastSeenMs (most recently active SDK heartbeat).
34
+ * 3. If two or more non-throttled sessions are within 1 s of each other, throw —
35
+ * genuinely ambiguous, agent must specify sessionId.
36
+ * 4. If ALL sessions are throttled (e.g. user is working in their editor on another
37
+ * desktop), skip the gap check and pick the freshest heartbeat. This lets the agent
38
+ * keep working in the background without requiring sessionId every time.
39
+ */
40
+ resolve(sessionId?: string, scope?: ResolveScope): Session;
41
+ }
42
+ export {};
43
+ //# sourceMappingURL=session-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;GAIG;AACH,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAwCD;;;;GAIG;AACH,qBAAa,cAAc;;IASzB,qFAAqF;IACrF,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI;IAItD,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;IAM1C,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAMjC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI3C,IAAI,IAAI,WAAW,EAAE;IAIrB,iGAAiG;IACjG,GAAG,IAAI,OAAO,EAAE;IAIhB,KAAK,IAAI,MAAM;IAIf;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO;CAsE3D"}
@@ -0,0 +1,155 @@
1
+ import { Session } from './session.js';
2
+ /** The scheme://host:port of a URL, or undefined if it can't be parsed. Used to compare origins. */
3
+ function originOf(url) {
4
+ if (url === undefined)
5
+ return undefined;
6
+ try {
7
+ return new URL(url).origin;
8
+ }
9
+ catch {
10
+ return undefined;
11
+ }
12
+ }
13
+ /**
14
+ * Narrow a session list to those belonging to the scoped project. With a `projectId` the match is by
15
+ * that stable id (origin ignored — it survives port swaps). With only a `url`, match by origin. With
16
+ * no scope, return the list unchanged (legacy single-/multi-session behavior).
17
+ */
18
+ function scopeSessions(sessions, scope) {
19
+ if (scope === undefined)
20
+ return sessions;
21
+ if (scope.projectId !== undefined) {
22
+ return sessions.filter((s) => s.projectId === scope.projectId);
23
+ }
24
+ const wantOrigin = originOf(scope.url);
25
+ if (wantOrigin !== undefined) {
26
+ return sessions.filter((s) => originOf(s.url) === wantOrigin);
27
+ }
28
+ return sessions;
29
+ }
30
+ /** Honest, scoped error when sessions exist but none match the agent's project. */
31
+ function scopeMissError(scope) {
32
+ const who = scope?.projectId !== undefined
33
+ ? `project '${scope.projectId}'`
34
+ : scope?.url !== undefined
35
+ ? `your app at ${scope.url}`
36
+ : 'the active project';
37
+ return `no browser session for ${who} — is that app running with @reticlehq/core enabled? (other apps may be connected, but they won't be driven by mistake)`;
38
+ }
39
+ /**
40
+ * Owns the set of connected browser sessions and the smart auto-selection that resolves which one a
41
+ * tool targets when the agent omits an explicit sessionId. Extracted from session.ts so each file
42
+ * stays one cohesive unit (Session = one tab; SessionManager = the registry over all tabs).
43
+ */
44
+ export class SessionManager {
45
+ #sessions = new Map();
46
+ /**
47
+ * The active project's scope, set once from the daemon's .reticle.json. When a tool resolves a session
48
+ * without passing its own scope, this is applied — so auto-selection is project-scoped by default
49
+ * and a stray tab from another app is never picked, even on the no-sessionId path.
50
+ */
51
+ #defaultScope;
52
+ /** Set the active project's default resolve scope (called once at daemon wiring). */
53
+ setDefaultScope(scope) {
54
+ this.#defaultScope = scope;
55
+ }
56
+ add(session) {
57
+ const previous = this.#sessions.get(session.id);
58
+ this.#sessions.set(session.id, session);
59
+ return previous;
60
+ }
61
+ remove(session) {
62
+ if (this.#sessions.get(session.id) !== session)
63
+ return false;
64
+ session.rejectAll('session disconnected');
65
+ return this.#sessions.delete(session.id);
66
+ }
67
+ get(sessionId) {
68
+ return this.#sessions.get(sessionId);
69
+ }
70
+ list() {
71
+ return [...this.#sessions.values()].map((s) => s.info());
72
+ }
73
+ /** Every connected session — used by the liveness reaper to sweep for idle/disconnected ones. */
74
+ all() {
75
+ return [...this.#sessions.values()];
76
+ }
77
+ count() {
78
+ return this.#sessions.size;
79
+ }
80
+ /**
81
+ * Resolve the target session. With an explicit id, returns it. With none and exactly
82
+ * one connected, returns that.
83
+ *
84
+ * With none and multiple connected, applies smart auto-selection:
85
+ * 1. Prefer non-throttled sessions (not hidden + recently heard from).
86
+ * 2. Within each tier, prefer lowest lastSeenMs (most recently active SDK heartbeat).
87
+ * 3. If two or more non-throttled sessions are within 1 s of each other, throw —
88
+ * genuinely ambiguous, agent must specify sessionId.
89
+ * 4. If ALL sessions are throttled (e.g. user is working in their editor on another
90
+ * desktop), skip the gap check and pick the freshest heartbeat. This lets the agent
91
+ * keep working in the background without requiring sessionId every time.
92
+ */
93
+ resolve(sessionId, scope) {
94
+ if (sessionId !== undefined) {
95
+ const found = this.#sessions.get(sessionId);
96
+ if (found === undefined) {
97
+ throw new Error(`no connected session with id '${sessionId}'`);
98
+ }
99
+ found.markAgentActivity(); // liveness — a targeted tool keeps the session alive / revives it
100
+ return found;
101
+ }
102
+ if (this.#sessions.size === 0) {
103
+ throw new Error('no browser session connected — is your app running with @reticlehq/browser enabled?');
104
+ }
105
+ // Scope to the agent's active project FIRST, so a stray tab from another app/origin (e.g. a
106
+ // leftover dashboard on a different port) is structurally unselectable — it never enters the
107
+ // candidate set, no matter how recently it was heard from. This is the anti-cross-talk guard.
108
+ // An explicit per-call scope wins; otherwise the daemon's active-project default applies.
109
+ const effectiveScope = scope ?? this.#defaultScope;
110
+ const all = scopeSessions([...this.#sessions.values()], effectiveScope);
111
+ if (all.length === 0) {
112
+ // Sessions exist, but none belong to the scoped project — never fall back to a foreign tab.
113
+ throw new Error(scopeMissError(effectiveScope));
114
+ }
115
+ if (all.length === 1) {
116
+ const [only] = all;
117
+ if (only === undefined)
118
+ throw new Error('session lookup failed');
119
+ only.markAgentActivity();
120
+ return only;
121
+ }
122
+ // Multiple sessions: score each (lower = better candidate for auto-selection).
123
+ // 0 = non-throttled (visible + recently-heard), 1 = throttled (hidden or stale heartbeat).
124
+ const scored = all.map((s) => ({ s, score: s.throttled() ? 1 : 0, ms: s.lastSeenMs() }));
125
+ const bestScore = Math.min(...scored.map((x) => x.score));
126
+ const candidates = scored.filter((x) => x.score === bestScore);
127
+ // Sort candidates by recency (ascending lastSeenMs = most recently active first).
128
+ candidates.sort((a, b) => a.ms - b.ms);
129
+ const [best, runnerUp] = candidates;
130
+ if (best === undefined)
131
+ throw new Error('session lookup failed');
132
+ // Only auto-select if there is a clear winner.
133
+ //
134
+ // When at least one non-throttled (focused/visible) session exists, require a >1 s recency
135
+ // gap before committing — two tabs that both had recent heartbeats are genuinely ambiguous.
136
+ //
137
+ // When ALL candidates are throttled (e.g. the user switched to their editor on another
138
+ // desktop), the gap requirement is dropped: every session is already in "background" mode
139
+ // so we just pick the one with the freshest heartbeat and let the agent proceed. Requiring
140
+ // a gap here only produces spurious "ambiguous" errors while the user works elsewhere.
141
+ const allThrottled = bestScore === 1;
142
+ const RECENCY_GAP_MS = allThrottled ? 0 : 1_000;
143
+ const clearWinner = runnerUp === undefined || best.ms + RECENCY_GAP_MS < runnerUp.ms;
144
+ if (!clearWinner) {
145
+ // Ambiguous: list sessions with their health so the agent can choose.
146
+ const detail = all
147
+ .map((s) => `${s.id} (${s.throttled() ? 'throttled' : 'active'}, lastSeenMs=${s.lastSeenMs()})`)
148
+ .join(', ');
149
+ throw new Error(`multiple sessions connected — pass sessionId to target one: ${detail}`);
150
+ }
151
+ best.s.markAgentActivity();
152
+ return best.s;
153
+ }
154
+ }
155
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * First-run readiness: the agent often issues its first tool call in the window between `reticle init`
3
+ * and the app's SDK actually connecting its WebSocket — so a naive resolve throws "no session". This
4
+ * lets the agent (via reticle_wait_ready) BLOCK briefly until a session appears instead of failing the
5
+ * race, smoothing the most common first-5-minutes footgun.
6
+ *
7
+ * Pure control loop: the session count, clock, and sleep are all injected, so it is unit-tested with
8
+ * no real timers — and in production it polls a real `setTimeout` sleep.
9
+ */
10
+ interface WaitForReadyOptions {
11
+ /** Live count of connected sessions (SessionManager.count). */
12
+ count: () => number;
13
+ /** Give up after this much elapsed time. */
14
+ timeoutMs: number;
15
+ /** Injected monotonic clock (ms). */
16
+ now: () => number;
17
+ /** Injected delay between polls. */
18
+ sleep: (ms: number) => Promise<void>;
19
+ /** Poll interval (ms). Default 100. */
20
+ pollMs?: number;
21
+ }
22
+ /**
23
+ * One-line orientation for a FRESH agent — the Reticle loop, returned by reticle_wait_ready (the first call)
24
+ * so an agent learns how to drive Reticle without reading docs. Named so it is not a free string; kept
25
+ * terse on purpose (it rides the first response, where token budget is tightest).
26
+ */
27
+ export declare const RETICLE_LOOP_GUIDE: string;
28
+ /**
29
+ * Resolve `true` as soon as at least one session is connected, or `false` if the timeout elapses
30
+ * first. Returns immediately when a session is already connected (the common, already-ready case —
31
+ * so this never adds latency on the happy path, including the benchmark which always has a session).
32
+ */
33
+ export declare function waitForReady(opts: WaitForReadyOptions): Promise<boolean>;
34
+ export {};
35
+ //# sourceMappingURL=session-readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-readiness.d.ts","sourceRoot":"","sources":["../../src/session/session-readiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,UAAU,mBAAmB;IAC3B,+DAA+D;IAC/D,KAAK,EAAE,MAAM,MAAM,CAAC;IACpB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,oCAAoC;IACpC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,QAO2E,CAAC;AAE3G;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAS9E"}
@@ -0,0 +1,32 @@
1
+ const DEFAULT_POLL_MS = 100;
2
+ /**
3
+ * One-line orientation for a FRESH agent — the Reticle loop, returned by reticle_wait_ready (the first call)
4
+ * so an agent learns how to drive Reticle without reading docs. Named so it is not a free string; kept
5
+ * terse on purpose (it rides the first response, where token budget is tightest).
6
+ */
7
+ export const RETICLE_LOOP_GUIDE = 'Reticle loop — LOOK: reticle_snapshot / reticle_query / reticle_inspect · ACT: reticle_act (or reticle_act_and_wait) · ' +
8
+ 'OBSERVE: reticle_observe / reticle_wait_for / reticle_network / reticle_console · ASSERT: reticle_assert over program ' +
9
+ 'truth, not just the DOM · REGRESS: reticle_record_start → reticle_replay, or reticle_flow_verify for the whole ' +
10
+ 'suite. The human can flag bugs from the panel — drain them with reticle_review and resolve each once fixed. ' +
11
+ 'MANDATORY: the moment you stop driving — finishing your reply or waiting on the human — call reticle_yield ' +
12
+ '(mode:"waiting", or mode:"ask" with the question) so the panel shows your real state; reticle_end_session ' +
13
+ 'only when the whole task is done. Never leave the panel reading "live" when you have actually stopped.';
14
+ /**
15
+ * Resolve `true` as soon as at least one session is connected, or `false` if the timeout elapses
16
+ * first. Returns immediately when a session is already connected (the common, already-ready case —
17
+ * so this never adds latency on the happy path, including the benchmark which always has a session).
18
+ */
19
+ export async function waitForReady(opts) {
20
+ if (opts.count() > 0)
21
+ return true;
22
+ const start = opts.now();
23
+ const poll = opts.pollMs ?? DEFAULT_POLL_MS;
24
+ for (;;) {
25
+ if (opts.now() - start >= opts.timeoutMs)
26
+ return opts.count() > 0;
27
+ await opts.sleep(poll);
28
+ if (opts.count() > 0)
29
+ return true;
30
+ }
31
+ }
32
+ //# sourceMappingURL=session-readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-readiness.js","sourceRoot":"","sources":["../../src/session/session-readiness.ts"],"names":[],"mappings":"AAsBA,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,yHAAyH;IACzH,wHAAwH;IACxH,iHAAiH;IACjH,8GAA8G;IAC9G,6GAA6G;IAC7G,4GAA4G;IAC5G,wGAAwG,CAAC;AAE3G;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC;IAC5C,SAAS,CAAC;QACR,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAClE,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACpC,CAAC;AACH,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { SessionManager } from './session.js';
2
+ /**
3
+ * Server-authoritative session liveness. The browser idle timer is throttled in a backgrounded tab
4
+ * and dies with the bridge if the agent (MCP client) is killed — so the Node server, which is immune
5
+ * to throttling, owns the decision. The reaper ends a session whose AGENT has gone quiet past its
6
+ * idle window; the end is pushed to the browser as a PRESENTER command, which a throttled tab still
7
+ * receives. A returning agent revives an auto-ended session (see Session.markAgentActivity).
8
+ */
9
+ /**
10
+ * Human-facing summary shown in the HUD when the MCP client (the agent) disconnects. Agent-neutral:
11
+ * Reticle runs under any agent (Codex/OpenCode/Claude/Hermes), so the copy never names one.
12
+ */
13
+ export declare const MCP_DISCONNECT_SUMMARY = "Session ended \u2014 the agent disconnected.";
14
+ /**
15
+ * Fold any unread human notes into the end-of-session notice. Pure. A prompt typed into the panel in
16
+ * the death-race — the agent stops before draining its inbox — would otherwise vanish silently; here
17
+ * it rides the end banner so the human can copy it into their terminal. No notes → the base unchanged.
18
+ */
19
+ export declare function composeEndedNotice(base: string, undelivered: string[]): string;
20
+ /**
21
+ * Hand back every session whose agent has gone quiet past its window — shown as WAITING (your turn),
22
+ * not a crash, since the agent is still connected and revives on its next action. Returns the ids.
23
+ */
24
+ export declare function reapIdleSessions(sessions: SessionManager): string[];
25
+ /** End every active session immediately (the agent / MCP client disconnected → WARN). Returns ended ids. */
26
+ export declare function endAllSessions(sessions: SessionManager, reason: string): string[];
27
+ /**
28
+ * Runs {@link reapIdleSessions} on a Node interval. The timer is `unref`'d so it never keeps the
29
+ * process alive on its own, and `start()` is idempotent.
30
+ */
31
+ export declare class SessionReaper {
32
+ #private;
33
+ constructor(sessions: SessionManager, intervalMs?: number);
34
+ start(): void;
35
+ stop(): void;
36
+ }
37
+ //# sourceMappingURL=session-reaper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-reaper.d.ts","sourceRoot":"","sources":["../../src/session/session-reaper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,cAAc,CAAC;AAG5D;;;;;;GAMG;AAEH;;;GAGG;AACH,eAAO,MAAM,sBAAsB,iDAA4C,CAAC;AAKhF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAI9E;AAWD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,EAAE,CAWnE;AAED,4GAA4G;AAC5G,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CASjF;AAED;;;GAGG;AACH,qBAAa,aAAa;;gBAKZ,QAAQ,EAAE,cAAc,EAAE,UAAU,GAAE,MAA2C;IAK7F,KAAK,IAAI,IAAI;IAQb,IAAI,IAAI,IAAI;CAKb"}
@@ -0,0 +1,94 @@
1
+ import { PresenterTone, SESSION_LIFECYCLE, UNDELIVERED_NOTES_LABEL } from '@reticlehq/core';
2
+ import { log } from '../log.js';
3
+ /**
4
+ * Server-authoritative session liveness. The browser idle timer is throttled in a backgrounded tab
5
+ * and dies with the bridge if the agent (MCP client) is killed — so the Node server, which is immune
6
+ * to throttling, owns the decision. The reaper ends a session whose AGENT has gone quiet past its
7
+ * idle window; the end is pushed to the browser as a PRESENTER command, which a throttled tab still
8
+ * receives. A returning agent revives an auto-ended session (see Session.markAgentActivity).
9
+ */
10
+ /**
11
+ * Human-facing summary shown in the HUD when the MCP client (the agent) disconnects. Agent-neutral:
12
+ * Reticle runs under any agent (Codex/OpenCode/Claude/Hermes), so the copy never names one.
13
+ */
14
+ export const MCP_DISCONNECT_SUMMARY = 'Session ended — the agent disconnected.';
15
+ /** Shown when the agent goes quiet between turns and the session is handed back to the human (WAITING). */
16
+ const IDLE_WAITING_SUMMARY = 'Agent idle — your turn. Continue in your terminal.';
17
+ /**
18
+ * Fold any unread human notes into the end-of-session notice. Pure. A prompt typed into the panel in
19
+ * the death-race — the agent stops before draining its inbox — would otherwise vanish silently; here
20
+ * it rides the end banner so the human can copy it into their terminal. No notes → the base unchanged.
21
+ */
22
+ export function composeEndedNotice(base, undelivered) {
23
+ if (undelivered.length === 0)
24
+ return base;
25
+ const notes = undelivered.map((text) => `"${text}"`).join(', ');
26
+ return `${base} · ${UNDELIVERED_NOTES_LABEL} ${notes}`;
27
+ }
28
+ /**
29
+ * End a session, surfacing any unread human notes in its end notice instead of dropping them. `tone`
30
+ * tells the panel how to present it: WAITING (agent went quiet) vs WARN (agent crashed/disconnected).
31
+ */
32
+ function endWithUndelivered(session, base, tone) {
33
+ const undelivered = session.drainInbox().map((m) => m.text);
34
+ session.autoEnd(composeEndedNotice(base, undelivered), tone);
35
+ }
36
+ /**
37
+ * Hand back every session whose agent has gone quiet past its window — shown as WAITING (your turn),
38
+ * not a crash, since the agent is still connected and revives on its next action. Returns the ids.
39
+ */
40
+ export function reapIdleSessions(sessions) {
41
+ const ended = [];
42
+ for (const session of sessions.all()) {
43
+ if (session.isEnded())
44
+ continue;
45
+ if (session.agentIdleMs() >= session.idleEndMs()) {
46
+ endWithUndelivered(session, IDLE_WAITING_SUMMARY, PresenterTone.WAITING);
47
+ ended.push(session.id);
48
+ }
49
+ }
50
+ if (ended.length > 0)
51
+ log('session_reaped_idle', { sessions: ended });
52
+ return ended;
53
+ }
54
+ /** End every active session immediately (the agent / MCP client disconnected → WARN). Returns ended ids. */
55
+ export function endAllSessions(sessions, reason) {
56
+ const ended = [];
57
+ for (const session of sessions.all()) {
58
+ if (session.isEnded())
59
+ continue;
60
+ endWithUndelivered(session, reason, PresenterTone.WARN);
61
+ ended.push(session.id);
62
+ }
63
+ if (ended.length > 0)
64
+ log('sessions_ended', { reason, sessions: ended });
65
+ return ended;
66
+ }
67
+ /**
68
+ * Runs {@link reapIdleSessions} on a Node interval. The timer is `unref`'d so it never keeps the
69
+ * process alive on its own, and `start()` is idempotent.
70
+ */
71
+ export class SessionReaper {
72
+ #timer;
73
+ #sessions;
74
+ #intervalMs;
75
+ constructor(sessions, intervalMs = SESSION_LIFECYCLE.REAP_INTERVAL_MS) {
76
+ this.#sessions = sessions;
77
+ this.#intervalMs = intervalMs;
78
+ }
79
+ start() {
80
+ if (this.#timer !== undefined)
81
+ return;
82
+ this.#timer = setInterval(() => {
83
+ reapIdleSessions(this.#sessions);
84
+ }, this.#intervalMs);
85
+ this.#timer.unref();
86
+ }
87
+ stop() {
88
+ if (this.#timer === undefined)
89
+ return;
90
+ clearInterval(this.#timer);
91
+ this.#timer = undefined;
92
+ }
93
+ }
94
+ //# sourceMappingURL=session-reaper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-reaper.js","sourceRoot":"","sources":["../../src/session/session-reaper.ts"],"names":[],"mappings":"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"}