opensentinel 3.1.1 → 3.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -83
- package/dist/agent-manager-7N7REQZQ.js +39 -0
- package/dist/agent-processor-I23VWQY3.js +280 -0
- package/dist/agent-processor-I23VWQY3.js.map +1 -0
- package/dist/agent-types-2T4PXLFQ.js +12 -0
- package/dist/alerting-4I37GG4U.js +699 -0
- package/dist/alerting-4I37GG4U.js.map +1 -0
- package/dist/analysis-agent-JWN2GXYE.js +288 -0
- package/dist/analysis-agent-JWN2GXYE.js.map +1 -0
- package/dist/{archiver-AVNBYCKQ.js → archiver-XLRIIXPY.js} +86 -17
- package/dist/archiver-XLRIIXPY.js.map +1 -0
- package/dist/{audit-logger-OBPR7CRO.js → audit-logger-AU3TMWKI.js} +6 -5
- package/dist/{auth-UOX5K2BE.js → auth-PH5IHISW.js} +2 -2
- package/dist/{autonomy-ZXDBDQUJ.js → autonomy-N7W5XPLX.js} +4 -3
- package/dist/autonomy-N7W5XPLX.js.map +1 -0
- package/dist/{aws-s3-Q4LLZZPD.js → aws-s3-QZMURYXB.js} +2 -2
- package/dist/{backup-restore-PZ7CYYB7.js → backup-restore-72OQTZO3.js} +2 -2
- package/dist/{blocks-R3PODY47.js → blocks-YOWOESDD.js} +4 -4
- package/dist/bot-MU2TJQ3Y.js +46 -0
- package/dist/brain-SLA474EU.js +65 -0
- package/dist/{camera-monitor-M5CYKUU4.js → camera-monitor-LHTUWHEL.js} +2 -2
- package/dist/{charts-V7ARZNKF.js → charts-FJ32GQK7.js} +2 -2
- package/dist/{chunk-6PMVAAA7.js → chunk-2RGPWU77.js} +3 -3
- package/dist/{chunk-TVEWKIK3.js → chunk-2WTKTG2C.js} +2 -2
- package/dist/{chunk-MXAPLSJ5.js → chunk-45YXODSB.js} +2 -2
- package/dist/{chunk-SJSUSJ47.js → chunk-4YJRBMMA.js} +2 -2
- package/dist/chunk-643M3AP5.js +564 -0
- package/dist/chunk-643M3AP5.js.map +1 -0
- package/dist/{chunk-766ASQWE.js → chunk-6JY4HNUH.js} +2413 -2368
- package/dist/chunk-6JY4HNUH.js.map +1 -0
- package/dist/chunk-6LTLIYAQ.js +194 -0
- package/dist/chunk-6LTLIYAQ.js.map +1 -0
- package/dist/chunk-6UZPE35A.js +724 -0
- package/dist/chunk-6UZPE35A.js.map +1 -0
- package/dist/chunk-6W6PTJFT.js +181 -0
- package/dist/chunk-6W6PTJFT.js.map +1 -0
- package/dist/chunk-7MZN73J2.js +162 -0
- package/dist/chunk-7MZN73J2.js.map +1 -0
- package/dist/{chunk-SVAPX2XN.js → chunk-A24GPVLY.js} +9 -7
- package/dist/{chunk-SVAPX2XN.js.map → chunk-A24GPVLY.js.map} +1 -1
- package/dist/chunk-AD6YEH6U.js +3408 -0
- package/dist/chunk-AD6YEH6U.js.map +1 -0
- package/dist/chunk-ADTDYJO7.js +265 -0
- package/dist/chunk-ADTDYJO7.js.map +1 -0
- package/dist/{chunk-WRAKK6K6.js → chunk-AR34B6XR.js} +5 -3
- package/dist/{chunk-WRAKK6K6.js.map → chunk-AR34B6XR.js.map} +1 -1
- package/dist/chunk-BMOUYXLX.js +418 -0
- package/dist/chunk-BMOUYXLX.js.map +1 -0
- package/dist/chunk-C6PELIHS.js +60 -0
- package/dist/chunk-C6PELIHS.js.map +1 -0
- package/dist/{chunk-MQJ2ECQT.js → chunk-CUPEENUY.js} +3 -3
- package/dist/{chunk-RZ4YESBG.js → chunk-DOYGMNMK.js} +1 -1
- package/dist/chunk-DOYGMNMK.js.map +1 -0
- package/dist/chunk-FFV2SXFD.js +380 -0
- package/dist/chunk-FFV2SXFD.js.map +1 -0
- package/dist/{chunk-EVE7MIIY.js → chunk-GUKKW7JI.js} +15 -16
- package/dist/chunk-GUKKW7JI.js.map +1 -0
- package/dist/{chunk-66OJ3WB4.js → chunk-H3BOLSTS.js} +2 -2
- package/dist/chunk-HKOPRRDJ.js +1021 -0
- package/dist/chunk-HKOPRRDJ.js.map +1 -0
- package/dist/{chunk-BXZ6EA52.js → chunk-HTF2GIQC.js} +57 -3
- package/dist/chunk-HTF2GIQC.js.map +1 -0
- package/dist/{chunk-TYAGMJNV.js → chunk-JOA5A3G3.js} +5 -5
- package/dist/{chunk-OCVQGBJK.js → chunk-KABG5PG3.js} +6 -4
- package/dist/{chunk-OCVQGBJK.js.map → chunk-KABG5PG3.js.map} +1 -1
- package/dist/{chunk-VEHFVBLI.js → chunk-KT7NLIXP.js} +2 -2
- package/dist/chunk-LFDXEYYB.js +150 -0
- package/dist/chunk-LFDXEYYB.js.map +1 -0
- package/dist/{chunk-I6BDYQIG.js → chunk-M7YLQHFP.js} +6 -6
- package/dist/chunk-M7YLQHFP.js.map +1 -0
- package/dist/{chunk-AYUKPTSM.js → chunk-MFK34XSY.js} +96 -218
- package/dist/chunk-MFK34XSY.js.map +1 -0
- package/dist/chunk-MIC5IBQF.js +386 -0
- package/dist/chunk-MIC5IBQF.js.map +1 -0
- package/dist/{chunk-4UOE5TUZ.js → chunk-NMSHVO5O.js} +4 -4
- package/dist/{chunk-XKYRH4FM.js → chunk-NYVBXUGD.js} +13 -32
- package/dist/chunk-NYVBXUGD.js.map +1 -0
- package/dist/chunk-ODCFS5WD.js +463 -0
- package/dist/chunk-ODCFS5WD.js.map +1 -0
- package/dist/{chunk-ZLZKF2PM.js → chunk-PUNIMPMY.js} +32 -2
- package/dist/chunk-PUNIMPMY.js.map +1 -0
- package/dist/chunk-S4NJJS5C.js +37 -0
- package/dist/chunk-S4NJJS5C.js.map +1 -0
- package/dist/{chunk-NHMBTUMW.js → chunk-TAAZB5KN.js} +2 -2
- package/dist/{chunk-BRBWNV65.js → chunk-U2X2J3FI.js} +3 -3
- package/dist/chunk-U2X2J3FI.js.map +1 -0
- package/dist/{chunk-PLDDJCW6.js → chunk-UP2VWCW5.js} +1 -12
- package/dist/{chunk-4GLYY4NN.js → chunk-UWUIJTT4.js} +8 -2
- package/dist/chunk-UWUIJTT4.js.map +1 -0
- package/dist/{chunk-SPPMCAKG.js → chunk-VKMFUIVA.js} +2 -2
- package/dist/chunk-VKMFUIVA.js.map +1 -0
- package/dist/chunk-WZAH34TG.js +129 -0
- package/dist/chunk-WZAH34TG.js.map +1 -0
- package/dist/{chunk-H5RQOFO2.js → chunk-X6Q3K3L2.js} +6 -6
- package/dist/chunk-X6Q3K3L2.js.map +1 -0
- package/dist/chunk-XTX7EK43.js +134 -0
- package/dist/chunk-XTX7EK43.js.map +1 -0
- package/dist/chunk-ZIYTHUM5.js +457 -0
- package/dist/chunk-ZIYTHUM5.js.map +1 -0
- package/dist/chunker-K6WTR62A.js +12 -0
- package/dist/cli.js +1 -1
- package/dist/{client-ZQSFPMOB.js → client-FOIYPOZQ.js} +5 -6
- package/dist/{clipboard-manager-TEO2GEDN.js → clipboard-manager-4SBNESGZ.js} +2 -2
- package/dist/coding-agent-DESSU3AC.js +233 -0
- package/dist/coding-agent-DESSU3AC.js.map +1 -0
- 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 +11 -0
- package/dist/{cron-explain-HHQKPD3M.js → cron-explain-UOOOYWZZ.js} +2 -2
- package/dist/{crypto-4AP47IKC.js → crypto-2VG3RJR2.js} +2 -2
- package/dist/{databases-37X4CI2Y.js → databases-XDPMG5AV.js} +4 -4
- package/dist/db-LRIOKQBO.js +77 -0
- package/dist/discord-NKR3X4AV.js +80 -0
- package/dist/documents-EYIYLZK2.js +184 -0
- package/dist/documents-EYIYLZK2.js.map +1 -0
- package/dist/docx-parser-EXL4TN5E.js +16 -0
- package/dist/{email-K7LO2IPB.js → email-EAQNULVD.js} +33 -25
- package/dist/{email-K7LO2IPB.js.map → email-EAQNULVD.js.map} +1 -1
- package/dist/{enhanced-retrieval-DNLLEM4Z.js → enhanced-retrieval-OGHT6TS5.js} +11 -8
- package/dist/{enhanced-retrieval-DNLLEM4Z.js.map → enhanced-retrieval-OGHT6TS5.js.map} +1 -1
- package/dist/enrichment-pipeline-CMUVBDC7.js +14 -0
- package/dist/{entity-resolution-Y3IUWEAT.js → entity-resolution-4X4JU43O.js} +6 -5
- package/dist/env-CHOFICED.js +12 -0
- package/dist/error-tracker-SVQSDQDW.js +32 -0
- package/dist/finnhub-X7ZMQSXF.js +178 -0
- package/dist/finnhub-X7ZMQSXF.js.map +1 -0
- package/dist/fred-TMUF3J2V.js +203 -0
- package/dist/fred-TMUF3J2V.js.map +1 -0
- package/dist/github-KGNILDWJ.js +833 -0
- package/dist/github-KGNILDWJ.js.map +1 -0
- package/dist/{google-workspace-DKWUVNGC.js → google-workspace-TSZPZK5G.js} +2 -2
- package/dist/{hash-tool-ULQYD7B5.js → hash-tool-ENAB5LWH.js} +2 -2
- package/dist/{heartbeat-monitor-GCISLXI3.js → heartbeat-monitor-KRDYTDBF.js} +2 -2
- package/dist/hooks-N4MIFBVM.js +14 -0
- package/dist/{image-generation-OSU7FP6F.js → image-generation-MDE6AVQO.js} +2 -2
- package/dist/imessage-V2XNDDHT.js +43 -0
- package/dist/inbox-summarizer-DKKRYXDR.js +55 -0
- package/dist/{incident-response-C5J7Q6DT.js → incident-response-ZTIKUWEO.js} +8 -6
- package/dist/{incident-response-C5J7Q6DT.js.map → incident-response-ZTIKUWEO.js.map} +1 -1
- package/dist/{inventory-manager-352OHXWD.js → inventory-manager-C67BSZM6.js} +2 -2
- package/dist/{jira-GSGDBMIG.js → jira-PAGZWUBJ.js} +2 -2
- package/dist/{json-tool-QE2SYHEG.js → json-tool-4FK5RNER.js} +2 -2
- package/dist/{key-rotation-DPHU4ZTB.js → key-rotation-WCC5FOYS.js} +2 -2
- package/dist/knowledge-base-J7PJ7MZ3.js +46 -0
- package/dist/lib.d.ts +73 -1
- package/dist/lib.js +86 -76
- package/dist/lib.js.map +1 -1
- package/dist/{mailchimp-KKNF6QJ7.js → mailchimp-ZFYDC44J.js} +2 -2
- package/dist/{matrix-QVHG76I7.js → matrix-XHTR53VQ.js} +29 -21
- package/dist/{matrix-QVHG76I7.js.map → matrix-XHTR53VQ.js.map} +1 -1
- package/dist/{mcp-3JI6W7ZE.js → mcp-3C2TN67D.js} +3 -3
- package/dist/metrics-VJDWQWU7.js +25 -0
- package/dist/{microsoft365-UCBKJHNX.js → microsoft365-6G2IJMWC.js} +2 -2
- package/dist/multi-user-S56GUD6L.js +411 -0
- package/dist/multi-user-S56GUD6L.js.map +1 -0
- package/dist/{ocr-AC7NPX33.js → ocr-LGUIPKVZ.js} +6 -4
- package/dist/{ollama-BOAMSPLJ.js → ollama-J7CU45WT.js} +2 -2
- package/dist/osint-agent-RL5XPBRQ.js +189 -0
- package/dist/osint-agent-RL5XPBRQ.js.map +1 -0
- package/dist/{pages-MI523RB7.js → pages-XDE7JRCA.js} +5 -5
- package/dist/{pair-JDFTERIK.js → pair-YZJFQUU5.js} +2 -2
- package/dist/{pairing-IFQYCPNS.js → pairing-77N47RAT.js} +2 -2
- package/dist/{pdf-ALQVOEJR.js → pdf-67HGXCFJ.js} +3 -3
- package/dist/pdf-parser-YLMTTYHL.js +14 -0
- package/dist/{presentations-DSV5IHG5.js → presentations-HXTAMGHT.js} +3 -3
- package/dist/presentations-HXTAMGHT.js.map +1 -0
- package/dist/{prometheus-JNT2BD4L.js → prometheus-YETCZO4I.js} +2 -2
- package/dist/{providers-J4LYPHDR.js → providers-H6YIC3MG.js} +6 -4
- package/dist/{qr-code-WIX4PB4U.js → qr-code-6WZJHRKL.js} +2 -2
- package/dist/{quickbooks-XB4NII2S.js → quickbooks-N675W7IK.js} +2 -2
- package/dist/{regex-tool-W4ABRKGK.js → regex-tool-6Q63LQ7B.js} +2 -2
- package/dist/regex-tool-6Q63LQ7B.js.map +1 -0
- package/dist/research-agent-WCRSY3UZ.js +168 -0
- package/dist/research-agent-WCRSY3UZ.js.map +1 -0
- package/dist/risk-engine-YKCPT5D5.js +10 -0
- package/dist/risk-engine-YKCPT5D5.js.map +1 -0
- package/dist/scheduler-CA5UNHZV.js +73 -0
- package/dist/scheduler-CA5UNHZV.js.map +1 -0
- package/dist/schema-ALJ67YVG.js +72 -0
- package/dist/schema-ALJ67YVG.js.map +1 -0
- package/dist/{search-BCLBO5E3.js → search-GMLKBHSW.js} +4 -4
- package/dist/search-GMLKBHSW.js.map +1 -0
- package/dist/{sendgrid-RNXCAFKM.js → sendgrid-QGJIVPWV.js} +2 -2
- package/dist/{shopify-NCXYJB4R.js → shopify-ON2PAU27.js} +2 -2
- package/dist/signal-X7IQJGRQ.js +43 -0
- package/dist/signal-X7IQJGRQ.js.map +1 -0
- package/dist/slack-P2LFUJUQ.js +85 -0
- package/dist/slack-P2LFUJUQ.js.map +1 -0
- package/dist/{sms-M3JIOTCW.js → sms-4VME2HUL.js} +4 -4
- package/dist/sms-4VME2HUL.js.map +1 -0
- package/dist/{src-VYUE6LRA.js → src-S5KX4YEV.js} +179 -48
- package/dist/src-S5KX4YEV.js.map +1 -0
- package/dist/{stocks-XXWBPOCU.js → stocks-4M4HZWZS.js} +2 -2
- package/dist/stocks-4M4HZWZS.js.map +1 -0
- package/dist/text-extractor-OAUBAW5P.js +12 -0
- package/dist/text-extractor-OAUBAW5P.js.map +1 -0
- package/dist/{text-transform-6SGUA5Z4.js → text-transform-HCLCUDFZ.js} +2 -2
- package/dist/text-transform-HCLCUDFZ.js.map +1 -0
- package/dist/tools-FGPN522P.js +46 -0
- package/dist/tools-FGPN522P.js.map +1 -0
- package/dist/{tunnel-IWMXUML4.js → tunnel-XOUVVRAK.js} +4 -2
- package/dist/tunnel-XOUVVRAK.js.map +1 -0
- package/dist/{twilio-53GEW5JT.js → twilio-3L7DUNYQ.js} +2 -2
- package/dist/{unit-converter-ZYXMEZOE.js → unit-converter-LYPAHU64.js} +2 -2
- package/dist/unit-converter-LYPAHU64.js.map +1 -0
- package/dist/whatsapp-KRPQ4YUX.js +43 -0
- package/dist/whatsapp-KRPQ4YUX.js.map +1 -0
- package/dist/{word-document-7B6SJMAY.js → word-document-D6N2C47N.js} +4 -4
- package/dist/word-document-D6N2C47N.js.map +1 -0
- package/dist/workflow-store-ZYAYE5P6.js +373 -0
- package/dist/workflow-store-ZYAYE5P6.js.map +1 -0
- package/dist/writing-agent-VDGLNOGO.js +243 -0
- package/dist/writing-agent-VDGLNOGO.js.map +1 -0
- package/dist/{xero-QYO66D45.js → xero-UHAHVYSD.js} +2 -2
- package/dist/{zapier-webhook-TBZ5YF2A.js → zapier-webhook-NIELLTXR.js} +2 -2
- package/package.json +11 -1
- package/dist/archiver-AVNBYCKQ.js.map +0 -1
- package/dist/autonomy-ZXDBDQUJ.js.map +0 -1
- package/dist/bot-QRARP4UN.js +0 -36
- package/dist/brain-7XLLM3KC.js +0 -56
- package/dist/chunk-4GLYY4NN.js.map +0 -1
- package/dist/chunk-766ASQWE.js.map +0 -1
- package/dist/chunk-AYUKPTSM.js.map +0 -1
- package/dist/chunk-BRBWNV65.js.map +0 -1
- package/dist/chunk-BXZ6EA52.js.map +0 -1
- package/dist/chunk-EVE7MIIY.js.map +0 -1
- package/dist/chunk-H5RQOFO2.js.map +0 -1
- package/dist/chunk-I6BDYQIG.js.map +0 -1
- package/dist/chunk-IZJMVV7O.js +0 -347
- package/dist/chunk-IZJMVV7O.js.map +0 -1
- package/dist/chunk-O7IH7JTI.js +0 -1898
- package/dist/chunk-O7IH7JTI.js.map +0 -1
- package/dist/chunk-RZ4YESBG.js.map +0 -1
- package/dist/chunk-SPPMCAKG.js.map +0 -1
- package/dist/chunk-VRD5CYRL.js +0 -1568
- package/dist/chunk-VRD5CYRL.js.map +0 -1
- package/dist/chunk-XKYRH4FM.js.map +0 -1
- package/dist/chunk-ZLZKF2PM.js.map +0 -1
- package/dist/discord-B3HUPGQ6.js +0 -70
- package/dist/dist-UISMLMFN.js +0 -21847
- package/dist/dist-UISMLMFN.js.map +0 -1
- package/dist/enrichment-pipeline-MNHNW65K.js +0 -13
- package/dist/env-IWXUVTCB.js +0 -12
- package/dist/imessage-NGA2XF2V.js +0 -35
- package/dist/inbox-summarizer-NRI4S7IF.js +0 -47
- package/dist/presentations-DSV5IHG5.js.map +0 -1
- package/dist/scheduler-VK4WFERV.js +0 -63
- package/dist/signal-6CGDFYL2.js +0 -35
- package/dist/slack-IZQWIKOH.js +0 -75
- package/dist/src-VYUE6LRA.js.map +0 -1
- package/dist/tools-2RLEI2N6.js +0 -38
- package/dist/tunnel-IWMXUML4.js.map +0 -1
- package/dist/whatsapp-LFX6YKCM.js +0 -35
- package/dist/word-document-7B6SJMAY.js.map +0 -1
- /package/dist/{audit-logger-OBPR7CRO.js.map → agent-manager-7N7REQZQ.js.map} +0 -0
- /package/dist/{auth-UOX5K2BE.js.map → agent-types-2T4PXLFQ.js.map} +0 -0
- /package/dist/{backup-restore-PZ7CYYB7.js.map → audit-logger-AU3TMWKI.js.map} +0 -0
- /package/dist/{blocks-R3PODY47.js.map → auth-PH5IHISW.js.map} +0 -0
- /package/dist/{aws-s3-Q4LLZZPD.js.map → aws-s3-QZMURYXB.js.map} +0 -0
- /package/dist/{bot-QRARP4UN.js.map → backup-restore-72OQTZO3.js.map} +0 -0
- /package/dist/{brain-7XLLM3KC.js.map → blocks-YOWOESDD.js.map} +0 -0
- /package/dist/{chunk-PLDDJCW6.js.map → bot-MU2TJQ3Y.js.map} +0 -0
- /package/dist/{client-ZQSFPMOB.js.map → brain-SLA474EU.js.map} +0 -0
- /package/dist/{camera-monitor-M5CYKUU4.js.map → camera-monitor-LHTUWHEL.js.map} +0 -0
- /package/dist/{charts-V7ARZNKF.js.map → charts-FJ32GQK7.js.map} +0 -0
- /package/dist/{chunk-6PMVAAA7.js.map → chunk-2RGPWU77.js.map} +0 -0
- /package/dist/{chunk-TVEWKIK3.js.map → chunk-2WTKTG2C.js.map} +0 -0
- /package/dist/{chunk-MXAPLSJ5.js.map → chunk-45YXODSB.js.map} +0 -0
- /package/dist/{chunk-SJSUSJ47.js.map → chunk-4YJRBMMA.js.map} +0 -0
- /package/dist/{chunk-MQJ2ECQT.js.map → chunk-CUPEENUY.js.map} +0 -0
- /package/dist/{chunk-66OJ3WB4.js.map → chunk-H3BOLSTS.js.map} +0 -0
- /package/dist/{chunk-TYAGMJNV.js.map → chunk-JOA5A3G3.js.map} +0 -0
- /package/dist/{chunk-VEHFVBLI.js.map → chunk-KT7NLIXP.js.map} +0 -0
- /package/dist/{chunk-4UOE5TUZ.js.map → chunk-NMSHVO5O.js.map} +0 -0
- /package/dist/{chunk-NHMBTUMW.js.map → chunk-TAAZB5KN.js.map} +0 -0
- /package/dist/{clipboard-manager-TEO2GEDN.js.map → chunk-UP2VWCW5.js.map} +0 -0
- /package/dist/{cron-explain-HHQKPD3M.js.map → chunker-K6WTR62A.js.map} +0 -0
- /package/dist/{crypto-4AP47IKC.js.map → client-FOIYPOZQ.js.map} +0 -0
- /package/dist/{databases-37X4CI2Y.js.map → clipboard-manager-4SBNESGZ.js.map} +0 -0
- /package/dist/{discord-B3HUPGQ6.js.map → cost-tracker-EMOIOYH7.js.map} +0 -0
- /package/dist/{enrichment-pipeline-MNHNW65K.js.map → cron-explain-UOOOYWZZ.js.map} +0 -0
- /package/dist/{entity-resolution-Y3IUWEAT.js.map → crypto-2VG3RJR2.js.map} +0 -0
- /package/dist/{env-IWXUVTCB.js.map → databases-XDPMG5AV.js.map} +0 -0
- /package/dist/{hash-tool-ULQYD7B5.js.map → db-LRIOKQBO.js.map} +0 -0
- /package/dist/{heartbeat-monitor-GCISLXI3.js.map → discord-NKR3X4AV.js.map} +0 -0
- /package/dist/{imessage-NGA2XF2V.js.map → docx-parser-EXL4TN5E.js.map} +0 -0
- /package/dist/{inbox-summarizer-NRI4S7IF.js.map → enrichment-pipeline-CMUVBDC7.js.map} +0 -0
- /package/dist/{inventory-manager-352OHXWD.js.map → entity-resolution-4X4JU43O.js.map} +0 -0
- /package/dist/{json-tool-QE2SYHEG.js.map → env-CHOFICED.js.map} +0 -0
- /package/dist/{key-rotation-DPHU4ZTB.js.map → error-tracker-SVQSDQDW.js.map} +0 -0
- /package/dist/{google-workspace-DKWUVNGC.js.map → google-workspace-TSZPZK5G.js.map} +0 -0
- /package/dist/{mcp-3JI6W7ZE.js.map → hash-tool-ENAB5LWH.js.map} +0 -0
- /package/dist/{ocr-AC7NPX33.js.map → heartbeat-monitor-KRDYTDBF.js.map} +0 -0
- /package/dist/{ollama-BOAMSPLJ.js.map → hooks-N4MIFBVM.js.map} +0 -0
- /package/dist/{image-generation-OSU7FP6F.js.map → image-generation-MDE6AVQO.js.map} +0 -0
- /package/dist/{pages-MI523RB7.js.map → imessage-V2XNDDHT.js.map} +0 -0
- /package/dist/{pairing-IFQYCPNS.js.map → inbox-summarizer-DKKRYXDR.js.map} +0 -0
- /package/dist/{pdf-ALQVOEJR.js.map → inventory-manager-C67BSZM6.js.map} +0 -0
- /package/dist/{jira-GSGDBMIG.js.map → jira-PAGZWUBJ.js.map} +0 -0
- /package/dist/{prometheus-JNT2BD4L.js.map → json-tool-4FK5RNER.js.map} +0 -0
- /package/dist/{providers-J4LYPHDR.js.map → key-rotation-WCC5FOYS.js.map} +0 -0
- /package/dist/{qr-code-WIX4PB4U.js.map → knowledge-base-J7PJ7MZ3.js.map} +0 -0
- /package/dist/{mailchimp-KKNF6QJ7.js.map → mailchimp-ZFYDC44J.js.map} +0 -0
- /package/dist/{regex-tool-W4ABRKGK.js.map → mcp-3C2TN67D.js.map} +0 -0
- /package/dist/{scheduler-VK4WFERV.js.map → metrics-VJDWQWU7.js.map} +0 -0
- /package/dist/{microsoft365-UCBKJHNX.js.map → microsoft365-6G2IJMWC.js.map} +0 -0
- /package/dist/{search-BCLBO5E3.js.map → ocr-LGUIPKVZ.js.map} +0 -0
- /package/dist/{signal-6CGDFYL2.js.map → ollama-J7CU45WT.js.map} +0 -0
- /package/dist/{slack-IZQWIKOH.js.map → pages-XDE7JRCA.js.map} +0 -0
- /package/dist/{pair-JDFTERIK.js.map → pair-YZJFQUU5.js.map} +0 -0
- /package/dist/{sms-M3JIOTCW.js.map → pairing-77N47RAT.js.map} +0 -0
- /package/dist/{stocks-XXWBPOCU.js.map → pdf-67HGXCFJ.js.map} +0 -0
- /package/dist/{text-transform-6SGUA5Z4.js.map → pdf-parser-YLMTTYHL.js.map} +0 -0
- /package/dist/{tools-2RLEI2N6.js.map → prometheus-YETCZO4I.js.map} +0 -0
- /package/dist/{unit-converter-ZYXMEZOE.js.map → providers-H6YIC3MG.js.map} +0 -0
- /package/dist/{whatsapp-LFX6YKCM.js.map → qr-code-6WZJHRKL.js.map} +0 -0
- /package/dist/{quickbooks-XB4NII2S.js.map → quickbooks-N675W7IK.js.map} +0 -0
- /package/dist/{sendgrid-RNXCAFKM.js.map → sendgrid-QGJIVPWV.js.map} +0 -0
- /package/dist/{shopify-NCXYJB4R.js.map → shopify-ON2PAU27.js.map} +0 -0
- /package/dist/{twilio-53GEW5JT.js.map → twilio-3L7DUNYQ.js.map} +0 -0
- /package/dist/{xero-QYO66D45.js.map → xero-UHAHVYSD.js.map} +0 -0
- /package/dist/{zapier-webhook-TBZ5YF2A.js.map → zapier-webhook-NIELLTXR.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/integrations/github/client.ts","../src/integrations/github/pull-requests.ts","../src/integrations/github/code-review.ts"],"sourcesContent":["/**\n * GitHub API Client\n *\n * Provides authenticated access to the GitHub API using Octokit.\n */\n\nimport { Octokit } from \"octokit\";\nimport { env } from \"../../config/env\";\n\nexport interface GitHubClientConfig {\n token?: string;\n baseUrl?: string;\n}\n\nlet octokitInstance: Octokit | null = null;\n\n/**\n * Get or create the Octokit instance\n */\nexport function getOctokit(config?: GitHubClientConfig): Octokit {\n const token = config?.token || env.GITHUB_TOKEN;\n\n if (!token) {\n throw new Error(\"GitHub token is required. Set GITHUB_TOKEN environment variable.\");\n }\n\n if (!octokitInstance || config?.token) {\n octokitInstance = new Octokit({\n auth: token,\n baseUrl: config?.baseUrl,\n });\n }\n\n return octokitInstance;\n}\n\n/**\n * Create a new Octokit instance with specific config\n */\nexport function createOctokit(config: GitHubClientConfig): Octokit {\n const token = config.token || env.GITHUB_TOKEN;\n\n if (!token) {\n throw new Error(\"GitHub token is required.\");\n }\n\n return new Octokit({\n auth: token,\n baseUrl: config.baseUrl,\n });\n}\n\n/**\n * Get authenticated user information\n */\nexport async function getAuthenticatedUser(config?: GitHubClientConfig): Promise<{\n login: string;\n id: number;\n name: string | null;\n email: string | null;\n avatarUrl: string;\n}> {\n const octokit = getOctokit(config);\n\n const { data } = await octokit.rest.users.getAuthenticated();\n\n return {\n login: data.login,\n id: data.id,\n name: data.name,\n email: data.email,\n avatarUrl: data.avatar_url,\n };\n}\n\n/**\n * Check rate limit status\n */\nexport async function getRateLimit(config?: GitHubClientConfig): Promise<{\n limit: number;\n remaining: number;\n reset: Date;\n used: number;\n}> {\n const octokit = getOctokit(config);\n\n const { data } = await octokit.rest.rateLimit.get();\n\n return {\n limit: data.rate.limit,\n remaining: data.rate.remaining,\n reset: new Date(data.rate.reset * 1000),\n used: data.rate.used,\n };\n}\n\n/**\n * Parse owner and repo from a repository URL or string\n */\nexport function parseRepoString(repoString: string): { owner: string; repo: string } {\n // Handle full GitHub URLs\n if (repoString.includes(\"github.com\")) {\n const match = repoString.match(/github\\.com[/:]([\\w.-]+)\\/([\\w.-]+)/);\n if (match) {\n return { owner: match[1], repo: match[2].replace(/\\.git$/, \"\") };\n }\n }\n\n // Handle owner/repo format\n const parts = repoString.split(\"/\");\n if (parts.length === 2) {\n return { owner: parts[0], repo: parts[1] };\n }\n\n throw new Error(`Invalid repository string: ${repoString}. Expected format: owner/repo or GitHub URL`);\n}\n\nexport { Octokit };\n","/**\r\n * GitHub Pull Request Operations\r\n *\r\n * Provides functions for creating, reviewing, and merging pull requests.\r\n */\r\n\r\nimport { getOctokit, parseRepoString, type GitHubClientConfig } from \"./client\";\r\n\r\nexport interface PullRequest {\r\n id: number;\r\n number: number;\r\n title: string;\r\n body: string | null;\r\n state: \"open\" | \"closed\";\r\n htmlUrl: string;\r\n diffUrl: string;\r\n patchUrl: string;\r\n draft: boolean;\r\n merged: boolean;\r\n mergeable: boolean | null;\r\n mergeableState: string;\r\n mergedAt: string | null;\r\n mergedBy: {\r\n login: string;\r\n id: number;\r\n avatarUrl: string;\r\n } | null;\r\n user: {\r\n login: string;\r\n id: number;\r\n avatarUrl: string;\r\n } | null;\r\n head: {\r\n ref: string;\r\n sha: string;\r\n repo: {\r\n fullName: string;\r\n cloneUrl: string;\r\n } | null;\r\n };\r\n base: {\r\n ref: string;\r\n sha: string;\r\n repo: {\r\n fullName: string;\r\n cloneUrl: string;\r\n } | null;\r\n };\r\n labels: Array<{\r\n id: number;\r\n name: string;\r\n color: string;\r\n description: string | null;\r\n }>;\r\n assignees: Array<{\r\n login: string;\r\n id: number;\r\n avatarUrl: string;\r\n }>;\r\n requestedReviewers: Array<{\r\n login: string;\r\n id: number;\r\n avatarUrl: string;\r\n }>;\r\n requestedTeams: Array<{\r\n id: number;\r\n name: string;\r\n slug: string;\r\n }>;\r\n milestone: {\r\n id: number;\r\n number: number;\r\n title: string;\r\n state: string;\r\n } | null;\r\n additions: number;\r\n deletions: number;\r\n changedFiles: number;\r\n commits: number;\r\n comments: number;\r\n reviewComments: number;\r\n createdAt: string;\r\n updatedAt: string;\r\n closedAt: string | null;\r\n}\r\n\r\nexport interface PullRequestReview {\r\n id: number;\r\n user: {\r\n login: string;\r\n id: number;\r\n avatarUrl: string;\r\n } | null;\r\n body: string | null;\r\n state: \"APPROVED\" | \"CHANGES_REQUESTED\" | \"COMMENTED\" | \"DISMISSED\" | \"PENDING\";\r\n htmlUrl: string;\r\n submittedAt: string | null;\r\n commitId: string;\r\n}\r\n\r\nexport interface ReviewComment {\r\n id: number;\r\n pullRequestReviewId: number | null;\r\n diffHunk: string;\r\n path: string;\r\n position: number | null;\r\n originalPosition: number | null;\r\n commitId: string;\r\n originalCommitId: string;\r\n user: {\r\n login: string;\r\n id: number;\r\n avatarUrl: string;\r\n } | null;\r\n body: string;\r\n htmlUrl: string;\r\n createdAt: string;\r\n updatedAt: string;\r\n line: number | null;\r\n side: \"LEFT\" | \"RIGHT\";\r\n startLine: number | null;\r\n startSide: \"LEFT\" | \"RIGHT\" | null;\r\n inReplyToId: number | null;\r\n}\r\n\r\nexport interface PullRequestFile {\r\n sha: string;\r\n filename: string;\r\n status: \"added\" | \"removed\" | \"modified\" | \"renamed\" | \"copied\" | \"changed\" | \"unchanged\";\r\n additions: number;\r\n deletions: number;\r\n changes: number;\r\n blobUrl: string;\r\n rawUrl: string;\r\n contentsUrl: string;\r\n patch?: string;\r\n previousFilename?: string;\r\n}\r\n\r\nexport interface CreatePullRequestOptions {\r\n title: string;\r\n body?: string;\r\n head: string;\r\n base: string;\r\n draft?: boolean;\r\n maintainerCanModify?: boolean;\r\n}\r\n\r\nexport interface UpdatePullRequestOptions {\r\n title?: string;\r\n body?: string;\r\n state?: \"open\" | \"closed\";\r\n base?: string;\r\n maintainerCanModify?: boolean;\r\n}\r\n\r\nexport interface ListPullRequestsOptions {\r\n state?: \"open\" | \"closed\" | \"all\";\r\n head?: string;\r\n base?: string;\r\n sort?: \"created\" | \"updated\" | \"popularity\" | \"long-running\";\r\n direction?: \"asc\" | \"desc\";\r\n perPage?: number;\r\n page?: number;\r\n}\r\n\r\nexport interface CreateReviewOptions {\r\n commitId?: string;\r\n body?: string;\r\n event?: \"APPROVE\" | \"REQUEST_CHANGES\" | \"COMMENT\";\r\n comments?: Array<{\r\n path: string;\r\n position?: number;\r\n body: string;\r\n line?: number;\r\n side?: \"LEFT\" | \"RIGHT\";\r\n startLine?: number;\r\n startSide?: \"LEFT\" | \"RIGHT\";\r\n }>;\r\n}\r\n\r\nexport interface MergeOptions {\r\n commitTitle?: string;\r\n commitMessage?: string;\r\n sha?: string;\r\n mergeMethod?: \"merge\" | \"squash\" | \"rebase\";\r\n}\r\n\r\n/**\r\n * List pull requests for a repository\r\n */\r\nexport async function listPullRequests(\r\n repoString: string,\r\n options: ListPullRequestsOptions = {},\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest[]> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.list({\r\n owner,\r\n repo,\r\n state: options.state || \"open\",\r\n head: options.head,\r\n base: options.base,\r\n sort: options.sort || \"created\",\r\n direction: options.direction || \"desc\",\r\n per_page: options.perPage || 30,\r\n page: options.page || 1,\r\n });\r\n\r\n return data.map(mapPullRequest);\r\n}\r\n\r\n/**\r\n * Get a specific pull request by number\r\n */\r\nexport async function getPullRequest(\r\n repoString: string,\r\n prNumber: number,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.get({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n });\r\n\r\n return mapPullRequest(data);\r\n}\r\n\r\n/**\r\n * Create a new pull request\r\n */\r\nexport async function createPullRequest(\r\n repoString: string,\r\n options: CreatePullRequestOptions,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.create({\r\n owner,\r\n repo,\r\n title: options.title,\r\n body: options.body,\r\n head: options.head,\r\n base: options.base,\r\n draft: options.draft,\r\n maintainer_can_modify: options.maintainerCanModify,\r\n });\r\n\r\n return mapPullRequest(data);\r\n}\r\n\r\n/**\r\n * Update a pull request\r\n */\r\nexport async function updatePullRequest(\r\n repoString: string,\r\n prNumber: number,\r\n options: UpdatePullRequestOptions,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.update({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n title: options.title,\r\n body: options.body,\r\n state: options.state,\r\n base: options.base,\r\n maintainer_can_modify: options.maintainerCanModify,\r\n });\r\n\r\n return mapPullRequest(data);\r\n}\r\n\r\n/**\r\n * Close a pull request without merging\r\n */\r\nexport async function closePullRequest(\r\n repoString: string,\r\n prNumber: number,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest> {\r\n return updatePullRequest(repoString, prNumber, { state: \"closed\" }, config);\r\n}\r\n\r\n/**\r\n * Reopen a closed pull request\r\n */\r\nexport async function reopenPullRequest(\r\n repoString: string,\r\n prNumber: number,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest> {\r\n return updatePullRequest(repoString, prNumber, { state: \"open\" }, config);\r\n}\r\n\r\n/**\r\n * Mark a pull request as ready for review (remove draft status)\r\n */\r\nexport async function markReadyForReview(\r\n repoString: string,\r\n prNumber: number,\r\n config?: GitHubClientConfig\r\n): Promise<void> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n // Use GraphQL API for this as REST doesn't support it\r\n await octokit.graphql(`\r\n mutation($pullRequestId: ID!) {\r\n markPullRequestReadyForReview(input: {pullRequestId: $pullRequestId}) {\r\n pullRequest {\r\n id\r\n }\r\n }\r\n }\r\n `, {\r\n pullRequestId: `PR_${Buffer.from(`010:PullRequest${await getPullRequestNodeId(octokit, owner, repo, prNumber)}`).toString(\"base64\")}`,\r\n }).catch(async () => {\r\n // Fallback: Get node ID properly\r\n const pr = await getPullRequest(repoString, prNumber, config);\r\n // If fallback is needed, the PR might already be ready or we don't have permission\r\n console.log(\"PR may already be ready for review or permissions are insufficient\");\r\n });\r\n}\r\n\r\n/**\r\n * Convert a pull request to draft\r\n */\r\nexport async function convertToDraft(\r\n repoString: string,\r\n prNumber: number,\r\n config?: GitHubClientConfig\r\n): Promise<void> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n // This requires GraphQL API\r\n const { repository } = await octokit.graphql<{ repository: { pullRequest: { id: string } } }>(`\r\n query($owner: String!, $repo: String!, $number: Int!) {\r\n repository(owner: $owner, name: $repo) {\r\n pullRequest(number: $number) {\r\n id\r\n }\r\n }\r\n }\r\n `, { owner, repo, number: prNumber });\r\n\r\n await octokit.graphql(`\r\n mutation($pullRequestId: ID!) {\r\n convertPullRequestToDraft(input: {pullRequestId: $pullRequestId}) {\r\n pullRequest {\r\n id\r\n }\r\n }\r\n }\r\n `, { pullRequestId: repository.pullRequest.id });\r\n}\r\n\r\n/**\r\n * Request reviewers for a pull request\r\n */\r\nexport async function requestReviewers(\r\n repoString: string,\r\n prNumber: number,\r\n reviewers: string[],\r\n teamReviewers?: string[],\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.requestReviewers({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n reviewers,\r\n team_reviewers: teamReviewers,\r\n });\r\n\r\n return mapPullRequest(data);\r\n}\r\n\r\n/**\r\n * Remove review request\r\n */\r\nexport async function removeReviewRequest(\r\n repoString: string,\r\n prNumber: number,\r\n reviewers: string[],\r\n teamReviewers?: string[],\r\n config?: GitHubClientConfig\r\n): Promise<PullRequest> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.removeRequestedReviewers({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n reviewers,\r\n team_reviewers: teamReviewers,\r\n });\r\n\r\n return mapPullRequest(data);\r\n}\r\n\r\n/**\r\n * List reviews on a pull request\r\n */\r\nexport async function listReviews(\r\n repoString: string,\r\n prNumber: number,\r\n options?: { perPage?: number; page?: number },\r\n config?: GitHubClientConfig\r\n): Promise<PullRequestReview[]> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.listReviews({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n per_page: options?.perPage || 30,\r\n page: options?.page || 1,\r\n });\r\n\r\n return data.map(mapReview);\r\n}\r\n\r\n/**\r\n * Create a review on a pull request\r\n */\r\nexport async function createReview(\r\n repoString: string,\r\n prNumber: number,\r\n options: CreateReviewOptions,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequestReview> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.createReview({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n commit_id: options.commitId,\r\n body: options.body,\r\n event: options.event,\r\n comments: options.comments,\r\n });\r\n\r\n return mapReview(data);\r\n}\r\n\r\n/**\r\n * Approve a pull request\r\n */\r\nexport async function approvePullRequest(\r\n repoString: string,\r\n prNumber: number,\r\n body?: string,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequestReview> {\r\n return createReview(repoString, prNumber, {\r\n event: \"APPROVE\",\r\n body,\r\n }, config);\r\n}\r\n\r\n/**\r\n * Request changes on a pull request\r\n */\r\nexport async function requestChanges(\r\n repoString: string,\r\n prNumber: number,\r\n body: string,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequestReview> {\r\n return createReview(repoString, prNumber, {\r\n event: \"REQUEST_CHANGES\",\r\n body,\r\n }, config);\r\n}\r\n\r\n/**\r\n * Submit a pending review\r\n */\r\nexport async function submitReview(\r\n repoString: string,\r\n prNumber: number,\r\n reviewId: number,\r\n event: \"APPROVE\" | \"REQUEST_CHANGES\" | \"COMMENT\",\r\n body?: string,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequestReview> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.submitReview({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n review_id: reviewId,\r\n event,\r\n body,\r\n });\r\n\r\n return mapReview(data);\r\n}\r\n\r\n/**\r\n * Dismiss a review\r\n */\r\nexport async function dismissReview(\r\n repoString: string,\r\n prNumber: number,\r\n reviewId: number,\r\n message: string,\r\n config?: GitHubClientConfig\r\n): Promise<PullRequestReview> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.dismissReview({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n review_id: reviewId,\r\n message,\r\n });\r\n\r\n return mapReview(data);\r\n}\r\n\r\n/**\r\n * List review comments on a pull request\r\n */\r\nexport async function listReviewComments(\r\n repoString: string,\r\n prNumber: number,\r\n options?: { sort?: \"created\" | \"updated\"; direction?: \"asc\" | \"desc\"; since?: string; perPage?: number; page?: number },\r\n config?: GitHubClientConfig\r\n): Promise<ReviewComment[]> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.listReviewComments({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n sort: options?.sort,\r\n direction: options?.direction,\r\n since: options?.since,\r\n per_page: options?.perPage || 30,\r\n page: options?.page || 1,\r\n });\r\n\r\n return data.map(mapReviewComment);\r\n}\r\n\r\n/**\r\n * Create a review comment\r\n */\r\nexport async function createReviewComment(\r\n repoString: string,\r\n prNumber: number,\r\n body: string,\r\n commitId: string,\r\n path: string,\r\n options?: { position?: number; line?: number; side?: \"LEFT\" | \"RIGHT\"; startLine?: number; startSide?: \"LEFT\" | \"RIGHT\"; inReplyTo?: number },\r\n config?: GitHubClientConfig\r\n): Promise<ReviewComment> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.createReviewComment({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n body,\r\n commit_id: commitId,\r\n path,\r\n position: options?.position,\r\n line: options?.line,\r\n side: options?.side,\r\n start_line: options?.startLine,\r\n start_side: options?.startSide,\r\n in_reply_to: options?.inReplyTo,\r\n });\r\n\r\n return mapReviewComment(data);\r\n}\r\n\r\n/**\r\n * Reply to a review comment\r\n */\r\nexport async function replyToReviewComment(\r\n repoString: string,\r\n prNumber: number,\r\n commentId: number,\r\n body: string,\r\n config?: GitHubClientConfig\r\n): Promise<ReviewComment> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.createReplyForReviewComment({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n comment_id: commentId,\r\n body,\r\n });\r\n\r\n return mapReviewComment(data);\r\n}\r\n\r\n/**\r\n * Get files changed in a pull request\r\n */\r\nexport async function listFiles(\r\n repoString: string,\r\n prNumber: number,\r\n options?: { perPage?: number; page?: number },\r\n config?: GitHubClientConfig\r\n): Promise<PullRequestFile[]> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.listFiles({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n per_page: options?.perPage || 30,\r\n page: options?.page || 1,\r\n });\r\n\r\n return data.map(mapPullRequestFile);\r\n}\r\n\r\n/**\r\n * Get commits in a pull request\r\n */\r\nexport async function listCommits(\r\n repoString: string,\r\n prNumber: number,\r\n options?: { perPage?: number; page?: number },\r\n config?: GitHubClientConfig\r\n): Promise<Array<{ sha: string; message: string; author: { name: string; email: string; date: string } | null; committer: { name: string; email: string; date: string } | null; htmlUrl: string }>> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.listCommits({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n per_page: options?.perPage || 30,\r\n page: options?.page || 1,\r\n });\r\n\r\n return data.map((commit: any) => ({\r\n sha: commit.sha,\r\n message: commit.commit.message,\r\n author: commit.commit.author\r\n ? {\r\n name: commit.commit.author.name || \"\",\r\n email: commit.commit.author.email || \"\",\r\n date: commit.commit.author.date || \"\",\r\n }\r\n : null,\r\n committer: commit.commit.committer\r\n ? {\r\n name: commit.commit.committer.name || \"\",\r\n email: commit.commit.committer.email || \"\",\r\n date: commit.commit.committer.date || \"\",\r\n }\r\n : null,\r\n htmlUrl: commit.html_url,\r\n }));\r\n}\r\n\r\n/**\r\n * Check if a pull request can be merged\r\n */\r\nexport async function checkMergeability(\r\n repoString: string,\r\n prNumber: number,\r\n config?: GitHubClientConfig\r\n): Promise<{ mergeable: boolean | null; mergeableState: string; merged: boolean }> {\r\n const pr = await getPullRequest(repoString, prNumber, config);\r\n\r\n return {\r\n mergeable: pr.mergeable,\r\n mergeableState: pr.mergeableState,\r\n merged: pr.merged,\r\n };\r\n}\r\n\r\n/**\r\n * Merge a pull request\r\n */\r\nexport async function mergePullRequest(\r\n repoString: string,\r\n prNumber: number,\r\n options: MergeOptions = {},\r\n config?: GitHubClientConfig\r\n): Promise<{ sha: string; merged: boolean; message: string }> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.merge({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n commit_title: options.commitTitle,\r\n commit_message: options.commitMessage,\r\n sha: options.sha,\r\n merge_method: options.mergeMethod || \"merge\",\r\n });\r\n\r\n return {\r\n sha: data.sha,\r\n merged: data.merged,\r\n message: data.message,\r\n };\r\n}\r\n\r\n/**\r\n * Update a pull request branch (merge base into head)\r\n */\r\nexport async function updateBranch(\r\n repoString: string,\r\n prNumber: number,\r\n expectedHeadSha?: string,\r\n config?: GitHubClientConfig\r\n): Promise<{ message: string; url: string }> {\r\n const octokit = getOctokit(config);\r\n const { owner, repo } = parseRepoString(repoString);\r\n\r\n const { data } = await octokit.rest.pulls.updateBranch({\r\n owner,\r\n repo,\r\n pull_number: prNumber,\r\n expected_head_sha: expectedHeadSha,\r\n });\r\n\r\n return {\r\n message: data.message || \"\",\r\n url: data.url || \"\",\r\n };\r\n}\r\n\r\n// Helper to get PR node ID for GraphQL operations\r\nasync function getPullRequestNodeId(\r\n octokit: ReturnType<typeof getOctokit>,\r\n owner: string,\r\n repo: string,\r\n prNumber: number\r\n): Promise<string> {\r\n const { repository } = await octokit.graphql<{ repository: { pullRequest: { id: string } } }>(`\r\n query($owner: String!, $repo: String!, $number: Int!) {\r\n repository(owner: $owner, name: $repo) {\r\n pullRequest(number: $number) {\r\n id\r\n }\r\n }\r\n }\r\n `, { owner, repo, number: prNumber });\r\n\r\n return repository.pullRequest.id;\r\n}\r\n\r\n// Helper function to map API response to PullRequest interface\r\nfunction mapPullRequest(data: any): PullRequest {\r\n return {\r\n id: data.id,\r\n number: data.number,\r\n title: data.title,\r\n body: data.body,\r\n state: data.state,\r\n htmlUrl: data.html_url,\r\n diffUrl: data.diff_url,\r\n patchUrl: data.patch_url,\r\n draft: data.draft || false,\r\n merged: data.merged || false,\r\n mergeable: data.mergeable,\r\n mergeableState: data.mergeable_state || \"unknown\",\r\n mergedAt: data.merged_at,\r\n mergedBy: data.merged_by\r\n ? {\r\n login: data.merged_by.login,\r\n id: data.merged_by.id,\r\n avatarUrl: data.merged_by.avatar_url,\r\n }\r\n : null,\r\n user: data.user\r\n ? {\r\n login: data.user.login,\r\n id: data.user.id,\r\n avatarUrl: data.user.avatar_url,\r\n }\r\n : null,\r\n head: {\r\n ref: data.head.ref,\r\n sha: data.head.sha,\r\n repo: data.head.repo\r\n ? {\r\n fullName: data.head.repo.full_name,\r\n cloneUrl: data.head.repo.clone_url,\r\n }\r\n : null,\r\n },\r\n base: {\r\n ref: data.base.ref,\r\n sha: data.base.sha,\r\n repo: data.base.repo\r\n ? {\r\n fullName: data.base.repo.full_name,\r\n cloneUrl: data.base.repo.clone_url,\r\n }\r\n : null,\r\n },\r\n labels: data.labels?.map((label: any) => ({\r\n id: label.id,\r\n name: label.name,\r\n color: label.color,\r\n description: label.description,\r\n })) || [],\r\n assignees: data.assignees?.map((assignee: any) => ({\r\n login: assignee.login,\r\n id: assignee.id,\r\n avatarUrl: assignee.avatar_url,\r\n })) || [],\r\n requestedReviewers: data.requested_reviewers?.map((reviewer: any) => ({\r\n login: reviewer.login,\r\n id: reviewer.id,\r\n avatarUrl: reviewer.avatar_url,\r\n })) || [],\r\n requestedTeams: data.requested_teams?.map((team: any) => ({\r\n id: team.id,\r\n name: team.name,\r\n slug: team.slug,\r\n })) || [],\r\n milestone: data.milestone\r\n ? {\r\n id: data.milestone.id,\r\n number: data.milestone.number,\r\n title: data.milestone.title,\r\n state: data.milestone.state,\r\n }\r\n : null,\r\n additions: data.additions || 0,\r\n deletions: data.deletions || 0,\r\n changedFiles: data.changed_files || 0,\r\n commits: data.commits || 0,\r\n comments: data.comments || 0,\r\n reviewComments: data.review_comments || 0,\r\n createdAt: data.created_at,\r\n updatedAt: data.updated_at,\r\n closedAt: data.closed_at,\r\n };\r\n}\r\n\r\n// Helper function to map API response to PullRequestReview interface\r\nfunction mapReview(data: any): PullRequestReview {\r\n return {\r\n id: data.id,\r\n user: data.user\r\n ? {\r\n login: data.user.login,\r\n id: data.user.id,\r\n avatarUrl: data.user.avatar_url,\r\n }\r\n : null,\r\n body: data.body,\r\n state: data.state,\r\n htmlUrl: data.html_url,\r\n submittedAt: data.submitted_at,\r\n commitId: data.commit_id,\r\n };\r\n}\r\n\r\n// Helper function to map API response to ReviewComment interface\r\nfunction mapReviewComment(data: any): ReviewComment {\r\n return {\r\n id: data.id,\r\n pullRequestReviewId: data.pull_request_review_id,\r\n diffHunk: data.diff_hunk,\r\n path: data.path,\r\n position: data.position,\r\n originalPosition: data.original_position,\r\n commitId: data.commit_id,\r\n originalCommitId: data.original_commit_id,\r\n user: data.user\r\n ? {\r\n login: data.user.login,\r\n id: data.user.id,\r\n avatarUrl: data.user.avatar_url,\r\n }\r\n : null,\r\n body: data.body,\r\n htmlUrl: data.html_url,\r\n createdAt: data.created_at,\r\n updatedAt: data.updated_at,\r\n line: data.line,\r\n side: data.side || \"RIGHT\",\r\n startLine: data.start_line,\r\n startSide: data.start_side,\r\n inReplyToId: data.in_reply_to_id,\r\n };\r\n}\r\n\r\n// Helper function to map API response to PullRequestFile interface\r\nfunction mapPullRequestFile(data: any): PullRequestFile {\r\n return {\r\n sha: data.sha,\r\n filename: data.filename,\r\n status: data.status,\r\n additions: data.additions,\r\n deletions: data.deletions,\r\n changes: data.changes,\r\n blobUrl: data.blob_url,\r\n rawUrl: data.raw_url,\r\n contentsUrl: data.contents_url,\r\n patch: data.patch,\r\n previousFilename: data.previous_filename,\r\n };\r\n}\r\n","/**\n * AI-Powered Code Review\n *\n * Uses the configured LLM provider to provide intelligent code review on pull requests.\n */\n\nimport { providerRegistry } from \"../../core/providers\";\nimport { getOctokit, parseRepoString, type GitHubClientConfig } from \"./client\";\nimport { getPullRequest, listFiles, listCommits, createReview, type PullRequestFile, type CreateReviewOptions } from \"./pull-requests\";\nimport { getContents } from \"./repos\";\n\nexport interface CodeReviewOptions {\n /**\n * Focus areas for the review\n */\n focusAreas?: Array<\n | \"security\"\n | \"performance\"\n | \"maintainability\"\n | \"readability\"\n | \"testing\"\n | \"documentation\"\n | \"error-handling\"\n | \"best-practices\"\n >;\n\n /**\n * Language-specific guidelines to apply\n */\n language?: string;\n\n /**\n * Custom review guidelines or rules\n */\n customGuidelines?: string;\n\n /**\n * Maximum number of files to review (default: 20)\n */\n maxFiles?: number;\n\n /**\n * Whether to automatically submit the review\n */\n autoSubmit?: boolean;\n\n /**\n * Severity threshold for auto-approval\n * If all issues are below this severity, approve automatically\n */\n autoApproveThreshold?: \"info\" | \"warning\" | \"error\";\n\n /**\n * GitHub client configuration\n */\n githubConfig?: GitHubClientConfig;\n}\n\nexport interface ReviewIssue {\n severity: \"info\" | \"warning\" | \"error\";\n file: string;\n line?: number;\n endLine?: number;\n message: string;\n suggestion?: string;\n category: string;\n}\n\nexport interface CodeReviewResult {\n pullRequest: {\n number: number;\n title: string;\n author: string | null;\n url: string;\n };\n summary: string;\n issues: ReviewIssue[];\n filesReviewed: number;\n linesReviewed: number;\n overallAssessment: \"approve\" | \"request-changes\" | \"comment\";\n recommendations: string[];\n metrics: {\n securityScore: number;\n maintainabilityScore: number;\n readabilityScore: number;\n overallScore: number;\n };\n reviewSubmitted: boolean;\n reviewId?: number;\n}\n\nexport interface DiffContext {\n file: PullRequestFile;\n oldContent?: string;\n newContent?: string;\n patch?: string;\n}\n\n/**\n * Perform an AI-powered code review on a pull request\n */\nexport async function reviewPullRequest(\n repoString: string,\n prNumber: number,\n options: CodeReviewOptions = {}\n): Promise<CodeReviewResult> {\n const { owner, repo } = parseRepoString(repoString);\n const maxFiles = options.maxFiles || 20;\n\n // Get PR details and files\n const [pr, files, commits] = await Promise.all([\n getPullRequest(repoString, prNumber, options.githubConfig),\n listFiles(repoString, prNumber, { perPage: maxFiles }, options.githubConfig),\n listCommits(repoString, prNumber, { perPage: 10 }, options.githubConfig),\n ]);\n\n // Filter out binary files and very large files\n const reviewableFiles = files.filter((f) => {\n // Skip binary files (no patch available)\n if (!f.patch) return false;\n // Skip very large patches\n if (f.patch.length > 50000) return false;\n // Skip generated files\n if (isGeneratedFile(f.filename)) return false;\n return true;\n });\n\n // Build context for the review\n const diffContexts: DiffContext[] = reviewableFiles.map((file) => ({\n file,\n patch: file.patch,\n }));\n\n // Calculate total lines\n const totalLines = reviewableFiles.reduce(\n (sum, f) => sum + f.additions + f.deletions,\n 0\n );\n\n // Build the review prompt\n const prompt = buildReviewPrompt(pr, diffContexts, commits, options);\n\n // Get AI review using the configured provider\n const provider = providerRegistry.getDefault();\n const response = await provider.createMessage({\n model: \"claude-sonnet-4-20250514\",\n max_tokens: 8192,\n system: getSystemPrompt(options),\n messages: [{ role: \"user\", content: prompt }],\n });\n\n // Parse the review response\n const reviewContent =\n response.content[0]?.type === \"text\" ? response.content[0].text || \"\" : \"\";\n\n const reviewResult = parseReviewResponse(\n reviewContent,\n pr,\n reviewableFiles.length,\n totalLines\n );\n\n // Submit the review if requested\n if (options.autoSubmit) {\n const reviewOptions = buildReviewOptions(reviewResult);\n const review = await createReview(\n repoString,\n prNumber,\n reviewOptions,\n options.githubConfig\n );\n reviewResult.reviewSubmitted = true;\n reviewResult.reviewId = review.id;\n }\n\n return reviewResult;\n}\n\n/**\n * Review a specific file in a pull request\n */\nexport async function reviewFile(\n repoString: string,\n prNumber: number,\n filename: string,\n options: CodeReviewOptions = {}\n): Promise<{\n issues: ReviewIssue[];\n suggestions: string[];\n summary: string;\n}> {\n const files = await listFiles(repoString, prNumber, { perPage: 100 }, options.githubConfig);\n const file = files.find((f) => f.filename === filename);\n\n if (!file) {\n throw new Error(`File not found in pull request: ${filename}`);\n }\n\n if (!file.patch) {\n throw new Error(`No diff available for file: ${filename}`);\n }\n\n const prompt = buildSingleFileReviewPrompt(file, options);\n\n const provider = providerRegistry.getDefault();\n const response = await provider.createMessage({\n model: \"claude-sonnet-4-20250514\",\n max_tokens: 4096,\n system: getSystemPrompt(options),\n messages: [{ role: \"user\", content: prompt }],\n });\n\n const reviewContent =\n response.content[0]?.type === \"text\" ? response.content[0].text || \"\" : \"\";\n\n return parseSingleFileReview(reviewContent, filename);\n}\n\n/**\n * Generate a summary of changes in a pull request\n */\nexport async function summarizeChanges(\n repoString: string,\n prNumber: number,\n options?: { githubConfig?: GitHubClientConfig }\n): Promise<{\n summary: string;\n keyChanges: string[];\n impactAreas: string[];\n breakingChanges: string[];\n testingRecommendations: string[];\n}> {\n const [pr, files, commits] = await Promise.all([\n getPullRequest(repoString, prNumber, options?.githubConfig),\n listFiles(repoString, prNumber, { perPage: 50 }, options?.githubConfig),\n listCommits(repoString, prNumber, { perPage: 20 }, options?.githubConfig),\n ]);\n\n const prompt = `Analyze this pull request and provide a summary:\n\n**Pull Request:** ${pr.title}\n**Description:** ${pr.body || \"No description provided\"}\n**Author:** ${pr.user?.login || \"Unknown\"}\n**Commits:** ${commits.length}\n**Files Changed:** ${files.length}\n**Lines Changed:** +${pr.additions} / -${pr.deletions}\n\n**Commit Messages:**\n${commits.map((c) => `- ${c.message.split(\"\\n\")[0]}`).join(\"\\n\")}\n\n**Files Changed:**\n${files.map((f) => `- ${f.filename} (${f.status}: +${f.additions}/-${f.deletions})`).join(\"\\n\")}\n\nProvide your analysis in the following JSON format:\n{\n \"summary\": \"A concise 2-3 sentence summary of what this PR does\",\n \"keyChanges\": [\"Key change 1\", \"Key change 2\"],\n \"impactAreas\": [\"Area that might be affected\"],\n \"breakingChanges\": [\"Any breaking changes, or empty array if none\"],\n \"testingRecommendations\": [\"What should be tested\"]\n}`;\n\n const provider = providerRegistry.getDefault();\n const response = await provider.createMessage({\n model: \"claude-sonnet-4-20250514\",\n max_tokens: 2048,\n messages: [{ role: \"user\", content: prompt }],\n });\n\n const content =\n response.content[0]?.type === \"text\" ? response.content[0].text || \"\" : \"\";\n\n try {\n // Extract JSON from the response\n const jsonMatch = content.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch (e) {\n // Fall back to default structure\n }\n\n return {\n summary: content,\n keyChanges: [],\n impactAreas: [],\n breakingChanges: [],\n testingRecommendations: [],\n };\n}\n\n/**\n * Check for security issues in a pull request\n */\nexport async function securityScan(\n repoString: string,\n prNumber: number,\n options?: { githubConfig?: GitHubClientConfig }\n): Promise<{\n vulnerabilities: Array<{\n severity: \"low\" | \"medium\" | \"high\" | \"critical\";\n type: string;\n file: string;\n line?: number;\n description: string;\n recommendation: string;\n }>;\n securityScore: number;\n summary: string;\n}> {\n const files = await listFiles(repoString, prNumber, { perPage: 50 }, options?.githubConfig);\n\n const reviewableFiles = files.filter((f) => f.patch && !isGeneratedFile(f.filename));\n\n const prompt = `Perform a security analysis of these code changes.\n\n**Files Changed:**\n${reviewableFiles\n .map(\n (f) => `\n### ${f.filename}\n\\`\\`\\`diff\n${f.patch?.slice(0, 5000) || \"\"}\n\\`\\`\\`\n`\n )\n .join(\"\\n\")}\n\nLook for:\n1. SQL injection vulnerabilities\n2. XSS vulnerabilities\n3. Authentication/authorization issues\n4. Hardcoded secrets or credentials\n5. Insecure dependencies\n6. Path traversal vulnerabilities\n7. Command injection\n8. Insecure deserialization\n9. Sensitive data exposure\n10. Security misconfigurations\n\nRespond in JSON format:\n{\n \"vulnerabilities\": [\n {\n \"severity\": \"high\",\n \"type\": \"SQL Injection\",\n \"file\": \"path/to/file.ts\",\n \"line\": 42,\n \"description\": \"Description of the issue\",\n \"recommendation\": \"How to fix it\"\n }\n ],\n \"securityScore\": 85,\n \"summary\": \"Overall security assessment\"\n}`;\n\n const provider = providerRegistry.getDefault();\n const response = await provider.createMessage({\n model: \"claude-sonnet-4-20250514\",\n max_tokens: 4096,\n system: \"You are a security expert reviewing code for vulnerabilities. Be thorough but avoid false positives.\",\n messages: [{ role: \"user\", content: prompt }],\n });\n\n const content =\n response.content[0]?.type === \"text\" ? response.content[0].text || \"\" : \"\";\n\n try {\n const jsonMatch = content.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch (e) {\n // Fall back to default\n }\n\n return {\n vulnerabilities: [],\n securityScore: 100,\n summary: \"Unable to parse security scan results\",\n };\n}\n\n// Helper functions\n\nfunction getSystemPrompt(options: CodeReviewOptions): string {\n let prompt = `You are an expert code reviewer with deep knowledge of software engineering best practices.\nYour task is to review pull requests and provide constructive, actionable feedback.\n\nGuidelines:\n- Be specific and constructive in your feedback\n- Prioritize issues by severity (error > warning > info)\n- Include code suggestions when possible\n- Consider the context and purpose of the changes\n- Acknowledge good practices when you see them`;\n\n if (options.focusAreas?.length) {\n prompt += `\\n\\nFocus especially on: ${options.focusAreas.join(\", \")}`;\n }\n\n if (options.language) {\n prompt += `\\n\\nThis codebase uses ${options.language}. Apply language-specific best practices.`;\n }\n\n if (options.customGuidelines) {\n prompt += `\\n\\nCustom Review Guidelines:\\n${options.customGuidelines}`;\n }\n\n return prompt;\n}\n\nfunction buildReviewPrompt(\n pr: Awaited<ReturnType<typeof getPullRequest>>,\n contexts: DiffContext[],\n commits: Awaited<ReturnType<typeof listCommits>>,\n options: CodeReviewOptions\n): string {\n let prompt = `Review this pull request:\n\n**Title:** ${pr.title}\n**Author:** ${pr.user?.login || \"Unknown\"}\n**Description:**\n${pr.body || \"No description provided\"}\n\n**Commits (${commits.length}):**\n${commits.slice(0, 5).map((c) => `- ${c.message.split(\"\\n\")[0]}`).join(\"\\n\")}\n${commits.length > 5 ? `... and ${commits.length - 5} more commits` : \"\"}\n\n**Changes:**\n- Files changed: ${contexts.length}\n- Additions: ${pr.additions}\n- Deletions: ${pr.deletions}\n\n**File Diffs:**\n`;\n\n for (const ctx of contexts) {\n prompt += `\n### ${ctx.file.filename} (${ctx.file.status}: +${ctx.file.additions}/-${ctx.file.deletions})\n\\`\\`\\`diff\n${ctx.patch?.slice(0, 8000) || \"No diff available\"}\n\\`\\`\\`\n`;\n }\n\n prompt += `\n\nPlease provide your review in the following JSON format:\n{\n \"summary\": \"A brief summary of the overall changes and their quality\",\n \"issues\": [\n {\n \"severity\": \"error|warning|info\",\n \"file\": \"path/to/file.ts\",\n \"line\": 42,\n \"endLine\": 45,\n \"message\": \"Description of the issue\",\n \"suggestion\": \"Code or explanation of how to fix it\",\n \"category\": \"security|performance|maintainability|readability|testing|documentation|error-handling|best-practices\"\n }\n ],\n \"overallAssessment\": \"approve|request-changes|comment\",\n \"recommendations\": [\"General recommendation 1\", \"General recommendation 2\"],\n \"metrics\": {\n \"securityScore\": 85,\n \"maintainabilityScore\": 90,\n \"readabilityScore\": 88,\n \"overallScore\": 87\n }\n}`;\n\n return prompt;\n}\n\nfunction buildSingleFileReviewPrompt(\n file: PullRequestFile,\n options: CodeReviewOptions\n): string {\n return `Review this file change:\n\n**File:** ${file.filename}\n**Status:** ${file.status}\n**Changes:** +${file.additions}/-${file.deletions}\n\n\\`\\`\\`diff\n${file.patch || \"No diff available\"}\n\\`\\`\\`\n\nProvide your review in JSON format:\n{\n \"issues\": [\n {\n \"severity\": \"error|warning|info\",\n \"line\": 42,\n \"message\": \"Issue description\",\n \"suggestion\": \"How to fix\",\n \"category\": \"category\"\n }\n ],\n \"suggestions\": [\"General improvement suggestion\"],\n \"summary\": \"Brief summary of the file changes\"\n}`;\n}\n\nfunction parseReviewResponse(\n content: string,\n pr: Awaited<ReturnType<typeof getPullRequest>>,\n filesReviewed: number,\n linesReviewed: number\n): CodeReviewResult {\n const defaultResult: CodeReviewResult = {\n pullRequest: {\n number: pr.number,\n title: pr.title,\n author: pr.user?.login || null,\n url: pr.htmlUrl,\n },\n summary: \"\",\n issues: [],\n filesReviewed,\n linesReviewed,\n overallAssessment: \"comment\",\n recommendations: [],\n metrics: {\n securityScore: 0,\n maintainabilityScore: 0,\n readabilityScore: 0,\n overallScore: 0,\n },\n reviewSubmitted: false,\n };\n\n try {\n const jsonMatch = content.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n const parsed = JSON.parse(jsonMatch[0]);\n return {\n ...defaultResult,\n summary: parsed.summary || \"\",\n issues: parsed.issues || [],\n overallAssessment: parsed.overallAssessment || \"comment\",\n recommendations: parsed.recommendations || [],\n metrics: parsed.metrics || defaultResult.metrics,\n };\n }\n } catch (e) {\n // JSON parsing failed, return default with content as summary\n return {\n ...defaultResult,\n summary: content.slice(0, 500),\n };\n }\n\n return defaultResult;\n}\n\nfunction parseSingleFileReview(\n content: string,\n filename: string\n): {\n issues: ReviewIssue[];\n suggestions: string[];\n summary: string;\n} {\n const defaultResult = {\n issues: [],\n suggestions: [],\n summary: content.slice(0, 300),\n };\n\n try {\n const jsonMatch = content.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n const parsed = JSON.parse(jsonMatch[0]);\n return {\n issues: (parsed.issues || []).map((issue: any) => ({\n ...issue,\n file: filename,\n })),\n suggestions: parsed.suggestions || [],\n summary: parsed.summary || \"\",\n };\n }\n } catch (e) {\n // Fall back to default\n }\n\n return defaultResult;\n}\n\nfunction buildReviewOptions(result: CodeReviewResult): CreateReviewOptions {\n const comments: CreateReviewOptions[\"comments\"] = [];\n\n // Add inline comments for issues with line numbers\n for (const issue of result.issues) {\n if (issue.line) {\n comments.push({\n path: issue.file,\n line: issue.line,\n body: `**${issue.severity.toUpperCase()}** (${issue.category}): ${issue.message}${\n issue.suggestion ? `\\n\\n**Suggestion:** ${issue.suggestion}` : \"\"\n }`,\n });\n }\n }\n\n let event: \"APPROVE\" | \"REQUEST_CHANGES\" | \"COMMENT\";\n switch (result.overallAssessment) {\n case \"approve\":\n event = \"APPROVE\";\n break;\n case \"request-changes\":\n event = \"REQUEST_CHANGES\";\n break;\n default:\n event = \"COMMENT\";\n }\n\n let body = `## AI Code Review\\n\\n${result.summary}\\n\\n`;\n\n if (result.issues.length > 0) {\n body += `### Issues Found (${result.issues.length})\\n\\n`;\n\n const errorCount = result.issues.filter((i) => i.severity === \"error\").length;\n const warningCount = result.issues.filter((i) => i.severity === \"warning\").length;\n const infoCount = result.issues.filter((i) => i.severity === \"info\").length;\n\n body += `- Errors: ${errorCount}\\n- Warnings: ${warningCount}\\n- Info: ${infoCount}\\n\\n`;\n }\n\n if (result.recommendations.length > 0) {\n body += `### Recommendations\\n\\n`;\n for (const rec of result.recommendations) {\n body += `- ${rec}\\n`;\n }\n body += \"\\n\";\n }\n\n body += `### Metrics\\n\\n`;\n body += `| Metric | Score |\\n|--------|-------|\\n`;\n body += `| Security | ${result.metrics.securityScore}/100 |\\n`;\n body += `| Maintainability | ${result.metrics.maintainabilityScore}/100 |\\n`;\n body += `| Readability | ${result.metrics.readabilityScore}/100 |\\n`;\n body += `| **Overall** | **${result.metrics.overallScore}/100** |\\n`;\n\n body += `\\n---\\n*Reviewed by OpenSentinel AI*`;\n\n return {\n event,\n body,\n comments: comments.length > 0 ? comments : undefined,\n };\n}\n\nfunction isGeneratedFile(filename: string): boolean {\n const generatedPatterns = [\n /\\.min\\.(js|css)$/,\n /\\.bundle\\.(js|css)$/,\n /package-lock\\.json$/,\n /yarn\\.lock$/,\n /bun\\.lockb$/,\n /\\.d\\.ts$/,\n /\\.map$/,\n /dist\\//,\n /build\\//,\n /node_modules\\//,\n /vendor\\//,\n /generated\\//,\n /\\.pb\\.(go|ts|js)$/,\n /\\.g\\.(dart|swift|kt)$/,\n ];\n\n return generatedPatterns.some((pattern) => pattern.test(filename));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
env
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PUNIMPMY.js";
|
|
4
4
|
import {
|
|
5
5
|
OpenAICompatibleProvider
|
|
6
6
|
} from "./chunk-35WYTA3C.js";
|
|
@@ -197,6 +197,36 @@ function mapStopReason(reason) {
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
// src/core/providers/gemini.ts
|
|
201
|
+
var GeminiProvider = class extends OpenAICompatibleProvider {
|
|
202
|
+
constructor(apiKey, defaultModel = "gemini-2.0-flash") {
|
|
203
|
+
super({
|
|
204
|
+
id: "gemini",
|
|
205
|
+
name: "Google Gemini",
|
|
206
|
+
type: "openai-compatible",
|
|
207
|
+
apiKey,
|
|
208
|
+
baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai/",
|
|
209
|
+
defaultModel,
|
|
210
|
+
enabled: true
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Gemini 2.0 Flash supports vision, tool use, and streaming
|
|
215
|
+
* with a 1M token context window.
|
|
216
|
+
*/
|
|
217
|
+
getCapabilities() {
|
|
218
|
+
return {
|
|
219
|
+
supportsVision: true,
|
|
220
|
+
supportsToolUse: true,
|
|
221
|
+
supportsStreaming: true,
|
|
222
|
+
supportsExtendedThinking: false,
|
|
223
|
+
supportsSystemPrompt: true,
|
|
224
|
+
maxContextWindow: 1048576
|
|
225
|
+
// 1M tokens
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
200
230
|
// src/core/providers/registry.ts
|
|
201
231
|
var ProviderRegistry = class {
|
|
202
232
|
providers = /* @__PURE__ */ new Map();
|
|
@@ -328,6 +358,29 @@ async function initializeProviders() {
|
|
|
328
358
|
);
|
|
329
359
|
console.log("[LLM] Registered provider: Mistral");
|
|
330
360
|
}
|
|
361
|
+
if (env.GEMINI_API_KEY) {
|
|
362
|
+
providerRegistry.register(
|
|
363
|
+
new GeminiProvider(
|
|
364
|
+
env.GEMINI_API_KEY,
|
|
365
|
+
env.GEMINI_DEFAULT_MODEL || "gemini-2.0-flash"
|
|
366
|
+
)
|
|
367
|
+
);
|
|
368
|
+
console.log("[LLM] Registered provider: Google Gemini");
|
|
369
|
+
}
|
|
370
|
+
if (env.XAI_API_KEY) {
|
|
371
|
+
providerRegistry.register(
|
|
372
|
+
new OpenAICompatibleProvider({
|
|
373
|
+
id: "xai",
|
|
374
|
+
name: "xAI (Grok)",
|
|
375
|
+
type: "openai-compatible",
|
|
376
|
+
apiKey: env.XAI_API_KEY,
|
|
377
|
+
baseUrl: "https://api.x.ai/v1",
|
|
378
|
+
defaultModel: env.XAI_DEFAULT_MODEL || "grok-2",
|
|
379
|
+
enabled: true
|
|
380
|
+
})
|
|
381
|
+
);
|
|
382
|
+
console.log("[LLM] Registered provider: xAI (Grok)");
|
|
383
|
+
}
|
|
331
384
|
if (env.OPENAI_COMPATIBLE_BASE_URL) {
|
|
332
385
|
providerRegistry.register(
|
|
333
386
|
new OpenAICompatibleProvider({
|
|
@@ -344,7 +397,7 @@ async function initializeProviders() {
|
|
|
344
397
|
}
|
|
345
398
|
if (env.OLLAMA_ENABLED) {
|
|
346
399
|
try {
|
|
347
|
-
const { OllamaProvider: OllamaProvider2 } = await import("./ollama-
|
|
400
|
+
const { OllamaProvider: OllamaProvider2 } = await import("./ollama-J7CU45WT.js");
|
|
348
401
|
const ollamaBaseUrl = env.OLLAMA_BASE_URL || "http://localhost:11434";
|
|
349
402
|
const ollamaModel = env.OLLAMA_DEFAULT_MODEL || "llama3.1";
|
|
350
403
|
const ollama = new OllamaProvider2(ollamaBaseUrl, ollamaModel);
|
|
@@ -376,7 +429,8 @@ async function initializeProviders() {
|
|
|
376
429
|
|
|
377
430
|
export {
|
|
378
431
|
AnthropicProvider,
|
|
432
|
+
GeminiProvider,
|
|
379
433
|
providerRegistry,
|
|
380
434
|
initializeProviders
|
|
381
435
|
};
|
|
382
|
-
//# sourceMappingURL=chunk-
|
|
436
|
+
//# sourceMappingURL=chunk-HTF2GIQC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/providers/anthropic-provider.ts","../src/core/providers/gemini.ts","../src/core/providers/registry.ts","../src/core/providers/index.ts"],"sourcesContent":["/**\n * Anthropic Provider — Wraps the Anthropic SDK\n *\n * Converts between provider-agnostic LLM types and Anthropic's SDK types.\n * Handles extended thinking, vision, and tool use natively.\n */\n\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport type { LLMProvider } from \"./provider\";\nimport type {\n LLMProviderCapabilities,\n LLMProviderConfig,\n LLMRequest,\n LLMResponse,\n LLMContentBlock,\n LLMStreamEvent,\n LLMStreamResult,\n LLMMessage,\n LLMTool,\n} from \"./types\";\n\nexport class AnthropicProvider implements LLMProvider {\n readonly id: string;\n readonly name: string;\n readonly type = \"anthropic\";\n private client: Anthropic;\n\n constructor(config: LLMProviderConfig) {\n this.id = config.id;\n this.name = config.name;\n this.client = new Anthropic({ apiKey: config.apiKey });\n }\n\n getCapabilities(): LLMProviderCapabilities {\n return {\n supportsVision: true,\n supportsToolUse: true,\n supportsStreaming: true,\n supportsExtendedThinking: true,\n supportsSystemPrompt: true,\n maxContextWindow: 200000,\n };\n }\n\n async createMessage(request: LLMRequest): Promise<LLMResponse> {\n const { system, messages } = this.extractSystem(request);\n\n const params: any = {\n model: request.model,\n max_tokens: request.max_tokens,\n system,\n messages,\n };\n\n if (request.tools?.length) {\n params.tools = request.tools.map(toLLMToolToAnthropicTool);\n }\n\n if (request.thinking) {\n params.thinking = request.thinking;\n }\n\n const response = await this.client.messages.create(params);\n\n return {\n content: response.content.map(anthropicBlockToLLM),\n stop_reason: mapStopReason(response.stop_reason),\n usage: {\n input_tokens: response.usage.input_tokens,\n output_tokens: response.usage.output_tokens,\n },\n model: response.model,\n };\n }\n\n streamMessage(request: LLMRequest): LLMStreamResult {\n const { system, messages } = this.extractSystem(request);\n\n const params: any = {\n model: request.model,\n max_tokens: request.max_tokens,\n system,\n messages,\n };\n\n if (request.tools?.length) {\n params.tools = request.tools.map(toLLMToolToAnthropicTool);\n }\n\n const stream = this.client.messages.stream(params);\n\n const events: AsyncIterable<LLMStreamEvent> = {\n async *[Symbol.asyncIterator]() {\n for await (const event of stream) {\n if (event.type === \"content_block_delta\" && (event.delta as any).type === \"text_delta\") {\n yield {\n type: \"content_block_delta\" as const,\n delta: { type: \"text_delta\" as const, text: (event.delta as any).text },\n };\n }\n }\n },\n };\n\n return {\n events,\n async finalMessage(): Promise<LLMResponse> {\n const msg = await stream.finalMessage();\n return {\n content: msg.content.map(anthropicBlockToLLM),\n stop_reason: mapStopReason(msg.stop_reason),\n usage: {\n input_tokens: msg.usage.input_tokens,\n output_tokens: msg.usage.output_tokens,\n },\n model: msg.model,\n };\n },\n };\n }\n\n async listModels(): Promise<string[]> {\n return [\n \"claude-haiku-4-5-20251001\",\n \"claude-sonnet-4-20250514\",\n \"claude-opus-4-20250514\",\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n // Minimal API call to check connectivity\n await this.client.messages.create({\n model: \"claude-haiku-4-5-20251001\",\n max_tokens: 1,\n messages: [{ role: \"user\", content: \"hi\" }],\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /** Get the raw Anthropic client (for specialized use cases like vision) */\n getClient(): Anthropic {\n return this.client;\n }\n\n /**\n * Extract system messages and convert LLMMessages to Anthropic MessageParam format.\n * Anthropic uses a separate `system` parameter instead of a system role message.\n */\n private extractSystem(request: LLMRequest): {\n system: string;\n messages: any[];\n } {\n let system = request.system || \"\";\n\n const messages = request.messages\n .filter((m) => m.role !== \"system\")\n .map((m) => llmMessageToAnthropicMessage(m));\n\n return { system, messages };\n }\n}\n\n// ============================================\n// Conversion helpers\n// ============================================\n\nfunction toLLMToolToAnthropicTool(tool: LLMTool): any {\n // Anthropic uses the same format: { name, description, input_schema }\n return {\n name: tool.name,\n description: tool.description,\n input_schema: tool.input_schema,\n };\n}\n\nfunction llmMessageToAnthropicMessage(msg: LLMMessage): any {\n if (typeof msg.content === \"string\") {\n return { role: msg.role, content: msg.content };\n }\n\n // Convert content blocks\n const anthropicContent = msg.content.map((block) => {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: block.text };\n case \"image\":\n return {\n type: \"image\",\n source: {\n type: block.source?.type || \"base64\",\n media_type: block.source?.mediaType || \"image/jpeg\",\n data: block.source?.data,\n ...(block.source?.url ? { url: block.source.url } : {}),\n },\n };\n case \"tool_use\":\n return {\n type: \"tool_use\",\n id: block.id,\n name: block.name,\n input: block.input,\n };\n case \"tool_result\":\n return {\n type: \"tool_result\",\n tool_use_id: block.tool_use_id,\n content: block.content,\n };\n default:\n return { type: \"text\", text: block.text || \"\" };\n }\n });\n\n return { role: msg.role, content: anthropicContent };\n}\n\nfunction anthropicBlockToLLM(block: any): LLMContentBlock {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: block.text };\n case \"tool_use\":\n return {\n type: \"tool_use\",\n id: block.id,\n name: block.name,\n input: block.input,\n };\n default:\n return { type: \"text\", text: block.text || \"\" };\n }\n}\n\nfunction mapStopReason(reason: string | null): LLMResponse[\"stop_reason\"] {\n switch (reason) {\n case \"end_turn\":\n return \"end_turn\";\n case \"tool_use\":\n return \"tool_use\";\n case \"max_tokens\":\n return \"max_tokens\";\n default:\n return \"end_turn\";\n }\n}\n","/**\r\n * Google Gemini Provider\r\n *\r\n * Extends the OpenAI-compatible provider for Google's Gemini API.\r\n * Gemini exposes an OpenAI-compatible endpoint at\r\n * https://generativelanguage.googleapis.com/v1beta/openai/\r\n */\r\n\r\nimport { OpenAICompatibleProvider } from \"./openai-compatible-provider\";\r\nimport type { LLMProviderCapabilities } from \"./types\";\r\n\r\nexport class GeminiProvider extends OpenAICompatibleProvider {\r\n constructor(\r\n apiKey: string,\r\n defaultModel: string = \"gemini-2.0-flash\"\r\n ) {\r\n super({\r\n id: \"gemini\",\r\n name: \"Google Gemini\",\r\n type: \"openai-compatible\",\r\n apiKey,\r\n baseUrl: \"https://generativelanguage.googleapis.com/v1beta/openai/\",\r\n defaultModel,\r\n enabled: true,\r\n });\r\n }\r\n\r\n /**\r\n * Gemini 2.0 Flash supports vision, tool use, and streaming\r\n * with a 1M token context window.\r\n */\r\n override getCapabilities(): LLMProviderCapabilities {\r\n return {\r\n supportsVision: true,\r\n supportsToolUse: true,\r\n supportsStreaming: true,\r\n supportsExtendedThinking: false,\r\n supportsSystemPrompt: true,\r\n maxContextWindow: 1048576, // 1M tokens\r\n };\r\n }\r\n}\r\n","/**\n * Provider Registry — Manages all configured LLM providers\n */\n\nimport type { LLMProvider } from \"./provider\";\n\nexport class ProviderRegistry {\n private providers: Map<string, LLMProvider> = new Map();\n private defaultProviderId: string | null = null;\n\n register(provider: LLMProvider): void {\n this.providers.set(provider.id, provider);\n // First registered provider becomes default\n if (!this.defaultProviderId) {\n this.defaultProviderId = provider.id;\n }\n }\n\n unregister(id: string): void {\n this.providers.delete(id);\n if (this.defaultProviderId === id) {\n this.defaultProviderId = this.providers.keys().next().value || null;\n }\n }\n\n get(id: string): LLMProvider | undefined {\n return this.providers.get(id);\n }\n\n getDefault(): LLMProvider {\n if (!this.defaultProviderId) {\n throw new Error(\n \"[ProviderRegistry] No LLM providers configured. Set CLAUDE_API_KEY, OPENROUTER_API_KEY, or OLLAMA_ENABLED.\"\n );\n }\n const provider = this.providers.get(this.defaultProviderId);\n if (!provider) {\n throw new Error(`[ProviderRegistry] Default provider '${this.defaultProviderId}' not found.`);\n }\n return provider;\n }\n\n setDefault(id: string): void {\n if (!this.providers.has(id)) {\n console.warn(`[ProviderRegistry] Provider '${id}' not registered, cannot set as default.`);\n return;\n }\n this.defaultProviderId = id;\n }\n\n getDefaultId(): string | null {\n return this.defaultProviderId;\n }\n\n has(id: string): boolean {\n return this.providers.has(id);\n }\n\n listProviders(): Array<{ id: string; name: string; type: string }> {\n return Array.from(this.providers.values()).map((p) => ({\n id: p.id,\n name: p.name,\n type: p.type,\n }));\n }\n\n getProviderCount(): number {\n return this.providers.size;\n }\n\n clear(): void {\n this.providers.clear();\n this.defaultProviderId = null;\n }\n}\n\nexport const providerRegistry = new ProviderRegistry();\n","/**\n * Provider initialization and re-exports\n */\n\nimport { env } from \"../../config/env\";\nimport { AnthropicProvider } from \"./anthropic-provider\";\nimport { OpenAICompatibleProvider } from \"./openai-compatible-provider\";\nimport { GeminiProvider } from \"./gemini\";\nimport { providerRegistry } from \"./registry\";\n\n/**\n * Initialize all configured LLM providers from environment variables.\n * Called once during application startup.\n */\nexport async function initializeProviders(): Promise<void> {\n // Always register Anthropic if CLAUDE_API_KEY is set\n if (env.CLAUDE_API_KEY) {\n providerRegistry.register(\n new AnthropicProvider({\n id: \"anthropic\",\n name: \"Anthropic\",\n type: \"anthropic\",\n apiKey: env.CLAUDE_API_KEY,\n enabled: true,\n })\n );\n console.log(\"[LLM] Registered provider: Anthropic\");\n }\n\n // Register OpenAI if key is set (for LLM use, separate from Whisper STT)\n if ((env as any).OPENAI_LLM_ENABLED && env.OPENAI_API_KEY) {\n providerRegistry.register(\n new OpenAICompatibleProvider({\n id: \"openai\",\n name: \"OpenAI\",\n type: \"openai\",\n apiKey: env.OPENAI_API_KEY,\n baseUrl: \"https://api.openai.com/v1\",\n defaultModel: \"gpt-4o\",\n enabled: true,\n })\n );\n console.log(\"[LLM] Registered provider: OpenAI\");\n }\n\n // Register OpenRouter if configured\n if ((env as any).OPENROUTER_API_KEY) {\n providerRegistry.register(\n new OpenAICompatibleProvider({\n id: \"openrouter\",\n name: \"OpenRouter\",\n type: \"openai-compatible\",\n apiKey: (env as any).OPENROUTER_API_KEY,\n baseUrl: (env as any).OPENROUTER_BASE_URL || \"https://openrouter.ai/api/v1\",\n defaultModel: \"anthropic/claude-sonnet-4-20250514\",\n enabled: true,\n })\n );\n console.log(\"[LLM] Registered provider: OpenRouter\");\n }\n\n // Register Groq if configured\n if ((env as any).GROQ_API_KEY) {\n providerRegistry.register(\n new OpenAICompatibleProvider({\n id: \"groq\",\n name: \"Groq\",\n type: \"openai-compatible\",\n apiKey: (env as any).GROQ_API_KEY,\n baseUrl: \"https://api.groq.com/openai/v1\",\n defaultModel: \"llama-3.1-70b-versatile\",\n enabled: true,\n })\n );\n console.log(\"[LLM] Registered provider: Groq\");\n }\n\n // Register Mistral if configured\n if ((env as any).MISTRAL_API_KEY) {\n providerRegistry.register(\n new OpenAICompatibleProvider({\n id: \"mistral\",\n name: \"Mistral\",\n type: \"openai-compatible\",\n apiKey: (env as any).MISTRAL_API_KEY,\n baseUrl: \"https://api.mistral.ai/v1\",\n defaultModel: \"mistral-large-latest\",\n enabled: true,\n })\n );\n console.log(\"[LLM] Registered provider: Mistral\");\n }\n\n // Register Google Gemini if configured\n if ((env as any).GEMINI_API_KEY) {\n providerRegistry.register(\n new GeminiProvider(\n (env as any).GEMINI_API_KEY,\n (env as any).GEMINI_DEFAULT_MODEL || \"gemini-2.0-flash\"\n )\n );\n console.log(\"[LLM] Registered provider: Google Gemini\");\n }\n\n // Register xAI (Grok) if configured\n if ((env as any).XAI_API_KEY) {\n providerRegistry.register(\n new OpenAICompatibleProvider({\n id: \"xai\",\n name: \"xAI (Grok)\",\n type: \"openai-compatible\",\n apiKey: (env as any).XAI_API_KEY,\n baseUrl: \"https://api.x.ai/v1\",\n defaultModel: (env as any).XAI_DEFAULT_MODEL || \"grok-2\",\n enabled: true,\n })\n );\n console.log(\"[LLM] Registered provider: xAI (Grok)\");\n }\n\n // Register generic OpenAI-compatible endpoint if configured\n if ((env as any).OPENAI_COMPATIBLE_BASE_URL) {\n providerRegistry.register(\n new OpenAICompatibleProvider({\n id: \"custom\",\n name: \"Custom Provider\",\n type: \"openai-compatible\",\n apiKey: (env as any).OPENAI_COMPATIBLE_API_KEY || \"not-needed\",\n baseUrl: (env as any).OPENAI_COMPATIBLE_BASE_URL,\n defaultModel: (env as any).OPENAI_COMPATIBLE_MODEL || \"default\",\n enabled: true,\n })\n );\n console.log(\"[LLM] Registered provider: Custom (\" + (env as any).OPENAI_COMPATIBLE_BASE_URL + \")\");\n }\n\n // Register Ollama if enabled (requires async probe)\n if ((env as any).OLLAMA_ENABLED) {\n try {\n const { OllamaProvider } = await import(\"./ollama\");\n const ollamaBaseUrl = (env as any).OLLAMA_BASE_URL || \"http://localhost:11434\";\n const ollamaModel = (env as any).OLLAMA_DEFAULT_MODEL || \"llama3.1\";\n const ollama = new OllamaProvider(ollamaBaseUrl, ollamaModel);\n\n const available = await ollama.isAvailable();\n if (available) {\n providerRegistry.register(ollama);\n const models = await ollama.listModels();\n console.log(`[LLM] Registered provider: Ollama (${models.length} model(s): ${models.slice(0, 5).join(\", \")})`);\n } else {\n console.warn(`[LLM] Ollama enabled but not reachable at ${ollamaBaseUrl}`);\n }\n } catch (err: any) {\n console.warn(\"[LLM] Failed to initialize Ollama:\", err.message);\n }\n }\n\n // Set default provider\n const defaultId = (env as any).LLM_PROVIDER || \"anthropic\";\n if (providerRegistry.has(defaultId)) {\n providerRegistry.setDefault(defaultId);\n }\n\n const providers = providerRegistry.listProviders();\n if (providers.length === 0) {\n console.warn(\"[LLM] No LLM providers configured. Set CLAUDE_API_KEY or another provider key.\");\n } else {\n console.log(\n `[LLM] ${providers.length} provider(s) ready. Default: ${providerRegistry.getDefaultId()}`\n );\n }\n}\n\n// Re-exports\nexport { providerRegistry } from \"./registry\";\nexport { AnthropicProvider } from \"./anthropic-provider\";\nexport { OpenAICompatibleProvider } from \"./openai-compatible-provider\";\nexport { OllamaProvider } from \"./ollama\";\nexport { GeminiProvider } from \"./gemini\";\nexport type { LLMProvider } from \"./provider\";\nexport type {\n LLMMessage,\n LLMContentBlock,\n LLMTool,\n LLMRequest,\n LLMResponse,\n LLMStreamEvent,\n LLMStreamResult,\n LLMProviderCapabilities,\n LLMProviderConfig,\n} from \"./types\";\n"],"mappings":"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","names":["OllamaProvider"]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
textToSpeech
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-45YXODSB.js";
|
|
4
4
|
import {
|
|
5
5
|
transcribeAudio
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4YJRBMMA.js";
|
|
7
7
|
import {
|
|
8
8
|
scheduleReminder
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MFK34XSY.js";
|
|
10
10
|
import {
|
|
11
11
|
chatWithTools
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-6JY4HNUH.js";
|
|
13
13
|
|
|
14
14
|
// src/inputs/discord/index.ts
|
|
15
15
|
import {
|
|
@@ -803,4 +803,4 @@ export {
|
|
|
803
803
|
createDiscordBot,
|
|
804
804
|
discord_default
|
|
805
805
|
};
|
|
806
|
-
//# sourceMappingURL=chunk-
|
|
806
|
+
//# sourceMappingURL=chunk-JOA5A3G3.js.map
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
auditLogs,
|
|
3
2
|
db
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-S4NJJS5C.js";
|
|
5
4
|
import {
|
|
6
5
|
env
|
|
7
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PUNIMPMY.js";
|
|
7
|
+
import {
|
|
8
|
+
auditLogs
|
|
9
|
+
} from "./chunk-NYVBXUGD.js";
|
|
8
10
|
|
|
9
11
|
// src/core/security/audit-logger.ts
|
|
10
12
|
import { createHmac, randomUUID } from "crypto";
|
|
@@ -290,4 +292,4 @@ export {
|
|
|
290
292
|
getAuditChainIntegrity,
|
|
291
293
|
audit
|
|
292
294
|
};
|
|
293
|
-
//# sourceMappingURL=chunk-
|
|
295
|
+
//# sourceMappingURL=chunk-KABG5PG3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/security/audit-logger.ts"],"sourcesContent":["import { createHmac, randomUUID } from \"crypto\";\nimport { db } from \"../../db\";\nimport { auditLogs, NewAuditLog } from \"../../db/schema\";\nimport { eq, and, gte, lte, desc, count, min, max, asc } from \"drizzle-orm\";\nimport { env } from \"../../config/env\";\n\nexport type AuditAction =\n | \"login\"\n | \"logout\"\n | \"session_create\"\n | \"session_invalidate\"\n | \"api_key_create\"\n | \"api_key_revoke\"\n | \"tool_use\"\n | \"chat_message\"\n | \"memory_create\"\n | \"memory_delete\"\n | \"memory_archive\"\n | \"settings_change\"\n | \"mode_change\"\n | \"agent_spawn\"\n | \"agent_complete\"\n | \"file_read\"\n | \"file_write\"\n | \"shell_execute\"\n | \"web_browse\"\n | \"error\";\n\nexport type AuditResource =\n | \"session\"\n | \"api_key\"\n | \"tool\"\n | \"chat\"\n | \"memory\"\n | \"settings\"\n | \"mode\"\n | \"agent\"\n | \"file\"\n | \"shell\"\n | \"browser\";\n\nexport interface AuditLogEntry {\n userId?: string;\n sessionId?: string;\n action: AuditAction;\n resource?: AuditResource;\n resourceId?: string;\n details?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n success?: boolean;\n}\n\n// --- Tamper-proof chain hashing helpers (SOC 2 compliance) ---\n\nlet _cachedSigningKey: string | null = null;\n\nfunction getAuditSigningKey(): string {\n if (_cachedSigningKey) return _cachedSigningKey;\n if (env.AUDIT_SIGNING_KEY) {\n _cachedSigningKey = env.AUDIT_SIGNING_KEY;\n return _cachedSigningKey;\n }\n _cachedSigningKey = randomUUID();\n console.warn(\n \"[audit-logger] AUDIT_SIGNING_KEY not set — using a random ephemeral key. \" +\n \"Set AUDIT_SIGNING_KEY in .env for persistent tamper-proof audit chains.\"\n );\n return _cachedSigningKey;\n}\n\nfunction signAuditEntry(\n sequenceNumber: number,\n action: string,\n userId: string | undefined,\n resource: string | undefined,\n detailsJson: string,\n timestamp: string,\n previousHash: string | null\n): string {\n const key = getAuditSigningKey();\n const data = [\n String(sequenceNumber),\n action,\n userId ?? \"\",\n resource ?? \"\",\n detailsJson,\n timestamp,\n previousHash ?? \"\",\n ].join(\"|\");\n return createHmac(\"sha256\", key).update(data).digest(\"hex\");\n}\n\nasync function getLastAuditEntry(): Promise<{\n sequenceNumber: number;\n entryHash: string;\n} | null> {\n const [last] = await db\n .select({\n sequenceNumber: auditLogs.sequenceNumber,\n entryHash: auditLogs.entryHash,\n })\n .from(auditLogs)\n .orderBy(desc(auditLogs.sequenceNumber))\n .limit(1);\n\n if (!last || last.sequenceNumber == null || last.entryHash == null) {\n return null;\n }\n\n return {\n sequenceNumber: last.sequenceNumber,\n entryHash: last.entryHash,\n };\n}\n\nexport async function logAudit(entry: AuditLogEntry): Promise<string> {\n // Fetch previous chain entry for tamper-proof linking\n const last = await getLastAuditEntry();\n const sequenceNumber = (last?.sequenceNumber ?? 0) + 1;\n const previousHash = last?.entryHash ?? null;\n\n const timestamp = new Date().toISOString();\n const detailsJson = entry.details ? JSON.stringify(entry.details) : \"{}\";\n\n const entryHash = signAuditEntry(\n sequenceNumber,\n entry.action,\n entry.userId,\n entry.resource,\n detailsJson,\n timestamp,\n previousHash\n );\n\n const [log] = await db\n .insert(auditLogs)\n .values({\n userId: entry.userId,\n sessionId: entry.sessionId,\n action: entry.action,\n resource: entry.resource,\n resourceId: entry.resourceId,\n details: entry.details,\n ipAddress: entry.ipAddress,\n userAgent: entry.userAgent,\n success: entry.success ?? true,\n createdAt: new Date(timestamp),\n sequenceNumber,\n entryHash,\n previousHash,\n })\n .returning();\n\n return log.id;\n}\n\nexport interface AuditQueryOptions {\n userId?: string;\n action?: AuditAction;\n resource?: AuditResource;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\nexport async function queryAuditLogs(options: AuditQueryOptions = {}) {\n const {\n userId,\n action,\n resource,\n startDate,\n endDate,\n limit = 100,\n offset = 0,\n } = options;\n\n let query = db.select().from(auditLogs);\n\n const conditions = [];\n\n if (userId) {\n conditions.push(eq(auditLogs.userId, userId));\n }\n\n if (action) {\n conditions.push(eq(auditLogs.action, action));\n }\n\n if (resource) {\n conditions.push(eq(auditLogs.resource, resource));\n }\n\n if (startDate) {\n conditions.push(gte(auditLogs.createdAt, startDate));\n }\n\n if (endDate) {\n conditions.push(lte(auditLogs.createdAt, endDate));\n }\n\n if (conditions.length > 0) {\n query = query.where(and(...conditions)) as typeof query;\n }\n\n const logs = await query\n .orderBy(desc(auditLogs.createdAt))\n .limit(limit)\n .offset(offset);\n\n return logs;\n}\n\nexport async function getRecentUserActivity(\n userId: string,\n hours = 24\n): Promise<typeof auditLogs.$inferSelect[]> {\n const since = new Date(Date.now() - hours * 60 * 60 * 1000);\n\n return db\n .select()\n .from(auditLogs)\n .where(and(eq(auditLogs.userId, userId), gte(auditLogs.createdAt, since)))\n .orderBy(desc(auditLogs.createdAt))\n .limit(100);\n}\n\nexport async function countActionsByType(\n userId: string,\n startDate: Date,\n endDate: Date\n): Promise<Record<string, number>> {\n const logs = await db\n .select()\n .from(auditLogs)\n .where(\n and(\n eq(auditLogs.userId, userId),\n gte(auditLogs.createdAt, startDate),\n lte(auditLogs.createdAt, endDate)\n )\n );\n\n const counts: Record<string, number> = {};\n for (const log of logs) {\n counts[log.action] = (counts[log.action] || 0) + 1;\n }\n\n return counts;\n}\n\n// --- Audit chain verification (SOC 2 compliance) ---\n\nexport async function verifyAuditChain(\n options?: { fromSequence?: number; limit?: number }\n): Promise<{\n valid: boolean;\n totalChecked: number;\n firstInvalid?: number;\n errors: Array<{ sequenceNumber: number; error: string }>;\n}> {\n const fromSequence = options?.fromSequence ?? 1;\n const batchLimit = options?.limit ?? 10000;\n\n // Fetch the entry just before fromSequence to get its hash for linkage check\n let expectedPreviousHash: string | null = null;\n let expectedSequence = fromSequence;\n\n if (fromSequence > 1) {\n const [prev] = await db\n .select({\n sequenceNumber: auditLogs.sequenceNumber,\n entryHash: auditLogs.entryHash,\n })\n .from(auditLogs)\n .where(eq(auditLogs.sequenceNumber, fromSequence - 1))\n .limit(1);\n\n expectedPreviousHash = prev?.entryHash ?? null;\n }\n\n const entries = await db\n .select()\n .from(auditLogs)\n .where(gte(auditLogs.sequenceNumber, fromSequence))\n .orderBy(asc(auditLogs.sequenceNumber))\n .limit(batchLimit);\n\n const errors: Array<{ sequenceNumber: number; error: string }> = [];\n\n for (const entry of entries) {\n const seq = entry.sequenceNumber;\n\n if (seq == null) {\n errors.push({\n sequenceNumber: expectedSequence,\n error: \"Missing sequence number\",\n });\n expectedSequence++;\n continue;\n }\n\n // Check sequence continuity\n if (seq !== expectedSequence) {\n errors.push({\n sequenceNumber: expectedSequence,\n error: `Sequence gap: expected ${expectedSequence}, got ${seq}`,\n });\n expectedSequence = seq; // re-sync\n }\n\n // Check previousHash linkage\n if ((entry.previousHash ?? null) !== expectedPreviousHash) {\n errors.push({\n sequenceNumber: seq,\n error: `Previous hash mismatch: expected ${expectedPreviousHash ?? \"(null)\"}, got ${entry.previousHash ?? \"(null)\"}`,\n });\n }\n\n // Recompute and verify entryHash\n const detailsJson = entry.details ? JSON.stringify(entry.details) : \"{}\";\n const timestamp = entry.createdAt.toISOString();\n\n const recomputed = signAuditEntry(\n seq,\n entry.action,\n entry.userId ?? undefined,\n entry.resource ?? undefined,\n detailsJson,\n timestamp,\n entry.previousHash\n );\n\n if (recomputed !== entry.entryHash) {\n errors.push({\n sequenceNumber: seq,\n error: \"Entry hash mismatch — record may have been tampered with\",\n });\n }\n\n // Advance expectations\n expectedPreviousHash = entry.entryHash;\n expectedSequence = seq + 1;\n }\n\n return {\n valid: errors.length === 0,\n totalChecked: entries.length,\n firstInvalid: errors.length > 0 ? errors[0].sequenceNumber : undefined,\n errors,\n };\n}\n\nexport async function getAuditChainIntegrity(): Promise<{\n totalEntries: number;\n oldestEntry: Date | null;\n newestEntry: Date | null;\n lastVerified: number;\n chainValid: boolean;\n lastSequence: number;\n}> {\n const [stats] = await db\n .select({\n totalEntries: count(auditLogs.id),\n oldestEntry: min(auditLogs.createdAt),\n newestEntry: max(auditLogs.createdAt),\n lastSequence: max(auditLogs.sequenceNumber),\n })\n .from(auditLogs);\n\n const totalEntries = Number(stats.totalEntries ?? 0);\n const lastSequence = stats.lastSequence ?? 0;\n\n // Verify the last 1000 entries\n const verifyFrom = Math.max(1, lastSequence - 999);\n const verification = await verifyAuditChain({\n fromSequence: verifyFrom,\n limit: 1000,\n });\n\n return {\n totalEntries,\n oldestEntry: stats.oldestEntry ? new Date(stats.oldestEntry) : null,\n newestEntry: stats.newestEntry ? new Date(stats.newestEntry) : null,\n lastVerified: verification.totalChecked,\n chainValid: verification.valid,\n lastSequence,\n };\n}\n\n// Convenience functions for common audit events\nexport const audit = {\n login: (userId: string, ipAddress?: string, userAgent?: string) =>\n logAudit({\n userId,\n action: \"login\",\n resource: \"session\",\n ipAddress,\n userAgent,\n }),\n\n logout: (userId: string, sessionId: string) =>\n logAudit({\n userId,\n sessionId,\n action: \"logout\",\n resource: \"session\",\n }),\n\n toolUse: (\n userId: string,\n toolName: string,\n input: Record<string, unknown>,\n success: boolean\n ) =>\n logAudit({\n userId,\n action: \"tool_use\",\n resource: \"tool\",\n resourceId: toolName,\n details: { input },\n success,\n }),\n\n shellExecute: (\n userId: string,\n command: string,\n exitCode: number,\n durationMs: number\n ) =>\n logAudit({\n userId,\n action: \"shell_execute\",\n resource: \"shell\",\n details: { command, exitCode, durationMs },\n success: exitCode === 0,\n }),\n\n fileAccess: (\n userId: string,\n action: \"file_read\" | \"file_write\",\n filePath: string\n ) =>\n logAudit({\n userId,\n action,\n resource: \"file\",\n resourceId: filePath,\n }),\n\n memoryCreate: (userId: string, memoryId: string, memoryType: string) =>\n logAudit({\n userId,\n action: \"memory_create\",\n resource: \"memory\",\n resourceId: memoryId,\n details: { type: memoryType },\n }),\n\n modeChange: (\n userId: string,\n fromMode: string | null,\n toMode: string\n ) =>\n logAudit({\n userId,\n action: \"mode_change\",\n resource: \"mode\",\n details: { fromMode, toMode },\n }),\n\n agentSpawn: (userId: string, agentId: string, agentType: string) =>\n logAudit({\n userId,\n action: \"agent_spawn\",\n resource: \"agent\",\n resourceId: agentId,\n details: { type: agentType },\n }),\n\n error: (\n userId: string | undefined,\n errorType: string,\n message: string,\n context?: Record<string, unknown>\n ) =>\n logAudit({\n userId,\n action: \"error\",\n details: { errorType, message, ...context },\n success: false,\n }),\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/security/audit-logger.ts"],"sourcesContent":["import { createHmac, randomUUID } from \"crypto\";\nimport { db } from \"../../db\";\nimport { auditLogs, NewAuditLog } from \"../../db/schema\";\nimport { eq, and, gte, lte, desc, count, min, max, asc } from \"drizzle-orm\";\nimport { env } from \"../../config/env\";\n\nexport type AuditAction =\n | \"login\"\n | \"logout\"\n | \"session_create\"\n | \"session_invalidate\"\n | \"api_key_create\"\n | \"api_key_revoke\"\n | \"tool_use\"\n | \"chat_message\"\n | \"memory_create\"\n | \"memory_delete\"\n | \"memory_archive\"\n | \"settings_change\"\n | \"mode_change\"\n | \"agent_spawn\"\n | \"agent_complete\"\n | \"file_read\"\n | \"file_write\"\n | \"shell_execute\"\n | \"web_browse\"\n | \"error\";\n\nexport type AuditResource =\n | \"session\"\n | \"api_key\"\n | \"tool\"\n | \"chat\"\n | \"memory\"\n | \"settings\"\n | \"mode\"\n | \"agent\"\n | \"file\"\n | \"shell\"\n | \"browser\";\n\nexport interface AuditLogEntry {\n userId?: string;\n sessionId?: string;\n action: AuditAction;\n resource?: AuditResource;\n resourceId?: string;\n details?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n success?: boolean;\n}\n\n// --- Tamper-proof chain hashing helpers (SOC 2 compliance) ---\n\nlet _cachedSigningKey: string | null = null;\n\nfunction getAuditSigningKey(): string {\n if (_cachedSigningKey) return _cachedSigningKey;\n if (env.AUDIT_SIGNING_KEY) {\n _cachedSigningKey = env.AUDIT_SIGNING_KEY;\n return _cachedSigningKey;\n }\n _cachedSigningKey = randomUUID();\n console.warn(\n \"[audit-logger] AUDIT_SIGNING_KEY not set — using a random ephemeral key. \" +\n \"Set AUDIT_SIGNING_KEY in .env for persistent tamper-proof audit chains.\"\n );\n return _cachedSigningKey;\n}\n\nfunction signAuditEntry(\n sequenceNumber: number,\n action: string,\n userId: string | undefined,\n resource: string | undefined,\n detailsJson: string,\n timestamp: string,\n previousHash: string | null\n): string {\n const key = getAuditSigningKey();\n const data = [\n String(sequenceNumber),\n action,\n userId ?? \"\",\n resource ?? \"\",\n detailsJson,\n timestamp,\n previousHash ?? \"\",\n ].join(\"|\");\n return createHmac(\"sha256\", key).update(data).digest(\"hex\");\n}\n\nasync function getLastAuditEntry(): Promise<{\n sequenceNumber: number;\n entryHash: string;\n} | null> {\n const [last] = await db\n .select({\n sequenceNumber: auditLogs.sequenceNumber,\n entryHash: auditLogs.entryHash,\n })\n .from(auditLogs)\n .orderBy(desc(auditLogs.sequenceNumber))\n .limit(1);\n\n if (!last || last.sequenceNumber == null || last.entryHash == null) {\n return null;\n }\n\n return {\n sequenceNumber: last.sequenceNumber,\n entryHash: last.entryHash,\n };\n}\n\nexport async function logAudit(entry: AuditLogEntry): Promise<string> {\n // Fetch previous chain entry for tamper-proof linking\n const last = await getLastAuditEntry();\n const sequenceNumber = (last?.sequenceNumber ?? 0) + 1;\n const previousHash = last?.entryHash ?? null;\n\n const timestamp = new Date().toISOString();\n const detailsJson = entry.details ? JSON.stringify(entry.details) : \"{}\";\n\n const entryHash = signAuditEntry(\n sequenceNumber,\n entry.action,\n entry.userId,\n entry.resource,\n detailsJson,\n timestamp,\n previousHash\n );\n\n const [log] = await db\n .insert(auditLogs)\n .values({\n userId: entry.userId,\n sessionId: entry.sessionId,\n action: entry.action,\n resource: entry.resource,\n resourceId: entry.resourceId,\n details: entry.details,\n ipAddress: entry.ipAddress,\n userAgent: entry.userAgent,\n success: entry.success ?? true,\n createdAt: new Date(timestamp),\n sequenceNumber,\n entryHash,\n previousHash,\n })\n .returning();\n\n return log.id;\n}\n\nexport interface AuditQueryOptions {\n userId?: string;\n action?: AuditAction;\n resource?: AuditResource;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\nexport async function queryAuditLogs(options: AuditQueryOptions = {}) {\n const {\n userId,\n action,\n resource,\n startDate,\n endDate,\n limit = 100,\n offset = 0,\n } = options;\n\n let query = db.select().from(auditLogs);\n\n const conditions = [];\n\n if (userId) {\n conditions.push(eq(auditLogs.userId, userId));\n }\n\n if (action) {\n conditions.push(eq(auditLogs.action, action));\n }\n\n if (resource) {\n conditions.push(eq(auditLogs.resource, resource));\n }\n\n if (startDate) {\n conditions.push(gte(auditLogs.createdAt, startDate));\n }\n\n if (endDate) {\n conditions.push(lte(auditLogs.createdAt, endDate));\n }\n\n if (conditions.length > 0) {\n query = query.where(and(...conditions)) as typeof query;\n }\n\n const logs = await query\n .orderBy(desc(auditLogs.createdAt))\n .limit(limit)\n .offset(offset);\n\n return logs;\n}\n\nexport async function getRecentUserActivity(\n userId: string,\n hours = 24\n): Promise<typeof auditLogs.$inferSelect[]> {\n const since = new Date(Date.now() - hours * 60 * 60 * 1000);\n\n return db\n .select()\n .from(auditLogs)\n .where(and(eq(auditLogs.userId, userId), gte(auditLogs.createdAt, since)))\n .orderBy(desc(auditLogs.createdAt))\n .limit(100);\n}\n\nexport async function countActionsByType(\n userId: string,\n startDate: Date,\n endDate: Date\n): Promise<Record<string, number>> {\n const logs = await db\n .select()\n .from(auditLogs)\n .where(\n and(\n eq(auditLogs.userId, userId),\n gte(auditLogs.createdAt, startDate),\n lte(auditLogs.createdAt, endDate)\n )\n );\n\n const counts: Record<string, number> = {};\n for (const log of logs) {\n counts[log.action] = (counts[log.action] || 0) + 1;\n }\n\n return counts;\n}\n\n// --- Audit chain verification (SOC 2 compliance) ---\n\nexport async function verifyAuditChain(\n options?: { fromSequence?: number; limit?: number }\n): Promise<{\n valid: boolean;\n totalChecked: number;\n firstInvalid?: number;\n errors: Array<{ sequenceNumber: number; error: string }>;\n}> {\n const fromSequence = options?.fromSequence ?? 1;\n const batchLimit = options?.limit ?? 10000;\n\n // Fetch the entry just before fromSequence to get its hash for linkage check\n let expectedPreviousHash: string | null = null;\n let expectedSequence = fromSequence;\n\n if (fromSequence > 1) {\n const [prev] = await db\n .select({\n sequenceNumber: auditLogs.sequenceNumber,\n entryHash: auditLogs.entryHash,\n })\n .from(auditLogs)\n .where(eq(auditLogs.sequenceNumber, fromSequence - 1))\n .limit(1);\n\n expectedPreviousHash = prev?.entryHash ?? null;\n }\n\n const entries = await db\n .select()\n .from(auditLogs)\n .where(gte(auditLogs.sequenceNumber, fromSequence))\n .orderBy(asc(auditLogs.sequenceNumber))\n .limit(batchLimit);\n\n const errors: Array<{ sequenceNumber: number; error: string }> = [];\n\n for (const entry of entries) {\n const seq = entry.sequenceNumber;\n\n if (seq == null) {\n errors.push({\n sequenceNumber: expectedSequence,\n error: \"Missing sequence number\",\n });\n expectedSequence++;\n continue;\n }\n\n // Check sequence continuity\n if (seq !== expectedSequence) {\n errors.push({\n sequenceNumber: expectedSequence,\n error: `Sequence gap: expected ${expectedSequence}, got ${seq}`,\n });\n expectedSequence = seq; // re-sync\n }\n\n // Check previousHash linkage\n if ((entry.previousHash ?? null) !== expectedPreviousHash) {\n errors.push({\n sequenceNumber: seq,\n error: `Previous hash mismatch: expected ${expectedPreviousHash ?? \"(null)\"}, got ${entry.previousHash ?? \"(null)\"}`,\n });\n }\n\n // Recompute and verify entryHash\n const detailsJson = entry.details ? JSON.stringify(entry.details) : \"{}\";\n const timestamp = entry.createdAt.toISOString();\n\n const recomputed = signAuditEntry(\n seq,\n entry.action,\n entry.userId ?? undefined,\n entry.resource ?? undefined,\n detailsJson,\n timestamp,\n entry.previousHash\n );\n\n if (recomputed !== entry.entryHash) {\n errors.push({\n sequenceNumber: seq,\n error: \"Entry hash mismatch — record may have been tampered with\",\n });\n }\n\n // Advance expectations\n expectedPreviousHash = entry.entryHash;\n expectedSequence = seq + 1;\n }\n\n return {\n valid: errors.length === 0,\n totalChecked: entries.length,\n firstInvalid: errors.length > 0 ? errors[0].sequenceNumber : undefined,\n errors,\n };\n}\n\nexport async function getAuditChainIntegrity(): Promise<{\n totalEntries: number;\n oldestEntry: Date | null;\n newestEntry: Date | null;\n lastVerified: number;\n chainValid: boolean;\n lastSequence: number;\n}> {\n const [stats] = await db\n .select({\n totalEntries: count(auditLogs.id),\n oldestEntry: min(auditLogs.createdAt),\n newestEntry: max(auditLogs.createdAt),\n lastSequence: max(auditLogs.sequenceNumber),\n })\n .from(auditLogs);\n\n const totalEntries = Number(stats.totalEntries ?? 0);\n const lastSequence = stats.lastSequence ?? 0;\n\n // Verify the last 1000 entries\n const verifyFrom = Math.max(1, lastSequence - 999);\n const verification = await verifyAuditChain({\n fromSequence: verifyFrom,\n limit: 1000,\n });\n\n return {\n totalEntries,\n oldestEntry: stats.oldestEntry ? new Date(stats.oldestEntry) : null,\n newestEntry: stats.newestEntry ? new Date(stats.newestEntry) : null,\n lastVerified: verification.totalChecked,\n chainValid: verification.valid,\n lastSequence,\n };\n}\n\n// Convenience functions for common audit events\nexport const audit = {\n login: (userId: string, ipAddress?: string, userAgent?: string) =>\n logAudit({\n userId,\n action: \"login\",\n resource: \"session\",\n ipAddress,\n userAgent,\n }),\n\n logout: (userId: string, sessionId: string) =>\n logAudit({\n userId,\n sessionId,\n action: \"logout\",\n resource: \"session\",\n }),\n\n toolUse: (\n userId: string,\n toolName: string,\n input: Record<string, unknown>,\n success: boolean\n ) =>\n logAudit({\n userId,\n action: \"tool_use\",\n resource: \"tool\",\n resourceId: toolName,\n details: { input },\n success,\n }),\n\n shellExecute: (\n userId: string,\n command: string,\n exitCode: number,\n durationMs: number\n ) =>\n logAudit({\n userId,\n action: \"shell_execute\",\n resource: \"shell\",\n details: { command, exitCode, durationMs },\n success: exitCode === 0,\n }),\n\n fileAccess: (\n userId: string,\n action: \"file_read\" | \"file_write\",\n filePath: string\n ) =>\n logAudit({\n userId,\n action,\n resource: \"file\",\n resourceId: filePath,\n }),\n\n memoryCreate: (userId: string, memoryId: string, memoryType: string) =>\n logAudit({\n userId,\n action: \"memory_create\",\n resource: \"memory\",\n resourceId: memoryId,\n details: { type: memoryType },\n }),\n\n modeChange: (\n userId: string,\n fromMode: string | null,\n toMode: string\n ) =>\n logAudit({\n userId,\n action: \"mode_change\",\n resource: \"mode\",\n details: { fromMode, toMode },\n }),\n\n agentSpawn: (userId: string, agentId: string, agentType: string) =>\n logAudit({\n userId,\n action: \"agent_spawn\",\n resource: \"agent\",\n resourceId: agentId,\n details: { type: agentType },\n }),\n\n error: (\n userId: string | undefined,\n errorType: string,\n message: string,\n context?: Record<string, unknown>\n ) =>\n logAudit({\n userId,\n action: \"error\",\n details: { errorType, message, ...context },\n success: false,\n }),\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
chatWithTools
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6JY4HNUH.js";
|
|
4
4
|
|
|
5
5
|
// src/inputs/signal/index.ts
|
|
6
6
|
import { spawn } from "child_process";
|
|
@@ -126,4 +126,4 @@ export {
|
|
|
126
126
|
SignalBot,
|
|
127
127
|
signal_default
|
|
128
128
|
};
|
|
129
|
-
//# sourceMappingURL=chunk-
|
|
129
|
+
//# sourceMappingURL=chunk-KT7NLIXP.js.map
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// src/core/agents/agent-types.ts
|
|
2
|
+
var AGENT_SYSTEM_PROMPTS = {
|
|
3
|
+
research: `You are a Research Agent. Your goal is to thoroughly investigate a topic and provide comprehensive, well-sourced information.
|
|
4
|
+
|
|
5
|
+
Process:
|
|
6
|
+
1. Break down the research question into sub-questions
|
|
7
|
+
2. Search for information from multiple sources
|
|
8
|
+
3. Cross-reference and verify findings
|
|
9
|
+
4. Synthesize information into a coherent report
|
|
10
|
+
5. Note confidence levels and any uncertainties
|
|
11
|
+
|
|
12
|
+
Guidelines:
|
|
13
|
+
- Always cite or reference your sources
|
|
14
|
+
- Present multiple perspectives when relevant
|
|
15
|
+
- Distinguish between facts and interpretations
|
|
16
|
+
- Flag when information might be outdated
|
|
17
|
+
- Structure findings hierarchically
|
|
18
|
+
|
|
19
|
+
Report your progress after each major step.`,
|
|
20
|
+
coding: `You are a Coding Agent. Your goal is to implement, debug, or improve code based on the given objective.
|
|
21
|
+
|
|
22
|
+
Process:
|
|
23
|
+
1. Understand the requirements thoroughly
|
|
24
|
+
2. Explore existing code if relevant
|
|
25
|
+
3. Plan the implementation approach
|
|
26
|
+
4. Write clean, documented code
|
|
27
|
+
5. Test and verify the solution
|
|
28
|
+
|
|
29
|
+
Guidelines:
|
|
30
|
+
- Follow existing code conventions in the project
|
|
31
|
+
- Write clear comments for complex logic
|
|
32
|
+
- Handle edge cases and errors gracefully
|
|
33
|
+
- Consider performance implications
|
|
34
|
+
- Provide a summary of changes made
|
|
35
|
+
|
|
36
|
+
Report your progress after each significant step.`,
|
|
37
|
+
writing: `You are a Writing Agent. Your goal is to create high-quality written content based on the given objective.
|
|
38
|
+
|
|
39
|
+
Process:
|
|
40
|
+
1. Understand the purpose and audience
|
|
41
|
+
2. Research the topic if needed
|
|
42
|
+
3. Create an outline
|
|
43
|
+
4. Write the first draft
|
|
44
|
+
5. Review and refine
|
|
45
|
+
|
|
46
|
+
Guidelines:
|
|
47
|
+
- Match the tone and style to the purpose
|
|
48
|
+
- Structure content logically
|
|
49
|
+
- Use clear, concise language
|
|
50
|
+
- Support claims with evidence when relevant
|
|
51
|
+
- Proofread for grammar and clarity
|
|
52
|
+
|
|
53
|
+
Report your progress at each stage.`,
|
|
54
|
+
analysis: `You are an Analysis Agent. Your goal is to analyze data or information and provide actionable insights.
|
|
55
|
+
|
|
56
|
+
Process:
|
|
57
|
+
1. Understand the analysis objective
|
|
58
|
+
2. Gather and organize the data
|
|
59
|
+
3. Apply appropriate analytical methods
|
|
60
|
+
4. Identify patterns and insights
|
|
61
|
+
5. Present findings with recommendations
|
|
62
|
+
|
|
63
|
+
Guidelines:
|
|
64
|
+
- Be objective and data-driven
|
|
65
|
+
- Acknowledge limitations in the data
|
|
66
|
+
- Provide context for numbers
|
|
67
|
+
- Make recommendations actionable
|
|
68
|
+
- Visualize data when helpful
|
|
69
|
+
|
|
70
|
+
Report your progress and key findings along the way.`,
|
|
71
|
+
osint: `You are an OSINT (Open Source Intelligence) Agent. Your goal is to investigate entities, trace financial flows, map organizational relationships, and build comprehensive intelligence profiles using public records and open data sources.
|
|
72
|
+
|
|
73
|
+
Process:
|
|
74
|
+
1. Identify the target entity (person, organization, committee)
|
|
75
|
+
2. Search across public records databases (FEC, IRS 990, USAspending, SEC EDGAR, OpenCorporates)
|
|
76
|
+
3. Resolve and deduplicate entities using fuzzy matching and identifiers
|
|
77
|
+
4. Build relationship graphs connecting discovered entities
|
|
78
|
+
5. Enrich discovered entities with additional data from all available sources
|
|
79
|
+
6. Analyze patterns: financial flows, organizational hierarchies, political connections
|
|
80
|
+
7. Generate an intelligence report with confidence levels
|
|
81
|
+
|
|
82
|
+
Guidelines:
|
|
83
|
+
- Use only publicly available information from official government databases
|
|
84
|
+
- Cross-reference data across multiple sources to verify findings
|
|
85
|
+
- Flag low-confidence matches explicitly
|
|
86
|
+
- Build the knowledge graph incrementally, enriching as you discover connections
|
|
87
|
+
- Track the provenance of every data point (source API, date retrieved)
|
|
88
|
+
- Respect rate limits on all public APIs
|
|
89
|
+
- Distinguish between confirmed facts and inferred connections
|
|
90
|
+
- Quantify financial relationships with exact dollar amounts when available
|
|
91
|
+
- Note temporal aspects (when relationships were active)
|
|
92
|
+
- Provide actionable next steps for further investigation
|
|
93
|
+
|
|
94
|
+
Report findings as you progress through each data source.`
|
|
95
|
+
};
|
|
96
|
+
var AGENT_TOOL_PERMISSIONS = {
|
|
97
|
+
research: [
|
|
98
|
+
"web_search",
|
|
99
|
+
"browse_url",
|
|
100
|
+
"read_file",
|
|
101
|
+
"list_directory",
|
|
102
|
+
"search_files"
|
|
103
|
+
],
|
|
104
|
+
coding: [
|
|
105
|
+
"read_file",
|
|
106
|
+
"write_file",
|
|
107
|
+
"list_directory",
|
|
108
|
+
"search_files",
|
|
109
|
+
"execute_command"
|
|
110
|
+
],
|
|
111
|
+
writing: [
|
|
112
|
+
"read_file",
|
|
113
|
+
"write_file",
|
|
114
|
+
"web_search",
|
|
115
|
+
"browse_url"
|
|
116
|
+
],
|
|
117
|
+
analysis: [
|
|
118
|
+
"read_file",
|
|
119
|
+
"web_search",
|
|
120
|
+
"browse_url",
|
|
121
|
+
"list_directory",
|
|
122
|
+
"search_files",
|
|
123
|
+
"fred_economic_data",
|
|
124
|
+
"finnhub_market_data",
|
|
125
|
+
"crypto_price",
|
|
126
|
+
"stock_price",
|
|
127
|
+
"currency_exchange"
|
|
128
|
+
],
|
|
129
|
+
osint: [
|
|
130
|
+
"web_search",
|
|
131
|
+
"browse_url",
|
|
132
|
+
"read_file",
|
|
133
|
+
"search_files",
|
|
134
|
+
"osint_search",
|
|
135
|
+
"osint_graph",
|
|
136
|
+
"osint_enrich",
|
|
137
|
+
"osint_analyze"
|
|
138
|
+
]
|
|
139
|
+
};
|
|
140
|
+
var agent_types_default = {
|
|
141
|
+
AGENT_SYSTEM_PROMPTS,
|
|
142
|
+
AGENT_TOOL_PERMISSIONS
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
AGENT_SYSTEM_PROMPTS,
|
|
147
|
+
AGENT_TOOL_PERMISSIONS,
|
|
148
|
+
agent_types_default
|
|
149
|
+
};
|
|
150
|
+
//# sourceMappingURL=chunk-LFDXEYYB.js.map
|