@reticlehq/server 2.4.0 → 2.6.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 (472) hide show
  1. package/SKILL.md +719 -0
  2. package/dist/bridge/auth-failure-reason.d.ts +19 -0
  3. package/dist/bridge/auth-failure-reason.js +29 -0
  4. package/dist/{bridge-security.d.ts → bridge/bridge-security.d.ts} +1 -1
  5. package/dist/{bridge-security.js → bridge/bridge-security.js} +1 -1
  6. package/dist/{bridge.d.ts → bridge/bridge.d.ts} +13 -1
  7. package/dist/{bridge.js → bridge/bridge.js} +95 -15
  8. package/dist/{bridge.test-harness.d.ts → bridge/bridge.test-harness.d.ts} +9 -11
  9. package/dist/{bridge.test-harness.js → bridge/bridge.test-harness.js} +18 -10
  10. package/dist/{pairing-token.js → bridge/pairing-token.js} +1 -1
  11. package/dist/capsule/capsule-store.d.ts +8 -3
  12. package/dist/capsule/capsule-store.js +7 -2
  13. package/dist/capsule/capsule.js +3 -3
  14. package/dist/capsule/causal-summary.d.ts +8 -0
  15. package/dist/capsule/causal-summary.js +22 -12
  16. package/dist/capsule/divergence.d.ts +9 -4
  17. package/dist/capsule/divergence.js +8 -8
  18. package/dist/capsule/predicate-to-links.js +11 -8
  19. package/dist/cli/cli-doctor.d.ts +1 -0
  20. package/dist/cli/cli-doctor.js +135 -0
  21. package/dist/{cli-flow-commands.d.ts → cli/cli-flow-commands.d.ts} +2 -2
  22. package/dist/{cli-flow-commands.js → cli/cli-flow-commands.js} +15 -15
  23. package/dist/{cli-launch.d.ts → cli/cli-launch.d.ts} +32 -3
  24. package/dist/cli/cli-launch.js +171 -0
  25. package/dist/cli/cli-parse-feedback.d.ts +31 -0
  26. package/dist/cli/cli-parse-feedback.js +56 -0
  27. package/dist/{cli-parse.d.ts → cli/cli-parse.d.ts} +6 -19
  28. package/dist/{cli-parse.js → cli/cli-parse.js} +118 -81
  29. package/dist/{cli-port.d.ts → cli/cli-port.d.ts} +12 -0
  30. package/dist/{cli-port.js → cli/cli-port.js} +9 -9
  31. package/dist/cli/cli-update-commands.d.ts +4 -0
  32. package/dist/cli/cli-update-commands.js +93 -0
  33. package/dist/{cli-verify.js → cli/cli-verify.js} +14 -14
  34. package/dist/{cloud-cli.js → cli/cloud-cli.js} +29 -24
  35. package/dist/cli/doctor-daemon-line.d.ts +37 -0
  36. package/dist/cli/doctor-daemon-line.js +35 -0
  37. package/dist/cli/port-holder.d.ts +43 -0
  38. package/dist/cli/port-holder.js +99 -0
  39. package/dist/cli.d.ts +2 -2
  40. package/dist/cli.js +302 -100
  41. package/dist/cloud/cloud-config.d.ts +0 -1
  42. package/dist/cloud/cloud-config.js +9 -9
  43. package/dist/cloud/cloud-sync.d.ts +1 -7
  44. package/dist/cloud/cloud-sync.js +12 -12
  45. package/dist/crawl/crawl-empty.d.ts +16 -0
  46. package/dist/crawl/crawl-empty.js +24 -0
  47. package/dist/crawl/crawl-tools.js +4 -1
  48. package/dist/crawl/crawl.js +26 -7
  49. package/dist/daemon/daemon-resilience.d.ts +73 -0
  50. package/dist/daemon/daemon-resilience.js +279 -0
  51. package/dist/daemon/daemon-usefulness.d.ts +61 -0
  52. package/dist/daemon/daemon-usefulness.js +62 -0
  53. package/dist/{daemon.d.ts → daemon/daemon.d.ts} +33 -8
  54. package/dist/{daemon.js → daemon/daemon.js} +105 -48
  55. package/dist/daemon/heartbeat.d.ts +115 -0
  56. package/dist/daemon/heartbeat.js +141 -0
  57. package/dist/daemon/idle-grace.d.ts +32 -0
  58. package/dist/daemon/idle-grace.js +41 -0
  59. package/dist/{idle-shutdown.d.ts → daemon/idle-shutdown.d.ts} +23 -2
  60. package/dist/{idle-shutdown.js → daemon/idle-shutdown.js} +37 -6
  61. package/dist/daemon/port-presence.d.ts +76 -0
  62. package/dist/daemon/port-presence.js +93 -0
  63. package/dist/daemon/state-dir.d.ts +7 -0
  64. package/dist/daemon/state-dir.js +59 -0
  65. package/dist/daemon/unclean-predecessor.d.ts +23 -0
  66. package/dist/daemon/unclean-predecessor.js +27 -0
  67. package/dist/domain/domain-model.js +2 -2
  68. package/dist/events/body-failures.js +8 -8
  69. package/dist/events/contradictions.d.ts +1 -1
  70. package/dist/events/contradictions.js +60 -10
  71. package/dist/events/echo-mismatch.js +10 -10
  72. package/dist/events/event-filters.js +6 -6
  73. package/dist/events/json-salvage.d.ts +2 -1
  74. package/dist/events/json-salvage.js +6 -6
  75. package/dist/events/observed-in-window.d.ts +12 -0
  76. package/dist/events/observed-in-window.js +21 -0
  77. package/dist/events/predicate-eval.d.ts +53 -20
  78. package/dist/events/predicate-eval.js +179 -55
  79. package/dist/events/predicate-parse.d.ts +23 -0
  80. package/dist/events/predicate-parse.js +54 -0
  81. package/dist/events/predicate.d.ts +7 -2
  82. package/dist/events/predicate.js +126 -35
  83. package/dist/events/reconcile.js +5 -5
  84. package/dist/events/ring-buffer.js +2 -17
  85. package/dist/events/stale-response.js +6 -6
  86. package/dist/events/testid-near-miss.d.ts +22 -0
  87. package/dist/events/testid-near-miss.js +33 -0
  88. package/dist/events/unit-mismatch.js +8 -8
  89. package/dist/flows/affected-tools.js +19 -4
  90. package/dist/flows/affected.js +1 -1
  91. package/dist/flows/annotate-target.d.ts +1 -0
  92. package/dist/flows/annotate-target.js +20 -0
  93. package/dist/flows/annotate-tools.js +25 -3
  94. package/dist/flows/annotate.js +17 -4
  95. package/dist/flows/assertion-integrity.d.ts +2 -1
  96. package/dist/flows/assertion-tiers-store.d.ts +3 -66
  97. package/dist/flows/assertion-tiers-store.js +2 -2
  98. package/dist/flows/attributed-failure.d.ts +17 -0
  99. package/dist/flows/attributed-failure.js +20 -0
  100. package/dist/flows/buddy-status.d.ts +2 -1
  101. package/dist/flows/buddy-status.js +2 -2
  102. package/dist/flows/coverage.d.ts +3 -2
  103. package/dist/flows/coverage.js +2 -2
  104. package/dist/flows/decision.js +24 -9
  105. package/dist/flows/empty-flow.d.ts +6 -0
  106. package/dist/flows/empty-flow.js +24 -0
  107. package/dist/flows/flake-store.d.ts +0 -1
  108. package/dist/flows/flake-store.js +1 -1
  109. package/dist/flows/flake.d.ts +2 -1
  110. package/dist/flows/flake.js +2 -2
  111. package/dist/flows/flow-classify.js +12 -0
  112. package/dist/flows/flow-replay-run.js +4 -4
  113. package/dist/flows/flow-replay.d.ts +6 -8
  114. package/dist/flows/flow-replay.js +132 -48
  115. package/dist/flows/flow-report.js +1 -1
  116. package/dist/flows/flow-scope.d.ts +1 -6
  117. package/dist/flows/flow-step-runners.d.ts +26 -6
  118. package/dist/flows/flow-step-runners.js +156 -6
  119. package/dist/flows/flow-success.js +20 -15
  120. package/dist/flows/flow-tools.js +63 -21
  121. package/dist/flows/flows.js +15 -11
  122. package/dist/flows/gate.d.ts +4 -3
  123. package/dist/flows/gate.js +1 -1
  124. package/dist/flows/heal-run.d.ts +0 -8
  125. package/dist/flows/heal-run.js +5 -5
  126. package/dist/flows/heal.js +3 -3
  127. package/dist/flows/predicate-to-expect.d.ts +38 -0
  128. package/dist/flows/predicate-to-expect.js +95 -0
  129. package/dist/flows/replay.d.ts +16 -1
  130. package/dist/flows/replay.js +58 -22
  131. package/dist/flows/role-anchor-nearest.d.ts +6 -0
  132. package/dist/flows/role-anchor-nearest.js +45 -0
  133. package/dist/flows/role-drift-reason.d.ts +20 -0
  134. package/dist/flows/role-drift-reason.js +39 -0
  135. package/dist/flows/server-verify.d.ts +1 -1
  136. package/dist/flows/server-verify.js +5 -5
  137. package/dist/flows/suite-flakes.d.ts +33 -0
  138. package/dist/flows/suite-flakes.js +32 -0
  139. package/dist/flows/verify-change-tools.js +32 -10
  140. package/dist/flows/verify-change-verdict.d.ts +15 -0
  141. package/dist/flows/verify-change-verdict.js +25 -0
  142. package/dist/flows/watch-batcher.d.ts +3 -2
  143. package/dist/honesty/already-true.d.ts +2 -0
  144. package/dist/honesty/already-true.js +31 -0
  145. package/dist/honesty/blind-spots.d.ts +35 -3
  146. package/dist/honesty/blind-spots.js +57 -12
  147. package/dist/honesty/honesty.d.ts +3 -2
  148. package/dist/honesty/honesty.js +4 -4
  149. package/dist/honesty/uncaptured-bodies.js +1 -1
  150. package/dist/honesty/unread-outcome.js +2 -2
  151. package/dist/honesty/verified.d.ts +31 -3
  152. package/dist/honesty/verified.js +64 -8
  153. package/dist/http-server.js +23 -7
  154. package/dist/hunt/hunt-report.d.ts +2 -1
  155. package/dist/hunt/hunt-report.js +2 -2
  156. package/dist/index.d.ts +9 -6
  157. package/dist/index.js +41 -25
  158. package/dist/init/agent-rules.d.ts +20 -1
  159. package/dist/init/agent-rules.js +64 -8
  160. package/dist/init/app-choice.d.ts +20 -0
  161. package/dist/init/app-choice.js +25 -0
  162. package/dist/init/astro-host.d.ts +21 -0
  163. package/dist/init/astro-host.js +27 -0
  164. package/dist/init/astro-patch.d.ts +16 -0
  165. package/dist/init/astro-patch.js +240 -0
  166. package/dist/init/capabilities.js +4 -1
  167. package/dist/init/cra.d.ts +50 -0
  168. package/dist/init/cra.js +106 -0
  169. package/dist/init/cursor.js +39 -4
  170. package/dist/init/desktop-doctor.d.ts +3 -2
  171. package/dist/init/desktop-doctor.js +4 -4
  172. package/dist/init/detect.d.ts +9 -2
  173. package/dist/init/detect.js +24 -5
  174. package/dist/init/mcp-clients.d.ts +81 -0
  175. package/dist/init/mcp-clients.js +248 -0
  176. package/dist/init/mcp-registered.d.ts +12 -0
  177. package/dist/init/mcp-registered.js +14 -0
  178. package/dist/init/mcp.d.ts +27 -2
  179. package/dist/init/mcp.js +40 -4
  180. package/dist/init/next-patch.d.ts +2 -4
  181. package/dist/init/next-patch.js +109 -19
  182. package/dist/init/node-io.js +29 -6
  183. package/dist/init/plan-framework.d.ts +16 -1
  184. package/dist/init/plan-framework.js +166 -8
  185. package/dist/init/plan.d.ts +85 -6
  186. package/dist/init/plan.js +196 -33
  187. package/dist/init/project-id.d.ts +5 -9
  188. package/dist/init/project-id.js +10 -22
  189. package/dist/init/run.d.ts +23 -1
  190. package/dist/init/run.js +338 -47
  191. package/dist/init/slash-command.d.ts +9 -0
  192. package/dist/init/slash-command.js +10 -1
  193. package/dist/init/snippets.d.ts +7 -10
  194. package/dist/init/snippets.js +44 -15
  195. package/dist/init/vite-config.js +1 -1
  196. package/dist/init/windows-quote.d.ts +38 -0
  197. package/dist/init/windows-quote.js +70 -0
  198. package/dist/init/workspace-apps.d.ts +23 -0
  199. package/dist/init/workspace-apps.js +68 -0
  200. package/dist/input/driven-redaction.js +1 -1
  201. package/dist/input/network-detail.js +8 -8
  202. package/dist/input/network-mock-tools.js +2 -2
  203. package/dist/input/network-mock.js +4 -4
  204. package/dist/input/real-input.js +8 -3
  205. package/dist/input/scroll-find.js +2 -2
  206. package/dist/input/scroll-tools.d.ts +0 -5
  207. package/dist/input/scroll-tools.js +11 -4
  208. package/dist/input/viewport-tools.js +2 -2
  209. package/dist/journal/ambient-store.d.ts +0 -2
  210. package/dist/journal/ambient-store.js +1 -1
  211. package/dist/journal/ambient.js +1 -1
  212. package/dist/journal/attach-journal.d.ts +2 -1
  213. package/dist/journal/deviation-report.js +6 -6
  214. package/dist/journal/deviation-service.js +1 -1
  215. package/dist/journal/envelope-store.d.ts +0 -2
  216. package/dist/journal/envelope-store.js +1 -1
  217. package/dist/journal/envelope.d.ts +2 -3
  218. package/dist/journal/envelope.js +3 -3
  219. package/dist/journal/journal-query.js +1 -1
  220. package/dist/journal/journal-recorder.d.ts +2 -1
  221. package/dist/journal/journal-recorder.js +2 -2
  222. package/dist/journal/rollups.js +9 -9
  223. package/dist/journal/session-end.d.ts +2 -1
  224. package/dist/journal/session-journal.js +4 -4
  225. package/dist/license/license.d.ts +0 -14
  226. package/dist/license/license.js +8 -8
  227. package/dist/log.d.ts +10 -0
  228. package/dist/log.js +11 -1
  229. package/dist/mcp/mcp-is-error.d.ts +13 -0
  230. package/dist/mcp/mcp-is-error.js +18 -0
  231. package/dist/mcp/mcp-outage.d.ts +32 -0
  232. package/dist/mcp/mcp-outage.js +55 -0
  233. package/dist/mcp/mcp-proxy.d.ts +134 -0
  234. package/dist/mcp/mcp-proxy.js +720 -0
  235. package/dist/{mcp.d.ts → mcp/mcp.d.ts} +13 -10
  236. package/dist/{mcp.js → mcp/mcp.js} +139 -37
  237. package/dist/mcp/proxy-handshake.d.ts +3 -0
  238. package/dist/mcp/proxy-handshake.js +54 -0
  239. package/dist/mcp/proxy-lifecycle.d.ts +64 -0
  240. package/dist/mcp/proxy-lifecycle.js +70 -0
  241. package/dist/mcp/tool-catalog-cache.d.ts +29 -0
  242. package/dist/mcp/tool-catalog-cache.js +55 -0
  243. package/dist/oracles/propose-consequences.d.ts +2 -1
  244. package/dist/oracles/propose-consequences.js +16 -11
  245. package/dist/oracles/self-instrument.d.ts +2 -1
  246. package/dist/oracles/self-instrument.js +1 -1
  247. package/dist/phenomena/phenomena.js +3 -3
  248. package/dist/platform.d.ts +16 -0
  249. package/dist/platform.js +16 -0
  250. package/dist/pool/browser-pool.d.ts +9 -0
  251. package/dist/pool/browser-pool.js +38 -9
  252. package/dist/pool/playwright-launcher.d.ts +15 -2
  253. package/dist/pool/playwright-launcher.js +21 -2
  254. package/dist/project/fs-port.js +1 -1
  255. package/dist/project/project-tools.js +2 -2
  256. package/dist/runs/build-verification-run.js +1 -1
  257. package/dist/runs/repair-prompt.d.ts +0 -6
  258. package/dist/runs/repair-prompt.js +3 -3
  259. package/dist/runs/risk-classify.js +1 -1
  260. package/dist/runs/run-diff.d.ts +0 -2
  261. package/dist/runs/run-diff.js +3 -3
  262. package/dist/runs/run-tools.js +2 -2
  263. package/dist/runs/verification-sync.js +2 -2
  264. package/dist/runs/verify-http.js +1 -1
  265. package/dist/runs/verify-server.js +1 -1
  266. package/dist/session/attachment-history.d.ts +46 -0
  267. package/dist/session/attachment-history.js +65 -0
  268. package/dist/session/command-timeout.d.ts +11 -3
  269. package/dist/session/command-timeout.js +2 -2
  270. package/dist/session/control-envelope.d.ts +6 -0
  271. package/dist/session/control-envelope.js +7 -1
  272. package/dist/session/dev-server-probe.d.ts +13 -0
  273. package/dist/session/dev-server-probe.js +52 -0
  274. package/dist/session/last-act.d.ts +17 -3
  275. package/dist/session/last-act.js +16 -4
  276. package/dist/session/live-control-tools.js +7 -2
  277. package/dist/session/live-control.js +1 -1
  278. package/dist/session/looks-like-dev-server.d.ts +14 -0
  279. package/dist/session/looks-like-dev-server.js +25 -0
  280. package/dist/session/no-session-diagnosis.d.ts +45 -0
  281. package/dist/session/no-session-diagnosis.js +120 -0
  282. package/dist/session/no-session-watch.d.ts +21 -0
  283. package/dist/session/no-session-watch.js +69 -0
  284. package/dist/session/observed-state.d.ts +4 -0
  285. package/dist/session/observed-state.js +19 -1
  286. package/dist/session/output-budget.js +1 -1
  287. package/dist/session/pending-commands.js +1 -0
  288. package/dist/session/session-health.d.ts +8 -1
  289. package/dist/session/session-health.js +8 -7
  290. package/dist/session/session-info.d.ts +43 -8
  291. package/dist/session/session-info.js +46 -1
  292. package/dist/session/session-lease.d.ts +0 -11
  293. package/dist/session/session-lease.js +1 -1
  294. package/dist/session/session-manager.d.ts +6 -0
  295. package/dist/session/session-manager.js +124 -12
  296. package/dist/session/session-readiness.d.ts +1 -1
  297. package/dist/session/session-readiness.js +6 -1
  298. package/dist/session/session-reaper.js +1 -1
  299. package/dist/session/session-reconnect.d.ts +32 -0
  300. package/dist/session/session-reconnect.js +42 -0
  301. package/dist/session/session.d.ts +15 -2
  302. package/dist/session/session.js +77 -26
  303. package/dist/session/state-select.d.ts +1 -1
  304. package/dist/session/state-select.js +1 -1
  305. package/dist/status-payload.d.ts +19 -0
  306. package/dist/status-payload.js +11 -0
  307. package/dist/telemetry/argument-shape.js +10 -1
  308. package/dist/telemetry/browser-mode.d.ts +27 -0
  309. package/dist/telemetry/browser-mode.js +33 -0
  310. package/dist/telemetry/bug-found.d.ts +17 -21
  311. package/dist/telemetry/bug-found.js +120 -8
  312. package/dist/telemetry/cli-telemetry.d.ts +2 -12
  313. package/dist/telemetry/cli-telemetry.js +27 -4
  314. package/dist/telemetry/crash-cause.d.ts +47 -0
  315. package/dist/telemetry/crash-cause.js +104 -0
  316. package/dist/telemetry/daemon-telemetry.d.ts +38 -1
  317. package/dist/telemetry/daemon-telemetry.js +37 -12
  318. package/dist/telemetry/dev-repo.js +4 -4
  319. package/dist/telemetry/error-class.d.ts +26 -0
  320. package/dist/telemetry/error-class.js +52 -0
  321. package/dist/telemetry/error-fingerprint.js +21 -2
  322. package/dist/telemetry/feedback-cli.d.ts +8 -3
  323. package/dist/telemetry/feedback-cli.js +52 -8
  324. package/dist/telemetry/feedback-context.d.ts +23 -6
  325. package/dist/telemetry/feedback-context.js +105 -5
  326. package/dist/telemetry/feedback-delivery.d.ts +20 -0
  327. package/dist/telemetry/feedback-delivery.js +30 -0
  328. package/dist/telemetry/feedback-outbox.d.ts +22 -0
  329. package/dist/telemetry/feedback-outbox.js +87 -0
  330. package/dist/telemetry/feedback.d.ts +22 -1
  331. package/dist/telemetry/feedback.js +67 -8
  332. package/dist/telemetry/git-facts.d.ts +7 -0
  333. package/dist/telemetry/git-facts.js +5 -5
  334. package/dist/telemetry/project-profile.js +2 -1
  335. package/dist/telemetry/session-metrics.d.ts +47 -3
  336. package/dist/telemetry/session-metrics.js +315 -15
  337. package/dist/telemetry/telemetry.d.ts +45 -2
  338. package/dist/telemetry/telemetry.js +150 -37
  339. package/dist/telemetry/verification-of.d.ts +22 -0
  340. package/dist/telemetry/verification-of.js +84 -0
  341. package/dist/tools/act-capsule.js +2 -2
  342. package/dist/tools/act-danger.d.ts +12 -0
  343. package/dist/tools/act-danger.js +20 -3
  344. package/dist/tools/act-helpers.js +4 -4
  345. package/dist/tools/act-tools.d.ts +0 -8
  346. package/dist/tools/act-tools.js +114 -118
  347. package/dist/tools/act-view.js +7 -7
  348. package/dist/tools/alias-args.d.ts +17 -0
  349. package/dist/tools/alias-args.js +25 -0
  350. package/dist/tools/assert-grade.js +9 -9
  351. package/dist/tools/assert-verdict.d.ts +9 -1
  352. package/dist/tools/assert-verdict.js +21 -6
  353. package/dist/tools/browser-tools.js +36 -11
  354. package/dist/tools/contract-tools.d.ts +0 -5
  355. package/dist/tools/contract-tools.js +27 -1
  356. package/dist/tools/coverage-identity.d.ts +34 -0
  357. package/dist/tools/coverage-identity.js +46 -0
  358. package/dist/tools/coverage-tools.js +10 -14
  359. package/dist/tools/dynamic-tools.d.ts +2 -1
  360. package/dist/tools/dynamic-tools.js +96 -19
  361. package/dist/tools/error-recovery.d.ts +34 -2
  362. package/dist/tools/error-recovery.js +255 -4
  363. package/dist/tools/feedback-invite.d.ts +48 -0
  364. package/dist/tools/feedback-invite.js +71 -0
  365. package/dist/tools/feedback-tools.d.ts +12 -1
  366. package/dist/tools/feedback-tools.js +28 -5
  367. package/dist/tools/invoke-tool.d.ts +0 -12
  368. package/dist/tools/invoke-tool.js +126 -33
  369. package/dist/tools/lease-hint.d.ts +17 -0
  370. package/dist/tools/lease-hint.js +24 -0
  371. package/dist/tools/lease-tools.js +6 -5
  372. package/dist/tools/merge-tools.d.ts +10 -1
  373. package/dist/tools/merge-tools.js +9 -3
  374. package/dist/tools/merged-name-redirect.d.ts +13 -0
  375. package/dist/tools/merged-name-redirect.js +55 -0
  376. package/dist/tools/navigate-arrival.d.ts +26 -0
  377. package/dist/tools/navigate-arrival.js +60 -0
  378. package/dist/tools/navigate-result.d.ts +31 -0
  379. package/dist/tools/navigate-result.js +38 -0
  380. package/dist/tools/observe-tools.js +72 -20
  381. package/dist/tools/observed-nothing.d.ts +25 -0
  382. package/dist/tools/observed-nothing.js +33 -0
  383. package/dist/tools/query-paginate.js +2 -2
  384. package/dist/tools/query-shape.d.ts +18 -0
  385. package/dist/tools/query-shape.js +39 -0
  386. package/dist/tools/read-tools.js +81 -20
  387. package/dist/tools/real-input-attempt.d.ts +28 -0
  388. package/dist/tools/real-input-attempt.js +93 -0
  389. package/dist/tools/reconcile-tools.js +7 -7
  390. package/dist/tools/reload-result.d.ts +14 -0
  391. package/dist/tools/reload-result.js +29 -0
  392. package/dist/tools/snapshot-delta.d.ts +4 -5
  393. package/dist/tools/snapshot-delta.js +0 -0
  394. package/dist/tools/tool-kit.d.ts +16 -0
  395. package/dist/tools/tool-surface.d.ts +83 -0
  396. package/dist/tools/tool-surface.js +217 -0
  397. package/dist/tools/tools-helpers.js +6 -6
  398. package/dist/tools/tools.d.ts +15 -0
  399. package/dist/tools/tools.js +53 -17
  400. package/dist/tools/unadvertised-help.d.ts +5 -0
  401. package/dist/tools/unadvertised-help.js +39 -0
  402. package/dist/trace.d.ts +69 -0
  403. package/dist/trace.js +150 -0
  404. package/dist/update/nudge-credit.d.ts +4 -0
  405. package/dist/update/nudge-credit.js +53 -0
  406. package/dist/update/sdk-sync.d.ts +21 -0
  407. package/dist/update/sdk-sync.js +42 -0
  408. package/dist/update/update-checker.js +3 -3
  409. package/dist/update/update-nudge.d.ts +63 -6
  410. package/dist/update/update-nudge.js +128 -15
  411. package/dist/update/updater.d.ts +1 -9
  412. package/dist/update/updater.js +13 -8
  413. package/dist/version/peer-announce.d.ts +4 -0
  414. package/dist/version/peer-announce.js +30 -0
  415. package/dist/{server-version.js → version/server-version.js} +5 -1
  416. package/dist/version/version-nudge.d.ts +28 -0
  417. package/dist/version/version-nudge.js +40 -0
  418. package/dist/version/version-skew.d.ts +66 -0
  419. package/dist/version/version-skew.js +71 -0
  420. package/dist/visual/visual-diff.js +2 -2
  421. package/dist/visual/visual-tools.js +4 -4
  422. package/docs/README.md +55 -0
  423. package/docs/agent-cheatsheet.md +85 -0
  424. package/docs/architecture.md +113 -0
  425. package/docs/benchmarks.md +255 -0
  426. package/docs/debugging.md +102 -0
  427. package/docs/deploy-checks.md +69 -0
  428. package/docs/desktop-apps.md +256 -0
  429. package/docs/enterprise.md +62 -0
  430. package/docs/fixtures-dispatch-receiver.yml +76 -0
  431. package/docs/fixtures.md +45 -0
  432. package/docs/flows.md +166 -0
  433. package/docs/gate-plan.md +98 -0
  434. package/docs/gates.md +117 -0
  435. package/docs/getting-started.md +469 -0
  436. package/docs/human-control.md +63 -0
  437. package/docs/integration-patterns.md +171 -0
  438. package/docs/local-registry.md +126 -0
  439. package/docs/matrix/2.5.0/claude-code-machine.json +19 -0
  440. package/docs/matrix/2.5.0/codex-machine.json +20 -0
  441. package/docs/matrix/2.5.0/cursor-machine.json +22 -0
  442. package/docs/matrix/2.5.0/gemini-machine.json +22 -0
  443. package/docs/matrix/2.5.0/opencode-machine.json +22 -0
  444. package/docs/matrix/2.5.0/vscode-machine.json +22 -0
  445. package/docs/matrix/2.5.0/windsurf-machine.json +22 -0
  446. package/docs/matrix/MATRIX.md +26 -0
  447. package/docs/matrix/README.md +59 -0
  448. package/docs/mint.json +61 -0
  449. package/docs/multi-agent-testing.md +55 -0
  450. package/docs/platform-integration.md +122 -0
  451. package/docs/system-map.md +152 -0
  452. package/docs/telemetry-contract.md +214 -0
  453. package/docs/telemetry.md +191 -0
  454. package/docs/testing.md +82 -0
  455. package/docs/token-efficiency.md +80 -0
  456. package/docs/usage.md +1046 -0
  457. package/package.json +8 -5
  458. package/dist/cli-doctor.d.ts +0 -6
  459. package/dist/cli-doctor.js +0 -60
  460. package/dist/cli-launch.js +0 -112
  461. package/dist/daemon-resilience.d.ts +0 -22
  462. package/dist/daemon-resilience.js +0 -85
  463. package/dist/mcp-proxy.d.ts +0 -67
  464. package/dist/mcp-proxy.js +0 -337
  465. package/dist/tools/profiles.d.ts +0 -37
  466. package/dist/tools/profiles.js +0 -139
  467. /package/dist/{pairing-token.d.ts → bridge/pairing-token.d.ts} +0 -0
  468. /package/dist/{token-auth.d.ts → bridge/token-auth.d.ts} +0 -0
  469. /package/dist/{token-auth.js → bridge/token-auth.js} +0 -0
  470. /package/dist/{cli-verify.d.ts → cli/cli-verify.d.ts} +0 -0
  471. /package/dist/{cloud-cli.d.ts → cli/cloud-cli.d.ts} +0 -0
  472. /package/dist/{server-version.d.ts → version/server-version.d.ts} +0 -0
@@ -7,7 +7,7 @@ export interface JournalTarget {
7
7
  elapsed(): number;
8
8
  setJournal(recorder: JournalRecorder, reader?: JournalReader): void;
9
9
  }
10
- export interface JournalAttachDeps {
10
+ interface JournalAttachDeps {
11
11
  fs: FileSystemPort;
12
12
  reticleRoot: string;
13
13
  /** Journaling is on by default; the opt-out (`.reticle.json` journal:false / env) sets this false. */
@@ -19,3 +19,4 @@ export interface JournalAttachDeps {
19
19
  * journaling concern). The recorder's clock is the session's own elapsed time.
20
20
  */
21
21
  export declare function makeJournalAttach(deps: JournalAttachDeps): (session: JournalTarget) => void;
22
+ export {};
@@ -6,13 +6,13 @@ function headlineFor(report) {
6
6
  if (report.insufficientSamples) {
7
7
  return `envelope too new (need ${String(MIN_ENVELOPE_SAMPLES)} runs) — see causal summary${truncNote}`;
8
8
  }
9
- if (report.deviations.length === 0) {
10
- const s = report.nominalSegments === 1 ? '' : 's';
9
+ if (0 === report.deviations.length) {
10
+ const s = 1 === report.nominalSegments ? '' : 's';
11
11
  return `${String(report.nominalSegments)} segment${s} nominal${truncNote}`;
12
12
  }
13
13
  const routes = [...new Set(report.deviations.map((d) => d.route))].join(', ');
14
14
  const n = report.deviations.length;
15
- return `${String(n)} deviation${n === 1 ? '' : 's'}: ${routes}${truncNote}`;
15
+ return `${String(n)} deviation${1 === n ? '' : 's'}: ${routes}${truncNote}`;
16
16
  }
17
17
  /**
18
18
  * Judge observed segments against their per-route envelopes. Segments without a route, or whose
@@ -27,7 +27,7 @@ export function buildDeviationReport(envelopes, segments, zThreshold) {
27
27
  if (segment.route === undefined)
28
28
  continue;
29
29
  // A truncated segment's counts understate reality — judging it could read a false "nominal".
30
- if (segment.truncated === true) {
30
+ if (true === segment.truncated) {
31
31
  truncated += 1;
32
32
  continue;
33
33
  }
@@ -36,7 +36,7 @@ export function buildDeviationReport(envelopes, segments, zThreshold) {
36
36
  continue;
37
37
  judged += 1;
38
38
  const segDeviations = compareSegment(envelope, segment, zThreshold);
39
- if (segDeviations.length === 0)
39
+ if (0 === segDeviations.length)
40
40
  nominal += 1;
41
41
  else
42
42
  deviations.push(...segDeviations);
@@ -47,7 +47,7 @@ export function buildDeviationReport(envelopes, segments, zThreshold) {
47
47
  nominalSegments: nominal,
48
48
  judgedSegments: judged,
49
49
  truncatedSegments: truncated,
50
- insufficientSamples: judged === 0,
50
+ insufficientSamples: 0 === judged,
51
51
  };
52
52
  return { ...base, headline: headlineFor(base) };
53
53
  }
@@ -20,7 +20,7 @@ export async function reportAndAccumulate(store, segments, zThreshold) {
20
20
  if (segment.route === undefined)
21
21
  continue;
22
22
  // Never learn from a truncated sample — its understated counts would poison the baseline.
23
- if (segment.truncated === true)
23
+ if (true === segment.truncated)
24
24
  continue;
25
25
  const current = envelopes.get(segment.route) ?? emptyEnvelope(segment.route);
26
26
  envelopes.set(segment.route, addSegmentToEnvelope(current, segment));
@@ -1,7 +1,5 @@
1
1
  import type { FileSystemPort } from '../project/fs-port.js';
2
2
  import { type RouteEnvelope } from './envelope.js';
3
- /** Bumped on any breaking change to the persisted envelope shape (matches the runs/contract convention). */
4
- export declare const ENVELOPE_FILE_VERSION = 1;
5
3
  /**
6
4
  * Persists the learned per-route envelopes at `.reticle/envelopes.json`. Local, single-project statistics
7
5
  * (single-player memory stays OSS — OSS-VS-SERVER). Loads never throw: a missing, malformed, or
@@ -3,7 +3,7 @@ import { dirname } from 'node:path';
3
3
  import { reticleDirPaths } from '../project/reticle-dir.js';
4
4
  import { RouteEnvelopeSchema } from './envelope.js';
5
5
  /** Bumped on any breaking change to the persisted envelope shape (matches the runs/contract convention). */
6
- export const ENVELOPE_FILE_VERSION = 1;
6
+ const ENVELOPE_FILE_VERSION = 1;
7
7
  const EnvelopeFileSchema = z.object({
8
8
  version: z.literal(ENVELOPE_FILE_VERSION),
9
9
  routes: z.record(RouteEnvelopeSchema),
@@ -21,7 +21,7 @@ export declare function stddev(stats: MetricStats): number;
21
21
  /** How many stddevs above the mean `x` sits (0 when there's no spread yet). */
22
22
  export declare function zScore(stats: MetricStats, x: number): number;
23
23
  /** The metrics an envelope tracks per route. */
24
- export declare const ENVELOPE_METRICS: readonly ["durationMs", "net", "netErrors", "consoleErrors"];
24
+ declare const ENVELOPE_METRICS: readonly ["durationMs", "net", "netErrors", "consoleErrors"];
25
25
  export type EnvelopeMetric = (typeof ENVELOPE_METRICS)[number];
26
26
  export interface RouteEnvelope {
27
27
  route: string;
@@ -31,8 +31,6 @@ export interface RouteEnvelope {
31
31
  }
32
32
  /** Below this, an envelope is noise — the deviation report falls back to the causal summary. */
33
33
  export declare const MIN_ENVELOPE_SAMPLES = 3;
34
- /** Default flag threshold in stddevs. The number is a placeholder for fleet-calibrated priors. */
35
- export declare const DEFAULT_Z_THRESHOLD = 3;
36
34
  /** Persisted shape of a route envelope. Validated on load; a bad file degrades to no envelope. */
37
35
  export declare const RouteEnvelopeSchema: z.ZodObject<{
38
36
  route: z.ZodString;
@@ -229,3 +227,4 @@ export interface Deviation {
229
227
  * falls back to the causal summary in that case.
230
228
  */
231
229
  export declare function compareSegment(envelope: RouteEnvelope, segment: SegmentRollup, zThreshold?: number): Deviation[];
230
+ export {};
@@ -15,14 +15,14 @@ export function stddev(stats) {
15
15
  /** How many stddevs above the mean `x` sits (0 when there's no spread yet). */
16
16
  export function zScore(stats, x) {
17
17
  const sd = stddev(stats);
18
- return sd === 0 ? 0 : (x - stats.mean) / sd;
18
+ return 0 === sd ? 0 : (x - stats.mean) / sd;
19
19
  }
20
20
  /** The metrics an envelope tracks per route. */
21
- export const ENVELOPE_METRICS = ['durationMs', 'net', 'netErrors', 'consoleErrors'];
21
+ const ENVELOPE_METRICS = ['durationMs', 'net', 'netErrors', 'consoleErrors'];
22
22
  /** Below this, an envelope is noise — the deviation report falls back to the causal summary. */
23
23
  export const MIN_ENVELOPE_SAMPLES = 3;
24
24
  /** Default flag threshold in stddevs. The number is a placeholder for fleet-calibrated priors. */
25
- export const DEFAULT_Z_THRESHOLD = 3;
25
+ const DEFAULT_Z_THRESHOLD = 3;
26
26
  const MetricStatsSchema = z.object({
27
27
  count: z.number(),
28
28
  mean: z.number(),
@@ -8,7 +8,7 @@ export function mergeEventsBySeq(journal, buffer) {
8
8
  const bySeq = new Map();
9
9
  const noSeq = [];
10
10
  for (const event of [...journal, ...buffer]) {
11
- if (typeof event.seq === 'number')
11
+ if ('number' === typeof event.seq)
12
12
  bySeq.set(event.seq, event);
13
13
  else
14
14
  noSeq.push(event);
@@ -8,7 +8,7 @@ export interface JournalSink {
8
8
  export interface JournalReader {
9
9
  readEvents(): Promise<ReticleEvent[]>;
10
10
  }
11
- export interface JournalRecorderOptions {
11
+ interface JournalRecorderOptions {
12
12
  /** Injected elapsed-ms clock (never read from Date here — the clock-injection rule). */
13
13
  now: () => number;
14
14
  /** Flush the pending-event batch once this many accumulate. */
@@ -35,3 +35,4 @@ export declare class JournalRecorder {
35
35
  /** Persist any buffered events now (call on session end). Awaits the write chain to settle. */
36
36
  flush(): Promise<void>;
37
37
  }
38
+ export {};
@@ -27,7 +27,7 @@ export class JournalRecorder {
27
27
  const active = this.#active;
28
28
  if (active !== undefined) {
29
29
  out = { ...event, actionId: active.actionId, attribution: EventAttribution.WINDOW };
30
- if (typeof event.seq === 'number') {
30
+ if ('number' === typeof event.seq) {
31
31
  active.seqFrom =
32
32
  active.seqFrom === undefined ? event.seq : Math.min(active.seqFrom, event.seq);
33
33
  active.seqTo = active.seqTo === undefined ? event.seq : Math.max(active.seqTo, event.seq);
@@ -71,7 +71,7 @@ export class JournalRecorder {
71
71
  await this.#chain;
72
72
  }
73
73
  #enqueueFlush() {
74
- if (this.#pending.length === 0)
74
+ if (0 === this.#pending.length)
75
75
  return;
76
76
  const batch = this.#pending;
77
77
  this.#pending = [];
@@ -1,4 +1,4 @@
1
- import { EventType } from '@reticlehq/core';
1
+ import { EventType, StreamDirection } from '@reticlehq/core';
2
2
  function finalize(acc) {
3
3
  return {
4
4
  ...(acc.route === undefined ? {} : { route: acc.route }),
@@ -9,13 +9,13 @@ function finalize(acc) {
9
9
  net: { total: acc.netTotal, errors: acc.netErrors },
10
10
  consoleErrors: acc.consoleErrors,
11
11
  statePathsChanged: acc.statePaths,
12
- ...(acc.streams.frames === 0 ? {} : { streams: acc.streams }),
12
+ ...(0 === acc.streams.frames ? {} : { streams: acc.streams }),
13
13
  ...(acc.truncated ? { truncated: true } : {}),
14
14
  };
15
15
  }
16
16
  function isNetError(event) {
17
17
  const status = event.data['status'];
18
- return event.data['ok'] === false || (typeof status === 'number' && status >= 400);
18
+ return false === event.data['ok'] || ('number' === typeof status && status >= 400);
19
19
  }
20
20
  /**
21
21
  * Fold an ordered event list into route segments split at each ROUTE_CHANGE. Pure: no clock, no IO —
@@ -41,13 +41,13 @@ export function computeSegments(events) {
41
41
  if (acc !== undefined)
42
42
  segments.push(finalize(acc));
43
43
  const pathname = event.data['pathname'];
44
- acc = open(typeof pathname === 'string' ? pathname : undefined, event.t);
44
+ acc = open('string' === typeof pathname ? pathname : undefined, event.t);
45
45
  continue;
46
46
  }
47
47
  if (acc === undefined)
48
48
  acc = open(undefined, event.t);
49
49
  acc.to = event.t;
50
- if (typeof event.actionId === 'string')
50
+ if ('string' === typeof event.actionId)
51
51
  acc.actionIds.add(event.actionId);
52
52
  if (event.type === EventType.NET_REQUEST) {
53
53
  acc.netTotal += 1;
@@ -59,17 +59,17 @@ export function computeSegments(events) {
59
59
  }
60
60
  if (event.type === EventType.STATE_CHANGE) {
61
61
  const name = event.data['name'];
62
- if (typeof name === 'string' && !acc.statePaths.includes(name))
62
+ if ('string' === typeof name && !acc.statePaths.includes(name))
63
63
  acc.statePaths.push(name);
64
64
  }
65
65
  if (event.type === EventType.NET_STREAM) {
66
66
  acc.streams.frames += 1;
67
67
  const direction = event.data['direction'];
68
- if (direction === 'open')
68
+ if (StreamDirection.OPEN === direction)
69
69
  acc.streams.opened += 1;
70
- else if (direction === 'in')
70
+ else if (StreamDirection.IN === direction)
71
71
  acc.streams.in += 1;
72
- else if (direction === 'out')
72
+ else if (StreamDirection.OUT === direction)
73
73
  acc.streams.out += 1;
74
74
  }
75
75
  if (event.type === EventType.TRUNCATED || event.type === EventType.TRANSPORT_OVERFLOW) {
@@ -17,7 +17,7 @@ export interface SessionEndTarget {
17
17
  ambientCounts(): AmbientCounts;
18
18
  ownAmbientCounts(): AmbientCounts;
19
19
  }
20
- export interface SessionEndDeps {
20
+ interface SessionEndDeps {
21
21
  fs: FileSystemPort;
22
22
  reticleRoot: string;
23
23
  /** Journaling/persistence off (opt-out) → teardown is a no-op. */
@@ -29,3 +29,4 @@ export interface SessionEndDeps {
29
29
  * starts already knowing which regions churn.
30
30
  */
31
31
  export declare function makeSessionEnd(deps: SessionEndDeps): (session: SessionEndTarget) => Promise<void>;
32
+ export {};
@@ -37,7 +37,7 @@ export class SessionJournal {
37
37
  this.#sessionId = sessionId;
38
38
  }
39
39
  async appendEvents(events) {
40
- if (events.length === 0)
40
+ if (0 === events.length)
41
41
  return;
42
42
  await this.#ensureDir();
43
43
  const text = `${events.map((e) => JSON.stringify(e)).join('\n')}\n`;
@@ -108,11 +108,11 @@ export class SessionJournal {
108
108
  #ingestTail(tail) {
109
109
  const cache = this.#eventCache ?? (this.#eventCache = []);
110
110
  const end = tail.lastIndexOf('\n') + 1;
111
- if (end === 0)
111
+ if (0 === end)
112
112
  return 0; // no complete line yet
113
113
  const complete = tail.slice(0, end);
114
114
  for (const line of complete.split('\n')) {
115
- if (line.length === 0)
115
+ if (0 === line.length)
116
116
  continue;
117
117
  let parsed;
118
118
  try {
@@ -148,7 +148,7 @@ export class SessionJournal {
148
148
  }
149
149
  const out = [];
150
150
  for (const line of text.split('\n')) {
151
- if (line.length === 0)
151
+ if (0 === line.length)
152
152
  continue;
153
153
  let parsed;
154
154
  try {
@@ -70,20 +70,6 @@ export declare function assertEnterprise(feature: string, ctx: GateContext): voi
70
70
  /** Env names that carry the activation: the operator's key, and the issuer public key baked at release. */
71
71
  export declare const LICENSE_KEY_ENV = "RETICLE_LICENSE_KEY";
72
72
  export declare const LICENSE_PUBLIC_KEY_ENV = "RETICLE_LICENSE_PUBLIC_KEY";
73
- /**
74
- * Issuer public key COMPILED INTO the build. Empty in the source tree; the release pipeline replaces
75
- * this literal with the real spki PEM. Baking it (rather than only reading env) is what makes the
76
- * enterprise gate fail closed: a self-hosted operator can no longer disable enforcement by simply
77
- * never setting RETICLE_LICENSE_PUBLIC_KEY, because the baked key takes precedence. The public key is
78
- * safe to ship openly — it can only verify licenses, never mint them (that needs the private key).
79
- */
80
- export declare const BAKED_ISSUER_PUBLIC_KEY_PEM = "";
81
- /**
82
- * Resolve the issuer public-key PEM enforcement uses: the baked-in release key wins, so it can't be
83
- * turned off from the environment. Only when nothing is baked (dev/repo) does the env var apply — that
84
- * env path is the test/self-eval escape hatch, not the production switch.
85
- */
86
- export declare function resolveIssuerPublicKeyPem(env: NodeJS.ProcessEnv, baked?: string): string | undefined;
87
73
  /** The human-facing state of enterprise activation on this machine (what `reticle license status` shows). */
88
74
  interface LicenseReport {
89
75
  status: 'active' | 'missing' | 'invalid' | 'expired' | 'eval';
@@ -37,13 +37,13 @@ export function signLicenseKey(payload, privateKey) {
37
37
  }
38
38
  /** Verify a key against the issuer public key. Never throws — returns a structured status. */
39
39
  export function verifyLicenseKey(key, publicKey, now) {
40
- if (key === undefined || key.length === 0)
40
+ if (key === undefined || 0 === key.length)
41
41
  return { status: LicenseStatus.MISSING };
42
42
  const parts = key.split(KEY_SEP);
43
43
  if (parts.length !== 2 ||
44
44
  parts[0] === undefined ||
45
45
  parts[1] === undefined ||
46
- parts[0].length === 0) {
46
+ 0 === parts[0].length) {
47
47
  return { status: LicenseStatus.MALFORMED };
48
48
  }
49
49
  let json;
@@ -85,7 +85,7 @@ export class EnterpriseLicenseError extends Error {
85
85
  /** The issuer public key from the environment (set at release / by the operator); undefined if unset. */
86
86
  function issuerPublicKey() {
87
87
  const pem = process.env[LICENSE_PUBLIC_KEY_ENV];
88
- if (pem === undefined || pem.length === 0)
88
+ if (pem === undefined || 0 === pem.length)
89
89
  return undefined;
90
90
  try {
91
91
  return createPublicKey(pem);
@@ -122,20 +122,20 @@ export const LICENSE_PUBLIC_KEY_ENV = 'RETICLE_LICENSE_PUBLIC_KEY';
122
122
  * never setting RETICLE_LICENSE_PUBLIC_KEY, because the baked key takes precedence. The public key is
123
123
  * safe to ship openly — it can only verify licenses, never mint them (that needs the private key).
124
124
  */
125
- export const BAKED_ISSUER_PUBLIC_KEY_PEM = '';
125
+ const BAKED_ISSUER_PUBLIC_KEY_PEM = '';
126
126
  /**
127
127
  * Resolve the issuer public-key PEM enforcement uses: the baked-in release key wins, so it can't be
128
128
  * turned off from the environment. Only when nothing is baked (dev/repo) does the env var apply — that
129
129
  * env path is the test/self-eval escape hatch, not the production switch.
130
130
  */
131
- export function resolveIssuerPublicKeyPem(env, baked = BAKED_ISSUER_PUBLIC_KEY_PEM) {
131
+ function resolveIssuerPublicKeyPem(env, baked = BAKED_ISSUER_PUBLIC_KEY_PEM) {
132
132
  if (baked.length > 0)
133
133
  return baked;
134
134
  const envPem = env[LICENSE_PUBLIC_KEY_ENV];
135
135
  return envPem !== undefined && envPem.length > 0 ? envPem : undefined;
136
136
  }
137
137
  function loadPublicKey(pem) {
138
- if (pem === undefined || pem.length === 0)
138
+ if (pem === undefined || 0 === pem.length)
139
139
  return undefined;
140
140
  try {
141
141
  return createPublicKey(pem);
@@ -151,7 +151,7 @@ function loadPublicKey(pem) {
151
151
  */
152
152
  export function describeLicense(now, env = process.env, baked = BAKED_ISSUER_PUBLIC_KEY_PEM) {
153
153
  const pem = resolveIssuerPublicKeyPem(env, baked);
154
- if (pem === undefined || pem.length === 0) {
154
+ if (pem === undefined || 0 === pem.length) {
155
155
  // In a production runtime this is NOT a benign eval session — it is a mis-built release whose gate
156
156
  // is off, and assertEnterpriseFromEnv now denies rather than unlocking. Say so loudly here too.
157
157
  return isProductionEnv(env)
@@ -196,7 +196,7 @@ export function describeLicense(now, env = process.env, baked = BAKED_ISSUER_PUB
196
196
  /** True in a production runtime (NODE_ENV=production) — where a missing issuer key is a mis-built
197
197
  * release, not an eval session, so the gate must fail CLOSED rather than run features free. */
198
198
  function isProductionEnv(env) {
199
- return env['NODE_ENV'] === 'production';
199
+ return 'production' === env['NODE_ENV'];
200
200
  }
201
201
  /**
202
202
  * Gate an enterprise feature using env-resolved activation. Enforcement is ON when the issuer public key
package/dist/log.d.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  /**
2
2
  * Structured logging to stderr. stdout is reserved for the MCP stdio transport — never
3
3
  * write logs there.
4
+ *
5
+ * Every line carries `t`, an ISO-8601 wall clock, FIRST.
6
+ *
7
+ * It did not, and that cost a real investigation its conclusion: `~/.reticle/daemon-4400.log` had
8
+ * grown to 24MB of events and not one of them could be placed in time, so "the daemon vanished right
9
+ * behind the proxy" could only ever be "points at" and never "is". Ordering the key first also means
10
+ * a huge log can be bisected by eye, and by `sort`, without parsing it.
11
+ *
12
+ * The clock is read here rather than injected: this is the I/O boundary, not pure logic, and a
13
+ * logger that needs its caller to supply the time is a logger callers will route around.
4
14
  */
5
15
  export declare function log(event: string, fields?: Record<string, unknown>): void;
package/dist/log.js CHANGED
@@ -1,8 +1,18 @@
1
1
  /**
2
2
  * Structured logging to stderr. stdout is reserved for the MCP stdio transport — never
3
3
  * write logs there.
4
+ *
5
+ * Every line carries `t`, an ISO-8601 wall clock, FIRST.
6
+ *
7
+ * It did not, and that cost a real investigation its conclusion: `~/.reticle/daemon-4400.log` had
8
+ * grown to 24MB of events and not one of them could be placed in time, so "the daemon vanished right
9
+ * behind the proxy" could only ever be "points at" and never "is". Ordering the key first also means
10
+ * a huge log can be bisected by eye, and by `sort`, without parsing it.
11
+ *
12
+ * The clock is read here rather than injected: this is the I/O boundary, not pure logic, and a
13
+ * logger that needs its caller to supply the time is a logger callers will route around.
4
14
  */
5
15
  export function log(event, fields = {}) {
6
- const line = JSON.stringify({ event, ...fields });
16
+ const line = JSON.stringify({ t: new Date().toISOString(), event, ...fields });
7
17
  process.stderr.write(`${line}\n`);
8
18
  }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Does a SUCCESSFUL tool result actually describe a refusal?
3
+ *
4
+ * `isError` used to be set only when a handler threw. Every tool that returns a well-formed
5
+ * `{ error, recovery }` object instead — and that is half the surface — came back as protocol
6
+ * success with the flag unset, so anything branching on `isError` read a refusal as a result.
7
+ * Reported from a field sweep that had to special-case each tool's shape to score a run at all.
8
+ *
9
+ * A top-level `error` STRING is this codebase's refusal convention (see buildErrorPayload), so that
10
+ * is the whole test. Deliberately top-level only: `error` appears inside console entries and network
11
+ * rows as ordinary data, and flipping the flag for those would make it useless in the other direction.
12
+ */
13
+ export declare function resultIsError(result: unknown): boolean;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Does a SUCCESSFUL tool result actually describe a refusal?
3
+ *
4
+ * `isError` used to be set only when a handler threw. Every tool that returns a well-formed
5
+ * `{ error, recovery }` object instead — and that is half the surface — came back as protocol
6
+ * success with the flag unset, so anything branching on `isError` read a refusal as a result.
7
+ * Reported from a field sweep that had to special-case each tool's shape to score a run at all.
8
+ *
9
+ * A top-level `error` STRING is this codebase's refusal convention (see buildErrorPayload), so that
10
+ * is the whole test. Deliberately top-level only: `error` appears inside console entries and network
11
+ * rows as ordinary data, and flipping the flag for those would make it useless in the other direction.
12
+ */
13
+ export function resultIsError(result) {
14
+ if (typeof result !== 'object' || null === result || Array.isArray(result))
15
+ return false;
16
+ const error = result.error;
17
+ return 'string' === typeof error && error.length > 0;
18
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Reporting that the agent lost its Reticle tools.
3
+ *
4
+ * The proxy already writes a full account of an outage to ~/.reticle/mcp-proxy.log, which is exactly
5
+ * where nobody looks and nothing aggregates. So the one question the transport must answer — how
6
+ * often does a real user's MCP server go down, and does it come back — had no answer outside the
7
+ * machine it happened on.
8
+ *
9
+ * Capped at two events per proxy process, and the cap is the design rather than a limitation. One
10
+ * measured afternoon produced 547 proxy reconnects; an event per reconnect would bill for the
11
+ * pathology instead of measuring it, which is the same mistake the per-call `tool` event made before
12
+ * it was removed. What a dashboard needs is the SHARE OF SESSIONS that lose MCP at all (the first
13
+ * outage) and the share where it never came back on its own (the budget being spent).
14
+ */
15
+ import { OutageReason, OutageStage } from '@reticlehq/core';
16
+ /**
17
+ * `OutageStage` and `OutageReason` are core's — this re-export only saves the proxy an import. They
18
+ * cross the wire, so the vocabulary lives in the contract package and is never re-listed here.
19
+ */
20
+ export { OutageReason, OutageStage };
21
+ /** Reset between tests; a real process reports each stage at most once. */
22
+ export declare function resetOutageReporting(): void;
23
+ /**
24
+ * Report one stage of an outage, at most once per process. Fire-and-forget on purpose: this runs on
25
+ * the transport's recovery path, and a telemetry POST must never be the thing that delays — or
26
+ * fails — the reconnect it is describing.
27
+ */
28
+ export declare function reportMcpOutage(stage: OutageStage, facts: {
29
+ reason: string;
30
+ attempts: number;
31
+ pendingLost?: number;
32
+ }): void;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Reporting that the agent lost its Reticle tools.
3
+ *
4
+ * The proxy already writes a full account of an outage to ~/.reticle/mcp-proxy.log, which is exactly
5
+ * where nobody looks and nothing aggregates. So the one question the transport must answer — how
6
+ * often does a real user's MCP server go down, and does it come back — had no answer outside the
7
+ * machine it happened on.
8
+ *
9
+ * Capped at two events per proxy process, and the cap is the design rather than a limitation. One
10
+ * measured afternoon produced 547 proxy reconnects; an event per reconnect would bill for the
11
+ * pathology instead of measuring it, which is the same mistake the per-call `tool` event made before
12
+ * it was removed. What a dashboard needs is the SHARE OF SESSIONS that lose MCP at all (the first
13
+ * outage) and the share where it never came back on its own (the budget being spent).
14
+ */
15
+ import { OutageReason, OutageStage, TelemetryEventKind } from '@reticlehq/core';
16
+ import { getTelemetry } from '../telemetry/telemetry.js';
17
+ /**
18
+ * `OutageStage` and `OutageReason` are core's — this re-export only saves the proxy an import. They
19
+ * cross the wire, so the vocabulary lives in the contract package and is never re-listed here.
20
+ */
21
+ export { OutageReason, OutageStage };
22
+ /**
23
+ * The proxy's reason strings are free text: they also feed `proxyLog`, where prose is fine, and the
24
+ * wire refuses anything unbounded. Unrecognised reports as `other` rather than being forwarded, so a
25
+ * new drop path can appear in the proxy without an unclassified string leaving the machine.
26
+ */
27
+ const KNOWN_REASONS = new Set(Object.values(OutageReason));
28
+ function outageReason(raw) {
29
+ return KNOWN_REASONS.has(raw) ? raw : OutageReason.OTHER;
30
+ }
31
+ const reported = new Set();
32
+ /** Reset between tests; a real process reports each stage at most once. */
33
+ export function resetOutageReporting() {
34
+ reported.clear();
35
+ }
36
+ /**
37
+ * Report one stage of an outage, at most once per process. Fire-and-forget on purpose: this runs on
38
+ * the transport's recovery path, and a telemetry POST must never be the thing that delays — or
39
+ * fails — the reconnect it is describing.
40
+ */
41
+ export function reportMcpOutage(stage, facts) {
42
+ if (reported.has(stage))
43
+ return;
44
+ reported.add(stage);
45
+ void getTelemetry().emit(TelemetryEventKind.MCP_CONNECTION_LOST, {
46
+ outage: {
47
+ stage,
48
+ reason: outageReason(facts.reason),
49
+ attempts: facts.attempts,
50
+ // Always sent, including zero: zero is the finding — a drop no agent could feel. See
51
+ // McpOutageSchema.pendingLost.
52
+ pendingLost: facts.pendingLost ?? 0,
53
+ },
54
+ });
55
+ }