@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,206 @@
1
+ /**
2
+ * Save job handler — Slice 8.
3
+ *
4
+ * Processes a POST /save payload:
5
+ * 1. Write raw payload to data/raw/conversations/{source}/{timestamp}_{id}.json
6
+ * 2. Generate embedding via EmbeddingProvider
7
+ * 3. Insert row into conversations_hot
8
+ *
9
+ * On failure (after raw write): quarantine to data/quarantine/{source}_{timestamp}_{hash}.json
10
+ * Raw file is written BEFORE table insert (crash safety).
11
+ *
12
+ * Replay safety:
13
+ * - Row ID is the root of the retry chain (walks `retry_of` to the
14
+ * first ancestor), so multi-hop retries all converge on one ID.
15
+ * - Before inserting, checks if the row already exists. If it does
16
+ * (prior run succeeded), the handler returns early — no mutation.
17
+ * - Raw file is written once per stable ID; replays detect the existing
18
+ * file, skip the write, and use the raw file's payload as the
19
+ * authoritative content. This prevents drift between the canonical
20
+ * raw artifact and the indexed row.
21
+ */
22
+ import crypto from "node:crypto";
23
+ import fs from "node:fs";
24
+ import path from "node:path";
25
+ import { getTable } from "../../storage/tables.js";
26
+ import { atomicWrite } from "../../storage/atomic.js";
27
+ /**
28
+ * Walk the `retry_of` chain to the root job.
29
+ *
30
+ * Queue retries point to the immediate failed parent, not the
31
+ * original. A -> B (retry_of=A) -> C (retry_of=B). This function
32
+ * returns A in all three cases, so all retries share one stable ID
33
+ * and one canonical payload.
34
+ */
35
+ function resolveChainRoot(job, queue) {
36
+ let current = job;
37
+ let depth = 0;
38
+ while (current.retry_of && depth < 50) {
39
+ const parent = queue.get(current.retry_of);
40
+ if (!parent)
41
+ break; // Parent not in queue (e.g. pruned) — stop here.
42
+ current = parent;
43
+ depth++;
44
+ }
45
+ return current;
46
+ }
47
+ /**
48
+ * Find the raw file for `rowId` under `rawDir`, if it exists.
49
+ * Files are named `{timestamp}_{rowId}.json`, so we match the suffix.
50
+ * Returns the full path, or undefined if not found.
51
+ */
52
+ function findRawFile(rawDir, rowId) {
53
+ if (!fs.existsSync(rawDir))
54
+ return undefined;
55
+ const suffix = `_${rowId}.json`;
56
+ const match = fs.readdirSync(rawDir).find((f) => f.endsWith(suffix));
57
+ return match ? path.join(rawDir, match) : undefined;
58
+ }
59
+ export function createSaveHandler(deps) {
60
+ return async (job) => {
61
+ const jobPayload = job.payload;
62
+ if (!jobPayload || !jobPayload.source || !jobPayload.summary) {
63
+ throw new Error("Invalid save job payload: missing source or summary");
64
+ }
65
+ // Resolve the chain root to get a stable ID and the original
66
+ // payload's source — the raw directory is always keyed to the
67
+ // first job's source, not the retry's.
68
+ const rootJob = resolveChainRoot(job, deps.queue);
69
+ const rootPayload = rootJob.payload ?? jobPayload;
70
+ const rowId = rootJob.id;
71
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
72
+ // --- 1. Write raw payload to disk (before table insert) ---
73
+ // Always use the root payload's source for the directory path so
74
+ // retries with a changed source still find the canonical artifact.
75
+ const rawDir = path.join(deps.dataDir, "raw", "conversations", rootPayload.source);
76
+ let payload;
77
+ const existingRawPath = findRawFile(rawDir, rowId);
78
+ // Track the path if we write a NEW raw file (not a replay).
79
+ // Used in the catch block to clean up on failed replacement saves.
80
+ let newRawPath;
81
+ if (existingRawPath) {
82
+ // Replay: read the canonical raw file so the indexed row always
83
+ // agrees with the raw artifact, even if the retry carried a
84
+ // different payload (including a different source).
85
+ payload = JSON.parse(fs.readFileSync(existingRawPath, "utf-8"));
86
+ }
87
+ else {
88
+ // First run: persist the raw artifact using the original payload.
89
+ payload = rootPayload;
90
+ const rawFileName = `${timestamp}_${rowId}.json`;
91
+ newRawPath = path.join(rawDir, rawFileName);
92
+ await atomicWrite(newRawPath, JSON.stringify(payload, null, 2));
93
+ }
94
+ // --- 2. Generate embedding + 3. Insert into conversations_hot ---
95
+ // Both steps are wrapped so ANY failure after raw write is quarantined.
96
+ try {
97
+ const table = getTable("conversations_hot");
98
+ // Replay guard: if the row already exists from a prior successful
99
+ // run, return early. No delete, so no risk of data loss.
100
+ const existing = await table
101
+ .query()
102
+ .where(`id = '${rowId}'`)
103
+ .toArray();
104
+ if (existing.length > 0) {
105
+ return; // Already indexed — nothing to do.
106
+ }
107
+ // Generate embedding FIRST — before any deletions so the old row
108
+ // is preserved if embedding fails (data-safety invariant).
109
+ const textForEmbedding = payload.content ?? payload.summary;
110
+ const embedding = await deps.embeddingProvider.embed(textForEmbedding);
111
+ const row = {
112
+ id: rowId,
113
+ content: payload.content ?? payload.summary,
114
+ summary: payload.summary,
115
+ embedding,
116
+ source: payload.source,
117
+ domain: payload.domain ?? "tech",
118
+ intent: "build", // Default — no LLM extraction in this slice
119
+ quality: "medium", // Default — no LLM extraction in this slice
120
+ topics: JSON.stringify(payload.topics ?? []),
121
+ decisions: JSON.stringify(payload.decisions ?? []),
122
+ key_outputs: JSON.stringify(payload.key_outputs ?? []),
123
+ indexed_at: new Date().toISOString(),
124
+ idempotency_key: payload.idempotency_key ?? "",
125
+ };
126
+ // Insert the new row FIRST. Old-version cleanup happens after the
127
+ // insert succeeds, so a failed insert never destroys the old version.
128
+ await table.add([row]);
129
+ // Clean up old version — best-effort AFTER new row is safely stored.
130
+ // Failure here means a temporary duplicate (old + new coexist),
131
+ // which is recoverable; the alternative (deleting old before insert
132
+ // succeeds) risks losing both versions on insert failure.
133
+ if (payload.replace_idempotency_key) {
134
+ try {
135
+ const coldTable = getTable("conversations_cold");
136
+ const hotOldRows = await table
137
+ .query()
138
+ .where(`idempotency_key = '${payload.replace_idempotency_key}'`)
139
+ .toArray();
140
+ const coldOldRows = await coldTable
141
+ .query()
142
+ .where(`idempotency_key = '${payload.replace_idempotency_key}'`)
143
+ .toArray();
144
+ const oldRow = hotOldRows[0] ?? coldOldRows[0];
145
+ if (oldRow) {
146
+ const oldRawDir = path.join(deps.dataDir, "raw", "conversations", oldRow.source);
147
+ const oldRawPath = findRawFile(oldRawDir, oldRow.id);
148
+ if (oldRawPath) {
149
+ try {
150
+ fs.unlinkSync(oldRawPath);
151
+ }
152
+ catch { /* best-effort */ }
153
+ }
154
+ }
155
+ if (hotOldRows.length > 0) {
156
+ await table.delete(`idempotency_key = '${payload.replace_idempotency_key}'`);
157
+ }
158
+ if (coldOldRows.length > 0) {
159
+ await coldTable.delete(`idempotency_key = '${payload.replace_idempotency_key}'`);
160
+ }
161
+ }
162
+ catch (cleanupErr) {
163
+ // Log but don't throw — new version is safely saved.
164
+ // Temporary duplicate is not data loss; reconcile-level
165
+ // dedup can address it if needed.
166
+ process.stderr.write(`save: warning: failed to clean up replaced version (key=${payload.replace_idempotency_key}): ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}\n`);
167
+ }
168
+ }
169
+ }
170
+ catch (err) {
171
+ // If this was a replacement save and we wrote a new raw file,
172
+ // clean it up so reconcile/rebuild won't resurrect the failed
173
+ // version alongside the still-valid old version. For non-
174
+ // replacement first-time saves the raw file is the intended
175
+ // safety net — reconcile recovers from it.
176
+ if (newRawPath && payload.replace_idempotency_key) {
177
+ try {
178
+ fs.unlinkSync(newRawPath);
179
+ }
180
+ catch { /* best-effort */ }
181
+ }
182
+ await quarantine(deps.dataDir, payload, err);
183
+ throw err; // Re-throw so the job is marked failed
184
+ }
185
+ };
186
+ }
187
+ /**
188
+ * Write a quarantine file for a failed save.
189
+ * Path: data/quarantine/{source}_{timestamp}_{hash}.json
190
+ */
191
+ async function quarantine(dataDir, payload, error) {
192
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
193
+ const hash = crypto
194
+ .createHash("sha256")
195
+ .update(JSON.stringify(payload))
196
+ .digest("hex")
197
+ .slice(0, 12);
198
+ const quarantinePath = path.join(dataDir, "quarantine", `${payload.source}_${timestamp}_${hash}.json`);
199
+ const quarantineData = {
200
+ payload,
201
+ error: error instanceof Error ? error.message : String(error),
202
+ quarantined_at: new Date().toISOString(),
203
+ };
204
+ await atomicWrite(quarantinePath, JSON.stringify(quarantineData, null, 2));
205
+ }
206
+ //# sourceMappingURL=save.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../../../../src/jobs/handlers/save.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { JobHandler } from "../types.js";
2
+ import { type TriageResult } from "../../capture/triage-provider.js";
3
+ import type { OpenAIConfig } from "../../config/schema.js";
4
+ import { type HistoricalTriageMeteringMode, type OperatorOverrideProvider } from "../../providers/operator-overrides.js";
5
+ import type { CostReportingTriageProvider } from "../../capture/batch-budget.js";
6
+ export interface TriageJobItem {
7
+ id: string;
8
+ content: string;
9
+ source?: string;
10
+ }
11
+ export interface TriageJobPayload {
12
+ items: TriageJobItem[];
13
+ /**
14
+ * Retained for route/backfill compatibility. Codex CLI is currently the
15
+ * only live triage provider, so provider_override is accepted but does not
16
+ * change provider selection.
17
+ */
18
+ provider_override?: OperatorOverrideProvider;
19
+ }
20
+ export interface TriageJobItemResult {
21
+ id: string;
22
+ triage?: TriageResult;
23
+ error?: string;
24
+ }
25
+ export interface TriageJobOutput {
26
+ job_id: string;
27
+ completed_at: string;
28
+ total: number;
29
+ succeeded: number;
30
+ failed: number;
31
+ cost_cap_exceeded: boolean;
32
+ metering_mode: HistoricalTriageMeteringMode;
33
+ spend_note?: string;
34
+ spent_usd: number;
35
+ cost_cap_usd: number;
36
+ items: TriageJobItemResult[];
37
+ }
38
+ export interface TriageHandlerDeps {
39
+ dataDir: string;
40
+ openai: OpenAIConfig;
41
+ /** Override the API-key resolver (tests). Defaults to macOS Keychain. */
42
+ apiKey?: () => Promise<string>;
43
+ /** Override the provider factory (tests). */
44
+ providerFactory?: (deps: TriageHandlerDeps, payload: TriageJobPayload) => CostReportingTriageProvider;
45
+ }
46
+ export declare function createTriageHandler(deps: TriageHandlerDeps): JobHandler;
47
+ //# sourceMappingURL=triage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage.d.ts","sourceRoot":"","sources":["../../../../src/jobs/handlers/triage.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAO,UAAU,EAAE,MAAM,aAAa,CAAC;AAOnD,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAGL,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC9B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAEjF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;CAC9C;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,4BAA4B,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,6CAA6C;IAC7C,eAAe,CAAC,EAAE,CAChB,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,gBAAgB,KACtB,2BAA2B,CAAC;CAClC;AAYD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,UAAU,CAkFvE"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Triage job handler — Slice 5.
3
+ *
4
+ * Triage is a first-class job type so batches can be queued, retried,
5
+ * and observed independently of ingest. The handler runs every item in
6
+ * the payload through a single guarded TriageProvider so a per-batch
7
+ * cost cap and parallelism limit are enforced at the job boundary.
8
+ *
9
+ * Output: a JSON file at `data/triage-results/{jobId}.json` containing
10
+ * one entry per input item with the triage decision + provenance
11
+ * (decision, confidence, rationale, model, provider, version). Callers
12
+ * (e.g. follow-up routing) read this file. We deliberately don't fan
13
+ * out save/review-queue side effects from inside this handler — Slice 5
14
+ * is about the runtime, not a redesign of the routing pipeline.
15
+ *
16
+ * BatchCostExceededError aborts the job: the failure is surfaced via
17
+ * the job's error field, which is operator-visible.
18
+ */
19
+ import path from "node:path";
20
+ import { atomicWrite } from "../../storage/atomic.js";
21
+ import { BatchBudget, Semaphore, withBatchGuards, } from "../../capture/batch-budget.js";
22
+ import { BatchCostExceededError, } from "../../capture/triage-provider.js";
23
+ import { CodexCliTriageProvider } from "../../capture/codex-cli-triage-provider.js";
24
+ import { resolveOperatorOverrideProvider, triageMeteringModeForProvider, } from "../../providers/operator-overrides.js";
25
+ function newDefaultProvider(_deps, _payload) {
26
+ // OpenAI remains available only via explicit test/providerFactory injection;
27
+ // the production default is intentionally Codex CLI so live capture uses the
28
+ // operator's existing CLI auth instead of a separate Keychain secret.
29
+ return new CodexCliTriageProvider();
30
+ }
31
+ export function createTriageHandler(deps) {
32
+ return async (job) => {
33
+ const payload = (job.payload ?? {});
34
+ const items = Array.isArray(payload.items) ? payload.items : [];
35
+ const providerOverride = resolveOperatorOverrideProvider(payload.provider_override);
36
+ if (items.length === 0) {
37
+ throw new Error("Triage job payload missing items");
38
+ }
39
+ const effectivePayload = {
40
+ items,
41
+ ...(providerOverride ? { provider_override: providerOverride } : {}),
42
+ };
43
+ const provider = (deps.providerFactory ?? newDefaultProvider)(deps, effectivePayload);
44
+ const meteringMode = triageMeteringModeForProvider(providerOverride ?? (deps.providerFactory ? undefined : "codex-cli"));
45
+ const budget = new BatchBudget(deps.openai.max_cost_per_batch_usd);
46
+ const semaphore = new Semaphore(deps.openai.max_parallel_requests);
47
+ const guarded = withBatchGuards(provider, budget, semaphore);
48
+ const results = [];
49
+ let costCapExceeded = false;
50
+ // Run all items in parallel — the semaphore enforces the in-flight cap.
51
+ await Promise.all(items.map(async (item) => {
52
+ try {
53
+ const triage = await guarded.triage({
54
+ content: item.content,
55
+ ...(item.source ? { source: item.source } : {}),
56
+ });
57
+ results.push({ id: item.id, triage });
58
+ }
59
+ catch (err) {
60
+ if (err instanceof BatchCostExceededError) {
61
+ costCapExceeded = true;
62
+ }
63
+ results.push({
64
+ id: item.id,
65
+ error: err instanceof Error ? err.message : String(err),
66
+ });
67
+ }
68
+ }));
69
+ const output = {
70
+ job_id: job.id,
71
+ completed_at: new Date().toISOString(),
72
+ total: items.length,
73
+ succeeded: results.filter((r) => r.triage !== undefined).length,
74
+ failed: results.filter((r) => r.error !== undefined).length,
75
+ cost_cap_exceeded: costCapExceeded,
76
+ metering_mode: meteringMode,
77
+ ...(meteringMode === "unmetered_codex_cli"
78
+ ? {
79
+ spend_note: "Codex CLI historical backfill override is unmetered by OpenAI USD.",
80
+ }
81
+ : {}),
82
+ spent_usd: meteringMode === "openai_usd" ? budget.spent : 0,
83
+ cost_cap_usd: meteringMode === "openai_usd" ? budget.capUsd : 0,
84
+ items: results,
85
+ };
86
+ const outPath = path.join(deps.dataDir, "triage-results", `${job.id}.json`);
87
+ await atomicWrite(outPath, JSON.stringify(output, null, 2));
88
+ if (costCapExceeded) {
89
+ throw new BatchCostExceededError(`Triage job ${job.id} aborted: batch cost cap of $${budget.capUsd.toFixed(2)} exceeded ` +
90
+ `(spent $${budget.spent.toFixed(4)}, ${output.succeeded}/${output.total} completed before cap). ` +
91
+ `Partial results written to ${outPath}.`, budget.spent, budget.capUsd);
92
+ }
93
+ };
94
+ }
95
+ //# sourceMappingURL=triage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage.js","sourceRoot":"","sources":["../../../../src/jobs/handlers/triage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ import type { Job, JobType, CreateJobResult, JobHandler } from "./types.js";
2
+ /**
3
+ * In-process job queue with:
4
+ * - Persistence to `queue.json` (atomic write: temp + rename)
5
+ * - State machine: queued -> running -> completed | failed, plus cancelled, interrupted
6
+ * - Idempotency checked before mutual exclusion (PRD 4.1)
7
+ * - Mutual exclusion for {compact, reindex, reconcile}
8
+ * - Crash recovery: running -> interrupted -> re-queued on startup
9
+ */
10
+ export declare class JobQueue {
11
+ private queuePath;
12
+ private jobs;
13
+ private handlers;
14
+ private processing;
15
+ private held;
16
+ constructor(queuePath: string);
17
+ /**
18
+ * Hold processing — registerHandler and create won't auto-start queued
19
+ * work until releaseHold() is called. Used at startup to prevent
20
+ * recovered jobs from executing before the integrity check completes.
21
+ */
22
+ hold(): void;
23
+ /** Release hold and kick processing for any waiting jobs. */
24
+ releaseHold(): void;
25
+ /** Register a handler for a job type. Kicks processing for any queued work. */
26
+ registerHandler(type: JobType, handler: JobHandler): void;
27
+ /** Check if a handler is registered for a job type. */
28
+ hasHandler(type: JobType): boolean;
29
+ /**
30
+ * Load persisted queue from disk. Mark any `running` jobs as
31
+ * `interrupted` and re-queue them — timers/progress don't survive restart.
32
+ *
33
+ * Only jobs that were `running` at crash time get re-queued. Jobs that
34
+ * were already `interrupted` (from a previous recovery) are left as-is
35
+ * so repeated loads don't multiply work.
36
+ */
37
+ load(): Promise<void>;
38
+ /**
39
+ * Create a job. Returns `{ job, duplicate }`.
40
+ *
41
+ * Idempotency is checked first (PRD 4.1):
42
+ * - If a job with the same `idempotency_key` exists in
43
+ * `queued | running | completed` -> return it with `duplicate: true`.
44
+ * - If it exists in `failed` -> create a new retry job with `retry_of`.
45
+ *
46
+ * Mutual exclusion is checked second:
47
+ * - If the job type is in the exclusive set and another exclusive job
48
+ * is `queued | running`, return null (caller should 409).
49
+ */
50
+ create(type: JobType, opts?: {
51
+ idempotency_key?: string;
52
+ payload?: unknown;
53
+ }): Promise<CreateJobResult | {
54
+ conflict: true;
55
+ }>;
56
+ /** Get a job by ID, or undefined. */
57
+ get(id: string): Job | undefined;
58
+ /**
59
+ * Check whether an idempotency key matches an existing active job.
60
+ * Returns the job if found in queued/running/completed state, undefined otherwise.
61
+ * Does NOT create or mutate anything — safe for pre-flight checks.
62
+ */
63
+ findDuplicate(idempotencyKey: string): Job | undefined;
64
+ /**
65
+ * Cancel a job.
66
+ * - `queued` or `interrupted` -> `cancelled`, returns the job.
67
+ * - `running` -> returns `{ conflict: true }`.
68
+ * - Others -> returns undefined (not found or not cancellable).
69
+ */
70
+ cancel(id: string): Promise<Job | {
71
+ conflict: true;
72
+ } | undefined>;
73
+ /** Atomic write: temp file + rename. */
74
+ private persist;
75
+ /**
76
+ * Find the active job for a given idempotency key.
77
+ * Skip superseded jobs (those with `retried_by` set) so we always
78
+ * find the leaf of the retry chain, not the old parent.
79
+ */
80
+ private findByIdempotencyKey;
81
+ /**
82
+ * Create a job that bypasses the mutual exclusion check and is
83
+ * inserted at the front of the queue (runs before other queued work).
84
+ *
85
+ * Used exclusively for startup corruption repair: the mandatory
86
+ * rebuild must run before any other queued work touches storage,
87
+ * regardless of what else is in the queue. Other exclusive jobs
88
+ * naturally wait (one-at-a-time processing) and run after the
89
+ * rebuild against healthy storage.
90
+ */
91
+ createUrgent(type: JobType, opts?: {
92
+ payload?: unknown;
93
+ }): Promise<CreateJobResult>;
94
+ /** Whether any exclusive job is queued or running. */
95
+ hasActiveExclusiveJob(): boolean;
96
+ /**
97
+ * Return the exclusive job that is currently running, or null.
98
+ * Only returns jobs with status "running" — queued exclusive jobs
99
+ * have not entered their coordinated maintenance phase.
100
+ */
101
+ getRunningExclusiveJob(): Job | null;
102
+ private createRetryJob;
103
+ /** Process the next queued job if no job is currently running. */
104
+ private processNext;
105
+ private findNextQueued;
106
+ }
107
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/jobs/queue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAa,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGvF;;;;;;;GAOG;AACH,qBAAa,QAAQ;IAMP,OAAO,CAAC,SAAS;IAL7B,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,IAAI,CAAS;gBAED,SAAS,EAAE,MAAM;IAErC;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAIZ,6DAA6D;IAC7D,WAAW,IAAI,IAAI;IAKnB,+EAA+E;IAC/E,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAKzD,uDAAuD;IACvD,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIlC;;;;;;;OAOG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C3B;;;;;;;;;;;OAWG;IACG,MAAM,CACV,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GACrD,OAAO,CAAC,eAAe,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC;IA0ChD,qCAAqC;IACrC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAIhC;;;;OAIG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAatD;;;;;OAKG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,SAAS,CAAC;IAkBvE,wCAAwC;YAC1B,OAAO;IAOrB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAO5B;;;;;;;;;OASG;IACG,YAAY,CAChB,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAC3B,OAAO,CAAC,eAAe,CAAC;IAwB3B,sDAAsD;IACtD,qBAAqB,IAAI,OAAO;IAYhC;;;;OAIG;IACH,sBAAsB,IAAI,GAAG,GAAG,IAAI;YAStB,cAAc;IA6B5B,kEAAkE;IAClE,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,cAAc;CAMvB"}