@remnic/core 9.66.0 → 9.66.2

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 (575) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -11
  2. package/dist/access-admin-ops-surface.js +31 -31
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +11 -11
  5. package/dist/access-authorization-probe.js +32 -32
  6. package/dist/access-boundary.d.ts +11 -11
  7. package/dist/access-boundary.js +31 -31
  8. package/dist/access-cli.js +105 -101
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-coding-context-resolution.d.ts +1 -1
  11. package/dist/access-extraction-force-flush.d.ts +11 -11
  12. package/dist/access-extraction-force-flush.js +31 -31
  13. package/dist/access-health-types.d.ts +1 -1
  14. package/dist/access-http-lcm-compaction.d.ts +11 -11
  15. package/dist/access-http-lifecycle-flush.d.ts +11 -11
  16. package/dist/access-http-offline-stream.d.ts +11 -11
  17. package/dist/access-http-query.d.ts +2 -2
  18. package/dist/access-http-query.js +33 -33
  19. package/dist/access-http.d.ts +12 -12
  20. package/dist/access-http.js +48 -48
  21. package/dist/access-identity-continuity-surface.d.ts +9 -9
  22. package/dist/access-identity-continuity-surface.js +31 -31
  23. package/dist/access-lcm-surface.d.ts +11 -11
  24. package/dist/access-lcm-surface.js +31 -31
  25. package/dist/access-mcp.d.ts +11 -11
  26. package/dist/access-mcp.js +39 -39
  27. package/dist/access-memory-search-fanout.d.ts +2 -2
  28. package/dist/{access-namespace-preflight-CLWUoMyW.d.ts → access-namespace-preflight-50VIkPhB.d.ts} +1 -1
  29. package/dist/access-namespace-preflight.d.ts +3 -3
  30. package/dist/access-namespace-preflight.js +31 -31
  31. package/dist/access-observe-write-surface.d.ts +11 -11
  32. package/dist/access-observe-write-surface.js +31 -31
  33. package/dist/access-offline-manifest.d.ts +9 -9
  34. package/dist/access-operations-batch.js +34 -34
  35. package/dist/access-operations.d.ts +11 -11
  36. package/dist/access-operations.js +38 -38
  37. package/dist/access-recall-concurrency.d.ts +11 -11
  38. package/dist/access-recall-concurrency.js +31 -31
  39. package/dist/access-recall-response.d.ts +11 -11
  40. package/dist/access-recall-response.js +31 -31
  41. package/dist/access-recall-surface.d.ts +11 -11
  42. package/dist/access-recall-surface.js +31 -31
  43. package/dist/access-schema.js +3 -3
  44. package/dist/{access-service-CEUE1Isj.d.ts → access-service-Dz6I9AZ-.d.ts} +13 -13
  45. package/dist/access-service-helpers.d.ts +11 -11
  46. package/dist/access-service.d.ts +11 -11
  47. package/dist/access-service.js +31 -31
  48. package/dist/access-surface-catalog.d.ts +11 -11
  49. package/dist/access-surface-catalog.js +33 -33
  50. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  51. package/dist/action-confidence.d.ts +1 -1
  52. package/dist/active-memory-bridge.d.ts +1 -1
  53. package/dist/active-recall.d.ts +1 -1
  54. package/dist/active-recall.js +4 -4
  55. package/dist/adapters/index.js +4 -4
  56. package/dist/adapters/registry.js +2 -2
  57. package/dist/ambient-provenance.d.ts +1 -1
  58. package/dist/artifact-search.d.ts +1 -1
  59. package/dist/behavior-learner.d.ts +1 -1
  60. package/dist/behavior-signals.d.ts +1 -1
  61. package/dist/bootstrap.d.ts +9 -9
  62. package/dist/briefing-window.d.ts +2 -2
  63. package/dist/briefing.d.ts +2 -2
  64. package/dist/briefing.js +10 -10
  65. package/dist/buffer-surprise-report.d.ts +1 -1
  66. package/dist/buffer-turn-helpers.d.ts +1 -1
  67. package/dist/buffer.d.ts +2 -2
  68. package/dist/buffer.js +4 -4
  69. package/dist/bulk-import/index.d.ts +3 -3
  70. package/dist/calibration.d.ts +1 -1
  71. package/dist/capabilities.d.ts +1 -1
  72. package/dist/{catalog-D1HgugTA.d.ts → catalog-C2jA-gLm.d.ts} +1 -1
  73. package/dist/causal-behavior.d.ts +1 -1
  74. package/dist/causal-behavior.js +2 -2
  75. package/dist/causal-chain.js +2 -2
  76. package/dist/causal-consolidation.d.ts +1 -1
  77. package/dist/causal-consolidation.js +13 -13
  78. package/dist/causal-retrieval.js +2 -2
  79. package/dist/causal-trajectory-graph.d.ts +1 -1
  80. package/dist/causal-trajectory-graph.js +2 -2
  81. package/dist/causal-trajectory.js +1 -1
  82. package/dist/{chunk-EZSCW4EM.js → chunk-25OLNWYG.js} +2 -2
  83. package/dist/{chunk-2LBAFHOQ.js → chunk-2QSGJTDG.js} +10 -10
  84. package/dist/{chunk-7UTDHQZ5.js → chunk-2VZHB5US.js} +2 -2
  85. package/dist/{chunk-VQNRICAQ.js → chunk-36HJ36FK.js} +3 -3
  86. package/dist/{chunk-XKNHFDTT.js → chunk-3A2Z4OOS.js} +2 -2
  87. package/dist/{chunk-KODXCHXJ.js → chunk-46XR5FNZ.js} +39 -3
  88. package/dist/chunk-46XR5FNZ.js.map +1 -0
  89. package/dist/{chunk-56IV4J5W.js → chunk-47WWTCJY.js} +1384 -99
  90. package/dist/chunk-47WWTCJY.js.map +1 -0
  91. package/dist/{chunk-RDGKVH6T.js → chunk-4NKIGSJM.js} +2 -2
  92. package/dist/{chunk-EFQCDJZ2.js → chunk-4PG2CKI6.js} +2 -2
  93. package/dist/{chunk-HJXA6ZM7.js → chunk-6545JDIM.js} +2 -2
  94. package/dist/{chunk-J3OND5QT.js → chunk-65HXVEVG.js} +2 -2
  95. package/dist/{chunk-HNPE66LB.js → chunk-6BYJQ3L2.js} +8 -8
  96. package/dist/{chunk-ZW4VXELZ.js → chunk-6PUF7LUO.js} +2 -2
  97. package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
  98. package/dist/{chunk-MN5NOOI7.js → chunk-AI5M4FVQ.js} +2 -2
  99. package/dist/{chunk-IHGMRDEE.js → chunk-B4B3QDV3.js} +235 -151
  100. package/dist/chunk-B4B3QDV3.js.map +1 -0
  101. package/dist/{chunk-YMOPYG3K.js → chunk-BIJAWZYW.js} +6 -6
  102. package/dist/{chunk-I5VB44ZK.js → chunk-BLHKR4GJ.js} +2 -2
  103. package/dist/chunk-BLUYQFRH.js +36 -0
  104. package/dist/chunk-BLUYQFRH.js.map +1 -0
  105. package/dist/{chunk-CEH2AFXG.js → chunk-C24UZSFW.js} +6 -6
  106. package/dist/{chunk-MJRGVXPQ.js → chunk-C3ZYZKDJ.js} +2 -2
  107. package/dist/{chunk-QCRJMU5V.js → chunk-CDLPF3PX.js} +2 -2
  108. package/dist/{chunk-23CVL7HS.js → chunk-CQ6IWZDI.js} +2 -2
  109. package/dist/{chunk-KWIGDKM2.js → chunk-D2YNNDML.js} +2 -2
  110. package/dist/{chunk-FTTJRVB7.js → chunk-D3DUA64S.js} +2 -2
  111. package/dist/{chunk-7XOG75AU.js → chunk-D6Q5EPOV.js} +2 -2
  112. package/dist/{chunk-GEJKYA7D.js → chunk-DSEHPUID.js} +6 -6
  113. package/dist/chunk-E4X2YX2F.js +22 -0
  114. package/dist/chunk-E4X2YX2F.js.map +1 -0
  115. package/dist/{chunk-PEBH5DCK.js → chunk-EH7BNIUN.js} +101 -19
  116. package/dist/chunk-EH7BNIUN.js.map +1 -0
  117. package/dist/{chunk-OAJMQKQR.js → chunk-EQRD4NMH.js} +2 -2
  118. package/dist/{chunk-H7VDIF2V.js → chunk-ER2UPUMG.js} +2 -2
  119. package/dist/{chunk-4FHRZD5T.js → chunk-F2JXJABQ.js} +2 -2
  120. package/dist/{chunk-FKKGCGYL.js → chunk-F4W5HTED.js} +2 -2
  121. package/dist/{chunk-DMEHOEC7.js → chunk-FFWONAAW.js} +3 -3
  122. package/dist/chunk-FYDW33ZB.js +13 -0
  123. package/dist/chunk-FYDW33ZB.js.map +1 -0
  124. package/dist/{chunk-TNGH4ZYI.js → chunk-GNWLTCKC.js} +2 -2
  125. package/dist/{chunk-CFVTRUR3.js → chunk-H6RSANGQ.js} +2 -2
  126. package/dist/chunk-HVAEXYPL.js +98 -0
  127. package/dist/chunk-HVAEXYPL.js.map +1 -0
  128. package/dist/{chunk-CTCGHNWN.js → chunk-J2R275FN.js} +4 -4
  129. package/dist/{chunk-IVIAHQBR.js → chunk-JJ6ZEFXC.js} +2 -2
  130. package/dist/{chunk-KXIXO76C.js → chunk-JMXHVJ2V.js} +14 -14
  131. package/dist/{chunk-7LCGFUMB.js → chunk-KQAFEZQX.js} +4 -4
  132. package/dist/{chunk-NACLNNFQ.js → chunk-KSZKQTZS.js} +2 -2
  133. package/dist/{chunk-NPIBN2VL.js → chunk-LK4TOYPU.js} +2 -2
  134. package/dist/{chunk-K66OY4EI.js → chunk-LSR5LQXN.js} +2 -2
  135. package/dist/chunk-MAG6M3B6.js +51 -0
  136. package/dist/chunk-MAG6M3B6.js.map +1 -0
  137. package/dist/{chunk-6CEGSTBD.js → chunk-NTFXBILO.js} +5 -5
  138. package/dist/{chunk-2PSX5BJU.js → chunk-NZPFCP5A.js} +2 -2
  139. package/dist/{chunk-FYWLSFFS.js → chunk-OERZXNSK.js} +2 -2
  140. package/dist/{chunk-ZJPM7GZ3.js → chunk-OIDICRH7.js} +2 -2
  141. package/dist/{chunk-LTBKKSCX.js → chunk-OLBZ2WGG.js} +2 -2
  142. package/dist/{chunk-PD66CVSD.js → chunk-OUKBMQ2O.js} +2 -2
  143. package/dist/{chunk-GPFZFCRN.js → chunk-PP7R754B.js} +1 -1
  144. package/dist/{chunk-GX6FTSYH.js → chunk-PRRUK2ZH.js} +2 -2
  145. package/dist/{chunk-MAH64N55.js → chunk-PW3GKWH3.js} +4 -4
  146. package/dist/chunk-Q3SHEAXR.js +80 -0
  147. package/dist/chunk-Q3SHEAXR.js.map +1 -0
  148. package/dist/{chunk-33MFRY25.js → chunk-R2Q6FTOX.js} +2 -2
  149. package/dist/{chunk-VCKWULAK.js → chunk-RCPKBW7K.js} +5 -5
  150. package/dist/{chunk-CN4VKV3S.js → chunk-RH3XLQG4.js} +2 -2
  151. package/dist/{chunk-2QSZNTDO.js → chunk-RKNJBZ55.js} +4 -4
  152. package/dist/{chunk-YXFCALVT.js → chunk-U4HZEW2B.js} +8 -8
  153. package/dist/{chunk-RZ3IZIJG.js → chunk-UHQE37NI.js} +2 -2
  154. package/dist/{chunk-Z3YEGSR4.js → chunk-UMZUKOJU.js} +4 -4
  155. package/dist/{chunk-72OIT7KS.js → chunk-UVYL5G7A.js} +3 -3
  156. package/dist/{chunk-4STAANV7.js → chunk-VKDBDJIX.js} +3 -3
  157. package/dist/{chunk-WKJFIMVN.js → chunk-VSMSYDIH.js} +2 -2
  158. package/dist/{chunk-GSKINLAK.js → chunk-W5IYHQA5.js} +3 -3
  159. package/dist/{chunk-FESUGFIL.js → chunk-WKWY7YF3.js} +2 -2
  160. package/dist/{chunk-UNUMFURP.js → chunk-X5PIDJ3L.js} +3 -3
  161. package/dist/{chunk-MINHJ55X.js → chunk-XXW32OL7.js} +1 -1
  162. package/dist/{chunk-MINHJ55X.js.map → chunk-XXW32OL7.js.map} +1 -1
  163. package/dist/{chunk-6RUHELWR.js → chunk-Y2YM4C75.js} +2 -2
  164. package/dist/{chunk-L4X4PJYK.js → chunk-YZ5VC2JJ.js} +2 -2
  165. package/dist/{chunk-VQ4AMTGZ.js → chunk-ZBIEX4XN.js} +1 -1
  166. package/dist/{chunk-O57GM3FR.js → chunk-ZMVW2HJJ.js} +2 -2
  167. package/dist/{chunk-6QDXA26G.js → chunk-ZXROBS53.js} +68 -68
  168. package/dist/{cli-BEkm2MEf.d.ts → cli-BOuEb4Ia.d.ts} +5 -5
  169. package/dist/cli.d.ts +13 -13
  170. package/dist/cli.js +76 -76
  171. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  172. package/dist/coding/export-okf-codegraph.js +10 -10
  173. package/dist/coding/pre-action-gate.d.ts +1 -1
  174. package/dist/coding/pre-action-gate.js +2 -2
  175. package/dist/compounding/engine.d.ts +2 -2
  176. package/dist/compounding/engine.js +10 -10
  177. package/dist/compounding/preference-consolidator.d.ts +1 -1
  178. package/dist/compression-optimizer.d.ts +1 -1
  179. package/dist/config.d.ts +1 -1
  180. package/dist/config.js +4 -4
  181. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  182. package/dist/connectors/codex-materialize-runner.js +10 -10
  183. package/dist/connectors/codex-materialize.d.ts +1 -1
  184. package/dist/connectors/index.d.ts +1 -1
  185. package/dist/connectors/index.js +10 -10
  186. package/dist/consolidation-provenance-check.d.ts +2 -2
  187. package/dist/consolidation-undo.d.ts +2 -2
  188. package/dist/contradiction/index.d.ts +3 -3
  189. package/dist/converge-config.d.ts +1 -1
  190. package/dist/convergence-refresh.d.ts +2 -2
  191. package/dist/convergence-refresh.js +12 -12
  192. package/dist/conversation-index/backend.d.ts +1 -1
  193. package/dist/conversation-index/chunker.d.ts +1 -1
  194. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  195. package/dist/conversation-index/indexer.d.ts +1 -1
  196. package/dist/conversation-index/search.d.ts +1 -1
  197. package/dist/corpus-watermark.d.ts +1 -1
  198. package/dist/corpus-watermark.js +12 -12
  199. package/dist/cross-lingual-recall.d.ts +1 -1
  200. package/dist/day-summary.d.ts +1 -1
  201. package/dist/delinearize.d.ts +1 -1
  202. package/dist/dependency-propagation-config.d.ts +1 -1
  203. package/dist/{dependency-propagation-delivery-BCpeo14F.d.ts → dependency-propagation-delivery-D4WMbOwA.d.ts} +1 -1
  204. package/dist/direct-answer-wiring.d.ts +1 -1
  205. package/dist/direct-answer.d.ts +1 -1
  206. package/dist/embedding-fallback.d.ts +1 -1
  207. package/dist/enrichment/index.d.ts +1 -1
  208. package/dist/entity-origin-fields.d.ts +1 -1
  209. package/dist/entity-retrieval.d.ts +2 -2
  210. package/dist/entity-retrieval.js +10 -10
  211. package/dist/entity-schema.d.ts +1 -1
  212. package/dist/episodic-context.d.ts +1 -1
  213. package/dist/eval-trajectory-contracts.d.ts +1 -1
  214. package/dist/eval-trajectory-store.d.ts +1 -1
  215. package/dist/eval-trajectory.d.ts +1 -1
  216. package/dist/explicit-capture.d.ts +9 -9
  217. package/dist/external-wiki-access.d.ts +11 -11
  218. package/dist/external-wiki-access.js +32 -32
  219. package/dist/external-wiki-collection-registration.d.ts +1 -1
  220. package/dist/external-wiki-collection.d.ts +1 -1
  221. package/dist/external-wiki-mcp-tools.d.ts +11 -11
  222. package/dist/extraction-error-classification.d.ts +1 -1
  223. package/dist/extraction-faithfulness.d.ts +1 -1
  224. package/dist/extraction-judge-telemetry.d.ts +1 -1
  225. package/dist/extraction-judge-training.d.ts +1 -1
  226. package/dist/extraction-judge.d.ts +1 -1
  227. package/dist/extraction-liveness.d.ts +1 -1
  228. package/dist/extraction-normalization.d.ts +1 -1
  229. package/dist/extraction-prompt.d.ts +1 -1
  230. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  231. package/dist/extraction-source-grounding.d.ts +1 -1
  232. package/dist/extraction-span-wire.d.ts +17 -0
  233. package/dist/extraction-span-wire.js +13 -0
  234. package/dist/extraction-span-wire.js.map +1 -0
  235. package/dist/extraction-span.d.ts +17 -0
  236. package/dist/extraction-span.js +8 -0
  237. package/dist/extraction.d.ts +1 -1
  238. package/dist/extraction.js +13 -13
  239. package/dist/fallback-llm.d.ts +1 -1
  240. package/dist/graph-dashboard-diff.d.ts +1 -1
  241. package/dist/graph-dashboard-key.d.ts +1 -1
  242. package/dist/graph-dashboard-parser.d.ts +1 -1
  243. package/dist/{graph-edge-decay-A4SDFMMS.js → graph-edge-decay-FXGELBFA.js} +4 -4
  244. package/dist/graph-edge-decay-FXGELBFA.js.map +1 -0
  245. package/dist/graph-edge-reinforcement.d.ts +1 -1
  246. package/dist/graph-path-reconstruction.d.ts +1 -1
  247. package/dist/graph-path-scoring.d.ts +1 -1
  248. package/dist/graph-snapshot.d.ts +1 -1
  249. package/dist/graph-snapshot.js +3 -3
  250. package/dist/graph.d.ts +1 -1
  251. package/dist/graph.js +3 -3
  252. package/dist/harmonic-retrieval.js +1 -1
  253. package/dist/importance.d.ts +1 -1
  254. package/dist/importers/index.d.ts +1 -1
  255. package/dist/in-flight-reads.d.ts +1 -1
  256. package/dist/{index-D_pyMUaP.d.ts → index-DuJnzwHv.d.ts} +2 -2
  257. package/dist/index.d.ts +341 -26
  258. package/dist/index.js +195 -114
  259. package/dist/intent.d.ts +1 -1
  260. package/dist/lcm/engine.d.ts +1 -1
  261. package/dist/lcm/engine.js +2 -2
  262. package/dist/lcm/index.d.ts +1 -1
  263. package/dist/lcm/index.js +7 -7
  264. package/dist/lcm/tools.d.ts +1 -1
  265. package/dist/lifecycle.d.ts +1 -1
  266. package/dist/live-connectors-runner.d.ts +1 -1
  267. package/dist/local-llm.d.ts +1 -1
  268. package/dist/local-model-endpoint.d.ts +1 -1
  269. package/dist/location/index.d.ts +3 -3
  270. package/dist/location/index.js +12 -12
  271. package/dist/maintenance/memory-governance.d.ts +1 -1
  272. package/dist/maintenance/memory-governance.js +10 -10
  273. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  274. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -10
  275. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  276. package/dist/maintenance/rebuild-memory-projection.js +11 -11
  277. package/dist/{maintenance-DDUX9d6D.d.ts → maintenance-BBeaeYRR.d.ts} +3 -3
  278. package/dist/mcp-memory-inspector-app.d.ts +11 -11
  279. package/dist/memory-action-policy.d.ts +1 -1
  280. package/dist/memory-cache.d.ts +1 -1
  281. package/dist/memory-controller.d.ts +1 -1
  282. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  283. package/dist/memory-projection-store.d.ts +1 -1
  284. package/dist/memory-provenance.d.ts +1 -1
  285. package/dist/memory-snapshot.d.ts +1 -1
  286. package/dist/memory-subject-cli.d.ts +11 -11
  287. package/dist/memory-subject.d.ts +11 -11
  288. package/dist/memory-worth-outcomes.d.ts +2 -2
  289. package/dist/models-json.d.ts +1 -1
  290. package/dist/namespaces/migrate.d.ts +3 -3
  291. package/dist/namespaces/migrate.js +11 -11
  292. package/dist/namespaces/principal.d.ts +1 -1
  293. package/dist/namespaces/search.d.ts +1 -1
  294. package/dist/namespaces/search.js +6 -6
  295. package/dist/namespaces/storage.d.ts +3 -3
  296. package/dist/namespaces/storage.js +10 -10
  297. package/dist/native-knowledge.d.ts +1 -1
  298. package/dist/offline-sync-impression-drain.d.ts +1 -1
  299. package/dist/operator-doctor-corpus.d.ts +1 -1
  300. package/dist/operator-doctor-corpus.js +13 -13
  301. package/dist/operator-doctor-replica.d.ts +1 -1
  302. package/dist/operator-toolkit.d.ts +3 -3
  303. package/dist/operator-toolkit.js +24 -24
  304. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  305. package/dist/orchestration/maintenance.d.ts +4 -4
  306. package/dist/orchestration/maintenance.js +19 -19
  307. package/dist/{orchestrator-3F4jihCo.d.ts → orchestrator-CaqnwNwM.d.ts} +8 -8
  308. package/dist/orchestrator.d.ts +9 -9
  309. package/dist/orchestrator.js +105 -101
  310. package/dist/patterns-cli.d.ts +1 -1
  311. package/dist/{pipeline-CB1dj6Uh.d.ts → pipeline-CrxVjlJr.d.ts} +1 -1
  312. package/dist/policy-runtime.d.ts +1 -1
  313. package/dist/proactive-contention.d.ts +1 -1
  314. package/dist/provenance.d.ts +1 -1
  315. package/dist/{public-http-34-JIAGQ.d.ts → public-http-CmQRjQCD.d.ts} +1 -1
  316. package/dist/{qmd-edLLZXc5.d.ts → qmd-BZgbJm0g.d.ts} +1 -1
  317. package/dist/qmd-preflight.d.ts +2 -2
  318. package/dist/qmd-recall-cache.d.ts +1 -1
  319. package/dist/qmd.d.ts +2 -2
  320. package/dist/qmd.js +4 -4
  321. package/dist/recall-concurrency-config.d.ts +1 -1
  322. package/dist/recall-deep-access.d.ts +30 -0
  323. package/dist/recall-deep-access.js +50 -0
  324. package/dist/recall-deep-access.js.map +1 -0
  325. package/dist/recall-deep-render.d.ts +11 -0
  326. package/dist/recall-deep-render.js +28 -0
  327. package/dist/recall-deep-render.js.map +1 -0
  328. package/dist/recall-deep.d.ts +37 -0
  329. package/dist/recall-deep.js +14 -0
  330. package/dist/recall-deep.js.map +1 -0
  331. package/dist/recall-disclosure-escalation.d.ts +1 -1
  332. package/dist/recall-explain-renderer.d.ts +1 -1
  333. package/dist/recall-explain-renderer.js +3 -3
  334. package/dist/recall-memory-map.d.ts +1 -1
  335. package/dist/recall-navigate.d.ts +70 -0
  336. package/dist/recall-navigate.js +15 -0
  337. package/dist/recall-navigate.js.map +1 -0
  338. package/dist/recall-planner-llm.d.ts +1 -1
  339. package/dist/recall-state-view-render.d.ts +18 -0
  340. package/dist/recall-state-view-render.js +22 -0
  341. package/dist/recall-state-view-render.js.map +1 -0
  342. package/dist/recall-state-view-widen.d.ts +13 -0
  343. package/dist/recall-state-view-widen.js +11 -0
  344. package/dist/recall-state-view-widen.js.map +1 -0
  345. package/dist/recall-state-view-wire.d.ts +13 -0
  346. package/dist/recall-state-view-wire.js +12 -0
  347. package/dist/recall-state-view-wire.js.map +1 -0
  348. package/dist/recall-state-view.d.ts +25 -0
  349. package/dist/recall-state-view.js +22 -0
  350. package/dist/recall-state-view.js.map +1 -0
  351. package/dist/recall-state.d.ts +1 -1
  352. package/dist/recall-tag-filter.d.ts +1 -1
  353. package/dist/recall-timings.d.ts +1 -1
  354. package/dist/recall-xray-cli.d.ts +1 -1
  355. package/dist/recall-xray-cli.js +4 -4
  356. package/dist/recall-xray-renderer.d.ts +1 -1
  357. package/dist/recall-xray-renderer.js +3 -3
  358. package/dist/recall-xray.d.ts +1 -1
  359. package/dist/recall-xray.js +2 -2
  360. package/dist/reconcile/cursor.d.ts +1 -1
  361. package/dist/reconcile/manifest.d.ts +1 -1
  362. package/dist/reconcile/plan.d.ts +1 -1
  363. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  364. package/dist/replay/normalizers/claude.d.ts +1 -1
  365. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  366. package/dist/replay/normalizers/shared.d.ts +1 -1
  367. package/dist/replay/runner.d.ts +1 -1
  368. package/dist/replay/types.d.ts +1 -1
  369. package/dist/replica-divergence.d.ts +1 -1
  370. package/dist/replica-peers-config.d.ts +1 -1
  371. package/dist/resolve-auth-token.d.ts +1 -1
  372. package/dist/resume-bundles.js +5 -5
  373. package/dist/retrieval-agents.d.ts +2 -2
  374. package/dist/retrieval-tiers.d.ts +1 -1
  375. package/dist/routing/engine.d.ts +1 -1
  376. package/dist/routing/store.d.ts +1 -1
  377. package/dist/salvage-envelope.d.ts +1 -1
  378. package/dist/schemas.d.ts +42 -42
  379. package/dist/{scope-profiles-BF2lu81V.d.ts → scope-profiles-DFaojvoP.d.ts} +1 -1
  380. package/dist/search/embed-helper.d.ts +1 -1
  381. package/dist/search/factory.d.ts +1 -1
  382. package/dist/search/factory.js +5 -5
  383. package/dist/search/index.d.ts +1 -1
  384. package/dist/search/index.js +9 -9
  385. package/dist/search/lancedb-backend.d.ts +1 -1
  386. package/dist/search/meilisearch-backend.d.ts +1 -1
  387. package/dist/search/noop-backend.d.ts +1 -1
  388. package/dist/search/orama-backend.d.ts +1 -1
  389. package/dist/search/port.d.ts +1 -1
  390. package/dist/search/remote-backend.d.ts +1 -1
  391. package/dist/{semantic-consolidation-5OuWXBRt.d.ts → semantic-consolidation-BiX68wZA.d.ts} +1 -1
  392. package/dist/semantic-consolidation.d.ts +2 -2
  393. package/dist/semantic-consolidation.js +11 -11
  394. package/dist/semantic-rule-promotion.js +10 -10
  395. package/dist/semantic-rule-verifier.d.ts +1 -1
  396. package/dist/semantic-rule-verifier.js +10 -10
  397. package/dist/{service-CrqEhLXD.d.ts → service-D5h2zZ0M.d.ts} +2 -2
  398. package/dist/session-observer-bands.d.ts +1 -1
  399. package/dist/session-observer-state.d.ts +1 -1
  400. package/dist/shared-context/manager.d.ts +1 -1
  401. package/dist/signal.d.ts +1 -1
  402. package/dist/source-agent-qualifier.d.ts +1 -1
  403. package/dist/source-agent-qualifier.js +12 -12
  404. package/dist/{storage-BQn-xnxm.d.ts → storage-CtsaojWD.d.ts} +1 -1
  405. package/dist/storage.d.ts +2 -2
  406. package/dist/storage.js +9 -9
  407. package/dist/subject-config.d.ts +1 -1
  408. package/dist/summarizer.d.ts +1 -1
  409. package/dist/summary-snapshot.d.ts +1 -1
  410. package/dist/support-passport/index.d.ts +14 -14
  411. package/dist/support-passport/index.js +34 -34
  412. package/dist/temporal-supersession.d.ts +2 -2
  413. package/dist/temporal-timeline-recall.d.ts +1 -1
  414. package/dist/temporal-validity.d.ts +1 -1
  415. package/dist/threading.d.ts +1 -1
  416. package/dist/tier-migration.d.ts +2 -2
  417. package/dist/tier-routing.d.ts +1 -1
  418. package/dist/topics.d.ts +1 -1
  419. package/dist/transcript.d.ts +1 -1
  420. package/dist/transfer/capsule-export.js +2 -2
  421. package/dist/transfer/capsule-import.js +2 -2
  422. package/dist/transfer/export-okf.d.ts +1 -1
  423. package/dist/transfer/export-okf.js +11 -11
  424. package/dist/transfer/types.d.ts +12 -12
  425. package/dist/trust-score-stage.d.ts +1 -1
  426. package/dist/trust-score.d.ts +1 -1
  427. package/dist/{types-BRpcNjHZ.d.ts → types-CIpfYz1I.d.ts} +16 -11
  428. package/dist/types.d.ts +1 -1
  429. package/dist/types.js +1 -1
  430. package/dist/utility-runtime.d.ts +1 -1
  431. package/dist/verified-recall.js +10 -10
  432. package/dist/who-knows-cli.d.ts +11 -11
  433. package/dist/who-knows-cli.js +11 -11
  434. package/dist/who-knows.d.ts +11 -11
  435. package/dist/who-knows.js +10 -10
  436. package/dist/write-envelope.d.ts +1 -1
  437. package/package.json +2 -2
  438. package/src/activity/config.test.ts +1 -1
  439. package/src/activity/config.ts +48 -3
  440. package/src/activity/index.ts +5 -0
  441. package/src/activity/journal-vault-read.test.ts +153 -0
  442. package/src/activity/journal-vault-read.ts +214 -0
  443. package/src/activity/journal.test.ts +97 -0
  444. package/src/activity/journal.ts +113 -0
  445. package/src/activity/privacy.test.ts +53 -0
  446. package/src/activity/privacy.ts +80 -0
  447. package/src/activity/timeline/analysis-batch.test.ts +56 -0
  448. package/src/activity/timeline/analysis-batch.ts +45 -0
  449. package/src/activity/timeline/analysis.test.ts +413 -0
  450. package/src/activity/timeline/analysis.ts +362 -0
  451. package/src/activity/timeline/index.ts +7 -0
  452. package/src/activity/timeline/journal-recap-persist.test.ts +148 -0
  453. package/src/activity/timeline/journal-recap-persist.ts +37 -0
  454. package/src/activity/timeline/journal-recap.test.ts +113 -0
  455. package/src/activity/timeline/journal-recap.ts +130 -0
  456. package/src/activity/timeline/query.test.ts +198 -0
  457. package/src/activity/timeline/query.ts +313 -0
  458. package/src/activity/timeline/weekly-persist.test.ts +121 -0
  459. package/src/activity/timeline/weekly-persist.ts +103 -0
  460. package/src/activity/timeline/weekly.test.ts +215 -0
  461. package/src/activity/timeline/weekly.ts +234 -0
  462. package/src/activity/types.ts +14 -0
  463. package/src/activity/vault-path.test.ts +38 -0
  464. package/src/activity/vault-path.ts +59 -0
  465. package/src/activity/vault-publish.test.ts +268 -0
  466. package/src/activity/vault-publish.ts +180 -0
  467. package/src/config.test.ts +1 -1
  468. package/src/config.ts +2 -22
  469. package/src/dedup/merge-on-write-wire.test.ts +101 -0
  470. package/src/dedup/merge-on-write-wire.ts +34 -0
  471. package/src/dedup/merge-on-write.test.ts +91 -0
  472. package/src/dedup/merge-on-write.ts +75 -0
  473. package/src/dedup/novelty-gate.test.ts +143 -0
  474. package/src/dedup/novelty-gate.ts +163 -0
  475. package/src/extraction-span-wire.test.ts +20 -0
  476. package/src/extraction-span-wire.ts +17 -0
  477. package/src/extraction-span.test.ts +59 -0
  478. package/src/extraction-span.ts +39 -0
  479. package/src/index.ts +1 -0
  480. package/src/location/recall-exclusion.test.ts +1 -0
  481. package/src/orchestration/extraction-persist.ts +22 -23
  482. package/src/orchestration/generic-recall-paths.ts +11 -0
  483. package/src/orchestration/recall-entry.ts +8 -3
  484. package/src/recall-deep-access.test.ts +58 -0
  485. package/src/recall-deep-access.ts +71 -0
  486. package/src/recall-deep-render.test.ts +68 -0
  487. package/src/recall-deep-render.ts +32 -0
  488. package/src/recall-deep.test.ts +72 -0
  489. package/src/recall-deep.ts +113 -0
  490. package/src/recall-navigate.test.ts +84 -0
  491. package/src/recall-navigate.ts +100 -0
  492. package/src/recall-state-view-render.test.ts +94 -0
  493. package/src/recall-state-view-render.ts +24 -0
  494. package/src/recall-state-view-widen.test.ts +66 -0
  495. package/src/recall-state-view-widen.ts +49 -0
  496. package/src/recall-state-view-wire.test.ts +35 -0
  497. package/src/recall-state-view-wire.ts +18 -0
  498. package/src/recall-state-view.test.ts +131 -0
  499. package/src/recall-state-view.ts +138 -0
  500. package/src/shared-context/governance.test.ts +53 -0
  501. package/src/shared-context/governance.ts +86 -0
  502. package/src/shared-context/staleness.test.ts +36 -0
  503. package/src/shared-context/staleness.ts +38 -0
  504. package/src/shared-context/trajectories.test.ts +77 -0
  505. package/src/shared-context/trajectories.ts +49 -0
  506. package/src/types.ts +3 -10
  507. package/dist/chunk-56IV4J5W.js.map +0 -1
  508. package/dist/chunk-IHGMRDEE.js.map +0 -1
  509. package/dist/chunk-KODXCHXJ.js.map +0 -1
  510. package/dist/chunk-PEBH5DCK.js.map +0 -1
  511. /package/dist/{chunk-EZSCW4EM.js.map → chunk-25OLNWYG.js.map} +0 -0
  512. /package/dist/{chunk-2LBAFHOQ.js.map → chunk-2QSGJTDG.js.map} +0 -0
  513. /package/dist/{chunk-7UTDHQZ5.js.map → chunk-2VZHB5US.js.map} +0 -0
  514. /package/dist/{chunk-VQNRICAQ.js.map → chunk-36HJ36FK.js.map} +0 -0
  515. /package/dist/{chunk-XKNHFDTT.js.map → chunk-3A2Z4OOS.js.map} +0 -0
  516. /package/dist/{chunk-RDGKVH6T.js.map → chunk-4NKIGSJM.js.map} +0 -0
  517. /package/dist/{chunk-EFQCDJZ2.js.map → chunk-4PG2CKI6.js.map} +0 -0
  518. /package/dist/{chunk-HJXA6ZM7.js.map → chunk-6545JDIM.js.map} +0 -0
  519. /package/dist/{chunk-J3OND5QT.js.map → chunk-65HXVEVG.js.map} +0 -0
  520. /package/dist/{chunk-HNPE66LB.js.map → chunk-6BYJQ3L2.js.map} +0 -0
  521. /package/dist/{chunk-ZW4VXELZ.js.map → chunk-6PUF7LUO.js.map} +0 -0
  522. /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
  523. /package/dist/{chunk-MN5NOOI7.js.map → chunk-AI5M4FVQ.js.map} +0 -0
  524. /package/dist/{chunk-YMOPYG3K.js.map → chunk-BIJAWZYW.js.map} +0 -0
  525. /package/dist/{chunk-I5VB44ZK.js.map → chunk-BLHKR4GJ.js.map} +0 -0
  526. /package/dist/{chunk-CEH2AFXG.js.map → chunk-C24UZSFW.js.map} +0 -0
  527. /package/dist/{chunk-MJRGVXPQ.js.map → chunk-C3ZYZKDJ.js.map} +0 -0
  528. /package/dist/{chunk-QCRJMU5V.js.map → chunk-CDLPF3PX.js.map} +0 -0
  529. /package/dist/{chunk-23CVL7HS.js.map → chunk-CQ6IWZDI.js.map} +0 -0
  530. /package/dist/{chunk-KWIGDKM2.js.map → chunk-D2YNNDML.js.map} +0 -0
  531. /package/dist/{chunk-FTTJRVB7.js.map → chunk-D3DUA64S.js.map} +0 -0
  532. /package/dist/{chunk-7XOG75AU.js.map → chunk-D6Q5EPOV.js.map} +0 -0
  533. /package/dist/{chunk-GEJKYA7D.js.map → chunk-DSEHPUID.js.map} +0 -0
  534. /package/dist/{chunk-OAJMQKQR.js.map → chunk-EQRD4NMH.js.map} +0 -0
  535. /package/dist/{chunk-H7VDIF2V.js.map → chunk-ER2UPUMG.js.map} +0 -0
  536. /package/dist/{chunk-4FHRZD5T.js.map → chunk-F2JXJABQ.js.map} +0 -0
  537. /package/dist/{chunk-FKKGCGYL.js.map → chunk-F4W5HTED.js.map} +0 -0
  538. /package/dist/{chunk-DMEHOEC7.js.map → chunk-FFWONAAW.js.map} +0 -0
  539. /package/dist/{chunk-TNGH4ZYI.js.map → chunk-GNWLTCKC.js.map} +0 -0
  540. /package/dist/{chunk-CFVTRUR3.js.map → chunk-H6RSANGQ.js.map} +0 -0
  541. /package/dist/{chunk-CTCGHNWN.js.map → chunk-J2R275FN.js.map} +0 -0
  542. /package/dist/{chunk-IVIAHQBR.js.map → chunk-JJ6ZEFXC.js.map} +0 -0
  543. /package/dist/{chunk-KXIXO76C.js.map → chunk-JMXHVJ2V.js.map} +0 -0
  544. /package/dist/{chunk-7LCGFUMB.js.map → chunk-KQAFEZQX.js.map} +0 -0
  545. /package/dist/{chunk-NACLNNFQ.js.map → chunk-KSZKQTZS.js.map} +0 -0
  546. /package/dist/{chunk-NPIBN2VL.js.map → chunk-LK4TOYPU.js.map} +0 -0
  547. /package/dist/{chunk-K66OY4EI.js.map → chunk-LSR5LQXN.js.map} +0 -0
  548. /package/dist/{chunk-6CEGSTBD.js.map → chunk-NTFXBILO.js.map} +0 -0
  549. /package/dist/{chunk-2PSX5BJU.js.map → chunk-NZPFCP5A.js.map} +0 -0
  550. /package/dist/{chunk-FYWLSFFS.js.map → chunk-OERZXNSK.js.map} +0 -0
  551. /package/dist/{chunk-ZJPM7GZ3.js.map → chunk-OIDICRH7.js.map} +0 -0
  552. /package/dist/{chunk-LTBKKSCX.js.map → chunk-OLBZ2WGG.js.map} +0 -0
  553. /package/dist/{chunk-PD66CVSD.js.map → chunk-OUKBMQ2O.js.map} +0 -0
  554. /package/dist/{chunk-GPFZFCRN.js.map → chunk-PP7R754B.js.map} +0 -0
  555. /package/dist/{chunk-GX6FTSYH.js.map → chunk-PRRUK2ZH.js.map} +0 -0
  556. /package/dist/{chunk-MAH64N55.js.map → chunk-PW3GKWH3.js.map} +0 -0
  557. /package/dist/{chunk-33MFRY25.js.map → chunk-R2Q6FTOX.js.map} +0 -0
  558. /package/dist/{chunk-VCKWULAK.js.map → chunk-RCPKBW7K.js.map} +0 -0
  559. /package/dist/{chunk-CN4VKV3S.js.map → chunk-RH3XLQG4.js.map} +0 -0
  560. /package/dist/{chunk-2QSZNTDO.js.map → chunk-RKNJBZ55.js.map} +0 -0
  561. /package/dist/{chunk-YXFCALVT.js.map → chunk-U4HZEW2B.js.map} +0 -0
  562. /package/dist/{chunk-RZ3IZIJG.js.map → chunk-UHQE37NI.js.map} +0 -0
  563. /package/dist/{chunk-Z3YEGSR4.js.map → chunk-UMZUKOJU.js.map} +0 -0
  564. /package/dist/{chunk-72OIT7KS.js.map → chunk-UVYL5G7A.js.map} +0 -0
  565. /package/dist/{chunk-4STAANV7.js.map → chunk-VKDBDJIX.js.map} +0 -0
  566. /package/dist/{chunk-WKJFIMVN.js.map → chunk-VSMSYDIH.js.map} +0 -0
  567. /package/dist/{chunk-GSKINLAK.js.map → chunk-W5IYHQA5.js.map} +0 -0
  568. /package/dist/{chunk-FESUGFIL.js.map → chunk-WKWY7YF3.js.map} +0 -0
  569. /package/dist/{chunk-UNUMFURP.js.map → chunk-X5PIDJ3L.js.map} +0 -0
  570. /package/dist/{chunk-6RUHELWR.js.map → chunk-Y2YM4C75.js.map} +0 -0
  571. /package/dist/{chunk-L4X4PJYK.js.map → chunk-YZ5VC2JJ.js.map} +0 -0
  572. /package/dist/{chunk-VQ4AMTGZ.js.map → chunk-ZBIEX4XN.js.map} +0 -0
  573. /package/dist/{chunk-O57GM3FR.js.map → chunk-ZMVW2HJJ.js.map} +0 -0
  574. /package/dist/{chunk-6QDXA26G.js.map → chunk-ZXROBS53.js.map} +0 -0
  575. /package/dist/{graph-edge-decay-A4SDFMMS.js.map → extraction-span.js.map} +0 -0
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Deterministic daily journal recap from timeline cards (issue #2051).
3
+ *
4
+ * Pure: cards + date + timezone in, Markdown out. No LLM, no I/O.
5
+ * Same cards always produce the same bytes. Empty days still yield a
6
+ * valid file body. Does not invent people, mood, or productivity claims.
7
+ */
8
+ import { activityDayWindow } from "../digest.js";
9
+ import type { TimelineCard } from "./types.js";
10
+
11
+ export interface DeterministicJournalOptions {
12
+ date: string;
13
+ timezone: string;
14
+ }
15
+
16
+ interface ClippedCard {
17
+ card: TimelineCard;
18
+ startMs: number;
19
+ endMs: number;
20
+ durationMs: number;
21
+ }
22
+
23
+ function formatMinutes(ms: number): string {
24
+ return `${Math.round(ms / 60_000)}m`;
25
+ }
26
+
27
+ function clipToWindow(
28
+ cards: readonly TimelineCard[],
29
+ winStart: number,
30
+ winEnd: number,
31
+ ): ClippedCard[] {
32
+ const clipped: ClippedCard[] = [];
33
+ for (const card of cards) {
34
+ const start = Date.parse(card.startUtc);
35
+ const end = Date.parse(card.endUtc);
36
+ if (!Number.isFinite(start) || !Number.isFinite(end)) continue;
37
+ const startMs = Math.max(start, winStart);
38
+ const endMs = Math.min(end, winEnd);
39
+ if (endMs <= startMs) continue;
40
+ clipped.push({ card, startMs, endMs, durationMs: endMs - startMs });
41
+ }
42
+ clipped.sort((left, right) => {
43
+ const byStart = left.startMs - right.startMs;
44
+ if (byStart !== 0) return byStart;
45
+ const byTitle = left.card.title.localeCompare(right.card.title);
46
+ if (byTitle !== 0) return byTitle;
47
+ return left.card.id.localeCompare(right.card.id);
48
+ });
49
+ return clipped;
50
+ }
51
+
52
+ function categoryLines(clipped: readonly ClippedCard[]): string[] {
53
+ const totals = new Map<string, number>();
54
+ for (const row of clipped) {
55
+ totals.set(row.card.categoryId, (totals.get(row.card.categoryId) ?? 0) + row.durationMs);
56
+ }
57
+ const rows = [...totals.entries()].sort((left, right) => {
58
+ const byDuration = right[1] - left[1];
59
+ return byDuration !== 0 ? byDuration : left[0].localeCompare(right[0]);
60
+ });
61
+ if (rows.length === 0) return ["_No categories._"];
62
+ return rows.map(([categoryId, durationMs]) => `- ${formatMinutes(durationMs)} ${categoryId}`);
63
+ }
64
+
65
+ function mergeIntervals(intervals: readonly (readonly [number, number])[]): Array<[number, number]> {
66
+ const ordered = [...intervals].sort((left, right) => left[0] - right[0] || left[1] - right[1]);
67
+ const merged: Array<[number, number]> = [];
68
+ for (const [start, end] of ordered) {
69
+ const last = merged[merged.length - 1];
70
+ if (!last || start > last[1]) merged.push([start, end]);
71
+ else last[1] = Math.max(last[1], end);
72
+ }
73
+ return merged;
74
+ }
75
+
76
+ function countGaps(
77
+ winStart: number,
78
+ winEnd: number,
79
+ intervals: readonly (readonly [number, number])[],
80
+ ): number {
81
+ const merged = mergeIntervals(intervals);
82
+ let gaps = 0;
83
+ let cursor = winStart;
84
+ for (const [start, end] of merged) {
85
+ if (start > cursor) gaps += 1;
86
+ cursor = Math.max(cursor, end);
87
+ }
88
+ if (cursor < winEnd) gaps += 1;
89
+ return gaps;
90
+ }
91
+
92
+ /** Render a byte-stable Markdown journal for one local day. */
93
+ export function renderDeterministicJournal(
94
+ cards: readonly TimelineCard[],
95
+ options: DeterministicJournalOptions,
96
+ ): string {
97
+ const window = activityDayWindow(options.date, options.timezone);
98
+ const winStart = Date.parse(window.startUtc);
99
+ const winEnd = Date.parse(window.endUtc);
100
+ const clipped = clipToWindow(cards, winStart, winEnd);
101
+ const idle = clipped.filter((row) => row.card.kind === "idle").length;
102
+ const pause = clipped.filter((row) => row.card.kind === "pause").length;
103
+ const gaps = countGaps(
104
+ winStart,
105
+ winEnd,
106
+ clipped.map((row) => [row.startMs, row.endMs]),
107
+ );
108
+ const cardLines =
109
+ clipped.length === 0
110
+ ? ["_No cards._"]
111
+ : clipped.map((row) => `- ${formatMinutes(row.durationMs)} ${row.card.title}`);
112
+ return [
113
+ `# Journal — ${options.date} (${options.timezone})`,
114
+ "",
115
+ "## Categories",
116
+ "",
117
+ ...categoryLines(clipped),
118
+ "",
119
+ "## Cards",
120
+ "",
121
+ ...cardLines,
122
+ "",
123
+ "## Gaps / idle / pause",
124
+ "",
125
+ `- Gaps: ${gaps}`,
126
+ `- Idle: ${idle}`,
127
+ `- Pause: ${pause}`,
128
+ "",
129
+ ].join("\n");
130
+ }
@@ -0,0 +1,198 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseActivityConfig } from "../config.js";
5
+ import {
6
+ queryTimelineRange,
7
+ queryTimelineSearch,
8
+ runTimelineCliCommand,
9
+ type TimelineQueryCard,
10
+ } from "./query.js";
11
+ import type { TimelineCard } from "./types.js";
12
+
13
+ function card(overrides: Partial<TimelineQueryCard> & Pick<TimelineCard, "id" | "startUtc" | "endUtc">): TimelineQueryCard {
14
+ return {
15
+ kind: "activity",
16
+ title: "Untitled",
17
+ summary: "none",
18
+ categoryId: "development",
19
+ confidence: 1,
20
+ dayKey: overrides.startUtc.slice(0, 10),
21
+ timezone: "UTC",
22
+ machine: "ws-a",
23
+ evidenceIds: [],
24
+ evidenceRange: null,
25
+ ...overrides,
26
+ };
27
+ }
28
+
29
+ const BOUNDARY_A = card({
30
+ id: "a",
31
+ title: "Morning editor",
32
+ summary: "typed in vscode",
33
+ startUtc: "2026-07-10T10:00:00.000Z",
34
+ endUtc: "2026-07-10T11:00:00.000Z",
35
+ });
36
+ const BOUNDARY_B = card({
37
+ id: "b",
38
+ title: "Standup call",
39
+ summary: "zoom standup",
40
+ categoryId: "communication",
41
+ startUtc: "2026-07-10T11:00:00.000Z",
42
+ endUtc: "2026-07-10T12:00:00.000Z",
43
+ });
44
+ const LATER = card({
45
+ id: "c",
46
+ title: "Docs writeup",
47
+ summary: "edited the standup notes",
48
+ detailedSummary: "longer writeup about the morning editor session",
49
+ startUtc: "2026-07-11T09:00:00.000Z",
50
+ endUtc: "2026-07-11T10:00:00.000Z",
51
+ });
52
+ const DISTRACTION = card({
53
+ id: "d",
54
+ title: "Video break",
55
+ summary: "watched a clip",
56
+ categoryId: "entertainment",
57
+ distraction: true,
58
+ startUtc: "2026-07-10T12:00:00.000Z",
59
+ endUtc: "2026-07-10T12:30:00.000Z",
60
+ });
61
+
62
+ const CARDS = [BOUNDARY_A, BOUNDARY_B, LATER, DISTRACTION];
63
+
64
+ test("range at a boundary instant returns only the containing card", () => {
65
+ const instant = "2026-07-10T11:00:00.000Z";
66
+ const result = queryTimelineRange(CARDS, { from: instant, to: instant, format: "cards" });
67
+ assert.ok(Array.isArray(result));
68
+ assert.deepEqual(
69
+ result.map((item) => item.id),
70
+ ["b"],
71
+ );
72
+ });
73
+
74
+ test("range rejects a reversed window and names the limit", () => {
75
+ assert.throws(
76
+ () =>
77
+ queryTimelineRange(CARDS, {
78
+ from: "2026-07-11T00:00:00.000Z",
79
+ to: "2026-07-10T00:00:00.000Z",
80
+ format: "cards",
81
+ }),
82
+ /reversed range/,
83
+ );
84
+ });
85
+
86
+ test("range rejects a 400-day window and names maxRangeDays", () => {
87
+ assert.throws(
88
+ () =>
89
+ queryTimelineRange(CARDS, {
90
+ from: "2026-01-01T00:00:00.000Z",
91
+ to: "2027-02-05T00:00:00.000Z",
92
+ format: "cards",
93
+ }),
94
+ /maxRangeDays \(31\)/,
95
+ );
96
+ });
97
+
98
+ test("range format cards and compact both round-trip the fixture", () => {
99
+ const from = "2026-07-10T10:00:00.000Z";
100
+ const to = "2026-07-10T12:00:00.000Z";
101
+ const full = queryTimelineRange(CARDS, { from, to, format: "cards", includeDistractions: true });
102
+ assert.ok(Array.isArray(full));
103
+ assert.deepEqual(
104
+ full.map((item) => item.id),
105
+ ["a", "b"],
106
+ );
107
+ const compact = queryTimelineRange(CARDS, { from, to, format: "compact", includeDistractions: true });
108
+ assert.ok(!Array.isArray(compact));
109
+ assert.equal(compact.day, "2026-07-10");
110
+ assert.deepEqual(compact.cards, [
111
+ { start: BOUNDARY_A.startUtc, end: BOUNDARY_A.endUtc, category: "development", title: "Morning editor", summary: "typed in vscode" },
112
+ { start: BOUNDARY_B.startUtc, end: BOUNDARY_B.endUtc, category: "communication", title: "Standup call", summary: "zoom standup" },
113
+ ]);
114
+ });
115
+
116
+ test("range rejects an unknown format against the allow-list", () => {
117
+ assert.throws(
118
+ () =>
119
+ queryTimelineRange(CARDS, {
120
+ from: "2026-07-10T10:00:00.000Z",
121
+ to: "2026-07-10T11:00:00.000Z",
122
+ format: "markdown" as "cards",
123
+ }),
124
+ /format must be one of: cards, compact/,
125
+ );
126
+ });
127
+
128
+ test("search empty results stay ok and unreadable store is distinct", () => {
129
+ assert.deepEqual(queryTimelineSearch(CARDS, { query: "no-such-token" }), { ok: true, results: [] });
130
+ assert.deepEqual(queryTimelineSearch(null, { query: "editor" }), { ok: false, error: "store_unreadable" });
131
+ assert.deepEqual(queryTimelineSearch(undefined, { query: "editor" }), { ok: false, error: "store_unreadable" });
132
+ });
133
+
134
+ test("search rank is match count then recency then id", () => {
135
+ const shuffled = [LATER, DISTRACTION, BOUNDARY_B, BOUNDARY_A];
136
+ const found = queryTimelineSearch(shuffled, { query: "standup editor" });
137
+ assert.equal(found.ok, true);
138
+ if (!found.ok) return;
139
+ assert.deepEqual(
140
+ found.results.map((item) => item.id),
141
+ ["c", "b", "a"],
142
+ );
143
+ });
144
+
145
+ test("search honors detailedSummary and a 1..50 limit", () => {
146
+ const found = queryTimelineSearch(CARDS, { query: "writeup", limit: 1 });
147
+ assert.equal(found.ok, true);
148
+ if (!found.ok) return;
149
+ assert.deepEqual(
150
+ found.results.map((item) => item.id),
151
+ ["c"],
152
+ );
153
+ assert.throws(() => queryTimelineSearch(CARDS, { query: "editor", limit: 0 }), /limit must be an integer from 1 to 50/);
154
+ assert.throws(() => queryTimelineSearch(CARDS, { query: "editor", limit: 51 }), /limit must be an integer from 1 to 50/);
155
+ });
156
+
157
+ test("timeline.qa defaults off and honors 0-style disable plus maxRangeDays bounds", () => {
158
+ const defaults = parseActivityConfig(undefined).timeline.qa;
159
+ assert.deepEqual(defaults, { enabled: false, maxRangeDays: 31 });
160
+ assert.equal(parseActivityConfig({ timeline: { qa: { enabled: 0 } } }).timeline.qa.enabled, false);
161
+ assert.equal(parseActivityConfig({ timeline: { qa: { enabled: "off" } } }).timeline.qa.enabled, false);
162
+ assert.equal(parseActivityConfig({ timeline: { qa: { enabled: true, maxRangeDays: 1 } } }).timeline.qa.maxRangeDays, 1);
163
+ assert.throws(
164
+ () => parseActivityConfig({ timeline: { qa: { maxRangeDays: 0 } } }),
165
+ /maxRangeDays must be an integer from 1 to 366/,
166
+ );
167
+ assert.throws(
168
+ () => parseActivityConfig({ timeline: { qa: { maxRangeDays: 367 } } }),
169
+ /maxRangeDays must be an integer from 1 to 366/,
170
+ );
171
+ });
172
+
173
+ test("CLI runner accepts in-memory cards and does not need a store", async () => {
174
+ const qa = { enabled: true, maxRangeDays: 31 };
175
+ let out = "";
176
+ let err = "";
177
+ const io = {
178
+ stdout: { write: (chunk: string) => (out += chunk) },
179
+ stderr: { write: (chunk: string) => (err += chunk) },
180
+ };
181
+ const rangeCode = await runTimelineCliCommand(
182
+ { cards: CARDS, qa, timelineEnabled: true },
183
+ ["range", "--from", "2026-07-10T11:00:00.000Z", "--to", "2026-07-10T11:00:00.000Z", "--format", "cards"],
184
+ io,
185
+ );
186
+ assert.equal(rangeCode, 0);
187
+ assert.deepEqual(JSON.parse(out).map((item: TimelineCard) => item.id), ["b"]);
188
+
189
+ out = "";
190
+ const unread = await runTimelineCliCommand(
191
+ { cards: null, qa, timelineEnabled: true },
192
+ ["search", "--query", "editor"],
193
+ io,
194
+ );
195
+ assert.equal(unread, 1);
196
+ assert.deepEqual(JSON.parse(out), { ok: false, error: "store_unreadable" });
197
+ assert.equal(err, "");
198
+ });
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Timeline range/search query (issue #1983 PR1).
3
+ *
4
+ * Pure functions over an in-memory card list. Half-open UTC [from, to).
5
+ * A zero-length range is an instant: include the card whose [start, end)
6
+ * contains it. Search returns distinct empty vs store_unreadable shapes.
7
+ *
8
+ * Config: activity.timeline.qa.{enabled, maxRangeDays}.
9
+ * MCP/HTTP and recall injection are later PRs.
10
+ */
11
+ import { parseFlexibleIsoTimestamp } from "../../utils/iso-timestamp.js";
12
+ import type { ActivityTimelineQaConfig } from "../types.js";
13
+ import type { TimelineCard } from "./types.js";
14
+
15
+ const RANGE_FORMATS = ["cards", "compact"] as const;
16
+ const MS_PER_DAY = 86_400_000;
17
+ const DEFAULT_MAX_RANGE_DAYS = 31;
18
+ const DEFAULT_SEARCH_LIMIT = 10;
19
+ const MIN_SEARCH_LIMIT = 1;
20
+ const MAX_SEARCH_LIMIT = 50;
21
+
22
+ export type TimelineRangeFormat = (typeof RANGE_FORMATS)[number];
23
+
24
+ /** Card fields the query layer reads; later slices may add optional extras. */
25
+ export type TimelineQueryCard = TimelineCard & {
26
+ detailedSummary?: string;
27
+ distraction?: boolean;
28
+ };
29
+
30
+ export interface TimelineRangeQuery {
31
+ from: string;
32
+ to: string;
33
+ categories?: readonly string[];
34
+ includeDistractions?: boolean;
35
+ format: TimelineRangeFormat;
36
+ maxRangeDays?: number;
37
+ }
38
+
39
+ export interface TimelineCompactCard {
40
+ start: string;
41
+ end: string;
42
+ category: string;
43
+ title: string;
44
+ summary: string;
45
+ }
46
+
47
+ export interface TimelineCompactRange {
48
+ day: string;
49
+ cards: TimelineCompactCard[];
50
+ }
51
+
52
+ export interface TimelineSearchQuery {
53
+ query: string;
54
+ from?: string;
55
+ to?: string;
56
+ limit?: number;
57
+ }
58
+
59
+ export type TimelineSearchResult =
60
+ | { ok: true; results: TimelineQueryCard[] }
61
+ | { ok: false; error: "store_unreadable" };
62
+
63
+ export interface TimelineCliIo {
64
+ stdout: { write(chunk: string): unknown };
65
+ stderr: { write(chunk: string): unknown };
66
+ }
67
+
68
+ /** Inject cards so CLI tests never need ActivityStore. */
69
+ export interface TimelineCliDeps {
70
+ cards: readonly TimelineQueryCard[] | null;
71
+ qa: ActivityTimelineQaConfig;
72
+ timelineEnabled?: boolean;
73
+ }
74
+
75
+ const USAGE = `Usage: timeline <command> [options]
76
+
77
+ Commands:
78
+ range --from <ISO> --to <ISO> [--format cards|compact] [--categories id,id] [--include-distractions]
79
+ search --query <text> [--from <ISO>] [--to <ISO>] [--limit N]
80
+ `;
81
+
82
+ const VALUE_FLAGS: Record<string, true> = {
83
+ "--from": true,
84
+ "--to": true,
85
+ "--format": true,
86
+ "--categories": true,
87
+ "--query": true,
88
+ "--limit": true,
89
+ };
90
+ const BOOLEAN_FLAGS: Record<string, true> = { "--include-distractions": true };
91
+
92
+ function parseInstant(value: string, label: string): number {
93
+ const ms = parseFlexibleIsoTimestamp(value);
94
+ if (ms === null) {
95
+ throw new TypeError(`${label} must be an ISO date or datetime`);
96
+ }
97
+ return ms;
98
+ }
99
+
100
+ function assertRange(fromMs: number, toMs: number, maxRangeDays: number): void {
101
+ if (fromMs > toMs) {
102
+ throw new RangeError("reversed range: from must be <= to");
103
+ }
104
+ if (fromMs === toMs) return;
105
+ if (toMs - fromMs > maxRangeDays * MS_PER_DAY) {
106
+ throw new RangeError(`range exceeds timeline.qa.maxRangeDays (${maxRangeDays})`);
107
+ }
108
+ }
109
+
110
+ function cardOverlaps(card: TimelineQueryCard, fromMs: number, toMs: number): boolean {
111
+ const start = Date.parse(card.startUtc);
112
+ const end = Date.parse(card.endUtc);
113
+ if (fromMs === toMs) return start <= fromMs && fromMs < end;
114
+ return start < toMs && end > fromMs;
115
+ }
116
+
117
+ function passesFilters(
118
+ card: TimelineQueryCard,
119
+ categories: ReadonlySet<string> | undefined,
120
+ includeDistractions: boolean,
121
+ ): boolean {
122
+ if (!includeDistractions && card.distraction === true) return false;
123
+ if (categories && !categories.has(card.categoryId)) return false;
124
+ return true;
125
+ }
126
+
127
+ function filterRange(
128
+ cards: readonly TimelineQueryCard[],
129
+ fromMs: number,
130
+ toMs: number,
131
+ categories: ReadonlySet<string> | undefined,
132
+ includeDistractions: boolean,
133
+ ): TimelineQueryCard[] {
134
+ return cards.filter(
135
+ (card) => cardOverlaps(card, fromMs, toMs) && passesFilters(card, categories, includeDistractions),
136
+ );
137
+ }
138
+
139
+ function toCompact(cards: readonly TimelineQueryCard[], from: string): TimelineCompactRange {
140
+ const day = from.length >= 10 ? from.slice(0, 10) : cards[0]?.dayKey ?? from;
141
+ return {
142
+ day,
143
+ cards: cards.map((card) => ({
144
+ start: card.startUtc,
145
+ end: card.endUtc,
146
+ category: card.categoryId,
147
+ title: card.title,
148
+ summary: card.summary,
149
+ })),
150
+ };
151
+ }
152
+
153
+ export function queryTimelineRange(
154
+ cards: readonly TimelineQueryCard[],
155
+ query: TimelineRangeQuery,
156
+ ): TimelineCard[] | TimelineCompactRange {
157
+ if (!RANGE_FORMATS.includes(query.format)) {
158
+ throw new TypeError(`format must be one of: ${RANGE_FORMATS.join(", ")}`);
159
+ }
160
+ const maxRangeDays = query.maxRangeDays ?? DEFAULT_MAX_RANGE_DAYS;
161
+ const fromMs = parseInstant(query.from, "from");
162
+ const toMs = parseInstant(query.to, "to");
163
+ assertRange(fromMs, toMs, maxRangeDays);
164
+ const categories = query.categories ? new Set(query.categories) : undefined;
165
+ const matched = filterRange(cards, fromMs, toMs, categories, query.includeDistractions === true);
166
+ if (query.format === "compact") return toCompact(matched, query.from);
167
+ return matched;
168
+ }
169
+
170
+ function haystack(card: TimelineQueryCard): string {
171
+ const parts = [card.title, card.summary];
172
+ if (card.detailedSummary) parts.push(card.detailedSummary);
173
+ return parts.join(" ").toLowerCase();
174
+ }
175
+
176
+ function tokenMatchCount(card: TimelineQueryCard, tokens: readonly string[]): number {
177
+ const text = haystack(card);
178
+ let count = 0;
179
+ for (const token of tokens) {
180
+ if (text.includes(token)) count += 1;
181
+ }
182
+ return count;
183
+ }
184
+
185
+ export function queryTimelineSearch(
186
+ cards: readonly TimelineQueryCard[] | null | undefined,
187
+ query: TimelineSearchQuery,
188
+ ): TimelineSearchResult {
189
+ if (!Array.isArray(cards)) return { ok: false, error: "store_unreadable" };
190
+ const tokens = query.query.trim().toLowerCase().split(/\s+/).filter(Boolean);
191
+ const limit = query.limit ?? DEFAULT_SEARCH_LIMIT;
192
+ if (!Number.isInteger(limit) || limit < MIN_SEARCH_LIMIT || limit > MAX_SEARCH_LIMIT) {
193
+ throw new RangeError(`limit must be an integer from ${MIN_SEARCH_LIMIT} to ${MAX_SEARCH_LIMIT}`);
194
+ }
195
+ let pool = cards;
196
+ if (query.from !== undefined || query.to !== undefined) {
197
+ const fromMs = parseInstant(query.from ?? query.to!, "from");
198
+ const toMs = parseInstant(query.to ?? query.from!, "to");
199
+ assertRange(fromMs, toMs, DEFAULT_MAX_RANGE_DAYS);
200
+ pool = filterRange(cards, fromMs, toMs, undefined, true);
201
+ }
202
+ if (tokens.length === 0) return { ok: true, results: [] };
203
+ const ranked = pool
204
+ .map((card) => ({ card, matches: tokenMatchCount(card, tokens) }))
205
+ .filter((row) => row.matches > 0)
206
+ .sort((a, b) => {
207
+ if (a.matches !== b.matches) return b.matches - a.matches;
208
+ const recency = Date.parse(b.card.endUtc) - Date.parse(a.card.endUtc);
209
+ if (recency !== 0) return recency;
210
+ return a.card.id < b.card.id ? -1 : a.card.id > b.card.id ? 1 : 0;
211
+ })
212
+ .slice(0, limit)
213
+ .map((row) => row.card);
214
+ return { ok: true, results: ranked };
215
+ }
216
+
217
+ function parseFlags(args: string[]): { flags: Map<string, string | true>; positional: string[] } {
218
+ const flags = new Map<string, string | true>();
219
+ const positional: string[] = [];
220
+ for (let i = 0; i < args.length; i++) {
221
+ const arg = args[i]!;
222
+ if (!arg.startsWith("--")) {
223
+ positional.push(arg);
224
+ continue;
225
+ }
226
+ if (VALUE_FLAGS[arg] === true) {
227
+ const value = args[i + 1];
228
+ if (value === undefined || value.startsWith("--")) {
229
+ throw new TypeError(`flag ${arg} requires a value`);
230
+ }
231
+ flags.set(arg, value);
232
+ i += 1;
233
+ continue;
234
+ }
235
+ if (BOOLEAN_FLAGS[arg] === true) {
236
+ flags.set(arg, true);
237
+ continue;
238
+ }
239
+ const known = [...Object.keys(VALUE_FLAGS), ...Object.keys(BOOLEAN_FLAGS)].sort().join(", ");
240
+ throw new TypeError(`unknown flag ${arg} (valid: ${known})`);
241
+ }
242
+ return { flags, positional };
243
+ }
244
+
245
+ function flagString(flags: Map<string, string | true>, name: string): string | undefined {
246
+ const value = flags.get(name);
247
+ return typeof value === "string" ? value : undefined;
248
+ }
249
+
250
+ /** Shared CLI runner. `deps.cards` may be an in-memory fixture. */
251
+ export async function runTimelineCliCommand(
252
+ deps: TimelineCliDeps,
253
+ args: string[],
254
+ io: TimelineCliIo,
255
+ ): Promise<number> {
256
+ const [command, ...rest] = args;
257
+ try {
258
+ if (command === undefined || command === "help" || command === "--help") {
259
+ io.stdout.write(USAGE);
260
+ return command === undefined ? 1 : 0;
261
+ }
262
+ if (deps.timelineEnabled === false || !deps.qa.enabled) {
263
+ io.stderr.write("timeline qa disabled — set activity.timeline.qa.enabled=true\n");
264
+ return 1;
265
+ }
266
+ const { flags } = parseFlags(rest);
267
+ if (command === "range") {
268
+ const from = flagString(flags, "--from");
269
+ const to = flagString(flags, "--to");
270
+ if (!from || !to) throw new TypeError("range requires --from and --to");
271
+ if (!Array.isArray(deps.cards)) {
272
+ io.stderr.write("store_unreadable\n");
273
+ return 1;
274
+ }
275
+ const formatRaw = flagString(flags, "--format") ?? "compact";
276
+ if (formatRaw !== "cards" && formatRaw !== "compact") {
277
+ throw new TypeError("format must be one of: cards, compact");
278
+ }
279
+ const categoriesRaw = flagString(flags, "--categories");
280
+ const result = queryTimelineRange(deps.cards, {
281
+ from,
282
+ to,
283
+ format: formatRaw,
284
+ categories: categoriesRaw ? categoriesRaw.split(",").filter(Boolean) : undefined,
285
+ includeDistractions: flags.get("--include-distractions") === true,
286
+ maxRangeDays: deps.qa.maxRangeDays,
287
+ });
288
+ io.stdout.write(`${JSON.stringify(result)}\n`);
289
+ return 0;
290
+ }
291
+ if (command === "search") {
292
+ const q = flagString(flags, "--query");
293
+ if (q === undefined) throw new TypeError("search requires --query");
294
+ const limitRaw = flagString(flags, "--limit");
295
+ const limit = limitRaw === undefined ? undefined : Number(limitRaw);
296
+ if (limitRaw !== undefined && !Number.isInteger(limit)) {
297
+ throw new RangeError("limit must be an integer from 1 to 50");
298
+ }
299
+ const result = queryTimelineSearch(deps.cards, {
300
+ query: q,
301
+ from: flagString(flags, "--from"),
302
+ to: flagString(flags, "--to"),
303
+ limit,
304
+ });
305
+ io.stdout.write(`${JSON.stringify(result)}\n`);
306
+ return result.ok ? 0 : 1;
307
+ }
308
+ throw new TypeError(`unknown command ${command} (valid: range, search)`);
309
+ } catch (err) {
310
+ io.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
311
+ return 1;
312
+ }
313
+ }