@getrift/rift 0.0.0 → 0.1.0-beta.1

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 (651) hide show
  1. package/README.dev.md +110 -0
  2. package/dist/src/auth/keychain.d.ts +25 -0
  3. package/dist/src/auth/keychain.d.ts.map +1 -0
  4. package/dist/src/auth/keychain.js +113 -0
  5. package/dist/src/auth/keychain.js.map +1 -0
  6. package/dist/src/auth/middleware.d.ts +20 -0
  7. package/dist/src/auth/middleware.d.ts.map +1 -0
  8. package/dist/src/auth/middleware.js +49 -0
  9. package/dist/src/auth/middleware.js.map +1 -0
  10. package/dist/src/auth/rate-limit.d.ts +16 -0
  11. package/dist/src/auth/rate-limit.d.ts.map +1 -0
  12. package/dist/src/auth/rate-limit.js +38 -0
  13. package/dist/src/auth/rate-limit.js.map +1 -0
  14. package/dist/src/auth/rotation.d.ts +67 -0
  15. package/dist/src/auth/rotation.d.ts.map +1 -0
  16. package/dist/src/auth/rotation.js +190 -0
  17. package/dist/src/auth/rotation.js.map +1 -0
  18. package/dist/src/backfill/project-context-batch-constructor.d.ts +127 -0
  19. package/dist/src/backfill/project-context-batch-constructor.d.ts.map +1 -0
  20. package/dist/src/backfill/project-context-batch-constructor.js +210 -0
  21. package/dist/src/backfill/project-context-batch-constructor.js.map +1 -0
  22. package/dist/src/capture/auto-capture.d.ts +162 -0
  23. package/dist/src/capture/auto-capture.d.ts.map +1 -0
  24. package/dist/src/capture/auto-capture.js +601 -0
  25. package/dist/src/capture/auto-capture.js.map +1 -0
  26. package/dist/src/capture/batch-budget.d.ts +90 -0
  27. package/dist/src/capture/batch-budget.d.ts.map +1 -0
  28. package/dist/src/capture/batch-budget.js +148 -0
  29. package/dist/src/capture/batch-budget.js.map +1 -0
  30. package/dist/src/capture/codex-cli-triage-provider.d.ts +17 -0
  31. package/dist/src/capture/codex-cli-triage-provider.d.ts.map +1 -0
  32. package/dist/src/capture/codex-cli-triage-provider.js +109 -0
  33. package/dist/src/capture/codex-cli-triage-provider.js.map +1 -0
  34. package/dist/src/capture/observability.d.ts +42 -0
  35. package/dist/src/capture/observability.d.ts.map +1 -0
  36. package/dist/src/capture/observability.js +87 -0
  37. package/dist/src/capture/observability.js.map +1 -0
  38. package/dist/src/capture/openai-triage-provider.d.ts +92 -0
  39. package/dist/src/capture/openai-triage-provider.d.ts.map +1 -0
  40. package/dist/src/capture/openai-triage-provider.js +267 -0
  41. package/dist/src/capture/openai-triage-provider.js.map +1 -0
  42. package/dist/src/capture/review-queue-index.d.ts +51 -0
  43. package/dist/src/capture/review-queue-index.d.ts.map +1 -0
  44. package/dist/src/capture/review-queue-index.js +204 -0
  45. package/dist/src/capture/review-queue-index.js.map +1 -0
  46. package/dist/src/capture/review-queue.d.ts +43 -0
  47. package/dist/src/capture/review-queue.d.ts.map +1 -0
  48. package/dist/src/capture/review-queue.js +116 -0
  49. package/dist/src/capture/review-queue.js.map +1 -0
  50. package/dist/src/capture/sources.d.ts +7 -0
  51. package/dist/src/capture/sources.d.ts.map +1 -0
  52. package/dist/src/capture/sources.js +3 -0
  53. package/dist/src/capture/sources.js.map +1 -0
  54. package/dist/src/capture/triage-lane.d.ts +39 -0
  55. package/dist/src/capture/triage-lane.d.ts.map +1 -0
  56. package/dist/src/capture/triage-lane.js +217 -0
  57. package/dist/src/capture/triage-lane.js.map +1 -0
  58. package/dist/src/capture/triage-provider.d.ts +75 -0
  59. package/dist/src/capture/triage-provider.d.ts.map +1 -0
  60. package/dist/src/capture/triage-provider.js +120 -0
  61. package/dist/src/capture/triage-provider.js.map +1 -0
  62. package/dist/src/capture/triage.d.ts +30 -0
  63. package/dist/src/capture/triage.d.ts.map +1 -0
  64. package/dist/src/capture/triage.js +48 -0
  65. package/dist/src/capture/triage.js.map +1 -0
  66. package/dist/src/cli/commands/backfill.d.ts +3 -0
  67. package/dist/src/cli/commands/backfill.d.ts.map +1 -0
  68. package/dist/src/cli/commands/backfill.js +1376 -0
  69. package/dist/src/cli/commands/backfill.js.map +1 -0
  70. package/dist/src/cli/commands/bulk-ingest.d.ts +3 -0
  71. package/dist/src/cli/commands/bulk-ingest.d.ts.map +1 -0
  72. package/dist/src/cli/commands/bulk-ingest.js +126 -0
  73. package/dist/src/cli/commands/bulk-ingest.js.map +1 -0
  74. package/dist/src/cli/commands/capture.d.ts +12 -0
  75. package/dist/src/cli/commands/capture.d.ts.map +1 -0
  76. package/dist/src/cli/commands/capture.js +123 -0
  77. package/dist/src/cli/commands/capture.js.map +1 -0
  78. package/dist/src/cli/commands/compact.d.ts +3 -0
  79. package/dist/src/cli/commands/compact.d.ts.map +1 -0
  80. package/dist/src/cli/commands/compact.js +70 -0
  81. package/dist/src/cli/commands/compact.js.map +1 -0
  82. package/dist/src/cli/commands/feedback.d.ts +22 -0
  83. package/dist/src/cli/commands/feedback.d.ts.map +1 -0
  84. package/dist/src/cli/commands/feedback.js +125 -0
  85. package/dist/src/cli/commands/feedback.js.map +1 -0
  86. package/dist/src/cli/commands/hooks-install.d.ts +19 -0
  87. package/dist/src/cli/commands/hooks-install.d.ts.map +1 -0
  88. package/dist/src/cli/commands/hooks-install.js +103 -0
  89. package/dist/src/cli/commands/hooks-install.js.map +1 -0
  90. package/dist/src/cli/commands/import.d.ts +19 -0
  91. package/dist/src/cli/commands/import.d.ts.map +1 -0
  92. package/dist/src/cli/commands/import.js +258 -0
  93. package/dist/src/cli/commands/import.js.map +1 -0
  94. package/dist/src/cli/commands/ingest.d.ts +3 -0
  95. package/dist/src/cli/commands/ingest.d.ts.map +1 -0
  96. package/dist/src/cli/commands/ingest.js +80 -0
  97. package/dist/src/cli/commands/ingest.js.map +1 -0
  98. package/dist/src/cli/commands/mcp-install.d.ts +25 -0
  99. package/dist/src/cli/commands/mcp-install.d.ts.map +1 -0
  100. package/dist/src/cli/commands/mcp-install.js +134 -0
  101. package/dist/src/cli/commands/mcp-install.js.map +1 -0
  102. package/dist/src/cli/commands/onboard.d.ts +98 -0
  103. package/dist/src/cli/commands/onboard.d.ts.map +1 -0
  104. package/dist/src/cli/commands/onboard.js +823 -0
  105. package/dist/src/cli/commands/onboard.js.map +1 -0
  106. package/dist/src/cli/commands/rebuild.d.ts +12 -0
  107. package/dist/src/cli/commands/rebuild.d.ts.map +1 -0
  108. package/dist/src/cli/commands/rebuild.js +164 -0
  109. package/dist/src/cli/commands/rebuild.js.map +1 -0
  110. package/dist/src/cli/commands/reconcile.d.ts +3 -0
  111. package/dist/src/cli/commands/reconcile.d.ts.map +1 -0
  112. package/dist/src/cli/commands/reconcile.js +56 -0
  113. package/dist/src/cli/commands/reconcile.js.map +1 -0
  114. package/dist/src/cli/commands/reindex.d.ts +3 -0
  115. package/dist/src/cli/commands/reindex.d.ts.map +1 -0
  116. package/dist/src/cli/commands/reindex.js +66 -0
  117. package/dist/src/cli/commands/reindex.js.map +1 -0
  118. package/dist/src/cli/commands/review.d.ts +13 -0
  119. package/dist/src/cli/commands/review.d.ts.map +1 -0
  120. package/dist/src/cli/commands/review.js +383 -0
  121. package/dist/src/cli/commands/review.js.map +1 -0
  122. package/dist/src/cli/commands/save.d.ts +3 -0
  123. package/dist/src/cli/commands/save.d.ts.map +1 -0
  124. package/dist/src/cli/commands/save.js +111 -0
  125. package/dist/src/cli/commands/save.js.map +1 -0
  126. package/dist/src/cli/commands/search.d.ts +35 -0
  127. package/dist/src/cli/commands/search.d.ts.map +1 -0
  128. package/dist/src/cli/commands/search.js +88 -0
  129. package/dist/src/cli/commands/search.js.map +1 -0
  130. package/dist/src/cli/commands/stats.d.ts +3 -0
  131. package/dist/src/cli/commands/stats.d.ts.map +1 -0
  132. package/dist/src/cli/commands/stats.js +42 -0
  133. package/dist/src/cli/commands/stats.js.map +1 -0
  134. package/dist/src/cli/commands/status.d.ts +15 -0
  135. package/dist/src/cli/commands/status.d.ts.map +1 -0
  136. package/dist/src/cli/commands/status.js +89 -0
  137. package/dist/src/cli/commands/status.js.map +1 -0
  138. package/dist/src/cli/commands/token-issue.d.ts +3 -0
  139. package/dist/src/cli/commands/token-issue.d.ts.map +1 -0
  140. package/dist/src/cli/commands/token-issue.js +25 -0
  141. package/dist/src/cli/commands/token-issue.js.map +1 -0
  142. package/dist/src/cli/commands/triage.d.ts +3 -0
  143. package/dist/src/cli/commands/triage.d.ts.map +1 -0
  144. package/dist/src/cli/commands/triage.js +125 -0
  145. package/dist/src/cli/commands/triage.js.map +1 -0
  146. package/dist/src/cli/commands/uninstall.d.ts +3 -0
  147. package/dist/src/cli/commands/uninstall.d.ts.map +1 -0
  148. package/dist/src/cli/commands/uninstall.js +238 -0
  149. package/dist/src/cli/commands/uninstall.js.map +1 -0
  150. package/dist/src/cli/feedback/feedback-config.d.ts +21 -0
  151. package/dist/src/cli/feedback/feedback-config.d.ts.map +1 -0
  152. package/dist/src/cli/feedback/feedback-config.js +43 -0
  153. package/dist/src/cli/feedback/feedback-config.js.map +1 -0
  154. package/dist/src/cli/feedback/feedback-history.d.ts +4 -0
  155. package/dist/src/cli/feedback/feedback-history.d.ts.map +1 -0
  156. package/dist/src/cli/feedback/feedback-history.js +115 -0
  157. package/dist/src/cli/feedback/feedback-history.js.map +1 -0
  158. package/dist/src/cli/feedback/feedback-payload.d.ts +53 -0
  159. package/dist/src/cli/feedback/feedback-payload.d.ts.map +1 -0
  160. package/dist/src/cli/feedback/feedback-payload.js +10 -0
  161. package/dist/src/cli/feedback/feedback-payload.js.map +1 -0
  162. package/dist/src/cli/feedback/feedback-relay.d.ts +15 -0
  163. package/dist/src/cli/feedback/feedback-relay.d.ts.map +1 -0
  164. package/dist/src/cli/feedback/feedback-relay.js +47 -0
  165. package/dist/src/cli/feedback/feedback-relay.js.map +1 -0
  166. package/dist/src/cli/feedback/feedback-status.d.ts +11 -0
  167. package/dist/src/cli/feedback/feedback-status.d.ts.map +1 -0
  168. package/dist/src/cli/feedback/feedback-status.js +122 -0
  169. package/dist/src/cli/feedback/feedback-status.js.map +1 -0
  170. package/dist/src/cli/hooks-writers/claude-code-policy-script.d.ts +25 -0
  171. package/dist/src/cli/hooks-writers/claude-code-policy-script.d.ts.map +1 -0
  172. package/dist/src/cli/hooks-writers/claude-code-policy-script.js +85 -0
  173. package/dist/src/cli/hooks-writers/claude-code-policy-script.js.map +1 -0
  174. package/dist/src/cli/hooks-writers/claude-code.d.ts +12 -0
  175. package/dist/src/cli/hooks-writers/claude-code.d.ts.map +1 -0
  176. package/dist/src/cli/hooks-writers/claude-code.js +228 -0
  177. package/dist/src/cli/hooks-writers/claude-code.js.map +1 -0
  178. package/dist/src/cli/hooks-writers/errors.d.ts +16 -0
  179. package/dist/src/cli/hooks-writers/errors.d.ts.map +1 -0
  180. package/dist/src/cli/hooks-writers/errors.js +24 -0
  181. package/dist/src/cli/hooks-writers/errors.js.map +1 -0
  182. package/dist/src/cli/hooks-writers/index.d.ts +13 -0
  183. package/dist/src/cli/hooks-writers/index.d.ts.map +1 -0
  184. package/dist/src/cli/hooks-writers/index.js +26 -0
  185. package/dist/src/cli/hooks-writers/index.js.map +1 -0
  186. package/dist/src/cli/hooks-writers/types.d.ts +27 -0
  187. package/dist/src/cli/hooks-writers/types.d.ts.map +1 -0
  188. package/dist/src/cli/hooks-writers/types.js +9 -0
  189. package/dist/src/cli/hooks-writers/types.js.map +1 -0
  190. package/dist/src/cli/http-client.d.ts +36 -0
  191. package/dist/src/cli/http-client.d.ts.map +1 -0
  192. package/dist/src/cli/http-client.js +153 -0
  193. package/dist/src/cli/http-client.js.map +1 -0
  194. package/dist/src/cli/index.d.ts +4 -0
  195. package/dist/src/cli/index.d.ts.map +1 -0
  196. package/dist/src/cli/index.js +68 -0
  197. package/dist/src/cli/index.js.map +1 -0
  198. package/dist/src/cli/job-poller.d.ts +13 -0
  199. package/dist/src/cli/job-poller.d.ts.map +1 -0
  200. package/dist/src/cli/job-poller.js +29 -0
  201. package/dist/src/cli/job-poller.js.map +1 -0
  202. package/dist/src/cli/mcp-config-writers/codex-toml.d.ts +10 -0
  203. package/dist/src/cli/mcp-config-writers/codex-toml.d.ts.map +1 -0
  204. package/dist/src/cli/mcp-config-writers/codex-toml.js +410 -0
  205. package/dist/src/cli/mcp-config-writers/codex-toml.js.map +1 -0
  206. package/dist/src/cli/mcp-config-writers/errors.d.ts +17 -0
  207. package/dist/src/cli/mcp-config-writers/errors.d.ts.map +1 -0
  208. package/dist/src/cli/mcp-config-writers/errors.js +13 -0
  209. package/dist/src/cli/mcp-config-writers/errors.js.map +1 -0
  210. package/dist/src/cli/mcp-config-writers/index.d.ts +18 -0
  211. package/dist/src/cli/mcp-config-writers/index.d.ts.map +1 -0
  212. package/dist/src/cli/mcp-config-writers/index.js +49 -0
  213. package/dist/src/cli/mcp-config-writers/index.js.map +1 -0
  214. package/dist/src/cli/mcp-config-writers/json-config.d.ts +12 -0
  215. package/dist/src/cli/mcp-config-writers/json-config.d.ts.map +1 -0
  216. package/dist/src/cli/mcp-config-writers/json-config.js +177 -0
  217. package/dist/src/cli/mcp-config-writers/json-config.js.map +1 -0
  218. package/dist/src/cli/mcp-config-writers/redact.d.ts +28 -0
  219. package/dist/src/cli/mcp-config-writers/redact.d.ts.map +1 -0
  220. package/dist/src/cli/mcp-config-writers/redact.js +48 -0
  221. package/dist/src/cli/mcp-config-writers/redact.js.map +1 -0
  222. package/dist/src/cli/mcp-config-writers/types.d.ts +32 -0
  223. package/dist/src/cli/mcp-config-writers/types.d.ts.map +1 -0
  224. package/dist/src/cli/mcp-config-writers/types.js +5 -0
  225. package/dist/src/cli/mcp-config-writers/types.js.map +1 -0
  226. package/dist/src/cli/output.d.ts +8 -0
  227. package/dist/src/cli/output.d.ts.map +1 -0
  228. package/dist/src/cli/output.js +34 -0
  229. package/dist/src/cli/output.js.map +1 -0
  230. package/dist/src/cli/status/friend-header.d.ts +33 -0
  231. package/dist/src/cli/status/friend-header.d.ts.map +1 -0
  232. package/dist/src/cli/status/friend-header.js +108 -0
  233. package/dist/src/cli/status/friend-header.js.map +1 -0
  234. package/dist/src/cli/status/local-signals.d.ts +14 -0
  235. package/dist/src/cli/status/local-signals.d.ts.map +1 -0
  236. package/dist/src/cli/status/local-signals.js +73 -0
  237. package/dist/src/cli/status/local-signals.js.map +1 -0
  238. package/dist/src/cli/token.d.ts +37 -0
  239. package/dist/src/cli/token.d.ts.map +1 -0
  240. package/dist/src/cli/token.js +105 -0
  241. package/dist/src/cli/token.js.map +1 -0
  242. package/dist/src/cli/uninstall/mcp-uninstall.d.ts +33 -0
  243. package/dist/src/cli/uninstall/mcp-uninstall.d.ts.map +1 -0
  244. package/dist/src/cli/uninstall/mcp-uninstall.js +181 -0
  245. package/dist/src/cli/uninstall/mcp-uninstall.js.map +1 -0
  246. package/dist/src/config/loader.d.ts +9 -0
  247. package/dist/src/config/loader.d.ts.map +1 -0
  248. package/dist/src/config/loader.js +73 -0
  249. package/dist/src/config/loader.js.map +1 -0
  250. package/dist/src/config/schema.d.ts +635 -0
  251. package/dist/src/config/schema.d.ts.map +1 -0
  252. package/dist/src/config/schema.js +208 -0
  253. package/dist/src/config/schema.js.map +1 -0
  254. package/dist/src/ingestion/bulk-ingest.d.ts +11 -0
  255. package/dist/src/ingestion/bulk-ingest.d.ts.map +1 -0
  256. package/dist/src/ingestion/bulk-ingest.js +11 -0
  257. package/dist/src/ingestion/bulk-ingest.js.map +1 -0
  258. package/dist/src/ingestion/extractor.d.ts +16 -0
  259. package/dist/src/ingestion/extractor.d.ts.map +1 -0
  260. package/dist/src/ingestion/extractor.js +85 -0
  261. package/dist/src/ingestion/extractor.js.map +1 -0
  262. package/dist/src/ingestion/extractors/docx.d.ts +3 -0
  263. package/dist/src/ingestion/extractors/docx.d.ts.map +1 -0
  264. package/dist/src/ingestion/extractors/docx.js +20 -0
  265. package/dist/src/ingestion/extractors/docx.js.map +1 -0
  266. package/dist/src/ingestion/extractors/pdf.d.ts +3 -0
  267. package/dist/src/ingestion/extractors/pdf.d.ts.map +1 -0
  268. package/dist/src/ingestion/extractors/pdf.js +32 -0
  269. package/dist/src/ingestion/extractors/pdf.js.map +1 -0
  270. package/dist/src/ingestion/historical-campaign.d.ts +340 -0
  271. package/dist/src/ingestion/historical-campaign.d.ts.map +1 -0
  272. package/dist/src/ingestion/historical-campaign.js +1010 -0
  273. package/dist/src/ingestion/historical-campaign.js.map +1 -0
  274. package/dist/src/ingestion/ignored-paths.d.ts +20 -0
  275. package/dist/src/ingestion/ignored-paths.d.ts.map +1 -0
  276. package/dist/src/ingestion/ignored-paths.js +45 -0
  277. package/dist/src/ingestion/ignored-paths.js.map +1 -0
  278. package/dist/src/ingestion/inbox-watcher.d.ts +12 -0
  279. package/dist/src/ingestion/inbox-watcher.d.ts.map +1 -0
  280. package/dist/src/ingestion/inbox-watcher.js +99 -0
  281. package/dist/src/ingestion/inbox-watcher.js.map +1 -0
  282. package/dist/src/ingestion/indexer.d.ts +32 -0
  283. package/dist/src/ingestion/indexer.d.ts.map +1 -0
  284. package/dist/src/ingestion/indexer.js +68 -0
  285. package/dist/src/ingestion/indexer.js.map +1 -0
  286. package/dist/src/ingestion/metadata-extraction.d.ts +53 -0
  287. package/dist/src/ingestion/metadata-extraction.d.ts.map +1 -0
  288. package/dist/src/ingestion/metadata-extraction.js +132 -0
  289. package/dist/src/ingestion/metadata-extraction.js.map +1 -0
  290. package/dist/src/ingestion/parsers/chatgpt-web.d.ts +29 -0
  291. package/dist/src/ingestion/parsers/chatgpt-web.d.ts.map +1 -0
  292. package/dist/src/ingestion/parsers/chatgpt-web.js +100 -0
  293. package/dist/src/ingestion/parsers/chatgpt-web.js.map +1 -0
  294. package/dist/src/ingestion/parsers/claude-code-jsonl.d.ts +16 -0
  295. package/dist/src/ingestion/parsers/claude-code-jsonl.d.ts.map +1 -0
  296. package/dist/src/ingestion/parsers/claude-code-jsonl.js +123 -0
  297. package/dist/src/ingestion/parsers/claude-code-jsonl.js.map +1 -0
  298. package/dist/src/ingestion/parsers/claude-web.d.ts +24 -0
  299. package/dist/src/ingestion/parsers/claude-web.d.ts.map +1 -0
  300. package/dist/src/ingestion/parsers/claude-web.js +78 -0
  301. package/dist/src/ingestion/parsers/claude-web.js.map +1 -0
  302. package/dist/src/ingestion/parsers/codex-jsonl.d.ts +18 -0
  303. package/dist/src/ingestion/parsers/codex-jsonl.d.ts.map +1 -0
  304. package/dist/src/ingestion/parsers/codex-jsonl.js +125 -0
  305. package/dist/src/ingestion/parsers/codex-jsonl.js.map +1 -0
  306. package/dist/src/ingestion/parsers/gemini-web.d.ts +16 -0
  307. package/dist/src/ingestion/parsers/gemini-web.d.ts.map +1 -0
  308. package/dist/src/ingestion/parsers/gemini-web.js +170 -0
  309. package/dist/src/ingestion/parsers/gemini-web.js.map +1 -0
  310. package/dist/src/ingestion/parsers/grok-web.d.ts +40 -0
  311. package/dist/src/ingestion/parsers/grok-web.d.ts.map +1 -0
  312. package/dist/src/ingestion/parsers/grok-web.js +67 -0
  313. package/dist/src/ingestion/parsers/grok-web.js.map +1 -0
  314. package/dist/src/ingestion/parsers/types.d.ts +34 -0
  315. package/dist/src/ingestion/parsers/types.d.ts.map +1 -0
  316. package/dist/src/ingestion/parsers/types.js +26 -0
  317. package/dist/src/ingestion/parsers/types.js.map +1 -0
  318. package/dist/src/ingestion/scanner.d.ts +48 -0
  319. package/dist/src/ingestion/scanner.d.ts.map +1 -0
  320. package/dist/src/ingestion/scanner.js +131 -0
  321. package/dist/src/ingestion/scanner.js.map +1 -0
  322. package/dist/src/ingestion/staging.d.ts +109 -0
  323. package/dist/src/ingestion/staging.d.ts.map +1 -0
  324. package/dist/src/ingestion/staging.js +411 -0
  325. package/dist/src/ingestion/staging.js.map +1 -0
  326. package/dist/src/ingestion/watcher.d.ts +65 -0
  327. package/dist/src/ingestion/watcher.d.ts.map +1 -0
  328. package/dist/src/ingestion/watcher.js +182 -0
  329. package/dist/src/ingestion/watcher.js.map +1 -0
  330. package/dist/src/jobs/codex-override-handler.d.ts +3 -0
  331. package/dist/src/jobs/codex-override-handler.d.ts.map +1 -0
  332. package/dist/src/jobs/codex-override-handler.js +16 -0
  333. package/dist/src/jobs/codex-override-handler.js.map +1 -0
  334. package/dist/src/jobs/handlers/compact.d.ts +30 -0
  335. package/dist/src/jobs/handlers/compact.d.ts.map +1 -0
  336. package/dist/src/jobs/handlers/compact.js +329 -0
  337. package/dist/src/jobs/handlers/compact.js.map +1 -0
  338. package/dist/src/jobs/handlers/ingest.d.ts +13 -0
  339. package/dist/src/jobs/handlers/ingest.d.ts.map +1 -0
  340. package/dist/src/jobs/handlers/ingest.js +255 -0
  341. package/dist/src/jobs/handlers/ingest.js.map +1 -0
  342. package/dist/src/jobs/handlers/reconcile.d.ts +29 -0
  343. package/dist/src/jobs/handlers/reconcile.d.ts.map +1 -0
  344. package/dist/src/jobs/handlers/reconcile.js +476 -0
  345. package/dist/src/jobs/handlers/reconcile.js.map +1 -0
  346. package/dist/src/jobs/handlers/reindex.d.ts +38 -0
  347. package/dist/src/jobs/handlers/reindex.d.ts.map +1 -0
  348. package/dist/src/jobs/handlers/reindex.js +52 -0
  349. package/dist/src/jobs/handlers/reindex.js.map +1 -0
  350. package/dist/src/jobs/handlers/save.d.ts +10 -0
  351. package/dist/src/jobs/handlers/save.d.ts.map +1 -0
  352. package/dist/src/jobs/handlers/save.js +206 -0
  353. package/dist/src/jobs/handlers/save.js.map +1 -0
  354. package/dist/src/jobs/handlers/triage.d.ts +47 -0
  355. package/dist/src/jobs/handlers/triage.d.ts.map +1 -0
  356. package/dist/src/jobs/handlers/triage.js +95 -0
  357. package/dist/src/jobs/handlers/triage.js.map +1 -0
  358. package/dist/src/jobs/queue.d.ts +107 -0
  359. package/dist/src/jobs/queue.d.ts.map +1 -0
  360. package/dist/src/jobs/queue.js +319 -0
  361. package/dist/src/jobs/queue.js.map +1 -0
  362. package/dist/src/jobs/types.d.ts +39 -0
  363. package/dist/src/jobs/types.d.ts.map +1 -0
  364. package/dist/src/jobs/types.js +29 -0
  365. package/dist/src/jobs/types.js.map +1 -0
  366. package/dist/src/jobs/worker-entry.d.ts +10 -0
  367. package/dist/src/jobs/worker-entry.d.ts.map +1 -0
  368. package/dist/src/jobs/worker-entry.js +210 -0
  369. package/dist/src/jobs/worker-entry.js.map +1 -0
  370. package/dist/src/jobs/worker-process.d.ts +50 -0
  371. package/dist/src/jobs/worker-process.d.ts.map +1 -0
  372. package/dist/src/jobs/worker-process.js +186 -0
  373. package/dist/src/jobs/worker-process.js.map +1 -0
  374. package/dist/src/jobs/worker.d.ts +11 -0
  375. package/dist/src/jobs/worker.d.ts.map +1 -0
  376. package/dist/src/jobs/worker.js +14 -0
  377. package/dist/src/jobs/worker.js.map +1 -0
  378. package/dist/src/main.d.ts +2 -0
  379. package/dist/src/main.d.ts.map +1 -0
  380. package/dist/src/main.js +425 -0
  381. package/dist/src/main.js.map +1 -0
  382. package/dist/src/mcp/errors.d.ts +8 -0
  383. package/dist/src/mcp/errors.d.ts.map +1 -0
  384. package/dist/src/mcp/errors.js +50 -0
  385. package/dist/src/mcp/errors.js.map +1 -0
  386. package/dist/src/mcp/server.d.ts +10 -0
  387. package/dist/src/mcp/server.d.ts.map +1 -0
  388. package/dist/src/mcp/server.js +94 -0
  389. package/dist/src/mcp/server.js.map +1 -0
  390. package/dist/src/mcp/tools/context-pack.d.ts +35 -0
  391. package/dist/src/mcp/tools/context-pack.d.ts.map +1 -0
  392. package/dist/src/mcp/tools/context-pack.js +97 -0
  393. package/dist/src/mcp/tools/context-pack.js.map +1 -0
  394. package/dist/src/mcp/tools/conversations-search.d.ts +38 -0
  395. package/dist/src/mcp/tools/conversations-search.d.ts.map +1 -0
  396. package/dist/src/mcp/tools/conversations-search.js +73 -0
  397. package/dist/src/mcp/tools/conversations-search.js.map +1 -0
  398. package/dist/src/mcp/tools/save.d.ts +32 -0
  399. package/dist/src/mcp/tools/save.d.ts.map +1 -0
  400. package/dist/src/mcp/tools/save.js +60 -0
  401. package/dist/src/mcp/tools/save.js.map +1 -0
  402. package/dist/src/mcp/tools/search.d.ts +33 -0
  403. package/dist/src/mcp/tools/search.d.ts.map +1 -0
  404. package/dist/src/mcp/tools/search.js +58 -0
  405. package/dist/src/mcp/tools/search.js.map +1 -0
  406. package/dist/src/mcp/tools/status.d.ts +17 -0
  407. package/dist/src/mcp/tools/status.d.ts.map +1 -0
  408. package/dist/src/mcp/tools/status.js +12 -0
  409. package/dist/src/mcp/tools/status.js.map +1 -0
  410. package/dist/src/observability/coverage.d.ts +100 -0
  411. package/dist/src/observability/coverage.d.ts.map +1 -0
  412. package/dist/src/observability/coverage.js +180 -0
  413. package/dist/src/observability/coverage.js.map +1 -0
  414. package/dist/src/observability/rift-context.d.ts +47 -0
  415. package/dist/src/observability/rift-context.d.ts.map +1 -0
  416. package/dist/src/observability/rift-context.js +118 -0
  417. package/dist/src/observability/rift-context.js.map +1 -0
  418. package/dist/src/observability/staleness.d.ts +43 -0
  419. package/dist/src/observability/staleness.d.ts.map +1 -0
  420. package/dist/src/observability/staleness.js +74 -0
  421. package/dist/src/observability/staleness.js.map +1 -0
  422. package/dist/src/observability/tool-usage-stats.d.ts +23 -0
  423. package/dist/src/observability/tool-usage-stats.d.ts.map +1 -0
  424. package/dist/src/observability/tool-usage-stats.js +83 -0
  425. package/dist/src/observability/tool-usage-stats.js.map +1 -0
  426. package/dist/src/observability/tool-usage.d.ts +68 -0
  427. package/dist/src/observability/tool-usage.d.ts.map +1 -0
  428. package/dist/src/observability/tool-usage.js +207 -0
  429. package/dist/src/observability/tool-usage.js.map +1 -0
  430. package/dist/src/onboarding/daemon-control.d.ts +33 -0
  431. package/dist/src/onboarding/daemon-control.d.ts.map +1 -0
  432. package/dist/src/onboarding/daemon-control.js +92 -0
  433. package/dist/src/onboarding/daemon-control.js.map +1 -0
  434. package/dist/src/onboarding/env-file.d.ts +18 -0
  435. package/dist/src/onboarding/env-file.d.ts.map +1 -0
  436. package/dist/src/onboarding/env-file.js +89 -0
  437. package/dist/src/onboarding/env-file.js.map +1 -0
  438. package/dist/src/onboarding/voyage-validate.d.ts +16 -0
  439. package/dist/src/onboarding/voyage-validate.d.ts.map +1 -0
  440. package/dist/src/onboarding/voyage-validate.js +85 -0
  441. package/dist/src/onboarding/voyage-validate.js.map +1 -0
  442. package/dist/src/providers/anthropic-digest.d.ts +23 -0
  443. package/dist/src/providers/anthropic-digest.d.ts.map +1 -0
  444. package/dist/src/providers/anthropic-digest.js +91 -0
  445. package/dist/src/providers/anthropic-digest.js.map +1 -0
  446. package/dist/src/providers/codex-cli-digest.d.ts +12 -0
  447. package/dist/src/providers/codex-cli-digest.d.ts.map +1 -0
  448. package/dist/src/providers/codex-cli-digest.js +70 -0
  449. package/dist/src/providers/codex-cli-digest.js.map +1 -0
  450. package/dist/src/providers/codex-cli-metadata-extraction.d.ts +14 -0
  451. package/dist/src/providers/codex-cli-metadata-extraction.d.ts.map +1 -0
  452. package/dist/src/providers/codex-cli-metadata-extraction.js +101 -0
  453. package/dist/src/providers/codex-cli-metadata-extraction.js.map +1 -0
  454. package/dist/src/providers/codex-cli-runner.d.ts +14 -0
  455. package/dist/src/providers/codex-cli-runner.d.ts.map +1 -0
  456. package/dist/src/providers/codex-cli-runner.js +272 -0
  457. package/dist/src/providers/codex-cli-runner.js.map +1 -0
  458. package/dist/src/providers/conversation-generation.d.ts +10 -0
  459. package/dist/src/providers/conversation-generation.d.ts.map +1 -0
  460. package/dist/src/providers/conversation-generation.js +54 -0
  461. package/dist/src/providers/conversation-generation.js.map +1 -0
  462. package/dist/src/providers/ollama-embed.d.ts +22 -0
  463. package/dist/src/providers/ollama-embed.d.ts.map +1 -0
  464. package/dist/src/providers/ollama-embed.js +133 -0
  465. package/dist/src/providers/ollama-embed.js.map +1 -0
  466. package/dist/src/providers/ollama.d.ts +42 -0
  467. package/dist/src/providers/ollama.d.ts.map +1 -0
  468. package/dist/src/providers/ollama.js +169 -0
  469. package/dist/src/providers/ollama.js.map +1 -0
  470. package/dist/src/providers/openai-metadata-extraction.d.ts +73 -0
  471. package/dist/src/providers/openai-metadata-extraction.d.ts.map +1 -0
  472. package/dist/src/providers/openai-metadata-extraction.js +161 -0
  473. package/dist/src/providers/openai-metadata-extraction.js.map +1 -0
  474. package/dist/src/providers/operator-overrides.d.ts +24 -0
  475. package/dist/src/providers/operator-overrides.d.ts.map +1 -0
  476. package/dist/src/providers/operator-overrides.js +84 -0
  477. package/dist/src/providers/operator-overrides.js.map +1 -0
  478. package/dist/src/providers/stub.d.ts +17 -0
  479. package/dist/src/providers/stub.d.ts.map +1 -0
  480. package/dist/src/providers/stub.js +72 -0
  481. package/dist/src/providers/stub.js.map +1 -0
  482. package/dist/src/providers/types.d.ts +82 -0
  483. package/dist/src/providers/types.d.ts.map +1 -0
  484. package/dist/src/providers/types.js +52 -0
  485. package/dist/src/providers/types.js.map +1 -0
  486. package/dist/src/providers/voyage.d.ts +23 -0
  487. package/dist/src/providers/voyage.d.ts.map +1 -0
  488. package/dist/src/providers/voyage.js +135 -0
  489. package/dist/src/providers/voyage.js.map +1 -0
  490. package/dist/src/retrieval/compact.d.ts +89 -0
  491. package/dist/src/retrieval/compact.d.ts.map +1 -0
  492. package/dist/src/retrieval/compact.js +348 -0
  493. package/dist/src/retrieval/compact.js.map +1 -0
  494. package/dist/src/retrieval/context-pack.d.ts +123 -0
  495. package/dist/src/retrieval/context-pack.d.ts.map +1 -0
  496. package/dist/src/retrieval/context-pack.js +553 -0
  497. package/dist/src/retrieval/context-pack.js.map +1 -0
  498. package/dist/src/retrieval/cwd.d.ts +25 -0
  499. package/dist/src/retrieval/cwd.d.ts.map +1 -0
  500. package/dist/src/retrieval/cwd.js +48 -0
  501. package/dist/src/retrieval/cwd.js.map +1 -0
  502. package/dist/src/retrieval/degraded.d.ts +20 -0
  503. package/dist/src/retrieval/degraded.d.ts.map +1 -0
  504. package/dist/src/retrieval/degraded.js +43 -0
  505. package/dist/src/retrieval/degraded.js.map +1 -0
  506. package/dist/src/retrieval/hybrid.d.ts +38 -0
  507. package/dist/src/retrieval/hybrid.d.ts.map +1 -0
  508. package/dist/src/retrieval/hybrid.js +82 -0
  509. package/dist/src/retrieval/hybrid.js.map +1 -0
  510. package/dist/src/retrieval/lexical.d.ts +28 -0
  511. package/dist/src/retrieval/lexical.d.ts.map +1 -0
  512. package/dist/src/retrieval/lexical.js +301 -0
  513. package/dist/src/retrieval/lexical.js.map +1 -0
  514. package/dist/src/retrieval/post-filter.d.ts +32 -0
  515. package/dist/src/retrieval/post-filter.d.ts.map +1 -0
  516. package/dist/src/retrieval/post-filter.js +57 -0
  517. package/dist/src/retrieval/post-filter.js.map +1 -0
  518. package/dist/src/retrieval/reranker.d.ts +72 -0
  519. package/dist/src/retrieval/reranker.d.ts.map +1 -0
  520. package/dist/src/retrieval/reranker.js +129 -0
  521. package/dist/src/retrieval/reranker.js.map +1 -0
  522. package/dist/src/retrieval/vector.d.ts +47 -0
  523. package/dist/src/retrieval/vector.d.ts.map +1 -0
  524. package/dist/src/retrieval/vector.js +112 -0
  525. package/dist/src/retrieval/vector.js.map +1 -0
  526. package/dist/src/runtime/legacy-migration.d.ts +27 -0
  527. package/dist/src/runtime/legacy-migration.d.ts.map +1 -0
  528. package/dist/src/runtime/legacy-migration.js +140 -0
  529. package/dist/src/runtime/legacy-migration.js.map +1 -0
  530. package/dist/src/runtime/legacy-name-guard.d.ts +35 -0
  531. package/dist/src/runtime/legacy-name-guard.d.ts.map +1 -0
  532. package/dist/src/runtime/legacy-name-guard.js +58 -0
  533. package/dist/src/runtime/legacy-name-guard.js.map +1 -0
  534. package/dist/src/runtime/rift-env.d.ts +14 -0
  535. package/dist/src/runtime/rift-env.d.ts.map +1 -0
  536. package/dist/src/runtime/rift-env.js +79 -0
  537. package/dist/src/runtime/rift-env.js.map +1 -0
  538. package/dist/src/runtime/watcher-startup.d.ts +2 -0
  539. package/dist/src/runtime/watcher-startup.d.ts.map +1 -0
  540. package/dist/src/runtime/watcher-startup.js +4 -0
  541. package/dist/src/runtime/watcher-startup.js.map +1 -0
  542. package/dist/src/security/archive.d.ts +23 -0
  543. package/dist/src/security/archive.d.ts.map +1 -0
  544. package/dist/src/security/archive.js +163 -0
  545. package/dist/src/security/archive.js.map +1 -0
  546. package/dist/src/security/paths.d.ts +21 -0
  547. package/dist/src/security/paths.d.ts.map +1 -0
  548. package/dist/src/security/paths.js +67 -0
  549. package/dist/src/security/paths.js.map +1 -0
  550. package/dist/src/server/app.d.ts +29 -0
  551. package/dist/src/server/app.d.ts.map +1 -0
  552. package/dist/src/server/app.js +226 -0
  553. package/dist/src/server/app.js.map +1 -0
  554. package/dist/src/server/build-info.d.ts +8 -0
  555. package/dist/src/server/build-info.d.ts.map +1 -0
  556. package/dist/src/server/build-info.js +61 -0
  557. package/dist/src/server/build-info.js.map +1 -0
  558. package/dist/src/server/lifecycle.d.ts +30 -0
  559. package/dist/src/server/lifecycle.d.ts.map +1 -0
  560. package/dist/src/server/lifecycle.js +59 -0
  561. package/dist/src/server/lifecycle.js.map +1 -0
  562. package/dist/src/server/middleware/multipart.d.ts +51 -0
  563. package/dist/src/server/middleware/multipart.d.ts.map +1 -0
  564. package/dist/src/server/middleware/multipart.js +86 -0
  565. package/dist/src/server/middleware/multipart.js.map +1 -0
  566. package/dist/src/server/routes/compact.d.ts +37 -0
  567. package/dist/src/server/routes/compact.d.ts.map +1 -0
  568. package/dist/src/server/routes/compact.js +77 -0
  569. package/dist/src/server/routes/compact.js.map +1 -0
  570. package/dist/src/server/routes/context.d.ts +5 -0
  571. package/dist/src/server/routes/context.d.ts.map +1 -0
  572. package/dist/src/server/routes/context.js +50 -0
  573. package/dist/src/server/routes/context.js.map +1 -0
  574. package/dist/src/server/routes/conversations-search.d.ts +4 -0
  575. package/dist/src/server/routes/conversations-search.d.ts.map +1 -0
  576. package/dist/src/server/routes/conversations-search.js +243 -0
  577. package/dist/src/server/routes/conversations-search.js.map +1 -0
  578. package/dist/src/server/routes/friend-status.d.ts +72 -0
  579. package/dist/src/server/routes/friend-status.d.ts.map +1 -0
  580. package/dist/src/server/routes/friend-status.js +71 -0
  581. package/dist/src/server/routes/friend-status.js.map +1 -0
  582. package/dist/src/server/routes/ingest.d.ts +15 -0
  583. package/dist/src/server/routes/ingest.d.ts.map +1 -0
  584. package/dist/src/server/routes/ingest.js +139 -0
  585. package/dist/src/server/routes/ingest.js.map +1 -0
  586. package/dist/src/server/routes/jobs.d.ts +10 -0
  587. package/dist/src/server/routes/jobs.d.ts.map +1 -0
  588. package/dist/src/server/routes/jobs.js +29 -0
  589. package/dist/src/server/routes/jobs.js.map +1 -0
  590. package/dist/src/server/routes/mcp-usage.d.ts +13 -0
  591. package/dist/src/server/routes/mcp-usage.d.ts.map +1 -0
  592. package/dist/src/server/routes/mcp-usage.js +17 -0
  593. package/dist/src/server/routes/mcp-usage.js.map +1 -0
  594. package/dist/src/server/routes/reconcile.d.ts +4 -0
  595. package/dist/src/server/routes/reconcile.d.ts.map +1 -0
  596. package/dist/src/server/routes/reconcile.js +43 -0
  597. package/dist/src/server/routes/reconcile.js.map +1 -0
  598. package/dist/src/server/routes/reindex.d.ts +4 -0
  599. package/dist/src/server/routes/reindex.d.ts.map +1 -0
  600. package/dist/src/server/routes/reindex.js +74 -0
  601. package/dist/src/server/routes/reindex.js.map +1 -0
  602. package/dist/src/server/routes/save.d.ts +40 -0
  603. package/dist/src/server/routes/save.d.ts.map +1 -0
  604. package/dist/src/server/routes/save.js +112 -0
  605. package/dist/src/server/routes/save.js.map +1 -0
  606. package/dist/src/server/routes/search.d.ts +5 -0
  607. package/dist/src/server/routes/search.d.ts.map +1 -0
  608. package/dist/src/server/routes/search.js +400 -0
  609. package/dist/src/server/routes/search.js.map +1 -0
  610. package/dist/src/server/routes/stats.d.ts +10 -0
  611. package/dist/src/server/routes/stats.d.ts.map +1 -0
  612. package/dist/src/server/routes/stats.js +15 -0
  613. package/dist/src/server/routes/stats.js.map +1 -0
  614. package/dist/src/server/routes/status.d.ts +20 -0
  615. package/dist/src/server/routes/status.d.ts.map +1 -0
  616. package/dist/src/server/routes/status.js +31 -0
  617. package/dist/src/server/routes/status.js.map +1 -0
  618. package/dist/src/server/routes/triage.d.ts +4 -0
  619. package/dist/src/server/routes/triage.d.ts.map +1 -0
  620. package/dist/src/server/routes/triage.js +94 -0
  621. package/dist/src/server/routes/triage.js.map +1 -0
  622. package/dist/src/server/save-quality.d.ts +21 -0
  623. package/dist/src/server/save-quality.d.ts.map +1 -0
  624. package/dist/src/server/save-quality.js +51 -0
  625. package/dist/src/server/save-quality.js.map +1 -0
  626. package/dist/src/storage/atomic.d.ts +8 -0
  627. package/dist/src/storage/atomic.d.ts.map +1 -0
  628. package/dist/src/storage/atomic.js +22 -0
  629. package/dist/src/storage/atomic.js.map +1 -0
  630. package/dist/src/storage/db.d.ts +15 -0
  631. package/dist/src/storage/db.d.ts.map +1 -0
  632. package/dist/src/storage/db.js +43 -0
  633. package/dist/src/storage/db.js.map +1 -0
  634. package/dist/src/storage/integrity.d.ts +11 -0
  635. package/dist/src/storage/integrity.d.ts.map +1 -0
  636. package/dist/src/storage/integrity.js +66 -0
  637. package/dist/src/storage/integrity.js.map +1 -0
  638. package/dist/src/storage/rebuild.d.ts +37 -0
  639. package/dist/src/storage/rebuild.d.ts.map +1 -0
  640. package/dist/src/storage/rebuild.js +353 -0
  641. package/dist/src/storage/rebuild.js.map +1 -0
  642. package/dist/src/storage/shadow-swap.d.ts +20 -0
  643. package/dist/src/storage/shadow-swap.d.ts.map +1 -0
  644. package/dist/src/storage/shadow-swap.js +163 -0
  645. package/dist/src/storage/shadow-swap.js.map +1 -0
  646. package/dist/src/storage/tables.d.ts +77 -0
  647. package/dist/src/storage/tables.d.ts.map +1 -0
  648. package/dist/src/storage/tables.js +196 -0
  649. package/dist/src/storage/tables.js.map +1 -0
  650. package/package.json +45 -14
  651. package/index.js +0 -3
@@ -0,0 +1,823 @@
1
+ /**
2
+ * `rift onboard` — first-run wizard.
3
+ *
4
+ * Walks a friend from "fresh install + Voyage key in hand" to "first
5
+ * useful recall against their freshly-imported data". Step ordering
6
+ * matches Slice 4 in the friend-beta plan; each step is idempotent and
7
+ * `--yes` accepts every prompt's default.
8
+ *
9
+ * Flags worth pointing out:
10
+ * --voyage-key <key> non-interactive key entry
11
+ * --voyage-label <label> operator-supplied display label (no inference)
12
+ * --enable-feedback-relay <url>
13
+ * opt into the Clem-side relay non-interactively
14
+ * --import-export <path> import an export inline; `--no-import-export`
15
+ * skips the prompt entirely
16
+ * --reconfigure-voyage Slice 6 recovery flow — skip everything
17
+ * except validate + write key + kickstart + smoke
18
+ * --yes accept all defaults (used by install scripts)
19
+ * --skip-capture suppress the post-onboarding capture pass
20
+ * (useful in tests / CI dry-runs)
21
+ */
22
+ import crypto from "node:crypto";
23
+ import fs from "node:fs";
24
+ import os from "node:os";
25
+ import path from "node:path";
26
+ import readline from "node:readline";
27
+ import { Command } from "commander";
28
+ import { CliError, createHttpClient, readToken, resolveBaseUrl, } from "../http-client.js";
29
+ import { issueToken } from "../token.js";
30
+ import { loadConfig } from "../../config/loader.js";
31
+ import { defaultRiftEnvPath, loadRiftEnv, } from "../../runtime/rift-env.js";
32
+ import { runLegacyMigration } from "../../runtime/legacy-migration.js";
33
+ import { sanitizeProjectLabel } from "../../runtime/legacy-name-guard.js";
34
+ import { validateVoyageKey } from "../../onboarding/voyage-validate.js";
35
+ import { writeEnvFile } from "../../onboarding/env-file.js";
36
+ import { kickstartDaemon, waitForHealth, } from "../../onboarding/daemon-control.js";
37
+ import { runAutoCapture, resolveCodexCaptureDeps, } from "../../capture/auto-capture.js";
38
+ import { CodexCliTriageProvider } from "../../capture/codex-cli-triage-provider.js";
39
+ import { discoverClaudeCodeSessions } from "../../ingestion/parsers/claude-code-jsonl.js";
40
+ import { discoverCodexSessions } from "../../ingestion/parsers/codex-jsonl.js";
41
+ import { writeHookConfig } from "../hooks-writers/index.js";
42
+ import { HooksParseFailedError } from "../hooks-writers/index.js";
43
+ import { pollJob } from "../job-poller.js";
44
+ import { isJobFailure } from "../output.js";
45
+ const SUPPORTED_INGEST_EXTENSIONS = new Set([".json", ".zip"]);
46
+ const DEFAULT_DATA_DIR = path.join(os.homedir(), "Library", "Application Support", "Rift", "data");
47
+ // Inline import is intentionally narrow until Slice 3 lands the real
48
+ // `rift import` flow with structural sniffing per source. ChatGPT exports
49
+ // are the most common friend handoff and we route them straight through.
50
+ const ONBOARD_INLINE_IMPORT_SOURCE = "chatgpt_web";
51
+ export function makeOnboardCommand() {
52
+ return new Command("onboard")
53
+ .description("First-run wizard: validate Voyage key, capture, import, recall test")
54
+ .option("--voyage-key <key>", "Voyage API key (skips paste prompt)")
55
+ .option("--voyage-label <label>", "Operator-supplied display label for the Voyage project")
56
+ .option("--enable-feedback-relay <url>", "Opt into the Rift feedback relay non-interactively (URL required)")
57
+ .option("--no-feedback-relay", "Decline the feedback relay (local-only)")
58
+ .option("--import-export <path>", "Import an export inline (.json or .zip)")
59
+ .option("--no-import-export", "Skip the import-now prompt")
60
+ .option("--reconfigure-voyage", "Recovery flow: replace the Voyage key only", false)
61
+ .option("--yes", "Accept all defaults (non-interactive)", false)
62
+ .option("--skip-capture", "Skip the post-setup capture pass (test-only)", false)
63
+ .option("--with-claude-hook", "Install the Rift policy hook into Claude Code without prompting", false)
64
+ .option("--no-claude-hook", "Skip the Claude Code policy-hook prompt entirely")
65
+ .action(async (opts, cmd) => {
66
+ const globalOpts = cmd.optsWithGlobals();
67
+ try {
68
+ await runOnboard(opts, globalOpts);
69
+ }
70
+ catch (err) {
71
+ const msg = err instanceof CliError
72
+ ? err.message
73
+ : err instanceof Error
74
+ ? err.message
75
+ : String(err);
76
+ process.stderr.write(`onboard failed: ${msg}\n`);
77
+ process.exitCode = 1;
78
+ }
79
+ });
80
+ }
81
+ async function runOnboard(opts, globalOpts) {
82
+ const rl = readline.createInterface({
83
+ input: process.stdin,
84
+ output: process.stdout,
85
+ terminal: !!process.stdin.isTTY,
86
+ });
87
+ try {
88
+ if (opts.reconfigureVoyage) {
89
+ await reconfigureVoyageFlow(opts, globalOpts, rl);
90
+ return;
91
+ }
92
+ say("");
93
+ say("Rift — first-run setup");
94
+ say("─────────────────────");
95
+ // Step 1 — legacy migration (idempotent).
96
+ const dataDir = await ensureConfigAndDataDir(globalOpts.config, opts, rl);
97
+ say("");
98
+ say("Running legacy migration check…");
99
+ const migration = await runLegacyMigration({ dataDir });
100
+ if (migration.migratedCount > 0) {
101
+ say(`Migrated ${migration.migratedCount} legacy artifact(s).`);
102
+ }
103
+ else {
104
+ say("No legacy artifacts found.");
105
+ }
106
+ // Step 2 — Voyage key + validate + persist + kickstart + smoke.
107
+ say("");
108
+ say("Voyage API key");
109
+ const last4 = await collectAndPersistVoyageKey(opts, globalOpts, rl);
110
+ // Step 2b — sanitize + persist optional --voyage-label to config.json
111
+ // (backup first). Invalid labels are dropped without echoing the raw
112
+ // value, so a key-shaped, path-shaped, or legacy-name-shaped label
113
+ // can never leak through stdout or config.json.
114
+ const safeLabel = applyVoyageLabel(opts.voyageLabel, globalOpts.config, say);
115
+ // Step 3 — Codex CLI preflight.
116
+ say("");
117
+ say("Codex CLI preflight…");
118
+ const codexOk = await codexPreflight();
119
+ if (!codexOk) {
120
+ say("Codex CLI is not authenticated. Run: codex login");
121
+ say("(Auto-capture needs Codex CLI auth. Re-run rift onboard once codex login succeeds.)");
122
+ throw new CliError("Codex CLI preflight failed.", "validation");
123
+ }
124
+ say("Codex CLI ready.");
125
+ // Step 4 — discover sessions.
126
+ say("");
127
+ const claudeSessions = safeDiscover(() => discoverClaudeCodeSessions(path.join(os.homedir(), ".claude")));
128
+ const codexSessions = safeDiscover(() => discoverCodexSessions());
129
+ say(`Found ${claudeSessions} Claude Code session(s) and ${codexSessions} Codex CLI session(s).`);
130
+ // Step 5 — privacy + feedback opt-in.
131
+ say("");
132
+ say("Privacy");
133
+ sayPrivacyContract();
134
+ const feedback = await collectFeedbackPreference(opts, rl, dataDir);
135
+ if (feedback.enabled) {
136
+ say(`Feedback relay enabled (installation_id: ${feedback.installation_id}).`);
137
+ }
138
+ else {
139
+ say("Feedback relay off — feedback stays in local JSONL only.");
140
+ }
141
+ // Step 5b — optional Claude Code policy hook.
142
+ say("");
143
+ await maybeInstallClaudeCodeHook(opts, rl);
144
+ // Step 6 + 7 — watermark current sessions + run one capture pass.
145
+ let captureSaved = 0;
146
+ if (!opts.skipCapture) {
147
+ say("");
148
+ say("Running first capture pass (watermark + scan)…");
149
+ const captureResult = await runFirstCapturePass(globalOpts.config, dataDir);
150
+ captureSaved = captureResult.saved;
151
+ }
152
+ else {
153
+ say("Skipping capture pass (--skip-capture).");
154
+ }
155
+ // Step 8 — optional export import.
156
+ say("");
157
+ let importSucceeded = false;
158
+ if (!opts.noImportExport) {
159
+ const importPath = await collectImportPath(opts, rl);
160
+ if (importPath) {
161
+ const outcome = await runImport(importPath, globalOpts.config);
162
+ if (outcome.kind === "imported" || outcome.kind === "duplicate") {
163
+ importSucceeded = true;
164
+ }
165
+ }
166
+ else {
167
+ say("Skipping import. Run rift import <path> --source <name> later.");
168
+ }
169
+ }
170
+ else {
171
+ say("Skipping import (--no-import-export).");
172
+ }
173
+ // Step 9 — first-recall verification.
174
+ // Onboarding declares "complete" only when (a) capture or import landed
175
+ // user data this run, AND (b) a recall query against the daemon returns
176
+ // at least one hit. Without (a), there is nothing to recall — calling
177
+ // it "complete" because /search returned 0 rows would be misleading.
178
+ say("");
179
+ const ingestedAny = captureSaved > 0 || importSucceeded;
180
+ say(`First-recall sanity check (capture saved ${captureSaved} · import ${importSucceeded ? "ok" : "none"})…`);
181
+ const recall = ingestedAny
182
+ ? await firstRecallCheck(globalOpts.config)
183
+ : { ok: false, reason: "no user data was captured or imported during onboarding" };
184
+ // Step 10 — next-action card.
185
+ say("");
186
+ say("─────────────────────");
187
+ for (const line of decideOnboardOutcome({ ingestedAny, recall }))
188
+ say(line);
189
+ say(`Voyage: key valid (last 4 …${last4})${safeLabel ? ` · label ${safeLabel}` : ""}`);
190
+ say("");
191
+ }
192
+ finally {
193
+ rl.close();
194
+ }
195
+ }
196
+ // ----- Step 1: config.json + data dir -----
197
+ async function ensureConfigAndDataDir(configPath, opts, rl) {
198
+ const absoluteConfig = path.resolve(configPath);
199
+ if (fs.existsSync(absoluteConfig)) {
200
+ const config = loadConfig(absoluteConfig);
201
+ say(`Using existing config: ${absoluteConfig}`);
202
+ say(`Data dir: ${config.data_paths.data_dir}`);
203
+ return config.data_paths.data_dir;
204
+ }
205
+ const defaultDataDir = DEFAULT_DATA_DIR;
206
+ const dataDir = opts.yes
207
+ ? defaultDataDir
208
+ : (await ask(rl, `Data dir [${defaultDataDir}]: `, defaultDataDir)).trim() ||
209
+ defaultDataDir;
210
+ fs.mkdirSync(dataDir, { recursive: true });
211
+ const inboxDir = path.join(dataDir, "inbox");
212
+ fs.mkdirSync(inboxDir, { recursive: true });
213
+ const config = {
214
+ sources: [
215
+ {
216
+ path: inboxDir,
217
+ extraction: "cloud",
218
+ mode: "watch",
219
+ scope: "project",
220
+ },
221
+ ],
222
+ embedding: { provider: "voyage", model: "voyage-3-lite" },
223
+ data_paths: { data_dir: dataDir, jobs_dir: path.join(dataDir, "..", "jobs") },
224
+ rate_limit: { window_ms: 60_000, max_requests: 100 },
225
+ capture: { enabled: true, interval_seconds: 3600 },
226
+ };
227
+ fs.mkdirSync(path.dirname(absoluteConfig), { recursive: true });
228
+ fs.writeFileSync(absoluteConfig, JSON.stringify(config, null, 2) + "\n", {
229
+ encoding: "utf8",
230
+ mode: 0o644,
231
+ });
232
+ say(`Wrote default config: ${absoluteConfig}`);
233
+ say(`Data dir: ${dataDir}`);
234
+ // Trigger ensureDirectories.
235
+ loadConfig(absoluteConfig);
236
+ return dataDir;
237
+ }
238
+ // ----- Step 2a: persist --voyage-label to config.json -----
239
+ /**
240
+ * Sanitize a raw `--voyage-label`, persist it when valid, and return the
241
+ * string the caller should use for display. Invalid labels are dropped
242
+ * with a generic notice that never echoes the raw value — so a
243
+ * key-shaped, path-shaped, or legacy-name-shaped label cannot leak
244
+ * through stdout or `config.json`. Returns `null` when the input was
245
+ * absent or rejected.
246
+ *
247
+ * Exported for orchestrator-level tests; `runOnboard` is the only
248
+ * production caller.
249
+ */
250
+ export function applyVoyageLabel(rawLabel, configPath, emit) {
251
+ if (rawLabel === undefined)
252
+ return null;
253
+ const sanitized = sanitizeProjectLabel(rawLabel);
254
+ if (!sanitized) {
255
+ // Generic message: never echo the raw value. Anything we say here
256
+ // also has to land in the friend's terminal, so it must not name
257
+ // the rejected token.
258
+ emit("Ignoring --voyage-label: must be 1–32 chars of letters, digits, '-' or '_' " +
259
+ "(no paths, secrets, or legacy product names).");
260
+ return null;
261
+ }
262
+ persistVoyageLabel(configPath, sanitized);
263
+ emit(`Stored Voyage label: ${sanitized}`);
264
+ return sanitized;
265
+ }
266
+ /**
267
+ * Merge `voyage.project_label` into the config file. The file is
268
+ * backed up to `<file>.bak.<iso>` first so an interrupted write or a
269
+ * future operator typo can be undone. Display only — never sent to the
270
+ * relay, never inferred from the key bytes.
271
+ *
272
+ * Defensively re-runs `sanitizeProjectLabel` even though the standard
273
+ * `applyVoyageLabel` caller has already validated: a future programmer
274
+ * who reaches for this export directly still cannot land an unsafe
275
+ * string in the file.
276
+ */
277
+ export function persistVoyageLabel(configPath, label) {
278
+ const sanitized = sanitizeProjectLabel(label);
279
+ if (!sanitized) {
280
+ throw new CliError("Refusing to persist Voyage label: not a valid label " +
281
+ "(1–32 chars of letters, digits, '-' or '_'; no paths, secrets, or legacy names).", "validation");
282
+ }
283
+ const absolute = path.resolve(configPath);
284
+ if (!fs.existsSync(absolute)) {
285
+ // ensureConfigAndDataDir always writes config.json before this runs;
286
+ // a missing file here means the caller bypassed step 1.
287
+ throw new CliError(`Cannot persist Voyage label: config not found at ${absolute}`, "validation");
288
+ }
289
+ const raw = fs.readFileSync(absolute, "utf8");
290
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
291
+ fs.writeFileSync(`${absolute}.bak.${stamp}`, raw, { encoding: "utf8", mode: 0o600 });
292
+ const parsed = JSON.parse(raw);
293
+ const voyage = parsed["voyage"] ?? {};
294
+ voyage["project_label"] = sanitized;
295
+ parsed["voyage"] = voyage;
296
+ const tmp = `${absolute}.tmp.${process.pid}`;
297
+ fs.writeFileSync(tmp, JSON.stringify(parsed, null, 2) + "\n", {
298
+ encoding: "utf8",
299
+ mode: 0o644,
300
+ });
301
+ fs.renameSync(tmp, absolute);
302
+ }
303
+ // ----- Step 2: Voyage key flow -----
304
+ async function collectAndPersistVoyageKey(opts, globalOpts, rl) {
305
+ const key = await collectVoyageKey(opts, rl);
306
+ say("Validating with Voyage API…");
307
+ const validation = await validateVoyageKey({ apiKey: key });
308
+ if (!validation.ok) {
309
+ throw new CliError(`Voyage validation failed: ${validation.reason}`, "validation");
310
+ }
311
+ say(`Voyage key valid (last 4 …${validation.last4}).`);
312
+ const envPath = defaultRiftEnvPath();
313
+ const writeResult = writeEnvFile({ filePath: envPath, key: "VOYAGE_API_KEY", value: key });
314
+ say(writeResult.backedUp
315
+ ? "Wrote ~/.rift.env (existing file backed up)."
316
+ : "Wrote ~/.rift.env (mode 0600).");
317
+ // Refresh process.env so any subsequent in-process Voyage call sees it.
318
+ loadRiftEnv({ filePath: envPath });
319
+ const refresh = await daemonRefreshFlow(globalOpts);
320
+ // `not_configured` / `agent_not_loaded` are recoverable — the daemon
321
+ // simply isn't running yet (typical on fresh-Mac install before
322
+ // install.sh bootstraps the plist). Onboarding continues without the
323
+ // post-kickstart smoke; install.sh will pick it up.
324
+ if (!refresh.ok && refresh.kind !== "not_configured" && refresh.kind !== "agent_not_loaded") {
325
+ throw new CliError(`Voyage smoke failed after daemon kickstart: ${refresh.reason}`, "server_error");
326
+ }
327
+ return validation.last4;
328
+ }
329
+ async function collectVoyageKey(opts, rl) {
330
+ if (opts.voyageKey)
331
+ return opts.voyageKey.trim();
332
+ if (process.env["VOYAGE_API_KEY"])
333
+ return process.env["VOYAGE_API_KEY"].trim();
334
+ if (opts.yes) {
335
+ throw new CliError("--yes given but no Voyage key found (use --voyage-key or set VOYAGE_API_KEY).", "validation");
336
+ }
337
+ const answer = (await ask(rl, "Paste your Voyage API key: ")).trim();
338
+ if (answer.length === 0) {
339
+ throw new CliError("Voyage key is required.", "validation");
340
+ }
341
+ return answer;
342
+ }
343
+ /**
344
+ * Kickstart, wait for /health, confirm the respawned daemon process has
345
+ * VOYAGE_API_KEY loaded. The smoke is fully non-indexing — `/health`
346
+ * exposes `voyage_key_present` so we never write a row to LanceDB just to
347
+ * prove the daemon read its env file. That keeps first-recall results
348
+ * free of an "onboarding probe" hit that would otherwise satisfy the
349
+ * completion check without any real user data being present.
350
+ */
351
+ async function daemonRefreshFlow(globalOpts) {
352
+ const baseUrl = safeResolveBaseUrl(globalOpts.config);
353
+ if (!baseUrl) {
354
+ say("Daemon not configured yet — skipping kickstart. Bootstrap via install.sh, then re-run rift onboard.");
355
+ return { ok: false, reason: "daemon not configured", kind: "not_configured" };
356
+ }
357
+ const kick = await kickstartDaemon();
358
+ if (kick.status === "agent_not_loaded") {
359
+ say(kick.hint);
360
+ return { ok: false, reason: kick.hint ?? "agent not loaded", kind: "agent_not_loaded" };
361
+ }
362
+ if (kick.status === "failed") {
363
+ return {
364
+ ok: false,
365
+ reason: kick.hint ?? "kickstart failed",
366
+ kind: "kickstart_failed",
367
+ };
368
+ }
369
+ say("Daemon kickstarted.");
370
+ const health = await waitForHealth({ baseUrl });
371
+ if (!health.ok) {
372
+ return { ok: false, reason: health.reason, kind: "health_failed" };
373
+ }
374
+ say(`Daemon healthy (uptime ${health.uptimeSeconds}s).`);
375
+ if (!health.voyageKeyPresent) {
376
+ return {
377
+ ok: false,
378
+ reason: "Daemon /health reports voyage_key_present=false after kickstart.",
379
+ kind: "smoke_failed",
380
+ };
381
+ }
382
+ say("Cloud embedding live (daemon loaded VOYAGE_API_KEY).");
383
+ return { ok: true, kickstarted: true };
384
+ }
385
+ // ----- Token helpers -----
386
+ async function ensureToken(configPath) {
387
+ const existing = await readToken();
388
+ if (existing)
389
+ return existing;
390
+ try {
391
+ const { token } = await issueToken(path.resolve(configPath));
392
+ // Mirror to ~/.rift/token so subsequent CLI calls don't depend on Keychain.
393
+ const tokenPath = path.join(os.homedir(), ".rift", "token");
394
+ fs.mkdirSync(path.dirname(tokenPath), { recursive: true });
395
+ fs.writeFileSync(tokenPath, token + "\n", { encoding: "utf8", mode: 0o600 });
396
+ fs.chmodSync(tokenPath, 0o600);
397
+ return token;
398
+ }
399
+ catch {
400
+ return null;
401
+ }
402
+ }
403
+ // ----- Step 3: Codex preflight -----
404
+ async function codexPreflight() {
405
+ try {
406
+ await new CodexCliTriageProvider({ timeoutMs: 120_000 }).triage({
407
+ content: "User: Rift onboarding preflight.\n\nAssistant: Ready.",
408
+ source: "codex_cli",
409
+ });
410
+ return true;
411
+ }
412
+ catch {
413
+ return false;
414
+ }
415
+ }
416
+ async function collectFeedbackPreference(opts, rl, dataDir) {
417
+ let enabled = false;
418
+ let url;
419
+ if (opts.enableFeedbackRelay) {
420
+ enabled = true;
421
+ url = opts.enableFeedbackRelay;
422
+ }
423
+ else if (opts.noFeedbackRelay || opts.yes) {
424
+ enabled = false;
425
+ }
426
+ else {
427
+ const answer = (await ask(rl, "Opt into the Rift feedback relay? [y/N]: ", "n"))
428
+ .trim()
429
+ .toLowerCase();
430
+ enabled = answer === "y" || answer === "yes";
431
+ if (enabled) {
432
+ url = (await ask(rl, "Relay URL: ")).trim();
433
+ if (!url) {
434
+ say("No URL supplied — keeping relay off.");
435
+ enabled = false;
436
+ url = undefined;
437
+ }
438
+ }
439
+ }
440
+ const cfg = enabled && url
441
+ ? { enabled: true, url, installation_id: crypto.randomUUID() }
442
+ : { enabled: false };
443
+ fs.mkdirSync(dataDir, { recursive: true });
444
+ const sidecar = path.join(dataDir, "feedback-config.json");
445
+ fs.writeFileSync(sidecar, JSON.stringify(cfg, null, 2) + "\n", {
446
+ encoding: "utf8",
447
+ mode: 0o600,
448
+ });
449
+ fs.chmodSync(sidecar, 0o600);
450
+ return cfg;
451
+ }
452
+ // ----- Step 5b: Claude Code policy hook (opt-in) -----
453
+ /**
454
+ * Offer to install the Rift policy hook into Claude Code's settings.
455
+ *
456
+ * Only runs when `~/.claude/settings.json` looks plausible (the dir
457
+ * exists). Honors `--with-claude-hook` (force install, no prompt) and
458
+ * `--no-claude-hook` (skip silently). Default `--yes` declines unless
459
+ * `--with-claude-hook` is also set, so non-interactive operators never
460
+ * silently get a global hook installed.
461
+ *
462
+ * Failures are non-fatal — onboarding continues. The hook is a quality
463
+ * guardrail, not a correctness requirement.
464
+ */
465
+ async function maybeInstallClaudeCodeHook(opts, rl) {
466
+ if (opts.noClaudeHook) {
467
+ return;
468
+ }
469
+ const homeDir = os.homedir();
470
+ const claudeDir = path.join(homeDir, ".claude");
471
+ const claudeCodeDetected = fs.existsSync(claudeDir);
472
+ if (!claudeCodeDetected) {
473
+ return;
474
+ }
475
+ let install = false;
476
+ if (opts.withClaudeHook) {
477
+ install = true;
478
+ }
479
+ else if (opts.yes) {
480
+ // Non-interactive default: skip. Operator must opt in with --with-claude-hook.
481
+ say("Claude Code detected — skipping the policy-hook prompt (pass --with-claude-hook to install non-interactively).");
482
+ return;
483
+ }
484
+ else {
485
+ say("Claude Code detected.");
486
+ say("Optional: install a PreToolUse policy hook so Rift retrieval starts with rift_context_pack");
487
+ say("(prevents broad rift_search dumps from burning context). Disable any time with RIFT_POLICY_DISABLED=1.");
488
+ const answer = (await ask(rl, "Install Claude Code policy hook? [y/N]: ", "n"))
489
+ .trim()
490
+ .toLowerCase();
491
+ install = answer === "y" || answer === "yes";
492
+ }
493
+ if (!install) {
494
+ say("Skipping Claude Code policy hook.");
495
+ return;
496
+ }
497
+ try {
498
+ const outcome = writeHookConfig({
499
+ client: "claude-code",
500
+ homeDir,
501
+ dryRun: false,
502
+ });
503
+ if (outcome.hookEntryAdded) {
504
+ say("Installed Rift policy hook into Claude Code (PreToolUse entry added).");
505
+ }
506
+ else if (outcome.hookEntryReplaced || outcome.scriptUpdated) {
507
+ say("Updated Rift policy hook in Claude Code.");
508
+ }
509
+ else {
510
+ say("Rift policy hook already up-to-date in Claude Code.");
511
+ }
512
+ if (outcome.backupId) {
513
+ say(` Backup ID: ${outcome.backupId}`);
514
+ }
515
+ say(" (Restart Claude Code or open /hooks once for the new entry to load.)");
516
+ }
517
+ catch (err) {
518
+ if (err instanceof HooksParseFailedError) {
519
+ say(err.message);
520
+ }
521
+ else {
522
+ say(`Claude Code hook install failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
523
+ }
524
+ }
525
+ }
526
+ // ----- Step 6 + 7: capture pass -----
527
+ export async function runFirstCapturePass(configPath, dataDir) {
528
+ const baseUrl = safeResolveBaseUrl(configPath);
529
+ if (!baseUrl) {
530
+ say("Daemon not reachable — skipping capture pass.");
531
+ return { saved: 0, reviewed: 0 };
532
+ }
533
+ const token = await ensureToken(configPath);
534
+ if (!token) {
535
+ say("No auth token — skipping capture pass.");
536
+ return { saved: 0, reviewed: 0 };
537
+ }
538
+ const client = createHttpClient({ baseUrl, token });
539
+ let codexCaptureDeps = {};
540
+ try {
541
+ const { loadConfig } = await import("../../config/loader.js");
542
+ codexCaptureDeps = resolveCodexCaptureDeps(loadConfig(configPath));
543
+ }
544
+ catch {
545
+ codexCaptureDeps = {};
546
+ }
547
+ try {
548
+ const report = await runAutoCapture({
549
+ dataDir,
550
+ ...codexCaptureDeps,
551
+ saveFn: async (saveOpts) => {
552
+ const { data } = await client.post("/save", {
553
+ source: saveOpts.source,
554
+ summary: saveOpts.summary,
555
+ content: saveOpts.content,
556
+ topics: saveOpts.topics,
557
+ domain: saveOpts.domain,
558
+ idempotency_key: saveOpts.idempotency_key,
559
+ ...(saveOpts.replace_idempotency_key
560
+ ? { replace_idempotency_key: saveOpts.replace_idempotency_key }
561
+ : {}),
562
+ });
563
+ const resp = data;
564
+ if (resp.duplicate)
565
+ return;
566
+ const result = await pollJob({ get: client.get.bind(client), jobId: resp.job_id });
567
+ if (isJobFailure(result.job, result.timedOut)) {
568
+ throw new Error(`Save job failed: ${result.job.error ?? "unknown"}`);
569
+ }
570
+ },
571
+ });
572
+ say(`Capture: discovered ${report.total_discovered}, new ${report.new_conversations}, saved ${report.saved}, review ${report.review}, errors ${report.errors}.`);
573
+ return { saved: report.saved, reviewed: report.review };
574
+ }
575
+ catch (err) {
576
+ say(`Capture pass error (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
577
+ return { saved: 0, reviewed: 0 };
578
+ }
579
+ }
580
+ // ----- Step 8: import -----
581
+ async function collectImportPath(opts, rl) {
582
+ if (opts.importExport)
583
+ return opts.importExport;
584
+ if (opts.yes)
585
+ return null;
586
+ const answer = (await ask(rl, "Drop a path to a ChatGPT/Claude/Grok/Gemini export to import now (or `skip`): ", "skip")).trim();
587
+ if (!answer || answer.toLowerCase() === "skip")
588
+ return null;
589
+ return answer;
590
+ }
591
+ /**
592
+ * Inline import is intentionally narrow: ChatGPT exports only.
593
+ * Friends importing Claude / Grok / Gemini exports during onboarding
594
+ * are pointed at the standalone `rift import <path> --source <name>`
595
+ * command (Slice 3), which adds structural sniffing per source.
596
+ */
597
+ async function runImport(filePath, configPath) {
598
+ const absolute = path.resolve(filePath);
599
+ if (!fs.existsSync(absolute)) {
600
+ say(`Import file not found: ${absolute}`);
601
+ return { kind: "skipped", reason: "file not found" };
602
+ }
603
+ const ext = path.extname(absolute).toLowerCase();
604
+ if (!SUPPORTED_INGEST_EXTENSIONS.has(ext)) {
605
+ say(`Unsupported file extension "${ext}". Allowed: .json, .zip.`);
606
+ return { kind: "skipped", reason: "unsupported extension" };
607
+ }
608
+ const baseUrl = safeResolveBaseUrl(configPath);
609
+ const token = await ensureToken(configPath);
610
+ if (!baseUrl || !token) {
611
+ say("Daemon not reachable — cannot import.");
612
+ return { kind: "skipped", reason: "daemon not reachable" };
613
+ }
614
+ const client = createHttpClient({ baseUrl, token });
615
+ const buf = fs.readFileSync(absolute);
616
+ const form = new FormData();
617
+ form.append("source", ONBOARD_INLINE_IMPORT_SOURCE);
618
+ form.append("file", new Blob([buf]), path.basename(absolute));
619
+ say(`Importing ${path.basename(absolute)} as ${ONBOARD_INLINE_IMPORT_SOURCE}…`);
620
+ say("(For Claude/Grok/Gemini exports, run: rift import <path> --source <name>)");
621
+ const { data } = await client.postMultipart("/ingest", form);
622
+ const resp = data;
623
+ if (resp.duplicate) {
624
+ say(`Import already submitted (job ${resp.job_id}).`);
625
+ return { kind: "duplicate", jobId: resp.job_id };
626
+ }
627
+ const result = await pollJob({ get: client.get.bind(client), jobId: resp.job_id });
628
+ if (isJobFailure(result.job, result.timedOut)) {
629
+ const reason = result.job.error ?? "unknown";
630
+ say(`Import failed: ${reason}`);
631
+ return { kind: "failed", reason };
632
+ }
633
+ say(`Import complete (job ${resp.job_id}).`);
634
+ return { kind: "imported", jobId: resp.job_id };
635
+ }
636
+ /**
637
+ * Pure outcome decision for the next-action card. Onboarding is only
638
+ * "complete" when this run actually ingested user data AND a recall
639
+ * query against the freshly-ingested data returned at least one hit.
640
+ * Smoke is non-indexing (see daemonRefreshFlow), so any hit is real
641
+ * user data, not a leftover probe.
642
+ */
643
+ export function decideOnboardOutcome(input) {
644
+ const { ingestedAny, recall } = input;
645
+ if (ingestedAny && recall.ok && recall.hits > 0) {
646
+ return [
647
+ `Setup complete — recall returned ${recall.hits} result(s) from your data.`,
648
+ "Next: rift mcp install --client=claude-desktop",
649
+ ];
650
+ }
651
+ if (!ingestedAny) {
652
+ return [
653
+ "Setup incomplete — no user data was captured or imported during onboarding.",
654
+ "Next: drop an export at the prompt above and re-run rift onboard,",
655
+ " or run: rift import <path> --source <name>",
656
+ ];
657
+ }
658
+ if (recall.ok) {
659
+ return [
660
+ "Setup partially complete — capture+import succeeded but search returned 0 hits.",
661
+ "Next: rift feedback --kind=broke --with-status \"first-recall returned 0\"",
662
+ ];
663
+ }
664
+ return [
665
+ `Setup partially complete — recall check failed: ${recall.reason}`,
666
+ "Next: rift status (then: rift feedback --kind=broke --with-status)",
667
+ ];
668
+ }
669
+ // ----- Step 9: first-recall verification -----
670
+ async function firstRecallCheck(configPath) {
671
+ const baseUrl = safeResolveBaseUrl(configPath);
672
+ const token = await ensureToken(configPath);
673
+ if (!baseUrl || !token) {
674
+ return { ok: false, reason: "daemon not reachable" };
675
+ }
676
+ const client = createHttpClient({ baseUrl, token });
677
+ // Generic, content-bearing query — likely to land on captured CLI
678
+ // sessions or imported chat exports without targeting any onboarding
679
+ // marker. The smoke is non-indexing (see daemonRefreshFlow), so any
680
+ // hit returned here is real user data, not a leftover probe.
681
+ try {
682
+ const { data } = await client.post("/search", {
683
+ query: "recent conversation",
684
+ scope: "all",
685
+ top_k: 10,
686
+ });
687
+ const body = data;
688
+ const hits = (body.results?.length ?? body.hits?.length ?? 0);
689
+ return { ok: true, hits };
690
+ }
691
+ catch (err) {
692
+ return { ok: false, reason: err instanceof Error ? err.message : String(err) };
693
+ }
694
+ }
695
+ // ----- Slice 6: --reconfigure-voyage -----
696
+ /**
697
+ * Reconfigure the Voyage key. ALL of (kickstart succeeds, /health 200,
698
+ * smoke `voyage_key_present=true`) must pass; any failure rolls back the
699
+ * env file AND restores the previous in-process VOYAGE_API_KEY so a
700
+ * caller is never left with a half-replaced credential. `agent_not_loaded`
701
+ * counts as a failure here (unlike initial onboard) because reconfigure
702
+ * is, by definition, called against a daemon that should already be
703
+ * running — if the launchd label is gone, we don't trust the new key.
704
+ */
705
+ async function reconfigureVoyageFlow(opts, globalOpts, rl) {
706
+ say("Reconfiguring Voyage key…");
707
+ const key = await collectVoyageKey(opts, rl);
708
+ await performVoyageReconfigure({
709
+ key,
710
+ envPath: defaultRiftEnvPath(),
711
+ refresh: () => daemonRefreshFlow(globalOpts),
712
+ });
713
+ }
714
+ /**
715
+ * Core reconfigure logic, extracted so tests can drive every failure
716
+ * branch (validate fail, kickstart agent_not_loaded, /health fail,
717
+ * voyage_key_present=false) without spinning up a real daemon.
718
+ *
719
+ * Contract: ALL of {validate ok, daemonRefresh ok} must succeed; any
720
+ * failure rolls back the env file AND restores the previous in-process
721
+ * VOYAGE_API_KEY. agent_not_loaded counts as a failure here — the call
722
+ * site only invokes this when the daemon should already be running.
723
+ */
724
+ export async function performVoyageReconfigure(deps) {
725
+ const validate = deps.validate ?? validateVoyageKey;
726
+ const write = deps.write ?? writeEnvFile;
727
+ const loadEnv = deps.loadEnv ?? loadRiftEnv;
728
+ const emit = deps.emit ?? say;
729
+ const validation = await validate({ apiKey: deps.key });
730
+ if (!validation.ok) {
731
+ throw new CliError(`Voyage validation failed: ${validation.reason}`, "validation");
732
+ }
733
+ emit(`Voyage key valid (last 4 …${validation.last4}).`);
734
+ const previousInProcessKey = process.env["VOYAGE_API_KEY"];
735
+ const writeResult = write({
736
+ filePath: deps.envPath,
737
+ key: "VOYAGE_API_KEY",
738
+ value: deps.key,
739
+ });
740
+ loadEnv({ filePath: deps.envPath });
741
+ const refresh = await deps.refresh();
742
+ if (refresh.ok) {
743
+ emit(`Voyage reconfigured (last 4 …${validation.last4}).`);
744
+ return;
745
+ }
746
+ rollbackVoyageEnv(deps.envPath, writeResult, previousInProcessKey);
747
+ throw new CliError(`Reconfigure failed — restored previous Voyage key (reason: ${refresh.reason}).`, "server_error");
748
+ }
749
+ /**
750
+ * Restore a Voyage env file + in-process VOYAGE_API_KEY after a failed
751
+ * write. Exported for testing — `reconfigureVoyageFlow` is the only
752
+ * production caller. When `writeResult.backedUp` is true, the prior
753
+ * env-file contents are copied back at mode 0600; when false (no prior
754
+ * file existed), the file we just wrote is removed so we don't leave
755
+ * a key paired with a now-rejected daemon respawn.
756
+ */
757
+ export function rollbackVoyageEnv(envPath, writeResult, previousInProcessKey) {
758
+ // 1. Env file.
759
+ if (writeResult.backedUp && writeResult.backupPath) {
760
+ try {
761
+ fs.copyFileSync(writeResult.backupPath, envPath);
762
+ fs.chmodSync(envPath, 0o600);
763
+ }
764
+ catch {
765
+ say("Reconfigure rollback: env-file restore failed — ping Clem for recovery.");
766
+ }
767
+ }
768
+ else {
769
+ // No prior env file — best effort: drop the line we just wrote so we
770
+ // don't leave a key paired with a now-rejected daemon respawn.
771
+ try {
772
+ fs.rmSync(envPath, { force: true });
773
+ }
774
+ catch {
775
+ // Best-effort.
776
+ }
777
+ }
778
+ // 2. In-process VOYAGE_API_KEY — restore prior value or delete.
779
+ if (typeof previousInProcessKey === "string" && previousInProcessKey.length > 0) {
780
+ process.env["VOYAGE_API_KEY"] = previousInProcessKey;
781
+ }
782
+ else {
783
+ delete process.env["VOYAGE_API_KEY"];
784
+ }
785
+ }
786
+ // ----- Helpers -----
787
+ function ask(rl, question, fallback) {
788
+ return new Promise((resolve) => {
789
+ rl.question(question, (answer) => {
790
+ resolve(answer || fallback || "");
791
+ });
792
+ });
793
+ }
794
+ function say(line) {
795
+ process.stdout.write(line + "\n");
796
+ }
797
+ function sayPrivacyContract() {
798
+ say([
799
+ " • Conversation content stays local (LanceDB + raw transcripts).",
800
+ " • Content snippets leave the machine for embedding only (Voyage AI).",
801
+ " • The Voyage key sits in ~/.rift.env (mode 0600). Never logged, never sent to Clem.",
802
+ " • Feedback is stored locally as JSONL. Relay is opt-in: explicit notes only,",
803
+ " plus daemon health booleans — no paths, no content, no key bytes.",
804
+ " • Full contract: docs/feedback/PRIVACY.md",
805
+ ].join("\n"));
806
+ }
807
+ function safeDiscover(fn) {
808
+ try {
809
+ return fn().length;
810
+ }
811
+ catch {
812
+ return 0;
813
+ }
814
+ }
815
+ function safeResolveBaseUrl(configPath) {
816
+ try {
817
+ return resolveBaseUrl(configPath);
818
+ }
819
+ catch {
820
+ return null;
821
+ }
822
+ }
823
+ //# sourceMappingURL=onboard.js.map