@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
@@ -0,0 +1,169 @@
1
+ /**
2
+ * The wiring `start` and `startDaemon` share, built in one place so the two entry points cannot drift.
3
+ *
4
+ * Split from `index.ts`: that file is the package's front door and the two entry points; these are
5
+ * the pieces both of them assemble — the browser pool, the drive/real-input provider, the CDP network
6
+ * router, and the per-project lookups the daemon closes over. `daemon-parity.test.ts` checks both
7
+ * entry points still call them.
8
+ */
9
+ import { join } from 'node:path';
10
+ import { cpus, homedir } from 'node:os';
11
+ import { bridgeWsUrl, EventType, ReticleDir, ReticleEnv } from '@reticlehq/core';
12
+ import { fetchPlatformConfig } from './features/harness/platform-config.js';
13
+ import { platformEnvPort } from './memory/cloud/cloud-config.js';
14
+ import { knownProjectCandidates, projectDirectoryFor, } from './memory/project/artifact-root-resolver.js';
15
+ import { createNodeFileSystem } from './memory/project/fs/fs-port.js';
16
+ import { originOf } from './portal/session/session-manager.js';
17
+ import { setBrowserMode, BrowserMode } from './telemetry/browser-mode.js';
18
+ import { sdkFixForDirectory } from './command/version/sdk-fix.js';
19
+ import { SERVER_VERSION } from './command/version/identity/server-version.js';
20
+ import { CdpRealInputProvider, LaunchedRealInputProvider } from './portal/input/real-input.js';
21
+ import { BrowserPool } from './portal/pool/browser-pool.js';
22
+ import { playwrightLauncher, resolveMaxContexts } from './portal/pool/playwright-launcher.js';
23
+ import { readReaderBundle, zeroInstallScript as zeroInstallScriptFor, } from './portal/pool/zero-install.js';
24
+ /**
25
+ * Build the shared browser pool (one headless Chromium, N capped isolated leased contexts). Lazy —
26
+ * no Chromium launches until the first lease — so creating it is free even when never used.
27
+ */
28
+ /** Where the zero-install reader connects: this daemon's own bridge, with its pairing token. */
29
+ export function readerConnect(port, token) {
30
+ return { url: bridgeWsUrl(port), ...(token === undefined ? {} : { token }) };
31
+ }
32
+ export function createBrowserPool(headless, reader) {
33
+ const maxContexts = resolveMaxContexts(process.env[ReticleEnv.MAX_CONTEXTS], cpus().length);
34
+ const genSessionId = () => `lease-${'function' === typeof globalThis.crypto?.randomUUID
35
+ ? globalThis.crypto.randomUUID()
36
+ : String(Date.now())}`;
37
+ // Built on first use and kept: the page that needs it is one whose app never connected.
38
+ let script;
39
+ const zeroInstallScript = () => {
40
+ if (script === undefined) {
41
+ const bundle = readReaderBundle();
42
+ script = bundle === undefined ? null : zeroInstallScriptFor(bundle, reader);
43
+ }
44
+ return script ?? undefined;
45
+ };
46
+ return new BrowserPool(playwrightLauncher({ headless }), {
47
+ maxContexts,
48
+ genSessionId,
49
+ zeroInstallScript,
50
+ launchHeaded: playwrightLauncher({ headless: false }),
51
+ });
52
+ }
53
+ /**
54
+ * Route CDP-authoritative network detail onto the driven session's journal.
55
+ *
56
+ * The page and the SDK session share an origin, so a NET_DETAIL is pushed to the matching connected
57
+ * session. Shared by both entry points: `startDaemon` previously omitted it entirely, so on the path
58
+ * users actually take, CDP network detail was collected and then dropped on the floor.
59
+ */
60
+ export function makeNetworkDetailRouter(bridge, driveUrl) {
61
+ const driveOrigin = originOf(driveUrl ?? '');
62
+ return (detail) => {
63
+ // Route by the DOCUMENT that issued the request, not by the request's own origin.
64
+ //
65
+ // Matching the request's origin only works for same-origin calls. An app on one origin calling an
66
+ // API on another — most API calls — produced a detail matching no session, and it was dropped
67
+ // without a trace. The drive-URL fallback papered over it on the launched path and did nothing on
68
+ // the CDP-attach path, where driveUrl is undefined and the fallback compares against ''.
69
+ const pageOrigin = originOf(detail.pageUrl ?? '');
70
+ const requestOrigin = originOf(detail.url);
71
+ for (const session of bridge.sessions.all()) {
72
+ const origin = originOf(session.url);
73
+ // originOf returns `string | undefined`, NEVER '' — so the old `!== ''` guards were dead, and a
74
+ // bare `origin === requestOrigin` matched `undefined === undefined` when BOTH the session URL and
75
+ // the detail URL were unparseable. That routed a NET_DETAIL (with its response headers, incl.
76
+ // set-cookie) onto an unrelated session. Require a DEFINED origin; undefined operands then simply
77
+ // fail to match any of the three candidates.
78
+ const matches = origin !== undefined &&
79
+ (origin === pageOrigin || origin === requestOrigin || origin === driveOrigin);
80
+ if (matches) {
81
+ session.pushEvent({
82
+ t: 0,
83
+ type: EventType.NET_DETAIL,
84
+ sessionId: session.id,
85
+ data: { ...detail },
86
+ });
87
+ }
88
+ }
89
+ };
90
+ }
91
+ /**
92
+ * Resolve the drive/real-input provider from options — shared by start and startDaemon so the
93
+ * precedence (driveUrl launch+own → CDP attach → none) and the storageState/injectConnect plumbing
94
+ * live in ONE place. `onNavigateError` is the entrypoint's own cleanup (close the bridge/shared server)
95
+ * so a failed launch never leaks a WS port. A past divergence between the two paths let daemon mode
96
+ * run with a different setup — this removes that risk.
97
+ */
98
+ export async function resolveRealInput(options, onNavigateError, onNetworkDetail) {
99
+ const driveUrl = options.driveUrl;
100
+ if (driveUrl !== undefined && driveUrl.length > 0) {
101
+ const headless = options.headless ?? true;
102
+ // The one place that knows. Everything downstream reads it rather than re-deriving it, and a
103
+ // daemon that launches nothing keeps the default (ATTACHED) rather than guessing.
104
+ setBrowserMode(headless ? BrowserMode.HEADLESS : BrowserMode.HEADED);
105
+ const injectConnect = options.injectConnect;
106
+ const storageState = options.storageState;
107
+ const factory = options.realInputFactory ??
108
+ ((opts) => new LaunchedRealInputProvider({
109
+ driveUrl: opts.driveUrl,
110
+ headless: opts.headless,
111
+ ...(injectConnect !== undefined ? { injectConnect } : {}),
112
+ ...(storageState !== undefined ? { storageState } : {}),
113
+ ...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
114
+ }));
115
+ const launched = factory({ driveUrl, headless });
116
+ try {
117
+ await launched.navigate();
118
+ }
119
+ catch (error) {
120
+ await onNavigateError(); // no leaked WS port on a failed start
121
+ throw error;
122
+ }
123
+ return { realInput: launched, owned: launched };
124
+ }
125
+ const cdpUrl = options.cdpUrl ?? process.env[ReticleEnv.CDP_URL];
126
+ if (cdpUrl !== undefined && cdpUrl.length > 0) {
127
+ // Same network sink as the launched path. Whether Reticle opened the browser or attached to one
128
+ // someone else opened has no bearing on whether it can read that browser's network.
129
+ const cdp = new CdpRealInputProvider({
130
+ cdpUrl,
131
+ ...(onNetworkDetail !== undefined ? { onNetworkDetail } : {}),
132
+ });
133
+ return { realInput: cdp, owned: cdp };
134
+ }
135
+ return {};
136
+ }
137
+ /**
138
+ * The SDK-upgrade sentence for the package.json of the project the page announced, evaluated at
139
+ * each HELLO so a just-edited manifest is what we name. The daemon's cwd only when that project's
140
+ * directory is unknown, and the framework-neutral sensor when that is not an app either (#1135).
141
+ */
142
+ export function sdkFixForProject(projectId) {
143
+ return sdkFixForDirectory(SERVER_VERSION, projectDirectoryFor(projectId) ?? process.cwd());
144
+ }
145
+ /**
146
+ * Resolve a session's artifact root, from everything this machine knows about where projects live.
147
+ *
148
+ * Built once per daemon and closed over by every tool call. The two sources are read lazily and
149
+ * cheaply on each call rather than snapshotted at startup: `init` can run in another terminal while
150
+ * this daemon is up, and a resolution that used a startup snapshot would keep answering with a map
151
+ * from before the project the agent is now driving existed.
152
+ */
153
+ /**
154
+ * Every `.reticle` root on this machine that sync should consider, from the same two sources the
155
+ * artifact resolver uses.
156
+ *
157
+ * Read on every call rather than snapshotted, for the same reason: `reticle link` can run in
158
+ * another terminal while this daemon is up, and a startup snapshot would keep that repo silent
159
+ * until somebody restarted a process they have no reason to suspect.
160
+ *
161
+ * Returns directories that MIGHT be linked; the caller resolves each and skips the ones that are
162
+ * not. Deciding that here would mean reading every cloud.json on every tick.
163
+ */
164
+ export function knownProjectRoots() {
165
+ return [...new Set(knownProjectCandidates().map((c) => join(c.directory, ReticleDir.ROOT)))];
166
+ }
167
+ /** This project's platform credential (stored, else the env key), as the env the platform readers take. */
168
+ export const platformEnvFor = (root) => platformEnvPort(createNodeFileSystem(), root ?? join(process.cwd(), ReticleDir.ROOT), homedir(), process.env);
169
+ export const loadHarnessConfig = async (root) => fetchPlatformConfig(await platformEnvFor(root)());
@@ -7,6 +7,7 @@
7
7
  * answering requests. See takeVersionSkewOnto in command/version/version-nudge.ts.
8
8
  */
9
9
  import type { SessionInfo } from './portal/session/session-info.js';
10
+ import { instrumentationOf, type InstrumentedTab } from './portal/session/recorded-gaps.js';
10
11
  interface StatusPayload {
11
12
  running: true;
12
13
  version: string;
@@ -30,12 +31,23 @@ interface StatusPayload {
30
31
  whyLead?: string;
31
32
  /** Port of the verify HTTP endpoint this daemon serves — present only when started with `--http`. */
32
33
  verifyPort?: number;
34
+ /**
35
+ * Each connected tab's instrumentation coverage and, once a verdict recorded a gap, the prompt for
36
+ * a coding agent — what `reticle doctor` prints as its coverage line.
37
+ */
38
+ coverage?: TabCoverage[];
33
39
  }
40
+ type TabCoverage = {
41
+ sessionId: string;
42
+ url?: string;
43
+ } & ReturnType<typeof instrumentationOf>;
34
44
  export declare function statusPayload(sessionCount: number, sessions: SessionInfo[],
35
45
  /** The no-session diagnosis, injected so this stays pure and the port probe stays off this path. */
36
46
  why?: string, verifyPort?: number,
37
47
  /** The short rendering of the same diagnosis. Absent on a daemon that has no provider wired. */
38
- whyLead?: string): StatusPayload;
48
+ whyLead?: string,
49
+ /** The live tabs, for their coverage. */
50
+ tabs?: readonly InstrumentedTab[]): StatusPayload;
39
51
  /**
40
52
  * Why `serve --http` cannot claim success against an already-running daemon — or undefined when
41
53
  * that daemon already serves the verify HTTP endpoint on the wanted port.
@@ -1,10 +1,13 @@
1
1
  import { CONTRACT_FINGERPRINT } from '@reticlehq/core';
2
2
  import { SERVER_VERSION } from './command/version/identity/server-version.js';
3
+ import { instrumentationOf } from './portal/session/recorded-gaps.js';
3
4
  export function statusPayload(sessionCount, sessions,
4
5
  /** The no-session diagnosis, injected so this stays pure and the port probe stays off this path. */
5
6
  why, verifyPort,
6
7
  /** The short rendering of the same diagnosis. Absent on a daemon that has no provider wired. */
7
- whyLead) {
8
+ whyLead,
9
+ /** The live tabs, for their coverage. */
10
+ tabs = []) {
8
11
  return {
9
12
  running: true,
10
13
  version: SERVER_VERSION,
@@ -16,6 +19,15 @@ whyLead) {
16
19
  ...(0 === sessionCount && why !== undefined ? { why } : {}),
17
20
  ...(0 === sessionCount && whyLead !== undefined ? { whyLead } : {}),
18
21
  ...(verifyPort === undefined ? {} : { verifyPort }),
22
+ ...(0 === tabs.length
23
+ ? {}
24
+ : {
25
+ coverage: tabs.map((tab) => ({
26
+ sessionId: tab.id,
27
+ ...(tab.url === undefined ? {} : { url: tab.url }),
28
+ ...instrumentationOf(tab),
29
+ })),
30
+ }),
19
31
  };
20
32
  }
21
33
  /**
@@ -5,6 +5,7 @@ import { getSessionMetrics } from '../telemetry/session-metrics.js';
5
5
  import { agentPeerSkew, PEER_VERSION_PARAM, PEER_CONTRACT_PARAM, } from '../command/version/peer-announce.js';
6
6
  import { log } from '../log.js';
7
7
  import { isLoopbackHost, isLocalWebOrigin, isLoopbackPeer, requestToken, tokensMatch, } from '../portal/bridge/token-auth.js';
8
+ import { clientDirectoryFromPeer, runWithClientDirectory } from '../hooks/client-directory.js';
8
9
  import { LOOPBACK_IDLE_MS } from './loopback-agent.js';
9
10
  /**
10
11
  * Creates a shared HTTP server that handles both the WebSocket bridge (browser SDK) and the
@@ -212,7 +213,12 @@ export function createSharedServer(options = {}) {
212
213
  res.end('session not found');
213
214
  return;
214
215
  }
215
- transport.handlePostMessage(req, res).catch((err) => {
216
+ const clientDirectory = clientDirectoryFromPeer(isLoopbackPeer(req.socket.remoteAddress), req.headers);
217
+ const deliver = () => transport.handlePostMessage(req, res);
218
+ const posted = clientDirectory === undefined
219
+ ? deliver()
220
+ : runWithClientDirectory(clientDirectory, deliver);
221
+ posted.catch((err) => {
216
222
  const message = err instanceof Error ? err.message : String(err);
217
223
  log('mcp_message_error', { error: message });
218
224
  });
@@ -71,6 +71,7 @@ export declare function describeAttachState(state: AttachState): string | undefi
71
71
  /** What `reticle status` reports about the client side of the install. */
72
72
  interface AttachStatusFields {
73
73
  mcpClient: AttachState;
74
+ mcpClientSaid: string;
74
75
  mcpClientAction?: string;
75
76
  }
76
77
  /**
@@ -169,6 +169,13 @@ export function describeAttachState(state) {
169
169
  return NEVER_CALLED_ACTION;
170
170
  return undefined;
171
171
  }
172
+ /** Each state in words, for a person: the state names are the record's, never the reader's. */
173
+ const ATTACH_STATE_SAID = {
174
+ [AttachState.ENUMERATED]: "✓ your agent has read and used Reticle's tools",
175
+ [AttachState.NEVER_CALLED]: "your agent read Reticle's tools and has not called one yet",
176
+ [AttachState.NEVER_ENUMERATED]: '✗ your agent started Reticle and never read its tools',
177
+ [AttachState.NEVER_ATTACHED]: 'no agent has started Reticle on this port yet',
178
+ };
172
179
  /**
173
180
  * The client-side fields for one `status` run.
174
181
  *
@@ -181,5 +188,9 @@ export function attachStatusFields(stateDir, port) {
181
188
  const action = describeAttachState(state);
182
189
  // OMITTED rather than undefined: `exactOptionalPropertyTypes` is on, and an absent key is also
183
190
  // what keeps the healthy line to one fact.
184
- return { mcpClient: state, ...(action === undefined ? {} : { mcpClientAction: action }) };
191
+ return {
192
+ mcpClient: state,
193
+ mcpClientSaid: ATTACH_STATE_SAID[state],
194
+ ...(action === undefined ? {} : { mcpClientAction: action }),
195
+ };
185
196
  }
@@ -25,6 +25,8 @@ export declare const RECONNECT_INITIALIZE_ID = "__reticle_proxy_reinit";
25
25
  export declare class PendingRequests {
26
26
  #private;
27
27
  observeOutbound(line: string): void;
28
+ /** Whether this unanswered request asked for a Harness drive. */
29
+ isDrive(id: unknown): boolean;
28
30
  observeInbound(line: string): void;
29
31
  get unanswered(): string[];
30
32
  /**
@@ -34,6 +36,8 @@ export declare class PendingRequests {
34
36
  take(id: unknown): boolean;
35
37
  /** Take every unanswered id and forget them, so the same request is failed at most once. */
36
38
  drain(): string[];
39
+ /** Forget which requests were drives, once their replies are written. */
40
+ clearDrives(): void;
37
41
  }
38
42
  /**
39
43
  * JSON-RPC errors for every request that was in flight when the stream died.
@@ -32,6 +32,7 @@ export { accountProxyLogWrite, proxyLog, proxyLogPath, PROXY_LOG_CHECK_BYTES, re
32
32
  import { proxyLog } from './proxy/proxy-log.js';
33
33
  import { OutageReason, OutageStage, reportMcpOutage } from './faults/mcp-outage.js';
34
34
  import { postToSession } from './proxy/mcp-post-transport.js';
35
+ import { MSG_DRIVE_MAY_BE_RUNNING, isHarnessDriveCall } from './proxy/drive-calls.js';
35
36
  import { reconnectDelayMs } from './proxy/proxy-backoff.js';
36
37
  import { PROXY_IDLE_EXIT_EVENT, ProxyIdleExit, resolveProxyIdleExitMs } from './proxy-idle-exit.js';
37
38
  export { reconnectDelayMs } from './proxy/proxy-backoff.js';
@@ -84,11 +85,20 @@ const INITIALIZED_METHOD = 'notifications/initialized';
84
85
  */
85
86
  export class PendingRequests {
86
87
  #ids = new Set();
88
+ /** The pending requests that start or poll a Harness drive, which outlives a lost connection. */
89
+ #drives = new Set();
87
90
  observeOutbound(line) {
88
91
  const msg = parseJsonRpc(line);
89
92
  if (null === msg || msg.id === undefined || msg.method === undefined)
90
93
  return;
91
- this.#ids.add(JSON.stringify(msg.id));
94
+ const id = JSON.stringify(msg.id);
95
+ this.#ids.add(id);
96
+ if (isHarnessDriveCall(msg))
97
+ this.#drives.add(id);
98
+ }
99
+ /** Whether this unanswered request asked for a Harness drive. */
100
+ isDrive(id) {
101
+ return this.#drives.has(JSON.stringify(id));
92
102
  }
93
103
  observeInbound(line) {
94
104
  const msg = parseJsonRpc(line);
@@ -104,6 +114,7 @@ export class PendingRequests {
104
114
  * a duplicate response to one id is a protocol violation, not a belt-and-braces retry.
105
115
  */
106
116
  take(id) {
117
+ this.#drives.delete(JSON.stringify(id));
107
118
  return this.#ids.delete(JSON.stringify(id));
108
119
  }
109
120
  /** Take every unanswered id and forget them, so the same request is failed at most once. */
@@ -112,6 +123,10 @@ export class PendingRequests {
112
123
  this.#ids.clear();
113
124
  return ids;
114
125
  }
126
+ /** Forget which requests were drives, once their replies are written. */
127
+ clearDrives() {
128
+ this.#drives.clear();
129
+ }
115
130
  }
116
131
  /**
117
132
  * JSON-RPC errors for every request that was in flight when the stream died.
@@ -126,9 +141,12 @@ export class PendingRequests {
126
141
  * with the MCP server still perfectly alive. An agent cannot tell that apart from "still working".
127
142
  */
128
143
  export function streamLossReplies(pending, reason, nextStep) {
129
- return pending
130
- .drain()
131
- .map((id) => transportLossReply(JSON.parse(id), reason, nextStep));
144
+ const replies = pending.drain().map((id) => {
145
+ const parsed = JSON.parse(id);
146
+ return transportLossReply(parsed, reason, nextStep, pending.isDrive(parsed));
147
+ });
148
+ pending.clearDrives();
149
+ return replies;
132
150
  }
133
151
  /**
134
152
  * -32001: a server-defined error. Not -32603 (internal): nothing went wrong INSIDE the call, the
@@ -142,14 +160,16 @@ const TRANSPORT_LOSS_CODE = -32001;
142
160
  * `nextStep` is appended when the caller knows one. Without it this reply describes a condition and
143
161
  * stops there, which is all a first-run user got out of their first ever tool call.
144
162
  */
145
- function transportLossReply(id, reason, nextStep) {
163
+ function transportLossReply(id, reason, nextStep, drive = false) {
146
164
  return JSON.stringify({
147
165
  jsonrpc: '2.0',
148
166
  id,
149
167
  error: {
150
168
  code: TRANSPORT_LOSS_CODE,
151
- message: `the daemon connection dropped (${reason}) before this call was answered — it did NOT ` +
152
- 'complete. Reticle is recovering the connection; retry if the action is safe to repeat.' +
169
+ message: (drive
170
+ ? `the daemon connection dropped (${reason}) before this call was answered. ${MSG_DRIVE_MAY_BE_RUNNING}`
171
+ : `the daemon connection dropped (${reason}) before this call was answered — it did NOT ` +
172
+ 'complete. Reticle is recovering the connection; retry if the action is safe to repeat.') +
153
173
  (nextStep === undefined ? '' : ` ${nextStep}`),
154
174
  },
155
175
  });
@@ -490,6 +510,7 @@ onUsableSession = () => undefined) {
490
510
  if (null === failure)
491
511
  return;
492
512
  const msg = parseJsonRpc(line);
513
+ const drive = null !== msg && pending.isDrive(msg.id);
493
514
  if (null === msg || msg.id === undefined || !pending.take(msg.id))
494
515
  return;
495
516
  // No outage is reported here, deliberately. A POST leg that died while the SSE stream is
@@ -503,7 +524,7 @@ onUsableSession = () => undefined) {
503
524
  reason: failure.reason,
504
525
  note: 'the stream is still up, so nothing else would ever have answered this call',
505
526
  });
506
- emit(transportLossReply(msg.id, failure.reason));
527
+ emit(transportLossReply(msg.id, failure.reason, undefined, drive));
507
528
  });
508
529
  };
509
530
  function onSseEvent(event, data, p) {
@@ -3,6 +3,7 @@ import { z } from 'zod';
3
3
  import { type ToolDeps } from '../tools/tools.js';
4
4
  import type { ToolDef } from '../tools/tools.js';
5
5
  import { type ToolSurface } from '../tools/tool-surface.js';
6
+ import { type ToolCall } from '../tools/tool-kit.js';
6
7
  import { type InstructionState } from './server-instructions.js';
7
8
  /** The JSON-RPC method the SDK registers its tool dispatcher under. */
8
9
  export declare const CALL_TOOL_METHOD = "tools/call";
@@ -36,6 +37,28 @@ export { firstSentence } from '../tools/first-sentence.js';
36
37
  * form with `RETICLE_ENCODING=pretty`; `RETICLE_ENCODING=toon` is the even-denser tabular encoding.
37
38
  */
38
39
  export declare function encodeResult(result: unknown, encoding: string): string;
40
+ /** The slice of the SDK's per-request `extra` a tool call reads: cancellation and progress. */
41
+ interface McpRequestExtra {
42
+ signal?: AbortSignal;
43
+ _meta?: {
44
+ progressToken?: string | number;
45
+ };
46
+ sendNotification?: (notification: {
47
+ method: typeof PROGRESS_NOTIFICATION;
48
+ params: {
49
+ progressToken: string | number;
50
+ progress: number;
51
+ message: string;
52
+ };
53
+ }) => Promise<void>;
54
+ }
55
+ declare const PROGRESS_NOTIFICATION = "notifications/progress";
56
+ /**
57
+ * The request's cancellation and, when the client sent a progress token, a progress reporter. A
58
+ * long call (a Harness drive's wait) reports each step, so a client that resets its timeout on
59
+ * progress keeps waiting instead of abandoning a call that is working.
60
+ */
61
+ export declare function toolCallOf(extra: McpRequestExtra | undefined): ToolCall;
39
62
  /**
40
63
  * The tools a profile advertises directly.
41
64
  *
@@ -38,6 +38,7 @@ import { SERVER_VERSION } from '../../command/version/identity/server-version.js
38
38
  import { setMcpClientNameHook } from '../../telemetry/feedback-context.js';
39
39
  import { getSessionMetrics } from '../../telemetry/session-metrics.js';
40
40
  import { reportMcpConnected } from '../../telemetry/mcp-connection.js';
41
+ import { noteAgentAttached, noteAgentDetached, runAsAgent } from '../../hooks/coding-agents.js';
41
42
  import { parsePredicate } from '@reticlehq/engine/question/predicate/predicate-parse.js';
42
43
  /**
43
44
  * Merge the runtime-spliced envelope into a tool's declared outputSchema so structuredContent
@@ -192,6 +193,27 @@ export function encodeResult(result, encoding) {
192
193
  }
193
194
  return encoding === PRETTY_VALUE ? JSON.stringify(result, null, 2) : JSON.stringify(result);
194
195
  }
196
+ const PROGRESS_NOTIFICATION = 'notifications/progress';
197
+ /**
198
+ * The request's cancellation and, when the client sent a progress token, a progress reporter. A
199
+ * long call (a Harness drive's wait) reports each step, so a client that resets its timeout on
200
+ * progress keeps waiting instead of abandoning a call that is working.
201
+ */
202
+ export function toolCallOf(extra) {
203
+ const token = extra?._meta?.progressToken;
204
+ const send = extra?.sendNotification;
205
+ return {
206
+ ...(extra?.signal === undefined ? {} : { signal: extra.signal }),
207
+ ...(token === undefined || send === undefined
208
+ ? {}
209
+ : {
210
+ progress: (progress, message) => void send({
211
+ method: PROGRESS_NOTIFICATION,
212
+ params: { progressToken: token, progress, message },
213
+ }).catch(() => undefined),
214
+ }),
215
+ };
216
+ }
195
217
  /**
196
218
  * The tools a profile advertises directly.
197
219
  *
@@ -430,8 +452,10 @@ function installUnadvertisedToolHelp(server, advertised, known) {
430
452
  return original(asCallOf(request, moved.tool, moved.action), extra);
431
453
  }
432
454
  const help = name === undefined ? undefined : unadvertisedToolHelp(name, advertised, known);
455
+ // A failed RESULT, not a JSON-RPC error: a client that reads only `result` rendered the error
456
+ // as an empty success, and the agent believed `reticle_flow_save` had saved its flow.
433
457
  if (help !== undefined)
434
- throw new McpError(ErrorCode.InvalidParams, help);
458
+ return { content: [{ type: 'text', text: help }], isError: true };
435
459
  return original(request, extra);
436
460
  });
437
461
  }
@@ -537,12 +561,15 @@ tools = tableForSurface(profile)) {
537
561
  if (info?.name === undefined)
538
562
  return;
539
563
  getSessionMetrics().recordClient(info.name, info.version);
564
+ // So the HUD can say which agent is connected, and credit a note to the one that read it.
565
+ noteAgentAttached(deps.attachId, info.name);
540
566
  // The one signal that separates "Reticle is running" from "somebody is USING it", reported from
541
567
  // the first moment it can carry WHO. It used to fire from the SSE `connect()` resolution, which
542
568
  // happens before the handshake — so every connect row was anonymous, and the field meant to say
543
569
  // which agent client converts best was empty on every event ever sent.
544
- reportMcpConnected(info.name);
570
+ void runAsAgent(deps.attachId, () => Promise.resolve(reportMcpConnected(info.name)));
545
571
  };
572
+ server.server.onclose = () => noteAgentDetached(deps.attachId);
546
573
  // Which agent is on the other end, for a feedback report. Registered as a lazy hook rather than
547
574
  // read here: the handshake has not happened yet at construction time, and a report filed twenty
548
575
  // tool calls later is exactly when we want the answer.
@@ -624,9 +651,12 @@ tools = tableForSurface(profile)) {
624
651
  // clients. This removes the single largest remaining slice of the per-request tax (~36% of the
625
652
  // hybrid payload) with no loss the agent can observe.
626
653
  const config = advertisedConfig(tool, advertised, profile);
627
- registerTool(tool.name, config, async (args) => {
654
+ registerTool(tool.name, config, async (args, extra) => {
628
655
  try {
629
- const result = await runTool(tool, deps, args);
656
+ // Inside the caller's connection, so the telemetry this call emits after its handler (the
657
+ // verdict, a defect, a refusal) is credited to the agent that made it, not to whichever
658
+ // agent is attached.
659
+ const result = await runAsAgent(deps.attachId, () => runTool(tool, deps, args, toolCallOf(extra)));
630
660
  // A tool this codebase did not write may not hand the agent a verdict.
631
661
  //
632
662
  // Only reached for a tool absent from the first-party table, so the shipped surface pays a
@@ -0,0 +1,10 @@
1
+ /** A `tools/call` of reticle_verify explore, directly or through the reticle_run hatch. */
2
+ export declare function isHarnessDriveCall(msg: {
3
+ method?: unknown;
4
+ params?: unknown;
5
+ }): boolean;
6
+ /**
7
+ * A drive lives in the daemon, not in the call: a lost connection does not end it, and retrying the
8
+ * call as if it had not run pays for a second drive.
9
+ */
10
+ export declare const MSG_DRIVE_MAY_BE_RUNNING: string;
@@ -0,0 +1,27 @@
1
+ /** Which proxied calls are Harness drives, and what to tell an agent whose drive call was lost. */
2
+ import { ReticleTool } from '@reticlehq/core';
3
+ const TOOLS_CALL = 'tools/call';
4
+ const EXPLORE_ACTION = 'explore';
5
+ /** A `tools/call` of reticle_verify explore, directly or through the reticle_run hatch. */
6
+ export function isHarnessDriveCall(msg) {
7
+ if (TOOLS_CALL !== msg.method)
8
+ return false;
9
+ const params = (msg.params ?? {});
10
+ const args = (params.arguments ?? {});
11
+ if (ReticleTool.VERIFY_EXPLORE === params.name)
12
+ return true;
13
+ if (ReticleTool.VERIFY === params.name)
14
+ return EXPLORE_ACTION === args['action'];
15
+ if (ReticleTool.RUN !== params.name)
16
+ return false;
17
+ const inner = (args['args'] ?? {});
18
+ return (ReticleTool.VERIFY_EXPLORE === args['tool'] ||
19
+ (ReticleTool.VERIFY === args['tool'] && EXPLORE_ACTION === inner['action']));
20
+ }
21
+ /**
22
+ * A drive lives in the daemon, not in the call: a lost connection does not end it, and retrying the
23
+ * call as if it had not run pays for a second drive.
24
+ */
25
+ export const MSG_DRIVE_MAY_BE_RUNNING = `The Harness drive this call started or polled may still be running in the daemon. Once ` +
26
+ `Reticle reconnects, call ${ReticleTool.VERIFY} {action:"explore"} with no runId to get the ` +
27
+ `running drive back (it will not start a second), then poll it by runId.`;
@@ -7,6 +7,7 @@
7
7
  * saying honestly that it never arrived — and the file it came from is about the SSE stream.
8
8
  */
9
9
  import * as http from 'node:http';
10
+ import { MCP_CLIENT_DIRECTORY_HEADER } from '@reticlehq/core';
10
11
  import { log } from '../../../log.js';
11
12
  import { getSessionMetrics } from '../../../telemetry/session-metrics.js';
12
13
  import { reconnectDelayMs } from './proxy-backoff.js';
@@ -47,6 +48,10 @@ export function postToSession(url, body, request = (options, callback) => http.r
47
48
  headers: {
48
49
  'Content-Type': 'application/json',
49
50
  'Content-Length': bodyBuf.byteLength,
51
+ // The project this proxy was started in. The daemon serves every project; without this
52
+ // it can only see the directory it itself started in. Percent-encoded: a cwd such as
53
+ // `/work/项目` is not a legal header value, and Node throws before the request is sent.
54
+ [MCP_CLIENT_DIRECTORY_HEADER]: encodeURIComponent(process.cwd()),
50
55
  },
51
56
  };
52
57
  // A keep-alive socket carries historical bytes; retry safety depends on this request's delta.