@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
@@ -12,8 +12,14 @@
12
12
  import { unwatchFile, watchFile } from 'node:fs';
13
13
  /** How often each watched file is stat'ed. A second reads as live to somebody switching windows. */
14
14
  export const ACCOUNT_WATCH_INTERVAL_MS = 1_000;
15
- export function watchAccountFiles(onChange, intervalMs = ACCOUNT_WATCH_INTERVAL_MS) {
15
+ /** How often `onTick` re-reads what has no file to watch; the platform config is polled as often. */
16
+ export const HUD_REFRESH_MS = 30_000;
17
+ export function watchAccountFiles(onChange, intervalMs = ACCOUNT_WATCH_INTERVAL_MS,
18
+ /** The rest of the platform's side of the HUD, which has no file to watch: run every 30s. */
19
+ onTick) {
16
20
  const watched = new Set();
21
+ const ticker = onTick === undefined ? undefined : setInterval(onTick, HUD_REFRESH_MS);
22
+ ticker?.unref();
17
23
  const listener = () => {
18
24
  onChange();
19
25
  };
@@ -26,9 +32,28 @@ export function watchAccountFiles(onChange, intervalMs = ACCOUNT_WATCH_INTERVAL_
26
32
  watchFile(path, { persistent: false, interval: intervalMs }, listener);
27
33
  },
28
34
  close() {
35
+ if (ticker !== undefined)
36
+ clearInterval(ticker);
29
37
  for (const path of watched)
30
38
  unwatchFile(path, listener);
31
39
  watched.clear();
32
40
  },
33
41
  };
34
42
  }
43
+ /** What each tab was last sent by `pushIfMoved`, so an unchanged snapshot is not sent again. */
44
+ const sent = new WeakMap();
45
+ /**
46
+ * Push a tab its impact snapshot, or, with `ifChanged`, only when it moved since this last pushed it.
47
+ *
48
+ * The daemon re-reads every tab on a timer so the platform's side of the HUD (sync status, runs on
49
+ * the dashboard, days left) reaches an idle tab without a tool call; resending an unchanged snapshot
50
+ * on every tick would repaint every HUD for nothing.
51
+ */
52
+ export function pushIfMoved(tab, read, ifChanged) {
53
+ const snapshot = read();
54
+ const json = JSON.stringify(snapshot);
55
+ if (ifChanged && sent.get(tab) === json)
56
+ return;
57
+ sent.set(tab, json);
58
+ tab.pushImpact(() => snapshot, true);
59
+ }
@@ -1,5 +1,4 @@
1
- import { type OfferSource } from '../cloud/harness-offer.js';
2
- import type { ConfigSource } from '../cloud/harness-config.js';
1
+ import { type ConfigSource } from '../cloud/harness-config.js';
3
2
  import { type NoticesSource } from '../cloud/hud-notices-source.js';
4
3
  import { type ImpactCounts, type ImpactDefect, type AccountState, type ImpactScope, type ImpactSnapshot } from '@reticlehq/core';
5
4
  /** Read a scope, tolerating absence and corruption: a broken file starts over rather than throwing. */
@@ -49,8 +48,6 @@ export declare class ImpactStore {
49
48
  globalRoot?: string;
50
49
  /** Reads whether this machine is signed in. Injected so the store stays testable and pure-ish. */
51
50
  account?: () => AccountState;
52
- /** Where the workspace stands with the free harness offer. Injected so no test touches a network. */
53
- offer?: OfferSource;
54
51
  config?: ConfigSource;
55
52
  /** The HUD rail's notices. Defaults to the daemon's cached copy of the published file. */
56
53
  notices?: NoticesSource;
@@ -1,9 +1,11 @@
1
1
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
- import { describeSync, overallStatus, readSyncSummary } from '../project/sync-status.js';
2
+ import { SyncStatus, dashboardRunUrl, describeSync, keyRefusalAtLastSync, overallStatus, readSyncSummary, } from '../project/sync-status.js';
3
+ import { describeUnsynced, unsentFlowCount, unsentRunCount, } from '../cloud/unsynced-roots.js';
4
+ import { readDashboardUrl } from '../project/sync-status.js';
3
5
  import { dirname, join } from 'node:path';
4
6
  import { homedir } from 'node:os';
5
7
  import { readAccountState } from '../cloud/account-state.js';
6
- import { harnessOfferSource } from '../cloud/harness-offer.js';
8
+ import { configForHud } from '../cloud/harness-config.js';
7
9
  import { hudNoticesSource } from '../cloud/hud-notices-source.js';
8
10
  import { selectNotices } from '@reticlehq/core/hud';
9
11
  import { ReticleDir, IMPACT_DAILY_BUCKETS, IMPACT_DEFECT_LIMIT, IMPACT_SCHEMA_VERSION, ImpactScopeSchema, addImpactCounts, emptyImpactCounts, emptyImpactRecords, estimateImpactSavings, } from '@reticlehq/core';
@@ -34,26 +36,6 @@ function impactPaths(reticleRoot, globalRoot) {
34
36
  global: join(globalRoot, ReticleDir.ROOT, ReticleDir.IMPACT_FILE),
35
37
  };
36
38
  }
37
- /**
38
- * Where this project's dashboard lives, if `reticle link` recorded one.
39
- *
40
- * Read from the link file rather than derived from the API url, because the API origin and the
41
- * console origin are different hosts in every deployment that is not a laptop. Synchronous and
42
- * best-effort, like every other read in this file: a missing or malformed link file means no link
43
- * in the HUD, never a failed tool call.
44
- */
45
- function readDashboardUrl(reticleRoot) {
46
- try {
47
- const raw = JSON.parse(readFileSync(join(reticleRoot, ReticleDir.CLOUD_LINK_FILE), 'utf8'));
48
- if ('object' !== typeof raw || null === raw)
49
- return undefined;
50
- const value = raw['dashboardUrl'];
51
- return 'string' === typeof value && value.length > 0 ? value : undefined;
52
- }
53
- catch {
54
- return undefined;
55
- }
56
- }
57
39
  function emptyScope(now) {
58
40
  const counts = emptyImpactCounts();
59
41
  return {
@@ -243,8 +225,6 @@ export class ImpactStore {
243
225
  #timer;
244
226
  #onChange;
245
227
  #account;
246
- /** Where this workspace stands with the free harness offer. Cached; see harness-offer.ts. */
247
- #offer;
248
228
  #config;
249
229
  #notices;
250
230
  #sdkVersion;
@@ -259,9 +239,6 @@ export class ImpactStore {
259
239
  this.#projectName = opts.projectName;
260
240
  this.#dashboardUrl = readDashboardUrl(opts.reticleRoot);
261
241
  this.#root = opts.reticleRoot;
262
- // The claim happens in the console, so the link this project was linked to IS the claim link —
263
- // built here rather than in the HUD, which has no way to know where this project points.
264
- this.#offer = opts.offer ?? harnessOfferSource(process.env, () => this.#dashboardUrl);
265
242
  this.#notices =
266
243
  opts.notices ??
267
244
  hudNoticesSource({
@@ -275,11 +252,30 @@ export class ImpactStore {
275
252
  this.#project = readScope(this.#paths.project, now);
276
253
  this.#global = readScope(this.#paths.global, now);
277
254
  }
278
- #syncStatus() {
255
+ #syncStatus(dashboardUrl) {
279
256
  const now = this.#now();
280
257
  if (this.#sync !== undefined && now - this.#sync.at < SYNC_STATUS_EVERY_MS)
281
258
  return this.#sync.value;
259
+ // Not linked: one line when runs or flows sit here that nothing will send, and nothing otherwise.
260
+ // `pending` counts both, so the HUD's existing "N not sent" includes a flow saved with no run.
261
+ if (dashboardUrl === undefined) {
262
+ const runs = unsentRunCount(this.#root);
263
+ const flows = unsentFlowCount(this.#root, false);
264
+ const value = 0 === runs + flows
265
+ ? undefined
266
+ : {
267
+ status: SyncStatus.LOCAL_ONLY,
268
+ pending: runs + flows,
269
+ runs,
270
+ flows,
271
+ said: describeUnsynced({ root: this.#root, runs, flows, linked: false }, dirname(this.#root)),
272
+ };
273
+ this.#sync = { at: now, value };
274
+ return value;
275
+ }
282
276
  const summary = readSyncSummary(this.#root, true);
277
+ const refusal = keyRefusalAtLastSync(this.#root);
278
+ const latest = summary.latestOnPlatform;
283
279
  const value = {
284
280
  status: overallStatus(summary),
285
281
  runs: summary.runs,
@@ -287,7 +283,11 @@ export class ImpactStore {
287
283
  pending: summary.pending,
288
284
  refused: summary.refused.length + summary.refusedMore,
289
285
  ...(summary.lastPushAt === undefined ? {} : { lastPushAt: summary.lastPushAt }),
286
+ // The run that just synced, on its own page — the HUD's "see it in your dashboard".
287
+ ...(latest === undefined ? {} : { runUrl: dashboardRunUrl(dashboardUrl, latest) }),
290
288
  said: describeSync(summary, now),
289
+ // The HUD's chip: a refused key is not "0 waiting".
290
+ ...(refusal === undefined ? {} : { keyRefused: refusal }),
291
291
  };
292
292
  this.#sync = { at: now, value };
293
293
  return value;
@@ -320,21 +320,10 @@ export class ImpactStore {
320
320
  if (this.#dashboardUrl !== undefined)
321
321
  snap.dashboardUrl = this.#dashboardUrl;
322
322
  snap.account = this.#account();
323
- const cfgForOffer = this.#config.read();
324
- const offer = this.#offer.read();
325
- // Joined here because this is the one place that holds BOTH the offer and the platform config.
326
- // The card reads the offer, so readiness has to travel on it rather than being re-derived in a
327
- // presenter that has no business knowing what a provider key is.
328
- if (offer !== undefined && cfgForOffer !== undefined)
329
- offer.drivable = cfgForOffer.providerReady;
330
- // Absent means "we have not heard", which the HUD renders as nothing at all. Never defaulted to
331
- // `{claimed:false}`: that would advertise the offer to everyone who is offline.
332
- if (offer !== undefined)
333
- snap.harnessOffer = offer;
334
323
  // Absent stays absent: the HUD reads that as "we have not heard" and renders no control.
335
324
  const cfg = this.#config.read();
336
325
  if (cfg !== undefined)
337
- snap.harnessConfig = cfg;
326
+ snap.harnessConfig = configForHud(cfg, this.#now());
338
327
  // Chosen here, where the account and the entitlement are both known. Absent when nothing applies,
339
328
  // so the HUD falls back to the slides bundled with the SDK.
340
329
  const notices = selectNotices(this.#notices.read(), {
@@ -350,8 +339,9 @@ export class ImpactStore {
350
339
  snap.coverage = coverage;
351
340
  // Only for a linked project: an unlinked one has nothing on the platform, and the HUD already
352
341
  // offers the way to link it.
353
- if (this.#dashboardUrl !== undefined)
354
- snap.sync = this.#syncStatus();
342
+ const sync = this.#syncStatus(this.#dashboardUrl);
343
+ if (sync !== undefined)
344
+ snap.sync = sync;
355
345
  return snap;
356
346
  }
357
347
  /** Write now (process exit, tests). */
@@ -55,6 +55,7 @@ export declare function dischargeInlineIntent(deps: ToolDeps, sessionId: string
55
55
  verdictId: string;
56
56
  grade: string;
57
57
  at: number;
58
+ runId?: string;
58
59
  },
59
60
  /** `file:line` of the element this verdict acted on, when there was one. */
60
61
  sourceLabel?: string): Promise<void>;
@@ -25,7 +25,7 @@ import { IntentFileSchema, IntentState, amendIntent, isActionLabel, } from '@ret
25
25
  import { IntentDir, ReticleDir } from '@reticlehq/core';
26
26
  import { reticleDirPaths } from '../project/dir/reticle-dir.js';
27
27
  import { withFileLock } from '../project/file-lock.js';
28
- import { subjectFor } from './intent-subject.js';
28
+ import { subjectFor, UNSORTED_SUBJECT } from './intent-subject.js';
29
29
  import { emptyShard, indexFrom, IntentShardSchema, IntentStatus, recordFromIntent, serialise, shardsFrom, statusFromState, } from './intent-shard.js';
30
30
  import { writeFileAtomic } from '../project/fs/write-atomic.js';
31
31
  const JSON_SUFFIX = '.json';
@@ -199,13 +199,25 @@ export class IntentShardStore {
199
199
  const subject = flow !== undefined
200
200
  ? subjectFor({ surface: { flow } })
201
201
  : (facts.subject ??
202
- existing?.subject ??
202
+ // `unsorted` is the absence of a subject, so new evidence may still file the record.
203
+ (UNSORTED_SUBJECT === existing?.subject ? undefined : existing?.subject) ??
203
204
  subjectFor({ surface: next.surface, binding: next.binding }));
204
205
  const why = facts.why ?? existing?.why;
205
206
  const source = facts.source ?? existing?.source;
207
+ // New words keep no check bound to the old ones: a later green on it would "prove" words it
208
+ // never tested. A binding the change brings with it stands.
209
+ const kept = existing !== undefined && existing.statement !== next.statement
210
+ ? { ...existing, binding: undefined }
211
+ : existing;
212
+ // Bound only while a check is bound: a record whose check was taken off (new words, a decision)
213
+ // said `bound` with none, and a check naming it then proved nothing and said nothing.
214
+ const merged = { ...kept, ...next };
215
+ const state = IntentState.BOUND === merged.state && merged.binding === undefined
216
+ ? IntentState.DECLARED
217
+ : merged.state;
206
218
  return {
207
- ...existing,
208
- ...next,
219
+ ...merged,
220
+ state,
209
221
  subject,
210
222
  status: this.#statusOf(next, existing, facts.status),
211
223
  updatedAt: this.#clock.now(),
@@ -63,14 +63,17 @@ declare const IntentRecordSchema: z.ZodObject<{
63
63
  verdictId: z.ZodString;
64
64
  grade: z.ZodString;
65
65
  at: z.ZodNumber;
66
+ runId: z.ZodOptional<z.ZodString>;
66
67
  }, "strip", z.ZodTypeAny, {
67
68
  at: number;
68
69
  grade: string;
69
70
  verdictId: string;
71
+ runId?: string | undefined;
70
72
  }, {
71
73
  at: number;
72
74
  grade: string;
73
75
  verdictId: string;
76
+ runId?: string | undefined;
74
77
  }>>;
75
78
  amended: z.ZodOptional<z.ZodArray<z.ZodObject<{
76
79
  statement: z.ZodString;
@@ -112,6 +115,7 @@ declare const IntentRecordSchema: z.ZodObject<{
112
115
  at: number;
113
116
  grade: string;
114
117
  verdictId: string;
118
+ runId?: string | undefined;
115
119
  } | undefined;
116
120
  amended?: {
117
121
  at: number;
@@ -137,6 +141,7 @@ declare const IntentRecordSchema: z.ZodObject<{
137
141
  at: number;
138
142
  grade: string;
139
143
  verdictId: string;
144
+ runId?: string | undefined;
140
145
  } | undefined;
141
146
  amended?: {
142
147
  at: number;
@@ -170,14 +175,17 @@ export declare const IntentShardSchema: z.ZodObject<{
170
175
  verdictId: z.ZodString;
171
176
  grade: z.ZodString;
172
177
  at: z.ZodNumber;
178
+ runId: z.ZodOptional<z.ZodString>;
173
179
  }, "strip", z.ZodTypeAny, {
174
180
  at: number;
175
181
  grade: string;
176
182
  verdictId: string;
183
+ runId?: string | undefined;
177
184
  }, {
178
185
  at: number;
179
186
  grade: string;
180
187
  verdictId: string;
188
+ runId?: string | undefined;
181
189
  }>>;
182
190
  amended: z.ZodOptional<z.ZodArray<z.ZodObject<{
183
191
  statement: z.ZodString;
@@ -219,6 +227,7 @@ export declare const IntentShardSchema: z.ZodObject<{
219
227
  at: number;
220
228
  grade: string;
221
229
  verdictId: string;
230
+ runId?: string | undefined;
222
231
  } | undefined;
223
232
  amended?: {
224
233
  at: number;
@@ -244,6 +253,7 @@ export declare const IntentShardSchema: z.ZodObject<{
244
253
  at: number;
245
254
  grade: string;
246
255
  verdictId: string;
256
+ runId?: string | undefined;
247
257
  } | undefined;
248
258
  amended?: {
249
259
  at: number;
@@ -272,6 +282,7 @@ export declare const IntentShardSchema: z.ZodObject<{
272
282
  at: number;
273
283
  grade: string;
274
284
  verdictId: string;
285
+ runId?: string | undefined;
275
286
  } | undefined;
276
287
  amended?: {
277
288
  at: number;
@@ -301,6 +312,7 @@ export declare const IntentShardSchema: z.ZodObject<{
301
312
  at: number;
302
313
  grade: string;
303
314
  verdictId: string;
315
+ runId?: string | undefined;
304
316
  } | undefined;
305
317
  amended?: {
306
318
  at: number;
@@ -48,5 +48,6 @@ export declare class IntentStore {
48
48
  verdictId: string;
49
49
  grade: string;
50
50
  at: number;
51
+ runId?: string;
51
52
  }): Promise<boolean>;
52
53
  }
@@ -7,6 +7,7 @@ import { reticleDirPaths } from '../project/dir/reticle-dir.js';
7
7
  import { IntentStore } from './intent-store.js';
8
8
  import { IntentShardStore } from './intent-shard-store.js';
9
9
  import { IntentStatus } from './intent-shard.js';
10
+ import { UNSORTED_SUBJECT } from './intent-subject.js';
10
11
  import { ReticleDir, ReticleTool, apiKeyFrom } from '@reticlehq/core';
11
12
  import { sessionIdShape } from '../../surface/tools/tool-kit.js';
12
13
  import { PredicateSchema } from '@reticlehq/engine/question/predicate/predicate.js';
@@ -107,6 +108,11 @@ export const INTENT_TOOLS = [
107
108
  .optional()
108
109
  .describe('declare only: statements not stored, and why.'),
109
110
  path: z.string().optional().describe('Where the ledger was written.'),
111
+ filesNotFound: z.array(z.string()).optional().describe('surface.files not in the project'),
112
+ noSubject: z
113
+ .object({ ids: z.array(z.string()), fix: z.string() })
114
+ .optional()
115
+ .describe('declare only: intents filed under nothing, and how to file them'),
110
116
  entries: z
111
117
  .array(z.unknown())
112
118
  .optional()
@@ -172,17 +178,51 @@ export const INTENT_TOOLS = [
172
178
  if (!Array.isArray(raw) || 0 === raw.length) {
173
179
  throw new Error(`${ReticleTool.INTENT} declare: \`intents\` must be a non-empty array of { id, statement }, got ${raw === undefined ? 'nothing' : JSON.stringify(raw)} — nothing was stored`);
174
180
  }
175
- const entries = raw;
181
+ const { entries, missing } = await withExistingFiles(deps, dirname(root), raw);
176
182
  const declared = await store.declare(entries);
177
183
  // Said, not swallowed: an agent that declared something and finds nothing stored would
178
184
  // otherwise conclude the ledger lost it.
179
185
  const refused = entries
180
186
  .filter((entry) => isActionLabel(entry.statement))
181
187
  .map((entry) => ({ id: entry.id, reason: STEP_LABEL_REFUSAL }));
182
- return { intents: declared, ...(0 === refused.length ? {} : { refused }), path: root };
188
+ // Asked, not refused: prose with nowhere to live is still worth keeping, but an agent
189
+ // looking for it later finds it by its subject, and the Memory page warns about these.
190
+ const unsorted = declared
191
+ .filter((intent) => UNSORTED_SUBJECT === intent.subject)
192
+ .map((intent) => intent.id);
193
+ return {
194
+ intents: declared,
195
+ ...(0 === refused.length ? {} : { refused }),
196
+ // Named, never kept as a fact's source: a path that is not in the project is a guess.
197
+ ...(0 === missing.length ? {} : { filesNotFound: missing }),
198
+ ...(0 === unsorted.length ? {} : { noSubject: { ids: unsorted, fix: NO_SUBJECT_FIX } }),
199
+ path: root,
200
+ };
183
201
  },
184
202
  },
185
203
  ];
204
+ /**
205
+ * The entries with each `surface.files` path that is not in the project left out, and those paths.
206
+ * An agent declared `src/pages/SavedItems.tsx` for `src/views/SavedItems.tsx`, and the dashboard
207
+ * showed the wrong file as the fact's source.
208
+ */
209
+ async function withExistingFiles(deps, projectDir, entries) {
210
+ const missing = [];
211
+ const kept = await Promise.all(entries.map(async (entry) => {
212
+ const surface = entry.surface;
213
+ if (!Array.isArray(surface?.files))
214
+ return entry;
215
+ const files = [];
216
+ for (const file of surface.files)
217
+ if ('string' === typeof file && (await deps.fs.exists(join(projectDir, file))))
218
+ files.push(file);
219
+ else if ('string' === typeof file)
220
+ missing.push(file);
221
+ return { ...entry, surface: { ...surface, files } };
222
+ }));
223
+ return { entries: kept, missing };
224
+ }
225
+ const NO_SUBJECT_FIX = 'Nothing says what these are about, so an agent looking for them cannot find them: declare each again with surface.route (the page it is about) or surface.flow.';
186
226
  const MAX_REQUEST = 20_000;
187
227
  const MAX_STATEMENT = 500;
188
228
  const MAX_STATEMENTS = 100;
@@ -10,6 +10,12 @@ import type { ToolDeps } from '../../surface/tools/tool-kit.js';
10
10
  * is a false accusation rather than an error.
11
11
  */
12
12
  export declare function openSessionIntents(deps: ToolDeps, sessionId: string | undefined): Promise<Intent[]>;
13
+ /**
14
+ * A reader of the same ledger, its root resolved NOW. For a verdict drawn after its tab may have
15
+ * left: a checkout click that takes the page to another origin closes the session, and resolving the
16
+ * root then refused the whole call with "names no session" instead of grading what was seen.
17
+ */
18
+ export declare function ledgerFor(deps: ToolDeps, sessionId: string | undefined): () => Promise<Intent[]>;
13
19
  /**
14
20
  * EVERY intent in the ledger, proved ones included — the denominator the open list is a subset of.
15
21
  *
@@ -10,7 +10,16 @@ import { sessionRoot } from '../project/session-root.js';
10
10
  * is a false accusation rather than an error.
11
11
  */
12
12
  export async function openSessionIntents(deps, sessionId) {
13
- return new IntentStore(deps.fs, sessionRoot(deps, sessionId), { now: deps.now }).open();
13
+ return ledgerFor(deps, sessionId)();
14
+ }
15
+ /**
16
+ * A reader of the same ledger, its root resolved NOW. For a verdict drawn after its tab may have
17
+ * left: a checkout click that takes the page to another origin closes the session, and resolving the
18
+ * root then refused the whole call with "names no session" instead of grading what was seen.
19
+ */
20
+ export function ledgerFor(deps, sessionId) {
21
+ const root = sessionRoot(deps, sessionId);
22
+ return () => new IntentStore(deps.fs, root, { now: deps.now }).open();
14
23
  }
15
24
  /**
16
25
  * EVERY intent in the ledger, proved ones included — the denominator the open list is a subset of.
@@ -0,0 +1,24 @@
1
+ import type { IntentShardStore } from './intent-shard-store.js';
2
+ import { IntentStatus } from './intent-shard.js';
3
+ /**
4
+ * One settled disagreement: the words kept, the words set aside, and who chose — or, with no words
5
+ * set aside, the status the team settled on the kept words.
6
+ */
7
+ export interface SettledWords {
8
+ kept: string;
9
+ setAside?: string;
10
+ by?: string;
11
+ status?: IntentStatus;
12
+ /** The file the platform holds for the kept words; a record re-sent without it erased it there. */
13
+ file?: string;
14
+ }
15
+ /** The settled disagreements in the platform's memory entries, read defensively. */
16
+ export declare function settledWordsIn(entries: readonly unknown[]): SettledWords[];
17
+ /** Apply them to the local records; returns how many records changed. */
18
+ export declare function applySettledWords(store: IntentShardStore, settled: readonly SettledWords[]): Promise<number>;
19
+ /**
20
+ * The agent's recorded request, with each statement a decision set aside replaced by the words kept:
21
+ * a run reports it as "What was asked", and the run that proved the kept words showed the rejected
22
+ * ones as its goal. Never throws; no request, nothing to change.
23
+ */
24
+ export declare function keptWordsInRequest(path: string, settled: readonly SettledWords[]): Promise<void>;
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Decisions made on the dashboard, brought down to the record of the person whose words were set
3
+ * aside.
4
+ *
5
+ * A maintainer settled a disagreement by keeping the team's words; the author's own record still
6
+ * said hers, agreed, and her daemon re-sent it every minute, so the same decision was made three
7
+ * times. The platform returns each memory entry with the decisions taken on it; a local record
8
+ * whose statement one of them set aside takes the words that were kept, and says who decided.
9
+ */
10
+ import { readFile, writeFile } from 'node:fs/promises';
11
+ import { asRecord, asString } from '@reticlehq/core';
12
+ import { IntentStatus } from './intent-shard.js';
13
+ /** How settled each status is; a record is only ever raised along it, never lowered. */
14
+ const RANK = {
15
+ [IntentStatus.PROPOSED]: 0,
16
+ [IntentStatus.AGREED]: 1,
17
+ [IntentStatus.PROVED]: 2,
18
+ [IntentStatus.STALE]: 1,
19
+ };
20
+ /** A status the platform settled, read defensively; proposed settles nothing. */
21
+ const settledStatus = (value) => [IntentStatus.AGREED, IntentStatus.PROVED, IntentStatus.STALE].find((s) => s === value);
22
+ const str = (value) => {
23
+ const text = asString(value);
24
+ return text === undefined || 0 === text.length ? undefined : text;
25
+ };
26
+ /** The settled disagreements in the platform's memory entries, read defensively. */
27
+ export function settledWordsIn(entries) {
28
+ return entries.flatMap((raw) => {
29
+ const entry = asRecord(raw);
30
+ const kept = str(entry['statement']);
31
+ const decisions = entry['decisions'];
32
+ const status = settledStatus(entry['status']);
33
+ const file = str(entry['sourceFile']);
34
+ if (kept === undefined)
35
+ return [];
36
+ const settled = status === undefined ? [] : [{ kept, status }];
37
+ if (!Array.isArray(decisions))
38
+ return settled;
39
+ return decisions
40
+ .flatMap((d) => {
41
+ const setAside = str(asRecord(asRecord(d)['setAside'])['statement']);
42
+ const by = str(asRecord(d)['byEmail']);
43
+ return setAside === undefined || setAside === kept
44
+ ? []
45
+ : [
46
+ {
47
+ kept,
48
+ setAside,
49
+ ...(by === undefined ? {} : { by }),
50
+ ...(file === undefined ? {} : { file }),
51
+ },
52
+ ];
53
+ })
54
+ .concat(settled);
55
+ });
56
+ }
57
+ /** Where the record's words now come from. */
58
+ const decidedBy = (by) => `decided on the dashboard${by === undefined ? '' : ` by ${by}`}`;
59
+ /** Apply them to the local records; returns how many records changed. */
60
+ export async function applySettledWords(store, settled) {
61
+ if (0 === settled.length)
62
+ return 0;
63
+ let changed = 0;
64
+ for (const record of await store.all()) {
65
+ // The team settled these very words: the record takes that status, so this machine never
66
+ // re-sends them as proposed and undoes the decision. Raised only, never lowered.
67
+ const status = settled.find((s) => s.status !== undefined && s.kept === record.statement)?.status;
68
+ if (status !== undefined && RANK[status] > RANK[record.status]) {
69
+ const raised = await store.upsert(record.id, (existing) => existing, {
70
+ status,
71
+ source: decidedBy(undefined),
72
+ });
73
+ if (raised?.status === status)
74
+ changed += 1;
75
+ continue;
76
+ }
77
+ const decision = settled.find((s) => s.setAside === record.statement);
78
+ if (decision === undefined)
79
+ continue;
80
+ const next = await store.upsert(record.id, (existing) =>
81
+ // The check bound to the words set aside proves nothing about the words kept.
82
+ existing === undefined
83
+ ? undefined
84
+ : {
85
+ ...withoutBinding(existing),
86
+ statement: decision.kept,
87
+ // The files were the set-aside words'; the kept words carry the platform's.
88
+ surface: {
89
+ ...existing.surface,
90
+ files: decision.file === undefined ? [] : [decision.file],
91
+ },
92
+ }, { source: decidedBy(decision.by) });
93
+ if (next?.statement === decision.kept)
94
+ changed += 1;
95
+ }
96
+ return changed;
97
+ }
98
+ /** A record with its bound check taken off: the words it was bound to were set aside. */
99
+ function withoutBinding(record) {
100
+ const { binding: _dropped, ...rest } = record;
101
+ return rest;
102
+ }
103
+ /**
104
+ * The agent's recorded request, with each statement a decision set aside replaced by the words kept:
105
+ * a run reports it as "What was asked", and the run that proved the kept words showed the rejected
106
+ * ones as its goal. Never throws; no request, nothing to change.
107
+ */
108
+ export async function keptWordsInRequest(path, settled) {
109
+ const decided = settled.filter((s) => s.setAside !== undefined);
110
+ if (0 === decided.length)
111
+ return;
112
+ try {
113
+ const raw = JSON.parse(await readFile(path, 'utf8'));
114
+ const statements = Array.isArray(raw['statements']) ? raw['statements'] : [];
115
+ let changed = false;
116
+ const next = statements.map((s) => {
117
+ const statement = asRecord(s);
118
+ const kept = decided.find((d) => d.setAside === statement['text'])?.kept;
119
+ if (kept === undefined)
120
+ return s;
121
+ changed = true;
122
+ return { ...statement, text: kept };
123
+ });
124
+ if (changed)
125
+ await writeFile(path, `${JSON.stringify({ ...raw, statements: next }, null, 2)}\n`);
126
+ }
127
+ catch {
128
+ // No request recorded, or one this cannot read: nothing to correct.
129
+ }
130
+ }
@@ -19,6 +19,8 @@ export interface TapeStep {
19
19
  endPage?: string;
20
20
  /** The intent the agent declared on this action. The first one names the journey. */
21
21
  intent?: string;
22
+ /** Recorder-internal: network mocks were active when it ran (#1459). Never written to disk. */
23
+ mocked?: true;
22
24
  }
23
25
  /** The compiled shape a flow store accepts. Structural, for the same reason as `TapeStep`. */
24
26
  export interface DriveProgram {
@@ -56,6 +58,13 @@ export declare const DRIVE_FLOW_PREFIX = "drive-";
56
58
  * see FlowStore.saveJourney.
57
59
  */
58
60
  export declare function driveFlowName(route?: string, steps?: readonly TapeStep[]): FlowName;
61
+ /** Why session end saved no flow, as reported on the `flow_recorded` step. */
62
+ export declare const DriveFlowSkipReason: {
63
+ /** The drive declared no consequence, so a saved flow could never go red. */
64
+ readonly NO_DECLARED_CONSEQUENCE: "no_declared_consequence";
65
+ /** What it proved rested on network mocks the flow would not carry (#1459). */
66
+ readonly DRIVEN_UNDER_NETWORK_MOCKS: "driven_under_network_mocks";
67
+ };
59
68
  export interface DriveFlowOutcome {
60
69
  /** The flows that were written — one per journey the session contained. */
61
70
  readonly saved?: readonly string[];
@@ -68,6 +77,13 @@ export interface DriveFlowOutcome {
68
77
  * "the agent drove and proved nothing" stays visible instead of looking like nothing happened.
69
78
  */
70
79
  readonly unprovenSteps?: number;
80
+ /**
81
+ * Steps of journeys that proved something and were NOT saved because they ran while network
82
+ * mocks were active (#1459). Such a journey replays against the real backend, so it either fails
83
+ * for a reason unrelated to the change or passes on data the original check never saw, and the
84
+ * flow file holds no trace of the precondition. Counted, so "not saved" has a reason.
85
+ */
86
+ readonly mockedSteps?: number;
71
87
  }
72
88
  /** A flow per journey, so two journeys in one session are two regression tests rather than one. */
73
89
  export declare function driveFlowsFrom(tape: {