@reticlehq/server 2.13.0 → 2.14.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 (451) hide show
  1. package/SKILL.md +8 -18
  2. package/bin/reticle.js +3 -0
  3. package/dist/bridge/auth-failure-reason.js +12 -1
  4. package/dist/bridge/bridge-security.d.ts +8 -0
  5. package/dist/bridge/bridge-security.js +6 -1
  6. package/dist/bridge/bridge.d.ts +3 -0
  7. package/dist/bridge/bridge.js +23 -1
  8. package/dist/bridge/bridge.test-harness.d.ts +10 -1
  9. package/dist/bridge/bridge.test-harness.js +7 -1
  10. package/dist/bridge/pairing-token.d.ts +17 -0
  11. package/dist/bridge/pairing-token.js +26 -0
  12. package/dist/bridge/token-auth.d.ts +7 -0
  13. package/dist/bridge/token-auth.js +7 -1
  14. package/dist/capsule/capsule-store.d.ts +4 -4
  15. package/dist/capsule/capsule.d.ts +1 -1
  16. package/dist/capsule/capsule.js +3 -3
  17. package/dist/capsule/causal-summary.d.ts +21 -1
  18. package/dist/capsule/causal-summary.js +8 -6
  19. package/dist/capsule/divergence.d.ts +1 -1
  20. package/dist/capsule/divergence.js +26 -10
  21. package/dist/chromium-launch-options.d.ts +2 -1
  22. package/dist/cli/adhoc-verdict.d.ts +58 -0
  23. package/dist/cli/adhoc-verdict.js +115 -0
  24. package/dist/cli/chromium-hint.d.ts +18 -4
  25. package/dist/cli/chromium-hint.js +54 -6
  26. package/dist/cli/cli-doctor.js +1 -2
  27. package/dist/cli/cli-flow-commands.d.ts +16 -2
  28. package/dist/cli/cli-flow-commands.js +28 -9
  29. package/dist/cli/cli-parse-feedback.js +1 -1
  30. package/dist/cli/cli-parse.d.ts +2 -1
  31. package/dist/cli/cli-parse.js +38 -0
  32. package/dist/cli/cli-port.d.ts +5 -13
  33. package/dist/cli/cli-port.js +5 -38
  34. package/dist/cli/cli-update-commands.js +4 -4
  35. package/dist/cli/cli-verify.d.ts +24 -7
  36. package/dist/cli/cli-verify.js +87 -13
  37. package/dist/cli/cloud-keystore.d.ts +2 -1
  38. package/dist/cli/cloud-login.d.ts +2 -1
  39. package/dist/cli/cloud-session.d.ts +2 -1
  40. package/dist/cli/cloud-session.js +1 -1
  41. package/dist/cli/daemon-start-options.d.ts +2 -1
  42. package/dist/cli/device-flow.d.ts +2 -2
  43. package/dist/cli/doctor-daemon-line.d.ts +2 -1
  44. package/dist/cli/doctor-project-line.d.ts +2 -1
  45. package/dist/cli/doctor-rows.d.ts +2 -1
  46. package/dist/cli/drive-attach.d.ts +4 -3
  47. package/dist/cli/gate-hook-message.d.ts +2 -1
  48. package/dist/cli/status-next-action.js +10 -11
  49. package/dist/cli.d.ts +1 -0
  50. package/dist/cli.js +21 -9
  51. package/dist/cloud/account-state.d.ts +20 -0
  52. package/dist/cloud/account-state.js +65 -0
  53. package/dist/cloud/cloud-sync.d.ts +46 -3
  54. package/dist/cloud/cloud-sync.js +116 -0
  55. package/dist/cloud/sync-cycle.d.ts +5 -4
  56. package/dist/cloud/sync-cycle.js +1 -1
  57. package/dist/cloud/sync-daemon.d.ts +3 -19
  58. package/dist/cloud/sync-daemon.js +2 -2
  59. package/dist/crawl/crawl-tools.js +1 -1
  60. package/dist/crawl/crawl.d.ts +5 -5
  61. package/dist/crawl/crawl.js +138 -4
  62. package/dist/daemon/daemon-resilience.d.ts +3 -2
  63. package/dist/daemon/daemon-resilience.js +43 -4
  64. package/dist/daemon/daemon-resolve.d.ts +0 -9
  65. package/dist/daemon/daemon-resolve.js +2 -2
  66. package/dist/daemon/dev-servers.d.ts +1 -1
  67. package/dist/daemon/dev-servers.js +1 -1
  68. package/dist/daemon/loopback-alias.d.ts +2 -1
  69. package/dist/daemon/startup-failure.d.ts +11 -0
  70. package/dist/daemon/startup-failure.js +46 -0
  71. package/dist/events/contradictions.d.ts +10 -16
  72. package/dist/events/contradictions.js +149 -17
  73. package/dist/events/declared.d.ts +13 -1
  74. package/dist/events/declared.js +59 -3
  75. package/dist/events/echo-mismatch.js +75 -6
  76. package/dist/events/lineage.d.ts +52 -0
  77. package/dist/events/lineage.js +122 -0
  78. package/dist/events/net-evidence.d.ts +21 -0
  79. package/dist/events/net-evidence.js +81 -0
  80. package/dist/events/predicate-console.d.ts +13 -0
  81. package/dist/events/predicate-console.js +138 -0
  82. package/dist/events/predicate-element.d.ts +13 -0
  83. package/dist/events/predicate-element.js +214 -0
  84. package/dist/events/predicate-eval.d.ts +15 -3
  85. package/dist/events/predicate-eval.js +128 -110
  86. package/dist/events/predicate-parse.js +34 -1
  87. package/dist/events/predicate-request-body.d.ts +50 -0
  88. package/dist/events/predicate-request-body.js +120 -0
  89. package/dist/events/predicate-route.d.ts +21 -1
  90. package/dist/events/predicate-route.js +149 -21
  91. package/dist/events/predicate-schema.d.ts +8 -1
  92. package/dist/events/predicate-schema.js +34 -0
  93. package/dist/events/predicate.d.ts +2 -0
  94. package/dist/events/predicate.js +52 -159
  95. package/dist/events/split-text-miss.d.ts +6 -4
  96. package/dist/events/split-text-miss.js +12 -5
  97. package/dist/flows/affected-tools.js +22 -9
  98. package/dist/flows/annotate.d.ts +2 -1
  99. package/dist/flows/annotate.js +19 -1
  100. package/dist/flows/coverage.d.ts +2 -2
  101. package/dist/flows/flake.d.ts +3 -3
  102. package/dist/flows/flow-expect-grammar.d.ts +33 -0
  103. package/dist/flows/flow-expect-grammar.js +155 -0
  104. package/dist/flows/flow-replay-run.d.ts +1 -1
  105. package/dist/flows/flow-replay-run.js +28 -15
  106. package/dist/flows/flow-replay.d.ts +10 -0
  107. package/dist/flows/flow-replay.js +57 -22
  108. package/dist/flows/flow-secret-field.d.ts +14 -0
  109. package/dist/flows/flow-secret-field.js +22 -0
  110. package/dist/flows/flow-step-runners.d.ts +1 -0
  111. package/dist/flows/flow-step-runners.js +91 -34
  112. package/dist/flows/flow-success.js +22 -0
  113. package/dist/flows/flow-tools.js +27 -8
  114. package/dist/flows/flow-upload-resolve.d.ts +23 -0
  115. package/dist/flows/flow-upload-resolve.js +46 -0
  116. package/dist/flows/flows.d.ts +15 -0
  117. package/dist/flows/flows.js +17 -14
  118. package/dist/flows/git-changed.d.ts +23 -4
  119. package/dist/flows/git-changed.js +32 -6
  120. package/dist/flows/heal-run.js +2 -2
  121. package/dist/flows/predicate-to-expect.d.ts +3 -2
  122. package/dist/flows/predicate-to-expect.js +11 -5
  123. package/dist/flows/recording-backtrack.d.ts +24 -0
  124. package/dist/flows/recording-backtrack.js +73 -0
  125. package/dist/flows/recordings.d.ts +6 -0
  126. package/dist/flows/replay-halt.d.ts +26 -0
  127. package/dist/flows/replay-halt.js +30 -0
  128. package/dist/flows/replay.d.ts +0 -8
  129. package/dist/flows/replay.js +15 -3
  130. package/dist/flows/suite-flakes.d.ts +2 -1
  131. package/dist/flows/verify-change-tools.js +16 -4
  132. package/dist/honesty/already-true.d.ts +14 -0
  133. package/dist/honesty/already-true.js +47 -4
  134. package/dist/honesty/blind-spots.d.ts +3 -1
  135. package/dist/honesty/blind-spots.js +24 -1
  136. package/dist/honesty/body-capture-remedy.d.ts +42 -0
  137. package/dist/honesty/body-capture-remedy.js +95 -0
  138. package/dist/honesty/feature-capture.d.ts +3 -2
  139. package/dist/honesty/feature-capture.js +1 -1
  140. package/dist/honesty/gap-ledger.d.ts +1 -1
  141. package/dist/honesty/gap-ledger.js +1 -1
  142. package/dist/honesty/instrumentation-gaps.d.ts +8 -1
  143. package/dist/honesty/instrumentation-gaps.js +12 -2
  144. package/dist/honesty/observability.d.ts +4 -3
  145. package/dist/honesty/tool-hit-rate.d.ts +3 -2
  146. package/dist/honesty/uncaptured-bodies.d.ts +3 -1
  147. package/dist/honesty/uncaptured-bodies.js +6 -2
  148. package/dist/honesty/unsettled.d.ts +9 -0
  149. package/dist/honesty/unsettled.js +45 -0
  150. package/dist/honesty/verified.d.ts +32 -1
  151. package/dist/honesty/verified.js +37 -10
  152. package/dist/impact/impact-store.d.ts +5 -14
  153. package/dist/impact/impact-store.js +49 -6
  154. package/dist/index.js +1 -1
  155. package/dist/input/network-detail.d.ts +26 -1
  156. package/dist/input/network-detail.js +44 -12
  157. package/dist/input/network-mock-tools.js +24 -17
  158. package/dist/input/real-input.js +1 -1
  159. package/dist/input/viewport-tools.js +25 -13
  160. package/dist/intent/inline-intent.d.ts +0 -10
  161. package/dist/intent/inline-intent.js +1 -1
  162. package/dist/intent/intent-shard-store.d.ts +3 -2
  163. package/dist/intent/intent-shard-store.js +1 -1
  164. package/dist/intent/intent-shard.d.ts +14 -14
  165. package/dist/intent/intent-shard.js +4 -4
  166. package/dist/intent/intent-store.d.ts +1 -1
  167. package/dist/intent/intent-store.js +1 -1
  168. package/dist/intent/intent-subject.d.ts +2 -1
  169. package/dist/intent/open-intents.d.ts +3 -2
  170. package/dist/license/license.d.ts +4 -4
  171. package/dist/license/license.js +1 -1
  172. package/dist/mcp/attach-memory.d.ts +2 -1
  173. package/dist/mcp/client-identity.d.ts +2 -1
  174. package/dist/mcp/mcp-outage.d.ts +1 -1
  175. package/dist/mcp/mcp-outage.js +1 -1
  176. package/dist/mcp/mcp-proxy.d.ts +3 -1
  177. package/dist/mcp/mcp-proxy.js +32 -7
  178. package/dist/mcp/mcp.js +3 -1
  179. package/dist/mcp/proxy-handshake.d.ts +2 -1
  180. package/dist/mcp/proxy-idle-exit.d.ts +45 -0
  181. package/dist/mcp/proxy-idle-exit.js +94 -0
  182. package/dist/mcp/server-instructions.d.ts +2 -1
  183. package/dist/memory/project-memory.d.ts +2 -3
  184. package/dist/memory/project-memory.js +1 -1
  185. package/dist/oracles/propose-consequences.js +5 -5
  186. package/dist/oracles/self-instrument.d.ts +2 -2
  187. package/dist/oracles/self-instrument.js +1 -1
  188. package/dist/platform.d.ts +3 -5
  189. package/dist/platform.js +3 -5
  190. package/dist/pool/browser-pool.d.ts +92 -0
  191. package/dist/pool/browser-pool.js +119 -5
  192. package/dist/pool/playwright-launcher.js +29 -2
  193. package/dist/pool/storage-seed.d.ts +23 -0
  194. package/dist/pool/storage-seed.js +198 -0
  195. package/dist/project/artifact-root.d.ts +2 -1
  196. package/dist/project/memory-fs.d.ts +2 -1
  197. package/dist/project/reticle-dir.js +1 -1
  198. package/dist/project/session-root.d.ts +8 -0
  199. package/dist/project/session-root.js +9 -2
  200. package/dist/runs/reticle-runner.d.ts +14 -1
  201. package/dist/runs/reticle-runner.js +39 -2
  202. package/dist/session/attachment-history.d.ts +2 -1
  203. package/dist/session/fake-session.d.ts +37 -0
  204. package/dist/session/fake-session.js +81 -0
  205. package/dist/session/lease-visibility.d.ts +2 -1
  206. package/dist/session/live-control-tools.js +6 -0
  207. package/dist/session/no-session-diagnosis.d.ts +17 -1
  208. package/dist/session/no-session-diagnosis.js +32 -6
  209. package/dist/session/no-session-next-action.d.ts +14 -0
  210. package/dist/session/no-session-next-action.js +18 -0
  211. package/dist/session/no-session-watch.js +46 -3
  212. package/dist/session/registered-projects.d.ts +54 -0
  213. package/dist/session/registered-projects.js +73 -0
  214. package/dist/session/review-store.d.ts +2 -1
  215. package/dist/session/session-health.d.ts +62 -1
  216. package/dist/session/session-health.js +82 -2
  217. package/dist/session/session-manager.d.ts +11 -1
  218. package/dist/session/session-manager.js +18 -3
  219. package/dist/session/session-replaced.d.ts +24 -0
  220. package/dist/session/session-replaced.js +29 -0
  221. package/dist/session/session-successor.js +20 -4
  222. package/dist/session/session.d.ts +13 -5
  223. package/dist/session/session.js +31 -23
  224. package/dist/setup/agent-configs.d.ts +3 -2
  225. package/dist/setup/agent-writer.d.ts +3 -2
  226. package/dist/setup/approval-migration.d.ts +2 -1
  227. package/dist/setup/approval-migration.js +1 -1
  228. package/dist/setup/auto-approve.d.ts +11 -19
  229. package/dist/setup/auto-approve.js +15 -12
  230. package/dist/{init → setup}/confirm.js +1 -1
  231. package/dist/setup/desktop-shape.d.ts +3 -2
  232. package/dist/setup/dev-server-wait.d.ts +8 -0
  233. package/dist/setup/dev-server-wait.js +3 -1
  234. package/dist/setup/drive-agent.d.ts +2 -3
  235. package/dist/setup/drive-agent.js +1 -1
  236. package/dist/setup/drive-plan.d.ts +3 -2
  237. package/dist/setup/ensure-daemon.d.ts +2 -1
  238. package/dist/setup/existing-app.d.ts +12 -0
  239. package/dist/setup/existing-app.js +13 -0
  240. package/dist/setup/init-host.d.ts +11 -0
  241. package/dist/setup/init-host.js +26 -0
  242. package/dist/setup/init-runtime.d.ts +4 -10
  243. package/dist/setup/init-runtime.js +23 -16
  244. package/dist/setup/license-key.d.ts +2 -1
  245. package/dist/setup/listeners.d.ts +2 -1
  246. package/dist/setup/loopback-probe-urls.d.ts +18 -0
  247. package/dist/setup/loopback-probe-urls.js +52 -0
  248. package/dist/setup/node-effects.d.ts +3 -0
  249. package/dist/setup/node-effects.js +26 -11
  250. package/dist/setup/page-probe.d.ts +5 -0
  251. package/dist/setup/relaunch.d.ts +2 -1
  252. package/dist/setup/run-setup.d.ts +5 -1
  253. package/dist/setup/run-setup.js +155 -48
  254. package/dist/setup/setup-command.d.ts +3 -2
  255. package/dist/setup/setup-command.js +8 -0
  256. package/dist/setup/setup-options.d.ts +5 -3
  257. package/dist/setup/setup-options.js +3 -2
  258. package/dist/setup/wait-progress.d.ts +28 -0
  259. package/dist/setup/wait-progress.js +43 -0
  260. package/dist/telemetry/app-instrumented.d.ts +2 -1
  261. package/dist/telemetry/app-instrumented.js +1 -1
  262. package/dist/telemetry/automation-hint.d.ts +1 -1
  263. package/dist/telemetry/automation-hint.js +1 -1
  264. package/dist/telemetry/cli-telemetry.js +1 -1
  265. package/dist/telemetry/connect-failure.d.ts +1 -1
  266. package/dist/telemetry/connect-failure.js +1 -1
  267. package/dist/telemetry/crash-cause.d.ts +3 -2
  268. package/dist/telemetry/crash-cause.js +1 -1
  269. package/dist/telemetry/daemon-telemetry.d.ts +3 -2
  270. package/dist/telemetry/daemon-telemetry.js +1 -1
  271. package/dist/telemetry/error-class.d.ts +3 -2
  272. package/dist/telemetry/error-class.js +1 -1
  273. package/dist/telemetry/feedback-cli.js +1 -1
  274. package/dist/telemetry/feedback-context.d.ts +3 -2
  275. package/dist/telemetry/feedback-context.js +5 -4
  276. package/dist/telemetry/feedback-local.d.ts +3 -2
  277. package/dist/telemetry/feedback.d.ts +4 -3
  278. package/dist/telemetry/feedback.js +1 -1
  279. package/dist/telemetry/git-facts.d.ts +2 -2
  280. package/dist/telemetry/git-facts.js +1 -1
  281. package/dist/telemetry/identify.d.ts +1 -1
  282. package/dist/telemetry/identify.js +1 -1
  283. package/dist/telemetry/init-telemetry.d.ts +2 -14
  284. package/dist/telemetry/init-telemetry.js +4 -13
  285. package/dist/telemetry/install-source.d.ts +7 -13
  286. package/dist/telemetry/install-source.js +7 -29
  287. package/dist/telemetry/license-activation.d.ts +3 -2
  288. package/dist/telemetry/license-activation.js +1 -1
  289. package/dist/telemetry/machine-snapshot.d.ts +1 -1
  290. package/dist/telemetry/mcp-connection.js +1 -1
  291. package/dist/telemetry/project-profile.d.ts +0 -14
  292. package/dist/telemetry/project-profile.js +1 -1
  293. package/dist/telemetry/proxy-telemetry.js +1 -1
  294. package/dist/telemetry/session-metrics.d.ts +1 -1
  295. package/dist/telemetry/session-metrics.js +1 -1
  296. package/dist/telemetry/telemetry.d.ts +1 -17
  297. package/dist/telemetry/telemetry.js +4 -4
  298. package/dist/telemetry/tool-refused.d.ts +1 -1
  299. package/dist/telemetry/tool-refused.js +1 -1
  300. package/dist/tools/act-observation.d.ts +3 -2
  301. package/dist/tools/act-preflight.js +8 -3
  302. package/dist/tools/act-target.d.ts +4 -0
  303. package/dist/tools/act-target.js +14 -5
  304. package/dist/tools/act-tools.d.ts +0 -2
  305. package/dist/tools/act-tools.js +45 -15
  306. package/dist/tools/assert-source.d.ts +30 -0
  307. package/dist/tools/assert-source.js +21 -0
  308. package/dist/tools/assert-verdict.d.ts +1 -1
  309. package/dist/tools/assert-verdict.js +14 -4
  310. package/dist/tools/browser-tools.js +28 -8
  311. package/dist/tools/complete-snapshot.d.ts +3 -2
  312. package/dist/tools/dynamic-tools.js +8 -0
  313. package/dist/tools/error-recovery.d.ts +10 -0
  314. package/dist/tools/error-recovery.js +23 -0
  315. package/dist/tools/feedback-tools.js +1 -1
  316. package/dist/tools/invoke-tool.js +2 -0
  317. package/dist/tools/lease-tools.d.ts +48 -20
  318. package/dist/tools/lease-tools.js +311 -76
  319. package/dist/tools/lineage-tools.d.ts +14 -0
  320. package/dist/tools/lineage-tools.js +64 -0
  321. package/dist/tools/merge-tools.js +1 -3
  322. package/dist/tools/navigate-arrival.d.ts +45 -1
  323. package/dist/tools/navigate-arrival.js +39 -6
  324. package/dist/tools/navigate-result.d.ts +8 -1
  325. package/dist/tools/navigate-result.js +14 -4
  326. package/dist/tools/numeric-bounds.d.ts +0 -11
  327. package/dist/tools/numeric-bounds.js +4 -4
  328. package/dist/tools/observe-tools.js +22 -26
  329. package/dist/tools/observed-nothing.d.ts +9 -0
  330. package/dist/tools/observed-nothing.js +2 -1
  331. package/dist/tools/read-tools.js +12 -17
  332. package/dist/tools/real-input-attempt.d.ts +14 -6
  333. package/dist/tools/real-input-attempt.js +75 -18
  334. package/dist/tools/reconcile-tools.js +2 -1
  335. package/dist/tools/reload-result.d.ts +6 -1
  336. package/dist/tools/reload-result.js +7 -2
  337. package/dist/tools/resolve-target.d.ts +7 -1
  338. package/dist/tools/resolve-target.js +72 -9
  339. package/dist/tools/settle-in-flight.d.ts +1 -1
  340. package/dist/tools/settle-in-flight.js +9 -2
  341. package/dist/tools/snapshot-delta.d.ts +24 -1
  342. package/dist/tools/snapshot-delta.js +66 -7
  343. package/dist/tools/tool-names.d.ts +1 -0
  344. package/dist/tools/tool-names.js +1 -0
  345. package/dist/tools/tool-surface.js +20 -2
  346. package/dist/tools/tools.js +120 -11
  347. package/dist/tools/verify-next-baton.d.ts +2 -1
  348. package/dist/update/sdk-sync.d.ts +1 -1
  349. package/dist/update/sdk-sync.js +1 -1
  350. package/dist/update/updater.js +1 -1
  351. package/dist/version/sdk-fix.d.ts +2 -1
  352. package/dist/version/version-skew.d.ts +0 -8
  353. package/dist/version/version-skew.js +1 -1
  354. package/docs/README.md +8 -6
  355. package/docs/actions.mdx +1 -1
  356. package/docs/agent-cheatsheet.md +4 -2
  357. package/docs/architecture.md +1 -1
  358. package/docs/cli/mcp.mdx +3 -1
  359. package/docs/cli/watch.mdx +1 -1
  360. package/docs/cli.mdx +1 -1
  361. package/docs/desktop.mdx +1 -1
  362. package/docs/docs.json +8 -3
  363. package/docs/faq.mdx +9 -0
  364. package/docs/first-drive.md +136 -0
  365. package/docs/frameworks.mdx +29 -7
  366. package/docs/gate-plan.md +2 -2
  367. package/docs/gates.md +19 -11
  368. package/docs/getting-started.md +7 -1
  369. package/docs/http-transport.md +164 -0
  370. package/docs/index.mdx +5 -3
  371. package/docs/install-manual.mdx +1 -1
  372. package/docs/packages/tauri.mdx +1 -1
  373. package/docs/packages.mdx +15 -3
  374. package/docs/platform-integration.md +1 -1
  375. package/docs/predicates.mdx +2 -0
  376. package/docs/system-map.md +2 -2
  377. package/docs/telemetry-contract.md +4 -4
  378. package/docs/telemetry-events.mdx +1 -1
  379. package/docs/telemetry.md +3 -3
  380. package/docs/tools-navigate.mdx +14 -6
  381. package/docs/usage.md +4 -4
  382. package/package.json +7 -4
  383. package/dist/init/agent-rules.d.ts +0 -116
  384. package/dist/init/agent-rules.js +0 -279
  385. package/dist/init/app-choice.d.ts +0 -20
  386. package/dist/init/app-choice.js +0 -25
  387. package/dist/init/astro-host.d.ts +0 -21
  388. package/dist/init/astro-host.js +0 -27
  389. package/dist/init/astro-patch.d.ts +0 -33
  390. package/dist/init/astro-patch.js +0 -300
  391. package/dist/init/capabilities.d.ts +0 -40
  392. package/dist/init/capabilities.js +0 -150
  393. package/dist/init/closing-hint.d.ts +0 -36
  394. package/dist/init/closing-hint.js +0 -120
  395. package/dist/init/connect-steps.d.ts +0 -2
  396. package/dist/init/connect-steps.js +0 -50
  397. package/dist/init/cra.d.ts +0 -79
  398. package/dist/init/cra.js +0 -178
  399. package/dist/init/csp-check.d.ts +0 -38
  400. package/dist/init/csp-check.js +0 -107
  401. package/dist/init/csp-doctor.d.ts +0 -32
  402. package/dist/init/csp-doctor.js +0 -54
  403. package/dist/init/desktop-doctor.d.ts +0 -41
  404. package/dist/init/desktop-doctor.js +0 -198
  405. package/dist/init/detect.d.ts +0 -96
  406. package/dist/init/detect.js +0 -209
  407. package/dist/init/dev-script.d.ts +0 -50
  408. package/dist/init/dev-script.js +0 -66
  409. package/dist/init/format-generated.d.ts +0 -18
  410. package/dist/init/format-generated.js +0 -39
  411. package/dist/init/install-hint.d.ts +0 -9
  412. package/dist/init/install-hint.js +0 -29
  413. package/dist/init/mcp-clients.d.ts +0 -89
  414. package/dist/init/mcp-clients.js +0 -299
  415. package/dist/init/mcp-registered.d.ts +0 -12
  416. package/dist/init/mcp-registered.js +0 -14
  417. package/dist/init/mcp.d.ts +0 -89
  418. package/dist/init/mcp.js +0 -129
  419. package/dist/init/next-patch.d.ts +0 -39
  420. package/dist/init/next-patch.js +0 -196
  421. package/dist/init/node-io.d.ts +0 -7
  422. package/dist/init/node-io.js +0 -117
  423. package/dist/init/non-js-project.d.ts +0 -27
  424. package/dist/init/non-js-project.js +0 -84
  425. package/dist/init/patch-kind.d.ts +0 -20
  426. package/dist/init/patch-kind.js +0 -10
  427. package/dist/init/plan-framework.d.ts +0 -64
  428. package/dist/init/plan-framework.js +0 -565
  429. package/dist/init/plan.d.ts +0 -242
  430. package/dist/init/plan.js +0 -703
  431. package/dist/init/preflight.d.ts +0 -28
  432. package/dist/init/preflight.js +0 -38
  433. package/dist/init/project-id.d.ts +0 -12
  434. package/dist/init/project-id.js +0 -25
  435. package/dist/init/refresh-rules.d.ts +0 -39
  436. package/dist/init/refresh-rules.js +0 -51
  437. package/dist/init/run.d.ts +0 -117
  438. package/dist/init/run.js +0 -806
  439. package/dist/init/slash-command.d.ts +0 -27
  440. package/dist/init/slash-command.js +0 -132
  441. package/dist/init/snippets.d.ts +0 -134
  442. package/dist/init/snippets.js +0 -572
  443. package/dist/init/vite-config.d.ts +0 -18
  444. package/dist/init/vite-config.js +0 -114
  445. package/dist/init/windows-quote.d.ts +0 -38
  446. package/dist/init/windows-quote.js +0 -70
  447. package/dist/init/workspace-apps.d.ts +0 -30
  448. package/dist/init/workspace-apps.js +0 -178
  449. package/dist/project/remember-project.d.ts +0 -24
  450. package/dist/project/remember-project.js +0 -40
  451. /package/dist/{init → setup}/confirm.d.ts +0 -0
@@ -25,6 +25,14 @@ export interface WaitFacts {
25
25
  readonly quietForMs: number;
26
26
  /** Milliseconds since the wait began. */
27
27
  readonly elapsedMs: number;
28
+ /**
29
+ * How long silence may mean "still starting" on THIS machine. Defaults to QUIET_MEANS_HUNG_MS.
30
+ *
31
+ * Passed in rather than read from the platform here, so this stays a pure decision and exactly one
32
+ * caller owns the platform check. 45s is generous on a laptop and tight on a cold Windows runner,
33
+ * where a first `npm run dev` optimises dependencies before Vite prints a line.
34
+ */
35
+ readonly quietMeansHungMs?: number;
28
36
  }
29
37
  export declare const WaitVerdict: {
30
38
  /** It is up. Carry on. */
@@ -41,7 +41,9 @@ export function judgeWait(facts) {
41
41
  if (facts.elapsedMs >= WAIT_CEILING_MS)
42
42
  return WaitVerdict.HUNG;
43
43
  // Output IS progress. Silence is what distinguishes a build from a wedge.
44
- return facts.quietForMs >= QUIET_MEANS_HUNG_MS ? WaitVerdict.HUNG : WaitVerdict.WAITING;
44
+ return facts.quietForMs >= (facts.quietMeansHungMs ?? QUIET_MEANS_HUNG_MS)
45
+ ? WaitVerdict.HUNG
46
+ : WaitVerdict.WAITING;
45
47
  }
46
48
  /** A url the dev server announced, if it has announced one. Never composed, only read. */
47
49
  const URL_IN_OUTPUT = /https?:\/\/(?:localhost|127\.0\.0\.1|\[::1\]):\d+/;
@@ -10,8 +10,6 @@
10
10
  * Two details here are not stylistic, and both cost a real run to learn.
11
11
  */
12
12
  import { type DriverSpec } from './drive-plan.js';
13
- /** Ten minutes. Long, because the drive is a model working, and bounded, because it can wedge. */
14
- export declare const DRIVE_TIMEOUT_MS: number;
15
13
  export interface DriveRequest {
16
14
  readonly url: string;
17
15
  readonly sessionId: string;
@@ -24,7 +22,7 @@ export interface DriveRequest {
24
22
  readonly budgetUsd: number;
25
23
  readonly model?: string | undefined;
26
24
  }
27
- export interface DriveReport {
25
+ interface DriveReport {
28
26
  /** The agent's own account, kept verbatim and never treated as a pass on its own. */
29
27
  readonly text: string;
30
28
  readonly grade?: string | undefined;
@@ -69,3 +67,4 @@ export declare function readDriveOutput(out: string): DriveReport;
69
67
  export declare function driveWith(driver: DriverSpec, req: DriveRequest, cwd: string): DriveReport;
70
68
  /** Everything that is not Claude Code reports prose, so the report IS its output. */
71
69
  export declare function readPlainOutput(out: string): DriveReport;
70
+ export {};
@@ -12,7 +12,7 @@
12
12
  import { spawnSync } from 'node:child_process';
13
13
  import { ASSERTED, readAssertionsGrade } from './drive-plan.js';
14
14
  /** Ten minutes. Long, because the drive is a model working, and bounded, because it can wedge. */
15
- export const DRIVE_TIMEOUT_MS = 10 * 60_000;
15
+ const DRIVE_TIMEOUT_MS = 10 * 60_000;
16
16
  /** Only the Reticle surface, unless the capabilities file has to be finished first. */
17
17
  const RETICLE_TOOLS = 'mcp__reticle';
18
18
  const CAPABILITY_TOOLS = 'mcp__reticle,Read,Edit,Write';
@@ -6,7 +6,7 @@
6
6
  * they can be tested without spending anything.
7
7
  */
8
8
  /** What a driver needs to build its own invocation. */
9
- export interface DriveInvocation {
9
+ interface DriveInvocation {
10
10
  /** The tools the drive may use, comma-separated, in Claude Code's spelling. */
11
11
  readonly tools: string;
12
12
  readonly budgetUsd: number;
@@ -49,7 +49,7 @@ export declare function chooseDriver(drivers: readonly DriverSpec[], probe: (bin
49
49
  export declare function readAssertionsGrade(text: string | undefined): string | undefined;
50
50
  /** The only grade that makes a saved flow worth replaying. */
51
51
  export declare const ASSERTED = "asserted";
52
- export interface EscalationInput {
52
+ interface EscalationInput {
53
53
  readonly escalationEnabled: boolean;
54
54
  /** Set only when a faster model was chosen, since escalation means retrying without it. */
55
55
  readonly fasterModel: string | undefined;
@@ -66,3 +66,4 @@ export interface EscalationInput {
66
66
  * choose is worse than spending a second drive on it.
67
67
  */
68
68
  export declare function shouldEscalate(input: EscalationInput): boolean;
69
+ export {};
@@ -11,7 +11,7 @@
11
11
  * Idempotent by construction: an alive daemon for this project is adopted, and one belonging to
12
12
  * somebody else is refused rather than stolen, which is the same rule `reticle mcp` follows.
13
13
  */
14
- export interface EnsureDaemonDeps {
14
+ interface EnsureDaemonDeps {
15
15
  readonly usable: (port: number) => Promise<boolean>;
16
16
  readonly spawn: (port: number) => boolean;
17
17
  readonly waitReady: (port: number) => Promise<unknown>;
@@ -27,3 +27,4 @@ export declare const EnsureDaemon: {
27
27
  export type EnsureDaemon = (typeof EnsureDaemon)[keyof typeof EnsureDaemon];
28
28
  export declare function ensureDaemon(port: number, deps: EnsureDaemonDeps): Promise<EnsureDaemon>;
29
29
  export declare function nodeEnsureDaemonDeps(): EnsureDaemonDeps;
30
+ export {};
@@ -0,0 +1,12 @@
1
+ import { type DevServerEntry } from '@reticlehq/core';
2
+ /**
3
+ * The URL of a live dev server that belongs to THIS project, if one has announced itself.
4
+ *
5
+ * Setup used to ignore the registry and spawn `dev` anyway. Vite then bound the next port (5174)
6
+ * beside the one already serving (5173), and `reticle_sessions` listed three tabs with no way to
7
+ * pick. The registry is scoped on purpose: an unscoped read would attach to a sibling app.
8
+ */
9
+ export declare function urlOfExistingApp(entries: readonly DevServerEntry[], scope: {
10
+ projectId?: string | undefined;
11
+ root?: string | undefined;
12
+ }): string | undefined;
@@ -0,0 +1,13 @@
1
+ import { devServersForProject } from '@reticlehq/core';
2
+ /**
3
+ * The URL of a live dev server that belongs to THIS project, if one has announced itself.
4
+ *
5
+ * Setup used to ignore the registry and spawn `dev` anyway. Vite then bound the next port (5174)
6
+ * beside the one already serving (5173), and `reticle_sessions` listed three tabs with no way to
7
+ * pick. The registry is scoped on purpose: an unscoped read would attach to a sibling app.
8
+ */
9
+ export function urlOfExistingApp(entries, scope) {
10
+ const mine = devServersForProject(entries, scope);
11
+ const first = mine[0];
12
+ return first === undefined ? undefined : first.url;
13
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The daemon half of `reticle init`.
3
+ *
4
+ * `@reticlehq/init` writes files and runs a package manager and knows nothing else — no tracer, no
5
+ * telemetry client, no bridge state directory. Those four capabilities are declared by `InitHost`
6
+ * and supplied here, which is the whole seam between the scaffolder and the daemon. Built in one
7
+ * place rather than at each call site so a caller cannot half-wire it: a missing reporter is a
8
+ * metric that is silently, permanently absent, which is the failure mode telemetry always has.
9
+ */
10
+ import type { InitHost } from '@reticlehq/init';
11
+ export declare function serverInitHost(): InitHost;
@@ -0,0 +1,26 @@
1
+ import { spanSync } from '../trace.js';
2
+ import { reportInitOutcome } from '../telemetry/init-telemetry.js';
3
+ import { defaultPairingTokenDir, readOrCreatePairingTokenSync } from '../bridge/pairing-token.js';
4
+ import { declaredInstallSource } from '../telemetry/install-source.js';
5
+ export function serverInitHost() {
6
+ return {
7
+ span(name, fields, fn) {
8
+ return spanSync(name, fields, fn);
9
+ },
10
+ reportOutcome(outcome) {
11
+ reportInitOutcome(outcome);
12
+ },
13
+ /**
14
+ * Minted here if nothing has written it yet. `init` used to READ the file and return empty when
15
+ * the daemon had never started; the CDN snippet inlined that empty value permanently, and
16
+ * regenerating the token made the pasted literal stale. Same mint as the daemon
17
+ * (`readOrCreatePairingToken`), and it honours `RETICLE_PAIRING_TOKEN_DIR`.
18
+ */
19
+ pairingToken() {
20
+ return readOrCreatePairingTokenSync(defaultPairingTokenDir()) ?? '';
21
+ },
22
+ installSource() {
23
+ return declaredInstallSource();
24
+ },
25
+ };
26
+ }
@@ -5,9 +5,9 @@
5
5
  * cli.ts is a dispatcher: a command that grew a second half should not make the file that routes
6
6
  * every command harder to read.
7
7
  */
8
- import type { InitResult } from '../init/run.js';
8
+ import type { InitResult } from '@reticlehq/init';
9
9
  /** Just enough of the parsed command to decide and run. */
10
- export interface InitRuntimeArgs {
10
+ interface InitRuntimeArgs {
11
11
  readonly port: number | undefined;
12
12
  readonly dryRun: boolean;
13
13
  readonly filesOnly?: boolean | undefined;
@@ -34,14 +34,8 @@ export interface InitRuntimeArgs {
34
34
  readonly driveModel?: string | undefined;
35
35
  readonly licenseKey?: string | undefined;
36
36
  }
37
- export interface RuntimePrintIo {
37
+ interface RuntimePrintIo {
38
38
  readonly print: (line: string) => void;
39
39
  }
40
- /**
41
- * Carry on from a finished `init`, or stop where it used to.
42
- *
43
- * `--files-only` is what init did before it learned to boot the app, and a dry run is a preview:
44
- * both keep the old ending. Everyone else gets the rest, because writing files was never the same
45
- * thing as an install working.
46
- */
47
40
  export declare function continueAfterInit(parsed: InitRuntimeArgs, result: InitResult, io: RuntimePrintIo, cwd: string): Promise<void>;
41
+ export {};
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
9
9
  import { RETICLE_DEFAULT_PORT } from '@reticlehq/core';
10
- import { confirmInstall, nodeConfirmDeps } from '../init/confirm.js';
10
+ import { confirmInstall, nodeConfirmDeps } from './confirm.js';
11
11
  import { writeLicenseKey } from './license-key.js';
12
12
  import { registerOtherAgents, runSetupCommand } from './setup-command.js';
13
13
  import { bridgeOccupied } from './bridge-port.js';
@@ -35,6 +35,19 @@ const licenseIo = {
35
35
  * both keep the old ending. Everyone else gets the rest, because writing files was never the same
36
36
  * thing as an install working.
37
37
  */
38
+ function printRelaunch(parsed, io, cwd) {
39
+ if (true !== parsed.relaunch)
40
+ return;
41
+ io.print(relaunchDecision({
42
+ ...(undefined === process.env['CLAUDE_CODE_SESSION_ID']
43
+ ? {}
44
+ : { claudeSessionId: process.env['CLAUDE_CODE_SESSION_ID'] }),
45
+ ...(undefined === codexSessionFor(cwd) ? {} : { codexSessionId: codexSessionFor(cwd) }),
46
+ transcriptExists: claudeTranscriptExists,
47
+ cwd,
48
+ }).message);
49
+ io.print('');
50
+ }
38
51
  export async function continueAfterInit(parsed, result, io, cwd) {
39
52
  const port = parsed.port ?? RETICLE_DEFAULT_PORT;
40
53
  // Before anything else: the key belongs in .env whichever way this run ends, and the CLI folds a
@@ -43,6 +56,15 @@ export async function continueAfterInit(parsed, result, io, cwd) {
43
56
  const written = writeLicenseKey(cwd, parsed.licenseKey, licenseIo);
44
57
  io.print(written.message);
45
58
  }
59
+ // Decided and printed before the `--files-only` return, not after it. The restart question is
60
+ // asked by whoever just installed, and `--files-only` is the mode an agent uses when the app is
61
+ // ALREADY running — so the one route that most needs the answer was the one route that could not
62
+ // reach it, and `--relaunch --files-only` accepted the flag and silently did nothing with it.
63
+ //
64
+ // Never performed: opening a terminal is not something a one-shot command should do behind a
65
+ // flag, and the half worth having is the refusal — `--resume` on an id with no transcript opens
66
+ // an EMPTY conversation that looks exactly like it worked. See relaunch.ts.
67
+ printRelaunch(parsed, io, cwd);
46
68
  if (true === parsed.filesOnly || parsed.dryRun) {
47
69
  // Registration and pre-approval still run here, and this is the ONLY route an existing user
48
70
  // has: nothing reaches back into a machine that installed Reticle a version ago, so the
@@ -72,21 +94,6 @@ export async function continueAfterInit(parsed, result, io, cwd) {
72
94
  // The run still ends non-zero: the phase returns `ok: false` when no session appears, and a
73
95
  // session appearing means the manual step WAS done and the app really did connect — which is a
74
96
  // green worth reporting, not one to suppress.
75
- // What a restart should do, decided and printed. Never performed: opening a terminal is not
76
- // something a one-shot command should do behind a flag, and the half worth having is the refusal —
77
- // `--resume` on an id with no transcript opens an EMPTY conversation that looks exactly like it
78
- // worked. See relaunch.ts.
79
- if (true === parsed.relaunch) {
80
- io.print(relaunchDecision({
81
- ...(undefined === process.env['CLAUDE_CODE_SESSION_ID']
82
- ? {}
83
- : { claudeSessionId: process.env['CLAUDE_CODE_SESSION_ID'] }),
84
- ...(undefined === codexSessionFor(cwd) ? {} : { codexSessionId: codexSessionFor(cwd) }),
85
- transcriptExists: claudeTranscriptExists,
86
- cwd,
87
- }).message);
88
- io.print('');
89
- }
90
97
  // Before the connect wait, never after: a bridge held by a stranger makes a session impossible,
91
98
  // so going ahead spends the entire budget and then reports what reads as an instrumentation
92
99
  // problem — the one place that is fine. See bridge-port.ts.
@@ -20,7 +20,7 @@ export declare const LicenseWrite: {
20
20
  readonly REPLACED: "replaced";
21
21
  };
22
22
  export type LicenseWrite = (typeof LicenseWrite)[keyof typeof LicenseWrite];
23
- export interface LicenseResult {
23
+ interface LicenseResult {
24
24
  readonly action: LicenseWrite;
25
25
  /** True when `.gitignore` had to be changed so the key cannot be committed. */
26
26
  readonly gitignoreUpdated: boolean;
@@ -37,3 +37,4 @@ export declare function gitignoreCoversEnv(contents: string): boolean;
37
37
  * which that is.
38
38
  */
39
39
  export declare function writeLicenseKey(dir: string, key: string, io: LicenseIo): LicenseResult;
40
+ export {};
@@ -8,7 +8,7 @@
8
8
  * platform's most common React setup.
9
9
  */
10
10
  /** One LISTENING socket and the process that owns it. */
11
- export interface Listener {
11
+ interface Listener {
12
12
  readonly port: number;
13
13
  readonly pid: number;
14
14
  }
@@ -35,3 +35,4 @@ export declare function parseWmicProcesses(out: string): ProcessPair[];
35
35
  * indistinguishable from "no server".
36
36
  */
37
37
  export declare function descendants(pairs: readonly ProcessPair[], root: number): number[];
38
+ export {};
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Alternate loopback URLs to try when a readiness probe misses on the announced host.
3
+ *
4
+ * Vite (and friends) sometimes print `http://127.0.0.1:PORT` even when the process only accepted
5
+ * on `[::1]`. Node `fetch` of that announcement then fails forever while `http://localhost:PORT`
6
+ * and `http://[::1]:PORT` answer — which is how `init` sat in the wait loop until something killed
7
+ * it (#884). Asking by name hands the family to the OS; asking both literal loopbacks does not.
8
+ *
9
+ * Same "either family is enough" rule as `PROBE_HOSTS` in the no-session diagnostic — this is the
10
+ * setup wait's copy of that lesson, applied to a full URL rather than a bare port.
11
+ */
12
+ /**
13
+ * URLs that mean the same loopback listener, for every family this machine might bind.
14
+ *
15
+ * Non-loopback URLs are returned unchanged (one candidate): a LAN or tunnel origin is not a
16
+ * family-split problem, and inventing alternates would probe the wrong machine.
17
+ */
18
+ export declare function loopbackProbeUrls(url: string): string[];
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Alternate loopback URLs to try when a readiness probe misses on the announced host.
3
+ *
4
+ * Vite (and friends) sometimes print `http://127.0.0.1:PORT` even when the process only accepted
5
+ * on `[::1]`. Node `fetch` of that announcement then fails forever while `http://localhost:PORT`
6
+ * and `http://[::1]:PORT` answer — which is how `init` sat in the wait loop until something killed
7
+ * it (#884). Asking by name hands the family to the OS; asking both literal loopbacks does not.
8
+ *
9
+ * Same "either family is enough" rule as `PROBE_HOSTS` in the no-session diagnostic — this is the
10
+ * setup wait's copy of that lesson, applied to a full URL rather than a bare port.
11
+ */
12
+ import { isLoopbackHostname } from '@reticlehq/core';
13
+ /** Hosts to try, in order: keep the caller's first, then fill the gaps. */
14
+ const LOOPBACK_HOSTS = ['127.0.0.1', 'localhost', '::1'];
15
+ /**
16
+ * URLs that mean the same loopback listener, for every family this machine might bind.
17
+ *
18
+ * Non-loopback URLs are returned unchanged (one candidate): a LAN or tunnel origin is not a
19
+ * family-split problem, and inventing alternates would probe the wrong machine.
20
+ */
21
+ export function loopbackProbeUrls(url) {
22
+ let parsed;
23
+ try {
24
+ parsed = new URL(url);
25
+ }
26
+ catch {
27
+ return [url];
28
+ }
29
+ if (!isLoopbackHostname(parsed.hostname))
30
+ return [url];
31
+ const out = [];
32
+ const seen = new Set();
33
+ const push = (host) => {
34
+ const next = new URL(parsed.href);
35
+ // `URL.hostname = '::1'` is a silent no-op in Node — the IPv6 form has to go through `host`
36
+ // with brackets, or the candidate list collapses to IPv4-only and the whole fallback is dead.
37
+ const port = parsed.port;
38
+ next.host = host.includes(':')
39
+ ? `[${host}]${port.length > 0 ? `:${port}` : ''}`
40
+ : `${host}${port.length > 0 ? `:${port}` : ''}`;
41
+ const href = next.href;
42
+ if (seen.has(href))
43
+ return;
44
+ seen.add(href);
45
+ out.push(href);
46
+ };
47
+ // Caller's host first so a working announcement is not reordered for no reason.
48
+ push(parsed.hostname);
49
+ for (const host of LOOPBACK_HOSTS)
50
+ push(host);
51
+ return out;
52
+ }
@@ -48,6 +48,9 @@ export declare class OwnedDevServer {
48
48
  * A refused certificate is reported separately because the server ANSWERED: a self-signed dev cert
49
49
  * is an ordinary local setup, and calling it "nothing is listening" sends somebody to start a
50
50
  * server that is already running.
51
+ *
52
+ * On loopback, the announced host is tried first and the other loopback families follow when it
53
+ * misses — so an IPv6-only Vite that printed `127.0.0.1` still counts as served (#884).
51
54
  */
52
55
  export declare function probePage(url: string): Promise<PageProbe>;
53
56
  /** Sessions the daemon is holding, in the shape the picker reads. */
@@ -17,6 +17,7 @@ import { existsSync, readdirSync } from 'node:fs';
17
17
  import { join } from 'node:path';
18
18
  import { fetchStatus } from '../cli/cli-launch.js';
19
19
  import { descendants, parseLsofPorts, parseNetstatListeners, parseWmicProcesses, } from './listeners.js';
20
+ import { loopbackProbeUrls } from './loopback-probe-urls.js';
20
21
  const WINDOWS = 'win32' === process.platform;
21
22
  /** A page fetch that is slow is a page fetch that failed, for our purposes. */
22
23
  const PROBE_TIMEOUT_MS = 5_000;
@@ -161,20 +162,34 @@ function windowsProcessPairs() {
161
162
  * A refused certificate is reported separately because the server ANSWERED: a self-signed dev cert
162
163
  * is an ordinary local setup, and calling it "nothing is listening" sends somebody to start a
163
164
  * server that is already running.
165
+ *
166
+ * On loopback, the announced host is tried first and the other loopback families follow when it
167
+ * misses — so an IPv6-only Vite that printed `127.0.0.1` still counts as served (#884).
164
168
  */
165
169
  export async function probePage(url) {
166
- try {
167
- const res = await fetch(url, { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
168
- const body = await res.text();
169
- return { served: true, sdkInPage: /@reticlehq|@reticle-connect|reticle-dev/.test(body) };
170
- }
171
- catch (err) {
172
- const message = String(err?.cause?.message ??
173
- err?.message ??
174
- '');
175
- const tlsRefused = /certificate|SELF_SIGNED|DEPTH_ZERO|ERR_TLS|unable to verify/i.test(message);
176
- return { served: false, sdkInPage: false, tlsRefused };
170
+ const candidates = loopbackProbeUrls(url);
171
+ let sawTlsRefused = false;
172
+ for (const candidate of candidates) {
173
+ try {
174
+ const res = await fetch(candidate, { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
175
+ const body = await res.text();
176
+ const sdkInPage = /@reticlehq|@reticle-connect|reticle-dev/.test(body);
177
+ // Only stamp reachedUrl when we had to leave the announcement — callers that already have
178
+ // the working URL should not rewrite it for a no-op.
179
+ return candidate === url
180
+ ? { served: true, sdkInPage }
181
+ : { served: true, sdkInPage, reachedUrl: candidate };
182
+ }
183
+ catch (err) {
184
+ const message = String(err?.cause?.message ??
185
+ err?.message ??
186
+ '');
187
+ if (/certificate|SELF_SIGNED|DEPTH_ZERO|ERR_TLS|unable to verify/i.test(message)) {
188
+ sawTlsRefused = true;
189
+ }
190
+ }
177
191
  }
192
+ return { served: false, sdkInPage: false, ...(sawTlsRefused ? { tlsRefused: true } : {}) };
178
193
  }
179
194
  /** Sessions the daemon is holding, in the shape the picker reads. */
180
195
  export async function listSessions(port) {
@@ -22,6 +22,11 @@ export interface PageProbe {
22
22
  * already running.
23
23
  */
24
24
  readonly tlsRefused?: boolean | undefined;
25
+ /**
26
+ * The URL that actually answered, when the announced host missed and a loopback sibling did not.
27
+ * Callers that open a browser or wait on a session should prefer this over the announcement (#884).
28
+ */
29
+ readonly reachedUrl?: string | undefined;
25
30
  }
26
31
  export declare const PageFinding: {
27
32
  readonly NOT_SERVED: "not-served";
@@ -29,8 +29,9 @@ export interface RelaunchEnv {
29
29
  transcriptExists(sessionId: string): boolean;
30
30
  readonly cwd: string;
31
31
  }
32
- export interface RelaunchDecision {
32
+ interface RelaunchDecision {
33
33
  readonly outcome: RelaunchOutcome;
34
34
  readonly message: string;
35
35
  }
36
36
  export declare function relaunchDecision(env: RelaunchEnv): RelaunchDecision;
37
+ export {};
@@ -14,7 +14,6 @@
14
14
  import { type CandidateSession } from './session-pick.js';
15
15
  import { type PageProbe } from './page-probe.js';
16
16
  import { AppShape } from './desktop-shape.js';
17
- /** Where a run got to, and why it stopped if it did. */
18
17
  export declare const SetupPhase: {
19
18
  readonly DEV_SERVER: "dev-server";
20
19
  readonly CONNECT: "connect";
@@ -39,6 +38,11 @@ export interface SetupOutcome {
39
38
  export interface SetupEffects {
40
39
  /** Start the dev server. Resolves once started; the caller owns stopping it. */
41
40
  readonly startDevServer: (command: string, cwd: string) => Promise<void>;
41
+ /**
42
+ * A live server this project already announced, if any. Setup attaches to it rather than
43
+ * starting a second one on the next port.
44
+ */
45
+ readonly existingAppUrl?: () => Promise<string | undefined>;
42
46
  /** Everything the dev server has printed so far. */
43
47
  readonly devServerOutput: () => string;
44
48
  readonly devServerExited: () => boolean;