@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
@@ -1,4 +1,5 @@
1
1
  import { CALL_SECRETS_ARG, callSecretsArg } from './fields/flow-secret-field.js';
2
+ import { REPLAYABILITY_OUTPUT, SKIP_WRITES_ARG } from './flow-replayable.js';
2
3
  import { flowAuthor } from './flow-author.js';
3
4
  import { FLOW_MUTATE_TOOL } from './flow-mutate-tools.js';
4
5
  import { seedSchema, workerCountSchema } from '../../surface/tools/args/numeric-bounds.js';
@@ -8,9 +9,9 @@ import { emptyFlowRefusal } from './empty-flow.js';
8
9
  import { aliasParam, aliasUsed } from '../../surface/tools/args/alias-args.js';
9
10
  import { stillRecording, stillRecordingMessage } from './flow-result.js';
10
11
  import { resolveAnnotateTarget } from './annotate-notes/annotate-target.js';
11
- import { FlowErrorCode, RecordedSaveError, ReplayStatus, SuiteIsolation, } from '@reticlehq/core';
12
+ import { FlowErrorCode, RecordedSaveError, SuiteIsolation, } from '@reticlehq/core';
12
13
  import { recordSuiteFlakes } from './suite/suite-flakes.js';
13
- import { AppRuntime, ReticleTool } from '@reticlehq/core';
14
+ import { ReticleTool } from '@reticlehq/core';
14
15
  import { asNumber, asString } from '@reticlehq/core';
15
16
  import { log } from '../../log.js';
16
17
  import { cloudFetch, syncFlowToCloud, SyncOutcome } from '../../memory/cloud/cloud-sync.js';
@@ -25,11 +26,11 @@ import { classifyFlowAssertions, flattenSteps } from './flow-classify.js';
25
26
  import { recordingBacktrackWarning } from './recording/recording-backtrack.js';
26
27
  import { isValidFlowName, flowPath } from '../../memory/project/dir/reticle-dir.js';
27
28
  import {} from './flows.js';
28
- import { flowsForSession } from './flow-store-for-session.js';
29
+ import { flowsForSession, flowsForSessionId } from './flow-store-for-session.js';
29
30
  import { rootForTarget, sessionTarget } from '../../memory/project/session-root.js';
30
31
  import { originOf } from '../../portal/session/session-manager.js';
31
32
  import { resolveSuiteSelection } from './suite-selection.js';
32
- import { flowErrorMessage, latestRecordedFlow, sessionProjectId } from './flow-replay-run.js';
33
+ import { flowErrorMessage, latestRecordedFlow } from './flow-replay-run.js';
33
34
  import { persistAndSyncVerificationRun, } from '../../judgement/runs/verification-sync.js';
34
35
  import { runServerVerify } from './suite/server-verify.js';
35
36
  import { healFlow } from './heal-run.js';
@@ -37,6 +38,8 @@ import { RESULT_FIELD, resultField, suiteResult } from '../../surface/tools/reti
37
38
  import { replayOneFlow } from './single-replay.js';
38
39
  export { replayNamedFlow } from './flow-replay-run.js';
39
40
  import { replayAndLearn } from './flow-learning.js';
41
+ import { leasableAppUrl, leaseFailureReplay, sessionUrlOf } from './flow-lease.js';
42
+ export { leasableAppUrl, leaseFailureReplay, sessionUrlOf } from './flow-lease.js';
40
43
  /**
41
44
  * Best-effort mirror of a just-saved flow to Reticle (only when logged in — both cloud env vars
42
45
  * set). Fire-and-forget: resolves the config, POSTs via the platform fetch, and logs the outcome. Any
@@ -48,8 +51,9 @@ async function syncSavedFlowToCloud(deps, flow, target) {
48
51
  // `flowsForSession`, and reading the credential from a different tree is how one project's work
49
52
  // reaches another project's dashboard.
50
53
  const cloud = await resolveProjectCloud(deps.fs, rootForTarget(deps, target), homedir(), process.env);
51
- if (null === cloud.config || !cloud.policy.flows)
52
- return; // not attached / flows disabled → local only
54
+ if (null === cloud.config || !cloud.policy.flows) {
55
+ return;
56
+ } // not attached / flows disabled → local only
53
57
  const result = await syncFlowToCloud(flow, cloud.config, target.projectId, cloudFetch);
54
58
  if (result.outcome !== SyncOutcome.SYNCED) {
55
59
  log('cloud-flow-sync-failed', { flow: flow.name, status: result.status, error: result.error });
@@ -57,57 +61,6 @@ async function syncSavedFlowToCloud(deps, flow, target) {
57
61
  }
58
62
  /** A step index no recorded flow reaches; bounds `to` and `at`. */
59
63
  const MAX_REPLAY_STEP = 10_000;
60
- /**
61
- * The URL a leased context should open: the app's ORIGIN, not the live tab's current location.
62
- *
63
- * The live tab drifts — every replay navigates it — so using its full URL made each lease start wherever
64
- * the previous run happened to finish (observed: leases opening /deployments and failing to find the
65
- * login control that only exists at the root). A lease must be a FRESH visit to a deterministic entry
66
- * point; flows that need another page carry their own startPath.
67
- */
68
- export function leasableAppUrl(deps, sessionId) {
69
- try {
70
- const session = deps.sessions.resolve(sessionId);
71
- if (AppRuntime.WEB !== (session.runtime ?? AppRuntime.WEB))
72
- return undefined; // desktop: no IPC in a lease
73
- const url = session.url;
74
- if (typeof url !== 'string' || 0 === url.length)
75
- return undefined;
76
- return new URL(url).origin;
77
- }
78
- catch {
79
- return undefined; // no live session (or an unparseable URL) → sequential path
80
- }
81
- }
82
- /**
83
- * The live session's own URL — what the fixture port must be looked up by.
84
- *
85
- * NOT `leasableAppUrl`. That returns an ORIGIN, and the input provider finds a page by comparing
86
- * full URLs, so an origin matched no page: `suiteFixtureSeed` answered `undefined` on every run and
87
- * every leased flow booted cold while the code read as if it were seeded. Silent, because every
88
- * refusal on that path is deliberately silent — a fixture is an optimisation, and a suite must not
89
- * die when one is unavailable.
90
- */
91
- export function sessionUrlOf(deps, sessionId) {
92
- try {
93
- return deps.sessions.resolve(sessionId).url;
94
- }
95
- catch {
96
- return undefined;
97
- }
98
- }
99
- /** A flow whose leased context never came up is a suite ERROR, never a silent pass. */
100
- export function leaseFailureReplay(name, error) {
101
- return {
102
- name,
103
- status: ReplayStatus.ERROR,
104
- steps: [],
105
- error: {
106
- code: ReplayStatus.ERROR,
107
- message: `could not run in a leased context: ${error ?? 'unknown error'}`,
108
- },
109
- };
110
- }
111
64
  /** Stand-in path for a flow whose name fails the path-segment guard — never a real join. */
112
65
  const INVALID_FLOW_NAME_PATH = '(invalid flow name — not a usable path)';
113
66
  /**
@@ -121,16 +74,18 @@ const INTENT_GAP_FIELD = z
121
74
  .unknown()
122
75
  .optional()
123
76
  .describe('Present ONLY when the flow was saved with nothing saying what it is for: { kind, missing, cost, fix }. The flow is on disk either way — this never blocks a save. Close it by saving again with `intent`, or by setting the flow file’s `intentId` to an intent already in the ledger. Nothing here is ever derived from the flow name, the steps or the assertions: a guessed goal reads as the author’s own words.');
77
+ /** `flow`: the name reticle_annotate gives the field the flow tools call `flowName`. */
78
+ const FLOW_NAME_ALIAS = z
79
+ .string()
80
+ .optional()
81
+ .describe('Alias for `flowName` (the name reticle_annotate uses).');
124
82
  export const FLOW_TOOLS = [
125
83
  FLOW_MUTATE_TOOL,
126
84
  {
127
85
  name: ReticleTool.FLOW_SAVE,
128
86
  description: 'Persist a STOPPED recording (by name) as a git-checked, anchor-resolved flow at .reticle/flows/<name>.json. A recording that is still running is refused: stop it first with reticle_record{action:"stop"}, and the refusal names the exact call. Each step is bound to a SEMANTIC anchor (testid/role/signal), never a volatile ref; steps without a resolvable testid are kept with degraded:true (a "add a data-testid here" marker) rather than dropped. Returns { name, stepCount, degraded, empty, assertions, warning? } — `assertions.grade` is asserted | presence-only | assertion-free: a flow that only acts (or only checks element presence) will pass even if the feature breaks, so when grade is not "asserted" follow assertions.warning and add a consequence assertion via reticle_annotate (assert-signal / assert-net / success-state). `warning` is present when the recording left a page and returned to it: replay has no navigation steps, so the next click will look for a control on a page the tab is no longer on.',
129
87
  inputSchema: {
130
- flow: z
131
- .string()
132
- .optional()
133
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
88
+ flow: FLOW_NAME_ALIAS,
134
89
  name: z.string().optional().describe('Alias for `flowName`.'),
135
90
  flowName: z
136
91
  .string()
@@ -244,8 +199,9 @@ export const FLOW_TOOLS = [
244
199
  // A zero-step recording is not a flow. Saving it wrote a file the suite reports "unverifiable"
245
200
  // forever while telling the agent it had saved a regression test — see empty-flow.
246
201
  const emptyRefusal = emptyFlowRefusal(program.steps.length, name);
247
- if (emptyRefusal !== undefined)
202
+ if (emptyRefusal !== undefined) {
248
203
  return Promise.resolve(emptyRefusal);
204
+ }
249
205
  const { flows, root } = flowsForSession(deps, target);
250
206
  const author = flowAuthor();
251
207
  const toSave = {
@@ -254,8 +210,9 @@ export const FLOW_TOOLS = [
254
210
  ...(author === undefined ? {} : { author }),
255
211
  };
256
212
  return flows.save(toSave, annotations, projectId).then(async (res) => {
257
- if (!res.ok)
213
+ if (!res.ok) {
258
214
  return { error: flowErrorMessage(res.code, res.detail), code: res.code };
215
+ }
259
216
  deps.annotations.clear(name);
260
217
  // Grade the saved flow's assertions so the agent learns immediately if it just saved a flow
261
218
  // that asserts nothing observable (passes even when the feature is broken).
@@ -327,10 +284,7 @@ export const FLOW_TOOLS = [
327
284
  name: ReticleTool.FLOW_LOAD,
328
285
  description: 'Read + validate a saved flow by flowName from .reticle/flows/<flowName>.json. Returns the FlowFile (version, flowName, createdAt, anchored steps) or a structured { error, code }. Step `expect` (and flow `success`) accepts the same allOf grammar as reticle_act_and_wait; a parse failure names the step and key rather than calling the file malformed.',
329
286
  inputSchema: {
330
- flow: z
331
- .string()
332
- .optional()
333
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
287
+ flow: FLOW_NAME_ALIAS,
334
288
  flowName: z
335
289
  .string()
336
290
  .describe('Flow file name (without .json extension) from reticle_flow{action:"list"}.'),
@@ -340,21 +294,19 @@ export const FLOW_TOOLS = [
340
294
  .describe('Active session ID — resolves the flow within that app’s scope.'),
341
295
  },
342
296
  outputSchema: {
343
- flow: z
344
- .string()
345
- .optional()
346
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
297
+ flow: FLOW_NAME_ALIAS,
347
298
  flowName: z.string(),
348
299
  steps: z.array(z.unknown()),
349
300
  createdAt: z.number().optional(),
350
301
  },
351
302
  handler: (deps, args) => {
352
- const projectId = sessionProjectId(deps, asString(args['sessionId']));
353
- return deps.flows
303
+ const { flows, projectId } = flowsForSessionId(deps, asString(args['sessionId']));
304
+ return flows
354
305
  .load(asString(aliasParam(args, 'flowName', ['flow'])['flowName']) ?? '', projectId)
355
306
  .then((res) => {
356
- if (!res.ok)
307
+ if (!res.ok) {
357
308
  return { error: flowErrorMessage(res.code, res.detail), code: res.code };
309
+ }
358
310
  const { name, ...rest } = res.value;
359
311
  return { flowName: name, ...rest };
360
312
  });
@@ -366,10 +318,7 @@ export const FLOW_TOOLS = [
366
318
  'to the connected app. Returns { deleted: true } or a structured { error, code } (code not_found ' +
367
319
  'when no such flow — deleting an absent flow is an error, not a silent no-op).',
368
320
  inputSchema: {
369
- flow: z
370
- .string()
371
- .optional()
372
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
321
+ flow: FLOW_NAME_ALIAS,
373
322
  flowName: z
374
323
  .string()
375
324
  .describe('Flow file name (without .json extension) from reticle_flow{action:"list"}.'),
@@ -384,12 +333,13 @@ export const FLOW_TOOLS = [
384
333
  code: z.string().optional(),
385
334
  },
386
335
  handler: (deps, args) => {
387
- const projectId = sessionProjectId(deps, asString(args['sessionId']));
388
- return deps.flows
336
+ const { flows, projectId } = flowsForSessionId(deps, asString(args['sessionId']));
337
+ return flows
389
338
  .remove(asString(aliasParam(args, 'flowName', ['flow'])['flowName']) ?? '', projectId)
390
339
  .then((res) => {
391
- if (!res.ok)
340
+ if (!res.ok) {
392
341
  return { error: flowErrorMessage(res.code, res.detail), code: res.code };
342
+ }
393
343
  return { deleted: true };
394
344
  });
395
345
  },
@@ -405,15 +355,14 @@ export const FLOW_TOOLS = [
405
355
  'document) — neither pass nor fail, treat as UNKNOWN. ' +
406
356
  'An ok replay of a flow asserting no consequence also carries unverifiable:{reason} — do not ' +
407
357
  'treat as proof. ' +
408
- 'Early halt carries halted:{atStep, notAttempted}: `steps` is shorter because replay stopped.',
358
+ 'Early halt carries halted:{atStep, notAttempted}: `steps` is shorter because replay stopped. ' +
359
+ 'A start page that kept loading past the step budget carries startPageWait:{waitedMs, budgetMs, stillLoading}.',
409
360
  inputSchema: {
410
- flow: z
411
- .string()
412
- .optional()
413
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
361
+ flow: FLOW_NAME_ALIAS,
414
362
  flowName: z
415
363
  .string()
416
- .describe('Flow file name (without .json extension) from reticle_flow{action:"list"}.'),
364
+ .optional()
365
+ .describe('Flow file name (without .json extension) from reticle_flow{action:"list"}. Required, here or as `flow`.'),
417
366
  [CALL_SECRETS_ARG]: callSecretsArg,
418
367
  confirmDangerous: confirmDangerousArg('this replay'),
419
368
  from: z
@@ -469,6 +418,11 @@ export const FLOW_TOOLS = [
469
418
  .object({ atStep: z.number(), notAttempted: z.number() })
470
419
  .optional()
471
420
  .describe('Set when the replay STOPPED at a failing step: `steps` is shorter than the flow, and this says where it stopped and how many steps were never attempted. Absent means every step ran.'),
421
+ // Declared for the same reason as `halted`: an undeclared field is stripped.
422
+ startPageWait: z
423
+ .object({ waitedMs: z.number(), budgetMs: z.number(), stillLoading: z.boolean() })
424
+ .optional()
425
+ .describe('Set when replay waited past the step budget because the start page was still loading. stillLoading is what the tab said the last time replay asked. Absent means the wait stayed inside the budget.'),
472
426
  // Declared here or a validating profile strips it -- the same way `name` was stripped once.
473
427
  // A field the handler sets and the schema omits arrives as nothing, silently.
474
428
  /*
@@ -510,7 +464,7 @@ export const FLOW_TOOLS = [
510
464
  },
511
465
  // The decision envelope is attached by replayNamedFlow only on drift/fail (clean pass stays
512
466
  // token-flat). Single-flow replay and whole-suite verify share that one implementation.
513
- handler: (deps, args) => replayOneFlow(deps, args, leasableAppUrl(deps, asString(args['sessionId']))),
467
+ handler: (deps, args) => replayOneFlow(deps, aliasParam(args, 'flowName', ['flow']), leasableAppUrl(deps, asString(args['sessionId']))),
514
468
  },
515
469
  {
516
470
  name: ReticleTool.FLOW_VERIFY,
@@ -533,6 +487,7 @@ export const FLOW_TOOLS = [
533
487
  .optional()
534
488
  .describe('Run this many flows at once, each in its own isolated leased browser context (needs the browser pool). Clamped to the pool capacity and the flow count. Omit for the sequential single-tab run.'),
535
489
  confirmDangerous: confirmDangerousArg('this run of the suite'),
490
+ skipWrites: SKIP_WRITES_ARG,
536
491
  sessionId: z
537
492
  .string()
538
493
  .optional()
@@ -583,6 +538,8 @@ export const FLOW_TOOLS = [
583
538
  .array(z.unknown())
584
539
  .optional()
585
540
  .describe('Flows whose prerequisite is not in this run — filtered out by a label, quarantined, or never saved. They did NOT run, because failing them would report the wrong thing.'),
541
+ replayability: REPLAYABILITY_OUTPUT,
542
+ skippedWrites: z.array(z.string()).optional().describe('Flows held back by skipWrites.'),
586
543
  // Session-EXEMPT, so it does not inherit `sessionEnvelopeShape` — declare the one-shot human
587
544
  // feedback ask here or a validating profile strips it off the suite verdict.
588
545
  feedback_prompt: z.unknown().optional(),
@@ -602,12 +559,14 @@ export const FLOW_TOOLS = [
602
559
  ...(0 === selected.unmatched.length ? {} : { unmatched: selected.unmatched }),
603
560
  ...(selected.cycles === undefined ? {} : { cycles: selected.cycles }),
604
561
  ...(selected.unsatisfied === undefined ? {} : { unsatisfied: selected.unsatisfied }),
562
+ ...(selected.writing === undefined ? {} : { skippedWrites: selected.writing }),
605
563
  };
606
564
  // verify:server — hand the whole suite to the hosted runner; it records the verification itself.
607
565
  const cloud = await resolveProjectCloud(deps.fs, rootForTarget(deps, target), homedir(), process.env);
608
566
  const server = await runServerVerify(deps, cloud, sessionId, requested);
609
- if (server !== null)
567
+ if (server !== null) {
610
568
  return server;
569
+ }
611
570
  // PARALLEL: flows race the DOM only when they share ONE tab. Given the lease pool, each
612
571
  // flow gets its own isolated context, so a large suite finishes in interactive time. Opt-in via
613
572
  // `parallel`; a missing prerequisite (no pool, unknown app URL) falls back to the sequential path
@@ -688,12 +647,7 @@ export const FLOW_TOOLS = [
688
647
  const timed = [];
689
648
  // Sequential default: every flow replays against the same live session, so they must not overlap.
690
649
  //
691
- // They also START wherever the previous flow left the app, which makes a verdict depend on RUN
692
- // ORDER — measured, and the cause of a contradiction that moved between flows run by run. A
693
- // reset between flows was BUILT AND REVERTED: see the ledger's 9.2. Playwright's
694
- // `storageState` carries cookies and localStorage and NOT sessionStorage, so a forced reload
695
- // restores part of an app's auth and drops the rest, and the suite went from noisy to FAILING
696
- // (1 of 2 flows). Restoring two thirds of a session is worse than restoring none.
650
+ // Each starts where the last left the app; a reset was built and reverted (see the ledger's 9.2).
697
651
  for (const flowName of requested) {
698
652
  const start = deps.now();
699
653
  const replay = await replayAndLearn(deps, { flowName, sessionId, ...confirmed });
@@ -737,10 +691,7 @@ export const FLOW_TOOLS = [
737
691
  'recorded name. Returns { name, stepCount, degraded, empty } or { error, code } (code ' +
738
692
  'flow_no_recorded when no recording is present).',
739
693
  inputSchema: {
740
- flow: z
741
- .string()
742
- .optional()
743
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
694
+ flow: FLOW_NAME_ALIAS,
744
695
  flowName: z
745
696
  .string()
746
697
  .optional()
@@ -786,15 +737,17 @@ export const FLOW_TOOLS = [
786
737
  // The store stamps the project into the file AND routes it to the per-project subdir (a shared
787
738
  // daemon serves many apps), so location and content agree from one source of truth.
788
739
  const emptyRecorded = emptyFlowRefusal(flow.steps.length, flow.name);
789
- if (emptyRecorded !== undefined)
740
+ if (emptyRecorded !== undefined) {
790
741
  return emptyRecorded;
742
+ }
791
743
  // Resolved like every other path now. This save used to go to the daemon's root while the
792
744
  // recorded-flow save resolved per session, so where a flow landed depended on which tool wrote
793
745
  // it — and the pair that disagreed were the two ways to save the same thing.
794
746
  const target = { projectId: session.projectId, origin: originOf(session.url) };
795
747
  const res = await flowsForSession(deps, target).flows.saveFlow(flow, session.projectId);
796
- if (!res.ok)
748
+ if (!res.ok) {
797
749
  return { error: flowErrorMessage(res.code, res.detail), code: res.code };
750
+ }
798
751
  // If logged in to Reticle, mirror the saved flow to the team's regression suite. Best-effort
799
752
  // and non-blocking: the flow is already on disk, so a sync failure never fails the save.
800
753
  void syncSavedFlowToCloud(deps, flow, target);
@@ -815,12 +768,9 @@ export const FLOW_TOOLS = [
815
768
  'untouched). Returns { name, status: healed|drift|unhealable|consequence_broken|' +
816
769
  'nothing_to_heal|error, applied, proposals[], changed[], message }.',
817
770
  inputSchema: {
818
- flow: z
819
- .string()
820
- .optional()
821
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
771
+ flow: FLOW_NAME_ALIAS,
822
772
  flowName: z.string().describe('Flow file name to heal (from reticle_flow{action:"list"}).'),
823
- apply: z.boolean().optional(),
773
+ apply: z.boolean().optional().describe('Write the rebind. Omit to see the proposal only.'),
824
774
  confirmDangerous: confirmDangerousArg('this heal replay'),
825
775
  sessionId: z
826
776
  .string()
@@ -828,10 +778,7 @@ export const FLOW_TOOLS = [
828
778
  .describe('Active session ID from reticle_sessions. Omit when only one browser session is open.'),
829
779
  },
830
780
  outputSchema: {
831
- flow: z
832
- .string()
833
- .optional()
834
- .describe('Alias for `flowName` (the name reticle_annotate uses).'),
781
+ flow: FLOW_NAME_ALIAS,
835
782
  flowName: z.string(),
836
783
  status: z.string(),
837
784
  applied: z.boolean(),
@@ -859,16 +806,19 @@ async function loadInvoked(flows, flow, projectId) {
859
806
  const seen = new Set([flow.name]);
860
807
  while (queue.length > 0) {
861
808
  const current = queue.shift();
862
- if (current === undefined)
809
+ if (current === undefined) {
863
810
  continue;
811
+ }
864
812
  for (const step of flattenSteps(current.steps)) {
865
813
  const name = step.invoke;
866
- if (name === undefined || seen.has(name))
814
+ if (name === undefined || seen.has(name)) {
867
815
  continue;
816
+ }
868
817
  seen.add(name);
869
818
  const sub = await flows.load(name, projectId);
870
- if (!sub.ok || sub.value === undefined)
819
+ if (!sub.ok || sub.value === undefined) {
871
820
  continue;
821
+ }
872
822
  out.set(name, sub.value);
873
823
  queue.push(sub.value);
874
824
  }
@@ -4,7 +4,8 @@ import { type FlowResult } from './flow-result.js';
4
4
  export type { FlowResult } from './flow-result.js';
5
5
  import type { FlowAnchor, FlowFile, FlowStep, HealChange, InstrumentationGap } from '@reticlehq/core';
6
6
  import type { CompiledProgram, RecordedStep } from './recording/tape/recordings.js';
7
- import type { FileSystemPort } from '../../memory/project/fs/fs-port.js';
7
+ import { type FileSystemPort } from '../../memory/project/fs/fs-port.js';
8
+ import { type Replayability } from './flow-replayable.js';
8
9
  import type { Clock } from '../../machine/clock.js';
9
10
  /** Pick the on-disk anchor for a normalized step: testid > component(auto) > degraded role. */
10
11
  export declare function anchorForStep(args: Record<string, unknown>): {
@@ -49,6 +50,8 @@ interface SaveSummary {
49
50
  * and absent the moment the flow carries prose or an `intentId`. See `flowIntentGap`.
50
51
  */
51
52
  intentGap?: InstrumentationGap;
53
+ /** Absent when the flow replays as it is; else whether it can, and why not, by step. */
54
+ replayability?: Replayability;
52
55
  }
53
56
  /**
54
57
  * The structured annotations folded onto a flow at save time: per-step
@@ -66,11 +69,6 @@ export interface FlowAnnotations {
66
69
  /** Persists anchored flows to .reticle/flows/<name>.json. Filesystem + clock are injected. */
67
70
  export declare class FlowStore {
68
71
  #private;
69
- /**
70
- * `onWrote` is told after a save lands, so cloud sync cycles on a new flow the way it does on a
71
- * new run (`RunStore` takes the same callback). Without it a flow saved with no run behind it
72
- * waited for the timer, and a daemon that exited first never sent it.
73
- */
74
72
  constructor(fs: FileSystemPort, root: string, clock: Clock, opts?: {
75
73
  onWrote?: () => void;
76
74
  });