@remnic/core 1.1.12 → 1.1.14

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 (1324) hide show
  1. package/dist/access-cli.d.ts +2 -1
  2. package/dist/access-cli.js +263 -82
  3. package/dist/access-cli.js.map +1 -1
  4. package/dist/access-http.d.ts +26 -60
  5. package/dist/access-http.js +43 -29
  6. package/dist/access-mcp.d.ts +24 -6
  7. package/dist/access-mcp.js +35 -28
  8. package/dist/access-schema.d.ts +9 -6
  9. package/dist/access-schema.js +7 -5
  10. package/dist/access-service-DcCDmNYC.d.ts +1542 -0
  11. package/dist/access-service.d.ts +25 -7
  12. package/dist/access-service.js +33 -26
  13. package/dist/active-memory-bridge.js +2 -2
  14. package/dist/active-recall.js +11 -3
  15. package/dist/active-recall.js.map +1 -1
  16. package/dist/adapters/claude-code.d.ts +24 -0
  17. package/dist/adapters/claude-code.js +9 -0
  18. package/dist/adapters/codex.d.ts +25 -0
  19. package/dist/adapters/codex.js +9 -0
  20. package/dist/adapters/hermes.d.ts +35 -0
  21. package/dist/adapters/hermes.js +9 -0
  22. package/dist/adapters/index.d.ts +6 -0
  23. package/dist/adapters/index.js +26 -0
  24. package/dist/adapters/registry.d.ts +20 -0
  25. package/dist/adapters/registry.js +13 -0
  26. package/dist/adapters/replit.d.ts +28 -0
  27. package/dist/adapters/replit.js +9 -0
  28. package/dist/adapters/types.d.ts +43 -0
  29. package/dist/adapters/types.js +8 -0
  30. package/dist/bootstrap.d.ts +20 -5
  31. package/dist/boxes.d.ts +7 -0
  32. package/dist/boxes.js +1 -1
  33. package/dist/briefing.d.ts +5 -3
  34. package/dist/briefing.js +9 -6
  35. package/dist/buffer-surprise-report.js +1 -1
  36. package/dist/buffer.d.ts +18 -4
  37. package/dist/buffer.js +1 -1
  38. package/dist/calibration.js +4 -4
  39. package/dist/capsule-cli.d.ts +4 -4
  40. package/dist/capsule-cli.js +1 -1
  41. package/dist/capsule-crypto-5CYAGVC5.js +18 -0
  42. package/dist/capsule-merge-4MGKE7C5.js +189 -0
  43. package/dist/causal-behavior.d.ts +8 -28
  44. package/dist/causal-behavior.js +6 -3
  45. package/dist/causal-behavior.js.map +1 -1
  46. package/dist/causal-chain.js +3 -2
  47. package/dist/causal-consolidation.d.ts +1 -1
  48. package/dist/causal-consolidation.js +24 -13
  49. package/dist/causal-consolidation.js.map +1 -1
  50. package/dist/causal-retrieval.js +3 -3
  51. package/dist/causal-trajectory.js +1 -1
  52. package/dist/chunk-25MQ7IHJ.js +427 -0
  53. package/dist/chunk-25MQ7IHJ.js.map +1 -0
  54. package/dist/chunk-2F2W355T.js +256 -0
  55. package/dist/chunk-2F2W355T.js.map +1 -0
  56. package/dist/chunk-2KI4QFHU.js +228 -0
  57. package/dist/chunk-2KI4QFHU.js.map +1 -0
  58. package/dist/chunk-2PRQG7PV.js +86 -0
  59. package/dist/chunk-2PRQG7PV.js.map +1 -0
  60. package/dist/chunk-2QR3XXIC.js +2272 -0
  61. package/dist/chunk-2QR3XXIC.js.map +1 -0
  62. package/dist/chunk-2WWLHTZY.js +121 -0
  63. package/dist/chunk-326G7DJK.js +2185 -0
  64. package/dist/chunk-326G7DJK.js.map +1 -0
  65. package/dist/chunk-34DQE4KF.js +174 -0
  66. package/dist/chunk-34DQE4KF.js.map +1 -0
  67. package/dist/chunk-3APJ5EVB.js +601 -0
  68. package/dist/chunk-3APJ5EVB.js.map +1 -0
  69. package/dist/chunk-3HPAPHUK.js +51 -0
  70. package/dist/chunk-3HPAPHUK.js.map +1 -0
  71. package/dist/chunk-3JXBXXM2.js +69 -0
  72. package/dist/chunk-3JXBXXM2.js.map +1 -0
  73. package/dist/chunk-3KW65B36.js +681 -0
  74. package/dist/chunk-3KW65B36.js.map +1 -0
  75. package/dist/chunk-3UXOZBHV.js +20 -0
  76. package/dist/chunk-3UXOZBHV.js.map +1 -0
  77. package/dist/chunk-3VAL7ZL2.js +266 -0
  78. package/dist/chunk-3VAL7ZL2.js.map +1 -0
  79. package/dist/chunk-3Y4P7RXM.js +31 -0
  80. package/dist/chunk-3Y4P7RXM.js.map +1 -0
  81. package/dist/chunk-47VWKCAF.js +273 -0
  82. package/dist/chunk-47VWKCAF.js.map +1 -0
  83. package/dist/chunk-4CRG46BG.js +271 -0
  84. package/dist/chunk-5375UYTQ.js +914 -0
  85. package/dist/chunk-5375UYTQ.js.map +1 -0
  86. package/dist/chunk-56K5QLHX.js +506 -0
  87. package/dist/chunk-56K5QLHX.js.map +1 -0
  88. package/dist/chunk-5RGLBDQF.js +596 -0
  89. package/dist/chunk-5RGLBDQF.js.map +1 -0
  90. package/dist/chunk-5UZXUTVO.js +9 -0
  91. package/dist/chunk-5UZXUTVO.js.map +1 -0
  92. package/dist/chunk-65PG43EQ.js +105 -0
  93. package/dist/chunk-65PG43EQ.js.map +1 -0
  94. package/dist/chunk-66DHUKLO.js +57 -0
  95. package/dist/chunk-66DHUKLO.js.map +1 -0
  96. package/dist/chunk-6FC5EGNV.js +46 -0
  97. package/dist/chunk-6FC5EGNV.js.map +1 -0
  98. package/dist/chunk-6H2TESSP.js +62 -0
  99. package/dist/chunk-6H2TESSP.js.map +1 -0
  100. package/dist/chunk-6LVVDPJ4.js +32 -0
  101. package/dist/chunk-6LVVDPJ4.js.map +1 -0
  102. package/dist/chunk-6RVI47ZR.js +159 -0
  103. package/dist/chunk-6RVI47ZR.js.map +1 -0
  104. package/dist/chunk-7AAT6G4Q.js +5117 -0
  105. package/dist/chunk-7AAT6G4Q.js.map +1 -0
  106. package/dist/chunk-7DTASS5T.js +29 -0
  107. package/dist/chunk-7DTASS5T.js.map +1 -0
  108. package/dist/chunk-7IASACLB.js +596 -0
  109. package/dist/chunk-7MNMYOFP.js +32 -0
  110. package/dist/chunk-7MNMYOFP.js.map +1 -0
  111. package/dist/chunk-7N4KAIGN.js +133 -0
  112. package/dist/chunk-7N4KAIGN.js.map +1 -0
  113. package/dist/chunk-7OZ53EXP.js +101 -0
  114. package/dist/chunk-7OZ53EXP.js.map +1 -0
  115. package/dist/chunk-7XYTQGCC.js +134 -0
  116. package/dist/chunk-7XYTQGCC.js.map +1 -0
  117. package/dist/chunk-A2XUIMJ3.js +341 -0
  118. package/dist/chunk-A2XUIMJ3.js.map +1 -0
  119. package/dist/chunk-AGZQD76C.js +201 -0
  120. package/dist/chunk-AGZQD76C.js.map +1 -0
  121. package/dist/chunk-APO3DCMU.js +361 -0
  122. package/dist/chunk-APO3DCMU.js.map +1 -0
  123. package/dist/chunk-BFBF3XEF.js +283 -0
  124. package/dist/chunk-BFBF3XEF.js.map +1 -0
  125. package/dist/chunk-BJ3KMYTB.js +1974 -0
  126. package/dist/chunk-BJ3KMYTB.js.map +1 -0
  127. package/dist/chunk-CHEL3SKB.js +6758 -0
  128. package/dist/chunk-CHEL3SKB.js.map +1 -0
  129. package/dist/chunk-CQZRLNMV.js +1491 -0
  130. package/dist/chunk-CQZRLNMV.js.map +1 -0
  131. package/dist/chunk-D46YSIYX.js +892 -0
  132. package/dist/chunk-D46YSIYX.js.map +1 -0
  133. package/dist/chunk-DINWEURR.js +648 -0
  134. package/dist/chunk-DINWEURR.js.map +1 -0
  135. package/dist/chunk-DK5LDEQM.js +530 -0
  136. package/dist/chunk-DK5LDEQM.js.map +1 -0
  137. package/dist/chunk-DOM4GKSW.js +34 -0
  138. package/dist/chunk-DOM4GKSW.js.map +1 -0
  139. package/dist/chunk-EDTHC6UD.js +1075 -0
  140. package/dist/chunk-EFJ3MQ4V.js +721 -0
  141. package/dist/chunk-EHRTFRWW.js +89 -0
  142. package/dist/chunk-EHRTFRWW.js.map +1 -0
  143. package/dist/chunk-FAJ7FZYM.js +11 -0
  144. package/dist/chunk-FAJ7FZYM.js.map +1 -0
  145. package/dist/chunk-FBYESMQ2.js +570 -0
  146. package/dist/chunk-FDU6HUUL.js +147 -0
  147. package/dist/chunk-FF4KLI5W.js +99 -0
  148. package/dist/chunk-FF4KLI5W.js.map +1 -0
  149. package/dist/chunk-FIT6DMX6.js +310 -0
  150. package/dist/chunk-FIT6DMX6.js.map +1 -0
  151. package/dist/chunk-FJ43PRLT.js +272 -0
  152. package/dist/chunk-FJ43PRLT.js.map +1 -0
  153. package/dist/chunk-FKFMOY3N.js +32 -0
  154. package/dist/chunk-FKFMOY3N.js.map +1 -0
  155. package/dist/chunk-FLTNHQK6.js +262 -0
  156. package/dist/chunk-FLTNHQK6.js.map +1 -0
  157. package/dist/chunk-GA454ALV.js +12436 -0
  158. package/dist/chunk-GA454ALV.js.map +1 -0
  159. package/dist/chunk-GGKRUQOO.js +228 -0
  160. package/dist/chunk-GIF42EW3.js +63 -0
  161. package/dist/chunk-GIF42EW3.js.map +1 -0
  162. package/dist/chunk-GL6I6MEQ.js +647 -0
  163. package/dist/chunk-H3ME6L6D.js +709 -0
  164. package/dist/chunk-H3ME6L6D.js.map +1 -0
  165. package/dist/chunk-HHLLAQGZ.js +1 -0
  166. package/dist/chunk-HXXBL2KD.js +2040 -0
  167. package/dist/chunk-I5V2VDIW.js +219 -0
  168. package/dist/chunk-I5V2VDIW.js.map +1 -0
  169. package/dist/chunk-I6K5FBRQ.js +35 -0
  170. package/dist/chunk-I6K5FBRQ.js.map +1 -0
  171. package/dist/chunk-ICRIXAP2.js +121 -0
  172. package/dist/chunk-ICRIXAP2.js.map +1 -0
  173. package/dist/chunk-J4EB7DNW.js +11 -0
  174. package/dist/chunk-J4EB7DNW.js.map +1 -0
  175. package/dist/chunk-JLFA7DQG.js +62 -0
  176. package/dist/chunk-JLFA7DQG.js.map +1 -0
  177. package/dist/chunk-KJTKLXTH.js +9 -0
  178. package/dist/chunk-KJTKLXTH.js.map +1 -0
  179. package/dist/chunk-KLAO5DGL.js +917 -0
  180. package/dist/chunk-KLAO5DGL.js.map +1 -0
  181. package/dist/chunk-KNKUID7G.js +183 -0
  182. package/dist/chunk-KOSORCJG.js +624 -0
  183. package/dist/chunk-KOSORCJG.js.map +1 -0
  184. package/dist/chunk-KUJVMMZQ.js +1262 -0
  185. package/dist/chunk-KUJVMMZQ.js.map +1 -0
  186. package/dist/chunk-LCR46JY5.js +123 -0
  187. package/dist/chunk-LCR46JY5.js.map +1 -0
  188. package/dist/chunk-LLQ2LLWF.js +148 -0
  189. package/dist/chunk-LLQ2LLWF.js.map +1 -0
  190. package/dist/chunk-LPMVBPA3.js +236 -0
  191. package/dist/chunk-LT3NLYSI.js +50 -0
  192. package/dist/chunk-LT3NLYSI.js.map +1 -0
  193. package/dist/chunk-LUDTDZLK.js +287 -0
  194. package/dist/chunk-LUDTDZLK.js.map +1 -0
  195. package/dist/chunk-M23FSH32.js +3963 -0
  196. package/dist/chunk-M23FSH32.js.map +1 -0
  197. package/dist/chunk-MC26UJIM.js +118 -0
  198. package/dist/chunk-ME6ESPZU.js +119 -0
  199. package/dist/chunk-ME6ESPZU.js.map +1 -0
  200. package/dist/chunk-MGKYQQYF.js +272 -0
  201. package/dist/chunk-MJFNCJXV.js +66 -0
  202. package/dist/chunk-MJFNCJXV.js.map +1 -0
  203. package/dist/chunk-MSWG7JI6.js +237 -0
  204. package/dist/chunk-MSWG7JI6.js.map +1 -0
  205. package/dist/chunk-MT25YHYH.js +141 -0
  206. package/dist/chunk-MT25YHYH.js.map +1 -0
  207. package/dist/chunk-MT4HVDUZ.js +53 -0
  208. package/dist/chunk-MY6TPVXW.js +219 -0
  209. package/dist/chunk-N2D6GXBM.js +267 -0
  210. package/dist/chunk-N2D6GXBM.js.map +1 -0
  211. package/dist/chunk-NJ3MJQZX.js +46 -0
  212. package/dist/chunk-NJ3MJQZX.js.map +1 -0
  213. package/dist/chunk-NMZY542O.js +335 -0
  214. package/dist/chunk-NMZY542O.js.map +1 -0
  215. package/dist/chunk-NNVTUXEB.js +23 -0
  216. package/dist/chunk-NZL6GGQE.js +375 -0
  217. package/dist/chunk-NZL6GGQE.js.map +1 -0
  218. package/dist/chunk-P4NEIHUT.js +108 -0
  219. package/dist/chunk-P7FMDTKL.js +103 -0
  220. package/dist/chunk-P7FMDTKL.js.map +1 -0
  221. package/dist/chunk-PHK3HARR.js +32 -0
  222. package/dist/chunk-PHK3HARR.js.map +1 -0
  223. package/dist/chunk-PIRJPV5T.js +98 -0
  224. package/dist/chunk-PIRJPV5T.js.map +1 -0
  225. package/dist/chunk-PK7H5L6Y.js +159 -0
  226. package/dist/chunk-PK7H5L6Y.js.map +1 -0
  227. package/dist/chunk-PR5FBTFU.js +233 -0
  228. package/dist/chunk-PR5FBTFU.js.map +1 -0
  229. package/dist/chunk-PU63GXWS.js +174 -0
  230. package/dist/chunk-PU63GXWS.js.map +1 -0
  231. package/dist/chunk-PZIAX57I.js +124 -0
  232. package/dist/chunk-PZIAX57I.js.map +1 -0
  233. package/dist/chunk-Q7P4WJDP.js +26 -0
  234. package/dist/chunk-Q7P4WJDP.js.map +1 -0
  235. package/dist/chunk-QQUAB63I.js +63 -0
  236. package/dist/chunk-QQUAB63I.js.map +1 -0
  237. package/dist/chunk-QRNI5JBH.js +18 -0
  238. package/dist/chunk-RHY3HH7P.js +601 -0
  239. package/dist/chunk-RHY3HH7P.js.map +1 -0
  240. package/dist/chunk-RRF5UOBJ.js +91 -0
  241. package/dist/chunk-RXDLTSWT.js +124 -0
  242. package/dist/chunk-RXDLTSWT.js.map +1 -0
  243. package/dist/chunk-RYED3SPJ.js +42 -0
  244. package/dist/chunk-RYED3SPJ.js.map +1 -0
  245. package/dist/chunk-S7KDBTWT.js +106 -0
  246. package/dist/chunk-S7KDBTWT.js.map +1 -0
  247. package/dist/chunk-SEDEKFYQ.js +1 -0
  248. package/dist/chunk-TECVW3JP.js +36 -0
  249. package/dist/chunk-TECVW3JP.js.map +1 -0
  250. package/dist/chunk-TFO23QT4.js +88 -0
  251. package/dist/chunk-TFO23QT4.js.map +1 -0
  252. package/dist/chunk-TK4UEOSK.js +76 -0
  253. package/dist/chunk-TK4UEOSK.js.map +1 -0
  254. package/dist/chunk-TKWGAOLV.js +122 -0
  255. package/dist/chunk-TKWGAOLV.js.map +1 -0
  256. package/dist/chunk-TMM4S4IJ.js +597 -0
  257. package/dist/chunk-TMM4S4IJ.js.map +1 -0
  258. package/dist/chunk-TMQLARTH.js +188 -0
  259. package/dist/chunk-TMQLARTH.js.map +1 -0
  260. package/dist/chunk-TPDBFYEG.js +130 -0
  261. package/dist/chunk-TPDBFYEG.js.map +1 -0
  262. package/dist/chunk-TPMQ3G6Z.js +145 -0
  263. package/dist/chunk-TPMQ3G6Z.js.map +1 -0
  264. package/dist/chunk-TZOLIGIG.js +61 -0
  265. package/dist/chunk-TZOLIGIG.js.map +1 -0
  266. package/dist/chunk-U3PN77QT.js +113 -0
  267. package/dist/chunk-U3WSW6PZ.js +277 -0
  268. package/dist/chunk-U4SCL7B7.js +640 -0
  269. package/dist/chunk-U4SCL7B7.js.map +1 -0
  270. package/dist/chunk-UWK5OXUJ.js +156 -0
  271. package/dist/chunk-UWK5OXUJ.js.map +1 -0
  272. package/dist/chunk-UWVJF25J.js +74 -0
  273. package/dist/chunk-UXHQAFNA.js +1317 -0
  274. package/dist/chunk-UXHQAFNA.js.map +1 -0
  275. package/dist/chunk-V5OCT34X.js +1 -0
  276. package/dist/chunk-VLXA6PI2.js +304 -0
  277. package/dist/chunk-VLXA6PI2.js.map +1 -0
  278. package/dist/chunk-VNO6ZJ35.js +500 -0
  279. package/dist/chunk-VNO6ZJ35.js.map +1 -0
  280. package/dist/chunk-VW676BEI.js +827 -0
  281. package/dist/chunk-VW676BEI.js.map +1 -0
  282. package/dist/chunk-W3LR522O.js +2296 -0
  283. package/dist/chunk-W4L6CZKA.js +96 -0
  284. package/dist/chunk-W4L6CZKA.js.map +1 -0
  285. package/dist/chunk-W4RVMTHR.js +372 -0
  286. package/dist/chunk-W4RVMTHR.js.map +1 -0
  287. package/dist/chunk-WEHSQBFR.js +188 -0
  288. package/dist/chunk-WEHSQBFR.js.map +1 -0
  289. package/dist/chunk-WELDCG6C.js +380 -0
  290. package/dist/chunk-WELDCG6C.js.map +1 -0
  291. package/dist/chunk-WZYKANL3.js +2800 -0
  292. package/dist/chunk-WZYKANL3.js.map +1 -0
  293. package/dist/chunk-XIG5PDM7.js +48 -0
  294. package/dist/chunk-XJNBEDFE.js +193 -0
  295. package/dist/chunk-XJNBEDFE.js.map +1 -0
  296. package/dist/chunk-XVVIG67A.js +291 -0
  297. package/dist/chunk-XVVIG67A.js.map +1 -0
  298. package/dist/chunk-XVZ7B3HG.js +135 -0
  299. package/dist/chunk-YBPYIAA5.js +73 -0
  300. package/dist/chunk-YBPYIAA5.js.map +1 -0
  301. package/dist/chunk-Z734BLO3.js +21 -0
  302. package/dist/chunk-Z734BLO3.js.map +1 -0
  303. package/dist/chunk-ZKSK55RC.js +269 -0
  304. package/dist/chunk-ZKSK55RC.js.map +1 -0
  305. package/dist/chunk-ZTFCYYEZ.js +69 -0
  306. package/dist/chunk-ZTFCYYEZ.js.map +1 -0
  307. package/dist/chunk-ZY2MNJR6.js +329 -0
  308. package/dist/chunk-ZY2MNJR6.js.map +1 -0
  309. package/dist/cli-D3VpkVwB.d.ts +1136 -0
  310. package/dist/cli.d.ts +39 -10
  311. package/dist/cli.js +108 -49
  312. package/dist/commitment-ledger.js +1 -1
  313. package/dist/compat/checks.d.ts +5 -0
  314. package/dist/compat/checks.js +11 -0
  315. package/dist/compat/checks.js.map +1 -0
  316. package/dist/compat/types.d.ts +30 -0
  317. package/dist/compat/types.js +1 -0
  318. package/dist/compat/types.js.map +1 -0
  319. package/dist/compounding/engine.d.ts +221 -0
  320. package/dist/compounding/engine.js +32 -0
  321. package/dist/compounding/engine.js.map +1 -0
  322. package/dist/compounding/preference-consolidator.d.ts +92 -0
  323. package/dist/compounding/preference-consolidator.js +553 -0
  324. package/dist/compounding/preference-consolidator.js.map +1 -0
  325. package/dist/config.d.ts +4 -2
  326. package/dist/config.js +9 -4
  327. package/dist/conflict-policy-DyJ2wd-h.d.ts +4 -0
  328. package/dist/connectors/codex-materialize-runner.d.ts +64 -0
  329. package/dist/connectors/codex-materialize-runner.js +33 -0
  330. package/dist/connectors/codex-materialize-runner.js.map +1 -0
  331. package/dist/connectors/codex-materialize.d.ts +195 -0
  332. package/dist/connectors/codex-materialize.js +38 -0
  333. package/dist/connectors/codex-materialize.js.map +1 -0
  334. package/dist/connectors/index.d.ts +444 -0
  335. package/dist/connectors/index.js +115 -0
  336. package/dist/connectors/index.js.map +1 -0
  337. package/dist/connectors-cli-CwbyjGR7.d.ts +257 -0
  338. package/dist/connectors-cli.d.ts +1 -1
  339. package/dist/consolidation-provenance-check.d.ts +3 -1
  340. package/dist/consolidation-undo.d.ts +3 -1
  341. package/dist/contradiction/index.d.ts +258 -0
  342. package/dist/contradiction/index.js +43 -0
  343. package/dist/contradiction/index.js.map +1 -0
  344. package/dist/contradiction-review-ATP4S6IC.js +30 -0
  345. package/dist/contradiction-review-ATP4S6IC.js.map +1 -0
  346. package/dist/contradiction-scan-5A4IDZV5.js +13 -0
  347. package/dist/contradiction-scan-5A4IDZV5.js.map +1 -0
  348. package/dist/conversation-index/backend.d.ts +97 -0
  349. package/dist/conversation-index/backend.js +13 -0
  350. package/dist/conversation-index/backend.js.map +1 -0
  351. package/dist/conversation-index/chunker.d.ts +16 -0
  352. package/dist/conversation-index/chunker.js +8 -0
  353. package/dist/conversation-index/chunker.js.map +1 -0
  354. package/dist/conversation-index/cleanup.d.ts +11 -0
  355. package/dist/conversation-index/cleanup.js +9 -0
  356. package/dist/conversation-index/cleanup.js.map +1 -0
  357. package/dist/conversation-index/faiss-adapter.d.ts +6 -0
  358. package/dist/conversation-index/faiss-adapter.js +16 -0
  359. package/dist/conversation-index/faiss-adapter.js.map +1 -0
  360. package/dist/conversation-index/indexer.d.ts +23 -0
  361. package/dist/conversation-index/indexer.js +15 -0
  362. package/dist/conversation-index/indexer.js.map +1 -0
  363. package/dist/conversation-index/search.d.ts +6 -0
  364. package/dist/conversation-index/search.js +11 -0
  365. package/dist/conversation-index/search.js.map +1 -0
  366. package/dist/embedding-fallback.js +2 -2
  367. package/dist/enrichment/index.d.ts +163 -0
  368. package/dist/enrichment/index.js +18 -0
  369. package/dist/enrichment/index.js.map +1 -0
  370. package/dist/entity-retrieval.d.ts +4 -2
  371. package/dist/entity-retrieval.js +8 -5
  372. package/dist/evals.js +1 -1
  373. package/dist/explicit-capture.d.ts +20 -5
  374. package/dist/explicit-capture.js +2 -2
  375. package/dist/extraction-judge-training.js +1 -1
  376. package/dist/extraction.js +8 -8
  377. package/dist/faiss-adapter-CzPghc4C.d.ts +70 -0
  378. package/dist/fallback-llm.d.ts +2 -0
  379. package/dist/fallback-llm.js +4 -4
  380. package/dist/graph-edge-decay-5DI5GUNL.js +207 -0
  381. package/dist/index.d.ts +66 -711
  382. package/dist/index.js +556 -2680
  383. package/dist/index.js.map +1 -1
  384. package/dist/lcm/archive.d.ts +89 -0
  385. package/dist/lcm/archive.js +12 -0
  386. package/dist/lcm/archive.js.map +1 -0
  387. package/dist/lcm/dag.d.ts +48 -0
  388. package/dist/lcm/dag.js +8 -0
  389. package/dist/lcm/dag.js.map +1 -0
  390. package/dist/lcm/engine.d.ts +116 -0
  391. package/dist/lcm/engine.js +20 -0
  392. package/dist/lcm/engine.js.map +1 -0
  393. package/dist/lcm/index.d.ts +12 -0
  394. package/dist/lcm/index.js +44 -0
  395. package/dist/lcm/index.js.map +1 -0
  396. package/dist/lcm/queue.d.ts +62 -0
  397. package/dist/lcm/queue.js +8 -0
  398. package/dist/lcm/queue.js.map +1 -0
  399. package/dist/lcm/recall.d.ts +20 -0
  400. package/dist/lcm/recall.js +8 -0
  401. package/dist/lcm/recall.js.map +1 -0
  402. package/dist/lcm/schema.d.ts +16 -0
  403. package/dist/lcm/schema.js +14 -0
  404. package/dist/lcm/schema.js.map +1 -0
  405. package/dist/lcm/summarizer.d.ts +38 -0
  406. package/dist/lcm/summarizer.js +12 -0
  407. package/dist/lcm/summarizer.js.map +1 -0
  408. package/dist/lcm/tools.d.ts +29 -0
  409. package/dist/lcm/tools.js +8 -0
  410. package/dist/lcm/tools.js.map +1 -0
  411. package/dist/live-connectors-runner.js +5 -5
  412. package/dist/local-llm.js +3 -3
  413. package/dist/maintenance/archive-observations.d.ts +18 -0
  414. package/dist/maintenance/archive-observations.js +8 -0
  415. package/dist/maintenance/archive-observations.js.map +1 -0
  416. package/dist/maintenance/backup-stamp.d.ts +3 -0
  417. package/dist/maintenance/backup-stamp.js +8 -0
  418. package/dist/maintenance/backup-stamp.js.map +1 -0
  419. package/dist/maintenance/memory-governance-cron.d.ts +85 -0
  420. package/dist/maintenance/memory-governance-cron.js +22 -0
  421. package/dist/maintenance/memory-governance-cron.js.map +1 -0
  422. package/dist/maintenance/memory-governance.d.ts +137 -0
  423. package/dist/maintenance/memory-governance.js +40 -0
  424. package/dist/maintenance/memory-governance.js.map +1 -0
  425. package/dist/maintenance/migrate-observations.d.ts +18 -0
  426. package/dist/maintenance/migrate-observations.js +9 -0
  427. package/dist/maintenance/migrate-observations.js.map +1 -0
  428. package/dist/maintenance/observation-ledger-utils.d.ts +10 -0
  429. package/dist/maintenance/observation-ledger-utils.js +10 -0
  430. package/dist/maintenance/observation-ledger-utils.js.map +1 -0
  431. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +15 -0
  432. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -0
  433. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js.map +1 -0
  434. package/dist/maintenance/rebuild-memory-projection.d.ts +77 -0
  435. package/dist/maintenance/rebuild-memory-projection.js +35 -0
  436. package/dist/maintenance/rebuild-memory-projection.js.map +1 -0
  437. package/dist/maintenance/rebuild-observations.d.ts +17 -0
  438. package/dist/maintenance/rebuild-observations.js +9 -0
  439. package/dist/maintenance/rebuild-observations.js.map +1 -0
  440. package/dist/mcp-memory-inspector-app.d.ts +24 -6
  441. package/dist/memory-projection-store.d.ts +108 -3
  442. package/dist/memory-projection-store.js +2 -1
  443. package/dist/memory-worth-outcomes.d.ts +4 -2
  444. package/dist/migrate/from-engram.d.ts +24 -0
  445. package/dist/migrate/from-engram.js +12 -0
  446. package/dist/migrate/from-engram.js.map +1 -0
  447. package/dist/namespaces/migrate.d.ts +50 -0
  448. package/dist/namespaces/migrate.js +50 -0
  449. package/dist/namespaces/migrate.js.map +1 -0
  450. package/dist/namespaces/principal.d.ts +17 -0
  451. package/dist/namespaces/principal.js +16 -0
  452. package/dist/namespaces/principal.js.map +1 -0
  453. package/dist/namespaces/search.d.ts +46 -0
  454. package/dist/namespaces/search.js +28 -0
  455. package/dist/namespaces/search.js.map +1 -0
  456. package/dist/namespaces/storage.d.ts +32 -0
  457. package/dist/namespaces/storage.js +28 -0
  458. package/dist/namespaces/storage.js.map +1 -0
  459. package/dist/network/tailscale.d.ts +41 -0
  460. package/dist/network/tailscale.js +9 -0
  461. package/dist/network/tailscale.js.map +1 -0
  462. package/dist/network/webdav.d.ts +39 -0
  463. package/dist/network/webdav.js +10 -0
  464. package/dist/network/webdav.js.map +1 -0
  465. package/dist/objective-state-writers.js +2 -2
  466. package/dist/operator-toolkit.d.ts +4 -2
  467. package/dist/operator-toolkit.js +32 -14
  468. package/dist/opik-exporter.js +2 -2
  469. package/dist/opik-exporter.js.map +1 -1
  470. package/dist/orchestrator-DuWl9Hwx.d.ts +1244 -0
  471. package/dist/orchestrator.d.ts +22 -7
  472. package/dist/orchestrator.js +79 -44
  473. package/dist/path-MR5JPYOP.js +9 -0
  474. package/dist/path-MR5JPYOP.js.map +1 -0
  475. package/dist/qmd-recall-cache.d.ts +1 -1
  476. package/dist/qmd.d.ts +102 -3
  477. package/dist/qmd.js +23 -5
  478. package/dist/recall-explain-renderer.js +3 -3
  479. package/dist/recall-xray-cli.js +4 -4
  480. package/dist/recall-xray-renderer.js +3 -3
  481. package/dist/recall-xray.js +2 -2
  482. package/dist/replay/normalizers/chatgpt.d.ts +6 -0
  483. package/dist/replay/normalizers/chatgpt.js +11 -0
  484. package/dist/replay/normalizers/chatgpt.js.map +1 -0
  485. package/dist/replay/normalizers/claude.d.ts +6 -0
  486. package/dist/replay/normalizers/claude.js +11 -0
  487. package/dist/replay/normalizers/claude.js.map +1 -0
  488. package/dist/replay/normalizers/openclaw.d.ts +6 -0
  489. package/dist/replay/normalizers/openclaw.js +11 -0
  490. package/dist/replay/normalizers/openclaw.js.map +1 -0
  491. package/dist/replay/normalizers/shared.d.ts +16 -0
  492. package/dist/replay/normalizers/shared.js +14 -0
  493. package/dist/replay/normalizers/shared.js.map +1 -0
  494. package/dist/replay/runner.d.ts +35 -0
  495. package/dist/replay/runner.js +16 -0
  496. package/dist/replay/runner.js.map +1 -0
  497. package/dist/replay/types.d.ts +57 -0
  498. package/dist/replay/types.js +19 -0
  499. package/dist/replay/types.js.map +1 -0
  500. package/dist/resolution-B7FNQSSP.js +12 -0
  501. package/dist/resolution-B7FNQSSP.js.map +1 -0
  502. package/dist/resolve-provider-secret.js +2 -2
  503. package/dist/resume-bundles.js +8 -6
  504. package/dist/retrieval-agents.d.ts +1 -1
  505. package/dist/routing/engine.d.ts +35 -0
  506. package/dist/routing/engine.js +16 -0
  507. package/dist/routing/engine.js.map +1 -0
  508. package/dist/routing/store.d.ts +27 -0
  509. package/dist/routing/store.js +10 -0
  510. package/dist/routing/store.js.map +1 -0
  511. package/dist/runtime/better-sqlite.d.ts +8 -0
  512. package/dist/runtime/better-sqlite.js +10 -0
  513. package/dist/runtime/better-sqlite.js.map +1 -0
  514. package/dist/runtime/child-process.d.ts +32 -0
  515. package/dist/runtime/child-process.js +10 -0
  516. package/dist/runtime/child-process.js.map +1 -0
  517. package/dist/runtime/env.d.ts +5 -0
  518. package/dist/runtime/env.js +12 -0
  519. package/dist/runtime/env.js.map +1 -0
  520. package/dist/schemas.d.ts +22 -22
  521. package/dist/sdk-compat.js +1 -1
  522. package/dist/search/document-scanner.d.ts +22 -0
  523. package/dist/search/document-scanner.js +8 -0
  524. package/dist/search/document-scanner.js.map +1 -0
  525. package/dist/search/embed-helper.d.ts +35 -0
  526. package/dist/search/embed-helper.js +9 -0
  527. package/dist/search/embed-helper.js.map +1 -0
  528. package/dist/search/factory.d.ts +32 -0
  529. package/dist/search/factory.js +29 -0
  530. package/dist/search/factory.js.map +1 -0
  531. package/dist/search/index.d.ts +15 -0
  532. package/dist/search/index.js +50 -0
  533. package/dist/search/index.js.map +1 -0
  534. package/dist/search/lancedb-backend.d.ts +51 -0
  535. package/dist/search/lancedb-backend.js +10 -0
  536. package/dist/search/lancedb-backend.js.map +1 -0
  537. package/dist/search/meilisearch-backend.d.ts +48 -0
  538. package/dist/search/meilisearch-backend.js +10 -0
  539. package/dist/search/meilisearch-backend.js.map +1 -0
  540. package/dist/search/noop-backend.d.ts +26 -0
  541. package/dist/search/noop-backend.js +8 -0
  542. package/dist/search/noop-backend.js.map +1 -0
  543. package/dist/search/orama-backend.d.ts +53 -0
  544. package/dist/search/orama-backend.js +10 -0
  545. package/dist/search/orama-backend.js.map +1 -0
  546. package/dist/search/port.d.ts +61 -0
  547. package/dist/search/port.js +1 -0
  548. package/dist/search/port.js.map +1 -0
  549. package/dist/search/remote-backend.d.ts +39 -0
  550. package/dist/search/remote-backend.js +9 -0
  551. package/dist/search/remote-backend.js.map +1 -0
  552. package/dist/secure-store/index.d.ts +890 -0
  553. package/dist/secure-store/index.js +156 -0
  554. package/dist/secure-store/index.js.map +1 -0
  555. package/dist/semantic-VwGI14Ok.d.ts +69 -0
  556. package/dist/semantic-consolidation-4HkHWgeI.d.ts +180 -0
  557. package/dist/semantic-consolidation.d.ts +2 -2
  558. package/dist/semantic-consolidation.js +13 -6
  559. package/dist/semantic-rule-promotion.js +8 -5
  560. package/dist/semantic-rule-verifier.js +8 -5
  561. package/dist/shared-context/manager.d.ts +131 -0
  562. package/dist/shared-context/manager.js +15 -0
  563. package/dist/shared-context/manager.js.map +1 -0
  564. package/dist/skills-registry.js +13 -1
  565. package/dist/skills-registry.js.map +1 -1
  566. package/dist/state-store-VZU2IA53.js +16 -0
  567. package/dist/state-store-VZU2IA53.js.map +1 -0
  568. package/dist/storage-paths.d.ts +9 -0
  569. package/dist/storage-paths.js +20 -0
  570. package/dist/storage-paths.js.map +1 -0
  571. package/dist/storage.d.ts +3 -1
  572. package/dist/storage.js +7 -4
  573. package/dist/summarizer.d.ts +5 -0
  574. package/dist/summarizer.js +9 -8
  575. package/dist/summary-snapshot.js +2 -1
  576. package/dist/surfaces/dreams.d.ts +16 -0
  577. package/dist/surfaces/dreams.js +282 -0
  578. package/dist/surfaces/dreams.js.map +1 -0
  579. package/dist/surfaces/heartbeat.d.ts +17 -0
  580. package/dist/surfaces/heartbeat.js +265 -0
  581. package/dist/surfaces/heartbeat.js.map +1 -0
  582. package/dist/temporal-supersession.d.ts +3 -1
  583. package/dist/threading.d.ts +5 -0
  584. package/dist/threading.js +2 -1
  585. package/dist/tier-migration.d.ts +4 -2
  586. package/dist/tokens.js +2 -2
  587. package/dist/transcript.d.ts +15 -1
  588. package/dist/transcript.js +2 -1
  589. package/dist/transfer/autodetect.d.ts +4 -0
  590. package/dist/transfer/autodetect.js +15 -0
  591. package/dist/transfer/autodetect.js.map +1 -0
  592. package/dist/transfer/backup.d.ts +21 -0
  593. package/dist/transfer/backup.js +17 -0
  594. package/dist/transfer/backup.js.map +1 -0
  595. package/dist/transfer/capsule-export.d.ts +113 -0
  596. package/dist/transfer/capsule-export.js +19 -0
  597. package/dist/transfer/capsule-export.js.map +1 -0
  598. package/dist/transfer/capsule-import.d.ts +124 -0
  599. package/dist/transfer/capsule-import.js +16 -0
  600. package/dist/transfer/capsule-import.js.map +1 -0
  601. package/dist/transfer/constants.d.ts +13 -0
  602. package/dist/transfer/constants.js +12 -0
  603. package/dist/transfer/constants.js.map +1 -0
  604. package/dist/transfer/export-json.d.ts +11 -0
  605. package/dist/transfer/export-json.js +11 -0
  606. package/dist/transfer/export-json.js.map +1 -0
  607. package/dist/transfer/export-md.d.ts +10 -0
  608. package/dist/transfer/export-md.js +13 -0
  609. package/dist/transfer/export-md.js.map +1 -0
  610. package/dist/transfer/export-sqlite.d.ts +9 -0
  611. package/dist/transfer/export-sqlite.js +12 -0
  612. package/dist/transfer/export-sqlite.js.map +1 -0
  613. package/dist/transfer/fs-utils.d.ts +61 -0
  614. package/dist/transfer/fs-utils.js +40 -0
  615. package/dist/transfer/fs-utils.js.map +1 -0
  616. package/dist/transfer/import-json.d.ts +16 -0
  617. package/dist/transfer/import-json.js +13 -0
  618. package/dist/transfer/import-json.js.map +1 -0
  619. package/dist/transfer/import-md.d.ts +14 -0
  620. package/dist/transfer/import-md.js +11 -0
  621. package/dist/transfer/import-md.js.map +1 -0
  622. package/dist/transfer/import-sqlite.d.ts +14 -0
  623. package/dist/transfer/import-sqlite.js +12 -0
  624. package/dist/transfer/import-sqlite.js.map +1 -0
  625. package/dist/transfer/sqlite-schema.d.ts +4 -0
  626. package/dist/transfer/sqlite-schema.js +10 -0
  627. package/dist/transfer/sqlite-schema.js.map +1 -0
  628. package/dist/transfer/types.d.ts +916 -0
  629. package/dist/transfer/types.js +30 -0
  630. package/dist/transfer/types.js.map +1 -0
  631. package/dist/types.d.ts +28 -1
  632. package/dist/types.js +1 -1
  633. package/dist/verified-recall.js +9 -6
  634. package/dist/work/board.d.ts +43 -0
  635. package/dist/work/board.js +14 -0
  636. package/dist/work/board.js.map +1 -0
  637. package/dist/work/boundary.d.ts +8 -0
  638. package/dist/work/boundary.js +14 -0
  639. package/dist/work/boundary.js.map +1 -0
  640. package/dist/work/storage.d.ts +39 -0
  641. package/dist/work/storage.js +11 -0
  642. package/dist/work/storage.js.map +1 -0
  643. package/dist/work/types.d.ts +75 -0
  644. package/dist/work/types.js +1 -0
  645. package/dist/work/types.js.map +1 -0
  646. package/package.json +2767 -6
  647. package/scripts/faiss_index.py +816 -0
  648. package/scripts/faiss_requirements.txt +3 -0
  649. package/skills/remnic-entities/SKILL.md +51 -0
  650. package/skills/remnic-memory-workflow/SKILL.md +61 -0
  651. package/skills/remnic-recall/SKILL.md +51 -0
  652. package/skills/remnic-remember/SKILL.md +56 -0
  653. package/skills/remnic-search/SKILL.md +51 -0
  654. package/skills/remnic-status/SKILL.md +51 -0
  655. package/src/abort-error.test.ts +49 -0
  656. package/src/abort-error.ts +46 -0
  657. package/src/abstraction-nodes.ts +162 -0
  658. package/src/access-audit.test.ts +178 -0
  659. package/src/access-audit.ts +125 -0
  660. package/src/access-cli.test.ts +439 -0
  661. package/src/access-cli.ts +438 -0
  662. package/src/access-http.test.ts +225 -0
  663. package/src/access-http.ts +1899 -0
  664. package/src/access-idempotency.ts +232 -0
  665. package/src/access-mcp.test.ts +568 -0
  666. package/src/access-mcp.ts +3056 -0
  667. package/src/access-schema-pi.test.ts +60 -0
  668. package/src/access-schema.ts +522 -0
  669. package/src/access-service-namespace.test.ts +123 -0
  670. package/src/access-service.ts +5629 -0
  671. package/src/action-confidence.test.ts +206 -0
  672. package/src/action-confidence.ts +466 -0
  673. package/src/active-memory-bridge.test.ts +285 -0
  674. package/src/active-memory-bridge.ts +217 -0
  675. package/src/active-recall.test.ts +484 -0
  676. package/src/active-recall.ts +459 -0
  677. package/src/adapters/claude-code.ts +56 -0
  678. package/src/adapters/codex.ts +57 -0
  679. package/src/adapters/hermes.ts +64 -0
  680. package/src/adapters/index.ts +6 -0
  681. package/src/adapters/registry.ts +41 -0
  682. package/src/adapters/replit.ts +55 -0
  683. package/src/adapters/types.ts +51 -0
  684. package/src/behavior-learner.ts +144 -0
  685. package/src/behavior-signals.ts +73 -0
  686. package/src/binary-lifecycle/backend.ts +117 -0
  687. package/src/binary-lifecycle/index.ts +35 -0
  688. package/src/binary-lifecycle/manifest.ts +79 -0
  689. package/src/binary-lifecycle/pipeline.ts +352 -0
  690. package/src/binary-lifecycle/scanner.ts +89 -0
  691. package/src/binary-lifecycle/types.ts +89 -0
  692. package/src/bootstrap.ts +178 -0
  693. package/src/boxes.ts +521 -0
  694. package/src/briefing.test.ts +1535 -0
  695. package/src/briefing.ts +1382 -0
  696. package/src/buffer-session.test.ts +443 -0
  697. package/src/buffer-surprise-report.ts +176 -0
  698. package/src/buffer-surprise-telemetry.test.ts +606 -0
  699. package/src/buffer-surprise-trigger.test.ts +766 -0
  700. package/src/buffer-surprise.test.ts +339 -0
  701. package/src/buffer-surprise.ts +203 -0
  702. package/src/buffer.ts +900 -0
  703. package/src/bulk-import/cli-command.test.ts +204 -0
  704. package/src/bulk-import/index.ts +34 -0
  705. package/src/bulk-import/pipeline.test.ts +445 -0
  706. package/src/bulk-import/pipeline.ts +178 -0
  707. package/src/bulk-import/registry.test.ts +151 -0
  708. package/src/bulk-import/registry.ts +72 -0
  709. package/src/bulk-import/types.test.ts +272 -0
  710. package/src/bulk-import/types.ts +145 -0
  711. package/src/calibration.ts +394 -0
  712. package/src/capsule-cli.test.ts +398 -0
  713. package/src/capsule-cli.ts +565 -0
  714. package/src/causal-behavior.ts +308 -0
  715. package/src/causal-chain.ts +419 -0
  716. package/src/causal-consolidation.ts +370 -0
  717. package/src/causal-retrieval.ts +286 -0
  718. package/src/causal-trajectory-graph.ts +60 -0
  719. package/src/causal-trajectory.ts +303 -0
  720. package/src/chunking.ts +220 -0
  721. package/src/citations.ts +232 -0
  722. package/src/cli.ts +9403 -0
  723. package/src/codex-cli-fallback.ts +162 -0
  724. package/src/codex-thread-key.ts +1 -0
  725. package/src/coding/access-coding-context.test.ts +197 -0
  726. package/src/coding/coding-branch-scope.test.ts +281 -0
  727. package/src/coding/coding-namespace.test.ts +360 -0
  728. package/src/coding/coding-namespace.ts +412 -0
  729. package/src/coding/coding-orchestrator.test.ts +249 -0
  730. package/src/coding/git-context.test.ts +507 -0
  731. package/src/coding/git-context.ts +336 -0
  732. package/src/coding/mcp-set-coding-context.test.ts +174 -0
  733. package/src/coding/review-context.test.ts +316 -0
  734. package/src/coding/review-context.ts +349 -0
  735. package/src/coding/wire-coding-context.test.ts +468 -0
  736. package/src/commitment-ledger.test.ts +78 -0
  737. package/src/commitment-ledger.ts +337 -0
  738. package/src/compat/checks.test.ts +206 -0
  739. package/src/compat/checks.ts +716 -0
  740. package/src/compat/types.ts +33 -0
  741. package/src/compounding/engine.ts +1686 -0
  742. package/src/compounding/preference-consolidator.ts +778 -0
  743. package/src/compression-optimizer.ts +312 -0
  744. package/src/config.test.ts +930 -0
  745. package/src/config.ts +3807 -0
  746. package/src/connectors/codex/instructions.md +160 -0
  747. package/src/connectors/codex/resources/namespace-cheatsheet.md +48 -0
  748. package/src/connectors/codex-marketplace.ts +500 -0
  749. package/src/connectors/codex-materialize-runner.ts +212 -0
  750. package/src/connectors/codex-materialize.ts +983 -0
  751. package/src/connectors/coerce.ts +62 -0
  752. package/src/connectors/index.test.ts +1570 -0
  753. package/src/connectors/index.ts +3222 -0
  754. package/src/connectors/live/framework.ts +164 -0
  755. package/src/connectors/live/github.test.ts +1218 -0
  756. package/src/connectors/live/github.ts +1068 -0
  757. package/src/connectors/live/gmail.test.ts +1706 -0
  758. package/src/connectors/live/gmail.ts +1293 -0
  759. package/src/connectors/live/google-drive.test.ts +696 -0
  760. package/src/connectors/live/google-drive.ts +724 -0
  761. package/src/connectors/live/index.ts +101 -0
  762. package/src/connectors/live/live-connectors.test.ts +689 -0
  763. package/src/connectors/live/notion.test.ts +1109 -0
  764. package/src/connectors/live/notion.ts +978 -0
  765. package/src/connectors/live/registry.ts +103 -0
  766. package/src/connectors/live/state-store.ts +399 -0
  767. package/src/connectors/live/transient-errors.ts +150 -0
  768. package/src/connectors/weclone-installer.test.ts +850 -0
  769. package/src/connectors-cli.ts +513 -0
  770. package/src/console/state.test.ts +224 -0
  771. package/src/console/state.ts +514 -0
  772. package/src/console/trace.test.ts +813 -0
  773. package/src/console/trace.ts +603 -0
  774. package/src/console/tui.test.ts +582 -0
  775. package/src/console/tui.ts +508 -0
  776. package/src/consolidation-operator.ts +182 -0
  777. package/src/consolidation-provenance-check.ts +551 -0
  778. package/src/consolidation-undo.ts +718 -0
  779. package/src/contradiction/contradiction-judge.test.ts +189 -0
  780. package/src/contradiction/contradiction-judge.ts +333 -0
  781. package/src/contradiction/contradiction-review.ts +574 -0
  782. package/src/contradiction/contradiction-scan.ts +504 -0
  783. package/src/contradiction/contradiction.test.ts +2230 -0
  784. package/src/contradiction/index.ts +37 -0
  785. package/src/contradiction/resolution.ts +383 -0
  786. package/src/conversation-index/backend.ts +323 -0
  787. package/src/conversation-index/chunker.ts +47 -0
  788. package/src/conversation-index/cleanup.ts +53 -0
  789. package/src/conversation-index/faiss-adapter.ts +384 -0
  790. package/src/conversation-index/indexer.test.ts +164 -0
  791. package/src/conversation-index/indexer.ts +192 -0
  792. package/src/conversation-index/search.ts +37 -0
  793. package/src/cross-namespace-budget.test.ts +275 -0
  794. package/src/cross-namespace-budget.ts +365 -0
  795. package/src/cue-anchors.ts +163 -0
  796. package/src/curation/index.ts +544 -0
  797. package/src/dashboard-runtime.ts +337 -0
  798. package/src/day-summary.ts +122 -0
  799. package/src/dedup/index.ts +330 -0
  800. package/src/dedup/semantic.test.ts +1577 -0
  801. package/src/dedup/semantic.ts +148 -0
  802. package/src/delinearize.ts +193 -0
  803. package/src/direct-answer-wiring.test.ts +473 -0
  804. package/src/direct-answer-wiring.ts +180 -0
  805. package/src/direct-answer.test.ts +484 -0
  806. package/src/direct-answer.ts +273 -0
  807. package/src/embedding-fallback.ts +565 -0
  808. package/src/enrichment/audit.ts +89 -0
  809. package/src/enrichment/index.ts +27 -0
  810. package/src/enrichment/pipeline.ts +197 -0
  811. package/src/enrichment/provider-registry.ts +85 -0
  812. package/src/enrichment/types.ts +100 -0
  813. package/src/enrichment/web-search-provider.ts +63 -0
  814. package/src/entity-retrieval.ts +774 -0
  815. package/src/entity-schema.ts +239 -0
  816. package/src/evals.ts +1312 -0
  817. package/src/event-order-recall.test.ts +4164 -0
  818. package/src/event-order-recall.ts +2802 -0
  819. package/src/evidence-pack.test.ts +89 -0
  820. package/src/evidence-pack.ts +388 -0
  821. package/src/explicit-capture.ts +530 -0
  822. package/src/explicit-cue-recall.test.ts +3019 -0
  823. package/src/explicit-cue-recall.ts +5545 -0
  824. package/src/extraction-judge-telemetry.ts +234 -0
  825. package/src/extraction-judge-training.ts +221 -0
  826. package/src/extraction-judge.ts +846 -0
  827. package/src/extraction-timeout.test.ts +265 -0
  828. package/src/extraction.ts +2719 -0
  829. package/src/fallback-llm.test.ts +1060 -0
  830. package/src/fallback-llm.ts +918 -0
  831. package/src/focused-list-recall.test.ts +734 -0
  832. package/src/focused-list-recall.ts +1160 -0
  833. package/src/graph-dashboard-diff.ts +35 -0
  834. package/src/graph-dashboard-key.ts +5 -0
  835. package/src/graph-dashboard-parser.ts +104 -0
  836. package/src/graph-edge-reinforcement.ts +192 -0
  837. package/src/graph-events.ts +151 -0
  838. package/src/graph-recall.test.ts +164 -0
  839. package/src/graph-recall.ts +189 -0
  840. package/src/graph-retrieval.test.ts +809 -0
  841. package/src/graph-retrieval.ts +823 -0
  842. package/src/graph-snapshot.ts +329 -0
  843. package/src/graph.ts +813 -0
  844. package/src/harmonic-retrieval.ts +223 -0
  845. package/src/himem.ts +154 -0
  846. package/src/hygiene.ts +87 -0
  847. package/src/identity-continuity.ts +333 -0
  848. package/src/importance.ts +328 -0
  849. package/src/importers/base.test.ts +294 -0
  850. package/src/importers/base.ts +436 -0
  851. package/src/importers/index.ts +21 -0
  852. package/src/index.ts +1204 -0
  853. package/src/intent.ts +154 -0
  854. package/src/json-extract.ts +85 -0
  855. package/src/json-store.ts +42 -0
  856. package/src/lcm/archive.ts +617 -0
  857. package/src/lcm/dag.ts +199 -0
  858. package/src/lcm/engine.ts +645 -0
  859. package/src/lcm/index.ts +7 -0
  860. package/src/lcm/queue.test.ts +178 -0
  861. package/src/lcm/queue.ts +200 -0
  862. package/src/lcm/recall.ts +117 -0
  863. package/src/lcm/schema.ts +154 -0
  864. package/src/lcm/summarizer.ts +235 -0
  865. package/src/lcm/tools.ts +191 -0
  866. package/src/lcm-engine.test.ts +660 -0
  867. package/src/legacy-hook-compat.test.ts +20 -0
  868. package/src/legacy-hook-compat.ts +45 -0
  869. package/src/lifecycle.ts +289 -0
  870. package/src/live-connectors-runner.ts +385 -0
  871. package/src/local-llm-qos.test.ts +303 -0
  872. package/src/local-llm-thinking.test.ts +292 -0
  873. package/src/local-llm.ts +1464 -0
  874. package/src/logger.ts +49 -0
  875. package/src/maintenance/archive-observations.ts +147 -0
  876. package/src/maintenance/backup-stamp.ts +3 -0
  877. package/src/maintenance/dreams-ledger.ts +516 -0
  878. package/src/maintenance/first-start-migration.ts +362 -0
  879. package/src/maintenance/forget.test.ts +206 -0
  880. package/src/maintenance/forget.ts +126 -0
  881. package/src/maintenance/graph-edge-decay.test.ts +409 -0
  882. package/src/maintenance/graph-edge-decay.ts +394 -0
  883. package/src/maintenance/memory-governance-cron.ts +447 -0
  884. package/src/maintenance/memory-governance.ts +1039 -0
  885. package/src/maintenance/migrate-observations.ts +216 -0
  886. package/src/maintenance/observation-ledger-utils.ts +54 -0
  887. package/src/maintenance/pattern-reinforcement.test.ts +875 -0
  888. package/src/maintenance/pattern-reinforcement.ts +369 -0
  889. package/src/maintenance/purge.ts +334 -0
  890. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +78 -0
  891. package/src/maintenance/rebuild-memory-projection.ts +1234 -0
  892. package/src/maintenance/rebuild-observations.ts +178 -0
  893. package/src/maintenance/tier-stats.test.ts +378 -0
  894. package/src/maintenance/tier-stats.ts +222 -0
  895. package/src/mcp-memory-inspector-app.ts +421 -0
  896. package/src/memory-action-policy.ts +80 -0
  897. package/src/memory-cache.ts +208 -0
  898. package/src/memory-extension/claude-code-publisher.ts +51 -0
  899. package/src/memory-extension/codex-publisher.ts +149 -0
  900. package/src/memory-extension/hermes-publisher.ts +51 -0
  901. package/src/memory-extension/index.ts +100 -0
  902. package/src/memory-extension/shared-instructions.ts +133 -0
  903. package/src/memory-extension/types.ts +86 -0
  904. package/src/memory-extension-host/host-discovery.ts +276 -0
  905. package/src/memory-extension-host/index.ts +14 -0
  906. package/src/memory-extension-host/render-extensions-block.ts +73 -0
  907. package/src/memory-extension-host/types.ts +21 -0
  908. package/src/memory-lifecycle-ledger-utils.ts +116 -0
  909. package/src/memory-projection-format.ts +11 -0
  910. package/src/memory-projection-store.ts +951 -0
  911. package/src/memory-provenance.test.ts +196 -0
  912. package/src/memory-provenance.ts +484 -0
  913. package/src/memory-worth-bench.test.ts +71 -0
  914. package/src/memory-worth-bench.ts +265 -0
  915. package/src/memory-worth-filter.test.ts +209 -0
  916. package/src/memory-worth-filter.ts +204 -0
  917. package/src/memory-worth-frontmatter.test.ts +311 -0
  918. package/src/memory-worth-outcomes.test.ts +316 -0
  919. package/src/memory-worth-outcomes.ts +286 -0
  920. package/src/memory-worth.test.ts +317 -0
  921. package/src/memory-worth.ts +215 -0
  922. package/src/message-parts/index.ts +806 -0
  923. package/src/message-parts/message-parts.test.ts +421 -0
  924. package/src/migrate/from-engram.ts +789 -0
  925. package/src/model-registry.ts +313 -0
  926. package/src/models-json.ts +76 -0
  927. package/src/namespaces/migrate.ts +187 -0
  928. package/src/namespaces/path.ts +25 -0
  929. package/src/namespaces/principal.test.ts +195 -0
  930. package/src/namespaces/principal.ts +86 -0
  931. package/src/namespaces/search.test.ts +105 -0
  932. package/src/namespaces/search.ts +233 -0
  933. package/src/namespaces/storage.ts +74 -0
  934. package/src/native-knowledge.ts +1823 -0
  935. package/src/negative.ts +72 -0
  936. package/src/network/tailscale.ts +179 -0
  937. package/src/network/webdav.ts +385 -0
  938. package/src/objective-state-writers.ts +951 -0
  939. package/src/objective-state.ts +320 -0
  940. package/src/onboarding/index.ts +529 -0
  941. package/src/openai-chat-compat.ts +56 -0
  942. package/src/operator-toolkit.ts +2132 -0
  943. package/src/opik-exporter.test.ts +72 -0
  944. package/src/opik-exporter.ts +587 -0
  945. package/src/orchestrator-extraction-queue.test.ts +197 -0
  946. package/src/orchestrator-flush.test.ts +1171 -0
  947. package/src/orchestrator-pattern-reinforcement.test.ts +128 -0
  948. package/src/orchestrator-source-attribution.test.ts +701 -0
  949. package/src/orchestrator.ts +16368 -0
  950. package/src/page-versioning.ts +450 -0
  951. package/src/patterns-cli.ts +574 -0
  952. package/src/peers/index.ts +54 -0
  953. package/src/peers/migrate-from-identity-anchor.test.ts +291 -0
  954. package/src/peers/migrate-from-identity-anchor.ts +350 -0
  955. package/src/peers/peers.test.ts +419 -0
  956. package/src/peers/profile-reasoner.ts +694 -0
  957. package/src/peers/storage.ts +1350 -0
  958. package/src/peers/types.ts +138 -0
  959. package/src/plugin-id.ts +84 -0
  960. package/src/policy-runtime.ts +209 -0
  961. package/src/procedural/procedure-miner.ts +150 -0
  962. package/src/procedural/procedure-recall.ts +93 -0
  963. package/src/procedural/procedure-stats.ts +213 -0
  964. package/src/procedural/procedure-types.ts +132 -0
  965. package/src/procedural/reinforcement-core.test.ts +132 -0
  966. package/src/procedural/reinforcement-core.ts +73 -0
  967. package/src/profiling.test.ts +263 -0
  968. package/src/profiling.ts +435 -0
  969. package/src/projection/index.ts +398 -0
  970. package/src/qmd-recall-cache.test.ts +138 -0
  971. package/src/qmd-recall-cache.ts +111 -0
  972. package/src/qmd.test.ts +258 -0
  973. package/src/qmd.ts +2614 -0
  974. package/src/reasoning-trace-recall.ts +201 -0
  975. package/src/reasoning-trace-types.ts +235 -0
  976. package/src/recall-audit-anomaly.test.ts +246 -0
  977. package/src/recall-audit-anomaly.ts +297 -0
  978. package/src/recall-audit.test.ts +51 -0
  979. package/src/recall-audit.ts +72 -0
  980. package/src/recall-budget-config.test.ts +87 -0
  981. package/src/recall-disclosure-escalation.test.ts +196 -0
  982. package/src/recall-disclosure-escalation.ts +158 -0
  983. package/src/recall-disclosure-shaping.test.ts +146 -0
  984. package/src/recall-disclosure.test.ts +214 -0
  985. package/src/recall-explain-renderer.test.ts +140 -0
  986. package/src/recall-explain-renderer.ts +356 -0
  987. package/src/recall-mmr.test.ts +808 -0
  988. package/src/recall-mmr.ts +607 -0
  989. package/src/recall-qos.test.ts +85 -0
  990. package/src/recall-qos.ts +82 -0
  991. package/src/recall-query-policy.ts +221 -0
  992. package/src/recall-state.test.ts +233 -0
  993. package/src/recall-state.ts +456 -0
  994. package/src/recall-tag-filter.ts +143 -0
  995. package/src/recall-tokenization.ts +35 -0
  996. package/src/recall-xray-cli.test.ts +118 -0
  997. package/src/recall-xray-cli.ts +100 -0
  998. package/src/recall-xray-disclosure-telemetry.test.ts +183 -0
  999. package/src/recall-xray-renderer.test.ts +539 -0
  1000. package/src/recall-xray-renderer.ts +487 -0
  1001. package/src/recall-xray.test.ts +503 -0
  1002. package/src/recall-xray.ts +621 -0
  1003. package/src/reconstruct.ts +41 -0
  1004. package/src/release-changelog.ts +35 -0
  1005. package/src/relevance.ts +67 -0
  1006. package/src/replay/normalizers/chatgpt.ts +133 -0
  1007. package/src/replay/normalizers/claude.ts +102 -0
  1008. package/src/replay/normalizers/openclaw.ts +119 -0
  1009. package/src/replay/normalizers/shared.ts +69 -0
  1010. package/src/replay/runner.ts +197 -0
  1011. package/src/replay/types.ts +143 -0
  1012. package/src/rerank.test.ts +48 -0
  1013. package/src/rerank.ts +176 -0
  1014. package/src/resolve-auth-token.test.ts +226 -0
  1015. package/src/resolve-auth-token.ts +151 -0
  1016. package/src/resolve-provider-secret.test.ts +187 -0
  1017. package/src/resolve-provider-secret.ts +410 -0
  1018. package/src/response-guidance-recall.test.ts +3952 -0
  1019. package/src/response-guidance-recall.ts +4431 -0
  1020. package/src/resume-bundles.ts +415 -0
  1021. package/src/retrieval-agents.ts +623 -0
  1022. package/src/retrieval-tiers.ts +25 -0
  1023. package/src/retrieval.ts +104 -0
  1024. package/src/review/index.test.ts +201 -0
  1025. package/src/review/index.ts +536 -0
  1026. package/src/routing/engine.ts +162 -0
  1027. package/src/routing/store.ts +321 -0
  1028. package/src/runtime/better-sqlite.test.ts +32 -0
  1029. package/src/runtime/better-sqlite.ts +76 -0
  1030. package/src/runtime/child-process.ts +67 -0
  1031. package/src/runtime/env.ts +48 -0
  1032. package/src/sanitize.ts +58 -0
  1033. package/src/schemas.ts +449 -0
  1034. package/src/sdk-compat.ts +87 -0
  1035. package/src/search/document-scanner.ts +96 -0
  1036. package/src/search/embed-helper.ts +142 -0
  1037. package/src/search/factory.ts +189 -0
  1038. package/src/search/index.ts +10 -0
  1039. package/src/search/lancedb-backend.ts +342 -0
  1040. package/src/search/meilisearch-backend.ts +232 -0
  1041. package/src/search/noop-backend.ts +57 -0
  1042. package/src/search/orama-backend.ts +358 -0
  1043. package/src/search/port.ts +86 -0
  1044. package/src/search/remote-backend.ts +124 -0
  1045. package/src/secure-store/cipher.ts +271 -0
  1046. package/src/secure-store/cli-handlers.ts +355 -0
  1047. package/src/secure-store/cli-renderer.ts +131 -0
  1048. package/src/secure-store/header.ts +373 -0
  1049. package/src/secure-store/index.ts +137 -0
  1050. package/src/secure-store/kdf.ts +263 -0
  1051. package/src/secure-store/keyring.ts +106 -0
  1052. package/src/secure-store/metadata.ts +394 -0
  1053. package/src/secure-store/passphrase-reader.ts +252 -0
  1054. package/src/secure-store/secure-fs.ts +571 -0
  1055. package/src/secure-store/secure-store.test.ts +755 -0
  1056. package/src/semantic-chunking.ts +545 -0
  1057. package/src/semantic-consolidation.test.ts +182 -0
  1058. package/src/semantic-consolidation.ts +432 -0
  1059. package/src/semantic-rule-promotion.ts +183 -0
  1060. package/src/semantic-rule-verifier.ts +160 -0
  1061. package/src/session-integrity.ts +569 -0
  1062. package/src/session-observer-bands.ts +11 -0
  1063. package/src/session-observer-state.ts +346 -0
  1064. package/src/session-toggles.test.ts +96 -0
  1065. package/src/session-toggles.ts +159 -0
  1066. package/src/shared-context/manager.ts +810 -0
  1067. package/src/signal.ts +84 -0
  1068. package/src/skills-registry.test.ts +277 -0
  1069. package/src/skills-registry.ts +120 -0
  1070. package/src/source-attribution-roundtrip.test.ts +215 -0
  1071. package/src/source-attribution.test.ts +1425 -0
  1072. package/src/source-attribution.ts +639 -0
  1073. package/src/spaces/index.ts +627 -0
  1074. package/src/storage-paths.ts +117 -0
  1075. package/src/storage.ts +6657 -0
  1076. package/src/store-contract.ts +55 -0
  1077. package/src/summarizer.ts +844 -0
  1078. package/src/summary-snapshot.test.ts +681 -0
  1079. package/src/summary-snapshot.ts +238 -0
  1080. package/src/surfaces/dreams.test.ts +394 -0
  1081. package/src/surfaces/dreams.ts +346 -0
  1082. package/src/surfaces/heartbeat.test.ts +415 -0
  1083. package/src/surfaces/heartbeat.ts +325 -0
  1084. package/src/sync/index.ts +308 -0
  1085. package/src/targeted-fact-recall.test.ts +1694 -0
  1086. package/src/targeted-fact-recall.ts +2905 -0
  1087. package/src/taxonomy/default-taxonomy.ts +87 -0
  1088. package/src/taxonomy/index.ts +26 -0
  1089. package/src/taxonomy/resolver-doc-generator.ts +57 -0
  1090. package/src/taxonomy/resolver.ts +184 -0
  1091. package/src/taxonomy/taxonomy-loader.ts +186 -0
  1092. package/src/taxonomy/types.ts +48 -0
  1093. package/src/telemetry-transcript.ts +70 -0
  1094. package/src/temporal-index.ts +890 -0
  1095. package/src/temporal-supersession.test.ts +2703 -0
  1096. package/src/temporal-supersession.ts +493 -0
  1097. package/src/temporal-validity.test.ts +448 -0
  1098. package/src/temporal-validity.ts +123 -0
  1099. package/src/threading.ts +395 -0
  1100. package/src/tier-migration.ts +124 -0
  1101. package/src/tier-routing.ts +102 -0
  1102. package/src/tmt.ts +462 -0
  1103. package/src/tokens.test.ts +178 -0
  1104. package/src/tokens.ts +279 -0
  1105. package/src/topics.ts +147 -0
  1106. package/src/training-export/cli-date-validation.test.ts +258 -0
  1107. package/src/training-export/converter.test.ts +452 -0
  1108. package/src/training-export/converter.ts +319 -0
  1109. package/src/training-export/date-parse.ts +117 -0
  1110. package/src/training-export/index.ts +26 -0
  1111. package/src/training-export/registry.test.ts +85 -0
  1112. package/src/training-export/registry.ts +57 -0
  1113. package/src/training-export/types.ts +31 -0
  1114. package/src/transcript.ts +1179 -0
  1115. package/src/transfer/autodetect.ts +30 -0
  1116. package/src/transfer/backup.ts +138 -0
  1117. package/src/transfer/capsule-crypto.ts +485 -0
  1118. package/src/transfer/capsule-encrypt.test.ts +690 -0
  1119. package/src/transfer/capsule-export.ts +543 -0
  1120. package/src/transfer/capsule-fork.ts +375 -0
  1121. package/src/transfer/capsule-import.ts +564 -0
  1122. package/src/transfer/capsule-merge.ts +433 -0
  1123. package/src/transfer/conflict-policy.ts +16 -0
  1124. package/src/transfer/constants.ts +13 -0
  1125. package/src/transfer/exclusions.ts +37 -0
  1126. package/src/transfer/export-json.ts +65 -0
  1127. package/src/transfer/export-md.ts +59 -0
  1128. package/src/transfer/export-sqlite.ts +52 -0
  1129. package/src/transfer/fs-utils.ts +269 -0
  1130. package/src/transfer/import-json.ts +108 -0
  1131. package/src/transfer/import-md.ts +84 -0
  1132. package/src/transfer/import-sqlite.ts +100 -0
  1133. package/src/transfer/integrity.ts +71 -0
  1134. package/src/transfer/sqlite-schema.ts +16 -0
  1135. package/src/transfer/types.ts +297 -0
  1136. package/src/trust-zones.ts +1186 -0
  1137. package/src/types.ts +3074 -0
  1138. package/src/user-model.test.ts +124 -0
  1139. package/src/user-model.ts +162 -0
  1140. package/src/utility-learner.ts +353 -0
  1141. package/src/utility-runtime.ts +88 -0
  1142. package/src/utility-telemetry.ts +215 -0
  1143. package/src/utils/category-dir.ts +44 -0
  1144. package/src/utils/errno.ts +6 -0
  1145. package/src/utils/iso-timestamp.test.ts +37 -0
  1146. package/src/utils/iso-timestamp.ts +164 -0
  1147. package/src/utils/path.ts +26 -0
  1148. package/src/verified-recall.ts +138 -0
  1149. package/src/version-utils.test.ts +10 -0
  1150. package/src/version-utils.ts +9 -0
  1151. package/src/whitespace.ts +10 -0
  1152. package/src/work/board.ts +359 -0
  1153. package/src/work/boundary.ts +107 -0
  1154. package/src/work/storage.ts +436 -0
  1155. package/src/work/types.ts +82 -0
  1156. package/src/work-product-ledger.ts +265 -0
  1157. package/dist/access-service-DDjzFALq.d.ts +0 -2088
  1158. package/dist/capsule-crypto-SJS5VVAP.js +0 -18
  1159. package/dist/capsule-export-7QNCBZOQ.js +0 -17
  1160. package/dist/capsule-import-EPBHD2EN.js +0 -16
  1161. package/dist/capsule-merge-DI7PNQ2H.js +0 -189
  1162. package/dist/chunk-23ZZK64Y.js +0 -26
  1163. package/dist/chunk-23ZZK64Y.js.map +0 -1
  1164. package/dist/chunk-242S3I2A.js +0 -647
  1165. package/dist/chunk-2LGMW3DJ.js +0 -111
  1166. package/dist/chunk-3B6KIRBH.js +0 -5213
  1167. package/dist/chunk-3B6KIRBH.js.map +0 -1
  1168. package/dist/chunk-457A4P3L.js +0 -119
  1169. package/dist/chunk-457A4P3L.js.map +0 -1
  1170. package/dist/chunk-4IS4SXIQ.js +0 -2040
  1171. package/dist/chunk-4YM32CRU.js +0 -721
  1172. package/dist/chunk-6TBWYBJ3.js +0 -236
  1173. package/dist/chunk-74EMIVE4.js +0 -329
  1174. package/dist/chunk-74EMIVE4.js.map +0 -1
  1175. package/dist/chunk-767ODGE6.js +0 -183
  1176. package/dist/chunk-7V22HTMD.js +0 -623
  1177. package/dist/chunk-7V22HTMD.js.map +0 -1
  1178. package/dist/chunk-7ZM3BFKK.js +0 -9705
  1179. package/dist/chunk-7ZM3BFKK.js.map +0 -1
  1180. package/dist/chunk-AQJNPMOA.js +0 -643
  1181. package/dist/chunk-AQJNPMOA.js.map +0 -1
  1182. package/dist/chunk-ASAITVLA.js +0 -64
  1183. package/dist/chunk-ASAITVLA.js.map +0 -1
  1184. package/dist/chunk-BBE34QBJ.js +0 -275
  1185. package/dist/chunk-BBE34QBJ.js.map +0 -1
  1186. package/dist/chunk-BZSQEPRW.js +0 -14710
  1187. package/dist/chunk-BZSQEPRW.js.map +0 -1
  1188. package/dist/chunk-CPKTBRS2.js +0 -891
  1189. package/dist/chunk-CPKTBRS2.js.map +0 -1
  1190. package/dist/chunk-D4GAOFF6.js +0 -562
  1191. package/dist/chunk-D4GAOFF6.js.map +0 -1
  1192. package/dist/chunk-D54LZC5L.js +0 -147
  1193. package/dist/chunk-DF3RVK3X.js +0 -119
  1194. package/dist/chunk-DF3RVK3X.js.map +0 -1
  1195. package/dist/chunk-DZZPC36E.js +0 -1451
  1196. package/dist/chunk-DZZPC36E.js.map +0 -1
  1197. package/dist/chunk-E2UCDP5S.js +0 -570
  1198. package/dist/chunk-E6K4NIEU.js +0 -747
  1199. package/dist/chunk-E6K4NIEU.js.map +0 -1
  1200. package/dist/chunk-EEQLFRUM.js +0 -89
  1201. package/dist/chunk-ETOW6ACV.js +0 -158
  1202. package/dist/chunk-ETOW6ACV.js.map +0 -1
  1203. package/dist/chunk-FMEBPEAO.js +0 -347
  1204. package/dist/chunk-FMEBPEAO.js.map +0 -1
  1205. package/dist/chunk-FQDPCE3I.js +0 -1837
  1206. package/dist/chunk-FQDPCE3I.js.map +0 -1
  1207. package/dist/chunk-FYIYMQ5N.js +0 -221
  1208. package/dist/chunk-FYIYMQ5N.js.map +0 -1
  1209. package/dist/chunk-G2WADRQ3.js +0 -219
  1210. package/dist/chunk-G4SK7DSQ.js +0 -121
  1211. package/dist/chunk-GVPWB7EY.js +0 -390
  1212. package/dist/chunk-GVPWB7EY.js.map +0 -1
  1213. package/dist/chunk-HELQZFZO.js +0 -1075
  1214. package/dist/chunk-HL5LRPNA.js +0 -1914
  1215. package/dist/chunk-HL5LRPNA.js.map +0 -1
  1216. package/dist/chunk-HQZVVSVB.js +0 -147
  1217. package/dist/chunk-HQZVVSVB.js.map +0 -1
  1218. package/dist/chunk-HY3L4WKC.js +0 -2195
  1219. package/dist/chunk-HY3L4WKC.js.map +0 -1
  1220. package/dist/chunk-IB3BFHGN.js +0 -228
  1221. package/dist/chunk-IXEJRKCZ.js +0 -18
  1222. package/dist/chunk-JBMSGZEQ.js +0 -441
  1223. package/dist/chunk-JBMSGZEQ.js.map +0 -1
  1224. package/dist/chunk-JESOB2HO.js +0 -108
  1225. package/dist/chunk-JKDVIE52.js +0 -272
  1226. package/dist/chunk-JRNQ3RNA.js +0 -284
  1227. package/dist/chunk-JRNQ3RNA.js.map +0 -1
  1228. package/dist/chunk-K6WK37A6.js +0 -865
  1229. package/dist/chunk-K6WK37A6.js.map +0 -1
  1230. package/dist/chunk-MARWOCVP.js +0 -48
  1231. package/dist/chunk-MNU6ZBWT.js +0 -4454
  1232. package/dist/chunk-MNU6ZBWT.js.map +0 -1
  1233. package/dist/chunk-N5AKDXAI.js +0 -74
  1234. package/dist/chunk-OA3L7BFR.js +0 -183
  1235. package/dist/chunk-OA3L7BFR.js.map +0 -1
  1236. package/dist/chunk-OR64ZGRZ.js +0 -23
  1237. package/dist/chunk-P77UEOU2.js +0 -1521
  1238. package/dist/chunk-P77UEOU2.js.map +0 -1
  1239. package/dist/chunk-PH4C2U43.js +0 -239
  1240. package/dist/chunk-PH4C2U43.js.map +0 -1
  1241. package/dist/chunk-RVPLBATS.js +0 -1586
  1242. package/dist/chunk-RVPLBATS.js.map +0 -1
  1243. package/dist/chunk-U5JMRGKX.js +0 -340
  1244. package/dist/chunk-U5JMRGKX.js.map +0 -1
  1245. package/dist/chunk-URB2WSKZ.js +0 -350
  1246. package/dist/chunk-URB2WSKZ.js.map +0 -1
  1247. package/dist/chunk-UVMUAWVT.js +0 -596
  1248. package/dist/chunk-WEJG4TB5.js +0 -118
  1249. package/dist/chunk-X7HPGUVG.js +0 -271
  1250. package/dist/chunk-XAMBKFQS.js +0 -2777
  1251. package/dist/chunk-XAMBKFQS.js.map +0 -1
  1252. package/dist/chunk-XJKFSSDW.js +0 -726
  1253. package/dist/chunk-XJKFSSDW.js.map +0 -1
  1254. package/dist/chunk-XMHBH5H6.js +0 -283
  1255. package/dist/chunk-XMHBH5H6.js.map +0 -1
  1256. package/dist/chunk-XMVFHBHT.js +0 -277
  1257. package/dist/chunk-Y3VMVTYX.js +0 -53
  1258. package/dist/chunk-YNB73F22.js +0 -137
  1259. package/dist/chunk-YNB73F22.js.map +0 -1
  1260. package/dist/chunk-Z2E7VW55.js +0 -335
  1261. package/dist/chunk-Z2E7VW55.js.map +0 -1
  1262. package/dist/chunk-ZG7PTKBK.js +0 -2296
  1263. package/dist/chunk-ZNQN6ZTA.js +0 -135
  1264. package/dist/chunk-ZVTKDVVM.js +0 -827
  1265. package/dist/chunk-ZVTKDVVM.js.map +0 -1
  1266. package/dist/cli-BR8KpIU0.d.ts +0 -1259
  1267. package/dist/codex-materialize-CQlLTzke.d.ts +0 -139
  1268. package/dist/connectors-cli-DFGtY2DB.d.ts +0 -257
  1269. package/dist/contradiction-review-5LTTVDQV.js +0 -22
  1270. package/dist/contradiction-scan-QTXAMBUA.js +0 -414
  1271. package/dist/contradiction-scan-QTXAMBUA.js.map +0 -1
  1272. package/dist/engine-35M5BKQ7.js +0 -28
  1273. package/dist/fs-utils-IRVUFB6G.js +0 -30
  1274. package/dist/graph-edge-decay-PWB63GRE.js +0 -207
  1275. package/dist/memory-governance-IMPQZXFC.js +0 -37
  1276. package/dist/memory-projection-store-CY8TU40w.d.ts +0 -222
  1277. package/dist/orchestrator-DDMPqU6R.d.ts +0 -1792
  1278. package/dist/path-RMTY5Y5A.js +0 -9
  1279. package/dist/port-B6VEDIkC.d.ts +0 -53
  1280. package/dist/resolution-YGIBORXI.js +0 -101
  1281. package/dist/resolution-YGIBORXI.js.map +0 -1
  1282. package/dist/secure-store-4R2GSO7S.js +0 -156
  1283. package/dist/semantic-consolidation-ByBXb-sf.d.ts +0 -180
  1284. package/dist/state-store-3EH7HYIN.js +0 -16
  1285. package/dist/types-V3FJ26TF.js +0 -30
  1286. /package/dist/{capsule-crypto-SJS5VVAP.js.map → adapters/claude-code.js.map} +0 -0
  1287. /package/dist/{capsule-export-7QNCBZOQ.js.map → adapters/codex.js.map} +0 -0
  1288. /package/dist/{capsule-import-EPBHD2EN.js.map → adapters/hermes.js.map} +0 -0
  1289. /package/dist/{contradiction-review-5LTTVDQV.js.map → adapters/index.js.map} +0 -0
  1290. /package/dist/{engine-35M5BKQ7.js.map → adapters/registry.js.map} +0 -0
  1291. /package/dist/{fs-utils-IRVUFB6G.js.map → adapters/replit.js.map} +0 -0
  1292. /package/dist/{memory-governance-IMPQZXFC.js.map → adapters/types.js.map} +0 -0
  1293. /package/dist/{path-RMTY5Y5A.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
  1294. /package/dist/{capsule-merge-DI7PNQ2H.js.map → capsule-merge-4MGKE7C5.js.map} +0 -0
  1295. /package/dist/{chunk-G4SK7DSQ.js.map → chunk-2WWLHTZY.js.map} +0 -0
  1296. /package/dist/{chunk-X7HPGUVG.js.map → chunk-4CRG46BG.js.map} +0 -0
  1297. /package/dist/{chunk-UVMUAWVT.js.map → chunk-7IASACLB.js.map} +0 -0
  1298. /package/dist/{chunk-HELQZFZO.js.map → chunk-EDTHC6UD.js.map} +0 -0
  1299. /package/dist/{chunk-4YM32CRU.js.map → chunk-EFJ3MQ4V.js.map} +0 -0
  1300. /package/dist/{chunk-E2UCDP5S.js.map → chunk-FBYESMQ2.js.map} +0 -0
  1301. /package/dist/{chunk-D54LZC5L.js.map → chunk-FDU6HUUL.js.map} +0 -0
  1302. /package/dist/{chunk-IB3BFHGN.js.map → chunk-GGKRUQOO.js.map} +0 -0
  1303. /package/dist/{chunk-242S3I2A.js.map → chunk-GL6I6MEQ.js.map} +0 -0
  1304. /package/dist/{secure-store-4R2GSO7S.js.map → chunk-HHLLAQGZ.js.map} +0 -0
  1305. /package/dist/{chunk-4IS4SXIQ.js.map → chunk-HXXBL2KD.js.map} +0 -0
  1306. /package/dist/{chunk-767ODGE6.js.map → chunk-KNKUID7G.js.map} +0 -0
  1307. /package/dist/{chunk-6TBWYBJ3.js.map → chunk-LPMVBPA3.js.map} +0 -0
  1308. /package/dist/{chunk-WEJG4TB5.js.map → chunk-MC26UJIM.js.map} +0 -0
  1309. /package/dist/{chunk-JKDVIE52.js.map → chunk-MGKYQQYF.js.map} +0 -0
  1310. /package/dist/{chunk-Y3VMVTYX.js.map → chunk-MT4HVDUZ.js.map} +0 -0
  1311. /package/dist/{chunk-G2WADRQ3.js.map → chunk-MY6TPVXW.js.map} +0 -0
  1312. /package/dist/{chunk-OR64ZGRZ.js.map → chunk-NNVTUXEB.js.map} +0 -0
  1313. /package/dist/{chunk-JESOB2HO.js.map → chunk-P4NEIHUT.js.map} +0 -0
  1314. /package/dist/{chunk-IXEJRKCZ.js.map → chunk-QRNI5JBH.js.map} +0 -0
  1315. /package/dist/{chunk-EEQLFRUM.js.map → chunk-RRF5UOBJ.js.map} +0 -0
  1316. /package/dist/{state-store-3EH7HYIN.js.map → chunk-SEDEKFYQ.js.map} +0 -0
  1317. /package/dist/{chunk-2LGMW3DJ.js.map → chunk-U3PN77QT.js.map} +0 -0
  1318. /package/dist/{chunk-XMVFHBHT.js.map → chunk-U3WSW6PZ.js.map} +0 -0
  1319. /package/dist/{chunk-N5AKDXAI.js.map → chunk-UWVJF25J.js.map} +0 -0
  1320. /package/dist/{types-V3FJ26TF.js.map → chunk-V5OCT34X.js.map} +0 -0
  1321. /package/dist/{chunk-ZG7PTKBK.js.map → chunk-W3LR522O.js.map} +0 -0
  1322. /package/dist/{chunk-MARWOCVP.js.map → chunk-XIG5PDM7.js.map} +0 -0
  1323. /package/dist/{chunk-ZNQN6ZTA.js.map → chunk-XVZ7B3HG.js.map} +0 -0
  1324. /package/dist/{graph-edge-decay-PWB63GRE.js.map → graph-edge-decay-5DI5GUNL.js.map} +0 -0
@@ -0,0 +1,1218 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import {
5
+ GITHUB_CONNECTOR_ID,
6
+ GITHUB_CURSOR_KIND,
7
+ GITHUB_DEFAULT_POLL_INTERVAL_MS,
8
+ createGitHubConnector,
9
+ isTransientGitHubError,
10
+ validateGitHubConfig,
11
+ type GitHubComment,
12
+ type GitHubFetchFn,
13
+ type GitHubSyncResult,
14
+ } from "./github.js";
15
+ import type { ConnectorCursor } from "./framework.js";
16
+
17
+ /**
18
+ * Tests for the GitHub connector (#683 PR 5/6). All GitHub API calls are
19
+ * stubbed via the `fetchFn` test hook — the suite never touches the network.
20
+ *
21
+ * Per CLAUDE.md privacy rules: no real tokens, no real usernames, no real
22
+ * repo names. All inputs are obviously synthetic.
23
+ */
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Synthetic test data
27
+ // ---------------------------------------------------------------------------
28
+
29
+ const SYNTHETIC_TOKEN = "ghp_synthetic_token_DO_NOT_USE_0000000000000000";
30
+ const SYNTHETIC_LOGIN = "synthetic-user";
31
+ const REPO_A = "synthetic-org/repo-alpha";
32
+ const REPO_B = "synthetic-org/repo-beta";
33
+
34
+ const SYNTHETIC_CONFIG = Object.freeze({
35
+ token: SYNTHETIC_TOKEN,
36
+ userLogin: SYNTHETIC_LOGIN,
37
+ repos: [REPO_A],
38
+ });
39
+
40
+ function makeComment(
41
+ id: number,
42
+ login: string,
43
+ body: string,
44
+ updatedAt: string,
45
+ htmlUrl?: string,
46
+ ): GitHubComment {
47
+ return {
48
+ id,
49
+ body,
50
+ user: { login },
51
+ created_at: updatedAt,
52
+ updated_at: updatedAt,
53
+ html_url: htmlUrl ?? `https://github.com/${REPO_A}/issues/1#issuecomment-${id}`,
54
+ };
55
+ }
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Mock fetch builder
59
+ // ---------------------------------------------------------------------------
60
+
61
+ type HandlerEntry = {
62
+ match: (url: string) => boolean;
63
+ respond: (url: string) => { status: number; data: unknown };
64
+ };
65
+
66
+ function makeFetch(handlers: HandlerEntry[]): GitHubFetchFn {
67
+ return async (url) => {
68
+ for (const handler of handlers) {
69
+ if (handler.match(url)) {
70
+ const { status, data } = handler.respond(url);
71
+ return {
72
+ ok: status >= 200 && status < 300,
73
+ status,
74
+ headers: {
75
+ get: (_name: string) => null,
76
+ },
77
+ json: async () => data,
78
+ };
79
+ }
80
+ }
81
+ throw new Error(`fetch stub: no handler for ${url}`);
82
+ };
83
+ }
84
+
85
+ /** Returns an empty array for all API calls. */
86
+ function emptyFetch(): GitHubFetchFn {
87
+ return makeFetch([
88
+ {
89
+ match: () => true,
90
+ respond: () => ({ status: 200, data: [] }),
91
+ },
92
+ ]);
93
+ }
94
+
95
+ function makeGitHubCursor(watermarks: Record<string, string>): ConnectorCursor {
96
+ return {
97
+ kind: GITHUB_CURSOR_KIND,
98
+ value: JSON.stringify({ watermarks }),
99
+ updatedAt: "2026-04-25T00:00:00.000Z",
100
+ };
101
+ }
102
+
103
+ // ---------------------------------------------------------------------------
104
+ // Config validation
105
+ // ---------------------------------------------------------------------------
106
+
107
+ test("validateGitHubConfig accepts a minimal valid config", () => {
108
+ const cfg = validateGitHubConfig({
109
+ token: SYNTHETIC_TOKEN,
110
+ userLogin: SYNTHETIC_LOGIN,
111
+ });
112
+ assert.equal(cfg.token, SYNTHETIC_TOKEN);
113
+ assert.equal(cfg.userLogin, SYNTHETIC_LOGIN);
114
+ assert.deepEqual([...cfg.repos], []);
115
+ assert.equal(cfg.pollIntervalMs, GITHUB_DEFAULT_POLL_INTERVAL_MS);
116
+ assert.equal(cfg.includeDiscussions, false);
117
+ });
118
+
119
+ test("validateGitHubConfig rejects non-object input", () => {
120
+ assert.throws(() => validateGitHubConfig(null), /must be an object/);
121
+ assert.throws(() => validateGitHubConfig([]), /must be an object/);
122
+ assert.throws(() => validateGitHubConfig("nope"), /must be an object/);
123
+ });
124
+
125
+ test("validateGitHubConfig rejects missing or empty token", () => {
126
+ assert.throws(() => validateGitHubConfig({ userLogin: SYNTHETIC_LOGIN }), /token must be a string/);
127
+ assert.throws(
128
+ () => validateGitHubConfig({ token: "", userLogin: SYNTHETIC_LOGIN }),
129
+ /token must be non-empty/,
130
+ );
131
+ assert.throws(
132
+ () => validateGitHubConfig({ token: " ", userLogin: SYNTHETIC_LOGIN }),
133
+ /token must be non-empty/,
134
+ );
135
+ });
136
+
137
+ test("validateGitHubConfig rejects missing or empty userLogin", () => {
138
+ assert.throws(
139
+ () => validateGitHubConfig({ token: SYNTHETIC_TOKEN }),
140
+ /userLogin must be a string/,
141
+ );
142
+ assert.throws(
143
+ () => validateGitHubConfig({ token: SYNTHETIC_TOKEN, userLogin: "" }),
144
+ /userLogin must be non-empty/,
145
+ );
146
+ });
147
+
148
+ test("validateGitHubConfig rejects malformed pollIntervalMs", () => {
149
+ assert.throws(
150
+ () =>
151
+ validateGitHubConfig({ token: SYNTHETIC_TOKEN, userLogin: SYNTHETIC_LOGIN, pollIntervalMs: "300000" }),
152
+ /pollIntervalMs/,
153
+ );
154
+ assert.throws(
155
+ () =>
156
+ validateGitHubConfig({ token: SYNTHETIC_TOKEN, userLogin: SYNTHETIC_LOGIN, pollIntervalMs: 50 }),
157
+ /≥1000/,
158
+ );
159
+ assert.throws(
160
+ () =>
161
+ validateGitHubConfig({
162
+ token: SYNTHETIC_TOKEN,
163
+ userLogin: SYNTHETIC_LOGIN,
164
+ pollIntervalMs: 25 * 60 * 60 * 1000,
165
+ }),
166
+ /≤/,
167
+ );
168
+ assert.throws(
169
+ () =>
170
+ validateGitHubConfig({
171
+ token: SYNTHETIC_TOKEN,
172
+ userLogin: SYNTHETIC_LOGIN,
173
+ pollIntervalMs: 3000.5,
174
+ }),
175
+ /integer/,
176
+ );
177
+ });
178
+
179
+ test("validateGitHubConfig accepts valid repos in owner/repo format", () => {
180
+ const cfg = validateGitHubConfig({
181
+ token: SYNTHETIC_TOKEN,
182
+ userLogin: SYNTHETIC_LOGIN,
183
+ repos: [REPO_A, REPO_B],
184
+ });
185
+ assert.deepEqual([...cfg.repos], [REPO_A, REPO_B]);
186
+ });
187
+
188
+ test("validateGitHubConfig rejects malformed repo slugs", () => {
189
+ assert.throws(
190
+ () =>
191
+ validateGitHubConfig({
192
+ token: SYNTHETIC_TOKEN,
193
+ userLogin: SYNTHETIC_LOGIN,
194
+ repos: ["no-slash"],
195
+ }),
196
+ /owner\/repo/,
197
+ );
198
+ assert.throws(
199
+ () =>
200
+ validateGitHubConfig({
201
+ token: SYNTHETIC_TOKEN,
202
+ userLogin: SYNTHETIC_LOGIN,
203
+ repos: ["../../../etc/passwd"],
204
+ }),
205
+ /owner\/repo/,
206
+ );
207
+ assert.throws(
208
+ () =>
209
+ validateGitHubConfig({
210
+ token: SYNTHETIC_TOKEN,
211
+ userLogin: SYNTHETIC_LOGIN,
212
+ repos: [42 as unknown as string],
213
+ }),
214
+ /repos entries must be strings/,
215
+ );
216
+ });
217
+
218
+ test("validateGitHubConfig deduplicates repos", () => {
219
+ const cfg = validateGitHubConfig({
220
+ token: SYNTHETIC_TOKEN,
221
+ userLogin: SYNTHETIC_LOGIN,
222
+ repos: [REPO_A, REPO_A, REPO_B],
223
+ });
224
+ assert.deepEqual([...cfg.repos], [REPO_A, REPO_B]);
225
+ });
226
+
227
+ test("validateGitHubConfig rejects non-boolean includeDiscussions", () => {
228
+ assert.throws(
229
+ () =>
230
+ validateGitHubConfig({
231
+ token: SYNTHETIC_TOKEN,
232
+ userLogin: SYNTHETIC_LOGIN,
233
+ includeDiscussions: "yes" as unknown as boolean,
234
+ }),
235
+ /includeDiscussions must be a boolean/,
236
+ );
237
+ });
238
+
239
+ test("validateGitHubConfig accepts includeDiscussions: true", () => {
240
+ const cfg = validateGitHubConfig({
241
+ token: SYNTHETIC_TOKEN,
242
+ userLogin: SYNTHETIC_LOGIN,
243
+ includeDiscussions: true,
244
+ });
245
+ assert.equal(cfg.includeDiscussions, true);
246
+ });
247
+
248
+ // ---------------------------------------------------------------------------
249
+ // Connector identity
250
+ // ---------------------------------------------------------------------------
251
+
252
+ test("createGitHubConnector exposes the documented id and display name", () => {
253
+ const connector = createGitHubConnector({ fetchFn: emptyFetch() });
254
+ assert.equal(connector.id, GITHUB_CONNECTOR_ID);
255
+ assert.equal(connector.id, "github");
256
+ assert.equal(connector.displayName, "GitHub");
257
+ });
258
+
259
+ // ---------------------------------------------------------------------------
260
+ // No-op when repos is empty
261
+ // ---------------------------------------------------------------------------
262
+
263
+ test("syncIncremental is a no-op when repos is empty", async () => {
264
+ let fetchCalled = false;
265
+ const fetchFn: GitHubFetchFn = async () => {
266
+ fetchCalled = true;
267
+ throw new Error("should not be called");
268
+ };
269
+ const connector = createGitHubConnector({ fetchFn });
270
+ const config = connector.validateConfig({ token: SYNTHETIC_TOKEN, userLogin: SYNTHETIC_LOGIN });
271
+
272
+ const r1 = (await connector.syncIncremental({ cursor: null, config })) as GitHubSyncResult;
273
+ assert.deepEqual(r1.newDocs, []);
274
+ assert.equal(r1.nextCursor.kind, GITHUB_CURSOR_KIND);
275
+ assert.equal(fetchCalled, false);
276
+
277
+ const r2 = (await connector.syncIncremental({
278
+ cursor: r1.nextCursor,
279
+ config,
280
+ })) as GitHubSyncResult;
281
+ assert.deepEqual(r2.newDocs, []);
282
+ assert.equal(fetchCalled, false);
283
+ });
284
+
285
+ // ---------------------------------------------------------------------------
286
+ // First-sync bootstrap
287
+ // ---------------------------------------------------------------------------
288
+
289
+ test("first sync (cursor=null) seeds watermark and returns no docs", async () => {
290
+ const comment = makeComment(1, SYNTHETIC_LOGIN, "Hello", "2026-04-25T10:00:00.000Z");
291
+
292
+ const fetchFn = makeFetch([
293
+ {
294
+ // issue comments seed
295
+ match: (url) => url.includes("/issues/comments"),
296
+ respond: () => ({ status: 200, data: [comment] }),
297
+ },
298
+ {
299
+ // PR review comments seed
300
+ match: (url) => url.includes("/pulls/comments"),
301
+ respond: () => ({ status: 200, data: [] }),
302
+ },
303
+ ]);
304
+
305
+ const connector = createGitHubConnector({ fetchFn });
306
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
307
+
308
+ const result = (await connector.syncIncremental({ cursor: null, config })) as GitHubSyncResult;
309
+ assert.deepEqual(result.newDocs, []);
310
+ assert.equal(result.nextCursor.kind, GITHUB_CURSOR_KIND);
311
+
312
+ // The cursor must record the watermark from the seeded comment.
313
+ const payload = JSON.parse(result.nextCursor.value) as { watermarks: Record<string, string> };
314
+ assert.equal(
315
+ payload.watermarks[`${REPO_A}/issue-comment`],
316
+ "2026-04-25T10:00:00.000Z",
317
+ );
318
+ });
319
+
320
+ test("first sync with empty API responses seeds empty cursor", async () => {
321
+ const connector = createGitHubConnector({ fetchFn: emptyFetch() });
322
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
323
+
324
+ const result = await connector.syncIncremental({ cursor: null, config });
325
+ assert.deepEqual(result.newDocs, []);
326
+ assert.equal(result.nextCursor.kind, GITHUB_CURSOR_KIND);
327
+ });
328
+
329
+ // ---------------------------------------------------------------------------
330
+ // Incremental sync: basic happy path
331
+ // ---------------------------------------------------------------------------
332
+
333
+ test("incremental sync emits ConnectorDocument for matching issue comments", async () => {
334
+ const comment = makeComment(
335
+ 42,
336
+ SYNTHETIC_LOGIN,
337
+ "This is my note",
338
+ "2026-04-26T09:00:00.000Z",
339
+ `https://github.com/${REPO_A}/issues/10#issuecomment-42`,
340
+ );
341
+
342
+ const fetchFn = makeFetch([
343
+ {
344
+ match: (url) => url.includes("/issues/comments"),
345
+ respond: () => ({ status: 200, data: [comment] }),
346
+ },
347
+ {
348
+ match: (url) => url.includes("/pulls/comments"),
349
+ respond: () => ({ status: 200, data: [] }),
350
+ },
351
+ ]);
352
+
353
+ const connector = createGitHubConnector({ fetchFn });
354
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
355
+ const cursor = makeGitHubCursor({
356
+ [`${REPO_A}/issue-comment`]: "2026-04-25T00:00:00.000Z",
357
+ });
358
+
359
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
360
+
361
+ assert.equal(result.newDocs.length, 1);
362
+ const doc = result.newDocs[0];
363
+ assert.equal(doc.source.connector, GITHUB_CONNECTOR_ID);
364
+ assert.equal(doc.source.externalId, `${REPO_A}/issue-comment/42`);
365
+ assert.equal(doc.source.externalRevision, "2026-04-26T09:00:00.000Z");
366
+ assert.equal(doc.source.externalUrl, `https://github.com/${REPO_A}/issues/10#issuecomment-42`);
367
+ assert.equal(doc.content, "This is my note");
368
+ assert.ok(doc.title?.includes("Issue comment"));
369
+ assert.ok(doc.title?.includes(REPO_A));
370
+ });
371
+
372
+ test("incremental sync emits ConnectorDocument for matching PR review comments", async () => {
373
+ const comment = makeComment(99, SYNTHETIC_LOGIN, "PR note here", "2026-04-26T10:00:00.000Z");
374
+
375
+ const fetchFn = makeFetch([
376
+ {
377
+ match: (url) => url.includes("/issues/comments"),
378
+ respond: () => ({ status: 200, data: [] }),
379
+ },
380
+ {
381
+ match: (url) => url.includes("/pulls/comments"),
382
+ respond: () => ({ status: 200, data: [comment] }),
383
+ },
384
+ ]);
385
+
386
+ const connector = createGitHubConnector({ fetchFn });
387
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
388
+ const cursor = makeGitHubCursor({});
389
+
390
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
391
+
392
+ assert.equal(result.newDocs.length, 1);
393
+ const doc = result.newDocs[0];
394
+ assert.equal(doc.source.externalId, `${REPO_A}/pr-review-comment/99`);
395
+ assert.ok(doc.title?.includes("PR review comment"));
396
+ });
397
+
398
+ // ---------------------------------------------------------------------------
399
+ // Author filtering
400
+ // ---------------------------------------------------------------------------
401
+
402
+ test("incremental sync skips comments authored by a different user", async () => {
403
+ const myComment = makeComment(1, SYNTHETIC_LOGIN, "Mine", "2026-04-26T09:00:00.000Z");
404
+ const otherComment = makeComment(2, "other-user", "Not mine", "2026-04-26T09:01:00.000Z");
405
+
406
+ const fetchFn = makeFetch([
407
+ {
408
+ match: (url) => url.includes("/issues/comments"),
409
+ respond: () => ({ status: 200, data: [myComment, otherComment] }),
410
+ },
411
+ {
412
+ match: (url) => url.includes("/pulls/comments"),
413
+ respond: () => ({ status: 200, data: [] }),
414
+ },
415
+ ]);
416
+
417
+ const connector = createGitHubConnector({ fetchFn });
418
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
419
+ const cursor = makeGitHubCursor({});
420
+
421
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
422
+
423
+ assert.equal(result.newDocs.length, 1);
424
+ assert.equal(result.newDocs[0].source.externalId, `${REPO_A}/issue-comment/1`);
425
+ assert.equal(result.skippedOtherAuthor, 1);
426
+ });
427
+
428
+ // ---------------------------------------------------------------------------
429
+ // Empty / too-large bodies
430
+ // ---------------------------------------------------------------------------
431
+
432
+ test("incremental sync skips comments with empty body", async () => {
433
+ const emptyComment = makeComment(5, SYNTHETIC_LOGIN, "", "2026-04-26T09:00:00.000Z");
434
+ const whitespaceComment = makeComment(6, SYNTHETIC_LOGIN, " \n\t ", "2026-04-26T09:01:00.000Z");
435
+
436
+ const fetchFn = makeFetch([
437
+ {
438
+ match: (url) => url.includes("/issues/comments"),
439
+ respond: () => ({ status: 200, data: [emptyComment, whitespaceComment] }),
440
+ },
441
+ {
442
+ match: (url) => url.includes("/pulls/comments"),
443
+ respond: () => ({ status: 200, data: [] }),
444
+ },
445
+ ]);
446
+
447
+ const connector = createGitHubConnector({ fetchFn });
448
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
449
+ const cursor = makeGitHubCursor({});
450
+
451
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
452
+ assert.deepEqual(result.newDocs, []);
453
+ assert.equal(result.skippedEmpty, 2);
454
+ });
455
+
456
+ // ---------------------------------------------------------------------------
457
+ // Watermark advancement
458
+ // ---------------------------------------------------------------------------
459
+
460
+ test("incremental sync advances watermark after importing comments", async () => {
461
+ const c1 = makeComment(10, SYNTHETIC_LOGIN, "first", "2026-04-26T09:00:00.000Z");
462
+ const c2 = makeComment(11, SYNTHETIC_LOGIN, "second", "2026-04-26T10:00:00.000Z");
463
+
464
+ const fetchFn = makeFetch([
465
+ {
466
+ match: (url) => url.includes("/issues/comments"),
467
+ respond: () => ({ status: 200, data: [c1, c2] }),
468
+ },
469
+ {
470
+ match: (url) => url.includes("/pulls/comments"),
471
+ respond: () => ({ status: 200, data: [] }),
472
+ },
473
+ ]);
474
+
475
+ const connector = createGitHubConnector({ fetchFn });
476
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
477
+ const cursor = makeGitHubCursor({
478
+ [`${REPO_A}/issue-comment`]: "2026-04-25T00:00:00.000Z",
479
+ });
480
+
481
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
482
+ assert.equal(result.newDocs.length, 2);
483
+
484
+ const payload = JSON.parse(result.nextCursor.value) as { watermarks: Record<string, string> };
485
+ // Watermark must advance to the latest comment's updated_at.
486
+ assert.equal(payload.watermarks[`${REPO_A}/issue-comment`], "2026-04-26T10:00:00.000Z");
487
+ });
488
+
489
+ test("incremental sync skips items strictly before the watermark", async () => {
490
+ // Only comments whose updated_at is STRICTLY before the watermark are
491
+ // dropped by the filter. A comment AT the watermark second passes through
492
+ // to the seenIds check (and, if not in seenIds, is ingested). A comment
493
+ // one second after the watermark is always ingested.
494
+ //
495
+ // "beforeComment" has a timestamp 1 second before the watermark → skipped.
496
+ // "atComment" is AT the watermark second and NOT in seenIds → ingested.
497
+ // "afterComment" is after the watermark → ingested.
498
+ const watermark = "2026-04-25T00:00:01.000Z";
499
+ const beforeComment = makeComment(1, SYNTHETIC_LOGIN, "before", "2026-04-25T00:00:00.000Z");
500
+ const atComment = makeComment(2, SYNTHETIC_LOGIN, "at watermark", watermark);
501
+ const afterComment = makeComment(3, SYNTHETIC_LOGIN, "after", "2026-04-25T00:00:02.000Z");
502
+
503
+ const fetchFn = makeFetch([
504
+ {
505
+ match: (url) => url.includes("/issues/comments"),
506
+ respond: () => ({ status: 200, data: [beforeComment, atComment, afterComment] }),
507
+ },
508
+ {
509
+ match: (url) => url.includes("/pulls/comments"),
510
+ respond: () => ({ status: 200, data: [] }),
511
+ },
512
+ ]);
513
+
514
+ const connector = createGitHubConnector({ fetchFn });
515
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
516
+ // Cursor watermark at exactly the "at" second; seenIds is empty.
517
+ const cursor: import("./framework.js").ConnectorCursor = {
518
+ kind: GITHUB_CURSOR_KIND,
519
+ value: JSON.stringify({
520
+ watermarks: { [`${REPO_A}/issue-comment`]: watermark },
521
+ seenIds: {},
522
+ }),
523
+ updatedAt: watermark,
524
+ };
525
+
526
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
527
+ // beforeComment is strictly before the watermark → skipped.
528
+ // atComment is AT the watermark and not in seenIds → ingested.
529
+ // afterComment is after the watermark → ingested.
530
+ assert.equal(result.newDocs.length, 2);
531
+ const ids = result.newDocs.map((d) => d.source.externalId);
532
+ assert.ok(ids.includes(`${REPO_A}/issue-comment/2`), "atComment must be ingested");
533
+ assert.ok(ids.includes(`${REPO_A}/issue-comment/3`), "afterComment must be ingested");
534
+ });
535
+
536
+ // ---------------------------------------------------------------------------
537
+ // Multiple repos
538
+ // ---------------------------------------------------------------------------
539
+
540
+ test("incremental sync handles multiple repos independently", async () => {
541
+ const commentA = makeComment(1, SYNTHETIC_LOGIN, "In A", "2026-04-26T09:00:00.000Z");
542
+ const commentB = makeComment(2, SYNTHETIC_LOGIN, "In B", "2026-04-26T09:00:00.000Z");
543
+
544
+ const fetchFn = makeFetch([
545
+ {
546
+ match: (url) => url.includes(`${REPO_A}/issues/comments`),
547
+ respond: () => ({ status: 200, data: [commentA] }),
548
+ },
549
+ {
550
+ match: (url) => url.includes(`${REPO_B}/issues/comments`),
551
+ respond: () => ({ status: 200, data: [commentB] }),
552
+ },
553
+ {
554
+ match: (url) => url.includes("/pulls/comments"),
555
+ respond: () => ({ status: 200, data: [] }),
556
+ },
557
+ ]);
558
+
559
+ const connector = createGitHubConnector({ fetchFn });
560
+ const config = connector.validateConfig({
561
+ token: SYNTHETIC_TOKEN,
562
+ userLogin: SYNTHETIC_LOGIN,
563
+ repos: [REPO_A, REPO_B],
564
+ });
565
+ const cursor = makeGitHubCursor({});
566
+
567
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
568
+ assert.equal(result.newDocs.length, 2);
569
+ const ids = result.newDocs.map((d) => d.source.externalId).sort();
570
+ assert.deepEqual(ids, [
571
+ `${REPO_A}/issue-comment/1`,
572
+ `${REPO_B}/issue-comment/2`,
573
+ ].sort());
574
+ });
575
+
576
+ // ---------------------------------------------------------------------------
577
+ // Discussion comments (opt-in)
578
+ // ---------------------------------------------------------------------------
579
+
580
+ test("discussion comments are not fetched unless includeDiscussions is true", async () => {
581
+ let discussionFetched = false;
582
+ const fetchFn = makeFetch([
583
+ {
584
+ match: (url) => url.includes("/discussions"),
585
+ respond: () => {
586
+ discussionFetched = true;
587
+ return { status: 200, data: [] };
588
+ },
589
+ },
590
+ {
591
+ match: () => true,
592
+ respond: () => ({ status: 200, data: [] }),
593
+ },
594
+ ]);
595
+
596
+ const connector = createGitHubConnector({ fetchFn });
597
+ const config = connector.validateConfig({
598
+ ...SYNTHETIC_CONFIG,
599
+ includeDiscussions: false,
600
+ });
601
+ const cursor = makeGitHubCursor({});
602
+
603
+ await connector.syncIncremental({ cursor, config });
604
+ assert.equal(discussionFetched, false);
605
+ });
606
+
607
+ test("discussion comments are fetched when includeDiscussions is true", async () => {
608
+ let discussionFetched = false;
609
+ const fetchFn = makeFetch([
610
+ {
611
+ match: (url) => url.includes("/discussions"),
612
+ respond: () => {
613
+ discussionFetched = true;
614
+ return { status: 200, data: [] };
615
+ },
616
+ },
617
+ {
618
+ match: () => true,
619
+ respond: () => ({ status: 200, data: [] }),
620
+ },
621
+ ]);
622
+
623
+ const connector = createGitHubConnector({ fetchFn });
624
+ const config = connector.validateConfig({
625
+ ...SYNTHETIC_CONFIG,
626
+ includeDiscussions: true,
627
+ });
628
+ const cursor = makeGitHubCursor({});
629
+
630
+ await connector.syncIncremental({ cursor, config });
631
+ assert.equal(discussionFetched, true);
632
+ });
633
+
634
+ // ---------------------------------------------------------------------------
635
+ // Error classification
636
+ // ---------------------------------------------------------------------------
637
+
638
+ test("isTransientGitHubError classifies common error shapes", () => {
639
+ // Terminal — skip-and-continue.
640
+ assert.equal(isTransientGitHubError({ githubStatus: 404 }), false);
641
+ assert.equal(isTransientGitHubError({ githubStatus: 403 }), false);
642
+ assert.equal(isTransientGitHubError({ githubStatus: 400 }), false);
643
+ assert.equal(isTransientGitHubError({ status: 410 }), false);
644
+ // Transient — re-throw.
645
+ assert.equal(isTransientGitHubError({ githubStatus: 429 }), true);
646
+ assert.equal(isTransientGitHubError({ githubStatus: 500 }), true);
647
+ assert.equal(isTransientGitHubError({ githubStatus: 503 }), true);
648
+ assert.equal(isTransientGitHubError({ status: 504 }), true);
649
+ // Network errors.
650
+ assert.equal(isTransientGitHubError({ code: "ECONNRESET" }), true);
651
+ assert.equal(isTransientGitHubError({ code: "ETIMEDOUT" }), true);
652
+ assert.equal(isTransientGitHubError({ code: "ENOTFOUND" }), true);
653
+ assert.equal(isTransientGitHubError({ code: "EAI_AGAIN" }), true);
654
+ // AbortError.
655
+ assert.equal(isTransientGitHubError({ name: "AbortError" }), true);
656
+ // Bare Error with no metadata — conservatively transient.
657
+ assert.equal(isTransientGitHubError(new Error("unknown")), true);
658
+ // Non-objects.
659
+ assert.equal(isTransientGitHubError(null), false);
660
+ assert.equal(isTransientGitHubError(undefined), false);
661
+ assert.equal(isTransientGitHubError("oops"), false);
662
+ });
663
+
664
+ // ---------------------------------------------------------------------------
665
+ // HTTP error handling
666
+ // ---------------------------------------------------------------------------
667
+
668
+ test("a 429 on issue comments re-throws (transient) and cursor does NOT advance", async () => {
669
+ const fetchFn = makeFetch([
670
+ {
671
+ match: (url) => url.includes("/issues/comments"),
672
+ respond: () => ({
673
+ status: 429,
674
+ data: { message: "API rate limit exceeded" },
675
+ }),
676
+ },
677
+ ]);
678
+
679
+ const connector = createGitHubConnector({ fetchFn });
680
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
681
+ const cursor = makeGitHubCursor({
682
+ [`${REPO_A}/issue-comment`]: "2026-04-25T00:00:00.000Z",
683
+ });
684
+
685
+ await assert.rejects(
686
+ connector.syncIncremental({ cursor, config }),
687
+ /rate limit/i,
688
+ );
689
+ });
690
+
691
+ test("a 503 on issue comments re-throws (transient)", async () => {
692
+ const fetchFn = makeFetch([
693
+ {
694
+ match: (url) => url.includes("/issues/comments"),
695
+ respond: () => ({
696
+ status: 503,
697
+ data: { message: "Service Unavailable" },
698
+ }),
699
+ },
700
+ ]);
701
+
702
+ const connector = createGitHubConnector({ fetchFn });
703
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
704
+ const cursor = makeGitHubCursor({});
705
+
706
+ await assert.rejects(
707
+ connector.syncIncremental({ cursor, config }),
708
+ /503/,
709
+ );
710
+ });
711
+
712
+ test("a 404 on issue comments is terminal (skip repo resource, continue)", async () => {
713
+ // Issue comments returns 404 → skipped.
714
+ // PR review comments returns a valid comment → should still be imported.
715
+ const prComment = makeComment(77, SYNTHETIC_LOGIN, "PR note", "2026-04-26T09:00:00.000Z");
716
+
717
+ const fetchFn = makeFetch([
718
+ {
719
+ match: (url) => url.includes("/issues/comments"),
720
+ respond: () => ({
721
+ status: 404,
722
+ data: { message: "Not Found" },
723
+ }),
724
+ },
725
+ {
726
+ match: (url) => url.includes("/pulls/comments"),
727
+ respond: () => ({ status: 200, data: [prComment] }),
728
+ },
729
+ ]);
730
+
731
+ const connector = createGitHubConnector({ fetchFn });
732
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
733
+ const cursor = makeGitHubCursor({});
734
+
735
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
736
+ // The 404 should be swallowed (terminal), and the PR comment should be imported.
737
+ assert.equal(result.newDocs.length, 1);
738
+ assert.equal(result.newDocs[0].source.externalId, `${REPO_A}/pr-review-comment/77`);
739
+ });
740
+
741
+ test("a 403 on issue comments is terminal (skip, continue to PR comments)", async () => {
742
+ const prComment = makeComment(88, SYNTHETIC_LOGIN, "Another PR note", "2026-04-26T09:00:00.000Z");
743
+
744
+ const fetchFn = makeFetch([
745
+ {
746
+ match: (url) => url.includes("/issues/comments"),
747
+ respond: () => ({
748
+ status: 403,
749
+ data: { message: "Forbidden" },
750
+ }),
751
+ },
752
+ {
753
+ match: (url) => url.includes("/pulls/comments"),
754
+ respond: () => ({ status: 200, data: [prComment] }),
755
+ },
756
+ ]);
757
+
758
+ const connector = createGitHubConnector({ fetchFn });
759
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
760
+ const cursor = makeGitHubCursor({});
761
+
762
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
763
+ assert.equal(result.newDocs.length, 1);
764
+ });
765
+
766
+ // ---------------------------------------------------------------------------
767
+ // AbortSignal
768
+ // ---------------------------------------------------------------------------
769
+
770
+ test("syncIncremental honors abortSignal", async () => {
771
+ const controller = new AbortController();
772
+ let callCount = 0;
773
+
774
+ const fetchFn: GitHubFetchFn = async () => {
775
+ callCount++;
776
+ if (callCount === 1) controller.abort();
777
+ return {
778
+ ok: true,
779
+ status: 200,
780
+ headers: { get: () => null },
781
+ json: async () => [],
782
+ };
783
+ };
784
+
785
+ const connector = createGitHubConnector({ fetchFn });
786
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
787
+ const cursor = makeGitHubCursor({});
788
+
789
+ await assert.rejects(
790
+ connector.syncIncremental({ cursor, config, abortSignal: controller.signal }),
791
+ /aborted/,
792
+ );
793
+ });
794
+
795
+ // ---------------------------------------------------------------------------
796
+ // Cursor validation
797
+ // ---------------------------------------------------------------------------
798
+
799
+ test("syncIncremental rejects a cursor of an unexpected kind", async () => {
800
+ const connector = createGitHubConnector({ fetchFn: emptyFetch() });
801
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
802
+ const badCursor: ConnectorCursor = {
803
+ kind: "wrong-kind",
804
+ value: "{}",
805
+ updatedAt: "2026-04-25T00:00:00.000Z",
806
+ };
807
+
808
+ await assert.rejects(
809
+ connector.syncIncremental({ cursor: badCursor, config }),
810
+ /unexpected cursor kind/,
811
+ );
812
+ });
813
+
814
+ test("syncIncremental rejects a cursor with invalid JSON", async () => {
815
+ const connector = createGitHubConnector({ fetchFn: emptyFetch() });
816
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
817
+ const badCursor: ConnectorCursor = {
818
+ kind: GITHUB_CURSOR_KIND,
819
+ value: "{ not valid json",
820
+ updatedAt: "2026-04-25T00:00:00.000Z",
821
+ };
822
+
823
+ await assert.rejects(
824
+ connector.syncIncremental({ cursor: badCursor, config }),
825
+ /not valid JSON/,
826
+ );
827
+ });
828
+
829
+ test("validateConfig is enforced again on every sync pass", async () => {
830
+ const connector = createGitHubConnector({ fetchFn: emptyFetch() });
831
+ const badConfig = { token: SYNTHETIC_TOKEN } as unknown as import("./framework.js").ConnectorConfig;
832
+ const cursor = makeGitHubCursor({});
833
+
834
+ await assert.rejects(
835
+ connector.syncIncremental({ cursor, config: badConfig }),
836
+ /userLogin/,
837
+ );
838
+ });
839
+
840
+ // ---------------------------------------------------------------------------
841
+ // Network-layer transient error
842
+ // ---------------------------------------------------------------------------
843
+
844
+ test("a network ECONNRESET on issue comments re-throws as transient", async () => {
845
+ const fetchFn: GitHubFetchFn = async () => {
846
+ throw Object.assign(new Error("socket hang up"), { code: "ECONNRESET" });
847
+ };
848
+
849
+ const connector = createGitHubConnector({ fetchFn });
850
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
851
+ const cursor = makeGitHubCursor({});
852
+
853
+ await assert.rejects(
854
+ connector.syncIncremental({ cursor, config }),
855
+ /socket hang up/,
856
+ );
857
+ });
858
+
859
+ // ---------------------------------------------------------------------------
860
+ // Non-matching author watermark advancement (CLAUDE.md gotcha #44 regression)
861
+ // ---------------------------------------------------------------------------
862
+
863
+ test("watermark advances for non-matching-author and empty comments so they aren't re-fetched", async () => {
864
+ // A comment from a different user. The watermark must still advance so we
865
+ // don't fetch the same item on every subsequent poll.
866
+ const otherComment = makeComment(200, "other-user", "Not mine", "2026-04-26T09:00:00.000Z");
867
+
868
+ const fetchFn = makeFetch([
869
+ {
870
+ match: (url) => url.includes("/issues/comments"),
871
+ respond: () => ({ status: 200, data: [otherComment] }),
872
+ },
873
+ {
874
+ match: (url) => url.includes("/pulls/comments"),
875
+ respond: () => ({ status: 200, data: [] }),
876
+ },
877
+ ]);
878
+
879
+ const connector = createGitHubConnector({ fetchFn });
880
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
881
+ const cursor = makeGitHubCursor({});
882
+
883
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
884
+ assert.deepEqual(result.newDocs, []);
885
+ assert.equal(result.skippedOtherAuthor, 1);
886
+
887
+ // The watermark must have advanced past the other-author comment so the
888
+ // next incremental pass skips it via the `since` filter.
889
+ const payload = JSON.parse(result.nextCursor.value) as { watermarks: Record<string, string> };
890
+ assert.equal(payload.watermarks[`${REPO_A}/issue-comment`], "2026-04-26T09:00:00.000Z");
891
+ });
892
+
893
+ // ---------------------------------------------------------------------------
894
+ // P1 fix: Same-timestamp dedup via seenIds (PRRT_kwDORJXyws59sfBq)
895
+ // ---------------------------------------------------------------------------
896
+
897
+ test("seenIds are stored in cursor for ingested comments at the watermark second", async () => {
898
+ // Two comments with the same second-level timestamp. Both are new (above watermark).
899
+ const c1 = makeComment(10, SYNTHETIC_LOGIN, "first comment", "2026-04-26T10:00:00.000Z");
900
+ const c2 = makeComment(11, SYNTHETIC_LOGIN, "second comment", "2026-04-26T10:00:00.500Z");
901
+
902
+ const fetchFn = makeFetch([
903
+ {
904
+ match: (url) => url.includes("/issues/comments"),
905
+ respond: () => ({ status: 200, data: [c1, c2] }),
906
+ },
907
+ {
908
+ match: (url) => url.includes("/pulls/comments"),
909
+ respond: () => ({ status: 200, data: [] }),
910
+ },
911
+ ]);
912
+
913
+ const connector = createGitHubConnector({ fetchFn });
914
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
915
+ const cursor = makeGitHubCursor({
916
+ [`${REPO_A}/issue-comment`]: "2026-04-26T09:00:00.000Z",
917
+ });
918
+
919
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
920
+ assert.equal(result.newDocs.length, 2);
921
+
922
+ const payload = JSON.parse(result.nextCursor.value) as {
923
+ watermarks: Record<string, string>;
924
+ seenIds: Record<string, string>;
925
+ };
926
+ // seenIds must contain both ingested comment ids.
927
+ assert.ok(
928
+ `${REPO_A}/issue-comment/10` in payload.seenIds,
929
+ "seenIds must include comment 10",
930
+ );
931
+ assert.ok(
932
+ `${REPO_A}/issue-comment/11` in payload.seenIds,
933
+ "seenIds must include comment 11",
934
+ );
935
+ });
936
+
937
+ test("seenIds prevent re-importing same-second comments on the next poll", async () => {
938
+ // Scenario: c1 was ingested on the previous pass and is recorded in seenIds.
939
+ // On this poll GitHub re-returns it (inclusive `since=` at the watermark
940
+ // second). It must be skipped without emitting a new document.
941
+ const ts = "2026-04-26T10:00:00.000Z";
942
+ const c1 = makeComment(10, SYNTHETIC_LOGIN, "already imported", ts);
943
+ const c2 = makeComment(12, SYNTHETIC_LOGIN, "new this poll", "2026-04-26T10:00:01.000Z");
944
+
945
+ const fetchFn = makeFetch([
946
+ {
947
+ match: (url) => url.includes("/issues/comments"),
948
+ respond: () => ({ status: 200, data: [c1, c2] }),
949
+ },
950
+ {
951
+ match: (url) => url.includes("/pulls/comments"),
952
+ respond: () => ({ status: 200, data: [] }),
953
+ },
954
+ ]);
955
+
956
+ const connector = createGitHubConnector({ fetchFn });
957
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
958
+ // Cursor encodes the watermark at c1's timestamp AND c1 already in seenIds.
959
+ const cursor: import("./framework.js").ConnectorCursor = {
960
+ kind: GITHUB_CURSOR_KIND,
961
+ value: JSON.stringify({
962
+ watermarks: { [`${REPO_A}/issue-comment`]: ts },
963
+ seenIds: { [`${REPO_A}/issue-comment/10`]: ts },
964
+ }),
965
+ updatedAt: "2026-04-26T10:00:00.000Z",
966
+ };
967
+
968
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
969
+ // c1 must be skipped (in seenIds); only c2 should be imported.
970
+ assert.equal(result.newDocs.length, 1);
971
+ assert.equal(result.newDocs[0].source.externalId, `${REPO_A}/issue-comment/12`);
972
+ });
973
+
974
+ test("seenIds are cleared when the watermark advances past a second boundary", async () => {
975
+ // Previous cursor has seenIds entries at the old second.
976
+ // After ingesting c2 which is in a new second, seenIds must be cleared.
977
+ const oldTs = "2026-04-26T10:00:00.000Z";
978
+ const newTs = "2026-04-26T10:00:01.000Z";
979
+ const c1Old = makeComment(10, SYNTHETIC_LOGIN, "old second item", oldTs);
980
+ const c2New = makeComment(20, SYNTHETIC_LOGIN, "new second item", newTs);
981
+
982
+ const fetchFn = makeFetch([
983
+ {
984
+ match: (url) => url.includes("/issues/comments"),
985
+ respond: () => ({ status: 200, data: [c1Old, c2New] }),
986
+ },
987
+ {
988
+ match: (url) => url.includes("/pulls/comments"),
989
+ respond: () => ({ status: 200, data: [] }),
990
+ },
991
+ ]);
992
+
993
+ const connector = createGitHubConnector({ fetchFn });
994
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
995
+ // Cursor: watermark is at oldTs, seenIds contains c1Old's id.
996
+ const cursor: import("./framework.js").ConnectorCursor = {
997
+ kind: GITHUB_CURSOR_KIND,
998
+ value: JSON.stringify({
999
+ watermarks: { [`${REPO_A}/issue-comment`]: oldTs },
1000
+ seenIds: { [`${REPO_A}/issue-comment/10`]: oldTs },
1001
+ }),
1002
+ updatedAt: oldTs,
1003
+ };
1004
+
1005
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
1006
+ // c1Old is in seenIds → skipped. c2New (above watermark) → imported.
1007
+ assert.equal(result.newDocs.length, 1);
1008
+ assert.equal(result.newDocs[0].source.externalId, `${REPO_A}/issue-comment/20`);
1009
+
1010
+ const payload = JSON.parse(result.nextCursor.value) as {
1011
+ watermarks: Record<string, string>;
1012
+ seenIds: Record<string, string>;
1013
+ };
1014
+ // Watermark must have advanced to the new second.
1015
+ assert.equal(payload.watermarks[`${REPO_A}/issue-comment`], newTs);
1016
+ // seenIds for c1Old must be cleared (watermark crossed the second boundary).
1017
+ assert.ok(
1018
+ !(`${REPO_A}/issue-comment/10` in payload.seenIds),
1019
+ "stale seenId from old second must be cleared",
1020
+ );
1021
+ // c2New must be in the fresh seenIds.
1022
+ assert.ok(
1023
+ `${REPO_A}/issue-comment/20` in payload.seenIds,
1024
+ "new-second comment must be in seenIds",
1025
+ );
1026
+ });
1027
+
1028
+ // ---------------------------------------------------------------------------
1029
+ // P1 fix: Skip-aware budget — skipped records don't consume the cap
1030
+ // (PRRT_kwDORJXyws59sfBs)
1031
+ // ---------------------------------------------------------------------------
1032
+
1033
+ test("skipped (wrong-author) records do not consume the per-pass budget", async () => {
1034
+ // Build MAX_ITEMS_PER_PASS wrong-author comments followed by one valid one.
1035
+ // The budget should NOT be exhausted by the skipped ones, so the valid
1036
+ // comment at the end must still be ingested.
1037
+ const MAX = 200; // matches MAX_ITEMS_PER_PASS constant
1038
+ const skippedComments = Array.from({ length: MAX }, (_, i) =>
1039
+ makeComment(1000 + i, "other-user", `not mine ${i}`, `2026-04-26T09:00:${String(i).padStart(2, "0")}.000Z`),
1040
+ );
1041
+ const validComment = makeComment(9999, SYNTHETIC_LOGIN, "mine", "2026-04-26T09:05:00.000Z");
1042
+
1043
+ // All comments returned on first page (we return MAX+1 items so pagination
1044
+ // doesn't trigger — but since GITHUB_PAGE_SIZE=100 we need to simulate
1045
+ // multiple pages). Simpler: just return one page with all items (>100),
1046
+ // but since the page-size check caps at 100 we'll use a single page of
1047
+ // exactly the right set. Instead use a simpler approach: return the skipped
1048
+ // comments as 2 pages of 100, then the valid comment on a "short" 3rd page.
1049
+ let callCount = 0;
1050
+ const issuePages: (typeof skippedComments)[] = [
1051
+ skippedComments.slice(0, 100),
1052
+ skippedComments.slice(100, 200),
1053
+ [validComment],
1054
+ ];
1055
+
1056
+ const fetchFn = makeFetch([
1057
+ {
1058
+ match: (url) => url.includes("/issues/comments"),
1059
+ respond: () => {
1060
+ const page = issuePages[callCount] ?? [];
1061
+ callCount++;
1062
+ return { status: 200, data: page };
1063
+ },
1064
+ },
1065
+ {
1066
+ match: (url) => url.includes("/pulls/comments"),
1067
+ respond: () => ({ status: 200, data: [] }),
1068
+ },
1069
+ ]);
1070
+
1071
+ const connector = createGitHubConnector({ fetchFn });
1072
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
1073
+ const cursor = makeGitHubCursor({});
1074
+
1075
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
1076
+
1077
+ // The valid comment must be imported despite all the skipped ones.
1078
+ assert.equal(
1079
+ result.newDocs.length,
1080
+ 1,
1081
+ "the valid comment must not be starved by budget-consuming skipped items",
1082
+ );
1083
+ assert.equal(result.newDocs[0].source.externalId, `${REPO_A}/issue-comment/9999`);
1084
+ assert.equal(result.skippedOtherAuthor, MAX);
1085
+ });
1086
+
1087
+ test("skipped (empty-body) records do not consume the per-pass budget", async () => {
1088
+ // 5 empty-body comments followed by 3 valid ones within a budget of 3.
1089
+ const emptyComments = Array.from({ length: 5 }, (_, i) =>
1090
+ makeComment(200 + i, SYNTHETIC_LOGIN, "", `2026-04-26T09:00:0${i}.000Z`),
1091
+ );
1092
+ const validComments = Array.from({ length: 3 }, (_, i) =>
1093
+ makeComment(300 + i, SYNTHETIC_LOGIN, `valid ${i}`, `2026-04-26T09:01:0${i}.000Z`),
1094
+ );
1095
+
1096
+ const fetchFn = makeFetch([
1097
+ {
1098
+ match: (url) => url.includes("/issues/comments"),
1099
+ respond: () => ({ status: 200, data: [...emptyComments, ...validComments] }),
1100
+ },
1101
+ {
1102
+ match: (url) => url.includes("/pulls/comments"),
1103
+ respond: () => ({ status: 200, data: [] }),
1104
+ },
1105
+ ]);
1106
+
1107
+ const connector = createGitHubConnector({ fetchFn });
1108
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
1109
+ const cursor = makeGitHubCursor({});
1110
+
1111
+ // Use a budget of 3. With the old (buggy) code, the 5 empty comments would
1112
+ // exhaust the budget before reaching the valid ones.
1113
+ // We can't set MAX_ITEMS_PER_PASS directly; instead verify that with the
1114
+ // default budget all 3 valid comments are imported.
1115
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
1116
+
1117
+ assert.equal(result.newDocs.length, 3, "all 3 valid comments must be imported");
1118
+ assert.equal(result.skippedEmpty, 5);
1119
+ });
1120
+
1121
+ // ---------------------------------------------------------------------------
1122
+ // Regression: strict watermark filter (<, not <=) + timestamp-gated seenIds
1123
+ // Fixes: Cursor High finding (watermark boundary), Codex P1 finding (seenIds).
1124
+ // ---------------------------------------------------------------------------
1125
+
1126
+ test("watermark uses strict < so boundary-second comments pass through to seenIds", async () => {
1127
+ // Scenario: The cursor watermark is set to T. On the next poll GitHub's
1128
+ // `since=T` filter re-returns any comment whose updated_at equals T
1129
+ // (GitHub's `since` parameter is inclusive). With the old `<=` filter these
1130
+ // were silently dropped before seenIds could distinguish them. This test
1131
+ // verifies the `<` fix: a comment AT exactly the watermark second that is
1132
+ // NOT in seenIds must be ingested.
1133
+ const ts = "2026-04-26T12:00:00.000Z";
1134
+ // commentAtTs is at the exact watermark second but was NOT ingested before.
1135
+ const commentAtTs = makeComment(42, SYNTHETIC_LOGIN, "exactly at watermark", ts);
1136
+
1137
+ const fetchFn = makeFetch([
1138
+ {
1139
+ match: (url) => url.includes("/issues/comments"),
1140
+ respond: () => ({ status: 200, data: [commentAtTs] }),
1141
+ },
1142
+ {
1143
+ match: (url) => url.includes("/pulls/comments"),
1144
+ respond: () => ({ status: 200, data: [] }),
1145
+ },
1146
+ ]);
1147
+
1148
+ const connector = createGitHubConnector({ fetchFn });
1149
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
1150
+ // Cursor watermark is AT ts; seenIds is empty (comment was NOT previously seen).
1151
+ const cursor: import("./framework.js").ConnectorCursor = {
1152
+ kind: GITHUB_CURSOR_KIND,
1153
+ value: JSON.stringify({
1154
+ watermarks: { [`${REPO_A}/issue-comment`]: ts },
1155
+ seenIds: {},
1156
+ }),
1157
+ updatedAt: ts,
1158
+ };
1159
+
1160
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
1161
+ // With `<` fix: commentAtTs is NOT before the watermark, NOT in seenIds →
1162
+ // must be ingested. With old `<=` it would have been silently dropped.
1163
+ assert.equal(
1164
+ result.newDocs.length,
1165
+ 1,
1166
+ "comment exactly at watermark second must be ingested when not in seenIds",
1167
+ );
1168
+ assert.equal(result.newDocs[0].source.externalId, `${REPO_A}/issue-comment/42`);
1169
+ });
1170
+
1171
+ test("seenIds check gates on (id + timestamp), not id alone", async () => {
1172
+ // Scenario: A comment was previously imported at ts1. It is then edited and
1173
+ // re-fetched at ts2 (same id, newer updated_at). With the old `!== undefined`
1174
+ // check the edited version would be silently dropped. With the new
1175
+ // `=== comment.updated_at` check only the exact (id, ts) pair is suppressed.
1176
+ const ts1 = "2026-04-26T13:00:00.000Z";
1177
+ const ts2 = "2026-04-26T13:00:01.000Z";
1178
+ // Same id as the previously-ingested comment, but updated_at has advanced.
1179
+ const editedComment = makeComment(77, SYNTHETIC_LOGIN, "edited body", ts2);
1180
+
1181
+ const fetchFn = makeFetch([
1182
+ {
1183
+ match: (url) => url.includes("/issues/comments"),
1184
+ respond: () => ({ status: 200, data: [editedComment] }),
1185
+ },
1186
+ {
1187
+ match: (url) => url.includes("/pulls/comments"),
1188
+ respond: () => ({ status: 200, data: [] }),
1189
+ },
1190
+ ]);
1191
+
1192
+ const connector = createGitHubConnector({ fetchFn });
1193
+ const config = connector.validateConfig({ ...SYNTHETIC_CONFIG });
1194
+ // Cursor records id 77 with ts1 in seenIds (the old ingested version).
1195
+ // Watermark is at ts1 so the edited comment (ts2 > ts1) is above it.
1196
+ const cursor: import("./framework.js").ConnectorCursor = {
1197
+ kind: GITHUB_CURSOR_KIND,
1198
+ value: JSON.stringify({
1199
+ watermarks: { [`${REPO_A}/issue-comment`]: ts1 },
1200
+ seenIds: { [`${REPO_A}/issue-comment/77`]: ts1 },
1201
+ }),
1202
+ updatedAt: ts1,
1203
+ };
1204
+
1205
+ const result = (await connector.syncIncremental({ cursor, config })) as GitHubSyncResult;
1206
+ // The edited comment (same id, newer ts) must be ingested — seenIds only
1207
+ // suppresses the (id, ts1) pair, not (id, ts2).
1208
+ assert.equal(
1209
+ result.newDocs.length,
1210
+ 1,
1211
+ "edited comment with newer updated_at must not be suppressed by seenIds",
1212
+ );
1213
+ assert.equal(result.newDocs[0].source.externalId, `${REPO_A}/issue-comment/77`);
1214
+ assert.ok(
1215
+ result.newDocs[0].content.includes("edited body"),
1216
+ "imported document must contain the new body",
1217
+ );
1218
+ });