@reticlehq/server 3.5.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (721) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +123 -116
  3. package/dist/chromium-launch-options.d.ts +3 -1
  4. package/dist/chromium-launch-options.js +2 -1
  5. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  6. package/dist/command/cli/adhoc-suite.js +42 -7
  7. package/dist/command/cli/adhoc-verdict.d.ts +19 -2
  8. package/dist/command/cli/adhoc-verdict.js +76 -9
  9. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  10. package/dist/command/cli/answers/gate-exit.js +45 -0
  11. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  12. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  13. package/dist/command/cli/answers/open-note.d.ts +2 -0
  14. package/dist/command/cli/answers/open-note.js +22 -0
  15. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  16. package/dist/command/cli/auth/device-flow.js +17 -0
  17. package/dist/command/cli/cli-doctor.js +14 -0
  18. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  19. package/dist/command/cli/cli-flow-commands.js +31 -112
  20. package/dist/command/cli/cli-kill.js +3 -2
  21. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  22. package/dist/command/cli/cli-parse-grammar.js +75 -0
  23. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  24. package/dist/command/cli/cli-parse-verify.js +18 -0
  25. package/dist/command/cli/cli-parse.d.ts +19 -28
  26. package/dist/command/cli/cli-parse.js +82 -182
  27. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  28. package/dist/command/cli/cli-update-commands.js +61 -9
  29. package/dist/command/cli/cli-usage.d.ts +33 -0
  30. package/dist/command/cli/cli-usage.js +287 -0
  31. package/dist/command/cli/cli-verify.d.ts +35 -5
  32. package/dist/command/cli/cli-verify.js +114 -35
  33. package/dist/command/cli/cloud-cli.d.ts +13 -0
  34. package/dist/command/cli/cloud-cli.js +192 -341
  35. package/dist/command/cli/cloud-kit.d.ts +12 -0
  36. package/dist/command/cli/cloud-kit.js +41 -2
  37. package/dist/command/cli/cloud-link.d.ts +57 -0
  38. package/dist/command/cli/cloud-link.js +308 -0
  39. package/dist/command/cli/cloud-login.d.ts +22 -0
  40. package/dist/command/cli/cloud-login.js +96 -8
  41. package/dist/command/cli/context-command.d.ts +1 -0
  42. package/dist/command/cli/context-command.js +33 -0
  43. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  44. package/dist/command/cli/daemon-start-options.js +24 -3
  45. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
  46. package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
  47. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  48. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  49. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  50. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  51. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  52. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  53. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  54. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  55. package/dist/command/cli/drive/drive-attach.d.ts +27 -2
  56. package/dist/command/cli/drive/drive-attach.js +71 -4
  57. package/dist/command/cli/drive/drive-command.d.ts +2 -1
  58. package/dist/command/cli/drive/drive-command.js +13 -7
  59. package/dist/command/cli/known-regression.d.ts +13 -0
  60. package/dist/command/cli/known-regression.js +34 -0
  61. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  62. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  63. package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
  64. package/dist/command/cli/mcp-command.d.ts +6 -0
  65. package/dist/command/cli/mcp-command.js +13 -5
  66. package/dist/command/cli/ports/port-holder.d.ts +10 -0
  67. package/dist/command/cli/ports/port-holder.js +25 -1
  68. package/dist/command/cli/project-name.d.ts +29 -1
  69. package/dist/command/cli/project-name.js +107 -2
  70. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  71. package/dist/command/cli/setup-mcp-cli.js +35 -12
  72. package/dist/command/cli/status/status-lines.d.ts +1 -0
  73. package/dist/command/cli/status/status-lines.js +47 -2
  74. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  75. package/dist/command/cli/status/workspace-links.js +29 -0
  76. package/dist/command/cli/try-command.d.ts +96 -0
  77. package/dist/command/cli/try-command.js +362 -0
  78. package/dist/command/cli/tutorial.d.ts +0 -100
  79. package/dist/command/cli/tutorial.js +0 -181
  80. package/dist/command/cli/verify-results.d.ts +19 -0
  81. package/dist/command/cli/verify-results.js +29 -0
  82. package/dist/command/cli-onboarding.d.ts +0 -11
  83. package/dist/command/cli-onboarding.js +0 -15
  84. package/dist/command/cli.d.ts +20 -0
  85. package/dist/command/cli.js +130 -104
  86. package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
  87. package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
  88. package/dist/command/daemon/daemon-resilience.js +4 -4
  89. package/dist/command/daemon/daemon-resolve.d.ts +23 -1
  90. package/dist/command/daemon/daemon-resolve.js +79 -9
  91. package/dist/command/setup/agent-writer.d.ts +1 -1
  92. package/dist/command/setup/agent-writer.js +3 -2
  93. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  94. package/dist/command/setup/bringup/bridge-port.js +13 -3
  95. package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
  96. package/dist/command/setup/bringup/connect-lease.js +1 -0
  97. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  98. package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
  99. package/dist/command/setup/bringup/dev-server-wait.js +19 -0
  100. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  101. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  102. package/dist/command/setup/init/agent-restart.js +28 -0
  103. package/dist/command/setup/init/init-port.d.ts +14 -1
  104. package/dist/command/setup/init/init-port.js +32 -2
  105. package/dist/command/setup/init/init-runtime.d.ts +22 -2
  106. package/dist/command/setup/init/init-runtime.js +114 -38
  107. package/dist/command/setup/node-effects.d.ts +2 -0
  108. package/dist/command/setup/node-effects.js +38 -9
  109. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  110. package/dist/command/setup/probe/existing-app.js +14 -0
  111. package/dist/command/setup/remaining-steps.js +2 -1
  112. package/dist/command/setup/run-setup.d.ts +34 -9
  113. package/dist/command/setup/run-setup.js +65 -51
  114. package/dist/command/setup/setup-command.d.ts +25 -1
  115. package/dist/command/setup/setup-command.js +59 -4
  116. package/dist/command/setup/setup-mcp.js +25 -2
  117. package/dist/command/setup/tauri-signing.d.ts +19 -0
  118. package/dist/command/setup/tauri-signing.js +79 -0
  119. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  120. package/dist/command/setup/terminal/listeners.js +37 -6
  121. package/dist/command/update/update-nudge.d.ts +9 -0
  122. package/dist/command/update/update-nudge.js +1 -1
  123. package/dist/command/update/updater.js +11 -15
  124. package/dist/command/version/version-nudge.js +3 -0
  125. package/dist/command/version/version-skew.d.ts +20 -1
  126. package/dist/command/version/version-skew.js +49 -4
  127. package/dist/features/crawl/crawl-tools.js +4 -0
  128. package/dist/features/crawl/crawl.d.ts +6 -0
  129. package/dist/features/crawl/crawl.js +23 -2
  130. package/dist/features/exhaust/ledger.d.ts +21 -14
  131. package/dist/features/exhaust/ledger.js +35 -9
  132. package/dist/features/harness/app-findings.d.ts +2 -0
  133. package/dist/features/harness/app-findings.js +52 -0
  134. package/dist/features/harness/drive-report.d.ts +61 -1
  135. package/dist/features/harness/drive-report.js +394 -26
  136. package/dist/features/harness/drive-runs.d.ts +120 -0
  137. package/dist/features/harness/drive-runs.js +289 -0
  138. package/dist/features/harness/drivers.d.ts +10 -14
  139. package/dist/features/harness/drivers.js +10 -14
  140. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  141. package/dist/features/harness/explore/console-pages.js +146 -0
  142. package/dist/features/harness/explore/disparity.d.ts +19 -0
  143. package/dist/features/harness/explore/disparity.js +71 -0
  144. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  145. package/dist/features/harness/explore/fake-app.js +49 -0
  146. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  147. package/dist/features/harness/explore/goal-search.js +144 -0
  148. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  149. package/dist/features/harness/explore/page-tree.js +148 -0
  150. package/dist/features/harness/explore/site-map.d.ts +34 -0
  151. package/dist/features/harness/explore/site-map.js +150 -0
  152. package/dist/features/harness/fill-values.d.ts +3 -73
  153. package/dist/features/harness/fill-values.js +3 -169
  154. package/dist/features/harness/goals.d.ts +82 -0
  155. package/dist/features/harness/goals.js +330 -0
  156. package/dist/features/harness/harness.d.ts +51 -1
  157. package/dist/features/harness/harness.js +207 -6
  158. package/dist/features/harness/platform/drive-target.d.ts +30 -0
  159. package/dist/features/harness/platform/drive-target.js +81 -0
  160. package/dist/features/harness/platform/local-apps.d.ts +127 -0
  161. package/dist/features/harness/platform/local-apps.js +280 -0
  162. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  163. package/dist/features/harness/platform/persona-credentials.js +69 -0
  164. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  165. package/dist/features/harness/platform/platform-drives.js +114 -0
  166. package/dist/features/harness/platform/refusal.d.ts +52 -0
  167. package/dist/features/harness/platform/refusal.js +71 -0
  168. package/dist/features/harness/platform/remote-drive.d.ts +186 -0
  169. package/dist/features/harness/platform/remote-drive.js +378 -0
  170. package/dist/features/harness/platform/script.d.ts +94 -0
  171. package/dist/features/harness/platform/script.js +260 -0
  172. package/dist/features/harness/platform/server-driver.d.ts +54 -0
  173. package/dist/features/harness/platform/server-driver.js +182 -0
  174. package/dist/features/harness/platform-config.d.ts +41 -1
  175. package/dist/features/harness/platform-config.js +106 -9
  176. package/dist/features/harness/route-guess.d.ts +13 -0
  177. package/dist/features/harness/route-guess.js +49 -0
  178. package/dist/features/harness/script/app-controls.d.ts +5 -0
  179. package/dist/features/harness/script/app-controls.js +40 -0
  180. package/dist/features/harness/script/lane-ids.d.ts +14 -0
  181. package/dist/features/harness/script/lane-ids.js +16 -0
  182. package/dist/features/harness/script/script-run.d.ts +70 -0
  183. package/dist/features/harness/script/script-run.js +606 -0
  184. package/dist/features/license/license.d.ts +2 -2
  185. package/dist/features/visual/step-shots.d.ts +31 -0
  186. package/dist/features/visual/step-shots.js +231 -0
  187. package/dist/features/visual/visual-tools.d.ts +10 -1
  188. package/dist/features/visual/visual-tools.js +62 -17
  189. package/dist/hooks/client-directory.d.ts +18 -0
  190. package/dist/hooks/client-directory.js +57 -0
  191. package/dist/hooks/coding-agents.d.ts +34 -0
  192. package/dist/hooks/coding-agents.js +117 -0
  193. package/dist/hooks/driven-by.d.ts +23 -0
  194. package/dist/hooks/driven-by.js +56 -0
  195. package/dist/hooks/hook-bus.d.ts +4 -0
  196. package/dist/hooks/hook-bus.js +18 -0
  197. package/dist/hooks/hook-commands.js +15 -4
  198. package/dist/hooks/tool-log.d.ts +9 -0
  199. package/dist/hooks/tool-log.js +29 -0
  200. package/dist/index.d.ts +2 -0
  201. package/dist/index.js +80 -243
  202. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  203. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  204. package/dist/judgement/capsule/causal-summary.js +33 -0
  205. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  206. package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
  207. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  208. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  209. package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
  210. package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
  211. package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
  212. package/dist/judgement/runs/artifact/run-store.js +195 -3
  213. package/dist/judgement/runs/context-tools.js +59 -1
  214. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  215. package/dist/judgement/runs/default-run-id.js +16 -0
  216. package/dist/judgement/runs/drive-run.d.ts +71 -1
  217. package/dist/judgement/runs/drive-run.js +317 -5
  218. package/dist/judgement/runs/repair-prompt.js +1 -1
  219. package/dist/judgement/runs/resume.d.ts +44 -0
  220. package/dist/judgement/runs/resume.js +137 -0
  221. package/dist/judgement/runs/reticle-runner.js +13 -3
  222. package/dist/judgement/runs/runner-port.d.ts +5 -1
  223. package/dist/judgement/runs/runner-port.js +8 -2
  224. package/dist/judgement/runs/verification-sync.d.ts +5 -2
  225. package/dist/judgement/runs/verification-sync.js +40 -18
  226. package/dist/language/flows/change/gate.d.ts +10 -0
  227. package/dist/language/flows/change/gate.js +22 -0
  228. package/dist/language/flows/decision.js +36 -1
  229. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  230. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  231. package/dist/language/flows/flow-anchor.d.ts +61 -10
  232. package/dist/language/flows/flow-anchor.js +98 -6
  233. package/dist/language/flows/flow-cross-step.d.ts +15 -0
  234. package/dist/language/flows/flow-cross-step.js +21 -0
  235. package/dist/language/flows/flow-intent.d.ts +1 -0
  236. package/dist/language/flows/flow-journey.d.ts +6 -0
  237. package/dist/language/flows/flow-journey.js +20 -0
  238. package/dist/language/flows/flow-learning.d.ts +4 -0
  239. package/dist/language/flows/flow-learning.js +45 -14
  240. package/dist/language/flows/flow-mutate-tools.js +5 -3
  241. package/dist/language/flows/flow-replay-run.d.ts +23 -9
  242. package/dist/language/flows/flow-replay-run.js +115 -110
  243. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  244. package/dist/language/flows/flow-replay.d.ts +40 -1
  245. package/dist/language/flows/flow-replay.js +110 -22
  246. package/dist/language/flows/flow-result.d.ts +22 -1
  247. package/dist/language/flows/flow-result.js +47 -2
  248. package/dist/language/flows/flow-scope.js +5 -1
  249. package/dist/language/flows/flow-step-runners.d.ts +22 -2
  250. package/dist/language/flows/flow-step-runners.js +247 -47
  251. package/dist/language/flows/flow-store-for-session.d.ts +2 -2
  252. package/dist/language/flows/flow-store-for-session.js +7 -3
  253. package/dist/language/flows/flow-tools.d.ts +10 -0
  254. package/dist/language/flows/flow-tools.js +112 -89
  255. package/dist/language/flows/flows.d.ts +16 -1
  256. package/dist/language/flows/flows.js +74 -12
  257. package/dist/language/flows/heal-run.js +6 -4
  258. package/dist/language/flows/narrow-write.d.ts +7 -0
  259. package/dist/language/flows/narrow-write.js +36 -1
  260. package/dist/language/flows/recording/flake.d.ts +2 -2
  261. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  262. package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
  263. package/dist/language/flows/recording/tape/recordings.js +95 -13
  264. package/dist/language/flows/replay-from-hud.d.ts +20 -0
  265. package/dist/language/flows/replay-from-hud.js +51 -0
  266. package/dist/language/flows/replay.d.ts +9 -5
  267. package/dist/language/flows/replay.js +56 -15
  268. package/dist/language/flows/single-replay.d.ts +7 -0
  269. package/dist/language/flows/single-replay.js +26 -0
  270. package/dist/language/flows/suite/suite-flakes.js +2 -0
  271. package/dist/language/flows/suite-selection.d.ts +2 -15
  272. package/dist/language/flows/suite-selection.js +4 -3
  273. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  274. package/dist/language/flows/verify-change-tools.js +202 -191
  275. package/dist/launch-chromium.d.ts +27 -5
  276. package/dist/launch-chromium.js +38 -8
  277. package/dist/memory/cloud/cloud-config.d.ts +22 -1
  278. package/dist/memory/cloud/cloud-config.js +34 -5
  279. package/dist/memory/cloud/cloud-sync.d.ts +17 -14
  280. package/dist/memory/cloud/cloud-sync.js +15 -4
  281. package/dist/memory/cloud/harness-config.d.ts +75 -1
  282. package/dist/memory/cloud/harness-config.js +115 -24
  283. package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
  284. package/dist/memory/cloud/hud-notices-source.js +128 -0
  285. package/dist/memory/cloud/memory-scope.d.ts +161 -0
  286. package/dist/memory/cloud/memory-scope.js +227 -0
  287. package/dist/memory/cloud/sync-cycle.d.ts +44 -7
  288. package/dist/memory/cloud/sync-cycle.js +129 -15
  289. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  290. package/dist/memory/cloud/sync-daemon.js +121 -9
  291. package/dist/memory/cloud/sync-disk.d.ts +1 -1
  292. package/dist/memory/cloud/sync-disk.js +31 -10
  293. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  294. package/dist/memory/cloud/sync-screenshots.js +105 -0
  295. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  296. package/dist/memory/cloud/unsynced-roots.js +166 -0
  297. package/dist/memory/impact/account-watch.d.ts +34 -0
  298. package/dist/memory/impact/account-watch.js +59 -0
  299. package/dist/memory/impact/impact-recorder.d.ts +8 -0
  300. package/dist/memory/impact/impact-recorder.js +12 -2
  301. package/dist/memory/impact/impact-store.d.ts +17 -4
  302. package/dist/memory/impact/impact-store.js +169 -63
  303. package/dist/memory/intent/inline-intent.d.ts +1 -0
  304. package/dist/memory/intent/intent-shard-store.js +16 -4
  305. package/dist/memory/intent/intent-shard.d.ts +14 -2
  306. package/dist/memory/intent/intent-store.d.ts +1 -0
  307. package/dist/memory/intent/intent-tools.js +122 -4
  308. package/dist/memory/intent/open-intents.d.ts +6 -0
  309. package/dist/memory/intent/open-intents.js +10 -1
  310. package/dist/memory/intent/settled-words.d.ts +24 -0
  311. package/dist/memory/intent/settled-words.js +130 -0
  312. package/dist/memory/journal/drive-flow.d.ts +16 -0
  313. package/dist/memory/journal/drive-flow.js +34 -2
  314. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  315. package/dist/memory/journal/drive-run-flush.js +20 -5
  316. package/dist/memory/journal/envelope.d.ts +8 -8
  317. package/dist/memory/journal/journal-recorder.js +52 -3
  318. package/dist/memory/journal/on-disk/retention.d.ts +8 -0
  319. package/dist/memory/journal/on-disk/retention.js +32 -2
  320. package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
  321. package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
  322. package/dist/memory/journal/session-end.d.ts +15 -1
  323. package/dist/memory/journal/session-end.js +42 -9
  324. package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
  325. package/dist/memory/project/artifact-root-resolver.js +125 -16
  326. package/dist/memory/project/artifact-root.d.ts +46 -8
  327. package/dist/memory/project/artifact-root.js +89 -10
  328. package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
  329. package/dist/memory/project/dir/reticle-dir.js +26 -3
  330. package/dist/memory/project/link-directory.d.ts +15 -0
  331. package/dist/memory/project/link-directory.js +44 -0
  332. package/dist/memory/project/project-tools.js +22 -3
  333. package/dist/memory/project/root-claims.d.ts +6 -0
  334. package/dist/memory/project/root-claims.js +39 -0
  335. package/dist/memory/project/session-root.d.ts +26 -1
  336. package/dist/memory/project/session-root.js +49 -5
  337. package/dist/memory/project/sync-status.d.ts +85 -0
  338. package/dist/memory/project/sync-status.js +224 -0
  339. package/dist/memory/recall/memory-tools.js +47 -2
  340. package/dist/memory/recall/platform-memory.d.ts +34 -0
  341. package/dist/memory/recall/platform-memory.js +139 -0
  342. package/dist/memory/recall/project-memory.d.ts +19 -0
  343. package/dist/memory/recall/project-memory.js +80 -13
  344. package/dist/portal/bridge/bridge.d.ts +9 -3
  345. package/dist/portal/bridge/bridge.js +82 -22
  346. package/dist/portal/bridge/harness-request.d.ts +23 -0
  347. package/dist/portal/bridge/harness-request.js +27 -0
  348. package/dist/portal/bridge/pairing-token.d.ts +9 -0
  349. package/dist/portal/bridge/pairing-token.js +17 -0
  350. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  351. package/dist/portal/bridge/wrong-path.js +35 -0
  352. package/dist/portal/input/network-mock-tools.js +11 -2
  353. package/dist/portal/input/real-input.d.ts +83 -10
  354. package/dist/portal/input/real-input.js +218 -30
  355. package/dist/portal/input/viewport-tools.js +3 -3
  356. package/dist/portal/pool/browser-pool.d.ts +70 -9
  357. package/dist/portal/pool/browser-pool.js +190 -37
  358. package/dist/portal/pool/context-permissions.d.ts +33 -0
  359. package/dist/portal/pool/context-permissions.js +33 -0
  360. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  361. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  362. package/dist/portal/pool/playwright-launcher.d.ts +35 -0
  363. package/dist/portal/pool/playwright-launcher.js +64 -3
  364. package/dist/portal/pool/pool-contract.d.ts +28 -5
  365. package/dist/portal/session/agent-link.d.ts +8 -0
  366. package/dist/portal/session/agent-link.js +17 -0
  367. package/dist/portal/session/command-payload.d.ts +8 -0
  368. package/dist/portal/session/command-payload.js +24 -0
  369. package/dist/portal/session/daemon-answers.d.ts +3 -3
  370. package/dist/portal/session/daemon-answers.js +4 -2
  371. package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
  372. package/dist/portal/session/dev-server/dev-command.js +87 -12
  373. package/dist/portal/session/facts/departure-note.d.ts +22 -0
  374. package/dist/portal/session/facts/departure-note.js +47 -0
  375. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  376. package/dist/portal/session/facts/observed-state.js +46 -3
  377. package/dist/portal/session/facts/session-replaced.d.ts +5 -0
  378. package/dist/portal/session/facts/session-replaced.js +5 -0
  379. package/dist/portal/session/first-run-wiring.d.ts +42 -0
  380. package/dist/portal/session/first-run-wiring.js +132 -0
  381. package/dist/portal/session/human/live-control.d.ts +9 -2
  382. package/dist/portal/session/human/live-control.js +12 -3
  383. package/dist/portal/session/human/notes-ledger.d.ts +20 -0
  384. package/dist/portal/session/human/notes-ledger.js +55 -0
  385. package/dist/portal/session/human/review-store.d.ts +12 -0
  386. package/dist/portal/session/human/review-store.js +18 -10
  387. package/dist/portal/session/live-control-tools.d.ts +0 -13
  388. package/dist/portal/session/live-control-tools.js +107 -13
  389. package/dist/portal/session/narration-args.d.ts +5 -0
  390. package/dist/portal/session/narration-args.js +17 -0
  391. package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
  392. package/dist/portal/session/no-session-diagnosis.js +46 -9
  393. package/dist/portal/session/no-session-next-action.d.ts +31 -0
  394. package/dist/portal/session/no-session-next-action.js +159 -60
  395. package/dist/portal/session/no-session-watch.d.ts +14 -1
  396. package/dist/portal/session/no-session-watch.js +227 -17
  397. package/dist/portal/session/presence/session-lease.js +1 -1
  398. package/dist/portal/session/presence/session-mirror.js +3 -0
  399. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  400. package/dist/portal/session/recorded-gaps.js +251 -0
  401. package/dist/portal/session/serving-directory.d.ts +27 -0
  402. package/dist/portal/session/serving-directory.js +45 -0
  403. package/dist/portal/session/session-health.d.ts +18 -0
  404. package/dist/portal/session/session-health.js +9 -1
  405. package/dist/portal/session/session-info.d.ts +8 -1
  406. package/dist/portal/session/session-info.js +8 -1
  407. package/dist/portal/session/session-manager.d.ts +39 -0
  408. package/dist/portal/session/session-manager.js +98 -11
  409. package/dist/portal/session/session-reaper.js +4 -1
  410. package/dist/portal/session/session-successor.d.ts +13 -0
  411. package/dist/portal/session/session-successor.js +1 -1
  412. package/dist/portal/session/session-tools.js +26 -3
  413. package/dist/portal/session/session.d.ts +22 -30
  414. package/dist/portal/session/session.js +81 -79
  415. package/dist/portal/session/timing/command-timeout.js +25 -1
  416. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  417. package/dist/portal/session/timing/wall-clock.js +1 -1
  418. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  419. package/dist/portal/session/zero-install-first-call.js +88 -0
  420. package/dist/start-options.d.ts +12 -0
  421. package/dist/start-wiring.d.ts +63 -0
  422. package/dist/start-wiring.js +169 -0
  423. package/dist/status-payload.d.ts +23 -1
  424. package/dist/status-payload.js +36 -1
  425. package/dist/surface/http-server.js +18 -2
  426. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  427. package/dist/surface/mcp/attach-memory.js +12 -1
  428. package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
  429. package/dist/surface/mcp/mcp-proxy.js +65 -13
  430. package/dist/surface/mcp/mcp.d.ts +34 -6
  431. package/dist/surface/mcp/mcp.js +61 -17
  432. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  433. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  434. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  435. package/dist/surface/mcp/server-instructions.d.ts +4 -2
  436. package/dist/surface/mcp/server-instructions.js +32 -14
  437. package/dist/surface/mcp/shared-params.js +2 -2
  438. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  439. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  440. package/dist/surface/tools/account-tool.d.ts +22 -0
  441. package/dist/surface/tools/account-tool.js +157 -0
  442. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  443. package/dist/surface/tools/act/act-danger.js +38 -1
  444. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  445. package/dist/surface/tools/act/act-observation.js +57 -0
  446. package/dist/surface/tools/act/act-preflight.js +25 -2
  447. package/dist/surface/tools/act/act-target.js +8 -3
  448. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
  449. package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
  450. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  451. package/dist/surface/tools/act/resolve-target.js +18 -3
  452. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  453. package/dist/surface/tools/act/screen-request.js +113 -0
  454. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  455. package/dist/surface/tools/act/sequence-grade.js +13 -2
  456. package/dist/surface/tools/act/settle-in-flight.js +25 -3
  457. package/dist/surface/tools/act-sequence-tool.js +138 -29
  458. package/dist/surface/tools/act-tools.d.ts +0 -9
  459. package/dist/surface/tools/act-tools.js +71 -41
  460. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  461. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  462. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  463. package/dist/surface/tools/agent/app-notes.js +48 -0
  464. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  465. package/dist/surface/tools/agent/build-staleness.js +62 -0
  466. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  467. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  468. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  469. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  470. package/dist/surface/tools/agent/notices.d.ts +50 -0
  471. package/dist/surface/tools/agent/notices.js +152 -0
  472. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  473. package/dist/surface/tools/agent/reteach.js +50 -0
  474. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  475. package/dist/surface/tools/args/alias-args.js +10 -0
  476. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  477. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  478. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  479. package/dist/surface/tools/assert/assert-source.js +40 -0
  480. package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
  481. package/dist/surface/tools/assert/assert-verdict.js +42 -17
  482. package/dist/surface/tools/browser-tools.js +51 -2
  483. package/dist/surface/tools/chat-drives.d.ts +101 -0
  484. package/dist/surface/tools/chat-drives.js +409 -0
  485. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  486. package/dist/surface/tools/coverage-tools.js +2 -53
  487. package/dist/surface/tools/dynamic-tools.js +29 -1
  488. package/dist/surface/tools/empty-session-list.d.ts +51 -0
  489. package/dist/surface/tools/empty-session-list.js +120 -0
  490. package/dist/surface/tools/error-recovery.d.ts +14 -0
  491. package/dist/surface/tools/error-recovery.js +105 -8
  492. package/dist/surface/tools/explore-tools.d.ts +31 -1
  493. package/dist/surface/tools/explore-tools.js +438 -66
  494. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  495. package/dist/surface/tools/feedback-tools.js +18 -3
  496. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  497. package/dist/surface/tools/gap-novelty.js +8 -1
  498. package/dist/surface/tools/harness-explore.d.ts +118 -57
  499. package/dist/surface/tools/harness-explore.js +344 -292
  500. package/dist/surface/tools/harness-gate.d.ts +88 -0
  501. package/dist/surface/tools/harness-gate.js +235 -0
  502. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  503. package/dist/surface/tools/harness-hunt.js +215 -0
  504. package/dist/surface/tools/harness-plan.d.ts +17 -0
  505. package/dist/surface/tools/harness-plan.js +38 -0
  506. package/dist/surface/tools/harness-script.d.ts +30 -0
  507. package/dist/surface/tools/harness-script.js +560 -0
  508. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  509. package/dist/surface/tools/harness-tab-guard.js +27 -0
  510. package/dist/surface/tools/harness-toolset.d.ts +22 -1
  511. package/dist/surface/tools/harness-toolset.js +101 -7
  512. package/dist/surface/tools/human-notes.d.ts +16 -0
  513. package/dist/surface/tools/human-notes.js +27 -0
  514. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  515. package/dist/surface/tools/invoke-tool.js +263 -85
  516. package/dist/surface/tools/lease-hint.js +26 -5
  517. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  518. package/dist/surface/tools/lease-permissions.js +73 -0
  519. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  520. package/dist/surface/tools/lease-readiness.js +57 -0
  521. package/dist/surface/tools/lease-seed.d.ts +49 -0
  522. package/dist/surface/tools/lease-seed.js +167 -0
  523. package/dist/surface/tools/lease-tools.d.ts +13 -24
  524. package/dist/surface/tools/lease-tools.js +146 -197
  525. package/dist/surface/tools/live-call-text.js +4 -4
  526. package/dist/surface/tools/merge-tools.js +42 -2
  527. package/dist/surface/tools/merged-name-redirect.js +4 -0
  528. package/dist/surface/tools/next-step.d.ts +29 -0
  529. package/dist/surface/tools/next-step.js +214 -0
  530. package/dist/surface/tools/observe-tools.js +45 -9
  531. package/dist/surface/tools/platform-moment.d.ts +72 -0
  532. package/dist/surface/tools/platform-moment.js +296 -0
  533. package/dist/surface/tools/query-hint-schema.d.ts +7 -0
  534. package/dist/surface/tools/query-hint-schema.js +10 -0
  535. package/dist/surface/tools/read-tools.js +71 -14
  536. package/dist/surface/tools/real-input-attempt.js +96 -13
  537. package/dist/surface/tools/reticle-result.d.ts +120 -0
  538. package/dist/surface/tools/reticle-result.js +364 -0
  539. package/dist/surface/tools/tool-kit.d.ts +83 -3
  540. package/dist/surface/tools/tool-kit.js +77 -7
  541. package/dist/surface/tools/tools.js +43 -59
  542. package/dist/telemetry/account-envelope.d.ts +7 -0
  543. package/dist/telemetry/account-envelope.js +61 -0
  544. package/dist/telemetry/agent-client.d.ts +15 -0
  545. package/dist/telemetry/agent-client.js +57 -0
  546. package/dist/telemetry/app-instrumented.js +9 -2
  547. package/dist/telemetry/argument-shape.d.ts +7 -0
  548. package/dist/telemetry/argument-shape.js +86 -1
  549. package/dist/telemetry/automation-hint.d.ts +2 -3
  550. package/dist/telemetry/automation-hint.js +33 -8
  551. package/dist/telemetry/cli-telemetry.js +7 -2
  552. package/dist/telemetry/daemon-telemetry.js +3 -0
  553. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  554. package/dist/telemetry/error-fingerprint.js +61 -5
  555. package/dist/telemetry/feedback-cli.d.ts +0 -13
  556. package/dist/telemetry/feedback-cli.js +0 -77
  557. package/dist/telemetry/feedback.d.ts +13 -0
  558. package/dist/telemetry/feedback.js +183 -17
  559. package/dist/telemetry/harness-run.d.ts +18 -0
  560. package/dist/telemetry/harness-run.js +80 -0
  561. package/dist/telemetry/hud-events.d.ts +16 -0
  562. package/dist/telemetry/hud-events.js +27 -0
  563. package/dist/telemetry/hud-metrics.d.ts +29 -6
  564. package/dist/telemetry/hud-metrics.js +116 -25
  565. package/dist/telemetry/init-telemetry.js +2 -2
  566. package/dist/telemetry/install-source.d.ts +13 -25
  567. package/dist/telemetry/install-source.js +44 -3
  568. package/dist/telemetry/mcp-connection.d.ts +0 -14
  569. package/dist/telemetry/mcp-connection.js +5 -1
  570. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  571. package/dist/telemetry/onboarding-firsts.js +81 -6
  572. package/dist/telemetry/platform-linked.d.ts +5 -0
  573. package/dist/telemetry/platform-linked.js +32 -0
  574. package/dist/telemetry/project-profile.js +5 -3
  575. package/dist/telemetry/proxy-telemetry.js +4 -1
  576. package/dist/telemetry/session-metrics.d.ts +15 -4
  577. package/dist/telemetry/session-metrics.js +88 -52
  578. package/dist/telemetry/telemetry.d.ts +38 -2
  579. package/dist/telemetry/telemetry.js +144 -34
  580. package/dist/telemetry/verification-of.d.ts +3 -1
  581. package/dist/telemetry/verification-of.js +13 -4
  582. package/dist/wire-journal.d.ts +2 -2
  583. package/dist/wire-journal.js +20 -6
  584. package/docs/README.md +3 -3
  585. package/docs/actions.mdx +6 -3
  586. package/docs/adapters.md +1 -1
  587. package/docs/agent-cheatsheet.md +25 -28
  588. package/docs/architecture.md +5 -5
  589. package/docs/autodrive.md +33 -28
  590. package/docs/benchmarks.md +5 -5
  591. package/docs/best-practices.mdx +27 -9
  592. package/docs/capabilities.mdx +14 -16
  593. package/docs/cli/affected.mdx +1 -1
  594. package/docs/cli/cloud.mdx +54 -75
  595. package/docs/cli/doctor.mdx +14 -3
  596. package/docs/cli/drive.mdx +20 -14
  597. package/docs/cli/feedback.mdx +3 -3
  598. package/docs/cli/gate.mdx +7 -2
  599. package/docs/cli/help.mdx +50 -55
  600. package/docs/cli/init.mdx +43 -28
  601. package/docs/cli/license.mdx +12 -8
  602. package/docs/cli/mcp.mdx +4 -4
  603. package/docs/cli/open.mdx +3 -3
  604. package/docs/cli/report.mdx +4 -2
  605. package/docs/cli/restart.mdx +2 -2
  606. package/docs/cli/rollback.mdx +14 -8
  607. package/docs/cli/serve.mdx +4 -4
  608. package/docs/cli/setup.mdx +23 -0
  609. package/docs/cli/status.mdx +18 -5
  610. package/docs/cli/stop.mdx +67 -8
  611. package/docs/cli/try.mdx +62 -0
  612. package/docs/cli/update.mdx +4 -3
  613. package/docs/cli/verify.mdx +17 -6
  614. package/docs/cli/version.mdx +5 -4
  615. package/docs/cli.mdx +111 -42
  616. package/docs/debugging.md +3 -3
  617. package/docs/deploy-checks.md +1 -1
  618. package/docs/desktop.mdx +9 -3
  619. package/docs/enterprise.md +11 -10
  620. package/docs/environment.mdx +7 -8
  621. package/docs/faq.mdx +3 -3
  622. package/docs/first-drive.md +5 -4
  623. package/docs/flows.md +35 -27
  624. package/docs/for-agents.md +4 -5
  625. package/docs/frameworks.mdx +32 -21
  626. package/docs/getting-started.md +65 -61
  627. package/docs/human-control.md +16 -16
  628. package/docs/index.mdx +15 -42
  629. package/docs/install-agentic.mdx +22 -37
  630. package/docs/install-manual.mdx +23 -13
  631. package/docs/instrumentation.mdx +5 -3
  632. package/docs/integration-patterns.md +7 -7
  633. package/docs/license-activation.mdx +1 -1
  634. package/docs/multi-agent-testing.md +24 -6
  635. package/docs/packages/babel-plugin.mdx +4 -2
  636. package/docs/packages/browser.mdx +16 -10
  637. package/docs/packages/core.mdx +12 -5
  638. package/docs/packages/electron.mdx +3 -2
  639. package/docs/packages/engine.mdx +1 -1
  640. package/docs/packages/eslint-plugin.mdx +18 -12
  641. package/docs/packages/next.mdx +8 -7
  642. package/docs/packages/open-verification.mdx +1 -1
  643. package/docs/packages/server.mdx +5 -5
  644. package/docs/packages/tauri.mdx +9 -9
  645. package/docs/packages/test.mdx +4 -10
  646. package/docs/packages/vite-plugin.mdx +32 -4
  647. package/docs/packages.mdx +11 -15
  648. package/docs/platform-integration.md +6 -5
  649. package/docs/predicates.mdx +40 -24
  650. package/docs/quickstart.mdx +69 -30
  651. package/docs/required-checks.md +8 -7
  652. package/docs/reticle-manual.md +15 -5
  653. package/docs/skill-file.mdx +17 -79
  654. package/docs/skill-setup.md +9 -9
  655. package/docs/skill.md +200 -0
  656. package/docs/system-map.md +7 -7
  657. package/docs/telemetry.md +23 -25
  658. package/docs/testing.md +4 -4
  659. package/docs/token-efficiency.md +12 -12
  660. package/docs/tools/act-and-wait.mdx +9 -2
  661. package/docs/tools/act-sequence.mdx +6 -7
  662. package/docs/tools/act.mdx +2 -2
  663. package/docs/tools/assert.mdx +18 -17
  664. package/docs/tools/console.mdx +9 -9
  665. package/docs/tools/inspect.mdx +16 -7
  666. package/docs/tools/look.mdx +24 -0
  667. package/docs/tools/navigate.mdx +5 -3
  668. package/docs/tools/network.mdx +2 -2
  669. package/docs/tools/observe.mdx +6 -6
  670. package/docs/tools/overview.mdx +34 -33
  671. package/docs/tools/query.mdx +5 -5
  672. package/docs/tools/session-and-feedback.mdx +22 -13
  673. package/docs/tools/sessions.mdx +8 -8
  674. package/docs/tools/snapshot.mdx +6 -5
  675. package/docs/tools/state.mdx +9 -9
  676. package/docs/tools/tools-and-run.mdx +26 -24
  677. package/docs/tools/verify.mdx +28 -0
  678. package/docs/tools/wait-for.mdx +8 -4
  679. package/docs/troubleshooting.mdx +21 -6
  680. package/docs/usage.md +55 -46
  681. package/docs/use-cases.mdx +3 -3
  682. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  683. package/docs/vs-playwright-mcp.mdx +3 -1
  684. package/docs/what-is-recorded.md +17 -5
  685. package/docs/what-is-reticle.mdx +5 -3
  686. package/docs/why-reticle.mdx +1 -1
  687. package/package.json +9 -12
  688. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  689. package/dist/command/cli/demo/demo-page.js +0 -241
  690. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  691. package/dist/command/cli/demo/demo-run.js +0 -138
  692. package/dist/features/harness/driver.d.ts +0 -50
  693. package/dist/features/harness/driver.js +0 -236
  694. package/dist/features/harness/jev-driver.d.ts +0 -188
  695. package/dist/features/harness/jev-driver.js +0 -678
  696. package/dist/features/harness/openai-driver.d.ts +0 -58
  697. package/dist/features/harness/openai-driver.js +0 -206
  698. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  699. package/dist/judgement/hunt/hunt-report.js +0 -84
  700. package/dist/language/flows/buddy-status.d.ts +0 -25
  701. package/dist/language/flows/buddy-status.js +0 -32
  702. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  703. package/dist/language/flows/change/watch-batcher.js +0 -19
  704. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  705. package/dist/memory/cloud/harness-offer.js +0 -145
  706. package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
  707. package/dist/memory/project/dir/fill-value-store.js +0 -88
  708. package/dist/surface/tools/feature-capture.d.ts +0 -151
  709. package/dist/surface/tools/feature-capture.js +0 -235
  710. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  711. package/dist/surface/tools/tool-hit-rate.js +0 -90
  712. package/dist/telemetry/harness-drive.d.ts +0 -4
  713. package/dist/telemetry/harness-drive.js +0 -35
  714. package/dist/telemetry/identify.d.ts +0 -22
  715. package/dist/telemetry/identify.js +0 -73
  716. package/docs/cli/capsules.mdx +0 -70
  717. package/docs/cli/hunt.mdx +0 -73
  718. package/docs/cli/identify.mdx +0 -76
  719. package/docs/cli/kill.mdx +0 -91
  720. package/docs/cli/watch.mdx +0 -62
  721. package/docs/local-registry.md +0 -143
@@ -1,23 +1,27 @@
1
1
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
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';
2
5
  import { dirname, join } from 'node:path';
3
6
  import { homedir } from 'node:os';
4
7
  import { readAccountState } from '../cloud/account-state.js';
5
- import { harnessOfferSource } from '../cloud/harness-offer.js';
8
+ import { configForHud } from '../cloud/harness-config.js';
9
+ import { hudNoticesSource } from '../cloud/hud-notices-source.js';
10
+ import { selectNotices } from '@reticlehq/core/hud';
6
11
  import { ReticleDir, IMPACT_DAILY_BUCKETS, IMPACT_DEFECT_LIMIT, IMPACT_SCHEMA_VERSION, ImpactScopeSchema, addImpactCounts, emptyImpactCounts, emptyImpactRecords, estimateImpactSavings, } from '@reticlehq/core';
7
12
  /**
8
13
  * Where Reticle keeps the record of what it has done for you.
9
14
  *
10
- * Two scopes, two files, both local and never uploaded: the project's own `.reticle/impact.json`,
11
- * and a machine-wide `~/.reticle/impact.json` that answers "what has Reticle done for me overall"
12
- * across every app you have instrumented.
15
+ * Two scopes, two files: the project's own `.reticle/impact.json`, and a machine-wide
16
+ * `~/.reticle/impact.json` that answers "what has Reticle done for me overall" across every app you
17
+ * have instrumented.
13
18
  *
14
- * This is NOT telemetry. Telemetry answers our questions about the product and leaves the machine;
15
- * this answers the user's question about their own work and never does.
19
+ * This is NOT telemetry. Telemetry answers our questions about the product; this answers the user's
20
+ * question about their own work. A linked project's record syncs to that user's own dashboard (the
21
+ * sync cycle's `impact` kind); the machine-wide record never leaves the machine.
16
22
  */
17
23
  /** Writes are debounced: a verification loop is 50-200 calls, and each one is a counter bump. */
18
24
  const WRITE_DEBOUNCE_MS = 800;
19
- /** The project's cloud binding, written by `reticle link`. Absent for an unlinked project. */
20
- const CLOUD_LINK_FILE = 'cloud.json';
21
25
  /**
22
26
  * `reticleRoot` is the project's own `.reticle` directory (what every other store here is handed);
23
27
  * the global scope lives beside the daemon's own state in `~/.reticle`.
@@ -32,26 +36,6 @@ function impactPaths(reticleRoot, globalRoot) {
32
36
  global: join(globalRoot, ReticleDir.ROOT, ReticleDir.IMPACT_FILE),
33
37
  };
34
38
  }
35
- /**
36
- * Where this project's dashboard lives, if `reticle link` recorded one.
37
- *
38
- * Read from the link file rather than derived from the API url, because the API origin and the
39
- * console origin are different hosts in every deployment that is not a laptop. Synchronous and
40
- * best-effort, like every other read in this file: a missing or malformed link file means no link
41
- * in the HUD, never a failed tool call.
42
- */
43
- function readDashboardUrl(reticleRoot) {
44
- try {
45
- const raw = JSON.parse(readFileSync(join(reticleRoot, CLOUD_LINK_FILE), 'utf8'));
46
- if ('object' !== typeof raw || null === raw)
47
- return undefined;
48
- const value = raw['dashboardUrl'];
49
- return 'string' === typeof value && value.length > 0 ? value : undefined;
50
- }
51
- catch {
52
- return undefined;
53
- }
54
- }
55
39
  function emptyScope(now) {
56
40
  const counts = emptyImpactCounts();
57
41
  return {
@@ -92,6 +76,12 @@ function writeScope(path, scope) {
92
76
  // memory and the next write attempt carries them.
93
77
  }
94
78
  }
79
+ /** The daemon's cached copy of the HUD notices file, beside the machine-wide impact record. */
80
+ const HUD_NOTICES_CACHE_FILE = 'hud-notices.json';
81
+ /** How long a sync status is reused before it is read again. */
82
+ const SYNC_STATUS_EVERY_MS = 10_000;
83
+ /** When the caller did not say which build this is: matches only notices with no `minSdk`. */
84
+ const UNKNOWN_SDK_VERSION = '0.0.0';
95
85
  /** YYYY-MM-DD in local time - the day boundary a person recognises, not UTC's. */
96
86
  export function isoDay(now) {
97
87
  const d = new Date(now);
@@ -105,33 +95,55 @@ function isNextDay(a, b) {
105
95
  const next = new Date(`${b}T00:00:00`);
106
96
  return 1 === Math.round((next.getTime() - prev.getTime()) / 86_400_000);
107
97
  }
98
+ /**
99
+ * Consecutive days ending at the newest recorded day, read from the days themselves.
100
+ *
101
+ * It was a counter bumped when a fold opened a new day and compared only with the bucket before it,
102
+ * so one stray day in between (a late flush from another daemon, a writer with a frozen clock) reset
103
+ * it to 1. Counting back from the newest date means no out-of-order write can shorten it.
104
+ */
105
+ function streakEndingAtLatest(sortedDates) {
106
+ let streak = 0;
107
+ let later;
108
+ for (let i = sortedDates.length - 1; i >= 0; i -= 1) {
109
+ const date = sortedDates[i];
110
+ if (date === undefined)
111
+ break;
112
+ if (later !== undefined && !isNextDay(date, later))
113
+ break;
114
+ streak += 1;
115
+ later = date;
116
+ }
117
+ return streak;
118
+ }
108
119
  /** Fold one delta into a scope: totals, today's bucket, records and streak. Pure. */
109
120
  export function applyDelta(scope, delta, now, meta = {}) {
110
121
  const today = isoDay(now);
111
122
  const counts = addImpactCounts(scope.counts, delta);
112
- const days = scope.days.slice();
113
- const last = days[days.length - 1];
114
- if (last !== undefined && last.date === today) {
115
- days[days.length - 1] = { date: today, counts: addImpactCounts(last.counts, delta) };
116
- }
117
- else {
118
- days.push({ date: today, counts: addImpactCounts(emptyImpactCounts(), delta) });
123
+ // One bucket per date, wherever the delta's date falls. The machine-wide record has many writers
124
+ // and a late flush carries an older date, so "the last bucket is today" is not something a fold
125
+ // may assume — appending on that assumption duplicated dates and put them out of order.
126
+ const byDate = new Map();
127
+ for (const day of scope.days) {
128
+ byDate.set(day.date, addImpactCounts(byDate.get(day.date) ?? emptyImpactCounts(), day.counts));
119
129
  }
130
+ const todayCounts = addImpactCounts(byDate.get(today) ?? emptyImpactCounts(), delta);
131
+ byDate.set(today, todayCounts);
132
+ const dates = [...byDate.keys()].sort();
133
+ const days = dates.map((date) => ({ date, counts: byDate.get(date) ?? emptyImpactCounts() }));
120
134
  while (days.length > IMPACT_DAILY_BUCKETS)
121
135
  days.shift();
122
- const todayCounts = days[days.length - 1]?.counts ?? emptyImpactCounts();
123
- const previousDay = days[days.length - 2];
124
136
  const records = { ...scope.records };
125
137
  records.bestVerdictDay = Math.max(records.bestVerdictDay, todayCounts.verdicts);
126
138
  records.bestDefectDay = Math.max(records.bestDefectDay, todayCounts.failed);
127
- if (last === undefined || last.date !== today) {
128
- // A new day joins the streak only if it follows yesterday; otherwise it starts a new one.
129
- records.streakDays =
130
- previousDay !== undefined && isNextDay(previousDay.date, today) ? records.streakDays + 1 : 1;
131
- }
132
- else if (0 === records.streakDays) {
133
- records.streakDays = 1;
134
- }
139
+ // The window keeps IMPACT_DAILY_BUCKETS days, so a streak longer than it cannot be read off the
140
+ // dates alone: when the whole window is one unbroken run, it continues the streak already held.
141
+ const inWindow = streakEndingAtLatest(dates);
142
+ const unbroken = inWindow === dates.length && scope.days.length >= IMPACT_DAILY_BUCKETS;
143
+ const newDay = !scope.days.some((day) => day.date === today);
144
+ records.streakDays = unbroken
145
+ ? Math.max(inWindow, scope.records.streakDays + (newDay ? 1 : 0))
146
+ : inWindow;
135
147
  records.bestStreakDays = Math.max(records.bestStreakDays, records.streakDays);
136
148
  records.longestRunMs = Math.max(records.longestRunMs, meta.runMs ?? 0);
137
149
  /*
@@ -150,6 +162,41 @@ export function applyDelta(scope, delta, now, meta = {}) {
150
162
  defects,
151
163
  };
152
164
  }
165
+ /** The larger of two counters, key by key. */
166
+ function maxEach(a, b) {
167
+ const out = { ...a };
168
+ for (const key of Object.keys(b))
169
+ out[key] = Math.max(a[key] ?? 0, b[key] ?? 0);
170
+ return out;
171
+ }
172
+ /**
173
+ * All time, never smaller than the project being looked at.
174
+ *
175
+ * The two scopes live in different files: the project's in its `.reticle`, the machine's in the
176
+ * home directory. A project whose history began before this machine's ledger (an upgrade, a new
177
+ * laptop, a moved checkout) showed more under "This project" than under "All time", which no reader
178
+ * can believe. The machine has done at least what any one of its projects has.
179
+ */
180
+ export function atLeastProject(global, project) {
181
+ // The earlier of the two starts; zero is "never recorded", not the epoch.
182
+ const starts = [global.since, project.since].filter((t) => 0 < t);
183
+ return {
184
+ ...global,
185
+ counts: maxEach(global.counts, project.counts),
186
+ records: maxEach(global.records, project.records),
187
+ savings: {
188
+ tokens: {
189
+ ...global.savings.tokens,
190
+ value: Math.max(global.savings.tokens.value, project.savings.tokens.value),
191
+ },
192
+ minutes: {
193
+ ...global.savings.minutes,
194
+ value: Math.max(global.savings.minutes.value, project.savings.minutes.value),
195
+ },
196
+ },
197
+ since: 0 === starts.length ? 0 : Math.min(...starts),
198
+ };
199
+ }
153
200
  /**
154
201
  * The live impact record for one project.
155
202
  *
@@ -158,6 +205,9 @@ export function applyDelta(scope, delta, now, meta = {}) {
158
205
  */
159
206
  export class ImpactStore {
160
207
  #paths;
208
+ #root;
209
+ /** The sync status, re-read at most every SYNC_STATUS_EVERY_MS: it reads every run file. */
210
+ #sync;
161
211
  #now;
162
212
  #projectName;
163
213
  #dashboardUrl;
@@ -175,10 +225,12 @@ export class ImpactStore {
175
225
  #timer;
176
226
  #onChange;
177
227
  #account;
178
- /** Where this workspace stands with the free harness offer. Cached; see harness-offer.ts. */
179
- #offer;
180
228
  #config;
229
+ #notices;
230
+ #sdkVersion;
231
+ #coverage;
181
232
  constructor(opts) {
233
+ this.#coverage = opts.coverage;
182
234
  this.#paths = impactPaths(opts.reticleRoot, opts.globalRoot ?? homedir());
183
235
  // Resolved per snapshot, not cached: a user who runs `reticle login` in another terminal must
184
236
  // see the HUD change without restarting the daemon that is watching their app.
@@ -186,9 +238,13 @@ export class ImpactStore {
186
238
  this.#now = opts.now ?? (() => Date.now());
187
239
  this.#projectName = opts.projectName;
188
240
  this.#dashboardUrl = readDashboardUrl(opts.reticleRoot);
189
- // The claim happens in the console, so the link this project was linked to IS the claim link —
190
- // built here rather than in the HUD, which has no way to know where this project points.
191
- this.#offer = opts.offer ?? harnessOfferSource(process.env, () => this.#dashboardUrl);
241
+ this.#root = opts.reticleRoot;
242
+ this.#notices =
243
+ opts.notices ??
244
+ hudNoticesSource({
245
+ cacheFile: join(opts.globalRoot ?? homedir(), ReticleDir.ROOT, HUD_NOTICES_CACHE_FILE),
246
+ });
247
+ this.#sdkVersion = opts.sdkVersion ?? UNKNOWN_SDK_VERSION;
192
248
  // No default: the loader lives in `features/harness` and this file may not reach for it.
193
249
  // A store built without one simply reports no harness config, which the HUD renders as no row.
194
250
  this.#config = opts.config ?? { read: () => undefined };
@@ -196,6 +252,46 @@ export class ImpactStore {
196
252
  this.#project = readScope(this.#paths.project, now);
197
253
  this.#global = readScope(this.#paths.global, now);
198
254
  }
255
+ #syncStatus(dashboardUrl) {
256
+ const now = this.#now();
257
+ if (this.#sync !== undefined && now - this.#sync.at < SYNC_STATUS_EVERY_MS)
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
+ }
276
+ const summary = readSyncSummary(this.#root, true);
277
+ const refusal = keyRefusalAtLastSync(this.#root);
278
+ const latest = summary.latestOnPlatform;
279
+ const value = {
280
+ status: overallStatus(summary),
281
+ runs: summary.runs,
282
+ onPlatform: summary.onPlatform,
283
+ pending: summary.pending,
284
+ refused: summary.refused.length + summary.refusedMore,
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) }),
288
+ said: describeSync(summary, now),
289
+ // The HUD's chip: a refused key is not "0 waiting".
290
+ ...(refusal === undefined ? {} : { keyRefused: refusal }),
291
+ };
292
+ this.#sync = { at: now, value };
293
+ return value;
294
+ }
199
295
  /** Notified after every fold, so the HUD can be pushed a fresh snapshot. */
200
296
  onChange(fn) {
201
297
  this.#onChange = fn;
@@ -214,28 +310,38 @@ export class ImpactStore {
214
310
  const snap = {
215
311
  schemaVersion: IMPACT_SCHEMA_VERSION,
216
312
  project: this.#project,
217
- global: this.#global,
313
+ global: atLeastProject(this.#global, this.#project),
218
314
  };
219
315
  if (this.#projectName !== undefined)
220
316
  snap.projectName = this.#projectName;
317
+ // Re-read, like the account: `reticle link` runs in another terminal while this store lives as
318
+ // long as the daemon, so a construction-time read said "Not linked" until a restart.
319
+ this.#dashboardUrl = readDashboardUrl(this.#root);
221
320
  if (this.#dashboardUrl !== undefined)
222
321
  snap.dashboardUrl = this.#dashboardUrl;
223
322
  snap.account = this.#account();
224
- const cfgForOffer = this.#config.read();
225
- const offer = this.#offer.read();
226
- // Joined here because this is the one place that holds BOTH the offer and the platform config.
227
- // The card reads the offer, so readiness has to travel on it rather than being re-derived in a
228
- // presenter that has no business knowing what a provider key is.
229
- if (offer !== undefined && cfgForOffer !== undefined)
230
- offer.drivable = cfgForOffer.providerReady;
231
- // Absent means "we have not heard", which the HUD renders as nothing at all. Never defaulted to
232
- // `{claimed:false}`: that would advertise the offer to everyone who is offline.
233
- if (offer !== undefined)
234
- snap.harnessOffer = offer;
235
323
  // Absent stays absent: the HUD reads that as "we have not heard" and renders no control.
236
324
  const cfg = this.#config.read();
237
325
  if (cfg !== undefined)
238
- snap.harnessConfig = cfg;
326
+ snap.harnessConfig = configForHud(cfg, this.#now());
327
+ // Chosen here, where the account and the entitlement are both known. Absent when nothing applies,
328
+ // so the HUD falls back to the slides bundled with the SDK.
329
+ const notices = selectNotices(this.#notices.read(), {
330
+ signedIn: snap.account?.signedIn,
331
+ entitled: cfg?.harnessEntitled,
332
+ sdkVersion: this.#sdkVersion,
333
+ now: this.#now(),
334
+ });
335
+ if (0 < notices.length)
336
+ snap.notices = notices;
337
+ const coverage = this.#coverage?.();
338
+ if (coverage !== undefined)
339
+ snap.coverage = coverage;
340
+ // Only for a linked project: an unlinked one has nothing on the platform, and the HUD already
341
+ // offers the way to link it.
342
+ const sync = this.#syncStatus(this.#dashboardUrl);
343
+ if (sync !== undefined)
344
+ snap.sync = sync;
239
345
  return snap;
240
346
  }
241
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;
@@ -252,7 +262,6 @@ export declare const IntentShardSchema: z.ZodObject<{
252
262
  }>>;
253
263
  }, "strip", z.ZodTypeAny, {
254
264
  version: 1;
255
- subject: string;
256
265
  intents: Record<string, {
257
266
  status: "proved" | "proposed" | "agreed" | "stale";
258
267
  state: "proved" | "declared" | "bound";
@@ -273,15 +282,16 @@ export declare const IntentShardSchema: z.ZodObject<{
273
282
  at: number;
274
283
  grade: string;
275
284
  verdictId: string;
285
+ runId?: string | undefined;
276
286
  } | undefined;
277
287
  amended?: {
278
288
  at: number;
279
289
  statement: string;
280
290
  }[] | undefined;
281
291
  }>;
292
+ subject: string;
282
293
  }, {
283
294
  version: 1;
284
- subject: string;
285
295
  intents: Record<string, {
286
296
  status: "proved" | "proposed" | "agreed" | "stale";
287
297
  state: "proved" | "declared" | "bound";
@@ -302,12 +312,14 @@ export declare const IntentShardSchema: z.ZodObject<{
302
312
  at: number;
303
313
  grade: string;
304
314
  verdictId: string;
315
+ runId?: string | undefined;
305
316
  } | undefined;
306
317
  amended?: {
307
318
  at: number;
308
319
  statement: string;
309
320
  }[] | undefined;
310
321
  }>;
322
+ subject: string;
311
323
  }>;
312
324
  export type IntentShard = z.infer<typeof IntentShardSchema>;
313
325
  export declare const IntentIndexSchema: z.ZodObject<{
@@ -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
  }
@@ -1,8 +1,14 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
1
3
  import { z } from 'zod';
4
+ import { StatementSource, classifyStatement, splitStatements, } from '@reticlehq/core/artifacts';
5
+ import { redactFeedbackText } from '../../telemetry/feedback.js';
6
+ import { reticleDirPaths } from '../project/dir/reticle-dir.js';
2
7
  import { IntentStore } from './intent-store.js';
3
8
  import { IntentShardStore } from './intent-shard-store.js';
4
9
  import { IntentStatus } from './intent-shard.js';
5
- import { ReticleTool } from '@reticlehq/core';
10
+ import { UNSORTED_SUBJECT } from './intent-subject.js';
11
+ import { ReticleDir, ReticleTool, apiKeyFrom } from '@reticlehq/core';
6
12
  import { sessionIdShape } from '../../surface/tools/tool-kit.js';
7
13
  import { PredicateSchema } from '@reticlehq/engine/question/predicate/predicate.js';
8
14
  import { sessionRoot } from '../project/session-root.js';
@@ -32,7 +38,7 @@ const MIGRATE = 'migrate';
32
38
  export const INTENT_TOOLS = [
33
39
  {
34
40
  name: ReticleTool.INTENT,
35
- description: 'Record what a change is SUPPOSED to make true, as a durable statement ABOUT THE PRODUCT that a teammate who was not here will understand in six months — name the behaviour, not this run or its step number, and never "renders cleanly", which nothing can check. It is SHARED memory: pooled per project and read back by later agents. Capture it while you still know — then verification does not have to re-derive it from the DOM later. { action:"declare", intents:[{ id, statement, surface? }] } takes prose and needs NO predicate: at declare time there is often no route, no ref and no code yet, and a predicate demanded there is just a mechanism. Declare EARLY (as you build) and batch them — one call per feature is the whole budget. { action:"bind", id, binding } attaches the predicate that would prove it once you know how; an intent with no binding is not a failure, it is the most interesting row in the ledger — something meant that nothing can currently prove. { action:"list" } returns what is still open. Stored in .reticle/intent/<subject>/intent.json (a flow name is its subject), git-checked so a human sees in review if an intent was later narrowed to match what was easy to prove.',
41
+ description: 'Record what a change is SUPPOSED to make true, as a durable statement ABOUT THE PRODUCT that a teammate who was not here will understand in six months — name the behaviour, not this run or its step number, and never "renders cleanly", which nothing can check. It is SHARED memory: pooled per project and read back by later agents. Capture it while you still know — then verification does not have to re-derive it from the DOM later. { action:"declare", intents:[{ id, statement, surface? }] } takes prose and needs NO predicate: at declare time there is often no route, no ref and no code yet, and a predicate demanded there is just a mechanism. Declare EARLY (as you build) and batch them — one call per feature is the whole budget. { action:"bind", id, binding } attaches the predicate that would prove it once you know how; an intent with no binding is not a failure, it is the most interesting row in the ledger — something meant that nothing can currently prove. { action:"list" } returns what is still open. Pass `request` (what the user asked, verbatim) once per task. Stored in .reticle/intent/, git-checked.',
36
42
  example: {
37
43
  action: DECLARE,
38
44
  intents: [
@@ -74,6 +80,7 @@ export const INTENT_TOOLS = [
74
80
  .min(1)
75
81
  .optional()
76
82
  .describe('declare only. Batchable — declare every intent for a feature in one call.'),
83
+ request: z.string().optional().describe("declare: the user's words, verbatim."),
77
84
  id: z.string().optional().describe('bind only: which intent the predicate proves.'),
78
85
  /*
79
86
  * The predicate schema, not `unknown`.
@@ -101,6 +108,11 @@ export const INTENT_TOOLS = [
101
108
  .optional()
102
109
  .describe('declare only: statements not stored, and why.'),
103
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'),
104
116
  entries: z
105
117
  .array(z.unknown())
106
118
  .optional()
@@ -155,19 +167,125 @@ export const INTENT_TOOLS = [
155
167
  return { intents: await store.open() };
156
168
  }
157
169
  const raw = args['intents'];
170
+ const request = asString(args['request']);
171
+ if (request !== undefined && 0 < request.trim().length) {
172
+ await recordRequest(deps, root, request, Array.isArray(raw) ? raw : []);
173
+ if (!Array.isArray(raw) || 0 === raw.length)
174
+ return { request: 'recorded', path: root };
175
+ }
158
176
  // Refused, not read as an empty list: `declare` with nothing to declare stored nothing and
159
177
  // answered `{ intents: [] }`, which an agent reads as a declaration that worked (#1118).
160
178
  if (!Array.isArray(raw) || 0 === raw.length) {
161
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`);
162
180
  }
163
- const entries = raw;
181
+ const { entries, missing } = await withExistingFiles(deps, dirname(root), raw);
164
182
  const declared = await store.declare(entries);
165
183
  // Said, not swallowed: an agent that declared something and finds nothing stored would
166
184
  // otherwise conclude the ledger lost it.
167
185
  const refused = entries
168
186
  .filter((entry) => isActionLabel(entry.statement))
169
187
  .map((entry) => ({ id: entry.id, reason: STEP_LABEL_REFUSAL }));
170
- 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
+ };
171
201
  },
172
202
  },
173
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.';
226
+ const MAX_REQUEST = 20_000;
227
+ const MAX_STATEMENT = 500;
228
+ const MAX_STATEMENTS = 100;
229
+ const PROJECT_CONFIG = '.reticle.json';
230
+ /** Credentials and personal data out, length capped: the same rules feedback reports follow. */
231
+ function redactSecrets(text, max) {
232
+ return redactFeedbackText(text, max).text;
233
+ }
234
+ /**
235
+ * Whether the request goes to the platform with the runs that verify it.
236
+ *
237
+ * A LINKED project shares it unless `.reticle.json` says `"shareRequests": false`: the platform
238
+ * reads what each run was for, which is half of what a run means. An unlinked project has nowhere
239
+ * to send it, and `"shareRequests": true` still shares from one that links later.
240
+ */
241
+ function sharesRequests(projectDir, reticleRoot) {
242
+ let setting;
243
+ try {
244
+ const config = JSON.parse(readFileSync(join(projectDir, PROJECT_CONFIG), 'utf8'));
245
+ setting = config?.shareRequests;
246
+ }
247
+ catch {
248
+ setting = undefined;
249
+ }
250
+ if (false === setting)
251
+ return false;
252
+ if (true === setting)
253
+ return true;
254
+ // Linked by `reticle connect` (cloud.json), or by a key in the environment, the way CI syncs.
255
+ return (existsSync(join(reticleRoot, ReticleDir.CLOUD_LINK_FILE)) ||
256
+ apiKeyFrom(process.env) !== undefined);
257
+ }
258
+ /**
259
+ * Keep the user's request, and every statement in it and in the declared intents, classified and
260
+ * attributed, for the runs that verify it. Secrets are redacted before anything is written.
261
+ *
262
+ * Shared with the platform from a linked project unless `.reticle.json` says `"shareRequests": false`.
263
+ */
264
+ async function recordRequest(deps, root, request, declared) {
265
+ const text = redactSecrets(request, MAX_REQUEST);
266
+ const agentStatements = declared.flatMap((d) => {
267
+ const statement = d?.statement;
268
+ return 'string' === typeof statement ? [statement] : [];
269
+ });
270
+ const context = {
271
+ request: text,
272
+ statements: [
273
+ ...splitStatements(text).map((t) => ({ text: t, source: StatementSource.USER })),
274
+ ...agentStatements.map((t) => ({
275
+ text: redactSecrets(t, MAX_STATEMENT),
276
+ source: StatementSource.AGENT,
277
+ })),
278
+ ]
279
+ .slice(0, MAX_STATEMENTS)
280
+ .map((s) => ({
281
+ ...s,
282
+ text: s.text.slice(0, MAX_STATEMENT),
283
+ kind: classifyStatement(s.text),
284
+ })),
285
+ at: deps.now(),
286
+ shared: sharesRequests(dirname(root), root),
287
+ };
288
+ const path = reticleDirPaths(root).request;
289
+ await deps.fs.mkdir(dirname(path));
290
+ await deps.fs.writeFile(path, `${JSON.stringify(context, null, 2)}\n`);
291
+ }