@reticlehq/server 2.2.1 → 2.3.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 (778) hide show
  1. package/README.md +1 -1
  2. package/dist/bridge-security.d.ts +0 -1
  3. package/dist/bridge-security.js +0 -1
  4. package/dist/bridge.d.ts +0 -1
  5. package/dist/bridge.js +60 -10
  6. package/dist/bridge.test-harness.d.ts +0 -1
  7. package/dist/bridge.test-harness.js +0 -1
  8. package/dist/capsule/capsule-store.d.ts +2 -3
  9. package/dist/capsule/capsule-store.js +0 -1
  10. package/dist/capsule/capsule.d.ts +0 -1
  11. package/dist/capsule/capsule.js +0 -1
  12. package/dist/capsule/causal-summary.d.ts +21 -1
  13. package/dist/capsule/causal-summary.js +20 -2
  14. package/dist/capsule/divergence.d.ts +0 -1
  15. package/dist/capsule/divergence.js +0 -1
  16. package/dist/capsule/minimize.d.ts +0 -1
  17. package/dist/capsule/minimize.js +0 -1
  18. package/dist/capsule/predicate-to-links.d.ts +0 -1
  19. package/dist/capsule/predicate-to-links.js +0 -1
  20. package/dist/cli-doctor.d.ts +6 -0
  21. package/dist/cli-doctor.js +60 -0
  22. package/dist/cli-flow-commands.d.ts +0 -1
  23. package/dist/cli-flow-commands.js +0 -1
  24. package/dist/cli-launch.d.ts +0 -1
  25. package/dist/cli-launch.js +7 -3
  26. package/dist/cli-parse.d.ts +34 -2
  27. package/dist/cli-parse.js +107 -1
  28. package/dist/cli-port.d.ts +0 -1
  29. package/dist/cli-port.js +0 -1
  30. package/dist/cli-verify.d.ts +0 -1
  31. package/dist/cli-verify.js +1 -2
  32. package/dist/cli.d.ts +0 -1
  33. package/dist/cli.js +79 -67
  34. package/dist/cloud/cloud-config.d.ts +0 -1
  35. package/dist/cloud/cloud-config.js +0 -1
  36. package/dist/cloud/cloud-sync.d.ts +4 -5
  37. package/dist/cloud/cloud-sync.js +0 -1
  38. package/dist/cloud-cli.d.ts +0 -1
  39. package/dist/cloud-cli.js +9 -2
  40. package/dist/crawl/crawl-tools.d.ts +0 -1
  41. package/dist/crawl/crawl-tools.js +1 -2
  42. package/dist/crawl/crawl.d.ts +17 -3
  43. package/dist/crawl/crawl.js +43 -4
  44. package/dist/daemon-resilience.d.ts +6 -1
  45. package/dist/daemon-resilience.js +63 -1
  46. package/dist/daemon.d.ts +23 -3
  47. package/dist/daemon.js +36 -24
  48. package/dist/domain/domain-model.d.ts +0 -1
  49. package/dist/domain/domain-model.js +1 -2
  50. package/dist/domain/domain-tools.d.ts +0 -7
  51. package/dist/domain/domain-tools.js +21 -4
  52. package/dist/domain/flow-risk.d.ts +0 -1
  53. package/dist/domain/flow-risk.js +0 -1
  54. package/dist/ee/audit-log.d.ts +0 -1
  55. package/dist/ee/audit-log.js +0 -1
  56. package/dist/events/body-failures.d.ts +4 -0
  57. package/dist/events/body-failures.js +113 -0
  58. package/dist/events/contradictions.d.ts +53 -0
  59. package/dist/events/contradictions.js +282 -0
  60. package/dist/events/echo-mismatch.d.ts +4 -0
  61. package/dist/events/echo-mismatch.js +138 -0
  62. package/dist/events/event-filters.d.ts +17 -3
  63. package/dist/events/event-filters.js +13 -3
  64. package/dist/events/json-salvage.d.ts +32 -0
  65. package/dist/events/json-salvage.js +96 -0
  66. package/dist/events/predicate-eval.d.ts +2 -1
  67. package/dist/events/predicate-eval.js +56 -9
  68. package/dist/events/predicate.d.ts +0 -1
  69. package/dist/events/predicate.js +56 -2
  70. package/dist/events/reaction.d.ts +0 -1
  71. package/dist/events/reaction.js +0 -1
  72. package/dist/events/reconcile.d.ts +39 -0
  73. package/dist/events/reconcile.js +211 -0
  74. package/dist/events/ring-buffer.d.ts +0 -1
  75. package/dist/events/ring-buffer.js +0 -1
  76. package/dist/events/stale-response.d.ts +4 -0
  77. package/dist/events/stale-response.js +139 -0
  78. package/dist/events/unit-mismatch.d.ts +16 -0
  79. package/dist/events/unit-mismatch.js +167 -0
  80. package/dist/flows/affected-tools.d.ts +18 -0
  81. package/dist/flows/affected-tools.js +52 -0
  82. package/dist/flows/affected.d.ts +0 -1
  83. package/dist/flows/affected.js +0 -1
  84. package/dist/flows/annotate-tools.d.ts +0 -1
  85. package/dist/flows/annotate-tools.js +21 -3
  86. package/dist/flows/annotate.d.ts +0 -1
  87. package/dist/flows/annotate.js +0 -1
  88. package/dist/flows/annotation-store.d.ts +0 -1
  89. package/dist/flows/annotation-store.js +0 -1
  90. package/dist/flows/assertion-integrity.d.ts +0 -1
  91. package/dist/flows/assertion-integrity.js +0 -1
  92. package/dist/flows/assertion-tiers-store.d.ts +0 -1
  93. package/dist/flows/assertion-tiers-store.js +0 -1
  94. package/dist/flows/buddy-status.d.ts +0 -1
  95. package/dist/flows/buddy-status.js +0 -1
  96. package/dist/flows/coverage.d.ts +0 -1
  97. package/dist/flows/coverage.js +0 -1
  98. package/dist/flows/decision.d.ts +0 -1
  99. package/dist/flows/decision.js +0 -1
  100. package/dist/flows/flake-store.d.ts +0 -1
  101. package/dist/flows/flake-store.js +0 -1
  102. package/dist/flows/flake.d.ts +0 -1
  103. package/dist/flows/flake.js +0 -1
  104. package/dist/flows/flow-classify.d.ts +0 -1
  105. package/dist/flows/flow-classify.js +0 -1
  106. package/dist/flows/flow-replay-run.d.ts +0 -1
  107. package/dist/flows/flow-replay-run.js +2 -3
  108. package/dist/flows/flow-replay.d.ts +20 -4
  109. package/dist/flows/flow-replay.js +9 -43
  110. package/dist/flows/flow-report.d.ts +0 -1
  111. package/dist/flows/flow-report.js +0 -1
  112. package/dist/flows/flow-scope.d.ts +0 -1
  113. package/dist/flows/flow-scope.js +0 -1
  114. package/dist/flows/flow-sources.d.ts +0 -1
  115. package/dist/flows/flow-sources.js +0 -1
  116. package/dist/flows/flow-step-runners.d.ts +23 -0
  117. package/dist/flows/flow-step-runners.js +102 -0
  118. package/dist/flows/flow-success.d.ts +0 -1
  119. package/dist/flows/flow-success.js +0 -1
  120. package/dist/flows/flow-tools.d.ts +0 -1
  121. package/dist/flows/flow-tools.js +30 -8
  122. package/dist/flows/flows.d.ts +6 -2
  123. package/dist/flows/flows.js +15 -2
  124. package/dist/flows/gate.d.ts +0 -1
  125. package/dist/flows/gate.js +0 -1
  126. package/dist/flows/git-changed.d.ts +0 -1
  127. package/dist/flows/git-changed.js +0 -1
  128. package/dist/flows/heal-run.d.ts +0 -1
  129. package/dist/flows/heal-run.js +0 -1
  130. package/dist/flows/heal.d.ts +0 -1
  131. package/dist/flows/heal.js +0 -1
  132. package/dist/flows/parallel-suite.d.ts +0 -1
  133. package/dist/flows/parallel-suite.js +0 -1
  134. package/dist/flows/recordings.d.ts +0 -1
  135. package/dist/flows/recordings.js +0 -1
  136. package/dist/flows/replay.d.ts +0 -1
  137. package/dist/flows/replay.js +71 -4
  138. package/dist/flows/server-verify.d.ts +0 -1
  139. package/dist/flows/server-verify.js +0 -1
  140. package/dist/flows/verify-change-tools.d.ts +2 -0
  141. package/dist/flows/verify-change-tools.js +187 -0
  142. package/dist/flows/watch-batcher.d.ts +0 -1
  143. package/dist/flows/watch-batcher.js +0 -1
  144. package/dist/honesty/accepted-write.d.ts +14 -0
  145. package/dist/honesty/accepted-write.js +17 -0
  146. package/dist/honesty/blind-spots.d.ts +18 -1
  147. package/dist/honesty/blind-spots.js +47 -5
  148. package/dist/honesty/honesty.d.ts +0 -1
  149. package/dist/honesty/honesty.js +0 -1
  150. package/dist/honesty/uncaptured-bodies.d.ts +19 -0
  151. package/dist/honesty/uncaptured-bodies.js +30 -0
  152. package/dist/honesty/unread-outcome.d.ts +2 -0
  153. package/dist/honesty/unread-outcome.js +50 -0
  154. package/dist/honesty/verified.d.ts +40 -0
  155. package/dist/honesty/verified.js +86 -0
  156. package/dist/http-server.d.ts +0 -1
  157. package/dist/http-server.js +5 -1
  158. package/dist/hunt/hunt-report.d.ts +50 -0
  159. package/dist/hunt/hunt-report.js +84 -0
  160. package/dist/idle-shutdown.d.ts +0 -1
  161. package/dist/idle-shutdown.js +0 -1
  162. package/dist/index.d.ts +0 -1
  163. package/dist/index.js +0 -1
  164. package/dist/init/agent-rules.d.ts +0 -1
  165. package/dist/init/agent-rules.js +4 -2
  166. package/dist/init/cursor.d.ts +0 -1
  167. package/dist/init/cursor.js +0 -1
  168. package/dist/init/desktop-doctor.d.ts +40 -0
  169. package/dist/init/desktop-doctor.js +198 -0
  170. package/dist/init/detect.d.ts +0 -1
  171. package/dist/init/detect.js +0 -1
  172. package/dist/init/mcp.d.ts +0 -1
  173. package/dist/init/mcp.js +0 -1
  174. package/dist/init/node-io.d.ts +0 -1
  175. package/dist/init/node-io.js +0 -1
  176. package/dist/init/plan.d.ts +4 -1
  177. package/dist/init/plan.js +23 -5
  178. package/dist/init/project-id.d.ts +0 -1
  179. package/dist/init/project-id.js +0 -1
  180. package/dist/init/run.d.ts +0 -1
  181. package/dist/init/run.js +31 -3
  182. package/dist/init/snippets.d.ts +5 -1
  183. package/dist/init/snippets.js +5 -1
  184. package/dist/init/vite-config.d.ts +0 -1
  185. package/dist/init/vite-config.js +0 -1
  186. package/dist/input/network-detail.d.ts +0 -1
  187. package/dist/input/network-detail.js +0 -1
  188. package/dist/input/network-mock-tools.d.ts +0 -1
  189. package/dist/input/network-mock-tools.js +3 -4
  190. package/dist/input/network-mock.d.ts +0 -1
  191. package/dist/input/network-mock.js +0 -1
  192. package/dist/input/real-input.d.ts +14 -1
  193. package/dist/input/real-input.js +45 -3
  194. package/dist/input/scroll-find.d.ts +0 -1
  195. package/dist/input/scroll-find.js +0 -1
  196. package/dist/input/scroll-tools.d.ts +0 -1
  197. package/dist/input/scroll-tools.js +0 -1
  198. package/dist/input/viewport-tools.d.ts +0 -1
  199. package/dist/input/viewport-tools.js +3 -4
  200. package/dist/journal/ambient-store.d.ts +0 -1
  201. package/dist/journal/ambient-store.js +0 -1
  202. package/dist/journal/ambient.d.ts +0 -1
  203. package/dist/journal/ambient.js +0 -1
  204. package/dist/journal/attach-journal.d.ts +0 -1
  205. package/dist/journal/attach-journal.js +0 -1
  206. package/dist/journal/deviation-report.d.ts +0 -1
  207. package/dist/journal/deviation-report.js +0 -1
  208. package/dist/journal/deviation-service.d.ts +0 -1
  209. package/dist/journal/deviation-service.js +0 -1
  210. package/dist/journal/envelope-store.d.ts +0 -1
  211. package/dist/journal/envelope-store.js +0 -1
  212. package/dist/journal/envelope.d.ts +8 -9
  213. package/dist/journal/envelope.js +0 -1
  214. package/dist/journal/journal-query.d.ts +0 -1
  215. package/dist/journal/journal-query.js +0 -1
  216. package/dist/journal/journal-recorder.d.ts +0 -1
  217. package/dist/journal/journal-recorder.js +0 -1
  218. package/dist/journal/retention.d.ts +0 -1
  219. package/dist/journal/retention.js +0 -1
  220. package/dist/journal/rollups.d.ts +0 -1
  221. package/dist/journal/rollups.js +0 -1
  222. package/dist/journal/session-end.d.ts +0 -1
  223. package/dist/journal/session-end.js +0 -1
  224. package/dist/journal/session-journal.d.ts +0 -1
  225. package/dist/journal/session-journal.js +0 -1
  226. package/dist/license/license.d.ts +0 -1
  227. package/dist/license/license.js +0 -1
  228. package/dist/log.d.ts +0 -1
  229. package/dist/log.js +0 -1
  230. package/dist/mcp-proxy.d.ts +0 -1
  231. package/dist/mcp-proxy.js +0 -1
  232. package/dist/mcp.d.ts +15 -1
  233. package/dist/mcp.js +145 -17
  234. package/dist/oracles/flow-instrument-gaps.d.ts +0 -1
  235. package/dist/oracles/flow-instrument-gaps.js +0 -1
  236. package/dist/oracles/propose-consequences.d.ts +0 -1
  237. package/dist/oracles/propose-consequences.js +0 -1
  238. package/dist/oracles/self-instrument.d.ts +0 -1
  239. package/dist/oracles/self-instrument.js +0 -1
  240. package/dist/pairing-token.d.ts +0 -1
  241. package/dist/pairing-token.js +0 -1
  242. package/dist/phenomena/phenomena.d.ts +0 -1
  243. package/dist/phenomena/phenomena.js +0 -1
  244. package/dist/pool/browser-pool.d.ts +0 -1
  245. package/dist/pool/browser-pool.js +0 -1
  246. package/dist/pool/lease-reaper.d.ts +0 -1
  247. package/dist/pool/lease-reaper.js +0 -1
  248. package/dist/pool/playwright-launcher.d.ts +0 -1
  249. package/dist/pool/playwright-launcher.js +10 -2
  250. package/dist/project/baselines.d.ts +0 -1
  251. package/dist/project/baselines.js +0 -1
  252. package/dist/project/file-lock.d.ts +2 -1
  253. package/dist/project/file-lock.js +12 -2
  254. package/dist/project/fs-port.d.ts +0 -1
  255. package/dist/project/fs-port.js +0 -1
  256. package/dist/project/project-store.d.ts +0 -1
  257. package/dist/project/project-store.js +0 -1
  258. package/dist/project/project-tools.d.ts +0 -1
  259. package/dist/project/project-tools.js +29 -4
  260. package/dist/project/reticle-dir.d.ts +0 -1
  261. package/dist/project/reticle-dir.js +0 -1
  262. package/dist/runs/build-verification-run.d.ts +0 -1
  263. package/dist/runs/build-verification-run.js +0 -1
  264. package/dist/runs/profile-redact.d.ts +0 -1
  265. package/dist/runs/profile-redact.js +0 -1
  266. package/dist/runs/render-report.d.ts +0 -1
  267. package/dist/runs/render-report.js +0 -1
  268. package/dist/runs/repair-prompt.d.ts +0 -1
  269. package/dist/runs/repair-prompt.js +0 -1
  270. package/dist/runs/replay-mapping.d.ts +0 -1
  271. package/dist/runs/replay-mapping.js +0 -1
  272. package/dist/runs/reticle-runner.d.ts +0 -1
  273. package/dist/runs/reticle-runner.js +4 -2
  274. package/dist/runs/risk-classify.d.ts +0 -1
  275. package/dist/runs/risk-classify.js +0 -1
  276. package/dist/runs/run-diff.d.ts +0 -1
  277. package/dist/runs/run-diff.js +0 -1
  278. package/dist/runs/run-store.d.ts +0 -1
  279. package/dist/runs/run-store.js +0 -1
  280. package/dist/runs/run-tools.d.ts +0 -1
  281. package/dist/runs/run-tools.js +0 -1
  282. package/dist/runs/runner-port.d.ts +0 -1
  283. package/dist/runs/runner-port.js +0 -1
  284. package/dist/runs/verification-sync.d.ts +0 -1
  285. package/dist/runs/verification-sync.js +0 -1
  286. package/dist/runs/verify-http.d.ts +0 -1
  287. package/dist/runs/verify-http.js +0 -1
  288. package/dist/runs/verify-server.d.ts +0 -1
  289. package/dist/runs/verify-server.js +0 -1
  290. package/dist/server-version.d.ts +0 -1
  291. package/dist/server-version.js +0 -1
  292. package/dist/session/command-timeout.d.ts +35 -0
  293. package/dist/session/command-timeout.js +41 -0
  294. package/dist/session/control-envelope.d.ts +2 -3
  295. package/dist/session/control-envelope.js +2 -3
  296. package/dist/session/last-act.d.ts +31 -0
  297. package/dist/session/last-act.js +24 -0
  298. package/dist/session/live-control-tools.d.ts +0 -1
  299. package/dist/session/live-control-tools.js +3 -4
  300. package/dist/session/live-control.d.ts +0 -1
  301. package/dist/session/live-control.js +0 -1
  302. package/dist/session/observed-state.d.ts +12 -2
  303. package/dist/session/observed-state.js +29 -2
  304. package/dist/session/output-budget.d.ts +0 -1
  305. package/dist/session/output-budget.js +0 -1
  306. package/dist/session/pending-commands.d.ts +12 -0
  307. package/dist/session/pending-commands.js +36 -0
  308. package/dist/session/presenter-args.d.ts +0 -1
  309. package/dist/session/presenter-args.js +0 -1
  310. package/dist/session/review-store.d.ts +0 -1
  311. package/dist/session/review-store.js +0 -1
  312. package/dist/session/session-health.d.ts +26 -2
  313. package/dist/session/session-health.js +13 -1
  314. package/dist/session/session-info.d.ts +29 -0
  315. package/dist/session/session-info.js +1 -0
  316. package/dist/session/session-lease.d.ts +25 -0
  317. package/dist/session/session-lease.js +14 -0
  318. package/dist/session/session-manager.d.ts +7 -19
  319. package/dist/session/session-manager.js +29 -2
  320. package/dist/session/session-readiness.d.ts +0 -1
  321. package/dist/session/session-readiness.js +3 -4
  322. package/dist/session/session-reaper.d.ts +0 -1
  323. package/dist/session/session-reaper.js +0 -1
  324. package/dist/session/session-recommendation.d.ts +0 -1
  325. package/dist/session/session-recommendation.js +0 -1
  326. package/dist/session/session-tools.d.ts +0 -1
  327. package/dist/session/session-tools.js +2 -3
  328. package/dist/session/session.d.ts +27 -53
  329. package/dist/session/session.js +95 -66
  330. package/dist/session/state-select.d.ts +0 -1
  331. package/dist/session/state-select.js +0 -1
  332. package/dist/telemetry/argument-shape.d.ts +41 -0
  333. package/dist/telemetry/argument-shape.js +87 -0
  334. package/dist/telemetry/bug-found.d.ts +33 -0
  335. package/dist/telemetry/bug-found.js +95 -0
  336. package/dist/telemetry/cli-telemetry.d.ts +13 -0
  337. package/dist/telemetry/cli-telemetry.js +43 -0
  338. package/dist/telemetry/connect-failure.d.ts +16 -0
  339. package/dist/telemetry/connect-failure.js +44 -0
  340. package/dist/telemetry/daemon-telemetry.d.ts +19 -0
  341. package/dist/telemetry/daemon-telemetry.js +76 -0
  342. package/dist/telemetry/dev-repo.d.ts +10 -0
  343. package/dist/telemetry/dev-repo.js +80 -0
  344. package/dist/telemetry/error-fingerprint.d.ts +24 -0
  345. package/dist/telemetry/error-fingerprint.js +88 -0
  346. package/dist/telemetry/feedback-cli.d.ts +31 -0
  347. package/dist/telemetry/feedback-cli.js +102 -0
  348. package/dist/telemetry/feedback-context.d.ts +32 -0
  349. package/dist/telemetry/feedback-context.js +143 -0
  350. package/dist/telemetry/feedback.d.ts +66 -0
  351. package/dist/telemetry/feedback.js +175 -0
  352. package/dist/telemetry/git-facts.d.ts +21 -0
  353. package/dist/telemetry/git-facts.js +109 -0
  354. package/dist/telemetry/identify.d.ts +22 -0
  355. package/dist/telemetry/identify.js +73 -0
  356. package/dist/telemetry/init-telemetry.d.ts +26 -0
  357. package/dist/telemetry/init-telemetry.js +33 -0
  358. package/dist/telemetry/machine-snapshot.d.ts +6 -0
  359. package/dist/telemetry/machine-snapshot.js +39 -0
  360. package/dist/telemetry/mcp-connection.d.ts +5 -0
  361. package/dist/telemetry/mcp-connection.js +44 -0
  362. package/dist/telemetry/project-profile.d.ts +44 -0
  363. package/dist/telemetry/project-profile.js +205 -0
  364. package/dist/telemetry/run-telemetry.d.ts +21 -0
  365. package/dist/telemetry/run-telemetry.js +62 -0
  366. package/dist/telemetry/session-metrics.d.ts +103 -0
  367. package/dist/telemetry/session-metrics.js +329 -0
  368. package/dist/telemetry/telemetry.d.ts +35 -8
  369. package/dist/telemetry/telemetry.js +105 -12
  370. package/dist/token-auth.d.ts +0 -1
  371. package/dist/token-auth.js +0 -1
  372. package/dist/tools/act-capsule.d.ts +23 -0
  373. package/dist/tools/act-capsule.js +47 -0
  374. package/dist/tools/act-danger.d.ts +7 -0
  375. package/dist/tools/act-danger.js +44 -0
  376. package/dist/tools/act-helpers.d.ts +17 -0
  377. package/dist/tools/act-helpers.js +40 -0
  378. package/dist/tools/act-tools.d.ts +8 -1
  379. package/dist/tools/act-tools.js +96 -98
  380. package/dist/tools/act-view.d.ts +7 -1
  381. package/dist/tools/act-view.js +13 -1
  382. package/dist/tools/assert-grade.d.ts +22 -1
  383. package/dist/tools/assert-grade.js +46 -1
  384. package/dist/tools/assert-verdict.d.ts +21 -0
  385. package/dist/tools/assert-verdict.js +62 -0
  386. package/dist/tools/browser-tools.d.ts +0 -1
  387. package/dist/tools/browser-tools.js +2 -2
  388. package/dist/tools/contract-tools.d.ts +0 -1
  389. package/dist/tools/contract-tools.js +0 -1
  390. package/dist/tools/coverage-tools.d.ts +9 -0
  391. package/dist/tools/coverage-tools.js +92 -0
  392. package/dist/tools/dynamic-tools.d.ts +0 -1
  393. package/dist/tools/dynamic-tools.js +21 -2
  394. package/dist/tools/error-recovery.d.ts +18 -2
  395. package/dist/tools/error-recovery.js +42 -7
  396. package/dist/tools/feedback-tools.d.ts +24 -0
  397. package/dist/tools/feedback-tools.js +180 -0
  398. package/dist/tools/invoke-tool.d.ts +0 -1
  399. package/dist/tools/invoke-tool.js +115 -5
  400. package/dist/tools/lease-tools.d.ts +0 -1
  401. package/dist/tools/lease-tools.js +6 -5
  402. package/dist/tools/merge-tools.d.ts +0 -1
  403. package/dist/tools/merge-tools.js +0 -1
  404. package/dist/tools/observe-tools.d.ts +0 -1
  405. package/dist/tools/observe-tools.js +91 -39
  406. package/dist/tools/profiles.d.ts +1 -2
  407. package/dist/tools/profiles.js +43 -16
  408. package/dist/tools/query-paginate.d.ts +0 -1
  409. package/dist/tools/query-paginate.js +0 -1
  410. package/dist/tools/read-tools.d.ts +0 -1
  411. package/dist/tools/read-tools.js +10 -8
  412. package/dist/tools/reconcile-tools.d.ts +2 -0
  413. package/dist/tools/reconcile-tools.js +111 -0
  414. package/dist/tools/snapshot-delta.d.ts +0 -1
  415. package/dist/tools/snapshot-delta.js +0 -0
  416. package/dist/tools/tool-invoker.d.ts +0 -1
  417. package/dist/tools/tool-invoker.js +0 -1
  418. package/dist/tools/tool-kit.d.ts +16 -1
  419. package/dist/tools/tool-kit.js +8 -2
  420. package/dist/tools/tool-names.d.ts +6 -1
  421. package/dist/tools/tool-names.js +6 -1
  422. package/dist/tools/tools-helpers.d.ts +0 -1
  423. package/dist/tools/tools-helpers.js +0 -1
  424. package/dist/tools/tools.d.ts +0 -1
  425. package/dist/tools/tools.js +24 -4
  426. package/dist/update/update-checker.d.ts +0 -1
  427. package/dist/update/update-checker.js +0 -1
  428. package/dist/update/update-nudge.d.ts +20 -0
  429. package/dist/update/update-nudge.js +72 -0
  430. package/dist/update/updater.d.ts +14 -1
  431. package/dist/update/updater.js +33 -2
  432. package/dist/visual/visual-diff.d.ts +0 -1
  433. package/dist/visual/visual-diff.js +0 -1
  434. package/dist/visual/visual-store.d.ts +0 -1
  435. package/dist/visual/visual-store.js +0 -1
  436. package/dist/visual/visual-tools.d.ts +0 -1
  437. package/dist/visual/visual-tools.js +103 -16
  438. package/package.json +2 -2
  439. package/dist/bridge-security.d.ts.map +0 -1
  440. package/dist/bridge-security.js.map +0 -1
  441. package/dist/bridge.d.ts.map +0 -1
  442. package/dist/bridge.js.map +0 -1
  443. package/dist/bridge.test-harness.d.ts.map +0 -1
  444. package/dist/bridge.test-harness.js.map +0 -1
  445. package/dist/capsule/capsule-store.d.ts.map +0 -1
  446. package/dist/capsule/capsule-store.js.map +0 -1
  447. package/dist/capsule/capsule.d.ts.map +0 -1
  448. package/dist/capsule/capsule.js.map +0 -1
  449. package/dist/capsule/causal-summary.d.ts.map +0 -1
  450. package/dist/capsule/causal-summary.js.map +0 -1
  451. package/dist/capsule/divergence.d.ts.map +0 -1
  452. package/dist/capsule/divergence.js.map +0 -1
  453. package/dist/capsule/minimize.d.ts.map +0 -1
  454. package/dist/capsule/minimize.js.map +0 -1
  455. package/dist/capsule/predicate-to-links.d.ts.map +0 -1
  456. package/dist/capsule/predicate-to-links.js.map +0 -1
  457. package/dist/cli-flow-commands.d.ts.map +0 -1
  458. package/dist/cli-flow-commands.js.map +0 -1
  459. package/dist/cli-launch.d.ts.map +0 -1
  460. package/dist/cli-launch.js.map +0 -1
  461. package/dist/cli-parse.d.ts.map +0 -1
  462. package/dist/cli-parse.js.map +0 -1
  463. package/dist/cli-port.d.ts.map +0 -1
  464. package/dist/cli-port.js.map +0 -1
  465. package/dist/cli-verify.d.ts.map +0 -1
  466. package/dist/cli-verify.js.map +0 -1
  467. package/dist/cli.d.ts.map +0 -1
  468. package/dist/cli.js.map +0 -1
  469. package/dist/cloud/cloud-config.d.ts.map +0 -1
  470. package/dist/cloud/cloud-config.js.map +0 -1
  471. package/dist/cloud/cloud-sync.d.ts.map +0 -1
  472. package/dist/cloud/cloud-sync.js.map +0 -1
  473. package/dist/cloud-cli.d.ts.map +0 -1
  474. package/dist/cloud-cli.js.map +0 -1
  475. package/dist/crawl/crawl-tools.d.ts.map +0 -1
  476. package/dist/crawl/crawl-tools.js.map +0 -1
  477. package/dist/crawl/crawl.d.ts.map +0 -1
  478. package/dist/crawl/crawl.js.map +0 -1
  479. package/dist/daemon-resilience.d.ts.map +0 -1
  480. package/dist/daemon-resilience.js.map +0 -1
  481. package/dist/daemon.d.ts.map +0 -1
  482. package/dist/daemon.js.map +0 -1
  483. package/dist/domain/domain-model.d.ts.map +0 -1
  484. package/dist/domain/domain-model.js.map +0 -1
  485. package/dist/domain/domain-tools.d.ts.map +0 -1
  486. package/dist/domain/domain-tools.js.map +0 -1
  487. package/dist/domain/flow-risk.d.ts.map +0 -1
  488. package/dist/domain/flow-risk.js.map +0 -1
  489. package/dist/ee/audit-log.d.ts.map +0 -1
  490. package/dist/ee/audit-log.js.map +0 -1
  491. package/dist/events/event-filters.d.ts.map +0 -1
  492. package/dist/events/event-filters.js.map +0 -1
  493. package/dist/events/predicate-eval.d.ts.map +0 -1
  494. package/dist/events/predicate-eval.js.map +0 -1
  495. package/dist/events/predicate.d.ts.map +0 -1
  496. package/dist/events/predicate.js.map +0 -1
  497. package/dist/events/reaction.d.ts.map +0 -1
  498. package/dist/events/reaction.js.map +0 -1
  499. package/dist/events/ring-buffer.d.ts.map +0 -1
  500. package/dist/events/ring-buffer.js.map +0 -1
  501. package/dist/flows/affected.d.ts.map +0 -1
  502. package/dist/flows/affected.js.map +0 -1
  503. package/dist/flows/annotate-tools.d.ts.map +0 -1
  504. package/dist/flows/annotate-tools.js.map +0 -1
  505. package/dist/flows/annotate.d.ts.map +0 -1
  506. package/dist/flows/annotate.js.map +0 -1
  507. package/dist/flows/annotation-store.d.ts.map +0 -1
  508. package/dist/flows/annotation-store.js.map +0 -1
  509. package/dist/flows/assertion-integrity.d.ts.map +0 -1
  510. package/dist/flows/assertion-integrity.js.map +0 -1
  511. package/dist/flows/assertion-tiers-store.d.ts.map +0 -1
  512. package/dist/flows/assertion-tiers-store.js.map +0 -1
  513. package/dist/flows/buddy-status.d.ts.map +0 -1
  514. package/dist/flows/buddy-status.js.map +0 -1
  515. package/dist/flows/coverage.d.ts.map +0 -1
  516. package/dist/flows/coverage.js.map +0 -1
  517. package/dist/flows/decision.d.ts.map +0 -1
  518. package/dist/flows/decision.js.map +0 -1
  519. package/dist/flows/flake-store.d.ts.map +0 -1
  520. package/dist/flows/flake-store.js.map +0 -1
  521. package/dist/flows/flake.d.ts.map +0 -1
  522. package/dist/flows/flake.js.map +0 -1
  523. package/dist/flows/flow-classify.d.ts.map +0 -1
  524. package/dist/flows/flow-classify.js.map +0 -1
  525. package/dist/flows/flow-replay-run.d.ts.map +0 -1
  526. package/dist/flows/flow-replay-run.js.map +0 -1
  527. package/dist/flows/flow-replay.d.ts.map +0 -1
  528. package/dist/flows/flow-replay.js.map +0 -1
  529. package/dist/flows/flow-report.d.ts.map +0 -1
  530. package/dist/flows/flow-report.js.map +0 -1
  531. package/dist/flows/flow-scope.d.ts.map +0 -1
  532. package/dist/flows/flow-scope.js.map +0 -1
  533. package/dist/flows/flow-sources.d.ts.map +0 -1
  534. package/dist/flows/flow-sources.js.map +0 -1
  535. package/dist/flows/flow-success.d.ts.map +0 -1
  536. package/dist/flows/flow-success.js.map +0 -1
  537. package/dist/flows/flow-tools.d.ts.map +0 -1
  538. package/dist/flows/flow-tools.js.map +0 -1
  539. package/dist/flows/flows.d.ts.map +0 -1
  540. package/dist/flows/flows.js.map +0 -1
  541. package/dist/flows/gate.d.ts.map +0 -1
  542. package/dist/flows/gate.js.map +0 -1
  543. package/dist/flows/git-changed.d.ts.map +0 -1
  544. package/dist/flows/git-changed.js.map +0 -1
  545. package/dist/flows/heal-run.d.ts.map +0 -1
  546. package/dist/flows/heal-run.js.map +0 -1
  547. package/dist/flows/heal.d.ts.map +0 -1
  548. package/dist/flows/heal.js.map +0 -1
  549. package/dist/flows/parallel-suite.d.ts.map +0 -1
  550. package/dist/flows/parallel-suite.js.map +0 -1
  551. package/dist/flows/recordings.d.ts.map +0 -1
  552. package/dist/flows/recordings.js.map +0 -1
  553. package/dist/flows/replay.d.ts.map +0 -1
  554. package/dist/flows/replay.js.map +0 -1
  555. package/dist/flows/server-verify.d.ts.map +0 -1
  556. package/dist/flows/server-verify.js.map +0 -1
  557. package/dist/flows/watch-batcher.d.ts.map +0 -1
  558. package/dist/flows/watch-batcher.js.map +0 -1
  559. package/dist/honesty/blind-spots.d.ts.map +0 -1
  560. package/dist/honesty/blind-spots.js.map +0 -1
  561. package/dist/honesty/honesty.d.ts.map +0 -1
  562. package/dist/honesty/honesty.js.map +0 -1
  563. package/dist/http-server.d.ts.map +0 -1
  564. package/dist/http-server.js.map +0 -1
  565. package/dist/idle-shutdown.d.ts.map +0 -1
  566. package/dist/idle-shutdown.js.map +0 -1
  567. package/dist/index.d.ts.map +0 -1
  568. package/dist/index.js.map +0 -1
  569. package/dist/init/agent-rules.d.ts.map +0 -1
  570. package/dist/init/agent-rules.js.map +0 -1
  571. package/dist/init/cursor.d.ts.map +0 -1
  572. package/dist/init/cursor.js.map +0 -1
  573. package/dist/init/detect.d.ts.map +0 -1
  574. package/dist/init/detect.js.map +0 -1
  575. package/dist/init/mcp.d.ts.map +0 -1
  576. package/dist/init/mcp.js.map +0 -1
  577. package/dist/init/node-io.d.ts.map +0 -1
  578. package/dist/init/node-io.js.map +0 -1
  579. package/dist/init/plan.d.ts.map +0 -1
  580. package/dist/init/plan.js.map +0 -1
  581. package/dist/init/project-id.d.ts.map +0 -1
  582. package/dist/init/project-id.js.map +0 -1
  583. package/dist/init/run.d.ts.map +0 -1
  584. package/dist/init/run.js.map +0 -1
  585. package/dist/init/snippets.d.ts.map +0 -1
  586. package/dist/init/snippets.js.map +0 -1
  587. package/dist/init/vite-config.d.ts.map +0 -1
  588. package/dist/init/vite-config.js.map +0 -1
  589. package/dist/input/network-detail.d.ts.map +0 -1
  590. package/dist/input/network-detail.js.map +0 -1
  591. package/dist/input/network-mock-tools.d.ts.map +0 -1
  592. package/dist/input/network-mock-tools.js.map +0 -1
  593. package/dist/input/network-mock.d.ts.map +0 -1
  594. package/dist/input/network-mock.js.map +0 -1
  595. package/dist/input/real-input.d.ts.map +0 -1
  596. package/dist/input/real-input.js.map +0 -1
  597. package/dist/input/scroll-find.d.ts.map +0 -1
  598. package/dist/input/scroll-find.js.map +0 -1
  599. package/dist/input/scroll-tools.d.ts.map +0 -1
  600. package/dist/input/scroll-tools.js.map +0 -1
  601. package/dist/input/viewport-tools.d.ts.map +0 -1
  602. package/dist/input/viewport-tools.js.map +0 -1
  603. package/dist/journal/ambient-store.d.ts.map +0 -1
  604. package/dist/journal/ambient-store.js.map +0 -1
  605. package/dist/journal/ambient.d.ts.map +0 -1
  606. package/dist/journal/ambient.js.map +0 -1
  607. package/dist/journal/attach-journal.d.ts.map +0 -1
  608. package/dist/journal/attach-journal.js.map +0 -1
  609. package/dist/journal/deviation-report.d.ts.map +0 -1
  610. package/dist/journal/deviation-report.js.map +0 -1
  611. package/dist/journal/deviation-service.d.ts.map +0 -1
  612. package/dist/journal/deviation-service.js.map +0 -1
  613. package/dist/journal/envelope-store.d.ts.map +0 -1
  614. package/dist/journal/envelope-store.js.map +0 -1
  615. package/dist/journal/envelope.d.ts.map +0 -1
  616. package/dist/journal/envelope.js.map +0 -1
  617. package/dist/journal/journal-query.d.ts.map +0 -1
  618. package/dist/journal/journal-query.js.map +0 -1
  619. package/dist/journal/journal-recorder.d.ts.map +0 -1
  620. package/dist/journal/journal-recorder.js.map +0 -1
  621. package/dist/journal/retention.d.ts.map +0 -1
  622. package/dist/journal/retention.js.map +0 -1
  623. package/dist/journal/rollups.d.ts.map +0 -1
  624. package/dist/journal/rollups.js.map +0 -1
  625. package/dist/journal/session-end.d.ts.map +0 -1
  626. package/dist/journal/session-end.js.map +0 -1
  627. package/dist/journal/session-journal.d.ts.map +0 -1
  628. package/dist/journal/session-journal.js.map +0 -1
  629. package/dist/license/license.d.ts.map +0 -1
  630. package/dist/license/license.js.map +0 -1
  631. package/dist/log.d.ts.map +0 -1
  632. package/dist/log.js.map +0 -1
  633. package/dist/mcp-proxy.d.ts.map +0 -1
  634. package/dist/mcp-proxy.js.map +0 -1
  635. package/dist/mcp.d.ts.map +0 -1
  636. package/dist/mcp.js.map +0 -1
  637. package/dist/oracles/flow-instrument-gaps.d.ts.map +0 -1
  638. package/dist/oracles/flow-instrument-gaps.js.map +0 -1
  639. package/dist/oracles/propose-consequences.d.ts.map +0 -1
  640. package/dist/oracles/propose-consequences.js.map +0 -1
  641. package/dist/oracles/self-instrument.d.ts.map +0 -1
  642. package/dist/oracles/self-instrument.js.map +0 -1
  643. package/dist/pairing-token.d.ts.map +0 -1
  644. package/dist/pairing-token.js.map +0 -1
  645. package/dist/phenomena/phenomena.d.ts.map +0 -1
  646. package/dist/phenomena/phenomena.js.map +0 -1
  647. package/dist/pool/browser-pool.d.ts.map +0 -1
  648. package/dist/pool/browser-pool.js.map +0 -1
  649. package/dist/pool/lease-reaper.d.ts.map +0 -1
  650. package/dist/pool/lease-reaper.js.map +0 -1
  651. package/dist/pool/playwright-launcher.d.ts.map +0 -1
  652. package/dist/pool/playwright-launcher.js.map +0 -1
  653. package/dist/project/baselines.d.ts.map +0 -1
  654. package/dist/project/baselines.js.map +0 -1
  655. package/dist/project/file-lock.d.ts.map +0 -1
  656. package/dist/project/file-lock.js.map +0 -1
  657. package/dist/project/fs-port.d.ts.map +0 -1
  658. package/dist/project/fs-port.js.map +0 -1
  659. package/dist/project/project-store.d.ts.map +0 -1
  660. package/dist/project/project-store.js.map +0 -1
  661. package/dist/project/project-tools.d.ts.map +0 -1
  662. package/dist/project/project-tools.js.map +0 -1
  663. package/dist/project/reticle-dir.d.ts.map +0 -1
  664. package/dist/project/reticle-dir.js.map +0 -1
  665. package/dist/runs/build-verification-run.d.ts.map +0 -1
  666. package/dist/runs/build-verification-run.js.map +0 -1
  667. package/dist/runs/profile-redact.d.ts.map +0 -1
  668. package/dist/runs/profile-redact.js.map +0 -1
  669. package/dist/runs/render-report.d.ts.map +0 -1
  670. package/dist/runs/render-report.js.map +0 -1
  671. package/dist/runs/repair-prompt.d.ts.map +0 -1
  672. package/dist/runs/repair-prompt.js.map +0 -1
  673. package/dist/runs/replay-mapping.d.ts.map +0 -1
  674. package/dist/runs/replay-mapping.js.map +0 -1
  675. package/dist/runs/reticle-runner.d.ts.map +0 -1
  676. package/dist/runs/reticle-runner.js.map +0 -1
  677. package/dist/runs/risk-classify.d.ts.map +0 -1
  678. package/dist/runs/risk-classify.js.map +0 -1
  679. package/dist/runs/run-diff.d.ts.map +0 -1
  680. package/dist/runs/run-diff.js.map +0 -1
  681. package/dist/runs/run-store.d.ts.map +0 -1
  682. package/dist/runs/run-store.js.map +0 -1
  683. package/dist/runs/run-tools.d.ts.map +0 -1
  684. package/dist/runs/run-tools.js.map +0 -1
  685. package/dist/runs/runner-port.d.ts.map +0 -1
  686. package/dist/runs/runner-port.js.map +0 -1
  687. package/dist/runs/verification-sync.d.ts.map +0 -1
  688. package/dist/runs/verification-sync.js.map +0 -1
  689. package/dist/runs/verify-http.d.ts.map +0 -1
  690. package/dist/runs/verify-http.js.map +0 -1
  691. package/dist/runs/verify-server.d.ts.map +0 -1
  692. package/dist/runs/verify-server.js.map +0 -1
  693. package/dist/server-version.d.ts.map +0 -1
  694. package/dist/server-version.js.map +0 -1
  695. package/dist/session/control-envelope.d.ts.map +0 -1
  696. package/dist/session/control-envelope.js.map +0 -1
  697. package/dist/session/live-control-tools.d.ts.map +0 -1
  698. package/dist/session/live-control-tools.js.map +0 -1
  699. package/dist/session/live-control.d.ts.map +0 -1
  700. package/dist/session/live-control.js.map +0 -1
  701. package/dist/session/observed-state.d.ts.map +0 -1
  702. package/dist/session/observed-state.js.map +0 -1
  703. package/dist/session/output-budget.d.ts.map +0 -1
  704. package/dist/session/output-budget.js.map +0 -1
  705. package/dist/session/presenter-args.d.ts.map +0 -1
  706. package/dist/session/presenter-args.js.map +0 -1
  707. package/dist/session/review-store.d.ts.map +0 -1
  708. package/dist/session/review-store.js.map +0 -1
  709. package/dist/session/session-health.d.ts.map +0 -1
  710. package/dist/session/session-health.js.map +0 -1
  711. package/dist/session/session-manager.d.ts.map +0 -1
  712. package/dist/session/session-manager.js.map +0 -1
  713. package/dist/session/session-readiness.d.ts.map +0 -1
  714. package/dist/session/session-readiness.js.map +0 -1
  715. package/dist/session/session-reaper.d.ts.map +0 -1
  716. package/dist/session/session-reaper.js.map +0 -1
  717. package/dist/session/session-recommendation.d.ts.map +0 -1
  718. package/dist/session/session-recommendation.js.map +0 -1
  719. package/dist/session/session-tools.d.ts.map +0 -1
  720. package/dist/session/session-tools.js.map +0 -1
  721. package/dist/session/session.d.ts.map +0 -1
  722. package/dist/session/session.js.map +0 -1
  723. package/dist/session/state-select.d.ts.map +0 -1
  724. package/dist/session/state-select.js.map +0 -1
  725. package/dist/telemetry/telemetry.d.ts.map +0 -1
  726. package/dist/telemetry/telemetry.js.map +0 -1
  727. package/dist/token-auth.d.ts.map +0 -1
  728. package/dist/token-auth.js.map +0 -1
  729. package/dist/tools/act-tools.d.ts.map +0 -1
  730. package/dist/tools/act-tools.js.map +0 -1
  731. package/dist/tools/act-view.d.ts.map +0 -1
  732. package/dist/tools/act-view.js.map +0 -1
  733. package/dist/tools/assert-grade.d.ts.map +0 -1
  734. package/dist/tools/assert-grade.js.map +0 -1
  735. package/dist/tools/browser-tools.d.ts.map +0 -1
  736. package/dist/tools/browser-tools.js.map +0 -1
  737. package/dist/tools/contract-tools.d.ts.map +0 -1
  738. package/dist/tools/contract-tools.js.map +0 -1
  739. package/dist/tools/dynamic-tools.d.ts.map +0 -1
  740. package/dist/tools/dynamic-tools.js.map +0 -1
  741. package/dist/tools/error-recovery.d.ts.map +0 -1
  742. package/dist/tools/error-recovery.js.map +0 -1
  743. package/dist/tools/invoke-tool.d.ts.map +0 -1
  744. package/dist/tools/invoke-tool.js.map +0 -1
  745. package/dist/tools/lease-tools.d.ts.map +0 -1
  746. package/dist/tools/lease-tools.js.map +0 -1
  747. package/dist/tools/merge-tools.d.ts.map +0 -1
  748. package/dist/tools/merge-tools.js.map +0 -1
  749. package/dist/tools/observe-tools.d.ts.map +0 -1
  750. package/dist/tools/observe-tools.js.map +0 -1
  751. package/dist/tools/profiles.d.ts.map +0 -1
  752. package/dist/tools/profiles.js.map +0 -1
  753. package/dist/tools/query-paginate.d.ts.map +0 -1
  754. package/dist/tools/query-paginate.js.map +0 -1
  755. package/dist/tools/read-tools.d.ts.map +0 -1
  756. package/dist/tools/read-tools.js.map +0 -1
  757. package/dist/tools/snapshot-delta.d.ts.map +0 -1
  758. package/dist/tools/snapshot-delta.js.map +0 -1
  759. package/dist/tools/tool-invoker.d.ts.map +0 -1
  760. package/dist/tools/tool-invoker.js.map +0 -1
  761. package/dist/tools/tool-kit.d.ts.map +0 -1
  762. package/dist/tools/tool-kit.js.map +0 -1
  763. package/dist/tools/tool-names.d.ts.map +0 -1
  764. package/dist/tools/tool-names.js.map +0 -1
  765. package/dist/tools/tools-helpers.d.ts.map +0 -1
  766. package/dist/tools/tools-helpers.js.map +0 -1
  767. package/dist/tools/tools.d.ts.map +0 -1
  768. package/dist/tools/tools.js.map +0 -1
  769. package/dist/update/update-checker.d.ts.map +0 -1
  770. package/dist/update/update-checker.js.map +0 -1
  771. package/dist/update/updater.d.ts.map +0 -1
  772. package/dist/update/updater.js.map +0 -1
  773. package/dist/visual/visual-diff.d.ts.map +0 -1
  774. package/dist/visual/visual-diff.js.map +0 -1
  775. package/dist/visual/visual-store.d.ts.map +0 -1
  776. package/dist/visual/visual-store.js.map +0 -1
  777. package/dist/visual/visual-tools.d.ts.map +0 -1
  778. package/dist/visual/visual-tools.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ import { z } from 'zod';
2
+ import { EventType, ReticleCommand, SnapshotMode } from '@reticlehq/core';
3
+ import { ReticleTool } from './tool-names.js';
4
+ import { reconcile } from '../events/reconcile.js';
5
+ import { salvageJson } from '../events/json-salvage.js';
6
+ import { withControl } from '../session/control-envelope.js';
7
+ import { asNumber, asString } from './tools-helpers.js';
8
+ import { sessionIdShape, commandOrThrow } from './tool-kit.js';
9
+ /**
10
+ * Does the screen agree with the data the app was given?
11
+ *
12
+ * A separate tool rather than a passive contradiction rule, because it needs the rendered page as
13
+ * well as the events — a comparison, not an observation. Passive rules stay pure and run on every
14
+ * window; this one costs a snapshot, so the agent asks for it.
15
+ *
16
+ * It exists because the misses that mattered on a real payments dashboard were all this shape: a USD
17
+ * amount rendered with a rupee sign, a settlement the API calls `on_hold` rendered as "pending". No
18
+ * request fails, no assertion fails, and the numbers on screen match the numbers in the payload. The
19
+ * only thing that disagrees is the meaning.
20
+ */
21
+ /** Response bodies captured in the window, newest last. Only JSON is worth comparing. */
22
+ async function capturedBodies(session, since, urlContains) {
23
+ const events = (await session.queryEvents({ since }));
24
+ const bodies = [];
25
+ let withBody = 0;
26
+ let total = 0;
27
+ let truncated = 0;
28
+ for (const event of events) {
29
+ if (event.type !== EventType.NET_REQUEST)
30
+ continue;
31
+ const url = typeof event.data['url'] === 'string' ? event.data['url'] : '';
32
+ if (urlContains !== undefined && !url.includes(urlContains))
33
+ continue;
34
+ total += 1;
35
+ const raw = event.data['responseBody'];
36
+ if (typeof raw !== 'string' || raw.length === 0)
37
+ continue;
38
+ // A capped body is not an absent one. Recover the records that closed before the cut rather than
39
+ // reporting nothing about the page with the most data on it.
40
+ const salvaged = salvageJson(raw);
41
+ if (salvaged.values.length === 0)
42
+ continue;
43
+ bodies.push(...salvaged.values);
44
+ withBody += 1;
45
+ if (salvaged.partial)
46
+ truncated += 1;
47
+ }
48
+ return { bodies, withBody, total, truncated };
49
+ }
50
+ export const RECONCILE_TOOLS = [
51
+ {
52
+ name: ReticleTool.RECONCILE,
53
+ example: { urlContains: '/api/v1/settlements' },
54
+ description: 'Compare what the API returned against what the page RENDERS. Catches the class no status code and no assertion can: a USD amount shown with a ₹ sign, a record the API calls `on_hold` displayed as "pending". Needs response bodies — enable `captureNetworkBodies` — and says so when they are missing rather than reporting a clean result over data it never read.',
55
+ inputSchema: {
56
+ ...sessionIdShape,
57
+ since: z
58
+ .number()
59
+ .optional()
60
+ .describe('Cursor from a prior act — scopes to responses received after it. Default: 0.'),
61
+ urlContains: z
62
+ .string()
63
+ .optional()
64
+ .describe('Only compare responses from URLs containing this, e.g. "/api/v1/settlements".'),
65
+ },
66
+ outputSchema: {
67
+ mismatches: z
68
+ .array(z.object({ entity: z.string(), field: z.string(), api: z.string() }).passthrough())
69
+ .describe('Fields whose rendering disagrees with the data the app was given.'),
70
+ compared: z.number().describe('How many responses carried a body that could be compared.'),
71
+ note: z
72
+ .string()
73
+ .optional()
74
+ .describe('Present when nothing could be compared — never silent about an empty check.'),
75
+ },
76
+ handler: async (deps, args) => {
77
+ const session = deps.sessions.resolve(asString(args['sessionId']));
78
+ const since = asNumber(args['since']) ?? 0;
79
+ const { bodies, withBody, total, truncated } = await capturedBodies(session, since, asString(args['urlContains']));
80
+ // An empty result over data that was never read is the exact false green this tool exists to
81
+ // prevent, so the two cases are reported differently and neither is silent.
82
+ if (bodies.length === 0) {
83
+ return withControl(session, {
84
+ mismatches: [],
85
+ compared: 0,
86
+ note: total === 0
87
+ ? 'no responses in this window matched — nothing was compared'
88
+ : `${String(total)} response(s) matched but NONE carried a recorded body, so nothing was compared. Enable it where your app calls connect(): \`reticle.connect({ captureNetworkBodies: true })\`, then re-run`,
89
+ });
90
+ }
91
+ const snapshot = await commandOrThrow(deps, session.id, ReticleCommand.SNAPSHOT, {
92
+ mode: SnapshotMode.FULL,
93
+ });
94
+ const tree = snapshot.tree;
95
+ const mismatches = reconcile(bodies, typeof tree === 'string' ? tree : '');
96
+ // A truncated body is declared whether or not anything was found in it: "no mismatches" over a
97
+ // partially-read payload is a weaker statement than over a whole one, and the difference is
98
+ // exactly the kind of omission this layer exists to refuse.
99
+ const partial = truncated > 0
100
+ ? {
101
+ note: `${String(truncated)} of ${String(withBody)} response(s) exceeded the body cap and were read only up to the cut — records after it were not compared`,
102
+ }
103
+ : mismatches.length === 0
104
+ ? {
105
+ note: `compared ${String(withBody)} response(s); nothing on screen contradicts them`,
106
+ }
107
+ : {};
108
+ return withControl(session, { mismatches, compared: withBody, ...partial });
109
+ },
110
+ },
111
+ ];
@@ -58,4 +58,3 @@ export interface SnapshotDeltaOpts {
58
58
  * the pure `snapshotDelta`.
59
59
  */
60
60
  export declare function applySnapshotDelta(raw: unknown, opts: SnapshotDeltaOpts, cache: SnapshotCache): unknown;
61
- //# sourceMappingURL=snapshot-delta.d.ts.map
Binary file
@@ -12,4 +12,3 @@ export type ToolInvoker = (toolName: string, args: Record<string, unknown>) => P
12
12
  * (the MCP `{ isError, content }` envelope is a transport concern this layer deliberately skips).
13
13
  */
14
14
  export declare function createToolInvoker(deps: ToolDeps): ToolInvoker;
15
- //# sourceMappingURL=tool-invoker.d.ts.map
@@ -17,4 +17,3 @@ export function createToolInvoker(deps) {
17
17
  return runTool(tool, deps, args);
18
18
  };
19
19
  }
20
- //# sourceMappingURL=tool-invoker.js.map
@@ -46,6 +46,22 @@ export interface ToolDef {
46
46
  * compose tool calls safely. Also drives TOON encoding for snapshot/query results.
47
47
  */
48
48
  outputSchema?: z.ZodRawShape;
49
+ /**
50
+ * One concrete, valid call — the shape, not the prose.
51
+ *
52
+ * A schema tells an agent the FIELD NAMES; it does not tell it how they compose, and under a lean
53
+ * profile only the first sentence of the description survives. So an agent reads "execute one
54
+ * action against a ref", sees `ref` / `action` / `args`, and guesses `{ action, testid }`. The
55
+ * guess fails inside the MCP SDK's own validation — BEFORE this package's error handling runs — so
56
+ * what comes back is a raw zod dump: the validator's internal state, naming no field and showing
57
+ * no correct shape. Two of those round trips cost more than the lean snapshot saves, which means
58
+ * arg-guessing quietly refunds the entire token advantage.
59
+ *
60
+ * Rendered into the advertised description, so it survives the terse profiles where it matters
61
+ * most. `tool-examples.test.ts` parses every one of these against its OWN inputSchema, because an
62
+ * example that does not validate is worse than none at all.
63
+ */
64
+ example?: Record<string, unknown>;
49
65
  handler: (deps: ToolDeps, args: Record<string, unknown>) => Promise<unknown>;
50
66
  }
51
67
  export declare const sessionIdShape: {
@@ -66,4 +82,3 @@ export declare function snapshotTree(deps: ToolDeps, sessionId: string | undefin
66
82
  lines: string[];
67
83
  route: string;
68
84
  }>;
69
- //# sourceMappingURL=tool-kit.d.ts.map
@@ -11,7 +11,7 @@ export const sessionIdShape = {
11
11
  sessionId: z
12
12
  .string()
13
13
  .optional()
14
- .describe('Active session ID from reticle_sessions. Omit when only one browser session is open — Reticle resolves it automatically.'),
14
+ .describe('OMIT THIS unless you mean a specific tab — Reticle scopes to your project, prefers the active one, and refuses rather than guesses when ambiguous. Pass an id from reticle_sessions only to target a particular tab. The previous wording ("omit when only ONE session is open") was wrong and cost real turns: with three sessions connected — an app plus two pool leases — resolution is still unambiguous, but that sentence sent the agent off to list and filter sessions by hand before every single call.'),
15
15
  };
16
16
  /**
17
17
  * Fields that `runTool` / `withControl` splice onto EVERY session-bound tool result at runtime
@@ -32,6 +32,13 @@ export const sessionEnvelopeShape = {
32
32
  // That is exactly what invoke-tool.ts's health splice exists to prevent, so it belongs in the shared
33
33
  // envelope, not per-tool.
34
34
  warning: z.string().optional(),
35
+ // The one-shot "ask the human how this went" envelope. Undeclared, a validating profile would strip
36
+ // it — and a feedback prompt that never reaches the agent is a feedback prompt that never reaches
37
+ // the person, which is the entire failure mode this channel exists to fix.
38
+ feedback_prompt: z.unknown().optional(),
39
+ // One-shot "a newer Reticle exists" notice. Undeclared, a validating profile would strip it and the
40
+ // agent would never learn an update was waiting.
41
+ update_available: z.unknown().optional(),
35
42
  };
36
43
  /** Unwrap a browser command result or throw its error so the agent sees a clean failure. */
37
44
  export async function commandOrThrow(deps, sessionId,
@@ -53,4 +60,3 @@ export async function snapshotTree(deps, sessionId) {
53
60
  const snap = (result.result ?? {});
54
61
  return { lines: normalizeLines(snap.tree ?? ''), route: snap.status?.route ?? '' };
55
62
  }
56
- //# sourceMappingURL=tool-kit.js.map
@@ -15,6 +15,7 @@ export declare const ReticleTool: {
15
15
  readonly CONSOLE: "reticle_console";
16
16
  readonly ANIMATIONS: "reticle_animations";
17
17
  readonly ASSERT: "reticle_assert";
18
+ readonly RECONCILE: "reticle_reconcile";
18
19
  readonly BASELINE_SAVE: "reticle_baseline_save";
19
20
  readonly BASELINE_LIST: "reticle_baseline_list";
20
21
  readonly DIFF: "reticle_diff";
@@ -42,6 +43,9 @@ export declare const ReticleTool: {
42
43
  readonly FLOW_HEAL: "reticle_flow_heal";
43
44
  /** structured annotation → compiles into the recording's expect/dynamic/success. */
44
45
  readonly ANNOTATE: "reticle_annotate";
46
+ readonly AFFECTED: "reticle_affected";
47
+ readonly COVERAGE: "reticle_coverage";
48
+ readonly VERIFY_CHANGE: "reticle_verify_change";
45
49
  /** read cross-run history (.reticle/project.json) + diff-vs-last for a name. */
46
50
  readonly PROJECT: "reticle_project";
47
51
  /** explicitly record a run outcome (the manual companion to auto-recording). */
@@ -94,6 +98,7 @@ export declare const ReticleTool: {
94
98
  readonly TOOLS: "reticle_tools";
95
99
  /** Meta: invoke any tool by name — the escape hatch that keeps a trimmed profile a trim, not a removal. */
96
100
  readonly RUN: "reticle_run";
101
+ /** Report that Reticle itself failed — the agent's only way to tell us what to fix. */
102
+ readonly FEEDBACK: "reticle_feedback";
97
103
  };
98
104
  export type ReticleTool = (typeof ReticleTool)[keyof typeof ReticleTool];
99
- //# sourceMappingURL=tool-names.d.ts.map
@@ -16,6 +16,7 @@ export const ReticleTool = {
16
16
  CONSOLE: 'reticle_console',
17
17
  ANIMATIONS: 'reticle_animations',
18
18
  ASSERT: 'reticle_assert',
19
+ RECONCILE: 'reticle_reconcile',
19
20
  BASELINE_SAVE: 'reticle_baseline_save',
20
21
  BASELINE_LIST: 'reticle_baseline_list',
21
22
  DIFF: 'reticle_diff',
@@ -43,6 +44,9 @@ export const ReticleTool = {
43
44
  FLOW_HEAL: 'reticle_flow_heal',
44
45
  /** structured annotation → compiles into the recording's expect/dynamic/success. */
45
46
  ANNOTATE: 'reticle_annotate',
47
+ AFFECTED: 'reticle_affected',
48
+ COVERAGE: 'reticle_coverage',
49
+ VERIFY_CHANGE: 'reticle_verify_change',
46
50
  /** read cross-run history (.reticle/project.json) + diff-vs-last for a name. */
47
51
  PROJECT: 'reticle_project',
48
52
  /** explicitly record a run outcome (the manual companion to auto-recording). */
@@ -95,5 +99,6 @@ export const ReticleTool = {
95
99
  TOOLS: 'reticle_tools',
96
100
  /** Meta: invoke any tool by name — the escape hatch that keeps a trimmed profile a trim, not a removal. */
97
101
  RUN: 'reticle_run',
102
+ /** Report that Reticle itself failed — the agent's only way to tell us what to fix. */
103
+ FEEDBACK: 'reticle_feedback',
98
104
  };
99
- //# sourceMappingURL=tool-names.js.map
@@ -21,4 +21,3 @@ export declare function sourceOf(value: unknown): {
21
21
  column?: number;
22
22
  } | undefined;
23
23
  export {};
24
- //# sourceMappingURL=tools-helpers.d.ts.map
@@ -39,4 +39,3 @@ export function sourceOf(value) {
39
39
  out.column = record['column'];
40
40
  return out;
41
41
  }
42
- //# sourceMappingURL=tools-helpers.js.map
@@ -1,4 +1,3 @@
1
1
  import { type ToolDef } from './tool-kit.js';
2
2
  export type { ToolDef, ToolDeps } from './tool-kit.js';
3
3
  export declare const TOOLS: ToolDef[];
4
- //# sourceMappingURL=tools.d.ts.map
@@ -12,6 +12,9 @@ import { FLOW_TOOLS } from '../flows/flow-tools.js';
12
12
  import { PROJECT_TOOLS } from '../project/project-tools.js';
13
13
  import { RUN_TOOLS } from '../runs/run-tools.js';
14
14
  import { VISUAL_TOOLS } from '../visual/visual-tools.js';
15
+ import { AFFECTED_TOOLS } from '../flows/affected-tools.js';
16
+ import { COVERAGE_TOOLS } from './coverage-tools.js';
17
+ import { VERIFY_CHANGE_TOOLS } from '../flows/verify-change-tools.js';
15
18
  import { CRAWL_TOOLS } from '../crawl/crawl-tools.js';
16
19
  import { SCROLL_TOOLS } from '../input/scroll-tools.js';
17
20
  import { NETWORK_MOCK_TOOLS } from '../input/network-mock-tools.js';
@@ -23,8 +26,10 @@ import { sessionIdShape, commandOrThrow } from './tool-kit.js';
23
26
  import { applyMerges } from './merge-tools.js';
24
27
  import { ACT_TOOLS } from './act-tools.js';
25
28
  import { OBSERVE_TOOLS } from './observe-tools.js';
29
+ import { RECONCILE_TOOLS } from './reconcile-tools.js';
26
30
  import { READ_TOOLS } from './read-tools.js';
27
31
  import { LEASE_TOOLS } from './lease-tools.js';
32
+ import { FEEDBACK_TOOLS } from './feedback-tools.js';
28
33
  /** Per-server last-snapshot cache backing reticle_snapshot's diff:true delta mode (route-invalidated). */
29
34
  const SNAPSHOT_CACHE = new SnapshotCache();
30
35
  const RAW_TOOLS = [
@@ -71,7 +76,8 @@ const RAW_TOOLS = [
71
76
  },
72
77
  {
73
78
  name: ReticleTool.SNAPSHOT,
74
- description: 'Semantic accessibility snapshot of the page or a subtree. mode: full|interactive|status. Use to see what is on screen right now. The result carries cost:{ bytes, tokens } (estimated) — if it is large, re-scope (pass `scope`) or use mode:interactive/status instead of reading the whole tree. Pass diff:true after your first snapshot to get back ONLY what changed since your last look (mode:delta with added/removed, or mode:unchanged) — far fewer tokens and no stale tree to mis-read; a route change resets it to a full snapshot automatically.',
79
+ example: { diff: true },
80
+ description: 'Semantic accessibility snapshot of the page or a subtree — `mode:"interactive"` returns only the controls, ~3x smaller. Refs (`e42`) are stable: the same element keeps its ref across snapshots and only stops resolving once it leaves the DOM — re-snapshot after a navigation or if a ref fails to resolve, not between ordinary actions. mode: full|interactive|status. Use to see what is on screen right now. The result carries cost:{ bytes, tokens } (estimated) — if it is large, re-scope (pass `scope`) or use mode:interactive/status instead of reading the whole tree. Pass diff:true after your first snapshot to get back ONLY what changed since your last look (mode:delta with added/removed, or mode:unchanged) — far fewer tokens and no stale tree to mis-read; a route change resets it to a full snapshot automatically.',
75
81
  inputSchema: {
76
82
  scope: z
77
83
  .string()
@@ -151,7 +157,8 @@ const RAW_TOOLS = [
151
157
  },
152
158
  {
153
159
  name: ReticleTool.QUERY,
154
- description: 'Find elements by Testing-Library semantics, INCLUDING inside open shadow roots. Pass `by` (role|text|label|placeholder|testid|alt) and `value` (the query string). Returns matching refs + descriptors + visibility. Pass `attrs:["href"]` to project attributes (link/image URLs) onto each match. Pass `limit` to cap descriptors (broad role queries can be large) or `count_only:true` for just the match count — both cut tokens. On zero matches, also returns hint:{ route, presentRegions[], knownEmptyState } so you can distinguish an empty state from a missing element WITHOUT taking a snapshot.',
160
+ example: { by: 'testid', value: 'todo-list' },
161
+ description: 'Find elements by Testing-Library semantics, INCLUDING open shadow roots — `count_only:true` gives just the count (~30x smaller); `limit` caps descriptors. Pass `by` (role|text|label|placeholder|testid|alt) and `value` (the query string). Returns matching refs + descriptors + visibility. Pass `attrs:["href"]` to project attributes (link/image URLs) onto each match. Pass `limit` to cap descriptors (broad role queries can be large) or `count_only:true` for just the match count — both cut tokens. On zero matches, also returns hint:{ route, presentRegions[], knownEmptyState } so you can distinguish an empty state from a missing element WITHOUT taking a snapshot.',
155
162
  inputSchema: {
156
163
  by: z.string().describe('Query strategy: role | text | label | placeholder | testid | alt'),
157
164
  value: z
@@ -171,6 +178,7 @@ const RAW_TOOLS = [
171
178
  .describe("Attribute names to return per match, e.g. ['href'] to inventory links or ['src'] for images. Absent attributes are omitted; credential-bearing names are redacted."),
172
179
  limit: z
173
180
  .number()
181
+ .nonnegative()
174
182
  .optional()
175
183
  .describe('Cap the returned descriptors to the first N (cuts tokens on broad queries). If more matched, the result carries total + truncated:true so the trim is never silent — narrow with name/scope.'),
176
184
  count_only: z
@@ -262,9 +270,12 @@ const RAW_TOOLS = [
262
270
  },
263
271
  {
264
272
  name: ReticleTool.INSPECT,
273
+ example: { ref: 'e42' },
265
274
  description: 'Deep info on one element by ref: full a11y props, visibility, box, and (with @reticlehq/react) component stack + source file.',
266
275
  inputSchema: {
267
- ref: z.string().describe("Element ref from reticle_snapshot or reticle_query (e.g. 'e42')."),
276
+ ref: z
277
+ .string()
278
+ .describe(`Element ref (e.g. 'e42') from reticle_snapshot/reticle_query — stable until the element leaves the DOM, so no re-snapshot between actions.`),
268
279
  ...sessionIdShape,
269
280
  },
270
281
  outputSchema: {
@@ -325,6 +336,7 @@ const RAW_TOOLS = [
325
336
  }),
326
337
  },
327
338
  // reticle_capabilities (live | fromDisk) + reticle_contract_save. See contract-tools.ts.
339
+ ...RECONCILE_TOOLS,
328
340
  ...CONTRACT_TOOLS,
329
341
  ...DOMAIN_TOOLS,
330
342
  // reticle_flow_save / reticle_flow_list / reticle_flow_load. See flow-tools.ts.
@@ -345,6 +357,13 @@ const RAW_TOOLS = [
345
357
  ...SESSION_TOOLS,
346
358
  // reticle_annotate (structured annotation → expect/dynamic/success). See annotate-tools.ts.
347
359
  ...ANNOTATE_TOOLS,
360
+ // reticle_affected — which saved flows a diff invalidates. Unadvertised (zero per-turn cost),
361
+ // reachable through reticle_run. See affected-tools.ts.
362
+ ...AFFECTED_TOOLS,
363
+ // reticle_coverage — which controls were driven vs never touched. Unadvertised; via reticle_run.
364
+ ...COVERAGE_TOOLS,
365
+ // reticle_verify_change — "did my change break anything" in one call. See verify-change-tools.ts.
366
+ ...VERIFY_CHANGE_TOOLS,
348
367
  // Live-control: reticle_end_session / reticle_resume / reticle_messages. See live-control-tools.ts.
349
368
  ...LIVE_CONTROL_TOOLS,
350
369
  // reticle_navigate / reticle_refresh — browser navigation tools. See browser-tools.ts.
@@ -353,6 +372,8 @@ const RAW_TOOLS = [
353
372
  ...OBSERVE_TOOLS,
354
373
  ...READ_TOOLS,
355
374
  ...LEASE_TOOLS,
375
+ // reticle_feedback — the agent reports that RETICLE failed (not that the app did). See feedback-tools.ts.
376
+ ...FEEDBACK_TOOLS,
356
377
  ];
357
378
  /**
358
379
  * surface consolidation. Tool defs are re-sent EVERY turn, so the advertised count is a per-turn
@@ -415,4 +436,3 @@ const RETIRED_FROM_SURFACE = [
415
436
  ReticleTool.WAIT_READY, // server-internal: the first live call already blocks for the session
416
437
  ];
417
438
  export const TOOLS = applyMerges(RAW_TOOLS, MERGE_PLANS, RETIRED_FROM_SURFACE);
418
- //# sourceMappingURL=tools.js.map
@@ -30,4 +30,3 @@ export interface UpdateCheckPorts {
30
30
  */
31
31
  export declare function checkForUpdate(currentVersion: string, now: () => number, ports?: UpdateCheckPorts): Promise<UpdateManifest>;
32
32
  export {};
33
- //# sourceMappingURL=update-checker.d.ts.map
@@ -120,4 +120,3 @@ export async function checkForUpdate(currentVersion, now, ports = defaultPorts)
120
120
  };
121
121
  }
122
122
  }
123
- //# sourceMappingURL=update-checker.js.map
@@ -0,0 +1,20 @@
1
+ export interface UpdateNudge {
2
+ /** The version available, so the agent can tell the human what they would be moving to. */
3
+ latestVersion: string;
4
+ currentVersion: string;
5
+ /** The exact command. Spelled out so the agent never has to guess or invent one. */
6
+ command: string;
7
+ action: string;
8
+ }
9
+ /**
10
+ * Kick off a background check. Non-blocking and best-effort: `checkForUpdate` never throws, caches
11
+ * for 24h on disk, and falls back to the cached manifest when the registry is unreachable — so this
12
+ * costs one npm registry request per day per machine, and nothing at all when offline.
13
+ */
14
+ export declare function startUpdateCheck(now?: () => number): void;
15
+ /** The nudge, once. Returns undefined afterwards so a long session is told exactly one time. */
16
+ export declare function takeUpdateNudge(): UpdateNudge | undefined;
17
+ /** Tests only — drop the module state so each case starts clean. */
18
+ export declare function resetUpdateNudge(): void;
19
+ /** Tests only — seed a pending nudge without going near the network. */
20
+ export declare function setPendingUpdate(nudge: UpdateNudge | undefined): void;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Telling the agent that a newer Reticle exists.
3
+ *
4
+ * Until now nothing did. `checkForUpdate` had exactly one caller — the `reticle update` command — so
5
+ * a published release was invisible to every install until a human happened to type that command,
6
+ * which in practice meant never. A fix could ship and sit unused for months on the machines that hit
7
+ * the bug it fixed.
8
+ *
9
+ * The nudge rides the tool-result envelope rather than being a tool of its own, for the same reason
10
+ * the session-health and pool-lease reminders do: the agent is mid-task, and something it has to go
11
+ * and ASK for is something it will not ask for. Delivered ONCE per daemon process — a repeated
12
+ * "please update" during someone's work is noise, and noise is what gets filtered out.
13
+ *
14
+ * It deliberately does NOT update anything by itself. A silent self-install would swap the binary
15
+ * under a running session, restart the daemon, and drop every agent attached to it — during work the
16
+ * human never agreed to interrupt. So the envelope carries the fact and the exact command, and the
17
+ * decision stays with the people whose machine it is.
18
+ */
19
+ import { checkForUpdate } from './update-checker.js';
20
+ import { SERVER_VERSION } from '../server-version.js';
21
+ import { log } from '../log.js';
22
+ /** Let the daemon finish coming up before touching the network. */
23
+ const CHECK_DELAY_MS = 8_000;
24
+ const UPDATE_COMMAND = 'reticle update';
25
+ let pending;
26
+ let delivered = false;
27
+ /**
28
+ * Kick off a background check. Non-blocking and best-effort: `checkForUpdate` never throws, caches
29
+ * for 24h on disk, and falls back to the cached manifest when the registry is unreachable — so this
30
+ * costs one npm registry request per day per machine, and nothing at all when offline.
31
+ */
32
+ export function startUpdateCheck(now = () => Date.now()) {
33
+ setTimeout(() => {
34
+ void checkForUpdate(SERVER_VERSION, now)
35
+ .then((manifest) => {
36
+ if (!manifest.updateAvailable || manifest.latestVersion === undefined)
37
+ return;
38
+ pending = {
39
+ currentVersion: SERVER_VERSION,
40
+ latestVersion: manifest.latestVersion,
41
+ command: UPDATE_COMMAND,
42
+ action: `A newer Reticle is available (${SERVER_VERSION} → ${manifest.latestVersion}). ` +
43
+ `Tell the human, and run \`${UPDATE_COMMAND}\` if they agree — it restarts the daemon, ` +
44
+ 'so do it between tasks rather than mid-verification. Continue your current task first.',
45
+ };
46
+ log('reticle_update_available', {
47
+ from: SERVER_VERSION,
48
+ to: manifest.latestVersion,
49
+ });
50
+ })
51
+ .catch(() => {
52
+ /* a version check must never surface to a user */
53
+ });
54
+ }, CHECK_DELAY_MS).unref();
55
+ }
56
+ /** The nudge, once. Returns undefined afterwards so a long session is told exactly one time. */
57
+ export function takeUpdateNudge() {
58
+ if (delivered || pending === undefined)
59
+ return undefined;
60
+ delivered = true;
61
+ return pending;
62
+ }
63
+ /** Tests only — drop the module state so each case starts clean. */
64
+ export function resetUpdateNudge() {
65
+ pending = undefined;
66
+ delivered = false;
67
+ }
68
+ /** Tests only — seed a pending nudge without going near the network. */
69
+ export function setPendingUpdate(nudge) {
70
+ pending = nudge;
71
+ delivered = false;
72
+ }
@@ -1,3 +1,17 @@
1
+ /** Which way the installed version moved. A rollback means a release hurt someone enough to retreat. */
2
+ export declare const VersionChangeDirection: {
3
+ readonly UPDATE: "update";
4
+ readonly ROLLBACK: "rollback";
5
+ };
6
+ export type VersionChangeDirection = (typeof VersionChangeDirection)[keyof typeof VersionChangeDirection];
7
+ /**
8
+ * Report a completed version move. Never throws — an install that worked must still be reported done.
9
+ *
10
+ * Exported so the emit path can be exercised directly: `applyUpdate`/`rollback` both run a real npm
11
+ * install and then `process.exit`, so there is no way to reach this through them in a test without
12
+ * mocking the package manager and the process itself.
13
+ */
14
+ export declare function reportVersionChange(from: string, to: string, direction: VersionChangeDirection): Promise<void>;
1
15
  /** How this reticle process was launched — determines which npm strategy to use for updates. */
2
16
  declare const ExecutionKind: {
3
17
  /** Launched via `npx @reticlehq/server` — npm re-resolves the package on restart. */
@@ -46,4 +60,3 @@ export declare function applyUpdate(targetVersion: string): Promise<void>;
46
60
  */
47
61
  export declare function rollback(): Promise<void>;
48
62
  export {};
49
- //# sourceMappingURL=updater.d.ts.map
@@ -3,8 +3,32 @@ import { existsSync } from 'node:fs';
3
3
  import { platform } from 'node:os';
4
4
  import { dirname, join } from 'node:path';
5
5
  import { loadManifest, saveManifest } from './update-checker.js';
6
- import { RETICLE_NPM_PACKAGE } from '../server-version.js';
6
+ import { RETICLE_NPM_PACKAGE, SERVER_VERSION } from '../server-version.js';
7
7
  import { log } from '../log.js';
8
+ import { TelemetryEventKind } from '@reticlehq/core';
9
+ import { getTelemetry } from '../telemetry/telemetry.js';
10
+ /** Which way the installed version moved. A rollback means a release hurt someone enough to retreat. */
11
+ export const VersionChangeDirection = {
12
+ UPDATE: 'update',
13
+ ROLLBACK: 'rollback',
14
+ };
15
+ /**
16
+ * Report a completed version move. Never throws — an install that worked must still be reported done.
17
+ *
18
+ * Exported so the emit path can be exercised directly: `applyUpdate`/`rollback` both run a real npm
19
+ * install and then `process.exit`, so there is no way to reach this through them in a test without
20
+ * mocking the package manager and the process itself.
21
+ */
22
+ export async function reportVersionChange(from, to, direction) {
23
+ try {
24
+ await getTelemetry().emit(TelemetryEventKind.VERSION_CHANGED, {
25
+ versionChange: { from, to, direction },
26
+ });
27
+ }
28
+ catch {
29
+ /* best-effort, like every other send */
30
+ }
31
+ }
8
32
  const NPM_BIN = platform() === 'win32' ? 'npm.cmd' : 'npm';
9
33
  const NPM_TIMEOUT_MS = 120_000;
10
34
  /** How this reticle process was launched — determines which npm strategy to use for updates. */
@@ -129,6 +153,11 @@ export async function applyUpdate(targetVersion) {
129
153
  log('reticle_update_applying', { version: targetVersion, executionKind: kind });
130
154
  await installVersion(targetVersion, kind);
131
155
  log('reticle_update_applied', { version: targetVersion, executionKind: kind });
156
+ // Emitted AFTER the install succeeded, so the metric counts versions that actually landed rather
157
+ // than attempts. Awaited, unlike every other send in the product: `process.exit(0)` on the next
158
+ // line would kill an in-flight fire-and-forget POST, and this event is rare enough that the wait
159
+ // costs nothing. A failed send still cannot block the exit — `emit` swallows its own errors.
160
+ await reportVersionChange(SERVER_VERSION, targetVersion, VersionChangeDirection.UPDATE);
132
161
  process.exit(0);
133
162
  }
134
163
  /**
@@ -145,10 +174,12 @@ export async function rollback() {
145
174
  log('reticle_rollback_applying', { version: prev, executionKind: kind });
146
175
  await installVersionRollback(prev, kind);
147
176
  log('reticle_rollback_applied', { version: prev, executionKind: kind });
177
+ // A rollback is a release-quality alarm — someone shipped something that broke a real user badly
178
+ // enough for them to go backwards. Worth knowing about within the hour, not at the next retro.
179
+ await reportVersionChange(SERVER_VERSION, prev, VersionChangeDirection.ROLLBACK);
148
180
  // For npx, exiting would let the next restart re-resolve @latest — rolling FORWARD, the opposite
149
181
  // of rollback. installVersionRollback already told the user to pin the version in.mcp.json, so
150
182
  // stay running rather than trigger that. Other kinds installed the old version and must restart.
151
183
  if (kind !== ExecutionKind.NPX)
152
184
  process.exit(0);
153
185
  }
154
- //# sourceMappingURL=updater.js.map
@@ -43,4 +43,3 @@ export interface VisualDiffResult {
43
43
  * mismatch is a hard fail (can't pixel-diff) reported as `dimensionMismatch`, never a throw.
44
44
  */
45
45
  export declare function diffPng(baselineBytes: Uint8Array, currentBytes: Uint8Array, opts?: DiffOptions): Promise<VisualDiffResult>;
46
- //# sourceMappingURL=visual-diff.d.ts.map
@@ -97,4 +97,3 @@ export async function diffPng(baselineBytes, currentBytes, opts = {}) {
97
97
  };
98
98
  return region === undefined ? result : { ...result, region };
99
99
  }
100
- //# sourceMappingURL=visual-diff.js.map
@@ -20,4 +20,3 @@ export declare class VisualStore {
20
20
  /** Write the overlay diff PNG for `name` (auto-creating .reticle/visual/). Returns its path. */
21
21
  saveDiff(name: string, png: Uint8Array): Promise<string>;
22
22
  }
23
- //# sourceMappingURL=visual-store.d.ts.map
@@ -62,4 +62,3 @@ export class VisualStore {
62
62
  return path;
63
63
  }
64
64
  }
65
- //# sourceMappingURL=visual-store.js.map
@@ -6,4 +6,3 @@ import type { ToolDef } from '../tools/tools.js';
6
6
  * stay the default; this is the complementary "does it look right" surface, never bundled in.
7
7
  */
8
8
  export declare const VISUAL_TOOLS: ToolDef[];
9
- //# sourceMappingURL=visual-tools.d.ts.map