@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
@@ -58,22 +58,25 @@ const PAGE_CAPABILITIES = [
58
58
  ];
59
59
  /** Why an action's settle wait ended, when the page said. */
60
60
  function readSettleReason(result) {
61
- if ('object' !== typeof result || null === result)
61
+ if ('object' !== typeof result || null === result) {
62
62
  return undefined;
63
+ }
63
64
  const reason = result.settleReason;
64
65
  return 'string' === typeof reason ? reason : undefined;
65
66
  }
66
67
  /** A network event's correlation id, if it carries one. Events are `unknown` at this boundary. */
67
68
  function readRequestId(data) {
68
- if ('object' !== typeof data || null === data)
69
+ if ('object' !== typeof data || null === data) {
69
70
  return undefined;
71
+ }
70
72
  const id = data.id;
71
73
  return 'string' === typeof id ? id : undefined;
72
74
  }
73
75
  /** What the request was pointed at, for a blind spot a person has to read. */
74
76
  function readUrl(data) {
75
- if ('object' !== typeof data || null === data)
77
+ if ('object' !== typeof data || null === data) {
76
78
  return undefined;
79
+ }
77
80
  const url = data.url;
78
81
  return 'string' === typeof url ? url : undefined;
79
82
  }
@@ -158,6 +161,11 @@ export const NOT_EVIDENCE = {
158
161
  */
159
162
  export const NO_PROTOCOL_CHANNEL = {
160
163
  download: 'a file the application produced; the protocol has no channel for an emitted artifact',
164
+ // Recorded for the episode, not yet read by a verdict. Both are screen facts and belong on `ui`,
165
+ // but putting them there changes what an assertion sees (a canvas animating every frame is a
166
+ // screen that never settles), and that ships only after the fixture bench measures it.
167
+ media: 'media playback state; kept as evidence, not yet adjudicated on `ui`',
168
+ canvas: 'a digest of canvas pixels; kept as evidence, not yet adjudicated on `ui`',
161
169
  };
162
170
  /**
163
171
  * The capabilities that change the world, and therefore need an attribution window.
@@ -193,6 +201,7 @@ const REPORTED_AS_COVERAGE = new Set([
193
201
  */
194
202
  const PROTOCOL_ANOMALY = {
195
203
  [ContradictionKind.UI_ADVANCED_REQUEST_FAILED]: AnomalyKind.ADVANCED_OVER_FAILURE,
204
+ [ContradictionKind.UI_ADVANCED_UNSIGNALLED]: AnomalyKind.ADVANCED_OVER_FAILURE,
196
205
  [ContradictionKind.SIGNAL_CONTRADICTED]: AnomalyKind.CLAIMED_OVER_FAILURE,
197
206
  [ContradictionKind.RESPONSE_IGNORED]: AnomalyKind.EFFECT_DISCARDED,
198
207
  [ContradictionKind.SIGNAL_WITHOUT_CONSEQUENCE]: AnomalyKind.CLAIM_UNCORROBORATED,
@@ -260,8 +269,9 @@ export class WebRealm extends Realm {
260
269
  super();
261
270
  this.#deps = deps;
262
271
  const breaker = deps.mutations;
263
- if (breaker !== undefined)
272
+ if (breaker !== undefined) {
264
273
  this.mutate = (mutation) => breaker.mutate(mutation);
274
+ }
265
275
  const port = deps.fixtures;
266
276
  if (port !== undefined) {
267
277
  this.captureFixture = async () => ({
@@ -348,8 +358,9 @@ export class WebRealm extends Realm {
348
358
  // rule `HandshakeFacts` states for every field it carries. Such a page gets the full list,
349
359
  // which is the behaviour it had before anyone could ask.
350
360
  const served = this.#deps.session.commands;
351
- if (served === undefined)
361
+ if (served === undefined) {
352
362
  return PAGE_CAPABILITIES;
363
+ }
353
364
  const offered = new Set(served);
354
365
  return PAGE_CAPABILITIES.filter((c) => offered.has(c.name));
355
366
  }
@@ -426,8 +437,9 @@ export class WebRealm extends Realm {
426
437
  const channel = CHANNEL_OF_PREFIX[String(event.type).split('.')[0] ?? ''];
427
438
  // Unrecognised prefix: reported on no channel rather than guessed onto one. An observation
428
439
  // attributed to a source that did not produce it is worse than an observation nobody has.
429
- if (channel === undefined)
440
+ if (channel === undefined) {
430
441
  continue;
442
+ }
431
443
  out.push({
432
444
  id: `${window.id}-${String(index)}`,
433
445
  window: window.id,
@@ -528,7 +540,11 @@ export class WebRealm extends Realm {
528
540
  */
529
541
  #effectElsewhere(window) {
530
542
  const events = this.#deps.session.eventsSince(window.openedAt);
531
- return findContradictions(events, { actionSince: window.openedAt })
543
+ return findContradictions(events, {
544
+ actionSince: window.openedAt,
545
+ appOrigin: this.#deps.session.url,
546
+ background: this.#deps.session.background,
547
+ })
532
548
  .filter((c) => ContradictionKind.CONSEQUENCE_ELSEWHERE === c.kind)
533
549
  .map((c) => ({
534
550
  kind: BlindSpotKind.EFFECT_ELSEWHERE,
@@ -549,12 +565,15 @@ export class WebRealm extends Realm {
549
565
  const opened = new Map();
550
566
  for (const event of this.#deps.session.eventsSince(window.openedAt)) {
551
567
  const id = readRequestId(event.data);
552
- if (id === undefined)
568
+ if (id === undefined) {
553
569
  continue;
554
- if (event.type === EventType.NET_PENDING)
570
+ }
571
+ if (event.type === EventType.NET_PENDING) {
555
572
  opened.set(id, readUrl(event.data) ?? id);
556
- else if (event.type === EventType.NET_REQUEST)
573
+ }
574
+ else if (event.type === EventType.NET_REQUEST) {
557
575
  opened.delete(id);
576
+ }
558
577
  }
559
578
  return [...opened.values()].map((where) => ({
560
579
  kind: BlindSpotKind.STILL_IN_FLIGHT,
@@ -589,7 +608,11 @@ export class WebRealm extends Realm {
589
608
  // finding relative to ONE action. Passing `{}` left that rule switched off, and a planted
590
609
  // double submit came back proved. In this protocol the window IS the action's extent, so
591
610
  // its opening moment is exactly the boundary those rules are asking for.
592
- const found = findContradictions(events, { actionSince: window.openedAt }).filter((c) => !REPORTED_AS_COVERAGE.has(c.kind));
611
+ const found = findContradictions(events, {
612
+ actionSince: window.openedAt,
613
+ appOrigin: this.#deps.session.url,
614
+ background: this.#deps.session.background,
615
+ }).filter((c) => !REPORTED_AS_COVERAGE.has(c.kind));
593
616
  // Synchronous underneath: the rules read a buffer that is already in memory. The interface
594
617
  // is async for a realm that has to go and ask.
595
618
  return Promise.resolve(found.map((contradiction) => {
@@ -622,18 +645,22 @@ export class WebRealm extends Realm {
622
645
  async locate(query) {
623
646
  const args = 'object' === typeof query && null !== query ? { ...query } : {};
624
647
  const result = await this.#deps.session.command(ReticleCommand.QUERY, args);
625
- if (true !== result.ok)
648
+ if (true !== result.ok) {
626
649
  return [];
650
+ }
627
651
  const elements = result.result?.elements;
628
- if (!Array.isArray(elements))
652
+ if (!Array.isArray(elements)) {
629
653
  return [];
654
+ }
630
655
  const found = [];
631
656
  for (const element of elements) {
632
- if ('object' !== typeof element || null === element)
657
+ if ('object' !== typeof element || null === element) {
633
658
  continue;
659
+ }
634
660
  const ref = element.ref;
635
- if ('string' !== typeof ref)
661
+ if ('string' !== typeof ref) {
636
662
  continue;
663
+ }
637
664
  const name = element.name;
638
665
  const text = element.text;
639
666
  found.push({
@@ -30,7 +30,7 @@ interface PausedResult {
30
30
  * human's message entirely (not merely hides it). Declared here beside PausedResult so the schema and
31
31
  * the runtime shape are the same source; spread into each act tool's outputSchema.
32
32
  */
33
- export declare const pausedOutputShape: z.ZodRawShape;
33
+ export declare const pausedOutputShape: Record<string, z.ZodType>;
34
34
  /** The optional `control` key `withControl` may add — keeps callers' return types honest. */
35
35
  type ControlSpread = {
36
36
  control?: ControlEnvelope;
@@ -1,8 +1,3 @@
1
- /**
2
- * The document a local dev server actually serves: its CSP header and HTML, read once and failing
3
- * soft. Shared by `doctor` (is a policy blocking the bridge?) and a lease that never dialled (was
4
- * it the page's own policy?), which is why it lives beside the dev-server probe and not in either.
5
- */
6
1
  /** What a served page said about its policy. The same shape `diagnoseObservedWebCsp` reads. */
7
2
  export interface ObservedWebDocument {
8
3
  url: string;
@@ -1,3 +1,9 @@
1
+ /**
2
+ * The document a local dev server actually serves: its CSP header and HTML, read once and failing
3
+ * soft. Shared by `doctor` (is a policy blocking the bridge?) and a lease that never dialled (was
4
+ * it the page's own policy?), which is why it lives beside the dev-server probe and not in either.
5
+ */
6
+ import { originOf } from '@reticlehq/core';
1
7
  const CSP_HEADER = 'content-security-policy';
2
8
  const DOCUMENT_TIMEOUT_MS = 1_000;
3
9
  const LOOPBACK_HOSTS = ['localhost', '127.0.0.1', '[::1]'];
@@ -13,14 +19,6 @@ function loopbackDocumentUrl(raw) {
13
19
  return undefined;
14
20
  }
15
21
  }
16
- function originOf(raw) {
17
- try {
18
- return new URL(raw).origin;
19
- }
20
- catch {
21
- return undefined;
22
- }
23
- }
24
22
  /** A connected tab for this project, or on its observed origin, disproves a CSP diagnosis. */
25
23
  export function hasConnectedDocument(sessions, documentUrls, projectId) {
26
24
  if (projectId !== undefined && sessions.some((session) => session.projectId === projectId)) {
@@ -1,4 +1,4 @@
1
- import type { ChannelId } from '@reticlehq/core';
1
+ import type { ChannelId, HelloInstrumentation } from '@reticlehq/core';
2
2
  /**
3
3
  * What the page told us about itself when it connected.
4
4
  *
@@ -46,6 +46,13 @@ export interface HandshakeFacts {
46
46
  * `false` separates "the project turned it off" from "nothing provides one".
47
47
  */
48
48
  sourceMapping?: boolean | undefined;
49
+ /**
50
+ * Who put the SDK in this page, when it said: `injected` by a hosted verifier, or `installed` by
51
+ * the app. Undefined means installed, as every SDK before the field was.
52
+ *
53
+ * Read by the session listing, so a URL-only check never looks like an app with the SDK installed.
54
+ */
55
+ instrumentation?: HelloInstrumentation | undefined;
49
56
  /**
50
57
  * Extra key names this app declared sensitive via `connect({ redact: { keys } })`.
51
58
  *
@@ -1,42 +1,9 @@
1
- export interface WiredStep {
2
- mark: string;
3
- title: string;
4
- target: string;
5
- }
6
- export interface WireOutcome {
7
- ok: boolean;
8
- /** Where init ran. */
9
- directory: string;
10
- /** Every step of init's plan, applied or not, as it printed them. */
11
- steps: WiredStep[];
12
- /** The app's url, when init got as far as the dev server. */
13
- url?: string;
14
- /** Why it stopped, in init's words or ours. */
15
- error?: string;
16
- }
17
- export interface RunResult {
18
- code: number;
19
- stdout: string;
20
- stderr: string;
21
- }
22
- export type RunCli = (args: readonly string[], cwd: string) => Promise<RunResult>;
23
1
  export interface FirstRunWiring {
24
2
  /**
25
- * The directory init would run in, or undefined when it cannot be told without guessing: a
26
- * daemon started in the home directory or at a filesystem root has no project of its own.
3
+ * The unwired web app at `cwd`, or undefined when it cannot be told without guessing: a daemon
4
+ * started in the home directory or at a filesystem root has no project of its own.
27
5
  */
28
6
  projectDirectory(cwd: string): string | undefined;
29
- wire(directory: string): Promise<WireOutcome>;
30
7
  }
31
8
  export declare function projectDirectoryOf(cwd: string, home?: string, wired?: (dir: string) => boolean): string | undefined;
32
- /** init's plan lines, and the one JSON object it prints last under `--json`. */
33
- export declare function readInitOutput(stdout: string): {
34
- steps: WiredStep[];
35
- result: unknown;
36
- };
37
- export declare function firstRunWiring(options: {
38
- /** This daemon's port, so init wires the app to it rather than choosing another. */
39
- port: number;
40
- cliPath: string;
41
- run?: RunCli;
42
- }): FirstRunWiring;
9
+ export declare function firstRunWiring(): FirstRunWiring;
@@ -1,36 +1,25 @@
1
1
  /**
2
- * Wiring the app the first time an agent needs it, instead of at installation.
2
+ * Which unwired web app a caller is in.
3
3
  *
4
- * Installing Reticle puts a CLI and an MCP server on the machine and touches no project. The app is
5
- * instrumented the first time an agent actually uses Reticle against it: the daemon runs its own
6
- * CLI's `init` in the project directory, the same codemod, dev-server start and connect a person
7
- * would have run by hand, and reports what it changed.
8
- *
9
- * A child process rather than an import: the daemon never imports `@reticlehq/init`
10
- * (library-path-boundary.test.ts), and running the CLI keeps that line where it is.
11
- *
12
- * Once per directory for the life of the daemon. A second call returns the first answer, so an agent
13
- * that asks again after a failure is told the same thing rather than re-running a codemod on files
14
- * the first run already changed.
4
+ * Installing Reticle puts a CLI and an MCP server on the machine and touches no project. The
5
+ * daemon never wires a project by itself: `init` changes the user's files, so it runs only when
6
+ * the user agrees (the agent runs the command, or the user does). The daemon only finds the
7
+ * unwired app, so that the first session call can offer the zero-install lease and the consent
8
+ * question for it.
15
9
  */
16
- import { spawn } from 'node:child_process';
17
10
  import { existsSync, readFileSync } from 'node:fs';
18
11
  import { homedir } from 'node:os';
19
12
  import { join, resolve } from 'node:path';
20
13
  import { isWebApp } from '@reticlehq/init';
21
14
  import { readProjectId } from '../../command/cli/ports/resolve/cli-port.js';
22
- /** init has a dev server to start and a page to wait for; past this it is not coming. */
23
- const WIRE_TIMEOUT_MS = 120_000;
24
- /** A plan line as init prints it: `[✓] Vite plugin → vite.config.ts`. */
25
- const PLAN_LINE = /^\s*\[(.)\]\s+(.+?)\s+→\s+(.+)$/;
26
15
  export function projectDirectoryOf(cwd, home = homedir(), wired = (dir) => readProjectId(dir) !== undefined) {
27
16
  const dir = resolve(cwd);
28
17
  if (dir === resolve(home) || dir === resolve('/'))
29
18
  return undefined;
30
- // Already wired: nothing for a first run to do, and init over a wired app proves nothing.
19
+ // Already wired: there is no step to offer.
31
20
  if (wired(dir))
32
21
  return undefined;
33
- // Only an app with a page: a daemon started in a library or API package wrote a config there.
22
+ // Only an app with a page: a library or an API package has nothing to lease or to wire.
34
23
  return isWebApp('.', {
35
24
  exists: (p) => existsSync(join(dir, p)),
36
25
  readFile: (p) => {
@@ -45,88 +34,6 @@ export function projectDirectoryOf(cwd, home = homedir(), wired = (dir) => readP
45
34
  ? dir
46
35
  : undefined;
47
36
  }
48
- /** init's plan lines, and the one JSON object it prints last under `--json`. */
49
- export function readInitOutput(stdout) {
50
- const steps = stdout
51
- .split('\n')
52
- .map((line) => PLAN_LINE.exec(line))
53
- .flatMap((m) => null === m
54
- ? []
55
- : [{ mark: m[1] ?? '', title: (m[2] ?? '').trim(), target: (m[3] ?? '').trim() }]);
56
- const at = stdout.lastIndexOf('\n{\n') + 1;
57
- let result;
58
- try {
59
- result = JSON.parse(stdout.slice(at));
60
- }
61
- catch {
62
- result = undefined;
63
- }
64
- return { steps, result };
65
- }
66
- function nodeRun(cliPath) {
67
- return (args, cwd) => new Promise((done) => {
68
- const child = spawn(process.execPath, [cliPath, ...args], {
69
- cwd,
70
- stdio: ['ignore', 'pipe', 'pipe'],
71
- env: process.env,
72
- });
73
- let stdout = '';
74
- let stderr = '';
75
- child.stdout.on('data', (chunk) => (stdout += chunk.toString('utf8')));
76
- child.stderr.on('data', (chunk) => (stderr += chunk.toString('utf8')));
77
- const timer = setTimeout(() => child.kill(), WIRE_TIMEOUT_MS);
78
- child.on('error', (error) => {
79
- clearTimeout(timer);
80
- done({ code: 1, stdout, stderr: `${stderr}${error.message}` });
81
- });
82
- child.on('close', (code) => {
83
- clearTimeout(timer);
84
- done({ code: code ?? 1, stdout, stderr });
85
- });
86
- });
87
- }
88
- export function firstRunWiring(options) {
89
- const run = options.run ?? nodeRun(options.cliPath);
90
- const done = new Map();
91
- return {
92
- projectDirectory: (cwd) => projectDirectoryOf(cwd),
93
- wire(directory) {
94
- const held = done.get(directory);
95
- if (held !== undefined)
96
- return held;
97
- const outcome = run(['init', '--no-mcp', '--json', '--port', String(options.port)], directory)
98
- .then(({ code, stdout, stderr }) => {
99
- // Under --json the plan lines may go to stderr, keeping stdout for the one object.
100
- const { result } = readInitOutput(stdout);
101
- const { steps } = readInitOutput(`${stdout}\n${stderr}`);
102
- const record = 'object' === typeof result && null !== result
103
- ? result
104
- : {};
105
- const url = 'string' === typeof record['url'] ? record['url'] : undefined;
106
- const ok = 0 === code && true === record['ok'];
107
- const lastError = stderr.trim().split('\n').at(-1);
108
- return {
109
- ok,
110
- directory,
111
- steps,
112
- ...(url === undefined ? {} : { url }),
113
- ...(ok
114
- ? {}
115
- : {
116
- error: lastError !== undefined && 0 < lastError.length
117
- ? lastError
118
- : `init exited ${String(code)}`,
119
- }),
120
- };
121
- })
122
- .catch((error) => ({
123
- ok: false,
124
- directory,
125
- steps: [],
126
- error: error instanceof Error ? error.message : String(error),
127
- }));
128
- done.set(directory, outcome);
129
- return outcome;
130
- },
131
- };
37
+ export function firstRunWiring() {
38
+ return { projectDirectory: (cwd) => projectDirectoryOf(cwd) };
132
39
  }
@@ -14,6 +14,20 @@ async function settledJournal(session) {
14
14
  await session.flushJournal?.();
15
15
  return session.readJournalActions();
16
16
  }
17
+ /**
18
+ * Did the caller name a session that has DEPARTED?
19
+ *
20
+ * `resolve` answers a departed id with its live SUCCESSOR. That is right for everything that
21
+ * observes -- a tab reloads, its id survives in sessionStorage, and an `assert` should keep
22
+ * working -- and wrong for a call that changes a session's state: it acts on a tab the caller never
23
+ * named (#983, #1774). An id the daemon has never seen is not departed; it falls through to
24
+ * `resolve`, which refuses it with the live ids named.
25
+ */
26
+ function namedSessionDeparted(sessions, requested) {
27
+ return (requested !== undefined &&
28
+ sessions.get(requested) === undefined &&
29
+ sessions.departed(requested) !== undefined);
30
+ }
17
31
  /**
18
32
  * The session an id-less yield hands back.
19
33
  *
@@ -70,6 +84,20 @@ function endingTurnWithNothingAttached(deps, id) {
70
84
  const DISCONNECT_NEEDS_SESSION_ID = '`disconnect: true` needs the `sessionId` of the page to detach — list them with ' +
71
85
  'reticle_session{action:"list"}; it is never picked for you, because detaching the wrong window ' +
72
86
  'cuts you off from the app.';
87
+ /** A resume on a named session that has departed: there is no pause left to clear (#1774). */
88
+ function resumeDepartedNote(requested) {
89
+ return (`session '${requested}' had already disconnected, so there was no pause to clear. ` +
90
+ 'Nothing else was resumed: a named session is matched exactly, never substituted.');
91
+ }
92
+ /**
93
+ * A review on a named session that has departed. Marks belong to one tab, so a listing from another
94
+ * tab answers a question the caller did not ask.
95
+ */
96
+ function reviewDepartedError(requested) {
97
+ return (`session '${requested}' had already disconnected, so its marks are gone. ` +
98
+ 'No other session was read: a named session is matched exactly, never substituted. ' +
99
+ 'List the live sessions with reticle_session{action:"list"}.');
100
+ }
73
101
  /** The agent's claim, when it is one of the words a run verdict uses. */
74
102
  function claimOf(value) {
75
103
  const claims = [
@@ -89,7 +117,7 @@ export const LIVE_CONTROL_TOOLS = [
89
117
  'until the daemon restarts — for a stray window (a hidden desktop webview, a 404 page) that keeps coming back. ' +
90
118
  'Ending a tab you leased also releases that lease (`leaseReleased: true`).',
91
119
  inputSchema: {
92
- summary: z.string().optional(),
120
+ summary: z.string().optional().describe('One sentence: what this session proved.'),
93
121
  claim: z
94
122
  .enum([VerdictStatus.PASS, VerdictStatus.FAIL, VerdictStatus.PARTIAL])
95
123
  .optional()
@@ -133,23 +161,14 @@ export const LIVE_CONTROL_TOOLS = [
133
161
  return Promise.resolve({ ended: true, note: YIELD_WITHOUT_SESSION_NOTE });
134
162
  }
135
163
  // A NAMED session that has DEPARTED is already ended, and nothing else may be ended in its
136
- // place.
137
- //
138
- // `resolve` answers a departed id with its live SUCCESSOR. That is right for everything
139
- // that observes -- a tab reloads, its id survives in sessionStorage, and an `assert` should
140
- // keep working -- and wrong here, because ending a session is destructive and cannot be
141
- // taken back. Reported from the field: `sessionId: "sac14d46c…"` returned `ended: true` for
142
- // `"s08e37e5c…"`, once where the requested session's browser had just closed, so the
143
- // behaviour was "target missing => end something else" rather than "target missing => say
144
- // so" (#983).
164
+ // place. Ending a session is destructive and cannot be taken back. Reported from the field:
165
+ // `sessionId: "sac14d46c…"` returned `ended: true` for `"s08e37e5c…"`, once where the
166
+ // requested session's browser had just closed, so the behaviour was "target missing => end
167
+ // something else" rather than "target missing => say so" (#983).
145
168
  //
146
169
  // Not an error, either: this tool is documented as idempotent, and "the session you named is
147
- // already gone" is precisely the idempotent answer. An id the daemon has never seen IS a
148
- // mistake about which tab, and falls through to `resolve`, which refuses it with the live
149
- // ids named.
150
- if (requested !== undefined &&
151
- deps.sessions.get(requested) === undefined &&
152
- deps.sessions.departed(requested) !== undefined) {
170
+ // already gone" is precisely the idempotent answer.
171
+ if (namedSessionDeparted(deps.sessions, requested)) {
153
172
  return Promise.resolve({
154
173
  ended: true,
155
174
  sessionId: requested,
@@ -231,6 +250,17 @@ export const LIVE_CONTROL_TOOLS = [
231
250
  note: YIELD_WITHOUT_SESSION_NOTE,
232
251
  });
233
252
  }
253
+ // A NAMED session that has DEPARTED has nothing to hand back, and no other tab may be marked
254
+ // as waiting in its place (#1774). The same idempotent answer `end` gives.
255
+ if (namedSessionDeparted(deps.sessions, requested)) {
256
+ return Promise.resolve({
257
+ yielded: true,
258
+ mode: ask ? PresenterTone.ASK : PresenterTone.WAITING,
259
+ sessionId: requested,
260
+ note: `session '${String(requested)}' had already disconnected, so there was nothing to yield. ` +
261
+ 'Nothing else was yielded: a named session is matched exactly, never substituted.',
262
+ });
263
+ }
234
264
  const session = resolveYieldTarget(deps.sessions, requested);
235
265
  const note = asString(args['note']);
236
266
  const tone = ask ? PresenterTone.ASK : PresenterTone.WAITING;
@@ -253,9 +283,15 @@ export const LIVE_CONTROL_TOOLS = [
253
283
  description: 'Clear a human pause and resume driving the page. Sets state "active" and syncs the panel ' +
254
284
  '(PRESENTER). Call after you have addressed the human guidance returned by a paused reticle_act.',
255
285
  inputSchema: { ...sessionIdShape },
256
- outputSchema: { ok: z.boolean() },
286
+ outputSchema: { ok: z.boolean(), note: z.string().optional() },
257
287
  handler: (deps, args) => {
258
- const session = deps.sessions.resolve(asString(args['sessionId']));
288
+ const requested = asString(args['sessionId']);
289
+ // A NAMED session that has DEPARTED has no pause to clear. Resuming its successor would clear a
290
+ // pause the human set by hand on a tab the agent never named (#1774). Idempotent, as `end` is.
291
+ if (namedSessionDeparted(deps.sessions, requested)) {
292
+ return Promise.resolve({ ok: true, note: resumeDepartedNote(String(requested)) });
293
+ }
294
+ const session = deps.sessions.resolve(requested);
259
295
  // setState echoes ACTIVE to the panel in a single PRESENTER push.
260
296
  session.setState(SessionState.ACTIVE);
261
297
  return Promise.resolve({ ok: true });
@@ -334,7 +370,13 @@ export const LIVE_CONTROL_TOOLS = [
334
370
  .describe('The note on the mark that was actually retired. CHECK IT against the mark you meant to resolve: a bare `resolved:true` cannot tell you it closed the right one, and ids are only meaningful while the session that issued them lives.'),
335
371
  },
336
372
  handler: (deps, args) => {
337
- const session = deps.sessions.resolve(asString(args['sessionId']));
373
+ const requested = asString(args['sessionId']);
374
+ // A NAMED session that has DEPARTED is refused, not substituted: a listing or a `resolve` on its
375
+ // successor reads or retires marks on a tab the caller never named (#1774).
376
+ if (namedSessionDeparted(deps.sessions, requested)) {
377
+ throw new Error(reviewDepartedError(String(requested)));
378
+ }
379
+ const session = deps.sessions.resolve(requested);
338
380
  const resolveId = asString(args['resolve']);
339
381
  let resolved;
340
382
  let resolvedNote;
@@ -28,6 +28,8 @@ interface NextActionFacts {
28
28
  everConnected: boolean;
29
29
  initialized: boolean;
30
30
  listening: readonly number[];
31
+ /** Scanned ports that serve a page from a process that cannot be tied to this project. */
32
+ otherListeners?: readonly number[];
31
33
  dev: DevCommand | undefined;
32
34
  /**
33
35
  * File-existence predicate for the project root, pure for testing.
@@ -114,6 +116,15 @@ export declare function departedPortGone(facts: {
114
116
  listening: readonly number[];
115
117
  slowListeners?: readonly number[];
116
118
  }): boolean;
119
+ export declare const INIT_COMMAND = "npx @reticlehq/server init";
120
+ /**
121
+ * The consent question for wiring, in one wording for every place that offers `init`: the
122
+ * handshake, the first session call, every next action and the plugin hook. `init` changes the user's files, so the
123
+ * agent asks first. The lease changes nothing, so it needs no question.
124
+ */
125
+ export declare function wiringConsent(init?: string): string;
126
+ /** The zero-install call, with the URL only when it can be named without guessing. */
127
+ export declare function zeroInstallLease(url: string | undefined): string;
117
128
  export declare function nextActionFor(facts: NextActionFacts): NoSessionNextAction;
118
129
  /** The same action as one sentence, for the prose message the human reads. */
119
130
  export declare function renderNextAction(next: NoSessionNextAction): string;