@reticlehq/server 3.8.2 → 3.10.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 (477) hide show
  1. package/LICENSE +201 -104
  2. package/NOTICE +5 -0
  3. package/README.md +1 -1
  4. package/SKILL.md +13 -12
  5. package/bin/launch.js +13 -0
  6. package/bin/package.json +3 -0
  7. package/bin/reticle.js +66 -8
  8. package/dist/chromium-launch-options.d.ts +25 -0
  9. package/dist/chromium-launch-options.js +21 -1
  10. package/dist/command/cli/adhoc-suite.js +2 -0
  11. package/dist/command/cli/adhoc-verdict.d.ts +2 -43
  12. package/dist/command/cli/adhoc-verdict.js +50 -160
  13. package/dist/command/cli/answers/gate-exit.d.ts +6 -2
  14. package/dist/command/cli/answers/gate-exit.js +12 -2
  15. package/dist/command/cli/answers/mcp-connection-hint.d.ts +2 -0
  16. package/dist/command/cli/answers/mcp-connection-hint.js +6 -0
  17. package/dist/command/cli/ci-hint.d.ts +44 -0
  18. package/dist/command/cli/ci-hint.js +72 -0
  19. package/dist/command/cli/cli-doctor.d.ts +6 -1
  20. package/dist/command/cli/cli-doctor.js +46 -5
  21. package/dist/command/cli/cli-flow-commands.d.ts +7 -1
  22. package/dist/command/cli/cli-flow-commands.js +39 -24
  23. package/dist/command/cli/cli-kill.d.ts +21 -0
  24. package/dist/command/cli/cli-kill.js +47 -4
  25. package/dist/command/cli/cli-parse-compare.d.ts +22 -0
  26. package/dist/command/cli/cli-parse-compare.js +75 -0
  27. package/dist/command/cli/cli-parse-grade.d.ts +36 -0
  28. package/dist/command/cli/cli-parse-grade.js +75 -0
  29. package/dist/command/cli/cli-parse-grammar.d.ts +2 -0
  30. package/dist/command/cli/cli-parse-grammar.js +18 -20
  31. package/dist/command/cli/cli-parse-verify.d.ts +10 -0
  32. package/dist/command/cli/cli-parse-verify.js +63 -14
  33. package/dist/command/cli/cli-parse.d.ts +22 -17
  34. package/dist/command/cli/cli-parse.js +54 -32
  35. package/dist/command/cli/cli-update-commands.d.ts +1 -1
  36. package/dist/command/cli/cli-update-commands.js +29 -20
  37. package/dist/command/cli/cli-usage.js +61 -31
  38. package/dist/command/cli/cli-verify.d.ts +17 -3
  39. package/dist/command/cli/cli-verify.js +59 -21
  40. package/dist/command/cli/cloud-cli.js +2 -119
  41. package/dist/command/cli/daemon-link/daemon-client.d.ts +45 -0
  42. package/dist/command/cli/daemon-link/daemon-client.js +205 -0
  43. package/dist/command/cli/doctor/browser/chromium-hint.d.ts +6 -1
  44. package/dist/command/cli/doctor/browser/chromium-hint.js +11 -5
  45. package/dist/command/cli/doctor/doctor-daemon-line.js +6 -3
  46. package/dist/command/cli/doctor/doctor-fix.d.ts +44 -0
  47. package/dist/command/cli/doctor/doctor-fix.js +89 -0
  48. package/dist/command/cli/doctor/doctor-launcher-line.d.ts +23 -0
  49. package/dist/command/cli/doctor/doctor-launcher-line.js +60 -0
  50. package/dist/command/cli/doctor/doctor-rows.d.ts +4 -0
  51. package/dist/command/cli/doctor/doctor-rows.js +4 -0
  52. package/dist/command/cli/doctor-repairs.d.ts +64 -0
  53. package/dist/command/cli/doctor-repairs.js +214 -0
  54. package/dist/command/cli/drive/drive-command.js +3 -7
  55. package/dist/command/cli/ensure-daemon.d.ts +26 -0
  56. package/dist/command/cli/ensure-daemon.js +57 -0
  57. package/dist/command/cli/finished-run/grade-command.d.ts +23 -0
  58. package/dist/command/cli/finished-run/grade-command.js +180 -0
  59. package/dist/command/cli/first-use-checks.d.ts +41 -0
  60. package/dist/command/cli/first-use-checks.js +127 -0
  61. package/dist/command/cli/first-verdict-node.d.ts +3 -0
  62. package/dist/command/cli/first-verdict-node.js +189 -0
  63. package/dist/command/cli/first-verdict.d.ts +126 -0
  64. package/dist/command/cli/first-verdict.js +267 -0
  65. package/dist/command/cli/launch/sdk-version-match.d.ts +3 -2
  66. package/dist/command/cli/launch/sdk-version-match.js +3 -2
  67. package/dist/command/cli/lifecycle/daemon-lifecycle.d.ts +1 -1
  68. package/dist/command/cli/lifecycle/daemon-lifecycle.js +7 -6
  69. package/dist/command/cli/mcp-command.js +13 -4
  70. package/dist/command/cli/ports/port-holder.d.ts +11 -0
  71. package/dist/command/cli/ports/port-holder.js +36 -4
  72. package/dist/command/cli/setup-mcp-cli.d.ts +27 -1
  73. package/dist/command/cli/setup-mcp-cli.js +98 -23
  74. package/dist/command/cli/status/status-lines.d.ts +2 -0
  75. package/dist/command/cli/status/status-lines.js +72 -17
  76. package/dist/command/cli/status-fields.d.ts +5 -1
  77. package/dist/command/cli/status-fields.js +24 -6
  78. package/dist/command/cli/try-command.d.ts +7 -0
  79. package/dist/command/cli/try-command.js +11 -3
  80. package/dist/command/cli/two-builds/compare-command.d.ts +48 -0
  81. package/dist/command/cli/two-builds/compare-command.js +314 -0
  82. package/dist/command/cli/verify-against.d.ts +61 -0
  83. package/dist/command/cli/verify-against.js +187 -0
  84. package/dist/command/cli/verify-no-session.d.ts +2 -0
  85. package/dist/command/cli/verify-no-session.js +13 -0
  86. package/dist/command/cli/verify-results.d.ts +35 -2
  87. package/dist/command/cli/verify-results.js +76 -10
  88. package/dist/command/cli.js +112 -70
  89. package/dist/command/daemon/binding/daemon-status-probe.d.ts +3 -1
  90. package/dist/command/daemon/binding/daemon-status-probe.js +4 -2
  91. package/dist/command/daemon/daemon-argv.d.ts +9 -0
  92. package/dist/command/daemon/daemon-argv.js +11 -0
  93. package/dist/command/daemon/daemon-resolve.d.ts +8 -1
  94. package/dist/command/daemon/daemon-resolve.js +27 -1
  95. package/dist/command/daemon/daemon.d.ts +22 -4
  96. package/dist/command/daemon/daemon.js +52 -10
  97. package/dist/command/daemon/lifetime/daemon-exit.d.ts +24 -0
  98. package/dist/command/daemon/lifetime/daemon-exit.js +39 -0
  99. package/dist/command/daemon/lifetime/death-cause.d.ts +15 -0
  100. package/dist/command/daemon/lifetime/death-cause.js +149 -0
  101. package/dist/command/daemon/lifetime/heartbeat.d.ts +7 -15
  102. package/dist/command/daemon/lifetime/heartbeat.js +11 -15
  103. package/dist/command/daemon/lifetime/startup-failure.d.ts +29 -0
  104. package/dist/command/daemon/lifetime/startup-failure.js +62 -0
  105. package/dist/command/daemon/port-state.d.ts +14 -0
  106. package/dist/command/daemon/port-state.js +31 -0
  107. package/dist/command/setup/agent-configs.d.ts +2 -0
  108. package/dist/command/setup/agent-configs.js +42 -15
  109. package/dist/command/setup/agent-next-steps.d.ts +77 -0
  110. package/dist/command/setup/agent-next-steps.js +284 -0
  111. package/dist/command/setup/agent-writer.js +11 -6
  112. package/dist/command/setup/bringup/dev-server-files.d.ts +9 -0
  113. package/dist/command/setup/bringup/dev-server-files.js +17 -0
  114. package/dist/command/setup/bringup/static-page-server.d.ts +14 -2
  115. package/dist/command/setup/bringup/static-page-server.js +43 -9
  116. package/dist/command/setup/init/init-host.js +2 -0
  117. package/dist/command/setup/init/init-runtime.d.ts +6 -1
  118. package/dist/command/setup/init/init-runtime.js +63 -21
  119. package/dist/command/setup/mcp-launcher.d.ts +3 -0
  120. package/dist/command/setup/mcp-launcher.js +11 -0
  121. package/dist/command/setup/node-effects.d.ts +3 -2
  122. package/dist/command/setup/node-effects.js +9 -3
  123. package/dist/command/setup/remaining-steps.d.ts +8 -0
  124. package/dist/command/setup/remaining-steps.js +10 -0
  125. package/dist/command/setup/run-setup.d.ts +2 -0
  126. package/dist/command/setup/run-setup.js +9 -1
  127. package/dist/command/setup/setup-command.js +36 -15
  128. package/dist/command/setup/setup-mcp.d.ts +8 -0
  129. package/dist/command/setup/setup-mcp.js +47 -20
  130. package/dist/command/setup/start-dev-server.d.ts +8 -0
  131. package/dist/command/setup/start-dev-server.js +43 -0
  132. package/dist/command/update/updater.js +6 -0
  133. package/dist/command/version/identity/server-version.d.ts +2 -0
  134. package/dist/command/version/identity/server-version.js +2 -0
  135. package/dist/command/version/version-skew.d.ts +7 -0
  136. package/dist/command/version/version-skew.js +14 -3
  137. package/dist/features/compare/action-plan.d.ts +260 -0
  138. package/dist/features/compare/action-plan.js +543 -0
  139. package/dist/features/compare/behaviour-compare.d.ts +24 -0
  140. package/dist/features/compare/behaviour-compare.js +85 -0
  141. package/dist/features/compare/behaviour-diff.d.ts +97 -0
  142. package/dist/features/compare/behaviour-diff.js +202 -0
  143. package/dist/features/compare/behaviour-report.d.ts +40 -0
  144. package/dist/features/compare/behaviour-report.js +128 -0
  145. package/dist/features/compare/build-readings.d.ts +106 -0
  146. package/dist/features/compare/build-readings.js +250 -0
  147. package/dist/features/compare/compare-diff.d.ts +62 -0
  148. package/dist/features/compare/compare-diff.js +177 -0
  149. package/dist/features/compare/compare-report-html.d.ts +6 -0
  150. package/dist/features/compare/compare-report-html.js +102 -0
  151. package/dist/features/compare/compare-report.d.ts +15 -0
  152. package/dist/features/compare/compare-report.js +73 -0
  153. package/dist/features/compare/compare-run.d.ts +60 -0
  154. package/dist/features/compare/compare-run.js +123 -0
  155. package/dist/features/compare/outside/effect-lines.d.ts +26 -0
  156. package/dist/features/compare/outside/effect-lines.js +103 -0
  157. package/dist/features/compare/outside/state-sources.d.ts +76 -0
  158. package/dist/features/compare/outside/state-sources.js +164 -0
  159. package/dist/features/compare/outside/value-dictionary.d.ts +51 -0
  160. package/dist/features/compare/outside/value-dictionary.js +227 -0
  161. package/dist/features/compare/visible-content.d.ts +20 -0
  162. package/dist/features/compare/visible-content.js +125 -0
  163. package/dist/features/crawl/crawl-empty.js +2 -1
  164. package/dist/features/crawl/crawl-exhaustive.d.ts +55 -0
  165. package/dist/features/crawl/crawl-exhaustive.js +138 -0
  166. package/dist/features/crawl/crawl-tools.d.ts +9 -2
  167. package/dist/features/crawl/crawl-tools.js +28 -12
  168. package/dist/features/crawl/crawl.d.ts +8 -9
  169. package/dist/features/crawl/crawl.js +61 -65
  170. package/dist/features/exhaust/app-coverage.d.ts +5 -1
  171. package/dist/features/exhaust/app-coverage.js +3 -1
  172. package/dist/features/exhaust/code-coverage.js +8 -4
  173. package/dist/features/exhaust/edge-cases.d.ts +133 -0
  174. package/dist/features/exhaust/edge-cases.js +310 -0
  175. package/dist/features/exhaust/edges/edge-drive.d.ts +42 -0
  176. package/dist/features/exhaust/edges/edge-drive.js +364 -0
  177. package/dist/features/exhaust/edges/edge-run.d.ts +59 -0
  178. package/dist/features/exhaust/edges/edge-run.js +169 -0
  179. package/dist/features/exhaust/explorer.d.ts +87 -14
  180. package/dist/features/exhaust/explorer.js +159 -25
  181. package/dist/features/exhaust/failure-branches.d.ts +5 -0
  182. package/dist/features/exhaust/failure-branches.js +29 -11
  183. package/dist/features/exhaust/invariants.d.ts +112 -0
  184. package/dist/features/exhaust/invariants.js +188 -0
  185. package/dist/features/exhaust/ledger.d.ts +68 -0
  186. package/dist/features/exhaust/ledger.js +121 -13
  187. package/dist/features/exhaust/session-fold.d.ts +10 -0
  188. package/dist/features/exhaust/session-fold.js +46 -3
  189. package/dist/features/exhaust/session-port.d.ts +3 -1
  190. package/dist/features/exhaust/session-port.js +97 -28
  191. package/dist/features/grade/grade-answer.d.ts +99 -0
  192. package/dist/features/grade/grade-answer.js +112 -0
  193. package/dist/features/grade/grade-noise.d.ts +27 -0
  194. package/dist/features/grade/grade-noise.js +55 -0
  195. package/dist/features/grade/grade-renumber.d.ts +12 -0
  196. package/dist/features/grade/grade-renumber.js +86 -0
  197. package/dist/features/grade/grade-state.d.ts +50 -0
  198. package/dist/features/grade/grade-state.js +93 -0
  199. package/dist/features/grade/grade-suggest.d.ts +33 -0
  200. package/dist/features/grade/grade-suggest.js +98 -0
  201. package/dist/features/license/license.d.ts +11 -71
  202. package/dist/features/license/license.js +43 -136
  203. package/dist/features/visual/desktop-capture.d.ts +33 -0
  204. package/dist/features/visual/desktop-capture.js +94 -0
  205. package/dist/features/visual/step-shots.js +139 -35
  206. package/dist/features/visual/visual-tools.d.ts +0 -18
  207. package/dist/features/visual/visual-tools.js +67 -99
  208. package/dist/import-graph.js +5 -6
  209. package/dist/index.d.ts +3 -1
  210. package/dist/index.js +19 -7
  211. package/dist/judgement/capsule/causal-summary.js +9 -2
  212. package/dist/judgement/runs/artifact/replay-mapping.d.ts +13 -1
  213. package/dist/judgement/runs/artifact/replay-mapping.js +1 -1
  214. package/dist/judgement/runs/reticle-runner.js +16 -2
  215. package/dist/judgement/runs/run-ledger.d.ts +7 -5
  216. package/dist/judgement/runs/run-ledger.js +98 -69
  217. package/dist/judgement/runs/runner-port.d.ts +2 -0
  218. package/dist/judgement/runs/runner-port.js +23 -5
  219. package/dist/judgement/runs/verification-sync.d.ts +6 -3
  220. package/dist/judgement/runs/verification-sync.js +21 -10
  221. package/dist/language/flows/affected-tools.d.ts +1 -1
  222. package/dist/language/flows/affected-tools.js +49 -30
  223. package/dist/language/flows/change/git-changed.d.ts +2 -1
  224. package/dist/language/flows/change/git-changed.js +19 -2
  225. package/dist/language/flows/fields/flow-secret-field.d.ts +1 -13
  226. package/dist/language/flows/fields/flow-secret-field.js +77 -21
  227. package/dist/language/flows/flow-anchor.d.ts +60 -2
  228. package/dist/language/flows/flow-anchor.js +125 -20
  229. package/dist/language/flows/flow-classify.d.ts +20 -0
  230. package/dist/language/flows/flow-classify.js +90 -12
  231. package/dist/language/flows/flow-cross-step.d.ts +7 -1
  232. package/dist/language/flows/flow-cross-step.js +25 -1
  233. package/dist/language/flows/flow-journey.d.ts +38 -4
  234. package/dist/language/flows/flow-journey.js +138 -8
  235. package/dist/language/flows/flow-replay-run.d.ts +0 -16
  236. package/dist/language/flows/flow-replay-run.js +76 -14
  237. package/dist/language/flows/flow-replay-types.d.ts +4 -2
  238. package/dist/language/flows/flow-replay.d.ts +19 -1
  239. package/dist/language/flows/flow-replay.js +169 -52
  240. package/dist/language/flows/flow-replayable.js +7 -1
  241. package/dist/language/flows/flow-start-path.d.ts +34 -5
  242. package/dist/language/flows/flow-start-path.js +202 -15
  243. package/dist/language/flows/flow-step-runners.d.ts +14 -13
  244. package/dist/language/flows/flow-step-runners.js +184 -109
  245. package/dist/language/flows/flow-store-for-session.d.ts +26 -25
  246. package/dist/language/flows/flow-store-for-session.js +51 -5
  247. package/dist/language/flows/flow-tools.js +46 -33
  248. package/dist/language/flows/flows.js +176 -76
  249. package/dist/language/flows/recording/tape/recordings.d.ts +21 -16
  250. package/dist/language/flows/recording/tape/recordings.js +112 -49
  251. package/dist/language/flows/replay.d.ts +36 -12
  252. package/dist/language/flows/replay.js +193 -50
  253. package/dist/language/flows/steps/page-steps.d.ts +68 -0
  254. package/dist/language/flows/steps/page-steps.js +198 -0
  255. package/dist/language/flows/suite/sequential-run.d.ts +68 -0
  256. package/dist/language/flows/suite/sequential-run.js +96 -0
  257. package/dist/language/flows/verify-change-tools.js +26 -15
  258. package/dist/launch-chromium.d.ts +1 -0
  259. package/dist/launch-chromium.js +49 -12
  260. package/dist/memory/cloud/background-sync.d.ts +13 -0
  261. package/dist/memory/cloud/background-sync.js +24 -3
  262. package/dist/memory/cloud/sync-daemon.js +26 -27
  263. package/dist/memory/cloud/sync-screenshots.js +6 -1
  264. package/dist/memory/journal/attach-journal.js +2 -1
  265. package/dist/memory/journal/drive-flow.d.ts +7 -0
  266. package/dist/memory/journal/drive-flow.js +44 -13
  267. package/dist/memory/journal/journal-recorder.d.ts +4 -2
  268. package/dist/memory/journal/session-journal.d.ts +7 -0
  269. package/dist/memory/journal/session-journal.js +58 -10
  270. package/dist/memory/project/root-claims.d.ts +9 -0
  271. package/dist/memory/project/root-claims.js +9 -4
  272. package/dist/portal/bridge/bridge.d.ts +13 -4
  273. package/dist/portal/bridge/bridge.js +10 -9
  274. package/dist/portal/input/download-capture.d.ts +7 -0
  275. package/dist/portal/input/download-capture.js +92 -0
  276. package/dist/portal/input/network-detail.d.ts +6 -0
  277. package/dist/portal/input/network-detail.js +12 -1
  278. package/dist/portal/input/network-mock-tools.js +49 -13
  279. package/dist/portal/input/network-mock.d.ts +8 -0
  280. package/dist/portal/input/network-mock.js +30 -10
  281. package/dist/portal/input/page-capture.d.ts +24 -0
  282. package/dist/portal/input/page-capture.js +33 -0
  283. package/dist/portal/input/real-input.d.ts +35 -18
  284. package/dist/portal/input/real-input.js +99 -33
  285. package/dist/portal/input/viewport-tools.d.ts +8 -0
  286. package/dist/portal/input/viewport-tools.js +81 -21
  287. package/dist/portal/pool/browser-pool.d.ts +16 -30
  288. package/dist/portal/pool/browser-pool.js +64 -52
  289. package/dist/portal/pool/context-permissions.d.ts +34 -17
  290. package/dist/portal/pool/context-permissions.js +94 -1
  291. package/dist/portal/pool/csp-widen.d.ts +62 -0
  292. package/dist/portal/pool/csp-widen.js +132 -0
  293. package/dist/portal/pool/determinism.d.ts +52 -0
  294. package/dist/portal/pool/determinism.js +259 -0
  295. package/dist/portal/pool/lease-emulation.d.ts +34 -1
  296. package/dist/portal/pool/lease-emulation.js +18 -0
  297. package/dist/portal/pool/lease-marker-stamp.d.ts +6 -0
  298. package/dist/portal/pool/lease-marker-stamp.js +15 -1
  299. package/dist/portal/pool/lease-page-error.d.ts +56 -0
  300. package/dist/portal/pool/lease-page-error.js +160 -0
  301. package/dist/portal/pool/page-error-journal.d.ts +63 -0
  302. package/dist/portal/pool/page-error-journal.js +208 -0
  303. package/dist/portal/pool/playwright-launcher.js +71 -15
  304. package/dist/portal/pool/pool-contract.d.ts +49 -1
  305. package/dist/portal/pool/pool-lease.d.ts +70 -2
  306. package/dist/portal/pool/pool-lease.js +23 -0
  307. package/dist/portal/pool/zero-install.d.ts +8 -0
  308. package/dist/portal/pool/zero-install.js +91 -1
  309. package/dist/portal/session/dev-server/dev-command.d.ts +11 -2
  310. package/dist/portal/session/dev-server/dev-command.js +110 -16
  311. package/dist/portal/session/dev-server/dev-server-probe.d.ts +7 -0
  312. package/dist/portal/session/dev-server/dev-server-probe.js +9 -0
  313. package/dist/portal/session/dev-server/project-ports.d.ts +21 -0
  314. package/dist/portal/session/dev-server/project-ports.js +62 -0
  315. package/dist/portal/session/facts/departed-network.d.ts +66 -0
  316. package/dist/portal/session/facts/departed-network.js +142 -0
  317. package/dist/portal/session/no-session-diagnosis.d.ts +9 -0
  318. package/dist/portal/session/no-session-diagnosis.js +76 -27
  319. package/dist/portal/session/no-session-next-action.d.ts +14 -0
  320. package/dist/portal/session/no-session-next-action.js +56 -7
  321. package/dist/portal/session/no-session-watch.d.ts +6 -0
  322. package/dist/portal/session/no-session-watch.js +41 -4
  323. package/dist/portal/session/page-commands/undeclared-command.d.ts +9 -3
  324. package/dist/portal/session/page-commands/undeclared-command.js +16 -7
  325. package/dist/portal/session/recorded-gaps.d.ts +1 -1
  326. package/dist/portal/session/recorded-gaps.js +5 -2
  327. package/dist/portal/session/serving-directory.d.ts +10 -0
  328. package/dist/portal/session/serving-directory.js +39 -8
  329. package/dist/portal/session/session-manager.d.ts +10 -0
  330. package/dist/portal/session/session-manager.js +211 -81
  331. package/dist/portal/session/session.js +4 -3
  332. package/dist/portal/session/zero-install-first-call.d.ts +20 -1
  333. package/dist/portal/session/zero-install-first-call.js +34 -2
  334. package/dist/start-wiring.d.ts +30 -2
  335. package/dist/start-wiring.js +74 -9
  336. package/dist/surface/mcp/mcp-proxy.js +10 -2
  337. package/dist/surface/mcp/mcp.js +8 -5
  338. package/dist/surface/mcp/peer/agents-connected.d.ts +6 -0
  339. package/dist/surface/mcp/peer/agents-connected.js +58 -0
  340. package/dist/surface/mcp/proxy/proxy-daemon-probe.js +17 -5
  341. package/dist/surface/mcp/shared-params.d.ts +2 -0
  342. package/dist/surface/mcp/shared-params.js +31 -0
  343. package/dist/surface/tools/act/act-observation.d.ts +40 -2
  344. package/dist/surface/tools/act/act-observation.js +118 -12
  345. package/dist/surface/tools/act/act-preflight.js +38 -18
  346. package/dist/surface/tools/act/act-sequence-retry.d.ts +23 -2
  347. package/dist/surface/tools/act/act-sequence-retry.js +61 -5
  348. package/dist/surface/tools/act/act-target.js +3 -1
  349. package/dist/surface/tools/act/after-match.d.ts +10 -0
  350. package/dist/surface/tools/act/after-match.js +40 -0
  351. package/dist/surface/tools/act/already-true.js +1 -1
  352. package/dist/surface/tools/act/navigation/reload-result.d.ts +12 -1
  353. package/dist/surface/tools/act/navigation/reload-result.js +25 -2
  354. package/dist/surface/tools/act/resolve-target.d.ts +17 -1
  355. package/dist/surface/tools/act/resolve-target.js +59 -9
  356. package/dist/surface/tools/act/sequence-grade.d.ts +15 -1
  357. package/dist/surface/tools/act/sequence-grade.js +45 -27
  358. package/dist/surface/tools/act/settle-in-flight.js +27 -15
  359. package/dist/surface/tools/act-command.d.ts +23 -0
  360. package/dist/surface/tools/act-command.js +50 -0
  361. package/dist/surface/tools/act-sequence-tool.js +81 -50
  362. package/dist/surface/tools/act-tools.d.ts +1 -13
  363. package/dist/surface/tools/act-tools.js +83 -95
  364. package/dist/surface/tools/agent/build-staleness.d.ts +1 -1
  365. package/dist/surface/tools/agent/build-staleness.js +1 -1
  366. package/dist/surface/tools/assert/assert-verdict.js +18 -12
  367. package/dist/surface/tools/browser-tools.js +87 -13
  368. package/dist/surface/tools/compare-tools.d.ts +11 -0
  369. package/dist/surface/tools/compare-tools.js +94 -0
  370. package/dist/surface/tools/coverage-tools.js +1 -1
  371. package/dist/surface/tools/dynamic-tools.js +11 -3
  372. package/dist/surface/tools/empty-session-list.d.ts +2 -0
  373. package/dist/surface/tools/empty-session-list.js +4 -2
  374. package/dist/surface/tools/error-recovery.d.ts +12 -1
  375. package/dist/surface/tools/error-recovery.js +131 -40
  376. package/dist/surface/tools/explore-tools.js +1 -1
  377. package/dist/surface/tools/invoke-tool.js +29 -21
  378. package/dist/surface/tools/lease-coverage-tools.d.ts +49 -0
  379. package/dist/surface/tools/lease-coverage-tools.js +128 -0
  380. package/dist/surface/tools/lease-hint.d.ts +42 -1
  381. package/dist/surface/tools/lease-hint.js +52 -3
  382. package/dist/surface/tools/lease-readiness.d.ts +47 -0
  383. package/dist/surface/tools/lease-readiness.js +126 -0
  384. package/dist/surface/tools/lease-seed.d.ts +16 -1
  385. package/dist/surface/tools/lease-seed.js +37 -4
  386. package/dist/surface/tools/lease-tools.d.ts +3 -41
  387. package/dist/surface/tools/lease-tools.js +104 -124
  388. package/dist/surface/tools/lease-url-identity.d.ts +46 -0
  389. package/dist/surface/tools/lease-url-identity.js +97 -0
  390. package/dist/surface/tools/merge-tools.js +99 -2
  391. package/dist/surface/tools/merged-name-redirect.js +5 -1
  392. package/dist/surface/tools/observe-tools.js +15 -9
  393. package/dist/surface/tools/read/console-pre-attach.d.ts +19 -0
  394. package/dist/surface/tools/read/console-pre-attach.js +23 -0
  395. package/dist/surface/tools/read-tools.js +33 -30
  396. package/dist/surface/tools/real-input-attempt.d.ts +0 -8
  397. package/dist/surface/tools/real-input-attempt.js +143 -28
  398. package/dist/surface/tools/repeat-hint.d.ts +40 -0
  399. package/dist/surface/tools/repeat-hint.js +171 -0
  400. package/dist/surface/tools/run-report.d.ts +2 -2
  401. package/dist/surface/tools/run-report.js +27 -15
  402. package/dist/surface/tools/session-ports.d.ts +14 -0
  403. package/dist/surface/tools/session-ports.js +53 -0
  404. package/dist/surface/tools/tool-kit.d.ts +18 -0
  405. package/dist/surface/tools/tool-kit.js +9 -3
  406. package/dist/surface/tools/tool-surface.js +0 -1
  407. package/dist/surface/tools/tools.js +54 -18
  408. package/dist/surface/tools/type-spelling.d.ts +13 -0
  409. package/dist/surface/tools/type-spelling.js +36 -0
  410. package/dist/telemetry/agent-client.d.ts +6 -0
  411. package/dist/telemetry/agent-client.js +10 -0
  412. package/dist/telemetry/argument-shape.js +17 -7
  413. package/dist/telemetry/cli-telemetry.d.ts +10 -1
  414. package/dist/telemetry/cli-telemetry.js +15 -0
  415. package/dist/telemetry/init-telemetry.d.ts +2 -1
  416. package/dist/telemetry/init-telemetry.js +47 -2
  417. package/dist/telemetry/install-trace.js +23 -4
  418. package/dist/telemetry/onboarding-funnel.d.ts +19 -2
  419. package/dist/telemetry/onboarding-funnel.js +25 -3
  420. package/dist/telemetry/proxy-telemetry.d.ts +2 -1
  421. package/dist/telemetry/proxy-telemetry.js +2 -2
  422. package/dist/telemetry/session-metrics.d.ts +1 -1
  423. package/dist/telemetry/session-metrics.js +67 -27
  424. package/dist/telemetry/telemetry.d.ts +3 -1
  425. package/dist/telemetry/telemetry.js +60 -28
  426. package/dist/telemetry/tool-refused.d.ts +6 -3
  427. package/dist/telemetry/tool-refused.js +15 -3
  428. package/docs/actions.mdx +3 -3
  429. package/docs/agent-cheatsheet.md +1 -1
  430. package/docs/architecture.md +3 -6
  431. package/docs/capabilities.mdx +61 -1
  432. package/docs/cli/affected.mdx +9 -7
  433. package/docs/cli/cloud.mdx +3 -3
  434. package/docs/cli/compare.mdx +94 -0
  435. package/docs/cli/doctor.mdx +41 -2
  436. package/docs/cli/grade.mdx +97 -0
  437. package/docs/cli/help.mdx +4 -2
  438. package/docs/cli/license.mdx +13 -12
  439. package/docs/cli/restart.mdx +7 -5
  440. package/docs/cli/rollback.mdx +5 -5
  441. package/docs/cli/setup.mdx +13 -2
  442. package/docs/cli/status.mdx +4 -0
  443. package/docs/cli/stop.mdx +3 -3
  444. package/docs/cli/update.mdx +2 -2
  445. package/docs/cli/verify.mdx +23 -1
  446. package/docs/cli.mdx +34 -24
  447. package/docs/deploy-checks.md +25 -0
  448. package/docs/desktop.mdx +1 -1
  449. package/docs/enterprise.md +17 -22
  450. package/docs/environment.mdx +1 -0
  451. package/docs/first-drive.md +1 -1
  452. package/docs/flows.md +11 -1
  453. package/docs/frameworks.mdx +9 -9
  454. package/docs/getting-started.md +1 -1
  455. package/docs/install-manual.mdx +16 -1
  456. package/docs/license-activation.mdx +3 -3
  457. package/docs/packages/engine.mdx +1 -1
  458. package/docs/packages/server.mdx +1 -1
  459. package/docs/packages/tauri.mdx +1 -1
  460. package/docs/packages/test.mdx +1 -1
  461. package/docs/packages.mdx +1 -1
  462. package/docs/platform-integration.md +1 -1
  463. package/docs/predicates.mdx +1 -1
  464. package/docs/quickstart.mdx +68 -49
  465. package/docs/skill-setup.md +1 -1
  466. package/docs/skill.md +14 -13
  467. package/docs/telemetry.md +6 -4
  468. package/docs/tools/navigate.mdx +1 -1
  469. package/docs/tools/verify.mdx +4 -1
  470. package/docs/troubleshooting.mdx +1 -1
  471. package/docs/usage.md +17 -14
  472. package/package.json +18 -14
  473. package/LICENSE-ENTERPRISE +0 -37
  474. package/dist/features/ee/audit-log.d.ts +0 -14
  475. package/dist/features/ee/audit-log.js +0 -11
  476. package/dist/features/exhaust/exhaust-run.d.ts +0 -33
  477. package/dist/features/exhaust/exhaust-run.js +0 -82
@@ -8,22 +8,29 @@
8
8
  * starts `npm run dev`, and the rest of setup (wait, open, prove the connect) runs unchanged.
9
9
  *
10
10
  * It is run as its own process (`node static-page-server.js --dir <app>`), not inside init, because it
11
- * has to outlive init exactly like any handed-over dev server. It imports nothing but Node, so the
12
- * built file runs on its own.
11
+ * has to outlive init exactly like any handed-over dev server. It imports only Node and
12
+ * `@reticlehq/init`, so the built file runs on its own.
13
+ *
14
+ * It adds the connect snippet to each HTML page it serves, so init does not edit the file the user
15
+ * hands over (#1544). The file on disk stays byte-identical.
13
16
  *
14
17
  * Loopback only, on both families: a page served to the LAN would publish the pairing token the
15
18
  * snippet carries.
16
19
  */
17
- import { existsSync, readFile, statSync } from 'node:fs';
20
+ import { existsSync, readFile, readFileSync, statSync } from 'node:fs';
18
21
  import { createServer } from 'node:http';
19
22
  import { extname, join, resolve, sep } from 'node:path';
20
23
  import { fileURLToPath, pathToFileURL } from 'node:url';
24
+ import { connectArg, projectIdOf, withStaticSnippet } from '@reticlehq/init';
21
25
  export const STATIC_PAGE_INDEX = 'index.html';
22
26
  /** Where the search for a free port starts when none is given — clear of Vite's 5173 run. */
23
27
  export const STATIC_PAGE_FIRST_PORT = 5500;
24
28
  const PORT_SEARCH_SPAN = 50;
25
29
  const DIR_FLAG = '--dir';
26
30
  const PORT_FLAG = '--port';
31
+ const BRIDGE_PORT_FLAG = '--bridge-port';
32
+ const PROJECT_CONFIG = '.reticle.json';
33
+ const HTML_EXTENSION = '.html';
27
34
  const LOOPBACK_V4 = '127.0.0.1';
28
35
  const LOOPBACK_V6 = '::1';
29
36
  const ANNOUNCED_HOST = 'localhost';
@@ -54,8 +61,9 @@ function fileFor(root, rawUrl) {
54
61
  return null;
55
62
  }
56
63
  const target = resolve(root, `.${path}`);
57
- if (target !== root && !target.startsWith(`${root}${sep}`))
64
+ if (target !== root && !target.startsWith(`${root}${sep}`)) {
58
65
  return null;
66
+ }
59
67
  const file = path.endsWith('/') ? join(target, STATIC_PAGE_INDEX) : target;
60
68
  try {
61
69
  return statSync(file).isFile() ? file : null;
@@ -64,6 +72,27 @@ function fileFor(root, rawUrl) {
64
72
  return null;
65
73
  }
66
74
  }
75
+ /**
76
+ * The connect literal for the page in `root`: the bridge port, and the project id its `.reticle.json`
77
+ * names. The same literal init wrote into the page before #1544.
78
+ */
79
+ export function staticPageConnect(root, bridgePort) {
80
+ let config;
81
+ try {
82
+ config = readFileSync(join(root, PROJECT_CONFIG), 'utf8');
83
+ }
84
+ catch {
85
+ config = null;
86
+ }
87
+ return connectArg(bridgePort, projectIdOf(config));
88
+ }
89
+ /** The body to send: an HTML page gets the connect snippet, unless it already connects. */
90
+ function servedBody(file, body, connect) {
91
+ if (undefined === connect || HTML_EXTENSION !== extname(file).toLowerCase()) {
92
+ return body;
93
+ }
94
+ return withStaticSnippet(body.toString('utf8'), connect) ?? body;
95
+ }
67
96
  function listen(server, port, host) {
68
97
  return new Promise((ok, fail) => {
69
98
  server.once('error', fail);
@@ -93,7 +122,7 @@ export async function startStaticPageServer(opts) {
93
122
  'content-type': CONTENT_TYPES[extname(file).toLowerCase()] ?? FALLBACK_TYPE,
94
123
  'cache-control': 'no-store',
95
124
  });
96
- res.end(body);
125
+ res.end(servedBody(file, body, opts.connect));
97
126
  });
98
127
  };
99
128
  const v4 = createServer(handler);
@@ -121,8 +150,9 @@ export async function startStaticPageServer(opts) {
121
150
  url: `http://${ANNOUNCED_HOST}:${String(bound)}/`,
122
151
  close: async () => {
123
152
  await closeServer(v4);
124
- if (hasV6)
153
+ if (hasV6) {
125
154
  await closeServer(v6);
155
+ }
126
156
  },
127
157
  };
128
158
  }
@@ -131,10 +161,12 @@ export async function startStaticPageServer(opts) {
131
161
  * that page. Quoted so an app path with a space survives the shell.
132
162
  */
133
163
  export function staticPageDevCommand(opts) {
134
- if (!opts.isStaticPage || !existsSync(join(opts.appDir, STATIC_PAGE_INDEX)))
164
+ if (!opts.isStaticPage || !existsSync(join(opts.appDir, STATIC_PAGE_INDEX))) {
135
165
  return undefined;
166
+ }
136
167
  const script = fileURLToPath(import.meta.url).replace(/\.ts$/, '.js');
137
- return `"${process.execPath}" "${script}" ${DIR_FLAG} "${opts.appDir}"`;
168
+ const bridge = undefined === opts.bridgePort ? '' : ` ${BRIDGE_PORT_FLAG} ${String(opts.bridgePort)}`;
169
+ return `"${process.execPath}" "${script}" ${DIR_FLAG} "${opts.appDir}"${bridge}`;
138
170
  }
139
171
  function flag(argv, name) {
140
172
  const at = argv.indexOf(name);
@@ -144,7 +176,9 @@ function flag(argv, name) {
144
176
  if (undefined !== process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
145
177
  const dir = flag(process.argv, DIR_FLAG) ?? process.cwd();
146
178
  const port = Number(flag(process.argv, PORT_FLAG) ?? STATIC_PAGE_FIRST_PORT);
147
- startStaticPageServer({ root: dir, port }).then((server) => process.stdout.write(`serving ${dir}\n Local: ${server.url}\n`), (err) => {
179
+ const bridgePort = flag(process.argv, BRIDGE_PORT_FLAG);
180
+ const connect = undefined === bridgePort ? undefined : staticPageConnect(dir, Number(bridgePort));
181
+ startStaticPageServer({ root: dir, port, connect }).then((server) => process.stdout.write(`serving ${dir}\n Local: ${server.url}\n`), (err) => {
148
182
  process.stderr.write(`static page server: ${String(err)}\n`);
149
183
  process.exit(1);
150
184
  });
@@ -1,6 +1,7 @@
1
1
  import { homedir } from 'node:os';
2
2
  import { spanSync } from '../../../trace.js';
3
3
  import { hookBinFor } from '../../cli/hook/hook-fast.js';
4
+ import { mcpLauncher } from '../mcp-launcher.js';
4
5
  import { reportInitOutcome } from '../../../telemetry/init-telemetry.js';
5
6
  import { reportOnboardingStep } from '../../../telemetry/onboarding-funnel.js';
6
7
  import { defaultPairingTokenDir, readOrCreatePairingTokenSync, } from '../../../portal/bridge/pairing-token.js';
@@ -44,6 +45,7 @@ export function serverInitHost() {
44
45
  hookBin() {
45
46
  return hookBinFor(homedir(), process.platform);
46
47
  },
48
+ mcpLauncher,
47
49
  insideClaudeCode() {
48
50
  return CLAUDE_CODE_MARKER_VALUE === process.env[CLAUDE_CODE_MARKER_ENV];
49
51
  },
@@ -53,7 +53,12 @@ interface InitRuntimeArgs {
53
53
  interface RuntimePrintIo {
54
54
  readonly print: (line: string) => void;
55
55
  }
56
+ /**
57
+ * Print the "Your agents:" block, and return the bounded wait for the agents to connect. `mayWait`
58
+ * false: the wait is a no-op. The caller adds the terminal check. See `agentsBlock`.
59
+ */
60
+ export type AgentsBlockPort = (print: (line: string) => void, mayWait: boolean) => () => Promise<void>;
56
61
  export declare function continueAfterInit(parsed: InitRuntimeArgs, result: InitResult, io: RuntimePrintIo, cwd: string,
57
62
  /** init's ending once the connection is proved: coverage and the agent prompt. See `FirstFlowPort`. */
58
- firstFlow?: FirstFlowPort): Promise<void>;
63
+ firstFlow?: FirstFlowPort, agentsBlock?: AgentsBlockPort): Promise<void>;
59
64
  export {};
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
9
9
  import { join } from 'node:path';
10
- import { InitConfirmation, RETICLE_DEFAULT_PORT } from '@reticlehq/core';
10
+ import { InitConfirmation, OnboardingPhase, OnboardingStop, RETICLE_DEFAULT_PORT, } from '@reticlehq/core';
11
11
  import { COMMUNITY_HINT, FEEDBACK_HINT, Framework, InitFailure, } from '@reticlehq/init';
12
12
  import { confirmInstall, nodeConfirmDeps } from '../terminal/confirm.js';
13
13
  import { writeLicenseKey } from '../license-key.js';
@@ -24,11 +24,14 @@ import { collectEnv, DEFAULT_PHASE_TIMEOUT_MS } from '../setup-options.js';
24
24
  import { staticPageDevCommand } from '../bringup/static-page-server.js';
25
25
  import { SetupPhase } from '../run-setup.js';
26
26
  import { reportInitOutcome } from '../../../telemetry/init-telemetry.js';
27
+ import { reportOnboardingStop } from '../../../telemetry/onboarding-funnel.js';
27
28
  /** Claude Code marks every process it spawns with this variable set to this value. */
28
29
  const CLAUDE_CODE_ENV = 'CLAUDECODE';
29
30
  const CLAUDE_CODE_MARKER = '1';
30
31
  /** How often the runtime phases look again: fast enough not to be the wait, slow enough to be free. */
31
32
  const POLL_MS = 250;
33
+ /** The step an agent without the `reticle_*` tools cannot take. */
34
+ const FIRST_LOOK_STEP = 'first_look';
32
35
  /**
33
36
  * The shapes whose served HTML carries the SDK marker: Vite injects it into index.html, and a plain
34
37
  * HTML page has the snippet pasted in. Everything else connects from the JS bundle, where a fetch
@@ -47,8 +50,9 @@ const NEXT_APP_CONNECT = ['app', 'src/app'].flatMap((d) => ['tsx', 'jsx', 'js'].
47
50
  * names chunks, not modules, so it stays silent.
48
51
  */
49
52
  export function htmlCarriesSdk(framework, exists) {
50
- if (HTML_CARRIES_SDK.has(framework))
53
+ if (HTML_CARRIES_SDK.has(framework)) {
51
54
  return true;
55
+ }
52
56
  return Framework.NEXT === framework && NEXT_APP_CONNECT.some(exists);
53
57
  }
54
58
  /** Registration is global MCP wiring, so both flags that disown it are read here. */
@@ -68,8 +72,9 @@ const licenseIo = {
68
72
  * thing as an install working.
69
73
  */
70
74
  function printRelaunch(parsed, io, cwd) {
71
- if (true !== parsed.relaunch)
75
+ if (true !== parsed.relaunch) {
72
76
  return;
77
+ }
73
78
  io.print(relaunchDecision({
74
79
  ...(undefined === process.env['CLAUDE_CODE_SESSION_ID']
75
80
  ? {}
@@ -82,13 +87,15 @@ function printRelaunch(parsed, io, cwd) {
82
87
  }
83
88
  export async function continueAfterInit(parsed, result, io, cwd,
84
89
  /** init's ending once the connection is proved: coverage and the agent prompt. See `FirstFlowPort`. */
85
- firstFlow) {
90
+ firstFlow, agentsBlock) {
86
91
  const port = parsed.port ?? RETICLE_DEFAULT_PORT;
87
92
  const stop = () => {
88
- if (true === parsed.keepGoing)
93
+ if (true === parsed.keepGoing) {
89
94
  process.exitCode = 1;
90
- else
95
+ }
96
+ else {
91
97
  process.exit(1);
98
+ }
92
99
  };
93
100
  // Real installs persist the key whichever way setup ends. A preview must leave .env and
94
101
  // .gitignore untouched, just as it leaves project wiring and agent configuration untouched.
@@ -114,16 +121,19 @@ firstFlow) {
114
121
  registerOtherAgents(io.print);
115
122
  }
116
123
  return confirmInstall(result, io, nodeConfirmDeps(port)).then(() => {
117
- if (true === parsed.json)
124
+ if (true === parsed.json) {
118
125
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
119
- if (!result.ok)
126
+ }
127
+ if (!result.ok) {
120
128
  stop();
129
+ }
121
130
  });
122
131
  }
123
132
  // From here on init left the ask to us, so it is the last thing on every exit below.
124
133
  const ask = (spaced = true) => {
125
- if (spaced)
134
+ if (spaced) {
126
135
  io.print('');
136
+ }
127
137
  io.print(FEEDBACK_HINT);
128
138
  };
129
139
  // `init` deferred its outcome to this phase, so every exit below reports it, and only once: the
@@ -131,8 +141,9 @@ firstFlow) {
131
141
  // would double the funnel this event exists to measure.
132
142
  let outcomeReported = false;
133
143
  const reportOnce = (init) => {
134
- if (outcomeReported)
144
+ if (outcomeReported) {
135
145
  return;
146
+ }
136
147
  outcomeReported = true;
137
148
  reportInitOutcome(init);
138
149
  };
@@ -140,11 +151,13 @@ firstFlow) {
140
151
  if (context === undefined) {
141
152
  // Nothing was established, so there is nothing to run against. init has already said why, and
142
153
  // the outcome it deferred (a failed dependency install, usually) is reported here or nowhere.
143
- if (result.outcome !== undefined)
154
+ if (result.outcome !== undefined) {
144
155
  reportOnce(result.outcome);
156
+ }
145
157
  ask();
146
- if (true === parsed.json)
158
+ if (true === parsed.json) {
147
159
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
160
+ }
148
161
  stop();
149
162
  return;
150
163
  }
@@ -188,6 +201,9 @@ firstFlow) {
188
201
  // A Ctrl-C during the wait ends the process with no `finally`, so the outcome is reported from the
189
202
  // signal itself. The send is detached, so it survives the exit that follows.
190
203
  const releaseInterrupt = reportOnInterrupt(() => reportFailure(InitFailure.INTERRUPTED));
204
+ // The wait for the agents runs last, after the interrupt handler is gone: a Ctrl+C that skips the
205
+ // wait is not a failed init.
206
+ let waitForAgents = () => Promise.resolve();
191
207
  return runSetupCommand({
192
208
  appDir: context.appDir,
193
209
  invokedAt: cwd,
@@ -217,19 +233,27 @@ firstFlow) {
217
233
  // A plain page with no dev script gets Reticle's own static server, so the page is actually
218
234
  // served and the connect can be proved, instead of stopping at "start the app yourself".
219
235
  ...(() => {
220
- if (undefined !== context.devCommand)
236
+ if (undefined !== context.devCommand) {
221
237
  return { devCommand: context.devCommand };
222
- if (undefined !== parsed.url)
238
+ }
239
+ if (undefined !== parsed.url) {
223
240
  return {};
241
+ }
224
242
  const devCommand = staticPageDevCommand({
225
243
  appDir: context.appDir,
226
244
  isStaticPage: Framework.HTML === context.framework,
245
+ // The server adds the connect snippet to the page, so init left the file alone (#1544).
246
+ bridgePort: port,
227
247
  });
228
248
  return undefined === devCommand ? {} : { devCommand, devCommandIsStaticPage: true };
229
249
  })(),
230
250
  ...(undefined === parsed.url ? {} : { suppliedUrl: parsed.url }),
231
251
  // So setup can tell which port the dev server will take, before it starts one (#1377).
232
252
  framework: context.framework,
253
+ // So a dev-server stop names the Vite step init could not do (#1263).
254
+ ...(undefined === context.pendingViteConfig
255
+ ? {}
256
+ : { pendingViteConfig: context.pendingViteConfig }),
233
257
  }, (line) => io.print(line))
234
258
  .then(async (outcome) => {
235
259
  if (result.outcome !== undefined) {
@@ -249,16 +273,18 @@ firstFlow) {
249
273
  outcome.reachedPhase === SetupPhase.DEV_SERVER
250
274
  ? InitFailure.DEV_SERVER
251
275
  : InitFailure.APP_CONNECTION;
252
- if (outcome.stop !== undefined)
276
+ if (outcome.stop !== undefined) {
253
277
  init.stop = outcome.stop;
278
+ }
254
279
  }
255
280
  reportOnce(init);
256
281
  }
257
282
  // One object, so an agent reads a result instead of interpreting a report.
258
283
  if (true === parsed.json) {
259
284
  process.stdout.write(`${JSON.stringify(outcome, null, 2)}\n`);
260
- if (!outcome.ok)
285
+ if (!outcome.ok) {
261
286
  stop();
287
+ }
262
288
  return;
263
289
  }
264
290
  io.print('');
@@ -274,7 +300,18 @@ firstFlow) {
274
300
  });
275
301
  if (undefined !== restart) {
276
302
  io.print(restart);
303
+ // The same block and wait as `reticle setup mcp`. No wait for a failed setup, or inside
304
+ // `reticle connect`, which signs in next.
305
+ if (agentsBlock !== undefined) {
306
+ waitForAgents = agentsBlock(io.print, outcome.ok && true !== parsed.keepGoing);
307
+ }
277
308
  io.print('');
309
+ // The agent cannot take its first look until it restarts. Detached: init exits soon.
310
+ reportOnboardingStop({
311
+ phase: OnboardingPhase.ONBOARD,
312
+ step: FIRST_LOOK_STEP,
313
+ stop: OnboardingStop.AGENT_NOT_RESTARTED,
314
+ }, { detach: true });
278
315
  }
279
316
  if (outcome.ok && !outcome.flowSaved) {
280
317
  // Success, and no flow. Saying "a flow was driven" here would replace a wrong exit code with
@@ -282,8 +319,9 @@ firstFlow) {
282
319
  // sentence is read by a person deciding whether their app is verified. It is not.
283
320
  // The connect already said "connected, nothing verified yet" and listed what to do next;
284
321
  // repeating it here was the same sentence twice, three lines apart.
285
- for (const [i, step] of outcome.fallback.entries())
322
+ for (const [i, step] of outcome.fallback.entries()) {
286
323
  io.print(` ${String(i + 1)}. ${step}`);
324
+ }
287
325
  // Already spaced by the blank line above when nothing was listed.
288
326
  ask(0 < outcome.fallback.length);
289
327
  io.print(COMMUNITY_HINT);
@@ -299,15 +337,17 @@ firstFlow) {
299
337
  // A run that produced no verdict did not succeed, and the exit code is the one place a caller
300
338
  // reads that without parsing anything.
301
339
  io.print('⚠ setup did not finish. To carry on from here:');
302
- for (const [i, step] of outcome.fallback.entries())
340
+ for (const [i, step] of outcome.fallback.entries()) {
303
341
  io.print(` ${i + 1}. ${step}`);
342
+ }
304
343
  ask();
305
344
  stop();
306
345
  }, (error) => {
307
346
  reportFailure(InitFailure.RUNTIME_ERROR);
308
347
  throw error;
309
348
  })
310
- .finally(releaseInterrupt);
349
+ .finally(releaseInterrupt)
350
+ .then(() => waitForAgents());
311
351
  }
312
352
  const INTERRUPT_SIGNALS = ['SIGINT', 'SIGTERM'];
313
353
  /** 128 + the signal number, which is what a shell reports. */
@@ -319,14 +359,16 @@ function reportOnInterrupt(report) {
319
359
  report();
320
360
  // Before setup installs its own handler ours may be the only one, and a listener present
321
361
  // means Node no longer exits on the signal by itself: without this, Ctrl-C would be ignored.
322
- if (1 === process.listenerCount(signal))
362
+ if (1 === process.listenerCount(signal)) {
323
363
  process.exit(INTERRUPT_EXIT_CODE[signal]);
364
+ }
324
365
  };
325
366
  process.on(signal, handler);
326
367
  return { signal, handler };
327
368
  });
328
369
  return () => {
329
- for (const { signal, handler } of handlers)
370
+ for (const { signal, handler } of handlers) {
330
371
  process.off(signal, handler);
372
+ }
331
373
  };
332
374
  }
@@ -0,0 +1,3 @@
1
+ /** `bin/reticle.js`, from `dist/command/setup/mcp-launcher.js`. The real path, not a symlink. */
2
+ export declare const CLI_BIN: string;
3
+ export declare function mcpLauncher(): string | undefined;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The bin that agent configs start the MCP server from, when this CLI is an install that stays on
3
+ * disk. Undefined for npx's cache and other run-once copies: see `installedLauncher` in init.
4
+ */
5
+ import { fileURLToPath } from 'node:url';
6
+ import { installedLauncher } from '@reticlehq/init';
7
+ /** `bin/reticle.js`, from `dist/command/setup/mcp-launcher.js`. The real path, not a symlink. */
8
+ export const CLI_BIN = fileURLToPath(new URL('../../../bin/reticle.js', import.meta.url));
9
+ export function mcpLauncher() {
10
+ return installedLauncher(CLI_BIN);
11
+ }
@@ -56,9 +56,10 @@ export declare class OwnedDevServer {
56
56
  *
57
57
  * Only `unref` is needed: the output is the supervisor's, so no pipe of ours holds the event loop
58
58
  * (`init` once printed "setup complete" and hung on one). `url` is recorded beside the log, so the
59
- * next `init` attaches to this server rather than starting a second one beside it.
59
+ * next `init` attaches to this server rather than starting a second one beside it. `bridgePort`
60
+ * is recorded too, so the next `init` on another port restarts this server instead.
60
61
  */
61
- handOver(url?: string): void;
62
+ handOver(url?: string, bridgePort?: number): void;
62
63
  stop(): void;
63
64
  }
64
65
  /** Run a command and return what it printed, or '' if it failed to finish within `timeoutMs`. */
@@ -175,14 +175,20 @@ export class OwnedDevServer {
175
175
  *
176
176
  * Only `unref` is needed: the output is the supervisor's, so no pipe of ours holds the event loop
177
177
  * (`init` once printed "setup complete" and hung on one). `url` is recorded beside the log, so the
178
- * next `init` attaches to this server rather than starting a second one beside it.
178
+ * next `init` attaches to this server rather than starting a second one beside it. `bridgePort`
179
+ * is recorded too, so the next `init` on another port restarts this server instead.
179
180
  */
180
- handOver(url) {
181
+ handOver(url, bridgePort) {
181
182
  this.handedOver = true;
182
183
  this.child?.unref();
183
184
  const pid = this.child?.pid;
184
185
  if (undefined !== url && undefined !== pid && undefined !== this.cwd) {
185
- recordHandOver(this.logDir, { pid, url, appDir: this.cwd });
186
+ recordHandOver(this.logDir, {
187
+ pid,
188
+ url,
189
+ appDir: this.cwd,
190
+ ...(undefined === bridgePort ? {} : { bridgePort }),
191
+ });
186
192
  }
187
193
  }
188
194
  stop() {
@@ -8,5 +8,13 @@ export interface Progress {
8
8
  readonly urlSuppliedByCaller: boolean;
9
9
  readonly url?: string | undefined;
10
10
  readonly devCommand?: string | undefined;
11
+ /** The Vite config that init could not patch and left as a manual step. */
12
+ readonly pendingViteConfig?: string | undefined;
11
13
  }
14
+ /**
15
+ * Said when the dev server stops after init left the Vite config unpatched (#1263).
16
+ *
17
+ * The dev server loads that config, so the step init already reported is the first cause to check.
18
+ */
19
+ export declare const pendingViteConfigCause: (config: string) => string;
12
20
  export declare function remainingSteps(p: Progress): string[];
@@ -6,6 +6,13 @@
6
6
  * worked — it should pick up at the step that did not. Ordered, and only ever the REMAINING steps.
7
7
  */
8
8
  import { FEEDBACK_KIND_CHOICES } from '@reticlehq/core';
9
+ /**
10
+ * Said when the dev server stops after init left the Vite config unpatched (#1263).
11
+ *
12
+ * The dev server loads that config, so the step init already reported is the first cause to check.
13
+ */
14
+ export const pendingViteConfigCause = (config) => `init could not patch ${config}, and its ⚠ Vite plugin step is not done. ` +
15
+ 'The dev server loads that config, so that step is the likely cause. Do it first.';
9
16
  const DOCS_INDEX = 'https://docs.reticle.sh/llms.txt';
10
17
  /**
11
18
  * The shell form on purpose, not `reticle_session { action: "feedback" }`.
@@ -21,6 +28,9 @@ export function remainingSteps(p) {
21
28
  if (!p.initDone) {
22
29
  steps.push('Run `npx @reticlehq/server@latest init` here, and fix every ⚠ it reports.');
23
30
  }
31
+ if (undefined !== p.pendingViteConfig) {
32
+ steps.push(`Do the ⚠ Vite plugin step that init printed: add \`reticle()\` to the plugins in ${p.pendingViteConfig}, or to the config that the dev server loads.`);
33
+ }
24
34
  if (!p.devServerUp && !p.urlSuppliedByCaller) {
25
35
  steps.push(`Start the dev server yourself: ${p.devCommand ?? 'the dev script in package.json'}, then open the app in a browser.`);
26
36
  }
@@ -158,6 +158,8 @@ export interface SetupInput {
158
158
  readonly suppliedUrl?: string | undefined;
159
159
  /** The port the dev command will take, when it is known. See probe/dev-port.ts. */
160
160
  readonly devPort?: number | undefined;
161
+ /** The Vite config init left for a manual step. A dev-server stop names it (#1263). */
162
+ readonly pendingViteConfig?: string | undefined;
161
163
  /**
162
164
  * The caller's own budget for the connect wait, when they named one.
163
165
  *
@@ -26,7 +26,7 @@ const WINDOWS_QUIET_MEANS_HUNG_MS = 3 * 60_000;
26
26
  const WINDOWS_QUIET_MEANS_HUNG_MS_APPLIES = 'win32' === process.platform;
27
27
  import { liveSessionOfProject, pickSession } from './session-pick.js';
28
28
  import { readPage, describePage, findingBeforeOpen, PageFinding, } from './probe/page-probe.js';
29
- import { remainingSteps } from './remaining-steps.js';
29
+ import { pendingViteConfigCause, remainingSteps } from './remaining-steps.js';
30
30
  import { splitDevPortNote } from './probe/dev-port.js';
31
31
  import { AppShape, isDesktop, policyFor } from './desktop-shape.js';
32
32
  import { InitStop } from '@reticlehq/core/telemetry';
@@ -82,6 +82,7 @@ const asProgress = (input, o) => ({
82
82
  urlSuppliedByCaller: undefined !== input.suppliedUrl,
83
83
  ...(undefined === o.url ? {} : { url: o.url }),
84
84
  ...(undefined === input.devCommand ? {} : { devCommand: input.devCommand }),
85
+ ...(undefined === input.pendingViteConfig ? {} : { pendingViteConfig: input.pendingViteConfig }),
85
86
  });
86
87
  /** The connect step a web page stopped at. A bundle-connect page's HTML never shows the SDK. */
87
88
  const connectStop = (finding, htmlCarriesSdk) => {
@@ -215,6 +216,10 @@ export async function runSetupPhases(input, fx) {
215
216
  if (WaitVerdict.DEAD === verdict) {
216
217
  const busy = portBusyMessage(fx.devServerOutput());
217
218
  note(busy ?? devServerDiedMessage(fx.devServerOutput()));
219
+ // A busy port is its own cause. Any other exit can come from the config init left alone.
220
+ if (undefined === busy && undefined !== input.pendingViteConfig) {
221
+ note(pendingViteConfigCause(input.pendingViteConfig));
222
+ }
218
223
  const step = undefined === busy ? InitStop.DEV_SERVER_EXITED : InitStop.PORT_BUSY;
219
224
  return stop(input, SetupPhase.DEV_SERVER, { stop: step }, notes);
220
225
  }
@@ -231,6 +236,9 @@ export async function runSetupPhases(input, fx) {
231
236
  ? `The dev server did not become ready${within}. `
232
237
  : `The dev server stopped making progress before ${watching} became ready. `) +
233
238
  'Check its log, increase --timeout for a slow build, or pass --url with the address it serves.');
239
+ if (undefined !== input.pendingViteConfig) {
240
+ note(pendingViteConfigCause(input.pendingViteConfig));
241
+ }
234
242
  const step = undefined === watching ? InitStop.NO_URL : InitStop.NOT_READY;
235
243
  return stop(input, SetupPhase.DEV_SERVER, { stop: step }, notes);
236
244
  }