@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
@@ -4,6 +4,7 @@
4
4
  * in its own leaf module (no dependency on any tool array) so the per-group tool files can import it
5
5
  * without a circular import — `tools.ts` assembles the groups and re-exports `ToolDef`/`ToolDeps`.
6
6
  */
7
+ import type { FirstRunWiring } from '../../portal/session/first-run-wiring.js';
7
8
  import { z } from 'zod';
8
9
  import { type ProjectId, ReticleCommand } from '@reticlehq/core';
9
10
  import type { SessionManager } from '../../portal/session/session-manager.js';
@@ -43,8 +44,9 @@ export interface ToolDeps<Ext = unknown> {
43
44
  * to: this is a port, and the daemon already resolves exactly this for cloud sync.
44
45
  *
45
46
  * Absent ⇒ nothing is linked, or the caller is an embedder with no filesystem. Never an error.
47
+ * `root` is the `.reticle` whose link is asked for; absent, the daemon's own.
46
48
  */
47
- linkedCloud?: () => Promise<{
49
+ linkedCloud?: (root?: string) => Promise<{
48
50
  url: string;
49
51
  apiKey: string;
50
52
  } | null>;
@@ -69,6 +71,23 @@ export interface ToolDeps<Ext = unknown> {
69
71
  peerSkew?: {
70
72
  take(): string | undefined;
71
73
  };
74
+ /**
75
+ * Who is asking: one id per MCP attach. A browser lease is handed back only to the attach that took
76
+ * it, so two agents on one origin never share a tab (#1226). Absent ⇒ every acquire gets its own.
77
+ */
78
+ attachId?: string;
79
+ /** Run one sync cycle with the platform now, for `reticle_project { push }`. Absent: not linked here. */
80
+ syncNow?: () => Promise<unknown>;
81
+ /** Wires the app on the agent's first use, instead of at installation. Absent: tell, do not wire. */
82
+ firstRun?: FirstRunWiring;
83
+ /**
84
+ * On the first page-needing call with nothing connected, opens this caller's UNWIRED app in a
85
+ * lease that supplies the SDK (see zero-install-first-call.ts). Absent: answer no-session as before.
86
+ */
87
+ openUnwiredApp?: () => Promise<{
88
+ url: string;
89
+ notice: string;
90
+ } | undefined>;
72
91
  /** cross-run outcome memory (.reticle/project.json). */
73
92
  project: ProjectStore;
74
93
  /** optional native-input provider. undefined ⇒ everything stays synthetic. */
@@ -90,7 +109,7 @@ export interface ToolDeps<Ext = unknown> {
90
109
  * embedding this engine may not have a filesystem to search. Absent ⇒ `reticleRoot`, which is
91
110
  * exactly today's behaviour.
92
111
  */
93
- artifactRootFor?: (projectId: ProjectId | undefined) => ArtifactRoot;
112
+ artifactRootFor?: (projectId: ProjectId | undefined, origin?: string) => ArtifactRoot;
94
113
  /**
95
114
  * A verification run just landed — wake cloud sync instead of waiting for its next tick.
96
115
  *
@@ -175,7 +194,17 @@ export interface ToolDef<Ext = unknown> {
175
194
  * handed a bag carrying no `ext` at all. That costs nothing here, because `ext` is optional by
176
195
  * design: any handler reading it already has to survive `undefined`.
177
196
  */
178
- handler(deps: ToolDeps<Ext>, args: Record<string, unknown>): Promise<unknown>;
197
+ handler(deps: ToolDeps<Ext>, args: Record<string, unknown>, call?: ToolCall): Promise<unknown>;
198
+ }
199
+ /**
200
+ * What the MCP request itself offers a handler: its cancellation, and a way to say it is still
201
+ * working. Absent off the MCP path (the Harness's own calls, the CLI, tests).
202
+ */
203
+ export interface ToolCall {
204
+ /** Aborts when the client cancels or the connection drops. */
205
+ signal?: AbortSignal;
206
+ /** Present when the client asked for progress: tells it the call is alive, and how far along. */
207
+ progress?: (progress: number, message: string) => void;
179
208
  }
180
209
  /**
181
210
  * The optional inline intent, on every tool that draws a verdict.
@@ -241,8 +270,45 @@ export declare const EnvelopeKey: {
241
270
  readonly VERSION_SKEW: "version_skew";
242
271
  /** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
243
272
  readonly FEEDBACK_UNDELIVERED: "feedback_undelivered";
273
+ /** Once per project: verified runs exist only on this machine. See platform-moment.ts. */
274
+ readonly PLATFORM: "platform";
275
+ /**
276
+ * This leased tab runs a STUB of the bindings a desktop shell injects (`reticle_lease acquire`'s
277
+ * `initScript`), so a verdict here is about the app's view logic and not about the real shell.
278
+ */
279
+ readonly HOST_STUB: "host_stub";
280
+ /** The one thing to do next: declare the request, yield, fix sync, connect. See next-step.ts. */
281
+ readonly NEXT: "next";
282
+ /** One-shot: a Harness drive started or finished, from any origin, and how to read it. */
283
+ readonly HARNESS: "harness";
284
+ /** Where this step's screenshot is (`{ path, source }`), or why there is none. See step-shots.ts. */
285
+ readonly SCREENSHOT: "screenshot";
286
+ /**
287
+ * One-shot: this call's tab was opened by Reticle on an app nobody wired, with the SDK supplied —
288
+ * what it cannot see, and the command that wires the app for good. See zero-install-first-call.ts.
289
+ */
290
+ readonly ZERO_INSTALL: "zero_install";
291
+ /** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
292
+ readonly NOTICES: "notices";
244
293
  };
245
294
  export type EnvelopeKey = (typeof EnvelopeKey)[keyof typeof EnvelopeKey];
295
+ /**
296
+ * The sentence every session-bound result carries while its leased tab runs on a stubbed shell.
297
+ *
298
+ * Spliced wherever the tab's health is spliced, because the fact matters to exactly the same
299
+ * readings: a green from a tab whose `window.go` Reticle faked is not evidence about the real shell,
300
+ * and nothing else in the result would say so.
301
+ */
302
+ export declare const HOST_STUB_NOTE: string;
303
+ /**
304
+ * The tools whose every answer leaves a screenshot of the page. A sequence (`reticle_act` with
305
+ * `steps`) takes one per step, inside the sequence, rather than one for the whole call.
306
+ */
307
+ export declare const STEP_SHOT_TOOLS: ReadonlySet<string>;
308
+ /** A step-screenshot tool, with the one sentence about its screenshot on the end of its description. */
309
+ export declare function withScreenshotDoc(tool: ToolDef): ToolDef;
310
+ /** The one sentence every tool that takes a step screenshot says about it. */
311
+ export declare const SCREENSHOT_DOC = " `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice.";
246
312
  /**
247
313
  * Fields that `runTool` / `withControl` splice onto EVERY session-bound tool result at runtime.
248
314
  * Merged into each session-bound tool's outputSchema so a schema-strict client (structuredContent
@@ -267,3 +333,17 @@ export declare function snapshotTree(deps: ToolDeps, sessionId: string | undefin
267
333
  * imports. See `ToolDeps.snapshots` for why a daemon-wide store cannot be correct.
268
334
  */
269
335
  export declare const newSnapshotCache: () => SnapshotCache;
336
+ /** The argument a replay takes its redacted fields' values in, for that call only. */
337
+ export declare const CALL_SECRETS_ARG = "secrets";
338
+ /** The secrets the current call supplied, keyed as given (a field, or its variable name). */
339
+ export declare function callSecrets(): Readonly<Record<string, string>> | undefined;
340
+ /**
341
+ * Take the call's secrets out of its arguments, so nothing downstream — the tool log, the journal,
342
+ * telemetry — ever sees them.
343
+ */
344
+ export declare function takeCallSecrets(args: Record<string, unknown>): {
345
+ secrets: Record<string, string> | undefined;
346
+ rest: Record<string, unknown>;
347
+ };
348
+ /** Run `fn` with these secrets supplied for it alone. */
349
+ export declare function withCallSecrets<T>(secrets: Readonly<Record<string, string>> | undefined, fn: () => Promise<T>): Promise<T>;
@@ -1,11 +1,6 @@
1
- /**
2
- * Shared kit for the MCP tool modules — the tool shape, the dependency bag, the common
3
- * session-id arg, and the two helpers (commandOrThrow, snapshotTree) every tool group needs. Lives
4
- * in its own leaf module (no dependency on any tool array) so the per-group tool files can import it
5
- * without a circular import — `tools.ts` assembles the groups and re-exports `ToolDef`/`ToolDeps`.
6
- */
7
1
  import { z } from 'zod';
8
- import { ReticleCommand, SnapshotMode } from '@reticlehq/core';
2
+ import { AsyncLocalStorage } from 'node:async_hooks';
3
+ import { asRecord, asString, ReticleCommand, ReticleTool, SnapshotMode, } from '@reticlehq/core';
9
4
  import { normalizeLines } from '../../memory/project/baselines.js';
10
5
  import { SnapshotCache } from './read/snapshot-delta.js';
11
6
  /**
@@ -84,7 +79,54 @@ export const EnvelopeKey = {
84
79
  VERSION_SKEW: 'version_skew',
85
80
  /** A feedback report that was accepted and then failed to send. Only the reporter can act on it. */
86
81
  FEEDBACK_UNDELIVERED: 'feedback_undelivered',
82
+ /** Once per project: verified runs exist only on this machine. See platform-moment.ts. */
83
+ PLATFORM: 'platform',
84
+ /**
85
+ * This leased tab runs a STUB of the bindings a desktop shell injects (`reticle_lease acquire`'s
86
+ * `initScript`), so a verdict here is about the app's view logic and not about the real shell.
87
+ */
88
+ HOST_STUB: 'host_stub',
89
+ /** The one thing to do next: declare the request, yield, fix sync, connect. See next-step.ts. */
90
+ NEXT: 'next',
91
+ /** One-shot: a Harness drive started or finished, from any origin, and how to read it. */
92
+ HARNESS: 'harness',
93
+ /** Where this step's screenshot is (`{ path, source }`), or why there is none. See step-shots.ts. */
94
+ SCREENSHOT: 'screenshot',
95
+ /**
96
+ * One-shot: this call's tab was opened by Reticle on an app nobody wired, with the SDK supplied —
97
+ * what it cannot see, and the command that wires the app for good. See zero-install-first-call.ts.
98
+ */
99
+ ZERO_INSTALL: 'zero_install',
100
+ /** Once-per-session advisory lines an agent's own call carries. See agent/notices.ts. */
101
+ NOTICES: 'notices',
87
102
  };
103
+ /**
104
+ * The sentence every session-bound result carries while its leased tab runs on a stubbed shell.
105
+ *
106
+ * Spliced wherever the tab's health is spliced, because the fact matters to exactly the same
107
+ * readings: a green from a tab whose `window.go` Reticle faked is not evidence about the real shell,
108
+ * and nothing else in the result would say so.
109
+ */
110
+ export const HOST_STUB_NOTE = 'a stub for the bindings a desktop shell injects was installed in this tab before its scripts ' +
111
+ 'ran, so a green here is not a verdict against the real shell.';
112
+ /**
113
+ * The tools whose every answer leaves a screenshot of the page. A sequence (`reticle_act` with
114
+ * `steps`) takes one per step, inside the sequence, rather than one for the whole call.
115
+ */
116
+ export const STEP_SHOT_TOOLS = new Set([
117
+ ReticleTool.ACT,
118
+ ReticleTool.ACT_AND_WAIT,
119
+ ReticleTool.NAVIGATE,
120
+ ReticleTool.ASSERT,
121
+ ]);
122
+ /** A step-screenshot tool, with the one sentence about its screenshot on the end of its description. */
123
+ export function withScreenshotDoc(tool) {
124
+ return STEP_SHOT_TOOLS.has(tool.name)
125
+ ? { ...tool, description: `${tool.description}${SCREENSHOT_DOC}` }
126
+ : tool;
127
+ }
128
+ /** The one sentence every tool that takes a step screenshot says about it. */
129
+ export const SCREENSHOT_DOC = ' `screenshot.path` is a picture of the page at the outcome: open it when the look of the page matters; reading it is your choice.';
88
130
  /**
89
131
  * Fields that `runTool` / `withControl` splice onto EVERY session-bound tool result at runtime.
90
132
  * Merged into each session-bound tool's outputSchema so a schema-strict client (structuredContent
@@ -126,3 +168,31 @@ export async function snapshotTree(deps, sessionId) {
126
168
  * imports. See `ToolDeps.snapshots` for why a daemon-wide store cannot be correct.
127
169
  */
128
170
  export const newSnapshotCache = () => new SnapshotCache();
171
+ /** The argument a replay takes its redacted fields' values in, for that call only. */
172
+ export const CALL_SECRETS_ARG = 'secrets';
173
+ /** Secrets a call supplied; never written anywhere, gone when the call ends. */
174
+ const callSecretStore = new AsyncLocalStorage();
175
+ /** The secrets the current call supplied, keyed as given (a field, or its variable name). */
176
+ export function callSecrets() {
177
+ return callSecretStore.getStore();
178
+ }
179
+ /**
180
+ * Take the call's secrets out of its arguments, so nothing downstream — the tool log, the journal,
181
+ * telemetry — ever sees them.
182
+ */
183
+ export function takeCallSecrets(args) {
184
+ if (!(CALL_SECRETS_ARG in args))
185
+ return { secrets: undefined, rest: args };
186
+ const { [CALL_SECRETS_ARG]: raw, ...rest } = args;
187
+ const secrets = {};
188
+ for (const [key, value] of Object.entries(asRecord(raw))) {
189
+ const text = asString(value);
190
+ if (text !== undefined && 0 < text.length)
191
+ secrets[key] = text;
192
+ }
193
+ return { secrets, rest };
194
+ }
195
+ /** Run `fn` with these secrets supplied for it alone. */
196
+ export function withCallSecrets(secrets, fn) {
197
+ return secrets === undefined ? fn() : callSecretStore.run(secrets, fn);
198
+ }
@@ -1,5 +1,7 @@
1
+ import { TESTID_FOUND_UNDER_SCHEMA } from './query-hint-schema.js';
1
2
  import { z } from 'zod';
2
- import { DiscoveryInvite, AttrNamesSchema, EventType, NoSessionAction, QueryBy, ReticleCommand, SnapshotMode, } from '@reticlehq/core';
3
+ import { EMPTY_SESSION_LIST_OUTPUT, emptySessionList, wireCallerBesideLiveSessions, } from './empty-session-list.js';
4
+ import { AttrNamesSchema, EventType, QueryBy, ReticleCommand, SnapshotMode } from '@reticlehq/core';
3
5
  import { ReticleTool } from '@reticlehq/core';
4
6
  import { withSizeCost } from '../../portal/session/output-budget.js';
5
7
  import { applySnapshotDelta, SnapshotCache } from './read/snapshot-delta.js';
@@ -41,23 +43,25 @@ import { VIEWPORT_TOOLS } from '../../portal/input/viewport-tools.js';
41
43
  import { SESSION_TOOLS } from '../../portal/session/session-tools.js';
42
44
  import { ANNOTATE_TOOLS } from '../../language/flows/annotate-tools.js';
43
45
  import { LIVE_CONTROL_TOOLS } from '../../portal/session/live-control-tools.js';
44
- import { sessionIdShape, commandOrThrow } from './tool-kit.js';
46
+ import { SCREENSHOT_DOC, sessionIdShape, commandOrThrow, withScreenshotDoc, } from './tool-kit.js';
45
47
  import { TOOL_SURFACE } from './tool-surface.js';
46
48
  import { mergeActWithSequence } from './act-merged.js';
47
49
  import { INSPECT_TOOL } from './inspect-tool.js';
48
50
  import { applyMerges } from './merge-tools.js';
49
51
  import { ACT_TOOLS } from './act-tools.js';
50
52
  import { ACT_SEQUENCE_TOOL } from './act-sequence-tool.js';
53
+ import { withCompactEnvelope } from './agent/compact-envelope.js';
51
54
  import { OBSERVE_TOOLS } from './observe-tools.js';
52
55
  import { LINEAGE_TOOLS } from './lineage-tools.js';
53
56
  import { RECONCILE_TOOLS } from './reconcile-tools.js';
54
57
  import { READ_TOOLS } from './read-tools.js';
55
58
  import { LEASE_TOOLS } from './lease-tools.js';
56
59
  import { FEEDBACK_TOOLS } from './feedback-tools.js';
60
+ import { ACCOUNT_TOOLS } from './account-tool.js';
57
61
  /** FALLBACK for `diff: true`; the real one is per MCP client on `deps.snapshots`, which says why. */
58
62
  const SNAPSHOT_CACHE = new SnapshotCache();
59
63
  /** Every handler, including tools retired from the advertised MCP surface. */
60
- export const RAW_TOOLS = [
64
+ export const RAW_TOOLS = withCompactEnvelope([
61
65
  {
62
66
  name: ReticleTool.SESSIONS,
63
67
  description: 'List connected browser sessions (tab url/title, sessionId, last-seen, health: hidden/focused/throttled, and `realInputAvailable` — true when native CDP/launched real input is driving this tab), plus a `recommendation` naming the in-protocol escape hatch (`reticle_run { tool: "reticle_lease" }`, with `reticle drive` as the human-side equivalent) when a tab is hidden/throttled and may be un-scriptable from here.',
@@ -82,6 +86,11 @@ export const RAW_TOOLS = [
82
86
  .string()
83
87
  .optional()
84
88
  .describe("Present only when this page's SDK version differs from the daemon's. A skewed pair connects and then disagrees about tool behaviour — usually surfacing as a bare -32000. Fix it before trusting any verdict from this session."),
89
+ window: z.string().optional().describe('Desktop window label (Tauri: main, setup…).'),
90
+ documentStatus: z
91
+ .number()
92
+ .optional()
93
+ .describe('Set only for an error page (4xx/5xx): not the app, never auto-selected first.'),
85
94
  lastSeenMs: z.number(),
86
95
  throttled: z.boolean(),
87
96
  focused: z.boolean(),
@@ -112,61 +121,25 @@ export const RAW_TOOLS = [
112
121
  .describe('Continuity of the SDK-to-daemon LINK for this tab, present for any tab the daemon has a record of: how long this attachment has lasted, how many times it dropped and came back, and when the last gap started and how long it lasted. `outages > 0` means a verdict over this window spans a gap where nothing was observed. These are link counters, NOT app health: they say nothing about whether the page origin is still serving, so a tab whose dev server has died reports `outages: 0` with a growing `connectedSinceMs` and is not evidence the app is up.'),
113
122
  }))
114
123
  .describe('Connected browser sessions with health state. `projectId` groups sessions by app (stable across port changes); `leased` marks a pool-managed headless context vs a human tab.'),
115
- why: z
116
- .string()
117
- .optional()
118
- .describe('Present ONLY when `sessions` is empty: why nothing is connected, and the next action that fixes it. An empty list is never the end of the road — read this before concluding the app cannot be driven.'),
119
- next_action: z
120
- .object({
121
- action: z.nativeEnum(NoSessionAction),
122
- command: z.string().optional(),
123
- port: z.number().optional(),
124
- reason: z.string(),
125
- })
126
- .optional()
127
- .describe("Present ONLY when `sessions` is empty: the same answer as `why`, executable. `command` is the LITERAL command to run, sourced from this project's own package.json scripts and lockfile — it is absent, never guessed, when the project declares no dev script. `action` is one of daemon_split | start_dev_server | run_init | open_app | reopen_app. `daemon_split` outranks the rest and means the app IS running and instrumented, on a DIFFERENT daemon than the one you are attached to — do not start or re-init anything, read `reason`."),
128
- talk_to_us: z
129
- .string()
130
- .optional()
131
- .describe('Present ONLY when `sessions` is empty: a call with the founder for the person you are working with. Offer it; never act on it.'),
132
- lastKnown: z
133
- .object({
134
- sessionId: z.string(),
135
- url: z.string(),
136
- })
137
- .optional()
138
- .describe('Present ONLY when `sessions` is empty AND a tab was connected to this daemon earlier: the last sessionId and URL that tab was on when it disappeared. A route that 500s tears the page down and the SDK never reconnects — this is the last thing we knew, not a route-500 verdict. An empty list with no lastKnown is a tab that never arrived.'),
124
+ ...EMPTY_SESSION_LIST_OUTPUT,
139
125
  },
140
126
  handler: async (deps) => {
141
127
  const provider = deps.realInput;
142
128
  const leasedIds = new Set(deps.pool?.leasedSessionIds() ?? []);
143
- const sessions = await Promise.all(deps.sessions.list().map(async (s) => ({
129
+ const list = () => Promise.all(deps.sessions.list().map(async (s) => ({
144
130
  ...s,
145
131
  realInputAvailable: provider !== undefined ? await provider.isAvailableFor(s.url) : false,
146
132
  leased: leasedIds.has(s.sessionId),
147
133
  })));
148
- // An empty list is the most common thing this tool ever returns, and on its own it is a dead
149
- // end: the agent asked the one question it knows to ask, got a confident-looking answer with
150
- // no next step, and stopped. The daemon already knows WHY nothing is connected — say it here
151
- // rather than only when a later tool fails for want of a session.
152
- if (0 === sessions.length) {
153
- const why = deps.sessions.noSessionHint();
154
- // The executable half. `why` is for the human reading the transcript; this is the one the
155
- // agent acts on, so it never has to parse a paragraph to find a command inside it.
156
- const next = deps.sessions.noSessionNextAction();
157
- // The last tab, when one was here. Optional-call: test stubs of SessionManager predate it.
158
- const known = deps.sessions.lastKnown?.();
159
- const lastKnown = undefined === known ? undefined : { sessionId: known.id, url: known.url };
160
- return {
161
- sessions,
162
- ...(why === undefined ? {} : { why }),
163
- ...(next === undefined ? {} : { next_action: next }),
164
- ...(undefined === lastKnown ? {} : { lastKnown }),
165
- // Setup that never connects is where most people give up; it is the talk worth having.
166
- talk_to_us: DiscoveryInvite.AGENT,
167
- };
168
- }
169
- return { sessions };
134
+ const sessions = await list();
135
+ // An empty list is a dead end on its own; see empty-session-list.ts for what it carries.
136
+ if (0 === sessions.length)
137
+ return emptySessionList(deps, sessions);
138
+ // Another project's tab is up. This caller's project may still never have been wired.
139
+ const wired = await wireCallerBesideLiveSessions(deps, sessions);
140
+ if (wired === undefined)
141
+ return { sessions };
142
+ return { sessions: await list(), wired };
170
143
  },
171
144
  },
172
145
  {
@@ -394,12 +367,17 @@ export const RAW_TOOLS = [
394
367
  .passthrough()
395
368
  .optional()
396
369
  .describe("Present when a TEXT search missed but the string IS on the page, split across this container's children. Retry as { scope: <ref>, self: true } — no text query can match a string no single element owns."),
370
+ caseMiss: z
371
+ .string()
372
+ .optional()
373
+ .describe('Present when a case-exact TEXT check missed and the page shows the text in another case: what it shows. Retry with ignoreCase: true if the case does not matter.'),
397
374
  // Declared here for the same reason presentRegions had to be: the browser emits it, and an
398
375
  // undeclared field is stripped from structuredContent without a word.
399
376
  nameNearMiss: z
400
377
  .array(z.string())
401
378
  .optional()
402
379
  .describe('Present when a ROLE+NAME search missed and that role DOES carry a nearly-matching name — role+name is exact, so "Mesh" does not find "2 Mesh". Retry with one of these spellings; no snapshot needed.'),
380
+ testidFoundUnder: TESTID_FOUND_UNDER_SCHEMA,
403
381
  })
404
382
  .optional()
405
383
  .describe('Present only on zero matches — tells you what IS on the page so you can diagnose the miss.'),
@@ -465,16 +443,14 @@ export const RAW_TOOLS = [
465
443
  // reachable through reticle_run. See affected-tools.ts.
466
444
  ...AFFECTED_TOOLS,
467
445
  // reticle_coverage — which controls were driven vs never touched. Unadvertised; via reticle_run.
468
- // The table is passed as a thunk so the coverage tool can report which of it was called without
469
- // importing it back — see buildCoverageTools. Called from the handler, long after TOOLS exists.
470
- ...buildCoverageTools(() => TOOLS.map((t) => t.name)),
446
+ ...buildCoverageTools(),
471
447
  // reticle_verify_change — "did my change break anything" in one call. See verify-change-tools.ts.
472
448
  ...VERIFY_CHANGE_TOOLS,
473
449
  // Live-control: reticle_end_session / reticle_resume / reticle_messages. See live-control-tools.ts.
474
450
  ...LIVE_CONTROL_TOOLS,
475
451
  // reticle_navigate / reticle_refresh — browser navigation tools. See browser-tools.ts.
476
- ...BROWSER_TOOLS,
477
- ...ACT_TOOLS,
452
+ ...BROWSER_TOOLS.map(withScreenshotDoc),
453
+ ...ACT_TOOLS.map(withScreenshotDoc),
478
454
  ACT_SEQUENCE_TOOL,
479
455
  ...OBSERVE_TOOLS,
480
456
  ...LINEAGE_TOOLS,
@@ -482,7 +458,8 @@ export const RAW_TOOLS = [
482
458
  ...LEASE_TOOLS,
483
459
  // reticle_feedback — the agent reports that RETICLE failed (not that the app did). See feedback-tools.ts.
484
460
  ...FEEDBACK_TOOLS,
485
- ];
461
+ ...ACCOUNT_TOOLS,
462
+ ]);
486
463
  /**
487
464
  * surface consolidation. Tool defs are re-sent EVERY turn, so the advertised count is a per-turn
488
465
  * tax multiplied by loop length. Sibling families collapse into one action-dispatched tool; the member
@@ -522,7 +499,10 @@ export const MERGE_PLANS = [
522
499
  // whatever comes first is what an agent discovers; when this sentence opened with `tune` the
523
500
  // MANDATORY handback sat past the cut and no agent reading the catalogue ever learned it
524
501
  // existed. The rule is: if a tool has an obligation, the obligation goes first.
525
- 'Session lifecycle and the human channel, by action: "yield" hands control back to the human and is MANDATORY before you stop driving (mode: waiting|ask, between turns); "tune" adjusts the presenter session (e.g. idle-end window); "end" terminates the session for good; "resume" clears a human pause; "messages" drains the human→agent inbox; "review" lists/resolves the mistakes a human pinned to elements; "narrate" states your intent on the presenter HUD.',
502
+ // The first sentence is all a lean surface shows (160 characters), so it carries the
503
+ // obligation and the HUD control; the rest is the detail for a full one.
504
+ 'By action: "yield" is MANDATORY before you stop driving; "tune" hides or moves the HUD, or sets the idle window; "account" says the plan, credits and Harness state. ' +
505
+ 'In full: "yield" hands control back to the human (mode: waiting|ask, between turns); "tune" takes `hud` (hidden, shown, removed until reload, or a corner) for when the HUD covers a control you must test, and `idleEndMs`; "end" terminates the session for good; "resume" clears a human pause; "messages" drains the human→agent inbox; "review" lists/resolves the mistakes a human pinned to elements; "narrate" states your intent on the presenter HUD.',
526
506
  members: {
527
507
  tune: ReticleTool.SESSION_TUNE,
528
508
  yield: ReticleTool.YIELD,
@@ -531,6 +511,7 @@ export const MERGE_PLANS = [
531
511
  messages: ReticleTool.MESSAGES,
532
512
  review: ReticleTool.REVIEW,
533
513
  narrate: ReticleTool.NARRATE,
514
+ account: ReticleTool.ACCOUNT,
534
515
  },
535
516
  // The handback the lease block orders on every session — the one call an agent MUST make, so it
536
517
  // is the one that must not need a schema lookup first.
@@ -538,7 +519,7 @@ export const MERGE_PLANS = [
538
519
  },
539
520
  {
540
521
  name: ReticleTool.VERIFY,
541
- description: 'What is proved, and what is not — by action. Start from a change: { action: "affected" } names which saved flows must re-verify for the files you edited (pass `files`, and/or `since` for a git ref), and "change" goes further and actually replays them, answering with one `verified` plus `because`. `unknown` there is the honest answer when NO saved flow covers the change: nothing ran, so nothing was proved, and it is never reported as green. Without a change to start from: "flows" replays every saved flow for one consolidated suite verdict (deterministic, no LLM per flow), and "coverage" lists the interactive controls you have and have NOT driven this session — an untouched list still holding the controls your change affects means you are not done. "crawl" is the no-script option: it drives every reachable control itself and reports single-channel faults (console errors, failed requests, dead controls) and CONTRADICTIONS, two channels disagreeing about the same click — the false greens a human cannot see, because a human watches the screen and the screen looks correct. "explore" is the one to reach for on a project with NO saved flows: a model inside the daemon drives the app for you — pass a `persona` and it completes that whole journey — and RECORDS what it drove, so the next run replays it with no model in the loop and none of the driving costs your context. "mutate" grades the FLOW rather than the app: it breaks the endpoint a saved flow declared it depends on and replays it, and a flow that stays GREEN through a broken subject is a click sequence, not a test. "heal" repairs a flow whose LOCATOR drifted (a renamed testid), re-asserting the saved consequence before it writes and refusing when that stops firing — it heals a locator, never an intent. DESTRUCTIVE: crawl and explore really click, and may navigate or mutate state; "mutate" really fails a request on a driven page, and always puts it back.',
522
+ description: 'What is proved, and what is not — by action. Start from a change: { action: "affected" } names which saved flows must re-verify for the files you edited (pass `files`, and/or `since` for a git ref), and "change" goes further and actually replays them, answering with one `verified` plus `because`. `unknown` there is the honest answer when NO saved flow covers the change: nothing ran, so nothing was proved, and it is never reported as green. Without a change to start from: "flows" replays every saved flow for one consolidated suite verdict (deterministic, no LLM per flow), and "coverage" lists the interactive controls you have and have NOT driven this session — an untouched list still holding the controls your change affects means you are not done. "crawl" is the no-script option: it drives every reachable control itself and reports single-channel faults (console errors, failed requests, dead controls) and CONTRADICTIONS, two channels disagreeing about the same click — the false greens a human cannot see, because a human watches the screen and the screen looks correct. "explore" is the one to reach for on a project with NO saved flows: the Reticle Harness drives the app for you on the platform — pass a `persona` and it completes that whole journey — and RECORDS what it drove, so the next run replays it with no model in the loop and none of the driving costs your context. "mutate" grades the FLOW rather than the app: it breaks the endpoint a saved flow declared it depends on and replays it, and a flow that stays GREEN through a broken subject is a click sequence, not a test. "heal" repairs a flow whose LOCATOR drifted (a renamed testid), re-asserting the saved consequence before it writes and refusing when that stops firing — it heals a locator, never an intent. DESTRUCTIVE: crawl and explore really click, and may navigate or mutate state; "mutate" really fails a request on a driven page, and always puts it back.',
542
523
  members: {
543
524
  change: ReticleTool.VERIFY_CHANGE,
544
525
  flows: ReticleTool.FLOW_VERIFY,
@@ -768,7 +749,8 @@ export const SURFACE_MERGE_PLANS = [
768
749
  },
769
750
  {
770
751
  name: ReticleTool.ASSERT,
771
- description: 'Prove a consequence, by action: "now" evaluates a predicate against the window that already exists, "wait" waits for one to become true within a budget. Both return a verdict; only `verified:"yes"` is a pass.',
752
+ description: 'Prove a consequence, by action: "now" evaluates a predicate against the window that already exists, "wait" waits for one to become true within a budget. Both return a verdict; only `verified:"yes"` is a pass.' +
753
+ SCREENSHOT_DOC,
772
754
  members: { now: ReticleTool.ASSERT, wait: ReticleTool.WAIT_FOR },
773
755
  example: { action: 'now' },
774
756
  // Evaluate against the window that already exists. `wait` spends a budget, so it is asked for.
@@ -804,6 +786,8 @@ export const MERGED_SURFACE_PLANS = [
804
786
  // surface: on the default one `reticle_sessions` still exists and this tool is purely
805
787
  // lifecycle, where no member is the obvious bare meaning.
806
788
  defaultAction: 'list',
789
+ description: 'By action: "list" (the default) shows connected tabs; "yield" is MANDATORY before you stop; "tune" hides or moves the HUD; "feedback" reports a problem. ' +
790
+ 'In full: "list" is the first call to make, and on a project that has never connected it wires the app and names the files it changed under `wired`; "yield" hands control back to the human (mode: waiting|ask); "tune" takes `hud` (hidden, shown, removed until reload, or a corner) for when the HUD covers a control you must test, and `idleEndMs`; "feedback" files a report; "end", "resume", "messages", "review" and "narrate" manage the session and the human channel.',
807
791
  }
808
792
  : plan),
809
793
  ...SURFACE_MERGE_PLANS,
@@ -0,0 +1,7 @@
1
+ import { TelemetryAccountState } from '@reticlehq/core/telemetry';
2
+ export interface AccountEnvelope {
3
+ accountState: TelemetryAccountState;
4
+ linked: boolean;
5
+ workspaceId?: string;
6
+ }
7
+ export declare function accountEnvelope(cwd: string, env: NodeJS.ProcessEnv, home: string): AccountEnvelope;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Where this machine stands with the platform, for every telemetry event: signed out, signed in, or
3
+ * this project linked to a workspace, and that workspace's id.
4
+ *
5
+ * Read from what the CLI already wrote, never asked of the network: the session file (through
6
+ * `readAccountState`, which cannot carry the token) and the project's `.reticle/cloud.json`. Read per
7
+ * event, because a sign-in from the HUD changes the answer mid-session.
8
+ *
9
+ * The workspace id is the platform's `orgId`: pseudonymous here, and the key the platform joins its
10
+ * own records on. The workspace NAME and the signed-in email are never read into this.
11
+ */
12
+ import { readFileSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ import { ReticleDir } from '@reticlehq/core';
15
+ import { TelemetryAccountState } from '@reticlehq/core/telemetry';
16
+ import { readAccountState } from '../memory/cloud/account-state.js';
17
+ import { linkDirectoryFrom } from '../memory/project/link-directory.js';
18
+ const MAX_WORKSPACE_ID = 128;
19
+ /** The link this project carries, if it is a real one (a project id and a host). */
20
+ function readLink(dir) {
21
+ try {
22
+ const raw = JSON.parse(readFileSync(join(dir, ReticleDir.ROOT, ReticleDir.CLOUD_LINK_FILE), 'utf8'));
23
+ if ('object' !== typeof raw || null === raw)
24
+ return undefined;
25
+ const o = raw;
26
+ const projectId = o['projectId'];
27
+ const url = o['url'];
28
+ if ('string' !== typeof projectId || 0 === projectId.length)
29
+ return undefined;
30
+ if ('string' !== typeof url || 0 === url.length)
31
+ return undefined;
32
+ const orgId = o['orgId'];
33
+ return 'string' === typeof orgId && 0 < orgId.length && orgId.length <= MAX_WORKSPACE_ID
34
+ ? { orgId }
35
+ : {};
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ }
41
+ export function accountEnvelope(cwd, env, home) {
42
+ let link;
43
+ try {
44
+ link = readLink(linkDirectoryFrom(cwd)) ?? readLink(cwd);
45
+ }
46
+ catch {
47
+ link = undefined;
48
+ }
49
+ if (link !== undefined) {
50
+ return {
51
+ accountState: TelemetryAccountState.LINKED,
52
+ linked: true,
53
+ ...(link.orgId === undefined ? {} : { workspaceId: link.orgId }),
54
+ };
55
+ }
56
+ const signedIn = readAccountState(home, env).signedIn;
57
+ return {
58
+ accountState: signedIn ? TelemetryAccountState.SIGNED_IN : TelemetryAccountState.SIGNED_OUT,
59
+ linked: false,
60
+ };
61
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Which coding agent an event came from, as a closed value — and how the running `reticle` was
3
+ * launched. Both are envelope fields, read per event (the client) or once per process (the launch).
4
+ *
5
+ * The client is the MCP handshake's `clientInfo.name` for the call in flight (or the only agent
6
+ * attached), normalised by `agentClientOf`. When no handshake has said anything — a one-shot CLI
7
+ * command, a proxy, a client that skipped `initialize` — the agent's own marker in the environment
8
+ * of what it spawned is the fallback. Only markers an agent sets on purpose are read.
9
+ */
10
+ import { AgentClient, LaunchMethod } from '@reticlehq/core/telemetry';
11
+ export declare function envAgentClient(env: NodeJS.ProcessEnv): AgentClient | undefined;
12
+ /** The client for an event being built now. */
13
+ export declare function currentAgentClient(env: NodeJS.ProcessEnv): AgentClient | undefined;
14
+ /** How the process was launched, from the path of its entry script. Only the bucket leaves. */
15
+ export declare function launchMethodOf(entry: string | undefined): LaunchMethod;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Which coding agent an event came from, as a closed value — and how the running `reticle` was
3
+ * launched. Both are envelope fields, read per event (the client) or once per process (the launch).
4
+ *
5
+ * The client is the MCP handshake's `clientInfo.name` for the call in flight (or the only agent
6
+ * attached), normalised by `agentClientOf`. When no handshake has said anything — a one-shot CLI
7
+ * command, a proxy, a client that skipped `initialize` — the agent's own marker in the environment
8
+ * of what it spawned is the fallback. Only markers an agent sets on purpose are read.
9
+ */
10
+ import { AgentClient, LaunchMethod } from '@reticlehq/core/telemetry';
11
+ import { agentClientOf, callingClientName } from '../hooks/coding-agents.js';
12
+ /**
13
+ * Environment markers a coding agent sets on the processes it spawns. A shared daemon inherits the
14
+ * environment of whichever agent started it, so this is a fallback after the handshake, never ahead
15
+ * of it.
16
+ */
17
+ const ENV_MARKERS = [
18
+ ['CLAUDECODE', AgentClient.CLAUDE_CODE],
19
+ ['CODEX_SANDBOX', AgentClient.CODEX],
20
+ ['CODEX_MANAGED_BY_NPM', AgentClient.CODEX],
21
+ ['CURSOR_TRACE_ID', AgentClient.CURSOR],
22
+ ['GEMINI_CLI', AgentClient.GEMINI_CLI],
23
+ ];
24
+ export function envAgentClient(env) {
25
+ return ENV_MARKERS.find(([key]) => (env[key] ?? '') !== '')?.[1];
26
+ }
27
+ /** The client for an event being built now. */
28
+ export function currentAgentClient(env) {
29
+ return agentClientOf(callingClientName()) ?? envAgentClient(env);
30
+ }
31
+ /**
32
+ * Where a global install puts packages, by package manager. A path that matches none of these but
33
+ * still sits in a `node_modules` is a project's own dependency.
34
+ */
35
+ const GLOBAL_DIRS = [
36
+ '/lib/node_modules/',
37
+ '/npm/node_modules/',
38
+ '/pnpm/global/',
39
+ '/.volta/',
40
+ '/.bun/install/global/',
41
+ '/yarn/global/',
42
+ '/.nvm/',
43
+ '/.npm-global/',
44
+ ];
45
+ /** How the process was launched, from the path of its entry script. Only the bucket leaves. */
46
+ export function launchMethodOf(entry) {
47
+ if (entry === undefined)
48
+ return LaunchMethod.OTHER;
49
+ const path = entry.replace(/\\/g, '/').toLowerCase();
50
+ if (path.includes('/_npx/') || path.includes('/dlx-'))
51
+ return LaunchMethod.NPX;
52
+ if (GLOBAL_DIRS.some((dir) => path.includes(dir)))
53
+ return LaunchMethod.GLOBAL;
54
+ if (path.includes('/node_modules/'))
55
+ return LaunchMethod.PROJECT;
56
+ return LaunchMethod.OTHER;
57
+ }
@@ -15,8 +15,10 @@
15
15
  */
16
16
  import { OnboardingPhase, OnboardingStepStatus, TelemetryEventKind, } from '@reticlehq/core/telemetry';
17
17
  import { getTelemetry } from './telemetry.js';
18
- import { reportOnboardingStep } from './onboarding-funnel.js';
18
+ import { FirstEver, claimFirstEver, reportFirstStep } from './onboarding-firsts.js';
19
19
  let reported = false;
20
+ /** The on-disk claim for the EVENT, kept apart from the `app_connected` step's own claim. */
21
+ const APP_INSTRUMENTED_CLAIM = 'app_instrumented';
20
22
  /** Set at daemon start so the first connect can report how long the install sat un-instrumented. */
21
23
  let daemonStartedAt;
22
24
  export function markInstrumentationClock(now) {
@@ -32,8 +34,13 @@ export function reportAppInstrumented(facts, now = () => Date.now()) {
32
34
  return;
33
35
  reported = true;
34
36
  try {
37
+ // Still once per RUN: `daemon_started` minus `app_instrumented`, joined on sessionId, is the
38
+ // documented failure side and needs a row per run. Only the true first on this machine +
39
+ // project says `firstEver`, so a per-machine count no longer counts daemon restarts.
40
+ const firstEver = FirstEver.FIRST === claimFirstEver(APP_INSTRUMENTED_CLAIM);
35
41
  void getTelemetry().emit(TelemetryEventKind.APP_INSTRUMENTED, {
36
42
  instrumentation: {
43
+ ...(firstEver ? { firstEver: true } : {}),
37
44
  initialized: facts.initialized,
38
45
  agentAttached: facts.agentAttached,
39
46
  // How long the daemon ran before an app showed up. Large values are the interesting ones:
@@ -47,7 +54,7 @@ export function reportAppInstrumented(facts, now = () => Date.now()) {
47
54
  //
48
55
  // `instrumented` means files were written; THIS means a page actually dialled the bridge. Every
49
56
  // silent install bug so far has lived in the gap between those two.
50
- void reportOnboardingStep({
57
+ reportFirstStep({
51
58
  phase: OnboardingPhase.FIRST_RUN,
52
59
  step: 'app_connected',
53
60
  status: OnboardingStepStatus.COMPLETED,