@reticlehq/server 2.2.1 → 2.3.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 (778) hide show
  1. package/README.md +1 -1
  2. package/dist/bridge-security.d.ts +0 -1
  3. package/dist/bridge-security.js +0 -1
  4. package/dist/bridge.d.ts +0 -1
  5. package/dist/bridge.js +60 -10
  6. package/dist/bridge.test-harness.d.ts +0 -1
  7. package/dist/bridge.test-harness.js +0 -1
  8. package/dist/capsule/capsule-store.d.ts +2 -3
  9. package/dist/capsule/capsule-store.js +0 -1
  10. package/dist/capsule/capsule.d.ts +0 -1
  11. package/dist/capsule/capsule.js +0 -1
  12. package/dist/capsule/causal-summary.d.ts +21 -1
  13. package/dist/capsule/causal-summary.js +20 -2
  14. package/dist/capsule/divergence.d.ts +0 -1
  15. package/dist/capsule/divergence.js +0 -1
  16. package/dist/capsule/minimize.d.ts +0 -1
  17. package/dist/capsule/minimize.js +0 -1
  18. package/dist/capsule/predicate-to-links.d.ts +0 -1
  19. package/dist/capsule/predicate-to-links.js +0 -1
  20. package/dist/cli-doctor.d.ts +6 -0
  21. package/dist/cli-doctor.js +60 -0
  22. package/dist/cli-flow-commands.d.ts +0 -1
  23. package/dist/cli-flow-commands.js +0 -1
  24. package/dist/cli-launch.d.ts +0 -1
  25. package/dist/cli-launch.js +7 -3
  26. package/dist/cli-parse.d.ts +34 -2
  27. package/dist/cli-parse.js +107 -1
  28. package/dist/cli-port.d.ts +0 -1
  29. package/dist/cli-port.js +0 -1
  30. package/dist/cli-verify.d.ts +0 -1
  31. package/dist/cli-verify.js +1 -2
  32. package/dist/cli.d.ts +0 -1
  33. package/dist/cli.js +79 -67
  34. package/dist/cloud/cloud-config.d.ts +0 -1
  35. package/dist/cloud/cloud-config.js +0 -1
  36. package/dist/cloud/cloud-sync.d.ts +4 -5
  37. package/dist/cloud/cloud-sync.js +0 -1
  38. package/dist/cloud-cli.d.ts +0 -1
  39. package/dist/cloud-cli.js +9 -2
  40. package/dist/crawl/crawl-tools.d.ts +0 -1
  41. package/dist/crawl/crawl-tools.js +1 -2
  42. package/dist/crawl/crawl.d.ts +17 -3
  43. package/dist/crawl/crawl.js +43 -4
  44. package/dist/daemon-resilience.d.ts +6 -1
  45. package/dist/daemon-resilience.js +63 -1
  46. package/dist/daemon.d.ts +23 -3
  47. package/dist/daemon.js +36 -24
  48. package/dist/domain/domain-model.d.ts +0 -1
  49. package/dist/domain/domain-model.js +1 -2
  50. package/dist/domain/domain-tools.d.ts +0 -7
  51. package/dist/domain/domain-tools.js +21 -4
  52. package/dist/domain/flow-risk.d.ts +0 -1
  53. package/dist/domain/flow-risk.js +0 -1
  54. package/dist/ee/audit-log.d.ts +0 -1
  55. package/dist/ee/audit-log.js +0 -1
  56. package/dist/events/body-failures.d.ts +4 -0
  57. package/dist/events/body-failures.js +113 -0
  58. package/dist/events/contradictions.d.ts +53 -0
  59. package/dist/events/contradictions.js +282 -0
  60. package/dist/events/echo-mismatch.d.ts +4 -0
  61. package/dist/events/echo-mismatch.js +138 -0
  62. package/dist/events/event-filters.d.ts +17 -3
  63. package/dist/events/event-filters.js +13 -3
  64. package/dist/events/json-salvage.d.ts +32 -0
  65. package/dist/events/json-salvage.js +96 -0
  66. package/dist/events/predicate-eval.d.ts +2 -1
  67. package/dist/events/predicate-eval.js +56 -9
  68. package/dist/events/predicate.d.ts +0 -1
  69. package/dist/events/predicate.js +56 -2
  70. package/dist/events/reaction.d.ts +0 -1
  71. package/dist/events/reaction.js +0 -1
  72. package/dist/events/reconcile.d.ts +39 -0
  73. package/dist/events/reconcile.js +211 -0
  74. package/dist/events/ring-buffer.d.ts +0 -1
  75. package/dist/events/ring-buffer.js +0 -1
  76. package/dist/events/stale-response.d.ts +4 -0
  77. package/dist/events/stale-response.js +139 -0
  78. package/dist/events/unit-mismatch.d.ts +16 -0
  79. package/dist/events/unit-mismatch.js +167 -0
  80. package/dist/flows/affected-tools.d.ts +18 -0
  81. package/dist/flows/affected-tools.js +52 -0
  82. package/dist/flows/affected.d.ts +0 -1
  83. package/dist/flows/affected.js +0 -1
  84. package/dist/flows/annotate-tools.d.ts +0 -1
  85. package/dist/flows/annotate-tools.js +21 -3
  86. package/dist/flows/annotate.d.ts +0 -1
  87. package/dist/flows/annotate.js +0 -1
  88. package/dist/flows/annotation-store.d.ts +0 -1
  89. package/dist/flows/annotation-store.js +0 -1
  90. package/dist/flows/assertion-integrity.d.ts +0 -1
  91. package/dist/flows/assertion-integrity.js +0 -1
  92. package/dist/flows/assertion-tiers-store.d.ts +0 -1
  93. package/dist/flows/assertion-tiers-store.js +0 -1
  94. package/dist/flows/buddy-status.d.ts +0 -1
  95. package/dist/flows/buddy-status.js +0 -1
  96. package/dist/flows/coverage.d.ts +0 -1
  97. package/dist/flows/coverage.js +0 -1
  98. package/dist/flows/decision.d.ts +0 -1
  99. package/dist/flows/decision.js +0 -1
  100. package/dist/flows/flake-store.d.ts +0 -1
  101. package/dist/flows/flake-store.js +0 -1
  102. package/dist/flows/flake.d.ts +0 -1
  103. package/dist/flows/flake.js +0 -1
  104. package/dist/flows/flow-classify.d.ts +0 -1
  105. package/dist/flows/flow-classify.js +0 -1
  106. package/dist/flows/flow-replay-run.d.ts +0 -1
  107. package/dist/flows/flow-replay-run.js +2 -3
  108. package/dist/flows/flow-replay.d.ts +20 -4
  109. package/dist/flows/flow-replay.js +9 -43
  110. package/dist/flows/flow-report.d.ts +0 -1
  111. package/dist/flows/flow-report.js +0 -1
  112. package/dist/flows/flow-scope.d.ts +0 -1
  113. package/dist/flows/flow-scope.js +0 -1
  114. package/dist/flows/flow-sources.d.ts +0 -1
  115. package/dist/flows/flow-sources.js +0 -1
  116. package/dist/flows/flow-step-runners.d.ts +23 -0
  117. package/dist/flows/flow-step-runners.js +102 -0
  118. package/dist/flows/flow-success.d.ts +0 -1
  119. package/dist/flows/flow-success.js +0 -1
  120. package/dist/flows/flow-tools.d.ts +0 -1
  121. package/dist/flows/flow-tools.js +30 -8
  122. package/dist/flows/flows.d.ts +6 -2
  123. package/dist/flows/flows.js +15 -2
  124. package/dist/flows/gate.d.ts +0 -1
  125. package/dist/flows/gate.js +0 -1
  126. package/dist/flows/git-changed.d.ts +0 -1
  127. package/dist/flows/git-changed.js +0 -1
  128. package/dist/flows/heal-run.d.ts +0 -1
  129. package/dist/flows/heal-run.js +0 -1
  130. package/dist/flows/heal.d.ts +0 -1
  131. package/dist/flows/heal.js +0 -1
  132. package/dist/flows/parallel-suite.d.ts +0 -1
  133. package/dist/flows/parallel-suite.js +0 -1
  134. package/dist/flows/recordings.d.ts +0 -1
  135. package/dist/flows/recordings.js +0 -1
  136. package/dist/flows/replay.d.ts +0 -1
  137. package/dist/flows/replay.js +71 -4
  138. package/dist/flows/server-verify.d.ts +0 -1
  139. package/dist/flows/server-verify.js +0 -1
  140. package/dist/flows/verify-change-tools.d.ts +2 -0
  141. package/dist/flows/verify-change-tools.js +187 -0
  142. package/dist/flows/watch-batcher.d.ts +0 -1
  143. package/dist/flows/watch-batcher.js +0 -1
  144. package/dist/honesty/accepted-write.d.ts +14 -0
  145. package/dist/honesty/accepted-write.js +17 -0
  146. package/dist/honesty/blind-spots.d.ts +18 -1
  147. package/dist/honesty/blind-spots.js +47 -5
  148. package/dist/honesty/honesty.d.ts +0 -1
  149. package/dist/honesty/honesty.js +0 -1
  150. package/dist/honesty/uncaptured-bodies.d.ts +19 -0
  151. package/dist/honesty/uncaptured-bodies.js +30 -0
  152. package/dist/honesty/unread-outcome.d.ts +2 -0
  153. package/dist/honesty/unread-outcome.js +50 -0
  154. package/dist/honesty/verified.d.ts +40 -0
  155. package/dist/honesty/verified.js +86 -0
  156. package/dist/http-server.d.ts +0 -1
  157. package/dist/http-server.js +5 -1
  158. package/dist/hunt/hunt-report.d.ts +50 -0
  159. package/dist/hunt/hunt-report.js +84 -0
  160. package/dist/idle-shutdown.d.ts +0 -1
  161. package/dist/idle-shutdown.js +0 -1
  162. package/dist/index.d.ts +0 -1
  163. package/dist/index.js +0 -1
  164. package/dist/init/agent-rules.d.ts +0 -1
  165. package/dist/init/agent-rules.js +4 -2
  166. package/dist/init/cursor.d.ts +0 -1
  167. package/dist/init/cursor.js +0 -1
  168. package/dist/init/desktop-doctor.d.ts +40 -0
  169. package/dist/init/desktop-doctor.js +198 -0
  170. package/dist/init/detect.d.ts +0 -1
  171. package/dist/init/detect.js +0 -1
  172. package/dist/init/mcp.d.ts +0 -1
  173. package/dist/init/mcp.js +0 -1
  174. package/dist/init/node-io.d.ts +0 -1
  175. package/dist/init/node-io.js +0 -1
  176. package/dist/init/plan.d.ts +4 -1
  177. package/dist/init/plan.js +23 -5
  178. package/dist/init/project-id.d.ts +0 -1
  179. package/dist/init/project-id.js +0 -1
  180. package/dist/init/run.d.ts +0 -1
  181. package/dist/init/run.js +31 -3
  182. package/dist/init/snippets.d.ts +5 -1
  183. package/dist/init/snippets.js +5 -1
  184. package/dist/init/vite-config.d.ts +0 -1
  185. package/dist/init/vite-config.js +0 -1
  186. package/dist/input/network-detail.d.ts +0 -1
  187. package/dist/input/network-detail.js +0 -1
  188. package/dist/input/network-mock-tools.d.ts +0 -1
  189. package/dist/input/network-mock-tools.js +3 -4
  190. package/dist/input/network-mock.d.ts +0 -1
  191. package/dist/input/network-mock.js +0 -1
  192. package/dist/input/real-input.d.ts +14 -1
  193. package/dist/input/real-input.js +45 -3
  194. package/dist/input/scroll-find.d.ts +0 -1
  195. package/dist/input/scroll-find.js +0 -1
  196. package/dist/input/scroll-tools.d.ts +0 -1
  197. package/dist/input/scroll-tools.js +0 -1
  198. package/dist/input/viewport-tools.d.ts +0 -1
  199. package/dist/input/viewport-tools.js +3 -4
  200. package/dist/journal/ambient-store.d.ts +0 -1
  201. package/dist/journal/ambient-store.js +0 -1
  202. package/dist/journal/ambient.d.ts +0 -1
  203. package/dist/journal/ambient.js +0 -1
  204. package/dist/journal/attach-journal.d.ts +0 -1
  205. package/dist/journal/attach-journal.js +0 -1
  206. package/dist/journal/deviation-report.d.ts +0 -1
  207. package/dist/journal/deviation-report.js +0 -1
  208. package/dist/journal/deviation-service.d.ts +0 -1
  209. package/dist/journal/deviation-service.js +0 -1
  210. package/dist/journal/envelope-store.d.ts +0 -1
  211. package/dist/journal/envelope-store.js +0 -1
  212. package/dist/journal/envelope.d.ts +8 -9
  213. package/dist/journal/envelope.js +0 -1
  214. package/dist/journal/journal-query.d.ts +0 -1
  215. package/dist/journal/journal-query.js +0 -1
  216. package/dist/journal/journal-recorder.d.ts +0 -1
  217. package/dist/journal/journal-recorder.js +0 -1
  218. package/dist/journal/retention.d.ts +0 -1
  219. package/dist/journal/retention.js +0 -1
  220. package/dist/journal/rollups.d.ts +0 -1
  221. package/dist/journal/rollups.js +0 -1
  222. package/dist/journal/session-end.d.ts +0 -1
  223. package/dist/journal/session-end.js +0 -1
  224. package/dist/journal/session-journal.d.ts +0 -1
  225. package/dist/journal/session-journal.js +0 -1
  226. package/dist/license/license.d.ts +0 -1
  227. package/dist/license/license.js +0 -1
  228. package/dist/log.d.ts +0 -1
  229. package/dist/log.js +0 -1
  230. package/dist/mcp-proxy.d.ts +0 -1
  231. package/dist/mcp-proxy.js +0 -1
  232. package/dist/mcp.d.ts +15 -1
  233. package/dist/mcp.js +145 -17
  234. package/dist/oracles/flow-instrument-gaps.d.ts +0 -1
  235. package/dist/oracles/flow-instrument-gaps.js +0 -1
  236. package/dist/oracles/propose-consequences.d.ts +0 -1
  237. package/dist/oracles/propose-consequences.js +0 -1
  238. package/dist/oracles/self-instrument.d.ts +0 -1
  239. package/dist/oracles/self-instrument.js +0 -1
  240. package/dist/pairing-token.d.ts +0 -1
  241. package/dist/pairing-token.js +0 -1
  242. package/dist/phenomena/phenomena.d.ts +0 -1
  243. package/dist/phenomena/phenomena.js +0 -1
  244. package/dist/pool/browser-pool.d.ts +0 -1
  245. package/dist/pool/browser-pool.js +0 -1
  246. package/dist/pool/lease-reaper.d.ts +0 -1
  247. package/dist/pool/lease-reaper.js +0 -1
  248. package/dist/pool/playwright-launcher.d.ts +0 -1
  249. package/dist/pool/playwright-launcher.js +10 -2
  250. package/dist/project/baselines.d.ts +0 -1
  251. package/dist/project/baselines.js +0 -1
  252. package/dist/project/file-lock.d.ts +2 -1
  253. package/dist/project/file-lock.js +12 -2
  254. package/dist/project/fs-port.d.ts +0 -1
  255. package/dist/project/fs-port.js +0 -1
  256. package/dist/project/project-store.d.ts +0 -1
  257. package/dist/project/project-store.js +0 -1
  258. package/dist/project/project-tools.d.ts +0 -1
  259. package/dist/project/project-tools.js +29 -4
  260. package/dist/project/reticle-dir.d.ts +0 -1
  261. package/dist/project/reticle-dir.js +0 -1
  262. package/dist/runs/build-verification-run.d.ts +0 -1
  263. package/dist/runs/build-verification-run.js +0 -1
  264. package/dist/runs/profile-redact.d.ts +0 -1
  265. package/dist/runs/profile-redact.js +0 -1
  266. package/dist/runs/render-report.d.ts +0 -1
  267. package/dist/runs/render-report.js +0 -1
  268. package/dist/runs/repair-prompt.d.ts +0 -1
  269. package/dist/runs/repair-prompt.js +0 -1
  270. package/dist/runs/replay-mapping.d.ts +0 -1
  271. package/dist/runs/replay-mapping.js +0 -1
  272. package/dist/runs/reticle-runner.d.ts +0 -1
  273. package/dist/runs/reticle-runner.js +4 -2
  274. package/dist/runs/risk-classify.d.ts +0 -1
  275. package/dist/runs/risk-classify.js +0 -1
  276. package/dist/runs/run-diff.d.ts +0 -1
  277. package/dist/runs/run-diff.js +0 -1
  278. package/dist/runs/run-store.d.ts +0 -1
  279. package/dist/runs/run-store.js +0 -1
  280. package/dist/runs/run-tools.d.ts +0 -1
  281. package/dist/runs/run-tools.js +0 -1
  282. package/dist/runs/runner-port.d.ts +0 -1
  283. package/dist/runs/runner-port.js +0 -1
  284. package/dist/runs/verification-sync.d.ts +0 -1
  285. package/dist/runs/verification-sync.js +0 -1
  286. package/dist/runs/verify-http.d.ts +0 -1
  287. package/dist/runs/verify-http.js +0 -1
  288. package/dist/runs/verify-server.d.ts +0 -1
  289. package/dist/runs/verify-server.js +0 -1
  290. package/dist/server-version.d.ts +0 -1
  291. package/dist/server-version.js +0 -1
  292. package/dist/session/command-timeout.d.ts +35 -0
  293. package/dist/session/command-timeout.js +41 -0
  294. package/dist/session/control-envelope.d.ts +2 -3
  295. package/dist/session/control-envelope.js +2 -3
  296. package/dist/session/last-act.d.ts +31 -0
  297. package/dist/session/last-act.js +24 -0
  298. package/dist/session/live-control-tools.d.ts +0 -1
  299. package/dist/session/live-control-tools.js +3 -4
  300. package/dist/session/live-control.d.ts +0 -1
  301. package/dist/session/live-control.js +0 -1
  302. package/dist/session/observed-state.d.ts +12 -2
  303. package/dist/session/observed-state.js +29 -2
  304. package/dist/session/output-budget.d.ts +0 -1
  305. package/dist/session/output-budget.js +0 -1
  306. package/dist/session/pending-commands.d.ts +12 -0
  307. package/dist/session/pending-commands.js +36 -0
  308. package/dist/session/presenter-args.d.ts +0 -1
  309. package/dist/session/presenter-args.js +0 -1
  310. package/dist/session/review-store.d.ts +0 -1
  311. package/dist/session/review-store.js +0 -1
  312. package/dist/session/session-health.d.ts +26 -2
  313. package/dist/session/session-health.js +13 -1
  314. package/dist/session/session-info.d.ts +29 -0
  315. package/dist/session/session-info.js +1 -0
  316. package/dist/session/session-lease.d.ts +25 -0
  317. package/dist/session/session-lease.js +14 -0
  318. package/dist/session/session-manager.d.ts +7 -19
  319. package/dist/session/session-manager.js +29 -2
  320. package/dist/session/session-readiness.d.ts +0 -1
  321. package/dist/session/session-readiness.js +3 -4
  322. package/dist/session/session-reaper.d.ts +0 -1
  323. package/dist/session/session-reaper.js +0 -1
  324. package/dist/session/session-recommendation.d.ts +0 -1
  325. package/dist/session/session-recommendation.js +0 -1
  326. package/dist/session/session-tools.d.ts +0 -1
  327. package/dist/session/session-tools.js +2 -3
  328. package/dist/session/session.d.ts +27 -53
  329. package/dist/session/session.js +95 -66
  330. package/dist/session/state-select.d.ts +0 -1
  331. package/dist/session/state-select.js +0 -1
  332. package/dist/telemetry/argument-shape.d.ts +41 -0
  333. package/dist/telemetry/argument-shape.js +87 -0
  334. package/dist/telemetry/bug-found.d.ts +33 -0
  335. package/dist/telemetry/bug-found.js +95 -0
  336. package/dist/telemetry/cli-telemetry.d.ts +13 -0
  337. package/dist/telemetry/cli-telemetry.js +43 -0
  338. package/dist/telemetry/connect-failure.d.ts +16 -0
  339. package/dist/telemetry/connect-failure.js +44 -0
  340. package/dist/telemetry/daemon-telemetry.d.ts +19 -0
  341. package/dist/telemetry/daemon-telemetry.js +76 -0
  342. package/dist/telemetry/dev-repo.d.ts +10 -0
  343. package/dist/telemetry/dev-repo.js +80 -0
  344. package/dist/telemetry/error-fingerprint.d.ts +24 -0
  345. package/dist/telemetry/error-fingerprint.js +88 -0
  346. package/dist/telemetry/feedback-cli.d.ts +31 -0
  347. package/dist/telemetry/feedback-cli.js +102 -0
  348. package/dist/telemetry/feedback-context.d.ts +32 -0
  349. package/dist/telemetry/feedback-context.js +143 -0
  350. package/dist/telemetry/feedback.d.ts +66 -0
  351. package/dist/telemetry/feedback.js +175 -0
  352. package/dist/telemetry/git-facts.d.ts +21 -0
  353. package/dist/telemetry/git-facts.js +109 -0
  354. package/dist/telemetry/identify.d.ts +22 -0
  355. package/dist/telemetry/identify.js +73 -0
  356. package/dist/telemetry/init-telemetry.d.ts +26 -0
  357. package/dist/telemetry/init-telemetry.js +33 -0
  358. package/dist/telemetry/machine-snapshot.d.ts +6 -0
  359. package/dist/telemetry/machine-snapshot.js +39 -0
  360. package/dist/telemetry/mcp-connection.d.ts +5 -0
  361. package/dist/telemetry/mcp-connection.js +44 -0
  362. package/dist/telemetry/project-profile.d.ts +44 -0
  363. package/dist/telemetry/project-profile.js +205 -0
  364. package/dist/telemetry/run-telemetry.d.ts +21 -0
  365. package/dist/telemetry/run-telemetry.js +62 -0
  366. package/dist/telemetry/session-metrics.d.ts +103 -0
  367. package/dist/telemetry/session-metrics.js +329 -0
  368. package/dist/telemetry/telemetry.d.ts +35 -8
  369. package/dist/telemetry/telemetry.js +105 -12
  370. package/dist/token-auth.d.ts +0 -1
  371. package/dist/token-auth.js +0 -1
  372. package/dist/tools/act-capsule.d.ts +23 -0
  373. package/dist/tools/act-capsule.js +47 -0
  374. package/dist/tools/act-danger.d.ts +7 -0
  375. package/dist/tools/act-danger.js +44 -0
  376. package/dist/tools/act-helpers.d.ts +17 -0
  377. package/dist/tools/act-helpers.js +40 -0
  378. package/dist/tools/act-tools.d.ts +8 -1
  379. package/dist/tools/act-tools.js +96 -98
  380. package/dist/tools/act-view.d.ts +7 -1
  381. package/dist/tools/act-view.js +13 -1
  382. package/dist/tools/assert-grade.d.ts +22 -1
  383. package/dist/tools/assert-grade.js +46 -1
  384. package/dist/tools/assert-verdict.d.ts +21 -0
  385. package/dist/tools/assert-verdict.js +62 -0
  386. package/dist/tools/browser-tools.d.ts +0 -1
  387. package/dist/tools/browser-tools.js +2 -2
  388. package/dist/tools/contract-tools.d.ts +0 -1
  389. package/dist/tools/contract-tools.js +0 -1
  390. package/dist/tools/coverage-tools.d.ts +9 -0
  391. package/dist/tools/coverage-tools.js +92 -0
  392. package/dist/tools/dynamic-tools.d.ts +0 -1
  393. package/dist/tools/dynamic-tools.js +21 -2
  394. package/dist/tools/error-recovery.d.ts +18 -2
  395. package/dist/tools/error-recovery.js +42 -7
  396. package/dist/tools/feedback-tools.d.ts +24 -0
  397. package/dist/tools/feedback-tools.js +180 -0
  398. package/dist/tools/invoke-tool.d.ts +0 -1
  399. package/dist/tools/invoke-tool.js +115 -5
  400. package/dist/tools/lease-tools.d.ts +0 -1
  401. package/dist/tools/lease-tools.js +6 -5
  402. package/dist/tools/merge-tools.d.ts +0 -1
  403. package/dist/tools/merge-tools.js +0 -1
  404. package/dist/tools/observe-tools.d.ts +0 -1
  405. package/dist/tools/observe-tools.js +91 -39
  406. package/dist/tools/profiles.d.ts +1 -2
  407. package/dist/tools/profiles.js +43 -16
  408. package/dist/tools/query-paginate.d.ts +0 -1
  409. package/dist/tools/query-paginate.js +0 -1
  410. package/dist/tools/read-tools.d.ts +0 -1
  411. package/dist/tools/read-tools.js +10 -8
  412. package/dist/tools/reconcile-tools.d.ts +2 -0
  413. package/dist/tools/reconcile-tools.js +111 -0
  414. package/dist/tools/snapshot-delta.d.ts +0 -1
  415. package/dist/tools/snapshot-delta.js +0 -0
  416. package/dist/tools/tool-invoker.d.ts +0 -1
  417. package/dist/tools/tool-invoker.js +0 -1
  418. package/dist/tools/tool-kit.d.ts +16 -1
  419. package/dist/tools/tool-kit.js +8 -2
  420. package/dist/tools/tool-names.d.ts +6 -1
  421. package/dist/tools/tool-names.js +6 -1
  422. package/dist/tools/tools-helpers.d.ts +0 -1
  423. package/dist/tools/tools-helpers.js +0 -1
  424. package/dist/tools/tools.d.ts +0 -1
  425. package/dist/tools/tools.js +24 -4
  426. package/dist/update/update-checker.d.ts +0 -1
  427. package/dist/update/update-checker.js +0 -1
  428. package/dist/update/update-nudge.d.ts +20 -0
  429. package/dist/update/update-nudge.js +72 -0
  430. package/dist/update/updater.d.ts +14 -1
  431. package/dist/update/updater.js +33 -2
  432. package/dist/visual/visual-diff.d.ts +0 -1
  433. package/dist/visual/visual-diff.js +0 -1
  434. package/dist/visual/visual-store.d.ts +0 -1
  435. package/dist/visual/visual-store.js +0 -1
  436. package/dist/visual/visual-tools.d.ts +0 -1
  437. package/dist/visual/visual-tools.js +103 -16
  438. package/package.json +2 -2
  439. package/dist/bridge-security.d.ts.map +0 -1
  440. package/dist/bridge-security.js.map +0 -1
  441. package/dist/bridge.d.ts.map +0 -1
  442. package/dist/bridge.js.map +0 -1
  443. package/dist/bridge.test-harness.d.ts.map +0 -1
  444. package/dist/bridge.test-harness.js.map +0 -1
  445. package/dist/capsule/capsule-store.d.ts.map +0 -1
  446. package/dist/capsule/capsule-store.js.map +0 -1
  447. package/dist/capsule/capsule.d.ts.map +0 -1
  448. package/dist/capsule/capsule.js.map +0 -1
  449. package/dist/capsule/causal-summary.d.ts.map +0 -1
  450. package/dist/capsule/causal-summary.js.map +0 -1
  451. package/dist/capsule/divergence.d.ts.map +0 -1
  452. package/dist/capsule/divergence.js.map +0 -1
  453. package/dist/capsule/minimize.d.ts.map +0 -1
  454. package/dist/capsule/minimize.js.map +0 -1
  455. package/dist/capsule/predicate-to-links.d.ts.map +0 -1
  456. package/dist/capsule/predicate-to-links.js.map +0 -1
  457. package/dist/cli-flow-commands.d.ts.map +0 -1
  458. package/dist/cli-flow-commands.js.map +0 -1
  459. package/dist/cli-launch.d.ts.map +0 -1
  460. package/dist/cli-launch.js.map +0 -1
  461. package/dist/cli-parse.d.ts.map +0 -1
  462. package/dist/cli-parse.js.map +0 -1
  463. package/dist/cli-port.d.ts.map +0 -1
  464. package/dist/cli-port.js.map +0 -1
  465. package/dist/cli-verify.d.ts.map +0 -1
  466. package/dist/cli-verify.js.map +0 -1
  467. package/dist/cli.d.ts.map +0 -1
  468. package/dist/cli.js.map +0 -1
  469. package/dist/cloud/cloud-config.d.ts.map +0 -1
  470. package/dist/cloud/cloud-config.js.map +0 -1
  471. package/dist/cloud/cloud-sync.d.ts.map +0 -1
  472. package/dist/cloud/cloud-sync.js.map +0 -1
  473. package/dist/cloud-cli.d.ts.map +0 -1
  474. package/dist/cloud-cli.js.map +0 -1
  475. package/dist/crawl/crawl-tools.d.ts.map +0 -1
  476. package/dist/crawl/crawl-tools.js.map +0 -1
  477. package/dist/crawl/crawl.d.ts.map +0 -1
  478. package/dist/crawl/crawl.js.map +0 -1
  479. package/dist/daemon-resilience.d.ts.map +0 -1
  480. package/dist/daemon-resilience.js.map +0 -1
  481. package/dist/daemon.d.ts.map +0 -1
  482. package/dist/daemon.js.map +0 -1
  483. package/dist/domain/domain-model.d.ts.map +0 -1
  484. package/dist/domain/domain-model.js.map +0 -1
  485. package/dist/domain/domain-tools.d.ts.map +0 -1
  486. package/dist/domain/domain-tools.js.map +0 -1
  487. package/dist/domain/flow-risk.d.ts.map +0 -1
  488. package/dist/domain/flow-risk.js.map +0 -1
  489. package/dist/ee/audit-log.d.ts.map +0 -1
  490. package/dist/ee/audit-log.js.map +0 -1
  491. package/dist/events/event-filters.d.ts.map +0 -1
  492. package/dist/events/event-filters.js.map +0 -1
  493. package/dist/events/predicate-eval.d.ts.map +0 -1
  494. package/dist/events/predicate-eval.js.map +0 -1
  495. package/dist/events/predicate.d.ts.map +0 -1
  496. package/dist/events/predicate.js.map +0 -1
  497. package/dist/events/reaction.d.ts.map +0 -1
  498. package/dist/events/reaction.js.map +0 -1
  499. package/dist/events/ring-buffer.d.ts.map +0 -1
  500. package/dist/events/ring-buffer.js.map +0 -1
  501. package/dist/flows/affected.d.ts.map +0 -1
  502. package/dist/flows/affected.js.map +0 -1
  503. package/dist/flows/annotate-tools.d.ts.map +0 -1
  504. package/dist/flows/annotate-tools.js.map +0 -1
  505. package/dist/flows/annotate.d.ts.map +0 -1
  506. package/dist/flows/annotate.js.map +0 -1
  507. package/dist/flows/annotation-store.d.ts.map +0 -1
  508. package/dist/flows/annotation-store.js.map +0 -1
  509. package/dist/flows/assertion-integrity.d.ts.map +0 -1
  510. package/dist/flows/assertion-integrity.js.map +0 -1
  511. package/dist/flows/assertion-tiers-store.d.ts.map +0 -1
  512. package/dist/flows/assertion-tiers-store.js.map +0 -1
  513. package/dist/flows/buddy-status.d.ts.map +0 -1
  514. package/dist/flows/buddy-status.js.map +0 -1
  515. package/dist/flows/coverage.d.ts.map +0 -1
  516. package/dist/flows/coverage.js.map +0 -1
  517. package/dist/flows/decision.d.ts.map +0 -1
  518. package/dist/flows/decision.js.map +0 -1
  519. package/dist/flows/flake-store.d.ts.map +0 -1
  520. package/dist/flows/flake-store.js.map +0 -1
  521. package/dist/flows/flake.d.ts.map +0 -1
  522. package/dist/flows/flake.js.map +0 -1
  523. package/dist/flows/flow-classify.d.ts.map +0 -1
  524. package/dist/flows/flow-classify.js.map +0 -1
  525. package/dist/flows/flow-replay-run.d.ts.map +0 -1
  526. package/dist/flows/flow-replay-run.js.map +0 -1
  527. package/dist/flows/flow-replay.d.ts.map +0 -1
  528. package/dist/flows/flow-replay.js.map +0 -1
  529. package/dist/flows/flow-report.d.ts.map +0 -1
  530. package/dist/flows/flow-report.js.map +0 -1
  531. package/dist/flows/flow-scope.d.ts.map +0 -1
  532. package/dist/flows/flow-scope.js.map +0 -1
  533. package/dist/flows/flow-sources.d.ts.map +0 -1
  534. package/dist/flows/flow-sources.js.map +0 -1
  535. package/dist/flows/flow-success.d.ts.map +0 -1
  536. package/dist/flows/flow-success.js.map +0 -1
  537. package/dist/flows/flow-tools.d.ts.map +0 -1
  538. package/dist/flows/flow-tools.js.map +0 -1
  539. package/dist/flows/flows.d.ts.map +0 -1
  540. package/dist/flows/flows.js.map +0 -1
  541. package/dist/flows/gate.d.ts.map +0 -1
  542. package/dist/flows/gate.js.map +0 -1
  543. package/dist/flows/git-changed.d.ts.map +0 -1
  544. package/dist/flows/git-changed.js.map +0 -1
  545. package/dist/flows/heal-run.d.ts.map +0 -1
  546. package/dist/flows/heal-run.js.map +0 -1
  547. package/dist/flows/heal.d.ts.map +0 -1
  548. package/dist/flows/heal.js.map +0 -1
  549. package/dist/flows/parallel-suite.d.ts.map +0 -1
  550. package/dist/flows/parallel-suite.js.map +0 -1
  551. package/dist/flows/recordings.d.ts.map +0 -1
  552. package/dist/flows/recordings.js.map +0 -1
  553. package/dist/flows/replay.d.ts.map +0 -1
  554. package/dist/flows/replay.js.map +0 -1
  555. package/dist/flows/server-verify.d.ts.map +0 -1
  556. package/dist/flows/server-verify.js.map +0 -1
  557. package/dist/flows/watch-batcher.d.ts.map +0 -1
  558. package/dist/flows/watch-batcher.js.map +0 -1
  559. package/dist/honesty/blind-spots.d.ts.map +0 -1
  560. package/dist/honesty/blind-spots.js.map +0 -1
  561. package/dist/honesty/honesty.d.ts.map +0 -1
  562. package/dist/honesty/honesty.js.map +0 -1
  563. package/dist/http-server.d.ts.map +0 -1
  564. package/dist/http-server.js.map +0 -1
  565. package/dist/idle-shutdown.d.ts.map +0 -1
  566. package/dist/idle-shutdown.js.map +0 -1
  567. package/dist/index.d.ts.map +0 -1
  568. package/dist/index.js.map +0 -1
  569. package/dist/init/agent-rules.d.ts.map +0 -1
  570. package/dist/init/agent-rules.js.map +0 -1
  571. package/dist/init/cursor.d.ts.map +0 -1
  572. package/dist/init/cursor.js.map +0 -1
  573. package/dist/init/detect.d.ts.map +0 -1
  574. package/dist/init/detect.js.map +0 -1
  575. package/dist/init/mcp.d.ts.map +0 -1
  576. package/dist/init/mcp.js.map +0 -1
  577. package/dist/init/node-io.d.ts.map +0 -1
  578. package/dist/init/node-io.js.map +0 -1
  579. package/dist/init/plan.d.ts.map +0 -1
  580. package/dist/init/plan.js.map +0 -1
  581. package/dist/init/project-id.d.ts.map +0 -1
  582. package/dist/init/project-id.js.map +0 -1
  583. package/dist/init/run.d.ts.map +0 -1
  584. package/dist/init/run.js.map +0 -1
  585. package/dist/init/snippets.d.ts.map +0 -1
  586. package/dist/init/snippets.js.map +0 -1
  587. package/dist/init/vite-config.d.ts.map +0 -1
  588. package/dist/init/vite-config.js.map +0 -1
  589. package/dist/input/network-detail.d.ts.map +0 -1
  590. package/dist/input/network-detail.js.map +0 -1
  591. package/dist/input/network-mock-tools.d.ts.map +0 -1
  592. package/dist/input/network-mock-tools.js.map +0 -1
  593. package/dist/input/network-mock.d.ts.map +0 -1
  594. package/dist/input/network-mock.js.map +0 -1
  595. package/dist/input/real-input.d.ts.map +0 -1
  596. package/dist/input/real-input.js.map +0 -1
  597. package/dist/input/scroll-find.d.ts.map +0 -1
  598. package/dist/input/scroll-find.js.map +0 -1
  599. package/dist/input/scroll-tools.d.ts.map +0 -1
  600. package/dist/input/scroll-tools.js.map +0 -1
  601. package/dist/input/viewport-tools.d.ts.map +0 -1
  602. package/dist/input/viewport-tools.js.map +0 -1
  603. package/dist/journal/ambient-store.d.ts.map +0 -1
  604. package/dist/journal/ambient-store.js.map +0 -1
  605. package/dist/journal/ambient.d.ts.map +0 -1
  606. package/dist/journal/ambient.js.map +0 -1
  607. package/dist/journal/attach-journal.d.ts.map +0 -1
  608. package/dist/journal/attach-journal.js.map +0 -1
  609. package/dist/journal/deviation-report.d.ts.map +0 -1
  610. package/dist/journal/deviation-report.js.map +0 -1
  611. package/dist/journal/deviation-service.d.ts.map +0 -1
  612. package/dist/journal/deviation-service.js.map +0 -1
  613. package/dist/journal/envelope-store.d.ts.map +0 -1
  614. package/dist/journal/envelope-store.js.map +0 -1
  615. package/dist/journal/envelope.d.ts.map +0 -1
  616. package/dist/journal/envelope.js.map +0 -1
  617. package/dist/journal/journal-query.d.ts.map +0 -1
  618. package/dist/journal/journal-query.js.map +0 -1
  619. package/dist/journal/journal-recorder.d.ts.map +0 -1
  620. package/dist/journal/journal-recorder.js.map +0 -1
  621. package/dist/journal/retention.d.ts.map +0 -1
  622. package/dist/journal/retention.js.map +0 -1
  623. package/dist/journal/rollups.d.ts.map +0 -1
  624. package/dist/journal/rollups.js.map +0 -1
  625. package/dist/journal/session-end.d.ts.map +0 -1
  626. package/dist/journal/session-end.js.map +0 -1
  627. package/dist/journal/session-journal.d.ts.map +0 -1
  628. package/dist/journal/session-journal.js.map +0 -1
  629. package/dist/license/license.d.ts.map +0 -1
  630. package/dist/license/license.js.map +0 -1
  631. package/dist/log.d.ts.map +0 -1
  632. package/dist/log.js.map +0 -1
  633. package/dist/mcp-proxy.d.ts.map +0 -1
  634. package/dist/mcp-proxy.js.map +0 -1
  635. package/dist/mcp.d.ts.map +0 -1
  636. package/dist/mcp.js.map +0 -1
  637. package/dist/oracles/flow-instrument-gaps.d.ts.map +0 -1
  638. package/dist/oracles/flow-instrument-gaps.js.map +0 -1
  639. package/dist/oracles/propose-consequences.d.ts.map +0 -1
  640. package/dist/oracles/propose-consequences.js.map +0 -1
  641. package/dist/oracles/self-instrument.d.ts.map +0 -1
  642. package/dist/oracles/self-instrument.js.map +0 -1
  643. package/dist/pairing-token.d.ts.map +0 -1
  644. package/dist/pairing-token.js.map +0 -1
  645. package/dist/phenomena/phenomena.d.ts.map +0 -1
  646. package/dist/phenomena/phenomena.js.map +0 -1
  647. package/dist/pool/browser-pool.d.ts.map +0 -1
  648. package/dist/pool/browser-pool.js.map +0 -1
  649. package/dist/pool/lease-reaper.d.ts.map +0 -1
  650. package/dist/pool/lease-reaper.js.map +0 -1
  651. package/dist/pool/playwright-launcher.d.ts.map +0 -1
  652. package/dist/pool/playwright-launcher.js.map +0 -1
  653. package/dist/project/baselines.d.ts.map +0 -1
  654. package/dist/project/baselines.js.map +0 -1
  655. package/dist/project/file-lock.d.ts.map +0 -1
  656. package/dist/project/file-lock.js.map +0 -1
  657. package/dist/project/fs-port.d.ts.map +0 -1
  658. package/dist/project/fs-port.js.map +0 -1
  659. package/dist/project/project-store.d.ts.map +0 -1
  660. package/dist/project/project-store.js.map +0 -1
  661. package/dist/project/project-tools.d.ts.map +0 -1
  662. package/dist/project/project-tools.js.map +0 -1
  663. package/dist/project/reticle-dir.d.ts.map +0 -1
  664. package/dist/project/reticle-dir.js.map +0 -1
  665. package/dist/runs/build-verification-run.d.ts.map +0 -1
  666. package/dist/runs/build-verification-run.js.map +0 -1
  667. package/dist/runs/profile-redact.d.ts.map +0 -1
  668. package/dist/runs/profile-redact.js.map +0 -1
  669. package/dist/runs/render-report.d.ts.map +0 -1
  670. package/dist/runs/render-report.js.map +0 -1
  671. package/dist/runs/repair-prompt.d.ts.map +0 -1
  672. package/dist/runs/repair-prompt.js.map +0 -1
  673. package/dist/runs/replay-mapping.d.ts.map +0 -1
  674. package/dist/runs/replay-mapping.js.map +0 -1
  675. package/dist/runs/reticle-runner.d.ts.map +0 -1
  676. package/dist/runs/reticle-runner.js.map +0 -1
  677. package/dist/runs/risk-classify.d.ts.map +0 -1
  678. package/dist/runs/risk-classify.js.map +0 -1
  679. package/dist/runs/run-diff.d.ts.map +0 -1
  680. package/dist/runs/run-diff.js.map +0 -1
  681. package/dist/runs/run-store.d.ts.map +0 -1
  682. package/dist/runs/run-store.js.map +0 -1
  683. package/dist/runs/run-tools.d.ts.map +0 -1
  684. package/dist/runs/run-tools.js.map +0 -1
  685. package/dist/runs/runner-port.d.ts.map +0 -1
  686. package/dist/runs/runner-port.js.map +0 -1
  687. package/dist/runs/verification-sync.d.ts.map +0 -1
  688. package/dist/runs/verification-sync.js.map +0 -1
  689. package/dist/runs/verify-http.d.ts.map +0 -1
  690. package/dist/runs/verify-http.js.map +0 -1
  691. package/dist/runs/verify-server.d.ts.map +0 -1
  692. package/dist/runs/verify-server.js.map +0 -1
  693. package/dist/server-version.d.ts.map +0 -1
  694. package/dist/server-version.js.map +0 -1
  695. package/dist/session/control-envelope.d.ts.map +0 -1
  696. package/dist/session/control-envelope.js.map +0 -1
  697. package/dist/session/live-control-tools.d.ts.map +0 -1
  698. package/dist/session/live-control-tools.js.map +0 -1
  699. package/dist/session/live-control.d.ts.map +0 -1
  700. package/dist/session/live-control.js.map +0 -1
  701. package/dist/session/observed-state.d.ts.map +0 -1
  702. package/dist/session/observed-state.js.map +0 -1
  703. package/dist/session/output-budget.d.ts.map +0 -1
  704. package/dist/session/output-budget.js.map +0 -1
  705. package/dist/session/presenter-args.d.ts.map +0 -1
  706. package/dist/session/presenter-args.js.map +0 -1
  707. package/dist/session/review-store.d.ts.map +0 -1
  708. package/dist/session/review-store.js.map +0 -1
  709. package/dist/session/session-health.d.ts.map +0 -1
  710. package/dist/session/session-health.js.map +0 -1
  711. package/dist/session/session-manager.d.ts.map +0 -1
  712. package/dist/session/session-manager.js.map +0 -1
  713. package/dist/session/session-readiness.d.ts.map +0 -1
  714. package/dist/session/session-readiness.js.map +0 -1
  715. package/dist/session/session-reaper.d.ts.map +0 -1
  716. package/dist/session/session-reaper.js.map +0 -1
  717. package/dist/session/session-recommendation.d.ts.map +0 -1
  718. package/dist/session/session-recommendation.js.map +0 -1
  719. package/dist/session/session-tools.d.ts.map +0 -1
  720. package/dist/session/session-tools.js.map +0 -1
  721. package/dist/session/session.d.ts.map +0 -1
  722. package/dist/session/session.js.map +0 -1
  723. package/dist/session/state-select.d.ts.map +0 -1
  724. package/dist/session/state-select.js.map +0 -1
  725. package/dist/telemetry/telemetry.d.ts.map +0 -1
  726. package/dist/telemetry/telemetry.js.map +0 -1
  727. package/dist/token-auth.d.ts.map +0 -1
  728. package/dist/token-auth.js.map +0 -1
  729. package/dist/tools/act-tools.d.ts.map +0 -1
  730. package/dist/tools/act-tools.js.map +0 -1
  731. package/dist/tools/act-view.d.ts.map +0 -1
  732. package/dist/tools/act-view.js.map +0 -1
  733. package/dist/tools/assert-grade.d.ts.map +0 -1
  734. package/dist/tools/assert-grade.js.map +0 -1
  735. package/dist/tools/browser-tools.d.ts.map +0 -1
  736. package/dist/tools/browser-tools.js.map +0 -1
  737. package/dist/tools/contract-tools.d.ts.map +0 -1
  738. package/dist/tools/contract-tools.js.map +0 -1
  739. package/dist/tools/dynamic-tools.d.ts.map +0 -1
  740. package/dist/tools/dynamic-tools.js.map +0 -1
  741. package/dist/tools/error-recovery.d.ts.map +0 -1
  742. package/dist/tools/error-recovery.js.map +0 -1
  743. package/dist/tools/invoke-tool.d.ts.map +0 -1
  744. package/dist/tools/invoke-tool.js.map +0 -1
  745. package/dist/tools/lease-tools.d.ts.map +0 -1
  746. package/dist/tools/lease-tools.js.map +0 -1
  747. package/dist/tools/merge-tools.d.ts.map +0 -1
  748. package/dist/tools/merge-tools.js.map +0 -1
  749. package/dist/tools/observe-tools.d.ts.map +0 -1
  750. package/dist/tools/observe-tools.js.map +0 -1
  751. package/dist/tools/profiles.d.ts.map +0 -1
  752. package/dist/tools/profiles.js.map +0 -1
  753. package/dist/tools/query-paginate.d.ts.map +0 -1
  754. package/dist/tools/query-paginate.js.map +0 -1
  755. package/dist/tools/read-tools.d.ts.map +0 -1
  756. package/dist/tools/read-tools.js.map +0 -1
  757. package/dist/tools/snapshot-delta.d.ts.map +0 -1
  758. package/dist/tools/snapshot-delta.js.map +0 -1
  759. package/dist/tools/tool-invoker.d.ts.map +0 -1
  760. package/dist/tools/tool-invoker.js.map +0 -1
  761. package/dist/tools/tool-kit.d.ts.map +0 -1
  762. package/dist/tools/tool-kit.js.map +0 -1
  763. package/dist/tools/tool-names.d.ts.map +0 -1
  764. package/dist/tools/tool-names.js.map +0 -1
  765. package/dist/tools/tools-helpers.d.ts.map +0 -1
  766. package/dist/tools/tools-helpers.js.map +0 -1
  767. package/dist/tools/tools.d.ts.map +0 -1
  768. package/dist/tools/tools.js.map +0 -1
  769. package/dist/update/update-checker.d.ts.map +0 -1
  770. package/dist/update/update-checker.js.map +0 -1
  771. package/dist/update/updater.d.ts.map +0 -1
  772. package/dist/update/updater.js.map +0 -1
  773. package/dist/visual/visual-diff.d.ts.map +0 -1
  774. package/dist/visual/visual-diff.js.map +0 -1
  775. package/dist/visual/visual-store.d.ts.map +0 -1
  776. package/dist/visual/visual-store.js.map +0 -1
  777. package/dist/visual/visual-tools.d.ts.map +0 -1
  778. package/dist/visual/visual-tools.js.map +0 -1
@@ -0,0 +1,31 @@
1
+ import { TelemetryAction } from '../cli-parse.js';
2
+ /**
3
+ * `reticle feedback [--rating 1-5] [--bug] "what happened"` — the human half of the feedback channel.
4
+ *
5
+ * Kept to a single command with no prompts, no editor, and no account: the cost of telling us
6
+ * something has to be lower than the cost of shrugging and moving on, or we only ever hear from people
7
+ * angry enough to open an issue. A bare rating is a valid report; the words are optional garnish.
8
+ *
9
+ * What is sent is PRINTED before it goes, every time. A channel that carries free text and does not
10
+ * show you the payload is asking for trust it has not earned.
11
+ */
12
+ export declare function handleFeedback(text: string, rating: number | undefined, bug: boolean): Promise<void>;
13
+ /**
14
+ * `reticle identify` — opt-in, and it shows the consent notice before it sends anything.
15
+ *
16
+ * Deliberately NOT interactive: a prompt that appears in the middle of someone's work is pressure,
17
+ * and this is the one command where the user must be choosing freely. They type what they want to
18
+ * share, or they never run it at all.
19
+ */
20
+ export declare function handleIdentify(parsed: {
21
+ context?: string;
22
+ company?: string;
23
+ email?: string;
24
+ forget: boolean;
25
+ }): Promise<void>;
26
+ /**
27
+ * `reticle telemetry [status|enable|disable]` — the user-facing control for anonymous usage metrics.
28
+ * `disable` persists a machine-wide opt-out (survives shells, unlike RETICLE_TELEMETRY=0); `status`
29
+ * says what's on, why, and where the full policy lives. Human-readable to stdout, like `doctor`.
30
+ */
31
+ export declare function handleTelemetry(action: TelemetryAction): void;
@@ -0,0 +1,102 @@
1
+ import { FeedbackKind, FeedbackSource } from '@reticlehq/core';
2
+ import { BUG_FLAG, RATING_FLAG } from '../cli-parse.js';
3
+ import { describeFeedbackPayload, submitFeedback } from './feedback.js';
4
+ import { describeTelemetry, setTelemetryEnabled } from './telemetry.js';
5
+ import { TelemetryAction } from '../cli-parse.js';
6
+ import { clearIdentity, IDENTIFY_NOTICE, readIdentity, saveIdentity, submitIdentity, UsageContextKind, } from './identify.js';
7
+ /**
8
+ * `reticle feedback [--rating 1-5] [--bug] "what happened"` — the human half of the feedback channel.
9
+ *
10
+ * Kept to a single command with no prompts, no editor, and no account: the cost of telling us
11
+ * something has to be lower than the cost of shrugging and moving on, or we only ever hear from people
12
+ * angry enough to open an issue. A bare rating is a valid report; the words are optional garnish.
13
+ *
14
+ * What is sent is PRINTED before it goes, every time. A channel that carries free text and does not
15
+ * show you the payload is asking for trust it has not earned.
16
+ */
17
+ export async function handleFeedback(text, rating, bug) {
18
+ const line = (s) => {
19
+ process.stdout.write(`${s}\n`);
20
+ };
21
+ if (text === '' && rating === undefined) {
22
+ line(`usage: reticle feedback [${RATING_FLAG} 1-5] [${BUG_FLAG}] "what worked, what didn't"`);
23
+ line(' your words go to the maintainers; nothing from your app is ever included.');
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+ const receipt = await submitFeedback({
28
+ source: FeedbackSource.HUMAN,
29
+ kind: bug ? FeedbackKind.BUG : FeedbackKind.EXPERIENCE,
30
+ // A rating with no words is a real report, but the schema wants text — say what the rating means.
31
+ text: text === '' ? `rated ${String(rating)}/5 with no comment` : text,
32
+ ...(rating !== undefined ? { rating } : {}),
33
+ });
34
+ line(`sending ${JSON.stringify(describeFeedbackPayload(receipt.context))}`);
35
+ if (receipt.redacted.length > 0) {
36
+ line(`redacted ${receipt.redacted.join(', ')} (removed before sending)`);
37
+ }
38
+ line(receipt.sent
39
+ ? 'thanks your feedback is in. it genuinely changes what gets built next.'
40
+ : `not sent ${receipt.reason ?? 'unknown reason'}`);
41
+ }
42
+ /**
43
+ * `reticle identify` — opt-in, and it shows the consent notice before it sends anything.
44
+ *
45
+ * Deliberately NOT interactive: a prompt that appears in the middle of someone's work is pressure,
46
+ * and this is the one command where the user must be choosing freely. They type what they want to
47
+ * share, or they never run it at all.
48
+ */
49
+ export async function handleIdentify(parsed) {
50
+ const line = (s) => {
51
+ process.stdout.write(`${s}\n`);
52
+ };
53
+ if (parsed.forget) {
54
+ clearIdentity();
55
+ line('forgotten the local identity file is deleted; nothing further is sent.');
56
+ line(' to have what was already sent removed, email support@reticlehq.com');
57
+ return;
58
+ }
59
+ const context = Object.values(UsageContextKind).find((k) => k === parsed.context);
60
+ if (context === undefined) {
61
+ const existing = readIdentity();
62
+ if (existing !== undefined)
63
+ line(`current ${JSON.stringify(existing)}`);
64
+ line(`usage: reticle identify --context <${Object.values(UsageContextKind).join('|')}>`);
65
+ line(' [--company "Acme"] [--email you@acme.com] [--forget]');
66
+ line('');
67
+ line(IDENTIFY_NOTICE);
68
+ process.exitCode = existing === undefined ? 1 : 0;
69
+ return;
70
+ }
71
+ const identity = {
72
+ context,
73
+ ...(parsed.company !== undefined ? { company: parsed.company } : {}),
74
+ ...(parsed.email !== undefined ? { email: parsed.email } : {}),
75
+ };
76
+ line(IDENTIFY_NOTICE);
77
+ line('');
78
+ line(`sending ${JSON.stringify(identity)}`);
79
+ saveIdentity(identity);
80
+ const sent = await submitIdentity(identity);
81
+ line(sent
82
+ ? 'thanks saved and sent. we may reach out; `reticle identify --forget` undoes this.'
83
+ : 'not sent telemetry is disabled on this machine, so it was saved locally only.');
84
+ }
85
+ /**
86
+ * `reticle telemetry [status|enable|disable]` — the user-facing control for anonymous usage metrics.
87
+ * `disable` persists a machine-wide opt-out (survives shells, unlike RETICLE_TELEMETRY=0); `status`
88
+ * says what's on, why, and where the full policy lives. Human-readable to stdout, like `doctor`.
89
+ */
90
+ export function handleTelemetry(action) {
91
+ const line = (s) => {
92
+ process.stdout.write(`${s}\n`);
93
+ };
94
+ if (action !== TelemetryAction.STATUS) {
95
+ setTelemetryEnabled(action === TelemetryAction.ENABLE);
96
+ }
97
+ const state = describeTelemetry();
98
+ line(`telemetry ${state.enabled ? 'enabled' : 'disabled'} (${state.reason})`);
99
+ line(`policy ${state.policyUrl}`);
100
+ if (state.enabled)
101
+ line('opt out reticle telemetry disable (or RETICLE_TELEMETRY=0 / DO_NOT_TRACK=1)');
102
+ }
@@ -0,0 +1,32 @@
1
+ import { McpScope, type Feedback } from '@reticlehq/core';
2
+ /** The context fields — the whole `Feedback` shape minus what the author supplies. */
3
+ export type FeedbackContext = Pick<Feedback, 'stack' | 'stackMajor' | 'runtime' | 'engine' | 'driver' | 'client' | 'clientVersion' | 'mcpScope'>;
4
+ /**
5
+ * The project's framework and its MAJOR version, or `{}` when package.json is absent, unreadable, or
6
+ * names nothing we recognize. The major comes from `parseMajor` — the same range parser `reticle init`
7
+ * uses to decide React 19 source mapping — so a range like `^15.0.0-canary.3` narrows the same way in
8
+ * both places instead of via a second, subtly different reader.
9
+ */
10
+ export declare function detectStack(cwd: string, read?: (path: string) => string): {
11
+ stack?: string;
12
+ stackMajor?: number;
13
+ };
14
+ /**
15
+ * User scope unless the project checks in its own MCP registration. `reticle init` deliberately
16
+ * registers ONCE at user scope, so `project` here means the team wired it up by hand — which is
17
+ * itself the interesting signal.
18
+ */
19
+ export declare function detectMcpScope(cwd: string, exists?: (path: string) => boolean): McpScope;
20
+ export declare function setMcpClientNameHook(hook: () => {
21
+ name?: string;
22
+ version?: string;
23
+ } | undefined): void;
24
+ /** What the connected session knows about itself — the shell it runs in and its rendering engine. */
25
+ export interface SessionFacts {
26
+ runtime?: string;
27
+ engine?: string;
28
+ /** True when Reticle drives the page over CDP rather than observing the human's own browser. */
29
+ driven?: boolean;
30
+ }
31
+ /** Assemble the full context. Every field independently optional — a partial context still ships. */
32
+ export declare function feedbackContext(cwd: string, session?: SessionFacts): FeedbackContext;
@@ -0,0 +1,143 @@
1
+ /**
2
+ * The environment context stapled to every feedback report. Feedback without it is a complaint;
3
+ * feedback with it is a work item — "reticle_act misses the click" is unactionable, "reticle_act
4
+ * misses the click on Tauri + SvelteKit under a CDP driver" names the bug.
5
+ *
6
+ * Everything here is detected LOCALLY from files and env already on the machine, and every field is
7
+ * low-cardinality by construction (an enum, or a framework name off a fixed list). No paths, no repo
8
+ * names, no dependency inventory, no UA string — the same non-identifying bar the rest of telemetry
9
+ * holds to. Detection is entirely best-effort: an unreadable package.json or an SDK too old to report
10
+ * its runtime yields `undefined`, never a throw and never a guess.
11
+ */
12
+ import { readFileSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ import { AppRuntime, McpScope, PageDriver } from '@reticlehq/core';
15
+ import { parseMajor } from '../init/detect.js';
16
+ /**
17
+ * Dependency → reported stack, in resolution order. Meta-frameworks come FIRST: a Next app also
18
+ * depends on react, and reporting `react` for it would collapse the single most important segment
19
+ * we have into the generic bucket.
20
+ *
21
+ * Deliberately NOT reusing `init/detect.ts`. That module answers a different question — "which build
22
+ * integration do I install?" — so its enum stops at next/vite/sveltekit/html. Widening it to carry
23
+ * vue/astro/solid would make `reticle init` branch on frameworks it has no install path for.
24
+ */
25
+ const STACK_BY_DEP = [
26
+ ['next', 'next'],
27
+ ['@sveltejs/kit', 'sveltekit'],
28
+ ['nuxt', 'nuxt'],
29
+ ['astro', 'astro'],
30
+ ['@remix-run/react', 'remix'],
31
+ ['@angular/core', 'angular'],
32
+ ['react', 'react'],
33
+ ['vue', 'vue'],
34
+ ['svelte', 'svelte'],
35
+ ['solid-js', 'solid'],
36
+ ['vite', 'vite'],
37
+ ];
38
+ const PACKAGE_JSON = 'package.json';
39
+ /** A project-scoped MCP registration lives in one of these; `reticle init` writes user scope instead. */
40
+ const PROJECT_MCP_FILES = ['.mcp.json', join('.cursor', 'mcp.json'), join('.vscode', 'mcp.json')];
41
+ /**
42
+ * The project's framework and its MAJOR version, or `{}` when package.json is absent, unreadable, or
43
+ * names nothing we recognize. The major comes from `parseMajor` — the same range parser `reticle init`
44
+ * uses to decide React 19 source mapping — so a range like `^15.0.0-canary.3` narrows the same way in
45
+ * both places instead of via a second, subtly different reader.
46
+ */
47
+ export function detectStack(cwd, read = readFile) {
48
+ let pkg;
49
+ try {
50
+ pkg = JSON.parse(read(join(cwd, PACKAGE_JSON)));
51
+ }
52
+ catch {
53
+ return {};
54
+ }
55
+ const deps = { ...pkg.devDependencies, ...pkg.dependencies };
56
+ for (const [dep, stack] of STACK_BY_DEP) {
57
+ const range = deps[dep];
58
+ if (range === undefined)
59
+ continue;
60
+ const stackMajor = parseMajor(range);
61
+ return { stack, ...(stackMajor !== undefined ? { stackMajor } : {}) };
62
+ }
63
+ return {};
64
+ }
65
+ /**
66
+ * User scope unless the project checks in its own MCP registration. `reticle init` deliberately
67
+ * registers ONCE at user scope, so `project` here means the team wired it up by hand — which is
68
+ * itself the interesting signal.
69
+ */
70
+ export function detectMcpScope(cwd, exists = fileExists) {
71
+ return PROJECT_MCP_FILES.some((file) => exists(join(cwd, file)))
72
+ ? McpScope.PROJECT
73
+ : McpScope.USER;
74
+ }
75
+ function readFile(path) {
76
+ return readFileSync(path, 'utf8');
77
+ }
78
+ function fileExists(path) {
79
+ try {
80
+ readFileSync(path);
81
+ return true;
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ }
87
+ /**
88
+ * The MCP client on the other end, self-reported in its `initialize` handshake (`claude-code`,
89
+ * `cursor-vscode`, …). Read through a HOOK rather than sniffing env vars: the handshake is the
90
+ * client's own claim about itself, while an env-var table is a guess that silently rots every time a
91
+ * vendor renames a variable. Unset (a CLI run with no MCP peer) simply reports no client.
92
+ */
93
+ let clientNameHook;
94
+ export function setMcpClientNameHook(hook) {
95
+ clientNameHook = hook;
96
+ }
97
+ /**
98
+ * The client's own name and version from its handshake.
99
+ *
100
+ * Note what is NOT here and cannot be: the MODEL. MCP's `clientInfo` carries a name, a title and a
101
+ * version and has no concept of a model, so the transport genuinely cannot tell us. The agent
102
+ * self-reports it on the feedback itself, which is the only mechanism available and a reliable one
103
+ * given the report is already something the agent authored.
104
+ */
105
+ function detectClient() {
106
+ try {
107
+ const info = clientNameHook?.();
108
+ const name = info?.name;
109
+ const version = info?.version;
110
+ return {
111
+ ...(name !== undefined && name !== '' ? { client: name.slice(0, 64) } : {}),
112
+ ...(version !== undefined && version !== '' ? { clientVersion: version.slice(0, 32) } : {}),
113
+ };
114
+ }
115
+ catch {
116
+ return {};
117
+ }
118
+ }
119
+ function asRuntime(value) {
120
+ return Object.values(AppRuntime).find((known) => known === value);
121
+ }
122
+ function asEngine(value) {
123
+ // The SDK already narrows to blink/gecko/webkit before it reports, so anything else is a stale or
124
+ // hand-forged payload — drop it rather than widen the enum at the boundary.
125
+ const known = ['blink', 'gecko', 'webkit'];
126
+ return known.find((engine) => engine === value);
127
+ }
128
+ /** Assemble the full context. Every field independently optional — a partial context still ships. */
129
+ export function feedbackContext(cwd, session) {
130
+ const runtime = asRuntime(session?.runtime);
131
+ const engine = asEngine(session?.engine);
132
+ const client = detectClient();
133
+ return {
134
+ ...detectStack(cwd),
135
+ ...client,
136
+ ...(runtime !== undefined ? { runtime } : {}),
137
+ ...(engine !== undefined ? { engine } : {}),
138
+ ...(session?.driven !== undefined
139
+ ? { driver: session.driven ? PageDriver.CDP : PageDriver.SDK }
140
+ : {}),
141
+ mcpScope: detectMcpScope(cwd),
142
+ };
143
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The feedback channel — the one place in Reticle that sends words someone wrote.
3
+ *
4
+ * Reticle is built for agents, and until now nothing closed the loop: when a tool misbehaved, or a
5
+ * verification came back undecidable, or an observer simply could not see the thing that mattered,
6
+ * that knowledge died in the agent's context window. This module is the return path. An agent files a
7
+ * report through `reticle_feedback` when a tool fails it; a human files one through `reticle
8
+ * feedback` with a rating and their own words.
9
+ *
10
+ * Three properties are non-negotiable here, because free text is a different privacy class from the
11
+ * event counters the rest of telemetry sends:
12
+ *
13
+ * 1. NEVER PASSIVE. There is no code path that emits feedback on its own. Every event is the direct
14
+ * result of an explicit call someone made carrying content they authored. Nothing is scraped
15
+ * from the app, the DOM, the network log, or the repo.
16
+ * 2. REDACTED BEFORE THE WIRE. `redactFeedbackText` strips the credential/PII shapes that leak into
17
+ * a pasted trace even when the author meant no harm. It runs client-side, so the redaction is
18
+ * auditable in this repo rather than promised in a policy.
19
+ * 3. INDEPENDENTLY DISABLE-ABLE. `RETICLE_FEEDBACK=0` kills the channel while leaving anonymous
20
+ * adoption metrics on — the setting an org wants when counters are fine but prose is not. Every
21
+ * existing switch (`RETICLE_TELEMETRY=0`, `DO_NOT_TRACK`, `reticle telemetry disable`) still
22
+ * disables it too, since it rides the same emitter.
23
+ */
24
+ import { type Feedback } from '@reticlehq/core';
25
+ import { type SessionFacts } from './feedback-context.js';
26
+ /** Kills the feedback channel ONLY — adoption counters keep flowing. */
27
+ export declare const FEEDBACK_ENV = "RETICLE_FEEDBACK";
28
+ /** What replaces a redacted match. Visible on purpose: a reader must see that something was removed. */
29
+ export declare const REDACTED = "[redacted]";
30
+ export interface Redaction {
31
+ text: string;
32
+ /** Which rules fired, deduped. Surfaced back to the author so a redaction is never silent. */
33
+ removed: string[];
34
+ }
35
+ /** Strip credential/PII shapes and cap the length. Pure — the tests read like a spec of what leaks. */
36
+ export declare function redactFeedbackText(input: string, max: number): Redaction;
37
+ /** True when the feedback channel is switched off on its own (the emitter's switches apply as well). */
38
+ export declare function feedbackDisabled(env?: NodeJS.ProcessEnv): boolean;
39
+ /** What the author supplies; the environment context is detected, never asked for. */
40
+ export type FeedbackInput = Pick<Feedback, 'source' | 'kind' | 'text' | 'trace' | 'rating' | 'need' | 'impact' | 'currentApproach' | 'model'>;
41
+ export interface FeedbackReceipt {
42
+ /** False when a kill switch is on — the report was DROPPED, and the caller is told so plainly. */
43
+ sent: boolean;
44
+ reason?: string;
45
+ /** Which redaction rules fired. Empty when nothing needed removing. */
46
+ redacted: string[];
47
+ /** The exact context that went with it, echoed back so the send is never a black box. */
48
+ context: Partial<Feedback>;
49
+ }
50
+ /**
51
+ * Redact, validate, and emit one feedback report. Returns a receipt rather than throwing: a feedback
52
+ * send that fails must never take down the tool call that reported the failure — that would punish
53
+ * the exact behaviour we are trying to encourage.
54
+ */
55
+ export declare function submitFeedback(input: FeedbackInput, opts?: {
56
+ cwd?: string;
57
+ session?: SessionFacts;
58
+ env?: NodeJS.ProcessEnv;
59
+ }): Promise<FeedbackReceipt>;
60
+ /**
61
+ * The receipt's context PLUS the fields the emitter stamps on every event regardless of kind — the
62
+ * reticle version, the OS, and whether this is CI. They are the single most-asked question of any bug
63
+ * report ("what version?"), so they are echoed here rather than left as an invisible claim: what the
64
+ * CLI prints is then genuinely everything that goes.
65
+ */
66
+ export declare function describeFeedbackPayload(context: Partial<Feedback>): Record<string, unknown>;
@@ -0,0 +1,175 @@
1
+ /**
2
+ * The feedback channel — the one place in Reticle that sends words someone wrote.
3
+ *
4
+ * Reticle is built for agents, and until now nothing closed the loop: when a tool misbehaved, or a
5
+ * verification came back undecidable, or an observer simply could not see the thing that mattered,
6
+ * that knowledge died in the agent's context window. This module is the return path. An agent files a
7
+ * report through `reticle_feedback` when a tool fails it; a human files one through `reticle
8
+ * feedback` with a rating and their own words.
9
+ *
10
+ * Three properties are non-negotiable here, because free text is a different privacy class from the
11
+ * event counters the rest of telemetry sends:
12
+ *
13
+ * 1. NEVER PASSIVE. There is no code path that emits feedback on its own. Every event is the direct
14
+ * result of an explicit call someone made carrying content they authored. Nothing is scraped
15
+ * from the app, the DOM, the network log, or the repo.
16
+ * 2. REDACTED BEFORE THE WIRE. `redactFeedbackText` strips the credential/PII shapes that leak into
17
+ * a pasted trace even when the author meant no harm. It runs client-side, so the redaction is
18
+ * auditable in this repo rather than promised in a policy.
19
+ * 3. INDEPENDENTLY DISABLE-ABLE. `RETICLE_FEEDBACK=0` kills the channel while leaving anonymous
20
+ * adoption metrics on — the setting an org wants when counters are fine but prose is not. Every
21
+ * existing switch (`RETICLE_TELEMETRY=0`, `DO_NOT_TRACK`, `reticle telemetry disable`) still
22
+ * disables it too, since it rides the same emitter.
23
+ */
24
+ import { FeedbackSchema, FEEDBACK_TEXT_MAX, FEEDBACK_TRACE_MAX, FEEDBACK_FIELD_MAX, TelemetryEventKind, } from '@reticlehq/core';
25
+ import { platform } from 'node:os';
26
+ import { getTelemetry } from './telemetry.js';
27
+ import { SERVER_VERSION } from '../server-version.js';
28
+ import { feedbackContext } from './feedback-context.js';
29
+ /** Kills the feedback channel ONLY — adoption counters keep flowing. */
30
+ export const FEEDBACK_ENV = 'RETICLE_FEEDBACK';
31
+ /** What replaces a redacted match. Visible on purpose: a reader must see that something was removed. */
32
+ export const REDACTED = '[redacted]';
33
+ /**
34
+ * The shapes that leak. Ordered most-specific first — a URL carrying inline credentials must be
35
+ * caught as a URL before the bare-token rule chews the middle out of it.
36
+ *
37
+ * This is a net, not a proof. It cannot catch a secret that looks like an ordinary word, which is
38
+ * exactly why the tool description tells the agent not to paste app source or user data in the first
39
+ * place. Defense in depth: instruct first, redact second, cap third.
40
+ */
41
+ const REDACTIONS = [
42
+ // scheme://user:pass@host — the credential is in the authority section.
43
+ { pattern: /\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+:[^\s/@]+@/gi, label: 'url-credentials' },
44
+ { pattern: /\b[\w.%+-]+@[\w.-]+\.[a-z]{2,}\b/gi, label: 'email' },
45
+ // Credential assignments: the KEY stays (it is the useful part), the VALUE goes. The auth SCHEME
46
+ // (`Bearer`, `Basic`, `Token`) is consumed as part of the value, not left as the value — matching
47
+ // only `\S+` after the separator ate the word "Bearer" and published the secret right behind it.
48
+ {
49
+ pattern: /\b(authorization|api[-_]?key|secret|token|password|passwd|pwd)\b(?:\s*[:=]\s*|\s+)(?:(?:bearer|basic|token|digest)\s+)?\S+/gi,
50
+ label: 'credential-assignment',
51
+ },
52
+ // Vendor key formats that are self-identifying (sk-…, ghp_…, AKIA…, xoxb-…, eyJ… JWTs).
53
+ { pattern: /\b(?:sk|pk|rk)-[A-Za-z0-9_-]{16,}\b/g, label: 'vendor-key' },
54
+ { pattern: /\bgh[pousr]_[A-Za-z0-9]{20,}\b/g, label: 'github-token' },
55
+ { pattern: /\bAKIA[0-9A-Z]{16}\b/g, label: 'aws-key' },
56
+ { pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, label: 'slack-token' },
57
+ { pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g, label: 'jwt' },
58
+ // Home directories carry the account name, and a trace is full of them.
59
+ { pattern: /(?:\/Users\/|\/home\/|[A-Z]:\\Users\\)[^\s/\\:"']+/g, label: 'home-path' },
60
+ ];
61
+ /** Strip credential/PII shapes and cap the length. Pure — the tests read like a spec of what leaks. */
62
+ export function redactFeedbackText(input, max) {
63
+ const removed = new Set();
64
+ let text = input;
65
+ for (const { pattern, label } of REDACTIONS) {
66
+ text = text.replace(pattern, (_match, ...groups) => {
67
+ removed.add(label);
68
+ // A rule with a leading capture keeps it (the scheme, the `api_key=` key) so the reader still
69
+ // sees WHAT was removed, not just that something was.
70
+ const prefix = typeof groups[0] === 'string' ? groups[0] : '';
71
+ return `${prefix}${REDACTED}`;
72
+ });
73
+ }
74
+ return { text: text.slice(0, max), removed: [...removed] };
75
+ }
76
+ /** True when the feedback channel is switched off on its own (the emitter's switches apply as well). */
77
+ export function feedbackDisabled(env = process.env) {
78
+ const value = (env[FEEDBACK_ENV] ?? '').toLowerCase();
79
+ return value === '0' || value === 'false' || value === 'off' || value === 'no';
80
+ }
81
+ /**
82
+ * The fields an author writes, and therefore the fields that must be redacted. ONE list, used both to
83
+ * redact and to assemble — so a new field cannot be added to one and missed by the other.
84
+ *
85
+ * `model` is deliberately included: it is agent-supplied text like the rest, and while a model name
86
+ * is not sensitive, exempting it would re-introduce the "which fields are safe?" judgement call that
87
+ * caused the original gap.
88
+ */
89
+ const AUTHOR_WRITTEN_FIELDS = new Set([
90
+ 'text',
91
+ 'trace',
92
+ 'need',
93
+ 'impact',
94
+ 'currentApproach',
95
+ 'model',
96
+ ]);
97
+ /** Per-field caps; anything unlisted uses the standard field cap. */
98
+ const FIELD_CAPS = {
99
+ text: FEEDBACK_TEXT_MAX,
100
+ trace: FEEDBACK_TRACE_MAX,
101
+ model: 64,
102
+ };
103
+ /**
104
+ * Redact, validate, and emit one feedback report. Returns a receipt rather than throwing: a feedback
105
+ * send that fails must never take down the tool call that reported the failure — that would punish
106
+ * the exact behaviour we are trying to encourage.
107
+ */
108
+ export async function submitFeedback(input, opts = {}) {
109
+ const env = opts.env ?? process.env;
110
+ const context = feedbackContext(opts.cwd ?? process.cwd(), opts.session);
111
+ // Redact EVERY author-written field, derived from the input rather than listed.
112
+ //
113
+ // The first version named `text` and `trace` explicitly. When `need`, `impact` and
114
+ // `currentApproach` were added later they silently bypassed redaction entirely — three new
115
+ // free-text fields going to the wire raw, and a `currentApproach` reading "hardcoding the token
116
+ // sk-…" would have shipped the token. Enumerating the fields to protect is the same class of
117
+ // mistake as hand-copying an enum: correct on the day it is written, quietly wrong at the next
118
+ // addition. Deriving the set means a sixth field is covered the moment it exists.
119
+ const redactions = new Map();
120
+ for (const [key, value] of Object.entries(input)) {
121
+ if (typeof value !== 'string' || value === '')
122
+ continue;
123
+ if (!AUTHOR_WRITTEN_FIELDS.has(key))
124
+ continue;
125
+ redactions.set(key, redactFeedbackText(value, FIELD_CAPS[key] ?? FEEDBACK_FIELD_MAX));
126
+ }
127
+ const body = redactions.get('text') ?? { text: '', removed: [] };
128
+ const redacted = [...new Set([...redactions.values()].flatMap((r) => r.removed))];
129
+ if (feedbackDisabled(env)) {
130
+ return { sent: false, reason: `feedback is disabled by ${FEEDBACK_ENV}`, redacted, context };
131
+ }
132
+ const telemetry = getTelemetry();
133
+ if (!telemetry.enabled) {
134
+ return {
135
+ sent: false,
136
+ reason: 'telemetry is disabled on this machine, so feedback has nowhere to go',
137
+ redacted,
138
+ context,
139
+ };
140
+ }
141
+ const parsed = FeedbackSchema.safeParse({
142
+ source: input.source,
143
+ kind: input.kind,
144
+ // Every author-written field, redacted. Built from the map so nothing can be forgotten here
145
+ // either — the field list exists in exactly one place.
146
+ ...Object.fromEntries([...redactions].filter(([, r]) => r.text !== '').map(([key, r]) => [key, r.text])),
147
+ text: body.text,
148
+ ...(input.rating !== undefined ? { rating: input.rating } : {}),
149
+ ...context,
150
+ });
151
+ if (!parsed.success) {
152
+ return {
153
+ sent: false,
154
+ reason: parsed.error.issues[0]?.message ?? 'invalid feedback',
155
+ redacted,
156
+ context,
157
+ };
158
+ }
159
+ await telemetry.emit(TelemetryEventKind.FEEDBACK_SUBMITTED, { feedback: parsed.data });
160
+ return { sent: true, redacted, context };
161
+ }
162
+ /**
163
+ * The receipt's context PLUS the fields the emitter stamps on every event regardless of kind — the
164
+ * reticle version, the OS, and whether this is CI. They are the single most-asked question of any bug
165
+ * report ("what version?"), so they are echoed here rather than left as an invisible claim: what the
166
+ * CLI prints is then genuinely everything that goes.
167
+ */
168
+ export function describeFeedbackPayload(context) {
169
+ return {
170
+ ...context,
171
+ version: SERVER_VERSION,
172
+ os: platform(),
173
+ ci: process.env['CI'] !== undefined,
174
+ };
175
+ }
@@ -0,0 +1,21 @@
1
+ import { GitState, RepoForge } from '@reticlehq/core';
2
+ export interface GitFacts {
3
+ /** none | local_only (init'd, never pushed) | remote (has an origin). */
4
+ state: GitState;
5
+ /** The NORMALIZED origin — hashed by the caller, never sent raw. Absent unless state is `remote`. */
6
+ origin?: string;
7
+ /** Which forge hosts it, bucketed. Absent unless state is `remote`. */
8
+ forge?: RepoForge;
9
+ }
10
+ /** `git@github.com:Acme/Web.git` / `https://u:p@github.com/Acme/Web` → `github.com/acme/web`. */
11
+ export declare const normalizeGitOrigin: (url: string) => string;
12
+ /** Bucket a normalized origin by its host. Unknown hosts are `self_hosted` — never the host itself. */
13
+ export declare function forgeOf(normalizedOrigin: string): RepoForge;
14
+ type FileReader = (path: string) => string;
15
+ type PathExists = (path: string) => boolean;
16
+ /**
17
+ * Walk up from `cwd` looking for a `.git`, and report what is there. Never throws: an unreadable or
18
+ * malformed config reports the state we could confirm rather than failing a startup path.
19
+ */
20
+ export declare function gitFacts(cwd: string, read?: FileReader, exists?: PathExists): GitFacts;
21
+ export {};