@reticlehq/server 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (614) hide show
  1. package/SKILL.md +122 -123
  2. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  3. package/dist/command/cli/adhoc-suite.js +42 -7
  4. package/dist/command/cli/adhoc-verdict.d.ts +18 -2
  5. package/dist/command/cli/adhoc-verdict.js +70 -6
  6. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  7. package/dist/command/cli/answers/gate-exit.js +45 -0
  8. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  9. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  10. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  11. package/dist/command/cli/auth/device-flow.js +17 -0
  12. package/dist/command/cli/cli-doctor.js +14 -0
  13. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  14. package/dist/command/cli/cli-flow-commands.js +28 -105
  15. package/dist/command/cli/cli-kill.js +3 -2
  16. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  17. package/dist/command/cli/cli-parse-grammar.js +75 -0
  18. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  19. package/dist/command/cli/cli-parse-verify.js +18 -0
  20. package/dist/command/cli/cli-parse.d.ts +19 -28
  21. package/dist/command/cli/cli-parse.js +82 -182
  22. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  23. package/dist/command/cli/cli-update-commands.js +61 -9
  24. package/dist/command/cli/cli-usage.d.ts +33 -0
  25. package/dist/command/cli/cli-usage.js +287 -0
  26. package/dist/command/cli/cli-verify.d.ts +34 -4
  27. package/dist/command/cli/cli-verify.js +81 -12
  28. package/dist/command/cli/cloud-cli.d.ts +13 -0
  29. package/dist/command/cli/cloud-cli.js +145 -333
  30. package/dist/command/cli/cloud-kit.d.ts +12 -0
  31. package/dist/command/cli/cloud-kit.js +41 -2
  32. package/dist/command/cli/cloud-link.d.ts +57 -0
  33. package/dist/command/cli/cloud-link.js +308 -0
  34. package/dist/command/cli/cloud-login.d.ts +15 -1
  35. package/dist/command/cli/cloud-login.js +67 -13
  36. package/dist/command/cli/context-command.d.ts +1 -0
  37. package/dist/command/cli/context-command.js +33 -0
  38. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  39. package/dist/command/cli/daemon-start-options.js +24 -3
  40. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  41. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  42. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  43. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  44. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  45. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  46. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  47. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  48. package/dist/command/cli/known-regression.d.ts +13 -0
  49. package/dist/command/cli/known-regression.js +34 -0
  50. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  51. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  52. package/dist/command/cli/lifecycle/daemon-lifecycle.js +11 -2
  53. package/dist/command/cli/mcp-command.d.ts +6 -0
  54. package/dist/command/cli/mcp-command.js +13 -5
  55. package/dist/command/cli/ports/port-holder.js +1 -1
  56. package/dist/command/cli/project-name.d.ts +29 -1
  57. package/dist/command/cli/project-name.js +107 -2
  58. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  59. package/dist/command/cli/setup-mcp-cli.js +29 -8
  60. package/dist/command/cli/status/status-lines.d.ts +1 -0
  61. package/dist/command/cli/status/status-lines.js +47 -2
  62. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  63. package/dist/command/cli/status/workspace-links.js +29 -0
  64. package/dist/command/cli/try-command.d.ts +96 -0
  65. package/dist/command/cli/try-command.js +362 -0
  66. package/dist/command/cli/tutorial.d.ts +0 -100
  67. package/dist/command/cli/tutorial.js +0 -178
  68. package/dist/command/cli/verify-results.d.ts +19 -0
  69. package/dist/command/cli/verify-results.js +29 -0
  70. package/dist/command/cli-onboarding.d.ts +0 -11
  71. package/dist/command/cli-onboarding.js +0 -15
  72. package/dist/command/cli.d.ts +14 -0
  73. package/dist/command/cli.js +103 -83
  74. package/dist/command/daemon/daemon-resilience.js +4 -4
  75. package/dist/command/daemon/daemon-resolve.d.ts +9 -1
  76. package/dist/command/daemon/daemon-resolve.js +49 -10
  77. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  78. package/dist/command/setup/bringup/bridge-port.js +13 -3
  79. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  80. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  81. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  82. package/dist/command/setup/init/agent-restart.js +28 -0
  83. package/dist/command/setup/init/init-port.d.ts +10 -1
  84. package/dist/command/setup/init/init-port.js +22 -2
  85. package/dist/command/setup/init/init-runtime.d.ts +12 -2
  86. package/dist/command/setup/init/init-runtime.js +96 -37
  87. package/dist/command/setup/node-effects.d.ts +2 -0
  88. package/dist/command/setup/node-effects.js +36 -8
  89. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  90. package/dist/command/setup/probe/existing-app.js +14 -0
  91. package/dist/command/setup/remaining-steps.js +1 -1
  92. package/dist/command/setup/run-setup.d.ts +29 -9
  93. package/dist/command/setup/run-setup.js +34 -28
  94. package/dist/command/setup/setup-command.d.ts +23 -0
  95. package/dist/command/setup/setup-command.js +57 -4
  96. package/dist/command/setup/setup-mcp.js +25 -2
  97. package/dist/command/setup/tauri-signing.d.ts +19 -0
  98. package/dist/command/setup/tauri-signing.js +79 -0
  99. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  100. package/dist/command/setup/terminal/listeners.js +37 -6
  101. package/dist/command/update/update-nudge.d.ts +9 -0
  102. package/dist/command/update/update-nudge.js +1 -1
  103. package/dist/command/update/updater.js +11 -15
  104. package/dist/command/version/version-nudge.js +3 -0
  105. package/dist/command/version/version-skew.d.ts +20 -1
  106. package/dist/command/version/version-skew.js +38 -2
  107. package/dist/features/crawl/crawl.js +14 -1
  108. package/dist/features/exhaust/ledger.d.ts +14 -14
  109. package/dist/features/harness/drive-report.d.ts +39 -5
  110. package/dist/features/harness/drive-report.js +271 -54
  111. package/dist/features/harness/drive-runs.d.ts +120 -0
  112. package/dist/features/harness/drive-runs.js +289 -0
  113. package/dist/features/harness/drivers.d.ts +1 -1
  114. package/dist/features/harness/drivers.js +1 -1
  115. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  116. package/dist/features/harness/explore/console-pages.js +146 -0
  117. package/dist/features/harness/explore/disparity.d.ts +19 -0
  118. package/dist/features/harness/explore/disparity.js +71 -0
  119. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  120. package/dist/features/harness/explore/fake-app.js +49 -0
  121. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  122. package/dist/features/harness/explore/goal-search.js +144 -0
  123. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  124. package/dist/features/harness/explore/page-tree.js +148 -0
  125. package/dist/features/harness/explore/site-map.d.ts +34 -0
  126. package/dist/features/harness/explore/site-map.js +150 -0
  127. package/dist/features/harness/goals.d.ts +68 -7
  128. package/dist/features/harness/goals.js +289 -36
  129. package/dist/features/harness/harness.d.ts +30 -1
  130. package/dist/features/harness/harness.js +141 -7
  131. package/dist/features/harness/platform/local-apps.d.ts +36 -3
  132. package/dist/features/harness/platform/local-apps.js +81 -5
  133. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  134. package/dist/features/harness/platform/persona-credentials.js +69 -0
  135. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  136. package/dist/features/harness/platform/platform-drives.js +114 -0
  137. package/dist/features/harness/platform/refusal.d.ts +52 -0
  138. package/dist/features/harness/platform/refusal.js +71 -0
  139. package/dist/features/harness/platform/remote-drive.d.ts +8 -2
  140. package/dist/features/harness/platform/remote-drive.js +22 -9
  141. package/dist/features/harness/platform/script.d.ts +57 -11
  142. package/dist/features/harness/platform/script.js +144 -12
  143. package/dist/features/harness/platform/server-driver.d.ts +17 -4
  144. package/dist/features/harness/platform/server-driver.js +29 -26
  145. package/dist/features/harness/platform-config.d.ts +38 -5
  146. package/dist/features/harness/platform-config.js +93 -8
  147. package/dist/features/harness/route-guess.d.ts +13 -0
  148. package/dist/features/harness/route-guess.js +49 -0
  149. package/dist/features/harness/script/script-run.d.ts +30 -1
  150. package/dist/features/harness/script/script-run.js +355 -48
  151. package/dist/features/license/license.d.ts +2 -2
  152. package/dist/features/visual/step-shots.d.ts +31 -0
  153. package/dist/features/visual/step-shots.js +231 -0
  154. package/dist/features/visual/visual-tools.js +22 -14
  155. package/dist/hooks/client-directory.d.ts +18 -0
  156. package/dist/hooks/client-directory.js +57 -0
  157. package/dist/hooks/coding-agents.d.ts +34 -0
  158. package/dist/hooks/coding-agents.js +117 -0
  159. package/dist/hooks/driven-by.d.ts +21 -2
  160. package/dist/hooks/driven-by.js +42 -2
  161. package/dist/hooks/hook-bus.d.ts +4 -0
  162. package/dist/hooks/hook-bus.js +18 -0
  163. package/dist/index.d.ts +1 -0
  164. package/dist/index.js +26 -183
  165. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  166. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  167. package/dist/judgement/capsule/causal-summary.js +33 -0
  168. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  169. package/dist/judgement/runs/artifact/build-verification-run.js +20 -4
  170. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  171. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  172. package/dist/judgement/runs/artifact/replay-mapping.js +25 -9
  173. package/dist/judgement/runs/artifact/run-store.d.ts +13 -1
  174. package/dist/judgement/runs/artifact/run-store.js +175 -8
  175. package/dist/judgement/runs/context-tools.js +59 -1
  176. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  177. package/dist/judgement/runs/default-run-id.js +16 -0
  178. package/dist/judgement/runs/drive-run.d.ts +53 -5
  179. package/dist/judgement/runs/drive-run.js +234 -20
  180. package/dist/judgement/runs/resume.d.ts +44 -0
  181. package/dist/judgement/runs/resume.js +137 -0
  182. package/dist/judgement/runs/reticle-runner.js +5 -2
  183. package/dist/judgement/runs/runner-port.d.ts +5 -1
  184. package/dist/judgement/runs/runner-port.js +8 -2
  185. package/dist/judgement/runs/verification-sync.d.ts +2 -0
  186. package/dist/judgement/runs/verification-sync.js +36 -15
  187. package/dist/language/flows/decision.js +2 -1
  188. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  189. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  190. package/dist/language/flows/flow-anchor.d.ts +7 -2
  191. package/dist/language/flows/flow-anchor.js +10 -3
  192. package/dist/language/flows/flow-intent.d.ts +1 -0
  193. package/dist/language/flows/flow-journey.d.ts +6 -0
  194. package/dist/language/flows/flow-journey.js +20 -0
  195. package/dist/language/flows/flow-learning.d.ts +4 -0
  196. package/dist/language/flows/flow-learning.js +37 -3
  197. package/dist/language/flows/flow-replay-run.js +16 -18
  198. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  199. package/dist/language/flows/flow-replay.d.ts +18 -1
  200. package/dist/language/flows/flow-replay.js +22 -7
  201. package/dist/language/flows/flow-result.d.ts +22 -1
  202. package/dist/language/flows/flow-result.js +47 -2
  203. package/dist/language/flows/flow-step-runners.d.ts +2 -0
  204. package/dist/language/flows/flow-step-runners.js +12 -6
  205. package/dist/language/flows/flow-store-for-session.js +5 -1
  206. package/dist/language/flows/flow-tools.d.ts +10 -0
  207. package/dist/language/flows/flow-tools.js +61 -62
  208. package/dist/language/flows/flows.d.ts +16 -1
  209. package/dist/language/flows/flows.js +69 -10
  210. package/dist/language/flows/narrow-write.d.ts +7 -0
  211. package/dist/language/flows/narrow-write.js +36 -1
  212. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  213. package/dist/language/flows/recording/tape/recordings.d.ts +29 -1
  214. package/dist/language/flows/recording/tape/recordings.js +60 -10
  215. package/dist/language/flows/replay.js +29 -6
  216. package/dist/language/flows/single-replay.d.ts +7 -0
  217. package/dist/language/flows/single-replay.js +26 -0
  218. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  219. package/dist/language/flows/verify-change-tools.js +200 -193
  220. package/dist/memory/cloud/cloud-config.d.ts +10 -1
  221. package/dist/memory/cloud/cloud-config.js +19 -5
  222. package/dist/memory/cloud/cloud-sync.js +3 -3
  223. package/dist/memory/cloud/harness-config.d.ts +49 -0
  224. package/dist/memory/cloud/harness-config.js +16 -20
  225. package/dist/memory/cloud/memory-scope.d.ts +17 -0
  226. package/dist/memory/cloud/memory-scope.js +22 -0
  227. package/dist/memory/cloud/sync-cycle.d.ts +32 -4
  228. package/dist/memory/cloud/sync-cycle.js +113 -12
  229. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  230. package/dist/memory/cloud/sync-daemon.js +114 -4
  231. package/dist/memory/cloud/sync-disk.js +26 -2
  232. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  233. package/dist/memory/cloud/sync-screenshots.js +105 -0
  234. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  235. package/dist/memory/cloud/unsynced-roots.js +166 -0
  236. package/dist/memory/impact/account-watch.d.ts +16 -1
  237. package/dist/memory/impact/account-watch.js +26 -1
  238. package/dist/memory/impact/impact-store.d.ts +1 -4
  239. package/dist/memory/impact/impact-store.js +32 -42
  240. package/dist/memory/intent/inline-intent.d.ts +1 -0
  241. package/dist/memory/intent/intent-shard-store.js +16 -4
  242. package/dist/memory/intent/intent-shard.d.ts +12 -0
  243. package/dist/memory/intent/intent-store.d.ts +1 -0
  244. package/dist/memory/intent/intent-tools.js +42 -2
  245. package/dist/memory/intent/open-intents.d.ts +6 -0
  246. package/dist/memory/intent/open-intents.js +10 -1
  247. package/dist/memory/intent/settled-words.d.ts +24 -0
  248. package/dist/memory/intent/settled-words.js +130 -0
  249. package/dist/memory/journal/drive-flow.d.ts +16 -0
  250. package/dist/memory/journal/drive-flow.js +34 -2
  251. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  252. package/dist/memory/journal/drive-run-flush.js +20 -5
  253. package/dist/memory/journal/journal-recorder.js +46 -3
  254. package/dist/memory/journal/on-disk/retention.d.ts +5 -0
  255. package/dist/memory/journal/on-disk/retention.js +27 -2
  256. package/dist/memory/journal/on-disk/workspace-tiers.js +2 -0
  257. package/dist/memory/journal/session-end.d.ts +15 -1
  258. package/dist/memory/journal/session-end.js +38 -7
  259. package/dist/memory/project/artifact-root-resolver.js +33 -5
  260. package/dist/memory/project/artifact-root.d.ts +4 -3
  261. package/dist/memory/project/artifact-root.js +2 -2
  262. package/dist/memory/project/dir/reticle-dir.d.ts +14 -0
  263. package/dist/memory/project/dir/reticle-dir.js +23 -2
  264. package/dist/memory/project/link-directory.d.ts +15 -0
  265. package/dist/memory/project/link-directory.js +44 -0
  266. package/dist/memory/project/root-claims.d.ts +6 -0
  267. package/dist/memory/project/root-claims.js +39 -0
  268. package/dist/memory/project/session-root.d.ts +2 -0
  269. package/dist/memory/project/session-root.js +9 -1
  270. package/dist/memory/project/sync-status.d.ts +46 -0
  271. package/dist/memory/project/sync-status.js +135 -1
  272. package/dist/memory/recall/memory-tools.js +46 -3
  273. package/dist/memory/recall/platform-memory.d.ts +34 -0
  274. package/dist/memory/recall/platform-memory.js +139 -0
  275. package/dist/memory/recall/project-memory.js +36 -8
  276. package/dist/portal/bridge/bridge.d.ts +9 -5
  277. package/dist/portal/bridge/bridge.js +66 -23
  278. package/dist/portal/bridge/harness-request.d.ts +23 -0
  279. package/dist/portal/bridge/harness-request.js +27 -0
  280. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  281. package/dist/portal/bridge/wrong-path.js +35 -0
  282. package/dist/portal/input/network-mock-tools.js +11 -2
  283. package/dist/portal/input/real-input.d.ts +2 -0
  284. package/dist/portal/input/real-input.js +13 -10
  285. package/dist/portal/pool/browser-pool.d.ts +48 -0
  286. package/dist/portal/pool/browser-pool.js +120 -2
  287. package/dist/portal/pool/context-permissions.d.ts +33 -0
  288. package/dist/portal/pool/context-permissions.js +33 -0
  289. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  290. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  291. package/dist/portal/pool/playwright-launcher.d.ts +27 -5
  292. package/dist/portal/pool/playwright-launcher.js +59 -14
  293. package/dist/portal/pool/pool-contract.d.ts +21 -1
  294. package/dist/portal/session/agent-link.d.ts +8 -0
  295. package/dist/portal/session/agent-link.js +17 -0
  296. package/dist/portal/session/command-payload.js +6 -1
  297. package/dist/portal/session/daemon-answers.d.ts +3 -3
  298. package/dist/portal/session/daemon-answers.js +4 -2
  299. package/dist/portal/session/dev-server/dev-command.d.ts +9 -0
  300. package/dist/portal/session/dev-server/dev-command.js +27 -1
  301. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  302. package/dist/portal/session/facts/observed-state.js +46 -3
  303. package/dist/portal/session/human/live-control.d.ts +9 -2
  304. package/dist/portal/session/human/live-control.js +12 -3
  305. package/dist/portal/session/live-control-tools.js +82 -13
  306. package/dist/portal/session/narration-args.d.ts +5 -0
  307. package/dist/portal/session/narration-args.js +17 -0
  308. package/dist/portal/session/no-session-diagnosis.d.ts +1 -1
  309. package/dist/portal/session/no-session-diagnosis.js +31 -9
  310. package/dist/portal/session/no-session-next-action.d.ts +20 -0
  311. package/dist/portal/session/no-session-next-action.js +134 -61
  312. package/dist/portal/session/no-session-watch.js +179 -22
  313. package/dist/portal/session/presence/session-lease.js +1 -1
  314. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  315. package/dist/portal/session/recorded-gaps.js +251 -0
  316. package/dist/portal/session/session-health.d.ts +11 -0
  317. package/dist/portal/session/session-health.js +3 -1
  318. package/dist/portal/session/session-info.js +2 -1
  319. package/dist/portal/session/session-manager.d.ts +18 -0
  320. package/dist/portal/session/session-manager.js +54 -3
  321. package/dist/portal/session/session-successor.d.ts +8 -0
  322. package/dist/portal/session/session-successor.js +1 -1
  323. package/dist/portal/session/session.d.ts +15 -28
  324. package/dist/portal/session/session.js +60 -61
  325. package/dist/portal/session/timing/command-timeout.js +25 -1
  326. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  327. package/dist/portal/session/timing/wall-clock.js +1 -1
  328. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  329. package/dist/portal/session/zero-install-first-call.js +88 -0
  330. package/dist/start-options.d.ts +7 -1
  331. package/dist/start-wiring.d.ts +63 -0
  332. package/dist/start-wiring.js +169 -0
  333. package/dist/status-payload.d.ts +13 -1
  334. package/dist/status-payload.js +13 -1
  335. package/dist/surface/http-server.js +7 -1
  336. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  337. package/dist/surface/mcp/attach-memory.js +12 -1
  338. package/dist/surface/mcp/mcp-proxy.d.ts +4 -0
  339. package/dist/surface/mcp/mcp-proxy.js +29 -8
  340. package/dist/surface/mcp/mcp.d.ts +23 -0
  341. package/dist/surface/mcp/mcp.js +34 -4
  342. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  343. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  344. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  345. package/dist/surface/mcp/server-instructions.js +22 -14
  346. package/dist/surface/mcp/shared-params.js +1 -1
  347. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  348. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  349. package/dist/surface/tools/account-tool.d.ts +22 -0
  350. package/dist/surface/tools/account-tool.js +157 -0
  351. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  352. package/dist/surface/tools/act/act-danger.js +38 -1
  353. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  354. package/dist/surface/tools/act/act-observation.js +57 -0
  355. package/dist/surface/tools/act/act-preflight.js +25 -2
  356. package/dist/surface/tools/act/act-target.js +8 -3
  357. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  358. package/dist/surface/tools/act/resolve-target.js +18 -3
  359. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  360. package/dist/surface/tools/act/screen-request.js +113 -0
  361. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  362. package/dist/surface/tools/act/sequence-grade.js +13 -2
  363. package/dist/surface/tools/act-sequence-tool.js +136 -27
  364. package/dist/surface/tools/act-tools.d.ts +0 -9
  365. package/dist/surface/tools/act-tools.js +48 -34
  366. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  367. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  368. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  369. package/dist/surface/tools/agent/app-notes.js +48 -0
  370. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  371. package/dist/surface/tools/agent/build-staleness.js +62 -0
  372. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  373. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  374. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  375. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  376. package/dist/surface/tools/agent/notices.d.ts +50 -0
  377. package/dist/surface/tools/agent/notices.js +152 -0
  378. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  379. package/dist/surface/tools/agent/reteach.js +50 -0
  380. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  381. package/dist/surface/tools/args/alias-args.js +10 -0
  382. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  383. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  384. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  385. package/dist/surface/tools/assert/assert-source.js +40 -0
  386. package/dist/surface/tools/assert/assert-verdict.js +25 -15
  387. package/dist/surface/tools/browser-tools.js +43 -1
  388. package/dist/surface/tools/chat-drives.d.ts +75 -0
  389. package/dist/surface/tools/chat-drives.js +265 -21
  390. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  391. package/dist/surface/tools/coverage-tools.js +2 -53
  392. package/dist/surface/tools/dynamic-tools.js +29 -1
  393. package/dist/surface/tools/empty-session-list.d.ts +10 -0
  394. package/dist/surface/tools/empty-session-list.js +45 -5
  395. package/dist/surface/tools/error-recovery.d.ts +8 -0
  396. package/dist/surface/tools/error-recovery.js +69 -5
  397. package/dist/surface/tools/explore-tools.d.ts +23 -2
  398. package/dist/surface/tools/explore-tools.js +377 -74
  399. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  400. package/dist/surface/tools/feedback-tools.js +4 -3
  401. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  402. package/dist/surface/tools/gap-novelty.js +8 -1
  403. package/dist/surface/tools/harness-explore.d.ts +52 -73
  404. package/dist/surface/tools/harness-explore.js +177 -146
  405. package/dist/surface/tools/harness-gate.d.ts +88 -0
  406. package/dist/surface/tools/harness-gate.js +235 -0
  407. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  408. package/dist/surface/tools/harness-hunt.js +215 -0
  409. package/dist/surface/tools/harness-plan.d.ts +5 -0
  410. package/dist/surface/tools/harness-plan.js +7 -0
  411. package/dist/surface/tools/harness-script.d.ts +22 -0
  412. package/dist/surface/tools/harness-script.js +256 -38
  413. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  414. package/dist/surface/tools/harness-tab-guard.js +27 -0
  415. package/dist/surface/tools/harness-toolset.d.ts +8 -0
  416. package/dist/surface/tools/harness-toolset.js +27 -4
  417. package/dist/surface/tools/human-notes.d.ts +16 -0
  418. package/dist/surface/tools/human-notes.js +27 -0
  419. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  420. package/dist/surface/tools/invoke-tool.js +220 -93
  421. package/dist/surface/tools/lease-hint.js +26 -5
  422. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  423. package/dist/surface/tools/lease-permissions.js +73 -0
  424. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  425. package/dist/surface/tools/lease-readiness.js +57 -0
  426. package/dist/surface/tools/lease-seed.d.ts +20 -0
  427. package/dist/surface/tools/lease-seed.js +45 -1
  428. package/dist/surface/tools/lease-tools.d.ts +10 -1
  429. package/dist/surface/tools/lease-tools.js +119 -69
  430. package/dist/surface/tools/live-call-text.js +2 -2
  431. package/dist/surface/tools/merge-tools.js +42 -2
  432. package/dist/surface/tools/merged-name-redirect.js +4 -0
  433. package/dist/surface/tools/next-step.d.ts +11 -1
  434. package/dist/surface/tools/next-step.js +73 -18
  435. package/dist/surface/tools/observe-tools.js +43 -5
  436. package/dist/surface/tools/platform-moment.d.ts +60 -0
  437. package/dist/surface/tools/platform-moment.js +132 -4
  438. package/dist/surface/tools/read-tools.js +65 -14
  439. package/dist/surface/tools/reticle-result.d.ts +120 -0
  440. package/dist/surface/tools/reticle-result.js +364 -0
  441. package/dist/surface/tools/tool-kit.d.ts +68 -2
  442. package/dist/surface/tools/tool-kit.js +73 -1
  443. package/dist/surface/tools/tools.js +25 -13
  444. package/dist/telemetry/account-envelope.d.ts +7 -0
  445. package/dist/telemetry/account-envelope.js +61 -0
  446. package/dist/telemetry/agent-client.d.ts +15 -0
  447. package/dist/telemetry/agent-client.js +57 -0
  448. package/dist/telemetry/app-instrumented.js +9 -2
  449. package/dist/telemetry/argument-shape.d.ts +7 -0
  450. package/dist/telemetry/argument-shape.js +86 -1
  451. package/dist/telemetry/automation-hint.d.ts +2 -3
  452. package/dist/telemetry/automation-hint.js +33 -8
  453. package/dist/telemetry/cli-telemetry.js +7 -2
  454. package/dist/telemetry/daemon-telemetry.js +3 -0
  455. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  456. package/dist/telemetry/error-fingerprint.js +61 -5
  457. package/dist/telemetry/feedback-cli.d.ts +0 -13
  458. package/dist/telemetry/feedback-cli.js +0 -77
  459. package/dist/telemetry/feedback.d.ts +13 -0
  460. package/dist/telemetry/feedback.js +183 -17
  461. package/dist/telemetry/harness-run.d.ts +18 -0
  462. package/dist/telemetry/harness-run.js +80 -0
  463. package/dist/telemetry/hud-events.d.ts +16 -0
  464. package/dist/telemetry/hud-events.js +27 -0
  465. package/dist/telemetry/hud-metrics.d.ts +27 -6
  466. package/dist/telemetry/hud-metrics.js +99 -25
  467. package/dist/telemetry/init-telemetry.js +2 -2
  468. package/dist/telemetry/install-source.d.ts +13 -25
  469. package/dist/telemetry/install-source.js +44 -3
  470. package/dist/telemetry/mcp-connection.d.ts +0 -14
  471. package/dist/telemetry/mcp-connection.js +5 -1
  472. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  473. package/dist/telemetry/onboarding-firsts.js +81 -6
  474. package/dist/telemetry/platform-linked.d.ts +5 -0
  475. package/dist/telemetry/platform-linked.js +32 -0
  476. package/dist/telemetry/project-profile.js +5 -3
  477. package/dist/telemetry/proxy-telemetry.js +4 -1
  478. package/dist/telemetry/session-metrics.d.ts +15 -4
  479. package/dist/telemetry/session-metrics.js +88 -52
  480. package/dist/telemetry/telemetry.d.ts +26 -2
  481. package/dist/telemetry/telemetry.js +102 -21
  482. package/dist/telemetry/verification-of.d.ts +3 -1
  483. package/dist/telemetry/verification-of.js +12 -4
  484. package/dist/wire-journal.d.ts +2 -2
  485. package/dist/wire-journal.js +16 -5
  486. package/docs/README.md +2 -2
  487. package/docs/actions.mdx +6 -3
  488. package/docs/adapters.md +1 -1
  489. package/docs/agent-cheatsheet.md +24 -27
  490. package/docs/architecture.md +5 -5
  491. package/docs/autodrive.md +13 -12
  492. package/docs/benchmarks.md +5 -5
  493. package/docs/best-practices.mdx +27 -9
  494. package/docs/capabilities.mdx +14 -16
  495. package/docs/cli/affected.mdx +1 -1
  496. package/docs/cli/cloud.mdx +54 -75
  497. package/docs/cli/doctor.mdx +8 -3
  498. package/docs/cli/drive.mdx +12 -12
  499. package/docs/cli/feedback.mdx +3 -3
  500. package/docs/cli/gate.mdx +7 -2
  501. package/docs/cli/help.mdx +50 -55
  502. package/docs/cli/init.mdx +32 -15
  503. package/docs/cli/license.mdx +12 -8
  504. package/docs/cli/mcp.mdx +4 -4
  505. package/docs/cli/open.mdx +3 -3
  506. package/docs/cli/report.mdx +4 -2
  507. package/docs/cli/restart.mdx +2 -2
  508. package/docs/cli/rollback.mdx +14 -8
  509. package/docs/cli/serve.mdx +4 -4
  510. package/docs/cli/setup.mdx +23 -0
  511. package/docs/cli/status.mdx +13 -4
  512. package/docs/cli/stop.mdx +67 -8
  513. package/docs/cli/try.mdx +62 -0
  514. package/docs/cli/update.mdx +4 -3
  515. package/docs/cli/verify.mdx +17 -6
  516. package/docs/cli/version.mdx +3 -2
  517. package/docs/cli.mdx +110 -41
  518. package/docs/debugging.md +3 -3
  519. package/docs/deploy-checks.md +1 -1
  520. package/docs/desktop.mdx +5 -3
  521. package/docs/enterprise.md +11 -10
  522. package/docs/environment.mdx +5 -2
  523. package/docs/faq.mdx +3 -3
  524. package/docs/first-drive.md +5 -4
  525. package/docs/flows.md +35 -27
  526. package/docs/for-agents.md +4 -5
  527. package/docs/frameworks.mdx +32 -21
  528. package/docs/getting-started.md +66 -64
  529. package/docs/human-control.md +15 -14
  530. package/docs/index.mdx +15 -43
  531. package/docs/install-agentic.mdx +22 -37
  532. package/docs/install-manual.mdx +22 -12
  533. package/docs/instrumentation.mdx +5 -3
  534. package/docs/integration-patterns.md +7 -7
  535. package/docs/license-activation.mdx +1 -1
  536. package/docs/multi-agent-testing.md +24 -6
  537. package/docs/packages/babel-plugin.mdx +4 -2
  538. package/docs/packages/browser.mdx +16 -10
  539. package/docs/packages/core.mdx +12 -5
  540. package/docs/packages/electron.mdx +3 -2
  541. package/docs/packages/engine.mdx +1 -1
  542. package/docs/packages/eslint-plugin.mdx +18 -12
  543. package/docs/packages/next.mdx +8 -7
  544. package/docs/packages/open-verification.mdx +1 -1
  545. package/docs/packages/server.mdx +5 -5
  546. package/docs/packages/tauri.mdx +8 -8
  547. package/docs/packages/test.mdx +4 -10
  548. package/docs/packages/vite-plugin.mdx +11 -4
  549. package/docs/packages.mdx +11 -15
  550. package/docs/platform-integration.md +6 -5
  551. package/docs/predicates.mdx +40 -24
  552. package/docs/quickstart.mdx +58 -29
  553. package/docs/required-checks.md +8 -7
  554. package/docs/reticle-manual.md +15 -5
  555. package/docs/skill-file.mdx +17 -79
  556. package/docs/skill-setup.md +9 -9
  557. package/docs/skill.md +200 -0
  558. package/docs/system-map.md +7 -7
  559. package/docs/telemetry.md +22 -24
  560. package/docs/testing.md +4 -4
  561. package/docs/token-efficiency.md +12 -12
  562. package/docs/tools/act-and-wait.mdx +9 -2
  563. package/docs/tools/act-sequence.mdx +6 -7
  564. package/docs/tools/act.mdx +2 -2
  565. package/docs/tools/assert.mdx +18 -17
  566. package/docs/tools/console.mdx +9 -9
  567. package/docs/tools/inspect.mdx +16 -7
  568. package/docs/tools/look.mdx +24 -0
  569. package/docs/tools/navigate.mdx +5 -3
  570. package/docs/tools/network.mdx +2 -2
  571. package/docs/tools/observe.mdx +6 -6
  572. package/docs/tools/overview.mdx +34 -33
  573. package/docs/tools/query.mdx +5 -5
  574. package/docs/tools/session-and-feedback.mdx +13 -4
  575. package/docs/tools/sessions.mdx +8 -8
  576. package/docs/tools/snapshot.mdx +6 -5
  577. package/docs/tools/state.mdx +9 -9
  578. package/docs/tools/tools-and-run.mdx +26 -24
  579. package/docs/tools/verify.mdx +28 -0
  580. package/docs/tools/wait-for.mdx +8 -4
  581. package/docs/troubleshooting.mdx +21 -6
  582. package/docs/usage.md +51 -45
  583. package/docs/use-cases.mdx +3 -3
  584. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  585. package/docs/vs-playwright-mcp.mdx +3 -1
  586. package/docs/what-is-recorded.md +7 -5
  587. package/docs/what-is-reticle.mdx +2 -2
  588. package/docs/why-reticle.mdx +1 -1
  589. package/package.json +6 -5
  590. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  591. package/dist/command/cli/demo/demo-page.js +0 -249
  592. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  593. package/dist/command/cli/demo/demo-run.js +0 -138
  594. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  595. package/dist/judgement/hunt/hunt-report.js +0 -84
  596. package/dist/language/flows/buddy-status.d.ts +0 -25
  597. package/dist/language/flows/buddy-status.js +0 -32
  598. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  599. package/dist/language/flows/change/watch-batcher.js +0 -19
  600. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  601. package/dist/memory/cloud/harness-offer.js +0 -145
  602. package/dist/surface/tools/feature-capture.d.ts +0 -151
  603. package/dist/surface/tools/feature-capture.js +0 -235
  604. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  605. package/dist/surface/tools/tool-hit-rate.js +0 -90
  606. package/dist/telemetry/harness-drive.d.ts +0 -4
  607. package/dist/telemetry/harness-drive.js +0 -35
  608. package/dist/telemetry/identify.d.ts +0 -22
  609. package/dist/telemetry/identify.js +0 -73
  610. package/docs/cli/capsules.mdx +0 -70
  611. package/docs/cli/hunt.mdx +0 -73
  612. package/docs/cli/identify.mdx +0 -76
  613. package/docs/cli/kill.mdx +0 -91
  614. package/docs/cli/watch.mdx +0 -62
@@ -16,16 +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
22
  import { ReticleEnv } from '@reticlehq/core';
23
23
  import { SERVER_VERSION } from '../command/version/identity/server-version.js';
24
24
  const RETICLE_DIR = join(homedir(), '.reticle');
25
- const ID_FILE = join(RETICLE_DIR, 'telemetry-id');
26
- 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';
27
28
  /** Presence of this file = a persistent, machine-wide opt-out (`reticle telemetry disable`). */
28
- 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';
29
36
  /** Where the full disclosure lives — printed in the first-run notice and `reticle telemetry status`. */
30
37
  const POLICY_URL = 'https://github.com/reticlehq/reticle/blob/main/docs/telemetry.md';
31
38
  /** PostHog batch-capture endpoint (US cloud). `RETICLE_TELEMETRY_URL` overrides the host (EU/self-host). */
@@ -91,15 +98,28 @@ const FEEDBACK_RETRY_BACKOFF_MS = 750;
91
98
  * likely to be dropped, and it fails silently like everything else here.
92
99
  */
93
100
  const DETACHED_SEND_TIMEOUT_MS = 15_000;
94
- const DETACHED_SEND_SCRIPT = "fetch(process.argv[1],{method:'POST',headers:{'content-type':'application/json'}," +
95
- `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})})` +
96
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;
97
115
  /** Env var names — mirror cloud-sync's `RETICLE_*` convention. */
98
116
  import { isReticleSourceCheckout } from './dev-repo.js';
99
117
  import { projectInstallSource } from './install-source.js';
100
118
  import { licenseFacts } from './license-activation.js';
101
119
  import { gitFacts } from './git-facts.js';
102
120
  import { currentAutomationHint } from './automation-hint.js';
121
+ import { accountEnvelope } from './account-envelope.js';
122
+ import { currentAgentClient, launchMethodOf } from './agent-client.js';
103
123
  const Env = {
104
124
  DISABLE: ReticleEnv.TELEMETRY, // "0" / "false" / "off" → disabled
105
125
  DO_NOT_TRACK: ReticleEnv.DO_NOT_TRACK, // the cross-tool opt-out convention (any truthy value)
@@ -107,6 +127,7 @@ const Env = {
107
127
  FILE: 'RETICLE_TELEMETRY_FILE', // record to a local JSONL file and send NOTHING — see the sink note
108
128
  KEY: 'RETICLE_TELEMETRY_KEY', // override the PostHog project key
109
129
  CI: 'CI', // presence marks a CI environment
130
+ INTERNAL: 'RETICLE_INTERNAL', // "1" marks the run as the Reticle team's own (dogfooding, sweeps)
110
131
  VITEST: 'VITEST', // set by vitest — unit tests must never phone home
111
132
  };
112
133
  const isDisabled = (env, cwd = process.cwd()) => {
@@ -183,8 +204,9 @@ export const resolveIdentity = (file = ID_FILE) => {
183
204
  return { anonymousId: id, firstRun: true };
184
205
  }
185
206
  catch {
186
- // Can't persist (read-only home, sandbox): still report, just as a fresh ephemeral id each time.
187
- 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 };
188
210
  }
189
211
  };
190
212
  /**
@@ -236,12 +258,12 @@ const packageRoot = (cwd) => {
236
258
  return null;
237
259
  };
238
260
  /** Print the opt-out notice exactly once per machine (honest disclosure, the OSS-trust bar). */
239
- const showNoticeOnce = () => {
261
+ const showNoticeOnce = (dir) => {
240
262
  try {
241
- mkdirSync(RETICLE_DIR, { recursive: true });
263
+ mkdirSync(dir, { recursive: true });
242
264
  // Exclusive create IS the "once": it throws when the file is already there, so the check and
243
265
  // the write cannot be split by a second process printing the notice too.
244
- writeFileSync(NOTICE_FILE, '1', { encoding: 'utf8', flag: 'wx' });
266
+ writeFileSync(join(dir, NOTICE_FILE_NAME), '1', { encoding: 'utf8', flag: 'wx' });
245
267
  process.stderr.write('reticle: anonymous usage telemetry helps improve reticle — no code, no PII, ' +
246
268
  `and your app's data never leaves your machine (${POLICY_URL}). ` +
247
269
  'Opt out any time: reticle telemetry disable\n');
@@ -264,7 +286,7 @@ export const describeTelemetry = (env = process.env, dir = RETICLE_DIR, cwd = pr
264
286
  if (isDisabled(env, cwd)) {
265
287
  return { enabled: false, reason: 'disabled by environment variable', policyUrl: POLICY_URL };
266
288
  }
267
- if (existsSync(join(dir, 'telemetry-opt-out'))) {
289
+ if (existsSync(join(dir, OPT_OUT_FILE_NAME))) {
268
290
  return {
269
291
  enabled: false,
270
292
  reason: 'disabled via `reticle telemetry disable`',
@@ -279,7 +301,7 @@ export const describeTelemetry = (env = process.env, dir = RETICLE_DIR, cwd = pr
279
301
  };
280
302
  /** Persist (or lift) the machine-wide opt-out — `reticle telemetry disable` / `enable`. */
281
303
  export const setTelemetryEnabled = (enabled, dir = RETICLE_DIR) => {
282
- const optOutFile = join(dir, 'telemetry-opt-out');
304
+ const optOutFile = join(dir, OPT_OUT_FILE_NAME);
283
305
  if (enabled) {
284
306
  rmSync(optOutFile, { force: true });
285
307
  return;
@@ -296,6 +318,7 @@ const NOOP = { emit: () => Promise.resolve(false), enabled: false, firstRun: fal
296
318
  * injected so this is testable without a clock or network.
297
319
  */
298
320
  export const createTelemetry = (opts) => {
321
+ const reticleDir = opts.reticleDir ?? RETICLE_DIR;
299
322
  const env = opts.env ?? process.env;
300
323
  const cwd = opts.cwd ?? process.cwd();
301
324
  // A source checkout silences metrics but must not silence FEEDBACK — see onlyBlockedBySourceCheckout.
@@ -303,7 +326,7 @@ export const createTelemetry = (opts) => {
303
326
  if (isDisabled(env, cwd) && !feedbackOnly)
304
327
  return NOOP;
305
328
  try {
306
- if (existsSync(OPT_OUT_FILE))
329
+ if (existsSync(join(reticleDir, OPT_OUT_FILE_NAME)))
307
330
  return NOOP; // the persistent `reticle telemetry disable` opt-out
308
331
  }
309
332
  catch {
@@ -322,7 +345,14 @@ export const createTelemetry = (opts) => {
322
345
  const os = platform();
323
346
  // Negated so it reads the way people say it: UTC+2 is +120, not -120.
324
347
  const tzOffsetMin = -new Date().getTimezoneOffset();
325
- 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);
326
356
  /**
327
357
  * One id per PROCESS, minted in memory and never persisted — which is exactly right: a daemon run
328
358
  * IS the session, and a restarted daemon is genuinely a new one. Ephemeral by construction, so it
@@ -336,10 +366,16 @@ export const createTelemetry = (opts) => {
336
366
  // was unknown for every event that could show whether they got anywhere. Reading it here puts it
337
367
  // on all of them, which is the only shape in which the question can be asked.
338
368
  const installSource = projectInstallSource(opts.cwd ?? process.cwd());
339
- 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);
340
374
  const spawnDetached = opts.spawnImpl ??
341
- ((command, args) => {
342
- 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();
343
379
  });
344
380
  /**
345
381
  * Returns whether the event was actually DELIVERED.
@@ -372,6 +408,9 @@ export const createTelemetry = (opts) => {
372
408
  // A SCALAR, so it needs the event build and the wire schema and no `blocks` entry — the same
373
409
  // three-place trap `outage` fell into, and `installSource` documents below.
374
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 } : {}),
375
414
  os,
376
415
  tzOffsetMin,
377
416
  projectIdSource,
@@ -406,13 +445,35 @@ export const createTelemetry = (opts) => {
406
445
  // the ambient one here would silently ignore it. Identical in production, wrong everywhere the
407
446
  // seam is actually used.
408
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 } : {}),
409
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
+ }
410
471
  // Map the core contract onto PostHog's capture shape: id/name/time move up, the rest are properties.
411
472
  // The feedback body is FLATTENED into `feedback_*` properties rather than sent as a nested object:
412
473
  // PostHog filters and breakdowns operate on top-level properties, so a nested `feedback.stack`
413
474
  // would be invisible to the exact "which stacks report the most bugs" question this exists to
414
475
  // answer. One prefix keeps them grouped in the UI without a nested path.
415
- 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;
416
477
  // `$session_id` is PostHog's OWN session property, so sending ours under that name lights up
417
478
  // its built-in session views and funnels for free rather than requiring custom HogQL everywhere.
418
479
  // `sessionId` rides only on events that happened inside a daemon run. A one-shot CLI command
@@ -444,6 +505,9 @@ export const createTelemetry = (opts) => {
444
505
  refusal,
445
506
  outage,
446
507
  instrumentation,
508
+ hud,
509
+ link,
510
+ harness,
447
511
  };
448
512
  for (const [prefix, block] of Object.entries(blocks)) {
449
513
  for (const [key, value] of Object.entries(block ?? {})) {
@@ -480,7 +544,7 @@ export const createTelemetry = (opts) => {
480
544
  }
481
545
  try {
482
546
  if (true === extra?.detach && opts.fetchImpl === undefined) {
483
- spawnDetached(process.execPath, ['-e', DETACHED_SEND_SCRIPT, url, body]);
547
+ spawnDetached(process.execPath, ['-e', DETACHED_SEND_SCRIPT, url], body);
484
548
  return false; // handed off, outcome unknowable from here
485
549
  }
486
550
  // Feedback is slower and retried; everything else keeps the fire-and-forget budget.
@@ -517,6 +581,23 @@ export const createTelemetry = (opts) => {
517
581
  };
518
582
  return { emit, enabled: true, firstRun };
519
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
+ };
520
601
  /**
521
602
  * The process-wide emitter. One identity resolution + one opt-out check per process; both the CLI
522
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
  *
@@ -115,7 +114,9 @@ function passedOf(result, status) {
115
114
  * `falseGreenCaught` is the one that matters: the assertion PASSED and Reticle still refused to call
116
115
  * it verified. That is the product's thesis reduced to a boolean.
117
116
  */
118
- 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) {
119
120
  if (!VERDICT_TOOLS.has(toolName))
120
121
  return undefined;
121
122
  // A paused session REFUSES the call — nothing driven, nothing asserted. The refusal carries a
@@ -123,6 +124,11 @@ export function verificationOf(toolName, result, durationMs, brand) {
123
124
  // here for work that happened.
124
125
  if (true === result['paused'])
125
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;
126
132
  const replay = replayVerdict(toolName, result['status']);
127
133
  const verified = 'string' === typeof result['verified'] ? result['verified'] : (replay?.verified ?? undefined);
128
134
  // flow_verify reports `status: pass|fail|unverifiable`; assert reports a boolean `pass`. Accept
@@ -169,7 +175,9 @@ export function verificationOf(toolName, result, durationMs, brand) {
169
175
  // WHAT was lost, when the reason was that something was. Three owners, three fixes, one bar
170
176
  // until now.
171
177
  ...(uncleanLoss === undefined ? {} : { uncleanLoss }),
172
- // WHOSE drive this was. Absent is the ordinary case — the agent called the tool itself.
173
- ...(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 } : {}),
174
182
  };
175
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,12 +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';
11
12
  import { servingDirectoryOf } from './portal/session/serving-directory.js';
12
13
  import { originOf } from './portal/session/session-manager.js';
13
14
  import { Bridge } from './portal/bridge/bridge.js';
14
15
  import { FlowStore } from './language/flows/flows.js';
15
16
  import { makeJournalAttach } from './memory/journal/attach-journal.js';
16
- import { makeSessionEnd, recordDriveRun } from './memory/journal/session-end.js';
17
+ import { endLiveSessions, makeSessionEnd, recordDriveRun } from './memory/journal/session-end.js';
17
18
  import { attachDriveRunFlush } from './memory/journal/drive-run-flush.js';
18
19
  import { AmbientStore } from './memory/journal/ambient-store.js';
19
20
  import { ensureWorkspaceGitignore } from './memory/journal/on-disk/workspace-gitignore.js';
@@ -45,7 +46,11 @@ export function attachJournal(bridge, deps) {
45
46
  // reached a different account's production dashboard.
46
47
  // The origin is passed for the case where the page never stamped a project id: it is the only
47
48
  // distinguishing fact left, and without it every such app shares one bucket.
48
- 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;
49
54
  // The project's config sits beside its `.reticle/`, so the declaration is read from the tab's
50
55
  // own project rather than from wherever the daemon was started.
51
56
  session.background = readBackgroundTraffic(findProjectConfig(dirname(session.artifactRoot)));
@@ -66,17 +71,20 @@ export function attachJournal(bridge, deps) {
66
71
  }
67
72
  });
68
73
  // Teardown: flush the journal tail to disk + persist what this session learned.
69
- bridge.attachSessionEnd(makeSessionEnd({
74
+ const teardown = makeSessionEnd({
70
75
  ...deps,
71
76
  // A drive is saved in the session's own project, where replay will look for it.
72
77
  ...(deps.flows === undefined
73
78
  ? {}
74
- : { 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
+ }),
75
82
  ...(deps.retain === undefined ? {} : { retain: deps.retain }),
76
83
  // Retention runs from teardown, and it must not delete the journal of a session that is still
77
84
  // being written. The registry is the only thing that knows which those are.
78
85
  liveSessionIds: () => new Set(bridge.sessions.all().map((s) => s.id)),
79
- }));
86
+ });
87
+ bridge.attachSessionEnd(teardown);
80
88
  /*
81
89
  * And the same write, DURING the session rather than only at the end of it.
82
90
  *
@@ -92,6 +100,7 @@ export function attachJournal(bridge, deps) {
92
100
  if (deps.enabled) {
93
101
  attachDriveRunFlush({
94
102
  resolve: (sessionId) => bridge.sessions.get(sessionId),
103
+ all: () => bridge.sessions.all(),
95
104
  write: (session) => recordDriveRun(deps, session),
96
105
  });
97
106
  }
@@ -104,4 +113,6 @@ export function attachJournal(bridge, deps) {
104
113
  // under which nothing ever deleted what was already there. Visual diffs, feedback copies and run
105
114
  // artifacts do not need the journal to be written at all and kept accumulating regardless.
106
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);
107
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 |
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.