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
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/inputs/matrix/index.ts"],"sourcesContent":["import sdk from \"matrix-js-sdk\";\nimport { chatWithTools, type Message } from \"../../core/brain\";\n\n/**\n * Matrix bot configuration\n */\nexport interface MatrixBotConfig {\n homeserverUrl: string;\n accessToken: string;\n userId: string;\n allowedRoomIds?: string[];\n autoJoin?: boolean;\n e2eEnabled?: boolean;\n}\n\n/**\n * Matrix bot class — connects to a Matrix homeserver and responds to messages\n * using the OpenSentinel brain (chatWithTools).\n */\nexport class MatrixBot {\n private client: any;\n private sessions: Map<string, Array<{ role: string; content: string }>> =\n new Map();\n private maxSessionMessages: number = 20;\n\n private homeserverUrl: string;\n private accessToken: string;\n private userId: string;\n private allowedRoomIds?: string[];\n private autoJoin: boolean;\n private e2eEnabled: boolean;\n\n constructor(config: MatrixBotConfig) {\n this.homeserverUrl = config.homeserverUrl;\n this.accessToken = config.accessToken;\n this.userId = config.userId;\n this.allowedRoomIds = config.allowedRoomIds;\n this.autoJoin = config.autoJoin ?? false;\n this.e2eEnabled = config.e2eEnabled ?? false;\n }\n\n /**\n * Start the Matrix bot — creates the client, registers event listeners,\n * and begins syncing with the homeserver.\n */\n async start(): Promise<void> {\n console.log(\"[Matrix] Starting bot...\");\n\n this.client = sdk.createClient({\n baseUrl: this.homeserverUrl,\n accessToken: this.accessToken,\n userId: this.userId,\n });\n\n // Handle incoming room timeline events (messages)\n this.client.on(\"Room.timeline\", async (event: any, room: any) => {\n try {\n // Only handle m.room.message events\n if (event.getType() !== \"m.room.message\") return;\n\n const sender: string = event.getSender();\n const roomId: string = room.roomId;\n\n // Ignore our own messages\n if (sender === this.userId) return;\n\n const content = event.getContent();\n\n // Ignore non-text messages (images, files, etc.)\n if (!content || content.msgtype !== \"m.text\") return;\n\n const body: string = content.body;\n if (!body || !body.trim()) return;\n\n // Check if room is in the allowed list (if configured)\n if (\n this.allowedRoomIds &&\n this.allowedRoomIds.length > 0 &&\n !this.allowedRoomIds.includes(roomId)\n ) {\n return;\n }\n\n // Only respond if the bot is mentioned or if it's a DM\n const mentioned = this.isMentioned(body);\n const dm = this.isDM(roomId);\n\n if (!mentioned && !dm) return;\n\n // Set typing indicator to show we're processing\n try {\n await this.client.sendTyping(roomId, true, 30000);\n } catch (err) {\n console.warn(\"[Matrix] Failed to set typing indicator:\", err);\n }\n\n // Process the message and get a response\n const response = await this.processMessage(roomId, sender, body);\n\n // Clear typing indicator\n try {\n await this.client.sendTyping(roomId, false, 0);\n } catch (err) {\n console.warn(\"[Matrix] Failed to clear typing indicator:\", err);\n }\n\n // Send the response, splitting if necessary\n await this.sendMessage(roomId, response);\n\n console.log(\n `[Matrix] Processed message from ${sender} in room ${roomId}`\n );\n } catch (error) {\n console.error(\"[Matrix] Error handling Room.timeline event:\", error);\n\n // Attempt to clear typing indicator on error\n try {\n await this.client.sendTyping(room.roomId, false, 0);\n } catch {\n // Ignore typing indicator cleanup errors\n }\n\n // Attempt to send error message to the room\n try {\n await this.client.sendEvent(\n room.roomId,\n \"m.room.message\",\n {\n msgtype: \"m.text\",\n body: \"Sorry, I encountered an error processing your message. Please try again.\",\n },\n \"\"\n );\n } catch (sendError) {\n console.error(\"[Matrix] Failed to send error message:\", sendError);\n }\n }\n });\n\n // Handle room membership events (auto-join invites)\n this.client.on(\n \"RoomMember.membership\",\n async (event: any, member: any) => {\n try {\n if (\n this.autoJoin &&\n member.membership === \"invite\" &&\n member.userId === this.userId\n ) {\n const roomId = member.roomId;\n console.log(`[Matrix] Auto-joining room: ${roomId}`);\n\n await this.client.joinRoom(roomId);\n console.log(`[Matrix] Successfully joined room: ${roomId}`);\n }\n } catch (error) {\n console.error(\"[Matrix] Error handling membership event:\", error);\n }\n }\n );\n\n // Start the client with a limited initial sync\n await this.client.startClient({ initialSyncLimit: 10 });\n\n console.log(`[Matrix] Bot started as ${this.userId}`);\n }\n\n /**\n * Stop the Matrix bot and disconnect from the homeserver.\n */\n async stop(): Promise<void> {\n console.log(\"[Matrix] Stopping bot...\");\n\n if (this.client) {\n this.client.stopClient();\n }\n\n console.log(\"[Matrix] Bot stopped\");\n }\n\n /**\n * Process an incoming message: manage session history, call chatWithTools,\n * and return the response text.\n */\n private async processMessage(\n roomId: string,\n sender: string,\n body: string\n ): Promise<string> {\n // Get or create the session for this room\n let session = this.sessions.get(roomId);\n if (!session) {\n session = [];\n this.sessions.set(roomId, session);\n }\n\n // Add the user message to the session\n session.push({ role: \"user\", content: body });\n\n // Trim session to the max allowed messages\n if (session.length > this.maxSessionMessages) {\n session.splice(0, session.length - this.maxSessionMessages);\n }\n\n try {\n // Call chatWithTools with the session messages\n const response = await chatWithTools(\n session as Message[],\n `matrix:${sender}`,\n async () => {\n // Refresh typing indicator during tool use\n try {\n await this.client.sendTyping(roomId, true, 30000);\n } catch {\n // Ignore typing indicator errors during tool use\n }\n }\n );\n\n // Add the assistant response to the session\n session.push({ role: \"assistant\", content: response.content });\n\n // Trim session again if needed\n if (session.length > this.maxSessionMessages) {\n session.splice(0, session.length - this.maxSessionMessages);\n }\n\n // Build response with tool usage info\n let finalResponse = response.content;\n if (response.toolsUsed && response.toolsUsed.length > 0) {\n const toolList = [...new Set(response.toolsUsed)].join(\", \");\n finalResponse = `[Used: ${toolList}]\\n\\n${response.content}`;\n }\n\n console.log(\n `[Matrix] Response generated. Tokens: ${response.inputTokens}/${response.outputTokens}` +\n (response.toolsUsed\n ? ` Tools: ${response.toolsUsed.join(\", \")}`\n : \"\")\n );\n\n return finalResponse;\n } catch (error) {\n console.error(\"[Matrix] Error calling chatWithTools:\", error);\n return \"Sorry, I encountered an error processing your message. Please try again.\";\n }\n }\n\n /**\n * Send a message to a room, splitting into multiple messages if the text\n * exceeds 4000 characters.\n */\n private async sendMessage(roomId: string, text: string): Promise<void> {\n const MAX_LENGTH = 4000;\n\n if (text.length <= MAX_LENGTH) {\n await this.client.sendEvent(\n roomId,\n \"m.room.message\",\n {\n msgtype: \"m.text\",\n body: text,\n },\n \"\"\n );\n } else {\n // Split into chunks at line boundaries when possible\n const chunks: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n if (remaining.length <= MAX_LENGTH) {\n chunks.push(remaining);\n break;\n }\n\n // Try to split at a newline near the limit\n let splitIndex = remaining.lastIndexOf(\"\\n\", MAX_LENGTH);\n if (splitIndex === -1 || splitIndex < MAX_LENGTH * 0.5) {\n // If no good newline break, try a space\n splitIndex = remaining.lastIndexOf(\" \", MAX_LENGTH);\n }\n if (splitIndex === -1 || splitIndex < MAX_LENGTH * 0.5) {\n // Hard split as a last resort\n splitIndex = MAX_LENGTH;\n }\n\n chunks.push(remaining.substring(0, splitIndex));\n remaining = remaining.substring(splitIndex).trimStart();\n }\n\n for (const chunk of chunks) {\n await this.client.sendEvent(\n roomId,\n \"m.room.message\",\n {\n msgtype: \"m.text\",\n body: chunk,\n },\n \"\"\n );\n }\n\n console.log(\n `[Matrix] Split long message into ${chunks.length} chunks for room ${roomId}`\n );\n }\n }\n\n /**\n * Check if the bot is mentioned in the message body.\n * Looks for the bot's full userId (e.g. @bot:matrix.org) or the localpart\n * (e.g. bot).\n */\n private isMentioned(body: string): boolean {\n const lowerBody = body.toLowerCase();\n\n // Check for full userId mention (e.g. @opensentinel:matrix.org)\n if (lowerBody.includes(this.userId.toLowerCase())) {\n return true;\n }\n\n // Check for localpart mention (e.g. opensentinel)\n // userId format is @localpart:server\n const localpart = this.userId.split(\":\")[0]?.replace(\"@\", \"\");\n if (localpart && lowerBody.includes(localpart.toLowerCase())) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Check if a room is a direct message (has exactly 2 joined members).\n */\n private isDM(roomId: string): boolean {\n try {\n const room = this.client.getRoom(roomId);\n if (!room) return false;\n\n const members = room.getJoinedMembers();\n return members && members.length === 2;\n } catch (error) {\n console.error(\"[Matrix] Error checking if room is DM:\", error);\n return false;\n }\n }\n}\n\n/**\n * Create and configure a Matrix bot\n */\nexport function createMatrixBot(config: MatrixBotConfig): MatrixBot {\n return new MatrixBot(config);\n}\n\n/**\n * Default export\n */\nexport default {\n createMatrixBot,\n MatrixBot,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/inputs/matrix/index.ts"],"sourcesContent":["import sdk from \"matrix-js-sdk\";\nimport { chatWithTools, type Message } from \"../../core/brain\";\n\n/**\n * Matrix bot configuration\n */\nexport interface MatrixBotConfig {\n homeserverUrl: string;\n accessToken: string;\n userId: string;\n allowedRoomIds?: string[];\n autoJoin?: boolean;\n e2eEnabled?: boolean;\n}\n\n/**\n * Matrix bot class — connects to a Matrix homeserver and responds to messages\n * using the OpenSentinel brain (chatWithTools).\n */\nexport class MatrixBot {\n private client: any;\n private sessions: Map<string, Array<{ role: string; content: string }>> =\n new Map();\n private maxSessionMessages: number = 20;\n\n private homeserverUrl: string;\n private accessToken: string;\n private userId: string;\n private allowedRoomIds?: string[];\n private autoJoin: boolean;\n private e2eEnabled: boolean;\n\n constructor(config: MatrixBotConfig) {\n this.homeserverUrl = config.homeserverUrl;\n this.accessToken = config.accessToken;\n this.userId = config.userId;\n this.allowedRoomIds = config.allowedRoomIds;\n this.autoJoin = config.autoJoin ?? false;\n this.e2eEnabled = config.e2eEnabled ?? false;\n }\n\n /**\n * Start the Matrix bot — creates the client, registers event listeners,\n * and begins syncing with the homeserver.\n */\n async start(): Promise<void> {\n console.log(\"[Matrix] Starting bot...\");\n\n this.client = sdk.createClient({\n baseUrl: this.homeserverUrl,\n accessToken: this.accessToken,\n userId: this.userId,\n });\n\n // Handle incoming room timeline events (messages)\n this.client.on(\"Room.timeline\", async (event: any, room: any) => {\n try {\n // Only handle m.room.message events\n if (event.getType() !== \"m.room.message\") return;\n\n const sender: string = event.getSender();\n const roomId: string = room.roomId;\n\n // Ignore our own messages\n if (sender === this.userId) return;\n\n const content = event.getContent();\n\n // Ignore non-text messages (images, files, etc.)\n if (!content || content.msgtype !== \"m.text\") return;\n\n const body: string = content.body;\n if (!body || !body.trim()) return;\n\n // Check if room is in the allowed list (if configured)\n if (\n this.allowedRoomIds &&\n this.allowedRoomIds.length > 0 &&\n !this.allowedRoomIds.includes(roomId)\n ) {\n return;\n }\n\n // Only respond if the bot is mentioned or if it's a DM\n const mentioned = this.isMentioned(body);\n const dm = this.isDM(roomId);\n\n if (!mentioned && !dm) return;\n\n // Set typing indicator to show we're processing\n try {\n await this.client.sendTyping(roomId, true, 30000);\n } catch (err) {\n console.warn(\"[Matrix] Failed to set typing indicator:\", err);\n }\n\n // Process the message and get a response\n const response = await this.processMessage(roomId, sender, body);\n\n // Clear typing indicator\n try {\n await this.client.sendTyping(roomId, false, 0);\n } catch (err) {\n console.warn(\"[Matrix] Failed to clear typing indicator:\", err);\n }\n\n // Send the response, splitting if necessary\n await this.sendMessage(roomId, response);\n\n console.log(\n `[Matrix] Processed message from ${sender} in room ${roomId}`\n );\n } catch (error) {\n console.error(\"[Matrix] Error handling Room.timeline event:\", error);\n\n // Attempt to clear typing indicator on error\n try {\n await this.client.sendTyping(room.roomId, false, 0);\n } catch {\n // Ignore typing indicator cleanup errors\n }\n\n // Attempt to send error message to the room\n try {\n await this.client.sendEvent(\n room.roomId,\n \"m.room.message\",\n {\n msgtype: \"m.text\",\n body: \"Sorry, I encountered an error processing your message. Please try again.\",\n },\n \"\"\n );\n } catch (sendError) {\n console.error(\"[Matrix] Failed to send error message:\", sendError);\n }\n }\n });\n\n // Handle room membership events (auto-join invites)\n this.client.on(\n \"RoomMember.membership\",\n async (event: any, member: any) => {\n try {\n if (\n this.autoJoin &&\n member.membership === \"invite\" &&\n member.userId === this.userId\n ) {\n const roomId = member.roomId;\n console.log(`[Matrix] Auto-joining room: ${roomId}`);\n\n await this.client.joinRoom(roomId);\n console.log(`[Matrix] Successfully joined room: ${roomId}`);\n }\n } catch (error) {\n console.error(\"[Matrix] Error handling membership event:\", error);\n }\n }\n );\n\n // Start the client with a limited initial sync\n await this.client.startClient({ initialSyncLimit: 10 });\n\n console.log(`[Matrix] Bot started as ${this.userId}`);\n }\n\n /**\n * Stop the Matrix bot and disconnect from the homeserver.\n */\n async stop(): Promise<void> {\n console.log(\"[Matrix] Stopping bot...\");\n\n if (this.client) {\n this.client.stopClient();\n }\n\n console.log(\"[Matrix] Bot stopped\");\n }\n\n /**\n * Process an incoming message: manage session history, call chatWithTools,\n * and return the response text.\n */\n private async processMessage(\n roomId: string,\n sender: string,\n body: string\n ): Promise<string> {\n // Get or create the session for this room\n let session = this.sessions.get(roomId);\n if (!session) {\n session = [];\n this.sessions.set(roomId, session);\n }\n\n // Add the user message to the session\n session.push({ role: \"user\", content: body });\n\n // Trim session to the max allowed messages\n if (session.length > this.maxSessionMessages) {\n session.splice(0, session.length - this.maxSessionMessages);\n }\n\n try {\n // Call chatWithTools with the session messages\n const response = await chatWithTools(\n session as Message[],\n `matrix:${sender}`,\n async () => {\n // Refresh typing indicator during tool use\n try {\n await this.client.sendTyping(roomId, true, 30000);\n } catch {\n // Ignore typing indicator errors during tool use\n }\n }\n );\n\n // Add the assistant response to the session\n session.push({ role: \"assistant\", content: response.content });\n\n // Trim session again if needed\n if (session.length > this.maxSessionMessages) {\n session.splice(0, session.length - this.maxSessionMessages);\n }\n\n // Build response with tool usage info\n let finalResponse = response.content;\n if (response.toolsUsed && response.toolsUsed.length > 0) {\n const toolList = [...new Set(response.toolsUsed)].join(\", \");\n finalResponse = `[Used: ${toolList}]\\n\\n${response.content}`;\n }\n\n console.log(\n `[Matrix] Response generated. Tokens: ${response.inputTokens}/${response.outputTokens}` +\n (response.toolsUsed\n ? ` Tools: ${response.toolsUsed.join(\", \")}`\n : \"\")\n );\n\n return finalResponse;\n } catch (error) {\n console.error(\"[Matrix] Error calling chatWithTools:\", error);\n return \"Sorry, I encountered an error processing your message. Please try again.\";\n }\n }\n\n /**\n * Send a message to a room, splitting into multiple messages if the text\n * exceeds 4000 characters.\n */\n private async sendMessage(roomId: string, text: string): Promise<void> {\n const MAX_LENGTH = 4000;\n\n if (text.length <= MAX_LENGTH) {\n await this.client.sendEvent(\n roomId,\n \"m.room.message\",\n {\n msgtype: \"m.text\",\n body: text,\n },\n \"\"\n );\n } else {\n // Split into chunks at line boundaries when possible\n const chunks: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n if (remaining.length <= MAX_LENGTH) {\n chunks.push(remaining);\n break;\n }\n\n // Try to split at a newline near the limit\n let splitIndex = remaining.lastIndexOf(\"\\n\", MAX_LENGTH);\n if (splitIndex === -1 || splitIndex < MAX_LENGTH * 0.5) {\n // If no good newline break, try a space\n splitIndex = remaining.lastIndexOf(\" \", MAX_LENGTH);\n }\n if (splitIndex === -1 || splitIndex < MAX_LENGTH * 0.5) {\n // Hard split as a last resort\n splitIndex = MAX_LENGTH;\n }\n\n chunks.push(remaining.substring(0, splitIndex));\n remaining = remaining.substring(splitIndex).trimStart();\n }\n\n for (const chunk of chunks) {\n await this.client.sendEvent(\n roomId,\n \"m.room.message\",\n {\n msgtype: \"m.text\",\n body: chunk,\n },\n \"\"\n );\n }\n\n console.log(\n `[Matrix] Split long message into ${chunks.length} chunks for room ${roomId}`\n );\n }\n }\n\n /**\n * Check if the bot is mentioned in the message body.\n * Looks for the bot's full userId (e.g. @bot:matrix.org) or the localpart\n * (e.g. bot).\n */\n private isMentioned(body: string): boolean {\n const lowerBody = body.toLowerCase();\n\n // Check for full userId mention (e.g. @opensentinel:matrix.org)\n if (lowerBody.includes(this.userId.toLowerCase())) {\n return true;\n }\n\n // Check for localpart mention (e.g. opensentinel)\n // userId format is @localpart:server\n const localpart = this.userId.split(\":\")[0]?.replace(\"@\", \"\");\n if (localpart && lowerBody.includes(localpart.toLowerCase())) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Check if a room is a direct message (has exactly 2 joined members).\n */\n private isDM(roomId: string): boolean {\n try {\n const room = this.client.getRoom(roomId);\n if (!room) return false;\n\n const members = room.getJoinedMembers();\n return members && members.length === 2;\n } catch (error) {\n console.error(\"[Matrix] Error checking if room is DM:\", error);\n return false;\n }\n }\n}\n\n/**\n * Create and configure a Matrix bot\n */\nexport function createMatrixBot(config: MatrixBotConfig): MatrixBot {\n return new MatrixBot(config);\n}\n\n/**\n * Default export\n */\nexport default {\n createMatrixBot,\n MatrixBot,\n};\n"],"mappings":"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","names":[]}
@@ -11,8 +11,8 @@ import {
11
11
  mcpToolToAnthropicTool,
12
12
  mcpToolsToAnthropicTools,
13
13
  parseMCPToolName
14
- } from "./chunk-4GLYY4NN.js";
15
- import "./chunk-PLDDJCW6.js";
14
+ } from "./chunk-CZTMGHUC.js";
15
+ import "./chunk-UP2VWCW5.js";
16
16
  export {
17
17
  MCPClient,
18
18
  MCPRegistry,
@@ -27,4 +27,4 @@ export {
27
27
  mcpToolsToAnthropicTools,
28
28
  parseMCPToolName
29
29
  };
30
- //# sourceMappingURL=mcp-3JI6W7ZE.js.map
30
+ //# sourceMappingURL=mcp-DJ2QDA6A.js.map
@@ -0,0 +1,25 @@
1
+ import {
2
+ cleanupOldMetrics,
3
+ flushMetrics,
4
+ getMetricAggregates,
5
+ getMetricTimeSeries,
6
+ getSystemMetrics,
7
+ metric,
8
+ queryMetrics,
9
+ recordMetric
10
+ } from "./chunk-YEDEAX6Y.js";
11
+ import "./chunk-5BTVJR7R.js";
12
+ import "./chunk-4KIHDIXZ.js";
13
+ import "./chunk-ZIBRVA3Y.js";
14
+ import "./chunk-UP2VWCW5.js";
15
+ export {
16
+ cleanupOldMetrics,
17
+ flushMetrics,
18
+ getMetricAggregates,
19
+ getMetricTimeSeries,
20
+ getSystemMetrics,
21
+ metric,
22
+ queryMetrics,
23
+ recordMetric
24
+ };
25
+ //# sourceMappingURL=metrics-BH3ZLGEV.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BaseAdapter
3
3
  } from "./chunk-7WQO5J2M.js";
4
- import "./chunk-PLDDJCW6.js";
4
+ import "./chunk-UP2VWCW5.js";
5
5
 
6
6
  // src/core/adapters/adapters/microsoft365.ts
7
7
  import { z } from "zod";
@@ -161,4 +161,4 @@ var Microsoft365Adapter = class extends BaseAdapter {
161
161
  export {
162
162
  Microsoft365Adapter
163
163
  };
164
- //# sourceMappingURL=microsoft365-UCBKJHNX.js.map
164
+ //# sourceMappingURL=microsoft365-6G2IJMWC.js.map
@@ -0,0 +1,411 @@
1
+ import {
2
+ db
3
+ } from "./chunk-5BTVJR7R.js";
4
+ import "./chunk-4KIHDIXZ.js";
5
+ import {
6
+ apiKeys,
7
+ organizationMembers,
8
+ organizations,
9
+ sessions,
10
+ users
11
+ } from "./chunk-ZIBRVA3Y.js";
12
+ import "./chunk-UP2VWCW5.js";
13
+
14
+ // src/core/enterprise/multi-user.ts
15
+ import { eq, and, sql, inArray } from "drizzle-orm";
16
+ import { randomBytes, createHash } from "crypto";
17
+ async function createUser(options) {
18
+ const {
19
+ email,
20
+ name,
21
+ role = "member",
22
+ organizationId,
23
+ department,
24
+ manager,
25
+ metadata = {}
26
+ } = options;
27
+ const existing = await db.execute(
28
+ sql`SELECT id FROM users WHERE preferences->>'email' = ${email}`
29
+ );
30
+ if (existing.rows.length > 0) {
31
+ throw new Error(`User with email ${email} already exists`);
32
+ }
33
+ const [user] = await db.insert(users).values({
34
+ name,
35
+ preferences: {
36
+ email,
37
+ role,
38
+ status: "pending",
39
+ organizationId,
40
+ department,
41
+ manager,
42
+ ...metadata
43
+ }
44
+ }).returning();
45
+ if (organizationId) {
46
+ await db.insert(organizationMembers).values({
47
+ organizationId,
48
+ userId: user.id,
49
+ role
50
+ });
51
+ }
52
+ return mapToEnterpriseUser(user);
53
+ }
54
+ async function getUser(userId) {
55
+ const [user] = await db.select().from(users).where(eq(users.id, userId)).limit(1);
56
+ if (!user) return null;
57
+ return mapToEnterpriseUser(user);
58
+ }
59
+ async function getUserByEmail(email) {
60
+ const result = await db.execute(
61
+ sql`SELECT * FROM users WHERE preferences->>'email' = ${email} LIMIT 1`
62
+ );
63
+ if (result.rows.length === 0) return null;
64
+ return mapToEnterpriseUser(result.rows[0]);
65
+ }
66
+ async function updateUser(userId, updates) {
67
+ const user = await getUser(userId);
68
+ if (!user) {
69
+ throw new Error(`User ${userId} not found`);
70
+ }
71
+ const newPreferences = {
72
+ ...user.metadata,
73
+ ...updates.metadata || {}
74
+ };
75
+ if (updates.role) {
76
+ newPreferences.role = updates.role;
77
+ }
78
+ if (updates.status) {
79
+ newPreferences.status = updates.status;
80
+ }
81
+ if (updates.department) {
82
+ newPreferences.department = updates.department;
83
+ }
84
+ if (updates.manager) {
85
+ newPreferences.manager = updates.manager;
86
+ }
87
+ const [updated] = await db.update(users).set({
88
+ name: updates.name || user.name,
89
+ preferences: newPreferences,
90
+ updatedAt: /* @__PURE__ */ new Date()
91
+ }).where(eq(users.id, userId)).returning();
92
+ if (updates.role && user.organizationId) {
93
+ await db.update(organizationMembers).set({ role: updates.role }).where(
94
+ and(
95
+ eq(organizationMembers.userId, userId),
96
+ eq(organizationMembers.organizationId, user.organizationId)
97
+ )
98
+ );
99
+ }
100
+ return mapToEnterpriseUser(updated);
101
+ }
102
+ async function deleteUser(userId) {
103
+ await updateUser(userId, { status: "inactive" });
104
+ await db.delete(sessions).where(eq(sessions.userId, userId));
105
+ await db.update(apiKeys).set({ revokedAt: /* @__PURE__ */ new Date() }).where(eq(apiKeys.userId, userId));
106
+ }
107
+ async function suspendUser(userId, reason) {
108
+ await updateUser(userId, {
109
+ status: "suspended",
110
+ metadata: { suspendedReason: reason }
111
+ });
112
+ await db.delete(sessions).where(eq(sessions.userId, userId));
113
+ }
114
+ async function reactivateUser(userId) {
115
+ await updateUser(userId, {
116
+ status: "active",
117
+ metadata: { suspendedReason: null }
118
+ });
119
+ }
120
+ async function searchUsers(options) {
121
+ const {
122
+ organizationId,
123
+ role,
124
+ status,
125
+ department,
126
+ query,
127
+ limit = 50,
128
+ offset = 0
129
+ } = options;
130
+ let sqlQuery = sql`SELECT * FROM users WHERE 1=1`;
131
+ let countQuery = sql`SELECT COUNT(*) as total FROM users WHERE 1=1`;
132
+ if (organizationId) {
133
+ const memberIds = await db.select({ userId: organizationMembers.userId }).from(organizationMembers).where(eq(organizationMembers.organizationId, organizationId));
134
+ const userIds = memberIds.map((m) => m.userId);
135
+ if (userIds.length > 0) {
136
+ sqlQuery = sql`${sqlQuery} AND id = ANY(${userIds}::uuid[])`;
137
+ countQuery = sql`${countQuery} AND id = ANY(${userIds}::uuid[])`;
138
+ }
139
+ }
140
+ if (role) {
141
+ sqlQuery = sql`${sqlQuery} AND preferences->>'role' = ${role}`;
142
+ countQuery = sql`${countQuery} AND preferences->>'role' = ${role}`;
143
+ }
144
+ if (status) {
145
+ sqlQuery = sql`${sqlQuery} AND preferences->>'status' = ${status}`;
146
+ countQuery = sql`${countQuery} AND preferences->>'status' = ${status}`;
147
+ }
148
+ if (department) {
149
+ sqlQuery = sql`${sqlQuery} AND preferences->>'department' = ${department}`;
150
+ countQuery = sql`${countQuery} AND preferences->>'department' = ${department}`;
151
+ }
152
+ if (query) {
153
+ sqlQuery = sql`${sqlQuery} AND (name ILIKE ${"%" + query + "%"} OR preferences->>'email' ILIKE ${"%" + query + "%"})`;
154
+ countQuery = sql`${countQuery} AND (name ILIKE ${"%" + query + "%"} OR preferences->>'email' ILIKE ${"%" + query + "%"})`;
155
+ }
156
+ sqlQuery = sql`${sqlQuery} ORDER BY created_at DESC LIMIT ${limit} OFFSET ${offset}`;
157
+ const [results, countResult] = await Promise.all([
158
+ db.execute(sqlQuery),
159
+ db.execute(countQuery)
160
+ ]);
161
+ return {
162
+ users: results.rows.map((r) => mapToEnterpriseUser(r)),
163
+ total: parseInt(countResult.rows[0].total, 10)
164
+ };
165
+ }
166
+ async function getOrganizationUsers(organizationId, limit = 100) {
167
+ const members = await db.select({
168
+ userId: organizationMembers.userId,
169
+ role: organizationMembers.role
170
+ }).from(organizationMembers).where(eq(organizationMembers.organizationId, organizationId)).limit(limit);
171
+ const userIds = members.map((m) => m.userId);
172
+ if (userIds.length === 0) return [];
173
+ const orgUsers = await db.select().from(users).where(inArray(users.id, userIds));
174
+ return orgUsers.map((u) => mapToEnterpriseUser(u));
175
+ }
176
+ async function getDirectReports(managerId) {
177
+ const result = await db.execute(
178
+ sql`SELECT * FROM users WHERE preferences->>'manager' = ${managerId}`
179
+ );
180
+ return result.rows.map((r) => mapToEnterpriseUser(r));
181
+ }
182
+ async function bulkImportUsers(rows, organizationId) {
183
+ const result = {
184
+ success: 0,
185
+ failed: 0,
186
+ errors: []
187
+ };
188
+ for (let i = 0; i < rows.length; i++) {
189
+ const row = rows[i];
190
+ try {
191
+ await createUser({
192
+ email: row.email,
193
+ name: row.name,
194
+ role: row.role || "member",
195
+ department: row.department,
196
+ organizationId
197
+ });
198
+ result.success++;
199
+ } catch (error) {
200
+ result.failed++;
201
+ result.errors.push({
202
+ row: i + 1,
203
+ error: error instanceof Error ? error.message : "Unknown error"
204
+ });
205
+ }
206
+ }
207
+ return result;
208
+ }
209
+ async function bulkUpdateUsers(userIds, updates) {
210
+ let success = 0;
211
+ let failed = 0;
212
+ for (const userId of userIds) {
213
+ try {
214
+ await updateUser(userId, updates);
215
+ success++;
216
+ } catch {
217
+ failed++;
218
+ }
219
+ }
220
+ return { success, failed };
221
+ }
222
+ async function bulkDeactivateUsers(userIds) {
223
+ return bulkUpdateUsers(userIds, { status: "inactive" });
224
+ }
225
+ async function createInvitation(email, organizationId, role, invitedBy) {
226
+ const token = randomBytes(32).toString("hex");
227
+ const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3);
228
+ const [org] = await db.select().from(organizations).where(eq(organizations.id, organizationId)).limit(1);
229
+ if (!org) {
230
+ throw new Error("Organization not found");
231
+ }
232
+ const settings = org.settings || {};
233
+ const invitations = settings.invitations || [];
234
+ const invitation = {
235
+ id: randomBytes(16).toString("hex"),
236
+ email,
237
+ organizationId,
238
+ role,
239
+ invitedBy,
240
+ token: createHash("sha256").update(token).digest("hex"),
241
+ expiresAt
242
+ };
243
+ invitations.push(invitation);
244
+ await db.update(organizations).set({ settings: { ...settings, invitations } }).where(eq(organizations.id, organizationId));
245
+ return { ...invitation, token };
246
+ }
247
+ async function acceptInvitation(token, name) {
248
+ const tokenHash = createHash("sha256").update(token).digest("hex");
249
+ const orgs = await db.select().from(organizations);
250
+ for (const org of orgs) {
251
+ const settings = org.settings || {};
252
+ const invitations = settings.invitations || [];
253
+ const invitation = invitations.find(
254
+ (i) => i.token === tokenHash && !i.acceptedAt && new Date(i.expiresAt) > /* @__PURE__ */ new Date()
255
+ );
256
+ if (invitation) {
257
+ const user = await createUser({
258
+ email: invitation.email,
259
+ name,
260
+ role: invitation.role,
261
+ organizationId: invitation.organizationId
262
+ });
263
+ await updateUser(user.id, { status: "active" });
264
+ invitation.acceptedAt = /* @__PURE__ */ new Date();
265
+ await db.update(organizations).set({ settings: { ...settings, invitations } }).where(eq(organizations.id, org.id));
266
+ return user;
267
+ }
268
+ }
269
+ throw new Error("Invalid or expired invitation token");
270
+ }
271
+ async function revokeInvitation(organizationId, invitationId) {
272
+ const [org] = await db.select().from(organizations).where(eq(organizations.id, organizationId)).limit(1);
273
+ if (!org) {
274
+ throw new Error("Organization not found");
275
+ }
276
+ const settings = org.settings || {};
277
+ const invitations = settings.invitations || [];
278
+ const filteredInvitations = invitations.filter((i) => i.id !== invitationId);
279
+ await db.update(organizations).set({ settings: { ...settings, invitations: filteredInvitations } }).where(eq(organizations.id, organizationId));
280
+ }
281
+ async function getPendingInvitations(organizationId) {
282
+ const [org] = await db.select().from(organizations).where(eq(organizations.id, organizationId)).limit(1);
283
+ if (!org) return [];
284
+ const settings = org.settings || {};
285
+ const invitations = settings.invitations || [];
286
+ return invitations.filter(
287
+ (i) => !i.acceptedAt && new Date(i.expiresAt) > /* @__PURE__ */ new Date()
288
+ );
289
+ }
290
+ function mapToEnterpriseUser(dbUser) {
291
+ const prefs = dbUser.preferences || {};
292
+ return {
293
+ id: dbUser.id,
294
+ email: prefs.email || "",
295
+ name: dbUser.name || "",
296
+ role: prefs.role || "member",
297
+ status: prefs.status || "active",
298
+ organizationId: prefs.organizationId,
299
+ department: prefs.department,
300
+ manager: prefs.manager,
301
+ metadata: {
302
+ timezone: prefs.timezone,
303
+ language: prefs.language,
304
+ avatar: prefs.avatar,
305
+ phoneNumber: prefs.phoneNumber,
306
+ title: prefs.title,
307
+ employeeId: prefs.employeeId,
308
+ costCenter: prefs.costCenter,
309
+ tags: prefs.tags
310
+ },
311
+ createdAt: new Date(dbUser.created_at || dbUser.createdAt),
312
+ updatedAt: new Date(dbUser.updated_at || dbUser.updatedAt),
313
+ lastLoginAt: prefs.lastLoginAt ? new Date(prefs.lastLoginAt) : void 0
314
+ };
315
+ }
316
+ async function getUserActivitySummary(userId, days = 30) {
317
+ const since = new Date(Date.now() - days * 24 * 60 * 60 * 1e3);
318
+ const sessionsResult = await db.execute(
319
+ sql`SELECT COUNT(*) as count, MAX(last_active_at) as last_active
320
+ FROM sessions
321
+ WHERE user_id = ${userId}
322
+ AND created_at >= ${since}`
323
+ );
324
+ const apiResult = await db.execute(
325
+ sql`SELECT COUNT(*) as count
326
+ FROM api_keys
327
+ WHERE user_id = ${userId}
328
+ AND last_used_at >= ${since}`
329
+ );
330
+ const sessionData = sessionsResult.rows[0];
331
+ return {
332
+ totalSessions: parseInt(sessionData?.count || "0", 10),
333
+ totalApiCalls: parseInt(apiResult.rows[0]?.count || "0", 10),
334
+ avgSessionDuration: 0,
335
+ // Would need session duration tracking
336
+ lastActive: sessionData?.last_active ? new Date(sessionData.last_active) : null
337
+ };
338
+ }
339
+ async function getOrganizationUserStats(organizationId) {
340
+ const members = await getOrganizationUsers(organizationId, 1e4);
341
+ const stats = {
342
+ totalUsers: members.length,
343
+ activeUsers: 0,
344
+ pendingUsers: 0,
345
+ suspendedUsers: 0,
346
+ byRole: {},
347
+ byDepartment: {}
348
+ };
349
+ for (const user of members) {
350
+ switch (user.status) {
351
+ case "active":
352
+ stats.activeUsers++;
353
+ break;
354
+ case "pending":
355
+ stats.pendingUsers++;
356
+ break;
357
+ case "suspended":
358
+ stats.suspendedUsers++;
359
+ break;
360
+ }
361
+ stats.byRole[user.role] = (stats.byRole[user.role] || 0) + 1;
362
+ if (user.department) {
363
+ stats.byDepartment[user.department] = (stats.byDepartment[user.department] || 0) + 1;
364
+ }
365
+ }
366
+ return stats;
367
+ }
368
+ var multi_user_default = {
369
+ createUser,
370
+ getUser,
371
+ getUserByEmail,
372
+ updateUser,
373
+ deleteUser,
374
+ suspendUser,
375
+ reactivateUser,
376
+ searchUsers,
377
+ getOrganizationUsers,
378
+ getDirectReports,
379
+ bulkImportUsers,
380
+ bulkUpdateUsers,
381
+ bulkDeactivateUsers,
382
+ createInvitation,
383
+ acceptInvitation,
384
+ revokeInvitation,
385
+ getPendingInvitations,
386
+ getUserActivitySummary,
387
+ getOrganizationUserStats
388
+ };
389
+ export {
390
+ acceptInvitation,
391
+ bulkDeactivateUsers,
392
+ bulkImportUsers,
393
+ bulkUpdateUsers,
394
+ createInvitation,
395
+ createUser,
396
+ multi_user_default as default,
397
+ deleteUser,
398
+ getDirectReports,
399
+ getOrganizationUserStats,
400
+ getOrganizationUsers,
401
+ getPendingInvitations,
402
+ getUser,
403
+ getUserActivitySummary,
404
+ getUserByEmail,
405
+ reactivateUser,
406
+ revokeInvitation,
407
+ searchUsers,
408
+ suspendUser,
409
+ updateUser
410
+ };
411
+ //# sourceMappingURL=multi-user-XAEMB244.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/enterprise/multi-user.ts"],"sourcesContent":["import { db } from \"../../db\";\nimport {\n users,\n organizations,\n organizationMembers,\n sessions,\n apiKeys,\n} from \"../../db/schema\";\nimport { eq, and, sql, desc, inArray } from \"drizzle-orm\";\nimport { randomBytes, createHash } from \"crypto\";\n\n// ============================================\n// TYPES\n// ============================================\n\n// Use same role type as database schema\nexport type UserRole = \"owner\" | \"admin\" | \"member\" | \"viewer\";\nexport type UserStatus = \"active\" | \"inactive\" | \"suspended\" | \"pending\";\n\nexport interface EnterpriseUser {\n id: string;\n email: string;\n name: string;\n role: UserRole;\n status: UserStatus;\n organizationId?: string;\n department?: string;\n manager?: string;\n metadata: UserMetadata;\n createdAt: Date;\n updatedAt: Date;\n lastLoginAt?: Date;\n}\n\nexport interface UserMetadata {\n timezone?: string;\n language?: string;\n avatar?: string;\n phoneNumber?: string;\n title?: string;\n employeeId?: string;\n costCenter?: string;\n tags?: string[];\n}\n\nexport interface CreateUserOptions {\n email: string;\n name: string;\n role?: UserRole;\n organizationId?: string;\n department?: string;\n manager?: string;\n metadata?: UserMetadata;\n sendInvite?: boolean;\n}\n\nexport interface UpdateUserOptions {\n name?: string;\n role?: UserRole;\n status?: UserStatus;\n department?: string;\n manager?: string;\n metadata?: Partial<UserMetadata>;\n}\n\nexport interface UserSearchOptions {\n organizationId?: string;\n role?: UserRole;\n status?: UserStatus;\n department?: string;\n query?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface BulkImportResult {\n success: number;\n failed: number;\n errors: Array<{ row: number; error: string }>;\n}\n\nexport interface UserInvitation {\n id: string;\n email: string;\n organizationId: string;\n role: UserRole;\n invitedBy: string;\n token: string;\n expiresAt: Date;\n acceptedAt?: Date;\n}\n\n// ============================================\n// USER MANAGEMENT\n// ============================================\n\n/**\n * Create a new enterprise user\n */\nexport async function createUser(options: CreateUserOptions): Promise<EnterpriseUser> {\n const {\n email,\n name,\n role = \"member\",\n organizationId,\n department,\n manager,\n metadata = {},\n } = options;\n\n // Check if user already exists\n const existing = await db.execute(\n sql`SELECT id FROM users WHERE preferences->>'email' = ${email}`\n ) as unknown as { rows: unknown[] };\n\n if (existing.rows.length > 0) {\n throw new Error(`User with email ${email} already exists`);\n }\n\n const [user] = await db\n .insert(users)\n .values({\n name,\n preferences: {\n email,\n role,\n status: \"pending\" as UserStatus,\n organizationId,\n department,\n manager,\n ...metadata,\n } as any,\n })\n .returning();\n\n // If organization specified, add as member\n if (organizationId) {\n await db.insert(organizationMembers).values({\n organizationId,\n userId: user.id,\n role,\n });\n }\n\n return mapToEnterpriseUser(user);\n}\n\n/**\n * Get user by ID\n */\nexport async function getUser(userId: string): Promise<EnterpriseUser | null> {\n const [user] = await db.select().from(users).where(eq(users.id, userId)).limit(1);\n\n if (!user) return null;\n\n return mapToEnterpriseUser(user);\n}\n\n/**\n * Get user by email\n */\nexport async function getUserByEmail(email: string): Promise<EnterpriseUser | null> {\n const result = await db.execute(\n sql`SELECT * FROM users WHERE preferences->>'email' = ${email} LIMIT 1`\n ) as unknown as { rows: unknown[] };\n\n if (result.rows.length === 0) return null;\n\n return mapToEnterpriseUser(result.rows[0] as any);\n}\n\n/**\n * Update user details\n */\nexport async function updateUser(\n userId: string,\n updates: UpdateUserOptions\n): Promise<EnterpriseUser> {\n const user = await getUser(userId);\n if (!user) {\n throw new Error(`User ${userId} not found`);\n }\n\n const newPreferences = {\n ...user.metadata,\n ...(updates.metadata || {}),\n };\n\n if (updates.role) {\n (newPreferences as any).role = updates.role;\n }\n if (updates.status) {\n (newPreferences as any).status = updates.status;\n }\n if (updates.department) {\n (newPreferences as any).department = updates.department;\n }\n if (updates.manager) {\n (newPreferences as any).manager = updates.manager;\n }\n\n const [updated] = await db\n .update(users)\n .set({\n name: updates.name || user.name,\n preferences: newPreferences as any,\n updatedAt: new Date(),\n })\n .where(eq(users.id, userId))\n .returning();\n\n // Update organization membership if role changed\n if (updates.role && user.organizationId) {\n await db\n .update(organizationMembers)\n .set({ role: updates.role })\n .where(\n and(\n eq(organizationMembers.userId, userId),\n eq(organizationMembers.organizationId, user.organizationId)\n )\n );\n }\n\n return mapToEnterpriseUser(updated);\n}\n\n/**\n * Delete user (soft delete by setting status to inactive)\n */\nexport async function deleteUser(userId: string): Promise<void> {\n await updateUser(userId, { status: \"inactive\" });\n\n // Invalidate all sessions\n await db.delete(sessions).where(eq(sessions.userId, userId));\n\n // Revoke all API keys\n await db\n .update(apiKeys)\n .set({ revokedAt: new Date() })\n .where(eq(apiKeys.userId, userId));\n}\n\n/**\n * Suspend user\n */\nexport async function suspendUser(userId: string, reason?: string): Promise<void> {\n await updateUser(userId, {\n status: \"suspended\",\n metadata: { suspendedReason: reason } as any,\n });\n\n // Invalidate all sessions\n await db.delete(sessions).where(eq(sessions.userId, userId));\n}\n\n/**\n * Reactivate suspended user\n */\nexport async function reactivateUser(userId: string): Promise<void> {\n await updateUser(userId, {\n status: \"active\",\n metadata: { suspendedReason: null } as any,\n });\n}\n\n// ============================================\n// USER SEARCH & LISTING\n// ============================================\n\n/**\n * Search users with filters\n */\nexport async function searchUsers(\n options: UserSearchOptions\n): Promise<{ users: EnterpriseUser[]; total: number }> {\n const {\n organizationId,\n role,\n status,\n department,\n query,\n limit = 50,\n offset = 0,\n } = options;\n\n let sqlQuery = sql`SELECT * FROM users WHERE 1=1`;\n let countQuery = sql`SELECT COUNT(*) as total FROM users WHERE 1=1`;\n\n if (organizationId) {\n const memberIds = await db\n .select({ userId: organizationMembers.userId })\n .from(organizationMembers)\n .where(eq(organizationMembers.organizationId, organizationId));\n\n const userIds = memberIds.map((m) => m.userId);\n if (userIds.length > 0) {\n sqlQuery = sql`${sqlQuery} AND id = ANY(${userIds}::uuid[])`;\n countQuery = sql`${countQuery} AND id = ANY(${userIds}::uuid[])`;\n }\n }\n\n if (role) {\n sqlQuery = sql`${sqlQuery} AND preferences->>'role' = ${role}`;\n countQuery = sql`${countQuery} AND preferences->>'role' = ${role}`;\n }\n\n if (status) {\n sqlQuery = sql`${sqlQuery} AND preferences->>'status' = ${status}`;\n countQuery = sql`${countQuery} AND preferences->>'status' = ${status}`;\n }\n\n if (department) {\n sqlQuery = sql`${sqlQuery} AND preferences->>'department' = ${department}`;\n countQuery = sql`${countQuery} AND preferences->>'department' = ${department}`;\n }\n\n if (query) {\n sqlQuery = sql`${sqlQuery} AND (name ILIKE ${\"%\" + query + \"%\"} OR preferences->>'email' ILIKE ${\"%\" + query + \"%\"})`;\n countQuery = sql`${countQuery} AND (name ILIKE ${\"%\" + query + \"%\"} OR preferences->>'email' ILIKE ${\"%\" + query + \"%\"})`;\n }\n\n sqlQuery = sql`${sqlQuery} ORDER BY created_at DESC LIMIT ${limit} OFFSET ${offset}`;\n\n const [results, countResult] = await Promise.all([\n db.execute(sqlQuery) as unknown as Promise<{ rows: unknown[] }>,\n db.execute(countQuery) as unknown as Promise<{ rows: unknown[] }>,\n ]);\n\n return {\n users: results.rows.map((r: any) => mapToEnterpriseUser(r)),\n total: parseInt((countResult.rows[0] as any).total, 10),\n };\n}\n\n/**\n * Get users in an organization\n */\nexport async function getOrganizationUsers(\n organizationId: string,\n limit = 100\n): Promise<EnterpriseUser[]> {\n const members = await db\n .select({\n userId: organizationMembers.userId,\n role: organizationMembers.role,\n })\n .from(organizationMembers)\n .where(eq(organizationMembers.organizationId, organizationId))\n .limit(limit);\n\n const userIds = members.map((m) => m.userId);\n if (userIds.length === 0) return [];\n\n const orgUsers = await db\n .select()\n .from(users)\n .where(inArray(users.id, userIds));\n\n return orgUsers.map((u) => mapToEnterpriseUser(u));\n}\n\n/**\n * Get user's direct reports (for managers)\n */\nexport async function getDirectReports(managerId: string): Promise<EnterpriseUser[]> {\n const result = await db.execute(\n sql`SELECT * FROM users WHERE preferences->>'manager' = ${managerId}`\n ) as unknown as { rows: unknown[] };\n\n return result.rows.map((r: any) => mapToEnterpriseUser(r));\n}\n\n// ============================================\n// BULK OPERATIONS\n// ============================================\n\n/**\n * Bulk import users from CSV data\n */\nexport async function bulkImportUsers(\n rows: Array<{\n email: string;\n name: string;\n role?: string;\n department?: string;\n }>,\n organizationId: string\n): Promise<BulkImportResult> {\n const result: BulkImportResult = {\n success: 0,\n failed: 0,\n errors: [],\n };\n\n for (let i = 0; i < rows.length; i++) {\n const row = rows[i];\n try {\n await createUser({\n email: row.email,\n name: row.name,\n role: (row.role as UserRole) || \"member\",\n department: row.department,\n organizationId,\n });\n result.success++;\n } catch (error) {\n result.failed++;\n result.errors.push({\n row: i + 1,\n error: error instanceof Error ? error.message : \"Unknown error\",\n });\n }\n }\n\n return result;\n}\n\n/**\n * Bulk update users\n */\nexport async function bulkUpdateUsers(\n userIds: string[],\n updates: UpdateUserOptions\n): Promise<{ success: number; failed: number }> {\n let success = 0;\n let failed = 0;\n\n for (const userId of userIds) {\n try {\n await updateUser(userId, updates);\n success++;\n } catch {\n failed++;\n }\n }\n\n return { success, failed };\n}\n\n/**\n * Bulk deactivate users\n */\nexport async function bulkDeactivateUsers(\n userIds: string[]\n): Promise<{ success: number; failed: number }> {\n return bulkUpdateUsers(userIds, { status: \"inactive\" });\n}\n\n// ============================================\n// USER INVITATIONS\n// ============================================\n\n/**\n * Create user invitation\n */\nexport async function createInvitation(\n email: string,\n organizationId: string,\n role: UserRole,\n invitedBy: string\n): Promise<UserInvitation> {\n const token = randomBytes(32).toString(\"hex\");\n const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 days\n\n // Store invitation in a table or return for sending\n // For simplicity, we'll store it in the organization's settings\n const [org] = await db\n .select()\n .from(organizations)\n .where(eq(organizations.id, organizationId))\n .limit(1);\n\n if (!org) {\n throw new Error(\"Organization not found\");\n }\n\n const settings = (org.settings as any) || {};\n const invitations = settings.invitations || [];\n\n const invitation: UserInvitation = {\n id: randomBytes(16).toString(\"hex\"),\n email,\n organizationId,\n role,\n invitedBy,\n token: createHash(\"sha256\").update(token).digest(\"hex\"),\n expiresAt,\n };\n\n invitations.push(invitation);\n\n await db\n .update(organizations)\n .set({ settings: { ...settings, invitations } })\n .where(eq(organizations.id, organizationId));\n\n return { ...invitation, token }; // Return raw token for email\n}\n\n/**\n * Accept invitation\n */\nexport async function acceptInvitation(\n token: string,\n name: string\n): Promise<EnterpriseUser> {\n const tokenHash = createHash(\"sha256\").update(token).digest(\"hex\");\n\n // Find the invitation\n const orgs = await db.select().from(organizations);\n\n for (const org of orgs) {\n const settings = (org.settings as any) || {};\n const invitations: UserInvitation[] = settings.invitations || [];\n\n const invitation = invitations.find(\n (i) => i.token === tokenHash && !i.acceptedAt && new Date(i.expiresAt) > new Date()\n );\n\n if (invitation) {\n // Create the user\n const user = await createUser({\n email: invitation.email,\n name,\n role: invitation.role,\n organizationId: invitation.organizationId,\n });\n\n // Update user status to active\n await updateUser(user.id, { status: \"active\" });\n\n // Mark invitation as accepted\n invitation.acceptedAt = new Date();\n await db\n .update(organizations)\n .set({ settings: { ...settings, invitations } })\n .where(eq(organizations.id, org.id));\n\n return user;\n }\n }\n\n throw new Error(\"Invalid or expired invitation token\");\n}\n\n/**\n * Revoke invitation\n */\nexport async function revokeInvitation(\n organizationId: string,\n invitationId: string\n): Promise<void> {\n const [org] = await db\n .select()\n .from(organizations)\n .where(eq(organizations.id, organizationId))\n .limit(1);\n\n if (!org) {\n throw new Error(\"Organization not found\");\n }\n\n const settings = (org.settings as any) || {};\n const invitations: UserInvitation[] = settings.invitations || [];\n\n const filteredInvitations = invitations.filter((i) => i.id !== invitationId);\n\n await db\n .update(organizations)\n .set({ settings: { ...settings, invitations: filteredInvitations } })\n .where(eq(organizations.id, organizationId));\n}\n\n/**\n * Get pending invitations for organization\n */\nexport async function getPendingInvitations(\n organizationId: string\n): Promise<UserInvitation[]> {\n const [org] = await db\n .select()\n .from(organizations)\n .where(eq(organizations.id, organizationId))\n .limit(1);\n\n if (!org) return [];\n\n const settings = (org.settings as any) || {};\n const invitations: UserInvitation[] = settings.invitations || [];\n\n return invitations.filter(\n (i) => !i.acceptedAt && new Date(i.expiresAt) > new Date()\n );\n}\n\n// ============================================\n// HELPERS\n// ============================================\n\nfunction mapToEnterpriseUser(dbUser: any): EnterpriseUser {\n const prefs = dbUser.preferences || {};\n\n return {\n id: dbUser.id,\n email: prefs.email || \"\",\n name: dbUser.name || \"\",\n role: prefs.role || \"member\",\n status: prefs.status || \"active\",\n organizationId: prefs.organizationId,\n department: prefs.department,\n manager: prefs.manager,\n metadata: {\n timezone: prefs.timezone,\n language: prefs.language,\n avatar: prefs.avatar,\n phoneNumber: prefs.phoneNumber,\n title: prefs.title,\n employeeId: prefs.employeeId,\n costCenter: prefs.costCenter,\n tags: prefs.tags,\n },\n createdAt: new Date(dbUser.created_at || dbUser.createdAt),\n updatedAt: new Date(dbUser.updated_at || dbUser.updatedAt),\n lastLoginAt: prefs.lastLoginAt ? new Date(prefs.lastLoginAt) : undefined,\n };\n}\n\n// ============================================\n// USER ANALYTICS\n// ============================================\n\n/**\n * Get user activity summary\n */\nexport async function getUserActivitySummary(\n userId: string,\n days = 30\n): Promise<{\n totalSessions: number;\n totalApiCalls: number;\n avgSessionDuration: number;\n lastActive: Date | null;\n}> {\n const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n\n const sessionsResult = await db.execute(\n sql`SELECT COUNT(*) as count, MAX(last_active_at) as last_active\n FROM sessions\n WHERE user_id = ${userId}\n AND created_at >= ${since}`\n ) as unknown as { rows: unknown[] };\n\n const apiResult = await db.execute(\n sql`SELECT COUNT(*) as count\n FROM api_keys\n WHERE user_id = ${userId}\n AND last_used_at >= ${since}`\n ) as unknown as { rows: unknown[] };\n\n const sessionData = sessionsResult.rows[0] as any;\n\n return {\n totalSessions: parseInt(sessionData?.count || \"0\", 10),\n totalApiCalls: parseInt((apiResult.rows[0] as any)?.count || \"0\", 10),\n avgSessionDuration: 0, // Would need session duration tracking\n lastActive: sessionData?.last_active ? new Date(sessionData.last_active) : null,\n };\n}\n\n/**\n * Get organization user statistics\n */\nexport async function getOrganizationUserStats(organizationId: string): Promise<{\n totalUsers: number;\n activeUsers: number;\n pendingUsers: number;\n suspendedUsers: number;\n byRole: Record<UserRole, number>;\n byDepartment: Record<string, number>;\n}> {\n const members = await getOrganizationUsers(organizationId, 10000);\n\n const stats = {\n totalUsers: members.length,\n activeUsers: 0,\n pendingUsers: 0,\n suspendedUsers: 0,\n byRole: {} as Record<UserRole, number>,\n byDepartment: {} as Record<string, number>,\n };\n\n for (const user of members) {\n // Status counts\n switch (user.status) {\n case \"active\":\n stats.activeUsers++;\n break;\n case \"pending\":\n stats.pendingUsers++;\n break;\n case \"suspended\":\n stats.suspendedUsers++;\n break;\n }\n\n // Role counts\n stats.byRole[user.role] = (stats.byRole[user.role] || 0) + 1;\n\n // Department counts\n if (user.department) {\n stats.byDepartment[user.department] =\n (stats.byDepartment[user.department] || 0) + 1;\n }\n }\n\n return stats;\n}\n\nexport default {\n createUser,\n getUser,\n getUserByEmail,\n updateUser,\n deleteUser,\n suspendUser,\n reactivateUser,\n searchUsers,\n getOrganizationUsers,\n getDirectReports,\n bulkImportUsers,\n bulkUpdateUsers,\n bulkDeactivateUsers,\n createInvitation,\n acceptInvitation,\n revokeInvitation,\n getPendingInvitations,\n getUserActivitySummary,\n getOrganizationUserStats,\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,34 @@
1
+ import {
2
+ REFRESH_BUFFER_MS,
3
+ buildAuthorizeUrl,
4
+ cleanupExpiredStates,
5
+ consumeState,
6
+ exchangeCodeForTokens,
7
+ generateCodeChallenge,
8
+ generateCodeVerifier,
9
+ getM365Config,
10
+ isM365Configured,
11
+ persistState,
12
+ refreshTokens,
13
+ shouldRefresh
14
+ } from "./chunk-3AWAWRWB.js";
15
+ import "./chunk-7BNFELEK.js";
16
+ import "./chunk-5BTVJR7R.js";
17
+ import "./chunk-4KIHDIXZ.js";
18
+ import "./chunk-ZIBRVA3Y.js";
19
+ import "./chunk-UP2VWCW5.js";
20
+ export {
21
+ REFRESH_BUFFER_MS,
22
+ buildAuthorizeUrl,
23
+ cleanupExpiredStates,
24
+ consumeState,
25
+ exchangeCodeForTokens,
26
+ generateCodeChallenge,
27
+ generateCodeVerifier,
28
+ getM365Config,
29
+ isM365Configured,
30
+ persistState,
31
+ refreshTokens,
32
+ shouldRefresh
33
+ };
34
+ //# sourceMappingURL=oauth-UPJYFOVU.js.map
@@ -6,10 +6,12 @@ import {
6
6
  ocrWithVision,
7
7
  ocr_default,
8
8
  performOCR
9
- } from "./chunk-EVE7MIIY.js";
9
+ } from "./chunk-4WH6MFEW.js";
10
+ import "./chunk-GW6V4D43.js";
10
11
  import "./chunk-CQ4JURG7.js";
11
- import "./chunk-ZLZKF2PM.js";
12
- import "./chunk-PLDDJCW6.js";
12
+ import "./chunk-4KIHDIXZ.js";
13
+ import "./chunk-35WYTA3C.js";
14
+ import "./chunk-UP2VWCW5.js";
13
15
  export {
14
16
  ocr_default as default,
15
17
  extractStructuredData,
@@ -19,4 +21,4 @@ export {
19
21
  ocrWithVision,
20
22
  performOCR
21
23
  };
22
- //# sourceMappingURL=ocr-AC7NPX33.js.map
24
+ //# sourceMappingURL=ocr-UONKTQU7.js.map