@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,239 @@
1
+ /**
2
+ * Static file serving for the bundled web UI.
3
+ *
4
+ * Serves `dist/web/` (the `vite build` output of `@boombot/web`) through the
5
+ * gateway's plain `node:http` server — zero dependencies, hand-rolled.
6
+ *
7
+ * The asset directory is resolved relative to THIS file
8
+ * (`fileURLToPath(import.meta.url)`), never `process.cwd()`, so a global
9
+ * `npm i -g @boombot/cli` install serves the UI no matter which
10
+ * directory the process starts from:
11
+ * - npm dist layout: `dist/gateway/static.js` → `dist/web/`
12
+ * - monorepo build: `agent-worker/dist/static.js` → `apps/web/dist/`
13
+ * - source dev: `agent-worker/src/static.ts` → `apps/web/dist/` when built
14
+ *
15
+ * Behavior:
16
+ * - `GET`/`HEAD` only; other methods fall through (the caller answers 404/405).
17
+ * - Exact file match → served with a content type, `ETag`/`Last-Modified`,
18
+ * and cache headers (`immutable` for `/assets/*`, `no-cache` for `index.html`).
19
+ * - Directory or extensionless miss → SPA fallback to `index.html`
20
+ * (client-side routing).
21
+ * - Missing path WITH an extension → 404 JSON (same error shape as the API),
22
+ * so a broken asset reference never returns HTML.
23
+ * - Path traversal, null bytes and dotfile segments → 404 (no information leak).
24
+ * - `BOOMBOT_WEB_ROOT` overrides the asset directory. The override is
25
+ * authoritative: when set, no other location is probed — a missing path
26
+ * means API-only mode (loud and debuggable, never a silent fallback).
27
+ * - When the asset directory is absent (source checkout without a web build),
28
+ * every request falls through and the gateway stays API-only — the dev
29
+ * workflow (`vite dev`) keeps working untouched.
30
+ */
31
+ import { createReadStream, existsSync, statSync } from 'node:fs';
32
+ import { dirname, extname, join, normalize, resolve, sep } from 'node:path';
33
+ import { fileURLToPath } from 'node:url';
34
+ const MIME_TYPES = {
35
+ '.html': 'text/html; charset=utf-8',
36
+ '.js': 'text/javascript; charset=utf-8',
37
+ '.mjs': 'text/javascript; charset=utf-8',
38
+ '.css': 'text/css; charset=utf-8',
39
+ '.json': 'application/json; charset=utf-8',
40
+ '.map': 'application/json; charset=utf-8',
41
+ '.svg': 'image/svg+xml',
42
+ '.png': 'image/png',
43
+ '.jpg': 'image/jpeg',
44
+ '.jpeg': 'image/jpeg',
45
+ '.gif': 'image/gif',
46
+ '.webp': 'image/webp',
47
+ '.avif': 'image/avif',
48
+ '.ico': 'image/x-icon',
49
+ '.woff': 'font/woff',
50
+ '.woff2': 'font/woff2',
51
+ '.ttf': 'font/ttf',
52
+ '.txt': 'text/plain; charset=utf-8',
53
+ };
54
+ /** Cached `resolveWebRoot()` result (`undefined` = not resolved yet). */
55
+ let cachedWebRoot;
56
+ /**
57
+ * Absolute path of the web asset directory, or `null` when it is absent.
58
+ * Result is cached for the process lifetime. `BOOMBOT_WEB_ROOT` (when set and
59
+ * non-empty) is authoritative: no fallback probing happens, so a wrong path
60
+ * fails loudly instead of silently serving another directory.
61
+ */
62
+ export function resolveWebRoot() {
63
+ if (cachedWebRoot !== undefined)
64
+ return cachedWebRoot;
65
+ const override = process.env['BOOMBOT_WEB_ROOT'];
66
+ const here = dirname(fileURLToPath(import.meta.url));
67
+ const candidates = override !== undefined && override.trim() !== ''
68
+ ? [resolve(override)]
69
+ : [
70
+ resolve(here, '..', 'web'),
71
+ resolve(here, '..', '..', '..', 'apps', 'web', 'dist'),
72
+ ];
73
+ cachedWebRoot =
74
+ candidates.find((candidate) => existsSync(candidate) && statSync(candidate).isDirectory()) ??
75
+ null;
76
+ return cachedWebRoot;
77
+ }
78
+ /** Clear the cached web-root resolution. Test-only: production code never calls this. */
79
+ export function resetWebRootCache() {
80
+ cachedWebRoot = undefined;
81
+ }
82
+ /** True when the bundled web UI exists and will be served. */
83
+ export function isWebUiEnabled() {
84
+ return resolveWebRoot() !== null;
85
+ }
86
+ /**
87
+ * Map a raw request pathname to a file under `webRoot`. Pure apart from
88
+ * `statSync`: safe to unit-test directly.
89
+ *
90
+ * - `..` segments are collapsed against a leading `/` first, so they can
91
+ * never climb above `webRoot`; the `startsWith(webRoot + sep)` check is
92
+ * defense in depth.
93
+ * - `blocked` (traversal, null byte, bad encoding, dotfile) and `missing`
94
+ * both surface as 404 to the client — never 403, to avoid confirming or
95
+ * denying the existence of anything outside the asset tree.
96
+ */
97
+ export function resolveStaticFile(webRoot, rawPathname) {
98
+ let pathname;
99
+ try {
100
+ pathname = decodeURIComponent(rawPathname);
101
+ }
102
+ catch {
103
+ return { kind: 'blocked' };
104
+ }
105
+ if (pathname.includes('\0'))
106
+ return { kind: 'blocked' };
107
+ const normalized = normalize(`/${pathname}`);
108
+ const target = join(webRoot, normalized);
109
+ if (target !== webRoot && !target.startsWith(webRoot + sep)) {
110
+ return { kind: 'blocked' };
111
+ }
112
+ // A vite build never ships dotfiles; don't serve them (or confirm them).
113
+ const relative = target.slice(webRoot.length);
114
+ if (relative.split(sep).some((segment) => segment.startsWith('.') && segment.length > 1)) {
115
+ return { kind: 'blocked' };
116
+ }
117
+ let file = target;
118
+ let isDir = false;
119
+ try {
120
+ isDir = statSync(target).isDirectory();
121
+ }
122
+ catch {
123
+ // Missing path: SPA fallback only for extensionless paths (client routes).
124
+ // A missing `*.js`/`*.css`/… is a broken asset reference → 404, not index.html.
125
+ if (extname(normalized) !== '')
126
+ return { kind: 'missing' };
127
+ file = join(webRoot, 'index.html');
128
+ }
129
+ if (isDir)
130
+ file = join(target, 'index.html');
131
+ try {
132
+ if (!statSync(file).isFile())
133
+ return { kind: 'missing' };
134
+ }
135
+ catch {
136
+ return { kind: 'missing' };
137
+ }
138
+ return { kind: 'file', filePath: file };
139
+ }
140
+ function contentType(filePath) {
141
+ return MIME_TYPES[extname(filePath).toLowerCase()] ?? 'application/octet-stream';
142
+ }
143
+ function cacheControl(requestPath, filePath) {
144
+ // `index.html` is the SPA entry: always revalidate so deploys take effect.
145
+ if (filePath.endsWith(`${sep}index.html`))
146
+ return 'no-cache';
147
+ // Vite content-hashes filenames under /assets/: immutable for a year.
148
+ if (requestPath.startsWith('/assets/'))
149
+ return 'public, max-age=31536000, immutable';
150
+ return 'public, max-age=3600';
151
+ }
152
+ function sendJsonError(res, status, code, message) {
153
+ const text = JSON.stringify({ error: { code, message } });
154
+ res.writeHead(status, {
155
+ 'Content-Type': 'application/json; charset=utf-8',
156
+ 'Content-Length': Buffer.byteLength(text),
157
+ });
158
+ res.end(text);
159
+ }
160
+ /**
161
+ * Serve one request from the bundled web UI.
162
+ *
163
+ * Returns `true` when the request was answered (file, 404, 400 or 304);
164
+ * `false` when static serving does not apply (no assets, wrong method) and
165
+ * the caller should keep routing (API routes, then its own 404).
166
+ */
167
+ export async function serveStatic(req, res, log) {
168
+ const webRoot = resolveWebRoot();
169
+ if (webRoot === null)
170
+ return false;
171
+ const method = (req.method ?? 'GET').toUpperCase();
172
+ if (method !== 'GET' && method !== 'HEAD')
173
+ return false;
174
+ let pathname;
175
+ try {
176
+ pathname = new URL(req.url ?? '/', 'http://localhost').pathname;
177
+ }
178
+ catch {
179
+ sendJsonError(res, 400, 'BAD_REQUEST', 'Malformed request URL');
180
+ return true;
181
+ }
182
+ const resolution = resolveStaticFile(webRoot, pathname);
183
+ if (resolution.kind !== 'file') {
184
+ log?.('debug', 'static miss', {
185
+ method,
186
+ path: pathname,
187
+ blocked: resolution.kind === 'blocked',
188
+ });
189
+ sendJsonError(res, 404, 'NOT_FOUND', `Unknown path: ${pathname}`);
190
+ return true;
191
+ }
192
+ let stat;
193
+ try {
194
+ stat = statSync(resolution.filePath);
195
+ }
196
+ catch {
197
+ sendJsonError(res, 404, 'NOT_FOUND', `Unknown path: ${pathname}`);
198
+ return true;
199
+ }
200
+ const etag = `W/"${stat.size.toString(16)}-${Math.floor(stat.mtimeMs).toString(16)}"`;
201
+ if (req.headers['if-none-match'] === etag) {
202
+ res.writeHead(304, { ETag: etag });
203
+ res.end();
204
+ log?.('debug', 'static', { method, path: pathname, status: 304 });
205
+ return true;
206
+ }
207
+ const headers = {
208
+ 'Content-Type': contentType(resolution.filePath),
209
+ 'Content-Length': stat.size,
210
+ 'Last-Modified': stat.mtime.toUTCString(),
211
+ ETag: etag,
212
+ 'Cache-Control': cacheControl(pathname, resolution.filePath),
213
+ };
214
+ if (method === 'HEAD') {
215
+ res.writeHead(200, headers);
216
+ res.end();
217
+ log?.('debug', 'static', { method, path: pathname, status: 200 });
218
+ return true;
219
+ }
220
+ await new Promise((done) => {
221
+ res.writeHead(200, headers);
222
+ const stream = createReadStream(resolution.filePath);
223
+ stream.on('error', () => {
224
+ if (!res.headersSent) {
225
+ sendJsonError(res, 500, 'INTERNAL_ERROR', 'Failed to read static file');
226
+ }
227
+ else {
228
+ res.destroy();
229
+ }
230
+ done();
231
+ });
232
+ stream.pipe(res);
233
+ res.on('finish', () => done());
234
+ // `close` also fires on aborted connections; `done` is idempotent.
235
+ res.on('close', () => done());
236
+ });
237
+ log?.('debug', 'static', { method, path: pathname, status: 200 });
238
+ return true;
239
+ }
@@ -0,0 +1,57 @@
1
+ export const CLARIFY_TOOL_NAME = 'clarify';
2
+ export const clarifyDefinition = {
3
+ name: CLARIFY_TOOL_NAME,
4
+ description: 'Ask the user one or more questions when you need a decision, clarification, or feedback before proceeding. ' +
5
+ 'Pass every question in `questions` (1-5 entries). Each question can have single-select choices, ' +
6
+ 'multi-select choices, or open-ended free text.',
7
+ parameters: {
8
+ type: 'object',
9
+ properties: {
10
+ questions: {
11
+ type: 'array',
12
+ description: 'The questions to ask the user.',
13
+ items: {
14
+ type: 'object',
15
+ properties: {
16
+ question: { type: 'string', description: 'Question text.' },
17
+ choices: {
18
+ type: 'array',
19
+ items: { type: 'string' },
20
+ description: 'Optional selectable options (recommended first).',
21
+ },
22
+ multi_select: { type: 'boolean', description: 'Allow multiple selections.' },
23
+ },
24
+ required: ['question'],
25
+ },
26
+ },
27
+ },
28
+ required: ['questions'],
29
+ additionalProperties: false,
30
+ },
31
+ };
32
+ export function registerClarifyTool(registry) {
33
+ registry.registerTool(clarifyDefinition, async (call) => {
34
+ const args = (call.arguments ?? {});
35
+ const questions = args.questions ?? [];
36
+ if (!questions.length) {
37
+ return { callId: call.id, name: call.name, output: 'No questions provided.', error: true };
38
+ }
39
+ const outputLines = ['[CLARIFY REQUEST TO USER]'];
40
+ questions.forEach((q, i) => {
41
+ outputLines.push(`Question ${i + 1}: ${q.question}`);
42
+ if (q.choices?.length) {
43
+ outputLines.push(`Choices (${q.multi_select ? 'Multi-select' : 'Single-select'}):`);
44
+ q.choices.forEach((c, ci) => outputLines.push(` [${ci + 1}] ${c}`));
45
+ }
46
+ else {
47
+ outputLines.push(' (Free-text response)');
48
+ }
49
+ });
50
+ return {
51
+ callId: call.id,
52
+ name: call.name,
53
+ output: outputLines.join('\n'),
54
+ error: false,
55
+ };
56
+ });
57
+ }
@@ -0,0 +1,96 @@
1
+ export const CRONJOB_TOOL_NAME = 'cronjob_manage';
2
+ export const cronjobDefinition = {
3
+ name: CRONJOB_TOOL_NAME,
4
+ description: 'Manage scheduled cron jobs. The bot can automatically run prompts on a schedule (e.g., daily summaries). ' +
5
+ 'Actions: "list" (show all), "create" (needs name, cron, prompt; timezone is optional), "update" (needs id, and fields to update), ' +
6
+ '"toggle" (needs id, enabled: boolean), "delete" (needs id), "run_now" (needs id).',
7
+ parameters: {
8
+ type: 'object',
9
+ properties: {
10
+ action: {
11
+ type: 'string',
12
+ enum: ['list', 'create', 'update', 'toggle', 'delete', 'run_now'],
13
+ description: 'The action to perform.',
14
+ },
15
+ id: { type: 'string', description: 'Job ID (required for update, toggle, delete, run_now).' },
16
+ name: { type: 'string', description: 'Job name (required for create).' },
17
+ cron: { type: 'string', description: 'Cron expression (e.g. "0 9 * * *", required for create).' },
18
+ timezone: { type: 'string', description: 'IANA timezone (e.g. "Asia/Ho_Chi_Minh").' },
19
+ prompt: { type: 'string', description: 'The prompt text to execute when the job fires.' },
20
+ enabled: { type: 'boolean', description: 'Enable or disable the job.' },
21
+ },
22
+ required: ['action'],
23
+ additionalProperties: false,
24
+ },
25
+ };
26
+ export function registerCronjobTool(registry, schedulerService) {
27
+ registry.registerTool(cronjobDefinition, async (call) => {
28
+ const { registry: schedRegistry, authContext } = schedulerService.internals;
29
+ const args = (call.arguments ?? {});
30
+ try {
31
+ switch (args.action) {
32
+ case 'list': {
33
+ const list = await schedRegistry.list(authContext);
34
+ return { callId: call.id, name: call.name, output: JSON.stringify(list, null, 2), error: false };
35
+ }
36
+ case 'create': {
37
+ if (!args.name || !args.cron || !args.prompt) {
38
+ throw new Error('create requires name, cron, and prompt');
39
+ }
40
+ const job = await schedRegistry.create(authContext, {
41
+ name: args.name,
42
+ cron: args.cron,
43
+ timezone: args.timezone ?? 'Asia/Ho_Chi_Minh',
44
+ promptText: args.prompt,
45
+ enabled: args.enabled !== false,
46
+ concurrencyPolicy: 'forbid',
47
+ missedRunPolicy: 'skip',
48
+ maxCatchUp: 3,
49
+ });
50
+ return { callId: call.id, name: call.name, output: `Created job ${job.id}`, error: false };
51
+ }
52
+ case 'update': {
53
+ if (!args.id)
54
+ throw new Error('update requires id');
55
+ const updates = {
56
+ ...(args.name === undefined ? {} : { name: args.name }),
57
+ ...(args.cron === undefined ? {} : { cron: args.cron }),
58
+ ...(args.timezone === undefined ? {} : { timezone: args.timezone }),
59
+ ...(args.prompt === undefined ? {} : { promptText: args.prompt }),
60
+ ...(args.enabled === undefined ? {} : { enabled: args.enabled }),
61
+ };
62
+ await schedRegistry.update(authContext, args.id, updates);
63
+ return { callId: call.id, name: call.name, output: `Updated job ${args.id}`, error: false };
64
+ }
65
+ case 'toggle': {
66
+ if (!args.id || typeof args.enabled !== 'boolean')
67
+ throw new Error('toggle requires id and enabled boolean');
68
+ await schedRegistry.update(authContext, args.id, { enabled: args.enabled });
69
+ return { callId: call.id, name: call.name, output: `Toggled job ${args.id} to ${args.enabled}`, error: false };
70
+ }
71
+ case 'delete': {
72
+ if (!args.id)
73
+ throw new Error('delete requires id');
74
+ await schedRegistry.remove(authContext, args.id);
75
+ return { callId: call.id, name: call.name, output: `Deleted job ${args.id}`, error: false };
76
+ }
77
+ case 'run_now': {
78
+ if (!args.id)
79
+ throw new Error('run_now requires id');
80
+ const res = await schedulerService.fireNow(args.id);
81
+ return { callId: call.id, name: call.name, output: `Fired job ${args.id}, Turn ID: ${res.turnId}`, error: false };
82
+ }
83
+ default:
84
+ throw new Error(`Unknown action: ${args.action}`);
85
+ }
86
+ }
87
+ catch (err) {
88
+ return {
89
+ callId: call.id,
90
+ name: call.name,
91
+ output: `cronjob_manage error: ${err instanceof Error ? err.message : String(err)}`,
92
+ error: true,
93
+ };
94
+ }
95
+ });
96
+ }
@@ -0,0 +1,154 @@
1
+ export const TOOL_SEARCH_NAME = 'tool_search';
2
+ export const TOOL_DESCRIBE_NAME = 'tool_describe';
3
+ export const TOOL_CALL_NAME = 'tool_call';
4
+ export const toolSearchDefinition = {
5
+ name: TOOL_SEARCH_NAME,
6
+ description: 'Search the catalog of deferred on-demand tools by keywords (e.g. ["github issue", "slack message"]). ' +
7
+ 'Returns matching tool names and brief summaries. Use `tool_describe` to inspect parameters before calling.',
8
+ parameters: {
9
+ type: 'object',
10
+ properties: {
11
+ queries: {
12
+ type: 'array',
13
+ items: { type: 'string' },
14
+ description: 'Keyword search queries to run against tool names and descriptions.',
15
+ },
16
+ limit: {
17
+ type: 'number',
18
+ description: 'Maximum matches per query (default 5).',
19
+ },
20
+ },
21
+ required: ['queries'],
22
+ additionalProperties: false,
23
+ },
24
+ };
25
+ export const toolDescribeDefinition = {
26
+ name: TOOL_DESCRIBE_NAME,
27
+ description: 'Load the full parameter JSON schema for deferred tools returned by `tool_search`. ' +
28
+ 'Call before `tool_call` to understand required parameters.',
29
+ parameters: {
30
+ type: 'object',
31
+ properties: {
32
+ names: {
33
+ type: 'array',
34
+ items: { type: 'string' },
35
+ description: 'Exact tool names to inspect schemas for.',
36
+ },
37
+ },
38
+ required: ['names'],
39
+ additionalProperties: false,
40
+ },
41
+ };
42
+ export const toolCallDefinition = {
43
+ name: TOOL_CALL_NAME,
44
+ description: 'Invoke one or more deferred tools loaded via `tool_search` and `tool_describe`. ' +
45
+ 'Takes an array of {name, arguments} invocations and runs them in parallel.',
46
+ parameters: {
47
+ type: 'object',
48
+ properties: {
49
+ calls: {
50
+ type: 'array',
51
+ description: 'One or more tool calls to execute.',
52
+ items: {
53
+ type: 'object',
54
+ properties: {
55
+ name: { type: 'string', description: 'Exact tool name to call.' },
56
+ arguments: { type: 'object', description: 'Arguments matching the tool parameter schema.' },
57
+ },
58
+ required: ['name', 'arguments'],
59
+ },
60
+ },
61
+ },
62
+ required: ['calls'],
63
+ additionalProperties: false,
64
+ },
65
+ };
66
+ export class DeferredToolManager {
67
+ catalog = new Map();
68
+ registerDeferred(definition, handler) {
69
+ this.catalog.set(definition.name, { definition, handler });
70
+ }
71
+ registerTo(registry) {
72
+ // 1. tool_search
73
+ registry.registerTool(toolSearchDefinition, async (call) => {
74
+ const args = (call.arguments ?? {});
75
+ const queries = args.queries ?? [];
76
+ const limit = args.limit ?? 5;
77
+ const results = {};
78
+ for (const query of queries) {
79
+ const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
80
+ const matches = [];
81
+ for (const [name, entry] of this.catalog.entries()) {
82
+ const text = `${name} ${entry.definition.description}`.toLowerCase();
83
+ const score = terms.reduce((acc, t) => acc + (text.includes(t) ? 1 : 0), 0);
84
+ if (score > 0) {
85
+ matches.push({
86
+ name,
87
+ description: entry.definition.description.slice(0, 160),
88
+ });
89
+ }
90
+ if (matches.length >= limit)
91
+ break;
92
+ }
93
+ results[query] = matches;
94
+ }
95
+ return {
96
+ callId: call.id,
97
+ name: call.name,
98
+ output: JSON.stringify(results, null, 2),
99
+ error: false,
100
+ };
101
+ });
102
+ // 2. tool_describe
103
+ registry.registerTool(toolDescribeDefinition, async (call) => {
104
+ const args = (call.arguments ?? {});
105
+ const names = args.names ?? [];
106
+ const schemas = {};
107
+ for (const name of names) {
108
+ const entry = this.catalog.get(name);
109
+ if (entry) {
110
+ schemas[name] = {
111
+ description: entry.definition.description,
112
+ parameters: entry.definition.parameters,
113
+ };
114
+ }
115
+ else {
116
+ schemas[name] = { error: `Tool '${name}' not found in deferred catalog.` };
117
+ }
118
+ }
119
+ return {
120
+ callId: call.id,
121
+ name: call.name,
122
+ output: JSON.stringify(schemas, null, 2),
123
+ error: false,
124
+ };
125
+ });
126
+ // 3. tool_call
127
+ registry.registerTool(toolCallDefinition, async (call, signal) => {
128
+ const args = (call.arguments ?? {});
129
+ const calls = args.calls ?? [];
130
+ if (!calls.length) {
131
+ return { callId: call.id, name: call.name, output: 'No calls provided.', error: true };
132
+ }
133
+ const results = await Promise.all(calls.map(async (subCall) => {
134
+ const entry = this.catalog.get(subCall.name);
135
+ if (!entry) {
136
+ return { name: subCall.name, error: `Tool '${subCall.name}' not found in deferred catalog.` };
137
+ }
138
+ try {
139
+ const res = await entry.handler({ id: `deferred_${Date.now()}`, name: subCall.name, arguments: subCall.arguments }, signal);
140
+ return { name: subCall.name, output: res.output, error: res.error };
141
+ }
142
+ catch (err) {
143
+ return { name: subCall.name, error: err instanceof Error ? err.message : String(err) };
144
+ }
145
+ }));
146
+ return {
147
+ callId: call.id,
148
+ name: call.name,
149
+ output: JSON.stringify(results, null, 2),
150
+ error: results.some((r) => r.error),
151
+ };
152
+ });
153
+ }
154
+ }
@@ -0,0 +1,84 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import { DEFAULT_PREVIEW_BYTES, formatSpilledOutput, previewStreams, writeSpillover, } from './spillover.js';
5
+ export const EXECUTE_CODE_TOOL_NAME = 'execute_code';
6
+ export const executeCodeDefinition = {
7
+ name: EXECUTE_CODE_TOOL_NAME,
8
+ description: 'Run Python code programmatically. Use when you need filtering, data processing, ' +
9
+ 'loops, or programmatic logic. Each call runs in a fresh Python process. ' +
10
+ 'Print your final result to stdout.',
11
+ parameters: {
12
+ type: 'object',
13
+ properties: {
14
+ code: {
15
+ type: 'string',
16
+ description: 'Python code to execute.',
17
+ },
18
+ },
19
+ required: ['code'],
20
+ additionalProperties: false,
21
+ },
22
+ };
23
+ export function registerExecuteCodeTool(registry, options) {
24
+ const { sandbox, workspaceRoot } = options;
25
+ registry.registerTool(executeCodeDefinition, async (call) => {
26
+ const args = (call.arguments ?? {});
27
+ const code = args.code ?? '';
28
+ if (!code.trim()) {
29
+ return {
30
+ callId: call.id,
31
+ name: call.name,
32
+ output: 'execute_code error: empty code provided',
33
+ error: true,
34
+ };
35
+ }
36
+ const scratchDir = resolve(workspaceRoot, '.execute-code');
37
+ mkdirSync(scratchDir, { recursive: true });
38
+ const scriptPath = join(scratchDir, `${randomUUID()}.py`);
39
+ writeFileSync(scriptPath, code, 'utf-8');
40
+ let result;
41
+ try {
42
+ result = await sandbox.run(['python', scriptPath], {
43
+ cwd: scratchDir,
44
+ timeoutMs: 300_000,
45
+ envAllowlist: ['PATH', 'PYTHONPATH', 'TEMP', 'TMP', 'PYTHONUTF8', 'PYTHONIOENCODING'],
46
+ });
47
+ }
48
+ catch (err) {
49
+ return {
50
+ callId: call.id,
51
+ name: call.name,
52
+ output: `execute_code failed: ${err instanceof Error ? err.message : String(err)}`,
53
+ error: true,
54
+ };
55
+ }
56
+ finally {
57
+ rmSync(scriptPath, { force: true });
58
+ }
59
+ const spillover = options.spillover;
60
+ let output;
61
+ if (result.truncated && spillover !== undefined) {
62
+ const info = writeSpillover(spillover.dir, call.id, result.stdout, result.stderr, {
63
+ exitCode: result.exitCode,
64
+ timedOut: result.timedOut,
65
+ truncated: result.truncated,
66
+ }, {
67
+ maxAgeMs: spillover.maxAgeMs,
68
+ maxTotalBytes: spillover.maxTotalBytes,
69
+ });
70
+ output = formatSpilledOutput(previewStreams(result.stdout, result.stderr, spillover.previewBytes ?? DEFAULT_PREVIEW_BYTES), info);
71
+ }
72
+ else {
73
+ output =
74
+ [result.stdout, result.stderr].filter(Boolean).join('\n') ||
75
+ 'Executed successfully with no output.';
76
+ }
77
+ return {
78
+ callId: call.id,
79
+ name: call.name,
80
+ output,
81
+ error: result.timedOut || result.exitCode !== 0,
82
+ };
83
+ });
84
+ }