@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
@@ -84,8 +84,9 @@ The cheapest path that answers the question:
84
84
  - "did my edit break anything?" -> \`reticle_verify { action: "change", files: [...] }\`
85
85
  - "does this known journey still work?" -> \`reticle_verify { action: "flows", names: ["..."] }\`
86
86
  - "does this new behaviour work?" -> \`reticle_act { steps: [...] }\` for the setup, then ONE \`reticle_act_and_wait\`
87
- - "nothing is recorded yet" -> \`reticle_verify { action: "explore", persona: "<who does what>" }\`, which
88
- drives the app and SAVES what it drove, so the next run replays with no model in the loop
87
+ - "nothing is recorded yet" -> drive the journey yourself with \`reticle_act_and_wait\` and an \`until\` on its
88
+ last step; it is saved as a flow, so the next run replays with no model in the loop. With a linked
89
+ project, \`reticle_verify { action: "explore", persona: "<who does what>" }\` drives it for you
89
90
  `;
90
91
  /**
91
92
  * Write the skill for agents that have somewhere to put it, and only where they are installed.
@@ -12,4 +12,6 @@
12
12
  */
13
13
  import { PortPresence } from '../../daemon/binding/port-presence.js';
14
14
  /** The refusal to print, or undefined when the port is usable. */
15
- export declare function bridgeOccupied(presence: PortPresence, port: number): string | undefined;
15
+ export declare function bridgeOccupied(presence: PortPresence, port: number, freePort?: number): string | undefined;
16
+ /** The first port after `port` that nothing answers on, or undefined within the scan. */
17
+ export declare function freePortAfter(port: number, isOpen: (port: number) => Promise<boolean>): Promise<number | undefined>;
@@ -12,13 +12,23 @@
12
12
  */
13
13
  import { PortPresence } from '../../daemon/binding/port-presence.js';
14
14
  /** The refusal to print, or undefined when the port is usable. */
15
- export function bridgeOccupied(presence, port) {
15
+ export function bridgeOccupied(presence, port, freePort) {
16
16
  // DAEMON is the ordinary case — that is the daemon init is about to use. FREE is fine too: one
17
17
  // gets started. Only a stranger is fatal.
18
18
  if (PortPresence.FOREIGN !== presence)
19
19
  return undefined;
20
20
  return (`port ${String(port)} is held by something that is not a Reticle daemon. That is the bridge — ` +
21
21
  'the channel between the daemon and the SDK in your page — so no session can ever appear while ' +
22
- 'it is occupied, however correct the wiring is. Free it, or re-run with --port <n> and set the ' +
23
- 'same port in .reticle.json.');
22
+ 'it is occupied, however correct the wiring is. Free it, or re-run on another port (init moves ' +
23
+ `the config and the page with it): reticle init --port ${freePort === undefined ? '<n>' : String(freePort)}`);
24
+ }
25
+ /** How many ports past the held one are tried before giving up on a suggestion. */
26
+ const FREE_PORT_SCAN = 20;
27
+ /** The first port after `port` that nothing answers on, or undefined within the scan. */
28
+ export async function freePortAfter(port, isOpen) {
29
+ for (let candidate = port + 1; candidate <= port + FREE_PORT_SCAN; candidate++) {
30
+ if (!(await isOpen(candidate)))
31
+ return candidate;
32
+ }
33
+ return undefined;
24
34
  }
@@ -9,6 +9,7 @@
9
9
  /** A lease this run opened, and the way to hand it back; or why it could not be opened. */
10
10
  type LeaseOutcome = {
11
11
  readonly sessionId: string;
12
+ readonly zeroInstall: boolean;
12
13
  readonly release: () => Promise<void>;
13
14
  } | {
14
15
  readonly failed: string;
@@ -25,6 +25,7 @@ export async function openLeaseFor(port, url, token) {
25
25
  }
26
26
  return {
27
27
  sessionId: got.leased,
28
+ zeroInstall: got.zeroInstall,
28
29
  release: async () => {
29
30
  await releaseLease(caller, got.leased);
30
31
  await close();
@@ -101,6 +101,8 @@ function main(argv) {
101
101
  const child = spawn(command, {
102
102
  shell: true,
103
103
  stdio: ['ignore', 'pipe', 'pipe'],
104
+ // This supervisor runs detached with no console on Windows, so the shell would open a window.
105
+ windowsHide: true,
104
106
  env: process.env,
105
107
  });
106
108
  child.stdout.on('data', (chunk) => log.write(chunk));
@@ -59,6 +59,14 @@ export declare const WAIT_CEILING_MS: number;
59
59
  */
60
60
  export declare function judgeWait(facts: WaitFacts): WaitVerdict;
61
61
  export declare function portBusyMessage(output: string): string | undefined;
62
+ /**
63
+ * The dev server died before serving: say so, and quote the end of what it printed.
64
+ *
65
+ * Without the tail the reason was invisible: a missing `vite` binary printed `vite: command not
66
+ * found` to its own log, setup said only "exited without serving anything", and its first remedy
67
+ * ("start the dev server yourself") failed the same way.
68
+ */
69
+ export declare function devServerDiedMessage(output: string): string;
62
70
  export declare function announcedUrl(output: string): string | undefined;
63
71
  /**
64
72
  * The url to watch: whatever the tool announced, else one composed from a port we OBSERVED our own
@@ -61,6 +61,25 @@ export function portBusyMessage(output) {
61
61
  return (`port ${port} is already in use — something else is serving there, so this launcher did not ` +
62
62
  `bind. Pass --url http://localhost:${port} if that process is this app, or free the port and re-run.`);
63
63
  }
64
+ /** How many of the dev server's last lines a failure quotes. Enough for a stack's first frames. */
65
+ const DIED_TAIL_LINES = 6;
66
+ /**
67
+ * The dev server died before serving: say so, and quote the end of what it printed.
68
+ *
69
+ * Without the tail the reason was invisible: a missing `vite` binary printed `vite: command not
70
+ * found` to its own log, setup said only "exited without serving anything", and its first remedy
71
+ * ("start the dev server yourself") failed the same way.
72
+ */
73
+ export function devServerDiedMessage(output) {
74
+ const tail = output
75
+ .split('\n')
76
+ .map((line) => line.trimEnd())
77
+ .filter((line) => 0 < line.trim().length)
78
+ .slice(-DIED_TAIL_LINES);
79
+ return 0 === tail.length
80
+ ? 'The dev server exited without serving anything, and printed nothing.'
81
+ : `The dev server exited without serving anything. The last it printed:\n${tail.map((line) => ` ${line}`).join('\n')}`;
82
+ }
64
83
  /** A url the dev server announced, if it has announced one. Never composed, only read. */
65
84
  const URL_IN_OUTPUT = /https?:\/\/(?:localhost|127\.0\.0\.1|\[::1\]):\d+/;
66
85
  export function announcedUrl(output) {
@@ -24,7 +24,7 @@ import { readDaemonRegistry } from '../../daemon/daemon-resolve.js';
24
24
  import { LOOPBACK_HOST, STATUS_HOLD_MS } from '@reticlehq/core';
25
25
  import { probePresence, presenceIsUsable } from '../../daemon/binding/port-presence.js';
26
26
  import { probeDaemon, waitForDaemonBind } from '../../../surface/mcp/mcp-proxy.js';
27
- import { daemonSpawnArgs } from '../../cli/daemon-start-options.js';
27
+ import { daemonSpawnArgs, headlessByDefault } from '../../cli/daemon-start-options.js';
28
28
  import { fetchStatus, summarizeStatus } from '../../daemon/binding/daemon-status-probe.js';
29
29
  import { runKill } from '../../cli/cli-kill.js';
30
30
  export const EnsureDaemon = {
@@ -154,7 +154,14 @@ export function nodeEnsureDaemonDeps(skewed) {
154
154
  const scriptPath = process.argv[1];
155
155
  if (undefined === scriptPath)
156
156
  return false;
157
- const started = spawnDaemon(process.execPath, scriptPath, daemonSpawnArgs({ port, headless: true, http: false }), port);
157
+ const started = spawnDaemon(process.execPath, scriptPath,
158
+ // The daemon init starts is the one the agent attaches to and drives through, so it follows
159
+ // the same rule as every other: shown on a desktop, hidden in CI or with no display.
160
+ daemonSpawnArgs({
161
+ port,
162
+ headless: headlessByDefault(process.env, process.platform),
163
+ http: false,
164
+ }), port);
158
165
  // For a log or a pipe. On a terminal it was a JSON line in the middle of `init`'s output, read
159
166
  // by a person, about a step the next lines already report in words.
160
167
  if (true !== process.stderr.isTTY)
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Whether the agent that ran `init` has to restart before it can use what `init` set up.
3
+ *
4
+ * An agent client reads its MCP server list when it STARTS and never re-reads it. So the session
5
+ * that ran `init` has the `reticle_*` tools only if Reticle was registered before it started, and
6
+ * nothing a running session does can add them: there is no server entry in it to reconnect. The
7
+ * honest answer is a restart, said plainly, once `init` can tell it is needed.
8
+ *
9
+ * Two ways to tell. This run registered the server (it cannot be in any open session), or `init`
10
+ * runs inside an agent and the daemon has no agent attached, which is what an agent with the tools
11
+ * always has. Pure: the facts come in, the sentence comes out.
12
+ */
13
+ export interface RestartFacts {
14
+ /** `init` was spawned by a coding agent (Claude Code, Codex), not typed by a person. */
15
+ readonly insideAgent: boolean;
16
+ /** This run registered the MCP server, so no open session has it. */
17
+ readonly newlyRegistered: boolean;
18
+ /** MCP clients attached to the daemon on this port; undefined when the daemon could not be asked. */
19
+ readonly attached: number | undefined;
20
+ }
21
+ export declare function restartNotice(facts: RestartFacts): string | undefined;
22
+ /** How many agents' MCP clients the daemon's `/status` lists, or undefined for no answer. */
23
+ export declare function attachedAgents(status: unknown): number | undefined;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Whether the agent that ran `init` has to restart before it can use what `init` set up.
3
+ *
4
+ * An agent client reads its MCP server list when it STARTS and never re-reads it. So the session
5
+ * that ran `init` has the `reticle_*` tools only if Reticle was registered before it started, and
6
+ * nothing a running session does can add them: there is no server entry in it to reconnect. The
7
+ * honest answer is a restart, said plainly, once `init` can tell it is needed.
8
+ *
9
+ * Two ways to tell. This run registered the server (it cannot be in any open session), or `init`
10
+ * runs inside an agent and the daemon has no agent attached, which is what an agent with the tools
11
+ * always has. Pure: the facts come in, the sentence comes out.
12
+ */
13
+ const RESTART_NOW = 'Restart your coding agent now: this session started before Reticle was registered with it, so ' +
14
+ 'the `reticle_*` tools are not in it, and an agent loads its tools only when it starts. ' +
15
+ '`npx @reticlehq/server init --relaunch` prints the exact resume command for Claude Code and ' +
16
+ 'Codex. Once per machine.';
17
+ export function restartNotice(facts) {
18
+ if (facts.newlyRegistered)
19
+ return RESTART_NOW;
20
+ return facts.insideAgent && 0 === facts.attached ? RESTART_NOW : undefined;
21
+ }
22
+ /** How many agents' MCP clients the daemon's `/status` lists, or undefined for no answer. */
23
+ export function attachedAgents(status) {
24
+ if ('object' !== typeof status || null === status)
25
+ return undefined;
26
+ const peers = status.mcpPeers;
27
+ return Array.isArray(peers) ? peers.length : 0;
28
+ }
@@ -1,3 +1,10 @@
1
+ /**
2
+ * The port a project asks for when the default is somebody else's: its own, from its id (or its
3
+ * directory, before it has one), the same on every run. Every project used to ask for the default
4
+ * plus one, so with the first one's daemon not yet running every later project was written the same
5
+ * port and shared it. Taken ports are still skipped by the caller's `pickPort`.
6
+ */
7
+ export declare function projectPortFor(seed: string): number;
1
8
  /**
2
9
  * `RETICLE_PORT`, when it names a port. The one reader of it for the CLI, `init` included.
3
10
  *
@@ -12,4 +19,10 @@ export declare function portForInit(explicit: number | undefined, configured: nu
12
19
  daemonProjects: (port: number) => Promise<readonly string[]>;
13
20
  daemonPresent: (port: number) => Promise<boolean>;
14
21
  pickPort: (preferred: number) => Promise<number>;
15
- }): Promise<number | undefined>;
22
+ /** The daemon on `port` was started from this project's directory or one above it. */
23
+ daemonStartedHere?: (port: number) => boolean;
24
+ },
25
+ /** The project's directory: the port's seed when the project has no id yet. */
26
+ dir?: string): Promise<number | undefined>;
27
+ /** Is `dir` the same directory as `cwd`, or an ancestor of it? */
28
+ export declare function isSameOrAbove(dir: string, cwd: string): boolean;
@@ -8,8 +8,26 @@
8
8
  *
9
9
  * Undefined means the default.
10
10
  */
11
+ import { relative, isAbsolute } from 'node:path';
11
12
  import { RETICLE_DEFAULT_PORT, ReticleEnv } from '@reticlehq/core';
12
13
  const MAX_PORT = 65_535;
14
+ /** Ports a project moved off the default may get: above it, and below the 5000s dev servers use. */
15
+ const PROJECT_PORT_FIRST = RETICLE_DEFAULT_PORT + 1;
16
+ const PROJECT_PORT_SPAN = 599;
17
+ const FNV_OFFSET = 0x811c9dc5;
18
+ const FNV_PRIME = 0x01000193;
19
+ /**
20
+ * The port a project asks for when the default is somebody else's: its own, from its id (or its
21
+ * directory, before it has one), the same on every run. Every project used to ask for the default
22
+ * plus one, so with the first one's daemon not yet running every later project was written the same
23
+ * port and shared it. Taken ports are still skipped by the caller's `pickPort`.
24
+ */
25
+ export function projectPortFor(seed) {
26
+ let hash = FNV_OFFSET;
27
+ for (let i = 0; i < seed.length; i++)
28
+ hash = Math.imul(hash ^ seed.charCodeAt(i), FNV_PRIME);
29
+ return PROJECT_PORT_FIRST + ((hash >>> 0) % PROJECT_PORT_SPAN);
30
+ }
13
31
  /**
14
32
  * `RETICLE_PORT`, when it names a port. The one reader of it for the CLI, `init` included.
15
33
  *
@@ -25,7 +43,9 @@ export function portFromEnv(env) {
25
43
  const port = Number(raw);
26
44
  return 0 < port && port <= MAX_PORT ? port : undefined;
27
45
  }
28
- export async function portForInit(explicit, configured, projectId, deps) {
46
+ export async function portForInit(explicit, configured, projectId, deps,
47
+ /** The project's directory: the port's seed when the project has no id yet. */
48
+ dir) {
29
49
  if (explicit !== undefined)
30
50
  return explicit;
31
51
  if (configured !== undefined)
@@ -34,11 +54,21 @@ export async function portForInit(explicit, configured, projectId, deps) {
34
54
  // config as a `port` nobody chose.
35
55
  if (!(await deps.daemonPresent(RETICLE_DEFAULT_PORT)))
36
56
  return undefined;
57
+ // Started here — by this project's own editor MCP, typically — so it is ours whatever project id
58
+ // it recorded. Moving off it strands that agent: an MCP resolves its port once, at startup.
59
+ if (true === deps.daemonStartedHere?.(RETICLE_DEFAULT_PORT))
60
+ return undefined;
37
61
  // The bridge's own rule: it refuses a page only when it has served exactly ONE other project. A
38
62
  // daemon serving nobody, several projects, or ours accepts this one. A project that has never
39
63
  // been through init has no id yet, so a single named holder is somebody else.
40
64
  const holders = await deps.daemonProjects(RETICLE_DEFAULT_PORT);
41
65
  if (1 !== holders.length || holders[0] === projectId)
42
66
  return undefined;
43
- return deps.pickPort(RETICLE_DEFAULT_PORT + 1);
67
+ const seed = projectId ?? dir;
68
+ return deps.pickPort(seed === undefined ? PROJECT_PORT_FIRST : projectPortFor(seed));
69
+ }
70
+ /** Is `dir` the same directory as `cwd`, or an ancestor of it? */
71
+ export function isSameOrAbove(dir, cwd) {
72
+ const rel = relative(dir, cwd);
73
+ return '' === rel || (!rel.startsWith('..') && !isAbsolute(rel));
44
74
  }
@@ -6,13 +6,25 @@
6
6
  * every command harder to read.
7
7
  */
8
8
  import { type InitResult } from '@reticlehq/init';
9
+ import { type FirstFlowPort } from '../setup-command.js';
10
+ /**
11
+ * Does the served document name the SDK, so its absence means a stale dev server?
12
+ *
13
+ * A Next App Router page names its client components in the flight data inlined into the HTML —
14
+ * `reticle-dev.tsx`, measured on Next 16 under Turbopack and webpack alike. Reported from a Next app
15
+ * whose dev server was already running before init: setup waited on a page that could never connect
16
+ * and said nothing, because Next was assumed to carry the SDK only in its bundle. The Pages Router
17
+ * names chunks, not modules, so it stays silent.
18
+ */
19
+ export declare function htmlCarriesSdk(framework: string, exists: (path: string) => boolean): boolean;
9
20
  /** Just enough of the parsed command to decide and run. */
10
21
  interface InitRuntimeArgs {
11
22
  readonly port: number | undefined;
12
23
  readonly dryRun: boolean;
13
24
  readonly filesOnly?: boolean | undefined;
14
25
  readonly json?: boolean | undefined;
15
- readonly drive?: boolean | undefined;
26
+ /** `--no-first-run` sets it false: connect, and stop without the coverage summary. */
27
+ readonly firstRun?: boolean | undefined;
16
28
  readonly open?: boolean | undefined;
17
29
  readonly agents?: boolean | undefined;
18
30
  /**
@@ -31,9 +43,17 @@ interface InitRuntimeArgs {
31
43
  /** Restart the calling client so IT gets the tools — see relaunch.ts. */
32
44
  readonly relaunch?: boolean | undefined;
33
45
  readonly licenseKey?: string | undefined;
46
+ /**
47
+ * Init is the first half of a longer command (`reticle connect`): a setup that did not finish
48
+ * sets a failing exit code and returns, so the command can still sign in and link. Exiting here
49
+ * ended connect before it signed in, and nothing said to run it again.
50
+ */
51
+ readonly keepGoing?: boolean | undefined;
34
52
  }
35
53
  interface RuntimePrintIo {
36
54
  readonly print: (line: string) => void;
37
55
  }
38
- export declare function continueAfterInit(parsed: InitRuntimeArgs, result: InitResult, io: RuntimePrintIo, cwd: string): Promise<void>;
56
+ export declare function continueAfterInit(parsed: InitRuntimeArgs, result: InitResult, io: RuntimePrintIo, cwd: string,
57
+ /** init's ending once the connection is proved: coverage and the agent prompt. See `FirstFlowPort`. */
58
+ firstFlow?: FirstFlowPort): Promise<void>;
39
59
  export {};
@@ -6,22 +6,27 @@
6
6
  * every command harder to read.
7
7
  */
8
8
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
9
+ import { join } from 'node:path';
9
10
  import { InitConfirmation, RETICLE_DEFAULT_PORT } from '@reticlehq/core';
10
11
  import { FEEDBACK_HINT, Framework, InitFailure } from '@reticlehq/init';
11
12
  import { confirmInstall, nodeConfirmDeps } from '../terminal/confirm.js';
12
13
  import { writeLicenseKey } from '../license-key.js';
13
- import { registerOtherAgents, runSetupCommand } from '../setup-command.js';
14
- import { bridgeOccupied } from '../bringup/bridge-port.js';
14
+ import { registerOtherAgents, runSetupCommand, } from '../setup-command.js';
15
+ import { bridgeOccupied, freePortAfter } from '../bringup/bridge-port.js';
15
16
  import { defaultPairingTokenDir, readOrCreatePairingTokenSync, } from '../../../portal/bridge/pairing-token.js';
16
17
  import { relaunchDecision } from '../bringup/relaunch.js';
18
+ import { attachedAgents, restartNotice } from './agent-restart.js';
17
19
  import { claudeTranscriptExists, codexSessionFor } from '../terminal/transcripts.js';
18
- import { probePresence } from '../../daemon/binding/port-presence.js';
20
+ import { PortPresence, probePresence } from '../../daemon/binding/port-presence.js';
19
21
  import { probeDaemon } from '../../../surface/mcp/proxy/proxy-daemon-probe.js';
20
22
  import { fetchStatus } from '../../daemon/binding/daemon-status-probe.js';
21
23
  import { collectEnv, DEFAULT_PHASE_TIMEOUT_MS } from '../setup-options.js';
22
24
  import { staticPageDevCommand } from '../bringup/static-page-server.js';
23
25
  import { SetupPhase } from '../run-setup.js';
24
26
  import { reportInitOutcome } from '../../../telemetry/init-telemetry.js';
27
+ /** Claude Code marks every process it spawns with this variable set to this value. */
28
+ const CLAUDE_CODE_ENV = 'CLAUDECODE';
29
+ const CLAUDE_CODE_MARKER = '1';
25
30
  /** How often the runtime phases look again: fast enough not to be the wait, slow enough to be free. */
26
31
  const POLL_MS = 250;
27
32
  /**
@@ -30,6 +35,22 @@ const POLL_MS = 250;
30
35
  * of the document can never see it. See `htmlCarriesSdk` in run-setup.ts.
31
36
  */
32
37
  const HTML_CARRIES_SDK = new Set([Framework.VITE, Framework.HTML]);
38
+ /** The connect component `init` writes for a Next App Router project. */
39
+ const NEXT_APP_CONNECT = ['app', 'src/app'].flatMap((d) => ['tsx', 'jsx', 'js'].map((ext) => `${d}/reticle-dev.${ext}`));
40
+ /**
41
+ * Does the served document name the SDK, so its absence means a stale dev server?
42
+ *
43
+ * A Next App Router page names its client components in the flight data inlined into the HTML —
44
+ * `reticle-dev.tsx`, measured on Next 16 under Turbopack and webpack alike. Reported from a Next app
45
+ * whose dev server was already running before init: setup waited on a page that could never connect
46
+ * and said nothing, because Next was assumed to carry the SDK only in its bundle. The Pages Router
47
+ * names chunks, not modules, so it stays silent.
48
+ */
49
+ export function htmlCarriesSdk(framework, exists) {
50
+ if (HTML_CARRIES_SDK.has(framework))
51
+ return true;
52
+ return Framework.NEXT === framework && NEXT_APP_CONNECT.some(exists);
53
+ }
33
54
  /** Registration is global MCP wiring, so both flags that disown it are read here. */
34
55
  function wantsAgents(parsed) {
35
56
  return false !== parsed.agents && false !== parsed.mcp;
@@ -59,8 +80,16 @@ function printRelaunch(parsed, io, cwd) {
59
80
  }).message);
60
81
  io.print('');
61
82
  }
62
- export async function continueAfterInit(parsed, result, io, cwd) {
83
+ export async function continueAfterInit(parsed, result, io, cwd,
84
+ /** init's ending once the connection is proved: coverage and the agent prompt. See `FirstFlowPort`. */
85
+ firstFlow) {
63
86
  const port = parsed.port ?? RETICLE_DEFAULT_PORT;
87
+ const stop = () => {
88
+ if (true === parsed.keepGoing)
89
+ process.exitCode = 1;
90
+ else
91
+ process.exit(1);
92
+ };
64
93
  // Real installs persist the key whichever way setup ends. A preview must leave .env and
65
94
  // .gitignore untouched, just as it leaves project wiring and agent configuration untouched.
66
95
  if (!parsed.dryRun && undefined !== parsed.licenseKey) {
@@ -88,7 +117,7 @@ export async function continueAfterInit(parsed, result, io, cwd) {
88
117
  if (true === parsed.json)
89
118
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
90
119
  if (!result.ok)
91
- process.exit(1);
120
+ stop();
92
121
  });
93
122
  }
94
123
  // From here on init left the ask to us, so it is the last thing on every exit below.
@@ -97,17 +126,31 @@ export async function continueAfterInit(parsed, result, io, cwd) {
97
126
  io.print('');
98
127
  io.print(FEEDBACK_HINT);
99
128
  };
129
+ // `init` deferred its outcome to this phase, so every exit below reports it, and only once: the
130
+ // success path, a failure, a throw and an interrupt can each reach here, and two rows for one run
131
+ // would double the funnel this event exists to measure.
132
+ let outcomeReported = false;
133
+ const reportOnce = (init) => {
134
+ if (outcomeReported)
135
+ return;
136
+ outcomeReported = true;
137
+ reportInitOutcome(init);
138
+ };
100
139
  const context = result.context;
101
140
  if (context === undefined) {
102
- // Nothing was established, so there is nothing to run against. init has already said why.
141
+ // Nothing was established, so there is nothing to run against. init has already said why, and
142
+ // the outcome it deferred (a failed dependency install, usually) is reported here or nowhere.
143
+ if (result.outcome !== undefined)
144
+ reportOnce(result.outcome);
103
145
  ask();
104
146
  if (true === parsed.json)
105
147
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
106
- process.exit(1);
148
+ stop();
149
+ return;
107
150
  }
108
151
  const reportFailure = (reason) => {
109
152
  if (result.outcome !== undefined) {
110
- reportInitOutcome({ ...result.outcome, ok: false, reason });
153
+ reportOnce({ ...result.outcome, ok: false, reason });
111
154
  }
112
155
  };
113
156
  // A PENDING connect step is not a reason to skip the runtime phase, and treating it as one made
@@ -125,10 +168,13 @@ export async function continueAfterInit(parsed, result, io, cwd) {
125
168
  // Before the connect wait, never after: a bridge held by a stranger makes a session impossible,
126
169
  // so going ahead spends the entire budget and then reports what reads as an instrumentation
127
170
  // problem — the one place that is fine. See bridge-port.ts.
128
- const refusal = bridgeOccupied(await probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus }).catch((error) => {
171
+ const presence = await probePresence(port, { tcpOpen: probeDaemon, status: fetchStatus }).catch((error) => {
129
172
  reportFailure(InitFailure.RUNTIME_ERROR);
130
173
  throw error;
131
- }), port);
174
+ });
175
+ const refusal = bridgeOccupied(presence, port, PortPresence.FOREIGN === presence
176
+ ? await freePortAfter(port, (p) => probeDaemon(p))
177
+ : undefined);
132
178
  if (refusal !== undefined) {
133
179
  reportFailure(InitFailure.BRIDGE_OCCUPIED);
134
180
  io.print(refusal);
@@ -136,8 +182,12 @@ export async function continueAfterInit(parsed, result, io, cwd) {
136
182
  if (true === parsed.json) {
137
183
  process.stdout.write(`${JSON.stringify({ ok: false, reason: InitFailure.BRIDGE_OCCUPIED }, null, 2)}\n`);
138
184
  }
139
- process.exit(1);
185
+ stop();
186
+ return;
140
187
  }
188
+ // A Ctrl-C during the wait ends the process with no `finally`, so the outcome is reported from the
189
+ // signal itself. The send is detached, so it survives the exit that follows.
190
+ const releaseInterrupt = reportOnInterrupt(() => reportFailure(InitFailure.INTERRUPTED));
141
191
  return runSetupCommand({
142
192
  appDir: context.appDir,
143
193
  invokedAt: cwd,
@@ -147,6 +197,9 @@ export async function continueAfterInit(parsed, result, io, cwd) {
147
197
  pairingToken: readOrCreatePairingTokenSync(defaultPairingTokenDir()),
148
198
  env: collectEnv(parsed.env ?? []),
149
199
  openBrowser: false !== parsed.open,
200
+ firstRun: false !== parsed.firstRun,
201
+ json: true === parsed.json,
202
+ firstFlow,
150
203
  registerAgents: wantsAgents(parsed),
151
204
  phaseTimeoutMs: undefined === parsed.timeoutSeconds
152
205
  ? DEFAULT_PHASE_TIMEOUT_MS
@@ -160,21 +213,23 @@ export async function continueAfterInit(parsed, result, io, cwd) {
160
213
  startupBudgetMs: parsed.timeoutSeconds * 1000,
161
214
  }),
162
215
  pollMs: POLL_MS,
163
- htmlCarriesSdk: HTML_CARRIES_SDK.has(context.framework),
216
+ htmlCarriesSdk: htmlCarriesSdk(context.framework, (rel) => existsSync(join(context.appDir, rel))),
164
217
  // A plain page with no dev script gets Reticle's own static server, so the page is actually
165
218
  // served and the connect can be proved, instead of stopping at "start the app yourself".
166
219
  ...(() => {
167
- const devCommand = context.devCommand ??
168
- (undefined === parsed.url
169
- ? staticPageDevCommand({
170
- appDir: context.appDir,
171
- isStaticPage: Framework.HTML === context.framework,
172
- })
173
- : undefined);
174
- return undefined === devCommand ? {} : { devCommand };
220
+ if (undefined !== context.devCommand)
221
+ return { devCommand: context.devCommand };
222
+ if (undefined !== parsed.url)
223
+ return {};
224
+ const devCommand = staticPageDevCommand({
225
+ appDir: context.appDir,
226
+ isStaticPage: Framework.HTML === context.framework,
227
+ });
228
+ return undefined === devCommand ? {} : { devCommand, devCommandIsStaticPage: true };
175
229
  })(),
176
230
  ...(undefined === parsed.url ? {} : { suppliedUrl: parsed.url }),
177
- }, (line) => io.print(line)).then((outcome) => {
231
+ }, (line) => io.print(line))
232
+ .then(async (outcome) => {
178
233
  if (result.outcome !== undefined) {
179
234
  const init = {
180
235
  ...result.outcome,
@@ -193,26 +248,28 @@ export async function continueAfterInit(parsed, result, io, cwd) {
193
248
  ? InitFailure.DEV_SERVER
194
249
  : InitFailure.APP_CONNECTION;
195
250
  }
196
- reportInitOutcome(init);
251
+ reportOnce(init);
197
252
  }
198
253
  // One object, so an agent reads a result instead of interpreting a report.
199
254
  if (true === parsed.json) {
200
255
  process.stdout.write(`${JSON.stringify(outcome, null, 2)}\n`);
201
256
  if (!outcome.ok)
202
- process.exit(1);
257
+ stop();
203
258
  return;
204
259
  }
205
260
  io.print('');
206
261
  // The precondition for everything the closing asks for, printed on the path that could not say
207
- // it. An agent client reads its MCP server list when it STARTS and never re-reads it, so on the
208
- // run that first registers Reticle the `reticle_*` tools are not in the session that just asked
209
- // for them -- and this path closes by telling that session to call `reticle_act_and_wait`.
210
- // `restartHint` has said this for a long time and is printed only when init stops at the files.
211
- if (true === result.mcpNewlyRegistered) {
212
- io.print('Reticle was registered with your agent by this run, and an agent reads its tool list only ' +
213
- 'when it starts: the `reticle_*` tools are NOT in this session yet. Restart it first — ' +
214
- '`npx @reticlehq/server init --relaunch` prints the exact resume command for Claude Code ' +
215
- 'and Codex. Once per machine.');
262
+ // it. An agent client reads its MCP server list when it STARTS and never re-reads it, so an
263
+ // agent that ran this without the `reticle_*` tools cannot do what the closing tells it to.
264
+ // See agent-restart.ts for the two ways that is known.
265
+ const restart = restartNotice({
266
+ insideAgent: CLAUDE_CODE_MARKER === process.env[CLAUDE_CODE_ENV] ||
267
+ undefined !== codexSessionFor(cwd),
268
+ newlyRegistered: true === result.mcpNewlyRegistered,
269
+ attached: attachedAgents(await fetchStatus(port)),
270
+ });
271
+ if (undefined !== restart) {
272
+ io.print(restart);
216
273
  io.print('');
217
274
  }
218
275
  if (outcome.ok && !outcome.flowSaved) {
@@ -228,11 +285,8 @@ export async function continueAfterInit(parsed, result, io, cwd) {
228
285
  return;
229
286
  }
230
287
  if (outcome.ok) {
231
- io.print(`✓ setup complete — ${outcome.url ?? 'the app'} is instrumented and a flow was driven.`);
232
- // A passing flow shows the mechanism working. What the run SAW is the part nobody can get for
233
- // themselves, and it deserves a line of its own rather than a paragraph that gets skimmed.
234
- io.print(' Read the FINDINGS above before moving on: a flow can pass with a failed request or a ' +
235
- 'console error behind it, and that is the app, not the check.');
288
+ io.print(`✓ setup complete — ${outcome.url ?? 'the app'} is instrumented and its first flow is ` +
289
+ 'saved. The tab stays open; a linked project sends the flow and its run to your dashboard.');
236
290
  ask();
237
291
  return;
238
292
  }
@@ -242,9 +296,31 @@ export async function continueAfterInit(parsed, result, io, cwd) {
242
296
  for (const [i, step] of outcome.fallback.entries())
243
297
  io.print(` ${i + 1}. ${step}`);
244
298
  ask();
245
- process.exit(1);
299
+ stop();
246
300
  }, (error) => {
247
301
  reportFailure(InitFailure.RUNTIME_ERROR);
248
302
  throw error;
303
+ })
304
+ .finally(releaseInterrupt);
305
+ }
306
+ const INTERRUPT_SIGNALS = ['SIGINT', 'SIGTERM'];
307
+ /** 128 + the signal number, which is what a shell reports. */
308
+ const INTERRUPT_EXIT_CODE = { SIGINT: 130, SIGTERM: 143 };
309
+ /** Run `report` if the process is interrupted. Returns the disposer. */
310
+ function reportOnInterrupt(report) {
311
+ const handlers = INTERRUPT_SIGNALS.map((signal) => {
312
+ const handler = () => {
313
+ report();
314
+ // Before setup installs its own handler ours may be the only one, and a listener present
315
+ // means Node no longer exits on the signal by itself: without this, Ctrl-C would be ignored.
316
+ if (1 === process.listenerCount(signal))
317
+ process.exit(INTERRUPT_EXIT_CODE[signal]);
318
+ };
319
+ process.on(signal, handler);
320
+ return { signal, handler };
249
321
  });
322
+ return () => {
323
+ for (const { signal, handler } of handlers)
324
+ process.off(signal, handler);
325
+ };
250
326
  }
@@ -53,6 +53,8 @@ export declare class OwnedDevServer {
53
53
  handOver(url?: string): void;
54
54
  stop(): void;
55
55
  }
56
+ /** Run a command and return what it printed, or '' if it failed to finish within `timeoutMs`. */
57
+ export declare function run(file: string, args: string[], timeoutMs?: number): string;
56
58
  /**
57
59
  * Fetch the page and say what came back.
58
60
  *