@jungjaehoon/mama-core 2.4.1 → 4.1.0

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 (378) hide show
  1. package/README.md +76 -239
  2. package/db/migrations/030-case-first-memory-substrate.sql +13 -98
  3. package/db/migrations/034-add-connector-event-scope-columns.sql +9 -13
  4. package/db/migrations/039-add-connector-event-operator-ingest-seq.sql +9 -95
  5. package/db/migrations/062-refresh-connector-event-sequences.sql +9 -113
  6. package/db/migrations/063-refresh-legacy-connector-event-updates.sql +9 -32
  7. package/db/migrations/067-add-connector-event-source-entity-id.sql +9 -13
  8. package/db/migrations/069-create-registry-nodes.sql +52 -0
  9. package/db/migrations/070-record-identity.sql +35 -0
  10. package/db/migrations/071-service-operation-origins.sql +187 -0
  11. package/db/migrations/072-observation-versions.sql +29 -0
  12. package/db/migrations/073-registry-corrections.sql +45 -0
  13. package/db/migrations/074-work-graph-ref-kinds.sql +39 -0
  14. package/db/migrations/075-agent-judgments.sql +58 -0
  15. package/db/migrations/076-scoped-checkpoint-bindings.sql +15 -0
  16. package/db/migrations/077-legacy-record-kind.sql +6 -0
  17. package/db/migrations/078-source-ingest-commands.sql +18 -0
  18. package/db/migrations/079-twin-edge-relations.sql +43 -0
  19. package/db/migrations/080-restore-duration-days.sql +7 -0
  20. package/db/migrations/081-mailbox.sql +61 -0
  21. package/db/migrations/082-commitments-row-id.sql +12 -0
  22. package/db/migrations/083-observation-is-the-evidence.sql +49 -0
  23. package/db/migrations/084-scope-kind-is-not-the-cores-to-list.sql +34 -0
  24. package/db/migrations/085-a-migration-has-a-source.sql +37 -0
  25. package/db/migrations/086-the-mailbox-is-generic.sql +110 -0
  26. package/db/migrations/087-mailbox-payload.sql +5 -0
  27. package/db/migrations/088-native-input-journal.sql +14 -0
  28. package/db/migrations/089-native-turn-receipt-lookup.sql +3 -0
  29. package/db/migrations/090-model-run-native-inputs.sql +29 -0
  30. package/db/migrations/091-native-turn-results.sql +11 -0
  31. package/db/migrations/092-restore-decision-fts.sql +34 -0
  32. package/db/migrations/093-native-turn-primary-kind.sql +14 -0
  33. package/db/migrations/094-commitment-run-provenance.sql +9 -0
  34. package/db/migrations/095-model-run-native-input-identity.sql +39 -0
  35. package/db/migrations/096-drop-connector-event-index-fts.sql +9 -0
  36. package/db/migrations/097-native-input-json-validity.sql +37 -0
  37. package/db/migrations/098-workflow-memory-kind.sql +105 -0
  38. package/db/migrations/099-commitment-revision-graph.sql +2 -0
  39. package/dist/action-contracts.d.ts +212 -0
  40. package/dist/action-contracts.js +10 -0
  41. package/dist/api/catalog.d.ts +118 -0
  42. package/dist/api/catalog.js +1756 -0
  43. package/dist/api/dispatch.d.ts +76 -0
  44. package/dist/api/dispatch.js +372 -0
  45. package/dist/canonicalize.d.ts +2 -2
  46. package/dist/canonicalize.js +3 -3
  47. package/dist/client/client.d.ts +33 -0
  48. package/dist/client/client.js +123 -0
  49. package/dist/client/ipc.d.ts +81 -0
  50. package/dist/client/ipc.js +314 -0
  51. package/dist/db-adapter/base-adapter.d.ts +6 -66
  52. package/dist/db-adapter/base-adapter.js +6 -6
  53. package/dist/db-adapter/index.d.ts +5 -5
  54. package/dist/db-adapter/index.js +2 -5
  55. package/dist/db-adapter/node-sqlite-adapter.d.ts +85 -15
  56. package/dist/db-adapter/node-sqlite-adapter.js +1985 -570
  57. package/dist/db-manager.d.ts +53 -97
  58. package/dist/db-manager.js +121 -603
  59. package/dist/embedding/embedder.d.ts +132 -0
  60. package/dist/embedding/embedder.js +299 -0
  61. package/dist/identity/principal-repository.d.ts +2 -2
  62. package/dist/index.d.ts +43 -58
  63. package/dist/index.js +97 -145
  64. package/dist/{context-compile/channel-grant.d.ts → knowledge/access.d.ts} +12 -17
  65. package/dist/knowledge/access.js +663 -0
  66. package/dist/knowledge/case-errors.d.ts +31 -0
  67. package/dist/knowledge/case-errors.js +40 -0
  68. package/dist/{cases/search-rollup.d.ts → knowledge/case-search-rollup.d.ts} +5 -4
  69. package/dist/{cases/search-rollup.js → knowledge/case-search-rollup.js} +6 -8
  70. package/dist/{cases/store.d.ts → knowledge/case-store.d.ts} +3 -6
  71. package/dist/{cases/store.js → knowledge/case-store.js} +7 -42
  72. package/dist/{cases/timeline-range.d.ts → knowledge/case-timeline-range.d.ts} +3 -3
  73. package/dist/{cases/timeline-range.js → knowledge/case-timeline-range.js} +47 -25
  74. package/dist/{cases/types.d.ts → knowledge/case-types.d.ts} +8 -2
  75. package/dist/{cases/types.js → knowledge/case-types.js} +1 -1
  76. package/dist/knowledge/commitment-revision-migration.d.ts +4 -0
  77. package/dist/knowledge/commitment-revision-migration.js +50 -0
  78. package/dist/knowledge/commitments.d.ts +192 -0
  79. package/dist/knowledge/commitments.js +386 -0
  80. package/dist/knowledge/decision-edges.d.ts +70 -0
  81. package/dist/knowledge/decision-edges.js +123 -0
  82. package/dist/{agent-graph/types.d.ts → knowledge/graph-query.d.ts} +80 -70
  83. package/dist/knowledge/graph-query.js +1585 -0
  84. package/dist/knowledge/identity.d.ts +16 -0
  85. package/dist/knowledge/identity.js +22 -0
  86. package/dist/knowledge/index.d.ts +47 -0
  87. package/dist/knowledge/index.js +90 -0
  88. package/dist/knowledge/judgment-edge.d.ts +6 -0
  89. package/dist/knowledge/judgment-edge.js +22 -0
  90. package/dist/knowledge/judgments.d.ts +118 -0
  91. package/dist/knowledge/judgments.js +802 -0
  92. package/dist/knowledge/observations.d.ts +160 -0
  93. package/dist/knowledge/observations.js +449 -0
  94. package/dist/knowledge/question-type.d.ts +34 -0
  95. package/dist/knowledge/question-type.js +70 -0
  96. package/dist/{search → knowledge}/ranker-features.js +1 -1
  97. package/dist/{search → knowledge}/search-quality.d.ts +0 -1
  98. package/dist/knowledge/search.d.ts +38 -0
  99. package/dist/knowledge/search.js +91 -0
  100. package/dist/knowledge/source-ingest.d.ts +65 -0
  101. package/dist/knowledge/source-ingest.js +174 -0
  102. package/dist/{edges/types.d.ts → knowledge/twin-edge-types.d.ts} +31 -4
  103. package/dist/{edges/types.js → knowledge/twin-edge-types.js} +13 -2
  104. package/dist/knowledge/work-dates.d.ts +49 -0
  105. package/dist/knowledge/work-dates.js +120 -0
  106. package/dist/mama-api.d.ts +114 -778
  107. package/dist/mama-api.js +313 -2461
  108. package/dist/memory/api.d.ts +264 -24
  109. package/dist/memory/api.js +1633 -843
  110. package/dist/memory/bootstrap-builder.d.ts +2 -1
  111. package/dist/memory/bootstrap-builder.js +5 -5
  112. package/dist/memory/channel-summary-state-store.d.ts +3 -2
  113. package/dist/memory/channel-summary-state-store.js +53 -51
  114. package/dist/memory/channel-summary-store.d.ts +5 -3
  115. package/dist/memory/channel-summary-store.js +3 -8
  116. package/dist/memory/dashboard-read.d.ts +46 -0
  117. package/dist/memory/dashboard-read.js +94 -0
  118. package/dist/memory/event-store.d.ts +3 -3
  119. package/dist/memory/event-store.js +3 -10
  120. package/dist/memory/finding-store.d.ts +3 -2
  121. package/dist/memory/finding-store.js +2 -7
  122. package/dist/memory/graph-read.d.ts +52 -0
  123. package/dist/memory/graph-read.js +130 -0
  124. package/dist/memory/judgment-types.d.ts +394 -0
  125. package/dist/memory/judgment-types.js +16 -0
  126. package/dist/memory/provenance-audit.d.ts +5 -2
  127. package/dist/memory/provenance-audit.js +8 -14
  128. package/dist/memory/provenance-live.d.ts +141 -0
  129. package/dist/memory/provenance-live.js +409 -0
  130. package/dist/memory/provenance-query.d.ts +5 -4
  131. package/dist/memory/provenance-query.js +21 -29
  132. package/dist/memory/provenance-resolver.d.ts +191 -0
  133. package/dist/memory/provenance-resolver.js +155 -0
  134. package/dist/memory/provenance.d.ts +1 -11
  135. package/dist/memory/provenance.js +2 -33
  136. package/dist/memory/recall-sanitize.d.ts +55 -0
  137. package/dist/memory/recall-sanitize.js +144 -0
  138. package/dist/memory/secret-filter.d.ts +32 -0
  139. package/dist/memory/secret-filter.js +126 -0
  140. package/dist/memory/truth-store.d.ts +2 -1
  141. package/dist/memory/truth-store.js +1 -4
  142. package/dist/memory/types.d.ts +74 -24
  143. package/dist/memory/types.js +75 -5
  144. package/dist/memory/write-adapters.d.ts +98 -0
  145. package/dist/memory/write-adapters.js +242 -0
  146. package/dist/operations/owner-action-effects.d.ts +53 -0
  147. package/dist/operations/owner-action-effects.js +96 -0
  148. package/dist/provenance/source-ref.d.ts +1 -1
  149. package/dist/provenance/source-ref.js +0 -2
  150. package/dist/registry/corrections.d.ts +31 -0
  151. package/dist/registry/corrections.js +332 -0
  152. package/dist/registry/record-identity.d.ts +49 -0
  153. package/dist/registry/record-identity.js +133 -0
  154. package/dist/registry/store.d.ts +101 -0
  155. package/dist/registry/store.js +395 -0
  156. package/dist/registry/types.d.ts +28 -0
  157. package/dist/registry/types.js +5 -0
  158. package/dist/relevance-scorer.js +2 -2
  159. package/dist/runtime/agent-event-bus.d.ts +50 -0
  160. package/dist/runtime/agent-event-bus.js +101 -0
  161. package/dist/runtime/drivers/claude-cli-wrapper.d.ts +152 -0
  162. package/dist/runtime/drivers/claude-cli-wrapper.js +375 -0
  163. package/dist/runtime/drivers/claude-effort.d.ts +4 -0
  164. package/dist/runtime/drivers/claude-effort.js +16 -0
  165. package/dist/runtime/drivers/cli-arg-redaction.d.ts +2 -0
  166. package/dist/runtime/drivers/cli-arg-redaction.js +18 -0
  167. package/dist/runtime/drivers/cli-secret-redaction.d.ts +17 -0
  168. package/dist/runtime/drivers/cli-secret-redaction.js +126 -0
  169. package/dist/runtime/drivers/codex-app-server-process.d.ts +277 -0
  170. package/dist/runtime/drivers/codex-app-server-process.js +2342 -0
  171. package/dist/runtime/drivers/codex-auxiliary-tools.d.ts +17 -0
  172. package/dist/runtime/drivers/codex-auxiliary-tools.js +267 -0
  173. package/dist/runtime/drivers/codex-home.d.ts +20 -0
  174. package/dist/runtime/drivers/codex-home.js +674 -0
  175. package/dist/runtime/drivers/codex-thread-registry.d.ts +63 -0
  176. package/dist/runtime/drivers/codex-thread-registry.js +433 -0
  177. package/dist/runtime/drivers/persistent-cli-adapter.d.ts +160 -0
  178. package/dist/runtime/drivers/persistent-cli-adapter.js +396 -0
  179. package/dist/runtime/drivers/persistent-cli-process.d.ts +425 -0
  180. package/dist/runtime/drivers/persistent-cli-process.js +1529 -0
  181. package/dist/runtime/drivers/types.d.ts +456 -0
  182. package/dist/runtime/drivers/types.js +110 -0
  183. package/dist/runtime/mailbox.d.ts +223 -0
  184. package/dist/runtime/mailbox.js +582 -0
  185. package/dist/runtime/model-run-store.d.ts +28 -0
  186. package/dist/{model-runs/store.js → runtime/model-run-store.js} +81 -41
  187. package/dist/{model-runs/types.d.ts → runtime/model-run-types.d.ts} +33 -4
  188. package/dist/{model-runs/types.js → runtime/model-run-types.js} +1 -1
  189. package/dist/runtime/native-effect-observer.d.ts +22 -0
  190. package/dist/runtime/native-effect-observer.js +103 -0
  191. package/dist/runtime/native-input-journal.d.ts +46 -0
  192. package/dist/runtime/native-input-journal.js +308 -0
  193. package/dist/runtime/native-prompt.d.ts +118 -0
  194. package/dist/runtime/native-prompt.js +496 -0
  195. package/dist/runtime/native-session.d.ts +10 -0
  196. package/dist/{agent-graph/index.js → runtime/native-session.js} +9 -6
  197. package/dist/runtime/native-tool-trace-observer.d.ts +5 -0
  198. package/dist/runtime/native-tool-trace-observer.js +65 -0
  199. package/dist/runtime/native-turn.d.ts +272 -0
  200. package/dist/runtime/native-turn.js +1041 -0
  201. package/dist/runtime/operations.d.ts +236 -0
  202. package/dist/runtime/operations.js +565 -0
  203. package/dist/runtime/post-tool-handler.d.ts +74 -0
  204. package/dist/runtime/post-tool-handler.js +137 -0
  205. package/dist/runtime/prompt-layers.d.ts +126 -0
  206. package/dist/runtime/prompt-layers.js +239 -0
  207. package/dist/runtime/runtime-process.d.ts +102 -0
  208. package/dist/runtime/runtime-process.js +206 -0
  209. package/dist/runtime/runtime.d.ts +278 -0
  210. package/dist/runtime/runtime.js +563 -0
  211. package/dist/runtime/session-pool.d.ts +176 -0
  212. package/dist/runtime/session-pool.js +369 -0
  213. package/dist/runtime/stimulus-payload.d.ts +5 -0
  214. package/dist/runtime/stimulus-payload.js +50 -0
  215. package/dist/runtime/subagent-bridge.d.ts +24 -0
  216. package/dist/{agent-graph/types.js → runtime/subagent-bridge.js} +1 -1
  217. package/dist/runtime/text-completion.d.ts +22 -0
  218. package/dist/{agent-situation/types.js → runtime/text-completion.js} +1 -1
  219. package/dist/runtime/token-estimator.d.ts +25 -0
  220. package/dist/runtime/token-estimator.js +75 -0
  221. package/dist/runtime/tool-trace-store.d.ts +22 -0
  222. package/dist/{model-runs → runtime}/tool-trace-store.js +46 -27
  223. package/dist/runtime/trace-summary.d.ts +5 -0
  224. package/dist/runtime/trace-summary.js +74 -0
  225. package/dist/runtime/turn-text.d.ts +23 -0
  226. package/dist/runtime/turn-text.js +41 -0
  227. package/dist/storage/database.d.ts +67 -0
  228. package/dist/storage/database.js +158 -0
  229. package/package.json +20 -34
  230. package/dist/agent-graph/alias-write.d.ts +0 -3
  231. package/dist/agent-graph/alias-write.js +0 -234
  232. package/dist/agent-graph/entity-resolve.d.ts +0 -3
  233. package/dist/agent-graph/entity-resolve.js +0 -271
  234. package/dist/agent-graph/errors.d.ts +0 -4
  235. package/dist/agent-graph/errors.js +0 -11
  236. package/dist/agent-graph/graph-query.d.ts +0 -5
  237. package/dist/agent-graph/graph-query.js +0 -360
  238. package/dist/agent-graph/index.d.ts +0 -6
  239. package/dist/agent-situation/builder.d.ts +0 -8
  240. package/dist/agent-situation/builder.js +0 -239
  241. package/dist/agent-situation/cache-key.d.ts +0 -4
  242. package/dist/agent-situation/cache-key.js +0 -64
  243. package/dist/agent-situation/index.d.ts +0 -7
  244. package/dist/agent-situation/index.js +0 -28
  245. package/dist/agent-situation/packet-store.d.ts +0 -27
  246. package/dist/agent-situation/packet-store.js +0 -228
  247. package/dist/agent-situation/ranking-policy.d.ts +0 -18
  248. package/dist/agent-situation/ranking-policy.js +0 -75
  249. package/dist/agent-situation/source-readers.d.ts +0 -52
  250. package/dist/agent-situation/source-readers.js +0 -300
  251. package/dist/agent-situation/types.d.ts +0 -195
  252. package/dist/cases/wiki-page-index.d.ts +0 -37
  253. package/dist/cases/wiki-page-index.js +0 -201
  254. package/dist/config-loader.d.ts +0 -68
  255. package/dist/config-loader.js +0 -239
  256. package/dist/connectors/event-index.d.ts +0 -24
  257. package/dist/connectors/event-index.js +0 -245
  258. package/dist/connectors/raw-query.d.ts +0 -40
  259. package/dist/connectors/raw-query.js +0 -412
  260. package/dist/connectors/types.d.ts +0 -117
  261. package/dist/connectors/types.js +0 -3
  262. package/dist/context-compile/boundary-defaults.d.ts +0 -12
  263. package/dist/context-compile/boundary-defaults.js +0 -105
  264. package/dist/context-compile/channel-grant.js +0 -66
  265. package/dist/context-compile/compiler-policy.d.ts +0 -39
  266. package/dist/context-compile/compiler-policy.js +0 -147
  267. package/dist/context-compile/compiler.d.ts +0 -18
  268. package/dist/context-compile/compiler.js +0 -404
  269. package/dist/context-compile/index.d.ts +0 -10
  270. package/dist/context-compile/index.js +0 -26
  271. package/dist/context-compile/packet-store.d.ts +0 -8
  272. package/dist/context-compile/packet-store.js +0 -239
  273. package/dist/context-compile/ref.d.ts +0 -7
  274. package/dist/context-compile/ref.js +0 -102
  275. package/dist/context-compile/source-readers.d.ts +0 -70
  276. package/dist/context-compile/source-readers.js +0 -840
  277. package/dist/context-compile/types.d.ts +0 -155
  278. package/dist/context-compile/types.js +0 -11
  279. package/dist/context-compile/visibility.d.ts +0 -21
  280. package/dist/context-compile/visibility.js +0 -224
  281. package/dist/decision-tracker.d.ts +0 -206
  282. package/dist/decision-tracker.js +0 -481
  283. package/dist/edges/ref-validation.d.ts +0 -7
  284. package/dist/edges/ref-validation.js +0 -321
  285. package/dist/edges/store.d.ts +0 -8
  286. package/dist/edges/store.js +0 -129
  287. package/dist/embedding-client.d.ts +0 -28
  288. package/dist/embedding-client.js +0 -53
  289. package/dist/embedding-server/index.d.ts +0 -67
  290. package/dist/embedding-server/index.js +0 -405
  291. package/dist/embedding-server/mobile/auth.d.ts +0 -44
  292. package/dist/embedding-server/mobile/auth.js +0 -150
  293. package/dist/embedding-server/mobile/daemon.d.ts +0 -129
  294. package/dist/embedding-server/mobile/daemon.js +0 -313
  295. package/dist/embedding-server/mobile/output-parser.d.ts +0 -115
  296. package/dist/embedding-server/mobile/output-parser.js +0 -241
  297. package/dist/embedding-server/mobile/session-api.d.ts +0 -57
  298. package/dist/embedding-server/mobile/session-api.js +0 -261
  299. package/dist/embedding-server/mobile/session-manager.d.ts +0 -138
  300. package/dist/embedding-server/mobile/session-manager.js +0 -378
  301. package/dist/embedding-server/mobile/websocket-handler.d.ts +0 -137
  302. package/dist/embedding-server/mobile/websocket-handler.js +0 -486
  303. package/dist/embeddings.d.ts +0 -68
  304. package/dist/embeddings.js +0 -244
  305. package/dist/entities/audit-metrics.d.ts +0 -68
  306. package/dist/entities/audit-metrics.js +0 -124
  307. package/dist/entities/candidate-generator.d.ts +0 -8
  308. package/dist/entities/candidate-generator.js +0 -24
  309. package/dist/entities/entity-linked-decision-counts.d.ts +0 -2
  310. package/dist/entities/entity-linked-decision-counts.js +0 -29
  311. package/dist/entities/entity-list.d.ts +0 -22
  312. package/dist/entities/entity-list.js +0 -3
  313. package/dist/entities/entity-orphan-list.d.ts +0 -17
  314. package/dist/entities/entity-orphan-list.js +0 -3
  315. package/dist/entities/entity-search.d.ts +0 -20
  316. package/dist/entities/entity-search.js +0 -3
  317. package/dist/entities/errors.d.ts +0 -55
  318. package/dist/entities/errors.js +0 -100
  319. package/dist/entities/lineage-store.d.ts +0 -28
  320. package/dist/entities/lineage-store.js +0 -204
  321. package/dist/entities/normalization.d.ts +0 -14
  322. package/dist/entities/normalization.js +0 -63
  323. package/dist/entities/policy-store.d.ts +0 -8
  324. package/dist/entities/policy-store.js +0 -75
  325. package/dist/entities/policy-types.d.ts +0 -72
  326. package/dist/entities/policy-types.js +0 -59
  327. package/dist/entities/projection.d.ts +0 -8
  328. package/dist/entities/projection.js +0 -82
  329. package/dist/entities/provenance-query.d.ts +0 -32
  330. package/dist/entities/provenance-query.js +0 -3
  331. package/dist/entities/read-identity.d.ts +0 -31
  332. package/dist/entities/read-identity.js +0 -264
  333. package/dist/entities/recall-bridge.d.ts +0 -5
  334. package/dist/entities/recall-bridge.js +0 -171
  335. package/dist/entities/resolution-engine.d.ts +0 -8
  336. package/dist/entities/resolution-engine.js +0 -3
  337. package/dist/entities/rollback-preview.d.ts +0 -35
  338. package/dist/entities/rollback-preview.js +0 -3
  339. package/dist/entities/source-locator.d.ts +0 -3
  340. package/dist/entities/source-locator.js +0 -32
  341. package/dist/entities/store.d.ts +0 -69
  342. package/dist/entities/store.js +0 -544
  343. package/dist/entities/types.d.ts +0 -166
  344. package/dist/entities/types.js +0 -30
  345. package/dist/memory/extraction-prompt.d.ts +0 -4
  346. package/dist/memory/extraction-prompt.js +0 -89
  347. package/dist/memory/scope-backfill.d.ts +0 -14
  348. package/dist/memory/scope-backfill.js +0 -3
  349. package/dist/memory/scope-store.d.ts +0 -4
  350. package/dist/memory/scope-store.js +0 -9
  351. package/dist/memory-store.d.ts +0 -87
  352. package/dist/memory-store.js +0 -78
  353. package/dist/model-runs/store.d.ts +0 -13
  354. package/dist/model-runs/tool-trace-store.d.ts +0 -8
  355. package/dist/notification-manager.d.ts +0 -7
  356. package/dist/notification-manager.js +0 -12
  357. package/dist/outcome-tracker.d.ts +0 -151
  358. package/dist/outcome-tracker.js +0 -271
  359. package/dist/query-intent.d.ts +0 -23
  360. package/dist/query-intent.js +0 -114
  361. package/dist/runtime/trusted-provenance.d.ts +0 -3
  362. package/dist/runtime/trusted-provenance.js +0 -6
  363. package/dist/search/question-type.d.ts +0 -5
  364. package/dist/search/question-type.js +0 -41
  365. package/dist/test-utils.d.ts +0 -80
  366. package/dist/test-utils.js +0 -218
  367. package/dist/tier-validator.d.ts +0 -43
  368. package/dist/tier-validator.js +0 -159
  369. package/dist/time-formatter.d.ts +0 -25
  370. package/dist/time-formatter.js +0 -93
  371. /package/dist/{search → knowledge}/feedback-store.d.ts +0 -0
  372. /package/dist/{search → knowledge}/feedback-store.js +0 -0
  373. /package/dist/{search → knowledge}/ranker-features.d.ts +0 -0
  374. /package/dist/{search → knowledge}/ranker-rescore.d.ts +0 -0
  375. /package/dist/{search → knowledge}/ranker-rescore.js +0 -0
  376. /package/dist/{search → knowledge}/ranker-trainer.d.ts +0 -0
  377. /package/dist/{search → knowledge}/ranker-trainer.js +0 -0
  378. /package/dist/{search → knowledge}/search-quality.js +0 -0
@@ -0,0 +1,395 @@
1
+ "use strict";
2
+ /**
3
+ * Registry store: work items, people and clients as nodes with the names they go by.
4
+ *
5
+ * Identity used to live in strings such as task titles and decision topics, so alternate
6
+ * spellings could not join without an explicit durable identity.
7
+ *
8
+ * A node here is cheap: an id, a kind, a display name, and the aliases it answers to.
9
+ * What it buys is that a record can point at identity instead of spelling it.
10
+ *
11
+ * Two decisions this module refuses to make on its own:
12
+ * - It never merges by similarity. `mergeNodes` happens because a caller decided, and the
13
+ * reason is stored with it.
14
+ * - It never reassigns a contested alias. Claiming an alias another node holds raises, so
15
+ * the caller resolves it (merge, or pick a different alias) rather than the store
16
+ * silently moving identity from under existing records.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.RegistryError = exports.REGISTRY_KINDS = void 0;
20
+ exports.currentIdentityRevision = currentIdentityRevision;
21
+ exports.rebuildRegistryProjections = rebuildRegistryProjections;
22
+ exports.normalizeAlias = normalizeAlias;
23
+ exports.createNode = createNode;
24
+ exports.addAliases = addAliases;
25
+ exports.upsertNode = upsertNode;
26
+ exports.addAlias = addAlias;
27
+ exports.resolveNodeById = resolveNodeById;
28
+ exports.resolveAlias = resolveAlias;
29
+ exports.resolveAliasCandidates = resolveAliasCandidates;
30
+ exports.listNodes = listNodes;
31
+ exports.mergeNodes = mergeNodes;
32
+ exports.splitNode = splitNode;
33
+ const node_crypto_1 = require("node:crypto");
34
+ const types_js_1 = require("./types.js");
35
+ Object.defineProperty(exports, "REGISTRY_KINDS", { enumerable: true, get: function () { return types_js_1.REGISTRY_KINDS; } });
36
+ class RegistryError extends Error {
37
+ code;
38
+ constructor(code, message) {
39
+ super(message);
40
+ this.code = code;
41
+ this.name = 'RegistryError';
42
+ }
43
+ }
44
+ exports.RegistryError = RegistryError;
45
+ function currentIdentityRevision(adapter) {
46
+ const row = adapter
47
+ .prepare('SELECT revision FROM registry_identity_state WHERE singleton = 1')
48
+ .get();
49
+ if (!row || !Number.isSafeInteger(row.revision) || row.revision < 0) {
50
+ throw new Error('registry_identity_state is missing or malformed');
51
+ }
52
+ return row.revision;
53
+ }
54
+ function rebuildRegistryProjections(adapter) {
55
+ const revision = currentIdentityRevision(adapter);
56
+ const row = adapter
57
+ .prepare('SELECT MAX(committed_revision) AS revision FROM registry_corrections')
58
+ .get();
59
+ if ((row.revision ?? 0) !== revision) {
60
+ throw new Error('Registry correction projection revision is inconsistent');
61
+ }
62
+ }
63
+ /**
64
+ * The lookup key for an alias: case-folded, inner runs of whitespace collapsed, trimmed.
65
+ *
66
+ * Deliberately conservative - it folds the differences that are the same string typed
67
+ * twice, and nothing else. Hyphens, underscores and script differences stay significant,
68
+ * because "a-0001" and "a_0001" being the same thing is a judgement about the work, not
69
+ * about text, and belongs in an alias row someone added.
70
+ */
71
+ function normalizeAlias(value) {
72
+ return value.trim().replace(/\s+/g, ' ').toLowerCase();
73
+ }
74
+ function toNode(row) {
75
+ return {
76
+ id: row.id,
77
+ kind: row.kind,
78
+ name: row.name,
79
+ parentId: row.parent_id,
80
+ mergedInto: row.merged_into,
81
+ note: row.note,
82
+ createdAt: row.created_at,
83
+ updatedAt: row.updated_at,
84
+ };
85
+ }
86
+ function requireKind(kind) {
87
+ if (!types_js_1.REGISTRY_KINDS.includes(kind)) {
88
+ throw new RegistryError('invalid_kind', `Unknown registry kind: ${kind}`);
89
+ }
90
+ return kind;
91
+ }
92
+ function readNode(adapter, id) {
93
+ const row = adapter.prepare('SELECT * FROM registry_nodes WHERE id = ?').get(id);
94
+ return row ? toNode(row) : null;
95
+ }
96
+ function isNodeVisible(adapter, id, scopes) {
97
+ const bindings = adapter
98
+ .prepare('SELECT scope_kind AS kind, scope_id AS id FROM registry_scope_bindings WHERE node_id = ?')
99
+ .all(id);
100
+ if (bindings.length === 0) {
101
+ return true;
102
+ }
103
+ if (!scopes || scopes.length === 0) {
104
+ return false;
105
+ }
106
+ return scopes.some((scope) => bindings.some((binding) => binding.kind === scope.kind && binding.id === scope.id));
107
+ }
108
+ /**
109
+ * Follow `merged_into` to the node that now holds this identity.
110
+ *
111
+ * Bounded: a cycle written by a bad merge would otherwise hang every lookup, so the walk
112
+ * stops and reports rather than spinning.
113
+ */
114
+ function followMerges(adapter, id) {
115
+ let current = readNode(adapter, id);
116
+ for (let hops = 0; current?.mergedInto && hops < 8; hops += 1) {
117
+ current = readNode(adapter, current.mergedInto);
118
+ }
119
+ if (current?.mergedInto) {
120
+ throw new RegistryError('merge_chain_too_long', `Merge chain from ${id} does not settle`);
121
+ }
122
+ return current;
123
+ }
124
+ /** Write one alias row, or raise when another node already answers to it. */
125
+ function aliasScopes(scopes) {
126
+ return scopes && scopes.length > 0 ? scopes : [{ kind: 'global', id: '*' }];
127
+ }
128
+ function insertAlias(adapter, nodeId, kind, alias, now, scopes) {
129
+ const normalized = normalizeAlias(alias);
130
+ if (!normalized) {
131
+ throw new RegistryError('empty_alias', 'An alias must contain at least one character');
132
+ }
133
+ for (const scope of aliasScopes(scopes)) {
134
+ const existing = adapter
135
+ .prepare(`SELECT node_id FROM registry_aliases
136
+ WHERE kind = ? AND alias = ? AND scope_kind = ? AND scope_id = ?`)
137
+ .get(kind, normalized, scope.kind, scope.id);
138
+ if (existing) {
139
+ if (existing.node_id === nodeId) {
140
+ continue;
141
+ }
142
+ throw new RegistryError('alias_taken', `Alias "${alias}" is already registered in this scope.`);
143
+ }
144
+ adapter
145
+ .prepare(`INSERT INTO registry_aliases
146
+ (node_id, kind, alias, alias_display, scope_kind, scope_id, created_at)
147
+ VALUES (?, ?, ?, ?, ?, ?, ?)`)
148
+ .run(nodeId, kind, normalized, alias.trim(), scope.kind, scope.id, now);
149
+ }
150
+ }
151
+ function createNode(adapter, input) {
152
+ const write = () => {
153
+ const kind = requireKind(input.kind);
154
+ const name = input.name.trim();
155
+ if (!name) {
156
+ throw new RegistryError('empty_name', 'A registry node needs a name');
157
+ }
158
+ const id = `reg_${(0, node_crypto_1.randomUUID)().replace(/-/g, '').slice(0, 20)}`;
159
+ const now = Date.now();
160
+ adapter
161
+ .prepare(`INSERT INTO registry_nodes (id, kind, name, parent_id, merged_into, merge_reason, note, created_at, updated_at)
162
+ VALUES (?, ?, ?, ?, NULL, NULL, ?, ?, ?)`)
163
+ .run(id, kind, name, input.parentId ?? null, input.note ?? null, now, now);
164
+ // The name is an alias too: asking for a node by the name it displays must work.
165
+ insertAlias(adapter, id, kind, name, now, input.scopes);
166
+ for (const alias of input.aliases ?? []) {
167
+ insertAlias(adapter, id, kind, alias, now, input.scopes);
168
+ }
169
+ for (const scope of input.scopes ?? []) {
170
+ if (!scope.id.trim()) {
171
+ throw new RegistryError('invalid_scope', 'Registry scope id must be nonblank');
172
+ }
173
+ adapter
174
+ .prepare(`INSERT INTO registry_scope_bindings (node_id, scope_kind, scope_id)
175
+ VALUES (?, ?, ?)`)
176
+ .run(id, scope.kind, scope.id);
177
+ }
178
+ return id;
179
+ };
180
+ return adapter.transaction(write);
181
+ }
182
+ function addAliases(adapter, nodeId, aliases, scopes) {
183
+ const write = () => {
184
+ if (scopes === undefined) {
185
+ for (const alias of aliases) {
186
+ addAlias(adapter, nodeId, alias);
187
+ }
188
+ return;
189
+ }
190
+ const node = readNode(adapter, nodeId);
191
+ if (!node || node.mergedInto) {
192
+ throw new RegistryError('unknown_node', 'Registry node unavailable');
193
+ }
194
+ for (const alias of aliases) {
195
+ insertAlias(adapter, nodeId, node.kind, alias, Date.now(), scopes);
196
+ }
197
+ };
198
+ adapter.transaction(write);
199
+ }
200
+ function upsertNode(adapter, input) {
201
+ const write = () => {
202
+ const existing = resolveAlias(adapter, input.name, input.kind, input.scopes);
203
+ if (existing) {
204
+ if (input.children && input.children.length > 0) {
205
+ throw new RegistryError('existing_children_unsupported', 'Adding children to an existing node requires an explicit correction.');
206
+ }
207
+ addAliases(adapter, existing.id, input.aliases ?? [], input.scopes);
208
+ return { id: existing.id, created: false, children: [] };
209
+ }
210
+ const id = createNode(adapter, input);
211
+ const children = input.children && input.children.length > 0
212
+ ? splitNode(adapter, {
213
+ parent: id,
214
+ children: input.children,
215
+ reason: input.note?.trim() || 'explicit parent declaration',
216
+ })
217
+ : [];
218
+ return { id, created: true, children };
219
+ };
220
+ return adapter.transaction(write);
221
+ }
222
+ function addAlias(adapter, nodeId, alias) {
223
+ const node = readNode(adapter, nodeId);
224
+ if (!node) {
225
+ throw new RegistryError('unknown_node', `No registry node ${nodeId}`);
226
+ }
227
+ if (node.mergedInto) {
228
+ throw new RegistryError('node_merged', `Node ${nodeId} was merged into ${node.mergedInto}; add the alias there`);
229
+ }
230
+ const scopes = adapter
231
+ .prepare('SELECT scope_kind AS kind, scope_id AS id FROM registry_scope_bindings WHERE node_id = ?')
232
+ .all(nodeId);
233
+ insertAlias(adapter, nodeId, node.kind, alias, Date.now(), scopes);
234
+ }
235
+ /** The live node behind an id, following merges. Null when the id is unknown. */
236
+ function resolveNodeById(adapter, id) {
237
+ return followMerges(adapter, id);
238
+ }
239
+ /** The node an alias names, following merges. `kind` narrows when the same word is both. */
240
+ function resolveAlias(adapter, alias, kind, scopes) {
241
+ const candidates = resolveAliasCandidates(adapter, alias, { kind, scopes });
242
+ if (candidates.length > 1) {
243
+ throw new RegistryError('alias_ambiguous', 'Alias resolves to multiple visible nodes.');
244
+ }
245
+ return candidates[0] ?? null;
246
+ }
247
+ function resolveAliasCandidates(adapter, alias, options) {
248
+ const normalized = normalizeAlias(alias);
249
+ if (!normalized) {
250
+ return [];
251
+ }
252
+ const admitted = options?.scopes && options.scopes.length > 0
253
+ ? options.scopes
254
+ : [{ kind: 'global', id: '*' }];
255
+ const whereKind = options?.kind ? 'kind = ? AND' : '';
256
+ const rows = adapter
257
+ .prepare(`SELECT node_id, alias_display FROM registry_aliases
258
+ WHERE ${whereKind} alias = ?
259
+ AND ((scope_kind = 'global' AND scope_id = '*')
260
+ OR (scope_kind || ':' || scope_id) IN (${admitted.map(() => '?').join(', ')}))
261
+ ORDER BY created_at, rowid`)
262
+ .all(...(options?.kind ? [requireKind(options.kind)] : []), normalized, ...admitted.map((scope) => `${scope.kind}:${scope.id}`));
263
+ const visible = rows
264
+ .map((row) => {
265
+ const node = followMerges(adapter, row.node_id);
266
+ if (!node || !isNodeVisible(adapter, node.id, admitted)) {
267
+ return null;
268
+ }
269
+ const canonicalVisible = adapter
270
+ .prepare(`SELECT 1 FROM registry_aliases
271
+ WHERE node_id = ? AND alias = ?
272
+ AND ((scope_kind = 'global' AND scope_id = '*')
273
+ OR (scope_kind || ':' || scope_id) IN (${admitted.map(() => '?').join(', ')}))
274
+ LIMIT 1`)
275
+ .get(node.id, normalizeAlias(node.name), ...admitted.map((scope) => `${scope.kind}:${scope.id}`));
276
+ return { ...node, name: canonicalVisible ? node.name : row.alias_display };
277
+ })
278
+ .filter((node) => node !== null);
279
+ const unique = [...new Map(visible.map((node) => [node.id, node])).values()];
280
+ return unique;
281
+ }
282
+ function listNodes(adapter, filter) {
283
+ const where = [];
284
+ const params = [];
285
+ if (filter?.kind) {
286
+ where.push('kind = ?');
287
+ params.push(requireKind(filter.kind));
288
+ }
289
+ if (filter?.parentId !== undefined) {
290
+ if (filter.parentId === null) {
291
+ where.push('parent_id IS NULL');
292
+ }
293
+ else {
294
+ where.push('parent_id = ?');
295
+ params.push(filter.parentId);
296
+ }
297
+ }
298
+ if (filter?.includeMerged !== true) {
299
+ where.push('merged_into IS NULL');
300
+ }
301
+ if (filter?.scopes && filter.scopes.length > 0) {
302
+ where.push(`(NOT EXISTS (SELECT 1 FROM registry_scope_bindings rs WHERE rs.node_id = registry_nodes.id)
303
+ OR EXISTS (
304
+ SELECT 1 FROM registry_scope_bindings rs
305
+ WHERE rs.node_id = registry_nodes.id
306
+ AND (rs.scope_kind || ':' || rs.scope_id) IN (${filter.scopes.map(() => '?').join(', ')})
307
+ ))`);
308
+ params.push(...filter.scopes.map((scope) => `${scope.kind}:${scope.id}`));
309
+ }
310
+ // rowid, not id: a split writes its children inside one millisecond, so `created_at`
311
+ // alone would order them by random uuid and report the parts in the wrong order.
312
+ const sql = `SELECT * FROM registry_nodes${where.length ? ` WHERE ${where.join(' AND ')}` : ''} ORDER BY created_at, rowid`;
313
+ return adapter.prepare(sql).all(...params).map(toNode);
314
+ }
315
+ /**
316
+ * Point one node's identity at another. The loser keeps its row as a tombstone so records
317
+ * that still reference it resolve forward instead of dangling.
318
+ */
319
+ function mergeNodes(adapter, input) {
320
+ if (input.loser === input.survivor) {
321
+ throw new RegistryError('merge_self', 'A node cannot merge into itself');
322
+ }
323
+ const loser = readNode(adapter, input.loser);
324
+ const survivor = readNode(adapter, input.survivor);
325
+ if (!loser) {
326
+ throw new RegistryError('unknown_node', `No registry node ${input.loser}`);
327
+ }
328
+ if (loser.mergedInto) {
329
+ throw new RegistryError('loser_merged', `Node ${input.loser} was already merged`);
330
+ }
331
+ if (!survivor) {
332
+ throw new RegistryError('unknown_node', `No registry node ${input.survivor}`);
333
+ }
334
+ if (survivor.mergedInto) {
335
+ throw new RegistryError('survivor_merged', `Node ${input.survivor} was itself merged into ${survivor.mergedInto}`);
336
+ }
337
+ if (loser.kind !== survivor.kind) {
338
+ throw new RegistryError('kind_mismatch', `Cannot merge ${loser.kind} into ${survivor.kind}`);
339
+ }
340
+ const reason = input.reason.trim();
341
+ if (!reason) {
342
+ throw new RegistryError('missing_reason', 'A merge must record why');
343
+ }
344
+ const now = Date.now();
345
+ // Aliases move rather than duplicate: (kind, alias) is unique, and the loser's rows are
346
+ // exactly the spellings that must now reach the survivor.
347
+ adapter.transaction(() => {
348
+ adapter
349
+ .prepare(`INSERT OR IGNORE INTO registry_scope_bindings (node_id, scope_kind, scope_id)
350
+ SELECT ?, scope_kind, scope_id FROM registry_scope_bindings WHERE node_id = ?`)
351
+ .run(input.survivor, input.loser);
352
+ adapter
353
+ .prepare('UPDATE registry_aliases SET node_id = ? WHERE node_id = ?')
354
+ .run(input.survivor, input.loser);
355
+ adapter
356
+ .prepare('UPDATE registry_nodes SET merged_into = ?, merge_reason = ?, updated_at = ? WHERE id = ?')
357
+ .run(input.survivor, reason, now, input.loser);
358
+ });
359
+ }
360
+ /**
361
+ * Split one item into the children it really covers, keeping the parent as the umbrella.
362
+ *
363
+ * Nothing is deleted: the parent stays resolvable by its own aliases, and existing records
364
+ * keep pointing at it until someone decides which child they belong to.
365
+ */
366
+ function splitNode(adapter, input) {
367
+ const write = () => {
368
+ const parent = readNode(adapter, input.parent);
369
+ if (!parent) {
370
+ throw new RegistryError('unknown_node', `No registry node ${input.parent}`);
371
+ }
372
+ if (parent.mergedInto) {
373
+ throw new RegistryError('node_merged', `Node ${input.parent} was merged away`);
374
+ }
375
+ if (input.children.length < 2) {
376
+ throw new RegistryError('split_too_small', 'A split needs at least two children');
377
+ }
378
+ if (!input.reason.trim()) {
379
+ throw new RegistryError('missing_reason', 'A split must record why');
380
+ }
381
+ const parentScopes = adapter
382
+ .prepare('SELECT scope_kind AS kind, scope_id AS id FROM registry_scope_bindings WHERE node_id = ?')
383
+ .all(parent.id);
384
+ return input.children.map((child) => createNode(adapter, {
385
+ kind: parent.kind,
386
+ name: child.name,
387
+ aliases: child.aliases,
388
+ parentId: parent.id,
389
+ note: input.reason.trim(),
390
+ scopes: parentScopes,
391
+ }));
392
+ };
393
+ return adapter.transaction(write);
394
+ }
395
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1,28 @@
1
+ export declare const REGISTRY_KINDS: readonly ["item", "person", "client"];
2
+ export type RegistryKind = (typeof REGISTRY_KINDS)[number];
3
+ export interface RegistryNode {
4
+ id: string;
5
+ kind: RegistryKind;
6
+ name: string;
7
+ parentId: string | null;
8
+ mergedInto: string | null;
9
+ note: string | null;
10
+ createdAt: number;
11
+ updatedAt: number;
12
+ }
13
+ export interface RecordActor {
14
+ personId: string;
15
+ role: string;
16
+ }
17
+ export interface RecordIdentity {
18
+ itemId: string | null;
19
+ }
20
+ export interface RegistryScopeRef {
21
+ /**
22
+ * The consumer's word for what kind of scope this is. The core matches it; it
23
+ * does not read it. Closed lists of kinds used to live here, in three copies.
24
+ */
25
+ kind: string;
26
+ id: string;
27
+ }
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REGISTRY_KINDS = void 0;
4
+ exports.REGISTRY_KINDS = ['item', 'person', 'client'];
5
+ //# sourceMappingURL=types.js.map
@@ -14,7 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.calculateRelevance = calculateRelevance;
15
15
  exports.selectTopDecisions = selectTopDecisions;
16
16
  exports.formatTopNContext = formatTopNContext;
17
- const embeddings_js_1 = require("./embeddings.js");
17
+ const embedder_js_1 = require("./embedding/embedder.js");
18
18
  /**
19
19
  * Outcome weights for importance scoring
20
20
  */
@@ -70,7 +70,7 @@ function calculateRelevance(decision, queryContext) {
70
70
  let semanticScore = 0;
71
71
  if (decision.embedding && queryContext.embedding) {
72
72
  // Task 1.3: Use cosine similarity function
73
- semanticScore = (0, embeddings_js_1.cosineSimilarity)(decision.embedding, queryContext.embedding);
73
+ semanticScore = (0, embedder_js_1.cosineSimilarity)(decision.embedding, queryContext.embedding);
74
74
  }
75
75
  else {
76
76
  // Fallback: no semantic match if embeddings missing
@@ -0,0 +1,50 @@
1
+ export interface AgentNotice {
2
+ agent: string;
3
+ action: string;
4
+ target: string;
5
+ timestamp: number;
6
+ }
7
+ export type AgentEvent = {
8
+ type: 'memory:saved';
9
+ topic: string;
10
+ project?: string;
11
+ } | {
12
+ type: 'extraction:completed';
13
+ projects: string[];
14
+ } | {
15
+ type: 'memory:promoted';
16
+ saved: number;
17
+ } | {
18
+ type: 'wiki:compiled';
19
+ pages: string[];
20
+ } | {
21
+ type: 'dashboard:refresh';
22
+ } | {
23
+ type: 'agent:action';
24
+ agent: string;
25
+ action: string;
26
+ target: string;
27
+ };
28
+ export type AgentEventType = AgentEvent['type'];
29
+ type EventHandler = (event: AgentEvent) => void | Promise<void>;
30
+ export declare class AgentEventBus {
31
+ static readonly MAX_NOTICES = 50;
32
+ private listeners;
33
+ private debounceTimers;
34
+ private listenerDebounceTimers;
35
+ private notices;
36
+ on(type: AgentEventType, handler: EventHandler): void;
37
+ off(type: AgentEventType, handler: EventHandler): void;
38
+ emit(event: AgentEvent): void;
39
+ emitDebounced(event: AgentEvent, delayMs: number): void;
40
+ /**
41
+ * Register a handler whose invocation is trailing-edge debounced: rapid
42
+ * successive events collapse into one call with the LAST event after
43
+ * delayMs of quiet. Pending invocations are cancelled by destroy().
44
+ */
45
+ onDebounced(type: AgentEventType, handler: EventHandler, delayMs: number): void;
46
+ getRecentNotices(limit: number): AgentNotice[];
47
+ destroy(): void;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=agent-event-bus.d.ts.map
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentEventBus = void 0;
4
+ class AgentEventBus {
5
+ static MAX_NOTICES = 50;
6
+ listeners = new Map();
7
+ debounceTimers = new Map();
8
+ listenerDebounceTimers = new Set();
9
+ notices = [];
10
+ on(type, handler) {
11
+ if (!this.listeners.has(type)) {
12
+ this.listeners.set(type, new Set());
13
+ }
14
+ this.listeners.get(type).add(handler);
15
+ }
16
+ off(type, handler) {
17
+ this.listeners.get(type)?.delete(handler);
18
+ }
19
+ emit(event) {
20
+ const handlers = this.listeners.get(event.type);
21
+ if (handlers) {
22
+ for (const handler of handlers) {
23
+ try {
24
+ const result = handler(event);
25
+ if (result && typeof result.catch === 'function') {
26
+ result.catch((err) => console.error(`[EventBus] Handler error for ${event.type}:`, err));
27
+ }
28
+ }
29
+ catch (err) {
30
+ console.error(`[EventBus] Sync handler error for ${event.type}:`, err);
31
+ }
32
+ }
33
+ }
34
+ if (event.type === 'agent:action') {
35
+ this.notices.unshift({
36
+ agent: event.agent,
37
+ action: event.action,
38
+ target: event.target,
39
+ timestamp: Date.now(),
40
+ });
41
+ if (this.notices.length > AgentEventBus.MAX_NOTICES) {
42
+ this.notices.length = AgentEventBus.MAX_NOTICES;
43
+ }
44
+ }
45
+ }
46
+ emitDebounced(event, delayMs) {
47
+ const existing = this.debounceTimers.get(event.type);
48
+ if (existing)
49
+ clearTimeout(existing);
50
+ this.debounceTimers.set(event.type, setTimeout(() => {
51
+ this.debounceTimers.delete(event.type);
52
+ this.emit(event);
53
+ }, delayMs));
54
+ }
55
+ /**
56
+ * Register a handler whose invocation is trailing-edge debounced: rapid
57
+ * successive events collapse into one call with the LAST event after
58
+ * delayMs of quiet. Pending invocations are cancelled by destroy().
59
+ */
60
+ onDebounced(type, handler, delayMs) {
61
+ let timer = null;
62
+ this.on(type, (event) => {
63
+ if (timer) {
64
+ clearTimeout(timer);
65
+ this.listenerDebounceTimers.delete(timer);
66
+ }
67
+ const scheduled = setTimeout(() => {
68
+ this.listenerDebounceTimers.delete(scheduled);
69
+ timer = null;
70
+ try {
71
+ const result = handler(event);
72
+ if (result && typeof result.catch === 'function') {
73
+ result.catch((err) => console.error(`[EventBus] Debounced handler error for ${type}:`, err));
74
+ }
75
+ }
76
+ catch (err) {
77
+ console.error(`[EventBus] Debounced handler error for ${type}:`, err);
78
+ }
79
+ }, delayMs);
80
+ timer = scheduled;
81
+ this.listenerDebounceTimers.add(scheduled);
82
+ });
83
+ }
84
+ getRecentNotices(limit) {
85
+ return this.notices.slice(0, limit);
86
+ }
87
+ destroy() {
88
+ for (const timer of this.debounceTimers.values()) {
89
+ clearTimeout(timer);
90
+ }
91
+ this.debounceTimers.clear();
92
+ for (const timer of this.listenerDebounceTimers.values()) {
93
+ clearTimeout(timer);
94
+ }
95
+ this.listenerDebounceTimers.clear();
96
+ this.listeners.clear();
97
+ this.notices.length = 0;
98
+ }
99
+ }
100
+ exports.AgentEventBus = AgentEventBus;
101
+ //# sourceMappingURL=agent-event-bus.js.map