@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
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { readFileSync, readdirSync } from 'node:fs';
12
12
  import { join } from 'node:path';
13
- import { desktopLaunch, workspacePackageDirs } from '@reticlehq/init';
13
+ import { RETICLE_NPM_PACKAGE, desktopLaunch, workspacePackageDirs } from '@reticlehq/init';
14
14
  /**
15
15
  * Script names checked, in order.
16
16
  *
@@ -23,7 +23,17 @@ const DEV_SCRIPTS = ['dev', 'develop', 'start'];
23
23
  const LOCKFILES = [
24
24
  { file: 'pnpm-lock.yaml', manager: 'pnpm' },
25
25
  { file: 'yarn.lock', manager: 'yarn' },
26
+ { file: 'bun.lockb', manager: 'bun' },
27
+ { file: 'bun.lock', manager: 'bun' },
26
28
  ];
29
+ /** The one-off runner each manager ships, for running Reticle's CLI without installing it. */
30
+ const RUNNER = { pnpm: 'pnpm dlx', bun: 'bunx' };
31
+ const NPX = 'npx';
32
+ const YARN = 'yarn';
33
+ /** `yarn dlx` exists only on Yarn 2+, which is the yarn that writes this file; classic yarn has none. */
34
+ const YARN_BERRY_MARKER = '.yarnrc.yml';
35
+ const YARN_DLX = 'yarn dlx';
36
+ const INIT_VERB = 'init';
27
37
  const DEFAULT_PACKAGE_MANAGER = 'npm';
28
38
  const PACKAGE_JSON = 'package.json';
29
39
  /** `--port 4311` / `--port=4311`, the flag every dev server in this list accepts. */
@@ -154,3 +164,19 @@ export function detectDevCommandInProject(directory, read = readTextFile, listDi
154
164
  }
155
165
  return undefined;
156
166
  }
167
+ /**
168
+ * The command that wires THIS project for good: `init`, in the app's own folder, through the
169
+ * one-off runner the project's package manager ships.
170
+ *
171
+ * Handed to an agent whose install never ran `init` (an MCP-only route), so it has to be right first
172
+ * time: `init` run in a folder that is not the app stops on a missing package.json, and a runner the
173
+ * machine does not have is "command not found". npx whenever there is doubt — it ships with Node.
174
+ */
175
+ export function initCommandIn(directory, read = readTextFile, listDirs = readDirNames) {
176
+ const manager = packageManager(directory, read);
177
+ const berry = read(join(directory, YARN_BERRY_MARKER)) !== undefined;
178
+ const runner = YARN === manager ? (berry ? YARN_DLX : NPX) : (RUNNER[manager] ?? NPX);
179
+ const command = `${runner} ${RETICLE_NPM_PACKAGE} ${INIT_VERB}`;
180
+ const app = detectDevCommandInProject(directory, read, listDirs)?.directory;
181
+ return app === undefined ? command : `cd ${app} && ${command}`;
182
+ }
@@ -1,21 +1,5 @@
1
1
  import { type ReticleEvent } from '@reticlehq/core';
2
2
  import { type AmbientCounts } from '@reticlehq/engine/window/ambient.js';
3
- /**
4
- * The two things a session learns by watching its own event stream, as opposed to storing.
5
- *
6
- * Both are LEVELS derived from a stream, and both have to outlive the ring buffer — which is what
7
- * separates them from the buffer's job and earns them their own unit:
8
- *
9
- * ambient — which regions of the page move on their own (chat, tickers, live counters). Used by
10
- * the settle oracle to ignore background motion, so an action isn't held open forever
11
- * by churn it did not cause.
12
- * blindSpots — how much of the page the SDK cannot observe (cross-origin frames, closed shadow
13
- * roots). The SDK reports these only when the count CHANGES, so a page that mounts
14
- * two frames at load announces them once and is silent forever after. Anything that
15
- * infers coverage from a window of events therefore sees nothing and concludes the
16
- * page was fully observed — a positive claim to have seen what we cannot see. Holding
17
- * the level here makes coverage something to ask rather than infer.
18
- */
19
3
  export declare class ObservedState {
20
4
  #private;
21
5
  /** Fold one already-attributed event into the learned state. */
@@ -57,8 +41,22 @@ export declare class ObservedState {
57
41
  * dropped before they reached the observer. Recording it here keeps the honesty contract intact —
58
42
  * a verdict over a sampled window says `coverage: partial` rather than implying it saw everything.
59
43
  */
60
- noteRateLimited(dropped: number): void;
61
- blindSpots(): Readonly<Record<string, number>>;
44
+ noteRateLimited(dropped: number, at?: number): void;
45
+ /**
46
+ * How many events the bridge sampled away at or after `since` (session-elapsed ms).
47
+ *
48
+ * A bucket is counted when any part of its second reaches the window, so a drop in the same
49
+ * second as the window's start still impeaches it: erring toward unclean is the safe direction.
50
+ */
51
+ rateDroppedSince(since: number): number;
52
+ /**
53
+ * The blind spots, session-wide; or, given `since`, with bridge sampling counted only from then on.
54
+ *
55
+ * Coverage reads the session-wide view: that sampling happened at all is a fact about the session.
56
+ * A verdict deciding whether ITS capture is clean reads the windowed one. Read session-wide there,
57
+ * one early burst made every later verdict on the tab `unclean_capture` (#1414).
58
+ */
59
+ blindSpots(since?: number): Readonly<Record<string, number>>;
62
60
  }
63
61
  /**
64
62
  * The snapshot-shaped labels an act reply names its control by: the testid, and `role "name"`.
@@ -16,12 +16,18 @@ import { ambientKeyOf } from '@reticlehq/engine/window/ambient.js';
16
16
  * page was fully observed — a positive claim to have seen what we cannot see. Holding
17
17
  * the level here makes coverage something to ask rather than infer.
18
18
  */
19
+ /** The resolution rate-limit drops are kept at: per second of session time. */
20
+ const RATE_DROP_BUCKET_MS = 1000;
21
+ /** An hour of seconds; older buckets are past any window a verdict reads. */
22
+ const MAX_RATE_DROP_BUCKETS = 3600;
19
23
  export class ObservedState {
20
24
  /** What THIS session observed. Never contains seeded history — see seedAmbient. */
21
25
  #ownAmbient = {};
22
26
  /** What previous sessions learned, kept separate so it is never re-persisted as if newly seen. */
23
27
  #seededAmbient = {};
24
28
  #blindSpots = {};
29
+ /** Bridge-side sampling, by second of session time. See noteRateLimited. */
30
+ #rateDrops = [];
25
31
  /** Fold one already-attributed event into the learned state. */
26
32
  observe(event) {
27
33
  // Only UNATTRIBUTED events count as ambient: an event caused by an action is the action's work,
@@ -124,11 +130,48 @@ export class ObservedState {
124
130
  * dropped before they reached the observer. Recording it here keeps the honesty contract intact —
125
131
  * a verdict over a sampled window says `coverage: partial` rather than implying it saw everything.
126
132
  */
127
- noteRateLimited(dropped) {
133
+ noteRateLimited(dropped, at) {
134
+ const before = this.#blindSpots[BlindSpotKind.RATE_LIMITED] ?? 0;
128
135
  this.#blindSpots[BlindSpotKind.RATE_LIMITED] = dropped;
136
+ // WHEN, beside how many: the running total above is a fact about the session, and read as one
137
+ // it made every verdict after a single burst `unclean_capture`, however quiet its own window
138
+ // was (#1414). Bucketed per second so a sustained flood stays a bounded list.
139
+ if (at === undefined || dropped <= before)
140
+ return;
141
+ const second = Math.floor(at / RATE_DROP_BUCKET_MS) * RATE_DROP_BUCKET_MS;
142
+ const last = this.#rateDrops[this.#rateDrops.length - 1];
143
+ if (last !== undefined && last.at === second)
144
+ last.count += dropped - before;
145
+ else
146
+ this.#rateDrops.push({ at: second, count: dropped - before });
147
+ if (this.#rateDrops.length > MAX_RATE_DROP_BUCKETS)
148
+ this.#rateDrops.shift();
129
149
  }
130
- blindSpots() {
131
- return this.#blindSpots;
150
+ /**
151
+ * How many events the bridge sampled away at or after `since` (session-elapsed ms).
152
+ *
153
+ * A bucket is counted when any part of its second reaches the window, so a drop in the same
154
+ * second as the window's start still impeaches it: erring toward unclean is the safe direction.
155
+ */
156
+ rateDroppedSince(since) {
157
+ let total = 0;
158
+ for (const bucket of this.#rateDrops) {
159
+ if (bucket.at + RATE_DROP_BUCKET_MS > since)
160
+ total += bucket.count;
161
+ }
162
+ return total;
163
+ }
164
+ /**
165
+ * The blind spots, session-wide; or, given `since`, with bridge sampling counted only from then on.
166
+ *
167
+ * Coverage reads the session-wide view: that sampling happened at all is a fact about the session.
168
+ * A verdict deciding whether ITS capture is clean reads the windowed one. Read session-wide there,
169
+ * one early burst made every later verdict on the tab `unclean_capture` (#1414).
170
+ */
171
+ blindSpots(since) {
172
+ if (since === undefined)
173
+ return this.#blindSpots;
174
+ return { ...this.#blindSpots, [BlindSpotKind.RATE_LIMITED]: this.rateDroppedSince(since) };
132
175
  }
133
176
  }
134
177
  /**
@@ -3,6 +3,10 @@ import { SessionState, type HumanControlData } from '@reticlehq/core';
3
3
  export interface InboxMessage {
4
4
  text: string;
5
5
  t: number;
6
+ /** Set once an agent's tool call took it: what lets the HUD say "Seen" and never before. */
7
+ seen?: boolean;
8
+ /** The agent whose call took it, when the daemon knows. */
9
+ by?: string;
6
10
  }
7
11
  export declare class LiveControl {
8
12
  #private;
@@ -20,8 +24,11 @@ export declare class LiveControl {
20
24
  * while I was away", which a destructive drain can never give twice.
21
25
  */
22
26
  history(): readonly InboxMessage[];
23
- /** Return the queued notes AND clear them — delivered once, so a hint never repeats. */
24
- drain(): InboxMessage[];
27
+ /**
28
+ * Return the queued notes AND clear them — delivered once, so a hint never repeats. Each is marked
29
+ * seen (by `by` when known) on the same object the history holds, so the HUD can show it.
30
+ */
31
+ drain(by?: string): InboxMessage[];
25
32
  /** Diagnostic read of the inbox depth (does not clear). */
26
33
  size(): number;
27
34
  /**
@@ -64,9 +64,18 @@ export class LiveControl {
64
64
  history() {
65
65
  return this.#history;
66
66
  }
67
- /** Return the queued notes AND clear them — delivered once, so a hint never repeats. */
68
- drain() {
69
- return this.#inbox.splice(0, this.#inbox.length);
67
+ /**
68
+ * Return the queued notes AND clear them — delivered once, so a hint never repeats. Each is marked
69
+ * seen (by `by` when known) on the same object the history holds, so the HUD can show it.
70
+ */
71
+ drain(by) {
72
+ const taken = this.#inbox.splice(0, this.#inbox.length);
73
+ for (const message of taken) {
74
+ message.seen = true;
75
+ if (by !== undefined)
76
+ message.by = by;
77
+ }
78
+ return taken;
70
79
  }
71
80
  /** Diagnostic read of the inbox depth (does not clear). */
72
81
  size() {
@@ -1,12 +1,45 @@
1
1
  import { z } from 'zod';
2
2
  import { noteEmptyRead } from '../../surface/tools/gaps/observed-nothing.js';
3
- import { AGENT_ASK_NOTICE, AGENT_WAITING_NOTICE, PresenterTone, SessionState, YIELD_WITHOUT_SESSION_NOTE, } from '@reticlehq/core';
3
+ import { AGENT_ASK_NOTICE, AGENT_WAITING_NOTICE, PresenterTone, SessionState, VerdictStatus, YIELD_WITHOUT_SESSION_NOTE, } from '@reticlehq/core';
4
4
  import { ReticleTool } from '@reticlehq/core';
5
5
  import { sessionIdShape } from '../../surface/tools/tool-kit.js';
6
6
  import { asString } from '@reticlehq/core';
7
+ import { releaseLease } from '../../surface/tools/lease-tools.js';
7
8
  import { gapReportLines } from '../../judgement/runs/artifact/gap-report.js';
8
9
  import { gapSummary } from '../../judgement/runs/artifact/gap-summary.js';
9
- import { DiscoveryInvite } from '@reticlehq/core';
10
+ import { RESULT_FIELD, claimAgainstGrade, endedAgentSession, verdictsSettled, resultField, sessionResult, } from '../../surface/tools/reticle-result.js';
11
+ /** The tab's journal once every verdict in flight has been decided and written. */
12
+ async function settledJournal(session) {
13
+ await verdictsSettled();
14
+ await session.flushJournal?.();
15
+ return session.readJournalActions();
16
+ }
17
+ /**
18
+ * The session an id-less yield hands back.
19
+ *
20
+ * Yield is non-destructive: it only gives the tab back to the human. With several projects connected,
21
+ * an id-less call hit the same "which session?" refusal a destructive action gets, so an agent that
22
+ * had just finished driving one tab had to look its id up in order to let go of it (#1258). When the
23
+ * ordinary resolution refuses, the one connected session this caller has DRIVEN (it holds a
24
+ * remembered act) is the clear candidate. None, or more than one, and the refusal stands: guessing
25
+ * which of two driven tabs to release is still a guess.
26
+ */
27
+ function resolveYieldTarget(sessions, requested) {
28
+ if (requested !== undefined)
29
+ return sessions.resolve(requested);
30
+ try {
31
+ return sessions.resolve();
32
+ }
33
+ catch (refusal) {
34
+ // In scope only: a tab the project scope refuses to hand over is not this caller's to release.
35
+ const driven = sessions.inScope().filter((s) => s.lastAct.cursor() !== undefined);
36
+ const [only] = driven;
37
+ if (1 !== driven.length || only === undefined)
38
+ throw refusal;
39
+ only.markAgentActivity();
40
+ return only;
41
+ }
42
+ }
10
43
  /**
11
44
  * Is this a turn ending with nothing attached, rather than a call about a specific tab?
12
45
  *
@@ -37,6 +70,15 @@ function endingTurnWithNothingAttached(deps, id) {
37
70
  const DISCONNECT_NEEDS_SESSION_ID = '`disconnect: true` needs the `sessionId` of the page to detach — list them with ' +
38
71
  'reticle_session{action:"list"}; it is never picked for you, because detaching the wrong window ' +
39
72
  'cuts you off from the app.';
73
+ /** The agent's claim, when it is one of the words a run verdict uses. */
74
+ function claimOf(value) {
75
+ const claims = [
76
+ VerdictStatus.PASS,
77
+ VerdictStatus.FAIL,
78
+ VerdictStatus.PARTIAL,
79
+ ];
80
+ return claims.includes(value) ? value : undefined;
81
+ }
40
82
  export const LIVE_CONTROL_TOOLS = [
41
83
  {
42
84
  name: ReticleTool.END_SESSION,
@@ -44,9 +86,14 @@ export const LIVE_CONTROL_TOOLS = [
44
86
  '(calm, terminal) and shows the optional `summary` on the panel. If you are just finishing a ' +
45
87
  'turn or waiting on the human, call reticle_session{action:"yield"} instead (revivable). Idempotent. ' +
46
88
  "With `disconnect: true` and a `sessionId` it also closes that page's connection and refuses it " +
47
- 'until the daemon restarts — for a stray window (a hidden desktop webview, a 404 page) that keeps coming back.',
89
+ 'until the daemon restarts — for a stray window (a hidden desktop webview, a 404 page) that keeps coming back. ' +
90
+ 'Ending a tab you leased also releases that lease (`leaseReleased: true`).',
48
91
  inputSchema: {
49
92
  summary: z.string().optional(),
93
+ claim: z
94
+ .enum([VerdictStatus.PASS, VerdictStatus.FAIL, VerdictStatus.PARTIAL])
95
+ .optional()
96
+ .describe('What YOU claim this session showed. Compared with the graded checks, never used as them.'),
50
97
  disconnect: z
51
98
  .boolean()
52
99
  .optional()
@@ -59,6 +106,10 @@ export const LIVE_CONTROL_TOOLS = [
59
106
  ended: z.boolean(),
60
107
  sessionId: z.string().optional(),
61
108
  disconnected: z.boolean().optional(),
109
+ leaseReleased: z
110
+ .boolean()
111
+ .optional()
112
+ .describe('True when the ended tab was your lease: its context is closed and its slot freed.'),
62
113
  note: z.string().optional(),
63
114
  talk_to_us: z
64
115
  .string()
@@ -68,10 +119,13 @@ export const LIVE_CONTROL_TOOLS = [
68
119
  .array(z.string())
69
120
  .optional()
70
121
  .describe('What this session claimed and what held — an `unknown` is never counted as held.'),
122
+ [RESULT_FIELD]: z.string().optional(),
123
+ claim: z.object({ claimed: z.string(), graded: z.string(), agrees: z.boolean() }).optional(),
71
124
  },
72
125
  handler: (deps, args) => {
73
126
  const requested = asString(args['sessionId']);
74
127
  const detach = true === args['disconnect'];
128
+ const claim = claimOf(args['claim']);
75
129
  // Named, never auto-picked: detaching the wrong window cuts the agent off from the app.
76
130
  if (detach && requested === undefined)
77
131
  throw new Error(DISCONNECT_NEEDS_SESSION_ID);
@@ -107,7 +161,13 @@ export const LIVE_CONTROL_TOOLS = [
107
161
  // rather than becoming a rejected promise the caller did not expect.
108
162
  const session = deps.sessions.resolve(requested);
109
163
  const summary = asString(args['summary']);
110
- return session.readJournalActions().then((actions) => {
164
+ // A verdict still being decided (an assert waiting out its budget) is one of this session's
165
+ // checks: decided and journaled before the session's result is folded, never after it.
166
+ return settledJournal(session).then(async (all) => {
167
+ // This agent session only: its own calls since its last end, never the Harness drives the
168
+ // tab also holds, and under its own run id so a later end does not overwrite this run.
169
+ const ended = endedAgentSession(session.id, all, session.elapsed?.(), claim);
170
+ const actions = ended.actions;
111
171
  // The moment the agent calls the task complete is when "and what did not hold" is worth a
112
172
  // line: the same fold `reticle_context` and `reticle report` serve, so they cannot disagree.
113
173
  const gap = gapReportLines(gapSummary(actions));
@@ -116,13 +176,24 @@ export const LIVE_CONTROL_TOOLS = [
116
176
  session.setState(SessionState.ENDED, 0 === panel.length ? undefined : panel.join('\n'));
117
177
  if (detach)
118
178
  deps.sessions.park(session);
119
- return {
179
+ const answer = {
120
180
  ended: true,
121
181
  sessionId: session.id,
122
182
  ...(detach ? { disconnected: true } : {}),
123
183
  gap,
124
- talk_to_us: DiscoveryInvite.AGENT,
184
+ // No founder's-call invite here: it is offered to someone stuck (an error, an empty
185
+ // session list), never at the end of every task.
186
+ ...(claim === undefined ? {} : { claim: claimAgainstGrade(claim, actions) }),
187
+ ...resultField(() => sessionResult(deps, session.id, actions, ended.wallMs, ended.runId)),
125
188
  };
189
+ // An ended lease left connected kept the tab registered until the reaper took it, so the
190
+ // next agent's every id-less call was refused as ambiguous. Released after the answer is
191
+ // folded, because releasing closes the tab. Only this caller's own lease, never another's.
192
+ const pool = deps.pool;
193
+ if (pool === undefined || !pool.heldBy(session.id, deps.attachId))
194
+ return answer;
195
+ await releaseLease(deps, pool, session.id);
196
+ return { ...answer, leaseReleased: true };
126
197
  });
127
198
  },
128
199
  },
@@ -160,7 +231,7 @@ export const LIVE_CONTROL_TOOLS = [
160
231
  note: YIELD_WITHOUT_SESSION_NOTE,
161
232
  });
162
233
  }
163
- const session = deps.sessions.resolve(requested);
234
+ const session = resolveYieldTarget(deps.sessions, requested);
164
235
  const note = asString(args['note']);
165
236
  const tone = ask ? PresenterTone.ASK : PresenterTone.WAITING;
166
237
  const text = ask && note !== undefined && note.trim().length > 0
@@ -227,12 +298,10 @@ export const LIVE_CONTROL_TOOLS = [
227
298
  // said nothing; the second means an agent is waiting on a channel that does not exist.
228
299
  return Promise.resolve(noteEmptyRead({ messages }, 'messages', {
229
300
  noun: 'messages from the human since the last poll',
230
- // The HUD no longer carries a text input — two boxes on one screen, and nothing said which
231
- // was which. Nothing in the shipped product produces one of these today, so an empty queue
232
- // here is structural rather than a quiet human, and a caller polling it deserves to know
233
- // that rather than infer silence.
234
- caveat: 'the HUD has no message box, so nothing currently sends on this channel — an empty ' +
235
- 'queue here is not evidence about what the human thinks',
301
+ // The HUD's note box is the one producer, and every tool result already carries what it
302
+ // sends, so polling this is rarely needed and silence here is only silence so far.
303
+ caveat: 'notes from the HUD also arrive inline on any Reticle tool result (`control.guidance`), ' +
304
+ 'so an empty queue means nothing new since the last call, not that the human agrees',
236
305
  }));
237
306
  },
238
307
  },
@@ -0,0 +1,5 @@
1
+ export interface NarrationBy {
2
+ harness: true;
3
+ summary?: boolean;
4
+ }
5
+ export declare function narrationArgs(text: string, by?: NarrationBy): Record<string, unknown>;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A narration line for the HUD, and who it is from.
3
+ *
4
+ * A Harness line names the Harness, so the HUD files it in the Harness log rather than the Agent
5
+ * Log: two drivers in one log read as one muddle and credited the agent with the Harness's steps. A
6
+ * `summary` line (a run starting or ending) is shown in the Agent Log too, because the agent that
7
+ * asked for the run reports its result.
8
+ */
9
+ import { CommandActor } from '@reticlehq/core';
10
+ export function narrationArgs(text, by) {
11
+ return {
12
+ text,
13
+ level: 'info',
14
+ ...(by === undefined ? {} : { actor: CommandActor.HARNESS }),
15
+ ...(true === by?.summary ? { summary: true } : {}),
16
+ };
17
+ }
@@ -186,7 +186,7 @@ export interface NoSessionFacts {
186
186
  * recovery: a message that already carries its own next action must not be handed a second, more
187
187
  * generic one that contradicts it.
188
188
  */
189
- export declare const SELF_RECOVERING_MARKER = "Then call reticle_sessions again \u2014 it will appear within a second of the page loading.";
189
+ export declare const SELF_RECOVERING_MARKER = "Then call reticle_session { action: \"list\" } again \u2014 it will appear within a second of the page loading.";
190
190
  /**
191
191
  * The diagnosis, and the CODE for the branch that produced it.
192
192
  *
@@ -17,6 +17,7 @@ import { leaseCaveat } from './presence/lease-availability.js';
17
17
  import { DEV_SERVER_PORTS } from '../../command/cli/ports/resolve/cli-port.js';
18
18
  import { siblingListenerNote } from '../../command/cli/ports/sibling-ports.js';
19
19
  import { STALL_AFTER_MS } from './stall-clock.js';
20
+ import { departedPortGone } from './no-session-next-action.js';
20
21
  import { pageTornDownWhileOn } from '@reticlehq/engine/evidence/page-teardown.js';
21
22
  /** How every hello-refusal reason the bridge records separates its cause from its fix. */
22
23
  const CAUSE_FIX_SEPARATOR = ' — ';
@@ -29,7 +30,7 @@ const NUXT = 'nuxt';
29
30
  * recovery: a message that already carries its own next action must not be handed a second, more
30
31
  * generic one that contradicts it.
31
32
  */
32
- export const SELF_RECOVERING_MARKER = 'Then call reticle_sessions again — it will appear within a second of the page loading.';
33
+ export const SELF_RECOVERING_MARKER = 'Then call reticle_session { action: "list" } again — it will appear within a second of the page loading.';
33
34
  const RETRY = SELF_RECOVERING_MARKER;
34
35
  /**
35
36
  * The no-shell path, for the branches where a BLIND lease would be wrong.
@@ -62,12 +63,21 @@ function leaseAdvice(base, facts) {
62
63
  /**
63
64
  * The way out that needs no human at all.
64
65
  *
65
- * Only offered when the app is known to carry the SDK: leasing an uninstrumented app just burns a
66
- * browser and comes back `ready:false`.
66
+ * Offered here when the app is known to carry the SDK. An app that carries none is offered
67
+ * {@link ZERO_INSTALL} instead, which says what a lease on it can and cannot see.
67
68
  */
68
69
  const SELF_SERVE = 'You do not have to wait for the human: reticle_lease {action:"acquire", url} opens a browser ' +
69
70
  'Reticle drives itself, and returns a sessionId you can use immediately (reach it with ' +
70
71
  'reticle_run {tool:"reticle_lease"} if it is not advertised directly; release it when you finish).';
72
+ /**
73
+ * The way past an app nobody wired, without waiting for the wiring.
74
+ *
75
+ * A lease on a page that never dials in hands it the zero-install reader, so an MCP-only install
76
+ * (a plugin, a hand-written `npx … mcp` config — `init` never ran) still gets a verdict on the first
77
+ * call instead of a diagnosis it stops at. The URL and the command live in the next action.
78
+ */
79
+ const ZERO_INSTALL = 'You can get a verdict NOW with nothing installed: reticle_lease on the app URL supplies the ' +
80
+ 'SDK itself (no component state or source file:line until it is wired) — the next action names it.';
71
81
  /** The hedge that is true for every vanished tab we did not watch leave. */
72
82
  const TAB_GONE_WHAT = 'The tab was closed, navigated away, or hard-reloaded.';
73
83
  /**
@@ -324,11 +334,12 @@ function alreadyListeningClause(listening) {
324
334
  return '';
325
335
  if (1 === listening.length) {
326
336
  const port = listening[0];
327
- return (` An app is already listening on ${String(port)}; just open http://localhost:${String(port)} ` +
328
- '— do not start a second stack.');
337
+ return (` Something is serving a page on :${String(port)}; it may not be this app — just open ` +
338
+ `http://localhost:${String(port)} rather than starting a second stack.`);
329
339
  }
330
- return (` An app is already listening on ${listening.join(', ')}; just open one of those URLs — do not ` +
331
- 'start a second stack.');
340
+ const ports = listening.map((p) => `:${String(p)}`).join(', ');
341
+ return (` Something is serving a page on ${ports}; those listeners may not be this ` +
342
+ 'app — open the URL that belongs to this project rather than starting a second stack.');
332
343
  }
333
344
  /**
334
345
  * The diagnosis, and the CODE for the branch that produced it.
@@ -419,6 +430,16 @@ export function explainNoSession(facts) {
419
430
  `problem. Ask the human to go back to the app${orOpenCommand(facts)}, or reload the tab. ` +
420
431
  `${leaseAdvice(SELF_SERVE, facts)} ${RETRY}`, alreadyListeningClause(listening).trim());
421
432
  }
433
+ // The dev server that served this session has stopped: the departed session's own port no
434
+ // longer answers, so "ask the human to reopen the app" points at a dead socket. Keyed on that
435
+ // port, as the next action is (#1421) — the prose and the executable half agree on the story.
436
+ // No "already listening" clause: whatever else answers is not where this app was.
437
+ if (facts.lastKnownUrl !== undefined && departedPortGone(facts)) {
438
+ return reason(NoSessionReason.TAB_GONE, 'no browser session connected, but one WAS connected to this daemon earlier, so the wiring ' +
439
+ `is correct. ${tabGoneWhat(facts.lastKnownUrl)} The dev server that served it has stopped ` +
440
+ '— nothing answers on that port any more — so start the app again (the command is in ' +
441
+ `\`next_action\`). ${RETRY}`);
442
+ }
422
443
  return reason(NoSessionReason.TAB_GONE, 'no browser session connected, but one WAS connected to this daemon earlier, so the wiring ' +
423
444
  `is correct. ${tabGoneWhat(facts.lastKnownUrl)} Ask the human to reopen ` +
424
445
  `the app${orOpenCommand(facts)}, or reload the tab. ${leaseAdvice(SELF_SERVE, facts)} ${RETRY}`, alreadyListeningClause(listening).trim());
@@ -464,7 +485,8 @@ export function explainNoSession(facts) {
464
485
  'dev server may not be running: START IT YOURSELF, in the background, using the command ' +
465
486
  'in `next_action`, and tell the human in one line that it is running. ' +
466
487
  `(2) There is no \`.reticle.json\` in ${where}, which is the file ${INIT_CMD} writes, so ` +
467
- `the app may carry no Reticle SDK. Check the app's OWN directory before re-running it. ${RETRY}`, `The scan covers ${SCANNED_PORTS} and nothing else, so a server on any other port is ` +
488
+ `the app may carry no Reticle SDK. Check the app's OWN directory before re-running it. ` +
489
+ `${ZERO_INSTALL} ${RETRY}`, `The scan covers ${SCANNED_PORTS} and nothing else, so a server on any other port is ` +
468
490
  'invisible to it: if the app IS running, ask for its URL rather than assuming it is down, ' +
469
491
  `and open it with ${OPEN_CMD}. The missing config is not proof either — in a monorepo the ` +
470
492
  'daemon often runs at the root while the app lives in a subdirectory, and an app wired by ' +
@@ -495,7 +517,7 @@ export function explainNoSession(facts) {
495
517
  `${INIT_CMD} writes, so the app may carry no Reticle SDK. Check the app's OWN directory: ` +
496
518
  `if it has no config, run ${INIT_CMD} ` +
497
519
  'there and restart the dev server; if it has one, the app is wired and simply has no page ' +
498
- `open — ${OPEN_CMD}. ${RETRY}`, 'That absence is not proof: the same one is expected in a monorepo whose daemon runs at the ' +
520
+ `open — ${OPEN_CMD}. ${ZERO_INSTALL} ${RETRY}`, 'That absence is not proof: the same one is expected in a monorepo whose daemon runs at the ' +
499
521
  'root while the app lives in a subdirectory, or in an app wired by the Vite or Babel ' +
500
522
  `plugin. ${unattributedListeners(listening)}${searchedClause(facts)}${siblingListenerClause(facts)}`);
501
523
  }
@@ -87,13 +87,33 @@ interface NextActionFacts {
87
87
  * its one hit is as likely to be another repo's dev server as this one's.
88
88
  */
89
89
  lastKnownUrl?: string;
90
+ /** Ports that accepted a connection and answered nothing in time: up, not gone. */
91
+ slowListeners?: readonly number[];
90
92
  /**
91
93
  * Where the departed tab was seen heading, when the SDK reported it fresh (#1256). The
92
94
  * next-action reason must agree with the diagnosis: when this is present the tab was not
93
95
  * closed, it navigated away.
94
96
  */
95
97
  departedTo?: string;
98
+ /**
99
+ * The command that wires THIS project for good — `init` in the app's own folder through the
100
+ * project's own runner (see `initCommandIn`). Absent means the generic npx spelling.
101
+ */
102
+ init?: string;
96
103
  }
104
+ /** The port a tombstone URL names, when it names one — anything unparseable names no port. */
105
+ export declare function portOfUrl(url: string): number | undefined;
106
+ /**
107
+ * The departed session's own port no longer answers. Direct evidence, because the scan always
108
+ * covers that port — unlike an empty scan, which proves nothing the moment another project
109
+ * happens to be listening (#1421). A slow listener is up, not gone, and a url with no explicit
110
+ * port was never scanned, so neither counts.
111
+ */
112
+ export declare function departedPortGone(facts: {
113
+ lastKnownUrl?: string;
114
+ listening: readonly number[];
115
+ slowListeners?: readonly number[];
116
+ }): boolean;
97
117
  export declare function nextActionFor(facts: NextActionFacts): NoSessionNextAction;
98
118
  /** The same action as one sentence, for the prose message the human reads. */
99
119
  export declare function renderNextAction(next: NoSessionNextAction): string;