@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,11 +1,12 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { dirname } from 'node:path';
2
+ import { dirname, join } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
4
  import { claudeAddCommand, McpClient, probeCli, terminalWidth, wrapForTerminal, } from '@reticlehq/init';
5
- import { installClosing, tutorialShownSteps } from './tutorial.js';
5
+ import { tutorialShownSteps } from './tutorial.js';
6
6
  import { setupMcp, knownClientLabels } from '../setup/setup-mcp.js';
7
7
  import { reportInstallSteps } from '../setup/setup-install.js';
8
8
  import { registerOtherAgents } from '../setup/setup-command.js';
9
+ /** How many coding agents on this machine have Reticle's tools after this run. */
9
10
  export function handleSetupMcp(reportStep, standalone = true) {
10
11
  const io = {
11
12
  exists: (p) => existsSync(p),
@@ -35,15 +36,17 @@ export function handleSetupMcp(reportStep, standalone = true) {
35
36
  const result = setupMcp(io);
36
37
  if (0 === result.detected.length) {
37
38
  // Even with no file-backed client, the broader set may still have somewhere to write.
38
- registerOtherAgents((line) => {
39
+ const preRegistered = registerOtherAgents((line) => {
39
40
  io.print(line);
40
41
  });
41
42
  // Named rather than a bare "none found". A person whose agent IS installed needs to know
42
43
  // whether we looked for it at all, and the list is the difference between "we did not find
43
- // yours" and "we do not support yours".
44
- io.print(`No coding agent config found. Looked for: ${knownClientLabels().join(', ')}.`);
45
- io.print('Install one, then run `reticle setup mcp` again.');
46
- return;
44
+ // yours" and "we do not support yours". When the broader set was written, saying "none found"
45
+ // right under its tick read as a contradiction: those agents are pre-registered, not found.
46
+ io.print(0 < preRegistered
47
+ ? `None of ${knownClientLabels().join(', ')} is installed here yet. The agents above are pre-registered and have Reticle's tools once installed; install one of the others, then run \`reticle setup mcp\` again.`
48
+ : `No coding agent config found. Looked for: ${knownClientLabels().join(', ')}. Install one, then run \`reticle setup mcp\` again.`);
49
+ return 0;
47
50
  }
48
51
  for (const id of result.registered)
49
52
  io.print(` ✓ ${id}`);
@@ -90,6 +93,25 @@ export function handleSetupMcp(reportStep, standalone = true) {
90
93
  io.print('Restart your agent for it to pick up the new server.');
91
94
  io.print('Then: cd <your project> && reticle init');
92
95
  }
96
+ return result.registered.length + result.alreadyThere.length;
97
+ }
98
+ /**
99
+ * The one line the launchers read and strip: what they cannot know and the next steps depend on.
100
+ *
101
+ * The launchers own the closing words (served from main, so wording changes on merge) and used to
102
+ * print "restart your coding agent" to a machine with none, and "cd your-app" to somebody already
103
+ * standing in it. An older launcher shows this line as is; a launcher reading an older CLI finds no
104
+ * line and keeps its generic wording, so neither half has to ship first.
105
+ */
106
+ export const INSTALL_RESULT_PREFIX = 'RETICLE_INSTALL';
107
+ const APP_MARKERS = ['package.json', 'index.html'];
108
+ /** Whether the folder the installer ran in is an app: `init` runs here, or after a `cd`. */
109
+ export const InstallAppHere = { HERE: 'here', NONE: 'none' };
110
+ export function installResultLine(agents, cwd) {
111
+ const app = APP_MARKERS.some((file) => existsSync(join(cwd, file)))
112
+ ? InstallAppHere.HERE
113
+ : InstallAppHere.NONE;
114
+ return `${INSTALL_RESULT_PREFIX} agents=${String(agents)} app=${app}`;
93
115
  }
94
116
  /**
95
117
  * `reticle setup install` — the Node half of the one-line installer.
@@ -100,16 +122,17 @@ export function handleSetupMcp(reportStep, standalone = true) {
100
122
  */
101
123
  export function handleSetupInstall(opts, reportStep) {
102
124
  reportInstallSteps({ runtimeSecs: opts.runtimeSecs, installSecs: opts.installSecs }, reportStep);
125
+ let agents = 0;
103
126
  if (opts.mcp) {
104
- handleSetupMcp(reportStep, false);
127
+ agents = handleSetupMcp(reportStep, false);
105
128
  }
106
129
  else {
107
130
  process.stdout.write('Skipping MCP registration (--no-mcp).\n');
108
131
  }
109
- // Installation and onboarding are one script, so the tour prints here and is not gated on
110
- // anything — see installClosing for the heuristic this replaced and why it reached nobody.
111
- process.stdout.write(`${wrapForTerminal(installClosing(opts.mcp), terminalWidth())}\n`);
112
- // Shown, so the ONBOARD steps are a fact rather than a guess.
132
+ // No closing here: the installer prints the next step and the agent prompt itself, right after
133
+ // this returns, so what this prints is progress and nothing else. Those two blocks are what the
134
+ // ONBOARD steps below now stand for: what Reticle is for, shown before anything is asked of anyone.
113
135
  for (const step of tutorialShownSteps())
114
136
  reportStep(step);
137
+ process.stdout.write(`${installResultLine(agents, process.cwd())}\n`);
115
138
  }
@@ -19,6 +19,7 @@ export declare const StatusLabel: {
19
19
  readonly DAEMON: "daemon";
20
20
  readonly SESSIONS: "sessions";
21
21
  readonly AGENT_LINK: "agent link";
22
+ readonly ACCOUNT: "account";
22
23
  readonly NEXT: "next";
23
24
  readonly SPLIT_BRAIN: "split brain";
24
25
  readonly UPDATE: "update";
@@ -19,6 +19,7 @@ export const StatusLabel = {
19
19
  DAEMON: 'daemon',
20
20
  SESSIONS: 'sessions',
21
21
  AGENT_LINK: 'agent link',
22
+ ACCOUNT: 'account',
22
23
  NEXT: 'next',
23
24
  SPLIT_BRAIN: 'split brain',
24
25
  UPDATE: 'update',
@@ -101,9 +102,40 @@ export function statusLines(fields) {
101
102
  if (why !== undefined)
102
103
  lines.push(continuation(why));
103
104
  }
105
+ // Who is signed in, and whether this repo is linked: what `whoami` used to answer. Only when the
106
+ // caller looked, which is what the key being present means.
107
+ if ('signedInAs' in fields) {
108
+ const who = str(fields, 'signedInAs');
109
+ const project = str(fields, 'linkedProject');
110
+ // Signed in to one workspace, a repo can still send to another: say which it sends to.
111
+ const workspace = str(fields, 'linkedWorkspace');
112
+ // A key the platform refused at the last sync is the answer, not "not signed in": a member
113
+ // removed from the workspace was told to connect while the key was set, and refused.
114
+ const refused = str(fields, 'keyRefused');
115
+ lines.push(row(StatusLabel.ACCOUNT, refused !== undefined
116
+ ? `${NOT_OK} refused at the last sync: ${refused}`
117
+ : who === undefined
118
+ ? `${NOT_OK} not signed in`
119
+ : `${OK} signed in as ${who}`));
120
+ const apps = appLinks(fields['workspaceApps']);
121
+ if (project === undefined && 0 < apps.length)
122
+ for (const { app, project: linked } of apps)
123
+ lines.push(continuation(null === linked
124
+ ? `${app} is not linked: run \`reticle connect\` in ${app}`
125
+ : `${app} is linked to ${linked}`));
126
+ else
127
+ lines.push(continuation(project === undefined
128
+ ? 'this repo is not linked: run `reticle connect`'
129
+ : `this repo is linked to ${project}${workspace === undefined ? '' : ` in workspace "${workspace}"`}`));
130
+ }
104
131
  const client = str(fields, 'mcpClient');
105
- if (client !== undefined)
106
- lines.push(row(StatusLabel.AGENT_LINK, client));
132
+ if (client !== undefined) {
133
+ // The state in words (`mcpClientSaid`), never the record's own name for it.
134
+ lines.push(row(StatusLabel.AGENT_LINK, str(fields, 'mcpClientSaid') ?? client));
135
+ const action = str(fields, 'mcpClientAction');
136
+ if (action !== undefined)
137
+ lines.push(continuation(action));
138
+ }
107
139
  for (const [label, key] of [
108
140
  [StatusLabel.NEXT, 'nextAction'],
109
141
  [StatusLabel.SPLIT_BRAIN, 'splitBrain'],
@@ -115,3 +147,16 @@ export function statusLines(fields) {
115
147
  }
116
148
  return lines;
117
149
  }
150
+ /** A workspace root's apps and their links, read defensively off the status fields. */
151
+ function appLinks(value) {
152
+ if (!Array.isArray(value))
153
+ return [];
154
+ return value.flatMap((raw) => {
155
+ if ('object' !== typeof raw || null === raw)
156
+ return [];
157
+ const { app, project } = raw;
158
+ return 'string' === typeof app
159
+ ? [{ app, project: 'string' === typeof project ? project : null }]
160
+ : [];
161
+ });
162
+ }
@@ -0,0 +1,10 @@
1
+ export interface AppLink {
2
+ /** The app's directory, relative to the root. */
3
+ app: string;
4
+ /** The project it sends to, or null when it is not linked. */
5
+ project: string | null;
6
+ }
7
+ /** Each app under `root`, in name order, with its link. Empty when `root` is no workspace. */
8
+ export declare function workspaceAppLinks(root: string, linkOf: (appDir: string) => Promise<string | null>): Promise<AppLink[]>;
9
+ /** The project an app folder's link file names, or null with none: local only, as status is. */
10
+ export declare function localLinkOf(appDir: string): Promise<string | null>;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The apps of a workspace root and the project each is linked to, for `reticle status` run at a root
3
+ * that is no app of its own: "this repo is not linked" there named nothing that could be acted on.
4
+ */
5
+ import { readFileSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { ReticleDir, asRecord, asString } from '@reticlehq/core';
8
+ import { SILENT_HOST, buildNodeIo, findWorkspaceApps } from '@reticlehq/init';
9
+ /** Each app under `root`, in name order, with its link. Empty when `root` is no workspace. */
10
+ export async function workspaceAppLinks(root, linkOf) {
11
+ let apps;
12
+ try {
13
+ apps = findWorkspaceApps(buildNodeIo(root, SILENT_HOST));
14
+ }
15
+ catch {
16
+ return [];
17
+ }
18
+ return Promise.all([...apps].sort().map(async (app) => ({ app, project: await linkOf(join(root, app)) })));
19
+ }
20
+ /** The project an app folder's link file names, or null with none: local only, as status is. */
21
+ export function localLinkOf(appDir) {
22
+ try {
23
+ const link = JSON.parse(readFileSync(join(appDir, ReticleDir.ROOT, ReticleDir.CLOUD_LINK_FILE), 'utf8'));
24
+ return Promise.resolve(asString(asRecord(link)['projectId']) ?? null);
25
+ }
26
+ catch {
27
+ return Promise.resolve(null);
28
+ }
29
+ }
@@ -0,0 +1,96 @@
1
+ import type { CloudConfig } from '../../memory/cloud/cloud-sync.js';
2
+ import { type FreeDrive } from '../../features/harness/platform/platform-drives.js';
3
+ export declare const MSG_SIGN_IN_FIRST = "Sign in first: reticle connect (it is free, no card)";
4
+ /** The whole drive, model turns and browser included, before the CLI stops waiting for it. */
5
+ export declare const TRY_BUDGET_MS = 120000;
6
+ /** Model turns in the one free drive. Bounds what it costs, not what it may find. */
7
+ export declare const TRY_MAX_STEPS = 40;
8
+ export interface TryJourney {
9
+ title: string;
10
+ status: string;
11
+ }
12
+ /** What one drive came back with, or the sentence that says why it could not run. */
13
+ export interface TryDrive {
14
+ journeys: TryJourney[];
15
+ runIds: string[];
16
+ error?: string;
17
+ }
18
+ export interface TryPorts {
19
+ /** The credential `reticle connect` filed for this folder, or null when it is not linked. */
20
+ linked: () => Promise<CloudConfig | null>;
21
+ requestDrive: (cloud: CloudConfig) => Promise<FreeDrive>;
22
+ drive: (request: {
23
+ url: string;
24
+ driveId: string;
25
+ persona?: string;
26
+ }) => Promise<TryDrive>;
27
+ /** Send the drive's run, as `reticle push` does. True when the cycle succeeded. */
28
+ sync: (runIds: readonly string[]) => Promise<boolean>;
29
+ dashboardUrl: (cloud: CloudConfig) => Promise<string | undefined>;
30
+ out: (line: string) => void;
31
+ fail: (line: string) => void;
32
+ }
33
+ export interface TryArgs {
34
+ url: string;
35
+ persona?: string;
36
+ }
37
+ /** `try <url> [--persona <who>]`, or the sentence that says what is missing. */
38
+ export declare function parseTryArgs(argv: readonly string[]): TryArgs | {
39
+ error: string;
40
+ };
41
+ /** The summary, worst news last so it is the line a reader's eye lands on. Pure. */
42
+ export declare function summarizeTry(journeys: readonly TryJourney[]): string[];
43
+ export declare function runTry(args: TryArgs, ports: TryPorts): Promise<number>;
44
+ /** The journeys out of an explore report, or one journey graded from the drive when unplanned. */
45
+ export declare function journeysOf(report: Record<string, unknown>, persona?: string): TryJourney[];
46
+ /** What `try` borrows from the cloud commands, passed in so neither module imports the other. */
47
+ export interface TryCloud {
48
+ push: () => Promise<number>;
49
+ dashboardUrl: (cloud: CloudConfig) => Promise<string | undefined>;
50
+ }
51
+ /** `reticle try`, wired to this machine. Returns the exit code. */
52
+ export declare function cmdTry(argv: readonly string[], cloudCommands: TryCloud): Promise<number>;
53
+ /**
54
+ * How `init` ends once the connection is proved: what Reticle sees of the app, what it is missing,
55
+ * and the prompt that hands the rest to the coding agent, which proves the first flow. `init` never
56
+ * drives: the Harness is opt-in and unlocks at a coverage score (core's `instrumentation-coverage.ts`), and a
57
+ * freshly wired app is rarely there yet.
58
+ *
59
+ * Read from the daemon's `/status`, the same coverage `doctor` prints, so the two never disagree.
60
+ */
61
+ /** What a project that is not linked is told, once, at the end. */
62
+ export declare const UNLINKED_PITCH: string[];
63
+ /** Prove one flow with the coding agent: the line every ending names. */
64
+ export declare const msgProveOneFlow: (url: string) => string;
65
+ /**
66
+ * The closing lines for one tab's coverage, as `/status` reports it: the score, what is missing, the
67
+ * Harness gate in its own sentence, and the prompt for the coding agent. Pure.
68
+ */
69
+ export declare function initCoverageLines(tab: Record<string, unknown> | undefined, url: string): string[];
70
+ /**
71
+ * This project's runs and flows that will never reach the dashboard as things stand, one line each:
72
+ * not linked, no key for its host, flow sync off, or refused. A linked root's pending runs are left
73
+ * out, because the daemon sends them within seconds and saying so would be noise.
74
+ */
75
+ export declare function strandedWorkLines(appDir: string): Promise<string[]>;
76
+ /** What `init` hands its ending, once the connection is proved. */
77
+ export interface FirstFlowContext {
78
+ appDir: string;
79
+ bridgePort: number;
80
+ pairingToken?: string | undefined;
81
+ url: string;
82
+ sessionId: string;
83
+ /** The proof came from a Reticle-owned browser, now closed: its own tab cannot be measured. */
84
+ leased: boolean;
85
+ openBrowser: boolean;
86
+ /** False for `--no-first-run`: connect, and say nothing more. */
87
+ firstRun: boolean;
88
+ json: boolean;
89
+ }
90
+ /**
91
+ * How `init` ends: the coverage score, the gaps and the agent prompt, the pitch when the project is
92
+ * not linked, then what will never reach the dashboard. Nothing is driven. Never throws.
93
+ */
94
+ export declare function initFirstFlow(ctx: FirstFlowContext, say: (line: string) => void): Promise<{
95
+ flowSaved: boolean;
96
+ }>;
@@ -0,0 +1,362 @@
1
+ /**
2
+ * `reticle try <url>`: one free Harness drive of somebody's app, watched in a window, ending in a
3
+ * plain list of which journeys work and which are broken.
4
+ *
5
+ * Sign-in comes first, and on purpose: the drive runs on the platform, so a machine that is not
6
+ * linked could only be told no AFTER a browser had opened, which is the worst moment to say it.
7
+ *
8
+ * The decisions (refuse, ask the platform, drive, summarise, sync) are `runTry`, behind `TryPorts`, so
9
+ * every branch is tested without a browser, a daemon or a network. The verdicts in the summary are the
10
+ * engine's: a journey that neither passed nor failed is "not proved", never rounded up to "works".
11
+ */
12
+ import { existsSync } from 'node:fs';
13
+ import { homedir } from 'node:os';
14
+ import { join } from 'node:path';
15
+ import { RETICLE_DEFAULT_PORT, ReticleDir, ReticleEnv, RunFlowStatus, ScriptStatus, asRecord, driveFlowStatus, } from '@reticlehq/core';
16
+ import { FreeDriveKind, planUrl, requestFreeDrive, } from '../../features/harness/platform/platform-drives.js';
17
+ import { linkedCloudPort, resolveProjectCloud } from '../../memory/cloud/cloud-config.js';
18
+ import { describeUnsynced, unsyncedRoots } from '../../memory/cloud/unsynced-roots.js';
19
+ import { createNodeFileSystem } from '../../memory/project/fs/fs-port.js';
20
+ import { defaultPairingTokenDir, readOrCreatePairingTokenSync, } from '../../portal/bridge/pairing-token.js';
21
+ import { spawnDaemon } from '../daemon/daemon.js';
22
+ import { PortPresence, describePresence, presenceIsUsable, probePresence, } from '../daemon/binding/port-presence.js';
23
+ import { fetchStatus } from '../daemon/binding/daemon-status-probe.js';
24
+ import { probeDaemon, waitForDaemonBind } from '../../surface/mcp/mcp-proxy.js';
25
+ import { readProjectPort } from './ports/resolve/cli-port.js';
26
+ import { callerArtifactRoot } from '../../memory/project/link-directory.js';
27
+ import { seeRunLine } from '../../memory/project/sync-status.js';
28
+ import { DAEMON_INNER_COMMAND, PORT_FLAG } from './cli-parse.js';
29
+ import { acquireLease, connectOverSse, endpointFor, exploreToEnd, refusalText, releaseLease, verdictOf, } from './adhoc-verdict.js';
30
+ export const MSG_SIGN_IN_FIRST = 'Sign in first: reticle connect (it is free, no card)';
31
+ const PERSONA_FLAG = '--persona';
32
+ /** The whole drive, model turns and browser included, before the CLI stops waiting for it. */
33
+ export const TRY_BUDGET_MS = 120_000;
34
+ /** Model turns in the one free drive. Bounds what it costs, not what it may find. */
35
+ export const TRY_MAX_STEPS = 40;
36
+ /** How long to wait for the daemon to write the drive's run once the tab is closed. */
37
+ const RUN_WRITE_WAIT_MS = 10_000;
38
+ const RUN_WRITE_POLL_MS = 250;
39
+ const EXIT_OK = 0;
40
+ const EXIT_FAIL = 1;
41
+ /** `try <url> [--persona <who>]`, or the sentence that says what is missing. */
42
+ export function parseTryArgs(argv) {
43
+ let url;
44
+ let persona;
45
+ for (let i = 0; i < argv.length; i++) {
46
+ const arg = argv[i];
47
+ if (arg === PERSONA_FLAG) {
48
+ persona = argv[i + 1];
49
+ if (persona === undefined)
50
+ return { error: `${PERSONA_FLAG} needs a value` };
51
+ i++;
52
+ }
53
+ else if (arg !== undefined && arg.startsWith('--')) {
54
+ return { error: `unknown argument '${arg}'` };
55
+ }
56
+ else if (url === undefined) {
57
+ url = arg;
58
+ }
59
+ else {
60
+ return { error: `unknown argument '${String(arg)}'` };
61
+ }
62
+ }
63
+ if (url === undefined)
64
+ return { error: 'usage: reticle try <url> [--persona <who>]' };
65
+ return persona === undefined ? { url } : { url, persona };
66
+ }
67
+ const WORKS = new Set([ScriptStatus.PASSED]);
68
+ const BROKEN = new Set([ScriptStatus.FAILED]);
69
+ /** The summary, worst news last so it is the line a reader's eye lands on. Pure. */
70
+ export function summarizeTry(journeys) {
71
+ // A branch whose condition did not hold was never a journey this app took.
72
+ const tried = journeys.filter((j) => ScriptStatus.NOT_TAKEN !== j.status);
73
+ const works = tried.filter((j) => WORKS.has(j.status)).length;
74
+ const broken = tried.filter((j) => BROKEN.has(j.status)).length;
75
+ const unproved = tried.length - works - broken;
76
+ const head = `Tried ${String(tried.length)} journey${1 === tried.length ? '' : 's'}: ` +
77
+ `${String(works)} work, ${String(broken)} broken` +
78
+ (0 === unproved ? '' : `, ${String(unproved)} not proved`);
79
+ return [
80
+ head,
81
+ ...tried.map((j) => WORKS.has(j.status)
82
+ ? ` ✓ works: ${j.title}`
83
+ : BROKEN.has(j.status)
84
+ ? ` ✗ broken: ${j.title}`
85
+ : ` ? not proved (${j.status}): ${j.title}`),
86
+ ];
87
+ }
88
+ export async function runTry(args, ports) {
89
+ const cloud = await ports.linked();
90
+ if (null === cloud) {
91
+ ports.fail(MSG_SIGN_IN_FIRST);
92
+ return EXIT_FAIL;
93
+ }
94
+ const grant = await ports.requestDrive(cloud);
95
+ if (!grant.granted) {
96
+ ports.fail(grant.message);
97
+ if (grant.hint !== undefined)
98
+ ports.fail(grant.hint);
99
+ if (grant.needsCard) {
100
+ const base = (await ports.dashboardUrl(cloud).catch(() => undefined)) ?? cloud.url;
101
+ ports.fail(`Plans: ${planUrl(base)}`);
102
+ }
103
+ return EXIT_FAIL;
104
+ }
105
+ ports.out(`Driving ${args.url} — watch the window Reticle opens.`);
106
+ const drive = await ports.drive({
107
+ url: args.url,
108
+ driveId: grant.driveId,
109
+ ...(args.persona === undefined ? {} : { persona: args.persona }),
110
+ });
111
+ if (drive.error !== undefined) {
112
+ ports.fail(drive.error);
113
+ return EXIT_FAIL;
114
+ }
115
+ for (const line of summarizeTry(drive.journeys))
116
+ ports.out(line);
117
+ // Saying "saved" over a sync that failed would be this command lying about its own work.
118
+ if (await ports.sync(drive.runIds).catch(() => false)) {
119
+ const dashboard = await ports.dashboardUrl(cloud).catch(() => undefined);
120
+ // Each run on its own page when the dashboard is known; the dashboard itself otherwise.
121
+ const lines = dashboard === undefined || 0 === drive.runIds.length
122
+ ? [`Saved to your dashboard: ${dashboard ?? cloud.url}`]
123
+ : drive.runIds.map((runId) => seeRunLine(dashboard, runId));
124
+ for (const line of lines)
125
+ ports.out(line);
126
+ }
127
+ else {
128
+ ports.fail('The run is kept on this machine; it could not be sent. Run `reticle sync` to retry.');
129
+ }
130
+ return EXIT_OK;
131
+ }
132
+ const str = (value) => ('string' === typeof value ? value : undefined);
133
+ /** The journeys out of an explore report, or one journey graded from the drive when unplanned. */
134
+ export function journeysOf(report, persona) {
135
+ const listed = report['journeys'];
136
+ if (Array.isArray(listed) && 0 < listed.length) {
137
+ return listed.flatMap((item) => {
138
+ const j = item;
139
+ const title = str(j['title']);
140
+ const status = str(j['status']);
141
+ return title === undefined || status === undefined ? [] : [{ title, status }];
142
+ });
143
+ }
144
+ // An unplanned drive is one journey, graded by the one rule every drive is: failed only when a
145
+ // check came back no. A missed goal or undecided checks prove nothing either way.
146
+ const checks = asRecord(report['checks']);
147
+ const count = (key) => ('number' === typeof checks[key] ? checks[key] : 0);
148
+ const goalMet = report['goalMet'];
149
+ const flow = driveFlowStatus({
150
+ held: count('held'),
151
+ failed: count('failed'),
152
+ ...('boolean' === typeof goalMet ? { goalMet } : {}),
153
+ });
154
+ const status = RunFlowStatus.FAIL === flow
155
+ ? ScriptStatus.FAILED
156
+ : RunFlowStatus.PASS === flow
157
+ ? ScriptStatus.PASSED
158
+ : ScriptStatus.BLOCKED;
159
+ return [{ title: persona ?? 'Autonomous drive', status }];
160
+ }
161
+ function tryPort(cwd) {
162
+ const fromEnv = Number(process.env[ReticleEnv.PORT]);
163
+ if (Number.isInteger(fromEnv) && 0 < fromEnv)
164
+ return fromEnv;
165
+ return readProjectPort(cwd) ?? RETICLE_DEFAULT_PORT;
166
+ }
167
+ /** A daemon serving `port`: the one already there, or one started now. Undefined when ready. */
168
+ async function ensureTryDaemon(port) {
169
+ const presence = await probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus });
170
+ if (presenceIsUsable(presence))
171
+ return undefined;
172
+ // A stranger on the port: a daemon spawned now could not bind, so say who holds it instead.
173
+ if (PortPresence.FREE !== presence)
174
+ return describePresence(presence, port);
175
+ const script = process.argv[1];
176
+ if (script === undefined)
177
+ return 'Cannot locate the reticle daemon script.';
178
+ spawnDaemon(process.execPath, script, [DAEMON_INNER_COMMAND, PORT_FLAG, String(port)], port);
179
+ return (await waitForDaemonBind(port))
180
+ ? undefined
181
+ : `Could not start the Reticle daemon on port ${String(port)}.`;
182
+ }
183
+ /** The drive itself, through the daemon: a watched window, the zero-install reader, one explore. */
184
+ async function driveThroughDaemon(port, request,
185
+ /** Where the drive's run must land: the folder `try` waits on and pushes from. */
186
+ reticleRoot) {
187
+ const unavailable = await ensureTryDaemon(port);
188
+ if (unavailable !== undefined)
189
+ return { journeys: [], runIds: [], error: unavailable };
190
+ const token = readOrCreatePairingTokenSync(defaultPairingTokenDir());
191
+ const caller = await connectOverSse(endpointFor(port, token));
192
+ try {
193
+ // Headed whatever the daemon was started as: the point of `try` is watching it happen. An app
194
+ // with no Reticle SDK gets one supplied by the lease.
195
+ const opened = await acquireLease(caller, request.url, true, reticleRoot);
196
+ if ('failed' in opened)
197
+ return { journeys: [], runIds: [], error: opened.failed.join('\n') };
198
+ try {
199
+ const drove = await exploreToEnd(caller, {
200
+ sessionId: opened.leased,
201
+ driveId: request.driveId,
202
+ maxSteps: TRY_MAX_STEPS,
203
+ ...(request.persona === undefined ? {} : { persona: request.persona }),
204
+ }, TRY_BUDGET_MS);
205
+ const refusal = refusalText(drove);
206
+ if (refusal !== undefined)
207
+ return { journeys: [], runIds: [], error: refusal };
208
+ const report = verdictOf(drove, 'stopReason') ?? {};
209
+ const runIds = Array.isArray(report['runIds'])
210
+ ? report['runIds'].filter((id) => 'string' === typeof id)
211
+ : [];
212
+ const broke = str(report['error']);
213
+ return {
214
+ journeys: journeysOf(report, request.persona),
215
+ runIds,
216
+ ...(broke === undefined ? {} : { error: `The drive broke: ${broke}` }),
217
+ };
218
+ }
219
+ finally {
220
+ // Closing the tab is what ends the session, and the session's end is what writes the run.
221
+ await releaseLease(caller, opened.leased);
222
+ }
223
+ }
224
+ finally {
225
+ await caller.close().catch(() => undefined);
226
+ }
227
+ }
228
+ /** Wait, bounded, for the daemon to write the drive's runs; a run that never lands is not sent. */
229
+ async function waitForRuns(reticleRoot, runIds) {
230
+ const runsDir = join(reticleRoot, ReticleDir.RUNS_SUBDIR);
231
+ for (let waited = 0; waited < RUN_WRITE_WAIT_MS; waited += RUN_WRITE_POLL_MS) {
232
+ if (runIds.every((id) => existsSync(join(runsDir, `${id}.json`))))
233
+ return;
234
+ await new Promise((resolve) => setTimeout(resolve, RUN_WRITE_POLL_MS));
235
+ }
236
+ }
237
+ /** `reticle try`, wired to this machine. Returns the exit code. */
238
+ export async function cmdTry(argv, cloudCommands) {
239
+ const parsed = parseTryArgs(argv);
240
+ if ('error' in parsed) {
241
+ process.stderr.write(`${parsed.error}\n`);
242
+ return EXIT_FAIL;
243
+ }
244
+ const cwd = process.cwd();
245
+ // The project this folder belongs to, else this folder: the lease writes the run here, and this is
246
+ // where try waits for it and pushes it from — wherever the daemon happened to be started.
247
+ const reticleRoot = callerArtifactRoot(cwd) ?? join(cwd, ReticleDir.ROOT);
248
+ const port = tryPort(cwd);
249
+ return runTry(parsed, {
250
+ linked: linkedCloudPort(createNodeFileSystem(), reticleRoot, homedir(), process.env),
251
+ requestDrive: (cloud) => requestFreeDrive(cloud, FreeDriveKind.TRY),
252
+ drive: (request) => driveThroughDaemon(port, request, reticleRoot),
253
+ sync: async (runIds) => {
254
+ await waitForRuns(reticleRoot, runIds);
255
+ return EXIT_OK === (await cloudCommands.push());
256
+ },
257
+ dashboardUrl: cloudCommands.dashboardUrl,
258
+ out: (line) => process.stdout.write(`${line}\n`),
259
+ fail: (line) => process.stderr.write(`${line}\n`),
260
+ });
261
+ }
262
+ // ── how `init` ends ───────────────────────────────────────────────────────────────────────
263
+ /**
264
+ * How `init` ends once the connection is proved: what Reticle sees of the app, what it is missing,
265
+ * and the prompt that hands the rest to the coding agent, which proves the first flow. `init` never
266
+ * drives: the Harness is opt-in and unlocks at a coverage score (core's `instrumentation-coverage.ts`), and a
267
+ * freshly wired app is rarely there yet.
268
+ *
269
+ * Read from the daemon's `/status`, the same coverage `doctor` prints, so the two never disagree.
270
+ */
271
+ /** What a project that is not linked is told, once, at the end. */
272
+ export const UNLINKED_PITCH = [
273
+ 'Results stay on this machine. `reticle connect` saves them to your dashboard and lets Reticle',
274
+ 'Harness test the whole app: a new account gets 10 free credits.',
275
+ ];
276
+ /** Prove one flow with the coding agent: the line every ending names. */
277
+ export const msgProveOneFlow = (url) => `Then ask your coding agent: "Use Reticle to prove one flow in ${url}: drive it, and end with ` +
278
+ 'reticle_act_and_wait and an until on the last step."';
279
+ const names = (value) => Array.isArray(value)
280
+ ? value.flatMap((item) => {
281
+ const name = 'object' === typeof item && null !== item
282
+ ? item['capability']
283
+ : item;
284
+ return 'string' === typeof name ? [name] : [];
285
+ })
286
+ : [];
287
+ /**
288
+ * The closing lines for one tab's coverage, as `/status` reports it: the score, what is missing, the
289
+ * Harness gate in its own sentence, and the prompt for the coding agent. Pure.
290
+ */
291
+ export function initCoverageLines(tab, url) {
292
+ const gate = asRecord(tab?.['harnessGate']);
293
+ const percent = gate['percent'];
294
+ if (tab === undefined || 'number' !== typeof percent)
295
+ return [
296
+ 'Instrumentation is measured on an open tab of the app: run `reticle doctor` with it open.',
297
+ msgProveOneFlow(url),
298
+ ];
299
+ const unseen = [...names(tab['missing']), ...names(tab['notSeenYet'])];
300
+ const reason = gate['reason'];
301
+ const prompt = tab['prompt'];
302
+ return [
303
+ `Instrumentation: ${String(percent)}%` +
304
+ (0 === unseen.length ? '' : ` — missing: ${unseen.join(', ')}`),
305
+ 'string' === typeof reason
306
+ ? reason
307
+ : `Harness can be switched on: it is off until you switch it on in the HUD's Settings.`,
308
+ ...('string' === typeof prompt
309
+ ? [
310
+ 'Paste this into your coding agent; it closes the gaps and proves the first flow:',
311
+ ...prompt.split('\n').map((line) => ` ${line}`),
312
+ ]
313
+ : [msgProveOneFlow(url)]),
314
+ ];
315
+ }
316
+ /** The project's own `.reticle`, where the drive's flow and run land and where its link lives. */
317
+ const projectRoot = (appDir) => callerArtifactRoot(appDir) ?? join(appDir, ReticleDir.ROOT);
318
+ /**
319
+ * This project's runs and flows that will never reach the dashboard as things stand, one line each:
320
+ * not linked, no key for its host, flow sync off, or refused. A linked root's pending runs are left
321
+ * out, because the daemon sends them within seconds and saying so would be noise.
322
+ */
323
+ export async function strandedWorkLines(appDir) {
324
+ const fs = createNodeFileSystem();
325
+ const cloud = () => resolveProjectCloud(fs, projectRoot(appDir), homedir(), process.env);
326
+ const roots = await unsyncedRoots([projectRoot(appDir)], async () => {
327
+ const c = await cloud();
328
+ return null !== c.config && null !== c.projectId;
329
+ }, async () => (await cloud()).policy.flows);
330
+ return roots
331
+ .filter((entry) => !entry.linked || 0 < entry.flows)
332
+ .map((entry) => `⚠ ${describeUnsynced(entry, appDir)}`);
333
+ }
334
+ /** The tab `init` proved, out of `/status`: by session, else the only one on the same url. */
335
+ function tabIn(status, sessionId, url) {
336
+ const list = asRecord(status)['coverage'];
337
+ if (!Array.isArray(list))
338
+ return undefined;
339
+ const tabs = list.map((entry) => asRecord(entry));
340
+ return (tabs.find((tab) => sessionId === tab['sessionId']) ??
341
+ tabs.find((tab) => 'string' === typeof tab['url'] && tab['url'].startsWith(url)));
342
+ }
343
+ /**
344
+ * How `init` ends: the coverage score, the gaps and the agent prompt, the pitch when the project is
345
+ * not linked, then what will never reach the dashboard. Nothing is driven. Never throws.
346
+ */
347
+ export async function initFirstFlow(ctx, say) {
348
+ if (ctx.firstRun) {
349
+ // A leased proof's tab has closed; another open tab of the same app still answers for it.
350
+ const status = await fetchStatus(ctx.bridgePort).catch(() => undefined);
351
+ say('');
352
+ for (const line of initCoverageLines(tabIn(status, ctx.sessionId, ctx.url), ctx.url))
353
+ say(line);
354
+ const linked = linkedCloudPort(createNodeFileSystem(), projectRoot(ctx.appDir), homedir(), process.env);
355
+ if (null === (await linked().catch(() => null)))
356
+ for (const line of UNLINKED_PITCH)
357
+ say(line);
358
+ }
359
+ for (const line of await strandedWorkLines(ctx.appDir).catch(() => []))
360
+ say(line);
361
+ return { flowSaved: false };
362
+ }