@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
@@ -0,0 +1,137 @@
1
+ /**
2
+ * The resume block: what an agent needs back after its context was compacted, in under ~1k tokens.
3
+ *
4
+ * Reticle holds the memory, never the agent. After a compaction the agent's copy of the session is a
5
+ * summary written by a model, and a summary is exactly where "the checkout step failed" becomes
6
+ * "checkout was tested". So this is folded from the daemon's OWN records — the journal on disk, the
7
+ * intent ledger, the declared request, the app notes — and a claim whose latest verdict is not `yes`
8
+ * is listed as failed or not proved, however the agent remembers it.
9
+ *
10
+ * Served two ways from this one fold: `reticle_context { compact: true }` over MCP, and
11
+ * `reticle context --compact` at the terminal (no daemon needed), which a Claude Code SessionStart
12
+ * hook with matcher `compact` prints straight back into the fresh context.
13
+ */
14
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
15
+ import { join } from 'node:path';
16
+ import { JournalVerdictEffectSchema, ReticleDir, Verified, } from '@reticlehq/core';
17
+ import { PromptContextSchema } from '@reticlehq/core/artifacts';
18
+ import { IntentStore } from '../../memory/intent/intent-store.js';
19
+ import { readAppNotes } from '../../surface/tools/agent/app-notes.js';
20
+ /** How many claims of each state are named before the rest are counted. Bounds the block. */
21
+ const SHOWN = 5;
22
+ /** Any one line, capped: the block must stay well under ~1k tokens whatever the journal holds. */
23
+ const LINE_MAX = 160;
24
+ /** The primer, short form. The full one lives in the agent's rules file (CLAUDE.md / AGENTS.md). */
25
+ export const RESUME_PRIMER = [
26
+ 'Only verified:"yes" passes; "unknown" and "no-fault" are neither pass nor fail.',
27
+ 'Declare the consequence before acting: reticle_act_and_wait { target, action, until }. Several steps: one reticle_act { steps: [{ target, action, expect }] }, last expect = end state.',
28
+ 'Text is exact-case (ignoreCase only when case does not matter); target by testid or role+name. On a failure read expected/observed/nearest first; never weaken a check.',
29
+ ];
30
+ function cap(text) {
31
+ const one = text.replace(/\s+/g, ' ').trim();
32
+ return one.length > LINE_MAX ? `${one.slice(0, LINE_MAX - 1)}…` : one;
33
+ }
34
+ function listed(label, items) {
35
+ if (0 === items.length)
36
+ return [];
37
+ const shown = items.slice(-SHOWN).map((item) => ` - ${cap(item)}`);
38
+ const more = items.length - Math.min(items.length, SHOWN);
39
+ return [
40
+ `${label} (${String(items.length)}):`,
41
+ ...(more > 0 ? [` … ${String(more)} earlier`] : []),
42
+ ...shown,
43
+ ];
44
+ }
45
+ /** Each claim's LATEST verdict, in the order the claims were first made. */
46
+ export function latestVerdicts(actions) {
47
+ const latest = new Map();
48
+ for (const action of actions) {
49
+ const parsed = JournalVerdictEffectSchema.safeParse(action.effect);
50
+ if (!parsed.success)
51
+ continue;
52
+ const { claim, verified, observed } = parsed.data;
53
+ latest.set(claim, { claim, verified, ...(observed === undefined ? {} : { observed }) });
54
+ }
55
+ return [...latest.values()];
56
+ }
57
+ /** The resume block, as lines. */
58
+ export function resumeLines(facts) {
59
+ const verdicts = latestVerdicts(facts.actions);
60
+ const failed = verdicts
61
+ .filter((v) => Verified.NO === v.verified)
62
+ .map((v) => (v.observed === undefined ? v.claim : `${v.claim} — saw: ${v.observed}`));
63
+ const unproved = verdicts
64
+ .filter((v) => Verified.YES !== v.verified && Verified.NO !== v.verified)
65
+ .map((v) => `${v.claim} (${v.verified})`);
66
+ const held = verdicts.filter((v) => Verified.YES === v.verified).map((v) => v.claim);
67
+ const where = [
68
+ facts.sessionId === undefined ? undefined : `tab ${facts.sessionId}`,
69
+ facts.route === undefined ? undefined : `on ${facts.route}`,
70
+ facts.cursor === undefined ? undefined : `cursor ${String(facts.cursor)}`,
71
+ ].filter((p) => p !== undefined);
72
+ return [
73
+ `Reticle resume${0 === where.length ? '' : ` — ${where.join(', ')}`}. This is the daemon's record, not a summary: trust it over your memory.`,
74
+ ...(facts.request === undefined ? [] : [`Asked: ${cap(facts.request)}`]),
75
+ `Claims: ${String(held.length)} proved · ${String(failed.length)} failed · ${String(unproved.length)} not proved.`,
76
+ ...listed('FAILED — not done', failed),
77
+ ...listed('NOT PROVED — not done', unproved),
78
+ ...listed('Proved', held),
79
+ ...listed('Intents still owed', facts.openIntents),
80
+ ...listed('App notes (hints for targeting, never evidence)', facts.notes),
81
+ 'Rules:',
82
+ ...RESUME_PRIMER.map((line) => ` - ${line}`),
83
+ ];
84
+ }
85
+ /** How long a declared request counts as this session's task (matches next-step.ts). */
86
+ const REQUEST_FRESH_MS = 6 * 60 * 60 * 1000;
87
+ /** The session whose action ledger was written most recently, if any. */
88
+ export function newestSessionId(root) {
89
+ const dir = join(root, ReticleDir.SESSIONS_SUBDIR);
90
+ if (!existsSync(dir))
91
+ return undefined;
92
+ let newest;
93
+ for (const id of readdirSync(dir)) {
94
+ const ledger = join(dir, id, ReticleDir.JOURNAL_ACTIONS_FILE);
95
+ if (!existsSync(ledger))
96
+ continue;
97
+ const at = statSync(ledger).mtimeMs;
98
+ if (newest === undefined || at > newest.at)
99
+ newest = { id, at };
100
+ }
101
+ return newest?.id;
102
+ }
103
+ /** The user's request, when one was declared recently enough to be this session's. */
104
+ export function recentRequest(root, now) {
105
+ try {
106
+ const parsed = PromptContextSchema.safeParse(JSON.parse(readFileSync(join(root, ReticleDir.REQUEST_FILE), 'utf8')));
107
+ if (!parsed.success || parsed.data.request === undefined)
108
+ return undefined;
109
+ const at = parsed.data.at;
110
+ return at !== undefined && now - at <= REQUEST_FRESH_MS ? parsed.data.request : undefined;
111
+ }
112
+ catch {
113
+ return undefined;
114
+ }
115
+ }
116
+ /**
117
+ * Everything the resume block needs, read from disk — no daemon, which is what a SessionStart hook
118
+ * has the moment after a compaction. The caller supplies the journal reader: the MCP tool holds the
119
+ * live journal, the CLI reads the newest session's ledger.
120
+ */
121
+ export async function resumeFromDisk(input) {
122
+ const sessionId = input.sessionId ?? newestSessionId(input.root);
123
+ // Asked even with no session on disk: a caller holding the live journal answers from it.
124
+ const actions = await input.readActions(sessionId ?? '').catch(() => []);
125
+ const open = await new IntentStore(input.fs, input.root, { now: () => input.now })
126
+ .open()
127
+ .catch(() => []);
128
+ return resumeLines({
129
+ actions,
130
+ openIntents: open.map((intent) => intent.statement),
131
+ request: recentRequest(input.root, input.now),
132
+ sessionId,
133
+ route: input.route,
134
+ cursor: input.cursor,
135
+ notes: readAppNotes(input.root),
136
+ });
137
+ }
@@ -14,6 +14,7 @@ import { boundFlowName, RunFlowStatus, VerifyPhase, } from '@reticlehq/core';
14
14
  import { buildVerificationRun, } from './artifact/build-verification-run.js';
15
15
  import { mapReplayToFlowResult } from './artifact/replay-mapping.js';
16
16
  import { buildRepairPackets } from './repair-prompt.js';
17
+ import { withShotRun } from './default-run-id.js';
17
18
  import { buildRisks, classifyChangedFiles, } from './risk-classify.js';
18
19
  export class ReticleRunner {
19
20
  #port;
@@ -44,6 +45,8 @@ export class ReticleRunner {
44
45
  // Announced BEFORE the loop: "step 3" without "of 12" does not answer the only question a
45
46
  // person watching is actually asking, which is whether to keep waiting.
46
47
  emit({ phase: VerifyPhase.FLOWS_FOUND, total, at: this.#port.now() });
48
+ // Minted first, so each replayed step's screenshot is filed under the run it belongs to.
49
+ const runId = this.#port.newRunId();
47
50
  const replays = [];
48
51
  const flows = [];
49
52
  for (const [index, name] of names.entries()) {
@@ -55,7 +58,7 @@ export class ReticleRunner {
55
58
  name: boundFlowName(name),
56
59
  at: start,
57
60
  });
58
- const replay = await this.#port.replayFlow(name);
61
+ const replay = await withShotRun(runId, () => this.#port.replayFlow(name));
59
62
  replays.push(replay);
60
63
  const mapped = mapReplayToFlowResult(replay, this.#port.now() - start);
61
64
  flows.push(mapped);
@@ -75,7 +78,7 @@ export class ReticleRunner {
75
78
  const risks = buildRisks(changedFiles, opts.policy);
76
79
  const failurePackets = buildRepairPackets(replays);
77
80
  const input = {
78
- runId: this.#port.newRunId(),
81
+ runId,
79
82
  durationMs: flows.reduce((sum, f) => sum + f.durationMs, 0),
80
83
  profile: opts.profile,
81
84
  project: opts.project,
@@ -85,7 +88,14 @@ export class ReticleRunner {
85
88
  flows,
86
89
  checks: [],
87
90
  risks,
88
- evidence: { consoleErrors: [], networkAnomalies: [], stateAssertions: [], timeline: [] },
91
+ // What the replay windows saw. An empty list written here regardless read as a clean
92
+ // console on a run whose steps had counted errors (#1344).
93
+ evidence: {
94
+ consoleErrors: replays.flatMap((r) => r.steps.flatMap((step) => step.consoleErrors ?? [])),
95
+ networkAnomalies: [],
96
+ stateAssertions: [],
97
+ timeline: [],
98
+ },
89
99
  ...(failurePackets.length > 0 ? { repair: { failurePackets } } : {}),
90
100
  };
91
101
  const run = buildVerificationRun(input, () => this.#port.now());
@@ -8,4 +8,8 @@ import type { ToolDeps } from '../../surface/tools/tool-kit.js';
8
8
  import type { RunnerPort } from './reticle-runner.js';
9
9
  export { defaultRunId } from './default-run-id.js';
10
10
  /** Wire a RunnerPort to the live session. Pass sessionId to disambiguate when several tabs are open. */
11
- export declare function createRunnerPort(deps: ToolDeps, sessionId?: string): RunnerPort;
11
+ export declare function createRunnerPort(deps: ToolDeps, sessionId?: string,
12
+ /** `reticle verify --confirm-dangerous`: this run acknowledges the steps held as destructive. */
13
+ opts?: {
14
+ confirmDangerous?: boolean;
15
+ }): RunnerPort;
@@ -8,10 +8,16 @@ import { replayAndLearn } from '../../language/flows/flow-learning.js';
8
8
  import { defaultRunId } from './default-run-id.js';
9
9
  export { defaultRunId } from './default-run-id.js';
10
10
  /** Wire a RunnerPort to the live session. Pass sessionId to disambiguate when several tabs are open. */
11
- export function createRunnerPort(deps, sessionId) {
11
+ export function createRunnerPort(deps, sessionId,
12
+ /** `reticle verify --confirm-dangerous`: this run acknowledges the steps held as destructive. */
13
+ opts = {}) {
12
14
  return {
13
15
  listFlows: () => deps.flows.list(),
14
- replayFlow: (name) => replayAndLearn(deps, sessionId !== undefined ? { flowName: name, sessionId } : { flowName: name }),
16
+ replayFlow: (name) => replayAndLearn(deps, {
17
+ flowName: name,
18
+ ...(sessionId === undefined ? {} : { sessionId }),
19
+ ...(true === opts.confirmDangerous ? { confirmDangerous: true } : {}),
20
+ }),
15
21
  now: () => deps.now(),
16
22
  newRunId: defaultRunId,
17
23
  };
@@ -1,4 +1,5 @@
1
- import { type ProjectId, type FlowFile, type FlowReplayResult } from '@reticlehq/core';
1
+ import { type FlowFile, type FlowReplayResult } from '@reticlehq/core';
2
+ import { type ProjectTarget } from '../../memory/project/session-root.js';
2
3
  import type { ToolDeps } from '../../surface/tools/tool-kit.js';
3
4
  /** A replay plus the wall-clock time it took — the shape the verify handler already collects. */
4
5
  export interface TimedReplay {
@@ -7,9 +8,11 @@ export interface TimedReplay {
7
8
  /** The flow file that was replayed, so the synced run can carry its recording. */
8
9
  flow?: FlowFile;
9
10
  }
11
+ /** The MCP client name `reticle verify` (the command line, CI's path) connects to a daemon as. */
12
+ export declare const CLI_CLIENT_NAME = "reticle-cli";
10
13
  /**
11
14
  * Persist the suite's run artifact and best-effort mirror it to the cloud. Never throws into the verify
12
15
  * tool — a disk or network failure is logged and swallowed so the verdict the agent asked for is
13
16
  * unaffected. Returns the runId (for logging/tests); undefined if nothing was produced (empty suite).
14
17
  */
15
- export declare function persistAndSyncVerificationRun(deps: ToolDeps, timed: TimedReplay[], projectId: ProjectId | undefined): Promise<string | undefined>;
18
+ export declare function persistAndSyncVerificationRun(deps: ToolDeps, timed: TimedReplay[], target: ProjectTarget): Promise<string | undefined>;
@@ -8,42 +8,58 @@
8
8
  * lighter per-flow RunRecord that feeds regression memory is synced separately in flow-replay-run.ts.
9
9
  * Both are best-effort + opt-in: no creds → the artifact still lands on disk, nothing leaves the machine.
10
10
  */
11
- import { mcpClientIdentity } from '../../surface/mcp/peer/client-identity.js';
12
- import { RunAgentKind, RunFramework, RunProfile, RunTrigger, } from '@reticlehq/core';
11
+ import { callerClientName } from '../../hooks/coding-agents.js';
12
+ import { currentDrivenBy } from '../../hooks/driven-by.js';
13
+ import { RunAgentKind, RunFramework, RunProfile, RunTrigger, asRunId, } from '@reticlehq/core';
13
14
  import { homedir } from 'node:os';
14
15
  import { buildVerificationRun, } from './artifact/build-verification-run.js';
15
16
  import { mapReplayToFlowResult } from './artifact/replay-mapping.js';
16
17
  import { defaultRunId } from './default-run-id.js';
18
+ import { currentShotRun } from './default-run-id.js';
17
19
  import { RunStore } from './artifact/run-store.js';
18
20
  import { cloudFetch, syncRunToCloud, SyncOutcome } from '../../memory/cloud/cloud-sync.js';
19
21
  import { resolveProjectCloud } from '../../memory/cloud/cloud-config.js';
20
22
  import { log } from '../../log.js';
21
- import { rootForProjectId } from '../../memory/project/session-root.js';
23
+ import { rootForTarget } from '../../memory/project/session-root.js';
22
24
  /** The author of record when no MCP peer introduced itself — a CLI run, or a client that skipped the handshake. */
23
25
  const RETICLE_MCP_AGENT_ID = 'reticle-mcp';
26
+ /** The MCP client name `reticle verify` (the command line, CI's path) connects to a daemon as. */
27
+ export const CLI_CLIENT_NAME = 'reticle-cli';
28
+ /**
29
+ * Who ran a suite, and why. The command line is the pipeline, whichever daemon replays for it:
30
+ * through a running daemon its runs read as a coding agent, trigger manual, credited to whoever
31
+ * minted the key, while the path that boots its own daemon said pipeline.
32
+ */
33
+ function agentAndTrigger(client) {
34
+ return CLI_CLIENT_NAME === client
35
+ ? { agent: { id: client, kind: RunAgentKind.OEM_PIPELINE }, trigger: { kind: RunTrigger.OEM } }
36
+ : {
37
+ agent: { id: client ?? RETICLE_MCP_AGENT_ID, kind: RunAgentKind.CODING_AGENT },
38
+ trigger: { kind: RunTrigger.MANUAL },
39
+ };
40
+ }
24
41
  /** Assemble the ReticleVerificationRun artifact for a verify suite (pure — no IO). */
25
- function assembleRun(deps, timed, projectId) {
42
+ function assembleRun(deps, timed,
43
+ /** The dashboard project this checkout is linked to, else the session's own id. */
44
+ projectName) {
26
45
  const flows = timed.map((t) => mapReplayToFlowResult(t.replay, t.durationMs, t.flow));
27
46
  const input = {
28
- runId: defaultRunId(),
47
+ // The run its replays' screenshots were filed under, when the verify minted one first.
48
+ runId: asRunId(currentShotRun() ?? defaultRunId()),
29
49
  durationMs: flows.reduce((sum, f) => sum + f.durationMs, 0),
30
50
  profile: RunProfile.DEV,
31
- project: { name: projectId ?? 'reticle', framework: RunFramework.OTHER },
51
+ project: { name: projectName ?? 'reticle', framework: RunFramework.OTHER },
32
52
  /*
33
53
  * WHICH agent drove this, not merely THAT one did.
34
54
  *
35
55
  * This was hardcoded to 'reticle-mcp', so every run in every workspace claimed the same author.
36
56
  * A dashboard built on it could say "an agent verified this" and never "Claude Code verified
37
57
  * this, Cursor broke it" — which is the question a team actually has once more than one agent
38
- * touches the repo. The name is the client's own claim from the MCP handshake; a plain CLI run
39
- * with no MCP peer keeps the old id, because inventing a vendor there would be worse than
40
- * admitting we do not know.
58
+ * touches the repo. The name is the client's own claim from the MCP handshake, for the call that
59
+ * ran this suite only; a plain CLI run, or a dashboard Re-verify no agent made, keeps the old id,
60
+ * because inventing a vendor there would be worse than admitting we do not know.
41
61
  */
42
- agent: {
43
- id: mcpClientIdentity().name ?? RETICLE_MCP_AGENT_ID,
44
- kind: RunAgentKind.CODING_AGENT,
45
- },
46
- trigger: { kind: RunTrigger.MANUAL },
62
+ ...agentAndTrigger(callerClientName()),
47
63
  changedFiles: [],
48
64
  flows,
49
65
  checks: [],
@@ -57,18 +73,25 @@ function assembleRun(deps, timed, projectId) {
57
73
  * tool — a disk or network failure is logged and swallowed so the verdict the agent asked for is
58
74
  * unaffected. Returns the runId (for logging/tests); undefined if nothing was produced (empty suite).
59
75
  */
60
- export async function persistAndSyncVerificationRun(deps, timed, projectId) {
76
+ export async function persistAndSyncVerificationRun(deps, timed, target) {
77
+ const { projectId } = target;
61
78
  if (0 === timed.length)
62
79
  return undefined;
80
+ // A replay the Harness made inside its own drive is part of that drive's run: written on its own
81
+ // it was a second row ("Passed · Flow replay · Your agent") beside the plan run it belonged to.
82
+ if (currentDrivenBy() !== undefined)
83
+ return undefined;
63
84
  let run;
64
85
  // The project the suite ran for, not the directory the daemon was started in. Both halves below
65
86
  // take it: the artifact `reticle_run` reads back through `sessionRoot`, and the cloud link that
66
87
  // decides WHICH DASHBOARD this run is pushed to. The daemon's own directory has no link file, so
67
88
  // a misrouted read silently meant "not attached" — and where it DID have one, the run was pushed
68
89
  // to a dashboard belonging to whoever that checkout was linked to.
69
- const root = rootForProjectId(deps, projectId);
90
+ const root = rootForTarget(deps, target);
91
+ const cloud = await resolveProjectCloud(deps.fs, root, homedir(), process.env);
70
92
  try {
71
- run = assembleRun(deps, timed, projectId);
93
+ // Named after the dashboard project the checkout is linked to: a Re-verify run read "reticle".
94
+ run = assembleRun(deps, timed, cloud.projectId ?? projectId);
72
95
  await new RunStore(deps.fs, root).write(run);
73
96
  }
74
97
  catch (error) {
@@ -78,7 +101,6 @@ export async function persistAndSyncVerificationRun(deps, timed, projectId) {
78
101
  return undefined;
79
102
  }
80
103
  // Per-project cloud: only push when THIS project has cloud attached AND its policy allows runs.
81
- const cloud = await resolveProjectCloud(deps.fs, root, homedir(), process.env);
82
104
  if (null === cloud.config || !cloud.policy.runs)
83
105
  return run.runId; // not attached / runs disabled → local only
84
106
  const result = await syncRunToCloud(run, cloud.config, cloudFetch);
@@ -5,6 +5,7 @@
5
5
  * unexplained flake that blocks a merge destroys trust in the red. Pure decision; the CLI computes the
6
6
  * inputs (git diff → affected → run artifacts + flake ledger) and maps `pass` to the exit code.
7
7
  */
8
+ import { type RunFlowResult } from '@reticlehq/core';
8
9
  /** A flow whose assertions were WEAKENED since its last passing run. */
9
10
  interface DowngradedFlow {
10
11
  flow: string;
@@ -56,4 +57,13 @@ interface GateResult {
56
57
  unexecuted: string[];
57
58
  }
58
59
  export declare function gateDecision(input: GateInput): GateResult;
60
+ /**
61
+ * The flows a run lets the gate count as passing.
62
+ *
63
+ * Every PASS or HEALED flow by its own name, as before. A generated copy of a template also credits
64
+ * the template, but only on a STRICT pass that proved a consequence (#1321): a suite replays runtime
65
+ * copies with fixture parameters and deletes them, so their own names match no saved flow. A healed
66
+ * anchor, a failed or unverifiable replay, and a pass that checked nothing credit nothing.
67
+ */
68
+ export declare function passingFlowNames(flows: readonly RunFlowResult[]): string[];
59
69
  export {};
@@ -5,6 +5,7 @@
5
5
  * unexplained flake that blocks a merge destroys trust in the red. Pure decision; the CLI computes the
6
6
  * inputs (git diff → affected → run artifacts + flake ledger) and maps `pass` to the exit code.
7
7
  */
8
+ import { RunFlowStatus } from '@reticlehq/core';
8
9
  export function gateDecision(input) {
9
10
  const passing = new Set(input.passing);
10
11
  const flaky = new Set(input.flaky ?? []);
@@ -42,3 +43,24 @@ export function gateDecision(input) {
42
43
  unexecuted,
43
44
  };
44
45
  }
46
+ /**
47
+ * The flows a run lets the gate count as passing.
48
+ *
49
+ * Every PASS or HEALED flow by its own name, as before. A generated copy of a template also credits
50
+ * the template, but only on a STRICT pass that proved a consequence (#1321): a suite replays runtime
51
+ * copies with fixture parameters and deletes them, so their own names match no saved flow. A healed
52
+ * anchor, a failed or unverifiable replay, and a pass that checked nothing credit nothing.
53
+ */
54
+ export function passingFlowNames(flows) {
55
+ const names = new Set();
56
+ for (const f of flows) {
57
+ if (f.status !== RunFlowStatus.PASS && f.status !== RunFlowStatus.HEALED)
58
+ continue;
59
+ names.add(f.name);
60
+ const proved = f.oracle !== undefined ||
61
+ (f.stepResults ?? []).some((s) => s.ok && s.consequence !== undefined);
62
+ if (f.template !== undefined && f.status === RunFlowStatus.PASS && proved)
63
+ names.add(f.template);
64
+ }
65
+ return [...names];
66
+ }
@@ -123,6 +123,35 @@ invoked = new Map()) {
123
123
  : 'the action ran and the expected consequence never appeared — check the handler behind it, or whether this flow needs a state it did not start in. The locator is not the problem.',
124
124
  };
125
125
  }
126
+ /*
127
+ * An anchor that matched SEVERAL elements is not an element that is gone, and the advice below
128
+ * says it is.
129
+ *
130
+ * `ANCHOR_AMBIGUOUS` carries `nearest: null` and `ambiguous: true`, so it fell through to the
131
+ * last line of this branch — "the anchored element is gone; rebind or update the flow" — for a
132
+ * locator that resolved several times over and lost nothing. Rebind TO WHAT is the question the
133
+ * drift just refused to answer; sending the reader looking for a replacement locator is the
134
+ * opposite of the fix, which is a NARROWER anchor on the one they already have.
135
+ *
136
+ * The same sentence was already wrong for a testid ambiguity (it is why `ambiguous: true` exists
137
+ * on that drift at all), and the role and component runners make it reachable for two more
138
+ * anchor kinds. The distinction this branch has to keep is the one it was written for: a
139
+ * CONSEQUENCE that never appeared has no anchor problem, an AMBIGUOUS anchor has nothing else.
140
+ */
141
+ if (DriftReason.ANCHOR_AMBIGUOUS === drift.reasonKind) {
142
+ return {
143
+ verdict: 'drift',
144
+ summary: withIntent(`"${name}" drifted at step ${step.step} (${step.anchor}) — the anchor is ambiguous.`, intentSaid),
145
+ whatChanged: drift.reason,
146
+ // The step's OWN anchor is the thing at fault here, so its source file is the right place to
147
+ // look — unlike the consequence case above, where the recorded source belongs to the element
148
+ // that was acted on and the anchor is not what failed.
149
+ ...(where !== undefined ? { whereInSource: where } : {}),
150
+ nextAction: 'the anchor matched several elements, so which one the recording meant is not decidable. ' +
151
+ 'Narrow the anchor on this step — a unique testid, or a role+name that only one control ' +
152
+ 'has — rather than rebinding it; nothing here says the element was renamed or removed.',
153
+ };
154
+ }
126
155
  const fix = drift.nearest !== null && drift.ambiguous !== true
127
156
  ? `rebind the anchor to "${drift.nearest}" (closest survivor)`
128
157
  : drift.nearest !== null
@@ -136,7 +165,8 @@ invoked = new Map()) {
136
165
  ...(fix !== undefined ? { suggestedFix: fix } : {}),
137
166
  nextAction: fix !== undefined
138
167
  ? `${fix}, or update the flow if the change was intended.`
139
- : `inspect ${where ?? 'the step'} — the anchored element is gone; rebind or update the flow.`,
168
+ : `inspect ${where ?? 'the step'} — the anchored element is not on the page and nothing there looks like a rename. ` +
169
+ 'If the replay began somewhere the recording did not (signed out, another route), record the steps that reach this one; otherwise rebind or update the flow.',
140
170
  };
141
171
  }
142
172
  // status error: an action failed, or the success oracle was not satisfied (green-but-wrong).
@@ -207,6 +237,11 @@ isolation) {
207
237
  const unverifiable = [];
208
238
  let passed = 0;
209
239
  for (const { replay, flow } of runs) {
240
+ if (replay.status === ReplayStatus.UNVERIFIABLE) {
241
+ const reason = replay.unverifiable?.reason ?? unverifiableReason(flow) ?? 'the flow could not be graded';
242
+ unverifiable.push({ flow: replay.name, reason });
243
+ continue;
244
+ }
210
245
  if (replay.status === ReplayStatus.OK) {
211
246
  /*
212
247
  * The REPLAY's own answer first, then the grader's.
@@ -1,4 +1,6 @@
1
+ import { z } from 'zod';
1
2
  import { type FlowAnchor, type FlowFile } from '@reticlehq/core';
3
+ import { CALL_SECRETS_ARG } from '../../../surface/tools/tool-kit.js';
2
4
  /**
3
5
  * What the anchor CALLS the field it points at.
4
6
  *
@@ -20,6 +22,8 @@ export declare function anchorFieldName(anchor: FlowAnchor): string | undefined;
20
22
  * reader what to do: the value belongs in the environment, not in a file they are about to commit.
21
23
  */
22
24
  export declare const REDACTED_FILL = "<redacted: supply at replay>";
25
+ /** The arg a saved redacted fill names its variable in. Dropped before the step reaches the page. */
26
+ export declare const SECRET_NAME_ARG = "secret";
23
27
  /**
24
28
  * The environment variable that supplies one redacted field.
25
29
  *
@@ -33,6 +37,14 @@ export declare const REDACTED_FILL = "<redacted: supply at replay>";
33
37
  * saying it had to stay together.
34
38
  */
35
39
  export declare const secretEnvKey: (field: string) => string;
40
+ /** The schema of that argument, shared by every tool that replays a flow. */
41
+ export { CALL_SECRETS_ARG };
42
+ export declare const callSecretsArg: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
43
+ /**
44
+ * One secret's value: supplied with this call (by field or by variable name), else from the
45
+ * daemon's environment.
46
+ */
47
+ export declare function secretValue(envKey: string, env: Record<string, string | undefined>): string | undefined;
36
48
  /** One field a flow needs supplied, and the variable that supplies it. */
37
49
  export interface UnsuppliedSecret {
38
50
  field: string;
@@ -1,4 +1,6 @@
1
+ import { z } from 'zod';
1
2
  import { AnchorKind } from '@reticlehq/core';
3
+ import { CALL_SECRETS_ARG, callSecrets } from '../../../surface/tools/tool-kit.js';
2
4
  /**
3
5
  * What the anchor CALLS the field it points at.
4
6
  *
@@ -28,6 +30,10 @@ export function anchorFieldName(anchor) {
28
30
  * reader what to do: the value belongs in the environment, not in a file they are about to commit.
29
31
  */
30
32
  export const REDACTED_FILL = '<redacted: supply at replay>';
33
+ /** The arg a saved redacted fill names its variable in. Dropped before the step reaches the page. */
34
+ export const SECRET_NAME_ARG = 'secret';
35
+ /** The prefix every secret's variable carries. */
36
+ const SECRET_ENV_PREFIX = 'RETICLE_SECRET_';
31
37
  /**
32
38
  * The environment variable that supplies one redacted field.
33
39
  *
@@ -40,7 +46,24 @@ export const REDACTED_FILL = '<redacted: supply at replay>';
40
46
  * rules must not be able to drift. It used to sit in `replay.ts`, one import away from the sentence
41
47
  * saying it had to stay together.
42
48
  */
43
- export const secretEnvKey = (field) => `RETICLE_SECRET_${field.replace(/[^a-zA-Z0-9]+/g, '_').toUpperCase()}`;
49
+ export const secretEnvKey = (field) => `${SECRET_ENV_PREFIX}${field.replace(/[^a-zA-Z0-9]+/g, '_').toUpperCase()}`;
50
+ /** The schema of that argument, shared by every tool that replays a flow. */
51
+ export { CALL_SECRETS_ARG };
52
+ export const callSecretsArg = z
53
+ .record(z.string())
54
+ .optional()
55
+ .describe('Redacted fields\' values, this call only, never kept: { "auth-password": "…" }');
56
+ /**
57
+ * One secret's value: supplied with this call (by field or by variable name), else from the
58
+ * daemon's environment.
59
+ */
60
+ export function secretValue(envKey, env) {
61
+ for (const [key, value] of Object.entries(callSecrets() ?? {})) {
62
+ if (envKey === (key.startsWith(SECRET_ENV_PREFIX) ? key : secretEnvKey(key)))
63
+ return value;
64
+ }
65
+ return env[envKey];
66
+ }
44
67
  /**
45
68
  * Every credential this flow will replay as the literal placeholder.
46
69
  *
@@ -63,7 +86,7 @@ export function unsuppliedSecrets(flow, env) {
63
86
  if (field === undefined)
64
87
  continue;
65
88
  const envKey = secretEnvKey(field);
66
- const supplied = env[envKey];
89
+ const supplied = secretValue(envKey, env);
67
90
  if (supplied !== undefined && supplied.length > 0)
68
91
  continue;
69
92
  if (seen.has(envKey))
@@ -16,8 +16,13 @@ import type { FlowReplaySession, Sleep } from './flow-replay-types.js';
16
16
  export declare function editDistance(a: string, b: string): number;
17
17
  /**
18
18
  * The closest present testid to a missing one, by case-insensitive edit distance, ties broken
19
- * by shortest length then lexically. Returns null only when nothing is present — so a drift
20
- * record always names a fix when one exists ("whose fault is it": here is the closest survivor).
19
+ * by shortest length then lexically — when it is close enough to be a rename. Null when nothing
20
+ * present is, so a drift record names a fix only when one plausibly exists.
21
+ *
22
+ * It used to name the closest survivor however far away it was. A replay that started signed out
23
+ * missed `compose-prompt` on the login screen and advised rebinding it to `login-submit`: eleven
24
+ * edits away, a different control on a different page, offered as the fix. Half the longer name is
25
+ * the ceiling — `chat-send` → `chat-submit` and `checkout-btn` → `checkout-button` stay in.
21
26
  */
22
27
  export declare function nearestTestid(missing: string, present: string[]): string | null;
23
28
  /**
@@ -29,17 +34,63 @@ export declare function nearestIsAmbiguous(missing: string, present: string[]):
29
34
  /** Build the legible-drift record for a testid anchor that resolved to zero live elements. */
30
35
  export declare function testidDrift(value: string, hint: QueryEmptyHint | undefined): Drift;
31
36
  /**
32
- * Build the drift for a step whose anchor matched MORE THAN ONE live element.
37
+ * What the stale-ref retry found when it ran the locator again.
38
+ *
39
+ * A discriminated result rather than the bare `string | undefined` this started as, because the two
40
+ * ways of getting no ref back are different answers and were arriving as one. `{ drift }` says the
41
+ * locator now names SEVERAL elements — the re-render turned an unambiguous anchor into an ambiguous
42
+ * one, and the fix is a NARROWER anchor. `undefined` says it named none, or named one and the second
43
+ * dispatch failed too; both of those are already told truthfully by the stale-ref error the first
44
+ * attempt produced, so there is nothing to add.
45
+ *
46
+ * Collapsed together, the ambiguous case was reported as "ref 'e-orig' no longer resolves to an
47
+ * element" — a sentence about an element that is GONE, sent for an element that is now three. An
48
+ * agent reading it hunts for a rename or re-records the flow; the truth is that the anchor needs
49
+ * narrowing, which is the whole reason `ANCHOR_AMBIGUOUS` exists as its own reason kind.
50
+ */
51
+ export type Reresolved = {
52
+ readonly ref: string;
53
+ } | {
54
+ readonly drift: Drift;
55
+ };
56
+ /**
57
+ * The ambiguity rule itself: an anchor that matched several live elements is DRIFT, never a guess.
58
+ *
59
+ * Returns null when the locator named zero or one element, so a runner reads it as
60
+ * `const drift = ambiguityDrift(anchor, refs); if (drift !== null) return { …, ok: false, drift };`
61
+ * and never has to reconstruct the record itself.
62
+ *
63
+ * ONE function, because three anchor kinds ask the same question and each used to answer for itself.
64
+ * testid was fixed first and role second, and role's fix was written as a copy of testid's — so "is
65
+ * this ambiguous" had two answers and COMPONENT had none at all. `runComponentStep` took `refs[0]`,
66
+ * dispatched and returned `ok: true` whenever `by:'component'` matched several elements, which is the
67
+ * ordinary case for a component rendered once per row (a table row's action button). The verdict
68
+ * reads `drift` and `ok` and nothing else, so that green was indistinguishable from a replay that did
69
+ * what it did before — the #1227 defect, one anchor kind over.
70
+ *
71
+ * The caller must not dispatch before checking. Acting and then reporting drift would leave the app
72
+ * changed by a click nobody can attribute, which is worse than the ambiguity it reports.
73
+ */
74
+ export declare function ambiguityDrift(anchor: FlowAnchor, refs: readonly string[]): Drift | null;
75
+ /**
76
+ * The one ref a step means: the only match, or the recorded position among same-named controls
77
+ * while the page still has exactly as many of them as when it was recorded. Otherwise undefined.
78
+ */
79
+ export declare function refFor(anchor: object, refs: readonly string[]): string | undefined;
80
+ /**
81
+ * The anchor as the stale-ref RETRY found it: one ref to dispatch at, an ambiguity to report, or
82
+ * neither.
33
83
  *
34
- * `ambiguous: true` is set because that is exactly what it is, and it is the field heal already
35
- * reads to refuse an auto-rebind -- an ambiguous drift must never be healed to an arbitrary pick,
36
- * which is the same reasoning that made this a drift instead of a note in the first place.
84
+ * The same rule as `ambiguityDrift`, one layer deeper, and shared for the same reason: a re-render
85
+ * can turn an unambiguous anchor into an ambiguous one between the two dispatches, and dispatching
86
+ * at the first of the new matches would re-make the guess the caller's own check exists to refuse —
87
+ * in a place the caller cannot see. Written once so the three runners cannot answer it differently,
88
+ * which is how the component runner came to have no answer at all.
37
89
  *
38
- * `nearest` is null on purpose. There is no nearest: the anchor was found, several times over, and
39
- * proposing one of the matches as "the" match would re-make the guess this reason exists to stop.
40
- * The fix is a NARROWER anchor, and only a human or an agent looking at the page can choose it.
90
+ * `refs[0]` is read only after `ambiguityDrift` has cleared the several-match case, so the only way
91
+ * it is undefined here is zero matches.
41
92
  */
42
- export declare function ambiguousAnchorDrift(value: string, matches: number): Drift;
93
+ export declare function reresolved(anchor: FlowAnchor, refs: readonly string[]): Reresolved | undefined;
43
94
  /**
44
95
  * Build the drift for a step whose `expect.element` testid was absent after the action ran.
45
96
  *