@reticlehq/server 2.2.1 → 2.4.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 (790) 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 +102 -12
  6. package/dist/bridge.test-harness.d.ts +5 -1
  7. package/dist/bridge.test-harness.js +12 -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 +47 -3
  27. package/dist/cli-parse.js +147 -13
  28. package/dist/cli-port.d.ts +3 -1
  29. package/dist/cli-port.js +21 -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 +88 -69
  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 -7
  99. package/dist/flows/decision.js +47 -7
  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 +44 -14
  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/capabilities.d.ts +17 -0
  167. package/dist/init/capabilities.js +51 -0
  168. package/dist/init/cursor.d.ts +0 -1
  169. package/dist/init/cursor.js +0 -1
  170. package/dist/init/desktop-doctor.d.ts +40 -0
  171. package/dist/init/desktop-doctor.js +198 -0
  172. package/dist/init/detect.d.ts +25 -1
  173. package/dist/init/detect.js +65 -4
  174. package/dist/init/mcp.d.ts +0 -1
  175. package/dist/init/mcp.js +0 -1
  176. package/dist/init/next-patch.d.ts +41 -0
  177. package/dist/init/next-patch.js +106 -0
  178. package/dist/init/node-io.d.ts +0 -1
  179. package/dist/init/node-io.js +25 -1
  180. package/dist/init/patch-kind.d.ts +20 -0
  181. package/dist/init/patch-kind.js +10 -0
  182. package/dist/init/plan-framework.d.ts +35 -0
  183. package/dist/init/plan-framework.js +217 -0
  184. package/dist/init/plan.d.ts +55 -4
  185. package/dist/init/plan.js +130 -112
  186. package/dist/init/project-id.d.ts +0 -1
  187. package/dist/init/project-id.js +0 -1
  188. package/dist/init/run.d.ts +17 -1
  189. package/dist/init/run.js +237 -18
  190. package/dist/init/slash-command.d.ts +18 -0
  191. package/dist/init/slash-command.js +52 -0
  192. package/dist/init/snippets.d.ts +48 -3
  193. package/dist/init/snippets.js +156 -6
  194. package/dist/init/vite-config.d.ts +4 -11
  195. package/dist/init/vite-config.js +15 -8
  196. package/dist/input/driven-redaction.d.ts +15 -0
  197. package/dist/input/driven-redaction.js +76 -0
  198. package/dist/input/network-detail.d.ts +9 -4
  199. package/dist/input/network-detail.js +35 -16
  200. package/dist/input/network-mock-tools.d.ts +0 -1
  201. package/dist/input/network-mock-tools.js +3 -4
  202. package/dist/input/network-mock.d.ts +0 -1
  203. package/dist/input/network-mock.js +0 -1
  204. package/dist/input/real-input.d.ts +14 -1
  205. package/dist/input/real-input.js +45 -3
  206. package/dist/input/scroll-find.d.ts +0 -1
  207. package/dist/input/scroll-find.js +0 -1
  208. package/dist/input/scroll-tools.d.ts +0 -1
  209. package/dist/input/scroll-tools.js +0 -1
  210. package/dist/input/viewport-tools.d.ts +0 -1
  211. package/dist/input/viewport-tools.js +3 -4
  212. package/dist/journal/ambient-store.d.ts +0 -1
  213. package/dist/journal/ambient-store.js +0 -1
  214. package/dist/journal/ambient.d.ts +0 -1
  215. package/dist/journal/ambient.js +0 -1
  216. package/dist/journal/attach-journal.d.ts +0 -1
  217. package/dist/journal/attach-journal.js +0 -1
  218. package/dist/journal/deviation-report.d.ts +0 -1
  219. package/dist/journal/deviation-report.js +0 -1
  220. package/dist/journal/deviation-service.d.ts +0 -1
  221. package/dist/journal/deviation-service.js +0 -1
  222. package/dist/journal/envelope-store.d.ts +0 -1
  223. package/dist/journal/envelope-store.js +0 -1
  224. package/dist/journal/envelope.d.ts +8 -9
  225. package/dist/journal/envelope.js +0 -1
  226. package/dist/journal/journal-query.d.ts +0 -1
  227. package/dist/journal/journal-query.js +0 -1
  228. package/dist/journal/journal-recorder.d.ts +0 -1
  229. package/dist/journal/journal-recorder.js +0 -1
  230. package/dist/journal/retention.d.ts +0 -1
  231. package/dist/journal/retention.js +0 -1
  232. package/dist/journal/rollups.d.ts +0 -1
  233. package/dist/journal/rollups.js +0 -1
  234. package/dist/journal/session-end.d.ts +0 -1
  235. package/dist/journal/session-end.js +0 -1
  236. package/dist/journal/session-journal.d.ts +0 -1
  237. package/dist/journal/session-journal.js +0 -1
  238. package/dist/license/license.d.ts +0 -1
  239. package/dist/license/license.js +0 -1
  240. package/dist/log.d.ts +0 -1
  241. package/dist/log.js +0 -1
  242. package/dist/mcp-proxy.d.ts +35 -4
  243. package/dist/mcp-proxy.js +174 -28
  244. package/dist/mcp.d.ts +15 -1
  245. package/dist/mcp.js +145 -17
  246. package/dist/oracles/flow-instrument-gaps.d.ts +0 -1
  247. package/dist/oracles/flow-instrument-gaps.js +0 -1
  248. package/dist/oracles/propose-consequences.d.ts +0 -1
  249. package/dist/oracles/propose-consequences.js +0 -1
  250. package/dist/oracles/self-instrument.d.ts +0 -1
  251. package/dist/oracles/self-instrument.js +0 -1
  252. package/dist/pairing-token.d.ts +0 -1
  253. package/dist/pairing-token.js +0 -1
  254. package/dist/phenomena/phenomena.d.ts +0 -1
  255. package/dist/phenomena/phenomena.js +0 -1
  256. package/dist/pool/browser-pool.d.ts +0 -1
  257. package/dist/pool/browser-pool.js +0 -1
  258. package/dist/pool/lease-reaper.d.ts +0 -1
  259. package/dist/pool/lease-reaper.js +0 -1
  260. package/dist/pool/playwright-launcher.d.ts +0 -1
  261. package/dist/pool/playwright-launcher.js +10 -2
  262. package/dist/project/baselines.d.ts +0 -1
  263. package/dist/project/baselines.js +0 -1
  264. package/dist/project/file-lock.d.ts +2 -1
  265. package/dist/project/file-lock.js +12 -2
  266. package/dist/project/fs-port.d.ts +0 -1
  267. package/dist/project/fs-port.js +0 -1
  268. package/dist/project/project-store.d.ts +0 -1
  269. package/dist/project/project-store.js +0 -1
  270. package/dist/project/project-tools.d.ts +0 -1
  271. package/dist/project/project-tools.js +29 -4
  272. package/dist/project/reticle-dir.d.ts +0 -1
  273. package/dist/project/reticle-dir.js +0 -1
  274. package/dist/runs/build-verification-run.d.ts +0 -1
  275. package/dist/runs/build-verification-run.js +0 -1
  276. package/dist/runs/profile-redact.d.ts +0 -1
  277. package/dist/runs/profile-redact.js +0 -1
  278. package/dist/runs/render-report.d.ts +0 -1
  279. package/dist/runs/render-report.js +0 -1
  280. package/dist/runs/repair-prompt.d.ts +0 -1
  281. package/dist/runs/repair-prompt.js +0 -1
  282. package/dist/runs/replay-mapping.d.ts +0 -1
  283. package/dist/runs/replay-mapping.js +0 -1
  284. package/dist/runs/reticle-runner.d.ts +0 -1
  285. package/dist/runs/reticle-runner.js +4 -2
  286. package/dist/runs/risk-classify.d.ts +0 -1
  287. package/dist/runs/risk-classify.js +0 -1
  288. package/dist/runs/run-diff.d.ts +0 -1
  289. package/dist/runs/run-diff.js +0 -1
  290. package/dist/runs/run-store.d.ts +0 -1
  291. package/dist/runs/run-store.js +0 -1
  292. package/dist/runs/run-tools.d.ts +0 -1
  293. package/dist/runs/run-tools.js +0 -1
  294. package/dist/runs/runner-port.d.ts +0 -1
  295. package/dist/runs/runner-port.js +0 -1
  296. package/dist/runs/verification-sync.d.ts +0 -1
  297. package/dist/runs/verification-sync.js +0 -1
  298. package/dist/runs/verify-http.d.ts +0 -1
  299. package/dist/runs/verify-http.js +0 -1
  300. package/dist/runs/verify-server.d.ts +0 -1
  301. package/dist/runs/verify-server.js +0 -1
  302. package/dist/server-version.d.ts +0 -1
  303. package/dist/server-version.js +0 -1
  304. package/dist/session/command-timeout.d.ts +35 -0
  305. package/dist/session/command-timeout.js +41 -0
  306. package/dist/session/control-envelope.d.ts +2 -3
  307. package/dist/session/control-envelope.js +2 -3
  308. package/dist/session/last-act.d.ts +31 -0
  309. package/dist/session/last-act.js +24 -0
  310. package/dist/session/live-control-tools.d.ts +0 -1
  311. package/dist/session/live-control-tools.js +3 -4
  312. package/dist/session/live-control.d.ts +0 -1
  313. package/dist/session/live-control.js +0 -1
  314. package/dist/session/observed-state.d.ts +12 -2
  315. package/dist/session/observed-state.js +29 -2
  316. package/dist/session/output-budget.d.ts +0 -1
  317. package/dist/session/output-budget.js +0 -1
  318. package/dist/session/pending-commands.d.ts +12 -0
  319. package/dist/session/pending-commands.js +36 -0
  320. package/dist/session/presenter-args.d.ts +0 -1
  321. package/dist/session/presenter-args.js +0 -1
  322. package/dist/session/review-store.d.ts +0 -1
  323. package/dist/session/review-store.js +0 -1
  324. package/dist/session/session-health.d.ts +26 -2
  325. package/dist/session/session-health.js +13 -1
  326. package/dist/session/session-info.d.ts +29 -0
  327. package/dist/session/session-info.js +1 -0
  328. package/dist/session/session-lease.d.ts +25 -0
  329. package/dist/session/session-lease.js +14 -0
  330. package/dist/session/session-manager.d.ts +7 -19
  331. package/dist/session/session-manager.js +35 -2
  332. package/dist/session/session-readiness.d.ts +0 -1
  333. package/dist/session/session-readiness.js +3 -4
  334. package/dist/session/session-reaper.d.ts +0 -1
  335. package/dist/session/session-reaper.js +0 -1
  336. package/dist/session/session-recommendation.d.ts +0 -1
  337. package/dist/session/session-recommendation.js +0 -1
  338. package/dist/session/session-tools.d.ts +0 -1
  339. package/dist/session/session-tools.js +2 -3
  340. package/dist/session/session.d.ts +33 -53
  341. package/dist/session/session.js +102 -66
  342. package/dist/session/state-select.d.ts +0 -1
  343. package/dist/session/state-select.js +0 -1
  344. package/dist/telemetry/argument-shape.d.ts +41 -0
  345. package/dist/telemetry/argument-shape.js +87 -0
  346. package/dist/telemetry/bug-found.d.ts +33 -0
  347. package/dist/telemetry/bug-found.js +95 -0
  348. package/dist/telemetry/cli-telemetry.d.ts +13 -0
  349. package/dist/telemetry/cli-telemetry.js +43 -0
  350. package/dist/telemetry/connect-failure.d.ts +16 -0
  351. package/dist/telemetry/connect-failure.js +44 -0
  352. package/dist/telemetry/daemon-telemetry.d.ts +19 -0
  353. package/dist/telemetry/daemon-telemetry.js +76 -0
  354. package/dist/telemetry/dev-repo.d.ts +10 -0
  355. package/dist/telemetry/dev-repo.js +80 -0
  356. package/dist/telemetry/error-fingerprint.d.ts +24 -0
  357. package/dist/telemetry/error-fingerprint.js +88 -0
  358. package/dist/telemetry/feedback-cli.d.ts +31 -0
  359. package/dist/telemetry/feedback-cli.js +102 -0
  360. package/dist/telemetry/feedback-context.d.ts +32 -0
  361. package/dist/telemetry/feedback-context.js +143 -0
  362. package/dist/telemetry/feedback.d.ts +66 -0
  363. package/dist/telemetry/feedback.js +175 -0
  364. package/dist/telemetry/git-facts.d.ts +21 -0
  365. package/dist/telemetry/git-facts.js +109 -0
  366. package/dist/telemetry/identify.d.ts +22 -0
  367. package/dist/telemetry/identify.js +73 -0
  368. package/dist/telemetry/init-telemetry.d.ts +26 -0
  369. package/dist/telemetry/init-telemetry.js +33 -0
  370. package/dist/telemetry/machine-snapshot.d.ts +6 -0
  371. package/dist/telemetry/machine-snapshot.js +39 -0
  372. package/dist/telemetry/mcp-connection.d.ts +5 -0
  373. package/dist/telemetry/mcp-connection.js +44 -0
  374. package/dist/telemetry/project-profile.d.ts +44 -0
  375. package/dist/telemetry/project-profile.js +205 -0
  376. package/dist/telemetry/run-telemetry.d.ts +21 -0
  377. package/dist/telemetry/run-telemetry.js +62 -0
  378. package/dist/telemetry/session-metrics.d.ts +103 -0
  379. package/dist/telemetry/session-metrics.js +329 -0
  380. package/dist/telemetry/telemetry.d.ts +35 -8
  381. package/dist/telemetry/telemetry.js +105 -12
  382. package/dist/token-auth.d.ts +0 -1
  383. package/dist/token-auth.js +0 -1
  384. package/dist/tools/act-capsule.d.ts +23 -0
  385. package/dist/tools/act-capsule.js +47 -0
  386. package/dist/tools/act-danger.d.ts +7 -0
  387. package/dist/tools/act-danger.js +44 -0
  388. package/dist/tools/act-helpers.d.ts +17 -0
  389. package/dist/tools/act-helpers.js +40 -0
  390. package/dist/tools/act-tools.d.ts +8 -1
  391. package/dist/tools/act-tools.js +96 -98
  392. package/dist/tools/act-view.d.ts +7 -1
  393. package/dist/tools/act-view.js +13 -1
  394. package/dist/tools/assert-grade.d.ts +22 -1
  395. package/dist/tools/assert-grade.js +46 -1
  396. package/dist/tools/assert-verdict.d.ts +21 -0
  397. package/dist/tools/assert-verdict.js +62 -0
  398. package/dist/tools/browser-tools.d.ts +0 -1
  399. package/dist/tools/browser-tools.js +2 -2
  400. package/dist/tools/contract-tools.d.ts +0 -1
  401. package/dist/tools/contract-tools.js +0 -1
  402. package/dist/tools/coverage-tools.d.ts +9 -0
  403. package/dist/tools/coverage-tools.js +92 -0
  404. package/dist/tools/dynamic-tools.d.ts +0 -1
  405. package/dist/tools/dynamic-tools.js +21 -2
  406. package/dist/tools/error-recovery.d.ts +18 -2
  407. package/dist/tools/error-recovery.js +42 -7
  408. package/dist/tools/feedback-tools.d.ts +24 -0
  409. package/dist/tools/feedback-tools.js +180 -0
  410. package/dist/tools/invoke-tool.d.ts +0 -1
  411. package/dist/tools/invoke-tool.js +115 -5
  412. package/dist/tools/lease-tools.d.ts +0 -1
  413. package/dist/tools/lease-tools.js +6 -5
  414. package/dist/tools/merge-tools.d.ts +0 -1
  415. package/dist/tools/merge-tools.js +0 -1
  416. package/dist/tools/observe-tools.d.ts +0 -1
  417. package/dist/tools/observe-tools.js +91 -39
  418. package/dist/tools/profiles.d.ts +1 -2
  419. package/dist/tools/profiles.js +43 -16
  420. package/dist/tools/query-paginate.d.ts +0 -1
  421. package/dist/tools/query-paginate.js +0 -1
  422. package/dist/tools/read-tools.d.ts +0 -1
  423. package/dist/tools/read-tools.js +14 -8
  424. package/dist/tools/reconcile-tools.d.ts +2 -0
  425. package/dist/tools/reconcile-tools.js +111 -0
  426. package/dist/tools/snapshot-delta.d.ts +0 -1
  427. package/dist/tools/snapshot-delta.js +0 -0
  428. package/dist/tools/tool-invoker.d.ts +0 -1
  429. package/dist/tools/tool-invoker.js +0 -1
  430. package/dist/tools/tool-kit.d.ts +16 -1
  431. package/dist/tools/tool-kit.js +8 -2
  432. package/dist/tools/tool-names.d.ts +6 -1
  433. package/dist/tools/tool-names.js +6 -1
  434. package/dist/tools/tools-helpers.d.ts +0 -1
  435. package/dist/tools/tools-helpers.js +0 -1
  436. package/dist/tools/tools.d.ts +0 -1
  437. package/dist/tools/tools.js +24 -4
  438. package/dist/update/update-checker.d.ts +0 -1
  439. package/dist/update/update-checker.js +0 -1
  440. package/dist/update/update-nudge.d.ts +20 -0
  441. package/dist/update/update-nudge.js +72 -0
  442. package/dist/update/updater.d.ts +14 -1
  443. package/dist/update/updater.js +33 -2
  444. package/dist/visual/visual-diff.d.ts +0 -1
  445. package/dist/visual/visual-diff.js +0 -1
  446. package/dist/visual/visual-store.d.ts +0 -1
  447. package/dist/visual/visual-store.js +0 -1
  448. package/dist/visual/visual-tools.d.ts +0 -1
  449. package/dist/visual/visual-tools.js +103 -16
  450. package/package.json +2 -2
  451. package/dist/bridge-security.d.ts.map +0 -1
  452. package/dist/bridge-security.js.map +0 -1
  453. package/dist/bridge.d.ts.map +0 -1
  454. package/dist/bridge.js.map +0 -1
  455. package/dist/bridge.test-harness.d.ts.map +0 -1
  456. package/dist/bridge.test-harness.js.map +0 -1
  457. package/dist/capsule/capsule-store.d.ts.map +0 -1
  458. package/dist/capsule/capsule-store.js.map +0 -1
  459. package/dist/capsule/capsule.d.ts.map +0 -1
  460. package/dist/capsule/capsule.js.map +0 -1
  461. package/dist/capsule/causal-summary.d.ts.map +0 -1
  462. package/dist/capsule/causal-summary.js.map +0 -1
  463. package/dist/capsule/divergence.d.ts.map +0 -1
  464. package/dist/capsule/divergence.js.map +0 -1
  465. package/dist/capsule/minimize.d.ts.map +0 -1
  466. package/dist/capsule/minimize.js.map +0 -1
  467. package/dist/capsule/predicate-to-links.d.ts.map +0 -1
  468. package/dist/capsule/predicate-to-links.js.map +0 -1
  469. package/dist/cli-flow-commands.d.ts.map +0 -1
  470. package/dist/cli-flow-commands.js.map +0 -1
  471. package/dist/cli-launch.d.ts.map +0 -1
  472. package/dist/cli-launch.js.map +0 -1
  473. package/dist/cli-parse.d.ts.map +0 -1
  474. package/dist/cli-parse.js.map +0 -1
  475. package/dist/cli-port.d.ts.map +0 -1
  476. package/dist/cli-port.js.map +0 -1
  477. package/dist/cli-verify.d.ts.map +0 -1
  478. package/dist/cli-verify.js.map +0 -1
  479. package/dist/cli.d.ts.map +0 -1
  480. package/dist/cli.js.map +0 -1
  481. package/dist/cloud/cloud-config.d.ts.map +0 -1
  482. package/dist/cloud/cloud-config.js.map +0 -1
  483. package/dist/cloud/cloud-sync.d.ts.map +0 -1
  484. package/dist/cloud/cloud-sync.js.map +0 -1
  485. package/dist/cloud-cli.d.ts.map +0 -1
  486. package/dist/cloud-cli.js.map +0 -1
  487. package/dist/crawl/crawl-tools.d.ts.map +0 -1
  488. package/dist/crawl/crawl-tools.js.map +0 -1
  489. package/dist/crawl/crawl.d.ts.map +0 -1
  490. package/dist/crawl/crawl.js.map +0 -1
  491. package/dist/daemon-resilience.d.ts.map +0 -1
  492. package/dist/daemon-resilience.js.map +0 -1
  493. package/dist/daemon.d.ts.map +0 -1
  494. package/dist/daemon.js.map +0 -1
  495. package/dist/domain/domain-model.d.ts.map +0 -1
  496. package/dist/domain/domain-model.js.map +0 -1
  497. package/dist/domain/domain-tools.d.ts.map +0 -1
  498. package/dist/domain/domain-tools.js.map +0 -1
  499. package/dist/domain/flow-risk.d.ts.map +0 -1
  500. package/dist/domain/flow-risk.js.map +0 -1
  501. package/dist/ee/audit-log.d.ts.map +0 -1
  502. package/dist/ee/audit-log.js.map +0 -1
  503. package/dist/events/event-filters.d.ts.map +0 -1
  504. package/dist/events/event-filters.js.map +0 -1
  505. package/dist/events/predicate-eval.d.ts.map +0 -1
  506. package/dist/events/predicate-eval.js.map +0 -1
  507. package/dist/events/predicate.d.ts.map +0 -1
  508. package/dist/events/predicate.js.map +0 -1
  509. package/dist/events/reaction.d.ts.map +0 -1
  510. package/dist/events/reaction.js.map +0 -1
  511. package/dist/events/ring-buffer.d.ts.map +0 -1
  512. package/dist/events/ring-buffer.js.map +0 -1
  513. package/dist/flows/affected.d.ts.map +0 -1
  514. package/dist/flows/affected.js.map +0 -1
  515. package/dist/flows/annotate-tools.d.ts.map +0 -1
  516. package/dist/flows/annotate-tools.js.map +0 -1
  517. package/dist/flows/annotate.d.ts.map +0 -1
  518. package/dist/flows/annotate.js.map +0 -1
  519. package/dist/flows/annotation-store.d.ts.map +0 -1
  520. package/dist/flows/annotation-store.js.map +0 -1
  521. package/dist/flows/assertion-integrity.d.ts.map +0 -1
  522. package/dist/flows/assertion-integrity.js.map +0 -1
  523. package/dist/flows/assertion-tiers-store.d.ts.map +0 -1
  524. package/dist/flows/assertion-tiers-store.js.map +0 -1
  525. package/dist/flows/buddy-status.d.ts.map +0 -1
  526. package/dist/flows/buddy-status.js.map +0 -1
  527. package/dist/flows/coverage.d.ts.map +0 -1
  528. package/dist/flows/coverage.js.map +0 -1
  529. package/dist/flows/decision.d.ts.map +0 -1
  530. package/dist/flows/decision.js.map +0 -1
  531. package/dist/flows/flake-store.d.ts.map +0 -1
  532. package/dist/flows/flake-store.js.map +0 -1
  533. package/dist/flows/flake.d.ts.map +0 -1
  534. package/dist/flows/flake.js.map +0 -1
  535. package/dist/flows/flow-classify.d.ts.map +0 -1
  536. package/dist/flows/flow-classify.js.map +0 -1
  537. package/dist/flows/flow-replay-run.d.ts.map +0 -1
  538. package/dist/flows/flow-replay-run.js.map +0 -1
  539. package/dist/flows/flow-replay.d.ts.map +0 -1
  540. package/dist/flows/flow-replay.js.map +0 -1
  541. package/dist/flows/flow-report.d.ts.map +0 -1
  542. package/dist/flows/flow-report.js.map +0 -1
  543. package/dist/flows/flow-scope.d.ts.map +0 -1
  544. package/dist/flows/flow-scope.js.map +0 -1
  545. package/dist/flows/flow-sources.d.ts.map +0 -1
  546. package/dist/flows/flow-sources.js.map +0 -1
  547. package/dist/flows/flow-success.d.ts.map +0 -1
  548. package/dist/flows/flow-success.js.map +0 -1
  549. package/dist/flows/flow-tools.d.ts.map +0 -1
  550. package/dist/flows/flow-tools.js.map +0 -1
  551. package/dist/flows/flows.d.ts.map +0 -1
  552. package/dist/flows/flows.js.map +0 -1
  553. package/dist/flows/gate.d.ts.map +0 -1
  554. package/dist/flows/gate.js.map +0 -1
  555. package/dist/flows/git-changed.d.ts.map +0 -1
  556. package/dist/flows/git-changed.js.map +0 -1
  557. package/dist/flows/heal-run.d.ts.map +0 -1
  558. package/dist/flows/heal-run.js.map +0 -1
  559. package/dist/flows/heal.d.ts.map +0 -1
  560. package/dist/flows/heal.js.map +0 -1
  561. package/dist/flows/parallel-suite.d.ts.map +0 -1
  562. package/dist/flows/parallel-suite.js.map +0 -1
  563. package/dist/flows/recordings.d.ts.map +0 -1
  564. package/dist/flows/recordings.js.map +0 -1
  565. package/dist/flows/replay.d.ts.map +0 -1
  566. package/dist/flows/replay.js.map +0 -1
  567. package/dist/flows/server-verify.d.ts.map +0 -1
  568. package/dist/flows/server-verify.js.map +0 -1
  569. package/dist/flows/watch-batcher.d.ts.map +0 -1
  570. package/dist/flows/watch-batcher.js.map +0 -1
  571. package/dist/honesty/blind-spots.d.ts.map +0 -1
  572. package/dist/honesty/blind-spots.js.map +0 -1
  573. package/dist/honesty/honesty.d.ts.map +0 -1
  574. package/dist/honesty/honesty.js.map +0 -1
  575. package/dist/http-server.d.ts.map +0 -1
  576. package/dist/http-server.js.map +0 -1
  577. package/dist/idle-shutdown.d.ts.map +0 -1
  578. package/dist/idle-shutdown.js.map +0 -1
  579. package/dist/index.d.ts.map +0 -1
  580. package/dist/index.js.map +0 -1
  581. package/dist/init/agent-rules.d.ts.map +0 -1
  582. package/dist/init/agent-rules.js.map +0 -1
  583. package/dist/init/cursor.d.ts.map +0 -1
  584. package/dist/init/cursor.js.map +0 -1
  585. package/dist/init/detect.d.ts.map +0 -1
  586. package/dist/init/detect.js.map +0 -1
  587. package/dist/init/mcp.d.ts.map +0 -1
  588. package/dist/init/mcp.js.map +0 -1
  589. package/dist/init/node-io.d.ts.map +0 -1
  590. package/dist/init/node-io.js.map +0 -1
  591. package/dist/init/plan.d.ts.map +0 -1
  592. package/dist/init/plan.js.map +0 -1
  593. package/dist/init/project-id.d.ts.map +0 -1
  594. package/dist/init/project-id.js.map +0 -1
  595. package/dist/init/run.d.ts.map +0 -1
  596. package/dist/init/run.js.map +0 -1
  597. package/dist/init/snippets.d.ts.map +0 -1
  598. package/dist/init/snippets.js.map +0 -1
  599. package/dist/init/vite-config.d.ts.map +0 -1
  600. package/dist/init/vite-config.js.map +0 -1
  601. package/dist/input/network-detail.d.ts.map +0 -1
  602. package/dist/input/network-detail.js.map +0 -1
  603. package/dist/input/network-mock-tools.d.ts.map +0 -1
  604. package/dist/input/network-mock-tools.js.map +0 -1
  605. package/dist/input/network-mock.d.ts.map +0 -1
  606. package/dist/input/network-mock.js.map +0 -1
  607. package/dist/input/real-input.d.ts.map +0 -1
  608. package/dist/input/real-input.js.map +0 -1
  609. package/dist/input/scroll-find.d.ts.map +0 -1
  610. package/dist/input/scroll-find.js.map +0 -1
  611. package/dist/input/scroll-tools.d.ts.map +0 -1
  612. package/dist/input/scroll-tools.js.map +0 -1
  613. package/dist/input/viewport-tools.d.ts.map +0 -1
  614. package/dist/input/viewport-tools.js.map +0 -1
  615. package/dist/journal/ambient-store.d.ts.map +0 -1
  616. package/dist/journal/ambient-store.js.map +0 -1
  617. package/dist/journal/ambient.d.ts.map +0 -1
  618. package/dist/journal/ambient.js.map +0 -1
  619. package/dist/journal/attach-journal.d.ts.map +0 -1
  620. package/dist/journal/attach-journal.js.map +0 -1
  621. package/dist/journal/deviation-report.d.ts.map +0 -1
  622. package/dist/journal/deviation-report.js.map +0 -1
  623. package/dist/journal/deviation-service.d.ts.map +0 -1
  624. package/dist/journal/deviation-service.js.map +0 -1
  625. package/dist/journal/envelope-store.d.ts.map +0 -1
  626. package/dist/journal/envelope-store.js.map +0 -1
  627. package/dist/journal/envelope.d.ts.map +0 -1
  628. package/dist/journal/envelope.js.map +0 -1
  629. package/dist/journal/journal-query.d.ts.map +0 -1
  630. package/dist/journal/journal-query.js.map +0 -1
  631. package/dist/journal/journal-recorder.d.ts.map +0 -1
  632. package/dist/journal/journal-recorder.js.map +0 -1
  633. package/dist/journal/retention.d.ts.map +0 -1
  634. package/dist/journal/retention.js.map +0 -1
  635. package/dist/journal/rollups.d.ts.map +0 -1
  636. package/dist/journal/rollups.js.map +0 -1
  637. package/dist/journal/session-end.d.ts.map +0 -1
  638. package/dist/journal/session-end.js.map +0 -1
  639. package/dist/journal/session-journal.d.ts.map +0 -1
  640. package/dist/journal/session-journal.js.map +0 -1
  641. package/dist/license/license.d.ts.map +0 -1
  642. package/dist/license/license.js.map +0 -1
  643. package/dist/log.d.ts.map +0 -1
  644. package/dist/log.js.map +0 -1
  645. package/dist/mcp-proxy.d.ts.map +0 -1
  646. package/dist/mcp-proxy.js.map +0 -1
  647. package/dist/mcp.d.ts.map +0 -1
  648. package/dist/mcp.js.map +0 -1
  649. package/dist/oracles/flow-instrument-gaps.d.ts.map +0 -1
  650. package/dist/oracles/flow-instrument-gaps.js.map +0 -1
  651. package/dist/oracles/propose-consequences.d.ts.map +0 -1
  652. package/dist/oracles/propose-consequences.js.map +0 -1
  653. package/dist/oracles/self-instrument.d.ts.map +0 -1
  654. package/dist/oracles/self-instrument.js.map +0 -1
  655. package/dist/pairing-token.d.ts.map +0 -1
  656. package/dist/pairing-token.js.map +0 -1
  657. package/dist/phenomena/phenomena.d.ts.map +0 -1
  658. package/dist/phenomena/phenomena.js.map +0 -1
  659. package/dist/pool/browser-pool.d.ts.map +0 -1
  660. package/dist/pool/browser-pool.js.map +0 -1
  661. package/dist/pool/lease-reaper.d.ts.map +0 -1
  662. package/dist/pool/lease-reaper.js.map +0 -1
  663. package/dist/pool/playwright-launcher.d.ts.map +0 -1
  664. package/dist/pool/playwright-launcher.js.map +0 -1
  665. package/dist/project/baselines.d.ts.map +0 -1
  666. package/dist/project/baselines.js.map +0 -1
  667. package/dist/project/file-lock.d.ts.map +0 -1
  668. package/dist/project/file-lock.js.map +0 -1
  669. package/dist/project/fs-port.d.ts.map +0 -1
  670. package/dist/project/fs-port.js.map +0 -1
  671. package/dist/project/project-store.d.ts.map +0 -1
  672. package/dist/project/project-store.js.map +0 -1
  673. package/dist/project/project-tools.d.ts.map +0 -1
  674. package/dist/project/project-tools.js.map +0 -1
  675. package/dist/project/reticle-dir.d.ts.map +0 -1
  676. package/dist/project/reticle-dir.js.map +0 -1
  677. package/dist/runs/build-verification-run.d.ts.map +0 -1
  678. package/dist/runs/build-verification-run.js.map +0 -1
  679. package/dist/runs/profile-redact.d.ts.map +0 -1
  680. package/dist/runs/profile-redact.js.map +0 -1
  681. package/dist/runs/render-report.d.ts.map +0 -1
  682. package/dist/runs/render-report.js.map +0 -1
  683. package/dist/runs/repair-prompt.d.ts.map +0 -1
  684. package/dist/runs/repair-prompt.js.map +0 -1
  685. package/dist/runs/replay-mapping.d.ts.map +0 -1
  686. package/dist/runs/replay-mapping.js.map +0 -1
  687. package/dist/runs/reticle-runner.d.ts.map +0 -1
  688. package/dist/runs/reticle-runner.js.map +0 -1
  689. package/dist/runs/risk-classify.d.ts.map +0 -1
  690. package/dist/runs/risk-classify.js.map +0 -1
  691. package/dist/runs/run-diff.d.ts.map +0 -1
  692. package/dist/runs/run-diff.js.map +0 -1
  693. package/dist/runs/run-store.d.ts.map +0 -1
  694. package/dist/runs/run-store.js.map +0 -1
  695. package/dist/runs/run-tools.d.ts.map +0 -1
  696. package/dist/runs/run-tools.js.map +0 -1
  697. package/dist/runs/runner-port.d.ts.map +0 -1
  698. package/dist/runs/runner-port.js.map +0 -1
  699. package/dist/runs/verification-sync.d.ts.map +0 -1
  700. package/dist/runs/verification-sync.js.map +0 -1
  701. package/dist/runs/verify-http.d.ts.map +0 -1
  702. package/dist/runs/verify-http.js.map +0 -1
  703. package/dist/runs/verify-server.d.ts.map +0 -1
  704. package/dist/runs/verify-server.js.map +0 -1
  705. package/dist/server-version.d.ts.map +0 -1
  706. package/dist/server-version.js.map +0 -1
  707. package/dist/session/control-envelope.d.ts.map +0 -1
  708. package/dist/session/control-envelope.js.map +0 -1
  709. package/dist/session/live-control-tools.d.ts.map +0 -1
  710. package/dist/session/live-control-tools.js.map +0 -1
  711. package/dist/session/live-control.d.ts.map +0 -1
  712. package/dist/session/live-control.js.map +0 -1
  713. package/dist/session/observed-state.d.ts.map +0 -1
  714. package/dist/session/observed-state.js.map +0 -1
  715. package/dist/session/output-budget.d.ts.map +0 -1
  716. package/dist/session/output-budget.js.map +0 -1
  717. package/dist/session/presenter-args.d.ts.map +0 -1
  718. package/dist/session/presenter-args.js.map +0 -1
  719. package/dist/session/review-store.d.ts.map +0 -1
  720. package/dist/session/review-store.js.map +0 -1
  721. package/dist/session/session-health.d.ts.map +0 -1
  722. package/dist/session/session-health.js.map +0 -1
  723. package/dist/session/session-manager.d.ts.map +0 -1
  724. package/dist/session/session-manager.js.map +0 -1
  725. package/dist/session/session-readiness.d.ts.map +0 -1
  726. package/dist/session/session-readiness.js.map +0 -1
  727. package/dist/session/session-reaper.d.ts.map +0 -1
  728. package/dist/session/session-reaper.js.map +0 -1
  729. package/dist/session/session-recommendation.d.ts.map +0 -1
  730. package/dist/session/session-recommendation.js.map +0 -1
  731. package/dist/session/session-tools.d.ts.map +0 -1
  732. package/dist/session/session-tools.js.map +0 -1
  733. package/dist/session/session.d.ts.map +0 -1
  734. package/dist/session/session.js.map +0 -1
  735. package/dist/session/state-select.d.ts.map +0 -1
  736. package/dist/session/state-select.js.map +0 -1
  737. package/dist/telemetry/telemetry.d.ts.map +0 -1
  738. package/dist/telemetry/telemetry.js.map +0 -1
  739. package/dist/token-auth.d.ts.map +0 -1
  740. package/dist/token-auth.js.map +0 -1
  741. package/dist/tools/act-tools.d.ts.map +0 -1
  742. package/dist/tools/act-tools.js.map +0 -1
  743. package/dist/tools/act-view.d.ts.map +0 -1
  744. package/dist/tools/act-view.js.map +0 -1
  745. package/dist/tools/assert-grade.d.ts.map +0 -1
  746. package/dist/tools/assert-grade.js.map +0 -1
  747. package/dist/tools/browser-tools.d.ts.map +0 -1
  748. package/dist/tools/browser-tools.js.map +0 -1
  749. package/dist/tools/contract-tools.d.ts.map +0 -1
  750. package/dist/tools/contract-tools.js.map +0 -1
  751. package/dist/tools/dynamic-tools.d.ts.map +0 -1
  752. package/dist/tools/dynamic-tools.js.map +0 -1
  753. package/dist/tools/error-recovery.d.ts.map +0 -1
  754. package/dist/tools/error-recovery.js.map +0 -1
  755. package/dist/tools/invoke-tool.d.ts.map +0 -1
  756. package/dist/tools/invoke-tool.js.map +0 -1
  757. package/dist/tools/lease-tools.d.ts.map +0 -1
  758. package/dist/tools/lease-tools.js.map +0 -1
  759. package/dist/tools/merge-tools.d.ts.map +0 -1
  760. package/dist/tools/merge-tools.js.map +0 -1
  761. package/dist/tools/observe-tools.d.ts.map +0 -1
  762. package/dist/tools/observe-tools.js.map +0 -1
  763. package/dist/tools/profiles.d.ts.map +0 -1
  764. package/dist/tools/profiles.js.map +0 -1
  765. package/dist/tools/query-paginate.d.ts.map +0 -1
  766. package/dist/tools/query-paginate.js.map +0 -1
  767. package/dist/tools/read-tools.d.ts.map +0 -1
  768. package/dist/tools/read-tools.js.map +0 -1
  769. package/dist/tools/snapshot-delta.d.ts.map +0 -1
  770. package/dist/tools/snapshot-delta.js.map +0 -1
  771. package/dist/tools/tool-invoker.d.ts.map +0 -1
  772. package/dist/tools/tool-invoker.js.map +0 -1
  773. package/dist/tools/tool-kit.d.ts.map +0 -1
  774. package/dist/tools/tool-kit.js.map +0 -1
  775. package/dist/tools/tool-names.d.ts.map +0 -1
  776. package/dist/tools/tool-names.js.map +0 -1
  777. package/dist/tools/tools-helpers.d.ts.map +0 -1
  778. package/dist/tools/tools-helpers.js.map +0 -1
  779. package/dist/tools/tools.d.ts.map +0 -1
  780. package/dist/tools/tools.js.map +0 -1
  781. package/dist/update/update-checker.d.ts.map +0 -1
  782. package/dist/update/update-checker.js.map +0 -1
  783. package/dist/update/updater.d.ts.map +0 -1
  784. package/dist/update/updater.js.map +0 -1
  785. package/dist/visual/visual-diff.d.ts.map +0 -1
  786. package/dist/visual/visual-diff.js.map +0 -1
  787. package/dist/visual/visual-store.d.ts.map +0 -1
  788. package/dist/visual/visual-store.js.map +0 -1
  789. package/dist/visual/visual-tools.d.ts.map +0 -1
  790. package/dist/visual/visual-tools.js.map +0 -1
@@ -1,7 +1,13 @@
1
1
  import { healthEnvelope } from '../session/session-health.js';
2
- import { getTelemetry, TelemetryEventKind } from '../telemetry/telemetry.js';
2
+ import { TelemetryActor, TelemetryEventKind } from '@reticlehq/core';
3
+ import { getSessionMetrics } from '../telemetry/session-metrics.js';
4
+ import { getTelemetry } from '../telemetry/telemetry.js';
5
+ import { VERIFICATION_TOOLS } from './feedback-tools.js';
6
+ import { takeUpdateNudge } from '../update/update-nudge.js';
7
+ import { bugsInResult } from '../telemetry/bug-found.js';
3
8
  import { asString } from './tools-helpers.js';
4
9
  import { ReticleTool } from './tool-names.js';
10
+ import { takeFeedbackPrompt } from './feedback-tools.js';
5
11
  /**
6
12
  * The live-session tools whose result MUST carry the
7
13
  * session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
@@ -12,12 +18,17 @@ export const SESSION_BOUND_TOOLS = new Set([
12
18
  ReticleTool.SNAPSHOT,
13
19
  ReticleTool.QUERY,
14
20
  ReticleTool.INSPECT,
21
+ ReticleTool.COVERAGE,
22
+ ReticleTool.VERIFY_CHANGE,
15
23
  ReticleTool.ACT,
16
24
  ReticleTool.ACT_SEQUENCE,
17
25
  ReticleTool.ACT_AND_WAIT,
18
26
  ReticleTool.OBSERVE,
19
27
  ReticleTool.WAIT_FOR,
20
28
  ReticleTool.ASSERT,
29
+ // Reads the live page as well as the event window, so a throttled tab can make it compare a stale
30
+ // render against fresh data — exactly the case the health envelope exists to disclose.
31
+ ReticleTool.RECONCILE,
21
32
  ReticleTool.NETWORK,
22
33
  ReticleTool.CONSOLE,
23
34
  ReticleTool.ANIMATIONS,
@@ -56,10 +67,74 @@ export const SESSION_EXEMPT_TOOLS = new Set([
56
67
  ReticleTool.VIEWPORT, // own contract (applied/width/height); provider-driven, not a live-DOM read
57
68
  ReticleTool.ANNOTATE, // annotates a recording's steps; pure disk-side metadata, no live DOM read
58
69
  ReticleTool.LEASE, // merged acquire/release — its sessionId is a pool lease id, not a live session
70
+ // Its sessionId only enriches the report with the tab's runtime/engine, and it must stay callable
71
+ // when NO session exists — "nothing ever connected" is feedback we especially want.
72
+ ReticleTool.FEEDBACK,
59
73
  ]);
60
74
  function isPlainObject(value) {
61
75
  return typeof value === 'object' && value !== null && !Array.isArray(value);
62
76
  }
77
+ /**
78
+ * Emit `verification_completed` when a verification tool produced a verdict.
79
+ *
80
+ * Read off the RESULT here rather than emitted from `decideVerified`, which is where the verdict is
81
+ * actually decided: that function is pure, and the repo's rules keep clocks, IO and side effects out
82
+ * of pure logic for good reason. Reading the result also means all four verification tools are covered
83
+ * by one site instead of four handler edits, and a fifth is covered the moment it joins the set.
84
+ *
85
+ * `falseGreenCaught` is the one that matters: the assertion PASSED and Reticle still refused to call
86
+ * it verified. That is the product's entire thesis reduced to a boolean, and it is the number worth
87
+ * putting in front of an investor — not "tools were called" but "this many greens were caught lying".
88
+ */
89
+ function recordVerification(toolName, result, durationMs) {
90
+ if (!VERIFICATION_TOOLS.has(toolName))
91
+ return;
92
+ const verified = typeof result['verified'] === 'string' ? result['verified'] : undefined;
93
+ // flow_verify reports `status: pass|fail`; assert reports a boolean `pass`. Accept either shape so
94
+ // the whole family is covered without normalizing four tools' contracts for a metric's convenience.
95
+ const passed = typeof result['pass'] === 'boolean'
96
+ ? result['pass']
97
+ : result['status'] === 'pass'
98
+ ? true
99
+ : undefined;
100
+ if (verified === undefined && passed === undefined)
101
+ return; // not a verdict-bearing result
102
+ const metrics = getSessionMetrics();
103
+ metrics.recordVerification();
104
+ void getTelemetry().emit(TelemetryEventKind.VERIFICATION_COMPLETED, {
105
+ actor: TelemetryActor.AGENT,
106
+ verification: {
107
+ via: toolName,
108
+ verified: verified ?? (passed === true ? 'yes' : 'no'),
109
+ passed: passed ?? verified === 'yes',
110
+ falseGreenCaught: passed === true && verified === 'no',
111
+ durationMs,
112
+ },
113
+ });
114
+ }
115
+ /**
116
+ * Emit one `bug_found` per defect in a tool result, and count it into the session.
117
+ *
118
+ * The outcome metric: everything else measures whether Reticle is used, this measures whether it
119
+ * works. Discrete events rather than only a counter, because the KIND distribution is the argument —
120
+ * "we found 4,000 bugs" is a claim, "1,200 were greens that lied" is evidence.
121
+ */
122
+ function reportBugsFound(toolName, result) {
123
+ const bugs = bugsInResult(toolName, result);
124
+ if (bugs.length === 0)
125
+ return;
126
+ const metrics = getSessionMetrics();
127
+ for (const bug of bugs) {
128
+ // `recordBug` answers whether this kind is new to the session, which is the only thing that
129
+ // separates "another defect" from "the same defect again". Counting instances as defects is how
130
+ // a published number inflates itself.
131
+ const first = metrics.recordBug(bug.kind);
132
+ void getTelemetry().emit(TelemetryEventKind.BUG_FOUND, {
133
+ actor: TelemetryActor.AGENT,
134
+ bug: { ...bug, repeat: !first },
135
+ });
136
+ }
137
+ }
63
138
  /**
64
139
  * The single entry point both the MCP server and the programmatic invoker call instead of
65
140
  * `tool.handler` directly. Runs the handler, then — for a live-session tool returning a plain
@@ -68,8 +143,16 @@ function isPlainObject(value) {
68
143
  */
69
144
  export async function runTool(tool, deps, args) {
70
145
  // Both dispatch paths (MCP + programmatic) pass through here — the one place "which tool is mostly
71
- // used" can be counted. Fire-and-forget: telemetry never delays or fails a tool call.
72
- void getTelemetry().emit(TelemetryEventKind.TOOL, { tool: tool.name });
146
+ // used" can be counted. This used to EMIT an event per call; it now increments an in-process counter
147
+ // that leaves once, with the session summary. A verification loop is 50–200 calls, and PostHog bills
148
+ // per event — so the old design made the telemetry bill scale with how hard people used the product,
149
+ // to answer a question the histogram answers better. Counting is also free: no network, no promise,
150
+ // nothing to fail on a tool call's hot path.
151
+ // Started/settled as a pair rather than a bare counter: several agents can be inside runTool at
152
+ // once, so a single "last start" field would attribute one tool's duration to another. The returned
153
+ // closure carries this call's own identity, which is also what makes peak-concurrency measurable.
154
+ const settleTiming = getSessionMetrics().startToolCall(tool.name, args);
155
+ const startedAt = Date.now();
73
156
  const rawSessionId = asString(args['sessionId']);
74
157
  const bound = SESSION_BOUND_TOOLS.has(tool.name);
75
158
  // Resolve the session identity ONCE, up front, for a live-session tool. The lease heartbeat must
@@ -90,7 +173,35 @@ export async function runTool(tool, deps, args) {
90
173
  const leaseId = session?.id ?? rawSessionId;
91
174
  if (leaseId !== undefined)
92
175
  deps.pool?.touch(leaseId);
93
- const result = await tool.handler(deps, args);
176
+ let raw;
177
+ try {
178
+ raw = await tool.handler(deps, args);
179
+ }
180
+ finally {
181
+ // In a `finally` so a THROWN call still settles: otherwise every failing tool would leak a
182
+ // concurrency slot and peakConcurrentTools would climb forever on an unhealthy session.
183
+ settleTiming(Date.now() - startedAt);
184
+ }
185
+ // The human-feedback ask rides out on the first VERIFICATION that completes — the one moment the
186
+ // experience is fresh and there is something concrete to react to. It is spliced BEFORE the
187
+ // session-bound early return, because two of the four verification tools (flow_verify,
188
+ // verify_change) are session-EXEMPT and would otherwise never carry it.
189
+ if (isPlainObject(raw)) {
190
+ recordVerification(tool.name, raw, Date.now() - startedAt);
191
+ reportBugsFound(tool.name, raw);
192
+ }
193
+ const prompt = isPlainObject(raw) ? takeFeedbackPrompt(tool.name) : undefined;
194
+ // Same one-shot channel as the feedback ask: the agent is mid-task, so anything it would have to go
195
+ // and ASK for is something it will never ask for. Spliced on ANY tool result, not just a
196
+ // verification, because an out-of-date install is worth mentioning whatever the agent is doing.
197
+ const update = isPlainObject(raw) ? takeUpdateNudge() : undefined;
198
+ const result = prompt === undefined && update === undefined
199
+ ? raw
200
+ : {
201
+ ...raw,
202
+ ...(prompt !== undefined ? { feedback_prompt: prompt } : {}),
203
+ ...(update !== undefined ? { update_available: update } : {}),
204
+ };
94
205
  if (!bound || !isPlainObject(result))
95
206
  return result;
96
207
  // Reuse the session resolved above so the health envelope describes the SAME session the handler
@@ -112,4 +223,3 @@ export async function runTool(tool, deps, args) {
112
223
  envelope['session_age_warning'] = warning;
113
224
  return Object.keys(envelope).length > 0 ? { ...result, ...envelope } : result;
114
225
  }
115
- //# sourceMappingURL=invoke-tool.js.map
@@ -44,4 +44,3 @@ export declare function acquireLeasedSession(pool: {
44
44
  }>;
45
45
  export declare function waitForLeasedSession(isConnected: () => boolean, sleeper?: (ms: number) => Promise<void>, attempts?: number, pollMs?: number): Promise<boolean>;
46
46
  export declare const LEASE_TOOLS: ToolDef[];
47
- //# sourceMappingURL=lease-tools.d.ts.map
@@ -94,7 +94,7 @@ export async function waitForLeasedSession(isConnected, sleeper = sleep, attempt
94
94
  export const LEASE_TOOLS = [
95
95
  {
96
96
  name: ReticleTool.LEASE_ACQUIRE,
97
- description: 'Lease a fresh isolated headless browser context from the shared pool and navigate it to the app URL (the app must already be running and embed @reticlehq/core). Returns the sessionId the leased tab registers — pass it to other tools. The pool keeps all leases in ONE browser and caps concurrency; if at capacity this waits for a free slot. Release with reticle_lease_release when the flow is done.',
97
+ description: 'Lease a fresh isolated headless browser context from the shared pool and navigate it to the app URL (the app must already be running and embed @reticlehq/core). Returns the sessionId the leased tab registers — pass it to other tools. The pool keeps all leases in ONE browser and caps concurrency; if at capacity this waits for a free slot. Release with reticle_lease{action:"release"} when the flow is done.',
98
98
  inputSchema: {
99
99
  url: z
100
100
  .string()
@@ -120,7 +120,7 @@ export const LEASE_TOOLS = [
120
120
  throw new Error(POOL_UNAVAILABLE);
121
121
  const url = asString(args['url']);
122
122
  if (url === undefined || url.length === 0)
123
- throw new Error('reticle_lease_acquire requires a url');
123
+ throw new Error('reticle_lease{action:"acquire"} requires a url');
124
124
  const projectId = asString(args['projectId']);
125
125
  const sessionId = newLeaseId();
126
126
  const navUrl = appendReticleParams(url, sessionId, projectId);
@@ -153,7 +153,9 @@ export const LEASE_TOOLS = [
153
153
  name: ReticleTool.LEASE_RELEASE,
154
154
  description: 'Release a leased browser context by sessionId, closing it and freeing the pool slot for a queued acquire. Call this when a flow finishes so the pool stays within its concurrency cap.',
155
155
  inputSchema: {
156
- sessionId: z.string().describe('The leased sessionId returned by reticle_lease_acquire.'),
156
+ sessionId: z
157
+ .string()
158
+ .describe('The leased sessionId returned by reticle_lease{action:"acquire"}.'),
157
159
  },
158
160
  outputSchema: {
159
161
  released: z.boolean(),
@@ -165,11 +167,10 @@ export const LEASE_TOOLS = [
165
167
  throw new Error(POOL_UNAVAILABLE);
166
168
  const sessionId = asString(args['sessionId']);
167
169
  if (sessionId === undefined || sessionId.length === 0) {
168
- throw new Error('reticle_lease_release requires a sessionId');
170
+ throw new Error('reticle_lease{action:"release"} requires a sessionId');
169
171
  }
170
172
  await pool.release(sessionId);
171
173
  return { released: true, leased: pool.activeCount() };
172
174
  },
173
175
  },
174
176
  ];
175
- //# sourceMappingURL=lease-tools.js.map
@@ -40,4 +40,3 @@ export interface MergePlan {
40
40
  */
41
41
  export declare function applyMerges(tools: readonly ToolDef[], plans: readonly MergePlan[], retired?: readonly string[]): ToolDef[];
42
42
  export declare function mergeTools(spec: MergeSpec): ToolDef;
43
- //# sourceMappingURL=merge-tools.d.ts.map
@@ -63,4 +63,3 @@ export function mergeTools(spec) {
63
63
  },
64
64
  };
65
65
  }
66
- //# sourceMappingURL=merge-tools.js.map
@@ -1,3 +1,2 @@
1
1
  import { type ToolDef } from './tool-kit.js';
2
2
  export declare const OBSERVE_TOOLS: ToolDef[];
3
- //# sourceMappingURL=observe-tools.d.ts.map
@@ -6,12 +6,14 @@ import { z } from 'zod';
6
6
  import { ReticleCommand, DEFAULT_ASSERT_TIMEOUT_MS } from '@reticlehq/core';
7
7
  import { ReticleTool } from './tool-names.js';
8
8
  import { buildReactionReport } from '../events/reaction.js';
9
+ import { findContradictions } from '../events/contradictions.js';
9
10
  import { evaluatePredicate, waitForPredicate, PredicateSchema } from '../events/predicate.js';
10
11
  import { matchNet, matchConsole, isConsoleEvent, eventMatchesFilters, netEmptyHint, consoleEmptyHint, reconcileNet, projectNetCall, projectConsoleLog, } from '../events/event-filters.js';
11
12
  import { applyEventBudget, costHint, withSizeCost, DEFAULT_QUERY_LIMIT, } from '../session/output-budget.js';
12
13
  import { healthEnvelope, bufferEnvelope } from '../session/session-health.js';
13
- import { isPresenceOnlyAssertion, PRESENCE_ONLY_ADVICE } from './assert-grade.js';
14
- import { buildCoverageStatement, blindSpotsFromState } from '../honesty/blind-spots.js';
14
+ import { assertsDerivedIpcStatus, DERIVED_IPC_STATUS_ADVICE, isPresenceOnlyAssertion, PRESENCE_ONLY_ADVICE, } from './assert-grade.js';
15
+ import { assertVerdict } from './assert-verdict.js';
16
+ import { bodiesNotCaptured } from '../honesty/uncaptured-bodies.js';
15
17
  import { withControl } from '../session/control-envelope.js';
16
18
  import { asString, asNumber } from './tools-helpers.js';
17
19
  import { sessionIdShape, commandOrThrow } from './tool-kit.js';
@@ -39,18 +41,39 @@ const bufferOutputShape = {
39
41
  function lastActSourceOnFailure(session, pass) {
40
42
  if (pass)
41
43
  return {};
42
- const source = session.lastActSource();
44
+ const source = session.lastAct.source();
43
45
  return source === undefined ? {} : { source };
44
46
  }
47
+ /**
48
+ * Drop `sessionId` from an event in a response the caller scoped to ONE session.
49
+ *
50
+ * The caller passed that id in the request, so echoing it on every event is the request quoted back
51
+ * once per row. Measured on a live app it was 25% of a four-event `reticle_observe` payload, and it
52
+ * grows linearly with the timeline — a fifty-event window spends ~2.5KB restating a fact the caller
53
+ * supplied. The id stays on the wire between SDK and bridge, where events from different sessions
54
+ * really do interleave; it is only redundant at this boundary.
55
+ */
56
+ function withoutConstantSessionId(event) {
57
+ if (typeof event !== 'object' || event === null)
58
+ return event;
59
+ const { sessionId: _sessionId, ...rest } = event;
60
+ return rest;
61
+ }
45
62
  export const OBSERVE_TOOLS = [
46
63
  {
47
64
  name: ReticleTool.OBSERVE,
65
+ example: { since: 0 },
48
66
  description: 'Return the timeline of everything the app did in a window (DOM/network/route/console/animation/signal), with a summary. Use after an action. Pass `max_events` to cap the timeline to the most recent N (older events are dropped and counted in cost.droppedOldest). Every result carries a `cost:{events,bytes}` hint so you can self-budget your next call.',
49
67
  inputSchema: {
50
68
  window_ms: z
51
69
  .number()
70
+ .positive()
71
+ // A non-positive window silently produced a FUTURE cursor, so the tool returned zero events
72
+ // and echoed the nonsense value back — indistinguishable from a genuinely quiet page. An
73
+ // agent that fumbles this argument gets a clean "nothing happened" instead of being told the
74
+ // question was malformed, which is the exact confusion this layer exists to refuse.
52
75
  .optional()
53
- .describe('Time window to look back. Default: 2000ms. Ignored when `since` is provided.'),
76
+ .describe('Time window to look back, in ms (must be > 0). Default: 2000. Ignored when `since` is provided.'),
54
77
  since: z
55
78
  .number()
56
79
  .optional()
@@ -71,6 +94,7 @@ export const OBSERVE_TOOLS = [
71
94
  'type (e.g. "net.request"). Omit to return all types.'),
72
95
  max_events: z
73
96
  .number()
97
+ .nonnegative()
74
98
  .optional()
75
99
  .describe('Cap the timeline to the most recent N events. Older events are counted in cost.droppedOldest.'),
76
100
  ...sessionIdShape,
@@ -91,6 +115,17 @@ export const OBSERVE_TOOLS = [
91
115
  animations: z.number(),
92
116
  signals: z.number(),
93
117
  }),
118
+ // Cross-channel disagreement in this window. Omitted when there is none, so a clean action
119
+ // costs zero tokens and a contradiction is impossible to scroll past.
120
+ contradictions: z
121
+ .array(z.object({
122
+ kind: z.string(),
123
+ claim: z.string(),
124
+ counter: z.string(),
125
+ detail: z.string(),
126
+ }))
127
+ .optional()
128
+ .describe('Channels that DISAGREE about this action — e.g. the UI advanced while its request failed. Each is a false green: the screen looks right and the app is wrong.'),
94
129
  cost: z.object({
95
130
  events: z.number(),
96
131
  bytes: z.number(),
@@ -121,9 +156,22 @@ export const OBSERVE_TOOLS = [
121
156
  // Output budget: cap to the most recent N (no silent caps — droppedOldest is surfaced in cost).
122
157
  const { events: budgeted, droppedOldest } = applyEventBudget(filtered, asNumber(args['max_events']));
123
158
  const report = buildReactionReport(budgeted, windowMs);
159
+ // Run over the FILTERED-but-unbudgeted window: a contradiction must not vanish because the
160
+ // timeline was capped for tokens. Detection is cheap; the events are already in hand.
161
+ // The act that opened this window is not in `args` — observe is a separate call — so its action
162
+ // and in-target mutation count are read back off the session. Without them the "this click did
163
+ // nothing" check is unreachable on the ordinary act-then-observe flow, which is most of them.
164
+ // Only when the act actually falls inside the window being judged — judging a click with a
165
+ // window that starts after it would accuse a control of doing nothing during a period it was
166
+ // never asked about.
167
+ const actCursor = session.lastAct.cursor();
168
+ const judgingTheAct = actCursor !== undefined && actCursor >= since;
169
+ const contradictions = findContradictions(filtered, judgingTheAct ? session.lastAct.effect() : {});
124
170
  // carry session health — a throttled tab means the observed timeline may be incomplete.
125
171
  return withControl(session, {
126
172
  ...report,
173
+ events: report.events.map(withoutConstantSessionId),
174
+ ...(contradictions.length > 0 ? { contradictions } : {}),
127
175
  cost: costHint(report, budgeted.length, droppedOldest),
128
176
  ...healthEnvelope(session),
129
177
  ...bufferEnvelope(session),
@@ -132,9 +180,10 @@ export const OBSERVE_TOOLS = [
132
180
  },
133
181
  {
134
182
  name: ReticleTool.WAIT_FOR,
183
+ example: { predicate: { kind: 'state', path: 'todos.length', equals: 3 } },
135
184
  description: 'Block until a predicate is satisfied (or already true in the recent buffer), else time out. Returns matching evidence or a near-miss diagnosis. By default it only counts events since your last act, so a signal buffered BEFORE the action can never fake a pass; pass `since` (an observe/act cursor) to widen or narrow that window explicitly.',
136
185
  inputSchema: {
137
- predicate: PredicateSchema.describe('Predicate to wait for: { signal }, { net }, { element }, { kind: "state", store, path, equals } (assert a registered store\'s value directly — the source of truth no DOM read can reach; equals takes a literal or { $gte | $contains | $length } pattern), { kind: "settled", quietMs } (deterministic network + DOM idle — prefer this over a fixed sleep), or a combination via allOf/anyOf.'),
186
+ predicate: PredicateSchema.describe('Predicate to wait for: { signal }, { net }, { element }, { kind: "net", ok: false } (assert on the OUTCOME — the honest field for IPC, which has no status code), { kind: "state", store, path, equals } (assert a registered store\'s value directly — the source of truth no DOM read can reach; equals takes a literal or { $gte | $contains | $length } pattern), { kind: "settled", quietMs } (deterministic network + DOM idle — prefer this over a fixed sleep), or a combination via allOf/anyOf.'),
138
187
  timeout_ms: z.number().optional().describe('Maximum wait in milliseconds. Default: 4000.'),
139
188
  since: z
140
189
  .number()
@@ -171,7 +220,7 @@ export const OBSERVE_TOOLS = [
171
220
  const session = deps.sessions.resolve(asString(args['sessionId']));
172
221
  const predicate = PredicateSchema.parse(args['predicate']);
173
222
  // Honesty: explicit since wins; else default to the last act's cursor; else the whole buffer.
174
- const since = asNumber(args['since']) ?? session.lastActCursor() ?? 0;
223
+ const since = asNumber(args['since']) ?? session.lastAct.cursor() ?? 0;
175
224
  const verdict = await waitForPredicate(session, predicate, asNumber(args['timeout_ms']) ?? DEFAULT_ASSERT_TIMEOUT_MS, since);
176
225
  // match reticle_assert — wrap with control + session health (throttle matters most while blocking)
177
226
  // and the buffer envelope, so a verdict reached over an evicted window says so.
@@ -185,6 +234,7 @@ export const OBSERVE_TOOLS = [
185
234
  },
186
235
  {
187
236
  name: ReticleTool.ASSERT,
237
+ example: { predicate: { kind: 'signal', name: 'todos:loaded' } },
188
238
  description: 'Evaluate a predicate (optionally waiting up to timeout_ms). Returns { pass, evidence, failureReason? }. The end of every verify loop. Prefer a { signal } or { net } consequence over { element }/{ text } presence — a passing presence-only assertion returns `advice` because a wrong/healed element can fake it. By default it only counts events since your last act, so a stale buffered signal can never fake a pass; pass `since` (an observe/act cursor) to set the window explicitly.',
189
239
  inputSchema: {
190
240
  predicate: PredicateSchema.describe('Predicate to evaluate: { signal }, { net }, { element } or a combination.'),
@@ -240,40 +290,27 @@ export const OBSERVE_TOOLS = [
240
290
  const predicate = PredicateSchema.parse(args['predicate']);
241
291
  const timeout = asNumber(args['timeout_ms']) ?? 0;
242
292
  // Honesty: explicit since wins; else default to the last act's cursor; else the whole buffer.
243
- const since = asNumber(args['since']) ?? session.lastActCursor() ?? 0;
293
+ const since = asNumber(args['since']) ?? session.lastAct.cursor() ?? 0;
244
294
  const verdict = timeout > 0
245
295
  ? await waitForPredicate(session, predicate, timeout, since)
246
296
  : await evaluatePredicate(session, predicate, since);
247
297
  // A GREEN presence-only assertion is the dangerous case (a wrong element can fake it) — nudge
248
298
  // toward a consequence. Never on a failing verdict (moot) or when a signal/net is asserted.
249
- const advice = verdict.pass && isPresenceOnlyAssertion(predicate) ? { advice: PRESENCE_ONLY_ADVICE } : {};
250
- // A verdict reached over an evicted buffer can be a FALSE NEGATIVE: "no console error" may
251
- // simply mean the error aged out. reticle_console has always disclosed this on the same window;
252
- // the verdict path — the one an agent actually gates on — did not. Omitted when nothing dropped.
253
- // Coverage, on the verdict an agent actually gates on.
254
- //
255
- // Scope caveat, stated because it is a real limitation and not a bug: blind spots are tracked
256
- // per SESSION, not per assertion window. So a cross-origin iframe seen once marks every later
257
- // verdict in that session partial, including ones about a region it cannot affect. That errs
258
- // toward over-warning, which is the correct direction for an honesty signal — the failure this
259
- // guards against is a green that implies coverage it never had, and the opposite error (a
260
- // needless caveat) costs the agent a sentence.
261
- //
262
- // act_and_wait has always disclosed this; plain assert did not — so a GREEN assert on a page
263
- // with a cross-origin iframe or a closed shadow root read as "the page is correct" when the
264
- // honest claim is "nothing failed in the part I could see". That is the false-green shape this
265
- // project exists to prevent, sitting on the most-used verdict path. Omitted entirely when
266
- // coverage is full, so an intact page pays nothing and the field's PRESENCE is the warning.
267
- const spots = blindSpotsFromState(session.blindSpots());
268
- const statement = buildCoverageStatement(spots);
269
- const coverage = statement.coverage === 'partial'
270
- ? {
271
- coverage: statement.note ?? 'partial',
272
- coverage_spots: statement.spots.map((sp) => ({ kind: sp.kind, count: sp.count })),
273
- }
274
- : {};
299
+ // Two nudges, both only on a GREEN verdict (a failing one is moot): a presence-only assertion
300
+ // a wrong element can fake, and an assertion pinned to a status Reticle derived rather than one
301
+ // a server sent. Neither blocks — the assertion still passes; they steer the next one.
302
+ const advice = !verdict.pass
303
+ ? {}
304
+ : isPresenceOnlyAssertion(predicate)
305
+ ? { advice: PRESENCE_ONLY_ADVICE }
306
+ : assertsDerivedIpcStatus(predicate)
307
+ ? { advice: DERIVED_IPC_STATUS_ADVICE }
308
+ : {};
309
+ const { decision, contradictions, coverage } = await assertVerdict(session, predicate, verdict.pass, since);
275
310
  return withControl(session, {
311
+ ...decision,
276
312
  ...verdict,
313
+ ...(contradictions.length > 0 ? { contradictions } : {}),
277
314
  ...advice,
278
315
  ...coverage,
279
316
  ...lastActSourceOnFailure(session, verdict.pass),
@@ -284,7 +321,8 @@ export const OBSERVE_TOOLS = [
284
321
  },
285
322
  {
286
323
  name: ReticleTool.NETWORK,
287
- description: 'Filtered list of network calls. Fast path for "did POST /x return 200?". A zero-match filter returns a `hint` { totalInWindow, present[] } of the calls that DID fire, so a miss is diagnosable.',
324
+ example: { urlContains: '/api/todos', method: 'POST' },
325
+ description: 'Filtered list of network calls. Fast path for "did POST /x return 200?". A zero-match filter returns a `hint` { totalInWindow, present[] } of the calls that DID fire, so a miss is diagnosable. Desktop IPC (`ipc://`) has no status code — the 200/500 there is derived, so filter on `ok` for those.',
288
326
  inputSchema: {
289
327
  since: z
290
328
  .number()
@@ -304,8 +342,13 @@ export const OBSERVE_TOOLS = [
304
342
  .describe('HTTP method filter: GET | POST | PUT | DELETE | PATCH etc.'),
305
343
  urlContains: z.string().optional().describe('Substring that the request URL must contain.'),
306
344
  status: z.number().optional().describe('HTTP status code filter (e.g. 200, 404, 500).'),
345
+ ok: z
346
+ .boolean()
347
+ .optional()
348
+ .describe('Outcome filter: false keeps only calls that FAILED, true only those that succeeded. The filter to use for desktop IPC (`ipc://`), whose status code is derived. A still-pending call matches neither.'),
307
349
  limit: z
308
350
  .number()
351
+ .nonnegative()
309
352
  .optional()
310
353
  .describe('Keep only the most recent N matching calls (older are dropped and counted in droppedOldest) — cuts tokens on a wide window. Defaults to 200 when omitted; pass a higher number for more, or scope with since/until.'),
311
354
  ...sessionIdShape,
@@ -318,6 +361,10 @@ export const OBSERVE_TOOLS = [
318
361
  .describe('Total matches before `limit` — present only when capped.'),
319
362
  droppedOldest: z.number().optional().describe('How many older matches `limit` dropped.'),
320
363
  hint: z.object({ totalInWindow: z.number(), present: z.array(z.string()) }).optional(),
364
+ bodiesNotCaptured: z
365
+ .string()
366
+ .optional()
367
+ .describe('Present when a POST/PUT/PATCH was returned and body capture is OFF — an absent body means unseen, not empty. Carries the one-line fix.'),
321
368
  cost: z.object({ bytes: z.number(), tokens: z.number() }).optional(),
322
369
  ...bufferOutputShape,
323
370
  },
@@ -327,6 +374,7 @@ export const OBSERVE_TOOLS = [
327
374
  const method = asString(args['method']);
328
375
  const urlContains = asString(args['urlContains']);
329
376
  const status = asNumber(args['status']);
377
+ const ok = typeof args['ok'] === 'boolean' ? args['ok'] : undefined;
330
378
  const limit = asNumber(args['limit']);
331
379
  const buffer = bufferEnvelope(session);
332
380
  // Completed calls + unresolved in-flight requests (a hung request shows as pending).
@@ -335,7 +383,7 @@ export const OBSERVE_TOOLS = [
335
383
  until: asNumber(args['until']),
336
384
  actionId: asString(args['actionId']),
337
385
  }));
338
- const matched = allNet.filter((e) => matchNet(e, method, urlContains, status));
386
+ const matched = allNet.filter((e) => matchNet(e, method, urlContains, status, ok));
339
387
  // zero-match filter returns what DID fire, not a bare [].
340
388
  if (matched.length === 0 && allNet.length > 0) {
341
389
  return withSizeCost({ calls: matched, hint: netEmptyHint(allNet), ...buffer });
@@ -343,13 +391,17 @@ export const OBSERVE_TOOLS = [
343
391
  // Default the cap so an omitted `limit` can't dump a whole flooded session (since defaults to 0).
344
392
  const { events: budgeted, droppedOldest } = applyEventBudget(matched, limit ?? DEFAULT_QUERY_LIMIT);
345
393
  const calls = budgeted.map(projectNetCall);
346
- return withSizeCost(droppedOldest > 0
347
- ? { calls, total: matched.length, droppedOldest, ...buffer }
348
- : { calls, ...buffer });
394
+ return withSizeCost({
395
+ calls,
396
+ ...(droppedOldest > 0 ? { total: matched.length, droppedOldest } : {}),
397
+ ...bodiesNotCaptured(calls),
398
+ ...buffer,
399
+ });
349
400
  },
350
401
  },
351
402
  {
352
403
  name: ReticleTool.CONSOLE,
404
+ example: { level: 'error' },
353
405
  description: 'Console/error log. Fast path for "were there any errors during this flow?". When a level filter matches nothing, returns a `hint` { totalInWindow, byLevel } so 0 errors is distinguishable from a silent page.',
354
406
  inputSchema: {
355
407
  level: z
@@ -370,6 +422,7 @@ export const OBSERVE_TOOLS = [
370
422
  .describe('Keep only log entries attributed to this action — "what did action N log".'),
371
423
  limit: z
372
424
  .number()
425
+ .nonnegative()
373
426
  .optional()
374
427
  .describe('Keep only the most recent N matching entries (older are dropped and counted in droppedOldest) — cuts tokens when a page spams the console. Defaults to 200 when omitted; pass a higher number for more, or scope with since/until.'),
375
428
  ...sessionIdShape,
@@ -419,4 +472,3 @@ export const OBSERVE_TOOLS = [
419
472
  handler: (deps, args) => commandOrThrow(deps, asString(args['sessionId']), ReticleCommand.ANIMATIONS, {}),
420
473
  },
421
474
  ];
422
- //# sourceMappingURL=observe-tools.js.map
@@ -6,7 +6,7 @@ import type { ToolDef } from './tools.js';
6
6
  *
7
7
  * MEASURED surface sizes (assert them with profile-reachability.test.ts rather than trusting prose —
8
8
  * every count previously written here was wrong, and the token figures below derive from those counts):
9
- * core 14 · standard 32 · hybrid 14 · full 41 · dynamic 2
9
+ * core 15 · standard 32 · hybrid 15 · full 43 · dynamic 2
10
10
  * core and hybrid are both 14 because a trimmed profile now also advertises the two meta-tools, which
11
11
  * is what keeps an un-advertised tool reachable through reticle_run.
12
12
  *
@@ -35,4 +35,3 @@ export declare const TOOL_PROFILE_ENV = "RETICLE_TOOL_PROFILE";
35
35
  export declare const CORE_TOOL_NAMES: ReadonlySet<string>;
36
36
  export declare function resolveToolProfile(explicit?: string): ToolProfile;
37
37
  export declare function filterTools(tools: ToolDef[], profile: ToolProfile): ToolDef[];
38
- //# sourceMappingURL=profiles.d.ts.map
@@ -6,7 +6,7 @@ import { ReticleTool } from './tool-names.js';
6
6
  *
7
7
  * MEASURED surface sizes (assert them with profile-reachability.test.ts rather than trusting prose —
8
8
  * every count previously written here was wrong, and the token figures below derive from those counts):
9
- * core 14 · standard 32 · hybrid 14 · full 41 · dynamic 2
9
+ * core 15 · standard 32 · hybrid 15 · full 43 · dynamic 2
10
10
  * core and hybrid are both 14 because a trimmed profile now also advertises the two meta-tools, which
11
11
  * is what keeps an un-advertised tool reachable through reticle_run.
12
12
  *
@@ -32,22 +32,37 @@ export const TOOL_PROFILE = {
32
32
  };
33
33
  export const TOOL_PROFILE_ENV = 'RETICLE_TOOL_PROFILE';
34
34
  // The set an agent needs to verify a change end-to-end. Tool DEFINITIONS are re-sent every turn, so a
35
- // smaller surface compounds. Measured per-turn surface cost (bench/first-drive, o200k proxy):
36
- // core 6,479 tok · standard 13,951 · full 20,441 — the hybrid default is far cheaper per turn than
37
- // advertising everything. STALE: these were measured against a 12/40/56-tool surface that no longer
38
- // exists (it is now 14/32/41 after the merge and the escape-hatch change), so treat the ratio as
39
- // directional and the absolute numbers as needing a re-measure before they are quoted anywhere.
35
+ // smaller surface compounds.
36
+ //
37
+ // MEASURED per-turn `tools/list` cost — the bytes an MCP client re-sends EVERY turn — taken off the
38
+ // real wire (spawn `mcp`, read tools/list, measure the serialized result), not estimated:
39
+ //
40
+ // dynamic 2 tools 1,531 B ~383 tok/turn
41
+ // core 15 tools 14,104 B ~3,526 tok/turn
42
+ // hybrid 15 tools 14,104 B ~3,526 tok/turn
43
+ // standard 32 tools 26,769 B ~6,692 tok/turn
44
+ // full 43 tools 105,061 B ~26,265 tok/turn
45
+ //
46
+ // These REPLACE the previous figures (core 6,479 / standard 13,951 / full 20,441), which the comment
47
+ // itself flagged as stale. Two of the three moved in opposite directions, which is why re-measuring
48
+ // mattered: the lean profiles got much CHEAPER because they now drop the advertised outputSchema,
49
+ // while `full` got much more EXPENSIVE because it still carries it — the gap between lean and full is
50
+ // 7.4x, not the ~3x the old numbers implied.
51
+ //
52
+ // Where the remaining cost sits, on the hybrid default: inputSchema is 76% of the payload (parameter
53
+ // descriptions are half of that), tool descriptions are 12%, and outputSchema is already ~0. So the
54
+ // next real saving is in parameter prose, not in dropping more tools.
40
55
  //
41
56
  // There is a floor, though: an 8-tool cut (dropping act/navigate/wait_for/sessions) was MEASURED to
42
- // regress real-agent accuracy 5/5 → 3/5, because the model loses scaffolding and wanders on harder
43
- // flows. These 12 are the lean sweet spot. Direct network/console stay (far more discoverable than
44
- // observe-with-filters → fewer turns, better verdicts).
57
+ // regress real-agent accuracy 5/5 -> 3/5, because the model loses scaffolding and wanders on harder
58
+ // flows. Direct network/console stay (far more discoverable than observe-with-filters -> fewer turns,
59
+ // better verdicts).
45
60
  //
46
- // Evidence status: the original 5/5 figure came from a single gpt-4o run and is STALE as a
47
- // justification. Current-model evidence is indirect but real — the cost-delta run
48
- // (bench/fix-loop/COST-DELTA.md) drove this hybrid default on a current model and fixed 4/4 cells with
49
- // ~25% FEWER tool calls than the baseline. A formal core-vs-hybrid A/B on a current model is
50
- // still UNRUN; do not quote the 5/5 number as if it were current. See bench/agent-loop-and-replay.md.
61
+ // Evidence status: the 5/5 figure came from a single gpt-4o run and is STALE as a justification.
62
+ // Current-model evidence is indirect but real — the cost-delta run (bench/fix-loop/COST-DELTA.md)
63
+ // drove this hybrid default on a current model and fixed 4/4 cells with ~25% FEWER tool calls than
64
+ // the baseline. A formal core-vs-hybrid A/B on a current model is still UNRUN; do not quote the 5/5
65
+ // number as if it were current. See bench/agent-loop-and-replay.md.
51
66
  export const CORE_TOOL_NAMES = new Set([
52
67
  ReticleTool.SESSIONS,
53
68
  ReticleTool.NAVIGATE,
@@ -61,11 +76,24 @@ export const CORE_TOOL_NAMES = new Set([
61
76
  ReticleTool.WAIT_FOR,
62
77
  ReticleTool.ASSERT,
63
78
  ReticleTool.STATE,
79
+ // INSPECT is what turns a finding into an EDIT: it maps a DOM node to `src/App.tsx:104`. Finding a
80
+ // bug is half the job; knowing which file to open is the half that makes the agent useful, and it
81
+ // is the one capability here with no substitute in any other verification tool. It sat in
82
+ // `standard`, so under the default profile an agent had to already know it existed and reach it
83
+ // through reticle_run — which, observed over a full 43-tool drive, means it never gets called.
84
+ // The measured floor that justifies a lean core was about CUTTING to 8 (accuracy 5/5 → 3/5), not
85
+ // about holding at 12; one tool of schema tax to close the find→fix loop is the right trade.
86
+ ReticleTool.INSPECT,
87
+ // FEEDBACK is in every profile for the same reason INSPECT is: a tool an agent has to already know
88
+ // about, and reach through reticle_run, is a tool that never gets called. That is fatal here in a way
89
+ // it is not elsewhere — an unadvertised feedback channel collects nothing, which is indistinguishable
90
+ // from not having built one. It is also the cheapest tool on the surface to carry (three params) and
91
+ // the only one whose whole purpose is telling us which of the other fifteen are failing.
92
+ ReticleTool.FEEDBACK,
64
93
  ]);
65
94
  const STANDARD_TOOL_NAMES = new Set([
66
95
  ...CORE_TOOL_NAMES,
67
96
  ReticleTool.ACT_SEQUENCE,
68
- ReticleTool.INSPECT,
69
97
  ReticleTool.NETWORK,
70
98
  ReticleTool.CONSOLE,
71
99
  ReticleTool.ANIMATIONS,
@@ -109,4 +137,3 @@ export function filterTools(tools, profile) {
109
137
  return tools.filter((t) => STANDARD_TOOL_NAMES.has(t.name));
110
138
  return tools;
111
139
  }
112
- //# sourceMappingURL=profiles.js.map
@@ -19,4 +19,3 @@
19
19
  * number that is silently wrong. `count` survives because it is a scalar. Trust it over the array.
20
20
  */
21
21
  export declare function paginateQueryResult(result: unknown, limit: number | undefined, countOnly: boolean): unknown;
22
- //# sourceMappingURL=query-paginate.d.ts.map
@@ -45,4 +45,3 @@ export function paginateQueryResult(result, limit, countOnly) {
45
45
  return { ...record, total, truncated: true };
46
46
  return result;
47
47
  }
48
- //# sourceMappingURL=query-paginate.js.map
@@ -1,3 +1,2 @@
1
1
  import { type ToolDef } from './tool-kit.js';
2
2
  export declare const READ_TOOLS: ToolDef[];
3
- //# sourceMappingURL=read-tools.d.ts.map