@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
@@ -16,15 +16,23 @@
16
16
  import { spawn } from 'node:child_process';
17
17
  import { randomUUID, createHash } from 'node:crypto';
18
18
  import { appendFileSync, readFileSync, writeFileSync, mkdirSync, existsSync, rmSync, } from 'node:fs';
19
- import { homedir, platform } from 'node:os';
19
+ import { homedir, platform, tmpdir } from 'node:os';
20
20
  import { dirname, join } from 'node:path';
21
- import { TelemetryEventKind, TELEMETRY_EVENT_VERSION, ProjectIdSource, isSessionScoped, } from '@reticlehq/core/telemetry';
21
+ import { TelemetryAccountState, TelemetryEventKind, TELEMETRY_EVENT_VERSION, TelemetryEventSchema, ProjectIdSource, isSessionScoped, } from '@reticlehq/core/telemetry';
22
+ import { ReticleEnv } from '@reticlehq/core';
22
23
  import { SERVER_VERSION } from '../command/version/identity/server-version.js';
23
24
  const RETICLE_DIR = join(homedir(), '.reticle');
24
- const ID_FILE = join(RETICLE_DIR, 'telemetry-id');
25
- const NOTICE_FILE = join(RETICLE_DIR, 'telemetry-notice-shown');
25
+ const ID_FILE_NAME = 'telemetry-id';
26
+ const ID_FILE = join(RETICLE_DIR, ID_FILE_NAME);
27
+ const NOTICE_FILE_NAME = 'telemetry-notice-shown';
26
28
  /** Presence of this file = a persistent, machine-wide opt-out (`reticle telemetry disable`). */
27
- const OPT_OUT_FILE = join(RETICLE_DIR, 'telemetry-opt-out');
29
+ const OPT_OUT_FILE_NAME = 'telemetry-opt-out';
30
+ /**
31
+ * Presence of this file marks the MACHINE as the Reticle team's own: every event carries
32
+ * `internal: true`. The persistent twin of `RETICLE_INTERNAL=1`, for a dev machine where setting a
33
+ * variable in every shell would be forgotten once and pollute the numbers for good.
34
+ */
35
+ export const INTERNAL_MARKER_FILE = 'telemetry-internal';
28
36
  /** Where the full disclosure lives — printed in the first-run notice and `reticle telemetry status`. */
29
37
  const POLICY_URL = 'https://github.com/reticlehq/reticle/blob/main/docs/telemetry.md';
30
38
  /** PostHog batch-capture endpoint (US cloud). `RETICLE_TELEMETRY_URL` overrides the host (EU/self-host). */
@@ -90,22 +98,36 @@ const FEEDBACK_RETRY_BACKOFF_MS = 750;
90
98
  * likely to be dropped, and it fails silently like everything else here.
91
99
  */
92
100
  const DETACHED_SEND_TIMEOUT_MS = 15_000;
93
- const DETACHED_SEND_SCRIPT = "fetch(process.argv[1],{method:'POST',headers:{'content-type':'application/json'}," +
94
- `body:process.argv[2],signal:AbortSignal.timeout(${DETACHED_SEND_TIMEOUT_MS})})` +
101
+ /**
102
+ * The body never rides in argv: argv is readable by every user on the machine through `ps`, and
103
+ * the body is the whole event. It is handed over in a file only its owner can read, which the child
104
+ * reads and deletes before sending. A file rather than a stdin pipe because the parent is a
105
+ * short-lived CLI that may `process.exit` the moment this returns, and an unflushed pipe write dies
106
+ * with it; a file is on disk before `spawn` is even called.
107
+ */
108
+ const DETACHED_SEND_SCRIPT = "const fs=require('fs');const f=process.argv[2];let b='';" +
109
+ 'try{b=fs.readFileSync(f,"utf8")}catch{}try{fs.unlinkSync(f)}catch{}' +
110
+ "fetch(process.argv[1],{method:'POST',headers:{'content-type':'application/json'}," +
111
+ `body:b,signal:AbortSignal.timeout(${DETACHED_SEND_TIMEOUT_MS})})` +
95
112
  '.catch(()=>{}).finally(()=>process.exit(0))';
113
+ /** Owner read/write only: the body file must not be readable by anyone else on the machine. */
114
+ const BODY_FILE_MODE = 0o600;
96
115
  /** Env var names — mirror cloud-sync's `RETICLE_*` convention. */
97
116
  import { isReticleSourceCheckout } from './dev-repo.js';
98
117
  import { projectInstallSource } from './install-source.js';
99
118
  import { licenseFacts } from './license-activation.js';
100
119
  import { gitFacts } from './git-facts.js';
101
120
  import { currentAutomationHint } from './automation-hint.js';
121
+ import { accountEnvelope } from './account-envelope.js';
122
+ import { currentAgentClient, launchMethodOf } from './agent-client.js';
102
123
  const Env = {
103
- DISABLE: 'RETICLE_TELEMETRY', // "0" / "false" / "off" → disabled
104
- DO_NOT_TRACK: 'DO_NOT_TRACK', // the cross-tool opt-out convention (any truthy value)
124
+ DISABLE: ReticleEnv.TELEMETRY, // "0" / "false" / "off" → disabled
125
+ DO_NOT_TRACK: ReticleEnv.DO_NOT_TRACK, // the cross-tool opt-out convention (any truthy value)
105
126
  URL: 'RETICLE_TELEMETRY_URL', // override the PostHog host (EU cloud / self-hosted)
106
127
  FILE: 'RETICLE_TELEMETRY_FILE', // record to a local JSONL file and send NOTHING — see the sink note
107
128
  KEY: 'RETICLE_TELEMETRY_KEY', // override the PostHog project key
108
129
  CI: 'CI', // presence marks a CI environment
130
+ INTERNAL: 'RETICLE_INTERNAL', // "1" marks the run as the Reticle team's own (dogfooding, sweeps)
109
131
  VITEST: 'VITEST', // set by vitest — unit tests must never phone home
110
132
  };
111
133
  const isDisabled = (env, cwd = process.cwd()) => {
@@ -140,22 +162,51 @@ const isDisabled = (env, cwd = process.cwd()) => {
140
162
  * file, and a test run. This lifts one implicit guard for one user-initiated event kind.
141
163
  */
142
164
  const onlyBlockedBySourceCheckout = (env, cwd) => isDisabled(env, cwd) && !isDisabled(env, '/');
143
- /** Read (or mint-and-persist) the anonymous machine id. `firstRun` is true the run that created it. */
144
- const resolveIdentity = () => {
165
+ /** Node's code for "the file is already there" — what an exclusive create answers when it lost. */
166
+ const EEXIST = 'EEXIST';
167
+ const isAlreadyThere = (error) => 'object' === typeof error && null !== error && EEXIST === error.code;
168
+ const readIdFile = (file) => {
145
169
  try {
146
- if (existsSync(ID_FILE)) {
147
- const id = readFileSync(ID_FILE, 'utf8').trim();
148
- if (id.length > 0)
149
- return { anonymousId: id, firstRun: false };
150
- }
170
+ const id = readFileSync(file, 'utf8').trim();
171
+ return id.length > 0 ? id : undefined;
172
+ }
173
+ catch {
174
+ return undefined;
175
+ }
176
+ };
177
+ /**
178
+ * Read (or mint-and-persist) the anonymous machine id. `firstRun` is true the run that created it.
179
+ *
180
+ * Read first and create exclusively (`wx`), rather than asking `existsSync` and then writing: two
181
+ * processes starting together used to both see no file, both mint, and the second write replaced
182
+ * the first id, so one machine reported as two first runs. The loser of the exclusive create now
183
+ * reads the winner's id instead.
184
+ */
185
+ export const resolveIdentity = (file = ID_FILE) => {
186
+ try {
187
+ const existing = readIdFile(file);
188
+ if (existing !== undefined)
189
+ return { anonymousId: existing, firstRun: false };
151
190
  const id = randomUUID();
152
- mkdirSync(RETICLE_DIR, { recursive: true });
153
- writeFileSync(ID_FILE, id, 'utf8');
191
+ mkdirSync(dirname(file), { recursive: true });
192
+ try {
193
+ writeFileSync(file, id, { encoding: 'utf8', flag: 'wx' });
194
+ }
195
+ catch (error) {
196
+ if (!isAlreadyThere(error))
197
+ throw error;
198
+ const raced = readIdFile(file);
199
+ if (raced !== undefined)
200
+ return { anonymousId: raced, firstRun: false };
201
+ // An empty file left by a crash: replace it, as the old code did.
202
+ writeFileSync(file, id, 'utf8');
203
+ }
154
204
  return { anonymousId: id, firstRun: true };
155
205
  }
156
206
  catch {
157
- // Can't persist (read-only home, sandbox): still report, just as a fresh ephemeral id each time.
158
- return { anonymousId: randomUUID(), firstRun: false };
207
+ // Can't persist (read-only home, sandbox): still report, as a fresh id each process, and SAY so —
208
+ // otherwise every process on that machine reads as a new user.
209
+ return { anonymousId: randomUUID(), firstRun: false, ephemeral: true };
159
210
  }
160
211
  };
161
212
  /**
@@ -207,12 +258,12 @@ const packageRoot = (cwd) => {
207
258
  return null;
208
259
  };
209
260
  /** Print the opt-out notice exactly once per machine (honest disclosure, the OSS-trust bar). */
210
- const showNoticeOnce = () => {
261
+ const showNoticeOnce = (dir) => {
211
262
  try {
212
- if (existsSync(NOTICE_FILE))
213
- return;
214
- mkdirSync(RETICLE_DIR, { recursive: true });
215
- writeFileSync(NOTICE_FILE, '1', 'utf8');
263
+ mkdirSync(dir, { recursive: true });
264
+ // Exclusive create IS the "once": it throws when the file is already there, so the check and
265
+ // the write cannot be split by a second process printing the notice too.
266
+ writeFileSync(join(dir, NOTICE_FILE_NAME), '1', { encoding: 'utf8', flag: 'wx' });
216
267
  process.stderr.write('reticle: anonymous usage telemetry helps improve reticle — no code, no PII, ' +
217
268
  `and your app's data never leaves your machine (${POLICY_URL}). ` +
218
269
  'Opt out any time: reticle telemetry disable\n');
@@ -235,7 +286,7 @@ export const describeTelemetry = (env = process.env, dir = RETICLE_DIR, cwd = pr
235
286
  if (isDisabled(env, cwd)) {
236
287
  return { enabled: false, reason: 'disabled by environment variable', policyUrl: POLICY_URL };
237
288
  }
238
- if (existsSync(join(dir, 'telemetry-opt-out'))) {
289
+ if (existsSync(join(dir, OPT_OUT_FILE_NAME))) {
239
290
  return {
240
291
  enabled: false,
241
292
  reason: 'disabled via `reticle telemetry disable`',
@@ -250,7 +301,7 @@ export const describeTelemetry = (env = process.env, dir = RETICLE_DIR, cwd = pr
250
301
  };
251
302
  /** Persist (or lift) the machine-wide opt-out — `reticle telemetry disable` / `enable`. */
252
303
  export const setTelemetryEnabled = (enabled, dir = RETICLE_DIR) => {
253
- const optOutFile = join(dir, 'telemetry-opt-out');
304
+ const optOutFile = join(dir, OPT_OUT_FILE_NAME);
254
305
  if (enabled) {
255
306
  rmSync(optOutFile, { force: true });
256
307
  return;
@@ -267,6 +318,7 @@ const NOOP = { emit: () => Promise.resolve(false), enabled: false, firstRun: fal
267
318
  * injected so this is testable without a clock or network.
268
319
  */
269
320
  export const createTelemetry = (opts) => {
321
+ const reticleDir = opts.reticleDir ?? RETICLE_DIR;
270
322
  const env = opts.env ?? process.env;
271
323
  const cwd = opts.cwd ?? process.cwd();
272
324
  // A source checkout silences metrics but must not silence FEEDBACK — see onlyBlockedBySourceCheckout.
@@ -274,7 +326,7 @@ export const createTelemetry = (opts) => {
274
326
  if (isDisabled(env, cwd) && !feedbackOnly)
275
327
  return NOOP;
276
328
  try {
277
- if (existsSync(OPT_OUT_FILE))
329
+ if (existsSync(join(reticleDir, OPT_OUT_FILE_NAME)))
278
330
  return NOOP; // the persistent `reticle telemetry disable` opt-out
279
331
  }
280
332
  catch {
@@ -293,7 +345,14 @@ export const createTelemetry = (opts) => {
293
345
  const os = platform();
294
346
  // Negated so it reads the way people say it: UTC+2 is +120, not -120.
295
347
  const tzOffsetMin = -new Date().getTimezoneOffset();
296
- const { anonymousId, firstRun } = resolveIdentity();
348
+ // Feedback-only (a source checkout) sends one kind of event, typed by a person: it borrows an
349
+ // existing id but never MINTS one, because minting spends `firstRun` and the machine's real first
350
+ // run would then never report its install.
351
+ const idFile = join(reticleDir, ID_FILE_NAME);
352
+ const { anonymousId, firstRun, ephemeral } = feedbackOnly
353
+ ? { anonymousId: readIdFile(idFile) ?? randomUUID(), firstRun: false, ephemeral: undefined }
354
+ : resolveIdentity(idFile);
355
+ const internal = isInternal(env, reticleDir);
297
356
  /**
298
357
  * One id per PROCESS, minted in memory and never persisted — which is exactly right: a daemon run
299
358
  * IS the session, and a restarted daemon is genuinely a new one. Ephemeral by construction, so it
@@ -307,10 +366,16 @@ export const createTelemetry = (opts) => {
307
366
  // was unknown for every event that could show whether they got anywhere. Reading it here puts it
308
367
  // on all of them, which is the only shape in which the question can be asked.
309
368
  const installSource = projectInstallSource(opts.cwd ?? process.cwd());
310
- showNoticeOnce();
369
+ // How this process was launched: a property of the process, so read once. Only the bucket leaves.
370
+ const launch = launchMethodOf(process.argv[1]);
371
+ const home = opts.home ?? homedir();
372
+ if (!feedbackOnly)
373
+ showNoticeOnce(reticleDir);
311
374
  const spawnDetached = opts.spawnImpl ??
312
- ((command, args) => {
313
- spawn(command, args, { detached: true, stdio: 'ignore' }).unref();
375
+ ((command, args, input) => {
376
+ const bodyFile = join(tmpdir(), `reticle-telemetry-${randomUUID()}.json`);
377
+ writeFileSync(bodyFile, input, { encoding: 'utf8', mode: BODY_FILE_MODE, flag: 'wx' });
378
+ spawn(command, [...args, bodyFile], { detached: true, stdio: 'ignore' }).unref();
314
379
  });
315
380
  /**
316
381
  * Returns whether the event was actually DELIVERED.
@@ -343,6 +408,9 @@ export const createTelemetry = (opts) => {
343
408
  // A SCALAR, so it needs the event build and the wire schema and no `blocks` entry — the same
344
409
  // three-place trap `outage` fell into, and `installSource` documents below.
345
410
  ...(automation !== undefined ? { automation } : {}),
411
+ // Two SCALARS, like `automation`: event build + wire schema, no `blocks` entry.
412
+ ...(internal ? { internal: true } : {}),
413
+ ...(true === ephemeral ? { idEphemeral: true } : {}),
346
414
  os,
347
415
  tzOffsetMin,
348
416
  projectIdSource,
@@ -377,13 +445,35 @@ export const createTelemetry = (opts) => {
377
445
  // the ambient one here would silently ignore it. Identical in production, wrong everywhere the
378
446
  // seam is actually used.
379
447
  ...licenseFacts(eventTs, env),
448
+ // Account, workspace and client: SCALARS on every event, so the event build and the wire
449
+ // schema and no `blocks` entry. Account and client are read per event: a HUD sign-in changes
450
+ // the first mid-session, and the second is whichever agent's call is in flight.
451
+ ...accountEnvelope(cwd, env, home),
452
+ ...(extra?.workspaceId !== undefined
453
+ ? {
454
+ workspaceId: extra.workspaceId,
455
+ linked: true,
456
+ accountState: TelemetryAccountState.LINKED,
457
+ }
458
+ : {}),
459
+ ...((client) => (client === undefined ? {} : { client }))(currentAgentClient(env)),
460
+ launch,
461
+ ...(extra?.hud !== undefined ? { hud: extra.hud } : {}),
462
+ ...(extra?.link !== undefined ? { link: extra.link } : {}),
463
+ ...(extra?.harness !== undefined ? { harness: extra.harness } : {}),
380
464
  };
465
+ // The wire schema's caps are only real if something applies them. An event that fails is
466
+ // DROPPED, never sent and never repaired: the payload is exactly what the caps exist to stop.
467
+ if (!TelemetryEventSchema.safeParse(event).success) {
468
+ invalidDropped += 1;
469
+ return false;
470
+ }
381
471
  // Map the core contract onto PostHog's capture shape: id/name/time move up, the rest are properties.
382
472
  // The feedback body is FLATTENED into `feedback_*` properties rather than sent as a nested object:
383
473
  // PostHog filters and breakdowns operate on top-level properties, so a nested `feedback.stack`
384
474
  // would be invisible to the exact "which stacks report the most bugs" question this exists to
385
475
  // answer. One prefix keeps them grouped in the UI without a nested path.
386
- const { anonymousId: distinctId, event: name, ts, sessionId: eventSessionId, feedback, session, project, verification, versionChange, crash, identity, connection, init, onboarding, bug, refusal, outage, instrumentation, ...rest } = event;
476
+ const { anonymousId: distinctId, event: name, ts, sessionId: eventSessionId, feedback, session, project, verification, versionChange, crash, identity, connection, init, onboarding, bug, refusal, outage, instrumentation, hud, link, harness, ...rest } = event;
387
477
  // `$session_id` is PostHog's OWN session property, so sending ours under that name lights up
388
478
  // its built-in session views and funnels for free rather than requiring custom HogQL everywhere.
389
479
  // `sessionId` rides only on events that happened inside a daemon run. A one-shot CLI command
@@ -415,6 +505,9 @@ export const createTelemetry = (opts) => {
415
505
  refusal,
416
506
  outage,
417
507
  instrumentation,
508
+ hud,
509
+ link,
510
+ harness,
418
511
  };
419
512
  for (const [prefix, block] of Object.entries(blocks)) {
420
513
  for (const [key, value] of Object.entries(block ?? {})) {
@@ -451,7 +544,7 @@ export const createTelemetry = (opts) => {
451
544
  }
452
545
  try {
453
546
  if (true === extra?.detach && opts.fetchImpl === undefined) {
454
- spawnDetached(process.execPath, ['-e', DETACHED_SEND_SCRIPT, url, body]);
547
+ spawnDetached(process.execPath, ['-e', DETACHED_SEND_SCRIPT, url], body);
455
548
  return false; // handed off, outcome unknowable from here
456
549
  }
457
550
  // Feedback is slower and retried; everything else keeps the fire-and-forget budget.
@@ -488,6 +581,23 @@ export const createTelemetry = (opts) => {
488
581
  };
489
582
  return { emit, enabled: true, firstRun };
490
583
  };
584
+ /**
585
+ * Events dropped because they failed the wire schema, this process. Local only: the bad payload is
586
+ * the thing that must not leave, so not even a count of it is sent from here.
587
+ */
588
+ let invalidDropped = 0;
589
+ export const droppedInvalidEvents = () => invalidDropped;
590
+ /** `RETICLE_INTERNAL=1`, or the machine-wide marker file. Unreadable home → not internal. */
591
+ const isInternal = (env, dir) => {
592
+ if ('1' === env[Env.INTERNAL] || 'true' === env[Env.INTERNAL])
593
+ return true;
594
+ try {
595
+ return existsSync(join(dir, INTERNAL_MARKER_FILE));
596
+ }
597
+ catch {
598
+ return false;
599
+ }
600
+ };
491
601
  /**
492
602
  * The process-wide emitter. One identity resolution + one opt-out check per process; both the CLI
493
603
  * lifecycle (install/invoke/session) and the per-tool hook in `runTool` share it.
@@ -17,4 +17,6 @@ import { type BrowserBrand, type Verification } from '@reticlehq/core';
17
17
  * `falseGreenCaught` is the one that matters: the assertion PASSED and Reticle still refused to call
18
18
  * it verified. That is the product's thesis reduced to a boolean.
19
19
  */
20
- export declare function verificationOf(toolName: string, result: Record<string, unknown>, durationMs: number, brand?: BrowserBrand): Verification | undefined;
20
+ export declare function verificationOf(toolName: string, result: Record<string, unknown>, durationMs: number, brand?: BrowserBrand,
21
+ /** The call ran inside a Harness drive's async context (`currentDrivenBy()`), read by the caller. */
22
+ drivenByHarness?: boolean): Verification | undefined;
@@ -13,7 +13,6 @@
13
13
  import { CaptureLoss, ReplayStatus, ReticleTool, VerificationDriver, Verified, VerifiedReason, } from '@reticlehq/core';
14
14
  import { VERDICT_TOOLS } from '../surface/tools/feedback-tools.js';
15
15
  import { getBrowserMode } from './browser-mode.js';
16
- import { harnessDriving } from './harness-drive.js';
17
16
  /**
18
17
  * The deciding clause, read off the result `decideVerified` wrote it onto.
19
18
  *
@@ -70,6 +69,7 @@ const REPLAY_VERDICTS = new Map([
70
69
  [ReplayStatus.OK, { verified: Verified.YES, passed: true }],
71
70
  [ReplayStatus.DRIFT, { verified: Verified.NO, passed: false }],
72
71
  [ReplayStatus.ERROR, { verified: Verified.UNKNOWN, passed: false }],
72
+ [ReplayStatus.UNVERIFIABLE, { verified: Verified.UNKNOWN, passed: false }],
73
73
  ]);
74
74
  function replayVerdict(toolName, status) {
75
75
  if (ReticleTool.FLOW_REPLAY !== toolName || 'string' !== typeof status)
@@ -114,7 +114,9 @@ function passedOf(result, status) {
114
114
  * `falseGreenCaught` is the one that matters: the assertion PASSED and Reticle still refused to call
115
115
  * it verified. That is the product's thesis reduced to a boolean.
116
116
  */
117
- export function verificationOf(toolName, result, durationMs, brand) {
117
+ export function verificationOf(toolName, result, durationMs, brand,
118
+ /** The call ran inside a Harness drive's async context (`currentDrivenBy()`), read by the caller. */
119
+ drivenByHarness = false) {
118
120
  if (!VERDICT_TOOLS.has(toolName))
119
121
  return undefined;
120
122
  // A paused session REFUSES the call — nothing driven, nothing asserted. The refusal carries a
@@ -122,6 +124,11 @@ export function verificationOf(toolName, result, durationMs, brand) {
122
124
  // here for work that happened.
123
125
  if (true === result['paused'])
124
126
  return undefined;
127
+ // A wait that stopped at the per-call limit is "not yet", not a verdict: it answers `pass: false`
128
+ // with `resume_ms`, and read here that became `verified: "no"`, so every paused wait was recorded
129
+ // as a red and advanced the feedback-prompt counter (#1119).
130
+ if ('number' === typeof result['resume_ms'])
131
+ return undefined;
125
132
  const replay = replayVerdict(toolName, result['status']);
126
133
  const verified = 'string' === typeof result['verified'] ? result['verified'] : (replay?.verified ?? undefined);
127
134
  // flow_verify reports `status: pass|fail|unverifiable`; assert reports a boolean `pass`. Accept
@@ -168,7 +175,9 @@ export function verificationOf(toolName, result, durationMs, brand) {
168
175
  // WHAT was lost, when the reason was that something was. Three owners, three fixes, one bar
169
176
  // until now.
170
177
  ...(uncleanLoss === undefined ? {} : { uncleanLoss }),
171
- // WHOSE drive this was. Absent is the ordinary case — the agent called the tool itself.
172
- ...(harnessDriving() ? { driven: VerificationDriver.HARNESS } : {}),
178
+ // WHOSE drive this was, read per call by the caller: a drive runs in the background while the
179
+ // agent keeps calling tools, so a process-wide flag credited the agent's verdicts too. Absent is
180
+ // the ordinary case — the agent called the tool itself.
181
+ ...(drivenByHarness ? { driven: VerificationDriver.HARNESS } : {}),
173
182
  };
174
183
  }
@@ -19,7 +19,7 @@ export declare function attachJournal(bridge: Bridge, deps: {
19
19
  fs: FileSystemPort;
20
20
  reticleRoot: string;
21
21
  enabled: boolean;
22
- takeAmbientTape?: () => {
22
+ takeAmbientTape?: (sessionId: string) => {
23
23
  steps: readonly TapeStep[];
24
24
  startPath?: string;
25
25
  } | undefined;
@@ -31,4 +31,4 @@ export declare function attachJournal(bridge: Bridge, deps: {
31
31
  author?: () => FlowFile['author'];
32
32
  /** What this project is willing to keep — the `retain` block of its `.reticle.json`. */
33
33
  retain?: PruneWorkspaceOptions;
34
- }): void;
34
+ }): () => Promise<void>;
@@ -8,11 +8,13 @@
8
8
  * the 1000-line backstop is what asked for the split.
9
9
  */
10
10
  import { artifactRootResolver } from './memory/project/artifact-root-resolver.js';
11
+ import { claimedArtifactRoot } from './memory/project/root-claims.js';
12
+ import { servingDirectoryOf } from './portal/session/serving-directory.js';
11
13
  import { originOf } from './portal/session/session-manager.js';
12
14
  import { Bridge } from './portal/bridge/bridge.js';
13
15
  import { FlowStore } from './language/flows/flows.js';
14
16
  import { makeJournalAttach } from './memory/journal/attach-journal.js';
15
- import { makeSessionEnd, recordDriveRun } from './memory/journal/session-end.js';
17
+ import { endLiveSessions, makeSessionEnd, recordDriveRun } from './memory/journal/session-end.js';
16
18
  import { attachDriveRunFlush } from './memory/journal/drive-run-flush.js';
17
19
  import { AmbientStore } from './memory/journal/ambient-store.js';
18
20
  import { ensureWorkspaceGitignore } from './memory/journal/on-disk/workspace-gitignore.js';
@@ -35,14 +37,20 @@ export function attachJournal(bridge, deps) {
35
37
  const ambientStore = new AmbientStore(deps.fs, deps.reticleRoot);
36
38
  // Built once, not per session: the resolver walks config discovery and the user-level registry,
37
39
  // and neither changes between two tabs connecting a second apart.
38
- const resolveArtifactRoot = artifactRootResolver(deps.reticleRoot);
40
+ const resolveArtifactRoot = artifactRootResolver(deps.reticleRoot, {
41
+ servingDirectory: servingDirectoryOf,
42
+ });
39
43
  bridge.attachSessionCreate((session) => {
40
44
  // Stamp the project's own `.reticle` before ANY counter fires for this session. Without it every
41
45
  // verdict is recorded against wherever the daemon was started, which is how one app's evidence
42
46
  // reached a different account's production dashboard.
43
47
  // The origin is passed for the case where the page never stamped a project id: it is the only
44
48
  // distinguishing fact left, and without it every such app shares one bucket.
45
- session.artifactRoot = resolveArtifactRoot(session.projectId, originOf(session.url)).root;
49
+ // A lease opened by `try`, a chat drive or `verify` carries the root of whoever opened it; the
50
+ // resolver would send a page with no project id to `unmatched/`, which nothing syncs.
51
+ session.artifactRoot =
52
+ claimedArtifactRoot(session.id, session.url) ??
53
+ resolveArtifactRoot(session.projectId, originOf(session.url)).root;
46
54
  // The project's config sits beside its `.reticle/`, so the declaration is read from the tab's
47
55
  // own project rather than from wherever the daemon was started.
48
56
  session.background = readBackgroundTraffic(findProjectConfig(dirname(session.artifactRoot)));
@@ -63,17 +71,20 @@ export function attachJournal(bridge, deps) {
63
71
  }
64
72
  });
65
73
  // Teardown: flush the journal tail to disk + persist what this session learned.
66
- bridge.attachSessionEnd(makeSessionEnd({
74
+ const teardown = makeSessionEnd({
67
75
  ...deps,
68
76
  // A drive is saved in the session's own project, where replay will look for it.
69
77
  ...(deps.flows === undefined
70
78
  ? {}
71
- : { flowsAt: (root) => new FlowStore(deps.fs, root, { now: Date.now }) }),
79
+ : {
80
+ flowsAt: (root) => new FlowStore(deps.fs, root, { now: Date.now }, deps.onRunPersisted === undefined ? {} : { onWrote: deps.onRunPersisted }),
81
+ }),
72
82
  ...(deps.retain === undefined ? {} : { retain: deps.retain }),
73
83
  // Retention runs from teardown, and it must not delete the journal of a session that is still
74
84
  // being written. The registry is the only thing that knows which those are.
75
85
  liveSessionIds: () => new Set(bridge.sessions.all().map((s) => s.id)),
76
- }));
86
+ });
87
+ bridge.attachSessionEnd(teardown);
77
88
  /*
78
89
  * And the same write, DURING the session rather than only at the end of it.
79
90
  *
@@ -89,6 +100,7 @@ export function attachJournal(bridge, deps) {
89
100
  if (deps.enabled) {
90
101
  attachDriveRunFlush({
91
102
  resolve: (sessionId) => bridge.sessions.get(sessionId),
103
+ all: () => bridge.sessions.all(),
92
104
  write: (session) => recordDriveRun(deps, session),
93
105
  });
94
106
  }
@@ -101,4 +113,6 @@ export function attachJournal(bridge, deps) {
101
113
  // under which nothing ever deleted what was already there. Visual diffs, feedback copies and run
102
114
  // artifacts do not need the journal to be written at all and kept accumulating regardless.
103
115
  void pruneWorkspace(deps.fs, deps.reticleRoot, new Set(bridge.sessions.all().map((s) => s.id)), deps.retain ?? {});
116
+ // For a closing daemon: tear down the tabs still open, awaited, before its last sync.
117
+ return () => endLiveSessions(bridge.sessions, teardown);
104
118
  }
package/docs/README.md CHANGED
@@ -27,7 +27,7 @@ Everything here is published to [docs.reticle.sh](https://docs.reticle.sh) by `d
27
27
  | [actions.mdx](actions.mdx) | every action and its arguments, including `press` and its history |
28
28
  | [environment.mdx](environment.mdx) | every environment variable Reticle reads, what it changes, and which process reads it |
29
29
  | [faq.mdx](faq.mdx) | production, frameworks, comparisons, and the honest limits |
30
- | [tools/overview.mdx](tools/overview.mdx) | the 18 advertised tools, the 30 in the cold tail, and why |
30
+ | [tools/overview.mdx](tools/overview.mdx) | the ten advertised tools, the rest reachable on demand, and why |
31
31
  | [tools/snapshot.mdx](tools/snapshot.mdx) | `reticle_look { action: "page" }`: three modes, from full tree to a 25-token route check |
32
32
  | [tools/query.mdx](tools/query.mdx) | `reticle_look { action: "find" }` finds elements by their reported roles, names and labels |
33
33
  | [tools/inspect.mdx](tools/inspect.mdx) | `reticle_look { action: "element" }`: one element, down to source and design tokens |
@@ -42,7 +42,7 @@ Everything here is published to [docs.reticle.sh](https://docs.reticle.sh) by `d
42
42
  | [tools/wait-for.mdx](tools/wait-for.mdx) | `reticle_assert { action: "wait" }`, for consequences you did not cause |
43
43
  | [tools/assert.mdx](tools/assert.mdx) | `reticle_assert`: verdicts, and a real failure explained |
44
44
  | [tools/sessions.mdx](tools/sessions.mdx) | `reticle_session { action: "list" }`: the health fields that decide if driving works |
45
- | [tools/tools-and-run.mdx](tools/tools-and-run.mdx) | `reticle_tools` / `reticle_run`, reaching the other 30 |
45
+ | [tools/tools-and-run.mdx](tools/tools-and-run.mdx) | `reticle_tools` / `reticle_run`, reaching the tools that are not advertised |
46
46
  | [tools/session-and-feedback.mdx](tools/session-and-feedback.mdx) | `reticle_session` / `reticle_session { action: "feedback" }`, the human boundary |
47
47
  | [packages.mdx](packages.mdx) | every library at a glance: what it does, why it exists, when you need it |
48
48
  | [packages/](packages/) | one page per published package, with its real exported API and dependencies |
@@ -76,7 +76,7 @@ Everything here is published to [docs.reticle.sh](https://docs.reticle.sh) by `d
76
76
  | [vs-screenshots.mdx](vs-screenshots.mdx) | why a better vision model does not fix a non-visual bug |
77
77
  | [what-is-recorded.md](what-is-recorded.md) | what Reticle keeps, what is redacted, and what it takes for any of it to leave your machine |
78
78
  | [telemetry.md](telemetry.md) | what is collected, and how to turn it off |
79
- | [local-registry.md](local-registry.md) | installing an unpublished build |
79
+ | [local-registry.md](https://github.com/reticlehq/reticle/blob/main/docs/local-registry.md) | installing an unpublished build |
80
80
  | [license-activation.mdx](license-activation.mdx) | you have a key: where to set it, how to confirm it, what to do when it fails |
81
81
  | [enterprise.md](enterprise.md) | the licensed surface |
82
82
 
package/docs/actions.mdx CHANGED
@@ -22,8 +22,11 @@ Every action Reticle can perform takes the same shape: a `ref` from [`reticle_lo
22
22
  | `select` | `{ value }` | For `<select>` |
23
23
  | `check` / `uncheck` | none | Checkbox and radio, or a `role="checkbox"`/`role="switch"` element (fails if `aria-checked` does not change) |
24
24
  | `submit` | none | Submits the element's `<form>` |
25
- | `press` | `{ text }` | The key **name**: `Escape`, `Tab`, `Enter` |
25
+ | `press` | `{ text, modifiers?, holdMs?, keys?, code? }` | `text` is the key **name**: `Escape`, `Tab`, `Enter`. `key` is an accepted alias. `modifiers` is an array of `Meta`, `Control`, `Shift`, `Alt`. `holdMs` holds the key down; `keys` holds several together; `code` names the physical key |
26
26
  | `scrollIntoView` | none | |
27
+ | `scroll` | `{ dy?, dx?, fraction? }` | Scrolls the nearest scrollable container (or the page, with no `ref`) by `dy`/`dx` pixels, either direction. `fraction` (0 to 1) jumps to that point of the height. No args steps down most of a screen |
28
+ | `tap` | `{ holdMs? }` | A touch tap: pointer and touch events, then `click`. `holdMs` makes it a long press |
29
+ | `zoom` | none | Page zoom. Refused inside the page, because CSS zoom changes how a page looks without changing its layout, and a passing check on it would be false |
27
30
  | `upload` | `{ content?, name?, type?, path? }` | Sets a file on `<input type="file">`. Inline bytes default to `"reticle test file"` / `"file.txt"` / `"text/plain"`. `path` reads a file from disk, scoped to the project root plus any opt-in directories listed in `.reticle.json` as `"uploadRoots": ["~/Downloads", "/Volumes/fixtures"]`. A refusal names every allowed root. |
28
31
  | `drag` | `{ toRef }` | Pointer-based drag (dnd-kit, react-beautiful-dnd) plus HTML5 DnD. `target` is an alias |
29
32
 
@@ -71,7 +74,7 @@ This one has history worth knowing. The implementation used to read `args.key` a
71
74
 
72
75
  Three consequences, worst last: the requested key never arrived, so Escape-to-close and Tab-traversal went unverified while looking verified; nothing in the result said the argument had been ignored; and `Enter` is not a neutral substitute. On a focused field inside a form it **submits it**. A request to close a dialog could file the form behind it.
73
76
 
74
- Two field reports were exactly this, both diagnosed as "synthetic events don't reach the app". Wrong root cause: the event reached the app perfectly well and simply said `Enter`.
77
+ This is often misdiagnosed as "synthetic events don't reach the app". That is the wrong root cause: the event reached the app perfectly well and simply said `Enter`.
75
78
 
76
79
  </Warning>
77
80
 
@@ -112,7 +115,7 @@ Several actions in one round trip:
112
115
 
113
116
  Fields sitting at their uninformative default are **omitted**, so a clean action collapses to its consequence. A missing `visible` means `true`, not `false`. Read an absence as "nothing to report" rather than as a failure.
114
117
 
115
- `occluded` is the answer to a large share of "the button doesn't work" reports: the click landed on the modal overlay sitting on top of it.
118
+ `occluded` is often the answer to "the button doesn't work": the click landed on the modal overlay sitting on top of it.
116
119
 
117
120
  <Card title="Full field-by-field walkthrough" icon="hand-pointer" href="/tools/act">
118
121
  What each effect field tells you, with a real response.
package/docs/adapters.md CHANGED
@@ -72,4 +72,4 @@ A **realm adapter** teaches Reticle about a kind of app that is not a browser ta
72
72
 
73
73
  If you want to write either, open an issue and say what you are building. The interfaces exist; what is missing is the door.
74
74
 
75
- A template for each of the four kinds, including the two that are contributable today, is in [`adapters/CONTRIBUTING.md`](https://github.com/reticlehq/reticle/blob/main/adapters/CONTRIBUTING.md). It carries the rules each adapter kind must hold to, and why each rule exists.
75
+ A template for each kind is in [`adapters/CONTRIBUTING.md`](https://github.com/reticlehq/reticle/blob/main/adapters/CONTRIBUTING.md). It also covers a fourth kind, lint (an ordinary ESLint plugin such as `@reticlehq/eslint-plugin`, which needs no registration and so is also contributable today), and carries the rules each kind must hold to, and why each rule exists.