@getrift/rift 0.1.0-beta.2 → 0.1.0-beta.21

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 (390) hide show
  1. package/README.md +35 -9
  2. package/dist/src/auth/keychain.d.ts +9 -0
  3. package/dist/src/auth/keychain.d.ts.map +1 -1
  4. package/dist/src/auth/keychain.js +37 -0
  5. package/dist/src/auth/keychain.js.map +1 -1
  6. package/dist/src/capture/auto-capture.d.ts +7 -0
  7. package/dist/src/capture/auto-capture.d.ts.map +1 -1
  8. package/dist/src/capture/auto-capture.js +82 -15
  9. package/dist/src/capture/auto-capture.js.map +1 -1
  10. package/dist/src/capture/auto-repair.d.ts +110 -0
  11. package/dist/src/capture/auto-repair.d.ts.map +1 -0
  12. package/dist/src/capture/auto-repair.js +269 -0
  13. package/dist/src/capture/auto-repair.js.map +1 -0
  14. package/dist/src/capture/codex-cli-triage-provider.d.ts.map +1 -1
  15. package/dist/src/capture/codex-cli-triage-provider.js +4 -3
  16. package/dist/src/capture/codex-cli-triage-provider.js.map +1 -1
  17. package/dist/src/capture/observability.d.ts +42 -0
  18. package/dist/src/capture/observability.d.ts.map +1 -1
  19. package/dist/src/capture/observability.js +45 -4
  20. package/dist/src/capture/observability.js.map +1 -1
  21. package/dist/src/capture/recover-quarantine.d.ts +260 -0
  22. package/dist/src/capture/recover-quarantine.d.ts.map +1 -0
  23. package/dist/src/capture/recover-quarantine.js +522 -0
  24. package/dist/src/capture/recover-quarantine.js.map +1 -0
  25. package/dist/src/cli/commands/backfill.d.ts.map +1 -1
  26. package/dist/src/cli/commands/backfill.js +5 -2
  27. package/dist/src/cli/commands/backfill.js.map +1 -1
  28. package/dist/src/cli/commands/capture-recover.d.ts +40 -0
  29. package/dist/src/cli/commands/capture-recover.d.ts.map +1 -0
  30. package/dist/src/cli/commands/capture-recover.js +184 -0
  31. package/dist/src/cli/commands/capture-recover.js.map +1 -0
  32. package/dist/src/cli/commands/capture.d.ts.map +1 -1
  33. package/dist/src/cli/commands/capture.js +96 -5
  34. package/dist/src/cli/commands/capture.js.map +1 -1
  35. package/dist/src/cli/commands/doctor.d.ts +6 -0
  36. package/dist/src/cli/commands/doctor.d.ts.map +1 -0
  37. package/dist/src/cli/commands/doctor.js +242 -0
  38. package/dist/src/cli/commands/doctor.js.map +1 -0
  39. package/dist/src/cli/commands/feedback.d.ts +12 -0
  40. package/dist/src/cli/commands/feedback.d.ts.map +1 -1
  41. package/dist/src/cli/commands/feedback.js +93 -4
  42. package/dist/src/cli/commands/feedback.js.map +1 -1
  43. package/dist/src/cli/commands/mcp-install.js +5 -2
  44. package/dist/src/cli/commands/mcp-install.js.map +1 -1
  45. package/dist/src/cli/commands/menubar.d.ts +80 -0
  46. package/dist/src/cli/commands/menubar.d.ts.map +1 -0
  47. package/dist/src/cli/commands/menubar.js +388 -0
  48. package/dist/src/cli/commands/menubar.js.map +1 -0
  49. package/dist/src/cli/commands/onboard.d.ts +143 -5
  50. package/dist/src/cli/commands/onboard.d.ts.map +1 -1
  51. package/dist/src/cli/commands/onboard.js +844 -188
  52. package/dist/src/cli/commands/onboard.js.map +1 -1
  53. package/dist/src/cli/commands/rebuild.d.ts.map +1 -1
  54. package/dist/src/cli/commands/rebuild.js +6 -3
  55. package/dist/src/cli/commands/rebuild.js.map +1 -1
  56. package/dist/src/cli/commands/reconcile.d.ts.map +1 -1
  57. package/dist/src/cli/commands/reconcile.js +12 -0
  58. package/dist/src/cli/commands/reconcile.js.map +1 -1
  59. package/dist/src/cli/commands/review.d.ts.map +1 -1
  60. package/dist/src/cli/commands/review.js +22 -7
  61. package/dist/src/cli/commands/review.js.map +1 -1
  62. package/dist/src/cli/commands/search.d.ts +2 -0
  63. package/dist/src/cli/commands/search.d.ts.map +1 -1
  64. package/dist/src/cli/commands/search.js +34 -4
  65. package/dist/src/cli/commands/search.js.map +1 -1
  66. package/dist/src/cli/commands/status.d.ts +9 -7
  67. package/dist/src/cli/commands/status.d.ts.map +1 -1
  68. package/dist/src/cli/commands/status.js +117 -12
  69. package/dist/src/cli/commands/status.js.map +1 -1
  70. package/dist/src/cli/commands/token-issue.d.ts.map +1 -1
  71. package/dist/src/cli/commands/token-issue.js +9 -1
  72. package/dist/src/cli/commands/token-issue.js.map +1 -1
  73. package/dist/src/cli/commands/triage.d.ts.map +1 -1
  74. package/dist/src/cli/commands/triage.js +7 -5
  75. package/dist/src/cli/commands/triage.js.map +1 -1
  76. package/dist/src/cli/commands/update.d.ts +80 -0
  77. package/dist/src/cli/commands/update.d.ts.map +1 -0
  78. package/dist/src/cli/commands/update.js +390 -0
  79. package/dist/src/cli/commands/update.js.map +1 -0
  80. package/dist/src/cli/default-config-path.d.ts +15 -0
  81. package/dist/src/cli/default-config-path.d.ts.map +1 -0
  82. package/dist/src/cli/default-config-path.js +27 -0
  83. package/dist/src/cli/default-config-path.js.map +1 -0
  84. package/dist/src/cli/feedback/feedback-config.d.ts +46 -0
  85. package/dist/src/cli/feedback/feedback-config.d.ts.map +1 -1
  86. package/dist/src/cli/feedback/feedback-config.js +130 -4
  87. package/dist/src/cli/feedback/feedback-config.js.map +1 -1
  88. package/dist/src/cli/feedback/feedback-history.d.ts +7 -0
  89. package/dist/src/cli/feedback/feedback-history.d.ts.map +1 -1
  90. package/dist/src/cli/feedback/feedback-history.js +39 -9
  91. package/dist/src/cli/feedback/feedback-history.js.map +1 -1
  92. package/dist/src/cli/feedback/feedback-payload.d.ts +22 -1
  93. package/dist/src/cli/feedback/feedback-payload.d.ts.map +1 -1
  94. package/dist/src/cli/feedback/feedback-payload.js.map +1 -1
  95. package/dist/src/cli/feedback/feedback-relay.d.ts +2 -2
  96. package/dist/src/cli/feedback/feedback-relay.d.ts.map +1 -1
  97. package/dist/src/cli/feedback/feedback-relay.js.map +1 -1
  98. package/dist/src/cli/feedback/invite.d.ts +17 -0
  99. package/dist/src/cli/feedback/invite.d.ts.map +1 -0
  100. package/dist/src/cli/feedback/invite.js +67 -0
  101. package/dist/src/cli/feedback/invite.js.map +1 -0
  102. package/dist/src/cli/feedback/relay-secret-store.d.ts +32 -0
  103. package/dist/src/cli/feedback/relay-secret-store.d.ts.map +1 -0
  104. package/dist/src/cli/feedback/relay-secret-store.js +137 -0
  105. package/dist/src/cli/feedback/relay-secret-store.js.map +1 -0
  106. package/dist/src/cli/http-client.d.ts +93 -1
  107. package/dist/src/cli/http-client.d.ts.map +1 -1
  108. package/dist/src/cli/http-client.js +254 -6
  109. package/dist/src/cli/http-client.js.map +1 -1
  110. package/dist/src/cli/index.d.ts.map +1 -1
  111. package/dist/src/cli/index.js +29 -6
  112. package/dist/src/cli/index.js.map +1 -1
  113. package/dist/src/cli/postinstall-menubar.d.ts +22 -0
  114. package/dist/src/cli/postinstall-menubar.d.ts.map +1 -0
  115. package/dist/src/cli/postinstall-menubar.js +53 -0
  116. package/dist/src/cli/postinstall-menubar.js.map +1 -0
  117. package/dist/src/cli/status/friend-header.d.ts +16 -1
  118. package/dist/src/cli/status/friend-header.d.ts.map +1 -1
  119. package/dist/src/cli/status/friend-header.js +354 -26
  120. package/dist/src/cli/status/friend-header.js.map +1 -1
  121. package/dist/src/cli/status/local-signals.d.ts +18 -0
  122. package/dist/src/cli/status/local-signals.d.ts.map +1 -1
  123. package/dist/src/cli/status/local-signals.js +29 -0
  124. package/dist/src/cli/status/local-signals.js.map +1 -1
  125. package/dist/src/cli/ui.d.ts +47 -0
  126. package/dist/src/cli/ui.d.ts.map +1 -0
  127. package/dist/src/cli/ui.js +166 -0
  128. package/dist/src/cli/ui.js.map +1 -0
  129. package/dist/src/config/schema.d.ts +79 -0
  130. package/dist/src/config/schema.d.ts.map +1 -1
  131. package/dist/src/config/schema.js +44 -0
  132. package/dist/src/config/schema.js.map +1 -1
  133. package/dist/src/diagnostics/codex-preflight.d.ts +33 -0
  134. package/dist/src/diagnostics/codex-preflight.d.ts.map +1 -0
  135. package/dist/src/diagnostics/codex-preflight.js +75 -0
  136. package/dist/src/diagnostics/codex-preflight.js.map +1 -0
  137. package/dist/src/diagnostics/doctor.d.ts +114 -0
  138. package/dist/src/diagnostics/doctor.d.ts.map +1 -0
  139. package/dist/src/diagnostics/doctor.js +352 -0
  140. package/dist/src/diagnostics/doctor.js.map +1 -0
  141. package/dist/src/diagnostics/notify.d.ts +90 -0
  142. package/dist/src/diagnostics/notify.d.ts.map +1 -0
  143. package/dist/src/diagnostics/notify.js +177 -0
  144. package/dist/src/diagnostics/notify.js.map +1 -0
  145. package/dist/src/diagnostics/repair-prompt.d.ts +49 -0
  146. package/dist/src/diagnostics/repair-prompt.d.ts.map +1 -0
  147. package/dist/src/diagnostics/repair-prompt.js +223 -0
  148. package/dist/src/diagnostics/repair-prompt.js.map +1 -0
  149. package/dist/src/ingestion/inbox-core/conversation-fingerprint.d.ts +2 -0
  150. package/dist/src/ingestion/inbox-core/conversation-fingerprint.d.ts.map +1 -0
  151. package/dist/src/ingestion/inbox-core/conversation-fingerprint.js +27 -0
  152. package/dist/src/ingestion/inbox-core/conversation-fingerprint.js.map +1 -0
  153. package/dist/src/ingestion/inbox-core/conversation-key.d.ts +2 -0
  154. package/dist/src/ingestion/inbox-core/conversation-key.d.ts.map +1 -0
  155. package/dist/src/ingestion/inbox-core/conversation-key.js +31 -0
  156. package/dist/src/ingestion/inbox-core/conversation-key.js.map +1 -0
  157. package/dist/src/ingestion/inbox-core/extensions.d.ts +3 -0
  158. package/dist/src/ingestion/inbox-core/extensions.d.ts.map +1 -0
  159. package/dist/src/ingestion/inbox-core/extensions.js +16 -0
  160. package/dist/src/ingestion/inbox-core/extensions.js.map +1 -0
  161. package/dist/src/ingestion/inbox-core/idempotency.d.ts +2 -0
  162. package/dist/src/ingestion/inbox-core/idempotency.d.ts.map +1 -0
  163. package/dist/src/ingestion/inbox-core/idempotency.js +22 -0
  164. package/dist/src/ingestion/inbox-core/idempotency.js.map +1 -0
  165. package/dist/src/ingestion/inbox-core/index.d.ts +20 -0
  166. package/dist/src/ingestion/inbox-core/index.d.ts.map +1 -0
  167. package/dist/src/ingestion/inbox-core/index.js +20 -0
  168. package/dist/src/ingestion/inbox-core/index.js.map +1 -0
  169. package/dist/src/ingestion/inbox-core/source-detection.d.ts +2 -0
  170. package/dist/src/ingestion/inbox-core/source-detection.d.ts.map +1 -0
  171. package/dist/src/ingestion/inbox-core/source-detection.js +23 -0
  172. package/dist/src/ingestion/inbox-core/source-detection.js.map +1 -0
  173. package/dist/src/ingestion/inbox-core/source-sniffer.d.ts +11 -0
  174. package/dist/src/ingestion/inbox-core/source-sniffer.d.ts.map +1 -0
  175. package/dist/src/ingestion/inbox-core/source-sniffer.js +69 -0
  176. package/dist/src/ingestion/inbox-core/source-sniffer.js.map +1 -0
  177. package/dist/src/ingestion/inbox-core/zip-sniffer.d.ts +70 -0
  178. package/dist/src/ingestion/inbox-core/zip-sniffer.d.ts.map +1 -0
  179. package/dist/src/ingestion/inbox-core/zip-sniffer.js +161 -0
  180. package/dist/src/ingestion/inbox-core/zip-sniffer.js.map +1 -0
  181. package/dist/src/ingestion/inbox-watcher.d.ts.map +1 -1
  182. package/dist/src/ingestion/inbox-watcher.js +34 -50
  183. package/dist/src/ingestion/inbox-watcher.js.map +1 -1
  184. package/dist/src/ingestion/indexer.d.ts +7 -0
  185. package/dist/src/ingestion/indexer.d.ts.map +1 -1
  186. package/dist/src/ingestion/indexer.js +36 -2
  187. package/dist/src/ingestion/indexer.js.map +1 -1
  188. package/dist/src/ingestion/metadata-extraction.d.ts +8 -5
  189. package/dist/src/ingestion/metadata-extraction.d.ts.map +1 -1
  190. package/dist/src/ingestion/metadata-extraction.js +24 -5
  191. package/dist/src/ingestion/metadata-extraction.js.map +1 -1
  192. package/dist/src/ingestion/skip-quarantine.d.ts +10 -0
  193. package/dist/src/ingestion/skip-quarantine.d.ts.map +1 -0
  194. package/dist/src/ingestion/skip-quarantine.js +35 -0
  195. package/dist/src/ingestion/skip-quarantine.js.map +1 -0
  196. package/dist/src/jobs/handlers/compact.d.ts.map +1 -1
  197. package/dist/src/jobs/handlers/compact.js +30 -4
  198. package/dist/src/jobs/handlers/compact.js.map +1 -1
  199. package/dist/src/jobs/handlers/dedupe-conversations.d.ts +134 -0
  200. package/dist/src/jobs/handlers/dedupe-conversations.d.ts.map +1 -0
  201. package/dist/src/jobs/handlers/dedupe-conversations.js +371 -0
  202. package/dist/src/jobs/handlers/dedupe-conversations.js.map +1 -0
  203. package/dist/src/jobs/handlers/ingest.d.ts.map +1 -1
  204. package/dist/src/jobs/handlers/ingest.js +295 -41
  205. package/dist/src/jobs/handlers/ingest.js.map +1 -1
  206. package/dist/src/jobs/handlers/reconcile.d.ts +28 -0
  207. package/dist/src/jobs/handlers/reconcile.d.ts.map +1 -1
  208. package/dist/src/jobs/handlers/reconcile.js +145 -19
  209. package/dist/src/jobs/handlers/reconcile.js.map +1 -1
  210. package/dist/src/jobs/handlers/reindex.d.ts.map +1 -1
  211. package/dist/src/jobs/handlers/reindex.js +13 -2
  212. package/dist/src/jobs/handlers/reindex.js.map +1 -1
  213. package/dist/src/jobs/handlers/save.d.ts.map +1 -1
  214. package/dist/src/jobs/handlers/save.js +57 -3
  215. package/dist/src/jobs/handlers/save.js.map +1 -1
  216. package/dist/src/jobs/queue.d.ts +51 -1
  217. package/dist/src/jobs/queue.d.ts.map +1 -1
  218. package/dist/src/jobs/queue.js +466 -26
  219. package/dist/src/jobs/queue.js.map +1 -1
  220. package/dist/src/jobs/worker-entry.d.ts.map +1 -1
  221. package/dist/src/jobs/worker-entry.js +35 -7
  222. package/dist/src/jobs/worker-entry.js.map +1 -1
  223. package/dist/src/jobs/worker-process.d.ts +11 -0
  224. package/dist/src/jobs/worker-process.d.ts.map +1 -1
  225. package/dist/src/jobs/worker-process.js +37 -4
  226. package/dist/src/jobs/worker-process.js.map +1 -1
  227. package/dist/src/main.js +199 -46
  228. package/dist/src/main.js.map +1 -1
  229. package/dist/src/mcp/errors.d.ts.map +1 -1
  230. package/dist/src/mcp/errors.js +20 -1
  231. package/dist/src/mcp/errors.js.map +1 -1
  232. package/dist/src/mcp/server.d.ts.map +1 -1
  233. package/dist/src/mcp/server.js +43 -3
  234. package/dist/src/mcp/server.js.map +1 -1
  235. package/dist/src/mcp/tools/context-pack.d.ts.map +1 -1
  236. package/dist/src/mcp/tools/context-pack.js +164 -23
  237. package/dist/src/mcp/tools/context-pack.js.map +1 -1
  238. package/dist/src/mcp/tools/search.d.ts +6 -2
  239. package/dist/src/mcp/tools/search.d.ts.map +1 -1
  240. package/dist/src/mcp/tools/search.js +35 -4
  241. package/dist/src/mcp/tools/search.js.map +1 -1
  242. package/dist/src/observability/embedding-events.d.ts +52 -0
  243. package/dist/src/observability/embedding-events.d.ts.map +1 -0
  244. package/dist/src/observability/embedding-events.js +149 -0
  245. package/dist/src/observability/embedding-events.js.map +1 -0
  246. package/dist/src/observability/index-events.d.ts +70 -0
  247. package/dist/src/observability/index-events.d.ts.map +1 -0
  248. package/dist/src/observability/index-events.js +148 -0
  249. package/dist/src/observability/index-events.js.map +1 -0
  250. package/dist/src/observability/onboarding-metric.d.ts +131 -0
  251. package/dist/src/observability/onboarding-metric.d.ts.map +1 -0
  252. package/dist/src/observability/onboarding-metric.js +351 -0
  253. package/dist/src/observability/onboarding-metric.js.map +1 -0
  254. package/dist/src/observability/tool-usage-stats.d.ts +77 -4
  255. package/dist/src/observability/tool-usage-stats.d.ts.map +1 -1
  256. package/dist/src/observability/tool-usage-stats.js +112 -32
  257. package/dist/src/observability/tool-usage-stats.js.map +1 -1
  258. package/dist/src/observability/tool-usage.d.ts +100 -7
  259. package/dist/src/observability/tool-usage.d.ts.map +1 -1
  260. package/dist/src/observability/tool-usage.js +196 -33
  261. package/dist/src/observability/tool-usage.js.map +1 -1
  262. package/dist/src/observability/version-check.d.ts +71 -0
  263. package/dist/src/observability/version-check.d.ts.map +1 -0
  264. package/dist/src/observability/version-check.js +198 -0
  265. package/dist/src/observability/version-check.js.map +1 -0
  266. package/dist/src/providers/basic-metadata-extraction.d.ts +60 -0
  267. package/dist/src/providers/basic-metadata-extraction.d.ts.map +1 -0
  268. package/dist/src/providers/basic-metadata-extraction.js +114 -0
  269. package/dist/src/providers/basic-metadata-extraction.js.map +1 -0
  270. package/dist/src/providers/codex-cli-metadata-extraction.d.ts +1 -0
  271. package/dist/src/providers/codex-cli-metadata-extraction.d.ts.map +1 -1
  272. package/dist/src/providers/codex-cli-metadata-extraction.js +6 -2
  273. package/dist/src/providers/codex-cli-metadata-extraction.js.map +1 -1
  274. package/dist/src/providers/codex-cli-model.d.ts +61 -0
  275. package/dist/src/providers/codex-cli-model.d.ts.map +1 -0
  276. package/dist/src/providers/codex-cli-model.js +194 -0
  277. package/dist/src/providers/codex-cli-model.js.map +1 -0
  278. package/dist/src/providers/codex-cli-runner.d.ts +39 -0
  279. package/dist/src/providers/codex-cli-runner.d.ts.map +1 -1
  280. package/dist/src/providers/codex-cli-runner.js +234 -48
  281. package/dist/src/providers/codex-cli-runner.js.map +1 -1
  282. package/dist/src/providers/conversation-generation.d.ts.map +1 -1
  283. package/dist/src/providers/conversation-generation.js +43 -6
  284. package/dist/src/providers/conversation-generation.js.map +1 -1
  285. package/dist/src/providers/ollama-embed.d.ts +2 -1
  286. package/dist/src/providers/ollama-embed.d.ts.map +1 -1
  287. package/dist/src/providers/ollama-embed.js +1 -0
  288. package/dist/src/providers/ollama-embed.js.map +1 -1
  289. package/dist/src/providers/openai-metadata-extraction.d.ts +3 -3
  290. package/dist/src/providers/openai-metadata-extraction.d.ts.map +1 -1
  291. package/dist/src/providers/openai-metadata-extraction.js +18 -3
  292. package/dist/src/providers/openai-metadata-extraction.js.map +1 -1
  293. package/dist/src/providers/placeholder-embed.d.ts +56 -0
  294. package/dist/src/providers/placeholder-embed.d.ts.map +1 -0
  295. package/dist/src/providers/placeholder-embed.js +64 -0
  296. package/dist/src/providers/placeholder-embed.js.map +1 -0
  297. package/dist/src/providers/stub.d.ts +2 -0
  298. package/dist/src/providers/stub.d.ts.map +1 -1
  299. package/dist/src/providers/stub.js +2 -0
  300. package/dist/src/providers/stub.js.map +1 -1
  301. package/dist/src/providers/types.d.ts +11 -0
  302. package/dist/src/providers/types.d.ts.map +1 -1
  303. package/dist/src/providers/voyage.d.ts +2 -1
  304. package/dist/src/providers/voyage.d.ts.map +1 -1
  305. package/dist/src/providers/voyage.js +1 -0
  306. package/dist/src/providers/voyage.js.map +1 -1
  307. package/dist/src/retrieval/compact.d.ts +116 -2
  308. package/dist/src/retrieval/compact.d.ts.map +1 -1
  309. package/dist/src/retrieval/compact.js +158 -5
  310. package/dist/src/retrieval/compact.js.map +1 -1
  311. package/dist/src/retrieval/context-pack.d.ts +114 -0
  312. package/dist/src/retrieval/context-pack.d.ts.map +1 -1
  313. package/dist/src/retrieval/context-pack.js +292 -8
  314. package/dist/src/retrieval/context-pack.js.map +1 -1
  315. package/dist/src/retrieval/current-truth.d.ts +360 -0
  316. package/dist/src/retrieval/current-truth.d.ts.map +1 -0
  317. package/dist/src/retrieval/current-truth.js +766 -0
  318. package/dist/src/retrieval/current-truth.js.map +1 -0
  319. package/dist/src/retrieval/git-state.d.ts +53 -0
  320. package/dist/src/retrieval/git-state.d.ts.map +1 -0
  321. package/dist/src/retrieval/git-state.js +174 -0
  322. package/dist/src/retrieval/git-state.js.map +1 -0
  323. package/dist/src/retrieval/lexical.d.ts.map +1 -1
  324. package/dist/src/retrieval/lexical.js +19 -3
  325. package/dist/src/retrieval/lexical.js.map +1 -1
  326. package/dist/src/retrieval/locator-boost.d.ts +37 -0
  327. package/dist/src/retrieval/locator-boost.d.ts.map +1 -0
  328. package/dist/src/retrieval/locator-boost.js +129 -0
  329. package/dist/src/retrieval/locator-boost.js.map +1 -0
  330. package/dist/src/retrieval/report-demotion.d.ts +46 -0
  331. package/dist/src/retrieval/report-demotion.d.ts.map +1 -0
  332. package/dist/src/retrieval/report-demotion.js +169 -0
  333. package/dist/src/retrieval/report-demotion.js.map +1 -0
  334. package/dist/src/retrieval/vector.d.ts.map +1 -1
  335. package/dist/src/retrieval/vector.js +11 -2
  336. package/dist/src/retrieval/vector.js.map +1 -1
  337. package/dist/src/server/app.d.ts.map +1 -1
  338. package/dist/src/server/app.js +92 -11
  339. package/dist/src/server/app.js.map +1 -1
  340. package/dist/src/server/routes/compact.d.ts.map +1 -1
  341. package/dist/src/server/routes/compact.js +4 -1
  342. package/dist/src/server/routes/compact.js.map +1 -1
  343. package/dist/src/server/routes/context.d.ts +1 -1
  344. package/dist/src/server/routes/context.d.ts.map +1 -1
  345. package/dist/src/server/routes/context.js +2 -1
  346. package/dist/src/server/routes/context.js.map +1 -1
  347. package/dist/src/server/routes/conversations-search.d.ts.map +1 -1
  348. package/dist/src/server/routes/conversations-search.js +28 -3
  349. package/dist/src/server/routes/conversations-search.js.map +1 -1
  350. package/dist/src/server/routes/enqueue.d.ts +11 -0
  351. package/dist/src/server/routes/enqueue.d.ts.map +1 -0
  352. package/dist/src/server/routes/enqueue.js +17 -0
  353. package/dist/src/server/routes/enqueue.js.map +1 -0
  354. package/dist/src/server/routes/friend-status.d.ts +339 -3
  355. package/dist/src/server/routes/friend-status.d.ts.map +1 -1
  356. package/dist/src/server/routes/friend-status.js +447 -13
  357. package/dist/src/server/routes/friend-status.js.map +1 -1
  358. package/dist/src/server/routes/ingest.d.ts.map +1 -1
  359. package/dist/src/server/routes/ingest.js +5 -2
  360. package/dist/src/server/routes/ingest.js.map +1 -1
  361. package/dist/src/server/routes/mcp-usage.d.ts +5 -4
  362. package/dist/src/server/routes/mcp-usage.d.ts.map +1 -1
  363. package/dist/src/server/routes/mcp-usage.js.map +1 -1
  364. package/dist/src/server/routes/reconcile.d.ts.map +1 -1
  365. package/dist/src/server/routes/reconcile.js +20 -1
  366. package/dist/src/server/routes/reconcile.js.map +1 -1
  367. package/dist/src/server/routes/reindex.d.ts.map +1 -1
  368. package/dist/src/server/routes/reindex.js +4 -1
  369. package/dist/src/server/routes/reindex.js.map +1 -1
  370. package/dist/src/server/routes/save.d.ts.map +1 -1
  371. package/dist/src/server/routes/save.js +4 -1
  372. package/dist/src/server/routes/save.js.map +1 -1
  373. package/dist/src/server/routes/search.d.ts +1 -1
  374. package/dist/src/server/routes/search.d.ts.map +1 -1
  375. package/dist/src/server/routes/search.js +253 -29
  376. package/dist/src/server/routes/search.js.map +1 -1
  377. package/dist/src/server/routes/triage.d.ts.map +1 -1
  378. package/dist/src/server/routes/triage.js +4 -1
  379. package/dist/src/server/routes/triage.js.map +1 -1
  380. package/dist/src/storage/rebuild.d.ts +35 -1
  381. package/dist/src/storage/rebuild.d.ts.map +1 -1
  382. package/dist/src/storage/rebuild.js +288 -64
  383. package/dist/src/storage/rebuild.js.map +1 -1
  384. package/dist/src/storage/tables.d.ts +29 -0
  385. package/dist/src/storage/tables.d.ts.map +1 -1
  386. package/dist/src/storage/tables.js +32 -1
  387. package/dist/src/storage/tables.js.map +1 -1
  388. package/operator/swiftbar/render-menu.py +524 -0
  389. package/operator/swiftbar/rift.10s.sh +176 -0
  390. package/package.json +9 -3
@@ -1,14 +1,20 @@
1
1
  /**
2
2
  * Feedback opt-in sidecar.
3
3
  *
4
- * Lives at `<data_dir>/feedback-config.json`, written by `rift onboard`.
5
- * Holds the relay URL + a per-installation pseudonymous UUID. Optional
6
- * `hmac_secret` lets the relay verify message integrity (used by the
7
- * Cloudflare Worker variant; Slack incoming webhooks don't validate it).
4
+ * Lives at `<data_dir>/feedback-config.json`, written by `rift onboard` /
5
+ * `rift feedback setup`. Holds the relay URL + a per-installation pseudonymous
6
+ * UUID + optional contact email all non-secret. The relay HMAC secret is
7
+ * NOT stored here: it lives in the macOS Keychain (see `relay-secret-store.ts`)
8
+ * and is resolved at POST time via `resolveRelaySecret`.
9
+ *
10
+ * `hmac_secret` remains in the schema ONLY so legacy plaintext sidecars still
11
+ * parse and can be migrated into the Keychain on next use; new writes never
12
+ * include it.
8
13
  *
9
14
  * Loader is fail-soft: a missing or unreadable sidecar yields a "relay
10
15
  * off" config so `rift feedback` still writes a local row.
11
16
  */
17
+ import crypto from "node:crypto";
12
18
  import fs from "node:fs";
13
19
  import path from "node:path";
14
20
  import { z } from "zod";
@@ -17,7 +23,19 @@ export const FeedbackConfigSchema = z
17
23
  enabled: z.boolean(),
18
24
  url: z.string().url().optional(),
19
25
  installation_id: z.string().min(1).optional(),
26
+ // DEPRECATED — legacy plaintext secret. Read only for one-time migration
27
+ // into the Keychain (see `resolveRelaySecret`); never written by new code.
20
28
  hmac_secret: z.string().min(1).optional(),
29
+ // True only for an intentionally-unsigned dev/local relay
30
+ // (`--allow-unsigned-feedback-relay`). Lets `maybeRelay` POST without a
31
+ // secret ONLY when this was an explicit choice — never as a silent
32
+ // fallback when a secret should exist but couldn't be resolved.
33
+ unsigned: z.boolean().optional(),
34
+ // Opt-in beta contact email, captured at onboarding. Stored locally;
35
+ // reaches the operator only via the relay (or the local
36
+ // beta-signups.jsonl) and only because the user chose to share it.
37
+ // Absent unless the user opted in.
38
+ email: z.string().email().optional(),
21
39
  })
22
40
  .strict();
23
41
  export function feedbackConfigPath(dataDir) {
@@ -40,4 +58,112 @@ export function loadFeedbackConfig(dataDir) {
40
58
  return { enabled: false };
41
59
  }
42
60
  }
61
+ /**
62
+ * Persist the feedback config, ALWAYS stripping the deprecated `hmac_secret`
63
+ * — the secret belongs in the Keychain, never the sidecar. Writes mode 0600.
64
+ */
65
+ export function writeFeedbackConfig(dataDir, cfg) {
66
+ const { hmac_secret: _legacy, ...safe } = cfg;
67
+ void _legacy;
68
+ fs.mkdirSync(dataDir, { recursive: true });
69
+ const file = feedbackConfigPath(dataDir);
70
+ fs.writeFileSync(file, JSON.stringify(safe, null, 2) + "\n", {
71
+ encoding: "utf8",
72
+ mode: 0o600,
73
+ });
74
+ try {
75
+ fs.chmodSync(file, 0o600);
76
+ }
77
+ catch {
78
+ // best-effort permission fix
79
+ }
80
+ }
81
+ /**
82
+ * Resolve the relay HMAC secret, migrating a legacy plaintext sidecar secret
83
+ * into the Keychain on first use. Order:
84
+ * 1. Keychain (the canonical home) — return it if present.
85
+ * 2. Legacy `hmac_secret` in the sidecar — write it to the Keychain, strip
86
+ * it from the file, then return it.
87
+ * 3. None / not securely resolvable — return null.
88
+ *
89
+ * NEVER returns a secret that isn't (or didn't just become) securely stored:
90
+ * - If the Keychain READ fails (e.g. locked), returns null — the caller must
91
+ * not downgrade to an unsigned production POST.
92
+ * - A legacy plaintext secret is returned ONLY after it is successfully
93
+ * written to the Keychain. If that write fails, returns null (no silent
94
+ * plaintext fallback); migration retries next time once the Keychain is
95
+ * reachable.
96
+ *
97
+ * NEVER throws — it runs in the best-effort `rift feedback` relay path. The
98
+ * plaintext strip is best-effort and RETRYABLE: a strip that fails (e.g. a
99
+ * read-only sidecar) leaves the plaintext for a later call to remove, and a
100
+ * later call strips a lingering plaintext copy even when the Keychain already
101
+ * holds the secret (the partial-migration case).
102
+ */
103
+ export async function resolveRelaySecret(deps) {
104
+ let fromStore;
105
+ try {
106
+ fromStore = await deps.store.read();
107
+ }
108
+ catch {
109
+ // Keychain unreadable (e.g. locked) — cannot resolve a secure secret.
110
+ return null;
111
+ }
112
+ if (fromStore) {
113
+ // Keychain is canonical. Strip any plaintext copy a prior partial
114
+ // migration left behind (best-effort; retried each call).
115
+ stripLegacyPlaintextSecret(deps.dataDir);
116
+ return fromStore;
117
+ }
118
+ const legacy = loadFeedbackConfig(deps.dataDir).hmac_secret;
119
+ if (!legacy)
120
+ return null;
121
+ try {
122
+ await deps.store.write(legacy);
123
+ }
124
+ catch {
125
+ // Could not secure the legacy secret — do NOT fall back to the plaintext.
126
+ return null;
127
+ }
128
+ // Now safely in the Keychain → strip the plaintext copy (best-effort) and
129
+ // use it. A strip failure must NOT throw out of the best-effort feedback
130
+ // path; the next call retries via the Keychain-hit branch above.
131
+ stripLegacyPlaintextSecret(deps.dataDir);
132
+ return legacy;
133
+ }
134
+ /**
135
+ * Best-effort removal of a legacy plaintext `hmac_secret` from the sidecar.
136
+ * Rewrites only when the secret is actually present (no needless writes) and
137
+ * NEVER throws — a failed strip (e.g. read-only file) leaves the plaintext for
138
+ * the next call to retry and must not break the best-effort feedback path.
139
+ */
140
+ function stripLegacyPlaintextSecret(dataDir) {
141
+ try {
142
+ const cfg = loadFeedbackConfig(dataDir);
143
+ if (cfg.hmac_secret === undefined)
144
+ return; // nothing to strip
145
+ writeFeedbackConfig(dataDir, cfg); // writeFeedbackConfig drops hmac_secret
146
+ }
147
+ catch {
148
+ // best-effort — retried on a later call once the sidecar is writable
149
+ }
150
+ }
151
+ /**
152
+ * Turn the relay on for this install (from an accepted invite or operator
153
+ * flags): set `enabled` + `url`, mint an `installation_id` when absent, and
154
+ * preserve any existing email. `writeFeedbackConfig` guarantees no secret
155
+ * lands in the sidecar — the caller writes the secret to the Keychain. Returns
156
+ * the persisted config.
157
+ */
158
+ export function applyRelayUrl(dataDir, url) {
159
+ const existing = loadFeedbackConfig(dataDir);
160
+ const cfg = {
161
+ enabled: true,
162
+ url,
163
+ installation_id: existing.installation_id ?? crypto.randomUUID(),
164
+ ...(existing.email ? { email: existing.email } : {}),
165
+ };
166
+ writeFeedbackConfig(dataDir, cfg);
167
+ return cfg;
168
+ }
43
169
  //# sourceMappingURL=feedback-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-config.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KAClC,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAChC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC7C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,OAAO,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"feedback-config.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-config.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,11 @@
1
1
  export declare function sanitizeText(input: string): string;
2
2
  export declare function formatHistoryLine(rawLine: string): string;
3
+ /**
4
+ * Render a beta-signup row. Signups carry the user's own email (no note),
5
+ * so the audit surface shows it back to them — that is the point of the
6
+ * audit. ts/email still pass through `sanitizeText` for control-char and
7
+ * path/secret safety.
8
+ */
9
+ export declare function formatSignupLine(rawLine: string): string;
3
10
  export declare function renderHistory(dataDir: string, emit: (line: string) => void): void;
4
11
  //# sourceMappingURL=feedback-history.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-history.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-history.ts"],"names":[],"mappings":"AA4EA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBzD;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC3B,IAAI,CAaN"}
1
+ {"version":3,"file":"feedback-history.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-history.ts"],"names":[],"mappings":"AA4EA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBzD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAcxD;AAUD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC3B,IAAI,CAaN"}
@@ -97,19 +97,49 @@ export function formatHistoryLine(rawLine) {
97
97
  const status = row.status_snapshot ? " (with status)" : "";
98
98
  return `${ts} · ${kind} · ${note}${status}`;
99
99
  }
100
- export function renderHistory(dataDir, emit) {
101
- const file = path.join(dataDir, "observability", "feedback.jsonl");
102
- if (!fs.existsSync(file)) {
103
- emit("No feedback rows yet.");
104
- return;
100
+ /**
101
+ * Render a beta-signup row. Signups carry the user's own email (no note),
102
+ * so the audit surface shows it back to them — that is the point of the
103
+ * audit. ts/email still pass through `sanitizeText` for control-char and
104
+ * path/secret safety.
105
+ */
106
+ export function formatSignupLine(rawLine) {
107
+ let parsed;
108
+ try {
109
+ parsed = JSON.parse(rawLine);
105
110
  }
106
- const raw = fs.readFileSync(file, "utf8");
107
- const lines = raw.split("\n").filter((l) => l.length > 0);
108
- if (lines.length === 0) {
111
+ catch {
112
+ return "[malformed row skipped]";
113
+ }
114
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
115
+ return "[malformed row — skipped]";
116
+ }
117
+ const row = parsed;
118
+ const ts = typeof row.ts === "string" ? sanitizeText(row.ts) : "?";
119
+ const email = typeof row.email === "string" ? sanitizeText(row.email) : "?";
120
+ return `${ts} · beta signup · ${email}`;
121
+ }
122
+ function readNonEmptyLines(file) {
123
+ if (!fs.existsSync(file))
124
+ return [];
125
+ return fs
126
+ .readFileSync(file, "utf8")
127
+ .split("\n")
128
+ .filter((l) => l.length > 0);
129
+ }
130
+ export function renderHistory(dataDir, emit) {
131
+ const obs = path.join(dataDir, "observability");
132
+ const feedbackLines = readNonEmptyLines(path.join(obs, "feedback.jsonl"));
133
+ // beta-signups.jsonl is part of "every byte that went to Clem", so the
134
+ // audit surface must include it — not just feedback.jsonl.
135
+ const signupLines = readNonEmptyLines(path.join(obs, "beta-signups.jsonl"));
136
+ if (feedbackLines.length === 0 && signupLines.length === 0) {
109
137
  emit("No feedback rows yet.");
110
138
  return;
111
139
  }
112
- for (const line of lines)
140
+ for (const line of feedbackLines)
113
141
  emit(formatHistoryLine(line));
142
+ for (const line of signupLines)
143
+ emit(formatSignupLine(line));
114
144
  }
115
145
  //# sourceMappingURL=feedback-history.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-history.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-history.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feedback-history.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-history.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,12 @@
6
6
  * - `ts` : ISO timestamp the friend hit enter.
7
7
  * - `installation_id` : per-install random UUID from `feedback-config.json`,
8
8
  * present only if relay opt-in is on. **Not** the
9
- * friend's username, hostname, or email.
9
+ * friend's username or hostname.
10
+ * - `email` : OPT-IN beta contact email, present only if the user
11
+ * chose to share it at onboarding (it lives in
12
+ * `feedback-config.json`). Lets the operator attribute
13
+ * feedback to a person and send news/pricing/launch
14
+ * updates. Absent for anyone who didn't opt in.
10
15
  * - `kind` : enum free-form intent tag (worked|broke|surprised|idea).
11
16
  * - `note` : free text from the friend. **Untrusted** — the
12
17
  * friend can paste anything they like into this. We
@@ -44,10 +49,26 @@ export interface FeedbackPayload {
44
49
  installation_id?: string;
45
50
  kind: FeedbackKind;
46
51
  note: string;
52
+ email?: string;
47
53
  version: string;
48
54
  commit: string;
49
55
  node: string;
50
56
  status_snapshot?: FeedbackStatusSnapshot;
51
57
  }
58
+ /**
59
+ * One-time beta signup, emitted at onboarding when a user opts in to stay
60
+ * connected. Distinct from feedback: it carries the email but no note/kind.
61
+ * Written to `data/observability/beta-signups.jsonl` (canonical) and POSTed
62
+ * to the relay when an endpoint URL is configured.
63
+ */
64
+ export interface SignupPayload {
65
+ ts: string;
66
+ event: "beta_signup";
67
+ email: string;
68
+ installation_id: string;
69
+ version: string;
70
+ commit: string;
71
+ node: string;
72
+ }
52
73
  export declare function isFeedbackKind(s: string): s is FeedbackKind;
53
74
  //# sourceMappingURL=feedback-payload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-payload.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;AAErE,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAKxC,CAAC;AAEX,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE;QACN,MAAM,EAAE,IAAI,GAAG,aAAa,CAAC;QAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;KACpC,CAAC;IACF,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE;QACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;QAC5B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;QAClC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;KACnC,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,sBAAsB,CAAC;CAC1C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,YAAY,CAE3D"}
1
+ {"version":3,"file":"feedback-payload.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;AAErE,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAKxC,CAAC;AAEX,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE;QACN,MAAM,EAAE,IAAI,GAAG,aAAa,CAAC;QAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAC;KACpC,CAAC;IACF,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE;QACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;QAC5B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;QAClC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;KACnC,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,sBAAsB,CAAC;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,IAAI,YAAY,CAE3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-payload.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-payload.ts"],"names":[],"mappings":"AAyBA,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,QAAQ;IACR,OAAO;IACP,WAAW;IACX,MAAM;CACE,CAAC;AA+BX,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,OAAQ,cAAoC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"feedback-payload.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-payload.ts"],"names":[],"mappings":"AA8BA,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,QAAQ;IACR,OAAO;IACP,WAAW;IACX,MAAM;CACE,CAAC;AAgDX,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,OAAQ,cAAoC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { FeedbackPayload } from "./feedback-payload.js";
1
+ import type { FeedbackPayload, SignupPayload } from "./feedback-payload.js";
2
2
  export interface RelayResult {
3
3
  attempted: boolean;
4
4
  ok: boolean;
@@ -11,5 +11,5 @@ export interface RelayOpts {
11
11
  fetchFn?: typeof fetch;
12
12
  timeoutMs?: number;
13
13
  }
14
- export declare function postFeedback(payload: FeedbackPayload, opts: RelayOpts): Promise<RelayResult>;
14
+ export declare function postFeedback(payload: FeedbackPayload | SignupPayload, opts: RelayOpts): Promise<RelayResult>;
15
15
  //# sourceMappingURL=feedback-relay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-relay.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-relay.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,WAAW,CAAC,CA+BtB"}
1
+ {"version":3,"file":"feedback-relay.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-relay.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE5E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,eAAe,GAAG,aAAa,EACxC,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,WAAW,CAAC,CA+BtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-relay.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiBzC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAwB,EACxB,IAAe;IAEf,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IACF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7E,OAAO,CAAC,kBAAkB,CAAC,GAAG,UAAU,GAAG,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;IAC5E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;YAClC,MAAM,EAAE,MAAM;YACd,IAAI;YACJ,OAAO;YACP,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,EAAE;YACX,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;YACnD,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,SAAS,EAAE,IAAI;YACf,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"feedback-relay.js","sourceRoot":"","sources":["../../../../src/cli/feedback/feedback-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiBzC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAwC,EACxC,IAAe;IAEf,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IACF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7E,OAAO,CAAC,kBAAkB,CAAC,GAAG,UAAU,GAAG,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;IAC5E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;YAClC,MAAM,EAAE,MAAM;YACd,IAAI;YACJ,OAAO;YACP,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,EAAE;YACX,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;YACnD,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,SAAS,EAAE,IAAI;YACf,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface RiftInvite {
2
+ url: string;
3
+ secret: string;
4
+ label?: string;
5
+ }
6
+ /**
7
+ * Decode an invite code into its parts. Throws a `validation` CliError on any
8
+ * malformation (bad prefix, bad base64, bad JSON, missing/invalid fields) with
9
+ * one friend-facing message — never leaks the decode internals.
10
+ */
11
+ export declare function parseInvite(raw: string): RiftInvite;
12
+ /**
13
+ * Build an invite code from its parts. The operator-side counterpart to
14
+ * `parseInvite` (used to mint codes and to round-trip in tests).
15
+ */
16
+ export declare function formatInvite(invite: RiftInvite): string;
17
+ //# sourceMappingURL=invite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/invite.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAmBnD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAWvD"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Feedback-relay invite codes.
3
+ *
4
+ * An invite is a single opaque string the operator hands a friend. It carries
5
+ * the relay URL + the HMAC secret so the friend never sees or types a raw
6
+ * secret — they paste ONE blob and Rift does the rest (URL → config, secret →
7
+ * Keychain). Shape:
8
+ *
9
+ * rift-invite_<base64url(JSON)> where JSON = { v: 1, url, secret, label? }
10
+ *
11
+ * NOTE (deferred, tracked): the invite embeds the *shared* beta secret, so it
12
+ * is only as revocable as that secret. Acceptable for beta (it signs feedback
13
+ * to Clem, low stakes); the revocable per-install token is the future upgrade.
14
+ */
15
+ import { z } from "zod";
16
+ import { CliError } from "../http-client.js";
17
+ const INVITE_PREFIX = "rift-invite_";
18
+ const InvitePayloadSchema = z
19
+ .object({
20
+ v: z.literal(1),
21
+ url: z.string().url(),
22
+ secret: z.string().min(1),
23
+ label: z.string().min(1).optional(),
24
+ })
25
+ .strict();
26
+ const INVALID = "That invite code is not valid. Ask Clem for a fresh `rift-invite_…` code.";
27
+ /**
28
+ * Decode an invite code into its parts. Throws a `validation` CliError on any
29
+ * malformation (bad prefix, bad base64, bad JSON, missing/invalid fields) with
30
+ * one friend-facing message — never leaks the decode internals.
31
+ */
32
+ export function parseInvite(raw) {
33
+ const code = raw.trim();
34
+ if (!code.startsWith(INVITE_PREFIX)) {
35
+ throw new CliError(INVALID, "validation");
36
+ }
37
+ const encoded = code.slice(INVITE_PREFIX.length);
38
+ let json;
39
+ try {
40
+ const decoded = Buffer.from(encoded, "base64url").toString("utf8");
41
+ json = JSON.parse(decoded);
42
+ }
43
+ catch {
44
+ throw new CliError(INVALID, "validation");
45
+ }
46
+ const parsed = InvitePayloadSchema.safeParse(json);
47
+ if (!parsed.success) {
48
+ throw new CliError(INVALID, "validation");
49
+ }
50
+ const { url, secret, label } = parsed.data;
51
+ return { url, secret, ...(label ? { label } : {}) };
52
+ }
53
+ /**
54
+ * Build an invite code from its parts. The operator-side counterpart to
55
+ * `parseInvite` (used to mint codes and to round-trip in tests).
56
+ */
57
+ export function formatInvite(invite) {
58
+ const payload = {
59
+ v: 1,
60
+ url: invite.url,
61
+ secret: invite.secret,
62
+ ...(invite.label ? { label: invite.label } : {}),
63
+ };
64
+ const encoded = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
65
+ return `${INVITE_PREFIX}${encoded}`;
66
+ }
67
+ //# sourceMappingURL=invite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite.js","sourceRoot":"","sources":["../../../../src/cli/feedback/invite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,aAAa,GAAG,cAAc,CAAC;AAErC,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACpC,CAAC;KACD,MAAM,EAAE,CAAC;AAQZ,MAAM,OAAO,GACX,2EAA2E,CAAC;AAE9E;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAkB;IAC7C,MAAM,OAAO,GAAG;QACd,CAAC,EAAE,CAAU;QACb,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjD,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CACnE,WAAW,CACZ,CAAC;IACF,OAAO,GAAG,aAAa,GAAG,OAAO,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** Minimal shape of the promisified `execFile` we depend on (stdout only). */
2
+ type ExecFn = (file: string, args: string[]) => Promise<{
3
+ stdout: string;
4
+ }>;
5
+ /**
6
+ * Storage for the relay HMAC secret. Abstracted so the feedback paths can be
7
+ * tested with an in-memory implementation that never shells out to `security`.
8
+ */
9
+ export interface RelaySecretStore {
10
+ /** The stored secret, or null when none is set. */
11
+ read(): Promise<string | null>;
12
+ /** Write (or overwrite) the secret. */
13
+ write(secret: string): Promise<void>;
14
+ /** Remove the secret. No-op when already absent. */
15
+ delete(): Promise<void>;
16
+ }
17
+ /**
18
+ * Production store backed by the macOS `security` CLI. `exec` is injectable so
19
+ * tests can drive the error mapping (locked keychain, item-not-found) without
20
+ * a real Keychain. There is deliberately NO plaintext fallback — if the secret
21
+ * cannot be stored securely, relay signing is simply unavailable.
22
+ */
23
+ export declare function createMacRelaySecretStore(exec?: ExecFn): RelaySecretStore;
24
+ /** Production store backed by the real macOS `security` CLI. */
25
+ export declare const macRelaySecretStore: RelaySecretStore;
26
+ /**
27
+ * In-memory store for tests and any non-Keychain injection point. Holds the
28
+ * secret in a closure — never persisted. Production code never reaches for it.
29
+ */
30
+ export declare function createInMemoryRelaySecretStore(initial?: string | null): RelaySecretStore;
31
+ export {};
32
+ //# sourceMappingURL=relay-secret-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-secret-store.d.ts","sourceRoot":"","sources":["../../../../src/cli/feedback/relay-secret-store.ts"],"names":[],"mappings":"AAmBA,8EAA8E;AAC9E,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AA2C5E;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,IAAI,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/B,uCAAuC;IACvC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,oDAAoD;IACpD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,GAAE,MAAoB,GAAG,gBAAgB,CAmDtF;AAED,gEAAgE;AAChE,eAAO,MAAM,mBAAmB,EAAE,gBAA8C,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,gBAAgB,CAalB"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Secure storage for the feedback-relay HMAC secret.
3
+ *
4
+ * The secret proves a feedback POST came from a configured Rift install (the
5
+ * Cloudflare Worker validates the `X-Rift-Signature` HMAC). It is a real
6
+ * secret, so it must NOT sit in plaintext `feedback-config.json`. It lives in
7
+ * the macOS Keychain instead, under the same service as the daemon auth token
8
+ * (`com.getrift.daemon`) so all Rift secrets share one keychain service.
9
+ *
10
+ * The store is an injectable interface: production uses the `security` CLI;
11
+ * tests inject `createInMemoryRelaySecretStore()` (no real Keychain, no GUI
12
+ * session) or `createMacRelaySecretStore(fakeExec)` to exercise the error
13
+ * mapping without shelling out.
14
+ */
15
+ import { execFile } from "node:child_process";
16
+ import { promisify } from "node:util";
17
+ import { LockedKeychainError } from "../../auth/keychain.js";
18
+ const defaultExec = promisify(execFile);
19
+ /** Same keychain service as the daemon auth token — one service per app. */
20
+ const SERVICE = "com.getrift.daemon";
21
+ /** Single (non-versioned) generic-password account for the relay secret. */
22
+ const ACCOUNT = "RELAY_HMAC_SECRET";
23
+ /** macOS `security` exit code for errSecItemNotFound — the only swallowed one. */
24
+ const ERR_SEC_ITEM_NOT_FOUND = 44;
25
+ /** Substring the `security` CLI emits when the login keychain is locked. */
26
+ const LOCKED_KEYCHAIN_SUBSTRING = "User interaction is not allowed";
27
+ // Predicates mirror the private helpers in ../../auth/keychain.ts. Kept local
28
+ // (not exported from there) to avoid refactoring the heavily-tested auth path;
29
+ // the auth token store remains the single owner of those internals.
30
+ function isItemNotFound(err) {
31
+ if (!(err instanceof Error))
32
+ return false;
33
+ return err.code === ERR_SEC_ITEM_NOT_FOUND;
34
+ }
35
+ function isLockedKeychain(err) {
36
+ if (!(err instanceof Error))
37
+ return false;
38
+ if (err.message.includes(LOCKED_KEYCHAIN_SUBSTRING))
39
+ return true;
40
+ const stderr = err.stderr;
41
+ return typeof stderr === "string" && stderr.includes(LOCKED_KEYCHAIN_SUBSTRING);
42
+ }
43
+ /**
44
+ * Normalize a `security` failure: a locked keychain becomes the typed
45
+ * `LockedKeychainError` (so callers render the unlock hint instead of leaking
46
+ * raw `security` output); every other error propagates unchanged. Applied on
47
+ * EVERY path — read, write, and delete — so write failures during invite
48
+ * setup map the same way reads do.
49
+ */
50
+ function rethrowKeychainError(err) {
51
+ if (isLockedKeychain(err)) {
52
+ throw new LockedKeychainError(err instanceof Error ? err.message : String(err));
53
+ }
54
+ throw err;
55
+ }
56
+ /**
57
+ * Production store backed by the macOS `security` CLI. `exec` is injectable so
58
+ * tests can drive the error mapping (locked keychain, item-not-found) without
59
+ * a real Keychain. There is deliberately NO plaintext fallback — if the secret
60
+ * cannot be stored securely, relay signing is simply unavailable.
61
+ */
62
+ export function createMacRelaySecretStore(exec = defaultExec) {
63
+ return {
64
+ async read() {
65
+ try {
66
+ const { stdout } = await exec("security", [
67
+ "find-generic-password",
68
+ "-a",
69
+ ACCOUNT,
70
+ "-s",
71
+ SERVICE,
72
+ "-w",
73
+ ]);
74
+ return stdout.trim() || null;
75
+ }
76
+ catch (err) {
77
+ if (isItemNotFound(err))
78
+ return null;
79
+ rethrowKeychainError(err);
80
+ }
81
+ },
82
+ async write(secret) {
83
+ try {
84
+ await exec("security", [
85
+ "add-generic-password",
86
+ "-a",
87
+ ACCOUNT,
88
+ "-s",
89
+ SERVICE,
90
+ "-w",
91
+ secret,
92
+ "-U", // update in place if it already exists
93
+ ]);
94
+ }
95
+ catch (err) {
96
+ rethrowKeychainError(err);
97
+ }
98
+ },
99
+ async delete() {
100
+ try {
101
+ await exec("security", [
102
+ "delete-generic-password",
103
+ "-a",
104
+ ACCOUNT,
105
+ "-s",
106
+ SERVICE,
107
+ ]);
108
+ }
109
+ catch (err) {
110
+ if (isItemNotFound(err))
111
+ return; // already gone — fine
112
+ rethrowKeychainError(err);
113
+ }
114
+ },
115
+ };
116
+ }
117
+ /** Production store backed by the real macOS `security` CLI. */
118
+ export const macRelaySecretStore = createMacRelaySecretStore();
119
+ /**
120
+ * In-memory store for tests and any non-Keychain injection point. Holds the
121
+ * secret in a closure — never persisted. Production code never reaches for it.
122
+ */
123
+ export function createInMemoryRelaySecretStore(initial) {
124
+ let secret = initial ?? null;
125
+ return {
126
+ async read() {
127
+ return secret;
128
+ },
129
+ async write(value) {
130
+ secret = value;
131
+ },
132
+ async delete() {
133
+ secret = null;
134
+ },
135
+ };
136
+ }
137
+ //# sourceMappingURL=relay-secret-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-secret-store.js","sourceRoot":"","sources":["../../../../src/cli/feedback/relay-secret-store.ts"],"names":[],"mappings":"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"}