@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
@@ -11,12 +11,33 @@
11
11
  * way of going wrong, and the alternative to injecting them is a test that boots a real dev server
12
12
  * and a real browser to find out what happens when neither works.
13
13
  */
14
- import { judgeWait, urlToWatch, WaitVerdict } from './dev-server-wait.js';
14
+ import { judgeWait, QUIET_MEANS_HUNG_MS, urlToWatch, WaitVerdict } from './dev-server-wait.js';
15
+ import { waitProgressLine } from './wait-progress.js';
16
+ /**
17
+ * Windows gets longer to say something before silence counts as a wedge.
18
+ *
19
+ * A first `npm run dev` on a cold Windows runner optimises dependencies before the bundler prints a
20
+ * line, and 45s of quiet is inside that window. Measured on the install gate: the Vue scaffold was
21
+ * declared hung, `init` exited 1, and the gate then started the very same app and connected to it
22
+ * on the next line. Nothing was wrong with the app; the wait was too impatient for the platform.
23
+ *
24
+ * Only the QUIET budget moves. The ceiling is unchanged, and a launcher that exits is still dead
25
+ * immediately, so this buys patience for a starting server and never for a broken one.
26
+ */
27
+ const WINDOWS_QUIET_MEANS_HUNG_MS = 3 * 60_000;
28
+ const WINDOWS_QUIET_MEANS_HUNG_MS_APPLIES = 'win32' === process.platform;
15
29
  import { pickSession } from './session-pick.js';
16
- import { readPage, describePage } from './page-probe.js';
30
+ import { readPage, describePage, PageFinding } from './page-probe.js';
17
31
  import { remainingSteps } from './remaining-steps.js';
18
32
  import { AppShape, isDesktop, policyFor } from './desktop-shape.js';
19
33
  /** Where a run got to, and why it stopped if it did. */
34
+ /**
35
+ * How long to keep asking whether the SDK has reached the page before giving up on opening a window.
36
+ * Bounded by the connect budget, so a short budget is never overrun by the readiness check.
37
+ */
38
+ const SDK_READY_WINDOW_MS = 15_000;
39
+ /** The wait left when no browser was opened: only a tab that is ALREADY loaded can still appear. */
40
+ const NO_BROWSER_GRACE_MS = 3_000;
20
41
  export const SetupPhase = {
21
42
  DEV_SERVER: 'dev-server',
22
43
  CONNECT: 'connect',
@@ -55,51 +76,81 @@ export async function runSetupPhases(input, fx) {
55
76
  };
56
77
  // ── the app has to be running ────────────────────────────────────────────────────────────────
57
78
  let url = input.suppliedUrl;
79
+ let attachedToExisting = false;
58
80
  if (undefined === url) {
59
- if (undefined === input.devCommand) {
81
+ const announced = undefined === fx.existingAppUrl ? undefined : await fx.existingAppUrl();
82
+ if (undefined !== announced && 0 < announced.length) {
83
+ // The plugin already announced a live server for THIS project. Starting `dev` beside it is
84
+ // how Vite binds 5174, a second tab opens, and `reticle_sessions` lists three with no way
85
+ // to pick. The registry is scoped; an unscoped listen would attach to a sibling app.
86
+ url = announced;
87
+ attachedToExisting = true;
88
+ note(`This project is already running at ${announced} — attaching instead of starting a second server.`);
89
+ }
90
+ else if (undefined === input.devCommand) {
60
91
  note(
61
92
  // "stop here rather than invent one" is the SKILL.md rule, and the words are the contract —
62
93
  // inventing a dev command is how a setup script runs the wrong thing and reports success.
63
94
  'No dev command: the project names no dev, start or serve script, and there is no --url. ' +
64
- 'Stopping here rather than invent one — pass --dev-cmd or --url to say what serves this app.');
95
+ 'Stopping here rather than invent one — start the app yourself and pass --url to say ' +
96
+ 'where it is serving, or add a dev/start/serve script to package.json and re-run.');
65
97
  return stop(input, SetupPhase.DEV_SERVER, {}, notes);
66
98
  }
67
- await fx.startDevServer(input.devCommand, input.appDir);
68
- const startedAt = fx.now();
69
- for (;;) {
70
- const watching = urlToWatch(fx.devServerOutput(), fx.observedPorts());
71
- const serving = undefined === watching ? false : (await fx.probePage(watching)).served;
72
- const verdict = judgeWait({
73
- output: fx.devServerOutput(),
74
- launcherExited: fx.devServerExited(),
75
- serving,
76
- quietForMs: fx.devServerQuietForMs(),
77
- elapsedMs: fx.now() - startedAt,
78
- });
79
- if (WaitVerdict.READY === verdict && undefined !== watching) {
80
- url = watching;
81
- break;
82
- }
83
- // A desktop shell serves its webview from inside the app, so there is no port to answer and
84
- // nothing to be READY. Once it has announced a url, or bound one we can see, that is as far
85
- // as this phase can get: the session it dials from its own window is the real signal.
86
- if (isDesktop(input.shape) && undefined !== watching) {
87
- url = watching;
88
- break;
89
- }
90
- if (WaitVerdict.DEAD === verdict) {
91
- note('The dev server exited without serving anything.');
92
- return stop(input, SetupPhase.DEV_SERVER, {}, notes);
93
- }
94
- if (WaitVerdict.HUNG === verdict) {
95
- // Says BOTH were checked. A server that prints nothing but IS listening is the CRA case and
96
- // must not be failed, so a reader has to be able to tell "we looked at the log" from "we
97
- // looked at the log AND the ports".
98
- note('The dev server neither printed a URL nor bound a port, so setup has nothing to open. ' +
99
- 'Check its log, or pass --url with the address it serves.');
100
- return stop(input, SetupPhase.DEV_SERVER, {}, notes);
99
+ else {
100
+ await fx.startDevServer(input.devCommand, input.appDir);
101
+ const startedAt = fx.now();
102
+ // This loop used to poll in complete silence. Reported as thirty minutes of nothing ending in a
103
+ // SIGKILL — and whatever made that wait long, a user who cannot tell "still starting" from
104
+ // "wedged" has been given no way to act. See wait-progress.ts.
105
+ let spokeAtMs;
106
+ for (;;) {
107
+ const watching = urlToWatch(fx.devServerOutput(), fx.observedPorts());
108
+ const waitedMs = fx.now() - startedAt;
109
+ const progress = waitProgressLine(waitedMs, watching, spokeAtMs);
110
+ if (progress !== undefined) {
111
+ note(progress);
112
+ spokeAtMs = waitedMs;
113
+ }
114
+ const probe = undefined === watching
115
+ ? { served: false, sdkInPage: false }
116
+ : await fx.probePage(watching);
117
+ const serving = probe.served;
118
+ const verdict = judgeWait({
119
+ output: fx.devServerOutput(),
120
+ launcherExited: fx.devServerExited(),
121
+ serving,
122
+ quietForMs: fx.devServerQuietForMs(),
123
+ elapsedMs: fx.now() - startedAt,
124
+ quietMeansHungMs: WINDOWS_QUIET_MEANS_HUNG_MS_APPLIES
125
+ ? WINDOWS_QUIET_MEANS_HUNG_MS
126
+ : QUIET_MEANS_HUNG_MS,
127
+ });
128
+ if (WaitVerdict.READY === verdict && undefined !== watching) {
129
+ // Prefer the URL that answered when the announcement was the wrong family (#884).
130
+ url = probe.reachedUrl ?? watching;
131
+ break;
132
+ }
133
+ // A desktop shell serves its webview from inside the app, so there is no port to answer and
134
+ // nothing to be READY. Once it has announced a url, or bound one we can see, that is as far
135
+ // as this phase can get: the session it dials from its own window is the real signal.
136
+ if (isDesktop(input.shape) && undefined !== watching) {
137
+ url = watching;
138
+ break;
139
+ }
140
+ if (WaitVerdict.DEAD === verdict) {
141
+ note('The dev server exited without serving anything.');
142
+ return stop(input, SetupPhase.DEV_SERVER, {}, notes);
143
+ }
144
+ if (WaitVerdict.HUNG === verdict) {
145
+ // Says BOTH were checked. A server that prints nothing but IS listening is the CRA case and
146
+ // must not be failed, so a reader has to be able to tell "we looked at the log" from "we
147
+ // looked at the log AND the ports".
148
+ note('The dev server neither printed a URL nor bound a port, so setup has nothing to open. ' +
149
+ 'Check its log, or pass --url with the address it serves.');
150
+ return stop(input, SetupPhase.DEV_SERVER, {}, notes);
151
+ }
152
+ await fx.sleep(input.pollMs);
101
153
  }
102
- await fx.sleep(input.pollMs);
103
154
  }
104
155
  }
105
156
  // ── and something has to connect from inside it ──────────────────────────────────────────────
@@ -107,17 +158,73 @@ export async function runSetupPhases(input, fx) {
107
158
  // Through `note`, not `fx.note`: a caller reading the result should see it too.
108
159
  if (undefined !== policy.note)
109
160
  note(policy.note);
110
- const before = new Set((await fx.listSessions()).map((s) => s.sessionId));
111
- // Never for a desktop app: its own window is the client, and a browser tab would be a SECOND
112
- // session that is not the app.
113
- if (input.openBrowser && policy.openBrowser)
114
- await fx.openBrowser(url);
115
- const deadline = fx.now() + (input.connectBudgetMs ?? Math.max(input.phaseTimeoutMs, policy.connectBudgetMs));
116
- let session = null;
117
- for (;;) {
161
+ const listed = await fx.listSessions();
162
+ const requiredRuntime = isDesktop(input.shape) ? input.shape : undefined;
163
+ // A tab already on this URL is the answer. Opening another is how three sessions appear.
164
+ // `before` is empty so pickSession will take that tab rather than waiting for a new one.
165
+ const alreadyConnected = attachedToExisting
166
+ ? pickSession(listed, url, new Set(), requiredRuntime)
167
+ : null;
168
+ const before = new Set(listed.map((s) => s.sessionId));
169
+ // Do not put a window in front of somebody until the page behind it can actually do something.
170
+ //
171
+ // The probe that says whether the SDK is even IN the page used to run only in the failure branch
172
+ // below, AFTER the browser was already open. So a mis-wired app opened a real window onto a page
173
+ // that was never going to connect, and the person watching it saw a browser appear and then
174
+ // nothing happen for the whole connect budget — which reads as "Reticle is broken" rather than
175
+ // "the bundle predates the config edit". One fetch, before the window, turns that into a sentence.
176
+ //
177
+ // Only the browser is gated. The wait below still runs: something else may connect (an already
178
+ // open tab, a desktop window), and the probe is a statement about one fetch of the document, not
179
+ // proof that nothing can ever dial in.
180
+ const budgetMs = input.connectBudgetMs ?? Math.max(input.phaseTimeoutMs, policy.connectBudgetMs);
181
+ let openedBrowser = false;
182
+ if (null === alreadyConnected && input.openBrowser && policy.openBrowser) {
183
+ // SERVED is the precondition, not SDK_PRESENT: a url that answers nothing is the only state
184
+ // where a window is certainly useless. Whether the SDK is in the served HTML is a DIFFERENT
185
+ // question — Vite injects a marker, while Nuxt, React Router, Astro, SvelteKit and CRA deliver
186
+ // the connect in the JS BUNDLE, so their HTML never carries it. Gating on presence failed five
187
+ // of ten scaffolds in the install gate: no window, so no bundle, so no session, so exit 1 on a
188
+ // correct install. page-probe.ts says it is a diagnostic for a connect that already failed; the
189
+ // same signal as a precondition deadlocks every case it is wrong about.
190
+ //
191
+ // So presence decides only WHEN: open the moment it appears (the fast path for the frameworks
192
+ // that inline it), otherwise once the short readiness window is out.
193
+ const readyBy = fx.now() + Math.min(SDK_READY_WINDOW_MS, budgetMs);
194
+ let finding = readPage(await fx.probePage(url));
195
+ while (PageFinding.SDK_MISSING === finding && fx.now() < readyBy) {
196
+ await fx.sleep(input.pollMs);
197
+ finding = readPage(await fx.probePage(url));
198
+ }
199
+ if (PageFinding.NOT_SERVED === finding || PageFinding.TLS_REFUSED === finding) {
200
+ note(describePage(finding, url));
201
+ note('Not opening a browser: nothing answered that url, so the window could only show an error ' +
202
+ 'page. Fix the line above and re-run — `init` is idempotent.');
203
+ }
204
+ else {
205
+ // Said BEFORE the window appears, so somebody watching a page that stays inert has already
206
+ // been told which of the two it is.
207
+ if (PageFinding.SDK_MISSING === finding)
208
+ note(describePage(finding, url));
209
+ await fx.openBrowser(url);
210
+ openedBrowser = true;
211
+ }
212
+ }
213
+ // Waiting the full budget for a session when nothing was opened to create one is dead time, and
214
+ // it used to be over two minutes of it: the browser is the session source on web, so declining to
215
+ // open it and then waiting as if we had is a promise to the reader that cannot be kept. Something
216
+ // else may still dial in — a tab the user already has open, a desktop window — and the existing
217
+ // diagnosis says such a session "will appear within a second of the page loading", so a short
218
+ // grace is the honest wait. A run that DID open a browser keeps the whole budget.
219
+ const deadline = fx.now() +
220
+ (openedBrowser || !(input.openBrowser && policy.openBrowser)
221
+ ? budgetMs
222
+ : Math.min(NO_BROWSER_GRACE_MS, budgetMs));
223
+ let session = alreadyConnected;
224
+ while (null === session) {
118
225
  // On a desktop app, only the desktop window counts. AppShape and the runtime a page reports use
119
226
  // the same three names, so the shape IS the requirement — see session-pick.
120
- session = pickSession(await fx.listSessions(), url, before, isDesktop(input.shape) ? input.shape : undefined);
227
+ session = pickSession(await fx.listSessions(), url, before, requiredRuntime);
121
228
  if (null !== session)
122
229
  break;
123
230
  if (deadline <= fx.now())
@@ -6,7 +6,7 @@
6
6
  * run-setup.ts and the pieces it calls.
7
7
  */
8
8
  import { type SetupInput, type SetupOutcome } from './run-setup.js';
9
- export interface SetupCommandInput extends Omit<SetupInput, 'shape'> {
9
+ interface SetupCommandInput extends Omit<SetupInput, 'shape'> {
10
10
  /** Where setup was invoked, which is not the app directory in a monorepo. */
11
11
  readonly invokedAt: string;
12
12
  readonly bridgePort: number;
@@ -26,7 +26,7 @@ export interface SetupCommandInput extends Omit<SetupInput, 'shape'> {
26
26
  * so a VS Code user has no tools outside the directory they ran init in.
27
27
  */
28
28
  export declare function registerOtherAgents(print: (line: string) => void): void;
29
- export interface SetupCommandResult extends SetupOutcome {
29
+ interface SetupCommandResult extends SetupOutcome {
30
30
  /** Set when a weak flow was re-recorded with the stronger model. */
31
31
  readonly escalated?: {
32
32
  readonly from: string;
@@ -43,3 +43,4 @@ export interface SetupCommandResult extends SetupOutcome {
43
43
  * files and a dead tab.
44
44
  */
45
45
  export declare function runSetupCommand(input: SetupCommandInput, print: (line: string) => void): Promise<SetupCommandResult>;
46
+ export {};
@@ -16,8 +16,12 @@ import { ApprovalOutcome, grantAutoApproval } from './auto-approve.js';
16
16
  import { agentIo } from './agent-io.js';
17
17
  import { EnsureDaemon, ensureDaemon, nodeEnsureDaemonDeps } from './ensure-daemon.js';
18
18
  import { openInBrowser } from '../cli/cli-launch.js';
19
+ import { readProjectId } from '../cli/cli-port.js';
20
+ import { reticleStateHome } from '../daemon/daemon.js';
21
+ import { readDevServers } from '../daemon/dev-servers.js';
19
22
  import { chooseDriver, DRIVERS, shouldEscalate } from './drive-plan.js';
20
23
  import { driveWith } from './drive-agent.js';
24
+ import { urlOfExistingApp } from './existing-app.js';
21
25
  import { binaryExists, flowsSaved, listSessions, OwnedDevServer, probePage, } from './node-effects.js';
22
26
  import { runSetupPhases, } from './run-setup.js';
23
27
  /** The capabilities file init scaffolds, in the order a project is likely to have it. */
@@ -105,6 +109,10 @@ export async function runSetupCommand(input, print) {
105
109
  server.start(command, cwd, input.env);
106
110
  return Promise.resolve();
107
111
  },
112
+ existingAppUrl: () => Promise.resolve(urlOfExistingApp(readDevServers(reticleStateHome()), {
113
+ projectId: readProjectId(input.appDir),
114
+ root: input.appDir,
115
+ })),
108
116
  devServerOutput: () => server.output(),
109
117
  devServerExited: () => server.exited(),
110
118
  devServerQuietForMs: () => server.quietForMs(),
@@ -18,8 +18,9 @@
18
18
  * backend named in the README, the variable that skips an auth wall: all readable by
19
19
  * an agent, none inferable by a script. Without this a real app sits on a login
20
20
  * screen and there is no flow to drive at all.
21
- * --dev-cmd the command, when the project's own scripts do not say it plainly.
22
- * --url the app is already running here, so do not start anything.
21
+ * --url the app is already running here, so do not start anything. This is also the answer
22
+ * when the project's own scripts do not name a dev command: start it yourself and say
23
+ * where. There is no flag that overrides the dev command; --url replaces the need.
23
24
  *
24
25
  * Everything else on this type is an operator's dial, not an agent's judgement.
25
26
  */
@@ -29,7 +30,7 @@ export declare const DEFAULT_BRIDGE_PORT = 4400;
29
30
  export declare const DEFAULT_PHASE_TIMEOUT_MS = 120000;
30
31
  /** What the drive may spend before it is stopped. */
31
32
  export declare const DEFAULT_DRIVE_BUDGET_USD = 3;
32
- export interface SetupOptions {
33
+ interface SetupOptions {
33
34
  /** The journey to drive, in the caller's own words. */
34
35
  readonly flow?: string | undefined;
35
36
  /** Which app in a monorepo. */
@@ -72,3 +73,4 @@ export declare function parseEnvAssignment(pair: string): {
72
73
  * something else should see its variable missing, not see setup invent one.
73
74
  */
74
75
  export declare function collectEnv(pairs: readonly string[]): Record<string, string>;
76
+ export {};
@@ -18,8 +18,9 @@
18
18
  * backend named in the README, the variable that skips an auth wall: all readable by
19
19
  * an agent, none inferable by a script. Without this a real app sits on a login
20
20
  * screen and there is no flow to drive at all.
21
- * --dev-cmd the command, when the project's own scripts do not say it plainly.
22
- * --url the app is already running here, so do not start anything.
21
+ * --url the app is already running here, so do not start anything. This is also the answer
22
+ * when the project's own scripts do not name a dev command: start it yourself and say
23
+ * where. There is no flag that overrides the dev command; --url replaces the need.
23
24
  *
24
25
  * Everything else on this type is an operator's dial, not an agent's judgement.
25
26
  */
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Say what the dev-server wait is waiting FOR, while it waits.
3
+ *
4
+ * `init`'s wait loop polled in complete silence. Reported as thirty minutes of nothing, ending in a
5
+ * SIGKILL: no output, no exit, no verdict. The cause of that particular wait is still unexplained,
6
+ * but the silence is a failure on its own terms — a user cannot tell "still starting" from "wedged",
7
+ * and cannot see the thing most likely to be wrong, which is the URL being watched rather than the
8
+ * server itself.
9
+ *
10
+ * That distinction is not hypothetical: `dev-server-wait.ts` already reasons about a server that
11
+ * serves happily on a port we never found (the CRA case, where no url is printed outside a tty), and
12
+ * has never said so out loud while it happens.
13
+ *
14
+ * Pure, and the clock is the caller's. `elapsedMs` and `lastSpokeAtMs` come in; nothing here reads a
15
+ * real clock, so the decision is testable without one and cannot assert a duration.
16
+ */
17
+ /**
18
+ * How often to speak. Long enough that a normal start — under a second — says nothing at all, since
19
+ * announcing a wait that is not happening is noise in the first command a user ever runs.
20
+ */
21
+ export declare const WAIT_PROGRESS_EVERY_MS = 15000;
22
+ /**
23
+ * The line to print now, or undefined to stay quiet.
24
+ *
25
+ * `lastSpokeAtMs` is when this last returned a line, so the caller can poll as fast as it likes
26
+ * without a line per poll burying the output it exists to explain.
27
+ */
28
+ export declare function waitProgressLine(elapsedMs: number, watching: string | undefined, lastSpokeAtMs: number | undefined): string | undefined;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Say what the dev-server wait is waiting FOR, while it waits.
3
+ *
4
+ * `init`'s wait loop polled in complete silence. Reported as thirty minutes of nothing, ending in a
5
+ * SIGKILL: no output, no exit, no verdict. The cause of that particular wait is still unexplained,
6
+ * but the silence is a failure on its own terms — a user cannot tell "still starting" from "wedged",
7
+ * and cannot see the thing most likely to be wrong, which is the URL being watched rather than the
8
+ * server itself.
9
+ *
10
+ * That distinction is not hypothetical: `dev-server-wait.ts` already reasons about a server that
11
+ * serves happily on a port we never found (the CRA case, where no url is printed outside a tty), and
12
+ * has never said so out loud while it happens.
13
+ *
14
+ * Pure, and the clock is the caller's. `elapsedMs` and `lastSpokeAtMs` come in; nothing here reads a
15
+ * real clock, so the decision is testable without one and cannot assert a duration.
16
+ */
17
+ /**
18
+ * How often to speak. Long enough that a normal start — under a second — says nothing at all, since
19
+ * announcing a wait that is not happening is noise in the first command a user ever runs.
20
+ */
21
+ export const WAIT_PROGRESS_EVERY_MS = 15_000;
22
+ /**
23
+ * The line to print now, or undefined to stay quiet.
24
+ *
25
+ * `lastSpokeAtMs` is when this last returned a line, so the caller can poll as fast as it likes
26
+ * without a line per poll burying the output it exists to explain.
27
+ */
28
+ export function waitProgressLine(elapsedMs, watching, lastSpokeAtMs) {
29
+ if (elapsedMs < WAIT_PROGRESS_EVERY_MS)
30
+ return undefined;
31
+ const since = elapsedMs - (lastSpokeAtMs ?? 0);
32
+ if (lastSpokeAtMs !== undefined && since < WAIT_PROGRESS_EVERY_MS)
33
+ return undefined;
34
+ const seconds = `${String(Math.floor(elapsedMs / 1000))}s`;
35
+ if (watching === undefined) {
36
+ // A different problem, and one the reader can act on: we do not know where to look. The CRA
37
+ // case reaches here, and so does any launcher whose url never appears in its output.
38
+ return (`Waiting ${seconds} for the dev server. It has not announced a url yet and no port was ` +
39
+ `observed, so there is nothing to watch — if it IS up, stop this and pass --url <its url>.`);
40
+ }
41
+ return (`Waiting ${seconds} for the dev server — watching ${watching}. If the app is already up ` +
42
+ `somewhere else, that url is the thing to check first.`);
43
+ }
@@ -16,7 +16,7 @@
16
16
  * `project_profiled` already carries it on the same daemon run, so the two join on sessionId.
17
17
  */
18
18
  export declare function markInstrumentationClock(now: number): void;
19
- export interface InstrumentationFacts {
19
+ interface InstrumentationFacts {
20
20
  /** Whether this project has a projectId stamped — i.e. `init` has run here. */
21
21
  initialized: boolean;
22
22
  /**
@@ -43,3 +43,4 @@ export declare function reportAppInstrumented(facts: InstrumentationFacts, now?:
43
43
  export declare function appEverConnected(): boolean;
44
44
  /** Tests only. */
45
45
  export declare function resetAppInstrumented(): void;
46
+ export {};
@@ -15,7 +15,7 @@
15
15
  * project path, the URL, or anything from the page. The stack is deliberately NOT repeated here;
16
16
  * `project_profiled` already carries it on the same daemon run, so the two join on sessionId.
17
17
  */
18
- import { TelemetryEventKind } from '@reticlehq/core';
18
+ import { TelemetryEventKind } from '@reticlehq/core/telemetry';
19
19
  import { getTelemetry } from './telemetry.js';
20
20
  let reported = false;
21
21
  /** Set at daemon start so the first connect can report how long the install sat un-instrumented. */
@@ -1,4 +1,4 @@
1
- import { AutomationHint } from '@reticlehq/core';
1
+ import { AutomationHint } from '@reticlehq/core/telemetry';
2
2
  interface AutomationInput {
3
3
  env: NodeJS.ProcessEnv;
4
4
  fileExists: (path: string) => boolean;
@@ -25,7 +25,7 @@
25
25
  * developer machines trip it; it separates nothing.
26
26
  */
27
27
  import { existsSync } from 'node:fs';
28
- import { AutomationHint } from '@reticlehq/core';
28
+ import { AutomationHint } from '@reticlehq/core/telemetry';
29
29
  /** Container runtimes drop one of these at the filesystem root. */
30
30
  const CONTAINER_MARKERS = ['/.dockerenv', '/run/.containerenv'];
31
31
  /** Hosted dev environments that declare themselves. Self-declared, never inferred. */
@@ -4,7 +4,7 @@
4
4
  * Lives in its own module so `cli.ts` stays a dispatcher, and so the `_daemon` exclusion below sits
5
5
  * next to the explanation of why it exists rather than buried in a startup function.
6
6
  */
7
- import { TelemetryEventKind } from '@reticlehq/core';
7
+ import { TelemetryEventKind } from '@reticlehq/core/telemetry';
8
8
  import { DAEMON_INNER_COMMAND, knownCommand } from '../cli/cli-parse.js';
9
9
  import { getTelemetry } from './telemetry.js';
10
10
  import { describeCliFlags } from './argument-shape.js';
@@ -11,6 +11,6 @@
11
11
  * this list needs another entry — which is a signal in itself, and the reason it is never merged
12
12
  * into one of the known causes.
13
13
  */
14
- import { ConnectFailure } from '@reticlehq/core';
14
+ import { ConnectFailure } from '@reticlehq/core/telemetry';
15
15
  /** The cause behind a connection error, or `OTHER` when we do not recognize it. */
16
16
  export declare function classifyConnectFailure(error: unknown): ConnectFailure;
@@ -11,7 +11,7 @@
11
11
  * this list needs another entry — which is a signal in itself, and the reason it is never merged
12
12
  * into one of the known causes.
13
13
  */
14
- import { ConnectFailure } from '@reticlehq/core';
14
+ import { ConnectFailure } from '@reticlehq/core/telemetry';
15
15
  /** Ordered most-specific first; the first match wins. Patterns track messages we have actually seen. */
16
16
  const RULES = [
17
17
  // Playwright's own wording when the browser was never downloaded.
@@ -20,14 +20,14 @@
20
20
  * are read and deliberately thrown away.
21
21
  */
22
22
  /** The structured cause of a crash, when the error carries one. Every field is optional. */
23
- export interface CrashCause {
23
+ interface CrashCause {
24
24
  syscall?: string;
25
25
  errno?: string;
26
26
  loopback?: boolean;
27
27
  port?: CrashPort;
28
28
  internalFrame?: string;
29
29
  }
30
- import { CrashPort } from '@reticlehq/core';
30
+ import { CrashPort } from '@reticlehq/core/telemetry';
31
31
  /**
32
32
  * The innermost frame that names NODE's own source.
33
33
  *
@@ -45,3 +45,4 @@ export declare function innermostInternalFrame(stack: string): string | undefine
45
45
  * comparison is testable — the port itself is used to answer one enum and is then discarded.
46
46
  */
47
47
  export declare function crashCause(value: unknown, knownPorts: readonly number[]): CrashCause;
48
+ export {};
@@ -19,7 +19,7 @@
19
19
  * reported as an enum, and the frame names a line in NODE's source. The address and the port number
20
20
  * are read and deliberately thrown away.
21
21
  */
22
- import { CrashPort } from '@reticlehq/core';
22
+ import { CrashPort } from '@reticlehq/core/telemetry';
23
23
  import { reticleFrames } from './error-fingerprint.js';
24
24
  /** IPv4 loopback is the whole 127/8 block, not just 127.0.0.1. */
25
25
  const IPV4_LOOPBACK = /^127\./;
@@ -6,7 +6,7 @@
6
6
  * (nothing here may ever be able to fail a daemon start), and because `cli.ts` is a dispatcher — the
7
7
  * more of this that lives there, the harder it is to see what a command actually does.
8
8
  */
9
- import { type SessionSummary } from '@reticlehq/core';
9
+ import { type SessionSummary } from '@reticlehq/core/telemetry';
10
10
  /**
11
11
  * How often a running daemon rolls up its window.
12
12
  *
@@ -36,7 +36,7 @@ export declare const SESSION_FLUSH_MS: number;
36
36
  */
37
37
  export declare const FIRST_FLUSH_MS: number;
38
38
  /** Stops the timers this installed. Called from the daemon's shutdown path. */
39
- export interface DaemonTelemetry {
39
+ interface DaemonTelemetry {
40
40
  /**
41
41
  * Emit the final, rich session summary and stop flushing. Safe to call more than once.
42
42
  *
@@ -61,3 +61,4 @@ export declare function installDaemonTelemetry(cwd: string, now?: () => number,
61
61
  * trustworthy.
62
62
  */
63
63
  port?: number): DaemonTelemetry;
64
+ export {};
@@ -6,7 +6,7 @@
6
6
  * (nothing here may ever be able to fail a daemon start), and because `cli.ts` is a dispatcher — the
7
7
  * more of this that lives there, the harder it is to see what a command actually does.
8
8
  */
9
- import { TelemetryEventKind } from '@reticlehq/core';
9
+ import { TelemetryEventKind } from '@reticlehq/core/telemetry';
10
10
  import { getTelemetry } from './telemetry.js';
11
11
  import { getSessionMetrics } from './session-metrics.js';
12
12
  import { profileProject } from './project-profile.js';
@@ -11,7 +11,7 @@
11
11
  * counts. The full message is already fingerprinted and skeletonised elsewhere.
12
12
  */
13
13
  /** Whose defect. Ordered by which fix it implies. */
14
- export declare const ErrorClass: {
14
+ declare const ErrorClass: {
15
15
  /** Missing/unknown parameter, wrong type, unparseable predicate. **Our schema is unclear.** */
16
16
  readonly SCHEMA: "schema";
17
17
  /** No session, stale ref, disconnected. The world moved under the agent; not a schema problem. */
@@ -21,6 +21,7 @@ export declare const ErrorClass: {
21
21
  /** Unrecognised. The bucket to watch: a large one is a blind spot, not a long tail. */
22
22
  readonly OTHER: "other";
23
23
  };
24
- export type ErrorClass = (typeof ErrorClass)[keyof typeof ErrorClass];
24
+ type ErrorClass = (typeof ErrorClass)[keyof typeof ErrorClass];
25
25
  /** Which bucket this message belongs to. Never throws — a classifier must not break a tool path. */
26
26
  export declare function classifyError(message: string): ErrorClass;
27
+ export {};
@@ -11,7 +11,7 @@
11
11
  * counts. The full message is already fingerprinted and skeletonised elsewhere.
12
12
  */
13
13
  /** Whose defect. Ordered by which fix it implies. */
14
- export const ErrorClass = {
14
+ const ErrorClass = {
15
15
  /** Missing/unknown parameter, wrong type, unparseable predicate. **Our schema is unclear.** */
16
16
  SCHEMA: 'schema',
17
17
  /** No session, stale ref, disconnected. The world moved under the agent; not a schema problem. */
@@ -1,4 +1,4 @@
1
- import { FeedbackKind, FeedbackSource } from '@reticlehq/core';
1
+ import { FeedbackKind, FeedbackSource } from '@reticlehq/core/telemetry';
2
2
  import { AGENT_FLAG, BUG_FLAG, FEEDBACK_KINDS, KIND_FLAG, RATING_FLAG } from '../cli/cli-parse.js';
3
3
  import { describeFeedbackPayload, submitFeedback } from './feedback.js';
4
4
  import { describeTelemetry, setTelemetryEnabled } from './telemetry.js';
@@ -1,6 +1,6 @@
1
- import { McpScope, StackUnknownReason, type Feedback } from '@reticlehq/core';
1
+ import { McpScope, StackUnknownReason, type Feedback } from '@reticlehq/core/telemetry';
2
2
  /** The context fields — the whole `Feedback` shape minus what the author supplies. */
3
- export type FeedbackContext = Pick<Feedback, 'stack' | 'stackMajor' | 'runtime' | 'engine' | 'driver' | 'client' | 'clientVersion' | 'mcpScope'>;
3
+ type FeedbackContext = Pick<Feedback, 'stack' | 'stackMajor' | 'runtime' | 'engine' | 'driver' | 'client' | 'clientVersion' | 'mcpScope'>;
4
4
  export declare function detectStack(cwd: string, read?: (path: string) => string): {
5
5
  stack?: string;
6
6
  stackMajor?: number;
@@ -55,3 +55,4 @@ export declare function reconcileStack(fromCwd: {
55
55
  };
56
56
  /** Assemble the full context. Every field independently optional — a partial context still ships. */
57
57
  export declare function feedbackContext(cwd: string, session?: SessionFacts): FeedbackContext;
58
+ export {};
@@ -12,9 +12,8 @@
12
12
  import { mcpClientIdentity, setMcpClientIdentityHook } from '../mcp/client-identity.js';
13
13
  import { existsSync, readFileSync, readdirSync } from 'node:fs';
14
14
  import { isAbsolute, join } from 'node:path';
15
- import { AppRuntime, McpScope, PageDriver, StackUnknownReason, } from '@reticlehq/core';
16
- import { parseMajor } from '../init/detect.js';
17
- import { findWorkspaceApps } from '../init/workspace-apps.js';
15
+ import { AppRuntime, McpScope, PageDriver, StackUnknownReason, } from '@reticlehq/core/telemetry';
16
+ import { parseMajor, findWorkspaceApps } from '@reticlehq/init';
18
17
  /**
19
18
  * Dependency → reported stack, in resolution order. Meta-frameworks come FIRST: a Next app also
20
19
  * depends on react, and reporting `react` for it would collapse the single most important segment
@@ -30,6 +29,8 @@ const STACK_BY_DEP = [
30
29
  ['nuxt', 'nuxt'],
31
30
  ['astro', 'astro'],
32
31
  ['@remix-run/react', 'remix'],
32
+ ['@tanstack/react-start', 'tanstack-start'],
33
+ ['@tanstack/start', 'tanstack-start'],
33
34
  ['@angular/core', 'angular'],
34
35
  ['react', 'react'],
35
36
  ['vue', 'vue'],
@@ -215,7 +216,7 @@ function detectClient() {
215
216
  * `sveltekit` are not — that pairing means the daemon's directory is not this session's project.
216
217
  */
217
218
  const ADAPTER_IMPLIES = {
218
- react: ['react', 'next', 'remix'],
219
+ react: ['react', 'next', 'remix', 'tanstack-start'],
219
220
  svelte: ['svelte', 'sveltekit'],
220
221
  vue: ['vue', 'nuxt'],
221
222
  solid: ['solid'],