@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
package/dist/mcp.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
2
3
  import { z } from 'zod';
3
4
  import { isToonable, resultToToon } from '@reticlehq/core';
4
5
  import { TOOLS } from './tools/tools.js';
@@ -10,6 +11,8 @@ import { buildErrorPayload } from './tools/error-recovery.js';
10
11
  import { log } from './log.js';
11
12
  import { SERVER_VERSION } from './server-version.js';
12
13
  import { MCP_SERVER_NAME } from './init/mcp.js';
14
+ import { setMcpClientNameHook } from './telemetry/feedback-context.js';
15
+ import { getSessionMetrics } from './telemetry/session-metrics.js';
13
16
  /**
14
17
  * Merge the runtime-spliced envelope (health/lease/age/control) into a session-bound tool's declared
15
18
  * outputSchema so structuredContent validation keeps those fields instead of dropping them. The tool's
@@ -25,10 +28,31 @@ const SERVER_INFO = { name: MCP_SERVER_NAME, version: SERVER_VERSION };
25
28
  /** First sentence of a description (purpose only) for lean profiles — keeps per-turn def cost
26
29
  * down. Cuts at the first sentence-ending period or newline; falls back to a 160-char cap. The
27
30
  * first clause retains the essentials (enum hints like "role | text | label" live there). */
28
- function firstSentence(description) {
31
+ /**
32
+ * Append the tool's example call to whatever description survived trimming.
33
+ *
34
+ * Costs a handful of tokens per turn and buys back the failed round trips an agent spends guessing
35
+ * how the fields compose — which is a far worse trade in the other direction.
36
+ */
37
+ function withExample(description, example) {
38
+ return example === undefined ? description : `${description} e.g. ${JSON.stringify(example)}`;
39
+ }
40
+ /**
41
+ * Abbreviations whose internal period is NOT a sentence end.
42
+ *
43
+ * The splitter looked for the first `". "`, which "e.g. " satisfies — so every lean-profile
44
+ * description containing one was cut off mid-abbreviation. `reticle_act`'s ref parameter reached the
45
+ * agent as "Element ref from reticle_snapshot or reticle_query (e.g." and stopped: the example gone,
46
+ * and any contract stated after it gone too. Silent, and it degraded the DEFAULT profile only, which
47
+ * is the one nobody reads the raw strings for.
48
+ */
49
+ const ABBREVIATIONS = ['e.g.', 'i.e.', 'etc.', 'vs.', 'cf.'];
50
+ export function firstSentence(description) {
29
51
  const nl = description.indexOf('\n');
30
52
  const base = nl >= 0 ? description.slice(0, nl) : description;
31
- const dot = base.search(/\.\s/);
53
+ // Mask abbreviations with an equal-length filler so offsets stay valid in the original string.
54
+ const masked = ABBREVIATIONS.reduce((text, abbr) => text.split(abbr).join('\u0000'.repeat(abbr.length)), base);
55
+ const dot = masked.search(/\.\s/);
32
56
  const sentence = dot >= 0 ? base.slice(0, dot + 1) : base;
33
57
  return sentence.length > 160 ? `${sentence.slice(0, 159)}…` : sentence;
34
58
  }
@@ -52,9 +76,34 @@ const PREDICATE_PARAMS = new Set(['predicate', 'until']);
52
76
  * grammar up front versus letting the agent fetch it from `reticle_tools` when it needs a variant it
53
77
  * has not used before.
54
78
  */
55
- const COMPACT_PREDICATE_DESCRIPTION = 'Predicate object: { kind, ...fields }. kind is one of element | text | net | route | console | ' +
56
- 'animation | signal | state | settled | allOf | anyOf | not. Call reticle_tools for the full ' +
57
- 'field grammar of a kind.';
79
+ /**
80
+ * The kind list — the part an agent needs to WRITE a predicate. Carried on every predicate parameter.
81
+ *
82
+ * An earlier version put this on one tool and pointed the other five at it ("same grammar as
83
+ * reticle_act_and_wait's"), which saved 790 B/turn. It was the wrong trade: it made writing a
84
+ * predicate require joining two tool descriptions, and accuracy is worth more here than the bytes.
85
+ * Only the "where to get field details" sentence is stated once now — that one IS a pointer, so
86
+ * making it a pointer costs nothing.
87
+ */
88
+ const PREDICATE_KINDS = 'Predicate object: { kind, ...fields }. kind is one of element | text | net | route | console | ' +
89
+ 'animation | signal | state | settled | allOf | anyOf | not.';
90
+ /**
91
+ * Said once per turn: the bug-catching options, and where to get the rest of the field grammar.
92
+ *
93
+ * `net.count`, `console.absent` and `absent` are the three predicate options that catch a class of
94
+ * bug rather than confirm an expectation — a double-submit, an action that "worked" while logging a
95
+ * caught error, something that should have disappeared and did not. They sat behind a
96
+ * `reticle_tools` round trip, so an agent only found them if it already knew to look, which is the
97
+ * wrong way round for the checks most likely to catch what nobody suspected.
98
+ *
99
+ * Anchored to one tool rather than repeated on all six: these are ADDITIONAL capability, not what
100
+ * makes a basic predicate correct, so one mention per turn is enough to make them reachable without
101
+ * paying for six.
102
+ */
103
+ const PREDICATE_FIELD_GRAMMAR_HINT = ' Bug-catching options: net.count (exact request count — catches double-submit), ' +
104
+ 'console.absent:true (action completed with a CLEAN console), absent:true on element/text ' +
105
+ '(it should be gone). Call reticle_tools for the full field grammar of a kind.';
106
+ const COMPACT_PREDICATE_DESCRIPTION = `${PREDICATE_KINDS}${PREDICATE_FIELD_GRAMMAR_HINT}`;
58
107
  /**
59
108
  * Lean copy of a tool's zod input shape for lean profiles: each parameter's description is
60
109
  * truncated to its first sentence via zod's own `.describe` (which returns a new schema, so the
@@ -62,11 +111,14 @@ const COMPACT_PREDICATE_DESCRIPTION = 'Predicate object: { kind, ...fields }. ki
62
111
  * schema cost; the first clause keeps each param's purpose and any enum hints. Params without a
63
112
  * description pass through unchanged. Predicate params are replaced wholesale — see above.
64
113
  */
65
- function leanZodShape(shape) {
114
+ function leanZodShape(shape, predicateAnchor) {
66
115
  const out = {};
67
116
  for (const [key, schema] of Object.entries(shape)) {
68
117
  if (PREDICATE_PARAMS.has(key)) {
69
- const compact = z.record(z.unknown()).describe(COMPACT_PREDICATE_DESCRIPTION);
118
+ // Every tool keeps the kinds; only the navigation hint is anchored to one.
119
+ const compact = z
120
+ .record(z.unknown())
121
+ .describe(predicateAnchor === undefined ? COMPACT_PREDICATE_DESCRIPTION : PREDICATE_KINDS);
70
122
  out[key] = schema.isOptional() ? compact.optional() : compact;
71
123
  continue;
72
124
  }
@@ -112,9 +164,84 @@ export function advertisedTools(profile) {
112
164
  const base = filterTools(TOOLS, profile === TOOL_PROFILE.HYBRID ? TOOL_PROFILE.CORE : profile);
113
165
  return [...base, ...buildDynamicTools(TOOLS)];
114
166
  }
167
+ /**
168
+ * Exactly what gets advertised for one tool under a profile: trimmed description, lean input shape,
169
+ * and (non-lean only) the output schema.
170
+ *
171
+ * Exported so tests assert on the REAL advertised text rather than on the tool definitions, which
172
+ * are trimmed later and would make a guard that cannot fail — a mistake already made once here, with
173
+ * an abbreviation test that read raw defs and would have passed with the bug fully present.
174
+ */
175
+ export function advertisedConfig(tool, advertised, profile) {
176
+ const terse = profile === TOOL_PROFILE.CORE ||
177
+ profile === TOOL_PROFILE.STANDARD ||
178
+ profile === TOOL_PROFILE.HYBRID;
179
+ // The first advertised tool carrying a predicate spells the grammar out; the rest point at it.
180
+ const anchor = advertised.find((t) => Object.keys(t.inputSchema).some((k) => PREDICATE_PARAMS.has(k)))?.name;
181
+ const outputSchema = terse ? undefined : withSessionEnvelope(tool.name, tool.outputSchema);
182
+ return {
183
+ description: withExample(terse ? firstSentence(tool.description) : tool.description, tool.example),
184
+ inputSchema: terse
185
+ ? leanZodShape(tool.inputSchema, tool.name === anchor ? undefined : anchor)
186
+ : tool.inputSchema,
187
+ ...(outputSchema !== undefined ? { outputSchema } : {}),
188
+ };
189
+ }
190
+ /** Argument keys the tool never declared. Empty when the tool's shape is unknown to us. */
191
+ function unknownKeys(args, allowed) {
192
+ if (allowed === undefined || typeof args !== 'object' || args === null)
193
+ return [];
194
+ return Object.keys(args).filter((key) => !allowed.has(key));
195
+ }
196
+ export function installFriendlyArgErrors(server, examples, allowedKeys = new Map()) {
197
+ const target = server;
198
+ const original = target.validateToolInput;
199
+ if (typeof original !== 'function')
200
+ return;
201
+ target.validateToolInput = async (tool, args, toolName) => {
202
+ // An UNKNOWN key is the failure zod cannot catch, because object schemas are non-strict: the key
203
+ // is silently dropped and the tool answers as if it had not been asked. Measured live —
204
+ // `reticle_clock { action: "freeze" }` returned `{"frozen":false}`, which reads as a fact about
205
+ // the app ("the clock is not frozen") when it means "you named the parameter wrong". That is a
206
+ // false NEGATIVE the caller cannot detect from the reply, in every tool at once.
207
+ const unknown = unknownKeys(args, allowedKeys.get(toolName));
208
+ if (unknown.length > 0) {
209
+ const example = examples.get(toolName);
210
+ throw new McpError(ErrorCode.InvalidParams, `Unknown ${unknown.length === 1 ? 'parameter' : 'parameters'} for ${toolName}: ${unknown.join(', ')}. ` +
211
+ `They were NOT applied — a result computed without them would look like an answer. ` +
212
+ (example === undefined
213
+ ? `Call reticle_tools { names: ["${toolName}"] } for its parameters.`
214
+ : `A valid call looks like: ${toolName} ${example}`));
215
+ }
216
+ try {
217
+ return await original.call(server, tool, args, toolName);
218
+ }
219
+ catch (error) {
220
+ // McpError.message already carries "MCP error -32602: "; re-wrapping would print it twice.
221
+ const raw = error instanceof Error ? error.message : String(error);
222
+ const detail = raw.replace(/^MCP error -?\d+:\s*/, '');
223
+ const example = examples.get(toolName);
224
+ const help = example === undefined
225
+ ? ` Call reticle_tools { names: ["${toolName}"] } for its parameters.`
226
+ : ` A valid call looks like: ${toolName} ${example}`;
227
+ throw new McpError(ErrorCode.InvalidParams, `${detail}${help}`);
228
+ }
229
+ };
230
+ }
115
231
  export function createMcpServer(deps, profile = TOOL_PROFILE.HYBRID) {
116
232
  const encoding = (process.env[ENCODING_ENV] ?? '').toLowerCase();
117
233
  const server = new McpServer(SERVER_INFO);
234
+ // Which agent is on the other end, taken from its own `initialize` handshake. Registered as a lazy
235
+ // hook rather than read here: the handshake has not happened yet at construction time, and a
236
+ // feedback report filed twenty tool calls later is exactly when we want the answer.
237
+ setMcpClientNameHook(() => {
238
+ const info = server.server.getClientVersion();
239
+ // Record it as a side effect of the first read so the session summary can report WHICH agents
240
+ // drove this daemon — the multi-agent story, visible without a second plumbing path.
241
+ if (info?.name !== undefined)
242
+ getSessionMetrics().recordClient(info.name);
243
+ return info === undefined ? undefined : { name: info.name, version: info.version };
244
+ });
118
245
  // Cast once to our bridge type so every per-tool call site is typed without `any`.
119
246
  const registerTool = server.registerTool.bind(server);
120
247
  // `dynamic` advertises only the 2 meta-tools (reticle_tools + reticle_run); real tools load on demand.
@@ -126,9 +253,12 @@ export function createMcpServer(deps, profile = TOOL_PROFILE.HYBRID) {
126
253
  // reticle_flow_save's own description instructs the agent to call. `full` advertises everything
127
254
  // directly and needs no hatch.
128
255
  const advertised = advertisedTools(profile);
129
- const terse = profile === TOOL_PROFILE.CORE ||
130
- profile === TOOL_PROFILE.STANDARD ||
131
- profile === TOOL_PROFILE.HYBRID;
256
+ installFriendlyArgErrors(server, new Map(advertised
257
+ .filter((tool) => tool.example !== undefined)
258
+ .map((tool) => [tool.name, JSON.stringify(tool.example)])),
259
+ // Every tool in TOOLS, not just the advertised ones: reticle_run dispatches to the full table,
260
+ // so an unadvertised tool reached through the hatch must be just as strict.
261
+ new Map(TOOLS.map((tool) => [tool.name, new Set(Object.keys(tool.inputSchema))])));
132
262
  for (const tool of advertised) {
133
263
  // Output schemas are now the largest slice of the per-request tax (55.6% of the hybrid payload
134
264
  // after the predicate fix) and we are the only one of the three MCP servers that sends them.
@@ -150,12 +280,7 @@ export function createMcpServer(deps, profile = TOOL_PROFILE.HYBRID) {
150
280
  // handler below is unchanged, so `full`/`dynamic` (non-terse) keep the schema for validating
151
281
  // clients. This removes the single largest remaining slice of the per-request tax (~36% of the
152
282
  // hybrid payload) with no loss the agent can observe.
153
- const outputSchema = terse ? undefined : withSessionEnvelope(tool.name, tool.outputSchema);
154
- const config = {
155
- description: terse ? firstSentence(tool.description) : tool.description,
156
- inputSchema: terse ? leanZodShape(tool.inputSchema) : tool.inputSchema,
157
- ...(outputSchema !== undefined ? { outputSchema } : {}),
158
- };
283
+ const config = advertisedConfig(tool, advertised, profile);
159
284
  registerTool(tool.name, config, async (args) => {
160
285
  try {
161
286
  const result = await runTool(tool, deps, args);
@@ -171,6 +296,10 @@ export function createMcpServer(deps, profile = TOOL_PROFILE.HYBRID) {
171
296
  catch (error) {
172
297
  const message = error instanceof Error ? error.message : String(error);
173
298
  log('tool_error', { tool: tool.name, error: message });
299
+ // Counted by FINGERPRINT, never by message — see error-fingerprint.ts. This is the single
300
+ // boundary every agent-visible tool failure crosses, so it is the one place "which error is
301
+ // hurting people most" can be answered without instrumenting every handler.
302
+ getSessionMetrics().recordToolError(message, tool.name);
174
303
  // Every error the agent hits should answer "what next?", not just "what broke".
175
304
  return {
176
305
  isError: true,
@@ -181,4 +310,3 @@ export function createMcpServer(deps, profile = TOOL_PROFILE.HYBRID) {
181
310
  }
182
311
  return server;
183
312
  }
184
- //# sourceMappingURL=mcp.js.map
@@ -16,4 +16,3 @@ export declare function lastSource(steps: readonly FlowStep[]): {
16
16
  * source are skipped (no location to propose). The suggested signal name is `<flow>:done`.
17
17
  */
18
18
  export declare function instrumentationGapsForFlows(unassertedFlows: readonly string[], flowStepsByName: ReadonlyMap<string, readonly FlowStep[]>): InstrumentationGap[];
19
- //# sourceMappingURL=flow-instrument-gaps.d.ts.map
@@ -42,4 +42,3 @@ export function instrumentationGapsForFlows(unassertedFlows, flowStepsByName) {
42
42
  }
43
43
  return gaps;
44
44
  }
45
- //# sourceMappingURL=flow-instrument-gaps.js.map
@@ -19,4 +19,3 @@ export interface ProposedConsequence {
19
19
  }
20
20
  /** Propose ranked consequences from a recorded event window. Deduped; strongest first. */
21
21
  export declare function proposeConsequences(events: readonly ReticleEvent[]): ProposedConsequence[];
22
- //# sourceMappingURL=propose-consequences.d.ts.map
@@ -90,4 +90,3 @@ export function proposeConsequences(events) {
90
90
  }
91
91
  return proposals.sort((a, b) => a.tier - b.tier);
92
92
  }
93
- //# sourceMappingURL=propose-consequences.js.map
@@ -29,4 +29,3 @@ export interface InstrumentationProposal {
29
29
  }
30
30
  /** Turn located capability gaps into ready-to-apply instrumentation proposals. Deterministic. */
31
31
  export declare function proposeInstrumentation(gaps: readonly InstrumentationGap[]): InstrumentationProposal[];
32
- //# sourceMappingURL=self-instrument.d.ts.map
@@ -41,4 +41,3 @@ export function proposeInstrumentation(gaps) {
41
41
  rationale: rationaleFor(gap),
42
42
  }));
43
43
  }
44
- //# sourceMappingURL=self-instrument.js.map
@@ -25,4 +25,3 @@ export declare function nodePairingTokenDeps(): PairingTokenDeps;
25
25
  * fails, so the caller degrades to the prior tokenless behavior rather than bricking the daemon.
26
26
  */
27
27
  export declare function readOrCreatePairingToken(dir: string, deps: PairingTokenDeps): Promise<string | undefined>;
28
- //# sourceMappingURL=pairing-token.d.ts.map
@@ -59,4 +59,3 @@ export async function readOrCreatePairingToken(dir, deps) {
59
59
  return undefined;
60
60
  }
61
61
  }
62
- //# sourceMappingURL=pairing-token.js.map
@@ -24,4 +24,3 @@ export declare function detectPreHydrationClicks(events: readonly ReticleEvent[]
24
24
  export declare function detectSwallowedErrors(events: readonly ReticleEvent[]): Finding[];
25
25
  /** Run every journal-only matcher over a session's events + actions. */
26
26
  export declare function detectPhenomena(events: readonly ReticleEvent[], actions: readonly JournalAction[]): Finding[];
27
- //# sourceMappingURL=phenomena.d.ts.map
@@ -99,4 +99,3 @@ export function detectPhenomena(events, actions) {
99
99
  ...detectSwallowedErrors(events),
100
100
  ];
101
101
  }
102
- //# sourceMappingURL=phenomena.js.map
@@ -89,4 +89,3 @@ export declare class BrowserPool {
89
89
  shutdown(): Promise<void>;
90
90
  }
91
91
  export {};
92
- //# sourceMappingURL=browser-pool.d.ts.map
@@ -236,4 +236,3 @@ export class BrowserPool {
236
236
  waiter(); // let them re-claim + relaunch
237
237
  }
238
238
  }
239
- //# sourceMappingURL=browser-pool.js.map
@@ -13,4 +13,3 @@ export declare class LeaseReaper {
13
13
  start(): void;
14
14
  stop(): void;
15
15
  }
16
- //# sourceMappingURL=lease-reaper.d.ts.map
@@ -38,4 +38,3 @@ export class LeaseReaper {
38
38
  this.#timer = undefined;
39
39
  }
40
40
  }
41
- //# sourceMappingURL=lease-reaper.js.map
@@ -18,4 +18,3 @@ export declare function playwrightLauncher(opts?: {
18
18
  * Pure (env value + cpu count passed in) so it's testable.
19
19
  */
20
20
  export declare function resolveMaxContexts(envValue: string | undefined, cpuCount: number): number;
21
- //# sourceMappingURL=playwright-launcher.d.ts.map
@@ -5,6 +5,9 @@
5
5
  *
6
6
  * Headless by default — the pool exists for fault-tolerant headless multi-agent testing.
7
7
  */
8
+ import { BrowserLaunchKind } from '@reticlehq/core';
9
+ import { getSessionMetrics } from '../telemetry/session-metrics.js';
10
+ import { classifyConnectFailure } from '../telemetry/connect-failure.js';
8
11
  function wrapBrowser(browser) {
9
12
  return {
10
13
  isConnected: () => browser.isConnected(),
@@ -38,10 +41,16 @@ export function playwrightLauncher(opts = {}) {
38
41
  // (where it's meaningful) instead of at import-time (where it kills unrelated features).
39
42
  return async () => {
40
43
  const { chromium } = await import('playwright');
44
+ // A pooled launch serves N parallel leases, so this counts BROWSERS, not contexts — which is the
45
+ // number that actually costs memory and the one that explains a slow machine.
46
+ const settle = getSessionMetrics().recordConnectAttempt(BrowserLaunchKind.POOLED);
41
47
  try {
42
- return wrapBrowser(await chromium.launch({ headless }));
48
+ const browser = wrapBrowser(await chromium.launch({ headless }));
49
+ settle();
50
+ return browser;
43
51
  }
44
52
  catch (err) {
53
+ settle(classifyConnectFailure(err));
45
54
  // Turn Playwright's raw "Executable doesn't exist" into the one command that fixes it.
46
55
  const msg = err instanceof Error ? err.message : String(err);
47
56
  if (/executable doesn.?t exist|playwright install|browsertype\.launch/i.test(msg)) {
@@ -74,4 +83,3 @@ export function resolveMaxContexts(envValue, cpuCount) {
74
83
  const byCpu = Math.max(MAX_CONTEXTS_FLOOR, cpuCount - 1);
75
84
  return Math.min(MAX_CONTEXTS_CEILING, byCpu);
76
85
  }
77
- //# sourceMappingURL=playwright-launcher.js.map
@@ -19,4 +19,3 @@ export declare class BaselineStore {
19
19
  list(): string[];
20
20
  }
21
21
  export {};
22
- //# sourceMappingURL=baselines.d.ts.map
@@ -44,4 +44,3 @@ export class BaselineStore {
44
44
  return [...this.#map.keys()];
45
45
  }
46
46
  }
47
- //# sourceMappingURL=baselines.js.map
@@ -1,2 +1,3 @@
1
1
  export declare function withFileLock<T>(path: string, fn: () => Promise<T>): Promise<T>;
2
- //# sourceMappingURL=file-lock.d.ts.map
2
+ /** Exposed for testing — returns the number of active chain entries. */
3
+ export declare function chainSize(): number;
@@ -18,7 +18,17 @@ export function withFileLock(path, fn) {
18
18
  // Run after the previous holder settles, regardless of whether it resolved or rejected.
19
19
  const run = prev.then(fn, fn);
20
20
  // Keep the chain alive but swallow the outcome so one task's rejection never rejects the next waiter.
21
- chains.set(path, run.then(() => undefined, () => undefined));
21
+ const settled = run.then(() => undefined, () => undefined);
22
+ chains.set(path, settled);
23
+ // Reclaim the entry once settled IF no successor queued behind us (the Map still points to our
24
+ // promise). Without this, every unique path leaks a Map slot for the daemon's lifetime.
25
+ void settled.then(() => {
26
+ if (chains.get(path) === settled)
27
+ chains.delete(path);
28
+ });
22
29
  return run;
23
30
  }
24
- //# sourceMappingURL=file-lock.js.map
31
+ /** Exposed for testing — returns the number of active chain entries. */
32
+ export function chainSize() {
33
+ return chains.size;
34
+ }
@@ -42,4 +42,3 @@ export interface FileSystemPort {
42
42
  }
43
43
  /** Production adapter — the single import site of node:fs/promises in the server. */
44
44
  export declare function createNodeFileSystem(): FileSystemPort;
45
- //# sourceMappingURL=fs-port.d.ts.map
@@ -51,4 +51,3 @@ export function createNodeFileSystem() {
51
51
  isNotFound: (error) => error?.code === 'ENOENT',
52
52
  };
53
53
  }
54
- //# sourceMappingURL=fs-port.js.map
@@ -29,4 +29,3 @@ export declare class ProjectStore {
29
29
  /** The most-recent run for `name` (undefined on missing/malformed/none). Powers diff-vs-last. */
30
30
  lastRun(name: string): Promise<RunRecord | undefined>;
31
31
  }
32
- //# sourceMappingURL=project-store.d.ts.map
@@ -142,4 +142,3 @@ function truncate(runs) {
142
142
  }
143
143
  return runs.filter((_, i) => kept.has(i));
144
144
  }
145
- //# sourceMappingURL=project-store.js.map
@@ -1,3 +1,2 @@
1
1
  import type { ToolDef } from '../tools/tools.js';
2
2
  export declare const PROJECT_TOOLS: ToolDef[];
3
- //# sourceMappingURL=project-tools.d.ts.map
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { ProjectReadError, RunKind, RunStatus } from '@reticlehq/core';
3
3
  import { ReticleTool } from '../tools/tool-names.js';
4
4
  import { sessionIdShape } from '../tools/tool-kit.js';
5
- import { asString } from '../tools/tools-helpers.js';
5
+ import { asNumber, asString } from '../tools/tools-helpers.js';
6
6
  import { fetchProjectRegressionFromCloud, resolveCloudConfig } from '../cloud/cloud-sync.js';
7
7
  import { RunStore } from '../runs/run-store.js';
8
8
  import { diffRuns as diffVerificationRuns, } from '../runs/run-diff.js';
@@ -49,6 +49,8 @@ async function cloudRegression(deps, sessionId) {
49
49
  return report ?? undefined;
50
50
  }
51
51
  /** The two most-recent runs for `name`, oldest-first, or undefined if there are fewer than two. */
52
+ /** Runs returned when the caller does not ask for a specific count. */
53
+ const DEFAULT_RUN_LIMIT = 25;
52
54
  function lastTwoFor(runs, name) {
53
55
  const matching = runs.filter((r) => r.name === name);
54
56
  const n = matching.length;
@@ -85,10 +87,18 @@ export const PROJECT_TOOLS = [
85
87
  description: 'Read cross-run history from .reticle/project.json — the memory of how past runs behaved. With { name } it also returns the last run for that flow plus a diff-vs-last summary (status change, regressed flag, consoleErrors/driftSteps deltas) so you can answer "did it behave like last time?". `diff` is the lightweight status/console/drift delta vs the previous run of that NAME; `runDiff` is the per-flow duration/status delta between the two most-recent full verification artifacts ("step 3: 412ms -> 987ms (+140%), +2 requests"). When logged in to Reticle Cloud, also returns `cloud`: the team\'s server-side regression report (broken/changed flows vs before) — the durable memory a fresh or context-lost agent can rely on even when local history is empty. Returns { runs, learned?, lastRun?, diff?, runDiff?, cloud? } or { error, reason, cloud? }.',
86
88
  inputSchema: {
87
89
  name: z.string().optional().describe('Filter runs by this name. Omit to return all runs.'),
90
+ limit: z
91
+ .number()
92
+ .optional()
93
+ .describe('Most-recent N runs to return. Defaults to 25 — the full history is unbounded and grows with every run (measured at ~20KB / ~5,000 tokens on a modest project), which is a large slice of an agent context for data it mostly does not read. `totalRuns` always reports the true count, so a cap is never silent.'),
88
94
  ...sessionIdShape,
89
95
  },
90
96
  outputSchema: {
91
97
  runs: z.array(z.unknown()),
98
+ totalRuns: z
99
+ .number()
100
+ .optional()
101
+ .describe('How many runs exist in total. Compare against runs.length to see if it was capped.'),
92
102
  diff: z.unknown().optional(),
93
103
  runDiff: z.unknown().optional(),
94
104
  cloud: z.unknown().optional(),
@@ -106,8 +116,22 @@ export const PROJECT_TOOLS = [
106
116
  });
107
117
  }
108
118
  const name = asString(args['name']);
119
+ // The most recent N, in the order they happened. The history is append-only and unbounded —
120
+ // measured at ~20KB (~5,000 tokens) across 176 runs on this repo — and an agent asking "how
121
+ // did this behave before" wants the recent past, not every run ever recorded. `totalRuns`
122
+ // travels with it so the cap is never silent, per the repo's no-silent-caps rule.
123
+ //
124
+ // Order is left alone deliberately. Reversing to newest-first was tried and reverted: it read
125
+ // better but broke an existing contract for no reason the bound required, and a caller relying
126
+ // on chronological order would have been silently handed the reverse.
127
+ const cap = asNumber(args['limit']) ?? DEFAULT_RUN_LIMIT;
128
+ const recent = (runs) => runs.slice(-cap);
109
129
  if (name === undefined) {
110
- return withCloud({ runs: read.file.runs, learned: read.file.learned });
130
+ return withCloud({
131
+ runs: recent(read.file.runs),
132
+ totalRuns: read.file.runs.length,
133
+ learned: read.file.learned,
134
+ });
111
135
  }
112
136
  const lastRun = await deps.project.lastRun(name);
113
137
  const pair = lastTwoFor(read.file.runs, name);
@@ -117,8 +141,10 @@ export const PROJECT_TOOLS = [
117
141
  // last time?" from project.json, while `runDiff` answers "what changed between the last two full
118
142
  // verification runs?" from .reticle/runs. Best-effort: no artifacts simply means no runDiff.
119
143
  const runDiff = await lastTwoRunArtifacts(deps);
144
+ const forName = read.file.runs.filter((r) => r.name === name);
120
145
  return withCloud({
121
- runs: read.file.runs.filter((r) => r.name === name),
146
+ runs: recent(forName),
147
+ totalRuns: forName.length,
122
148
  learned: read.file.learned,
123
149
  lastRun,
124
150
  ...(pair !== undefined ? { diff: diffRuns(pair[0], pair[1]) } : {}),
@@ -156,4 +182,3 @@ export const PROJECT_TOOLS = [
156
182
  },
157
183
  },
158
184
  ];
159
- //# sourceMappingURL=project-tools.js.map
@@ -83,4 +83,3 @@ export type ReadContractResult = {
83
83
  };
84
84
  /** Never throws. Missing → MISSING. Bad JSON / failed schema → MALFORMED. */
85
85
  export declare function readContract(fs: FileSystemPort, root: string): Promise<ReadContractResult>;
86
- //# sourceMappingURL=reticle-dir.d.ts.map
@@ -167,4 +167,3 @@ export async function readContract(fs, root) {
167
167
  return { ok: false, reason: ContractReadError.MALFORMED };
168
168
  return { ok: true, capabilities: result.data.capabilities, generatedAt: result.data.generatedAt };
169
169
  }
170
- //# sourceMappingURL=reticle-dir.js.map
@@ -27,4 +27,3 @@ export declare function computeVerdict(input: VerificationRunInput): RunVerdict;
27
27
  * input can never escape as an "artifact".
28
28
  */
29
29
  export declare function buildVerificationRun(input: VerificationRunInput, now: () => number): ReticleVerificationRun;
30
- //# sourceMappingURL=build-verification-run.d.ts.map
@@ -68,4 +68,3 @@ export function buildVerificationRun(input, now) {
68
68
  };
69
69
  return redactForProfile(ReticleVerificationRunSchema.parse(run));
70
70
  }
71
- //# sourceMappingURL=build-verification-run.js.map
@@ -13,4 +13,3 @@ export declare const REDACTED = "[redacted:prod-preview]";
13
13
  * the repair block (source-naming) is dropped and stateAssertion values are redacted.
14
14
  */
15
15
  export declare function redactForProfile(run: ReticleVerificationRun): ReticleVerificationRun;
16
- //# sourceMappingURL=profile-redact.d.ts.map
@@ -29,4 +29,3 @@ export function redactForProfile(run) {
29
29
  void repair; // intentionally dropped — fix instructions name source files
30
30
  return { ...rest, evidence };
31
31
  }
32
- //# sourceMappingURL=profile-redact.js.map
@@ -6,4 +6,3 @@
6
6
  import { type ReticleVerificationRun } from '@reticlehq/core';
7
7
  /** Render the run as a plain-text report. Sections with no content are omitted. */
8
8
  export declare function renderRunReport(run: ReticleVerificationRun): string;
9
- //# sourceMappingURL=render-report.d.ts.map
@@ -67,4 +67,3 @@ export function renderRunReport(run) {
67
67
  }
68
68
  return out.join('\n');
69
69
  }
70
- //# sourceMappingURL=render-report.js.map
@@ -14,4 +14,3 @@ export declare function deviationHeadline(deviation: unknown): string | undefine
14
14
  export declare function buildRepairPacket(replay: FlowReplayResult): RepairPacket | undefined;
15
15
  /** Build the repair packets for a set of replays (failed ones only). */
16
16
  export declare function buildRepairPackets(replays: ReadonlyArray<FlowReplayResult>): RepairPacket[];
17
- //# sourceMappingURL=repair-prompt.d.ts.map
@@ -69,4 +69,3 @@ export function buildRepairPacket(replay) {
69
69
  export function buildRepairPackets(replays) {
70
70
  return replays.map(buildRepairPacket).filter((p) => p !== undefined);
71
71
  }
72
- //# sourceMappingURL=repair-prompt.js.map
@@ -9,4 +9,3 @@ import { ReplayStatus, RunFlowStatus, type FlowReplayResult, type RunFlowResult
9
9
  export declare function runFlowStatusOf(status: ReplayStatus): RunFlowStatus;
10
10
  /** Map one replay (plus its measured duration) into a RunFlowResult for the artifact's flows[]. */
11
11
  export declare function mapReplayToFlowResult(replay: FlowReplayResult, durationMs: number): RunFlowResult;
12
- //# sourceMappingURL=replay-mapping.d.ts.map
@@ -32,4 +32,3 @@ export function mapReplayToFlowResult(replay, durationMs) {
32
32
  ...(failureReason !== undefined ? { failureReason } : {}),
33
33
  };
34
34
  }
35
- //# sourceMappingURL=replay-mapping.js.map
@@ -45,4 +45,3 @@ export declare class ReticleRunner {
45
45
  */
46
46
  verify(opts: VerifyOptions): Promise<ReticleVerificationRun>;
47
47
  }
48
- //# sourceMappingURL=reticle-runner.d.ts.map
@@ -9,6 +9,7 @@
9
9
  * top of this — the orchestration and the verdict live here so the MCP path and the API produce the
10
10
  * same artifact byte-for-byte.
11
11
  */
12
+ import { reportRunTelemetry } from '../telemetry/run-telemetry.js';
12
13
  import { buildVerificationRun } from './build-verification-run.js';
13
14
  import { mapReplayToFlowResult } from './replay-mapping.js';
14
15
  import { buildRepairPackets } from './repair-prompt.js';
@@ -50,7 +51,8 @@ export class ReticleRunner {
50
51
  evidence: { consoleErrors: [], networkAnomalies: [], stateAssertions: [], timeline: [] },
51
52
  ...(failurePackets.length > 0 ? { repair: { failurePackets } } : {}),
52
53
  };
53
- return buildVerificationRun(input, () => this.#port.now());
54
+ const run = buildVerificationRun(input, () => this.#port.now());
55
+ reportRunTelemetry(run);
56
+ return run;
54
57
  }
55
58
  }
56
- //# sourceMappingURL=reticle-runner.js.map
@@ -24,4 +24,3 @@ export declare function classifyChangedFiles(files: ReadonlyArray<ChangedFileInp
24
24
  * severity and a gated flag driven by the policy. This is what the verdict counts as blocking.
25
25
  */
26
26
  export declare function buildRisks(changedFiles: ReadonlyArray<RunChangedFile>, policy?: RiskPolicy): RunRisk[];
27
- //# sourceMappingURL=risk-classify.d.ts.map
@@ -73,4 +73,3 @@ export function buildRisks(changedFiles, policy = {}) {
73
73
  }
74
74
  return risks;
75
75
  }
76
- //# sourceMappingURL=risk-classify.js.map
@@ -31,4 +31,3 @@ export declare const DEFAULT_NOISE_FLOOR_PCT = 10;
31
31
  * console diffs land once runs persist per-step detail.
32
32
  */
33
33
  export declare function diffRuns(before: ReticleVerificationRun, after: ReticleVerificationRun, noiseFloorPct?: number): RunDiff;
34
- //# sourceMappingURL=run-diff.d.ts.map