@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
@@ -10,7 +10,7 @@
10
10
  * the person can fix in ten seconds (open the app), and leaving it unclaimed lets the chat tell them
11
11
  * exactly that. One drive at a time: a second request waits for the first to finish.
12
12
  */
13
- import { DriveMode, DriveTarget, LinkPath, PLATFORM_LINK_VERSION, PresenterTone, TOOL_SESSION_LIMITS, parseDriveSpec, parseToolSessionReply, sessionAskRetryable, } from '@reticlehq/core';
13
+ import { DriveMode, DriveTarget, LinkPath, PLATFORM_LINK_VERSION, PresenterTone, RunFlowStatus, TOOL_SESSION_LIMITS, driveFlowStatus, parseDriveSpec, parseToolSessionReply, sessionAskRetryable, } from '@reticlehq/core';
14
14
  import { serverOptionsFromEnv } from './server-driver.js';
15
15
  /**
16
16
  * How often to ask while an app is connected.
@@ -141,7 +141,7 @@ export function startRemoteDrives(deps) {
141
141
  let outcome;
142
142
  let framesSent = 0;
143
143
  try {
144
- outcome = await deps.drive(drive.goal, sessionId);
144
+ outcome = await deps.drive(drive.goal, sessionId, parsed.spec);
145
145
  }
146
146
  catch (error) {
147
147
  outcome = { ok: false, summary: error instanceof Error ? error.message : String(error) };
@@ -288,14 +288,23 @@ export const NO_OWN_TAB = "No tab of this project is connected to Reticle on thi
288
288
  * daemon serves every project on the machine but polls with ONE credential, so without this a
289
289
  * request made in project A drove project B's tab and sent pictures of it to A's chat.
290
290
  */
291
- export async function pickOwnDriveSession(tabs, goal, apiKey, keyOf) {
291
+ export async function pickOwnDriveSession(tabs, goal, apiKey, keyOf,
292
+ /**
293
+ * Open the project's app when none of its tabs is connected, and the session it opened. A
294
+ * dashboard Re-verify with the dev server up and no tab open was answered "Open this project's
295
+ * app, then ask again" by a daemon that knew the app's address.
296
+ */
297
+ reopen) {
292
298
  const own = [];
293
299
  for (const tab of tabs) {
294
300
  const key = await keyOf(tab.sessionId).catch(() => undefined);
295
301
  if (key === apiKey)
296
302
  own.push(tab);
297
303
  }
298
- return pickDriveSession(own, goal) ?? null;
304
+ const picked = pickDriveSession(own, goal);
305
+ if (picked !== undefined)
306
+ return picked;
307
+ return (await reopen?.().catch(() => undefined)) ?? null;
299
308
  }
300
309
  /** The address of an http(s) URL, `host:port`, for matching a tab to the app a request names. */
301
310
  const hostOf = (url) => {
@@ -341,10 +350,14 @@ export function pickDriveSession(tabs, goal) {
341
350
  export function driveVerdict(out) {
342
351
  if (out.error !== undefined)
343
352
  return 'unknown';
344
- // A goal judged unmet, or a check that came back "no", is a failed drive whatever else held.
345
- if (false === out.goalMet)
346
- return 'no';
347
- if (0 < (out.checks?.failed ?? 0))
353
+ // A check that came back "no" is a failed drive whatever else held. A goal the model judged unmet
354
+ // is its opinion, not evidence: with no check against it the drive is not proved, never failed.
355
+ const graded = driveFlowStatus({
356
+ held: out.checks?.held ?? 0,
357
+ failed: out.checks?.failed ?? 0,
358
+ goalMet: out.goalMet,
359
+ });
360
+ if (RunFlowStatus.FAIL === graded)
348
361
  return 'no';
349
362
  // The quoted texts are looked for on the page the drive ENDED on. None there refutes the goal;
350
363
  // some missing does not, because a goal that quotes where it starts ("from "Count is 0" to
@@ -355,7 +368,7 @@ export function driveVerdict(out) {
355
368
  if (0 < goals.length && !goals.some((g) => 'yes' === g.verified))
356
369
  return 'unknown';
357
370
  // A yes needs a check that held behind it: the model saying the goal was met is not evidence.
358
- if (!out.proved || 0 === (out.checks?.held ?? 0))
371
+ if (!out.proved || RunFlowStatus.PASS !== graded)
359
372
  return 'unknown';
360
373
  if (true === out.goalMet)
361
374
  return 'yes';
@@ -1,5 +1,6 @@
1
1
  import { ScriptStatus, type FlowFile, type FlowStep, type PlanView } from '@reticlehq/core';
2
- import { type DriveScript } from '@reticlehq/core/artifacts';
2
+ import { type JourneyBy, type DriveScript } from '@reticlehq/core/artifacts';
3
+ import { type PlatformCredential } from './server-driver.js';
3
4
  type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
4
5
  export interface ScriptAsk {
5
6
  about: string;
@@ -25,24 +26,69 @@ export declare function personasIn(flows: readonly FlowFile[]): {
25
26
  }[];
26
27
  /** Equal for two steps that drive the same control the same way; the values never leave. */
27
28
  export declare function stepHash(step: FlowStep): string;
28
- export declare function proposeScript(platform: {
29
- url: string;
30
- apiKey: string;
31
- }, ask: ScriptAsk, doFetch?: FetchLike): Promise<{
29
+ /** What a run that names nothing asks for: the whole app, which the platform splits into journeys. */
30
+ export declare const WHOLE_APP_REQUEST = "Test my app: plan the journeys this app offers and drive them";
31
+ export declare function proposeScript(platform: PlatformCredential, ask: ScriptAsk, doFetch?: FetchLike): Promise<{
32
32
  script: DriveScript;
33
33
  planId?: string;
34
+ creditsSpent?: number;
35
+ } | {
36
+ refused: string;
34
37
  } | undefined>;
38
+ /**
39
+ * A plan the platform saved, as it stands now: somebody may have edited it on the dashboard since it
40
+ * last ran. Checked like a proposed one; `undefined` when it cannot be read or cannot run.
41
+ */
42
+ export declare function fetchScript(platform: PlatformCredential, planId: string, doFetch?: FetchLike): Promise<DriveScript | undefined>;
43
+ /**
44
+ * A rerun replays what passed before. A journey the plan's history shows passing, with the flows it
45
+ * saved, replays those flows; the model drives its goal only when they decide nothing (`fallback`),
46
+ * and a replay that fails is a regression, never re-driven. A rerun re-drove a journey that had
47
+ * passed, at a model's cost, and failed it twice. Journeys that already replay are left as planned.
48
+ */
49
+ export declare function replayFirst(script: DriveScript, plan: unknown): DriveScript;
35
50
  /** One journey's outcome, as the platform keeps it beside the plan. */
36
51
  export interface JourneyResult {
37
52
  id: string;
38
53
  title: string;
39
54
  status: ScriptStatus;
55
+ /** What happened, in a line: why a journey that never ran was blocked. */
56
+ line?: string;
57
+ /** Replayed with no model, or driven by it. Absent for a journey that never ran. */
58
+ by?: JourneyBy;
59
+ /** Model tokens it spent; 0 for a pure replay. */
60
+ tokens?: number;
61
+ /** Credits its model drives spent, when the platform said. */
62
+ credits?: number;
63
+ /** The flows it replayed or recorded: the platform links the journey to these. */
64
+ flows?: string[];
65
+ /** Whether the goals the run was asked were reached, once graded. Absent when none were judged. */
66
+ goalMet?: boolean;
67
+ }
68
+ /** How one journey that ran was answered, from the run (`JourneyRun`). */
69
+ export interface JourneyAnswer {
70
+ id: string;
71
+ by?: JourneyBy;
72
+ tokens: number;
73
+ credits?: number;
74
+ flows: string[];
40
75
  }
41
- /** How each journey of a run plan went, once each. */
42
- export declare function journeyResults(view: PlanView): JourneyResult[];
76
+ /**
77
+ * The plan only replays saved flows: no step anywhere, branch cases included, hands the model
78
+ * anything to do. Such a run spends no model turns, so the gates that guard a model drive do not
79
+ * apply to it.
80
+ */
81
+ export declare function drivesNothing(script: DriveScript): boolean;
82
+ /** The saved plan reads as one that only replays saved flows. Unreadable: not known to, so false. */
83
+ export declare function savedPlanDrivesNothing(platform: PlatformCredential, planId: string, doFetch?: FetchLike): Promise<boolean>;
84
+ /**
85
+ * A saved plan the run was refused for, or that broke before any journey ran, told to the plan
86
+ * anyway: every journey blocked, with the reason, so the plan's history records the attempt instead
87
+ * of showing nothing. Best-effort, like every report to the plan.
88
+ */
89
+ export declare function reportPlanBlocked(platform: PlatformCredential, planId: string, reason: string, doFetch?: FetchLike): Promise<boolean>;
90
+ /** How each journey of a run plan went, once each, matched to how it was answered by id. */
91
+ export declare function journeyResults(view: PlanView, answers?: readonly JourneyAnswer[]): JourneyResult[];
43
92
  /** Tell the platform how its plan went. A failure costs the next plan its memory, never this run. */
44
- export declare function reportPlanResults(platform: {
45
- url: string;
46
- apiKey: string;
47
- }, planId: string, results: readonly JourneyResult[], doFetch?: FetchLike): Promise<boolean>;
93
+ export declare function reportPlanResults(platform: PlatformCredential, planId: string, results: readonly JourneyResult[], runIds?: readonly string[], doFetch?: FetchLike): Promise<boolean>;
48
94
  export {};
@@ -12,9 +12,11 @@
12
12
  * The platform keeps every plan under an id, and is told afterwards how each journey went: that is
13
13
  * what the next plan learns from (what failed is driven first).
14
14
  */
15
+ import { readRefusal, refusalSentence } from './refusal.js';
15
16
  import { createHash } from 'node:crypto';
16
- import { ScriptStatus, StepEffect, } from '@reticlehq/core';
17
- import { DriveScriptSchema, checkScript } from '@reticlehq/core/artifacts';
17
+ import { ScriptStatus, asRecord, asString, StepEffect, } from '@reticlehq/core';
18
+ import { DriveScriptSchema, ScriptStepKind, checkScript, } from '@reticlehq/core/artifacts';
19
+ import { platformHeaders } from './server-driver.js';
18
20
  const SCRIPTS_PATH = '/v1/harness/scripts';
19
21
  const RESULTS_PATH = '/results';
20
22
  const TIMEOUT_MS = 90_000;
@@ -50,11 +52,21 @@ export function stepHash(step) {
50
52
  .digest('hex')
51
53
  .slice(0, STEP_HASH_CHARS);
52
54
  }
55
+ /** What a run that names nothing asks for: the whole app, which the platform splits into journeys. */
56
+ export const WHOLE_APP_REQUEST = 'Test my app: plan the journeys this app offers and drive them';
57
+ /**
58
+ * The goals a plan request carries. The platform refuses one that names nothing — no journey, no
59
+ * persona, nothing to replay — and no longer invents personas, so such a run asks for the whole app.
60
+ */
61
+ function goalsToAsk(ask) {
62
+ const named = 0 < ask.goals.length || 0 < ask.replay.length || 0 < (ask.personas?.length ?? 0);
63
+ return named ? ask.goals : [WHOLE_APP_REQUEST];
64
+ }
53
65
  export async function proposeScript(platform, ask, doFetch = (url, init) => fetch(url, init)) {
54
66
  try {
55
67
  const res = await doFetch(`${platform.url}${SCRIPTS_PATH}`, {
56
68
  method: 'POST',
57
- headers: { 'content-type': 'application/json', authorization: `Bearer ${platform.apiKey}` },
69
+ headers: platformHeaders(platform),
58
70
  body: JSON.stringify({
59
71
  about: ask.about,
60
72
  flows: ask.flows.map((flow) => ({
@@ -67,7 +79,7 @@ export async function proposeScript(platform, ask, doFetch = (url, init) => fetc
67
79
  checks: flow.steps.filter((step) => step.expect !== undefined || true === step.steps?.some((s) => s.expect !== undefined)).length,
68
80
  })),
69
81
  replay: ask.replay,
70
- goals: ask.goals,
82
+ goals: goalsToAsk(ask),
71
83
  gaps: ask.gaps,
72
84
  rules: ask.rules,
73
85
  ...(ask.personas === undefined || 0 === ask.personas.length
@@ -76,8 +88,9 @@ export async function proposeScript(platform, ask, doFetch = (url, init) => fetc
76
88
  }),
77
89
  signal: AbortSignal.timeout(TIMEOUT_MS),
78
90
  });
91
+ // The platform's own reason, so a drive that goes on without a plan can say why.
79
92
  if (!res.ok)
80
- return undefined;
93
+ return { refused: await refusalOf(res) };
81
94
  const body = (await res.json());
82
95
  const parsed = DriveScriptSchema.safeParse(body.script);
83
96
  if (!parsed.success || 0 < checkScript(parsed.data).length)
@@ -85,39 +98,158 @@ export async function proposeScript(platform, ask, doFetch = (url, init) => fetc
85
98
  return {
86
99
  script: parsed.data,
87
100
  ...('string' === typeof body.planId ? { planId: body.planId } : {}),
101
+ // What writing the plan cost: part of the run's spend, not free.
102
+ ...('number' === typeof body.creditsSpent ? { creditsSpent: body.creditsSpent } : {}),
88
103
  };
89
104
  }
90
105
  catch {
91
106
  return undefined;
92
107
  }
93
108
  }
109
+ async function refusalOf(res) {
110
+ // The code picks the lead sentence (refusal.ts), so what this says never rests on the wording.
111
+ return refusalSentence(readRefusal(await res.text().catch(() => '')), res.status);
112
+ }
113
+ /**
114
+ * A plan the platform saved, as it stands now: somebody may have edited it on the dashboard since it
115
+ * last ran. Checked like a proposed one; `undefined` when it cannot be read or cannot run.
116
+ */
117
+ export async function fetchScript(platform, planId, doFetch = (url, init) => fetch(url, init)) {
118
+ try {
119
+ const res = await doFetch(`${platform.url}${SCRIPTS_PATH}/${encodeURIComponent(planId)}`, {
120
+ method: 'GET',
121
+ headers: platformHeaders(platform),
122
+ signal: AbortSignal.timeout(TIMEOUT_MS),
123
+ });
124
+ if (!res.ok)
125
+ return undefined;
126
+ const plan = (await res.json());
127
+ const parsed = DriveScriptSchema.safeParse(plan.script);
128
+ return parsed.success && 0 === checkScript(parsed.data).length
129
+ ? replayFirst(parsed.data, plan)
130
+ : undefined;
131
+ }
132
+ catch {
133
+ return undefined;
134
+ }
135
+ }
136
+ /**
137
+ * A rerun replays what passed before. A journey the plan's history shows passing, with the flows it
138
+ * saved, replays those flows; the model drives its goal only when they decide nothing (`fallback`),
139
+ * and a replay that fails is a regression, never re-driven. A rerun re-drove a journey that had
140
+ * passed, at a model's cost, and failed it twice. Journeys that already replay are left as planned.
141
+ */
142
+ export function replayFirst(script, plan) {
143
+ const passedFlows = new Map();
144
+ const record = asRecord(plan);
145
+ const runs = Array.isArray(record['runs']) ? record['runs'] : [];
146
+ const batches = [...runs.map((run) => asRecord(run)['results']), record['results']];
147
+ for (const batch of batches) {
148
+ if (!Array.isArray(batch))
149
+ continue;
150
+ for (const raw of batch) {
151
+ const result = asRecord(raw);
152
+ const id = asString(result['id']);
153
+ const flows = Array.isArray(result['flows'])
154
+ ? result['flows'].filter((f) => 'string' === typeof f && 0 < f.length)
155
+ : [];
156
+ if (id !== undefined && ScriptStatus.PASSED === result['status'] && 0 < flows.length)
157
+ passedFlows.set(id, flows);
158
+ }
159
+ }
160
+ if (0 === passedFlows.size)
161
+ return script;
162
+ return {
163
+ ...script,
164
+ journeys: script.journeys.map((journey) => {
165
+ const flows = passedFlows.get(journey.id);
166
+ const goals = journey.steps.map((step) => ScriptStepKind.ACT === step.kind ? step.goal : undefined);
167
+ if (flows === undefined || journey.fallback !== undefined || goals.includes(undefined))
168
+ return journey;
169
+ return {
170
+ ...journey,
171
+ steps: flows.map((flow) => ({ kind: ScriptStepKind.REPLAY, flow })),
172
+ fallback: { goal: goals.join('; ') },
173
+ };
174
+ }),
175
+ };
176
+ }
177
+ /**
178
+ * The plan only replays saved flows: no step anywhere, branch cases included, hands the model
179
+ * anything to do. Such a run spends no model turns, so the gates that guard a model drive do not
180
+ * apply to it.
181
+ */
182
+ export function drivesNothing(script) {
183
+ return script.journeys.every((journey) => journey.steps.every((step) => ScriptStepKind.BRANCH === step.kind
184
+ ? step.cases.every((c) => c.steps.every((leaf) => ScriptStepKind.ACT !== leaf.kind))
185
+ : ScriptStepKind.ACT !== step.kind));
186
+ }
187
+ /** The saved plan reads as one that only replays saved flows. Unreadable: not known to, so false. */
188
+ export async function savedPlanDrivesNothing(platform, planId, doFetch = (url, init) => fetch(url, init)) {
189
+ const script = await fetchScript(platform, planId, doFetch);
190
+ return script !== undefined && drivesNothing(script);
191
+ }
192
+ /**
193
+ * A saved plan the run was refused for, or that broke before any journey ran, told to the plan
194
+ * anyway: every journey blocked, with the reason, so the plan's history records the attempt instead
195
+ * of showing nothing. Best-effort, like every report to the plan.
196
+ */
197
+ export async function reportPlanBlocked(platform, planId, reason, doFetch = (url, init) => fetch(url, init)) {
198
+ const script = await fetchScript(platform, planId, doFetch);
199
+ const results = (script?.journeys ?? []).map((journey) => ({
200
+ id: journey.id,
201
+ title: journey.title,
202
+ status: ScriptStatus.BLOCKED,
203
+ line: reason,
204
+ }));
205
+ return reportPlanResults(platform, planId, results, [], doFetch);
206
+ }
94
207
  /** Worst first: a journey that ran in two lanes reports the worse of the two. */
95
208
  const SEVERITY = [
96
209
  ScriptStatus.FAILED,
97
210
  ScriptStatus.BLOCKED,
98
211
  ScriptStatus.RUNNING,
99
212
  ScriptStatus.PENDING,
213
+ ScriptStatus.UNDECIDED,
100
214
  ScriptStatus.NOT_TAKEN,
101
215
  ScriptStatus.PASSED,
102
216
  ];
103
- /** How each journey of a run plan went, once each. */
104
- export function journeyResults(view) {
217
+ /** How each journey of a run plan went, once each, matched to how it was answered by id. */
218
+ export function journeyResults(view, answers = []) {
105
219
  const byId = new Map();
106
220
  for (const lane of view.lanes)
107
221
  for (const card of lane.journeys) {
108
222
  const seen = byId.get(card.id);
109
223
  if (seen === undefined || SEVERITY.indexOf(card.status) < SEVERITY.indexOf(seen.status))
110
- byId.set(card.id, { id: card.id, title: card.title, status: card.status });
224
+ byId.set(card.id, {
225
+ id: card.id,
226
+ title: card.title,
227
+ status: card.status,
228
+ ...(card.why === undefined ? {} : { line: card.why }),
229
+ });
111
230
  }
112
- return [...byId.values()];
231
+ const answered = new Map(answers.map((a) => [a.id, a]));
232
+ return [...byId.values()].map((result) => {
233
+ const answer = answered.get(result.id);
234
+ if (answer === undefined)
235
+ return result;
236
+ return {
237
+ ...result,
238
+ ...(answer.by === undefined ? {} : { by: answer.by }),
239
+ tokens: answer.tokens,
240
+ ...(answer.credits === undefined ? {} : { credits: answer.credits }),
241
+ ...(0 === answer.flows.length ? {} : { flows: [...answer.flows] }),
242
+ };
243
+ });
113
244
  }
114
245
  /** Tell the platform how its plan went. A failure costs the next plan its memory, never this run. */
115
- export async function reportPlanResults(platform, planId, results, doFetch = (url, init) => fetch(url, init)) {
246
+ export async function reportPlanResults(platform, planId, results, runIds = [], doFetch = (url, init) => fetch(url, init)) {
116
247
  try {
117
248
  const res = await doFetch(`${platform.url}${SCRIPTS_PATH}/${encodeURIComponent(planId)}${RESULTS_PATH}`, {
118
249
  method: 'POST',
119
- headers: { 'content-type': 'application/json', authorization: `Bearer ${platform.apiKey}` },
120
- body: JSON.stringify({ results }),
250
+ headers: platformHeaders(platform),
251
+ // The runs it made, so the plan's history opens each one.
252
+ body: JSON.stringify({ results, ...(0 === runIds.length ? {} : { runIds }) }),
121
253
  signal: AbortSignal.timeout(TIMEOUT_MS),
122
254
  });
123
255
  return res.ok;
@@ -1,4 +1,6 @@
1
1
  import { type ModelDriver } from '../harness.js';
2
+ import { DRIVE_HEADER } from '../platform-config.js';
3
+ export { DRIVE_HEADER };
2
4
  export declare const SERVER_DRIVER_NAME = "server";
3
5
  type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
4
6
  export interface ServerDriverOptions {
@@ -19,16 +21,28 @@ export interface ServerDriverOptions {
19
21
  }[];
20
22
  /** The signal names the app declares, so the engine can claim one by name. */
21
23
  vocabulary?: readonly string[];
24
+ /** The survey of the app taken before the drive: where each text and control lives. */
25
+ siteMap?: unknown;
22
26
  /** Where secret field values live. Only their NAMES go to the platform. Defaults to `process.env`. */
23
27
  env?: Record<string, string | undefined>;
24
28
  maxSteps?: number;
29
+ /** The free drive this run is billed to, sent as `DRIVE_HEADER` on every turn. */
30
+ driveId?: string;
25
31
  fetch?: FetchLike;
26
32
  }
27
- /** The platform's url and this project's key, when the machine is linked. */
28
- export declare function serverOptionsFromEnv(env: Record<string, string | undefined>): {
33
+ /** Where to reach the platform, as which key, and for which free drive when there is one. */
34
+ export interface PlatformCredential {
29
35
  url: string;
30
36
  apiKey: string;
31
- } | undefined;
37
+ driveId?: string;
38
+ }
39
+ /** The platform's url and this project's key, when the machine is linked. */
40
+ export declare function serverOptionsFromEnv(env: Record<string, string | undefined>): PlatformCredential | undefined;
41
+ /** The headers every Harness call carries: JSON, the key, and the free drive it is billed to. */
42
+ export declare function platformHeaders(platform: {
43
+ apiKey: string;
44
+ driveId?: string | undefined;
45
+ }): Record<string, string>;
32
46
  export declare class ServerHarnessError extends Error {
33
47
  readonly status: number;
34
48
  constructor(message: string, status: number);
@@ -38,4 +52,3 @@ export declare function serverDriver(options: ServerDriverOptions): ModelDriver;
38
52
  export declare function secretNames(env: Record<string, string | undefined>): string[];
39
53
  /** The call's arguments with every secret placeholder replaced by its value from this machine. */
40
54
  export declare function withSecrets(args: Record<string, unknown>, env: Record<string, string | undefined>): Record<string, unknown>;
41
- export {};
@@ -10,22 +10,37 @@
10
10
  * This is the only Harness driver: every decision is the platform's, for a workspace with a plan or
11
11
  * trial. A secret field travels by name only, and its value is filled in here before the call runs.
12
12
  */
13
+ import { PlatformRefusalCode, readRefusal, refusalSentence } from './refusal.js';
13
14
  import { ReticleEnv, cloudUrlFrom } from '@reticlehq/core';
14
15
  import { DriveStoppedError, } from '../harness.js';
16
+ import { DRIVE_HEADER } from '../platform-config.js';
17
+ export { DRIVE_HEADER };
15
18
  export const SERVER_DRIVER_NAME = 'server';
16
19
  const RUNS_PATH = '/v1/harness/runs';
17
20
  const TURN_TIMEOUT_MS = 110_000;
18
21
  const RETRIES = 1;
19
22
  /** The platform's code for a run whose project had autonomous driving switched off. */
20
- const HARNESS_OFF = 'harness_off';
21
23
  const FINISH = 'finish';
22
24
  /** The platform's url and this project's key, when the machine is linked. */
23
25
  export function serverOptionsFromEnv(env) {
24
26
  const url = cloudUrlFrom(env);
25
27
  const apiKey = env[ReticleEnv.API_KEY];
28
+ const driveId = env[ReticleEnv.DRIVE_ID];
26
29
  return url === undefined || apiKey === undefined || 0 === apiKey.length
27
30
  ? undefined
28
- : { url: url.replace(/\/+$/, ''), apiKey };
31
+ : {
32
+ url: url.replace(/\/+$/, ''),
33
+ apiKey,
34
+ ...(driveId === undefined || 0 === driveId.length ? {} : { driveId }),
35
+ };
36
+ }
37
+ /** The headers every Harness call carries: JSON, the key, and the free drive it is billed to. */
38
+ export function platformHeaders(platform) {
39
+ return {
40
+ 'content-type': 'application/json',
41
+ authorization: `Bearer ${platform.apiKey}`,
42
+ ...(platform.driveId === undefined ? {} : { [DRIVE_HEADER]: platform.driveId }),
43
+ };
29
44
  }
30
45
  export class ServerHarnessError extends Error {
31
46
  status;
@@ -45,18 +60,16 @@ export function serverDriver(options) {
45
60
  try {
46
61
  const res = await doFetch(`${options.url}${path}`, {
47
62
  method: 'POST',
48
- headers: {
49
- 'content-type': 'application/json',
50
- authorization: `Bearer ${options.apiKey}`,
51
- },
63
+ headers: platformHeaders(options),
52
64
  body: JSON.stringify(body),
53
65
  signal: AbortSignal.timeout(TURN_TIMEOUT_MS),
54
66
  });
55
67
  const text = await res.text();
56
68
  if (!res.ok) {
57
- const message = errorMessage(text) ?? `the platform answered ${String(res.status)}`;
69
+ const refusal = readRefusal(text);
70
+ const message = refusalSentence(refusal, res.status);
58
71
  // A person turned it off: the drive ends, and the result says that rather than "broken".
59
- if (HARNESS_OFF === errorCode(text))
72
+ if (PlatformRefusalCode.HARNESS_OFF === refusal.code)
60
73
  throw new DriveStoppedError(message);
61
74
  // A refusal is an answer; only a network failure is worth asking again.
62
75
  throw new ServerHarnessError(message, res.status);
@@ -82,6 +95,7 @@ export function serverDriver(options) {
82
95
  ...(options.maxSteps === undefined ? {} : { maxSteps: options.maxSteps }),
83
96
  ...(options.planSteps === undefined ? {} : { planSteps: options.planSteps }),
84
97
  ...(options.vocabulary === undefined ? {} : { vocabulary: options.vocabulary }),
98
+ ...(options.siteMap === undefined ? {} : { siteMap: options.siteMap }),
85
99
  secrets: secretNames(options.env ?? process.env),
86
100
  tools: input.tools.filter((t) => FINISH !== t.name).map(toolSpec),
87
101
  }));
@@ -93,9 +107,13 @@ export function serverDriver(options) {
93
107
  const fresh = input.history.slice(seen);
94
108
  seen = input.history.length;
95
109
  const outcomes = fresh.flatMap((entry) => 'tool' === entry.role ? entry.outcomes.map(outcomeOf) : []);
110
+ // What somebody said to the drive since the last turn. The opening line is the loop's own and
111
+ // the platform writes its own, so only words that arrived after it travel.
112
+ const say = fresh.flatMap((entry, i) => 'user' === entry.role && (0 < turn || 0 < i) ? [entry.text] : []);
96
113
  const reply = (await call(`${RUNS_PATH}/${encodeURIComponent(runId)}/turn`, {
97
114
  turn,
98
115
  outcomes,
116
+ ...(0 === say.length ? {} : { say }),
99
117
  }));
100
118
  turn = reply.turn + 1;
101
119
  // The platform's spend, reported so the drive's cost is visible here as it is for a local one.
@@ -112,6 +130,9 @@ export function serverDriver(options) {
112
130
  args: {
113
131
  summary: reply.summary ?? reply.text,
114
132
  ...('boolean' === typeof reply.goalMet ? { goalMet: reply.goalMet } : {}),
133
+ ...('number' === typeof reply.creditsSpent
134
+ ? { creditsSpent: reply.creditsSpent }
135
+ : {}),
115
136
  },
116
137
  },
117
138
  ],
@@ -133,24 +154,6 @@ function toolSpec(tool) {
133
154
  function outcomeOf(o) {
134
155
  return { id: o.id, name: o.name, result: o.result, isError: o.isError };
135
156
  }
136
- function errorCode(text) {
137
- try {
138
- const body = JSON.parse(text);
139
- return 'string' === typeof body.error?.code ? body.error.code : undefined;
140
- }
141
- catch {
142
- return undefined;
143
- }
144
- }
145
- function errorMessage(text) {
146
- try {
147
- const body = JSON.parse(text);
148
- return 'string' === typeof body.error?.message ? body.error.message : undefined;
149
- }
150
- catch {
151
- return undefined;
152
- }
153
- }
154
157
  /** The prefix of a variable holding one secret field: `RETICLE_SECRET_AUTH_PASSWORD`. */
155
158
  const SECRET_ENV_PREFIX = 'RETICLE_SECRET_';
156
159
  /** What the platform types into a field whose secret this machine holds. */
@@ -16,11 +16,15 @@
16
16
  * - it never overrides someone who was EXPLICIT. A driver named in the call, or set in the
17
17
  * environment, wins over the stored preference. Precedence lives in the caller.
18
18
  */
19
+ import { CreditKind } from '@reticlehq/core';
20
+ import type { Credits } from '@reticlehq/core/hud';
21
+ /** The header naming the free drive a call belongs to. See `ReticleEnv.DRIVE_ID`. */
22
+ export declare const DRIVE_HEADER = "x-reticle-drive";
19
23
  /** The subset of the platform's answer the harness acts on. */
20
24
  export interface PlatformModelConfig {
21
25
  /** `jev` | `anthropic` | `openai`, as the platform spells it. Not validated here. */
22
26
  provider: string;
23
- /** Whether the person wants autonomous driving at all. */
27
+ /** Whether the person switched the Harness on. Off unless the platform says on. */
24
28
  harnessEnabled: boolean;
25
29
  /**
26
30
  * Whether this workspace may drive on OUR model spend — a claimed free period, or a paid plan.
@@ -40,13 +44,42 @@ export interface PlatformModelConfig {
40
44
  * not have its silence treated as a refusal.
41
45
  */
42
46
  providerReady: boolean;
43
- /** Harness credits used and held this 30 days. Absent when the plan is unbounded or the API is older. */
44
- credits?: {
45
- used: number;
46
- limit: number;
47
+ /**
48
+ * Harness credits used and held this 30 days, and when the grant ends (`endsAt`, epoch ms) when
49
+ * the platform says. Absent when the plan is unbounded or the API is older.
50
+ */
51
+ credits?: Credits & {
52
+ endsAt?: number;
47
53
  };
48
54
  /** The platform that answered, no trailing slash: where the HUD's settings and plan links go. */
49
55
  platformUrl?: string;
56
+ /**
57
+ * The page where credits and the trial are bought (`planUrl`), on the console's origin. The API
58
+ * and the console are different origins on every deployment but a laptop, so a link built from
59
+ * the API's origin 404s. Absent from an older platform.
60
+ */
61
+ planUrl?: string;
62
+ /** The platform's coverage gate (`harnessUnlocked`, `coverageScore`, `harnessLock`), when it sent one. */
63
+ gate?: PlatformGate;
64
+ /** The plan in force (`plan`), for the HUD's account menu. */
65
+ plan?: PlatformPlan;
66
+ /** Harness runs the platform holds for this project (`harnessRuns.total`). */
67
+ harnessRuns?: number;
68
+ /** Memory entries the platform holds for this project (`memory.entries`). */
69
+ memoryEntries?: number;
70
+ }
71
+ /** The plan as the HUD is pushed it: which grant, and the trial's days and seats when said. */
72
+ export interface PlatformPlan {
73
+ kind: CreditKind;
74
+ daysLeft?: number;
75
+ seats?: number;
76
+ }
77
+ /** The platform's Harness coverage gate, as the HUD is pushed it. */
78
+ export interface PlatformGate {
79
+ unlocked: boolean;
80
+ percent?: number;
81
+ reason?: string;
82
+ prompt?: string;
50
83
  }
51
84
  /** A GET, narrowed to what this file uses, so a test can answer it without a network. */
52
85
  export type ConfigFetch = (url: string, init: {