@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
@@ -0,0 +1,409 @@
1
+ /**
2
+ * The daemon's side of the platform chat: the apps it reports, and the drives it takes.
3
+ *
4
+ * Out of `index.ts`, which only calls this and hands it the cloud credentials (the tool surface does
5
+ * not reach `memory/cloud`; see `withLinkedCredential`): both halves share the same view of which tab is which
6
+ * app, and keeping them together is what stops a drive attached to one app landing in another that
7
+ * happens to be on the same port. See `local-apps.ts` and `remote-drive.ts` for each half.
8
+ */
9
+ import { isUnmatchedRoot } from '../../memory/project/dir/reticle-dir.js';
10
+ import { readProjectId } from '../../command/cli/ports/resolve/cli-port.js';
11
+ import { basename, dirname, join } from 'node:path';
12
+ import { homedir, hostname } from 'node:os';
13
+ import { LinkCapability, ReticleDir, ReticleTool, asRecord, } from '@reticlehq/core';
14
+ import { prepareDrive } from '../../features/harness/platform/drive-target.js';
15
+ import { reticleToolset } from './harness-toolset.js';
16
+ import { projectDirFor, sessionRoot } from '../../memory/project/session-root.js';
17
+ import { readDashboardUrl } from '../../memory/project/sync-status.js';
18
+ import { driveFrame } from '../../features/visual/visual-tools.js';
19
+ import { LEASE_ACQUIRE_TOOL } from './lease-tools.js';
20
+ import { REMOTE_DRIVE_JPEG_QUALITY, endDrivenTab, pickOwnDriveSession, startRemoteDrives, } from '../../features/harness/platform/remote-drive.js';
21
+ import { appKeyOf, appsByPlatform, homeRelative, machineOf, mayOpen, NOT_AN_APP_ADDRESS, nameFromProjectId, pickAppTab, startAppReports, withoutMarks, } from '../../features/harness/platform/local-apps.js';
22
+ import { serverOptionsFromEnv } from '../../features/harness/platform/server-driver.js';
23
+ import { EXPLORE_TOOLS, driveForChat } from './explore-tools.js';
24
+ import { MSG_NO_HARNESS_KEY, harnessLockRefusal, withLinkedCredential } from './harness-explore.js';
25
+ import { runTool } from './invoke-tool.js';
26
+ import { announcedChannels, probeMarkers, notApplicableOf, recordedGaps, } from '../../portal/session/recorded-gaps.js';
27
+ import { probeDevServers } from '../../portal/session/dev-server/dev-server-probe.js';
28
+ import { DriveOrigin, onDriveChange, onDriveStep, runningDrive, stopDrive, } from '../../features/harness/drive-runs.js';
29
+ import { FreeDriveKind, planUrl, requestFreeDrive, } from '../../features/harness/platform/platform-drives.js';
30
+ import { HumanControlKind } from '@reticlehq/core';
31
+ import { onAgentsChange } from '../../hooks/coding-agents.js';
32
+ /** Why a platform drive with no tab of its own runs no tool. */
33
+ const NO_DRIVEN_TAB = 'No tab was picked for this drive, so no tool runs.';
34
+ /** What this daemon does for the platform's chat. Each one is listed only once it is built. */
35
+ export const CHAT_CAPABILITIES = [
36
+ LinkCapability.DRIVE_SPEC,
37
+ LinkCapability.TARGET_TAB,
38
+ LinkCapability.TARGET_HEADLESS,
39
+ LinkCapability.TARGET_HEADED,
40
+ LinkCapability.HUD,
41
+ LinkCapability.TOOL_SESSION,
42
+ LinkCapability.FRAMES,
43
+ ];
44
+ /** A project's own name: its package's, else its id's, else its folder's. */
45
+ const nameOf = async (fs, dir, projectId) => {
46
+ try {
47
+ const name = JSON.parse(await fs.readFile(join(dir, 'package.json')))
48
+ .name;
49
+ if ('string' === typeof name && 0 < name.length)
50
+ return name;
51
+ }
52
+ catch {
53
+ // No package, or not JSON: the folder names it.
54
+ }
55
+ // Not mapped to a checkout (the daemon's shared `unmatched` directory): the id the SDK stamped.
56
+ if (undefined !== projectId)
57
+ return nameFromProjectId(projectId);
58
+ return basename(dir) || dir;
59
+ };
60
+ /** How often the localhost dev-server scan may run: never more than this, however often we report. */
61
+ const DEV_SERVER_SCAN_EVERY_MS = 30_000;
62
+ /**
63
+ * Dev servers listening on localhost with no connected Reticle page — an app that is up and not
64
+ * instrumented, or not dialling. The same probe `doctor` and the no-session diagnosis use, cached.
65
+ */
66
+ function devServerScan(connectedUrls, now) {
67
+ let last;
68
+ return async () => {
69
+ if (last === undefined || now() - last.at >= DEV_SERVER_SCAN_EVERY_MS)
70
+ last = { at: now(), ports: await probeDevServers() };
71
+ const connected = new Set(connectedUrls().map((url) => {
72
+ try {
73
+ return Number(new URL(url).port);
74
+ }
75
+ catch {
76
+ return 0;
77
+ }
78
+ }));
79
+ return last.ports
80
+ .filter((port) => !connected.has(port))
81
+ .map((port) => ({ url: `http://${LOCALHOST_HOST}:${String(port)}`, port }));
82
+ };
83
+ }
84
+ const LOCALHOST_HOST = 'localhost';
85
+ export function startChatDrives(deps, sessions, fs, cloud, log) {
86
+ const env = process.env;
87
+ const machine = machineOf(hostname(), homedir());
88
+ const sessionCloud = cloud.sessionCloud;
89
+ const sessionKey = async (id) => (await sessionCloud(id))?.apiKey;
90
+ // ponytail: a tab whose project resolves to nothing counts as the daemon's own project here, as it
91
+ // does for flows and runs; a per-tab "unresolved" app is the upgrade if that ever misleads.
92
+ const appOf = (id) => {
93
+ try {
94
+ const projectId = sessions.list().find((tab) => tab.sessionId === id)?.projectId;
95
+ return appKeyOf(machine.id, projectDirFor(deps, id), projectId);
96
+ }
97
+ catch {
98
+ return undefined;
99
+ }
100
+ };
101
+ // Opened headless, like `reticle drive <url>`, through runTool so it is counted like any call.
102
+ const openable = (url) => {
103
+ if (!mayOpen(url, sessions.list().map((tab) => tab.url)))
104
+ throw new Error(NOT_AN_APP_ADDRESS);
105
+ };
106
+ /**
107
+ * The `.reticle` each reported app writes into, learned from its tabs. A tab the chat opens for an
108
+ * app is leased into that root: resolved from the page alone, an app with no project id would land
109
+ * in `unmatched/`, which nothing syncs.
110
+ */
111
+ const rootByApp = new Map();
112
+ /**
113
+ * The root AND the project a tab the daemon opens for an app is stamped with. Stamped with the
114
+ * root alone, a page that reports no project of its own opened as nobody's: its run fell to
115
+ * `unmatched/` and the drive answered a linked project "run reticle connect".
116
+ */
117
+ const claimFor = (appKey) => (appKey === undefined ? undefined : rootByApp.get(appKey)) ?? {};
118
+ /** Where each credential's project was last open on this machine, from the reports. */
119
+ const lastUrlByKey = new Map();
120
+ /** Lease the app a credential's project was last open at, for a drive no tab of it can take. */
121
+ const reopenFor = async (key) => {
122
+ const last = lastUrlByKey.get(key);
123
+ if (last === undefined)
124
+ return undefined;
125
+ openable(last.url);
126
+ const id = asRecord(await runTool(LEASE_ACQUIRE_TOOL, deps, { ...last }))['sessionId'];
127
+ return 'string' === typeof id ? id : undefined;
128
+ };
129
+ const open = async (url, appKey) => {
130
+ openable(url);
131
+ await runTool(LEASE_ACQUIRE_TOOL, deps, { url, ...claimFor(appKey) });
132
+ };
133
+ const pick = (goal, key, app) => undefined === app
134
+ ? pickOwnDriveSession(sessions.list(), goal, key, sessionKey, () => reopenFor(key))
135
+ : pickAppTab(app, goal, () => sessions.list(), appOf, (url) => open(url, app.key)).then(async (id) =>
136
+ // The app the platform named must be one this credential's project owns.
137
+ 'string' === typeof id && (await sessionKey(id)) !== key ? null : id);
138
+ const drives = startRemoteDrives({
139
+ env: () => withLinkedCredential(deps, env),
140
+ connected: () => 0 < sessions.count(),
141
+ pick,
142
+ // The spec's target and HUD, applied through the same counted tools an agent would call.
143
+ prepare: ({ goal, apiKey, app, spec }) => prepareDrive(spec, app?.url ?? undefined, {
144
+ pickTab: () => pick(goal, apiKey, app),
145
+ open: async (url, headed, hud) => {
146
+ openable(url);
147
+ const lease = asRecord(await runTool(LEASE_ACQUIRE_TOOL, deps, {
148
+ url,
149
+ ...(headed ? { headed } : {}),
150
+ ...(hud === undefined ? {} : { hud }),
151
+ ...claimFor(app?.key),
152
+ }));
153
+ const id = lease['sessionId'];
154
+ if ('string' !== typeof id)
155
+ throw new Error(`could not open ${url}`);
156
+ return id;
157
+ },
158
+ tuneHud: async (sessionId, hud) => {
159
+ await reticleToolset(deps, { sessionId }).invoke(ReticleTool.SESSION_TUNE, { hud });
160
+ },
161
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
162
+ }),
163
+ // A platform drive: Reticle's own tools on the driven tab, and nothing else. Locked, so a call
164
+ // naming another tab still lands on this one; with no tab picked, nothing runs at all.
165
+ session: (sessionId) => {
166
+ if (sessionId === undefined)
167
+ return { invoke: () => Promise.reject(new Error(NO_DRIVEN_TAB)) };
168
+ const tools = reticleToolset(deps, { sessionId, locked: true });
169
+ return { tools: tools.tools, invoke: (tool, args) => tools.invoke(tool, args) };
170
+ },
171
+ drive: async (goal, sessionId, spec) => {
172
+ const url = sessions.list().find((tab) => tab.sessionId === sessionId)?.url;
173
+ const outcome = await driveForChat(deps, goal, sessionId, spec?.plan, spec?.confirmDangerous);
174
+ return url === undefined ? outcome : { ...outcome, url };
175
+ },
176
+ // The leased tab, or a desktop window's own capture. A web tab only the SDK reaches has no camera.
177
+ frame: (sessionId) => sessionId === undefined
178
+ ? Promise.resolve(undefined)
179
+ : driveFrame(deps, sessionId, REMOTE_DRIVE_JPEG_QUALITY),
180
+ settle: (id, outcome) => endDrivenTab(id === undefined ? undefined : sessions.get(id), outcome),
181
+ log,
182
+ });
183
+ const scanDevServers = devServerScan(() => sessions.list().map((tab) => tab.url), () => Date.now());
184
+ const reports = startAppReports({
185
+ machine,
186
+ version: cloud.version,
187
+ capabilities: CHAT_CAPABILITIES,
188
+ apps: async () => {
189
+ // The setup score the dashboard shows is what the app's pages carry, asked of each page
190
+ // until its app has shown both markers: never only what an act happened to reach.
191
+ await probeMarkers(sessions.list().flatMap((tab) => {
192
+ const live = sessions.get(tab.sessionId);
193
+ const command = live?.command?.bind(live);
194
+ return command === undefined
195
+ ? []
196
+ : [{ id: tab.sessionId, url: tab.url, projectId: tab.projectId, command }];
197
+ }));
198
+ return appsByPlatform(sessions.list().map((tab) => {
199
+ const live = sessions.get(tab.sessionId);
200
+ const sdkVersion = live?.sdkVersion;
201
+ // What the page announced plus the gaps its verdicts paid for: what the dashboard's
202
+ // coverage line and coding-agent prompt are built from.
203
+ const channels = announcedChannels({
204
+ id: tab.sessionId,
205
+ url: tab.url,
206
+ projectId: tab.projectId,
207
+ channels: live?.channels,
208
+ sourceMapping: live?.sourceMapping,
209
+ });
210
+ const gaps = recordedGaps(tab.sessionId).map(({ kind, missing, fix, seenAt }) => ({
211
+ kind,
212
+ missing,
213
+ fix,
214
+ seenAt,
215
+ }));
216
+ return {
217
+ ...tab,
218
+ ...(sdkVersion === undefined ? {} : { sdkVersion }),
219
+ ...(0 === channels.length ? {} : { channels }),
220
+ gaps,
221
+ notApplicable: notApplicableOf({
222
+ id: tab.sessionId,
223
+ url: tab.url,
224
+ projectId: tab.projectId,
225
+ }),
226
+ };
227
+ }), serverOptionsFromEnv(await withLinkedCredential(deps, env)), machine.id, async (tab) => {
228
+ const root = sessionRoot(deps, tab.sessionId);
229
+ const dir = dirname(root);
230
+ const projectId = tab.projectId ?? readProjectId(dir);
231
+ const stamp = { root, ...(projectId === undefined ? {} : { projectId }) };
232
+ rootByApp.set(appKeyOf(machine.id, dir, tab.projectId), stamp);
233
+ const platform = await sessionCloud(tab.sessionId);
234
+ if (undefined !== platform)
235
+ lastUrlByKey.set(platform.apiKey, { url: withoutMarks(tab.url), ...stamp });
236
+ return {
237
+ dir,
238
+ name: await nameOf(fs, dir, tab.projectId),
239
+ ...(undefined === platform
240
+ ? {}
241
+ : { platform: { url: platform.url.replace(/\/+$/, ''), apiKey: platform.apiKey } }),
242
+ };
243
+ });
244
+ },
245
+ open,
246
+ extras: async () => {
247
+ const closure = sessions.lastClosure?.();
248
+ const unsynced = cloud.unsynced?.();
249
+ return {
250
+ devServers: await scanDevServers(),
251
+ ...(closure === undefined
252
+ ? {}
253
+ : { helloFailure: { reason: closure.reason, at: closure.at } }),
254
+ ...unsyncedReport(unsynced, homedir()),
255
+ };
256
+ },
257
+ drivePending: (platform) => void drives.tick(platform),
258
+ // What the platform wants the person told: in the daemon's log, and on the HUD of each open tab
259
+ // of that project, so somebody who never reads the log still sees "update Reticle".
260
+ notify: (notice, platform) => {
261
+ const line = `${notice.text}${notice.url === undefined ? '' : ` ${notice.url}`}`;
262
+ log(`reticle: from the platform: ${line}`);
263
+ void (async () => {
264
+ for (const tab of sessions.list()) {
265
+ const key = await sessionKey(tab.sessionId).catch(() => undefined);
266
+ if (key === platform.apiKey)
267
+ sessions.get(tab.sessionId)?.pushNarration(line);
268
+ }
269
+ })();
270
+ },
271
+ log,
272
+ });
273
+ // Once now, so the chat sees this machine's apps as soon as the daemon is up.
274
+ void reports.tick();
275
+ return {
276
+ stop: () => {
277
+ drives.stop();
278
+ reports.stop();
279
+ },
280
+ };
281
+ }
282
+ /** The dashboard the tab's project is linked to, when its link names one. */
283
+ function dashboardOf(deps, sessionId) {
284
+ try {
285
+ return readDashboardUrl(sessionRoot(deps, sessionId));
286
+ }
287
+ catch {
288
+ return undefined;
289
+ }
290
+ }
291
+ /** Said on the HUD when Link this project ends. */
292
+ const MSG_LINKED = 'Linked. This project now reports to your dashboard.';
293
+ const MSG_LINK_FAILED = 'Could not link this project. Run `reticle connect` in its folder.';
294
+ /** A page with no projectId: linking it would bind a hash-named project nothing here reads. */
295
+ const MSG_LINK_NEEDS_PROJECT = 'This page did not say which project it is, so there is nothing to link yet. Run `npx @reticlehq/server init` in your app (or pass `projectId` to `connect()`), then Link.';
296
+ const MSG_LINK_UNAVAILABLE = 'This Reticle cannot link from the panel. Run `reticle connect` in the project folder.';
297
+ /** Said on the HUD when Stop finds nothing to stop. */
298
+ const MSG_NOTHING_DRIVING = 'No Harness drive is running in this tab.';
299
+ const msgStartTrial = (url) => `Start your trial: ${url}`;
300
+ /**
301
+ * The panel's Harness controls. The switch is the platform's autonomous mode, unchanged. Run Harness
302
+ * and Stop drive. A run asks the platform for the drive's grant, then starts it
303
+ * through the same explore an agent calls (counted, recorded, polled the same way); its lines and
304
+ * steps reach the HUD log as the drive narrates them. A refused grant says why, and where to start
305
+ * a trial when it wants a card.
306
+ */
307
+ export async function hudDrive(deps, sessionId,
308
+ /** The panel's control, as the bridge narrowed it (`harness-request.ts`). */
309
+ request,
310
+ /** The autonomous switch: written through to the platform, which the daemon owns. */
311
+ applySwitch, grant = (platform) => requestFreeDrive(platform, FreeDriveKind.EXPLORE)) {
312
+ if (HumanControlKind.HARNESS === request.kind)
313
+ return applySwitch(request.enabled);
314
+ // What the panel's Run and Stop answer belongs in the Harness log, and in the Agent Log as a summary.
315
+ const say = (text) => deps.sessions.get?.(sessionId)?.pushNarration(text, true, { harness: true, summary: true });
316
+ if (HumanControlKind.HARNESS_STOP === request.kind) {
317
+ const running = runningDrive(sessionId);
318
+ if (running === undefined || !stopDrive(running.harnessRun))
319
+ say(MSG_NOTHING_DRIVING);
320
+ return;
321
+ }
322
+ // Before the grant: a drive the gate refuses must not take one. The panel shows the prompt.
323
+ const env = await withLinkedCredential(deps, process.env, { sessionId });
324
+ const locked = await harnessLockRefusal(deps, sessionId, env);
325
+ if (locked !== undefined)
326
+ return say(locked.split('\n')[0] ?? locked);
327
+ const platform = serverOptionsFromEnv(env);
328
+ if (platform === undefined)
329
+ return say(MSG_NO_HARNESS_KEY);
330
+ const granted = await grant(platform);
331
+ if (!granted.granted) {
332
+ say(granted.message);
333
+ // At the console's origin (the tab's link names it), never the API's, which 404s when split.
334
+ if (granted.needsCard)
335
+ say(msgStartTrial(planUrl(dashboardOf(deps, sessionId) ?? platform.url)));
336
+ return;
337
+ }
338
+ const explore = EXPLORE_TOOLS.find((tool) => ReticleTool.VERIFY_EXPLORE === tool.name);
339
+ if (explore === undefined)
340
+ return;
341
+ try {
342
+ await runTool(explore, deps, {
343
+ sessionId,
344
+ driveId: granted.driveId,
345
+ origin: DriveOrigin.HUD,
346
+ wait: 0,
347
+ ...(request.persona === undefined ? {} : { persona: request.persona }),
348
+ });
349
+ }
350
+ catch (error) {
351
+ say(error instanceof Error ? error.message : String(error));
352
+ }
353
+ }
354
+ /**
355
+ * The link a panel sign-in makes once it lands: the tab's project, never a page that did not say
356
+ * which project it is (that would bind a hash-named project nothing here reads).
357
+ */
358
+ export function projectLinkOnly(link) {
359
+ return link === undefined
360
+ ? undefined
361
+ : (root) => (isUnmatchedRoot(root) ? Promise.resolve(0) : link(root));
362
+ }
363
+ /**
364
+ * The panel's Harness controls on a bridge: the switch writes through to the platform, so console
365
+ * and panel cannot disagree; Run and Stop drive, in the project of the tab that asked.
366
+ */
367
+ export function attachHudHarness(bridge, daemon, applySwitch,
368
+ /** Link this project: what `reticle connect` does from that folder. Absent: the button says so. */
369
+ link) {
370
+ bridge.attachHarnessRequest((request, s) => {
371
+ const root = s.artifactRoot ?? daemon.root;
372
+ if (HumanControlKind.HARNESS_LINK === request.kind) {
373
+ const say = (text) => daemon.deps().sessions.get?.(s.id)?.pushNarration(text);
374
+ if (link === undefined)
375
+ return say(MSG_LINK_UNAVAILABLE);
376
+ if (isUnmatchedRoot(root))
377
+ return say(MSG_LINK_NEEDS_PROJECT);
378
+ void link(root)
379
+ .then((code) => say(0 === code ? MSG_LINKED : MSG_LINK_FAILED))
380
+ .catch(() => say(MSG_LINK_FAILED))
381
+ .finally(daemon.repaint);
382
+ return;
383
+ }
384
+ void hudDrive(daemon.deps(), s.id, request, (on) => applySwitch(root, on));
385
+ });
386
+ onDriveChange(daemon.repaint);
387
+ // Each step too, so the panel's "N steps so far" counts up instead of sitting at zero.
388
+ onDriveStep(daemon.repaint);
389
+ // And "Connected: Claude Code" follows an agent attaching or leaving.
390
+ onAgentsChange(daemon.repaint);
391
+ }
392
+ /**
393
+ * The `unsynced` field of a report. Sent empty too, once this daemon has counted: the platform reads
394
+ * an absent list as "no news" and kept a "never sent" banner for runs that had long been sent.
395
+ */
396
+ export function unsyncedReport(unsynced, home) {
397
+ if (unsynced === undefined)
398
+ return {};
399
+ return {
400
+ // A folder no project claimed cannot be connected, so no board should tell anyone to.
401
+ unsynced: unsynced
402
+ .filter((u) => !isUnmatchedRoot(u.root))
403
+ .map((u) => ({
404
+ ...u,
405
+ // The project, not its `.reticle`: the dashboard tells the person to run a command there.
406
+ root: homeRelative(ReticleDir.ROOT === basename(u.root) ? dirname(u.root) : u.root, home),
407
+ })),
408
+ };
409
+ }
@@ -5,14 +5,6 @@ interface Control {
5
5
  }
6
6
  /** Parse the interactive snapshot into {ref,label} controls, preserving document order. */
7
7
  export declare function parseControls(tree: string): Control[];
8
- /**
9
- * Build the coverage tool over the dispatchable tool table.
10
- *
11
- * The table arrives as a thunk rather than an import: `tools.ts` assembles it FROM this module, so
12
- * importing it back would close a cycle whose failure mode is a load-order-dependent crash rather
13
- * than an error anyone sees while writing it. The thunk is called inside the handler, long after the
14
- * table exists. It carries the merged names — the ones `reticle_run` will actually accept — because
15
- * a tool that merged into a parent is not something an agent can call or a maintainer can cut.
16
- */
17
- export declare function buildCoverageTools(toolNames: () => readonly string[]): ToolDef[];
8
+ /** Build the coverage tool. */
9
+ export declare function buildCoverageTools(): ToolDef[];
18
10
  export {};
@@ -2,9 +2,6 @@ import { z } from 'zod';
2
2
  import { sessionRoot } from '../../memory/project/session-root.js';
3
3
  import { projectForRoot } from '../../memory/project/project-for-root.js';
4
4
  import { coverageRegressed, observabilityOf } from '@reticlehq/engine/evidence/observability.js';
5
- import { foldFeatureCapture } from './feature-capture.js';
6
- import { foldToolHitRate } from './tool-hit-rate.js';
7
- import { allSessionIntents } from '../../memory/intent/open-intents.js';
8
5
  import { ReticleCommand, SnapshotMode } from '@reticlehq/core';
9
6
  import { ReticleTool } from '@reticlehq/core';
10
7
  import { asString } from '@reticlehq/core';
@@ -55,16 +52,8 @@ export function parseControls(tree) {
55
52
  }
56
53
  return controls;
57
54
  }
58
- /**
59
- * Build the coverage tool over the dispatchable tool table.
60
- *
61
- * The table arrives as a thunk rather than an import: `tools.ts` assembles it FROM this module, so
62
- * importing it back would close a cycle whose failure mode is a load-order-dependent crash rather
63
- * than an error anyone sees while writing it. The thunk is called inside the handler, long after the
64
- * table exists. It carries the merged names — the ones `reticle_run` will actually accept — because
65
- * a tool that merged into a parent is not something an agent can call or a maintainer can cut.
66
- */
67
- export function buildCoverageTools(toolNames) {
55
+ /** Build the coverage tool. */
56
+ export function buildCoverageTools() {
68
57
  return [
69
58
  {
70
59
  name: ReticleTool.COVERAGE,
@@ -100,25 +89,6 @@ export function buildCoverageTools(toolNames) {
100
89
  .object({ driven: z.number(), observable: z.number(), percent: z.number().optional() })
101
90
  .optional()
102
91
  .describe('Of the controls you DROVE, how many Reticle could fully observe. `untouched` above is work left for you; this is work left in the APP, and driving more controls does not move it. `percent` is OMITTED when nothing was driven, because 0/0 is not 100%.'),
103
- featureUse: z
104
- .object({
105
- observed: z.boolean(),
106
- truncated: z.boolean().optional(),
107
- context: z.unknown().optional(),
108
- intents: z.unknown().optional(),
109
- missed: z.unknown().optional(),
110
- })
111
- .optional()
112
- .describe('Whether this session used `reticle_context` and `reticle_intent` at all, and what it cost when it did not: `context` counts the calls and what followed each one, `intents` the ledger, `missed` the verdicts drawn against an empty ledger and the reads that re-fetched a fact already established. `observed:false` means nothing was recorded for this session — NOT that nothing was used. An instrument for deciding whether those two features earn their place; nothing here is a fault of yours.'),
113
- toolHitRate: z
114
- .object({
115
- observed: z.boolean(),
116
- cells: z.unknown().optional(),
117
- called: z.unknown().optional(),
118
- neverCalled: z.unknown().optional(),
119
- })
120
- .optional()
121
- .describe('Which Reticle tools THIS session called, and how reachable each one was: `called` lists every tool with its call count, `neverCalled` the rest of the table, and both carry a `tier` — `default` (advertised to every agent), `extended` (advertised only on the full surface) or `run-only` (reachable solely by naming it to reticle_run). `cells` counts each tier on both sides. `observed:false` means nothing was recorded for this session, NOT that nothing was called. THREE LIMITS, all load-bearing: this is ONE session, so it is evidence about this run and is not a hit rate — a hit rate is a distribution over many sessions. A never-called tool is not a useless tool; one used once a month in an emergency looks identical here to one nobody has ever called, so frequency alone cannot decide a cut. And the counts describe how this run went, never how it should have gone — nothing here is a fault of yours.'),
122
92
  observabilityRegressed: z
123
93
  .object({ was: z.number(), now: z.number() })
124
94
  .optional()
@@ -143,25 +113,6 @@ export function buildCoverageTools(toolNames) {
143
113
  // first without the second is how an agent finishes a pass believing it verified something the
144
114
  // app was never able to confirm.
145
115
  const gaps = session.gaps?.open() ?? [];
146
- // Folded here rather than given a tool of its own: this is already the "am I done, and what is
147
- // this verdict worth" read, and a number nobody has a reason to ask for separately is one
148
- // nobody ever sees. It is a fold over the journal and the intent ledger plus the one thing
149
- // neither records — see surface/tools/feature-capture.ts.
150
- const featureUse = foldFeatureCapture({
151
- calls: session.capture.calls(),
152
- dropped: session.capture.dropped,
153
- actions: await session.readJournalActions(),
154
- intents: await allSessionIntents(deps, sessionId),
155
- finalActions: session.actionCount,
156
- });
157
- // Same fold, same reason, one level out: which of the whole tool table this session reached
158
- // for, crossed with how reachable each name was. See surface/tools/tool-hit-rate.ts for what it can
159
- // and cannot establish — the limits matter more than usual, because this is the number a
160
- // decision to DELETE tools would be made on.
161
- const toolHitRate = foldToolHitRate({
162
- calls: session.capture?.toolCalls(),
163
- allTools: toolNames(),
164
- });
165
116
  // The number, and the floor under it, together. A coverage figure that can only ever be
166
117
  // reported and never contradicted is one an agent learns to satisfy rather than to earn.
167
118
  const observability = observabilityOf(session.actedRefs(), gaps);
@@ -179,8 +130,6 @@ export function buildCoverageTools(toolNames) {
179
130
  ...(gaps.length > 0 ? { instrumentationGaps: gaps, unproven: true } : {}),
180
131
  observability,
181
132
  ...(regressed === undefined ? {} : { observabilityRegressed: regressed }),
182
- featureUse,
183
- toolHitRate,
184
133
  ...(true === args['app']
185
134
  ? {
186
135
  app: await foldAppCoverage({
@@ -8,13 +8,41 @@ import { ReticleTool } from '@reticlehq/core';
8
8
  import { ADVERTISE_ALL_ENV } from './tool-surface.js';
9
9
  import { getSessionMetrics } from '../../telemetry/session-metrics.js';
10
10
  import { isPredicateParam, predicateGrammar, } from '@reticlehq/engine/question/predicate/predicate-eval.js';
11
+ /**
12
+ * A numeric parameter's enforced bounds, read off the schema that enforces them (#1537).
13
+ *
14
+ * The descriptions name a default and rarely a ceiling, so `timeout_ms: 60000` on act_and_wait was
15
+ * refused and the agent learned the 55000 cap from the error. Read here rather than written into
16
+ * prose, so the number shown is the number checked and cannot drift from it.
17
+ */
18
+ function boundsOf(schema) {
19
+ let inner = schema;
20
+ for (;;) {
21
+ if (inner instanceof z.ZodOptional || inner instanceof z.ZodNullable) {
22
+ inner = inner.unwrap();
23
+ }
24
+ else if (inner instanceof z.ZodDefault) {
25
+ inner = inner.removeDefault();
26
+ }
27
+ else if (inner instanceof z.ZodEffects) {
28
+ inner = inner.innerType();
29
+ }
30
+ else
31
+ break;
32
+ }
33
+ if (!(inner instanceof z.ZodNumber))
34
+ return {};
35
+ const { minValue: min, maxValue: max } = inner;
36
+ return { ...(null === min ? {} : { min }), ...(null === max ? {} : { max }) };
37
+ }
11
38
  /** Compact param list from a tool's zod shape — name/required/description (the description already
12
- * carries the type and any enum hints, so no JSON-Schema machinery is needed). */
39
+ * carries the type and any enum hints, so no JSON-Schema machinery is needed), plus numeric bounds. */
13
40
  function paramInfo(shape) {
14
41
  return Object.entries(shape).map(([name, schema]) => ({
15
42
  name,
16
43
  required: !schema.isOptional(),
17
44
  description: schema.description ?? '',
45
+ ...boundsOf(schema),
18
46
  }));
19
47
  }
20
48
  /**
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ import type { ToolDeps } from './tool-kit.js';
3
+ /** The fields only an empty list carries, declared so a schema-aware client does not strip them. */
4
+ export declare const EMPTY_SESSION_LIST_OUTPUT: {
5
+ why: z.ZodOptional<z.ZodString>;
6
+ next_action: z.ZodOptional<z.ZodObject<{
7
+ action: z.ZodNativeEnum<{
8
+ readonly START_DEV_SERVER: "start_dev_server";
9
+ readonly RUN_INIT: "run_init";
10
+ readonly OPEN_APP: "open_app";
11
+ readonly REOPEN_APP: "reopen_app";
12
+ readonly DAEMON_SPLIT: "daemon_split";
13
+ }>;
14
+ command: z.ZodOptional<z.ZodString>;
15
+ port: z.ZodOptional<z.ZodNumber>;
16
+ reason: z.ZodString;
17
+ }, "strip", z.ZodTypeAny, {
18
+ action: "start_dev_server" | "run_init" | "open_app" | "reopen_app" | "daemon_split";
19
+ reason: string;
20
+ port?: number | undefined;
21
+ command?: string | undefined;
22
+ }, {
23
+ action: "start_dev_server" | "run_init" | "open_app" | "reopen_app" | "daemon_split";
24
+ reason: string;
25
+ port?: number | undefined;
26
+ command?: string | undefined;
27
+ }>>;
28
+ talk_to_us: z.ZodOptional<z.ZodString>;
29
+ wired: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
30
+ lastKnown: z.ZodOptional<z.ZodObject<{
31
+ sessionId: z.ZodString;
32
+ url: z.ZodString;
33
+ }, "strip", z.ZodTypeAny, {
34
+ sessionId: string;
35
+ url: string;
36
+ }, {
37
+ sessionId: string;
38
+ url: string;
39
+ }>>;
40
+ };
41
+ /**
42
+ * Wire the calling project when another project's tab is the one currently connected.
43
+ *
44
+ * The list handler only used to reach {@link emptySessionList} when the daemon's whole list was
45
+ * empty. A live tab in project A then answered project B's first call with A's sessions, and B
46
+ * was never wired.
47
+ */
48
+ export declare function wireCallerBesideLiveSessions(deps: ToolDeps, sessions: readonly {
49
+ projectId?: string;
50
+ }[]): Promise<unknown>;
51
+ export declare function emptySessionList(deps: ToolDeps, sessions: unknown[]): Promise<Record<string, unknown>>;