@reticlehq/server 3.7.0 → 3.8.1

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 (578) hide show
  1. package/SKILL.md +59 -68
  2. package/bin/reticle.js +9 -2
  3. package/dist/command/cli/adhoc-suite.js +1 -1
  4. package/dist/command/cli/adhoc-verdict.d.ts +12 -0
  5. package/dist/command/cli/adhoc-verdict.js +62 -4
  6. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  7. package/dist/command/cli/answers/gate-hook-message.js +5 -1
  8. package/dist/command/cli/auth/cloud-session.d.ts +11 -19
  9. package/dist/command/cli/auth/cloud-session.js +23 -0
  10. package/dist/command/cli/auth/device-flow.d.ts +3 -37
  11. package/dist/command/cli/cli-doctor.js +66 -21
  12. package/dist/command/cli/cli-flow-commands.js +53 -11
  13. package/dist/command/cli/cli-kill.d.ts +8 -0
  14. package/dist/command/cli/cli-kill.js +43 -3
  15. package/dist/command/cli/cli-parse-feedback.d.ts +4 -0
  16. package/dist/command/cli/cli-parse-feedback.js +13 -1
  17. package/dist/command/cli/cli-parse-grammar.d.ts +1 -2
  18. package/dist/command/cli/cli-parse-grammar.js +1 -6
  19. package/dist/command/cli/cli-parse-serve.d.ts +24 -0
  20. package/dist/command/cli/cli-parse-serve.js +124 -0
  21. package/dist/command/cli/cli-parse.d.ts +12 -11
  22. package/dist/command/cli/cli-parse.js +100 -123
  23. package/dist/command/cli/cli-usage.d.ts +0 -11
  24. package/dist/command/cli/cli-usage.js +43 -16
  25. package/dist/command/cli/cli-verify.d.ts +1 -1
  26. package/dist/command/cli/cli-verify.js +29 -14
  27. package/dist/command/cli/cloud-cli.js +27 -9
  28. package/dist/command/cli/cloud-kit.js +3 -3
  29. package/dist/command/cli/cloud-link.d.ts +1 -20
  30. package/dist/command/cli/cloud-link.js +2 -0
  31. package/dist/command/cli/cloud-login.d.ts +6 -2
  32. package/dist/command/cli/cloud-login.js +13 -41
  33. package/dist/command/cli/config/checkout.d.ts +10 -0
  34. package/dist/command/cli/config/checkout.js +78 -0
  35. package/dist/command/cli/doctor/doctor-agent-link.d.ts +23 -0
  36. package/dist/command/cli/doctor/doctor-agent-link.js +28 -0
  37. package/dist/command/cli/doctor/doctor-coverage-line.js +1 -7
  38. package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
  39. package/dist/command/cli/doctor/doctor-rows.js +4 -0
  40. package/dist/command/cli/drive/drive-attach.d.ts +5 -0
  41. package/dist/command/cli/drive/drive-attach.js +21 -1
  42. package/dist/command/cli/hook/codex-transcript.d.ts +20 -0
  43. package/dist/command/cli/hook/codex-transcript.js +224 -0
  44. package/dist/command/cli/hook/episode-structure.d.ts +24 -0
  45. package/dist/command/cli/hook/episode-structure.js +138 -0
  46. package/dist/command/cli/hook/hook-command.d.ts +9 -0
  47. package/dist/command/cli/hook/hook-command.js +211 -0
  48. package/dist/command/cli/hook/hook-fast.d.ts +31 -0
  49. package/dist/command/cli/hook/hook-fast.js +136 -0
  50. package/dist/command/cli/hook/prompt-hook.d.ts +30 -0
  51. package/dist/command/cli/hook/prompt-hook.js +199 -0
  52. package/dist/command/cli/hook/tool-hook.d.ts +21 -0
  53. package/dist/command/cli/hook/tool-hook.js +259 -0
  54. package/dist/command/cli/launch/cli-launch.d.ts +2 -0
  55. package/dist/command/cli/launch/cli-launch.js +22 -2
  56. package/dist/command/cli/lifecycle/daemon-lifecycle.js +28 -2
  57. package/dist/command/cli/mcp-command.d.ts +9 -0
  58. package/dist/command/cli/mcp-command.js +127 -41
  59. package/dist/command/cli/open-navigate.d.ts +43 -0
  60. package/dist/command/cli/open-navigate.js +85 -0
  61. package/dist/command/cli/ports/port-holder.d.ts +16 -4
  62. package/dist/command/cli/ports/port-holder.js +58 -12
  63. package/dist/command/cli/ports/resolve/cli-port.js +18 -2
  64. package/dist/command/cli/project-name.d.ts +1 -7
  65. package/dist/command/cli/project-name.js +1 -0
  66. package/dist/command/cli/report-command.d.ts +8 -2
  67. package/dist/command/cli/report-command.js +95 -18
  68. package/dist/command/cli/status-fields.d.ts +9 -2
  69. package/dist/command/cli/status-fields.js +148 -4
  70. package/dist/command/cli/try-command.d.ts +3 -4
  71. package/dist/command/cli/try-command.js +6 -11
  72. package/dist/command/cli/verify-results.d.ts +4 -1
  73. package/dist/command/cli/verify-results.js +3 -1
  74. package/dist/command/cli.d.ts +1 -7
  75. package/dist/command/cli.js +79 -160
  76. package/dist/command/daemon/daemon-resilience.d.ts +6 -1
  77. package/dist/command/daemon/daemon-resilience.js +31 -18
  78. package/dist/command/daemon/daemon.d.ts +11 -0
  79. package/dist/command/daemon/daemon.js +70 -2
  80. package/dist/command/daemon/lifetime/daemon-usefulness.d.ts +2 -0
  81. package/dist/command/daemon/lifetime/daemon-usefulness.js +13 -2
  82. package/dist/command/daemon/wake-decision.js +4 -2
  83. package/dist/command/daemon/win32-escape.d.ts +32 -0
  84. package/dist/command/daemon/win32-escape.js +119 -0
  85. package/dist/command/setup/agent-configs.d.ts +9 -0
  86. package/dist/command/setup/agent-configs.js +9 -0
  87. package/dist/command/setup/auto-approve.d.ts +10 -3
  88. package/dist/command/setup/auto-approve.js +51 -3
  89. package/dist/command/setup/bringup/dev-server-files.d.ts +1 -9
  90. package/dist/command/setup/bringup/dev-server-wait.js +5 -1
  91. package/dist/command/setup/bringup/ensure-daemon.js +4 -7
  92. package/dist/command/setup/init/init-host.js +6 -0
  93. package/dist/command/setup/init/init-port.js +5 -4
  94. package/dist/command/setup/init/init-runtime.js +7 -1
  95. package/dist/command/setup/node-effects.d.ts +8 -0
  96. package/dist/command/setup/node-effects.js +36 -4
  97. package/dist/command/setup/probe/dev-port.d.ts +26 -0
  98. package/dist/command/setup/probe/dev-port.js +117 -0
  99. package/dist/command/setup/probe/page-probe.d.ts +1 -1
  100. package/dist/command/setup/probe/page-probe.js +11 -3
  101. package/dist/command/setup/remaining-steps.d.ts +0 -7
  102. package/dist/command/setup/remaining-steps.js +3 -2
  103. package/dist/command/setup/run-setup.d.ts +11 -0
  104. package/dist/command/setup/run-setup.js +33 -5
  105. package/dist/command/setup/setup-command.d.ts +2 -0
  106. package/dist/command/setup/setup-command.js +22 -4
  107. package/dist/command/update/updater.d.ts +1 -6
  108. package/dist/command/update/updater.js +4 -5
  109. package/dist/command/update/version-seen.d.ts +24 -0
  110. package/dist/command/update/version-seen.js +65 -0
  111. package/dist/command/version/peer-announce.d.ts +9 -1
  112. package/dist/command/version/peer-announce.js +25 -2
  113. package/dist/command/version/sdk-fix.d.ts +5 -6
  114. package/dist/command/version/sdk-fix.js +17 -32
  115. package/dist/command/version/version-skew.d.ts +16 -1
  116. package/dist/command/version/version-skew.js +84 -10
  117. package/dist/features/crawl/crawl-tools.js +2 -2
  118. package/dist/features/crawl/crawl.js +2 -0
  119. package/dist/features/exhaust/ledger.d.ts +15 -96
  120. package/dist/features/exhaust/ledger.js +3 -3
  121. package/dist/features/harness/drive-runs.d.ts +28 -4
  122. package/dist/features/harness/drive-runs.js +99 -7
  123. package/dist/features/harness/drivers.d.ts +1 -1
  124. package/dist/features/harness/drivers.js +1 -1
  125. package/dist/features/harness/harness.d.ts +5 -0
  126. package/dist/features/harness/harness.js +24 -12
  127. package/dist/features/harness/platform/platform-drives.d.ts +7 -1
  128. package/dist/features/harness/platform/platform-drives.js +12 -7
  129. package/dist/features/harness/platform/refusal.d.ts +1 -1
  130. package/dist/features/harness/platform/refusal.js +4 -4
  131. package/dist/features/harness/platform/remote-drive.js +70 -28
  132. package/dist/features/harness/platform/server-driver.js +22 -1
  133. package/dist/features/harness/platform-config.d.ts +1 -10
  134. package/dist/features/harness/platform-config.js +0 -20
  135. package/dist/features/license/license.d.ts +2 -14
  136. package/dist/features/visual/step-shots.d.ts +33 -1
  137. package/dist/features/visual/step-shots.js +155 -1
  138. package/dist/features/visual/visual-tools.js +12 -4
  139. package/dist/hooks/coding-agents.d.ts +6 -0
  140. package/dist/hooks/coding-agents.js +24 -3
  141. package/dist/hooks/episode-stamp.d.ts +32 -0
  142. package/dist/hooks/episode-stamp.js +61 -0
  143. package/dist/hooks/hook-commands.js +19 -9
  144. package/dist/index.d.ts +5 -1
  145. package/dist/index.js +66 -24
  146. package/dist/judgement/app-graph/journal-steps.d.ts +8 -0
  147. package/dist/judgement/app-graph/journal-steps.js +92 -0
  148. package/dist/judgement/capsule/capsule-store.d.ts +2 -39
  149. package/dist/judgement/domain/domain-model.js +1 -10
  150. package/dist/judgement/domain/domain-tools.js +4 -2
  151. package/dist/judgement/runs/artifact/run-store.d.ts +28 -8
  152. package/dist/judgement/runs/artifact/run-store.js +153 -28
  153. package/dist/judgement/runs/default-run-id.d.ts +3 -1
  154. package/dist/judgement/runs/default-run-id.js +15 -3
  155. package/dist/judgement/runs/drive-run.d.ts +3 -3
  156. package/dist/judgement/runs/drive-run.js +11 -7
  157. package/dist/judgement/runs/run-ledger.d.ts +21 -0
  158. package/dist/judgement/runs/run-ledger.js +143 -0
  159. package/dist/judgement/runs/runner-port.d.ts +1 -1
  160. package/dist/judgement/runs/runner-port.js +8 -2
  161. package/dist/judgement/runs/verification-sync.d.ts +4 -3
  162. package/dist/judgement/runs/verification-sync.js +27 -5
  163. package/dist/language/flows/affected-tools.js +2 -1
  164. package/dist/language/flows/annotate-notes/annotate.js +8 -3
  165. package/dist/language/flows/annotate-tools.js +1 -1
  166. package/dist/language/flows/change/affected.d.ts +8 -0
  167. package/dist/language/flows/change/affected.js +20 -7
  168. package/dist/language/flows/decision.js +19 -4
  169. package/dist/language/flows/fields/flow-secret-field.d.ts +9 -0
  170. package/dist/language/flows/fields/flow-secret-field.js +67 -5
  171. package/dist/language/flows/flow-anchor.d.ts +5 -0
  172. package/dist/language/flows/flow-anchor.js +4 -0
  173. package/dist/language/flows/flow-cross-step.d.ts +7 -1
  174. package/dist/language/flows/flow-cross-step.js +9 -0
  175. package/dist/language/flows/flow-expect-grammar.js +15 -10
  176. package/dist/language/flows/flow-intent.js +6 -1
  177. package/dist/language/flows/flow-journey.d.ts +8 -0
  178. package/dist/language/flows/flow-journey.js +13 -0
  179. package/dist/language/flows/flow-lease.d.ts +27 -0
  180. package/dist/language/flows/flow-lease.js +59 -0
  181. package/dist/language/flows/flow-replay-run.d.ts +1 -87
  182. package/dist/language/flows/flow-replay-run.js +111 -310
  183. package/dist/language/flows/flow-replay.js +21 -19
  184. package/dist/language/flows/flow-replayable.d.ts +38 -0
  185. package/dist/language/flows/flow-replayable.js +179 -0
  186. package/dist/language/flows/flow-start-path.d.ts +108 -0
  187. package/dist/language/flows/flow-start-path.js +313 -0
  188. package/dist/language/flows/flow-step-runners.d.ts +23 -2
  189. package/dist/language/flows/flow-step-runners.js +191 -32
  190. package/dist/language/flows/flow-store-for-session.d.ts +8 -1
  191. package/dist/language/flows/flow-store-for-session.js +6 -0
  192. package/dist/language/flows/flow-tools.d.ts +2 -23
  193. package/dist/language/flows/flow-tools.js +63 -113
  194. package/dist/language/flows/flows.d.ts +4 -6
  195. package/dist/language/flows/flows.js +90 -15
  196. package/dist/language/flows/heal-run.d.ts +10 -4
  197. package/dist/language/flows/heal-run.js +26 -9
  198. package/dist/language/flows/recording/flake.d.ts +3 -27
  199. package/dist/language/flows/recording/flake.js +1 -1
  200. package/dist/language/flows/recording/recording-backtrack.js +1 -4
  201. package/dist/language/flows/recording/tape/recordings.d.ts +11 -1
  202. package/dist/language/flows/recording/tape/recordings.js +9 -3
  203. package/dist/language/flows/replay.d.ts +25 -5
  204. package/dist/language/flows/replay.js +83 -16
  205. package/dist/language/flows/stores/assertion-tiers-store.js +1 -1
  206. package/dist/language/flows/suite/coverage.d.ts +9 -0
  207. package/dist/language/flows/suite/coverage.js +12 -1
  208. package/dist/language/flows/suite-selection.d.ts +25 -0
  209. package/dist/language/flows/suite-selection.js +41 -9
  210. package/dist/machine/git-tracks.d.ts +6 -0
  211. package/dist/machine/git-tracks.js +36 -0
  212. package/dist/memory/cloud/background-sync.d.ts +25 -0
  213. package/dist/memory/cloud/background-sync.js +79 -0
  214. package/dist/memory/cloud/cloud-config.d.ts +12 -1
  215. package/dist/memory/cloud/cloud-config.js +39 -13
  216. package/dist/memory/cloud/cloud-sync.d.ts +3 -24
  217. package/dist/memory/cloud/cloud-sync.js +5 -2
  218. package/dist/memory/cloud/harness-config.d.ts +0 -7
  219. package/dist/memory/cloud/memory-scope.d.ts +19 -0
  220. package/dist/memory/cloud/memory-scope.js +48 -0
  221. package/dist/memory/cloud/sync-answer.d.ts +43 -0
  222. package/dist/memory/cloud/sync-answer.js +42 -0
  223. package/dist/memory/cloud/sync-cycle.d.ts +40 -10
  224. package/dist/memory/cloud/sync-cycle.js +97 -144
  225. package/dist/memory/cloud/sync-daemon.d.ts +50 -3
  226. package/dist/memory/cloud/sync-daemon.js +473 -83
  227. package/dist/memory/cloud/sync-describe.d.ts +28 -0
  228. package/dist/memory/cloud/sync-describe.js +92 -0
  229. package/dist/memory/cloud/sync-disk.d.ts +9 -1
  230. package/dist/memory/cloud/sync-disk.js +137 -33
  231. package/dist/memory/cloud/sync-flow-versions.d.ts +26 -0
  232. package/dist/memory/cloud/sync-flow-versions.js +42 -0
  233. package/dist/memory/impact/impact-store.js +32 -15
  234. package/dist/memory/intent/intent-shard.d.ts +41 -266
  235. package/dist/memory/intent/intent-tools.js +20 -61
  236. package/dist/memory/intent/record-request.d.ts +27 -0
  237. package/dist/memory/intent/record-request.js +88 -0
  238. package/dist/memory/intent/settled-words.js +9 -1
  239. package/dist/memory/journal/drive-flow.d.ts +3 -0
  240. package/dist/memory/journal/drive-flow.js +11 -41
  241. package/dist/memory/journal/envelope-store.js +1 -1
  242. package/dist/memory/journal/envelope.d.ts +6 -154
  243. package/dist/memory/journal/episode-log.d.ts +107 -0
  244. package/dist/memory/journal/episode-log.js +302 -0
  245. package/dist/memory/journal/journal-recorder.d.ts +7 -0
  246. package/dist/memory/journal/journal-recorder.js +22 -9
  247. package/dist/memory/journal/on-disk/ambient-file.d.ts +1 -7
  248. package/dist/memory/journal/on-disk/ambient-file.js +1 -1
  249. package/dist/memory/journal/on-disk/workspace-gitignore.d.ts +24 -3
  250. package/dist/memory/journal/on-disk/workspace-gitignore.js +38 -7
  251. package/dist/memory/journal/on-disk/workspace-tiers.js +7 -0
  252. package/dist/memory/journal/self-observation.js +3 -1
  253. package/dist/memory/journal/session-end.js +23 -9
  254. package/dist/memory/journal/session-journal.js +39 -20
  255. package/dist/memory/project/artifact-root-resolver.d.ts +14 -1
  256. package/dist/memory/project/artifact-root-resolver.js +68 -23
  257. package/dist/memory/project/artifact-root.d.ts +17 -3
  258. package/dist/memory/project/artifact-root.js +47 -9
  259. package/dist/memory/project/fs/fs-port.d.ts +5 -0
  260. package/dist/memory/project/fs/fs-port.js +13 -0
  261. package/dist/memory/project/learned-routes.d.ts +3 -4
  262. package/dist/memory/project/learned-routes.js +3 -11
  263. package/dist/memory/project/link-directory.js +5 -2
  264. package/dist/memory/project/root-claims.d.ts +3 -1
  265. package/dist/memory/project/root-claims.js +41 -7
  266. package/dist/memory/project/session-root.d.ts +1 -1
  267. package/dist/memory/project/session-root.js +1 -15
  268. package/dist/memory/project/sync-status.js +5 -6
  269. package/dist/memory/recall/memory-tools.js +2 -2
  270. package/dist/memory/recall/platform-memory.d.ts +3 -1
  271. package/dist/memory/recall/platform-memory.js +9 -1
  272. package/dist/memory/recall/project-memory.js +15 -19
  273. package/dist/portal/bridge/auth-failure-reason.d.ts +13 -0
  274. package/dist/portal/bridge/auth-failure-reason.js +19 -0
  275. package/dist/portal/bridge/bridge.d.ts +19 -4
  276. package/dist/portal/bridge/bridge.js +150 -177
  277. package/dist/portal/bridge/harness-request.d.ts +15 -0
  278. package/dist/portal/bridge/harness-request.js +19 -0
  279. package/dist/portal/bridge/origin/origin-follow.d.ts +46 -0
  280. package/dist/portal/bridge/origin/origin-follow.js +110 -0
  281. package/dist/portal/bridge/pairing-token.d.ts +6 -0
  282. package/dist/portal/bridge/pairing-token.js +47 -16
  283. package/dist/portal/bridge/protocol-skew.d.ts +27 -2
  284. package/dist/portal/bridge/protocol-skew.js +66 -2
  285. package/dist/portal/bridge/session-nonces.d.ts +46 -0
  286. package/dist/portal/bridge/session-nonces.js +72 -0
  287. package/dist/portal/input/viewport-tools.d.ts +31 -0
  288. package/dist/portal/input/viewport-tools.js +106 -15
  289. package/dist/portal/pool/bounded-close.d.ts +23 -0
  290. package/dist/portal/pool/bounded-close.js +38 -0
  291. package/dist/portal/pool/browser-pool.d.ts +44 -39
  292. package/dist/portal/pool/browser-pool.js +247 -95
  293. package/dist/portal/pool/context-permissions.d.ts +9 -1
  294. package/dist/portal/pool/context-permissions.js +26 -0
  295. package/dist/portal/pool/lease-emulation.d.ts +37 -0
  296. package/dist/portal/pool/lease-emulation.js +29 -0
  297. package/dist/portal/pool/playwright-launcher.d.ts +6 -0
  298. package/dist/portal/pool/playwright-launcher.js +74 -7
  299. package/dist/portal/pool/pool-contract.d.ts +23 -1
  300. package/dist/portal/pool/pool-lease.d.ts +128 -0
  301. package/dist/portal/pool/pool-lease.js +49 -0
  302. package/dist/portal/pool/zero-install.d.ts +8 -1
  303. package/dist/portal/pool/zero-install.js +24 -2
  304. package/dist/portal/production/production-activation.d.ts +136 -0
  305. package/dist/portal/production/production-activation.js +173 -0
  306. package/dist/portal/production/production-drive.d.ts +52 -0
  307. package/dist/portal/production/production-drive.js +301 -0
  308. package/dist/portal/production/production-hello.d.ts +23 -0
  309. package/dist/portal/production/production-hello.js +23 -0
  310. package/dist/portal/realm/web-realm.js +42 -15
  311. package/dist/portal/session/control-envelope.d.ts +1 -1
  312. package/dist/portal/session/dev-server/served-document.d.ts +0 -5
  313. package/dist/portal/session/dev-server/served-document.js +6 -8
  314. package/dist/portal/session/facts/handshake-facts.d.ts +8 -1
  315. package/dist/portal/session/first-run-wiring.d.ts +3 -36
  316. package/dist/portal/session/first-run-wiring.js +10 -103
  317. package/dist/portal/session/live-control-tools.js +61 -19
  318. package/dist/portal/session/no-session-next-action.d.ts +11 -0
  319. package/dist/portal/session/no-session-next-action.js +40 -15
  320. package/dist/portal/session/no-session-watch.d.ts +7 -0
  321. package/dist/portal/session/no-session-watch.js +67 -23
  322. package/dist/portal/session/output-budget.d.ts +10 -0
  323. package/dist/portal/session/output-budget.js +16 -0
  324. package/dist/portal/session/presence/session-lease.d.ts +2 -0
  325. package/dist/portal/session/presence/session-lease.js +8 -0
  326. package/dist/portal/session/recorded-gaps.d.ts +15 -11
  327. package/dist/portal/session/recorded-gaps.js +39 -18
  328. package/dist/portal/session/serving-directory.d.ts +24 -2
  329. package/dist/portal/session/serving-directory.js +93 -5
  330. package/dist/portal/session/session-info.d.ts +26 -0
  331. package/dist/portal/session/session-info.js +20 -0
  332. package/dist/portal/session/session-manager.d.ts +35 -3
  333. package/dist/portal/session/session-manager.js +69 -14
  334. package/dist/portal/session/session-successor.js +1 -9
  335. package/dist/portal/session/session-tools.js +22 -4
  336. package/dist/portal/session/session.d.ts +10 -10
  337. package/dist/portal/session/session.js +37 -29
  338. package/dist/portal/session/zero-install-first-call.d.ts +7 -2
  339. package/dist/portal/session/zero-install-first-call.js +43 -20
  340. package/dist/start-wiring.d.ts +2 -2
  341. package/dist/start-wiring.js +17 -3
  342. package/dist/status-payload.d.ts +11 -1
  343. package/dist/status-payload.js +7 -1
  344. package/dist/surface/agent-presence-grace.d.ts +11 -0
  345. package/dist/surface/agent-presence-grace.js +34 -0
  346. package/dist/surface/http-server.d.ts +12 -1
  347. package/dist/surface/http-server.js +64 -15
  348. package/dist/surface/mcp/faults/mcp-outage.d.ts +12 -2
  349. package/dist/surface/mcp/faults/mcp-outage.js +19 -1
  350. package/dist/surface/mcp/mcp-proxy.d.ts +17 -74
  351. package/dist/surface/mcp/mcp-proxy.js +194 -267
  352. package/dist/surface/mcp/mcp.d.ts +20 -3
  353. package/dist/surface/mcp/mcp.js +88 -25
  354. package/dist/surface/mcp/proxy/drive-calls.d.ts +44 -0
  355. package/dist/surface/mcp/proxy/drive-calls.js +114 -5
  356. package/dist/surface/mcp/proxy/proxy-boot.d.ts +11 -0
  357. package/dist/surface/mcp/proxy/proxy-boot.js +1 -0
  358. package/dist/surface/mcp/proxy/proxy-daemon-probe.d.ts +6 -0
  359. package/dist/surface/mcp/proxy/proxy-daemon-probe.js +14 -1
  360. package/dist/surface/mcp/proxy/proxy-handshake.d.ts +34 -2
  361. package/dist/surface/mcp/proxy/proxy-handshake.js +76 -8
  362. package/dist/surface/mcp/server-instructions.js +35 -16
  363. package/dist/surface/mcp/shared-params.d.ts +8 -0
  364. package/dist/surface/mcp/shared-params.js +15 -1
  365. package/dist/surface/mcp/sse-frame-parser.d.ts +11 -0
  366. package/dist/surface/mcp/sse-frame-parser.js +18 -0
  367. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  368. package/dist/surface/mcp/surface-vocabulary.js +13 -0
  369. package/dist/surface/mcp/tool-catalog-cache.d.ts +2 -0
  370. package/dist/surface/mcp/tool-catalog-cache.js +14 -4
  371. package/dist/surface/tools/account-tool.d.ts +4 -3
  372. package/dist/surface/tools/account-tool.js +20 -31
  373. package/dist/surface/tools/act/act-danger.d.ts +2 -0
  374. package/dist/surface/tools/act/act-danger.js +41 -14
  375. package/dist/surface/tools/act/act-observation.d.ts +11 -0
  376. package/dist/surface/tools/act/act-observation.js +33 -0
  377. package/dist/surface/tools/act/act-preflight.js +10 -3
  378. package/dist/surface/tools/act/act-sequence-retry.js +2 -1
  379. package/dist/surface/tools/act/act-target.js +19 -5
  380. package/dist/surface/tools/act/durable.js +1 -1
  381. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +9 -7
  382. package/dist/surface/tools/act/navigation/navigate-arrival.js +11 -14
  383. package/dist/surface/tools/act/unsettled-find.d.ts +36 -0
  384. package/dist/surface/tools/act/unsettled-find.js +71 -0
  385. package/dist/surface/tools/act-sequence-tool.js +53 -24
  386. package/dist/surface/tools/act-tools.d.ts +2 -3
  387. package/dist/surface/tools/act-tools.js +49 -47
  388. package/dist/surface/tools/agent/compact-envelope.d.ts +2 -2
  389. package/dist/surface/tools/agent/for-the-agent.js +41 -3
  390. package/dist/surface/tools/assert/assert-grade.js +8 -3
  391. package/dist/surface/tools/assert/assert-verdict.js +4 -2
  392. package/dist/surface/tools/browser-tools.js +7 -4
  393. package/dist/surface/tools/chat-drives.js +50 -25
  394. package/dist/surface/tools/coverage-tools.js +1 -1
  395. package/dist/surface/tools/dynamic-tools.d.ts +8 -0
  396. package/dist/surface/tools/dynamic-tools.js +89 -34
  397. package/dist/surface/tools/empty-session-list.d.ts +18 -25
  398. package/dist/surface/tools/empty-session-list.js +67 -38
  399. package/dist/surface/tools/error-recovery.d.ts +17 -7
  400. package/dist/surface/tools/error-recovery.js +53 -20
  401. package/dist/surface/tools/explore-tools.d.ts +10 -0
  402. package/dist/surface/tools/explore-tools.js +72 -19
  403. package/dist/surface/tools/feedback-tools.js +23 -2
  404. package/dist/surface/tools/gap-novelty.d.ts +6 -0
  405. package/dist/surface/tools/gap-novelty.js +9 -0
  406. package/dist/surface/tools/gaps/capability-absences.js +4 -3
  407. package/dist/surface/tools/harness-explore.d.ts +1 -1
  408. package/dist/surface/tools/harness-explore.js +6 -4
  409. package/dist/surface/tools/harness-gate.d.ts +43 -21
  410. package/dist/surface/tools/harness-gate.js +55 -81
  411. package/dist/surface/tools/harness-script.d.ts +2 -0
  412. package/dist/surface/tools/harness-script.js +11 -6
  413. package/dist/surface/tools/harness-toolset.js +3 -4
  414. package/dist/surface/tools/invoke-tool.d.ts +0 -8
  415. package/dist/surface/tools/invoke-tool.js +164 -178
  416. package/dist/surface/tools/lease-hint.d.ts +9 -0
  417. package/dist/surface/tools/lease-hint.js +22 -3
  418. package/dist/surface/tools/lease-permissions.d.ts +1 -1
  419. package/dist/surface/tools/lease-readiness.d.ts +55 -0
  420. package/dist/surface/tools/lease-readiness.js +150 -2
  421. package/dist/surface/tools/lease-tools.d.ts +3 -75
  422. package/dist/surface/tools/lease-tools.js +124 -188
  423. package/dist/surface/tools/map-tools.d.ts +20 -0
  424. package/dist/surface/tools/map-tools.js +145 -0
  425. package/dist/surface/tools/merge-tools.js +11 -7
  426. package/dist/surface/tools/next-step.js +6 -3
  427. package/dist/surface/tools/observe-tools.js +46 -35
  428. package/dist/surface/tools/platform-moment.d.ts +3 -12
  429. package/dist/surface/tools/platform-moment.js +12 -24
  430. package/dist/surface/tools/read/complete-snapshot.d.ts +7 -1
  431. package/dist/surface/tools/read/complete-snapshot.js +13 -2
  432. package/dist/surface/tools/read/query-paginate.js +6 -0
  433. package/dist/surface/tools/read/query-shape.d.ts +9 -0
  434. package/dist/surface/tools/read/query-shape.js +15 -0
  435. package/dist/surface/tools/read/snapshot-unmounted-note.d.ts +1 -0
  436. package/dist/surface/tools/read/snapshot-unmounted-note.js +73 -0
  437. package/dist/surface/tools/read-tools.js +5 -5
  438. package/dist/surface/tools/real-input-attempt.d.ts +11 -0
  439. package/dist/surface/tools/real-input-attempt.js +206 -38
  440. package/dist/surface/tools/reconcile-tools.js +21 -8
  441. package/dist/surface/tools/reticle-result.d.ts +3 -0
  442. package/dist/surface/tools/reticle-result.js +8 -1
  443. package/dist/surface/tools/run-report.d.ts +22 -0
  444. package/dist/surface/tools/run-report.js +141 -0
  445. package/dist/surface/tools/session-ports.d.ts +57 -0
  446. package/dist/surface/tools/session-ports.js +102 -0
  447. package/dist/surface/tools/tool-kit.d.ts +58 -4
  448. package/dist/surface/tools/tool-kit.js +140 -6
  449. package/dist/surface/tools/tool-surface.d.ts +2 -0
  450. package/dist/surface/tools/tool-surface.js +45 -0
  451. package/dist/surface/tools/tools.js +49 -87
  452. package/dist/telemetry/automation-hint.d.ts +5 -0
  453. package/dist/telemetry/automation-hint.js +7 -0
  454. package/dist/telemetry/cli-telemetry.d.ts +22 -0
  455. package/dist/telemetry/cli-telemetry.js +80 -11
  456. package/dist/telemetry/daemon-telemetry.d.ts +3 -1
  457. package/dist/telemetry/daemon-telemetry.js +9 -2
  458. package/dist/telemetry/feedback-cli.d.ts +1 -1
  459. package/dist/telemetry/feedback-cli.js +8 -3
  460. package/dist/telemetry/feedback.d.ts +1 -1
  461. package/dist/telemetry/feedback.js +51 -4
  462. package/dist/telemetry/harness-run.d.ts +3 -3
  463. package/dist/telemetry/harness-run.js +18 -7
  464. package/dist/telemetry/hud-events.d.ts +1 -1
  465. package/dist/telemetry/hud-metrics.d.ts +6 -3
  466. package/dist/telemetry/hud-metrics.js +20 -8
  467. package/dist/telemetry/install-source.js +1 -1
  468. package/dist/telemetry/mcp-connection.d.ts +1 -1
  469. package/dist/telemetry/mcp-connection.js +21 -2
  470. package/dist/telemetry/onboarding-firsts.d.ts +6 -1
  471. package/dist/telemetry/onboarding-firsts.js +41 -1
  472. package/dist/telemetry/proxy-telemetry.d.ts +42 -0
  473. package/dist/telemetry/proxy-telemetry.js +70 -1
  474. package/dist/telemetry/session-metrics.d.ts +1 -3
  475. package/dist/telemetry/session-metrics.js +16 -12
  476. package/dist/telemetry/telemetry.d.ts +9 -1
  477. package/dist/telemetry/telemetry.js +16 -1
  478. package/dist/telemetry/verification-of.d.ts +3 -1
  479. package/dist/telemetry/verification-of.js +7 -1
  480. package/dist/wire-journal.js +12 -2
  481. package/docs/README.md +4 -2
  482. package/docs/actions.mdx +7 -6
  483. package/docs/adapters.md +2 -1
  484. package/docs/agent-cheatsheet.md +19 -5
  485. package/docs/architecture.md +13 -10
  486. package/docs/autodrive.md +6 -5
  487. package/docs/benchmarks.md +2 -2
  488. package/docs/capabilities.mdx +1 -1
  489. package/docs/cli/affected.mdx +1 -1
  490. package/docs/cli/cloud.mdx +6 -6
  491. package/docs/cli/doctor.mdx +3 -1
  492. package/docs/cli/feedback.mdx +11 -7
  493. package/docs/cli/gate.mdx +1 -1
  494. package/docs/cli/help.mdx +1 -1
  495. package/docs/cli/init.mdx +20 -16
  496. package/docs/cli/mcp.mdx +5 -2
  497. package/docs/cli/open.mdx +5 -2
  498. package/docs/cli/report.mdx +1 -1
  499. package/docs/cli/restart.mdx +1 -1
  500. package/docs/cli/rollback.mdx +4 -4
  501. package/docs/cli/serve.mdx +7 -5
  502. package/docs/cli/setup.mdx +1 -1
  503. package/docs/cli/status.mdx +6 -2
  504. package/docs/cli/stop.mdx +3 -3
  505. package/docs/cli/telemetry.mdx +5 -1
  506. package/docs/cli/try.mdx +8 -8
  507. package/docs/cli/update.mdx +8 -5
  508. package/docs/cli/verify.mdx +12 -5
  509. package/docs/cli/version.mdx +1 -1
  510. package/docs/cli.mdx +10 -6
  511. package/docs/debugging.md +1 -1
  512. package/docs/deploy-checks.md +8 -6
  513. package/docs/desktop.mdx +14 -18
  514. package/docs/enterprise.md +6 -6
  515. package/docs/environment.mdx +5 -3
  516. package/docs/faq.mdx +9 -6
  517. package/docs/first-drive.md +19 -9
  518. package/docs/flows.md +3 -4
  519. package/docs/for-agents.md +1 -1
  520. package/docs/frameworks.mdx +34 -11
  521. package/docs/getting-started.md +46 -29
  522. package/docs/http-transport.md +2 -2
  523. package/docs/human-control.md +8 -8
  524. package/docs/index.mdx +2 -2
  525. package/docs/install-agentic.mdx +18 -19
  526. package/docs/install-manual.mdx +8 -4
  527. package/docs/integration-patterns.md +5 -5
  528. package/docs/multi-agent-testing.md +7 -5
  529. package/docs/packages/browser.mdx +34 -2
  530. package/docs/packages/core.mdx +2 -1
  531. package/docs/packages/electron.mdx +15 -3
  532. package/docs/packages/eslint-plugin.mdx +1 -1
  533. package/docs/packages/next.mdx +17 -5
  534. package/docs/packages/react.mdx +8 -1
  535. package/docs/packages/server.mdx +3 -3
  536. package/docs/packages/tauri.mdx +3 -3
  537. package/docs/packages/vite-plugin.mdx +1 -1
  538. package/docs/packages.mdx +19 -6
  539. package/docs/platform-integration.md +12 -4
  540. package/docs/predicates.mdx +18 -7
  541. package/docs/production-mode.md +108 -0
  542. package/docs/prompt-capture.md +99 -0
  543. package/docs/quickstart.mdx +14 -12
  544. package/docs/recipes.mdx +9 -8
  545. package/docs/required-checks.md +3 -2
  546. package/docs/skill-file.mdx +4 -3
  547. package/docs/skill-setup.md +2 -2
  548. package/docs/skill.md +62 -70
  549. package/docs/state-files.md +1 -0
  550. package/docs/state-management.mdx +11 -9
  551. package/docs/system-map.md +14 -13
  552. package/docs/telemetry.md +32 -24
  553. package/docs/testing.md +9 -5
  554. package/docs/tools/act-and-wait.mdx +17 -13
  555. package/docs/tools/act-sequence.mdx +40 -66
  556. package/docs/tools/act.mdx +7 -5
  557. package/docs/tools/assert.mdx +1 -1
  558. package/docs/tools/look.mdx +1 -1
  559. package/docs/tools/navigate.mdx +1 -1
  560. package/docs/tools/network.mdx +13 -11
  561. package/docs/tools/overview.mdx +3 -3
  562. package/docs/tools/query.mdx +3 -3
  563. package/docs/tools/session-and-feedback.mdx +9 -6
  564. package/docs/tools/sessions.mdx +7 -0
  565. package/docs/tools/snapshot.mdx +9 -7
  566. package/docs/tools/tools-and-run.mdx +11 -10
  567. package/docs/tools/verify.mdx +1 -1
  568. package/docs/troubleshooting.mdx +21 -9
  569. package/docs/usage.md +58 -43
  570. package/docs/use-cases.mdx +2 -2
  571. package/docs/vs-chrome-devtools-mcp.mdx +5 -5
  572. package/docs/vs-playwright-mcp.mdx +5 -4
  573. package/docs/what-is-recorded.md +12 -7
  574. package/docs/what-is-reticle.mdx +2 -2
  575. package/docs/why-reticle.mdx +1 -1
  576. package/package.json +9 -12
  577. package/dist/command/dev/stale-issue-guard.d.ts +0 -34
  578. package/dist/command/dev/stale-issue-guard.js +0 -69
@@ -0,0 +1,141 @@
1
+ /**
2
+ * The end-of-run report: the run ledger as the agent shows it to the user.
3
+ *
4
+ * Added to the answer of the call that ends an agent's run: a session end, a yield, or a released
5
+ * tab. A run that ended by releasing its tab got no word about the run before this, and its agent
6
+ * wrote its own summary. The report is a schema'd object, the markdown built from it, and one
7
+ * instruction. The cloud line is said only when the project is not linked, and it says what it is.
8
+ */
9
+ import { CLOUD_VALUE_LINE, ReticleTool, RUN_REPORT_FIELD, RUN_REPORT_INSTRUCTION, UPGRADE_HINT_SILENCE_ENV, Verified, asString, } from '@reticlehq/core';
10
+ import { ResultWord, linkedToPlatform, seconds } from './reticle-result.js';
11
+ const HEAD = '**Reticle run report: ';
12
+ const SEP = ' · ';
13
+ /** Claims listed before the rest are counted: enough to read, not enough to flood a reply. */
14
+ const CLAIMS_SHOWN = 20;
15
+ const Said = {
16
+ NOTHING_CHECKED: 'nothing was checked',
17
+ CAUGHT: 'Caught, expected to hold and did not',
18
+ FLOWS_SAVED: 'Flows saved',
19
+ FLOWS_REPLAYED: 'Flows replayed',
20
+ NO_FLOWS: 'Flows: none saved, none replayed',
21
+ MEMORY: 'Memory',
22
+ TIME: 'Time',
23
+ FIRST_VERDICT: 'first verdict after',
24
+ };
25
+ const WORD = {
26
+ [Verified.YES]: ResultWord.PROVED,
27
+ [Verified.NO]: ResultWord.FAILED,
28
+ [Verified.UNKNOWN]: ResultWord.NOT_PROVED,
29
+ [Verified.NO_FAULT]: ResultWord.NOT_PROVED,
30
+ };
31
+ const plural = (n, word) => `${String(n)} ${word}${1 === n ? '' : 's'}`;
32
+ function headline(report) {
33
+ const all = [...report.claims, ...report.flows.replayed].map((c) => c.verified);
34
+ const count = (v) => all.filter((each) => v === each).length;
35
+ const total = all.length;
36
+ const word = `${HEAD}${WORD[report.verified]}**${SEP}`;
37
+ if (0 === total)
38
+ return `${word}${Said.NOTHING_CHECKED}`;
39
+ if (Verified.NO === report.verified)
40
+ return `${word}${String(count(Verified.NO))} of ${plural(total, 'check')} did not hold`;
41
+ if (Verified.YES === report.verified)
42
+ return `${word}${String(total)} of ${plural(total, 'check')} held`;
43
+ return `${word}${String(total - count(Verified.YES) - count(Verified.NO))} of ${plural(total, 'check')} undecided`;
44
+ }
45
+ /** The report as markdown: the verdict, each claim with its evidence, then what the run left. */
46
+ export function renderRunReport(report) {
47
+ const claims = report.claims
48
+ .slice(0, CLAIMS_SHOWN)
49
+ .map((c) => `- ${c.verified}: ${c.claim}${c.evidence === undefined ? '' : ` (${c.evidence})`}`);
50
+ const more = report.claims.length - CLAIMS_SHOWN;
51
+ const { saved, replayed } = report.flows;
52
+ const flows = 0 === saved.length && 0 === replayed.length
53
+ ? [`- ${Said.NO_FLOWS}`]
54
+ : [
55
+ ...(0 === saved.length ? [] : [`- ${Said.FLOWS_SAVED}: ${saved.join(', ')}`]),
56
+ ...(0 === replayed.length
57
+ ? []
58
+ : [
59
+ `- ${Said.FLOWS_REPLAYED}: ${replayed.map((r) => `${r.name} (${r.verified})`).join(', ')}`,
60
+ ]),
61
+ ];
62
+ const time = report.firstVerdictMs === undefined
63
+ ? seconds(report.wallMs)
64
+ : `${seconds(report.wallMs)}, ${Said.FIRST_VERDICT} ${seconds(report.firstVerdictMs)}`;
65
+ return [
66
+ headline(report),
67
+ ...claims,
68
+ ...(0 < more ? [`- (+${String(more)} more claims)`] : []),
69
+ ...(0 === report.caught.length ? [] : [`- ${Said.CAUGHT}: ${report.caught.join('; ')}`]),
70
+ ...flows,
71
+ `- ${Said.MEMORY}: ${plural(report.memory.written, 'note')} written, ${String(report.memory.read)} read`,
72
+ `- ${Said.TIME}: ${time}`,
73
+ ...(report.cloud === undefined ? [] : [`- ${report.cloud}`]),
74
+ ].join('\n');
75
+ }
76
+ /** The calls that end an agent's run, by their own name or as an action of a merged tool. */
77
+ export function endsRun(tool, args) {
78
+ const action = asString(args['action']);
79
+ switch (tool) {
80
+ case ReticleTool.END_SESSION:
81
+ case ReticleTool.YIELD:
82
+ case ReticleTool.LEASE_RELEASE:
83
+ return true;
84
+ case ReticleTool.SESSION:
85
+ return 'end' === action || 'yield' === action;
86
+ case ReticleTool.LEASE:
87
+ return 'release' === action;
88
+ default:
89
+ return false;
90
+ }
91
+ }
92
+ /** `reticle_intent` actions that write a statement, and the ones that read them back. */
93
+ const IntentWrite = { RECORD: 'record', DECLARE: 'declare' };
94
+ const INTENT_READS = new Set(['list', 'index', 'subject', 'get']);
95
+ const isRecord = (value) => null !== value && 'object' === typeof value && !Array.isArray(value);
96
+ /** What an answer says the run saved or read. An answer that refused counts for nothing. */
97
+ export function noteToolResult(ledger, tool, args, result) {
98
+ if (!isRecord(result) || result['error'] !== undefined)
99
+ return;
100
+ if (ReticleTool.FLOW_SAVE === tool || ReticleTool.FLOW_SAVE_RECORDED === tool) {
101
+ const name = result['name'];
102
+ if ('string' === typeof name)
103
+ ledger.flowSaved(name);
104
+ return;
105
+ }
106
+ const action = asString(args['action']);
107
+ if (ReticleTool.INTENT === tool) {
108
+ // The intent ledger in `.reticle/intent/` is the memory an unlinked project has.
109
+ if (IntentWrite.RECORD === action)
110
+ ledger.memoryWritten();
111
+ const declared = args['intents'];
112
+ if (IntentWrite.DECLARE === action && Array.isArray(declared))
113
+ ledger.memoryWritten(declared.length);
114
+ if (action !== undefined && INTENT_READS.has(action))
115
+ ledger.memoryRead([JSON.stringify(result)]);
116
+ return;
117
+ }
118
+ if (ReticleTool.MEMORY !== tool)
119
+ return;
120
+ if ('add' === action && result['added'] !== undefined)
121
+ ledger.memoryWritten();
122
+ const known = result['known'];
123
+ if (Array.isArray(known))
124
+ ledger.memoryRead(known.map((entry) => JSON.stringify(entry)));
125
+ }
126
+ /** The report as an answer field, or no field when the ledger holds no run. Empties the ledger. */
127
+ export function runReportField(ledger, root, env, now) {
128
+ if (ledger.isEmpty())
129
+ return {};
130
+ const taken = ledger.take(now);
131
+ const silenced = env[UPGRADE_HINT_SILENCE_ENV] !== undefined;
132
+ const linked = root === undefined || linkedToPlatform(root, env);
133
+ const report = silenced || linked ? taken : { ...taken, cloud: CLOUD_VALUE_LINE };
134
+ return {
135
+ [RUN_REPORT_FIELD]: {
136
+ report,
137
+ markdown: renderRunReport(report),
138
+ instruction: RUN_REPORT_INSTRUCTION,
139
+ },
140
+ };
141
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Provider capabilities handed to features as ports: a suite fixture to seed from, save/restore,
3
+ * slowing the page and breaking it. Each is `undefined` when the provider cannot do it. They sit on
4
+ * the tool side because a feature reaching into the input layer directly would depend on a driver.
5
+ */
6
+ import type { RealInputProvider } from '../../portal/input/real-input.js';
7
+ import { type StorageFixturePort } from '../../portal/input/storage-fixture.js';
8
+ import { type NetworkMutationPort } from '../../portal/input/network-mutation.js';
9
+ import type { Perturbation, SeedStorage } from '@reticlehq/core';
10
+ /**
11
+ * The state a suite should boot its flows from: whatever the agent is already sitting in.
12
+ *
13
+ * This is the join the fixture work was building toward. A suite's flows each start from cold, so
14
+ * fifty of them prove the login works fifty times — and the flow that LOGS OUT leaves every flow
15
+ * after it signed out, which no navigation repairs, because the problem is not where the subject is
16
+ * but what it holds. A seed is applied to an isolated context BEFORE the first navigation, which is
17
+ * exactly and only when a fixture can work.
18
+ *
19
+ * Best-effort, deliberately. A fixture is an OPTIMISATION over running from cold, and running from
20
+ * cold is correct: a suite that refused to start because a cookie jar could not be read would have
21
+ * traded a slow answer for no answer. Every "no" here — no provider, no storage support, nothing
22
+ * driven, a browser that threw, nothing worth seeding — produces the same honest `undefined`, and
23
+ * the suite runs exactly as it did before any of this existed.
24
+ */
25
+ export declare function suiteFixtureSeed(realInput: RealInputProvider | undefined, appUrl: string): Promise<SeedStorage | undefined>;
26
+ /**
27
+ * A way to make this session's page SLOW on purpose, or nothing.
28
+ *
29
+ * The third of these seams, for the same reason as the other two: a feature reaching into the input
30
+ * layer directly is a feature depending on a driver, and the boundary guard asks about it.
31
+ *
32
+ * Installs delays and NOTHING else. A rule that carried a status or a body would substitute a
33
+ * response the server never sent, and an app raced against invented data produces invented races —
34
+ * a fabricated defect handed to somebody at 3am, which is worse than finding nothing.
35
+ */
36
+ export declare function sessionPerturbationPort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<{
37
+ slow(rules: readonly Perturbation[]): Promise<void>;
38
+ clear(): Promise<void>;
39
+ } | undefined>;
40
+ /**
41
+ * Save/restore for this session's page, or nothing.
42
+ *
43
+ * The same job as `suiteFixtureSeed` next door, stopping one step earlier: that one captures and
44
+ * converts, this hands back the PORT so a caller can re-apply what it captured later. It lives here
45
+ * for the reason written above — a feature reaching into the input layer directly is a feature
46
+ * depending on a driver, and the boundary guard asks about it. It asked.
47
+ */
48
+ export declare function suiteFixturePort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<StorageFixturePort | undefined>;
49
+ /**
50
+ * A way to break this session's page, or nothing.
51
+ *
52
+ * Sits beside `suiteFixtureSeed` because it is the same shape of job: turning a provider capability
53
+ * into something a feature can use, on the one side of the graph that is allowed to know about both.
54
+ * A flow tool reaching into the input layer directly would be a feature depending on a driver, which
55
+ * is the reach the boundary guard exists to ask about.
56
+ */
57
+ export declare function sessionMutationPort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<NetworkMutationPort | undefined>;
@@ -0,0 +1,102 @@
1
+ import { fixturePortFor, seedFromStorageState, } from '../../portal/input/storage-fixture.js';
2
+ import { mutationPortFor } from '../../portal/input/network-mutation.js';
3
+ /**
4
+ * The state a suite should boot its flows from: whatever the agent is already sitting in.
5
+ *
6
+ * This is the join the fixture work was building toward. A suite's flows each start from cold, so
7
+ * fifty of them prove the login works fifty times — and the flow that LOGS OUT leaves every flow
8
+ * after it signed out, which no navigation repairs, because the problem is not where the subject is
9
+ * but what it holds. A seed is applied to an isolated context BEFORE the first navigation, which is
10
+ * exactly and only when a fixture can work.
11
+ *
12
+ * Best-effort, deliberately. A fixture is an OPTIMISATION over running from cold, and running from
13
+ * cold is correct: a suite that refused to start because a cookie jar could not be read would have
14
+ * traded a slow answer for no answer. Every "no" here — no provider, no storage support, nothing
15
+ * driven, a browser that threw, nothing worth seeding — produces the same honest `undefined`, and
16
+ * the suite runs exactly as it did before any of this existed.
17
+ */
18
+ export async function suiteFixtureSeed(realInput, appUrl) {
19
+ if (realInput === undefined) {
20
+ return undefined;
21
+ }
22
+ try {
23
+ const port = await fixturePortFor(realInput, appUrl);
24
+ if (port === undefined) {
25
+ return undefined;
26
+ }
27
+ return seedFromStorageState(await port.capture(), appUrl);
28
+ }
29
+ catch {
30
+ return undefined;
31
+ }
32
+ }
33
+ /**
34
+ * A way to make this session's page SLOW on purpose, or nothing.
35
+ *
36
+ * The third of these seams, for the same reason as the other two: a feature reaching into the input
37
+ * layer directly is a feature depending on a driver, and the boundary guard asks about it.
38
+ *
39
+ * Installs delays and NOTHING else. A rule that carried a status or a body would substitute a
40
+ * response the server never sent, and an app raced against invented data produces invented races —
41
+ * a fabricated defect handed to somebody at 3am, which is worse than finding nothing.
42
+ */
43
+ export async function sessionPerturbationPort(realInput, appUrl) {
44
+ if (realInput === undefined || appUrl === undefined) {
45
+ return undefined;
46
+ }
47
+ const setMocks = realInput.setMocks?.bind(realInput);
48
+ if (setMocks === undefined) {
49
+ return undefined;
50
+ }
51
+ if (!(await realInput.isAvailableFor(appUrl))) {
52
+ return undefined;
53
+ }
54
+ return {
55
+ slow: async (rules) => {
56
+ await setMocks(appUrl, [...rules]);
57
+ },
58
+ /** Clearing is the undo. A page left slowed is damage the next run inherits. */
59
+ clear: async () => {
60
+ await setMocks(appUrl, []);
61
+ },
62
+ };
63
+ }
64
+ /**
65
+ * Save/restore for this session's page, or nothing.
66
+ *
67
+ * The same job as `suiteFixtureSeed` next door, stopping one step earlier: that one captures and
68
+ * converts, this hands back the PORT so a caller can re-apply what it captured later. It lives here
69
+ * for the reason written above — a feature reaching into the input layer directly is a feature
70
+ * depending on a driver, and the boundary guard asks about it. It asked.
71
+ */
72
+ export async function suiteFixturePort(realInput, appUrl) {
73
+ if (realInput === undefined || appUrl === undefined) {
74
+ return undefined;
75
+ }
76
+ try {
77
+ return await fixturePortFor(realInput, appUrl);
78
+ }
79
+ catch {
80
+ return undefined;
81
+ }
82
+ }
83
+ /**
84
+ * A way to break this session's page, or nothing.
85
+ *
86
+ * Sits beside `suiteFixtureSeed` because it is the same shape of job: turning a provider capability
87
+ * into something a feature can use, on the one side of the graph that is allowed to know about both.
88
+ * A flow tool reaching into the input layer directly would be a feature depending on a driver, which
89
+ * is the reach the boundary guard exists to ask about.
90
+ */
91
+ export async function sessionMutationPort(realInput, appUrl) {
92
+ if (realInput === undefined || appUrl === undefined) {
93
+ return undefined;
94
+ }
95
+ try {
96
+ return await mutationPortFor(realInput, appUrl);
97
+ }
98
+ catch {
99
+ // A provider that cannot answer is the same answer as a provider that cannot break anything.
100
+ return undefined;
101
+ }
102
+ }
@@ -13,6 +13,7 @@ import type { BaselineStore } from '../../memory/project/baselines.js';
13
13
  import type { RecordingStore } from '../../language/flows/recording/tape/recordings.js';
14
14
  import type { FileSystemPort } from '../../memory/project/fs/fs-port.js';
15
15
  import type { ArtifactRoot } from '../../memory/project/artifact-root.js';
16
+ import type { NonceMinter } from '../../portal/production/production-activation.js';
16
17
  import type { FlowStore } from '../../language/flows/flows.js';
17
18
  import type { ProjectStore } from '../../memory/project/project-store.js';
18
19
  import type { AnnotationStore } from '../../language/flows/stores/annotation-store.js';
@@ -76,6 +77,11 @@ export interface ToolDeps<Ext = unknown> {
76
77
  * it, so two agents on one origin never share a tab (#1226). Absent ⇒ every acquire gets its own.
77
78
  */
78
79
  attachId?: string;
80
+ /**
81
+ * The coding agent's own session id, as its MCP server announced it on connect. Joins this
82
+ * connection's episode to the agent hooks' records. Absent: the agent announced none.
83
+ */
84
+ agentSession?: string;
79
85
  /** Run one sync cycle with the platform now, for `reticle_project { push }`. Absent: not linked here. */
80
86
  syncNow?: () => Promise<unknown>;
81
87
  /** Wires the app on the agent's first use, instead of at installation. Absent: tell, do not wire. */
@@ -88,6 +94,8 @@ export interface ToolDeps<Ext = unknown> {
88
94
  url: string;
89
95
  notice: string;
90
96
  } | undefined>;
97
+ /** The one dev server running in the caller's project folder, for a lease that names no url. */
98
+ projectAppUrl?: () => Promise<string | undefined>;
91
99
  /** cross-run outcome memory (.reticle/project.json). */
92
100
  project: ProjectStore;
93
101
  /** optional native-input provider. undefined ⇒ everything stays synthetic. */
@@ -140,6 +148,11 @@ export interface ToolDeps<Ext = unknown> {
140
148
  * ToolDeps keeps working; absent falls back to the default port.
141
149
  */
142
150
  bridgePort?: number;
151
+ /**
152
+ * The bridge's session-nonce registry. Local callers only: a production lease mints its nonce
153
+ * here. Absent where no bridge runs in this process, and a production lease then refuses.
154
+ */
155
+ nonces?: NonceMinter;
143
156
  /**
144
157
  * A consumer's OWN dependencies, carried through untouched.
145
158
  *
@@ -159,13 +172,13 @@ export interface ToolDeps<Ext = unknown> {
159
172
  export interface ToolDef<Ext = unknown> {
160
173
  name: string;
161
174
  description: string;
162
- inputSchema: z.ZodRawShape;
175
+ inputSchema: Record<string, z.ZodType>;
163
176
  /**
164
177
  * JSON Schema-compatible output schema for this tool. When present, the MCP server advertises it
165
178
  * in the tools/list response so schema-aware clients (like @reticlehq/cli) can validate outputs and
166
179
  * compose tool calls safely. Also drives TOON encoding for snapshot/query results.
167
180
  */
168
- outputSchema?: z.ZodRawShape;
181
+ outputSchema?: Record<string, z.ZodType>;
169
182
  /**
170
183
  * One concrete, valid call — the shape, not the prose.
171
184
  *
@@ -268,6 +281,8 @@ export declare const EnvelopeKey: {
268
281
  readonly TALK_TO_US: "talk_to_us";
269
282
  /** SDK/daemon version skew — often the one fact that explains everything else in the session. */
270
283
  readonly VERSION_SKEW: "version_skew";
284
+ /** On each verdict from a page whose SDK is behind the daemon. See session-info.ts. */
285
+ readonly SDK_BEHIND: "sdk_behind";
271
286
  /** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
272
287
  readonly FEEDBACK_UNDELIVERED: "feedback_undelivered";
273
288
  /** Once per project: verified runs exist only on this machine. See platform-moment.ts. */
@@ -290,6 +305,8 @@ export declare const EnvelopeKey: {
290
305
  readonly ZERO_INSTALL: "zero_install";
291
306
  /** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
292
307
  readonly NOTICES: "notices";
308
+ /** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
309
+ readonly RUN_REPORT: "runReport";
293
310
  };
294
311
  export type EnvelopeKey = (typeof EnvelopeKey)[keyof typeof EnvelopeKey];
295
312
  /**
@@ -305,10 +322,47 @@ export declare const HOST_STUB_NOTE: string;
305
322
  * `steps`) takes one per step, inside the sequence, rather than one for the whole call.
306
323
  */
307
324
  export declare const STEP_SHOT_TOOLS: ReadonlySet<string>;
325
+ /**
326
+ * Tools that DRIVE the page. An action with no verdict after it is the signature of the loop
327
+ * breaking mid-task — see `abandonedActions`. `act_and_wait` is one of these AND a verification, so
328
+ * it settles its own action, which is exactly right: it is the tool that does both.
329
+ */
330
+ export declare const ACTION_TOOLS: ReadonlySet<string>;
331
+ /**
332
+ * Tools that go through Playwright CDP rather than the page SDK.
333
+ *
334
+ * Under version skew these fail with "Target page, context or browser has been closed" while every
335
+ * DOM tool against the same tab still works (#688). They are session-EXEMPT (own result contracts),
336
+ * so the bound-tool resolve in `runTool` never runs for them — resolve again there so we can refuse with
337
+ * the skew sentence before Playwright lies about a closed page.
338
+ */
339
+ export declare const CDP_TOOLS: ReadonlySet<string>;
340
+ /**
341
+ * Tools whose result hands the agent refs. The tab they were minted in is remembered, so the call
342
+ * that spends one cannot be routed to a different tab without saying so — see ref-provenance.ts.
343
+ *
344
+ * Over-inclusion is the safe direction here and under-inclusion is not dangerous either: both ends
345
+ * produce a REFUSAL naming the two tabs, never a silent drive against the wrong one.
346
+ */
347
+ export declare const REF_MINTING_TOOLS: ReadonlySet<string>;
348
+ /**
349
+ * The live-session tools whose result MUST carry the
350
+ * session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
351
+ * can never return a healthy-looking result from any of these. `runTool` is the single choke point
352
+ * (mcp.ts + tool-invoker.ts) that splices health on (`invoke-tool.ts`); the guard test asserts the set is exhaustive.
353
+ */
354
+ export declare const SESSION_BOUND_TOOLS: ReadonlySet<string>;
355
+ /**
356
+ * Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
357
+ * disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
358
+ * exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
359
+ * `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
360
+ */
361
+ export declare const SESSION_EXEMPT_TOOLS: ReadonlySet<string>;
308
362
  /** A step-screenshot tool, with the one sentence about its screenshot on the end of its description. */
309
363
  export declare function withScreenshotDoc(tool: ToolDef): ToolDef;
310
364
  /** The one sentence every tool that takes a step screenshot says about it. */
311
- export declare const SCREENSHOT_DOC = " `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice.";
365
+ export declare const SCREENSHOT_DOC = " `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice. When `pending: true`, the file may still be in write; wait before you read it.";
312
366
  /**
313
367
  * Fields that `runTool` / `withControl` splice onto EVERY session-bound tool result at runtime.
314
368
  * Merged into each session-bound tool's outputSchema so a schema-strict client (structuredContent
@@ -317,7 +371,7 @@ export declare const SCREENSHOT_DOC = " `screenshot.path` is a picture of the pa
317
371
  * Derived from `EnvelopeKey` rather than re-listed: this shape and the splice sites disagreed for a
318
372
  * whole release, and every key that went missing was a channel nobody could see was missing.
319
373
  */
320
- export declare const sessionEnvelopeShape: z.ZodRawShape;
374
+ export declare const sessionEnvelopeShape: Record<string, z.ZodType>;
321
375
  /** Unwrap a browser command result or throw its error so the agent sees a clean failure. */
322
376
  export declare function commandOrThrow(deps: ToolDeps, sessionId: string | undefined, name: ReticleCommand, args: Record<string, unknown>): Promise<unknown>;
323
377
  /** Full DOM snapshot → normalized tree lines + route, for tools that diff or scan the page. */
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { AsyncLocalStorage } from 'node:async_hooks';
3
- import { asRecord, asString, ReticleCommand, ReticleTool, SnapshotMode, } from '@reticlehq/core';
3
+ import { asRecord, asString, ReticleCommand, ReticleTool, SnapshotMode, RUN_REPORT_FIELD, } from '@reticlehq/core';
4
4
  import { normalizeLines } from '../../memory/project/baselines.js';
5
5
  import { SnapshotCache } from './read/snapshot-delta.js';
6
6
  /**
@@ -77,6 +77,8 @@ export const EnvelopeKey = {
77
77
  TALK_TO_US: 'talk_to_us',
78
78
  /** SDK/daemon version skew — often the one fact that explains everything else in the session. */
79
79
  VERSION_SKEW: 'version_skew',
80
+ /** On each verdict from a page whose SDK is behind the daemon. See session-info.ts. */
81
+ SDK_BEHIND: 'sdk_behind',
80
82
  /** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
81
83
  FEEDBACK_UNDELIVERED: 'feedback_undelivered',
82
84
  /** Once per project: verified runs exist only on this machine. See platform-moment.ts. */
@@ -99,6 +101,8 @@ export const EnvelopeKey = {
99
101
  ZERO_INSTALL: 'zero_install',
100
102
  /** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
101
103
  NOTICES: 'notices',
104
+ /** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
105
+ RUN_REPORT: RUN_REPORT_FIELD,
102
106
  };
103
107
  /**
104
108
  * The sentence every session-bound result carries while its leased tab runs on a stubbed shell.
@@ -119,6 +123,132 @@ export const STEP_SHOT_TOOLS = new Set([
119
123
  ReticleTool.NAVIGATE,
120
124
  ReticleTool.ASSERT,
121
125
  ]);
126
+ /**
127
+ * Tools that DRIVE the page. An action with no verdict after it is the signature of the loop
128
+ * breaking mid-task — see `abandonedActions`. `act_and_wait` is one of these AND a verification, so
129
+ * it settles its own action, which is exactly right: it is the tool that does both.
130
+ */
131
+ export const ACTION_TOOLS = new Set([
132
+ ReticleTool.ACT,
133
+ ReticleTool.ACT_SEQUENCE,
134
+ ReticleTool.ACT_AND_WAIT,
135
+ ]);
136
+ /**
137
+ * Tools that go through Playwright CDP rather than the page SDK.
138
+ *
139
+ * Under version skew these fail with "Target page, context or browser has been closed" while every
140
+ * DOM tool against the same tab still works (#688). They are session-EXEMPT (own result contracts),
141
+ * so the bound-tool resolve in `runTool` never runs for them — resolve again there so we can refuse with
142
+ * the skew sentence before Playwright lies about a closed page.
143
+ */
144
+ export const CDP_TOOLS = new Set([
145
+ ReticleTool.SCREENSHOT,
146
+ ReticleTool.VISUAL_DIFF,
147
+ ReticleTool.NETWORK_MOCK,
148
+ ReticleTool.VIEWPORT,
149
+ // Breaks a request through the same Playwright route `reticle_network_mock` uses, so it fails the
150
+ // same way under version skew and must be refused with the same sentence.
151
+ ReticleTool.FLOW_MUTATE,
152
+ ]);
153
+ /**
154
+ * Tools whose result hands the agent refs. The tab they were minted in is remembered, so the call
155
+ * that spends one cannot be routed to a different tab without saying so — see ref-provenance.ts.
156
+ *
157
+ * Over-inclusion is the safe direction here and under-inclusion is not dangerous either: both ends
158
+ * produce a REFUSAL naming the two tabs, never a silent drive against the wrong one.
159
+ */
160
+ export const REF_MINTING_TOOLS = new Set([
161
+ ReticleTool.SNAPSHOT,
162
+ ReticleTool.QUERY,
163
+ ReticleTool.INSPECT,
164
+ // The same three merged, on the `merged` surface. Its `state` action mints nothing, and
165
+ // over-inclusion is the safe direction here: the worst case is a refusal naming two tabs.
166
+ ReticleTool.LOOK,
167
+ ReticleTool.EXPLORE,
168
+ // `crawl` mints refs for the controls it drives and `coverage` for the ones it reports untouched.
169
+ // Both are actions on the merged verify tool now.
170
+ ReticleTool.VERIFY,
171
+ ]);
172
+ /**
173
+ * The live-session tools whose result MUST carry the
174
+ * session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
175
+ * can never return a healthy-looking result from any of these. `runTool` is the single choke point
176
+ * (mcp.ts + tool-invoker.ts) that splices health on (`invoke-tool.ts`); the guard test asserts the set is exhaustive.
177
+ */
178
+ export const SESSION_BOUND_TOOLS = new Set([
179
+ // Resolves a session and reads its event window (`session.eventsSince`), exactly as OBSERVE and
180
+ // NETWORK do. Without this it runs with no session and answers from nothing.
181
+ ReticleTool.SNAPSHOT,
182
+ ReticleTool.QUERY,
183
+ ReticleTool.INSPECT,
184
+ // All four merged. Every member here is session-bound, so unlike `verify` there is no split to
185
+ // adjudicate — the merged tool inherits the only answer its members ever gave.
186
+ ReticleTool.LOOK,
187
+ // Merged change/flows/affected/coverage/crawl. Its members were SPLIT across bound and exempt —
188
+ // coverage/change/crawl bound, flow_verify exempt because it returns its own suite contract — and
189
+ // a merged tool has to be one or the other. Bound is the right side: `crawl` drives the app
190
+ // itself, so a throttled or event-dropping tab is exactly the condition its verdict depends on,
191
+ // and dropping the health disclosure there to protect a sibling's output shape would trade an
192
+ // honesty signal for a formatting preference.
193
+ ReticleTool.VERIFY,
194
+ ReticleTool.ACT,
195
+ ReticleTool.ACT_SEQUENCE,
196
+ ReticleTool.ACT_AND_WAIT,
197
+ ReticleTool.OBSERVE,
198
+ ReticleTool.WAIT_FOR,
199
+ ReticleTool.ASSERT,
200
+ // Reads the live page as well as the event window, so a throttled tab can make it compare a stale
201
+ // render against fresh data — exactly the case the health envelope exists to disclose.
202
+ ReticleTool.RECONCILE,
203
+ ReticleTool.NETWORK,
204
+ ReticleTool.CONSOLE,
205
+ ReticleTool.ANIMATIONS,
206
+ ReticleTool.BASELINE, // merged save/list/diff — save+diff are live reads
207
+ ReticleTool.RECORD, // merged start/stop — both live
208
+ ReticleTool.REPLAY,
209
+ ReticleTool.CLOCK,
210
+ ReticleTool.STATE,
211
+ ReticleTool.STORAGE,
212
+ ReticleTool.EXPLORE,
213
+ ReticleTool.SCROLL_TO,
214
+ ReticleTool.NAVIGATE,
215
+ ]);
216
+ /**
217
+ * Tools that carry a `sessionId` arg but are NOT live-session-health tools — they read/write
218
+ * disk (capabilities/contract/flow/project), drain a buffer, or steer session lifecycle. They are
219
+ * exempt from the health splice ON PURPOSE. Kept explicit so the guard test can force every new
220
+ * `sessionId`-bearing tool to be classified into exactly one set (bound XOR exempt).
221
+ */
222
+ export const SESSION_EXEMPT_TOOLS = new Set([
223
+ ReticleTool.CAPABILITIES, // has a fromDisk mode with no live session
224
+ ReticleTool.CONTRACT_SAVE, // persists the registry to disk
225
+ ReticleTool.FLOW_SAVE, // sessionId only scopes the write to the app's flow subdir; disk-side
226
+ ReticleTool.FLOW, // merged list/load/delete — sessionId only scopes the project; all disk-side
227
+ ReticleTool.FLOW_REPLAY, // returns its own FlowReplayResult contract (+ auto-records a run)
228
+ ReticleTool.FLOW_SAVE_RECORDED, // reads the recording buffer, writes disk
229
+ // FLOW_HEAL is no longer a name runTool ever sees: it became `reticle_verify {action:"heal"}`,
230
+ // and VERIFY is already listed here, so the exemption is inherited from the parent. Left as a
231
+ // dangling name it would be a lie this file's own test 6 is written to catch.
232
+ ReticleTool.INTENT, // reads/writes .reticle/intent/; sessionId only picks the project
233
+ ReticleTool.CONTEXT, // folds the journal + intent ledger; must still answer when nothing is connected
234
+ ReticleTool.MAP, // folds the journals on disk into the App Graph; answers with no tab connected
235
+ ReticleTool.PROJECT, // reads .reticle/project.json
236
+ // Reads the team's shared memory over HTTP; sessionId only resolves WHICH project's link file to
237
+ // use. It must answer with no tab connected — "what does this project know?" is a question an
238
+ // agent asks before it has opened anything.
239
+ ReticleTool.MEMORY,
240
+ ReticleTool.RUN_EXPORT, // reads .reticle/runs/<id>.json (verification-run artifact)
241
+ ReticleTool.SESSION, // merged lifecycle/human-channel family (tune/yield/end/resume/messages/review/narrate)
242
+ ReticleTool.SCREENSHOT, // own contract; provider-driven, not a live-DOM-health read
243
+ ReticleTool.VISUAL_DIFF, // own contract (matched/ratio/region)
244
+ ReticleTool.NETWORK_MOCK, // own contract (applied/count); provider-driven, not a live-DOM read
245
+ ReticleTool.VIEWPORT, // own contract (applied/width/height); provider-driven, not a live-DOM read
246
+ ReticleTool.ANNOTATE, // annotates a recording's steps; pure disk-side metadata, no live DOM read
247
+ ReticleTool.LEASE, // merged acquire/release — its sessionId is a pool lease id, not a live session
248
+ // Its sessionId only enriches the report with the tab's runtime/engine, and it must stay callable
249
+ // when NO session exists — "nothing ever connected" is feedback we especially want.
250
+ ReticleTool.FEEDBACK,
251
+ ]);
122
252
  /** A step-screenshot tool, with the one sentence about its screenshot on the end of its description. */
123
253
  export function withScreenshotDoc(tool) {
124
254
  return STEP_SHOT_TOOLS.has(tool.name)
@@ -126,7 +256,7 @@ export function withScreenshotDoc(tool) {
126
256
  : tool;
127
257
  }
128
258
  /** The one sentence every tool that takes a step screenshot says about it. */
129
- export const SCREENSHOT_DOC = ' `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice.';
259
+ export const SCREENSHOT_DOC = ' `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice. When `pending: true`, the file may still be in write; wait before you read it.';
130
260
  /**
131
261
  * Fields that `runTool` / `withControl` splice onto EVERY session-bound tool result at runtime.
132
262
  * Merged into each session-bound tool's outputSchema so a schema-strict client (structuredContent
@@ -147,16 +277,18 @@ export async function commandOrThrow(deps, sessionId,
147
277
  name, args) {
148
278
  const session = deps.sessions.resolve(sessionId);
149
279
  const result = await session.command(name, args);
150
- if (!result.ok)
280
+ if (!result.ok) {
151
281
  throw new Error(result.error ?? `command '${name}' failed`);
282
+ }
152
283
  return result.result;
153
284
  }
154
285
  /** Full DOM snapshot → normalized tree lines + route, for tools that diff or scan the page. */
155
286
  export async function snapshotTree(deps, sessionId) {
156
287
  const session = deps.sessions.resolve(sessionId);
157
288
  const result = await session.command(ReticleCommand.SNAPSHOT, { mode: SnapshotMode.FULL });
158
- if (!result.ok)
289
+ if (!result.ok) {
159
290
  throw new Error(result.error ?? 'snapshot failed');
291
+ }
160
292
  const snap = (result.result ?? {});
161
293
  return { lines: normalizeLines(snap.tree ?? ''), route: snap.status?.route ?? '' };
162
294
  }
@@ -181,14 +313,16 @@ export function callSecrets() {
181
313
  * telemetry — ever sees them.
182
314
  */
183
315
  export function takeCallSecrets(args) {
184
- if (!(CALL_SECRETS_ARG in args))
316
+ if (!(CALL_SECRETS_ARG in args)) {
185
317
  return { secrets: undefined, rest: args };
318
+ }
186
319
  const { [CALL_SECRETS_ARG]: raw, ...rest } = args;
187
320
  const secrets = {};
188
321
  for (const [key, value] of Object.entries(asRecord(raw))) {
189
322
  const text = asString(value);
190
- if (text !== undefined && 0 < text.length)
323
+ if (text !== undefined && 0 < text.length) {
191
324
  secrets[key] = text;
325
+ }
192
326
  }
193
327
  return { secrets, rest };
194
328
  }
@@ -1,3 +1,4 @@
1
+ import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
1
2
  import type { ToolDef } from './tool-kit.js';
2
3
  /**
3
4
  * There is ONE tool surface. This is not a menu.
@@ -193,3 +194,4 @@ export declare function describeToolSurface(active: ToolSurface, requested?: str
193
194
  */
194
195
  export declare function defaultAdvertisedNames(): readonly string[];
195
196
  export declare function filterTools(tools: ToolDef[], surface: ToolSurface): ToolDef[];
197
+ export declare function toolAnnotations(name: string): ToolAnnotations;