opensentinel 3.6.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.
- package/README.md +12 -0
- package/dist/{agent-manager-7N7REQZQ.js → agent-manager-JZ4IM7XI.js} +8 -8
- package/dist/{agent-processor-I23VWQY3.js → agent-processor-DDDHC2SO.js} +22 -21
- package/dist/{agent-processor-I23VWQY3.js.map → agent-processor-DDDHC2SO.js.map} +1 -1
- package/dist/{alerting-4I37GG4U.js → alerting-LK7VVYTX.js} +4 -4
- package/dist/alerting-LK7VVYTX.js.map +1 -0
- package/dist/analyzer-OTWE3ARE.js +22 -0
- package/dist/{archiver-XLRIIXPY.js → archiver-FPGKRP6P.js} +16 -85
- package/dist/archiver-FPGKRP6P.js.map +1 -0
- package/dist/{audit-logger-AU3TMWKI.js → audit-logger-CI4WZQPD.js} +5 -5
- package/dist/bot-VDHBGUVI.js +47 -0
- package/dist/{brain-SLA474EU.js → brain-6QTXN4QP.js} +18 -17
- package/dist/{chunk-AR34B6XR.js → chunk-2I5QHYG6.js} +3 -3
- package/dist/chunk-2I5QHYG6.js.map +1 -0
- package/dist/chunk-3AWAWRWB.js +143 -0
- package/dist/chunk-3AWAWRWB.js.map +1 -0
- package/dist/{chunk-PUNIMPMY.js → chunk-4KIHDIXZ.js} +13 -2
- package/dist/chunk-4KIHDIXZ.js.map +1 -0
- package/dist/{chunk-GUKKW7JI.js → chunk-4WH6MFEW.js} +2 -2
- package/dist/chunk-4WH6MFEW.js.map +1 -0
- package/dist/{chunk-M7YLQHFP.js → chunk-56UJS2LA.js} +6 -6
- package/dist/{chunk-S4NJJS5C.js → chunk-5BTVJR7R.js} +3 -3
- package/dist/{chunk-HKOPRRDJ.js → chunk-5JJTLWOR.js} +3 -3
- package/dist/chunk-5JJTLWOR.js.map +1 -0
- package/dist/chunk-66SAOZPU.js +236 -0
- package/dist/chunk-66SAOZPU.js.map +1 -0
- package/dist/chunk-6HGMRR4J.js +113 -0
- package/dist/chunk-6HGMRR4J.js.map +1 -0
- package/dist/{chunk-BMOUYXLX.js → chunk-6ZNCY2GI.js} +5 -5
- package/dist/chunk-7BNFELEK.js +31 -0
- package/dist/chunk-7BNFELEK.js.map +1 -0
- package/dist/{chunk-KABG5PG3.js → chunk-BBN4VCNK.js} +4 -4
- package/dist/chunk-BBN4VCNK.js.map +1 -0
- package/dist/{chunk-4YJRBMMA.js → chunk-BNZHWAZC.js} +2 -2
- package/dist/{chunk-TAAZB5KN.js → chunk-CWT6CAE5.js} +2 -2
- package/dist/{chunk-UWUIJTT4.js → chunk-CZTMGHUC.js} +1 -1
- package/dist/chunk-CZTMGHUC.js.map +1 -0
- package/dist/chunk-DTISLIMB.js +89 -0
- package/dist/chunk-DTISLIMB.js.map +1 -0
- package/dist/{chunk-VKMFUIVA.js → chunk-GBVJTRXS.js} +2 -2
- package/dist/{chunk-MFK34XSY.js → chunk-GJETKBOY.js} +15 -15
- package/dist/chunk-GJETKBOY.js.map +1 -0
- package/dist/{chunk-HTF2GIQC.js → chunk-GW6V4D43.js} +2 -2
- package/dist/chunk-GW6V4D43.js.map +1 -0
- package/dist/{chunk-2RGPWU77.js → chunk-HJSEEFO3.js} +2 -2
- package/dist/{chunk-JOA5A3G3.js → chunk-HQZQFEAX.js} +5 -5
- package/dist/{chunk-45YXODSB.js → chunk-J4JW73TT.js} +2 -2
- package/dist/{chunk-KT7NLIXP.js → chunk-JHYYFPKX.js} +2 -2
- package/dist/{chunk-XMCVRVTF.js → chunk-P64EV4YY.js} +1 -1
- package/dist/chunk-P64EV4YY.js.map +1 -0
- package/dist/chunk-PBOCSGNL.js +84 -0
- package/dist/chunk-PBOCSGNL.js.map +1 -0
- package/dist/{chunk-H3BOLSTS.js → chunk-PD3CTDO6.js} +2 -2
- package/dist/{chunk-6UZPE35A.js → chunk-QPY3WRVM.js} +10 -87
- package/dist/chunk-QPY3WRVM.js.map +1 -0
- package/dist/{chunk-AD6YEH6U.js → chunk-S2EOIVF4.js} +590 -91
- package/dist/chunk-S2EOIVF4.js.map +1 -0
- package/dist/chunk-SDLOMKCW.js +213 -0
- package/dist/chunk-SDLOMKCW.js.map +1 -0
- package/dist/{chunk-7MZN73J2.js → chunk-TKBVW7ZJ.js} +4 -4
- package/dist/{chunk-A24GPVLY.js → chunk-V3OKHQUX.js} +5 -5
- package/dist/{chunk-NMSHVO5O.js → chunk-WMDVOWN6.js} +4 -4
- package/dist/{chunk-643M3AP5.js → chunk-WMFYI7XC.js} +7 -7
- package/dist/{chunk-6LTLIYAQ.js → chunk-YEDEAX6Y.js} +3 -3
- package/dist/{chunk-NYVBXUGD.js → chunk-ZIBRVA3Y.js} +60 -1
- package/dist/chunk-ZIBRVA3Y.js.map +1 -0
- package/dist/{chunk-6JY4HNUH.js → chunk-ZMML6T63.js} +361 -24
- package/dist/chunk-ZMML6T63.js.map +1 -0
- package/dist/{chunk-FFV2SXFD.js → chunk-ZVHG4KF2.js} +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/start.js +2 -2
- package/dist/commands/status.js +1 -1
- package/dist/commands/stop.js +1 -1
- package/dist/commands/utils.js +1 -1
- package/dist/{cost-tracker-EMOIOYH7.js → cost-tracker-KZQSTSE2.js} +2 -2
- package/dist/{db-LRIOKQBO.js → db-I7MNG6CL.js} +10 -4
- package/dist/{discord-NKR3X4AV.js → discord-6UQHCN27.js} +24 -23
- package/dist/{documents-EYIYLZK2.js → documents-PFHSK7SZ.js} +19 -19
- package/dist/{email-EAQNULVD.js → email-6OIN4SYL.js} +22 -21
- package/dist/email-6OIN4SYL.js.map +1 -0
- package/dist/{enhanced-retrieval-OGHT6TS5.js → enhanced-retrieval-JWX2HWU4.js} +7 -6
- package/dist/{enhanced-retrieval-OGHT6TS5.js.map → enhanced-retrieval-JWX2HWU4.js.map} +1 -1
- package/dist/enrichment-pipeline-7FE5R5ZI.js +14 -0
- package/dist/{entity-resolution-4X4JU43O.js → entity-resolution-7Z6STVXX.js} +5 -5
- package/dist/{env-CHOFICED.js → env-GN5VHI43.js} +2 -2
- package/dist/{error-tracker-SVQSDQDW.js → error-tracker-64DEH3D7.js} +6 -6
- package/dist/{github-KGNILDWJ.js → github-DUWSXCNP.js} +4 -4
- package/dist/graph-client-NB475AK5.js +17 -0
- package/dist/{imessage-V2XNDDHT.js → imessage-DSGSGUZS.js} +19 -18
- package/dist/{inbox-summarizer-DKKRYXDR.js → inbox-summarizer-F2KAU72V.js} +19 -18
- package/dist/{incident-response-ZTIKUWEO.js → incident-response-E3UGMX5G.js} +5 -5
- package/dist/incident-response-E3UGMX5G.js.map +1 -0
- package/dist/{knowledge-base-J7PJ7MZ3.js → knowledge-base-5SMMOGQJ.js} +5 -5
- package/dist/lib.d.ts +21 -0
- package/dist/lib.js +64 -57
- package/dist/lib.js.map +1 -1
- package/dist/{matrix-XHTR53VQ.js → matrix-WYGEOZL5.js} +18 -17
- package/dist/{matrix-XHTR53VQ.js.map → matrix-WYGEOZL5.js.map} +1 -1
- package/dist/{mcp-3C2TN67D.js → mcp-DJ2QDA6A.js} +2 -2
- package/dist/{metrics-VJDWQWU7.js → metrics-BH3ZLGEV.js} +5 -5
- package/dist/{multi-user-S56GUD6L.js → multi-user-XAEMB244.js} +4 -4
- package/dist/oauth-UPJYFOVU.js +34 -0
- package/dist/{ocr-LGUIPKVZ.js → ocr-UONKTQU7.js} +4 -4
- package/dist/{presentations-HXTAMGHT.js → presentations-UOET2FVZ.js} +2 -2
- package/dist/{providers-H6YIC3MG.js → providers-2YQ6E3IF.js} +3 -3
- package/dist/{scheduler-CA5UNHZV.js → scheduler-6PLLAQI7.js} +21 -20
- package/dist/{schema-ALJ67YVG.js → schema-ETY7L2VA.js} +8 -2
- package/dist/sharepoint-V5P4Q62L.js +30 -0
- package/dist/{signal-X7IQJGRQ.js → signal-7D5EPGVL.js} +19 -18
- package/dist/{slack-P2LFUJUQ.js → slack-KSS6YK5Z.js} +23 -22
- package/dist/slack-KSS6YK5Z.js.map +1 -0
- package/dist/{sms-4VME2HUL.js → sms-CSUCC7HL.js} +3 -3
- package/dist/sms-CSUCC7HL.js.map +1 -0
- package/dist/{src-S5KX4YEV.js → src-GO7GGW7O.js} +48 -41
- package/dist/{src-S5KX4YEV.js.map → src-GO7GGW7O.js.map} +1 -1
- package/dist/token-store-SEWRX6RE.js +20 -0
- package/dist/token-store-SEWRX6RE.js.map +1 -0
- package/dist/{tools-FGPN522P.js → tools-PJZ6RI4P.js} +18 -17
- package/dist/tools-PJZ6RI4P.js.map +1 -0
- package/dist/{whatsapp-KRPQ4YUX.js → whatsapp-DWXK25V2.js} +19 -18
- package/dist/whatsapp-DWXK25V2.js.map +1 -0
- package/dist/{word-document-D6N2C47N.js → word-document-AV3YB4L2.js} +2 -2
- package/dist/{workflow-store-ZYAYE5P6.js → workflow-store-5Y56GUP7.js} +4 -4
- package/drizzle/0002_mushy_master_mold.sql +139 -139
- package/drizzle/0003_overjoyed_rhodey.sql +46 -0
- package/drizzle/meta/0002_snapshot.json +3636 -3636
- package/drizzle/meta/0003_snapshot.json +3946 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +110 -110
- package/dist/alerting-4I37GG4U.js.map +0 -1
- package/dist/archiver-XLRIIXPY.js.map +0 -1
- package/dist/bot-MU2TJQ3Y.js +0 -46
- package/dist/chunk-6JY4HNUH.js.map +0 -1
- package/dist/chunk-6UZPE35A.js.map +0 -1
- package/dist/chunk-AD6YEH6U.js.map +0 -1
- package/dist/chunk-AR34B6XR.js.map +0 -1
- package/dist/chunk-GUKKW7JI.js.map +0 -1
- package/dist/chunk-HKOPRRDJ.js.map +0 -1
- package/dist/chunk-HTF2GIQC.js.map +0 -1
- package/dist/chunk-KABG5PG3.js.map +0 -1
- package/dist/chunk-MFK34XSY.js.map +0 -1
- package/dist/chunk-NYVBXUGD.js.map +0 -1
- package/dist/chunk-PUNIMPMY.js.map +0 -1
- package/dist/chunk-UWUIJTT4.js.map +0 -1
- package/dist/chunk-XMCVRVTF.js.map +0 -1
- package/dist/email-EAQNULVD.js.map +0 -1
- package/dist/enrichment-pipeline-CMUVBDC7.js +0 -14
- package/dist/incident-response-ZTIKUWEO.js.map +0 -1
- /package/dist/{agent-manager-7N7REQZQ.js.map → agent-manager-JZ4IM7XI.js.map} +0 -0
- /package/dist/{audit-logger-AU3TMWKI.js.map → analyzer-OTWE3ARE.js.map} +0 -0
- /package/dist/{bot-MU2TJQ3Y.js.map → audit-logger-CI4WZQPD.js.map} +0 -0
- /package/dist/{brain-SLA474EU.js.map → bot-VDHBGUVI.js.map} +0 -0
- /package/dist/{cost-tracker-EMOIOYH7.js.map → brain-6QTXN4QP.js.map} +0 -0
- /package/dist/{chunk-M7YLQHFP.js.map → chunk-56UJS2LA.js.map} +0 -0
- /package/dist/{chunk-S4NJJS5C.js.map → chunk-5BTVJR7R.js.map} +0 -0
- /package/dist/{chunk-BMOUYXLX.js.map → chunk-6ZNCY2GI.js.map} +0 -0
- /package/dist/{chunk-4YJRBMMA.js.map → chunk-BNZHWAZC.js.map} +0 -0
- /package/dist/{chunk-TAAZB5KN.js.map → chunk-CWT6CAE5.js.map} +0 -0
- /package/dist/{chunk-VKMFUIVA.js.map → chunk-GBVJTRXS.js.map} +0 -0
- /package/dist/{chunk-2RGPWU77.js.map → chunk-HJSEEFO3.js.map} +0 -0
- /package/dist/{chunk-JOA5A3G3.js.map → chunk-HQZQFEAX.js.map} +0 -0
- /package/dist/{chunk-45YXODSB.js.map → chunk-J4JW73TT.js.map} +0 -0
- /package/dist/{chunk-KT7NLIXP.js.map → chunk-JHYYFPKX.js.map} +0 -0
- /package/dist/{chunk-H3BOLSTS.js.map → chunk-PD3CTDO6.js.map} +0 -0
- /package/dist/{chunk-7MZN73J2.js.map → chunk-TKBVW7ZJ.js.map} +0 -0
- /package/dist/{chunk-A24GPVLY.js.map → chunk-V3OKHQUX.js.map} +0 -0
- /package/dist/{chunk-NMSHVO5O.js.map → chunk-WMDVOWN6.js.map} +0 -0
- /package/dist/{chunk-643M3AP5.js.map → chunk-WMFYI7XC.js.map} +0 -0
- /package/dist/{chunk-6LTLIYAQ.js.map → chunk-YEDEAX6Y.js.map} +0 -0
- /package/dist/{chunk-FFV2SXFD.js.map → chunk-ZVHG4KF2.js.map} +0 -0
- /package/dist/{db-LRIOKQBO.js.map → cost-tracker-KZQSTSE2.js.map} +0 -0
- /package/dist/{discord-NKR3X4AV.js.map → db-I7MNG6CL.js.map} +0 -0
- /package/dist/{enrichment-pipeline-CMUVBDC7.js.map → discord-6UQHCN27.js.map} +0 -0
- /package/dist/{documents-EYIYLZK2.js.map → documents-PFHSK7SZ.js.map} +0 -0
- /package/dist/{entity-resolution-4X4JU43O.js.map → enrichment-pipeline-7FE5R5ZI.js.map} +0 -0
- /package/dist/{env-CHOFICED.js.map → entity-resolution-7Z6STVXX.js.map} +0 -0
- /package/dist/{error-tracker-SVQSDQDW.js.map → env-GN5VHI43.js.map} +0 -0
- /package/dist/{imessage-V2XNDDHT.js.map → error-tracker-64DEH3D7.js.map} +0 -0
- /package/dist/{github-KGNILDWJ.js.map → github-DUWSXCNP.js.map} +0 -0
- /package/dist/{inbox-summarizer-DKKRYXDR.js.map → graph-client-NB475AK5.js.map} +0 -0
- /package/dist/{knowledge-base-J7PJ7MZ3.js.map → imessage-DSGSGUZS.js.map} +0 -0
- /package/dist/{mcp-3C2TN67D.js.map → inbox-summarizer-F2KAU72V.js.map} +0 -0
- /package/dist/{metrics-VJDWQWU7.js.map → knowledge-base-5SMMOGQJ.js.map} +0 -0
- /package/dist/{ocr-LGUIPKVZ.js.map → mcp-DJ2QDA6A.js.map} +0 -0
- /package/dist/{providers-H6YIC3MG.js.map → metrics-BH3ZLGEV.js.map} +0 -0
- /package/dist/{multi-user-S56GUD6L.js.map → multi-user-XAEMB244.js.map} +0 -0
- /package/dist/{scheduler-CA5UNHZV.js.map → oauth-UPJYFOVU.js.map} +0 -0
- /package/dist/{schema-ALJ67YVG.js.map → ocr-UONKTQU7.js.map} +0 -0
- /package/dist/{presentations-HXTAMGHT.js.map → presentations-UOET2FVZ.js.map} +0 -0
- /package/dist/{signal-X7IQJGRQ.js.map → providers-2YQ6E3IF.js.map} +0 -0
- /package/dist/{slack-P2LFUJUQ.js.map → scheduler-6PLLAQI7.js.map} +0 -0
- /package/dist/{sms-4VME2HUL.js.map → schema-ETY7L2VA.js.map} +0 -0
- /package/dist/{tools-FGPN522P.js.map → sharepoint-V5P4Q62L.js.map} +0 -0
- /package/dist/{whatsapp-KRPQ4YUX.js.map → signal-7D5EPGVL.js.map} +0 -0
- /package/dist/{word-document-D6N2C47N.js.map → word-document-AV3YB4L2.js.map} +0 -0
- /package/dist/{workflow-store-ZYAYE5P6.js.map → workflow-store-5Y56GUP7.js.map} +0 -0
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
logAudit,
|
|
7
7
|
queryAuditLogs,
|
|
8
8
|
verifyAuditChain
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-BBN4VCNK.js";
|
|
10
|
+
import "./chunk-5BTVJR7R.js";
|
|
11
|
+
import "./chunk-4KIHDIXZ.js";
|
|
12
|
+
import "./chunk-ZIBRVA3Y.js";
|
|
13
13
|
import "./chunk-UP2VWCW5.js";
|
|
14
14
|
export {
|
|
15
15
|
audit,
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
queryAuditLogs,
|
|
21
21
|
verifyAuditChain
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=audit-logger-
|
|
23
|
+
//# sourceMappingURL=audit-logger-CI4WZQPD.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createBot
|
|
3
|
+
} from "./chunk-56UJS2LA.js";
|
|
4
|
+
import "./chunk-J4JW73TT.js";
|
|
5
|
+
import "./chunk-BNZHWAZC.js";
|
|
6
|
+
import "./chunk-GJETKBOY.js";
|
|
7
|
+
import "./chunk-ZMML6T63.js";
|
|
8
|
+
import "./chunk-5JJTLWOR.js";
|
|
9
|
+
import "./chunk-QPY3WRVM.js";
|
|
10
|
+
import "./chunk-ADTDYJO7.js";
|
|
11
|
+
import "./chunk-LFDXEYYB.js";
|
|
12
|
+
import "./chunk-TKBVW7ZJ.js";
|
|
13
|
+
import "./chunk-DTISLIMB.js";
|
|
14
|
+
import "./chunk-CUPEENUY.js";
|
|
15
|
+
import "./chunk-2WTKTG2C.js";
|
|
16
|
+
import "./chunk-U2X2J3FI.js";
|
|
17
|
+
import "./chunk-X6Q3K3L2.js";
|
|
18
|
+
import "./chunk-ODCFS5WD.js";
|
|
19
|
+
import "./chunk-KM22GV7G.js";
|
|
20
|
+
import "./chunk-P6QINGFL.js";
|
|
21
|
+
import "./chunk-HJSEEFO3.js";
|
|
22
|
+
import "./chunk-C6PELIHS.js";
|
|
23
|
+
import "./chunk-7WQO5J2M.js";
|
|
24
|
+
import "./chunk-WMFYI7XC.js";
|
|
25
|
+
import "./chunk-YEDEAX6Y.js";
|
|
26
|
+
import "./chunk-6ZNCY2GI.js";
|
|
27
|
+
import "./chunk-WZAH34TG.js";
|
|
28
|
+
import "./chunk-6KONMXQ6.js";
|
|
29
|
+
import "./chunk-22VGGA7S.js";
|
|
30
|
+
import "./chunk-HN3F4WSW.js";
|
|
31
|
+
import "./chunk-V3OKHQUX.js";
|
|
32
|
+
import "./chunk-2I5QHYG6.js";
|
|
33
|
+
import "./chunk-CZTMGHUC.js";
|
|
34
|
+
import "./chunk-4WH6MFEW.js";
|
|
35
|
+
import "./chunk-GW6V4D43.js";
|
|
36
|
+
import "./chunk-DOYGMNMK.js";
|
|
37
|
+
import "./chunk-CQ4JURG7.js";
|
|
38
|
+
import "./chunk-BBN4VCNK.js";
|
|
39
|
+
import "./chunk-5BTVJR7R.js";
|
|
40
|
+
import "./chunk-4KIHDIXZ.js";
|
|
41
|
+
import "./chunk-ZIBRVA3Y.js";
|
|
42
|
+
import "./chunk-35WYTA3C.js";
|
|
43
|
+
import "./chunk-UP2VWCW5.js";
|
|
44
|
+
export {
|
|
45
|
+
createBot
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=bot-VDHBGUVI.js.map
|
|
@@ -10,10 +10,11 @@ import {
|
|
|
10
10
|
requestTracer,
|
|
11
11
|
streamChat,
|
|
12
12
|
streamChatWithTools
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-ZMML6T63.js";
|
|
14
|
+
import "./chunk-5JJTLWOR.js";
|
|
15
|
+
import "./chunk-QPY3WRVM.js";
|
|
16
16
|
import "./chunk-ADTDYJO7.js";
|
|
17
|
+
import "./chunk-DTISLIMB.js";
|
|
17
18
|
import "./chunk-CUPEENUY.js";
|
|
18
19
|
import "./chunk-2WTKTG2C.js";
|
|
19
20
|
import "./chunk-U2X2J3FI.js";
|
|
@@ -21,30 +22,30 @@ import "./chunk-X6Q3K3L2.js";
|
|
|
21
22
|
import "./chunk-ODCFS5WD.js";
|
|
22
23
|
import "./chunk-KM22GV7G.js";
|
|
23
24
|
import "./chunk-P6QINGFL.js";
|
|
24
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-HJSEEFO3.js";
|
|
25
26
|
import "./chunk-C6PELIHS.js";
|
|
26
27
|
import "./chunk-7WQO5J2M.js";
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-WMFYI7XC.js";
|
|
29
|
+
import "./chunk-YEDEAX6Y.js";
|
|
29
30
|
import {
|
|
30
31
|
costTracker,
|
|
31
32
|
modelRouter
|
|
32
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-6ZNCY2GI.js";
|
|
33
34
|
import "./chunk-WZAH34TG.js";
|
|
34
35
|
import "./chunk-6KONMXQ6.js";
|
|
35
36
|
import "./chunk-22VGGA7S.js";
|
|
36
37
|
import "./chunk-HN3F4WSW.js";
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-
|
|
39
|
-
import "./chunk-
|
|
40
|
-
import "./chunk-
|
|
41
|
-
import "./chunk-
|
|
38
|
+
import "./chunk-V3OKHQUX.js";
|
|
39
|
+
import "./chunk-2I5QHYG6.js";
|
|
40
|
+
import "./chunk-CZTMGHUC.js";
|
|
41
|
+
import "./chunk-4WH6MFEW.js";
|
|
42
|
+
import "./chunk-GW6V4D43.js";
|
|
42
43
|
import "./chunk-DOYGMNMK.js";
|
|
43
44
|
import "./chunk-CQ4JURG7.js";
|
|
44
|
-
import "./chunk-
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-
|
|
47
|
-
import "./chunk-
|
|
45
|
+
import "./chunk-BBN4VCNK.js";
|
|
46
|
+
import "./chunk-5BTVJR7R.js";
|
|
47
|
+
import "./chunk-4KIHDIXZ.js";
|
|
48
|
+
import "./chunk-ZIBRVA3Y.js";
|
|
48
49
|
import "./chunk-35WYTA3C.js";
|
|
49
50
|
import "./chunk-UP2VWCW5.js";
|
|
50
51
|
export {
|
|
@@ -62,4 +63,4 @@ export {
|
|
|
62
63
|
streamChat,
|
|
63
64
|
streamChatWithTools
|
|
64
65
|
};
|
|
65
|
-
//# sourceMappingURL=brain-
|
|
66
|
+
//# sourceMappingURL=brain-6QTXN4QP.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
db
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5BTVJR7R.js";
|
|
4
4
|
import {
|
|
5
5
|
graphEntities,
|
|
6
6
|
graphRelationships
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZIBRVA3Y.js";
|
|
8
8
|
|
|
9
9
|
// src/core/intelligence/entity-resolution.ts
|
|
10
10
|
import { eq, ilike, sql } from "drizzle-orm";
|
|
@@ -264,4 +264,4 @@ export {
|
|
|
264
264
|
mergeEntities,
|
|
265
265
|
findDuplicates
|
|
266
266
|
};
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
267
|
+
//# sourceMappingURL=chunk-2I5QHYG6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/intelligence/entity-resolution.ts"],"sourcesContent":["/**\r\n * Entity Resolution Pipeline\r\n *\r\n * Resolves, deduplicates, and matches entities across multiple public records\r\n * databases (FEC, IRS 990, USAspending, SEC EDGAR, OpenCorporates).\r\n *\r\n * Flow: exact match → identifier match (EIN/CIK/FEC) → fuzzy match → create new\r\n */\r\n\r\nimport { db } from \"../../db\";\r\nimport { graphEntities, graphRelationships } from \"../../db/schema\";\r\nimport { eq, ilike, sql } from \"drizzle-orm\";\r\n\r\n// Extended entity type for OSINT sources\r\nexport type OSINTEntityType =\r\n | \"person\"\r\n | \"organization\"\r\n | \"committee\"\r\n | \"contract\"\r\n | \"filing\"\r\n | \"location\"\r\n | \"topic\";\r\n\r\nexport interface EntityCandidate {\r\n name: string;\r\n type: OSINTEntityType;\r\n source: string; // \"fec\" | \"irs990\" | \"usaspending\" | \"sec\" | \"opencorporates\" | \"manual\"\r\n identifiers?: {\r\n ein?: string;\r\n cik?: string;\r\n fecId?: string;\r\n duns?: string;\r\n uei?: string;\r\n };\r\n attributes?: Record<string, unknown>;\r\n aliases?: string[];\r\n}\r\n\r\nexport interface ResolvedEntity {\r\n isNew: boolean;\r\n entityId: string; // postgres graphEntities.id\r\n confidence: number; // 0-1\r\n matchedBy: \"exact\" | \"fuzzy\" | \"identifier\" | \"new\";\r\n}\r\n\r\n/**\r\n * Normalize an entity name for comparison.\r\n * Strips punctuation, extra whitespace, common suffixes.\r\n */\r\nexport function normalizeEntityName(name: string): string {\r\n return name\r\n .toLowerCase()\r\n .replace(/[.,;:'\"!?()\\[\\]{}]/g, \"\")\r\n .replace(/\\b(inc|llc|corp|ltd|co|foundation|fund|assoc|association|committee|pac)\\b\\.?/gi, \"\")\r\n .replace(/\\s+/g, \" \")\r\n .trim();\r\n}\r\n\r\n/**\r\n * Jaro-Winkler similarity between two strings (0-1).\r\n */\r\nexport function fuzzyMatch(a: string, b: string): number {\r\n const s1 = normalizeEntityName(a);\r\n const s2 = normalizeEntityName(b);\r\n\r\n if (s1 === s2) return 1.0;\r\n if (s1.length === 0 || s2.length === 0) return 0.0;\r\n\r\n const matchWindow = Math.max(Math.floor(Math.max(s1.length, s2.length) / 2) - 1, 0);\r\n const s1Matches = new Array(s1.length).fill(false);\r\n const s2Matches = new Array(s2.length).fill(false);\r\n\r\n let matches = 0;\r\n let transpositions = 0;\r\n\r\n for (let i = 0; i < s1.length; i++) {\r\n const start = Math.max(0, i - matchWindow);\r\n const end = Math.min(i + matchWindow + 1, s2.length);\r\n for (let j = start; j < end; j++) {\r\n if (s2Matches[j] || s1[i] !== s2[j]) continue;\r\n s1Matches[i] = true;\r\n s2Matches[j] = true;\r\n matches++;\r\n break;\r\n }\r\n }\r\n\r\n if (matches === 0) return 0.0;\r\n\r\n let k = 0;\r\n for (let i = 0; i < s1.length; i++) {\r\n if (!s1Matches[i]) continue;\r\n while (!s2Matches[k]) k++;\r\n if (s1[i] !== s2[k]) transpositions++;\r\n k++;\r\n }\r\n\r\n const jaro =\r\n (matches / s1.length + matches / s2.length + (matches - transpositions / 2) / matches) / 3;\r\n\r\n // Winkler bonus for common prefix (up to 4 chars)\r\n let prefix = 0;\r\n for (let i = 0; i < Math.min(4, Math.min(s1.length, s2.length)); i++) {\r\n if (s1[i] === s2[i]) prefix++;\r\n else break;\r\n }\r\n\r\n return jaro + prefix * 0.1 * (1 - jaro);\r\n}\r\n\r\n/**\r\n * Match entity by EIN (Employer Identification Number).\r\n */\r\nexport async function matchByEIN(ein: string): Promise<string | null> {\r\n try {\r\n const results = await db\r\n .select({ id: graphEntities.id })\r\n .from(graphEntities)\r\n .where(sql`${graphEntities.attributes}->>'ein' = ${ein}`)\r\n .limit(1);\r\n return results.length > 0 ? results[0].id : null;\r\n } catch (error) {\r\n console.error(\"[EntityResolution] EIN match error:\", error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Match entity by CIK (SEC Central Index Key).\r\n */\r\nexport async function matchByCIK(cik: string): Promise<string | null> {\r\n try {\r\n const results = await db\r\n .select({ id: graphEntities.id })\r\n .from(graphEntities)\r\n .where(sql`${graphEntities.attributes}->>'cik' = ${cik}`)\r\n .limit(1);\r\n return results.length > 0 ? results[0].id : null;\r\n } catch (error) {\r\n console.error(\"[EntityResolution] CIK match error:\", error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Match entity by FEC committee/candidate ID.\r\n */\r\nexport async function matchByFECId(fecId: string): Promise<string | null> {\r\n try {\r\n const results = await db\r\n .select({ id: graphEntities.id })\r\n .from(graphEntities)\r\n .where(sql`${graphEntities.attributes}->>'fecId' = ${fecId}`)\r\n .limit(1);\r\n return results.length > 0 ? results[0].id : null;\r\n } catch (error) {\r\n console.error(\"[EntityResolution] FEC ID match error:\", error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Core entity resolution function.\r\n * Resolves a candidate entity against the existing knowledge graph.\r\n *\r\n * Resolution order:\r\n * 1. Exact name match\r\n * 2. Identifier match (EIN, CIK, FEC ID)\r\n * 3. Fuzzy name match (Jaro-Winkler > 0.85)\r\n * 4. Create new entity\r\n */\r\nexport async function resolveEntity(candidate: EntityCandidate): Promise<ResolvedEntity> {\r\n try {\r\n // 1. Exact name match\r\n const exactMatches = await db\r\n .select({ id: graphEntities.id })\r\n .from(graphEntities)\r\n .where(ilike(graphEntities.name, candidate.name))\r\n .limit(1);\r\n\r\n if (exactMatches.length > 0) {\r\n // Update with new source attributes\r\n await mergeAttributes(exactMatches[0].id, candidate);\r\n return {\r\n isNew: false,\r\n entityId: exactMatches[0].id,\r\n confidence: 1.0,\r\n matchedBy: \"exact\",\r\n };\r\n }\r\n\r\n // 2. Identifier match\r\n if (candidate.identifiers) {\r\n if (candidate.identifiers.ein) {\r\n const id = await matchByEIN(candidate.identifiers.ein);\r\n if (id) {\r\n await mergeAttributes(id, candidate);\r\n return { isNew: false, entityId: id, confidence: 0.99, matchedBy: \"identifier\" };\r\n }\r\n }\r\n if (candidate.identifiers.cik) {\r\n const id = await matchByCIK(candidate.identifiers.cik);\r\n if (id) {\r\n await mergeAttributes(id, candidate);\r\n return { isNew: false, entityId: id, confidence: 0.99, matchedBy: \"identifier\" };\r\n }\r\n }\r\n if (candidate.identifiers.fecId) {\r\n const id = await matchByFECId(candidate.identifiers.fecId);\r\n if (id) {\r\n await mergeAttributes(id, candidate);\r\n return { isNew: false, entityId: id, confidence: 0.99, matchedBy: \"identifier\" };\r\n }\r\n }\r\n }\r\n\r\n // 3. Fuzzy name match against existing entities of the same type\r\n const typeFilter = [\"person\", \"organization\", \"committee\"].includes(candidate.type)\r\n ? candidate.type\r\n : undefined;\r\n\r\n const potentialMatches = await db\r\n .select({ id: graphEntities.id, name: graphEntities.name, aliases: graphEntities.aliases })\r\n .from(graphEntities)\r\n .where(typeFilter ? eq(graphEntities.type, typeFilter as any) : sql`true`)\r\n .limit(500);\r\n\r\n let bestMatch: { id: string; score: number } | null = null;\r\n\r\n for (const entity of potentialMatches) {\r\n // Check main name\r\n const nameScore = fuzzyMatch(candidate.name, entity.name);\r\n if (nameScore > (bestMatch?.score ?? 0.85)) {\r\n bestMatch = { id: entity.id, score: nameScore };\r\n }\r\n\r\n // Check aliases\r\n const aliases = (entity.aliases as string[]) || [];\r\n for (const alias of aliases) {\r\n const aliasScore = fuzzyMatch(candidate.name, alias);\r\n if (aliasScore > (bestMatch?.score ?? 0.85)) {\r\n bestMatch = { id: entity.id, score: aliasScore };\r\n }\r\n }\r\n }\r\n\r\n if (bestMatch) {\r\n await mergeAttributes(bestMatch.id, candidate);\r\n return {\r\n isNew: false,\r\n entityId: bestMatch.id,\r\n confidence: bestMatch.score,\r\n matchedBy: \"fuzzy\",\r\n };\r\n }\r\n\r\n // 4. Create new entity\r\n const newEntity = await db\r\n .insert(graphEntities)\r\n .values({\r\n type: mapOSINTTypeToGraphType(candidate.type) as any,\r\n name: candidate.name,\r\n aliases: candidate.aliases || [],\r\n description: `Discovered from ${candidate.source}`,\r\n attributes: {\r\n ...candidate.attributes,\r\n ...candidate.identifiers,\r\n sources: [candidate.source],\r\n discoveredAt: new Date().toISOString(),\r\n },\r\n importance: 5,\r\n mentionCount: 1,\r\n })\r\n .returning({ id: graphEntities.id });\r\n\r\n console.log(`[EntityResolution] Created new entity: ${candidate.name} (${candidate.type}) from ${candidate.source}`);\r\n\r\n return {\r\n isNew: true,\r\n entityId: newEntity[0].id,\r\n confidence: 1.0,\r\n matchedBy: \"new\",\r\n };\r\n } catch (error) {\r\n console.error(\"[EntityResolution] Error resolving entity:\", error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Merge new attributes and aliases into an existing entity.\r\n */\r\nasync function mergeAttributes(entityId: string, candidate: EntityCandidate): Promise<void> {\r\n try {\r\n const existing = await db\r\n .select({ attributes: graphEntities.attributes, aliases: graphEntities.aliases, mentionCount: graphEntities.mentionCount })\r\n .from(graphEntities)\r\n .where(eq(graphEntities.id, entityId))\r\n .limit(1);\r\n\r\n if (existing.length === 0) return;\r\n\r\n const currentAttrs = (existing[0].attributes as Record<string, unknown>) || {};\r\n const currentAliases = (existing[0].aliases as string[]) || [];\r\n const currentSources = (currentAttrs.sources as string[]) || [];\r\n\r\n // Merge attributes\r\n const mergedAttrs = {\r\n ...currentAttrs,\r\n ...candidate.attributes,\r\n ...candidate.identifiers,\r\n sources: [...new Set([...currentSources, candidate.source])],\r\n lastUpdated: new Date().toISOString(),\r\n };\r\n\r\n // Merge aliases\r\n const newAliases = candidate.aliases || [];\r\n const mergedAliases = [...new Set([...currentAliases, ...newAliases])];\r\n\r\n await db\r\n .update(graphEntities)\r\n .set({\r\n attributes: mergedAttrs,\r\n aliases: mergedAliases,\r\n mentionCount: (existing[0].mentionCount || 0) + 1,\r\n })\r\n .where(eq(graphEntities.id, entityId));\r\n } catch (error) {\r\n console.error(\"[EntityResolution] Error merging attributes:\", error);\r\n }\r\n}\r\n\r\n/**\r\n * Map OSINT entity types to the existing graph entity types.\r\n */\r\nfunction mapOSINTTypeToGraphType(type: OSINTEntityType): string {\r\n switch (type) {\r\n case \"person\": return \"person\";\r\n case \"organization\": return \"organization\";\r\n case \"committee\": return \"organization\";\r\n case \"contract\": return \"event\";\r\n case \"filing\": return \"event\";\r\n case \"location\": return \"location\";\r\n case \"topic\": return \"topic\";\r\n default: return \"organization\";\r\n }\r\n}\r\n\r\n/**\r\n * Merge two entities (mark duplicate as alias of primary).\r\n */\r\nexport async function mergeEntities(primaryId: string, duplicateId: string): Promise<void> {\r\n try {\r\n const [primary, duplicate] = await Promise.all([\r\n db.select().from(graphEntities).where(eq(graphEntities.id, primaryId)).limit(1),\r\n db.select().from(graphEntities).where(eq(graphEntities.id, duplicateId)).limit(1),\r\n ]);\r\n\r\n if (primary.length === 0 || duplicate.length === 0) return;\r\n\r\n // Add duplicate name as alias\r\n const aliases = [...new Set([\r\n ...((primary[0].aliases as string[]) || []),\r\n duplicate[0].name,\r\n ...((duplicate[0].aliases as string[]) || []),\r\n ])];\r\n\r\n // Merge attributes\r\n const mergedAttrs = {\r\n ...((duplicate[0].attributes as Record<string, unknown>) || {}),\r\n ...((primary[0].attributes as Record<string, unknown>) || {}),\r\n };\r\n\r\n await db\r\n .update(graphEntities)\r\n .set({ aliases, attributes: mergedAttrs })\r\n .where(eq(graphEntities.id, primaryId));\r\n\r\n // Reassign all relationships from duplicate to primary\r\n await db\r\n .update(graphRelationships)\r\n .set({ sourceEntityId: primaryId })\r\n .where(eq(graphRelationships.sourceEntityId, duplicateId));\r\n\r\n await db\r\n .update(graphRelationships)\r\n .set({ targetEntityId: primaryId })\r\n .where(eq(graphRelationships.targetEntityId, duplicateId));\r\n\r\n // Delete the duplicate\r\n await db.delete(graphEntities).where(eq(graphEntities.id, duplicateId));\r\n\r\n console.log(`[EntityResolution] Merged entity ${duplicate[0].name} into ${primary[0].name}`);\r\n } catch (error) {\r\n console.error(\"[EntityResolution] Error merging entities:\", error);\r\n }\r\n}\r\n\r\n/**\r\n * Find potential duplicate entities based on fuzzy matching.\r\n */\r\nexport async function findDuplicates(\r\n threshold: number = 0.85\r\n): Promise<Array<{ entities: [string, string]; names: [string, string]; score: number }>> {\r\n try {\r\n const allEntities = await db\r\n .select({ id: graphEntities.id, name: graphEntities.name })\r\n .from(graphEntities)\r\n .limit(1000);\r\n\r\n const duplicates: Array<{ entities: [string, string]; names: [string, string]; score: number }> = [];\r\n\r\n for (let i = 0; i < allEntities.length; i++) {\r\n for (let j = i + 1; j < allEntities.length; j++) {\r\n const score = fuzzyMatch(allEntities[i].name, allEntities[j].name);\r\n if (score >= threshold && score < 1.0) {\r\n duplicates.push({\r\n entities: [allEntities[i].id, allEntities[j].id],\r\n names: [allEntities[i].name, allEntities[j].name],\r\n score,\r\n });\r\n }\r\n }\r\n }\r\n\r\n return duplicates.sort((a, b) => b.score - a.score);\r\n } catch (error) {\r\n console.error(\"[EntityResolution] Error finding duplicates:\", error);\r\n return [];\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger
|
|
3
|
+
} from "./chunk-7BNFELEK.js";
|
|
4
|
+
import {
|
|
5
|
+
db
|
|
6
|
+
} from "./chunk-5BTVJR7R.js";
|
|
7
|
+
import {
|
|
8
|
+
env
|
|
9
|
+
} from "./chunk-4KIHDIXZ.js";
|
|
10
|
+
import {
|
|
11
|
+
m365OauthStates
|
|
12
|
+
} from "./chunk-ZIBRVA3Y.js";
|
|
13
|
+
|
|
14
|
+
// src/integrations/m365/oauth.ts
|
|
15
|
+
import { createHash, randomBytes } from "crypto";
|
|
16
|
+
import { eq, lt } from "drizzle-orm";
|
|
17
|
+
var log = createLogger("m365:oauth");
|
|
18
|
+
var STATE_TTL_MS = 10 * 60 * 1e3;
|
|
19
|
+
function getM365Config() {
|
|
20
|
+
if (!env.M365_CLIENT_ID || !env.M365_CLIENT_SECRET) return null;
|
|
21
|
+
return {
|
|
22
|
+
clientId: env.M365_CLIENT_ID,
|
|
23
|
+
clientSecret: env.M365_CLIENT_SECRET,
|
|
24
|
+
tenantId: env.M365_TENANT_ID || "common",
|
|
25
|
+
redirectUri: env.M365_REDIRECT_URI || `http://localhost:${env.PORT}/api/m365/auth/callback`,
|
|
26
|
+
scopes: env.M365_GRAPH_SCOPES
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function isM365Configured() {
|
|
30
|
+
return getM365Config() !== null;
|
|
31
|
+
}
|
|
32
|
+
function base64Url(buf) {
|
|
33
|
+
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
34
|
+
}
|
|
35
|
+
function generateCodeVerifier() {
|
|
36
|
+
return base64Url(randomBytes(32));
|
|
37
|
+
}
|
|
38
|
+
function generateCodeChallenge(verifier) {
|
|
39
|
+
return base64Url(createHash("sha256").update(verifier).digest());
|
|
40
|
+
}
|
|
41
|
+
async function persistState(opts) {
|
|
42
|
+
await db.insert(m365OauthStates).values({
|
|
43
|
+
state: opts.state,
|
|
44
|
+
codeVerifier: opts.codeVerifier,
|
|
45
|
+
userKey: opts.userKey ?? null,
|
|
46
|
+
returnTo: opts.returnTo ?? null,
|
|
47
|
+
expiresAt: new Date(Date.now() + STATE_TTL_MS)
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function consumeState(state) {
|
|
51
|
+
const rows = await db.select().from(m365OauthStates).where(eq(m365OauthStates.state, state)).limit(1);
|
|
52
|
+
if (rows.length === 0) return null;
|
|
53
|
+
const row = rows[0];
|
|
54
|
+
await db.delete(m365OauthStates).where(eq(m365OauthStates.state, state));
|
|
55
|
+
if (row.expiresAt.getTime() < Date.now()) {
|
|
56
|
+
log.warn("state expired", { state });
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
codeVerifier: row.codeVerifier,
|
|
61
|
+
userKey: row.userKey,
|
|
62
|
+
returnTo: row.returnTo
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async function cleanupExpiredStates() {
|
|
66
|
+
const result = await db.delete(m365OauthStates).where(lt(m365OauthStates.expiresAt, /* @__PURE__ */ new Date()));
|
|
67
|
+
return result?.count ?? 0;
|
|
68
|
+
}
|
|
69
|
+
function buildAuthorizeUrl(config, params) {
|
|
70
|
+
const query = new URLSearchParams({
|
|
71
|
+
client_id: config.clientId,
|
|
72
|
+
response_type: "code",
|
|
73
|
+
redirect_uri: config.redirectUri,
|
|
74
|
+
response_mode: "query",
|
|
75
|
+
scope: config.scopes,
|
|
76
|
+
state: params.state,
|
|
77
|
+
code_challenge: params.codeChallenge,
|
|
78
|
+
code_challenge_method: "S256"
|
|
79
|
+
});
|
|
80
|
+
if (params.loginHint) query.set("login_hint", params.loginHint);
|
|
81
|
+
return `https://login.microsoftonline.com/${config.tenantId}/oauth2/v2.0/authorize?${query.toString()}`;
|
|
82
|
+
}
|
|
83
|
+
async function postToken(config, body) {
|
|
84
|
+
const url = `https://login.microsoftonline.com/${config.tenantId}/oauth2/v2.0/token`;
|
|
85
|
+
const res = await fetch(url, {
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
88
|
+
body: body.toString()
|
|
89
|
+
});
|
|
90
|
+
const data = await res.json();
|
|
91
|
+
if (!res.ok || data.error || !data.access_token) {
|
|
92
|
+
const msg = data.error_description || data.error || `token endpoint returned ${res.status}`;
|
|
93
|
+
throw new Error(`M365 token exchange failed: ${msg}`);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
accessToken: data.access_token,
|
|
97
|
+
refreshToken: data.refresh_token,
|
|
98
|
+
expiresAt: new Date(Date.now() + data.expires_in * 1e3),
|
|
99
|
+
scope: data.scope,
|
|
100
|
+
tokenType: data.token_type ?? "Bearer"
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async function exchangeCodeForTokens(config, code, codeVerifier) {
|
|
104
|
+
const body = new URLSearchParams({
|
|
105
|
+
client_id: config.clientId,
|
|
106
|
+
client_secret: config.clientSecret,
|
|
107
|
+
grant_type: "authorization_code",
|
|
108
|
+
code,
|
|
109
|
+
redirect_uri: config.redirectUri,
|
|
110
|
+
code_verifier: codeVerifier
|
|
111
|
+
});
|
|
112
|
+
return postToken(config, body);
|
|
113
|
+
}
|
|
114
|
+
async function refreshTokens(config, refreshToken) {
|
|
115
|
+
const body = new URLSearchParams({
|
|
116
|
+
client_id: config.clientId,
|
|
117
|
+
client_secret: config.clientSecret,
|
|
118
|
+
grant_type: "refresh_token",
|
|
119
|
+
refresh_token: refreshToken,
|
|
120
|
+
scope: config.scopes
|
|
121
|
+
});
|
|
122
|
+
return postToken(config, body);
|
|
123
|
+
}
|
|
124
|
+
var REFRESH_BUFFER_MS = 2 * 60 * 1e3;
|
|
125
|
+
function shouldRefresh(expiresAt) {
|
|
126
|
+
return expiresAt.getTime() - Date.now() < REFRESH_BUFFER_MS;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
getM365Config,
|
|
131
|
+
isM365Configured,
|
|
132
|
+
generateCodeVerifier,
|
|
133
|
+
generateCodeChallenge,
|
|
134
|
+
persistState,
|
|
135
|
+
consumeState,
|
|
136
|
+
cleanupExpiredStates,
|
|
137
|
+
buildAuthorizeUrl,
|
|
138
|
+
exchangeCodeForTokens,
|
|
139
|
+
refreshTokens,
|
|
140
|
+
REFRESH_BUFFER_MS,
|
|
141
|
+
shouldRefresh
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=chunk-3AWAWRWB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/integrations/m365/oauth.ts"],"sourcesContent":["/**\n * Microsoft 365 / Entra ID OAuth helpers.\n *\n * Implements the Authorization Code flow with PKCE and a server-side state\n * store for CSRF protection. No client secret is leaked to the browser.\n *\n * Flow:\n * 1. buildLoginUrl() — generate state + code_verifier, persist, redirect user.\n * 2. exchangeCode() — on callback, verify state, exchange code for tokens.\n * 3. refreshTokens() — called by token-store when access_token is near expiry.\n */\n\nimport { createHash, randomBytes } from \"crypto\";\nimport { db, m365OauthStates } from \"../../db\";\nimport { env } from \"../../config/env\";\nimport { createLogger } from \"../../core/logger\";\nimport { eq, lt } from \"drizzle-orm\";\n\nconst log = createLogger(\"m365:oauth\");\n\nconst STATE_TTL_MS = 10 * 60 * 1000; // 10 minutes\n\nexport interface TokenSet {\n accessToken: string;\n refreshToken?: string;\n expiresAt: Date;\n scope?: string;\n tokenType: string;\n}\n\nexport interface M365Config {\n clientId: string;\n clientSecret: string;\n tenantId: string;\n redirectUri: string;\n scopes: string;\n}\n\nexport function getM365Config(): M365Config | null {\n if (!env.M365_CLIENT_ID || !env.M365_CLIENT_SECRET) return null;\n return {\n clientId: env.M365_CLIENT_ID,\n clientSecret: env.M365_CLIENT_SECRET,\n tenantId: env.M365_TENANT_ID || \"common\",\n redirectUri:\n env.M365_REDIRECT_URI || `http://localhost:${env.PORT}/api/m365/auth/callback`,\n scopes: env.M365_GRAPH_SCOPES,\n };\n}\n\nexport function isM365Configured(): boolean {\n return getM365Config() !== null;\n}\n\n// ---------------------------------------------------------------------------\n// PKCE helpers\n// ---------------------------------------------------------------------------\n\nfunction base64Url(buf: Buffer): string {\n return buf.toString(\"base64\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\nexport function generateCodeVerifier(): string {\n return base64Url(randomBytes(32));\n}\n\nexport function generateCodeChallenge(verifier: string): string {\n return base64Url(createHash(\"sha256\").update(verifier).digest());\n}\n\n// ---------------------------------------------------------------------------\n// State store — persisted so we can validate across redirect\n// ---------------------------------------------------------------------------\n\nexport async function persistState(opts: {\n state: string;\n codeVerifier: string;\n userKey?: string;\n returnTo?: string;\n}): Promise<void> {\n await db.insert(m365OauthStates).values({\n state: opts.state,\n codeVerifier: opts.codeVerifier,\n userKey: opts.userKey ?? null,\n returnTo: opts.returnTo ?? null,\n expiresAt: new Date(Date.now() + STATE_TTL_MS),\n });\n}\n\nexport async function consumeState(state: string): Promise<{\n codeVerifier: string;\n userKey: string | null;\n returnTo: string | null;\n} | null> {\n const rows = await db.select().from(m365OauthStates).where(eq(m365OauthStates.state, state)).limit(1);\n if (rows.length === 0) return null;\n const row = rows[0];\n await db.delete(m365OauthStates).where(eq(m365OauthStates.state, state));\n\n if (row.expiresAt.getTime() < Date.now()) {\n log.warn(\"state expired\", { state });\n return null;\n }\n\n return {\n codeVerifier: row.codeVerifier,\n userKey: row.userKey,\n returnTo: row.returnTo,\n };\n}\n\n// Periodic cleanup — call opportunistically from routes\nexport async function cleanupExpiredStates(): Promise<number> {\n const result = await db.delete(m365OauthStates).where(lt(m365OauthStates.expiresAt, new Date()));\n return (result as any)?.count ?? 0;\n}\n\n// ---------------------------------------------------------------------------\n// URL builders / token exchange\n// ---------------------------------------------------------------------------\n\nexport function buildAuthorizeUrl(\n config: M365Config,\n params: { state: string; codeChallenge: string; loginHint?: string }\n): string {\n const query = new URLSearchParams({\n client_id: config.clientId,\n response_type: \"code\",\n redirect_uri: config.redirectUri,\n response_mode: \"query\",\n scope: config.scopes,\n state: params.state,\n code_challenge: params.codeChallenge,\n code_challenge_method: \"S256\",\n });\n if (params.loginHint) query.set(\"login_hint\", params.loginHint);\n\n return `https://login.microsoftonline.com/${config.tenantId}/oauth2/v2.0/authorize?${query.toString()}`;\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n scope?: string;\n token_type?: string;\n error?: string;\n error_description?: string;\n}\n\nasync function postToken(config: M365Config, body: URLSearchParams): Promise<TokenSet> {\n const url = `https://login.microsoftonline.com/${config.tenantId}/oauth2/v2.0/token`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n const data = (await res.json()) as TokenResponse;\n\n if (!res.ok || data.error || !data.access_token) {\n const msg = data.error_description || data.error || `token endpoint returned ${res.status}`;\n throw new Error(`M365 token exchange failed: ${msg}`);\n }\n\n return {\n accessToken: data.access_token,\n refreshToken: data.refresh_token,\n expiresAt: new Date(Date.now() + data.expires_in * 1000),\n scope: data.scope,\n tokenType: data.token_type ?? \"Bearer\",\n };\n}\n\nexport async function exchangeCodeForTokens(\n config: M365Config,\n code: string,\n codeVerifier: string\n): Promise<TokenSet> {\n const body = new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n grant_type: \"authorization_code\",\n code,\n redirect_uri: config.redirectUri,\n code_verifier: codeVerifier,\n });\n return postToken(config, body);\n}\n\nexport async function refreshTokens(\n config: M365Config,\n refreshToken: string\n): Promise<TokenSet> {\n const body = new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n scope: config.scopes,\n });\n return postToken(config, body);\n}\n\n// Expiry buffer — refresh if access_token has less than this many ms left.\nexport const REFRESH_BUFFER_MS = 2 * 60 * 1000;\n\nexport function shouldRefresh(expiresAt: Date): boolean {\n return expiresAt.getTime() - Date.now() < REFRESH_BUFFER_MS;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -121,6 +121,17 @@ var envSchema = z.object({
|
|
|
121
121
|
OUTLOOK_CLIENT_SECRET: z.string().optional(),
|
|
122
122
|
OUTLOOK_REDIRECT_URI: z.string().url().optional(),
|
|
123
123
|
OUTLOOK_REFRESH_TOKEN: z.string().optional(),
|
|
124
|
+
// Microsoft 365 / Entra ID (Graph API — mail, files, sites)
|
|
125
|
+
// Scoped broader than Outlook Calendar: powers /api/m365/* routes.
|
|
126
|
+
M365_CLIENT_ID: z.string().optional(),
|
|
127
|
+
M365_CLIENT_SECRET: z.string().optional(),
|
|
128
|
+
M365_TENANT_ID: z.string().optional().default("common"),
|
|
129
|
+
M365_REDIRECT_URI: z.string().optional(),
|
|
130
|
+
M365_GRAPH_SCOPES: z.string().optional().default(
|
|
131
|
+
"openid profile offline_access User.Read Mail.Read Mail.ReadWrite Mail.Send Calendars.Read Files.Read"
|
|
132
|
+
),
|
|
133
|
+
M365_ANALYZE_RATE_LIMIT: z.coerce.number().optional().default(30),
|
|
134
|
+
M365_ANALYZE_RATE_REFILL: z.coerce.number().optional().default(0.5),
|
|
124
135
|
// Dropbox (additional OAuth fields)
|
|
125
136
|
DROPBOX_CLIENT_ID: z.string().optional(),
|
|
126
137
|
DROPBOX_CLIENT_SECRET: z.string().optional(),
|
|
@@ -276,7 +287,7 @@ function configure(config) {
|
|
|
276
287
|
);
|
|
277
288
|
}
|
|
278
289
|
_env = result.data;
|
|
279
|
-
_providerInitPromise = import("./providers-
|
|
290
|
+
_providerInitPromise = import("./providers-2YQ6E3IF.js").then((m) => m.initializeProviders()).catch(() => {
|
|
280
291
|
});
|
|
281
292
|
return _env;
|
|
282
293
|
}
|
|
@@ -337,4 +348,4 @@ export {
|
|
|
337
348
|
ready,
|
|
338
349
|
env
|
|
339
350
|
};
|
|
340
|
-
//# sourceMappingURL=chunk-
|
|
351
|
+
//# sourceMappingURL=chunk-4KIHDIXZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/env.ts"],"sourcesContent":["import { z } from \"zod\";\r\n\r\nconst envSchema = z.object({\r\n // Claude API\r\n CLAUDE_API_KEY: z.string().min(1, \"CLAUDE_API_KEY is required\"),\r\n\r\n // Telegram\r\n TELEGRAM_BOT_TOKEN: z.string().optional().default(\"\"),\r\n TELEGRAM_CHAT_ID: z.string().optional().default(\"\"),\r\n\r\n // OpenAI (Whisper STT)\r\n OPENAI_API_KEY: z.string().optional().default(\"\"),\r\n\r\n // ElevenLabs TTS\r\n ELEVENLABS_API_KEY: z.string().optional().default(\"\"),\r\n ELEVENLABS_VOICE_ID: z.string().optional().default(\"\"),\r\n\r\n // Database\r\n DATABASE_URL: z\r\n .string()\r\n .default(\"\"),\r\n\r\n // Redis\r\n REDIS_URL: z.string().default(\"redis://localhost:6379\"),\r\n\r\n // Discord (optional)\r\n DISCORD_BOT_TOKEN: z.string().optional(),\r\n DISCORD_CLIENT_ID: z.string().optional(),\r\n DISCORD_GUILD_ID: z.string().optional(),\r\n DISCORD_ALLOWED_USER_IDS: z.string().optional(), // Comma-separated list\r\n DISCORD_ALLOWED_ROLE_IDS: z.string().optional(), // Comma-separated list\r\n\r\n // Slack (optional)\r\n SLACK_BOT_TOKEN: z.string().optional(),\r\n SLACK_SIGNING_SECRET: z.string().optional(),\r\n SLACK_APP_TOKEN: z.string().optional(),\r\n SLACK_SOCKET_MODE: z.coerce.boolean().optional().default(false),\r\n SLACK_PORT: z.coerce.number().optional().default(3000),\r\n SLACK_ALLOWED_USER_IDS: z.string().optional(), // Comma-separated list\r\n SLACK_ALLOWED_CHANNEL_IDS: z.string().optional(), // Comma-separated list\r\n\r\n // Notion (optional)\r\n NOTION_API_KEY: z.string().optional(),\r\n NOTION_ROOT_PAGE_ID: z.string().optional(),\r\n\r\n // Email (optional)\r\n EMAIL_IMAP_HOST: z.string().optional(),\r\n EMAIL_IMAP_PORT: z.coerce.number().optional().default(993),\r\n EMAIL_IMAP_SECURE: z.coerce.boolean().optional().default(true),\r\n EMAIL_SMTP_HOST: z.string().optional(),\r\n EMAIL_SMTP_PORT: z.coerce.number().optional().default(587),\r\n EMAIL_SMTP_SECURE: z.coerce.boolean().optional().default(false),\r\n EMAIL_USER: z.string().optional(),\r\n EMAIL_PASSWORD: z.string().optional(),\r\n EMAIL_PROVIDER: z.enum([\"gmail\", \"outlook\", \"yahoo\", \"custom\"]).optional(),\r\n\r\n // Local Mail Server (Dovecot master user for multi-account access)\r\n EMAIL_MASTER_USER: z.string().optional(),\r\n EMAIL_MASTER_PASSWORD: z.string().optional(),\r\n EMAIL_LOCAL_IMAP_HOST: z.string().optional().default(\"127.0.0.1\"),\r\n EMAIL_LOCAL_IMAP_PORT: z.coerce.number().optional().default(993),\r\n EMAIL_LOCAL_SMTP_HOST: z.string().optional().default(\"127.0.0.1\"),\r\n EMAIL_LOCAL_SMTP_PORT: z.coerce.number().optional().default(25),\r\n\r\n // GitHub (optional)\r\n GITHUB_TOKEN: z.string().optional(),\r\n GITHUB_WEBHOOK_SECRET: z.string().optional(),\r\n\r\n // Google Services (unified OAuth2 — optional, falls back to service-specific)\r\n GOOGLE_CLIENT_ID: z.string().optional(),\r\n GOOGLE_CLIENT_SECRET: z.string().optional(),\r\n GOOGLE_REDIRECT_URI: z.string().optional(),\r\n GOOGLE_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Google Drive (optional)\r\n GOOGLE_DRIVE_CLIENT_ID: z.string().optional(),\r\n GOOGLE_DRIVE_CLIENT_SECRET: z.string().optional(),\r\n GOOGLE_DRIVE_REDIRECT_URI: z.string().optional(),\r\n GOOGLE_DRIVE_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Dropbox (optional)\r\n DROPBOX_APP_KEY: z.string().optional(),\r\n DROPBOX_APP_SECRET: z.string().optional(),\r\n DROPBOX_ACCESS_TOKEN: z.string().optional(),\r\n DROPBOX_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // GIF Search (optional)\r\n TENOR_API_KEY: z.string().optional(),\r\n GIPHY_API_KEY: z.string().optional(),\r\n\r\n // Finance (optional)\r\n ALPHA_VANTAGE_API_KEY: z.string().optional(),\r\n FRED_API_KEY: z.string().optional(), // Federal Reserve Economic Data\r\n FINNHUB_API_KEY: z.string().optional(), // Finnhub financial market data\r\n\r\n // Exchange Trading (optional)\r\n COINBASE_API_KEY: z.string().optional(),\r\n COINBASE_PRIVATE_KEY: z.string().optional(),\r\n BINANCE_API_KEY: z.string().optional(),\r\n BINANCE_API_SECRET: z.string().optional(),\r\n BINANCE_TESTNET: z.coerce.boolean().optional().default(false),\r\n EXCHANGE_REQUIRE_CONFIRMATION: z.coerce.boolean().optional().default(true),\r\n EXCHANGE_MAX_TRADE_SIZE: z.coerce.number().optional().default(100),\r\n EXCHANGE_MAX_DAILY_SPEND: z.coerce.number().optional().default(500),\r\n EXCHANGE_MAX_TRADES_PER_HOUR: z.coerce.number().optional().default(5),\r\n EXCHANGE_AGENT_TRADING_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // DeFi (optional)\r\n DEFILLAMA_API_KEY: z.string().optional(), // Pro tier\r\n\r\n // On-Chain Analytics (optional)\r\n ETHERSCAN_API_KEY: z.string().optional(),\r\n ALCHEMY_API_KEY: z.string().optional(),\r\n ALCHEMY_NETWORK: z.string().optional().default(\"eth-mainnet\"),\r\n\r\n // Optional\r\n HUGGINGFACE_ACCESS_TOKEN: z.string().optional(),\r\n TWILIO_ACCOUNT_SID: z.string().optional(),\r\n TWILIO_AUTH_TOKEN: z.string().optional(),\r\n TWILIO_PHONE_NUMBER: z.string().optional(),\r\n\r\n // Home Assistant (optional)\r\n HOME_ASSISTANT_URL: z.string().url().optional(),\r\n HOME_ASSISTANT_TOKEN: z.string().optional(),\r\n\r\n // Spotify (optional)\r\n SPOTIFY_CLIENT_ID: z.string().optional(),\r\n SPOTIFY_CLIENT_SECRET: z.string().optional(),\r\n SPOTIFY_REDIRECT_URI: z.string().optional(),\r\n SPOTIFY_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Google Calendar (optional)\r\n GOOGLE_CALENDAR_CLIENT_ID: z.string().optional(),\r\n GOOGLE_CALENDAR_CLIENT_SECRET: z.string().optional(),\r\n GOOGLE_CALENDAR_REDIRECT_URI: z.string().url().optional(),\r\n GOOGLE_CALENDAR_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Outlook Calendar (optional)\r\n OUTLOOK_CLIENT_ID: z.string().optional(),\r\n OUTLOOK_CLIENT_SECRET: z.string().optional(),\r\n OUTLOOK_REDIRECT_URI: z.string().url().optional(),\r\n OUTLOOK_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Microsoft 365 / Entra ID (Graph API — mail, files, sites)\r\n // Scoped broader than Outlook Calendar: powers /api/m365/* routes.\r\n M365_CLIENT_ID: z.string().optional(),\r\n M365_CLIENT_SECRET: z.string().optional(),\r\n M365_TENANT_ID: z.string().optional().default(\"common\"),\r\n M365_REDIRECT_URI: z.string().optional(),\r\n M365_GRAPH_SCOPES: z\r\n .string()\r\n .optional()\r\n .default(\r\n \"openid profile offline_access User.Read Mail.Read Mail.ReadWrite Mail.Send Calendars.Read Files.Read\"\r\n ),\r\n M365_ANALYZE_RATE_LIMIT: z.coerce.number().optional().default(30),\r\n M365_ANALYZE_RATE_REFILL: z.coerce.number().optional().default(0.5),\r\n\r\n // Dropbox (additional OAuth fields)\r\n DROPBOX_CLIENT_ID: z.string().optional(),\r\n DROPBOX_CLIENT_SECRET: z.string().optional(),\r\n DROPBOX_REDIRECT_URI: z.string().url().optional(),\r\n\r\n // MCP (Model Context Protocol)\r\n MCP_ENABLED: z.coerce.boolean().optional().default(true),\r\n MCP_CONFIG_PATH: z.string().optional().default(\"./mcp.json\"),\r\n\r\n // Multi-Provider LLM\r\n LLM_PROVIDER: z.string().optional().default(\"anthropic\"),\r\n OPENROUTER_API_KEY: z.string().optional(),\r\n OPENROUTER_BASE_URL: z.string().optional(),\r\n GROQ_API_KEY: z.string().optional(),\r\n MISTRAL_API_KEY: z.string().optional(),\r\n OPENAI_LLM_ENABLED: z.coerce.boolean().optional().default(false),\r\n OPENAI_COMPATIBLE_API_KEY: z.string().optional(),\r\n OPENAI_COMPATIBLE_BASE_URL: z.string().optional(),\r\n OPENAI_COMPATIBLE_MODEL: z.string().optional(),\r\n\r\n // xAI (Grok)\r\n XAI_API_KEY: z.string().optional(),\r\n XAI_DEFAULT_MODEL: z.string().optional().default(\"grok-2\"),\r\n\r\n // Google Gemini (optional)\r\n GEMINI_API_KEY: z.string().optional(),\r\n GEMINI_DEFAULT_MODEL: z.string().optional().default(\"gemini-2.0-flash\"),\r\n\r\n // Ollama (local models)\r\n OLLAMA_ENABLED: z.coerce.boolean().optional().default(false),\r\n OLLAMA_BASE_URL: z.string().optional().default(\"http://localhost:11434\"),\r\n OLLAMA_DEFAULT_MODEL: z.string().optional().default(\"llama3.1\"),\r\n\r\n // Model Routing\r\n MODEL_ROUTING_ENABLED: z.coerce.boolean().optional().default(true),\r\n MODEL_OPUS_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // Context Compaction\r\n COMPACTION_ENABLED: z.coerce.boolean().optional().default(true),\r\n COMPACTION_TOKEN_THRESHOLD: z.coerce.number().optional().default(80000),\r\n COMPACTION_PRESERVE_RECENT: z.coerce.number().optional().default(6),\r\n\r\n // Security (OWASP Agentic)\r\n PROMPT_GUARD_ENABLED: z.coerce.boolean().optional().default(true),\r\n PROMPT_GUARD_THRESHOLD: z.coerce.number().optional().default(0.7),\r\n CIRCUIT_BREAKER_ENABLED: z.coerce.boolean().optional().default(true),\r\n TOOL_SANDBOX_ENABLED: z.coerce.boolean().optional().default(true),\r\n\r\n // Observability\r\n COST_TRACKING_ENABLED: z.coerce.boolean().optional().default(true),\r\n QUALITY_SCORING_ENABLED: z.coerce.boolean().optional().default(true),\r\n REQUEST_TRACING_ENABLED: z.coerce.boolean().optional().default(true),\r\n\r\n // Intent Parser & Gateway\r\n LOCAL_INTENT_PARSER_ENABLED: z.coerce.boolean().optional().default(true),\r\n UNIFIED_GATEWAY_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // WhatsApp (optional)\r\n WHATSAPP_ENABLED: z.coerce.boolean().optional().default(false),\r\n WHATSAPP_AUTH_DIR: z.string().optional().default(\"./whatsapp-auth\"),\r\n WHATSAPP_ALLOWED_NUMBERS: z.string().optional(), // Comma-separated\r\n\r\n // Signal (optional)\r\n SIGNAL_ENABLED: z.coerce.boolean().optional().default(false),\r\n SIGNAL_PHONE_NUMBER: z.string().optional(),\r\n SIGNAL_CLI_PATH: z.string().optional().default(\"signal-cli\"),\r\n SIGNAL_ALLOWED_NUMBERS: z.string().optional(), // Comma-separated\r\n\r\n // iMessage (optional, macOS only)\r\n IMESSAGE_ENABLED: z.coerce.boolean().optional().default(false),\r\n IMESSAGE_MODE: z.enum([\"bluebubbles\", \"applescript\"]).optional().default(\"applescript\"),\r\n IMESSAGE_BLUEBUBBLES_URL: z.string().optional(),\r\n IMESSAGE_BLUEBUBBLES_PASSWORD: z.string().optional(),\r\n IMESSAGE_ALLOWED_NUMBERS: z.string().optional(), // Comma-separated\r\n\r\n // Tunnel Support\r\n TUNNEL_ENABLED: z.coerce.boolean().optional().default(false),\r\n TUNNEL_PROVIDER: z.enum([\"cloudflare\", \"ngrok\", \"localtunnel\"]).optional().default(\"cloudflare\"),\r\n TUNNEL_SUBDOMAIN: z.string().optional(),\r\n TUNNEL_AUTH_TOKEN: z.string().optional(),\r\n\r\n // Autonomy Levels\r\n AUTONOMY_LEVEL: z.enum([\"readonly\", \"supervised\", \"autonomous\"]).optional().default(\"autonomous\"),\r\n\r\n // Prometheus/OpenTelemetry\r\n PROMETHEUS_ENABLED: z.coerce.boolean().optional().default(false),\r\n PROMETHEUS_PATH: z.string().optional().default(\"/metrics\"),\r\n\r\n // Device Pairing\r\n PAIRING_ENABLED: z.coerce.boolean().optional().default(false),\r\n PAIRING_CODE_LIFETIME_MINUTES: z.coerce.number().optional().default(5),\r\n\r\n // Gateway Authentication (OpenClaw-style)\r\n // If set, web UI and API requests require this token. Unset = open access (localhost-friendly).\r\n GATEWAY_TOKEN: z.string().optional(),\r\n\r\n // Matrix (optional)\r\n MATRIX_ENABLED: z.coerce.boolean().optional().default(false),\r\n MATRIX_HOMESERVER_URL: z.string().optional(),\r\n MATRIX_ACCESS_TOKEN: z.string().optional(),\r\n MATRIX_USER_ID: z.string().optional(),\r\n MATRIX_ALLOWED_ROOM_IDS: z.string().optional(), // Comma-separated\r\n MATRIX_AUTO_JOIN: z.coerce.boolean().optional().default(true),\r\n MATRIX_E2E_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // Neo4j (OSINT graph database)\r\n NEO4J_URI: z.string().optional().default(\"bolt://localhost:7687\"),\r\n NEO4J_USER: z.string().optional().default(\"neo4j\"),\r\n NEO4J_PASSWORD: z.string().optional().default(\"\"),\r\n NEO4J_DATABASE: z.string().optional().default(\"neo4j\"),\r\n\r\n // OSINT API Keys\r\n FEC_API_KEY: z.string().optional().default(\"\"),\r\n OPENCORPORATES_API_TOKEN: z.string().optional().default(\"\"),\r\n SEC_EDGAR_USER_AGENT: z.string().optional().default(\"OpenSentinel/2.1 (contact@opensentinel.ai)\"),\r\n\r\n // OSINT Feature Toggle\r\n OSINT_ENABLED: z.coerce.boolean().optional().default(false),\r\n OSINT_RATE_LIMIT_BUFFER_MS: z.coerce.number().optional().default(200),\r\n\r\n // Embedding Provider\r\n EMBEDDING_PROVIDER: z.enum([\"openai\", \"huggingface\", \"tfidf\"]).optional().default(\"openai\"),\r\n EMBEDDING_MODEL: z.string().optional(),\r\n EMBEDDING_DIMENSIONS: z.coerce.number().optional(),\r\n EMBEDDING_DB_DIMENSIONS: z.coerce.number().optional().default(1536),\r\n EMBEDDING_BATCH_SIZE: z.coerce.number().optional().default(32),\r\n\r\n // Advanced RAG\r\n HYDE_ENABLED: z.coerce.boolean().optional().default(false),\r\n RERANK_ENABLED: z.coerce.boolean().optional().default(false),\r\n RERANK_MIN_SCORE: z.coerce.number().optional().default(3),\r\n MULTISTEP_RAG_ENABLED: z.coerce.boolean().optional().default(false),\r\n MULTISTEP_MAX_STEPS: z.coerce.number().optional().default(2),\r\n RETRIEVAL_CACHE_ENABLED: z.coerce.boolean().optional().default(false),\r\n CONTEXTUAL_QUERY_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // Agentic RAG Pipeline\r\n TOOL_CLASSIFIER_ENABLED: z.coerce.boolean().optional().default(false),\r\n TOOL_CLASSIFIER_TIMEOUT_MS: z.coerce.number().optional().default(5000),\r\n TOOL_CLASSIFIER_MAX_CATEGORIES: z.coerce.number().optional().default(3),\r\n\r\n // AI Memory (auto-extract/search)\r\n AUTO_MEMORY_EXTRACT_ENABLED: z.coerce.boolean().optional().default(false),\r\n AUTO_MEMORY_EXTRACT_DEDUP_THRESHOLD: z.coerce.number().optional().default(0.9),\r\n AUTO_MEMORY_SEARCH_THRESHOLD: z.coerce.number().optional().default(0.3),\r\n\r\n // Agentic Pipeline Orchestrator\r\n AGENTIC_PIPELINE_ENABLED: z.coerce.boolean().optional().default(false),\r\n AGENTIC_PRE_EXECUTION_ENABLED: z.coerce.boolean().optional().default(false),\r\n AGENTIC_PRE_EXECUTION_TIMEOUT_MS: z.coerce.number().optional().default(8000),\r\n\r\n // Agent Processor\r\n AGENT_PROCESSOR_ENABLED: z.coerce.boolean().optional().default(false),\r\n AGENT_PROCESSOR_CONCURRENCY: z.coerce.number().optional().default(1),\r\n AGENT_MAX_TURNS: z.coerce.number().optional().default(20),\r\n\r\n // SOC 2 Encryption & Audit\r\n ENCRYPTION_MASTER_KEY: z.string().optional(), // 32-byte base64 key for field encryption\r\n AUDIT_SIGNING_KEY: z.string().optional(), // HMAC key for tamper-proof audit logs\r\n\r\n // Server\r\n PORT: z.coerce.number().default(8030),\r\n NODE_ENV: z.enum([\"development\", \"production\", \"test\"]).default(\"development\"),\r\n});\r\n\r\nexport type Env = z.infer<typeof envSchema>;\r\n\r\n// Internal mutable store\r\nlet _env: Env | null = null;\r\n\r\n/**\r\n * Programmatic configuration for library use.\r\n * Call this before any module accesses `env`.\r\n * Config values are merged with process.env (config takes precedence).\r\n */\r\nlet _providerInitPromise: Promise<void> | null = null;\r\n\r\nexport function configure(config: Partial<Env> & { CLAUDE_API_KEY: string }): Env {\r\n const merged = { ...process.env, ...config };\r\n const result = envSchema.safeParse(merged);\r\n\r\n if (!result.success) {\r\n const errors = result.error.errors.map(\r\n (e) => `${e.path.join(\".\")}: ${e.message}`\r\n );\r\n throw new Error(\r\n `OpenSentinel configuration validation failed:\\n ${errors.join(\"\\n \")}`\r\n );\r\n }\r\n\r\n _env = result.data;\r\n\r\n // Auto-initialize LLM providers after configuration\r\n _providerInitPromise = import(\"../core/providers\").then((m) => m.initializeProviders()).catch(() => {});\r\n\r\n return _env;\r\n}\r\n\r\n/**\r\n * Wait for provider initialization to complete.\r\n * Call after configure() if you need providers ready before first API call.\r\n */\r\nexport async function ready(): Promise<void> {\r\n if (_providerInitPromise) await _providerInitPromise;\r\n}\r\n\r\n/**\r\n * Load config from process.env.\r\n * Called lazily on first access if configure() was not called.\r\n *\r\n * When used as a library, env vars may not be set at import time\r\n * (module-level singletons trigger this during static initialization).\r\n * In that case, we populate with defaults and partial values rather\r\n * than throwing — services will fail with clear errors when actually used.\r\n */\r\nfunction loadFromProcessEnv(): Env {\r\n const result = envSchema.safeParse(process.env);\r\n\r\n if (!result.success) {\r\n // If running as CLI (not library), throw so the user sees the error immediately\r\n if (process.env.__OPENSENTINEL_CLI__) {\r\n const errors = result.error.errors.map(\r\n (e) => `${e.path.join(\".\")}: ${e.message}`\r\n );\r\n throw new Error(\r\n `Environment validation failed:\\n ${errors.join(\"\\n \")}`\r\n );\r\n }\r\n\r\n // For library use: populate with whatever we have, fill missing with defaults\r\n // Services will fail individually when they try to use undefined API keys\r\n const lenientSchema = envSchema.extend({\r\n CLAUDE_API_KEY: z.string().default(\"\"),\r\n });\r\n const lenientResult = lenientSchema.safeParse(process.env);\r\n _env = (lenientResult.success ? lenientResult.data : {}) as Env;\r\n return _env;\r\n }\r\n\r\n _env = result.data;\r\n return _env;\r\n}\r\n\r\n/**\r\n * The env accessor. Lazy — loads from process.env on first access\r\n * if configure() was not called first.\r\n *\r\n * All 37+ consumer files keep using `env.SOME_PROP` unchanged.\r\n */\r\nexport const env: Env = new Proxy({} as Env, {\r\n get(_target, prop: string) {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return (_env as any)[prop];\r\n },\r\n has(_target, prop: string) {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return prop in (_env as any);\r\n },\r\n ownKeys() {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return Reflect.ownKeys(_env as any);\r\n },\r\n getOwnPropertyDescriptor(_target, prop) {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return Object.getOwnPropertyDescriptor(_env as any, prop);\r\n },\r\n});\r\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
providerRegistry
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GW6V4D43.js";
|
|
4
4
|
import {
|
|
5
5
|
isPathAllowed
|
|
6
6
|
} from "./chunk-CQ4JURG7.js";
|
|
@@ -286,4 +286,4 @@ export {
|
|
|
286
286
|
extractStructuredData,
|
|
287
287
|
ocr_default
|
|
288
288
|
};
|
|
289
|
-
//# sourceMappingURL=chunk-
|
|
289
|
+
//# sourceMappingURL=chunk-4WH6MFEW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/image-analysis.ts","../src/tools/ocr.ts"],"sourcesContent":["import { providerRegistry } from \"../core/providers\";\r\nimport { readFile } from \"fs/promises\";\r\nimport { isPathAllowed } from \"../utils/paths\";\r\n\r\nexport interface ImageAnalysisResult {\r\n success: boolean;\r\n analysis?: string;\r\n error?: string;\r\n}\r\n\r\n// Supported image MIME types\r\nconst SUPPORTED_TYPES: Record<string, string> = {\r\n \".jpg\": \"image/jpeg\",\r\n \".jpeg\": \"image/jpeg\",\r\n \".png\": \"image/png\",\r\n \".gif\": \"image/gif\",\r\n \".webp\": \"image/webp\",\r\n};\r\n\r\nfunction getMimeType(filename: string): string | null {\r\n const ext = filename.toLowerCase().slice(filename.lastIndexOf(\".\"));\r\n return SUPPORTED_TYPES[ext] || null;\r\n}\r\n\r\n// Analyze image from URL\r\nexport async function analyzeImageUrl(\r\n imageUrl: string,\r\n prompt: string\r\n): Promise<ImageAnalysisResult> {\r\n try {\r\n const provider = providerRegistry.getDefault();\r\n const response = await provider.createMessage({\r\n model: \"claude-sonnet-4-20250514\",\r\n max_tokens: 1024,\r\n messages: [\r\n {\r\n role: \"user\",\r\n content: [\r\n {\r\n type: \"image\",\r\n source: {\r\n type: \"url\",\r\n url: imageUrl,\r\n },\r\n },\r\n {\r\n type: \"text\",\r\n text: prompt || \"Describe this image in detail.\",\r\n },\r\n ],\r\n },\r\n ],\r\n });\r\n\r\n const textContent = response.content.find((c) => c.type === \"text\");\r\n return {\r\n success: true,\r\n analysis: textContent?.text,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n}\r\n\r\n// Analyze image from local file\r\nexport async function analyzeImageFile(\r\n filePath: string,\r\n prompt: string\r\n): Promise<ImageAnalysisResult> {\r\n try {\r\n // Security check\r\n if (!isPathAllowed(filePath)) {\r\n return {\r\n success: false,\r\n error: \"Access to this path is not allowed\",\r\n };\r\n }\r\n\r\n const mimeType = getMimeType(filePath);\r\n if (!mimeType) {\r\n return {\r\n success: false,\r\n error: \"Unsupported image format. Supported: jpg, png, gif, webp\",\r\n };\r\n }\r\n\r\n const imageData = await readFile(filePath);\r\n const base64 = imageData.toString(\"base64\");\r\n\r\n const provider = providerRegistry.getDefault();\r\n const response = await provider.createMessage({\r\n model: \"claude-sonnet-4-20250514\",\r\n max_tokens: 1024,\r\n messages: [\r\n {\r\n role: \"user\",\r\n content: [\r\n {\r\n type: \"image\",\r\n source: {\r\n type: \"base64\",\r\n mediaType: mimeType,\r\n data: base64,\r\n },\r\n },\r\n {\r\n type: \"text\",\r\n text: prompt || \"Describe this image in detail.\",\r\n },\r\n ],\r\n },\r\n ],\r\n });\r\n\r\n const textContent = response.content.find((c) => c.type === \"text\");\r\n return {\r\n success: true,\r\n analysis: textContent?.text,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n}\r\n\r\n// Analyze image from buffer\r\nexport async function analyzeImageBuffer(\r\n imageBuffer: Buffer,\r\n mimeType: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\",\r\n prompt: string\r\n): Promise<ImageAnalysisResult> {\r\n try {\r\n const base64 = imageBuffer.toString(\"base64\");\r\n\r\n const provider = providerRegistry.getDefault();\r\n const response = await provider.createMessage({\r\n model: \"claude-sonnet-4-20250514\",\r\n max_tokens: 1024,\r\n messages: [\r\n {\r\n role: \"user\",\r\n content: [\r\n {\r\n type: \"image\",\r\n source: {\r\n type: \"base64\",\r\n mediaType: mimeType,\r\n data: base64,\r\n },\r\n },\r\n {\r\n type: \"text\",\r\n text: prompt || \"Describe this image in detail.\",\r\n },\r\n ],\r\n },\r\n ],\r\n });\r\n\r\n const textContent = response.content.find((c) => c.type === \"text\");\r\n return {\r\n success: true,\r\n analysis: textContent?.text,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n}\r\n\r\n// Combined function for tool use\r\nexport async function analyzeImage(\r\n options: {\r\n imageUrl?: string;\r\n imagePath?: string;\r\n prompt: string;\r\n }\r\n): Promise<ImageAnalysisResult> {\r\n if (options.imageUrl) {\r\n return analyzeImageUrl(options.imageUrl, options.prompt);\r\n }\r\n\r\n if (options.imagePath) {\r\n return analyzeImageFile(options.imagePath, options.prompt);\r\n }\r\n\r\n return {\r\n success: false,\r\n error: \"Either imageUrl or imagePath must be provided\",\r\n };\r\n}\r\n\r\nexport default {\r\n analyzeImage,\r\n analyzeImageUrl,\r\n analyzeImageFile,\r\n analyzeImageBuffer,\r\n};\r\n","import { readFile } from \"fs/promises\";\r\nimport { isPathAllowed } from \"../utils/paths\";\r\nimport { analyzeImageFile } from \"./image-analysis\";\r\n\r\nexport interface OCRResult {\r\n success: boolean;\r\n text?: string;\r\n confidence?: number;\r\n error?: string;\r\n}\r\n\r\n// OCR using Tesseract.js (local, no API key needed)\r\nexport async function ocrWithTesseract(\r\n filePath: string,\r\n language: string = \"eng\"\r\n): Promise<OCRResult> {\r\n try {\r\n const Tesseract = await import(\"tesseract.js\");\r\n const worker = await Tesseract.createWorker(language);\r\n const { data } = await worker.recognize(filePath);\r\n await worker.terminate();\r\n\r\n return {\r\n success: true,\r\n text: data.text,\r\n confidence: data.confidence / 100,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n error: `Tesseract OCR failed: ${error instanceof Error ? error.message : String(error)}`,\r\n };\r\n }\r\n}\r\n\r\n// Use LLM Vision for OCR (most reliable for complex documents)\r\nexport async function ocrWithVision(\r\n filePath: string,\r\n language?: string\r\n): Promise<OCRResult> {\r\n const prompt = language\r\n ? `Extract all text from this image. The text is in ${language}. Return only the extracted text, preserving the original formatting and layout as much as possible.`\r\n : `Extract all text from this image. Return only the extracted text, preserving the original formatting and layout as much as possible.`;\r\n\r\n const result = await analyzeImageFile(filePath, prompt);\r\n\r\n if (result.success && result.analysis) {\r\n return {\r\n success: true,\r\n text: result.analysis,\r\n };\r\n }\r\n\r\n return {\r\n success: false,\r\n error: result.error || \"Failed to extract text\",\r\n };\r\n}\r\n\r\n// OCR using Tesseract.js as primary, falling back to Vision API\r\nexport async function ocrSimple(filePath: string): Promise<OCRResult> {\r\n const result = await ocrWithTesseract(filePath);\r\n if (result.success && result.confidence && result.confidence > 0.6) {\r\n return result;\r\n }\r\n // Fall back to Vision API on low confidence or failure\r\n return ocrWithVision(filePath);\r\n}\r\n\r\n// OCR for PDF files (extract text from each page)\r\nexport async function ocrPdf(\r\n filePath: string,\r\n pages?: string // e.g., \"1-5\" or \"1,3,5\"\r\n): Promise<OCRResult> {\r\n // For PDFs, we'll use LLM Vision on the file directly\r\n const prompt = `Extract all text from this PDF document. Return the text content, preserving the structure and formatting as much as possible. If there are multiple pages, separate them clearly.`;\r\n\r\n const result = await analyzeImageFile(filePath, prompt);\r\n\r\n if (result.success && result.analysis) {\r\n return {\r\n success: true,\r\n text: result.analysis,\r\n };\r\n }\r\n\r\n return {\r\n success: false,\r\n error: result.error || \"Failed to extract text from PDF\",\r\n };\r\n}\r\n\r\n// Main OCR function that determines the best approach\r\nexport async function performOCR(\r\n filePath: string,\r\n options?: {\r\n language?: string;\r\n useVision?: boolean;\r\n }\r\n): Promise<OCRResult> {\r\n // Security check\r\n if (!isPathAllowed(filePath)) {\r\n return {\r\n success: false,\r\n error: \"Access to this path is not allowed\",\r\n };\r\n }\r\n\r\n const ext = filePath.toLowerCase().slice(filePath.lastIndexOf(\".\"));\r\n\r\n // PDF handling\r\n if (ext === \".pdf\") {\r\n return ocrPdf(filePath);\r\n }\r\n\r\n // Image handling - use Vision API (most accurate)\r\n if ([\".jpg\", \".jpeg\", \".png\", \".gif\", \".webp\", \".bmp\", \".tiff\"].includes(ext)) {\r\n if (options?.useVision !== false) {\r\n return ocrWithVision(filePath, options?.language);\r\n }\r\n return ocrSimple(filePath);\r\n }\r\n\r\n return {\r\n success: false,\r\n error: `Unsupported file type: ${ext}`,\r\n };\r\n}\r\n\r\n// Extract structured data from document (tables, forms)\r\nexport async function extractStructuredData(\r\n filePath: string,\r\n dataType?: \"table\" | \"form\" | \"receipt\" | \"invoice\"\r\n): Promise<{\r\n success: boolean;\r\n data?: Record<string, unknown>;\r\n error?: string;\r\n}> {\r\n const prompts: Record<string, string> = {\r\n table: `Extract all tables from this image. Return the data as JSON arrays where each table is an array of rows, and each row is an array of cell values.`,\r\n form: `Extract all form fields from this image. Return as a JSON object where keys are field labels and values are the filled-in content.`,\r\n receipt: `Extract receipt information from this image. Return as JSON with: store_name, date, items (array with name, quantity, price), subtotal, tax, total.`,\r\n invoice: `Extract invoice information from this image. Return as JSON with: vendor, invoice_number, date, due_date, line_items (array), subtotal, tax, total, billing_address.`,\r\n };\r\n\r\n const prompt = dataType\r\n ? prompts[dataType]\r\n : `Extract any structured data from this image. Return as JSON.`;\r\n\r\n const result = await analyzeImageFile(filePath, prompt);\r\n\r\n if (result.success && result.analysis) {\r\n try {\r\n // Try to parse as JSON\r\n const jsonMatch = result.analysis.match(/```json\\n?([\\s\\S]*?)\\n?```/);\r\n if (jsonMatch) {\r\n return {\r\n success: true,\r\n data: JSON.parse(jsonMatch[1]),\r\n };\r\n }\r\n\r\n // Try direct parse\r\n const data = JSON.parse(result.analysis);\r\n return { success: true, data };\r\n } catch {\r\n // Return raw text if not JSON\r\n return {\r\n success: true,\r\n data: { rawText: result.analysis },\r\n };\r\n }\r\n }\r\n\r\n return {\r\n success: false,\r\n error: result.error || \"Failed to extract structured data\",\r\n };\r\n}\r\n\r\nexport default {\r\n performOCR,\r\n ocrWithVision,\r\n ocrWithTesseract,\r\n extractStructuredData,\r\n};\r\n"],"mappings":"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","names":[]}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
textToSpeech
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-J4JW73TT.js";
|
|
4
4
|
import {
|
|
5
5
|
transcribeAudio
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BNZHWAZC.js";
|
|
7
7
|
import {
|
|
8
8
|
scheduleReminder
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-GJETKBOY.js";
|
|
10
10
|
import {
|
|
11
11
|
chatWithTools
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ZMML6T63.js";
|
|
13
13
|
import {
|
|
14
14
|
env
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-4KIHDIXZ.js";
|
|
16
16
|
|
|
17
17
|
// src/inputs/telegram/bot.ts
|
|
18
18
|
import { Bot, session } from "grammy";
|
|
@@ -259,4 +259,4 @@ Send me a message or voice note to get started!`
|
|
|
259
259
|
export {
|
|
260
260
|
createBot
|
|
261
261
|
};
|
|
262
|
-
//# sourceMappingURL=chunk-
|
|
262
|
+
//# sourceMappingURL=chunk-56UJS2LA.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
env
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4KIHDIXZ.js";
|
|
4
4
|
import {
|
|
5
5
|
schema_exports
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZIBRVA3Y.js";
|
|
7
7
|
|
|
8
8
|
// src/db/index.ts
|
|
9
9
|
import { drizzle } from "drizzle-orm/postgres-js";
|
|
@@ -34,4 +34,4 @@ var db = new Proxy(
|
|
|
34
34
|
export {
|
|
35
35
|
db
|
|
36
36
|
};
|
|
37
|
-
//# sourceMappingURL=chunk-
|
|
37
|
+
//# sourceMappingURL=chunk-5BTVJR7R.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
providerRegistry
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GW6V4D43.js";
|
|
4
4
|
import {
|
|
5
5
|
env
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4KIHDIXZ.js";
|
|
7
7
|
|
|
8
8
|
// src/integrations/github/client.ts
|
|
9
9
|
import { Octokit } from "octokit";
|
|
@@ -1018,4 +1018,4 @@ export {
|
|
|
1018
1018
|
summarizeChanges,
|
|
1019
1019
|
securityScan
|
|
1020
1020
|
};
|
|
1021
|
-
//# sourceMappingURL=chunk-
|
|
1021
|
+
//# sourceMappingURL=chunk-5JJTLWOR.js.map
|