@remnic/core 9.45.3 → 9.45.4

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 (747) hide show
  1. package/dist/abort-error.d.ts +2 -1
  2. package/dist/abort-error.js +3 -1
  3. package/dist/access-admin-ops-surface.d.ts +14 -10
  4. package/dist/access-admin-ops-surface.js +84 -76
  5. package/dist/access-audit.js +2 -2
  6. package/dist/access-authorization-probe.d.ts +14 -10
  7. package/dist/access-authorization-probe.js +85 -77
  8. package/dist/access-boundary.d.ts +15 -11
  9. package/dist/access-boundary.js +84 -76
  10. package/dist/access-citation-namespace.js +2 -2
  11. package/dist/access-cli.js +193 -181
  12. package/dist/access-cli.js.map +1 -1
  13. package/dist/access-coding-context-resolution.d.ts +16 -0
  14. package/dist/access-coding-context-resolution.js +13 -0
  15. package/dist/access-coding-context-resolution.js.map +1 -0
  16. package/dist/access-extraction-force-flush.d.ts +14 -10
  17. package/dist/access-extraction-force-flush.js +84 -76
  18. package/dist/access-health-types.d.ts +2 -1
  19. package/dist/access-http-lcm-compaction.d.ts +16 -12
  20. package/dist/access-http-lcm-compaction.js +3 -3
  21. package/dist/access-http-lifecycle-flush.d.ts +14 -10
  22. package/dist/access-http-lifecycle-flush.js +2 -2
  23. package/dist/access-http-offline-stream.d.ts +123 -0
  24. package/dist/access-http-offline-stream.js +10 -0
  25. package/dist/access-http-offline-stream.js.map +1 -0
  26. package/dist/access-http-query.js +84 -76
  27. package/dist/access-http.d.ts +15 -10
  28. package/dist/access-http.js +105 -92
  29. package/dist/access-identity-continuity-surface.d.ts +9 -8
  30. package/dist/access-identity-continuity-surface.js +84 -76
  31. package/dist/access-lcm-surface.d.ts +14 -10
  32. package/dist/access-lcm-surface.js +84 -76
  33. package/dist/access-mcp-output-schemas.js +1 -1
  34. package/dist/access-mcp.d.ts +14 -10
  35. package/dist/access-mcp.js +95 -83
  36. package/dist/access-memory-search-fanout.d.ts +3 -2
  37. package/dist/{access-namespace-preflight-5yZ4g6F8.d.ts → access-namespace-preflight-CWUDwB4M.d.ts} +1 -1
  38. package/dist/access-namespace-preflight.d.ts +4 -3
  39. package/dist/access-namespace-preflight.js +84 -76
  40. package/dist/access-observe-helpers.d.ts +1 -0
  41. package/dist/access-observe-helpers.js +1 -1
  42. package/dist/access-observe-write-surface.d.ts +16 -10
  43. package/dist/access-observe-write-surface.js +84 -76
  44. package/dist/access-offline-manifest.d.ts +104 -0
  45. package/dist/access-offline-manifest.js +45 -0
  46. package/dist/access-offline-manifest.js.map +1 -0
  47. package/dist/access-operations-batch.js +86 -78
  48. package/dist/access-operations.d.ts +15 -11
  49. package/dist/access-operations.js +91 -80
  50. package/dist/access-recall-concurrency.d.ts +16 -26
  51. package/dist/access-recall-concurrency.js +86 -77
  52. package/dist/access-recall-response.d.ts +18 -14
  53. package/dist/access-recall-response.js +84 -76
  54. package/dist/access-recall-surface.d.ts +29 -24
  55. package/dist/access-recall-surface.js +84 -76
  56. package/dist/access-schema.js +3 -3
  57. package/dist/{access-service-CiJRsgAB.d.ts → access-service-CsU-ljFD.d.ts} +25 -16
  58. package/dist/access-service-helpers.d.ts +14 -10
  59. package/dist/access-service.d.ts +14 -10
  60. package/dist/access-service.js +84 -76
  61. package/dist/access-surface-catalog.d.ts +14 -10
  62. package/dist/access-surface-catalog.js +4 -0
  63. package/dist/access-surface-catalog.js.map +1 -1
  64. package/dist/access-wearables-meetings-surface.d.ts +4 -3
  65. package/dist/action-confidence.d.ts +2 -1
  66. package/dist/active-memory-bridge.d.ts +2 -1
  67. package/dist/active-recall.d.ts +2 -1
  68. package/dist/active-recall.js +10 -8
  69. package/dist/active-recall.js.map +1 -1
  70. package/dist/adapters/index.js +7 -7
  71. package/dist/adapters/registry.js +3 -3
  72. package/dist/{auto-sync-5OE5QOZB.js → auto-sync-UPTUVE4X.js} +6 -6
  73. package/dist/behavior-learner.d.ts +2 -1
  74. package/dist/behavior-learner.js +1 -1
  75. package/dist/behavior-signals.d.ts +2 -1
  76. package/dist/bootstrap.d.ts +9 -8
  77. package/dist/briefing.d.ts +3 -2
  78. package/dist/briefing.js +23 -22
  79. package/dist/buffer-surprise-report.d.ts +2 -1
  80. package/dist/buffer-turn-helpers.d.ts +2 -1
  81. package/dist/buffer.d.ts +3 -2
  82. package/dist/buffer.js +12 -11
  83. package/dist/bulk-import/index.d.ts +4 -3
  84. package/dist/calibration.d.ts +2 -1
  85. package/dist/capabilities.d.ts +2 -1
  86. package/dist/{capsule-merge-IDWJPCWK.js → capsule-merge-Q6AR3XL7.js} +67 -54
  87. package/dist/capsule-merge-Q6AR3XL7.js.map +1 -0
  88. package/dist/{catalog-scBmy0sO.d.ts → catalog-bctMURhN.d.ts} +1 -1
  89. package/dist/causal-behavior.d.ts +2 -1
  90. package/dist/causal-behavior.js +2 -2
  91. package/dist/causal-chain.js +2 -2
  92. package/dist/causal-consolidation.d.ts +2 -1
  93. package/dist/causal-consolidation.js +27 -26
  94. package/dist/causal-consolidation.js.map +1 -1
  95. package/dist/causal-retrieval.js +2 -2
  96. package/dist/causal-trajectory-graph.d.ts +2 -1
  97. package/dist/causal-trajectory.js +1 -1
  98. package/dist/{chunk-VUPTKTDV.js → chunk-2MRHJNWL.js} +3 -3
  99. package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
  100. package/dist/{chunk-5IVLTFOV.js → chunk-44N6ESJ4.js} +2 -2
  101. package/dist/{chunk-WOCNN776.js → chunk-4POAMKV6.js} +100 -41
  102. package/dist/chunk-4POAMKV6.js.map +1 -0
  103. package/dist/{chunk-HO3QBJEY.js → chunk-5546W5SI.js} +2 -2
  104. package/dist/{chunk-U7GW7NE7.js → chunk-5CEECY6P.js} +10 -10
  105. package/dist/{chunk-4UH4BTGK.js → chunk-5SNZSWWR.js} +82 -82
  106. package/dist/{chunk-6CZPDBJS.js → chunk-5U7ID3EZ.js} +3 -3
  107. package/dist/{chunk-GF22HWS2.js → chunk-6NNNURLK.js} +7 -7
  108. package/dist/chunk-773TRRGT.js +36 -0
  109. package/dist/chunk-773TRRGT.js.map +1 -0
  110. package/dist/chunk-7CITSYSH.js +242 -0
  111. package/dist/chunk-7CITSYSH.js.map +1 -0
  112. package/dist/{chunk-227UFSEQ.js → chunk-7RZJWZ46.js} +5 -5
  113. package/dist/{chunk-E5UK4VPE.js → chunk-7SHJHPTY.js} +5 -5
  114. package/dist/{chunk-UVIKWC7M.js → chunk-7YERSTN7.js} +17 -17
  115. package/dist/{chunk-DLVPUX7U.js → chunk-7YKVM5H3.js} +8 -6
  116. package/dist/chunk-7YKVM5H3.js.map +1 -0
  117. package/dist/{chunk-3CE77VAP.js → chunk-A4JMGKCD.js} +87 -74
  118. package/dist/chunk-A4JMGKCD.js.map +1 -0
  119. package/dist/chunk-A5KNZSNA.js +26 -0
  120. package/dist/chunk-A5KNZSNA.js.map +1 -0
  121. package/dist/{chunk-S2NCTZGJ.js → chunk-AJQ57VV3.js} +15 -15
  122. package/dist/chunk-AJQ57VV3.js.map +1 -0
  123. package/dist/{chunk-CUM2BBPN.js → chunk-AUMWZSE7.js} +19 -10
  124. package/dist/chunk-AUMWZSE7.js.map +1 -0
  125. package/dist/{chunk-XYTOI63Z.js → chunk-BGHFOD5A.js} +19 -11
  126. package/dist/chunk-BGHFOD5A.js.map +1 -0
  127. package/dist/{chunk-BUE5E2HL.js → chunk-BGLY7EEM.js} +5 -314
  128. package/dist/chunk-BGLY7EEM.js.map +1 -0
  129. package/dist/chunk-BIPBQQFI.js +44 -0
  130. package/dist/chunk-BIPBQQFI.js.map +1 -0
  131. package/dist/{chunk-S5SLVSVY.js → chunk-BQIFZ2MP.js} +5 -5
  132. package/dist/chunk-BTTPKDIL.js +34 -0
  133. package/dist/{chunk-PVGDJXVK.js.map → chunk-BTTPKDIL.js.map} +1 -1
  134. package/dist/{chunk-E53DSZEN.js → chunk-C26TE27X.js} +3 -3
  135. package/dist/{chunk-LZ4LDKHZ.js → chunk-CLB32OHM.js} +6 -6
  136. package/dist/{chunk-Q6IP2ARR.js → chunk-CSOYVTRX.js} +2 -2
  137. package/dist/{chunk-XOQSEF7X.js → chunk-CVILPI77.js} +6 -6
  138. package/dist/chunk-D3I2MCN7.js +29 -0
  139. package/dist/chunk-D3I2MCN7.js.map +1 -0
  140. package/dist/{chunk-A5OJCXZL.js → chunk-DSUAAZZX.js} +15 -4
  141. package/dist/chunk-DSUAAZZX.js.map +1 -0
  142. package/dist/{chunk-HREE4JHI.js → chunk-DYVMXPCF.js} +486 -287
  143. package/dist/chunk-DYVMXPCF.js.map +1 -0
  144. package/dist/{chunk-J7VGGECD.js → chunk-DZPFMQZ7.js} +1 -1
  145. package/dist/chunk-DZPFMQZ7.js.map +1 -0
  146. package/dist/{chunk-PDLBLTOK.js → chunk-EITZHSX6.js} +9 -9
  147. package/dist/{chunk-D3J5SLQK.js → chunk-EJHEWCGQ.js} +81 -20
  148. package/dist/chunk-EJHEWCGQ.js.map +1 -0
  149. package/dist/{chunk-WUNIWKY4.js → chunk-ELIL2A37.js} +6 -6
  150. package/dist/{chunk-E6PNLPGJ.js → chunk-FZP32336.js} +806 -470
  151. package/dist/chunk-FZP32336.js.map +1 -0
  152. package/dist/{chunk-HZFHQ4AQ.js → chunk-G7A5HLUS.js} +23 -17
  153. package/dist/chunk-G7A5HLUS.js.map +1 -0
  154. package/dist/{chunk-CINZGPSJ.js → chunk-GUMZC2BO.js} +2 -2
  155. package/dist/{chunk-H24WNPA2.js → chunk-GWFSVJ4P.js} +3 -3
  156. package/dist/{chunk-7XC2HX75.js → chunk-GYPQL6XN.js} +157 -16
  157. package/dist/chunk-GYPQL6XN.js.map +1 -0
  158. package/dist/{chunk-TSH56VPU.js → chunk-HAYSYUAB.js} +2 -2
  159. package/dist/{chunk-TDHTVMPG.js → chunk-HFPASSFV.js} +7 -2
  160. package/dist/chunk-HFPASSFV.js.map +1 -0
  161. package/dist/chunk-J2WC5LF4.js +395 -0
  162. package/dist/chunk-J2WC5LF4.js.map +1 -0
  163. package/dist/{chunk-PKNLM44P.js → chunk-JH6BPLOP.js} +9 -9
  164. package/dist/{chunk-KXB4VXHY.js → chunk-JIYDRBVZ.js} +2 -2
  165. package/dist/chunk-JV3C2MNQ.js +74 -0
  166. package/dist/chunk-JV3C2MNQ.js.map +1 -0
  167. package/dist/{chunk-AV5ZEH4M.js → chunk-KVJRXN2E.js} +2 -2
  168. package/dist/{chunk-JVLCVFQ4.js → chunk-KXEFRMCF.js} +3 -3
  169. package/dist/{chunk-WFTIGIIS.js → chunk-L6CQ7WIW.js} +5 -5
  170. package/dist/{chunk-EJUEXZHX.js → chunk-LLJMAULE.js} +2 -2
  171. package/dist/{chunk-N5Z4EVOR.js → chunk-LNEWDF2A.js} +36 -11
  172. package/dist/chunk-LNEWDF2A.js.map +1 -0
  173. package/dist/{chunk-AS7YMSL6.js → chunk-M23RF3LJ.js} +4 -4
  174. package/dist/{chunk-UYLMNVY6.js → chunk-MDISBSYA.js} +16 -9
  175. package/dist/chunk-MDISBSYA.js.map +1 -0
  176. package/dist/{chunk-3F2LKUMU.js → chunk-NIS256NW.js} +2 -2
  177. package/dist/{chunk-YIAA2X3D.js → chunk-NK5RGJ65.js} +3 -3
  178. package/dist/chunk-NLDVVWCL.js +84 -0
  179. package/dist/chunk-NLDVVWCL.js.map +1 -0
  180. package/dist/{chunk-OQ5PRDDS.js → chunk-NTOIP2E6.js} +6 -6
  181. package/dist/{chunk-HLPD7B7P.js → chunk-NUEQKLNB.js} +2 -2
  182. package/dist/{chunk-4J7G5SY4.js → chunk-NZBZ7IS2.js} +72 -24
  183. package/dist/chunk-NZBZ7IS2.js.map +1 -0
  184. package/dist/{chunk-3TBLDMJA.js → chunk-O4KMGRXE.js} +5 -2
  185. package/dist/chunk-O4KMGRXE.js.map +1 -0
  186. package/dist/{chunk-33PLLLL7.js → chunk-P7NGM24P.js} +6 -6
  187. package/dist/{chunk-7TWUCYER.js → chunk-PNRA7FAD.js} +7 -7
  188. package/dist/{chunk-5I4M26Q7.js → chunk-QBSFOKY6.js} +4 -4
  189. package/dist/{chunk-QJAQNXWI.js → chunk-QCECHYZL.js} +76 -79
  190. package/dist/chunk-QCECHYZL.js.map +1 -0
  191. package/dist/{chunk-P4DRWEYC.js → chunk-QVSBTCVP.js} +2 -2
  192. package/dist/{chunk-AAIUERNB.js → chunk-R5RFK3CB.js} +6 -6
  193. package/dist/{chunk-WDISJRMG.js → chunk-RMMVQQA6.js} +2 -2
  194. package/dist/{chunk-KWMXR7XS.js → chunk-S2V7RUCL.js} +8 -1
  195. package/dist/{chunk-KWMXR7XS.js.map → chunk-S2V7RUCL.js.map} +1 -1
  196. package/dist/{chunk-5SM35XZR.js → chunk-S5NZBKKQ.js} +2 -2
  197. package/dist/{chunk-VNA7W7QF.js → chunk-SVH57F5Z.js} +12 -4
  198. package/dist/chunk-SVH57F5Z.js.map +1 -0
  199. package/dist/{chunk-WIPEXG6R.js → chunk-SXIMQLGV.js} +2 -2
  200. package/dist/{chunk-RVLJEII5.js → chunk-SYUBB3WM.js} +256 -187
  201. package/dist/chunk-SYUBB3WM.js.map +1 -0
  202. package/dist/{chunk-OAEQLRCY.js → chunk-TN76AKO3.js} +5 -5
  203. package/dist/{chunk-QN25OCUF.js → chunk-TQ4GD737.js} +5 -5
  204. package/dist/{chunk-VCD4PSK2.js → chunk-TQZ4DVBC.js} +7 -4
  205. package/dist/chunk-TQZ4DVBC.js.map +1 -0
  206. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  207. package/dist/{chunk-DNWXFTLD.js → chunk-TYISDI6B.js} +2 -2
  208. package/dist/{chunk-4LMA77JH.js → chunk-U2VLVBBH.js} +3 -3
  209. package/dist/{chunk-5ZE7QHTK.js → chunk-ULVR5KG7.js} +5 -5
  210. package/dist/{chunk-NVRYW264.js → chunk-UQWIKLQK.js} +18 -15
  211. package/dist/chunk-UQWIKLQK.js.map +1 -0
  212. package/dist/{chunk-YV32N67O.js → chunk-URS5GSM7.js} +1 -1
  213. package/dist/chunk-URS5GSM7.js.map +1 -0
  214. package/dist/{chunk-4B77XSG5.js → chunk-UV72DEZD.js} +5 -5
  215. package/dist/{chunk-S2BBISHU.js → chunk-VANZKHTN.js} +3 -3
  216. package/dist/chunk-VHFXP27N.js +250 -0
  217. package/dist/chunk-VHFXP27N.js.map +1 -0
  218. package/dist/{chunk-3Y224NYC.js → chunk-VYISFWVX.js} +2 -2
  219. package/dist/{chunk-TIHMZFIV.js → chunk-W3IC7QOY.js} +3 -3
  220. package/dist/{chunk-NRV4Y3PM.js → chunk-W4FBGYGK.js} +1 -1
  221. package/dist/{chunk-P2BM76KT.js → chunk-WAS4HV46.js} +174 -43
  222. package/dist/chunk-WAS4HV46.js.map +1 -0
  223. package/dist/{chunk-57QKLRBV.js → chunk-WB7JSQCP.js} +2 -1
  224. package/dist/chunk-WB7JSQCP.js.map +1 -0
  225. package/dist/chunk-WGP57SR3.js +68 -0
  226. package/dist/chunk-WGP57SR3.js.map +1 -0
  227. package/dist/{chunk-ECK75GDJ.js → chunk-WQIHRA5F.js} +43 -24
  228. package/dist/chunk-WQIHRA5F.js.map +1 -0
  229. package/dist/{chunk-MU7ZHSZE.js → chunk-WZFAPHIK.js} +2 -2
  230. package/dist/{chunk-T2TTP3KU.js → chunk-X4IDNPOS.js} +2 -2
  231. package/dist/{chunk-BLAKS3CP.js → chunk-XL3TATMJ.js} +3 -3
  232. package/dist/{chunk-W4XJFLAL.js → chunk-XPRJSHNI.js} +2 -2
  233. package/dist/{chunk-5TFP4CUL.js → chunk-XQ3HXAQH.js} +14 -11
  234. package/dist/chunk-XQ3HXAQH.js.map +1 -0
  235. package/dist/{chunk-VWAXN2BN.js → chunk-XSFHWBQO.js} +93 -31
  236. package/dist/chunk-XSFHWBQO.js.map +1 -0
  237. package/dist/{chunk-DL7ZD3JH.js → chunk-XTAUXTDO.js} +14 -9
  238. package/dist/chunk-XTAUXTDO.js.map +1 -0
  239. package/dist/{chunk-JE7EK33X.js → chunk-Y7HRYCNW.js} +2 -2
  240. package/dist/{chunk-E6EE5B67.js → chunk-YK6BDDHP.js} +4 -4
  241. package/dist/{chunk-ES36HTSC.js → chunk-YLHM5BQQ.js} +3 -3
  242. package/dist/{chunk-RN7DY3FC.js → chunk-YMAQDHQM.js} +31 -12
  243. package/dist/chunk-YMAQDHQM.js.map +1 -0
  244. package/dist/{chunk-ULARSG5Z.js → chunk-YN6ASZUG.js} +10 -8
  245. package/dist/{chunk-ULARSG5Z.js.map → chunk-YN6ASZUG.js.map} +1 -1
  246. package/dist/{chunk-IKKWIPYN.js → chunk-YYQAKIDJ.js} +37 -1
  247. package/dist/chunk-YYQAKIDJ.js.map +1 -0
  248. package/dist/{chunk-BJKPPZ6Z.js → chunk-ZFGZ6PZ2.js} +2 -2
  249. package/dist/{chunk-CJ2ZR7UA.js → chunk-ZI32MKDW.js} +267 -214
  250. package/dist/chunk-ZI32MKDW.js.map +1 -0
  251. package/dist/{chunk-64UDOIMI.js → chunk-ZLQ37WJX.js} +2 -2
  252. package/dist/chunk-ZMAYKGPN.js +351 -0
  253. package/dist/chunk-ZMAYKGPN.js.map +1 -0
  254. package/dist/{cli-BUGN3d6_.d.ts → cli-BBHDtG36.d.ts} +5 -5
  255. package/dist/cli.d.ts +16 -12
  256. package/dist/cli.js +138 -124
  257. package/dist/compounding/engine.d.ts +3 -2
  258. package/dist/compounding/engine.js +24 -23
  259. package/dist/compounding/preference-consolidator.d.ts +2 -1
  260. package/dist/compression-optimizer.d.ts +2 -1
  261. package/dist/config.d.ts +2 -1
  262. package/dist/config.js +10 -8
  263. package/dist/connectors/codex-materialize-runner.d.ts +2 -1
  264. package/dist/connectors/codex-materialize-runner.js +23 -22
  265. package/dist/connectors/codex-materialize.d.ts +2 -1
  266. package/dist/connectors/index.d.ts +2 -1
  267. package/dist/connectors/index.js +26 -25
  268. package/dist/consolidation-provenance-check.d.ts +3 -2
  269. package/dist/consolidation-provenance-check.js +4 -4
  270. package/dist/consolidation-undo.d.ts +3 -2
  271. package/dist/consolidation-undo.js +10 -7
  272. package/dist/consolidation-undo.js.map +1 -1
  273. package/dist/contradiction/index.d.ts +3 -2
  274. package/dist/converge-config.d.ts +2 -1
  275. package/dist/convergence-refresh.d.ts +4 -3
  276. package/dist/convergence-refresh.js +27 -26
  277. package/dist/conversation-index/backend.d.ts +2 -1
  278. package/dist/conversation-index/backend.js +2 -2
  279. package/dist/conversation-index/chunker.d.ts +2 -1
  280. package/dist/conversation-index/faiss-adapter.d.ts +2 -1
  281. package/dist/conversation-index/indexer.d.ts +2 -1
  282. package/dist/conversation-index/search.d.ts +2 -1
  283. package/dist/corpus-watermark.d.ts +2 -1
  284. package/dist/corpus-watermark.js +42 -41
  285. package/dist/day-summary.d.ts +2 -1
  286. package/dist/delinearize.d.ts +2 -1
  287. package/dist/direct-answer-wiring.d.ts +2 -1
  288. package/dist/direct-answer-wiring.js +2 -2
  289. package/dist/direct-answer.d.ts +2 -1
  290. package/dist/embedding-fallback.d.ts +2 -1
  291. package/dist/embedding-fallback.js +2 -2
  292. package/dist/enrichment/index.d.ts +2 -1
  293. package/dist/entity-retrieval-boundaries.js +1 -1
  294. package/dist/entity-retrieval.d.ts +3 -2
  295. package/dist/entity-retrieval.js +24 -23
  296. package/dist/entity-schema.d.ts +2 -1
  297. package/dist/explicit-capture.d.ts +9 -8
  298. package/dist/explicit-capture.js +11 -9
  299. package/dist/external-wiki-access.d.ts +127 -0
  300. package/dist/external-wiki-access.js +186 -0
  301. package/dist/external-wiki-access.js.map +1 -0
  302. package/dist/external-wiki-cli.d.ts +13 -0
  303. package/dist/external-wiki-cli.js +96 -0
  304. package/dist/external-wiki-cli.js.map +1 -0
  305. package/dist/external-wiki-collection-registration.d.ts +39 -0
  306. package/dist/external-wiki-collection-registration.js +79 -0
  307. package/dist/external-wiki-collection-registration.js.map +1 -0
  308. package/dist/external-wiki-collection.d.ts +50 -0
  309. package/dist/external-wiki-collection.js +387 -0
  310. package/dist/external-wiki-collection.js.map +1 -0
  311. package/dist/external-wiki-config.d.ts +13 -0
  312. package/dist/external-wiki-config.js +13 -0
  313. package/dist/external-wiki-config.js.map +1 -0
  314. package/dist/external-wiki-guard.d.ts +11 -0
  315. package/dist/external-wiki-guard.js +18 -0
  316. package/dist/external-wiki-guard.js.map +1 -0
  317. package/dist/external-wiki-mcp-tools.d.ts +123 -0
  318. package/dist/external-wiki-mcp-tools.js +8 -0
  319. package/dist/external-wiki-mcp-tools.js.map +1 -0
  320. package/dist/external-wiki-search.d.ts +42 -0
  321. package/dist/external-wiki-search.js +11 -0
  322. package/dist/external-wiki-search.js.map +1 -0
  323. package/dist/external-wiki.d.ts +43 -0
  324. package/dist/external-wiki.js +16 -0
  325. package/dist/external-wiki.js.map +1 -0
  326. package/dist/extraction-error-classification.d.ts +2 -1
  327. package/dist/extraction-faithfulness.d.ts +2 -1
  328. package/dist/extraction-judge-telemetry.d.ts +2 -1
  329. package/dist/extraction-judge-training.d.ts +2 -1
  330. package/dist/extraction-judge.d.ts +2 -1
  331. package/dist/extraction-liveness.d.ts +2 -1
  332. package/dist/extraction-source-grounding-helpers.d.ts +5 -3
  333. package/dist/extraction-source-grounding-helpers.js +1 -1
  334. package/dist/extraction-source-grounding-rules.d.ts +2 -1
  335. package/dist/extraction-source-grounding-rules.js +2 -2
  336. package/dist/extraction-source-grounding.d.ts +2 -1
  337. package/dist/extraction-source-grounding.js +5 -5
  338. package/dist/extraction.d.ts +2 -1
  339. package/dist/extraction.js +45 -43
  340. package/dist/fallback-llm.d.ts +2 -1
  341. package/dist/graph-dashboard-diff.d.ts +2 -1
  342. package/dist/graph-dashboard-key.d.ts +2 -1
  343. package/dist/graph-dashboard-parser.d.ts +2 -1
  344. package/dist/graph-edge-reinforcement.d.ts +2 -1
  345. package/dist/graph-snapshot.d.ts +2 -1
  346. package/dist/graph.d.ts +2 -1
  347. package/dist/harmonic-retrieval.js +2 -2
  348. package/dist/importance.d.ts +2 -1
  349. package/dist/importers/index.d.ts +2 -1
  350. package/dist/in-flight-reads.d.ts +2 -1
  351. package/dist/index.d.ts +362 -350
  352. package/dist/index.js +291 -259
  353. package/dist/intent.d.ts +2 -1
  354. package/dist/lcm/engine.d.ts +2 -1
  355. package/dist/lcm/engine.js +3 -3
  356. package/dist/lcm/index.d.ts +2 -1
  357. package/dist/lcm/index.js +8 -8
  358. package/dist/lcm/tools.d.ts +2 -1
  359. package/dist/lifecycle.d.ts +2 -1
  360. package/dist/live-connectors-runner.d.ts +2 -1
  361. package/dist/local-llm.d.ts +2 -1
  362. package/dist/local-llm.js +2 -2
  363. package/dist/local-model-endpoint.d.ts +2 -1
  364. package/dist/maintenance/memory-governance.d.ts +2 -1
  365. package/dist/maintenance/memory-governance.js +24 -23
  366. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
  367. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +24 -23
  368. package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
  369. package/dist/maintenance/rebuild-memory-projection.js +26 -25
  370. package/dist/{maintenance-LbuS2rUA.d.ts → maintenance-D2mveyCd.d.ts} +3 -3
  371. package/dist/mcp-memory-inspector-app.d.ts +14 -10
  372. package/dist/mcp-read-only-tools.js +1 -1
  373. package/dist/memory-action-policy.d.ts +2 -1
  374. package/dist/memory-cache.d.ts +2 -1
  375. package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
  376. package/dist/memory-projection-store.d.ts +2 -1
  377. package/dist/memory-provenance.d.ts +2 -1
  378. package/dist/memory-worth-outcomes.d.ts +3 -2
  379. package/dist/models-json.d.ts +2 -1
  380. package/dist/namespaces/migrate.d.ts +4 -3
  381. package/dist/namespaces/migrate.js +40 -39
  382. package/dist/namespaces/principal.d.ts +2 -1
  383. package/dist/namespaces/search.d.ts +2 -1
  384. package/dist/namespaces/search.js +18 -18
  385. package/dist/namespaces/storage.d.ts +4 -3
  386. package/dist/namespaces/storage.js +23 -22
  387. package/dist/native-knowledge.d.ts +2 -1
  388. package/dist/offline-sync-impression-drain.d.ts +2 -1
  389. package/dist/offline-sync-impression-drain.js +11 -9
  390. package/dist/offline-sync.d.ts +29 -3
  391. package/dist/offline-sync.js +6 -2
  392. package/dist/operator-doctor-corpus.d.ts +2 -1
  393. package/dist/operator-doctor-corpus.js +45 -44
  394. package/dist/operator-doctor-replica.d.ts +2 -1
  395. package/dist/operator-doctor-replica.js +3 -3
  396. package/dist/operator-toolkit.d.ts +4 -3
  397. package/dist/operator-toolkit.js +59 -55
  398. package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
  399. package/dist/orchestration/maintenance.d.ts +5 -4
  400. package/dist/orchestration/maintenance.js +36 -33
  401. package/dist/{orchestrator-rHiWt32X.d.ts → orchestrator-DJYlwiUv.d.ts} +14 -7
  402. package/dist/orchestrator.d.ts +9 -8
  403. package/dist/orchestrator.js +201 -189
  404. package/dist/page-versioning.js +3 -3
  405. package/dist/patterns-cli.d.ts +2 -1
  406. package/dist/{pipeline-W_97O8BV.d.ts → pipeline-CNjY4wk3.d.ts} +1 -1
  407. package/dist/policy-runtime.d.ts +2 -1
  408. package/dist/policy-runtime.js +1 -1
  409. package/dist/proactive-contention.d.ts +2 -1
  410. package/dist/provenance.d.ts +2 -1
  411. package/dist/provenance.js +2 -2
  412. package/dist/{qmd-LWtMofAf.d.ts → qmd-C0UDZidt.d.ts} +9 -7
  413. package/dist/qmd-preflight.d.ts +5 -4
  414. package/dist/qmd-preflight.js +2 -2
  415. package/dist/qmd-recall-cache.d.ts +2 -1
  416. package/dist/qmd.d.ts +4 -3
  417. package/dist/qmd.js +5 -5
  418. package/dist/recall-concurrency-config.d.ts +2 -1
  419. package/dist/recall-disclosure-escalation.d.ts +2 -1
  420. package/dist/recall-explain-renderer.d.ts +2 -1
  421. package/dist/recall-explain-renderer.js +3 -3
  422. package/dist/recall-memory-map.d.ts +2 -1
  423. package/dist/recall-planner-llm.d.ts +2 -1
  424. package/dist/recall-state.d.ts +2 -1
  425. package/dist/recall-tag-filter.d.ts +2 -1
  426. package/dist/recall-timings.d.ts +2 -1
  427. package/dist/recall-xray-cli.d.ts +2 -1
  428. package/dist/recall-xray-cli.js +4 -4
  429. package/dist/recall-xray-renderer.d.ts +2 -1
  430. package/dist/recall-xray-renderer.js +3 -3
  431. package/dist/recall-xray.d.ts +8 -1
  432. package/dist/recall-xray.js +2 -2
  433. package/dist/reconcile/cursor.d.ts +12 -2
  434. package/dist/reconcile/cursor.js +46 -7
  435. package/dist/reconcile/cursor.js.map +1 -1
  436. package/dist/reconcile/manifest.d.ts +9 -2
  437. package/dist/reconcile/manifest.js +15 -268
  438. package/dist/reconcile/manifest.js.map +1 -1
  439. package/dist/reconcile/plan.d.ts +4 -1
  440. package/dist/reconcile/plan.js +4 -4
  441. package/dist/replay/normalizers/chatgpt.d.ts +2 -1
  442. package/dist/replay/normalizers/claude.d.ts +2 -1
  443. package/dist/replay/normalizers/openclaw.d.ts +2 -1
  444. package/dist/replay/normalizers/shared.d.ts +2 -1
  445. package/dist/replay/runner.d.ts +2 -1
  446. package/dist/replay/types.d.ts +2 -1
  447. package/dist/replica-divergence.d.ts +2 -1
  448. package/dist/replica-divergence.js +2 -2
  449. package/dist/replica-peers-config.d.ts +2 -1
  450. package/dist/resolve-auth-token.d.ts +2 -1
  451. package/dist/resume-bundles.js +12 -10
  452. package/dist/retrieval-agents.d.ts +4 -3
  453. package/dist/retrieval-agents.js +2 -2
  454. package/dist/retrieval-tiers.d.ts +2 -1
  455. package/dist/routing/engine.d.ts +2 -1
  456. package/dist/routing/store.d.ts +2 -1
  457. package/dist/salvage-envelope.d.ts +2 -1
  458. package/dist/schemas.d.ts +32 -32
  459. package/dist/{scope-profiles-BiQKOE-p.d.ts → scope-profiles-BJzp2F5A.d.ts} +1 -1
  460. package/dist/search/embed-helper.d.ts +2 -1
  461. package/dist/search/embed-helper.js +3 -3
  462. package/dist/search/factory.d.ts +4 -2
  463. package/dist/search/factory.js +20 -18
  464. package/dist/search/index.d.ts +2 -1
  465. package/dist/search/index.js +22 -22
  466. package/dist/search/lancedb-backend.d.ts +2 -1
  467. package/dist/search/lancedb-backend.js +4 -4
  468. package/dist/search/meilisearch-backend.d.ts +2 -1
  469. package/dist/search/meilisearch-backend.js +4 -4
  470. package/dist/search/noop-backend.d.ts +2 -1
  471. package/dist/search/orama-backend.d.ts +2 -1
  472. package/dist/search/orama-backend.js +4 -4
  473. package/dist/search/port.d.ts +18 -1
  474. package/dist/search/port.js +1 -1
  475. package/dist/search/remote-backend.d.ts +2 -1
  476. package/dist/search/remote-backend.js +2 -2
  477. package/dist/secure-store/index.js +2 -2
  478. package/dist/{semantic-consolidation-dHYCyqgh.d.ts → semantic-consolidation-D4KAZO2G.d.ts} +1 -1
  479. package/dist/semantic-consolidation.d.ts +3 -2
  480. package/dist/semantic-consolidation.js +25 -24
  481. package/dist/semantic-rule-promotion.js +23 -22
  482. package/dist/semantic-rule-verifier.d.ts +2 -1
  483. package/dist/semantic-rule-verifier.js +24 -23
  484. package/dist/{service-DJG3KCQ4.d.ts → service-BeDxSqE-.d.ts} +2 -2
  485. package/dist/session-observer-bands.d.ts +2 -1
  486. package/dist/session-observer-state.d.ts +2 -1
  487. package/dist/shared-context/manager.d.ts +2 -1
  488. package/dist/shared-context/manager.js +2 -2
  489. package/dist/signal.d.ts +2 -1
  490. package/dist/source-agent-qualifier.d.ts +2 -1
  491. package/dist/source-agent-qualifier.js +42 -40
  492. package/dist/{storage-F9FVh-w9.d.ts → storage-DfjxusTE.d.ts} +24 -12
  493. package/dist/storage.d.ts +3 -2
  494. package/dist/storage.js +25 -24
  495. package/dist/summarizer.d.ts +2 -1
  496. package/dist/summarizer.js +5 -5
  497. package/dist/summary-snapshot.d.ts +2 -1
  498. package/dist/temporal-supersession.d.ts +3 -2
  499. package/dist/temporal-timeline-recall.d.ts +2 -1
  500. package/dist/temporal-validity.d.ts +2 -1
  501. package/dist/threading.d.ts +2 -1
  502. package/dist/tier-migration.d.ts +3 -2
  503. package/dist/tier-routing.d.ts +2 -1
  504. package/dist/tool-scoped-memory.d.ts +5 -1
  505. package/dist/tool-scoped-memory.js +3 -1
  506. package/dist/topics.d.ts +2 -1
  507. package/dist/transcript.d.ts +2 -1
  508. package/dist/transfer/capsule-import.js +4 -4
  509. package/dist/transfer/types.d.ts +12 -12
  510. package/dist/trust-score-stage.d.ts +2 -1
  511. package/dist/trust-score.d.ts +2 -1
  512. package/dist/{types-rEwubvim.d.ts → types-yX_FwERf.d.ts} +8 -1
  513. package/dist/types.d.ts +2 -1
  514. package/dist/types.js +1 -1
  515. package/dist/utility-runtime.d.ts +2 -1
  516. package/dist/verified-recall.js +24 -23
  517. package/dist/write-envelope.d.ts +2 -1
  518. package/package.json +2 -2
  519. package/src/abort-error.ts +17 -0
  520. package/src/access-admin-ops-surface.ts +1 -0
  521. package/src/access-boundary.ts +1 -0
  522. package/src/access-coding-context-resolution.ts +42 -0
  523. package/src/access-extraction-force-flush.ts +38 -2
  524. package/src/access-http-lcm-compaction.ts +5 -2
  525. package/src/access-http-offline-stream.ts +79 -0
  526. package/src/access-http.test.ts +310 -3
  527. package/src/access-http.ts +85 -21
  528. package/src/access-mcp-output-schemas.ts +36 -0
  529. package/src/access-mcp.test.ts +95 -1
  530. package/src/access-mcp.ts +7 -9
  531. package/src/access-observe-helpers.ts +64 -22
  532. package/src/access-observe-write-surface.ts +8 -0
  533. package/src/access-offline-manifest.ts +54 -0
  534. package/src/access-operations-batch.ts +3 -3
  535. package/src/access-operations.ts +13 -7
  536. package/src/access-recall-concurrency.ts +3 -27
  537. package/src/access-recall-surface.ts +3 -0
  538. package/src/access-service-health.test.ts +32 -7
  539. package/src/access-service-namespace.test.ts +55 -0
  540. package/src/access-service-observe-idempotency.test.ts +34 -2
  541. package/src/access-service-observe-lcm-parity.test.ts +138 -3
  542. package/src/access-service-observe-scope.test.ts +160 -1
  543. package/src/access-service-offline-file-content.test.ts +345 -1
  544. package/src/access-service.ts +86 -59
  545. package/src/access-surface-catalog.ts +4 -0
  546. package/src/admin/admin-surfaces.ts +2 -0
  547. package/src/binary-lifecycle/pipeline.test.ts +106 -1
  548. package/src/binary-lifecycle/pipeline.ts +3 -0
  549. package/src/coding/git-context.test.ts +47 -0
  550. package/src/coding/git-context.ts +129 -27
  551. package/src/config.test.ts +24 -0
  552. package/src/config.ts +9 -12
  553. package/src/connector-provenance.test.ts +101 -0
  554. package/src/consolidation-undo.ts +3 -0
  555. package/src/convergence-refresh.ts +14 -2
  556. package/src/correction/correction-access-wiring.ts +9 -7
  557. package/src/correction/correction-executor.test.ts +206 -2
  558. package/src/correction/correction-executor.ts +29 -20
  559. package/src/correction/correction-planner.test.ts +36 -0
  560. package/src/correction/correction-planner.ts +9 -15
  561. package/src/correction/correction-service.ts +3 -1
  562. package/src/correction/correction-storage-integration.test.ts +77 -0
  563. package/src/correction/correction-surfaces.test.ts +41 -28
  564. package/src/correction/passive-capture.test.ts +59 -0
  565. package/src/correction/passive-capture.ts +4 -1
  566. package/src/entity-retrieval-boundaries.ts +17 -4
  567. package/src/entity-retrieval.ts +27 -6
  568. package/src/external-wiki-access.test.ts +65 -0
  569. package/src/external-wiki-access.ts +31 -0
  570. package/src/external-wiki-cli.ts +92 -0
  571. package/src/external-wiki-collection-registration.test.ts +163 -0
  572. package/src/external-wiki-collection-registration.ts +101 -0
  573. package/src/external-wiki-collection.test.ts +502 -0
  574. package/src/external-wiki-collection.ts +503 -0
  575. package/src/external-wiki-config.test.ts +135 -0
  576. package/src/external-wiki-config.ts +100 -0
  577. package/src/external-wiki-guard.ts +83 -0
  578. package/src/external-wiki-mcp-tools.ts +23 -0
  579. package/src/external-wiki-search.test.ts +301 -0
  580. package/src/external-wiki-search.ts +362 -0
  581. package/src/external-wiki.test.ts +240 -0
  582. package/src/external-wiki.ts +453 -0
  583. package/src/extraction-scope-source-agent.test.ts +21 -0
  584. package/src/extraction-source-grounding-helpers.ts +243 -53
  585. package/src/extraction-source-grounding-rules.ts +133 -39
  586. package/src/extraction-source-grounding.test.ts +363 -33
  587. package/src/extraction-timeout.test.ts +1 -0
  588. package/src/extraction-watermark.test.ts +150 -7
  589. package/src/extraction.ts +8 -1
  590. package/src/index.ts +8 -0
  591. package/src/mcp-read-only-tools.ts +1 -0
  592. package/src/offline-sync.test.ts +194 -0
  593. package/src/offline-sync.ts +217 -13
  594. package/src/orchestration/external-wiki-recall-guard.test.ts +94 -0
  595. package/src/orchestration/extraction-persist.ts +19 -2
  596. package/src/orchestration/extraction-run-helpers.ts +37 -19
  597. package/src/orchestration/extraction-run.test.ts +171 -2
  598. package/src/orchestration/extraction-run.ts +11 -13
  599. package/src/orchestration/extraction-watermark.ts +106 -17
  600. package/src/orchestration/generic-recall-paths.ts +14 -0
  601. package/src/orchestration/orchestrator-helpers.ts +2 -0
  602. package/src/orchestration/orchestrator-init.ts +9 -0
  603. package/src/orchestration/recall-internal-deps.ts +6 -0
  604. package/src/orchestration/recall-internal.ts +154 -33
  605. package/src/orchestration/recall-rerank-coordinator.ts +60 -25
  606. package/src/orchestration/recall-search-pipeline.test.ts +75 -1
  607. package/src/orchestration/recall-search-pipeline.ts +50 -10
  608. package/src/orchestrator-convergence-refresh.test.ts +36 -2
  609. package/src/orchestrator.ts +13 -3
  610. package/src/page-versioning.ts +5 -19
  611. package/src/procedural/procedure-recall.ts +5 -1
  612. package/src/provenance-surfaces.test.ts +3 -0
  613. package/src/qmd-client.test.ts +78 -17
  614. package/src/qmd.test.ts +24 -0
  615. package/src/qmd.ts +224 -315
  616. package/src/recall-explain-renderer.ts +3 -0
  617. package/src/recall-rerank-coordinator.test.ts +61 -0
  618. package/src/recall-xray-renderer.test.ts +6 -0
  619. package/src/recall-xray.test.ts +88 -1
  620. package/src/recall-xray.ts +15 -0
  621. package/src/reconcile/cursor.test.ts +48 -0
  622. package/src/reconcile/cursor.ts +58 -11
  623. package/src/reconcile/manifest.test.ts +4 -0
  624. package/src/reconcile/manifest.ts +41 -51
  625. package/src/reconcile/plan.test.ts +4 -0
  626. package/src/reconcile/plan.ts +28 -16
  627. package/src/search/factory.ts +6 -6
  628. package/src/search/port.ts +25 -9
  629. package/src/secure-store/secure-fs.ts +20 -12
  630. package/src/secure-store/secure-store.test.ts +41 -2
  631. package/src/spaces/index.test.ts +61 -2
  632. package/src/spaces/index.ts +44 -18
  633. package/src/storage/entity-alias-config.ts +97 -0
  634. package/src/storage/entity-canonical-id-lock.ts +53 -23
  635. package/src/storage/entity-canonical-id-migration.ts +53 -22
  636. package/src/storage/entity-canonical-id-references.ts +3 -0
  637. package/src/storage/entity-id-safety.ts +7 -0
  638. package/src/storage/entity-store.ts +6 -2
  639. package/src/storage/memory-frontmatter-metadata.ts +4 -9
  640. package/src/storage/memory-migration-serialization.ts +10 -15
  641. package/src/storage/tombstone-blocked-capture-mutation.ts +52 -64
  642. package/src/storage/tombstone-blocked-capture-sync.ts +244 -199
  643. package/src/storage-deletion-revisions.test.ts +91 -0
  644. package/src/storage-fact-hash-index-defer.test.ts +446 -163
  645. package/src/storage.ts +534 -245
  646. package/src/tool-scoped-memory.ts +10 -0
  647. package/src/transfer/capsule-import.ts +13 -0
  648. package/src/transfer/capsule-merge.ts +13 -0
  649. package/src/trust-score-recall-paths.test.ts +75 -1
  650. package/src/types.ts +7 -3
  651. package/dist/capsule-merge-IDWJPCWK.js.map +0 -1
  652. package/dist/chunk-3CE77VAP.js.map +0 -1
  653. package/dist/chunk-3TBLDMJA.js.map +0 -1
  654. package/dist/chunk-4J7G5SY4.js.map +0 -1
  655. package/dist/chunk-57QKLRBV.js.map +0 -1
  656. package/dist/chunk-5TFP4CUL.js.map +0 -1
  657. package/dist/chunk-7XC2HX75.js.map +0 -1
  658. package/dist/chunk-A5OJCXZL.js.map +0 -1
  659. package/dist/chunk-BUE5E2HL.js.map +0 -1
  660. package/dist/chunk-CJ2ZR7UA.js.map +0 -1
  661. package/dist/chunk-CUM2BBPN.js.map +0 -1
  662. package/dist/chunk-D3J5SLQK.js.map +0 -1
  663. package/dist/chunk-DL7ZD3JH.js.map +0 -1
  664. package/dist/chunk-DLVPUX7U.js.map +0 -1
  665. package/dist/chunk-E6PNLPGJ.js.map +0 -1
  666. package/dist/chunk-ECK75GDJ.js.map +0 -1
  667. package/dist/chunk-HREE4JHI.js.map +0 -1
  668. package/dist/chunk-HZFHQ4AQ.js.map +0 -1
  669. package/dist/chunk-IKKWIPYN.js.map +0 -1
  670. package/dist/chunk-J7VGGECD.js.map +0 -1
  671. package/dist/chunk-N5Z4EVOR.js.map +0 -1
  672. package/dist/chunk-NVRYW264.js.map +0 -1
  673. package/dist/chunk-P2BM76KT.js.map +0 -1
  674. package/dist/chunk-PVGDJXVK.js +0 -21
  675. package/dist/chunk-QJAQNXWI.js.map +0 -1
  676. package/dist/chunk-RN7DY3FC.js.map +0 -1
  677. package/dist/chunk-RVLJEII5.js.map +0 -1
  678. package/dist/chunk-S2NCTZGJ.js.map +0 -1
  679. package/dist/chunk-TDHTVMPG.js.map +0 -1
  680. package/dist/chunk-UYLMNVY6.js.map +0 -1
  681. package/dist/chunk-VCD4PSK2.js.map +0 -1
  682. package/dist/chunk-VNA7W7QF.js.map +0 -1
  683. package/dist/chunk-VWAXN2BN.js.map +0 -1
  684. package/dist/chunk-WOCNN776.js.map +0 -1
  685. package/dist/chunk-XYTOI63Z.js.map +0 -1
  686. package/dist/chunk-YV32N67O.js.map +0 -1
  687. /package/dist/{auto-sync-5OE5QOZB.js.map → auto-sync-UPTUVE4X.js.map} +0 -0
  688. /package/dist/{chunk-VUPTKTDV.js.map → chunk-2MRHJNWL.js.map} +0 -0
  689. /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
  690. /package/dist/{chunk-5IVLTFOV.js.map → chunk-44N6ESJ4.js.map} +0 -0
  691. /package/dist/{chunk-HO3QBJEY.js.map → chunk-5546W5SI.js.map} +0 -0
  692. /package/dist/{chunk-U7GW7NE7.js.map → chunk-5CEECY6P.js.map} +0 -0
  693. /package/dist/{chunk-4UH4BTGK.js.map → chunk-5SNZSWWR.js.map} +0 -0
  694. /package/dist/{chunk-6CZPDBJS.js.map → chunk-5U7ID3EZ.js.map} +0 -0
  695. /package/dist/{chunk-GF22HWS2.js.map → chunk-6NNNURLK.js.map} +0 -0
  696. /package/dist/{chunk-227UFSEQ.js.map → chunk-7RZJWZ46.js.map} +0 -0
  697. /package/dist/{chunk-E5UK4VPE.js.map → chunk-7SHJHPTY.js.map} +0 -0
  698. /package/dist/{chunk-UVIKWC7M.js.map → chunk-7YERSTN7.js.map} +0 -0
  699. /package/dist/{chunk-S5SLVSVY.js.map → chunk-BQIFZ2MP.js.map} +0 -0
  700. /package/dist/{chunk-E53DSZEN.js.map → chunk-C26TE27X.js.map} +0 -0
  701. /package/dist/{chunk-LZ4LDKHZ.js.map → chunk-CLB32OHM.js.map} +0 -0
  702. /package/dist/{chunk-Q6IP2ARR.js.map → chunk-CSOYVTRX.js.map} +0 -0
  703. /package/dist/{chunk-XOQSEF7X.js.map → chunk-CVILPI77.js.map} +0 -0
  704. /package/dist/{chunk-PDLBLTOK.js.map → chunk-EITZHSX6.js.map} +0 -0
  705. /package/dist/{chunk-WUNIWKY4.js.map → chunk-ELIL2A37.js.map} +0 -0
  706. /package/dist/{chunk-CINZGPSJ.js.map → chunk-GUMZC2BO.js.map} +0 -0
  707. /package/dist/{chunk-H24WNPA2.js.map → chunk-GWFSVJ4P.js.map} +0 -0
  708. /package/dist/{chunk-TSH56VPU.js.map → chunk-HAYSYUAB.js.map} +0 -0
  709. /package/dist/{chunk-PKNLM44P.js.map → chunk-JH6BPLOP.js.map} +0 -0
  710. /package/dist/{chunk-KXB4VXHY.js.map → chunk-JIYDRBVZ.js.map} +0 -0
  711. /package/dist/{chunk-AV5ZEH4M.js.map → chunk-KVJRXN2E.js.map} +0 -0
  712. /package/dist/{chunk-JVLCVFQ4.js.map → chunk-KXEFRMCF.js.map} +0 -0
  713. /package/dist/{chunk-WFTIGIIS.js.map → chunk-L6CQ7WIW.js.map} +0 -0
  714. /package/dist/{chunk-EJUEXZHX.js.map → chunk-LLJMAULE.js.map} +0 -0
  715. /package/dist/{chunk-AS7YMSL6.js.map → chunk-M23RF3LJ.js.map} +0 -0
  716. /package/dist/{chunk-3F2LKUMU.js.map → chunk-NIS256NW.js.map} +0 -0
  717. /package/dist/{chunk-YIAA2X3D.js.map → chunk-NK5RGJ65.js.map} +0 -0
  718. /package/dist/{chunk-OQ5PRDDS.js.map → chunk-NTOIP2E6.js.map} +0 -0
  719. /package/dist/{chunk-HLPD7B7P.js.map → chunk-NUEQKLNB.js.map} +0 -0
  720. /package/dist/{chunk-33PLLLL7.js.map → chunk-P7NGM24P.js.map} +0 -0
  721. /package/dist/{chunk-7TWUCYER.js.map → chunk-PNRA7FAD.js.map} +0 -0
  722. /package/dist/{chunk-5I4M26Q7.js.map → chunk-QBSFOKY6.js.map} +0 -0
  723. /package/dist/{chunk-P4DRWEYC.js.map → chunk-QVSBTCVP.js.map} +0 -0
  724. /package/dist/{chunk-AAIUERNB.js.map → chunk-R5RFK3CB.js.map} +0 -0
  725. /package/dist/{chunk-WDISJRMG.js.map → chunk-RMMVQQA6.js.map} +0 -0
  726. /package/dist/{chunk-5SM35XZR.js.map → chunk-S5NZBKKQ.js.map} +0 -0
  727. /package/dist/{chunk-WIPEXG6R.js.map → chunk-SXIMQLGV.js.map} +0 -0
  728. /package/dist/{chunk-OAEQLRCY.js.map → chunk-TN76AKO3.js.map} +0 -0
  729. /package/dist/{chunk-QN25OCUF.js.map → chunk-TQ4GD737.js.map} +0 -0
  730. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  731. /package/dist/{chunk-DNWXFTLD.js.map → chunk-TYISDI6B.js.map} +0 -0
  732. /package/dist/{chunk-4LMA77JH.js.map → chunk-U2VLVBBH.js.map} +0 -0
  733. /package/dist/{chunk-5ZE7QHTK.js.map → chunk-ULVR5KG7.js.map} +0 -0
  734. /package/dist/{chunk-4B77XSG5.js.map → chunk-UV72DEZD.js.map} +0 -0
  735. /package/dist/{chunk-S2BBISHU.js.map → chunk-VANZKHTN.js.map} +0 -0
  736. /package/dist/{chunk-3Y224NYC.js.map → chunk-VYISFWVX.js.map} +0 -0
  737. /package/dist/{chunk-TIHMZFIV.js.map → chunk-W3IC7QOY.js.map} +0 -0
  738. /package/dist/{chunk-NRV4Y3PM.js.map → chunk-W4FBGYGK.js.map} +0 -0
  739. /package/dist/{chunk-MU7ZHSZE.js.map → chunk-WZFAPHIK.js.map} +0 -0
  740. /package/dist/{chunk-T2TTP3KU.js.map → chunk-X4IDNPOS.js.map} +0 -0
  741. /package/dist/{chunk-BLAKS3CP.js.map → chunk-XL3TATMJ.js.map} +0 -0
  742. /package/dist/{chunk-W4XJFLAL.js.map → chunk-XPRJSHNI.js.map} +0 -0
  743. /package/dist/{chunk-JE7EK33X.js.map → chunk-Y7HRYCNW.js.map} +0 -0
  744. /package/dist/{chunk-E6EE5B67.js.map → chunk-YK6BDDHP.js.map} +0 -0
  745. /package/dist/{chunk-ES36HTSC.js.map → chunk-YLHM5BQQ.js.map} +0 -0
  746. /package/dist/{chunk-BJKPPZ6Z.js.map → chunk-ZFGZ6PZ2.js.map} +0 -0
  747. /package/dist/{chunk-64UDOIMI.js.map → chunk-ZLQ37WJX.js.map} +0 -0
@@ -1,13 +1,13 @@
1
+ import {
2
+ normalizeNamespaceIdentity
3
+ } from "./chunk-EGGE52UU.js";
1
4
  import {
2
5
  CONVERGE_CONFLICT_POLICIES,
3
6
  DEFAULT_CONVERGE_CONFLICT_POLICY
4
7
  } from "./chunk-HBVPYRDW.js";
5
- import {
6
- normalizeNamespaceIdentity
7
- } from "./chunk-EGGE52UU.js";
8
8
  import {
9
9
  OFFLINE_SYNC_MAX_MTIME_MS
10
- } from "./chunk-7XC2HX75.js";
10
+ } from "./chunk-GYPQL6XN.js";
11
11
  import {
12
12
  validateArchiveRelativePath
13
13
  } from "./chunk-GCGJW34D.js";
@@ -272,6 +272,13 @@ function planNamespaceReconciliation(input, options = {}) {
272
272
  }
273
273
  if (!peerFile) {
274
274
  if (baseSha256 !== void 0) {
275
+ const peerDeletionMtime = peerDeletionMtimeMs.get(path);
276
+ const resolution2 = baseSha256 === localFile.sha256 ? "unresolved" : resolveConflict(
277
+ policy,
278
+ localFile.mtimeMs,
279
+ peerDeletionMtime,
280
+ "unresolved"
281
+ );
275
282
  entries.push({
276
283
  path,
277
284
  namespace,
@@ -279,12 +286,8 @@ function planNamespaceReconciliation(input, options = {}) {
279
286
  reason: baseSha256 === localFile.sha256 ? "peer_deleted" : "local_modified_peer_deleted",
280
287
  localSha256: localFile.sha256,
281
288
  baseSha256,
282
- resolution: baseSha256 === localFile.sha256 ? "unresolved" : resolveConflict(
283
- policy,
284
- localFile.mtimeMs,
285
- peerDeletionMtimeMs.get(path),
286
- "unresolved"
287
- )
289
+ resolution: resolution2,
290
+ ...resolution2 === "peer-wins" && peerDeletionMtime !== void 0 ? { deletionMtimeMs: peerDeletionMtime } : {}
288
291
  });
289
292
  continue;
290
293
  }
@@ -366,6 +369,13 @@ function planNamespaceReconciliation(input, options = {}) {
366
369
  continue;
367
370
  }
368
371
  if (baseSha256 !== void 0) {
372
+ const localDeletionMtime = localDeletionMtimeMs.get(path);
373
+ const resolution = baseSha256 === peerFile.sha256 ? "unresolved" : resolveConflict(
374
+ policy,
375
+ localDeletionMtime,
376
+ peerFile.mtimeMs,
377
+ "unresolved"
378
+ );
369
379
  entries.push({
370
380
  path,
371
381
  namespace,
@@ -373,12 +383,8 @@ function planNamespaceReconciliation(input, options = {}) {
373
383
  reason: baseSha256 === peerFile.sha256 ? "local_deleted" : "local_deleted_peer_modified",
374
384
  peerSha256: peerFile.sha256,
375
385
  baseSha256,
376
- resolution: baseSha256 === peerFile.sha256 ? "unresolved" : resolveConflict(
377
- policy,
378
- localDeletionMtimeMs.get(path),
379
- peerFile.mtimeMs,
380
- "unresolved"
381
- )
386
+ resolution,
387
+ ...resolution === "local-wins" && localDeletionMtime !== void 0 ? { deletionMtimeMs: localDeletionMtime } : {}
382
388
  });
383
389
  continue;
384
390
  }
@@ -440,4 +446,4 @@ export {
440
446
  summarizeReconcilePlan,
441
447
  planReconciliation
442
448
  };
443
- //# sourceMappingURL=chunk-HZFHQ4AQ.js.map
449
+ //# sourceMappingURL=chunk-G7A5HLUS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/reconcile/plan.ts"],"sourcesContent":["import { normalizeNamespaceIdentity } from \"../namespaces/identity.js\";\nimport { OFFLINE_SYNC_MAX_MTIME_MS } from \"../offline-sync.js\";\nimport { validateArchiveRelativePath } from \"../transfer/fs-utils.js\";\nimport type { OfflineSyncFileState } from \"../offline-sync.js\";\nimport {\n CONVERGE_CONFLICT_POLICIES,\n DEFAULT_CONVERGE_CONFLICT_POLICY,\n} from \"../converge-config.js\";\nimport type { ConvergeConflictPolicy } from \"../types.js\";\nexport type ReconcileConflictPolicy = ConvergeConflictPolicy;\n\n/**\n * Bootstrap reconciliation planner for two peer daemons whose corpora have\n * already diverged (issue #2150).\n *\n * The offline-sync protocol assumes a satellite that shares a common base with\n * one daemon: every path it does not know about is a pull, and a conflict is\n * rare. Two long-lived daemons are the opposite case — each side holds months\n * of history the other never saw, both sides are authoritative, and there is\n * NO common base on the first run. That is a different decision problem, so it\n * gets its own planner rather than another mode flag inside `applyOfflineSync*`.\n *\n * This module is deliberately pure: it takes two file censuses and returns what\n * to do. No I/O, no transport, no clock. Everything that makes reconciliation\n * risky — which side wins, what counts as converged, what is reported — is\n * decided here where it can be exhaustively tested, and the transport layer is\n * left to carry out an already-settled plan.\n */\n\n/** Which way a path must move for the two corpora to agree. */\nexport type ReconcileAction = \"pull\" | \"push\" | \"identical\" | \"conflict\" | \"suppress\";\n\n/**\n * What the planner decided for a conflicting path.\n * `supersede-link` records that both revisions need durable preservation when\n * timestamps cannot safely select a winner. Apply must stop until transport\n * can assign distinct durable identities to both revisions.\n */\nexport type ReconcileResolution = \"local-wins\" | \"peer-wins\" | \"supersede-link\" | \"unresolved\";\n\nexport interface ReconcileSemanticFileState {\n path: string;\n sha256: string;\n}\n\nexport interface ReconcileSemanticAgreement {\n local: ReconcileSemanticFileState;\n peer: ReconcileSemanticFileState;\n}\n\nexport type ReconcileSemanticChange = \"unchanged\" | \"local_changed\" | \"peer_changed\" | \"both_modified\";\n\nexport interface ReconcilePlanEntry {\n path: string;\n namespace: string;\n action: ReconcileAction;\n /** Stable machine-readable cause, safe to assert on and to aggregate. */\n reason: ReconcileReason;\n localSha256?: string;\n peerSha256?: string;\n /** Present only when a prior converged run left a cursor covering this path. */\n baseSha256?: string;\n /** Set only when `action` is `conflict`. */\n resolution?: ReconcileResolution;\n /** Original revision time when conflict resolution propagates a deletion. */\n deletionMtimeMs?: number;\n /**\n * Which side holds the retracted revision. Set only when `action` is\n * `suppress`: with different digests on each side and only one retracted,\n * the entry would otherwise be identical either way and transport could\n * delete the live copy instead of the retracted one.\n */\n suppressSide?: \"local\" | \"peer\" | \"both\";\n /**\n * Real per-side identities for a cross-path semantic agreement. Synthetic\n * rows omit the top-level side digests because `path` cannot name both files.\n */\n semanticAgreement?: ReconcileSemanticAgreement;\n /** Each side's current digest compared with its own prior semantic digest. */\n semanticChange?: ReconcileSemanticChange;\n}\n\nexport type ReconcileReason =\n | \"peer_only\"\n | \"local_only\"\n /** Cursor showed only that side moved since agreement; both still hold the path. */\n | \"peer_changed\"\n | \"local_changed\"\n | \"same_content\"\n | \"semantic_duplicate\"\n | \"both_modified\"\n | \"peer_deleted\"\n | \"local_deleted\"\n /** Peer deleted it while this side edited it — the offline-sync delete/modify pair. */\n | \"local_modified_peer_deleted\"\n | \"local_deleted_peer_modified\"\n | \"tombstoned\";\n\nexport interface ReconcileNamespaceReport {\n namespace: string;\n pull: number;\n push: number;\n identical: number;\n conflict: number;\n /** Local retractions the peer must be told about before the pair agrees. */\n suppress: number;\n /**\n * Conflicts still needing an operator: those the policy declined to settle,\n * plus supersede links whose direction could not be determined.\n */\n unresolved: number;\n}\n\nexport interface ReconcilePlan {\n entries: ReconcilePlanEntry[];\n byNamespace: ReconcileNamespaceReport[];\n /**\n * True when the two corpora already agree — every shared path matches and\n * neither side holds a path the other lacks.\n *\n * This is the idempotency contract from #2150: running reconciliation against\n * an already-converged peer must be a no-op, and a caller can skip the whole\n * transfer phase on this flag alone.\n */\n converged: boolean;\n}\n\n/** Minimal shape the planner needs; `OfflineSyncFileState` satisfies it. */\nexport type ReconcileFileState = Pick<OfflineSyncFileState, \"path\" | \"sha256\"> &\n Partial<Pick<OfflineSyncFileState, \"mtimeMs\" | \"bytes\">>;\n\nexport interface ReconcileNamespaceInput {\n namespace: string;\n local: Iterable<ReconcileFileState>;\n peer: Iterable<ReconcileFileState>;\n /**\n * File states agreed at the end of the last converged run with THIS peer.\n * Absent on a bootstrap merge, which is why a path missing from one side is\n * read as \"never seen\" rather than \"deleted\".\n */\n base?: Iterable<ReconcileFileState>;\n /**\n * Revision timestamps for paths deleted locally since the base cursor.\n * A deletion is a revision and must carry a comparable time for\n * `newest-wins`; absence alone has no timestamp.\n */\n localDeletionMtimeMs?: ReadonlyMap<string, number>;\n /** Revision timestamps for paths deleted by the peer since the base cursor. */\n peerDeletionMtimeMs?: ReadonlyMap<string, number>;\n /**\n * Digests of FILES this side has retracted, in the same form as\n * `ReconcileFileState.sha256` — a hash of the serialized file.\n *\n * Deliberately NOT `TombstoneEntry.contentHash`, which hashes the canonical\n * raw fact text and therefore never equals a file digest (§13: one content\n * form, everywhere). Mapping retracted fact hashes onto the file digests that\n * carry them is the caller's job, because only the caller can read its own\n * corpus; handing this the wrong form would silently plan `pull` and\n * resurrect every retracted fact, so the parameter name states the form.\n */\n tombstonedFileSha256?: Iterable<string>;\n /**\n * Digests the PEER has retracted, same form.\n *\n * Without this a bootstrap merge cannot tell \"the peer never had it\" from\n * \"the peer deliberately retracted it\": the peer census simply omits both,\n * so a file we still hold is planned `push` and the peer's retraction is\n * undone. Reconciliation is symmetric, so retraction has to be too.\n *\n * SCOPE: these sets decide what happens to files that still EXIST on one\n * side. Sharing the retraction records themselves is not modelled here -\n * tombstones are corpus files (`state/tombstones.jsonl`), so they reconcile\n * as ordinary paths through this same plan. A digest both censuses have\n * already dropped therefore produces no entry, by design: there is no file\n * left to act on, and synthesizing a path-less entry would hand transport\n * something it cannot apply.\n */\n peerTombstonedFileSha256?: Iterable<string>;\n}\n\nexport interface ReconcileOptions {\n conflictPolicy?: ConvergeConflictPolicy;\n}\n\n/**\n * A census the planner refuses to reason about.\n *\n * Dropping a malformed or contradictory record would let the planner return\n * `converged: true` for a corpus it could not actually read, and transport is\n * invited to skip everything on that flag — so bad input fails loudly instead\n * (§1/§39).\n */\nexport class ReconcilePlanInputError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ReconcilePlanInputError\";\n }\n}\n\n/** Matches `assertSha256` in offline-sync so both surfaces reject the same values (§40). */\nconst SHA256_PATTERN = /^[a-f0-9]{64}$/i;\n\n/**\n * Validate a census record's identity fields.\n *\n * The digest matters as much as the path: two records that both omit `sha256`\n * compare `undefined === undefined` and plan as `identical`, converging a\n * corpus the planner never actually read.\n */\nfunction assertCensusRecord(\n file: ReconcileFileState | undefined,\n side: string,\n namespace: string,\n): ReconcileFileState {\n const path = file?.path;\n if (typeof path !== \"string\" || path.length === 0) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} contains a record with no path`,\n );\n }\n // Same boundary offline-sync applies to this field: a peer census is\n // untrusted input, and an absolute or traversal path would otherwise become\n // a transfer instruction pointing outside the corpus root.\n try {\n validateArchiveRelativePath(path, `reconcile: ${side} census for namespace ${namespace}`);\n } catch (err) {\n throw new ReconcilePlanInputError(err instanceof Error ? err.message : String(err));\n }\n assertPortablePathSegments(path, side, namespace);\n return {\n ...file,\n path,\n sha256: assertDigest(file?.sha256, `${side} census for namespace ${namespace} entry ${path}`),\n ...(file?.mtimeMs === undefined\n ? {}\n : { mtimeMs: assertMtimeMs(file.mtimeMs, `${side} census for namespace ${namespace} entry ${path}`) }),\n };\n}\n\n/**\n * `newest-wins` decides which corpus keeps its history from this number, so a\n * NaN, an Infinity or a value past the Date range must not pick the winner.\n *\n * Fractional values ARE valid: `fs.stat()` reports sub-millisecond mtimes on\n * common filesystems and offline-sync forwards them unrounded, so this matches\n * its `assertOfflineSyncMtimeMs` — non-negative finite within Date range — and\n * deliberately does not require an integer.\n */\nfunction assertMtimeMs(value: unknown, context: string): number {\n if (\n typeof value !== \"number\"\n || !Number.isFinite(value)\n || value < 0\n || value > OFFLINE_SYNC_MAX_MTIME_MS\n ) {\n throw new ReconcilePlanInputError(\n `reconcile: ${context} has an out-of-range mtimeMs; expected a finite value between 0 and ${OFFLINE_SYNC_MAX_MTIME_MS}`,\n );\n }\n return value;\n}\n\n/**\n * Digests are canonicalized to lowercase, exactly as offline-sync's\n * `assertSha256` does. Keeping the caller's spelling would make two forms of\n * one digest compare unequal, so identical files would plan `both_modified`\n * and tombstone lookups would silently miss.\n */\nfunction assertDigest(value: unknown, context: string): string {\n if (typeof value !== \"string\" || !SHA256_PATTERN.test(value)) {\n throw new ReconcilePlanInputError(\n `reconcile: ${context} must carry a 64-character sha256 hex digest`,\n );\n }\n return value.toLowerCase();\n}\n\nfunction isPlainObject(value: unknown): boolean {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nfunction assertNamespace(namespace: unknown): string {\n if (typeof namespace !== \"string\" || namespace.length === 0) {\n throw new ReconcilePlanInputError(\"reconcile: every namespace input needs a non-empty namespace\");\n }\n // `team` and ` team ` are one namespace to the rest of core, so accepting\n // both here would slip two inputs past the duplicate check and let them plan\n // contradictory actions for the same path. Rejected rather than silently\n // rewritten, so the namespace on every entry is the caller's own string.\n if (LONE_SURROGATE.test(namespace)) {\n // `namespaceIdentityToken()` encodes through TextEncoder, so a lone\n // surrogate and a literal U+FFFD collapse to ONE storage identity while\n // comparing as two here - slipping both past the duplicate-namespace guard.\n throw new ReconcilePlanInputError(\n \"reconcile: namespace contains an unpaired surrogate; it would collide with another namespace on disk\",\n );\n }\n if (normalizeNamespaceIdentity(namespace) !== namespace) {\n throw new ReconcilePlanInputError(\n `reconcile: namespace ${JSON.stringify(namespace)} is not canonical; pass ${JSON.stringify(normalizeNamespaceIdentity(namespace))}`,\n );\n }\n return namespace;\n}\n\nfunction assertIterable(value: unknown, side: string, namespace: string): Iterable<ReconcileFileState> {\n if (value === null || typeof value !== \"object\" || typeof (value as Iterable<ReconcileFileState>)[Symbol.iterator] !== \"function\") {\n throw new ReconcilePlanInputError(`reconcile: ${side} census for namespace ${namespace} must be iterable`);\n }\n return value as Iterable<ReconcileFileState>;\n}\n\n/**\n * Two paths that a participant's filesystem resolves to ONE file must not draw\n * separate push/pull work, or application order decides which revision\n * survives. Remnic is explicitly multi-platform, so all three aliasing rules\n * are folded together and a collision is rejected rather than raced:\n * case (macOS, Windows), Unicode normalization (macOS stores decomposed and\n * compares canonically), and Win32 trailing dots/spaces, which the Windows API\n * strips before touching disk.\n */\n// eslint-disable-next-line no-control-regex -- control characters are exactly what this rejects\nconst WIN32_INVALID_CHARS = /[<>:\"|?*\\u0000-\\u001f]/;\n// Windows treats the superscripts as their digits in COM/LPT device names.\nconst LONE_SURROGATE = /[\\ud800-\\udbff](?![\\udc00-\\udfff])|(?<![\\ud800-\\udbff])[\\udc00-\\udfff]/;\nconst WIN32_RESERVED_NAMES = /^(con|prn|aux|nul|(com|lpt)[1-9\\u00b9\\u00b2\\u00b3])$/i;\n\nfunction assertPortablePathSegments(path: string, side: string, namespace: string): void {\n for (const segment of path.split(\"/\")) {\n if (segment.length === 0) continue;\n if (segment.endsWith(\".\") || segment.endsWith(\" \")) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} path ${path} has a segment ending in a dot or space; ` +\n \"Windows strips those and would alias it onto another file\",\n );\n }\n // `:` opens an alternate data stream, the rest cannot be created at all,\n // and a reserved device name resolves to hardware. A plan containing any of\n // them cannot be applied on a Windows participant.\n if (LONE_SURROGATE.test(segment)) {\n // Node encodes an unpaired surrogate as U+FFFD, so this path and a\n // literal U+FFFD path are one file on disk while comparing as distinct.\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} path ${path} contains an unpaired surrogate`,\n );\n }\n if (WIN32_INVALID_CHARS.test(segment)) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} path ${path} contains a character Windows cannot store`,\n );\n }\n if (WIN32_RESERVED_NAMES.test(segment.split(\".\")[0] ?? \"\")) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} path ${path} uses a reserved Windows device name`,\n );\n }\n }\n}\n\nfunction assertNoPathAlias(\n seen: Map<string, string>,\n path: string,\n namespace: string,\n): void {\n // NFC first: macOS stores decomposed names and compares canonically, so\n // `é` (U+00E9) and `é` (e + U+0301) are ONE file there. Then a FULL caseless\n // fold - upper-then-lower, which collapses forms a bare toLowerCase() keeps\n // apart, such as final sigma `ς` against `σ`. Lowercasing alone would leave\n // those distinct and the planner would emit both a push and a pull.\n // `ß` upper-folds to `ss` while `ẞ` folds to `ß`, so one more pass equalizes\n // the pair that a single upper-then-lower still leaves apart.\n const folded = path.normalize(\"NFC\").toUpperCase().toLowerCase().replace(/\\u00df/g, \"ss\");\n const existing = seen.get(folded);\n if (existing !== undefined && existing !== path) {\n throw new ReconcilePlanInputError(\n `reconcile: namespace ${namespace} has aliasing paths (${existing}, ${path}); ` +\n \"they resolve to one file on a case-insensitive or Unicode-normalizing peer\",\n );\n }\n seen.set(folded, path);\n}\n\n/**\n * Duplicate paths are accepted only when they agree. Two digests for one path\n * make the plan depend on which record arrived last, which would break the\n * byte-stable ordering the convergence report relies on.\n */\nfunction rejectConflictingDuplicate(\n existing: { sha256: string; mtimeMs?: number } | undefined,\n incoming: { sha256: string; mtimeMs?: number },\n path: string,\n side: string,\n namespace: string,\n): boolean {\n if (!existing) return false;\n if (existing.sha256 !== incoming.sha256) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} lists ${path} twice with different digests`,\n );\n }\n // Same bytes but a different mtime is still ambiguous: `newest-wins` reads\n // that timestamp, so accepting the first arrival would let input order decide\n // the winner.\n if (existing.mtimeMs !== incoming.mtimeMs) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} lists ${path} twice with different mtimeMs`,\n );\n }\n return true;\n}\n\nfunction indexByPath(\n files: Iterable<ReconcileFileState>,\n side: string,\n namespace: string,\n): Map<string, ReconcileFileState> {\n const index = new Map<string, ReconcileFileState>();\n for (const raw of files) {\n const file = assertCensusRecord(raw, side, namespace);\n if (rejectConflictingDuplicate(index.get(file.path), file, file.path, side, namespace)) continue;\n index.set(file.path, file);\n }\n return index;\n}\n\n/**\n * A bare string satisfies `Iterable<string>`, and `new Set(\"abc…\")` would split\n * it into 64 one-character members — every membership test then misses and each\n * retracted file is planned as `pull` and resurrected. Reject the scalar and\n * canonicalize every member.\n */\nfunction parseTombstonedDigests(\n value: Iterable<string> | undefined,\n namespace: string,\n field = \"tombstonedFileSha256\",\n): Set<string> {\n if (value === undefined) return new Set();\n if (typeof value === \"string\") {\n throw new ReconcilePlanInputError(\n `reconcile: ${field} for namespace ${namespace} must be a collection of digests, not a single string`,\n );\n }\n if (value === null || typeof value !== \"object\" || typeof value[Symbol.iterator] !== \"function\") {\n // Otherwise the for...of below throws a raw TypeError and a caller handling\n // ReconcilePlanInputError cannot tell a bad request from a planner bug.\n throw new ReconcilePlanInputError(\n `reconcile: ${field} for namespace ${namespace} must be an iterable collection of digests`,\n );\n }\n const digests = new Set<string>();\n for (const entry of value) {\n digests.add(assertDigest(entry, `${field} for namespace ${namespace}`));\n }\n return digests;\n}\n\n/**\n * Validate a census while keeping ONLY path -> digest.\n *\n * The base cursor is read for digests alone, so indexing full records and\n * compacting afterwards would hold a corpus-sized record map and its copy at\n * once - the peak this avoids.\n */\nfunction indexDigestsByPath(\n files: Iterable<ReconcileFileState>,\n side: string,\n namespace: string,\n): Map<string, string> {\n const index = new Map<string, string>();\n for (const raw of files) {\n const file = assertCensusRecord(raw, side, namespace);\n const existing = index.get(file.path);\n // One map, not a parallel `seen`: the base's own mtimeMs is never a\n // decision input (only the local and peer timestamps order a conflict), so\n // a duplicate that agrees on the digest is unambiguous here regardless of\n // its timestamp, and the digest alone is enough to detect a real clash.\n if (existing !== undefined) {\n if (existing !== file.sha256) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} census for namespace ${namespace} lists ${file.path} twice with different digests`,\n );\n }\n continue;\n }\n index.set(file.path, file.sha256);\n }\n return index;\n}\n\nfunction assertConflictPolicy(value: ConvergeConflictPolicy | undefined): ConvergeConflictPolicy {\n if (value === undefined) return DEFAULT_CONVERGE_CONFLICT_POLICY;\n if (!CONVERGE_CONFLICT_POLICIES.includes(value)) {\n throw new ReconcilePlanInputError(\n `reconcile: unknown conflictPolicy ${JSON.stringify(value)}; expected one of ${CONVERGE_CONFLICT_POLICIES.join(\", \")}`,\n );\n }\n return value;\n}\n\n/**\n * Total ordering for plan entries (§12): namespace, then path. Both are unique\n * per entry, so equal keys are impossible and the comparator never has to\n * return 0 for distinct rows — the output is byte-identical across runs, which\n * is what makes a convergence report diffable.\n */\nfunction compareEntries(a: ReconcilePlanEntry, b: ReconcilePlanEntry): number {\n if (a.namespace !== b.namespace) return a.namespace < b.namespace ? -1 : 1;\n if (a.path !== b.path) return a.path < b.path ? -1 : 1;\n return 0;\n}\n\n\nfunction resolveConflict(\n policy: ConvergeConflictPolicy,\n localMtimeMs: number | undefined,\n peerMtimeMs: number | undefined,\n missingTimestampResolution: ReconcileResolution,\n): ReconcileResolution {\n if (policy !== \"newest-wins\") return \"unresolved\";\n if (localMtimeMs === undefined || peerMtimeMs === undefined || localMtimeMs === peerMtimeMs) {\n return missingTimestampResolution;\n }\n return localMtimeMs > peerMtimeMs ? \"local-wins\" : \"peer-wins\";\n}\n\nfunction parseDeletionMtimes(\n value: ReadonlyMap<string, number> | undefined,\n side: string,\n namespace: string,\n): ReadonlyMap<string, number> {\n if (value === undefined) return new Map();\n if (!(value instanceof Map)) {\n throw new ReconcilePlanInputError(\n `reconcile: ${side} deletion mtimes for namespace ${namespace} must be a Map`,\n );\n }\n const parsed = new Map<string, number>();\n for (const [path, mtimeMs] of value) {\n try {\n validateArchiveRelativePath(path, `reconcile: ${side} deletion mtimes for namespace ${namespace}`);\n } catch (err) {\n throw new ReconcilePlanInputError(err instanceof Error ? err.message : String(err));\n }\n assertPortablePathSegments(path, side, namespace);\n parsed.set(path, assertMtimeMs(mtimeMs, `${side} deletion for namespace ${namespace} entry ${path}`));\n }\n return parsed;\n}\n\n/**\n * Plan one namespace. Exposed for callers that stream namespaces one at a time.\n *\n * Residency is one peer index + a set of local paths + the entry list. The\n * local census is consumed as a stream and never materialized, so a 100k-file\n * corpus does not hold two full censuses at once — but this is NOT constant\n * memory, and a caller holding its own census arrays adds to that.\n */\nexport function planNamespaceReconciliation(\n input: ReconcileNamespaceInput,\n options: ReconcileOptions = {},\n): ReconcilePlanEntry[] {\n if (!isPlainObject(input)) {\n throw new ReconcilePlanInputError(\"reconcile: namespace input must be a plain object\");\n }\n if (!isPlainObject(options)) {\n // A Date, Map or RegExp passes a bare typeof check, exposes no\n // `conflictPolicy`, and would silently take the default policy - hiding a\n // malformed request behind `manual`.\n throw new ReconcilePlanInputError(\"reconcile: options must be a plain object\");\n }\n const namespace = assertNamespace(input.namespace);\n const policy = assertConflictPolicy(options.conflictPolicy);\n const localCensus = assertIterable(input.local, \"local\", namespace);\n const caseFold = new Map<string, string>();\n // Index the peer census only, then stream the local one against it, removing\n // each match as it is consumed. Peak residency is one index plus the entry\n // list rather than two full censuses (round 2, codex P2).\n const peer = indexByPath(assertIterable(input.peer, \"peer\", namespace), \"peer\", namespace);\n // Only `base.sha256` is ever read, so the base is compacted to path -> digest\n // instead of a second full record index (round 7, codex P2).\n // Only an ABSENT base means bootstrap. A null/invalid cursor silently read as\n // \"no prior agreement\" would turn a peer-side deletion into a push and\n // resurrect it.\n const base = input.base === undefined\n ? null\n : indexDigestsByPath(assertIterable(input.base, \"base\", namespace), \"base\", namespace);\n const tombstoned = parseTombstonedDigests(input.tombstonedFileSha256, namespace);\n const peerTombstoned = parseTombstonedDigests(\n input.peerTombstonedFileSha256,\n namespace,\n \"peerTombstonedFileSha256\",\n );\n const localDeletionMtimeMs = parseDeletionMtimes(input.localDeletionMtimeMs, \"local\", namespace);\n const peerDeletionMtimeMs = parseDeletionMtimes(input.peerDeletionMtimeMs, \"peer\", namespace);\n const entries: ReconcilePlanEntry[] = [];\n\n // Path -> digest only, never the file objects: enough to make the stream\n // idempotent and to catch contradictory duplicates without materializing the\n // second census.\n // Base paths participate in the collision check: a base `Facts/A.md` against\n // a local `facts/a.md` is the same delete/change ambiguity on a\n // case-insensitive participant.\n if (base) for (const basePath of base.keys()) assertNoPathAlias(caseFold, basePath, namespace);\n // Path -> decision-relevant fields only, never the whole record: enough to\n // make the stream idempotent and to catch contradictory duplicates without\n // materializing the second census.\n const seenLocal = new Map<string, { sha256: string; mtimeMs?: number }>();\n for (const rawLocal of localCensus) {\n const localFile = assertCensusRecord(rawLocal, \"local\", namespace);\n const path = localFile.path;\n assertNoPathAlias(caseFold, path, namespace);\n const seen = seenLocal.get(path);\n if (seen !== undefined) {\n // Same rule the indexed censuses get: mtimeMs is decision-relevant under\n // `newest-wins`, so a duplicate that disagrees on it is ambiguous too.\n if (rejectConflictingDuplicate(seen, localFile, path, \"local\", namespace)) continue;\n }\n seenLocal.set(path, { sha256: localFile.sha256, mtimeMs: localFile.mtimeMs });\n const peerFile = peer.get(path);\n // Consumed: whatever remains in the index afterwards is peer-only.\n peer.delete(path);\n const baseSha256 = base?.get(path);\n // Retraction outranks every other decision for this path, on EITHER side.\n // Checked before hash comparison and conflict resolution: a retracted peer\n // revision reaching the conflict ladder can win under `newest-wins`, and a\n // retracted LOCAL revision would otherwise be pushed - which is also how a\n // suppression undoes itself on the next run, since the local copy survives\n // the peer-side delete (round 4).\n // Either side's retraction removes the copy that carries the digest, so a\n // peer retraction of something we still hold suppresses OUR copy rather\n // than pushing it back.\n const localRetracted = tombstoned.has(localFile.sha256) || peerTombstoned.has(localFile.sha256);\n const peerRetracted =\n peerFile !== undefined && (tombstoned.has(peerFile.sha256) || peerTombstoned.has(peerFile.sha256));\n if (localRetracted || peerRetracted) {\n entries.push({\n path,\n namespace,\n action: \"suppress\",\n reason: \"tombstoned\",\n localSha256: localFile.sha256,\n ...(peerFile ? { peerSha256: peerFile.sha256 } : {}),\n ...(baseSha256 === undefined ? {} : { baseSha256 }),\n suppressSide: localRetracted && peerRetracted ? \"both\" : localRetracted ? \"local\" : \"peer\",\n });\n continue;\n }\n if (!peerFile) {\n // Base PRESENCE is what proves a deletion, not equality with whatever the\n // surviving side now holds. If we also edited since the base, this is\n // delete-versus-modify: still a conflict, and pushing it would resurrect\n // a deliberate deletion. Without a base the peer simply never saw the\n // path, and a bootstrap merge must push — both sides hold unique data.\n if (baseSha256 !== undefined) {\n const peerDeletionMtime = peerDeletionMtimeMs.get(path);\n const resolution = baseSha256 === localFile.sha256\n ? \"unresolved\"\n : resolveConflict(\n policy,\n localFile.mtimeMs,\n peerDeletionMtime,\n \"unresolved\",\n );\n entries.push({\n path,\n namespace,\n action: \"conflict\",\n reason: baseSha256 === localFile.sha256 ? \"peer_deleted\" : \"local_modified_peer_deleted\",\n localSha256: localFile.sha256,\n baseSha256,\n resolution,\n ...(resolution === \"peer-wins\" && peerDeletionMtime !== undefined\n ? { deletionMtimeMs: peerDeletionMtime }\n : {}),\n });\n continue;\n }\n entries.push({\n path,\n namespace,\n action: \"push\",\n reason: \"local_only\",\n localSha256: localFile.sha256,\n });\n continue;\n }\n if (peerFile.sha256 === localFile.sha256) {\n entries.push({\n path,\n namespace,\n action: \"identical\",\n reason: \"same_content\",\n localSha256: localFile.sha256,\n peerSha256: peerFile.sha256,\n ...(baseSha256 === undefined ? {} : { baseSha256 }),\n });\n continue;\n }\n // A base that matches one side turns a \"conflict\" into an ordinary\n // one-sided change: that side is the only one that moved since agreement.\n if (baseSha256 !== undefined && baseSha256 === localFile.sha256) {\n entries.push({\n path,\n namespace,\n action: \"pull\",\n reason: \"peer_changed\",\n localSha256: localFile.sha256,\n peerSha256: peerFile.sha256,\n baseSha256,\n });\n continue;\n }\n if (baseSha256 !== undefined && baseSha256 === peerFile.sha256) {\n entries.push({\n path,\n namespace,\n action: \"push\",\n reason: \"local_changed\",\n localSha256: localFile.sha256,\n peerSha256: peerFile.sha256,\n baseSha256,\n });\n continue;\n }\n const resolution = resolveConflict(\n policy,\n localFile.mtimeMs,\n peerFile.mtimeMs,\n \"supersede-link\",\n );\n entries.push({\n path,\n namespace,\n action: \"conflict\",\n reason: \"both_modified\",\n localSha256: localFile.sha256,\n peerSha256: peerFile.sha256,\n ...(baseSha256 === undefined ? {} : { baseSha256 }),\n resolution,\n });\n }\n\n for (const [path, peerFile] of peer) {\n assertNoPathAlias(caseFold, path, namespace);\n const baseSha256 = base?.get(path);\n if (tombstoned.has(peerFile.sha256) || peerTombstoned.has(peerFile.sha256)) {\n // Retracted here on purpose, and the peer still serves it. Pulling it\n // back would undo the retraction; calling it `identical` would be worse,\n // because a converged plan lets transport skip everything and the peer\n // keeps serving the retracted fact forever. It is work: propagate the\n // tombstone.\n entries.push({\n path,\n namespace,\n action: \"suppress\",\n reason: \"tombstoned\",\n peerSha256: peerFile.sha256,\n ...(baseSha256 === undefined ? {} : { baseSha256 }),\n suppressSide: \"peer\",\n });\n continue;\n }\n if (baseSha256 !== undefined) {\n const localDeletionMtime = localDeletionMtimeMs.get(path);\n const resolution = baseSha256 === peerFile.sha256\n ? \"unresolved\"\n : resolveConflict(\n policy,\n localDeletionMtime,\n peerFile.mtimeMs,\n \"unresolved\",\n );\n entries.push({\n path,\n namespace,\n action: \"conflict\",\n reason: baseSha256 === peerFile.sha256 ? \"local_deleted\" : \"local_deleted_peer_modified\",\n peerSha256: peerFile.sha256,\n baseSha256,\n resolution,\n ...(resolution === \"local-wins\" && localDeletionMtime !== undefined\n ? { deletionMtimeMs: localDeletionMtime }\n : {}),\n });\n continue;\n }\n entries.push({\n path,\n namespace,\n action: \"pull\",\n reason: \"peer_only\",\n peerSha256: peerFile.sha256,\n });\n }\n\n return entries.sort(compareEntries);\n}\n\n/** Aggregate entries into the per-namespace convergence report (#2150). */\nexport function summarizeReconcilePlan(entries: readonly ReconcilePlanEntry[]): ReconcileNamespaceReport[] {\n const byNamespace = new Map<string, ReconcileNamespaceReport>();\n for (const entry of entries) {\n let report = byNamespace.get(entry.namespace);\n if (!report) {\n report = { namespace: entry.namespace, pull: 0, push: 0, identical: 0, conflict: 0, suppress: 0, unresolved: 0 };\n byNamespace.set(entry.namespace, report);\n }\n report[entry.action] += 1;\n const needsOperator =\n entry.resolution === \"unresolved\"\n || entry.resolution === \"supersede-link\";\n if (entry.action === \"conflict\" && needsOperator) report.unresolved += 1;\n }\n return [...byNamespace.values()].sort((a, b) => (a.namespace === b.namespace ? 0 : a.namespace < b.namespace ? -1 : 1));\n}\n\n/**\n * Plan a full reconciliation across namespaces.\n *\n * `converged` is an affirmative claim that nothing needs to move, so it is\n * derived from the entries rather than tracked alongside them: any action other\n * than `identical` disproves it.\n */\nexport function planReconciliation(\n namespaces: readonly ReconcileNamespaceInput[],\n options: ReconcileOptions = {},\n): ReconcilePlan {\n if (!Array.isArray(namespaces)) {\n throw new ReconcilePlanInputError(\"reconcile: planReconciliation expects an array of namespace inputs\");\n }\n // Validated here too: with an empty array the per-namespace path never runs,\n // and a malformed options envelope would return `converged` instead of\n // raising - the same call failing or succeeding based on list length.\n if (!isPlainObject(options)) {\n throw new ReconcilePlanInputError(\"reconcile: options must be a plain object\");\n }\n assertConflictPolicy(options.conflictPolicy);\n const entries: ReconcilePlanEntry[] = [];\n // Two inputs for one namespace are planned independently, so the same\n // (namespace, path) can draw contradictory actions - and because those\n // entries also sort equal, batch order would decide which revision survives.\n const seenNamespaces = new Set<string>();\n for (const namespace of namespaces) {\n const name = assertNamespace(namespace?.namespace);\n if (seenNamespaces.has(name)) {\n throw new ReconcilePlanInputError(\n `reconcile: namespace ${name} appears twice; merge its censuses before planning`,\n );\n }\n seenNamespaces.add(name);\n entries.push(...planNamespaceReconciliation(namespace, options));\n }\n entries.sort(compareEntries);\n return {\n entries,\n byNamespace: summarizeReconcilePlan(entries),\n converged: entries.every((entry) => entry.action === \"identical\"),\n };\n}\n"],"mappings":"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","names":["resolution"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  throwIfAborted
3
- } from "./chunk-PVGDJXVK.js";
3
+ } from "./chunk-BTTPKDIL.js";
4
4
 
5
5
  // src/search/abort.ts
6
6
  function isSearchAborted(execution) {
@@ -19,4 +19,4 @@ export {
19
19
  throwIfSearchAborted,
20
20
  withTimeoutSignal
21
21
  };
22
- //# sourceMappingURL=chunk-CINZGPSJ.js.map
22
+ //# sourceMappingURL=chunk-GUMZC2BO.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  withTimeoutSignal
3
- } from "./chunk-CINZGPSJ.js";
3
+ } from "./chunk-GUMZC2BO.js";
4
4
  import {
5
5
  getHostEmbeddingProvider,
6
6
  normalizeHostEmbeddingVector
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-2XRE6FLM.js";
13
13
  import {
14
14
  isAbortError
15
- } from "./chunk-PVGDJXVK.js";
15
+ } from "./chunk-BTTPKDIL.js";
16
16
  import {
17
17
  log
18
18
  } from "./chunk-3WCASNQZ.js";
@@ -310,4 +310,4 @@ function normalizeHttpEmbeddingVector(vector) {
310
310
  export {
311
311
  EmbedHelper
312
312
  };
313
- //# sourceMappingURL=chunk-H24WNPA2.js.map
313
+ //# sourceMappingURL=chunk-GWFSVJ4P.js.map
@@ -16,7 +16,7 @@ import {
16
16
  import {
17
17
  MAGIC_HEADER_SIZE,
18
18
  isEncryptedFile
19
- } from "./chunk-5TFP4CUL.js";
19
+ } from "./chunk-XQ3HXAQH.js";
20
20
 
21
21
  // src/offline-sync.ts
22
22
  import { createHash, randomUUID } from "crypto";
@@ -175,6 +175,63 @@ function normalizeFileStates(input) {
175
175
  }
176
176
  return input.map((entry, index) => normalizeFileState(entry, `baseFiles[${index}]`));
177
177
  }
178
+ function normalizeDeletionRevisions(input, fieldPrefix) {
179
+ if (input === void 0) return void 0;
180
+ if (!Array.isArray(input)) {
181
+ throw new Error(`${fieldPrefix} must be an array`);
182
+ }
183
+ const deletions = input.map((entry, index) => {
184
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
185
+ throw new Error(`${fieldPrefix}[${index}] must be an object`);
186
+ }
187
+ const obj = entry;
188
+ return {
189
+ path: normalizeRelativePath(obj.path, `${fieldPrefix}[${index}].path`),
190
+ mtimeMs: assertOfflineSyncMtimeMs(obj.mtimeMs, `${fieldPrefix}[${index}].mtimeMs`)
191
+ };
192
+ });
193
+ assertUniquePaths(deletions, fieldPrefix);
194
+ return deletions.sort(compareByPath);
195
+ }
196
+ function snapshotBuilderDeletions(options) {
197
+ const deletions = normalizeDeletionRevisions(options.deletions, "deletions");
198
+ if (deletions === void 0) return void 0;
199
+ if (deletions.length === 0) return deletions;
200
+ const presentPaths = new Set(options.files.map((file) => file.path.toLowerCase()));
201
+ const scopedPaths = options.paths ? new Set(options.paths.map((relPath) => relPath.toLowerCase())) : void 0;
202
+ return deletions.filter((deletion) => (scopedPaths === void 0 || scopedPaths.has(deletion.path.toLowerCase())) && !presentPaths.has(deletion.path.toLowerCase()) && !(options.excludeNodeLocalState === false ? shouldExcludeRelPath(deletion.path, options.includeTranscripts) : shouldExcludePushRelPath(
203
+ deletion.path,
204
+ options.includeTranscripts,
205
+ options.userExcludeRegexps
206
+ )));
207
+ }
208
+ async function filterOfflineSyncDeletionRevisions(options) {
209
+ const deletions = normalizeDeletionRevisions(options.deletions, "deletions");
210
+ if (deletions === void 0) throw new Error("deletions must be an array");
211
+ if (deletions.length === 0) return deletions;
212
+ const root = await prepareSafeArchiveRoot(
213
+ path.resolve(options.root),
214
+ "filterOfflineSyncDeletionRevisions",
215
+ "root"
216
+ );
217
+ const includeTranscripts = options.includeTranscripts !== false;
218
+ const filtered = [];
219
+ for (const deletion of deletions) {
220
+ if (shouldExcludePushRelPath(deletion.path, includeTranscripts, options.userExcludeRegexps)) {
221
+ continue;
222
+ }
223
+ const filePath = path.join(root.abs, ...deletion.path.split("/"));
224
+ const present = await lstat(filePath).then(
225
+ () => true,
226
+ (error) => {
227
+ if (error.code === "ENOENT") return false;
228
+ throw error;
229
+ }
230
+ );
231
+ if (!present) filtered.push(deletion);
232
+ }
233
+ return filtered;
234
+ }
178
235
  function normalizeOfflineSyncSnapshot(input, options = {}) {
179
236
  if (!input || typeof input !== "object" || Array.isArray(input)) {
180
237
  throw new Error("offline sync snapshot must be an object");
@@ -193,16 +250,18 @@ function normalizeOfflineSyncSnapshot(input, options = {}) {
193
250
  throw new Error("offline sync snapshot files must be an array");
194
251
  }
195
252
  const files = obj.files.map((entry, index) => normalizeFileRecord(entry, `files[${index}]`, options.requireContent === true)).filter((file) => !shouldIgnoreIncomingRuntimePath(file.path)).sort(compareByPath);
196
- assertUniquePaths(files, "offline sync snapshot");
253
+ const deletions = normalizeDeletionRevisions(obj.deletions, "deletions")?.filter((deletion) => !shouldIgnoreIncomingRuntimePath(deletion.path));
254
+ const entries = deletions && deletions.length > 0 ? [...files, ...deletions] : files;
255
+ assertUniquePaths(entries, "offline sync snapshot");
197
256
  if (!includeTranscripts) {
198
- const transcriptPath = files.find((file) => file.path.split("/")[0] === "transcripts")?.path;
257
+ const transcriptPath = entries.find((entry) => entry.path.split("/")[0] === "transcripts")?.path;
199
258
  if (transcriptPath) {
200
259
  throw new Error(
201
260
  `offline sync snapshot includeTranscripts is false but contains transcript path: ${transcriptPath}`
202
261
  );
203
262
  }
204
263
  }
205
- const excludedPath = files.find((file) => shouldExcludeRelPath(file.path, true))?.path;
264
+ const excludedPath = entries.find((entry) => shouldExcludeRelPath(entry.path, true))?.path;
206
265
  if (excludedPath) {
207
266
  throw new Error(`offline sync snapshot contains excluded path: ${excludedPath}`);
208
267
  }
@@ -212,7 +271,8 @@ function normalizeOfflineSyncSnapshot(input, options = {}) {
212
271
  createdAt,
213
272
  sourceId,
214
273
  includeTranscripts,
215
- files
274
+ files,
275
+ ...deletions === void 0 ? {} : { deletions }
216
276
  };
217
277
  }
218
278
  function normalizeOfflineSyncChangeset(input) {
@@ -257,10 +317,12 @@ function normalizeOfflineSyncChangeset(input) {
257
317
  };
258
318
  }
259
319
  if (type === "delete") {
320
+ const mtimeMs = change.mtimeMs === void 0 ? void 0 : assertOfflineSyncMtimeMs(change.mtimeMs, `changes[${index}].mtimeMs`);
260
321
  return {
261
322
  type: "delete",
262
323
  path: relPath,
263
- baseSha256: assertSha256(change.baseSha256, `changes[${index}].baseSha256`)
324
+ baseSha256: assertSha256(change.baseSha256, `changes[${index}].baseSha256`),
325
+ ...mtimeMs === void 0 ? {} : { mtimeMs }
264
326
  };
265
327
  }
266
328
  throw new Error(`changes[${index}].type must be "upsert" or "delete"`);
@@ -313,7 +375,12 @@ function assertUniquePaths(entries, context) {
313
375
  seen.add(key);
314
376
  }
315
377
  }
378
+ function isInternalRemnicStatePath(relPosix) {
379
+ const normalized = relPosix.includes("\\") ? relPosix.replaceAll("\\", "/") : relPosix;
380
+ return normalized === ".remnic" || normalized.startsWith(".remnic/") || normalized.endsWith("/.remnic") || normalized.includes("/.remnic/");
381
+ }
316
382
  function shouldExcludeRelPath(relPosix, includeTranscripts) {
383
+ if (isInternalRemnicStatePath(relPosix)) return true;
317
384
  const parts = relPosix.split("/");
318
385
  if (parts.some((part) => DEFAULT_TRANSFER_EXCLUDE_DIRS.has(part))) return true;
319
386
  if (parts.some((part) => part === SYNC_INTERNAL_DIR)) return true;
@@ -366,6 +433,7 @@ function parseOfflineSyncExcludes(raw) {
366
433
  return globs;
367
434
  }
368
435
  function shouldIgnoreIncomingRuntimePath(relPosix) {
436
+ if (isInternalRemnicStatePath(relPosix)) return true;
369
437
  const parts = relPosix.split("/");
370
438
  const basename = parts[parts.length - 1] ?? "";
371
439
  return isCanonicalRuntimeStatePath(parts) && basename.includes(".tmp-");
@@ -521,13 +589,22 @@ async function buildOfflineSyncSnapshot(options) {
521
589
  const files = [];
522
590
  for await (const file of iterateOfflineSyncSnapshotFileRecords(options)) files.push(file);
523
591
  throwIfOfflineSyncAborted(options.signal);
592
+ const sortedFiles = files.sort(compareByPath);
593
+ const deletions = snapshotBuilderDeletions({
594
+ deletions: options.deletions,
595
+ files: sortedFiles,
596
+ includeTranscripts,
597
+ excludeNodeLocalState: options.excludeNodeLocalState,
598
+ userExcludeRegexps: options.userExcludeRegexps
599
+ });
524
600
  return {
525
601
  format: OFFLINE_SYNC_SNAPSHOT_FORMAT,
526
602
  schemaVersion: 1,
527
603
  createdAt: (options.now ?? /* @__PURE__ */ new Date()).toISOString(),
528
604
  sourceId: normalizeSourceId(options.sourceId, "sourceId"),
529
605
  includeTranscripts,
530
- files: files.sort(compareByPath)
606
+ files: sortedFiles,
607
+ ...deletions === void 0 ? {} : { deletions }
531
608
  };
532
609
  }
533
610
  async function buildOfflineSyncSnapshotFromBase(options) {
@@ -576,13 +653,22 @@ async function buildOfflineSyncSnapshotFromBase(options) {
576
653
  }
577
654
  await walk(root.abs);
578
655
  throwIfOfflineSyncAborted(options.signal);
656
+ const sortedFiles = files.sort(compareByPath);
657
+ const deletions = snapshotBuilderDeletions({
658
+ deletions: options.deletions,
659
+ files: sortedFiles,
660
+ includeTranscripts,
661
+ excludeNodeLocalState: options.excludeNodeLocalState,
662
+ userExcludeRegexps: options.userExcludeRegexps
663
+ });
579
664
  return {
580
665
  format: OFFLINE_SYNC_SNAPSHOT_FORMAT,
581
666
  schemaVersion: 1,
582
667
  createdAt: (options.now ?? /* @__PURE__ */ new Date()).toISOString(),
583
668
  sourceId: normalizeSourceId(options.sourceId, "sourceId"),
584
669
  includeTranscripts,
585
- files: files.sort(compareByPath)
670
+ files: sortedFiles,
671
+ ...deletions === void 0 ? {} : { deletions }
586
672
  };
587
673
  }
588
674
  async function buildOfflineSyncSnapshotForPaths(options) {
@@ -617,13 +703,23 @@ async function buildOfflineSyncSnapshotForPaths(options) {
617
703
  }));
618
704
  }
619
705
  throwIfOfflineSyncAborted(options.signal);
706
+ const sortedFiles = files.sort(compareByPath);
707
+ const deletions = snapshotBuilderDeletions({
708
+ deletions: options.deletions,
709
+ files: sortedFiles,
710
+ paths: [...seen],
711
+ includeTranscripts,
712
+ excludeNodeLocalState: options.excludeNodeLocalState,
713
+ userExcludeRegexps: options.userExcludeRegexps
714
+ });
620
715
  return {
621
716
  format: OFFLINE_SYNC_SNAPSHOT_FORMAT,
622
717
  schemaVersion: 1,
623
718
  createdAt: (options.now ?? /* @__PURE__ */ new Date()).toISOString(),
624
719
  sourceId: normalizeSourceId(options.sourceId, "sourceId"),
625
720
  includeTranscripts,
626
- files: files.sort(compareByPath)
721
+ files: sortedFiles,
722
+ ...deletions === void 0 ? {} : { deletions }
627
723
  };
628
724
  }
629
725
  async function readOfflineSyncFileContentChunk(options) {
@@ -695,6 +791,7 @@ async function buildOfflineSyncChangeset(options) {
695
791
  root: options.root,
696
792
  sourceId: options.sourceId,
697
793
  baseFiles: options.baseFiles,
794
+ deletions: options.deletions,
698
795
  baseCapturedAt: options.baseCapturedAt,
699
796
  includeContent: false,
700
797
  includeTranscripts,
@@ -708,6 +805,7 @@ async function buildOfflineSyncChangeset(options) {
708
805
  sourceId: options.sourceId,
709
806
  baseFiles: options.baseFiles,
710
807
  currentFiles: current.files,
808
+ deletions: current.deletions,
711
809
  excludePaths: options.excludePaths,
712
810
  includeTranscripts,
713
811
  now: options.now,
@@ -728,6 +826,8 @@ async function buildOfflineSyncChangesetFromSnapshot(options) {
728
826
  normalizeFileStates(options.currentFiles),
729
827
  includeTranscripts
730
828
  ));
829
+ const deletions = normalizeDeletionRevisions(options.deletions, "deletions");
830
+ const deletionMtimeByPath = deletions === void 0 ? void 0 : new Map(deletions.map((deletion) => [deletion.path, deletion.mtimeMs]));
731
831
  const changes = [];
732
832
  for (const relPath of unionPaths(base, currentMap)) {
733
833
  if (excludedPaths.has(relPath)) continue;
@@ -759,10 +859,12 @@ async function buildOfflineSyncChangesetFromSnapshot(options) {
759
859
  continue;
760
860
  }
761
861
  if (!currentEntry && baseEntry) {
862
+ const mtimeMs = deletionMtimeByPath?.get(relPath);
762
863
  changes.push({
763
864
  type: "delete",
764
865
  path: relPath,
765
- baseSha256: baseEntry.sha256
866
+ baseSha256: baseEntry.sha256,
867
+ ...mtimeMs === void 0 ? {} : { mtimeMs }
766
868
  });
767
869
  }
768
870
  }
@@ -843,6 +945,7 @@ async function applyOfflineSyncSnapshot(options) {
843
945
  snapshot.includeTranscripts
844
946
  ));
845
947
  const incomingMap = byPath(snapshot.files);
948
+ const deletionMtimeByPath = snapshot.deletions === void 0 ? void 0 : new Map(snapshot.deletions.map((deletion) => [deletion.path, deletion.mtimeMs]));
846
949
  const incomingBuffers = verifyRecordContents(snapshot.files, "offline sync snapshot", {
847
950
  requireContent: false
848
951
  });
@@ -858,6 +961,19 @@ async function applyOfflineSyncSnapshot(options) {
858
961
  })).files;
859
962
  const currentMap = byPath(currentFiles);
860
963
  const deferredPaths = new Set(options.deferredPaths ?? []);
964
+ if (deletionMtimeByPath && options.recordDeletionRevision) {
965
+ for (const [relPath, mtimeMs] of deletionMtimeByPath) {
966
+ if (currentMap.has(relPath) || deferredPaths.has(relPath) || matchesOfflineSyncDefaultExclude(relPath)) {
967
+ continue;
968
+ }
969
+ await options.recordDeletionRevision({
970
+ root: root.abs,
971
+ path: relPath,
972
+ filePath: await resolveSafeArchiveTarget(root, relPath),
973
+ mtimeMs
974
+ });
975
+ }
976
+ }
861
977
  const nextBase = new Map(baseMap);
862
978
  const conflicts = [];
863
979
  let upserted = 0;
@@ -968,7 +1084,12 @@ async function applyOfflineSyncSnapshot(options) {
968
1084
  continue;
969
1085
  }
970
1086
  if (shouldPreferIncomingOfflineRuntimeFile(relPath) && (base || shouldDeleteAbsentIncomingOfflineRuntimeFile(relPath))) {
971
- await deleteSafeFile(root, relPath, options.deleteFile);
1087
+ await deleteSafeFile(
1088
+ root,
1089
+ relPath,
1090
+ options.deleteFile,
1091
+ deletionMtimeByPath?.get(relPath)
1092
+ );
972
1093
  nextBase.delete(relPath);
973
1094
  deleted += 1;
974
1095
  continue;
@@ -979,7 +1100,12 @@ async function applyOfflineSyncSnapshot(options) {
979
1100
  continue;
980
1101
  }
981
1102
  if (base && currentEntry.sha256 === base.sha256) {
982
- await deleteSafeFile(root, relPath, options.deleteFile);
1103
+ await deleteSafeFile(
1104
+ root,
1105
+ relPath,
1106
+ options.deleteFile,
1107
+ deletionMtimeByPath?.get(relPath)
1108
+ );
983
1109
  nextBase.delete(relPath);
984
1110
  deleted += 1;
985
1111
  continue;
@@ -1088,11 +1214,19 @@ async function applyOfflineSyncChangeset(options) {
1088
1214
  continue;
1089
1215
  }
1090
1216
  if (!currentEntry) {
1217
+ if (change.mtimeMs !== void 0 && options.recordDeletionRevision) {
1218
+ await options.recordDeletionRevision({
1219
+ root: root.abs,
1220
+ path: change.path,
1221
+ filePath: await resolveSafeArchiveTarget(root, change.path),
1222
+ mtimeMs: change.mtimeMs
1223
+ });
1224
+ }
1091
1225
  skipped += 1;
1092
1226
  continue;
1093
1227
  }
1094
1228
  if (currentEntry.sha256 === change.baseSha256) {
1095
- await deleteSafeFile(root, change.path, options.deleteFile);
1229
+ await deleteSafeFile(root, change.path, options.deleteFile, change.mtimeMs);
1096
1230
  currentMap.delete(change.path);
1097
1231
  appliedDeletes += 1;
1098
1232
  continue;
@@ -1630,10 +1764,15 @@ async function writeOfflineUploadContent(options) {
1630
1764
  content: options.content
1631
1765
  });
1632
1766
  }
1633
- async function deleteSafeFile(root, relPath, deleteFile) {
1767
+ async function deleteSafeFile(root, relPath, deleteFile, mtimeMs) {
1634
1768
  const target = await resolveSafeArchiveTarget(root, relPath);
1635
1769
  if (deleteFile) {
1636
- await deleteFile({ root: root.abs, path: relPath, filePath: target });
1770
+ await deleteFile({
1771
+ root: root.abs,
1772
+ path: relPath,
1773
+ filePath: target,
1774
+ ...mtimeMs === void 0 ? {} : { mtimeMs }
1775
+ });
1637
1776
  return;
1638
1777
  }
1639
1778
  await unlink(target).catch((error) => {
@@ -1735,8 +1874,10 @@ export {
1735
1874
  OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES,
1736
1875
  OFFLINE_SYNC_MAX_MTIME_MS,
1737
1876
  globToRegExp,
1877
+ filterOfflineSyncDeletionRevisions,
1738
1878
  normalizeOfflineSyncSnapshot,
1739
1879
  normalizeOfflineSyncChangeset,
1880
+ isInternalRemnicStatePath,
1740
1881
  compileOfflineSyncExcludeGlobs,
1741
1882
  parseOfflineSyncExcludes,
1742
1883
  shouldPreferIncomingOfflineRuntimeFile,
@@ -1760,4 +1901,4 @@ export {
1760
1901
  normalizeOfflineSyncState,
1761
1902
  fileStatesFromSnapshot
1762
1903
  };
1763
- //# sourceMappingURL=chunk-7XC2HX75.js.map
1904
+ //# sourceMappingURL=chunk-GYPQL6XN.js.map