@reticlehq/server 2.11.0 → 2.13.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 (513) hide show
  1. package/SKILL.md +93 -111
  2. package/dist/bridge/auth-failure-reason.d.ts +6 -2
  3. package/dist/bridge/auth-failure-reason.js +15 -8
  4. package/dist/bridge/bridge.d.ts +18 -14
  5. package/dist/bridge/bridge.js +248 -165
  6. package/dist/bridge/bridge.test-harness.d.ts +2 -0
  7. package/dist/bridge/bridge.test-harness.js +8 -1
  8. package/dist/bridge/pairing-token.d.ts +5 -0
  9. package/dist/bridge/pairing-token.js +28 -0
  10. package/dist/bridge/protocol-skew.d.ts +37 -0
  11. package/dist/bridge/protocol-skew.js +45 -0
  12. package/dist/capsule/capsule-store.d.ts +8 -7
  13. package/dist/capsule/capsule-store.js +1 -1
  14. package/dist/capsule/causal-summary.d.ts +2 -2
  15. package/dist/capsule/causal-summary.js +7 -2
  16. package/dist/chromium-launch-options.d.ts +28 -0
  17. package/dist/chromium-launch-options.js +29 -0
  18. package/dist/cli/cli-doctor.js +39 -1
  19. package/dist/cli/cli-flow-commands.d.ts +3 -1
  20. package/dist/cli/cli-flow-commands.js +34 -4
  21. package/dist/cli/cli-kill.d.ts +2 -1
  22. package/dist/cli/cli-launch.d.ts +11 -1
  23. package/dist/cli/cli-launch.js +59 -10
  24. package/dist/cli/cli-parse.d.ts +17 -1
  25. package/dist/cli/cli-parse.js +238 -12
  26. package/dist/cli/cli-update-commands.js +20 -1
  27. package/dist/cli/cli-verify.d.ts +2 -1
  28. package/dist/cli/cli-verify.js +5 -4
  29. package/dist/cli/cloud-cli.js +428 -253
  30. package/dist/cli/cloud-keystore.d.ts +37 -0
  31. package/dist/cli/cloud-keystore.js +97 -0
  32. package/dist/cli/cloud-kit.d.ts +37 -0
  33. package/dist/cli/cloud-kit.js +121 -0
  34. package/dist/cli/cloud-login.d.ts +17 -0
  35. package/dist/cli/cloud-login.js +183 -0
  36. package/dist/cli/cloud-session.d.ts +48 -0
  37. package/dist/cli/cloud-session.js +53 -0
  38. package/dist/cli/config-discovery.d.ts +2 -1
  39. package/dist/cli/config-discovery.js +1 -0
  40. package/dist/cli/daemon-start-options.d.ts +32 -0
  41. package/dist/cli/daemon-start-options.js +38 -0
  42. package/dist/cli/device-flow.d.ts +76 -0
  43. package/dist/cli/device-flow.js +56 -0
  44. package/dist/cli/doctor-rows.d.ts +12 -1
  45. package/dist/cli/doctor-rows.js +12 -1
  46. package/dist/cli/drive-attach.d.ts +13 -0
  47. package/dist/cli/drive-attach.js +18 -0
  48. package/dist/cli/drive-command.js +7 -3
  49. package/dist/cli/gate-exit.d.ts +21 -0
  50. package/dist/cli/gate-exit.js +21 -0
  51. package/dist/cli/gate-hook-message.d.ts +33 -0
  52. package/dist/cli/gate-hook-message.js +46 -0
  53. package/dist/cli/mcp-command.d.ts +25 -0
  54. package/dist/cli/mcp-command.js +174 -0
  55. package/dist/cli/project-name.d.ts +30 -0
  56. package/dist/cli/project-name.js +44 -0
  57. package/dist/cli/sibling-ports.d.ts +37 -0
  58. package/dist/cli/sibling-ports.js +56 -0
  59. package/dist/cli/status-next-action.d.ts +14 -0
  60. package/dist/cli/status-next-action.js +4 -4
  61. package/dist/cli.d.ts +1 -0
  62. package/dist/cli.js +167 -186
  63. package/dist/cloud/cloud-config.d.ts +24 -2
  64. package/dist/cloud/cloud-config.js +64 -5
  65. package/dist/cloud/cloud-sync.d.ts +16 -5
  66. package/dist/cloud/cloud-sync.js +64 -1
  67. package/dist/cloud/sync-cycle.d.ts +110 -0
  68. package/dist/cloud/sync-cycle.js +270 -0
  69. package/dist/cloud/sync-daemon.d.ts +69 -0
  70. package/dist/cloud/sync-daemon.js +260 -0
  71. package/dist/cloud/sync-disk.d.ts +9 -0
  72. package/dist/cloud/sync-disk.js +191 -0
  73. package/dist/cloud/sync-hash.d.ts +2 -0
  74. package/dist/cloud/sync-hash.js +35 -0
  75. package/dist/crawl/crawl-tools.js +5 -3
  76. package/dist/crawl/crawl.d.ts +12 -13
  77. package/dist/crawl/crawl.js +25 -3
  78. package/dist/daemon/daemon-resolve.d.ts +122 -0
  79. package/dist/daemon/daemon-resolve.js +187 -0
  80. package/dist/daemon/dev-servers.d.ts +15 -0
  81. package/dist/daemon/dev-servers.js +68 -0
  82. package/dist/daemon/free-port.d.ts +29 -0
  83. package/dist/daemon/free-port.js +55 -0
  84. package/dist/daemon/heartbeat.d.ts +0 -4
  85. package/dist/daemon/heartbeat.js +2 -2
  86. package/dist/daemon/wake-decision.d.ts +32 -0
  87. package/dist/daemon/wake-decision.js +38 -0
  88. package/dist/dev/stale-issue-guard.d.ts +0 -2
  89. package/dist/dev/stale-issue-guard.js +1 -1
  90. package/dist/domain/domain-tools.js +2 -2
  91. package/dist/events/contradictions.d.ts +59 -0
  92. package/dist/events/contradictions.js +253 -27
  93. package/dist/events/declared.d.ts +17 -0
  94. package/dist/events/declared.js +43 -1
  95. package/dist/events/echo-mismatch.js +65 -1
  96. package/dist/events/event-filters.d.ts +8 -0
  97. package/dist/events/event-filters.js +19 -2
  98. package/dist/events/observed-in-window.d.ts +12 -0
  99. package/dist/events/observed-in-window.js +17 -0
  100. package/dist/events/predicate-asks.d.ts +13 -0
  101. package/dist/events/predicate-asks.js +22 -0
  102. package/dist/events/predicate-eval.js +117 -27
  103. package/dist/events/predicate-parse.d.ts +0 -6
  104. package/dist/events/predicate-parse.js +43 -3
  105. package/dist/events/predicate-precheck.d.ts +8 -0
  106. package/dist/events/predicate-precheck.js +41 -0
  107. package/dist/events/predicate-route.d.ts +14 -0
  108. package/dist/events/predicate-route.js +36 -8
  109. package/dist/events/predicate-schema.d.ts +44 -0
  110. package/dist/events/predicate-schema.js +126 -23
  111. package/dist/events/predicate.d.ts +20 -0
  112. package/dist/events/predicate.js +77 -6
  113. package/dist/events/split-text-miss.d.ts +30 -0
  114. package/dist/events/split-text-miss.js +44 -0
  115. package/dist/flows/coverage.d.ts +0 -8
  116. package/dist/flows/coverage.js +1 -1
  117. package/dist/flows/decision.d.ts +5 -1
  118. package/dist/flows/decision.js +33 -7
  119. package/dist/flows/flake.d.ts +6 -8
  120. package/dist/flows/flake.js +1 -1
  121. package/dist/flows/flow-intent.d.ts +52 -0
  122. package/dist/flows/flow-intent.js +123 -0
  123. package/dist/flows/flow-memory-consult.d.ts +55 -0
  124. package/dist/flows/flow-memory-consult.js +38 -0
  125. package/dist/flows/flow-replay-run.d.ts +18 -7
  126. package/dist/flows/flow-replay-run.js +263 -23
  127. package/dist/flows/flow-replay.js +11 -2
  128. package/dist/flows/flow-step-runners.d.ts +8 -0
  129. package/dist/flows/flow-step-runners.js +8 -2
  130. package/dist/flows/flow-store-for-session.d.ts +31 -0
  131. package/dist/flows/flow-store-for-session.js +33 -0
  132. package/dist/flows/flow-success.js +15 -3
  133. package/dist/flows/flow-tools.js +87 -33
  134. package/dist/flows/flows.d.ts +14 -1
  135. package/dist/flows/flows.js +502 -24
  136. package/dist/flows/heal-run.js +5 -2
  137. package/dist/flows/predicate-to-expect.d.ts +17 -12
  138. package/dist/flows/predicate-to-expect.js +36 -15
  139. package/dist/flows/recordings.d.ts +13 -1
  140. package/dist/flows/recordings.js +17 -2
  141. package/dist/flows/replay.d.ts +22 -2
  142. package/dist/flows/replay.js +28 -2
  143. package/dist/flows/server-verify.js +16 -2
  144. package/dist/flows/verify-change-tools.js +9 -3
  145. package/dist/honesty/blind-spots.d.ts +51 -15
  146. package/dist/honesty/blind-spots.js +64 -4
  147. package/dist/honesty/feature-capture.d.ts +150 -0
  148. package/dist/honesty/feature-capture.js +233 -0
  149. package/dist/honesty/honesty.d.ts +24 -0
  150. package/dist/honesty/honesty.js +25 -1
  151. package/dist/honesty/instrumentation-gaps.d.ts +39 -6
  152. package/dist/honesty/instrumentation-gaps.js +88 -5
  153. package/dist/honesty/tool-hit-rate.d.ts +86 -0
  154. package/dist/honesty/tool-hit-rate.js +90 -0
  155. package/dist/honesty/undeclared-change.d.ts +51 -0
  156. package/dist/honesty/undeclared-change.js +56 -0
  157. package/dist/honesty/verified.d.ts +16 -0
  158. package/dist/honesty/verified.js +84 -5
  159. package/dist/http-server.d.ts +0 -1
  160. package/dist/http-server.js +13 -1
  161. package/dist/hunt/hunt-report.d.ts +0 -2
  162. package/dist/hunt/hunt-report.js +1 -1
  163. package/dist/impact/impact-recorder.d.ts +31 -8
  164. package/dist/impact/impact-recorder.js +104 -21
  165. package/dist/impact/impact-store.d.ts +13 -4
  166. package/dist/impact/impact-store.js +44 -3
  167. package/dist/index.d.ts +4 -1
  168. package/dist/index.js +113 -7
  169. package/dist/init/agent-rules.d.ts +30 -6
  170. package/dist/init/agent-rules.js +54 -13
  171. package/dist/init/astro-patch.d.ts +16 -0
  172. package/dist/init/astro-patch.js +28 -0
  173. package/dist/init/capabilities.d.ts +4 -3
  174. package/dist/init/capabilities.js +23 -3
  175. package/dist/init/closing-hint.d.ts +36 -0
  176. package/dist/init/closing-hint.js +120 -0
  177. package/dist/init/confirm.d.ts +27 -28
  178. package/dist/init/confirm.js +51 -11
  179. package/dist/init/cra.d.ts +34 -5
  180. package/dist/init/cra.js +96 -25
  181. package/dist/init/csp-check.js +17 -2
  182. package/dist/init/csp-doctor.d.ts +8 -1
  183. package/dist/init/csp-doctor.js +8 -3
  184. package/dist/init/dev-script.d.ts +50 -0
  185. package/dist/init/dev-script.js +66 -0
  186. package/dist/init/format-generated.d.ts +18 -0
  187. package/dist/init/format-generated.js +39 -0
  188. package/dist/init/install-hint.d.ts +9 -0
  189. package/dist/init/install-hint.js +29 -0
  190. package/dist/init/mcp-clients.d.ts +7 -0
  191. package/dist/init/mcp-clients.js +7 -0
  192. package/dist/init/mcp.d.ts +17 -6
  193. package/dist/init/mcp.js +27 -11
  194. package/dist/init/node-io.js +11 -1
  195. package/dist/init/plan-framework.d.ts +0 -5
  196. package/dist/init/plan-framework.js +147 -37
  197. package/dist/init/plan.d.ts +30 -37
  198. package/dist/init/plan.js +50 -60
  199. package/dist/init/preflight.d.ts +28 -0
  200. package/dist/init/preflight.js +38 -0
  201. package/dist/init/refresh-rules.d.ts +39 -0
  202. package/dist/init/refresh-rules.js +51 -0
  203. package/dist/init/run.d.ts +32 -35
  204. package/dist/init/run.js +151 -202
  205. package/dist/init/slash-command.d.ts +1 -1
  206. package/dist/init/snippets.js +90 -31
  207. package/dist/init/vite-config.d.ts +1 -1
  208. package/dist/init/vite-config.js +39 -25
  209. package/dist/init/workspace-apps.d.ts +17 -10
  210. package/dist/init/workspace-apps.js +110 -0
  211. package/dist/input/network-mock-tools.js +3 -6
  212. package/dist/input/real-input.d.ts +2 -0
  213. package/dist/input/real-input.js +28 -7
  214. package/dist/input/scroll-find.d.ts +7 -4
  215. package/dist/input/scroll-find.js +63 -25
  216. package/dist/input/scroll-tools.js +4 -6
  217. package/dist/input/viewport-tools.js +5 -4
  218. package/dist/intent/inline-intent.d.ts +37 -0
  219. package/dist/intent/inline-intent.js +193 -0
  220. package/dist/intent/intent-shard-store.d.ts +72 -0
  221. package/dist/intent/intent-shard-store.js +203 -0
  222. package/dist/intent/intent-shard.d.ts +411 -0
  223. package/dist/intent/intent-shard.js +176 -0
  224. package/dist/intent/intent-store.d.ts +49 -0
  225. package/dist/intent/intent-store.js +133 -0
  226. package/dist/intent/intent-subject.d.ts +45 -0
  227. package/dist/intent/intent-subject.js +177 -0
  228. package/dist/intent/intent-tools.d.ts +2 -0
  229. package/dist/intent/intent-tools.js +143 -0
  230. package/dist/intent/open-intents.d.ts +42 -0
  231. package/dist/intent/open-intents.js +40 -0
  232. package/dist/journal/envelope.d.ts +26 -26
  233. package/dist/journal/journal-recorder.d.ts +23 -0
  234. package/dist/journal/journal-recorder.js +35 -0
  235. package/dist/license/license-env.d.ts +29 -0
  236. package/dist/license/license-env.js +148 -0
  237. package/dist/loopback-agent.d.ts +31 -0
  238. package/dist/loopback-agent.js +57 -0
  239. package/dist/mcp/attach-memory.d.ts +83 -0
  240. package/dist/mcp/attach-memory.js +185 -0
  241. package/dist/mcp/client-identity.d.ts +31 -0
  242. package/dist/mcp/client-identity.js +51 -0
  243. package/dist/mcp/mcp-post-transport.d.ts +26 -0
  244. package/dist/mcp/mcp-post-transport.js +109 -0
  245. package/dist/mcp/mcp-proxy.d.ts +2 -8
  246. package/dist/mcp/mcp-proxy.js +64 -62
  247. package/dist/mcp/mcp.d.ts +2 -0
  248. package/dist/mcp/mcp.js +52 -24
  249. package/dist/mcp/proxy-backoff.d.ts +11 -0
  250. package/dist/mcp/proxy-backoff.js +13 -0
  251. package/dist/mcp/proxy-daemon-probe.d.ts +1 -0
  252. package/dist/mcp/proxy-daemon-probe.js +7 -1
  253. package/dist/mcp/proxy-handshake.d.ts +23 -0
  254. package/dist/mcp/proxy-handshake.js +31 -0
  255. package/dist/mcp/server-instructions.js +45 -3
  256. package/dist/mcp/tool-catalog-cache.d.ts +16 -0
  257. package/dist/mcp/tool-catalog-cache.js +22 -0
  258. package/dist/memory/memory-tools.d.ts +2 -0
  259. package/dist/memory/memory-tools.js +82 -0
  260. package/dist/memory/project-memory.d.ts +34 -0
  261. package/dist/memory/project-memory.js +96 -0
  262. package/dist/oracles/flow-instrument-gaps.d.ts +4 -4
  263. package/dist/oracles/flow-instrument-gaps.js +4 -5
  264. package/dist/oracles/propose-consequences.js +12 -3
  265. package/dist/oracles/self-instrument.d.ts +9 -9
  266. package/dist/oracles/self-instrument.js +19 -13
  267. package/dist/pool/browser-pool.d.ts +75 -5
  268. package/dist/pool/browser-pool.js +144 -5
  269. package/dist/pool/playwright-launcher.js +12 -1
  270. package/dist/project/fs-port.d.ts +3 -0
  271. package/dist/project/fs-port.js +3 -2
  272. package/dist/project/memory-fs.js +6 -1
  273. package/dist/project/project-tools.js +6 -35
  274. package/dist/project/reticle-dir.d.ts +17 -2
  275. package/dist/project/reticle-dir.js +22 -4
  276. package/dist/runs/context-tools.d.ts +2 -0
  277. package/dist/runs/context-tools.js +89 -0
  278. package/dist/runs/run-context.d.ts +40 -0
  279. package/dist/runs/run-context.js +158 -0
  280. package/dist/runs/run-diff.d.ts +2 -1
  281. package/dist/runs/run-store.d.ts +10 -0
  282. package/dist/runs/run-store.js +10 -0
  283. package/dist/runs/verification-sync.d.ts +0 -11
  284. package/dist/runs/verification-sync.js +24 -3
  285. package/dist/runs/verify-server.d.ts +8 -1
  286. package/dist/runs/verify-server.js +14 -2
  287. package/dist/session/command-timeout.d.ts +5 -2
  288. package/dist/session/command-timeout.js +5 -4
  289. package/dist/session/dev-server-probe.d.ts +0 -8
  290. package/dist/session/dev-server-probe.js +1 -1
  291. package/dist/session/last-act.d.ts +7 -1
  292. package/dist/session/last-act.js +2 -2
  293. package/dist/session/lease-visibility.d.ts +67 -0
  294. package/dist/session/lease-visibility.js +76 -0
  295. package/dist/session/live-control-tools.js +1 -42
  296. package/dist/session/no-session-diagnosis.d.ts +33 -0
  297. package/dist/session/no-session-diagnosis.js +82 -24
  298. package/dist/session/no-session-next-action.d.ts +12 -0
  299. package/dist/session/no-session-next-action.js +77 -6
  300. package/dist/session/no-session-watch.d.ts +18 -6
  301. package/dist/session/no-session-watch.js +125 -75
  302. package/dist/session/output-budget.js +4 -1
  303. package/dist/session/pending-commands.d.ts +11 -1
  304. package/dist/session/pending-commands.js +12 -2
  305. package/dist/session/resolve-within.d.ts +34 -0
  306. package/dist/session/resolve-within.js +53 -0
  307. package/dist/session/session-health.d.ts +9 -0
  308. package/dist/session/session-health.js +23 -0
  309. package/dist/session/session-info.d.ts +18 -0
  310. package/dist/session/session-info.js +11 -0
  311. package/dist/session/session-manager.d.ts +14 -0
  312. package/dist/session/session-manager.js +111 -4
  313. package/dist/session/session-mirror.d.ts +16 -0
  314. package/dist/session/session-mirror.js +22 -0
  315. package/dist/session/session-recommendation.d.ts +19 -5
  316. package/dist/session/session-recommendation.js +25 -9
  317. package/dist/session/session-successor.d.ts +37 -0
  318. package/dist/session/session-successor.js +113 -0
  319. package/dist/session/session-tools.js +2 -2
  320. package/dist/session/session.d.ts +53 -3
  321. package/dist/session/session.js +162 -9
  322. package/dist/session/wall-clock.d.ts +12 -0
  323. package/dist/session/wall-clock.js +14 -0
  324. package/dist/setup/agent-configs.d.ts +96 -0
  325. package/dist/setup/agent-configs.js +333 -0
  326. package/dist/setup/agent-io.d.ts +9 -0
  327. package/dist/setup/agent-io.js +16 -0
  328. package/dist/setup/agent-writer.d.ts +51 -0
  329. package/dist/setup/agent-writer.js +115 -0
  330. package/dist/setup/approval-migration.d.ts +47 -0
  331. package/dist/setup/approval-migration.js +68 -0
  332. package/dist/setup/auto-approve.d.ts +85 -0
  333. package/dist/setup/auto-approve.js +150 -0
  334. package/dist/setup/bridge-port.d.ts +15 -0
  335. package/dist/setup/bridge-port.js +24 -0
  336. package/dist/setup/desktop-shape.d.ts +57 -0
  337. package/dist/setup/desktop-shape.js +63 -0
  338. package/dist/setup/dev-server-wait.d.ts +60 -0
  339. package/dist/setup/dev-server-wait.js +65 -0
  340. package/dist/setup/drive-agent.d.ts +71 -0
  341. package/dist/setup/drive-agent.js +171 -0
  342. package/dist/setup/drive-plan.d.ts +68 -0
  343. package/dist/setup/drive-plan.js +130 -0
  344. package/dist/setup/ensure-daemon.d.ts +29 -0
  345. package/dist/setup/ensure-daemon.js +58 -0
  346. package/dist/setup/init-runtime.d.ts +47 -0
  347. package/dist/setup/init-runtime.js +160 -0
  348. package/dist/setup/interrupt.d.ts +25 -0
  349. package/dist/setup/interrupt.js +40 -0
  350. package/dist/setup/license-key.d.ts +39 -0
  351. package/dist/setup/license-key.js +72 -0
  352. package/dist/setup/listeners.d.ts +37 -0
  353. package/dist/setup/listeners.js +85 -0
  354. package/dist/setup/node-effects.d.ts +60 -0
  355. package/dist/setup/node-effects.js +210 -0
  356. package/dist/setup/page-probe.d.ts +39 -0
  357. package/dist/setup/page-probe.js +49 -0
  358. package/dist/setup/relaunch.d.ts +36 -0
  359. package/dist/setup/relaunch.js +57 -0
  360. package/dist/setup/remaining-steps.d.ts +19 -0
  361. package/dist/setup/remaining-steps.js +31 -0
  362. package/dist/setup/run-setup.d.ts +99 -0
  363. package/dist/setup/run-setup.js +187 -0
  364. package/dist/setup/session-pick.d.ts +47 -0
  365. package/dist/setup/session-pick.js +51 -0
  366. package/dist/setup/setup-command.d.ts +45 -0
  367. package/dist/setup/setup-command.js +199 -0
  368. package/dist/setup/setup-options.d.ts +74 -0
  369. package/dist/setup/setup-options.js +67 -0
  370. package/dist/setup/transcripts.d.ts +16 -0
  371. package/dist/setup/transcripts.js +43 -0
  372. package/dist/status-payload.d.ts +14 -1
  373. package/dist/status-payload.js +23 -1
  374. package/dist/telemetry/automation-hint.d.ts +2 -1
  375. package/dist/telemetry/daemon-telemetry.d.ts +8 -1
  376. package/dist/telemetry/daemon-telemetry.js +52 -5
  377. package/dist/telemetry/error-class.js +1 -1
  378. package/dist/telemetry/feedback-context.d.ts +9 -1
  379. package/dist/telemetry/feedback-context.js +60 -29
  380. package/dist/telemetry/feedback-local.d.ts +15 -0
  381. package/dist/telemetry/feedback-local.js +56 -0
  382. package/dist/telemetry/feedback-outbox.d.ts +2 -1
  383. package/dist/telemetry/feedback.d.ts +11 -0
  384. package/dist/telemetry/feedback.js +19 -6
  385. package/dist/telemetry/init-telemetry.d.ts +2 -0
  386. package/dist/telemetry/init-telemetry.js +2 -0
  387. package/dist/telemetry/install-source.d.ts +14 -0
  388. package/dist/telemetry/install-source.js +30 -0
  389. package/dist/telemetry/license-activation.d.ts +7 -1
  390. package/dist/telemetry/license-activation.js +9 -5
  391. package/dist/telemetry/mcp-connection.js +7 -0
  392. package/dist/telemetry/project-profile.d.ts +12 -9
  393. package/dist/telemetry/project-profile.js +12 -7
  394. package/dist/telemetry/proxy-telemetry.d.ts +3 -0
  395. package/dist/telemetry/proxy-telemetry.js +21 -0
  396. package/dist/telemetry/run-telemetry.d.ts +0 -2
  397. package/dist/telemetry/run-telemetry.js +1 -1
  398. package/dist/telemetry/session-metrics.d.ts +12 -0
  399. package/dist/telemetry/session-metrics.js +35 -1
  400. package/dist/telemetry/telemetry.js +17 -2
  401. package/dist/telemetry/tool-refused.d.ts +3 -1
  402. package/dist/telemetry/tool-refused.js +34 -2
  403. package/dist/telemetry/verification-of.js +2 -2
  404. package/dist/tools/act-capsule.d.ts +10 -0
  405. package/dist/tools/act-capsule.js +8 -2
  406. package/dist/tools/act-danger.d.ts +2 -1
  407. package/dist/tools/act-danger.js +11 -3
  408. package/dist/tools/act-observation.d.ts +41 -0
  409. package/dist/tools/act-observation.js +36 -0
  410. package/dist/tools/act-preflight.d.ts +20 -0
  411. package/dist/tools/act-preflight.js +98 -0
  412. package/dist/tools/act-sequence-retry.d.ts +45 -0
  413. package/dist/tools/act-sequence-retry.js +58 -0
  414. package/dist/tools/act-sequence-tool.d.ts +13 -0
  415. package/dist/tools/act-sequence-tool.js +135 -0
  416. package/dist/tools/act-target.d.ts +14 -0
  417. package/dist/tools/act-target.js +47 -0
  418. package/dist/tools/act-tools.d.ts +21 -1
  419. package/dist/tools/act-tools.js +196 -204
  420. package/dist/tools/assert-source.d.ts +22 -0
  421. package/dist/tools/assert-source.js +53 -0
  422. package/dist/tools/assert-verdict.d.ts +20 -3
  423. package/dist/tools/assert-verdict.js +58 -20
  424. package/dist/tools/browser-tools.js +6 -22
  425. package/dist/tools/complete-snapshot.d.ts +48 -0
  426. package/dist/tools/complete-snapshot.js +75 -0
  427. package/dist/tools/coverage-tools.d.ts +10 -1
  428. package/dist/tools/coverage-tools.js +123 -69
  429. package/dist/tools/dynamic-tools.js +53 -13
  430. package/dist/tools/error-recovery.d.ts +25 -14
  431. package/dist/tools/error-recovery.js +78 -9
  432. package/dist/tools/feedback-tools.d.ts +1 -1
  433. package/dist/tools/feedback-tools.js +2 -2
  434. package/dist/tools/invoke-tool.js +121 -11
  435. package/dist/tools/lease-hint.d.ts +10 -0
  436. package/dist/tools/lease-hint.js +53 -4
  437. package/dist/tools/lease-tools.d.ts +35 -5
  438. package/dist/tools/lease-tools.js +191 -13
  439. package/dist/tools/merged-name-redirect.d.ts +13 -0
  440. package/dist/tools/merged-name-redirect.js +22 -0
  441. package/dist/tools/navigate-arrival.d.ts +0 -2
  442. package/dist/tools/navigate-arrival.js +1 -1
  443. package/dist/tools/numeric-bounds.d.ts +100 -0
  444. package/dist/tools/numeric-bounds.js +125 -0
  445. package/dist/tools/observe-tools.js +109 -65
  446. package/dist/tools/read-tools.js +31 -8
  447. package/dist/tools/real-input-attempt.d.ts +32 -0
  448. package/dist/tools/real-input-attempt.js +212 -2
  449. package/dist/tools/reconcile-tools.js +22 -8
  450. package/dist/tools/resolve-target.d.ts +0 -7
  451. package/dist/tools/sdk-marker-probe.d.ts +29 -0
  452. package/dist/tools/sdk-marker-probe.js +57 -0
  453. package/dist/tools/snapshot-delta.d.ts +1 -1
  454. package/dist/tools/tool-kit.d.ts +24 -0
  455. package/dist/tools/tool-kit.js +21 -0
  456. package/dist/tools/tool-names.d.ts +5 -0
  457. package/dist/tools/tool-names.js +5 -0
  458. package/dist/tools/tool-surface.d.ts +85 -6
  459. package/dist/tools/tool-surface.js +122 -2
  460. package/dist/tools/tools-helpers.d.ts +19 -0
  461. package/dist/tools/tools-helpers.js +46 -0
  462. package/dist/tools/tools.d.ts +2 -0
  463. package/dist/tools/tools.js +78 -12
  464. package/dist/tools/unadvertised-help.js +4 -4
  465. package/dist/tools/verify-next-baton.d.ts +53 -0
  466. package/dist/tools/verify-next-baton.js +52 -0
  467. package/dist/update/reticle-deps.d.ts +9 -0
  468. package/dist/update/reticle-deps.js +27 -0
  469. package/dist/update/sdk-sync.d.ts +1 -2
  470. package/dist/update/sdk-sync.js +1 -21
  471. package/dist/update/update-nudge.d.ts +25 -10
  472. package/dist/update/update-nudge.js +32 -3
  473. package/dist/update/updater.d.ts +1 -1
  474. package/dist/version/peer-announce.js +4 -2
  475. package/dist/version/sdk-fix.d.ts +47 -0
  476. package/dist/version/sdk-fix.js +127 -0
  477. package/dist/version/version-nudge.d.ts +14 -0
  478. package/dist/version/version-nudge.js +21 -0
  479. package/dist/version/version-skew.d.ts +38 -3
  480. package/dist/version/version-skew.js +83 -7
  481. package/dist/visual/visual-store.d.ts +6 -6
  482. package/dist/visual/visual-store.js +18 -16
  483. package/dist/visual/visual-tools.js +57 -12
  484. package/docs/README.md +2 -1
  485. package/docs/cli/cloud.mdx +1 -1
  486. package/docs/cli/doctor.mdx +2 -0
  487. package/docs/cli/serve.mdx +4 -2
  488. package/docs/cli/verify.mdx +4 -5
  489. package/docs/cli.mdx +7 -3
  490. package/docs/desktop.mdx +1 -1
  491. package/docs/docs.json +2 -2
  492. package/docs/gates.md +1 -1
  493. package/docs/getting-started.md +19 -3
  494. package/docs/index.mdx +9 -6
  495. package/docs/install-agentic.mdx +38 -12
  496. package/docs/install-manual.mdx +1 -1
  497. package/docs/packages/browser.mdx +2 -2
  498. package/docs/packages/server.mdx +1 -1
  499. package/docs/packages.mdx +8 -6
  500. package/docs/platform-integration.md +17 -0
  501. package/docs/predicates.mdx +8 -0
  502. package/docs/reticle-manual.md +106 -0
  503. package/docs/skill-file.mdx +3 -3
  504. package/docs/telemetry-contract.md +108 -4
  505. package/docs/tools-act-sequence.mdx +16 -0
  506. package/docs/tools-tools-and-run.mdx +2 -4
  507. package/docs/troubleshooting.mdx +9 -0
  508. package/docs/usage.md +4 -3
  509. package/package.json +4 -3
  510. package/dist/init/cursor.d.ts +0 -24
  511. package/dist/init/cursor.js +0 -80
  512. package/dist/session/session-readiness.d.ts +0 -34
  513. package/dist/session/session-readiness.js +0 -36
@@ -30,10 +30,10 @@ function bridgeOrigins(port) {
30
30
  * Matches to the end of the directive (`;`) or the end of the enclosing quoted string, which is how
31
31
  * these are written in both a Next `headers()` value and a `<meta content="...">`.
32
32
  */
33
- function connectSrcSources(text) {
33
+ function directiveSources(text, directive) {
34
34
  // Stops at the directive separator or the closing double quote of the enclosing string. Single
35
35
  // quotes are NOT terminators: `'self'` is a source, not the end of the list.
36
- const match = /connect-src([^;"]*)/i.exec(text);
36
+ const match = new RegExp(`${directive}([^;"]*)`, 'i').exec(text);
37
37
  const list = match?.[1];
38
38
  if (list === undefined)
39
39
  return undefined;
@@ -42,6 +42,21 @@ function connectSrcSources(text) {
42
42
  .map((source) => source.trim())
43
43
  .filter((source) => source.length > 0);
44
44
  }
45
+ /**
46
+ * What this policy allows a WebSocket to reach — `connect-src`, or `default-src` when it is absent.
47
+ *
48
+ * The fallback is the CSP spec's, and leaving it out made the check blind to the commonest strict
49
+ * policy there is. MarkText, a production Electron editor, declares
50
+ * `default-src 'self'; script-src 'self'; …` with NO `connect-src`: its WebSockets are restricted to
51
+ * 'self', the bridge is blocked, and this returned "no problem" because it was looking for a
52
+ * directive that was not written. Every fetch-directive falls back to `default-src`; that is what
53
+ * `default` means, and it is why an author does not repeat themselves.
54
+ *
55
+ * Still undefined when NEITHER is present — a policy that constrains neither is not blocking us.
56
+ */
57
+ function connectSrcSources(text) {
58
+ return directiveSources(text, 'connect-src') ?? directiveSources(text, 'default-src');
59
+ }
45
60
  /**
46
61
  * The problem with this app's `connect-src`, or undefined if there is not one.
47
62
  *
@@ -21,5 +21,12 @@ export interface CspDiagnosis {
21
21
  /** Exactly what to add — copy-pasteable, with the port actually in use. */
22
22
  fix: string;
23
23
  }
24
- export declare function diagnoseWebCsp(read: ReadFile, port: number): CspDiagnosis[];
24
+ /**
25
+ * The places a Content-Security-Policy gets written in a JS app.
26
+ *
27
+ * Next config and middleware cover `headers()` and the edge-middleware style; the layouts and the
28
+ * plain `index.html` cover the `<meta http-equiv>` style. Both reported cases were in this list.
29
+ */
30
+ export declare const CSP_FILES: readonly string[];
31
+ export declare function diagnoseWebCsp(read: ReadFile, port: number, alsoCheck?: readonly string[]): CspDiagnosis[];
25
32
  export {};
@@ -18,7 +18,7 @@ import { cspConnectSrcProblem, devCspAddition } from './csp-check.js';
18
18
  * Next config and middleware cover `headers()` and the edge-middleware style; the layouts and the
19
19
  * plain `index.html` cover the `<meta http-equiv>` style. Both reported cases were in this list.
20
20
  */
21
- const CSP_FILES = [
21
+ export const CSP_FILES = [
22
22
  'next.config.js',
23
23
  'next.config.mjs',
24
24
  'next.config.ts',
@@ -31,12 +31,17 @@ const CSP_FILES = [
31
31
  'pages/_document.js',
32
32
  'index.html',
33
33
  'public/index.html',
34
+ // Vite puts the entry HTML at the project root; electron-vite and Tauri put the RENDERER's one
35
+ // under src/. MarkText declares its policy in `src/renderer/index.html`, and a desktop app is the
36
+ // likeliest place to meet a strict CSP at all — Electron's own security guidance asks for one.
37
+ 'src/index.html',
38
+ 'src/renderer/index.html',
34
39
  'vercel.json',
35
40
  'netlify.toml',
36
41
  ];
37
- export function diagnoseWebCsp(read, port) {
42
+ export function diagnoseWebCsp(read, port, alsoCheck = []) {
38
43
  const findings = [];
39
- for (const file of CSP_FILES) {
44
+ for (const file of [...alsoCheck, ...CSP_FILES]) {
40
45
  const source = read(file);
41
46
  if (source === undefined)
42
47
  continue;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Which command starts this project, and should we start it ourselves?
3
+ *
4
+ * `init` finishes by telling the human to start or restart their dev server, in a closing
5
+ * paragraph, in a terminal that is about to be cleared by the client restart it also asks for.
6
+ * That is the second unmarked hand-off in the install, after the capabilities file, and it lands
7
+ * on the same surface: prose nobody re-reads.
8
+ *
9
+ * Every fact needed to remove it is already in the project. `package.json` names the script; the
10
+ * framework tells us the conventional port; a probe tells us whether something already answers
11
+ * there. Nothing here needs a human.
12
+ *
13
+ * Kept as a PURE decision, separate from spawning, because the interesting part is the judgement —
14
+ * which script, and whether to touch anything at all — and that is what wants testing. Spawning a
15
+ * process is not.
16
+ */
17
+ /** Script names a JS project uses to run itself, in the order we would pick them. */
18
+ export declare const DEV_SCRIPT_NAMES: readonly ["dev", "start", "serve"];
19
+ export declare const DevScriptChoice: {
20
+ /** Something already answers on the port. Use it; never replace a server the user is running. */
21
+ readonly ALREADY_SERVING: "already-serving";
22
+ /** We know the command and nothing is listening. Start it. */
23
+ readonly START: "start";
24
+ /** No script we recognise. Say so rather than guess a command. */
25
+ readonly NO_SCRIPT: "no-script";
26
+ };
27
+ export type DevScriptChoice = (typeof DevScriptChoice)[keyof typeof DevScriptChoice];
28
+ export interface DevScriptPlan {
29
+ choice: DevScriptChoice;
30
+ /** The npm script name, when there is one. */
31
+ script?: string;
32
+ /** What a human would type, for the line we print. */
33
+ command?: string;
34
+ }
35
+ /**
36
+ * Pick the script and decide whether to run it.
37
+ *
38
+ * `serving` is the probe result, passed in rather than measured here so the decision stays pure.
39
+ * When something is already answering we do not care which script exists: the rule is never to
40
+ * start a second server, because the one that is running may be the user's, with their state in it.
41
+ */
42
+ export declare function planDevScript(scripts: Readonly<Record<string, string>>, packageManager: string, serving: boolean): DevScriptPlan;
43
+ /**
44
+ * The command to print for this project, straight from its `package.json`.
45
+ *
46
+ * Lives here rather than in `run.ts` because it is the same judgement as `planDevScript` with the
47
+ * parsing attached, and `run.ts` is at its cohesion limit. Returns undefined for anything it cannot
48
+ * read: this phrasing decides nothing, so it must never be able to break an install.
49
+ */
50
+ export declare function devCommandFrom(pkg: unknown, packageManager: string): string | undefined;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Which command starts this project, and should we start it ourselves?
3
+ *
4
+ * `init` finishes by telling the human to start or restart their dev server, in a closing
5
+ * paragraph, in a terminal that is about to be cleared by the client restart it also asks for.
6
+ * That is the second unmarked hand-off in the install, after the capabilities file, and it lands
7
+ * on the same surface: prose nobody re-reads.
8
+ *
9
+ * Every fact needed to remove it is already in the project. `package.json` names the script; the
10
+ * framework tells us the conventional port; a probe tells us whether something already answers
11
+ * there. Nothing here needs a human.
12
+ *
13
+ * Kept as a PURE decision, separate from spawning, because the interesting part is the judgement —
14
+ * which script, and whether to touch anything at all — and that is what wants testing. Spawning a
15
+ * process is not.
16
+ */
17
+ /** Script names a JS project uses to run itself, in the order we would pick them. */
18
+ export const DEV_SCRIPT_NAMES = ['dev', 'start', 'serve'];
19
+ const CANDIDATES = DEV_SCRIPT_NAMES;
20
+ export const DevScriptChoice = {
21
+ /** Something already answers on the port. Use it; never replace a server the user is running. */
22
+ ALREADY_SERVING: 'already-serving',
23
+ /** We know the command and nothing is listening. Start it. */
24
+ START: 'start',
25
+ /** No script we recognise. Say so rather than guess a command. */
26
+ NO_SCRIPT: 'no-script',
27
+ };
28
+ /**
29
+ * Pick the script and decide whether to run it.
30
+ *
31
+ * `serving` is the probe result, passed in rather than measured here so the decision stays pure.
32
+ * When something is already answering we do not care which script exists: the rule is never to
33
+ * start a second server, because the one that is running may be the user's, with their state in it.
34
+ */
35
+ export function planDevScript(scripts, packageManager, serving) {
36
+ if (serving)
37
+ return { choice: DevScriptChoice.ALREADY_SERVING };
38
+ const name = CANDIDATES.find((c) => 'string' === typeof scripts[c] && scripts[c] !== '');
39
+ if (name === undefined)
40
+ return { choice: DevScriptChoice.NO_SCRIPT };
41
+ // `npm` needs `run`; the others take the script name directly. Getting this wrong prints a
42
+ // command that fails, which is worse than printing nothing.
43
+ const command = 'npm' === packageManager ? `npm run ${name}` : `${packageManager} ${name}`;
44
+ return { choice: DevScriptChoice.START, script: name, command };
45
+ }
46
+ /**
47
+ * The command to print for this project, straight from its `package.json`.
48
+ *
49
+ * Lives here rather than in `run.ts` because it is the same judgement as `planDevScript` with the
50
+ * parsing attached, and `run.ts` is at its cohesion limit. Returns undefined for anything it cannot
51
+ * read: this phrasing decides nothing, so it must never be able to break an install.
52
+ */
53
+ export function devCommandFrom(pkg, packageManager) {
54
+ try {
55
+ // Takes the PARSED manifest. It used to take the raw string and parse it a fourth time — the
56
+ // caller now reads the file once, through a guard, so there is one place a malformed manifest
57
+ // can be noticed and it is not this one.
58
+ const scripts = 'object' === typeof pkg && null !== pkg
59
+ ? (pkg.scripts ?? {})
60
+ : {};
61
+ return planDevScript(scripts, packageManager, false).command;
62
+ }
63
+ catch {
64
+ return undefined;
65
+ }
66
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Format a file `init` is about to write, using the project's own Prettier when it is installed.
3
+ *
4
+ * Reported from the field (#684): a clean CRA install failed the project's own lint because
5
+ * `src/reticle-dev.ts` was emitted as one long line. The project already had Prettier; init never
6
+ * asked it. Best-effort: resolve Prettier from the app (not from ours — we do not ship it), apply
7
+ * its config, and on any failure return the original content so init never fails because of a
8
+ * formatter. Sync only — `applyEffects` is sync, and Prettier 3's async `format` cannot join here.
9
+ */
10
+ /** True when this write is a connect/dev module lint will treat as project source. */
11
+ export declare function isGeneratedSourcePath(relPath: string): boolean;
12
+ /**
13
+ * Format `content` for `relPath` under `projectRoot`, or return it unchanged.
14
+ *
15
+ * Only the sync Prettier API is used. Prettier 3's async `format` is skipped (returns the original)
16
+ * rather than holding init open on a promise `applyEffects` cannot await.
17
+ */
18
+ export declare function formatGeneratedSource(content: string, relPath: string, projectRoot: string): string;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Format a file `init` is about to write, using the project's own Prettier when it is installed.
3
+ *
4
+ * Reported from the field (#684): a clean CRA install failed the project's own lint because
5
+ * `src/reticle-dev.ts` was emitted as one long line. The project already had Prettier; init never
6
+ * asked it. Best-effort: resolve Prettier from the app (not from ours — we do not ship it), apply
7
+ * its config, and on any failure return the original content so init never fails because of a
8
+ * formatter. Sync only — `applyEffects` is sync, and Prettier 3's async `format` cannot join here.
9
+ */
10
+ import { createRequire } from 'node:module';
11
+ import { basename, join } from 'node:path';
12
+ /** Basenames of full-file generators that a project's lint will see. */
13
+ const GENERATED_SOURCE_NAMES = new Set(['reticle-dev.ts', 'reticle-dev.tsx', 'hooks.client.ts']);
14
+ /** True when this write is a connect/dev module lint will treat as project source. */
15
+ export function isGeneratedSourcePath(relPath) {
16
+ return GENERATED_SOURCE_NAMES.has(basename(relPath));
17
+ }
18
+ /**
19
+ * Format `content` for `relPath` under `projectRoot`, or return it unchanged.
20
+ *
21
+ * Only the sync Prettier API is used. Prettier 3's async `format` is skipped (returns the original)
22
+ * rather than holding init open on a promise `applyEffects` cannot await.
23
+ */
24
+ export function formatGeneratedSource(content, relPath, projectRoot) {
25
+ if (!isGeneratedSourcePath(relPath))
26
+ return content;
27
+ try {
28
+ const require = createRequire(join(projectRoot, 'package.json'));
29
+ const prettier = require('prettier');
30
+ const filePath = join(projectRoot, relPath);
31
+ const resolved = prettier.resolveConfig.sync?.(filePath) ?? {};
32
+ const formatted = prettier.format(content, { ...resolved, filepath: filePath });
33
+ // Prettier 2 returns a string; Prettier 3 returns a Promise we cannot join from sync code.
34
+ return 'string' === typeof formatted ? formatted : content;
35
+ }
36
+ catch {
37
+ return content;
38
+ }
39
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * What to say when the dependency install fails.
3
+ *
4
+ * Split out of plan.ts, which was at the 1000-line backstop. A cohesive unit rather than an
5
+ * arbitrary cut: it is prose about one step's failure modes, and the only thing it needs is which
6
+ * package manager was used.
7
+ */
8
+ import { PackageManager } from './detect.js';
9
+ export declare function installFailureHint(pm: PackageManager): string;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * What to say when the dependency install fails.
3
+ *
4
+ * Split out of plan.ts, which was at the 1000-line backstop. A cohesive unit rather than an
5
+ * arbitrary cut: it is prose about one step's failure modes, and the only thing it needs is which
6
+ * package manager was used.
7
+ */
8
+ import { PackageManager } from './detect.js';
9
+ /**
10
+ * Every package manager fetches, so every one of them can fail for a reason that is nothing to do
11
+ * with the project: offline, a proxy that blocks npmjs, a corporate mirror that is down.
12
+ *
13
+ * The hint used to name only version pinning and pnpm's maturity window. Both are real causes, and
14
+ * neither is that one — so a blocked registry sent the reader through their own dependency versions
15
+ * looking for a problem that was entirely about reachability.
16
+ */
17
+ const REGISTRY_HINT = 'If it could not reach the registry at all (offline, a proxy, a mirror that is down), that is ' +
18
+ 'about reachability and not about this project: check `npm config get registry` and whether this ' +
19
+ 'machine can reach it.';
20
+ export function installFailureHint(pm) {
21
+ if (pm !== PackageManager.PNPM) {
22
+ return `If the version was refused, install the SDK yourself. ${REGISTRY_HINT}`;
23
+ }
24
+ return ('If pnpm reported ERR_PNPM_NO_MATURE_MATCHING_VERSION, its minimumReleaseAge setting is holding ' +
25
+ 'this release back. Either wait out the window, or allow these packages explicitly:\n' +
26
+ ' pnpm config set minimumReleaseAgeExclude "@reticlehq/*"\n' +
27
+ 'Do NOT drop the version pin — unpinned, pnpm installs an older SDK against a newer daemon, and ' +
28
+ `that mismatch surfaces as a -32000 with nothing naming a version.\n${REGISTRY_HINT}`);
29
+ }
@@ -78,5 +78,12 @@ export declare function clientSnippet(spec: ClientSpec): string;
78
78
  * because a fresh Cursor profile has not written `~/.cursor` yet.
79
79
  */
80
80
  export declare function clientMarkerRelPath(spec: ClientSpec): string;
81
+ /**
82
+ * Project-relative directory whose presence signals Cursor is in use for this repo.
83
+ *
84
+ * A fresh Cursor profile has not written `~/.cursor` yet, so the home marker alone misses real
85
+ * users. A project-level `.cursor/` is unambiguous evidence somebody uses Cursor here.
86
+ */
87
+ export declare const CURSOR_PROJECT_MARKER = ".cursor";
81
88
  /** Clients `init` can wire by writing a file — everything but the CLI-registered one. */
82
89
  export declare function fileBackedClients(): readonly ClientSpec[];
@@ -286,6 +286,13 @@ export function clientMarkerRelPath(spec) {
286
286
  const parts = spec.relPath.split('/');
287
287
  return parts.length > 1 ? parts.slice(0, -1).join('/') : spec.relPath;
288
288
  }
289
+ /**
290
+ * Project-relative directory whose presence signals Cursor is in use for this repo.
291
+ *
292
+ * A fresh Cursor profile has not written `~/.cursor` yet, so the home marker alone misses real
293
+ * users. A project-level `.cursor/` is unambiguous evidence somebody uses Cursor here.
294
+ */
295
+ export const CURSOR_PROJECT_MARKER = '.cursor';
289
296
  /** Clients `init` can wire by writing a file — everything but the CLI-registered one. */
290
297
  export function fileBackedClients() {
291
298
  return MCP_CLIENTS.filter((spec) => spec.scope !== ConfigScope.CLI);
@@ -15,11 +15,16 @@ export { MCP_SERVER_NAME } from '@reticlehq/core';
15
15
  /**
16
16
  * The registered command is STILL bare `npx` on every platform, deliberately.
17
17
  *
18
- * Windows is 66% of Reticle's users (65 of 99 in a day of telemetry) and has NO CI, no fixture, and
19
- * nothing in this repo has ever run there. Switching the majority platform to a launch command
20
- * nobody can test — where `.cmd` also has its own spawn caveats in some hosts — risks breaking the
21
- * users it is meant to help. So the fallback is DOCUMENTED (see mcpManual) rather than defaulted,
22
- * until somebody can run it on Windows.
18
+ * Windows is most of Reticle's users and, when this was written, had no CI. There is Windows CI
19
+ * now, so the `cmd /c` fallback is testable. Defaulting the majority platform to that launch
20
+ * command is still the riskier change: `.cmd` has spawn caveats in some hosts, and a registration
21
+ * that works on the machines we can test can still fail in the hosts we cannot. So the fallback
22
+ * stays documented rather than defaulted.
23
+ *
24
+ * What DID change is when it is printed. `mcpManual` used to run only when the `claude` CLI was
25
+ * absent. The reported Windows install had `claude mcp add` succeed, so the one paragraph that
26
+ * would have unblocked zero tools never appeared. `mcpWindowsNote` is that paragraph, and init
27
+ * prints it on every Windows run — including the ones that look like a clean registration.
23
28
  */
24
29
  export declare const NPX = "npx";
25
30
  /**
@@ -38,7 +43,7 @@ export declare const NPX = "npx";
38
43
  *
39
44
  * So it stays unpinned, and the skew is handled where it actually shows up: the contract fingerprint
40
45
  * makes a real mismatch loud on the next tool result (see version-skew), and a stale entry of our own
41
- * shape is now repaired on re-run rather than reported "already registered" (see cursor.ts).
46
+ * shape is now repaired on re-run rather than reported "already registered" (see mcp-clients.ts).
42
47
  */
43
48
  export declare function npxServerArgs(): string[];
44
49
  /**
@@ -74,5 +79,11 @@ export declare function claudeAvailableProbe(): {
74
79
  command: string;
75
80
  args: string[];
76
81
  };
82
+ /**
83
+ * The Windows `cmd /c npx` registration. Printed on every Windows init, not only when the `claude`
84
+ * CLI is missing — a successful `claude mcp add` of bare `npx` is exactly the failure that reported
85
+ * as a clean install with zero tools.
86
+ */
87
+ export declare function mcpWindowsNote(): string;
77
88
  /** Printed when the `claude` CLI isn't available — register Reticle globally once, by hand. */
78
89
  export declare function mcpManual(): string;
package/dist/init/mcp.js CHANGED
@@ -19,11 +19,16 @@ import { MCP_SERVER_NAME } from '@reticlehq/core';
19
19
  /**
20
20
  * The registered command is STILL bare `npx` on every platform, deliberately.
21
21
  *
22
- * Windows is 66% of Reticle's users (65 of 99 in a day of telemetry) and has NO CI, no fixture, and
23
- * nothing in this repo has ever run there. Switching the majority platform to a launch command
24
- * nobody can test — where `.cmd` also has its own spawn caveats in some hosts — risks breaking the
25
- * users it is meant to help. So the fallback is DOCUMENTED (see mcpManual) rather than defaulted,
26
- * until somebody can run it on Windows.
22
+ * Windows is most of Reticle's users and, when this was written, had no CI. There is Windows CI
23
+ * now, so the `cmd /c` fallback is testable. Defaulting the majority platform to that launch
24
+ * command is still the riskier change: `.cmd` has spawn caveats in some hosts, and a registration
25
+ * that works on the machines we can test can still fail in the hosts we cannot. So the fallback
26
+ * stays documented rather than defaulted.
27
+ *
28
+ * What DID change is when it is printed. `mcpManual` used to run only when the `claude` CLI was
29
+ * absent. The reported Windows install had `claude mcp add` succeed, so the one paragraph that
30
+ * would have unblocked zero tools never appeared. `mcpWindowsNote` is that paragraph, and init
31
+ * prints it on every Windows run — including the ones that look like a clean registration.
27
32
  */
28
33
  export const NPX = 'npx';
29
34
  // The `reticle` bin lives in the server package, so `npx <pkg> mcp` runs the bridge without the
@@ -31,6 +36,9 @@ export const NPX = 'npx';
31
36
  const RETICLE_PACKAGE = RETICLE_NPM_PACKAGE;
32
37
  const MCP_SUBCOMMAND = 'mcp';
33
38
  const CLAUDE_CLI = 'claude';
39
+ /** Windows `cmd /c` — the spawn that PowerShell's execution policy does not gate. */
40
+ const WINDOWS_SHELL = 'cmd';
41
+ const WINDOWS_SHELL_C = '/c';
34
42
  /**
35
43
  * Args after `npx` that launch the bridge: `@reticlehq/server mcp`. Portless — the port comes from
36
44
  * the project's `.reticle.json` at runtime, so one global entry works for every project.
@@ -47,7 +55,7 @@ const CLAUDE_CLI = 'claude';
47
55
  *
48
56
  * So it stays unpinned, and the skew is handled where it actually shows up: the contract fingerprint
49
57
  * makes a real mismatch loud on the next tool result (see version-skew), and a stale entry of our own
50
- * shape is now repaired on re-run rather than reported "already registered" (see cursor.ts).
58
+ * shape is now repaired on re-run rather than reported "already registered" (see mcp-clients.ts).
51
59
  */
52
60
  export function npxServerArgs() {
53
61
  return [RETICLE_PACKAGE, MCP_SUBCOMMAND];
@@ -94,6 +102,18 @@ export function claudeExistsProbe() {
94
102
  export function claudeAvailableProbe() {
95
103
  return { command: CLAUDE_CLI, args: ['--version'] };
96
104
  }
105
+ /**
106
+ * The Windows `cmd /c npx` registration. Printed on every Windows init, not only when the `claude`
107
+ * CLI is missing — a successful `claude mcp add` of bare `npx` is exactly the failure that reported
108
+ * as a clean install with zero tools.
109
+ */
110
+ export function mcpWindowsNote() {
111
+ return `On Windows, if the agent cannot start Reticle because npx is blocked ("running scripts is disabled
112
+ on this system" — a PowerShell execution policy), register it through cmd instead, which that policy
113
+ does not gate:
114
+
115
+ "${MCP_SERVER_NAME}": { "command": "${WINDOWS_SHELL}", "args": ${JSON.stringify([WINDOWS_SHELL_C, NPX, ...serverInvocation().slice(1)])} }`;
116
+ }
97
117
  /** Printed when the `claude` CLI isn't available — register Reticle globally once, by hand. */
98
118
  export function mcpManual() {
99
119
  const tail = serverInvocation().join(' ');
@@ -105,9 +125,5 @@ Or, for another agent, add this to its global MCP config (e.g. Cursor's ~/.curso
105
125
 
106
126
  "${MCP_SERVER_NAME}": { "command": "${NPX}", "args": ${JSON.stringify(serverInvocation().slice(1))} }
107
127
 
108
- On Windows, if the agent cannot start Reticle because npx is blocked ("running scripts is disabled
109
- on this system" — a PowerShell execution policy), register it through cmd instead, which that policy
110
- does not gate:
111
-
112
- "${MCP_SERVER_NAME}": { "command": "cmd", "args": ${JSON.stringify(['/c', NPX, ...serverInvocation().slice(1)])} }`;
128
+ ${mcpWindowsNote()}`;
113
129
  }
@@ -3,7 +3,7 @@
3
3
  * `runInit` stays testable with an in-memory IO. Prints to stdout — `init` is a one-shot CLI
4
4
  * command, not the MCP stdio transport.
5
5
  */
6
- import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';
6
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, accessSync, constants, } from 'node:fs';
7
7
  import { NodePlatform } from '../platform.js';
8
8
  import { join, dirname, isAbsolute } from 'node:path';
9
9
  import { homedir } from 'node:os';
@@ -95,6 +95,16 @@ export function buildNodeIo(cwd) {
95
95
  const result = spawnSync(command, shellSafe(args), { cwd, stdio: 'inherit', ...shellOpt() });
96
96
  return 0 === result.status;
97
97
  },
98
+ /** One access check, rather than discovering it as an EACCES stack four phases later. */
99
+ canWrite() {
100
+ try {
101
+ accessSync(cwd, constants.W_OK);
102
+ return true;
103
+ }
104
+ catch {
105
+ return false;
106
+ }
107
+ },
98
108
  probe(command, args) {
99
109
  // Quiet yes/no check (CLI availability, existing registration). Never throws.
100
110
  const result = spawnSync(command, shellSafe(args), { cwd, stdio: 'ignore', ...shellOpt() });
@@ -17,11 +17,6 @@ export declare const VITE_PLUGIN_DETAIL: {
17
17
  readonly SVELTEKIT: "add reticle() to plugins (stamps data-reticle-source in .svelte components)";
18
18
  };
19
19
  export declare function viteSteps(input: PlanInput, detail?: string): Step[];
20
- /**
21
- * Next used to be the ONLY stack with hand edits left over — and both of them fail silently when
22
- * skipped, so a Next user's app booted, connected to nothing, and said nothing about why. Both are
23
- * now patched by the same conservative rules the Vite config gets.
24
- */
25
20
  export declare function nextSteps(input: PlanInput): Step[];
26
21
  /**
27
22
  * SvelteKit is WIRED but not SUPPORTED, and the plan says so out loud.