@reticlehq/server 3.5.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (721) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +123 -116
  3. package/dist/chromium-launch-options.d.ts +3 -1
  4. package/dist/chromium-launch-options.js +2 -1
  5. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  6. package/dist/command/cli/adhoc-suite.js +42 -7
  7. package/dist/command/cli/adhoc-verdict.d.ts +19 -2
  8. package/dist/command/cli/adhoc-verdict.js +76 -9
  9. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  10. package/dist/command/cli/answers/gate-exit.js +45 -0
  11. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  12. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  13. package/dist/command/cli/answers/open-note.d.ts +2 -0
  14. package/dist/command/cli/answers/open-note.js +22 -0
  15. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  16. package/dist/command/cli/auth/device-flow.js +17 -0
  17. package/dist/command/cli/cli-doctor.js +14 -0
  18. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  19. package/dist/command/cli/cli-flow-commands.js +31 -112
  20. package/dist/command/cli/cli-kill.js +3 -2
  21. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  22. package/dist/command/cli/cli-parse-grammar.js +75 -0
  23. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  24. package/dist/command/cli/cli-parse-verify.js +18 -0
  25. package/dist/command/cli/cli-parse.d.ts +19 -28
  26. package/dist/command/cli/cli-parse.js +82 -182
  27. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  28. package/dist/command/cli/cli-update-commands.js +61 -9
  29. package/dist/command/cli/cli-usage.d.ts +33 -0
  30. package/dist/command/cli/cli-usage.js +287 -0
  31. package/dist/command/cli/cli-verify.d.ts +35 -5
  32. package/dist/command/cli/cli-verify.js +114 -35
  33. package/dist/command/cli/cloud-cli.d.ts +13 -0
  34. package/dist/command/cli/cloud-cli.js +192 -341
  35. package/dist/command/cli/cloud-kit.d.ts +12 -0
  36. package/dist/command/cli/cloud-kit.js +41 -2
  37. package/dist/command/cli/cloud-link.d.ts +57 -0
  38. package/dist/command/cli/cloud-link.js +308 -0
  39. package/dist/command/cli/cloud-login.d.ts +22 -0
  40. package/dist/command/cli/cloud-login.js +96 -8
  41. package/dist/command/cli/context-command.d.ts +1 -0
  42. package/dist/command/cli/context-command.js +33 -0
  43. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  44. package/dist/command/cli/daemon-start-options.js +24 -3
  45. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
  46. package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
  47. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  48. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  49. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  50. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  51. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  52. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  53. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  54. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  55. package/dist/command/cli/drive/drive-attach.d.ts +27 -2
  56. package/dist/command/cli/drive/drive-attach.js +71 -4
  57. package/dist/command/cli/drive/drive-command.d.ts +2 -1
  58. package/dist/command/cli/drive/drive-command.js +13 -7
  59. package/dist/command/cli/known-regression.d.ts +13 -0
  60. package/dist/command/cli/known-regression.js +34 -0
  61. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  62. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  63. package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
  64. package/dist/command/cli/mcp-command.d.ts +6 -0
  65. package/dist/command/cli/mcp-command.js +13 -5
  66. package/dist/command/cli/ports/port-holder.d.ts +10 -0
  67. package/dist/command/cli/ports/port-holder.js +25 -1
  68. package/dist/command/cli/project-name.d.ts +29 -1
  69. package/dist/command/cli/project-name.js +107 -2
  70. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  71. package/dist/command/cli/setup-mcp-cli.js +35 -12
  72. package/dist/command/cli/status/status-lines.d.ts +1 -0
  73. package/dist/command/cli/status/status-lines.js +47 -2
  74. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  75. package/dist/command/cli/status/workspace-links.js +29 -0
  76. package/dist/command/cli/try-command.d.ts +96 -0
  77. package/dist/command/cli/try-command.js +362 -0
  78. package/dist/command/cli/tutorial.d.ts +0 -100
  79. package/dist/command/cli/tutorial.js +0 -181
  80. package/dist/command/cli/verify-results.d.ts +19 -0
  81. package/dist/command/cli/verify-results.js +29 -0
  82. package/dist/command/cli-onboarding.d.ts +0 -11
  83. package/dist/command/cli-onboarding.js +0 -15
  84. package/dist/command/cli.d.ts +20 -0
  85. package/dist/command/cli.js +130 -104
  86. package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
  87. package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
  88. package/dist/command/daemon/daemon-resilience.js +4 -4
  89. package/dist/command/daemon/daemon-resolve.d.ts +23 -1
  90. package/dist/command/daemon/daemon-resolve.js +79 -9
  91. package/dist/command/setup/agent-writer.d.ts +1 -1
  92. package/dist/command/setup/agent-writer.js +3 -2
  93. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  94. package/dist/command/setup/bringup/bridge-port.js +13 -3
  95. package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
  96. package/dist/command/setup/bringup/connect-lease.js +1 -0
  97. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  98. package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
  99. package/dist/command/setup/bringup/dev-server-wait.js +19 -0
  100. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  101. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  102. package/dist/command/setup/init/agent-restart.js +28 -0
  103. package/dist/command/setup/init/init-port.d.ts +14 -1
  104. package/dist/command/setup/init/init-port.js +32 -2
  105. package/dist/command/setup/init/init-runtime.d.ts +22 -2
  106. package/dist/command/setup/init/init-runtime.js +114 -38
  107. package/dist/command/setup/node-effects.d.ts +2 -0
  108. package/dist/command/setup/node-effects.js +38 -9
  109. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  110. package/dist/command/setup/probe/existing-app.js +14 -0
  111. package/dist/command/setup/remaining-steps.js +2 -1
  112. package/dist/command/setup/run-setup.d.ts +34 -9
  113. package/dist/command/setup/run-setup.js +65 -51
  114. package/dist/command/setup/setup-command.d.ts +25 -1
  115. package/dist/command/setup/setup-command.js +59 -4
  116. package/dist/command/setup/setup-mcp.js +25 -2
  117. package/dist/command/setup/tauri-signing.d.ts +19 -0
  118. package/dist/command/setup/tauri-signing.js +79 -0
  119. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  120. package/dist/command/setup/terminal/listeners.js +37 -6
  121. package/dist/command/update/update-nudge.d.ts +9 -0
  122. package/dist/command/update/update-nudge.js +1 -1
  123. package/dist/command/update/updater.js +11 -15
  124. package/dist/command/version/version-nudge.js +3 -0
  125. package/dist/command/version/version-skew.d.ts +20 -1
  126. package/dist/command/version/version-skew.js +49 -4
  127. package/dist/features/crawl/crawl-tools.js +4 -0
  128. package/dist/features/crawl/crawl.d.ts +6 -0
  129. package/dist/features/crawl/crawl.js +23 -2
  130. package/dist/features/exhaust/ledger.d.ts +21 -14
  131. package/dist/features/exhaust/ledger.js +35 -9
  132. package/dist/features/harness/app-findings.d.ts +2 -0
  133. package/dist/features/harness/app-findings.js +52 -0
  134. package/dist/features/harness/drive-report.d.ts +61 -1
  135. package/dist/features/harness/drive-report.js +394 -26
  136. package/dist/features/harness/drive-runs.d.ts +120 -0
  137. package/dist/features/harness/drive-runs.js +289 -0
  138. package/dist/features/harness/drivers.d.ts +10 -14
  139. package/dist/features/harness/drivers.js +10 -14
  140. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  141. package/dist/features/harness/explore/console-pages.js +146 -0
  142. package/dist/features/harness/explore/disparity.d.ts +19 -0
  143. package/dist/features/harness/explore/disparity.js +71 -0
  144. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  145. package/dist/features/harness/explore/fake-app.js +49 -0
  146. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  147. package/dist/features/harness/explore/goal-search.js +144 -0
  148. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  149. package/dist/features/harness/explore/page-tree.js +148 -0
  150. package/dist/features/harness/explore/site-map.d.ts +34 -0
  151. package/dist/features/harness/explore/site-map.js +150 -0
  152. package/dist/features/harness/fill-values.d.ts +3 -73
  153. package/dist/features/harness/fill-values.js +3 -169
  154. package/dist/features/harness/goals.d.ts +82 -0
  155. package/dist/features/harness/goals.js +330 -0
  156. package/dist/features/harness/harness.d.ts +51 -1
  157. package/dist/features/harness/harness.js +207 -6
  158. package/dist/features/harness/platform/drive-target.d.ts +30 -0
  159. package/dist/features/harness/platform/drive-target.js +81 -0
  160. package/dist/features/harness/platform/local-apps.d.ts +127 -0
  161. package/dist/features/harness/platform/local-apps.js +280 -0
  162. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  163. package/dist/features/harness/platform/persona-credentials.js +69 -0
  164. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  165. package/dist/features/harness/platform/platform-drives.js +114 -0
  166. package/dist/features/harness/platform/refusal.d.ts +52 -0
  167. package/dist/features/harness/platform/refusal.js +71 -0
  168. package/dist/features/harness/platform/remote-drive.d.ts +186 -0
  169. package/dist/features/harness/platform/remote-drive.js +378 -0
  170. package/dist/features/harness/platform/script.d.ts +94 -0
  171. package/dist/features/harness/platform/script.js +260 -0
  172. package/dist/features/harness/platform/server-driver.d.ts +54 -0
  173. package/dist/features/harness/platform/server-driver.js +182 -0
  174. package/dist/features/harness/platform-config.d.ts +41 -1
  175. package/dist/features/harness/platform-config.js +106 -9
  176. package/dist/features/harness/route-guess.d.ts +13 -0
  177. package/dist/features/harness/route-guess.js +49 -0
  178. package/dist/features/harness/script/app-controls.d.ts +5 -0
  179. package/dist/features/harness/script/app-controls.js +40 -0
  180. package/dist/features/harness/script/lane-ids.d.ts +14 -0
  181. package/dist/features/harness/script/lane-ids.js +16 -0
  182. package/dist/features/harness/script/script-run.d.ts +70 -0
  183. package/dist/features/harness/script/script-run.js +606 -0
  184. package/dist/features/license/license.d.ts +2 -2
  185. package/dist/features/visual/step-shots.d.ts +31 -0
  186. package/dist/features/visual/step-shots.js +231 -0
  187. package/dist/features/visual/visual-tools.d.ts +10 -1
  188. package/dist/features/visual/visual-tools.js +62 -17
  189. package/dist/hooks/client-directory.d.ts +18 -0
  190. package/dist/hooks/client-directory.js +57 -0
  191. package/dist/hooks/coding-agents.d.ts +34 -0
  192. package/dist/hooks/coding-agents.js +117 -0
  193. package/dist/hooks/driven-by.d.ts +23 -0
  194. package/dist/hooks/driven-by.js +56 -0
  195. package/dist/hooks/hook-bus.d.ts +4 -0
  196. package/dist/hooks/hook-bus.js +18 -0
  197. package/dist/hooks/hook-commands.js +15 -4
  198. package/dist/hooks/tool-log.d.ts +9 -0
  199. package/dist/hooks/tool-log.js +29 -0
  200. package/dist/index.d.ts +2 -0
  201. package/dist/index.js +80 -243
  202. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  203. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  204. package/dist/judgement/capsule/causal-summary.js +33 -0
  205. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  206. package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
  207. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  208. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  209. package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
  210. package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
  211. package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
  212. package/dist/judgement/runs/artifact/run-store.js +195 -3
  213. package/dist/judgement/runs/context-tools.js +59 -1
  214. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  215. package/dist/judgement/runs/default-run-id.js +16 -0
  216. package/dist/judgement/runs/drive-run.d.ts +71 -1
  217. package/dist/judgement/runs/drive-run.js +317 -5
  218. package/dist/judgement/runs/repair-prompt.js +1 -1
  219. package/dist/judgement/runs/resume.d.ts +44 -0
  220. package/dist/judgement/runs/resume.js +137 -0
  221. package/dist/judgement/runs/reticle-runner.js +13 -3
  222. package/dist/judgement/runs/runner-port.d.ts +5 -1
  223. package/dist/judgement/runs/runner-port.js +8 -2
  224. package/dist/judgement/runs/verification-sync.d.ts +5 -2
  225. package/dist/judgement/runs/verification-sync.js +40 -18
  226. package/dist/language/flows/change/gate.d.ts +10 -0
  227. package/dist/language/flows/change/gate.js +22 -0
  228. package/dist/language/flows/decision.js +36 -1
  229. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  230. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  231. package/dist/language/flows/flow-anchor.d.ts +61 -10
  232. package/dist/language/flows/flow-anchor.js +98 -6
  233. package/dist/language/flows/flow-cross-step.d.ts +15 -0
  234. package/dist/language/flows/flow-cross-step.js +21 -0
  235. package/dist/language/flows/flow-intent.d.ts +1 -0
  236. package/dist/language/flows/flow-journey.d.ts +6 -0
  237. package/dist/language/flows/flow-journey.js +20 -0
  238. package/dist/language/flows/flow-learning.d.ts +4 -0
  239. package/dist/language/flows/flow-learning.js +45 -14
  240. package/dist/language/flows/flow-mutate-tools.js +5 -3
  241. package/dist/language/flows/flow-replay-run.d.ts +23 -9
  242. package/dist/language/flows/flow-replay-run.js +115 -110
  243. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  244. package/dist/language/flows/flow-replay.d.ts +40 -1
  245. package/dist/language/flows/flow-replay.js +110 -22
  246. package/dist/language/flows/flow-result.d.ts +22 -1
  247. package/dist/language/flows/flow-result.js +47 -2
  248. package/dist/language/flows/flow-scope.js +5 -1
  249. package/dist/language/flows/flow-step-runners.d.ts +22 -2
  250. package/dist/language/flows/flow-step-runners.js +247 -47
  251. package/dist/language/flows/flow-store-for-session.d.ts +2 -2
  252. package/dist/language/flows/flow-store-for-session.js +7 -3
  253. package/dist/language/flows/flow-tools.d.ts +10 -0
  254. package/dist/language/flows/flow-tools.js +112 -89
  255. package/dist/language/flows/flows.d.ts +16 -1
  256. package/dist/language/flows/flows.js +74 -12
  257. package/dist/language/flows/heal-run.js +6 -4
  258. package/dist/language/flows/narrow-write.d.ts +7 -0
  259. package/dist/language/flows/narrow-write.js +36 -1
  260. package/dist/language/flows/recording/flake.d.ts +2 -2
  261. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  262. package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
  263. package/dist/language/flows/recording/tape/recordings.js +95 -13
  264. package/dist/language/flows/replay-from-hud.d.ts +20 -0
  265. package/dist/language/flows/replay-from-hud.js +51 -0
  266. package/dist/language/flows/replay.d.ts +9 -5
  267. package/dist/language/flows/replay.js +56 -15
  268. package/dist/language/flows/single-replay.d.ts +7 -0
  269. package/dist/language/flows/single-replay.js +26 -0
  270. package/dist/language/flows/suite/suite-flakes.js +2 -0
  271. package/dist/language/flows/suite-selection.d.ts +2 -15
  272. package/dist/language/flows/suite-selection.js +4 -3
  273. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  274. package/dist/language/flows/verify-change-tools.js +202 -191
  275. package/dist/launch-chromium.d.ts +27 -5
  276. package/dist/launch-chromium.js +38 -8
  277. package/dist/memory/cloud/cloud-config.d.ts +22 -1
  278. package/dist/memory/cloud/cloud-config.js +34 -5
  279. package/dist/memory/cloud/cloud-sync.d.ts +17 -14
  280. package/dist/memory/cloud/cloud-sync.js +15 -4
  281. package/dist/memory/cloud/harness-config.d.ts +75 -1
  282. package/dist/memory/cloud/harness-config.js +115 -24
  283. package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
  284. package/dist/memory/cloud/hud-notices-source.js +128 -0
  285. package/dist/memory/cloud/memory-scope.d.ts +161 -0
  286. package/dist/memory/cloud/memory-scope.js +227 -0
  287. package/dist/memory/cloud/sync-cycle.d.ts +44 -7
  288. package/dist/memory/cloud/sync-cycle.js +129 -15
  289. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  290. package/dist/memory/cloud/sync-daemon.js +121 -9
  291. package/dist/memory/cloud/sync-disk.d.ts +1 -1
  292. package/dist/memory/cloud/sync-disk.js +31 -10
  293. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  294. package/dist/memory/cloud/sync-screenshots.js +105 -0
  295. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  296. package/dist/memory/cloud/unsynced-roots.js +166 -0
  297. package/dist/memory/impact/account-watch.d.ts +34 -0
  298. package/dist/memory/impact/account-watch.js +59 -0
  299. package/dist/memory/impact/impact-recorder.d.ts +8 -0
  300. package/dist/memory/impact/impact-recorder.js +12 -2
  301. package/dist/memory/impact/impact-store.d.ts +17 -4
  302. package/dist/memory/impact/impact-store.js +169 -63
  303. package/dist/memory/intent/inline-intent.d.ts +1 -0
  304. package/dist/memory/intent/intent-shard-store.js +16 -4
  305. package/dist/memory/intent/intent-shard.d.ts +14 -2
  306. package/dist/memory/intent/intent-store.d.ts +1 -0
  307. package/dist/memory/intent/intent-tools.js +122 -4
  308. package/dist/memory/intent/open-intents.d.ts +6 -0
  309. package/dist/memory/intent/open-intents.js +10 -1
  310. package/dist/memory/intent/settled-words.d.ts +24 -0
  311. package/dist/memory/intent/settled-words.js +130 -0
  312. package/dist/memory/journal/drive-flow.d.ts +16 -0
  313. package/dist/memory/journal/drive-flow.js +34 -2
  314. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  315. package/dist/memory/journal/drive-run-flush.js +20 -5
  316. package/dist/memory/journal/envelope.d.ts +8 -8
  317. package/dist/memory/journal/journal-recorder.js +52 -3
  318. package/dist/memory/journal/on-disk/retention.d.ts +8 -0
  319. package/dist/memory/journal/on-disk/retention.js +32 -2
  320. package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
  321. package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
  322. package/dist/memory/journal/session-end.d.ts +15 -1
  323. package/dist/memory/journal/session-end.js +42 -9
  324. package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
  325. package/dist/memory/project/artifact-root-resolver.js +125 -16
  326. package/dist/memory/project/artifact-root.d.ts +46 -8
  327. package/dist/memory/project/artifact-root.js +89 -10
  328. package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
  329. package/dist/memory/project/dir/reticle-dir.js +26 -3
  330. package/dist/memory/project/link-directory.d.ts +15 -0
  331. package/dist/memory/project/link-directory.js +44 -0
  332. package/dist/memory/project/project-tools.js +22 -3
  333. package/dist/memory/project/root-claims.d.ts +6 -0
  334. package/dist/memory/project/root-claims.js +39 -0
  335. package/dist/memory/project/session-root.d.ts +26 -1
  336. package/dist/memory/project/session-root.js +49 -5
  337. package/dist/memory/project/sync-status.d.ts +85 -0
  338. package/dist/memory/project/sync-status.js +224 -0
  339. package/dist/memory/recall/memory-tools.js +47 -2
  340. package/dist/memory/recall/platform-memory.d.ts +34 -0
  341. package/dist/memory/recall/platform-memory.js +139 -0
  342. package/dist/memory/recall/project-memory.d.ts +19 -0
  343. package/dist/memory/recall/project-memory.js +80 -13
  344. package/dist/portal/bridge/bridge.d.ts +9 -3
  345. package/dist/portal/bridge/bridge.js +82 -22
  346. package/dist/portal/bridge/harness-request.d.ts +23 -0
  347. package/dist/portal/bridge/harness-request.js +27 -0
  348. package/dist/portal/bridge/pairing-token.d.ts +9 -0
  349. package/dist/portal/bridge/pairing-token.js +17 -0
  350. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  351. package/dist/portal/bridge/wrong-path.js +35 -0
  352. package/dist/portal/input/network-mock-tools.js +11 -2
  353. package/dist/portal/input/real-input.d.ts +83 -10
  354. package/dist/portal/input/real-input.js +218 -30
  355. package/dist/portal/input/viewport-tools.js +3 -3
  356. package/dist/portal/pool/browser-pool.d.ts +70 -9
  357. package/dist/portal/pool/browser-pool.js +190 -37
  358. package/dist/portal/pool/context-permissions.d.ts +33 -0
  359. package/dist/portal/pool/context-permissions.js +33 -0
  360. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  361. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  362. package/dist/portal/pool/playwright-launcher.d.ts +35 -0
  363. package/dist/portal/pool/playwright-launcher.js +64 -3
  364. package/dist/portal/pool/pool-contract.d.ts +28 -5
  365. package/dist/portal/session/agent-link.d.ts +8 -0
  366. package/dist/portal/session/agent-link.js +17 -0
  367. package/dist/portal/session/command-payload.d.ts +8 -0
  368. package/dist/portal/session/command-payload.js +24 -0
  369. package/dist/portal/session/daemon-answers.d.ts +3 -3
  370. package/dist/portal/session/daemon-answers.js +4 -2
  371. package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
  372. package/dist/portal/session/dev-server/dev-command.js +87 -12
  373. package/dist/portal/session/facts/departure-note.d.ts +22 -0
  374. package/dist/portal/session/facts/departure-note.js +47 -0
  375. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  376. package/dist/portal/session/facts/observed-state.js +46 -3
  377. package/dist/portal/session/facts/session-replaced.d.ts +5 -0
  378. package/dist/portal/session/facts/session-replaced.js +5 -0
  379. package/dist/portal/session/first-run-wiring.d.ts +42 -0
  380. package/dist/portal/session/first-run-wiring.js +132 -0
  381. package/dist/portal/session/human/live-control.d.ts +9 -2
  382. package/dist/portal/session/human/live-control.js +12 -3
  383. package/dist/portal/session/human/notes-ledger.d.ts +20 -0
  384. package/dist/portal/session/human/notes-ledger.js +55 -0
  385. package/dist/portal/session/human/review-store.d.ts +12 -0
  386. package/dist/portal/session/human/review-store.js +18 -10
  387. package/dist/portal/session/live-control-tools.d.ts +0 -13
  388. package/dist/portal/session/live-control-tools.js +107 -13
  389. package/dist/portal/session/narration-args.d.ts +5 -0
  390. package/dist/portal/session/narration-args.js +17 -0
  391. package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
  392. package/dist/portal/session/no-session-diagnosis.js +46 -9
  393. package/dist/portal/session/no-session-next-action.d.ts +31 -0
  394. package/dist/portal/session/no-session-next-action.js +159 -60
  395. package/dist/portal/session/no-session-watch.d.ts +14 -1
  396. package/dist/portal/session/no-session-watch.js +227 -17
  397. package/dist/portal/session/presence/session-lease.js +1 -1
  398. package/dist/portal/session/presence/session-mirror.js +3 -0
  399. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  400. package/dist/portal/session/recorded-gaps.js +251 -0
  401. package/dist/portal/session/serving-directory.d.ts +27 -0
  402. package/dist/portal/session/serving-directory.js +45 -0
  403. package/dist/portal/session/session-health.d.ts +18 -0
  404. package/dist/portal/session/session-health.js +9 -1
  405. package/dist/portal/session/session-info.d.ts +8 -1
  406. package/dist/portal/session/session-info.js +8 -1
  407. package/dist/portal/session/session-manager.d.ts +39 -0
  408. package/dist/portal/session/session-manager.js +98 -11
  409. package/dist/portal/session/session-reaper.js +4 -1
  410. package/dist/portal/session/session-successor.d.ts +13 -0
  411. package/dist/portal/session/session-successor.js +1 -1
  412. package/dist/portal/session/session-tools.js +26 -3
  413. package/dist/portal/session/session.d.ts +22 -30
  414. package/dist/portal/session/session.js +81 -79
  415. package/dist/portal/session/timing/command-timeout.js +25 -1
  416. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  417. package/dist/portal/session/timing/wall-clock.js +1 -1
  418. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  419. package/dist/portal/session/zero-install-first-call.js +88 -0
  420. package/dist/start-options.d.ts +12 -0
  421. package/dist/start-wiring.d.ts +63 -0
  422. package/dist/start-wiring.js +169 -0
  423. package/dist/status-payload.d.ts +23 -1
  424. package/dist/status-payload.js +36 -1
  425. package/dist/surface/http-server.js +18 -2
  426. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  427. package/dist/surface/mcp/attach-memory.js +12 -1
  428. package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
  429. package/dist/surface/mcp/mcp-proxy.js +65 -13
  430. package/dist/surface/mcp/mcp.d.ts +34 -6
  431. package/dist/surface/mcp/mcp.js +61 -17
  432. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  433. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  434. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  435. package/dist/surface/mcp/server-instructions.d.ts +4 -2
  436. package/dist/surface/mcp/server-instructions.js +32 -14
  437. package/dist/surface/mcp/shared-params.js +2 -2
  438. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  439. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  440. package/dist/surface/tools/account-tool.d.ts +22 -0
  441. package/dist/surface/tools/account-tool.js +157 -0
  442. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  443. package/dist/surface/tools/act/act-danger.js +38 -1
  444. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  445. package/dist/surface/tools/act/act-observation.js +57 -0
  446. package/dist/surface/tools/act/act-preflight.js +25 -2
  447. package/dist/surface/tools/act/act-target.js +8 -3
  448. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
  449. package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
  450. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  451. package/dist/surface/tools/act/resolve-target.js +18 -3
  452. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  453. package/dist/surface/tools/act/screen-request.js +113 -0
  454. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  455. package/dist/surface/tools/act/sequence-grade.js +13 -2
  456. package/dist/surface/tools/act/settle-in-flight.js +25 -3
  457. package/dist/surface/tools/act-sequence-tool.js +138 -29
  458. package/dist/surface/tools/act-tools.d.ts +0 -9
  459. package/dist/surface/tools/act-tools.js +71 -41
  460. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  461. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  462. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  463. package/dist/surface/tools/agent/app-notes.js +48 -0
  464. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  465. package/dist/surface/tools/agent/build-staleness.js +62 -0
  466. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  467. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  468. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  469. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  470. package/dist/surface/tools/agent/notices.d.ts +50 -0
  471. package/dist/surface/tools/agent/notices.js +152 -0
  472. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  473. package/dist/surface/tools/agent/reteach.js +50 -0
  474. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  475. package/dist/surface/tools/args/alias-args.js +10 -0
  476. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  477. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  478. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  479. package/dist/surface/tools/assert/assert-source.js +40 -0
  480. package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
  481. package/dist/surface/tools/assert/assert-verdict.js +42 -17
  482. package/dist/surface/tools/browser-tools.js +51 -2
  483. package/dist/surface/tools/chat-drives.d.ts +101 -0
  484. package/dist/surface/tools/chat-drives.js +409 -0
  485. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  486. package/dist/surface/tools/coverage-tools.js +2 -53
  487. package/dist/surface/tools/dynamic-tools.js +29 -1
  488. package/dist/surface/tools/empty-session-list.d.ts +51 -0
  489. package/dist/surface/tools/empty-session-list.js +120 -0
  490. package/dist/surface/tools/error-recovery.d.ts +14 -0
  491. package/dist/surface/tools/error-recovery.js +105 -8
  492. package/dist/surface/tools/explore-tools.d.ts +31 -1
  493. package/dist/surface/tools/explore-tools.js +438 -66
  494. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  495. package/dist/surface/tools/feedback-tools.js +18 -3
  496. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  497. package/dist/surface/tools/gap-novelty.js +8 -1
  498. package/dist/surface/tools/harness-explore.d.ts +118 -57
  499. package/dist/surface/tools/harness-explore.js +344 -292
  500. package/dist/surface/tools/harness-gate.d.ts +88 -0
  501. package/dist/surface/tools/harness-gate.js +235 -0
  502. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  503. package/dist/surface/tools/harness-hunt.js +215 -0
  504. package/dist/surface/tools/harness-plan.d.ts +17 -0
  505. package/dist/surface/tools/harness-plan.js +38 -0
  506. package/dist/surface/tools/harness-script.d.ts +30 -0
  507. package/dist/surface/tools/harness-script.js +560 -0
  508. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  509. package/dist/surface/tools/harness-tab-guard.js +27 -0
  510. package/dist/surface/tools/harness-toolset.d.ts +22 -1
  511. package/dist/surface/tools/harness-toolset.js +101 -7
  512. package/dist/surface/tools/human-notes.d.ts +16 -0
  513. package/dist/surface/tools/human-notes.js +27 -0
  514. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  515. package/dist/surface/tools/invoke-tool.js +263 -85
  516. package/dist/surface/tools/lease-hint.js +26 -5
  517. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  518. package/dist/surface/tools/lease-permissions.js +73 -0
  519. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  520. package/dist/surface/tools/lease-readiness.js +57 -0
  521. package/dist/surface/tools/lease-seed.d.ts +49 -0
  522. package/dist/surface/tools/lease-seed.js +167 -0
  523. package/dist/surface/tools/lease-tools.d.ts +13 -24
  524. package/dist/surface/tools/lease-tools.js +146 -197
  525. package/dist/surface/tools/live-call-text.js +4 -4
  526. package/dist/surface/tools/merge-tools.js +42 -2
  527. package/dist/surface/tools/merged-name-redirect.js +4 -0
  528. package/dist/surface/tools/next-step.d.ts +29 -0
  529. package/dist/surface/tools/next-step.js +214 -0
  530. package/dist/surface/tools/observe-tools.js +45 -9
  531. package/dist/surface/tools/platform-moment.d.ts +72 -0
  532. package/dist/surface/tools/platform-moment.js +296 -0
  533. package/dist/surface/tools/query-hint-schema.d.ts +7 -0
  534. package/dist/surface/tools/query-hint-schema.js +10 -0
  535. package/dist/surface/tools/read-tools.js +71 -14
  536. package/dist/surface/tools/real-input-attempt.js +96 -13
  537. package/dist/surface/tools/reticle-result.d.ts +120 -0
  538. package/dist/surface/tools/reticle-result.js +364 -0
  539. package/dist/surface/tools/tool-kit.d.ts +83 -3
  540. package/dist/surface/tools/tool-kit.js +77 -7
  541. package/dist/surface/tools/tools.js +43 -59
  542. package/dist/telemetry/account-envelope.d.ts +7 -0
  543. package/dist/telemetry/account-envelope.js +61 -0
  544. package/dist/telemetry/agent-client.d.ts +15 -0
  545. package/dist/telemetry/agent-client.js +57 -0
  546. package/dist/telemetry/app-instrumented.js +9 -2
  547. package/dist/telemetry/argument-shape.d.ts +7 -0
  548. package/dist/telemetry/argument-shape.js +86 -1
  549. package/dist/telemetry/automation-hint.d.ts +2 -3
  550. package/dist/telemetry/automation-hint.js +33 -8
  551. package/dist/telemetry/cli-telemetry.js +7 -2
  552. package/dist/telemetry/daemon-telemetry.js +3 -0
  553. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  554. package/dist/telemetry/error-fingerprint.js +61 -5
  555. package/dist/telemetry/feedback-cli.d.ts +0 -13
  556. package/dist/telemetry/feedback-cli.js +0 -77
  557. package/dist/telemetry/feedback.d.ts +13 -0
  558. package/dist/telemetry/feedback.js +183 -17
  559. package/dist/telemetry/harness-run.d.ts +18 -0
  560. package/dist/telemetry/harness-run.js +80 -0
  561. package/dist/telemetry/hud-events.d.ts +16 -0
  562. package/dist/telemetry/hud-events.js +27 -0
  563. package/dist/telemetry/hud-metrics.d.ts +29 -6
  564. package/dist/telemetry/hud-metrics.js +116 -25
  565. package/dist/telemetry/init-telemetry.js +2 -2
  566. package/dist/telemetry/install-source.d.ts +13 -25
  567. package/dist/telemetry/install-source.js +44 -3
  568. package/dist/telemetry/mcp-connection.d.ts +0 -14
  569. package/dist/telemetry/mcp-connection.js +5 -1
  570. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  571. package/dist/telemetry/onboarding-firsts.js +81 -6
  572. package/dist/telemetry/platform-linked.d.ts +5 -0
  573. package/dist/telemetry/platform-linked.js +32 -0
  574. package/dist/telemetry/project-profile.js +5 -3
  575. package/dist/telemetry/proxy-telemetry.js +4 -1
  576. package/dist/telemetry/session-metrics.d.ts +15 -4
  577. package/dist/telemetry/session-metrics.js +88 -52
  578. package/dist/telemetry/telemetry.d.ts +38 -2
  579. package/dist/telemetry/telemetry.js +144 -34
  580. package/dist/telemetry/verification-of.d.ts +3 -1
  581. package/dist/telemetry/verification-of.js +13 -4
  582. package/dist/wire-journal.d.ts +2 -2
  583. package/dist/wire-journal.js +20 -6
  584. package/docs/README.md +3 -3
  585. package/docs/actions.mdx +6 -3
  586. package/docs/adapters.md +1 -1
  587. package/docs/agent-cheatsheet.md +25 -28
  588. package/docs/architecture.md +5 -5
  589. package/docs/autodrive.md +33 -28
  590. package/docs/benchmarks.md +5 -5
  591. package/docs/best-practices.mdx +27 -9
  592. package/docs/capabilities.mdx +14 -16
  593. package/docs/cli/affected.mdx +1 -1
  594. package/docs/cli/cloud.mdx +54 -75
  595. package/docs/cli/doctor.mdx +14 -3
  596. package/docs/cli/drive.mdx +20 -14
  597. package/docs/cli/feedback.mdx +3 -3
  598. package/docs/cli/gate.mdx +7 -2
  599. package/docs/cli/help.mdx +50 -55
  600. package/docs/cli/init.mdx +43 -28
  601. package/docs/cli/license.mdx +12 -8
  602. package/docs/cli/mcp.mdx +4 -4
  603. package/docs/cli/open.mdx +3 -3
  604. package/docs/cli/report.mdx +4 -2
  605. package/docs/cli/restart.mdx +2 -2
  606. package/docs/cli/rollback.mdx +14 -8
  607. package/docs/cli/serve.mdx +4 -4
  608. package/docs/cli/setup.mdx +23 -0
  609. package/docs/cli/status.mdx +18 -5
  610. package/docs/cli/stop.mdx +67 -8
  611. package/docs/cli/try.mdx +62 -0
  612. package/docs/cli/update.mdx +4 -3
  613. package/docs/cli/verify.mdx +17 -6
  614. package/docs/cli/version.mdx +5 -4
  615. package/docs/cli.mdx +111 -42
  616. package/docs/debugging.md +3 -3
  617. package/docs/deploy-checks.md +1 -1
  618. package/docs/desktop.mdx +9 -3
  619. package/docs/enterprise.md +11 -10
  620. package/docs/environment.mdx +7 -8
  621. package/docs/faq.mdx +3 -3
  622. package/docs/first-drive.md +5 -4
  623. package/docs/flows.md +35 -27
  624. package/docs/for-agents.md +4 -5
  625. package/docs/frameworks.mdx +32 -21
  626. package/docs/getting-started.md +65 -61
  627. package/docs/human-control.md +16 -16
  628. package/docs/index.mdx +15 -42
  629. package/docs/install-agentic.mdx +22 -37
  630. package/docs/install-manual.mdx +23 -13
  631. package/docs/instrumentation.mdx +5 -3
  632. package/docs/integration-patterns.md +7 -7
  633. package/docs/license-activation.mdx +1 -1
  634. package/docs/multi-agent-testing.md +24 -6
  635. package/docs/packages/babel-plugin.mdx +4 -2
  636. package/docs/packages/browser.mdx +16 -10
  637. package/docs/packages/core.mdx +12 -5
  638. package/docs/packages/electron.mdx +3 -2
  639. package/docs/packages/engine.mdx +1 -1
  640. package/docs/packages/eslint-plugin.mdx +18 -12
  641. package/docs/packages/next.mdx +8 -7
  642. package/docs/packages/open-verification.mdx +1 -1
  643. package/docs/packages/server.mdx +5 -5
  644. package/docs/packages/tauri.mdx +9 -9
  645. package/docs/packages/test.mdx +4 -10
  646. package/docs/packages/vite-plugin.mdx +32 -4
  647. package/docs/packages.mdx +11 -15
  648. package/docs/platform-integration.md +6 -5
  649. package/docs/predicates.mdx +40 -24
  650. package/docs/quickstart.mdx +69 -30
  651. package/docs/required-checks.md +8 -7
  652. package/docs/reticle-manual.md +15 -5
  653. package/docs/skill-file.mdx +17 -79
  654. package/docs/skill-setup.md +9 -9
  655. package/docs/skill.md +200 -0
  656. package/docs/system-map.md +7 -7
  657. package/docs/telemetry.md +23 -25
  658. package/docs/testing.md +4 -4
  659. package/docs/token-efficiency.md +12 -12
  660. package/docs/tools/act-and-wait.mdx +9 -2
  661. package/docs/tools/act-sequence.mdx +6 -7
  662. package/docs/tools/act.mdx +2 -2
  663. package/docs/tools/assert.mdx +18 -17
  664. package/docs/tools/console.mdx +9 -9
  665. package/docs/tools/inspect.mdx +16 -7
  666. package/docs/tools/look.mdx +24 -0
  667. package/docs/tools/navigate.mdx +5 -3
  668. package/docs/tools/network.mdx +2 -2
  669. package/docs/tools/observe.mdx +6 -6
  670. package/docs/tools/overview.mdx +34 -33
  671. package/docs/tools/query.mdx +5 -5
  672. package/docs/tools/session-and-feedback.mdx +22 -13
  673. package/docs/tools/sessions.mdx +8 -8
  674. package/docs/tools/snapshot.mdx +6 -5
  675. package/docs/tools/state.mdx +9 -9
  676. package/docs/tools/tools-and-run.mdx +26 -24
  677. package/docs/tools/verify.mdx +28 -0
  678. package/docs/tools/wait-for.mdx +8 -4
  679. package/docs/troubleshooting.mdx +21 -6
  680. package/docs/usage.md +55 -46
  681. package/docs/use-cases.mdx +3 -3
  682. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  683. package/docs/vs-playwright-mcp.mdx +3 -1
  684. package/docs/what-is-recorded.md +17 -5
  685. package/docs/what-is-reticle.mdx +5 -3
  686. package/docs/why-reticle.mdx +1 -1
  687. package/package.json +9 -12
  688. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  689. package/dist/command/cli/demo/demo-page.js +0 -241
  690. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  691. package/dist/command/cli/demo/demo-run.js +0 -138
  692. package/dist/features/harness/driver.d.ts +0 -50
  693. package/dist/features/harness/driver.js +0 -236
  694. package/dist/features/harness/jev-driver.d.ts +0 -188
  695. package/dist/features/harness/jev-driver.js +0 -678
  696. package/dist/features/harness/openai-driver.d.ts +0 -58
  697. package/dist/features/harness/openai-driver.js +0 -206
  698. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  699. package/dist/judgement/hunt/hunt-report.js +0 -84
  700. package/dist/language/flows/buddy-status.d.ts +0 -25
  701. package/dist/language/flows/buddy-status.js +0 -32
  702. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  703. package/dist/language/flows/change/watch-batcher.js +0 -19
  704. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  705. package/dist/memory/cloud/harness-offer.js +0 -145
  706. package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
  707. package/dist/memory/project/dir/fill-value-store.js +0 -88
  708. package/dist/surface/tools/feature-capture.d.ts +0 -151
  709. package/dist/surface/tools/feature-capture.js +0 -235
  710. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  711. package/dist/surface/tools/tool-hit-rate.js +0 -90
  712. package/dist/telemetry/harness-drive.d.ts +0 -4
  713. package/dist/telemetry/harness-drive.js +0 -35
  714. package/dist/telemetry/identify.d.ts +0 -22
  715. package/dist/telemetry/identify.js +0 -73
  716. package/docs/cli/capsules.mdx +0 -70
  717. package/docs/cli/hunt.mdx +0 -73
  718. package/docs/cli/identify.mdx +0 -76
  719. package/docs/cli/kill.mdx +0 -91
  720. package/docs/cli/watch.mdx +0 -62
  721. package/docs/local-registry.md +0 -143
@@ -1,6 +1,21 @@
1
+ import { takeCallSecrets, withCallSecrets } from './tool-kit.js';
1
2
  import { healthEnvelope } from '../../portal/session/session-health.js';
3
+ import { logToolCall, toolLogPath } from '../../hooks/tool-log.js';
4
+ import { nextStep } from './next-step.js';
5
+ import { currentDrivenBy } from '../../hooks/driven-by.js';
6
+ import { runAsAgent } from '../../hooks/coding-agents.js';
7
+ import { takeHumanNotes } from './human-notes.js';
8
+ import { takeDriveNotes } from '../../features/harness/drive-runs.js';
9
+ import { harnessDriving, msgHarnessHasTheTab } from './harness-tab-guard.js';
10
+ import { sessionRoot, sessionTarget } from '../../memory/project/session-root.js';
11
+ import { ArtifactRootReason } from '../../memory/project/artifact-root.js';
12
+ import { agentNudge, takePlatformMoment } from './platform-moment.js';
13
+ import { RESULT_FIELD, trackVerdict } from './reticle-result.js';
14
+ import { forTheAgent } from './agent/for-the-agent.js';
15
+ import { feedbackAlreadyAsked, noteFeedbackAsked } from './agent/notices.js';
16
+ import { SKEW_SHORT_WARNING, SKEW_VERDICT_WARNING } from '../../portal/session/session-health.js';
2
17
  import { verifyNextBaton, SUPPRESS_VERIFY_NEXT_ENV } from './verify-next-baton.js';
3
- import { TelemetryActor, TelemetryEventKind, TRANSPORT_LIMITS, fingerprintFinding, } from '@reticlehq/core';
18
+ import { TelemetryActor, TelemetryEventKind, THROTTLED_WARNING, TRANSPORT_LIMITS, fingerprintFinding, } from '@reticlehq/core';
4
19
  import { getSessionMetrics } from '../../telemetry/session-metrics.js';
5
20
  import { getTelemetry } from '../../telemetry/telemetry.js';
6
21
  import { takeUpdateNudge } from '../../command/update/update-nudge.js';
@@ -13,21 +28,19 @@ import { buildErrorPayload, refusalReasonFor } from './error-recovery.js';
13
28
  import { resultIsError } from '../mcp/faults/mcp-is-error.js';
14
29
  import { verificationOf } from '../../telemetry/verification-of.js';
15
30
  import { emitBugFoundHook, emitVerdictHook } from '../../hooks/hook-emit.js';
16
- import { reportOnboardingStep } from '../../telemetry/onboarding-funnel.js';
17
- import { noteActed, noteFirstVerdict, noteOnboardingFirst } from '../../telemetry/onboarding-firsts.js';
18
- import { withHarnessDrive } from '../../telemetry/harness-drive.js';
19
- import { OnboardingPhase, OnboardingStepStatus } from '@reticlehq/core/telemetry';
20
- import { DiscoveryInvite, asString } from '@reticlehq/core';
31
+ import { noteActed, noteFirstVerdict, noteOnboardingFirst, noteVerdictProduced, } from '../../telemetry/onboarding-firsts.js';
32
+ import { DiscoveryInvite } from '@reticlehq/core';
21
33
  import { SESSION_ID_ARG, sessionIdFromArgs, spentRefFromArgs } from './tools-helpers.js';
22
- import { EnvelopeKey } from './tool-kit.js';
34
+ import { EnvelopeKey, HOST_STUB_NOTE, STEP_SHOT_TOOLS } from './tool-kit.js';
23
35
  import { ReticleTool } from '@reticlehq/core';
24
36
  import { takeFeedbackPrompt } from './feedback-tools.js';
25
37
  import { takeFeedbackUndelivered } from '../../telemetry/feedback-delivery.js';
26
38
  import { noteRefsMinted, wrongTabRefusal } from '../../portal/session/facts/ref-provenance.js';
27
- import { CAPTURED_TOOLS, noteCapturedCall, noteToolDispatched, } from './feature-capture.js';
28
39
  import { span } from '../../trace.js';
40
+ import { takeStepShot } from '../../features/visual/step-shots.js';
29
41
  import { defectForToolResult, deltaForToolResult, impactSnapshot, initImpact, recordImpact, } from '../../memory/impact/impact-recorder.js';
30
- import { frictionOf, inviteFor } from './feedback-invite.js';
42
+ import { FrictionKind, frictionOf, inviteFor } from './feedback-invite.js';
43
+ import { VACUOUS_BECAUSE } from '@reticlehq/engine/evidence/verified.js';
31
44
  /**
32
45
  * The live-session tools whose result MUST carry the
33
46
  * session-health envelope. Owned in ONE place — not retrofitted per handler — so a throttled tab
@@ -153,17 +166,6 @@ export const SESSION_EXEMPT_TOOLS = new Set([
153
166
  // when NO session exists — "nothing ever connected" is feedback we especially want.
154
167
  ReticleTool.FEEDBACK,
155
168
  ]);
156
- /**
157
- * The merged action that hands the drive to a model inside the daemon.
158
- *
159
- * Derived from the member tool's own name rather than spelled again: the merge dispatches on
160
- * `action`, and `reticle_verify` plus `explore` IS `reticle_verify_explore`. A literal here would be
161
- * a third spelling of one name, and the one that silently stops matching when the action is renamed.
162
- */
163
- const HARNESS_DRIVE_ACTION = ReticleTool.VERIFY_EXPLORE.slice(`${ReticleTool.VERIFY}_`.length);
164
- function isHarnessDrive(toolName, args) {
165
- return ReticleTool.VERIFY === toolName && HARNESS_DRIVE_ACTION === args['action'];
166
- }
167
169
  function isPlainObject(value) {
168
170
  return 'object' === typeof value && value !== null && !Array.isArray(value);
169
171
  }
@@ -178,7 +180,7 @@ function isPlainObject(value) {
178
180
  * The RULE itself lives in verification-of.ts, because getting it wrong fails silently.
179
181
  */
180
182
  function recordVerification(toolName, result, durationMs, brand, sessionId) {
181
- const verification = verificationOf(toolName, result, durationMs, brand);
183
+ const verification = verificationOf(toolName, result, durationMs, brand, currentDrivenBy() !== undefined);
182
184
  if (verification === undefined)
183
185
  return;
184
186
  getSessionMetrics().recordVerification();
@@ -197,12 +199,8 @@ function recordVerification(toolName, result, durationMs, brand, sessionId) {
197
199
  emitVerdictHook(toolName, result, verification.verified, sessionId);
198
200
  // The ONBOARD half of the same moment: the first verdict of this run, once.
199
201
  noteFirstVerdict();
200
- void reportOnboardingStep({
201
- phase: OnboardingPhase.FIRST_RUN,
202
- step: 'verdict_produced',
203
- status: OnboardingStepStatus.COMPLETED,
204
- elapsedMs: Math.max(0, Math.round(durationMs)),
205
- });
202
+ // The FIRST_RUN rung: once per machine + project, not once per verdict.
203
+ noteVerdictProduced(durationMs);
206
204
  }
207
205
  /**
208
206
  * Emit one `bug_found` per defect in a tool result, and count it into the session.
@@ -226,9 +224,15 @@ function reportBugsFound(toolName, result, sessionId) {
226
224
  ? { kind: bug.kind, source: bug.source, route }
227
225
  : { kind: bug.kind, source: bug.source };
228
226
  const fingerprint = fingerprintFinding(identity);
227
+ const occurrence = metrics.recordBugOccurrence(fingerprint);
229
228
  void getTelemetry().emit(TelemetryEventKind.BUG_FOUND, {
230
229
  actor: TelemetryActor.AGENT,
231
- bug: { ...bug, repeat: !first, fingerprint },
230
+ bug: {
231
+ ...bug,
232
+ repeat: !first,
233
+ fingerprint,
234
+ ...(occurrence === undefined ? {} : { occurrence }),
235
+ },
232
236
  });
233
237
  // The same defect, said out loud to whoever is building on Reticle. Inside the loop rather than
234
238
  // after it because the event is PER DEFECT — one event carrying a list would make a consumer
@@ -273,7 +277,9 @@ function frictionInviteFor(toolName, raw) {
273
277
  return undefined;
274
278
  const friction = frictionOf({
275
279
  unknownTool: false,
276
- verifiedUnknown: 'unknown' === raw['verified'],
280
+ // A vacuous unknown is the caller's: it asserted nothing real (a bare `settled` wait, which the
281
+ // instructions recommend). Inviting a bug report there told agents Reticle had failed them.
282
+ verifiedUnknown: 'unknown' === raw['verified'] && VACUOUS_BECAUSE !== raw['because'],
277
283
  repeatRun: getSessionMetrics().currentRun,
278
284
  errored: resultIsError(raw),
279
285
  // A verdict is progress. Without this, three successful act_and_wait calls in a row — the exact
@@ -339,7 +345,62 @@ function pinnedArgs(args, explicitSessionId, session) {
339
345
  return args;
340
346
  return { ...args, [SESSION_ID_ARG]: session.id };
341
347
  }
342
- export async function runTool(tool, deps, args) {
348
+ export async function runTool(tool, deps, given, call) {
349
+ // A replay's secrets leave the arguments here, before the tool log, the journal or telemetry can
350
+ // see them, and are supplied to this call alone.
351
+ const { secrets, rest: args } = takeCallSecrets(given);
352
+ // A verdict still being decided is waited for by a session end (`trackVerdict`); the result is
353
+ // compacted for the agent last, after telemetry and the tool log have read the full result.
354
+ return trackVerdict(tool.name, withCallSecrets(secrets, async () => {
355
+ const result = await loggedTool(tool, deps, args, call);
356
+ const attach = currentDrivenBy() === undefined ? deps.attachId : undefined;
357
+ const root = attach === undefined
358
+ ? undefined
359
+ : safeRoot(() => sessionRoot(deps, sessionIdFromArgs(args)));
360
+ return forTheAgent({ name: tool.name, args, result, attach, root, fold: NOTICE_FOLD });
361
+ }));
362
+ }
363
+ /** Advisories that become once-per-session notice lines. See agent/notices.ts. */
364
+ export const NOTICE_FOLD = {
365
+ advisories: [
366
+ EnvelopeKey.FEEDBACK_PROMPT,
367
+ EnvelopeKey.FEEDBACK_INVITE,
368
+ EnvelopeKey.TALK_TO_US,
369
+ EnvelopeKey.UPDATE_AVAILABLE,
370
+ // NOT `version_skew`: it is decisive — it explains every result after it and names the command to
371
+ // run — so it rides out as its own key, untouched (one-shot at its source already).
372
+ EnvelopeKey.PLATFORM,
373
+ EnvelopeKey.SESSION_LEASE,
374
+ EnvelopeKey.SESSION_AGE_WARNING,
375
+ EnvelopeKey.FEEDBACK_UNDELIVERED,
376
+ EnvelopeKey.ZERO_INSTALL,
377
+ ],
378
+ notices: EnvelopeKey.NOTICES,
379
+ next: EnvelopeKey.NEXT,
380
+ warning: EnvelopeKey.WARNING,
381
+ onceWarnings: new Map([
382
+ // `session.throttled` still rides on every result: only the paragraph explaining it goes.
383
+ [THROTTLED_WARNING, undefined],
384
+ [SKEW_VERDICT_WARNING, SKEW_SHORT_WARNING],
385
+ ]),
386
+ };
387
+ async function loggedTool(tool, deps, args, call) {
388
+ const logPath = toolLogPath();
389
+ if (logPath === undefined)
390
+ return dispatchTool(tool, deps, args, call);
391
+ const at = deps.now();
392
+ try {
393
+ const result = await dispatchTool(tool, deps, args, call);
394
+ logToolCall(logPath, { tool: tool.name, args, at, ms: deps.now() - at, result });
395
+ return result;
396
+ }
397
+ catch (error) {
398
+ const message = error instanceof Error ? error.message : String(error);
399
+ logToolCall(logPath, { tool: tool.name, args, at, ms: deps.now() - at, error: message });
400
+ throw error;
401
+ }
402
+ }
403
+ async function dispatchTool(tool, deps, args, call) {
343
404
  // Both dispatch paths (MCP + programmatic) pass through here — the one place "which tool is mostly
344
405
  // used" can be counted. This used to EMIT an event per call; it now increments an in-process counter
345
406
  // that leaves once, with the session summary. A verification loop is 50–200 calls, and PostHog bills
@@ -378,6 +439,14 @@ export async function runTool(tool, deps, args) {
378
439
  reportRefusal(tool.name, error);
379
440
  return { error };
380
441
  }
442
+ // One driver per tab. The Harness clicking through a page while the agent clicks too is two hands
443
+ // on one mouse: neither result means anything. The agent's own action waits; its reads still run.
444
+ const busy = ACTION_TOOLS.has(tool.name) ? harnessDriving(deps, args) : undefined;
445
+ if (busy !== undefined) {
446
+ const error = msgHarnessHasTheTab(busy);
447
+ reportRefusal(tool.name, error);
448
+ return { error };
449
+ }
381
450
  // An ACTION is what gets abandoned. Counted here, against verifications, so "the agent drove the
382
451
  // page and then wandered off" becomes a number instead of an impression.
383
452
  if (ACTION_TOOLS.has(tool.name)) {
@@ -402,6 +471,24 @@ export async function runTool(tool, deps, args) {
402
471
  session = undefined;
403
472
  }
404
473
  }
474
+ // Nothing connected, and the app was never wired: a call that needs a page opens it zero-install
475
+ // rather than answering with a diagnosis the agent stops at. See zero-install-first-call.ts.
476
+ const openUnwired = deps.openUnwiredApp;
477
+ const opened = openUnwired !== undefined &&
478
+ session === undefined &&
479
+ bound &&
480
+ rawSessionId === undefined &&
481
+ 0 === deps.sessions.list().length
482
+ ? await openUnwired()
483
+ : undefined;
484
+ if (opened !== undefined) {
485
+ try {
486
+ session = deps.sessions.resolve(rawSessionId);
487
+ }
488
+ catch {
489
+ session = undefined;
490
+ }
491
+ }
405
492
  // CDP tools against a skewed session: refuse with the sentence reticle_sessions already knows,
406
493
  // before Playwright invents a closed page. ready:true leases still hit this path.
407
494
  if (session?.versionSkew !== undefined && CDP_TOOLS.has(tool.name)) {
@@ -409,43 +496,6 @@ export async function runTool(tool, deps, args) {
409
496
  reportRefusal(tool.name, message);
410
497
  throw new Error(message);
411
498
  }
412
- // The read-only calls the journal never keeps, recorded HERE because this is the one dispatch
413
- // point every call routes through — a second recording site is a second thing to forget, and this
414
- // instrument exists precisely because nothing was recorded before. Recorded before the handler
415
- // runs: a read dispatches no action, so the counter reads the same either side.
416
- //
417
- // `reticle_context` is session-EXEMPT, so `session` above is undefined for it and it needs its own
418
- // lenient resolve. Failing that resolve is silent by design: a call made with nothing connected
419
- // has no per-session ledger to land in, and an instrument must never be why a tool call fails.
420
- //
421
- // EVERY tool is counted here, not just the read set: which of the 70-odd names in the table an
422
- // agent actually reaches for is the question a decision about cutting or consolidating the surface
423
- // turns on, and it had no answer. `reticle_run` is the one exclusion, for the same reason
424
- // `reportRefusal` and `bugsInResult` exclude it — its handler calls `runTool` on the real tool, so
425
- // the inner call is already counted under the name that RAN, and counting the wrapper too would
426
- // both double the total and hide the run-only tier behind a single wrapper name. That tier is
427
- // precisely the one the decision hinges on. See surface/tools/tool-hit-rate.ts.
428
- if (ReticleTool.RUN !== tool.name) {
429
- let target = session;
430
- if (target === undefined) {
431
- try {
432
- target = deps.sessions.resolve(rawSessionId);
433
- }
434
- catch {
435
- target = undefined;
436
- }
437
- }
438
- if (target !== undefined) {
439
- noteToolDispatched(target, tool.name);
440
- if (CAPTURED_TOOLS.has(tool.name)) {
441
- const subject = asString(args['ref']) ?? asString(args['target']);
442
- noteCapturedCall(target, {
443
- tool: tool.name,
444
- ...(subject === undefined ? {} : { subject }),
445
- });
446
- }
447
- }
448
- }
449
499
  // A ref that was handed out by a DIFFERENT tab, on a call that named no session. Refused here, at
450
500
  // the one point that knows both the ref and the tab resolution picked — the handler only learns
451
501
  // that the ref missed, and answers that with "the DOM re-rendered", which is a confident diagnosis
@@ -479,16 +529,11 @@ export async function runTool(tool, deps, args) {
479
529
  // `dispatchArgs`, not `args`: an inferred session is pinned into the arguments before the
480
530
  // handler sees them, so a tool that resolves the session a second time cannot land on a
481
531
  // different one than the dispatcher chose.
482
- const call = () => span('tool.handler', { tool: tool.name, session: session?.id }, () => tool.handler(deps, dispatchArgs));
483
- // A drive we run on the user's behalf, marked for its whole span so the verdicts it produces
484
- // underneath are distinguishable from the ones the user's own agent earned.
485
- //
486
- // The outer call emits no verdict of its own, and that is the honest answer rather than a gap:
487
- // it drives and records, it adjudicates nothing, and its result carries no verified/pass field
488
- // to read. Deriving one from how far the drive got would be inventing a verdict nobody reached.
489
- // What was missing was never an event here — it was that a session driven BY US read exactly
490
- // like one the agent earned, which is what the span fixes.
491
- raw = await (isHarnessDrive(tool.name, args) ? withHarnessDrive(call) : call());
532
+ const invokeHandler = () => span('tool.handler', { tool: tool.name, session: session?.id }, () => tool.handler(deps, dispatchArgs, call));
533
+ // The Harness's own inner calls carry their drive in an async context (`runDrivenBy`), which is
534
+ // what attributes their verdicts; the outer explore call adjudicates nothing of its own.
535
+ // As the agent on this connection, so a note it reads is marked seen by that agent.
536
+ raw = await runAsAgent(deps.attachId, invokeHandler);
492
537
  }
493
538
  catch (error) {
494
539
  // The commonest refusal shape by far, and the one nothing could see: the message is built, handed
@@ -526,6 +571,7 @@ export async function runTool(tool, deps, args) {
526
571
  // concurrency slot and peakConcurrentTools would climb forever on an unhealthy session.
527
572
  settleTiming(Date.now() - startedAt);
528
573
  }
574
+ raw = await withStepShot(tool.name, deps, args, raw, session?.id ?? rawSessionId);
529
575
  // Milestones describe work that ran. Refusals and paused calls must not consume the firsts.
530
576
  // Record action before verdict: act_and_wait can complete both in this same call.
531
577
  if (isPlainObject(raw) && !resultIsError(raw) && raw['paused'] !== true && raw['ok'] !== false) {
@@ -579,7 +625,10 @@ export async function runTool(tool, deps, args) {
579
625
  if (session !== undefined && REF_MINTING_TOOLS.has(tool.name))
580
626
  noteRefsMinted(session.id);
581
627
  }
582
- const prompt = isPlainObject(raw) ? takeFeedbackPrompt(tool.name) : undefined;
628
+ // The feedback family is asked at most once per agent session (agent/notices.ts): gated here, at
629
+ // the take, so a suppressed ask is never counted as one that was made.
630
+ const asked = feedbackAlreadyAsked(currentDrivenBy() === undefined ? deps.attachId : undefined);
631
+ const prompt = isPlainObject(raw) && !asked ? takeFeedbackPrompt(tool.name) : undefined;
583
632
  // Same one-shot channel as the feedback ask: the agent is mid-task, so anything it would have to go
584
633
  // and ASK for is something it will never ask for. Spliced on ANY tool result, not just a
585
634
  // verification, because an out-of-date install is worth mentioning whatever the agent is doing.
@@ -604,25 +653,85 @@ export async function runTool(tool, deps, args) {
604
653
  // `refused` friction the line is written for. `errored` could only ever see the handlers that
605
654
  // RETURN an error. So the denominator was counting a small, unrepresentative slice of the
606
655
  // invitations and reading near-empty, which looks identical to a nudge that never fires.
607
- const friction = frictionInviteFor(tool.name, raw);
608
- const result = prompt === undefined &&
656
+ const friction = asked || prompt !== undefined ? undefined : frictionInviteFor(tool.name, raw);
657
+ if (prompt !== undefined || friction !== undefined)
658
+ noteFeedbackAsked(currentDrivenBy() === undefined ? deps.attachId : undefined);
659
+ // Once per project, on a proved verdict, when the runs live only on this machine. Not on a result
660
+ // whose `reticleResult` already ends with the platform line: once per result, never twice.
661
+ const platform = isPlainObject(raw) && !(RESULT_FIELD in raw)
662
+ ? await takePlatformMoment(deps, raw, () => sessionRoot(deps, rawSessionId))
663
+ : undefined;
664
+ // What the agent should do next, on every client that reads results. Not for the Harness, whose
665
+ // runs the daemon syncs itself and which cannot relay the user's words, and not on `reticle_run`'s
666
+ // outer result: the inner call already carried one.
667
+ const next = isPlainObject(raw) && ReticleTool.RUN !== tool.name && currentDrivenBy() === undefined
668
+ ? nextStep({
669
+ tool: tool.name,
670
+ unmatched: unmatchedRootOf(deps, rawSessionId),
671
+ verdict: 'verified' in raw,
672
+ root: safeRoot(() => sessionRoot(deps, rawSessionId)),
673
+ // A partial deps (tests, the demo) may carry no clock; the line is advice, never a reason to fail.
674
+ now: 'function' === typeof deps.now ? deps.now() : Date.now(),
675
+ })
676
+ : undefined;
677
+ // Only an agent's own call (an MCP connection, not the Harness, not the HUD's or the chat's calls
678
+ // into the same tools) takes what is waiting for the agent: those calls answer nobody who reads.
679
+ const answer = isPlainObject(raw) ? raw : undefined;
680
+ const agentCall = answer !== undefined && deps.attachId !== undefined && currentDrivenBy() === undefined;
681
+ // A Harness drive started or finished, from the HUD, the platform's chat or this agent: one line,
682
+ // once. Not about the run this very result already reports.
683
+ // One-time advisories toward the platform and the Harness (`platform-moment.ts`), only on the agent's
684
+ // own calls, riding the same platform line as the moments above.
685
+ const nudge = agentCall && answer !== undefined
686
+ ? await agentNudge({
687
+ deps,
688
+ tool: tool.name,
689
+ raw: answer,
690
+ isError: resultIsError(answer),
691
+ tab: session,
692
+ root: safeRoot(() => sessionRoot(deps, rawSessionId)),
693
+ harnessOn: () => impactSnapshot(artifactRoot)?.harnessConfig?.harnessEnabled,
694
+ })
695
+ : undefined;
696
+ const platformLine = platform === undefined ? nudge : nudge === undefined ? platform : `${platform}\n${nudge}`;
697
+ const drives = agentCall
698
+ ? takeDriveNotes('string' === typeof answer?.['runId'] ? answer['runId'] : undefined)
699
+ : [];
700
+ // The person's notes from the HUD, on ANY tool. Act tools splice their own `control` first.
701
+ const notes = agentCall && answer !== undefined && !(EnvelopeKey.CONTROL in answer)
702
+ ? await runAsAgent(deps.attachId, () => Promise.resolve(takeHumanNotes(deps.sessions, rawSessionId, session)))
703
+ : undefined;
704
+ const result = 0 === drives.length &&
705
+ notes === undefined &&
706
+ prompt === undefined &&
609
707
  update === undefined &&
610
708
  skew === undefined &&
611
709
  undelivered === undefined &&
612
- friction === undefined
710
+ friction === undefined &&
711
+ platformLine === undefined &&
712
+ next === undefined
613
713
  ? raw
614
714
  : {
715
+ // First, so a model that truncates a long result still reads it.
716
+ ...(next !== undefined ? { [EnvelopeKey.NEXT]: next } : {}),
615
717
  ...raw,
616
718
  ...(friction !== undefined
617
719
  ? {
618
720
  [EnvelopeKey.FEEDBACK_INVITE]: inviteFor(friction),
619
- // The moment Reticle got in somebody's way is the moment to offer them the founder.
620
- [EnvelopeKey.TALK_TO_US]: DiscoveryInvite.AGENT,
721
+ // The founder's calendar only for an agent genuinely STUCK (the same call, again,
722
+ // with no progress). An ordinary refusal carried it too, and read as a sales pitch
723
+ // stapled to an error message.
724
+ ...(FrictionKind.REPEATING === friction
725
+ ? { [EnvelopeKey.TALK_TO_US]: DiscoveryInvite.AGENT }
726
+ : {}),
621
727
  }
622
728
  : {}),
623
729
  ...(prompt !== undefined ? { [EnvelopeKey.FEEDBACK_PROMPT]: prompt } : {}),
624
730
  ...(update !== undefined ? { [EnvelopeKey.UPDATE_AVAILABLE]: update } : {}),
625
731
  ...(skew !== undefined ? { [EnvelopeKey.VERSION_SKEW]: skew } : {}),
732
+ ...(platformLine !== undefined ? { [EnvelopeKey.PLATFORM]: platformLine } : {}),
733
+ ...(0 === drives.length ? {} : { [EnvelopeKey.HARNESS]: drives.join('\n') }),
734
+ ...(notes === undefined ? {} : { [EnvelopeKey.CONTROL]: notes }),
626
735
  ...(undelivered !== undefined
627
736
  ? {
628
737
  [EnvelopeKey.FEEDBACK_UNDELIVERED]: `your earlier report did NOT send: ${undelivered}. Tell the human what you found so it is not lost.`,
@@ -633,7 +742,15 @@ export async function runTool(tool, deps, args) {
633
742
  return result;
634
743
  // Reuse the session resolved above so the health envelope describes the SAME session the handler
635
744
  // drove; only re-resolve if the up-front attempt failed but the handler somehow succeeded.
636
- const driven = session ?? deps.sessions.resolve(rawSessionId);
745
+ // A handler that answered with no tab to resolve (a Harness drive polled by runId after a daemon
746
+ // restart reads its record from disk) keeps its answer: there is no session health to describe.
747
+ let driven = session;
748
+ try {
749
+ driven ??= deps.sessions.resolve(rawSessionId);
750
+ }
751
+ catch {
752
+ return result;
753
+ }
637
754
  // ...unless the call replaced that document. A full navigation or reload registers a NEW Session
638
755
  // under the same id (or under the id the result reports it arrived at), and the object resolved
639
756
  // before the call is the page that unloaded: it reported itself hidden on the way out, so every
@@ -642,6 +759,14 @@ export async function runTool(tool, deps, args) {
642
759
  const arrivedId = 'string' === typeof result['sessionId'] ? result['sessionId'] : driven.id;
643
760
  const resolved = deps.sessions.get?.(arrivedId) ?? driven;
644
761
  const envelope = {};
762
+ // A leased tab opened with `initScript` runs a STUB of the bindings a desktop shell injects. Said
763
+ // on every session-bound result, not only on verdicts, for the same reason health is: a green from
764
+ // that tab proves the app's view logic, and nothing else in the result would say so.
765
+ // Optional-called: a partial pool in a test double has no lookup, and absence must read as "no
766
+ // stub", never as a crash on the whole tool surface.
767
+ if (true === deps.pool?.stubInstalled?.(resolved.id)) {
768
+ envelope[EnvelopeKey.HOST_STUB] = HOST_STUB_NOTE;
769
+ }
645
770
  // The health block is idempotent: add it only when the handler didn't already include a `session`.
646
771
  if (!('session' in result))
647
772
  Object.assign(envelope, healthEnvelope(resolved));
@@ -650,8 +775,13 @@ export async function runTool(tool, deps, args) {
650
775
  // does) — so a long-running backgrounded session, the case most likely to leak, never got the
651
776
  // one-time pool-lease reminder or the age cleanup nudge. Splice them regardless.
652
777
  const lease = resolved.takeSessionLease();
653
- if (lease !== undefined)
778
+ // In CI there is no panel and no human to hand it back to: the reminder was noise in every
779
+ // pipeline log. Still taken, so the once-per-session cadence is unchanged.
780
+ if (lease !== undefined && process.env['CI'] === undefined) {
654
781
  envelope[EnvelopeKey.SESSION_LEASE] = lease;
782
+ }
783
+ if (opened !== undefined)
784
+ envelope[EnvelopeKey.ZERO_INSTALL] = opened.notice;
655
785
  const warning = resolved.ageWarning();
656
786
  if (warning !== undefined)
657
787
  envelope[EnvelopeKey.SESSION_AGE_WARNING] = warning;
@@ -683,3 +813,51 @@ export async function runTool(tool, deps, args) {
683
813
  envelope[EnvelopeKey.VERIFY_NEXT] = verifyNextBaton(unverified, resolved.lastAct?.effect() ?? {});
684
814
  return Object.keys(envelope).length > 0 ? { ...result, ...envelope } : result;
685
815
  }
816
+ /**
817
+ * A picture of the page the moment this call's outcome was decided, named on the result. Only on
818
+ * an answer that touched the page: a refusal or a paused call drove nothing worth a picture. A
819
+ * navigation can land the page under a new id, so the id the result reports wins.
820
+ */
821
+ async function withStepShot(name, deps, args, raw, sessionId) {
822
+ if (!STEP_SHOT_TOOLS.has(name) || Array.isArray(args['steps']))
823
+ return raw;
824
+ if (!isPlainObject(raw) || resultIsError(raw) || true === raw['paused'])
825
+ return raw;
826
+ const tab = 'string' === typeof raw['sessionId'] ? raw['sessionId'] : sessionId;
827
+ if (tab === undefined)
828
+ return raw;
829
+ // Paired with its check when the run is written: the n-th verdict picture is the n-th check.
830
+ const verdict = 'verified' in raw && (ReticleTool.ACT_AND_WAIT === name || ReticleTool.ASSERT === name);
831
+ return { ...raw, [EnvelopeKey.SCREENSHOT]: await takeStepShot(deps, tab, name, { verdict }) };
832
+ }
833
+ /** A root, or undefined when none can be resolved: a missing root is never a reason to throw. */
834
+ function safeRoot(get) {
835
+ try {
836
+ return get();
837
+ }
838
+ catch {
839
+ return undefined;
840
+ }
841
+ }
842
+ /**
843
+ * Where this session's evidence goes when no project claims it (`~/.reticle/unmatched/<id>`), with
844
+ * the folders that compete for its id; undefined when it lands in a project. Never throws.
845
+ */
846
+ function unmatchedRootOf(deps, sessionId) {
847
+ try {
848
+ const target = sessionTarget(deps, sessionId);
849
+ const resolved = deps.artifactRootFor?.(target.projectId, target.origin);
850
+ if (resolved === undefined || ArtifactRootReason.MATCHED_PROJECT === resolved.reason)
851
+ return undefined;
852
+ if (resolved.root === deps.reticleRoot)
853
+ return undefined;
854
+ return {
855
+ root: resolved.root,
856
+ contenders: resolved.candidates ?? [],
857
+ ...(resolved.serving === undefined ? {} : { serving: resolved.serving }),
858
+ };
859
+ }
860
+ catch {
861
+ return undefined;
862
+ }
863
+ }
@@ -17,6 +17,7 @@
17
17
  * So: rank by what the daemon actually knows, and fall back to the differential only when it knows
18
18
  * nothing. A cause we hold positive evidence against is not printed at all.
19
19
  */
20
+ import { isLoopbackHostname } from '@reticlehq/core';
20
21
  const NUXT = 'nuxt';
21
22
  const PORT_DIFFERENTIAL = "The usual cause is a PORT MISMATCH: the app's SDK connects to the port it was BUILT with, so a " +
22
23
  "daemon on a different port never hears from it — check the app's reticle port (`.reticle.json`, " +
@@ -36,6 +37,17 @@ const NUXT_FIRST = 'This project is Nuxt: the most likely cause by a distance is
36
37
  'Reticle plugin, because Nuxt does NOT register a newly added plugin on HMR. Restart `nuxt dev` ' +
37
38
  'and re-acquire before investigating anything else.';
38
39
  const RELEASE = 'The tab stays leased either way — release it with reticle_lease{action:"release"}.';
40
+ const PRODUCTION_STUB = ' If this is a production build (`vite build`, `next build`, `next start`, or a deployed site), it strips ' +
41
+ 'Reticle or replaces it with an inert stub by design; point the lease at the dev server instead.';
42
+ function isRemoteUrl(url) {
43
+ try {
44
+ const hostname = new URL(url).hostname.toLowerCase();
45
+ return !isLoopbackHostname(hostname);
46
+ }
47
+ catch {
48
+ return false;
49
+ }
50
+ }
39
51
  function markerClause(sdkMarker) {
40
52
  if (sdkMarker === undefined)
41
53
  return '';
@@ -82,8 +94,8 @@ export function leaseNotConnectedHint(url, port, evidence = {}) {
82
94
  `this daemon is on ${String(port)}, so the dial never reached it. Nothing about the app's ` +
83
95
  `wiring is in question. Either start the daemon on ${String(dialled)}, or point the app at ` +
84
96
  `${String(port)} — the app's port comes from its build config (\`.reticle.json\`, ` +
85
- `RETICLE_PORT, or the build plugin's \`port\`), and \`VITE_RETICLE_WS_URL\` overrides it ` +
86
- `outright.${marker} ${RELEASE}`);
97
+ `RETICLE_PORT, or the build plugin's \`port\`), and \`reticle.connect({ url })\` ` +
98
+ `overrides it outright.${marker} ${RELEASE}`);
87
99
  }
88
100
  // 0b. The page's own policy forbids the connection. Read off the document it served, so it is
89
101
  // proof about the page in hand, and it holds whether or not the app ships an SDK: neither
@@ -118,18 +130,27 @@ export function leaseNotConnectedHint(url, port, evidence = {}) {
118
130
  : ' That may have been a DIFFERENT app, though: this one may carry no Reticle SDK at all, ' +
119
131
  'in which case run `reticle init` in ITS directory first — every cause below assumes the ' +
120
132
  'SDK is already installed.';
133
+ // Never beside a marker that WAS found: "it ships the SDK" and "the build stripped it" cannot
134
+ // both be the story.
135
+ const production = true !== evidence.sdkMarker && (false === evidence.sdkMarker || isRemoteUrl(url))
136
+ ? PRODUCTION_STUB
137
+ : '';
121
138
  return (`${opening} An app for this project HAS connected on this port before, so the port is ` +
122
- `proven.${notThisApp}${nuxt}${marker} ${REAL_CAUSES} ${RELEASE}`);
139
+ `proven.${notThisApp}${nuxt}${marker}${production} ${REAL_CAUSES} ${RELEASE}`);
123
140
  }
124
141
  // 4. Wired, but never seen connect. Rank the real causes; keep the port differential last, where
125
142
  // the evidence for it actually sits.
126
143
  if (true === evidence.initialized) {
127
- return `${opening}${nuxt}${marker} ${REAL_CAUSES} If none of those, it may be dialling a different daemon than this one: check the app's reticle port matches ${String(port)}. ${RELEASE}`;
144
+ const production = false === evidence.sdkMarker ? PRODUCTION_STUB : '';
145
+ return `${opening}${nuxt}${marker}${production} ${REAL_CAUSES} If none of those, it may be dialling a different daemon than this one: check the app's reticle port matches ${String(port)}. ${RELEASE}`;
128
146
  }
129
147
  // 5. Nothing known. The differential, plus the possibility this app carries no SDK at all —
130
148
  // except when the marker check already ruled that out, which is the whole reason for the bit.
149
+ // Nothing says the project was ever wired, so `reticle init` stays the advice whenever the SDK
150
+ // was not seen; a production build is the other way to serve a page without it.
131
151
  const noSdk = true === evidence.sdkMarker
132
152
  ? ''
133
- : ' If the app carries no Reticle SDK at all, run `reticle init` in it first.';
153
+ : ' If the app carries no Reticle SDK at all, run `reticle init` in it first.' +
154
+ (false === evidence.sdkMarker || isRemoteUrl(url) ? PRODUCTION_STUB : '');
134
155
  return `${opening}${nuxt}${marker} ${PORT_DIFFERENTIAL}${noSdk} ${REAL_CAUSES} ${RELEASE}`;
135
156
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The `permissions` argument of `reticle_lease { action: "acquire" }` (#1370).
3
+ *
4
+ * Granted before the first navigation of a fresh lease. On an origin that already has a live lease,
5
+ * acquire hands back THAT lease rather than opening a second tab, and it may be another agent's tab
6
+ * mid-flow — nothing at this layer knows whose it is. So its grants never change there: the same list
7
+ * is a plain reuse, a different one is refused with the way out (release, then acquire again).
8
+ */
9
+ import { z } from 'zod';
10
+ import type { BrowserPool } from '../../portal/pool/browser-pool.js';
11
+ export declare const LEASE_PERMISSIONS_ARG: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
12
+ type PermissionPool = Pick<BrowserPool, 'notificationPermission'>;
13
+ /** The validated list, undefined when the caller passed none, or a refusal naming the right shape. */
14
+ export declare function parseLeasePermissions(raw: unknown): readonly string[] | undefined;
15
+ /** A permission failure, reworded for the agent; undefined for every other error. */
16
+ export declare function permissionRefusal(err: unknown): Error | undefined;
17
+ /**
18
+ * What to tell the agent when the page cannot see a notifications grant, else undefined.
19
+ *
20
+ * Undefined too when the page could not be asked: the grant was made, and a reading nobody took is
21
+ * not evidence that it failed.
22
+ */
23
+ export declare function notificationReadBack(pool: PermissionPool, sessionId: string, permissions: readonly string[] | undefined): Promise<string | undefined>;
24
+ /**
25
+ * Refuse to reuse a held lease under a different set of grants. Nothing to refuse when the caller
26
+ * named no list, or the same one in any order.
27
+ */
28
+ export declare function refuseRegrant(pool: Pick<BrowserPool, 'permissionsOf'>, sessionId: string, permissions: readonly string[] | undefined): void;
29
+ /** `{ hint }` joining whichever parts are present, or nothing at all. */
30
+ export declare function hintOf(...parts: (string | undefined)[]): {
31
+ hint?: string;
32
+ };
33
+ export {};