@remnic/core 9.69.44 → 9.69.45

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 (482) hide show
  1. package/dist/access-admin-ops-surface.d.ts +14 -14
  2. package/dist/access-admin-ops-surface.js +22 -22
  3. package/dist/access-authorization-probe.d.ts +14 -14
  4. package/dist/access-authorization-probe.js +23 -23
  5. package/dist/access-boundary.d.ts +14 -14
  6. package/dist/access-boundary.js +22 -22
  7. package/dist/access-cli.js +65 -63
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +1 -1
  10. package/dist/access-extraction-force-flush.d.ts +14 -14
  11. package/dist/access-extraction-force-flush.js +22 -22
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-briefing.d.ts +14 -14
  14. package/dist/access-http-briefing.js +23 -23
  15. package/dist/access-http-lcm-compaction.d.ts +14 -14
  16. package/dist/access-http-lifecycle-flush.d.ts +14 -14
  17. package/dist/access-http-offline-stream.d.ts +14 -14
  18. package/dist/access-http-query.d.ts +2 -2
  19. package/dist/access-http-query.js +24 -24
  20. package/dist/access-http.d.ts +15 -15
  21. package/dist/access-http.js +37 -37
  22. package/dist/access-identity-continuity-surface.d.ts +11 -11
  23. package/dist/access-identity-continuity-surface.js +22 -22
  24. package/dist/access-lcm-surface.d.ts +14 -14
  25. package/dist/access-lcm-surface.js +22 -22
  26. package/dist/access-mcp-shared-context-tools.d.ts +14 -14
  27. package/dist/access-mcp.d.ts +14 -14
  28. package/dist/access-mcp.js +30 -30
  29. package/dist/access-memory-search-fanout.d.ts +2 -2
  30. package/dist/{access-namespace-preflight-CE-RrXKu.d.ts → access-namespace-preflight-DDnsN22V.d.ts} +1 -1
  31. package/dist/access-namespace-preflight.d.ts +3 -3
  32. package/dist/access-namespace-preflight.js +22 -22
  33. package/dist/access-observe-transcript.d.ts +11 -11
  34. package/dist/access-observe-write-category.d.ts +3 -3
  35. package/dist/access-observe-write-surface.d.ts +14 -14
  36. package/dist/access-observe-write-surface.js +22 -22
  37. package/dist/access-offline-manifest.d.ts +11 -11
  38. package/dist/access-offline-manifest.js +3 -3
  39. package/dist/access-operations-batch.js +23 -23
  40. package/dist/access-operations.d.ts +14 -14
  41. package/dist/access-operations.js +29 -29
  42. package/dist/access-recall-concurrency.d.ts +14 -14
  43. package/dist/access-recall-concurrency.js +22 -22
  44. package/dist/access-recall-response.d.ts +14 -14
  45. package/dist/access-recall-response.js +22 -22
  46. package/dist/access-recall-surface.d.ts +14 -14
  47. package/dist/access-recall-surface.js +22 -22
  48. package/dist/access-schema.d.ts +114 -114
  49. package/dist/{access-service-Cww3xAAy.d.ts → access-service-CDteK_Gt.d.ts} +73 -73
  50. package/dist/access-service-helpers.d.ts +14 -14
  51. package/dist/access-service.d.ts +14 -14
  52. package/dist/access-service.js +22 -22
  53. package/dist/access-surface-catalog.d.ts +14 -14
  54. package/dist/access-surface-catalog.js +24 -24
  55. package/dist/access-wearables-meetings-surface.d.ts +4 -4
  56. package/dist/action-confidence.d.ts +1 -1
  57. package/dist/active-memory-bridge.d.ts +1 -1
  58. package/dist/active-recall.d.ts +1 -1
  59. package/dist/activity/digest.d.ts +1 -1
  60. package/dist/ambient-provenance.d.ts +1 -1
  61. package/dist/artifact-search.d.ts +1 -1
  62. package/dist/{auto-sync-QZD4RD6H.js → auto-sync-DG5KEOF5.js} +5 -5
  63. package/dist/background-generation.d.ts +1 -1
  64. package/dist/behavior-learner.d.ts +1 -1
  65. package/dist/behavior-signals.d.ts +1 -1
  66. package/dist/bootstrap.d.ts +11 -11
  67. package/dist/briefing-window.d.ts +2 -2
  68. package/dist/briefing.d.ts +2 -2
  69. package/dist/briefing.js +6 -6
  70. package/dist/buffer-surprise-report.d.ts +1 -1
  71. package/dist/buffer-turn-helpers.d.ts +1 -1
  72. package/dist/buffer.d.ts +2 -2
  73. package/dist/buffer.js +3 -3
  74. package/dist/bulk-import/index.d.ts +3 -3
  75. package/dist/calibration.d.ts +1 -1
  76. package/dist/calibration.js +2 -2
  77. package/dist/capabilities.d.ts +1 -1
  78. package/dist/{catalog-Ya3DDn_T.d.ts → catalog-Dl2hYqpS.d.ts} +1 -1
  79. package/dist/causal-behavior.d.ts +1 -1
  80. package/dist/causal-consolidation.d.ts +1 -1
  81. package/dist/causal-consolidation.js +7 -7
  82. package/dist/causal-trajectory-graph.d.ts +1 -1
  83. package/dist/{chunk-BZDK5EOD.js → chunk-2LRO73MN.js} +2 -2
  84. package/dist/{chunk-JDL5BYYF.js → chunk-46A4RGBC.js} +2 -2
  85. package/dist/{chunk-6EGIQEKC.js → chunk-4HTQ76O4.js} +2 -2
  86. package/dist/{chunk-7L54ARML.js → chunk-4XTSKGLX.js} +2 -2
  87. package/dist/{chunk-IOTYIECA.js → chunk-5TKHJ5RW.js} +11 -11
  88. package/dist/{chunk-ZVQ5HF77.js → chunk-5XTILJRI.js} +2 -2
  89. package/dist/{chunk-J2MGTGKC.js → chunk-5ZXGH2ZL.js} +20 -3
  90. package/dist/chunk-5ZXGH2ZL.js.map +1 -0
  91. package/dist/{chunk-VJXMFBVR.js → chunk-6II55MXS.js} +2 -2
  92. package/dist/{chunk-K3IVJ5ML.js → chunk-7LKXP4QG.js} +17 -17
  93. package/dist/{chunk-PF7LQ22G.js → chunk-A2YN3FR4.js} +3 -3
  94. package/dist/chunk-AAQA6ZUP.js +41 -0
  95. package/dist/chunk-AAQA6ZUP.js.map +1 -0
  96. package/dist/{chunk-RJ7Z7YXK.js → chunk-AG6PANBG.js} +14 -20
  97. package/dist/chunk-AG6PANBG.js.map +1 -0
  98. package/dist/{chunk-KDLOKVX7.js → chunk-AOMUIF3R.js} +2 -2
  99. package/dist/{chunk-2YIUUXNK.js → chunk-B55FYF6F.js} +2 -2
  100. package/dist/{chunk-2HDLDBJW.js → chunk-BOWAP64Q.js} +2 -2
  101. package/dist/{chunk-SUS64JER.js → chunk-C3MCMFNV.js} +2 -2
  102. package/dist/{chunk-DABSYX7V.js → chunk-D3DJYGU2.js} +3 -3
  103. package/dist/{chunk-F2FJTOV6.js → chunk-DO6R3LIE.js} +2 -2
  104. package/dist/{chunk-LD22AAJI.js → chunk-DSHSQGSN.js} +2 -2
  105. package/dist/{chunk-3254BYQV.js → chunk-E5VOKZQV.js} +1 -1
  106. package/dist/{chunk-46FVFU7S.js → chunk-EC5SVM6H.js} +2 -2
  107. package/dist/{chunk-UHSOPTNB.js → chunk-EP6BA7VV.js} +50 -15
  108. package/dist/chunk-EP6BA7VV.js.map +1 -0
  109. package/dist/{chunk-BPXJINHW.js → chunk-EUP4AXIW.js} +2 -2
  110. package/dist/{chunk-WJPR2XUN.js → chunk-F6AYWLRN.js} +2 -2
  111. package/dist/{chunk-4AX5OYKC.js → chunk-FDDCZDBI.js} +2 -2
  112. package/dist/{chunk-VHANUT45.js → chunk-HBGSZ62Z.js} +7 -7
  113. package/dist/{chunk-XLPZN3A5.js → chunk-HVGCQMTQ.js} +2 -2
  114. package/dist/{chunk-GMU7MAHS.js → chunk-IAT5WFEU.js} +3 -3
  115. package/dist/{chunk-R3H2AXO2.js → chunk-IFULZYYQ.js} +2 -2
  116. package/dist/{chunk-ZYSOT6HD.js → chunk-J3IWHCMF.js} +2 -2
  117. package/dist/{chunk-QCTXQ2HW.js → chunk-J6NEOCQC.js} +2 -2
  118. package/dist/{chunk-H2N6SLTR.js → chunk-JIWZVOQM.js} +2 -2
  119. package/dist/{chunk-HKQAI6XI.js → chunk-JPNUKKSL.js} +2 -2
  120. package/dist/{chunk-F6PTJLEM.js → chunk-K4KE5MYE.js} +1 -1
  121. package/dist/{chunk-5AJZ7EUW.js → chunk-K75H7FSO.js} +2 -2
  122. package/dist/{chunk-JL4TQYM5.js → chunk-L272A5QW.js} +33 -2
  123. package/dist/{chunk-JL4TQYM5.js.map → chunk-L272A5QW.js.map} +1 -1
  124. package/dist/{chunk-7F47R4H4.js → chunk-LZAJONO5.js} +2 -2
  125. package/dist/{chunk-OCX7OWOC.js → chunk-M7ECD3KN.js} +2 -2
  126. package/dist/{chunk-KORQWGUA.js → chunk-MDYZCPNQ.js} +2 -2
  127. package/dist/{chunk-IWHNT35B.js → chunk-N6I257OM.js} +3 -3
  128. package/dist/{chunk-YR5QT4SR.js → chunk-NAFPHFDM.js} +2 -2
  129. package/dist/{chunk-D7UUB33A.js → chunk-NGAFYIHQ.js} +2 -2
  130. package/dist/{chunk-3K64PLY3.js → chunk-NKDQXDFL.js} +14 -14
  131. package/dist/{chunk-ZBSP4BSN.js → chunk-NRFUYVW7.js} +2 -2
  132. package/dist/{chunk-XOCGC3FJ.js → chunk-OFBJD3V5.js} +2 -2
  133. package/dist/{chunk-SZV2L2IG.js → chunk-OOBUWMPY.js} +3 -3
  134. package/dist/{chunk-WLHPCAVD.js → chunk-OREGA7GY.js} +5 -5
  135. package/dist/{chunk-4WMGRLTV.js → chunk-Q4MI2KCG.js} +2 -2
  136. package/dist/{chunk-MOL7JK4F.js → chunk-R4HFCATE.js} +2 -2
  137. package/dist/{chunk-VDLNQVYW.js → chunk-SPN5YFXN.js} +7 -7
  138. package/dist/{chunk-XK76RJBN.js → chunk-T2ZNUWUY.js} +2 -2
  139. package/dist/{chunk-Y77UTH7F.js → chunk-TFS5FAAC.js} +35 -35
  140. package/dist/{chunk-JDOBQPJY.js → chunk-TNQR7N52.js} +2 -2
  141. package/dist/{chunk-ROXDOKLM.js → chunk-UJXNBZYJ.js} +3 -3
  142. package/dist/{chunk-DDGQDNQW.js → chunk-VA5QRTZX.js} +2 -2
  143. package/dist/{chunk-GKKLI23D.js → chunk-WCQ7L54B.js} +2 -2
  144. package/dist/{chunk-3YQ7VLP3.js → chunk-WMTYEQO5.js} +2 -2
  145. package/dist/{chunk-OGAKUA7I.js → chunk-YHSEUZV5.js} +2 -2
  146. package/dist/{chunk-GR76OKET.js → chunk-YSBYNCCN.js} +2 -2
  147. package/dist/{chunk-IAGEEVQL.js → chunk-Z5YNVWRD.js} +2 -2
  148. package/dist/{chunk-EOXCOZ6L.js → chunk-ZLVURGAJ.js} +2 -2
  149. package/dist/{chunk-M6FKXOYV.js → chunk-ZQ533JDE.js} +2 -2
  150. package/dist/{chunk-TRTLWUDD.js → chunk-ZTHGFTMW.js} +2 -2
  151. package/dist/{cli-Cl7bKIWJ.d.ts → cli-CZDhIcxu.d.ts} +5 -5
  152. package/dist/cli.d.ts +16 -16
  153. package/dist/cli.js +47 -47
  154. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  155. package/dist/coding/export-okf-codegraph.js +5 -5
  156. package/dist/coding/pre-action-gate.d.ts +1 -1
  157. package/dist/compounding/engine.d.ts +2 -2
  158. package/dist/compounding/engine.js +6 -6
  159. package/dist/compounding/preference-consolidator.d.ts +1 -1
  160. package/dist/compression-optimizer.d.ts +1 -1
  161. package/dist/config.d.ts +1 -1
  162. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  163. package/dist/connectors/codex-materialize-runner.js +6 -6
  164. package/dist/connectors/codex-materialize.d.ts +1 -1
  165. package/dist/connectors/index.d.ts +1 -1
  166. package/dist/connectors/index.js +6 -6
  167. package/dist/consolidation-provenance-check.d.ts +2 -2
  168. package/dist/consolidation-undo.d.ts +2 -2
  169. package/dist/contradiction/index.d.ts +4 -4
  170. package/dist/converge-config.d.ts +1 -1
  171. package/dist/convergence-refresh.d.ts +2 -2
  172. package/dist/convergence-refresh.js +8 -8
  173. package/dist/conversation-index/backend.d.ts +1 -1
  174. package/dist/conversation-index/chunker.d.ts +1 -1
  175. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  176. package/dist/conversation-index/indexer.d.ts +1 -1
  177. package/dist/conversation-index/search.d.ts +1 -1
  178. package/dist/corpus-watermark.d.ts +1 -1
  179. package/dist/corpus-watermark.js +8 -8
  180. package/dist/cross-lingual-recall.d.ts +1 -1
  181. package/dist/day-summary.d.ts +1 -1
  182. package/dist/deep-recall-http-glue.d.ts +14 -14
  183. package/dist/deep-recall-mcp-tools.d.ts +14 -14
  184. package/dist/deep-recall-policy-llm.d.ts +2 -2
  185. package/dist/deep-recall-policy-llm.js +3 -3
  186. package/dist/deep-recall-seeds.d.ts +1 -1
  187. package/dist/delinearize.d.ts +1 -1
  188. package/dist/dependency-propagation-config.d.ts +1 -1
  189. package/dist/{dependency-propagation-delivery-CggS9BFT.d.ts → dependency-propagation-delivery-BXaUoVUf.d.ts} +1 -1
  190. package/dist/direct-answer-wiring.d.ts +1 -1
  191. package/dist/direct-answer.d.ts +1 -1
  192. package/dist/embedding-fallback.d.ts +1 -1
  193. package/dist/enrichment/index.d.ts +1 -1
  194. package/dist/entity-origin-fields.d.ts +1 -1
  195. package/dist/entity-retrieval.d.ts +2 -2
  196. package/dist/entity-retrieval.js +6 -6
  197. package/dist/entity-schema.d.ts +1 -1
  198. package/dist/episodic-context.d.ts +1 -1
  199. package/dist/eval-trajectory-contracts.d.ts +1 -1
  200. package/dist/eval-trajectory-store.d.ts +1 -1
  201. package/dist/eval-trajectory.d.ts +1 -1
  202. package/dist/explicit-capture.d.ts +11 -11
  203. package/dist/external-wiki-access.d.ts +14 -14
  204. package/dist/external-wiki-access.js +23 -23
  205. package/dist/external-wiki-collection-registration.d.ts +1 -1
  206. package/dist/external-wiki-collection.d.ts +1 -1
  207. package/dist/external-wiki-mcp-tools.d.ts +14 -14
  208. package/dist/extraction-error-classification.d.ts +1 -1
  209. package/dist/extraction-faithfulness.d.ts +2 -2
  210. package/dist/extraction-faithfulness.js +3 -3
  211. package/dist/extraction-judge-telemetry.d.ts +2 -2
  212. package/dist/extraction-judge-training.d.ts +2 -2
  213. package/dist/extraction-judge.d.ts +2 -2
  214. package/dist/extraction-judge.js +3 -3
  215. package/dist/extraction-liveness.d.ts +1 -1
  216. package/dist/extraction-normalization.d.ts +1 -1
  217. package/dist/extraction-prompt.d.ts +1 -1
  218. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  219. package/dist/extraction-source-grounding.d.ts +1 -1
  220. package/dist/extraction-span-config.d.ts +1 -1
  221. package/dist/extraction-span-materialize.d.ts +1 -1
  222. package/dist/extraction-span-wire.d.ts +23 -4
  223. package/dist/extraction-span-wire.js +7 -8
  224. package/dist/extraction-span-wire.js.map +1 -1
  225. package/dist/extraction.d.ts +2 -2
  226. package/dist/extraction.js +13 -11
  227. package/dist/fallback-llm-codex-subscription.d.ts +1 -1
  228. package/dist/fallback-llm-codex-subscription.js +1 -1
  229. package/dist/fallback-llm.d.ts +1 -1
  230. package/dist/fallback-llm.js +2 -2
  231. package/dist/{generic-recall-paths-CoXPSnCw.d.ts → generic-recall-paths-BkVVEoeO.d.ts} +1 -1
  232. package/dist/graph-append-error.d.ts +1 -1
  233. package/dist/graph-dashboard-diff.d.ts +1 -1
  234. package/dist/graph-dashboard-key.d.ts +1 -1
  235. package/dist/graph-dashboard-parser.d.ts +1 -1
  236. package/dist/graph-edge-reinforcement.d.ts +1 -1
  237. package/dist/graph-jsonl.d.ts +1 -1
  238. package/dist/graph-path-reconstruction.d.ts +1 -1
  239. package/dist/graph-path-scoring.d.ts +1 -1
  240. package/dist/graph-snapshot.d.ts +1 -1
  241. package/dist/graph.d.ts +1 -1
  242. package/dist/harmonic-retrieval.js +1 -1
  243. package/dist/importance.d.ts +1 -1
  244. package/dist/importers/index.d.ts +1 -1
  245. package/dist/importers/test-utils.d.ts +1 -1
  246. package/dist/in-flight-reads.d.ts +1 -1
  247. package/dist/{index-fdw_oK5a.d.ts → index-TBPe6NvB.d.ts} +3 -3
  248. package/dist/index.d.ts +703 -703
  249. package/dist/index.js +65 -63
  250. package/dist/intent.d.ts +1 -1
  251. package/dist/lcm/engine.d.ts +1 -1
  252. package/dist/lcm/index.d.ts +1 -1
  253. package/dist/lcm/tools.d.ts +1 -1
  254. package/dist/lifecycle.d.ts +1 -1
  255. package/dist/live-connectors-runner.d.ts +1 -1
  256. package/dist/{local-llm-3-jtw52a.d.ts → local-llm-DdrhmecM.d.ts} +1 -1
  257. package/dist/local-llm-helpers.d.ts +2 -2
  258. package/dist/local-llm.d.ts +2 -2
  259. package/dist/local-model-endpoint.d.ts +1 -1
  260. package/dist/location/index.d.ts +5 -5
  261. package/dist/location/index.js +8 -8
  262. package/dist/maintenance/memory-governance.d.ts +1 -1
  263. package/dist/maintenance/memory-governance.js +6 -6
  264. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  265. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +6 -6
  266. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  267. package/dist/maintenance/rebuild-memory-projection.js +7 -7
  268. package/dist/{maintenance-DgeeH0a1.d.ts → maintenance-B813YFWJ.d.ts} +3 -3
  269. package/dist/mcp-memory-inspector-app.d.ts +14 -14
  270. package/dist/memory-action-policy.d.ts +1 -1
  271. package/dist/memory-cache.d.ts +1 -1
  272. package/dist/memory-controller.d.ts +1 -1
  273. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  274. package/dist/memory-projection-store.d.ts +1 -1
  275. package/dist/memory-provenance.d.ts +1 -1
  276. package/dist/memory-snapshot.d.ts +1 -1
  277. package/dist/memory-subject-cli.d.ts +14 -14
  278. package/dist/memory-subject.d.ts +14 -14
  279. package/dist/memory-worth-outcomes.d.ts +2 -2
  280. package/dist/models-json.d.ts +1 -1
  281. package/dist/namespaces/migrate.d.ts +3 -3
  282. package/dist/namespaces/migrate.js +7 -7
  283. package/dist/namespaces/principal.d.ts +1 -1
  284. package/dist/namespaces/search.d.ts +1 -1
  285. package/dist/namespaces/storage.d.ts +3 -3
  286. package/dist/namespaces/storage.js +6 -6
  287. package/dist/native-knowledge.d.ts +1 -1
  288. package/dist/offline-sync-impression-drain.d.ts +1 -1
  289. package/dist/operator-doctor-corpus.d.ts +1 -1
  290. package/dist/operator-doctor-corpus.js +9 -9
  291. package/dist/operator-doctor-replica.d.ts +1 -1
  292. package/dist/operator-toolkit.d.ts +3 -3
  293. package/dist/operator-toolkit.js +14 -14
  294. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  295. package/dist/orchestration/maintenance.d.ts +4 -4
  296. package/dist/orchestration/maintenance.js +14 -14
  297. package/dist/{orchestrator-VXWKdatm.d.ts → orchestrator-BCvQavIS.d.ts} +10 -10
  298. package/dist/orchestrator.d.ts +11 -11
  299. package/dist/orchestrator.js +65 -63
  300. package/dist/patterns-cli.d.ts +1 -1
  301. package/dist/{pipeline-CwXZBKR5.d.ts → pipeline-4lqKJZ_0.d.ts} +1 -1
  302. package/dist/policy-runtime.d.ts +1 -1
  303. package/dist/proactive-contention.d.ts +2 -2
  304. package/dist/provenance.d.ts +1 -1
  305. package/dist/{public-http-DdmM4scJ.d.ts → public-http-NH72a6aa.d.ts} +1 -1
  306. package/dist/{qmd-DOLTPIQg.d.ts → qmd-DnoWaXKb.d.ts} +1 -1
  307. package/dist/qmd-preflight.d.ts +2 -2
  308. package/dist/qmd-recall-cache.d.ts +1 -1
  309. package/dist/qmd.d.ts +2 -2
  310. package/dist/recall-concurrency-config.d.ts +1 -1
  311. package/dist/recall-disclosure-escalation.d.ts +1 -1
  312. package/dist/recall-explain-renderer.d.ts +1 -1
  313. package/dist/recall-memory-map.d.ts +1 -1
  314. package/dist/recall-navigate-access.d.ts +1 -1
  315. package/dist/recall-navigate-disclosure.d.ts +1 -1
  316. package/dist/recall-navigate.d.ts +1 -1
  317. package/dist/recall-navigation-http-glue.d.ts +14 -14
  318. package/dist/recall-navigation-mcp-tools.d.ts +14 -14
  319. package/dist/recall-navigation-operations.js +23 -23
  320. package/dist/recall-navigation-renderer.d.ts +1 -1
  321. package/dist/recall-navigation.d.ts +1 -1
  322. package/dist/recall-navigation.js +22 -22
  323. package/dist/recall-planner-llm.d.ts +1 -1
  324. package/dist/recall-planner-llm.js +2 -2
  325. package/dist/recall-state-view-admission.d.ts +2 -2
  326. package/dist/recall-state-view-admission.js +3 -3
  327. package/dist/recall-state-view-anchors.d.ts +1 -1
  328. package/dist/recall-state.d.ts +1 -1
  329. package/dist/recall-tag-filter.d.ts +1 -1
  330. package/dist/recall-timings.d.ts +1 -1
  331. package/dist/recall-xray-cli.d.ts +1 -1
  332. package/dist/recall-xray-renderer.d.ts +1 -1
  333. package/dist/recall-xray.d.ts +1 -1
  334. package/dist/reconcile/cursor.d.ts +1 -1
  335. package/dist/reconcile/manifest.d.ts +1 -1
  336. package/dist/reconcile/manifest.js +2 -2
  337. package/dist/reconcile/plan.d.ts +1 -1
  338. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  339. package/dist/replay/normalizers/claude.d.ts +1 -1
  340. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  341. package/dist/replay/normalizers/shared.d.ts +1 -1
  342. package/dist/replay/runner.d.ts +1 -1
  343. package/dist/replay/types.d.ts +1 -1
  344. package/dist/replica-divergence.d.ts +1 -1
  345. package/dist/replica-peers-config.d.ts +1 -1
  346. package/dist/resolve-auth-token.d.ts +1 -1
  347. package/dist/retrieval-agents.d.ts +2 -2
  348. package/dist/retrieval-tiers.d.ts +1 -1
  349. package/dist/routing/engine.d.ts +1 -1
  350. package/dist/routing/store.d.ts +1 -1
  351. package/dist/salvage-envelope.d.ts +1 -1
  352. package/dist/schemas.d.ts +160 -160
  353. package/dist/{scope-profiles-C564-hrv.d.ts → scope-profiles-crazXegZ.d.ts} +1 -1
  354. package/dist/search/embed-helper.d.ts +1 -1
  355. package/dist/search/factory.d.ts +1 -1
  356. package/dist/search/index.d.ts +1 -1
  357. package/dist/search/lancedb-backend.d.ts +1 -1
  358. package/dist/search/meilisearch-backend.d.ts +1 -1
  359. package/dist/search/noop-backend.d.ts +1 -1
  360. package/dist/search/orama-backend.d.ts +1 -1
  361. package/dist/search/port.d.ts +1 -1
  362. package/dist/search/remote-backend.d.ts +1 -1
  363. package/dist/{semantic-consolidation-g6x-ShY8.d.ts → semantic-consolidation-B09JI9WM.d.ts} +1 -1
  364. package/dist/semantic-consolidation.d.ts +2 -2
  365. package/dist/semantic-consolidation.js +7 -7
  366. package/dist/semantic-rule-promotion.js +6 -6
  367. package/dist/semantic-rule-verifier.d.ts +1 -1
  368. package/dist/semantic-rule-verifier.js +6 -6
  369. package/dist/{service-CaCOk0rd.d.ts → service-Echc5Xso.d.ts} +2 -2
  370. package/dist/session-observer-bands.d.ts +1 -1
  371. package/dist/session-observer-state.d.ts +1 -1
  372. package/dist/shared-context/manager.d.ts +7 -7
  373. package/dist/signal.d.ts +1 -1
  374. package/dist/source-agent-qualifier.d.ts +1 -1
  375. package/dist/source-agent-qualifier.js +9 -9
  376. package/dist/source-attribution.d.ts +7 -4
  377. package/dist/source-attribution.js +1 -1
  378. package/dist/standup/build.js +6 -6
  379. package/dist/{storage-C9nsZX5Q.d.ts → storage-ClkHCQSE.d.ts} +1 -1
  380. package/dist/storage.d.ts +2 -2
  381. package/dist/storage.js +5 -5
  382. package/dist/subject-config.d.ts +1 -1
  383. package/dist/summarizer.d.ts +1 -1
  384. package/dist/summarizer.js +3 -3
  385. package/dist/summary-snapshot.d.ts +1 -1
  386. package/dist/support-passport/index.d.ts +17 -17
  387. package/dist/support-passport/index.js +25 -25
  388. package/dist/{tagging-BA4RFdH3.d.ts → tagging-ksktJ60G.d.ts} +2 -2
  389. package/dist/temporal-supersession.d.ts +2 -2
  390. package/dist/temporal-timeline-recall.d.ts +1 -1
  391. package/dist/temporal-validity.d.ts +1 -1
  392. package/dist/threading.d.ts +1 -1
  393. package/dist/tier-migration.d.ts +2 -2
  394. package/dist/tier-routing.d.ts +1 -1
  395. package/dist/topics.d.ts +1 -1
  396. package/dist/transcript.d.ts +1 -1
  397. package/dist/transfer/export-okf.d.ts +1 -1
  398. package/dist/transfer/export-okf.js +6 -6
  399. package/dist/transfer/types.d.ts +78 -78
  400. package/dist/trust-score-stage.d.ts +1 -1
  401. package/dist/trust-score.d.ts +1 -1
  402. package/dist/{types-Sps-lg5I.d.ts → types-nmhnJpxx.d.ts} +1 -1
  403. package/dist/types.d.ts +1 -1
  404. package/dist/utility-runtime.d.ts +1 -1
  405. package/dist/verified-recall.js +6 -6
  406. package/dist/who-knows-cli.d.ts +14 -14
  407. package/dist/who-knows-cli.js +7 -7
  408. package/dist/who-knows.d.ts +14 -14
  409. package/dist/who-knows.js +6 -6
  410. package/dist/write-envelope.d.ts +1 -1
  411. package/package.json +2 -2
  412. package/src/background-generation.test.ts +77 -0
  413. package/src/extraction-span-wire.test.ts +17 -1
  414. package/src/extraction-span-wire.ts +46 -3
  415. package/src/extraction.ts +2 -11
  416. package/src/providers/codex-subscription.test.ts +109 -3
  417. package/src/providers/codex-subscription.ts +57 -17
  418. package/src/source-attribution.test.ts +27 -0
  419. package/src/source-attribution.ts +41 -5
  420. package/src/summarizer.ts +18 -0
  421. package/dist/chunk-J2MGTGKC.js.map +0 -1
  422. package/dist/chunk-RJ7Z7YXK.js.map +0 -1
  423. package/dist/chunk-UHSOPTNB.js.map +0 -1
  424. /package/dist/{auto-sync-QZD4RD6H.js.map → auto-sync-DG5KEOF5.js.map} +0 -0
  425. /package/dist/{chunk-BZDK5EOD.js.map → chunk-2LRO73MN.js.map} +0 -0
  426. /package/dist/{chunk-JDL5BYYF.js.map → chunk-46A4RGBC.js.map} +0 -0
  427. /package/dist/{chunk-6EGIQEKC.js.map → chunk-4HTQ76O4.js.map} +0 -0
  428. /package/dist/{chunk-7L54ARML.js.map → chunk-4XTSKGLX.js.map} +0 -0
  429. /package/dist/{chunk-IOTYIECA.js.map → chunk-5TKHJ5RW.js.map} +0 -0
  430. /package/dist/{chunk-ZVQ5HF77.js.map → chunk-5XTILJRI.js.map} +0 -0
  431. /package/dist/{chunk-VJXMFBVR.js.map → chunk-6II55MXS.js.map} +0 -0
  432. /package/dist/{chunk-K3IVJ5ML.js.map → chunk-7LKXP4QG.js.map} +0 -0
  433. /package/dist/{chunk-PF7LQ22G.js.map → chunk-A2YN3FR4.js.map} +0 -0
  434. /package/dist/{chunk-KDLOKVX7.js.map → chunk-AOMUIF3R.js.map} +0 -0
  435. /package/dist/{chunk-2YIUUXNK.js.map → chunk-B55FYF6F.js.map} +0 -0
  436. /package/dist/{chunk-2HDLDBJW.js.map → chunk-BOWAP64Q.js.map} +0 -0
  437. /package/dist/{chunk-SUS64JER.js.map → chunk-C3MCMFNV.js.map} +0 -0
  438. /package/dist/{chunk-DABSYX7V.js.map → chunk-D3DJYGU2.js.map} +0 -0
  439. /package/dist/{chunk-F2FJTOV6.js.map → chunk-DO6R3LIE.js.map} +0 -0
  440. /package/dist/{chunk-LD22AAJI.js.map → chunk-DSHSQGSN.js.map} +0 -0
  441. /package/dist/{chunk-3254BYQV.js.map → chunk-E5VOKZQV.js.map} +0 -0
  442. /package/dist/{chunk-46FVFU7S.js.map → chunk-EC5SVM6H.js.map} +0 -0
  443. /package/dist/{chunk-BPXJINHW.js.map → chunk-EUP4AXIW.js.map} +0 -0
  444. /package/dist/{chunk-WJPR2XUN.js.map → chunk-F6AYWLRN.js.map} +0 -0
  445. /package/dist/{chunk-4AX5OYKC.js.map → chunk-FDDCZDBI.js.map} +0 -0
  446. /package/dist/{chunk-VHANUT45.js.map → chunk-HBGSZ62Z.js.map} +0 -0
  447. /package/dist/{chunk-XLPZN3A5.js.map → chunk-HVGCQMTQ.js.map} +0 -0
  448. /package/dist/{chunk-GMU7MAHS.js.map → chunk-IAT5WFEU.js.map} +0 -0
  449. /package/dist/{chunk-R3H2AXO2.js.map → chunk-IFULZYYQ.js.map} +0 -0
  450. /package/dist/{chunk-ZYSOT6HD.js.map → chunk-J3IWHCMF.js.map} +0 -0
  451. /package/dist/{chunk-QCTXQ2HW.js.map → chunk-J6NEOCQC.js.map} +0 -0
  452. /package/dist/{chunk-H2N6SLTR.js.map → chunk-JIWZVOQM.js.map} +0 -0
  453. /package/dist/{chunk-HKQAI6XI.js.map → chunk-JPNUKKSL.js.map} +0 -0
  454. /package/dist/{chunk-F6PTJLEM.js.map → chunk-K4KE5MYE.js.map} +0 -0
  455. /package/dist/{chunk-5AJZ7EUW.js.map → chunk-K75H7FSO.js.map} +0 -0
  456. /package/dist/{chunk-7F47R4H4.js.map → chunk-LZAJONO5.js.map} +0 -0
  457. /package/dist/{chunk-OCX7OWOC.js.map → chunk-M7ECD3KN.js.map} +0 -0
  458. /package/dist/{chunk-KORQWGUA.js.map → chunk-MDYZCPNQ.js.map} +0 -0
  459. /package/dist/{chunk-IWHNT35B.js.map → chunk-N6I257OM.js.map} +0 -0
  460. /package/dist/{chunk-YR5QT4SR.js.map → chunk-NAFPHFDM.js.map} +0 -0
  461. /package/dist/{chunk-D7UUB33A.js.map → chunk-NGAFYIHQ.js.map} +0 -0
  462. /package/dist/{chunk-3K64PLY3.js.map → chunk-NKDQXDFL.js.map} +0 -0
  463. /package/dist/{chunk-ZBSP4BSN.js.map → chunk-NRFUYVW7.js.map} +0 -0
  464. /package/dist/{chunk-XOCGC3FJ.js.map → chunk-OFBJD3V5.js.map} +0 -0
  465. /package/dist/{chunk-SZV2L2IG.js.map → chunk-OOBUWMPY.js.map} +0 -0
  466. /package/dist/{chunk-WLHPCAVD.js.map → chunk-OREGA7GY.js.map} +0 -0
  467. /package/dist/{chunk-4WMGRLTV.js.map → chunk-Q4MI2KCG.js.map} +0 -0
  468. /package/dist/{chunk-MOL7JK4F.js.map → chunk-R4HFCATE.js.map} +0 -0
  469. /package/dist/{chunk-VDLNQVYW.js.map → chunk-SPN5YFXN.js.map} +0 -0
  470. /package/dist/{chunk-XK76RJBN.js.map → chunk-T2ZNUWUY.js.map} +0 -0
  471. /package/dist/{chunk-Y77UTH7F.js.map → chunk-TFS5FAAC.js.map} +0 -0
  472. /package/dist/{chunk-JDOBQPJY.js.map → chunk-TNQR7N52.js.map} +0 -0
  473. /package/dist/{chunk-ROXDOKLM.js.map → chunk-UJXNBZYJ.js.map} +0 -0
  474. /package/dist/{chunk-DDGQDNQW.js.map → chunk-VA5QRTZX.js.map} +0 -0
  475. /package/dist/{chunk-GKKLI23D.js.map → chunk-WCQ7L54B.js.map} +0 -0
  476. /package/dist/{chunk-3YQ7VLP3.js.map → chunk-WMTYEQO5.js.map} +0 -0
  477. /package/dist/{chunk-OGAKUA7I.js.map → chunk-YHSEUZV5.js.map} +0 -0
  478. /package/dist/{chunk-GR76OKET.js.map → chunk-YSBYNCCN.js.map} +0 -0
  479. /package/dist/{chunk-IAGEEVQL.js.map → chunk-Z5YNVWRD.js.map} +0 -0
  480. /package/dist/{chunk-EOXCOZ6L.js.map → chunk-ZLVURGAJ.js.map} +0 -0
  481. /package/dist/{chunk-M6FKXOYV.js.map → chunk-ZQ533JDE.js.map} +0 -0
  482. /package/dist/{chunk-TRTLWUDD.js.map → chunk-ZTHGFTMW.js.map} +0 -0
@@ -177,7 +177,7 @@ export interface CodexSubscriptionRunnerDeps {
177
177
  /** Runs `codex exec`. Default: isolated subprocess via launchProcess. */
178
178
  runCodexExec?: (request: CodexSubscriptionExecRequest) => Promise<CodexSubscriptionExecResult>;
179
179
  /** Runs `codex login status`. Default: isolated subprocess. Receives the
180
- * login-status timeout budget (capped by the request deadline) and the
180
+ * shared login-status ceiling (not any one caller's deadline) and the
181
181
  * shared-check abort signal (fires when the last waiter leaves). */
182
182
  runLoginStatus?: (
183
183
  executable: string,
@@ -210,6 +210,7 @@ interface LoginStatusCacheEntry {
210
210
  }
211
211
 
212
212
  const loginStatusCache = new Map<string, LoginStatusCacheEntry>();
213
+ const inFlightLoginByRunner = new WeakMap<CodexCliFallbackRunner, Map<string, LoginStatusCacheEntry>>();
213
214
  const childrenByRunner = new WeakMap<CodexCliFallbackRunner, Set<number>>();
214
215
  const runnerByOwner = new WeakMap<object, CodexCliFallbackRunner>();
215
216
  const shutdownByRunner = new WeakMap<CodexCliFallbackRunner, AbortController>();
@@ -239,6 +240,7 @@ export function createCodexSubscriptionRunner(deps: CodexSubscriptionRunnerDeps
239
240
  { ...request, options: { ...request.options, signal } },
240
241
  runnerDeps,
241
242
  envSource,
243
+ runner,
242
244
  );
243
245
  };
244
246
  childrenByRunner.set(runner, children);
@@ -320,7 +322,8 @@ export function beginCodexSubscriptionShutdown(
320
322
  async function runCodexSubscriptionRequest(
321
323
  request: CodexCliFallbackRequest,
322
324
  deps: CodexSubscriptionRunnerDeps,
323
- envSource: NodeJS.ProcessEnv
325
+ envSource: NodeJS.ProcessEnv,
326
+ runner: CodexCliFallbackRunner,
324
327
  ): Promise<CodexCliFallbackResult> {
325
328
  const { config } = request;
326
329
  assertNoApiKeyConfig(config);
@@ -339,7 +342,7 @@ async function runCodexSubscriptionRequest(
339
342
  throw abortErrorOf(request.options.signal);
340
343
  }
341
344
  await assertSubscriptionLogin(executable, env, deps, {
342
- loginStatusTimeoutMs: Math.min(LOGIN_STATUS_TIMEOUT_MS, timeoutMs),
345
+ runner,
343
346
  callerTimeoutMs: timeoutMs,
344
347
  deadlineStartedAt,
345
348
  signal: request.options.signal,
@@ -460,8 +463,7 @@ function isAllowedEnvKey(key: string): boolean {
460
463
  }
461
464
 
462
465
  interface LoginCheckContext {
463
- /** Budget for the login-status subprocess itself. */
464
- loginStatusTimeoutMs: number;
466
+ runner: CodexCliFallbackRunner;
465
467
  /** The caller's overall effective deadline (login + exec). */
466
468
  callerTimeoutMs: number;
467
469
  deadlineStartedAt: number;
@@ -483,16 +485,32 @@ async function assertSubscriptionLogin(
483
485
  ctx: LoginCheckContext
484
486
  ): Promise<void> {
485
487
  const now = deps.now ?? Date.now;
486
- const cacheKey = `${executable}\0${resolveCodexAuthHome(env) ?? ""}`;
488
+ const cacheKey = loginCacheKey(executable, env);
489
+ const inflight = inFlightLoginsFor(ctx.runner).get(cacheKey);
490
+ if (inflight && now() - inflight.at < LOGIN_STATUS_CACHE_TTL_MS) {
491
+ await waitForLoginEntry(inflight, cacheKey, ctx, now);
492
+ return;
493
+ }
487
494
  const cached = loginStatusCache.get(cacheKey);
488
495
  if (cached && now() - cached.at < LOGIN_STATUS_CACHE_TTL_MS) {
489
496
  if (!cached.settled || (await authStoreFingerprint(env)) === cached.fingerprint) {
490
497
  await waitForLoginEntry(cached, cacheKey, ctx, now);
491
498
  return;
492
499
  }
493
-
500
+ if (loginStatusCache.get(cacheKey) === cached) {
501
+ loginStatusCache.delete(cacheKey);
502
+ }
503
+ }
504
+ const raced = inFlightLoginsFor(ctx.runner).get(cacheKey);
505
+ if (raced && now() - raced.at < LOGIN_STATUS_CACHE_TTL_MS) {
506
+ await waitForLoginEntry(raced, cacheKey, ctx, now);
507
+ return;
508
+ }
509
+ const published = loginStatusCache.get(cacheKey);
510
+ if (published && now() - published.at < LOGIN_STATUS_CACHE_TTL_MS) {
511
+ await waitForLoginEntry(published, cacheKey, ctx, now);
512
+ return;
494
513
  }
495
- loginStatusCache.delete(cacheKey);
496
514
  if (ctx.signal?.aborted) {
497
515
  throw abortErrorOf(ctx.signal);
498
516
  }
@@ -504,19 +522,19 @@ async function assertSubscriptionLogin(
504
522
  controller: new AbortController(),
505
523
  promise: Promise.resolve(undefined),
506
524
  };
507
- entry.promise = runLoginStatusCheck(executable, env, deps, ctx, entry);
525
+ entry.promise = runLoginStatusCheck(executable, env, deps, entry);
508
526
  entry.promise.then(
509
527
  () => {
510
528
  entry.settled = true;
529
+ loginStatusCache.set(cacheKey, entry);
530
+ dropInFlightLogin(ctx.runner, cacheKey, entry);
511
531
  },
512
532
  () => {
513
533
  entry.settled = true;
514
- if (loginStatusCache.get(cacheKey) === entry) {
515
- loginStatusCache.delete(cacheKey);
516
- }
534
+ dropInFlightLogin(ctx.runner, cacheKey, entry);
517
535
  }
518
536
  );
519
- loginStatusCache.set(cacheKey, entry);
537
+ inFlightLoginsFor(ctx.runner).set(cacheKey, entry);
520
538
  await waitForLoginEntry(entry, cacheKey, ctx, now);
521
539
  }
522
540
 
@@ -524,16 +542,15 @@ async function runLoginStatusCheck(
524
542
  executable: string,
525
543
  env: NodeJS.ProcessEnv,
526
544
  deps: CodexSubscriptionRunnerDeps,
527
- ctx: LoginCheckContext,
528
545
  entry: LoginStatusCacheEntry
529
546
  ): Promise<void> {
530
547
  const runLoginStatus = deps.runLoginStatus!;
531
- const result = await runLoginStatus(executable, env, ctx.loginStatusTimeoutMs, entry.controller.signal);
548
+ const result = await runLoginStatus(executable, env, LOGIN_STATUS_TIMEOUT_MS, entry.controller.signal);
532
549
  const output = `${result.stdout}\n${result.stderr}`.trim();
533
550
  if (TIMEOUT_PATTERN.test(output)) {
534
551
  // A login-status subprocess timeout is a deadline expiry, not an auth
535
552
  // failure — never report it as "unauthenticated".
536
- throw new CodexSubscriptionTimeoutError(ctx.loginStatusTimeoutMs);
553
+ throw new CodexSubscriptionTimeoutError(LOGIN_STATUS_TIMEOUT_MS);
537
554
  }
538
555
  if (result.status === 0 && LOGIN_OK_PATTERN.test(output)) {
539
556
  entry.fingerprint = await authStoreFingerprint(env);
@@ -602,6 +619,7 @@ async function waitForLoginEntry(
602
619
  entry.waiters--;
603
620
  if (entry.waiters <= 0 && !entry.settled) {
604
621
  entry.controller.abort();
622
+ dropInFlightLogin(ctx.runner, cacheKey, entry);
605
623
  if (loginStatusCache.get(cacheKey) === entry) {
606
624
  loginStatusCache.delete(cacheKey);
607
625
  }
@@ -633,6 +651,28 @@ function resolveCodexAuthHome(env: NodeJS.ProcessEnv): string | undefined {
633
651
  return profile ? path.join(profile, ".codex") : undefined;
634
652
  }
635
653
 
654
+ function loginCacheKey(executable: string, env: NodeJS.ProcessEnv): string {
655
+ return `${executable}\0${resolveCodexAuthHome(env) ?? ""}`;
656
+ }
657
+
658
+ function inFlightLoginsFor(runner: CodexCliFallbackRunner): Map<string, LoginStatusCacheEntry> {
659
+ let map = inFlightLoginByRunner.get(runner);
660
+ if (!map) {
661
+ map = new Map();
662
+ inFlightLoginByRunner.set(runner, map);
663
+ }
664
+ return map;
665
+ }
666
+
667
+ function dropInFlightLogin(
668
+ runner: CodexCliFallbackRunner,
669
+ cacheKey: string,
670
+ entry: LoginStatusCacheEntry,
671
+ ): void {
672
+ const map = inFlightLoginByRunner.get(runner);
673
+ if (map?.get(cacheKey) === entry) map.delete(cacheKey);
674
+ }
675
+
636
676
  /**
637
677
  * Args mirror the bench provider: fully sandboxed, ephemeral, no tools/hooks/
638
678
  * plugins/memories — extraction must behave as a plain completion endpoint.
@@ -755,7 +795,7 @@ function execFailureError(
755
795
  }
756
796
  if (AUTH_FAILURE_PATTERN.test(combined)) {
757
797
  // Re-check login on the next request; the cached status is now stale.
758
- loginStatusCache.delete(`${executable}\0${env.CODEX_HOME ?? env.HOME ?? ""}`);
798
+ loginStatusCache.delete(loginCacheKey(executable, env));
759
799
  return new CodexSubscriptionAuthError(
760
800
  "expired_or_revoked",
761
801
  "codex-subscription: the Codex CLI rejected the request as unauthenticated " +
@@ -16,6 +16,7 @@ import {
16
16
  formatCitation,
17
17
  hasCitation,
18
18
  hasCitationForTemplate,
19
+ lastRecognizedCitationMarker,
19
20
  parseAllCitations,
20
21
  parseCitation,
21
22
  stripCitation,
@@ -578,6 +579,32 @@ test("citationTemplatesToRecognize drops undetectable shapes and keeps prior his
578
579
  ]);
579
580
  });
580
581
 
582
+ test("stripCitationForTemplate: literal template strips the exact marker (#2951)", () => {
583
+ const template = "[cited-fixed]";
584
+ const body = "Fact body. [cited-fixed]";
585
+ assert.equal(citationTemplateIsDetectable(template), true);
586
+ assert.equal(hasCitationForTemplate(body, template), true);
587
+ assert.equal(stripCitationForTemplate(body, template), "Fact body.");
588
+ });
589
+
590
+ test("citationTemplatesToRecognize: overlapping custom marker wins over inner default (#2951)", () => {
591
+ const custom = "[Source: agent={agent}, session={sessionId}, ts={ts}; via={agent}]";
592
+ const ctx = {
593
+ agent: "planner",
594
+ session: "agent:planner:main",
595
+ ts: "2026-04-10T14:25:07Z",
596
+ };
597
+ const marker = formatCitation(ctx, custom);
598
+ const body = `The cadence is weekly. ${marker}`;
599
+ const recognized = citationTemplatesToRecognize(custom);
600
+ assert.ok(
601
+ recognized.indexOf(custom) < recognized.indexOf(DEFAULT_CITATION_FORMAT),
602
+ "current overlapping template must be recognized before the inner default",
603
+ );
604
+ assert.equal(lastRecognizedCitationMarker(body, recognized), marker);
605
+ assert.equal(stripRecognizedCitations(body, recognized), "The cadence is weekly.");
606
+ });
607
+
581
608
  test("formatCitation: substituted values containing placeholder syntax are not re-interpreted", () => {
582
609
  // Regression for PR #401 (low-severity): the previous implementation chained
583
610
  // `.replace(/\{agent\}/g, ...)`, `.replace(/\{ts\}/g, ...)` etc. If the agent
@@ -499,10 +499,10 @@ export function citationTemplateIsDetectable(template: string): boolean {
499
499
  }
500
500
 
501
501
  /**
502
- * Templates the merge path may lift, preserve, or strip: the default
503
- * format, the current format when it is detectable, then any prior
504
- * configured formats the caller still holds. Undetectable shapes are
505
- * dropped so we never hash or attach a marker we cannot re-match.
502
+ * Templates the merge path may lift, preserve, or strip. Longest
503
+ * templates first so an overlapping custom marker beats an inner default
504
+ * match; the current template wins equal-length ties. Undetectable
505
+ * shapes are dropped so we never hash or attach a marker we cannot re-match.
506
506
  */
507
507
  export function citationTemplatesToRecognize(
508
508
  primary: string | undefined,
@@ -514,9 +514,15 @@ export function citationTemplatesToRecognize(
514
514
  if (!citationTemplateIsDetectable(template)) return;
515
515
  if (!out.includes(template)) out.push(template);
516
516
  };
517
- add(DEFAULT_CITATION_FORMAT);
518
517
  add(primary);
519
518
  for (const template of extra) add(template);
519
+ add(DEFAULT_CITATION_FORMAT);
520
+ out.sort((a, b) => {
521
+ if (b.length !== a.length) return b.length - a.length;
522
+ if (a === primary && b !== primary) return -1;
523
+ if (b === primary && a !== primary) return 1;
524
+ return 0;
525
+ });
520
526
  return out;
521
527
  }
522
528
 
@@ -708,6 +714,9 @@ export function stripCitation(text: string): string {
708
714
  * written under the default format can carry the default marker plus a
709
715
  * custom marker appended after a config change; returning after the
710
716
  * default pass alone left the custom marker inside hash inputs (#2330).
717
+ * - Fully-literal templates (no placeholders) are stripped by exact match
718
+ * of the template text, the same inclusion check `hasCitationForTemplate`
719
+ * uses.
711
720
  * - All-placeholder templates (no literal prefix/suffix/separator) cannot
712
721
  * produce a reliable matcher. `hasCitationForTemplate` already returns
713
722
  * `false` for such templates, so this function never attempts to strip an
@@ -731,6 +740,13 @@ export function stripCitationForTemplate(
731
740
 
732
741
  if (!hasCitationForTemplate(afterDefault, template)) return afterDefault;
733
742
 
743
+ PLACEHOLDER_REGEX.lastIndex = 0;
744
+ if (!PLACEHOLDER_REGEX.test(template)) {
745
+ PLACEHOLDER_REGEX.lastIndex = 0;
746
+ return stripExactLiteralCitation(afterDefault, template);
747
+ }
748
+ PLACEHOLDER_REGEX.lastIndex = 0;
749
+
734
750
  // Build the template matcher. hasCitationForTemplate already returned true,
735
751
  // which means templateMatcher produced a non-null result. The null branch
736
752
  // here is a defensive fallback only — the default pass already ran.
@@ -769,6 +785,26 @@ export function stripCitationForTemplate(
769
785
  return result.trimEnd();
770
786
  }
771
787
 
788
+ function stripExactLiteralCitation(text: string, marker: string): string {
789
+ if (marker.length === 0) return text;
790
+ let result = "";
791
+ let lastIndex = 0;
792
+ let idx = text.indexOf(marker);
793
+ if (idx === -1) return text;
794
+ while (idx !== -1) {
795
+ const before = text.slice(lastIndex, idx).replace(/[ \t]+$/, "");
796
+ result += before;
797
+ lastIndex = idx + marker.length;
798
+ idx = text.indexOf(marker, lastIndex);
799
+ }
800
+ const after = text.slice(lastIndex).replace(/^[ \t]+/, "");
801
+ if (after.length > 0) {
802
+ if (result.length > 0) result += " ";
803
+ result += after;
804
+ }
805
+ return result.trimEnd();
806
+ }
807
+
772
808
  function enclosingDelimiterRange(
773
809
  text: string,
774
810
  start: number,
package/src/summarizer.ts CHANGED
@@ -360,6 +360,24 @@ Respond with valid JSON matching this schema:
360
360
 
361
361
  const user = `Hour: ${hourIso}\nSession: ${sessionKey}\n\n${statsLine}${toolStatsLine}Conversation:\n${conversation}\n`;
362
362
 
363
+ if (this.config.backgroundGeneration) {
364
+ try {
365
+ const text = await completeBackgroundGeneration(this.config, [
366
+ { role: "system", content: sys },
367
+ { role: "user", content: user },
368
+ ]);
369
+ const parsed = parseBackgroundGenerationJson(text, (value) => HourlySummaryExtendedSchema.parse(value));
370
+ if (parsed) {
371
+ log.debug(
372
+ `generated extended hourly summary for ${sessionKey} at ${hourIso} in ${Date.now() - startTime}ms (background)`
373
+ );
374
+ return { ...parsed, _meta: { userTurns, assistantTurns, toolCalls, toolCounts } };
375
+ }
376
+ } catch {
377
+ log.info("extended summary: background generation unavailable, continuing");
378
+ }
379
+ }
380
+
363
381
  // Try local LLM first if enabled
364
382
  if (this.shouldUseLocalLlm) {
365
383
  try {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/summarizer.ts"],"sourcesContent":["import { mkdir, readFile, writeFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { log } from \"./logger.js\";\nimport { LocalLlmClient } from \"./local-llm.js\";\nimport { FallbackLlmClient, fallbackLlmRuntimeContextFromConfig, gatewayTaskChainOptions } from \"./fallback-llm.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { extractJsonCandidates } from \"./json-extract.js\";\nimport {\n completeBackgroundGeneration,\n parseBackgroundGenerationJson,\n} from \"./background-generation.js\";\nimport type { HourlySummary, TranscriptEntry, PluginConfig, GatewayConfig } from \"./types.js\";\nimport type { TranscriptManager } from \"./transcript.js\";\nimport { readSummarySnapshot, upsertSummarySnapshot, writeSummarySnapshot } from \"./summary-snapshot.js\";\nimport { encodeStoragePathSegment, resolveSafeStoragePath } from \"./storage-paths.js\";\nimport { sessionStoragePaths } from \"./session-identity.js\";\nimport { resolveLocalLlmCapabilities } from \"./capabilities.js\";\nimport { resolvePipelineProcessingCapabilities } from \"./capabilities.js\";\n\n// Schema for LLM summary output\nconst HourlySummarySchema = z.object({\n bullets: z.array(z.string().trim().min(1)).min(1).describe(\"3-5 bullet points summarizing the hour's activity\"),\n});\n\ntype HourlySummaryResult = z.infer<typeof HourlySummarySchema>;\n\nconst HourlySummaryExtendedSchema = z.object({\n topics: z.array(z.string()).default([]),\n decisions: z.array(z.string()).default([]),\n actionItems: z.array(z.string()).default([]),\n rejected: z.array(z.string()).default([]),\n});\n\ntype HourlySummaryExtendedResult = z.infer<typeof HourlySummaryExtendedSchema>;\n\ntype HourlySummaryExtendedMeta = {\n userTurns: number;\n assistantTurns: number;\n toolCalls: number;\n toolCounts: Record<string, number>;\n};\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Outcome stats of one `runHourly` pass (issue #2783). The summarizer must\n * not report success on empty work: an empty or stale transcript store is\n * the delegate-mode starvation signature, and callers surface these counts\n * and the staleness flag as a distinct warning instead of a bare ok.\n */\nexport interface HourlySummarizerRunStats {\n sessionsConsidered: number;\n sessionsWithEntries: number;\n summariesWritten: number;\n /** True when the newest transcript entry across the store is older than STALE_STORE_MS. */\n staleStore: boolean;\n /** ISO timestamp of the newest transcript entry seen by the scan, when any exist. */\n newestEntryTimestamp: string | null;\n /** True when the transcript scan itself FAILED (unreadable store) — distinct from an empty store. */\n scanFailed: boolean;\n}\n\n/** A store whose newest entry is older than this is considered stale (starvation signal, issue #2783). */\nconst STALE_STORE_MS = 2 * 60 * 60 * 1000;\n\n/**\n * Interpret one {@link HourlySummarizerRunStats} into the operator-facing\n * message/warning (issue #2783). Every degraded shape — failed scan, empty\n * store, backend-down, stale store — is DISTINCT from success; monitoring\n * alerts on `warning`, never on `ok` (ok only means \"the run completed\").\n */\nexport function summarizeHourlyStatus(stats: HourlySummarizerRunStats): {\n message: string;\n warning?: string;\n} {\n if (stats.scanFailed) {\n return {\n message:\n \"Hourly summarization completed, but the transcript store scan FAILED (unreadable directory or I/O error). Investigate the daemon's memoryDir.\",\n warning: \"transcript store scan failed\",\n };\n }\n if (stats.sessionsConsidered === 0) {\n return {\n message:\n \"Hourly summarization completed, but the transcript store is empty — no sessions found. If turns are ingested via observe, transcript persistence may be disabled or failing.\",\n warning: \"transcript store is empty\",\n };\n }\n if (stats.sessionsWithEntries > 0 && stats.summariesWritten === 0) {\n return {\n message: `Hourly summarization found ${stats.sessionsWithEntries} session(s) with transcript entries but wrote no summaries — the summarizer backend may be down.`,\n warning: \"sessions with entries produced no summaries\",\n };\n }\n if (stats.sessionsWithEntries === 0 && stats.staleStore) {\n return {\n message: `Hourly summarization completed with no transcript entries for the target hour, and the store looks stale (newest entry ${stats.newestEntryTimestamp ?? \"unknown\"}).`,\n warning: \"no transcript entries for the target hour and no new entries recently\",\n };\n }\n return {\n message: `Hourly summarization completed: ${stats.summariesWritten} summar${stats.summariesWritten === 1 ? \"y\" : \"ies\"} written across ${stats.sessionsWithEntries} session${stats.sessionsWithEntries === 1 ? \"\" : \"s\"} with transcript entries.`,\n };\n}\n\nexport class HourlySummarizer {\n private summariesDir: string;\n private config: PluginConfig;\n private localLlm: LocalLlmClient;\n private fallbackLlm: FallbackLlmClient;\n private modelRegistry: ModelRegistry;\n private transcript?: TranscriptManager;\n\n constructor(\n config: PluginConfig,\n gatewayConfig?: GatewayConfig,\n modelRegistry?: ModelRegistry,\n transcript?: TranscriptManager\n ) {\n this.config = config;\n this.summariesDir = path.join(config.memoryDir, \"summaries\", \"hourly\");\n this.modelRegistry = modelRegistry ?? new ModelRegistry(config.memoryDir);\n this.transcript = transcript;\n\n // Initialize local LLM client with shared model registry\n this.localLlm = new LocalLlmClient(config, this.modelRegistry);\n\n // Initialize fallback client with gateway config\n this.fallbackLlm = new FallbackLlmClient(gatewayConfig, fallbackLlmRuntimeContextFromConfig(config));\n\n if (\n !gatewayConfig?.agents?.defaults?.model?.primary &&\n !resolveLocalLlmCapabilities(config).localLlm &&\n config.modelSource !== \"gateway\"\n ) {\n log.warn(\"no gateway default AI and local LLM disabled — hourly summarization disabled\");\n }\n }\n\n private get useGatewayModelSource(): boolean {\n return this.config.modelSource === \"gateway\";\n }\n\n private get shouldUseLocalLlm(): boolean {\n return resolveLocalLlmCapabilities(this.config).localLlm && !this.useGatewayModelSource;\n }\n\n private withGatewayAgent(\n options: import(\"./fallback-llm.js\").FallbackLlmOptions\n ): import(\"./fallback-llm.js\").FallbackLlmOptions {\n if (!this.useGatewayModelSource) return options;\n // Shared resolution (taskModelChain > gatewayAgentId) — gotcha #22. Issue #1365.\n return { ...options, ...gatewayTaskChainOptions(this.config) };\n }\n\n async initialize(): Promise<void> {\n await mkdir(this.summariesDir, { recursive: true });\n log.info(\"hourly summarizer initialized\");\n }\n\n private async summarySessionDir(sessionKey: string): Promise<string> {\n return resolveSafeStoragePath(this.summariesDir, encodeStoragePathSegment(sessionKey, \"session\"));\n }\n\n private async legacySummarySessionDir(sessionKey: string): Promise<string | null> {\n if (sessionKey.includes(\"\\0\")) return null;\n try {\n return await resolveSafeStoragePath(this.summariesDir, sessionKey);\n } catch {\n return null;\n }\n }\n\n private summaryDateString(hour: string): string {\n const dateStr = hour.slice(0, 10);\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(dateStr)) {\n throw new Error(`invalid hourly summary timestamp: ${hour}`);\n }\n return dateStr;\n }\n\n // Generate summary for a specific hour and session\n async generateSummary(\n sessionKey: string,\n hourStart: Date,\n entries: TranscriptEntry[]\n ): Promise<HourlySummary | null> {\n if (entries.length === 0) return null;\n\n // Format entries for the LLM\n const conversation = entries.map((e) => `[${e.role}] ${e.content}`).join(\"\\n\\n\");\n\n if (resolvePipelineProcessingCapabilities(this.config).hourlySummariesExtended) {\n const extended = await this.generateExtended(sessionKey, hourStart, conversation, entries);\n if (!extended) return null;\n const meta: HourlySummaryExtendedMeta = {\n userTurns: entries.filter((e) => e.role === \"user\").length,\n assistantTurns: entries.filter((e) => e.role === \"assistant\").length,\n toolCalls: extended._meta.toolCalls,\n toolCounts: extended._meta.toolCounts,\n };\n // Keep HourlySummary surface stable; encode \"topics\" as bullets for recall injection.\n const base: HourlySummary = {\n hour: hourStart.toISOString(),\n sessionKey,\n bullets: extended.topics.length > 0 ? extended.topics.slice(0, 5) : [\"(summary generated)\"],\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n const withExtras = base as any;\n withExtras._extended = extended;\n withExtras._extendedMeta = meta;\n return base;\n }\n\n const hourIso = hourStart.toISOString();\n const startTime = Date.now();\n\n if (this.config.backgroundGeneration) {\n try {\n const text = await completeBackgroundGeneration(this.config, [\n {\n role: \"system\",\n content:\n \"You are a conversation summarization system. Summarize the following conversation transcript into 3-5 concise bullet points.\\n\\nGuidelines:\\n- Focus on what was accomplished, decided, or discussed\\n- Include specific topics, projects, or entities mentioned\\n- Note any significant user requests or agent actions\\n- Keep bullets brief but informative (1-2 sentences each)\\n- Skip trivial greetings or meta-conversation\\n- Use present tense for ongoing work, past for completed items\\n\\nRespond with valid JSON only, matching this schema:\\n{\\\"bullets\\\": [\\\"bullet 1\\\", \\\"bullet 2\\\", \\\"bullet 3\\\"]}\",\n },\n { role: \"user\", content: `Summarize this conversation:\\n\\n${conversation}` },\n ]);\n const parsed = parseBackgroundGenerationJson(text, (value) => HourlySummarySchema.parse(value));\n if (parsed) {\n return {\n hour: hourIso,\n sessionKey,\n bullets: parsed.bullets,\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n }\n } catch {\n log.info(\"summary generation: background generation unavailable, continuing\");\n }\n }\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const localResult = await this.generateWithLocalLlm(conversation);\n if (localResult) {\n const durationMs = Date.now() - startTime;\n log.debug(`generated hourly summary for ${sessionKey} at ${hourIso} in ${durationMs}ms using local LLM`);\n return {\n hour: hourIso,\n sessionKey,\n bullets: localResult.bullets,\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n }\n // Local failed, fall back if allowed\n if (!this.config.localLlmFallback) {\n log.warn(\"summary generation: local LLM failed and fallback disabled\");\n return null;\n }\n log.info(\"summary generation: local LLM unavailable, falling back to gateway default AI\");\n } catch (err) {\n if (!this.config.localLlmFallback) {\n log.warn(\"summary generation: local LLM error and fallback disabled:\", err);\n return null;\n }\n log.info(\"summary generation: local LLM error, falling back to gateway default AI:\", err);\n }\n }\n\n // Fall back to gateway's default AI\n log.info(\"summary generation: falling back to gateway default AI\");\n\n try {\n const messages = [\n {\n role: \"system\" as const,\n content: `You are a conversation summarization system. Summarize the following conversation transcript into 3-5 concise bullet points.\n\nGuidelines:\n- Focus on what was accomplished, decided, or discussed\n- Include specific topics, projects, or entities mentioned\n- Note any significant user requests or agent actions\n- Keep bullets brief but informative (1-2 sentences each)\n- Skip trivial greetings or meta-conversation\n- Use present tense for ongoing work, past for completed items\n\nRespond with valid JSON matching this schema:\n{\n \"bullets\": [\"bullet 1\", \"bullet 2\", \"bullet 3\"]\n}`,\n },\n { role: \"user\" as const, content: `Summarize this conversation:\\n\\n${conversation}` },\n ];\n\n const result = await this.fallbackLlm.parseWithSchema(\n messages,\n HourlySummarySchema,\n this.withGatewayAgent({ temperature: 0.3, maxTokens: 8192 })\n );\n\n const durationMs = Date.now() - startTime;\n\n if (result) {\n log.debug(`generated hourly summary for ${sessionKey} at ${hourIso} in ${durationMs}ms via fallback`);\n return {\n hour: hourIso,\n sessionKey,\n bullets: result.bullets,\n turnCount: entries.length,\n generatedAt: new Date().toISOString(),\n };\n }\n\n log.warn(\"summary generation fallback returned no parsed output\");\n return null;\n } catch (err) {\n log.error(\"summary generation fallback failed\", err);\n return null;\n }\n }\n\n private async generateExtended(\n sessionKey: string,\n hourStart: Date,\n conversation: string,\n entries: TranscriptEntry[]\n ): Promise<(HourlySummaryExtendedResult & { _meta: HourlySummaryExtendedMeta }) | null> {\n const hourIso = hourStart.toISOString();\n const startTime = Date.now();\n\n const hourEnd = new Date(hourStart.getTime() + 60 * 60 * 1000);\n let toolCounts: Record<string, number> = {};\n if (this.config.hourlySummariesIncludeToolStats && this.transcript) {\n const uses = await this.transcript.readToolUse(sessionKey, hourStart, hourEnd);\n for (const u of uses) toolCounts[u.tool] = (toolCounts[u.tool] ?? 0) + 1;\n }\n\n const sys = `You are a conversation summarization system.\\n\\nSummarize the hour into structured sections.\\n\\nReturn valid JSON matching:\\n{\\n \\\"topics\\\": [\\\"...\\\"],\\n \\\"decisions\\\": [\\\"...\\\"],\\n \\\"actionItems\\\": [\\\"...\\\"],\\n \\\"rejected\\\": [\\\"...\\\"]\\n}\\n\\nGuidelines:\\n- Prefer concrete topics and decisions.\\n- Action items should be imperative.\\n- Rejected ideas are things that were explicitly discarded or reversed.\\n- If there are none for a section, return an empty array.\\n`;\n\n const toolStatsLine =\n Object.keys(toolCounts).length > 0\n ? `Tools used (counts): ${Object.entries(toolCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \")}\\n\\n`\n : \"\";\n const userTurns = entries.filter((e) => e.role === \"user\").length;\n const assistantTurns = entries.filter((e) => e.role === \"assistant\").length;\n const toolCalls = Object.values(toolCounts).reduce((a, b) => a + b, 0);\n const statsLine = `Stats: userTurns=${userTurns}, assistantTurns=${assistantTurns}, toolCalls=${toolCalls}\\n\\n`;\n\n const user = `Hour: ${hourIso}\\nSession: ${sessionKey}\\n\\n${statsLine}${toolStatsLine}Conversation:\\n${conversation}\\n`;\n\n // Try local LLM first if enabled\n if (this.shouldUseLocalLlm) {\n try {\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n const truncated =\n user.length > contextSizes.maxInputChars\n ? user.slice(0, contextSizes.maxInputChars) + \"\\n\\n[truncated]\"\n : user;\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"Output valid JSON only.\" },\n { role: \"user\", content: sys + \"\\n\\n\" + truncated },\n ],\n {\n temperature: 0.2,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"hourly_summary_extended\",\n priority: \"background\",\n }\n );\n if (response?.content) {\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n const result = HourlySummaryExtendedSchema.parse(parsed);\n log.debug(\n `generated extended hourly summary for ${sessionKey} at ${hourIso} in ${Date.now() - startTime}ms (local)`\n );\n return { ...result, _meta: { userTurns, assistantTurns, toolCalls, toolCounts } };\n } catch {\n // keep trying candidates\n }\n }\n }\n } catch (err) {\n if (!this.config.localLlmFallback) return null;\n log.info(\"extended summary: local failed, falling back:\", err);\n }\n }\n\n try {\n const result = await this.fallbackLlm.parseWithSchema(\n [\n { role: \"system\" as const, content: sys },\n { role: \"user\" as const, content: user },\n ],\n HourlySummaryExtendedSchema,\n this.withGatewayAgent({ temperature: 0.2, maxTokens: 2048 })\n );\n if (result) {\n log.debug(\n `generated extended hourly summary for ${sessionKey} at ${hourIso} in ${Date.now() - startTime}ms (fallback)`\n );\n return { ...result, _meta: { userTurns, assistantTurns, toolCalls, toolCounts } };\n }\n return null;\n } catch (err) {\n log.error(\"extended summary generation failed\", err);\n return null;\n }\n }\n\n /**\n * Generate summary using local LLM with JSON mode.\n * Uses dynamic context sizing based on model capabilities.\n */\n private async generateWithLocalLlm(conversation: string): Promise<HourlySummaryResult | null> {\n // Get dynamic context sizes based on model capabilities\n const contextSizes = this.modelRegistry.calculateContextSizes(\n this.config.localLlmModel,\n this.config.localLlmMaxContext\n );\n log.debug(`Summarizer model context: ${contextSizes.description}`);\n\n const maxConversationChars = contextSizes.maxInputChars;\n const truncatedConversation =\n conversation.length > maxConversationChars\n ? conversation.slice(0, maxConversationChars) + \"\\n\\n[truncated]\"\n : conversation;\n\n const instructions = `You are a conversation summarization system. Summarize the following conversation transcript into 3-5 concise bullet points.\n\nGuidelines:\n- Focus on what was accomplished, decided, or discussed\n- Include specific topics, projects, or entities mentioned\n- Note any significant user requests or agent actions\n- Keep bullets brief but informative (1-2 sentences each)\n- Skip trivial greetings or meta-conversation\n- Use present tense for ongoing work, past for completed items\n\nRespond with valid JSON matching this schema:\n{\n \"bullets\": [\"bullet 1\", \"bullet 2\", \"bullet 3\"]\n}`;\n\n const fullPrompt = `${instructions}\\n\\nConversation to summarize:\\n${truncatedConversation}`;\n\n const response = await this.localLlm.chatCompletion(\n [\n { role: \"system\", content: \"You are a conversation summarization system. Output valid JSON only.\" },\n { role: \"user\", content: fullPrompt },\n ],\n {\n temperature: 0.3,\n maxTokens: contextSizes.maxOutputTokens,\n operation: \"hourly_summary\",\n priority: \"background\",\n }\n );\n\n if (!response?.content) {\n return null;\n }\n\n try {\n // Parse JSON response\n const content = response.content.trim();\n for (const candidate of extractJsonCandidates(content)) {\n try {\n const parsed = JSON.parse(candidate);\n return HourlySummarySchema.parse(parsed);\n } catch {\n // keep trying candidates\n }\n }\n return null;\n } catch (err) {\n log.warn(\"local LLM summary: failed to parse JSON response:\", err);\n return null;\n }\n }\n\n // Save summary to file\n async saveSummary(summary: HourlySummary): Promise<void> {\n const sessionDir = await this.summarySessionDir(summary.sessionKey);\n await mkdir(sessionDir, { recursive: true });\n\n // Format date as YYYY-MM-DD for the filename\n const dateStr = this.summaryDateString(summary.hour);\n const filePath = await resolveSafeStoragePath(sessionDir, `${dateStr}.md`);\n\n // Format hour as HH:00 for display\n const hourStr = summary.hour.slice(11, 13);\n\n // Build markdown content\n const lines: string[] = [];\n\n // Check if file exists to append or create\n let existingContent = \"\";\n try {\n existingContent = await readFile(filePath, \"utf-8\");\n } catch {\n // File doesn't exist yet, will create new\n }\n\n // Check if this hour already exists (idempotent)\n const hourHeader = `## ${hourStr}:00`;\n if (existingContent.includes(hourHeader)) {\n // Replace existing hour section\n const headerMatch = new RegExp(`(^|\\\\n)${escapeRegExp(hourHeader)}\\\\n`).exec(existingContent);\n const sectionStart = headerMatch\n ? headerMatch.index + headerMatch[1].length\n : existingContent.indexOf(hourHeader);\n const nextHeaderPattern = /\\n## \\d{2}:00\\n/g;\n nextHeaderPattern.lastIndex = sectionStart + hourHeader.length;\n const nextHeader = nextHeaderPattern.exec(existingContent);\n const beforeHour = existingContent.slice(0, sectionStart);\n const afterHour = nextHeader ? existingContent.slice(nextHeader.index + 1) : \"\";\n const newSection = this.formatHourSection(summary, hourHeader);\n existingContent = beforeHour + newSection.trimEnd() + (afterHour ? \"\\n\\n\" + afterHour : \"\\n\");\n\n await writeFile(filePath, existingContent, \"utf-8\");\n log.debug(`updated hourly summary for ${summary.sessionKey} at ${hourStr}:00`);\n } else {\n // Append new hour section\n const newSection = this.formatHourSection(summary, hourHeader);\n\n if (existingContent) {\n // Add to existing file\n await writeFile(filePath, existingContent.trimEnd() + \"\\n\\n\" + newSection, \"utf-8\");\n } else {\n // Create new file with header\n const header = `# Hourly Summaries — ${dateStr}\\n\\n*Session: ${summary.sessionKey}*\\n`;\n await writeFile(filePath, header + \"\\n\" + newSection, \"utf-8\");\n }\n log.debug(`saved hourly summary for ${summary.sessionKey} at ${hourStr}:00`);\n }\n try {\n await upsertSummarySnapshot(this.config.memoryDir, summary);\n } catch (error) {\n log.warn(\n `hourly summarizer: failed to update summary snapshot for ${summary.sessionKey} (fail-open): ${String(error)}`\n );\n }\n }\n\n private formatHourSection(summary: HourlySummary, hourHeader: string): string {\n const ext = (summary as any)._extended as\n | (HourlySummaryExtendedResult & { _meta?: HourlySummaryExtendedMeta })\n | undefined;\n const meta = (summary as any)._extendedMeta as HourlySummaryExtendedMeta | undefined;\n const lines: string[] = [hourHeader, \"\"];\n\n if (resolvePipelineProcessingCapabilities(this.config).hourlySummariesExtended && ext) {\n lines.push(\"### Topics Discussed\");\n for (const t of ext.topics) lines.push(`- ${t}`);\n lines.push(\"\");\n lines.push(\"### Decisions Made\");\n for (const d of ext.decisions) lines.push(`- ${d}`);\n lines.push(\"\");\n lines.push(\"### Action Items\");\n for (const a of ext.actionItems) lines.push(`- ${a}`);\n lines.push(\"\");\n lines.push(\"### Rejected Ideas / Reversals\");\n for (const r of ext.rejected) lines.push(`- ${r}`);\n lines.push(\"\");\n if (meta && Object.keys(meta.toolCounts).length > 0) {\n lines.push(\"### Tools Used\");\n const top = Object.entries(meta.toolCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 12);\n for (const [name, count] of top) lines.push(`- ${name}: ${count}`);\n lines.push(\"\");\n }\n lines.push(\"### Stats\");\n lines.push(`- Turns: ${summary.turnCount}`);\n if (meta) {\n lines.push(`- User turns: ${meta.userTurns}`);\n lines.push(`- Assistant turns: ${meta.assistantTurns}`);\n lines.push(`- Tool calls: ${meta.toolCalls}`);\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n }\n\n for (const bullet of summary.bullets) lines.push(`- ${bullet}`);\n lines.push(` *(${summary.turnCount} turns)*`);\n lines.push(\"\");\n return lines.join(\"\\n\");\n }\n\n // Read recent summaries for recall injection\n async readRecent(sessionKey: string, hours: number): Promise<HourlySummary[]> {\n try {\n const cutoffTime = Date.now() - hours * 60 * 60 * 1000;\n\n const snapshot = await readSummarySnapshot(this.config.memoryDir, sessionKey);\n if (snapshot) {\n return snapshot\n .filter((s) => new Date(s.hour).getTime() >= cutoffTime)\n .sort((a, b) => new Date(b.hour).getTime() - new Date(a.hour).getTime());\n }\n\n const summaries: HourlySummary[] = [];\n const encodedDir = await this.summarySessionDir(sessionKey);\n const legacyDir = await this.legacySummarySessionDir(sessionKey);\n const seenDirs = new Set<string>();\n\n for (const sessionDir of [encodedDir, legacyDir]) {\n if (!sessionDir || seenDirs.has(sessionDir)) continue;\n seenDirs.add(sessionDir);\n const parsed = await this.readSummaryDir(sessionDir, sessionKey);\n summaries.push(...parsed);\n }\n\n const byHour = new Map<string, HourlySummary>();\n for (const summary of summaries) {\n if (!byHour.has(summary.hour)) byHour.set(summary.hour, summary);\n }\n\n const sortedSummaries = Array.from(byHour.values()).sort(\n (a, b) => new Date(b.hour).getTime() - new Date(a.hour).getTime()\n );\n\n // Filter to recent hours while materializing the full parsed history.\n const recent = sortedSummaries.filter((s) => new Date(s.hour).getTime() >= cutoffTime);\n\n if (sortedSummaries.length > 0) {\n try {\n await writeSummarySnapshot(this.config.memoryDir, sessionKey, sortedSummaries);\n } catch (error) {\n log.warn(\n `hourly summarizer: failed to materialize summary snapshot for ${sessionKey} (fail-open): ${String(error)}`\n );\n }\n }\n\n return recent;\n } catch {\n // Directory doesn't exist or error reading\n return [];\n }\n }\n\n private async readSummaryDir(sessionDir: string, sessionKey: string): Promise<HourlySummary[]> {\n let files: string[];\n try {\n files = await readdir(sessionDir);\n } catch {\n return [];\n }\n\n const summaries: HourlySummary[] = [];\n const mdFiles = files.filter((f) => f.endsWith(\".md\"));\n for (const file of mdFiles) {\n const filePath = await resolveSafeStoragePath(sessionDir, file).catch(() => null);\n if (filePath === null) continue;\n\n try {\n const content = await readFile(filePath, \"utf-8\");\n summaries.push(...this.parseSummaryFile(content, sessionKey, file));\n } catch {\n // Skip unreadable summary files.\n }\n }\n\n return summaries;\n }\n\n private parseSummaryFile(content: string, sessionKey: string, filename: string): HourlySummary[] {\n const summaries: HourlySummary[] = [];\n\n // Extract date from filename (YYYY-MM-DD.md)\n const dateMatch = filename.match(/^(\\d{4}-\\d{2}-\\d{2})\\.md$/);\n if (!dateMatch) return summaries;\n const dateStr = dateMatch[1];\n\n // Split by hour sections\n const hourSections = content.split(/\\n## (\\d{2}):00\\n/);\n\n // First element is the header, skip it\n for (let i = 1; i < hourSections.length; i += 2) {\n const hourStr = hourSections[i];\n const sectionContent = hourSections[i + 1] || \"\";\n\n // Parse bullets\n const bullets: string[] = [];\n const lines = sectionContent.split(\"\\n\");\n let turnCount = 0;\n\n let inTopics = false;\n let sawExtendedTopicsHeader = false;\n for (const line of lines) {\n if (line.startsWith(\"### Topics\")) {\n inTopics = true;\n sawExtendedTopicsHeader = true;\n continue;\n }\n if (line.startsWith(\"### \") && !line.startsWith(\"### Topics\")) {\n inTopics = false;\n }\n const bulletMatch = line.match(/^- (.+)$/);\n if (bulletMatch) {\n // For extended format, only treat topic bullets as recall bullets.\n if (!sawExtendedTopicsHeader || inTopics) bullets.push(bulletMatch[1]);\n }\n const turnMatch = line.match(/\\((\\d+) turns?\\)/);\n if (turnMatch) turnCount = parseInt(turnMatch[1], 10);\n }\n\n if (bullets.length > 0) {\n summaries.push({\n hour: `${dateStr}T${hourStr}:00:00.000Z`,\n sessionKey,\n bullets,\n turnCount,\n generatedAt: \"\", // Not stored in file, not needed for recall\n });\n }\n }\n\n return summaries;\n }\n\n // Format summaries for recall injection\n formatForRecall(summaries: HourlySummary[], maxCount: number): string {\n if (summaries.length === 0) return \"\";\n\n const limited = summaries.slice(0, maxCount);\n const lines: string[] = [`## Recent Activity (last ${limited.length} hours)`];\n\n for (const summary of limited) {\n const hourStr = summary.hour.slice(11, 16); // HH:MM\n for (const bullet of summary.bullets) {\n lines.push(`- ${hourStr}: ${bullet}`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n // Main entry point for cron job\n async runHourly(): Promise<HourlySummarizerRunStats> {\n log.debug(\"running hourly summary generation\");\n\n // Get active sessions from transcript. The scan outcome is kept LOCAL to\n // this invocation (review round 2): shared instance state would let two\n // concurrent runHourly calls cross-report each other's timestamps.\n const scan = await this.getActiveSessions();\n const sessions = scan.sessionKeys;\n let sessionsWithEntries = 0;\n let summariesWritten = 0;\n\n for (const sessionKey of sessions) {\n // Calculate the hour we want to summarize (previous hour)\n const now = new Date();\n const hourStart = new Date(now.getTime() - 60 * 60 * 1000);\n hourStart.setMinutes(0, 0, 0);\n const hourEnd = new Date(hourStart.getTime() + 60 * 60 * 1000);\n\n // Get entries for this session in the target hour\n const entries = await this.getTranscriptEntries(sessionKey, hourStart, hourEnd);\n\n if (entries.length === 0) {\n log.debug(`no transcript entries for ${sessionKey} at ${hourStart.toISOString()}`);\n continue;\n }\n sessionsWithEntries += 1;\n\n // Generate and save summary\n const summary = await this.generateSummary(sessionKey, hourStart, entries);\n if (summary) {\n await this.saveSummary(summary);\n summariesWritten += 1;\n log.info(`generated hourly summary for ${sessionKey} (${entries.length} turns)`);\n }\n }\n\n return {\n sessionsConsidered: sessions.length,\n sessionsWithEntries,\n summariesWritten,\n // Staleness signal (issue #2783): newest entry across the whole\n // store, from the same scan getActiveSessions already performs.\n staleStore:\n scan.newestEntryTimestamp !== null &&\n Date.now() - new Date(scan.newestEntryTimestamp).getTime() > STALE_STORE_MS,\n newestEntryTimestamp: scan.newestEntryTimestamp,\n scanFailed: scan.scanFailed,\n };\n }\n\n // Get list of active sessions from the transcript directory, plus the\n // scan bookkeeping runHourly reports: newest entry timestamp (staleness\n // signal) and whether the scan itself FAILED. A failed scan must not be\n // reported as an empty store — those are different incidents (review\n // round 2).\n private async getActiveSessions(): Promise<{\n sessionKeys: string[];\n newestEntryTimestamp: string | null;\n scanFailed: boolean;\n }> {\n const transcriptDir = await resolveSafeStoragePath(this.config.memoryDir, \"transcripts\").catch(() => null);\n if (transcriptDir === null) {\n return { sessionKeys: [], newestEntryTimestamp: null, scanFailed: false };\n }\n\n const sessionKeys = new Set<string>();\n let newestEntryTimestamp: string | null = null;\n let newestEntryTimeMs = Number.NaN;\n let fileReadFailed = false;\n const collect = async (transcriptPath: string): Promise<void> => {\n try {\n const raw = await readFile(transcriptPath, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as TranscriptEntry;\n if (typeof entry.sessionKey === \"string\" && entry.sessionKey.length > 0) {\n sessionKeys.add(entry.sessionKey);\n }\n // Compare parsed epoch values, never strings: a malformed\n // timestamp in a hand-edited file must not poison the staleness\n // signal with a lexically-maximal garbage value (review).\n if (typeof entry.timestamp === \"string\") {\n const timeMs = new Date(entry.timestamp).getTime();\n if (Number.isFinite(timeMs) && (Number.isNaN(newestEntryTimeMs) || timeMs > newestEntryTimeMs)) {\n newestEntryTimeMs = timeMs;\n newestEntryTimestamp = entry.timestamp;\n }\n }\n } catch {\n // ignore malformed transcript lines\n }\n }\n } catch (err) {\n // ENOENT is a concurrently-deleted file — ignore. Any other read\n // failure (permissions, I/O) means the store is partially UNREADABLE:\n // mark the scan failed so the caller warns instead of reporting an\n // empty store (review round 3).\n if ((err as NodeJS.ErrnoException)?.code !== \"ENOENT\") {\n fileReadFailed = true;\n }\n }\n };\n\n try {\n const typeEntries = await readdir(transcriptDir, { withFileTypes: true });\n for (const typeEnt of typeEntries) {\n if (!typeEnt.isDirectory()) continue;\n const typeDir = await resolveSafeStoragePath(transcriptDir, typeEnt.name).catch(() => null);\n if (typeDir === null) continue;\n const idEntries = await readdir(typeDir, { withFileTypes: true });\n for (const idEnt of idEntries) {\n if (!idEnt.isDirectory()) continue;\n const chanDir = await resolveSafeStoragePath(typeDir, idEnt.name).catch(() => null);\n if (chanDir === null) continue;\n const files = (await readdir(chanDir)).filter((f) => f.endsWith(\".jsonl\")).sort();\n for (const file of files) {\n const transcriptPath = await resolveSafeStoragePath(chanDir, file).catch(() => null);\n if (transcriptPath === null) continue;\n await collect(transcriptPath);\n }\n }\n }\n return {\n sessionKeys: Array.from(sessionKeys),\n newestEntryTimestamp,\n scanFailed: fileReadFailed,\n };\n } catch (err) {\n // ENOENT on the root is a never-written store — an EMPTY store, not a\n // scan failure (those are different incidents).\n const code = (err as NodeJS.ErrnoException)?.code;\n if (code === \"ENOENT\") {\n return { sessionKeys: [], newestEntryTimestamp: null, scanFailed: false };\n }\n log.warn(`transcript scan failed: ${err}`);\n return { sessionKeys: [], newestEntryTimestamp: null, scanFailed: true };\n }\n }\n\n // Get transcript entries for a session within a time range\n private async getTranscriptEntries(sessionKey: string, startTime: Date, endTime: Date): Promise<TranscriptEntry[]> {\n // Shared session-identity layer (issue #1496, rule #22). Arbitrary keys\n // route to `session/<hash>`; legacy `agent:<id>:...` keep their paths. The\n // shared helper also supplies the read-back-only candidate dirs (mirrors\n // TranscriptManager) so legacy `other/default` AND old `parts.length >= 3`\n // data stays discoverable here too.\n const paths = sessionStoragePaths(sessionKey);\n\n try {\n const transcriptRoot = path.join(this.config.memoryDir, \"transcripts\");\n const candidateDirs = new Set(\n [paths.dir, paths.alternateDir, paths.legacyDir, ...paths.readbackDirs].filter(\n (dir): dir is string => typeof dir === \"string\" && dir.length > 0\n )\n );\n const entries: TranscriptEntry[] = [];\n // Dedup identical raw rows that a partially-applied migration may have\n // left in both the primary dir and a read-back dir (issue #1496, cursor\n // review). Exact raw JSONL line is the stable identity.\n const seenRawLines = new Set<string>();\n\n // Read all daily transcript files in the directory\n for (const candidateDir of candidateDirs) {\n const transcriptDir = await resolveSafeStoragePath(transcriptRoot, candidateDir).catch(() => null);\n if (transcriptDir === null) continue;\n\n const files = await readdir(transcriptDir).catch(() => []);\n for (const file of files) {\n if (!file.endsWith(\".jsonl\")) continue;\n\n const transcriptPath = await resolveSafeStoragePath(transcriptDir, file).catch(() => null);\n if (transcriptPath === null) continue;\n\n try {\n const content = await readFile(transcriptPath, \"utf-8\");\n const lines = content.trim().split(\"\\n\");\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as TranscriptEntry;\n const entryTime = new Date(entry.timestamp).getTime();\n\n if (\n entry.sessionKey === sessionKey &&\n entryTime >= startTime.getTime() &&\n entryTime < endTime.getTime() &&\n !seenRawLines.has(line)\n ) {\n seenRawLines.add(line);\n entries.push(entry);\n }\n } catch {\n // Skip malformed lines\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return entries;\n } catch {\n return [];\n }\n }\n}\n"],"mappings":"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","names":[]}