@theowlops/boombot 0.0.0-stage → 1.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 (544) hide show
  1. package/README.md +69 -3
  2. package/dist/LICENSE +21 -0
  3. package/dist/bin/boombot.js +16 -0
  4. package/dist/cli/api-key.js +123 -0
  5. package/dist/cli/bin-bun.js +17 -0
  6. package/dist/cli/bin.js +34 -0
  7. package/dist/cli/cli/cli-error.js +61 -0
  8. package/dist/cli/cli/dispatch.js +138 -0
  9. package/dist/cli/cli/help.js +83 -0
  10. package/dist/cli/cli/parser.js +89 -0
  11. package/dist/cli/cli/registry.js +185 -0
  12. package/dist/cli/cli/spec.js +41 -0
  13. package/dist/cli/cli/suggest.js +125 -0
  14. package/dist/cli/cli/version.js +30 -0
  15. package/dist/cli/cli/vocabulary.js +87 -0
  16. package/dist/cli/commands/doctor.js +365 -0
  17. package/dist/cli/commands/gateway.js +290 -0
  18. package/dist/cli/commands/migrate.js +270 -0
  19. package/dist/cli/commands/plugin.js +97 -0
  20. package/dist/cli/commands/setup.js +230 -0
  21. package/dist/cli/config-file.js +133 -0
  22. package/dist/cli/master-key.js +78 -0
  23. package/dist/cli/open-browser.js +59 -0
  24. package/dist/cli/web-assets.js +58 -0
  25. package/dist/gateway/auth.js +46 -0
  26. package/dist/gateway/config-format.js +202 -0
  27. package/dist/gateway/config.js +427 -0
  28. package/dist/gateway/context.js +1 -0
  29. package/dist/gateway/env-file.js +129 -0
  30. package/dist/gateway/events.js +172 -0
  31. package/dist/gateway/guard/tagging.js +505 -0
  32. package/dist/gateway/handlers/index.js +66 -0
  33. package/dist/gateway/handlers/memory.js +54 -0
  34. package/dist/gateway/handlers/providers.js +73 -0
  35. package/dist/gateway/handlers/registry.js +39 -0
  36. package/dist/gateway/handlers/sessions.js +188 -0
  37. package/dist/gateway/handlers/system.js +12 -0
  38. package/dist/gateway/handlers/tasks.js +191 -0
  39. package/dist/gateway/handlers/turn.js +100 -0
  40. package/dist/gateway/index.js +126 -0
  41. package/dist/gateway/main.js +23 -0
  42. package/dist/gateway/server.js +354 -0
  43. package/dist/gateway/services/context-limits.js +75 -0
  44. package/dist/gateway/services/history-normalizer.js +42 -0
  45. package/dist/gateway/services/image-pipeline.js +56 -0
  46. package/dist/gateway/services/key-roulette-client.js +43 -0
  47. package/dist/gateway/services/llm-client.js +593 -0
  48. package/dist/gateway/services/llm-decoder.js +200 -0
  49. package/dist/gateway/services/local-fallback.js +135 -0
  50. package/dist/gateway/services/memory.js +511 -0
  51. package/dist/gateway/services/persistent-memory.js +196 -0
  52. package/dist/gateway/services/providers.js +44 -0
  53. package/dist/gateway/services/tasks.js +237 -0
  54. package/dist/gateway/services/verification.js +124 -0
  55. package/dist/gateway/services/vision-payload.js +48 -0
  56. package/dist/gateway/services.js +257 -0
  57. package/dist/gateway/session-snapshot.js +19 -0
  58. package/dist/gateway/sessions.js +701 -0
  59. package/dist/gateway/static.js +239 -0
  60. package/dist/gateway/turns/clarify-tool.js +57 -0
  61. package/dist/gateway/turns/cronjob-tool.js +96 -0
  62. package/dist/gateway/turns/deferred-tools.js +154 -0
  63. package/dist/gateway/turns/execute-code-tool.js +84 -0
  64. package/dist/gateway/turns/file-tool-defs.js +178 -0
  65. package/dist/gateway/turns/file-tool-ops.js +178 -0
  66. package/dist/gateway/turns/file-tool-scan.js +182 -0
  67. package/dist/gateway/turns/file-tool.js +302 -0
  68. package/dist/gateway/turns/index.js +416 -0
  69. package/dist/gateway/turns/jev-middleware.js +91 -0
  70. package/dist/gateway/turns/local-reply.js +156 -0
  71. package/dist/gateway/turns/mcp-client.js +643 -0
  72. package/dist/gateway/turns/memory-tool.js +171 -0
  73. package/dist/gateway/turns/middleware.js +96 -0
  74. package/dist/gateway/turns/python-core.js +397 -0
  75. package/dist/gateway/turns/routing/index.js +3 -0
  76. package/dist/gateway/turns/routing/intent-classifier.js +60 -0
  77. package/dist/gateway/turns/routing/planner-adapter.js +91 -0
  78. package/dist/gateway/turns/routing/types.js +1 -0
  79. package/dist/gateway/turns/runtime-deps.js +228 -0
  80. package/dist/gateway/turns/self-config-tool.js +277 -0
  81. package/dist/gateway/turns/service-types.js +11 -0
  82. package/dist/gateway/turns/service.js +820 -0
  83. package/dist/gateway/turns/session-adapter.js +158 -0
  84. package/dist/gateway/turns/session-tool.js +49 -0
  85. package/dist/gateway/turns/shell-tool.js +190 -0
  86. package/dist/gateway/turns/skill-tool.js +239 -0
  87. package/dist/gateway/turns/spillover.js +201 -0
  88. package/dist/gateway/turns/subagent-tool.js +140 -0
  89. package/dist/gateway/turns/system-prompt.js +121 -0
  90. package/dist/gateway/turns/tool-schema.js +90 -0
  91. package/dist/gateway/turns/turn-utils.js +58 -0
  92. package/dist/gateway/turns/vision-tool.js +120 -0
  93. package/dist/gateway/types.js +1 -0
  94. package/dist/native/win32-x64/boombot-native-host.exe +0 -0
  95. package/dist/node_modules/@boombot/channels/handlers.d.ts +9 -0
  96. package/dist/node_modules/@boombot/channels/handlers.js +109 -0
  97. package/dist/node_modules/@boombot/channels/index.d.ts +12 -0
  98. package/dist/node_modules/@boombot/channels/index.js +12 -0
  99. package/dist/node_modules/@boombot/channels/package.json +9 -0
  100. package/dist/node_modules/@boombot/channels/service.d.ts +62 -0
  101. package/dist/node_modules/@boombot/channels/service.js +608 -0
  102. package/dist/node_modules/@boombot/channels/tool.d.ts +10 -0
  103. package/dist/node_modules/@boombot/channels/tool.js +46 -0
  104. package/dist/node_modules/@boombot/channels/transports/common/dedup.d.ts +17 -0
  105. package/dist/node_modules/@boombot/channels/transports/common/dedup.js +42 -0
  106. package/dist/node_modules/@boombot/channels/transports/common/handoff.d.ts +19 -0
  107. package/dist/node_modules/@boombot/channels/transports/common/handoff.js +32 -0
  108. package/dist/node_modules/@boombot/channels/transports/common/index.d.ts +3 -0
  109. package/dist/node_modules/@boombot/channels/transports/common/index.js +3 -0
  110. package/dist/node_modules/@boombot/channels/transports/common/types.d.ts +99 -0
  111. package/dist/node_modules/@boombot/channels/transports/common/types.js +54 -0
  112. package/dist/node_modules/@boombot/channels/transports/common.d.ts +2 -0
  113. package/dist/node_modules/@boombot/channels/transports/common.js +2 -0
  114. package/dist/node_modules/@boombot/channels/transports/dedup/index.d.ts +1 -0
  115. package/dist/node_modules/@boombot/channels/transports/dedup/index.js +1 -0
  116. package/dist/node_modules/@boombot/channels/transports/dedup.d.ts +2 -0
  117. package/dist/node_modules/@boombot/channels/transports/dedup.js +2 -0
  118. package/dist/node_modules/@boombot/channels/transports/discord/index.d.ts +1 -0
  119. package/dist/node_modules/@boombot/channels/transports/discord/index.js +1 -0
  120. package/dist/node_modules/@boombot/channels/transports/discord/transport.d.ts +36 -0
  121. package/dist/node_modules/@boombot/channels/transports/discord/transport.js +199 -0
  122. package/dist/node_modules/@boombot/channels/transports/discord.d.ts +2 -0
  123. package/dist/node_modules/@boombot/channels/transports/discord.js +2 -0
  124. package/dist/node_modules/@boombot/channels/transports/handoff.d.ts +2 -0
  125. package/dist/node_modules/@boombot/channels/transports/handoff.js +2 -0
  126. package/dist/node_modules/@boombot/channels/transports/messenger/index.d.ts +1 -0
  127. package/dist/node_modules/@boombot/channels/transports/messenger/index.js +1 -0
  128. package/dist/node_modules/@boombot/channels/transports/messenger/transport.d.ts +34 -0
  129. package/dist/node_modules/@boombot/channels/transports/messenger/transport.js +180 -0
  130. package/dist/node_modules/@boombot/channels/transports/messenger.d.ts +2 -0
  131. package/dist/node_modules/@boombot/channels/transports/messenger.js +2 -0
  132. package/dist/node_modules/@boombot/channels/transports/slack/index.d.ts +1 -0
  133. package/dist/node_modules/@boombot/channels/transports/slack/index.js +1 -0
  134. package/dist/node_modules/@boombot/channels/transports/slack/transport.d.ts +35 -0
  135. package/dist/node_modules/@boombot/channels/transports/slack/transport.js +183 -0
  136. package/dist/node_modules/@boombot/channels/transports/slack.d.ts +2 -0
  137. package/dist/node_modules/@boombot/channels/transports/slack.js +2 -0
  138. package/dist/node_modules/@boombot/channels/transports/streamer/index.d.ts +1 -0
  139. package/dist/node_modules/@boombot/channels/transports/streamer/index.js +1 -0
  140. package/dist/node_modules/@boombot/channels/transports/streamer/streamer.d.ts +31 -0
  141. package/dist/node_modules/@boombot/channels/transports/streamer/streamer.js +141 -0
  142. package/dist/node_modules/@boombot/channels/transports/streamer.d.ts +2 -0
  143. package/dist/node_modules/@boombot/channels/transports/streamer.js +2 -0
  144. package/dist/node_modules/@boombot/channels/transports/telegram/index.d.ts +1 -0
  145. package/dist/node_modules/@boombot/channels/transports/telegram/index.js +1 -0
  146. package/dist/node_modules/@boombot/channels/transports/telegram/transport.d.ts +75 -0
  147. package/dist/node_modules/@boombot/channels/transports/telegram/transport.js +395 -0
  148. package/dist/node_modules/@boombot/channels/transports/telegram.d.ts +2 -0
  149. package/dist/node_modules/@boombot/channels/transports/telegram.js +2 -0
  150. package/dist/node_modules/@boombot/channels/transports/tiktok/index.d.ts +1 -0
  151. package/dist/node_modules/@boombot/channels/transports/tiktok/index.js +1 -0
  152. package/dist/node_modules/@boombot/channels/transports/tiktok/transport.d.ts +27 -0
  153. package/dist/node_modules/@boombot/channels/transports/tiktok/transport.js +97 -0
  154. package/dist/node_modules/@boombot/channels/transports/tiktok.d.ts +2 -0
  155. package/dist/node_modules/@boombot/channels/transports/tiktok.js +2 -0
  156. package/dist/node_modules/@boombot/channels/transports/whatsapp/index.d.ts +1 -0
  157. package/dist/node_modules/@boombot/channels/transports/whatsapp/index.js +1 -0
  158. package/dist/node_modules/@boombot/channels/transports/whatsapp/transport.d.ts +38 -0
  159. package/dist/node_modules/@boombot/channels/transports/whatsapp/transport.js +189 -0
  160. package/dist/node_modules/@boombot/channels/transports/whatsapp.d.ts +2 -0
  161. package/dist/node_modules/@boombot/channels/transports/whatsapp.js +2 -0
  162. package/dist/node_modules/@boombot/channels/transports/zalo/index.d.ts +2 -0
  163. package/dist/node_modules/@boombot/channels/transports/zalo/index.js +2 -0
  164. package/dist/node_modules/@boombot/channels/transports/zalo/oa.d.ts +28 -0
  165. package/dist/node_modules/@boombot/channels/transports/zalo/oa.js +94 -0
  166. package/dist/node_modules/@boombot/channels/transports/zalo/personal.d.ts +106 -0
  167. package/dist/node_modules/@boombot/channels/transports/zalo/personal.js +171 -0
  168. package/dist/node_modules/@boombot/channels/transports/zalo-personal.d.ts +2 -0
  169. package/dist/node_modules/@boombot/channels/transports/zalo-personal.js +2 -0
  170. package/dist/node_modules/@boombot/channels/transports/zalo.d.ts +2 -0
  171. package/dist/node_modules/@boombot/channels/transports/zalo.js +2 -0
  172. package/dist/node_modules/@boombot/core/agent-core/index.d.ts +12 -0
  173. package/dist/node_modules/@boombot/core/agent-core/index.js +12 -0
  174. package/dist/node_modules/@boombot/core/agent-core/middleware.d.ts +60 -0
  175. package/dist/node_modules/@boombot/core/agent-core/middleware.js +152 -0
  176. package/dist/node_modules/@boombot/core/agent-core/routing.d.ts +128 -0
  177. package/dist/node_modules/@boombot/core/agent-core/routing.js +437 -0
  178. package/dist/node_modules/@boombot/core/agent-core/runtime-deps.d.ts +88 -0
  179. package/dist/node_modules/@boombot/core/agent-core/runtime-deps.js +8 -0
  180. package/dist/node_modules/@boombot/core/agent-core/tool-errors.d.ts +44 -0
  181. package/dist/node_modules/@boombot/core/agent-core/tool-errors.js +60 -0
  182. package/dist/node_modules/@boombot/core/agent-core/turn-loop.d.ts +21 -0
  183. package/dist/node_modules/@boombot/core/agent-core/turn-loop.js +561 -0
  184. package/dist/node_modules/@boombot/core/agent-core/types.d.ts +189 -0
  185. package/dist/node_modules/@boombot/core/agent-core/types.js +7 -0
  186. package/dist/node_modules/@boombot/core/compaction/compactor.d.ts +19 -0
  187. package/dist/node_modules/@boombot/core/compaction/compactor.js +127 -0
  188. package/dist/node_modules/@boombot/core/compaction/estimator.d.ts +10 -0
  189. package/dist/node_modules/@boombot/core/compaction/estimator.js +48 -0
  190. package/dist/node_modules/@boombot/core/compaction/index.d.ts +3 -0
  191. package/dist/node_modules/@boombot/core/compaction/index.js +3 -0
  192. package/dist/node_modules/@boombot/core/compaction/types.d.ts +31 -0
  193. package/dist/node_modules/@boombot/core/compaction/types.js +7 -0
  194. package/dist/node_modules/@boombot/core/index.d.ts +9 -0
  195. package/dist/node_modules/@boombot/core/index.js +9 -0
  196. package/dist/node_modules/@boombot/core/jev/index.d.ts +2 -0
  197. package/dist/node_modules/@boombot/core/jev/index.js +2 -0
  198. package/dist/node_modules/@boombot/core/jev/jev.d.ts +30 -0
  199. package/dist/node_modules/@boombot/core/jev/jev.js +164 -0
  200. package/dist/node_modules/@boombot/core/jev/types.d.ts +22 -0
  201. package/dist/node_modules/@boombot/core/jev/types.js +1 -0
  202. package/dist/node_modules/@boombot/core/memory/consolidation/budget.d.ts +63 -0
  203. package/dist/node_modules/@boombot/core/memory/consolidation/budget.js +94 -0
  204. package/dist/node_modules/@boombot/core/memory/consolidation/consolidator.d.ts +152 -0
  205. package/dist/node_modules/@boombot/core/memory/consolidation/consolidator.js +318 -0
  206. package/dist/node_modules/@boombot/core/memory/consolidation/index.d.ts +12 -0
  207. package/dist/node_modules/@boombot/core/memory/consolidation/index.js +12 -0
  208. package/dist/node_modules/@boombot/core/memory/curation.d.ts +86 -0
  209. package/dist/node_modules/@boombot/core/memory/curation.js +120 -0
  210. package/dist/node_modules/@boombot/core/memory/errors.d.ts +12 -0
  211. package/dist/node_modules/@boombot/core/memory/errors.js +20 -0
  212. package/dist/node_modules/@boombot/core/memory/hybrid-search.d.ts +29 -0
  213. package/dist/node_modules/@boombot/core/memory/hybrid-search.js +52 -0
  214. package/dist/node_modules/@boombot/core/memory/index.d.ts +23 -0
  215. package/dist/node_modules/@boombot/core/memory/index.js +23 -0
  216. package/dist/node_modules/@boombot/core/memory/indexer.d.ts +47 -0
  217. package/dist/node_modules/@boombot/core/memory/indexer.js +138 -0
  218. package/dist/node_modules/@boombot/core/memory/lifecycle.d.ts +12 -0
  219. package/dist/node_modules/@boombot/core/memory/lifecycle.js +66 -0
  220. package/dist/node_modules/@boombot/core/memory/provider.d.ts +84 -0
  221. package/dist/node_modules/@boombot/core/memory/provider.js +117 -0
  222. package/dist/node_modules/@boombot/core/memory/recall.d.ts +7 -0
  223. package/dist/node_modules/@boombot/core/memory/recall.js +111 -0
  224. package/dist/node_modules/@boombot/core/memory/scope-resolver.d.ts +27 -0
  225. package/dist/node_modules/@boombot/core/memory/scope-resolver.js +60 -0
  226. package/dist/node_modules/@boombot/core/memory/search.d.ts +37 -0
  227. package/dist/node_modules/@boombot/core/memory/search.js +158 -0
  228. package/dist/node_modules/@boombot/core/memory/store.d.ts +60 -0
  229. package/dist/node_modules/@boombot/core/memory/store.js +289 -0
  230. package/dist/node_modules/@boombot/core/memory/types.d.ts +121 -0
  231. package/dist/node_modules/@boombot/core/memory/types.js +21 -0
  232. package/dist/node_modules/@boombot/core/memory/vector-index.d.ts +34 -0
  233. package/dist/node_modules/@boombot/core/memory/vector-index.js +65 -0
  234. package/dist/node_modules/@boombot/core/package.json +9 -0
  235. package/dist/node_modules/@boombot/core/reflection/classifier.d.ts +13 -0
  236. package/dist/node_modules/@boombot/core/reflection/classifier.js +77 -0
  237. package/dist/node_modules/@boombot/core/reflection/index.d.ts +2 -0
  238. package/dist/node_modules/@boombot/core/reflection/index.js +2 -0
  239. package/dist/node_modules/@boombot/core/reflection/types.d.ts +13 -0
  240. package/dist/node_modules/@boombot/core/reflection/types.js +4 -0
  241. package/dist/node_modules/@boombot/core/research/config.d.ts +89 -0
  242. package/dist/node_modules/@boombot/core/research/config.js +206 -0
  243. package/dist/node_modules/@boombot/core/research/crawl.d.ts +36 -0
  244. package/dist/node_modules/@boombot/core/research/crawl.js +179 -0
  245. package/dist/node_modules/@boombot/core/research/factory.d.ts +26 -0
  246. package/dist/node_modules/@boombot/core/research/factory.js +46 -0
  247. package/dist/node_modules/@boombot/core/research/http.d.ts +87 -0
  248. package/dist/node_modules/@boombot/core/research/http.js +250 -0
  249. package/dist/node_modules/@boombot/core/research/index.d.ts +17 -0
  250. package/dist/node_modules/@boombot/core/research/index.js +10 -0
  251. package/dist/node_modules/@boombot/core/research/orchestrator.d.ts +113 -0
  252. package/dist/node_modules/@boombot/core/research/orchestrator.js +252 -0
  253. package/dist/node_modules/@boombot/core/research/parse/docx.d.ts +24 -0
  254. package/dist/node_modules/@boombot/core/research/parse/docx.js +183 -0
  255. package/dist/node_modules/@boombot/core/research/parse/guards.d.ts +89 -0
  256. package/dist/node_modules/@boombot/core/research/parse/guards.js +171 -0
  257. package/dist/node_modules/@boombot/core/research/parse/index.d.ts +68 -0
  258. package/dist/node_modules/@boombot/core/research/parse/index.js +219 -0
  259. package/dist/node_modules/@boombot/core/research/parse/pdf.d.ts +38 -0
  260. package/dist/node_modules/@boombot/core/research/parse/pdf.js +567 -0
  261. package/dist/node_modules/@boombot/core/research/providers/arxiv.d.ts +9 -0
  262. package/dist/node_modules/@boombot/core/research/providers/arxiv.js +72 -0
  263. package/dist/node_modules/@boombot/core/research/providers/brave.d.ts +11 -0
  264. package/dist/node_modules/@boombot/core/research/providers/brave.js +36 -0
  265. package/dist/node_modules/@boombot/core/research/providers/duckduckgo.d.ts +9 -0
  266. package/dist/node_modules/@boombot/core/research/providers/duckduckgo.js +78 -0
  267. package/dist/node_modules/@boombot/core/research/providers/exa.d.ts +11 -0
  268. package/dist/node_modules/@boombot/core/research/providers/exa.js +34 -0
  269. package/dist/node_modules/@boombot/core/research/providers/firecrawl.d.ts +16 -0
  270. package/dist/node_modules/@boombot/core/research/providers/firecrawl.js +47 -0
  271. package/dist/node_modules/@boombot/core/research/providers/index.d.ts +17 -0
  272. package/dist/node_modules/@boombot/core/research/providers/index.js +11 -0
  273. package/dist/node_modules/@boombot/core/research/providers/jina.d.ts +13 -0
  274. package/dist/node_modules/@boombot/core/research/providers/jina.js +114 -0
  275. package/dist/node_modules/@boombot/core/research/providers/openalex.d.ts +14 -0
  276. package/dist/node_modules/@boombot/core/research/providers/openalex.js +66 -0
  277. package/dist/node_modules/@boombot/core/research/providers/semantic-scholar.d.ts +9 -0
  278. package/dist/node_modules/@boombot/core/research/providers/semantic-scholar.js +56 -0
  279. package/dist/node_modules/@boombot/core/research/providers/tavily.d.ts +11 -0
  280. package/dist/node_modules/@boombot/core/research/providers/tavily.js +35 -0
  281. package/dist/node_modules/@boombot/core/research/providers/wikipedia.d.ts +12 -0
  282. package/dist/node_modules/@boombot/core/research/providers/wikipedia.js +47 -0
  283. package/dist/node_modules/@boombot/core/research/tools.d.ts +27 -0
  284. package/dist/node_modules/@boombot/core/research/tools.js +251 -0
  285. package/dist/node_modules/@boombot/core/research/types.d.ts +133 -0
  286. package/dist/node_modules/@boombot/core/research/types.js +8 -0
  287. package/dist/node_modules/@boombot/core/research/wiring.d.ts +25 -0
  288. package/dist/node_modules/@boombot/core/research/wiring.js +51 -0
  289. package/dist/node_modules/@boombot/core/scheduler/cron.d.ts +34 -0
  290. package/dist/node_modules/@boombot/core/scheduler/cron.js +147 -0
  291. package/dist/node_modules/@boombot/core/scheduler/evaluator.d.ts +42 -0
  292. package/dist/node_modules/@boombot/core/scheduler/evaluator.js +148 -0
  293. package/dist/node_modules/@boombot/core/scheduler/index.d.ts +15 -0
  294. package/dist/node_modules/@boombot/core/scheduler/index.js +15 -0
  295. package/dist/node_modules/@boombot/core/scheduler/registry.d.ts +81 -0
  296. package/dist/node_modules/@boombot/core/scheduler/registry.js +263 -0
  297. package/dist/node_modules/@boombot/core/scheduler/runner.d.ts +59 -0
  298. package/dist/node_modules/@boombot/core/scheduler/runner.js +257 -0
  299. package/dist/node_modules/@boombot/core/scheduler/store.d.ts +150 -0
  300. package/dist/node_modules/@boombot/core/scheduler/store.js +526 -0
  301. package/dist/node_modules/@boombot/core/scheduler/timezone.d.ts +35 -0
  302. package/dist/node_modules/@boombot/core/scheduler/timezone.js +96 -0
  303. package/dist/node_modules/@boombot/core/scheduler/types.d.ts +157 -0
  304. package/dist/node_modules/@boombot/core/scheduler/types.js +89 -0
  305. package/dist/node_modules/@boombot/core/task-runner/index.d.ts +7 -0
  306. package/dist/node_modules/@boombot/core/task-runner/index.js +5 -0
  307. package/dist/node_modules/@boombot/core/task-runner/planner.d.ts +37 -0
  308. package/dist/node_modules/@boombot/core/task-runner/planner.js +154 -0
  309. package/dist/node_modules/@boombot/core/task-runner/runner.d.ts +8 -0
  310. package/dist/node_modules/@boombot/core/task-runner/runner.js +564 -0
  311. package/dist/node_modules/@boombot/core/task-runner/store.d.ts +28 -0
  312. package/dist/node_modules/@boombot/core/task-runner/store.js +126 -0
  313. package/dist/node_modules/@boombot/core/task-runner/types.d.ts +138 -0
  314. package/dist/node_modules/@boombot/core/task-runner/types.js +11 -0
  315. package/dist/node_modules/@boombot/core/workflow/dag.d.ts +16 -0
  316. package/dist/node_modules/@boombot/core/workflow/dag.js +109 -0
  317. package/dist/node_modules/@boombot/core/workflow/engine.d.ts +34 -0
  318. package/dist/node_modules/@boombot/core/workflow/engine.js +304 -0
  319. package/dist/node_modules/@boombot/core/workflow/index.d.ts +3 -0
  320. package/dist/node_modules/@boombot/core/workflow/index.js +3 -0
  321. package/dist/node_modules/@boombot/core/workflow/types.d.ts +98 -0
  322. package/dist/node_modules/@boombot/core/workflow/types.js +21 -0
  323. package/dist/node_modules/@boombot/cronjobs/handlers.d.ts +11 -0
  324. package/dist/node_modules/@boombot/cronjobs/handlers.js +174 -0
  325. package/dist/node_modules/@boombot/cronjobs/index.d.ts +2 -0
  326. package/dist/node_modules/@boombot/cronjobs/index.js +2 -0
  327. package/dist/node_modules/@boombot/cronjobs/package.json +9 -0
  328. package/dist/node_modules/@boombot/cronjobs/service.d.ts +53 -0
  329. package/dist/node_modules/@boombot/cronjobs/service.js +200 -0
  330. package/dist/node_modules/@boombot/plugins/index.d.ts +2 -0
  331. package/dist/node_modules/@boombot/plugins/index.js +2 -0
  332. package/dist/node_modules/@boombot/plugins/installer.d.ts +45 -0
  333. package/dist/node_modules/@boombot/plugins/installer.js +487 -0
  334. package/dist/node_modules/@boombot/plugins/manager.d.ts +23 -0
  335. package/dist/node_modules/@boombot/plugins/manager.js +243 -0
  336. package/dist/node_modules/@boombot/plugins/package.json +9 -0
  337. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-channels.d.ts +125 -0
  338. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-channels.js +76 -0
  339. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-plugins.d.ts +220 -0
  340. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-plugins.js +60 -0
  341. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-scheduler.d.ts +33 -0
  342. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands-scheduler.js +25 -0
  343. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands.d.ts +4349 -0
  344. package/dist/node_modules/@boombot/protocol/gateway-protocol/commands.js +563 -0
  345. package/dist/node_modules/@boombot/protocol/gateway-protocol/envelope.d.ts +32 -0
  346. package/dist/node_modules/@boombot/protocol/gateway-protocol/envelope.js +61 -0
  347. package/dist/node_modules/@boombot/protocol/gateway-protocol/errors.d.ts +13 -0
  348. package/dist/node_modules/@boombot/protocol/gateway-protocol/errors.js +16 -0
  349. package/dist/node_modules/@boombot/protocol/gateway-protocol/events.d.ts +567 -0
  350. package/dist/node_modules/@boombot/protocol/gateway-protocol/events.js +395 -0
  351. package/dist/node_modules/@boombot/protocol/gateway-protocol/index.d.ts +20 -0
  352. package/dist/node_modules/@boombot/protocol/gateway-protocol/index.js +13 -0
  353. package/dist/node_modules/@boombot/protocol/gateway-protocol/types.d.ts +91 -0
  354. package/dist/node_modules/@boombot/protocol/gateway-protocol/types.js +7 -0
  355. package/dist/node_modules/@boombot/protocol/index.d.ts +4 -0
  356. package/dist/node_modules/@boombot/protocol/index.js +3 -0
  357. package/dist/node_modules/@boombot/protocol/package.json +9 -0
  358. package/dist/node_modules/@boombot/protocol/plugin-sdk/channel.d.ts +41 -0
  359. package/dist/node_modules/@boombot/protocol/plugin-sdk/channel.js +17 -0
  360. package/dist/node_modules/@boombot/protocol/plugin-sdk/index.d.ts +10 -0
  361. package/dist/node_modules/@boombot/protocol/plugin-sdk/index.js +10 -0
  362. package/dist/node_modules/@boombot/protocol/plugin-sdk/manifest.d.ts +58 -0
  363. package/dist/node_modules/@boombot/protocol/plugin-sdk/manifest.js +116 -0
  364. package/dist/node_modules/@boombot/protocol/plugin-sdk/plugin.d.ts +25 -0
  365. package/dist/node_modules/@boombot/protocol/plugin-sdk/plugin.js +1 -0
  366. package/dist/node_modules/@boombot/protocol/providers/cipher.d.ts +7 -0
  367. package/dist/node_modules/@boombot/protocol/providers/cipher.js +52 -0
  368. package/dist/node_modules/@boombot/protocol/providers/index.d.ts +19 -0
  369. package/dist/node_modules/@boombot/protocol/providers/index.js +19 -0
  370. package/dist/node_modules/@boombot/protocol/providers/key-roulette.d.ts +79 -0
  371. package/dist/node_modules/@boombot/protocol/providers/key-roulette.js +81 -0
  372. package/dist/node_modules/@boombot/protocol/providers/probe.d.ts +29 -0
  373. package/dist/node_modules/@boombot/protocol/providers/probe.js +96 -0
  374. package/dist/node_modules/@boombot/protocol/providers/profiles/anthropic.d.ts +11 -0
  375. package/dist/node_modules/@boombot/protocol/providers/profiles/anthropic.js +11 -0
  376. package/dist/node_modules/@boombot/protocol/providers/profiles/custom.d.ts +22 -0
  377. package/dist/node_modules/@boombot/protocol/providers/profiles/custom.js +222 -0
  378. package/dist/node_modules/@boombot/protocol/providers/profiles/deepseek.d.ts +7 -0
  379. package/dist/node_modules/@boombot/protocol/providers/profiles/deepseek.js +9 -0
  380. package/dist/node_modules/@boombot/protocol/providers/profiles/google.d.ts +10 -0
  381. package/dist/node_modules/@boombot/protocol/providers/profiles/google.js +10 -0
  382. package/dist/node_modules/@boombot/protocol/providers/profiles/index.d.ts +31 -0
  383. package/dist/node_modules/@boombot/protocol/providers/profiles/index.js +56 -0
  384. package/dist/node_modules/@boombot/protocol/providers/profiles/local.d.ts +10 -0
  385. package/dist/node_modules/@boombot/protocol/providers/profiles/local.js +11 -0
  386. package/dist/node_modules/@boombot/protocol/providers/profiles/mistral.d.ts +7 -0
  387. package/dist/node_modules/@boombot/protocol/providers/profiles/mistral.js +9 -0
  388. package/dist/node_modules/@boombot/protocol/providers/profiles/openai-compatible.d.ts +10 -0
  389. package/dist/node_modules/@boombot/protocol/providers/profiles/openai-compatible.js +10 -0
  390. package/dist/node_modules/@boombot/protocol/providers/profiles/openai.d.ts +7 -0
  391. package/dist/node_modules/@boombot/protocol/providers/profiles/openai.js +11 -0
  392. package/dist/node_modules/@boombot/protocol/providers/profiles/types.d.ts +58 -0
  393. package/dist/node_modules/@boombot/protocol/providers/profiles/types.js +1 -0
  394. package/dist/node_modules/@boombot/protocol/providers/profiles/xai.d.ts +7 -0
  395. package/dist/node_modules/@boombot/protocol/providers/profiles/xai.js +10 -0
  396. package/dist/node_modules/@boombot/protocol/providers/request-profile.d.ts +102 -0
  397. package/dist/node_modules/@boombot/protocol/providers/request-profile.js +118 -0
  398. package/dist/node_modules/@boombot/protocol/providers/service.d.ts +2 -0
  399. package/dist/node_modules/@boombot/protocol/providers/service.js +418 -0
  400. package/dist/node_modules/@boombot/protocol/providers/types.d.ts +141 -0
  401. package/dist/node_modules/@boombot/protocol/providers/types.js +16 -0
  402. package/dist/node_modules/@boombot/sandbox/fs-path.d.ts +13 -0
  403. package/dist/node_modules/@boombot/sandbox/fs-path.js +79 -0
  404. package/dist/node_modules/@boombot/sandbox/index.d.ts +13 -0
  405. package/dist/node_modules/@boombot/sandbox/index.js +13 -0
  406. package/dist/node_modules/@boombot/sandbox/native.d.ts +39 -0
  407. package/dist/node_modules/@boombot/sandbox/native.js +224 -0
  408. package/dist/node_modules/@boombot/sandbox/package.json +9 -0
  409. package/dist/node_modules/@boombot/sandbox/sandbox.d.ts +92 -0
  410. package/dist/node_modules/@boombot/sandbox/sandbox.js +229 -0
  411. package/dist/node_modules/@boombot/security/harness-guard/boundary.d.ts +22 -0
  412. package/dist/node_modules/@boombot/security/harness-guard/boundary.js +105 -0
  413. package/dist/node_modules/@boombot/security/harness-guard/gates.d.ts +90 -0
  414. package/dist/node_modules/@boombot/security/harness-guard/gates.js +791 -0
  415. package/dist/node_modules/@boombot/security/harness-guard/index.d.ts +23 -0
  416. package/dist/node_modules/@boombot/security/harness-guard/index.js +23 -0
  417. package/dist/node_modules/@boombot/security/harness-guard/policy.d.ts +20 -0
  418. package/dist/node_modules/@boombot/security/harness-guard/policy.js +70 -0
  419. package/dist/node_modules/@boombot/security/harness-guard/sanitizer.d.ts +53 -0
  420. package/dist/node_modules/@boombot/security/harness-guard/sanitizer.js +145 -0
  421. package/dist/node_modules/@boombot/security/harness-guard/types.d.ts +71 -0
  422. package/dist/node_modules/@boombot/security/harness-guard/types.js +10 -0
  423. package/dist/node_modules/@boombot/security/harness-guard/verifier.d.ts +59 -0
  424. package/dist/node_modules/@boombot/security/harness-guard/verifier.js +169 -0
  425. package/dist/node_modules/@boombot/security/index.d.ts +5 -0
  426. package/dist/node_modules/@boombot/security/index.js +9 -0
  427. package/dist/node_modules/@boombot/security/package.json +9 -0
  428. package/dist/node_modules/@boombot/security/policy/approval.d.ts +117 -0
  429. package/dist/node_modules/@boombot/security/policy/approval.js +223 -0
  430. package/dist/node_modules/@boombot/security/reasoning-guard/claim-extractor.d.ts +10 -0
  431. package/dist/node_modules/@boombot/security/reasoning-guard/claim-extractor.js +124 -0
  432. package/dist/node_modules/@boombot/security/reasoning-guard/evidence-ledger.d.ts +25 -0
  433. package/dist/node_modules/@boombot/security/reasoning-guard/evidence-ledger.js +70 -0
  434. package/dist/node_modules/@boombot/security/reasoning-guard/gate.d.ts +38 -0
  435. package/dist/node_modules/@boombot/security/reasoning-guard/gate.js +61 -0
  436. package/dist/node_modules/@boombot/security/reasoning-guard/grounding-check.d.ts +12 -0
  437. package/dist/node_modules/@boombot/security/reasoning-guard/grounding-check.js +234 -0
  438. package/dist/node_modules/@boombot/security/reasoning-guard/index.d.ts +17 -0
  439. package/dist/node_modules/@boombot/security/reasoning-guard/index.js +13 -0
  440. package/dist/node_modules/@boombot/security/reasoning-guard/policy.d.ts +15 -0
  441. package/dist/node_modules/@boombot/security/reasoning-guard/policy.js +39 -0
  442. package/dist/node_modules/@boombot/security/reasoning-guard/types.d.ts +46 -0
  443. package/dist/node_modules/@boombot/security/reasoning-guard/types.js +7 -0
  444. package/dist/node_modules/@boombot/security/security/approval.d.ts +63 -0
  445. package/dist/node_modules/@boombot/security/security/approval.js +140 -0
  446. package/dist/node_modules/@boombot/security/security/audit.d.ts +39 -0
  447. package/dist/node_modules/@boombot/security/security/audit.js +70 -0
  448. package/dist/node_modules/@boombot/security/security/index.d.ts +12 -0
  449. package/dist/node_modules/@boombot/security/security/index.js +12 -0
  450. package/dist/node_modules/@boombot/security/security/trust.d.ts +79 -0
  451. package/dist/node_modules/@boombot/security/security/trust.js +87 -0
  452. package/dist/package.json +5 -0
  453. package/dist/proto/agent_core.proto +56 -0
  454. package/dist/python/agent-core-python/pyproject.toml +40 -0
  455. package/dist/python/agent-core-python/src/boombot_agent/__init__.py +5 -0
  456. package/dist/python/agent-core-python/src/boombot_agent/generated/__init__.py +0 -0
  457. package/dist/python/agent-core-python/src/boombot_agent/generated/agent_core_pb2.py +54 -0
  458. package/dist/python/agent-core-python/src/boombot_agent/generated/agent_core_pb2_grpc.py +140 -0
  459. package/dist/python/agent-core-python/src/boombot_agent/rpc.py +265 -0
  460. package/dist/python/agent-core-python/src/boombot_agent/turn.py +577 -0
  461. package/dist/python/agent-core-python/src/boombot_ml/__init__.py +12 -0
  462. package/dist/python/agent-core-python/src/boombot_ml/embeddings.py +58 -0
  463. package/dist/python/agent-core-python/src/boombot_ml/training.py +156 -0
  464. package/dist/python/agent-core-python/uv.lock +2856 -0
  465. package/dist/web/assets/ChatView-BZrSD-64.js +262 -0
  466. package/dist/web/assets/ChatView-Cahbjez6.css +1 -0
  467. package/dist/web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  468. package/dist/web/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  469. package/dist/web/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  470. package/dist/web/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  471. package/dist/web/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  472. package/dist/web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  473. package/dist/web/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  474. package/dist/web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  475. package/dist/web/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  476. package/dist/web/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  477. package/dist/web/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  478. package/dist/web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  479. package/dist/web/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  480. package/dist/web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  481. package/dist/web/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  482. package/dist/web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  483. package/dist/web/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  484. package/dist/web/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  485. package/dist/web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  486. package/dist/web/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  487. package/dist/web/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  488. package/dist/web/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  489. package/dist/web/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  490. package/dist/web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  491. package/dist/web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  492. package/dist/web/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  493. package/dist/web/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  494. package/dist/web/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  495. package/dist/web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  496. package/dist/web/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  497. package/dist/web/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  498. package/dist/web/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  499. package/dist/web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  500. package/dist/web/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  501. package/dist/web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  502. package/dist/web/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  503. package/dist/web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  504. package/dist/web/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  505. package/dist/web/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  506. package/dist/web/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  507. package/dist/web/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  508. package/dist/web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  509. package/dist/web/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  510. package/dist/web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  511. package/dist/web/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  512. package/dist/web/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  513. package/dist/web/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  514. package/dist/web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  515. package/dist/web/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  516. package/dist/web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  517. package/dist/web/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  518. package/dist/web/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  519. package/dist/web/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  520. package/dist/web/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  521. package/dist/web/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  522. package/dist/web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  523. package/dist/web/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  524. package/dist/web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  525. package/dist/web/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  526. package/dist/web/assets/MemoryView-BJbXqqs7.css +1 -0
  527. package/dist/web/assets/MemoryView-BfMq_6CD.js +1 -0
  528. package/dist/web/assets/SchedulesView-B22QmPR-.js +1 -0
  529. package/dist/web/assets/SchedulesView-C6XK7A8a.css +1 -0
  530. package/dist/web/assets/SessionsView-C1dqdhxI.css +1 -0
  531. package/dist/web/assets/SessionsView-DS0-aH2a.js +1 -0
  532. package/dist/web/assets/TasksView-Dtasg4hd.css +1 -0
  533. package/dist/web/assets/TasksView-ey0FLsW8.js +2 -0
  534. package/dist/web/assets/Textarea-DN3Zybl1.js +1 -0
  535. package/dist/web/assets/Tooltip-Bn2cqFPz.css +1 -0
  536. package/dist/web/assets/Tooltip-MzV2Gqnc.js +1 -0
  537. package/dist/web/assets/browser-Bnt73-Ub.js +8 -0
  538. package/dist/web/assets/index-BL8bi7Yt.css +1 -0
  539. package/dist/web/assets/index-CuPR73Tn.js +73 -0
  540. package/dist/web/favicon.svg +4 -0
  541. package/dist/web/index.html +26 -0
  542. package/dist/web/logo.jpg +0 -0
  543. package/dist/web/logo.png +0 -0
  544. package/package.json +51 -4
@@ -0,0 +1,234 @@
1
+ /** Lowercase + collapse whitespace, so matching ignores casing and layout. */
2
+ function normalize(text) {
3
+ return text.toLowerCase().replace(/\s+/gu, ' ').trim();
4
+ }
5
+ // Order matters: ISO dates and DD/MM/YYYY dates before bare decimals, times
6
+ // before bare numbers, so "2026-10-03" and "14:30" extract as single tokens.
7
+ const NUMBER_TOKEN_RE = /\d{4}-\d{2}-\d{2}|\d{1,2}[/-]\d{1,2}[/-]\d{2,4}|\d{1,2}:\d{2}|\d+(?:\.\d+)?%?/g;
8
+ function extractNumberTokens(text) {
9
+ NUMBER_TOKEN_RE.lastIndex = 0;
10
+ const tokens = [];
11
+ let m;
12
+ while ((m = NUMBER_TOKEN_RE.exec(text)) !== null) {
13
+ tokens.push(m[0]);
14
+ }
15
+ return tokens;
16
+ }
17
+ /**
18
+ * "95" and "95%" denote the same numeric value for grounding purposes
19
+ * (the extractor may keep or drop the space before `%`). Strip it before
20
+ * comparing so a cosmetic `%` never flips a verdict.
21
+ */
22
+ function canonicalNumber(token) {
23
+ return token.endsWith('%') ? token.slice(0, -1) : token;
24
+ }
25
+ const QUOTE_RE = /"([^"]+)"|"([^"]+)"|«([^»]+)»/g;
26
+ function extractQuotes(text) {
27
+ QUOTE_RE.lastIndex = 0;
28
+ const quotes = [];
29
+ let m;
30
+ while ((m = QUOTE_RE.exec(text)) !== null) {
31
+ const raw = m[1] ?? m[2] ?? m[3] ?? '';
32
+ const quote = normalize(raw);
33
+ if (quote.length >= 2) {
34
+ quotes.push(quote);
35
+ }
36
+ }
37
+ return quotes;
38
+ }
39
+ /**
40
+ * ~60 Vietnamese + English stopwords. Removed from the claim side before
41
+ * scoring so overlap measures content words, not glue words.
42
+ */
43
+ const STOPWORDS = new Set([
44
+ 'là',
45
+ 'của',
46
+ 'và',
47
+ 'đã',
48
+ 'trong',
49
+ 'trên',
50
+ 'với',
51
+ 'cho',
52
+ 'này',
53
+ 'đó',
54
+ 'đây',
55
+ 'các',
56
+ 'một',
57
+ 'những',
58
+ 'bị',
59
+ 'được',
60
+ 'sẽ',
61
+ 'có',
62
+ 'không',
63
+ 'còn',
64
+ 'cũng',
65
+ 'rất',
66
+ 'như',
67
+ 'từ',
68
+ 'đến',
69
+ 'ở',
70
+ 'lại',
71
+ 'mà',
72
+ 'thì',
73
+ 'nếu',
74
+ 'khi',
75
+ 'về',
76
+ 'the',
77
+ 'a',
78
+ 'an',
79
+ 'is',
80
+ 'are',
81
+ 'was',
82
+ 'were',
83
+ 'has',
84
+ 'have',
85
+ 'be',
86
+ 'been',
87
+ 'being',
88
+ 'to',
89
+ 'of',
90
+ 'in',
91
+ 'on',
92
+ 'and',
93
+ 'or',
94
+ 'for',
95
+ 'with',
96
+ 'that',
97
+ 'this',
98
+ 'it',
99
+ 'its',
100
+ 'as',
101
+ 'at',
102
+ 'by',
103
+ 'from',
104
+ 'but',
105
+ 'not',
106
+ ]);
107
+ function tokenize(text) {
108
+ return normalize(text)
109
+ .split(/[^\p{L}\p{N}]+/u)
110
+ .filter((t) => t.length > 0 && !STOPWORDS.has(t));
111
+ }
112
+ function checkNumberClaim(claim, evidences) {
113
+ const claimTokens = extractNumberTokens(normalize(claim.text)).map(canonicalNumber);
114
+ if (claimTokens.length === 0) {
115
+ return {
116
+ claimId: claim.id,
117
+ verdict: 'ungrounded',
118
+ evidenceIds: [],
119
+ reason: 'factual-number claim contains no numeric tokens to verify',
120
+ };
121
+ }
122
+ const supported = new Set();
123
+ for (const evidence of evidences) {
124
+ for (const token of extractNumberTokens(normalize(evidence.excerpt))) {
125
+ supported.add(canonicalNumber(token));
126
+ }
127
+ }
128
+ const missing = claimTokens.filter((token) => !supported.has(token));
129
+ if (missing.length > 0) {
130
+ return {
131
+ claimId: claim.id,
132
+ verdict: 'ungrounded',
133
+ evidenceIds: [],
134
+ reason: `missing number token(s): ${missing.join(', ')}`,
135
+ };
136
+ }
137
+ const evidenceIds = [];
138
+ for (const evidence of evidences) {
139
+ const evidenceTokens = new Set(extractNumberTokens(normalize(evidence.excerpt)).map(canonicalNumber));
140
+ if (claimTokens.some((token) => evidenceTokens.has(token))) {
141
+ evidenceIds.push(evidence.id);
142
+ }
143
+ }
144
+ return { claimId: claim.id, verdict: 'grounded', evidenceIds };
145
+ }
146
+ function checkQuoteClaim(claim, evidences) {
147
+ const quotes = extractQuotes(normalize(claim.text));
148
+ if (quotes.length === 0) {
149
+ return {
150
+ claimId: claim.id,
151
+ verdict: 'ungrounded',
152
+ evidenceIds: [],
153
+ reason: 'quote claim contains no quotable segment to verify',
154
+ };
155
+ }
156
+ const normalizedExcerpts = evidences.map((e) => normalize(e.excerpt));
157
+ const missing = quotes.filter((quote) => !normalizedExcerpts.some((excerpt) => excerpt.includes(quote)));
158
+ if (missing.length > 0) {
159
+ const first = missing[0] ?? '';
160
+ return {
161
+ claimId: claim.id,
162
+ verdict: 'ungrounded',
163
+ evidenceIds: [],
164
+ reason: `quote not found in evidence: "${first}"`,
165
+ };
166
+ }
167
+ const evidenceIds = [];
168
+ for (const evidence of evidences) {
169
+ const excerpt = normalize(evidence.excerpt);
170
+ if (quotes.some((quote) => excerpt.includes(quote))) {
171
+ evidenceIds.push(evidence.id);
172
+ }
173
+ }
174
+ return { claimId: claim.id, verdict: 'grounded', evidenceIds };
175
+ }
176
+ function checkOverlapClaim(claim, evidences, minEntityOverlap) {
177
+ const claimTokens = tokenize(claim.text);
178
+ if (claimTokens.length === 0) {
179
+ return {
180
+ claimId: claim.id,
181
+ verdict: 'ungrounded',
182
+ evidenceIds: [],
183
+ reason: 'no verifiable tokens after stopword removal',
184
+ };
185
+ }
186
+ const matchingIds = [];
187
+ let best = 0;
188
+ for (const evidence of evidences) {
189
+ const evidenceTokens = new Set(tokenize(evidence.excerpt));
190
+ let hits = 0;
191
+ for (const token of claimTokens) {
192
+ if (evidenceTokens.has(token)) {
193
+ hits += 1;
194
+ }
195
+ }
196
+ const score = hits / claimTokens.length;
197
+ if (score > best) {
198
+ best = score;
199
+ }
200
+ if (score >= minEntityOverlap) {
201
+ matchingIds.push(evidence.id);
202
+ }
203
+ }
204
+ if (matchingIds.length === 0) {
205
+ return {
206
+ claimId: claim.id,
207
+ verdict: 'ungrounded',
208
+ evidenceIds: [],
209
+ reason: `best overlap ${best.toFixed(2)} < threshold ${minEntityOverlap}`,
210
+ };
211
+ }
212
+ return { claimId: claim.id, verdict: 'grounded', evidenceIds: matchingIds };
213
+ }
214
+ /**
215
+ * Verify every claim against the evidence ledger.
216
+ *
217
+ * Conservative by design: when in doubt the claim is `ungrounded`, never
218
+ * silently passed. `non-falsifiable` claims always pass without evidence.
219
+ */
220
+ export function checkGrounding(claims, evidences, opts) {
221
+ return claims.map((claim) => {
222
+ switch (claim.kind) {
223
+ case 'non-falsifiable':
224
+ return { claimId: claim.id, verdict: 'non-falsifiable', evidenceIds: [] };
225
+ case 'factual-number':
226
+ return checkNumberClaim(claim, evidences);
227
+ case 'quote':
228
+ return checkQuoteClaim(claim, evidences);
229
+ case 'factual-entity':
230
+ case 'factual-status':
231
+ return checkOverlapClaim(claim, evidences, opts.minEntityOverlap);
232
+ }
233
+ });
234
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Public API of `@boombot/security`.
3
+ *
4
+ * Deterministic, rule-based verification layer (no LLM): extract factual
5
+ * claims from a draft, check them against an evidence ledger of tool
6
+ * outputs, and enforce a warn/strict/off policy.
7
+ */
8
+ export { extractClaims } from './claim-extractor.js';
9
+ export { EvidenceLedger } from './evidence-ledger.js';
10
+ export type { RecordInput } from './evidence-ledger.js';
11
+ export { checkGrounding } from './grounding-check.js';
12
+ export type { GroundingOptions } from './grounding-check.js';
13
+ export { applyPolicy, UNGROUNDED_DISCLAIMER } from './policy.js';
14
+ export { verifyTurn, verifyTurnWithClaims } from './gate.js';
15
+ export type { TurnResult, TurnVerification } from './gate.js';
16
+ export { DEFAULT_GUARD_CONFIG } from './types.js';
17
+ export type { Claim, ClaimKind, ClaimSpan, ClaimVerdict, Evidence, GuardConfig, GuardMode, VerificationReport, } from './types.js';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Public API of `@boombot/security`.
3
+ *
4
+ * Deterministic, rule-based verification layer (no LLM): extract factual
5
+ * claims from a draft, check them against an evidence ledger of tool
6
+ * outputs, and enforce a warn/strict/off policy.
7
+ */
8
+ export { extractClaims } from './claim-extractor.js';
9
+ export { EvidenceLedger } from './evidence-ledger.js';
10
+ export { checkGrounding } from './grounding-check.js';
11
+ export { applyPolicy, UNGROUNDED_DISCLAIMER } from './policy.js';
12
+ export { verifyTurn, verifyTurnWithClaims } from './gate.js';
13
+ export { DEFAULT_GUARD_CONFIG } from './types.js';
@@ -0,0 +1,15 @@
1
+ import type { Claim, ClaimVerdict, GuardMode } from './types.js';
2
+ /** Replacement text for ungrounded factual spans in `strict` mode. */
3
+ export declare const UNGROUNDED_DISCLAIMER = "[unverified]";
4
+ /**
5
+ * Enforce the guard mode on a verified draft.
6
+ *
7
+ * - `off` / `warn`: return the text untouched (`warn` only reports).
8
+ * - `strict`: replace the `[start, end)` span of every ungrounded factual
9
+ * claim with a disclaimer. Spans are spliced from the end backwards so
10
+ * earlier offsets stay valid.
11
+ *
12
+ * The policy never invents replacement content: it only deletes
13
+ * unverifiable spans and marks them.
14
+ */
15
+ export declare function applyPolicy(text: string, claims: readonly Claim[], verdicts: readonly ClaimVerdict[], mode: GuardMode): string;
@@ -0,0 +1,39 @@
1
+ /** Replacement text for ungrounded factual spans in `strict` mode. */
2
+ export const UNGROUNDED_DISCLAIMER = '[unverified]';
3
+ /**
4
+ * Enforce the guard mode on a verified draft.
5
+ *
6
+ * - `off` / `warn`: return the text untouched (`warn` only reports).
7
+ * - `strict`: replace the `[start, end)` span of every ungrounded factual
8
+ * claim with a disclaimer. Spans are spliced from the end backwards so
9
+ * earlier offsets stay valid.
10
+ *
11
+ * The policy never invents replacement content: it only deletes
12
+ * unverifiable spans and marks them.
13
+ */
14
+ export function applyPolicy(text, claims, verdicts, mode) {
15
+ if (mode === 'off' || mode === 'warn') {
16
+ return text;
17
+ }
18
+ const verdictByClaim = new Map();
19
+ for (const verdict of verdicts) {
20
+ verdictByClaim.set(verdict.claimId, verdict);
21
+ }
22
+ const targets = [];
23
+ for (const claim of claims) {
24
+ if (claim.kind === 'non-falsifiable') {
25
+ continue;
26
+ }
27
+ const verdict = verdictByClaim.get(claim.id);
28
+ if (verdict !== undefined && verdict.verdict === 'ungrounded') {
29
+ targets.push({ start: claim.span.start, end: claim.span.end });
30
+ }
31
+ }
32
+ targets.sort((a, b) => b.start - a.start);
33
+ let result = text;
34
+ for (const target of targets) {
35
+ result =
36
+ result.slice(0, target.start) + UNGROUNDED_DISCLAIMER + result.slice(target.end);
37
+ }
38
+ return result;
39
+ }
@@ -0,0 +1,46 @@
1
+ /** Shared types for the deterministic reasoning-verification layer. */
2
+ export type ClaimKind = 'factual-number' | 'factual-entity' | 'factual-status' | 'quote' | 'non-falsifiable';
3
+ export interface ClaimSpan {
4
+ readonly start: number;
5
+ readonly end: number;
6
+ }
7
+ export interface Claim {
8
+ readonly id: string;
9
+ readonly text: string;
10
+ readonly kind: ClaimKind;
11
+ readonly span: ClaimSpan;
12
+ }
13
+ export interface Evidence {
14
+ readonly id: string;
15
+ readonly tool: string;
16
+ readonly argsHash: string;
17
+ readonly excerpt: string;
18
+ readonly ts: number;
19
+ }
20
+ export type Verdict = 'grounded' | 'ungrounded' | 'non-falsifiable';
21
+ export interface ClaimVerdict {
22
+ readonly claimId: string;
23
+ readonly verdict: Verdict;
24
+ readonly evidenceIds: readonly string[];
25
+ readonly reason?: string;
26
+ }
27
+ export interface VerificationReport {
28
+ readonly verdicts: readonly ClaimVerdict[];
29
+ readonly ungroundedCount: number;
30
+ readonly mode: GuardMode;
31
+ readonly msElapsed: number;
32
+ readonly truncated: boolean;
33
+ }
34
+ export type GuardMode = 'strict' | 'warn' | 'off';
35
+ export interface GuardConfig {
36
+ readonly mode: GuardMode;
37
+ readonly maxClaimChars?: number;
38
+ readonly maxExcerptChars?: number;
39
+ readonly minEntityOverlap?: number;
40
+ }
41
+ export declare const DEFAULT_GUARD_CONFIG: {
42
+ readonly mode: GuardMode;
43
+ readonly maxClaimChars: number;
44
+ readonly maxExcerptChars: number;
45
+ readonly minEntityOverlap: number;
46
+ };
@@ -0,0 +1,7 @@
1
+ /** Shared types for the deterministic reasoning-verification layer. */
2
+ export const DEFAULT_GUARD_CONFIG = {
3
+ mode: 'warn',
4
+ maxClaimChars: 4000,
5
+ maxExcerptChars: 500,
6
+ minEntityOverlap: 0.6,
7
+ };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @boombot/security — approval policy (mandatory middleware, not an optional hook).
3
+ *
4
+ * Honest framing (root SECURITY.md §1): approval and denylists are
5
+ * **accident prevention**, not a security boundary against a determined
6
+ * adversary. The real boundary is the OS (sandbox). This module makes the
7
+ * accident-prevention layer deterministic: a pure function of
8
+ * (policy, tool call) → decision, no LLM judgement involved.
9
+ *
10
+ * Risk floors:
11
+ * - known-destructive commands → `deny` (never executes, even with approval)
12
+ * - unknown or side-effecting tools → `require-approval`
13
+ * - known read-only tools → `allow`
14
+ * - subagent policy: `require-approval` escalates to `deny`
15
+ * (a child never gets a looser decision than its parent)
16
+ */
17
+ import type { AuditSink } from './audit.js';
18
+ /** A tool call proposed by the agent. Args are untrusted data. */
19
+ export interface ToolCall {
20
+ /** Tool name, e.g. 'exec', 'file.write', 'memory.search'. */
21
+ readonly tool: string;
22
+ /** Arguments. Never interpolated into shell/SQL — validated per tool. */
23
+ readonly args: Readonly<Record<string, unknown>>;
24
+ /** Authenticated principal id requesting the call. */
25
+ readonly principalId: string;
26
+ }
27
+ export type ApprovalDecision = 'allow' | 'deny' | 'require-approval';
28
+ export interface PolicyEvaluation {
29
+ readonly decision: ApprovalDecision;
30
+ /** Which rule fired. Stable strings for audit. */
31
+ readonly rule: string;
32
+ readonly reason: string;
33
+ }
34
+ /** A policy that deterministically evaluates tool calls. */
35
+ export interface ApprovalPolicy {
36
+ evaluate(call: ToolCall): PolicyEvaluation;
37
+ }
38
+ export interface ApprovalPolicyOptions {
39
+ /** Extra tools that are always allowed (read-only, side-effect free). */
40
+ readonly allowTools?: readonly string[];
41
+ /** Extra tools that are always denied. */
42
+ readonly denyTools?: readonly string[];
43
+ /** Sink receiving one audit event per non-allow decision. Optional. */
44
+ readonly auditSink?: AuditSink;
45
+ /** Autonomous mode: allow non-destructive tools without HITL pause. */
46
+ readonly autonomous?: boolean;
47
+ }
48
+ /** Default deterministic approval policy with risk floors. */
49
+ export declare class DefaultApprovalPolicy implements ApprovalPolicy {
50
+ private readonly allowTools;
51
+ private readonly denyTools;
52
+ private readonly auditSink?;
53
+ private readonly autonomous;
54
+ constructor(options?: ApprovalPolicyOptions);
55
+ evaluate(call: ToolCall): PolicyEvaluation;
56
+ private decide;
57
+ }
58
+ /**
59
+ * Derive a child (subagent) policy from a parent policy. A subagent never
60
+ * gets a looser decision: `require-approval` escalates to `deny` because
61
+ * there is no operator in the loop to approve on its behalf.
62
+ */
63
+ export declare function deriveSubagentPolicy(parent: ApprovalPolicy): ApprovalPolicy;
@@ -0,0 +1,140 @@
1
+ /**
2
+ * @boombot/security — approval policy (mandatory middleware, not an optional hook).
3
+ *
4
+ * Honest framing (root SECURITY.md §1): approval and denylists are
5
+ * **accident prevention**, not a security boundary against a determined
6
+ * adversary. The real boundary is the OS (sandbox). This module makes the
7
+ * accident-prevention layer deterministic: a pure function of
8
+ * (policy, tool call) → decision, no LLM judgement involved.
9
+ *
10
+ * Risk floors:
11
+ * - known-destructive commands → `deny` (never executes, even with approval)
12
+ * - unknown or side-effecting tools → `require-approval`
13
+ * - known read-only tools → `allow`
14
+ * - subagent policy: `require-approval` escalates to `deny`
15
+ * (a child never gets a looser decision than its parent)
16
+ */
17
+ /** Tools whose only effect is reading state — safe to auto-allow. */
18
+ const DEFAULT_ALLOW_TOOLS = new Set([
19
+ 'memory.search',
20
+ 'memory.recall',
21
+ 'provider.list',
22
+ 'scheduler.list',
23
+ 'scheduler.get',
24
+ 'file.read',
25
+ 'help',
26
+ 'research.search',
27
+ 'research.extract',
28
+ 'research.deep',
29
+ 'research.academic',
30
+ 'research.crawl',
31
+ ]);
32
+ /** Destructive command patterns — deny floor, no approval can override. */
33
+ const DESTRUCTIVE_PATTERNS = [
34
+ { pattern: /\brm\s+(-[a-z]*r[a-z]*\s+|--recursive\s+)(\S*\s+)*\/( |$)/, label: 'recursive delete from /' },
35
+ { pattern: /:\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;?\s*:/, label: 'fork bomb' },
36
+ { pattern: /\bmkfs(\.\w+)?\b/, label: 'filesystem format' },
37
+ { pattern: /\bdd\b[^;|&]*\bof=\/dev\//, label: 'raw disk write' },
38
+ { pattern: /\b(shutdown|reboot|halt|poweroff)\b/, label: 'host power control' },
39
+ { pattern: /\bcurl\b[^|]*\|\s*(ba)?sh\b/, label: 'remote script piped to shell' },
40
+ { pattern: /\bwget\b[^|]*\|\s*(ba)?sh\b/, label: 'remote script piped to shell' },
41
+ { pattern: />\s*\/dev\/(sd[a-z]|nvme|hd[a-z]|vd[a-z])/, label: 'raw device overwrite' },
42
+ { pattern: /chmod\s+-R\s+777\s+\//, label: 'recursive chmod 777 from /' },
43
+ ];
44
+ function argsToText(args) {
45
+ return Object.values(args)
46
+ .map((v) => (typeof v === 'string' ? v : JSON.stringify(v) ?? ''))
47
+ .join('\n');
48
+ }
49
+ /** Default deterministic approval policy with risk floors. */
50
+ export class DefaultApprovalPolicy {
51
+ allowTools;
52
+ denyTools;
53
+ auditSink;
54
+ autonomous;
55
+ constructor(options = {}) {
56
+ this.allowTools = new Set([...DEFAULT_ALLOW_TOOLS, ...(options.allowTools ?? [])]);
57
+ this.denyTools = new Set(options.denyTools ?? []);
58
+ this.auditSink = options.auditSink;
59
+ this.autonomous = options.autonomous ?? false;
60
+ }
61
+ evaluate(call) {
62
+ const result = this.decide(call);
63
+ if (result.decision !== 'allow' && this.auditSink !== undefined) {
64
+ this.auditSink.append({
65
+ actor: call.principalId,
66
+ action: `approval.${result.decision}`,
67
+ target: call.tool,
68
+ meta: { rule: result.rule, reason: result.reason },
69
+ });
70
+ }
71
+ return result;
72
+ }
73
+ decide(call) {
74
+ if (this.denyTools.has(call.tool)) {
75
+ return { decision: 'deny', rule: 'deny-list', reason: `tool '${call.tool}' is on the deny list` };
76
+ }
77
+ if (this.allowTools.has(call.tool)) {
78
+ return { decision: 'allow', rule: 'allow-list', reason: `tool '${call.tool}' is read-only` };
79
+ }
80
+ // Destructive-command floor for shell-like tools: deny, no override.
81
+ if (call.tool === 'exec' || call.tool === 'shell' || call.tool === 'run_command' || call.tool === 'shell.exec') {
82
+ const text = argsToText(call.args);
83
+ for (const { pattern, label } of DESTRUCTIVE_PATTERNS) {
84
+ if (pattern.test(text)) {
85
+ return { decision: 'deny', rule: 'destructive-command', reason: `destructive pattern: ${label}` };
86
+ }
87
+ }
88
+ if (this.autonomous) {
89
+ return { decision: 'allow', rule: 'autonomous-mode', reason: 'autonomous mode enabled' };
90
+ }
91
+ return {
92
+ decision: 'require-approval',
93
+ rule: 'exec-default',
94
+ reason: 'shell execution always requires approval',
95
+ };
96
+ }
97
+ // If autonomous mode is enabled, non-destructive tools are automatically allowed.
98
+ if (this.autonomous) {
99
+ return { decision: 'allow', rule: 'autonomous-mode', reason: 'autonomous mode enabled' };
100
+ }
101
+ // Side-effecting tool families require approval by default (fail closed).
102
+ if (call.tool.startsWith('file.write') ||
103
+ call.tool.startsWith('secret.') ||
104
+ call.tool.startsWith('channel.send') ||
105
+ call.tool.startsWith('scheduler.') ||
106
+ call.tool.startsWith('memory.')) {
107
+ return {
108
+ decision: 'require-approval',
109
+ rule: 'side-effect-default',
110
+ reason: `tool '${call.tool}' has side effects`,
111
+ };
112
+ }
113
+ // Unknown tools: fail closed.
114
+ return {
115
+ decision: 'require-approval',
116
+ rule: 'unknown-tool',
117
+ reason: `tool '${call.tool}' is not recognized; defaulting to require-approval`,
118
+ };
119
+ }
120
+ }
121
+ /**
122
+ * Derive a child (subagent) policy from a parent policy. A subagent never
123
+ * gets a looser decision: `require-approval` escalates to `deny` because
124
+ * there is no operator in the loop to approve on its behalf.
125
+ */
126
+ export function deriveSubagentPolicy(parent) {
127
+ return {
128
+ evaluate(call) {
129
+ const parentResult = parent.evaluate(call);
130
+ if (parentResult.decision === 'require-approval') {
131
+ return {
132
+ decision: 'deny',
133
+ rule: 'subagent-escalation',
134
+ reason: `parent required approval for '${call.tool}'; subagents cannot request approval → deny`,
135
+ };
136
+ }
137
+ return parentResult;
138
+ },
139
+ };
140
+ }
@@ -0,0 +1,39 @@
1
+ /** A single auditable security event. Never carries secret values. */
2
+ export interface AuditEvent {
3
+ /** Unique id, assigned by the sink. */
4
+ readonly id: string;
5
+ /** ISO-8601 timestamp, assigned by the sink. */
6
+ readonly ts: string;
7
+ /** Authenticated actor id (from `createAuthenticatedPrincipal`, never raw input). */
8
+ readonly actor: string;
9
+ /** Machine-readable action, e.g. 'secret.rotate', 'approval.deny', 'memory.revoke'. */
10
+ readonly action: string;
11
+ /** Optional target of the action (record id, tool name, …). */
12
+ readonly target?: string;
13
+ /** Structured detail. Secret-looking values are redacted on append. */
14
+ readonly meta?: Readonly<Record<string, unknown>>;
15
+ }
16
+ /** Input for `AuditSink.append` — id/ts are assigned by the sink. */
17
+ export type NewAuditEvent = Omit<AuditEvent, 'id' | 'ts'>;
18
+ /**
19
+ * Append-only audit sink. Implementations must guarantee:
20
+ * - every appended event is persisted before `append` returns;
21
+ * - events are never mutated or deleted through this interface.
22
+ */
23
+ export interface AuditSink {
24
+ append(event: NewAuditEvent): AuditEvent;
25
+ }
26
+ /** Redact secret-looking entries from audit metadata (defense in depth). */
27
+ export declare function redactAuditMeta(meta: Readonly<Record<string, unknown>> | undefined): Record<string, unknown> | undefined;
28
+ /** In-memory audit sink. Bounded (default 10k events, oldest dropped first). */
29
+ export declare class InMemoryAuditSink implements AuditSink {
30
+ private readonly maxEvents;
31
+ private readonly events;
32
+ constructor(maxEvents?: number);
33
+ append(event: NewAuditEvent): AuditEvent;
34
+ /** Newest last. Returns a copy — the log itself is immutable. */
35
+ list(): readonly AuditEvent[];
36
+ /** Filter by action prefix, e.g. 'approval.'. */
37
+ query(actionPrefix: string): readonly AuditEvent[];
38
+ get size(): number;
39
+ }