@reticlehq/server 3.5.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (721) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +123 -116
  3. package/dist/chromium-launch-options.d.ts +3 -1
  4. package/dist/chromium-launch-options.js +2 -1
  5. package/dist/command/cli/adhoc-suite.d.ts +14 -0
  6. package/dist/command/cli/adhoc-suite.js +42 -7
  7. package/dist/command/cli/adhoc-verdict.d.ts +19 -2
  8. package/dist/command/cli/adhoc-verdict.js +76 -9
  9. package/dist/command/cli/answers/gate-exit.d.ts +23 -0
  10. package/dist/command/cli/answers/gate-exit.js +45 -0
  11. package/dist/command/cli/answers/gate-hook-message.d.ts +2 -0
  12. package/dist/command/cli/answers/gate-hook-message.js +3 -1
  13. package/dist/command/cli/answers/open-note.d.ts +2 -0
  14. package/dist/command/cli/answers/open-note.js +22 -0
  15. package/dist/command/cli/auth/device-flow.d.ts +13 -2
  16. package/dist/command/cli/auth/device-flow.js +17 -0
  17. package/dist/command/cli/cli-doctor.js +14 -0
  18. package/dist/command/cli/cli-flow-commands.d.ts +0 -11
  19. package/dist/command/cli/cli-flow-commands.js +31 -112
  20. package/dist/command/cli/cli-kill.js +3 -2
  21. package/dist/command/cli/cli-parse-grammar.d.ts +24 -0
  22. package/dist/command/cli/cli-parse-grammar.js +75 -0
  23. package/dist/command/cli/cli-parse-verify.d.ts +2 -0
  24. package/dist/command/cli/cli-parse-verify.js +18 -0
  25. package/dist/command/cli/cli-parse.d.ts +19 -28
  26. package/dist/command/cli/cli-parse.js +82 -182
  27. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  28. package/dist/command/cli/cli-update-commands.js +61 -9
  29. package/dist/command/cli/cli-usage.d.ts +33 -0
  30. package/dist/command/cli/cli-usage.js +287 -0
  31. package/dist/command/cli/cli-verify.d.ts +35 -5
  32. package/dist/command/cli/cli-verify.js +114 -35
  33. package/dist/command/cli/cloud-cli.d.ts +13 -0
  34. package/dist/command/cli/cloud-cli.js +192 -341
  35. package/dist/command/cli/cloud-kit.d.ts +12 -0
  36. package/dist/command/cli/cloud-kit.js +41 -2
  37. package/dist/command/cli/cloud-link.d.ts +57 -0
  38. package/dist/command/cli/cloud-link.js +308 -0
  39. package/dist/command/cli/cloud-login.d.ts +22 -0
  40. package/dist/command/cli/cloud-login.js +96 -8
  41. package/dist/command/cli/context-command.d.ts +1 -0
  42. package/dist/command/cli/context-command.js +33 -0
  43. package/dist/command/cli/daemon-start-options.d.ts +3 -0
  44. package/dist/command/cli/daemon-start-options.js +24 -3
  45. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
  46. package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
  47. package/dist/command/cli/doctor/doctor-coverage-line.d.ts +2 -0
  48. package/dist/command/cli/doctor/doctor-coverage-line.js +47 -0
  49. package/dist/command/cli/doctor/doctor-project-line.d.ts +0 -12
  50. package/dist/command/cli/doctor/doctor-project-line.js +5 -4
  51. package/dist/command/cli/doctor/doctor-rows.d.ts +6 -0
  52. package/dist/command/cli/doctor/doctor-rows.js +6 -0
  53. package/dist/command/cli/doctor/doctor-signing-line.d.ts +38 -0
  54. package/dist/command/cli/doctor/doctor-signing-line.js +114 -0
  55. package/dist/command/cli/drive/drive-attach.d.ts +27 -2
  56. package/dist/command/cli/drive/drive-attach.js +71 -4
  57. package/dist/command/cli/drive/drive-command.d.ts +2 -1
  58. package/dist/command/cli/drive/drive-command.js +13 -7
  59. package/dist/command/cli/known-regression.d.ts +13 -0
  60. package/dist/command/cli/known-regression.js +34 -0
  61. package/dist/command/cli/launch/sdk-version-match.d.ts +12 -0
  62. package/dist/command/cli/launch/sdk-version-match.js +25 -0
  63. package/dist/command/cli/lifecycle/daemon-lifecycle.js +15 -3
  64. package/dist/command/cli/mcp-command.d.ts +6 -0
  65. package/dist/command/cli/mcp-command.js +13 -5
  66. package/dist/command/cli/ports/port-holder.d.ts +10 -0
  67. package/dist/command/cli/ports/port-holder.js +25 -1
  68. package/dist/command/cli/project-name.d.ts +29 -1
  69. package/dist/command/cli/project-name.js +107 -2
  70. package/dist/command/cli/setup-mcp-cli.d.ts +17 -1
  71. package/dist/command/cli/setup-mcp-cli.js +35 -12
  72. package/dist/command/cli/status/status-lines.d.ts +1 -0
  73. package/dist/command/cli/status/status-lines.js +47 -2
  74. package/dist/command/cli/status/workspace-links.d.ts +10 -0
  75. package/dist/command/cli/status/workspace-links.js +29 -0
  76. package/dist/command/cli/try-command.d.ts +96 -0
  77. package/dist/command/cli/try-command.js +362 -0
  78. package/dist/command/cli/tutorial.d.ts +0 -100
  79. package/dist/command/cli/tutorial.js +0 -181
  80. package/dist/command/cli/verify-results.d.ts +19 -0
  81. package/dist/command/cli/verify-results.js +29 -0
  82. package/dist/command/cli-onboarding.d.ts +0 -11
  83. package/dist/command/cli-onboarding.js +0 -15
  84. package/dist/command/cli.d.ts +20 -0
  85. package/dist/command/cli.js +130 -104
  86. package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
  87. package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
  88. package/dist/command/daemon/daemon-resilience.js +4 -4
  89. package/dist/command/daemon/daemon-resolve.d.ts +23 -1
  90. package/dist/command/daemon/daemon-resolve.js +79 -9
  91. package/dist/command/setup/agent-writer.d.ts +1 -1
  92. package/dist/command/setup/agent-writer.js +3 -2
  93. package/dist/command/setup/bringup/bridge-port.d.ts +3 -1
  94. package/dist/command/setup/bringup/bridge-port.js +13 -3
  95. package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
  96. package/dist/command/setup/bringup/connect-lease.js +1 -0
  97. package/dist/command/setup/bringup/dev-server-log-cap.js +2 -0
  98. package/dist/command/setup/bringup/dev-server-wait.d.ts +8 -0
  99. package/dist/command/setup/bringup/dev-server-wait.js +19 -0
  100. package/dist/command/setup/bringup/ensure-daemon.js +9 -2
  101. package/dist/command/setup/init/agent-restart.d.ts +23 -0
  102. package/dist/command/setup/init/agent-restart.js +28 -0
  103. package/dist/command/setup/init/init-port.d.ts +14 -1
  104. package/dist/command/setup/init/init-port.js +32 -2
  105. package/dist/command/setup/init/init-runtime.d.ts +22 -2
  106. package/dist/command/setup/init/init-runtime.js +114 -38
  107. package/dist/command/setup/node-effects.d.ts +2 -0
  108. package/dist/command/setup/node-effects.js +38 -9
  109. package/dist/command/setup/probe/existing-app.d.ts +12 -0
  110. package/dist/command/setup/probe/existing-app.js +14 -0
  111. package/dist/command/setup/remaining-steps.js +2 -1
  112. package/dist/command/setup/run-setup.d.ts +34 -9
  113. package/dist/command/setup/run-setup.js +65 -51
  114. package/dist/command/setup/setup-command.d.ts +25 -1
  115. package/dist/command/setup/setup-command.js +59 -4
  116. package/dist/command/setup/setup-mcp.js +25 -2
  117. package/dist/command/setup/tauri-signing.d.ts +19 -0
  118. package/dist/command/setup/tauri-signing.js +79 -0
  119. package/dist/command/setup/terminal/listeners.d.ts +10 -1
  120. package/dist/command/setup/terminal/listeners.js +37 -6
  121. package/dist/command/update/update-nudge.d.ts +9 -0
  122. package/dist/command/update/update-nudge.js +1 -1
  123. package/dist/command/update/updater.js +11 -15
  124. package/dist/command/version/version-nudge.js +3 -0
  125. package/dist/command/version/version-skew.d.ts +20 -1
  126. package/dist/command/version/version-skew.js +49 -4
  127. package/dist/features/crawl/crawl-tools.js +4 -0
  128. package/dist/features/crawl/crawl.d.ts +6 -0
  129. package/dist/features/crawl/crawl.js +23 -2
  130. package/dist/features/exhaust/ledger.d.ts +21 -14
  131. package/dist/features/exhaust/ledger.js +35 -9
  132. package/dist/features/harness/app-findings.d.ts +2 -0
  133. package/dist/features/harness/app-findings.js +52 -0
  134. package/dist/features/harness/drive-report.d.ts +61 -1
  135. package/dist/features/harness/drive-report.js +394 -26
  136. package/dist/features/harness/drive-runs.d.ts +120 -0
  137. package/dist/features/harness/drive-runs.js +289 -0
  138. package/dist/features/harness/drivers.d.ts +10 -14
  139. package/dist/features/harness/drivers.js +10 -14
  140. package/dist/features/harness/explore/console-pages.d.ts +15 -0
  141. package/dist/features/harness/explore/console-pages.js +146 -0
  142. package/dist/features/harness/explore/disparity.d.ts +19 -0
  143. package/dist/features/harness/explore/disparity.js +71 -0
  144. package/dist/features/harness/explore/fake-app.d.ts +16 -0
  145. package/dist/features/harness/explore/fake-app.js +49 -0
  146. package/dist/features/harness/explore/goal-search.d.ts +26 -0
  147. package/dist/features/harness/explore/goal-search.js +144 -0
  148. package/dist/features/harness/explore/page-tree.d.ts +49 -0
  149. package/dist/features/harness/explore/page-tree.js +148 -0
  150. package/dist/features/harness/explore/site-map.d.ts +34 -0
  151. package/dist/features/harness/explore/site-map.js +150 -0
  152. package/dist/features/harness/fill-values.d.ts +3 -73
  153. package/dist/features/harness/fill-values.js +3 -169
  154. package/dist/features/harness/goals.d.ts +82 -0
  155. package/dist/features/harness/goals.js +330 -0
  156. package/dist/features/harness/harness.d.ts +51 -1
  157. package/dist/features/harness/harness.js +207 -6
  158. package/dist/features/harness/platform/drive-target.d.ts +30 -0
  159. package/dist/features/harness/platform/drive-target.js +81 -0
  160. package/dist/features/harness/platform/local-apps.d.ts +127 -0
  161. package/dist/features/harness/platform/local-apps.js +280 -0
  162. package/dist/features/harness/platform/persona-credentials.d.ts +20 -0
  163. package/dist/features/harness/platform/persona-credentials.js +69 -0
  164. package/dist/features/harness/platform/platform-drives.d.ts +61 -0
  165. package/dist/features/harness/platform/platform-drives.js +114 -0
  166. package/dist/features/harness/platform/refusal.d.ts +52 -0
  167. package/dist/features/harness/platform/refusal.js +71 -0
  168. package/dist/features/harness/platform/remote-drive.d.ts +186 -0
  169. package/dist/features/harness/platform/remote-drive.js +378 -0
  170. package/dist/features/harness/platform/script.d.ts +94 -0
  171. package/dist/features/harness/platform/script.js +260 -0
  172. package/dist/features/harness/platform/server-driver.d.ts +54 -0
  173. package/dist/features/harness/platform/server-driver.js +182 -0
  174. package/dist/features/harness/platform-config.d.ts +41 -1
  175. package/dist/features/harness/platform-config.js +106 -9
  176. package/dist/features/harness/route-guess.d.ts +13 -0
  177. package/dist/features/harness/route-guess.js +49 -0
  178. package/dist/features/harness/script/app-controls.d.ts +5 -0
  179. package/dist/features/harness/script/app-controls.js +40 -0
  180. package/dist/features/harness/script/lane-ids.d.ts +14 -0
  181. package/dist/features/harness/script/lane-ids.js +16 -0
  182. package/dist/features/harness/script/script-run.d.ts +70 -0
  183. package/dist/features/harness/script/script-run.js +606 -0
  184. package/dist/features/license/license.d.ts +2 -2
  185. package/dist/features/visual/step-shots.d.ts +31 -0
  186. package/dist/features/visual/step-shots.js +231 -0
  187. package/dist/features/visual/visual-tools.d.ts +10 -1
  188. package/dist/features/visual/visual-tools.js +62 -17
  189. package/dist/hooks/client-directory.d.ts +18 -0
  190. package/dist/hooks/client-directory.js +57 -0
  191. package/dist/hooks/coding-agents.d.ts +34 -0
  192. package/dist/hooks/coding-agents.js +117 -0
  193. package/dist/hooks/driven-by.d.ts +23 -0
  194. package/dist/hooks/driven-by.js +56 -0
  195. package/dist/hooks/hook-bus.d.ts +4 -0
  196. package/dist/hooks/hook-bus.js +18 -0
  197. package/dist/hooks/hook-commands.js +15 -4
  198. package/dist/hooks/tool-log.d.ts +9 -0
  199. package/dist/hooks/tool-log.js +29 -0
  200. package/dist/index.d.ts +2 -0
  201. package/dist/index.js +80 -243
  202. package/dist/judgement/capsule/capsule-store.d.ts +2 -2
  203. package/dist/judgement/capsule/causal-summary.d.ts +15 -1
  204. package/dist/judgement/capsule/causal-summary.js +33 -0
  205. package/dist/judgement/runs/artifact/build-verification-run.d.ts +1 -1
  206. package/dist/judgement/runs/artifact/build-verification-run.js +25 -3
  207. package/dist/judgement/runs/artifact/gap-summary.d.ts +0 -18
  208. package/dist/judgement/runs/artifact/gap-summary.js +12 -3
  209. package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
  210. package/dist/judgement/runs/artifact/replay-mapping.js +37 -11
  211. package/dist/judgement/runs/artifact/run-store.d.ts +14 -2
  212. package/dist/judgement/runs/artifact/run-store.js +195 -3
  213. package/dist/judgement/runs/context-tools.js +59 -1
  214. package/dist/judgement/runs/default-run-id.d.ts +3 -0
  215. package/dist/judgement/runs/default-run-id.js +16 -0
  216. package/dist/judgement/runs/drive-run.d.ts +71 -1
  217. package/dist/judgement/runs/drive-run.js +317 -5
  218. package/dist/judgement/runs/repair-prompt.js +1 -1
  219. package/dist/judgement/runs/resume.d.ts +44 -0
  220. package/dist/judgement/runs/resume.js +137 -0
  221. package/dist/judgement/runs/reticle-runner.js +13 -3
  222. package/dist/judgement/runs/runner-port.d.ts +5 -1
  223. package/dist/judgement/runs/runner-port.js +8 -2
  224. package/dist/judgement/runs/verification-sync.d.ts +5 -2
  225. package/dist/judgement/runs/verification-sync.js +40 -18
  226. package/dist/language/flows/change/gate.d.ts +10 -0
  227. package/dist/language/flows/change/gate.js +22 -0
  228. package/dist/language/flows/decision.js +36 -1
  229. package/dist/language/flows/fields/flow-secret-field.d.ts +12 -0
  230. package/dist/language/flows/fields/flow-secret-field.js +25 -2
  231. package/dist/language/flows/flow-anchor.d.ts +61 -10
  232. package/dist/language/flows/flow-anchor.js +98 -6
  233. package/dist/language/flows/flow-cross-step.d.ts +15 -0
  234. package/dist/language/flows/flow-cross-step.js +21 -0
  235. package/dist/language/flows/flow-intent.d.ts +1 -0
  236. package/dist/language/flows/flow-journey.d.ts +6 -0
  237. package/dist/language/flows/flow-journey.js +20 -0
  238. package/dist/language/flows/flow-learning.d.ts +4 -0
  239. package/dist/language/flows/flow-learning.js +45 -14
  240. package/dist/language/flows/flow-mutate-tools.js +5 -3
  241. package/dist/language/flows/flow-replay-run.d.ts +23 -9
  242. package/dist/language/flows/flow-replay-run.js +115 -110
  243. package/dist/language/flows/flow-replay-types.d.ts +1 -1
  244. package/dist/language/flows/flow-replay.d.ts +40 -1
  245. package/dist/language/flows/flow-replay.js +110 -22
  246. package/dist/language/flows/flow-result.d.ts +22 -1
  247. package/dist/language/flows/flow-result.js +47 -2
  248. package/dist/language/flows/flow-scope.js +5 -1
  249. package/dist/language/flows/flow-step-runners.d.ts +22 -2
  250. package/dist/language/flows/flow-step-runners.js +247 -47
  251. package/dist/language/flows/flow-store-for-session.d.ts +2 -2
  252. package/dist/language/flows/flow-store-for-session.js +7 -3
  253. package/dist/language/flows/flow-tools.d.ts +10 -0
  254. package/dist/language/flows/flow-tools.js +112 -89
  255. package/dist/language/flows/flows.d.ts +16 -1
  256. package/dist/language/flows/flows.js +74 -12
  257. package/dist/language/flows/heal-run.js +6 -4
  258. package/dist/language/flows/narrow-write.d.ts +7 -0
  259. package/dist/language/flows/narrow-write.js +36 -1
  260. package/dist/language/flows/recording/flake.d.ts +2 -2
  261. package/dist/language/flows/recording/recording-backtrack.js +14 -1
  262. package/dist/language/flows/recording/tape/recordings.d.ts +58 -4
  263. package/dist/language/flows/recording/tape/recordings.js +95 -13
  264. package/dist/language/flows/replay-from-hud.d.ts +20 -0
  265. package/dist/language/flows/replay-from-hud.js +51 -0
  266. package/dist/language/flows/replay.d.ts +9 -5
  267. package/dist/language/flows/replay.js +56 -15
  268. package/dist/language/flows/single-replay.d.ts +7 -0
  269. package/dist/language/flows/single-replay.js +26 -0
  270. package/dist/language/flows/suite/suite-flakes.js +2 -0
  271. package/dist/language/flows/suite-selection.d.ts +2 -15
  272. package/dist/language/flows/suite-selection.js +4 -3
  273. package/dist/language/flows/verify-change-tools.d.ts +1 -0
  274. package/dist/language/flows/verify-change-tools.js +202 -191
  275. package/dist/launch-chromium.d.ts +27 -5
  276. package/dist/launch-chromium.js +38 -8
  277. package/dist/memory/cloud/cloud-config.d.ts +22 -1
  278. package/dist/memory/cloud/cloud-config.js +34 -5
  279. package/dist/memory/cloud/cloud-sync.d.ts +17 -14
  280. package/dist/memory/cloud/cloud-sync.js +15 -4
  281. package/dist/memory/cloud/harness-config.d.ts +75 -1
  282. package/dist/memory/cloud/harness-config.js +115 -24
  283. package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
  284. package/dist/memory/cloud/hud-notices-source.js +128 -0
  285. package/dist/memory/cloud/memory-scope.d.ts +161 -0
  286. package/dist/memory/cloud/memory-scope.js +227 -0
  287. package/dist/memory/cloud/sync-cycle.d.ts +44 -7
  288. package/dist/memory/cloud/sync-cycle.js +129 -15
  289. package/dist/memory/cloud/sync-daemon.d.ts +11 -0
  290. package/dist/memory/cloud/sync-daemon.js +121 -9
  291. package/dist/memory/cloud/sync-disk.d.ts +1 -1
  292. package/dist/memory/cloud/sync-disk.js +31 -10
  293. package/dist/memory/cloud/sync-screenshots.d.ts +32 -0
  294. package/dist/memory/cloud/sync-screenshots.js +105 -0
  295. package/dist/memory/cloud/unsynced-roots.d.ts +47 -0
  296. package/dist/memory/cloud/unsynced-roots.js +166 -0
  297. package/dist/memory/impact/account-watch.d.ts +34 -0
  298. package/dist/memory/impact/account-watch.js +59 -0
  299. package/dist/memory/impact/impact-recorder.d.ts +8 -0
  300. package/dist/memory/impact/impact-recorder.js +12 -2
  301. package/dist/memory/impact/impact-store.d.ts +17 -4
  302. package/dist/memory/impact/impact-store.js +169 -63
  303. package/dist/memory/intent/inline-intent.d.ts +1 -0
  304. package/dist/memory/intent/intent-shard-store.js +16 -4
  305. package/dist/memory/intent/intent-shard.d.ts +14 -2
  306. package/dist/memory/intent/intent-store.d.ts +1 -0
  307. package/dist/memory/intent/intent-tools.js +122 -4
  308. package/dist/memory/intent/open-intents.d.ts +6 -0
  309. package/dist/memory/intent/open-intents.js +10 -1
  310. package/dist/memory/intent/settled-words.d.ts +24 -0
  311. package/dist/memory/intent/settled-words.js +130 -0
  312. package/dist/memory/journal/drive-flow.d.ts +16 -0
  313. package/dist/memory/journal/drive-flow.js +34 -2
  314. package/dist/memory/journal/drive-run-flush.d.ts +2 -0
  315. package/dist/memory/journal/drive-run-flush.js +20 -5
  316. package/dist/memory/journal/envelope.d.ts +8 -8
  317. package/dist/memory/journal/journal-recorder.js +52 -3
  318. package/dist/memory/journal/on-disk/retention.d.ts +8 -0
  319. package/dist/memory/journal/on-disk/retention.js +32 -2
  320. package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
  321. package/dist/memory/journal/on-disk/workspace-tiers.js +9 -4
  322. package/dist/memory/journal/session-end.d.ts +15 -1
  323. package/dist/memory/journal/session-end.js +42 -9
  324. package/dist/memory/project/artifact-root-resolver.d.ts +26 -1
  325. package/dist/memory/project/artifact-root-resolver.js +125 -16
  326. package/dist/memory/project/artifact-root.d.ts +46 -8
  327. package/dist/memory/project/artifact-root.js +89 -10
  328. package/dist/memory/project/dir/reticle-dir.d.ts +18 -2
  329. package/dist/memory/project/dir/reticle-dir.js +26 -3
  330. package/dist/memory/project/link-directory.d.ts +15 -0
  331. package/dist/memory/project/link-directory.js +44 -0
  332. package/dist/memory/project/project-tools.js +22 -3
  333. package/dist/memory/project/root-claims.d.ts +6 -0
  334. package/dist/memory/project/root-claims.js +39 -0
  335. package/dist/memory/project/session-root.d.ts +26 -1
  336. package/dist/memory/project/session-root.js +49 -5
  337. package/dist/memory/project/sync-status.d.ts +85 -0
  338. package/dist/memory/project/sync-status.js +224 -0
  339. package/dist/memory/recall/memory-tools.js +47 -2
  340. package/dist/memory/recall/platform-memory.d.ts +34 -0
  341. package/dist/memory/recall/platform-memory.js +139 -0
  342. package/dist/memory/recall/project-memory.d.ts +19 -0
  343. package/dist/memory/recall/project-memory.js +80 -13
  344. package/dist/portal/bridge/bridge.d.ts +9 -3
  345. package/dist/portal/bridge/bridge.js +82 -22
  346. package/dist/portal/bridge/harness-request.d.ts +23 -0
  347. package/dist/portal/bridge/harness-request.js +27 -0
  348. package/dist/portal/bridge/pairing-token.d.ts +9 -0
  349. package/dist/portal/bridge/pairing-token.js +17 -0
  350. package/dist/portal/bridge/wrong-path.d.ts +17 -0
  351. package/dist/portal/bridge/wrong-path.js +35 -0
  352. package/dist/portal/input/network-mock-tools.js +11 -2
  353. package/dist/portal/input/real-input.d.ts +83 -10
  354. package/dist/portal/input/real-input.js +218 -30
  355. package/dist/portal/input/viewport-tools.js +3 -3
  356. package/dist/portal/pool/browser-pool.d.ts +70 -9
  357. package/dist/portal/pool/browser-pool.js +190 -37
  358. package/dist/portal/pool/context-permissions.d.ts +33 -0
  359. package/dist/portal/pool/context-permissions.js +33 -0
  360. package/dist/portal/pool/lease-marker-stamp.d.ts +23 -0
  361. package/dist/portal/pool/lease-marker-stamp.js +49 -0
  362. package/dist/portal/pool/playwright-launcher.d.ts +35 -0
  363. package/dist/portal/pool/playwright-launcher.js +64 -3
  364. package/dist/portal/pool/pool-contract.d.ts +28 -5
  365. package/dist/portal/session/agent-link.d.ts +8 -0
  366. package/dist/portal/session/agent-link.js +17 -0
  367. package/dist/portal/session/command-payload.d.ts +8 -0
  368. package/dist/portal/session/command-payload.js +24 -0
  369. package/dist/portal/session/daemon-answers.d.ts +3 -3
  370. package/dist/portal/session/daemon-answers.js +4 -2
  371. package/dist/portal/session/dev-server/dev-command.d.ts +21 -0
  372. package/dist/portal/session/dev-server/dev-command.js +87 -12
  373. package/dist/portal/session/facts/departure-note.d.ts +22 -0
  374. package/dist/portal/session/facts/departure-note.js +47 -0
  375. package/dist/portal/session/facts/observed-state.d.ts +16 -18
  376. package/dist/portal/session/facts/observed-state.js +46 -3
  377. package/dist/portal/session/facts/session-replaced.d.ts +5 -0
  378. package/dist/portal/session/facts/session-replaced.js +5 -0
  379. package/dist/portal/session/first-run-wiring.d.ts +42 -0
  380. package/dist/portal/session/first-run-wiring.js +132 -0
  381. package/dist/portal/session/human/live-control.d.ts +9 -2
  382. package/dist/portal/session/human/live-control.js +12 -3
  383. package/dist/portal/session/human/notes-ledger.d.ts +20 -0
  384. package/dist/portal/session/human/notes-ledger.js +55 -0
  385. package/dist/portal/session/human/review-store.d.ts +12 -0
  386. package/dist/portal/session/human/review-store.js +18 -10
  387. package/dist/portal/session/live-control-tools.d.ts +0 -13
  388. package/dist/portal/session/live-control-tools.js +107 -13
  389. package/dist/portal/session/narration-args.d.ts +5 -0
  390. package/dist/portal/session/narration-args.js +17 -0
  391. package/dist/portal/session/no-session-diagnosis.d.ts +8 -1
  392. package/dist/portal/session/no-session-diagnosis.js +46 -9
  393. package/dist/portal/session/no-session-next-action.d.ts +31 -0
  394. package/dist/portal/session/no-session-next-action.js +159 -60
  395. package/dist/portal/session/no-session-watch.d.ts +14 -1
  396. package/dist/portal/session/no-session-watch.js +227 -17
  397. package/dist/portal/session/presence/session-lease.js +1 -1
  398. package/dist/portal/session/presence/session-mirror.js +3 -0
  399. package/dist/portal/session/recorded-gaps.d.ts +97 -0
  400. package/dist/portal/session/recorded-gaps.js +251 -0
  401. package/dist/portal/session/serving-directory.d.ts +27 -0
  402. package/dist/portal/session/serving-directory.js +45 -0
  403. package/dist/portal/session/session-health.d.ts +18 -0
  404. package/dist/portal/session/session-health.js +9 -1
  405. package/dist/portal/session/session-info.d.ts +8 -1
  406. package/dist/portal/session/session-info.js +8 -1
  407. package/dist/portal/session/session-manager.d.ts +39 -0
  408. package/dist/portal/session/session-manager.js +98 -11
  409. package/dist/portal/session/session-reaper.js +4 -1
  410. package/dist/portal/session/session-successor.d.ts +13 -0
  411. package/dist/portal/session/session-successor.js +1 -1
  412. package/dist/portal/session/session-tools.js +26 -3
  413. package/dist/portal/session/session.d.ts +22 -30
  414. package/dist/portal/session/session.js +81 -79
  415. package/dist/portal/session/timing/command-timeout.js +25 -1
  416. package/dist/portal/session/timing/wall-clock.d.ts +1 -1
  417. package/dist/portal/session/timing/wall-clock.js +1 -1
  418. package/dist/portal/session/zero-install-first-call.d.ts +31 -0
  419. package/dist/portal/session/zero-install-first-call.js +88 -0
  420. package/dist/start-options.d.ts +12 -0
  421. package/dist/start-wiring.d.ts +63 -0
  422. package/dist/start-wiring.js +169 -0
  423. package/dist/status-payload.d.ts +23 -1
  424. package/dist/status-payload.js +36 -1
  425. package/dist/surface/http-server.js +18 -2
  426. package/dist/surface/mcp/attach-memory.d.ts +1 -0
  427. package/dist/surface/mcp/attach-memory.js +12 -1
  428. package/dist/surface/mcp/mcp-proxy.d.ts +9 -0
  429. package/dist/surface/mcp/mcp-proxy.js +65 -13
  430. package/dist/surface/mcp/mcp.d.ts +34 -6
  431. package/dist/surface/mcp/mcp.js +61 -17
  432. package/dist/surface/mcp/proxy/drive-calls.d.ts +10 -0
  433. package/dist/surface/mcp/proxy/drive-calls.js +27 -0
  434. package/dist/surface/mcp/proxy/mcp-post-transport.js +5 -0
  435. package/dist/surface/mcp/server-instructions.d.ts +4 -2
  436. package/dist/surface/mcp/server-instructions.js +32 -14
  437. package/dist/surface/mcp/shared-params.js +2 -2
  438. package/dist/surface/mcp/surface-vocabulary.d.ts +2 -0
  439. package/dist/surface/mcp/surface-vocabulary.js +1 -0
  440. package/dist/surface/tools/account-tool.d.ts +22 -0
  441. package/dist/surface/tools/account-tool.js +157 -0
  442. package/dist/surface/tools/act/act-danger.d.ts +11 -0
  443. package/dist/surface/tools/act/act-danger.js +38 -1
  444. package/dist/surface/tools/act/act-observation.d.ts +33 -0
  445. package/dist/surface/tools/act/act-observation.js +57 -0
  446. package/dist/surface/tools/act/act-preflight.js +25 -2
  447. package/dist/surface/tools/act/act-target.js +8 -3
  448. package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
  449. package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
  450. package/dist/surface/tools/act/resolve-target.d.ts +1 -1
  451. package/dist/surface/tools/act/resolve-target.js +18 -3
  452. package/dist/surface/tools/act/screen-request.d.ts +34 -0
  453. package/dist/surface/tools/act/screen-request.js +113 -0
  454. package/dist/surface/tools/act/sequence-grade.d.ts +8 -0
  455. package/dist/surface/tools/act/sequence-grade.js +13 -2
  456. package/dist/surface/tools/act/settle-in-flight.js +25 -3
  457. package/dist/surface/tools/act-sequence-tool.js +138 -29
  458. package/dist/surface/tools/act-tools.d.ts +0 -9
  459. package/dist/surface/tools/act-tools.js +71 -41
  460. package/dist/surface/tools/agent/app-notes-learning.d.ts +7 -0
  461. package/dist/surface/tools/agent/app-notes-learning.js +80 -0
  462. package/dist/surface/tools/agent/app-notes.d.ts +4 -0
  463. package/dist/surface/tools/agent/app-notes.js +48 -0
  464. package/dist/surface/tools/agent/build-staleness.d.ts +7 -0
  465. package/dist/surface/tools/agent/build-staleness.js +62 -0
  466. package/dist/surface/tools/agent/compact-envelope.d.ts +80 -0
  467. package/dist/surface/tools/agent/compact-envelope.js +374 -0
  468. package/dist/surface/tools/agent/for-the-agent.d.ts +12 -0
  469. package/dist/surface/tools/agent/for-the-agent.js +44 -0
  470. package/dist/surface/tools/agent/notices.d.ts +50 -0
  471. package/dist/surface/tools/agent/notices.js +152 -0
  472. package/dist/surface/tools/agent/reteach.d.ts +11 -0
  473. package/dist/surface/tools/agent/reteach.js +50 -0
  474. package/dist/surface/tools/args/alias-args.d.ts +5 -0
  475. package/dist/surface/tools/args/alias-args.js +10 -0
  476. package/dist/surface/tools/args/confirm-dangerous-arg.d.ts +6 -0
  477. package/dist/surface/tools/args/confirm-dangerous-arg.js +6 -0
  478. package/dist/surface/tools/assert/assert-source.d.ts +15 -0
  479. package/dist/surface/tools/assert/assert-source.js +40 -0
  480. package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
  481. package/dist/surface/tools/assert/assert-verdict.js +42 -17
  482. package/dist/surface/tools/browser-tools.js +51 -2
  483. package/dist/surface/tools/chat-drives.d.ts +101 -0
  484. package/dist/surface/tools/chat-drives.js +409 -0
  485. package/dist/surface/tools/coverage-tools.d.ts +2 -10
  486. package/dist/surface/tools/coverage-tools.js +2 -53
  487. package/dist/surface/tools/dynamic-tools.js +29 -1
  488. package/dist/surface/tools/empty-session-list.d.ts +51 -0
  489. package/dist/surface/tools/empty-session-list.js +120 -0
  490. package/dist/surface/tools/error-recovery.d.ts +14 -0
  491. package/dist/surface/tools/error-recovery.js +105 -8
  492. package/dist/surface/tools/explore-tools.d.ts +31 -1
  493. package/dist/surface/tools/explore-tools.js +438 -66
  494. package/dist/surface/tools/feedback-tools.d.ts +2 -3
  495. package/dist/surface/tools/feedback-tools.js +18 -3
  496. package/dist/surface/tools/gap-novelty.d.ts +3 -1
  497. package/dist/surface/tools/gap-novelty.js +8 -1
  498. package/dist/surface/tools/harness-explore.d.ts +118 -57
  499. package/dist/surface/tools/harness-explore.js +344 -292
  500. package/dist/surface/tools/harness-gate.d.ts +88 -0
  501. package/dist/surface/tools/harness-gate.js +235 -0
  502. package/dist/surface/tools/harness-hunt.d.ts +43 -0
  503. package/dist/surface/tools/harness-hunt.js +215 -0
  504. package/dist/surface/tools/harness-plan.d.ts +17 -0
  505. package/dist/surface/tools/harness-plan.js +38 -0
  506. package/dist/surface/tools/harness-script.d.ts +30 -0
  507. package/dist/surface/tools/harness-script.js +560 -0
  508. package/dist/surface/tools/harness-tab-guard.d.ts +5 -0
  509. package/dist/surface/tools/harness-tab-guard.js +27 -0
  510. package/dist/surface/tools/harness-toolset.d.ts +22 -1
  511. package/dist/surface/tools/harness-toolset.js +101 -7
  512. package/dist/surface/tools/human-notes.d.ts +16 -0
  513. package/dist/surface/tools/human-notes.js +27 -0
  514. package/dist/surface/tools/invoke-tool.d.ts +5 -2
  515. package/dist/surface/tools/invoke-tool.js +263 -85
  516. package/dist/surface/tools/lease-hint.js +26 -5
  517. package/dist/surface/tools/lease-permissions.d.ts +33 -0
  518. package/dist/surface/tools/lease-permissions.js +73 -0
  519. package/dist/surface/tools/lease-readiness.d.ts +38 -0
  520. package/dist/surface/tools/lease-readiness.js +57 -0
  521. package/dist/surface/tools/lease-seed.d.ts +49 -0
  522. package/dist/surface/tools/lease-seed.js +167 -0
  523. package/dist/surface/tools/lease-tools.d.ts +13 -24
  524. package/dist/surface/tools/lease-tools.js +146 -197
  525. package/dist/surface/tools/live-call-text.js +4 -4
  526. package/dist/surface/tools/merge-tools.js +42 -2
  527. package/dist/surface/tools/merged-name-redirect.js +4 -0
  528. package/dist/surface/tools/next-step.d.ts +29 -0
  529. package/dist/surface/tools/next-step.js +214 -0
  530. package/dist/surface/tools/observe-tools.js +45 -9
  531. package/dist/surface/tools/platform-moment.d.ts +72 -0
  532. package/dist/surface/tools/platform-moment.js +296 -0
  533. package/dist/surface/tools/query-hint-schema.d.ts +7 -0
  534. package/dist/surface/tools/query-hint-schema.js +10 -0
  535. package/dist/surface/tools/read-tools.js +71 -14
  536. package/dist/surface/tools/real-input-attempt.js +96 -13
  537. package/dist/surface/tools/reticle-result.d.ts +120 -0
  538. package/dist/surface/tools/reticle-result.js +364 -0
  539. package/dist/surface/tools/tool-kit.d.ts +83 -3
  540. package/dist/surface/tools/tool-kit.js +77 -7
  541. package/dist/surface/tools/tools.js +43 -59
  542. package/dist/telemetry/account-envelope.d.ts +7 -0
  543. package/dist/telemetry/account-envelope.js +61 -0
  544. package/dist/telemetry/agent-client.d.ts +15 -0
  545. package/dist/telemetry/agent-client.js +57 -0
  546. package/dist/telemetry/app-instrumented.js +9 -2
  547. package/dist/telemetry/argument-shape.d.ts +7 -0
  548. package/dist/telemetry/argument-shape.js +86 -1
  549. package/dist/telemetry/automation-hint.d.ts +2 -3
  550. package/dist/telemetry/automation-hint.js +33 -8
  551. package/dist/telemetry/cli-telemetry.js +7 -2
  552. package/dist/telemetry/daemon-telemetry.js +3 -0
  553. package/dist/telemetry/error-fingerprint.d.ts +10 -1
  554. package/dist/telemetry/error-fingerprint.js +61 -5
  555. package/dist/telemetry/feedback-cli.d.ts +0 -13
  556. package/dist/telemetry/feedback-cli.js +0 -77
  557. package/dist/telemetry/feedback.d.ts +13 -0
  558. package/dist/telemetry/feedback.js +183 -17
  559. package/dist/telemetry/harness-run.d.ts +18 -0
  560. package/dist/telemetry/harness-run.js +80 -0
  561. package/dist/telemetry/hud-events.d.ts +16 -0
  562. package/dist/telemetry/hud-events.js +27 -0
  563. package/dist/telemetry/hud-metrics.d.ts +29 -6
  564. package/dist/telemetry/hud-metrics.js +116 -25
  565. package/dist/telemetry/init-telemetry.js +2 -2
  566. package/dist/telemetry/install-source.d.ts +13 -25
  567. package/dist/telemetry/install-source.js +44 -3
  568. package/dist/telemetry/mcp-connection.d.ts +0 -14
  569. package/dist/telemetry/mcp-connection.js +5 -1
  570. package/dist/telemetry/onboarding-firsts.d.ts +32 -0
  571. package/dist/telemetry/onboarding-firsts.js +81 -6
  572. package/dist/telemetry/platform-linked.d.ts +5 -0
  573. package/dist/telemetry/platform-linked.js +32 -0
  574. package/dist/telemetry/project-profile.js +5 -3
  575. package/dist/telemetry/proxy-telemetry.js +4 -1
  576. package/dist/telemetry/session-metrics.d.ts +15 -4
  577. package/dist/telemetry/session-metrics.js +88 -52
  578. package/dist/telemetry/telemetry.d.ts +38 -2
  579. package/dist/telemetry/telemetry.js +144 -34
  580. package/dist/telemetry/verification-of.d.ts +3 -1
  581. package/dist/telemetry/verification-of.js +13 -4
  582. package/dist/wire-journal.d.ts +2 -2
  583. package/dist/wire-journal.js +20 -6
  584. package/docs/README.md +3 -3
  585. package/docs/actions.mdx +6 -3
  586. package/docs/adapters.md +1 -1
  587. package/docs/agent-cheatsheet.md +25 -28
  588. package/docs/architecture.md +5 -5
  589. package/docs/autodrive.md +33 -28
  590. package/docs/benchmarks.md +5 -5
  591. package/docs/best-practices.mdx +27 -9
  592. package/docs/capabilities.mdx +14 -16
  593. package/docs/cli/affected.mdx +1 -1
  594. package/docs/cli/cloud.mdx +54 -75
  595. package/docs/cli/doctor.mdx +14 -3
  596. package/docs/cli/drive.mdx +20 -14
  597. package/docs/cli/feedback.mdx +3 -3
  598. package/docs/cli/gate.mdx +7 -2
  599. package/docs/cli/help.mdx +50 -55
  600. package/docs/cli/init.mdx +43 -28
  601. package/docs/cli/license.mdx +12 -8
  602. package/docs/cli/mcp.mdx +4 -4
  603. package/docs/cli/open.mdx +3 -3
  604. package/docs/cli/report.mdx +4 -2
  605. package/docs/cli/restart.mdx +2 -2
  606. package/docs/cli/rollback.mdx +14 -8
  607. package/docs/cli/serve.mdx +4 -4
  608. package/docs/cli/setup.mdx +23 -0
  609. package/docs/cli/status.mdx +18 -5
  610. package/docs/cli/stop.mdx +67 -8
  611. package/docs/cli/try.mdx +62 -0
  612. package/docs/cli/update.mdx +4 -3
  613. package/docs/cli/verify.mdx +17 -6
  614. package/docs/cli/version.mdx +5 -4
  615. package/docs/cli.mdx +111 -42
  616. package/docs/debugging.md +3 -3
  617. package/docs/deploy-checks.md +1 -1
  618. package/docs/desktop.mdx +9 -3
  619. package/docs/enterprise.md +11 -10
  620. package/docs/environment.mdx +7 -8
  621. package/docs/faq.mdx +3 -3
  622. package/docs/first-drive.md +5 -4
  623. package/docs/flows.md +35 -27
  624. package/docs/for-agents.md +4 -5
  625. package/docs/frameworks.mdx +32 -21
  626. package/docs/getting-started.md +65 -61
  627. package/docs/human-control.md +16 -16
  628. package/docs/index.mdx +15 -42
  629. package/docs/install-agentic.mdx +22 -37
  630. package/docs/install-manual.mdx +23 -13
  631. package/docs/instrumentation.mdx +5 -3
  632. package/docs/integration-patterns.md +7 -7
  633. package/docs/license-activation.mdx +1 -1
  634. package/docs/multi-agent-testing.md +24 -6
  635. package/docs/packages/babel-plugin.mdx +4 -2
  636. package/docs/packages/browser.mdx +16 -10
  637. package/docs/packages/core.mdx +12 -5
  638. package/docs/packages/electron.mdx +3 -2
  639. package/docs/packages/engine.mdx +1 -1
  640. package/docs/packages/eslint-plugin.mdx +18 -12
  641. package/docs/packages/next.mdx +8 -7
  642. package/docs/packages/open-verification.mdx +1 -1
  643. package/docs/packages/server.mdx +5 -5
  644. package/docs/packages/tauri.mdx +9 -9
  645. package/docs/packages/test.mdx +4 -10
  646. package/docs/packages/vite-plugin.mdx +32 -4
  647. package/docs/packages.mdx +11 -15
  648. package/docs/platform-integration.md +6 -5
  649. package/docs/predicates.mdx +40 -24
  650. package/docs/quickstart.mdx +69 -30
  651. package/docs/required-checks.md +8 -7
  652. package/docs/reticle-manual.md +15 -5
  653. package/docs/skill-file.mdx +17 -79
  654. package/docs/skill-setup.md +9 -9
  655. package/docs/skill.md +200 -0
  656. package/docs/system-map.md +7 -7
  657. package/docs/telemetry.md +23 -25
  658. package/docs/testing.md +4 -4
  659. package/docs/token-efficiency.md +12 -12
  660. package/docs/tools/act-and-wait.mdx +9 -2
  661. package/docs/tools/act-sequence.mdx +6 -7
  662. package/docs/tools/act.mdx +2 -2
  663. package/docs/tools/assert.mdx +18 -17
  664. package/docs/tools/console.mdx +9 -9
  665. package/docs/tools/inspect.mdx +16 -7
  666. package/docs/tools/look.mdx +24 -0
  667. package/docs/tools/navigate.mdx +5 -3
  668. package/docs/tools/network.mdx +2 -2
  669. package/docs/tools/observe.mdx +6 -6
  670. package/docs/tools/overview.mdx +34 -33
  671. package/docs/tools/query.mdx +5 -5
  672. package/docs/tools/session-and-feedback.mdx +22 -13
  673. package/docs/tools/sessions.mdx +8 -8
  674. package/docs/tools/snapshot.mdx +6 -5
  675. package/docs/tools/state.mdx +9 -9
  676. package/docs/tools/tools-and-run.mdx +26 -24
  677. package/docs/tools/verify.mdx +28 -0
  678. package/docs/tools/wait-for.mdx +8 -4
  679. package/docs/troubleshooting.mdx +21 -6
  680. package/docs/usage.md +55 -46
  681. package/docs/use-cases.mdx +3 -3
  682. package/docs/vs-chrome-devtools-mcp.mdx +9 -6
  683. package/docs/vs-playwright-mcp.mdx +3 -1
  684. package/docs/what-is-recorded.md +17 -5
  685. package/docs/what-is-reticle.mdx +5 -3
  686. package/docs/why-reticle.mdx +1 -1
  687. package/package.json +9 -12
  688. package/dist/command/cli/demo/demo-page.d.ts +0 -78
  689. package/dist/command/cli/demo/demo-page.js +0 -241
  690. package/dist/command/cli/demo/demo-run.d.ts +0 -38
  691. package/dist/command/cli/demo/demo-run.js +0 -138
  692. package/dist/features/harness/driver.d.ts +0 -50
  693. package/dist/features/harness/driver.js +0 -236
  694. package/dist/features/harness/jev-driver.d.ts +0 -188
  695. package/dist/features/harness/jev-driver.js +0 -678
  696. package/dist/features/harness/openai-driver.d.ts +0 -58
  697. package/dist/features/harness/openai-driver.js +0 -206
  698. package/dist/judgement/hunt/hunt-report.d.ts +0 -49
  699. package/dist/judgement/hunt/hunt-report.js +0 -84
  700. package/dist/language/flows/buddy-status.d.ts +0 -25
  701. package/dist/language/flows/buddy-status.js +0 -32
  702. package/dist/language/flows/change/watch-batcher.d.ts +0 -18
  703. package/dist/language/flows/change/watch-batcher.js +0 -19
  704. package/dist/memory/cloud/harness-offer.d.ts +0 -44
  705. package/dist/memory/cloud/harness-offer.js +0 -145
  706. package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
  707. package/dist/memory/project/dir/fill-value-store.js +0 -88
  708. package/dist/surface/tools/feature-capture.d.ts +0 -151
  709. package/dist/surface/tools/feature-capture.js +0 -235
  710. package/dist/surface/tools/tool-hit-rate.d.ts +0 -87
  711. package/dist/surface/tools/tool-hit-rate.js +0 -90
  712. package/dist/telemetry/harness-drive.d.ts +0 -4
  713. package/dist/telemetry/harness-drive.js +0 -35
  714. package/dist/telemetry/identify.d.ts +0 -22
  715. package/dist/telemetry/identify.js +0 -73
  716. package/docs/cli/capsules.mdx +0 -70
  717. package/docs/cli/hunt.mdx +0 -73
  718. package/docs/cli/identify.mdx +0 -76
  719. package/docs/cli/kill.mdx +0 -91
  720. package/docs/cli/watch.mdx +0 -62
  721. package/docs/local-registry.md +0 -143
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ import { PlatformLinkVia } from '@reticlehq/core/telemetry';
3
+ import { hudSignIn } from './cli/cloud-login.js';
2
4
  import { handleSetupMcp, handleSetupInstall } from './cli/setup-mcp-cli.js';
3
- import { reportStepFromCli, reportTutorialShown } from './cli-onboarding.js';
4
- import { runDemoTour } from './cli/demo/demo-run.js';
5
- import { renderTutorial } from './cli/tutorial.js';
5
+ import { reportStepFromCli } from './cli-onboarding.js';
6
6
  import { pathToFileURL } from 'node:url';
7
- import { openFailureNote } from './cli/answers/open-note.js';
7
+ import { openFailureNote, openLaunchFailureNote } from './cli/answers/open-note.js';
8
8
  import { realpathSync } from 'node:fs';
9
9
  import { join } from 'node:path';
10
10
  import { installCrashGuard } from './setup/setup-command.js';
@@ -15,21 +15,24 @@ import { splitBrainFields, withNextAction } from './cli/status-fields.js';
15
15
  import { reticleStateHome } from './daemon/daemon.js';
16
16
  import { handleMcp } from './cli/mcp-command.js';
17
17
  import { handleReport } from './cli/report-command.js';
18
- import { daemonProjectAt, resolveDaemonForProject } from './daemon/daemon-resolve.js';
18
+ import { handleContext } from './cli/context-command.js';
19
+ import { daemonProjectAt, readDaemonRegistry, resolveDaemonForProject, } from './daemon/daemon-resolve.js';
19
20
  import { pickDaemonPortToBind } from './daemon/binding/free-port.js';
20
- import { portForInit, portFromEnv } from './setup/init/init-port.js';
21
+ import { isSameOrAbove, portForInit, portFromEnv } from './setup/init/init-port.js';
21
22
  import { daemonStartOptions } from './cli/daemon-start-options.js';
22
- import { handleWatch, handleCapsules, handleGate, loadNamedFlows, resolveChangedFiles, } from './cli/cli-flow-commands.js';
23
+ import { handleGate, loadNamedFlows, resolveChangedFiles } from './cli/cli-flow-commands.js';
23
24
  import { RETICLE_DEFAULT_PORT, ReticleDir, ReticleEnv, devServersForProject, } from '@reticlehq/core';
24
25
  import { loadDotEnv } from '../telemetry/dev-repo.js';
25
26
  import { licenseKeyFromEnvFiles } from '../features/license/license-env.js';
26
27
  import { LICENSE_KEY_ENV } from '../features/license/license.js';
27
28
  import { createNodeFileSystem } from '../memory/project/fs/fs-port.js';
29
+ import { localLinkOf, workspaceAppLinks } from './cli/status/workspace-links.js';
28
30
  import { affectedSavedFlows } from '../language/flows/change/flow-sources.js';
29
31
  import { availableUpdate } from './update/update-nudge.js';
30
32
  import { handleUpdate, handleRollback } from './cli/cli-update-commands.js';
33
+ import { headlessByDefault } from './cli/daemon-start-options.js';
31
34
  import { startDaemon } from '../index.js';
32
- import { isCloudCommand, runCloudCommand } from './cli/cloud-cli.js';
35
+ import { accountStatusFields, cmdLink, connectInstalls, isCloudCommand, runCloudCommand, } from './cli/cloud-cli.js';
33
36
  import { SERVER_VERSION } from './version/identity/server-version.js';
34
37
  import { log } from '../log.js';
35
38
  import { readPid, isAlive, removePid, spawnDaemon, discoverDaemonPort, writeDaemonRegistry, } from './daemon/daemon.js';
@@ -45,20 +48,46 @@ import { fetchStatus } from './daemon/binding/daemon-status-probe.js';
45
48
  import { handleDrive } from './cli/drive/drive-command.js';
46
49
  import { handleVerify } from './cli/cli-verify.js';
47
50
  import { runKill } from './cli/cli-kill.js';
48
- import { summarizeHunt } from '../judgement/hunt/hunt-report.js';
49
- import { runInit, buildNodeIo } from '@reticlehq/init';
51
+ import { runInit, buildNodeIo, InitFailure } from '@reticlehq/init';
50
52
  import { continueAfterInit } from './setup/init/init-runtime.js';
53
+ import { initFirstFlow } from './cli/try-command.js';
51
54
  import { handleDoctor } from './cli/cli-doctor.js';
52
55
  import { serverInitHost } from './setup/init/init-host.js';
53
56
  import { describeLicense } from '../features/license/license.js';
54
57
  import { isLikelyDevServerPort, devServerPortWarning, readProjectPort, readProjectId, workspacePortConflict, projectDirOf, } from './cli/ports/resolve/cli-port.js';
55
- import { nodeSpawner, readTextFile, reexecAtVersion, versionMatchNote, versionToMatch, } from './cli/launch/sdk-version-match.js';
58
+ import { helpRunsAt, helpVersionNote, nodeSpawner, readTextFile, reexecAtVersion, versionMatchNote, versionToMatch, } from './cli/launch/sdk-version-match.js';
56
59
  import { DAEMON_INNER_COMMAND, PORT_FLAG, parseCliArgs, CLI_USAGE, dialsTheDaemon, } from './cli/cli-parse.js';
57
- import { handleFeedback, handleIdentify, handleTelemetry } from '../telemetry/feedback-cli.js';
60
+ import { renderHelp } from './cli/cli-usage.js';
61
+ import { RENAMED_COMMANDS, renamedCommandFor, renamedNote } from './cli/cli-parse-grammar.js';
62
+ import { handleFeedback, handleTelemetry } from '../telemetry/feedback-cli.js';
58
63
  import { installDaemonTelemetry } from '../telemetry/daemon-telemetry.js';
59
64
  import { reportCliRun } from '../telemetry/cli-telemetry.js';
60
65
  // Re-exported so existing imports (and the CLI tests) keep resolving from '@/cli.js'.
61
66
  export { parseCliArgs, CLI_USAGE };
67
+ /** Said when `connect` carries on past an init whose setup did not finish. */
68
+ const MSG_CONNECT_AFTER_UNFINISHED_INIT = 'Setup did not finish (above) — signing in and linking anyway. Fix what it names, then run ' +
69
+ '`reticle init` again.';
70
+ /**
71
+ * Said last, when the account is linked and the one thing left is installing a dependency. Exit 0:
72
+ * connect's job — signing in and linking — is done, and a non-zero exit read as a failed connect.
73
+ */
74
+ export const MSG_CONNECTED_DEPS_PENDING = '⚠ Connected, but the dependency install did not finish (see above). Run the install it names, ' +
75
+ 'then `reticle init` to wire the app.';
76
+ /**
77
+ * How `reticle connect` exits: the cloud step's code when linking failed; 0 when it linked and setup
78
+ * finished or left only the dependency install (said in `note`); 1 when setup stopped for anything
79
+ * else. `initUnfinished` is why init's setup did not finish, or undefined when it did.
80
+ */
81
+ export function connectExit(cloudCode, initUnfinished) {
82
+ if (0 !== cloudCode)
83
+ return { code: cloudCode };
84
+ if (initUnfinished === undefined)
85
+ return { code: 0 };
86
+ if (InitFailure.DEPENDENCY_INSTALL === initUnfinished) {
87
+ return { code: 0, note: MSG_CONNECTED_DEPS_PENDING };
88
+ }
89
+ return { code: 1 };
90
+ }
62
91
  async function handleInit(parsed) {
63
92
  const cwd = process.cwd();
64
93
  // RETICLE_PORT counts as explicit, as it does for every other command: resolved once here, so the
@@ -78,7 +107,11 @@ async function handleInit(parsed) {
78
107
  },
79
108
  daemonPresent: async (p) => presenceIsUsable(await probePresence(p, { tcpOpen: probeDaemon, status: fetchStatus })),
80
109
  pickPort: (p) => pickDaemonPortToBind(p),
81
- });
110
+ daemonStartedHere: (p) => {
111
+ const started = readDaemonRegistry(reticleStateHome()).find((e) => e.port === p)?.cwd;
112
+ return started !== undefined && isSameOrAbove(started, cwd);
113
+ },
114
+ }, cwd);
82
115
  const io = buildNodeIo(cwd, serverInitHost(), { stderr: true === parsed.json });
83
116
  const result = runInit({
84
117
  cwd,
@@ -97,28 +130,40 @@ async function handleInit(parsed) {
97
130
  deferOutcome: true,
98
131
  continuesToRuntime: true !== parsed.filesOnly && true !== parsed.dryRun,
99
132
  }, io);
100
- await continueAfterInit({ ...parsed, port }, result, io, cwd);
133
+ await continueAfterInit({ ...parsed, port }, result, io, cwd, initFirstFlow);
134
+ return result;
101
135
  }
102
136
  // `serve`, `stop` and `restart` live in `cli/lifecycle/daemon-lifecycle.ts`: one idea, and the
103
137
  // largest group this file could give up without splitting something that belongs together.
104
138
  import { handleServe, handleStop, handleRestart } from './cli/lifecycle/daemon-lifecycle.js';
105
139
  import { statusLines } from './cli/status/status-lines.js';
106
140
  /**
107
- * Log the status event AND print it for a person.
108
- *
109
- * Both, not either: the JSON line is documented and is what a log is for, and the block is for
110
- * whoever is reading the terminal — which, once an agent is running the command, is somebody who
111
- * did not type it and cannot be assumed to parse it.
141
+ * Report status to the terminal. `--json` writes one structured line to STDOUT so it can be piped
142
+ * into `jq`; the human-readable block goes to stdout too. `log()` stays on stderr (the MCP
143
+ * transport lives on stdout), so `--json` must not go through it.
112
144
  */
113
- function reportStatus(fields, json) {
145
+ export function reportStatus(fields, json) {
114
146
  if (json) {
115
- log('reticle_status', fields);
147
+ const line = JSON.stringify({
148
+ t: new Date().toISOString(),
149
+ event: 'reticle_status',
150
+ ...fields,
151
+ });
152
+ process.stdout.write(`${line}\n`);
116
153
  return;
117
154
  }
118
155
  process.stdout.write(`${statusLines(fields).join('\n')}\n`);
119
156
  }
120
157
  export async function handleStatus(port, json = false) {
121
- const report = (fields) => reportStatus(fields, json);
158
+ // A broken session file must not cost the reader the rest of the status.
159
+ const account = await accountStatusFields().catch(() => ({}));
160
+ // At a workspace root that is no app of its own, each app and its link: "not linked" named none.
161
+ const linked = account.linkedProject;
162
+ if ('string' !== typeof linked && readProjectId(process.cwd()) === undefined)
163
+ Object.assign(account, {
164
+ workspaceApps: await workspaceAppLinks(process.cwd(), localLinkOf).catch(() => []),
165
+ });
166
+ const report = (fields) => reportStatus({ ...fields, ...account }, json);
122
167
  const pid = readPid(port);
123
168
  // Durable, so it survives the daemon idling out — which is the state `status` is most often run in.
124
169
  const projectId = readProjectId(process.cwd());
@@ -223,14 +268,13 @@ export async function handleStatus(port, json = false) {
223
268
  ...nudge,
224
269
  });
225
270
  }
226
- /** Print the running package version (resolved once in server-version.ts). */
271
+ /**
272
+ * Print the running package version (resolved once in server-version.ts), and nothing else.
273
+ *
274
+ * Bare on stdout so `V=$(reticle version)` works. It also wrote a JSON event to stderr, which a
275
+ * terminal shows: the first thing a new user typed after installing answered with a log line.
276
+ */
227
277
  function handleVersion() {
228
- log('reticle_version', { version: SERVER_VERSION });
229
- // Also on stdout, bare, because every diagnostic here starts by asking which build is running and
230
- // that answer has to be copyable. The event alone looked fine in a terminal -- stderr is on the
231
- // screen too -- but `V=$(reticle version)` came back empty, which is exactly the shape somebody
232
- // reaches for when writing an issue template or a CI check. The event stays; machine-readable
233
- // events all go to stderr and that consistency is worth keeping.
234
278
  process.stdout.write(`${SERVER_VERSION}\n`);
235
279
  }
236
280
  /** `reticle license` — show enterprise activation resolved from the environment (offline; nothing leaves). */
@@ -262,42 +306,6 @@ async function handleAffected(files, since) {
262
306
  });
263
307
  }
264
308
  }
265
- /**
266
- * `reticle hunt <dir>` — aggregate crawl reports from many checkouts into one number.
267
- *
268
- * Detection already exists (`reticle_crawl`). This is the arithmetic that turns a pile of runs into
269
- * the claim worth making: over N already-merged, already-green changes, how many carried a candidate
270
- * false green? No control arm is needed, because those changes SHIPPED — the counterfactual is
271
- * already established, which is what makes this the cheapest credible evidence available.
272
- *
273
- * Each file in <dir> is one crawl result. Producing them is a shell loop over a commit range:
274
- * check out, boot the app, `reticle_crawl`, write the JSON here.
275
- */
276
- async function handleHunt(dir) {
277
- try {
278
- const fs = createNodeFileSystem();
279
- const names = await fs.readdir(dir);
280
- const runs = [];
281
- for (const name of names.filter((n) => n.endsWith('.json'))) {
282
- const raw = await fs.readFile(join(dir, name));
283
- if (raw === undefined)
284
- continue;
285
- const parsed = JSON.parse(raw);
286
- const report = parsed;
287
- runs.push({
288
- label: report.label ?? name.replace(/\.json$/, ''),
289
- anomalies: report.anomalies ?? [],
290
- ...(report.stepsRun === undefined ? {} : { stepsRun: report.stepsRun }),
291
- });
292
- }
293
- log('reticle_hunt', { ...summarizeHunt(runs) });
294
- }
295
- catch (error) {
296
- log('reticle_hunt_failed', {
297
- error: error instanceof Error ? error.message : String(error),
298
- });
299
- }
300
- }
301
309
  /** Ensure a daemon is reachable on `port` (probe the real port; spawn + wait only if nothing's there). */
302
310
  function ensureDaemon(port) {
303
311
  return probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus }).then(async (presence) => {
@@ -395,9 +403,7 @@ function handleOpen(requestedPort, url) {
395
403
  // Points at the OS handler, not at `reticle doctor`. Doctor's browser check is about
396
404
  // Reticle's own Chromium, which this command never touches — the same misdirect the
397
405
  // no-session note below spells out at length, left standing here for one more release.
398
- recovery: 'Nothing was opened. This command asks the OS to open a url in your default browser ' +
399
- `(\`${openCommand(decision.url, process.platform).cmd}\` on this platform) and that ` +
400
- 'failed, so the fix is on the OS side: open the url yourself, or set a default browser.',
406
+ recovery: openLaunchFailureNote(decision.url, openCommand(decision.url, process.platform).cmd),
401
407
  });
402
408
  process.exit(1);
403
409
  return;
@@ -431,7 +437,12 @@ function handleOpen(requestedPort, url) {
431
437
  });
432
438
  }
433
439
  function handleDaemonInner(parsed) {
434
- const options = daemonStartOptions(parsed);
440
+ // The daemon the CLI starts is the one that can sign in for the panel: it owns ~/.reticle.
441
+ const options = {
442
+ ...daemonStartOptions(parsed),
443
+ hudSignIn: (repaint, link) => hudSignIn(repaint, undefined, undefined, link),
444
+ hudLink: (root) => cmdLink([], root, PlatformLinkVia.HUD),
445
+ };
435
446
  startDaemon(options)
436
447
  .then((server) => {
437
448
  log('reticle_daemon_ready', { port: parsed.port, pid: process.pid });
@@ -549,13 +560,15 @@ export function main() {
549
560
  // `version_skew`, and the unpinned `npx @reticlehq/server` every agent entry uses resolves the
550
561
  // LATEST major whatever the project installed. Hand the same arguments to the matching release and
551
562
  // step aside — it reports its own run. See cli/launch/sdk-version-match.ts.
552
- const matchVersion = versionToMatch({
563
+ // One project lookup for both questions below: it reads config and walks the workspace.
564
+ const versionInput = {
553
565
  argv,
554
566
  cliVersion: SERVER_VERSION,
555
567
  env: process.env,
556
568
  projectDir: projectDirOf(process.cwd()),
557
569
  readFile: readTextFile,
558
- });
570
+ };
571
+ const matchVersion = versionToMatch(versionInput);
559
572
  if (matchVersion !== undefined) {
560
573
  process.stderr.write(`${versionMatchNote(matchVersion, SERVER_VERSION)}\n`);
561
574
  reexecAtVersion(matchVersion, argv, process.env, {
@@ -565,6 +578,11 @@ export function main() {
565
578
  });
566
579
  return;
567
580
  }
581
+ // Help stays on this binary, so say which version the command it describes really runs at (#1378).
582
+ const helpVersion = helpRunsAt(versionInput);
583
+ if (helpVersion !== undefined) {
584
+ process.stdout.write(`${helpVersionNote(helpVersion, SERVER_VERSION)}\n\n`);
585
+ }
568
586
  // Every invocation passes through here — the single chokepoint for the "how often is it used / how
569
587
  // many distinct machines + projects" metrics. Fire-and-forget: a metric must never delay or fail a run.
570
588
  //
@@ -576,6 +594,13 @@ export function main() {
576
594
  // just the scale, which is the kind of error you cannot correct for after the fact. The daemon's
577
595
  // own lifecycle is already reported by `daemon_started` / `daemon_stopped`; it is not a CLI run.
578
596
  reportCliRun(argv);
597
+ // An old name still runs, for one release, and says once what it is called now. Not when the
598
+ // person only asked for help: that answer names the new command itself, on stdout.
599
+ const renamedTo = renamedCommandFor(argv);
600
+ if (renamedTo !== undefined) {
601
+ const colour = true === process.stderr.isTTY && process.env['NO_COLOR'] === undefined;
602
+ process.stderr.write(`${renamedNote(argv[0] ?? '', renamedTo, colour)}\n`);
603
+ }
579
604
  // Cloud subcommands (login/link/project/config/push) are a distinct family with their own async client;
580
605
  // handle them before the local typed parser so `reticle login` etc. work as one tool.
581
606
  if (isCloudCommand(argv[0])) {
@@ -584,17 +609,39 @@ export function main() {
584
609
  // `reticle link --help` used to run the command: it reached for the network and answered
585
610
  // `fetch failed` with exit 1, to somebody who had asked what the command was for.
586
611
  if (argv.some((arg) => '--help' === arg || '-h' === arg)) {
587
- process.stdout.write(`${CLI_USAGE}\n`);
612
+ process.stdout.write(`${renderHelp(argv[0], RENAMED_COMMANDS)}\n`);
588
613
  return;
589
614
  }
590
615
  if ('connect' === argv[0]) {
591
616
  void (async () => {
592
617
  // A fresh project gets the same install, dev-server handover and browser proof as `init`.
593
618
  // Its failure exits non-zero before any cloud binding can claim this repo is ready.
619
+ // A setup that did not finish is said above and still fails the run, but no longer ends it
620
+ // before sign-in: the second identical run was the only way to get signed in.
621
+ let unfinished;
594
622
  if (readProjectId(process.cwd()) === undefined) {
595
- await handleInit({ port: undefined, mcp: true, dryRun: false, install: true });
623
+ const init = await handleInit({
624
+ port: undefined,
625
+ mcp: true,
626
+ dryRun: false,
627
+ install: connectInstalls(argv),
628
+ keepGoing: true,
629
+ });
630
+ if (1 === process.exitCode) {
631
+ // init hands no context over exactly when the dependency install failed (run.ts); its
632
+ // outcome's own reason is unset when the files were all written and the app was not.
633
+ unfinished =
634
+ init.context === undefined && init.outcome !== undefined
635
+ ? InitFailure.DEPENDENCY_INSTALL
636
+ : (init.outcome?.reason ?? InitFailure.OTHER);
637
+ process.exitCode = 0;
638
+ process.stderr.write(`${MSG_CONNECT_AFTER_UNFINISHED_INIT}\n`);
639
+ }
596
640
  }
597
- return runCloudCommand(argv);
641
+ const exit = connectExit(await runCloudCommand(argv), unfinished);
642
+ if (exit.note !== undefined)
643
+ process.stderr.write(`${exit.note}\n`);
644
+ return exit.code;
598
645
  })()
599
646
  .then((code) => process.exit(code))
600
647
  .catch((cause) => {
@@ -635,7 +682,7 @@ export function main() {
635
682
  const defaultPort = envPort ?? projectPort ?? myDaemonPort ?? RETICLE_DEFAULT_PORT;
636
683
  // Headed by default; hidden only where there is no display to be headed on. A run nobody can see
637
684
  // is a run nobody trusts, and every "did it actually do anything?" cost a human round-trip.
638
- const parsed = parseCliArgs(argv, defaultPort, process.env['CI'] !== undefined);
685
+ const parsed = parseCliArgs(argv, defaultPort, headlessByDefault(process.env, process.platform));
639
686
  // The refusal the line above promised. Printing it and carrying on let the default port answer
640
687
  // anyway, for whichever project's daemon owned it.
641
688
  if (portConflict !== undefined && dialsTheDaemon(parsed)) {
@@ -680,14 +727,15 @@ export function main() {
680
727
  case 'feedback':
681
728
  void handleFeedback(parsed.text, parsed.rating, parsed.bug, parsed.feedbackKind, parsed.agent);
682
729
  break;
683
- case 'identify':
684
- void handleIdentify(parsed);
685
- break;
686
730
  case 'version':
687
731
  handleVersion();
688
732
  break;
689
733
  case 'help':
690
- process.stdout.write(`${CLI_USAGE}\n`);
734
+ process.stdout.write(`${renderHelp(parsed.topic, RENAMED_COMMANDS)}\n`);
735
+ break;
736
+ case 'removed':
737
+ process.stderr.write(`${parsed.message}\n`);
738
+ process.exit(1);
691
739
  break;
692
740
  case 'doctor':
693
741
  void handleDoctor(parsed.port);
@@ -702,48 +750,26 @@ export function main() {
702
750
  mcp: parsed.mcp,
703
751
  }, reportStepFromCli);
704
752
  break;
705
- case 'tutorial':
706
- // Reported for BOTH paths, and before either: a run is a tour too, and these two steps are
707
- // about the tour being asked for, which is already true by the time we get here.
708
- reportTutorialShown();
709
- if (parsed.run) {
710
- void runDemoTour({
711
- port: parsed.port,
712
- headless: parsed.headless,
713
- say: (line) => process.stdout.write(`${line}\n`),
714
- }).then((result) => {
715
- process.exit(result.code);
716
- });
717
- break;
718
- }
719
- process.stdout.write(`${renderTutorial(parsed.audience)}\n`);
720
- break;
721
753
  case 'open':
722
754
  handleOpen(parsed.port, parsed.url);
723
755
  break;
724
756
  case 'drive':
725
- handleDrive(parsed);
757
+ handleDrive(parsed, readProjectId(process.cwd()));
726
758
  break;
727
759
  case 'verify':
728
760
  handleVerify(parsed);
729
761
  break;
730
- case 'capsules':
731
- void handleCapsules();
732
- break;
733
762
  case 'affected':
734
763
  void handleAffected(parsed.files, parsed.since);
735
764
  break;
736
- case 'hunt':
737
- void handleHunt(parsed.dir);
738
- break;
739
765
  case 'gate':
740
766
  void handleGate(parsed.files, parsed.since, parsed.hook, parsed.acceptCoverage);
741
767
  break;
742
768
  case 'report':
743
769
  void handleReport(parsed.session, parsed.hook);
744
770
  break;
745
- case 'watch':
746
- handleWatch();
771
+ case 'context':
772
+ void handleContext(parsed.session);
747
773
  break;
748
774
  case 'update':
749
775
  void handleUpdate();
@@ -15,6 +15,8 @@ interface StatusSession {
15
15
  sessionId: string;
16
16
  url: string;
17
17
  projectId?: string;
18
+ /** The page's own title. Absent when the page has none, or on a daemon too old to send it. */
19
+ title?: string;
18
20
  throttled: boolean;
19
21
  /**
20
22
  * The tab is backgrounded. Reported by the daemon on every session; `false` on one too old to say,
@@ -102,6 +102,7 @@ export function summarizeStatus(payload) {
102
102
  ...('string' === typeof r['projectId'] && 0 < r['projectId'].length
103
103
  ? { projectId: r['projectId'] }
104
104
  : {}),
105
+ ...('string' === typeof r['title'] && 0 < r['title'].length ? { title: r['title'] } : {}),
105
106
  throttled: true === r['throttled'],
106
107
  hidden: true === r['hidden'],
107
108
  stale: true === r['stale'],
@@ -8,7 +8,7 @@
8
8
  * per Node's guidance, so LOG a clear reason and exit cleanly; the next `reticle mcp` respawns a fresh
9
9
  * daemon, which beats crashing silently or limping along corrupt.
10
10
  */
11
- import { RETICLE_DEFAULT_PORT, TelemetryActor, TelemetryEventKind } from '@reticlehq/core';
11
+ import { RETICLE_DEFAULT_PORT, TelemetryEventKind } from '@reticlehq/core';
12
12
  import { errorSkeleton, errorTypeOf, fingerprintCrash, MAX_REPORTED_FRAMES, reticleFrames, } from '../../telemetry/error-fingerprint.js';
13
13
  import { getSessionMetrics } from '../../telemetry/session-metrics.js';
14
14
  import { machineSnapshot } from '../../telemetry/machine-snapshot.js';
@@ -157,9 +157,9 @@ function reportCrash(kind, value) {
157
157
  * gone for months.
158
158
  */
159
159
  detach: true,
160
- // A crash is ALWAYS reached through something the agent asked for — the daemon does nothing on
161
- // its own — so attributing it to the agent is accurate rather than a guess.
162
- actor: TelemetryActor.AGENT,
160
+ // No `actor`. The daemon does plenty on its own (timers, the bridge, a page's SDK, the update
161
+ // check), and the core contract says a crash is neither human nor agent: tagging every one
162
+ // `agent` put the whole crash count on the agent side of every actor split.
163
163
  crash: {
164
164
  kind,
165
165
  errorType,
@@ -76,6 +76,20 @@ export declare function daemonProjectAt(port: number, home: string): string | un
76
76
  * Only LIVE daemons are named: a port a session used yesterday is history, not a split.
77
77
  */
78
78
  export declare function daemonsServingProjectElsewhere(projectId: string | undefined, myPort: number, home: string, alive: (pid: number) => boolean, connectedOn: (port: number) => boolean): readonly number[];
79
+ /** Live daemons that serve a named project, on any port but `myPort`. */
80
+ export declare function projectDaemonsElsewhere(myPort: number, home: string, alive: (pid: number) => boolean): {
81
+ port: number;
82
+ projectId: string;
83
+ }[];
84
+ /**
85
+ * The sentence for a daemon started outside any project while projects run their own daemons, or
86
+ * `undefined` when there are none. Its sessions are empty because the apps dial their own ports,
87
+ * and "check your scope" is not something an agent inside an editor can act on (#1240).
88
+ */
89
+ export declare function projectlessNote(myPort: number, others: readonly {
90
+ port: number;
91
+ projectId: string;
92
+ }[]): string | undefined;
79
93
  /**
80
94
  * The sentence for a split brain, or `undefined` when there is none.
81
95
  *
@@ -98,6 +112,12 @@ export declare function splitBrainNote(myPort: number, elsewhere: readonly numbe
98
112
  * being inspected is the project's own.
99
113
  */
100
114
  export declare function wrongDaemonNote(inspectedPort: number, ownPort: number | undefined): string | undefined;
115
+ /**
116
+ * Why the proxy serves `port` and not the `requested` one, in words a person can act on. It said
117
+ * "the requested port serves a different project" for every move, including the commonest one: this
118
+ * project's own daemon was already running elsewhere (a `connect` started it on the default).
119
+ */
120
+ export declare function relocationReason(requested: number, port: number, projectId: string | undefined, home: string, alive: (pid: number) => boolean): string;
101
121
  /**
102
122
  * The port this agent's MCP proxy should serve, decided BEFORE the proxy starts.
103
123
  *
@@ -119,4 +139,6 @@ export declare function resolveMcpPort(preferred: number, projectId: string | un
119
139
  alive: (pid: number) => boolean;
120
140
  daemonPresent: (port: number) => Promise<boolean>;
121
141
  pickPort: (preferred: number) => Promise<number>;
122
- }): Promise<number>;
142
+ },
143
+ /** The port this project's `.reticle.json` names: the one its app dials. */
144
+ own?: number): Promise<number>;
@@ -19,6 +19,8 @@
19
19
  import { readdirSync, readFileSync } from 'node:fs';
20
20
  import { join } from 'node:path';
21
21
  import { DaemonRegistryEntrySchema, daemonRegistryPort, pickDaemonPort, } from '@reticlehq/core/artifacts';
22
+ import { ReticleEnv, RETICLE_DEFAULT_PORT } from '@reticlehq/core';
23
+ const RETICLE_PORT_ENV = ReticleEnv.PORT;
22
24
  /**
23
25
  * Every well-formed registry entry in `home`.
24
26
  *
@@ -117,6 +119,30 @@ export function daemonsServingProjectElsewhere(projectId, myPort, home, alive, c
117
119
  .map((entry) => entry.port)
118
120
  .sort((a, b) => a - b);
119
121
  }
122
+ /** Live daemons that serve a named project, on any port but `myPort`. */
123
+ export function projectDaemonsElsewhere(myPort, home, alive) {
124
+ return readDaemonRegistry(home)
125
+ .filter((entry) => entry.port !== myPort && alive(entry.pid))
126
+ .flatMap((entry) => entry.projectId === undefined || 0 === entry.projectId.length
127
+ ? []
128
+ : [{ port: entry.port, projectId: entry.projectId }])
129
+ .sort((a, b) => a.port - b.port);
130
+ }
131
+ /**
132
+ * The sentence for a daemon started outside any project while projects run their own daemons, or
133
+ * `undefined` when there are none. Its sessions are empty because the apps dial their own ports,
134
+ * and "check your scope" is not something an agent inside an editor can act on (#1240).
135
+ */
136
+ export function projectlessNote(myPort, others) {
137
+ const first = others[0];
138
+ if (first === undefined)
139
+ return undefined;
140
+ const listed = others.map((o) => `${o.projectId} on :${String(o.port)}`).join(', ');
141
+ return (`this daemon on :${String(myPort)} was started outside any project, and the projects on this ` +
142
+ `machine run their own daemons: ${listed}. Their apps connect there, not here. Point the MCP ` +
143
+ `server at one — set ${RETICLE_PORT_ENV}=${String(first.port)} in its config, or launch it from ` +
144
+ 'that project directory.');
145
+ }
120
146
  /**
121
147
  * The sentence for a split brain, or `undefined` when there is none.
122
148
  *
@@ -130,12 +156,17 @@ export function splitBrainNote(myPort, elsewhere) {
130
156
  return undefined;
131
157
  const listed = elsewhere.map((port) => `:${String(port)}`).join(', ');
132
158
  const first = elsewhere[0] ?? myPort;
159
+ // The agent moves, not the app (#1546). The daemon the app is on is a working session this agent
160
+ // did not start, and it may be a person's, another agent's or another project's. Stopping it was
161
+ // the first thing this used to say. It comes last now, with what it costs.
133
162
  return (`this project's app is connected to a DIFFERENT Reticle daemon (${listed}), while this one is ` +
134
163
  `on :${String(myPort)} — two daemons for one project, and the agent is attached to the empty ` +
135
- 'half. Nothing is wrong with the app or the wiring. Stop the other daemon with ' +
136
- `\`reticle stop --port ${String(first)}\` and restart the dev server so the app rediscovers ` +
137
- 'this one, or start the agent and the dev server from the same project directory so both ' +
138
- 'resolve the same daemon.');
164
+ 'half. Nothing is wrong with the app or the wiring. Move the agent to the app: set ' +
165
+ `${RETICLE_PORT_ENV}=${String(first)} in this MCP server's config, or launch the agent from the ` +
166
+ `project directory the dev server runs in, then restart the agent session. Leave :${String(first)} ` +
167
+ 'running. Only if nothing else is using it, `reticle stop --port ' +
168
+ `${String(first)}\` and a dev server restart move the app here instead; that disconnects every ` +
169
+ 'tab and agent on that daemon.');
139
170
  }
140
171
  /**
141
172
  * The other stance on the same split, for a command standing on the port that HAS the app.
@@ -158,6 +189,25 @@ export function wrongDaemonNote(inspectedPort, ownPort) {
158
189
  'be different processes, with both reporting healthy. Stop one of them and restart the dev ' +
159
190
  'server so everything lands on the same port.');
160
191
  }
192
+ /**
193
+ * Why the proxy serves `port` and not the `requested` one, in words a person can act on. It said
194
+ * "the requested port serves a different project" for every move, including the commonest one: this
195
+ * project's own daemon was already running elsewhere (a `connect` started it on the default).
196
+ */
197
+ export function relocationReason(requested, port, projectId, home, alive) {
198
+ const at = `:${String(port)}`;
199
+ if (projectId !== undefined && resolveDaemonForProject(projectId, home, alive) === port)
200
+ return (`this project's daemon is already running on ${at}, so the agent uses it instead of ` +
201
+ `:${String(requested)}. To use :${String(requested)}, run \`reticle stop --port ${String(port)}\` ` +
202
+ 'and reconnect the agent.');
203
+ const holder = daemonProjectAt(requested, home);
204
+ if (holder !== undefined && holder !== projectId)
205
+ return (`:${String(requested)} serves project "${holder}", so this one is served on ${at}. Give this ` +
206
+ 'project its own port (RETICLE_PORT, or `port` in its .reticle.json) and restart the agent.');
207
+ if (projectId === undefined)
208
+ return `no project here, and the one live project daemon is on ${at}: the agent uses it.`;
209
+ return `nothing usable answered on :${String(requested)}, so the agent is served on ${at}.`;
210
+ }
161
211
  /**
162
212
  * The port this agent's MCP proxy should serve, decided BEFORE the proxy starts.
163
213
  *
@@ -175,13 +225,33 @@ export function wrongDaemonNote(inspectedPort, ownPort) {
175
225
  * silent adoption is what made every agent on a machine share one process, one identity and one
176
226
  * blast radius.
177
227
  */
178
- export async function resolveMcpPort(preferred, projectId, home, deps) {
228
+ export async function resolveMcpPort(preferred, projectId, home, deps,
229
+ /** The port this project's `.reticle.json` names: the one its app dials. */
230
+ own) {
179
231
  const mine = resolveDaemonForProject(projectId, home, deps.alive);
180
232
  if (mine !== undefined)
181
233
  return mine;
182
- if (!(await deps.daemonPresent(preferred)))
234
+ if (!(await deps.daemonPresent(preferred))) {
235
+ // A caller outside any project (an editor's user-scope MCP, launched from $HOME) used to dial the
236
+ // default and never see the one project that had moved off it (#1240). With exactly one project
237
+ // daemon live, that is the one; with several, the no-session answer names them instead.
238
+ // Only on the DEFAULT port, which is the guess #1240 corrects. A port passed with --port or
239
+ // RETICLE_PORT is a choice: relocating it attached an unwired app to another project's daemon.
240
+ const projects = projectId === undefined && RETICLE_DEFAULT_PORT === preferred
241
+ ? projectDaemonsElsewhere(preferred, home, deps.alive)
242
+ : [];
243
+ return 1 === projects.length ? (projects[0]?.port ?? preferred) : preferred;
244
+ }
245
+ if (adoptable(daemonProjectAt(preferred, home), projectId))
183
246
  return preferred;
184
- return adoptable(daemonProjectAt(preferred, home), projectId)
185
- ? preferred
186
- : deps.pickPort(preferred);
247
+ // Moved off a port another project holds: to the one this project's app dials, when it is free or
248
+ // already ours. A random port served nobody — the app kept dialling its own, and the agent was
249
+ // told "wired, and a dev server is listening, but no session".
250
+ if (own !== undefined && own !== preferred) {
251
+ if (!(await deps.daemonPresent(own)))
252
+ return own;
253
+ if (adoptable(daemonProjectAt(own, home), projectId))
254
+ return own;
255
+ }
256
+ return deps.pickPort(preferred);
187
257
  }
@@ -34,7 +34,7 @@ interface AgentWriteResult {
34
34
  */
35
35
  export declare function applyAgentPlan(plan: readonly AgentPlanStep[], io: AgentWriterIo): AgentWriteResult[];
36
36
  /** The `/reticle` instruction, for agents that load skills from a directory. */
37
- export declare const RETICLE_SKILL = "---\nname: reticle\ndescription: Verify a change against the running app, from inside it, before calling it done.\n---\n\nReticle exposes the running app to you as `reticle_*` MCP tools. Look, act, observe, assert.\n\nOnly `reticle_act_and_wait` and `reticle_assert` produce a verdict. Everything else moves or\nreads the app and proves nothing, so a drive that ends without one of those has no result however\nmany tools it used.\n\n`verified: \"unknown\"` is not a pass: it means Reticle could not tell what happened.\n`verified: \"no-fault\"` is not a pass either, because nothing was declared to prove. Never weaken a\ncheck to make it pass.\n\nThe cheapest path that answers the question:\n\n- \"did my edit break anything?\" -> `reticle_verify { action: \"change\", files: [...] }`\n- \"does this known journey still work?\" -> `reticle_verify { action: \"flows\", names: [\"...\"] }`\n- \"does this new behaviour work?\" -> `reticle_act { steps: [...] }` for the setup, then ONE `reticle_act_and_wait`\n- \"nothing is recorded yet\" -> `reticle_verify { action: \"explore\", persona: \"<who does what>\" }`, which\n drives the app and SAVES what it drove, so the next run replays with no model in the loop\n";
37
+ export declare const RETICLE_SKILL = "---\nname: reticle\ndescription: Verify a change against the running app, from inside it, before calling it done.\n---\n\nReticle exposes the running app to you as `reticle_*` MCP tools. Look, act, observe, assert.\n\nOnly `reticle_act_and_wait` and `reticle_assert` produce a verdict. Everything else moves or\nreads the app and proves nothing, so a drive that ends without one of those has no result however\nmany tools it used.\n\n`verified: \"unknown\"` is not a pass: it means Reticle could not tell what happened.\n`verified: \"no-fault\"` is not a pass either, because nothing was declared to prove. Never weaken a\ncheck to make it pass.\n\nThe cheapest path that answers the question:\n\n- \"did my edit break anything?\" -> `reticle_verify { action: \"change\", files: [...] }`\n- \"does this known journey still work?\" -> `reticle_verify { action: \"flows\", names: [\"...\"] }`\n- \"does this new behaviour work?\" -> `reticle_act { steps: [...] }` for the setup, then ONE `reticle_act_and_wait`\n- \"nothing is recorded yet\" -> drive the journey yourself with `reticle_act_and_wait` and an `until` on its\n last step; it is saved as a flow, so the next run replays with no model in the loop. With a linked\n project, `reticle_verify { action: \"explore\", persona: \"<who does what>\" }` drives it for you\n";
38
38
  interface SkillWriteResult {
39
39
  readonly id: string;
40
40
  readonly file: string;