@reticlehq/server 2.4.0 → 2.6.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 (472) hide show
  1. package/SKILL.md +719 -0
  2. package/dist/bridge/auth-failure-reason.d.ts +19 -0
  3. package/dist/bridge/auth-failure-reason.js +29 -0
  4. package/dist/{bridge-security.d.ts → bridge/bridge-security.d.ts} +1 -1
  5. package/dist/{bridge-security.js → bridge/bridge-security.js} +1 -1
  6. package/dist/{bridge.d.ts → bridge/bridge.d.ts} +13 -1
  7. package/dist/{bridge.js → bridge/bridge.js} +95 -15
  8. package/dist/{bridge.test-harness.d.ts → bridge/bridge.test-harness.d.ts} +9 -11
  9. package/dist/{bridge.test-harness.js → bridge/bridge.test-harness.js} +18 -10
  10. package/dist/{pairing-token.js → bridge/pairing-token.js} +1 -1
  11. package/dist/capsule/capsule-store.d.ts +8 -3
  12. package/dist/capsule/capsule-store.js +7 -2
  13. package/dist/capsule/capsule.js +3 -3
  14. package/dist/capsule/causal-summary.d.ts +8 -0
  15. package/dist/capsule/causal-summary.js +22 -12
  16. package/dist/capsule/divergence.d.ts +9 -4
  17. package/dist/capsule/divergence.js +8 -8
  18. package/dist/capsule/predicate-to-links.js +11 -8
  19. package/dist/cli/cli-doctor.d.ts +1 -0
  20. package/dist/cli/cli-doctor.js +135 -0
  21. package/dist/{cli-flow-commands.d.ts → cli/cli-flow-commands.d.ts} +2 -2
  22. package/dist/{cli-flow-commands.js → cli/cli-flow-commands.js} +15 -15
  23. package/dist/{cli-launch.d.ts → cli/cli-launch.d.ts} +32 -3
  24. package/dist/cli/cli-launch.js +171 -0
  25. package/dist/cli/cli-parse-feedback.d.ts +31 -0
  26. package/dist/cli/cli-parse-feedback.js +56 -0
  27. package/dist/{cli-parse.d.ts → cli/cli-parse.d.ts} +6 -19
  28. package/dist/{cli-parse.js → cli/cli-parse.js} +118 -81
  29. package/dist/{cli-port.d.ts → cli/cli-port.d.ts} +12 -0
  30. package/dist/{cli-port.js → cli/cli-port.js} +9 -9
  31. package/dist/cli/cli-update-commands.d.ts +4 -0
  32. package/dist/cli/cli-update-commands.js +93 -0
  33. package/dist/{cli-verify.js → cli/cli-verify.js} +14 -14
  34. package/dist/{cloud-cli.js → cli/cloud-cli.js} +29 -24
  35. package/dist/cli/doctor-daemon-line.d.ts +37 -0
  36. package/dist/cli/doctor-daemon-line.js +35 -0
  37. package/dist/cli/port-holder.d.ts +43 -0
  38. package/dist/cli/port-holder.js +99 -0
  39. package/dist/cli.d.ts +2 -2
  40. package/dist/cli.js +302 -100
  41. package/dist/cloud/cloud-config.d.ts +0 -1
  42. package/dist/cloud/cloud-config.js +9 -9
  43. package/dist/cloud/cloud-sync.d.ts +1 -7
  44. package/dist/cloud/cloud-sync.js +12 -12
  45. package/dist/crawl/crawl-empty.d.ts +16 -0
  46. package/dist/crawl/crawl-empty.js +24 -0
  47. package/dist/crawl/crawl-tools.js +4 -1
  48. package/dist/crawl/crawl.js +26 -7
  49. package/dist/daemon/daemon-resilience.d.ts +73 -0
  50. package/dist/daemon/daemon-resilience.js +279 -0
  51. package/dist/daemon/daemon-usefulness.d.ts +61 -0
  52. package/dist/daemon/daemon-usefulness.js +62 -0
  53. package/dist/{daemon.d.ts → daemon/daemon.d.ts} +33 -8
  54. package/dist/{daemon.js → daemon/daemon.js} +105 -48
  55. package/dist/daemon/heartbeat.d.ts +115 -0
  56. package/dist/daemon/heartbeat.js +141 -0
  57. package/dist/daemon/idle-grace.d.ts +32 -0
  58. package/dist/daemon/idle-grace.js +41 -0
  59. package/dist/{idle-shutdown.d.ts → daemon/idle-shutdown.d.ts} +23 -2
  60. package/dist/{idle-shutdown.js → daemon/idle-shutdown.js} +37 -6
  61. package/dist/daemon/port-presence.d.ts +76 -0
  62. package/dist/daemon/port-presence.js +93 -0
  63. package/dist/daemon/state-dir.d.ts +7 -0
  64. package/dist/daemon/state-dir.js +59 -0
  65. package/dist/daemon/unclean-predecessor.d.ts +23 -0
  66. package/dist/daemon/unclean-predecessor.js +27 -0
  67. package/dist/domain/domain-model.js +2 -2
  68. package/dist/events/body-failures.js +8 -8
  69. package/dist/events/contradictions.d.ts +1 -1
  70. package/dist/events/contradictions.js +60 -10
  71. package/dist/events/echo-mismatch.js +10 -10
  72. package/dist/events/event-filters.js +6 -6
  73. package/dist/events/json-salvage.d.ts +2 -1
  74. package/dist/events/json-salvage.js +6 -6
  75. package/dist/events/observed-in-window.d.ts +12 -0
  76. package/dist/events/observed-in-window.js +21 -0
  77. package/dist/events/predicate-eval.d.ts +53 -20
  78. package/dist/events/predicate-eval.js +179 -55
  79. package/dist/events/predicate-parse.d.ts +23 -0
  80. package/dist/events/predicate-parse.js +54 -0
  81. package/dist/events/predicate.d.ts +7 -2
  82. package/dist/events/predicate.js +126 -35
  83. package/dist/events/reconcile.js +5 -5
  84. package/dist/events/ring-buffer.js +2 -17
  85. package/dist/events/stale-response.js +6 -6
  86. package/dist/events/testid-near-miss.d.ts +22 -0
  87. package/dist/events/testid-near-miss.js +33 -0
  88. package/dist/events/unit-mismatch.js +8 -8
  89. package/dist/flows/affected-tools.js +19 -4
  90. package/dist/flows/affected.js +1 -1
  91. package/dist/flows/annotate-target.d.ts +1 -0
  92. package/dist/flows/annotate-target.js +20 -0
  93. package/dist/flows/annotate-tools.js +25 -3
  94. package/dist/flows/annotate.js +17 -4
  95. package/dist/flows/assertion-integrity.d.ts +2 -1
  96. package/dist/flows/assertion-tiers-store.d.ts +3 -66
  97. package/dist/flows/assertion-tiers-store.js +2 -2
  98. package/dist/flows/attributed-failure.d.ts +17 -0
  99. package/dist/flows/attributed-failure.js +20 -0
  100. package/dist/flows/buddy-status.d.ts +2 -1
  101. package/dist/flows/buddy-status.js +2 -2
  102. package/dist/flows/coverage.d.ts +3 -2
  103. package/dist/flows/coverage.js +2 -2
  104. package/dist/flows/decision.js +24 -9
  105. package/dist/flows/empty-flow.d.ts +6 -0
  106. package/dist/flows/empty-flow.js +24 -0
  107. package/dist/flows/flake-store.d.ts +0 -1
  108. package/dist/flows/flake-store.js +1 -1
  109. package/dist/flows/flake.d.ts +2 -1
  110. package/dist/flows/flake.js +2 -2
  111. package/dist/flows/flow-classify.js +12 -0
  112. package/dist/flows/flow-replay-run.js +4 -4
  113. package/dist/flows/flow-replay.d.ts +6 -8
  114. package/dist/flows/flow-replay.js +132 -48
  115. package/dist/flows/flow-report.js +1 -1
  116. package/dist/flows/flow-scope.d.ts +1 -6
  117. package/dist/flows/flow-step-runners.d.ts +26 -6
  118. package/dist/flows/flow-step-runners.js +156 -6
  119. package/dist/flows/flow-success.js +20 -15
  120. package/dist/flows/flow-tools.js +63 -21
  121. package/dist/flows/flows.js +15 -11
  122. package/dist/flows/gate.d.ts +4 -3
  123. package/dist/flows/gate.js +1 -1
  124. package/dist/flows/heal-run.d.ts +0 -8
  125. package/dist/flows/heal-run.js +5 -5
  126. package/dist/flows/heal.js +3 -3
  127. package/dist/flows/predicate-to-expect.d.ts +38 -0
  128. package/dist/flows/predicate-to-expect.js +95 -0
  129. package/dist/flows/replay.d.ts +16 -1
  130. package/dist/flows/replay.js +58 -22
  131. package/dist/flows/role-anchor-nearest.d.ts +6 -0
  132. package/dist/flows/role-anchor-nearest.js +45 -0
  133. package/dist/flows/role-drift-reason.d.ts +20 -0
  134. package/dist/flows/role-drift-reason.js +39 -0
  135. package/dist/flows/server-verify.d.ts +1 -1
  136. package/dist/flows/server-verify.js +5 -5
  137. package/dist/flows/suite-flakes.d.ts +33 -0
  138. package/dist/flows/suite-flakes.js +32 -0
  139. package/dist/flows/verify-change-tools.js +32 -10
  140. package/dist/flows/verify-change-verdict.d.ts +15 -0
  141. package/dist/flows/verify-change-verdict.js +25 -0
  142. package/dist/flows/watch-batcher.d.ts +3 -2
  143. package/dist/honesty/already-true.d.ts +2 -0
  144. package/dist/honesty/already-true.js +31 -0
  145. package/dist/honesty/blind-spots.d.ts +35 -3
  146. package/dist/honesty/blind-spots.js +57 -12
  147. package/dist/honesty/honesty.d.ts +3 -2
  148. package/dist/honesty/honesty.js +4 -4
  149. package/dist/honesty/uncaptured-bodies.js +1 -1
  150. package/dist/honesty/unread-outcome.js +2 -2
  151. package/dist/honesty/verified.d.ts +31 -3
  152. package/dist/honesty/verified.js +64 -8
  153. package/dist/http-server.js +23 -7
  154. package/dist/hunt/hunt-report.d.ts +2 -1
  155. package/dist/hunt/hunt-report.js +2 -2
  156. package/dist/index.d.ts +9 -6
  157. package/dist/index.js +41 -25
  158. package/dist/init/agent-rules.d.ts +20 -1
  159. package/dist/init/agent-rules.js +64 -8
  160. package/dist/init/app-choice.d.ts +20 -0
  161. package/dist/init/app-choice.js +25 -0
  162. package/dist/init/astro-host.d.ts +21 -0
  163. package/dist/init/astro-host.js +27 -0
  164. package/dist/init/astro-patch.d.ts +16 -0
  165. package/dist/init/astro-patch.js +240 -0
  166. package/dist/init/capabilities.js +4 -1
  167. package/dist/init/cra.d.ts +50 -0
  168. package/dist/init/cra.js +106 -0
  169. package/dist/init/cursor.js +39 -4
  170. package/dist/init/desktop-doctor.d.ts +3 -2
  171. package/dist/init/desktop-doctor.js +4 -4
  172. package/dist/init/detect.d.ts +9 -2
  173. package/dist/init/detect.js +24 -5
  174. package/dist/init/mcp-clients.d.ts +81 -0
  175. package/dist/init/mcp-clients.js +248 -0
  176. package/dist/init/mcp-registered.d.ts +12 -0
  177. package/dist/init/mcp-registered.js +14 -0
  178. package/dist/init/mcp.d.ts +27 -2
  179. package/dist/init/mcp.js +40 -4
  180. package/dist/init/next-patch.d.ts +2 -4
  181. package/dist/init/next-patch.js +109 -19
  182. package/dist/init/node-io.js +29 -6
  183. package/dist/init/plan-framework.d.ts +16 -1
  184. package/dist/init/plan-framework.js +166 -8
  185. package/dist/init/plan.d.ts +85 -6
  186. package/dist/init/plan.js +196 -33
  187. package/dist/init/project-id.d.ts +5 -9
  188. package/dist/init/project-id.js +10 -22
  189. package/dist/init/run.d.ts +23 -1
  190. package/dist/init/run.js +338 -47
  191. package/dist/init/slash-command.d.ts +9 -0
  192. package/dist/init/slash-command.js +10 -1
  193. package/dist/init/snippets.d.ts +7 -10
  194. package/dist/init/snippets.js +44 -15
  195. package/dist/init/vite-config.js +1 -1
  196. package/dist/init/windows-quote.d.ts +38 -0
  197. package/dist/init/windows-quote.js +70 -0
  198. package/dist/init/workspace-apps.d.ts +23 -0
  199. package/dist/init/workspace-apps.js +68 -0
  200. package/dist/input/driven-redaction.js +1 -1
  201. package/dist/input/network-detail.js +8 -8
  202. package/dist/input/network-mock-tools.js +2 -2
  203. package/dist/input/network-mock.js +4 -4
  204. package/dist/input/real-input.js +8 -3
  205. package/dist/input/scroll-find.js +2 -2
  206. package/dist/input/scroll-tools.d.ts +0 -5
  207. package/dist/input/scroll-tools.js +11 -4
  208. package/dist/input/viewport-tools.js +2 -2
  209. package/dist/journal/ambient-store.d.ts +0 -2
  210. package/dist/journal/ambient-store.js +1 -1
  211. package/dist/journal/ambient.js +1 -1
  212. package/dist/journal/attach-journal.d.ts +2 -1
  213. package/dist/journal/deviation-report.js +6 -6
  214. package/dist/journal/deviation-service.js +1 -1
  215. package/dist/journal/envelope-store.d.ts +0 -2
  216. package/dist/journal/envelope-store.js +1 -1
  217. package/dist/journal/envelope.d.ts +2 -3
  218. package/dist/journal/envelope.js +3 -3
  219. package/dist/journal/journal-query.js +1 -1
  220. package/dist/journal/journal-recorder.d.ts +2 -1
  221. package/dist/journal/journal-recorder.js +2 -2
  222. package/dist/journal/rollups.js +9 -9
  223. package/dist/journal/session-end.d.ts +2 -1
  224. package/dist/journal/session-journal.js +4 -4
  225. package/dist/license/license.d.ts +0 -14
  226. package/dist/license/license.js +8 -8
  227. package/dist/log.d.ts +10 -0
  228. package/dist/log.js +11 -1
  229. package/dist/mcp/mcp-is-error.d.ts +13 -0
  230. package/dist/mcp/mcp-is-error.js +18 -0
  231. package/dist/mcp/mcp-outage.d.ts +32 -0
  232. package/dist/mcp/mcp-outage.js +55 -0
  233. package/dist/mcp/mcp-proxy.d.ts +134 -0
  234. package/dist/mcp/mcp-proxy.js +720 -0
  235. package/dist/{mcp.d.ts → mcp/mcp.d.ts} +13 -10
  236. package/dist/{mcp.js → mcp/mcp.js} +139 -37
  237. package/dist/mcp/proxy-handshake.d.ts +3 -0
  238. package/dist/mcp/proxy-handshake.js +54 -0
  239. package/dist/mcp/proxy-lifecycle.d.ts +64 -0
  240. package/dist/mcp/proxy-lifecycle.js +70 -0
  241. package/dist/mcp/tool-catalog-cache.d.ts +29 -0
  242. package/dist/mcp/tool-catalog-cache.js +55 -0
  243. package/dist/oracles/propose-consequences.d.ts +2 -1
  244. package/dist/oracles/propose-consequences.js +16 -11
  245. package/dist/oracles/self-instrument.d.ts +2 -1
  246. package/dist/oracles/self-instrument.js +1 -1
  247. package/dist/phenomena/phenomena.js +3 -3
  248. package/dist/platform.d.ts +16 -0
  249. package/dist/platform.js +16 -0
  250. package/dist/pool/browser-pool.d.ts +9 -0
  251. package/dist/pool/browser-pool.js +38 -9
  252. package/dist/pool/playwright-launcher.d.ts +15 -2
  253. package/dist/pool/playwright-launcher.js +21 -2
  254. package/dist/project/fs-port.js +1 -1
  255. package/dist/project/project-tools.js +2 -2
  256. package/dist/runs/build-verification-run.js +1 -1
  257. package/dist/runs/repair-prompt.d.ts +0 -6
  258. package/dist/runs/repair-prompt.js +3 -3
  259. package/dist/runs/risk-classify.js +1 -1
  260. package/dist/runs/run-diff.d.ts +0 -2
  261. package/dist/runs/run-diff.js +3 -3
  262. package/dist/runs/run-tools.js +2 -2
  263. package/dist/runs/verification-sync.js +2 -2
  264. package/dist/runs/verify-http.js +1 -1
  265. package/dist/runs/verify-server.js +1 -1
  266. package/dist/session/attachment-history.d.ts +46 -0
  267. package/dist/session/attachment-history.js +65 -0
  268. package/dist/session/command-timeout.d.ts +11 -3
  269. package/dist/session/command-timeout.js +2 -2
  270. package/dist/session/control-envelope.d.ts +6 -0
  271. package/dist/session/control-envelope.js +7 -1
  272. package/dist/session/dev-server-probe.d.ts +13 -0
  273. package/dist/session/dev-server-probe.js +52 -0
  274. package/dist/session/last-act.d.ts +17 -3
  275. package/dist/session/last-act.js +16 -4
  276. package/dist/session/live-control-tools.js +7 -2
  277. package/dist/session/live-control.js +1 -1
  278. package/dist/session/looks-like-dev-server.d.ts +14 -0
  279. package/dist/session/looks-like-dev-server.js +25 -0
  280. package/dist/session/no-session-diagnosis.d.ts +45 -0
  281. package/dist/session/no-session-diagnosis.js +120 -0
  282. package/dist/session/no-session-watch.d.ts +21 -0
  283. package/dist/session/no-session-watch.js +69 -0
  284. package/dist/session/observed-state.d.ts +4 -0
  285. package/dist/session/observed-state.js +19 -1
  286. package/dist/session/output-budget.js +1 -1
  287. package/dist/session/pending-commands.js +1 -0
  288. package/dist/session/session-health.d.ts +8 -1
  289. package/dist/session/session-health.js +8 -7
  290. package/dist/session/session-info.d.ts +43 -8
  291. package/dist/session/session-info.js +46 -1
  292. package/dist/session/session-lease.d.ts +0 -11
  293. package/dist/session/session-lease.js +1 -1
  294. package/dist/session/session-manager.d.ts +6 -0
  295. package/dist/session/session-manager.js +124 -12
  296. package/dist/session/session-readiness.d.ts +1 -1
  297. package/dist/session/session-readiness.js +6 -1
  298. package/dist/session/session-reaper.js +1 -1
  299. package/dist/session/session-reconnect.d.ts +32 -0
  300. package/dist/session/session-reconnect.js +42 -0
  301. package/dist/session/session.d.ts +15 -2
  302. package/dist/session/session.js +77 -26
  303. package/dist/session/state-select.d.ts +1 -1
  304. package/dist/session/state-select.js +1 -1
  305. package/dist/status-payload.d.ts +19 -0
  306. package/dist/status-payload.js +11 -0
  307. package/dist/telemetry/argument-shape.js +10 -1
  308. package/dist/telemetry/browser-mode.d.ts +27 -0
  309. package/dist/telemetry/browser-mode.js +33 -0
  310. package/dist/telemetry/bug-found.d.ts +17 -21
  311. package/dist/telemetry/bug-found.js +120 -8
  312. package/dist/telemetry/cli-telemetry.d.ts +2 -12
  313. package/dist/telemetry/cli-telemetry.js +27 -4
  314. package/dist/telemetry/crash-cause.d.ts +47 -0
  315. package/dist/telemetry/crash-cause.js +104 -0
  316. package/dist/telemetry/daemon-telemetry.d.ts +38 -1
  317. package/dist/telemetry/daemon-telemetry.js +37 -12
  318. package/dist/telemetry/dev-repo.js +4 -4
  319. package/dist/telemetry/error-class.d.ts +26 -0
  320. package/dist/telemetry/error-class.js +52 -0
  321. package/dist/telemetry/error-fingerprint.js +21 -2
  322. package/dist/telemetry/feedback-cli.d.ts +8 -3
  323. package/dist/telemetry/feedback-cli.js +52 -8
  324. package/dist/telemetry/feedback-context.d.ts +23 -6
  325. package/dist/telemetry/feedback-context.js +105 -5
  326. package/dist/telemetry/feedback-delivery.d.ts +20 -0
  327. package/dist/telemetry/feedback-delivery.js +30 -0
  328. package/dist/telemetry/feedback-outbox.d.ts +22 -0
  329. package/dist/telemetry/feedback-outbox.js +87 -0
  330. package/dist/telemetry/feedback.d.ts +22 -1
  331. package/dist/telemetry/feedback.js +67 -8
  332. package/dist/telemetry/git-facts.d.ts +7 -0
  333. package/dist/telemetry/git-facts.js +5 -5
  334. package/dist/telemetry/project-profile.js +2 -1
  335. package/dist/telemetry/session-metrics.d.ts +47 -3
  336. package/dist/telemetry/session-metrics.js +315 -15
  337. package/dist/telemetry/telemetry.d.ts +45 -2
  338. package/dist/telemetry/telemetry.js +150 -37
  339. package/dist/telemetry/verification-of.d.ts +22 -0
  340. package/dist/telemetry/verification-of.js +84 -0
  341. package/dist/tools/act-capsule.js +2 -2
  342. package/dist/tools/act-danger.d.ts +12 -0
  343. package/dist/tools/act-danger.js +20 -3
  344. package/dist/tools/act-helpers.js +4 -4
  345. package/dist/tools/act-tools.d.ts +0 -8
  346. package/dist/tools/act-tools.js +114 -118
  347. package/dist/tools/act-view.js +7 -7
  348. package/dist/tools/alias-args.d.ts +17 -0
  349. package/dist/tools/alias-args.js +25 -0
  350. package/dist/tools/assert-grade.js +9 -9
  351. package/dist/tools/assert-verdict.d.ts +9 -1
  352. package/dist/tools/assert-verdict.js +21 -6
  353. package/dist/tools/browser-tools.js +36 -11
  354. package/dist/tools/contract-tools.d.ts +0 -5
  355. package/dist/tools/contract-tools.js +27 -1
  356. package/dist/tools/coverage-identity.d.ts +34 -0
  357. package/dist/tools/coverage-identity.js +46 -0
  358. package/dist/tools/coverage-tools.js +10 -14
  359. package/dist/tools/dynamic-tools.d.ts +2 -1
  360. package/dist/tools/dynamic-tools.js +96 -19
  361. package/dist/tools/error-recovery.d.ts +34 -2
  362. package/dist/tools/error-recovery.js +255 -4
  363. package/dist/tools/feedback-invite.d.ts +48 -0
  364. package/dist/tools/feedback-invite.js +71 -0
  365. package/dist/tools/feedback-tools.d.ts +12 -1
  366. package/dist/tools/feedback-tools.js +28 -5
  367. package/dist/tools/invoke-tool.d.ts +0 -12
  368. package/dist/tools/invoke-tool.js +126 -33
  369. package/dist/tools/lease-hint.d.ts +17 -0
  370. package/dist/tools/lease-hint.js +24 -0
  371. package/dist/tools/lease-tools.js +6 -5
  372. package/dist/tools/merge-tools.d.ts +10 -1
  373. package/dist/tools/merge-tools.js +9 -3
  374. package/dist/tools/merged-name-redirect.d.ts +13 -0
  375. package/dist/tools/merged-name-redirect.js +55 -0
  376. package/dist/tools/navigate-arrival.d.ts +26 -0
  377. package/dist/tools/navigate-arrival.js +60 -0
  378. package/dist/tools/navigate-result.d.ts +31 -0
  379. package/dist/tools/navigate-result.js +38 -0
  380. package/dist/tools/observe-tools.js +72 -20
  381. package/dist/tools/observed-nothing.d.ts +25 -0
  382. package/dist/tools/observed-nothing.js +33 -0
  383. package/dist/tools/query-paginate.js +2 -2
  384. package/dist/tools/query-shape.d.ts +18 -0
  385. package/dist/tools/query-shape.js +39 -0
  386. package/dist/tools/read-tools.js +81 -20
  387. package/dist/tools/real-input-attempt.d.ts +28 -0
  388. package/dist/tools/real-input-attempt.js +93 -0
  389. package/dist/tools/reconcile-tools.js +7 -7
  390. package/dist/tools/reload-result.d.ts +14 -0
  391. package/dist/tools/reload-result.js +29 -0
  392. package/dist/tools/snapshot-delta.d.ts +4 -5
  393. package/dist/tools/snapshot-delta.js +0 -0
  394. package/dist/tools/tool-kit.d.ts +16 -0
  395. package/dist/tools/tool-surface.d.ts +83 -0
  396. package/dist/tools/tool-surface.js +217 -0
  397. package/dist/tools/tools-helpers.js +6 -6
  398. package/dist/tools/tools.d.ts +15 -0
  399. package/dist/tools/tools.js +53 -17
  400. package/dist/tools/unadvertised-help.d.ts +5 -0
  401. package/dist/tools/unadvertised-help.js +39 -0
  402. package/dist/trace.d.ts +69 -0
  403. package/dist/trace.js +150 -0
  404. package/dist/update/nudge-credit.d.ts +4 -0
  405. package/dist/update/nudge-credit.js +53 -0
  406. package/dist/update/sdk-sync.d.ts +21 -0
  407. package/dist/update/sdk-sync.js +42 -0
  408. package/dist/update/update-checker.js +3 -3
  409. package/dist/update/update-nudge.d.ts +63 -6
  410. package/dist/update/update-nudge.js +128 -15
  411. package/dist/update/updater.d.ts +1 -9
  412. package/dist/update/updater.js +13 -8
  413. package/dist/version/peer-announce.d.ts +4 -0
  414. package/dist/version/peer-announce.js +30 -0
  415. package/dist/{server-version.js → version/server-version.js} +5 -1
  416. package/dist/version/version-nudge.d.ts +28 -0
  417. package/dist/version/version-nudge.js +40 -0
  418. package/dist/version/version-skew.d.ts +66 -0
  419. package/dist/version/version-skew.js +71 -0
  420. package/dist/visual/visual-diff.js +2 -2
  421. package/dist/visual/visual-tools.js +4 -4
  422. package/docs/README.md +55 -0
  423. package/docs/agent-cheatsheet.md +85 -0
  424. package/docs/architecture.md +113 -0
  425. package/docs/benchmarks.md +255 -0
  426. package/docs/debugging.md +102 -0
  427. package/docs/deploy-checks.md +69 -0
  428. package/docs/desktop-apps.md +256 -0
  429. package/docs/enterprise.md +62 -0
  430. package/docs/fixtures-dispatch-receiver.yml +76 -0
  431. package/docs/fixtures.md +45 -0
  432. package/docs/flows.md +166 -0
  433. package/docs/gate-plan.md +98 -0
  434. package/docs/gates.md +117 -0
  435. package/docs/getting-started.md +469 -0
  436. package/docs/human-control.md +63 -0
  437. package/docs/integration-patterns.md +171 -0
  438. package/docs/local-registry.md +126 -0
  439. package/docs/matrix/2.5.0/claude-code-machine.json +19 -0
  440. package/docs/matrix/2.5.0/codex-machine.json +20 -0
  441. package/docs/matrix/2.5.0/cursor-machine.json +22 -0
  442. package/docs/matrix/2.5.0/gemini-machine.json +22 -0
  443. package/docs/matrix/2.5.0/opencode-machine.json +22 -0
  444. package/docs/matrix/2.5.0/vscode-machine.json +22 -0
  445. package/docs/matrix/2.5.0/windsurf-machine.json +22 -0
  446. package/docs/matrix/MATRIX.md +26 -0
  447. package/docs/matrix/README.md +59 -0
  448. package/docs/mint.json +61 -0
  449. package/docs/multi-agent-testing.md +55 -0
  450. package/docs/platform-integration.md +122 -0
  451. package/docs/system-map.md +152 -0
  452. package/docs/telemetry-contract.md +214 -0
  453. package/docs/telemetry.md +191 -0
  454. package/docs/testing.md +82 -0
  455. package/docs/token-efficiency.md +80 -0
  456. package/docs/usage.md +1046 -0
  457. package/package.json +8 -5
  458. package/dist/cli-doctor.d.ts +0 -6
  459. package/dist/cli-doctor.js +0 -60
  460. package/dist/cli-launch.js +0 -112
  461. package/dist/daemon-resilience.d.ts +0 -22
  462. package/dist/daemon-resilience.js +0 -85
  463. package/dist/mcp-proxy.d.ts +0 -67
  464. package/dist/mcp-proxy.js +0 -337
  465. package/dist/tools/profiles.d.ts +0 -37
  466. package/dist/tools/profiles.js +0 -139
  467. /package/dist/{pairing-token.d.ts → bridge/pairing-token.d.ts} +0 -0
  468. /package/dist/{token-auth.d.ts → bridge/token-auth.d.ts} +0 -0
  469. /package/dist/{token-auth.js → bridge/token-auth.js} +0 -0
  470. /package/dist/{cli-verify.d.ts → cli/cli-verify.d.ts} +0 -0
  471. /package/dist/{cloud-cli.d.ts → cli/cloud-cli.d.ts} +0 -0
  472. /package/dist/{server-version.d.ts → version/server-version.d.ts} +0 -0
@@ -4,14 +4,9 @@
4
4
  * file-size cap and keep the parser pure + unit-testable. Re-exported from cli.ts so existing
5
5
  * imports are unchanged.
6
6
  */
7
- export declare const CLI_USAGE = "usage:\n reticle init [--dry-run] [--port N] [--no-mcp] [--no-install] (wire Reticle into the project in this directory)\n reticle serve [--port N] [--drive <url>] [--headless] [--http] [--http-port N] [--http-token T]\n reticle stop [--port N] [--quiet]\n reticle status [--port N]\n reticle doctor [--port N] (diagnose setup: Chromium, daemon, port \u2014 one command)\n reticle open [url] [--port N] (show the app: reuse the connected tab, else open one)\n reticle verify <url> [--headed] [--timeout N] [--storage-state <file>] (one-shot: drive the URL, verify saved flows, exit 0=pass)\n reticle affected [--since <ref>] [file...] (which saved flows must re-verify for the changed files)\n reticle gate [--since <ref>] [file...] (exit non-zero unless passing artifacts cover the affected flows)\n reticle watch [url] (on save, report which saved flows must re-verify)\n reticle drive <url> [--headless] (foreground mode \u2014 for debugging)\n reticle mcp [--port N] [--drive <url>] [--headless] (MCP stdio proxy \u2014 auto-starts daemon if needed)\n reticle update (install the latest server version and restart)\n reticle rollback (restore the previous server version and restart)\n reticle license (show enterprise license status: active | eval | missing)\n reticle telemetry [status|enable|disable] (anonymous usage metrics \u2014 status shows what's sent + the policy)\n reticle feedback [--rating 1-5] [--bug] \"message\" (tell us what worked and what didn't \u2014 prints exactly what it sends)\n reticle identify --context company|side_project|open_source|learning [--company N] [--email E] [--forget]\n (OPT-IN: tell us who you are, e.g. for support or an enterprise trial)\n\nCloud (link this project to Reticle Cloud \u2014 runs/flows recorded on the dashboard):\n reticle login --email <e> [--code <c>] [--org <n>] (sign in: mails a code, then exchanges it)\n reticle link [--project <name|id>] (bind this repo: mints a scoped key, writes .reticle/cloud.json)\n reticle whoami (who am I signed in as, and is this repo attached?)\n reticle project <ls|create <name>> (list or create cloud projects)\n reticle config [--runs on|off] [--memory on|off] [--flows on|off] [--verify local|server]\n reticle push (send local run artifacts to the dashboard)\n reticle runs | regression | share <runId> (read cloud state; regression exits 3 if any flow broke)\n\n'drive' shows the browser; everything else is hidden (serve/mcp own the pool behind leases, replay\nand the spec runner \u2014 batch work). --headed opts any of them in, --headless hides drive, CI hides it.";
8
- export declare const COMPANY_FLAG = "--company";
9
- export declare const EMAIL_FLAG = "--email";
10
- export declare const CONTEXT_FLAG = "--context";
11
- export declare const FORGET_FLAG = "--forget";
12
- /** `reticle feedback --rating 4 "the words"` — the human half of the channel. */
13
- export declare const RATING_FLAG = "--rating";
14
- export declare const BUG_FLAG = "--bug";
7
+ import { type ParsedFeedback } from './cli-parse-feedback.js';
8
+ export { AGENT_FLAG, BUG_FLAG, FEEDBACK_KINDS, KIND_FLAG, RATING_FLAG, } from './cli-parse-feedback.js';
9
+ export declare const CLI_USAGE = "usage:\n reticle init [--dry-run] [--port N] [--no-mcp] [--no-install] [--app <dir>] (wire Reticle into the project in this directory)\n --app picks WHICH app in a monorepo, when several are found\n --no-mcp skips MORE than the server registration: also the agent rule files\n (CLAUDE.md / AGENTS.md / .cursor) and the /reticle command, because all three\n only make sense once the tools are reachable.\n reticle serve [--port N] [--drive <url>] [--headless] [--http] [--http-port N] [--http-token T]\n reticle stop [--port N] [--quiet]\n reticle status [--port N]\n reticle doctor [--port N] (diagnose setup: Chromium, daemon, port \u2014 one command)\n reticle open [url] [--port N] (show the app: reuse the connected tab, else open one)\n reticle verify <url> [--headed] [--timeout N] [--storage-state <file>] (one-shot: drive the URL, verify saved flows, exit 0=pass)\n reticle affected [--since <ref>] [file...] (which saved flows must re-verify for the changed files)\n reticle gate [--since <ref>] [file...] (exit non-zero unless passing artifacts cover the affected flows)\n reticle watch [url] (on save, report which saved flows must re-verify)\n reticle drive <url> [--headless] (foreground mode \u2014 for debugging)\n reticle mcp [--port N] [--drive <url>] [--headless] (MCP stdio proxy \u2014 auto-starts daemon if needed)\n reticle update (install the latest server version and restart)\n reticle rollback (restore the previous server version and restart)\n reticle license (show enterprise license status: active | eval | missing)\n reticle telemetry [status|enable|disable] (anonymous usage metrics \u2014 status shows what's sent + the policy)\n reticle feedback [--rating 1-5] [--bug] \"message\" (tell us what worked and what didn't \u2014 prints exactly what it sends)\n reticle feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement> \"message\"\n (agents: file from anywhere, including a setup that never finished)\n reticle identify --context company|side_project|open_source|learning [--company N] [--email E] [--forget]\n (OPT-IN: tell us who you are, e.g. for support or an enterprise trial)\n\nCloud (link this project to Reticle Cloud \u2014 runs/flows recorded on the dashboard):\n reticle login --email <e> [--code <c>] [--org <n>] (sign in: mails a code, then exchanges it)\n reticle link [--project <name|id>] (bind this repo: mints a scoped key, writes .reticle/cloud.json)\n reticle whoami (who am I signed in as, and is this repo attached?)\n reticle project <ls|create <name>> (list or create cloud projects)\n reticle config [--runs on|off] [--memory on|off] [--flows on|off] [--verify local|server]\n reticle push (send local run artifacts to the dashboard)\n reticle runs | regression | share <runId> (read cloud state; regression exits 3 if any flow broke)\n\n'drive' shows the browser; everything else is hidden (serve/mcp own the pool behind leases, replay\nand the spec runner \u2014 batch work). --headed opts any of them in, --headless hides drive, CI hides it.";
15
10
  /** The `reticle telemetry` sub-actions. Bare `reticle telemetry` means `status`. */
16
11
  export declare const TelemetryAction: {
17
12
  readonly STATUS: "status";
@@ -33,12 +28,6 @@ export declare const UNKNOWN_COMMAND = "unknown";
33
28
  /** The subcommand name if we recognize it, else `unknown`. Bare `reticle` reports `help`. */
34
29
  export declare function knownCommand(arg: string | undefined): string;
35
30
  export declare const HEADED_FLAG = "--headed";
36
- /**
37
- * Force a hidden browser. The default is now HEADED: a run nobody can see is a run nobody trusts,
38
- * and every "did it actually do anything?" question cost a round-trip. CI passes this (or just sets
39
- * CI, which flips the default) because there is no display there to be headed on.
40
- */
41
- export declare const HEADLESS_FLAG = "--headless";
42
31
  export declare const PORT_FLAG = "--port";
43
32
  export declare const DRIVE_FLAG = "--drive";
44
33
  export declare const HTTP_FLAG = "--http";
@@ -50,6 +39,7 @@ export type CliResult = {
50
39
  mcp: boolean;
51
40
  dryRun: boolean;
52
41
  install: boolean;
42
+ app: string | undefined;
53
43
  } | {
54
44
  kind: 'serve';
55
45
  port: number;
@@ -70,12 +60,9 @@ export type CliResult = {
70
60
  } | {
71
61
  kind: 'telemetry';
72
62
  action: TelemetryAction;
73
- } | {
63
+ } | Extract<ParsedFeedback, {
74
64
  kind: 'feedback';
75
- text: string;
76
- rating?: number;
77
- bug: boolean;
78
- } | {
65
+ }> | {
79
66
  kind: 'identify';
80
67
  context?: string;
81
68
  company?: string;
@@ -4,8 +4,15 @@
4
4
  * file-size cap and keep the parser pure + unit-testable. Re-exported from cli.ts so existing
5
5
  * imports are unchanged.
6
6
  */
7
+ import { parseFeedbackArgs } from './cli-parse-feedback.js';
8
+ // Re-exported so every existing importer of these flags is unaffected by the file split.
9
+ export { AGENT_FLAG, BUG_FLAG, FEEDBACK_KINDS, KIND_FLAG, RATING_FLAG, } from './cli-parse-feedback.js';
7
10
  export const CLI_USAGE = `usage:
8
- reticle init [--dry-run] [--port N] [--no-mcp] [--no-install] (wire Reticle into the project in this directory)
11
+ reticle init [--dry-run] [--port N] [--no-mcp] [--no-install] [--app <dir>] (wire Reticle into the project in this directory)
12
+ --app picks WHICH app in a monorepo, when several are found
13
+ --no-mcp skips MORE than the server registration: also the agent rule files
14
+ (CLAUDE.md / AGENTS.md / .cursor) and the /reticle command, because all three
15
+ only make sense once the tools are reachable.
9
16
  reticle serve [--port N] [--drive <url>] [--headless] [--http] [--http-port N] [--http-token T]
10
17
  reticle stop [--port N] [--quiet]
11
18
  reticle status [--port N]
@@ -22,6 +29,8 @@ export const CLI_USAGE = `usage:
22
29
  reticle license (show enterprise license status: active | eval | missing)
23
30
  reticle telemetry [status|enable|disable] (anonymous usage metrics — status shows what's sent + the policy)
24
31
  reticle feedback [--rating 1-5] [--bug] "message" (tell us what worked and what didn't — prints exactly what it sends)
32
+ reticle feedback --agent --kind <bug|gap|ambiguity|feature_request|improvement> "message"
33
+ (agents: file from anywhere, including a setup that never finished)
25
34
  reticle identify --context company|side_project|open_source|learning [--company N] [--email E] [--forget]
26
35
  (OPT-IN: tell us who you are, e.g. for support or an enterprise trial)
27
36
 
@@ -56,13 +65,10 @@ const VERSION_COMMAND = 'version';
56
65
  const TELEMETRY_COMMAND = 'telemetry';
57
66
  const FEEDBACK_COMMAND = 'feedback';
58
67
  const IDENTIFY_COMMAND = 'identify';
59
- export const COMPANY_FLAG = '--company';
60
- export const EMAIL_FLAG = '--email';
61
- export const CONTEXT_FLAG = '--context';
62
- export const FORGET_FLAG = '--forget';
63
- /** `reticle feedback --rating 4 "the words"` — the human half of the channel. */
64
- export const RATING_FLAG = '--rating';
65
- export const BUG_FLAG = '--bug';
68
+ const COMPANY_FLAG = '--company';
69
+ const EMAIL_FLAG = '--email';
70
+ const CONTEXT_FLAG = '--context';
71
+ const FORGET_FLAG = '--forget';
66
72
  /** The `reticle telemetry` sub-actions. Bare `reticle telemetry` means `status`. */
67
73
  export const TelemetryAction = {
68
74
  STATUS: 'status',
@@ -118,7 +124,7 @@ const KNOWN_COMMANDS = new Set([
118
124
  ]);
119
125
  /** The subcommand name if we recognize it, else `unknown`. Bare `reticle` reports `help`. */
120
126
  export function knownCommand(arg) {
121
- if (arg === undefined || arg === '')
127
+ if (arg === undefined || '' === arg)
122
128
  return 'help';
123
129
  return KNOWN_COMMANDS.has(arg) ? arg : UNKNOWN_COMMAND;
124
130
  }
@@ -128,25 +134,40 @@ export const HEADED_FLAG = '--headed';
128
134
  * and every "did it actually do anything?" question cost a round-trip. CI passes this (or just sets
129
135
  * CI, which flips the default) because there is no display there to be headed on.
130
136
  */
131
- export const HEADLESS_FLAG = '--headless';
137
+ const HEADLESS_FLAG = '--headless';
132
138
  export const PORT_FLAG = '--port';
133
139
  export const DRIVE_FLAG = '--drive';
134
140
  const QUIET_FLAG = '--quiet';
135
141
  const DRY_RUN_FLAG = '--dry-run';
136
142
  const YES_FLAG = '--yes';
137
143
  const NO_MCP_FLAG = '--no-mcp';
144
+ const APP_FLAG = '--app';
138
145
  const NO_INSTALL_FLAG = '--no-install';
139
146
  export const HTTP_FLAG = '--http';
140
147
  export const HTTP_PORT_FLAG = '--http-port';
141
148
  export const HTTP_TOKEN_FLAG = '--http-token';
142
149
  const TIMEOUT_FLAG = '--timeout';
143
150
  const STORAGE_STATE_FLAG = '--storage-state';
144
- /**
145
- * `serve` / `mcp` / `_daemon` own the browser POOL, which backs automated work — leased contexts for
146
- * parallel agents, flow replay, the spec runner. Those are batch: nobody is watching, and launching
147
- * them headed changed timing enough to break four e2e specs. The headed default belongs to the
148
- * INTERACTIVE command (`drive`), where a human asked to see the run. `--headed` still opts in here.
149
- */
151
+ const unknownArgument = (arg) => ({
152
+ kind: 'error',
153
+ message: `unknown argument '${arg}'`,
154
+ });
155
+ const missingValue = (flag) => ({
156
+ kind: 'error',
157
+ message: `${flag} needs a value`,
158
+ });
159
+ const notANumber = (flag, value) => ({
160
+ kind: 'error',
161
+ message: `${flag} expects a number, got '${value}'`,
162
+ });
163
+ const missingOperand = (command, what) => ({
164
+ kind: 'error',
165
+ message: `${command} needs ${what}`,
166
+ });
167
+ const unknownCommand = (command) => ({
168
+ kind: 'error',
169
+ message: `unknown command '${command}'`,
170
+ });
150
171
  function parseServeFlags(args, defaultPort, _defaultHeadless) {
151
172
  let port = defaultPort;
152
173
  let driveUrl;
@@ -157,21 +178,25 @@ function parseServeFlags(args, defaultPort, _defaultHeadless) {
157
178
  let i = 0;
158
179
  while (i < args.length) {
159
180
  const arg = args[i];
181
+ // `i < args.length` already guarantees this, but the index signature does not say so and the
182
+ // unknown-argument error needs a real string to name.
183
+ if (arg === undefined)
184
+ break;
160
185
  if (arg === PORT_FLAG) {
161
186
  i++;
162
187
  const n = args[i];
163
188
  if (n === undefined)
164
- return { kind: 'error', message: CLI_USAGE };
189
+ return missingValue(PORT_FLAG);
165
190
  const parsed = parseInt(n, 10);
166
191
  if (isNaN(parsed))
167
- return { kind: 'error', message: CLI_USAGE };
192
+ return notANumber(PORT_FLAG, n);
168
193
  port = parsed;
169
194
  }
170
195
  else if (arg === DRIVE_FLAG) {
171
196
  i++;
172
197
  driveUrl = args[i];
173
198
  if (driveUrl === undefined)
174
- return { kind: 'error', message: CLI_USAGE };
199
+ return missingValue(DRIVE_FLAG);
175
200
  }
176
201
  else if (arg === HEADED_FLAG) {
177
202
  headless = false;
@@ -186,20 +211,20 @@ function parseServeFlags(args, defaultPort, _defaultHeadless) {
186
211
  i++;
187
212
  const n = args[i];
188
213
  if (n === undefined)
189
- return { kind: 'error', message: CLI_USAGE };
214
+ return missingValue(HTTP_PORT_FLAG);
190
215
  const parsed = parseInt(n, 10);
191
216
  if (isNaN(parsed))
192
- return { kind: 'error', message: CLI_USAGE };
217
+ return notANumber(HTTP_PORT_FLAG, n);
193
218
  httpPort = parsed;
194
219
  }
195
220
  else if (arg === HTTP_TOKEN_FLAG) {
196
221
  i++;
197
222
  httpToken = args[i];
198
223
  if (httpToken === undefined)
199
- return { kind: 'error', message: CLI_USAGE };
224
+ return missingValue(HTTP_TOKEN_FLAG);
200
225
  }
201
226
  else {
202
- return { kind: 'error', message: CLI_USAGE };
227
+ return unknownArgument(arg);
203
228
  }
204
229
  i++;
205
230
  }
@@ -215,7 +240,7 @@ function parseServeFlags(args, defaultPort, _defaultHeadless) {
215
240
  }
216
241
  function parsePortFlag(args, defaultPort) {
217
242
  const idx = args.indexOf(PORT_FLAG);
218
- if (idx === -1)
243
+ if (-1 === idx)
219
244
  return defaultPort;
220
245
  const n = args[idx + 1];
221
246
  if (n === undefined)
@@ -234,17 +259,17 @@ function parseDriveSuffix(args, port, defaultHeadless) {
234
259
  headless = true;
235
260
  }
236
261
  else if (arg.startsWith('--')) {
237
- return { kind: 'error', message: CLI_USAGE };
262
+ return unknownArgument(arg);
238
263
  }
239
264
  else if (driveUrl === undefined) {
240
265
  driveUrl = arg;
241
266
  }
242
267
  else {
243
- return { kind: 'error', message: CLI_USAGE };
268
+ return unknownArgument(arg);
244
269
  }
245
270
  }
246
271
  if (driveUrl === undefined)
247
- return { kind: 'error', message: CLI_USAGE };
272
+ return missingOperand(DRIVE_COMMAND, 'a url');
248
273
  return { kind: 'ok', port, driveUrl, headless };
249
274
  }
250
275
  /**
@@ -268,32 +293,32 @@ function parseVerifySuffix(args) {
268
293
  i++;
269
294
  const n = args[i];
270
295
  if (n === undefined)
271
- return { kind: 'error', message: CLI_USAGE };
296
+ return missingValue(TIMEOUT_FLAG);
272
297
  const parsed = parseInt(n, 10);
273
298
  if (isNaN(parsed))
274
- return { kind: 'error', message: CLI_USAGE };
299
+ return notANumber(TIMEOUT_FLAG, n);
275
300
  timeoutMs = parsed;
276
301
  }
277
302
  else if (arg === STORAGE_STATE_FLAG) {
278
303
  i++;
279
304
  const v = args[i];
280
305
  if (v === undefined)
281
- return { kind: 'error', message: CLI_USAGE };
306
+ return missingValue(STORAGE_STATE_FLAG);
282
307
  storageState = v;
283
308
  }
284
309
  else if (arg.startsWith('--')) {
285
- return { kind: 'error', message: CLI_USAGE };
310
+ return unknownArgument(arg);
286
311
  }
287
312
  else if (url === undefined) {
288
313
  url = arg;
289
314
  }
290
315
  else {
291
- return { kind: 'error', message: CLI_USAGE };
316
+ return unknownArgument(arg);
292
317
  }
293
318
  i++;
294
319
  }
295
320
  if (url === undefined)
296
- return { kind: 'error', message: CLI_USAGE };
321
+ return missingOperand(VERIFY_COMMAND, 'a url');
297
322
  return {
298
323
  kind: 'ok',
299
324
  url,
@@ -307,19 +332,31 @@ function parseInitFlags(args) {
307
332
  let mcp = true;
308
333
  let dryRun = false;
309
334
  let install = true;
335
+ let app;
310
336
  let i = 0;
311
337
  while (i < args.length) {
312
338
  const arg = args[i];
339
+ // `i < args.length` already guarantees this, but the index signature does not say so and the
340
+ // unknown-argument error needs a real string to name.
341
+ if (arg === undefined)
342
+ break;
313
343
  if (arg === PORT_FLAG) {
314
344
  i++;
315
345
  const n = args[i];
316
346
  if (n === undefined)
317
- return { kind: 'error', message: CLI_USAGE };
347
+ return missingValue(PORT_FLAG);
318
348
  const parsed = parseInt(n, 10);
319
349
  if (isNaN(parsed))
320
- return { kind: 'error', message: CLI_USAGE };
350
+ return notANumber(PORT_FLAG, n);
321
351
  port = parsed;
322
352
  }
353
+ else if (arg === APP_FLAG) {
354
+ i++;
355
+ const value = args[i];
356
+ if (value === undefined)
357
+ return missingValue(APP_FLAG);
358
+ app = value;
359
+ }
323
360
  else if (arg === NO_MCP_FLAG) {
324
361
  mcp = false;
325
362
  }
@@ -333,15 +370,29 @@ function parseInitFlags(args) {
333
370
  // Accepted for scripting/CI; init has no interactive prompts today.
334
371
  }
335
372
  else {
336
- return { kind: 'error', message: CLI_USAGE };
373
+ return unknownArgument(arg);
337
374
  }
338
375
  i++;
339
376
  }
340
- return { kind: 'ok', port, mcp, dryRun, install };
377
+ return { kind: 'ok', port, mcp, dryRun, install, app };
341
378
  }
342
379
  /** Pure CLI arg parser — exported for unit tests. argv = process.argv.slice(2). */
343
380
  const SINCE_FLAG = '--since';
344
381
  /** Parse `[--since <ref>] [file...]` shared by `affected` and `gate`. */
382
+ /**
383
+ * What `reticle gate` / `reticle affected` mean with NOTHING after them: the working tree.
384
+ *
385
+ * They used to mean a usage error — while the rule `reticle init` writes into the agent's own
386
+ * instruction file says, in as many words, "run `reticle gate`". An instruction the tool rejects is
387
+ * worse than no instruction: the agent spends a turn on it and concludes Reticle is broken.
388
+ *
389
+ * HEAD is the ref that answers the question being asked. Explicit files or an explicit --since still
390
+ * win; this only fills the empty case.
391
+ */
392
+ const WORKING_TREE_REF = 'HEAD';
393
+ function implicitSince(files) {
394
+ return 0 === files.length ? WORKING_TREE_REF : undefined;
395
+ }
345
396
  function parseTargetArgs(rest) {
346
397
  const files = [];
347
398
  let since;
@@ -365,27 +416,37 @@ function parseTargetArgs(rest) {
365
416
  */
366
417
  export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
367
418
  // Bare `reticle` is `serve` — a pool-owning command, so headless like the rest of that family.
368
- if (argv.length === 0)
419
+ if (0 === argv.length)
369
420
  return { kind: 'serve', port: defaultPort, headless: true, http: false };
370
421
  const [cmd, ...rest] = argv;
422
+ // Guaranteed by the bare-argv check above; restated so the unknown-command error can name it.
423
+ if (cmd === undefined)
424
+ return { kind: 'error', message: CLI_USAGE };
371
425
  // `version` (or the conventional -v/--version flags) prints the running version — the diagnostic the
372
426
  // troubleshooting docs lean on to confirm which npx-resolved build is actually executing.
373
- if (cmd === VERSION_COMMAND || cmd === '--version' || cmd === '-v')
427
+ if (cmd === VERSION_COMMAND || '--version' === cmd || '-v' === cmd)
374
428
  return { kind: 'version' };
375
429
  // `help` (and the conventional -h/--help) print usage to stdout and exit 0 — the universal first move
376
430
  // for a new user, which otherwise fell through to a JSON error with exit 1.
377
- if (cmd === 'help' || cmd === '--help' || cmd === '-h')
431
+ if ('help' === cmd || '--help' === cmd || '-h' === cmd)
378
432
  return { kind: 'help' };
379
433
  switch (cmd) {
380
434
  case INIT_COMMAND: {
381
435
  const r = parseInitFlags(rest);
382
- if (r.kind === 'error')
436
+ if ('error' === r.kind)
383
437
  return r;
384
- return { kind: 'init', port: r.port, mcp: r.mcp, dryRun: r.dryRun, install: r.install };
438
+ return {
439
+ kind: 'init',
440
+ port: r.port,
441
+ mcp: r.mcp,
442
+ dryRun: r.dryRun,
443
+ install: r.install,
444
+ app: r.app,
445
+ };
385
446
  }
386
447
  case SERVE_COMMAND: {
387
448
  const r = parseServeFlags(rest, defaultPort, defaultHeadless);
388
- if (r.kind === 'error')
449
+ if ('error' === r.kind)
389
450
  return r;
390
451
  return {
391
452
  kind: 'serve',
@@ -424,7 +485,7 @@ export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
424
485
  case IDENTIFY_COMMAND: {
425
486
  const flag = (name) => {
426
487
  const at = rest.indexOf(name);
427
- return at === -1 ? undefined : rest[at + 1];
488
+ return -1 === at ? undefined : rest[at + 1];
428
489
  };
429
490
  const context = flag(CONTEXT_FLAG);
430
491
  const company = flag(COMPANY_FLAG);
@@ -437,26 +498,8 @@ export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
437
498
  forget: rest.includes(FORGET_FLAG),
438
499
  };
439
500
  }
440
- case FEEDBACK_COMMAND: {
441
- const ratingAt = rest.indexOf(RATING_FLAG);
442
- const rating = ratingAt === -1 ? undefined : Number(rest[ratingAt + 1]);
443
- if (rating !== undefined && (!Number.isInteger(rating) || rating < 1 || rating > 5)) {
444
- return { kind: 'error', message: `${RATING_FLAG} takes a whole number from 1 to 5` };
445
- }
446
- // Everything that is not a flag or the rating's value is the message. Quoting is the user's
447
- // job for shell reasons, but joining the remainder means an unquoted sentence still works.
448
- const consumed = new Set(ratingAt === -1 ? [] : [ratingAt, ratingAt + 1]);
449
- const text = rest
450
- .filter((arg, i) => !consumed.has(i) && !arg.startsWith('--'))
451
- .join(' ')
452
- .trim();
453
- return {
454
- kind: 'feedback',
455
- text,
456
- ...(rating !== undefined ? { rating } : {}),
457
- bug: rest.includes(BUG_FLAG),
458
- };
459
- }
501
+ case FEEDBACK_COMMAND:
502
+ return parseFeedbackArgs(rest);
460
503
  case OPEN_COMMAND: {
461
504
  const port = parsePortFlag(rest, defaultPort);
462
505
  // The first non-flag arg is the url (optional — omitting reuses a connected tab).
@@ -465,13 +508,13 @@ export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
465
508
  }
466
509
  case DRIVE_COMMAND: {
467
510
  const r = parseDriveSuffix(rest, defaultPort, defaultHeadless);
468
- if (r.kind === 'error')
511
+ if ('error' === r.kind)
469
512
  return r;
470
513
  return { kind: 'drive', port: r.port, driveUrl: r.driveUrl, headless: r.headless };
471
514
  }
472
515
  case DAEMON_INNER_COMMAND: {
473
516
  const r = parseServeFlags(rest, defaultPort, defaultHeadless);
474
- if (r.kind === 'error')
517
+ if ('error' === r.kind)
475
518
  return r;
476
519
  return {
477
520
  kind: '_daemon',
@@ -485,7 +528,7 @@ export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
485
528
  }
486
529
  case VERIFY_COMMAND: {
487
530
  const r = parseVerifySuffix(rest);
488
- if (r.kind === 'error')
531
+ if ('error' === r.kind)
489
532
  return r;
490
533
  return {
491
534
  kind: 'verify',
@@ -505,21 +548,13 @@ export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
505
548
  }
506
549
  case AFFECTED_COMMAND: {
507
550
  const t = parseTargetArgs(rest);
508
- if (t.files.length === 0 && t.since === undefined) {
509
- return { kind: 'error', message: 'usage: reticle affected [--since <ref>] [file...]' };
510
- }
511
- return {
512
- kind: 'affected',
513
- files: t.files,
514
- ...(t.since === undefined ? {} : { since: t.since }),
515
- };
551
+ const since = t.since ?? implicitSince(t.files);
552
+ return { kind: 'affected', files: t.files, ...(since === undefined ? {} : { since }) };
516
553
  }
517
554
  case GATE_COMMAND: {
518
555
  const t = parseTargetArgs(rest);
519
- if (t.files.length === 0 && t.since === undefined) {
520
- return { kind: 'error', message: 'usage: reticle gate [--since <ref>] [file...]' };
521
- }
522
- return { kind: 'gate', files: t.files, ...(t.since === undefined ? {} : { since: t.since }) };
556
+ const since = t.since ?? implicitSince(t.files);
557
+ return { kind: 'gate', files: t.files, ...(since === undefined ? {} : { since }) };
523
558
  }
524
559
  case WATCH_COMMAND: {
525
560
  // `reticle watch [url]` — on file save, report which saved flows must re-verify.
@@ -532,7 +567,7 @@ export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
532
567
  return { kind: 'rollback' };
533
568
  case MCP_COMMAND: {
534
569
  const r = parseServeFlags(rest, defaultPort, defaultHeadless);
535
- if (r.kind === 'error')
570
+ if ('error' === r.kind)
536
571
  return r;
537
572
  return {
538
573
  kind: 'mcp',
@@ -545,6 +580,8 @@ export function parseCliArgs(argv, defaultPort, defaultHeadless = false) {
545
580
  };
546
581
  }
547
582
  default:
548
- return { kind: 'error', message: CLI_USAGE };
583
+ // A bare `reticle` never lands here — it defaults to `serve` above — so `cmd` is always a real
584
+ // word somebody typed, and naming it is strictly more useful than reprinting the whole help.
585
+ return unknownCommand(cmd);
549
586
  }
550
587
  }
@@ -7,6 +7,18 @@
7
7
  * 3..reticle.json "port" field in the cwd ← per-project isolation
8
8
  * 4. RETICLE_DEFAULT_PORT (4400)
9
9
  */
10
+ /**
11
+ * Ports that belong to a DEV SERVER, not to Reticle's bridge. Next defaults to 3000, Vite to 5173,
12
+ * Astro to 4321, and so on.
13
+ *
14
+ * `.reticle.json`'s `port` is the bridge — the daemon ↔ SDK channel, default 4400 — and it has
15
+ * nothing to do with the port the app is served on. Setting it to the dev-server port makes the
16
+ * daemon try to bind the port the app already holds; what the user sees is either a bind failure or
17
+ * a daemon that never connects, neither of which mentions the actual mistake. The old setup skill
18
+ * asked "what port does your dev server run on?" a few lines before showing this field, which is how
19
+ * the confusion got manufactured in the first place.
20
+ */
21
+ export declare const DEV_SERVER_PORTS: ReadonlySet<number>;
10
22
  export declare function isLikelyDevServerPort(port: number): boolean;
11
23
  /** The warning printed when a project pins the bridge to something that looks like its dev server. */
12
24
  export declare function devServerPortWarning(port: number): string;
@@ -19,7 +19,7 @@ import { readFileSync } from 'node:fs';
19
19
  * asked "what port does your dev server run on?" a few lines before showing this field, which is how
20
20
  * the confusion got manufactured in the first place.
21
21
  */
22
- const DEV_SERVER_PORTS = new Set([
22
+ export const DEV_SERVER_PORTS = new Set([
23
23
  3000, 3001, 4200, 4321, 5000, 5173, 5174, 8000, 8080, 8100, 9000,
24
24
  ]);
25
25
  export function isLikelyDevServerPort(port) {
@@ -37,9 +37,9 @@ export function readProjectPort(cwd) {
37
37
  try {
38
38
  const raw = readFileSync(`${cwd}/.reticle.json`, 'utf8');
39
39
  const config = JSON.parse(raw);
40
- if (typeof config === 'object' && config !== null) {
40
+ if ('object' === typeof config && config !== null) {
41
41
  const p = config['port'];
42
- if (typeof p === 'number' && Number.isInteger(p) && p > 0 && p < 65536)
42
+ if ('number' === typeof p && Number.isInteger(p) && p > 0 && p < 65536)
43
43
  return p;
44
44
  }
45
45
  }
@@ -57,9 +57,9 @@ export function readProjectId(cwd) {
57
57
  try {
58
58
  const raw = readFileSync(`${cwd}/.reticle.json`, 'utf8');
59
59
  const config = JSON.parse(raw);
60
- if (typeof config === 'object' && config !== null) {
60
+ if ('object' === typeof config && config !== null) {
61
61
  const id = config['projectId'];
62
- if (typeof id === 'string' && id.length > 0)
62
+ if ('string' === typeof id && id.length > 0)
63
63
  return id;
64
64
  }
65
65
  }
@@ -76,16 +76,16 @@ export function readProjectId(cwd) {
76
76
  export function readJournalEnabled(cwd, env) {
77
77
  if (env !== undefined) {
78
78
  const v = env.trim().toLowerCase();
79
- if (v === '0' || v === 'false' || v === 'off')
79
+ if ('0' === v || 'false' === v || 'off' === v)
80
80
  return false;
81
- if (v === '1' || v === 'true' || v === 'on')
81
+ if ('1' === v || 'true' === v || 'on' === v)
82
82
  return true;
83
83
  }
84
84
  try {
85
85
  const raw = readFileSync(`${cwd}/.reticle.json`, 'utf8');
86
86
  const config = JSON.parse(raw);
87
- if (typeof config === 'object' && config !== null) {
88
- if (config['journal'] === false)
87
+ if ('object' === typeof config && config !== null) {
88
+ if (false === config['journal'])
89
89
  return false;
90
90
  }
91
91
  }
@@ -0,0 +1,4 @@
1
+ /** `reticle update` — install the latest server version, sync the app's SDK, and restart. */
2
+ export declare function handleUpdate(): Promise<void>;
3
+ /** `reticle rollback` — restore the previous server version and restart. */
4
+ export declare function handleRollback(): Promise<void>;