@datasynx/agentic-crm 0.1.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +270 -669
- package/dist/{approvals-DpjxGHFp.js → approvals-CmDT2eUg.js} +7 -24
- package/dist/approvals-CmDT2eUg.js.map +1 -0
- package/dist/{ask-CID3jnuL.js → ask-CDysGnRg.js} +6 -6
- package/dist/{ask-CID3jnuL.js.map → ask-CDysGnRg.js.map} +1 -1
- package/dist/atomic-write-8yjqqLtS.js +29 -0
- package/dist/atomic-write-8yjqqLtS.js.map +1 -0
- package/dist/atomic-write-BYmF-ThH.cjs +37 -0
- package/dist/atomic-write-BYmF-ThH.cjs.map +1 -0
- package/dist/attachments-CX2GAtsw.cjs +517 -0
- package/dist/attachments-CX2GAtsw.cjs.map +1 -0
- package/dist/attachments-D207gXfN.js +514 -0
- package/dist/attachments-D207gXfN.js.map +1 -0
- package/dist/attachments-rLa96rOK.js +514 -0
- package/dist/attachments-rLa96rOK.js.map +1 -0
- package/dist/auth-B5DcjJ_6.js +2 -0
- package/dist/{auth-DFWwWcYD.js → auth-DDXZTwS0.js} +4 -13
- package/dist/auth-DDXZTwS0.js.map +1 -0
- package/dist/{autofill-Di_-SP7t.js → autofill-B9VtlR2j.js} +2 -2
- package/dist/{autofill-Di_-SP7t.js.map → autofill-B9VtlR2j.js.map} +1 -1
- package/dist/{backup-CeMk9z86.js → backup-CTlIxUdO.js} +5 -7
- package/dist/backup-CTlIxUdO.js.map +1 -0
- package/dist/backup-LFnC09oV.js +2 -0
- package/dist/chunk-BfDYWZQ8.cjs +32 -0
- package/dist/chunk-BfDYWZQ8.cjs.map +1 -0
- package/dist/chunk-BhUZmQg5.js +32 -0
- package/dist/chunk-BhUZmQg5.js.map +1 -0
- package/dist/chunk-ChC83jai.js +2 -0
- package/dist/chunk-e_w8qqtP.js +32 -0
- package/dist/chunk-e_w8qqtP.js.map +1 -0
- package/dist/{churn-C28IgnAj.js → churn-DN9WDGNM.js} +3 -3
- package/dist/{churn-C28IgnAj.js.map → churn-DN9WDGNM.js.map} +1 -1
- package/dist/cli.js +285 -186
- package/dist/cli.js.map +1 -1
- package/dist/{compliance-CKSBoQUe.js → compliance-Bc12Hn9a.js} +3 -3
- package/dist/{compliance-CKSBoQUe.js.map → compliance-Bc12Hn9a.js.map} +1 -1
- package/dist/{compliance-CujOqAKk.js → compliance-TqYQXhBj.js} +1 -1
- package/dist/{compliance-B1kk5-YS.js → compliance-kq0xHRw3.js} +3 -3
- package/dist/{compliance-B1kk5-YS.js.map → compliance-kq0xHRw3.js.map} +1 -1
- package/dist/{compliance-B91zNvCR.cjs → compliance-pAj9FcGI.cjs} +3 -3
- package/dist/{compliance-B91zNvCR.cjs.map → compliance-pAj9FcGI.cjs.map} +1 -1
- package/dist/{context-builder-BzWAp3Zs.js → context-builder-7Uab5-G4.js} +3 -2
- package/dist/context-builder-7Uab5-G4.js.map +1 -0
- package/dist/context-builder-hmOPvgso.js +2 -0
- package/dist/{custom-fields-CzNeD3_v.js → custom-fields-BMyz5Ruh.js} +1 -1
- package/dist/{custom-fields-Pl2t9xzp.js → custom-fields-GzpOHW_2.js} +4 -13
- package/dist/custom-fields-GzpOHW_2.js.map +1 -0
- package/dist/{custom-objects-CIFrmQ2V.js → custom-objects-BNy-ayR-.js} +1 -1
- package/dist/{custom-objects-BHgn1GEX.js → custom-objects-CxW1gHwJ.js} +10 -25
- package/dist/custom-objects-CxW1gHwJ.js.map +1 -0
- package/dist/{customer-dir-DIylZ8Q6.js → customer-dir-CkMMXhb0.js} +9 -4
- package/dist/customer-dir-CkMMXhb0.js.map +1 -0
- package/dist/daemon/worker.js +66 -40
- package/dist/daemon/worker.js.map +1 -1
- package/dist/doctor-C14-vnJ1.js +103 -0
- package/dist/doctor-C14-vnJ1.js.map +1 -0
- package/dist/email-body-BFSRa0AW.cjs +42 -0
- package/dist/email-body-BFSRa0AW.cjs.map +1 -0
- package/dist/email-body-BOd7U-D2.js +42 -0
- package/dist/email-body-BOd7U-D2.js.map +1 -0
- package/dist/{enrichment-3XvgGDfB.js → enrichment-CDFdWmvD.js} +3 -3
- package/dist/{enrichment-3XvgGDfB.js.map → enrichment-CDFdWmvD.js.map} +1 -1
- package/dist/{file-lock-B_zi7NQl.js → file-lock-CcHotQkZ.js} +3 -4
- package/dist/file-lock-CcHotQkZ.js.map +1 -0
- package/dist/{gmail-sync-DIaxInDT.js → gmail-sync-B4Iu3AQb.js} +56 -22
- package/dist/gmail-sync-B4Iu3AQb.js.map +1 -0
- package/dist/{gmail-sync-hHm9gaWd.cjs → gmail-sync-BpSVESSe.cjs} +55 -21
- package/dist/gmail-sync-BpSVESSe.cjs.map +1 -0
- package/dist/{gmail-sync-rQaVqKWd.js → gmail-sync-DIbrPnTK.js} +55 -21
- package/dist/gmail-sync-DIbrPnTK.js.map +1 -0
- package/dist/{gmail-webhook-handler-e5Od25FX.js → gmail-webhook-handler-BzOFbvgh.js} +4 -4
- package/dist/{gmail-webhook-handler-e5Od25FX.js.map → gmail-webhook-handler-BzOFbvgh.js.map} +1 -1
- package/dist/{gmail-webhook-handler-DS7OlRPX.js → gmail-webhook-handler-CvSDW_Js.js} +2 -2
- package/dist/{goal-engine-KpBftn4V.js → goal-engine-BbroPhqm.js} +10 -11
- package/dist/goal-engine-BbroPhqm.js.map +1 -0
- package/dist/{goal-engine-CUZSpERI.js → goal-engine-CfDAJTFt.js} +1 -1
- package/dist/{google-drive-sync-DEPcqFca.js → google-drive-sync-B_I1d54Y.js} +3 -3
- package/dist/{google-drive-sync-DEPcqFca.js.map → google-drive-sync-B_I1d54Y.js.map} +1 -1
- package/dist/html-BaeOCZKE.js +36 -0
- package/dist/html-BaeOCZKE.js.map +1 -0
- package/dist/html-CmOku6jS.cjs +47 -0
- package/dist/html-CmOku6jS.cjs.map +1 -0
- package/dist/{hygiene-DZqfYpFf.js → hygiene-DzQPnc6P.js} +3 -3
- package/dist/{hygiene-DZqfYpFf.js.map → hygiene-DzQPnc6P.js.map} +1 -1
- package/dist/identity-CB7j-Zr1.js +2 -0
- package/dist/{identity-CI6olMNm.js → identity-_uZ3Lbr2.js} +2 -2
- package/dist/{identity-CI6olMNm.js.map → identity-_uZ3Lbr2.js.map} +1 -1
- package/dist/{import-hubspot-BaK71U_K.js → import-hubspot-CTId9IGV.js} +51 -45
- package/dist/import-hubspot-CTId9IGV.js.map +1 -0
- package/dist/{index-YqwMd6aQ.d.cts → index-BAutNcAT.d.cts} +20 -12
- package/dist/index-BAutNcAT.d.cts.map +1 -0
- package/dist/{index-V8BFaH-b.d.ts → index-FzDsNSSb.d.ts} +12 -4
- package/dist/index-FzDsNSSb.d.ts.map +1 -0
- package/dist/index.cjs +19 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -21
- package/dist/index.js.map +1 -1
- package/dist/interactions-writer-B2y-73lh.js +2 -0
- package/dist/{interactions-writer-SLHnoEeE.js → interactions-writer-B8XAzdqR.js} +34 -4
- package/dist/interactions-writer-B8XAzdqR.js.map +1 -0
- package/dist/{interactions-writer-CrPStUll.cjs → interactions-writer-BRJNrefF.cjs} +7 -3
- package/dist/interactions-writer-BRJNrefF.cjs.map +1 -0
- package/dist/{interactions-writer-DO3KcSR3.js → interactions-writer-ZQcpFOh9.js} +7 -3
- package/dist/interactions-writer-ZQcpFOh9.js.map +1 -0
- package/dist/json-store-WWsFzXub.js +43 -0
- package/dist/json-store-WWsFzXub.js.map +1 -0
- package/dist/{knowledge-base-D0Fh40kc.js → knowledge-base--063Kpa3.js} +51 -22
- package/dist/knowledge-base--063Kpa3.js.map +1 -0
- package/dist/{lancedb-CCBbpulq.js → lancedb-CswQEE5K.js} +1 -1
- package/dist/{lancedb-rlvWoPwl.js → lancedb-CuHKNsNZ.js} +4 -3
- package/dist/lancedb-CuHKNsNZ.js.map +1 -0
- package/dist/{lead-model-BCFzyktm.js → lead-model-CEmx7te7.js} +6 -14
- package/dist/lead-model-CEmx7te7.js.map +1 -0
- package/dist/{llm-Z8RIYkpF.js → llm-BnSUBisu.js} +2 -2
- package/dist/{llm-Z8RIYkpF.js.map → llm-BnSUBisu.js.map} +1 -1
- package/dist/{llm-iijeXmgq.cjs → llm-CXycmEl9.cjs} +2 -2
- package/dist/{llm-iijeXmgq.cjs.map → llm-CXycmEl9.cjs.map} +1 -1
- package/dist/{llm-DEjWcqmW.js → llm-DSX1-wFu.js} +1 -1
- package/dist/{llm-DvzZqva0.js → llm-PZzgPphl.js} +3 -3
- package/dist/{llm-DvzZqva0.js.map → llm-PZzgPphl.js.map} +1 -1
- package/dist/logger-BkInaGoV.cjs +167 -0
- package/dist/logger-BkInaGoV.cjs.map +1 -0
- package/dist/logger-Dyl4VcLO.js +147 -0
- package/dist/logger-Dyl4VcLO.js.map +1 -0
- package/dist/logger-UaF5p9d1.js +147 -0
- package/dist/logger-UaF5p9d1.js.map +1 -0
- package/dist/logger-vKQS34w9.js +2 -0
- package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
- package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
- package/dist/mcp.cjs +365 -319
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.d.cts.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +365 -319
- package/dist/mcp.js.map +1 -1
- package/dist/{memory-Cy6-Tbyl.js → memory-D8hmgD9d.js} +1 -1
- package/dist/{memory-Bb6ky3kb.js → memory-Dzr9dXSM.js} +4 -11
- package/dist/memory-Dzr9dXSM.js.map +1 -0
- package/dist/{microsoft-calendar-B6MMtUQK.js → microsoft-calendar-BgVR8GDv.js} +4 -4
- package/dist/{microsoft-calendar-B6MMtUQK.js.map → microsoft-calendar-BgVR8GDv.js.map} +1 -1
- package/dist/{microsoft-sync-CpZVoSuq.js → microsoft-sync-D30_XksI.js} +5 -5
- package/dist/{microsoft-sync-CpZVoSuq.js.map → microsoft-sync-D30_XksI.js.map} +1 -1
- package/dist/{nba-3wanmJ0U.js → nba-DwdfM93s.js} +3 -3
- package/dist/{nba-3wanmJ0U.js.map → nba-DwdfM93s.js.map} +1 -1
- package/dist/{notification-dispatcher-0vYNngWe.js → notification-dispatcher-inpKyuBz.js} +7 -3
- package/dist/notification-dispatcher-inpKyuBz.js.map +1 -0
- package/dist/{pipeline-writer-BqBrYrQc.js → pipeline-writer-0LJ6Qkat.js} +1 -1
- package/dist/{pipeline-writer-N2omexxp.cjs → pipeline-writer-B1tRAhuD.cjs} +11 -3
- package/dist/pipeline-writer-B1tRAhuD.cjs.map +1 -0
- package/dist/{pipeline-writer-BvVquKIe.js → pipeline-writer-CIllfnZl.js} +5 -3
- package/dist/pipeline-writer-CIllfnZl.js.map +1 -0
- package/dist/{pipeline-writer-eufx_0o1.js → pipeline-writer-rDj-ni6q.js} +6 -4
- package/dist/pipeline-writer-rDj-ni6q.js.map +1 -0
- package/dist/{proactive-agent-BgQXw3ac.js → proactive-agent-B7u3Bj_l.js} +6 -6
- package/dist/{proactive-agent-BgQXw3ac.js.map → proactive-agent-B7u3Bj_l.js.map} +1 -1
- package/dist/{proactive-worker-BrLHNhjH.js → proactive-worker-1zkm6aJD.js} +7 -8
- package/dist/proactive-worker-1zkm6aJD.js.map +1 -0
- package/dist/{push-manager-CowY-0IK.js → push-manager-BXM-IHfP.js} +1 -1
- package/dist/{push-manager-CdqIIkuh.js → push-manager-C0ECQgva.js} +4 -4
- package/dist/push-manager-C0ECQgva.js.map +1 -0
- package/dist/{quote-generator-OhSFsi3x.js → quote-generator-ByUyIYtw.js} +1 -1
- package/dist/{quote-generator-BfwENXzg.js → quote-generator-CTdR8eEI.js} +5 -5
- package/dist/quote-generator-CTdR8eEI.js.map +1 -0
- package/dist/rbac-DzbyFhVH.js +2 -0
- package/dist/{rbac-CTIktZaC.js → rbac-msmBc_tK.js} +19 -12
- package/dist/rbac-msmBc_tK.js.map +1 -0
- package/dist/regex-Jt5DatPi.js +13 -0
- package/dist/regex-Jt5DatPi.js.map +1 -0
- package/dist/{relationship-health-odxEoQdJ.js → relationship-health-ZZNXR1RZ.js} +8 -16
- package/dist/relationship-health-ZZNXR1RZ.js.map +1 -0
- package/dist/{revenue-simulation-Bqf2DLVB.js → revenue-simulation-D8f_YkUY.js} +9 -19
- package/dist/revenue-simulation-D8f_YkUY.js.map +1 -0
- package/dist/{revenue-simulation-BJdRTEHc.js → revenue-simulation-njJZlTqm.js} +1 -1
- package/dist/safe-path-mpp0dKtO.js +18 -0
- package/dist/safe-path-mpp0dKtO.js.map +1 -0
- package/dist/{segments-BqcD5HIl.js → segments-DI3LOQNe.js} +5 -14
- package/dist/segments-DI3LOQNe.js.map +1 -0
- package/dist/sequence-engine-C6nnewHX.js +2 -0
- package/dist/{sequence-engine-J1lTW_in.js → sequence-engine-DNTVLq7o.js} +15 -8
- package/dist/sequence-engine-DNTVLq7o.js.map +1 -0
- package/dist/{sequence-store-DaaWr0Os.js → sequence-store-CmYb6s0g.js} +6 -5
- package/dist/sequence-store-CmYb6s0g.js.map +1 -0
- package/dist/{server-Dyva03K8.js → server-DoRPPOeR.js} +308 -230
- package/dist/server-DoRPPOeR.js.map +1 -0
- package/dist/{session-D9ub6Wl1.js → session-B6XaP83h.js} +3 -3
- package/dist/session-B6XaP83h.js.map +1 -0
- package/dist/{session-B9AilxOE.js → session-BgGDyP2C.js} +3 -3
- package/dist/session-BgGDyP2C.js.map +1 -0
- package/dist/session-Bp4zTh4l.js +2 -0
- package/dist/{session-D0qFkBla.cjs → session-Mm7GQbSH.cjs} +3 -3
- package/dist/session-Mm7GQbSH.cjs.map +1 -0
- package/dist/{session-store-C8tEvMPw.js → session-store-DWxJ5Pof.js} +79 -17
- package/dist/session-store-DWxJ5Pof.js.map +1 -0
- package/dist/{session-store-B0QZE8Bx.cjs → session-store-yfwnj0OC.cjs} +126 -16
- package/dist/session-store-yfwnj0OC.cjs.map +1 -0
- package/dist/{sla-engine-5IhTsBUR.js → sla-engine-CP2KiKDS.js} +1 -1
- package/dist/{sla-engine-BqX-7u-7.js → sla-engine-O-A1ntu_.js} +2 -2
- package/dist/{sla-engine-BqX-7u-7.js.map → sla-engine-O-A1ntu_.js.map} +1 -1
- package/dist/{sop-Vp0UPWFW.js → sop-BV7ICAFR.js} +4 -11
- package/dist/sop-BV7ICAFR.js.map +1 -0
- package/dist/{sop-DkhVChGy.js → sop-D33qTHUb.js} +1 -1
- package/dist/survey-engine-DKctGcLQ.js +2 -0
- package/dist/{survey-engine-DBjCYqCv.js → survey-engine-DngXBv47.js} +5 -4
- package/dist/survey-engine-DngXBv47.js.map +1 -0
- package/dist/{sync-state-CwLSt_1m.js → sync-state-BaA8LbTI.js} +1 -1
- package/dist/{sync-state-ChaLbamC.js → sync-state-DMZgzpez.js} +4 -12
- package/dist/sync-state-DMZgzpez.js.map +1 -0
- package/dist/{ticket-writer-CjqKeIRD.js → ticket-writer-DsfpeLGZ.js} +1 -1
- package/dist/{ticket-writer-j2oX_Wal.js → ticket-writer-a9on36Wb.js} +12 -24
- package/dist/ticket-writer-a9on36Wb.js.map +1 -0
- package/dist/{tone-Bdm5uaht.js → tone-C7bqK69y.js} +5 -12
- package/dist/tone-C7bqK69y.js.map +1 -0
- package/dist/{tone-DRKlZgPr.cjs → tone-Cmc7O2Fx.cjs} +3 -9
- package/dist/tone-Cmc7O2Fx.cjs.map +1 -0
- package/dist/{tone-vNb2DAAD.js → tone-mXSftvTn.js} +3 -8
- package/dist/tone-mXSftvTn.js.map +1 -0
- package/dist/{transcript-watcher-CL2QUygI.js → transcript-watcher-BoClrJAz.js} +18 -11
- package/dist/transcript-watcher-BoClrJAz.js.map +1 -0
- package/dist/unmatched-transcripts-C92zAoM4.js +2 -0
- package/dist/unmatched-transcripts-DC-VQ9YS.js +16 -0
- package/dist/unmatched-transcripts-DC-VQ9YS.js.map +1 -0
- package/dist/update-deal-CWy1eLJI.js +2 -0
- package/dist/{update-deal-DKC79skb.js → update-deal-DSzr_Aau.js} +3 -3
- package/dist/{update-deal-DKC79skb.js.map → update-deal-DSzr_Aau.js.map} +1 -1
- package/dist/{usage-D0-TYJkw.js → usage-BVlFlKW_.js} +8 -6
- package/dist/usage-BVlFlKW_.js.map +1 -0
- package/dist/usage-CClTf5e6.cjs.map +1 -1
- package/dist/usage-D0u9a-lV.js.map +1 -1
- package/dist/{vault-DXCg29W-.js → vault-CfwZdNzC.js} +3 -4
- package/dist/vault-CfwZdNzC.js.map +1 -0
- package/dist/{vault-C1D3zScD.js → vault-DxKP4_R2.js} +1 -1
- package/dist/{webhooks-Xn6zO6kd.cjs → webhooks-CwW-3kvG.cjs} +5 -19
- package/dist/webhooks-CwW-3kvG.cjs.map +1 -0
- package/dist/{webhooks-7EpA05Qr.js → webhooks-DXr1IoKn.js} +8 -21
- package/dist/webhooks-DXr1IoKn.js.map +1 -0
- package/dist/{webhooks-BO2UAnmn.js → webhooks-sWZ8CJtR.js} +5 -18
- package/dist/webhooks-sWZ8CJtR.js.map +1 -0
- package/package.json +22 -2
- package/dist/approvals-DpjxGHFp.js.map +0 -1
- package/dist/auth-CyFuu9X_.js +0 -2
- package/dist/auth-DFWwWcYD.js.map +0 -1
- package/dist/backup-CeMk9z86.js.map +0 -1
- package/dist/backup-f_hC7rBV.js +0 -2
- package/dist/context-builder-BzWAp3Zs.js.map +0 -1
- package/dist/context-builder-DlrRcqmJ.js +0 -2
- package/dist/custom-fields-Pl2t9xzp.js.map +0 -1
- package/dist/custom-objects-BHgn1GEX.js.map +0 -1
- package/dist/customer-dir-DIylZ8Q6.js.map +0 -1
- package/dist/file-lock-B_zi7NQl.js.map +0 -1
- package/dist/gmail-sync-DIaxInDT.js.map +0 -1
- package/dist/gmail-sync-hHm9gaWd.cjs.map +0 -1
- package/dist/gmail-sync-rQaVqKWd.js.map +0 -1
- package/dist/goal-engine-KpBftn4V.js.map +0 -1
- package/dist/identity-gyfWdrcX.js +0 -2
- package/dist/import-hubspot-BaK71U_K.js.map +0 -1
- package/dist/index-V8BFaH-b.d.ts.map +0 -1
- package/dist/index-YqwMd6aQ.d.cts.map +0 -1
- package/dist/interactions-writer-CrPStUll.cjs.map +0 -1
- package/dist/interactions-writer-DO3KcSR3.js.map +0 -1
- package/dist/interactions-writer-SLHnoEeE.js.map +0 -1
- package/dist/interactions-writer-dSPy1XfO.js +0 -2
- package/dist/knowledge-base-D0Fh40kc.js.map +0 -1
- package/dist/lancedb-rlvWoPwl.js.map +0 -1
- package/dist/lead-model-BCFzyktm.js.map +0 -1
- package/dist/memory-Bb6ky3kb.js.map +0 -1
- package/dist/notification-dispatcher-0vYNngWe.js.map +0 -1
- package/dist/pipeline-writer-BvVquKIe.js.map +0 -1
- package/dist/pipeline-writer-N2omexxp.cjs.map +0 -1
- package/dist/pipeline-writer-eufx_0o1.js.map +0 -1
- package/dist/proactive-worker-BrLHNhjH.js.map +0 -1
- package/dist/push-manager-CdqIIkuh.js.map +0 -1
- package/dist/quote-generator-BfwENXzg.js.map +0 -1
- package/dist/rbac-C7c8tcES.js +0 -2
- package/dist/rbac-CTIktZaC.js.map +0 -1
- package/dist/relationship-health-odxEoQdJ.js.map +0 -1
- package/dist/revenue-simulation-Bqf2DLVB.js.map +0 -1
- package/dist/segments-BqcD5HIl.js.map +0 -1
- package/dist/sequence-engine-CCTHEBgi.js +0 -2
- package/dist/sequence-engine-J1lTW_in.js.map +0 -1
- package/dist/sequence-store-DaaWr0Os.js.map +0 -1
- package/dist/server-Dyva03K8.js.map +0 -1
- package/dist/session-B9AilxOE.js.map +0 -1
- package/dist/session-D0qFkBla.cjs.map +0 -1
- package/dist/session-D9ub6Wl1.js.map +0 -1
- package/dist/session-mWHA71Lw.js +0 -2
- package/dist/session-store-B0QZE8Bx.cjs.map +0 -1
- package/dist/session-store-C8tEvMPw.js.map +0 -1
- package/dist/sop-Vp0UPWFW.js.map +0 -1
- package/dist/survey-engine-C06hcQt3.js +0 -2
- package/dist/survey-engine-DBjCYqCv.js.map +0 -1
- package/dist/sync-state-ChaLbamC.js.map +0 -1
- package/dist/ticket-writer-j2oX_Wal.js.map +0 -1
- package/dist/tone-Bdm5uaht.js.map +0 -1
- package/dist/tone-DRKlZgPr.cjs.map +0 -1
- package/dist/tone-vNb2DAAD.js.map +0 -1
- package/dist/transcript-watcher-CL2QUygI.js.map +0 -1
- package/dist/unmatched-transcripts-BsH5bhkU.js +0 -26
- package/dist/unmatched-transcripts-BsH5bhkU.js.map +0 -1
- package/dist/unmatched-transcripts-D0PrJ9iz.js +0 -2
- package/dist/update-deal-BNwPGaTV.js +0 -2
- package/dist/usage-D0-TYJkw.js.map +0 -1
- package/dist/vault-DXCg29W-.js.map +0 -1
- package/dist/webhooks-7EpA05Qr.js.map +0 -1
- package/dist/webhooks-BO2UAnmn.js.map +0 -1
- package/dist/webhooks-Xn6zO6kd.cjs.map +0 -1
package/dist/mcp.cjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-DakpK96I.cjs");
|
|
3
|
-
const require_session_store = require("./session-store-
|
|
3
|
+
const require_session_store = require("./session-store-yfwnj0OC.cjs");
|
|
4
|
+
const require_atomic_write = require("./atomic-write-BYmF-ThH.cjs");
|
|
4
5
|
const require_write_queue = require("./write-queue-BDolUxfs.cjs");
|
|
5
|
-
const require_interactions_writer = require("./interactions-writer-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const require_interactions_writer = require("./interactions-writer-BRJNrefF.cjs");
|
|
7
|
+
const require_logger = require("./logger-BkInaGoV.cjs");
|
|
8
|
+
const require_pipeline_writer = require("./pipeline-writer-B1tRAhuD.cjs");
|
|
9
|
+
const require_llm = require("./llm-CXycmEl9.cjs");
|
|
8
10
|
let path = require("path");
|
|
9
11
|
path = require_chunk.__toESM(path, 1);
|
|
10
12
|
let fs = require("fs");
|
|
@@ -63,11 +65,10 @@ async function readSubscriptions(dataDir) {
|
|
|
63
65
|
async function writeSubscriptions(dataDir, subs) {
|
|
64
66
|
const filePath = subscriptionsPath(dataDir);
|
|
65
67
|
fs.default.mkdirSync(path.default.dirname(filePath), { recursive: true });
|
|
66
|
-
|
|
68
|
+
require_session_store.writeJsonFile(filePath, {
|
|
67
69
|
subscriptions: subs,
|
|
68
70
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
69
|
-
};
|
|
70
|
-
fs.default.writeFileSync(filePath, JSON.stringify(file, null, 2), "utf-8");
|
|
71
|
+
});
|
|
71
72
|
}
|
|
72
73
|
function expiresAtForProvider(provider) {
|
|
73
74
|
if (provider === "gmail") return new Date(Date.now() + 10080 * 60 * 1e3).toISOString();
|
|
@@ -98,23 +99,15 @@ function getSyncStatePath(dataDir) {
|
|
|
98
99
|
return path.default.join(dataDir, ".agentic", "sync-state.json");
|
|
99
100
|
}
|
|
100
101
|
function readSyncState(dataDir) {
|
|
101
|
-
|
|
102
|
-
if (!fs.default.existsSync(filePath)) return {};
|
|
103
|
-
try {
|
|
104
|
-
return JSON.parse(fs.default.readFileSync(filePath, "utf-8"));
|
|
105
|
-
} catch {
|
|
106
|
-
return {};
|
|
107
|
-
}
|
|
102
|
+
return require_session_store.readJsonFile(getSyncStatePath(dataDir), {});
|
|
108
103
|
}
|
|
109
104
|
function updateSlugSyncState(dataDir, slug, update) {
|
|
110
|
-
const filePath = getSyncStatePath(dataDir);
|
|
111
|
-
fs.default.mkdirSync(path.default.dirname(filePath), { recursive: true });
|
|
112
105
|
const state = readSyncState(dataDir);
|
|
113
106
|
state[slug] = {
|
|
114
107
|
...state[slug],
|
|
115
108
|
...update
|
|
116
109
|
};
|
|
117
|
-
|
|
110
|
+
require_session_store.writeJsonFile(getSyncStatePath(dataDir), state);
|
|
118
111
|
}
|
|
119
112
|
function getLastGmailSync(dataDir, slug) {
|
|
120
113
|
const ts = readSyncState(dataDir)[slug]?.lastGmailSync;
|
|
@@ -412,7 +405,7 @@ Config: \`.agentic/rbac.json\` | Actor: \`DXCRM_ACTOR\` env var
|
|
|
412
405
|
| log_interaction | Write a new interaction entry (call, email, meeting, note) — immediately searchable | rep+ |
|
|
413
406
|
| update_deal | Create or update a deal in pipeline.md — upserts by deal name | rep+ |
|
|
414
407
|
| update_customer_facts | Update fields in customer profile (domain, contact, stage, tags) | admin |
|
|
415
|
-
| export_customer | Export all customer data as JSON or Markdown | admin |
|
|
408
|
+
| export_customer | Export all customer data (incl. attachment contents) as JSON or Markdown | admin |
|
|
416
409
|
| get_deal_health | Score deal health 0–100 (A–F grade) based on activity, velocity, close date, probability | any |
|
|
417
410
|
| get_pipeline_forecast | Aggregate weighted pipeline revenue across all customers grouped by stage | any |
|
|
418
411
|
| get_pipeline_stages | List all configured pipeline stages (defaults: lead, qualified, proposal, negotiation, won, lost) | any |
|
|
@@ -456,6 +449,7 @@ Config: \`.agentic/rbac.json\` | Actor: \`DXCRM_ACTOR\` env var
|
|
|
456
449
|
| list_backups | List available backups with date, size, verification status, and customer count | any |
|
|
457
450
|
| trigger_sync | Force immediate Gmail sync for one or all customers | rep+ |
|
|
458
451
|
| get_audit_log | Read audit log — all write operations with actor, tool, customer | admin |
|
|
452
|
+
| get_logs | Query/aggregate the structured application log (level, component, errors) | admin |
|
|
459
453
|
| define_custom_object | Define a runtime custom object type with typed fields (no migration) | admin |
|
|
460
454
|
| create_record | Create a record of a custom object (validated against its schema) | rep+ |
|
|
461
455
|
| list_records | List records of a custom object | any |
|
|
@@ -545,12 +539,14 @@ RBAC: admin
|
|
|
545
539
|
- Input: slug (required) + any combination of the optional fields
|
|
546
540
|
- Returns: { success: boolean, facts: object }
|
|
547
541
|
|
|
548
|
-
### export_customer({ slug, format? })
|
|
549
|
-
Export all customer data (main_facts + interactions
|
|
542
|
+
### export_customer({ slug, format?, includeAttachmentContent? })
|
|
543
|
+
Export all customer data (main_facts + interactions + pipeline + attachments).
|
|
544
|
+
Set includeAttachmentContent to inline every attachment's converted Markdown —
|
|
545
|
+
a single sendable bundle of all conversations and documents for the customer.
|
|
550
546
|
RBAC: admin
|
|
551
|
-
- Input: { slug: string, format?: "json" | "markdown" (default "json") }
|
|
552
|
-
- Returns (JSON): { slug, exportedAt, mainFacts, interactionsCount, pipeline, attachments }
|
|
553
|
-
- Returns (Markdown): Formatted document with all sections
|
|
547
|
+
- Input: { slug: string, format?: "json" | "markdown" (default "json"), includeAttachmentContent?: boolean (default false) }
|
|
548
|
+
- Returns (JSON): { slug, exportedAt, mainFacts, interactionsCount, pipeline, attachments[, attachmentContents] }
|
|
549
|
+
- Returns (Markdown): Formatted document with all sections (and attachment contents when requested)
|
|
554
550
|
|
|
555
551
|
### get_deal_health({ slug })
|
|
556
552
|
Score the health of all deals for a customer based on activity recency, stage velocity,
|
|
@@ -1330,6 +1326,16 @@ function registerGetActiveSession(server) {
|
|
|
1330
1326
|
}, async () => handleGetActiveSession());
|
|
1331
1327
|
}
|
|
1332
1328
|
//#endregion
|
|
1329
|
+
//#region src/core/regex.ts
|
|
1330
|
+
/**
|
|
1331
|
+
* Escape a string so it can be embedded safely as a literal inside a `RegExp`.
|
|
1332
|
+
* Prevents both broken patterns and ReDoS/injection when interpolating
|
|
1333
|
+
* field names, section headers, or other dynamic values into a regex.
|
|
1334
|
+
*/
|
|
1335
|
+
function escapeRegExp(value) {
|
|
1336
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1337
|
+
}
|
|
1338
|
+
//#endregion
|
|
1333
1339
|
//#region src/core/context-builder.ts
|
|
1334
1340
|
var context_builder_exports = /* @__PURE__ */ require_chunk.__exportAll({ buildContext: () => buildContext });
|
|
1335
1341
|
const MAX_INTERACTIONS = 10;
|
|
@@ -1345,7 +1351,7 @@ function parsePipelineContent(filePath) {
|
|
|
1345
1351
|
return fs.default.readFileSync(filePath, "utf-8").trim();
|
|
1346
1352
|
}
|
|
1347
1353
|
function extractSection(content, sectionName) {
|
|
1348
|
-
const match = new RegExp(`## ${sectionName}([\\s\\S]*?)(?=^## |$)`, "m").exec(content);
|
|
1354
|
+
const match = new RegExp(`## ${escapeRegExp(sectionName)}([\\s\\S]*?)(?=^## |$)`, "m").exec(content);
|
|
1349
1355
|
return match ? (match[1] ?? "").trim() : "";
|
|
1350
1356
|
}
|
|
1351
1357
|
async function buildContext(dataDir, slug) {
|
|
@@ -1422,7 +1428,7 @@ async function buildContext(dataDir, slug) {
|
|
|
1422
1428
|
}
|
|
1423
1429
|
//#endregion
|
|
1424
1430
|
//#region src/mcp/tools/get-customer-context.ts
|
|
1425
|
-
const DATA_DIR$
|
|
1431
|
+
const DATA_DIR$52 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1426
1432
|
function triggerOnQuerySync(dataDir, slug) {
|
|
1427
1433
|
const auth = getGmailAuth();
|
|
1428
1434
|
if (!auth) return;
|
|
@@ -1435,7 +1441,7 @@ function triggerOnQuerySync(dataDir, slug) {
|
|
|
1435
1441
|
const sources = JSON.parse(fs.default.readFileSync(sourcesPath, "utf-8"));
|
|
1436
1442
|
if (!sources.gmail?.enabled || !sources.gmail.query) return;
|
|
1437
1443
|
const query = sources.gmail.query;
|
|
1438
|
-
Promise.resolve().then(() => require("./gmail-sync-
|
|
1444
|
+
Promise.resolve().then(() => require("./gmail-sync-BpSVESSe.cjs")).then(({ syncGmail }) => syncGmail({
|
|
1439
1445
|
slug,
|
|
1440
1446
|
dataDir,
|
|
1441
1447
|
auth,
|
|
@@ -1443,7 +1449,7 @@ function triggerOnQuerySync(dataDir, slug) {
|
|
|
1443
1449
|
}).then(() => updateSlugSyncState(dataDir, slug, { lastGmailSync: (/* @__PURE__ */ new Date()).toISOString() })).catch(() => {})).catch(() => {});
|
|
1444
1450
|
} catch {}
|
|
1445
1451
|
}
|
|
1446
|
-
async function handleGetCustomerContext(input, dataDir = DATA_DIR$
|
|
1452
|
+
async function handleGetCustomerContext(input, dataDir = DATA_DIR$52) {
|
|
1447
1453
|
const targetSlug = input.slug ?? require_session_store.getSession()?.customerSlug;
|
|
1448
1454
|
if (!targetSlug) return {
|
|
1449
1455
|
content: [{
|
|
@@ -1559,7 +1565,7 @@ async function indexInLanceDB(dataDir, slug, text, sourceRef, meta) {
|
|
|
1559
1565
|
}]);
|
|
1560
1566
|
await table.mergeInsert("source_ref").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(data);
|
|
1561
1567
|
} catch (err) {
|
|
1562
|
-
|
|
1568
|
+
require_logger.logger.error("lancedb", "indexInLanceDB failed", { error: err.message });
|
|
1563
1569
|
}
|
|
1564
1570
|
}
|
|
1565
1571
|
async function searchKnowledge(dataDir, slug, query, limit) {
|
|
@@ -1579,8 +1585,8 @@ async function searchKnowledge(dataDir, slug, query, limit) {
|
|
|
1579
1585
|
}
|
|
1580
1586
|
//#endregion
|
|
1581
1587
|
//#region src/mcp/tools/search-customer-knowledge.ts
|
|
1582
|
-
const DATA_DIR$
|
|
1583
|
-
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$
|
|
1588
|
+
const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1589
|
+
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$51) {
|
|
1584
1590
|
const limit = input.limit ?? 5;
|
|
1585
1591
|
try {
|
|
1586
1592
|
const results = await searchKnowledge(dataDir, input.slug, input.query, limit);
|
|
@@ -1628,14 +1634,14 @@ If no results: returns empty array with a helpful sync suggestion.`,
|
|
|
1628
1634
|
}
|
|
1629
1635
|
//#endregion
|
|
1630
1636
|
//#region src/mcp/tools/list-customers.ts
|
|
1631
|
-
const DATA_DIR$
|
|
1637
|
+
const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1632
1638
|
function extractLastInteractionDate(interactionsPath) {
|
|
1633
1639
|
if (!fs.default.existsSync(interactionsPath)) return void 0;
|
|
1634
1640
|
const content = fs.default.readFileSync(interactionsPath, "utf-8");
|
|
1635
1641
|
const match = /^## (\d{4}-\d{2}-\d{2})/m.exec(content);
|
|
1636
1642
|
return match ? match[1] : void 0;
|
|
1637
1643
|
}
|
|
1638
|
-
async function handleListCustomers(input, dataDir = DATA_DIR$
|
|
1644
|
+
async function handleListCustomers(input, dataDir = DATA_DIR$50) {
|
|
1639
1645
|
const customersDir = path.default.join(dataDir, "customers");
|
|
1640
1646
|
const customers = [];
|
|
1641
1647
|
if (!fs.default.existsSync(customersDir)) return { content: [{
|
|
@@ -1643,6 +1649,7 @@ async function handleListCustomers(input, dataDir = DATA_DIR$49) {
|
|
|
1643
1649
|
text: JSON.stringify([], null, 2)
|
|
1644
1650
|
}] };
|
|
1645
1651
|
const entries = fs.default.readdirSync(customersDir);
|
|
1652
|
+
const canSee = require_session_store.customerVisibility(dataDir, process.env["DXCRM_ACTOR"] ?? "system");
|
|
1646
1653
|
for (const entry of entries) {
|
|
1647
1654
|
const customerDir = path.default.join(customersDir, entry);
|
|
1648
1655
|
try {
|
|
@@ -1669,7 +1676,7 @@ async function handleListCustomers(input, dataDir = DATA_DIR$49) {
|
|
|
1669
1676
|
const filterLower = input.filter.toLowerCase();
|
|
1670
1677
|
if (!(name.toLowerCase().includes(filterLower) || entry.toLowerCase().includes(filterLower) || stage.toLowerCase().includes(filterLower))) continue;
|
|
1671
1678
|
}
|
|
1672
|
-
if (!
|
|
1679
|
+
if (!canSee(entry)) continue;
|
|
1673
1680
|
customers.push(summary);
|
|
1674
1681
|
} catch {
|
|
1675
1682
|
continue;
|
|
@@ -1704,8 +1711,7 @@ async function withJsonFile(filePath, updater) {
|
|
|
1704
1711
|
current = null;
|
|
1705
1712
|
}
|
|
1706
1713
|
const next = await updater(current);
|
|
1707
|
-
|
|
1708
|
-
fs.default.writeFileSync(filePath, JSON.stringify(next, null, 2), "utf-8");
|
|
1714
|
+
require_atomic_write.writeFileAtomic(filePath, JSON.stringify(next, null, 2));
|
|
1709
1715
|
return next;
|
|
1710
1716
|
});
|
|
1711
1717
|
}
|
|
@@ -1729,7 +1735,7 @@ function readGraph(dataDir, slug) {
|
|
|
1729
1735
|
try {
|
|
1730
1736
|
return JSON.parse(fs.default.readFileSync(p, "utf-8"));
|
|
1731
1737
|
} catch {
|
|
1732
|
-
|
|
1738
|
+
require_logger.logger.warn("graph", "failed to parse graph file — returning empty graph", { path: p });
|
|
1733
1739
|
return emptyGraph(slug);
|
|
1734
1740
|
}
|
|
1735
1741
|
}
|
|
@@ -1982,23 +1988,13 @@ function healthPath(dataDir, slug) {
|
|
|
1982
1988
|
return path.default.join(dataDir, "customers", slug, "health.json");
|
|
1983
1989
|
}
|
|
1984
1990
|
function readHealth(dataDir, slug) {
|
|
1985
|
-
|
|
1986
|
-
if (!fs.default.existsSync(p)) return null;
|
|
1987
|
-
try {
|
|
1988
|
-
return JSON.parse(fs.default.readFileSync(p, "utf-8"));
|
|
1989
|
-
} catch {
|
|
1990
|
-
return null;
|
|
1991
|
-
}
|
|
1991
|
+
return require_session_store.readJsonFile(healthPath(dataDir, slug), null);
|
|
1992
1992
|
}
|
|
1993
1993
|
function writeHealth(dataDir, slug, health) {
|
|
1994
|
-
|
|
1995
|
-
const dir = path.default.dirname(p);
|
|
1996
|
-
if (!fs.default.existsSync(dir)) fs.default.mkdirSync(dir, { recursive: true });
|
|
1997
|
-
const updated = {
|
|
1994
|
+
require_session_store.writeJsonFile(healthPath(dataDir, slug), {
|
|
1998
1995
|
...health,
|
|
1999
1996
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2000
|
-
};
|
|
2001
|
-
fs.default.writeFileSync(p, JSON.stringify(updated, null, 2), "utf-8");
|
|
1997
|
+
});
|
|
2002
1998
|
}
|
|
2003
1999
|
function parseContactInteractions(content) {
|
|
2004
2000
|
const blocks = content.split(/(?=^## \d{4}-\d{2}-\d{2})/m).filter((b) => b.trim().length > 0);
|
|
@@ -2158,8 +2154,8 @@ async function updateHealthFromInteraction(dataDir, slug) {
|
|
|
2158
2154
|
}
|
|
2159
2155
|
//#endregion
|
|
2160
2156
|
//#region src/mcp/tools/log-interaction.ts
|
|
2161
|
-
const DATA_DIR$
|
|
2162
|
-
async function handleLogInteraction(input, dataDir = DATA_DIR$
|
|
2157
|
+
const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2158
|
+
async function handleLogInteraction(input, dataDir = DATA_DIR$49) {
|
|
2163
2159
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2164
2160
|
const interactionDate = input.date ?? today;
|
|
2165
2161
|
const sourceRef = input.source ?? `agent://log/${Date.now()}`;
|
|
@@ -2189,7 +2185,7 @@ async function handleLogInteraction(input, dataDir = DATA_DIR$48) {
|
|
|
2189
2185
|
raw.data.last_touchpoint = interactionDate;
|
|
2190
2186
|
let serialized = gray_matter.default.stringify(raw.content, raw.data);
|
|
2191
2187
|
serialized = serialized.replace(/^(last_touchpoint:\s*)['"](\d{4}-\d{2}-\d{2})['"]/m, "$1$2");
|
|
2192
|
-
|
|
2188
|
+
require_atomic_write.writeFileAtomic(mainFactsPath, serialized);
|
|
2193
2189
|
} catch {}
|
|
2194
2190
|
require_session_store.writeAuditEntry(dataDir, {
|
|
2195
2191
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -2268,8 +2264,8 @@ var update_deal_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
|
2268
2264
|
handleUpdateDeal: () => handleUpdateDeal,
|
|
2269
2265
|
registerUpdateDeal: () => registerUpdateDeal
|
|
2270
2266
|
});
|
|
2271
|
-
const DATA_DIR$
|
|
2272
|
-
async function handleUpdateDeal(input, dataDir = DATA_DIR$
|
|
2267
|
+
const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2268
|
+
async function handleUpdateDeal(input, dataDir = DATA_DIR$48) {
|
|
2273
2269
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2274
2270
|
const deal = {
|
|
2275
2271
|
name: input.dealName,
|
|
@@ -2352,12 +2348,12 @@ Returns: { success: boolean, deal: object }`,
|
|
|
2352
2348
|
}
|
|
2353
2349
|
//#endregion
|
|
2354
2350
|
//#region src/mcp/tools/export-customer.ts
|
|
2355
|
-
const DATA_DIR$
|
|
2351
|
+
const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2356
2352
|
function countInteractions(content) {
|
|
2357
2353
|
const matches = content.match(/^## \d{4}-\d{2}-\d{2}/gm);
|
|
2358
2354
|
return matches ? matches.length : 0;
|
|
2359
2355
|
}
|
|
2360
|
-
async function handleExportCustomer(input, dataDir = DATA_DIR$
|
|
2356
|
+
async function handleExportCustomer(input, dataDir = DATA_DIR$47) {
|
|
2361
2357
|
require_session_store.enforceRbac(dataDir, "export_customer");
|
|
2362
2358
|
const customerDir = path.default.join(dataDir, "customers", input.slug);
|
|
2363
2359
|
if (!fs.default.existsSync(customerDir)) return {
|
|
@@ -2384,14 +2380,27 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$46) {
|
|
|
2384
2380
|
interactionsCount = countInteractions(interactionsContent);
|
|
2385
2381
|
}
|
|
2386
2382
|
const pipeline = await require_pipeline_writer.readPipeline(dataDir, input.slug);
|
|
2383
|
+
const includeAttachmentContent = input.includeAttachmentContent ?? false;
|
|
2387
2384
|
const attachmentsDir = path.default.join(customerDir, "attachments");
|
|
2388
2385
|
const attachments = [];
|
|
2386
|
+
const attachmentContents = {};
|
|
2389
2387
|
if (fs.default.existsSync(attachmentsDir)) try {
|
|
2390
2388
|
const files = fs.default.readdirSync(attachmentsDir);
|
|
2391
2389
|
for (const f of files) try {
|
|
2392
|
-
if (fs.default.statSync(path.default.join(attachmentsDir, f)).isFile())
|
|
2390
|
+
if (!fs.default.statSync(path.default.join(attachmentsDir, f)).isFile()) continue;
|
|
2391
|
+
attachments.push(f);
|
|
2392
|
+
if (includeAttachmentContent && f.endsWith(".md")) attachmentContents[f] = fs.default.readFileSync(path.default.join(attachmentsDir, f), "utf-8");
|
|
2393
2393
|
} catch {}
|
|
2394
2394
|
} catch {}
|
|
2395
|
+
const attachmentContentSection = () => {
|
|
2396
|
+
const entries = Object.entries(attachmentContents);
|
|
2397
|
+
if (!includeAttachmentContent || entries.length === 0) return [];
|
|
2398
|
+
return [
|
|
2399
|
+
"",
|
|
2400
|
+
`## Attachment Contents (${entries.length})`,
|
|
2401
|
+
...entries.map(([name, content]) => `\n### ${name}\n\n${content.trim()}`)
|
|
2402
|
+
];
|
|
2403
|
+
};
|
|
2395
2404
|
if (format === "markdown") return { content: [{
|
|
2396
2405
|
type: "text",
|
|
2397
2406
|
text: [
|
|
@@ -2410,7 +2419,8 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$46) {
|
|
|
2410
2419
|
pipeline.length > 0 ? pipeline.map((d) => `- **${d.name}** · ${d.stage}${d.value !== void 0 ? ` · €${d.value}` : ""}${d.close_date ? ` · close: ${d.close_date}` : ""}`).join("\n") : "(no deals)",
|
|
2411
2420
|
"",
|
|
2412
2421
|
`## Attachments (${attachments.length})`,
|
|
2413
|
-
attachments.length > 0 ? attachments.map((f) => `- ${f}`).join("\n") : "(none)"
|
|
2422
|
+
attachments.length > 0 ? attachments.map((f) => `- ${f}`).join("\n") : "(none)",
|
|
2423
|
+
...attachmentContentSection()
|
|
2414
2424
|
].join("\n")
|
|
2415
2425
|
}] };
|
|
2416
2426
|
const exported = {
|
|
@@ -2419,7 +2429,8 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$46) {
|
|
|
2419
2429
|
mainFacts,
|
|
2420
2430
|
interactionsCount,
|
|
2421
2431
|
pipeline,
|
|
2422
|
-
attachments
|
|
2432
|
+
attachments,
|
|
2433
|
+
...includeAttachmentContent ? { attachmentContents } : {}
|
|
2423
2434
|
};
|
|
2424
2435
|
return { content: [{
|
|
2425
2436
|
type: "text",
|
|
@@ -2429,29 +2440,34 @@ async function handleExportCustomer(input, dataDir = DATA_DIR$46) {
|
|
|
2429
2440
|
function registerExportCustomer(server) {
|
|
2430
2441
|
server.registerTool("export_customer", {
|
|
2431
2442
|
title: "Export Customer",
|
|
2432
|
-
description: `Export all customer data (main_facts + interactions
|
|
2433
|
-
Useful for reporting, audits, or creating
|
|
2443
|
+
description: `Export all customer data (main_facts + interactions + pipeline deals + attachments).
|
|
2444
|
+
Useful for reporting, audits, handoffs, or creating a complete sendable bundle
|
|
2445
|
+
of every conversation and document for a customer.
|
|
2434
2446
|
|
|
2435
2447
|
Args:
|
|
2436
2448
|
slug: Customer ID (e.g. "acme-corp")
|
|
2437
2449
|
format: Output format — "json" (default) or "markdown"
|
|
2450
|
+
includeAttachmentContent: Inline the converted Markdown of every attachment
|
|
2451
|
+
(default false). Use this to produce a single self-contained bundle.
|
|
2438
2452
|
|
|
2439
2453
|
Returns:
|
|
2440
|
-
JSON: { slug, exportedAt, mainFacts, interactionsCount, pipeline }
|
|
2441
|
-
Markdown: Formatted document with all sections`,
|
|
2454
|
+
JSON: { slug, exportedAt, mainFacts, interactionsCount, pipeline, attachments[, attachmentContents] }
|
|
2455
|
+
Markdown: Formatted document with all sections (and attachment contents when requested)`,
|
|
2442
2456
|
inputSchema: zod.z.object({
|
|
2443
2457
|
slug: zod.z.string().describe("Customer slug (e.g. 'acme-corp')"),
|
|
2444
|
-
format: zod.z.enum(["json", "markdown"]).optional().describe("Output format: 'json' (default) or 'markdown'")
|
|
2458
|
+
format: zod.z.enum(["json", "markdown"]).optional().describe("Output format: 'json' (default) or 'markdown'"),
|
|
2459
|
+
includeAttachmentContent: zod.z.boolean().optional().describe("Inline converted attachment Markdown into the export (default false)")
|
|
2445
2460
|
})
|
|
2446
|
-
}, async ({ slug, format }) => handleExportCustomer({
|
|
2461
|
+
}, async ({ slug, format, includeAttachmentContent }) => handleExportCustomer({
|
|
2447
2462
|
slug,
|
|
2448
|
-
...format !== void 0 ? { format } : {}
|
|
2463
|
+
...format !== void 0 ? { format } : {},
|
|
2464
|
+
...includeAttachmentContent !== void 0 ? { includeAttachmentContent } : {}
|
|
2449
2465
|
}));
|
|
2450
2466
|
}
|
|
2451
2467
|
//#endregion
|
|
2452
2468
|
//#region src/mcp/tools/update-customer-facts.ts
|
|
2453
|
-
const DATA_DIR$
|
|
2454
|
-
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$
|
|
2469
|
+
const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2470
|
+
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$46) {
|
|
2455
2471
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2456
2472
|
try {
|
|
2457
2473
|
require_session_store.enforceRbac(dataDir, "update_customer_facts");
|
|
@@ -2601,10 +2617,36 @@ function scoreDeal(deal, signals) {
|
|
|
2601
2617
|
warnings
|
|
2602
2618
|
};
|
|
2603
2619
|
}
|
|
2620
|
+
const MS_PER_DAY = 864e5;
|
|
2621
|
+
/**
|
|
2622
|
+
* Derive activity/close timing for a deal relative to `todayDate`. Centralizes
|
|
2623
|
+
* the day-diff math that deal-room and deal-agent each computed identically.
|
|
2624
|
+
* A blank/whitespace close_date yields `undefined` (not a NaN day count).
|
|
2625
|
+
*/
|
|
2626
|
+
function deriveDealTiming(deal, todayDate) {
|
|
2627
|
+
const updatedDate = deal.updated ? new Date(deal.updated) : todayDate;
|
|
2628
|
+
const daysSinceLastActivity = Math.floor((todayDate.getTime() - updatedDate.getTime()) / MS_PER_DAY);
|
|
2629
|
+
const timing = {
|
|
2630
|
+
daysSinceLastActivity,
|
|
2631
|
+
daysInCurrentStage: daysSinceLastActivity
|
|
2632
|
+
};
|
|
2633
|
+
if (deal.close_date && deal.close_date.trim() !== "") timing.daysToClose = Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / MS_PER_DAY);
|
|
2634
|
+
return timing;
|
|
2635
|
+
}
|
|
2636
|
+
/** Score a deal using timing derived from `todayDate` plus the deal's probability. */
|
|
2637
|
+
function scoreDealForToday(deal, todayDate) {
|
|
2638
|
+
const timing = deriveDealTiming(deal, todayDate);
|
|
2639
|
+
return scoreDeal(deal, {
|
|
2640
|
+
daysSinceLastActivity: timing.daysSinceLastActivity,
|
|
2641
|
+
daysInCurrentStage: timing.daysInCurrentStage,
|
|
2642
|
+
...timing.daysToClose !== void 0 ? { daysToClose: timing.daysToClose } : {},
|
|
2643
|
+
...deal.probability !== void 0 ? { probability: deal.probability } : {}
|
|
2644
|
+
});
|
|
2645
|
+
}
|
|
2604
2646
|
//#endregion
|
|
2605
2647
|
//#region src/mcp/tools/get-deal-health.ts
|
|
2606
|
-
const DATA_DIR$
|
|
2607
|
-
async function handleGetDealHealth(input, dataDir = DATA_DIR$
|
|
2648
|
+
const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2649
|
+
async function handleGetDealHealth(input, dataDir = DATA_DIR$45) {
|
|
2608
2650
|
try {
|
|
2609
2651
|
const deals = await require_pipeline_writer.readPipeline(dataDir, input.slug);
|
|
2610
2652
|
const today = /* @__PURE__ */ new Date();
|
|
@@ -2653,28 +2695,13 @@ Returns: { slug, deals: [{ deal, stage, score, grade, signals, warnings }] }`,
|
|
|
2653
2695
|
}
|
|
2654
2696
|
//#endregion
|
|
2655
2697
|
//#region src/mcp/tools/get-pipeline-forecast.ts
|
|
2656
|
-
const DATA_DIR$
|
|
2657
|
-
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$
|
|
2698
|
+
const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2699
|
+
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$44) {
|
|
2658
2700
|
try {
|
|
2659
|
-
const
|
|
2660
|
-
if (!fs.default.existsSync(customersDir)) return { content: [{
|
|
2661
|
-
type: "text",
|
|
2662
|
-
text: JSON.stringify({
|
|
2663
|
-
deals: [],
|
|
2664
|
-
totalWeightedValue: 0,
|
|
2665
|
-
byStage: {}
|
|
2666
|
-
}, null, 2)
|
|
2667
|
-
}] };
|
|
2668
|
-
const slugs = fs.default.readdirSync(customersDir).filter((d) => {
|
|
2669
|
-
if (input.filter && !d.includes(input.filter)) return false;
|
|
2670
|
-
return fs.default.statSync(path.default.join(customersDir, d)).isDirectory();
|
|
2671
|
-
});
|
|
2701
|
+
const slugs = require_session_store.listCustomerSlugs(dataDir).filter((d) => !input.filter || d.includes(input.filter));
|
|
2672
2702
|
const allDeals = [];
|
|
2673
2703
|
for (const slug of slugs) {
|
|
2674
|
-
const
|
|
2675
|
-
if (!fs.default.existsSync(pipelinePath)) continue;
|
|
2676
|
-
const { readPipeline } = await Promise.resolve().then(() => require("./pipeline-writer-N2omexxp.cjs")).then((n) => n.pipeline_writer_exports);
|
|
2677
|
-
const deals = await readPipeline(dataDir, slug).catch(() => []);
|
|
2704
|
+
const deals = require_pipeline_writer.readPipelineSync(dataDir, slug);
|
|
2678
2705
|
for (const deal of deals) {
|
|
2679
2706
|
if (deal.stage === "won" || deal.stage === "lost") continue;
|
|
2680
2707
|
const prob = deal.probability ?? 50;
|
|
@@ -2730,13 +2757,13 @@ Returns: { deals: [...], totalWeightedValue: number, byStage: { stage: { count,
|
|
|
2730
2757
|
}
|
|
2731
2758
|
//#endregion
|
|
2732
2759
|
//#region src/mcp/tools/summarize-meeting.ts
|
|
2733
|
-
const DATA_DIR$
|
|
2734
|
-
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$
|
|
2760
|
+
const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2761
|
+
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$43) {
|
|
2735
2762
|
try {
|
|
2736
2763
|
let summary = input.transcript.slice(0, 400);
|
|
2737
2764
|
let nextSteps = [];
|
|
2738
2765
|
try {
|
|
2739
|
-
const { callLlm } = await Promise.resolve().then(() => require("./llm-
|
|
2766
|
+
const { callLlm } = await Promise.resolve().then(() => require("./llm-CXycmEl9.cjs")).then((n) => n.llm_exports);
|
|
2740
2767
|
const response = await callLlm(`Summarize this meeting transcript in 3-5 sentences and extract action items.\n\nTranscript:\n${input.transcript.slice(0, 3e3)}\n\nRespond as JSON: { "summary": "...", "nextSteps": ["..."] }`);
|
|
2741
2768
|
const parsed = JSON.parse(response);
|
|
2742
2769
|
summary = parsed.summary ?? summary;
|
|
@@ -2850,18 +2877,12 @@ function stagesPath(dataDir) {
|
|
|
2850
2877
|
return path.default.join(dataDir, ".agentic", "pipeline-stages.json");
|
|
2851
2878
|
}
|
|
2852
2879
|
function getPipelineStages(dataDir) {
|
|
2853
|
-
|
|
2854
|
-
if (!fs.default.existsSync(p)) return DEFAULT_STAGES;
|
|
2855
|
-
try {
|
|
2856
|
-
return JSON.parse(fs.default.readFileSync(p, "utf-8"));
|
|
2857
|
-
} catch {
|
|
2858
|
-
return DEFAULT_STAGES;
|
|
2859
|
-
}
|
|
2880
|
+
return require_session_store.readJsonFile(stagesPath(dataDir), DEFAULT_STAGES);
|
|
2860
2881
|
}
|
|
2861
2882
|
//#endregion
|
|
2862
2883
|
//#region src/mcp/tools/get-pipeline-stages.ts
|
|
2863
|
-
const DATA_DIR$
|
|
2864
|
-
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$
|
|
2884
|
+
const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2885
|
+
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$42) {
|
|
2865
2886
|
const stages = getPipelineStages(dataDir);
|
|
2866
2887
|
return { content: [{
|
|
2867
2888
|
type: "text",
|
|
@@ -2879,21 +2900,18 @@ function registerGetPipelineStages(server) {
|
|
|
2879
2900
|
//#region src/core/cross-customer.ts
|
|
2880
2901
|
async function searchAcrossCustomers(dataDir, query, limit = 5, excludeSlug) {
|
|
2881
2902
|
const slugs = require_session_store.listCustomerSlugs(dataDir).filter((d) => d !== excludeSlug);
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
const results = await searchKnowledge(dataDir, slug, query, 2);
|
|
2885
|
-
for (const r of results) allResults.push({
|
|
2903
|
+
return (await Promise.all(slugs.map(async (slug) => {
|
|
2904
|
+
return (await searchKnowledge(dataDir, slug, query, 2)).map((r) => ({
|
|
2886
2905
|
slug,
|
|
2887
2906
|
relevantContent: r.content.slice(0, 200),
|
|
2888
2907
|
score: r.score
|
|
2889
|
-
});
|
|
2890
|
-
}
|
|
2891
|
-
return allResults.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
2908
|
+
}));
|
|
2909
|
+
}))).flat().sort((a, b) => b.score - a.score).slice(0, limit);
|
|
2892
2910
|
}
|
|
2893
2911
|
//#endregion
|
|
2894
2912
|
//#region src/mcp/tools/get-market-intelligence.ts
|
|
2895
|
-
const DATA_DIR$
|
|
2896
|
-
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$
|
|
2913
|
+
const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2914
|
+
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$41) {
|
|
2897
2915
|
const excludeSlug = input.excludeCurrentCustomer ? input.slug : void 0;
|
|
2898
2916
|
const all = require_session_store.listCustomerSlugs(dataDir);
|
|
2899
2917
|
const totalCustomersSearched = excludeSlug ? all.filter((s) => s !== excludeSlug).length : all.length;
|
|
@@ -2924,7 +2942,7 @@ function registerGetMarketIntelligence(server) {
|
|
|
2924
2942
|
}
|
|
2925
2943
|
//#endregion
|
|
2926
2944
|
//#region src/mcp/tools/get-relationship-graph.ts
|
|
2927
|
-
const DATA_DIR$
|
|
2945
|
+
const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2928
2946
|
function summarizeNode(n) {
|
|
2929
2947
|
return {
|
|
2930
2948
|
id: n.id,
|
|
@@ -2932,7 +2950,7 @@ function summarizeNode(n) {
|
|
|
2932
2950
|
email: n.properties["email"]
|
|
2933
2951
|
};
|
|
2934
2952
|
}
|
|
2935
|
-
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$
|
|
2953
|
+
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$40) {
|
|
2936
2954
|
try {
|
|
2937
2955
|
const graph = readGraph(dataDir, input.slug);
|
|
2938
2956
|
const stakeholders = getStakeholders(graph);
|
|
@@ -3000,9 +3018,9 @@ Returns: {
|
|
|
3000
3018
|
}
|
|
3001
3019
|
//#endregion
|
|
3002
3020
|
//#region src/mcp/tools/get-relationship-health.ts
|
|
3003
|
-
const DATA_DIR$
|
|
3021
|
+
const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3004
3022
|
const MAX_HEALTH_AGE_MS = 3600 * 1e3;
|
|
3005
|
-
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$
|
|
3023
|
+
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$39) {
|
|
3006
3024
|
try {
|
|
3007
3025
|
let health = readHealth(dataDir, input.slug);
|
|
3008
3026
|
if (health === null || Date.now() - new Date(health.updatedAt).getTime() > MAX_HEALTH_AGE_MS) {
|
|
@@ -3082,8 +3100,7 @@ async function writePlaybook(dataDir, slug, playbook) {
|
|
|
3082
3100
|
const filePath = path.default.join(dir, `${playbook.name}.md`);
|
|
3083
3101
|
await require_write_queue.withFileQueue(filePath, async () => {
|
|
3084
3102
|
fs.default.mkdirSync(dir, { recursive: true });
|
|
3085
|
-
|
|
3086
|
-
fs.default.writeFileSync(filePath, raw, "utf-8");
|
|
3103
|
+
require_atomic_write.writeFileAtomic(filePath, gray_matter.default.stringify(playbook.content, playbook.frontmatter));
|
|
3087
3104
|
});
|
|
3088
3105
|
}
|
|
3089
3106
|
function toKebabCase(name) {
|
|
@@ -3285,11 +3302,10 @@ function writeAgentQueue(dataDir, slug, queue) {
|
|
|
3285
3302
|
const p = agentQueuePath(dataDir, slug);
|
|
3286
3303
|
const dir = path.default.dirname(p);
|
|
3287
3304
|
if (!fs.default.existsSync(dir)) fs.default.mkdirSync(dir, { recursive: true });
|
|
3288
|
-
|
|
3305
|
+
require_session_store.writeJsonFile(p, {
|
|
3289
3306
|
...queue,
|
|
3290
3307
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3291
|
-
};
|
|
3292
|
-
fs.default.writeFileSync(p, JSON.stringify(updated, null, 2), "utf-8");
|
|
3308
|
+
});
|
|
3293
3309
|
}
|
|
3294
3310
|
function makeActionId() {
|
|
3295
3311
|
return `da_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -3324,17 +3340,9 @@ async function observeDeal(dataDir, slug, dealName, today) {
|
|
|
3324
3340
|
const deal = (await require_pipeline_writer.readPipeline(dataDir, slug).catch(() => [])).find((d) => d.name.toLowerCase() === dealName.toLowerCase());
|
|
3325
3341
|
if (!deal) return null;
|
|
3326
3342
|
const todayDate = new Date(today);
|
|
3327
|
-
const
|
|
3328
|
-
const
|
|
3329
|
-
const
|
|
3330
|
-
const daysToClose = deal.close_date && deal.close_date.trim() !== "" ? Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / 864e5) : void 0;
|
|
3331
|
-
const dealHealthScore = scoreDeal(deal, {
|
|
3332
|
-
daysSinceLastActivity,
|
|
3333
|
-
daysInCurrentStage,
|
|
3334
|
-
...daysToClose !== void 0 ? { daysToClose } : {},
|
|
3335
|
-
...deal.probability !== void 0 ? { probability: deal.probability } : {}
|
|
3336
|
-
});
|
|
3337
|
-
const health = computeCustomerHealth(dataDir, slug, today);
|
|
3343
|
+
const { daysSinceLastActivity, daysInCurrentStage, daysToClose } = deriveDealTiming(deal, todayDate);
|
|
3344
|
+
const dealHealthScore = scoreDealForToday(deal, todayDate);
|
|
3345
|
+
const health = readHealth(dataDir, slug) ?? computeCustomerHealth(dataDir, slug, today);
|
|
3338
3346
|
const atRiskContacts = health.contacts.filter((c) => c.riskFlags.length > 0).map((c) => c.email ?? c.contactId);
|
|
3339
3347
|
const coldContacts = health.contacts.filter((c) => c.trend === "cold").map((c) => c.email ?? c.contactId);
|
|
3340
3348
|
const stakeholders = getStakeholders(readGraph(dataDir, slug));
|
|
@@ -3562,7 +3570,7 @@ async function executeAction(action, dataDir) {
|
|
|
3562
3570
|
if (!slug) return "skipped";
|
|
3563
3571
|
switch (action.type) {
|
|
3564
3572
|
case "log_interaction": {
|
|
3565
|
-
const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-
|
|
3573
|
+
const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-BRJNrefF.cjs")).then((n) => n.interactions_writer_exports);
|
|
3566
3574
|
await appendInteraction(dataDir, slug, {
|
|
3567
3575
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
3568
3576
|
type: action.payload["type"] ?? "Note",
|
|
@@ -3575,7 +3583,7 @@ async function executeAction(action, dataDir) {
|
|
|
3575
3583
|
return "executed";
|
|
3576
3584
|
}
|
|
3577
3585
|
case "schedule_meeting": {
|
|
3578
|
-
const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-
|
|
3586
|
+
const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-BRJNrefF.cjs")).then((n) => n.interactions_writer_exports);
|
|
3579
3587
|
await appendInteraction(dataDir, slug, {
|
|
3580
3588
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
3581
3589
|
type: "Note",
|
|
@@ -3681,8 +3689,8 @@ async function runDealAgent(config, dataDir, llmFn = require_llm.callLlm) {
|
|
|
3681
3689
|
}
|
|
3682
3690
|
//#endregion
|
|
3683
3691
|
//#region src/mcp/tools/run-deal-agent.ts
|
|
3684
|
-
const DATA_DIR$
|
|
3685
|
-
async function handleRunDealAgent(input, dataDir = DATA_DIR$
|
|
3692
|
+
const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3693
|
+
async function handleRunDealAgent(input, dataDir = DATA_DIR$38) {
|
|
3686
3694
|
try {
|
|
3687
3695
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3688
3696
|
const result = await runDealAgent({
|
|
@@ -3749,8 +3757,8 @@ Returns: { assessment, riskLevel, plan[], actionsQueued[], actionsExecuted[], tr
|
|
|
3749
3757
|
}
|
|
3750
3758
|
//#endregion
|
|
3751
3759
|
//#region src/mcp/tools/approve-agent-action.ts
|
|
3752
|
-
const DATA_DIR$
|
|
3753
|
-
async function handleApproveAgentAction(input, dataDir = DATA_DIR$
|
|
3760
|
+
const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3761
|
+
async function handleApproveAgentAction(input, dataDir = DATA_DIR$37) {
|
|
3754
3762
|
try {
|
|
3755
3763
|
const queue = readAgentQueue(dataDir, input.slug);
|
|
3756
3764
|
const idx = queue.pendingActions.findIndex((a) => a.actionId === input.actionId);
|
|
@@ -4010,8 +4018,8 @@ async function buildSimulationInput(dataDir, horizon, today, externalSignals = [
|
|
|
4010
4018
|
}
|
|
4011
4019
|
//#endregion
|
|
4012
4020
|
//#region src/mcp/tools/simulate-revenue.ts
|
|
4013
|
-
const DATA_DIR$
|
|
4014
|
-
async function handleSimulateRevenue(input, dataDir = DATA_DIR$
|
|
4021
|
+
const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4022
|
+
async function handleSimulateRevenue(input, dataDir = DATA_DIR$36) {
|
|
4015
4023
|
try {
|
|
4016
4024
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4017
4025
|
const horizon = input.horizon ?? "quarter";
|
|
@@ -4069,8 +4077,8 @@ Returns: { forecast: { p10, p50, p90, expected, stdDev, atRiskRevenue, byCloseMo
|
|
|
4069
4077
|
}
|
|
4070
4078
|
//#endregion
|
|
4071
4079
|
//#region src/mcp/tools/get-playbook.ts
|
|
4072
|
-
const DATA_DIR$
|
|
4073
|
-
async function handleGetPlaybook(input, dataDir = DATA_DIR$
|
|
4080
|
+
const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4081
|
+
async function handleGetPlaybook(input, dataDir = DATA_DIR$35) {
|
|
4074
4082
|
try {
|
|
4075
4083
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
4076
4084
|
if (!(input.stage !== void 0 || input.value !== void 0 || input.healthScore !== void 0)) return { content: [{
|
|
@@ -4155,12 +4163,12 @@ Returns: { matches: [{ name, score, trigger, successRate, usedCount, content }],
|
|
|
4155
4163
|
...healthScore !== void 0 ? { healthScore } : {},
|
|
4156
4164
|
...daysSinceContact !== void 0 ? { daysSinceContact } : {},
|
|
4157
4165
|
...championPresent !== void 0 ? { championPresent } : {}
|
|
4158
|
-
}, DATA_DIR$
|
|
4166
|
+
}, DATA_DIR$35));
|
|
4159
4167
|
}
|
|
4160
4168
|
//#endregion
|
|
4161
4169
|
//#region src/mcp/tools/create-playbook.ts
|
|
4162
|
-
const DATA_DIR$
|
|
4163
|
-
async function handleCreatePlaybook(input, dataDir = DATA_DIR$
|
|
4170
|
+
const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4171
|
+
async function handleCreatePlaybook(input, dataDir = DATA_DIR$34) {
|
|
4164
4172
|
try {
|
|
4165
4173
|
const name = toKebabCase(input.name);
|
|
4166
4174
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -4233,12 +4241,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path } }`,
|
|
|
4233
4241
|
trigger,
|
|
4234
4242
|
content,
|
|
4235
4243
|
...successRate !== void 0 ? { successRate } : {}
|
|
4236
|
-
}, DATA_DIR$
|
|
4244
|
+
}, DATA_DIR$34));
|
|
4237
4245
|
}
|
|
4238
4246
|
//#endregion
|
|
4239
4247
|
//#region src/mcp/tools/list-playbooks.ts
|
|
4240
|
-
const DATA_DIR$
|
|
4241
|
-
async function handleListPlaybooks(input, dataDir = DATA_DIR$
|
|
4248
|
+
const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4249
|
+
async function handleListPlaybooks(input, dataDir = DATA_DIR$33) {
|
|
4242
4250
|
try {
|
|
4243
4251
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
4244
4252
|
return { content: [{
|
|
@@ -4277,12 +4285,12 @@ Args:
|
|
|
4277
4285
|
|
|
4278
4286
|
Returns: { playbooks: [{ name, trigger, successRate, usedCount, lastUpdated }], count, slug }`,
|
|
4279
4287
|
inputSchema: zod.z.object({ slug: zod.z.string().describe("Customer ID") })
|
|
4280
|
-
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$
|
|
4288
|
+
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$33));
|
|
4281
4289
|
}
|
|
4282
4290
|
//#endregion
|
|
4283
4291
|
//#region src/mcp/tools/distill-playbook.ts
|
|
4284
|
-
const DATA_DIR$
|
|
4285
|
-
async function handleDistillPlaybook(input, dataDir = DATA_DIR$
|
|
4292
|
+
const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4293
|
+
async function handleDistillPlaybook(input, dataDir = DATA_DIR$32, llmFn = require_llm.callLlm) {
|
|
4286
4294
|
try {
|
|
4287
4295
|
const result = await distillPlaybook(dataDir, input.slug, input.dealName, input.outcome, llmFn);
|
|
4288
4296
|
if (!result.ok) {
|
|
@@ -4341,7 +4349,7 @@ Returns: { success: true, playbook: { name, trigger, successRate, path }, reason
|
|
|
4341
4349
|
slug,
|
|
4342
4350
|
dealName,
|
|
4343
4351
|
outcome
|
|
4344
|
-
}, DATA_DIR$
|
|
4352
|
+
}, DATA_DIR$32));
|
|
4345
4353
|
}
|
|
4346
4354
|
//#endregion
|
|
4347
4355
|
//#region src/core/goal-engine.ts
|
|
@@ -4559,8 +4567,8 @@ function getActiveGoals(dataDir) {
|
|
|
4559
4567
|
}
|
|
4560
4568
|
//#endregion
|
|
4561
4569
|
//#region src/mcp/tools/pursue-goal.ts
|
|
4562
|
-
const DATA_DIR$
|
|
4563
|
-
async function handlePursueGoal(input, dataDir = DATA_DIR$
|
|
4570
|
+
const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4571
|
+
async function handlePursueGoal(input, dataDir = DATA_DIR$31, options = {}) {
|
|
4564
4572
|
try {
|
|
4565
4573
|
require_session_store.enforceRbac(dataDir, "pursue_goal");
|
|
4566
4574
|
const goal = await pursueGoal(dataDir, {
|
|
@@ -4623,12 +4631,12 @@ Returns: { goalId, description, target, deadline, decomposition: { analysis, cur
|
|
|
4623
4631
|
goal,
|
|
4624
4632
|
deadline,
|
|
4625
4633
|
...context !== void 0 ? { context } : {}
|
|
4626
|
-
}, DATA_DIR$
|
|
4634
|
+
}, DATA_DIR$31));
|
|
4627
4635
|
}
|
|
4628
4636
|
//#endregion
|
|
4629
4637
|
//#region src/mcp/tools/get-goal-status.ts
|
|
4630
|
-
const DATA_DIR$
|
|
4631
|
-
async function handleGetGoalStatus(input, dataDir = DATA_DIR$
|
|
4638
|
+
const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4639
|
+
async function handleGetGoalStatus(input, dataDir = DATA_DIR$30) {
|
|
4632
4640
|
try {
|
|
4633
4641
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4634
4642
|
const allGoals = input.goalId ? readGoals(dataDir).filter((g) => g.id === input.goalId) : getActiveGoals(dataDir);
|
|
@@ -4687,17 +4695,17 @@ Args:
|
|
|
4687
4695
|
|
|
4688
4696
|
Returns: { goals: [{ id, description, target, progress, status, deadline, daysRemaining, subGoals }], activeCount, completedCount }`,
|
|
4689
4697
|
inputSchema: zod.z.object({ goalId: zod.z.string().optional().describe("Specific goal ID (omit for all active goals)") })
|
|
4690
|
-
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$
|
|
4698
|
+
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$30));
|
|
4691
4699
|
}
|
|
4692
4700
|
//#endregion
|
|
4693
4701
|
//#region src/mcp/tools/register-push-subscription.ts
|
|
4694
|
-
const DATA_DIR$
|
|
4702
|
+
const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4695
4703
|
const VALID_PROVIDERS = [
|
|
4696
4704
|
"gmail",
|
|
4697
4705
|
"microsoft-graph",
|
|
4698
4706
|
"slack"
|
|
4699
4707
|
];
|
|
4700
|
-
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$
|
|
4708
|
+
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$29) {
|
|
4701
4709
|
try {
|
|
4702
4710
|
if (!VALID_PROVIDERS.includes(input.provider)) return { content: [{
|
|
4703
4711
|
type: "text",
|
|
@@ -4783,12 +4791,12 @@ Returns: { subscriptionId, provider, slug, status, expiresAt, createdAt, warning
|
|
|
4783
4791
|
...microsoftResource !== void 0 ? { microsoftResource } : {},
|
|
4784
4792
|
...slackTeamId !== void 0 ? { slackTeamId } : {},
|
|
4785
4793
|
...slackChannelId !== void 0 ? { slackChannelId } : {}
|
|
4786
|
-
}, DATA_DIR$
|
|
4794
|
+
}, DATA_DIR$29));
|
|
4787
4795
|
}
|
|
4788
4796
|
//#endregion
|
|
4789
4797
|
//#region src/mcp/tools/get-push-status.ts
|
|
4790
|
-
const DATA_DIR$
|
|
4791
|
-
async function handleGetPushStatus(input, dataDir = DATA_DIR$
|
|
4798
|
+
const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4799
|
+
async function handleGetPushStatus(input, dataDir = DATA_DIR$28) {
|
|
4792
4800
|
try {
|
|
4793
4801
|
let subs = await readSubscriptions(dataDir);
|
|
4794
4802
|
if (input.slug) subs = subs.filter((s) => s.slug === input.slug);
|
|
@@ -4860,7 +4868,7 @@ Returns: { subscriptions: [{ id, provider, slug, status, expiresAt, expiresInHou
|
|
|
4860
4868
|
}, async ({ slug, provider }) => handleGetPushStatus({
|
|
4861
4869
|
...slug !== void 0 ? { slug } : {},
|
|
4862
4870
|
...provider !== void 0 ? { provider } : {}
|
|
4863
|
-
}, DATA_DIR$
|
|
4871
|
+
}, DATA_DIR$28));
|
|
4864
4872
|
}
|
|
4865
4873
|
//#endregion
|
|
4866
4874
|
//#region src/core/org-intelligence.ts
|
|
@@ -4926,8 +4934,8 @@ function deriveRecommendation(people, missingRoles) {
|
|
|
4926
4934
|
}
|
|
4927
4935
|
//#endregion
|
|
4928
4936
|
//#region src/mcp/tools/get-org-intelligence.ts
|
|
4929
|
-
const DATA_DIR$
|
|
4930
|
-
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$
|
|
4937
|
+
const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4938
|
+
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$27) {
|
|
4931
4939
|
try {
|
|
4932
4940
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4933
4941
|
const map = buildStakeholderMap(dataDir, input.slug, today, input.dealName);
|
|
@@ -4978,15 +4986,7 @@ async function buildDealRoom(dataDir, slug, dealName, today) {
|
|
|
4978
4986
|
});
|
|
4979
4987
|
const todayDate = new Date(today);
|
|
4980
4988
|
const dealHealth = pipelineDeals.filter((d) => d.stage !== "won" && d.stage !== "lost").map((deal) => {
|
|
4981
|
-
const
|
|
4982
|
-
const daysSinceLastActivity = Math.floor((todayDate.getTime() - updatedDate.getTime()) / 864e5);
|
|
4983
|
-
const daysToClose = deal.close_date ? Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / 864e5) : void 0;
|
|
4984
|
-
const scored = scoreDeal(deal, {
|
|
4985
|
-
daysSinceLastActivity,
|
|
4986
|
-
daysInCurrentStage: daysSinceLastActivity,
|
|
4987
|
-
...daysToClose !== void 0 ? { daysToClose } : {},
|
|
4988
|
-
...deal.probability !== void 0 ? { probability: deal.probability } : {}
|
|
4989
|
-
});
|
|
4989
|
+
const scored = scoreDealForToday(deal, todayDate);
|
|
4990
4990
|
return {
|
|
4991
4991
|
deal: deal.name,
|
|
4992
4992
|
stage: deal.stage,
|
|
@@ -5068,8 +5068,8 @@ function buildExecutiveSummary(slug, dealName, stakeholders, overallHealth, sim,
|
|
|
5068
5068
|
}
|
|
5069
5069
|
//#endregion
|
|
5070
5070
|
//#region src/mcp/tools/open-deal-room.ts
|
|
5071
|
-
const DATA_DIR$
|
|
5072
|
-
async function handleOpenDealRoom(input, dataDir = DATA_DIR$
|
|
5071
|
+
const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5072
|
+
async function handleOpenDealRoom(input, dataDir = DATA_DIR$26) {
|
|
5073
5073
|
try {
|
|
5074
5074
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5075
5075
|
const brief = await buildDealRoom(dataDir, input.slug, input.dealName, today);
|
|
@@ -5152,8 +5152,8 @@ async function buildDailyBriefing(dataDir, today) {
|
|
|
5152
5152
|
}
|
|
5153
5153
|
//#endregion
|
|
5154
5154
|
//#region src/mcp/tools/get-proactive-briefing.ts
|
|
5155
|
-
const DATA_DIR$
|
|
5156
|
-
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$
|
|
5155
|
+
const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5156
|
+
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$25) {
|
|
5157
5157
|
try {
|
|
5158
5158
|
const briefing = await buildDailyBriefing(dataDir, input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
|
|
5159
5159
|
return { content: [{
|
|
@@ -5253,15 +5253,15 @@ function getTemplate(dataDir, id) {
|
|
|
5253
5253
|
}
|
|
5254
5254
|
//#endregion
|
|
5255
5255
|
//#region src/mcp/tools/list-email-templates.ts
|
|
5256
|
-
const DATA_DIR$
|
|
5257
|
-
async function handleListEmailTemplates(input, dataDir = DATA_DIR$
|
|
5256
|
+
const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5257
|
+
async function handleListEmailTemplates(input, dataDir = DATA_DIR$24) {
|
|
5258
5258
|
const summary = listTemplates(dataDir, input.category ? { category: input.category } : {}).map(({ body: _body, ...meta }) => meta);
|
|
5259
5259
|
return { content: [{
|
|
5260
5260
|
type: "text",
|
|
5261
5261
|
text: JSON.stringify(summary, null, 2)
|
|
5262
5262
|
}] };
|
|
5263
5263
|
}
|
|
5264
|
-
function registerListEmailTemplates(server, dataDir = DATA_DIR$
|
|
5264
|
+
function registerListEmailTemplates(server, dataDir = DATA_DIR$24) {
|
|
5265
5265
|
server.registerTool("list_email_templates", {
|
|
5266
5266
|
description: "List available email templates. Optionally filter by category (e.g. 'outreach', 'followup', 'support').",
|
|
5267
5267
|
inputSchema: zod.z.object({ category: zod.z.string().optional().describe("Filter by category") })
|
|
@@ -5295,8 +5295,8 @@ async function buildVariablesFromCustomer(dataDir, slug) {
|
|
|
5295
5295
|
}
|
|
5296
5296
|
//#endregion
|
|
5297
5297
|
//#region src/mcp/tools/get-email-template.ts
|
|
5298
|
-
const DATA_DIR$
|
|
5299
|
-
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$
|
|
5298
|
+
const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5299
|
+
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$23) {
|
|
5300
5300
|
const tmpl = getTemplate(dataDir, input.id);
|
|
5301
5301
|
if (!tmpl) return { content: [{
|
|
5302
5302
|
type: "text",
|
|
@@ -5312,7 +5312,7 @@ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$22) {
|
|
|
5312
5312
|
}, null, 2)
|
|
5313
5313
|
}] };
|
|
5314
5314
|
}
|
|
5315
|
-
function registerGetEmailTemplate(server, dataDir = DATA_DIR$
|
|
5315
|
+
function registerGetEmailTemplate(server, dataDir = DATA_DIR$23) {
|
|
5316
5316
|
server.registerTool("get_email_template", {
|
|
5317
5317
|
description: "Get a specific email template by ID, including its body and detected variables.",
|
|
5318
5318
|
inputSchema: zod.z.object({ id: zod.z.string().describe("Template ID (e.g. 'enterprise-intro')") })
|
|
@@ -5320,8 +5320,8 @@ function registerGetEmailTemplate(server, dataDir = DATA_DIR$22) {
|
|
|
5320
5320
|
}
|
|
5321
5321
|
//#endregion
|
|
5322
5322
|
//#region src/mcp/tools/draft-email.ts
|
|
5323
|
-
const DATA_DIR$
|
|
5324
|
-
async function handleDraftEmail(input, dataDir = DATA_DIR$
|
|
5323
|
+
const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5324
|
+
async function handleDraftEmail(input, dataDir = DATA_DIR$22) {
|
|
5325
5325
|
const tmpl = getTemplate(dataDir, input.templateId);
|
|
5326
5326
|
if (!tmpl) return { content: [{
|
|
5327
5327
|
type: "text",
|
|
@@ -5335,17 +5335,17 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$21) {
|
|
|
5335
5335
|
const interpolatedBody = interpolate(tmpl.body, vars);
|
|
5336
5336
|
let effectiveTone = input.tone;
|
|
5337
5337
|
if (!effectiveTone) {
|
|
5338
|
-
const { resolveTone, toneInstruction } = await Promise.resolve().then(() => require("./tone-
|
|
5338
|
+
const { resolveTone, toneInstruction } = await Promise.resolve().then(() => require("./tone-Cmc7O2Fx.cjs"));
|
|
5339
5339
|
const instr = toneInstruction(resolveTone(dataDir, input.slug));
|
|
5340
5340
|
if (instr) effectiveTone = instr;
|
|
5341
5341
|
}
|
|
5342
5342
|
let body = interpolatedBody;
|
|
5343
5343
|
let polished = false;
|
|
5344
5344
|
if (effectiveTone) try {
|
|
5345
|
-
const { callLlm } = await Promise.resolve().then(() => require("./llm-
|
|
5345
|
+
const { callLlm } = await Promise.resolve().then(() => require("./llm-CXycmEl9.cjs")).then((n) => n.llm_exports);
|
|
5346
5346
|
const refined = await callLlm(`Rewrite the following email in a ${effectiveTone} tone. Keep the same language, preserve all names and facts, and do not invent details. Return ONLY the rewritten email body, no preamble.\n\n---\n${interpolatedBody}`);
|
|
5347
5347
|
if (refined && refined.trim()) {
|
|
5348
|
-
const { labelAiContent } = await Promise.resolve().then(() => require("./compliance-
|
|
5348
|
+
const { labelAiContent } = await Promise.resolve().then(() => require("./compliance-pAj9FcGI.cjs")).then((n) => n.compliance_exports);
|
|
5349
5349
|
body = labelAiContent(refined.trim());
|
|
5350
5350
|
polished = true;
|
|
5351
5351
|
}
|
|
@@ -5365,7 +5365,7 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$21) {
|
|
|
5365
5365
|
}, null, 2)
|
|
5366
5366
|
}] };
|
|
5367
5367
|
}
|
|
5368
|
-
function registerDraftEmail(server, dataDir = DATA_DIR$
|
|
5368
|
+
function registerDraftEmail(server, dataDir = DATA_DIR$22) {
|
|
5369
5369
|
server.registerTool("draft_email", {
|
|
5370
5370
|
description: `Draft a personalized email for a customer using a stored template.
|
|
5371
5371
|
Variables are auto-filled from the customer's main_facts.md. Override any variable manually.
|
|
@@ -5473,8 +5473,8 @@ async function updateEnrollment(dataDir, id, updates) {
|
|
|
5473
5473
|
}
|
|
5474
5474
|
//#endregion
|
|
5475
5475
|
//#region src/mcp/tools/enroll-in-sequence.ts
|
|
5476
|
-
const DATA_DIR$
|
|
5477
|
-
async function handleEnrollInSequence(input, dataDir = DATA_DIR$
|
|
5476
|
+
const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5477
|
+
async function handleEnrollInSequence(input, dataDir = DATA_DIR$21) {
|
|
5478
5478
|
const sequence = getSequence(dataDir, input.sequenceId);
|
|
5479
5479
|
if (!sequence) return { content: [{
|
|
5480
5480
|
type: "text",
|
|
@@ -5506,7 +5506,7 @@ async function handleEnrollInSequence(input, dataDir = DATA_DIR$20) {
|
|
|
5506
5506
|
})
|
|
5507
5507
|
}] };
|
|
5508
5508
|
}
|
|
5509
|
-
function registerEnrollInSequence(server, dataDir = DATA_DIR$
|
|
5509
|
+
function registerEnrollInSequence(server, dataDir = DATA_DIR$21) {
|
|
5510
5510
|
server.registerTool("enroll_in_sequence", {
|
|
5511
5511
|
description: `Enroll a contact in an email sequence. Validates that the sequence and its first template exist.
|
|
5512
5512
|
Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
@@ -5523,8 +5523,8 @@ Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
|
5523
5523
|
}
|
|
5524
5524
|
//#endregion
|
|
5525
5525
|
//#region src/mcp/tools/list-sequence-enrollments.ts
|
|
5526
|
-
const DATA_DIR$
|
|
5527
|
-
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$
|
|
5526
|
+
const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5527
|
+
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$20) {
|
|
5528
5528
|
let enrollments = readEnrollments(dataDir);
|
|
5529
5529
|
if (input.slug !== void 0) enrollments = enrollments.filter((e) => e.slug === input.slug);
|
|
5530
5530
|
if (input.status !== void 0) enrollments = enrollments.filter((e) => e.status === input.status);
|
|
@@ -5533,7 +5533,7 @@ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$19) {
|
|
|
5533
5533
|
text: JSON.stringify({ enrollments }, null, 2)
|
|
5534
5534
|
}] };
|
|
5535
5535
|
}
|
|
5536
|
-
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$
|
|
5536
|
+
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$20) {
|
|
5537
5537
|
server.registerTool("list_sequence_enrollments", {
|
|
5538
5538
|
description: `List email sequence enrollments. Filter by customer slug or status.
|
|
5539
5539
|
Returns: { enrollments: SequenceEnrollment[] }`,
|
|
@@ -5552,8 +5552,8 @@ Returns: { enrollments: SequenceEnrollment[] }`,
|
|
|
5552
5552
|
}
|
|
5553
5553
|
//#endregion
|
|
5554
5554
|
//#region src/mcp/tools/unenroll-from-sequence.ts
|
|
5555
|
-
const DATA_DIR$
|
|
5556
|
-
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$
|
|
5555
|
+
const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5556
|
+
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$19) {
|
|
5557
5557
|
if (!await updateEnrollment(dataDir, input.enrollmentId, { status: "paused" })) return { content: [{
|
|
5558
5558
|
type: "text",
|
|
5559
5559
|
text: JSON.stringify({
|
|
@@ -5566,7 +5566,7 @@ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$18) {
|
|
|
5566
5566
|
text: JSON.stringify({ success: true })
|
|
5567
5567
|
}] };
|
|
5568
5568
|
}
|
|
5569
|
-
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$
|
|
5569
|
+
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$19) {
|
|
5570
5570
|
server.registerTool("unenroll_from_sequence", {
|
|
5571
5571
|
description: `Unenroll (pause) a contact from an email sequence. Sets status to "paused" (soft delete).
|
|
5572
5572
|
Returns: { success: boolean }`,
|
|
@@ -5575,8 +5575,8 @@ Returns: { success: boolean }`,
|
|
|
5575
5575
|
}
|
|
5576
5576
|
//#endregion
|
|
5577
5577
|
//#region src/mcp/tools/list-sequences.ts
|
|
5578
|
-
const DATA_DIR$
|
|
5579
|
-
async function handleListSequences(_input, dataDir = DATA_DIR$
|
|
5578
|
+
const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5579
|
+
async function handleListSequences(_input, dataDir = DATA_DIR$18) {
|
|
5580
5580
|
const sequences = listSequences(dataDir);
|
|
5581
5581
|
const enrollments = readEnrollments(dataDir);
|
|
5582
5582
|
const result = sequences.map((seq) => ({
|
|
@@ -5590,7 +5590,7 @@ async function handleListSequences(_input, dataDir = DATA_DIR$17) {
|
|
|
5590
5590
|
text: JSON.stringify({ sequences: result }, null, 2)
|
|
5591
5591
|
}] };
|
|
5592
5592
|
}
|
|
5593
|
-
function registerListSequences(server, dataDir = DATA_DIR$
|
|
5593
|
+
function registerListSequences(server, dataDir = DATA_DIR$18) {
|
|
5594
5594
|
server.registerTool("list_sequences", {
|
|
5595
5595
|
description: `List all email sequences with step count and enrollment count.
|
|
5596
5596
|
Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
|
|
@@ -5640,7 +5640,7 @@ function buildHtml(quote, config, customerName) {
|
|
|
5640
5640
|
<p><strong>${config.companyName ?? ""}</strong><br>${config.companyAddress ?? ""}<br>${config.vatId ? `USt-IdNr.: ${config.vatId}` : ""}</p>
|
|
5641
5641
|
<hr>
|
|
5642
5642
|
<p><strong>An:</strong> ${customerName}</p>
|
|
5643
|
-
<p><strong>
|
|
5643
|
+
<p><strong>Date:</strong> ${quote.createdAt.slice(0, 10)} <strong>Valid until:</strong> ${quote.validUntil}</p>
|
|
5644
5644
|
<h2>Leistungen</h2>
|
|
5645
5645
|
<table>
|
|
5646
5646
|
<thead><tr><th>Beschreibung</th><th style="text-align:right">Menge</th><th style="text-align:right">Einzelpreis</th><th style="text-align:right">Gesamt</th></tr></thead>
|
|
@@ -5719,15 +5719,14 @@ async function generateQuote(dataDir, input) {
|
|
|
5719
5719
|
status: "draft",
|
|
5720
5720
|
htmlPath
|
|
5721
5721
|
};
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
fs.default.writeFileSync(htmlPath, html, "utf-8");
|
|
5722
|
+
require_atomic_write.writeFileAtomic(path.default.join(dir, `${quoteNumber}.json`), JSON.stringify(quote, null, 2));
|
|
5723
|
+
require_atomic_write.writeFileAtomic(htmlPath, buildHtml(quote, config, readCustomerName(dataDir, input.slug)));
|
|
5725
5724
|
return quote;
|
|
5726
5725
|
}
|
|
5727
5726
|
//#endregion
|
|
5728
5727
|
//#region src/mcp/tools/generate-quote.ts
|
|
5729
|
-
const DATA_DIR$
|
|
5730
|
-
async function handleGenerateQuote(input, dataDir = DATA_DIR$
|
|
5728
|
+
const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5729
|
+
async function handleGenerateQuote(input, dataDir = DATA_DIR$17) {
|
|
5731
5730
|
try {
|
|
5732
5731
|
const quote = await generateQuote(dataDir, input);
|
|
5733
5732
|
return { content: [{
|
|
@@ -5751,7 +5750,7 @@ async function handleGenerateQuote(input, dataDir = DATA_DIR$16) {
|
|
|
5751
5750
|
}] };
|
|
5752
5751
|
}
|
|
5753
5752
|
}
|
|
5754
|
-
function registerGenerateQuote(server, dataDir = DATA_DIR$
|
|
5753
|
+
function registerGenerateQuote(server, dataDir = DATA_DIR$17) {
|
|
5755
5754
|
server.registerTool("generate_quote", {
|
|
5756
5755
|
description: `Generate a professional HTML quote/offer for a customer deal.
|
|
5757
5756
|
Calculates subtotal, VAT, and total. Saves JSON + HTML to .agentic/quotes/.
|
|
@@ -5779,8 +5778,8 @@ Returns: { quoteNumber, htmlPath, total, currency, validUntil }`,
|
|
|
5779
5778
|
}
|
|
5780
5779
|
//#endregion
|
|
5781
5780
|
//#region src/mcp/tools/get-quote-status.ts
|
|
5782
|
-
const DATA_DIR$
|
|
5783
|
-
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$
|
|
5781
|
+
const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5782
|
+
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$16) {
|
|
5784
5783
|
if (input.quoteNumber) {
|
|
5785
5784
|
const quote = readQuote(dataDir, input.quoteNumber);
|
|
5786
5785
|
if (!quote) return { content: [{
|
|
@@ -5798,7 +5797,7 @@ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$15) {
|
|
|
5798
5797
|
text: JSON.stringify({ quotes }, null, 2)
|
|
5799
5798
|
}] };
|
|
5800
5799
|
}
|
|
5801
|
-
function registerGetQuoteStatus(server, dataDir = DATA_DIR$
|
|
5800
|
+
function registerGetQuoteStatus(server, dataDir = DATA_DIR$16) {
|
|
5802
5801
|
server.registerTool("get_quote_status", {
|
|
5803
5802
|
description: `Get quote status and details. Filter by quoteNumber (single quote) or slug (all quotes for a customer).
|
|
5804
5803
|
Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
@@ -5813,7 +5812,7 @@ Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
|
5813
5812
|
}
|
|
5814
5813
|
//#endregion
|
|
5815
5814
|
//#region src/mcp/tools/get-booking-link.ts
|
|
5816
|
-
const DATA_DIR$
|
|
5815
|
+
const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5817
5816
|
function loadCalendlyConfig(dataDir) {
|
|
5818
5817
|
const p = path.default.join(dataDir, ".agentic", "integrations", "calendly.yaml");
|
|
5819
5818
|
if (!fs.default.existsSync(p)) return {};
|
|
@@ -5836,7 +5835,7 @@ function readCustomerFacts(dataDir, slug) {
|
|
|
5836
5835
|
...email ? { email } : {}
|
|
5837
5836
|
};
|
|
5838
5837
|
}
|
|
5839
|
-
async function handleGetBookingLink(input, dataDir = DATA_DIR$
|
|
5838
|
+
async function handleGetBookingLink(input, dataDir = DATA_DIR$15) {
|
|
5840
5839
|
const config = loadCalendlyConfig(dataDir);
|
|
5841
5840
|
const apiKey = config.apiKey ?? process.env["CALENDLY_API_KEY"] ?? "";
|
|
5842
5841
|
if (!apiKey) return { content: [{
|
|
@@ -5864,7 +5863,7 @@ async function handleGetBookingLink(input, dataDir = DATA_DIR$14) {
|
|
|
5864
5863
|
}] };
|
|
5865
5864
|
}
|
|
5866
5865
|
}
|
|
5867
|
-
function registerGetBookingLink(server, dataDir = DATA_DIR$
|
|
5866
|
+
function registerGetBookingLink(server, dataDir = DATA_DIR$15) {
|
|
5868
5867
|
server.registerTool("get_booking_link", {
|
|
5869
5868
|
description: `Get a Calendly booking link for a customer. Optionally pre-fills the customer's name/email.
|
|
5870
5869
|
Requires CALENDLY_API_KEY env var or .agentic/integrations/calendly.yaml config.
|
|
@@ -5912,6 +5911,7 @@ const TICKET_HEADER = "# Tickets\n\n";
|
|
|
5912
5911
|
const TABLE_HEADER = `| ID | Title | Status | Priority | Assignee | Created | SLA Due | Resolved |
|
|
5913
5912
|
|----|-------|--------|----------|----------|---------|---------|---------|`;
|
|
5914
5913
|
function ticketsPath(dataDir, slug) {
|
|
5914
|
+
require_session_store.assertSafeSlug(slug);
|
|
5915
5915
|
return path.default.join(dataDir, "customers", slug, "tickets.md");
|
|
5916
5916
|
}
|
|
5917
5917
|
function escapeMd(s) {
|
|
@@ -5964,7 +5964,7 @@ async function upsertTicket(dataDir, slug, ticket) {
|
|
|
5964
5964
|
const idx = existing.findIndex((t) => t.id === ticket.id);
|
|
5965
5965
|
if (idx >= 0) existing[idx] = ticket;
|
|
5966
5966
|
else existing.push(ticket);
|
|
5967
|
-
|
|
5967
|
+
require_atomic_write.writeFileAtomic(p, serializeTickets(existing));
|
|
5968
5968
|
}
|
|
5969
5969
|
function nextTicketId(tickets) {
|
|
5970
5970
|
const nums = tickets.map((t) => parseInt(t.id.replace("T-", ""), 10)).filter((n) => !isNaN(n));
|
|
@@ -5972,28 +5972,13 @@ function nextTicketId(tickets) {
|
|
|
5972
5972
|
return `T-${String(max + 1).padStart(3, "0")}`;
|
|
5973
5973
|
}
|
|
5974
5974
|
async function listAllTickets(dataDir, filter) {
|
|
5975
|
-
const
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
}
|
|
5981
|
-
|
|
5982
|
-
}
|
|
5983
|
-
});
|
|
5984
|
-
const results = [];
|
|
5985
|
-
for (const slug of slugs) {
|
|
5986
|
-
const tickets = await readTickets(dataDir, slug);
|
|
5987
|
-
for (const ticket of tickets) {
|
|
5988
|
-
if (filter?.status && ticket.status !== filter.status) continue;
|
|
5989
|
-
if (filter?.priority && ticket.priority !== filter.priority) continue;
|
|
5990
|
-
if (filter?.assignee && ticket.assignee !== filter.assignee) continue;
|
|
5991
|
-
results.push({
|
|
5992
|
-
slug,
|
|
5993
|
-
ticket
|
|
5994
|
-
});
|
|
5995
|
-
}
|
|
5996
|
-
}
|
|
5975
|
+
const slugs = filter?.slug ? [filter.slug] : require_session_store.listCustomerSlugs(dataDir);
|
|
5976
|
+
const results = (await Promise.all(slugs.map(async (slug) => {
|
|
5977
|
+
return (await readTickets(dataDir, slug)).filter((ticket) => (!filter?.status || ticket.status === filter.status) && (!filter?.priority || ticket.priority === filter.priority) && (!filter?.assignee || ticket.assignee === filter.assignee)).map((ticket) => ({
|
|
5978
|
+
slug,
|
|
5979
|
+
ticket
|
|
5980
|
+
}));
|
|
5981
|
+
}))).flat();
|
|
5997
5982
|
const priorityOrder = {
|
|
5998
5983
|
urgent: 0,
|
|
5999
5984
|
high: 1,
|
|
@@ -6048,8 +6033,8 @@ function calcSlaDue(createdDate, priority, rules) {
|
|
|
6048
6033
|
}
|
|
6049
6034
|
//#endregion
|
|
6050
6035
|
//#region src/mcp/tools/create-ticket.ts
|
|
6051
|
-
const DATA_DIR$
|
|
6052
|
-
async function handleCreateTicket(input, dataDir = DATA_DIR$
|
|
6036
|
+
const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6037
|
+
async function handleCreateTicket(input, dataDir = DATA_DIR$14) {
|
|
6053
6038
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
6054
6039
|
const rules = loadSlaRules(dataDir);
|
|
6055
6040
|
const priority = input.priority ?? "normal";
|
|
@@ -6071,7 +6056,7 @@ async function handleCreateTicket(input, dataDir = DATA_DIR$13) {
|
|
|
6071
6056
|
text: JSON.stringify({ ticket }, null, 2)
|
|
6072
6057
|
}] };
|
|
6073
6058
|
}
|
|
6074
|
-
function registerCreateTicket(server, dataDir = DATA_DIR$
|
|
6059
|
+
function registerCreateTicket(server, dataDir = DATA_DIR$14) {
|
|
6075
6060
|
server.registerTool("create_ticket", {
|
|
6076
6061
|
description: `Create a support ticket for a customer. Auto-calculates SLA due date based on priority.
|
|
6077
6062
|
Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
@@ -6097,8 +6082,8 @@ Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
|
6097
6082
|
}
|
|
6098
6083
|
//#endregion
|
|
6099
6084
|
//#region src/mcp/tools/update-ticket.ts
|
|
6100
|
-
const DATA_DIR$
|
|
6101
|
-
async function handleUpdateTicket(input, dataDir = DATA_DIR$
|
|
6085
|
+
const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6086
|
+
async function handleUpdateTicket(input, dataDir = DATA_DIR$13) {
|
|
6102
6087
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
6103
6088
|
if (!ticket) return { content: [{
|
|
6104
6089
|
type: "text",
|
|
@@ -6117,7 +6102,7 @@ async function handleUpdateTicket(input, dataDir = DATA_DIR$12) {
|
|
|
6117
6102
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
6118
6103
|
}] };
|
|
6119
6104
|
}
|
|
6120
|
-
function registerUpdateTicket(server, dataDir = DATA_DIR$
|
|
6105
|
+
function registerUpdateTicket(server, dataDir = DATA_DIR$13) {
|
|
6121
6106
|
server.registerTool("update_ticket", {
|
|
6122
6107
|
description: `Update a ticket's status or assignee. Setting status=resolved auto-sets resolved date.
|
|
6123
6108
|
Returns: { ticket }`,
|
|
@@ -6142,8 +6127,8 @@ Returns: { ticket }`,
|
|
|
6142
6127
|
}
|
|
6143
6128
|
//#endregion
|
|
6144
6129
|
//#region src/mcp/tools/list-tickets.ts
|
|
6145
|
-
const DATA_DIR$
|
|
6146
|
-
async function handleListTickets(input, dataDir = DATA_DIR$
|
|
6130
|
+
const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6131
|
+
async function handleListTickets(input, dataDir = DATA_DIR$12) {
|
|
6147
6132
|
const results = await listAllTickets(dataDir, {
|
|
6148
6133
|
...input.slug !== void 0 ? { slug: input.slug } : {},
|
|
6149
6134
|
...input.status !== void 0 ? { status: input.status } : {},
|
|
@@ -6155,7 +6140,7 @@ async function handleListTickets(input, dataDir = DATA_DIR$11) {
|
|
|
6155
6140
|
text: JSON.stringify({ tickets: results }, null, 2)
|
|
6156
6141
|
}] };
|
|
6157
6142
|
}
|
|
6158
|
-
function registerListTickets(server, dataDir = DATA_DIR$
|
|
6143
|
+
function registerListTickets(server, dataDir = DATA_DIR$12) {
|
|
6159
6144
|
server.registerTool("list_tickets", {
|
|
6160
6145
|
description: `List support tickets. Filter by customer, status, priority, or assignee. Sorted by priority then date.
|
|
6161
6146
|
Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
@@ -6185,8 +6170,8 @@ Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
|
6185
6170
|
}
|
|
6186
6171
|
//#endregion
|
|
6187
6172
|
//#region src/mcp/tools/close-ticket.ts
|
|
6188
|
-
const DATA_DIR$
|
|
6189
|
-
async function handleCloseTicket(input, dataDir = DATA_DIR$
|
|
6173
|
+
const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6174
|
+
async function handleCloseTicket(input, dataDir = DATA_DIR$11) {
|
|
6190
6175
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
6191
6176
|
if (!ticket) return { content: [{
|
|
6192
6177
|
type: "text",
|
|
@@ -6213,7 +6198,7 @@ async function handleCloseTicket(input, dataDir = DATA_DIR$10) {
|
|
|
6213
6198
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
6214
6199
|
}] };
|
|
6215
6200
|
}
|
|
6216
|
-
function registerCloseTicket(server, dataDir = DATA_DIR$
|
|
6201
|
+
function registerCloseTicket(server, dataDir = DATA_DIR$11) {
|
|
6217
6202
|
server.registerTool("close_ticket", {
|
|
6218
6203
|
description: `Close a support ticket. Optionally logs the resolution as an interaction.
|
|
6219
6204
|
Returns: { ticket } with status=closed`,
|
|
@@ -6323,7 +6308,7 @@ async function recordSurveyResponse(dataDir, token, score, comment) {
|
|
|
6323
6308
|
const dir = responsesDir(dataDir, pending.surveyId);
|
|
6324
6309
|
fs.default.mkdirSync(dir, { recursive: true });
|
|
6325
6310
|
const filename = `${pending.slug}_${pending.contactEmail.replace("@", "_at_")}_${Date.now()}.json`;
|
|
6326
|
-
|
|
6311
|
+
require_atomic_write.writeFileAtomic(path.default.join(dir, filename), JSON.stringify(response, null, 2));
|
|
6327
6312
|
fs.default.unlinkSync(path.default.join(pendingDir, file));
|
|
6328
6313
|
return response;
|
|
6329
6314
|
} catch {
|
|
@@ -6363,12 +6348,12 @@ async function savePendingSurvey(dataDir, surveyId, slug, contactEmail, token) {
|
|
|
6363
6348
|
contactEmail,
|
|
6364
6349
|
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6365
6350
|
};
|
|
6366
|
-
|
|
6351
|
+
require_atomic_write.writeFileAtomic(path.default.join(pendingDir, filename), JSON.stringify(pending, null, 2));
|
|
6367
6352
|
}
|
|
6368
6353
|
//#endregion
|
|
6369
6354
|
//#region src/mcp/tools/send-nps-survey.ts
|
|
6370
|
-
const DATA_DIR$
|
|
6371
|
-
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$
|
|
6355
|
+
const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6356
|
+
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$10) {
|
|
6372
6357
|
const survey = getSurvey(dataDir, input.surveyId);
|
|
6373
6358
|
if (!survey) return { content: [{
|
|
6374
6359
|
type: "text",
|
|
@@ -6389,7 +6374,7 @@ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$9) {
|
|
|
6389
6374
|
}, null, 2)
|
|
6390
6375
|
}] };
|
|
6391
6376
|
}
|
|
6392
|
-
function registerSendNpsSurvey(server, dataDir = DATA_DIR$
|
|
6377
|
+
function registerSendNpsSurvey(server, dataDir = DATA_DIR$10) {
|
|
6393
6378
|
server.registerTool("send_nps_survey", {
|
|
6394
6379
|
description: `Generate an NPS/CSAT survey email for a customer contact. Returns subject, HTML body, and a token-based response URL.
|
|
6395
6380
|
Does NOT send automatically — returns draft for review.
|
|
@@ -6409,8 +6394,8 @@ Returns: { token, subject, body, surveyUrl }`,
|
|
|
6409
6394
|
}
|
|
6410
6395
|
//#endregion
|
|
6411
6396
|
//#region src/mcp/tools/get-survey-results.ts
|
|
6412
|
-
const DATA_DIR$
|
|
6413
|
-
async function handleGetSurveyResults(input, dataDir = DATA_DIR$
|
|
6397
|
+
const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6398
|
+
async function handleGetSurveyResults(input, dataDir = DATA_DIR$9) {
|
|
6414
6399
|
const responses = loadSurveyResponses(dataDir, input.surveyId, input.slug);
|
|
6415
6400
|
const nps = calcNpsScore(responses);
|
|
6416
6401
|
const promoters = responses.filter((r) => r.score >= 9).length;
|
|
@@ -6436,7 +6421,7 @@ async function handleGetSurveyResults(input, dataDir = DATA_DIR$8) {
|
|
|
6436
6421
|
}, null, 2)
|
|
6437
6422
|
}] };
|
|
6438
6423
|
}
|
|
6439
|
-
function registerGetSurveyResults(server, dataDir = DATA_DIR$
|
|
6424
|
+
function registerGetSurveyResults(server, dataDir = DATA_DIR$9) {
|
|
6440
6425
|
server.registerTool("get_survey_results", {
|
|
6441
6426
|
description: `Get NPS/CSAT survey results with score breakdown. Calculates Net Promoter Score.
|
|
6442
6427
|
Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[] }`,
|
|
@@ -6466,18 +6451,21 @@ const KbArticleSchema = zod.z.object({
|
|
|
6466
6451
|
function kbDir(dataDir) {
|
|
6467
6452
|
return path.default.join(dataDir, ".agentic", "knowledge-base");
|
|
6468
6453
|
}
|
|
6469
|
-
|
|
6470
|
-
|
|
6454
|
+
/** Category subdirectories of the knowledge base. */
|
|
6455
|
+
function kbCategories(dir) {
|
|
6471
6456
|
if (!fs.default.existsSync(dir)) return [];
|
|
6472
|
-
|
|
6473
|
-
const categories = fs.default.readdirSync(dir).filter((f) => {
|
|
6457
|
+
return fs.default.readdirSync(dir).filter((f) => {
|
|
6474
6458
|
try {
|
|
6475
6459
|
return fs.default.statSync(path.default.join(dir, f)).isDirectory();
|
|
6476
6460
|
} catch {
|
|
6477
6461
|
return false;
|
|
6478
6462
|
}
|
|
6479
6463
|
});
|
|
6480
|
-
|
|
6464
|
+
}
|
|
6465
|
+
function listKbArticles(dataDir, opts) {
|
|
6466
|
+
const dir = kbDir(dataDir);
|
|
6467
|
+
const results = [];
|
|
6468
|
+
for (const cat of kbCategories(dir)) {
|
|
6481
6469
|
const catDir = path.default.join(dir, cat);
|
|
6482
6470
|
const files = fs.default.readdirSync(catDir).filter((f) => f.endsWith(".md"));
|
|
6483
6471
|
for (const file of files) try {
|
|
@@ -6497,14 +6485,31 @@ function listKbArticles(dataDir, opts) {
|
|
|
6497
6485
|
return results;
|
|
6498
6486
|
}
|
|
6499
6487
|
function getKbArticle(dataDir, id) {
|
|
6500
|
-
|
|
6488
|
+
if (!require_session_store.isSafePathSegment(id)) return null;
|
|
6489
|
+
const dir = kbDir(dataDir);
|
|
6490
|
+
for (const cat of kbCategories(dir)) {
|
|
6491
|
+
const filePath = path.default.join(dir, cat, `${id}.md`);
|
|
6492
|
+
if (!fs.default.existsSync(filePath)) continue;
|
|
6493
|
+
try {
|
|
6494
|
+
const parsed = (0, gray_matter.default)(fs.default.readFileSync(filePath, "utf-8"));
|
|
6495
|
+
const meta = KbArticleSchema.safeParse(parsed.data);
|
|
6496
|
+
if (!meta.success) return null;
|
|
6497
|
+
return {
|
|
6498
|
+
...meta.data,
|
|
6499
|
+
body: parsed.content.trim()
|
|
6500
|
+
};
|
|
6501
|
+
} catch {
|
|
6502
|
+
return null;
|
|
6503
|
+
}
|
|
6504
|
+
}
|
|
6505
|
+
return null;
|
|
6501
6506
|
}
|
|
6502
6507
|
function writeKbArticle(dataDir, article) {
|
|
6503
|
-
|
|
6504
|
-
|
|
6508
|
+
require_session_store.assertSafePathSegment(article.category, "knowledge-base category");
|
|
6509
|
+
require_session_store.assertSafePathSegment(article.id, "knowledge-base article id");
|
|
6505
6510
|
const { body, ...meta } = article;
|
|
6506
6511
|
const content = gray_matter.default.stringify(body, meta);
|
|
6507
|
-
|
|
6512
|
+
require_atomic_write.writeFileAtomic(path.default.join(kbDir(dataDir), article.category, `${article.id}.md`), content);
|
|
6508
6513
|
}
|
|
6509
6514
|
function searchKbSimple(dataDir, query, opts) {
|
|
6510
6515
|
const all = listKbArticles(dataDir, opts?.publicOnly ? { publicOnly: true } : {});
|
|
@@ -6517,8 +6522,8 @@ function getKbMetaForExport(article) {
|
|
|
6517
6522
|
}
|
|
6518
6523
|
//#endregion
|
|
6519
6524
|
//#region src/mcp/tools/search-knowledge-base.ts
|
|
6520
|
-
const DATA_DIR$
|
|
6521
|
-
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$
|
|
6525
|
+
const DATA_DIR$8 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6526
|
+
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$8) {
|
|
6522
6527
|
const results = searchKbSimple(dataDir, input.query, { ...input.publicOnly ? { publicOnly: true } : {} });
|
|
6523
6528
|
const limited = (input.category ? results.filter((a) => a.category === input.category) : results).slice(0, input.limit ?? 10);
|
|
6524
6529
|
return { content: [{
|
|
@@ -6533,7 +6538,7 @@ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$7) {
|
|
|
6533
6538
|
}, null, 2)
|
|
6534
6539
|
}] };
|
|
6535
6540
|
}
|
|
6536
|
-
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$
|
|
6541
|
+
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$8) {
|
|
6537
6542
|
server.registerTool("search_knowledge_base", {
|
|
6538
6543
|
description: `Search the knowledge base for articles. Text search on title, body, and tags.
|
|
6539
6544
|
Returns: { count, articles[] } with excerpts`,
|
|
@@ -6552,8 +6557,8 @@ Returns: { count, articles[] } with excerpts`,
|
|
|
6552
6557
|
}
|
|
6553
6558
|
//#endregion
|
|
6554
6559
|
//#region src/mcp/tools/create-kb-article.ts
|
|
6555
|
-
const DATA_DIR$
|
|
6556
|
-
async function handleCreateKbArticle(input, dataDir = DATA_DIR$
|
|
6560
|
+
const DATA_DIR$7 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6561
|
+
async function handleCreateKbArticle(input, dataDir = DATA_DIR$7) {
|
|
6557
6562
|
if (getKbArticle(dataDir, input.id)) return { content: [{
|
|
6558
6563
|
type: "text",
|
|
6559
6564
|
text: JSON.stringify({ error: `Article '${input.id}' already exists` })
|
|
@@ -6581,7 +6586,7 @@ async function handleCreateKbArticle(input, dataDir = DATA_DIR$6) {
|
|
|
6581
6586
|
}, null, 2)
|
|
6582
6587
|
}] };
|
|
6583
6588
|
}
|
|
6584
|
-
function registerCreateKbArticle(server, dataDir = DATA_DIR$
|
|
6589
|
+
function registerCreateKbArticle(server, dataDir = DATA_DIR$7) {
|
|
6585
6590
|
server.registerTool("create_kb_article", {
|
|
6586
6591
|
description: `Create a new knowledge base article. Articles are stored as Markdown files in .agentic/knowledge-base/.
|
|
6587
6592
|
Returns: { id, title, category, path }`,
|
|
@@ -6606,8 +6611,8 @@ Returns: { id, title, category, path }`,
|
|
|
6606
6611
|
}
|
|
6607
6612
|
//#endregion
|
|
6608
6613
|
//#region src/mcp/tools/backup-now.ts
|
|
6609
|
-
const DATA_DIR$
|
|
6610
|
-
async function handleBackupNow(input, dataDir = DATA_DIR$
|
|
6614
|
+
const DATA_DIR$6 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6615
|
+
async function handleBackupNow(input, dataDir = DATA_DIR$6) {
|
|
6611
6616
|
const zipPath = path.default.join(dataDir, `dxcrm-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.zip`);
|
|
6612
6617
|
const manifest = await require_session_store.runBackup(zipPath, dataDir, { ...input.remote ? { remote: input.remote } : {} }).catch(() => null);
|
|
6613
6618
|
if (!manifest) return { content: [{
|
|
@@ -6644,8 +6649,8 @@ function registerBackupNow(server) {
|
|
|
6644
6649
|
}
|
|
6645
6650
|
//#endregion
|
|
6646
6651
|
//#region src/mcp/tools/list-backups.ts
|
|
6647
|
-
const DATA_DIR$
|
|
6648
|
-
async function handleListBackups(input, dataDir = DATA_DIR$
|
|
6652
|
+
const DATA_DIR$5 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6653
|
+
async function handleListBackups(input, dataDir = DATA_DIR$5) {
|
|
6649
6654
|
const logEntries = require_session_store.readBackupLog(dataDir);
|
|
6650
6655
|
const fileEntries = require_session_store.listBackupsInDir(dataDir);
|
|
6651
6656
|
const entries = logEntries.length > 0 ? logEntries : fileEntries;
|
|
@@ -6679,8 +6684,8 @@ function registerListBackups(server) {
|
|
|
6679
6684
|
}
|
|
6680
6685
|
//#endregion
|
|
6681
6686
|
//#region src/mcp/tools/trigger-sync.ts
|
|
6682
|
-
const DATA_DIR$
|
|
6683
|
-
async function handleTriggerSync(input, dataDir = DATA_DIR$
|
|
6687
|
+
const DATA_DIR$4 = process.cwd();
|
|
6688
|
+
async function handleTriggerSync(input, dataDir = DATA_DIR$4) {
|
|
6684
6689
|
const auth = getGmailAuth();
|
|
6685
6690
|
if (!auth) return { content: [{
|
|
6686
6691
|
type: "text",
|
|
@@ -6715,7 +6720,7 @@ async function handleTriggerSync(input, dataDir = DATA_DIR$3) {
|
|
|
6715
6720
|
try {
|
|
6716
6721
|
const sources = JSON.parse(fs.default.readFileSync(sourcesPath, "utf-8"));
|
|
6717
6722
|
if (!sources.gmail?.enabled || !sources.gmail.query) continue;
|
|
6718
|
-
const { syncGmail } = await Promise.resolve().then(() => require("./gmail-sync-
|
|
6723
|
+
const { syncGmail } = await Promise.resolve().then(() => require("./gmail-sync-BpSVESSe.cjs"));
|
|
6719
6724
|
const result = await syncGmail({
|
|
6720
6725
|
slug,
|
|
6721
6726
|
dataDir,
|
|
@@ -6774,8 +6779,8 @@ Returns: { success: boolean, synced: number, skipped: number, customers: [...],
|
|
|
6774
6779
|
}
|
|
6775
6780
|
//#endregion
|
|
6776
6781
|
//#region src/mcp/tools/get-audit-log.ts
|
|
6777
|
-
const DATA_DIR$
|
|
6778
|
-
async function handleGetAuditLog(input, dataDir = DATA_DIR$
|
|
6782
|
+
const DATA_DIR$3 = process.cwd();
|
|
6783
|
+
async function handleGetAuditLog(input, dataDir = DATA_DIR$3) {
|
|
6779
6784
|
const entries = require_session_store.readAuditLog(dataDir);
|
|
6780
6785
|
const filterOpts = { limit: input.limit ?? 50 };
|
|
6781
6786
|
if (input.slug !== void 0) filterOpts.slug = input.slug;
|
|
@@ -6816,6 +6821,69 @@ Returns: { total: number, returned: number, entries: [{timestamp, actor, tool, s
|
|
|
6816
6821
|
});
|
|
6817
6822
|
}
|
|
6818
6823
|
//#endregion
|
|
6824
|
+
//#region src/mcp/tools/get-logs.ts
|
|
6825
|
+
const DATA_DIR$2 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6826
|
+
async function handleGetLogs(input, dataDir = DATA_DIR$2) {
|
|
6827
|
+
const query = {
|
|
6828
|
+
...input.level !== void 0 ? { level: input.level } : {},
|
|
6829
|
+
...input.component !== void 0 ? { component: input.component } : {},
|
|
6830
|
+
...input.since !== void 0 ? { since: input.since } : {},
|
|
6831
|
+
...input.contains !== void 0 ? { contains: input.contains } : {},
|
|
6832
|
+
limit: input.limit ?? 100
|
|
6833
|
+
};
|
|
6834
|
+
const payload = input.summary ? require_logger.summarizeLogs(dataDir, query) : (() => {
|
|
6835
|
+
const entries = require_logger.queryLogs(dataDir, query);
|
|
6836
|
+
return {
|
|
6837
|
+
returned: entries.length,
|
|
6838
|
+
entries
|
|
6839
|
+
};
|
|
6840
|
+
})();
|
|
6841
|
+
return { content: [{
|
|
6842
|
+
type: "text",
|
|
6843
|
+
text: JSON.stringify(payload, null, 2)
|
|
6844
|
+
}] };
|
|
6845
|
+
}
|
|
6846
|
+
function registerGetLogs(server) {
|
|
6847
|
+
server.registerTool("get_logs", {
|
|
6848
|
+
title: "Get Logs",
|
|
6849
|
+
description: `Read and analyze the structured application log (.agentic/logs.ndjson).
|
|
6850
|
+
Use to answer "what went wrong recently?", "show errors from gmail sync", or "summarize today's activity".
|
|
6851
|
+
|
|
6852
|
+
Args:
|
|
6853
|
+
level: Minimum level to include — debug | info | warn | error (optional)
|
|
6854
|
+
component: Filter by component, e.g. "gmail-sync", "lancedb" (optional)
|
|
6855
|
+
since: ISO timestamp; only entries at or after it (optional)
|
|
6856
|
+
contains: Case-insensitive substring of the message (optional)
|
|
6857
|
+
limit: Max entries to return (default 100, most recent)
|
|
6858
|
+
summary: When true, return aggregated counts (by level + component) and recent errors instead of raw entries
|
|
6859
|
+
|
|
6860
|
+
Returns (entries): { returned: number, entries: [{ts, level, component, message, context?}] }
|
|
6861
|
+
Returns (summary): { total, byLevel, byComponent, firstTs, lastTs, recentErrors }`,
|
|
6862
|
+
inputSchema: zod.z.object({
|
|
6863
|
+
level: zod.z.enum([
|
|
6864
|
+
"debug",
|
|
6865
|
+
"info",
|
|
6866
|
+
"warn",
|
|
6867
|
+
"error"
|
|
6868
|
+
]).optional().describe("Minimum level"),
|
|
6869
|
+
component: zod.z.string().optional().describe("Filter by component"),
|
|
6870
|
+
since: zod.z.string().optional().describe("ISO timestamp lower bound"),
|
|
6871
|
+
contains: zod.z.string().optional().describe("Message substring filter"),
|
|
6872
|
+
limit: zod.z.number().int().min(1).max(1e3).optional().describe("Max entries (default 100)"),
|
|
6873
|
+
summary: zod.z.boolean().optional().describe("Return aggregated summary instead of entries")
|
|
6874
|
+
})
|
|
6875
|
+
}, async ({ level, component, since, contains, limit, summary }) => {
|
|
6876
|
+
const input = {};
|
|
6877
|
+
if (level !== void 0) input.level = level;
|
|
6878
|
+
if (component !== void 0) input.component = component;
|
|
6879
|
+
if (since !== void 0) input.since = since;
|
|
6880
|
+
if (contains !== void 0) input.contains = contains;
|
|
6881
|
+
if (limit !== void 0) input.limit = limit;
|
|
6882
|
+
if (summary !== void 0) input.summary = summary;
|
|
6883
|
+
return handleGetLogs(input);
|
|
6884
|
+
});
|
|
6885
|
+
}
|
|
6886
|
+
//#endregion
|
|
6819
6887
|
//#region src/mcp/prompts.ts
|
|
6820
6888
|
/**
|
|
6821
6889
|
* CRM playbook prompts exposed via MCP `prompts/list` + `prompts/get`.
|
|
@@ -6897,7 +6965,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
|
|
|
6897
6965
|
description: "Open and closed deals for a customer",
|
|
6898
6966
|
mimeType: "application/json"
|
|
6899
6967
|
}, async (uri, variables) => {
|
|
6900
|
-
const { readPipeline } = await Promise.resolve().then(() => require("./pipeline-writer-
|
|
6968
|
+
const { readPipeline } = await Promise.resolve().then(() => require("./pipeline-writer-B1tRAhuD.cjs")).then((n) => n.pipeline_writer_exports);
|
|
6901
6969
|
const deals = await readPipeline(dataDir, String(variables["slug"]));
|
|
6902
6970
|
return { contents: [{
|
|
6903
6971
|
uri: uri.href,
|
|
@@ -6910,7 +6978,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
|
|
|
6910
6978
|
description: "Newest-first interaction history for a customer",
|
|
6911
6979
|
mimeType: "text/markdown"
|
|
6912
6980
|
}, async (uri, variables) => {
|
|
6913
|
-
const { readInteractions } = await Promise.resolve().then(() => require("./interactions-writer-
|
|
6981
|
+
const { readInteractions } = await Promise.resolve().then(() => require("./interactions-writer-BRJNrefF.cjs")).then((n) => n.interactions_writer_exports);
|
|
6914
6982
|
const text = await readInteractions(dataDir, String(variables["slug"]));
|
|
6915
6983
|
return { contents: [{
|
|
6916
6984
|
uri: uri.href,
|
|
@@ -6969,46 +7037,30 @@ function objectsSchemaPath(dataDir) {
|
|
|
6969
7037
|
return path.default.join(dataDir, ".agentic", "schema", "custom-objects.json");
|
|
6970
7038
|
}
|
|
6971
7039
|
function recordsPath(dataDir, name) {
|
|
7040
|
+
require_session_store.assertSafePathSegment(name, "custom object name");
|
|
6972
7041
|
return path.default.join(dataDir, ".agentic", "objects", `${name}.json`);
|
|
6973
7042
|
}
|
|
6974
7043
|
function loadCustomObjects(dataDir) {
|
|
6975
|
-
|
|
6976
|
-
if (!fs.default.existsSync(p)) return [];
|
|
6977
|
-
try {
|
|
6978
|
-
const data = JSON.parse(fs.default.readFileSync(p, "utf-8"));
|
|
6979
|
-
return Array.isArray(data.objects) ? data.objects : [];
|
|
6980
|
-
} catch {
|
|
6981
|
-
return [];
|
|
6982
|
-
}
|
|
7044
|
+
return require_session_store.readJsonArray(objectsSchemaPath(dataDir), "objects");
|
|
6983
7045
|
}
|
|
6984
7046
|
function getObjectDefinition(dataDir, name) {
|
|
6985
7047
|
return loadCustomObjects(dataDir).find((o) => o.name === name);
|
|
6986
7048
|
}
|
|
6987
7049
|
/** Add or update (by name) a custom object definition. */
|
|
6988
7050
|
function defineCustomObject(dataDir, def) {
|
|
7051
|
+
require_session_store.assertSafePathSegment(def.name, "custom object name");
|
|
6989
7052
|
const objs = loadCustomObjects(dataDir);
|
|
6990
7053
|
const idx = objs.findIndex((o) => o.name === def.name);
|
|
6991
7054
|
if (idx >= 0) objs[idx] = def;
|
|
6992
7055
|
else objs.push(def);
|
|
6993
|
-
|
|
6994
|
-
fs.default.mkdirSync(path.default.dirname(p), { recursive: true });
|
|
6995
|
-
fs.default.writeFileSync(p, JSON.stringify({ objects: objs }, null, 2), "utf-8");
|
|
7056
|
+
require_session_store.writeJsonArray(objectsSchemaPath(dataDir), "objects", objs);
|
|
6996
7057
|
return objs;
|
|
6997
7058
|
}
|
|
6998
7059
|
function listRecords(dataDir, name) {
|
|
6999
|
-
|
|
7000
|
-
if (!fs.default.existsSync(p)) return [];
|
|
7001
|
-
try {
|
|
7002
|
-
const data = JSON.parse(fs.default.readFileSync(p, "utf-8"));
|
|
7003
|
-
return Array.isArray(data.records) ? data.records : [];
|
|
7004
|
-
} catch {
|
|
7005
|
-
return [];
|
|
7006
|
-
}
|
|
7060
|
+
return require_session_store.readJsonArray(recordsPath(dataDir, name), "records");
|
|
7007
7061
|
}
|
|
7008
7062
|
function writeRecords(dataDir, name, records) {
|
|
7009
|
-
|
|
7010
|
-
fs.default.mkdirSync(path.default.dirname(p), { recursive: true });
|
|
7011
|
-
fs.default.writeFileSync(p, JSON.stringify({ records }, null, 2), "utf-8");
|
|
7063
|
+
require_session_store.writeJsonArray(recordsPath(dataDir, name), "records", records);
|
|
7012
7064
|
}
|
|
7013
7065
|
function createRecord(dataDir, name, values) {
|
|
7014
7066
|
const def = getObjectDefinition(dataDir, name);
|
|
@@ -7066,7 +7118,7 @@ function handleCreateRecord(input, dataDir = DATA_DIR) {
|
|
|
7066
7118
|
require_session_store.enforceRbac(dataDir, "create_record");
|
|
7067
7119
|
const res = createRecord(dataDir, input.object, input.values);
|
|
7068
7120
|
if (!res.ok) return json({ error: (res.errors ?? []).join("; ") });
|
|
7069
|
-
Promise.resolve().then(() => require("./webhooks-
|
|
7121
|
+
Promise.resolve().then(() => require("./webhooks-CwW-3kvG.cjs")).then(({ emitEvent }) => emitEvent(dataDir, "record.created", {
|
|
7070
7122
|
object: input.object,
|
|
7071
7123
|
record: res.record
|
|
7072
7124
|
}));
|
|
@@ -7128,14 +7180,7 @@ function hashToken(token) {
|
|
|
7128
7180
|
return (0, crypto.createHash)("sha256").update(token).digest("hex");
|
|
7129
7181
|
}
|
|
7130
7182
|
function loadMcpTokens(dataDir) {
|
|
7131
|
-
|
|
7132
|
-
if (!fs.default.existsSync(p)) return [];
|
|
7133
|
-
try {
|
|
7134
|
-
const data = JSON.parse(fs.default.readFileSync(p, "utf-8"));
|
|
7135
|
-
return Array.isArray(data.tokens) ? data.tokens : [];
|
|
7136
|
-
} catch {
|
|
7137
|
-
return [];
|
|
7138
|
-
}
|
|
7183
|
+
return require_session_store.readJsonArray(tokensPath(dataDir), "tokens");
|
|
7139
7184
|
}
|
|
7140
7185
|
/**
|
|
7141
7186
|
* Whether the HTTP MCP endpoint must require a bearer token.
|
|
@@ -7254,6 +7299,7 @@ function createMcpServer() {
|
|
|
7254
7299
|
registerListBackups(server);
|
|
7255
7300
|
registerTriggerSync(server);
|
|
7256
7301
|
registerGetAuditLog(server);
|
|
7302
|
+
registerGetLogs(server);
|
|
7257
7303
|
registerCustomObjectTools(server);
|
|
7258
7304
|
registerPrompts(server);
|
|
7259
7305
|
registerResources(server);
|
|
@@ -7264,7 +7310,7 @@ async function startStdio() {
|
|
|
7264
7310
|
const server = createMcpServer();
|
|
7265
7311
|
const transport = new _modelcontextprotocol_sdk_server_stdio_js.StdioServerTransport();
|
|
7266
7312
|
await server.connect(transport);
|
|
7267
|
-
|
|
7313
|
+
require_logger.logger.info("mcp-server", "running via stdio");
|
|
7268
7314
|
}
|
|
7269
7315
|
async function startHttp(port = 3847) {
|
|
7270
7316
|
await initOAuthFromDisk(process.cwd());
|
|
@@ -7304,7 +7350,7 @@ async function startHttp(port = 3847) {
|
|
|
7304
7350
|
});
|
|
7305
7351
|
app.get("/sessions", async (_req, res) => {
|
|
7306
7352
|
try {
|
|
7307
|
-
const { readAllSessions } = await Promise.resolve().then(() => require("./session-
|
|
7353
|
+
const { readAllSessions } = await Promise.resolve().then(() => require("./session-Mm7GQbSH.cjs"));
|
|
7308
7354
|
const sessions = readAllSessions(dataDir);
|
|
7309
7355
|
res.json({ sessions });
|
|
7310
7356
|
} catch {
|
|
@@ -7438,15 +7484,15 @@ button{margin-top:12px;padding:12px 28px;background:#1a1a2e;color:#fff;border:no
|
|
|
7438
7484
|
res.send(surveyThankYouPage(numScore, commentText));
|
|
7439
7485
|
});
|
|
7440
7486
|
app.listen(port, () => {
|
|
7441
|
-
|
|
7487
|
+
require_logger.logger.info("mcp-server", "running over http", { url: `http://0.0.0.0:${port}/mcp` });
|
|
7442
7488
|
});
|
|
7443
7489
|
}
|
|
7444
7490
|
if ((process.env["DXCRM_MCP_MODE"] ?? "stdio") === "http") startHttp(parseInt(process.env["DXCRM_MCP_PORT"] ?? "3847", 10)).catch((err) => {
|
|
7445
|
-
|
|
7491
|
+
require_logger.logger.error("mcp-server", "fatal error", { error: err.message });
|
|
7446
7492
|
process.exit(1);
|
|
7447
7493
|
});
|
|
7448
7494
|
else startStdio().catch((err) => {
|
|
7449
|
-
|
|
7495
|
+
require_logger.logger.error("mcp-server", "fatal error", { error: err.message });
|
|
7450
7496
|
process.exit(1);
|
|
7451
7497
|
});
|
|
7452
7498
|
//#endregion
|