@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
@@ -1,15 +1,15 @@
1
1
  import { asFlowName, asProjectId, } from '@reticlehq/core';
2
- import { REDACTED_FILL } from './fields/flow-secret-field.js';
2
+ import { REDACTED_FILL, SECRET_NAME_ARG, secretEnvKey } from './fields/flow-secret-field.js';
3
3
  export { REDACTED_FILL, secretEnvKey } from './fields/flow-secret-field.js';
4
4
  import { safeProjectId } from './flow-result.js';
5
5
  import { changeInPlace } from './narrow-write.js';
6
6
  import { AnchorKind, DEGRADED_ANCHOR_ROLE, FLOW_FILE_VERSION, flowFileVersionFor, FlowErrorCode, FlowFileSchema, FlowStepTool, QueryBy, defaultIsSensitiveKey, } from '@reticlehq/core';
7
- import { ReticleTool } from '@reticlehq/core';
7
+ import { ReticleTool, flowJsonReplacer } from '@reticlehq/core';
8
8
  import { asRecord, asString } from '@reticlehq/core';
9
9
  import { applyHealChanges } from './heal.js';
10
10
  import { withLearnedSources } from './learned-sources.js';
11
11
  import { flowIntentGap, linkFlowIntent } from './flow-intent.js';
12
- import { journeyFingerprint, journeyName, mergeJourney, routeClaims } from './flow-journey.js';
12
+ import { journeyFingerprint, journeyName, mergeJourney, routeClaims, withinJourney, } from './flow-journey.js';
13
13
  import { IntentStore } from '../../memory/intent/intent-store.js';
14
14
  import { flowDir, flowParentDir, flowPath, reticleDirPaths, isValidFlowName, } from '../../memory/project/dir/reticle-dir.js';
15
15
  import { describeFlowZodFailure, parseFlowFileText } from './flow-expect-grammar.js';
@@ -76,8 +76,11 @@ export function anchorForStep(args) {
76
76
  if (by === QueryBy.ROLE && value !== undefined) {
77
77
  const name = asString(args['name']);
78
78
  if (name !== undefined && name.length > 0) {
79
- // The schema carries role + name only; provenance lives on the step, not the anchor.
80
- return { anchor: { kind: AnchorKind.ROLE, role: value, name }, degraded: false };
79
+ // Provenance lives on the step, not the anchor; the position among namesakes is identity.
80
+ const nth = args['nth'];
81
+ const of = args['of'];
82
+ const among = 'number' === typeof nth && 'number' === typeof of ? { nth, of } : {};
83
+ return { anchor: { kind: AnchorKind.ROLE, role: value, name, ...among }, degraded: false };
81
84
  }
82
85
  }
83
86
  if (by === QueryBy.COMPONENT) {
@@ -127,7 +130,32 @@ function redactSecretFill(anchor, args) {
127
130
  const field = anchorFieldName(anchor);
128
131
  if (field === undefined || !defaultIsSensitiveKey(field))
129
132
  return args;
130
- return { ...args, value: REDACTED_FILL };
133
+ // The variable that supplies it, beside the placeholder: the file alone says what to set.
134
+ return { ...args, value: REDACTED_FILL, [SECRET_NAME_ARG]: secretEnvKey(field) };
135
+ }
136
+ /**
137
+ * The recorded steps as they may be SHOWN: every credential fill carries the placeholder.
138
+ *
139
+ * The same rule the saved flow is written by, applied to what a tool hands back. `record stop`
140
+ * returned the compiled program verbatim, so the password a saved flow never contained went into
141
+ * the agent's transcript instead. The store keeps the real value — an in-session replay types it.
142
+ */
143
+ export function redactRecordedSteps(steps) {
144
+ return steps.map((step) => {
145
+ if (step.tool === ReticleTool.ACT_SEQUENCE && Array.isArray(step.args['steps'])) {
146
+ const subs = step.args['steps'].map((raw) => redactNormalizedArgs(asRecord(raw)));
147
+ return { ...step, args: { ...step.args, steps: subs } };
148
+ }
149
+ return { ...step, args: redactNormalizedArgs(step.args) };
150
+ });
151
+ }
152
+ /** One normalized act's args with its inner fill `args` redacted by the anchor it would save as. */
153
+ function redactNormalizedArgs(normalized) {
154
+ const inner = normalized['args'];
155
+ if ('object' !== typeof inner || null === inner)
156
+ return normalized;
157
+ const redacted = redactSecretFill(anchorForStep(normalized).anchor, asRecord(inner));
158
+ return redacted === inner ? normalized : { ...normalized, args: redacted };
131
159
  }
132
160
  /**
133
161
  * What the anchor CALLS the field it points at.
@@ -166,6 +194,8 @@ function buildStep(tool, anchor, action, args, degraded) {
166
194
  */
167
195
  export function recordedStepToFlowStep(step) {
168
196
  const out = anchoredStep(step);
197
+ if (step.timeoutMs !== undefined)
198
+ out.timeoutMs = step.timeoutMs;
169
199
  if (step.page !== undefined)
170
200
  out.page = step.page;
171
201
  if (step.endPage !== undefined && step.endPage !== step.page)
@@ -235,10 +265,17 @@ export class FlowStore {
235
265
  #fs;
236
266
  #root;
237
267
  #clock;
238
- constructor(fs, root, clock) {
268
+ #onWrote;
269
+ /**
270
+ * `onWrote` is told after a save lands, so cloud sync cycles on a new flow the way it does on a
271
+ * new run (`RunStore` takes the same callback). Without it a flow saved with no run behind it
272
+ * waited for the timer, and a daemon that exited first never sent it.
273
+ */
274
+ constructor(fs, root, clock, opts = {}) {
239
275
  this.#fs = fs;
240
276
  this.#root = root;
241
277
  this.#clock = clock;
278
+ this.#onWrote = opts.onWrote;
242
279
  }
243
280
  /**
244
281
  * The single byte-stable flow serializer: 2-space indent + one trailing newline. save,
@@ -247,7 +284,7 @@ export class FlowStore {
247
284
  */
248
285
  #serialize(flow) {
249
286
  const stamped = { ...flow, version: flowFileVersionFor(flow) };
250
- return `${JSON.stringify(stamped, null, JSON_INDENT)}\n`;
287
+ return `${JSON.stringify(stamped, flowJsonReplacer, JSON_INDENT)}\n`;
251
288
  }
252
289
  /**
253
290
  * Register the flow's business goal in the intent ledger and stamp the row's id onto the flow.
@@ -321,6 +358,7 @@ export class FlowStore {
321
358
  const flow = await this.#linkIntent(base);
322
359
  await this.#fs.mkdir(flowParentDir(this.#root, program.name, pid));
323
360
  await this.#fs.writeFile(flowPath(this.#root, program.name, pid), this.#serialize(flow));
361
+ this.#onWrote?.();
324
362
  return { ok: true, value: this.#summary(flow) };
325
363
  }
326
364
  /**
@@ -337,19 +375,40 @@ export class FlowStore {
337
375
  const pid = safeProjectId(projectId);
338
376
  const fresh = this.#build(program, undefined, pid);
339
377
  const saved = [];
340
- for (const name of (await this.list(pid)).filter((n) => n.startsWith(prefix))) {
378
+ const freshPrint = journeyFingerprint(fresh);
379
+ for (const name of await this.list(pid)) {
341
380
  const loaded = await this.load(name, pid);
342
- if (loaded.ok)
381
+ if (!loaded.ok)
382
+ continue;
383
+ if (name.startsWith(prefix))
343
384
  saved.push(loaded.value);
385
+ // The agent already saved this journey under its own name: one journey, one flow. A web drive
386
+ // saved its named flow and an automatic `drive-saved-<email>` beside it, every time.
387
+ else if (journeyFingerprint(loaded.value) === freshPrint) {
388
+ return { ok: true, value: this.#summary(loaded.value) };
389
+ }
344
390
  }
345
391
  const byPrint = new Map();
346
392
  for (const flow of saved) {
347
393
  const print = journeyFingerprint(flow);
348
394
  byPrint.set(print, [...(byPrint.get(print) ?? []), flow]);
349
395
  }
350
- const print = journeyFingerprint(fresh);
396
+ const print = freshPrint;
351
397
  const taken = new Map(saved.map((flow) => [flow.name, journeyFingerprint(flow)]));
352
- const named = { ...fresh, name: journeyName(fresh.name, print, taken) };
398
+ // The same name holding this journey driven with a step more or less: one file, the fuller drive.
399
+ const same = saved.find((flow) => flow.name === fresh.name && taken.get(flow.name) !== print);
400
+ if (same !== undefined && withinJourney(same, fresh))
401
+ return { ok: true, value: this.#summary(same) };
402
+ const extended = same !== undefined && withinJourney(fresh, same);
403
+ if (extended)
404
+ taken.delete(fresh.name);
405
+ const named = {
406
+ ...fresh,
407
+ ...(extended && fresh.intent === undefined && same.intent !== undefined
408
+ ? { intent: same.intent }
409
+ : {}),
410
+ name: journeyName(fresh.name, print, taken),
411
+ };
353
412
  byPrint.set(print, [...(byPrint.get(print) ?? []), named]);
354
413
  let result = named;
355
414
  for (const [groupPrint, group] of byPrint) {
@@ -367,6 +426,7 @@ export class FlowStore {
367
426
  if (groupPrint === print)
368
427
  result = merged;
369
428
  }
429
+ this.#onWrote?.();
370
430
  return { ok: true, value: this.#summary(result) };
371
431
  }
372
432
  /** Write a flow where it already lives, or into its project's directory when it is new. */
@@ -401,6 +461,7 @@ export class FlowStore {
401
461
  const valid = await this.#linkIntent(parsed.data);
402
462
  await this.#fs.mkdir(flowParentDir(this.#root, asFlowName(valid.name), pid));
403
463
  await this.#fs.writeFile(flowPath(this.#root, asFlowName(valid.name), pid), this.#serialize(valid));
464
+ this.#onWrote?.();
404
465
  return { ok: true, value: this.#summary(valid) };
405
466
  }
406
467
  /**
@@ -419,6 +480,7 @@ export class FlowStore {
419
480
  resolvePath: (n, p) => this.#resolveReadPath(asFlowName(n), p),
420
481
  write: (path, contents) => this.#fs.writeFile(path, contents),
421
482
  serialize: (flow) => this.#serialize(flow),
483
+ readRaw: (path) => this.#fs.readFile(path),
422
484
  }, name, projectId, change);
423
485
  }
424
486
  /** Write back only what a replay LEARNED. See `#changeInPlace` for why it is not `saveFlow`. */
@@ -12,7 +12,8 @@ import { replayFlow } from './flow-replay.js';
12
12
  import { applyHealChanges, collectProposals } from './heal.js';
13
13
  import { healPrecondition } from './heal-precondition.js';
14
14
  import { assertSuccess, dynamicTestids, successLabel } from './flow-success.js';
15
- import { flowErrorMessage, sessionProjectId } from './flow-replay-run.js';
15
+ import { flowErrorMessage } from './flow-replay-run.js';
16
+ import { sessionTarget } from '../../memory/project/session-root.js';
16
17
  import { flowsForSession } from './flow-store-for-session.js';
17
18
  const HEAL_MESSAGES = {
18
19
  NOTHING: 'nothing to heal — every anchor resolved on replay',
@@ -48,8 +49,9 @@ function toChange(proposal) {
48
49
  export async function healFlow(deps, args) {
49
50
  const name = asString(args['flowName']) ?? '';
50
51
  const apply = true === args['apply'];
51
- const projectId = sessionProjectId(deps, asString(args['sessionId']));
52
- const loaded = await flowsForSession(deps, projectId).flows.load(name, projectId);
52
+ const target = sessionTarget(deps, asString(args['sessionId']));
53
+ const { projectId } = target;
54
+ const loaded = await flowsForSession(deps, target).flows.load(name, projectId);
53
55
  if (!loaded.ok) {
54
56
  return {
55
57
  name,
@@ -163,7 +165,7 @@ export async function healFlow(deps, args) {
163
165
  }
164
166
  // Healing WRITES, so it must land where the load came from — a heal that read the app's flow and
165
167
  // wrote the daemon's copy would silently fork the two.
166
- const written = await flowsForSession(deps, projectId).flows.heal(name, proposals.map(toChange), projectId);
168
+ const written = await flowsForSession(deps, target).flows.heal(name, proposals.map(toChange), projectId);
167
169
  if (!written.ok) {
168
170
  return {
169
171
  name,
@@ -25,7 +25,14 @@ export interface NarrowWritePort {
25
25
  resolvePath: (name: string, projectId?: ProjectId) => Promise<string | null>;
26
26
  write: (path: string, contents: string) => Promise<void>;
27
27
  serialize: (flow: FlowFile) => string;
28
+ /** The file as it is on disk, so a change lands in it and nothing else moves. */
29
+ readRaw?: (path: string) => Promise<string>;
28
30
  }
31
+ /**
32
+ * `raw` with only what changed between `before` and `after` applied, everything else as written:
33
+ * its key order, its fields the reader fills in by default, its own spelling. Pure.
34
+ */
35
+ export declare function withChangesOnly(raw: unknown, before: unknown, after: unknown): unknown;
29
36
  export declare function changeInPlace<T>(port: NarrowWritePort, name: string, projectId: ProjectId | undefined, change: (flow: FlowFile) => {
30
37
  next: FlowFile;
31
38
  value: T;
@@ -2,6 +2,28 @@ import { FlowErrorCode, FlowFileSchema } from '@reticlehq/core';
2
2
  import { describeFlowZodFailure } from './flow-expect-grammar.js';
3
3
  import { isValidFlowName } from '../../memory/project/dir/reticle-dir.js';
4
4
  import { safeProjectId } from './flow-result.js';
5
+ const isPlain = (v) => 'object' === typeof v && null !== v && !Array.isArray(v);
6
+ const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
7
+ /**
8
+ * `raw` with only what changed between `before` and `after` applied, everything else as written:
9
+ * its key order, its fields the reader fills in by default, its own spelling. Pure.
10
+ */
11
+ export function withChangesOnly(raw, before, after) {
12
+ if (Array.isArray(raw) && Array.isArray(before) && Array.isArray(after))
13
+ return raw.length === before.length && before.length === after.length
14
+ ? raw.map((item, i) => withChangesOnly(item, before[i], after[i]))
15
+ : after;
16
+ if (!isPlain(raw) || !isPlain(before) || !isPlain(after))
17
+ return after;
18
+ const out = { ...raw };
19
+ for (const key of Object.keys(after))
20
+ if (!same(after[key], before[key]))
21
+ out[key] = key in raw ? withChangesOnly(raw[key], before[key], after[key]) : after[key];
22
+ for (const key of Object.keys(before))
23
+ if (!(key in after))
24
+ delete out[key];
25
+ return out;
26
+ }
5
27
  export async function changeInPlace(port, name, projectId, change) {
6
28
  if (!isValidFlowName(name))
7
29
  return { ok: false, code: FlowErrorCode.INVALID_NAME };
@@ -21,6 +43,19 @@ export async function changeInPlace(port, name, projectId, change) {
21
43
  detail: describeFlowZodFailure(parsed.error),
22
44
  };
23
45
  }
24
- await port.write(path, port.serialize(parsed.data));
46
+ // A replay that learned nothing new leaves a committed file alone: every replay used to rewrite
47
+ // it (keys reordered, defaults written in), and `git status` called it modified.
48
+ if (port.serialize(parsed.data) === port.serialize(loaded.value))
49
+ return { ok: true, value };
50
+ let raw;
51
+ try {
52
+ raw = JSON.parse((await port.readRaw?.(path)) ?? 'null');
53
+ }
54
+ catch {
55
+ raw = null;
56
+ }
57
+ await port.write(path, isPlain(raw)
58
+ ? `${JSON.stringify(withChangesOnly(raw, loaded.value, parsed.data), null, 2)}\n`
59
+ : port.serialize(parsed.data));
25
60
  return { ok: true, value };
26
61
  }
@@ -31,17 +31,17 @@ export declare const FlakeFileSchema: z.ZodObject<{
31
31
  fails: number;
32
32
  }>>;
33
33
  }, "strip", z.ZodTypeAny, {
34
- version: 1;
35
34
  flows: Record<string, {
36
35
  runs: number;
37
36
  fails: number;
38
37
  }>;
39
- }, {
40
38
  version: 1;
39
+ }, {
41
40
  flows: Record<string, {
42
41
  runs: number;
43
42
  fails: number;
44
43
  }>;
44
+ version: 1;
45
45
  }>;
46
46
  export declare function emptyRecord(): FlakeRecord;
47
47
  /** Accrue one unchanged-code replay outcome. */
@@ -27,6 +27,19 @@ function recordingRouteOf(pathname, hash = '') {
27
27
  return routePathOf(0 === pathname.length ? '/' : pathname, fragment);
28
28
  return pathname;
29
29
  }
30
+ /**
31
+ * A startPath as a page key: its query dropped, hash kept. A startPath keeps the app's query so
32
+ * replay starts on the filtered page (#1411), but a ROUTE_CHANGE contributes only pathname and
33
+ * hash, so `/products?scope=X` then `/checkout` then `/products` must compare the first and last
34
+ * as one page or the backtrack goes unseen.
35
+ */
36
+ function pageKeyOf(startPath) {
37
+ const hashAt = startPath.indexOf('#');
38
+ const queryAt = startPath.indexOf('?');
39
+ if (queryAt < 0 || (hashAt >= 0 && queryAt > hashAt))
40
+ return startPath;
41
+ return startPath.slice(0, queryAt) + (hashAt >= 0 ? startPath.slice(hashAt) : '');
42
+ }
30
43
  function collapseConsecutive(routes) {
31
44
  const out = [];
32
45
  for (const route of routes) {
@@ -60,7 +73,7 @@ export function recordingBacktrackWarning(routes) {
60
73
  export function routesFromRecording(startPath, events) {
61
74
  const raw = [];
62
75
  if (undefined !== startPath)
63
- raw.push(recordingRouteOf(startPath));
76
+ raw.push(recordingRouteOf(pageKeyOf(startPath)));
64
77
  for (const event of events) {
65
78
  if (EventType.ROUTE_CHANGE !== event.type)
66
79
  continue;
@@ -7,6 +7,8 @@ export interface RecordedStep {
7
7
  args: Record<string, unknown>;
8
8
  /** false if any ref could not be normalized to a testid (replay only valid in-session). */
9
9
  stable: boolean;
10
+ /** The caller's per-step wait budget, when one was explicitly provided. */
11
+ timeoutMs?: number;
10
12
  /** Optional post-condition annotation carried into the on-disk flow's expect. */
11
13
  expect?: Predicate;
12
14
  /**
@@ -27,18 +29,41 @@ export interface RecordedStep {
27
29
  * `invoke` first and treats the step as a call.
28
30
  */
29
31
  invoke?: string;
32
+ /**
33
+ * Network mocks were active on this step's tab when it ran. RECORDER-INTERNAL, ambient tape only,
34
+ * like `route`: a journey that ran against mocked responses replays against the real backend,
35
+ * so it is not auto-saved (#1459).
36
+ */
37
+ mocked?: true;
30
38
  /** The page this step ran on. Written to the saved step (unlike `route`, which cuts journeys). */
31
39
  page?: string;
32
40
  /** The page it ended on once it settled — see `markEnded`. */
33
41
  endPage?: string;
34
42
  /** Why the agent took this step: the `intent` it declared on the action. Names the saved flow. */
35
43
  intent?: string;
44
+ /**
45
+ * Why a consequence this step PROVED is not in the flow: the flow file could not express it (a
46
+ * session ref such as `e12` means nothing on a later page). Said at stop, so a weaker flow is
47
+ * never saved silently.
48
+ */
49
+ unkeptExpect?: string;
36
50
  }
37
51
  interface ActiveRecording {
38
52
  cursor: number;
53
+ /**
54
+ * The session (tab) that started it. Only that session's steps join it: one daemon serves every
55
+ * agent and app on the machine, and capturing into every open recording put a click from an
56
+ * unrelated app into somebody else's saved flow (#988). Absent: takes every session's steps.
57
+ */
58
+ session?: string;
39
59
  steps: RecordedStep[];
40
60
  /** The route the journey began on. See CompiledProgram.startPath. */
41
61
  startPath?: string;
62
+ /**
63
+ * The document the tab was on at start. A full-page load makes a new one even when the SDK keeps
64
+ * its session id, and its clock is from a different connection, so this is how stop tells (#1411).
65
+ */
66
+ document?: string;
42
67
  /**
43
68
  * For each recording that was ALREADY in flight when this one started, how many steps it had.
44
69
  *
@@ -89,9 +114,20 @@ export declare const INVOKE_TOOL: string;
89
114
  * buffer.
90
115
  */
91
116
  export declare const AMBIENT_RECORDING = "__ambient__";
117
+ /**
118
+ * One ambient tape per tab. It was one for the whole daemon, so a drive in ANOTHER app (the console
119
+ * beside the repo's own app) was cut into a flow and saved into this repo's committed `flows/`, and
120
+ * synced to its project. A tape now holds one tab's steps, and that tab's end takes only its own.
121
+ */
122
+ export declare const ambientRecordingOf: (session: string | undefined) => string;
123
+ /** Whether a recording is an ambient tape: the daemon's own, never one somebody opened. */
124
+ export declare const isAmbient: (name: string) => boolean;
92
125
  export declare class RecordingStore {
93
126
  #private;
94
- start(name: string, cursor: number, startPath?: string): void;
127
+ private readonly byHarness;
128
+ /** `byHarness`: whether the step being captured was driven by the Harness, which tapes its own. */
129
+ constructor(byHarness?: () => boolean);
130
+ start(name: string, cursor: number, startPath?: string, session?: string, document?: string): void;
95
131
  isRecording(name: string): boolean;
96
132
  /**
97
133
  * Number of steps captured so far in the named ACTIVE recording (0 if it
@@ -112,7 +148,12 @@ export declare class RecordingStore {
112
148
  * Opened lazily on the first step rather than in the constructor: a store that never records
113
149
  * anything should not carry an empty tape, and "did anything happen at all" stays answerable.
114
150
  */
115
- capture(step: RecordedStep, route?: string): void;
151
+ /**
152
+ * Whether a tab has network mocks installed from now on. Each ambient step on it is marked while
153
+ * they are, so the journey it belongs to is not auto-saved as a flow (#1459).
154
+ */
155
+ markMocked(session: string | undefined, active: boolean): void;
156
+ capture(step: RecordedStep, route?: string, session?: string): void;
116
157
  /**
117
158
  * Add a consequence to the last captured step of every active recording.
118
159
  *
@@ -120,20 +161,31 @@ export declare class RecordingStore {
120
161
  * reached the recorder — only the act tools called `capture` — so the flow kept the click and lost
121
162
  * the proof. What the step already declared is kept; the new check joins it under `allOf`.
122
163
  */
123
- attachExpect(expect: Predicate): void;
164
+ attachExpect(expect: Predicate, session?: string): void;
124
165
  /**
125
166
  * A navigation happened. Navigating records no step, so until the next one is captured, a check
126
167
  * proved now is about the page the navigation opened, not about the last step — and kept on that
127
168
  * step, replay would ask it right after the click, of a page it was never true on.
128
169
  */
129
170
  markNavigated(): void;
171
+ /**
172
+ * Take the expectation off the ambient tape's last step, because the verdict on it came back no.
173
+ *
174
+ * A step is captured at dispatch, before anything is judged, so a claim that turned out false is
175
+ * already on the tape as that step's `expect`. Cut into a journey it becomes a flow that is red for
176
+ * ever, on an expectation nobody but the agent's wrong guess made. The failure is not lost: it is
177
+ * filed as a capsule, the artifact built for "this should hold and does not". The ACTION stays,
178
+ * since the steps after it ran on the page it produced. A recording somebody opened deliberately
179
+ * is left as they drove it.
180
+ */
181
+ unassertLast(): void;
130
182
  /**
131
183
  * The page the step just captured ended on, once its action settled.
132
184
  *
133
185
  * Fills only a step that has none, so calling it after an action that captured nothing leaves the
134
186
  * previous step's own answer alone.
135
187
  */
136
- markEnded(page: string | undefined): void;
188
+ markEnded(page: string | undefined, session?: string): void;
137
189
  /**
138
190
  * Returns the active recording (cursor + steps) and clears it, or undefined if not recording.
139
191
  *
@@ -150,6 +202,8 @@ export declare class RecordingStore {
150
202
  saveCompiled(program: CompiledProgram): void;
151
203
  getCompiled(name: string): CompiledProgram | undefined;
152
204
  active(): string[];
205
+ /** The ambient tape of one tab (or of steps no tab named), taken: what its session end saves. */
206
+ takeAmbient(session: string | undefined): ActiveRecording | undefined;
153
207
  /**
154
208
  * Names of recordings that have been STOPPED and compiled.
155
209
  *
@@ -20,6 +20,14 @@ export const INVOKE_TOOL = FlowStepTool.INVOKE;
20
20
  * buffer.
21
21
  */
22
22
  export const AMBIENT_RECORDING = '__ambient__';
23
+ /**
24
+ * One ambient tape per tab. It was one for the whole daemon, so a drive in ANOTHER app (the console
25
+ * beside the repo's own app) was cut into a flow and saved into this repo's committed `flows/`, and
26
+ * synced to its project. A tape now holds one tab's steps, and that tab's end takes only its own.
27
+ */
28
+ export const ambientRecordingOf = (session) => session === undefined ? AMBIENT_RECORDING : `${AMBIENT_RECORDING}:${session}`;
29
+ /** Whether a recording is an ambient tape: the daemon's own, never one somebody opened. */
30
+ export const isAmbient = (name) => AMBIENT_RECORDING === name || name.startsWith(`${AMBIENT_RECORDING}:`);
23
31
  /**
24
32
  * How long a journey the ambient tape will hold.
25
33
  *
@@ -29,21 +37,36 @@ export const AMBIENT_RECORDING = '__ambient__';
29
37
  */
30
38
  const AMBIENT_STEP_CAP = 400;
31
39
  export class RecordingStore {
40
+ byHarness;
32
41
  #active = new Map();
33
42
  #compiled = new Map();
43
+ /** The ambient tape the last step went on: the one a refuted claim is taken off. */
44
+ #lastAmbient;
34
45
  /** A navigation came after the last captured step — see markNavigated. */
35
46
  #navigatedSinceStep = false;
36
- start(name, cursor, startPath) {
47
+ /** Tabs with network mocks installed now, keyed by session ('' for none named). See markMocked. */
48
+ #mocked = new Set();
49
+ /** `byHarness`: whether the step being captured was driven by the Harness, which tapes its own. */
50
+ constructor(byHarness = () => false) {
51
+ this.byHarness = byHarness;
52
+ }
53
+ start(name, cursor, startPath, session, document) {
37
54
  const openedOver = new Map();
38
- for (const [outer, rec] of this.#active)
55
+ for (const [outer, rec] of this.#targets(session))
39
56
  openedOver.set(outer, rec.steps.length);
40
57
  this.#active.set(name, {
41
58
  cursor,
42
59
  steps: [],
43
60
  openedOver,
44
61
  ...(startPath === undefined ? {} : { startPath }),
62
+ ...(session === undefined ? {} : { session }),
63
+ ...(document === undefined ? {} : { document }),
45
64
  });
46
65
  }
66
+ /** The open recordings a step from `session` belongs to. See ActiveRecording.session. */
67
+ #targets(session) {
68
+ return [...this.#active].filter(([, rec]) => rec.session === undefined || session === undefined || rec.session === session);
69
+ }
47
70
  isRecording(name) {
48
71
  return this.#active.has(name);
49
72
  }
@@ -68,23 +91,44 @@ export class RecordingStore {
68
91
  * Opened lazily on the first step rather than in the constructor: a store that never records
69
92
  * anything should not carry an empty tape, and "did anything happen at all" stays answerable.
70
93
  */
71
- capture(step, route) {
94
+ /**
95
+ * Whether a tab has network mocks installed from now on. Each ambient step on it is marked while
96
+ * they are, so the journey it belongs to is not auto-saved as a flow (#1459).
97
+ */
98
+ markMocked(session, active) {
99
+ if (active)
100
+ this.#mocked.add(session ?? '');
101
+ else
102
+ this.#mocked.delete(session ?? '');
103
+ }
104
+ capture(step, route, session) {
72
105
  this.#navigatedSinceStep = false;
73
- if (!this.#active.has(AMBIENT_RECORDING)) {
74
- this.#active.set(AMBIENT_RECORDING, {
106
+ const mocked = this.#mocked.has(session ?? '');
107
+ const ambient = ambientRecordingOf(session);
108
+ if (!this.#active.has(ambient)) {
109
+ this.#active.set(ambient, {
75
110
  cursor: 0,
76
111
  steps: [],
77
112
  openedOver: new Map(),
113
+ ...(session === undefined ? {} : { session }),
78
114
  });
79
115
  }
80
- for (const [name, rec] of this.#active) {
116
+ this.#lastAmbient = ambient;
117
+ for (const [name, rec] of this.#targets(session)) {
118
+ // Another tab's tape is that tab's journey, whatever else this step belongs to.
119
+ if (isAmbient(name) && name !== ambient)
120
+ continue;
81
121
  // The ambient tape is opened by the system and closed by nobody, so it is the one recording
82
122
  // with no human deciding when it has seen enough. Bounded here rather than left to grow for
83
123
  // the length of a daemon's life. Appending STOPS at the cap instead of dropping the oldest: a
84
124
  // flow replays from its FIRST step, so a tape missing its beginning is not a shorter journey,
85
125
  // it is a different one that starts in a state nothing established. A recording somebody
86
126
  // opened on purpose is not capped — they said when it starts and they say when it stops.
87
- if (AMBIENT_RECORDING === name && rec.steps.length >= AMBIENT_STEP_CAP)
127
+ if (isAmbient(name) && rec.steps.length >= AMBIENT_STEP_CAP)
128
+ continue;
129
+ // The Harness saves its own recordings. Taping its steps too saved every drive twice: once as
130
+ // the Harness's flow and again, at session end, as a `drive-*` copy with a guessed name.
131
+ if (isAmbient(name) && this.byHarness())
88
132
  continue;
89
133
  // A step nobody marked ended where the next one began.
90
134
  const previous = rec.steps.at(-1);
@@ -94,7 +138,13 @@ export class RecordingStore {
94
138
  // The route rides on the AMBIENT tape only: a recording somebody opened deliberately is
95
139
  // already one journey by construction, and stamping a route on its steps would change what a
96
140
  // deliberate recording contains.
97
- rec.steps.push(AMBIENT_RECORDING === name && route !== undefined ? { ...step, route } : step);
141
+ rec.steps.push(isAmbient(name) && (route !== undefined || mocked)
142
+ ? {
143
+ ...step,
144
+ ...(route === undefined ? {} : { route }),
145
+ ...(mocked ? { mocked: true } : {}),
146
+ }
147
+ : step);
98
148
  }
99
149
  }
100
150
  /**
@@ -104,13 +154,20 @@ export class RecordingStore {
104
154
  * reached the recorder — only the act tools called `capture` — so the flow kept the click and lost
105
155
  * the proof. What the step already declared is kept; the new check joins it under `allOf`.
106
156
  */
107
- attachExpect(expect) {
157
+ attachExpect(expect, session) {
108
158
  if (this.#navigatedSinceStep)
109
159
  return;
110
- for (const rec of this.#active.values()) {
160
+ const mocked = this.#mocked.has(session ?? '');
161
+ for (const [name, rec] of this.#targets(session)) {
162
+ if (isAmbient(name) && name !== ambientRecordingOf(session))
163
+ continue;
111
164
  const last = rec.steps.at(-1);
112
165
  if (last === undefined)
113
166
  continue;
167
+ // A proof read while mocks are active rests on mocked responses even when the act before it
168
+ // ran unmocked, so the ambient step it joins is marked too (#1459).
169
+ if (mocked && isAmbient(name))
170
+ last.mocked = true;
114
171
  const held = last.expect;
115
172
  last.expect =
116
173
  held === undefined
@@ -128,16 +185,36 @@ export class RecordingStore {
128
185
  markNavigated() {
129
186
  this.#navigatedSinceStep = true;
130
187
  }
188
+ /**
189
+ * Take the expectation off the ambient tape's last step, because the verdict on it came back no.
190
+ *
191
+ * A step is captured at dispatch, before anything is judged, so a claim that turned out false is
192
+ * already on the tape as that step's `expect`. Cut into a journey it becomes a flow that is red for
193
+ * ever, on an expectation nobody but the agent's wrong guess made. The failure is not lost: it is
194
+ * filed as a capsule, the artifact built for "this should hold and does not". The ACTION stays,
195
+ * since the steps after it ran on the page it produced. A recording somebody opened deliberately
196
+ * is left as they drove it.
197
+ */
198
+ unassertLast() {
199
+ const tape = this.#lastAmbient === undefined ? undefined : this.#active.get(this.#lastAmbient);
200
+ const last = tape?.steps.at(-1);
201
+ if (tape === undefined || last === undefined || last.expect === undefined)
202
+ return;
203
+ const { expect: _dropped, ...kept } = last;
204
+ tape.steps[tape.steps.length - 1] = kept;
205
+ }
131
206
  /**
132
207
  * The page the step just captured ended on, once its action settled.
133
208
  *
134
209
  * Fills only a step that has none, so calling it after an action that captured nothing leaves the
135
210
  * previous step's own answer alone.
136
211
  */
137
- markEnded(page) {
212
+ markEnded(page, session) {
138
213
  if (page === undefined)
139
214
  return;
140
- for (const rec of this.#active.values()) {
215
+ for (const [name, rec] of this.#targets(session)) {
216
+ if (isAmbient(name) && name !== ambientRecordingOf(session))
217
+ continue;
141
218
  const last = rec.steps.at(-1);
142
219
  if (last !== undefined && last.endPage === undefined)
143
220
  last.endPage = page;
@@ -182,7 +259,12 @@ export class RecordingStore {
182
259
  return this.#compiled.get(name);
183
260
  }
184
261
  active() {
185
- return [...this.#active.keys()];
262
+ // One tab's tape is that tab's: the list names what somebody opened, and the plain tape as before.
263
+ return [...this.#active.keys()].filter((name) => !name.startsWith(`${AMBIENT_RECORDING}:`));
264
+ }
265
+ /** The ambient tape of one tab (or of steps no tab named), taken: what its session end saves. */
266
+ takeAmbient(session) {
267
+ return this.stop(ambientRecordingOf(session));
186
268
  }
187
269
  /**
188
270
  * Names of recordings that have been STOPPED and compiled.