@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
package/dist/index.js CHANGED
@@ -1,26 +1,27 @@
1
+ import { agentSessionInEnv } from './command/version/peer-announce.js';
1
2
  import { applyHarnessSwitch, harnessConfigsByRoot } from './memory/cloud/harness-config.js';
2
3
  import { coveragePercents } from './features/exhaust/ledger.js';
3
4
  import { agentWiring } from './portal/session/zero-install-first-call.js';
4
5
  import { pushIfMoved, watchAccountFiles } from './memory/impact/account-watch.js';
5
6
  import { SESSION_FILE } from './command/cli/cloud-kit.js';
7
+ import { signedInTo } from './command/cli/auth/cloud-session.js';
6
8
  import { join } from 'node:path';
7
9
  import { homedir } from 'node:os';
8
10
  import { linkedCloudPort, sessionCloudPort } from './memory/cloud/cloud-config.js';
9
11
  import { sessionRoot } from './memory/project/session-root.js';
10
- import { attachCloudSync } from './memory/cloud/sync-daemon.js';
12
+ import { attachCloudSync, flushWithin } from './memory/cloud/sync-daemon.js';
11
13
  import { wireHooks } from './hooks/hook-commands.js';
12
14
  import { currentDrivenBy } from './hooks/driven-by.js';
13
15
  import { artifactRootResolver } from './memory/project/artifact-root-resolver.js';
14
- import { servingDirectoryOf } from './portal/session/serving-directory.js';
16
+ import { liveCheckoutSource, servingDirectoryOf } from './portal/session/serving-directory.js';
15
17
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
16
- import { AGENT_STOPPED_NOTICE, RETICLE_DEFAULT_PORT, ReticleCommand, ReticleDir, ReticleEnv, LOOPBACK_HOST, } from '@reticlehq/core';
18
+ import { AGENT_STOPPED_NOTICE, AGENT_DETACH_GRACE_MS, RETICLE_DEFAULT_PORT, ReticleCommand, ReticleDir, ReticleEnv, LOOPBACK_HOST, } from '@reticlehq/core';
17
19
  import { replayFromHud } from './language/flows/replay-from-hud.js';
18
20
  import { createSharedServer } from './surface/http-server.js';
19
21
  import { openLoopbackAlias } from './command/daemon/binding/loopback-alias.js';
20
22
  import { reportAppInstrumented } from './telemetry/app-instrumented.js';
21
23
  import { resolveBridgeSecurityWithAutoToken } from './portal/bridge/bridge-security.js';
22
24
  import { Bridge } from './portal/bridge/bridge.js';
23
- import { connectionSkew } from './command/version/version-nudge.js';
24
25
  import { SERVER_VERSION } from './command/version/identity/server-version.js';
25
26
  import { BaselineStore } from './memory/project/baselines.js';
26
27
  import { RecordingStore } from './language/flows/recording/tape/recordings.js';
@@ -38,14 +39,15 @@ import { ReticleRunner } from './judgement/runs/reticle-runner.js';
38
39
  import { createRunnerPort } from './judgement/runs/runner-port.js';
39
40
  import { RunStore } from './judgement/runs/artifact/run-store.js';
40
41
  import { startVerifyServer } from './judgement/runs/verify-server.js';
41
- import { createMcpServer } from './surface/mcp/mcp.js';
42
+ import { createMcpServer, mcpServerFactoryFor } from './surface/mcp/mcp.js';
42
43
  import { instructionStateAt } from './surface/mcp/mcp-proxy.js';
43
44
  import { LEASE_ACQUIRE_TOOL } from './surface/tools/lease-tools.js';
44
45
  import { attachHudHarness, projectLinkOnly, startChatDrives } from './surface/tools/chat-drives.js';
45
46
  import { runTool } from './surface/tools/invoke-tool.js';
46
47
  import { SessionReaper, endAllSessions, MCP_DISCONNECT_SUMMARY, } from './portal/session/session-reaper.js';
47
48
  import { wireSessionScope } from './portal/session/no-session-watch.js';
48
- import { buildIdlePredicate, noteSetupHold } from './command/daemon/lifetime/daemon-usefulness.js';
49
+ import { withDetachGrace } from './surface/agent-presence-grace.js';
50
+ import { buildIdlePredicate, noteAgentPresence, noteSetupHold, } from './command/daemon/lifetime/daemon-usefulness.js';
49
51
  import { resolveToolSurface } from './surface/tools/tool-surface.js';
50
52
  import { statusPayload } from './status-payload.js';
51
53
  import { AGENT_ALREADY_DRIVING_ELSEWHERE, shouldGreetWithLeaseNotice, } from './portal/session/lease-visibility.js';
@@ -68,7 +70,8 @@ export { SessionManager } from './portal/session/session-manager.js';
68
70
  export { buildSessionRecommendation } from './portal/session/presence/session-recommendation.js';
69
71
  export { TOOLS } from './surface/tools/tools.js';
70
72
  export { createToolInvoker, UNKNOWN_TOOL_ERROR } from './surface/tools/tool-invoker.js';
71
- export { runTool, SESSION_BOUND_TOOLS, SESSION_EXEMPT_TOOLS } from './surface/tools/invoke-tool.js';
73
+ export { runTool } from './surface/tools/invoke-tool.js';
74
+ export { SESSION_BOUND_TOOLS, SESSION_EXEMPT_TOOLS } from './surface/tools/tool-kit.js';
72
75
  /**
73
76
  * The port-presence check the CLI commands (`drive`, `verify`, `status`, `doctor`, `kill`) all share,
74
77
  * re-exported so a consumer embedding `start()` in its own process can refuse a taken port the same
@@ -99,6 +102,8 @@ export { findContradictions } from '@reticlehq/engine/disagreement/contradiction
99
102
  /** Default localhost port for the verify HTTP endpoint (see docs/platform-integration.md). */
100
103
  export const RETICLE_VERIFY_DEFAULT_PORT = 7331;
101
104
  export { resolveBridgeSecurity } from './portal/bridge/bridge-security.js';
105
+ /** How long `start().close()` waits for its last sync cycle. Exit must not hang on the network. */
106
+ const EXIT_SYNC_BUDGET_MS = 5_000;
102
107
  /** Start the Reticle bridge (browser WS endpoint) and, by default, the MCP stdio server. */
103
108
  export async function start(options = {}) {
104
109
  const port = options.port ?? RETICLE_DEFAULT_PORT;
@@ -116,6 +121,19 @@ export async function start(options = {}) {
116
121
  coverageForRoot: (root) => () => coveragePercents(root),
117
122
  });
118
123
  const uninstallHooks = wireHooks(options.reticleRoot ?? join(process.cwd(), ReticleDir.ROOT), readProjectId(process.cwd()));
124
+ /*
125
+ * The same sync the daemon runs. `reticle drive` without a daemon and a self-booting `verify` run
126
+ * here, and their work waited on disk for a later daemon. It does nothing for an unlinked root,
127
+ * and `close` sends one last bounded cycle.
128
+ */
129
+ const cloudSync = attachCloudSync({
130
+ fs: createNodeFileSystem(),
131
+ reticleRoot: options.reticleRoot ?? join(process.cwd(), ReticleDir.ROOT),
132
+ homeDir: homedir(),
133
+ env: process.env,
134
+ otherRoots: knownProjectRoots,
135
+ clientVersion: SERVER_VERSION,
136
+ });
119
137
  const security = await resolveBridgeSecurityWithAutoToken(options);
120
138
  const bridge = new Bridge({ port, sdkFix: sdkFixForProject, ...security });
121
139
  // Server-authoritative liveness: a Node-side reaper (immune to browser throttling) ends sessions
@@ -128,6 +146,8 @@ export async function start(options = {}) {
128
146
  if (activeProjectId !== undefined) {
129
147
  bridge.sessions.setDefaultScope({ projectId: activeProjectId });
130
148
  }
149
+ // Then to the agent's own git worktree: every worktree declares the same projectId.
150
+ bridge.sessions.setCheckoutScope(liveCheckoutSource());
131
151
  const baselines = new BaselineStore();
132
152
  const recordings = new RecordingStore(() => currentDrivenBy() !== undefined);
133
153
  // drive precedence: driveUrl (launch+own a browser) → CDP (attach) → none.
@@ -158,6 +178,8 @@ export async function start(options = {}) {
158
178
  reportStep: reportOnboardingStep,
159
179
  flows,
160
180
  author: flowAuthor,
181
+ // A run or flow written mid-drive goes out within seconds, as it does under the daemon.
182
+ onRunPersisted: () => cloudSync.nudge(),
161
183
  });
162
184
  const project = new ProjectStore(fs, reticleRoot, { now });
163
185
  attachRouteLearning(bridge, projectStoreResolver(fs, project, reticleRoot, now));
@@ -181,8 +203,9 @@ export async function start(options = {}) {
181
203
  bridge.attachSessionCreate((session) => {
182
204
  const leasedIds = leasePool.leasedSessionIds();
183
205
  const leasedProjects = leasedIds.map((id) => bridge.sessions.get(id)?.projectId);
184
- if (shouldGreetWithLeaseNotice(session, leasedIds, leasedProjects))
206
+ if (shouldGreetWithLeaseNotice(session, leasedIds, leasedProjects)) {
185
207
  session.pushNarration(AGENT_ALREADY_DRIVING_ELSEWHERE);
208
+ }
186
209
  });
187
210
  const deps = {
188
211
  sessions: bridge.sessions,
@@ -198,6 +221,7 @@ export async function start(options = {}) {
198
221
  artifactRootFor: artifactRootResolver(reticleRoot, { servingDirectory: servingDirectoryOf }),
199
222
  now,
200
223
  bridgePort: port,
224
+ nonces: bridge.nonces,
201
225
  browserProbe: probeLaunchableChromium,
202
226
  // The daemon's OWN project, so a tool can tell "this session is mine" from "this session
203
227
  // belongs to a sibling app under the same daemon". contract_save refuses on the second.
@@ -210,12 +234,16 @@ export async function start(options = {}) {
210
234
  sessionCloud: sessionCloudPort(fs, homedir(), process.env, (id) => sessionRoot(toolDeps, id)),
211
235
  version: SERVER_VERSION,
212
236
  }, log);
213
- const server = createMcpServer(toolDeps, profile, instructionStateAt(port, bridge.sessions.count()));
237
+ // Over stdio this process IS the agent's MCP server: the agent's session is in its environment.
238
+ const agentSession = agentSessionInEnv(process.env);
239
+ const server = createMcpServer(agentSession === undefined ? toolDeps : { ...toolDeps, agentSession }, profile, instructionStateAt(port, bridge.sessions.count()));
214
240
  // When the agent (the MCP client) disconnects cleanly, end every active session at once so the
215
241
  // HUD doesn't linger. (If the agent instead KILLS this process, the WS dies and the browser
216
242
  // self-ends via SESSION_LIFECYCLE.BRIDGE_LOST_MS — see transport.ts.)
217
243
  server.server.onclose = () => {
218
244
  endAllSessions(bridge.sessions, MCP_DISCONNECT_SUMMARY);
245
+ // The client often kills this process without calling `close`: send what the teardown wrote.
246
+ cloudSync.nudge();
219
247
  };
220
248
  await server.connect(new StdioServerTransport());
221
249
  log('mcp_connected', { port });
@@ -230,6 +258,7 @@ export async function start(options = {}) {
230
258
  await cleanupCaptureDirectories();
231
259
  leaseReaper?.stop();
232
260
  chatDrives?.stop();
261
+ await flushWithin(cloudSync, EXIT_SYNC_BUDGET_MS);
233
262
  await pool?.shutdown();
234
263
  await owned?.dispose();
235
264
  await bridge.close();
@@ -268,11 +297,14 @@ export async function startDaemon(options = {}) {
268
297
  sdkFix: sdkFixForProject,
269
298
  ...security,
270
299
  });
300
+ // The daemon serves every agent on the machine: scope id-less calls to the calling agent's worktree.
301
+ bridge.sessions.setCheckoutScope(liveCheckoutSource());
271
302
  const repaint = (only, ifChanged = false) => {
272
303
  for (const session of bridge.sessions.all()) {
273
304
  const root = session.artifactRoot ?? options.reticleRoot ?? join(process.cwd(), ReticleDir.ROOT);
274
- if ((only ?? root) === root)
305
+ if ((only ?? root) === root) {
275
306
  pushIfMoved(session, () => impactSnapshot(root), ifChanged);
307
+ }
276
308
  }
277
309
  };
278
310
  pushHarnessConfig = repaint;
@@ -289,22 +321,29 @@ export async function startDaemon(options = {}) {
289
321
  // the requested `--http-port` instead of silently ignoring the flag (#687).
290
322
  shared.attachStatus((held) => {
291
323
  // `init` holds the daemon it is waiting on, so the idle rule cannot shut it down mid-wait.
292
- if (held)
324
+ if (held) {
293
325
  noteSetupHold(Date.now());
294
- return statusPayload(bridge.sessions.count(), bridge.sessions.list(), bridge.sessions.noSessionHint(), verifyHttp?.port, bridge.sessions.noSessionLead(), bridge.sessions.all());
326
+ }
327
+ const tabs = bridge.sessions.all();
328
+ return statusPayload(bridge.sessions.count(), bridge.sessions.list(), bridge.sessions.noSessionHint(), verifyHttp?.port, bridge.sessions.noSessionLead(), tabs, tabs.map((session) => session.sdkVersion ?? null));
295
329
  });
330
+ // Called when an agent connects. The pages already up are the ones a restart would skew (#1709).
331
+ shared.attachPageSdkVersions(() => bridge.sessions.all().map((session) => session.sdkVersion));
296
332
  // Agent-independent presence: the daemon outlives any single agent, so when the LAST agent's MCP
297
333
  // connection drops (it stopped, or is waiting on the human), end every session and push a clear
298
334
  // "go to your terminal" notice to the panel — the human is on the browser and must not lose a typed
299
335
  // prompt into a dead session. A returning agent's next tool call revives the auto-ended session.
300
336
  // Track agent presence for the idle-shutdown predicate (below): the daemon is "idle" only when no
301
337
  // agent is attached AND no browser tab is connected AND no pool lease is active.
338
+ // The detach waits a short grace: a proxy that reconnects inside it keeps the sessions.
302
339
  let agentConnected = false;
303
- shared.attachAgentPresence((connected) => {
340
+ shared.attachAgentPresence(withDetachGrace((connected) => {
304
341
  agentConnected = connected;
305
- if (!connected)
342
+ noteAgentPresence(Date.now());
343
+ if (!connected) {
306
344
  endAllSessions(bridge.sessions, AGENT_STOPPED_NOTICE);
307
- });
345
+ }
346
+ }, AGENT_DETACH_GRACE_MS));
308
347
  const reaper = new SessionReaper(bridge.sessions);
309
348
  reaper.start();
310
349
  const { realInput, owned } = await resolveRealInput(options, () => shared.close(), makeNetworkDetailRouter(bridge, options.driveUrl));
@@ -366,12 +405,15 @@ export async function startDaemon(options = {}) {
366
405
  homeDir: homedir(),
367
406
  env: process.env,
368
407
  otherRoots: knownProjectRoots,
408
+ clientVersion: SERVER_VERSION,
409
+ signedIn: (url) => signedInTo(join(homedir(), ReticleDir.ROOT), url),
369
410
  });
370
411
  syncNudge.run = () => cloudSync.nudge();
371
412
  // `syncNow`, not `nudge` (a cycle soon): somebody is watching the button. Never awaited.
372
413
  bridge.attachSyncRequest(() => void cloudSync.syncNow());
373
- if (options.hudSignIn !== undefined)
414
+ if (options.hudSignIn !== undefined) {
374
415
  bridge.attachSigninRequest(options.hudSignIn(repaint, projectLinkOnly(options.hudLink)));
416
+ }
375
417
  // Logout and link run in another process: repaint when their files change, the rest on a timer.
376
418
  const accountFiles = watchAccountFiles(repaint, undefined, () => repaint(undefined, true));
377
419
  accountFiles.watch(join(homedir(), ReticleDir.ROOT, SESSION_FILE));
@@ -409,19 +451,16 @@ export async function startDaemon(options = {}) {
409
451
  artifactRootFor: artifactRootResolver(reticleRoot, { servingDirectory: servingDirectoryOf }),
410
452
  now,
411
453
  bridgePort: port,
454
+ nonces: bridge.nonces,
412
455
  browserProbe: probeLaunchableChromium,
413
- ...agentWiring(port, bridge.sessions, leaseUrl),
456
+ ...agentWiring(bridge.sessions, leaseUrl),
414
457
  // A finished verification should not sit behind a one-minute timer — see ToolDeps.onRunPersisted.
415
458
  onRunPersisted: () => cloudSync.nudge(),
416
459
  syncNow: () => cloudSync.syncNow(),
417
460
  };
418
461
  const profile = resolveToolSurface(options.toolProfile);
419
462
  const effectiveDeps = realInput !== undefined ? { ...deps, realInput } : deps;
420
- // Read per attach, not once: a project that gets wired while this daemon is alive should stop
421
- // being told to wire itself on the next agent that connects.
422
- shared.attachMcp((peerSkew) => createMcpServer(peerSkew === undefined
423
- ? effectiveDeps
424
- : { ...effectiveDeps, peerSkew: connectionSkew(peerSkew) }, profile, instructionStateAt(port, bridge.sessions.count())));
463
+ shared.attachMcp(mcpServerFactoryFor(effectiveDeps, profile, () => instructionStateAt(port, bridge.sessions.count())));
425
464
  shared.attachDrive(leaseUrl); // `reticle drive <url>` — see cli/drive/drive-attach.ts.
426
465
  // The platform chat's apps and drives, run here. See chat-drives.ts.
427
466
  const chatDrives = startChatDrives(effectiveDeps, bridge.sessions, fs, {
@@ -446,8 +485,9 @@ export async function startDaemon(options = {}) {
446
485
  // verdict into the same activity log they watch the agent in. The page animates via the normal
447
486
  // replay path, so they see it re-drive and the ✓/⚠/✗ land.
448
487
  bridge.attachReplay((sessionId, flowName) => {
449
- if (bridge.sessions.get(sessionId) === undefined)
488
+ if (bridge.sessions.get(sessionId) === undefined) {
450
489
  return;
490
+ }
451
491
  void replayFromHud(effectiveDeps, (id) => bridge.sessions.get(id), sessionId, flowName);
452
492
  });
453
493
  // On connect, hand the panel the replayable flows so it can render the ▶ list. Scoped to the
@@ -511,12 +551,14 @@ export async function startDaemon(options = {}) {
511
551
  // says WHETHER it is idle; this says how long that quiet should be tolerated — see idle-grace.
512
552
  agentAttached: () => agentConnected,
513
553
  announceShutdown: () => shared.announceShutdown(),
554
+ onShutdownRequest: (handler) => shared.attachShutdown(handler),
514
555
  close: async () => {
515
556
  reaper.stop();
516
557
  await cleanupCaptureDirectories();
517
558
  const vh = verifyHttp;
518
- if (vh !== undefined)
559
+ if (vh !== undefined) {
519
560
  await new Promise((resolve) => vh.server.close(() => resolve()));
561
+ }
520
562
  leaseReaper.stop();
521
563
  chatDrives.stop();
522
564
  accountFiles.close();
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A session's journal as the App Graph's driven steps (`@reticlehq/core`'s `mapOfRun`): what each act
3
+ * pressed, anchored the way a flow anchors it, the events of its own window, and whether what it
4
+ * declared held. The cloud reads the same steps off its harness's calls; a coding agent's acts are
5
+ * read off the journal the daemon already keeps, so building the graph costs the act path nothing.
6
+ */
7
+ import { type DrivenStep, type JournalAction, type ReticleEvent } from '@reticlehq/core';
8
+ export declare function journalSteps(actions: readonly JournalAction[], events: readonly ReticleEvent[]): DrivenStep[];
@@ -0,0 +1,92 @@
1
+ /**
2
+ * A session's journal as the App Graph's driven steps (`@reticlehq/core`'s `mapOfRun`): what each act
3
+ * pressed, anchored the way a flow anchors it, the events of its own window, and whether what it
4
+ * declared held. The cloud reads the same steps off its harness's calls; a coding agent's acts are
5
+ * read off the journal the daemon already keeps, so building the graph costs the act path nothing.
6
+ */
7
+ import { ReticleTool, asString, } from '@reticlehq/core';
8
+ /** The acts that press something. Reads, waits and navigation press nothing. */
9
+ const PRESSING = new Set([
10
+ ReticleTool.ACT,
11
+ ReticleTool.ACT_AND_WAIT,
12
+ ReticleTool.ACT_SEQUENCE,
13
+ ]);
14
+ const record = (value) => 'object' === typeof value && null !== value ? value : {};
15
+ /** A step's target as a flow's anchor; undefined for a ref, which no later run can find again. */
16
+ const anchorOf = (step) => {
17
+ const target = record(step['target']);
18
+ const testid = asString(target['testid']) ?? ('testid' === step['by'] ? asString(step['value']) : undefined);
19
+ if (testid !== undefined) {
20
+ return { by: 'testid', value: testid };
21
+ }
22
+ const role = asString(target['role']) ?? ('role' === step['by'] ? asString(step['value']) : undefined);
23
+ const name = asString(target['name']) ?? asString(step['name']);
24
+ return role !== undefined && name !== undefined ? { by: 'role', value: role, name } : undefined;
25
+ };
26
+ const heldOf = (effect) => {
27
+ const verified = record(effect)['verified'];
28
+ if ('yes' === verified) {
29
+ return true;
30
+ }
31
+ if ('no' === verified) {
32
+ return false;
33
+ }
34
+ return undefined;
35
+ };
36
+ export function journalSteps(actions, events) {
37
+ const steps = [];
38
+ const within = (from, to) => events.filter((e) => e.t >= from && e.t <= to);
39
+ // The steps of the last sequence, by index, so its later verdict lines find them.
40
+ let sequence = [];
41
+ for (const a of actions) {
42
+ if (!PRESSING.has(a.tool)) {
43
+ continue;
44
+ }
45
+ const args = record(a.args);
46
+ const index = args['step'];
47
+ // A sequence's verdict for one of its steps arrives as its own line.
48
+ if ('number' === typeof index) {
49
+ const step = sequence[index];
50
+ const held = heldOf(a.effect);
51
+ if (step !== undefined && held !== undefined) {
52
+ step.held = held;
53
+ }
54
+ continue;
55
+ }
56
+ const inner = Array.isArray(args['steps']) ? args['steps'].map(record) : undefined;
57
+ if (inner === undefined) {
58
+ const anchor = anchorOf(args);
59
+ if (anchor === undefined) {
60
+ continue;
61
+ }
62
+ const held = heldOf(a.effect);
63
+ steps.push({
64
+ anchor,
65
+ since: a.tRange.from,
66
+ window: within(a.tRange.from, a.tRange.to),
67
+ ...(held === undefined ? {} : { held }),
68
+ });
69
+ continue;
70
+ }
71
+ // ponytail: one window for the whole sequence, credited to its last step; per-step windows
72
+ // would need the journal to record each step's range.
73
+ sequence = [];
74
+ inner.forEach((step, i) => {
75
+ const anchor = anchorOf(step);
76
+ const last = i === inner.length - 1;
77
+ const driven = anchor === undefined
78
+ ? undefined
79
+ : {
80
+ anchor,
81
+ since: a.tRange.from,
82
+ window: last ? within(a.tRange.from, a.tRange.to) : [],
83
+ };
84
+ if (driven !== undefined) {
85
+ steps.push(driven);
86
+ }
87
+ // Kept by position, so a step without an anchor still takes its index.
88
+ sequence[i] = driven ?? { anchor: {}, since: a.tRange.from, window: [] };
89
+ });
90
+ }
91
+ return steps;
92
+ }
@@ -18,52 +18,15 @@ export declare const CAPSULE_VERSION = 1;
18
18
  declare const CapsuleSchema: z.ZodObject<{
19
19
  version: z.ZodLiteral<1>;
20
20
  id: z.ZodString;
21
- /** The flow the failure happened in, when it came from one (a bare assert has no flow). */
22
21
  flow: z.ZodOptional<z.ZodString>;
23
22
  createdAt: z.ZodNumber;
24
- /** Why it was captured — a failed assertion, a crawl anomaly, a human review pin. */
25
23
  origin: z.ZodString;
26
- /** The consequence that was supposed to hold. */
27
24
  expected: z.ZodString;
28
- /** What was observed instead — the first-divergence sentence. */
29
25
  observed: z.ZodString;
30
- /** Minimal steps to reproduce (prefix-trimmed). */
31
- steps: z.ZodArray<z.ZodType<FlowStep, z.ZodTypeDef, FlowStep>, "many">;
32
- /**
33
- * How many times this exact failure has been captured, and when it last was.
34
- *
35
- * A repeat is not a new capsule -- it is the same one, again. "This failed 37 times, most
36
- * recently at T" is strictly MORE than 37 files each holding one timestamp, so folding the
37
- * duplicates in adds information rather than discarding it.
38
- *
39
- * Optional, because a capsule written before these existed has neither and must not be read as
40
- * though it were seen once when nobody counted.
41
- */
26
+ steps: z.ZodArray<z.ZodType<FlowStep, unknown, z.core.$ZodTypeInternals<FlowStep, unknown>>>;
42
27
  seen: z.ZodOptional<z.ZodNumber>;
43
28
  lastSeenAt: z.ZodOptional<z.ZodNumber>;
44
- }, "strip", z.ZodTypeAny, {
45
- version: 1;
46
- id: string;
47
- origin: string;
48
- createdAt: number;
49
- expected: string;
50
- steps: FlowStep[];
51
- observed: string;
52
- flow?: string | undefined;
53
- seen?: number | undefined;
54
- lastSeenAt?: number | undefined;
55
- }, {
56
- version: 1;
57
- id: string;
58
- origin: string;
59
- createdAt: number;
60
- expected: string;
61
- steps: FlowStep[];
62
- observed: string;
63
- flow?: string | undefined;
64
- seen?: number | undefined;
65
- lastSeenAt?: number | undefined;
66
- }>;
29
+ }, z.core.$strip>;
67
30
  export type Capsule = z.infer<typeof CapsuleSchema>;
68
31
  /** Capsule ids are filenames — refuse anything that could escape the capsules directory. */
69
32
  export declare function isValidCapsuleId(id: string): boolean;
@@ -13,18 +13,9 @@
13
13
  * Pure: no IO, no clock. The tool layer loads flows + contract and calls this.
14
14
  */
15
15
  import { AnchorKind, PredicateKind, compareSourceClauses, } from '@reticlehq/core';
16
- import { classifyFlowAssertions, FlowAssertionGrade } from '../../language/flows/flow-classify.js';
16
+ import { classifyFlowAssertions, FlowAssertionGrade, flattenSteps as flatten, } from '../../language/flows/flow-classify.js';
17
17
  import { successLabel } from '../../language/flows/flow-success.js';
18
18
  import { flowRisk, latestRun, rankByRisk, RiskLevel } from './flow-risk.js';
19
- function flatten(steps) {
20
- const out = [];
21
- for (const s of steps) {
22
- out.push(s);
23
- if (s.steps !== undefined)
24
- out.push(...flatten(s.steps));
25
- }
26
- return out;
27
- }
28
19
  /*
29
20
  * The vocabulary a flow uses, read out of a predicate TREE.
30
21
  *
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { projectForRoot } from '../../memory/project/project-for-root.js';
3
3
  import { sessionRoot } from '../../memory/project/session-root.js';
4
+ import { flowsForSessionId } from '../../language/flows/flow-store-for-session.js';
4
5
  import { asNumber, asString } from '@reticlehq/core';
5
6
  import { ReticleTool } from '@reticlehq/core';
6
7
  import { countSchema } from '../../surface/tools/args/numeric-bounds.js';
@@ -69,10 +70,11 @@ export const DOMAIN_TOOLS = [
69
70
  .describe('Ready-to-apply instrumentation proposals for gaps that have a source location — { file, line, insert, rationale }. Apply, re-verify, and the app’s observability compounds.'),
70
71
  },
71
72
  handler: async (deps, args) => {
72
- const names = await deps.flows.list();
73
+ const { flows: store, projectId } = flowsForSessionId(deps, asString(args['sessionId']));
74
+ const names = await store.list(projectId);
73
75
  const flows = [];
74
76
  for (const name of names) {
75
- const loaded = await deps.flows.load(name);
77
+ const loaded = await store.load(name, projectId);
76
78
  if (loaded.ok)
77
79
  flows.push(loaded.value);
78
80
  }
@@ -5,8 +5,8 @@
5
5
  * individual run to a deploy. The run is already clock-stamped by buildVerificationRun, so the store
6
6
  * needs no clock.
7
7
  */
8
- import { RunReadError, type ReticleVerificationRun, type RunId, type RunScreenshot } from '@reticlehq/core';
9
- import type { FileSystemPort } from '../../../memory/project/fs/fs-port.js';
8
+ import { RunReadError, type ReticleVerificationRun, type RunFlowResult, type RunId, type RunScreenshot } from '@reticlehq/core';
9
+ import { type FileSystemPort } from '../../../memory/project/fs/fs-port.js';
10
10
  /** Never-throws read result (mirrors ReadProjectResult). */
11
11
  export type ReadRunResult = {
12
12
  ok: true;
@@ -30,21 +30,41 @@ interface RunStoreOptions {
30
30
  */
31
31
  onWrote?: () => void;
32
32
  }
33
+ interface FlowAt {
34
+ result: RunFlowResult;
35
+ createdAt: number;
36
+ id: string;
37
+ }
33
38
  export declare class RunStore {
34
39
  #private;
35
40
  constructor(fs: FileSystemPort, root: string, opts?: RunStoreOptions);
36
- /**
37
- * Write one run artifact. Creates .reticle/runs/ first; byte-stable (fixed indent + trailing newline).
38
- * Guards runId as a safe path segment BEFORE building the path — a runId can originate from a caller
39
- * (an OEM may set it), so an unsafe value must never escape .reticle/runs/ (mirrors the read guard).
40
- */
41
- write(given: ReticleVerificationRun): Promise<void>;
41
+ write(given: ReticleVerificationRun,
42
+ /** The tab the run came from, so a run written outside any call still finds its episode. */
43
+ hint?: {
44
+ sessionId?: string;
45
+ }): Promise<void>;
42
46
  /** Never throws. Invalid id / missing → MISSING; bad JSON or failed schema → MALFORMED. */
43
47
  read(runId: RunId): Promise<ReadRunResult>;
44
48
  /** List run ids on disk (filenames minus.json). Empty when the runs dir is absent. */
45
49
  list(): Promise<RunId[]>;
50
+ /** Every readable run. Retention bounds how many there are. */
51
+ all(): Promise<ReticleVerificationRun[]>;
46
52
  /** The most-recent run by createdAt (undefined when none). Powers reticle_run_export's default. */
47
53
  latest(): Promise<ReticleVerificationRun | undefined>;
54
+ /**
55
+ * The newest recorded result for each flow name, taken across every readable run, with the time
56
+ * and id of the run it came from. A run that carries no flows (a drive or an export) says nothing
57
+ * about any flow, so it can neither supply nor erase a result: judging coverage from `latest()`
58
+ * alone let one such run hide every earlier replay. Equal times break on the run id, so the answer
59
+ * never depends on the order `list()` returns.
60
+ */
61
+ latestPerFlow(): Promise<Map<string, FlowAt>>;
62
+ /**
63
+ * The names `credit` (the gate's passing rule) gives each flow's newest result, each with the time
64
+ * of that result, so a caller can refuse a pass that predates an edit. The rule is passed in, so
65
+ * the run store does not reach into the flow language.
66
+ */
67
+ passingFlowTimes(credit: (flows: readonly RunFlowResult[]) => readonly string[]): Promise<Map<string, number>>;
48
68
  /**
49
69
  * The two most-recent runs by createdAt as `[previous, current]` (oldest-first), or undefined when
50
70
  * fewer than two readable runs exist. Powers reticle_run_export's `format:"diff"` (run-to-run deltas).