@reticlehq/server 3.8.2 → 3.10.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 (477) hide show
  1. package/LICENSE +201 -104
  2. package/NOTICE +5 -0
  3. package/README.md +1 -1
  4. package/SKILL.md +13 -12
  5. package/bin/launch.js +13 -0
  6. package/bin/package.json +3 -0
  7. package/bin/reticle.js +66 -8
  8. package/dist/chromium-launch-options.d.ts +25 -0
  9. package/dist/chromium-launch-options.js +21 -1
  10. package/dist/command/cli/adhoc-suite.js +2 -0
  11. package/dist/command/cli/adhoc-verdict.d.ts +2 -43
  12. package/dist/command/cli/adhoc-verdict.js +50 -160
  13. package/dist/command/cli/answers/gate-exit.d.ts +6 -2
  14. package/dist/command/cli/answers/gate-exit.js +12 -2
  15. package/dist/command/cli/answers/mcp-connection-hint.d.ts +2 -0
  16. package/dist/command/cli/answers/mcp-connection-hint.js +6 -0
  17. package/dist/command/cli/ci-hint.d.ts +44 -0
  18. package/dist/command/cli/ci-hint.js +72 -0
  19. package/dist/command/cli/cli-doctor.d.ts +6 -1
  20. package/dist/command/cli/cli-doctor.js +46 -5
  21. package/dist/command/cli/cli-flow-commands.d.ts +7 -1
  22. package/dist/command/cli/cli-flow-commands.js +39 -24
  23. package/dist/command/cli/cli-kill.d.ts +21 -0
  24. package/dist/command/cli/cli-kill.js +47 -4
  25. package/dist/command/cli/cli-parse-compare.d.ts +22 -0
  26. package/dist/command/cli/cli-parse-compare.js +75 -0
  27. package/dist/command/cli/cli-parse-grade.d.ts +36 -0
  28. package/dist/command/cli/cli-parse-grade.js +75 -0
  29. package/dist/command/cli/cli-parse-grammar.d.ts +2 -0
  30. package/dist/command/cli/cli-parse-grammar.js +18 -20
  31. package/dist/command/cli/cli-parse-verify.d.ts +10 -0
  32. package/dist/command/cli/cli-parse-verify.js +63 -14
  33. package/dist/command/cli/cli-parse.d.ts +22 -17
  34. package/dist/command/cli/cli-parse.js +54 -32
  35. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  36. package/dist/command/cli/cli-update-commands.js +29 -20
  37. package/dist/command/cli/cli-usage.js +61 -31
  38. package/dist/command/cli/cli-verify.d.ts +17 -3
  39. package/dist/command/cli/cli-verify.js +59 -21
  40. package/dist/command/cli/cloud-cli.js +2 -119
  41. package/dist/command/cli/daemon-link/daemon-client.d.ts +45 -0
  42. package/dist/command/cli/daemon-link/daemon-client.js +205 -0
  43. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +6 -1
  44. package/dist/command/cli/doctor/browser/chromium-hint.js +11 -5
  45. package/dist/command/cli/doctor/doctor-daemon-line.js +6 -3
  46. package/dist/command/cli/doctor/doctor-fix.d.ts +44 -0
  47. package/dist/command/cli/doctor/doctor-fix.js +89 -0
  48. package/dist/command/cli/doctor/doctor-launcher-line.d.ts +23 -0
  49. package/dist/command/cli/doctor/doctor-launcher-line.js +60 -0
  50. package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
  51. package/dist/command/cli/doctor/doctor-rows.js +4 -0
  52. package/dist/command/cli/doctor-repairs.d.ts +64 -0
  53. package/dist/command/cli/doctor-repairs.js +214 -0
  54. package/dist/command/cli/drive/drive-command.js +3 -7
  55. package/dist/command/cli/ensure-daemon.d.ts +26 -0
  56. package/dist/command/cli/ensure-daemon.js +57 -0
  57. package/dist/command/cli/finished-run/grade-command.d.ts +23 -0
  58. package/dist/command/cli/finished-run/grade-command.js +180 -0
  59. package/dist/command/cli/first-use-checks.d.ts +41 -0
  60. package/dist/command/cli/first-use-checks.js +127 -0
  61. package/dist/command/cli/first-verdict-node.d.ts +3 -0
  62. package/dist/command/cli/first-verdict-node.js +189 -0
  63. package/dist/command/cli/first-verdict.d.ts +126 -0
  64. package/dist/command/cli/first-verdict.js +267 -0
  65. package/dist/command/cli/launch/sdk-version-match.d.ts +3 -2
  66. package/dist/command/cli/launch/sdk-version-match.js +3 -2
  67. package/dist/command/cli/lifecycle/daemon-lifecycle.d.ts +1 -1
  68. package/dist/command/cli/lifecycle/daemon-lifecycle.js +7 -6
  69. package/dist/command/cli/mcp-command.js +13 -4
  70. package/dist/command/cli/ports/port-holder.d.ts +11 -0
  71. package/dist/command/cli/ports/port-holder.js +36 -4
  72. package/dist/command/cli/setup-mcp-cli.d.ts +27 -1
  73. package/dist/command/cli/setup-mcp-cli.js +98 -23
  74. package/dist/command/cli/status/status-lines.d.ts +2 -0
  75. package/dist/command/cli/status/status-lines.js +72 -17
  76. package/dist/command/cli/status-fields.d.ts +5 -1
  77. package/dist/command/cli/status-fields.js +24 -6
  78. package/dist/command/cli/try-command.d.ts +7 -0
  79. package/dist/command/cli/try-command.js +11 -3
  80. package/dist/command/cli/two-builds/compare-command.d.ts +48 -0
  81. package/dist/command/cli/two-builds/compare-command.js +314 -0
  82. package/dist/command/cli/verify-against.d.ts +61 -0
  83. package/dist/command/cli/verify-against.js +187 -0
  84. package/dist/command/cli/verify-no-session.d.ts +2 -0
  85. package/dist/command/cli/verify-no-session.js +13 -0
  86. package/dist/command/cli/verify-results.d.ts +35 -2
  87. package/dist/command/cli/verify-results.js +76 -10
  88. package/dist/command/cli.js +112 -70
  89. package/dist/command/daemon/binding/daemon-status-probe.d.ts +3 -1
  90. package/dist/command/daemon/binding/daemon-status-probe.js +4 -2
  91. package/dist/command/daemon/daemon-argv.d.ts +9 -0
  92. package/dist/command/daemon/daemon-argv.js +11 -0
  93. package/dist/command/daemon/daemon-resolve.d.ts +8 -1
  94. package/dist/command/daemon/daemon-resolve.js +27 -1
  95. package/dist/command/daemon/daemon.d.ts +22 -4
  96. package/dist/command/daemon/daemon.js +52 -10
  97. package/dist/command/daemon/lifetime/daemon-exit.d.ts +24 -0
  98. package/dist/command/daemon/lifetime/daemon-exit.js +39 -0
  99. package/dist/command/daemon/lifetime/death-cause.d.ts +15 -0
  100. package/dist/command/daemon/lifetime/death-cause.js +149 -0
  101. package/dist/command/daemon/lifetime/heartbeat.d.ts +7 -15
  102. package/dist/command/daemon/lifetime/heartbeat.js +11 -15
  103. package/dist/command/daemon/lifetime/startup-failure.d.ts +29 -0
  104. package/dist/command/daemon/lifetime/startup-failure.js +62 -0
  105. package/dist/command/daemon/port-state.d.ts +14 -0
  106. package/dist/command/daemon/port-state.js +31 -0
  107. package/dist/command/setup/agent-configs.d.ts +2 -0
  108. package/dist/command/setup/agent-configs.js +42 -15
  109. package/dist/command/setup/agent-next-steps.d.ts +77 -0
  110. package/dist/command/setup/agent-next-steps.js +284 -0
  111. package/dist/command/setup/agent-writer.js +11 -6
  112. package/dist/command/setup/bringup/dev-server-files.d.ts +9 -0
  113. package/dist/command/setup/bringup/dev-server-files.js +17 -0
  114. package/dist/command/setup/bringup/static-page-server.d.ts +14 -2
  115. package/dist/command/setup/bringup/static-page-server.js +43 -9
  116. package/dist/command/setup/init/init-host.js +2 -0
  117. package/dist/command/setup/init/init-runtime.d.ts +6 -1
  118. package/dist/command/setup/init/init-runtime.js +63 -21
  119. package/dist/command/setup/mcp-launcher.d.ts +3 -0
  120. package/dist/command/setup/mcp-launcher.js +11 -0
  121. package/dist/command/setup/node-effects.d.ts +3 -2
  122. package/dist/command/setup/node-effects.js +9 -3
  123. package/dist/command/setup/remaining-steps.d.ts +8 -0
  124. package/dist/command/setup/remaining-steps.js +10 -0
  125. package/dist/command/setup/run-setup.d.ts +2 -0
  126. package/dist/command/setup/run-setup.js +9 -1
  127. package/dist/command/setup/setup-command.js +36 -15
  128. package/dist/command/setup/setup-mcp.d.ts +8 -0
  129. package/dist/command/setup/setup-mcp.js +47 -20
  130. package/dist/command/setup/start-dev-server.d.ts +8 -0
  131. package/dist/command/setup/start-dev-server.js +43 -0
  132. package/dist/command/update/updater.js +6 -0
  133. package/dist/command/version/identity/server-version.d.ts +2 -0
  134. package/dist/command/version/identity/server-version.js +2 -0
  135. package/dist/command/version/version-skew.d.ts +7 -0
  136. package/dist/command/version/version-skew.js +14 -3
  137. package/dist/features/compare/action-plan.d.ts +260 -0
  138. package/dist/features/compare/action-plan.js +543 -0
  139. package/dist/features/compare/behaviour-compare.d.ts +24 -0
  140. package/dist/features/compare/behaviour-compare.js +85 -0
  141. package/dist/features/compare/behaviour-diff.d.ts +97 -0
  142. package/dist/features/compare/behaviour-diff.js +202 -0
  143. package/dist/features/compare/behaviour-report.d.ts +40 -0
  144. package/dist/features/compare/behaviour-report.js +128 -0
  145. package/dist/features/compare/build-readings.d.ts +106 -0
  146. package/dist/features/compare/build-readings.js +250 -0
  147. package/dist/features/compare/compare-diff.d.ts +62 -0
  148. package/dist/features/compare/compare-diff.js +177 -0
  149. package/dist/features/compare/compare-report-html.d.ts +6 -0
  150. package/dist/features/compare/compare-report-html.js +102 -0
  151. package/dist/features/compare/compare-report.d.ts +15 -0
  152. package/dist/features/compare/compare-report.js +73 -0
  153. package/dist/features/compare/compare-run.d.ts +60 -0
  154. package/dist/features/compare/compare-run.js +123 -0
  155. package/dist/features/compare/outside/effect-lines.d.ts +26 -0
  156. package/dist/features/compare/outside/effect-lines.js +103 -0
  157. package/dist/features/compare/outside/state-sources.d.ts +76 -0
  158. package/dist/features/compare/outside/state-sources.js +164 -0
  159. package/dist/features/compare/outside/value-dictionary.d.ts +51 -0
  160. package/dist/features/compare/outside/value-dictionary.js +227 -0
  161. package/dist/features/compare/visible-content.d.ts +20 -0
  162. package/dist/features/compare/visible-content.js +125 -0
  163. package/dist/features/crawl/crawl-empty.js +2 -1
  164. package/dist/features/crawl/crawl-exhaustive.d.ts +55 -0
  165. package/dist/features/crawl/crawl-exhaustive.js +138 -0
  166. package/dist/features/crawl/crawl-tools.d.ts +9 -2
  167. package/dist/features/crawl/crawl-tools.js +28 -12
  168. package/dist/features/crawl/crawl.d.ts +8 -9
  169. package/dist/features/crawl/crawl.js +61 -65
  170. package/dist/features/exhaust/app-coverage.d.ts +5 -1
  171. package/dist/features/exhaust/app-coverage.js +3 -1
  172. package/dist/features/exhaust/code-coverage.js +8 -4
  173. package/dist/features/exhaust/edge-cases.d.ts +133 -0
  174. package/dist/features/exhaust/edge-cases.js +310 -0
  175. package/dist/features/exhaust/edges/edge-drive.d.ts +42 -0
  176. package/dist/features/exhaust/edges/edge-drive.js +364 -0
  177. package/dist/features/exhaust/edges/edge-run.d.ts +59 -0
  178. package/dist/features/exhaust/edges/edge-run.js +169 -0
  179. package/dist/features/exhaust/explorer.d.ts +87 -14
  180. package/dist/features/exhaust/explorer.js +159 -25
  181. package/dist/features/exhaust/failure-branches.d.ts +5 -0
  182. package/dist/features/exhaust/failure-branches.js +29 -11
  183. package/dist/features/exhaust/invariants.d.ts +112 -0
  184. package/dist/features/exhaust/invariants.js +188 -0
  185. package/dist/features/exhaust/ledger.d.ts +68 -0
  186. package/dist/features/exhaust/ledger.js +121 -13
  187. package/dist/features/exhaust/session-fold.d.ts +10 -0
  188. package/dist/features/exhaust/session-fold.js +46 -3
  189. package/dist/features/exhaust/session-port.d.ts +3 -1
  190. package/dist/features/exhaust/session-port.js +97 -28
  191. package/dist/features/grade/grade-answer.d.ts +99 -0
  192. package/dist/features/grade/grade-answer.js +112 -0
  193. package/dist/features/grade/grade-noise.d.ts +27 -0
  194. package/dist/features/grade/grade-noise.js +55 -0
  195. package/dist/features/grade/grade-renumber.d.ts +12 -0
  196. package/dist/features/grade/grade-renumber.js +86 -0
  197. package/dist/features/grade/grade-state.d.ts +50 -0
  198. package/dist/features/grade/grade-state.js +93 -0
  199. package/dist/features/grade/grade-suggest.d.ts +33 -0
  200. package/dist/features/grade/grade-suggest.js +98 -0
  201. package/dist/features/license/license.d.ts +11 -71
  202. package/dist/features/license/license.js +43 -136
  203. package/dist/features/visual/desktop-capture.d.ts +33 -0
  204. package/dist/features/visual/desktop-capture.js +94 -0
  205. package/dist/features/visual/step-shots.js +139 -35
  206. package/dist/features/visual/visual-tools.d.ts +0 -18
  207. package/dist/features/visual/visual-tools.js +67 -99
  208. package/dist/import-graph.js +5 -6
  209. package/dist/index.d.ts +3 -1
  210. package/dist/index.js +19 -7
  211. package/dist/judgement/capsule/causal-summary.js +9 -2
  212. package/dist/judgement/runs/artifact/replay-mapping.d.ts +13 -1
  213. package/dist/judgement/runs/artifact/replay-mapping.js +1 -1
  214. package/dist/judgement/runs/reticle-runner.js +16 -2
  215. package/dist/judgement/runs/run-ledger.d.ts +7 -5
  216. package/dist/judgement/runs/run-ledger.js +98 -69
  217. package/dist/judgement/runs/runner-port.d.ts +2 -0
  218. package/dist/judgement/runs/runner-port.js +23 -5
  219. package/dist/judgement/runs/verification-sync.d.ts +6 -3
  220. package/dist/judgement/runs/verification-sync.js +21 -10
  221. package/dist/language/flows/affected-tools.d.ts +1 -1
  222. package/dist/language/flows/affected-tools.js +49 -30
  223. package/dist/language/flows/change/git-changed.d.ts +2 -1
  224. package/dist/language/flows/change/git-changed.js +19 -2
  225. package/dist/language/flows/fields/flow-secret-field.d.ts +1 -13
  226. package/dist/language/flows/fields/flow-secret-field.js +77 -21
  227. package/dist/language/flows/flow-anchor.d.ts +60 -2
  228. package/dist/language/flows/flow-anchor.js +125 -20
  229. package/dist/language/flows/flow-classify.d.ts +20 -0
  230. package/dist/language/flows/flow-classify.js +90 -12
  231. package/dist/language/flows/flow-cross-step.d.ts +7 -1
  232. package/dist/language/flows/flow-cross-step.js +25 -1
  233. package/dist/language/flows/flow-journey.d.ts +38 -4
  234. package/dist/language/flows/flow-journey.js +138 -8
  235. package/dist/language/flows/flow-replay-run.d.ts +0 -16
  236. package/dist/language/flows/flow-replay-run.js +76 -14
  237. package/dist/language/flows/flow-replay-types.d.ts +4 -2
  238. package/dist/language/flows/flow-replay.d.ts +19 -1
  239. package/dist/language/flows/flow-replay.js +169 -52
  240. package/dist/language/flows/flow-replayable.js +7 -1
  241. package/dist/language/flows/flow-start-path.d.ts +34 -5
  242. package/dist/language/flows/flow-start-path.js +202 -15
  243. package/dist/language/flows/flow-step-runners.d.ts +14 -13
  244. package/dist/language/flows/flow-step-runners.js +184 -109
  245. package/dist/language/flows/flow-store-for-session.d.ts +26 -25
  246. package/dist/language/flows/flow-store-for-session.js +51 -5
  247. package/dist/language/flows/flow-tools.js +46 -33
  248. package/dist/language/flows/flows.js +176 -76
  249. package/dist/language/flows/recording/tape/recordings.d.ts +21 -16
  250. package/dist/language/flows/recording/tape/recordings.js +112 -49
  251. package/dist/language/flows/replay.d.ts +36 -12
  252. package/dist/language/flows/replay.js +193 -50
  253. package/dist/language/flows/steps/page-steps.d.ts +68 -0
  254. package/dist/language/flows/steps/page-steps.js +198 -0
  255. package/dist/language/flows/suite/sequential-run.d.ts +68 -0
  256. package/dist/language/flows/suite/sequential-run.js +96 -0
  257. package/dist/language/flows/verify-change-tools.js +26 -15
  258. package/dist/launch-chromium.d.ts +1 -0
  259. package/dist/launch-chromium.js +49 -12
  260. package/dist/memory/cloud/background-sync.d.ts +13 -0
  261. package/dist/memory/cloud/background-sync.js +24 -3
  262. package/dist/memory/cloud/sync-daemon.js +26 -27
  263. package/dist/memory/cloud/sync-screenshots.js +6 -1
  264. package/dist/memory/journal/attach-journal.js +2 -1
  265. package/dist/memory/journal/drive-flow.d.ts +7 -0
  266. package/dist/memory/journal/drive-flow.js +44 -13
  267. package/dist/memory/journal/journal-recorder.d.ts +4 -2
  268. package/dist/memory/journal/session-journal.d.ts +7 -0
  269. package/dist/memory/journal/session-journal.js +58 -10
  270. package/dist/memory/project/root-claims.d.ts +9 -0
  271. package/dist/memory/project/root-claims.js +9 -4
  272. package/dist/portal/bridge/bridge.d.ts +13 -4
  273. package/dist/portal/bridge/bridge.js +10 -9
  274. package/dist/portal/input/download-capture.d.ts +7 -0
  275. package/dist/portal/input/download-capture.js +92 -0
  276. package/dist/portal/input/network-detail.d.ts +6 -0
  277. package/dist/portal/input/network-detail.js +12 -1
  278. package/dist/portal/input/network-mock-tools.js +49 -13
  279. package/dist/portal/input/network-mock.d.ts +8 -0
  280. package/dist/portal/input/network-mock.js +30 -10
  281. package/dist/portal/input/page-capture.d.ts +24 -0
  282. package/dist/portal/input/page-capture.js +33 -0
  283. package/dist/portal/input/real-input.d.ts +35 -18
  284. package/dist/portal/input/real-input.js +99 -33
  285. package/dist/portal/input/viewport-tools.d.ts +8 -0
  286. package/dist/portal/input/viewport-tools.js +81 -21
  287. package/dist/portal/pool/browser-pool.d.ts +16 -30
  288. package/dist/portal/pool/browser-pool.js +64 -52
  289. package/dist/portal/pool/context-permissions.d.ts +34 -17
  290. package/dist/portal/pool/context-permissions.js +94 -1
  291. package/dist/portal/pool/csp-widen.d.ts +62 -0
  292. package/dist/portal/pool/csp-widen.js +132 -0
  293. package/dist/portal/pool/determinism.d.ts +52 -0
  294. package/dist/portal/pool/determinism.js +259 -0
  295. package/dist/portal/pool/lease-emulation.d.ts +34 -1
  296. package/dist/portal/pool/lease-emulation.js +18 -0
  297. package/dist/portal/pool/lease-marker-stamp.d.ts +6 -0
  298. package/dist/portal/pool/lease-marker-stamp.js +15 -1
  299. package/dist/portal/pool/lease-page-error.d.ts +56 -0
  300. package/dist/portal/pool/lease-page-error.js +160 -0
  301. package/dist/portal/pool/page-error-journal.d.ts +63 -0
  302. package/dist/portal/pool/page-error-journal.js +208 -0
  303. package/dist/portal/pool/playwright-launcher.js +71 -15
  304. package/dist/portal/pool/pool-contract.d.ts +49 -1
  305. package/dist/portal/pool/pool-lease.d.ts +70 -2
  306. package/dist/portal/pool/pool-lease.js +23 -0
  307. package/dist/portal/pool/zero-install.d.ts +8 -0
  308. package/dist/portal/pool/zero-install.js +91 -1
  309. package/dist/portal/session/dev-server/dev-command.d.ts +11 -2
  310. package/dist/portal/session/dev-server/dev-command.js +110 -16
  311. package/dist/portal/session/dev-server/dev-server-probe.d.ts +7 -0
  312. package/dist/portal/session/dev-server/dev-server-probe.js +9 -0
  313. package/dist/portal/session/dev-server/project-ports.d.ts +21 -0
  314. package/dist/portal/session/dev-server/project-ports.js +62 -0
  315. package/dist/portal/session/facts/departed-network.d.ts +66 -0
  316. package/dist/portal/session/facts/departed-network.js +142 -0
  317. package/dist/portal/session/no-session-diagnosis.d.ts +9 -0
  318. package/dist/portal/session/no-session-diagnosis.js +76 -27
  319. package/dist/portal/session/no-session-next-action.d.ts +14 -0
  320. package/dist/portal/session/no-session-next-action.js +56 -7
  321. package/dist/portal/session/no-session-watch.d.ts +6 -0
  322. package/dist/portal/session/no-session-watch.js +41 -4
  323. package/dist/portal/session/page-commands/undeclared-command.d.ts +9 -3
  324. package/dist/portal/session/page-commands/undeclared-command.js +16 -7
  325. package/dist/portal/session/recorded-gaps.d.ts +1 -1
  326. package/dist/portal/session/recorded-gaps.js +5 -2
  327. package/dist/portal/session/serving-directory.d.ts +10 -0
  328. package/dist/portal/session/serving-directory.js +39 -8
  329. package/dist/portal/session/session-manager.d.ts +10 -0
  330. package/dist/portal/session/session-manager.js +211 -81
  331. package/dist/portal/session/session.js +4 -3
  332. package/dist/portal/session/zero-install-first-call.d.ts +20 -1
  333. package/dist/portal/session/zero-install-first-call.js +34 -2
  334. package/dist/start-wiring.d.ts +30 -2
  335. package/dist/start-wiring.js +74 -9
  336. package/dist/surface/mcp/mcp-proxy.js +10 -2
  337. package/dist/surface/mcp/mcp.js +8 -5
  338. package/dist/surface/mcp/peer/agents-connected.d.ts +6 -0
  339. package/dist/surface/mcp/peer/agents-connected.js +58 -0
  340. package/dist/surface/mcp/proxy/proxy-daemon-probe.js +17 -5
  341. package/dist/surface/mcp/shared-params.d.ts +2 -0
  342. package/dist/surface/mcp/shared-params.js +31 -0
  343. package/dist/surface/tools/act/act-observation.d.ts +40 -2
  344. package/dist/surface/tools/act/act-observation.js +118 -12
  345. package/dist/surface/tools/act/act-preflight.js +38 -18
  346. package/dist/surface/tools/act/act-sequence-retry.d.ts +23 -2
  347. package/dist/surface/tools/act/act-sequence-retry.js +61 -5
  348. package/dist/surface/tools/act/act-target.js +3 -1
  349. package/dist/surface/tools/act/after-match.d.ts +10 -0
  350. package/dist/surface/tools/act/after-match.js +40 -0
  351. package/dist/surface/tools/act/already-true.js +1 -1
  352. package/dist/surface/tools/act/navigation/reload-result.d.ts +12 -1
  353. package/dist/surface/tools/act/navigation/reload-result.js +25 -2
  354. package/dist/surface/tools/act/resolve-target.d.ts +17 -1
  355. package/dist/surface/tools/act/resolve-target.js +59 -9
  356. package/dist/surface/tools/act/sequence-grade.d.ts +15 -1
  357. package/dist/surface/tools/act/sequence-grade.js +45 -27
  358. package/dist/surface/tools/act/settle-in-flight.js +27 -15
  359. package/dist/surface/tools/act-command.d.ts +23 -0
  360. package/dist/surface/tools/act-command.js +50 -0
  361. package/dist/surface/tools/act-sequence-tool.js +81 -50
  362. package/dist/surface/tools/act-tools.d.ts +1 -13
  363. package/dist/surface/tools/act-tools.js +83 -95
  364. package/dist/surface/tools/agent/build-staleness.d.ts +1 -1
  365. package/dist/surface/tools/agent/build-staleness.js +1 -1
  366. package/dist/surface/tools/assert/assert-verdict.js +18 -12
  367. package/dist/surface/tools/browser-tools.js +87 -13
  368. package/dist/surface/tools/compare-tools.d.ts +11 -0
  369. package/dist/surface/tools/compare-tools.js +94 -0
  370. package/dist/surface/tools/coverage-tools.js +1 -1
  371. package/dist/surface/tools/dynamic-tools.js +11 -3
  372. package/dist/surface/tools/empty-session-list.d.ts +2 -0
  373. package/dist/surface/tools/empty-session-list.js +4 -2
  374. package/dist/surface/tools/error-recovery.d.ts +12 -1
  375. package/dist/surface/tools/error-recovery.js +131 -40
  376. package/dist/surface/tools/explore-tools.js +1 -1
  377. package/dist/surface/tools/invoke-tool.js +29 -21
  378. package/dist/surface/tools/lease-coverage-tools.d.ts +49 -0
  379. package/dist/surface/tools/lease-coverage-tools.js +128 -0
  380. package/dist/surface/tools/lease-hint.d.ts +42 -1
  381. package/dist/surface/tools/lease-hint.js +52 -3
  382. package/dist/surface/tools/lease-readiness.d.ts +47 -0
  383. package/dist/surface/tools/lease-readiness.js +126 -0
  384. package/dist/surface/tools/lease-seed.d.ts +16 -1
  385. package/dist/surface/tools/lease-seed.js +37 -4
  386. package/dist/surface/tools/lease-tools.d.ts +3 -41
  387. package/dist/surface/tools/lease-tools.js +104 -124
  388. package/dist/surface/tools/lease-url-identity.d.ts +46 -0
  389. package/dist/surface/tools/lease-url-identity.js +97 -0
  390. package/dist/surface/tools/merge-tools.js +99 -2
  391. package/dist/surface/tools/merged-name-redirect.js +5 -1
  392. package/dist/surface/tools/observe-tools.js +15 -9
  393. package/dist/surface/tools/read/console-pre-attach.d.ts +19 -0
  394. package/dist/surface/tools/read/console-pre-attach.js +23 -0
  395. package/dist/surface/tools/read-tools.js +33 -30
  396. package/dist/surface/tools/real-input-attempt.d.ts +0 -8
  397. package/dist/surface/tools/real-input-attempt.js +143 -28
  398. package/dist/surface/tools/repeat-hint.d.ts +40 -0
  399. package/dist/surface/tools/repeat-hint.js +171 -0
  400. package/dist/surface/tools/run-report.d.ts +2 -2
  401. package/dist/surface/tools/run-report.js +27 -15
  402. package/dist/surface/tools/session-ports.d.ts +14 -0
  403. package/dist/surface/tools/session-ports.js +53 -0
  404. package/dist/surface/tools/tool-kit.d.ts +18 -0
  405. package/dist/surface/tools/tool-kit.js +9 -3
  406. package/dist/surface/tools/tool-surface.js +0 -1
  407. package/dist/surface/tools/tools.js +54 -18
  408. package/dist/surface/tools/type-spelling.d.ts +13 -0
  409. package/dist/surface/tools/type-spelling.js +36 -0
  410. package/dist/telemetry/agent-client.d.ts +6 -0
  411. package/dist/telemetry/agent-client.js +10 -0
  412. package/dist/telemetry/argument-shape.js +17 -7
  413. package/dist/telemetry/cli-telemetry.d.ts +10 -1
  414. package/dist/telemetry/cli-telemetry.js +15 -0
  415. package/dist/telemetry/init-telemetry.d.ts +2 -1
  416. package/dist/telemetry/init-telemetry.js +47 -2
  417. package/dist/telemetry/install-trace.js +23 -4
  418. package/dist/telemetry/onboarding-funnel.d.ts +19 -2
  419. package/dist/telemetry/onboarding-funnel.js +25 -3
  420. package/dist/telemetry/proxy-telemetry.d.ts +2 -1
  421. package/dist/telemetry/proxy-telemetry.js +2 -2
  422. package/dist/telemetry/session-metrics.d.ts +1 -1
  423. package/dist/telemetry/session-metrics.js +67 -27
  424. package/dist/telemetry/telemetry.d.ts +3 -1
  425. package/dist/telemetry/telemetry.js +60 -28
  426. package/dist/telemetry/tool-refused.d.ts +6 -3
  427. package/dist/telemetry/tool-refused.js +15 -3
  428. package/docs/actions.mdx +3 -3
  429. package/docs/agent-cheatsheet.md +1 -1
  430. package/docs/architecture.md +3 -6
  431. package/docs/capabilities.mdx +61 -1
  432. package/docs/cli/affected.mdx +9 -7
  433. package/docs/cli/cloud.mdx +3 -3
  434. package/docs/cli/compare.mdx +94 -0
  435. package/docs/cli/doctor.mdx +41 -2
  436. package/docs/cli/grade.mdx +97 -0
  437. package/docs/cli/help.mdx +4 -2
  438. package/docs/cli/license.mdx +13 -12
  439. package/docs/cli/restart.mdx +7 -5
  440. package/docs/cli/rollback.mdx +5 -5
  441. package/docs/cli/setup.mdx +13 -2
  442. package/docs/cli/status.mdx +4 -0
  443. package/docs/cli/stop.mdx +3 -3
  444. package/docs/cli/update.mdx +2 -2
  445. package/docs/cli/verify.mdx +23 -1
  446. package/docs/cli.mdx +34 -24
  447. package/docs/deploy-checks.md +25 -0
  448. package/docs/desktop.mdx +1 -1
  449. package/docs/enterprise.md +17 -22
  450. package/docs/environment.mdx +1 -0
  451. package/docs/first-drive.md +1 -1
  452. package/docs/flows.md +11 -1
  453. package/docs/frameworks.mdx +9 -9
  454. package/docs/getting-started.md +1 -1
  455. package/docs/install-manual.mdx +16 -1
  456. package/docs/license-activation.mdx +3 -3
  457. package/docs/packages/engine.mdx +1 -1
  458. package/docs/packages/server.mdx +1 -1
  459. package/docs/packages/tauri.mdx +1 -1
  460. package/docs/packages/test.mdx +1 -1
  461. package/docs/packages.mdx +1 -1
  462. package/docs/platform-integration.md +1 -1
  463. package/docs/predicates.mdx +1 -1
  464. package/docs/quickstart.mdx +68 -49
  465. package/docs/skill-setup.md +1 -1
  466. package/docs/skill.md +14 -13
  467. package/docs/telemetry.md +6 -4
  468. package/docs/tools/navigate.mdx +1 -1
  469. package/docs/tools/verify.mdx +4 -1
  470. package/docs/troubleshooting.mdx +1 -1
  471. package/docs/usage.md +17 -14
  472. package/package.json +18 -14
  473. package/LICENSE-ENTERPRISE +0 -37
  474. package/dist/features/ee/audit-log.d.ts +0 -14
  475. package/dist/features/ee/audit-log.js +0 -11
  476. package/dist/features/exhaust/exhaust-run.d.ts +0 -33
  477. package/dist/features/exhaust/exhaust-run.js +0 -82
@@ -0,0 +1,40 @@
1
+ /** The call in a streak that gets the hint. Two calls can be a deliberate retry; three is a loop. */
2
+ export declare const REPEAT_HINT_AT = 3;
3
+ export declare const RepeatHint: {
4
+ readonly NO_MATCH: string;
5
+ /** A no_match whose refusal listed the nearest targets: the retry is one of those refs. */
6
+ readonly noMatchNearest: (ref: string) => string;
7
+ readonly LOOK_SAME: string;
8
+ readonly RECOVERY: string;
9
+ readonly SAME: `You made this call ${string} times in a row with the same result.`;
10
+ /** A verdict repeated: name its own reason, the only thing the result says about why. */
11
+ readonly verdict: (verified: string, because: string | undefined) => string;
12
+ };
13
+ /** What a call came back with, as far as a repeat is concerned: an identity and the line to say. */
14
+ export interface RepeatOutcome {
15
+ readonly id: string;
16
+ readonly hint: string;
17
+ }
18
+ /** The outcome of a call that threw: its refusal reason. */
19
+ export declare function outcomeOfError(error: unknown): RepeatOutcome;
20
+ /** The outcome of a call that answered: its refusal reason, its verdict, or its whole answer. */
21
+ export declare function outcomeOfResult(tool: string, result: unknown): RepeatOutcome;
22
+ /** Tests only. */
23
+ export declare function resetRepeatHints(): void;
24
+ /**
25
+ * Note one call of one connection, and answer the hint when this call is the third in a streak.
26
+ * `owner` is the agent connection; undefined (the Harness, the HUD, an embedding) is never counted.
27
+ */
28
+ export declare function noteRepeat(owner: string | undefined, tool: string, args: Record<string, unknown>, outcome: RepeatOutcome): string | undefined;
29
+ /**
30
+ * Run one call of one connection inside its repeat streak. Answers the result and, on the third
31
+ * identical call, the hint. A call that throws keeps its hint beside the error (`withRepeatHint`).
32
+ */
33
+ export declare function inRepeatStreak(owner: string | undefined, tool: string, args: Record<string, unknown>, run: () => Promise<unknown>): Promise<{
34
+ raw: unknown;
35
+ hint: string | undefined;
36
+ }>;
37
+ /** The answer with the hint beside it. Extra text only: the verdict and every field stay as they are. */
38
+ export declare function withHintOn(answer: unknown, hint: string | undefined): unknown;
39
+ /** The error payload with the hint its call earned, if any. */
40
+ export declare function withRepeatHint<T extends object>(payload: T, error: unknown): T;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * One hint when an agent makes the same call, with the same result, for the third time in a row.
3
+ *
4
+ * Agents in the field made the same call five times or more in a row. Each answer was the same, and
5
+ * nothing in it said so. This module remembers the LAST call of each agent connection and gives one
6
+ * line, on the third identical call, that says what to try instead.
7
+ *
8
+ * Advice only: it reads a result that is already decided and never changes or blocks it. A hint says
9
+ * only what the result supports. When there is nothing specific to say, it says that the call was
10
+ * repeated with the same result.
11
+ */
12
+ import { createHash } from 'node:crypto';
13
+ import { RefusalReason, ReticleTool, isPlainRecord } from '@reticlehq/core';
14
+ import { resultIsError } from '../mcp/faults/mcp-is-error.js';
15
+ import { buildErrorPayload, codedRefusalOf, refusalReasonFor } from './error-recovery.js';
16
+ import { EnvelopeKey } from './tool-kit.js';
17
+ import { NEAREST_TARGETS_LEAD } from './act/resolve-target.js';
18
+ /** The call in a streak that gets the hint. Two calls can be a deliberate retry; three is a loop. */
19
+ export const REPEAT_HINT_AT = 3;
20
+ const COUNT = String(REPEAT_HINT_AT);
21
+ export const RepeatHint = {
22
+ NO_MATCH: `You made this call ${COUNT} times and each time no element matched. Do not send it again. ` +
23
+ 'Take one reticle_look { action: "find" } and use a ref from its answer.',
24
+ /** A no_match whose refusal listed the nearest targets: the retry is one of those refs. */
25
+ noMatchNearest: (ref) => `You made this call ${COUNT} times and each time no element matched. Do not send it again. ` +
26
+ `The refusal lists the nearest targets. Pass one of their refs as \`ref\`, for example "${ref}".`,
27
+ LOOK_SAME: `You made this look ${COUNT} times and each answer was the same, so the page did not change. ` +
28
+ 'Act on the page, or wait for a change with reticle_assert { action: "wait" }.',
29
+ RECOVERY: `You made this call ${COUNT} times and it was refused for the same reason each time. ` +
30
+ 'Do the step in `recovery` before you send it again.',
31
+ SAME: `You made this call ${COUNT} times in a row with the same result.`,
32
+ /** A verdict repeated: name its own reason, the only thing the result says about why. */
33
+ verdict: (verified, because) => `You made this call ${COUNT} times and each verdict was "${verified}".` +
34
+ (because === undefined ? '' : ` Its reason: "${because}".`) +
35
+ ' The same call gives the same verdict. Change the target, the action or the `until`.',
36
+ };
37
+ /**
38
+ * Result keys that change from call to call when nothing else did: the dispatcher's own advisories,
39
+ * the screenshot path, and the clock. A key that is missed here only means no hint fires.
40
+ */
41
+ const VOLATILE_KEYS = new Set([
42
+ ...Object.values(EnvelopeKey),
43
+ 'cursor',
44
+ 'since',
45
+ 'at',
46
+ 'ms',
47
+ 'elapsedMs',
48
+ 'durationMs',
49
+ ]);
50
+ /** The same JSON for the same value, whatever the key order. */
51
+ function stableJson(value) {
52
+ if (Array.isArray(value)) {
53
+ return `[${value.map(stableJson).join(',')}]`;
54
+ }
55
+ if (isPlainRecord(value)) {
56
+ const keys = Object.keys(value)
57
+ .filter((key) => value[key] !== undefined)
58
+ .sort();
59
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(',')}}`;
60
+ }
61
+ return JSON.stringify(value) ?? 'undefined';
62
+ }
63
+ /** A short digest, so a connection keeps a few bytes and not a whole page tree. */
64
+ function digest(text) {
65
+ return createHash('sha256').update(text).digest('hex').slice(0, 16);
66
+ }
67
+ /** The first ref in a no_match refusal's nearest-target list, or undefined when it has no list. */
68
+ function firstNearestRef(message) {
69
+ const at = message.indexOf(NEAREST_TARGETS_LEAD);
70
+ if (-1 === at) {
71
+ return undefined;
72
+ }
73
+ return /^(\S+) \(/.exec(message.slice(at + NEAREST_TARGETS_LEAD.length))?.[1];
74
+ }
75
+ function refusal(reason, recovery, message) {
76
+ const id = `refused:${reason}`;
77
+ if (RefusalReason.NO_MATCH === reason) {
78
+ const ref = firstNearestRef(message);
79
+ return { id, hint: ref === undefined ? RepeatHint.NO_MATCH : RepeatHint.noMatchNearest(ref) };
80
+ }
81
+ return { id, hint: 'string' === typeof recovery ? RepeatHint.RECOVERY : RepeatHint.SAME };
82
+ }
83
+ /** The outcome of a call that threw: its refusal reason. */
84
+ export function outcomeOfError(error) {
85
+ const message = error instanceof Error ? error.message : String(error);
86
+ const coded = codedRefusalOf(error);
87
+ return refusal(refusalReasonFor(message, coded), buildErrorPayload(message, coded).recovery, message);
88
+ }
89
+ /** The outcome of a call that answered: its refusal reason, its verdict, or its whole answer. */
90
+ export function outcomeOfResult(tool, result) {
91
+ if (!isPlainRecord(result)) {
92
+ return { id: `value:${digest(stableJson(result))}`, hint: RepeatHint.SAME };
93
+ }
94
+ if (resultIsError(result)) {
95
+ const message = String(result['error']);
96
+ return refusal(refusalReasonFor(message), result['recovery'], message);
97
+ }
98
+ if ('verified' in result) {
99
+ const verified = String(result['verified']);
100
+ const because = 'string' === typeof result['because'] ? result['because'] : undefined;
101
+ return {
102
+ id: `verdict:${verified}:${because ?? ''}`,
103
+ hint: RepeatHint.verdict(verified, because),
104
+ };
105
+ }
106
+ const kept = Object.fromEntries(Object.entries(result).filter(([key]) => !VOLATILE_KEYS.has(key)));
107
+ return {
108
+ id: `answer:${digest(stableJson(kept))}`,
109
+ hint: ReticleTool.LOOK === tool ? RepeatHint.LOOK_SAME : RepeatHint.SAME,
110
+ };
111
+ }
112
+ /** Bound on remembered connections: a daemon outlives them. Each keeps only its last call. */
113
+ const MAX_CONNECTIONS = 500;
114
+ const lastByConnection = new Map();
115
+ /** Tests only. */
116
+ export function resetRepeatHints() {
117
+ lastByConnection.clear();
118
+ }
119
+ /**
120
+ * Note one call of one connection, and answer the hint when this call is the third in a streak.
121
+ * `owner` is the agent connection; undefined (the Harness, the HUD, an embedding) is never counted.
122
+ */
123
+ export function noteRepeat(owner, tool, args, outcome) {
124
+ if (owner === undefined) {
125
+ return undefined;
126
+ }
127
+ const call = digest(`${tool}:${stableJson(args)}`);
128
+ const last = lastByConnection.get(owner);
129
+ const count = last?.call === call && last.outcome === outcome.id ? last.count + 1 : 1;
130
+ // Delete first, so the map order is last use and the oldest connection is the one that goes.
131
+ lastByConnection.delete(owner);
132
+ if (lastByConnection.size >= MAX_CONNECTIONS) {
133
+ const oldest = lastByConnection.keys().next().value;
134
+ if (oldest !== undefined) {
135
+ lastByConnection.delete(oldest);
136
+ }
137
+ }
138
+ lastByConnection.set(owner, { call, outcome: outcome.id, count });
139
+ return REPEAT_HINT_AT === count ? outcome.hint : undefined;
140
+ }
141
+ /** Hints for calls that threw, kept beside the error so the boundary that answers can read them. */
142
+ const hintByError = new WeakMap();
143
+ /**
144
+ * Run one call of one connection inside its repeat streak. Answers the result and, on the third
145
+ * identical call, the hint. A call that throws keeps its hint beside the error (`withRepeatHint`).
146
+ */
147
+ export async function inRepeatStreak(owner, tool, args, run) {
148
+ let raw;
149
+ try {
150
+ raw = await run();
151
+ }
152
+ catch (error) {
153
+ const hint = noteRepeat(owner, tool, args, outcomeOfError(error));
154
+ if (hint !== undefined && 'object' === typeof error && null !== error) {
155
+ hintByError.set(error, hint);
156
+ }
157
+ throw error;
158
+ }
159
+ return { raw, hint: noteRepeat(owner, tool, args, outcomeOfResult(tool, raw)) };
160
+ }
161
+ /** The answer with the hint beside it. Extra text only: the verdict and every field stay as they are. */
162
+ export function withHintOn(answer, hint) {
163
+ return hint !== undefined && isPlainRecord(answer)
164
+ ? { ...answer, [EnvelopeKey.REPEAT_HINT]: hint }
165
+ : answer;
166
+ }
167
+ /** The error payload with the hint its call earned, if any. */
168
+ export function withRepeatHint(payload, error) {
169
+ const hint = 'object' === typeof error && null !== error ? hintByError.get(error) : undefined;
170
+ return hint === undefined ? payload : { ...payload, [EnvelopeKey.REPEAT_HINT]: hint };
171
+ }
@@ -14,8 +14,8 @@ export declare function renderRunReport(report: RunReport): string;
14
14
  export declare function endsRun(tool: string, args: Record<string, unknown>): boolean;
15
15
  /** What an answer says the run saved or read. An answer that refused counts for nothing. */
16
16
  export declare function noteToolResult(ledger: RunLedger, tool: string, args: Record<string, unknown>, result: unknown): void;
17
- /** The report as an answer field, or no field when the ledger holds no run. Empties the ledger. */
18
- export declare function runReportField(ledger: RunLedger, root: string | undefined, env: Record<string, string | undefined>, now: number): Partial<Record<typeof RUN_REPORT_FIELD, {
17
+ /** The owner's report as an answer field, or no field when the owner has no run. Ends that run. */
18
+ export declare function runReportField(ledger: RunLedger, root: string | undefined, env: Record<string, string | undefined>, now: number, owner?: string): Partial<Record<typeof RUN_REPORT_FIELD, {
19
19
  report: RunReport;
20
20
  markdown: string;
21
21
  instruction: string;
@@ -34,12 +34,15 @@ function headline(report) {
34
34
  const count = (v) => all.filter((each) => v === each).length;
35
35
  const total = all.length;
36
36
  const word = `${HEAD}${WORD[report.verified]}**${SEP}`;
37
- if (0 === total)
37
+ if (0 === total) {
38
38
  return `${word}${Said.NOTHING_CHECKED}`;
39
- if (Verified.NO === report.verified)
39
+ }
40
+ if (Verified.NO === report.verified) {
40
41
  return `${word}${String(count(Verified.NO))} of ${plural(total, 'check')} did not hold`;
41
- if (Verified.YES === report.verified)
42
+ }
43
+ if (Verified.YES === report.verified) {
42
44
  return `${word}${String(total)} of ${plural(total, 'check')} held`;
45
+ }
43
46
  return `${word}${String(total - count(Verified.YES) - count(Verified.NO))} of ${plural(total, 'check')} undecided`;
44
47
  }
45
48
  /** The report as markdown: the verdict, each claim with its evidence, then what the run left. */
@@ -95,39 +98,48 @@ const INTENT_READS = new Set(['list', 'index', 'subject', 'get']);
95
98
  const isRecord = (value) => null !== value && 'object' === typeof value && !Array.isArray(value);
96
99
  /** What an answer says the run saved or read. An answer that refused counts for nothing. */
97
100
  export function noteToolResult(ledger, tool, args, result) {
98
- if (!isRecord(result) || result['error'] !== undefined)
101
+ if (!isRecord(result) || result['error'] !== undefined) {
99
102
  return;
103
+ }
100
104
  if (ReticleTool.FLOW_SAVE === tool || ReticleTool.FLOW_SAVE_RECORDED === tool) {
101
105
  const name = result['name'];
102
- if ('string' === typeof name)
106
+ if ('string' === typeof name) {
103
107
  ledger.flowSaved(name);
108
+ }
104
109
  return;
105
110
  }
106
111
  const action = asString(args['action']);
107
112
  if (ReticleTool.INTENT === tool) {
108
113
  // The intent ledger in `.reticle/intent/` is the memory an unlinked project has.
109
- if (IntentWrite.RECORD === action)
114
+ if (IntentWrite.RECORD === action) {
110
115
  ledger.memoryWritten();
116
+ }
111
117
  const declared = args['intents'];
112
- if (IntentWrite.DECLARE === action && Array.isArray(declared))
118
+ if (IntentWrite.DECLARE === action && Array.isArray(declared)) {
113
119
  ledger.memoryWritten(declared.length);
114
- if (action !== undefined && INTENT_READS.has(action))
120
+ }
121
+ if (action !== undefined && INTENT_READS.has(action)) {
115
122
  ledger.memoryRead([JSON.stringify(result)]);
123
+ }
116
124
  return;
117
125
  }
118
- if (ReticleTool.MEMORY !== tool)
126
+ if (ReticleTool.MEMORY !== tool) {
119
127
  return;
120
- if ('add' === action && result['added'] !== undefined)
128
+ }
129
+ if ('add' === action && result['added'] !== undefined) {
121
130
  ledger.memoryWritten();
131
+ }
122
132
  const known = result['known'];
123
- if (Array.isArray(known))
133
+ if (Array.isArray(known)) {
124
134
  ledger.memoryRead(known.map((entry) => JSON.stringify(entry)));
135
+ }
125
136
  }
126
- /** The report as an answer field, or no field when the ledger holds no run. Empties the ledger. */
127
- export function runReportField(ledger, root, env, now) {
128
- if (ledger.isEmpty())
137
+ /** The owner's report as an answer field, or no field when the owner has no run. Ends that run. */
138
+ export function runReportField(ledger, root, env, now, owner) {
139
+ if (ledger.isEmpty(owner)) {
129
140
  return {};
130
- const taken = ledger.take(now);
141
+ }
142
+ const taken = ledger.take(now, owner);
131
143
  const silenced = env[UPGRADE_HINT_SILENCE_ENV] !== undefined;
132
144
  const linked = root === undefined || linkedToPlatform(root, env);
133
145
  const report = silenced || linked ? taken : { ...taken, cloud: CLOUD_VALUE_LINE };
@@ -55,3 +55,17 @@ export declare function suiteFixturePort(realInput: RealInputProvider | undefine
55
55
  * is the reach the boundary guard exists to ask about.
56
56
  */
57
57
  export declare function sessionMutationPort(realInput: RealInputProvider | undefined, appUrl: string | undefined): Promise<NetworkMutationPort | undefined>;
58
+ /**
59
+ * The state a verify run started in, put back before each flow after the first.
60
+ *
61
+ * `reticle verify` replays every flow in ONE driven page. A flow that signs out (an auto-saved
62
+ * "log out" fragment, or a journey that ends on the logout link) left every later flow signed out,
63
+ * and each of them then failed for a reason none of them named. The leased suite path never had
64
+ * this: each flow boots its own context from one captured seed. This gives the single-page path
65
+ * the same start.
66
+ *
67
+ * Call it before each flow. It answers `undefined` to go on, or the reason the flow cannot start
68
+ * where the run started, which the caller reports as not proved. Nothing to capture (no driven
69
+ * page, no storage support) means the run goes on as before.
70
+ */
71
+ export declare function flowStartState(provider: RealInputProvider | undefined, currentUrl: () => string | undefined): () => Promise<string | undefined>;
@@ -100,3 +100,56 @@ export async function sessionMutationPort(realInput, appUrl) {
100
100
  return undefined;
101
101
  }
102
102
  }
103
+ /**
104
+ * The state a verify run started in, put back before each flow after the first.
105
+ *
106
+ * `reticle verify` replays every flow in ONE driven page. A flow that signs out (an auto-saved
107
+ * "log out" fragment, or a journey that ends on the logout link) left every later flow signed out,
108
+ * and each of them then failed for a reason none of them named. The leased suite path never had
109
+ * this: each flow boots its own context from one captured seed. This gives the single-page path
110
+ * the same start.
111
+ *
112
+ * Call it before each flow. It answers `undefined` to go on, or the reason the flow cannot start
113
+ * where the run started, which the caller reports as not proved. Nothing to capture (no driven
114
+ * page, no storage support) means the run goes on as before.
115
+ */
116
+ export function flowStartState(provider, currentUrl) {
117
+ let first = true;
118
+ let saved;
119
+ return async () => {
120
+ const url = currentUrl();
121
+ if (first) {
122
+ first = false;
123
+ if (provider === undefined || url === undefined) {
124
+ return undefined;
125
+ }
126
+ try {
127
+ const port = await fixturePortFor(provider, url);
128
+ saved = port === undefined ? undefined : { state: await port.capture(), url };
129
+ }
130
+ catch {
131
+ saved = undefined;
132
+ }
133
+ return undefined;
134
+ }
135
+ if (saved === undefined || provider === undefined) {
136
+ return undefined;
137
+ }
138
+ try {
139
+ // Straight to the provider, not through `fixturePortFor`: its address check compares the
140
+ // session's recorded address with the page's, and a flow that reloaded or signed out leaves
141
+ // the two different while the page is the same. The provider still refuses a page it does
142
+ // not drive (it answers false), so nothing is restored into a stranger's page.
143
+ // Tabs first: a tab the previous flow opened is a second connected session otherwise.
144
+ await provider.closeOtherPages?.();
145
+ const restored = await provider.applyStorageState?.(url ?? saved.url, saved.state);
146
+ return true === restored
147
+ ? undefined
148
+ : 'could not put the page back in the state the run started with: no driven page matched';
149
+ }
150
+ catch (error) {
151
+ const message = error instanceof Error ? error.message : String(error);
152
+ return `could not put the page back in the state the run started with: ${message}`;
153
+ }
154
+ };
155
+ }
@@ -31,6 +31,12 @@ export interface ToolDeps<Ext = unknown> {
31
31
  * the fake-pool lease tests are deliberately runnable without a real Chromium.
32
32
  */
33
33
  browserProbe?: () => Promise<ChromiumProbe>;
34
+ /**
35
+ * Whether something on this loopback port accepted a connection. Asked only after a lease
36
+ * navigation timed out, to tell a dev server compiling its first route from no server (#2005).
37
+ * Optional: absent ⇒ the timeout keeps its generic advice.
38
+ */
39
+ portAccepts?: (port: number) => Promise<boolean>;
34
40
  baselines: BaselineStore;
35
41
  recordings: RecordingStore;
36
42
  /** on-disk anchored-flow store (.reticle/flows/). */
@@ -96,6 +102,11 @@ export interface ToolDeps<Ext = unknown> {
96
102
  } | undefined>;
97
103
  /** The one dev server running in the caller's project folder, for a lease that names no url. */
98
104
  projectAppUrl?: () => Promise<string | undefined>;
105
+ /**
106
+ * The first-session offer for this attach id's first call, when no app is attached and the
107
+ * project is not wired (see zero-install-first-call.ts). Absent: no offer.
108
+ */
109
+ firstSessionOffer?: (attachId: string) => string | undefined;
99
110
  /** cross-run outcome memory (.reticle/project.json). */
100
111
  project: ProjectStore;
101
112
  /** optional native-input provider. undefined ⇒ everything stays synthetic. */
@@ -303,10 +314,17 @@ export declare const EnvelopeKey: {
303
314
  * what it cannot see, and the command that wires the app for good. See zero-install-first-call.ts.
304
315
  */
305
316
  readonly ZERO_INSTALL: "zero_install";
317
+ /**
318
+ * Once per agent connection, on its first call: this unwired web app can be checked now with the
319
+ * lease, and `init` needs the user's consent. See zero-install-first-call.ts.
320
+ */
321
+ readonly FIRST_SESSION_OFFER: "first_session_offer";
306
322
  /** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
307
323
  readonly NOTICES: "notices";
308
324
  /** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
309
325
  readonly RUN_REPORT: "runReport";
326
+ /** On the third identical call with the same result: what to try instead. See repeat-hint.ts. */
327
+ readonly REPEAT_HINT: "repeatHint";
310
328
  };
311
329
  export type EnvelopeKey = (typeof EnvelopeKey)[keyof typeof EnvelopeKey];
312
330
  /**
@@ -99,10 +99,17 @@ export const EnvelopeKey = {
99
99
  * what it cannot see, and the command that wires the app for good. See zero-install-first-call.ts.
100
100
  */
101
101
  ZERO_INSTALL: 'zero_install',
102
+ /**
103
+ * Once per agent connection, on its first call: this unwired web app can be checked now with the
104
+ * lease, and `init` needs the user's consent. See zero-install-first-call.ts.
105
+ */
106
+ FIRST_SESSION_OFFER: 'first_session_offer',
102
107
  /** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
103
108
  NOTICES: 'notices',
104
109
  /** The end-of-run report, on the call that ends an agent's run. See run-report.ts. */
105
110
  RUN_REPORT: RUN_REPORT_FIELD,
111
+ /** On the third identical call with the same result: what to try instead. See repeat-hint.ts. */
112
+ REPEAT_HINT: 'repeatHint',
106
113
  };
107
114
  /**
108
115
  * The sentence every session-bound result carries while its leased tab runs on a stubbed shell.
@@ -149,6 +156,8 @@ export const CDP_TOOLS = new Set([
149
156
  // Breaks a request through the same Playwright route `reticle_network_mock` uses, so it fails the
150
157
  // same way under version skew and must be refused with the same sentence.
151
158
  ReticleTool.FLOW_MUTATE,
159
+ // Reads JS coverage through the lease's Playwright page, the way `reticle_network_mock` reaches it.
160
+ ReticleTool.LEASE_COVERAGE,
152
161
  ]);
153
162
  /**
154
163
  * Tools whose result hands the agent refs. The tab they were minted in is remembered, so the call
@@ -164,7 +173,6 @@ export const REF_MINTING_TOOLS = new Set([
164
173
  // The same three merged, on the `merged` surface. Its `state` action mints nothing, and
165
174
  // over-inclusion is the safe direction here: the worst case is a refusal naming two tabs.
166
175
  ReticleTool.LOOK,
167
- ReticleTool.EXPLORE,
168
176
  // `crawl` mints refs for the controls it drives and `coverage` for the ones it reports untouched.
169
177
  // Both are actions on the merged verify tool now.
170
178
  ReticleTool.VERIFY,
@@ -205,11 +213,9 @@ export const SESSION_BOUND_TOOLS = new Set([
205
213
  ReticleTool.ANIMATIONS,
206
214
  ReticleTool.BASELINE, // merged save/list/diff — save+diff are live reads
207
215
  ReticleTool.RECORD, // merged start/stop — both live
208
- ReticleTool.REPLAY,
209
216
  ReticleTool.CLOCK,
210
217
  ReticleTool.STATE,
211
218
  ReticleTool.STORAGE,
212
- ReticleTool.EXPLORE,
213
219
  ReticleTool.SCROLL_TO,
214
220
  ReticleTool.NAVIGATE,
215
221
  ]);
@@ -473,7 +473,6 @@ const OPEN_WORLD = new Set([
473
473
  ReticleTool.NAVIGATE,
474
474
  ReticleTool.SESSION,
475
475
  ReticleTool.VERIFY,
476
- ReticleTool.EXPLORE,
477
476
  ReticleTool.FEEDBACK,
478
477
  ReticleTool.RUN,
479
478
  ]);