@remnic/core 9.3.719 → 9.3.721

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 (387) hide show
  1. package/dist/access-boundary.d.ts +10 -7
  2. package/dist/access-boundary.js +37 -34
  3. package/dist/access-cli.js +71 -66
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +11 -8
  6. package/dist/access-http.js +44 -41
  7. package/dist/access-mcp.d.ts +11 -8
  8. package/dist/access-mcp.js +40 -37
  9. package/dist/access-operations-batch.js +38 -35
  10. package/dist/access-operations.d.ts +11 -8
  11. package/dist/access-operations.js +39 -36
  12. package/dist/access-schema.d.ts +19 -19
  13. package/dist/access-schema.js +3 -3
  14. package/dist/{access-service-CZbnt0t2.d.ts → access-service-Dj3I-VBS.d.ts} +3 -3
  15. package/dist/access-service.d.ts +11 -8
  16. package/dist/access-service.js +36 -33
  17. package/dist/access-surface-catalog.d.ts +10 -7
  18. package/dist/action-confidence.d.ts +1 -1
  19. package/dist/active-memory-bridge.d.ts +1 -1
  20. package/dist/active-recall.d.ts +1 -1
  21. package/dist/active-recall.js +4 -2
  22. package/dist/active-recall.js.map +1 -1
  23. package/dist/adapters/index.js +7 -7
  24. package/dist/adapters/registry.js +3 -3
  25. package/dist/{auto-sync-24NNS3GU.js → auto-sync-F3KCSQFJ.js} +5 -5
  26. package/dist/behavior-learner.d.ts +1 -1
  27. package/dist/behavior-signals.d.ts +1 -1
  28. package/dist/bootstrap.d.ts +11 -8
  29. package/dist/briefing.d.ts +1 -1
  30. package/dist/briefing.js +12 -10
  31. package/dist/buffer-surprise-report.d.ts +1 -1
  32. package/dist/buffer.d.ts +1 -1
  33. package/dist/calibration.d.ts +1 -1
  34. package/dist/calibration.js +2 -2
  35. package/dist/capabilities.d.ts +30 -2
  36. package/dist/capabilities.js +3 -1
  37. package/dist/{catalog-CEYlMs9X.d.ts → catalog-F-OEVbRQ.d.ts} +1 -1
  38. package/dist/causal-behavior.d.ts +1 -1
  39. package/dist/causal-behavior.js +2 -2
  40. package/dist/causal-chain.js +2 -2
  41. package/dist/causal-consolidation.d.ts +1 -1
  42. package/dist/causal-consolidation.js +15 -13
  43. package/dist/causal-consolidation.js.map +1 -1
  44. package/dist/causal-retrieval.js +2 -2
  45. package/dist/causal-trajectory-graph.d.ts +4 -0
  46. package/dist/causal-trajectory-graph.js +2 -2
  47. package/dist/causal-trajectory.js +1 -1
  48. package/dist/{chunk-TH7WMHVK.js → chunk-3NN73CM7.js} +2 -2
  49. package/dist/{chunk-A5TUPZ3N.js → chunk-4SF232E6.js} +60 -30
  50. package/dist/chunk-4SF232E6.js.map +1 -0
  51. package/dist/{chunk-DGTDRIUO.js → chunk-4T3BMHKD.js} +2 -2
  52. package/dist/{chunk-EH27LHML.js → chunk-5O42UKXI.js} +2 -2
  53. package/dist/{chunk-KRGC4EDX.js → chunk-6FAMMBQ3.js} +2 -2
  54. package/dist/{chunk-FEB7W5JG.js → chunk-6OIDDKAA.js} +27 -6
  55. package/dist/chunk-6OIDDKAA.js.map +1 -0
  56. package/dist/{chunk-67HG7KFE.js → chunk-6YKIYQU7.js} +2 -2
  57. package/dist/{chunk-LXSG4L55.js → chunk-7CTNUVHZ.js} +2 -2
  58. package/dist/{chunk-UCJ5CDTK.js → chunk-A5XNBK2D.js} +22 -14
  59. package/dist/chunk-A5XNBK2D.js.map +1 -0
  60. package/dist/{chunk-7EEVXW7X.js → chunk-A7TJZLPK.js} +2 -2
  61. package/dist/{chunk-P5IPFZVH.js → chunk-B7WISIAJ.js} +5 -5
  62. package/dist/chunk-BCDKBDSY.js +173 -0
  63. package/dist/chunk-BCDKBDSY.js.map +1 -0
  64. package/dist/{chunk-JAKYZGV4.js → chunk-BXEOHV7K.js} +3 -3
  65. package/dist/chunk-C4X4QGIO.js +60 -0
  66. package/dist/chunk-C4X4QGIO.js.map +1 -0
  67. package/dist/{chunk-S3OPGGZB.js → chunk-D7EBTQ24.js} +2 -2
  68. package/dist/{chunk-IO5NQEGZ.js → chunk-DKT3X5C3.js} +2 -2
  69. package/dist/{chunk-PBH4JUAB.js → chunk-DVRHLN2O.js} +18 -3
  70. package/dist/chunk-DVRHLN2O.js.map +1 -0
  71. package/dist/{chunk-S35FX6MU.js → chunk-EBDA5TYA.js} +2 -2
  72. package/dist/{chunk-2PTBLS2S.js → chunk-EDOQM4E4.js} +2 -2
  73. package/dist/{chunk-YTZLBBEB.js → chunk-EEJMD2L2.js} +3 -3
  74. package/dist/{chunk-YGKUAX2B.js → chunk-EHQ5HO5T.js} +11 -11
  75. package/dist/chunk-EHQ5HO5T.js.map +1 -0
  76. package/dist/{chunk-JIZGYQYH.js → chunk-EM2LDXJ2.js} +4 -4
  77. package/dist/{chunk-YYOK4GVF.js → chunk-EVPNWN7Z.js} +10 -10
  78. package/dist/{chunk-HLIR3RJ7.js → chunk-EXUCUPV2.js} +2 -2
  79. package/dist/{chunk-F3PVXKHP.js → chunk-GDUOCHCD.js} +27 -21
  80. package/dist/chunk-GDUOCHCD.js.map +1 -0
  81. package/dist/{chunk-L5ASZA2F.js → chunk-GJSL4WG2.js} +17 -2
  82. package/dist/chunk-GJSL4WG2.js.map +1 -0
  83. package/dist/{chunk-2SXMCQEQ.js → chunk-GZQXOQQ2.js} +3 -3
  84. package/dist/{chunk-2KAYTPPT.js → chunk-HCVWF657.js} +12 -12
  85. package/dist/{chunk-N3DUH6OO.js → chunk-ILFSEIRT.js} +1 -1
  86. package/dist/chunk-ILFSEIRT.js.map +1 -0
  87. package/dist/{chunk-4KZGLDJJ.js → chunk-J3JPB7ZI.js} +2 -2
  88. package/dist/{chunk-3JJWNZTT.js → chunk-L2B3EE7B.js} +102 -42
  89. package/dist/chunk-L2B3EE7B.js.map +1 -0
  90. package/dist/{chunk-NFRBADNR.js → chunk-LA3HZKES.js} +610 -369
  91. package/dist/chunk-LA3HZKES.js.map +1 -0
  92. package/dist/{chunk-LQ6JI4VH.js → chunk-LD53WPMU.js} +4 -4
  93. package/dist/{chunk-URM3HW2R.js → chunk-LLUGAZ3B.js} +2 -2
  94. package/dist/{chunk-RVLB4E6N.js → chunk-MDBZTH7N.js} +5 -32
  95. package/dist/chunk-MDBZTH7N.js.map +1 -0
  96. package/dist/{chunk-U5H7WHTS.js → chunk-N77ELJ2D.js} +4 -4
  97. package/dist/{chunk-2VHMVWPU.js → chunk-NXRUUDUF.js} +2 -2
  98. package/dist/{chunk-DIFU33GU.js → chunk-OHTOPFRF.js} +2 -2
  99. package/dist/{chunk-74MYJSKB.js → chunk-ORAK3LNZ.js} +2 -2
  100. package/dist/{chunk-REWQAFSA.js → chunk-PD42EYQN.js} +2 -2
  101. package/dist/chunk-PHK3HARR.js +32 -0
  102. package/dist/chunk-PHK3HARR.js.map +1 -0
  103. package/dist/{chunk-773DPI6T.js → chunk-PKMQK2WY.js} +4 -4
  104. package/dist/{chunk-72VDBALG.js → chunk-QD6QP5P6.js} +63 -54
  105. package/dist/chunk-QD6QP5P6.js.map +1 -0
  106. package/dist/{chunk-CTOQEZSN.js → chunk-QR67FU5G.js} +2 -2
  107. package/dist/{chunk-AU7Q3LSC.js → chunk-RKNJBZ55.js} +7 -7
  108. package/dist/{chunk-YI7RZO7Y.js → chunk-SQNED75R.js} +1 -1
  109. package/dist/{chunk-5CEJH5ZN.js → chunk-TAPSNIMA.js} +4 -4
  110. package/dist/{chunk-IF362TF6.js → chunk-TQT3USCG.js} +2 -2
  111. package/dist/chunk-TQT3USCG.js.map +1 -0
  112. package/dist/{chunk-5RHM43BJ.js → chunk-TXQCG6SE.js} +3 -3
  113. package/dist/{chunk-ANI5DUAE.js → chunk-UIXXE6NI.js} +7 -7
  114. package/dist/{chunk-2COL35PK.js → chunk-UO5ZHIIH.js} +2 -2
  115. package/dist/{chunk-OJU73BUX.js → chunk-VCLGUIFM.js} +2 -2
  116. package/dist/{chunk-5J4OL7TJ.js → chunk-VUA4S7P6.js} +4 -4
  117. package/dist/{chunk-A66YRSOS.js → chunk-WQYSDPMA.js} +2 -2
  118. package/dist/chunk-XGTBNVIU.js +79 -0
  119. package/dist/chunk-XGTBNVIU.js.map +1 -0
  120. package/dist/{chunk-OZ2KQ7HF.js → chunk-YEE5KJQQ.js} +2 -2
  121. package/dist/chunk-YN2UN7N3.js +217 -0
  122. package/dist/chunk-YN2UN7N3.js.map +1 -0
  123. package/dist/{chunk-WRFKZEO6.js → chunk-YQGHW5ML.js} +4 -4
  124. package/dist/{chunk-APUJIMDM.js → chunk-Z4RU5VPM.js} +2 -2
  125. package/dist/{chunk-DCWIQFNA.js → chunk-ZUDM75KG.js} +4 -4
  126. package/dist/{cli-1orcdXOY.d.ts → cli-P_GaYcCY.d.ts} +3 -3
  127. package/dist/cli.d.ts +9 -6
  128. package/dist/cli.js +67 -63
  129. package/dist/compounding/engine.d.ts +1 -1
  130. package/dist/compounding/engine.js +12 -10
  131. package/dist/compounding/preference-consolidator.d.ts +1 -1
  132. package/dist/compression-optimizer.d.ts +1 -1
  133. package/dist/config.d.ts +1 -1
  134. package/dist/config.js +4 -2
  135. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  136. package/dist/connectors/codex-materialize-runner.js +12 -10
  137. package/dist/connectors/codex-materialize.d.ts +1 -1
  138. package/dist/connectors/index.d.ts +1 -1
  139. package/dist/connectors/index.js +13 -11
  140. package/dist/consolidation-provenance-check.d.ts +1 -1
  141. package/dist/consolidation-undo.d.ts +1 -1
  142. package/dist/contradiction/index.d.ts +1 -1
  143. package/dist/conversation-index/backend.d.ts +1 -1
  144. package/dist/conversation-index/backend.js +2 -2
  145. package/dist/conversation-index/chunker.d.ts +1 -1
  146. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  147. package/dist/conversation-index/indexer.d.ts +1 -1
  148. package/dist/conversation-index/search.d.ts +1 -1
  149. package/dist/day-summary.d.ts +1 -1
  150. package/dist/delinearize.d.ts +1 -1
  151. package/dist/direct-answer-wiring.d.ts +1 -1
  152. package/dist/direct-answer.d.ts +1 -1
  153. package/dist/embedding-fallback.d.ts +1 -1
  154. package/dist/enrichment/index.d.ts +1 -1
  155. package/dist/entity-retrieval.d.ts +1 -1
  156. package/dist/entity-retrieval.js +12 -10
  157. package/dist/entity-schema.d.ts +1 -1
  158. package/dist/explicit-capture.d.ts +11 -8
  159. package/dist/extraction-faithfulness.d.ts +8 -2
  160. package/dist/extraction-faithfulness.js +4 -3
  161. package/dist/extraction-judge-telemetry.d.ts +1 -1
  162. package/dist/extraction-judge-training.d.ts +1 -1
  163. package/dist/extraction-judge.d.ts +1 -1
  164. package/dist/extraction-judge.js +3 -3
  165. package/dist/extraction.d.ts +1 -1
  166. package/dist/extraction.js +5 -4
  167. package/dist/faithfulness-config.d.ts +55 -0
  168. package/dist/faithfulness-config.js +11 -0
  169. package/dist/faithfulness-config.js.map +1 -0
  170. package/dist/fallback-llm.d.ts +1 -1
  171. package/dist/fallback-llm.js +2 -2
  172. package/dist/{forget-U66KPDPY.js → forget-OEE5OELK.js} +2 -2
  173. package/dist/graph-dashboard-diff.d.ts +4 -0
  174. package/dist/graph-dashboard-key.d.ts +4 -0
  175. package/dist/graph-dashboard-parser.d.ts +4 -0
  176. package/dist/{graph-edge-decay-JLOF3YW4.js → graph-edge-decay-QPRJQ7DL.js} +3 -3
  177. package/dist/graph-edge-reinforcement.d.ts +4 -0
  178. package/dist/graph-snapshot.d.ts +7 -3
  179. package/dist/graph-snapshot.js +3 -3
  180. package/dist/graph.d.ts +7 -1
  181. package/dist/graph.js +2 -2
  182. package/dist/identity-continuity.d.ts +1 -1
  183. package/dist/importance.d.ts +1 -1
  184. package/dist/index.d.ts +571 -570
  185. package/dist/index.js +104 -99
  186. package/dist/index.js.map +1 -1
  187. package/dist/intent.d.ts +1 -1
  188. package/dist/lcm/engine.d.ts +1 -1
  189. package/dist/lcm/engine.js +2 -2
  190. package/dist/lcm/index.d.ts +1 -1
  191. package/dist/lcm/index.js +4 -4
  192. package/dist/lcm/tools.d.ts +1 -1
  193. package/dist/lifecycle.d.ts +1 -1
  194. package/dist/live-connectors-runner.d.ts +1 -1
  195. package/dist/local-llm.d.ts +1 -1
  196. package/dist/local-model-endpoint.d.ts +96 -0
  197. package/dist/local-model-endpoint.js +12 -0
  198. package/dist/local-model-endpoint.js.map +1 -0
  199. package/dist/maintenance/memory-governance.d.ts +1 -1
  200. package/dist/maintenance/memory-governance.js +12 -10
  201. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +12 -10
  202. package/dist/maintenance/rebuild-memory-projection.js +13 -11
  203. package/dist/mcp-memory-inspector-app.d.ts +11 -8
  204. package/dist/memory-action-policy.d.ts +1 -1
  205. package/dist/memory-cache.d.ts +1 -1
  206. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  207. package/dist/memory-projection-store.d.ts +1 -1
  208. package/dist/memory-provenance.d.ts +1 -1
  209. package/dist/memory-worth-outcomes.d.ts +1 -1
  210. package/dist/models-json.d.ts +1 -1
  211. package/dist/namespaces/migrate.d.ts +2 -2
  212. package/dist/namespaces/migrate.js +22 -20
  213. package/dist/namespaces/principal.d.ts +1 -1
  214. package/dist/namespaces/search.d.ts +1 -1
  215. package/dist/namespaces/search.js +9 -9
  216. package/dist/namespaces/storage.d.ts +2 -2
  217. package/dist/namespaces/storage.js +12 -10
  218. package/dist/native-knowledge.d.ts +1 -1
  219. package/dist/operator-toolkit.d.ts +3 -2
  220. package/dist/operator-toolkit.js +32 -28
  221. package/dist/orchestration/maintenance.d.ts +2 -2
  222. package/dist/orchestration/maintenance.js +14 -12
  223. package/dist/{orchestrator-kOxredSr.d.ts → orchestrator-f5xv19kp.d.ts} +178 -81
  224. package/dist/orchestrator.d.ts +8 -5
  225. package/dist/orchestrator.js +56 -52
  226. package/dist/patterns-cli.d.ts +1 -1
  227. package/dist/policy-runtime.d.ts +1 -1
  228. package/dist/provenance.d.ts +1 -1
  229. package/dist/provenance.js +2 -1
  230. package/dist/qmd-recall-cache.d.ts +1 -1
  231. package/dist/qmd.d.ts +1 -1
  232. package/dist/recall-disclosure-escalation.d.ts +1 -1
  233. package/dist/recall-explain-renderer.d.ts +1 -1
  234. package/dist/recall-explain-renderer.js +3 -3
  235. package/dist/recall-planner-llm.d.ts +1 -1
  236. package/dist/recall-planner-llm.js +2 -2
  237. package/dist/recall-state.d.ts +1 -1
  238. package/dist/recall-tag-filter.d.ts +1 -1
  239. package/dist/recall-xray-cli.d.ts +1 -1
  240. package/dist/recall-xray-cli.js +4 -4
  241. package/dist/recall-xray-renderer.d.ts +1 -1
  242. package/dist/recall-xray-renderer.js +3 -3
  243. package/dist/recall-xray.d.ts +18 -1
  244. package/dist/recall-xray.js +2 -2
  245. package/dist/resolve-auth-token.d.ts +1 -1
  246. package/dist/resume-bundles.js +5 -3
  247. package/dist/retrieval-agents.d.ts +1 -1
  248. package/dist/retrieval-tiers.d.ts +1 -1
  249. package/dist/routing/engine.d.ts +1 -1
  250. package/dist/routing/store.d.ts +1 -1
  251. package/dist/search/embed-helper.d.ts +1 -1
  252. package/dist/search/factory.d.ts +1 -1
  253. package/dist/search/factory.js +8 -8
  254. package/dist/search/index.d.ts +1 -1
  255. package/dist/search/index.js +14 -14
  256. package/dist/search/lancedb-backend.d.ts +1 -1
  257. package/dist/search/lancedb-backend.js +2 -2
  258. package/dist/search/meilisearch-backend.d.ts +1 -1
  259. package/dist/search/meilisearch-backend.js +2 -2
  260. package/dist/search/noop-backend.d.ts +1 -1
  261. package/dist/search/orama-backend.d.ts +1 -1
  262. package/dist/search/orama-backend.js +2 -2
  263. package/dist/search/port.d.ts +1 -1
  264. package/dist/search/remote-backend.d.ts +1 -1
  265. package/dist/{semantic-consolidation-B58v3S-a.d.ts → semantic-consolidation-BQm1e1Pn.d.ts} +1 -1
  266. package/dist/semantic-consolidation.d.ts +2 -2
  267. package/dist/semantic-consolidation.js +13 -11
  268. package/dist/semantic-rule-promotion.js +12 -10
  269. package/dist/semantic-rule-verifier.d.ts +1 -1
  270. package/dist/semantic-rule-verifier.js +12 -10
  271. package/dist/session-observer-bands.d.ts +1 -1
  272. package/dist/session-observer-state.d.ts +1 -1
  273. package/dist/shared-context/manager.d.ts +1 -1
  274. package/dist/signal.d.ts +1 -1
  275. package/dist/storage.d.ts +45 -1
  276. package/dist/storage.js +11 -9
  277. package/dist/summarizer.d.ts +1 -1
  278. package/dist/summarizer.js +3 -3
  279. package/dist/summary-snapshot.d.ts +1 -1
  280. package/dist/temporal-supersession.d.ts +1 -1
  281. package/dist/temporal-validity.d.ts +1 -1
  282. package/dist/threading.d.ts +1 -1
  283. package/dist/tier-migration.d.ts +1 -1
  284. package/dist/tier-routing.d.ts +1 -1
  285. package/dist/topics.d.ts +1 -1
  286. package/dist/transcript.d.ts +1 -1
  287. package/dist/transfer/backup.js +2 -2
  288. package/dist/transfer/capsule-export.js +2 -2
  289. package/dist/transfer/capsule-import.js +1 -1
  290. package/dist/trust-score-stage.d.ts +178 -0
  291. package/dist/trust-score-stage.js +18 -0
  292. package/dist/trust-score-stage.js.map +1 -0
  293. package/dist/trust-score.d.ts +164 -0
  294. package/dist/trust-score.js +22 -0
  295. package/dist/trust-score.js.map +1 -0
  296. package/dist/{types-ACmDOScJ.d.ts → types-DwO1Ot4n.d.ts} +56 -2
  297. package/dist/types.d.ts +1 -1
  298. package/dist/types.js +1 -1
  299. package/dist/utility-runtime.d.ts +1 -1
  300. package/dist/verified-recall.js +12 -10
  301. package/package.json +2 -2
  302. package/src/access-service.ts +8 -5
  303. package/src/capabilities-cluster-b.test.ts +78 -0
  304. package/src/capabilities.test.ts +11 -1
  305. package/src/capabilities.ts +58 -0
  306. package/src/cli/research-status-commands.ts +7 -3
  307. package/src/cli.ts +11 -6
  308. package/src/config.ts +60 -30
  309. package/src/extraction-faithfulness.test.ts +175 -0
  310. package/src/extraction-faithfulness.ts +53 -1
  311. package/src/faithfulness-config.test.ts +96 -0
  312. package/src/faithfulness-config.ts +138 -0
  313. package/src/graph-snapshot.ts +3 -3
  314. package/src/graph.ts +8 -7
  315. package/src/lifecycle/tombstones.test.ts +242 -1
  316. package/src/lifecycle/tombstones.ts +157 -70
  317. package/src/local-model-endpoint.test.ts +155 -0
  318. package/src/local-model-endpoint.ts +189 -0
  319. package/src/operator-toolkit.ts +24 -7
  320. package/src/orchestration/tier-migration-coordinator.ts +286 -0
  321. package/src/orchestrator.ts +331 -222
  322. package/src/recall-xray.test.ts +62 -0
  323. package/src/recall-xray.ts +34 -0
  324. package/src/trust-score-recall-paths.test.ts +157 -0
  325. package/src/trust-score-stage.test.ts +350 -0
  326. package/src/trust-score-stage.ts +398 -0
  327. package/src/trust-score.test.ts +282 -0
  328. package/src/trust-score.ts +449 -0
  329. package/src/types.ts +61 -1
  330. package/dist/chunk-3JJWNZTT.js.map +0 -1
  331. package/dist/chunk-72VDBALG.js.map +0 -1
  332. package/dist/chunk-A5TUPZ3N.js.map +0 -1
  333. package/dist/chunk-F3PVXKHP.js.map +0 -1
  334. package/dist/chunk-FEB7W5JG.js.map +0 -1
  335. package/dist/chunk-IF362TF6.js.map +0 -1
  336. package/dist/chunk-L5ASZA2F.js.map +0 -1
  337. package/dist/chunk-N3DUH6OO.js.map +0 -1
  338. package/dist/chunk-NFRBADNR.js.map +0 -1
  339. package/dist/chunk-PBH4JUAB.js.map +0 -1
  340. package/dist/chunk-RVLB4E6N.js.map +0 -1
  341. package/dist/chunk-UCJ5CDTK.js.map +0 -1
  342. package/dist/chunk-YGKUAX2B.js.map +0 -1
  343. /package/dist/{auto-sync-24NNS3GU.js.map → auto-sync-F3KCSQFJ.js.map} +0 -0
  344. /package/dist/{chunk-TH7WMHVK.js.map → chunk-3NN73CM7.js.map} +0 -0
  345. /package/dist/{chunk-DGTDRIUO.js.map → chunk-4T3BMHKD.js.map} +0 -0
  346. /package/dist/{chunk-EH27LHML.js.map → chunk-5O42UKXI.js.map} +0 -0
  347. /package/dist/{chunk-KRGC4EDX.js.map → chunk-6FAMMBQ3.js.map} +0 -0
  348. /package/dist/{chunk-67HG7KFE.js.map → chunk-6YKIYQU7.js.map} +0 -0
  349. /package/dist/{chunk-LXSG4L55.js.map → chunk-7CTNUVHZ.js.map} +0 -0
  350. /package/dist/{chunk-7EEVXW7X.js.map → chunk-A7TJZLPK.js.map} +0 -0
  351. /package/dist/{chunk-P5IPFZVH.js.map → chunk-B7WISIAJ.js.map} +0 -0
  352. /package/dist/{chunk-JAKYZGV4.js.map → chunk-BXEOHV7K.js.map} +0 -0
  353. /package/dist/{chunk-S3OPGGZB.js.map → chunk-D7EBTQ24.js.map} +0 -0
  354. /package/dist/{chunk-IO5NQEGZ.js.map → chunk-DKT3X5C3.js.map} +0 -0
  355. /package/dist/{chunk-S35FX6MU.js.map → chunk-EBDA5TYA.js.map} +0 -0
  356. /package/dist/{chunk-2PTBLS2S.js.map → chunk-EDOQM4E4.js.map} +0 -0
  357. /package/dist/{chunk-YTZLBBEB.js.map → chunk-EEJMD2L2.js.map} +0 -0
  358. /package/dist/{chunk-JIZGYQYH.js.map → chunk-EM2LDXJ2.js.map} +0 -0
  359. /package/dist/{chunk-YYOK4GVF.js.map → chunk-EVPNWN7Z.js.map} +0 -0
  360. /package/dist/{chunk-HLIR3RJ7.js.map → chunk-EXUCUPV2.js.map} +0 -0
  361. /package/dist/{chunk-2SXMCQEQ.js.map → chunk-GZQXOQQ2.js.map} +0 -0
  362. /package/dist/{chunk-2KAYTPPT.js.map → chunk-HCVWF657.js.map} +0 -0
  363. /package/dist/{chunk-4KZGLDJJ.js.map → chunk-J3JPB7ZI.js.map} +0 -0
  364. /package/dist/{chunk-LQ6JI4VH.js.map → chunk-LD53WPMU.js.map} +0 -0
  365. /package/dist/{chunk-URM3HW2R.js.map → chunk-LLUGAZ3B.js.map} +0 -0
  366. /package/dist/{chunk-U5H7WHTS.js.map → chunk-N77ELJ2D.js.map} +0 -0
  367. /package/dist/{chunk-2VHMVWPU.js.map → chunk-NXRUUDUF.js.map} +0 -0
  368. /package/dist/{chunk-DIFU33GU.js.map → chunk-OHTOPFRF.js.map} +0 -0
  369. /package/dist/{chunk-74MYJSKB.js.map → chunk-ORAK3LNZ.js.map} +0 -0
  370. /package/dist/{chunk-REWQAFSA.js.map → chunk-PD42EYQN.js.map} +0 -0
  371. /package/dist/{chunk-773DPI6T.js.map → chunk-PKMQK2WY.js.map} +0 -0
  372. /package/dist/{chunk-CTOQEZSN.js.map → chunk-QR67FU5G.js.map} +0 -0
  373. /package/dist/{chunk-AU7Q3LSC.js.map → chunk-RKNJBZ55.js.map} +0 -0
  374. /package/dist/{chunk-YI7RZO7Y.js.map → chunk-SQNED75R.js.map} +0 -0
  375. /package/dist/{chunk-5CEJH5ZN.js.map → chunk-TAPSNIMA.js.map} +0 -0
  376. /package/dist/{chunk-5RHM43BJ.js.map → chunk-TXQCG6SE.js.map} +0 -0
  377. /package/dist/{chunk-ANI5DUAE.js.map → chunk-UIXXE6NI.js.map} +0 -0
  378. /package/dist/{chunk-2COL35PK.js.map → chunk-UO5ZHIIH.js.map} +0 -0
  379. /package/dist/{chunk-OJU73BUX.js.map → chunk-VCLGUIFM.js.map} +0 -0
  380. /package/dist/{chunk-5J4OL7TJ.js.map → chunk-VUA4S7P6.js.map} +0 -0
  381. /package/dist/{chunk-A66YRSOS.js.map → chunk-WQYSDPMA.js.map} +0 -0
  382. /package/dist/{chunk-OZ2KQ7HF.js.map → chunk-YEE5KJQQ.js.map} +0 -0
  383. /package/dist/{chunk-WRFKZEO6.js.map → chunk-YQGHW5ML.js.map} +0 -0
  384. /package/dist/{chunk-APUJIMDM.js.map → chunk-Z4RU5VPM.js.map} +0 -0
  385. /package/dist/{chunk-DCWIQFNA.js.map → chunk-ZUDM75KG.js.map} +0 -0
  386. /package/dist/{forget-U66KPDPY.js.map → forget-OEE5OELK.js.map} +0 -0
  387. /package/dist/{graph-edge-decay-JLOF3YW4.js.map → graph-edge-decay-QPRJQ7DL.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { PluginEntryResolverOptions, resolvePluginEntry } from './plugin-entry-resolver.js';
2
2
  export { isOpenaiApiKeyDisabled, parseConfig, resolveEnvVars } from './config.js';
3
3
  export { MigrationOptions, MigrationResult, RollbackResult, migrateFromEngram, rollbackFromEngramMigration } from './migrate/from-engram.js';
4
- import { S as SpeakerRegistry, W as WearablesService } from './orchestrator-kOxredSr.js';
5
- export { D as DEFAULT_SELF_NAME, O as Orchestrator, R as ResolvedSpeaker, a as SpeakerOverride, b as WEARABLE_SOURCE_PREFIX, c as WearableDayTranscriptView, d as WearableMemoryGenDeps, e as WearableMemoryGenResult, f as WearableMemorySearchResult, g as WearableMemoryWriter, h as WearableSearchBackend, i as WearableStorageIo, j as WearableSyncDeps, k as WearableSyncOptions, l as WearableTranscriptSearchResult, m as WearablesServiceDeps, n as buildExtractionTurns, o as dateInTimezone, p as defaultTimezone, q as defaultWorkspaceDir, r as distinctSpeakerLabels, s as emptySpeakerRegistry, t as generateWearableMemories, u as importNativeMemories, v as loadSpeakerRegistry, w as locateTranscriptPath, x as memoryStatusForMode, y as resolveSpeaker, z as resolveSyncDates, A as sanitizeSessionKeyForFilename, B as saveSpeakerRegistry, C as speakerRegistryKey, E as speakersFilePath, F as syncWearableSource, H as wearableDayTag, J as wearableSourceLabel, K as writeDailyDigestMemory } from './orchestrator-kOxredSr.js';
4
+ import { S as SpeakerRegistry, W as WearablesService } from './orchestrator-f5xv19kp.js';
5
+ export { D as DEFAULT_SELF_NAME, O as Orchestrator, R as ResolvedSpeaker, a as SpeakerOverride, b as WEARABLE_SOURCE_PREFIX, c as WearableDayTranscriptView, d as WearableMemoryGenDeps, e as WearableMemoryGenResult, f as WearableMemorySearchResult, g as WearableMemoryWriter, h as WearableSearchBackend, i as WearableStorageIo, j as WearableSyncDeps, k as WearableSyncOptions, l as WearableTranscriptSearchResult, m as WearablesServiceDeps, n as buildExtractionTurns, o as dateInTimezone, p as defaultTimezone, q as defaultWorkspaceDir, r as distinctSpeakerLabels, s as emptySpeakerRegistry, t as generateWearableMemories, u as importNativeMemories, v as loadSpeakerRegistry, w as locateTranscriptPath, x as memoryStatusForMode, y as resolveSpeaker, z as resolveSyncDates, A as sanitizeSessionKeyForFilename, B as saveSpeakerRegistry, C as speakerRegistryKey, E as speakersFilePath, F as syncWearableSource, H as wearableDayTag, J as wearableSourceLabel, K as writeDailyDigestMemory } from './orchestrator-f5xv19kp.js';
6
6
  export { normalizeProjectionPreview, normalizeProjectionTags } from './memory-projection-format.js';
7
7
  export { ModelCapabilities, ModelRegistry } from './model-registry.js';
8
8
  export { ACTIVE_STATUSES, ContradictionFilter, ContradictionJudgeBatchResult, ContradictionJudgeInput, ContradictionJudgeResult, ContradictionListResult, ContradictionVerdict, ResolutionResult, ResolutionVerb, ScanDependencies, ScanResult, computePairId, executeResolution, isCoolingDown, isValidResolutionVerb, judgeContradictionPairs, listPairs, readPair, resolvePair, runContradictionScan, writePair, writePairs } from './contradiction/index.js';
@@ -20,11 +20,11 @@ export { CodexCliFallbackConfig, CodexCliFallbackMessage, CodexCliFallbackOption
20
20
  export { BufferSurpriseProbe, SmartBuffer, TriggerDecision } from './buffer.js';
21
21
  export { ComputeSurpriseOptions, DEFAULT_SURPRISE_K, RecentMemoryLike, computeSurprise } from './buffer-surprise.js';
22
22
  export { BufferSurpriseDistribution, BufferSurpriseReader, BufferSurpriseReportOptions, reportBufferSurpriseDistribution } from './buffer-surprise-report.js';
23
- import { aG as CodingContext, aR as CodingModeConfig, P as PluginConfig, M as MemoryCategory, aS as WearableCleanupSettings, ax as WearableSourceSettings, aB as WearablesConfig, aA as WearableSourceConnector, aw as WearableConversation, aF as WearableCorrectionRule, aT as WearableDayTranscriptMeta, aE as WearableDayTranscript } from './types-ACmDOScJ.js';
24
- export { J as AgentAccessAuthToken, r as BriefingActiveThread, aU as BriefingConfig, p as BriefingFocus, o as BriefingFollowup, aV as BriefingOpenCommitment, t as BriefingRecentEntity, s as BriefingResult, n as BriefingSections, aW as BriefingWindow, z as BufferSurpriseEvent, q as CalendarEvent, C as CalendarSource, aX as CodexCompatConfig, aJ as ConsolidationObservation, a6 as ContinuityImprovementLoop, aY as DEFAULT_RECALL_DISCLOSURE, E as EntityFile, $ as EntityStructuredSection, aZ as ExtractedFact, G as GatewayConfig, ac as MemoryActionEligibilityContext, a_ as MemoryActionEligibilitySource, U as MemoryActionType, g as MemoryFile, k as MemoryFrontmatter, a$ as MemoryObservation, b0 as MemoryScope, b1 as RECALL_DISCLOSURE_LEVELS, i as RecallDisclosure, D as SecretRef, b2 as WearableAuthCheck, b3 as WearableFetchOptions, b4 as WearableFetchPage, az as WearableMemoryMode, ay as WearableNativeMemory, b5 as WearableNativeMemoryPage, aD as WearableSourceStatus, aC as WearableSyncSummary, b6 as WearableTranscriptSegment, b7 as isRecallDisclosure } from './types-ACmDOScJ.js';
23
+ import { aH as CodingContext, aS as CodingModeConfig, P as PluginConfig, M as MemoryCategory, aT as WearableCleanupSettings, ay as WearableSourceSettings, aC as WearablesConfig, aB as WearableSourceConnector, ax as WearableConversation, aG as WearableCorrectionRule, aU as WearableDayTranscriptMeta, aF as WearableDayTranscript } from './types-DwO1Ot4n.js';
24
+ export { J as AgentAccessAuthToken, r as BriefingActiveThread, aV as BriefingConfig, p as BriefingFocus, o as BriefingFollowup, aW as BriefingOpenCommitment, t as BriefingRecentEntity, s as BriefingResult, n as BriefingSections, aX as BriefingWindow, z as BufferSurpriseEvent, q as CalendarEvent, C as CalendarSource, aY as CodexCompatConfig, aK as ConsolidationObservation, a6 as ContinuityImprovementLoop, aZ as DEFAULT_RECALL_DISCLOSURE, E as EntityFile, $ as EntityStructuredSection, a_ as ExtractedFact, G as GatewayConfig, ac as MemoryActionEligibilityContext, a$ as MemoryActionEligibilitySource, U as MemoryActionType, g as MemoryFile, k as MemoryFrontmatter, b0 as MemoryObservation, b1 as MemoryScope, b2 as RECALL_DISCLOSURE_LEVELS, i as RecallDisclosure, D as SecretRef, b3 as WearableAuthCheck, b4 as WearableFetchOptions, b5 as WearableFetchPage, aA as WearableMemoryMode, az as WearableNativeMemory, b6 as WearableNativeMemoryPage, aE as WearableSourceStatus, aD as WearableSyncSummary, b7 as WearableTranscriptSegment, b8 as isRecallDisclosure } from './types-DwO1Ot4n.js';
25
25
  export { JudgeBatchResult, JudgeCandidate, JudgeVerdict, JudgeVerdictKind, clearVerdictCache, createVerdictCache, getVerdictKind, isDurableVerdict, isValidCachedVerdict, judgeFactDurability, normalizeCachedVerdict, verdictCacheSize } from './extraction-judge.js';
26
26
  export { hasBroadGraphIntent, inferIntentFromText, intentCompatibilityScore, isTaskInitiationIntent, planRecallMode } from './intent.js';
27
- export { i as EngramAccessInputError, g as EngramAccessService, P as ProcedureStatsConfigSnapshot, j as ProcedureStatsRecent, k as ProcedureStatsReport, l as ProcedureStatusCounts, m as computeProcedureStats, n as formatProcedureStatsText } from './access-service-CZbnt0t2.js';
27
+ export { i as EngramAccessInputError, g as EngramAccessService, P as ProcedureStatsConfigSnapshot, j as ProcedureStatsRecent, k as ProcedureStatsReport, l as ProcedureStatusCounts, m as computeProcedureStats, n as formatProcedureStatsText } from './access-service-Dj3I-VBS.js';
28
28
  export { FILTER_LABELS as DIRECT_ANSWER_FILTER_LABELS, DirectAnswerCandidate, DirectAnswerConfig, DirectAnswerInput, DirectAnswerReason, DirectAnswerResult, isDirectAnswerEligible } from './direct-answer.js';
29
29
  export { MemoryTier, TierRoutingPolicy, TierTransitionDecision, computeTierValueScore, decideTierTransition } from './tier-routing.js';
30
30
  export { ApplyReasoningTraceBoostOptions, BoostableResult, DEFAULT_REASONING_TRACE_BOOST, applyReasoningTraceBoost, isReasoningTracePath, looksLikeProblemSolvingQuery } from './reasoning-trace-recall.js';
@@ -38,7 +38,7 @@ export { OramaBackend } from './search/orama-backend.js';
38
38
  export { MeilisearchBackend } from './search/meilisearch-backend.js';
39
39
  export { buildEntityRecallSection } from './entity-retrieval.js';
40
40
  export { resolvePrincipal } from './namespaces/principal.js';
41
- export { N as NamespaceCatalog, c as NamespaceCatalogFilter, d as NamespaceCatalogRebuildResult, e as NamespaceCatalogSkippedRoot, f as NamespaceDiscoverySource, a as NamespaceKind, b as NamespaceRecord, g as NamespaceTouchMetadata } from './catalog-CEYlMs9X.js';
41
+ export { N as NamespaceCatalog, c as NamespaceCatalogFilter, d as NamespaceCatalogRebuildResult, e as NamespaceCatalogSkippedRoot, f as NamespaceDiscoverySource, a as NamespaceKind, b as NamespaceRecord, g as NamespaceTouchMetadata } from './catalog-F-OEVbRQ.js';
42
42
  export { SESSION_CHANNEL_TYPE, SessionIdentity, SessionStoragePaths, legacyParserReadbackDir, parseSessionIdentity, sessionStoragePaths } from './session-identity.js';
43
43
  export { storagePathHash } from './storage-paths.js';
44
44
  export { TrustZoneName, TrustZoneRecord, TrustZoneRecordKind, TrustZoneSourceClass, isTrustZoneName } from './trust-zones.js';
@@ -62,8 +62,8 @@ export { CitationBlock, CitationEntry, CitationMetadata, buildCitationGuidance,
62
62
  export { initLogger, log } from './logger.js';
63
63
  export { b as SemanticDedupDecision, S as SemanticDedupHit, a as SemanticDedupLookup, c as SemanticDedupOptions, d as decideSemanticDedup } from './semantic-SLAa_prH.js';
64
64
  export { OFFLINE_SYNC_APPLY_MAX_BODY_BYTES, OFFLINE_SYNC_CHANGESET_FORMAT, OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES, OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES, OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES, OFFLINE_SYNC_SNAPSHOT_FORMAT, OFFLINE_SYNC_STATE_VERSION, OfflineSyncApplyChangesetResult, OfflineSyncApplyFileContentChunkResult, OfflineSyncApplySnapshotResult, OfflineSyncChange, OfflineSyncChangeset, OfflineSyncConflict, OfflineSyncFileContentChunk, OfflineSyncFileDigest, OfflineSyncFileRecord, OfflineSyncFileState, OfflineSyncFileTarget, OfflineSyncFileWriteTarget, OfflineSyncSnapshot, OfflineSyncState, applyOfflineSyncChangeset, applyOfflineSyncFileContentChunk, applyOfflineSyncSnapshot, buildOfflineSyncChangeset, buildOfflineSyncChangesetFromSnapshot, buildOfflineSyncSnapshot, buildOfflineSyncSnapshotForPaths, buildOfflineSyncSnapshotFromBase, defaultOfflineSyncStatePath, fileStatesFromSnapshot, iterateOfflineSyncSnapshotFileRecords, normalizeOfflineSyncChangeset, normalizeOfflineSyncSnapshot, offlineSyncStateFromSnapshot, readOfflineSyncFileContentChunk, readOfflineSyncState, shouldPreferIncomingOfflineRuntimeFile, summarizeOfflineSyncChangeset, summarizeOfflineSyncPendingChanges, summarizeOfflineSyncPendingFiles, writeOfflineSyncState } from './offline-sync.js';
65
- import { D as DiscoveredExtension } from './semantic-consolidation-B58v3S-a.js';
66
- export { E as ExtensionSchema, R as REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT, b as buildExtensionsBlockForConsolidation, d as discoverMemoryExtensions, r as resolveExtensionsRoot } from './semantic-consolidation-B58v3S-a.js';
65
+ import { D as DiscoveredExtension } from './semantic-consolidation-BQm1e1Pn.js';
66
+ export { E as ExtensionSchema, R as REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT, b as buildExtensionsBlockForConsolidation, d as discoverMemoryExtensions, r as resolveExtensionsRoot } from './semantic-consolidation-BQm1e1Pn.js';
67
67
  export { ConnectorCapability, ConnectorInstance, ConnectorManifest, ConnectorRegistry, DoctorCheck, DoctorResult, InstallOptions, InstallResult, MARKETPLACE_MANIFEST_FILENAME, MARKETPLACE_SCHEMA_VERSION, MarketplaceConfig, MarketplaceEntry, MarketplaceInstallResult, MarketplaceInstallType, MarketplaceLogger, MarketplaceManifest, MarketplaceValidation, RemoveResult, checkMarketplaceManifest, coerceInstallExtension, doctorConnector, generateMarketplaceManifest, getConnectorToken, installConnector, installFromMarketplace, listConnectors, loadRegistry, removeConnector, saveRegistry, validateMarketplaceManifest, writeMarketplaceManifest } from './connectors/index.js';
68
68
  import { L as LiveConnector, S as SyncIncrementalResult } from './framework-CNDn2164.js';
69
69
  export { c as CONNECTOR_ID_PATTERN, C as ConnectorConfig, b as ConnectorCursor, a as ConnectorDocument, d as ConnectorDocumentSource, e as SyncIncrementalArgs, i as isValidConnectorId, p as persistableConnectorConfig, r as redactConnectorConfigSecrets } from './framework-CNDn2164.js';
@@ -79,7 +79,7 @@ export { EnrichmentAuditEntry, EnrichmentCandidate, EnrichmentCostTier, Enrichme
79
79
  export { d as BulkImportError, B as BulkImportOptions, b as BulkImportResult, a as BulkImportSource, e as BulkImportSourceAdapter, f as ImportSourceRole, I as ImportTurn, g as ImportTurnValidationIssue, i as isImportRole, p as parseIsoTimestamp, v as validateImportTurn } from './types-gb_SNtjR.js';
80
80
  export { clearBulkImportSources, getBulkImportSource, listBulkImportSources, registerBulkImportSource } from './bulk-import/index.js';
81
81
  export { a as ProcessBatchContext, P as ProcessBatchFn, b as ProcessBatchResult, f as formatBatchTranscript, r as resolveBulkImportContext, c as runBulkImportPipeline, v as validateBatchSize } from './pipeline-DmqtvION.js';
82
- export { B as BulkImportCliCommandOptions, p as parseStrictCliDate, r as runBulkImportCliCommand } from './cli-1orcdXOY.js';
82
+ export { B as BulkImportCliCommandOptions, p as parseStrictCliDate, r as runBulkImportCliCommand } from './cli-P_GaYcCY.js';
83
83
  export { DEFAULT_IMPORT_BATCH_SIZE, ImportProgress, ImportedMemory, ImporterAdapter, ImporterParseOptions, ImporterTransformOptions, ImporterWriteResult, ImporterWriteTarget, RunImportOptions, RunImporterResult, defaultWriteMemoriesToOrchestrator, importedMemoryToTurn, runImporter, validateImportBatchSize, validateImportRateLimit } from './importers/index.js';
84
84
  export { FallbackLlmClient, FallbackLlmOptions, FallbackLlmResponse, FallbackLlmRuntimeContext } from './fallback-llm.js';
85
85
  export { ComputeMemoryWorthInput, MemoryWorthResult, computeMemoryWorth } from './memory-worth.js';
@@ -105,16 +105,26 @@ import './session-integrity.js';
105
105
  import './summarizer.js';
106
106
  import './orchestration/maintenance.js';
107
107
  import './namespaces/search.js';
108
+ import './recall-state.js';
109
+ import './compounding/engine.js';
110
+ import './shared-context/manager.js';
111
+ import 'zod';
112
+ import './consolidation-operator.js';
113
+ import './memory-projection-store.js';
114
+ import './maintenance/memory-governance.js';
115
+ import './runtime/better-sqlite.js';
116
+ import 'better-sqlite3';
117
+ import './structured-attributes.js';
118
+ import './utility-runtime.js';
119
+ import './lifecycle.js';
108
120
  import './relevance.js';
109
121
  import './negative.js';
110
- import './recall-state.js';
111
122
  import './session-observer-state.js';
112
123
  import './embedding-fallback.js';
113
124
  import './capabilities.js';
114
125
  import './replay/types.js';
115
126
  import './lcm/engine.js';
116
127
  import './lcm/archive.js';
117
- import 'better-sqlite3';
118
128
  import './lcm/summarizer.js';
119
129
  import './lcm/dag.js';
120
130
  import './lcm/queue.js';
@@ -122,14 +132,6 @@ import './conversation-index/backend.js';
122
132
  import './conversation-index/chunker.js';
123
133
  import './faiss-adapter-BHecI1fF.js';
124
134
  import './runtime/child-process.js';
125
- import './shared-context/manager.js';
126
- import 'zod';
127
- import './compounding/engine.js';
128
- import './consolidation-operator.js';
129
- import './memory-projection-store.js';
130
- import './maintenance/memory-governance.js';
131
- import './runtime/better-sqlite.js';
132
- import './structured-attributes.js';
133
135
  import './policy-runtime.js';
134
136
  import './profiling.js';
135
137
  import './schemas.js';
@@ -139,7 +141,6 @@ import './graph-snapshot.js';
139
141
  import './graph.js';
140
142
  import './transfer/capsule-export.js';
141
143
  import './capsule-cli.js';
142
- import './lifecycle.js';
143
144
  import './search/embed-helper.js';
144
145
  import 'node:http';
145
146
  import './adapters/types.js';
@@ -287,608 +288,248 @@ interface CodingScopeDescription {
287
288
  declare function describeCodingScope(codingContext: CodingContext | null | undefined, config: Pick<CodingModeConfig, "projectScope" | "branchScope" | "globalFallback">, defaultNamespace?: string): CodingScopeDescription;
288
289
 
289
290
  /**
290
- * @remnic/core Live Connectors Registry (issue #683 PR 1/N)
291
- *
292
- * Pure in-memory registry. No I/O. Concrete connectors register themselves at
293
- * orchestrator boot (later PRs); the maintenance scheduler asks the registry
294
- * for the active set when running due syncs.
291
+ * Strict UTC-only parser accepts `YYYY-MM-DDTHH:MM:SS[.sss]Z`.
292
+ * Returns milliseconds since epoch, or `null` if invalid.
293
+ */
294
+ declare function parseIsoUtcTimestamp(value: string): number | null;
295
+ /**
296
+ * Lenient parser — accepts variable-precision fractional seconds and either
297
+ * a `Z` suffix or a `[+-]HH:MM` offset. Returns milliseconds since epoch, or
298
+ * `null` if the string is not a well-formed RFC 3339 timestamp.
299
+ */
300
+ declare function parseIsoOffsetTimestamp(value: string): number | null;
301
+ /**
302
+ * Benchmark/adapter parser — accepts ISO date-only values plus reduced
303
+ * precision date-times used by public benchmark fixtures. Returns milliseconds
304
+ * since epoch, or `null` if invalid.
295
305
  */
306
+ declare function parseFlexibleIsoTimestamp(value: string): number | null;
296
307
 
297
308
  /**
298
- * Thrown when registering a duplicate id or an id that fails validation.
299
- *
300
- * Distinct error class so callers can distinguish framework-level mistakes
301
- * (which are programmer errors) from connector-runtime failures.
309
+ * Intent-gated recall for active procedure memories (issue #519).
302
310
  */
303
- declare class LiveConnectorRegistryError extends Error {
304
- constructor(message: string);
311
+
312
+ /**
313
+ * Build markdown for the recall pipeline when procedural memory is enabled and
314
+ * the prompt looks like task initiation.
315
+ */
316
+ declare function buildProcedureRecallSection(storage: StorageManager, prompt: string, config: PluginConfig): Promise<string | null>;
317
+
318
+ /**
319
+ * Procedural memory types (issue #519).
320
+ * Bodies use ordered "## Step N" sections; machine fields live in frontmatter / structuredAttributes.
321
+ */
322
+ interface ProcedureStep {
323
+ order: number;
324
+ intent: string;
325
+ toolCall?: {
326
+ kind: string;
327
+ signature: string;
328
+ };
329
+ expectedOutcome?: string;
330
+ optional?: boolean;
305
331
  }
332
+ /** Serialize steps into markdown body (human-editable). */
333
+ declare function buildProcedureMarkdownBody(steps: ProcedureStep[]): string;
306
334
  /**
307
- * In-memory registry of live connectors. One instance per orchestrator. Not
308
- * safe for cross-process sharing wire each process to its own registry.
335
+ * Best-effort parse of "## Step N" blocks into ProcedureStep records.
336
+ * Returns null when no step headers are found.
309
337
  */
310
- declare class LiveConnectorRegistry {
311
- private readonly connectors;
338
+ declare function parseProcedureStepsFromBody(content: string): ProcedureStep[] | null;
339
+
340
+ interface GitContext {
312
341
  /**
313
- * Register a connector. Throws `LiveConnectorRegistryError` if the id is
314
- * malformed or already registered.
342
+ * Stable identifier for the project. Derived from `git remote get-url origin`
343
+ * when an origin remote is configured, otherwise from the repo root path.
315
344
  *
316
- * Re-registration is rejected (rather than silently overwriting) because
317
- * silent overwrites mask plugin loading bugs in development and could let
318
- * a malicious extension shadow a built-in connector.
345
+ * Formatted as `origin:<hex>` or `root:<hex>` so that the source is visible
346
+ * to operators (see `remnic doctor`, issue #569 acceptance criteria).
319
347
  */
320
- register(connector: LiveConnector): void;
348
+ projectId: string;
321
349
  /**
322
- * Look up a connector by id. Returns `undefined` if not registered.
350
+ * Current branch, e.g. `main`, `feat/foo`. `null` only in detached-HEAD
351
+ * state (e.g. rebase in progress). Callers should treat `null` as "no
352
+ * branch-scope overlay applies" without erroring.
323
353
  */
324
- get(id: string): LiveConnector | undefined;
354
+ branch: string | null;
325
355
  /**
326
- * Return all registered connectors, sorted by id for stable enumeration.
356
+ * Absolute path to the repository root (the directory containing `.git`).
357
+ * Tilde-expanded per CLAUDE.md #17.
327
358
  */
328
- list(): LiveConnector[];
359
+ rootPath: string;
329
360
  /**
330
- * Remove a connector. Returns `true` if a connector was removed, `false`
331
- * otherwise. The cursor / state file on disk is **not** touched — callers
332
- * who want to fully decommission a connector must also delete its state
333
- * file via the `state-store` module.
361
+ * Best-effort default branch (usually `main` or `master`). Derived from the
362
+ * `refs/remotes/origin/HEAD` symbolic ref. `null` when not available (e.g.
363
+ * fresh clone without a default branch symref, or no origin remote).
334
364
  */
335
- unregister(id: string): boolean;
365
+ defaultBranch: string | null;
366
+ }
367
+ /**
368
+ * Injectable git-invocation surface. Only the commands `resolveGitContext`
369
+ * actually needs are exposed. Tests inject a mock implementation to avoid
370
+ * spawning a real git process.
371
+ */
372
+ interface GitInvoker {
336
373
  /**
337
- * Number of registered connectors. Cheap; safe to call frequently.
374
+ * Run `git <args>` with `cwd` as the working directory. Must return
375
+ * `{ stdout, exitCode }` with `stdout` trimmed by the caller as needed.
376
+ * Implementations should NOT throw for non-zero exit codes — they should
377
+ * return the exit code so the resolver can decide how to recover.
338
378
  */
339
- size(): number;
379
+ (cwd: string, args: string[]): {
380
+ stdout: string;
381
+ exitCode: number;
382
+ };
340
383
  }
341
-
342
384
  /**
343
- * @remnic/core Google Drive live connector (issue #683 PR 2/N)
344
- *
345
- * Concrete `LiveConnector` implementation that incrementally imports text
346
- * content from a user's Google Drive into Remnic. Built on top of the
347
- * framework shipped in PR 1/N (`framework.ts` / `registry.ts` /
348
- * `state-store.ts`).
349
- *
350
- * Design notes:
351
- *
352
- * - **Cursor semantics.** We page Drive with the official `changes` API
353
- * when a `startPageToken` is available. The cursor is opaque from the
354
- * framework's POV (`{kind: "drivePageToken", value: ...}`), and on the
355
- * very first sync (cursor=null) we call `changes.getStartPageToken()`
356
- * to seed it without importing anything. This matches the documented
357
- * Drive incremental-sync recipe and means re-runs never re-ingest the
358
- * same file as long as the cursor file survives.
359
- *
360
- * - **Folder scope.** When `folderIds` is non-empty, files are filtered
361
- * to those whose `parents` intersect the configured folder set. Drive
362
- * does not currently support server-side parent filtering on the
363
- * `changes.list` endpoint, so we pull the change record's `file` payload
364
- * and apply the filter on our side. Folder ids are validated up front so
365
- * a typo in config doesn't silently cause a broad import.
366
- *
367
- * - **Content extraction.** Google-native MIME types
368
- * (`application/vnd.google-apps.{document,spreadsheet,presentation}`)
369
- * are exported via `files.export` to plaintext. Plain-text MIME types
370
- * are pulled with `files.get?alt=media`. Everything else is skipped —
371
- * bytes from binary formats (images, PDFs, archives) belong in the
372
- * binary-lifecycle pipeline, not in the textual ingestion path.
373
- *
374
- * - **Idempotency.** Each emitted `ConnectorDocument.source` carries
375
- * `externalId = file.id` plus `externalRevision = file.modifiedTime`,
376
- * so downstream dedup (CLAUDE.md gotcha #44 — never index content that
377
- * failed to persist) can recognise repeat fetches even if the cursor is
378
- * manually rewound.
379
- *
380
- * - **Privacy.** No document content is ever logged. Folder ids and
381
- * counts may be logged. OAuth credentials (`clientId`,
382
- * `clientSecret`, `refreshToken`) are accepted via config but the
383
- * intent is for callers to populate them from a secret store; we never
384
- * persist credentials through the connector state-store. Per CLAUDE.md
385
- * repository-privacy rules, no real credentials may appear in tests,
386
- * fixtures, or comments.
387
- *
388
- * - **À-la-carte packaging (CLAUDE.md gotcha #57).** `googleapis` is NOT
389
- * listed as a hard dependency of `@remnic/core`. It is loaded via a
390
- * computed-specifier dynamic import (`await import("google" + "apis")`)
391
- * so bundlers cannot statically resolve it, and it is declared as an
392
- * optional peer dependency. Operators who never enable the connector
393
- * pay nothing for it.
385
+ * Non-cryptographic stable hash. Used only to derive a deterministic
386
+ * `projectId` from either the origin URL or the root path. The hash does not
387
+ * need to be collision-resistant against adversarial input — it is purely a
388
+ * namespace discriminator.
394
389
  *
395
- * - **Read-only.** This connector only reads. It never marks files as
396
- * read, edits metadata, or modifies sharing settings.
390
+ * Uses FNV-1a 32-bit so we don't pull in `node:crypto` for a simple bucket
391
+ * key. Output is lowercase hex, zero-padded to 8 characters.
397
392
  */
398
-
393
+ declare function stableHash(input: string): string;
399
394
  /**
400
- * Stable connector id. Lives in the registry under this exact string.
395
+ * Normalize a git remote URL so that equivalent SSH / HTTPS forms of the
396
+ * same repo produce the same `projectId`. Handles:
397
+ * - `git@github.com:foo/bar.git` → `github.com/foo/bar`
398
+ * - `https://github.com/foo/bar` → `github.com/foo/bar`
399
+ * - `https://github.com/foo/bar.git` → `github.com/foo/bar`
400
+ * - `ssh://git@github.com/foo/bar` → `github.com/foo/bar`
401
+ * - `ssh://git@github.com:2222/foo/bar` → `github.com/foo/bar` (port stripped)
402
+ *
403
+ * Case-insensitive (remote hostnames and most repo paths on major forges are
404
+ * case-insensitive in practice).
401
405
  */
402
- declare const GOOGLE_DRIVE_CONNECTOR_ID = "google-drive";
406
+ declare function normalizeOriginUrl(rawUrl: string): string;
407
+ interface ResolveGitContextOptions {
408
+ /** Inject a git invoker (tests). Defaults to spawning real `git`. */
409
+ invoker?: GitInvoker;
410
+ }
403
411
  /**
404
- * Cursor `kind` we emit. Treated as opaque by the framework; documented
405
- * here so tests can assert on it.
412
+ * Detect the git project + branch for `cwd`.
413
+ *
414
+ * Returns `null` when:
415
+ * - `cwd` is not an absolute path (invalid input, CLAUDE.md #51)
416
+ * - `cwd` is not inside a git worktree
417
+ * - `git` is not available on PATH
418
+ *
419
+ * Never throws.
406
420
  */
407
- declare const GOOGLE_DRIVE_CURSOR_KIND = "drivePageToken";
421
+ declare function resolveGitContext(cwd: string, options?: ResolveGitContextOptions): Promise<GitContext | null>;
422
+
408
423
  /**
409
- * Default poll interval (5 minutes). Surfaced in `openclaw.plugin.json`
410
- * defaults and in the documented config schema. Drive's `changes.list`
411
- * endpoint is cheap, but polling sub-minute is wasteful for a personal
412
- * memory layer.
424
+ * Diff-aware review-context packer (issue #569 PR 4).
425
+ *
426
+ * When an agent is asked "review this PR" / "what changed in this diff" /
427
+ * "look at this diff", the prompt that reaches recall is short and generic
428
+ * — the real signal is the diff itself. This module:
429
+ *
430
+ * 1. Detects review-intent prompts via `isReviewPrompt`.
431
+ * 2. Extracts the touched file list from a unified diff via
432
+ * `parseTouchedFiles`.
433
+ * 3. Re-ranks a set of candidate memories so that memories whose
434
+ * `entityRefs` mention a touched path float to the top. The boost is
435
+ * additive and bounded so it doesn't obliterate the original ranking —
436
+ * it's a bias, not a filter.
437
+ *
438
+ * Pure — no orchestrator, no storage. Callers inject the candidate memories
439
+ * they already have from their normal recall pipeline. This keeps the
440
+ * module easy to test and integrates cleanly with the existing tiered-recall
441
+ * code in `orchestrator.ts` (the tier itself can be wired later; the pure
442
+ * surface is what PRs 5/6/7 will call).
413
443
  */
414
- declare const DEFAULT_POLL_INTERVAL_MS: number;
415
444
  /**
416
- * Validated, frozen view of `connectors.googleDrive.*`.
445
+ * A memory candidate as fed into review-context ranking. The shape is a
446
+ * deliberate subset of the core `MemorySummary` / recall result — only the
447
+ * fields we actually need — so this module stays decoupled from the rest of
448
+ * the codebase and can be reused by CLI tools, bench fixtures, etc.
417
449
  */
418
- interface GoogleDriveConnectorConfig {
419
- readonly clientId: string;
420
- readonly clientSecret: string;
421
- readonly refreshToken: string;
422
- /** Poll interval surfaced to the scheduler. */
423
- readonly pollIntervalMs: number;
424
- /** Folder ids to scope import to. Empty = "all accessible". */
425
- readonly folderIds: readonly string[];
426
- }
427
- /**
428
- * Optional injection point for tests. The real connector dynamically imports
429
- * `googleapis`; tests pass a stub here to avoid the optional-peer-dep
430
- * machinery and to keep the test suite hermetic.
431
- *
432
- * The shape only covers the tiny slice of the SDK we actually use.
433
- */
434
- interface GoogleDriveClientFactory {
435
- (config: GoogleDriveConnectorConfig): Promise<GoogleDriveClient>;
436
- }
437
- /**
438
- * Minimal Drive client surface. Tests provide a fake; production wraps
439
- * `googleapis` to fit. Method shapes mirror the upstream API where it
440
- * matters (`startPageToken` / `nextPageToken` / `newStartPageToken`,
441
- * `files.modifiedTime` ISO 8601 strings).
442
- */
443
- interface GoogleDriveClient {
444
- /** Mirrors `drive.changes.getStartPageToken()`. */
445
- getStartPageToken(): Promise<{
446
- startPageToken: string;
447
- }>;
450
+ interface ReviewCandidate {
451
+ /** Opaque identifier. Echoed unchanged in the output. */
452
+ id: string;
448
453
  /**
449
- * Mirrors `drive.changes.list(...)`. We page until the response yields a
450
- * `newStartPageToken` (i.e., no more pages). Each `change.file`, when
451
- * present, includes the metadata we need to decide whether to ingest.
454
+ * Pre-review relevance score from the upstream recall pipeline. Higher is
455
+ * better. `0` is treated as "no prior signal" and gets the full review
456
+ * boost when a path match is found.
452
457
  */
453
- listChanges(args: {
454
- pageToken: string;
455
- pageSize: number;
456
- }): Promise<DriveChangesPage>;
458
+ score: number;
457
459
  /**
458
- * Export a Google-native doc to plaintext. Returns the body as a string.
460
+ * References the memory mentions (file paths, entity names, etc.). Used
461
+ * to decide whether any touched file appears in the memory's scope.
462
+ *
463
+ * Accepts `undefined`/missing so callers can pass sparse records from
464
+ * legacy storage without pre-filling.
459
465
  */
460
- exportFile(args: {
461
- fileId: string;
462
- mimeType: string;
463
- }): Promise<string>;
466
+ entityRefs?: string[];
467
+ }
468
+ interface ReviewContext {
464
469
  /**
465
- * Download a non-Google-native file as a string. Used for `text/*` MIME
466
- * types; binary formats are filtered out before we get here.
470
+ * Normalized file paths touched by the diff. Each entry is forward-slashed
471
+ * and relative to the repo root when possible.
467
472
  */
468
- getFileMedia(args: {
469
- fileId: string;
470
- }): Promise<string>;
471
- }
472
- interface DriveChangesPage {
473
- readonly changes: readonly DriveChange[];
474
- readonly newStartPageToken?: string;
475
- readonly nextPageToken?: string;
476
- }
477
- interface DriveChange {
478
- readonly removed?: boolean;
479
- readonly fileId?: string;
480
- readonly file?: DriveFileMetadata;
481
- }
482
- interface DriveFileMetadata {
483
- readonly id: string;
484
- readonly name?: string;
485
- readonly mimeType?: string;
486
- readonly modifiedTime?: string;
487
- readonly trashed?: boolean;
488
- readonly parents?: readonly string[];
489
- readonly webViewLink?: string;
490
- readonly size?: string | number;
491
- }
492
- /**
493
- * Result of a single sync pass — exposed for richer test assertions.
494
- * Strict superset of `SyncIncrementalResult`.
495
- */
496
- interface GoogleDriveSyncResult extends SyncIncrementalResult {
497
- readonly skippedBinary: number;
498
- readonly skippedFolderScope: number;
499
- readonly skippedTooLarge: number;
473
+ touchedFiles: string[];
474
+ /**
475
+ * Candidates re-sorted so memories whose `entityRefs` mention a touched
476
+ * path are boosted. Shape matches the input `ReviewCandidate[]` — the
477
+ * boost is recorded on each entry as `boost` for observability.
478
+ */
479
+ rankedRecall: Array<ReviewCandidate & {
480
+ boost: number;
481
+ }>;
500
482
  }
501
483
  /**
502
- * Validate and normalise raw config. Throws with a concrete message on any
503
- * malformed input — never silently defaults (CLAUDE.md gotcha #51).
504
- */
505
- declare function validateGoogleDriveConfig(raw: unknown): GoogleDriveConnectorConfig;
506
- /**
507
- * Construct the connector. The `clientFactory` argument is the test hook —
508
- * production callers omit it and the connector lazy-loads `googleapis`.
509
- */
510
- declare function createGoogleDriveConnector(options?: {
511
- clientFactory?: GoogleDriveClientFactory;
512
- }): LiveConnector;
513
- /**
514
- * Production client factory. Lazy-loads `googleapis` via a computed-specifier
515
- * dynamic import so bundlers never statically resolve it (CLAUDE.md gotcha
516
- * #57). Surfaces a precise install hint on miss.
484
+ * `true` when the prompt looks like a review / diff-explanation request.
517
485
  *
518
- * Exported only for the `index.ts` barrel; consumers that already inject a
519
- * test factory don't need to touch this.
486
+ * Empty / non-string input `false` (the caller shouldn't branch on an
487
+ * invalid prompt).
520
488
  */
521
- declare const defaultGoogleDriveClientFactory: GoogleDriveClientFactory;
522
-
489
+ declare function isReviewPrompt(prompt: string | null | undefined): boolean;
523
490
  /**
524
- * @remnic/core Notion live connector (issue #683 PR 3/N)
525
- *
526
- * Concrete `LiveConnector` implementation that incrementally imports text
527
- * content from Notion database pages into Remnic. Built on top of the
528
- * framework shipped in PR 1/N (`framework.ts` / `registry.ts` /
529
- * `state-store.ts`) and mirrors the structure of the Google Drive connector
530
- * (PR 2/N).
531
- *
532
- * Design notes:
533
- *
534
- * - **Auth.** Integration token from config (`connectors.notion.token`).
535
- * The token is accepted at config-parse time but never logged. Operators
536
- * must populate it from a secret store; per the repo-wide privacy policy
537
- * no real value may appear in tests or comments.
538
- *
539
- * - **Scope.** `databaseIds` in config limits the import to the listed
540
- * Notion databases. The connector queries each database for pages whose
541
- * `last_edited_time` is after a per-page high-water mark stored in the
542
- * cursor. When `databaseIds` is empty the connector does nothing (safe
543
- * default — no credentials → no import).
544
- *
545
- * - **Cursor semantics.** The cursor is a JSON string encoding a
546
- * `NotionCursorPayload`: a map from page-id to last-seen
547
- * `last_edited_time` ISO string. On the first sync (cursor=null) we
548
- * seed the payload from the current state of each database WITHOUT
549
- * importing any content, so "first install" doesn't re-ingest history.
550
- * Each subsequent pass only imports pages edited after the stored
551
- * watermark.
552
- *
553
- * - **Block extraction.** Page content is fetched via
554
- * `blocks.children.list` recursively up to `MAX_BLOCK_DEPTH` levels.
555
- * Block text is extracted to Markdown-ish plain text (no raw JSON blobs).
556
- * Only text-bearing block types are included; unsupported types are
557
- * silently skipped.
558
- *
559
- * - **Raw `fetch`.** We call the Notion REST API directly rather than using
560
- * `@notionhq/client` — there is no optional-peer-dep machinery needed and
561
- * the API surface we consume is tiny. The `fetchFn` argument is the test
562
- * hook allowing stubbing without network access.
563
- *
564
- * - **Idempotency.** `ConnectorDocument.source.externalId` is the page id
565
- * and `externalRevision` is `last_edited_time`, so downstream dedup can
566
- * recognise repeat fetches if the cursor is rewound.
567
- *
568
- * - **Privacy.** No page content is ever logged. Database ids and counts
569
- * may be logged. The integration token is never exposed in logs, state,
570
- * or error messages.
491
+ * Parse a unified diff and return the set of files touched. Accepts both the
492
+ * `diff --git` form (`diff --git a/foo b/bar`) and the `--- / +++` form
493
+ * (`--- a/foo\n+++ b/bar`). Returns deduplicated, repo-root-relative paths
494
+ * (with the conventional `a/` / `b/` prefixes stripped).
571
495
  *
572
- * - **Read-only.** This connector only reads. It never modifies pages,
573
- * databases, or any other Notion resource.
574
- */
575
-
576
- /** Stable connector id. Lives in the registry under this exact string. */
577
- declare const NOTION_CONNECTOR_ID = "notion";
578
- /**
579
- * Cursor `kind` we emit. Opaque to the framework; documented here so
580
- * tests can assert on it.
581
- */
582
- declare const NOTION_CURSOR_KIND = "notionWatermark";
583
- /**
584
- * Default poll interval (5 minutes). Notion's API has no push capability;
585
- * polling sub-minute wastes quota for a personal memory layer.
586
- */
587
- declare const NOTION_DEFAULT_POLL_INTERVAL_MS: number;
588
- /**
589
- * Validated, frozen view of `connectors.notion.*`.
496
+ * Path entries of `/dev/null` (used in adds/deletes) are excluded.
590
497
  */
591
- interface NotionConnectorConfig {
592
- /** Notion integration token. Starts with `secret_`. */
593
- readonly token: string;
594
- /** Database ids to import pages from. Empty = connector is a no-op. */
595
- readonly databaseIds: readonly string[];
596
- /** Poll interval surfaced to the scheduler (ms). */
597
- readonly pollIntervalMs: number;
598
- }
498
+ declare function parseTouchedFiles(diff: string | null | undefined): string[];
599
499
  /**
600
- * Minimal fetch-compatible surface we use. The real connector delegates to
601
- * the global `fetch`; tests inject a stub factory.
500
+ * Build a review-context ranking for a set of candidate memories.
501
+ *
502
+ * Contract:
503
+ * - `touchedFiles` is the parsed diff file list.
504
+ * - `candidates` is passed through unchanged when no boost applies.
505
+ * - When a boost applies, the result is sorted by `(score + boost)` desc,
506
+ * with a stable secondary sort on the original `id` for determinism
507
+ * (CLAUDE.md #19 — comparators must return 0 for equal items).
602
508
  */
603
- type NotionFetchFn = (url: string, init: {
604
- method: string;
605
- headers: Record<string, string>;
606
- body?: string;
607
- signal?: AbortSignal;
608
- }) => Promise<{
609
- ok: boolean;
610
- status: number;
611
- json(): Promise<unknown>;
509
+ declare function rankReviewCandidates(candidates: ReviewCandidate[], touchedFiles: string[]): Array<ReviewCandidate & {
510
+ boost: number;
612
511
  }>;
512
+ interface PackReviewContextInput {
513
+ /** Unified diff, as produced by `git diff`. */
514
+ diff: string | null | undefined;
515
+ /** Candidate memories from the upstream recall pipeline. */
516
+ candidates: ReviewCandidate[];
517
+ }
613
518
  /**
614
- * Validate and normalise raw config. Throws with a concrete message on any
615
- * malformed input never silently defaults (CLAUDE.md gotcha #51).
616
- */
617
- declare function validateNotionConfig(raw: unknown): NotionConnectorConfig;
618
- /**
619
- * Construct the connector. The `fetchFn` argument is the test hook —
620
- * production callers omit it and the connector uses the global `fetch`.
621
- */
622
- declare function createNotionConnector(options?: {
623
- fetchFn?: NotionFetchFn;
624
- }): LiveConnector;
625
-
626
- /**
627
- * memory-extension-host/render-extensions-block.ts — Render discovered extensions
628
- * into a markdown block for injection into consolidation prompts.
519
+ * Top-level entry point used by the orchestrator (and CLI / bench) when a
520
+ * review-intent prompt is detected.
629
521
  *
630
- * Respects the global token budget (REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT) and
631
- * truncates with a footer listing omitted extensions when over budget.
522
+ * Parses the diff, re-ranks the candidates, and returns both artefacts so
523
+ * the caller can surface `touchedFiles` as context and `rankedRecall` as
524
+ * the recall result.
632
525
  */
526
+ declare function packReviewContext(input: PackReviewContextInput): ReviewContext;
633
527
 
634
528
  /**
635
- * Render a markdown block containing extension instructions for injection
636
- * into consolidation prompts.
529
+ * Binary file lifecycle management types.
637
530
  *
638
- * If the list is empty, returns "".
639
- * Inlines extensions in name order until the token budget is exhausted.
640
- * If the budget is exceeded, appends a truncation footer listing omitted extensions.
641
- */
642
- declare function renderExtensionsBlock(extensions: DiscoveredExtension[]): string;
643
- /**
644
- * Render a compact one-line footer listing active extension names.
645
- * Used by day-summary and summary-snapshot where full instructions are not needed.
646
- */
647
- declare function renderExtensionsFooter(extensions: DiscoveredExtension[]): string;
648
-
649
- /**
650
- * Strict UTC-only parser — accepts `YYYY-MM-DDTHH:MM:SS[.sss]Z`.
651
- * Returns milliseconds since epoch, or `null` if invalid.
652
- */
653
- declare function parseIsoUtcTimestamp(value: string): number | null;
654
- /**
655
- * Lenient parser — accepts variable-precision fractional seconds and either
656
- * a `Z` suffix or a `[+-]HH:MM` offset. Returns milliseconds since epoch, or
657
- * `null` if the string is not a well-formed RFC 3339 timestamp.
658
- */
659
- declare function parseIsoOffsetTimestamp(value: string): number | null;
660
- /**
661
- * Benchmark/adapter parser — accepts ISO date-only values plus reduced
662
- * precision date-times used by public benchmark fixtures. Returns milliseconds
663
- * since epoch, or `null` if invalid.
664
- */
665
- declare function parseFlexibleIsoTimestamp(value: string): number | null;
666
-
667
- /**
668
- * Intent-gated recall for active procedure memories (issue #519).
669
- */
670
-
671
- /**
672
- * Build markdown for the recall pipeline when procedural memory is enabled and
673
- * the prompt looks like task initiation.
674
- */
675
- declare function buildProcedureRecallSection(storage: StorageManager, prompt: string, config: PluginConfig): Promise<string | null>;
676
-
677
- /**
678
- * Procedural memory types (issue #519).
679
- * Bodies use ordered "## Step N" sections; machine fields live in frontmatter / structuredAttributes.
680
- */
681
- interface ProcedureStep {
682
- order: number;
683
- intent: string;
684
- toolCall?: {
685
- kind: string;
686
- signature: string;
687
- };
688
- expectedOutcome?: string;
689
- optional?: boolean;
690
- }
691
- /** Serialize steps into markdown body (human-editable). */
692
- declare function buildProcedureMarkdownBody(steps: ProcedureStep[]): string;
693
- /**
694
- * Best-effort parse of "## Step N" blocks into ProcedureStep records.
695
- * Returns null when no step headers are found.
696
- */
697
- declare function parseProcedureStepsFromBody(content: string): ProcedureStep[] | null;
698
-
699
- interface GitContext {
700
- /**
701
- * Stable identifier for the project. Derived from `git remote get-url origin`
702
- * when an origin remote is configured, otherwise from the repo root path.
703
- *
704
- * Formatted as `origin:<hex>` or `root:<hex>` so that the source is visible
705
- * to operators (see `remnic doctor`, issue #569 acceptance criteria).
706
- */
707
- projectId: string;
708
- /**
709
- * Current branch, e.g. `main`, `feat/foo`. `null` only in detached-HEAD
710
- * state (e.g. rebase in progress). Callers should treat `null` as "no
711
- * branch-scope overlay applies" without erroring.
712
- */
713
- branch: string | null;
714
- /**
715
- * Absolute path to the repository root (the directory containing `.git`).
716
- * Tilde-expanded per CLAUDE.md #17.
717
- */
718
- rootPath: string;
719
- /**
720
- * Best-effort default branch (usually `main` or `master`). Derived from the
721
- * `refs/remotes/origin/HEAD` symbolic ref. `null` when not available (e.g.
722
- * fresh clone without a default branch symref, or no origin remote).
723
- */
724
- defaultBranch: string | null;
725
- }
726
- /**
727
- * Injectable git-invocation surface. Only the commands `resolveGitContext`
728
- * actually needs are exposed. Tests inject a mock implementation to avoid
729
- * spawning a real git process.
730
- */
731
- interface GitInvoker {
732
- /**
733
- * Run `git <args>` with `cwd` as the working directory. Must return
734
- * `{ stdout, exitCode }` with `stdout` trimmed by the caller as needed.
735
- * Implementations should NOT throw for non-zero exit codes — they should
736
- * return the exit code so the resolver can decide how to recover.
737
- */
738
- (cwd: string, args: string[]): {
739
- stdout: string;
740
- exitCode: number;
741
- };
742
- }
743
- /**
744
- * Non-cryptographic stable hash. Used only to derive a deterministic
745
- * `projectId` from either the origin URL or the root path. The hash does not
746
- * need to be collision-resistant against adversarial input — it is purely a
747
- * namespace discriminator.
748
- *
749
- * Uses FNV-1a 32-bit so we don't pull in `node:crypto` for a simple bucket
750
- * key. Output is lowercase hex, zero-padded to 8 characters.
751
- */
752
- declare function stableHash(input: string): string;
753
- /**
754
- * Normalize a git remote URL so that equivalent SSH / HTTPS forms of the
755
- * same repo produce the same `projectId`. Handles:
756
- * - `git@github.com:foo/bar.git` → `github.com/foo/bar`
757
- * - `https://github.com/foo/bar` → `github.com/foo/bar`
758
- * - `https://github.com/foo/bar.git` → `github.com/foo/bar`
759
- * - `ssh://git@github.com/foo/bar` → `github.com/foo/bar`
760
- * - `ssh://git@github.com:2222/foo/bar` → `github.com/foo/bar` (port stripped)
761
- *
762
- * Case-insensitive (remote hostnames and most repo paths on major forges are
763
- * case-insensitive in practice).
764
- */
765
- declare function normalizeOriginUrl(rawUrl: string): string;
766
- interface ResolveGitContextOptions {
767
- /** Inject a git invoker (tests). Defaults to spawning real `git`. */
768
- invoker?: GitInvoker;
769
- }
770
- /**
771
- * Detect the git project + branch for `cwd`.
772
- *
773
- * Returns `null` when:
774
- * - `cwd` is not an absolute path (invalid input, CLAUDE.md #51)
775
- * - `cwd` is not inside a git worktree
776
- * - `git` is not available on PATH
777
- *
778
- * Never throws.
779
- */
780
- declare function resolveGitContext(cwd: string, options?: ResolveGitContextOptions): Promise<GitContext | null>;
781
-
782
- /**
783
- * Diff-aware review-context packer (issue #569 PR 4).
784
- *
785
- * When an agent is asked "review this PR" / "what changed in this diff" /
786
- * "look at this diff", the prompt that reaches recall is short and generic
787
- * — the real signal is the diff itself. This module:
788
- *
789
- * 1. Detects review-intent prompts via `isReviewPrompt`.
790
- * 2. Extracts the touched file list from a unified diff via
791
- * `parseTouchedFiles`.
792
- * 3. Re-ranks a set of candidate memories so that memories whose
793
- * `entityRefs` mention a touched path float to the top. The boost is
794
- * additive and bounded so it doesn't obliterate the original ranking —
795
- * it's a bias, not a filter.
796
- *
797
- * Pure — no orchestrator, no storage. Callers inject the candidate memories
798
- * they already have from their normal recall pipeline. This keeps the
799
- * module easy to test and integrates cleanly with the existing tiered-recall
800
- * code in `orchestrator.ts` (the tier itself can be wired later; the pure
801
- * surface is what PRs 5/6/7 will call).
802
- */
803
- /**
804
- * A memory candidate as fed into review-context ranking. The shape is a
805
- * deliberate subset of the core `MemorySummary` / recall result — only the
806
- * fields we actually need — so this module stays decoupled from the rest of
807
- * the codebase and can be reused by CLI tools, bench fixtures, etc.
808
- */
809
- interface ReviewCandidate {
810
- /** Opaque identifier. Echoed unchanged in the output. */
811
- id: string;
812
- /**
813
- * Pre-review relevance score from the upstream recall pipeline. Higher is
814
- * better. `0` is treated as "no prior signal" and gets the full review
815
- * boost when a path match is found.
816
- */
817
- score: number;
818
- /**
819
- * References the memory mentions (file paths, entity names, etc.). Used
820
- * to decide whether any touched file appears in the memory's scope.
821
- *
822
- * Accepts `undefined`/missing so callers can pass sparse records from
823
- * legacy storage without pre-filling.
824
- */
825
- entityRefs?: string[];
826
- }
827
- interface ReviewContext {
828
- /**
829
- * Normalized file paths touched by the diff. Each entry is forward-slashed
830
- * and relative to the repo root when possible.
831
- */
832
- touchedFiles: string[];
833
- /**
834
- * Candidates re-sorted so memories whose `entityRefs` mention a touched
835
- * path are boosted. Shape matches the input `ReviewCandidate[]` — the
836
- * boost is recorded on each entry as `boost` for observability.
837
- */
838
- rankedRecall: Array<ReviewCandidate & {
839
- boost: number;
840
- }>;
841
- }
842
- /**
843
- * `true` when the prompt looks like a review / diff-explanation request.
844
- *
845
- * Empty / non-string input → `false` (the caller shouldn't branch on an
846
- * invalid prompt).
847
- */
848
- declare function isReviewPrompt(prompt: string | null | undefined): boolean;
849
- /**
850
- * Parse a unified diff and return the set of files touched. Accepts both the
851
- * `diff --git` form (`diff --git a/foo b/bar`) and the `--- / +++` form
852
- * (`--- a/foo\n+++ b/bar`). Returns deduplicated, repo-root-relative paths
853
- * (with the conventional `a/` / `b/` prefixes stripped).
854
- *
855
- * Path entries of `/dev/null` (used in adds/deletes) are excluded.
856
- */
857
- declare function parseTouchedFiles(diff: string | null | undefined): string[];
858
- /**
859
- * Build a review-context ranking for a set of candidate memories.
860
- *
861
- * Contract:
862
- * - `touchedFiles` is the parsed diff file list.
863
- * - `candidates` is passed through unchanged when no boost applies.
864
- * - When a boost applies, the result is sorted by `(score + boost)` desc,
865
- * with a stable secondary sort on the original `id` for determinism
866
- * (CLAUDE.md #19 — comparators must return 0 for equal items).
867
- */
868
- declare function rankReviewCandidates(candidates: ReviewCandidate[], touchedFiles: string[]): Array<ReviewCandidate & {
869
- boost: number;
870
- }>;
871
- interface PackReviewContextInput {
872
- /** Unified diff, as produced by `git diff`. */
873
- diff: string | null | undefined;
874
- /** Candidate memories from the upstream recall pipeline. */
875
- candidates: ReviewCandidate[];
876
- }
877
- /**
878
- * Top-level entry point used by the orchestrator (and CLI / bench) when a
879
- * review-intent prompt is detected.
880
- *
881
- * Parses the diff, re-ranks the candidates, and returns both artefacts so
882
- * the caller can surface `touchedFiles` as context and `rankedRecall` as
883
- * the recall result.
884
- */
885
- declare function packReviewContext(input: PackReviewContextInput): ReviewContext;
886
-
887
- /**
888
- * Binary file lifecycle management types.
889
- *
890
- * Defines the configuration, manifest, and record structures for the
891
- * three-stage binary lifecycle pipeline: mirror, redirect, clean.
531
+ * Defines the configuration, manifest, and record structures for the
532
+ * three-stage binary lifecycle pipeline: mirror, redirect, clean.
892
533
  */
893
534
  interface BinaryLifecycleConfig {
894
535
  /** Master toggle. Default: false. */
@@ -1520,6 +1161,366 @@ declare function watchForChanges(options: SyncOptions, onChange: (changes: FileC
1520
1161
  stop: () => void;
1521
1162
  };
1522
1163
 
1164
+ /**
1165
+ * memory-extension-host/render-extensions-block.ts — Render discovered extensions
1166
+ * into a markdown block for injection into consolidation prompts.
1167
+ *
1168
+ * Respects the global token budget (REMNIC_EXTENSIONS_TOTAL_TOKEN_LIMIT) and
1169
+ * truncates with a footer listing omitted extensions when over budget.
1170
+ */
1171
+
1172
+ /**
1173
+ * Render a markdown block containing extension instructions for injection
1174
+ * into consolidation prompts.
1175
+ *
1176
+ * If the list is empty, returns "".
1177
+ * Inlines extensions in name order until the token budget is exhausted.
1178
+ * If the budget is exceeded, appends a truncation footer listing omitted extensions.
1179
+ */
1180
+ declare function renderExtensionsBlock(extensions: DiscoveredExtension[]): string;
1181
+ /**
1182
+ * Render a compact one-line footer listing active extension names.
1183
+ * Used by day-summary and summary-snapshot where full instructions are not needed.
1184
+ */
1185
+ declare function renderExtensionsFooter(extensions: DiscoveredExtension[]): string;
1186
+
1187
+ /**
1188
+ * @remnic/core — Live Connectors Registry (issue #683 PR 1/N)
1189
+ *
1190
+ * Pure in-memory registry. No I/O. Concrete connectors register themselves at
1191
+ * orchestrator boot (later PRs); the maintenance scheduler asks the registry
1192
+ * for the active set when running due syncs.
1193
+ */
1194
+
1195
+ /**
1196
+ * Thrown when registering a duplicate id or an id that fails validation.
1197
+ *
1198
+ * Distinct error class so callers can distinguish framework-level mistakes
1199
+ * (which are programmer errors) from connector-runtime failures.
1200
+ */
1201
+ declare class LiveConnectorRegistryError extends Error {
1202
+ constructor(message: string);
1203
+ }
1204
+ /**
1205
+ * In-memory registry of live connectors. One instance per orchestrator. Not
1206
+ * safe for cross-process sharing — wire each process to its own registry.
1207
+ */
1208
+ declare class LiveConnectorRegistry {
1209
+ private readonly connectors;
1210
+ /**
1211
+ * Register a connector. Throws `LiveConnectorRegistryError` if the id is
1212
+ * malformed or already registered.
1213
+ *
1214
+ * Re-registration is rejected (rather than silently overwriting) because
1215
+ * silent overwrites mask plugin loading bugs in development and could let
1216
+ * a malicious extension shadow a built-in connector.
1217
+ */
1218
+ register(connector: LiveConnector): void;
1219
+ /**
1220
+ * Look up a connector by id. Returns `undefined` if not registered.
1221
+ */
1222
+ get(id: string): LiveConnector | undefined;
1223
+ /**
1224
+ * Return all registered connectors, sorted by id for stable enumeration.
1225
+ */
1226
+ list(): LiveConnector[];
1227
+ /**
1228
+ * Remove a connector. Returns `true` if a connector was removed, `false`
1229
+ * otherwise. The cursor / state file on disk is **not** touched — callers
1230
+ * who want to fully decommission a connector must also delete its state
1231
+ * file via the `state-store` module.
1232
+ */
1233
+ unregister(id: string): boolean;
1234
+ /**
1235
+ * Number of registered connectors. Cheap; safe to call frequently.
1236
+ */
1237
+ size(): number;
1238
+ }
1239
+
1240
+ /**
1241
+ * @remnic/core — Google Drive live connector (issue #683 PR 2/N)
1242
+ *
1243
+ * Concrete `LiveConnector` implementation that incrementally imports text
1244
+ * content from a user's Google Drive into Remnic. Built on top of the
1245
+ * framework shipped in PR 1/N (`framework.ts` / `registry.ts` /
1246
+ * `state-store.ts`).
1247
+ *
1248
+ * Design notes:
1249
+ *
1250
+ * - **Cursor semantics.** We page Drive with the official `changes` API
1251
+ * when a `startPageToken` is available. The cursor is opaque from the
1252
+ * framework's POV (`{kind: "drivePageToken", value: ...}`), and on the
1253
+ * very first sync (cursor=null) we call `changes.getStartPageToken()`
1254
+ * to seed it without importing anything. This matches the documented
1255
+ * Drive incremental-sync recipe and means re-runs never re-ingest the
1256
+ * same file as long as the cursor file survives.
1257
+ *
1258
+ * - **Folder scope.** When `folderIds` is non-empty, files are filtered
1259
+ * to those whose `parents` intersect the configured folder set. Drive
1260
+ * does not currently support server-side parent filtering on the
1261
+ * `changes.list` endpoint, so we pull the change record's `file` payload
1262
+ * and apply the filter on our side. Folder ids are validated up front so
1263
+ * a typo in config doesn't silently cause a broad import.
1264
+ *
1265
+ * - **Content extraction.** Google-native MIME types
1266
+ * (`application/vnd.google-apps.{document,spreadsheet,presentation}`)
1267
+ * are exported via `files.export` to plaintext. Plain-text MIME types
1268
+ * are pulled with `files.get?alt=media`. Everything else is skipped —
1269
+ * bytes from binary formats (images, PDFs, archives) belong in the
1270
+ * binary-lifecycle pipeline, not in the textual ingestion path.
1271
+ *
1272
+ * - **Idempotency.** Each emitted `ConnectorDocument.source` carries
1273
+ * `externalId = file.id` plus `externalRevision = file.modifiedTime`,
1274
+ * so downstream dedup (CLAUDE.md gotcha #44 — never index content that
1275
+ * failed to persist) can recognise repeat fetches even if the cursor is
1276
+ * manually rewound.
1277
+ *
1278
+ * - **Privacy.** No document content is ever logged. Folder ids and
1279
+ * counts may be logged. OAuth credentials (`clientId`,
1280
+ * `clientSecret`, `refreshToken`) are accepted via config but the
1281
+ * intent is for callers to populate them from a secret store; we never
1282
+ * persist credentials through the connector state-store. Per CLAUDE.md
1283
+ * repository-privacy rules, no real credentials may appear in tests,
1284
+ * fixtures, or comments.
1285
+ *
1286
+ * - **À-la-carte packaging (CLAUDE.md gotcha #57).** `googleapis` is NOT
1287
+ * listed as a hard dependency of `@remnic/core`. It is loaded via a
1288
+ * computed-specifier dynamic import (`await import("google" + "apis")`)
1289
+ * so bundlers cannot statically resolve it, and it is declared as an
1290
+ * optional peer dependency. Operators who never enable the connector
1291
+ * pay nothing for it.
1292
+ *
1293
+ * - **Read-only.** This connector only reads. It never marks files as
1294
+ * read, edits metadata, or modifies sharing settings.
1295
+ */
1296
+
1297
+ /**
1298
+ * Stable connector id. Lives in the registry under this exact string.
1299
+ */
1300
+ declare const GOOGLE_DRIVE_CONNECTOR_ID = "google-drive";
1301
+ /**
1302
+ * Cursor `kind` we emit. Treated as opaque by the framework; documented
1303
+ * here so tests can assert on it.
1304
+ */
1305
+ declare const GOOGLE_DRIVE_CURSOR_KIND = "drivePageToken";
1306
+ /**
1307
+ * Default poll interval (5 minutes). Surfaced in `openclaw.plugin.json`
1308
+ * defaults and in the documented config schema. Drive's `changes.list`
1309
+ * endpoint is cheap, but polling sub-minute is wasteful for a personal
1310
+ * memory layer.
1311
+ */
1312
+ declare const DEFAULT_POLL_INTERVAL_MS: number;
1313
+ /**
1314
+ * Validated, frozen view of `connectors.googleDrive.*`.
1315
+ */
1316
+ interface GoogleDriveConnectorConfig {
1317
+ readonly clientId: string;
1318
+ readonly clientSecret: string;
1319
+ readonly refreshToken: string;
1320
+ /** Poll interval surfaced to the scheduler. */
1321
+ readonly pollIntervalMs: number;
1322
+ /** Folder ids to scope import to. Empty = "all accessible". */
1323
+ readonly folderIds: readonly string[];
1324
+ }
1325
+ /**
1326
+ * Optional injection point for tests. The real connector dynamically imports
1327
+ * `googleapis`; tests pass a stub here to avoid the optional-peer-dep
1328
+ * machinery and to keep the test suite hermetic.
1329
+ *
1330
+ * The shape only covers the tiny slice of the SDK we actually use.
1331
+ */
1332
+ interface GoogleDriveClientFactory {
1333
+ (config: GoogleDriveConnectorConfig): Promise<GoogleDriveClient>;
1334
+ }
1335
+ /**
1336
+ * Minimal Drive client surface. Tests provide a fake; production wraps
1337
+ * `googleapis` to fit. Method shapes mirror the upstream API where it
1338
+ * matters (`startPageToken` / `nextPageToken` / `newStartPageToken`,
1339
+ * `files.modifiedTime` ISO 8601 strings).
1340
+ */
1341
+ interface GoogleDriveClient {
1342
+ /** Mirrors `drive.changes.getStartPageToken()`. */
1343
+ getStartPageToken(): Promise<{
1344
+ startPageToken: string;
1345
+ }>;
1346
+ /**
1347
+ * Mirrors `drive.changes.list(...)`. We page until the response yields a
1348
+ * `newStartPageToken` (i.e., no more pages). Each `change.file`, when
1349
+ * present, includes the metadata we need to decide whether to ingest.
1350
+ */
1351
+ listChanges(args: {
1352
+ pageToken: string;
1353
+ pageSize: number;
1354
+ }): Promise<DriveChangesPage>;
1355
+ /**
1356
+ * Export a Google-native doc to plaintext. Returns the body as a string.
1357
+ */
1358
+ exportFile(args: {
1359
+ fileId: string;
1360
+ mimeType: string;
1361
+ }): Promise<string>;
1362
+ /**
1363
+ * Download a non-Google-native file as a string. Used for `text/*` MIME
1364
+ * types; binary formats are filtered out before we get here.
1365
+ */
1366
+ getFileMedia(args: {
1367
+ fileId: string;
1368
+ }): Promise<string>;
1369
+ }
1370
+ interface DriveChangesPage {
1371
+ readonly changes: readonly DriveChange[];
1372
+ readonly newStartPageToken?: string;
1373
+ readonly nextPageToken?: string;
1374
+ }
1375
+ interface DriveChange {
1376
+ readonly removed?: boolean;
1377
+ readonly fileId?: string;
1378
+ readonly file?: DriveFileMetadata;
1379
+ }
1380
+ interface DriveFileMetadata {
1381
+ readonly id: string;
1382
+ readonly name?: string;
1383
+ readonly mimeType?: string;
1384
+ readonly modifiedTime?: string;
1385
+ readonly trashed?: boolean;
1386
+ readonly parents?: readonly string[];
1387
+ readonly webViewLink?: string;
1388
+ readonly size?: string | number;
1389
+ }
1390
+ /**
1391
+ * Result of a single sync pass — exposed for richer test assertions.
1392
+ * Strict superset of `SyncIncrementalResult`.
1393
+ */
1394
+ interface GoogleDriveSyncResult extends SyncIncrementalResult {
1395
+ readonly skippedBinary: number;
1396
+ readonly skippedFolderScope: number;
1397
+ readonly skippedTooLarge: number;
1398
+ }
1399
+ /**
1400
+ * Validate and normalise raw config. Throws with a concrete message on any
1401
+ * malformed input — never silently defaults (CLAUDE.md gotcha #51).
1402
+ */
1403
+ declare function validateGoogleDriveConfig(raw: unknown): GoogleDriveConnectorConfig;
1404
+ /**
1405
+ * Construct the connector. The `clientFactory` argument is the test hook —
1406
+ * production callers omit it and the connector lazy-loads `googleapis`.
1407
+ */
1408
+ declare function createGoogleDriveConnector(options?: {
1409
+ clientFactory?: GoogleDriveClientFactory;
1410
+ }): LiveConnector;
1411
+ /**
1412
+ * Production client factory. Lazy-loads `googleapis` via a computed-specifier
1413
+ * dynamic import so bundlers never statically resolve it (CLAUDE.md gotcha
1414
+ * #57). Surfaces a precise install hint on miss.
1415
+ *
1416
+ * Exported only for the `index.ts` barrel; consumers that already inject a
1417
+ * test factory don't need to touch this.
1418
+ */
1419
+ declare const defaultGoogleDriveClientFactory: GoogleDriveClientFactory;
1420
+
1421
+ /**
1422
+ * @remnic/core — Notion live connector (issue #683 PR 3/N)
1423
+ *
1424
+ * Concrete `LiveConnector` implementation that incrementally imports text
1425
+ * content from Notion database pages into Remnic. Built on top of the
1426
+ * framework shipped in PR 1/N (`framework.ts` / `registry.ts` /
1427
+ * `state-store.ts`) and mirrors the structure of the Google Drive connector
1428
+ * (PR 2/N).
1429
+ *
1430
+ * Design notes:
1431
+ *
1432
+ * - **Auth.** Integration token from config (`connectors.notion.token`).
1433
+ * The token is accepted at config-parse time but never logged. Operators
1434
+ * must populate it from a secret store; per the repo-wide privacy policy
1435
+ * no real value may appear in tests or comments.
1436
+ *
1437
+ * - **Scope.** `databaseIds` in config limits the import to the listed
1438
+ * Notion databases. The connector queries each database for pages whose
1439
+ * `last_edited_time` is after a per-page high-water mark stored in the
1440
+ * cursor. When `databaseIds` is empty the connector does nothing (safe
1441
+ * default — no credentials → no import).
1442
+ *
1443
+ * - **Cursor semantics.** The cursor is a JSON string encoding a
1444
+ * `NotionCursorPayload`: a map from page-id to last-seen
1445
+ * `last_edited_time` ISO string. On the first sync (cursor=null) we
1446
+ * seed the payload from the current state of each database WITHOUT
1447
+ * importing any content, so "first install" doesn't re-ingest history.
1448
+ * Each subsequent pass only imports pages edited after the stored
1449
+ * watermark.
1450
+ *
1451
+ * - **Block extraction.** Page content is fetched via
1452
+ * `blocks.children.list` recursively up to `MAX_BLOCK_DEPTH` levels.
1453
+ * Block text is extracted to Markdown-ish plain text (no raw JSON blobs).
1454
+ * Only text-bearing block types are included; unsupported types are
1455
+ * silently skipped.
1456
+ *
1457
+ * - **Raw `fetch`.** We call the Notion REST API directly rather than using
1458
+ * `@notionhq/client` — there is no optional-peer-dep machinery needed and
1459
+ * the API surface we consume is tiny. The `fetchFn` argument is the test
1460
+ * hook allowing stubbing without network access.
1461
+ *
1462
+ * - **Idempotency.** `ConnectorDocument.source.externalId` is the page id
1463
+ * and `externalRevision` is `last_edited_time`, so downstream dedup can
1464
+ * recognise repeat fetches if the cursor is rewound.
1465
+ *
1466
+ * - **Privacy.** No page content is ever logged. Database ids and counts
1467
+ * may be logged. The integration token is never exposed in logs, state,
1468
+ * or error messages.
1469
+ *
1470
+ * - **Read-only.** This connector only reads. It never modifies pages,
1471
+ * databases, or any other Notion resource.
1472
+ */
1473
+
1474
+ /** Stable connector id. Lives in the registry under this exact string. */
1475
+ declare const NOTION_CONNECTOR_ID = "notion";
1476
+ /**
1477
+ * Cursor `kind` we emit. Opaque to the framework; documented here so
1478
+ * tests can assert on it.
1479
+ */
1480
+ declare const NOTION_CURSOR_KIND = "notionWatermark";
1481
+ /**
1482
+ * Default poll interval (5 minutes). Notion's API has no push capability;
1483
+ * polling sub-minute wastes quota for a personal memory layer.
1484
+ */
1485
+ declare const NOTION_DEFAULT_POLL_INTERVAL_MS: number;
1486
+ /**
1487
+ * Validated, frozen view of `connectors.notion.*`.
1488
+ */
1489
+ interface NotionConnectorConfig {
1490
+ /** Notion integration token. Starts with `secret_`. */
1491
+ readonly token: string;
1492
+ /** Database ids to import pages from. Empty = connector is a no-op. */
1493
+ readonly databaseIds: readonly string[];
1494
+ /** Poll interval surfaced to the scheduler (ms). */
1495
+ readonly pollIntervalMs: number;
1496
+ }
1497
+ /**
1498
+ * Minimal fetch-compatible surface we use. The real connector delegates to
1499
+ * the global `fetch`; tests inject a stub factory.
1500
+ */
1501
+ type NotionFetchFn = (url: string, init: {
1502
+ method: string;
1503
+ headers: Record<string, string>;
1504
+ body?: string;
1505
+ signal?: AbortSignal;
1506
+ }) => Promise<{
1507
+ ok: boolean;
1508
+ status: number;
1509
+ json(): Promise<unknown>;
1510
+ }>;
1511
+ /**
1512
+ * Validate and normalise raw config. Throws with a concrete message on any
1513
+ * malformed input — never silently defaults (CLAUDE.md gotcha #51).
1514
+ */
1515
+ declare function validateNotionConfig(raw: unknown): NotionConnectorConfig;
1516
+ /**
1517
+ * Construct the connector. The `fetchFn` argument is the test hook —
1518
+ * production callers omit it and the connector uses the global `fetch`.
1519
+ */
1520
+ declare function createNotionConnector(options?: {
1521
+ fetchFn?: NotionFetchFn;
1522
+ }): LiveConnector;
1523
+
1523
1524
  /**
1524
1525
  * @remnic/core — Spaces + Collaboration
1525
1526
  *