@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
@@ -5,11 +5,11 @@ import { ambiguityDrift, anchorLabel, expectElementDrift, reresolved, resolveTes
5
5
  export { nearestIsAmbiguous, nearestTestid, resolveQuery } from './flow-anchor.js';
6
6
  import { routeOfEvent, routeOfUrl } from '@reticlehq/engine/question/predicate/predicate-route.js';
7
7
  import { evalConsole } from '@reticlehq/engine/question/predicate/predicate-console.js';
8
- import { stepEffect } from '@reticlehq/engine/evidence/step-effect.js';
8
+ import { appScope, stepEffect } from '@reticlehq/engine/evidence/step-effect.js';
9
9
  import { AnchorKind, DriftReason, EventType, FlowStepTool, StepEffect, PredicateKind, ReplayStatus, } from '@reticlehq/core';
10
10
  import { asString, invokedFlowMissing, isConsequenceDrift } from '@reticlehq/core';
11
11
  import { anchorFieldName } from './fields/flow-secret-field.js';
12
- import { degradedStepResult, isDegradedAnchor, runComponentStep, runRoleStep, runSequenceStep, } from './flow-step-runners.js';
12
+ import { degradedStepResult, isDocumentPressStep, isDegradedAnchor, runComponentStep, runRoleStep, runSequenceStep, } from './flow-step-runners.js';
13
13
  import { inFlightRequestLabels } from '../../surface/tools/act/settle-in-flight.js';
14
14
  import { namedNetIsInFlight } from '@reticlehq/engine/evidence/unsettled.js';
15
15
  /** What a still-open named request means, in the drift's own words. */
@@ -464,6 +464,9 @@ export async function replayFlow(session, flow, waitForSignal, signalTimeoutMs,
464
464
  continue;
465
465
  }
466
466
  const label = anchorLabel(step.anchor);
467
+ /** One sub-step's expect, over the window that sub-step opened. See runSequenceStep. */
468
+ const judgeSubStep = async (expectation, since) => (await assertStepExpect(session, expectation, waitForSignal, waitFor(step), since)) ??
469
+ lateConsoleDrift(expectation, session.eventsSince(since).filter((e) => e.t >= since));
467
470
  // The page this step runs on (the journey's "which page") — captured before the action.
468
471
  const page = currentRoute(session);
469
472
  // Event-time floor so the consequence reflects only THIS step's aftermath, not prior steps'.
@@ -477,8 +480,12 @@ export async function replayFlow(session, flow, waitForSignal, signalTimeoutMs,
477
480
  // Never QUERY the sentinel — it marks "no anchor was determined", not an element to find.
478
481
  return degradedStepResult(step, index, label);
479
482
  }
483
+ if (subSteps === undefined && isDocumentPressStep(step)) {
484
+ // A document-key press: dispatched with no ref, as it ran live (#1559).
485
+ return actOnResolvedRef(session, step, index, label, '', confirmDangerous);
486
+ }
480
487
  if (subSteps !== undefined && subSteps.length > 0) {
481
- return runSequenceStep(session, step, index, subSteps, confirmDangerous, sleep, dynamic);
488
+ return runSequenceStep(session, step, index, subSteps, confirmDangerous, sleep, dynamic, index < from ? undefined : judgeSubStep);
482
489
  }
483
490
  if (step.anchor.kind === AnchorKind.SIGNAL) {
484
491
  return runSignalStep(session, step, index, label, waitForSignal, waitFor(step), replayFloor);
@@ -496,25 +503,18 @@ export async function replayFlow(session, flow, waitForSignal, signalTimeoutMs,
496
503
  // Once the anchor resolved and the action ran, the step's own expect is evaluated — signal, net,
497
504
  // console and store truth alike — deterministically, in the same cheap replay loop, with no LLM.
498
505
  /*
499
- * The step's own expect, and then every sub-step's.
500
- *
501
- * `classifyFlowAssertions` already walks act_sequence sub-steps and counts an expect on either
502
- * level, and states the invariant plainly: this and what replay enforces must move together, or
503
- * "the difference is a false green or a lost verification". Enforcing only the top level was
504
- * that difference -- a sequence whose sub-step declared a consequence was GRADED asserted and
505
- * checked by nothing, so it could not go red while wearing the grade that says it could.
506
+ * The step's own expect. A sub-step's expect was judged by the sequence runner, in the window
507
+ * of that sub-step, as the live `act_sequence` path judges it.
506
508
  *
507
- * WEAKER THAN THE LIVE PATH, and deliberately so rather than silently. A recorded sequence is
508
- * dispatched as ONE batched command, so there are no per-sub-step cursors to open a window with
509
- * -- every sub-step expect is evaluated against the window the whole sequence opened, which
510
- * means sub-step three's claim can be satisfied by sub-step one's consequence. The live
511
- * `act_sequence` path takes a cursor before each dispatch and does not have this. Narrowing it
512
- * here means dispatching sub-steps individually on replay, which is a behaviour change to the
513
- * replay path and belongs in its own commit.
509
+ * `classifyFlowAssertions` walks act_sequence sub-steps and counts an expect on either level,
510
+ * and this and what replay enforces must move together, or "the difference is a false green or
511
+ * a lost verification". Judged here, at the end, a route expect on a middle sub-step failed
512
+ * once a later one moved on, and a later claim could pass on an earlier sub-step's request.
514
513
  */
515
514
  const declared = [step.expect, ...(step.steps ?? []).map((sub) => sub.expect)].filter((expectation) => expectation !== undefined);
515
+ const own = step.expect === undefined ? [] : [step.expect];
516
516
  // A setup step's consequence is not checked: it is re-driven to get somewhere, not to prove it.
517
- const checked = index < from ? [] : declared;
517
+ const checked = index < from ? [] : own;
518
518
  for (const expectation of checked) {
519
519
  if (!result.ok || result.drift !== undefined)
520
520
  break;
@@ -551,7 +551,9 @@ export async function replayFlow(session, flow, waitForSignal, signalTimeoutMs,
551
551
  const cursorAfter = session.elapsed();
552
552
  // ONE builder, shared with the live act path, so a driven step and a replayed one describe what
553
553
  // happened in identical words rather than in two vocabularies that agree by coincidence.
554
- Object.assign(result, stepEffect(windowEvents, { since: cursorBefore, until: cursorAfter }));
554
+ Object.assign(result, stepEffect(windowEvents, { since: cursorBefore, until: cursorAfter },
555
+ // A failure the step declared is its expected result, as it is on the live path.
556
+ { ...appScope(session), declared }));
555
557
  /*
556
558
  * A prefix step is setup and is not reported -- UNLESS it failed.
557
559
  *
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Whether a saved flow can replay at all, decided when it is saved, and what save changes so it can.
3
+ *
4
+ * Of 34 flows saved over one night, 5 replayed green. None of the misses was a defect in the app:
5
+ * a flow with no starting page, an anchor six buttons share, a live count ("Open 336") the next run
6
+ * cannot see again, or a step that WROTE real data each time it replayed. Each was found by a
7
+ * replay that drifted, never said when the flow was saved. This says it at save, and again with
8
+ * every suite verdict.
9
+ *
10
+ * Pure: a flow in, a flow or a report out. No IO, no clock.
11
+ */
12
+ import { z } from 'zod';
13
+ import { type FlowFile } from '@reticlehq/core';
14
+ export declare const Replayable: {
15
+ readonly YES: "replayable";
16
+ readonly NO: "not_replayable";
17
+ /** It replays, but an expect names data the next run will not see again. */
18
+ readonly DATA_BOUND: "data_bound";
19
+ };
20
+ export type Replayable = (typeof Replayable)[keyof typeof Replayable];
21
+ export interface Replayability {
22
+ status: Replayable;
23
+ /** One sentence for each reason, by step. Absent when there is nothing to say. */
24
+ why?: string[];
25
+ /** A step sends a write request, so a replay changes real data. */
26
+ writes?: true;
27
+ }
28
+ /**
29
+ * The flow as it is saved: a live count in a text expect becomes word-level where the step allows
30
+ * it, and a step whose expect names a write request is marked `writes`. A money check keeps its
31
+ * number exact, and the report then says the flow is bound to the data.
32
+ */
33
+ export declare function readyForReplay(flow: FlowFile): FlowFile;
34
+ /** Whether the flow can replay, and why not, by step. */
35
+ export declare function replayability(flow: FlowFile): Replayability;
36
+ /** The suite's argument and field for this, worded once. */
37
+ export declare const SKIP_WRITES_ARG: z.ZodOptional<z.ZodBoolean>;
38
+ export declare const REPLAYABILITY_OUTPUT: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Whether a saved flow can replay at all, decided when it is saved, and what save changes so it can.
3
+ *
4
+ * Of 34 flows saved over one night, 5 replayed green. None of the misses was a defect in the app:
5
+ * a flow with no starting page, an anchor six buttons share, a live count ("Open 336") the next run
6
+ * cannot see again, or a step that WROTE real data each time it replayed. Each was found by a
7
+ * replay that drifted, never said when the flow was saved. This says it at save, and again with
8
+ * every suite verdict.
9
+ *
10
+ * Pure: a flow in, a flow or a report out. No IO, no clock.
11
+ */
12
+ import { z } from 'zod';
13
+ import { AnchorKind, DEGRADED_ANCHOR_ROLE, MUTATING_METHODS, PredicateKind, } from '@reticlehq/core';
14
+ export const Replayable = {
15
+ YES: 'replayable',
16
+ NO: 'not_replayable',
17
+ /** It replays, but an expect names data the next run will not see again. */
18
+ DATA_BOUND: 'data_bound',
19
+ };
20
+ const NUMBER = /\d[\d,.]*/g;
21
+ const HAS_NUMBER = /\d/;
22
+ /** The words of a money check. Its number IS the claim, so it is never made word-level. */
23
+ const MONEY = /credit|price|cost|charge|balance|paid|pay|invoice|refund|\$|€|£/i;
24
+ /** A fragment kept as the words of a count: at least two letters. */
25
+ const WORDS = /[A-Za-z]{2,}/;
26
+ const NUMBER_PATTERN = '\\d[\\d,.]*';
27
+ const MATCHES_PATTERN = 'matchesPattern';
28
+ const escapeRegex = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
29
+ /**
30
+ * A text expect with a live count, made word-level: the words stay exact, the number may change.
31
+ * Undefined when it cannot be: no words beside the number, a money check, or a `satisfies` already.
32
+ */
33
+ function wordLevel(contains, money) {
34
+ if (money || MONEY.test(contains))
35
+ return undefined;
36
+ const words = contains
37
+ .split(NUMBER)
38
+ .map((part) => part.trim())
39
+ .filter((part) => WORDS.test(part))
40
+ .sort((a, b) => b.length - a.length)[0];
41
+ if (words === undefined)
42
+ return undefined;
43
+ const pattern = contains.split(NUMBER).map(escapeRegex).join(NUMBER_PATTERN);
44
+ return {
45
+ kind: PredicateKind.TEXT,
46
+ contains: words,
47
+ satisfies: { property: MATCHES_PATTERN, pattern },
48
+ };
49
+ }
50
+ function relax(predicate, money) {
51
+ if (PredicateKind.ALL_OF === predicate.kind || PredicateKind.ANY_OF === predicate.kind) {
52
+ return { ...predicate, predicates: predicate.predicates.map((p) => relax(p, money)) };
53
+ }
54
+ if (PredicateKind.TEXT === predicate.kind &&
55
+ predicate.satisfies === undefined &&
56
+ predicate.contains !== undefined &&
57
+ HAS_NUMBER.test(predicate.contains)) {
58
+ const relaxed = wordLevel(predicate.contains, money);
59
+ if (relaxed !== undefined) {
60
+ const { contains: _contains, ...rest } = predicate;
61
+ return { ...rest, ...relaxed };
62
+ }
63
+ }
64
+ return predicate;
65
+ }
66
+ /** Every leaf predicate under a composite, `not` included: a count is data-bound either way. */
67
+ function leaves(predicate) {
68
+ if (predicate === undefined)
69
+ return [];
70
+ if (PredicateKind.ALL_OF === predicate.kind || PredicateKind.ANY_OF === predicate.kind) {
71
+ return predicate.predicates.flatMap(leaves);
72
+ }
73
+ if (PredicateKind.NOT === predicate.kind)
74
+ return leaves(predicate.predicate);
75
+ return [predicate];
76
+ }
77
+ /** The write requests an expect names, as "METHOD url". */
78
+ function writesNamed(predicate) {
79
+ return leaves(predicate).flatMap((leaf) => PredicateKind.NET === leaf.kind &&
80
+ leaf.method !== undefined &&
81
+ MUTATING_METHODS.includes(leaf.method.toUpperCase())
82
+ ? [`${leaf.method.toUpperCase()} ${leaf.urlContains ?? ''}`.trim()]
83
+ : []);
84
+ }
85
+ /** The live data an expect names: a number in text, in an element's name or text, or in state. */
86
+ function liveData(predicate) {
87
+ return leaves(predicate).flatMap((leaf) => {
88
+ if (PredicateKind.TEXT === leaf.kind && leaf.satisfies === undefined) {
89
+ return leaf.contains !== undefined && HAS_NUMBER.test(leaf.contains) ? [leaf.contains] : [];
90
+ }
91
+ if (PredicateKind.ELEMENT === leaf.kind) {
92
+ return [leaf.query.name, leaf.query.text].filter((value) => value !== undefined && HAS_NUMBER.test(value));
93
+ }
94
+ if (PredicateKind.STATE === leaf.kind && 'number' === typeof leaf.equals) {
95
+ return [`${leaf.path} = ${String(leaf.equals)}`];
96
+ }
97
+ return [];
98
+ });
99
+ }
100
+ function readyStep(step, money) {
101
+ const steps = step.steps?.map((sub) => readyStep(sub, money));
102
+ const expect = step.expect === undefined ? undefined : relax(step.expect, money);
103
+ const writes = true === step.writes ||
104
+ 0 < writesNamed(step.expect).length ||
105
+ true === steps?.some((sub) => true === sub.writes);
106
+ return {
107
+ ...step,
108
+ ...(expect === undefined ? {} : { expect }),
109
+ ...(steps === undefined ? {} : { steps }),
110
+ ...(writes ? { writes: true } : {}),
111
+ };
112
+ }
113
+ /**
114
+ * The flow as it is saved: a live count in a text expect becomes word-level where the step allows
115
+ * it, and a step whose expect names a write request is marked `writes`. A money check keeps its
116
+ * number exact, and the report then says the flow is bound to the data.
117
+ */
118
+ export function readyForReplay(flow) {
119
+ const money = MONEY.test(flow.intent ?? '');
120
+ return { ...flow, steps: flow.steps.map((step) => readyStep(step, money)) };
121
+ }
122
+ function addressed(steps, prefix = '') {
123
+ return steps.flatMap((step, i) => {
124
+ const at = `${prefix}${String(i + 1)}`;
125
+ return [{ at, step }, ...addressed(step.steps ?? [], `${at}.`)];
126
+ });
127
+ }
128
+ /** Whether the flow can replay, and why not, by step. */
129
+ export function replayability(flow) {
130
+ const blocked = [];
131
+ const bound = [];
132
+ const writes = [];
133
+ if (flow.startPath === undefined || '' === flow.startPath) {
134
+ blocked.push('no starting page was recorded, so a replay starts wherever the tab is');
135
+ }
136
+ for (const { at, step } of addressed(flow.steps)) {
137
+ // A hand-written flow read without the schema can lack an anchor; it then says nothing here.
138
+ const anchor = step.anchor;
139
+ // A sequence's own anchor is a copy of a sub-step's; the sub-step answers for it.
140
+ const own = step.steps === undefined;
141
+ if (own &&
142
+ (true === step.degraded ||
143
+ (AnchorKind.ROLE === anchor?.kind && DEGRADED_ANCHOR_ROLE === anchor.role))) {
144
+ blocked.push(`step ${at} has no anchor a replay can find`);
145
+ }
146
+ else if (own && AnchorKind.TESTID === anchor?.kind && anchor.of !== undefined) {
147
+ blocked.push(`step ${at} anchors on test id '${anchor.value}', which ${String(anchor.of)} elements share`);
148
+ }
149
+ if (own &&
150
+ AnchorKind.ROLE === anchor?.kind &&
151
+ anchor.name !== undefined &&
152
+ HAS_NUMBER.test(anchor.name)) {
153
+ bound.push(`step ${at} acts on a control named '${anchor.name}', a live count`);
154
+ }
155
+ for (const data of liveData(step.expect))
156
+ bound.push(`step ${at} expects '${data}', live data`);
157
+ for (const write of own ? writesNamed(step.expect) : [])
158
+ writes.push(`step ${at} sends ${write}`);
159
+ if (own && true === step.writes && 0 === writesNamed(step.expect).length) {
160
+ writes.push(`step ${at} sent a write request when it was recorded`);
161
+ }
162
+ }
163
+ const why = [...blocked, ...bound, ...writes];
164
+ const status = 0 < blocked.length ? Replayable.NO : 0 < bound.length ? Replayable.DATA_BOUND : Replayable.YES;
165
+ return {
166
+ status,
167
+ ...(0 === why.length ? {} : { why }),
168
+ ...(0 === writes.length ? {} : { writes: true }),
169
+ };
170
+ }
171
+ /** The suite's argument and field for this, worded once. */
172
+ export const SKIP_WRITES_ARG = z
173
+ .boolean()
174
+ .optional()
175
+ .describe('Certify without changing data: hold back every flow with a step that sends a write request (POST, PUT, PATCH, DELETE), and name them in `skippedWrites`.');
176
+ export const REPLAYABILITY_OUTPUT = z
177
+ .array(z.unknown())
178
+ .optional()
179
+ .describe('Each flow that cannot replay as saved: not_replayable (no starting page, an anchor no replay can find or several elements share) or data_bound (live data in an expect), and writes when a step sends a write request. A drift on such a flow is the flow, not the app.');
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Replay's arrival at a flow's start page: navigate (or reload) before step 1, wait for the session
3
+ * the SDK reconnects as, and say what happened when it does not.
4
+ */
5
+ import { type CommandResult, type FlowFile, type FlowReplayResult, type ReticleEvent, type StartPageWait } from '@reticlehq/core';
6
+ import type { ArrivalClock } from '../../surface/tools/act/navigation/navigate-arrival.js';
7
+ import type { SessionManager } from '../../portal/session/session-manager.js';
8
+ import type { Session } from '../../portal/session/session.js';
9
+ /** The slice of a session the start-path logic reads: the live URL plus the event buffer. */
10
+ interface StartPathSession {
11
+ url?: string;
12
+ eventsSince(cursor: number): ReticleEvent[];
13
+ }
14
+ /**
15
+ * When a flow records the page its journey started on (`startPath`) and the tab is currently on a
16
+ * different route, step 1 drifts for a reason that has nothing to do with the app regressing — the
17
+ * anchor simply isn't on this page yet. Detect that so the decision says "navigate there first"
18
+ * instead of a mystifying "a step no longer matches". Returns undefined when the routes agree or the
19
+ * current route is unobservable — never a false alarm. Replay normally never gets here on a
20
+ * wrong page (arriveAtStartPath navigates before step 1); this is the fallback when navigation
21
+ * was refused. A page that never reconnected is reported as unverifiable before step 1.
22
+ */
23
+ export declare function startPathMismatchHint(flow: FlowFile, session: StartPathSession): string | undefined;
24
+ /** What replay learned on its way to step 0. Both fields absent = the tab was left exactly as it was. */
25
+ export interface StartPathArrival {
26
+ /** The successor session replay must continue on. Absent when nothing was navigated, or arrival timed out. */
27
+ session?: Session;
28
+ /** Set when the RESET itself is why step 1 cannot start — the reason a step-1 red is not drift. */
29
+ resetCost?: string;
30
+ /** Set when the tab was sent away and nothing reconnected: the old handle will never answer (#1129). */
31
+ lost?: string;
32
+ /** A live successor arrived on a different route, so replay must not use the dead old handle. */
33
+ redirected?: string;
34
+ /** Set when the page's loading kept replay waiting past the step budget. */
35
+ wait?: StartPageWait;
36
+ }
37
+ /** The replay result, with how long replay waited for its start page when that went past the budget. */
38
+ export declare function withStartPageWait<R extends FlowReplayResult>(result: R, arrival: StartPathArrival): R;
39
+ /**
40
+ * Replay's half of the FlowFile contract: put the tab on the flow's `startPath` before step 1, and
41
+ * RELOAD it if it is already there.
42
+ *
43
+ * The reload is the state contract. Replaying "add a task" twice against a tab nobody reset gives
44
+ * the second run a world the recording never saw, and its assertions then describe the first run
45
+ * rather than the app. Our own `replay-determinism.mjs` has always refreshed before every run — the
46
+ * determinism we measured was never the determinism a user got.
47
+ *
48
+ * `requires` is the declared opt-out, and its first caller. A flow that says it starts from state
49
+ * another flow established is the one flow a page load would destroy, so it is never reset — here
50
+ * or from the wrong page. Silence is not an opt-out: a flow that depends on leftovers without
51
+ * saying so is a flow whose green means nothing on a fresh machine, and CI is a fresh machine.
52
+ *
53
+ * A full-page load tears down the session socket, so the navigation must happen here — before any
54
+ * step runs — and the replay continues on the session the SDK reconnects as (found via the same
55
+ * tombstone rebind that lets `resolve(oldId)` answer after any navigation). Best-effort by design:
56
+ * when the flow carries no startPath, the current route is unobservable, or navigation is refused,
57
+ * replay proceeds on the connected session. A missing successor stops before step 1; a redirect
58
+ * continues on the live successor with a route-specific hint.
59
+ */
60
+ export declare function arriveAtStartPath(sessions: SessionManager, session: StartPathSession & {
61
+ id: string;
62
+ command(name: string, args?: Record<string, unknown>): Promise<CommandResult>;
63
+ }, flow: FlowFile, timeoutMs?: number, clock?: ArrivalClock,
64
+ /** Whether the tab is still loading. Replay passes one for a pool lease, the only tab it can ask. */
65
+ stillLoading?: () => Promise<boolean>, loadingCapMs?: number): Promise<StartPathArrival>;
66
+ /**
67
+ * Send a tab somewhere and wait for the session that comes back.
68
+ *
69
+ * A navigation is a full page load: the session that issued it DIES and a successor connects with a
70
+ * new id. Every caller therefore has to wait for that successor rather than reuse the handle it
71
+ * already holds, and getting this wrong does not error — it leaves the caller talking to a session
72
+ * that will never answer again.
73
+ *
74
+ * Extracted so there is ONE of these rather than one per caller. `arriveAtStartPath` decides WHETHER
75
+ * to move and this decides how, which is also why the deliberate short-circuits live up there and
76
+ * not in here: a caller that has already decided it must move should not have to argue with them.
77
+ */
78
+ /**
79
+ * How a navigate ended: target, redirect, refusal (untouched tab), or no successor. `wait` is set
80
+ * when the page's loading earned it time past the budget.
81
+ */
82
+ export type NavigateOutcome = {
83
+ kind: 'arrived';
84
+ session: Session;
85
+ wait?: StartPageWait;
86
+ } | {
87
+ kind: 'redirected';
88
+ session: Session;
89
+ wait?: StartPageWait;
90
+ } | {
91
+ kind: 'refused';
92
+ } | {
93
+ kind: 'lost';
94
+ waitedMs: number;
95
+ stillLoading: boolean;
96
+ wait?: StartPageWait;
97
+ };
98
+ export declare function navigateAndAwait(sessions: SessionManager, session: {
99
+ id: string;
100
+ /** Optional because a session's URL is, and `carryReticleIdentity` already handles its absence. */
101
+ url?: string;
102
+ command(name: string, args?: Record<string, unknown>): Promise<CommandResult>;
103
+ }, destination: string, expectedPath: string, timeoutMs: number, clock?: ArrivalClock,
104
+ /** True when the destination is the page we are already on — see `arrivedSuccessor`. */
105
+ isReload?: boolean,
106
+ /** Whether the navigated page is still loading; absent when it cannot be asked. */
107
+ stillLoading?: () => Promise<boolean>, loadingCapMs?: number): Promise<NavigateOutcome>;
108
+ export {};