@reticlehq/server 2.13.1 → 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 (449) 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/drive-agent.d.ts +2 -3
  233. package/dist/setup/drive-agent.js +1 -1
  234. package/dist/setup/drive-plan.d.ts +3 -2
  235. package/dist/setup/ensure-daemon.d.ts +2 -1
  236. package/dist/setup/existing-app.d.ts +12 -0
  237. package/dist/setup/existing-app.js +13 -0
  238. package/dist/setup/init-host.d.ts +11 -0
  239. package/dist/setup/init-host.js +26 -0
  240. package/dist/setup/init-runtime.d.ts +4 -10
  241. package/dist/setup/init-runtime.js +23 -16
  242. package/dist/setup/license-key.d.ts +2 -1
  243. package/dist/setup/listeners.d.ts +2 -1
  244. package/dist/setup/loopback-probe-urls.d.ts +18 -0
  245. package/dist/setup/loopback-probe-urls.js +52 -0
  246. package/dist/setup/node-effects.d.ts +3 -0
  247. package/dist/setup/node-effects.js +26 -11
  248. package/dist/setup/page-probe.d.ts +5 -0
  249. package/dist/setup/relaunch.d.ts +2 -1
  250. package/dist/setup/run-setup.d.ts +5 -1
  251. package/dist/setup/run-setup.js +141 -50
  252. package/dist/setup/setup-command.d.ts +3 -2
  253. package/dist/setup/setup-command.js +8 -0
  254. package/dist/setup/setup-options.d.ts +5 -3
  255. package/dist/setup/setup-options.js +3 -2
  256. package/dist/setup/wait-progress.d.ts +28 -0
  257. package/dist/setup/wait-progress.js +43 -0
  258. package/dist/telemetry/app-instrumented.d.ts +2 -1
  259. package/dist/telemetry/app-instrumented.js +1 -1
  260. package/dist/telemetry/automation-hint.d.ts +1 -1
  261. package/dist/telemetry/automation-hint.js +1 -1
  262. package/dist/telemetry/cli-telemetry.js +1 -1
  263. package/dist/telemetry/connect-failure.d.ts +1 -1
  264. package/dist/telemetry/connect-failure.js +1 -1
  265. package/dist/telemetry/crash-cause.d.ts +3 -2
  266. package/dist/telemetry/crash-cause.js +1 -1
  267. package/dist/telemetry/daemon-telemetry.d.ts +3 -2
  268. package/dist/telemetry/daemon-telemetry.js +1 -1
  269. package/dist/telemetry/error-class.d.ts +3 -2
  270. package/dist/telemetry/error-class.js +1 -1
  271. package/dist/telemetry/feedback-cli.js +1 -1
  272. package/dist/telemetry/feedback-context.d.ts +3 -2
  273. package/dist/telemetry/feedback-context.js +5 -4
  274. package/dist/telemetry/feedback-local.d.ts +3 -2
  275. package/dist/telemetry/feedback.d.ts +4 -3
  276. package/dist/telemetry/feedback.js +1 -1
  277. package/dist/telemetry/git-facts.d.ts +2 -2
  278. package/dist/telemetry/git-facts.js +1 -1
  279. package/dist/telemetry/identify.d.ts +1 -1
  280. package/dist/telemetry/identify.js +1 -1
  281. package/dist/telemetry/init-telemetry.d.ts +2 -14
  282. package/dist/telemetry/init-telemetry.js +4 -13
  283. package/dist/telemetry/install-source.d.ts +7 -13
  284. package/dist/telemetry/install-source.js +7 -29
  285. package/dist/telemetry/license-activation.d.ts +3 -2
  286. package/dist/telemetry/license-activation.js +1 -1
  287. package/dist/telemetry/machine-snapshot.d.ts +1 -1
  288. package/dist/telemetry/mcp-connection.js +1 -1
  289. package/dist/telemetry/project-profile.d.ts +0 -14
  290. package/dist/telemetry/project-profile.js +1 -1
  291. package/dist/telemetry/proxy-telemetry.js +1 -1
  292. package/dist/telemetry/session-metrics.d.ts +1 -1
  293. package/dist/telemetry/session-metrics.js +1 -1
  294. package/dist/telemetry/telemetry.d.ts +1 -17
  295. package/dist/telemetry/telemetry.js +4 -4
  296. package/dist/telemetry/tool-refused.d.ts +1 -1
  297. package/dist/telemetry/tool-refused.js +1 -1
  298. package/dist/tools/act-observation.d.ts +3 -2
  299. package/dist/tools/act-preflight.js +8 -3
  300. package/dist/tools/act-target.d.ts +4 -0
  301. package/dist/tools/act-target.js +14 -5
  302. package/dist/tools/act-tools.d.ts +0 -2
  303. package/dist/tools/act-tools.js +45 -15
  304. package/dist/tools/assert-source.d.ts +30 -0
  305. package/dist/tools/assert-source.js +21 -0
  306. package/dist/tools/assert-verdict.d.ts +1 -1
  307. package/dist/tools/assert-verdict.js +14 -4
  308. package/dist/tools/browser-tools.js +28 -8
  309. package/dist/tools/complete-snapshot.d.ts +3 -2
  310. package/dist/tools/dynamic-tools.js +8 -0
  311. package/dist/tools/error-recovery.d.ts +10 -0
  312. package/dist/tools/error-recovery.js +23 -0
  313. package/dist/tools/feedback-tools.js +1 -1
  314. package/dist/tools/invoke-tool.js +2 -0
  315. package/dist/tools/lease-tools.d.ts +48 -20
  316. package/dist/tools/lease-tools.js +311 -76
  317. package/dist/tools/lineage-tools.d.ts +14 -0
  318. package/dist/tools/lineage-tools.js +64 -0
  319. package/dist/tools/merge-tools.js +1 -3
  320. package/dist/tools/navigate-arrival.d.ts +45 -1
  321. package/dist/tools/navigate-arrival.js +39 -6
  322. package/dist/tools/navigate-result.d.ts +8 -1
  323. package/dist/tools/navigate-result.js +14 -4
  324. package/dist/tools/numeric-bounds.d.ts +0 -11
  325. package/dist/tools/numeric-bounds.js +4 -4
  326. package/dist/tools/observe-tools.js +22 -26
  327. package/dist/tools/observed-nothing.d.ts +9 -0
  328. package/dist/tools/observed-nothing.js +2 -1
  329. package/dist/tools/read-tools.js +12 -17
  330. package/dist/tools/real-input-attempt.d.ts +14 -6
  331. package/dist/tools/real-input-attempt.js +75 -18
  332. package/dist/tools/reconcile-tools.js +2 -1
  333. package/dist/tools/reload-result.d.ts +6 -1
  334. package/dist/tools/reload-result.js +7 -2
  335. package/dist/tools/resolve-target.d.ts +7 -1
  336. package/dist/tools/resolve-target.js +72 -9
  337. package/dist/tools/settle-in-flight.d.ts +1 -1
  338. package/dist/tools/settle-in-flight.js +9 -2
  339. package/dist/tools/snapshot-delta.d.ts +24 -1
  340. package/dist/tools/snapshot-delta.js +66 -7
  341. package/dist/tools/tool-names.d.ts +1 -0
  342. package/dist/tools/tool-names.js +1 -0
  343. package/dist/tools/tool-surface.js +20 -2
  344. package/dist/tools/tools.js +120 -11
  345. package/dist/tools/verify-next-baton.d.ts +2 -1
  346. package/dist/update/sdk-sync.d.ts +1 -1
  347. package/dist/update/sdk-sync.js +1 -1
  348. package/dist/update/updater.js +1 -1
  349. package/dist/version/sdk-fix.d.ts +2 -1
  350. package/dist/version/version-skew.d.ts +0 -8
  351. package/dist/version/version-skew.js +1 -1
  352. package/docs/README.md +8 -6
  353. package/docs/actions.mdx +1 -1
  354. package/docs/agent-cheatsheet.md +4 -2
  355. package/docs/architecture.md +1 -1
  356. package/docs/cli/mcp.mdx +3 -1
  357. package/docs/cli/watch.mdx +1 -1
  358. package/docs/cli.mdx +1 -1
  359. package/docs/desktop.mdx +1 -1
  360. package/docs/docs.json +8 -3
  361. package/docs/faq.mdx +9 -0
  362. package/docs/first-drive.md +136 -0
  363. package/docs/frameworks.mdx +29 -7
  364. package/docs/gate-plan.md +2 -2
  365. package/docs/gates.md +19 -11
  366. package/docs/getting-started.md +7 -1
  367. package/docs/http-transport.md +164 -0
  368. package/docs/index.mdx +5 -3
  369. package/docs/install-manual.mdx +1 -1
  370. package/docs/packages/tauri.mdx +1 -1
  371. package/docs/packages.mdx +15 -3
  372. package/docs/platform-integration.md +1 -1
  373. package/docs/predicates.mdx +2 -0
  374. package/docs/system-map.md +2 -2
  375. package/docs/telemetry-contract.md +4 -4
  376. package/docs/telemetry-events.mdx +1 -1
  377. package/docs/telemetry.md +3 -3
  378. package/docs/tools-navigate.mdx +14 -6
  379. package/docs/usage.md +4 -4
  380. package/package.json +7 -4
  381. package/dist/init/agent-rules.d.ts +0 -116
  382. package/dist/init/agent-rules.js +0 -279
  383. package/dist/init/app-choice.d.ts +0 -20
  384. package/dist/init/app-choice.js +0 -25
  385. package/dist/init/astro-host.d.ts +0 -21
  386. package/dist/init/astro-host.js +0 -27
  387. package/dist/init/astro-patch.d.ts +0 -33
  388. package/dist/init/astro-patch.js +0 -300
  389. package/dist/init/capabilities.d.ts +0 -40
  390. package/dist/init/capabilities.js +0 -150
  391. package/dist/init/closing-hint.d.ts +0 -36
  392. package/dist/init/closing-hint.js +0 -120
  393. package/dist/init/connect-steps.d.ts +0 -2
  394. package/dist/init/connect-steps.js +0 -50
  395. package/dist/init/cra.d.ts +0 -79
  396. package/dist/init/cra.js +0 -178
  397. package/dist/init/csp-check.d.ts +0 -38
  398. package/dist/init/csp-check.js +0 -107
  399. package/dist/init/csp-doctor.d.ts +0 -32
  400. package/dist/init/csp-doctor.js +0 -54
  401. package/dist/init/desktop-doctor.d.ts +0 -41
  402. package/dist/init/desktop-doctor.js +0 -198
  403. package/dist/init/detect.d.ts +0 -96
  404. package/dist/init/detect.js +0 -209
  405. package/dist/init/dev-script.d.ts +0 -50
  406. package/dist/init/dev-script.js +0 -66
  407. package/dist/init/format-generated.d.ts +0 -18
  408. package/dist/init/format-generated.js +0 -39
  409. package/dist/init/install-hint.d.ts +0 -9
  410. package/dist/init/install-hint.js +0 -29
  411. package/dist/init/mcp-clients.d.ts +0 -89
  412. package/dist/init/mcp-clients.js +0 -299
  413. package/dist/init/mcp-registered.d.ts +0 -12
  414. package/dist/init/mcp-registered.js +0 -14
  415. package/dist/init/mcp.d.ts +0 -89
  416. package/dist/init/mcp.js +0 -129
  417. package/dist/init/next-patch.d.ts +0 -39
  418. package/dist/init/next-patch.js +0 -196
  419. package/dist/init/node-io.d.ts +0 -7
  420. package/dist/init/node-io.js +0 -117
  421. package/dist/init/non-js-project.d.ts +0 -27
  422. package/dist/init/non-js-project.js +0 -84
  423. package/dist/init/patch-kind.d.ts +0 -20
  424. package/dist/init/patch-kind.js +0 -10
  425. package/dist/init/plan-framework.d.ts +0 -64
  426. package/dist/init/plan-framework.js +0 -565
  427. package/dist/init/plan.d.ts +0 -242
  428. package/dist/init/plan.js +0 -703
  429. package/dist/init/preflight.d.ts +0 -28
  430. package/dist/init/preflight.js +0 -38
  431. package/dist/init/project-id.d.ts +0 -12
  432. package/dist/init/project-id.js +0 -25
  433. package/dist/init/refresh-rules.d.ts +0 -39
  434. package/dist/init/refresh-rules.js +0 -51
  435. package/dist/init/run.d.ts +0 -117
  436. package/dist/init/run.js +0 -806
  437. package/dist/init/slash-command.d.ts +0 -27
  438. package/dist/init/slash-command.js +0 -132
  439. package/dist/init/snippets.d.ts +0 -134
  440. package/dist/init/snippets.js +0 -572
  441. package/dist/init/vite-config.d.ts +0 -18
  442. package/dist/init/vite-config.js +0 -114
  443. package/dist/init/windows-quote.d.ts +0 -38
  444. package/dist/init/windows-quote.js +0 -70
  445. package/dist/init/workspace-apps.d.ts +0 -30
  446. package/dist/init/workspace-apps.js +0 -178
  447. package/dist/project/remember-project.d.ts +0 -24
  448. package/dist/project/remember-project.js +0 -40
  449. /package/dist/{init → setup}/confirm.d.ts +0 -0
package/dist/init/mcp.js DELETED
@@ -1,129 +0,0 @@
1
- /**
2
- * Global (user-scope) MCP registration for `reticle init`. The bridge + MCP server is a single
3
- * process that serves every project, so it is registered ONCE at user scope — not per-project via
4
- * a checked-in `.mcp.json`. We shell out to the official `claude mcp add -s user` CLI rather than
5
- * hand-editing `~/.claude.json` (a large stateful file). When the `claude` CLI is absent we print a
6
- * manual instruction instead.
7
- *
8
- * The registration is intentionally PORTLESS — `npx @reticlehq/server mcp`, never `--port N`. A single
9
- * global entry serves every project, so baking a port into it would pin every project to one port
10
- * and defeat per-project isolation. Instead `reticle mcp` resolves the port at runtime from the
11
- * project's `.reticle.json` in its CWD (see cli-port.ts). The port belongs to the project, not the
12
- * global agent config.
13
- */
14
- import { RETICLE_NPM_PACKAGE } from '../version/server-version.js';
15
- // The name is a wire identity and lives in the contract; re-exported here so the registration writers
16
- // below (and their tests) keep reading it from the module that USES it.
17
- export { MCP_SERVER_NAME } from '@reticlehq/core';
18
- import { MCP_SERVER_NAME } from '@reticlehq/core';
19
- /**
20
- * The registered command is STILL bare `npx` on every platform, deliberately.
21
- *
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.
32
- */
33
- export const NPX = 'npx';
34
- // The `reticle` bin lives in the server package, so `npx <pkg> mcp` runs the bridge without the
35
- // retired `core` umbrella. Sourced from the single derived identity so it can never drift.
36
- const RETICLE_PACKAGE = RETICLE_NPM_PACKAGE;
37
- const MCP_SUBCOMMAND = 'mcp';
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';
42
- /**
43
- * Args after `npx` that launch the bridge: `@reticlehq/server mcp`. Portless — the port comes from
44
- * the project's `.reticle.json` at runtime, so one global entry works for every project.
45
- *
46
- * DELIBERATELY UNPINNED, and the trade is worth stating. `reticle init` pins the SDK to the CLI's
47
- * exact version, so on release day the app can be on the new one while npx serves a cached older
48
- * build — a real skew, reported from the field. Pinning this entry would remove that window.
49
- *
50
- * It would also freeze the agent's MCP server at whatever version was installed the day `init` ran,
51
- * for as long as that entry survives — and `reticle update` upgrades the CLI, not a global agent
52
- * config. Reticle's biggest measured problem is fixes not reaching people (2.4.0 reached zero users
53
- * before its nudge existed), and a permanent pin makes that worse for every install, to close a
54
- * window that lasts until the next npx cache miss.
55
- *
56
- * So it stays unpinned, and the skew is handled where it actually shows up: the contract fingerprint
57
- * makes a real mismatch loud on the next tool result (see version-skew), and a stale entry of our own
58
- * shape is now repaired on re-run rather than reported "already registered" (see mcp-clients.ts).
59
- */
60
- export function npxServerArgs() {
61
- return [RETICLE_PACKAGE, MCP_SUBCOMMAND];
62
- }
63
- /** The npm scope every Reticle package shares — the marker of a registration we are entitled to fix. */
64
- const RETICLE_SCOPE = '@reticlehq/';
65
- /**
66
- * Is this existing registration one WE are responsible for?
67
- *
68
- * Deliberately the SCOPE and not the server package. An entry naming any `@reticlehq/*` package is
69
- * ours to repair — including one naming the WRONG package, which is the case this widened for:
70
- * `args: ["@reticlehq/core","mcp"]` was reported from the field, where `core` has no `mcp` bin, so
71
- * the client showed the server errored with zero tools while `init` reported it already wired and
72
- * left it alone on every re-run. Every `reticle_*` tool was blocked until a human edited that file.
73
- *
74
- * An entry that names no Reticle package at all — a local build, a wrapper script — is still someone
75
- * else's deliberate choice and is left exactly as it is.
76
- *
77
- * @param tokens every string in the entry's command + args, in any of the client shapes.
78
- */
79
- export function isReticleRegistration(tokens) {
80
- return tokens.includes(NPX) && tokens.some((t) => t.includes(RETICLE_SCOPE));
81
- }
82
- /** The full `npx …` invocation — the tail after `claude mcp add … --`. */
83
- function serverInvocation() {
84
- return [NPX, ...npxServerArgs()];
85
- }
86
- /** `claude mcp add reticle -s user -- npx @reticlehq/server mcp` — registers globally for all projects (portless). */
87
- export function claudeAddCommand() {
88
- const tail = serverInvocation();
89
- const args = [MCP_SUBCOMMAND, 'add', MCP_SERVER_NAME, '-s', 'user', '--', ...tail];
90
- return { command: CLAUDE_CLI, args, display: `${CLAUDE_CLI} ${args.join(' ')}` };
91
- }
92
- /** Probe args that tell us whether an `reticle` server already exists in any scope (exit 0 = exists). */
93
- export function claudeExistsProbe() {
94
- // NO `-s`: `claude mcp get` takes no options at all, so passing one exits 1 with "unknown option
95
- // '-s'" — the probe answered "not registered" on EVERY machine, init then ran `claude mcp add`,
96
- // which exits 1 with "already exists", and a re-run reported `[⚠] step failed` plus a manual
97
- // command that fails the same way. A false positive from a project-scoped entry costs one skipped
98
- // registration; the flag cost every re-run a failed step.
99
- return { command: CLAUDE_CLI, args: [MCP_SUBCOMMAND, 'get', MCP_SERVER_NAME] };
100
- }
101
- /** Probe args for whether the `claude` CLI is installed at all. */
102
- export function claudeAvailableProbe() {
103
- return { command: CLAUDE_CLI, args: ['--version'] };
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
- }
117
- /** Printed when the `claude` CLI isn't available — register Reticle globally once, by hand. */
118
- export function mcpManual() {
119
- const tail = serverInvocation().join(' ');
120
- return `Register the Reticle MCP server ONCE, globally (so every project gets it):
121
-
122
- ${CLAUDE_CLI} ${MCP_SUBCOMMAND} add ${MCP_SERVER_NAME} -s user -- ${tail}
123
-
124
- Or, for another agent, add this to its global MCP config (e.g. Cursor's ~/.cursor/mcp.json):
125
-
126
- "${MCP_SERVER_NAME}": { "command": "${NPX}", "args": ${JSON.stringify(serverInvocation().slice(1))} }
127
-
128
- ${mcpWindowsNote()}`;
129
- }
@@ -1,39 +0,0 @@
1
- /**
2
- * Pure, conservative patchers for the two files a Next app needed edited BY HAND: `next.config.*`
3
- * (wrap the export in `withReticle`) and `app/layout.tsx` (mount `<ReticleDev />`). Same contract as
4
- * the Vite patcher — recognise the obvious shape, bail to `manual` on anything ambiguous, never
5
- * half-edit. Leaving these manual is why Next connected 0% of the time: both edits are silent when
6
- * skipped, and one of them is JSX.
7
- */
8
- import { type SourcePatch } from './patch-kind.js';
9
- /** Where the generated connect component goes, and how the mount file should import it. */
10
- interface ReticleDevLocation {
11
- /** Project-relative path to write. */
12
- path: string;
13
- /** What the mount file (`app/layout.*` or `pages/_app.*`) should import. */
14
- importSpecifier: string;
15
- }
16
- /**
17
- * Decide where the connect component lives, from the file that will mount it.
18
- *
19
- * Two things this gets wrong if hardcoded, both of which broke real apps:
20
- *
21
- * - **Pages Router routes on presence.** EVERY file under `pages/` is a route, so a component
22
- * dropped there has no default export: `/reticle-dev` 500s and `next build` fails. It has to go
23
- * somewhere that is not a route directory. App Router routes on FILENAME (`page`/`layout`/
24
- * `route`), so an extra file beside the layout is inert and can stay there.
25
- * - **The extension is not cosmetic.** A `.tsx` file in a JavaScript project makes Next auto-install
26
- * TypeScript on the next `next dev` — and on Next 13 that takes its require-hook down with it, so
27
- * the dev server never starts. The install then looks like it broke the app, because it did.
28
- */
29
- export declare function reticleDevLocation(mountPath: string, typescript: boolean): ReticleDevLocation;
30
- export declare function patchNextConfig(source: string): SourcePatch;
31
- /**
32
- * Pages Router has no root layout to mount into — `app/layout.tsx` does not exist — so the connect
33
- * rides in `pages/_app` instead, wrapped in a fragment alongside the page. Without this, `init`
34
- * wrote `app/reticle-dev.tsx` into a directory the app does not have and nothing ever connected,
35
- * with no error to say so.
36
- */
37
- export declare function patchPagesApp(source: string, importSpecifier?: string): SourcePatch;
38
- export declare function patchRootLayout(source: string): SourcePatch;
39
- export {};
@@ -1,196 +0,0 @@
1
- /**
2
- * Pure, conservative patchers for the two files a Next app needed edited BY HAND: `next.config.*`
3
- * (wrap the export in `withReticle`) and `app/layout.tsx` (mount `<ReticleDev />`). Same contract as
4
- * the Vite patcher — recognise the obvious shape, bail to `manual` on anything ambiguous, never
5
- * half-edit. Leaving these manual is why Next connected 0% of the time: both edits are silent when
6
- * skipped, and one of them is JSX.
7
- */
8
- import { PatchKind } from './patch-kind.js';
9
- const RETICLE_NEXT_PACKAGE = '@reticlehq/next';
10
- const NEXT_CONFIG_IMPORT = `import { withReticle } from '${RETICLE_NEXT_PACKAGE}';`;
11
- const NEXT_CONFIG_REQUIRE = `const { withReticle } = require('${RETICLE_NEXT_PACKAGE}');`;
12
- const RETICLE_DEV_COMPONENT = 'ReticleDev';
13
- const RETICLE_DEV_BASENAME = 'reticle-dev';
14
- /** Default import specifier: the component sits beside the file importing it (App Router). */
15
- const RETICLE_DEV_SIBLING = `./${RETICLE_DEV_BASENAME}`;
16
- const reticleDevImport = (specifier) => `import { ${RETICLE_DEV_COMPONENT} } from '${specifier}';`;
17
- const RETICLE_DEV_IMPORT = reticleDevImport(RETICLE_DEV_SIBLING);
18
- /**
19
- * Decide where the connect component lives, from the file that will mount it.
20
- *
21
- * Two things this gets wrong if hardcoded, both of which broke real apps:
22
- *
23
- * - **Pages Router routes on presence.** EVERY file under `pages/` is a route, so a component
24
- * dropped there has no default export: `/reticle-dev` 500s and `next build` fails. It has to go
25
- * somewhere that is not a route directory. App Router routes on FILENAME (`page`/`layout`/
26
- * `route`), so an extra file beside the layout is inert and can stay there.
27
- * - **The extension is not cosmetic.** A `.tsx` file in a JavaScript project makes Next auto-install
28
- * TypeScript on the next `next dev` — and on Next 13 that takes its require-hook down with it, so
29
- * the dev server never starts. The install then looks like it broke the app, because it did.
30
- */
31
- export function reticleDevLocation(mountPath, typescript) {
32
- const ext = typescript ? '.tsx' : '.jsx';
33
- const slash = mountPath.lastIndexOf('/');
34
- const dir = -1 === slash ? '' : mountPath.slice(0, slash);
35
- const isPagesRouter = /(^|\/)pages$/.test(dir);
36
- if (!isPagesRouter) {
37
- return {
38
- path: `${'' === dir ? '' : `${dir}/`}${RETICLE_DEV_BASENAME}${ext}`,
39
- importSpecifier: RETICLE_DEV_SIBLING,
40
- };
41
- }
42
- // Siblings of `pages/`, so `src/pages/_app.js` → `src/components/…` and `pages/_app.js` → `components/…`.
43
- const parent = dir.slice(0, Math.max(0, dir.length - 'pages'.length));
44
- return {
45
- path: `${parent}components/${RETICLE_DEV_BASENAME}${ext}`,
46
- importSpecifier: `../components/${RETICLE_DEV_BASENAME}`,
47
- };
48
- }
49
- /** The dev-guarded mount. Production strips it — `process.env.NODE_ENV` is inlined at build time. */
50
- const RETICLE_DEV_MOUNT = `{process.env.NODE_ENV === 'development' ? <${RETICLE_DEV_COMPONENT} /> : null}`;
51
- /**
52
- * `export default ` / `module.exports = ` at the START of a line — the head of the assignment, not
53
- * the whole statement. Where the exported expression ENDS is decided by `expressionEnd` below.
54
- *
55
- * These used to be `/…([\s\S]+?);?\s*$/`, which reads as "the expression, lazily". It is not: with
56
- * no `m` flag the `$` is end-of-FILE and the trailing `;?\s*` is satisfiable only there, so the
57
- * capture always ran to the last non-blank character of the file. Every config whose export was not
58
- * the final statement got everything after it swallowed into the wrap. On a config exporting
59
- * conditionally that produced an unbalanced paren — a syntax error, so `next dev` exited 1 while
60
- * `init` reported the step as ✓ and the only symptom was "dev server never served".
61
- */
62
- const ESM_DEFAULT_HEAD = /^[ \t]*export[ \t]+default[ \t]+/gm;
63
- const CJS_EXPORT_HEAD = /^[ \t]*module\.exports[ \t]*=[ \t]*/gm;
64
- /** The opening `<body ...>` tag, whose first child is where the mount goes. */
65
- const BODY_OPEN_TAG = /<body(\s[^>]*)?>/g;
66
- const NO_EXPORT_REASON = "couldn't find an `export default` or `module.exports` to wrap";
67
- const NO_BODY_REASON = "couldn't find a single <body> tag to mount <ReticleDev /> inside";
68
- /** Bracket pairs that keep an expression open. A `;` at depth 0 is what ends it. */
69
- const OPENERS = '([{';
70
- const CLOSERS = ')]}';
71
- const LINE_COMMENT = '//';
72
- const BLOCK_COMMENT_OPEN = '/*';
73
- const BLOCK_COMMENT_CLOSE = '*/';
74
- const QUOTES = '\'"`';
75
- /**
76
- * Index just past the exported expression that starts at `from` — the `;` that closes it, or end of
77
- * file. Tracks bracket depth so a multi-line object or a nested call ends in the right place, and
78
- * skips strings and comments so a `;` or a brace inside one cannot end it early.
79
- *
80
- * Deliberately a scanner and not a parser: `next.config.*` is arbitrary JS and this file's contract
81
- * is to recognise the obvious shape or bail. It only has to be right about where ONE expression
82
- * stops, and wrong is caught by the caller bailing to manual, never by a half-edit.
83
- */
84
- function expressionEnd(source, from) {
85
- let depth = 0;
86
- for (let i = from; i < source.length; i++) {
87
- const ch = source[i] ?? '';
88
- const pair = source.slice(i, i + 2);
89
- if (pair === LINE_COMMENT) {
90
- const nl = source.indexOf('\n', i);
91
- if (-1 === nl)
92
- return source.length;
93
- i = nl;
94
- continue;
95
- }
96
- if (pair === BLOCK_COMMENT_OPEN) {
97
- const close = source.indexOf(BLOCK_COMMENT_CLOSE, i + 2);
98
- i = -1 === close ? source.length : close + 1;
99
- continue;
100
- }
101
- if (QUOTES.includes(ch)) {
102
- for (i++; i < source.length; i++) {
103
- if ('\\' === source[i])
104
- i++;
105
- else if (source[i] === ch)
106
- break;
107
- }
108
- continue;
109
- }
110
- if (OPENERS.includes(ch))
111
- depth++;
112
- else if (CLOSERS.includes(ch)) {
113
- // A closer at depth 0 belongs to an enclosing block, so the expression ended before it.
114
- if (0 === depth)
115
- return i;
116
- depth--;
117
- }
118
- else if (';' === ch && 0 === depth)
119
- return i;
120
- }
121
- return source.length;
122
- }
123
- /** Every top-level export assignment in the file, in source order. */
124
- function exportSites(source, head) {
125
- const sites = [];
126
- for (const match of source.matchAll(head)) {
127
- if (match.index === undefined)
128
- continue;
129
- const start = match.index + match[0].length;
130
- sites.push({ start, end: expressionEnd(source, start) });
131
- }
132
- return sites;
133
- }
134
- /**
135
- * Wrap every listed expression in `withReticle(...)`, leaving every other byte of the file alone.
136
- *
137
- * All of them, not just the first: a config can export CONDITIONALLY — Sentry-wrapped in one branch,
138
- * plain in the other — and which branch runs is an environment variable's business, not ours.
139
- * Wrapping each assignment is correct whichever one executes, and it is what turns that shape from a
140
- * manual step (an app that boots and never connects) into a working install.
141
- *
142
- * Applied back-to-front so each splice leaves the earlier offsets valid.
143
- */
144
- function wrapAll(source, sites) {
145
- let out = source;
146
- for (const site of [...sites].sort((a, b) => b.start - a.start)) {
147
- out = `${out.slice(0, site.start)}withReticle(${out.slice(site.start, site.end)})${out.slice(site.end)}`;
148
- }
149
- return out;
150
- }
151
- export function patchNextConfig(source) {
152
- if (source.includes(RETICLE_NEXT_PACKAGE))
153
- return { kind: PatchKind.ALREADY };
154
- const esm = exportSites(source, ESM_DEFAULT_HEAD);
155
- if (esm.length > 0) {
156
- return { kind: PatchKind.APPLY, code: `${NEXT_CONFIG_IMPORT}\n${wrapAll(source, esm)}` };
157
- }
158
- const cjs = exportSites(source, CJS_EXPORT_HEAD);
159
- if (cjs.length > 0) {
160
- return { kind: PatchKind.APPLY, code: `${NEXT_CONFIG_REQUIRE}\n${wrapAll(source, cjs)}` };
161
- }
162
- return { kind: PatchKind.MANUAL, reason: NO_EXPORT_REASON };
163
- }
164
- /** `<Component {...pageProps} />` — the one element every `pages/_app` renders. */
165
- const PAGES_APP_COMPONENT = /<Component\b[^>]*\/>/g;
166
- const NO_PAGES_COMPONENT_REASON = "couldn't find a single <Component {...pageProps} /> to wrap in pages/_app";
167
- /**
168
- * Pages Router has no root layout to mount into — `app/layout.tsx` does not exist — so the connect
169
- * rides in `pages/_app` instead, wrapped in a fragment alongside the page. Without this, `init`
170
- * wrote `app/reticle-dev.tsx` into a directory the app does not have and nothing ever connected,
171
- * with no error to say so.
172
- */
173
- export function patchPagesApp(source, importSpecifier = RETICLE_DEV_SIBLING) {
174
- if (source.includes(RETICLE_DEV_COMPONENT))
175
- return { kind: PatchKind.ALREADY };
176
- const matches = [...source.matchAll(PAGES_APP_COMPONENT)];
177
- const match = 1 === matches.length ? matches[0] : undefined;
178
- if (match?.index === undefined)
179
- return { kind: PatchKind.MANUAL, reason: NO_PAGES_COMPONENT_REASON };
180
- const wrapped = `<>${RETICLE_DEV_MOUNT}${match[0]}</>`;
181
- const code = source.slice(0, match.index) + wrapped + source.slice(match.index + match[0].length);
182
- return { kind: PatchKind.APPLY, code: `${reticleDevImport(importSpecifier)}\n${code}` };
183
- }
184
- export function patchRootLayout(source) {
185
- if (source.includes(RETICLE_DEV_COMPONENT))
186
- return { kind: PatchKind.ALREADY };
187
- const tags = [...source.matchAll(BODY_OPEN_TAG)];
188
- // Exactly one <body> or we cannot tell which one actually renders — and mounting into the wrong
189
- // one is the same silent no-connect as not mounting at all.
190
- const tag = 1 === tags.length ? tags[0] : undefined;
191
- if (tag?.index === undefined)
192
- return { kind: PatchKind.MANUAL, reason: NO_BODY_REASON };
193
- const insertAt = tag.index + tag[0].length;
194
- const mounted = `${source.slice(0, insertAt)}${RETICLE_DEV_MOUNT}${source.slice(insertAt)}`;
195
- return { kind: PatchKind.APPLY, code: `${RETICLE_DEV_IMPORT}\n${mounted}` };
196
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * The real (Node filesystem) implementation of `InitIo`. Kept separate from the pure runner so
3
- * `runInit` stays testable with an in-memory IO. Prints to stdout — `init` is a one-shot CLI
4
- * command, not the MCP stdio transport.
5
- */
6
- import type { InitIo } from './run.js';
7
- export declare function buildNodeIo(cwd: string): InitIo;
@@ -1,117 +0,0 @@
1
- /**
2
- * The real (Node filesystem) implementation of `InitIo`. Kept separate from the pure runner so
3
- * `runInit` stays testable with an in-memory IO. Prints to stdout — `init` is a one-shot CLI
4
- * command, not the MCP stdio transport.
5
- */
6
- import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, accessSync, constants, } from 'node:fs';
7
- import { NodePlatform } from '../platform.js';
8
- import { join, dirname, isAbsolute } from 'node:path';
9
- import { homedir } from 'node:os';
10
- import { spawnSync } from 'node:child_process';
11
- import { windowsShellArg } from './windows-quote.js';
12
- /**
13
- * `shell: true` ONLY where it earns its keep.
14
- *
15
- * It exists so package-manager shims (`pnpm.cmd`, `npx.cmd`) resolve on Windows. On POSIX it buys
16
- * nothing and costs correctness: under a shell, arguments are re-parsed, so a path containing a
17
- * space — `/Users/ada/My Projects/app` — silently becomes two arguments and registration fails with
18
- * no error anyone can read.
19
- */
20
- function shellOpt() {
21
- return NodePlatform.WINDOWS === process.platform ? { shell: true } : {};
22
- }
23
- /**
24
- * Under a shell, quote what the shell would otherwise split or interpret. Windows only, where
25
- * `shell: true` is required (see shellOpt). The rule itself lives in windows-quote.ts as a pure
26
- * function so it can be tested on every platform — keeping it inside this branch is why it was
27
- * wrong for as long as it was.
28
- */
29
- function shellSafe(args) {
30
- if (process.platform !== NodePlatform.WINDOWS)
31
- return [...args];
32
- return args.map(windowsShellArg);
33
- }
34
- export function buildNodeIo(cwd) {
35
- // Project-relative by default; absolute paths (e.g. ~/.cursor/mcp.json) pass through unchanged.
36
- const abs = (rel) => (isAbsolute(rel) ? rel : join(cwd, rel));
37
- return {
38
- readFile(rel) {
39
- const path = abs(rel);
40
- if (!existsSync(path))
41
- return null;
42
- return readFileSync(path, 'utf8');
43
- },
44
- writeFile(rel, content) {
45
- const path = abs(rel);
46
- mkdirSync(dirname(path), { recursive: true });
47
- writeFileSync(path, content, 'utf8');
48
- },
49
- exists(rel) {
50
- return existsSync(abs(rel));
51
- },
52
- homeDir() {
53
- return homedir();
54
- },
55
- cwd() {
56
- return cwd;
57
- },
58
- rootFiles() {
59
- return readdirSync(cwd).filter((name) => {
60
- try {
61
- return statSync(join(cwd, name)).isFile();
62
- }
63
- catch {
64
- return false;
65
- }
66
- });
67
- },
68
- listDirs(rel) {
69
- const path = abs(rel);
70
- if (!existsSync(path))
71
- return [];
72
- try {
73
- return readdirSync(path).filter((name) => statSync(join(path, name)).isDirectory());
74
- }
75
- catch {
76
- return [];
77
- }
78
- },
79
- listFiles(rel) {
80
- const path = abs(rel);
81
- if (!existsSync(path))
82
- return [];
83
- try {
84
- return readdirSync(path).filter((name) => !statSync(join(path, name)).isDirectory());
85
- }
86
- catch {
87
- return [];
88
- }
89
- },
90
- scoped(rel) {
91
- return buildNodeIo(abs(rel));
92
- },
93
- exec(command, args) {
94
- // Inherit stdio so the install's own progress is visible to the user.
95
- const result = spawnSync(command, shellSafe(args), { cwd, stdio: 'inherit', ...shellOpt() });
96
- return 0 === result.status;
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
- },
108
- probe(command, args) {
109
- // Quiet yes/no check (CLI availability, existing registration). Never throws.
110
- const result = spawnSync(command, shellSafe(args), { cwd, stdio: 'ignore', ...shellOpt() });
111
- return 0 === result.status;
112
- },
113
- print(line) {
114
- process.stdout.write(`${line}\n`);
115
- },
116
- };
117
- }
@@ -1,27 +0,0 @@
1
- /**
2
- * Telling a Python (or Ruby, or Go, or PHP) developer why Reticle cannot wire their app.
3
- *
4
- * `reticle init` answered "No package.json found here, and no app directory beneath it either",
5
- * which reads as *you are in the wrong directory* — so an agent on a Streamlit app went looking for
6
- * a directory that does not exist, then went looking for a standalone browser bundle to inject by
7
- * hand, and only worked out the real answer several steps later.
8
- *
9
- * The real answer is not about directories at all: Reticle's SDK has to be imported by the app's own
10
- * JS build, and a server-rendered Python app has no JS build to import it from. That is a property
11
- * of the project, it is knowable from one look at the filesystem, and saying it plainly costs the
12
- * reader nothing while the directory message costs them the whole investigation.
13
- *
14
- * Deliberately a hint, not a refusal: a Django or Rails app with a `frontend/` package.json is a
15
- * perfectly ordinary Reticle install, and this only ever speaks when there is no package.json to be
16
- * found anywhere.
17
- */
18
- /** The ecosystem this directory looks like, or undefined when nothing says. */
19
- export declare function detectNonJsEcosystem(exists: (file: string) => boolean): string | undefined;
20
- /**
21
- * What `init` should say when there is no package.json.
22
- *
23
- * Two genuinely different situations behind one old sentence: a JS developer standing in the wrong
24
- * directory, and a developer whose project is not JavaScript at all. The first needs a path; the
25
- * second needs to know that no path exists and why.
26
- */
27
- export declare function noPackageJsonMessage(exists: (file: string) => boolean): string;
@@ -1,84 +0,0 @@
1
- /**
2
- * Telling a Python (or Ruby, or Go, or PHP) developer why Reticle cannot wire their app.
3
- *
4
- * `reticle init` answered "No package.json found here, and no app directory beneath it either",
5
- * which reads as *you are in the wrong directory* — so an agent on a Streamlit app went looking for
6
- * a directory that does not exist, then went looking for a standalone browser bundle to inject by
7
- * hand, and only worked out the real answer several steps later.
8
- *
9
- * The real answer is not about directories at all: Reticle's SDK has to be imported by the app's own
10
- * JS build, and a server-rendered Python app has no JS build to import it from. That is a property
11
- * of the project, it is knowable from one look at the filesystem, and saying it plainly costs the
12
- * reader nothing while the directory message costs them the whole investigation.
13
- *
14
- * Deliberately a hint, not a refusal: a Django or Rails app with a `frontend/` package.json is a
15
- * perfectly ordinary Reticle install, and this only ever speaks when there is no package.json to be
16
- * found anywhere.
17
- */
18
- /** Marker files that identify an ecosystem, and what to call it. */
19
- const ECOSYSTEM_MARKERS = [
20
- ['requirements.txt', 'Python'],
21
- ['pyproject.toml', 'Python'],
22
- ['Pipfile', 'Python'],
23
- ['setup.py', 'Python'],
24
- ['manage.py', 'Python (Django)'],
25
- ['Gemfile', 'Ruby'],
26
- ['go.mod', 'Go'],
27
- ['composer.json', 'PHP'],
28
- ['Cargo.toml', 'Rust'],
29
- ['pom.xml', 'Java'],
30
- ['build.gradle', 'Java'],
31
- ['mix.exs', 'Elixir'],
32
- // Not like the others. Every ecosystem above can grow a JS front end that Reticle instruments
33
- // perfectly well, so their message ends with a lead. Flutter web paints into a canvas, and there
34
- // is no DOM behind it at any path, so the honest answer is a named refusal.
35
- ['pubspec.yaml', 'Flutter'],
36
- ];
37
- /** The one ecosystem where no directory, front end or flag could ever help. */
38
- const FLUTTER = 'Flutter';
39
- /** The ecosystem this directory looks like, or undefined when nothing says. */
40
- export function detectNonJsEcosystem(exists) {
41
- for (const [marker, name] of ECOSYSTEM_MARKERS) {
42
- if (exists(marker))
43
- return name;
44
- }
45
- return undefined;
46
- }
47
- /**
48
- * What `init` should say when there is no package.json.
49
- *
50
- * Two genuinely different situations behind one old sentence: a JS developer standing in the wrong
51
- * directory, and a developer whose project is not JavaScript at all. The first needs a path; the
52
- * second needs to know that no path exists and why.
53
- */
54
- export function noPackageJsonMessage(exists) {
55
- const ecosystem = detectNonJsEcosystem(exists);
56
- if (ecosystem === undefined) {
57
- return ('No package.json found here, and no app directory beneath it either. Run `reticle init` from ' +
58
- "your app's directory, or from a repo root that contains it.");
59
- }
60
- if (ecosystem === FLUTTER) {
61
- // An agent on a Flutter workspace asked us to "support Flutter, or clearly identify it as
62
- // unsupported during init". The second is the truthful one, and saying it by name in one line
63
- // is the difference between an agent that stops and an agent that spends an hour looking for
64
- // the package.json we told it was missing.
65
- return ('This is a Flutter project. Reticle cannot instrument it, and no directory or flag will ' +
66
- 'change that: Reticle reads the DOM of a running page, and Flutter web paints its entire UI ' +
67
- 'into a single canvas element with no DOM behind it. Nothing here is missing or misconfigured. ' +
68
- 'If this repo also contains an ordinary web app with its own package.json, run `reticle init` ' +
69
- 'inside that directory instead.');
70
- }
71
- return (`This looks like a ${ecosystem} project, and there is no package.json here or in any app ` +
72
- 'directory beneath it. That is not a blocker: Reticle needs its SDK loaded by the page, not ' +
73
- 'built by npm, and a page with no build step can load it from a URL. ' +
74
- // The old message ended at "there is no directory you could run this from that would change
75
- // that", which read as a refusal and was acted on as one — agents went looking for a bundler,
76
- // or for a standalone build to inject by hand, or gave up and used a different tool. The
77
- // capability was there the whole time; only the sentence was missing. Proven end to end on a
78
- // page served by `python3 -m http.server` before this line was written.
79
- 'Add the script-tag snippet below to a template you only serve in development, then reload the ' +
80
- 'page. ' +
81
- 'If this project ALSO has a JS front end (a `frontend/`, `client/` or `assets/` directory with ' +
82
- 'its own package.json), running `reticle init` there instead gives you source mapping and ' +
83
- 'framework state as well: point at it with `--app <dir>`.');
84
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * The outcome vocabulary shared by every conservative source patcher in `init` (Vite config, Next
3
- * config, Next root layout). One enum so a new patcher cannot invent a fourth status the reporter
4
- * has no symbol for.
5
- */
6
- export declare const PatchKind: {
7
- readonly APPLY: "apply";
8
- readonly ALREADY: "already";
9
- readonly MANUAL: "manual";
10
- };
11
- export type PatchKind = (typeof PatchKind)[keyof typeof PatchKind];
12
- export type SourcePatch = {
13
- kind: typeof PatchKind.APPLY;
14
- code: string;
15
- } | {
16
- kind: typeof PatchKind.ALREADY;
17
- } | {
18
- kind: typeof PatchKind.MANUAL;
19
- reason: string;
20
- };
@@ -1,10 +0,0 @@
1
- /**
2
- * The outcome vocabulary shared by every conservative source patcher in `init` (Vite config, Next
3
- * config, Next root layout). One enum so a new patcher cannot invent a fourth status the reporter
4
- * has no symbol for.
5
- */
6
- export const PatchKind = {
7
- APPLY: 'apply',
8
- ALREADY: 'already',
9
- MANUAL: 'manual',
10
- };