@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
@@ -19,11 +19,11 @@
19
19
  * the base64 4/3 inflation factor applied, so the encoded payload always fits in one WebSocket
20
20
  * frame.
21
21
  */
22
- import { ActionType, InputModeReason, ReticleCommand, TRANSPORT_LIMITS } from '@reticlehq/core';
23
- import { boxCenter, isPointerAction } from '../../portal/input/real-input.js';
22
+ import { ActionType, DriveErrorCode, InputModeReason, ReticleCommand, TRANSPORT_LIMITS, } from '@reticlehq/core';
23
+ import { boxCenter, DriveError, isRealInputAction, unspellablePressReason, } from '../../portal/input/real-input.js';
24
24
  import { assertDragNotDestructive, assertNotDestructive } from './act/act-danger.js';
25
25
  import { NATIVE_INPUT_ARG } from '@reticlehq/core';
26
- import { asRecord, asString } from '@reticlehq/core';
26
+ import { asNumber, asRecord, asString } from '@reticlehq/core';
27
27
  import { commandOrThrow } from './tool-kit.js';
28
28
  import { asBox } from './act/act-helpers.js';
29
29
  import { isAbsolute, join, relative, extname, basename, resolve } from 'node:path';
@@ -228,6 +228,13 @@ function synthetic(reason) {
228
228
  ? { result: undefined, settled: false }
229
229
  : { result: undefined, settled: false, reason };
230
230
  }
231
+ /**
232
+ * Filler for the provider signature, which demands a box on every action.
233
+ *
234
+ * No coordinate is derived from it and none is reported back: `performGesture` returns before it
235
+ * reads the box on a press, because a key addresses focus rather than a point.
236
+ */
237
+ const PRESS_HAS_NO_BOX = { x: 0, y: 0, width: 0, height: 0 };
231
238
  /**
232
239
  * Hover without a native pointer is a false success: synthetic mouseover reports dispatched and
233
240
  * settled while CSS `:hover` never applies. Same refusal shape as contenteditable — name the gap
@@ -258,8 +265,10 @@ async function hoverForReal(deps, session, ref, inner, provider) {
258
265
  if (providerReady && provider !== undefined) {
259
266
  try {
260
267
  const performed = await provider.perform(session.url, ActionType.HOVER, box, {});
268
+ // Hover always has a resolved box, so there is always a center to report: the provider's own
269
+ // reading, or the box's if it reported none. Both are the same point, not a fabricated one.
261
270
  if (performed.performed)
262
- return hoverSucceeded(performed.center);
271
+ return hoverSucceeded(performed.center ?? boxCenter(box));
263
272
  }
264
273
  catch {
265
274
  // A provider error used to fall back to synthetic dispatch. For hover that is a lie.
@@ -295,7 +304,14 @@ export async function tryRealInput(deps, session, ref, action, args) {
295
304
  // real debugging time, because the tool description promises a reason is "never silent".
296
305
  return askedForNative ? synthetic(InputModeReason.NOT_CONFIGURED) : synthetic();
297
306
  }
298
- if (!isPointerAction(action))
307
+ // Two `press`es this module will NOT drive, and neither is a fallback — the reason says which
308
+ // one was asked for, instead of a different gesture being sent. See `unspellablePressReason`.
309
+ if (action === ActionType.PRESS) {
310
+ const unspellable = unspellablePressReason(ref, inner);
311
+ if (unspellable !== undefined)
312
+ return synthetic(unspellable);
313
+ }
314
+ if (!isRealInputAction(action))
299
315
  return synthetic(InputModeReason.NOT_POINTER); // fill/type stay synthetic
300
316
  // "Don't click, run the code": a click/dblclick runs the occlusion-honest SYNTHETIC path by default
301
317
  // even with a provider configured — no coordinate gesture to be intercepted by the HUD or missed
@@ -307,11 +323,85 @@ export async function tryRealInput(deps, session, ref, action, args) {
307
323
  // Under version skew CDP is unusable while DOM tools still work (#688). Surface the skew sentence
308
324
  // rather than "page not correlated" / a silent provider-error fallback — those send the agent
309
325
  // hunting a dead context that is not dead.
310
- if (session.versionSkew !== undefined) {
326
+ //
327
+ // `press` is exempt, and it is the one action where throwing would take something away: a
328
+ // document key is dispatched entirely in the page, so it does not need CDP at all and has always
329
+ // worked under skew. Routing it into real input made it reach this line for the first time, and
330
+ // throwing here would turn a working synthetic press into a hard failure. It falls through to
331
+ // `isAvailableFor` instead, and a driver that really is dead answers PROVIDER_ERROR with the
332
+ // usual `fellBack` — still a signal, just not a refusal.
333
+ if (action !== ActionType.PRESS && session.versionSkew !== undefined) {
311
334
  throw new Error(session.versionSkew);
312
335
  }
313
336
  if (!(await provider.isAvailableFor(session.url)))
314
337
  return synthetic(InputModeReason.PAGE_NOT_CORRELATED);
338
+ const performArgs = {};
339
+ const value = asString(inner['value']);
340
+ if (value !== undefined)
341
+ performArgs.value = value;
342
+ const text = asString(inner['text']);
343
+ if (text !== undefined)
344
+ performArgs.text = text;
345
+ const key = asString(inner['key']);
346
+ if (key !== undefined)
347
+ performArgs.key = key;
348
+ const modifiers = inner['modifiers'];
349
+ if (Array.isArray(modifiers)) {
350
+ performArgs.modifiers = modifiers.filter((m) => 'string' === typeof m);
351
+ }
352
+ // A held key is the whole point of a hold-to-confirm control, and the synthetic path has honoured
353
+ // `holdMs` all along. Not forwarding it made the real keyboard the WEAKER of the two paths: it
354
+ // drove the key instantly and reported a hold that never held.
355
+ const holdMs = asNumber(inner['holdMs']);
356
+ if (holdMs !== undefined)
357
+ performArgs.holdMs = holdMs;
358
+ // `keys` and `code` are read but not forwarded: both are routed away above — a multi-key sequence
359
+ // and an explicit physical code have no driver spelling — so carrying them into the provider would
360
+ // only invite it to guess at a gesture the caller did not ask for.
361
+ // A document key has no element of its own: skip INSPECT and the box entirely.
362
+ if (action === ActionType.PRESS) {
363
+ try {
364
+ const performed = await provider.perform(session.url, action, PRESS_HAS_NO_BOX, performArgs);
365
+ if (!performed.performed)
366
+ return synthetic(InputModeReason.PROVIDER_DECLINED);
367
+ // No `center`: a key addresses focus, not a point. The placeholder's zero happened nowhere.
368
+ //
369
+ // `heldMs` IS forwarded, and it is the whole reason this object is not just the three fields
370
+ // above: `reticle_act`'s description promises `effect.heldMs` reports the hold actually
371
+ // achieved, and on the real path the act result IS the `effect` block. Dropping it here made
372
+ // that promise true on the synthetic path and silently false on the one this release added
373
+ // `holdMs` to — an agent checking for an armed hold-to-confirm control read `undefined`.
374
+ return {
375
+ result: {
376
+ performed: true,
377
+ action,
378
+ inputMode: performed.inputMode,
379
+ ...(performed.heldMs !== undefined ? { heldMs: performed.heldMs } : {}),
380
+ },
381
+ settled: true,
382
+ };
383
+ }
384
+ catch (error) {
385
+ // The ONE failure that must not fall back. Every other throw means the gesture did not
386
+ // happen, and the synthetic path is the honest answer. A release that failed means the
387
+ // gesture DID happen and the key may still be down — replaying it synthetically presses the
388
+ // same key a second time on top of a keyboard that is already holding something, which is
389
+ // the corruption the release exists to prevent. Refusing is the only answer that cannot
390
+ // make it worse.
391
+ if (error instanceof DriveError && error.code === DriveErrorCode.RELEASE_FAILED) {
392
+ throw error;
393
+ }
394
+ // No skew re-throw here, unlike the pointer path below: this action has a working synthetic
395
+ // route (see the skew check above), so the honest answer to a driver that threw is the
396
+ // fallback, not a refusal.
397
+ return {
398
+ result: undefined,
399
+ settled: false,
400
+ fellBack: true,
401
+ reason: InputModeReason.PROVIDER_ERROR,
402
+ };
403
+ }
404
+ }
315
405
  const inspected = await commandOrThrow(deps, session.id, ReticleCommand.INSPECT, { ref });
316
406
  assertNotDestructive(action, inner, inspected);
317
407
  const box = asBox(inspected);
@@ -332,13 +422,6 @@ export async function tryRealInput(deps, session, ref, action, args) {
332
422
  if (toBox === undefined)
333
423
  return synthetic(InputModeReason.DRAG_TARGET_UNRESOLVED);
334
424
  }
335
- const performArgs = {};
336
- const value = asString(inner['value']);
337
- if (value !== undefined)
338
- performArgs.value = value;
339
- const text = asString(inner['text']);
340
- if (text !== undefined)
341
- performArgs.text = text;
342
425
  if (toBox !== undefined)
343
426
  performArgs.toBox = toBox;
344
427
  try {
@@ -0,0 +1,120 @@
1
+ import { Verified, VerdictStatus, type FlowReplayResult, type JournalAction, type SuiteVerdict } from '@reticlehq/core';
2
+ import type { TimedReplay } from '../../judgement/runs/verification-sync.js';
3
+ import type { ToolDeps } from './tool-kit.js';
4
+ export declare const ResultWord: {
5
+ readonly PROVED: "proved";
6
+ readonly NOT_PROVED: "not proved";
7
+ readonly FAILED: "failed";
8
+ };
9
+ export type ResultWord = (typeof ResultWord)[keyof typeof ResultWord];
10
+ /** The output field every result that ends a verification carries. */
11
+ export declare const RESULT_FIELD = "reticleResult";
12
+ export interface ResultFacts {
13
+ yes: number;
14
+ no: number;
15
+ undecided: number;
16
+ /** The journeys or flows the checks covered. */
17
+ covered?: readonly string[];
18
+ /** The journeys, flows or claims that did not hold. */
19
+ failed?: readonly string[];
20
+ flowsReplayed?: number;
21
+ /** Harness journeys answered by replaying saved flows (no model), and driven by the model. */
22
+ journeysReplayed?: number;
23
+ journeysDriven?: number;
24
+ wallMs?: number;
25
+ screenshots?: readonly string[];
26
+ /** From `platformLine`. */
27
+ platform: string;
28
+ }
29
+ /**
30
+ * Each fact once. The headline carries the check count, so the metrics do not repeat it; with one
31
+ * check the headline is the whole tally, so the per-word count line is left out.
32
+ */
33
+ export declare function buildReticleResult(f: ResultFacts): string;
34
+ /**
35
+ * The same block under a verdict decided above the counts: `reticle_verify { change }` can turn a
36
+ * green suite into `no` (a channel disagreed) or `unknown` (the flows do not cover the files).
37
+ */
38
+ export declare function retitleResult(block: string, verified: Verified, because: string): string;
39
+ /** The platform line when the key was refused: one true sentence, and the fix. */
40
+ export declare const KEY_REFUSED_HEAD = "Not on the platform: ";
41
+ /** The line for a key refused for no reason the platform named. */
42
+ export declare const KEY_REFUSED_LINE: string;
43
+ /** The platform line: where the run lives when linked, what linking adds when not. One line. */
44
+ export declare function platformLine(root: string, env: Record<string, string | undefined>, runId?: string): string;
45
+ /**
46
+ * The block for a replayed suite: the flows are the journeys, each flow's verdict one check, decided
47
+ * as the run decides it (`mapReplayToFlowResult`): a green a channel contradicted is undecided, as
48
+ * the suite's `unverifiable` status says, never held.
49
+ */
50
+ export declare function suiteResult(root: string, verdict: SuiteVerdict, timed: readonly TimedReplay[], runId: string | undefined): string;
51
+ /**
52
+ * `reticle_verify { change }`'s answer with the block on it. Its verdict is decided ABOVE the suite
53
+ * (uncovered files, a disagreeing channel), so the suite's own block is retitled with that verdict
54
+ * and moved to the top level: a nested block saying "proved" under an outer `no` is a false green.
55
+ */
56
+ export declare function changeResult(root: string, out: unknown): unknown;
57
+ /**
58
+ * The block for one replayed flow: one check, decided as the synced run decides it — a pass whose
59
+ * flow asserts nothing, or whose channels disagreed, is undecided, never held.
60
+ */
61
+ export declare function replayResult(root: string, replay: FlowReplayResult, durationMs: number, runId: string | undefined): string;
62
+ /** What a Harness drive's answer says about itself, as the block reads it. */
63
+ export interface DriveFacts {
64
+ checks: {
65
+ held: number;
66
+ failed: number;
67
+ undecided: number;
68
+ };
69
+ /** The end-state goals the Harness graded itself. */
70
+ goals: readonly {
71
+ verified: string;
72
+ }[];
73
+ goalMet?: boolean;
74
+ journeys?: readonly {
75
+ title: string;
76
+ status: string;
77
+ by?: string;
78
+ }[];
79
+ runIds?: readonly string[];
80
+ }
81
+ /**
82
+ * The block for a Harness drive: its checks and its graded goals are the checks; a plan's journeys
83
+ * are what it covered, with how many were replayed and how many the model drove. Checks that held
84
+ * over a goal the drive did not reach are not proved, as the answer's own `proved` says.
85
+ */
86
+ export declare function exploreResult(root: string, drive: DriveFacts): string;
87
+ /**
88
+ * The block for a session ending: every verdict the journal holds is one check. `no-fault` (nothing
89
+ * declared) counts as undecided, never as held — a session that proved nothing must not read as one
90
+ * that proved something.
91
+ */
92
+ export declare function sessionResult(deps: ToolDeps, sessionId: string, actions: readonly JournalAction[], wallMs: number | undefined, runId?: string): string;
93
+ /**
94
+ * What an ending agent session reports: its own calls since its previous end in the tab, never the
95
+ * Harness drives the tab also holds, and the run they are kept under.
96
+ */
97
+ export declare function endedAgentSession(sessionId: string, actions: readonly JournalAction[], at: number | undefined, claim?: VerdictStatus): {
98
+ actions: JournalAction[];
99
+ runId: string;
100
+ wallMs?: number;
101
+ };
102
+ /**
103
+ * The agent's own claim beside what grading the session's checks gave: the comparison a dashboard
104
+ * makes, said where the agent can read it. The claim never becomes the verdict.
105
+ */
106
+ export declare function claimAgainstGrade(claim: VerdictStatus, actions: readonly JournalAction[]): {
107
+ claimed: VerdictStatus;
108
+ graded: VerdictStatus;
109
+ agrees: boolean;
110
+ };
111
+ /**
112
+ * A verdict tool's call, remembered until it settles, so a session that ends meanwhile counts it.
113
+ * An agent ended its session while a `reticle_assert { wait }` was still waiting: the end folded
114
+ * first ("proved · 1 of 1"), a PASS on the dashboard, and the failure landed in the next run.
115
+ */
116
+ export declare function trackVerdict<T>(tool: string, call: Promise<T>): Promise<T>;
117
+ /** Resolves once every verdict in flight now has been decided (and journaled). */
118
+ export declare function verdictsSettled(): Promise<void>;
119
+ /** The block as a field, or no field: the block is advice, never the reason a result throws. */
120
+ export declare function resultField(build: () => string): Partial<Record<typeof RESULT_FIELD, string>>;
@@ -0,0 +1,364 @@
1
+ /**
2
+ * The "Reticle result" block: what an agent pastes, verbatim, when it finishes verifying.
3
+ *
4
+ * Built by the server from facts it already holds, so the wording of a verdict is ours and not the
5
+ * agent's: an agent asked to summarise an `unknown` tends to summarise it into a pass. Three verdict
6
+ * words only — proved, not proved, failed — and an undecided check is never proved.
7
+ *
8
+ * The last line is the platform line, said once per result and never as a prompt: linked, where the
9
+ * run is on the dashboard; not linked, what the platform adds and the one command. Nothing here is
10
+ * measured that was not measured: a metric with no number is left out, never printed as a zero.
11
+ */
12
+ import { existsSync, readdirSync } from 'node:fs';
13
+ import { dirname, join } from 'node:path';
14
+ import { JournalVerdictEffectSchema, ReticleDir, ReticleTool, RunFlowStatus, Verified, VerdictStatus, apiKeyFrom, } from '@reticlehq/core';
15
+ import { JourneyBy } from '@reticlehq/core/artifacts';
16
+ import { runVerdict } from '../../features/harness/drive-report.js';
17
+ import { mapReplayToFlowResult } from '../../judgement/runs/artifact/replay-mapping.js';
18
+ import { gapSummary } from '../../judgement/runs/artifact/gap-summary.js';
19
+ import { driveRunFrom, driveRunId, endAgentSession } from '../../judgement/runs/drive-run.js';
20
+ import { computeVerdict } from '../../judgement/runs/artifact/build-verification-run.js';
21
+ import { stepShotDir } from '../../memory/project/dir/reticle-dir.js';
22
+ import { TRIAL_OFFER } from '@reticlehq/core/hud';
23
+ import { KEY_REFUSED, dashboardRunUrl, keyRefusalAtLastSync, readDashboardUrl, } from '../../memory/project/sync-status.js';
24
+ import { CONNECT } from './platform-moment.js';
25
+ import { sessionRoot } from '../../memory/project/session-root.js';
26
+ export const ResultWord = {
27
+ PROVED: 'proved',
28
+ NOT_PROVED: 'not proved',
29
+ FAILED: 'failed',
30
+ };
31
+ /** The output field every result that ends a verification carries. */
32
+ export const RESULT_FIELD = 'reticleResult';
33
+ /** Paths shown before the rest are counted: enough to open one, not enough to flood a reply. */
34
+ const EVIDENCE_SHOWN = 3;
35
+ const SEP = ' · ';
36
+ const HEAD = '**Reticle result: ';
37
+ const Said = {
38
+ NOTHING_CHECKED: 'nothing was checked',
39
+ CHECKS: 'Checks',
40
+ COVERED: 'Covered',
41
+ DID_NOT_HOLD: 'Did not hold',
42
+ METRICS: 'Metrics',
43
+ EVIDENCE: 'Evidence',
44
+ RUN_LINK: 'Run on the dashboard',
45
+ DASHBOARD: 'On the dashboard',
46
+ SYNCED: 'Saved: the daemon syncs this run to the Reticle platform',
47
+ PITCH: 'Kept on this machine only. The Reticle platform adds run history, your team and Reticle Harness',
48
+ };
49
+ const plural = (n, word) => `${String(n)} ${word}${1 === n ? '' : 's'}`;
50
+ const seconds = (ms) => ms < 60_000
51
+ ? `${(ms / 1000).toFixed(1)}s`
52
+ : `${String(Math.floor(ms / 60_000))}m ${String(Math.round((ms % 60_000) / 1000))}s`;
53
+ function headline(f) {
54
+ const total = f.yes + f.no + f.undecided;
55
+ if (0 < f.no)
56
+ return `${HEAD}${ResultWord.FAILED}**${SEP}${String(f.no)} of ${plural(total, 'check')} did not hold`;
57
+ if (0 === total)
58
+ return `${HEAD}${ResultWord.NOT_PROVED}**${SEP}${Said.NOTHING_CHECKED}`;
59
+ if (0 < f.undecided)
60
+ return `${HEAD}${ResultWord.NOT_PROVED}**${SEP}${String(f.undecided)} of ${plural(total, 'check')} undecided`;
61
+ return `${HEAD}${ResultWord.PROVED}**${SEP}${String(f.yes)} of ${plural(total, 'check')} held`;
62
+ }
63
+ /**
64
+ * The evidence line. Screenshots filed under one run share one folder, so the folder is named once
65
+ * with the count: three long paths cost a single replay more tokens than its verdict, and its answer
66
+ * already lists each step's own path.
67
+ */
68
+ function evidenceLine(shots) {
69
+ if (0 === shots.length)
70
+ return [];
71
+ const dirs = new Set(shots.map((s) => dirname(s)));
72
+ const [dir] = dirs;
73
+ if (1 < shots.length && 1 === dirs.size && dir !== undefined)
74
+ return [`- ${Said.EVIDENCE}: ${plural(shots.length, 'screenshot')} in ${dir}`];
75
+ const more = shots.length - EVIDENCE_SHOWN;
76
+ return [
77
+ `- ${Said.EVIDENCE}: ${shots.slice(0, EVIDENCE_SHOWN).join(', ')}${0 < more ? ` (+${String(more)} more)` : ''}`,
78
+ ];
79
+ }
80
+ /**
81
+ * Each fact once. The headline carries the check count, so the metrics do not repeat it; with one
82
+ * check the headline is the whole tally, so the per-word count line is left out.
83
+ */
84
+ export function buildReticleResult(f) {
85
+ const total = f.yes + f.no + f.undecided;
86
+ const metrics = [
87
+ ...(f.flowsReplayed === undefined ? [] : [`${plural(f.flowsReplayed, 'flow')} replayed`]),
88
+ ...(f.journeysReplayed === undefined
89
+ ? []
90
+ : [`${plural(f.journeysReplayed, 'journey')} replayed`]),
91
+ ...(f.journeysDriven === undefined ? [] : [`${plural(f.journeysDriven, 'journey')} driven`]),
92
+ ...(f.wallMs === undefined ? [] : [seconds(f.wallMs)]),
93
+ ];
94
+ return [
95
+ headline(f),
96
+ ...(1 < total
97
+ ? [
98
+ `- ${Said.CHECKS}: ${String(f.yes)} yes${SEP}${String(f.no)} no${SEP}${String(f.undecided)} undecided`,
99
+ ]
100
+ : []),
101
+ ...(0 < (f.covered?.length ?? 0) ? [`- ${Said.COVERED}: ${(f.covered ?? []).join(', ')}`] : []),
102
+ ...(0 < (f.failed?.length ?? 0)
103
+ ? [`- ${Said.DID_NOT_HOLD}: ${(f.failed ?? []).join(', ')}`]
104
+ : []),
105
+ ...(0 === metrics.length ? [] : [`- ${Said.METRICS}: ${metrics.join(SEP)}`]),
106
+ ...evidenceLine(f.screenshots ?? []),
107
+ f.platform,
108
+ ].join('\n');
109
+ }
110
+ const WORD_FOR = {
111
+ [Verified.YES]: ResultWord.PROVED,
112
+ [Verified.NO]: ResultWord.FAILED,
113
+ [Verified.UNKNOWN]: ResultWord.NOT_PROVED,
114
+ [Verified.NO_FAULT]: ResultWord.NOT_PROVED,
115
+ };
116
+ /**
117
+ * The same block under a verdict decided above the counts: `reticle_verify { change }` can turn a
118
+ * green suite into `no` (a channel disagreed) or `unknown` (the flows do not cover the files).
119
+ */
120
+ export function retitleResult(block, verified, because) {
121
+ const [, ...rest] = block.split('\n');
122
+ return [`${HEAD}${WORD_FOR[verified]}**${SEP}${because}`, ...rest].join('\n');
123
+ }
124
+ /** The platform line when the key was refused: one true sentence, and the fix. */
125
+ export const KEY_REFUSED_HEAD = 'Not on the platform: ';
126
+ const keyRefusedLine = (why) => `${KEY_REFUSED_HEAD}${why.replace(/\.$/, '')}. Mint a new key in Settings → API keys; the run is kept on this machine`;
127
+ /** The line for a key refused for no reason the platform named. */
128
+ export const KEY_REFUSED_LINE = keyRefusedLine(KEY_REFUSED);
129
+ /** The platform line: where the run lives when linked, what linking adds when not. One line. */
130
+ export function platformLine(root, env, runId) {
131
+ // Before any link: a run the platform will refuse is not "saved" and not "on the dashboard".
132
+ const refusal = keyRefusalAtLastSync(root);
133
+ if (refusal !== undefined)
134
+ return `- ${keyRefusedLine(refusal)}`;
135
+ const dashboard = readDashboardUrl(root);
136
+ if (dashboard !== undefined)
137
+ return runId === undefined
138
+ ? `- ${Said.DASHBOARD}: ${dashboard}`
139
+ : `- ${Said.RUN_LINK}: ${dashboardRunUrl(dashboard, runId)}`;
140
+ if (existsSync(join(root, ReticleDir.CLOUD_LINK_FILE)) || apiKeyFrom(env) !== undefined)
141
+ return `- ${Said.SYNCED}.`;
142
+ return `- ${Said.PITCH} (${TRIAL_OFFER}): ${CONNECT}.`;
143
+ }
144
+ /** Screenshot paths a replay filed, in step order. */
145
+ const replayShots = (replay) => replay.steps.flatMap((s) => s.screenshot !== undefined && 'path' in s.screenshot ? [s.screenshot.path] : []);
146
+ /**
147
+ * The block for a replayed suite: the flows are the journeys, each flow's verdict one check, decided
148
+ * as the run decides it (`mapReplayToFlowResult`): a green a channel contradicted is undecided, as
149
+ * the suite's `unverifiable` status says, never held.
150
+ */
151
+ export function suiteResult(root, verdict, timed, runId) {
152
+ const statuses = timed.map((t) => mapReplayToFlowResult(t.replay, t.durationMs).status);
153
+ const count = (s) => statuses.filter((each) => s === each).length;
154
+ return buildReticleResult({
155
+ yes: count(RunFlowStatus.PASS),
156
+ no: count(RunFlowStatus.FAIL),
157
+ undecided: statuses.length - count(RunFlowStatus.PASS) - count(RunFlowStatus.FAIL),
158
+ covered: timed.map((t) => t.replay.name),
159
+ failed: verdict.failures.map((f) => f.flow),
160
+ flowsReplayed: timed.length,
161
+ wallMs: timed.reduce((sum, t) => sum + t.durationMs, 0),
162
+ screenshots: timed.flatMap((t) => replayShots(t.replay)),
163
+ platform: platformLine(root, process.env, runId),
164
+ });
165
+ }
166
+ /**
167
+ * `reticle_verify { change }`'s answer with the block on it. Its verdict is decided ABOVE the suite
168
+ * (uncovered files, a disagreeing channel), so the suite's own block is retitled with that verdict
169
+ * and moved to the top level: a nested block saying "proved" under an outer `no` is a false green.
170
+ */
171
+ export function changeResult(root, out) {
172
+ if (null === out || 'object' !== typeof out)
173
+ return out;
174
+ const answer = out;
175
+ const verified = answer['verified'];
176
+ if (!Object.values(Verified).includes(verified))
177
+ return out;
178
+ const suite = answer['suite'];
179
+ const inner = null !== suite && 'object' === typeof suite
180
+ ? suite[RESULT_FIELD]
181
+ : undefined;
182
+ const block = 'string' === typeof inner
183
+ ? inner
184
+ : buildReticleResult({
185
+ yes: 0,
186
+ no: 0,
187
+ undecided: 0,
188
+ platform: platformLine(root, process.env),
189
+ });
190
+ const because = 'string' === typeof answer['because'] ? answer['because'] : '';
191
+ return {
192
+ ...answer,
193
+ ...('string' === typeof inner
194
+ ? {
195
+ suite: Object.fromEntries(Object.entries(suite).filter(([k]) => RESULT_FIELD !== k)),
196
+ }
197
+ : {}),
198
+ [RESULT_FIELD]: retitleResult(block, verified, because),
199
+ };
200
+ }
201
+ /** Claims named before the rest are counted: a session can hold dozens. */
202
+ const COVERED_SHOWN = 5;
203
+ const capped = (items, shown) => items.length <= shown
204
+ ? [...items]
205
+ : [...items.slice(0, shown), `(+${String(items.length - shown)} more)`];
206
+ /** The step screenshots a drive filed under its run, or none: evidence is listed, never assumed. */
207
+ function shotsOf(root, runId) {
208
+ try {
209
+ const dir = stepShotDir(root, runId);
210
+ return readdirSync(dir)
211
+ .sort()
212
+ .map((f) => join(dir, f));
213
+ }
214
+ catch {
215
+ return [];
216
+ }
217
+ }
218
+ /**
219
+ * The block for one replayed flow: one check, decided as the synced run decides it — a pass whose
220
+ * flow asserts nothing, or whose channels disagreed, is undecided, never held.
221
+ */
222
+ export function replayResult(root, replay, durationMs, runId) {
223
+ const status = mapReplayToFlowResult(replay, durationMs).status;
224
+ const held = RunFlowStatus.PASS === status;
225
+ const failed = RunFlowStatus.FAIL === status;
226
+ return buildReticleResult({
227
+ yes: held ? 1 : 0,
228
+ no: failed ? 1 : 0,
229
+ undecided: held || failed ? 0 : 1,
230
+ covered: [replay.name],
231
+ ...(failed ? { failed: [replay.name] } : {}),
232
+ flowsReplayed: 1,
233
+ wallMs: durationMs,
234
+ screenshots: replayShots(replay),
235
+ platform: platformLine(root, process.env, runId),
236
+ });
237
+ }
238
+ const MSG_GOAL_NOT_REACHED = 'the drive did not reach its goal';
239
+ /**
240
+ * The block for a Harness drive: its checks and its graded goals are the checks; a plan's journeys
241
+ * are what it covered, with how many were replayed and how many the model drove. Checks that held
242
+ * over a goal the drive did not reach are not proved, as the answer's own `proved` says.
243
+ */
244
+ export function exploreResult(root, drive) {
245
+ // The checks, counted once and as the run's own summary counts them: the graded goals decide
246
+ // `goalMet` (and the headline below) and were added on top, so one run read "2 of 2 check(s)
247
+ // held" in its summary and "3 of 3" here.
248
+ const yes = drive.checks.held;
249
+ const no = drive.checks.failed;
250
+ const undecided = drive.checks.undecided;
251
+ const journeys = drive.journeys ?? [];
252
+ const by = (b) => journeys.filter((j) => b === j.by).length;
253
+ const answered = journeys.some((j) => j.by !== undefined);
254
+ const block = buildReticleResult({
255
+ yes,
256
+ no,
257
+ undecided,
258
+ ...(0 === journeys.length
259
+ ? {}
260
+ : {
261
+ covered: capped(journeys.map((j) => j.title), COVERED_SHOWN),
262
+ failed: journeys.filter((j) => 'failed' === j.status).map((j) => j.title),
263
+ }),
264
+ ...(answered
265
+ ? { journeysReplayed: by(JourneyBy.REPLAY), journeysDriven: by(JourneyBy.MODEL) }
266
+ : {}),
267
+ screenshots: (drive.runIds ?? []).flatMap((id) => shotsOf(root, id)),
268
+ platform: platformLine(root, process.env, drive.runIds?.[0]),
269
+ });
270
+ // A plan's verdict is its journeys' (the same line the run ends on), never a count beside it.
271
+ if (0 < journeys.length) {
272
+ const { verified: word, line } = runVerdict(drive.checks, drive.goalMet, journeys);
273
+ return WORD_FOR[word] === headWord(block)
274
+ ? block
275
+ : retitleResult(block, word, (line.split(' — ')[1] ?? line).replace(/\.$/, ''));
276
+ }
277
+ return 0 === no && 0 === undecided && 0 < yes && false === drive.goalMet
278
+ ? retitleResult(block, Verified.UNKNOWN, MSG_GOAL_NOT_REACHED)
279
+ : block;
280
+ }
281
+ /** The verdict word a block's headline carries. */
282
+ function headWord(block) {
283
+ return block.slice(HEAD.length).split('**')[0];
284
+ }
285
+ /**
286
+ * The block for a session ending: every verdict the journal holds is one check. `no-fault` (nothing
287
+ * declared) counts as undecided, never as held — a session that proved nothing must not read as one
288
+ * that proved something.
289
+ */
290
+ export function sessionResult(deps, sessionId, actions, wallMs, runId = driveRunId(sessionId)) {
291
+ const gap = gapSummary(actions);
292
+ const held = [
293
+ ...new Set(actions.flatMap((a) => {
294
+ const v = JournalVerdictEffectSchema.safeParse(a.effect);
295
+ return v.success && Verified.YES === v.data.verified ? [v.data.claim] : [];
296
+ })),
297
+ ];
298
+ // The session's project, never wherever the daemon was launched.
299
+ const root = sessionRoot(deps, sessionId);
300
+ return buildReticleResult({
301
+ yes: gap.held,
302
+ no: gap.failed,
303
+ undecided: gap.undecided + gap.nothingToProve,
304
+ covered: capped(held, COVERED_SHOWN),
305
+ failed: capped(gap.failures.map((f) => f.claim), COVERED_SHOWN),
306
+ ...(wallMs === undefined ? {} : { wallMs }),
307
+ screenshots: shotsOf(root, runId),
308
+ platform: platformLine(root, process.env, 0 < gap.claims ? runId : undefined),
309
+ });
310
+ }
311
+ /**
312
+ * What an ending agent session reports: its own calls since its previous end in the tab, never the
313
+ * Harness drives the tab also holds, and the run they are kept under.
314
+ */
315
+ export function endedAgentSession(sessionId, actions, at, claim) {
316
+ return endAgentSession(sessionId, actions, at, claim);
317
+ }
318
+ /**
319
+ * The agent's own claim beside what grading the session's checks gave: the comparison a dashboard
320
+ * makes, said where the agent can read it. The claim never becomes the verdict.
321
+ */
322
+ export function claimAgainstGrade(claim, actions) {
323
+ const run = driveRunFrom(actions, { runId: 'claim' });
324
+ // computeVerdict decides it, once: a failed check beside a passed one is a fail there too.
325
+ const graded = run === undefined ? VerdictStatus.UNKNOWN : computeVerdict(run).status;
326
+ return { claimed: claim, graded, agrees: claim === graded };
327
+ }
328
+ /** The tools whose verdicts an agent session's block counts: each one is one of its checks. */
329
+ const SESSION_VERDICT_TOOLS = new Set([
330
+ ReticleTool.ACT_AND_WAIT,
331
+ // `reticle_act { steps }` dispatches under ACT's name: a journey still grading is waited for too.
332
+ ReticleTool.ACT,
333
+ ReticleTool.ACT_SEQUENCE,
334
+ ReticleTool.ASSERT,
335
+ ReticleTool.WAIT_FOR,
336
+ ]);
337
+ /** Verdicts being decided right now. ponytail: daemon-wide, not per tab; an end waits for all. */
338
+ const inFlight = new Set();
339
+ /**
340
+ * A verdict tool's call, remembered until it settles, so a session that ends meanwhile counts it.
341
+ * An agent ended its session while a `reticle_assert { wait }` was still waiting: the end folded
342
+ * first ("proved · 1 of 1"), a PASS on the dashboard, and the failure landed in the next run.
343
+ */
344
+ export function trackVerdict(tool, call) {
345
+ if (!SESSION_VERDICT_TOOLS.has(tool))
346
+ return call;
347
+ const settled = call.then(() => undefined, () => undefined);
348
+ inFlight.add(settled);
349
+ void settled.then(() => inFlight.delete(settled));
350
+ return call;
351
+ }
352
+ /** Resolves once every verdict in flight now has been decided (and journaled). */
353
+ export async function verdictsSettled() {
354
+ await Promise.all([...inFlight]);
355
+ }
356
+ /** The block as a field, or no field: the block is advice, never the reason a result throws. */
357
+ export function resultField(build) {
358
+ try {
359
+ return { [RESULT_FIELD]: build() };
360
+ }
361
+ catch {
362
+ return {};
363
+ }
364
+ }