@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,6 +8,7 @@
8
8
  import { chmodSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
9
9
  import { homedir } from 'node:os';
10
10
  import { join } from 'node:path';
11
+ import { mcpLauncher } from './mcp-launcher.js';
11
12
  import { planAgentConfigs, platformKey } from './agent-configs.js';
12
13
  import { AppShape, describeShape, readShape } from './desktop-shape.js';
13
14
  import { devConfigText, expectedDevPort, loneLoopbackOnDevPort, pinnedDevPort, } from './probe/dev-port.js';
@@ -25,7 +26,7 @@ import { spawnSync } from 'node:child_process';
25
26
  import { isAlive, reticleStateHome } from '../daemon/daemon.js';
26
27
  import { readDevServers } from '../daemon/dev-servers.js';
27
28
  import { connectedAppUrl, urlOfExistingApp } from './probe/existing-app.js';
28
- import { handedOverUrl, stopHandedOver } from './bringup/dev-server-files.js';
29
+ import { handedOverToOtherPort, handedOverUrl, stopHandedOver, } from './bringup/dev-server-files.js';
29
30
  import { listSessions, OwnedDevServer, probePage } from './node-effects.js';
30
31
  import { fetchStatus } from '../daemon/binding/daemon-status-probe.js';
31
32
  import { daemonSkew, summarizeStatus } from '../cli/launch/cli-launch.js';
@@ -73,8 +74,9 @@ export function installCrashGuard() {
73
74
  function hasElectronDependency(dir) {
74
75
  try {
75
76
  const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
76
- if ('object' !== typeof pkg || null === pkg)
77
+ if ('object' !== typeof pkg || null === pkg) {
77
78
  return false;
79
+ }
78
80
  const p = pkg;
79
81
  return undefined !== { ...p.dependencies, ...p.devDependencies }['electron'];
80
82
  }
@@ -95,7 +97,13 @@ const agentWord = (n) => (1 === n ? 'agent' : 'agents');
95
97
  export function registerOtherAgents(print) {
96
98
  const platform = platformKey(process.platform);
97
99
  const home = homedir();
98
- const results = applyAgentPlan(planAgentConfigs({ home, platform, exists: agentIo.exists, readFile: agentIo.readFile }), agentIo);
100
+ const results = applyAgentPlan(planAgentConfigs({
101
+ home,
102
+ platform,
103
+ exists: agentIo.exists,
104
+ readFile: agentIo.readFile,
105
+ launcher: mcpLauncher(),
106
+ }), agentIo);
99
107
  const wrote = results.filter((r) => 'created' === r.action || 'merged' === r.action);
100
108
  if (0 < wrote.length) {
101
109
  print(` ✓ ${String(wrote.length)} more ${agentWord(wrote.length)}: ${wrote.map((r) => r.name).join(', ')}`);
@@ -115,8 +123,9 @@ export function registerOtherAgents(print) {
115
123
  }
116
124
  rememberSaid(stateHome, fresh.map((n) => noticeKey(n)));
117
125
  const skills = applyAgentSkills(agentIo, { home, platform });
118
- if (0 < skills.length)
126
+ if (0 < skills.length) {
119
127
  print(` ✓ the /reticle skill, for ${String(skills.length)} ${agentWord(skills.length)}`);
128
+ }
120
129
  // Registration alone still leaves an Accept dialog in front of every call, and a verification run
121
130
  // makes dozens of them: the loop is only autonomous once the tools are pre-approved.
122
131
  const approvals = grantAutoApproval(agentIo, { home, platform });
@@ -173,8 +182,9 @@ async function restartHandedOverServer(appDir) {
173
182
  */
174
183
  async function afterConnect(input, url, sessionId, outcome, print) {
175
184
  const notes = [...outcome.notes];
176
- if (input.firstFlow === undefined)
185
+ if (input.firstFlow === undefined) {
177
186
  return { flowSaved: false, notes };
187
+ }
178
188
  const { flowSaved } = await input.firstFlow({
179
189
  appDir: input.appDir,
180
190
  bridgePort: input.bridgePort,
@@ -192,8 +202,9 @@ async function afterConnect(input, url, sessionId, outcome, print) {
192
202
  return { flowSaved, notes };
193
203
  }
194
204
  export async function runSetupCommand(input, print) {
195
- if (input.registerAgents)
205
+ if (input.registerAgents) {
196
206
  registerOtherAgents(print);
207
+ }
197
208
  // A moved port first: this project's daemon on the OLD port would otherwise be the one the page
198
209
  // finds and dials, while everything below waits on the new one.
199
210
  const retired = await retireMovedDaemons(readProjectId(input.appDir), input.bridgePort, nodeRetireDeps());
@@ -203,14 +214,18 @@ export async function runSetupCommand(input, print) {
203
214
  }
204
215
  // And the dev server a previous init left running, which may have read the old port once at
205
216
  // startup (Next does) — so the attach below would keep a page dialling the daemon just stopped.
206
- if (0 < retired.length && (await restartHandedOverServer(input.appDir))) {
217
+ // Its record names the port it was started for, so this works when the old daemon is gone too.
218
+ const movedUnderServer = 0 < retired.length ||
219
+ handedOverToOtherPort(reticleStateHome(), input.appDir, input.bridgePort, { alive: isAlive });
220
+ if (movedUnderServer && (await restartHandedOverServer(input.appDir))) {
207
221
  print(`stopped the dev server a previous init started, so it restarts on port ${String(input.bridgePort)}.`);
208
222
  }
209
223
  // Before the app is booted, because the app's whole job from here is to dial this port. Without
210
224
  // it the phases wait out their budget and then report the SDK as the thing that failed.
211
225
  const daemon = await ensureDaemon(input.bridgePort, nodeEnsureDaemonDeps((status) => undefined !== daemonSkew(status)));
212
- if (undefined !== daemon.message)
226
+ if (undefined !== daemon.message) {
213
227
  print(daemon.message);
228
+ }
214
229
  if (EnsureDaemon.SKEWED_IN_USE === daemon.state) {
215
230
  // Stop here: every hello from the page would be refused, and waiting out the connect budget
216
231
  // only to blame the page is the run this exists to prevent.
@@ -235,8 +250,9 @@ export async function runSetupCommand(input, print) {
235
250
  hasTauriConf: existsSync(join(input.appDir, 'src-tauri', 'tauri.conf.json')),
236
251
  hasElectronDep: hasElectronDependency(input.appDir),
237
252
  });
238
- if (AppShape.WEB !== shape)
253
+ if (AppShape.WEB !== shape) {
239
254
  print(`detected ${describeShape(shape)}`);
255
+ }
240
256
  const server = new OwnedDevServer();
241
257
  const effects = {
242
258
  startDevServer: (command, cwd) => {
@@ -261,8 +277,9 @@ export async function runSetupCommand(input, print) {
261
277
  },
262
278
  })
263
279
  : {};
264
- if (SigningEnv.IDENTITY in signing)
280
+ if (SigningEnv.IDENTITY in signing) {
265
281
  print(`signing the dev build as ${String(signing[SigningEnv.IDENTITY])}, so macOS does not ask for the keychain password`);
282
+ }
266
283
  server.start(command, cwd, { ...input.env, ...signing });
267
284
  return Promise.resolve();
268
285
  },
@@ -288,8 +305,9 @@ export async function runSetupCommand(input, print) {
288
305
  probePage,
289
306
  openBrowser: async (url) => {
290
307
  const failure = await openInBrowser(url);
291
- if (null === failure)
308
+ if (null === failure) {
292
309
  return undefined;
310
+ }
293
311
  // It used to end "nothing else here will open one", which stopped being true once a
294
312
  // Reticle-owned browser could always launch: run-setup opens a lease on this failure, so the
295
313
  // reader is told what happens next rather than sent to find a browser by hand.
@@ -310,8 +328,9 @@ export async function runSetupCommand(input, print) {
310
328
  // A daemon too old to report the short one falls back to the long one, because saying the
311
329
  // right thing at length beats saying nothing.
312
330
  const lead = status.whyLead ?? full;
313
- if (undefined === lead)
331
+ if (undefined === lead) {
314
332
  return undefined;
333
+ }
315
334
  return undefined === full ? { lead } : { lead, full };
316
335
  },
317
336
  now: () => Date.now(),
@@ -348,15 +367,17 @@ export async function runSetupCommand(input, print) {
348
367
  }, effects);
349
368
  // The app stays up only when there is something worth watching.
350
369
  if (outcome.ok) {
351
- server.handOver(outcome.url);
370
+ server.handOver(outcome.url, input.bridgePort);
352
371
  // Its output is on a file now, not this terminal, so say where: a compile error that used to
353
372
  // scroll past here is the first thing somebody will look for.
354
373
  const log = server.logPath();
355
- if (undefined !== log)
374
+ if (undefined !== log) {
356
375
  print(`The dev server keeps running; its output goes to ${log}`);
376
+ }
357
377
  }
358
- if (!outcome.ok || undefined === outcome.url || undefined === outcome.sessionId)
378
+ if (!outcome.ok || undefined === outcome.url || undefined === outcome.sessionId) {
359
379
  return outcome;
380
+ }
360
381
  return {
361
382
  ...outcome,
362
383
  ...(await afterConnect(input, outcome.url, outcome.sessionId, outcome, print)),
@@ -17,6 +17,8 @@ export interface SetupMcpIo {
17
17
  writeFile(path: string, contents: string): void;
18
18
  homeDir(): string;
19
19
  print(line: string): void;
20
+ /** The installed bin to register (`InitHost.mcpLauncher`). Absent: the pinned npx command. */
21
+ readonly launcher?: string | undefined;
20
22
  /** Register with a client that owns its own registration (Claude Code). Returns whether it took. */
21
23
  runCli(command: string, args: readonly string[]): boolean;
22
24
  /**
@@ -46,6 +48,12 @@ export interface SetupMcpResult {
46
48
  * and a pre-seeded `~/.codex/config.toml`; the file came back byte-identical both times.
47
49
  */
48
50
  readonly manual: readonly ManualClient[];
51
+ /** Clients whose Reticle plugin brings the server, so nothing was registered for them. */
52
+ readonly pluginActive: readonly string[];
53
+ /** Clients with the plugin AND a user-scope `reticle` entry: two servers. Named, never removed. */
54
+ readonly duplicates: readonly string[];
55
+ /** Clients whose `reticle` entry is the floating npx form. Named with the fix, never replaced. */
56
+ readonly stale: readonly string[];
49
57
  }
50
58
  /** A client the caller has to tell somebody about, with the two facts they need to act. */
51
59
  export interface ManualClient {
@@ -1,5 +1,5 @@
1
- import { McpClient, MCP_CLIENTS, claudeAddCommand, claudeAvailableProbe, claudeHasReticle, codexAddCommand, codexAvailableProbe, codexNamesOurServer, detectMcpClients, mergeClientConfig, clientSpec, ClientMergeStatus, } from '@reticlehq/init';
2
- import { OnboardingPhase, OnboardingStepStatus, } from '@reticlehq/core/telemetry';
1
+ import { McpClient, MCP_CLIENTS, claudeAddCommand, claudeAvailableProbe, claudeHasReticle, claudePluginInstalled, claudeUserEntryIsFloating, codexAddCommand, codexAvailableProbe, codexNamesOurServer, detectMcpClients, mergeClientConfig, clientSpec, ClientMergeStatus, } from '@reticlehq/init';
2
+ import { OnboardingPhase, OnboardingStepStatus, OnboardingStop, } from '@reticlehq/core/telemetry';
3
3
  /**
4
4
  * Codex registers through `codex mcp add`, which does the TOML editing we refuse to do (#1238).
5
5
  * `undefined` when that does not apply, and the caller reports a hand edit exactly as before: not
@@ -12,9 +12,10 @@ function registerWithCodexCli(io, client, serversKey) {
12
12
  return undefined;
13
13
  }
14
14
  const probe = codexAvailableProbe();
15
- if (!io.runCli(probe.command, probe.args))
15
+ if (!io.runCli(probe.command, probe.args)) {
16
16
  return undefined;
17
- const cmd = codexAddCommand();
17
+ }
18
+ const cmd = codexAddCommand(io.launcher);
18
19
  return io.runCli(cmd.command, cmd.args);
19
20
  }
20
21
  export function setupMcp(io) {
@@ -23,6 +24,9 @@ export function setupMcp(io) {
23
24
  const alreadyThere = [];
24
25
  const failed = [];
25
26
  const manual = [];
27
+ const pluginActive = [];
28
+ const duplicates = [];
29
+ const stale = [];
26
30
  /*
27
31
  * Claude Code first, because nothing else can find it.
28
32
  *
@@ -41,21 +45,34 @@ export function setupMcp(io) {
41
45
  if (io.runCli(available.command, available.args)) {
42
46
  detected.push(McpClient.CLAUDE_CODE);
43
47
  // Read from Claude's config: `claude mcp get` health-checks by launching the server.
44
- if (claudeHasReticle(io, undefined)) {
48
+ const hasEntry = claudeHasReticle(io, undefined);
49
+ if (claudePluginInstalled(io)) {
50
+ // The plugin brings its own server. A user-scope entry next to it is a second one.
51
+ pluginActive.push(McpClient.CLAUDE_CODE);
52
+ if (hasEntry) {
53
+ duplicates.push(McpClient.CLAUDE_CODE);
54
+ }
55
+ }
56
+ else if (hasEntry) {
45
57
  alreadyThere.push(McpClient.CLAUDE_CODE);
58
+ if (claudeUserEntryIsFloating(io)) {
59
+ stale.push(McpClient.CLAUDE_CODE);
60
+ }
46
61
  }
47
62
  else {
48
- const cmd = claudeAddCommand();
49
- if (io.runCli(cmd.command, cmd.args))
63
+ const cmd = claudeAddCommand(io.launcher);
64
+ if (io.runCli(cmd.command, cmd.args)) {
50
65
  registered.push(McpClient.CLAUDE_CODE);
51
- else
66
+ }
67
+ else {
52
68
  failed.push(McpClient.CLAUDE_CODE);
69
+ }
53
70
  }
54
71
  }
55
72
  for (const client of detectMcpClients(io)) {
56
73
  detected.push(client.id);
57
74
  const spec = clientSpec(client.id);
58
- const merged = mergeClientConfig(spec, client.existing);
75
+ const merged = mergeClientConfig(spec, client.existing, io.launcher);
59
76
  if (ClientMergeStatus.ALREADY === merged.status) {
60
77
  alreadyThere.push(client.id);
61
78
  continue;
@@ -65,12 +82,15 @@ export function setupMcp(io) {
65
82
  // sends somebody to an agent that has no Reticle tools in it.
66
83
  if (ClientMergeStatus.MANUAL === merged.status) {
67
84
  const viaCli = registerWithCodexCli(io, client, spec.serversKey);
68
- if (true === viaCli)
85
+ if (true === viaCli) {
69
86
  registered.push(client.id);
70
- else if (false === viaCli)
87
+ }
88
+ else if (false === viaCli) {
71
89
  failed.push(client.id);
72
- else
90
+ }
91
+ else {
73
92
  manual.push({ id: client.id, configPath: client.configPath, docs: spec.docs });
93
+ }
74
94
  continue;
75
95
  }
76
96
  try {
@@ -93,6 +113,7 @@ export function setupMcp(io) {
93
113
  step: 'agents_detected',
94
114
  status: OnboardingStepStatus.COMPLETED,
95
115
  });
116
+ const mcpStatus = mcpRegisteredStatus(detected.length, registered.length, alreadyThere.length + pluginActive.length);
96
117
  io.reportStep({
97
118
  phase: OnboardingPhase.INSTALL,
98
119
  step: 'mcp_registered',
@@ -107,15 +128,21 @@ export function setupMcp(io) {
107
128
  * for. Registering some and not others is still COMPLETED: the agent they are using may well be
108
129
  * one that worked, and a partial win is not a failed step.
109
130
  */
110
- status: 0 === detected.length
111
- ? OnboardingStepStatus.SKIPPED
112
- : 0 === registered.length && alreadyThere.length > 0
113
- ? OnboardingStepStatus.SKIPPED
114
- : 0 === registered.length && 0 === alreadyThere.length
115
- ? OnboardingStepStatus.FAILED
116
- : OnboardingStepStatus.COMPLETED,
131
+ status: mcpStatus,
132
+ ...(OnboardingStepStatus.FAILED === mcpStatus
133
+ ? { stop: OnboardingStop.MCP_NOT_REGISTERED }
134
+ : {}),
117
135
  });
118
- return { detected, registered, alreadyThere, failed, manual };
136
+ return { detected, registered, alreadyThere, failed, manual, pluginActive, duplicates, stale };
137
+ }
138
+ function mcpRegisteredStatus(detected, registered, alreadyThere) {
139
+ if (0 === detected || (0 === registered && 0 < alreadyThere)) {
140
+ return OnboardingStepStatus.SKIPPED;
141
+ }
142
+ if (0 === registered) {
143
+ return OnboardingStepStatus.FAILED;
144
+ }
145
+ return OnboardingStepStatus.COMPLETED;
119
146
  }
120
147
  /** Everything this machine could be asked about, for the report when nothing was found. */
121
148
  export function knownClientLabels() {
@@ -0,0 +1,8 @@
1
+ /** The url it serves and how to stop it, or why it did not serve. */
2
+ export type StartedDevServer = {
3
+ url: string;
4
+ stop: () => void;
5
+ } | {
6
+ failed: string;
7
+ };
8
+ export declare function startDevServerAndWait(command: string, dir: string, budgetMs: number): Promise<StartedDevServer>;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Start a project's dev script and wait until it serves a page, for a command that is not `init`.
3
+ *
4
+ * The same pieces `init` uses: the supervised `OwnedDevServer`, the URL it announces or the port its
5
+ * process tree binds, and `judgeWait` for ready, dead or hung. `init` keeps its own loop because it
6
+ * also reports progress and hands the server over; this one stops the server when the caller is done.
7
+ */
8
+ import { OwnedDevServer, probePage } from './node-effects.js';
9
+ import { WaitVerdict, devServerDiedMessage, judgeWait, portBusyMessage, urlToWatch, } from './bringup/dev-server-wait.js';
10
+ const POLL_MS = 500;
11
+ const MS_PER_S = 1000;
12
+ export async function startDevServerAndWait(command, dir, budgetMs) {
13
+ const server = new OwnedDevServer();
14
+ server.start(command, dir, {});
15
+ const startedAt = Date.now();
16
+ for (;;) {
17
+ const watching = urlToWatch(server.output(), server.listeningPorts());
18
+ const probe = watching === undefined ? undefined : await probePage(watching);
19
+ const verdict = judgeWait({
20
+ output: server.output(),
21
+ launcherExited: server.exited(),
22
+ serving: true === probe?.served,
23
+ quietForMs: server.quietForMs(),
24
+ elapsedMs: Date.now() - startedAt,
25
+ budgetMs,
26
+ });
27
+ if (WaitVerdict.READY === verdict && watching !== undefined) {
28
+ return { url: probe?.reachedUrl ?? watching, stop: () => server.stop() };
29
+ }
30
+ if (WaitVerdict.DEAD === verdict) {
31
+ const failed = portBusyMessage(server.output()) ?? devServerDiedMessage(server.output());
32
+ server.stop();
33
+ return { failed };
34
+ }
35
+ if (WaitVerdict.HUNG === verdict) {
36
+ server.stop();
37
+ return {
38
+ failed: `The dev server did not serve a page in ${String(budgetMs / MS_PER_S)}s.`,
39
+ };
40
+ }
41
+ await new Promise((resolve) => setTimeout(resolve, POLL_MS));
42
+ }
43
+ }
@@ -1,5 +1,6 @@
1
1
  import { execFile } from 'node:child_process';
2
2
  import { NodePlatform } from '../../machine/platform.js';
3
+ import { PLUGIN_SERVER_DIR } from '../../telemetry/agent-client.js';
3
4
  import { existsSync } from 'node:fs';
4
5
  import { platform } from 'node:os';
5
6
  import { dirname, join } from 'node:path';
@@ -63,6 +64,11 @@ function detectExecutionKind() {
63
64
  export function classifyExecutionKind(script) {
64
65
  if (script.includes('/_npx/') || script.includes('\\_npx\\'))
65
66
  return ExecutionKind.NPX;
67
+ // The Claude Code plugin's copy sits in a `node_modules`, but it is not the project's. It is pinned
68
+ // to the plugin version, so treat it as npx: a restart picks the version, and nothing is installed.
69
+ if (script.includes(`/${PLUGIN_SERVER_DIR}/`) || script.includes(`\\${PLUGIN_SERVER_DIR}\\`)) {
70
+ return ExecutionKind.NPX;
71
+ }
66
72
  const globalSignals = [
67
73
  '/lib/node_modules/',
68
74
  '\\npm\\node_modules\\',
@@ -5,3 +5,5 @@ export declare const SERVER_VERSION: string;
5
5
  * drift. Self-update installs THIS (never `@reticlehq/core`, which is schema-only and has no bin).
6
6
  */
7
7
  export declare const RETICLE_NPM_PACKAGE: string;
8
+ /** The Node.js range this package declares in `engines`, such as `>=20.11`. */
9
+ export declare const SERVER_NODE_RANGE: string | undefined;
@@ -48,3 +48,5 @@ export const SERVER_VERSION = _pkg.version;
48
48
  * drift. Self-update installs THIS (never `@reticlehq/core`, which is schema-only and has no bin).
49
49
  */
50
50
  export const RETICLE_NPM_PACKAGE = _pkg.name;
51
+ /** The Node.js range this package declares in `engines`, such as `>=20.11`. */
52
+ export const SERVER_NODE_RANGE = _pkg.engines?.node;
@@ -106,6 +106,13 @@ export declare function compareVersions(a: string | undefined, b: string): numbe
106
106
  export declare function sdkIsBehind(sdk: string | undefined, daemon: string): boolean;
107
107
  /** The same fact for the person looking at the page, on its overlay. */
108
108
  export declare const SDK_BEHIND_NARRATION: (sdk: string, daemon: string) => string;
109
+ /**
110
+ * The sentence for a screenshot the page cannot draw because its SDK is behind this daemon.
111
+ *
112
+ * `render` is one of the things a behind page does not have. The refusal from the page names the
113
+ * missing command and nothing else; this is the same update the overlay already shows.
114
+ */
115
+ export declare function sdkBehindNote(sdk: string | undefined): string | undefined;
109
116
  /**
110
117
  * A page whose SDK is a minor release or more behind this daemon.
111
118
  *
@@ -23,6 +23,7 @@
23
23
  * a human acts on.
24
24
  */
25
25
  import { RETIRED_WIRE_NAMES } from '@reticlehq/core';
26
+ import { SERVER_VERSION } from './identity/server-version.js';
26
27
  import { resolveSdkFix } from './sdk-fix.js';
27
28
  /** Which pair disagreed. Named so the nudge can report each independently. */
28
29
  export const SkewPair = {
@@ -60,7 +61,7 @@ function namesWeDoNotKnow(peer, self) {
60
61
  export const SKEW_CONVERGE = "To put every piece on one version, update the CLI and the app SDK (`reticle update` in the app's " +
61
62
  'folder does both), then restart the MCP host.';
62
63
  /** The fix for two builds of one version. */
63
- const SAME_VERSION_FIX = 'Both say the same version, so one of them is an older build of it: run `reticle restart`, then ' +
64
+ const SAME_VERSION_FIX = 'Both say the same version, so one of them is an older build of it: run `reticle serve --restart`, then ' +
64
65
  'reload the page so it loads the SDK the dev server serves now.';
65
66
  function versionPhrase(peer, self) {
66
67
  return peer.version === undefined
@@ -177,9 +178,19 @@ export function sdkIsBehind(sdk, daemon) {
177
178
  const order = compareVersions(minorOf(sdk), minorOf(daemon));
178
179
  return order !== undefined && order < 0;
179
180
  }
181
+ /** What to run so the page picks up the daemon's SDK. */
182
+ const UPDATE_THE_SDK = "Run `reticle update` in the app's folder, then restart its dev server.";
180
183
  /** The same fact for the person looking at the page, on its overlay. */
181
- export const SDK_BEHIND_NARRATION = (sdk, daemon) => `This app runs Reticle SDK ${sdk}, older than Reticle ${daemon}. Run \`reticle update\` in the ` +
182
- "app's folder, then restart its dev server.";
184
+ export const SDK_BEHIND_NARRATION = (sdk, daemon) => `This app runs Reticle SDK ${sdk}, older than Reticle ${daemon}. ${UPDATE_THE_SDK}`;
185
+ /**
186
+ * The sentence for a screenshot the page cannot draw because its SDK is behind this daemon.
187
+ *
188
+ * `render` is one of the things a behind page does not have. The refusal from the page names the
189
+ * missing command and nothing else; this is the same update the overlay already shows.
190
+ */
191
+ export function sdkBehindNote(sdk) {
192
+ return describeSdkBehind(sdk, SERVER_VERSION, () => UPDATE_THE_SDK);
193
+ }
183
194
  /**
184
195
  * A page whose SDK is a minor release or more behind this daemon.
185
196
  *