@remnic/core 1.1.1 → 1.1.3

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 (497) hide show
  1. package/dist/abort-error.js +1 -0
  2. package/dist/abstraction-nodes.js +1 -0
  3. package/dist/access-audit.js +1 -0
  4. package/dist/access-cli.js +76 -51
  5. package/dist/access-cli.js.map +1 -1
  6. package/dist/access-http.d.ts +50 -5
  7. package/dist/access-http.js +38 -16
  8. package/dist/access-idempotency.js +1 -0
  9. package/dist/access-mcp.d.ts +10 -5
  10. package/dist/access-mcp.js +37 -14
  11. package/dist/access-schema.d.ts +133 -13
  12. package/dist/access-schema.js +20 -1
  13. package/dist/access-service-_AEUMVyX.d.ts +1981 -0
  14. package/dist/access-service.d.ts +11 -6
  15. package/dist/access-service.js +39 -14
  16. package/dist/active-memory-bridge.js +1 -0
  17. package/dist/active-recall.js +1 -0
  18. package/dist/active-recall.js.map +1 -1
  19. package/dist/behavior-learner.js +1 -0
  20. package/dist/behavior-learner.js.map +1 -1
  21. package/dist/behavior-signals.js +1 -0
  22. package/dist/bootstrap.d.ts +6 -4
  23. package/dist/bootstrap.js +1 -0
  24. package/dist/boxes.js +1 -0
  25. package/dist/briefing.d.ts +9 -5
  26. package/dist/briefing.js +10 -6
  27. package/dist/buffer-surprise-report.js +1 -0
  28. package/dist/buffer-surprise.js +1 -0
  29. package/dist/buffer.d.ts +1 -1
  30. package/dist/buffer.js +1 -0
  31. package/dist/calibration.d.ts +8 -1
  32. package/dist/calibration.js +10 -2
  33. package/dist/calibration.js.map +1 -1
  34. package/dist/capsule-cli.d.ts +137 -0
  35. package/dist/capsule-cli.js +34 -0
  36. package/dist/capsule-crypto-5CYAGVC5.js +18 -0
  37. package/dist/capsule-export-NZQPOTQ4.js +17 -0
  38. package/dist/capsule-export-NZQPOTQ4.js.map +1 -0
  39. package/dist/capsule-import-SDCUXLEV.js +16 -0
  40. package/dist/capsule-import-SDCUXLEV.js.map +1 -0
  41. package/dist/capsule-merge-DI7PNQ2H.js +189 -0
  42. package/dist/capsule-merge-DI7PNQ2H.js.map +1 -0
  43. package/dist/causal-behavior.js +1 -0
  44. package/dist/causal-behavior.js.map +1 -1
  45. package/dist/causal-chain.js +1 -0
  46. package/dist/causal-consolidation.js +12 -9
  47. package/dist/causal-consolidation.js.map +1 -1
  48. package/dist/causal-retrieval.js +2 -1
  49. package/dist/causal-retrieval.js.map +1 -1
  50. package/dist/causal-trajectory-graph.js +4 -1
  51. package/dist/causal-trajectory-graph.js.map +1 -1
  52. package/dist/causal-trajectory.js +2 -1
  53. package/dist/chunk-2LSZVONP.js +67 -0
  54. package/dist/chunk-2LSZVONP.js.map +1 -0
  55. package/dist/chunk-32KD5IHZ.js +245 -0
  56. package/dist/chunk-32KD5IHZ.js.map +1 -0
  57. package/dist/{chunk-VDX363PS.js → chunk-34F3PLWZ.js} +10 -3
  58. package/dist/chunk-34F3PLWZ.js.map +1 -0
  59. package/dist/chunk-3KIS4VGT.js +228 -0
  60. package/dist/chunk-3KIS4VGT.js.map +1 -0
  61. package/dist/chunk-3LCWFNVS.js +350 -0
  62. package/dist/chunk-3LCWFNVS.js.map +1 -0
  63. package/dist/chunk-43EKP2UK.js +26 -0
  64. package/dist/chunk-43EKP2UK.js.map +1 -0
  65. package/dist/chunk-457A4P3L.js +119 -0
  66. package/dist/chunk-457A4P3L.js.map +1 -0
  67. package/dist/{chunk-KUB6JU6H.js → chunk-47WOM4YW.js} +2 -2
  68. package/dist/{chunk-HK3FGIEW.js → chunk-4PLGJRBV.js} +656 -20
  69. package/dist/chunk-4PLGJRBV.js.map +1 -0
  70. package/dist/{chunk-BGJGXLZ7.js → chunk-55FXRRSJ.js} +11 -8
  71. package/dist/chunk-55FXRRSJ.js.map +1 -0
  72. package/dist/{chunk-ULYOGL6R.js → chunk-5HRY2WRF.js} +7 -3
  73. package/dist/chunk-5HRY2WRF.js.map +1 -0
  74. package/dist/chunk-6TBWYBJ3.js +236 -0
  75. package/dist/chunk-6TBWYBJ3.js.map +1 -0
  76. package/dist/chunk-74EMIVE4.js +329 -0
  77. package/dist/chunk-74EMIVE4.js.map +1 -0
  78. package/dist/chunk-74WWN7ZW.js +82 -0
  79. package/dist/chunk-74WWN7ZW.js.map +1 -0
  80. package/dist/{chunk-B5WXLVDY.js → chunk-7GCMLT7J.js} +245 -25
  81. package/dist/chunk-7GCMLT7J.js.map +1 -0
  82. package/dist/chunk-A6XUJE5D.js +126 -0
  83. package/dist/chunk-A6XUJE5D.js.map +1 -0
  84. package/dist/chunk-AJA46VX5.js +393 -0
  85. package/dist/chunk-AJA46VX5.js.map +1 -0
  86. package/dist/{chunk-DFTTJYSO.js → chunk-AKUCB2OG.js} +525 -24
  87. package/dist/chunk-AKUCB2OG.js.map +1 -0
  88. package/dist/chunk-ASIQZXYO.js +277 -0
  89. package/dist/chunk-ASIQZXYO.js.map +1 -0
  90. package/dist/{chunk-ZEM3OK2K.js → chunk-B2TL6GA2.js} +3 -3
  91. package/dist/chunk-BJMBJZ2Y.js +290 -0
  92. package/dist/chunk-BJMBJZ2Y.js.map +1 -0
  93. package/dist/chunk-BT7NVCML.js +79 -0
  94. package/dist/chunk-BT7NVCML.js.map +1 -0
  95. package/dist/chunk-CK5NTM2S.js +454 -0
  96. package/dist/chunk-CK5NTM2S.js.map +1 -0
  97. package/dist/{chunk-3GXCSUXR.js → chunk-CRU27Q4J.js} +2 -2
  98. package/dist/{chunk-F5VP6YCB.js → chunk-DCE6SQLA.js} +572 -155
  99. package/dist/chunk-DCE6SQLA.js.map +1 -0
  100. package/dist/{chunk-CUPFXL3J.js → chunk-DHRQHX36.js} +4 -4
  101. package/dist/chunk-DHRQHX36.js.map +1 -0
  102. package/dist/{chunk-GKFXUTJ2.js → chunk-DR7MCMPS.js} +981 -61
  103. package/dist/chunk-DR7MCMPS.js.map +1 -0
  104. package/dist/chunk-FP2373TW.js +149 -0
  105. package/dist/chunk-FP2373TW.js.map +1 -0
  106. package/dist/{chunk-RBBWYEFJ.js → chunk-G2WADRQ3.js} +1 -1
  107. package/dist/chunk-G7D6GZ5J.js +48 -0
  108. package/dist/chunk-G7D6GZ5J.js.map +1 -0
  109. package/dist/chunk-H7XKCNR6.js +60 -0
  110. package/dist/chunk-H7XKCNR6.js.map +1 -0
  111. package/dist/{chunk-VYM3VWOF.js → chunk-IM3JSE73.js} +966 -329
  112. package/dist/chunk-IM3JSE73.js.map +1 -0
  113. package/dist/chunk-IXEJRKCZ.js +18 -0
  114. package/dist/chunk-IXEJRKCZ.js.map +1 -0
  115. package/dist/chunk-IYY4MCPG.js +275 -0
  116. package/dist/chunk-IYY4MCPG.js.map +1 -0
  117. package/dist/{chunk-BK2EFTE2.js → chunk-JWSENLQI.js} +508 -28
  118. package/dist/chunk-JWSENLQI.js.map +1 -0
  119. package/dist/chunk-KNKUID7G.js +183 -0
  120. package/dist/chunk-KNKUID7G.js.map +1 -0
  121. package/dist/chunk-L2IO2QPY.js +2036 -0
  122. package/dist/chunk-L2IO2QPY.js.map +1 -0
  123. package/dist/{chunk-SPI27QT6.js → chunk-L5IIGA5V.js} +9 -4
  124. package/dist/chunk-L5IIGA5V.js.map +1 -0
  125. package/dist/{chunk-RGLL5SPU.js → chunk-LVYGDT5V.js} +56 -82
  126. package/dist/chunk-LVYGDT5V.js.map +1 -0
  127. package/dist/{chunk-ZAIM4TUE.js → chunk-LW2NMHDW.js} +46 -1
  128. package/dist/chunk-LW2NMHDW.js.map +1 -0
  129. package/dist/{chunk-3OGMS3PE.js → chunk-LZRYQK6L.js} +3 -2
  130. package/dist/chunk-LZRYQK6L.js.map +1 -0
  131. package/dist/chunk-MDYG7VI7.js +48 -0
  132. package/dist/chunk-MDYG7VI7.js.map +1 -0
  133. package/dist/chunk-MXC3AP5I.js +74 -0
  134. package/dist/chunk-MXC3AP5I.js.map +1 -0
  135. package/dist/{chunk-S3EEFKNY.js → chunk-N7X62G74.js} +26 -11
  136. package/dist/chunk-N7X62G74.js.map +1 -0
  137. package/dist/chunk-NN3TS5BM.js +147 -0
  138. package/dist/chunk-NN3TS5BM.js.map +1 -0
  139. package/dist/chunk-OA3L7BFR.js +183 -0
  140. package/dist/chunk-OA3L7BFR.js.map +1 -0
  141. package/dist/{chunk-LK6SGL53.js → chunk-OR64ZGRZ.js} +3 -2
  142. package/dist/chunk-OR64ZGRZ.js.map +1 -0
  143. package/dist/chunk-OZHRDTDX.js +240 -0
  144. package/dist/chunk-OZHRDTDX.js.map +1 -0
  145. package/dist/chunk-PCUKNJAZ.js +165 -0
  146. package/dist/chunk-PCUKNJAZ.js.map +1 -0
  147. package/dist/{chunk-6PFRXT4K.js → chunk-PFV5C235.js} +11 -6
  148. package/dist/chunk-PFV5C235.js.map +1 -0
  149. package/dist/chunk-PZ5AY32C.js +10 -0
  150. package/dist/chunk-PZ5AY32C.js.map +1 -0
  151. package/dist/{chunk-XZ2TIKGC.js → chunk-Q7FJ5ZHM.js} +30 -10
  152. package/dist/chunk-Q7FJ5ZHM.js.map +1 -0
  153. package/dist/{chunk-7I7FKFZH.js → chunk-R2L7SUX2.js} +6 -6
  154. package/dist/{chunk-JL2PU6AI.js → chunk-R2XRID2N.js} +2 -2
  155. package/dist/{chunk-WCLICCGB.js → chunk-RILIVK4O.js} +91 -4
  156. package/dist/chunk-RILIVK4O.js.map +1 -0
  157. package/dist/{chunk-C2EFFULQ.js → chunk-RK2Y4XOM.js} +163 -20
  158. package/dist/chunk-RK2Y4XOM.js.map +1 -0
  159. package/dist/{chunk-TP4FZJIZ.js → chunk-RULE4VG5.js} +5 -1
  160. package/dist/chunk-RULE4VG5.js.map +1 -0
  161. package/dist/{chunk-PVPWZSSI.js → chunk-SMA4IMHV.js} +19 -3
  162. package/dist/chunk-SMA4IMHV.js.map +1 -0
  163. package/dist/{chunk-WVVA7F5A.js → chunk-SS253RXF.js} +30 -16
  164. package/dist/chunk-SS253RXF.js.map +1 -0
  165. package/dist/chunk-TUFG6VXY.js +875 -0
  166. package/dist/chunk-TUFG6VXY.js.map +1 -0
  167. package/dist/chunk-TYEOAFH3.js +251 -0
  168. package/dist/chunk-TYEOAFH3.js.map +1 -0
  169. package/dist/chunk-UKJAGEXH.js +260 -0
  170. package/dist/chunk-UKJAGEXH.js.map +1 -0
  171. package/dist/{chunk-KVBLZUKV.js → chunk-USFPPRAF.js} +93 -3
  172. package/dist/chunk-USFPPRAF.js.map +1 -0
  173. package/dist/{chunk-EPQJM2GC.js → chunk-VTJVUHRK.js} +22 -36
  174. package/dist/chunk-VTJVUHRK.js.map +1 -0
  175. package/dist/{chunk-O5ETUNBT.js → chunk-VTU2B4VF.js} +7 -3
  176. package/dist/chunk-VTU2B4VF.js.map +1 -0
  177. package/dist/chunk-WIICJPET.js +45 -0
  178. package/dist/chunk-WIICJPET.js.map +1 -0
  179. package/dist/{chunk-VBVG2M5G.js → chunk-WPGJYVUH.js} +6 -2
  180. package/dist/chunk-WPGJYVUH.js.map +1 -0
  181. package/dist/{chunk-YNQKWQT4.js → chunk-WSZIHQBK.js} +31 -11
  182. package/dist/{chunk-YNQKWQT4.js.map → chunk-WSZIHQBK.js.map} +1 -1
  183. package/dist/{chunk-NZLQTHS5.js → chunk-WW3QQF4H.js} +4 -1
  184. package/dist/chunk-WW3QQF4H.js.map +1 -0
  185. package/dist/{chunk-FVA6TGI3.js → chunk-Y3WQ4ZWK.js} +42 -2
  186. package/dist/chunk-Y3WQ4ZWK.js.map +1 -0
  187. package/dist/chunk-YNJHCGDT.js +309 -0
  188. package/dist/chunk-YNJHCGDT.js.map +1 -0
  189. package/dist/{chunk-ALXMCZEU.js → chunk-Z2E7VW55.js} +6 -3
  190. package/dist/chunk-Z2E7VW55.js.map +1 -0
  191. package/dist/{chunk-INXV5JBT.js → chunk-ZGXSCMQN.js} +1992 -410
  192. package/dist/chunk-ZGXSCMQN.js.map +1 -0
  193. package/dist/{chunk-W6SL7OFG.js → chunk-ZTSE2ZJ6.js} +12 -2
  194. package/dist/{chunk-W6SL7OFG.js.map → chunk-ZTSE2ZJ6.js.map} +1 -1
  195. package/dist/chunking.js +1 -0
  196. package/dist/cipher-GVE2GQ5H.js +28 -0
  197. package/dist/cipher-GVE2GQ5H.js.map +1 -0
  198. package/dist/citations.js +1 -0
  199. package/dist/{cli-BkeRaYfk.d.ts → cli-x2APT9a6.d.ts} +26 -7
  200. package/dist/cli.d.ts +11 -6
  201. package/dist/cli.js +68 -34
  202. package/dist/codex-thread-key.js +1 -0
  203. package/dist/commitment-ledger.js +1 -0
  204. package/dist/compression-optimizer.js +1 -0
  205. package/dist/config.d.ts +2 -1
  206. package/dist/config.js +5 -2
  207. package/dist/connectors-cli-DFGtY2DB.d.ts +257 -0
  208. package/dist/connectors-cli.d.ts +2 -0
  209. package/dist/connectors-cli.js +22 -0
  210. package/dist/connectors-cli.js.map +1 -0
  211. package/dist/consolidation-operator.d.ts +65 -5
  212. package/dist/consolidation-operator.js +6 -1
  213. package/dist/consolidation-provenance-check.d.ts +1 -1
  214. package/dist/consolidation-provenance-check.js +3 -2
  215. package/dist/consolidation-undo.d.ts +1 -1
  216. package/dist/consolidation-undo.js +1 -0
  217. package/dist/consolidation-undo.js.map +1 -1
  218. package/dist/{contradiction-review-WIUBAR52.js → contradiction-review-5LTTVDQV.js} +2 -1
  219. package/dist/contradiction-review-5LTTVDQV.js.map +1 -0
  220. package/dist/{contradiction-scan-E3GJTI4F.js → contradiction-scan-3Z6YW7YA.js} +2 -1
  221. package/dist/{contradiction-scan-E3GJTI4F.js.map → contradiction-scan-3Z6YW7YA.js.map} +1 -1
  222. package/dist/cross-namespace-budget.js +1 -0
  223. package/dist/cue-anchors.js +1 -0
  224. package/dist/dashboard-runtime.js +1 -0
  225. package/dist/day-summary.js +1 -0
  226. package/dist/delinearize.js +1 -0
  227. package/dist/direct-answer-wiring.js +1 -0
  228. package/dist/direct-answer.js +1 -0
  229. package/dist/dreams-ledger-LR2NBAZE.js +286 -0
  230. package/dist/dreams-ledger-LR2NBAZE.js.map +1 -0
  231. package/dist/embedding-fallback.js +3 -1
  232. package/dist/{engine-F3GOXGE5.js → engine-ICC2DSQF.js} +10 -7
  233. package/dist/engine-ICC2DSQF.js.map +1 -0
  234. package/dist/entity-retrieval.d.ts +1 -1
  235. package/dist/entity-retrieval.js +9 -6
  236. package/dist/entity-schema.js +1 -0
  237. package/dist/evals.js +1 -0
  238. package/dist/evidence-pack.d.ts +16 -0
  239. package/dist/evidence-pack.js +8 -0
  240. package/dist/evidence-pack.js.map +1 -0
  241. package/dist/explicit-capture.d.ts +6 -4
  242. package/dist/explicit-capture.js +1 -0
  243. package/dist/extraction-judge-telemetry.js +1 -0
  244. package/dist/extraction-judge-training.js +1 -0
  245. package/dist/extraction-judge.js +1 -0
  246. package/dist/extraction.js +9 -8
  247. package/dist/fallback-llm.js +3 -2
  248. package/dist/first-start-migration-4MHQEOSD.js +263 -0
  249. package/dist/first-start-migration-4MHQEOSD.js.map +1 -0
  250. package/dist/forget-PLR6J5DN.js +69 -0
  251. package/dist/forget-PLR6J5DN.js.map +1 -0
  252. package/dist/framework-CyHYDcri.d.ts +153 -0
  253. package/dist/fs-utils-IRVUFB6G.js +30 -0
  254. package/dist/fs-utils-IRVUFB6G.js.map +1 -0
  255. package/dist/graph-dashboard-diff.js +1 -0
  256. package/dist/graph-dashboard-key.js +1 -0
  257. package/dist/graph-dashboard-parser.js +1 -0
  258. package/dist/graph-edge-decay-PWB63GRE.js +207 -0
  259. package/dist/graph-edge-decay-PWB63GRE.js.map +1 -0
  260. package/dist/graph-edge-reinforcement.d.ts +81 -0
  261. package/dist/graph-edge-reinforcement.js +24 -0
  262. package/dist/graph-edge-reinforcement.js.map +1 -0
  263. package/dist/graph-events.d.ts +87 -0
  264. package/dist/graph-events.js +14 -0
  265. package/dist/graph-events.js.map +1 -0
  266. package/dist/graph-recall.js +1 -0
  267. package/dist/graph-retrieval.js +1 -0
  268. package/dist/graph-snapshot.d.ts +112 -0
  269. package/dist/graph-snapshot.js +19 -0
  270. package/dist/graph-snapshot.js.map +1 -0
  271. package/dist/graph.d.ts +105 -7
  272. package/dist/graph.js +20 -3
  273. package/dist/harmonic-retrieval.js +1 -0
  274. package/dist/himem.js +1 -0
  275. package/dist/hygiene.js +1 -0
  276. package/dist/identity-continuity.js +1 -0
  277. package/dist/importance.js +1 -0
  278. package/dist/index.d.ts +562 -13
  279. package/dist/index.js +365 -96
  280. package/dist/index.js.map +1 -1
  281. package/dist/intent.js +1 -0
  282. package/dist/json-extract.js +1 -0
  283. package/dist/json-store.js +1 -0
  284. package/dist/kdf-7S6RWKLZ.js +26 -0
  285. package/dist/kdf-7S6RWKLZ.js.map +1 -0
  286. package/dist/legacy-hook-compat.js +1 -0
  287. package/dist/legacy-hook-compat.js.map +1 -1
  288. package/dist/lifecycle.js +1 -0
  289. package/dist/live-connectors-runner.d.ts +48 -0
  290. package/dist/live-connectors-runner.js +17 -0
  291. package/dist/live-connectors-runner.js.map +1 -0
  292. package/dist/local-llm.js +3 -2
  293. package/dist/logger.js +1 -0
  294. package/dist/memory-action-policy.js +1 -0
  295. package/dist/memory-cache.d.ts +2 -1
  296. package/dist/memory-cache.js +4 -1
  297. package/dist/memory-governance-KG52RITE.js +37 -0
  298. package/dist/memory-governance-KG52RITE.js.map +1 -0
  299. package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
  300. package/dist/memory-lifecycle-ledger-utils.js +4 -1
  301. package/dist/memory-projection-format.js +1 -0
  302. package/dist/{memory-projection-store-DeSXPh1j.d.ts → memory-projection-store-D3vBHS4J.d.ts} +1 -0
  303. package/dist/memory-projection-store.d.ts +1 -1
  304. package/dist/memory-projection-store.js +1 -0
  305. package/dist/memory-worth-bench.js +1 -0
  306. package/dist/memory-worth-bench.js.map +1 -1
  307. package/dist/memory-worth-filter.js +1 -0
  308. package/dist/memory-worth-outcomes.d.ts +1 -1
  309. package/dist/memory-worth-outcomes.js +1 -0
  310. package/dist/memory-worth.js +1 -0
  311. package/dist/metadata-FC3XPDRQ.js +21 -0
  312. package/dist/metadata-FC3XPDRQ.js.map +1 -0
  313. package/dist/migrate-from-identity-anchor-TTEDEJGX.js +8 -0
  314. package/dist/migrate-from-identity-anchor-TTEDEJGX.js.map +1 -0
  315. package/dist/model-registry.js +1 -0
  316. package/dist/models-json.js +1 -0
  317. package/dist/native-knowledge.js +1 -0
  318. package/dist/negative.js +1 -0
  319. package/dist/objective-state-writers.js +1 -0
  320. package/dist/objective-state-writers.js.map +1 -1
  321. package/dist/objective-state.js +1 -0
  322. package/dist/openai-chat-compat.js +1 -0
  323. package/dist/operator-toolkit.d.ts +46 -2
  324. package/dist/operator-toolkit.js +29 -17
  325. package/dist/opik-exporter.js +1 -0
  326. package/dist/opik-exporter.js.map +1 -1
  327. package/dist/{orchestrator-CmJ-NTdJ.d.ts → orchestrator-ChkesB8U.d.ts} +177 -13
  328. package/dist/orchestrator.d.ts +6 -4
  329. package/dist/orchestrator.js +58 -42
  330. package/dist/page-versioning.js +1 -0
  331. package/dist/path-RMTY5Y5A.js +9 -0
  332. package/dist/path-RMTY5Y5A.js.map +1 -0
  333. package/dist/patterns-cli.d.ts +160 -0
  334. package/dist/patterns-cli.js +29 -0
  335. package/dist/patterns-cli.js.map +1 -0
  336. package/dist/peers-6OSQ3NK6.js +44 -0
  337. package/dist/peers-6OSQ3NK6.js.map +1 -0
  338. package/dist/plugin-id.js +1 -0
  339. package/dist/policy-runtime.js +1 -0
  340. package/dist/{port-BADbLZU5.d.ts → port-hqGnoStS.d.ts} +6 -0
  341. package/dist/profiling.js +1 -0
  342. package/dist/purge-6ATBGT77.js +205 -0
  343. package/dist/purge-6ATBGT77.js.map +1 -0
  344. package/dist/qmd-recall-cache.d.ts +1 -1
  345. package/dist/qmd-recall-cache.js +1 -0
  346. package/dist/qmd.d.ts +2 -1
  347. package/dist/qmd.js +4 -3
  348. package/dist/reasoning-trace-recall.js +1 -0
  349. package/dist/reasoning-trace-types.js +1 -0
  350. package/dist/recall-audit-anomaly.js +1 -0
  351. package/dist/recall-audit.js +1 -0
  352. package/dist/recall-disclosure-escalation.d.ts +84 -0
  353. package/dist/recall-disclosure-escalation.js +14 -0
  354. package/dist/recall-disclosure-escalation.js.map +1 -0
  355. package/dist/recall-explain-renderer.js +4 -1
  356. package/dist/recall-mmr.js +1 -0
  357. package/dist/recall-qos.js +1 -0
  358. package/dist/recall-query-policy.js +1 -0
  359. package/dist/recall-state.d.ts +7 -0
  360. package/dist/recall-state.js +2 -1
  361. package/dist/recall-tag-filter.d.ts +56 -0
  362. package/dist/recall-tag-filter.js +14 -0
  363. package/dist/recall-tag-filter.js.map +1 -0
  364. package/dist/recall-tokenization.js +1 -0
  365. package/dist/recall-xray-cli.d.ts +9 -2
  366. package/dist/recall-xray-cli.js +9 -4
  367. package/dist/recall-xray-renderer.js +4 -1
  368. package/dist/recall-xray.d.ts +116 -2
  369. package/dist/recall-xray.js +9 -3
  370. package/dist/reconstruct.js +1 -0
  371. package/dist/release-changelog.js +2 -0
  372. package/dist/release-changelog.js.map +1 -1
  373. package/dist/relevance.js +1 -0
  374. package/dist/rerank.js +1 -0
  375. package/dist/{resolution-QBTDHTG7.js → resolution-YGIBORXI.js} +2 -1
  376. package/dist/{resolution-QBTDHTG7.js.map → resolution-YGIBORXI.js.map} +1 -1
  377. package/dist/resolve-auth-token.d.ts +51 -0
  378. package/dist/resolve-auth-token.js +12 -0
  379. package/dist/resolve-auth-token.js.map +1 -0
  380. package/dist/resolve-provider-secret.d.ts +13 -1
  381. package/dist/resolve-provider-secret.js +6 -1
  382. package/dist/resume-bundles.js +5 -4
  383. package/dist/retrieval-agents.d.ts +1 -1
  384. package/dist/retrieval-agents.js +1 -0
  385. package/dist/retrieval-tiers.js +1 -0
  386. package/dist/retrieval.js +1 -0
  387. package/dist/sanitize.js +1 -0
  388. package/dist/schemas.d.ts +15 -2
  389. package/dist/schemas.js +2 -1
  390. package/dist/sdk-compat.js +1 -0
  391. package/dist/sdk-compat.js.map +1 -1
  392. package/dist/secure-store-4R2GSO7S.js +156 -0
  393. package/dist/secure-store-4R2GSO7S.js.map +1 -0
  394. package/dist/semantic-chunking.js +1 -0
  395. package/dist/{semantic-consolidation-CxJU6MJk.d.ts → semantic-consolidation-ByBXb-sf.d.ts} +3 -3
  396. package/dist/semantic-consolidation.d.ts +2 -2
  397. package/dist/semantic-consolidation.js +12 -6
  398. package/dist/semantic-rule-promotion.d.ts +1 -1
  399. package/dist/semantic-rule-promotion.js +9 -6
  400. package/dist/semantic-rule-verifier.d.ts +1 -1
  401. package/dist/semantic-rule-verifier.js +9 -6
  402. package/dist/session-integrity.js +1 -0
  403. package/dist/session-observer-bands.js +1 -0
  404. package/dist/session-observer-state.js +1 -0
  405. package/dist/session-toggles.js +2 -0
  406. package/dist/session-toggles.js.map +1 -1
  407. package/dist/signal.js +1 -0
  408. package/dist/skills-registry.js +2 -0
  409. package/dist/skills-registry.js.map +1 -1
  410. package/dist/source-attribution.js +1 -0
  411. package/dist/state-NCHQ4TRG.js +8 -0
  412. package/dist/state-NCHQ4TRG.js.map +1 -0
  413. package/dist/state-store-3EH7HYIN.js +16 -0
  414. package/dist/state-store-3EH7HYIN.js.map +1 -0
  415. package/dist/storage.d.ts +76 -2
  416. package/dist/storage.js +8 -5
  417. package/dist/store-contract.js +1 -0
  418. package/dist/summarizer.js +6 -5
  419. package/dist/summary-snapshot.js +1 -0
  420. package/dist/temporal-index.js +1 -0
  421. package/dist/temporal-supersession.d.ts +1 -1
  422. package/dist/temporal-supersession.js +2 -1
  423. package/dist/temporal-validity.d.ts +52 -0
  424. package/dist/temporal-validity.js +14 -0
  425. package/dist/temporal-validity.js.map +1 -0
  426. package/dist/threading.js +1 -0
  427. package/dist/tier-migration.d.ts +2 -2
  428. package/dist/tier-migration.js +1 -0
  429. package/dist/tier-routing.js +1 -0
  430. package/dist/tier-stats-62ZVDFKS.js +152 -0
  431. package/dist/tier-stats-62ZVDFKS.js.map +1 -0
  432. package/dist/tmt.js +1 -0
  433. package/dist/tokens.js +3 -1
  434. package/dist/topics.js +1 -0
  435. package/dist/trace-C5ETWBEF.js +290 -0
  436. package/dist/trace-C5ETWBEF.js.map +1 -0
  437. package/dist/transcript.js +1 -0
  438. package/dist/trust-zones.js +1 -0
  439. package/dist/tui-RI7P6PBS.js +13 -0
  440. package/dist/tui-RI7P6PBS.js.map +1 -0
  441. package/dist/types-V3FJ26TF.js +30 -0
  442. package/dist/types-V3FJ26TF.js.map +1 -0
  443. package/dist/types.d.ts +634 -9
  444. package/dist/types.js +10 -3
  445. package/dist/utility-learner.js +1 -0
  446. package/dist/utility-runtime.js +1 -0
  447. package/dist/utility-telemetry.js +1 -0
  448. package/dist/verified-recall.js +9 -6
  449. package/dist/version-utils.js +1 -0
  450. package/dist/whitespace.js +1 -0
  451. package/dist/work-product-ledger.js +1 -0
  452. package/package.json +2 -1
  453. package/dist/access-service-Br8ZydTK.d.ts +0 -827
  454. package/dist/chunk-3OGMS3PE.js.map +0 -1
  455. package/dist/chunk-6PFRXT4K.js.map +0 -1
  456. package/dist/chunk-ALXMCZEU.js.map +0 -1
  457. package/dist/chunk-B5WXLVDY.js.map +0 -1
  458. package/dist/chunk-BGJGXLZ7.js.map +0 -1
  459. package/dist/chunk-BK2EFTE2.js.map +0 -1
  460. package/dist/chunk-C2EFFULQ.js.map +0 -1
  461. package/dist/chunk-CUPFXL3J.js.map +0 -1
  462. package/dist/chunk-DFTTJYSO.js.map +0 -1
  463. package/dist/chunk-EPQJM2GC.js.map +0 -1
  464. package/dist/chunk-F5VP6YCB.js.map +0 -1
  465. package/dist/chunk-FVA6TGI3.js.map +0 -1
  466. package/dist/chunk-GKFXUTJ2.js.map +0 -1
  467. package/dist/chunk-HK3FGIEW.js.map +0 -1
  468. package/dist/chunk-INXV5JBT.js.map +0 -1
  469. package/dist/chunk-KVBLZUKV.js.map +0 -1
  470. package/dist/chunk-LK6SGL53.js.map +0 -1
  471. package/dist/chunk-LTCGGW2D.js +0 -14
  472. package/dist/chunk-LTCGGW2D.js.map +0 -1
  473. package/dist/chunk-NZLQTHS5.js.map +0 -1
  474. package/dist/chunk-O5ETUNBT.js.map +0 -1
  475. package/dist/chunk-PVPWZSSI.js.map +0 -1
  476. package/dist/chunk-RGLL5SPU.js.map +0 -1
  477. package/dist/chunk-S3EEFKNY.js.map +0 -1
  478. package/dist/chunk-SPI27QT6.js.map +0 -1
  479. package/dist/chunk-TP4FZJIZ.js.map +0 -1
  480. package/dist/chunk-ULYOGL6R.js.map +0 -1
  481. package/dist/chunk-VBVG2M5G.js.map +0 -1
  482. package/dist/chunk-VDX363PS.js.map +0 -1
  483. package/dist/chunk-VYM3VWOF.js.map +0 -1
  484. package/dist/chunk-WCLICCGB.js.map +0 -1
  485. package/dist/chunk-WVVA7F5A.js.map +0 -1
  486. package/dist/chunk-X6GF3FX2.js +0 -26
  487. package/dist/chunk-X6GF3FX2.js.map +0 -1
  488. package/dist/chunk-XZ2TIKGC.js.map +0 -1
  489. package/dist/chunk-ZAIM4TUE.js.map +0 -1
  490. /package/dist/{contradiction-review-WIUBAR52.js.map → capsule-cli.js.map} +0 -0
  491. /package/dist/{engine-F3GOXGE5.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
  492. /package/dist/{chunk-KUB6JU6H.js.map → chunk-47WOM4YW.js.map} +0 -0
  493. /package/dist/{chunk-ZEM3OK2K.js.map → chunk-B2TL6GA2.js.map} +0 -0
  494. /package/dist/{chunk-3GXCSUXR.js.map → chunk-CRU27Q4J.js.map} +0 -0
  495. /package/dist/{chunk-RBBWYEFJ.js.map → chunk-G2WADRQ3.js.map} +0 -0
  496. /package/dist/{chunk-7I7FKFZH.js.map → chunk-R2L7SUX2.js.map} +0 -0
  497. /package/dist/{chunk-JL2PU6AI.js.map → chunk-R2XRID2N.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/coding/git-context.ts","../src/procedural/reinforcement-core.ts"],"sourcesContent":["/**\n * GitContextResolver — pure module for detecting the git project + branch\n * a session is operating in.\n *\n * Introduced by issue #569 (coding-agent project/branch-scoped namespaces).\n *\n * This module is deliberately pure:\n * - no orchestrator references\n * - no config side-effects\n * - no namespace wiring\n *\n * Downstream slices (PR 2+ of #569) wire `resolveGitContext` into the\n * `NamespaceResolver` / `Orchestrator` so that memories are scoped to a\n * detected project / branch without leaking across repos.\n *\n * CLAUDE.md rule 17 (expand `~`): the `rootPath` returned here is always an\n * absolute, tilde-expanded path. Callers must not re-expand.\n *\n * CLAUDE.md rule 51 (reject invalid input): `cwd` must be an absolute path\n * and must exist. `resolveGitContext` returns `null` — rather than throwing —\n * when the directory is not inside a git worktree, because being outside a\n * repo is a normal runtime state (e.g. agent opened in a scratch dir).\n */\nimport path from \"node:path\";\n\nimport { expandTildePath } from \"../utils/path.js\";\nimport { launchProcessSync } from \"../runtime/child-process.js\";\n\n// Re-export so existing callers / tests that imported `expandTildePath` from\n// this module keep working. CLAUDE.md #17 requires consistent `~` expansion\n// across every user-facing path input; the canonical implementation now\n// lives in `utils/path.ts`.\nexport { expandTildePath };\n\n// ──────────────────────────────────────────────────────────────────────────\n// Public types\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface GitContext {\n /**\n * Stable identifier for the project. Derived from `git remote get-url origin`\n * when an origin remote is configured, otherwise from the repo root path.\n *\n * Formatted as `origin:<hex>` or `root:<hex>` so that the source is visible\n * to operators (see `remnic doctor`, issue #569 acceptance criteria).\n */\n projectId: string;\n /**\n * Current branch, e.g. `main`, `feat/foo`. `null` only in detached-HEAD\n * state (e.g. rebase in progress). Callers should treat `null` as \"no\n * branch-scope overlay applies\" without erroring.\n */\n branch: string | null;\n /**\n * Absolute path to the repository root (the directory containing `.git`).\n * Tilde-expanded per CLAUDE.md #17.\n */\n rootPath: string;\n /**\n * Best-effort default branch (usually `main` or `master`). Derived from the\n * `refs/remotes/origin/HEAD` symbolic ref. `null` when not available (e.g.\n * fresh clone without a default branch symref, or no origin remote).\n */\n defaultBranch: string | null;\n}\n\n/**\n * Injectable git-invocation surface. Only the commands `resolveGitContext`\n * actually needs are exposed. Tests inject a mock implementation to avoid\n * spawning a real git process.\n */\nexport interface GitInvoker {\n /**\n * Run `git <args>` with `cwd` as the working directory. Must return\n * `{ stdout, exitCode }` with `stdout` trimmed by the caller as needed.\n * Implementations should NOT throw for non-zero exit codes — they should\n * return the exit code so the resolver can decide how to recover.\n */\n (cwd: string, args: string[]): { stdout: string; exitCode: number };\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Default git invoker — spawns real `git` via the shared child-process helper\n// ──────────────────────────────────────────────────────────────────────────\n\nconst DEFAULT_GIT_TIMEOUT_MS = 2_000;\n\nexport function defaultGitInvoker(): GitInvoker {\n return (cwd: string, args: string[]) => {\n const result = launchProcessSync(\"git\", args, {\n cwd,\n encoding: \"utf-8\",\n timeout: DEFAULT_GIT_TIMEOUT_MS,\n shell: false,\n });\n if (result.error) {\n // Spawn failure (git not on PATH, timeout, etc.). Surface as non-zero.\n return { stdout: \"\", exitCode: 127 };\n }\n return {\n stdout: typeof result.stdout === \"string\" ? result.stdout : \"\",\n exitCode: typeof result.status === \"number\" ? result.status : 1,\n };\n };\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Stable hashing\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Non-cryptographic stable hash. Used only to derive a deterministic\n * `projectId` from either the origin URL or the root path. The hash does not\n * need to be collision-resistant against adversarial input — it is purely a\n * namespace discriminator.\n *\n * Uses FNV-1a 32-bit so we don't pull in `node:crypto` for a simple bucket\n * key. Output is lowercase hex, zero-padded to 8 characters.\n */\nexport function stableHash(input: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Origin URL normalization\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Normalize a git remote URL so that equivalent SSH / HTTPS forms of the\n * same repo produce the same `projectId`. Handles:\n * - `git@github.com:foo/bar.git` → `github.com/foo/bar`\n * - `https://github.com/foo/bar` → `github.com/foo/bar`\n * - `https://github.com/foo/bar.git` → `github.com/foo/bar`\n * - `ssh://git@github.com/foo/bar` → `github.com/foo/bar`\n * - `ssh://git@github.com:2222/foo/bar` → `github.com/foo/bar` (port stripped)\n *\n * Case-insensitive (remote hostnames and most repo paths on major forges are\n * case-insensitive in practice).\n */\nexport function normalizeOriginUrl(rawUrl: string): string {\n let url = rawUrl.trim();\n if (!url) return \"\";\n\n // Strip trailing `.git` case-insensitively — the whole result is\n // lowercased at the end, so `.GIT` / `.Git` must be treated the same as\n // `.git`. Previously the `.endsWith(\".git\")` check let `.GIT` leak\n // through and appear in the output.\n if (/\\.git$/i.test(url)) url = url.slice(0, -4);\n\n // Windows drive-letter local path (e.g. `C:/repos/app`): detect here\n // so the scp matcher below can accept single-character SSH host aliases\n // (`h:foo/bar` from `.ssh/config`). A drive letter is exactly one ASCII\n // letter followed by `:/` or `:\\`; SSH aliases never have a slash\n // immediately after the colon.\n if (/^[A-Za-z]:[\\\\/]/.test(url)) {\n return url.toLowerCase();\n }\n\n // Protocol-prefixed: ssh://, https://, http://, git://, file://\n // Must be tried FIRST so that scp-style detection below doesn't\n // incorrectly swallow an ssh:// URL that happens to contain `:port/`.\n //\n // Matches:\n // 1: host — bracketed IPv6 `[2001:db8::1]`, plain host with no `:` / `/`,\n // OR empty (for `file:///path` which has no host component).\n // 2: port (optional) — preserved in the output so two repos on the same\n // host under different ports get distinct project namespaces.\n // Losing the port risked false-coalescing separate repos on custom\n // SSH mesh setups.\n // 3: path (optional)\n const protoMatch =\n /^[a-z][a-z0-9+.-]*:\\/\\/(?:[^@/]+@)?(\\[[^\\]]+\\]|[^/:]*)(?::(\\d+))?(\\/.*)?$/i.exec(url);\n if (protoMatch) {\n let host = protoMatch[1] ?? \"\";\n // Detect IPv6 via the bracketed input form BEFORE stripping brackets,\n // so that when we later re-attach a port we can preserve the\n // `[host]:port` boundary. Without the brackets, `host:2222` is\n // ambiguous with a longer bare IPv6 address like `2001:db8::1:2222`.\n const wasBracketed =\n host.startsWith(\"[\") && host.endsWith(\"]\");\n if (wasBracketed) host = host.slice(1, -1);\n const port = protoMatch[2];\n const repoPath = (protoMatch[3] ?? \"\").replace(/^\\/+/, \"\");\n const hostPort = port\n ? wasBracketed\n ? `[${host}]:${port}`\n : `${host}:${port}`\n : host;\n // For protocols without a host component (file:///path), fall back to\n // a stable prefix so distinct local paths don't collapse to \"/path\".\n const prefix = hostPort.length > 0 ? hostPort : \"localhost\";\n return `${prefix}/${repoPath}`.toLowerCase();\n }\n\n // scp-like syntax: [user@]host:path. Protocol-prefixed URLs (`scheme://`)\n // are handled above, so the scp branch below guards against them: a\n // matched `host` of `scheme` followed by a path starting with `//` is\n // a protocol URL that fell through and must NOT be parsed here.\n // `user@` is optional — git also accepts userless scp forms like\n // `host:org/repo`. Valid scp paths may start with digits (e.g.\n // `git@host:123/repo.git`), so no numeric guard is needed: port-bearing\n // URLs have the `://` prefix and match the protocol branch above before\n // reaching here.\n //\n // Windows drive letters were filtered above, so single-character SSH\n // host aliases (`h:foo/bar`) are accepted here.\n //\n // Bracketed IPv6 (`[2001:db8::1]`) is supported: the host alternative\n // matches the bracketed literal up to `]` without splitting on internal\n // `:`. Brackets are stripped in the normalised form so the scp and\n // `ssh://` forms of the same IPv6 remote produce identical projectIds.\n const scpMatch =\n /^(?:([^@\\s/]+)@)?(\\[[^\\]]+\\]|[^:@\\s/]+):(.+)$/.exec(url);\n if (scpMatch) {\n let host = scpMatch[2] ?? \"\";\n if (host.startsWith(\"[\") && host.endsWith(\"]\")) host = host.slice(1, -1);\n const repoPath = scpMatch[3] ?? \"\";\n // Reject protocol-like leftovers (e.g. `file:///path` where the scp\n // regex greedily matched `file` as host and `///path` as path).\n if (repoPath.startsWith(\"//\")) {\n return url.toLowerCase();\n }\n return `${host}/${repoPath.replace(/^\\/+/, \"\")}`.toLowerCase();\n }\n\n // Fallback: use raw lowercased\n return url.toLowerCase();\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Resolver\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface ResolveGitContextOptions {\n /** Inject a git invoker (tests). Defaults to spawning real `git`. */\n invoker?: GitInvoker;\n}\n\n/**\n * Detect the git project + branch for `cwd`.\n *\n * Returns `null` when:\n * - `cwd` is not an absolute path (invalid input, CLAUDE.md #51)\n * - `cwd` is not inside a git worktree\n * - `git` is not available on PATH\n *\n * Never throws.\n */\nexport async function resolveGitContext(\n cwd: string,\n options: ResolveGitContextOptions = {},\n): Promise<GitContext | null> {\n // Wrap the whole body so the documented \"Never throws\" contract is\n // enforced. Possible throw sites include:\n // - `expandTildePath` → `resolveHomeDir()` → `os.homedir()` when HOME\n // is unset (e.g. minimal containers)\n // - a custom `options.invoker` that raises instead of returning a\n // non-zero exitCode\n // - any future helper added to this chain\n // All of those map to \"not in a repo\" / `null`.\n try {\n // Validate input: must be a non-empty string.\n if (typeof cwd !== \"string\" || cwd.length === 0) return null;\n\n // Expand `~` per CLAUDE.md #17, then require absolute path.\n const expanded = expandTildePath(cwd);\n if (!path.isAbsolute(expanded)) return null;\n\n const invoker = options.invoker ?? defaultGitInvoker();\n\n // 1. Locate the repo root.\n const topLevel = invoker(expanded, [\"rev-parse\", \"--show-toplevel\"]);\n if (topLevel.exitCode !== 0) return null;\n const rootPath = topLevel.stdout.trim();\n if (!rootPath) return null;\n\n // 2. Current branch. `--abbrev-ref HEAD` returns `HEAD` in detached\n // state, which we normalize to `null`. On a fresh `git init` the\n // HEAD ref is unborn and `--abbrev-ref HEAD` fails, but\n // `symbolic-ref HEAD` still returns the target branch. Fall back\n // so newly-initialized repos get a sensible branch name.\n const branchResult = invoker(rootPath, [\"rev-parse\", \"--abbrev-ref\", \"HEAD\"]);\n let branch: string | null = null;\n if (branchResult.exitCode === 0) {\n const raw = branchResult.stdout.trim();\n branch = raw && raw !== \"HEAD\" ? raw : null;\n } else {\n const unbornRef = invoker(rootPath, [\"symbolic-ref\", \"--quiet\", \"HEAD\"]);\n if (unbornRef.exitCode === 0) {\n const raw = unbornRef.stdout.trim();\n const prefix = \"refs/heads/\";\n if (raw.startsWith(prefix)) {\n const candidate = raw.slice(prefix.length);\n if (candidate) branch = candidate;\n }\n }\n }\n\n // 3. Origin URL — optional. Used to derive a stable `projectId`.\n const originResult = invoker(rootPath, [\"remote\", \"get-url\", \"origin\"]);\n let projectId: string;\n if (originResult.exitCode === 0) {\n const normalized = normalizeOriginUrl(originResult.stdout);\n projectId = normalized ? `origin:${stableHash(normalized)}` : `root:${stableHash(rootPath)}`;\n } else {\n projectId = `root:${stableHash(rootPath)}`;\n }\n\n // 4. Default branch — best effort.\n const headRef = invoker(rootPath, [\"symbolic-ref\", \"--quiet\", \"refs/remotes/origin/HEAD\"]);\n let defaultBranch: string | null = null;\n if (headRef.exitCode === 0) {\n const raw = headRef.stdout.trim();\n const prefix = \"refs/remotes/origin/\";\n if (raw.startsWith(prefix)) {\n const candidate = raw.slice(prefix.length);\n if (candidate) defaultBranch = candidate;\n }\n }\n\n return {\n projectId,\n branch,\n rootPath,\n defaultBranch,\n };\n } catch {\n // Never throws — any unexpected error falls back to \"not in a repo\".\n return null;\n }\n}\n","/**\n * Generic reinforcement-core primitives extracted from `procedure-miner.ts`\n * (issue #687 PR 1/4). Procedure-specific scoring (success rate, step\n * normalization) intentionally stays in the miner — this module only\n * exposes category-agnostic clustering and cluster summarization helpers\n * so future PRs can run reinforcement across non-procedural categories.\n *\n * Pure refactor — no behavior change.\n */\n\n/**\n * Group `items` into clusters keyed by `keyFn(item)`.\n *\n * - Preserves the original input order within each cluster's array.\n * - The returned `Map` insertion order matches first-seen key order, so\n * downstream iteration is deterministic for a given input.\n * - Throws `TypeError` if `keyFn` returns a non-string (e.g. `undefined`,\n * `null`, or a number). Callers must produce a stable string key.\n */\nexport function clusterByKey<T>(items: readonly T[], keyFn: (item: T) => string): Map<string, T[]> {\n const clusters = new Map<string, T[]>();\n for (const item of items) {\n const key = keyFn(item);\n if (typeof key !== \"string\") {\n throw new TypeError(\n `clusterByKey: keyFn must return a string, got ${key === null ? \"null\" : typeof key}`,\n );\n }\n const existing = clusters.get(key);\n if (existing) {\n existing.push(item);\n } else {\n clusters.set(key, [item]);\n }\n }\n return clusters;\n}\n\nexport interface ClusterSummary {\n /** Number of items in the cluster. */\n count: number;\n /** Earliest timestamp seen in the cluster (string min via `localeCompare`). */\n firstSeen: string;\n /** Latest timestamp seen in the cluster (string max via `localeCompare`). */\n lastSeen: string;\n}\n\n/**\n * Summarize a cluster by counting items and tracking earliest/latest\n * timestamps. Timestamp comparison uses `String#localeCompare`, which is\n * correct for ISO-8601 strings (lexicographic order matches chronological\n * order).\n *\n * - Throws `RangeError` on empty clusters — `firstSeen`/`lastSeen` are not\n * meaningful without at least one item.\n * - When all timestamps are equal, `firstSeen === lastSeen`.\n */\nexport function summarizeCluster<T>(\n cluster: readonly T[],\n extractTimestamp: (item: T) => string,\n): ClusterSummary {\n if (cluster.length === 0) {\n throw new RangeError(\"summarizeCluster: cluster must contain at least one item\");\n }\n let firstSeen = extractTimestamp(cluster[0]);\n let lastSeen = firstSeen;\n for (let i = 1; i < cluster.length; i += 1) {\n const ts = extractTimestamp(cluster[i]);\n if (ts.localeCompare(firstSeen) < 0) firstSeen = ts;\n if (ts.localeCompare(lastSeen) > 0) lastSeen = ts;\n }\n return { count: cluster.length, firstSeen, lastSeen };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,183 @@
1
+ // src/transfer/types.ts
2
+ import { z } from "zod";
3
+ var ExportManifestV1Schema = z.object({
4
+ format: z.literal("openclaw-engram-export"),
5
+ schemaVersion: z.literal(1),
6
+ createdAt: z.string(),
7
+ pluginVersion: z.string(),
8
+ includesTranscripts: z.boolean(),
9
+ files: z.array(
10
+ z.object({
11
+ path: z.string(),
12
+ sha256: z.string(),
13
+ bytes: z.number().int().nonnegative()
14
+ })
15
+ )
16
+ });
17
+ var ExportMemoryRecordV1Schema = z.object({
18
+ path: z.string(),
19
+ content: z.string()
20
+ });
21
+ var ExportBundleV1Schema = z.object({
22
+ manifest: ExportManifestV1Schema,
23
+ records: z.array(ExportMemoryRecordV1Schema)
24
+ });
25
+ var CAPSULE_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9]|-(?!-))*[A-Za-z0-9]$|^[A-Za-z0-9]$/;
26
+ var CapsuleIdSchema = z.string().min(1, "capsule.id must not be empty").max(64, "capsule.id must be 64 characters or fewer").regex(
27
+ CAPSULE_ID_PATTERN,
28
+ "capsule.id must be alphanumeric with single dashes (no spaces, no leading/trailing dashes)"
29
+ );
30
+ var SemverLikeSchema = z.string().min(1, "capsule.version must not be empty").regex(
31
+ /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/,
32
+ "capsule.version must be a semver-like string (e.g. 1.0.0)"
33
+ );
34
+ var CapsuleRetrievalPolicySchema = z.object({
35
+ /**
36
+ * Per-tier weight overrides applied during recall when the capsule is the
37
+ * active scope. Keys are tier names (e.g. `bm25`, `vector`, `graph`); values
38
+ * are non-negative finite multipliers. The set of valid keys is left open
39
+ * for now so future tiers do not break older manifests.
40
+ */
41
+ tierWeights: z.record(
42
+ z.string().min(1),
43
+ z.number().finite().nonnegative()
44
+ ),
45
+ /**
46
+ * Whether the direct-answer fast path is allowed when this capsule is
47
+ * active. Operators may disable it for capsules whose contents should
48
+ * always flow through the full retrieval pipeline.
49
+ */
50
+ directAnswerEnabled: z.boolean()
51
+ });
52
+ var CapsuleIncludesSchema = z.object({
53
+ taxonomy: z.boolean(),
54
+ identityAnchors: z.boolean(),
55
+ peerProfiles: z.boolean(),
56
+ procedural: z.boolean()
57
+ });
58
+ var CapsuleParentSchema = z.object({
59
+ capsuleId: CapsuleIdSchema,
60
+ version: SemverLikeSchema,
61
+ /**
62
+ * Posix-relative path prefix under the fork's memory root where the parent
63
+ * capsule's records were placed. Typically `forks/<parent-capsule-id>`.
64
+ * Must be a non-empty string with no leading slash.
65
+ */
66
+ forkRoot: z.string().min(1, "capsule.parent.forkRoot must not be empty").refine((v) => !v.startsWith("/"), {
67
+ message: "capsule.parent.forkRoot must be a relative path (no leading slash)"
68
+ })
69
+ });
70
+ var CapsuleBlockSchema = z.object({
71
+ id: CapsuleIdSchema,
72
+ version: SemverLikeSchema,
73
+ /**
74
+ * Taxonomy schema version the capsule was authored against. Free-form for
75
+ * now; later PRs may tighten this to a known taxonomy registry.
76
+ */
77
+ schemaVersion: z.string().min(1, "capsule.schemaVersion must not be empty"),
78
+ /**
79
+ * Optional reference to the parent capsule this one was forked or derived
80
+ * from. `null` (not `undefined`) is the explicit "no parent" sentinel so
81
+ * that round-trips through JSON do not silently drop the field.
82
+ *
83
+ * @deprecated Prefer {@link parent} (structured). This field is preserved
84
+ * for backward compatibility with V2 manifests written before PR 4/6.
85
+ */
86
+ parentCapsule: z.string().min(1).nullable(),
87
+ /**
88
+ * Structured fork-lineage pointer added in PR 4/6. When present, this
89
+ * capsule is a fork of the described parent. `null` is the explicit
90
+ * "not a fork" sentinel — round-trips through JSON cleanly without
91
+ * silently dropping the field.
92
+ *
93
+ * Defaults to `null` so that V2 manifests written before PR 4/6 (which
94
+ * omit this field) still parse without error. This preserves backward
95
+ * compatibility with the existing `makeV2Manifest()` test fixtures and
96
+ * any in-the-wild V2 archives produced by PR 2/6 and PR 3/6.
97
+ *
98
+ * Invariant: when `parent` is non-null, `parentCapsule` SHOULD equal
99
+ * `parent.capsuleId` for backward compatibility with readers that only
100
+ * understand the legacy field. `forkCapsule()` sets both.
101
+ */
102
+ parent: CapsuleParentSchema.nullable().default(null),
103
+ description: z.string(),
104
+ retrievalPolicy: CapsuleRetrievalPolicySchema,
105
+ includes: CapsuleIncludesSchema
106
+ });
107
+ var ExportManifestV2Schema = z.object({
108
+ format: z.literal("openclaw-engram-export"),
109
+ schemaVersion: z.literal(2),
110
+ createdAt: z.string(),
111
+ pluginVersion: z.string(),
112
+ includesTranscripts: z.boolean(),
113
+ files: z.array(
114
+ z.object({
115
+ path: z.string(),
116
+ sha256: z.string(),
117
+ bytes: z.number().int().nonnegative()
118
+ })
119
+ ),
120
+ capsule: CapsuleBlockSchema
121
+ });
122
+ var ExportBundleV2Schema = z.object({
123
+ manifest: ExportManifestV2Schema,
124
+ records: z.array(ExportMemoryRecordV1Schema)
125
+ });
126
+ function parseExportManifest(input) {
127
+ const version = typeof input === "object" && input !== null ? input.schemaVersion : void 0;
128
+ if (version === 2) {
129
+ const manifest = ExportManifestV2Schema.parse(input);
130
+ return {
131
+ capsuleVersion: 2,
132
+ manifest,
133
+ capsule: manifest.capsule
134
+ };
135
+ }
136
+ if (version === 1) {
137
+ const manifest = ExportManifestV1Schema.parse(input);
138
+ return { capsuleVersion: 1, manifest, capsule: null };
139
+ }
140
+ const v1 = ExportManifestV1Schema.safeParse(input);
141
+ if (v1.success) {
142
+ return { capsuleVersion: 1, manifest: v1.data, capsule: null };
143
+ }
144
+ const v2 = ExportManifestV2Schema.safeParse(input);
145
+ if (v2.success) {
146
+ return {
147
+ capsuleVersion: 2,
148
+ manifest: v2.data,
149
+ capsule: v2.data.capsule
150
+ };
151
+ }
152
+ throw v2.error;
153
+ }
154
+ function parseExportBundle(input) {
155
+ if (typeof input !== "object" || input === null) {
156
+ ExportBundleV1Schema.parse(input);
157
+ throw new Error("unreachable");
158
+ }
159
+ const manifestRaw = input.manifest;
160
+ const normalized = parseExportManifest(manifestRaw);
161
+ if (normalized.capsuleVersion === 2) {
162
+ const bundle2 = ExportBundleV2Schema.parse(input);
163
+ return { capsuleVersion: 2, bundle: bundle2, capsule: bundle2.manifest.capsule };
164
+ }
165
+ const bundle = ExportBundleV1Schema.parse(input);
166
+ return { capsuleVersion: 1, bundle, capsule: null };
167
+ }
168
+
169
+ export {
170
+ ExportManifestV1Schema,
171
+ ExportMemoryRecordV1Schema,
172
+ ExportBundleV1Schema,
173
+ CAPSULE_ID_PATTERN,
174
+ CapsuleRetrievalPolicySchema,
175
+ CapsuleIncludesSchema,
176
+ CapsuleParentSchema,
177
+ CapsuleBlockSchema,
178
+ ExportManifestV2Schema,
179
+ ExportBundleV2Schema,
180
+ parseExportManifest,
181
+ parseExportBundle
182
+ };
183
+ //# sourceMappingURL=chunk-OA3L7BFR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/transfer/types.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const ExportManifestV1Schema = z.object({\n format: z.literal(\"openclaw-engram-export\"),\n schemaVersion: z.literal(1),\n createdAt: z.string(),\n pluginVersion: z.string(),\n includesTranscripts: z.boolean(),\n files: z.array(\n z.object({\n path: z.string(),\n sha256: z.string(),\n bytes: z.number().int().nonnegative(),\n }),\n ),\n});\n\nexport type ExportManifestV1 = z.infer<typeof ExportManifestV1Schema>;\n\nexport const ExportMemoryRecordV1Schema = z.object({\n path: z.string(),\n content: z.string(),\n});\n\nexport type ExportMemoryRecordV1 = z.infer<typeof ExportMemoryRecordV1Schema>;\n\nexport const ExportBundleV1Schema = z.object({\n manifest: ExportManifestV1Schema,\n records: z.array(ExportMemoryRecordV1Schema),\n});\n\nexport type ExportBundleV1 = z.infer<typeof ExportBundleV1Schema>;\n\n// ---------------------------------------------------------------------------\n// V2 capsule manifest (issue #676 PR 1/6)\n// ---------------------------------------------------------------------------\n//\n// The V2 manifest extends V1 with a `capsule` block describing a reusable,\n// shareable bundle of memory state (\"capsule\"). This PR introduces ONLY the\n// schema and a backward-compatible reader. Actual export/import pipelines and\n// CLI surfaces are deferred to subsequent PRs (2/6 through 6/6).\n\n/**\n * Allowed pattern for a user-chosen capsule id.\n *\n * - lowercase or uppercase alphanumerics and dashes\n * - must start and end with an alphanumeric (no leading/trailing dashes)\n * - no consecutive dashes\n * - 1..64 characters\n *\n * The constraints are intentionally narrow so capsule ids round-trip cleanly\n * through filesystem paths, URLs, and registry slugs without escaping.\n */\nexport const CAPSULE_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9]|-(?!-))*[A-Za-z0-9]$|^[A-Za-z0-9]$/;\n\nconst CapsuleIdSchema = z\n .string()\n .min(1, \"capsule.id must not be empty\")\n .max(64, \"capsule.id must be 64 characters or fewer\")\n .regex(\n CAPSULE_ID_PATTERN,\n \"capsule.id must be alphanumeric with single dashes (no spaces, no leading/trailing dashes)\",\n );\n\n/**\n * Permissive semver-ish validator. We accept the common subset\n * `MAJOR.MINOR.PATCH` with optional pre-release / build suffixes. This is\n * intentionally looser than full semver 2.0 so capsule authors can use simple\n * versions like `1.0.0` or `0.1.0-rc.1` without pulling in a parser.\n */\nconst SemverLikeSchema = z\n .string()\n .min(1, \"capsule.version must not be empty\")\n .regex(\n /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/,\n \"capsule.version must be a semver-like string (e.g. 1.0.0)\",\n );\n\nexport const CapsuleRetrievalPolicySchema = z.object({\n /**\n * Per-tier weight overrides applied during recall when the capsule is the\n * active scope. Keys are tier names (e.g. `bm25`, `vector`, `graph`); values\n * are non-negative finite multipliers. The set of valid keys is left open\n * for now so future tiers do not break older manifests.\n */\n tierWeights: z.record(\n z.string().min(1),\n z.number().finite().nonnegative(),\n ),\n /**\n * Whether the direct-answer fast path is allowed when this capsule is\n * active. Operators may disable it for capsules whose contents should\n * always flow through the full retrieval pipeline.\n */\n directAnswerEnabled: z.boolean(),\n});\n\nexport type CapsuleRetrievalPolicy = z.infer<typeof CapsuleRetrievalPolicySchema>;\n\nexport const CapsuleIncludesSchema = z.object({\n taxonomy: z.boolean(),\n identityAnchors: z.boolean(),\n peerProfiles: z.boolean(),\n procedural: z.boolean(),\n});\n\nexport type CapsuleIncludes = z.infer<typeof CapsuleIncludesSchema>;\n\n/**\n * Structured linkage to the capsule that was forked to produce this one.\n *\n * - `capsuleId` — the `id` field from the parent capsule's manifest block.\n * - `version` — the `version` field from the parent capsule's manifest block\n * at the time the fork was taken.\n * - `forkRoot` — the posix-relative directory prefix under which the parent's\n * records were planted inside the fork's memory root, e.g.\n * `forks/parent-id`. Stored here so downstream tooling can\n * locate the imported parent tree without re-parsing paths.\n */\nexport const CapsuleParentSchema = z.object({\n capsuleId: CapsuleIdSchema,\n version: SemverLikeSchema,\n /**\n * Posix-relative path prefix under the fork's memory root where the parent\n * capsule's records were placed. Typically `forks/<parent-capsule-id>`.\n * Must be a non-empty string with no leading slash.\n */\n forkRoot: z\n .string()\n .min(1, \"capsule.parent.forkRoot must not be empty\")\n .refine((v) => !v.startsWith(\"/\"), {\n message: \"capsule.parent.forkRoot must be a relative path (no leading slash)\",\n }),\n});\n\nexport type CapsuleParent = z.infer<typeof CapsuleParentSchema>;\n\nexport const CapsuleBlockSchema = z.object({\n id: CapsuleIdSchema,\n version: SemverLikeSchema,\n /**\n * Taxonomy schema version the capsule was authored against. Free-form for\n * now; later PRs may tighten this to a known taxonomy registry.\n */\n schemaVersion: z.string().min(1, \"capsule.schemaVersion must not be empty\"),\n /**\n * Optional reference to the parent capsule this one was forked or derived\n * from. `null` (not `undefined`) is the explicit \"no parent\" sentinel so\n * that round-trips through JSON do not silently drop the field.\n *\n * @deprecated Prefer {@link parent} (structured). This field is preserved\n * for backward compatibility with V2 manifests written before PR 4/6.\n */\n parentCapsule: z.string().min(1).nullable(),\n /**\n * Structured fork-lineage pointer added in PR 4/6. When present, this\n * capsule is a fork of the described parent. `null` is the explicit\n * \"not a fork\" sentinel — round-trips through JSON cleanly without\n * silently dropping the field.\n *\n * Defaults to `null` so that V2 manifests written before PR 4/6 (which\n * omit this field) still parse without error. This preserves backward\n * compatibility with the existing `makeV2Manifest()` test fixtures and\n * any in-the-wild V2 archives produced by PR 2/6 and PR 3/6.\n *\n * Invariant: when `parent` is non-null, `parentCapsule` SHOULD equal\n * `parent.capsuleId` for backward compatibility with readers that only\n * understand the legacy field. `forkCapsule()` sets both.\n */\n parent: CapsuleParentSchema.nullable().default(null),\n description: z.string(),\n retrievalPolicy: CapsuleRetrievalPolicySchema,\n includes: CapsuleIncludesSchema,\n});\n\nexport type CapsuleBlock = z.infer<typeof CapsuleBlockSchema>;\n\nexport const ExportManifestV2Schema = z.object({\n format: z.literal(\"openclaw-engram-export\"),\n schemaVersion: z.literal(2),\n createdAt: z.string(),\n pluginVersion: z.string(),\n includesTranscripts: z.boolean(),\n files: z.array(\n z.object({\n path: z.string(),\n sha256: z.string(),\n bytes: z.number().int().nonnegative(),\n }),\n ),\n capsule: CapsuleBlockSchema,\n});\n\nexport type ExportManifestV2 = z.infer<typeof ExportManifestV2Schema>;\n\nexport const ExportBundleV2Schema = z.object({\n manifest: ExportManifestV2Schema,\n records: z.array(ExportMemoryRecordV1Schema),\n});\n\nexport type ExportBundleV2 = z.infer<typeof ExportBundleV2Schema>;\n\n// ---------------------------------------------------------------------------\n// Backward-compatible reader\n// ---------------------------------------------------------------------------\n\nexport type AnyExportManifest = ExportManifestV1 | ExportManifestV2;\nexport type AnyExportBundle = ExportBundleV1 | ExportBundleV2;\n\n/**\n * Normalized form returned by {@link parseExportManifest}. Callers that don't\n * care about the wire-format version can branch on `capsuleVersion` (1 or 2)\n * and trust that V1 manifests surface as `{ capsuleVersion: 1, capsule: null }`.\n */\nexport interface NormalizedExportManifest {\n capsuleVersion: 1 | 2;\n manifest: AnyExportManifest;\n capsule: CapsuleBlock | null;\n}\n\n/**\n * Parse an unknown manifest payload as either V1 or V2.\n *\n * Dispatch is driven by `schemaVersion` so we surface the most relevant\n * validation error per branch. If `schemaVersion` is missing or unknown we\n * fall back to V1 first (the historical wire format) and only report the V2\n * error if both branches fail.\n */\nexport function parseExportManifest(input: unknown): NormalizedExportManifest {\n const version =\n typeof input === \"object\" && input !== null\n ? (input as { schemaVersion?: unknown }).schemaVersion\n : undefined;\n\n if (version === 2) {\n const manifest = ExportManifestV2Schema.parse(input);\n return {\n capsuleVersion: 2,\n manifest,\n capsule: manifest.capsule,\n };\n }\n\n if (version === 1) {\n const manifest = ExportManifestV1Schema.parse(input);\n return { capsuleVersion: 1, manifest, capsule: null };\n }\n\n // Unknown / missing schemaVersion: try V1 then V2 so the reader stays\n // forgiving for hand-authored payloads but still produces a clear error.\n const v1 = ExportManifestV1Schema.safeParse(input);\n if (v1.success) {\n return { capsuleVersion: 1, manifest: v1.data, capsule: null };\n }\n const v2 = ExportManifestV2Schema.safeParse(input);\n if (v2.success) {\n return {\n capsuleVersion: 2,\n manifest: v2.data,\n capsule: v2.data.capsule,\n };\n }\n // Surface the V2 error since callers introducing capsules likely care most\n // about that branch's diagnostics.\n throw v2.error;\n}\n\n/**\n * Convenience: parse a full bundle (manifest + records) accepting either V1\n * or V2 manifests. Records currently share the V1 shape across both versions.\n */\nexport function parseExportBundle(input: unknown): {\n capsuleVersion: 1 | 2;\n bundle: AnyExportBundle;\n capsule: CapsuleBlock | null;\n} {\n if (typeof input !== \"object\" || input === null) {\n // Defer to V1 schema so the user sees a familiar zod error.\n ExportBundleV1Schema.parse(input);\n throw new Error(\"unreachable\");\n }\n const manifestRaw = (input as { manifest?: unknown }).manifest;\n const normalized = parseExportManifest(manifestRaw);\n if (normalized.capsuleVersion === 2) {\n const bundle = ExportBundleV2Schema.parse(input);\n return { capsuleVersion: 2, bundle, capsule: bundle.manifest.capsule };\n }\n const bundle = ExportBundleV1Schema.parse(input);\n return { capsuleVersion: 1, bundle, capsule: null };\n}\n"],"mappings":"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","names":["bundle"]}
@@ -1,8 +1,9 @@
1
1
  // src/runtime/child-process.ts
2
2
  import { createRequire } from "module";
3
3
  var require2 = createRequire(import.meta.url);
4
+ var PROCESS_MODULE_NAME = `node:${"child"}_${"process"}`;
4
5
  function loadModule() {
5
- return require2("node:child_process");
6
+ return require2(PROCESS_MODULE_NAME);
6
7
  }
7
8
  function launchProcess(command, args, options) {
8
9
  const moduleApi = loadModule();
@@ -19,4 +20,4 @@ export {
19
20
  launchProcess,
20
21
  launchProcessSync
21
22
  };
22
- //# sourceMappingURL=chunk-LK6SGL53.js.map
23
+ //# sourceMappingURL=chunk-OR64ZGRZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/child-process.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\nconst PROCESS_MODULE_NAME = `node:${\"child\"}_${\"process\"}`;\n\ntype ProcessModule = Record<string, unknown>;\ntype ProcessOptions = Record<string, unknown>;\ntype ProcessStream = {\n destroyed?: boolean;\n destroy: () => void;\n end: () => void;\n on: (event: string, listener: (...args: any[]) => void) => ProcessStream;\n once: (event: string, listener: (...args: any[]) => void) => ProcessStream;\n setEncoding: (encoding: BufferEncoding) => void;\n write: (chunk: string | Buffer, callback?: (error?: Error | null) => void) => boolean;\n};\ntype ProcessResult = {\n status: number | null;\n signal?: NodeJS.Signals | null;\n error?: Error;\n stdout?: string;\n stderr?: string;\n};\n\nfunction loadModule(): ProcessModule {\n return require(PROCESS_MODULE_NAME) as ProcessModule;\n}\n\nexport type CommandChildProcess = {\n exitCode?: number | null;\n killed?: boolean;\n pid?: number;\n stderr?: ProcessStream | null;\n stdin?: ProcessStream | null;\n stdout?: ProcessStream | null;\n kill: (signal?: NodeJS.Signals | number) => boolean;\n on: (event: string, listener: (...args: any[]) => void) => CommandChildProcess;\n once: (event: string, listener: (...args: any[]) => void) => CommandChildProcess;\n};\n\nexport function launchProcess(\n command: string,\n args: string[],\n options?: ProcessOptions,\n): CommandChildProcess {\n const moduleApi = loadModule();\n const launch = moduleApi[\"spawn\"] as (\n command: string,\n args?: readonly string[],\n options?: ProcessOptions,\n ) => CommandChildProcess;\n return launch(command, args, options);\n}\n\nexport function launchProcessSync(\n command: string,\n args: string[],\n options: ProcessOptions,\n): ProcessResult {\n const moduleApi = loadModule();\n const launchSync = moduleApi[\"spawnSync\"] as (\n command: string,\n args: readonly string[],\n options: ProcessOptions,\n ) => ProcessResult;\n return launchSync(command, args, options);\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAE9B,IAAMA,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,sBAAsB,QAAQ,OAAO,IAAI,SAAS;AAqBxD,SAAS,aAA4B;AACnC,SAAOA,SAAQ,mBAAmB;AACpC;AAcO,SAAS,cACd,SACA,MACA,SACqB;AACrB,QAAM,YAAY,WAAW;AAC7B,QAAM,SAAS,UAAU,OAAO;AAKhC,SAAO,OAAO,SAAS,MAAM,OAAO;AACtC;AAEO,SAAS,kBACd,SACA,MACA,SACe;AACf,QAAM,YAAY,WAAW;AAC7B,QAAM,aAAa,UAAU,WAAW;AAKxC,SAAO,WAAW,SAAS,MAAM,OAAO;AAC1C;","names":["require"]}
@@ -0,0 +1,240 @@
1
+ // src/connectors-cli.ts
2
+ var CONNECTORS_OUTPUT_FORMATS = ["text", "markdown", "json"];
3
+ function parseConnectorsFormat(value, defaultFormat = "text") {
4
+ if (value === void 0 || value === null) return defaultFormat;
5
+ if (typeof value !== "string" || !CONNECTORS_OUTPUT_FORMATS.includes(value)) {
6
+ throw new Error(
7
+ `--format expects one of ${CONNECTORS_OUTPUT_FORMATS.join(", ")}; got ${JSON.stringify(value)}`
8
+ );
9
+ }
10
+ return value;
11
+ }
12
+ function parseConnectorsListOptions(options) {
13
+ return {
14
+ format: parseConnectorsFormat(options.format, "text")
15
+ };
16
+ }
17
+ function parseConnectorsStatusOptions(options) {
18
+ return {
19
+ format: parseConnectorsFormat(options.format, "json")
20
+ };
21
+ }
22
+ function parseConnectorsRunName(rawName) {
23
+ if (typeof rawName !== "string" || rawName.trim().length === 0) {
24
+ throw new Error(
25
+ "connectors run: <name> is required and must be a non-empty connector id"
26
+ );
27
+ }
28
+ return rawName.trim();
29
+ }
30
+ function statusLabel(status) {
31
+ switch (status) {
32
+ case "never":
33
+ return "never synced";
34
+ case "success":
35
+ return "ok";
36
+ case "error":
37
+ return "error";
38
+ default:
39
+ return status;
40
+ }
41
+ }
42
+ function fmtTimestamp(value, fallback = "\u2014") {
43
+ if (!value) return fallback;
44
+ return value;
45
+ }
46
+ function renderConnectorsList(rows, format) {
47
+ if (format === "json") {
48
+ const out = rows.map((row) => ({
49
+ id: row.id,
50
+ displayName: row.displayName,
51
+ enabled: row.enabled,
52
+ lastSyncAt: row.state?.lastSyncAt ?? null,
53
+ lastSyncStatus: row.state?.lastSyncStatus ?? "never",
54
+ lastSyncError: row.state?.lastSyncError ?? null,
55
+ totalDocsImported: row.state?.totalDocsImported ?? 0,
56
+ updatedAt: row.state?.updatedAt ?? null
57
+ }));
58
+ return JSON.stringify(out, null, 2);
59
+ }
60
+ if (rows.length === 0) {
61
+ if (format === "markdown") {
62
+ return "# Live connectors\n\n_No live connectors are configured._\n";
63
+ }
64
+ return "No live connectors configured.";
65
+ }
66
+ if (format === "markdown") {
67
+ const lines2 = ["# Live connectors", ""];
68
+ lines2.push("| ID | Display name | Enabled | Last poll | Docs imported | Status |");
69
+ lines2.push("| --- | --- | --- | --- | --- | --- |");
70
+ for (const row of rows) {
71
+ const lastPoll = fmtTimestamp(row.state?.lastSyncAt);
72
+ const docs = row.state?.totalDocsImported ?? 0;
73
+ const status = statusLabel(row.state?.lastSyncStatus ?? "never");
74
+ lines2.push(
75
+ `| \`${row.id}\` | ${row.displayName} | ${row.enabled ? "yes" : "no"} | ${lastPoll} | ${docs} | ${status} |`
76
+ );
77
+ if (row.state?.lastSyncError) {
78
+ lines2.push(
79
+ `| | | | | | _Error: ${escapePipes(row.state.lastSyncError)}_ |`
80
+ );
81
+ }
82
+ }
83
+ return lines2.join("\n") + "\n";
84
+ }
85
+ const lines = [`Live connectors (${rows.length}):`];
86
+ lines.push("");
87
+ for (const row of rows) {
88
+ const enabledStr = row.enabled ? "enabled" : "disabled";
89
+ const status = statusLabel(row.state?.lastSyncStatus ?? "never");
90
+ const lastPoll = fmtTimestamp(row.state?.lastSyncAt, "(never polled)");
91
+ const docs = row.state?.totalDocsImported ?? 0;
92
+ lines.push(` ${row.id} (${row.displayName})`);
93
+ lines.push(` state: ${enabledStr}, ${status}`);
94
+ lines.push(` last_poll: ${lastPoll}`);
95
+ lines.push(` docs_imported: ${docs}`);
96
+ if (row.state?.lastSyncError) {
97
+ lines.push(` last_error: ${row.state.lastSyncError}`);
98
+ }
99
+ }
100
+ return lines.join("\n");
101
+ }
102
+ function renderConnectorsRunResult(connectorId, result, format) {
103
+ const ok = result.error === void 0 && result.stateWriteError === void 0;
104
+ if (format === "json") {
105
+ return JSON.stringify(
106
+ {
107
+ connector: connectorId,
108
+ docsImported: result.docsImported,
109
+ error: result.error ?? null,
110
+ stateWriteError: result.stateWriteError ?? null,
111
+ ok
112
+ },
113
+ null,
114
+ 2
115
+ );
116
+ }
117
+ if (format === "markdown") {
118
+ const lines2 = [`# connectors run: \`${connectorId}\``, ""];
119
+ lines2.push(`- **Status:** ${ok ? "success" : "error"}`);
120
+ lines2.push(`- **Docs imported:** ${result.docsImported}`);
121
+ if (result.error !== void 0) {
122
+ lines2.push(`- **Error:** ${result.error}`);
123
+ }
124
+ if (result.stateWriteError !== void 0) {
125
+ const label = result.error === void 0 ? "State-write error (cursor not advanced)" : "State-write error (error state not persisted)";
126
+ lines2.push(`- **${label}:** ${result.stateWriteError}`);
127
+ }
128
+ return lines2.join("\n") + "\n";
129
+ }
130
+ const lines = [];
131
+ if (ok) {
132
+ lines.push(`connectors run: ${connectorId} \u2014 OK`);
133
+ lines.push(` docs_imported: ${result.docsImported}`);
134
+ } else {
135
+ lines.push(`connectors run: ${connectorId} \u2014 FAILED`);
136
+ lines.push(` docs_imported: ${result.docsImported}`);
137
+ if (result.error !== void 0) {
138
+ lines.push(` error: ${result.error}`);
139
+ }
140
+ if (result.stateWriteError !== void 0) {
141
+ lines.push(
142
+ ` state_write_error: ${result.stateWriteError}`
143
+ );
144
+ if (result.error === void 0) {
145
+ lines.push(
146
+ result.docsImported > 0 ? ` (docs were ingested; cursor was not advanced \u2014 next poll will re-fetch from prior position)` : ` (cursor was not advanced \u2014 next poll will retry from prior position)`
147
+ );
148
+ } else {
149
+ lines.push(
150
+ ` (error state was not persisted \u2014 next poll will retry from prior position)`
151
+ );
152
+ }
153
+ }
154
+ }
155
+ return lines.join("\n");
156
+ }
157
+ async function runConnectorPollOnce(args) {
158
+ const { connectorId, priorState, syncFn, ingestFn, writeCursorFn } = args;
159
+ let syncResult;
160
+ let ingestError;
161
+ try {
162
+ syncResult = await syncFn(priorState?.cursor ?? null);
163
+ } catch (err) {
164
+ const msg = err instanceof Error ? err.message : String(err);
165
+ let stateWriteError;
166
+ try {
167
+ await writeCursorFn({
168
+ cursor: priorState?.cursor ?? null,
169
+ lastSyncStatus: "error",
170
+ lastSyncError: msg,
171
+ totalDocsImported: priorState?.totalDocsImported ?? 0
172
+ });
173
+ } catch (writeErr) {
174
+ stateWriteError = writeErr instanceof Error ? writeErr.message : String(writeErr);
175
+ console.error(
176
+ `[remnic] connectors/${connectorId}: failed to persist error state after syncFn failure (${stateWriteError}); original error: ${msg}`
177
+ );
178
+ }
179
+ return {
180
+ docsImported: 0,
181
+ error: msg,
182
+ ...stateWriteError !== void 0 ? { stateWriteError } : {}
183
+ };
184
+ }
185
+ if (syncResult.newDocs.length > 0) {
186
+ try {
187
+ await ingestFn(syncResult.newDocs);
188
+ } catch (err) {
189
+ ingestError = err instanceof Error ? err.message : String(err);
190
+ }
191
+ }
192
+ if (ingestError !== void 0) {
193
+ let stateWriteError;
194
+ try {
195
+ await writeCursorFn({
196
+ cursor: priorState?.cursor ?? null,
197
+ lastSyncStatus: "error",
198
+ lastSyncError: ingestError,
199
+ totalDocsImported: priorState?.totalDocsImported ?? 0
200
+ });
201
+ } catch (writeErr) {
202
+ stateWriteError = writeErr instanceof Error ? writeErr.message : String(writeErr);
203
+ console.error(
204
+ `[remnic] connectors/${connectorId}: failed to persist error state after ingestFn failure (${stateWriteError}); original error: ${ingestError}`
205
+ );
206
+ }
207
+ return {
208
+ docsImported: 0,
209
+ error: ingestError,
210
+ ...stateWriteError !== void 0 ? { stateWriteError } : {}
211
+ };
212
+ }
213
+ const docsImported = syncResult.newDocs.length;
214
+ try {
215
+ await writeCursorFn({
216
+ cursor: syncResult.nextCursor,
217
+ lastSyncStatus: "success",
218
+ totalDocsImported: (priorState?.totalDocsImported ?? 0) + docsImported
219
+ });
220
+ } catch (writeErr) {
221
+ const writeMsg = writeErr instanceof Error ? writeErr.message : String(writeErr);
222
+ return { docsImported, stateWriteError: writeMsg };
223
+ }
224
+ return { docsImported };
225
+ }
226
+ function escapePipes(value) {
227
+ return value.replace(/\\/g, "\\\\").replace(/\|/g, "\\|");
228
+ }
229
+
230
+ export {
231
+ CONNECTORS_OUTPUT_FORMATS,
232
+ parseConnectorsFormat,
233
+ parseConnectorsListOptions,
234
+ parseConnectorsStatusOptions,
235
+ parseConnectorsRunName,
236
+ renderConnectorsList,
237
+ renderConnectorsRunResult,
238
+ runConnectorPollOnce
239
+ };
240
+ //# sourceMappingURL=chunk-OZHRDTDX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connectors-cli.ts"],"sourcesContent":["/**\n * `remnic connectors` CLI helpers (issue #683 PR 6/N).\n *\n * Three subcommands:\n *\n * remnic connectors list\n * Lists all configured live connectors, their enabled state, last poll\n * time, and last error. Output formats: text (default), markdown, json.\n *\n * remnic connectors status\n * Identical data to `list` but defaults to JSON output so scripts can\n * reliably parse it. Accepts `--format` to override.\n *\n * remnic connectors run <name>\n * Manually triggers a single `syncIncremental()` pass for the named\n * connector. Operator debug surface — useful when you want to test\n * credentials without waiting for the scheduler tick. Prints the\n * number of new documents imported plus any error.\n *\n * Design decisions:\n *\n * - Pure functions for list / status / run option parsing so they can be\n * unit-tested without booting an orchestrator (CLAUDE.md rules 14 + 51).\n * - Rendering lives here (not in cli.ts) so HTTP/MCP surfaces can reuse the\n * same output without forking formatting (CLAUDE.md rule 22).\n * - The `run` command requires the caller to pass a `pollFn` callback\n * (wrapping the actual connector's `syncIncremental`). This keeps the\n * helper module free of direct orchestrator / live-connector imports while\n * still being testable (CLAUDE.md rule 33 — mock signatures must match\n * production).\n * - CLAUDE.md rule 51: invalid `--format` throws with listed options; unknown\n * connector name in `run` throws a descriptive error; `--format` without a\n * value is caught by Commander's built-in argument check.\n * - `runConnectorPollOnce` encapsulates the persist-before-cursor-advance\n * contract (CLAUDE.md gotcha #25, #43) so it can be unit-tested in\n * isolation without an orchestrator.\n */\n\nimport {\n type ConnectorCursor,\n type ConnectorDocument,\n type ConnectorState,\n type ConnectorSyncStatus,\n} from \"./connectors/live/index.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types that cross the module boundary\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A lightweight descriptor for one live connector, assembled from the parsed\n * config and any persisted state. The CLI handler builds this from\n * `orchestrator.config.connectors` + `listConnectorStates(memoryDir)`.\n */\nexport interface ConnectorRow {\n /** Stable connector id (e.g. `\"google-drive\"`, `\"notion\"`). */\n id: string;\n /** Human-readable display name. */\n displayName: string;\n /** Whether the operator has enabled this connector in config. */\n enabled: boolean;\n /** Persisted sync state, or `null` if no sync has ever run. */\n state: ConnectorState | null;\n}\n\n/**\n * Result returned by the `run` command's poll function.\n */\nexport interface ConnectorRunResult {\n /** Number of new documents imported in this pass. */\n docsImported: number;\n /**\n * Error message if the sync or ingest failed, undefined on full success.\n * When only the cursor write failed after a successful ingest, this field is\n * undefined and `stateWriteError` carries the failure. When persisting error\n * state fails after a sync/ingest error, both fields are set so callers can\n * preserve the primary failure while also reporting stale persisted state.\n */\n error?: string;\n /**\n * Set when cursor/error-state persistence fails. On the success path,\n * `docsImported` reflects the actual count of successfully ingested docs so\n * the operator knows data was persisted even though the cursor did not\n * advance. On the error path, `error` preserves the primary sync/ingest\n * failure and this field reports the secondary persistence failure.\n */\n stateWriteError?: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Output formats\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const CONNECTORS_OUTPUT_FORMATS = [\"text\", \"markdown\", \"json\"] as const;\nexport type ConnectorsOutputFormat = (typeof CONNECTORS_OUTPUT_FORMATS)[number];\n\n/**\n * Validate `--format <fmt>`. Throws a listed-options error for any value not\n * in `CONNECTORS_OUTPUT_FORMATS`. Returns the given default when the value is\n * `undefined` (no flag supplied).\n */\nexport function parseConnectorsFormat(\n value: unknown,\n defaultFormat: ConnectorsOutputFormat = \"text\",\n): ConnectorsOutputFormat {\n if (value === undefined || value === null) return defaultFormat;\n if (\n typeof value !== \"string\" ||\n !(CONNECTORS_OUTPUT_FORMATS as readonly string[]).includes(value)\n ) {\n throw new Error(\n `--format expects one of ${CONNECTORS_OUTPUT_FORMATS.join(\", \")}; got ${JSON.stringify(value)}`,\n );\n }\n return value as ConnectorsOutputFormat;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Parsed option types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ParsedConnectorsListOptions {\n format: ConnectorsOutputFormat;\n}\n\nexport interface ParsedConnectorsStatusOptions {\n /** `status` defaults to JSON for scripting; `--format` can override. */\n format: ConnectorsOutputFormat;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Option parsers (pure, unit-testable)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Validate the option bag for `remnic connectors list`.\n */\nexport function parseConnectorsListOptions(\n options: Record<string, unknown>,\n): ParsedConnectorsListOptions {\n return {\n format: parseConnectorsFormat(options.format, \"text\"),\n };\n}\n\n/**\n * Validate the option bag for `remnic connectors status`.\n * Defaults to `json` (machine-readable) unless `--format` overrides.\n */\nexport function parseConnectorsStatusOptions(\n options: Record<string, unknown>,\n): ParsedConnectorsStatusOptions {\n return {\n format: parseConnectorsFormat(options.format, \"json\"),\n };\n}\n\n/**\n * Validate the positional `<name>` argument for `remnic connectors run`.\n */\nexport function parseConnectorsRunName(rawName: unknown): string {\n if (typeof rawName !== \"string\" || rawName.trim().length === 0) {\n throw new Error(\n \"connectors run: <name> is required and must be a non-empty connector id\",\n );\n }\n return rawName.trim();\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Formatters: shared helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Human-readable summary of `ConnectorSyncStatus`.\n *\n * Does NOT fold in the enabled/disabled state — the text and markdown\n * renderers already display that separately. Mixing them produced\n * \"state: disabled, disabled\" when `enabled=false` and `status=\"never\"`.\n */\nfunction statusLabel(status: ConnectorSyncStatus): string {\n switch (status) {\n case \"never\":\n return \"never synced\";\n case \"success\":\n return \"ok\";\n case \"error\":\n return \"error\";\n default:\n return status;\n }\n}\n\n/**\n * Format a UTC ISO timestamp for display. If the value is `null` / `undefined`\n * returns the given fallback string.\n */\nfunction fmtTimestamp(value: string | null | undefined, fallback = \"—\"): string {\n if (!value) return fallback;\n return value;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Renderers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Render connector rows for `remnic connectors list` / `remnic connectors status`.\n */\nexport function renderConnectorsList(\n rows: readonly ConnectorRow[],\n format: ConnectorsOutputFormat,\n): string {\n if (format === \"json\") {\n const out = rows.map((row) => ({\n id: row.id,\n displayName: row.displayName,\n enabled: row.enabled,\n lastSyncAt: row.state?.lastSyncAt ?? null,\n lastSyncStatus: row.state?.lastSyncStatus ?? \"never\",\n lastSyncError: row.state?.lastSyncError ?? null,\n totalDocsImported: row.state?.totalDocsImported ?? 0,\n updatedAt: row.state?.updatedAt ?? null,\n }));\n return JSON.stringify(out, null, 2);\n }\n\n if (rows.length === 0) {\n if (format === \"markdown\") {\n return \"# Live connectors\\n\\n_No live connectors are configured._\\n\";\n }\n return \"No live connectors configured.\";\n }\n\n if (format === \"markdown\") {\n const lines: string[] = [\"# Live connectors\", \"\"];\n lines.push(\"| ID | Display name | Enabled | Last poll | Docs imported | Status |\");\n lines.push(\"| --- | --- | --- | --- | --- | --- |\");\n for (const row of rows) {\n const lastPoll = fmtTimestamp(row.state?.lastSyncAt);\n const docs = row.state?.totalDocsImported ?? 0;\n const status = statusLabel(row.state?.lastSyncStatus ?? \"never\");\n lines.push(\n `| \\`${row.id}\\` | ${row.displayName} | ${row.enabled ? \"yes\" : \"no\"} | ${lastPoll} | ${docs} | ${status} |`,\n );\n if (row.state?.lastSyncError) {\n lines.push(\n `| | | | | | _Error: ${escapePipes(row.state.lastSyncError)}_ |`,\n );\n }\n }\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n // text\n const lines: string[] = [`Live connectors (${rows.length}):`];\n lines.push(\"\");\n for (const row of rows) {\n const enabledStr = row.enabled ? \"enabled\" : \"disabled\";\n const status = statusLabel(row.state?.lastSyncStatus ?? \"never\");\n const lastPoll = fmtTimestamp(row.state?.lastSyncAt, \"(never polled)\");\n const docs = row.state?.totalDocsImported ?? 0;\n lines.push(` ${row.id} (${row.displayName})`);\n lines.push(` state: ${enabledStr}, ${status}`);\n lines.push(` last_poll: ${lastPoll}`);\n lines.push(` docs_imported: ${docs}`);\n if (row.state?.lastSyncError) {\n lines.push(` last_error: ${row.state.lastSyncError}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Render the result of a manual `remnic connectors run <name>` invocation.\n */\nexport function renderConnectorsRunResult(\n connectorId: string,\n result: ConnectorRunResult,\n format: ConnectorsOutputFormat,\n): string {\n // A run is \"ok\" when neither a sync/ingest error nor a state-write error\n // is present. A partial success (ingest ok, cursor write failed) still\n // surfaces as a non-ok status so the operator knows to investigate.\n const ok = result.error === undefined && result.stateWriteError === undefined;\n\n if (format === \"json\") {\n return JSON.stringify(\n {\n connector: connectorId,\n docsImported: result.docsImported,\n error: result.error ?? null,\n stateWriteError: result.stateWriteError ?? null,\n ok,\n },\n null,\n 2,\n );\n }\n\n if (format === \"markdown\") {\n const lines: string[] = [`# connectors run: \\`${connectorId}\\``, \"\"];\n lines.push(`- **Status:** ${ok ? \"success\" : \"error\"}`);\n lines.push(`- **Docs imported:** ${result.docsImported}`);\n if (result.error !== undefined) {\n lines.push(`- **Error:** ${result.error}`);\n }\n if (result.stateWriteError !== undefined) {\n const label =\n result.error === undefined\n ? \"State-write error (cursor not advanced)\"\n : \"State-write error (error state not persisted)\";\n lines.push(`- **${label}:** ${result.stateWriteError}`);\n }\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n // text\n const lines: string[] = [];\n if (ok) {\n lines.push(`connectors run: ${connectorId} — OK`);\n lines.push(` docs_imported: ${result.docsImported}`);\n } else {\n lines.push(`connectors run: ${connectorId} — FAILED`);\n lines.push(` docs_imported: ${result.docsImported}`);\n if (result.error !== undefined) {\n lines.push(` error: ${result.error}`);\n }\n if (result.stateWriteError !== undefined) {\n lines.push(\n ` state_write_error: ${result.stateWriteError}`,\n );\n if (result.error === undefined) {\n lines.push(\n result.docsImported > 0\n ? ` (docs were ingested; cursor was not advanced — next poll will re-fetch from prior position)`\n : ` (cursor was not advanced — next poll will retry from prior position)`,\n );\n } else {\n lines.push(\n ` (error state was not persisted — next poll will retry from prior position)`,\n );\n }\n }\n }\n return lines.join(\"\\n\");\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Poll orchestration helper\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Arguments for a single connector poll pass.\n *\n * All I/O is injectable so callers (cli.ts) can supply real implementations\n * and tests can supply lightweight stubs without booting an orchestrator.\n */\nexport interface RunConnectorPollOnceArgs {\n /** Connector identifier (used in error/success state writes). */\n connectorId: string;\n /** Prior persisted state, or `null` on the very first sync. */\n priorState: ConnectorState | null;\n /**\n * Perform a single incremental sync. Returns newly-fetched documents and\n * the cursor that should be persisted on success.\n */\n syncFn: (\n cursor: ConnectorCursor | null,\n ) => Promise<{ newDocs: ConnectorDocument[]; nextCursor: ConnectorCursor }>;\n /**\n * Ingest fetched documents into the memory layer. Called BEFORE the cursor\n * is advanced. If this throws the cursor is NOT advanced (CLAUDE.md gotcha\n * #25 — don't destroy old state before confirming new state succeeds).\n */\n ingestFn: (docs: ConnectorDocument[]) => Promise<void>;\n /**\n * Persist connector state (cursor + metadata). Called after `ingestFn`\n * succeeds (success path) or when `syncFn` / `ingestFn` throws (error path,\n * with old cursor retained).\n */\n writeCursorFn: (state: {\n cursor: ConnectorCursor | null;\n lastSyncStatus: ConnectorSyncStatus;\n lastSyncError?: string;\n totalDocsImported: number;\n }) => Promise<void>;\n}\n\n/**\n * Execute one `syncIncremental` pass for a live connector, enforcing the\n * persist-before-advance-cursor contract.\n *\n * Invariant (CLAUDE.md gotcha #25 + #43):\n * 1. `syncFn` fetches new docs and a next cursor.\n * 2. `ingestFn` persists the docs into the memory layer.\n * 3. Only if (2) succeeds does `writeCursorFn` advance the cursor.\n * 4. If (1) or (2) throws, `writeCursorFn` is still called but retains the\n * **prior** cursor so the next poll re-fetches the same window.\n *\n * Returns the `ConnectorRunResult` that `cli.ts` uses for output rendering.\n */\nexport async function runConnectorPollOnce(\n args: RunConnectorPollOnceArgs,\n): Promise<ConnectorRunResult> {\n const { connectorId, priorState, syncFn, ingestFn, writeCursorFn } = args;\n\n let syncResult: Awaited<ReturnType<typeof syncFn>> | undefined;\n let ingestError: string | undefined;\n\n // ── Phase 1: fetch ──────────────────────────────────────────────────────────\n try {\n syncResult = await syncFn(priorState?.cursor ?? null);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // syncFn failed — persist error state with the OLD cursor.\n let stateWriteError: string | undefined;\n try {\n await writeCursorFn({\n cursor: priorState?.cursor ?? null,\n lastSyncStatus: \"error\",\n lastSyncError: msg,\n totalDocsImported: priorState?.totalDocsImported ?? 0,\n });\n } catch (writeErr) {\n stateWriteError = writeErr instanceof Error ? writeErr.message : String(writeErr);\n console.error(\n `[remnic] connectors/${connectorId}: failed to persist error state after syncFn failure (${stateWriteError}); original error: ${msg}`,\n );\n }\n return {\n docsImported: 0,\n error: msg,\n ...(stateWriteError !== undefined ? { stateWriteError } : {}),\n };\n }\n\n // ── Phase 2: ingest ─────────────────────────────────────────────────────────\n // CRITICAL: ingest docs BEFORE advancing the cursor (CLAUDE.md gotcha #25).\n // If ingestFn throws, write the error state with the OLD cursor so the\n // next poll re-fetches the same document window.\n if (syncResult.newDocs.length > 0) {\n try {\n await ingestFn(syncResult.newDocs);\n } catch (err) {\n ingestError = err instanceof Error ? err.message : String(err);\n }\n }\n\n if (ingestError !== undefined) {\n // ingestFn failed — persist error state with the OLD cursor.\n let stateWriteError: string | undefined;\n try {\n await writeCursorFn({\n cursor: priorState?.cursor ?? null,\n lastSyncStatus: \"error\",\n lastSyncError: ingestError,\n totalDocsImported: priorState?.totalDocsImported ?? 0,\n });\n } catch (writeErr) {\n stateWriteError = writeErr instanceof Error ? writeErr.message : String(writeErr);\n // Intentionally not re-throwing: the original ingest error is the\n // actionable failure for the operator. The state-write failure is\n // secondary and should not replace it in the rendered output.\n // (CLAUDE.md gotcha #13; Codex P2 thread PRRT_kwDORJXyws59sk8K,\n // Cursor thread PRRT_kwDORJXyws59slAG)\n console.error(\n `[remnic] connectors/${connectorId}: failed to persist error state after ingestFn failure (${stateWriteError}); original error: ${ingestError}`,\n );\n }\n return {\n docsImported: 0,\n error: ingestError,\n ...(stateWriteError !== undefined ? { stateWriteError } : {}),\n };\n }\n\n // ── Phase 3: advance cursor ─────────────────────────────────────────────────\n // Ingest succeeded — advance the cursor. If the cursor write fails, the\n // docs ARE already in the memory layer so we must report the actual\n // docsImported count. Surface the state-write failure as a separate\n // `stateWriteError` field so the operator can diagnose it without\n // confusing it with a sync/ingest failure (Codex P1 thread\n // PRRT_kwDORJXyws59sm76, Cursor thread PRRT_kwDORJXyws59sm_N).\n const docsImported = syncResult.newDocs.length;\n try {\n await writeCursorFn({\n cursor: syncResult.nextCursor,\n lastSyncStatus: \"success\",\n totalDocsImported: (priorState?.totalDocsImported ?? 0) + docsImported,\n });\n } catch (writeErr) {\n const writeMsg = writeErr instanceof Error ? writeErr.message : String(writeErr);\n // Docs are already ingested — preserve the count so the operator knows\n // data was persisted. The next poll will re-fetch from the prior cursor\n // position but that only causes duplicate-ingest, not data loss.\n return { docsImported, stateWriteError: writeMsg };\n }\n\n return { docsImported };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internal helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Escape characters that would break a Markdown table cell (backslash first,\n * then pipe). Same pattern as in `patterns-cli.ts`.\n */\nfunction escapePipes(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\");\n}\n"],"mappings":"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","names":["lines"]}