@reticlehq/server 3.6.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 (614) hide show
  1. package/SKILL.md +122 -123
  2. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  3. package/dist/command/cli/adhoc-suite.js +42 -7
  4. package/dist/command/cli/adhoc-verdict.d.ts +18 -2
  5. package/dist/command/cli/adhoc-verdict.js +70 -6
  6. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  7. package/dist/command/cli/answers/gate-exit.js +45 -0
  8. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  9. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  10. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  11. package/dist/command/cli/auth/device-flow.js +17 -0
  12. package/dist/command/cli/cli-doctor.js +14 -0
  13. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  14. package/dist/command/cli/cli-flow-commands.js +28 -105
  15. package/dist/command/cli/cli-kill.js +3 -2
  16. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  17. package/dist/command/cli/cli-parse-grammar.js +75 -0
  18. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  19. package/dist/command/cli/cli-parse-verify.js +18 -0
  20. package/dist/command/cli/cli-parse.d.ts +19 -28
  21. package/dist/command/cli/cli-parse.js +82 -182
  22. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  23. package/dist/command/cli/cli-update-commands.js +61 -9
  24. package/dist/command/cli/cli-usage.d.ts +33 -0
  25. package/dist/command/cli/cli-usage.js +287 -0
  26. package/dist/command/cli/cli-verify.d.ts +34 -4
  27. package/dist/command/cli/cli-verify.js +81 -12
  28. package/dist/command/cli/cloud-cli.d.ts +13 -0
  29. package/dist/command/cli/cloud-cli.js +145 -333
  30. package/dist/command/cli/cloud-kit.d.ts +12 -0
  31. package/dist/command/cli/cloud-kit.js +41 -2
  32. package/dist/command/cli/cloud-link.d.ts +57 -0
  33. package/dist/command/cli/cloud-link.js +308 -0
  34. package/dist/command/cli/cloud-login.d.ts +15 -1
  35. package/dist/command/cli/cloud-login.js +67 -13
  36. package/dist/command/cli/context-command.d.ts +1 -0
  37. package/dist/command/cli/context-command.js +33 -0
  38. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  39. package/dist/command/cli/daemon-start-options.js +24 -3
  40. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  41. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  42. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  43. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  44. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  45. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  46. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  47. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  48. package/dist/command/cli/known-regression.d.ts +13 -0
  49. package/dist/command/cli/known-regression.js +34 -0
  50. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  51. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  52. package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
  53. package/dist/command/cli/mcp-command.d.ts +6 -0
  54. package/dist/command/cli/mcp-command.js +13 -5
  55. package/dist/command/cli/ports/port-holder.js +1 -1
  56. package/dist/command/cli/project-name.d.ts +29 -1
  57. package/dist/command/cli/project-name.js +107 -2
  58. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  59. package/dist/command/cli/setup-mcp-cli.js +29 -8
  60. package/dist/command/cli/status/status-lines.d.ts +1 -0
  61. package/dist/command/cli/status/status-lines.js +47 -2
  62. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  63. package/dist/command/cli/status/workspace-links.js +29 -0
  64. package/dist/command/cli/try-command.d.ts +96 -0
  65. package/dist/command/cli/try-command.js +362 -0
  66. package/dist/command/cli/tutorial.d.ts +0 -100
  67. package/dist/command/cli/tutorial.js +0 -178
  68. package/dist/command/cli/verify-results.d.ts +19 -0
  69. package/dist/command/cli/verify-results.js +29 -0
  70. package/dist/command/cli-onboarding.d.ts +0 -11
  71. package/dist/command/cli-onboarding.js +0 -15
  72. package/dist/command/cli.d.ts +14 -0
  73. package/dist/command/cli.js +103 -83
  74. package/dist/command/daemon/daemon-resilience.js +4 -4
  75. package/dist/command/daemon/daemon-resolve.d.ts +9 -1
  76. package/dist/command/daemon/daemon-resolve.js +49 -10
  77. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  78. package/dist/command/setup/bringup/bridge-port.js +13 -3
  79. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  80. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  81. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  82. package/dist/command/setup/init/agent-restart.js +28 -0
  83. package/dist/command/setup/init/init-port.d.ts +10 -1
  84. package/dist/command/setup/init/init-port.js +22 -2
  85. package/dist/command/setup/init/init-runtime.d.ts +12 -2
  86. package/dist/command/setup/init/init-runtime.js +96 -37
  87. package/dist/command/setup/node-effects.d.ts +2 -0
  88. package/dist/command/setup/node-effects.js +36 -8
  89. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  90. package/dist/command/setup/probe/existing-app.js +14 -0
  91. package/dist/command/setup/remaining-steps.js +1 -1
  92. package/dist/command/setup/run-setup.d.ts +29 -9
  93. package/dist/command/setup/run-setup.js +34 -28
  94. package/dist/command/setup/setup-command.d.ts +23 -0
  95. package/dist/command/setup/setup-command.js +57 -4
  96. package/dist/command/setup/setup-mcp.js +25 -2
  97. package/dist/command/setup/tauri-signing.d.ts +19 -0
  98. package/dist/command/setup/tauri-signing.js +79 -0
  99. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  100. package/dist/command/setup/terminal/listeners.js +37 -6
  101. package/dist/command/update/update-nudge.d.ts +9 -0
  102. package/dist/command/update/update-nudge.js +1 -1
  103. package/dist/command/update/updater.js +11 -15
  104. package/dist/command/version/version-nudge.js +3 -0
  105. package/dist/command/version/version-skew.d.ts +20 -1
  106. package/dist/command/version/version-skew.js +38 -2
  107. package/dist/features/crawl/crawl.js +14 -1
  108. package/dist/features/exhaust/ledger.d.ts +14 -14
  109. package/dist/features/harness/drive-report.d.ts +39 -5
  110. package/dist/features/harness/drive-report.js +271 -54
  111. package/dist/features/harness/drive-runs.d.ts +120 -0
  112. package/dist/features/harness/drive-runs.js +289 -0
  113. package/dist/features/harness/drivers.d.ts +1 -1
  114. package/dist/features/harness/drivers.js +1 -1
  115. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  116. package/dist/features/harness/explore/console-pages.js +146 -0
  117. package/dist/features/harness/explore/disparity.d.ts +19 -0
  118. package/dist/features/harness/explore/disparity.js +71 -0
  119. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  120. package/dist/features/harness/explore/fake-app.js +49 -0
  121. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  122. package/dist/features/harness/explore/goal-search.js +144 -0
  123. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  124. package/dist/features/harness/explore/page-tree.js +148 -0
  125. package/dist/features/harness/explore/site-map.d.ts +34 -0
  126. package/dist/features/harness/explore/site-map.js +150 -0
  127. package/dist/features/harness/goals.d.ts +68 -7
  128. package/dist/features/harness/goals.js +289 -36
  129. package/dist/features/harness/harness.d.ts +30 -1
  130. package/dist/features/harness/harness.js +141 -7
  131. package/dist/features/harness/platform/local-apps.d.ts +36 -3
  132. package/dist/features/harness/platform/local-apps.js +81 -5
  133. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  134. package/dist/features/harness/platform/persona-credentials.js +69 -0
  135. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  136. package/dist/features/harness/platform/platform-drives.js +114 -0
  137. package/dist/features/harness/platform/refusal.d.ts +52 -0
  138. package/dist/features/harness/platform/refusal.js +71 -0
  139. package/dist/features/harness/platform/remote-drive.d.ts +8 -2
  140. package/dist/features/harness/platform/remote-drive.js +22 -9
  141. package/dist/features/harness/platform/script.d.ts +57 -11
  142. package/dist/features/harness/platform/script.js +144 -12
  143. package/dist/features/harness/platform/server-driver.d.ts +17 -4
  144. package/dist/features/harness/platform/server-driver.js +29 -26
  145. package/dist/features/harness/platform-config.d.ts +38 -5
  146. package/dist/features/harness/platform-config.js +93 -8
  147. package/dist/features/harness/route-guess.d.ts +13 -0
  148. package/dist/features/harness/route-guess.js +49 -0
  149. package/dist/features/harness/script/script-run.d.ts +30 -1
  150. package/dist/features/harness/script/script-run.js +355 -48
  151. package/dist/features/license/license.d.ts +2 -2
  152. package/dist/features/visual/step-shots.d.ts +31 -0
  153. package/dist/features/visual/step-shots.js +231 -0
  154. package/dist/features/visual/visual-tools.js +22 -14
  155. package/dist/hooks/client-directory.d.ts +18 -0
  156. package/dist/hooks/client-directory.js +57 -0
  157. package/dist/hooks/coding-agents.d.ts +34 -0
  158. package/dist/hooks/coding-agents.js +117 -0
  159. package/dist/hooks/driven-by.d.ts +21 -2
  160. package/dist/hooks/driven-by.js +42 -2
  161. package/dist/hooks/hook-bus.d.ts +4 -0
  162. package/dist/hooks/hook-bus.js +18 -0
  163. package/dist/index.d.ts +1 -0
  164. package/dist/index.js +26 -183
  165. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  166. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  167. package/dist/judgement/capsule/causal-summary.js +33 -0
  168. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  169. package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
  170. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  171. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  172. package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
  173. package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
  174. package/dist/judgement/runs/artifact/run-store.js +175 -8
  175. package/dist/judgement/runs/context-tools.js +59 -1
  176. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  177. package/dist/judgement/runs/default-run-id.js +16 -0
  178. package/dist/judgement/runs/drive-run.d.ts +53 -5
  179. package/dist/judgement/runs/drive-run.js +234 -20
  180. package/dist/judgement/runs/resume.d.ts +44 -0
  181. package/dist/judgement/runs/resume.js +137 -0
  182. package/dist/judgement/runs/reticle-runner.js +5 -2
  183. package/dist/judgement/runs/runner-port.d.ts +5 -1
  184. package/dist/judgement/runs/runner-port.js +8 -2
  185. package/dist/judgement/runs/verification-sync.d.ts +2 -0
  186. package/dist/judgement/runs/verification-sync.js +36 -15
  187. package/dist/language/flows/decision.js +2 -1
  188. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  189. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  190. package/dist/language/flows/flow-anchor.d.ts +7 -2
  191. package/dist/language/flows/flow-anchor.js +10 -3
  192. package/dist/language/flows/flow-intent.d.ts +1 -0
  193. package/dist/language/flows/flow-journey.d.ts +6 -0
  194. package/dist/language/flows/flow-journey.js +20 -0
  195. package/dist/language/flows/flow-learning.d.ts +4 -0
  196. package/dist/language/flows/flow-learning.js +37 -3
  197. package/dist/language/flows/flow-replay-run.js +16 -18
  198. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  199. package/dist/language/flows/flow-replay.d.ts +18 -1
  200. package/dist/language/flows/flow-replay.js +22 -7
  201. package/dist/language/flows/flow-result.d.ts +22 -1
  202. package/dist/language/flows/flow-result.js +47 -2
  203. package/dist/language/flows/flow-step-runners.d.ts +2 -0
  204. package/dist/language/flows/flow-step-runners.js +12 -6
  205. package/dist/language/flows/flow-store-for-session.js +5 -1
  206. package/dist/language/flows/flow-tools.d.ts +10 -0
  207. package/dist/language/flows/flow-tools.js +61 -62
  208. package/dist/language/flows/flows.d.ts +16 -1
  209. package/dist/language/flows/flows.js +69 -10
  210. package/dist/language/flows/narrow-write.d.ts +7 -0
  211. package/dist/language/flows/narrow-write.js +36 -1
  212. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  213. package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
  214. package/dist/language/flows/recording/tape/recordings.js +60 -10
  215. package/dist/language/flows/replay.js +29 -6
  216. package/dist/language/flows/single-replay.d.ts +7 -0
  217. package/dist/language/flows/single-replay.js +26 -0
  218. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  219. package/dist/language/flows/verify-change-tools.js +200 -193
  220. package/dist/memory/cloud/cloud-config.d.ts +10 -1
  221. package/dist/memory/cloud/cloud-config.js +19 -5
  222. package/dist/memory/cloud/cloud-sync.js +3 -3
  223. package/dist/memory/cloud/harness-config.d.ts +49 -0
  224. package/dist/memory/cloud/harness-config.js +16 -20
  225. package/dist/memory/cloud/memory-scope.d.ts +17 -0
  226. package/dist/memory/cloud/memory-scope.js +22 -0
  227. package/dist/memory/cloud/sync-cycle.d.ts +32 -4
  228. package/dist/memory/cloud/sync-cycle.js +113 -12
  229. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  230. package/dist/memory/cloud/sync-daemon.js +114 -4
  231. package/dist/memory/cloud/sync-disk.js +26 -2
  232. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  233. package/dist/memory/cloud/sync-screenshots.js +105 -0
  234. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  235. package/dist/memory/cloud/unsynced-roots.js +166 -0
  236. package/dist/memory/impact/account-watch.d.ts +16 -1
  237. package/dist/memory/impact/account-watch.js +26 -1
  238. package/dist/memory/impact/impact-store.d.ts +1 -4
  239. package/dist/memory/impact/impact-store.js +32 -42
  240. package/dist/memory/intent/inline-intent.d.ts +1 -0
  241. package/dist/memory/intent/intent-shard-store.js +16 -4
  242. package/dist/memory/intent/intent-shard.d.ts +12 -0
  243. package/dist/memory/intent/intent-store.d.ts +1 -0
  244. package/dist/memory/intent/intent-tools.js +42 -2
  245. package/dist/memory/intent/open-intents.d.ts +6 -0
  246. package/dist/memory/intent/open-intents.js +10 -1
  247. package/dist/memory/intent/settled-words.d.ts +24 -0
  248. package/dist/memory/intent/settled-words.js +130 -0
  249. package/dist/memory/journal/drive-flow.d.ts +16 -0
  250. package/dist/memory/journal/drive-flow.js +34 -2
  251. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  252. package/dist/memory/journal/drive-run-flush.js +20 -5
  253. package/dist/memory/journal/journal-recorder.js +46 -3
  254. package/dist/memory/journal/on-disk/retention.d.ts +5 -0
  255. package/dist/memory/journal/on-disk/retention.js +27 -2
  256. package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
  257. package/dist/memory/journal/session-end.d.ts +15 -1
  258. package/dist/memory/journal/session-end.js +38 -7
  259. package/dist/memory/project/artifact-root-resolver.js +33 -5
  260. package/dist/memory/project/artifact-root.d.ts +4 -3
  261. package/dist/memory/project/artifact-root.js +2 -2
  262. package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
  263. package/dist/memory/project/dir/reticle-dir.js +23 -2
  264. package/dist/memory/project/link-directory.d.ts +15 -0
  265. package/dist/memory/project/link-directory.js +44 -0
  266. package/dist/memory/project/root-claims.d.ts +6 -0
  267. package/dist/memory/project/root-claims.js +39 -0
  268. package/dist/memory/project/session-root.d.ts +2 -0
  269. package/dist/memory/project/session-root.js +9 -1
  270. package/dist/memory/project/sync-status.d.ts +46 -0
  271. package/dist/memory/project/sync-status.js +135 -1
  272. package/dist/memory/recall/memory-tools.js +46 -3
  273. package/dist/memory/recall/platform-memory.d.ts +34 -0
  274. package/dist/memory/recall/platform-memory.js +139 -0
  275. package/dist/memory/recall/project-memory.js +36 -8
  276. package/dist/portal/bridge/bridge.d.ts +9 -5
  277. package/dist/portal/bridge/bridge.js +66 -23
  278. package/dist/portal/bridge/harness-request.d.ts +23 -0
  279. package/dist/portal/bridge/harness-request.js +27 -0
  280. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  281. package/dist/portal/bridge/wrong-path.js +35 -0
  282. package/dist/portal/input/network-mock-tools.js +11 -2
  283. package/dist/portal/input/real-input.d.ts +2 -0
  284. package/dist/portal/input/real-input.js +13 -10
  285. package/dist/portal/pool/browser-pool.d.ts +48 -0
  286. package/dist/portal/pool/browser-pool.js +120 -2
  287. package/dist/portal/pool/context-permissions.d.ts +33 -0
  288. package/dist/portal/pool/context-permissions.js +33 -0
  289. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  290. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  291. package/dist/portal/pool/playwright-launcher.d.ts +27 -5
  292. package/dist/portal/pool/playwright-launcher.js +59 -14
  293. package/dist/portal/pool/pool-contract.d.ts +21 -1
  294. package/dist/portal/session/agent-link.d.ts +8 -0
  295. package/dist/portal/session/agent-link.js +17 -0
  296. package/dist/portal/session/command-payload.js +6 -1
  297. package/dist/portal/session/daemon-answers.d.ts +3 -3
  298. package/dist/portal/session/daemon-answers.js +4 -2
  299. package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
  300. package/dist/portal/session/dev-server/dev-command.js +27 -1
  301. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  302. package/dist/portal/session/facts/observed-state.js +46 -3
  303. package/dist/portal/session/human/live-control.d.ts +9 -2
  304. package/dist/portal/session/human/live-control.js +12 -3
  305. package/dist/portal/session/live-control-tools.js +82 -13
  306. package/dist/portal/session/narration-args.d.ts +5 -0
  307. package/dist/portal/session/narration-args.js +17 -0
  308. package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
  309. package/dist/portal/session/no-session-diagnosis.js +31 -9
  310. package/dist/portal/session/no-session-next-action.d.ts +20 -0
  311. package/dist/portal/session/no-session-next-action.js +134 -61
  312. package/dist/portal/session/no-session-watch.js +179 -22
  313. package/dist/portal/session/presence/session-lease.js +1 -1
  314. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  315. package/dist/portal/session/recorded-gaps.js +251 -0
  316. package/dist/portal/session/session-health.d.ts +11 -0
  317. package/dist/portal/session/session-health.js +3 -1
  318. package/dist/portal/session/session-info.js +2 -1
  319. package/dist/portal/session/session-manager.d.ts +18 -0
  320. package/dist/portal/session/session-manager.js +54 -3
  321. package/dist/portal/session/session-successor.d.ts +8 -0
  322. package/dist/portal/session/session-successor.js +1 -1
  323. package/dist/portal/session/session.d.ts +15 -28
  324. package/dist/portal/session/session.js +60 -61
  325. package/dist/portal/session/timing/command-timeout.js +25 -1
  326. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  327. package/dist/portal/session/timing/wall-clock.js +1 -1
  328. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  329. package/dist/portal/session/zero-install-first-call.js +88 -0
  330. package/dist/start-options.d.ts +7 -1
  331. package/dist/start-wiring.d.ts +63 -0
  332. package/dist/start-wiring.js +169 -0
  333. package/dist/status-payload.d.ts +13 -1
  334. package/dist/status-payload.js +13 -1
  335. package/dist/surface/http-server.js +7 -1
  336. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  337. package/dist/surface/mcp/attach-memory.js +12 -1
  338. package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
  339. package/dist/surface/mcp/mcp-proxy.js +29 -8
  340. package/dist/surface/mcp/mcp.d.ts +23 -0
  341. package/dist/surface/mcp/mcp.js +34 -4
  342. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  343. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  344. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  345. package/dist/surface/mcp/server-instructions.js +22 -14
  346. package/dist/surface/mcp/shared-params.js +1 -1
  347. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  348. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  349. package/dist/surface/tools/account-tool.d.ts +22 -0
  350. package/dist/surface/tools/account-tool.js +157 -0
  351. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  352. package/dist/surface/tools/act/act-danger.js +38 -1
  353. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  354. package/dist/surface/tools/act/act-observation.js +57 -0
  355. package/dist/surface/tools/act/act-preflight.js +25 -2
  356. package/dist/surface/tools/act/act-target.js +8 -3
  357. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  358. package/dist/surface/tools/act/resolve-target.js +18 -3
  359. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  360. package/dist/surface/tools/act/screen-request.js +113 -0
  361. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  362. package/dist/surface/tools/act/sequence-grade.js +13 -2
  363. package/dist/surface/tools/act-sequence-tool.js +136 -27
  364. package/dist/surface/tools/act-tools.d.ts +0 -9
  365. package/dist/surface/tools/act-tools.js +48 -34
  366. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  367. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  368. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  369. package/dist/surface/tools/agent/app-notes.js +48 -0
  370. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  371. package/dist/surface/tools/agent/build-staleness.js +62 -0
  372. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  373. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  374. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  375. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  376. package/dist/surface/tools/agent/notices.d.ts +50 -0
  377. package/dist/surface/tools/agent/notices.js +152 -0
  378. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  379. package/dist/surface/tools/agent/reteach.js +50 -0
  380. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  381. package/dist/surface/tools/args/alias-args.js +10 -0
  382. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  383. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  384. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  385. package/dist/surface/tools/assert/assert-source.js +40 -0
  386. package/dist/surface/tools/assert/assert-verdict.js +25 -15
  387. package/dist/surface/tools/browser-tools.js +43 -1
  388. package/dist/surface/tools/chat-drives.d.ts +75 -0
  389. package/dist/surface/tools/chat-drives.js +265 -21
  390. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  391. package/dist/surface/tools/coverage-tools.js +2 -53
  392. package/dist/surface/tools/dynamic-tools.js +29 -1
  393. package/dist/surface/tools/empty-session-list.d.ts +10 -0
  394. package/dist/surface/tools/empty-session-list.js +45 -5
  395. package/dist/surface/tools/error-recovery.d.ts +8 -0
  396. package/dist/surface/tools/error-recovery.js +69 -5
  397. package/dist/surface/tools/explore-tools.d.ts +23 -2
  398. package/dist/surface/tools/explore-tools.js +377 -74
  399. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  400. package/dist/surface/tools/feedback-tools.js +4 -3
  401. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  402. package/dist/surface/tools/gap-novelty.js +8 -1
  403. package/dist/surface/tools/harness-explore.d.ts +52 -73
  404. package/dist/surface/tools/harness-explore.js +177 -146
  405. package/dist/surface/tools/harness-gate.d.ts +88 -0
  406. package/dist/surface/tools/harness-gate.js +235 -0
  407. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  408. package/dist/surface/tools/harness-hunt.js +215 -0
  409. package/dist/surface/tools/harness-plan.d.ts +5 -0
  410. package/dist/surface/tools/harness-plan.js +7 -0
  411. package/dist/surface/tools/harness-script.d.ts +22 -0
  412. package/dist/surface/tools/harness-script.js +256 -38
  413. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  414. package/dist/surface/tools/harness-tab-guard.js +27 -0
  415. package/dist/surface/tools/harness-toolset.d.ts +8 -0
  416. package/dist/surface/tools/harness-toolset.js +27 -4
  417. package/dist/surface/tools/human-notes.d.ts +16 -0
  418. package/dist/surface/tools/human-notes.js +27 -0
  419. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  420. package/dist/surface/tools/invoke-tool.js +220 -93
  421. package/dist/surface/tools/lease-hint.js +26 -5
  422. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  423. package/dist/surface/tools/lease-permissions.js +73 -0
  424. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  425. package/dist/surface/tools/lease-readiness.js +57 -0
  426. package/dist/surface/tools/lease-seed.d.ts +20 -0
  427. package/dist/surface/tools/lease-seed.js +45 -1
  428. package/dist/surface/tools/lease-tools.d.ts +10 -1
  429. package/dist/surface/tools/lease-tools.js +119 -69
  430. package/dist/surface/tools/live-call-text.js +2 -2
  431. package/dist/surface/tools/merge-tools.js +42 -2
  432. package/dist/surface/tools/merged-name-redirect.js +4 -0
  433. package/dist/surface/tools/next-step.d.ts +11 -1
  434. package/dist/surface/tools/next-step.js +73 -18
  435. package/dist/surface/tools/observe-tools.js +43 -5
  436. package/dist/surface/tools/platform-moment.d.ts +60 -0
  437. package/dist/surface/tools/platform-moment.js +132 -4
  438. package/dist/surface/tools/read-tools.js +65 -14
  439. package/dist/surface/tools/reticle-result.d.ts +120 -0
  440. package/dist/surface/tools/reticle-result.js +364 -0
  441. package/dist/surface/tools/tool-kit.d.ts +68 -2
  442. package/dist/surface/tools/tool-kit.js +73 -1
  443. package/dist/surface/tools/tools.js +25 -13
  444. package/dist/telemetry/account-envelope.d.ts +7 -0
  445. package/dist/telemetry/account-envelope.js +61 -0
  446. package/dist/telemetry/agent-client.d.ts +15 -0
  447. package/dist/telemetry/agent-client.js +57 -0
  448. package/dist/telemetry/app-instrumented.js +9 -2
  449. package/dist/telemetry/argument-shape.d.ts +7 -0
  450. package/dist/telemetry/argument-shape.js +86 -1
  451. package/dist/telemetry/automation-hint.d.ts +2 -3
  452. package/dist/telemetry/automation-hint.js +33 -8
  453. package/dist/telemetry/cli-telemetry.js +7 -2
  454. package/dist/telemetry/daemon-telemetry.js +3 -0
  455. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  456. package/dist/telemetry/error-fingerprint.js +61 -5
  457. package/dist/telemetry/feedback-cli.d.ts +0 -13
  458. package/dist/telemetry/feedback-cli.js +0 -77
  459. package/dist/telemetry/feedback.d.ts +13 -0
  460. package/dist/telemetry/feedback.js +183 -17
  461. package/dist/telemetry/harness-run.d.ts +18 -0
  462. package/dist/telemetry/harness-run.js +80 -0
  463. package/dist/telemetry/hud-events.d.ts +16 -0
  464. package/dist/telemetry/hud-events.js +27 -0
  465. package/dist/telemetry/hud-metrics.d.ts +27 -6
  466. package/dist/telemetry/hud-metrics.js +99 -25
  467. package/dist/telemetry/init-telemetry.js +2 -2
  468. package/dist/telemetry/install-source.d.ts +13 -25
  469. package/dist/telemetry/install-source.js +44 -3
  470. package/dist/telemetry/mcp-connection.d.ts +0 -14
  471. package/dist/telemetry/mcp-connection.js +5 -1
  472. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  473. package/dist/telemetry/onboarding-firsts.js +81 -6
  474. package/dist/telemetry/platform-linked.d.ts +5 -0
  475. package/dist/telemetry/platform-linked.js +32 -0
  476. package/dist/telemetry/project-profile.js +5 -3
  477. package/dist/telemetry/proxy-telemetry.js +4 -1
  478. package/dist/telemetry/session-metrics.d.ts +15 -4
  479. package/dist/telemetry/session-metrics.js +88 -52
  480. package/dist/telemetry/telemetry.d.ts +26 -2
  481. package/dist/telemetry/telemetry.js +102 -21
  482. package/dist/telemetry/verification-of.d.ts +3 -1
  483. package/dist/telemetry/verification-of.js +12 -4
  484. package/dist/wire-journal.d.ts +2 -2
  485. package/dist/wire-journal.js +16 -5
  486. package/docs/README.md +2 -2
  487. package/docs/actions.mdx +6 -3
  488. package/docs/adapters.md +1 -1
  489. package/docs/agent-cheatsheet.md +24 -27
  490. package/docs/architecture.md +5 -5
  491. package/docs/autodrive.md +13 -12
  492. package/docs/benchmarks.md +5 -5
  493. package/docs/best-practices.mdx +27 -9
  494. package/docs/capabilities.mdx +14 -16
  495. package/docs/cli/affected.mdx +1 -1
  496. package/docs/cli/cloud.mdx +54 -75
  497. package/docs/cli/doctor.mdx +8 -3
  498. package/docs/cli/drive.mdx +12 -12
  499. package/docs/cli/feedback.mdx +3 -3
  500. package/docs/cli/gate.mdx +7 -2
  501. package/docs/cli/help.mdx +50 -55
  502. package/docs/cli/init.mdx +32 -15
  503. package/docs/cli/license.mdx +12 -8
  504. package/docs/cli/mcp.mdx +4 -4
  505. package/docs/cli/open.mdx +3 -3
  506. package/docs/cli/report.mdx +4 -2
  507. package/docs/cli/restart.mdx +2 -2
  508. package/docs/cli/rollback.mdx +14 -8
  509. package/docs/cli/serve.mdx +4 -4
  510. package/docs/cli/setup.mdx +23 -0
  511. package/docs/cli/status.mdx +13 -4
  512. package/docs/cli/stop.mdx +67 -8
  513. package/docs/cli/try.mdx +62 -0
  514. package/docs/cli/update.mdx +4 -3
  515. package/docs/cli/verify.mdx +17 -6
  516. package/docs/cli/version.mdx +3 -2
  517. package/docs/cli.mdx +110 -41
  518. package/docs/debugging.md +3 -3
  519. package/docs/deploy-checks.md +1 -1
  520. package/docs/desktop.mdx +5 -3
  521. package/docs/enterprise.md +11 -10
  522. package/docs/environment.mdx +5 -2
  523. package/docs/faq.mdx +3 -3
  524. package/docs/first-drive.md +5 -4
  525. package/docs/flows.md +35 -27
  526. package/docs/for-agents.md +4 -5
  527. package/docs/frameworks.mdx +32 -21
  528. package/docs/getting-started.md +66 -64
  529. package/docs/human-control.md +15 -14
  530. package/docs/index.mdx +15 -43
  531. package/docs/install-agentic.mdx +22 -37
  532. package/docs/install-manual.mdx +22 -12
  533. package/docs/instrumentation.mdx +5 -3
  534. package/docs/integration-patterns.md +7 -7
  535. package/docs/license-activation.mdx +1 -1
  536. package/docs/multi-agent-testing.md +24 -6
  537. package/docs/packages/babel-plugin.mdx +4 -2
  538. package/docs/packages/browser.mdx +16 -10
  539. package/docs/packages/core.mdx +12 -5
  540. package/docs/packages/electron.mdx +3 -2
  541. package/docs/packages/engine.mdx +1 -1
  542. package/docs/packages/eslint-plugin.mdx +18 -12
  543. package/docs/packages/next.mdx +8 -7
  544. package/docs/packages/open-verification.mdx +1 -1
  545. package/docs/packages/server.mdx +5 -5
  546. package/docs/packages/tauri.mdx +8 -8
  547. package/docs/packages/test.mdx +4 -10
  548. package/docs/packages/vite-plugin.mdx +11 -4
  549. package/docs/packages.mdx +11 -15
  550. package/docs/platform-integration.md +6 -5
  551. package/docs/predicates.mdx +40 -24
  552. package/docs/quickstart.mdx +58 -29
  553. package/docs/required-checks.md +8 -7
  554. package/docs/reticle-manual.md +15 -5
  555. package/docs/skill-file.mdx +17 -79
  556. package/docs/skill-setup.md +9 -9
  557. package/docs/skill.md +200 -0
  558. package/docs/system-map.md +7 -7
  559. package/docs/telemetry.md +22 -24
  560. package/docs/testing.md +4 -4
  561. package/docs/token-efficiency.md +12 -12
  562. package/docs/tools/act-and-wait.mdx +9 -2
  563. package/docs/tools/act-sequence.mdx +6 -7
  564. package/docs/tools/act.mdx +2 -2
  565. package/docs/tools/assert.mdx +18 -17
  566. package/docs/tools/console.mdx +9 -9
  567. package/docs/tools/inspect.mdx +16 -7
  568. package/docs/tools/look.mdx +24 -0
  569. package/docs/tools/navigate.mdx +5 -3
  570. package/docs/tools/network.mdx +2 -2
  571. package/docs/tools/observe.mdx +6 -6
  572. package/docs/tools/overview.mdx +34 -33
  573. package/docs/tools/query.mdx +5 -5
  574. package/docs/tools/session-and-feedback.mdx +13 -4
  575. package/docs/tools/sessions.mdx +8 -8
  576. package/docs/tools/snapshot.mdx +6 -5
  577. package/docs/tools/state.mdx +9 -9
  578. package/docs/tools/tools-and-run.mdx +26 -24
  579. package/docs/tools/verify.mdx +28 -0
  580. package/docs/tools/wait-for.mdx +8 -4
  581. package/docs/troubleshooting.mdx +21 -6
  582. package/docs/usage.md +51 -45
  583. package/docs/use-cases.mdx +3 -3
  584. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  585. package/docs/vs-playwright-mcp.mdx +3 -1
  586. package/docs/what-is-recorded.md +7 -5
  587. package/docs/what-is-reticle.mdx +2 -2
  588. package/docs/why-reticle.mdx +1 -1
  589. package/package.json +6 -5
  590. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  591. package/dist/command/cli/demo/demo-page.js +0 -249
  592. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  593. package/dist/command/cli/demo/demo-run.js +0 -138
  594. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  595. package/dist/judgement/hunt/hunt-report.js +0 -84
  596. package/dist/language/flows/buddy-status.d.ts +0 -25
  597. package/dist/language/flows/buddy-status.js +0 -32
  598. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  599. package/dist/language/flows/change/watch-batcher.js +0 -19
  600. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  601. package/dist/memory/cloud/harness-offer.js +0 -145
  602. package/dist/surface/tools/feature-capture.d.ts +0 -151
  603. package/dist/surface/tools/feature-capture.js +0 -235
  604. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  605. package/dist/surface/tools/tool-hit-rate.js +0 -90
  606. package/dist/telemetry/harness-drive.d.ts +0 -4
  607. package/dist/telemetry/harness-drive.js +0 -35
  608. package/dist/telemetry/identify.d.ts +0 -22
  609. package/dist/telemetry/identify.js +0 -73
  610. package/docs/cli/capsules.mdx +0 -70
  611. package/docs/cli/hunt.mdx +0 -73
  612. package/docs/cli/identify.mdx +0 -76
  613. package/docs/cli/kill.mdx +0 -91
  614. package/docs/cli/watch.mdx +0 -62
@@ -18,7 +18,11 @@
18
18
  * leaving a verdict of `unknown` to be read as a pass.
19
19
  */
20
20
  import { appFindings } from './app-findings.js';
21
- import { asRecord, asString, ReticleTool, Verified } from '@reticlehq/core';
21
+ import { MSG_OPENED_MENU, MSG_ROUTE_GUESS_MISSED, claimsOnlyRoute } from './route-guess.js';
22
+ import { asRecord, asString, ActionType, NO_SUCH_FLOW, ReplayStatus, ReticleTool, ScriptStatus, Verified, } from '@reticlehq/core';
23
+ import { supersededChecks } from '@reticlehq/engine/evidence/superseded-checks.js';
24
+ import { PredicateSchema } from '@reticlehq/engine/question/predicate/predicate-schema.js';
25
+ import { describeWaitTarget } from '@reticlehq/engine/evidence/unsettled.js';
22
26
  function refusedAsDestructive(call) {
23
27
  const error = asString(asRecord(call.result)['error']) ?? '';
24
28
  return call.isError && error.includes(DESTRUCTIVE_REFUSAL);
@@ -130,6 +134,8 @@ export const ReplayOutcome = {
130
134
  ERROR: 'error',
131
135
  /** Stopped at a step the flow marks destructive: not run, which is not a regression. */
132
136
  GUARDED: 'guarded',
137
+ /** Not saved on this computer: nothing ran, which is not a regression either. */
138
+ MISSING: 'missing',
133
139
  };
134
140
  export function replayedFlows(toolCalls) {
135
141
  const out = [];
@@ -142,9 +148,13 @@ export function replayedFlows(toolCalls) {
142
148
  const status = call.isError ? ReplayOutcome.ERROR : asString(result['status']);
143
149
  out.push({
144
150
  name,
145
- status: ReplayOutcome.ERROR === status && message.includes(DESTRUCTIVE_REFUSAL)
146
- ? ReplayOutcome.GUARDED
147
- : status,
151
+ status: ReplayOutcome.ERROR !== status
152
+ ? status
153
+ : message.includes(DESTRUCTIVE_REFUSAL)
154
+ ? ReplayOutcome.GUARDED
155
+ : message.includes(NO_SUCH_FLOW)
156
+ ? ReplayOutcome.MISSING
157
+ : status,
148
158
  });
149
159
  }
150
160
  return out;
@@ -180,10 +190,82 @@ function describeClaim(until) {
180
190
  return 'a request or a signal';
181
191
  return kind;
182
192
  }
193
+ /** The declared consequence: `until`, or `predicate`, its alias on act_and_wait and on assert. */
194
+ function untilOf(args) {
195
+ return args['until'] ?? args['predicate'];
196
+ }
197
+ /** A `no` on a click whose only claim was a route: the driver's guess, not the app (route-guess.ts). */
198
+ function routeGuessMissed(args, result) {
199
+ return Verified.NO === result['verified'] && claimsOnlyRoute(untilOf(args));
200
+ }
201
+ /** The line a re-press graded undecided carries instead of the raw `no`. */
202
+ const MSG_REPRESS = "a second press of a control whose claim already held: the Harness's own extra action, not the app";
203
+ /** Every check in drive order: act_and_wait with an `until` and asserts, through reticle_run too. */
204
+ function gradedChecks(toolCalls) {
205
+ const heldPresses = new Set();
206
+ const out = [];
207
+ const checks = toolCalls.flatMap((made, index) => {
208
+ const call = throughRun(made);
209
+ const args = asRecord(call.args);
210
+ const until = untilOf(args);
211
+ const isCheck = ReticleTool.ASSERT === call.name ||
212
+ (ReticleTool.ACT_AND_WAIT === call.name && until !== undefined);
213
+ if (!isCheck || call.isError)
214
+ return [];
215
+ const predicate = PredicateSchema.safeParse(until);
216
+ const key = predicate.success
217
+ ? `${predicate.data.kind}|${describeWaitTarget(predicate.data)}`
218
+ : JSON.stringify(until ?? null);
219
+ return [{ index, call, args, result: asRecord(call.result), key }];
220
+ });
221
+ const superseded = supersededChecks(checks.map(({ call, result, key }) => ({
222
+ key,
223
+ passive: ReticleTool.ASSERT === call.name,
224
+ held: Verified.YES === asString(result['verified']),
225
+ failed: Verified.NO === asString(result['verified']),
226
+ })));
227
+ for (const [at, { index, args, result, key }] of checks.entries()) {
228
+ // The driver's own wrong guess about the route checked the driver, not the app.
229
+ if (routeGuessMissed(args, result))
230
+ continue;
231
+ const verified = asString(result['verified']);
232
+ // A passive assert that read too early: see superseded-checks.ts.
233
+ if (superseded.has(at))
234
+ continue;
235
+ // A second press of a control whose claim already held is the Harness's own extra action.
236
+ const ref = asString(args['ref']);
237
+ const pressed = ref === undefined ? undefined : `${ref}|${key}`;
238
+ const repress = Verified.NO === verified && pressed !== undefined && heldPresses.has(pressed);
239
+ if (Verified.YES === verified && pressed !== undefined)
240
+ heldPresses.add(pressed);
241
+ const outcome = Verified.YES === verified
242
+ ? 'held'
243
+ : Verified.NO === verified && !repress
244
+ ? 'failed'
245
+ : 'undecided';
246
+ out.push({ index, key, outcome, repress });
247
+ }
248
+ return out;
249
+ }
250
+ /**
251
+ * A `reticle_run` call as the tool it ran. A navigation made through it was recorded under the
252
+ * run's name, and a run that navigated between two pages said it made no action against the app.
253
+ */
254
+ function throughRun(call) {
255
+ if (ReticleTool.RUN !== call.name)
256
+ return call;
257
+ const args = asRecord(call.args);
258
+ const name = asString(args['tool']);
259
+ return name === undefined ? call : { ...call, name, args: asRecord(args['args']) };
260
+ }
183
261
  /** Reduce the raw call log to the actions that actually drove the app. */
184
262
  export function drivenSteps(toolCalls) {
185
263
  const steps = [];
186
- for (const [index, call] of toolCalls.entries()) {
264
+ const represses = new Set(gradedChecks(toolCalls)
265
+ .filter((check) => check.repress)
266
+ .map((check) => check.index));
267
+ for (const [index, made] of toolCalls.entries()) {
268
+ const call = throughRun(made);
187
269
  if (!DRIVING_TOOLS.has(call.name))
188
270
  continue;
189
271
  const args = asRecord(call.args);
@@ -193,19 +275,49 @@ export function drivenSteps(toolCalls) {
193
275
  if (refusedAsDestructive(call))
194
276
  continue;
195
277
  const action = ReticleTool.NAVIGATE === call.name ? 'navigate' : (asString(args['action']) ?? 'act');
278
+ const guessMissed = !call.isError && routeGuessMissed(args, result);
279
+ if (represses.has(index)) {
280
+ steps.push({
281
+ action,
282
+ target: targetOf(args, result),
283
+ verified: Verified.UNKNOWN,
284
+ because: MSG_REPRESS,
285
+ claimed: describeClaim(untilOf(args)),
286
+ evidence: [],
287
+ });
288
+ continue;
289
+ }
290
+ // A menu or dialog it opened is the way to the route it named, not a wrong guess.
291
+ const opened = guessMissed && 0 < openedADialog(result, toolCalls.slice(index + 1)).length;
196
292
  steps.push({
293
+ ...(guessMissed ? { guess: true } : {}),
197
294
  action,
198
295
  target: targetOf(args, result),
199
- verified: call.isError ? 'error' : asString(result['verified']),
200
- because: call.isError ? asString(result['error']) : asString(result['because']),
201
- claimed: describeClaim(args['until']),
202
- evidence: call.isError
296
+ verified: call.isError
297
+ ? 'error'
298
+ : guessMissed
299
+ ? Verified.UNKNOWN
300
+ : asString(result['verified']),
301
+ because: call.isError
302
+ ? asString(result['error'])
303
+ : opened
304
+ ? MSG_OPENED_MENU
305
+ : guessMissed
306
+ ? MSG_ROUTE_GUESS_MISSED
307
+ : asString(result['because']),
308
+ claimed: describeClaim(untilOf(args)),
309
+ evidence: call.isError || opened
203
310
  ? []
204
311
  : [...evidenceOf(result), ...openedADialog(result, toolCalls.slice(index + 1))],
205
312
  });
206
313
  }
207
314
  return steps;
208
315
  }
316
+ /** Whether the drive did anything to the app: an action that ran, or a flow it replayed. */
317
+ export function actedOnApp(toolCalls) {
318
+ return (drivenSteps(toolCalls).some((step) => 'error' !== step.verified) ||
319
+ 0 < replayedFlows(toolCalls).length);
320
+ }
209
321
  /**
210
322
  * The account, as lines.
211
323
  *
@@ -218,7 +330,7 @@ export function drivenSteps(toolCalls) {
218
330
  /** Every `__reticle_*` query parameter, wherever it sits in the route. */
219
331
  const RETICLE_PARAMS = /[?&]__reticle_[^&#]*/g;
220
332
  /** The pages the drive's own snapshots reported, in order, each distinct page once. */
221
- function pagesReached(toolCalls) {
333
+ export function pagesReached(toolCalls) {
222
334
  const pages = [];
223
335
  for (const call of toolCalls) {
224
336
  if (ReticleTool.SNAPSHOT !== call.name || call.isError)
@@ -231,50 +343,131 @@ function pagesReached(toolCalls) {
231
343
  }
232
344
  return pages;
233
345
  }
346
+ /** The values the drive's acts filled or typed, sequence steps included. */
347
+ export function typedValues(toolCalls) {
348
+ const out = [];
349
+ const read = (act) => {
350
+ const inner = asRecord(act['args']);
351
+ const value = asString(inner['value']) ?? asString(inner['text']);
352
+ if (value !== undefined &&
353
+ (ActionType.FILL === act['action'] || ActionType.TYPE === act['action']))
354
+ out.push(value);
355
+ };
356
+ for (const call of toolCalls) {
357
+ const steps = call.args['steps'];
358
+ if (Array.isArray(steps))
359
+ for (const step of steps)
360
+ read(asRecord(step));
361
+ else
362
+ read(call.args);
363
+ }
364
+ return out;
365
+ }
234
366
  /** How the drive's checks came out: act_and_wait with an `until`, and asserts. */
235
367
  export function checkTally(toolCalls) {
236
- // One check per control and claim, at its worst: a live drive pressed "Sign in" fifteen times and
237
- // reported "15 of 15 check(s) held" for one fact proved fifteen times over.
238
- const worst = new Map();
239
- for (const call of toolCalls) {
240
- const args = asRecord(call.args);
241
- const isCheck = ReticleTool.ASSERT === call.name ||
242
- (ReticleTool.ACT_AND_WAIT === call.name && args['until'] !== undefined);
243
- if (!isCheck || call.isError)
368
+ // One check per (kind, claim, outcome), exactly as the platform counts a run's checks: a live
369
+ // drive pressed "Sign in" fifteen times and read "15 of 15 check(s) held" for one fact, and an
370
+ // answer that counted by control said "2 of 2" beside a dashboard counting the same run otherwise.
371
+ const seen = new Set();
372
+ const tally = { held: 0, failed: 0, undecided: 0 };
373
+ const count = (key, now) => {
374
+ if (seen.has(`${key}|${now}`))
375
+ return;
376
+ seen.add(`${key}|${now}`);
377
+ tally[now] += 1;
378
+ };
379
+ for (const check of gradedChecks(toolCalls))
380
+ count(check.key, check.outcome);
381
+ // A replayed flow is a check too: its own expects decided it. A passed replay counted as "no
382
+ // check" and its run read NOT PROVED beside a dashboard that said Passed.
383
+ for (const replay of replayedFlows(toolCalls)) {
384
+ const now = REPLAY_CHECK[replay.status ?? ''];
385
+ if (now === undefined)
244
386
  continue;
245
- const result = asRecord(call.result);
246
- const effect = asRecord(result['effect']);
247
- const control = asString(effect['testid']) ??
248
- `${asString(effect['role']) ?? ''} ${asString(effect['name']) ?? asString(args['ref']) ?? ''}`;
249
- const key = `${call.name}|${control}|${JSON.stringify(args['until'] ?? args['predicate'] ?? null)}`;
250
- const verified = asString(result['verified']);
251
- const now = Verified.YES === verified ? 'held' : Verified.NO === verified ? 'failed' : 'undecided';
252
- const before = worst.get(key);
253
- if (before === undefined || 'failed' === now || ('undecided' === now && 'held' === before))
254
- worst.set(key, now);
387
+ count(`${ReticleTool.FLOW_REPLAY}|${replay.name}`, now);
255
388
  }
256
- const tally = { held: 0, failed: 0, undecided: 0 };
257
- for (const verdict of worst.values())
258
- tally[verdict] += 1;
259
389
  return tally;
260
390
  }
391
+ /** A replay as a check. Guarded and missing never ran, so they are no check at all. */
392
+ const REPLAY_CHECK = {
393
+ [ReplayOutcome.OK]: 'held',
394
+ [ReplayOutcome.ERROR]: 'failed',
395
+ [ReplayOutcome.DRIFT]: 'undecided',
396
+ [ReplayStatus.UNVERIFIABLE]: 'undecided',
397
+ };
398
+ /** Statuses that leave a plan proved: passed, or a side road deliberately not taken (named in its line). */
399
+ const SETTLED_JOURNEY = new Set([ScriptStatus.PASSED, ScriptStatus.NOT_TAKEN]);
400
+ /**
401
+ * A plan run's verdict is its journeys', decided as the platform decides it (`planRunVerdict`): any
402
+ * failed → failed; every journey passed (or deliberately not taken) → proved; some passed beside
403
+ * journeys left undecided or blocked → not proved. Undefined when there is no plan.
404
+ *
405
+ * "Any passed → proved" read PROVED for a plan whose other journeys a credit cut-off had blocked:
406
+ * one journey proved and the rest never decided, reported as the whole plan proved.
407
+ */
408
+ function journeysVerdict(journeys, counts) {
409
+ if (0 === journeys.length)
410
+ return undefined;
411
+ const of = (status) => journeys.filter((j) => status === j.status).length;
412
+ const total = String(journeys.length);
413
+ const passed = of(ScriptStatus.PASSED);
414
+ if (0 < of(ScriptStatus.FAILED))
415
+ return {
416
+ verified: Verified.NO,
417
+ line: `NOT PROVED — ${String(of(ScriptStatus.FAILED))} of ${total} journey(s) failed${counts}.`,
418
+ };
419
+ if (0 < passed && journeys.every((j) => SETTLED_JOURNEY.has(j.status)))
420
+ return {
421
+ verified: Verified.YES,
422
+ line: `PROVED — ${String(passed)} of ${total} journey(s) passed${counts}.`,
423
+ };
424
+ if (0 < passed)
425
+ return {
426
+ verified: Verified.UNKNOWN,
427
+ line: `NOT PROVED — ${String(passed)} of ${total} journey(s) passed and the rest were not decided${counts}.`,
428
+ };
429
+ return { verified: Verified.UNKNOWN, line: `NOT PROVED — no journey passed${counts}.` };
430
+ }
261
431
  /**
262
- * The first line a caller reads, and the one the HUD ends on. A drive whose only passing check was
263
- * a page change, beside a refund that failed, is NOT "proved its checks"; that line ended a run
264
- * where the journey it was asked to prove had failed.
432
+ * The first line a caller reads, and the one the HUD ends on, with the verdict it states. A drive
433
+ * whose only passing check was a page change, beside a refund that failed, is NOT "proved its
434
+ * checks"; that line ended a run where the journey it was asked to prove had failed.
265
435
  */
266
- export function verdictLine(tally) {
436
+ export function runVerdict(tally, goalMet,
437
+ /** A plan's journeys: when there are any, their verdict is the run's. */
438
+ journeys = []) {
267
439
  const total = tally.held + tally.failed + tally.undecided;
268
- if (0 === total)
269
- return 'NOT PROVED: the drive ran no check.';
270
440
  const counts = `${String(tally.held)} of ${String(total)} check(s) held, ${String(tally.failed)} failed, ${String(tally.undecided)} undecided`;
441
+ const planned = journeysVerdict(journeys, 0 === total ? '' : `; ${counts}`);
442
+ const not = (line) => ({ verified: Verified.UNKNOWN, line });
443
+ // Journeys that passed are not the run's goal reached: the goals the run was asked decide it too.
444
+ if (Verified.YES === planned?.verified && false === goalMet)
445
+ return not(`NOT PROVED — ${planned.line.slice('PROVED — '.length).replace(/\.$/, '')}, but the goal was not reached.`);
446
+ if (planned !== undefined)
447
+ return planned;
448
+ if (0 === total)
449
+ return not('NOT PROVED: the drive ran no check.');
271
450
  if (0 < tally.failed)
272
- return `NOT PROVED — ${counts}. The failures below are findings.`;
451
+ return {
452
+ verified: Verified.NO,
453
+ line: `NOT PROVED — ${counts}. The failures below are findings.`,
454
+ };
273
455
  if (0 < tally.undecided)
274
- return `NOT PROVED — ${counts}.`;
275
- return `PROVED — ${counts}.`;
456
+ return not(`NOT PROVED — ${counts}.`);
457
+ // Checks that held on the way are not the journey done.
458
+ if (false === goalMet)
459
+ return not(`NOT PROVED — ${counts}, but the goal was not reached.`);
460
+ return { verified: Verified.YES, line: `PROVED — ${counts}.` };
461
+ }
462
+ /** The line alone. */
463
+ export function verdictLine(tally, goalMet, journeys = []) {
464
+ return runVerdict(tally, goalMet, journeys).line;
276
465
  }
277
- export function describeDrive(toolCalls, savedFlows, unverifiedFlows = []) {
466
+ /** Whether the run is proved, exactly as its headline says: the `proved` an answer carries. */
467
+ export function runProved(tally, goalMet, journeys = []) {
468
+ return Verified.YES === runVerdict(tally, goalMet, journeys).verified;
469
+ }
470
+ export function describeDrive(toolCalls, savedFlows, unverifiedFlows = [], goalMet, journeys = []) {
278
471
  const steps = drivenSteps(toolCalls);
279
472
  const replays = replayedFlows(toolCalls);
280
473
  /*
@@ -291,11 +484,15 @@ export function describeDrive(toolCalls, savedFlows, unverifiedFlows = []) {
291
484
  const failed = replays.filter((r) => ReplayOutcome.ERROR === r.status);
292
485
  const drifted = replays.filter((r) => ReplayOutcome.DRIFT === r.status);
293
486
  const guarded = replays.filter((r) => ReplayOutcome.GUARDED === r.status);
487
+ const missing = replays.filter((r) => ReplayOutcome.MISSING === r.status);
294
488
  const lines = [
295
489
  `Replayed ${String(replays.length)} recorded journey(s) with NO model in the loop: ` +
296
490
  `${String(held.length)} still hold, ${String(failed.length)} failed, ${String(drifted.length)} drifted` +
297
- `${0 === guarded.length ? '' : `, ${String(guarded.length)} not run`}.`,
491
+ `${0 === guarded.length ? '' : `, ${String(guarded.length)} not run`}` +
492
+ `${0 === missing.length ? '' : `, ${String(missing.length)} not on this computer`}.`,
298
493
  ];
494
+ if (0 < missing.length)
495
+ lines.push(` MISSING: ${missing.map((r) => r.name).join(', ')} — not saved on this computer, or calls a flow that is not, so it never ran. Not a regression: pull or record them here first.`);
299
496
  if (0 < failed.length)
300
497
  lines.push(` FAILED: ${failed.map((r) => r.name).join(', ')} — regressions in journeys that used to pass.`);
301
498
  if (0 < guarded.length)
@@ -304,18 +501,32 @@ export function describeDrive(toolCalls, savedFlows, unverifiedFlows = []) {
304
501
  lines.push(` DRIFTED: ${drifted.map((r) => r.name).join(', ')} — the app moved under these recordings; the flow needs re-anchoring, not the app fixing.`);
305
502
  return lines.join('\n');
306
503
  })();
307
- if (0 === steps.length)
308
- return (replayLine ??
309
- 'Nothing was driven and nothing was replayed: the run made no action against the app.');
504
+ // A plan run leads with its journeys' verdict even when the model drove nothing: its replays, or
505
+ // a journey a guard stopped, are a result, never "no action against the app".
506
+ if (0 === steps.length) {
507
+ const lead = 0 === journeys.length ? undefined : verdictLine(checkTally(toolCalls), goalMet, journeys);
508
+ return [
509
+ lead,
510
+ replayLine ??
511
+ (lead === undefined
512
+ ? 'Nothing was driven and nothing was replayed: the run made no action against the app.'
513
+ : undefined),
514
+ ]
515
+ .filter((line) => line !== undefined)
516
+ .join('\n');
517
+ }
310
518
  const proved = steps.filter((step) => Verified.YES === step.verified);
311
519
  const failed = steps.filter((step) => Verified.NO === step.verified);
312
- const undecided = steps.filter((step) => Verified.YES !== step.verified && Verified.NO !== step.verified);
520
+ // The driver's own route guesses are no check (as `checkTally` counts), so not "not decided".
521
+ const guesses = steps.filter((step) => true === step.guess);
522
+ const undecided = steps.filter((step) => true !== step.guess && Verified.YES !== step.verified && Verified.NO !== step.verified);
313
523
  const pages = pagesReached(toolCalls);
314
524
  const lines = [
315
- verdictLine(checkTally(toolCalls)),
525
+ verdictLine(checkTally(toolCalls), goalMet, journeys),
316
526
  ...(replayLine === undefined ? [] : [replayLine]),
317
- `Drove ${String(steps.length)} action(s): ${String(proved.length)} proved, ` +
318
- `${String(failed.length)} failed, ${String(undecided.length)} not decided.`,
527
+ // The outcomes are counted once, in the checks line above: no second breakdown here.
528
+ `Drove ${String(steps.length)} action(s)` +
529
+ (0 === guesses.length ? '.' : `; ${String(guesses.length)} guess of its own, not a check.`),
319
530
  // How DEEP it got. An action count reads the same for a checkout walked to its receipt and for
320
531
  // eleven clicks on the home page; the pages reached are what tell them apart.
321
532
  ...(0 === pages.length
@@ -323,7 +534,7 @@ export function describeDrive(toolCalls, savedFlows, unverifiedFlows = []) {
323
534
  : [`Reached ${String(pages.length)} page(s): ${pages.join(' → ')}.`]),
324
535
  ...appFindings(toolCalls),
325
536
  ];
326
- const listed = [...failed, ...proved, ...undecided].slice(0, Math.max(MAX_LISTED, Math.min(failed.length, MAX_FAILED)));
537
+ const listed = [...failed, ...proved, ...undecided, ...guesses].slice(0, Math.max(MAX_LISTED, Math.min(failed.length, MAX_FAILED)));
327
538
  for (const step of listed) {
328
539
  const verdict = step.verified ?? 'nothing declared';
329
540
  const because = step.because === undefined ? '' : ` — ${step.because}`;
@@ -349,10 +560,16 @@ export function describeDrive(toolCalls, savedFlows, unverifiedFlows = []) {
349
560
  const confirmed = confirmedDestructive(toolCalls);
350
561
  if (0 < confirmed)
351
562
  lines.push(`${String(confirmed)} destructive action(s) were confirmed and REALLY RAN against the app (the drive confirms one only after the gate refuses it; the refusal itself changed nothing).`);
352
- if (0 < failed.length)
353
- lines.push(`${String(failed.length)} action(s) FAILED — the app did not do what the drive declared it would. These are findings.`);
354
- if (0 < undecided.length)
355
- lines.push(`${String(undecided.length)} action(s) were NOT PROVED. That is undecided evidence, not a failure: it calls for a better check, not a code change.`);
563
+ // Counted from the same graded checks as the checks line, never from the raw step verdicts: an
564
+ // answer read "0 failed" beside "1 action(s) FAILED … These are findings" about one re-press.
565
+ const tally = checkTally(toolCalls);
566
+ if (0 < tally.failed)
567
+ lines.push(`${String(tally.failed)} check(s) FAILED — the app did not do what the drive declared it would. These are findings.`);
568
+ if (0 < tally.undecided)
569
+ lines.push(`${String(tally.undecided)} check(s) undecided. That is undecided evidence, not a failure: it calls for a better check, not a code change.`);
570
+ const undeclared = undecided.filter((step) => step.claimed === undefined).length;
571
+ if (0 < undeclared)
572
+ lines.push(`${String(undeclared)} action(s) declared no consequence, so they prove nothing either way: not a check, not a failure.`);
356
573
  // A flow with no step that asserts anything replays as "verified nothing": offered as a replay it
357
574
  // reads as evidence, so it is named for what it is instead.
358
575
  const empty = new Set(unverifiedFlows);
@@ -0,0 +1,120 @@
1
+ /**
2
+ * The Harness drives this daemon is running, and the ones it finished, by run id.
3
+ *
4
+ * A drive takes minutes and an MCP client gives a tool call about one. Awaited inside the call, a
5
+ * drive outlived the client's timeout: the agent got no run id, the daemon kept driving and
6
+ * spending, and a retry started a second paid drive. So a drive is started here and the call only
7
+ * waits on it for a while; whoever asks again by run id (the same agent, another one, the HUD)
8
+ * reads the same entry.
9
+ *
10
+ * No I/O and no tool surface: what to run and where to write it arrive as functions, so this stays
11
+ * a sink the surface hands things to.
12
+ */
13
+ import { type ImpactSnapshot } from '@reticlehq/core';
14
+ export declare const DriveStatus: {
15
+ readonly RUNNING: "running";
16
+ readonly DONE: "done";
17
+ readonly STOPPED: "stopped";
18
+ readonly BROKEN: "broken";
19
+ /** Refused before it drove anything (switched off, no credits, locked): not a broken drive. */
20
+ readonly REFUSED: "refused";
21
+ };
22
+ export type DriveStatus = (typeof DriveStatus)[keyof typeof DriveStatus];
23
+ /**
24
+ * Thrown when the platform or the gate refuses a drive before it drives. Releasing a tab reported
25
+ * such a run as "broken", which reads as a fault in the Harness; a refusal is a refusal.
26
+ */
27
+ export declare class DriveRefusedError extends Error {
28
+ }
29
+ /** Who asked for the drive. */
30
+ export declare const DriveOrigin: {
31
+ readonly AGENT: "agent";
32
+ readonly HUD: "hud";
33
+ readonly CHAT: "chat";
34
+ readonly TRY: "try";
35
+ };
36
+ export type DriveOrigin = (typeof DriveOrigin)[keyof typeof DriveOrigin];
37
+ /**
38
+ * One drive, as it is written to `.reticle/runs/<run>.drive.json` and answered to a poll.
39
+ *
40
+ * The id is `harnessRun`, never `runId`: the sync uploads every file in that directory carrying a
41
+ * `runId` as a verification run, and this record would then collide with the drive's own run.
42
+ */
43
+ export interface DriveRecord {
44
+ harnessRun: string;
45
+ status: DriveStatus;
46
+ origin: DriveOrigin;
47
+ sessionId?: string;
48
+ startedAt: number;
49
+ endedAt?: number;
50
+ steps: number;
51
+ lastLine: string;
52
+ /** The tool's full answer, once the drive has ended. */
53
+ result?: Record<string, unknown>;
54
+ /** Why it broke, when it threw instead of answering. */
55
+ error?: string;
56
+ }
57
+ /** What a running drive reads from whoever started it. */
58
+ export interface DriveControl {
59
+ /** True once somebody asked it to stop. */
60
+ stopped: () => boolean;
61
+ /** Text somebody said to it since it last asked, oldest first. */
62
+ takeSaid: () => string[];
63
+ }
64
+ export interface StartDrive {
65
+ harness: string;
66
+ runId: string;
67
+ origin: DriveOrigin;
68
+ sessionId?: string;
69
+ now: () => number;
70
+ persist: (record: DriveRecord) => Promise<void>;
71
+ run: (control: DriveControl) => Promise<{
72
+ status: DriveStatus;
73
+ result: Record<string, unknown>;
74
+ }>;
75
+ }
76
+ export declare function startDrive(start: StartDrive): DriveRecord;
77
+ /** The drive this run id names, while this daemon still holds it. */
78
+ export declare function driveRecord(runId: string): DriveRecord | undefined;
79
+ /**
80
+ * The drive running on this session, if any. An unnamed session matches any running drive, and a
81
+ * drive started without one matches any session: either way it is the tab a second start would use.
82
+ */
83
+ export declare function runningDrive(sessionId: string | undefined): DriveRecord | undefined;
84
+ /** Every drive still running, for the HUD. */
85
+ export declare function runningDrives(): DriveRecord[];
86
+ /**
87
+ * Wait until the drive ends, `ms` passes (no limit when undefined), or `signal` aborts — whichever
88
+ * is first. Ending the wait never ends the drive. `onChange` hears every step while waiting.
89
+ */
90
+ export declare function awaitDrive(runId: string, ms: number | undefined, signal?: AbortSignal, onChange?: (record: DriveRecord) => void): Promise<void>;
91
+ /** Ask a running drive to stop. False when there is no such drive running. */
92
+ export declare function stopDrive(runId: string): boolean;
93
+ /** Queue text for the driver's next turn. False when there is no such drive running. */
94
+ export declare function sayToDrive(runId: string, text: string): boolean;
95
+ /** One tool call a drive made. `harness` may be a lane's id (`<harness>-L2`). */
96
+ export declare function noteDriveStep(harness: string, tool: string): void;
97
+ /** A line the drive narrated to the HUD. */
98
+ export declare function noteDriveLine(harness: string, line: string): void;
99
+ /** Hear every step a drive takes, so a panel showing its count can repaint. Returns the unsubscribe. */
100
+ export declare function onDriveStep(listener: (record: DriveRecord) => void): () => void;
101
+ /** Hear every drive start and end, from any origin. Returns the unsubscribe. */
102
+ export declare function onDriveChange(listener: (record: DriveRecord) => void): () => void;
103
+ /**
104
+ * The notes the agent has not heard: a drive started or finished, from any origin. Taken once.
105
+ * `except` is the run the agent is already reading, which needs no note about itself.
106
+ */
107
+ export declare function takeDriveNotes(except?: string): string[];
108
+ /** Tests only: every drive and note forgotten. */
109
+ export declare function forgetDrives(): void;
110
+ /**
111
+ * How long one poll waits on a drive before answering `running`. Under the 60s tool timeout most
112
+ * MCP clients use, with room for the answer to travel; a poll's `wait` overrides it.
113
+ */
114
+ export declare const POLL_WAIT_DEFAULT_S = 50;
115
+ /** The exact call that reads a drive: the same call while it runs and once it has ended. */
116
+ export declare function pollCall(runId: string): string;
117
+ /** What a poll answering `running` tells the agent to do, so it stays rather than walks away. */
118
+ export declare function stillRunning(runId: string, steps: number, elapsedS: number): string;
119
+ /** The impact snapshot, with the drive running on this tab when there is one. */
120
+ export declare function withRunningDrive(snapshot: ImpactSnapshot | undefined, sessionId: string): ImpactSnapshot | undefined;