opensentinel 3.1.1 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/README.md +138 -83
  2. package/dist/agent-manager-JZ4IM7XI.js +39 -0
  3. package/dist/agent-processor-DDDHC2SO.js +281 -0
  4. package/dist/agent-processor-DDDHC2SO.js.map +1 -0
  5. package/dist/agent-types-2T4PXLFQ.js +12 -0
  6. package/dist/alerting-LK7VVYTX.js +699 -0
  7. package/dist/alerting-LK7VVYTX.js.map +1 -0
  8. package/dist/analysis-agent-JWN2GXYE.js +288 -0
  9. package/dist/analysis-agent-JWN2GXYE.js.map +1 -0
  10. package/dist/analyzer-OTWE3ARE.js +22 -0
  11. package/dist/{archiver-AVNBYCKQ.js → archiver-FPGKRP6P.js} +2 -2
  12. package/dist/{audit-logger-OBPR7CRO.js → audit-logger-CI4WZQPD.js} +6 -5
  13. package/dist/{auth-UOX5K2BE.js → auth-PH5IHISW.js} +2 -2
  14. package/dist/{autonomy-ZXDBDQUJ.js → autonomy-N7W5XPLX.js} +4 -3
  15. package/dist/autonomy-N7W5XPLX.js.map +1 -0
  16. package/dist/{aws-s3-Q4LLZZPD.js → aws-s3-QZMURYXB.js} +2 -2
  17. package/dist/{backup-restore-PZ7CYYB7.js → backup-restore-72OQTZO3.js} +2 -2
  18. package/dist/{blocks-R3PODY47.js → blocks-YOWOESDD.js} +4 -4
  19. package/dist/bot-VDHBGUVI.js +47 -0
  20. package/dist/brain-6QTXN4QP.js +66 -0
  21. package/dist/{camera-monitor-M5CYKUU4.js → camera-monitor-LHTUWHEL.js} +2 -2
  22. package/dist/{charts-V7ARZNKF.js → charts-FJ32GQK7.js} +2 -2
  23. package/dist/{chunk-WRAKK6K6.js → chunk-2I5QHYG6.js} +5 -3
  24. package/dist/chunk-2I5QHYG6.js.map +1 -0
  25. package/dist/{chunk-TVEWKIK3.js → chunk-2WTKTG2C.js} +2 -2
  26. package/dist/chunk-3AWAWRWB.js +143 -0
  27. package/dist/chunk-3AWAWRWB.js.map +1 -0
  28. package/dist/{chunk-ZLZKF2PM.js → chunk-4KIHDIXZ.js} +43 -2
  29. package/dist/chunk-4KIHDIXZ.js.map +1 -0
  30. package/dist/{chunk-EVE7MIIY.js → chunk-4WH6MFEW.js} +15 -16
  31. package/dist/chunk-4WH6MFEW.js.map +1 -0
  32. package/dist/{chunk-I6BDYQIG.js → chunk-56UJS2LA.js} +6 -6
  33. package/dist/chunk-56UJS2LA.js.map +1 -0
  34. package/dist/chunk-5BTVJR7R.js +37 -0
  35. package/dist/chunk-5BTVJR7R.js.map +1 -0
  36. package/dist/chunk-5JJTLWOR.js +1021 -0
  37. package/dist/chunk-5JJTLWOR.js.map +1 -0
  38. package/dist/chunk-66SAOZPU.js +236 -0
  39. package/dist/chunk-66SAOZPU.js.map +1 -0
  40. package/dist/chunk-6HGMRR4J.js +113 -0
  41. package/dist/chunk-6HGMRR4J.js.map +1 -0
  42. package/dist/chunk-6W6PTJFT.js +181 -0
  43. package/dist/chunk-6W6PTJFT.js.map +1 -0
  44. package/dist/chunk-6ZNCY2GI.js +418 -0
  45. package/dist/chunk-6ZNCY2GI.js.map +1 -0
  46. package/dist/chunk-7BNFELEK.js +31 -0
  47. package/dist/chunk-7BNFELEK.js.map +1 -0
  48. package/dist/chunk-ADTDYJO7.js +265 -0
  49. package/dist/chunk-ADTDYJO7.js.map +1 -0
  50. package/dist/{chunk-OCVQGBJK.js → chunk-BBN4VCNK.js} +6 -4
  51. package/dist/chunk-BBN4VCNK.js.map +1 -0
  52. package/dist/{chunk-SJSUSJ47.js → chunk-BNZHWAZC.js} +2 -2
  53. package/dist/chunk-C6PELIHS.js +60 -0
  54. package/dist/chunk-C6PELIHS.js.map +1 -0
  55. package/dist/{chunk-MQJ2ECQT.js → chunk-CUPEENUY.js} +3 -3
  56. package/dist/{chunk-NHMBTUMW.js → chunk-CWT6CAE5.js} +2 -2
  57. package/dist/{chunk-4GLYY4NN.js → chunk-CZTMGHUC.js} +8 -2
  58. package/dist/chunk-CZTMGHUC.js.map +1 -0
  59. package/dist/{chunk-RZ4YESBG.js → chunk-DOYGMNMK.js} +1 -1
  60. package/dist/chunk-DOYGMNMK.js.map +1 -0
  61. package/dist/chunk-DTISLIMB.js +89 -0
  62. package/dist/chunk-DTISLIMB.js.map +1 -0
  63. package/dist/{chunk-SPPMCAKG.js → chunk-GBVJTRXS.js} +2 -2
  64. package/dist/chunk-GBVJTRXS.js.map +1 -0
  65. package/dist/{chunk-AYUKPTSM.js → chunk-GJETKBOY.js} +96 -218
  66. package/dist/chunk-GJETKBOY.js.map +1 -0
  67. package/dist/{chunk-BXZ6EA52.js → chunk-GW6V4D43.js} +57 -3
  68. package/dist/chunk-GW6V4D43.js.map +1 -0
  69. package/dist/{chunk-6PMVAAA7.js → chunk-HJSEEFO3.js} +3 -3
  70. package/dist/{chunk-TYAGMJNV.js → chunk-HQZQFEAX.js} +5 -5
  71. package/dist/{chunk-MXAPLSJ5.js → chunk-J4JW73TT.js} +2 -2
  72. package/dist/{chunk-VEHFVBLI.js → chunk-JHYYFPKX.js} +2 -2
  73. package/dist/chunk-LFDXEYYB.js +150 -0
  74. package/dist/chunk-LFDXEYYB.js.map +1 -0
  75. package/dist/chunk-MIC5IBQF.js +386 -0
  76. package/dist/chunk-MIC5IBQF.js.map +1 -0
  77. package/dist/chunk-ODCFS5WD.js +463 -0
  78. package/dist/chunk-ODCFS5WD.js.map +1 -0
  79. package/dist/{chunk-XMCVRVTF.js → chunk-P64EV4YY.js} +1 -1
  80. package/dist/chunk-P64EV4YY.js.map +1 -0
  81. package/dist/chunk-PBOCSGNL.js +84 -0
  82. package/dist/chunk-PBOCSGNL.js.map +1 -0
  83. package/dist/{chunk-66OJ3WB4.js → chunk-PD3CTDO6.js} +2 -2
  84. package/dist/chunk-QPY3WRVM.js +647 -0
  85. package/dist/chunk-QPY3WRVM.js.map +1 -0
  86. package/dist/chunk-S2EOIVF4.js +3907 -0
  87. package/dist/chunk-S2EOIVF4.js.map +1 -0
  88. package/dist/chunk-SDLOMKCW.js +213 -0
  89. package/dist/chunk-SDLOMKCW.js.map +1 -0
  90. package/dist/chunk-TKBVW7ZJ.js +162 -0
  91. package/dist/chunk-TKBVW7ZJ.js.map +1 -0
  92. package/dist/{chunk-BRBWNV65.js → chunk-U2X2J3FI.js} +3 -3
  93. package/dist/chunk-U2X2J3FI.js.map +1 -0
  94. package/dist/{chunk-PLDDJCW6.js → chunk-UP2VWCW5.js} +1 -12
  95. package/dist/{chunk-SVAPX2XN.js → chunk-V3OKHQUX.js} +9 -7
  96. package/dist/{chunk-SVAPX2XN.js.map → chunk-V3OKHQUX.js.map} +1 -1
  97. package/dist/{chunk-4UOE5TUZ.js → chunk-WMDVOWN6.js} +4 -4
  98. package/dist/chunk-WMFYI7XC.js +564 -0
  99. package/dist/chunk-WMFYI7XC.js.map +1 -0
  100. package/dist/chunk-WZAH34TG.js +129 -0
  101. package/dist/chunk-WZAH34TG.js.map +1 -0
  102. package/dist/{chunk-H5RQOFO2.js → chunk-X6Q3K3L2.js} +6 -6
  103. package/dist/chunk-X6Q3K3L2.js.map +1 -0
  104. package/dist/chunk-XTX7EK43.js +134 -0
  105. package/dist/chunk-XTX7EK43.js.map +1 -0
  106. package/dist/chunk-YEDEAX6Y.js +194 -0
  107. package/dist/chunk-YEDEAX6Y.js.map +1 -0
  108. package/dist/{chunk-XKYRH4FM.js → chunk-ZIBRVA3Y.js} +70 -30
  109. package/dist/chunk-ZIBRVA3Y.js.map +1 -0
  110. package/dist/chunk-ZIYTHUM5.js +457 -0
  111. package/dist/chunk-ZIYTHUM5.js.map +1 -0
  112. package/dist/{chunk-766ASQWE.js → chunk-ZMML6T63.js} +2711 -2329
  113. package/dist/chunk-ZMML6T63.js.map +1 -0
  114. package/dist/chunk-ZVHG4KF2.js +380 -0
  115. package/dist/chunk-ZVHG4KF2.js.map +1 -0
  116. package/dist/chunker-K6WTR62A.js +12 -0
  117. package/dist/cli.js +1 -1
  118. package/dist/cli.js.map +1 -1
  119. package/dist/{client-ZQSFPMOB.js → client-FOIYPOZQ.js} +5 -6
  120. package/dist/{clipboard-manager-TEO2GEDN.js → clipboard-manager-4SBNESGZ.js} +2 -2
  121. package/dist/coding-agent-DESSU3AC.js +233 -0
  122. package/dist/coding-agent-DESSU3AC.js.map +1 -0
  123. package/dist/commands/setup.js +2 -2
  124. package/dist/commands/start.js +3 -3
  125. package/dist/commands/status.js +2 -2
  126. package/dist/commands/stop.js +2 -2
  127. package/dist/commands/utils.js +2 -2
  128. package/dist/cost-tracker-KZQSTSE2.js +11 -0
  129. package/dist/{cron-explain-HHQKPD3M.js → cron-explain-UOOOYWZZ.js} +2 -2
  130. package/dist/{crypto-4AP47IKC.js → crypto-2VG3RJR2.js} +2 -2
  131. package/dist/{databases-37X4CI2Y.js → databases-XDPMG5AV.js} +4 -4
  132. package/dist/db-I7MNG6CL.js +83 -0
  133. package/dist/discord-6UQHCN27.js +81 -0
  134. package/dist/documents-PFHSK7SZ.js +184 -0
  135. package/dist/documents-PFHSK7SZ.js.map +1 -0
  136. package/dist/docx-parser-EXL4TN5E.js +16 -0
  137. package/dist/{email-K7LO2IPB.js → email-6OIN4SYL.js} +34 -25
  138. package/dist/email-6OIN4SYL.js.map +1 -0
  139. package/dist/{enhanced-retrieval-DNLLEM4Z.js → enhanced-retrieval-JWX2HWU4.js} +12 -8
  140. package/dist/{enhanced-retrieval-DNLLEM4Z.js.map → enhanced-retrieval-JWX2HWU4.js.map} +1 -1
  141. package/dist/enrichment-pipeline-7FE5R5ZI.js +14 -0
  142. package/dist/{entity-resolution-Y3IUWEAT.js → entity-resolution-7Z6STVXX.js} +6 -5
  143. package/dist/env-GN5VHI43.js +12 -0
  144. package/dist/error-tracker-64DEH3D7.js +32 -0
  145. package/dist/finnhub-X7ZMQSXF.js +178 -0
  146. package/dist/finnhub-X7ZMQSXF.js.map +1 -0
  147. package/dist/fred-TMUF3J2V.js +203 -0
  148. package/dist/fred-TMUF3J2V.js.map +1 -0
  149. package/dist/github-DUWSXCNP.js +833 -0
  150. package/dist/github-DUWSXCNP.js.map +1 -0
  151. package/dist/{google-workspace-DKWUVNGC.js → google-workspace-TSZPZK5G.js} +2 -2
  152. package/dist/graph-client-NB475AK5.js +17 -0
  153. package/dist/{hash-tool-ULQYD7B5.js → hash-tool-ENAB5LWH.js} +2 -2
  154. package/dist/{heartbeat-monitor-GCISLXI3.js → heartbeat-monitor-KRDYTDBF.js} +2 -2
  155. package/dist/hooks-N4MIFBVM.js +14 -0
  156. package/dist/{image-generation-OSU7FP6F.js → image-generation-MDE6AVQO.js} +2 -2
  157. package/dist/imessage-DSGSGUZS.js +44 -0
  158. package/dist/inbox-summarizer-F2KAU72V.js +56 -0
  159. package/dist/{incident-response-C5J7Q6DT.js → incident-response-E3UGMX5G.js} +8 -6
  160. package/dist/incident-response-E3UGMX5G.js.map +1 -0
  161. package/dist/{inventory-manager-352OHXWD.js → inventory-manager-C67BSZM6.js} +2 -2
  162. package/dist/{jira-GSGDBMIG.js → jira-PAGZWUBJ.js} +2 -2
  163. package/dist/{json-tool-QE2SYHEG.js → json-tool-4FK5RNER.js} +2 -2
  164. package/dist/{key-rotation-DPHU4ZTB.js → key-rotation-WCC5FOYS.js} +2 -2
  165. package/dist/knowledge-base-5SMMOGQJ.js +46 -0
  166. package/dist/lib.d.ts +94 -1
  167. package/dist/lib.js +83 -66
  168. package/dist/lib.js.map +1 -1
  169. package/dist/{mailchimp-KKNF6QJ7.js → mailchimp-ZFYDC44J.js} +2 -2
  170. package/dist/{matrix-QVHG76I7.js → matrix-WYGEOZL5.js} +30 -21
  171. package/dist/{matrix-QVHG76I7.js.map → matrix-WYGEOZL5.js.map} +1 -1
  172. package/dist/{mcp-3JI6W7ZE.js → mcp-DJ2QDA6A.js} +3 -3
  173. package/dist/metrics-BH3ZLGEV.js +25 -0
  174. package/dist/{microsoft365-UCBKJHNX.js → microsoft365-6G2IJMWC.js} +2 -2
  175. package/dist/multi-user-XAEMB244.js +411 -0
  176. package/dist/multi-user-XAEMB244.js.map +1 -0
  177. package/dist/oauth-UPJYFOVU.js +34 -0
  178. package/dist/{ocr-AC7NPX33.js → ocr-UONKTQU7.js} +6 -4
  179. package/dist/{ollama-BOAMSPLJ.js → ollama-J7CU45WT.js} +2 -2
  180. package/dist/osint-agent-RL5XPBRQ.js +189 -0
  181. package/dist/osint-agent-RL5XPBRQ.js.map +1 -0
  182. package/dist/{pages-MI523RB7.js → pages-XDE7JRCA.js} +5 -5
  183. package/dist/{pair-JDFTERIK.js → pair-YZJFQUU5.js} +2 -2
  184. package/dist/{pairing-IFQYCPNS.js → pairing-77N47RAT.js} +2 -2
  185. package/dist/{pdf-ALQVOEJR.js → pdf-67HGXCFJ.js} +3 -3
  186. package/dist/pdf-parser-YLMTTYHL.js +14 -0
  187. package/dist/{presentations-DSV5IHG5.js → presentations-UOET2FVZ.js} +3 -3
  188. package/dist/presentations-UOET2FVZ.js.map +1 -0
  189. package/dist/{prometheus-JNT2BD4L.js → prometheus-YETCZO4I.js} +2 -2
  190. package/dist/prometheus-YETCZO4I.js.map +1 -0
  191. package/dist/{providers-J4LYPHDR.js → providers-2YQ6E3IF.js} +6 -4
  192. package/dist/providers-2YQ6E3IF.js.map +1 -0
  193. package/dist/{qr-code-WIX4PB4U.js → qr-code-6WZJHRKL.js} +2 -2
  194. package/dist/qr-code-6WZJHRKL.js.map +1 -0
  195. package/dist/{quickbooks-XB4NII2S.js → quickbooks-N675W7IK.js} +2 -2
  196. package/dist/{regex-tool-W4ABRKGK.js → regex-tool-6Q63LQ7B.js} +2 -2
  197. package/dist/regex-tool-6Q63LQ7B.js.map +1 -0
  198. package/dist/research-agent-WCRSY3UZ.js +168 -0
  199. package/dist/research-agent-WCRSY3UZ.js.map +1 -0
  200. package/dist/risk-engine-YKCPT5D5.js +10 -0
  201. package/dist/risk-engine-YKCPT5D5.js.map +1 -0
  202. package/dist/scheduler-6PLLAQI7.js +74 -0
  203. package/dist/scheduler-6PLLAQI7.js.map +1 -0
  204. package/dist/schema-ETY7L2VA.js +78 -0
  205. package/dist/schema-ETY7L2VA.js.map +1 -0
  206. package/dist/{search-BCLBO5E3.js → search-GMLKBHSW.js} +4 -4
  207. package/dist/search-GMLKBHSW.js.map +1 -0
  208. package/dist/{sendgrid-RNXCAFKM.js → sendgrid-QGJIVPWV.js} +2 -2
  209. package/dist/sharepoint-V5P4Q62L.js +30 -0
  210. package/dist/sharepoint-V5P4Q62L.js.map +1 -0
  211. package/dist/{shopify-NCXYJB4R.js → shopify-ON2PAU27.js} +2 -2
  212. package/dist/signal-7D5EPGVL.js +44 -0
  213. package/dist/signal-7D5EPGVL.js.map +1 -0
  214. package/dist/slack-KSS6YK5Z.js +86 -0
  215. package/dist/slack-KSS6YK5Z.js.map +1 -0
  216. package/dist/{sms-M3JIOTCW.js → sms-CSUCC7HL.js} +4 -4
  217. package/dist/sms-CSUCC7HL.js.map +1 -0
  218. package/dist/{src-VYUE6LRA.js → src-GO7GGW7O.js} +190 -52
  219. package/dist/src-GO7GGW7O.js.map +1 -0
  220. package/dist/{stocks-XXWBPOCU.js → stocks-4M4HZWZS.js} +2 -2
  221. package/dist/stocks-4M4HZWZS.js.map +1 -0
  222. package/dist/text-extractor-OAUBAW5P.js +12 -0
  223. package/dist/text-extractor-OAUBAW5P.js.map +1 -0
  224. package/dist/{text-transform-6SGUA5Z4.js → text-transform-HCLCUDFZ.js} +2 -2
  225. package/dist/text-transform-HCLCUDFZ.js.map +1 -0
  226. package/dist/token-store-SEWRX6RE.js +20 -0
  227. package/dist/token-store-SEWRX6RE.js.map +1 -0
  228. package/dist/tools-PJZ6RI4P.js +47 -0
  229. package/dist/tools-PJZ6RI4P.js.map +1 -0
  230. package/dist/{tunnel-IWMXUML4.js → tunnel-XOUVVRAK.js} +4 -2
  231. package/dist/tunnel-XOUVVRAK.js.map +1 -0
  232. package/dist/{twilio-53GEW5JT.js → twilio-3L7DUNYQ.js} +2 -2
  233. package/dist/{unit-converter-ZYXMEZOE.js → unit-converter-LYPAHU64.js} +2 -2
  234. package/dist/unit-converter-LYPAHU64.js.map +1 -0
  235. package/dist/whatsapp-DWXK25V2.js +44 -0
  236. package/dist/whatsapp-DWXK25V2.js.map +1 -0
  237. package/dist/{word-document-7B6SJMAY.js → word-document-AV3YB4L2.js} +4 -4
  238. package/dist/word-document-AV3YB4L2.js.map +1 -0
  239. package/dist/workflow-store-5Y56GUP7.js +373 -0
  240. package/dist/workflow-store-5Y56GUP7.js.map +1 -0
  241. package/dist/writing-agent-VDGLNOGO.js +243 -0
  242. package/dist/writing-agent-VDGLNOGO.js.map +1 -0
  243. package/dist/{xero-QYO66D45.js → xero-UHAHVYSD.js} +2 -2
  244. package/dist/{zapier-webhook-TBZ5YF2A.js → zapier-webhook-NIELLTXR.js} +2 -2
  245. package/drizzle/0002_mushy_master_mold.sql +139 -139
  246. package/drizzle/0003_overjoyed_rhodey.sql +46 -0
  247. package/drizzle/meta/0002_snapshot.json +3636 -3636
  248. package/drizzle/meta/0003_snapshot.json +3946 -0
  249. package/drizzle/meta/_journal.json +7 -0
  250. package/package.json +110 -100
  251. package/dist/autonomy-ZXDBDQUJ.js.map +0 -1
  252. package/dist/bot-QRARP4UN.js +0 -36
  253. package/dist/brain-7XLLM3KC.js +0 -56
  254. package/dist/chunk-4GLYY4NN.js.map +0 -1
  255. package/dist/chunk-766ASQWE.js.map +0 -1
  256. package/dist/chunk-AYUKPTSM.js.map +0 -1
  257. package/dist/chunk-BRBWNV65.js.map +0 -1
  258. package/dist/chunk-BXZ6EA52.js.map +0 -1
  259. package/dist/chunk-EVE7MIIY.js.map +0 -1
  260. package/dist/chunk-H5RQOFO2.js.map +0 -1
  261. package/dist/chunk-I6BDYQIG.js.map +0 -1
  262. package/dist/chunk-IZJMVV7O.js +0 -347
  263. package/dist/chunk-IZJMVV7O.js.map +0 -1
  264. package/dist/chunk-O7IH7JTI.js +0 -1898
  265. package/dist/chunk-O7IH7JTI.js.map +0 -1
  266. package/dist/chunk-OCVQGBJK.js.map +0 -1
  267. package/dist/chunk-RZ4YESBG.js.map +0 -1
  268. package/dist/chunk-SPPMCAKG.js.map +0 -1
  269. package/dist/chunk-VRD5CYRL.js +0 -1568
  270. package/dist/chunk-VRD5CYRL.js.map +0 -1
  271. package/dist/chunk-WRAKK6K6.js.map +0 -1
  272. package/dist/chunk-XKYRH4FM.js.map +0 -1
  273. package/dist/chunk-XMCVRVTF.js.map +0 -1
  274. package/dist/chunk-ZLZKF2PM.js.map +0 -1
  275. package/dist/discord-B3HUPGQ6.js +0 -70
  276. package/dist/dist-UISMLMFN.js +0 -21847
  277. package/dist/dist-UISMLMFN.js.map +0 -1
  278. package/dist/email-K7LO2IPB.js.map +0 -1
  279. package/dist/enrichment-pipeline-MNHNW65K.js +0 -13
  280. package/dist/env-IWXUVTCB.js +0 -12
  281. package/dist/imessage-NGA2XF2V.js +0 -35
  282. package/dist/inbox-summarizer-NRI4S7IF.js +0 -47
  283. package/dist/incident-response-C5J7Q6DT.js.map +0 -1
  284. package/dist/presentations-DSV5IHG5.js.map +0 -1
  285. package/dist/scheduler-VK4WFERV.js +0 -63
  286. package/dist/signal-6CGDFYL2.js +0 -35
  287. package/dist/slack-IZQWIKOH.js +0 -75
  288. package/dist/src-VYUE6LRA.js.map +0 -1
  289. package/dist/tools-2RLEI2N6.js +0 -38
  290. package/dist/tunnel-IWMXUML4.js.map +0 -1
  291. package/dist/whatsapp-LFX6YKCM.js +0 -35
  292. package/dist/word-document-7B6SJMAY.js.map +0 -1
  293. /package/dist/{audit-logger-OBPR7CRO.js.map → agent-manager-JZ4IM7XI.js.map} +0 -0
  294. /package/dist/{auth-UOX5K2BE.js.map → agent-types-2T4PXLFQ.js.map} +0 -0
  295. /package/dist/{backup-restore-PZ7CYYB7.js.map → analyzer-OTWE3ARE.js.map} +0 -0
  296. /package/dist/{archiver-AVNBYCKQ.js.map → archiver-FPGKRP6P.js.map} +0 -0
  297. /package/dist/{blocks-R3PODY47.js.map → audit-logger-CI4WZQPD.js.map} +0 -0
  298. /package/dist/{bot-QRARP4UN.js.map → auth-PH5IHISW.js.map} +0 -0
  299. /package/dist/{aws-s3-Q4LLZZPD.js.map → aws-s3-QZMURYXB.js.map} +0 -0
  300. /package/dist/{brain-7XLLM3KC.js.map → backup-restore-72OQTZO3.js.map} +0 -0
  301. /package/dist/{chunk-PLDDJCW6.js.map → blocks-YOWOESDD.js.map} +0 -0
  302. /package/dist/{client-ZQSFPMOB.js.map → bot-VDHBGUVI.js.map} +0 -0
  303. /package/dist/{clipboard-manager-TEO2GEDN.js.map → brain-6QTXN4QP.js.map} +0 -0
  304. /package/dist/{camera-monitor-M5CYKUU4.js.map → camera-monitor-LHTUWHEL.js.map} +0 -0
  305. /package/dist/{charts-V7ARZNKF.js.map → charts-FJ32GQK7.js.map} +0 -0
  306. /package/dist/{chunk-TVEWKIK3.js.map → chunk-2WTKTG2C.js.map} +0 -0
  307. /package/dist/{chunk-SJSUSJ47.js.map → chunk-BNZHWAZC.js.map} +0 -0
  308. /package/dist/{chunk-MQJ2ECQT.js.map → chunk-CUPEENUY.js.map} +0 -0
  309. /package/dist/{chunk-NHMBTUMW.js.map → chunk-CWT6CAE5.js.map} +0 -0
  310. /package/dist/{chunk-6PMVAAA7.js.map → chunk-HJSEEFO3.js.map} +0 -0
  311. /package/dist/{chunk-TYAGMJNV.js.map → chunk-HQZQFEAX.js.map} +0 -0
  312. /package/dist/{chunk-MXAPLSJ5.js.map → chunk-J4JW73TT.js.map} +0 -0
  313. /package/dist/{chunk-VEHFVBLI.js.map → chunk-JHYYFPKX.js.map} +0 -0
  314. /package/dist/{chunk-66OJ3WB4.js.map → chunk-PD3CTDO6.js.map} +0 -0
  315. /package/dist/{cron-explain-HHQKPD3M.js.map → chunk-UP2VWCW5.js.map} +0 -0
  316. /package/dist/{chunk-4UOE5TUZ.js.map → chunk-WMDVOWN6.js.map} +0 -0
  317. /package/dist/{crypto-4AP47IKC.js.map → chunker-K6WTR62A.js.map} +0 -0
  318. /package/dist/{databases-37X4CI2Y.js.map → client-FOIYPOZQ.js.map} +0 -0
  319. /package/dist/{discord-B3HUPGQ6.js.map → clipboard-manager-4SBNESGZ.js.map} +0 -0
  320. /package/dist/{enrichment-pipeline-MNHNW65K.js.map → cost-tracker-KZQSTSE2.js.map} +0 -0
  321. /package/dist/{entity-resolution-Y3IUWEAT.js.map → cron-explain-UOOOYWZZ.js.map} +0 -0
  322. /package/dist/{env-IWXUVTCB.js.map → crypto-2VG3RJR2.js.map} +0 -0
  323. /package/dist/{hash-tool-ULQYD7B5.js.map → databases-XDPMG5AV.js.map} +0 -0
  324. /package/dist/{heartbeat-monitor-GCISLXI3.js.map → db-I7MNG6CL.js.map} +0 -0
  325. /package/dist/{imessage-NGA2XF2V.js.map → discord-6UQHCN27.js.map} +0 -0
  326. /package/dist/{inbox-summarizer-NRI4S7IF.js.map → docx-parser-EXL4TN5E.js.map} +0 -0
  327. /package/dist/{inventory-manager-352OHXWD.js.map → enrichment-pipeline-7FE5R5ZI.js.map} +0 -0
  328. /package/dist/{json-tool-QE2SYHEG.js.map → entity-resolution-7Z6STVXX.js.map} +0 -0
  329. /package/dist/{key-rotation-DPHU4ZTB.js.map → env-GN5VHI43.js.map} +0 -0
  330. /package/dist/{mcp-3JI6W7ZE.js.map → error-tracker-64DEH3D7.js.map} +0 -0
  331. /package/dist/{google-workspace-DKWUVNGC.js.map → google-workspace-TSZPZK5G.js.map} +0 -0
  332. /package/dist/{ocr-AC7NPX33.js.map → graph-client-NB475AK5.js.map} +0 -0
  333. /package/dist/{ollama-BOAMSPLJ.js.map → hash-tool-ENAB5LWH.js.map} +0 -0
  334. /package/dist/{pages-MI523RB7.js.map → heartbeat-monitor-KRDYTDBF.js.map} +0 -0
  335. /package/dist/{pairing-IFQYCPNS.js.map → hooks-N4MIFBVM.js.map} +0 -0
  336. /package/dist/{image-generation-OSU7FP6F.js.map → image-generation-MDE6AVQO.js.map} +0 -0
  337. /package/dist/{pdf-ALQVOEJR.js.map → imessage-DSGSGUZS.js.map} +0 -0
  338. /package/dist/{prometheus-JNT2BD4L.js.map → inbox-summarizer-F2KAU72V.js.map} +0 -0
  339. /package/dist/{providers-J4LYPHDR.js.map → inventory-manager-C67BSZM6.js.map} +0 -0
  340. /package/dist/{jira-GSGDBMIG.js.map → jira-PAGZWUBJ.js.map} +0 -0
  341. /package/dist/{qr-code-WIX4PB4U.js.map → json-tool-4FK5RNER.js.map} +0 -0
  342. /package/dist/{regex-tool-W4ABRKGK.js.map → key-rotation-WCC5FOYS.js.map} +0 -0
  343. /package/dist/{scheduler-VK4WFERV.js.map → knowledge-base-5SMMOGQJ.js.map} +0 -0
  344. /package/dist/{mailchimp-KKNF6QJ7.js.map → mailchimp-ZFYDC44J.js.map} +0 -0
  345. /package/dist/{search-BCLBO5E3.js.map → mcp-DJ2QDA6A.js.map} +0 -0
  346. /package/dist/{signal-6CGDFYL2.js.map → metrics-BH3ZLGEV.js.map} +0 -0
  347. /package/dist/{microsoft365-UCBKJHNX.js.map → microsoft365-6G2IJMWC.js.map} +0 -0
  348. /package/dist/{slack-IZQWIKOH.js.map → oauth-UPJYFOVU.js.map} +0 -0
  349. /package/dist/{sms-M3JIOTCW.js.map → ocr-UONKTQU7.js.map} +0 -0
  350. /package/dist/{stocks-XXWBPOCU.js.map → ollama-J7CU45WT.js.map} +0 -0
  351. /package/dist/{text-transform-6SGUA5Z4.js.map → pages-XDE7JRCA.js.map} +0 -0
  352. /package/dist/{pair-JDFTERIK.js.map → pair-YZJFQUU5.js.map} +0 -0
  353. /package/dist/{tools-2RLEI2N6.js.map → pairing-77N47RAT.js.map} +0 -0
  354. /package/dist/{unit-converter-ZYXMEZOE.js.map → pdf-67HGXCFJ.js.map} +0 -0
  355. /package/dist/{whatsapp-LFX6YKCM.js.map → pdf-parser-YLMTTYHL.js.map} +0 -0
  356. /package/dist/{quickbooks-XB4NII2S.js.map → quickbooks-N675W7IK.js.map} +0 -0
  357. /package/dist/{sendgrid-RNXCAFKM.js.map → sendgrid-QGJIVPWV.js.map} +0 -0
  358. /package/dist/{shopify-NCXYJB4R.js.map → shopify-ON2PAU27.js.map} +0 -0
  359. /package/dist/{twilio-53GEW5JT.js.map → twilio-3L7DUNYQ.js.map} +0 -0
  360. /package/dist/{xero-QYO66D45.js.map → xero-UHAHVYSD.js.map} +0 -0
  361. /package/dist/{zapier-webhook-TBZ5YF2A.js.map → zapier-webhook-NIELLTXR.js.map} +0 -0
@@ -0,0 +1,181 @@
1
+ // src/integrations/documents/docx-parser.ts
2
+ import mammoth from "mammoth";
3
+ import * as fs from "fs/promises";
4
+ import * as path from "path";
5
+ async function parseDOCX(input, options = {}) {
6
+ let buffer;
7
+ if (typeof input === "string") {
8
+ const absolutePath = path.isAbsolute(input) ? input : path.resolve(input);
9
+ buffer = await fs.readFile(absolutePath);
10
+ } else {
11
+ buffer = input;
12
+ }
13
+ const mammothOptions = {};
14
+ if (options.styleMap && options.styleMap.length > 0) {
15
+ mammothOptions.styleMap = options.styleMap;
16
+ }
17
+ if (options.includeImages) {
18
+ mammothOptions.convertImage = mammoth.images.imgElement((image) => {
19
+ return image.read("base64").then((imageBuffer) => {
20
+ return {
21
+ src: `data:${image.contentType};base64,${imageBuffer}`
22
+ };
23
+ });
24
+ });
25
+ }
26
+ const htmlResult = await mammoth.convertToHtml(
27
+ { buffer },
28
+ mammothOptions
29
+ );
30
+ const textResult = await mammoth.extractRawText({ buffer });
31
+ let markdown = "";
32
+ if (options.outputMarkdown) {
33
+ markdown = htmlToMarkdown(htmlResult.value);
34
+ }
35
+ const text = textResult.value;
36
+ const wordCount = text.split(/\s+/).filter((word) => word.length > 0).length;
37
+ const characterCount = text.length;
38
+ const paragraphCount = text.split(/\n\n+/).filter((p) => p.trim().length > 0).length;
39
+ const messages = htmlResult.messages.map((msg) => ({
40
+ type: msg.type,
41
+ message: msg.message,
42
+ paragraphIndex: msg.paragraphIndex
43
+ }));
44
+ return {
45
+ text: textResult.value,
46
+ html: htmlResult.value,
47
+ markdown: markdown || htmlToMarkdown(htmlResult.value),
48
+ messages,
49
+ metadata: {
50
+ wordCount,
51
+ characterCount,
52
+ paragraphCount
53
+ }
54
+ };
55
+ }
56
+ function htmlToMarkdown(html) {
57
+ let markdown = html;
58
+ markdown = markdown.replace(/<h1[^>]*>(.*?)<\/h1>/gi, "# $1\n\n");
59
+ markdown = markdown.replace(/<h2[^>]*>(.*?)<\/h2>/gi, "## $1\n\n");
60
+ markdown = markdown.replace(/<h3[^>]*>(.*?)<\/h3>/gi, "### $1\n\n");
61
+ markdown = markdown.replace(/<h4[^>]*>(.*?)<\/h4>/gi, "#### $1\n\n");
62
+ markdown = markdown.replace(/<h5[^>]*>(.*?)<\/h5>/gi, "##### $1\n\n");
63
+ markdown = markdown.replace(/<h6[^>]*>(.*?)<\/h6>/gi, "###### $1\n\n");
64
+ markdown = markdown.replace(/<strong[^>]*>(.*?)<\/strong>/gi, "**$1**");
65
+ markdown = markdown.replace(/<b[^>]*>(.*?)<\/b>/gi, "**$1**");
66
+ markdown = markdown.replace(/<em[^>]*>(.*?)<\/em>/gi, "*$1*");
67
+ markdown = markdown.replace(/<i[^>]*>(.*?)<\/i>/gi, "*$1*");
68
+ markdown = markdown.replace(
69
+ /<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi,
70
+ "[$2]($1)"
71
+ );
72
+ markdown = markdown.replace(
73
+ /<img[^>]*src="([^"]*)"[^>]*alt="([^"]*)"[^>]*\/?>/gi,
74
+ "![$2]($1)"
75
+ );
76
+ markdown = markdown.replace(
77
+ /<img[^>]*src="([^"]*)"[^>]*\/?>/gi,
78
+ "![]($1)"
79
+ );
80
+ markdown = markdown.replace(/<ul[^>]*>/gi, "\n");
81
+ markdown = markdown.replace(/<\/ul>/gi, "\n");
82
+ markdown = markdown.replace(/<ol[^>]*>/gi, "\n");
83
+ markdown = markdown.replace(/<\/ol>/gi, "\n");
84
+ markdown = markdown.replace(/<li[^>]*>(.*?)<\/li>/gi, "- $1\n");
85
+ markdown = markdown.replace(/<p[^>]*>(.*?)<\/p>/gi, "$1\n\n");
86
+ markdown = markdown.replace(/<br[^>]*\/?>/gi, "\n");
87
+ markdown = markdown.replace(/<code[^>]*>(.*?)<\/code>/gi, "`$1`");
88
+ markdown = markdown.replace(/<pre[^>]*>(.*?)<\/pre>/gis, "```\n$1\n```\n");
89
+ markdown = markdown.replace(
90
+ /<blockquote[^>]*>(.*?)<\/blockquote>/gis,
91
+ (match, content) => {
92
+ return content.split("\n").map((line) => `> ${line}`).join("\n");
93
+ }
94
+ );
95
+ markdown = markdown.replace(/<table[^>]*>/gi, "\n");
96
+ markdown = markdown.replace(/<\/table>/gi, "\n");
97
+ markdown = markdown.replace(/<tr[^>]*>/gi, "");
98
+ markdown = markdown.replace(/<\/tr>/gi, "|\n");
99
+ markdown = markdown.replace(/<th[^>]*>(.*?)<\/th>/gi, "| **$1** ");
100
+ markdown = markdown.replace(/<td[^>]*>(.*?)<\/td>/gi, "| $1 ");
101
+ markdown = markdown.replace(/<hr[^>]*\/?>/gi, "\n---\n");
102
+ markdown = markdown.replace(/<[^>]+>/g, "");
103
+ markdown = decodeHtmlEntities(markdown);
104
+ markdown = markdown.replace(/\n{3,}/g, "\n\n");
105
+ markdown = markdown.trim();
106
+ return markdown;
107
+ }
108
+ function decodeHtmlEntities(text) {
109
+ const entities = {
110
+ "&amp;": "&",
111
+ "&lt;": "<",
112
+ "&gt;": ">",
113
+ "&quot;": '"',
114
+ "&#39;": "'",
115
+ "&apos;": "'",
116
+ "&nbsp;": " ",
117
+ "&ndash;": "-",
118
+ "&mdash;": "--",
119
+ "&lsquo;": "'",
120
+ "&rsquo;": "'",
121
+ "&ldquo;": '"',
122
+ "&rdquo;": '"',
123
+ "&hellip;": "...",
124
+ "&copy;": "(c)",
125
+ "&reg;": "(R)",
126
+ "&trade;": "(TM)"
127
+ };
128
+ let result = text;
129
+ for (const [entity, char] of Object.entries(entities)) {
130
+ result = result.replace(new RegExp(entity, "g"), char);
131
+ }
132
+ result = result.replace(
133
+ /&#(\d+);/g,
134
+ (match, dec) => String.fromCharCode(parseInt(dec, 10))
135
+ );
136
+ result = result.replace(
137
+ /&#x([0-9a-fA-F]+);/g,
138
+ (match, hex) => String.fromCharCode(parseInt(hex, 16))
139
+ );
140
+ return result;
141
+ }
142
+ async function extractDOCXText(input) {
143
+ const result = await parseDOCX(input);
144
+ return result.text;
145
+ }
146
+ async function extractDOCXMarkdown(input) {
147
+ const result = await parseDOCX(input, { outputMarkdown: true });
148
+ return result.markdown;
149
+ }
150
+ async function isValidDOCX(input) {
151
+ try {
152
+ let buffer;
153
+ if (typeof input === "string") {
154
+ const absolutePath = path.isAbsolute(input) ? input : path.resolve(input);
155
+ buffer = await fs.readFile(absolutePath);
156
+ } else {
157
+ buffer = input;
158
+ }
159
+ const header = buffer.slice(0, 4);
160
+ if (header[0] !== 80 || header[1] !== 75) {
161
+ return false;
162
+ }
163
+ await mammoth.extractRawText({ buffer });
164
+ return true;
165
+ } catch {
166
+ return false;
167
+ }
168
+ }
169
+ async function getDOCXStats(input) {
170
+ const result = await parseDOCX(input);
171
+ return result.metadata;
172
+ }
173
+
174
+ export {
175
+ parseDOCX,
176
+ extractDOCXText,
177
+ extractDOCXMarkdown,
178
+ isValidDOCX,
179
+ getDOCXStats
180
+ };
181
+ //# sourceMappingURL=chunk-6W6PTJFT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/integrations/documents/docx-parser.ts"],"sourcesContent":["/**\r\n * DOCX Parser for OpenSentinel Document Ingestion\r\n *\r\n * Extracts text content from Word documents using mammoth.\r\n */\r\n\r\nimport mammoth from \"mammoth\";\r\nimport * as fs from \"fs/promises\";\r\nimport * as path from \"path\";\r\n\r\nexport interface DOCXParseResult {\r\n text: string;\r\n html: string;\r\n markdown: string;\r\n messages: DOCXMessage[];\r\n metadata: DOCXMetadata;\r\n}\r\n\r\nexport interface DOCXMessage {\r\n type: \"warning\" | \"error\";\r\n message: string;\r\n paragraphIndex?: number;\r\n}\r\n\r\nexport interface DOCXMetadata {\r\n /** Estimated word count */\r\n wordCount: number;\r\n /** Estimated character count */\r\n characterCount: number;\r\n /** Number of paragraphs */\r\n paragraphCount: number;\r\n}\r\n\r\nexport interface DOCXParseOptions {\r\n /** Include images as base64 data URIs */\r\n includeImages?: boolean;\r\n /** Custom style mappings for mammoth */\r\n styleMap?: string[];\r\n /** Convert to markdown instead of plain text */\r\n outputMarkdown?: boolean;\r\n}\r\n\r\n/**\r\n * Parse a DOCX file and extract its content\r\n */\r\nexport async function parseDOCX(\r\n input: string | Buffer,\r\n options: DOCXParseOptions = {}\r\n): Promise<DOCXParseResult> {\r\n let buffer: Buffer;\r\n\r\n if (typeof input === \"string\") {\r\n const absolutePath = path.isAbsolute(input) ? input : path.resolve(input);\r\n buffer = await fs.readFile(absolutePath);\r\n } else {\r\n buffer = input;\r\n }\r\n\r\n const mammothOptions: any = {};\r\n\r\n // Apply custom style mappings\r\n if (options.styleMap && options.styleMap.length > 0) {\r\n mammothOptions.styleMap = options.styleMap;\r\n }\r\n\r\n // Handle images\r\n if (options.includeImages) {\r\n mammothOptions.convertImage = mammoth.images.imgElement((image) => {\r\n return image.read(\"base64\").then((imageBuffer) => {\r\n return {\r\n src: `data:${image.contentType};base64,${imageBuffer}`,\r\n };\r\n });\r\n });\r\n }\r\n\r\n // Extract HTML\r\n const htmlResult = await mammoth.convertToHtml(\r\n { buffer },\r\n mammothOptions\r\n );\r\n\r\n // Extract plain text\r\n const textResult = await mammoth.extractRawText({ buffer });\r\n\r\n // Convert to markdown if requested\r\n let markdown = \"\";\r\n if (options.outputMarkdown) {\r\n markdown = htmlToMarkdown(htmlResult.value);\r\n }\r\n\r\n // Calculate metadata\r\n const text = textResult.value;\r\n const wordCount = text\r\n .split(/\\s+/)\r\n .filter((word) => word.length > 0).length;\r\n const characterCount = text.length;\r\n const paragraphCount = text.split(/\\n\\n+/).filter((p) => p.trim().length > 0)\r\n .length;\r\n\r\n // Map messages\r\n const messages: DOCXMessage[] = htmlResult.messages.map((msg) => ({\r\n type: msg.type as \"warning\" | \"error\",\r\n message: msg.message,\r\n paragraphIndex: (msg as any).paragraphIndex,\r\n }));\r\n\r\n return {\r\n text: textResult.value,\r\n html: htmlResult.value,\r\n markdown: markdown || htmlToMarkdown(htmlResult.value),\r\n messages,\r\n metadata: {\r\n wordCount,\r\n characterCount,\r\n paragraphCount,\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Convert HTML to basic markdown\r\n */\r\nfunction htmlToMarkdown(html: string): string {\r\n let markdown = html;\r\n\r\n // Headers\r\n markdown = markdown.replace(/<h1[^>]*>(.*?)<\\/h1>/gi, \"# $1\\n\\n\");\r\n markdown = markdown.replace(/<h2[^>]*>(.*?)<\\/h2>/gi, \"## $1\\n\\n\");\r\n markdown = markdown.replace(/<h3[^>]*>(.*?)<\\/h3>/gi, \"### $1\\n\\n\");\r\n markdown = markdown.replace(/<h4[^>]*>(.*?)<\\/h4>/gi, \"#### $1\\n\\n\");\r\n markdown = markdown.replace(/<h5[^>]*>(.*?)<\\/h5>/gi, \"##### $1\\n\\n\");\r\n markdown = markdown.replace(/<h6[^>]*>(.*?)<\\/h6>/gi, \"###### $1\\n\\n\");\r\n\r\n // Bold and italic\r\n markdown = markdown.replace(/<strong[^>]*>(.*?)<\\/strong>/gi, \"**$1**\");\r\n markdown = markdown.replace(/<b[^>]*>(.*?)<\\/b>/gi, \"**$1**\");\r\n markdown = markdown.replace(/<em[^>]*>(.*?)<\\/em>/gi, \"*$1*\");\r\n markdown = markdown.replace(/<i[^>]*>(.*?)<\\/i>/gi, \"*$1*\");\r\n\r\n // Links\r\n markdown = markdown.replace(\r\n /<a[^>]*href=\"([^\"]*)\"[^>]*>(.*?)<\\/a>/gi,\r\n \"[$2]($1)\"\r\n );\r\n\r\n // Images\r\n markdown = markdown.replace(\r\n /<img[^>]*src=\"([^\"]*)\"[^>]*alt=\"([^\"]*)\"[^>]*\\/?>/gi,\r\n \"![$2]($1)\"\r\n );\r\n markdown = markdown.replace(\r\n /<img[^>]*src=\"([^\"]*)\"[^>]*\\/?>/gi,\r\n \"![]($1)\"\r\n );\r\n\r\n // Lists\r\n markdown = markdown.replace(/<ul[^>]*>/gi, \"\\n\");\r\n markdown = markdown.replace(/<\\/ul>/gi, \"\\n\");\r\n markdown = markdown.replace(/<ol[^>]*>/gi, \"\\n\");\r\n markdown = markdown.replace(/<\\/ol>/gi, \"\\n\");\r\n markdown = markdown.replace(/<li[^>]*>(.*?)<\\/li>/gi, \"- $1\\n\");\r\n\r\n // Paragraphs and line breaks\r\n markdown = markdown.replace(/<p[^>]*>(.*?)<\\/p>/gi, \"$1\\n\\n\");\r\n markdown = markdown.replace(/<br[^>]*\\/?>/gi, \"\\n\");\r\n\r\n // Code\r\n markdown = markdown.replace(/<code[^>]*>(.*?)<\\/code>/gi, \"`$1`\");\r\n markdown = markdown.replace(/<pre[^>]*>(.*?)<\\/pre>/gis, \"```\\n$1\\n```\\n\");\r\n\r\n // Blockquotes\r\n markdown = markdown.replace(\r\n /<blockquote[^>]*>(.*?)<\\/blockquote>/gis,\r\n (match, content) => {\r\n return content\r\n .split(\"\\n\")\r\n .map((line: string) => `> ${line}`)\r\n .join(\"\\n\");\r\n }\r\n );\r\n\r\n // Tables (basic support)\r\n markdown = markdown.replace(/<table[^>]*>/gi, \"\\n\");\r\n markdown = markdown.replace(/<\\/table>/gi, \"\\n\");\r\n markdown = markdown.replace(/<tr[^>]*>/gi, \"\");\r\n markdown = markdown.replace(/<\\/tr>/gi, \"|\\n\");\r\n markdown = markdown.replace(/<th[^>]*>(.*?)<\\/th>/gi, \"| **$1** \");\r\n markdown = markdown.replace(/<td[^>]*>(.*?)<\\/td>/gi, \"| $1 \");\r\n\r\n // Horizontal rule\r\n markdown = markdown.replace(/<hr[^>]*\\/?>/gi, \"\\n---\\n\");\r\n\r\n // Remove remaining HTML tags\r\n markdown = markdown.replace(/<[^>]+>/g, \"\");\r\n\r\n // Decode HTML entities\r\n markdown = decodeHtmlEntities(markdown);\r\n\r\n // Clean up whitespace\r\n markdown = markdown.replace(/\\n{3,}/g, \"\\n\\n\");\r\n markdown = markdown.trim();\r\n\r\n return markdown;\r\n}\r\n\r\n/**\r\n * Decode common HTML entities\r\n */\r\nfunction decodeHtmlEntities(text: string): string {\r\n const entities: Record<string, string> = {\r\n \"&amp;\": \"&\",\r\n \"&lt;\": \"<\",\r\n \"&gt;\": \">\",\r\n \"&quot;\": '\"',\r\n \"&#39;\": \"'\",\r\n \"&apos;\": \"'\",\r\n \"&nbsp;\": \" \",\r\n \"&ndash;\": \"-\",\r\n \"&mdash;\": \"--\",\r\n \"&lsquo;\": \"'\",\r\n \"&rsquo;\": \"'\",\r\n \"&ldquo;\": '\"',\r\n \"&rdquo;\": '\"',\r\n \"&hellip;\": \"...\",\r\n \"&copy;\": \"(c)\",\r\n \"&reg;\": \"(R)\",\r\n \"&trade;\": \"(TM)\",\r\n };\r\n\r\n let result = text;\r\n for (const [entity, char] of Object.entries(entities)) {\r\n result = result.replace(new RegExp(entity, \"g\"), char);\r\n }\r\n\r\n // Handle numeric entities\r\n result = result.replace(/&#(\\d+);/g, (match, dec) =>\r\n String.fromCharCode(parseInt(dec, 10))\r\n );\r\n result = result.replace(/&#x([0-9a-fA-F]+);/g, (match, hex) =>\r\n String.fromCharCode(parseInt(hex, 16))\r\n );\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Extract plain text from DOCX\r\n */\r\nexport async function extractDOCXText(input: string | Buffer): Promise<string> {\r\n const result = await parseDOCX(input);\r\n return result.text;\r\n}\r\n\r\n/**\r\n * Extract markdown from DOCX\r\n */\r\nexport async function extractDOCXMarkdown(\r\n input: string | Buffer\r\n): Promise<string> {\r\n const result = await parseDOCX(input, { outputMarkdown: true });\r\n return result.markdown;\r\n}\r\n\r\n/**\r\n * Check if a file is a valid DOCX\r\n */\r\nexport async function isValidDOCX(input: string | Buffer): Promise<boolean> {\r\n try {\r\n let buffer: Buffer;\r\n\r\n if (typeof input === \"string\") {\r\n const absolutePath = path.isAbsolute(input) ? input : path.resolve(input);\r\n buffer = await fs.readFile(absolutePath);\r\n } else {\r\n buffer = input;\r\n }\r\n\r\n // DOCX is a ZIP file, check for ZIP magic number\r\n const header = buffer.slice(0, 4);\r\n if (header[0] !== 0x50 || header[1] !== 0x4b) {\r\n return false;\r\n }\r\n\r\n // Try parsing to verify it's a valid DOCX\r\n await mammoth.extractRawText({ buffer });\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get document statistics without full parsing\r\n */\r\nexport async function getDOCXStats(\r\n input: string | Buffer\r\n): Promise<DOCXMetadata> {\r\n const result = await parseDOCX(input);\r\n return result.metadata;\r\n}\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,418 @@
1
+ import {
2
+ LinearRegression
3
+ } from "./chunk-WZAH34TG.js";
4
+
5
+ // src/core/brain/router.ts
6
+ var MODEL_TIERS = {
7
+ fast: {
8
+ tier: "fast",
9
+ model: "claude-haiku-4-5-20251001",
10
+ provider: "anthropic",
11
+ label: "Haiku 4.5",
12
+ maxTokens: 2048,
13
+ costPerMInputToken: 0.8,
14
+ costPerMOutputToken: 4
15
+ },
16
+ balanced: {
17
+ tier: "balanced",
18
+ model: "claude-sonnet-4-20250514",
19
+ provider: "anthropic",
20
+ label: "Sonnet 4",
21
+ maxTokens: 4096,
22
+ costPerMInputToken: 3,
23
+ costPerMOutputToken: 15
24
+ },
25
+ powerful: {
26
+ tier: "powerful",
27
+ model: "claude-opus-4-20250514",
28
+ provider: "anthropic",
29
+ label: "Opus 4",
30
+ maxTokens: 8192,
31
+ costPerMInputToken: 15,
32
+ costPerMOutputToken: 75
33
+ }
34
+ };
35
+ var FAST_PATTERNS = [
36
+ // Greetings and acknowledgments
37
+ /^(hi|hello|hey|thanks|thank you|ok|okay|yes|no|sure|got it|np|ty|thx|gm|gn)\b/i,
38
+ // Simple questions
39
+ /^(what time|what date|what day|how are you|who are you)\b/i,
40
+ // Short commands
41
+ /^(remind me|set timer|play|pause|stop|next|skip|mute|unmute)\b/i,
42
+ // Status checks
43
+ /^(status|check|ping|health|uptime)\b/i,
44
+ // Single-word queries
45
+ /^\w+[?!.]?$/i
46
+ ];
47
+ var POWERFUL_PATTERNS = [
48
+ // Mathematical/formal reasoning
49
+ /\b(prove|theorem|derive|lemma|formal proof|mathematical induction)\b/i,
50
+ // Deep analysis
51
+ /\b(comprehensive analysis|in-depth|systematic review|research paper)\b/i,
52
+ // Complex coding tasks
53
+ /\b(architect|design pattern|refactor.{0,20}entire|rewrite.{0,20}from|full implementation)\b/i,
54
+ // Multi-step planning
55
+ /\b(step.by.step plan|detailed strategy|long.term plan|roadmap|proposal)\b/i,
56
+ // Compare/contrast
57
+ /\b(compare and contrast|pros and cons|trade.?offs|evaluate.{0,20}options)\b/i,
58
+ // Long-form writing
59
+ /\b(write.{0,15}essay|write.{0,15}report|write.{0,15}article|draft.{0,15}document)\b/i,
60
+ // Legal/medical/financial analysis
61
+ /\b(legal analysis|medical review|financial analysis|risk assessment)\b/i
62
+ ];
63
+ var COMPLEX_TOOLS = /* @__PURE__ */ new Set([
64
+ "execute_command",
65
+ "write_file",
66
+ "generate_document",
67
+ "generate_spreadsheet",
68
+ "generate_chart",
69
+ "code_review",
70
+ "spawn_agent",
71
+ "create_workflow",
72
+ "analyze_image"
73
+ ]);
74
+ var SIMPLE_TOOLS = /* @__PURE__ */ new Set([
75
+ "get_time",
76
+ "get_weather",
77
+ "search_web",
78
+ "read_file",
79
+ "list_files",
80
+ "get_system_info",
81
+ "get_calendar_events"
82
+ ]);
83
+ var ModelRouter = class {
84
+ enabled;
85
+ defaultTier;
86
+ opusEnabled;
87
+ // Routing statistics
88
+ stats = { fast: 0, balanced: 0, powerful: 0 };
89
+ constructor(options) {
90
+ this.enabled = options?.enabled ?? true;
91
+ this.defaultTier = options?.defaultTier ?? "balanced";
92
+ this.opusEnabled = options?.opusEnabled ?? false;
93
+ }
94
+ /**
95
+ * Analyze message complexity and return recommended model config
96
+ */
97
+ routeMessage(message, context) {
98
+ if (!this.enabled) {
99
+ this.stats[this.defaultTier]++;
100
+ return MODEL_TIERS[this.defaultTier];
101
+ }
102
+ const tier = this.classifyComplexity(message, context);
103
+ this.stats[tier]++;
104
+ return MODEL_TIERS[tier];
105
+ }
106
+ /**
107
+ * Classify message complexity into a model tier
108
+ */
109
+ classifyComplexity(message, context) {
110
+ if (context?.thinkingLevel === "extended" && this.opusEnabled) {
111
+ return "powerful";
112
+ }
113
+ const trimmed = message.trim();
114
+ if (trimmed.length < 15) {
115
+ return "fast";
116
+ }
117
+ for (const pattern of FAST_PATTERNS) {
118
+ if (pattern.test(trimmed)) {
119
+ return "fast";
120
+ }
121
+ }
122
+ if (this.opusEnabled) {
123
+ for (const pattern of POWERFUL_PATTERNS) {
124
+ if (pattern.test(trimmed)) {
125
+ return "powerful";
126
+ }
127
+ }
128
+ }
129
+ if (context?.toolsRequested) {
130
+ const hasComplexTools = context.toolsRequested.some((t) => COMPLEX_TOOLS.has(t));
131
+ const hasOnlySimpleTools = context.toolsRequested.every((t) => SIMPLE_TOOLS.has(t));
132
+ if (hasComplexTools && this.opusEnabled) {
133
+ return "powerful";
134
+ }
135
+ if (hasOnlySimpleTools && context.toolsRequested.length <= 2) {
136
+ return "fast";
137
+ }
138
+ }
139
+ const wordCount = trimmed.split(/\s+/).length;
140
+ if (wordCount < 8) {
141
+ return "fast";
142
+ }
143
+ if (trimmed.length > 500 && this.opusEnabled) {
144
+ return "powerful";
145
+ }
146
+ const result = this.defaultTier;
147
+ if (context?.appTypeTier) {
148
+ const tierOrder = { fast: 0, balanced: 1, powerful: 2 };
149
+ if (tierOrder[context.appTypeTier] > tierOrder[result]) {
150
+ return context.appTypeTier;
151
+ }
152
+ }
153
+ return result;
154
+ }
155
+ /**
156
+ * Estimate cost for a given tier and token counts
157
+ */
158
+ estimateCost(tier, inputTokens, outputTokens) {
159
+ const config = MODEL_TIERS[tier];
160
+ return inputTokens / 1e6 * config.costPerMInputToken + outputTokens / 1e6 * config.costPerMOutputToken;
161
+ }
162
+ /**
163
+ * Get info about a model tier
164
+ */
165
+ getTierInfo(tier) {
166
+ return MODEL_TIERS[tier];
167
+ }
168
+ /**
169
+ * Get routing statistics
170
+ */
171
+ getStats() {
172
+ const total = this.stats.fast + this.stats.balanced + this.stats.powerful;
173
+ return { ...this.stats, total };
174
+ }
175
+ /**
176
+ * Reset routing statistics
177
+ */
178
+ resetStats() {
179
+ this.stats = { fast: 0, balanced: 0, powerful: 0 };
180
+ }
181
+ /**
182
+ * Get estimated cost savings vs always using balanced
183
+ */
184
+ getEstimatedSavings(avgInputTokens = 1e3, avgOutputTokens = 500) {
185
+ const stats = this.getStats();
186
+ if (stats.total === 0) return { withRouting: 0, withoutRouting: 0, savings: 0, savingsPercent: 0 };
187
+ const withRouting = this.estimateCost("fast", avgInputTokens * stats.fast, avgOutputTokens * stats.fast) + this.estimateCost("balanced", avgInputTokens * stats.balanced, avgOutputTokens * stats.balanced) + this.estimateCost("powerful", avgInputTokens * stats.powerful, avgOutputTokens * stats.powerful);
188
+ const withoutRouting = this.estimateCost("balanced", avgInputTokens * stats.total, avgOutputTokens * stats.total);
189
+ const savings = withoutRouting - withRouting;
190
+ const savingsPercent = withoutRouting > 0 ? savings / withoutRouting * 100 : 0;
191
+ return { withRouting, withoutRouting, savings, savingsPercent };
192
+ }
193
+ isEnabled() {
194
+ return this.enabled;
195
+ }
196
+ setEnabled(enabled) {
197
+ this.enabled = enabled;
198
+ }
199
+ isOpusEnabled() {
200
+ return this.opusEnabled;
201
+ }
202
+ setOpusEnabled(enabled) {
203
+ this.opusEnabled = enabled;
204
+ }
205
+ };
206
+ var modelRouter = new ModelRouter();
207
+
208
+ // src/core/observability/cost-tracker.ts
209
+ var CostTracker = class {
210
+ records = [];
211
+ maxRecords = 1e4;
212
+ // Keep last 10K records in memory
213
+ dbLoaded = false;
214
+ /**
215
+ * Load historical cost records from the database on startup
216
+ */
217
+ async loadFromDb() {
218
+ if (this.dbLoaded) return;
219
+ try {
220
+ const { db } = await import("./db-I7MNG6CL.js");
221
+ const { metrics } = await import("./schema-ETY7L2VA.js");
222
+ const { eq, desc } = await import("drizzle-orm");
223
+ const rows = await db.select().from(metrics).where(eq(metrics.name, "token_cost")).orderBy(desc(metrics.timestamp)).limit(this.maxRecords);
224
+ for (const row of rows.reverse()) {
225
+ const tags = row.tags || {};
226
+ this.records.push({
227
+ tier: tags.tier || "balanced",
228
+ inputTokens: parseInt(tags.inputTokens || "0"),
229
+ outputTokens: parseInt(tags.outputTokens || "0"),
230
+ cost: (row.value || 0) / 1e6,
231
+ // stored as micro-dollars
232
+ timestamp: new Date(row.timestamp).getTime()
233
+ });
234
+ }
235
+ this.dbLoaded = true;
236
+ if (this.records.length > 0) {
237
+ console.log(`[CostTracker] Loaded ${this.records.length} historical records from DB`);
238
+ }
239
+ } catch {
240
+ }
241
+ }
242
+ /**
243
+ * Record token usage for a request
244
+ */
245
+ recordUsage(tier, inputTokens, outputTokens) {
246
+ const tierConfig = MODEL_TIERS[tier] || MODEL_TIERS.balanced;
247
+ const inputCost = inputTokens / 1e6 * tierConfig.costPerMInputToken;
248
+ const outputCost = outputTokens / 1e6 * tierConfig.costPerMOutputToken;
249
+ const totalCost = inputCost + outputCost;
250
+ const record = {
251
+ tier,
252
+ inputTokens,
253
+ outputTokens,
254
+ cost: totalCost,
255
+ timestamp: Date.now()
256
+ };
257
+ this.records.push(record);
258
+ if (this.records.length > this.maxRecords) {
259
+ this.records = this.records.slice(-this.maxRecords);
260
+ }
261
+ this.persistRecord(record).catch(() => {
262
+ });
263
+ return record;
264
+ }
265
+ async persistRecord(record) {
266
+ try {
267
+ const { db } = await import("./db-I7MNG6CL.js");
268
+ const { metrics } = await import("./schema-ETY7L2VA.js");
269
+ await db.insert(metrics).values({
270
+ name: "token_cost",
271
+ value: Math.round(record.cost * 1e6),
272
+ // store as micro-dollars for integer precision
273
+ unit: "microdollars",
274
+ tags: {
275
+ tier: record.tier,
276
+ inputTokens: String(record.inputTokens),
277
+ outputTokens: String(record.outputTokens)
278
+ }
279
+ });
280
+ } catch {
281
+ }
282
+ }
283
+ /**
284
+ * Get cost summary for a time range
285
+ */
286
+ getCostSummary(since, until) {
287
+ const start = since || 0;
288
+ const end = until || Date.now();
289
+ const filtered = this.records.filter(
290
+ (r) => r.timestamp >= start && r.timestamp <= end
291
+ );
292
+ const costByTier = {};
293
+ let totalCost = 0;
294
+ let totalInputTokens = 0;
295
+ let totalOutputTokens = 0;
296
+ for (const record of filtered) {
297
+ totalCost += record.cost;
298
+ totalInputTokens += record.inputTokens;
299
+ totalOutputTokens += record.outputTokens;
300
+ costByTier[record.tier] = (costByTier[record.tier] || 0) + record.cost;
301
+ }
302
+ return {
303
+ totalCost,
304
+ costByTier,
305
+ totalInputTokens,
306
+ totalOutputTokens,
307
+ requestCount: filtered.length,
308
+ timeRange: { start, end }
309
+ };
310
+ }
311
+ /**
312
+ * Get average cost per interaction
313
+ */
314
+ getCostPerInteraction() {
315
+ if (this.records.length === 0) return 0;
316
+ const total = this.records.reduce((sum, r) => sum + r.cost, 0);
317
+ return total / this.records.length;
318
+ }
319
+ /**
320
+ * Get estimated monthly cost using Linear Regression forecasting.
321
+ * Fits a regression on daily cost totals from the last 14 days, then projects 30 days.
322
+ */
323
+ getEstimatedMonthlyCost() {
324
+ if (this.records.length < 2) return 0;
325
+ const now = Date.now();
326
+ const dailyCosts = this.getDailyCostHistory(14);
327
+ if (dailyCosts.length < 2) {
328
+ const oneDayAgo = now - 864e5;
329
+ const recentRecords = this.records.filter((r) => r.timestamp >= oneDayAgo);
330
+ if (recentRecords.length === 0) return 0;
331
+ const dailyCost = recentRecords.reduce((sum, r) => sum + r.cost, 0);
332
+ return dailyCost * 30;
333
+ }
334
+ const predictions = LinearRegression.forecast(dailyCosts, 30);
335
+ return predictions.reduce((sum, p) => sum + Math.max(0, p.value), 0);
336
+ }
337
+ /**
338
+ * Detect spending trend: up, down, or flat.
339
+ */
340
+ getCostTrend() {
341
+ const dailyCosts = this.getDailyCostHistory(14);
342
+ if (dailyCosts.length < 3) {
343
+ return { direction: "flat", strength: 0, dailyChange: 0 };
344
+ }
345
+ const trend = LinearRegression.detectTrend(dailyCosts);
346
+ return {
347
+ direction: trend.direction,
348
+ strength: trend.strength,
349
+ dailyChange: trend.slopePerUnit
350
+ };
351
+ }
352
+ /**
353
+ * Get forecast with confidence intervals for the next N days.
354
+ */
355
+ getForecast(daysAhead = 7) {
356
+ const dailyCosts = this.getDailyCostHistory(14);
357
+ if (dailyCosts.length < 2) return [];
358
+ const predictions = LinearRegression.forecast(dailyCosts, daysAhead);
359
+ return predictions.map((p, i) => ({
360
+ day: i + 1,
361
+ predicted: Math.max(0, p.value),
362
+ lower: Math.max(0, p.lower95),
363
+ upper: Math.max(0, p.upper95)
364
+ }));
365
+ }
366
+ /**
367
+ * Get daily cost totals for the last N days.
368
+ */
369
+ getDailyCostHistory(days) {
370
+ const now = Date.now();
371
+ const msPerDay = 864e5;
372
+ const dailyCosts = [];
373
+ for (let d = days - 1; d >= 0; d--) {
374
+ const dayStart = now - (d + 1) * msPerDay;
375
+ const dayEnd = now - d * msPerDay;
376
+ const dayCost = this.records.filter((r) => r.timestamp >= dayStart && r.timestamp < dayEnd).reduce((sum, r) => sum + r.cost, 0);
377
+ dailyCosts.push(dayCost);
378
+ }
379
+ return dailyCosts;
380
+ }
381
+ /**
382
+ * Get cost per million tokens for a tier
383
+ */
384
+ getCostPerMillionTokens(tier) {
385
+ const config = MODEL_TIERS[tier] || MODEL_TIERS.balanced;
386
+ return {
387
+ input: config.costPerMInputToken,
388
+ output: config.costPerMOutputToken
389
+ };
390
+ }
391
+ /**
392
+ * Get all records (for debugging/export)
393
+ */
394
+ getRecords() {
395
+ return [...this.records];
396
+ }
397
+ /**
398
+ * Get record count
399
+ */
400
+ getRecordCount() {
401
+ return this.records.length;
402
+ }
403
+ /**
404
+ * Clear all records
405
+ */
406
+ reset() {
407
+ this.records = [];
408
+ }
409
+ };
410
+ var costTracker = new CostTracker();
411
+
412
+ export {
413
+ MODEL_TIERS,
414
+ modelRouter,
415
+ CostTracker,
416
+ costTracker
417
+ };
418
+ //# sourceMappingURL=chunk-6ZNCY2GI.js.map