@reticlehq/server 3.5.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (721) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +123 -116
  3. package/dist/chromium-launch-options.d.ts +3 -1
  4. package/dist/chromium-launch-options.js +2 -1
  5. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  6. package/dist/command/cli/adhoc-suite.js +42 -7
  7. package/dist/command/cli/adhoc-verdict.d.ts +19 -2
  8. package/dist/command/cli/adhoc-verdict.js +76 -9
  9. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  10. package/dist/command/cli/answers/gate-exit.js +45 -0
  11. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  12. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  13. package/dist/command/cli/answers/open-note.d.ts +2 -0
  14. package/dist/command/cli/answers/open-note.js +22 -0
  15. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  16. package/dist/command/cli/auth/device-flow.js +17 -0
  17. package/dist/command/cli/cli-doctor.js +14 -0
  18. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  19. package/dist/command/cli/cli-flow-commands.js +31 -112
  20. package/dist/command/cli/cli-kill.js +3 -2
  21. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  22. package/dist/command/cli/cli-parse-grammar.js +75 -0
  23. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  24. package/dist/command/cli/cli-parse-verify.js +18 -0
  25. package/dist/command/cli/cli-parse.d.ts +19 -28
  26. package/dist/command/cli/cli-parse.js +82 -182
  27. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  28. package/dist/command/cli/cli-update-commands.js +61 -9
  29. package/dist/command/cli/cli-usage.d.ts +33 -0
  30. package/dist/command/cli/cli-usage.js +287 -0
  31. package/dist/command/cli/cli-verify.d.ts +35 -5
  32. package/dist/command/cli/cli-verify.js +114 -35
  33. package/dist/command/cli/cloud-cli.d.ts +13 -0
  34. package/dist/command/cli/cloud-cli.js +192 -341
  35. package/dist/command/cli/cloud-kit.d.ts +12 -0
  36. package/dist/command/cli/cloud-kit.js +41 -2
  37. package/dist/command/cli/cloud-link.d.ts +57 -0
  38. package/dist/command/cli/cloud-link.js +308 -0
  39. package/dist/command/cli/cloud-login.d.ts +22 -0
  40. package/dist/command/cli/cloud-login.js +96 -8
  41. package/dist/command/cli/context-command.d.ts +1 -0
  42. package/dist/command/cli/context-command.js +33 -0
  43. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  44. package/dist/command/cli/daemon-start-options.js +24 -3
  45. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
  46. package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
  47. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  48. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  49. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  50. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  51. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  52. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  53. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  54. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  55. package/dist/command/cli/drive/drive-attach.d.ts +27 -2
  56. package/dist/command/cli/drive/drive-attach.js +71 -4
  57. package/dist/command/cli/drive/drive-command.d.ts +2 -1
  58. package/dist/command/cli/drive/drive-command.js +13 -7
  59. package/dist/command/cli/known-regression.d.ts +13 -0
  60. package/dist/command/cli/known-regression.js +34 -0
  61. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  62. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  63. package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
  64. package/dist/command/cli/mcp-command.d.ts +6 -0
  65. package/dist/command/cli/mcp-command.js +13 -5
  66. package/dist/command/cli/ports/port-holder.d.ts +10 -0
  67. package/dist/command/cli/ports/port-holder.js +25 -1
  68. package/dist/command/cli/project-name.d.ts +29 -1
  69. package/dist/command/cli/project-name.js +107 -2
  70. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  71. package/dist/command/cli/setup-mcp-cli.js +35 -12
  72. package/dist/command/cli/status/status-lines.d.ts +1 -0
  73. package/dist/command/cli/status/status-lines.js +47 -2
  74. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  75. package/dist/command/cli/status/workspace-links.js +29 -0
  76. package/dist/command/cli/try-command.d.ts +96 -0
  77. package/dist/command/cli/try-command.js +362 -0
  78. package/dist/command/cli/tutorial.d.ts +0 -100
  79. package/dist/command/cli/tutorial.js +0 -181
  80. package/dist/command/cli/verify-results.d.ts +19 -0
  81. package/dist/command/cli/verify-results.js +29 -0
  82. package/dist/command/cli-onboarding.d.ts +0 -11
  83. package/dist/command/cli-onboarding.js +0 -15
  84. package/dist/command/cli.d.ts +20 -0
  85. package/dist/command/cli.js +130 -104
  86. package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
  87. package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
  88. package/dist/command/daemon/daemon-resilience.js +4 -4
  89. package/dist/command/daemon/daemon-resolve.d.ts +23 -1
  90. package/dist/command/daemon/daemon-resolve.js +79 -9
  91. package/dist/command/setup/agent-writer.d.ts +1 -1
  92. package/dist/command/setup/agent-writer.js +3 -2
  93. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  94. package/dist/command/setup/bringup/bridge-port.js +13 -3
  95. package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
  96. package/dist/command/setup/bringup/connect-lease.js +1 -0
  97. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  98. package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
  99. package/dist/command/setup/bringup/dev-server-wait.js +19 -0
  100. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  101. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  102. package/dist/command/setup/init/agent-restart.js +28 -0
  103. package/dist/command/setup/init/init-port.d.ts +14 -1
  104. package/dist/command/setup/init/init-port.js +32 -2
  105. package/dist/command/setup/init/init-runtime.d.ts +22 -2
  106. package/dist/command/setup/init/init-runtime.js +114 -38
  107. package/dist/command/setup/node-effects.d.ts +2 -0
  108. package/dist/command/setup/node-effects.js +38 -9
  109. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  110. package/dist/command/setup/probe/existing-app.js +14 -0
  111. package/dist/command/setup/remaining-steps.js +2 -1
  112. package/dist/command/setup/run-setup.d.ts +34 -9
  113. package/dist/command/setup/run-setup.js +65 -51
  114. package/dist/command/setup/setup-command.d.ts +25 -1
  115. package/dist/command/setup/setup-command.js +59 -4
  116. package/dist/command/setup/setup-mcp.js +25 -2
  117. package/dist/command/setup/tauri-signing.d.ts +19 -0
  118. package/dist/command/setup/tauri-signing.js +79 -0
  119. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  120. package/dist/command/setup/terminal/listeners.js +37 -6
  121. package/dist/command/update/update-nudge.d.ts +9 -0
  122. package/dist/command/update/update-nudge.js +1 -1
  123. package/dist/command/update/updater.js +11 -15
  124. package/dist/command/version/version-nudge.js +3 -0
  125. package/dist/command/version/version-skew.d.ts +20 -1
  126. package/dist/command/version/version-skew.js +49 -4
  127. package/dist/features/crawl/crawl-tools.js +4 -0
  128. package/dist/features/crawl/crawl.d.ts +6 -0
  129. package/dist/features/crawl/crawl.js +23 -2
  130. package/dist/features/exhaust/ledger.d.ts +21 -14
  131. package/dist/features/exhaust/ledger.js +35 -9
  132. package/dist/features/harness/app-findings.d.ts +2 -0
  133. package/dist/features/harness/app-findings.js +52 -0
  134. package/dist/features/harness/drive-report.d.ts +61 -1
  135. package/dist/features/harness/drive-report.js +394 -26
  136. package/dist/features/harness/drive-runs.d.ts +120 -0
  137. package/dist/features/harness/drive-runs.js +289 -0
  138. package/dist/features/harness/drivers.d.ts +10 -14
  139. package/dist/features/harness/drivers.js +10 -14
  140. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  141. package/dist/features/harness/explore/console-pages.js +146 -0
  142. package/dist/features/harness/explore/disparity.d.ts +19 -0
  143. package/dist/features/harness/explore/disparity.js +71 -0
  144. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  145. package/dist/features/harness/explore/fake-app.js +49 -0
  146. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  147. package/dist/features/harness/explore/goal-search.js +144 -0
  148. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  149. package/dist/features/harness/explore/page-tree.js +148 -0
  150. package/dist/features/harness/explore/site-map.d.ts +34 -0
  151. package/dist/features/harness/explore/site-map.js +150 -0
  152. package/dist/features/harness/fill-values.d.ts +3 -73
  153. package/dist/features/harness/fill-values.js +3 -169
  154. package/dist/features/harness/goals.d.ts +82 -0
  155. package/dist/features/harness/goals.js +330 -0
  156. package/dist/features/harness/harness.d.ts +51 -1
  157. package/dist/features/harness/harness.js +207 -6
  158. package/dist/features/harness/platform/drive-target.d.ts +30 -0
  159. package/dist/features/harness/platform/drive-target.js +81 -0
  160. package/dist/features/harness/platform/local-apps.d.ts +127 -0
  161. package/dist/features/harness/platform/local-apps.js +280 -0
  162. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  163. package/dist/features/harness/platform/persona-credentials.js +69 -0
  164. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  165. package/dist/features/harness/platform/platform-drives.js +114 -0
  166. package/dist/features/harness/platform/refusal.d.ts +52 -0
  167. package/dist/features/harness/platform/refusal.js +71 -0
  168. package/dist/features/harness/platform/remote-drive.d.ts +186 -0
  169. package/dist/features/harness/platform/remote-drive.js +378 -0
  170. package/dist/features/harness/platform/script.d.ts +94 -0
  171. package/dist/features/harness/platform/script.js +260 -0
  172. package/dist/features/harness/platform/server-driver.d.ts +54 -0
  173. package/dist/features/harness/platform/server-driver.js +182 -0
  174. package/dist/features/harness/platform-config.d.ts +41 -1
  175. package/dist/features/harness/platform-config.js +106 -9
  176. package/dist/features/harness/route-guess.d.ts +13 -0
  177. package/dist/features/harness/route-guess.js +49 -0
  178. package/dist/features/harness/script/app-controls.d.ts +5 -0
  179. package/dist/features/harness/script/app-controls.js +40 -0
  180. package/dist/features/harness/script/lane-ids.d.ts +14 -0
  181. package/dist/features/harness/script/lane-ids.js +16 -0
  182. package/dist/features/harness/script/script-run.d.ts +70 -0
  183. package/dist/features/harness/script/script-run.js +606 -0
  184. package/dist/features/license/license.d.ts +2 -2
  185. package/dist/features/visual/step-shots.d.ts +31 -0
  186. package/dist/features/visual/step-shots.js +231 -0
  187. package/dist/features/visual/visual-tools.d.ts +10 -1
  188. package/dist/features/visual/visual-tools.js +62 -17
  189. package/dist/hooks/client-directory.d.ts +18 -0
  190. package/dist/hooks/client-directory.js +57 -0
  191. package/dist/hooks/coding-agents.d.ts +34 -0
  192. package/dist/hooks/coding-agents.js +117 -0
  193. package/dist/hooks/driven-by.d.ts +23 -0
  194. package/dist/hooks/driven-by.js +56 -0
  195. package/dist/hooks/hook-bus.d.ts +4 -0
  196. package/dist/hooks/hook-bus.js +18 -0
  197. package/dist/hooks/hook-commands.js +15 -4
  198. package/dist/hooks/tool-log.d.ts +9 -0
  199. package/dist/hooks/tool-log.js +29 -0
  200. package/dist/index.d.ts +2 -0
  201. package/dist/index.js +80 -243
  202. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  203. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  204. package/dist/judgement/capsule/causal-summary.js +33 -0
  205. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  206. package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
  207. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  208. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  209. package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
  210. package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
  211. package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
  212. package/dist/judgement/runs/artifact/run-store.js +195 -3
  213. package/dist/judgement/runs/context-tools.js +59 -1
  214. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  215. package/dist/judgement/runs/default-run-id.js +16 -0
  216. package/dist/judgement/runs/drive-run.d.ts +71 -1
  217. package/dist/judgement/runs/drive-run.js +317 -5
  218. package/dist/judgement/runs/repair-prompt.js +1 -1
  219. package/dist/judgement/runs/resume.d.ts +44 -0
  220. package/dist/judgement/runs/resume.js +137 -0
  221. package/dist/judgement/runs/reticle-runner.js +13 -3
  222. package/dist/judgement/runs/runner-port.d.ts +5 -1
  223. package/dist/judgement/runs/runner-port.js +8 -2
  224. package/dist/judgement/runs/verification-sync.d.ts +5 -2
  225. package/dist/judgement/runs/verification-sync.js +40 -18
  226. package/dist/language/flows/change/gate.d.ts +10 -0
  227. package/dist/language/flows/change/gate.js +22 -0
  228. package/dist/language/flows/decision.js +36 -1
  229. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  230. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  231. package/dist/language/flows/flow-anchor.d.ts +61 -10
  232. package/dist/language/flows/flow-anchor.js +98 -6
  233. package/dist/language/flows/flow-cross-step.d.ts +15 -0
  234. package/dist/language/flows/flow-cross-step.js +21 -0
  235. package/dist/language/flows/flow-intent.d.ts +1 -0
  236. package/dist/language/flows/flow-journey.d.ts +6 -0
  237. package/dist/language/flows/flow-journey.js +20 -0
  238. package/dist/language/flows/flow-learning.d.ts +4 -0
  239. package/dist/language/flows/flow-learning.js +45 -14
  240. package/dist/language/flows/flow-mutate-tools.js +5 -3
  241. package/dist/language/flows/flow-replay-run.d.ts +23 -9
  242. package/dist/language/flows/flow-replay-run.js +115 -110
  243. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  244. package/dist/language/flows/flow-replay.d.ts +40 -1
  245. package/dist/language/flows/flow-replay.js +110 -22
  246. package/dist/language/flows/flow-result.d.ts +22 -1
  247. package/dist/language/flows/flow-result.js +47 -2
  248. package/dist/language/flows/flow-scope.js +5 -1
  249. package/dist/language/flows/flow-step-runners.d.ts +22 -2
  250. package/dist/language/flows/flow-step-runners.js +247 -47
  251. package/dist/language/flows/flow-store-for-session.d.ts +2 -2
  252. package/dist/language/flows/flow-store-for-session.js +7 -3
  253. package/dist/language/flows/flow-tools.d.ts +10 -0
  254. package/dist/language/flows/flow-tools.js +112 -89
  255. package/dist/language/flows/flows.d.ts +16 -1
  256. package/dist/language/flows/flows.js +74 -12
  257. package/dist/language/flows/heal-run.js +6 -4
  258. package/dist/language/flows/narrow-write.d.ts +7 -0
  259. package/dist/language/flows/narrow-write.js +36 -1
  260. package/dist/language/flows/recording/flake.d.ts +2 -2
  261. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  262. package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
  263. package/dist/language/flows/recording/tape/recordings.js +95 -13
  264. package/dist/language/flows/replay-from-hud.d.ts +20 -0
  265. package/dist/language/flows/replay-from-hud.js +51 -0
  266. package/dist/language/flows/replay.d.ts +9 -5
  267. package/dist/language/flows/replay.js +56 -15
  268. package/dist/language/flows/single-replay.d.ts +7 -0
  269. package/dist/language/flows/single-replay.js +26 -0
  270. package/dist/language/flows/suite/suite-flakes.js +2 -0
  271. package/dist/language/flows/suite-selection.d.ts +2 -15
  272. package/dist/language/flows/suite-selection.js +4 -3
  273. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  274. package/dist/language/flows/verify-change-tools.js +202 -191
  275. package/dist/launch-chromium.d.ts +27 -5
  276. package/dist/launch-chromium.js +38 -8
  277. package/dist/memory/cloud/cloud-config.d.ts +22 -1
  278. package/dist/memory/cloud/cloud-config.js +34 -5
  279. package/dist/memory/cloud/cloud-sync.d.ts +17 -14
  280. package/dist/memory/cloud/cloud-sync.js +15 -4
  281. package/dist/memory/cloud/harness-config.d.ts +75 -1
  282. package/dist/memory/cloud/harness-config.js +115 -24
  283. package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
  284. package/dist/memory/cloud/hud-notices-source.js +128 -0
  285. package/dist/memory/cloud/memory-scope.d.ts +161 -0
  286. package/dist/memory/cloud/memory-scope.js +227 -0
  287. package/dist/memory/cloud/sync-cycle.d.ts +44 -7
  288. package/dist/memory/cloud/sync-cycle.js +129 -15
  289. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  290. package/dist/memory/cloud/sync-daemon.js +121 -9
  291. package/dist/memory/cloud/sync-disk.d.ts +1 -1
  292. package/dist/memory/cloud/sync-disk.js +31 -10
  293. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  294. package/dist/memory/cloud/sync-screenshots.js +105 -0
  295. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  296. package/dist/memory/cloud/unsynced-roots.js +166 -0
  297. package/dist/memory/impact/account-watch.d.ts +34 -0
  298. package/dist/memory/impact/account-watch.js +59 -0
  299. package/dist/memory/impact/impact-recorder.d.ts +8 -0
  300. package/dist/memory/impact/impact-recorder.js +12 -2
  301. package/dist/memory/impact/impact-store.d.ts +17 -4
  302. package/dist/memory/impact/impact-store.js +169 -63
  303. package/dist/memory/intent/inline-intent.d.ts +1 -0
  304. package/dist/memory/intent/intent-shard-store.js +16 -4
  305. package/dist/memory/intent/intent-shard.d.ts +14 -2
  306. package/dist/memory/intent/intent-store.d.ts +1 -0
  307. package/dist/memory/intent/intent-tools.js +122 -4
  308. package/dist/memory/intent/open-intents.d.ts +6 -0
  309. package/dist/memory/intent/open-intents.js +10 -1
  310. package/dist/memory/intent/settled-words.d.ts +24 -0
  311. package/dist/memory/intent/settled-words.js +130 -0
  312. package/dist/memory/journal/drive-flow.d.ts +16 -0
  313. package/dist/memory/journal/drive-flow.js +34 -2
  314. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  315. package/dist/memory/journal/drive-run-flush.js +20 -5
  316. package/dist/memory/journal/envelope.d.ts +8 -8
  317. package/dist/memory/journal/journal-recorder.js +52 -3
  318. package/dist/memory/journal/on-disk/retention.d.ts +8 -0
  319. package/dist/memory/journal/on-disk/retention.js +32 -2
  320. package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
  321. package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
  322. package/dist/memory/journal/session-end.d.ts +15 -1
  323. package/dist/memory/journal/session-end.js +42 -9
  324. package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
  325. package/dist/memory/project/artifact-root-resolver.js +125 -16
  326. package/dist/memory/project/artifact-root.d.ts +46 -8
  327. package/dist/memory/project/artifact-root.js +89 -10
  328. package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
  329. package/dist/memory/project/dir/reticle-dir.js +26 -3
  330. package/dist/memory/project/link-directory.d.ts +15 -0
  331. package/dist/memory/project/link-directory.js +44 -0
  332. package/dist/memory/project/project-tools.js +22 -3
  333. package/dist/memory/project/root-claims.d.ts +6 -0
  334. package/dist/memory/project/root-claims.js +39 -0
  335. package/dist/memory/project/session-root.d.ts +26 -1
  336. package/dist/memory/project/session-root.js +49 -5
  337. package/dist/memory/project/sync-status.d.ts +85 -0
  338. package/dist/memory/project/sync-status.js +224 -0
  339. package/dist/memory/recall/memory-tools.js +47 -2
  340. package/dist/memory/recall/platform-memory.d.ts +34 -0
  341. package/dist/memory/recall/platform-memory.js +139 -0
  342. package/dist/memory/recall/project-memory.d.ts +19 -0
  343. package/dist/memory/recall/project-memory.js +80 -13
  344. package/dist/portal/bridge/bridge.d.ts +9 -3
  345. package/dist/portal/bridge/bridge.js +82 -22
  346. package/dist/portal/bridge/harness-request.d.ts +23 -0
  347. package/dist/portal/bridge/harness-request.js +27 -0
  348. package/dist/portal/bridge/pairing-token.d.ts +9 -0
  349. package/dist/portal/bridge/pairing-token.js +17 -0
  350. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  351. package/dist/portal/bridge/wrong-path.js +35 -0
  352. package/dist/portal/input/network-mock-tools.js +11 -2
  353. package/dist/portal/input/real-input.d.ts +83 -10
  354. package/dist/portal/input/real-input.js +218 -30
  355. package/dist/portal/input/viewport-tools.js +3 -3
  356. package/dist/portal/pool/browser-pool.d.ts +70 -9
  357. package/dist/portal/pool/browser-pool.js +190 -37
  358. package/dist/portal/pool/context-permissions.d.ts +33 -0
  359. package/dist/portal/pool/context-permissions.js +33 -0
  360. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  361. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  362. package/dist/portal/pool/playwright-launcher.d.ts +35 -0
  363. package/dist/portal/pool/playwright-launcher.js +64 -3
  364. package/dist/portal/pool/pool-contract.d.ts +28 -5
  365. package/dist/portal/session/agent-link.d.ts +8 -0
  366. package/dist/portal/session/agent-link.js +17 -0
  367. package/dist/portal/session/command-payload.d.ts +8 -0
  368. package/dist/portal/session/command-payload.js +24 -0
  369. package/dist/portal/session/daemon-answers.d.ts +3 -3
  370. package/dist/portal/session/daemon-answers.js +4 -2
  371. package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
  372. package/dist/portal/session/dev-server/dev-command.js +87 -12
  373. package/dist/portal/session/facts/departure-note.d.ts +22 -0
  374. package/dist/portal/session/facts/departure-note.js +47 -0
  375. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  376. package/dist/portal/session/facts/observed-state.js +46 -3
  377. package/dist/portal/session/facts/session-replaced.d.ts +5 -0
  378. package/dist/portal/session/facts/session-replaced.js +5 -0
  379. package/dist/portal/session/first-run-wiring.d.ts +42 -0
  380. package/dist/portal/session/first-run-wiring.js +132 -0
  381. package/dist/portal/session/human/live-control.d.ts +9 -2
  382. package/dist/portal/session/human/live-control.js +12 -3
  383. package/dist/portal/session/human/notes-ledger.d.ts +20 -0
  384. package/dist/portal/session/human/notes-ledger.js +55 -0
  385. package/dist/portal/session/human/review-store.d.ts +12 -0
  386. package/dist/portal/session/human/review-store.js +18 -10
  387. package/dist/portal/session/live-control-tools.d.ts +0 -13
  388. package/dist/portal/session/live-control-tools.js +107 -13
  389. package/dist/portal/session/narration-args.d.ts +5 -0
  390. package/dist/portal/session/narration-args.js +17 -0
  391. package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
  392. package/dist/portal/session/no-session-diagnosis.js +46 -9
  393. package/dist/portal/session/no-session-next-action.d.ts +31 -0
  394. package/dist/portal/session/no-session-next-action.js +159 -60
  395. package/dist/portal/session/no-session-watch.d.ts +14 -1
  396. package/dist/portal/session/no-session-watch.js +227 -17
  397. package/dist/portal/session/presence/session-lease.js +1 -1
  398. package/dist/portal/session/presence/session-mirror.js +3 -0
  399. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  400. package/dist/portal/session/recorded-gaps.js +251 -0
  401. package/dist/portal/session/serving-directory.d.ts +27 -0
  402. package/dist/portal/session/serving-directory.js +45 -0
  403. package/dist/portal/session/session-health.d.ts +18 -0
  404. package/dist/portal/session/session-health.js +9 -1
  405. package/dist/portal/session/session-info.d.ts +8 -1
  406. package/dist/portal/session/session-info.js +8 -1
  407. package/dist/portal/session/session-manager.d.ts +39 -0
  408. package/dist/portal/session/session-manager.js +98 -11
  409. package/dist/portal/session/session-reaper.js +4 -1
  410. package/dist/portal/session/session-successor.d.ts +13 -0
  411. package/dist/portal/session/session-successor.js +1 -1
  412. package/dist/portal/session/session-tools.js +26 -3
  413. package/dist/portal/session/session.d.ts +22 -30
  414. package/dist/portal/session/session.js +81 -79
  415. package/dist/portal/session/timing/command-timeout.js +25 -1
  416. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  417. package/dist/portal/session/timing/wall-clock.js +1 -1
  418. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  419. package/dist/portal/session/zero-install-first-call.js +88 -0
  420. package/dist/start-options.d.ts +12 -0
  421. package/dist/start-wiring.d.ts +63 -0
  422. package/dist/start-wiring.js +169 -0
  423. package/dist/status-payload.d.ts +23 -1
  424. package/dist/status-payload.js +36 -1
  425. package/dist/surface/http-server.js +18 -2
  426. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  427. package/dist/surface/mcp/attach-memory.js +12 -1
  428. package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
  429. package/dist/surface/mcp/mcp-proxy.js +65 -13
  430. package/dist/surface/mcp/mcp.d.ts +34 -6
  431. package/dist/surface/mcp/mcp.js +61 -17
  432. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  433. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  434. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  435. package/dist/surface/mcp/server-instructions.d.ts +4 -2
  436. package/dist/surface/mcp/server-instructions.js +32 -14
  437. package/dist/surface/mcp/shared-params.js +2 -2
  438. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  439. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  440. package/dist/surface/tools/account-tool.d.ts +22 -0
  441. package/dist/surface/tools/account-tool.js +157 -0
  442. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  443. package/dist/surface/tools/act/act-danger.js +38 -1
  444. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  445. package/dist/surface/tools/act/act-observation.js +57 -0
  446. package/dist/surface/tools/act/act-preflight.js +25 -2
  447. package/dist/surface/tools/act/act-target.js +8 -3
  448. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
  449. package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
  450. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  451. package/dist/surface/tools/act/resolve-target.js +18 -3
  452. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  453. package/dist/surface/tools/act/screen-request.js +113 -0
  454. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  455. package/dist/surface/tools/act/sequence-grade.js +13 -2
  456. package/dist/surface/tools/act/settle-in-flight.js +25 -3
  457. package/dist/surface/tools/act-sequence-tool.js +138 -29
  458. package/dist/surface/tools/act-tools.d.ts +0 -9
  459. package/dist/surface/tools/act-tools.js +71 -41
  460. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  461. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  462. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  463. package/dist/surface/tools/agent/app-notes.js +48 -0
  464. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  465. package/dist/surface/tools/agent/build-staleness.js +62 -0
  466. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  467. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  468. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  469. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  470. package/dist/surface/tools/agent/notices.d.ts +50 -0
  471. package/dist/surface/tools/agent/notices.js +152 -0
  472. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  473. package/dist/surface/tools/agent/reteach.js +50 -0
  474. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  475. package/dist/surface/tools/args/alias-args.js +10 -0
  476. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  477. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  478. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  479. package/dist/surface/tools/assert/assert-source.js +40 -0
  480. package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
  481. package/dist/surface/tools/assert/assert-verdict.js +42 -17
  482. package/dist/surface/tools/browser-tools.js +51 -2
  483. package/dist/surface/tools/chat-drives.d.ts +101 -0
  484. package/dist/surface/tools/chat-drives.js +409 -0
  485. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  486. package/dist/surface/tools/coverage-tools.js +2 -53
  487. package/dist/surface/tools/dynamic-tools.js +29 -1
  488. package/dist/surface/tools/empty-session-list.d.ts +51 -0
  489. package/dist/surface/tools/empty-session-list.js +120 -0
  490. package/dist/surface/tools/error-recovery.d.ts +14 -0
  491. package/dist/surface/tools/error-recovery.js +105 -8
  492. package/dist/surface/tools/explore-tools.d.ts +31 -1
  493. package/dist/surface/tools/explore-tools.js +438 -66
  494. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  495. package/dist/surface/tools/feedback-tools.js +18 -3
  496. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  497. package/dist/surface/tools/gap-novelty.js +8 -1
  498. package/dist/surface/tools/harness-explore.d.ts +118 -57
  499. package/dist/surface/tools/harness-explore.js +344 -292
  500. package/dist/surface/tools/harness-gate.d.ts +88 -0
  501. package/dist/surface/tools/harness-gate.js +235 -0
  502. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  503. package/dist/surface/tools/harness-hunt.js +215 -0
  504. package/dist/surface/tools/harness-plan.d.ts +17 -0
  505. package/dist/surface/tools/harness-plan.js +38 -0
  506. package/dist/surface/tools/harness-script.d.ts +30 -0
  507. package/dist/surface/tools/harness-script.js +560 -0
  508. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  509. package/dist/surface/tools/harness-tab-guard.js +27 -0
  510. package/dist/surface/tools/harness-toolset.d.ts +22 -1
  511. package/dist/surface/tools/harness-toolset.js +101 -7
  512. package/dist/surface/tools/human-notes.d.ts +16 -0
  513. package/dist/surface/tools/human-notes.js +27 -0
  514. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  515. package/dist/surface/tools/invoke-tool.js +263 -85
  516. package/dist/surface/tools/lease-hint.js +26 -5
  517. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  518. package/dist/surface/tools/lease-permissions.js +73 -0
  519. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  520. package/dist/surface/tools/lease-readiness.js +57 -0
  521. package/dist/surface/tools/lease-seed.d.ts +49 -0
  522. package/dist/surface/tools/lease-seed.js +167 -0
  523. package/dist/surface/tools/lease-tools.d.ts +13 -24
  524. package/dist/surface/tools/lease-tools.js +146 -197
  525. package/dist/surface/tools/live-call-text.js +4 -4
  526. package/dist/surface/tools/merge-tools.js +42 -2
  527. package/dist/surface/tools/merged-name-redirect.js +4 -0
  528. package/dist/surface/tools/next-step.d.ts +29 -0
  529. package/dist/surface/tools/next-step.js +214 -0
  530. package/dist/surface/tools/observe-tools.js +45 -9
  531. package/dist/surface/tools/platform-moment.d.ts +72 -0
  532. package/dist/surface/tools/platform-moment.js +296 -0
  533. package/dist/surface/tools/query-hint-schema.d.ts +7 -0
  534. package/dist/surface/tools/query-hint-schema.js +10 -0
  535. package/dist/surface/tools/read-tools.js +71 -14
  536. package/dist/surface/tools/real-input-attempt.js +96 -13
  537. package/dist/surface/tools/reticle-result.d.ts +120 -0
  538. package/dist/surface/tools/reticle-result.js +364 -0
  539. package/dist/surface/tools/tool-kit.d.ts +83 -3
  540. package/dist/surface/tools/tool-kit.js +77 -7
  541. package/dist/surface/tools/tools.js +43 -59
  542. package/dist/telemetry/account-envelope.d.ts +7 -0
  543. package/dist/telemetry/account-envelope.js +61 -0
  544. package/dist/telemetry/agent-client.d.ts +15 -0
  545. package/dist/telemetry/agent-client.js +57 -0
  546. package/dist/telemetry/app-instrumented.js +9 -2
  547. package/dist/telemetry/argument-shape.d.ts +7 -0
  548. package/dist/telemetry/argument-shape.js +86 -1
  549. package/dist/telemetry/automation-hint.d.ts +2 -3
  550. package/dist/telemetry/automation-hint.js +33 -8
  551. package/dist/telemetry/cli-telemetry.js +7 -2
  552. package/dist/telemetry/daemon-telemetry.js +3 -0
  553. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  554. package/dist/telemetry/error-fingerprint.js +61 -5
  555. package/dist/telemetry/feedback-cli.d.ts +0 -13
  556. package/dist/telemetry/feedback-cli.js +0 -77
  557. package/dist/telemetry/feedback.d.ts +13 -0
  558. package/dist/telemetry/feedback.js +183 -17
  559. package/dist/telemetry/harness-run.d.ts +18 -0
  560. package/dist/telemetry/harness-run.js +80 -0
  561. package/dist/telemetry/hud-events.d.ts +16 -0
  562. package/dist/telemetry/hud-events.js +27 -0
  563. package/dist/telemetry/hud-metrics.d.ts +29 -6
  564. package/dist/telemetry/hud-metrics.js +116 -25
  565. package/dist/telemetry/init-telemetry.js +2 -2
  566. package/dist/telemetry/install-source.d.ts +13 -25
  567. package/dist/telemetry/install-source.js +44 -3
  568. package/dist/telemetry/mcp-connection.d.ts +0 -14
  569. package/dist/telemetry/mcp-connection.js +5 -1
  570. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  571. package/dist/telemetry/onboarding-firsts.js +81 -6
  572. package/dist/telemetry/platform-linked.d.ts +5 -0
  573. package/dist/telemetry/platform-linked.js +32 -0
  574. package/dist/telemetry/project-profile.js +5 -3
  575. package/dist/telemetry/proxy-telemetry.js +4 -1
  576. package/dist/telemetry/session-metrics.d.ts +15 -4
  577. package/dist/telemetry/session-metrics.js +88 -52
  578. package/dist/telemetry/telemetry.d.ts +38 -2
  579. package/dist/telemetry/telemetry.js +144 -34
  580. package/dist/telemetry/verification-of.d.ts +3 -1
  581. package/dist/telemetry/verification-of.js +13 -4
  582. package/dist/wire-journal.d.ts +2 -2
  583. package/dist/wire-journal.js +20 -6
  584. package/docs/README.md +3 -3
  585. package/docs/actions.mdx +6 -3
  586. package/docs/adapters.md +1 -1
  587. package/docs/agent-cheatsheet.md +25 -28
  588. package/docs/architecture.md +5 -5
  589. package/docs/autodrive.md +33 -28
  590. package/docs/benchmarks.md +5 -5
  591. package/docs/best-practices.mdx +27 -9
  592. package/docs/capabilities.mdx +14 -16
  593. package/docs/cli/affected.mdx +1 -1
  594. package/docs/cli/cloud.mdx +54 -75
  595. package/docs/cli/doctor.mdx +14 -3
  596. package/docs/cli/drive.mdx +20 -14
  597. package/docs/cli/feedback.mdx +3 -3
  598. package/docs/cli/gate.mdx +7 -2
  599. package/docs/cli/help.mdx +50 -55
  600. package/docs/cli/init.mdx +43 -28
  601. package/docs/cli/license.mdx +12 -8
  602. package/docs/cli/mcp.mdx +4 -4
  603. package/docs/cli/open.mdx +3 -3
  604. package/docs/cli/report.mdx +4 -2
  605. package/docs/cli/restart.mdx +2 -2
  606. package/docs/cli/rollback.mdx +14 -8
  607. package/docs/cli/serve.mdx +4 -4
  608. package/docs/cli/setup.mdx +23 -0
  609. package/docs/cli/status.mdx +18 -5
  610. package/docs/cli/stop.mdx +67 -8
  611. package/docs/cli/try.mdx +62 -0
  612. package/docs/cli/update.mdx +4 -3
  613. package/docs/cli/verify.mdx +17 -6
  614. package/docs/cli/version.mdx +5 -4
  615. package/docs/cli.mdx +111 -42
  616. package/docs/debugging.md +3 -3
  617. package/docs/deploy-checks.md +1 -1
  618. package/docs/desktop.mdx +9 -3
  619. package/docs/enterprise.md +11 -10
  620. package/docs/environment.mdx +7 -8
  621. package/docs/faq.mdx +3 -3
  622. package/docs/first-drive.md +5 -4
  623. package/docs/flows.md +35 -27
  624. package/docs/for-agents.md +4 -5
  625. package/docs/frameworks.mdx +32 -21
  626. package/docs/getting-started.md +65 -61
  627. package/docs/human-control.md +16 -16
  628. package/docs/index.mdx +15 -42
  629. package/docs/install-agentic.mdx +22 -37
  630. package/docs/install-manual.mdx +23 -13
  631. package/docs/instrumentation.mdx +5 -3
  632. package/docs/integration-patterns.md +7 -7
  633. package/docs/license-activation.mdx +1 -1
  634. package/docs/multi-agent-testing.md +24 -6
  635. package/docs/packages/babel-plugin.mdx +4 -2
  636. package/docs/packages/browser.mdx +16 -10
  637. package/docs/packages/core.mdx +12 -5
  638. package/docs/packages/electron.mdx +3 -2
  639. package/docs/packages/engine.mdx +1 -1
  640. package/docs/packages/eslint-plugin.mdx +18 -12
  641. package/docs/packages/next.mdx +8 -7
  642. package/docs/packages/open-verification.mdx +1 -1
  643. package/docs/packages/server.mdx +5 -5
  644. package/docs/packages/tauri.mdx +9 -9
  645. package/docs/packages/test.mdx +4 -10
  646. package/docs/packages/vite-plugin.mdx +32 -4
  647. package/docs/packages.mdx +11 -15
  648. package/docs/platform-integration.md +6 -5
  649. package/docs/predicates.mdx +40 -24
  650. package/docs/quickstart.mdx +69 -30
  651. package/docs/required-checks.md +8 -7
  652. package/docs/reticle-manual.md +15 -5
  653. package/docs/skill-file.mdx +17 -79
  654. package/docs/skill-setup.md +9 -9
  655. package/docs/skill.md +200 -0
  656. package/docs/system-map.md +7 -7
  657. package/docs/telemetry.md +23 -25
  658. package/docs/testing.md +4 -4
  659. package/docs/token-efficiency.md +12 -12
  660. package/docs/tools/act-and-wait.mdx +9 -2
  661. package/docs/tools/act-sequence.mdx +6 -7
  662. package/docs/tools/act.mdx +2 -2
  663. package/docs/tools/assert.mdx +18 -17
  664. package/docs/tools/console.mdx +9 -9
  665. package/docs/tools/inspect.mdx +16 -7
  666. package/docs/tools/look.mdx +24 -0
  667. package/docs/tools/navigate.mdx +5 -3
  668. package/docs/tools/network.mdx +2 -2
  669. package/docs/tools/observe.mdx +6 -6
  670. package/docs/tools/overview.mdx +34 -33
  671. package/docs/tools/query.mdx +5 -5
  672. package/docs/tools/session-and-feedback.mdx +22 -13
  673. package/docs/tools/sessions.mdx +8 -8
  674. package/docs/tools/snapshot.mdx +6 -5
  675. package/docs/tools/state.mdx +9 -9
  676. package/docs/tools/tools-and-run.mdx +26 -24
  677. package/docs/tools/verify.mdx +28 -0
  678. package/docs/tools/wait-for.mdx +8 -4
  679. package/docs/troubleshooting.mdx +21 -6
  680. package/docs/usage.md +55 -46
  681. package/docs/use-cases.mdx +3 -3
  682. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  683. package/docs/vs-playwright-mcp.mdx +3 -1
  684. package/docs/what-is-recorded.md +17 -5
  685. package/docs/what-is-reticle.mdx +5 -3
  686. package/docs/why-reticle.mdx +1 -1
  687. package/package.json +9 -12
  688. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  689. package/dist/command/cli/demo/demo-page.js +0 -241
  690. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  691. package/dist/command/cli/demo/demo-run.js +0 -138
  692. package/dist/features/harness/driver.d.ts +0 -50
  693. package/dist/features/harness/driver.js +0 -236
  694. package/dist/features/harness/jev-driver.d.ts +0 -188
  695. package/dist/features/harness/jev-driver.js +0 -678
  696. package/dist/features/harness/openai-driver.d.ts +0 -58
  697. package/dist/features/harness/openai-driver.js +0 -206
  698. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  699. package/dist/judgement/hunt/hunt-report.js +0 -84
  700. package/dist/language/flows/buddy-status.d.ts +0 -25
  701. package/dist/language/flows/buddy-status.js +0 -32
  702. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  703. package/dist/language/flows/change/watch-batcher.js +0 -19
  704. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  705. package/dist/memory/cloud/harness-offer.js +0 -145
  706. package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
  707. package/dist/memory/project/dir/fill-value-store.js +0 -88
  708. package/dist/surface/tools/feature-capture.d.ts +0 -151
  709. package/dist/surface/tools/feature-capture.js +0 -235
  710. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  711. package/dist/surface/tools/tool-hit-rate.js +0 -90
  712. package/dist/telemetry/harness-drive.d.ts +0 -4
  713. package/dist/telemetry/harness-drive.js +0 -35
  714. package/dist/telemetry/identify.d.ts +0 -22
  715. package/dist/telemetry/identify.js +0 -73
  716. package/docs/cli/capsules.mdx +0 -70
  717. package/docs/cli/hunt.mdx +0 -73
  718. package/docs/cli/identify.mdx +0 -76
  719. package/docs/cli/kill.mdx +0 -91
  720. package/docs/cli/watch.mdx +0 -62
  721. package/docs/local-registry.md +0 -143
@@ -4,10 +4,10 @@ import { EventType, FLOW_SIGNAL_TIMEOUT_MS, FlowErrorCode, RecordedFlowSchema, R
4
4
  import { haltedFrom } from './recording/replay-halt.js';
5
5
  import { establishedState, samePath } from './flow-journey.js';
6
6
  import { asRecord, asString } from '@reticlehq/core';
7
- import { routeOfEvent, routeOfUrl } from '@reticlehq/engine/question/predicate/predicate-route.js';
7
+ import { navigablePath, routeOfEvent, routeOfUrl, } from '@reticlehq/engine/question/predicate/predicate-route.js';
8
8
  import { carryReticleIdentity } from '../../surface/tools/lease-tools.js';
9
- import { replayFlow } from './flow-replay.js';
10
- import { anchorPrecondition, anchorQueryArgs } from './flow-step-runners.js';
9
+ import { partialStatus, replayFlow, replayWindow } from './flow-replay.js';
10
+ import { anchorPrecondition, anchorQueryArgs, staleTargetResult } from './flow-step-runners.js';
11
11
  import { queryRefs } from './replay.js';
12
12
  import { assertSuccess, dynamicTestids, successLabel, SUCCESS_STEP_TOOL } from './flow-success.js';
13
13
  import { buildDecision, unverifiableReason } from './decision.js';
@@ -17,7 +17,7 @@ import { isDocumentGoneError } from '../../portal/session/facts/session-replaced
17
17
  import { classifyFlowAssertions, flattenSteps } from './flow-classify.js';
18
18
  import { dischargeFlowIntent, flowIntentStatement, flowReplayVerdictId } from './flow-intent.js';
19
19
  import { IntentStore } from '../../memory/intent/intent-store.js';
20
- import { sessionRoot } from '../../memory/project/session-root.js';
20
+ import { safeSessionTarget, sessionRoot, } from '../../memory/project/session-root.js';
21
21
  import { waitForPredicate } from '@reticlehq/engine/question/predicate/predicate.js';
22
22
  import { computeSegments } from '../../memory/journal/rollups.js';
23
23
  import { stepEffect } from '@reticlehq/engine/evidence/step-effect.js';
@@ -28,10 +28,13 @@ import { EnvelopeStore } from '../../memory/journal/envelope-store.js';
28
28
  import { homedir } from 'node:os';
29
29
  import { cloudFetch, syncRunRecordToCloud, SyncOutcome } from '../../memory/cloud/cloud-sync.js';
30
30
  import { resolveProjectCloud } from '../../memory/cloud/cloud-config.js';
31
+ import { memoryReadHeaders, memoryReadUrl, scopedMemoryEntries, } from '../../memory/cloud/memory-scope.js';
31
32
  import { consultSubjectFor, selectConsulted } from './flow-memory-consult.js';
32
33
  import { log } from '../../log.js';
34
+ import { replayStepShooter } from '../../features/visual/step-shots.js';
33
35
  import { flowsForSession } from './flow-store-for-session.js';
34
36
  import { projectForRoot } from '../../memory/project/project-for-root.js';
37
+ import { CROSS_STEP_INDEX, crossStepOnly } from './flow-cross-step.js';
35
38
  export function latestRecordedFlow(events) {
36
39
  for (let i = events.length - 1; i >= 0; i--) {
37
40
  const event = events[i];
@@ -44,7 +47,7 @@ export function latestRecordedFlow(events) {
44
47
  return undefined;
45
48
  }
46
49
  export { flowErrorMessage } from './flow-result.js';
47
- import { flowErrorMessage } from './flow-result.js';
50
+ import { flowErrorMessage, noteReplayCheck } from './flow-result.js';
48
51
  /** Map the wire ReplayStatus onto the persisted RunStatus (ok→pass). */
49
52
  function replayToRunStatus(status) {
50
53
  switch (status) {
@@ -105,13 +108,14 @@ function currentPathOf(session) {
105
108
  // query usually decides what the page renders, so a tab on `?tab=summary` would read as "already
106
109
  // at `?tab=wrap`" and the replay would start on the wrong page with nothing saying so. Both sides
107
110
  // carry it, which keeps a real difference visible and stops the false one.
111
+ // Reticle's own params dropped, as the recording drops them from `startPath` (#1411).
108
112
  const observed = last === undefined ? undefined : routeOfEvent(last);
109
113
  if (observed !== undefined)
110
- return `${observed.docPath}${observed.search}${observed.hash}`;
114
+ return navigablePath(observed);
111
115
  if (session.url === undefined)
112
116
  return undefined;
113
117
  const fromUrl = routeOfUrl(session.url);
114
- return fromUrl === undefined ? undefined : `${fromUrl.docPath}${fromUrl.search}${fromUrl.hash}`;
118
+ return fromUrl === undefined ? undefined : navigablePath(fromUrl);
115
119
  }
116
120
  /**
117
121
  * Ask the project what it already knows about this flow.
@@ -130,18 +134,17 @@ async function consultProjectMemory(deps, flow, root) {
130
134
  if (subject === undefined)
131
135
  return undefined;
132
136
  try {
133
- // The APP's root, not the daemon's. `deps.reticleRoot` is wherever the daemon was launched,
134
- // which for a user-scoped MCP registration is almost never the project being verified — so the
135
- // link file it reads is the wrong one, or absent, and every project silently reads as
136
- // "not attached". Same class of bug as the flow store resolving per daemon instead of per
137
- // session, and it is invisible: the feature simply never appears.
137
+ // The APP's root, not the daemon's (wherever it was launched): its link file is this project's.
138
138
  const cloud = await resolveProjectCloud(deps.fs, root, homedir(), process.env);
139
139
  if (null === cloud.config || !cloud.policy.memory)
140
140
  return undefined;
141
- const url = `${cloud.config.url}/v1/memory?subject=${encodeURIComponent(subject)}`;
141
+ // Scoped to the linked project. The key covers a whole workspace, so a read that named no
142
+ // project could be answered with ANOTHER repo's knowledge and this replay would carry it into a
143
+ // verdict as if it were this app's — see `memory-scope.ts` for the whole shape.
144
+ const url = memoryReadUrl(cloud.config.url, { projectId: cloud.projectId, subject });
142
145
  const res = await cloudFetch(url, {
143
146
  method: 'GET',
144
- headers: { authorization: `Bearer ${cloud.config.apiKey}` },
147
+ headers: memoryReadHeaders(cloud.config.apiKey),
145
148
  });
146
149
  if (200 !== res.status)
147
150
  return undefined;
@@ -149,9 +152,14 @@ async function consultProjectMemory(deps, flow, root) {
149
152
  // property yields the function itself, `.entries` on it is undefined, and the whole feature
150
153
  // fails silently to "the project knows nothing" — which is indistinguishable from the honest
151
154
  // empty case and is why this took a live drive to notice at all.
152
- const body = (await res.json());
153
- const entries = body?.entries;
154
- if (!Array.isArray(entries))
155
+ const body = await res.json();
156
+ // The envelope is the check that works: the platform names the project on the RESPONSE and not
157
+ // on each entry, so the entry-level filter alone kept a whole sibling workspace while looking
158
+ // like it did something. `undefined` means the response could not be shown to be this project's
159
+ // — nothing is attached, because a verdict carrying another repo's "established knowledge" is
160
+ // worse than one carrying none. See `memory-scope.ts`.
161
+ const entries = scopedMemoryEntries(body, cloud.projectId);
162
+ if (entries === undefined)
155
163
  return undefined;
156
164
  const picked = selectConsulted(entries);
157
165
  return 0 === picked.length ? undefined : picked;
@@ -167,8 +175,8 @@ async function consultProjectMemory(deps, flow, root) {
167
175
  * anchor simply isn't on this page yet. Detect that so the decision says "navigate there first"
168
176
  * instead of a mystifying "a step no longer matches". Returns undefined when the routes agree or the
169
177
  * current route is unobservable — never a false alarm. Replay normally never gets here on a
170
- * wrong page (arriveAtStartPath navigates before step 1); this is the fallback for when that
171
- * navigation was refused or the SDK never reconnected in the window.
178
+ * wrong page (arriveAtStartPath navigates before step 1); this is the fallback when navigation
179
+ * was refused. A page that never reconnected is reported as unverifiable before step 1.
172
180
  */
173
181
  export function startPathMismatchHint(flow, session) {
174
182
  const startPath = flow.startPath;
@@ -188,33 +196,25 @@ const REAL_ARRIVAL_CLOCK = {
188
196
  };
189
197
  /**
190
198
  * The session `oldId` denotes right now — itself, or the tombstone successor `resolve` rebinds to
191
- * after a full-document navigation — but only once it actually sits on `target`. Undefined while
192
- * the tab is still travelling (or in the gap between teardown and the successor's HELLO, when
193
- * `resolve` throws). Keyed to the navigated tab's own identity on purpose: matching "any session at
194
- * the target page" would happily hand replay an unrelated tab that was already sitting there.
199
+ * after a full-document navigation. A different instance proves the SDK reconnected even when the
200
+ * app redirected to another route. Keyed to the navigated tab's own identity on purpose: matching
201
+ * "any session at the target page" could hand replay an unrelated tab already sitting there.
195
202
  */
196
203
  function arrivedSuccessor(sessions, oldId, target,
197
- /** The handle that issued the navigation, when only a genuinely new one counts as arrival. */
198
- mustReplace) {
204
+ /** The handle that issued the navigation. */
205
+ issuedBy, isReload) {
199
206
  try {
200
207
  const candidate = sessions.resolve(oldId);
201
- /*
202
- * A RELOAD lands on the path it left, so the path cannot tell the successor from the tab that
203
- * is still tearing down — `resolve(oldId)` answers with the dying one while it is registered,
204
- * which looks like instant arrival and hands replay a socket that will never answer again.
205
- *
206
- * The discriminator is the OBJECT, not the id. A leased tab carries its identity across a page
207
- * load (that is what the identity params are for), so it reconnects under the SAME id — waiting
208
- * for a new id there waits forever, and the first lease this was tried on timed out at step 1
209
- * on a tab that was perfectly healthy. `SessionManager.add` replaces the instance on every
210
- * reconnect, so a different instance is exactly "the socket came back".
211
- *
212
- * A navigation to a different route has the path as its discriminator and does not need this.
213
- */
214
- if (mustReplace !== undefined && candidate === mustReplace)
208
+ // A reload can return the dying handle on the same path. Compare instances, not ids: a leased
209
+ // tab can reconnect under the same id. A redirect counts only on a new instance.
210
+ if (isReload && candidate === issuedBy)
215
211
  return undefined;
216
212
  const path = currentPathOf(candidate);
217
- return path !== undefined && samePath(path, target) ? candidate : undefined;
213
+ if (path === undefined)
214
+ return undefined;
215
+ const matches = samePath(path, target);
216
+ // A still-connected old tab on the wrong route is not a redirected successor.
217
+ return matches || candidate !== issuedBy ? { session: candidate, matches } : undefined;
218
218
  }
219
219
  catch {
220
220
  return undefined;
@@ -267,10 +267,9 @@ async function firstStepResolvesHere(session, flow) {
267
267
  * A full-page load tears down the session socket, so the navigation must happen here — before any
268
268
  * step runs — and the replay continues on the session the SDK reconnects as (found via the same
269
269
  * tombstone rebind that lets `resolve(oldId)` answer after any navigation). Best-effort by design:
270
- * when the flow carries no startPath, the current route is unobservable, the navigation is refused,
271
- * or the SDK never reconnects in the window, replay proceeds on the connected session as before —
272
- * with startPathMismatchHint turning any resulting drift into an actionable next move rather than a
273
- * mystifying one.
270
+ * when the flow carries no startPath, the current route is unobservable, or navigation is refused,
271
+ * replay proceeds on the connected session. A missing successor stops before step 1; a redirect
272
+ * continues on the live successor with a route-specific hint.
274
273
  */
275
274
  export async function arriveAtStartPath(sessions, session, flow, timeoutMs = START_PATH_ARRIVAL_TIMEOUT_MS, clock = REAL_ARRIVAL_CLOCK) {
276
275
  const target = flow.startPath;
@@ -304,9 +303,24 @@ export async function arriveAtStartPath(sessions, session, flow, timeoutMs = STA
304
303
  // gone after is the reload's doing, not the flow file's. Without this, an app holding its session
305
304
  // in memory comes back signed out and step 1 blames a component that is completely fine.
306
305
  const resolvedBefore = here && (await firstStepResolvesHere(session, flow));
307
- const arrived = await navigateAndAwait(sessions, session, destination, target, timeoutMs, clock, here);
308
- if (arrived === undefined)
306
+ const outcome = await navigateAndAwait(sessions, session, destination, target, timeoutMs, clock, here);
307
+ if ('lost' === outcome.kind) {
308
+ return {
309
+ lost: `replay ${here ? 'reloaded' : 'navigated to'} ${target} before step 1 and no page was connected ` +
310
+ `after ${String(timeoutMs)}ms, so the session it was driving is gone and nothing ran. A slow ` +
311
+ `or backgrounded tab can take longer to come back: bring it to the front and replay`,
312
+ };
313
+ }
314
+ if ('refused' === outcome.kind)
309
315
  return {};
316
+ if ('redirected' === outcome.kind) {
317
+ const path = currentPathOf(outcome.session) ?? 'another route';
318
+ return {
319
+ session: outcome.session,
320
+ redirected: `replay ${here ? 'reloaded' : 'navigated to'} ${target} before step 1, but the tab reconnected on ${path}. Check the redirect or sign in before replaying`,
321
+ };
322
+ }
323
+ const arrived = outcome.session;
310
324
  if (!resolvedBefore || (await firstStepResolvesHere(arrived, flow)))
311
325
  return { session: arrived };
312
326
  return {
@@ -329,18 +343,6 @@ function resetCostHint(flow, target) {
329
343
  return (`replay reloaded ${target} before step 1 and the first anchor did not come back — this flow ` +
330
344
  `starts from state a page load discards. ${optOut}, or record it from a cold page`);
331
345
  }
332
- /**
333
- * Send a tab somewhere and wait for the session that comes back.
334
- *
335
- * A navigation is a full page load: the session that issued it DIES and a successor connects with a
336
- * new id. Every caller therefore has to wait for that successor rather than reuse the handle it
337
- * already holds, and getting this wrong does not error — it leaves the caller talking to a session
338
- * that will never answer again.
339
- *
340
- * Extracted so there is ONE of these rather than one per caller. `arriveAtStartPath` decides WHETHER
341
- * to move and this decides how, which is also why the deliberate short-circuits live up there and
342
- * not in here: a caller that has already decided it must move should not have to argue with them.
343
- */
344
346
  export async function navigateAndAwait(sessions, session, destination, expectedPath, timeoutMs = START_PATH_ARRIVAL_TIMEOUT_MS, clock = REAL_ARRIVAL_CLOCK,
345
347
  /** True when the destination is the page we are already on — see `arrivedSuccessor`. */
346
348
  isReload = false) {
@@ -349,7 +351,7 @@ isReload = false) {
349
351
  try {
350
352
  const outcome = await session.command(ReticleCommand.NAVIGATE, { url });
351
353
  if (!outcome.ok || true !== asRecord(outcome.result)['ok'])
352
- return undefined;
354
+ return { kind: 'refused' };
353
355
  }
354
356
  catch (error) {
355
357
  // A navigation that unloads the page rejects the very command that asked for it — the transport
@@ -357,15 +359,18 @@ isReload = false) {
357
359
  // and left replay driving a handle that could never answer again, which is how a flow with a
358
360
  // startPath died at step 1 on an app that had loaded perfectly. Anything else is a real refusal.
359
361
  if (!isDocumentGoneError(error))
360
- return undefined;
362
+ return { kind: 'refused' };
361
363
  }
362
364
  const deadline = clock.now() + timeoutMs;
363
365
  for (;;) {
364
- const arrived = arrivedSuccessor(sessions, session.id, expectedPath, isReload ? session : undefined);
365
- if (arrived !== undefined)
366
- return arrived;
366
+ const arrived = arrivedSuccessor(sessions, session.id, expectedPath, session, isReload);
367
+ if (true === arrived?.matches)
368
+ return { kind: 'arrived', session: arrived.session };
369
+ // A live redirect is a different result from no SDK reconnection at all.
367
370
  if (clock.now() >= deadline)
368
- return undefined;
371
+ return arrived === undefined
372
+ ? { kind: 'lost' }
373
+ : { kind: 'redirected', session: arrived.session };
369
374
  await clock.sleep(START_PATH_POLL_MS);
370
375
  }
371
376
  }
@@ -382,7 +387,7 @@ isReload = false) {
382
387
  * conservative direction, because a composite graded on a flow nobody could read is graded on a
383
388
  * promise.
384
389
  */
385
- async function loadInvokedFlows(deps, flow, projectId) {
390
+ async function loadInvokedFlows(deps, flow, target) {
386
391
  const out = new Map();
387
392
  const queue = [flow];
388
393
  const seen = new Set([flow.name]);
@@ -395,7 +400,7 @@ async function loadInvokedFlows(deps, flow, projectId) {
395
400
  if (name === undefined || seen.has(name))
396
401
  continue;
397
402
  seen.add(name);
398
- const sub = await flowsForSession(deps, projectId).flows.load(name, projectId);
403
+ const sub = await flowsForSession(deps, target).flows.load(name, target.projectId);
399
404
  if (!sub.ok)
400
405
  continue;
401
406
  out.set(name, sub.value);
@@ -453,7 +458,7 @@ async function firstUnmetPrecondition(session, flow, since) {
453
458
  export function lostDocumentResult(name, lost) {
454
459
  return {
455
460
  name,
456
- status: ReplayStatus.OK,
461
+ status: ReplayStatus.UNVERIFIABLE,
457
462
  steps: lost.steps,
458
463
  unverifiable: {
459
464
  reason: `the page's connection to Reticle was replaced while step ${String(lost.atStep)} was running ` +
@@ -473,16 +478,11 @@ observe = (s) => s) {
473
478
  // Resolve within the connecting app's scope so a shared daemon replays THIS project's flow, not a
474
479
  // same-named flow from another app. Safe-resolve: a missing session degrades to the global store,
475
480
  // and the load-then-session order (unchanged) still surfaces a not-found before a no-session error.
476
- let projectId;
477
- try {
478
- projectId = deps.sessions.resolve(asString(args['sessionId'])).projectId;
479
- }
480
- catch {
481
- projectId = undefined;
482
- }
481
+ const target = safeSessionTarget(deps, asString(args['sessionId']));
482
+ const { projectId } = target;
483
483
  // The app's store, not the daemon's: this load answering `flow_not_found` for a flow plainly on
484
484
  // disk is what made replay unusable from a daemon started outside the project.
485
- const loaded = await flowsForSession(deps, projectId).flows.load(name, projectId);
485
+ const loaded = await flowsForSession(deps, target).flows.load(name, projectId);
486
486
  if (!loaded.ok) {
487
487
  await recordReplayRun(deps, name, ReplayStatus.ERROR, 0, deps.now() - startedAt, projectId, sessionRoot(deps, asString(args['sessionId'])));
488
488
  return {
@@ -507,11 +507,23 @@ observe = (s) => s) {
507
507
  // The FlowFile contract: replay navigates to the flow's startPath before step 1, and the steps run
508
508
  // on the session the SDK reconnects as. When arrival can't be confirmed, replay proceeds on the
509
509
  // connected session — and the hint below turns the wrong-page drift into an actionable next move.
510
- const arrival = await arriveAtStartPath(deps.sessions, connected, loaded.value);
510
+ // Continuing at a step means the page is already there; going to the start would undo it.
511
+ const { to, at: continueAt } = replayWindow(args);
512
+ const arrival = continueAt === undefined ? await arriveAtStartPath(deps.sessions, connected, loaded.value) : {};
513
+ // Continuing on `connected` after the tab left timed every step out on a dead handle (#1129).
514
+ if (arrival.lost !== undefined) {
515
+ const reason = arrival.lost;
516
+ return {
517
+ name: loaded.value.name,
518
+ status: ReplayStatus.UNVERIFIABLE,
519
+ steps: [],
520
+ unverifiable: { reason },
521
+ };
522
+ }
511
523
  const session = arrival.session ?? connected;
512
524
  // The reset's own cost outranks the wrong-page hint: if the reload is why step 1 cannot start,
513
525
  // "navigate there and replay" is advice that would do the same thing again.
514
- const startPathHint = arrival.resetCost ?? startPathMismatchHint(loaded.value, session);
526
+ const startPathHint = arrival.redirected ?? arrival.resetCost ?? startPathMismatchHint(loaded.value, session);
515
527
  // Floor the success oracle at the start of THIS replay so a stale signal from a prior run
516
528
  // in the same session can't fake a pass.
517
529
  const replayFloor = session.elapsed();
@@ -521,7 +533,7 @@ observe = (s) => s) {
521
533
  // Loaded once and used for BOTH the replay and the grading below. A composite asserts through
522
534
  // what it runs, and a grader that cannot see the sub-flows reports `unverifiable` on a journey
523
535
  // that checks itself thoroughly — right about the file, wrong about the journey.
524
- const invokedFlows = await loadInvokedFlows(deps, replayable, projectId);
536
+ const invokedFlows = await loadInvokedFlows(deps, replayable, target);
525
537
  /*
526
538
  * The flow's own preconditions, before a single step runs.
527
539
  *
@@ -557,11 +569,11 @@ observe = (s) => s) {
557
569
  const names = missing.map((each) => each.envKey).join(', ');
558
570
  return {
559
571
  name: replayable.name,
560
- status: ReplayStatus.OK,
572
+ status: ReplayStatus.UNVERIFIABLE,
561
573
  steps: [],
562
574
  unverifiable: {
563
- reason: `this flow fills a redacted field and nothing supplied it, so nothing ran and nothing ` +
564
- `was proved. Set ${names} in the environment the daemon runs in, then replay. Until then ` +
575
+ reason: `this flow fills a redacted field and nothing supplied it, so nothing ran and nothing was ` +
576
+ `proved. Pass it with this call — secrets: { ${missing.map((each) => `"${each.field}": "…"`).join(', ')} } — or set ${names} where the daemon runs and restart it. Until then ` +
565
577
  `the value typed would be the placeholder itself, and any failure after it would be ` +
566
578
  `about this and not about the application.`,
567
579
  },
@@ -577,7 +589,7 @@ observe = (s) => s) {
577
589
  if (unmet !== undefined) {
578
590
  return {
579
591
  name: replayable.name,
580
- status: ReplayStatus.OK,
592
+ status: ReplayStatus.UNVERIFIABLE,
581
593
  steps: [],
582
594
  unverifiable: { reason: unmet },
583
595
  };
@@ -588,13 +600,21 @@ observe = (s) => s) {
588
600
  // How an `invoke` step finds the flow it runs. Scoped to the same project as the flow being
589
601
  // replayed, so a composite cannot reach into another app's store for a same-named sub-journey.
590
602
  resolveFlow: async (invoked) => {
591
- const sub = await flowsForSession(deps, projectId).flows.load(invoked, projectId);
603
+ const sub = await flowsForSession(deps, target).flows.load(invoked, projectId);
592
604
  return sub.ok ? await resolveFlowUploads(deps, sub.value) : undefined;
593
605
  },
594
606
  // Bug-sweep mode: keep going past a step whose action ran and whose consequence merely did
595
607
  // not hold, so one flow reports one verdict per step instead of stopping at the first defect.
596
608
  sweep: true === args['sweep'],
597
609
  ...(from === undefined ? {} : { from }),
610
+ ...(to === undefined ? {} : { to }),
611
+ ...(continueAt === undefined ? {} : { at: continueAt }),
612
+ // The HUD's replay chip, when the human pressed ▶. In-process only: an agent's arguments
613
+ // arrive as JSON and can never carry a function.
614
+ onStepResult: replayStepShooter(deps, session.id),
615
+ ...('function' === typeof args['onStep']
616
+ ? { onStep: args['onStep'] }
617
+ : {}),
598
618
  });
599
619
  }
600
620
  catch (error) {
@@ -602,6 +622,9 @@ observe = (s) => s) {
602
622
  throw error;
603
623
  return lostDocumentResult(name, error);
604
624
  }
625
+ // Only part of the journey was driven here: its steps were checked, nothing about the whole flow.
626
+ if (0 < (continueAt ?? 0) || (to !== undefined && to < loaded.value.steps.length))
627
+ return { name, status: partialStatus(steps), steps };
605
628
  // Computed HERE, before the synthetic success row is appended below: once that row is pushed,
606
629
  // `steps.length` no longer counts only the flow's own steps and the arithmetic is wrong.
607
630
  const halted = haltedFrom(steps, loaded.value.steps.length);
@@ -639,6 +662,9 @@ observe = (s) => s) {
639
662
  };
640
663
  steps.push(row);
641
664
  }
665
+ const staleTarget = staleTargetResult(name, steps);
666
+ if (staleTarget !== undefined)
667
+ return staleTarget;
642
668
  const driftSteps = steps.filter((s) => s.drift !== undefined).length;
643
669
  const allOk = steps.every((s) => s.ok);
644
670
  const status = driftSteps > 0 ? ReplayStatus.DRIFT : allOk ? ReplayStatus.OK : ReplayStatus.ERROR;
@@ -674,8 +700,9 @@ observe = (s) => s) {
674
700
  * moment somebody needs to know what this feature is supposed to do and who established it. A
675
701
  * knowledge base you only see when everything is already fine is decoration.
676
702
  */
677
- // No projectId argument: the API key is already bound to one project server-side, so passing a
678
- // second opinion about which project this is would only create a way for the two to disagree.
703
+ // The scope comes from the link file, inside `consultProjectMemory`. It is NOT the API key's
704
+ // job: a key covers a whole workspace and a workspace holds more than one repo, so "bound to one
705
+ // project server-side" was an assumption that handed this replay another app's knowledge.
679
706
  const knows = await consultProjectMemory(deps, loaded.value, replayRoot);
680
707
  const failed = steps.find((step) => !step.ok && step.drift === undefined);
681
708
  if (failed !== undefined) {
@@ -700,13 +727,12 @@ observe = (s) => s) {
700
727
  result.halted = halted;
701
728
  if (knows !== undefined)
702
729
  result.knows = knows;
703
- // A green that cannot go red is not a pass. `reticle_flow_verify` already refuses to count these,
704
- // via this same function -- a single-flow caller saw a bare `ok` and had no way to learn the flow
705
- // asserts nothing. Derived from the same helper on purpose: two copies of this judgement would
706
- // drift, and the sibling tools would then disagree about the same flow.
730
+ // A green that cannot go red is not a pass: the same judgement `reticle_flow_verify` makes.
707
731
  const cannotFail = status === ReplayStatus.OK ? unverifiableReason(loaded.value, invokedFlows) : undefined;
708
732
  if (cannotFail !== undefined)
709
733
  result.unverifiable = { reason: cannotFail };
734
+ // One check of the session that ran it, so its end does not say "nothing was checked".
735
+ noteReplayCheck(session, name, status, cannotFail !== undefined);
710
736
  if (status !== ReplayStatus.OK)
711
737
  result.decision = buildDecision(result, loaded.value, intentSaid, invokedFlows);
712
738
  applyStartPathHint(result, startPathHint);
@@ -768,27 +794,6 @@ observe = (s) => s) {
768
794
  */
769
795
  return result;
770
796
  }
771
- /** A contradiction's identity for de-duplication: the rule that fired, and the evidence it fired on. */
772
- function contradictionId(found) {
773
- return `${found.kind}|${found.detail}`;
774
- }
775
- /**
776
- * The contradictions the whole-span pass found that no individual step could.
777
- *
778
- * A step's window closes when the step ends, so a request fired at step 2 and still unanswered at
779
- * step 5 is invisible to every per-step window: step 2's closed before the answer came and step 5
780
- * never saw it start. Re-running the detectors over the whole replay span finds those — and re-finds
781
- * everything the steps already reported, which is what the subtraction is for. Reporting a finding
782
- * twice teaches a reader that the count is noise.
783
- *
784
- * Exported for its own test: the subtraction is the whole rule, and it is pure.
785
- */
786
- /** Cross-step findings belong to no single step; -1 is the address the suite verdict already uses. */
787
- const CROSS_STEP_INDEX = -1;
788
- export function crossStepOnly(whole, steps) {
789
- const seen = new Set(steps.flatMap((step) => (step.contradictions ?? []).map(contradictionId)));
790
- return whole.filter((found) => !seen.has(contradictionId(found)));
791
- }
792
797
  /**
793
798
  * The deviation report over a replay's route segments — compared against the learned envelope, which is
794
799
  * then updated. Best-effort: any failure (disk, empty window) yields undefined, never breaking the replay.
@@ -12,7 +12,7 @@ import type { EvalResult } from '@reticlehq/engine/question/predicate/predicate.
12
12
  * (via the injected waitForPredicate). Mirrors PredicateSession so the same fake drives both.
13
13
  */
14
14
  export interface FlowReplaySession {
15
- command(name: string, args?: Record<string, unknown>): Promise<CommandResult>;
15
+ command(name: string, args?: Record<string, unknown>, timeoutMs?: number): Promise<CommandResult>;
16
16
  /**
17
17
  * Attribution window around each replayed step. Optional so a minimal test double still satisfies the
18
18
  * interface, but a real session MUST supply it: without a window the step's own effects carry no
@@ -1,7 +1,7 @@
1
1
  export { nearestIsAmbiguous, nearestTestid, resolveQuery } from './flow-anchor.js';
2
2
  import type { FlowReplaySession, WaitForSignal, Sleep } from './flow-replay-types.js';
3
3
  export type { FlowReplaySession, WaitForSignal, Sleep } from './flow-replay-types.js';
4
- import { type Drift, type FlowFile, type FlowStep, type FlowStepResult } from '@reticlehq/core';
4
+ import { type Drift, type FlowFile, type FlowStep, type FlowStepResult, ReplayStatus } from '@reticlehq/core';
5
5
  /**
6
6
  * The document this replay was driving went away mid-run.
7
7
  *
@@ -43,6 +43,15 @@ export declare function runTestidStep(session: FlowReplaySession, step: FlowStep
43
43
  * state it was never meant to run in.
44
44
  */
45
45
  export declare function assertStepExpect(session: FlowReplaySession, expect: NonNullable<FlowStep['expect']>, waitForSignal: WaitForSignal, timeoutMs: number, since: number): Promise<Drift | undefined>;
46
+ /**
47
+ * A text check that missed only on case says so, with what would hold. Text checks match case
48
+ * exactly now, so a flow saved when they did not goes red on capitalisation alone; the person
49
+ * reading its replay needs the fix (`ignoreCase: true`, or re-record), not a bare "did not hold".
50
+ */
51
+ export declare function withCaseOnly(reason: string, verdict: {
52
+ caseOnlyMiss?: boolean;
53
+ wouldHold?: string;
54
+ }): string;
46
55
  /**
47
56
  * Replay a loaded flow by RE-RESOLVING every step's semantic anchor against the live DOM — never
48
57
  * a stale ref. A testid anchor is re-found by reticle_query; a signal anchor waits on a predicate.
@@ -53,6 +62,16 @@ export declare function assertStepExpect(session: FlowReplaySession, expect: Non
53
62
  * How a replay is loaded, where it starts reporting, and how far it goes.
54
63
  */
55
64
  export interface ReplayFromOptions {
65
+ /**
66
+ * Told after every step it reports: how many are done, of how many, and whether this one held.
67
+ * The HUD's replay chip draws its progress from this; it must never throw into the replay.
68
+ */
69
+ onStep?: (done: number, total: number, held: boolean) => void;
70
+ /**
71
+ * Told each reported step the moment its outcome is decided, before it is kept, so a caller can
72
+ * add to it (the step's screenshot). Never allowed to fail the replay.
73
+ */
74
+ onStepResult?: (result: FlowStepResult, flow: string) => Promise<void>;
56
75
  /**
57
76
  * Resume at this step: an index, or a step's `id` (which survives edits that shift indices).
58
77
  *
@@ -62,6 +81,16 @@ export interface ReplayFromOptions {
62
81
  * for, and swallowing that would report the run as starting where it did not.
63
82
  */
64
83
  from?: number | string;
84
+ /**
85
+ * Stop before this step index: drive the journey only as far as a point, such as a dialog that
86
+ * several journeys branch from. Absent means the whole flow.
87
+ */
88
+ to?: number;
89
+ /**
90
+ * Continue at this step on the page as it is: earlier steps are not driven at all, because the
91
+ * caller already drove an identical prefix (another flow replayed `to` this step).
92
+ */
93
+ at?: number;
65
94
  /**
66
95
  * How to load a flow this one INVOKES. Absent means invocations cannot be followed.
67
96
  *
@@ -99,6 +128,16 @@ export interface ReplayFromOptions {
99
128
  * is not setup, it is a second charge, a second email, a second record.
100
129
  */
101
130
  export declare function resumeIndex(from: number | string | undefined, steps: readonly FlowStep[]): number | undefined;
131
+ /**
132
+ * How far a replay drives: `to` stops before a step (positive), `at` picks up at one on the page as
133
+ * it is. `at: 0` is the whole flow continuing the page the flow before it left, with no reload.
134
+ */
135
+ export declare function replayWindow(args: Record<string, unknown>): {
136
+ to?: number;
137
+ at?: number;
138
+ };
139
+ /** A part-way replay's status, from the steps it drove. */
140
+ export declare function partialStatus(steps: readonly FlowStepResult[]): ReplayStatus;
102
141
  /** The `from` argument, narrowed: a step index or a step id. */
103
142
  export declare function resumeArg(raw: unknown): number | string | undefined;
104
143
  /** Why `from` cannot be resumed at, or undefined when it can (or was not given). */