@theowlops/boombot 0.0.0-stage → 1.1.1

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 +244 -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,171 @@
1
+ /**
2
+ * Security guards for document parsing (`research.parse`).
3
+ *
4
+ * Parsing attacker-influenced bytes — a URL the model or user asked
5
+ * `research.extract` to read — is an attack surface: zip bombs, decompression
6
+ * bombs hidden in PDF content streams, and absurd entry counts. This module
7
+ * is the choke point every parser runs through: the same role
8
+ * `sanitizeExtractUrl` plays for URL inputs in `orchestrator.extract()`.
9
+ *
10
+ * Two lines of defense, because declared sizes are attacker-controlled:
11
+ * 1. Declared sizes are checked BEFORE inflating — cheaply rejects 42.zip-style
12
+ * entries whose headers claim gigabytes.
13
+ * 2. Actual output bytes are counted DURING streaming inflation — closes the
14
+ * understated/zero-size hole (the adm-zip CVE-2026-77301 class of bug, where
15
+ * a streaming path never checked accumulated output).
16
+ *
17
+ * Fail-closed: any cap breach throws `DocumentParseError`; a parser never
18
+ * returns a partial buffer.
19
+ */
20
+ import { createInflate, createInflateRaw, } from 'node:zlib';
21
+ export class DocumentParseError extends Error {
22
+ code;
23
+ constructor(code, message, options) {
24
+ super(message, options);
25
+ this.name = 'DocumentParseError';
26
+ this.code = code;
27
+ }
28
+ }
29
+ /**
30
+ * Hard cap on raw document bytes accepted for parsing. Matches
31
+ * `DEFAULT_MAX_RESPONSE_BYTES` in `../http.ts` so a document fetch can never
32
+ * exceed what a normal extract response may already hold.
33
+ */
34
+ export const MAX_DOCUMENT_BYTES = 5_242_880; // 5 MiB
35
+ /** Max entries in a ZIP central directory — a docx rarely has a few hundred. */
36
+ export const MAX_ZIP_ENTRIES = 2048;
37
+ /** Max declared uncompressed size of a single ZIP entry. */
38
+ export const MAX_ZIP_ENTRY_BYTES = 20_971_520; // 20 MiB
39
+ /** Max total decompressed bytes across every inflated entry/stream of one document. */
40
+ export const MAX_TOTAL_DECOMPRESSED_BYTES = 52_428_800; // 50 MiB
41
+ /**
42
+ * Declared compression ratio above this is treated as a bomb. Legitimate
43
+ * docx XML compresses ~5–20:1; real zip bombs start around 100,000:1, so
44
+ * 100:1 rejects every known bomb shape with wide margin for legit files.
45
+ */
46
+ export const MAX_COMPRESSION_RATIO = 100;
47
+ /** Max content streams inflated from a single PDF. */
48
+ export const MAX_PDF_STREAMS = 20_000;
49
+ /**
50
+ * Ceiling on extracted plain-text characters — defense-in-depth past the
51
+ * byte quotas, so parser output can never blow up turn context on its own.
52
+ */
53
+ export const MAX_EXTRACTED_CHARS = 200_000;
54
+ /** Reject an input buffer that exceeds {@link MAX_DOCUMENT_BYTES}. */
55
+ export function assertDocumentSize(byteLength, label = 'document') {
56
+ if (byteLength > MAX_DOCUMENT_BYTES) {
57
+ throw new DocumentParseError('DOCUMENT_TOO_LARGE', `${label} is ${byteLength} bytes; document parsing is capped at ${MAX_DOCUMENT_BYTES} bytes.`);
58
+ }
59
+ }
60
+ /**
61
+ * Check a ZIP entry's DECLARED sizes before touching its data.
62
+ * Cheap first line of defense — rejects 42.zip-style headers outright.
63
+ */
64
+ export function assertDeclaredEntrySizes(args) {
65
+ const { compressedSize, uncompressedSize, method, label } = args;
66
+ if (uncompressedSize > MAX_ZIP_ENTRY_BYTES) {
67
+ throw new DocumentParseError('ARCHIVE_LIMIT', `ZIP entry '${label}' declares ${uncompressedSize} uncompressed bytes (cap ${MAX_ZIP_ENTRY_BYTES}).`);
68
+ }
69
+ if (method === 8) {
70
+ if (compressedSize === 0) {
71
+ // The size-0 bypass: a deflated entry with no compressed bytes can
72
+ // still expand (or is simply malformed). Only a truly empty entry
73
+ // (0 → 0) is allowed through.
74
+ if (uncompressedSize !== 0) {
75
+ throw new DocumentParseError('ARCHIVE_LIMIT', `ZIP entry '${label}' is deflated but declares 0 compressed bytes (possible bomb).`);
76
+ }
77
+ return;
78
+ }
79
+ const ratio = uncompressedSize / compressedSize;
80
+ if (ratio > MAX_COMPRESSION_RATIO) {
81
+ throw new DocumentParseError('ARCHIVE_LIMIT', `ZIP entry '${label}' declares a ${Math.round(ratio)}:1 compression ratio ` +
82
+ `(cap ${MAX_COMPRESSION_RATIO}:1, possible zip bomb).`);
83
+ }
84
+ }
85
+ else if (method === 0) {
86
+ if (compressedSize !== uncompressedSize) {
87
+ throw new DocumentParseError('CORRUPT_DOCUMENT', `ZIP entry '${label}' is stored but compressed size ${compressedSize} ` +
88
+ `!= uncompressed size ${uncompressedSize}.`);
89
+ }
90
+ }
91
+ else {
92
+ throw new DocumentParseError('UNSUPPORTED_TYPE', `ZIP entry '${label}' uses compression method ${method} (only stored/deflated are supported).`);
93
+ }
94
+ }
95
+ /**
96
+ * Tracks the running total of decompressed bytes for one document and
97
+ * inflates raw-deflate blocks with both per-entry and total caps enforced
98
+ * DURING decompression (streaming). Declared sizes are attacker-controlled,
99
+ * so this second line of defense measures actual output — an entry that
100
+ * understates its size still trips the cap mid-inflate instead of landing
101
+ * a huge buffer in memory first.
102
+ */
103
+ export class DecompressionQuota {
104
+ #usedTotal = 0;
105
+ /** Bytes inflated so far across all entries/streams of this document. */
106
+ get usedTotal() {
107
+ return this.#usedTotal;
108
+ }
109
+ /** Account `byteLength` raw (stored, not inflated) bytes against the total quota. */
110
+ trackRaw(byteLength, label) {
111
+ this.#usedTotal += byteLength;
112
+ if (this.#usedTotal > MAX_TOTAL_DECOMPRESSED_BYTES) {
113
+ throw new DocumentParseError('ARCHIVE_LIMIT', `Decompression quota exceeded reading '${label}' (possible zip bomb): ` +
114
+ `document total ${this.#usedTotal} bytes (cap ${MAX_TOTAL_DECOMPRESSED_BYTES}).`);
115
+ }
116
+ }
117
+ /**
118
+ * Inflate one deflate block through `inflater`. Rejects with `ARCHIVE_LIMIT`
119
+ * when the entry would exceed `maxEntryBytes` or the document would exceed
120
+ * {@link MAX_TOTAL_DECOMPRESSED_BYTES}.
121
+ */
122
+ #runInflate(inflater, compressed, maxEntryBytes, label) {
123
+ return new Promise((resolve, reject) => {
124
+ const chunks = [];
125
+ let entryBytes = 0;
126
+ let settled = false;
127
+ const fail = (err) => {
128
+ if (settled)
129
+ return;
130
+ settled = true;
131
+ inflater.destroy();
132
+ reject(err);
133
+ };
134
+ inflater.on('data', (chunk) => {
135
+ entryBytes += chunk.length;
136
+ this.#usedTotal += chunk.length;
137
+ if (entryBytes > maxEntryBytes ||
138
+ this.#usedTotal > MAX_TOTAL_DECOMPRESSED_BYTES) {
139
+ fail(new DocumentParseError('ARCHIVE_LIMIT', `Decompression quota exceeded while inflating '${label}' (possible zip bomb): ` +
140
+ `entry ${entryBytes} bytes (cap ${maxEntryBytes}), ` +
141
+ `document total ${this.#usedTotal} bytes (cap ${MAX_TOTAL_DECOMPRESSED_BYTES}).`));
142
+ return;
143
+ }
144
+ chunks.push(chunk);
145
+ });
146
+ inflater.on('end', () => {
147
+ if (settled)
148
+ return;
149
+ settled = true;
150
+ resolve(Buffer.concat(chunks));
151
+ });
152
+ inflater.on('error', (err) => {
153
+ fail(new DocumentParseError('CORRUPT_DOCUMENT', `Failed to inflate '${label}': ${err.message}.`));
154
+ });
155
+ inflater.end(compressed);
156
+ });
157
+ }
158
+ /**
159
+ * Inflate one zlib-wrapped deflate block (PDF `/FlateDecode` is zlib /
160
+ * RFC 1950 per the PDF spec, NOT raw deflate).
161
+ */
162
+ inflate(compressed, maxEntryBytes, label) {
163
+ return this.#runInflate(createInflate(), compressed, maxEntryBytes, label);
164
+ }
165
+ /**
166
+ * Inflate one raw deflate block (ZIP entry data has no zlib wrapper).
167
+ */
168
+ inflateRaw(compressed, maxEntryBytes, label) {
169
+ return this.#runInflate(createInflateRaw(), compressed, maxEntryBytes, label);
170
+ }
171
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * `research.parse` — zero-dependency document parsing for research.
3
+ *
4
+ * `parseDocument(bytes, mimeType)` extracts text from PDF and DOCX without
5
+ * any npm dependency (only `node:zlib` for decompression, quota-guarded in
6
+ * `./guards.ts`). `extractDocument()` is the fetch-level entry the
7
+ * orchestrator calls: it downloads the URL with a hard byte cap, sniffs the
8
+ * magic bytes, and parses — or hands back to the regular extract backend
9
+ * when the bytes are not actually a document.
10
+ *
11
+ * Security posture (parse = attack surface):
12
+ * - Every input passes `./guards.ts` caps (file size, entry count, declared
13
+ * + actual decompression quotas) — the input-side choke point, mirroring
14
+ * what `sanitizeExtractUrl` does for URLs.
15
+ * - Extracted text passes `sanitizeExtractedText()` before entering turn
16
+ * context — the output-side analog: control characters stripped, newlines
17
+ * normalized, length capped.
18
+ */
19
+ import type { ExtractOpts, ExtractProvider, ExtractResult } from '../types.js';
20
+ export { DocumentParseError } from './guards.js';
21
+ export type { DocumentParseErrorCode } from './guards.js';
22
+ export type { DocxExtractedText } from './docx.js';
23
+ export type { PdfCMap, PdfExtractedText } from './pdf.js';
24
+ export declare const PDF_MIME = "application/pdf";
25
+ export declare const DOCX_MIME = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
26
+ /** Document kinds this module can parse. */
27
+ export type SupportedDocumentKind = 'pdf' | 'docx';
28
+ export interface ParsedDocument {
29
+ readonly kind: SupportedDocumentKind;
30
+ readonly mimeType: string;
31
+ readonly text: string;
32
+ readonly title: string;
33
+ /** PDF only, best-effort. */
34
+ readonly pageCount?: number;
35
+ }
36
+ /**
37
+ * Guess the document kind from a URL's path extension (query/fragment
38
+ * ignored). Used to decide whether a URL is worth fetching as a document;
39
+ * the magic-byte sniff always has the final say.
40
+ */
41
+ export declare function detectDocumentKindFromUrl(url: string): SupportedDocumentKind | undefined;
42
+ /** Identify a document by magic bytes: `%PDF-` or the ZIP `PK\x03\x04`. */
43
+ export declare function sniffDocumentType(bytes: Uint8Array): SupportedDocumentKind | undefined;
44
+ /**
45
+ * Parse document `bytes` of the given MIME type. Throws
46
+ * {@link DocumentParseError} (`UNSUPPORTED_TYPE` / `DOCUMENT_TOO_LARGE` /
47
+ * `ARCHIVE_LIMIT` / `CORRUPT_DOCUMENT`) — never returns partial text.
48
+ */
49
+ export declare function parseDocument(bytes: Uint8Array, mimeType: string): Promise<ParsedDocument>;
50
+ /**
51
+ * Sanitize extracted text before it enters turn context — the output-side
52
+ * analog of `sanitizeExtractUrl`: strip control characters (log/terminal
53
+ * injection, model-input noise), normalize newlines, collapse blank runs,
54
+ * and cap length as defense-in-depth past the byte quotas.
55
+ */
56
+ export declare function sanitizeExtractedText(text: string): string;
57
+ /**
58
+ * Fetch `url`, sniff it, and parse it as a document — the entry point
59
+ * `ResearchOrchestrator.extract()` uses for `.pdf`/`.docx` URLs.
60
+ *
61
+ * - Magic bytes decide the parser (extension is only the trigger); a URL
62
+ * that merely LOOKS like a document but serves HTML falls back to the
63
+ * regular extract backend instead of failing.
64
+ * - A corrupt/oversize/bomb document throws `DocumentParseError` with a
65
+ * clear message (fail-closed — never silently handed to a third party).
66
+ * - Supports the same `offset` windowing as the other extract providers.
67
+ */
68
+ export declare function extractDocument(url: string, extractProvider: ExtractProvider, signal?: AbortSignal, opts?: ExtractOpts): Promise<ExtractResult>;
@@ -0,0 +1,219 @@
1
+ /**
2
+ * `research.parse` — zero-dependency document parsing for research.
3
+ *
4
+ * `parseDocument(bytes, mimeType)` extracts text from PDF and DOCX without
5
+ * any npm dependency (only `node:zlib` for decompression, quota-guarded in
6
+ * `./guards.ts`). `extractDocument()` is the fetch-level entry the
7
+ * orchestrator calls: it downloads the URL with a hard byte cap, sniffs the
8
+ * magic bytes, and parses — or hands back to the regular extract backend
9
+ * when the bytes are not actually a document.
10
+ *
11
+ * Security posture (parse = attack surface):
12
+ * - Every input passes `./guards.ts` caps (file size, entry count, declared
13
+ * + actual decompression quotas) — the input-side choke point, mirroring
14
+ * what `sanitizeExtractUrl` does for URLs.
15
+ * - Extracted text passes `sanitizeExtractedText()` before entering turn
16
+ * context — the output-side analog: control characters stripped, newlines
17
+ * normalized, length capped.
18
+ */
19
+ import { Buffer } from 'node:buffer';
20
+ import { DEFAULT_USER_AGENT, ResearchError, TRUNCATED_MARKER, } from '../http.js';
21
+ import { extractDocxText } from './docx.js';
22
+ import { DocumentParseError, MAX_DOCUMENT_BYTES, MAX_EXTRACTED_CHARS, assertDocumentSize, } from './guards.js';
23
+ import { extractPdfText } from './pdf.js';
24
+ export { DocumentParseError } from './guards.js';
25
+ export const PDF_MIME = 'application/pdf';
26
+ export const DOCX_MIME = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
27
+ /**
28
+ * Guess the document kind from a URL's path extension (query/fragment
29
+ * ignored). Used to decide whether a URL is worth fetching as a document;
30
+ * the magic-byte sniff always has the final say.
31
+ */
32
+ export function detectDocumentKindFromUrl(url) {
33
+ const path = url.split(/[?#]/, 1)[0]?.toLowerCase() ?? '';
34
+ if (path.endsWith('.pdf'))
35
+ return 'pdf';
36
+ if (path.endsWith('.docx'))
37
+ return 'docx';
38
+ return undefined;
39
+ }
40
+ /** Identify a document by magic bytes: `%PDF-` or the ZIP `PK\x03\x04`. */
41
+ export function sniffDocumentType(bytes) {
42
+ if (bytes.length >= 5 &&
43
+ bytes[0] === 0x25 && // %
44
+ bytes[1] === 0x50 && // P
45
+ bytes[2] === 0x44 && // D
46
+ bytes[3] === 0x46 && // F
47
+ bytes[4] === 0x2d // -
48
+ ) {
49
+ return 'pdf';
50
+ }
51
+ if (bytes.length >= 4 &&
52
+ bytes[0] === 0x50 && // P
53
+ bytes[1] === 0x4b && // K
54
+ bytes[2] === 0x03 &&
55
+ bytes[3] === 0x04) {
56
+ return 'docx';
57
+ }
58
+ return undefined;
59
+ }
60
+ /**
61
+ * Parse document `bytes` of the given MIME type. Throws
62
+ * {@link DocumentParseError} (`UNSUPPORTED_TYPE` / `DOCUMENT_TOO_LARGE` /
63
+ * `ARCHIVE_LIMIT` / `CORRUPT_DOCUMENT`) — never returns partial text.
64
+ */
65
+ export async function parseDocument(bytes, mimeType) {
66
+ assertDocumentSize(bytes.length);
67
+ const mime = mimeType.split(';', 1)[0]?.trim().toLowerCase() ?? '';
68
+ if (mime === PDF_MIME) {
69
+ const parsed = await extractPdfText(bytes);
70
+ return {
71
+ kind: 'pdf',
72
+ mimeType: PDF_MIME,
73
+ text: parsed.text,
74
+ title: parsed.title,
75
+ pageCount: parsed.pageCount,
76
+ };
77
+ }
78
+ if (mime === DOCX_MIME) {
79
+ const parsed = await extractDocxText(bytes);
80
+ return {
81
+ kind: 'docx',
82
+ mimeType: DOCX_MIME,
83
+ text: parsed.text,
84
+ title: parsed.title,
85
+ };
86
+ }
87
+ throw new DocumentParseError('UNSUPPORTED_TYPE', `Unsupported document type '${mimeType}'. Supported: ${PDF_MIME}, ${DOCX_MIME}.`);
88
+ }
89
+ /**
90
+ * Sanitize extracted text before it enters turn context — the output-side
91
+ * analog of `sanitizeExtractUrl`: strip control characters (log/terminal
92
+ * injection, model-input noise), normalize newlines, collapse blank runs,
93
+ * and cap length as defense-in-depth past the byte quotas.
94
+ */
95
+ export function sanitizeExtractedText(text) {
96
+ let out = '';
97
+ for (const ch of text) {
98
+ const code = ch.codePointAt(0) ?? 0;
99
+ if (code === 0x0a || code === 0x09)
100
+ out += ch;
101
+ else if (code < 0x20 || code === 0x7f)
102
+ continue;
103
+ else
104
+ out += ch;
105
+ }
106
+ out = out
107
+ .replace(/\r\n?/g, '\n')
108
+ .replace(/\n{3,}/g, '\n\n')
109
+ .trim();
110
+ if (out.length > MAX_EXTRACTED_CHARS)
111
+ out = out.slice(0, MAX_EXTRACTED_CHARS);
112
+ return out;
113
+ }
114
+ const FETCH_TIMEOUT_MS = 15_000;
115
+ /** Extract window, matching the jina provider's window for paging parity. */
116
+ const WINDOW_CHARS = 8000;
117
+ /**
118
+ * Fetch a URL as bytes with a hard cap — same streaming-cap pattern as
119
+ * `fetchText` in `../http.ts`, but returning bytes (a document is not text
120
+ * until parsed). Throws typed {@link ResearchError}s like the rest of the
121
+ * module.
122
+ */
123
+ async function fetchBytes(url, opts) {
124
+ const timeoutSignal = AbortSignal.timeout(opts.timeoutMs);
125
+ const signal = opts.signal === undefined
126
+ ? timeoutSignal
127
+ : AbortSignal.any([opts.signal, timeoutSignal]);
128
+ let response;
129
+ try {
130
+ response = await fetch(url, {
131
+ signal,
132
+ headers: { 'User-Agent': DEFAULT_USER_AGENT },
133
+ });
134
+ }
135
+ catch (err) {
136
+ if (err instanceof DOMException && err.name === 'TimeoutError') {
137
+ throw new ResearchError('TIMEOUT', `Request to ${url} timed out`);
138
+ }
139
+ if (err instanceof DOMException && err.name === 'AbortError') {
140
+ throw new ResearchError('ABORTED', `Request to ${url} was aborted`);
141
+ }
142
+ const detail = err instanceof Error ? err.message : String(err);
143
+ throw new ResearchError('NETWORK_ERROR', `Network error fetching ${url}: ${detail}`);
144
+ }
145
+ if (!response.ok) {
146
+ const code = response.status >= 400 && response.status < 500 ? 'HTTP_4XX' : 'HTTP_5XX';
147
+ throw new ResearchError(code, `HTTP ${response.status} from ${url}`);
148
+ }
149
+ const body = response.body;
150
+ if (body === null)
151
+ return new Uint8Array(0);
152
+ const reader = body.getReader();
153
+ const chunks = [];
154
+ let total = 0;
155
+ for (;;) {
156
+ let read;
157
+ try {
158
+ read = await reader.read();
159
+ }
160
+ catch (err) {
161
+ const detail = err instanceof Error ? err.message : String(err);
162
+ throw new ResearchError('NETWORK_ERROR', `Network error fetching ${url}: ${detail}`);
163
+ }
164
+ if (read.done)
165
+ break;
166
+ total += read.value.byteLength;
167
+ if (total > opts.maxBytes) {
168
+ await reader.cancel().catch(() => undefined);
169
+ throw new ResearchError('RESPONSE_TOO_LARGE', `Response from ${url} exceeds ${opts.maxBytes} bytes`);
170
+ }
171
+ chunks.push(read.value);
172
+ }
173
+ return Buffer.concat(chunks);
174
+ }
175
+ function firstLine(text) {
176
+ const line = text.split('\n', 1)[0]?.trim() ?? '';
177
+ return line.length > 120 ? `${line.slice(0, 120)}…` : line;
178
+ }
179
+ /**
180
+ * Fetch `url`, sniff it, and parse it as a document — the entry point
181
+ * `ResearchOrchestrator.extract()` uses for `.pdf`/`.docx` URLs.
182
+ *
183
+ * - Magic bytes decide the parser (extension is only the trigger); a URL
184
+ * that merely LOOKS like a document but serves HTML falls back to the
185
+ * regular extract backend instead of failing.
186
+ * - A corrupt/oversize/bomb document throws `DocumentParseError` with a
187
+ * clear message (fail-closed — never silently handed to a third party).
188
+ * - Supports the same `offset` windowing as the other extract providers.
189
+ */
190
+ export async function extractDocument(url, extractProvider, signal, opts) {
191
+ const bytes = await fetchBytes(url, {
192
+ signal,
193
+ timeoutMs: FETCH_TIMEOUT_MS,
194
+ maxBytes: MAX_DOCUMENT_BYTES,
195
+ });
196
+ // Magic bytes decide the parser (the extension is only the trigger): a URL
197
+ // that merely LOOKS like a document but serves something else (e.g. an
198
+ // HTML error page) falls back to the regular extract backend instead of
199
+ // failing.
200
+ const kind = sniffDocumentType(bytes);
201
+ if (kind === undefined) {
202
+ return extractProvider.extract(url, signal, opts);
203
+ }
204
+ const parsed = await parseDocument(bytes, kind === 'pdf' ? PDF_MIME : DOCX_MIME);
205
+ const text = sanitizeExtractedText(parsed.text);
206
+ const offset = Math.max(0, Math.floor(opts?.offset ?? 0));
207
+ const slice = text.slice(offset, offset + WINDOW_CHARS);
208
+ const totalLength = text.length;
209
+ const hasMore = offset + slice.length < totalLength;
210
+ return {
211
+ url,
212
+ title: parsed.title !== '' ? parsed.title : firstLine(slice),
213
+ markdown: hasMore ? slice + TRUNCATED_MARKER : slice,
214
+ truncated: hasMore,
215
+ offset,
216
+ totalLength,
217
+ nextOffset: hasMore ? offset + WINDOW_CHARS : undefined,
218
+ };
219
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Minimal PDF text extractor — hand-written, zero npm dependencies.
3
+ *
4
+ * Only `node:zlib` (via `./guards.ts` quotas) is used, for `/FlateDecode`
5
+ * content streams. This is a deliberate trade-off, documented honestly:
6
+ *
7
+ * - COVERED: text-based PDFs from common generators (FlateDecode or
8
+ * uncompressed content streams, `Tj`/`TJ`/`'`/`"` operators, literal and
9
+ * hex strings, WinAnsi/PDFDocEncoding bytes, UTF-16BE strings, and
10
+ * `/ToUnicode` CMaps — the subsetted-font encoding arXiv/LaTeX PDFs use).
11
+ * - NOT covered: encrypted PDFs (rejected), scanned/image-only PDFs (no OCR —
12
+ * text extraction correctly yields nothing), exotic filters (ASCII85,
13
+ * LZW, CCITT images are skipped), fonts with NEITHER a standard encoding
14
+ * NOR a ToUnicode map (byte values are emitted best-effort).
15
+ *
16
+ * A full renderer (pdf.js, poppler) would cover more, but both violate the
17
+ * project's zero-new-runtime-dep / easy-self-host philosophy — poppler is an
18
+ * OS package that may not exist on the host, pdf.js is megabytes of npm.
19
+ * For `research.extract`/`research.deep`, "most text out of most PDFs" is
20
+ * the right weight class.
21
+ */
22
+ export interface PdfExtractedText {
23
+ readonly text: string;
24
+ readonly title: string;
25
+ /** Best-effort page count from `/Type /Page` objects; absent when undeterminable. */
26
+ readonly pageCount?: number;
27
+ }
28
+ /** A parsed `/ToUnicode` CMap: byte-group size + code → unicode char. */
29
+ export interface PdfCMap {
30
+ readonly bytesPerChar: number;
31
+ readonly map: ReadonlyMap<number, string>;
32
+ }
33
+ /**
34
+ * Extract text from PDF `bytes`. Throws {@link DocumentParseError} with
35
+ * `CORRUPT_DOCUMENT` (not a PDF), `UNSUPPORTED_TYPE` (encrypted),
36
+ * `DOCUMENT_TOO_LARGE`, or `ARCHIVE_LIMIT` (stream bomb).
37
+ */
38
+ export declare function extractPdfText(bytes: Uint8Array): Promise<PdfExtractedText>;