@reticlehq/server 2.3.0 → 2.5.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 (424) hide show
  1. package/SKILL.md +702 -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} +1 -1
  7. package/dist/{bridge.js → bridge/bridge.js} +105 -15
  8. package/dist/{bridge.test-harness.d.ts → bridge/bridge.test-harness.d.ts} +6 -11
  9. package/dist/{bridge.test-harness.js → bridge/bridge.test-harness.js} +21 -9
  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-doctor.js → cli/cli-doctor.js} +9 -2
  20. package/dist/{cli-flow-commands.d.ts → cli/cli-flow-commands.d.ts} +2 -2
  21. package/dist/{cli-flow-commands.js → cli/cli-flow-commands.js} +15 -15
  22. package/dist/{cli-launch.d.ts → cli/cli-launch.d.ts} +32 -3
  23. package/dist/cli/cli-launch.js +171 -0
  24. package/dist/cli/cli-parse.d.ts +143 -0
  25. package/dist/{cli-parse.js → cli/cli-parse.js} +146 -65
  26. package/dist/{cli-port.d.ts → cli/cli-port.d.ts} +15 -0
  27. package/dist/{cli-port.js → cli/cli-port.js} +29 -8
  28. package/dist/cli/cli-update-commands.d.ts +4 -0
  29. package/dist/cli/cli-update-commands.js +93 -0
  30. package/dist/{cli-verify.js → cli/cli-verify.js} +14 -14
  31. package/dist/{cloud-cli.js → cli/cloud-cli.js} +29 -24
  32. package/dist/cli.d.ts +2 -2
  33. package/dist/cli.js +182 -93
  34. package/dist/cloud/cloud-config.d.ts +0 -1
  35. package/dist/cloud/cloud-config.js +9 -9
  36. package/dist/cloud/cloud-sync.d.ts +1 -7
  37. package/dist/cloud/cloud-sync.js +12 -12
  38. package/dist/crawl/crawl-empty.d.ts +16 -0
  39. package/dist/crawl/crawl-empty.js +24 -0
  40. package/dist/crawl/crawl-tools.js +4 -1
  41. package/dist/crawl/crawl.js +26 -7
  42. package/dist/daemon/daemon-resilience.d.ts +49 -0
  43. package/dist/daemon/daemon-resilience.js +191 -0
  44. package/dist/daemon/daemon-usefulness.d.ts +61 -0
  45. package/dist/daemon/daemon-usefulness.js +62 -0
  46. package/dist/{daemon.d.ts → daemon/daemon.d.ts} +33 -8
  47. package/dist/{daemon.js → daemon/daemon.js} +80 -48
  48. package/dist/daemon/idle-grace.d.ts +32 -0
  49. package/dist/daemon/idle-grace.js +41 -0
  50. package/dist/{idle-shutdown.d.ts → daemon/idle-shutdown.d.ts} +13 -0
  51. package/dist/{idle-shutdown.js → daemon/idle-shutdown.js} +27 -4
  52. package/dist/domain/domain-model.js +2 -2
  53. package/dist/events/body-failures.js +8 -8
  54. package/dist/events/contradictions.d.ts +1 -1
  55. package/dist/events/contradictions.js +60 -10
  56. package/dist/events/echo-mismatch.js +10 -10
  57. package/dist/events/event-filters.js +6 -6
  58. package/dist/events/json-salvage.d.ts +2 -1
  59. package/dist/events/json-salvage.js +6 -6
  60. package/dist/events/observed-in-window.d.ts +12 -0
  61. package/dist/events/observed-in-window.js +21 -0
  62. package/dist/events/predicate-eval.d.ts +43 -20
  63. package/dist/events/predicate-eval.js +159 -55
  64. package/dist/events/predicate.d.ts +2 -2
  65. package/dist/events/predicate.js +112 -35
  66. package/dist/events/reconcile.js +5 -5
  67. package/dist/events/ring-buffer.js +1 -1
  68. package/dist/events/stale-response.js +6 -6
  69. package/dist/events/testid-near-miss.d.ts +22 -0
  70. package/dist/events/testid-near-miss.js +33 -0
  71. package/dist/events/unit-mismatch.js +8 -8
  72. package/dist/flows/affected-tools.js +19 -4
  73. package/dist/flows/affected.js +1 -1
  74. package/dist/flows/annotate-target.d.ts +1 -0
  75. package/dist/flows/annotate-target.js +20 -0
  76. package/dist/flows/annotate-tools.js +25 -3
  77. package/dist/flows/annotate.js +17 -4
  78. package/dist/flows/assertion-integrity.d.ts +2 -1
  79. package/dist/flows/assertion-tiers-store.d.ts +3 -66
  80. package/dist/flows/assertion-tiers-store.js +2 -2
  81. package/dist/flows/attributed-failure.d.ts +17 -0
  82. package/dist/flows/attributed-failure.js +20 -0
  83. package/dist/flows/buddy-status.d.ts +2 -1
  84. package/dist/flows/buddy-status.js +2 -2
  85. package/dist/flows/coverage.d.ts +3 -2
  86. package/dist/flows/coverage.js +2 -2
  87. package/dist/flows/decision.d.ts +0 -6
  88. package/dist/flows/decision.js +64 -8
  89. package/dist/flows/empty-flow.d.ts +6 -0
  90. package/dist/flows/empty-flow.js +24 -0
  91. package/dist/flows/flake-store.d.ts +0 -1
  92. package/dist/flows/flake-store.js +1 -1
  93. package/dist/flows/flake.d.ts +2 -1
  94. package/dist/flows/flake.js +2 -2
  95. package/dist/flows/flow-classify.js +12 -0
  96. package/dist/flows/flow-replay-run.js +4 -4
  97. package/dist/flows/flow-replay.d.ts +5 -7
  98. package/dist/flows/flow-replay.js +114 -47
  99. package/dist/flows/flow-report.js +1 -1
  100. package/dist/flows/flow-scope.d.ts +1 -6
  101. package/dist/flows/flow-step-runners.d.ts +26 -6
  102. package/dist/flows/flow-step-runners.js +157 -6
  103. package/dist/flows/flow-success.js +20 -15
  104. package/dist/flows/flow-tools.js +67 -13
  105. package/dist/flows/flows.js +15 -11
  106. package/dist/flows/gate.d.ts +4 -3
  107. package/dist/flows/gate.js +1 -1
  108. package/dist/flows/heal-run.d.ts +0 -8
  109. package/dist/flows/heal-run.js +5 -5
  110. package/dist/flows/heal.js +3 -3
  111. package/dist/flows/predicate-to-expect.d.ts +38 -0
  112. package/dist/flows/predicate-to-expect.js +95 -0
  113. package/dist/flows/replay.d.ts +16 -1
  114. package/dist/flows/replay.js +58 -22
  115. package/dist/flows/role-anchor-nearest.d.ts +6 -0
  116. package/dist/flows/role-anchor-nearest.js +45 -0
  117. package/dist/flows/server-verify.d.ts +1 -1
  118. package/dist/flows/server-verify.js +5 -5
  119. package/dist/flows/verify-change-tools.js +32 -10
  120. package/dist/flows/verify-change-verdict.d.ts +15 -0
  121. package/dist/flows/verify-change-verdict.js +25 -0
  122. package/dist/flows/watch-batcher.d.ts +3 -2
  123. package/dist/honesty/already-true.d.ts +2 -0
  124. package/dist/honesty/already-true.js +31 -0
  125. package/dist/honesty/blind-spots.d.ts +16 -3
  126. package/dist/honesty/blind-spots.js +24 -12
  127. package/dist/honesty/honesty.d.ts +3 -2
  128. package/dist/honesty/honesty.js +4 -4
  129. package/dist/honesty/uncaptured-bodies.js +1 -1
  130. package/dist/honesty/unread-outcome.js +2 -2
  131. package/dist/honesty/verified.d.ts +22 -3
  132. package/dist/honesty/verified.js +48 -8
  133. package/dist/http-server.js +14 -7
  134. package/dist/hunt/hunt-report.d.ts +2 -1
  135. package/dist/hunt/hunt-report.js +2 -2
  136. package/dist/index.d.ts +8 -6
  137. package/dist/index.js +32 -25
  138. package/dist/init/agent-rules.d.ts +2 -1
  139. package/dist/init/agent-rules.js +45 -7
  140. package/dist/init/app-choice.d.ts +20 -0
  141. package/dist/init/app-choice.js +25 -0
  142. package/dist/init/astro-host.d.ts +21 -0
  143. package/dist/init/astro-host.js +27 -0
  144. package/dist/init/astro-patch.d.ts +16 -0
  145. package/dist/init/astro-patch.js +240 -0
  146. package/dist/init/capabilities.d.ts +17 -0
  147. package/dist/init/capabilities.js +54 -0
  148. package/dist/init/cra.d.ts +37 -0
  149. package/dist/init/cra.js +90 -0
  150. package/dist/init/cursor.js +39 -4
  151. package/dist/init/desktop-doctor.d.ts +3 -2
  152. package/dist/init/desktop-doctor.js +4 -4
  153. package/dist/init/detect.d.ts +26 -0
  154. package/dist/init/detect.js +78 -5
  155. package/dist/init/mcp-registered.d.ts +12 -0
  156. package/dist/init/mcp-registered.js +14 -0
  157. package/dist/init/mcp.d.ts +27 -2
  158. package/dist/init/mcp.js +40 -4
  159. package/dist/init/next-patch.d.ts +39 -0
  160. package/dist/init/next-patch.js +196 -0
  161. package/dist/init/node-io.js +48 -6
  162. package/dist/init/patch-kind.d.ts +20 -0
  163. package/dist/init/patch-kind.js +10 -0
  164. package/dist/init/plan-framework.d.ts +50 -0
  165. package/dist/init/plan-framework.js +341 -0
  166. package/dist/init/plan.d.ts +119 -6
  167. package/dist/init/plan.js +230 -131
  168. package/dist/init/project-id.d.ts +5 -9
  169. package/dist/init/project-id.js +10 -22
  170. package/dist/init/run.d.ts +22 -0
  171. package/dist/init/run.js +393 -28
  172. package/dist/init/slash-command.d.ts +27 -0
  173. package/dist/init/slash-command.js +61 -0
  174. package/dist/init/snippets.d.ts +41 -3
  175. package/dist/init/snippets.js +185 -10
  176. package/dist/init/vite-config.d.ts +4 -10
  177. package/dist/init/vite-config.js +15 -7
  178. package/dist/init/workspace-apps.d.ts +23 -0
  179. package/dist/init/workspace-apps.js +68 -0
  180. package/dist/input/driven-redaction.d.ts +15 -0
  181. package/dist/input/driven-redaction.js +76 -0
  182. package/dist/input/network-detail.d.ts +9 -3
  183. package/dist/input/network-detail.js +43 -23
  184. package/dist/input/network-mock-tools.js +2 -2
  185. package/dist/input/network-mock.js +4 -4
  186. package/dist/input/real-input.js +8 -3
  187. package/dist/input/scroll-find.js +2 -2
  188. package/dist/input/scroll-tools.d.ts +0 -5
  189. package/dist/input/scroll-tools.js +11 -4
  190. package/dist/input/viewport-tools.js +2 -2
  191. package/dist/journal/ambient-store.d.ts +0 -2
  192. package/dist/journal/ambient-store.js +1 -1
  193. package/dist/journal/ambient.js +1 -1
  194. package/dist/journal/attach-journal.d.ts +2 -1
  195. package/dist/journal/deviation-report.js +6 -6
  196. package/dist/journal/deviation-service.js +1 -1
  197. package/dist/journal/envelope-store.d.ts +0 -2
  198. package/dist/journal/envelope-store.js +1 -1
  199. package/dist/journal/envelope.d.ts +2 -3
  200. package/dist/journal/envelope.js +3 -3
  201. package/dist/journal/journal-query.js +1 -1
  202. package/dist/journal/journal-recorder.d.ts +2 -1
  203. package/dist/journal/journal-recorder.js +2 -2
  204. package/dist/journal/rollups.js +9 -9
  205. package/dist/journal/session-end.d.ts +2 -1
  206. package/dist/journal/session-journal.js +4 -4
  207. package/dist/license/license.d.ts +0 -14
  208. package/dist/license/license.js +8 -8
  209. package/dist/log.d.ts +10 -0
  210. package/dist/log.js +11 -1
  211. package/dist/mcp/mcp-is-error.d.ts +13 -0
  212. package/dist/mcp/mcp-is-error.js +18 -0
  213. package/dist/mcp/mcp-outage.d.ts +31 -0
  214. package/dist/mcp/mcp-outage.js +48 -0
  215. package/dist/mcp/mcp-proxy.d.ts +124 -0
  216. package/dist/mcp/mcp-proxy.js +697 -0
  217. package/dist/{mcp.d.ts → mcp/mcp.d.ts} +13 -10
  218. package/dist/{mcp.js → mcp/mcp.js} +110 -35
  219. package/dist/mcp/proxy-handshake.d.ts +3 -0
  220. package/dist/mcp/proxy-handshake.js +54 -0
  221. package/dist/mcp/proxy-lifecycle.d.ts +64 -0
  222. package/dist/mcp/proxy-lifecycle.js +70 -0
  223. package/dist/mcp/tool-catalog-cache.d.ts +29 -0
  224. package/dist/mcp/tool-catalog-cache.js +55 -0
  225. package/dist/oracles/propose-consequences.d.ts +2 -1
  226. package/dist/oracles/propose-consequences.js +16 -11
  227. package/dist/oracles/self-instrument.d.ts +2 -1
  228. package/dist/oracles/self-instrument.js +1 -1
  229. package/dist/phenomena/phenomena.js +3 -3
  230. package/dist/platform.d.ts +16 -0
  231. package/dist/platform.js +16 -0
  232. package/dist/pool/playwright-launcher.d.ts +15 -2
  233. package/dist/pool/playwright-launcher.js +21 -2
  234. package/dist/project/fs-port.js +1 -1
  235. package/dist/project/project-tools.js +2 -2
  236. package/dist/runs/build-verification-run.js +1 -1
  237. package/dist/runs/repair-prompt.d.ts +0 -6
  238. package/dist/runs/repair-prompt.js +3 -3
  239. package/dist/runs/risk-classify.js +1 -1
  240. package/dist/runs/run-diff.d.ts +0 -2
  241. package/dist/runs/run-diff.js +3 -3
  242. package/dist/runs/run-tools.js +2 -2
  243. package/dist/runs/verification-sync.js +2 -2
  244. package/dist/runs/verify-http.js +1 -1
  245. package/dist/runs/verify-server.js +1 -1
  246. package/dist/session/command-timeout.d.ts +11 -3
  247. package/dist/session/command-timeout.js +2 -2
  248. package/dist/session/control-envelope.d.ts +6 -0
  249. package/dist/session/control-envelope.js +7 -1
  250. package/dist/session/dev-server-probe.d.ts +13 -0
  251. package/dist/session/dev-server-probe.js +52 -0
  252. package/dist/session/last-act.d.ts +17 -3
  253. package/dist/session/last-act.js +16 -4
  254. package/dist/session/live-control-tools.js +7 -2
  255. package/dist/session/live-control.js +1 -1
  256. package/dist/session/looks-like-dev-server.d.ts +14 -0
  257. package/dist/session/looks-like-dev-server.js +25 -0
  258. package/dist/session/no-session-diagnosis.d.ts +38 -0
  259. package/dist/session/no-session-diagnosis.js +70 -0
  260. package/dist/session/no-session-watch.d.ts +19 -0
  261. package/dist/session/no-session-watch.js +61 -0
  262. package/dist/session/observed-state.d.ts +4 -0
  263. package/dist/session/observed-state.js +19 -1
  264. package/dist/session/output-budget.js +1 -1
  265. package/dist/session/session-health.d.ts +8 -1
  266. package/dist/session/session-health.js +8 -7
  267. package/dist/session/session-info.d.ts +26 -7
  268. package/dist/session/session-info.js +42 -1
  269. package/dist/session/session-lease.d.ts +0 -11
  270. package/dist/session/session-lease.js +1 -1
  271. package/dist/session/session-manager.d.ts +3 -0
  272. package/dist/session/session-manager.js +58 -9
  273. package/dist/session/session-readiness.d.ts +1 -1
  274. package/dist/session/session-readiness.js +6 -1
  275. package/dist/session/session-reaper.js +1 -1
  276. package/dist/session/session-reconnect.d.ts +32 -0
  277. package/dist/session/session-reconnect.js +42 -0
  278. package/dist/session/session.d.ts +20 -2
  279. package/dist/session/session.js +76 -26
  280. package/dist/session/state-select.d.ts +1 -1
  281. package/dist/session/state-select.js +1 -1
  282. package/dist/status-payload.d.ts +19 -0
  283. package/dist/status-payload.js +11 -0
  284. package/dist/telemetry/argument-shape.js +10 -1
  285. package/dist/telemetry/browser-mode.d.ts +27 -0
  286. package/dist/telemetry/browser-mode.js +33 -0
  287. package/dist/telemetry/bug-found.d.ts +17 -21
  288. package/dist/telemetry/bug-found.js +120 -8
  289. package/dist/telemetry/cli-telemetry.d.ts +2 -12
  290. package/dist/telemetry/cli-telemetry.js +27 -4
  291. package/dist/telemetry/daemon-telemetry.d.ts +19 -0
  292. package/dist/telemetry/daemon-telemetry.js +12 -2
  293. package/dist/telemetry/dev-repo.js +4 -4
  294. package/dist/telemetry/error-fingerprint.js +21 -2
  295. package/dist/telemetry/feedback-cli.d.ts +1 -1
  296. package/dist/telemetry/feedback-cli.js +4 -4
  297. package/dist/telemetry/feedback-context.d.ts +22 -0
  298. package/dist/telemetry/feedback-context.js +41 -1
  299. package/dist/telemetry/feedback-delivery.d.ts +20 -0
  300. package/dist/telemetry/feedback-delivery.js +30 -0
  301. package/dist/telemetry/feedback-outbox.d.ts +22 -0
  302. package/dist/telemetry/feedback-outbox.js +87 -0
  303. package/dist/telemetry/feedback.d.ts +22 -1
  304. package/dist/telemetry/feedback.js +67 -8
  305. package/dist/telemetry/git-facts.js +1 -1
  306. package/dist/telemetry/session-metrics.d.ts +2 -0
  307. package/dist/telemetry/session-metrics.js +68 -6
  308. package/dist/telemetry/telemetry.d.ts +27 -2
  309. package/dist/telemetry/telemetry.js +119 -29
  310. package/dist/telemetry/verification-of.d.ts +22 -0
  311. package/dist/telemetry/verification-of.js +84 -0
  312. package/dist/tools/act-capsule.js +2 -2
  313. package/dist/tools/act-danger.d.ts +12 -0
  314. package/dist/tools/act-danger.js +20 -3
  315. package/dist/tools/act-helpers.js +4 -4
  316. package/dist/tools/act-tools.d.ts +0 -8
  317. package/dist/tools/act-tools.js +84 -115
  318. package/dist/tools/act-view.js +7 -7
  319. package/dist/tools/alias-args.d.ts +17 -0
  320. package/dist/tools/alias-args.js +25 -0
  321. package/dist/tools/assert-grade.js +9 -9
  322. package/dist/tools/assert-verdict.d.ts +3 -1
  323. package/dist/tools/assert-verdict.js +8 -5
  324. package/dist/tools/browser-tools.js +30 -11
  325. package/dist/tools/contract-tools.js +1 -1
  326. package/dist/tools/coverage-identity.d.ts +34 -0
  327. package/dist/tools/coverage-identity.js +46 -0
  328. package/dist/tools/coverage-tools.js +10 -14
  329. package/dist/tools/dynamic-tools.d.ts +2 -1
  330. package/dist/tools/dynamic-tools.js +90 -18
  331. package/dist/tools/error-recovery.d.ts +20 -2
  332. package/dist/tools/error-recovery.js +179 -4
  333. package/dist/tools/feedback-tools.d.ts +12 -1
  334. package/dist/tools/feedback-tools.js +28 -5
  335. package/dist/tools/invoke-tool.d.ts +0 -6
  336. package/dist/tools/invoke-tool.js +57 -32
  337. package/dist/tools/lease-hint.d.ts +17 -0
  338. package/dist/tools/lease-hint.js +24 -0
  339. package/dist/tools/lease-tools.js +6 -5
  340. package/dist/tools/merge-tools.d.ts +10 -1
  341. package/dist/tools/merge-tools.js +9 -3
  342. package/dist/tools/merged-name-redirect.d.ts +13 -0
  343. package/dist/tools/merged-name-redirect.js +55 -0
  344. package/dist/tools/navigate-result.d.ts +17 -0
  345. package/dist/tools/navigate-result.js +31 -0
  346. package/dist/tools/observe-tools.js +54 -20
  347. package/dist/tools/observed-nothing.d.ts +25 -0
  348. package/dist/tools/observed-nothing.js +33 -0
  349. package/dist/tools/query-paginate.js +2 -2
  350. package/dist/tools/query-shape.d.ts +18 -0
  351. package/dist/tools/query-shape.js +39 -0
  352. package/dist/tools/read-tools.js +85 -20
  353. package/dist/tools/real-input-attempt.d.ts +28 -0
  354. package/dist/tools/real-input-attempt.js +88 -0
  355. package/dist/tools/reconcile-tools.js +7 -7
  356. package/dist/tools/reload-result.d.ts +14 -0
  357. package/dist/tools/reload-result.js +29 -0
  358. package/dist/tools/snapshot-delta.d.ts +4 -5
  359. package/dist/tools/snapshot-delta.js +0 -0
  360. package/dist/tools/tool-kit.d.ts +8 -0
  361. package/dist/tools/tool-surface.d.ts +83 -0
  362. package/dist/tools/tool-surface.js +204 -0
  363. package/dist/tools/tools-helpers.js +6 -6
  364. package/dist/tools/tools.d.ts +15 -0
  365. package/dist/tools/tools.js +53 -17
  366. package/dist/tools/unadvertised-help.d.ts +5 -0
  367. package/dist/tools/unadvertised-help.js +39 -0
  368. package/dist/trace.d.ts +69 -0
  369. package/dist/trace.js +150 -0
  370. package/dist/update/nudge-credit.d.ts +4 -0
  371. package/dist/update/nudge-credit.js +53 -0
  372. package/dist/update/sdk-sync.d.ts +21 -0
  373. package/dist/update/sdk-sync.js +42 -0
  374. package/dist/update/update-checker.js +3 -3
  375. package/dist/update/update-nudge.d.ts +63 -6
  376. package/dist/update/update-nudge.js +128 -15
  377. package/dist/update/updater.d.ts +1 -9
  378. package/dist/update/updater.js +13 -8
  379. package/dist/version/peer-announce.d.ts +4 -0
  380. package/dist/version/peer-announce.js +30 -0
  381. package/dist/{server-version.js → version/server-version.js} +5 -1
  382. package/dist/version/version-nudge.d.ts +28 -0
  383. package/dist/version/version-nudge.js +40 -0
  384. package/dist/version/version-skew.d.ts +66 -0
  385. package/dist/version/version-skew.js +71 -0
  386. package/dist/visual/visual-diff.js +2 -2
  387. package/dist/visual/visual-tools.js +4 -4
  388. package/docs/agent-cheatsheet.md +85 -0
  389. package/docs/architecture.md +113 -0
  390. package/docs/benchmarks.md +255 -0
  391. package/docs/debugging.md +102 -0
  392. package/docs/deploy-checks.md +69 -0
  393. package/docs/desktop-apps.md +256 -0
  394. package/docs/enterprise.md +62 -0
  395. package/docs/fixtures.md +28 -0
  396. package/docs/flows.md +166 -0
  397. package/docs/getting-started.md +469 -0
  398. package/docs/human-control.md +63 -0
  399. package/docs/integration-patterns.md +171 -0
  400. package/docs/local-registry.md +126 -0
  401. package/docs/mint.json +61 -0
  402. package/docs/multi-agent-testing.md +55 -0
  403. package/docs/platform-integration.md +122 -0
  404. package/docs/telemetry-contract.md +214 -0
  405. package/docs/telemetry.md +184 -0
  406. package/docs/testing.md +82 -0
  407. package/docs/token-efficiency.md +80 -0
  408. package/docs/usage.md +1046 -0
  409. package/package.json +8 -5
  410. package/dist/cli-launch.js +0 -112
  411. package/dist/cli-parse.d.ts +0 -140
  412. package/dist/daemon-resilience.d.ts +0 -22
  413. package/dist/daemon-resilience.js +0 -85
  414. package/dist/mcp-proxy.d.ts +0 -35
  415. package/dist/mcp-proxy.js +0 -190
  416. package/dist/tools/profiles.d.ts +0 -37
  417. package/dist/tools/profiles.js +0 -139
  418. /package/dist/{pairing-token.d.ts → bridge/pairing-token.d.ts} +0 -0
  419. /package/dist/{token-auth.d.ts → bridge/token-auth.d.ts} +0 -0
  420. /package/dist/{token-auth.js → bridge/token-auth.js} +0 -0
  421. /package/dist/{cli-doctor.d.ts → cli/cli-doctor.d.ts} +0 -0
  422. /package/dist/{cli-verify.d.ts → cli/cli-verify.d.ts} +0 -0
  423. /package/dist/{cloud-cli.d.ts → cli/cloud-cli.d.ts} +0 -0
  424. /package/dist/{server-version.d.ts → version/server-version.d.ts} +0 -0
@@ -1,3 +1,4 @@
1
+ import { ConsequenceKind, PredicateKind } from '@reticlehq/core';
1
2
  /**
2
3
  * Convert a mustHold predicate into the ordered ExpectedLinks the divergence capsule walks. Only the
3
4
  * consequence kinds (signal/net/state) become links — a presence check (element/text) can't diverge in a
@@ -5,24 +6,26 @@
5
6
  */
6
7
  export function predicateToExpectedLinks(predicate) {
7
8
  switch (predicate.kind) {
8
- case 'signal':
9
- return predicate.name === undefined ? [] : [{ kind: 'signal', name: predicate.name }];
10
- case 'net':
9
+ case PredicateKind.SIGNAL:
10
+ return predicate.name === undefined
11
+ ? []
12
+ : [{ kind: ConsequenceKind.SIGNAL, name: predicate.name }];
13
+ case PredicateKind.NET:
11
14
  return predicate.urlContains === undefined
12
15
  ? []
13
16
  : [
14
17
  {
15
- kind: 'net',
18
+ kind: ConsequenceKind.NET,
16
19
  urlContains: predicate.urlContains,
17
20
  ...(predicate.status === undefined ? {} : { status: predicate.status }),
18
21
  },
19
22
  ];
20
- case 'state': {
23
+ case PredicateKind.STATE: {
21
24
  const name = predicate.store ?? predicate.path;
22
- return [{ kind: 'state', name }];
25
+ return [{ kind: ConsequenceKind.STATE, name }];
23
26
  }
24
- case 'allOf':
25
- case 'anyOf':
27
+ case PredicateKind.ALL_OF:
28
+ case PredicateKind.ANY_OF:
26
29
  return predicate.predicates.flatMap(predicateToExpectedLinks);
27
30
  default:
28
31
  return [];
@@ -1,7 +1,8 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- import { readPid, isAlive } from './daemon.js';
4
- import { diagnoseDesktop, isDesktopProject } from './init/desktop-doctor.js';
3
+ import { ReticleEnv } from '@reticlehq/core';
4
+ import { readPid, isAlive, reticleStateHome } from '../daemon/daemon.js';
5
+ import { diagnoseDesktop, isDesktopProject } from '../init/desktop-doctor.js';
5
6
  /**
6
7
  * `reticle doctor` — collapse the ~6 independent first-run failure modes into one command. Checks the
7
8
  * Chromium install (the #1 silent failure), whether a daemon is up on the resolved bridge port, and
@@ -31,6 +32,12 @@ export async function handleDoctor(port) {
31
32
  line(` daemon ✗ not running on :${port} — your agent runs \`reticle mcp\` (or \`reticle serve\`)`);
32
33
  }
33
34
  line(` bridge port ${port} (your app must dial THIS port — not your dev-server port)`);
35
+ // Where to LOOK when something is wrong. The daemon has always written a structured log here and
36
+ // nothing ever said so, so the first move in every investigation was reading source instead of
37
+ // reading the log. `RETICLE_TRACE=1` turns the same stream into a per-stage trace — see
38
+ // docs/debugging.md.
39
+ line(` daemon log ${join(reticleStateHome(), `daemon-${String(port)}.log`)}`);
40
+ line(` tracing ${ReticleEnv.TRACE}=1 on the daemon for per-stage timings in that log`);
34
41
  // Desktop setup RCA. Every one of these fails SILENTLY — a Tauri app with the default CSP runs
35
42
  // perfectly and never connects; an Electron app without the preload line reports zero network
36
43
  // activity forever, which reads as "makes no backend calls" rather than "you are blind to them".
@@ -5,8 +5,8 @@
5
5
  * opens first. These five functions form one cohesive group: they all read the flow store and report on
6
6
  * verification state, and none of them touch daemon lifecycle, which is what the rest of cli.ts does.
7
7
  */
8
- import { type FileSystemPort } from './project/fs-port.js';
9
- import { type NamedFlow } from './flows/flow-sources.js';
8
+ import { type FileSystemPort } from '../project/fs-port.js';
9
+ import { type NamedFlow } from '../flows/flow-sources.js';
10
10
  /** Load the {name, steps} of every saved flow for the active project. */
11
11
  /** Explicit files plus, when --since is given, the git-changed files since that ref. */
12
12
  export declare function resolveChangedFiles(files: string[], since: string | undefined): Promise<string[]>;
@@ -6,23 +6,23 @@
6
6
  * verification state, and none of them touch daemon lifecycle, which is what the rest of cli.ts does.
7
7
  */
8
8
  import { readProjectId } from './cli-port.js';
9
- import { changedFilesSince } from './flows/git-changed.js';
9
+ import { changedFilesSince } from '../flows/git-changed.js';
10
10
  import { join } from 'node:path';
11
11
  import { ReticleDir, RunFlowStatus } from '@reticlehq/core';
12
- import { FlowStore } from './flows/flows.js';
13
- import { RunStore } from './runs/run-store.js';
14
- import { createNodeFileSystem } from './project/fs-port.js';
15
- import { affectedSavedFlows } from './flows/flow-sources.js';
16
- import { gateDecision } from './flows/gate.js';
17
- import { FlakeStore } from './flows/flake-store.js';
18
- import { formatBuddyStatus } from './flows/buddy-status.js';
19
- import { CapsuleStore } from './capsule/capsule-store.js';
20
- import { AssertionTiersStore } from './flows/assertion-tiers-store.js';
21
- import { detectDowngrades } from './flows/assertion-integrity.js';
22
- import { computeCoverage } from './flows/coverage.js';
23
- import { createWatchBatcher } from './flows/watch-batcher.js';
12
+ import { FlowStore } from '../flows/flows.js';
13
+ import { RunStore } from '../runs/run-store.js';
14
+ import { createNodeFileSystem } from '../project/fs-port.js';
15
+ import { affectedSavedFlows } from '../flows/flow-sources.js';
16
+ import { gateDecision } from '../flows/gate.js';
17
+ import { FlakeStore } from '../flows/flake-store.js';
18
+ import { formatBuddyStatus } from '../flows/buddy-status.js';
19
+ import { CapsuleStore } from '../capsule/capsule-store.js';
20
+ import { AssertionTiersStore } from '../flows/assertion-tiers-store.js';
21
+ import { detectDowngrades } from '../flows/assertion-integrity.js';
22
+ import { computeCoverage } from '../flows/coverage.js';
23
+ import { createWatchBatcher } from '../flows/watch-batcher.js';
24
24
  import { watch } from 'node:fs';
25
- import { log } from './log.js';
25
+ import { log } from '../log.js';
26
26
  /** Load the {name, steps} of every saved flow for the active project. */
27
27
  /** Explicit files plus, when --since is given, the git-changed files since that ref. */
28
28
  export async function resolveChangedFiles(files, since) {
@@ -107,7 +107,7 @@ export function handleWatch() {
107
107
  .then((flows) => emitBuddyStatus(fs, reticleRoot, flows, []))
108
108
  .catch(() => undefined);
109
109
  watch(process.cwd(), { recursive: true }, (_event, filename) => {
110
- if (typeof filename === 'string' && WATCHED_EXTENSIONS.test(filename))
110
+ if ('string' === typeof filename && WATCHED_EXTENSIONS.test(filename))
111
111
  batcher.onChange(filename);
112
112
  });
113
113
  }
@@ -20,12 +20,26 @@ export declare function summarizeStatus(payload: unknown): {
20
20
  sessionCount: number;
21
21
  sessions: StatusSession[];
22
22
  };
23
+ /**
24
+ * Warn when the daemon already on this port is a different version than this CLI, and attach anyway.
25
+ *
26
+ * Attaching to whatever owns the port is the point of a daemon — but it means an upgrade does not
27
+ * take effect until that daemon dies, and nothing used to say so. Killing it here would take out
28
+ * another agent's session on a version bump, which is worse than a loud line.
29
+ */
30
+ export declare function warnOnDaemonSkew(port: number): Promise<void>;
23
31
  /** GET the daemon's /status JSON. Resolves to the parsed body, or undefined on any failure. */
24
32
  export declare function fetchStatus(port: number): Promise<unknown>;
25
33
  /** What `reticle open` should do: reuse an already-connected tab, open a new one, or ask for a url. */
26
34
  type OpenDecision = {
27
35
  action: 'reuse';
28
36
  url: string;
37
+ }
38
+ /** A tab on that origin exists, but on another page — kept, and NOT reported as done. */
39
+ | {
40
+ action: 'left-as-is';
41
+ url: string;
42
+ requested: string;
29
43
  } | {
30
44
  action: 'open';
31
45
  url: string;
@@ -36,8 +50,16 @@ type OpenDecision = {
36
50
  * Decide what `reticle open [url]` does, given the currently-connected tabs. Pure.
37
51
  * - no url + a tab connected → reuse it (the app is already open; don't spawn a duplicate).
38
52
  * - no url + nothing connected → ask for one.
39
- * - url + a tab already on that origin → reuse it (idempotent — re-running never piles up tabs).
53
+ * - url + a tab already AT that url → reuse it (idempotent — re-running never piles up tabs).
54
+ * - url + a tab on that origin but another page → keep it, and say so (`left-as-is`).
40
55
  * - url + no matching tab → open it.
56
+ *
57
+ * The origin match is why re-running this never piles up tabs, and it stays. What changed is the
58
+ * REPORT: matching by origin meant `reticle open http://localhost:3000/settings` answered `reusing`
59
+ * for a tab sitting on `http://localhost:3000/` and exited 0, so the caller read a success for a page
60
+ * that was never opened. Navigating the tab instead was the other option and is worse: `reticle open`
61
+ * is run by a human whose browser this is, and yanking the page they are looking at to somewhere else
62
+ * is a bigger surprise than being told where the tab actually is.
41
63
  */
42
64
  export declare function decideOpen(sessions: {
43
65
  url: string;
@@ -47,6 +69,13 @@ export declare function openCommand(url: string, platform: NodeJS.Platform): {
47
69
  cmd: string;
48
70
  args: string[];
49
71
  };
50
- /** Launch the default browser at `url` (detached). The spawn is injected so tests stay hermetic. */
51
- export declare function openInBrowser(url: string, platform?: NodeJS.Platform, run?: (cmd: string, args: string[]) => void): void;
72
+ /**
73
+ * Launch the default browser at `url` (detached). The spawn is injected so tests stay hermetic.
74
+ *
75
+ * Resolves to whether the launch COMMAND started — not to whether a page appeared. It used to return
76
+ * nothing at all and the caller printed `{"opened": url}` unconditionally, so a launcher that failed
77
+ * outright still reported success. Reported from the field as twenty minutes lost chasing a phantom
78
+ * port problem while nothing had ever opened.
79
+ */
80
+ export declare function openInBrowser(url: string, platform?: NodeJS.Platform, run?: (cmd: string, args: string[]) => Promise<string | null>): Promise<string | null>;
52
81
  export {};
@@ -0,0 +1,171 @@
1
+ import * as http from 'node:http';
2
+ import { NodePlatform } from '../platform.js';
3
+ import { spawn } from 'node:child_process';
4
+ import { isOpaqueOrigin, LOOPBACK_HOST, STATUS_PATH } from '@reticlehq/core';
5
+ import { describeSkew, DAEMON_FIX } from '../version/version-skew.js';
6
+ import { CONTRACT_FINGERPRINT } from '@reticlehq/core';
7
+ import { SERVER_VERSION } from '../version/server-version.js';
8
+ import { log } from '../log.js';
9
+ /**
10
+ * Reduce the daemon's /status JSON to the compact view `reticle status` prints. Pure: narrows the
11
+ * untrusted wire payload (never `any`) and tolerates a missing/partial body so a malformed response
12
+ * degrades to "running, 0 sessions" instead of throwing.
13
+ */
14
+ export function summarizeStatus(payload) {
15
+ if (typeof payload !== 'object' || null === payload)
16
+ return { sessionCount: 0, sessions: [] };
17
+ const obj = payload;
18
+ const raw = Array.isArray(obj['sessions']) ? obj['sessions'] : [];
19
+ const sessions = raw
20
+ .map((s) => {
21
+ if (typeof s !== 'object' || null === s)
22
+ return null;
23
+ const r = s;
24
+ const sessionId = 'string' === typeof r['sessionId'] ? r['sessionId'] : '';
25
+ if ('' === sessionId)
26
+ return null;
27
+ return {
28
+ sessionId,
29
+ url: 'string' === typeof r['url'] ? r['url'] : '',
30
+ throttled: true === r['throttled'],
31
+ stale: true === r['stale'],
32
+ pendingMarks: 'number' === typeof r['pendingMarks'] ? r['pendingMarks'] : 0,
33
+ };
34
+ })
35
+ .filter((s) => s !== null);
36
+ const sessionCount = 'number' === typeof obj['sessionCount'] ? obj['sessionCount'] : sessions.length;
37
+ return { sessionCount, sessions };
38
+ }
39
+ /** A string field off the /status body, or undefined on a daemon too old to report it. */
40
+ function statusField(payload, key) {
41
+ if (typeof payload !== 'object' || null === payload)
42
+ return undefined;
43
+ const value = payload[key];
44
+ return 'string' === typeof value && value.length > 0 ? value : undefined;
45
+ }
46
+ /**
47
+ * Warn when the daemon already on this port is a different version than this CLI, and attach anyway.
48
+ *
49
+ * Attaching to whatever owns the port is the point of a daemon — but it means an upgrade does not
50
+ * take effect until that daemon dies, and nothing used to say so. Killing it here would take out
51
+ * another agent's session on a version bump, which is worse than a loud line.
52
+ */
53
+ export async function warnOnDaemonSkew(port) {
54
+ const status = await fetchStatus(port);
55
+ const skew = describeSkew({
56
+ what: 'the daemon already running on this port',
57
+ version: statusField(status, 'version'),
58
+ contract: statusField(status, 'contract'),
59
+ fix: DAEMON_FIX,
60
+ }, { version: SERVER_VERSION, contract: CONTRACT_FINGERPRINT });
61
+ if (skew !== undefined)
62
+ log('reticle_daemon_skew', { port, warning: skew });
63
+ }
64
+ /** How long the daemon /status probe waits before giving up — a local loopback call is near-instant. */
65
+ const STATUS_PROBE_TIMEOUT_MS = 1000;
66
+ /** GET the daemon's /status JSON. Resolves to the parsed body, or undefined on any failure. */
67
+ export function fetchStatus(port) {
68
+ return new Promise((resolve) => {
69
+ const req = http.get({ host: LOOPBACK_HOST, port, path: STATUS_PATH, timeout: STATUS_PROBE_TIMEOUT_MS }, (res) => {
70
+ let body = '';
71
+ res.setEncoding('utf8');
72
+ res.on('data', (chunk) => (body += chunk));
73
+ res.on('end', () => {
74
+ try {
75
+ resolve(JSON.parse(body));
76
+ }
77
+ catch {
78
+ resolve(undefined);
79
+ }
80
+ });
81
+ });
82
+ req.on('error', () => resolve(undefined));
83
+ req.on('timeout', () => {
84
+ req.destroy();
85
+ resolve(undefined);
86
+ });
87
+ });
88
+ }
89
+ function sameOrigin(a, b) {
90
+ try {
91
+ const origin = new URL(a).origin;
92
+ // Two opaque origins (desktop webviews, file:// docs) BOTH stringify to "null", so comparing them
93
+ // would call every desktop app the same app and reuse the wrong session. Never match on opaque.
94
+ if (isOpaqueOrigin(origin))
95
+ return false;
96
+ return origin === new URL(b).origin;
97
+ }
98
+ catch {
99
+ return false;
100
+ }
101
+ }
102
+ /**
103
+ * Decide what `reticle open [url]` does, given the currently-connected tabs. Pure.
104
+ * - no url + a tab connected → reuse it (the app is already open; don't spawn a duplicate).
105
+ * - no url + nothing connected → ask for one.
106
+ * - url + a tab already AT that url → reuse it (idempotent — re-running never piles up tabs).
107
+ * - url + a tab on that origin but another page → keep it, and say so (`left-as-is`).
108
+ * - url + no matching tab → open it.
109
+ *
110
+ * The origin match is why re-running this never piles up tabs, and it stays. What changed is the
111
+ * REPORT: matching by origin meant `reticle open http://localhost:3000/settings` answered `reusing`
112
+ * for a tab sitting on `http://localhost:3000/` and exited 0, so the caller read a success for a page
113
+ * that was never opened. Navigating the tab instead was the other option and is worse: `reticle open`
114
+ * is run by a human whose browser this is, and yanking the page they are looking at to somewhere else
115
+ * is a bigger surprise than being told where the tab actually is.
116
+ */
117
+ export function decideOpen(sessions, url) {
118
+ if (url === undefined) {
119
+ const first = sessions[0];
120
+ return first !== undefined ? { action: 'reuse', url: first.url } : { action: 'need-url' };
121
+ }
122
+ const exact = sessions.find((s) => s.url === url);
123
+ if (exact !== undefined)
124
+ return { action: 'reuse', url: exact.url };
125
+ const onOrigin = sessions.find((s) => sameOrigin(s.url, url));
126
+ return onOrigin !== undefined
127
+ ? { action: 'left-as-is', url: onOrigin.url, requested: url }
128
+ : { action: 'open', url };
129
+ }
130
+ /**
131
+ * Percent-encode the cmd.exe metacharacters that `start` re-parses so a URL can't break out into
132
+ * command execution on Windows (`?next=x&calc` → command chaining). `%` is left untouched so an
133
+ * already-encoded URL isn't double-encoded; the browser decodes the escapes back to the real URL.
134
+ */
135
+ function encodeForWindowsStart(url) {
136
+ return url.replace(/[&^|<>()"'!]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`);
137
+ }
138
+ /** The OS command that opens a URL in the default browser, per platform. Pure — unit-tested. */
139
+ export function openCommand(url, platform) {
140
+ if (NodePlatform.MACOS === platform)
141
+ return { cmd: 'open', args: [url] };
142
+ if (NodePlatform.WINDOWS === platform) {
143
+ return { cmd: 'cmd', args: ['/c', 'start', '', encodeForWindowsStart(url)] };
144
+ }
145
+ return { cmd: 'xdg-open', args: [url] };
146
+ }
147
+ /**
148
+ * Launch the default browser at `url` (detached). The spawn is injected so tests stay hermetic.
149
+ *
150
+ * Resolves to whether the launch COMMAND started — not to whether a page appeared. It used to return
151
+ * nothing at all and the caller printed `{"opened": url}` unconditionally, so a launcher that failed
152
+ * outright still reported success. Reported from the field as twenty minutes lost chasing a phantom
153
+ * port problem while nothing had ever opened.
154
+ */
155
+ export async function openInBrowser(url, platform = process.platform, run = defaultRun) {
156
+ const { cmd, args } = openCommand(url, platform);
157
+ return run(cmd, args);
158
+ }
159
+ /** null when the launcher started; the failure message when it could not be run at all. */
160
+ function defaultRun(cmd, args) {
161
+ return new Promise((resolve) => {
162
+ const child = spawn(cmd, args, { detached: true, stdio: 'ignore' });
163
+ // An unhandled 'error' on a ChildProcess throws — and ENOENT on the launcher is exactly the case
164
+ // this function exists to report, so it must be listened for either way.
165
+ child.on('error', (err) => resolve(err.message));
166
+ child.on('spawn', () => {
167
+ child.unref();
168
+ resolve(null);
169
+ });
170
+ });
171
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Pure CLI argument parsing — the command/flag grammar, the CliResult union, and parseCliArgs.
3
+ * Split out of cli.ts (which keeps the side-effecting handlers + dispatch) to stay under the
4
+ * file-size cap and keep the parser pure + unit-testable. Re-exported from cli.ts so existing
5
+ * imports are unchanged.
6
+ */
7
+ 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 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
+ /** `reticle feedback --rating 4 "the words"` — the human half of the channel. */
9
+ export declare const RATING_FLAG = "--rating";
10
+ export declare const BUG_FLAG = "--bug";
11
+ /** The `reticle telemetry` sub-actions. Bare `reticle telemetry` means `status`. */
12
+ export declare const TelemetryAction: {
13
+ readonly STATUS: "status";
14
+ readonly ENABLE: "enable";
15
+ readonly DISABLE: "disable";
16
+ };
17
+ export type TelemetryAction = (typeof TelemetryAction)[keyof typeof TelemetryAction];
18
+ export declare const DAEMON_INNER_COMMAND = "_daemon";
19
+ /**
20
+ * Every subcommand a person can type, as one closed vocabulary. Telemetry reports which one ran, and
21
+ * this is what keeps that property low-cardinality and non-identifying: an argument we do not
22
+ * recognize reports as `unknown` rather than being echoed, so a typo — which may be a path, a URL, or
23
+ * a flow name — can never reach the wire just because someone misspelled `status`.
24
+ *
25
+ * Lives here rather than in the telemetry module because this is where the command names are already
26
+ * defined; a second list somewhere else would drift the first time a command is added.
27
+ */
28
+ export declare const UNKNOWN_COMMAND = "unknown";
29
+ /** The subcommand name if we recognize it, else `unknown`. Bare `reticle` reports `help`. */
30
+ export declare function knownCommand(arg: string | undefined): string;
31
+ export declare const HEADED_FLAG = "--headed";
32
+ export declare const PORT_FLAG = "--port";
33
+ export declare const DRIVE_FLAG = "--drive";
34
+ export declare const HTTP_FLAG = "--http";
35
+ export declare const HTTP_PORT_FLAG = "--http-port";
36
+ export declare const HTTP_TOKEN_FLAG = "--http-token";
37
+ export type CliResult = {
38
+ kind: 'init';
39
+ port: number | undefined;
40
+ mcp: boolean;
41
+ dryRun: boolean;
42
+ install: boolean;
43
+ app: string | undefined;
44
+ } | {
45
+ kind: 'serve';
46
+ port: number;
47
+ driveUrl?: string;
48
+ headless: boolean;
49
+ http: boolean;
50
+ httpPort?: number;
51
+ httpToken?: string;
52
+ } | {
53
+ kind: 'stop';
54
+ port: number;
55
+ quiet: boolean;
56
+ } | {
57
+ kind: 'status';
58
+ port: number;
59
+ } | {
60
+ kind: 'license';
61
+ } | {
62
+ kind: 'telemetry';
63
+ action: TelemetryAction;
64
+ } | {
65
+ kind: 'feedback';
66
+ text: string;
67
+ rating?: number;
68
+ bug: boolean;
69
+ } | {
70
+ kind: 'identify';
71
+ context?: string;
72
+ company?: string;
73
+ email?: string;
74
+ forget: boolean;
75
+ } | {
76
+ kind: 'version';
77
+ } | {
78
+ kind: 'help';
79
+ } | {
80
+ kind: 'doctor';
81
+ port: number;
82
+ } | {
83
+ kind: 'open';
84
+ port: number;
85
+ url?: string;
86
+ } | {
87
+ kind: '_daemon';
88
+ port: number;
89
+ driveUrl?: string;
90
+ headless: boolean;
91
+ http: boolean;
92
+ httpPort?: number;
93
+ httpToken?: string;
94
+ } | {
95
+ kind: 'drive';
96
+ port: number;
97
+ driveUrl: string;
98
+ headless: boolean;
99
+ } | {
100
+ kind: 'verify';
101
+ url: string;
102
+ headless: boolean;
103
+ timeoutMs?: number;
104
+ storageState?: string;
105
+ } | {
106
+ kind: 'affected';
107
+ files: string[];
108
+ since?: string;
109
+ } | {
110
+ kind: 'hunt';
111
+ dir: string;
112
+ } | {
113
+ kind: 'capsules';
114
+ } | {
115
+ kind: 'gate';
116
+ files: string[];
117
+ since?: string;
118
+ } | {
119
+ kind: 'watch';
120
+ url?: string;
121
+ } | {
122
+ kind: 'update';
123
+ } | {
124
+ kind: 'rollback';
125
+ } | {
126
+ kind: 'mcp';
127
+ port: number;
128
+ driveUrl?: string;
129
+ headless: boolean;
130
+ http: boolean;
131
+ httpPort?: number;
132
+ httpToken?: string;
133
+ } | {
134
+ kind: 'error';
135
+ message: string;
136
+ };
137
+ /**
138
+ * @param defaultHeadless Whether a browser Reticle launches should be hidden when no flag says
139
+ * otherwise. Injected rather than read from the environment here, because this module is pure —
140
+ * `cli.ts` decides it from `CI`. The product default is FALSE: showing the run is what makes it
141
+ * trustworthy, and asking people to opt into seeing their own app was backwards.
142
+ */
143
+ export declare function parseCliArgs(argv: string[], defaultPort: number, defaultHeadless?: boolean): CliResult;