@datasynx/agentic-crm 0.1.0 → 1.0.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 +264 -670
- package/dist/{approvals-DpjxGHFp.js → approvals-CmDT2eUg.js} +7 -24
- package/dist/approvals-CmDT2eUg.js.map +1 -0
- package/dist/{ask-CID3jnuL.js → ask-D8iYqDAr.js} +6 -6
- package/dist/{ask-CID3jnuL.js.map → ask-D8iYqDAr.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/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/{churn-C28IgnAj.js → churn-DN9WDGNM.js} +3 -3
- package/dist/{churn-C28IgnAj.js.map → churn-DN9WDGNM.js.map} +1 -1
- package/dist/cli.js +282 -184
- 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/{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-rQaVqKWd.js → gmail-sync-C-NmibzS.js} +13 -9
- package/dist/gmail-sync-C-NmibzS.js.map +1 -0
- package/dist/{gmail-sync-DIaxInDT.js → gmail-sync-DueE6tl5.js} +14 -10
- package/dist/gmail-sync-DueE6tl5.js.map +1 -0
- package/dist/{gmail-sync-hHm9gaWd.cjs → gmail-sync-GEy3oVvw.cjs} +13 -9
- package/dist/gmail-sync-GEy3oVvw.cjs.map +1 -0
- package/dist/{gmail-webhook-handler-DS7OlRPX.js → gmail-webhook-handler-B26COilD.js} +2 -2
- package/dist/{gmail-webhook-handler-e5Od25FX.js → gmail-webhook-handler-kGKpbY9h.js} +4 -4
- package/dist/{gmail-webhook-handler-e5Od25FX.js.map → gmail-webhook-handler-kGKpbY9h.js.map} +1 -1
- 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-D1n7WKZn.js} +3 -3
- package/dist/{google-drive-sync-DEPcqFca.js.map → google-drive-sync-D1n7WKZn.js.map} +1 -1
- 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-DB4n89jy.js} +51 -45
- package/dist/import-hubspot-DB4n89jy.js.map +1 -0
- package/dist/{index-V8BFaH-b.d.ts → index-B0IMMrp_.d.ts} +8 -4
- package/dist/{index-V8BFaH-b.d.ts.map → index-B0IMMrp_.d.ts.map} +1 -1
- package/dist/{index-YqwMd6aQ.d.cts → index-pY7tYXwH.d.cts} +8 -4
- package/dist/{index-YqwMd6aQ.d.cts.map → index-pY7tYXwH.d.cts.map} +1 -1
- package/dist/index.cjs +19 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +8 -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-DO3KcSR3.js → interactions-writer-BZzUIgJd.js} +5 -2
- package/dist/interactions-writer-BZzUIgJd.js.map +1 -0
- package/dist/{interactions-writer-SLHnoEeE.js → interactions-writer-DbSyI2rt.js} +32 -3
- package/dist/interactions-writer-DbSyI2rt.js.map +1 -0
- package/dist/interactions-writer-RJB8SWf2.js +2 -0
- package/dist/{interactions-writer-CrPStUll.cjs → interactions-writer-a2yzBd7T.cjs} +5 -2
- package/dist/interactions-writer-a2yzBd7T.cjs.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-DHNc4hVj.js} +43 -16
- package/dist/knowledge-base-DHNc4hVj.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 +327 -303
- 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 +327 -303
- 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-jIu9K5zX.js} +4 -4
- package/dist/{microsoft-calendar-B6MMtUQK.js.map → microsoft-calendar-jIu9K5zX.js.map} +1 -1
- package/dist/{microsoft-sync-CpZVoSuq.js → microsoft-sync-R_r8HL-B.js} +5 -5
- package/dist/{microsoft-sync-CpZVoSuq.js.map → microsoft-sync-R_r8HL-B.js.map} +1 -1
- package/dist/{nba-3wanmJ0U.js → nba-mTJ4yEqD.js} +3 -3
- package/dist/{nba-3wanmJ0U.js.map → nba-mTJ4yEqD.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-DqSMYhSA.js} +278 -220
- package/dist/server-DqSMYhSA.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-0mh2ZhmH.js} +18 -11
- package/dist/transcript-watcher-0mh2ZhmH.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 +11 -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/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
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as readMainFacts, i as listCustomerSlugs, n as customerExists, o as writeMainFacts, r as ensureCustomerDir } from "./customer-dir-CkMMXhb0.js";
|
|
2
|
+
import { t as writeFileAtomic } from "./atomic-write-8yjqqLtS.js";
|
|
3
|
+
import { i as writeJsonFile } from "./json-store-WWsFzXub.js";
|
|
2
4
|
import { n as getSession } from "./session-store-CEa39Dxs.js";
|
|
3
|
-
import { a as searchKbSimple, n as getKbArticle, o as writeKbArticle, r as getKbMetaForExport, s as CAPABILITIES_TEXT } from "./knowledge-base-
|
|
4
|
-
import { i as readBackupLog, n as listBackupsInDir, o as runBackup } from "./backup-
|
|
5
|
-
import { r as updateSlugSyncState, t as getLastGmailSync } from "./sync-state-
|
|
5
|
+
import { a as searchKbSimple, n as getKbArticle, o as writeKbArticle, r as getKbMetaForExport, s as CAPABILITIES_TEXT } from "./knowledge-base-DHNc4hVj.js";
|
|
6
|
+
import { i as readBackupLog, n as listBackupsInDir, o as runBackup } from "./backup-CTlIxUdO.js";
|
|
7
|
+
import { r as updateSlugSyncState, t as getLastGmailSync } from "./sync-state-DMZgzpez.js";
|
|
6
8
|
import { t as withFileQueue } from "./write-queue-IbsAjUnh.js";
|
|
7
|
-
import { n as
|
|
9
|
+
import { n as appendInteraction, r as formatInteractionEntry } from "./interactions-writer-DbSyI2rt.js";
|
|
8
10
|
import { i as writeAuditEntry, n as getActor, r as readAuditLog, t as filterAuditLog } from "./audit-log-DNMY9mUZ.js";
|
|
9
|
-
import { a as
|
|
10
|
-
import { f as getPipelineStages, i as buildSimulationInput, l as runSimulation, n as buildConfidenceMessage } from "./revenue-simulation-
|
|
11
|
-
import { t as readPipeline } from "./pipeline-writer-
|
|
12
|
-
import { a as
|
|
13
|
-
import { t as
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { n as
|
|
18
|
-
import {
|
|
19
|
-
import { i as
|
|
20
|
-
import { i as
|
|
21
|
-
import { t as
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { n as
|
|
11
|
+
import { a as customerVisibility, n as canSeeCustomer, o as enforceRbac } from "./rbac-msmBc_tK.js";
|
|
12
|
+
import { f as getPipelineStages, i as buildSimulationInput, l as runSimulation, n as buildConfidenceMessage } from "./revenue-simulation-D8f_YkUY.js";
|
|
13
|
+
import { n as readPipelineSync, t as readPipeline } from "./pipeline-writer-CIllfnZl.js";
|
|
14
|
+
import { a as summarizeLogs, i as queryLogs, n as logger } from "./logger-Dyl4VcLO.js";
|
|
15
|
+
import { a as updateGraphFromInteraction, c as readGraph, i as writeHealth, n as readHealth, o as findPath, r as updateHealthFromInteraction, s as getStakeholders, t as computeCustomerHealth } from "./relationship-health-ZZNXR1RZ.js";
|
|
16
|
+
import { t as callLlm } from "./llm-PZzgPphl.js";
|
|
17
|
+
import { d as pursueGoal, i as getActiveGoals, p as readGoals } from "./goal-engine-BbroPhqm.js";
|
|
18
|
+
import { n as readSubscriptions, r as register, s as writeSubscriptions } from "./push-manager-C0ECQgva.js";
|
|
19
|
+
import { a as writeEnrollment, c as extractVariables, d as getTemplate, f as listTemplates, i as updateEnrollment, l as interpolate, n as listSequences, r as readEnrollments, s as buildVariablesFromCustomer, t as getSequence } from "./sequence-store-CmYb6s0g.js";
|
|
20
|
+
import { n as listQuotes, r as readQuote, t as generateQuote } from "./quote-generator-CTdR8eEI.js";
|
|
21
|
+
import { i as upsertTicket, n as nextTicketId, r as readTickets, t as listAllTickets } from "./ticket-writer-a9on36Wb.js";
|
|
22
|
+
import { i as loadSlaRules, t as calcSlaDue } from "./sla-engine-O-A1ntu_.js";
|
|
23
|
+
import { i as getSurvey, l as savePendingSurvey, n as calcNpsScore, o as loadSurveyResponses, r as generateSurveyToken, t as buildSurveyEmail } from "./survey-engine-DngXBv47.js";
|
|
24
|
+
import { t as buildContext } from "./context-builder-7Uab5-G4.js";
|
|
25
|
+
import { a as loadCustomObjects, i as listRecords, n as defineCustomObject, t as createRecord } from "./custom-objects-CxW1gHwJ.js";
|
|
26
|
+
import { r as searchKnowledge } from "./lancedb-CuHKNsNZ.js";
|
|
27
|
+
import { t as buildDailyBriefing } from "./proactive-agent-B7u3Bj_l.js";
|
|
28
|
+
import { a as protectedResourceMetadata, o as verifyBearer, r as isAuthRequired, s as wwwAuthenticateHeader } from "./auth-DDXZTwS0.js";
|
|
29
|
+
import { i as verifyGmailPubSubSignature, n as decodeGmailPubSubPayload, r as handleGmailPushEvent } from "./gmail-webhook-handler-kGKpbY9h.js";
|
|
30
|
+
import { n as registerUpdateDeal } from "./update-deal-DSzr_Aau.js";
|
|
28
31
|
import path from "path";
|
|
29
32
|
import fs from "fs";
|
|
30
33
|
import matter from "gray-matter";
|
|
@@ -251,7 +254,7 @@ function registerGetActiveSession(server) {
|
|
|
251
254
|
}
|
|
252
255
|
//#endregion
|
|
253
256
|
//#region src/mcp/tools/get-customer-context.ts
|
|
254
|
-
const DATA_DIR$
|
|
257
|
+
const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
255
258
|
function triggerOnQuerySync(dataDir, slug) {
|
|
256
259
|
const auth = getGmailAuth();
|
|
257
260
|
if (!auth) return;
|
|
@@ -264,7 +267,7 @@ function triggerOnQuerySync(dataDir, slug) {
|
|
|
264
267
|
const sources = JSON.parse(fs.readFileSync(sourcesPath, "utf-8"));
|
|
265
268
|
if (!sources.gmail?.enabled || !sources.gmail.query) return;
|
|
266
269
|
const query = sources.gmail.query;
|
|
267
|
-
import("./gmail-sync-
|
|
270
|
+
import("./gmail-sync-DueE6tl5.js").then(({ syncGmail }) => syncGmail({
|
|
268
271
|
slug,
|
|
269
272
|
dataDir,
|
|
270
273
|
auth,
|
|
@@ -272,7 +275,7 @@ function triggerOnQuerySync(dataDir, slug) {
|
|
|
272
275
|
}).then(() => updateSlugSyncState(dataDir, slug, { lastGmailSync: (/* @__PURE__ */ new Date()).toISOString() })).catch(() => {})).catch(() => {});
|
|
273
276
|
} catch {}
|
|
274
277
|
}
|
|
275
|
-
async function handleGetCustomerContext(input, dataDir = DATA_DIR$
|
|
278
|
+
async function handleGetCustomerContext(input, dataDir = DATA_DIR$51) {
|
|
276
279
|
const targetSlug = input.slug ?? getSession()?.customerSlug;
|
|
277
280
|
if (!targetSlug) return {
|
|
278
281
|
content: [{
|
|
@@ -324,8 +327,8 @@ Performance: <3 seconds. Token budget: <3000.`,
|
|
|
324
327
|
}
|
|
325
328
|
//#endregion
|
|
326
329
|
//#region src/mcp/tools/search-customer-knowledge.ts
|
|
327
|
-
const DATA_DIR$
|
|
328
|
-
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$
|
|
330
|
+
const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
331
|
+
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$50) {
|
|
329
332
|
const limit = input.limit ?? 5;
|
|
330
333
|
try {
|
|
331
334
|
const results = await searchKnowledge(dataDir, input.slug, input.query, limit);
|
|
@@ -373,14 +376,14 @@ If no results: returns empty array with a helpful sync suggestion.`,
|
|
|
373
376
|
}
|
|
374
377
|
//#endregion
|
|
375
378
|
//#region src/mcp/tools/list-customers.ts
|
|
376
|
-
const DATA_DIR$
|
|
379
|
+
const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
377
380
|
function extractLastInteractionDate(interactionsPath) {
|
|
378
381
|
if (!fs.existsSync(interactionsPath)) return void 0;
|
|
379
382
|
const content = fs.readFileSync(interactionsPath, "utf-8");
|
|
380
383
|
const match = /^## (\d{4}-\d{2}-\d{2})/m.exec(content);
|
|
381
384
|
return match ? match[1] : void 0;
|
|
382
385
|
}
|
|
383
|
-
async function handleListCustomers(input, dataDir = DATA_DIR$
|
|
386
|
+
async function handleListCustomers(input, dataDir = DATA_DIR$49) {
|
|
384
387
|
const customersDir = path.join(dataDir, "customers");
|
|
385
388
|
const customers = [];
|
|
386
389
|
if (!fs.existsSync(customersDir)) return { content: [{
|
|
@@ -388,6 +391,7 @@ async function handleListCustomers(input, dataDir = DATA_DIR$48) {
|
|
|
388
391
|
text: JSON.stringify([], null, 2)
|
|
389
392
|
}] };
|
|
390
393
|
const entries = fs.readdirSync(customersDir);
|
|
394
|
+
const canSee = customerVisibility(dataDir, process.env["DXCRM_ACTOR"] ?? "system");
|
|
391
395
|
for (const entry of entries) {
|
|
392
396
|
const customerDir = path.join(customersDir, entry);
|
|
393
397
|
try {
|
|
@@ -414,7 +418,7 @@ async function handleListCustomers(input, dataDir = DATA_DIR$48) {
|
|
|
414
418
|
const filterLower = input.filter.toLowerCase();
|
|
415
419
|
if (!(name.toLowerCase().includes(filterLower) || entry.toLowerCase().includes(filterLower) || stage.toLowerCase().includes(filterLower))) continue;
|
|
416
420
|
}
|
|
417
|
-
if (!
|
|
421
|
+
if (!canSee(entry)) continue;
|
|
418
422
|
customers.push(summary);
|
|
419
423
|
} catch {
|
|
420
424
|
continue;
|
|
@@ -440,8 +444,8 @@ Returns: Array of { slug, name, stage, lastInteraction?, dealValue? }`,
|
|
|
440
444
|
}
|
|
441
445
|
//#endregion
|
|
442
446
|
//#region src/mcp/tools/log-interaction.ts
|
|
443
|
-
const DATA_DIR$
|
|
444
|
-
async function handleLogInteraction(input, dataDir = DATA_DIR$
|
|
447
|
+
const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
448
|
+
async function handleLogInteraction(input, dataDir = DATA_DIR$48) {
|
|
445
449
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
446
450
|
const interactionDate = input.date ?? today;
|
|
447
451
|
const sourceRef = input.source ?? `agent://log/${Date.now()}`;
|
|
@@ -471,7 +475,7 @@ async function handleLogInteraction(input, dataDir = DATA_DIR$47) {
|
|
|
471
475
|
raw.data.last_touchpoint = interactionDate;
|
|
472
476
|
let serialized = matter.stringify(raw.content, raw.data);
|
|
473
477
|
serialized = serialized.replace(/^(last_touchpoint:\s*)['"](\d{4}-\d{2}-\d{2})['"]/m, "$1$2");
|
|
474
|
-
|
|
478
|
+
writeFileAtomic(mainFactsPath, serialized);
|
|
475
479
|
} catch {}
|
|
476
480
|
writeAuditEntry(dataDir, {
|
|
477
481
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -546,12 +550,12 @@ Returns: { success: boolean, path: string, entry: string }`,
|
|
|
546
550
|
}
|
|
547
551
|
//#endregion
|
|
548
552
|
//#region src/mcp/tools/export-customer.ts
|
|
549
|
-
const DATA_DIR$
|
|
553
|
+
const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
550
554
|
function countInteractions(content) {
|
|
551
555
|
const matches = content.match(/^## \d{4}-\d{2}-\d{2}/gm);
|
|
552
556
|
return matches ? matches.length : 0;
|
|
553
557
|
}
|
|
554
|
-
async function handleExportCustomer(input, dataDir = DATA_DIR$
|
|
558
|
+
async function handleExportCustomer(input, dataDir = DATA_DIR$47) {
|
|
555
559
|
enforceRbac(dataDir, "export_customer");
|
|
556
560
|
const customerDir = path.join(dataDir, "customers", input.slug);
|
|
557
561
|
if (!fs.existsSync(customerDir)) return {
|
|
@@ -644,8 +648,8 @@ Returns:
|
|
|
644
648
|
}
|
|
645
649
|
//#endregion
|
|
646
650
|
//#region src/mcp/tools/update-customer-facts.ts
|
|
647
|
-
const DATA_DIR$
|
|
648
|
-
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$
|
|
651
|
+
const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
652
|
+
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$46) {
|
|
649
653
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
650
654
|
try {
|
|
651
655
|
enforceRbac(dataDir, "update_customer_facts");
|
|
@@ -795,10 +799,36 @@ function scoreDeal(deal, signals) {
|
|
|
795
799
|
warnings
|
|
796
800
|
};
|
|
797
801
|
}
|
|
802
|
+
const MS_PER_DAY = 864e5;
|
|
803
|
+
/**
|
|
804
|
+
* Derive activity/close timing for a deal relative to `todayDate`. Centralizes
|
|
805
|
+
* the day-diff math that deal-room and deal-agent each computed identically.
|
|
806
|
+
* A blank/whitespace close_date yields `undefined` (not a NaN day count).
|
|
807
|
+
*/
|
|
808
|
+
function deriveDealTiming(deal, todayDate) {
|
|
809
|
+
const updatedDate = deal.updated ? new Date(deal.updated) : todayDate;
|
|
810
|
+
const daysSinceLastActivity = Math.floor((todayDate.getTime() - updatedDate.getTime()) / MS_PER_DAY);
|
|
811
|
+
const timing = {
|
|
812
|
+
daysSinceLastActivity,
|
|
813
|
+
daysInCurrentStage: daysSinceLastActivity
|
|
814
|
+
};
|
|
815
|
+
if (deal.close_date && deal.close_date.trim() !== "") timing.daysToClose = Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / MS_PER_DAY);
|
|
816
|
+
return timing;
|
|
817
|
+
}
|
|
818
|
+
/** Score a deal using timing derived from `todayDate` plus the deal's probability. */
|
|
819
|
+
function scoreDealForToday(deal, todayDate) {
|
|
820
|
+
const timing = deriveDealTiming(deal, todayDate);
|
|
821
|
+
return scoreDeal(deal, {
|
|
822
|
+
daysSinceLastActivity: timing.daysSinceLastActivity,
|
|
823
|
+
daysInCurrentStage: timing.daysInCurrentStage,
|
|
824
|
+
...timing.daysToClose !== void 0 ? { daysToClose: timing.daysToClose } : {},
|
|
825
|
+
...deal.probability !== void 0 ? { probability: deal.probability } : {}
|
|
826
|
+
});
|
|
827
|
+
}
|
|
798
828
|
//#endregion
|
|
799
829
|
//#region src/mcp/tools/get-deal-health.ts
|
|
800
|
-
const DATA_DIR$
|
|
801
|
-
async function handleGetDealHealth(input, dataDir = DATA_DIR$
|
|
830
|
+
const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
831
|
+
async function handleGetDealHealth(input, dataDir = DATA_DIR$45) {
|
|
802
832
|
try {
|
|
803
833
|
const deals = await readPipeline(dataDir, input.slug);
|
|
804
834
|
const today = /* @__PURE__ */ new Date();
|
|
@@ -847,28 +877,13 @@ Returns: { slug, deals: [{ deal, stage, score, grade, signals, warnings }] }`,
|
|
|
847
877
|
}
|
|
848
878
|
//#endregion
|
|
849
879
|
//#region src/mcp/tools/get-pipeline-forecast.ts
|
|
850
|
-
const DATA_DIR$
|
|
851
|
-
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$
|
|
880
|
+
const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
881
|
+
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$44) {
|
|
852
882
|
try {
|
|
853
|
-
const
|
|
854
|
-
if (!fs.existsSync(customersDir)) return { content: [{
|
|
855
|
-
type: "text",
|
|
856
|
-
text: JSON.stringify({
|
|
857
|
-
deals: [],
|
|
858
|
-
totalWeightedValue: 0,
|
|
859
|
-
byStage: {}
|
|
860
|
-
}, null, 2)
|
|
861
|
-
}] };
|
|
862
|
-
const slugs = fs.readdirSync(customersDir).filter((d) => {
|
|
863
|
-
if (input.filter && !d.includes(input.filter)) return false;
|
|
864
|
-
return fs.statSync(path.join(customersDir, d)).isDirectory();
|
|
865
|
-
});
|
|
883
|
+
const slugs = listCustomerSlugs(dataDir).filter((d) => !input.filter || d.includes(input.filter));
|
|
866
884
|
const allDeals = [];
|
|
867
885
|
for (const slug of slugs) {
|
|
868
|
-
const
|
|
869
|
-
if (!fs.existsSync(pipelinePath)) continue;
|
|
870
|
-
const { readPipeline } = await import("./pipeline-writer-BqBrYrQc.js");
|
|
871
|
-
const deals = await readPipeline(dataDir, slug).catch(() => []);
|
|
886
|
+
const deals = readPipelineSync(dataDir, slug);
|
|
872
887
|
for (const deal of deals) {
|
|
873
888
|
if (deal.stage === "won" || deal.stage === "lost") continue;
|
|
874
889
|
const prob = deal.probability ?? 50;
|
|
@@ -924,13 +939,13 @@ Returns: { deals: [...], totalWeightedValue: number, byStage: { stage: { count,
|
|
|
924
939
|
}
|
|
925
940
|
//#endregion
|
|
926
941
|
//#region src/mcp/tools/summarize-meeting.ts
|
|
927
|
-
const DATA_DIR$
|
|
928
|
-
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$
|
|
942
|
+
const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
943
|
+
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$43) {
|
|
929
944
|
try {
|
|
930
945
|
let summary = input.transcript.slice(0, 400);
|
|
931
946
|
let nextSteps = [];
|
|
932
947
|
try {
|
|
933
|
-
const { callLlm } = await import("./llm-
|
|
948
|
+
const { callLlm } = await import("./llm-DSX1-wFu.js");
|
|
934
949
|
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": ["..."] }`);
|
|
935
950
|
const parsed = JSON.parse(response);
|
|
936
951
|
summary = parsed.summary ?? summary;
|
|
@@ -1000,8 +1015,8 @@ Returns: { success, summary, nextSteps, sourceRef }`,
|
|
|
1000
1015
|
}
|
|
1001
1016
|
//#endregion
|
|
1002
1017
|
//#region src/mcp/tools/get-pipeline-stages.ts
|
|
1003
|
-
const DATA_DIR$
|
|
1004
|
-
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$
|
|
1018
|
+
const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1019
|
+
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$42) {
|
|
1005
1020
|
const stages = getPipelineStages(dataDir);
|
|
1006
1021
|
return { content: [{
|
|
1007
1022
|
type: "text",
|
|
@@ -1019,21 +1034,18 @@ function registerGetPipelineStages(server) {
|
|
|
1019
1034
|
//#region src/core/cross-customer.ts
|
|
1020
1035
|
async function searchAcrossCustomers(dataDir, query, limit = 5, excludeSlug) {
|
|
1021
1036
|
const slugs = listCustomerSlugs(dataDir).filter((d) => d !== excludeSlug);
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
const results = await searchKnowledge(dataDir, slug, query, 2);
|
|
1025
|
-
for (const r of results) allResults.push({
|
|
1037
|
+
return (await Promise.all(slugs.map(async (slug) => {
|
|
1038
|
+
return (await searchKnowledge(dataDir, slug, query, 2)).map((r) => ({
|
|
1026
1039
|
slug,
|
|
1027
1040
|
relevantContent: r.content.slice(0, 200),
|
|
1028
1041
|
score: r.score
|
|
1029
|
-
});
|
|
1030
|
-
}
|
|
1031
|
-
return allResults.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
1042
|
+
}));
|
|
1043
|
+
}))).flat().sort((a, b) => b.score - a.score).slice(0, limit);
|
|
1032
1044
|
}
|
|
1033
1045
|
//#endregion
|
|
1034
1046
|
//#region src/mcp/tools/get-market-intelligence.ts
|
|
1035
|
-
const DATA_DIR$
|
|
1036
|
-
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$
|
|
1047
|
+
const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1048
|
+
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$41) {
|
|
1037
1049
|
const excludeSlug = input.excludeCurrentCustomer ? input.slug : void 0;
|
|
1038
1050
|
const all = listCustomerSlugs(dataDir);
|
|
1039
1051
|
const totalCustomersSearched = excludeSlug ? all.filter((s) => s !== excludeSlug).length : all.length;
|
|
@@ -1064,7 +1076,7 @@ function registerGetMarketIntelligence(server) {
|
|
|
1064
1076
|
}
|
|
1065
1077
|
//#endregion
|
|
1066
1078
|
//#region src/mcp/tools/get-relationship-graph.ts
|
|
1067
|
-
const DATA_DIR$
|
|
1079
|
+
const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1068
1080
|
function summarizeNode(n) {
|
|
1069
1081
|
return {
|
|
1070
1082
|
id: n.id,
|
|
@@ -1072,7 +1084,7 @@ function summarizeNode(n) {
|
|
|
1072
1084
|
email: n.properties["email"]
|
|
1073
1085
|
};
|
|
1074
1086
|
}
|
|
1075
|
-
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$
|
|
1087
|
+
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$40) {
|
|
1076
1088
|
try {
|
|
1077
1089
|
const graph = readGraph(dataDir, input.slug);
|
|
1078
1090
|
const stakeholders = getStakeholders(graph);
|
|
@@ -1140,9 +1152,9 @@ Returns: {
|
|
|
1140
1152
|
}
|
|
1141
1153
|
//#endregion
|
|
1142
1154
|
//#region src/mcp/tools/get-relationship-health.ts
|
|
1143
|
-
const DATA_DIR$
|
|
1155
|
+
const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1144
1156
|
const MAX_HEALTH_AGE_MS = 3600 * 1e3;
|
|
1145
|
-
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$
|
|
1157
|
+
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$39) {
|
|
1146
1158
|
try {
|
|
1147
1159
|
let health = readHealth(dataDir, input.slug);
|
|
1148
1160
|
if (health === null || Date.now() - new Date(health.updatedAt).getTime() > MAX_HEALTH_AGE_MS) {
|
|
@@ -1222,8 +1234,7 @@ async function writePlaybook(dataDir, slug, playbook) {
|
|
|
1222
1234
|
const filePath = path.join(dir, `${playbook.name}.md`);
|
|
1223
1235
|
await withFileQueue(filePath, async () => {
|
|
1224
1236
|
fs.mkdirSync(dir, { recursive: true });
|
|
1225
|
-
|
|
1226
|
-
fs.writeFileSync(filePath, raw, "utf-8");
|
|
1237
|
+
writeFileAtomic(filePath, matter.stringify(playbook.content, playbook.frontmatter));
|
|
1227
1238
|
});
|
|
1228
1239
|
}
|
|
1229
1240
|
function toKebabCase(name) {
|
|
@@ -1425,11 +1436,10 @@ function writeAgentQueue(dataDir, slug, queue) {
|
|
|
1425
1436
|
const p = agentQueuePath(dataDir, slug);
|
|
1426
1437
|
const dir = path.dirname(p);
|
|
1427
1438
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
1428
|
-
|
|
1439
|
+
writeJsonFile(p, {
|
|
1429
1440
|
...queue,
|
|
1430
1441
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1431
|
-
};
|
|
1432
|
-
fs.writeFileSync(p, JSON.stringify(updated, null, 2), "utf-8");
|
|
1442
|
+
});
|
|
1433
1443
|
}
|
|
1434
1444
|
function makeActionId() {
|
|
1435
1445
|
return `da_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -1464,17 +1474,9 @@ async function observeDeal(dataDir, slug, dealName, today) {
|
|
|
1464
1474
|
const deal = (await readPipeline(dataDir, slug).catch(() => [])).find((d) => d.name.toLowerCase() === dealName.toLowerCase());
|
|
1465
1475
|
if (!deal) return null;
|
|
1466
1476
|
const todayDate = new Date(today);
|
|
1467
|
-
const
|
|
1468
|
-
const
|
|
1469
|
-
const
|
|
1470
|
-
const daysToClose = deal.close_date && deal.close_date.trim() !== "" ? Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / 864e5) : void 0;
|
|
1471
|
-
const dealHealthScore = scoreDeal(deal, {
|
|
1472
|
-
daysSinceLastActivity,
|
|
1473
|
-
daysInCurrentStage,
|
|
1474
|
-
...daysToClose !== void 0 ? { daysToClose } : {},
|
|
1475
|
-
...deal.probability !== void 0 ? { probability: deal.probability } : {}
|
|
1476
|
-
});
|
|
1477
|
-
const health = computeCustomerHealth(dataDir, slug, today);
|
|
1477
|
+
const { daysSinceLastActivity, daysInCurrentStage, daysToClose } = deriveDealTiming(deal, todayDate);
|
|
1478
|
+
const dealHealthScore = scoreDealForToday(deal, todayDate);
|
|
1479
|
+
const health = readHealth(dataDir, slug) ?? computeCustomerHealth(dataDir, slug, today);
|
|
1478
1480
|
const atRiskContacts = health.contacts.filter((c) => c.riskFlags.length > 0).map((c) => c.email ?? c.contactId);
|
|
1479
1481
|
const coldContacts = health.contacts.filter((c) => c.trend === "cold").map((c) => c.email ?? c.contactId);
|
|
1480
1482
|
const stakeholders = getStakeholders(readGraph(dataDir, slug));
|
|
@@ -1702,7 +1704,7 @@ async function executeAction(action, dataDir) {
|
|
|
1702
1704
|
if (!slug) return "skipped";
|
|
1703
1705
|
switch (action.type) {
|
|
1704
1706
|
case "log_interaction": {
|
|
1705
|
-
const { appendInteraction } = await import("./interactions-writer-
|
|
1707
|
+
const { appendInteraction } = await import("./interactions-writer-RJB8SWf2.js");
|
|
1706
1708
|
await appendInteraction(dataDir, slug, {
|
|
1707
1709
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
1708
1710
|
type: action.payload["type"] ?? "Note",
|
|
@@ -1715,7 +1717,7 @@ async function executeAction(action, dataDir) {
|
|
|
1715
1717
|
return "executed";
|
|
1716
1718
|
}
|
|
1717
1719
|
case "schedule_meeting": {
|
|
1718
|
-
const { appendInteraction } = await import("./interactions-writer-
|
|
1720
|
+
const { appendInteraction } = await import("./interactions-writer-RJB8SWf2.js");
|
|
1719
1721
|
await appendInteraction(dataDir, slug, {
|
|
1720
1722
|
date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
1721
1723
|
type: "Note",
|
|
@@ -1728,7 +1730,7 @@ async function executeAction(action, dataDir) {
|
|
|
1728
1730
|
return "executed";
|
|
1729
1731
|
}
|
|
1730
1732
|
case "update_deal": {
|
|
1731
|
-
const { handleUpdateDeal } = await import("./update-deal-
|
|
1733
|
+
const { handleUpdateDeal } = await import("./update-deal-CWy1eLJI.js");
|
|
1732
1734
|
const payload = action.payload;
|
|
1733
1735
|
const validStage = VALID_STAGES.find((s) => s === payload.stage);
|
|
1734
1736
|
await handleUpdateDeal({
|
|
@@ -1821,8 +1823,8 @@ async function runDealAgent(config, dataDir, llmFn = callLlm) {
|
|
|
1821
1823
|
}
|
|
1822
1824
|
//#endregion
|
|
1823
1825
|
//#region src/mcp/tools/run-deal-agent.ts
|
|
1824
|
-
const DATA_DIR$
|
|
1825
|
-
async function handleRunDealAgent(input, dataDir = DATA_DIR$
|
|
1826
|
+
const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1827
|
+
async function handleRunDealAgent(input, dataDir = DATA_DIR$38) {
|
|
1826
1828
|
try {
|
|
1827
1829
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1828
1830
|
const result = await runDealAgent({
|
|
@@ -1889,8 +1891,8 @@ Returns: { assessment, riskLevel, plan[], actionsQueued[], actionsExecuted[], tr
|
|
|
1889
1891
|
}
|
|
1890
1892
|
//#endregion
|
|
1891
1893
|
//#region src/mcp/tools/approve-agent-action.ts
|
|
1892
|
-
const DATA_DIR$
|
|
1893
|
-
async function handleApproveAgentAction(input, dataDir = DATA_DIR$
|
|
1894
|
+
const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1895
|
+
async function handleApproveAgentAction(input, dataDir = DATA_DIR$37) {
|
|
1894
1896
|
try {
|
|
1895
1897
|
const queue = readAgentQueue(dataDir, input.slug);
|
|
1896
1898
|
const idx = queue.pendingActions.findIndex((a) => a.actionId === input.actionId);
|
|
@@ -1967,8 +1969,8 @@ Returns: { success, actionId, status }`,
|
|
|
1967
1969
|
}
|
|
1968
1970
|
//#endregion
|
|
1969
1971
|
//#region src/mcp/tools/simulate-revenue.ts
|
|
1970
|
-
const DATA_DIR$
|
|
1971
|
-
async function handleSimulateRevenue(input, dataDir = DATA_DIR$
|
|
1972
|
+
const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1973
|
+
async function handleSimulateRevenue(input, dataDir = DATA_DIR$36) {
|
|
1972
1974
|
try {
|
|
1973
1975
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1974
1976
|
const horizon = input.horizon ?? "quarter";
|
|
@@ -2026,8 +2028,8 @@ Returns: { forecast: { p10, p50, p90, expected, stdDev, atRiskRevenue, byCloseMo
|
|
|
2026
2028
|
}
|
|
2027
2029
|
//#endregion
|
|
2028
2030
|
//#region src/mcp/tools/get-playbook.ts
|
|
2029
|
-
const DATA_DIR$
|
|
2030
|
-
async function handleGetPlaybook(input, dataDir = DATA_DIR$
|
|
2031
|
+
const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2032
|
+
async function handleGetPlaybook(input, dataDir = DATA_DIR$35) {
|
|
2031
2033
|
try {
|
|
2032
2034
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
2033
2035
|
if (!(input.stage !== void 0 || input.value !== void 0 || input.healthScore !== void 0)) return { content: [{
|
|
@@ -2112,12 +2114,12 @@ Returns: { matches: [{ name, score, trigger, successRate, usedCount, content }],
|
|
|
2112
2114
|
...healthScore !== void 0 ? { healthScore } : {},
|
|
2113
2115
|
...daysSinceContact !== void 0 ? { daysSinceContact } : {},
|
|
2114
2116
|
...championPresent !== void 0 ? { championPresent } : {}
|
|
2115
|
-
}, DATA_DIR$
|
|
2117
|
+
}, DATA_DIR$35));
|
|
2116
2118
|
}
|
|
2117
2119
|
//#endregion
|
|
2118
2120
|
//#region src/mcp/tools/create-playbook.ts
|
|
2119
|
-
const DATA_DIR$
|
|
2120
|
-
async function handleCreatePlaybook(input, dataDir = DATA_DIR$
|
|
2121
|
+
const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2122
|
+
async function handleCreatePlaybook(input, dataDir = DATA_DIR$34) {
|
|
2121
2123
|
try {
|
|
2122
2124
|
const name = toKebabCase(input.name);
|
|
2123
2125
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -2190,12 +2192,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path } }`,
|
|
|
2190
2192
|
trigger,
|
|
2191
2193
|
content,
|
|
2192
2194
|
...successRate !== void 0 ? { successRate } : {}
|
|
2193
|
-
}, DATA_DIR$
|
|
2195
|
+
}, DATA_DIR$34));
|
|
2194
2196
|
}
|
|
2195
2197
|
//#endregion
|
|
2196
2198
|
//#region src/mcp/tools/list-playbooks.ts
|
|
2197
|
-
const DATA_DIR$
|
|
2198
|
-
async function handleListPlaybooks(input, dataDir = DATA_DIR$
|
|
2199
|
+
const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2200
|
+
async function handleListPlaybooks(input, dataDir = DATA_DIR$33) {
|
|
2199
2201
|
try {
|
|
2200
2202
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
2201
2203
|
return { content: [{
|
|
@@ -2234,12 +2236,12 @@ Args:
|
|
|
2234
2236
|
|
|
2235
2237
|
Returns: { playbooks: [{ name, trigger, successRate, usedCount, lastUpdated }], count, slug }`,
|
|
2236
2238
|
inputSchema: z.object({ slug: z.string().describe("Customer ID") })
|
|
2237
|
-
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$
|
|
2239
|
+
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$33));
|
|
2238
2240
|
}
|
|
2239
2241
|
//#endregion
|
|
2240
2242
|
//#region src/mcp/tools/distill-playbook.ts
|
|
2241
|
-
const DATA_DIR$
|
|
2242
|
-
async function handleDistillPlaybook(input, dataDir = DATA_DIR$
|
|
2243
|
+
const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2244
|
+
async function handleDistillPlaybook(input, dataDir = DATA_DIR$32, llmFn = callLlm) {
|
|
2243
2245
|
try {
|
|
2244
2246
|
const result = await distillPlaybook(dataDir, input.slug, input.dealName, input.outcome, llmFn);
|
|
2245
2247
|
if (!result.ok) {
|
|
@@ -2298,12 +2300,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path }, reason
|
|
|
2298
2300
|
slug,
|
|
2299
2301
|
dealName,
|
|
2300
2302
|
outcome
|
|
2301
|
-
}, DATA_DIR$
|
|
2303
|
+
}, DATA_DIR$32));
|
|
2302
2304
|
}
|
|
2303
2305
|
//#endregion
|
|
2304
2306
|
//#region src/mcp/tools/pursue-goal.ts
|
|
2305
|
-
const DATA_DIR$
|
|
2306
|
-
async function handlePursueGoal(input, dataDir = DATA_DIR$
|
|
2307
|
+
const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2308
|
+
async function handlePursueGoal(input, dataDir = DATA_DIR$31, options = {}) {
|
|
2307
2309
|
try {
|
|
2308
2310
|
enforceRbac(dataDir, "pursue_goal");
|
|
2309
2311
|
const goal = await pursueGoal(dataDir, {
|
|
@@ -2366,12 +2368,12 @@ Returns: { goalId, description, target, deadline, decomposition: { analysis, cur
|
|
|
2366
2368
|
goal,
|
|
2367
2369
|
deadline,
|
|
2368
2370
|
...context !== void 0 ? { context } : {}
|
|
2369
|
-
}, DATA_DIR$
|
|
2371
|
+
}, DATA_DIR$31));
|
|
2370
2372
|
}
|
|
2371
2373
|
//#endregion
|
|
2372
2374
|
//#region src/mcp/tools/get-goal-status.ts
|
|
2373
|
-
const DATA_DIR$
|
|
2374
|
-
async function handleGetGoalStatus(input, dataDir = DATA_DIR$
|
|
2375
|
+
const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2376
|
+
async function handleGetGoalStatus(input, dataDir = DATA_DIR$30) {
|
|
2375
2377
|
try {
|
|
2376
2378
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2377
2379
|
const allGoals = input.goalId ? readGoals(dataDir).filter((g) => g.id === input.goalId) : getActiveGoals(dataDir);
|
|
@@ -2430,17 +2432,17 @@ Args:
|
|
|
2430
2432
|
|
|
2431
2433
|
Returns: { goals: [{ id, description, target, progress, status, deadline, daysRemaining, subGoals }], activeCount, completedCount }`,
|
|
2432
2434
|
inputSchema: z.object({ goalId: z.string().optional().describe("Specific goal ID (omit for all active goals)") })
|
|
2433
|
-
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$
|
|
2435
|
+
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$30));
|
|
2434
2436
|
}
|
|
2435
2437
|
//#endregion
|
|
2436
2438
|
//#region src/mcp/tools/register-push-subscription.ts
|
|
2437
|
-
const DATA_DIR$
|
|
2439
|
+
const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2438
2440
|
const VALID_PROVIDERS = [
|
|
2439
2441
|
"gmail",
|
|
2440
2442
|
"microsoft-graph",
|
|
2441
2443
|
"slack"
|
|
2442
2444
|
];
|
|
2443
|
-
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$
|
|
2445
|
+
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$29) {
|
|
2444
2446
|
try {
|
|
2445
2447
|
if (!VALID_PROVIDERS.includes(input.provider)) return { content: [{
|
|
2446
2448
|
type: "text",
|
|
@@ -2526,12 +2528,12 @@ Returns: { subscriptionId, provider, slug, status, expiresAt, createdAt, warning
|
|
|
2526
2528
|
...microsoftResource !== void 0 ? { microsoftResource } : {},
|
|
2527
2529
|
...slackTeamId !== void 0 ? { slackTeamId } : {},
|
|
2528
2530
|
...slackChannelId !== void 0 ? { slackChannelId } : {}
|
|
2529
|
-
}, DATA_DIR$
|
|
2531
|
+
}, DATA_DIR$29));
|
|
2530
2532
|
}
|
|
2531
2533
|
//#endregion
|
|
2532
2534
|
//#region src/mcp/tools/get-push-status.ts
|
|
2533
|
-
const DATA_DIR$
|
|
2534
|
-
async function handleGetPushStatus(input, dataDir = DATA_DIR$
|
|
2535
|
+
const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2536
|
+
async function handleGetPushStatus(input, dataDir = DATA_DIR$28) {
|
|
2535
2537
|
try {
|
|
2536
2538
|
let subs = await readSubscriptions(dataDir);
|
|
2537
2539
|
if (input.slug) subs = subs.filter((s) => s.slug === input.slug);
|
|
@@ -2603,7 +2605,7 @@ Returns: { subscriptions: [{ id, provider, slug, status, expiresAt, expiresInHou
|
|
|
2603
2605
|
}, async ({ slug, provider }) => handleGetPushStatus({
|
|
2604
2606
|
...slug !== void 0 ? { slug } : {},
|
|
2605
2607
|
...provider !== void 0 ? { provider } : {}
|
|
2606
|
-
}, DATA_DIR$
|
|
2608
|
+
}, DATA_DIR$28));
|
|
2607
2609
|
}
|
|
2608
2610
|
//#endregion
|
|
2609
2611
|
//#region src/core/org-intelligence.ts
|
|
@@ -2669,8 +2671,8 @@ function deriveRecommendation(people, missingRoles) {
|
|
|
2669
2671
|
}
|
|
2670
2672
|
//#endregion
|
|
2671
2673
|
//#region src/mcp/tools/get-org-intelligence.ts
|
|
2672
|
-
const DATA_DIR$
|
|
2673
|
-
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$
|
|
2674
|
+
const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2675
|
+
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$27) {
|
|
2674
2676
|
try {
|
|
2675
2677
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2676
2678
|
const map = buildStakeholderMap(dataDir, input.slug, today, input.dealName);
|
|
@@ -2721,15 +2723,7 @@ async function buildDealRoom(dataDir, slug, dealName, today) {
|
|
|
2721
2723
|
});
|
|
2722
2724
|
const todayDate = new Date(today);
|
|
2723
2725
|
const dealHealth = pipelineDeals.filter((d) => d.stage !== "won" && d.stage !== "lost").map((deal) => {
|
|
2724
|
-
const
|
|
2725
|
-
const daysSinceLastActivity = Math.floor((todayDate.getTime() - updatedDate.getTime()) / 864e5);
|
|
2726
|
-
const daysToClose = deal.close_date ? Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / 864e5) : void 0;
|
|
2727
|
-
const scored = scoreDeal(deal, {
|
|
2728
|
-
daysSinceLastActivity,
|
|
2729
|
-
daysInCurrentStage: daysSinceLastActivity,
|
|
2730
|
-
...daysToClose !== void 0 ? { daysToClose } : {},
|
|
2731
|
-
...deal.probability !== void 0 ? { probability: deal.probability } : {}
|
|
2732
|
-
});
|
|
2726
|
+
const scored = scoreDealForToday(deal, todayDate);
|
|
2733
2727
|
return {
|
|
2734
2728
|
deal: deal.name,
|
|
2735
2729
|
stage: deal.stage,
|
|
@@ -2811,8 +2805,8 @@ function buildExecutiveSummary(slug, dealName, stakeholders, overallHealth, sim,
|
|
|
2811
2805
|
}
|
|
2812
2806
|
//#endregion
|
|
2813
2807
|
//#region src/mcp/tools/open-deal-room.ts
|
|
2814
|
-
const DATA_DIR$
|
|
2815
|
-
async function handleOpenDealRoom(input, dataDir = DATA_DIR$
|
|
2808
|
+
const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2809
|
+
async function handleOpenDealRoom(input, dataDir = DATA_DIR$26) {
|
|
2816
2810
|
try {
|
|
2817
2811
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2818
2812
|
const brief = await buildDealRoom(dataDir, input.slug, input.dealName, today);
|
|
@@ -2847,8 +2841,8 @@ Returns: { slug, dealName, generatedAt, stakeholders, relationshipHealth, dealHe
|
|
|
2847
2841
|
}
|
|
2848
2842
|
//#endregion
|
|
2849
2843
|
//#region src/mcp/tools/get-proactive-briefing.ts
|
|
2850
|
-
const DATA_DIR$
|
|
2851
|
-
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$
|
|
2844
|
+
const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2845
|
+
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$25) {
|
|
2852
2846
|
try {
|
|
2853
2847
|
const briefing = await buildDailyBriefing(dataDir, input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
|
|
2854
2848
|
return { content: [{
|
|
@@ -2876,15 +2870,15 @@ Returns: { date, generatedAt, urgent: string[], opportunities: string[], forecas
|
|
|
2876
2870
|
}
|
|
2877
2871
|
//#endregion
|
|
2878
2872
|
//#region src/mcp/tools/list-email-templates.ts
|
|
2879
|
-
const DATA_DIR$
|
|
2880
|
-
async function handleListEmailTemplates(input, dataDir = DATA_DIR$
|
|
2873
|
+
const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2874
|
+
async function handleListEmailTemplates(input, dataDir = DATA_DIR$24) {
|
|
2881
2875
|
const summary = listTemplates(dataDir, input.category ? { category: input.category } : {}).map(({ body: _body, ...meta }) => meta);
|
|
2882
2876
|
return { content: [{
|
|
2883
2877
|
type: "text",
|
|
2884
2878
|
text: JSON.stringify(summary, null, 2)
|
|
2885
2879
|
}] };
|
|
2886
2880
|
}
|
|
2887
|
-
function registerListEmailTemplates(server, dataDir = DATA_DIR$
|
|
2881
|
+
function registerListEmailTemplates(server, dataDir = DATA_DIR$24) {
|
|
2888
2882
|
server.registerTool("list_email_templates", {
|
|
2889
2883
|
description: "List available email templates. Optionally filter by category (e.g. 'outreach', 'followup', 'support').",
|
|
2890
2884
|
inputSchema: z.object({ category: z.string().optional().describe("Filter by category") })
|
|
@@ -2892,8 +2886,8 @@ function registerListEmailTemplates(server, dataDir = DATA_DIR$23) {
|
|
|
2892
2886
|
}
|
|
2893
2887
|
//#endregion
|
|
2894
2888
|
//#region src/mcp/tools/get-email-template.ts
|
|
2895
|
-
const DATA_DIR$
|
|
2896
|
-
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$
|
|
2889
|
+
const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2890
|
+
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$23) {
|
|
2897
2891
|
const tmpl = getTemplate(dataDir, input.id);
|
|
2898
2892
|
if (!tmpl) return { content: [{
|
|
2899
2893
|
type: "text",
|
|
@@ -2909,7 +2903,7 @@ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$22) {
|
|
|
2909
2903
|
}, null, 2)
|
|
2910
2904
|
}] };
|
|
2911
2905
|
}
|
|
2912
|
-
function registerGetEmailTemplate(server, dataDir = DATA_DIR$
|
|
2906
|
+
function registerGetEmailTemplate(server, dataDir = DATA_DIR$23) {
|
|
2913
2907
|
server.registerTool("get_email_template", {
|
|
2914
2908
|
description: "Get a specific email template by ID, including its body and detected variables.",
|
|
2915
2909
|
inputSchema: z.object({ id: z.string().describe("Template ID (e.g. 'enterprise-intro')") })
|
|
@@ -2917,8 +2911,8 @@ function registerGetEmailTemplate(server, dataDir = DATA_DIR$22) {
|
|
|
2917
2911
|
}
|
|
2918
2912
|
//#endregion
|
|
2919
2913
|
//#region src/mcp/tools/draft-email.ts
|
|
2920
|
-
const DATA_DIR$
|
|
2921
|
-
async function handleDraftEmail(input, dataDir = DATA_DIR$
|
|
2914
|
+
const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2915
|
+
async function handleDraftEmail(input, dataDir = DATA_DIR$22) {
|
|
2922
2916
|
const tmpl = getTemplate(dataDir, input.templateId);
|
|
2923
2917
|
if (!tmpl) return { content: [{
|
|
2924
2918
|
type: "text",
|
|
@@ -2932,17 +2926,17 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$21) {
|
|
|
2932
2926
|
const interpolatedBody = interpolate(tmpl.body, vars);
|
|
2933
2927
|
let effectiveTone = input.tone;
|
|
2934
2928
|
if (!effectiveTone) {
|
|
2935
|
-
const { resolveTone, toneInstruction } = await import("./tone-
|
|
2929
|
+
const { resolveTone, toneInstruction } = await import("./tone-C7bqK69y.js");
|
|
2936
2930
|
const instr = toneInstruction(resolveTone(dataDir, input.slug));
|
|
2937
2931
|
if (instr) effectiveTone = instr;
|
|
2938
2932
|
}
|
|
2939
2933
|
let body = interpolatedBody;
|
|
2940
2934
|
let polished = false;
|
|
2941
2935
|
if (effectiveTone) try {
|
|
2942
|
-
const { callLlm } = await import("./llm-
|
|
2936
|
+
const { callLlm } = await import("./llm-DSX1-wFu.js");
|
|
2943
2937
|
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}`);
|
|
2944
2938
|
if (refined && refined.trim()) {
|
|
2945
|
-
const { labelAiContent } = await import("./compliance-
|
|
2939
|
+
const { labelAiContent } = await import("./compliance-TqYQXhBj.js");
|
|
2946
2940
|
body = labelAiContent(refined.trim());
|
|
2947
2941
|
polished = true;
|
|
2948
2942
|
}
|
|
@@ -2962,7 +2956,7 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$21) {
|
|
|
2962
2956
|
}, null, 2)
|
|
2963
2957
|
}] };
|
|
2964
2958
|
}
|
|
2965
|
-
function registerDraftEmail(server, dataDir = DATA_DIR$
|
|
2959
|
+
function registerDraftEmail(server, dataDir = DATA_DIR$22) {
|
|
2966
2960
|
server.registerTool("draft_email", {
|
|
2967
2961
|
description: `Draft a personalized email for a customer using a stored template.
|
|
2968
2962
|
Variables are auto-filled from the customer's main_facts.md. Override any variable manually.
|
|
@@ -2984,8 +2978,8 @@ Returns: { subject, body, to, tone, polished, resolvedVariables } — does NOT s
|
|
|
2984
2978
|
}
|
|
2985
2979
|
//#endregion
|
|
2986
2980
|
//#region src/mcp/tools/enroll-in-sequence.ts
|
|
2987
|
-
const DATA_DIR$
|
|
2988
|
-
async function handleEnrollInSequence(input, dataDir = DATA_DIR$
|
|
2981
|
+
const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2982
|
+
async function handleEnrollInSequence(input, dataDir = DATA_DIR$21) {
|
|
2989
2983
|
const sequence = getSequence(dataDir, input.sequenceId);
|
|
2990
2984
|
if (!sequence) return { content: [{
|
|
2991
2985
|
type: "text",
|
|
@@ -3017,7 +3011,7 @@ async function handleEnrollInSequence(input, dataDir = DATA_DIR$20) {
|
|
|
3017
3011
|
})
|
|
3018
3012
|
}] };
|
|
3019
3013
|
}
|
|
3020
|
-
function registerEnrollInSequence(server, dataDir = DATA_DIR$
|
|
3014
|
+
function registerEnrollInSequence(server, dataDir = DATA_DIR$21) {
|
|
3021
3015
|
server.registerTool("enroll_in_sequence", {
|
|
3022
3016
|
description: `Enroll a contact in an email sequence. Validates that the sequence and its first template exist.
|
|
3023
3017
|
Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
@@ -3034,8 +3028,8 @@ Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
|
3034
3028
|
}
|
|
3035
3029
|
//#endregion
|
|
3036
3030
|
//#region src/mcp/tools/list-sequence-enrollments.ts
|
|
3037
|
-
const DATA_DIR$
|
|
3038
|
-
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$
|
|
3031
|
+
const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3032
|
+
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$20) {
|
|
3039
3033
|
let enrollments = readEnrollments(dataDir);
|
|
3040
3034
|
if (input.slug !== void 0) enrollments = enrollments.filter((e) => e.slug === input.slug);
|
|
3041
3035
|
if (input.status !== void 0) enrollments = enrollments.filter((e) => e.status === input.status);
|
|
@@ -3044,7 +3038,7 @@ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$19) {
|
|
|
3044
3038
|
text: JSON.stringify({ enrollments }, null, 2)
|
|
3045
3039
|
}] };
|
|
3046
3040
|
}
|
|
3047
|
-
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$
|
|
3041
|
+
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$20) {
|
|
3048
3042
|
server.registerTool("list_sequence_enrollments", {
|
|
3049
3043
|
description: `List email sequence enrollments. Filter by customer slug or status.
|
|
3050
3044
|
Returns: { enrollments: SequenceEnrollment[] }`,
|
|
@@ -3063,8 +3057,8 @@ Returns: { enrollments: SequenceEnrollment[] }`,
|
|
|
3063
3057
|
}
|
|
3064
3058
|
//#endregion
|
|
3065
3059
|
//#region src/mcp/tools/unenroll-from-sequence.ts
|
|
3066
|
-
const DATA_DIR$
|
|
3067
|
-
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$
|
|
3060
|
+
const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3061
|
+
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$19) {
|
|
3068
3062
|
if (!await updateEnrollment(dataDir, input.enrollmentId, { status: "paused" })) return { content: [{
|
|
3069
3063
|
type: "text",
|
|
3070
3064
|
text: JSON.stringify({
|
|
@@ -3077,7 +3071,7 @@ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$18) {
|
|
|
3077
3071
|
text: JSON.stringify({ success: true })
|
|
3078
3072
|
}] };
|
|
3079
3073
|
}
|
|
3080
|
-
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$
|
|
3074
|
+
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$19) {
|
|
3081
3075
|
server.registerTool("unenroll_from_sequence", {
|
|
3082
3076
|
description: `Unenroll (pause) a contact from an email sequence. Sets status to "paused" (soft delete).
|
|
3083
3077
|
Returns: { success: boolean }`,
|
|
@@ -3086,8 +3080,8 @@ Returns: { success: boolean }`,
|
|
|
3086
3080
|
}
|
|
3087
3081
|
//#endregion
|
|
3088
3082
|
//#region src/mcp/tools/list-sequences.ts
|
|
3089
|
-
const DATA_DIR$
|
|
3090
|
-
async function handleListSequences(_input, dataDir = DATA_DIR$
|
|
3083
|
+
const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3084
|
+
async function handleListSequences(_input, dataDir = DATA_DIR$18) {
|
|
3091
3085
|
const sequences = listSequences(dataDir);
|
|
3092
3086
|
const enrollments = readEnrollments(dataDir);
|
|
3093
3087
|
const result = sequences.map((seq) => ({
|
|
@@ -3101,7 +3095,7 @@ async function handleListSequences(_input, dataDir = DATA_DIR$17) {
|
|
|
3101
3095
|
text: JSON.stringify({ sequences: result }, null, 2)
|
|
3102
3096
|
}] };
|
|
3103
3097
|
}
|
|
3104
|
-
function registerListSequences(server, dataDir = DATA_DIR$
|
|
3098
|
+
function registerListSequences(server, dataDir = DATA_DIR$18) {
|
|
3105
3099
|
server.registerTool("list_sequences", {
|
|
3106
3100
|
description: `List all email sequences with step count and enrollment count.
|
|
3107
3101
|
Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
|
|
@@ -3110,8 +3104,8 @@ Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
|
|
|
3110
3104
|
}
|
|
3111
3105
|
//#endregion
|
|
3112
3106
|
//#region src/mcp/tools/generate-quote.ts
|
|
3113
|
-
const DATA_DIR$
|
|
3114
|
-
async function handleGenerateQuote(input, dataDir = DATA_DIR$
|
|
3107
|
+
const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3108
|
+
async function handleGenerateQuote(input, dataDir = DATA_DIR$17) {
|
|
3115
3109
|
try {
|
|
3116
3110
|
const quote = await generateQuote(dataDir, input);
|
|
3117
3111
|
return { content: [{
|
|
@@ -3135,7 +3129,7 @@ async function handleGenerateQuote(input, dataDir = DATA_DIR$16) {
|
|
|
3135
3129
|
}] };
|
|
3136
3130
|
}
|
|
3137
3131
|
}
|
|
3138
|
-
function registerGenerateQuote(server, dataDir = DATA_DIR$
|
|
3132
|
+
function registerGenerateQuote(server, dataDir = DATA_DIR$17) {
|
|
3139
3133
|
server.registerTool("generate_quote", {
|
|
3140
3134
|
description: `Generate a professional HTML quote/offer for a customer deal.
|
|
3141
3135
|
Calculates subtotal, VAT, and total. Saves JSON + HTML to .agentic/quotes/.
|
|
@@ -3163,8 +3157,8 @@ Returns: { quoteNumber, htmlPath, total, currency, validUntil }`,
|
|
|
3163
3157
|
}
|
|
3164
3158
|
//#endregion
|
|
3165
3159
|
//#region src/mcp/tools/get-quote-status.ts
|
|
3166
|
-
const DATA_DIR$
|
|
3167
|
-
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$
|
|
3160
|
+
const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3161
|
+
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$16) {
|
|
3168
3162
|
if (input.quoteNumber) {
|
|
3169
3163
|
const quote = readQuote(dataDir, input.quoteNumber);
|
|
3170
3164
|
if (!quote) return { content: [{
|
|
@@ -3182,7 +3176,7 @@ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$15) {
|
|
|
3182
3176
|
text: JSON.stringify({ quotes }, null, 2)
|
|
3183
3177
|
}] };
|
|
3184
3178
|
}
|
|
3185
|
-
function registerGetQuoteStatus(server, dataDir = DATA_DIR$
|
|
3179
|
+
function registerGetQuoteStatus(server, dataDir = DATA_DIR$16) {
|
|
3186
3180
|
server.registerTool("get_quote_status", {
|
|
3187
3181
|
description: `Get quote status and details. Filter by quoteNumber (single quote) or slug (all quotes for a customer).
|
|
3188
3182
|
Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
@@ -3197,7 +3191,7 @@ Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
|
3197
3191
|
}
|
|
3198
3192
|
//#endregion
|
|
3199
3193
|
//#region src/mcp/tools/get-booking-link.ts
|
|
3200
|
-
const DATA_DIR$
|
|
3194
|
+
const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3201
3195
|
function loadCalendlyConfig(dataDir) {
|
|
3202
3196
|
const p = path.join(dataDir, ".agentic", "integrations", "calendly.yaml");
|
|
3203
3197
|
if (!fs.existsSync(p)) return {};
|
|
@@ -3220,7 +3214,7 @@ function readCustomerFacts(dataDir, slug) {
|
|
|
3220
3214
|
...email ? { email } : {}
|
|
3221
3215
|
};
|
|
3222
3216
|
}
|
|
3223
|
-
async function handleGetBookingLink(input, dataDir = DATA_DIR$
|
|
3217
|
+
async function handleGetBookingLink(input, dataDir = DATA_DIR$15) {
|
|
3224
3218
|
const config = loadCalendlyConfig(dataDir);
|
|
3225
3219
|
const apiKey = config.apiKey ?? process.env["CALENDLY_API_KEY"] ?? "";
|
|
3226
3220
|
if (!apiKey) return { content: [{
|
|
@@ -3248,7 +3242,7 @@ async function handleGetBookingLink(input, dataDir = DATA_DIR$14) {
|
|
|
3248
3242
|
}] };
|
|
3249
3243
|
}
|
|
3250
3244
|
}
|
|
3251
|
-
function registerGetBookingLink(server, dataDir = DATA_DIR$
|
|
3245
|
+
function registerGetBookingLink(server, dataDir = DATA_DIR$15) {
|
|
3252
3246
|
server.registerTool("get_booking_link", {
|
|
3253
3247
|
description: `Get a Calendly booking link for a customer. Optionally pre-fills the customer's name/email.
|
|
3254
3248
|
Requires CALENDLY_API_KEY env var or .agentic/integrations/calendly.yaml config.
|
|
@@ -3266,8 +3260,8 @@ Returns: { bookingUrl, eventType, duration }`,
|
|
|
3266
3260
|
}
|
|
3267
3261
|
//#endregion
|
|
3268
3262
|
//#region src/mcp/tools/create-ticket.ts
|
|
3269
|
-
const DATA_DIR$
|
|
3270
|
-
async function handleCreateTicket(input, dataDir = DATA_DIR$
|
|
3263
|
+
const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3264
|
+
async function handleCreateTicket(input, dataDir = DATA_DIR$14) {
|
|
3271
3265
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3272
3266
|
const rules = loadSlaRules(dataDir);
|
|
3273
3267
|
const priority = input.priority ?? "normal";
|
|
@@ -3289,7 +3283,7 @@ async function handleCreateTicket(input, dataDir = DATA_DIR$13) {
|
|
|
3289
3283
|
text: JSON.stringify({ ticket }, null, 2)
|
|
3290
3284
|
}] };
|
|
3291
3285
|
}
|
|
3292
|
-
function registerCreateTicket(server, dataDir = DATA_DIR$
|
|
3286
|
+
function registerCreateTicket(server, dataDir = DATA_DIR$14) {
|
|
3293
3287
|
server.registerTool("create_ticket", {
|
|
3294
3288
|
description: `Create a support ticket for a customer. Auto-calculates SLA due date based on priority.
|
|
3295
3289
|
Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
@@ -3315,8 +3309,8 @@ Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
|
3315
3309
|
}
|
|
3316
3310
|
//#endregion
|
|
3317
3311
|
//#region src/mcp/tools/update-ticket.ts
|
|
3318
|
-
const DATA_DIR$
|
|
3319
|
-
async function handleUpdateTicket(input, dataDir = DATA_DIR$
|
|
3312
|
+
const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3313
|
+
async function handleUpdateTicket(input, dataDir = DATA_DIR$13) {
|
|
3320
3314
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
3321
3315
|
if (!ticket) return { content: [{
|
|
3322
3316
|
type: "text",
|
|
@@ -3335,7 +3329,7 @@ async function handleUpdateTicket(input, dataDir = DATA_DIR$12) {
|
|
|
3335
3329
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
3336
3330
|
}] };
|
|
3337
3331
|
}
|
|
3338
|
-
function registerUpdateTicket(server, dataDir = DATA_DIR$
|
|
3332
|
+
function registerUpdateTicket(server, dataDir = DATA_DIR$13) {
|
|
3339
3333
|
server.registerTool("update_ticket", {
|
|
3340
3334
|
description: `Update a ticket's status or assignee. Setting status=resolved auto-sets resolved date.
|
|
3341
3335
|
Returns: { ticket }`,
|
|
@@ -3360,8 +3354,8 @@ Returns: { ticket }`,
|
|
|
3360
3354
|
}
|
|
3361
3355
|
//#endregion
|
|
3362
3356
|
//#region src/mcp/tools/list-tickets.ts
|
|
3363
|
-
const DATA_DIR$
|
|
3364
|
-
async function handleListTickets(input, dataDir = DATA_DIR$
|
|
3357
|
+
const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3358
|
+
async function handleListTickets(input, dataDir = DATA_DIR$12) {
|
|
3365
3359
|
const results = await listAllTickets(dataDir, {
|
|
3366
3360
|
...input.slug !== void 0 ? { slug: input.slug } : {},
|
|
3367
3361
|
...input.status !== void 0 ? { status: input.status } : {},
|
|
@@ -3373,7 +3367,7 @@ async function handleListTickets(input, dataDir = DATA_DIR$11) {
|
|
|
3373
3367
|
text: JSON.stringify({ tickets: results }, null, 2)
|
|
3374
3368
|
}] };
|
|
3375
3369
|
}
|
|
3376
|
-
function registerListTickets(server, dataDir = DATA_DIR$
|
|
3370
|
+
function registerListTickets(server, dataDir = DATA_DIR$12) {
|
|
3377
3371
|
server.registerTool("list_tickets", {
|
|
3378
3372
|
description: `List support tickets. Filter by customer, status, priority, or assignee. Sorted by priority then date.
|
|
3379
3373
|
Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
@@ -3403,8 +3397,8 @@ Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
|
3403
3397
|
}
|
|
3404
3398
|
//#endregion
|
|
3405
3399
|
//#region src/mcp/tools/close-ticket.ts
|
|
3406
|
-
const DATA_DIR$
|
|
3407
|
-
async function handleCloseTicket(input, dataDir = DATA_DIR$
|
|
3400
|
+
const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3401
|
+
async function handleCloseTicket(input, dataDir = DATA_DIR$11) {
|
|
3408
3402
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
3409
3403
|
if (!ticket) return { content: [{
|
|
3410
3404
|
type: "text",
|
|
@@ -3431,7 +3425,7 @@ async function handleCloseTicket(input, dataDir = DATA_DIR$10) {
|
|
|
3431
3425
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
3432
3426
|
}] };
|
|
3433
3427
|
}
|
|
3434
|
-
function registerCloseTicket(server, dataDir = DATA_DIR$
|
|
3428
|
+
function registerCloseTicket(server, dataDir = DATA_DIR$11) {
|
|
3435
3429
|
server.registerTool("close_ticket", {
|
|
3436
3430
|
description: `Close a support ticket. Optionally logs the resolution as an interaction.
|
|
3437
3431
|
Returns: { ticket } with status=closed`,
|
|
@@ -3448,8 +3442,8 @@ Returns: { ticket } with status=closed`,
|
|
|
3448
3442
|
}
|
|
3449
3443
|
//#endregion
|
|
3450
3444
|
//#region src/mcp/tools/send-nps-survey.ts
|
|
3451
|
-
const DATA_DIR$
|
|
3452
|
-
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$
|
|
3445
|
+
const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3446
|
+
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$10) {
|
|
3453
3447
|
const survey = getSurvey(dataDir, input.surveyId);
|
|
3454
3448
|
if (!survey) return { content: [{
|
|
3455
3449
|
type: "text",
|
|
@@ -3470,7 +3464,7 @@ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$9) {
|
|
|
3470
3464
|
}, null, 2)
|
|
3471
3465
|
}] };
|
|
3472
3466
|
}
|
|
3473
|
-
function registerSendNpsSurvey(server, dataDir = DATA_DIR$
|
|
3467
|
+
function registerSendNpsSurvey(server, dataDir = DATA_DIR$10) {
|
|
3474
3468
|
server.registerTool("send_nps_survey", {
|
|
3475
3469
|
description: `Generate an NPS/CSAT survey email for a customer contact. Returns subject, HTML body, and a token-based response URL.
|
|
3476
3470
|
Does NOT send automatically — returns draft for review.
|
|
@@ -3490,8 +3484,8 @@ Returns: { token, subject, body, surveyUrl }`,
|
|
|
3490
3484
|
}
|
|
3491
3485
|
//#endregion
|
|
3492
3486
|
//#region src/mcp/tools/get-survey-results.ts
|
|
3493
|
-
const DATA_DIR$
|
|
3494
|
-
async function handleGetSurveyResults(input, dataDir = DATA_DIR$
|
|
3487
|
+
const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3488
|
+
async function handleGetSurveyResults(input, dataDir = DATA_DIR$9) {
|
|
3495
3489
|
const responses = loadSurveyResponses(dataDir, input.surveyId, input.slug);
|
|
3496
3490
|
const nps = calcNpsScore(responses);
|
|
3497
3491
|
const promoters = responses.filter((r) => r.score >= 9).length;
|
|
@@ -3517,7 +3511,7 @@ async function handleGetSurveyResults(input, dataDir = DATA_DIR$8) {
|
|
|
3517
3511
|
}, null, 2)
|
|
3518
3512
|
}] };
|
|
3519
3513
|
}
|
|
3520
|
-
function registerGetSurveyResults(server, dataDir = DATA_DIR$
|
|
3514
|
+
function registerGetSurveyResults(server, dataDir = DATA_DIR$9) {
|
|
3521
3515
|
server.registerTool("get_survey_results", {
|
|
3522
3516
|
description: `Get NPS/CSAT survey results with score breakdown. Calculates Net Promoter Score.
|
|
3523
3517
|
Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[] }`,
|
|
@@ -3532,8 +3526,8 @@ Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[
|
|
|
3532
3526
|
}
|
|
3533
3527
|
//#endregion
|
|
3534
3528
|
//#region src/mcp/tools/search-knowledge-base.ts
|
|
3535
|
-
const DATA_DIR$
|
|
3536
|
-
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$
|
|
3529
|
+
const DATA_DIR$8 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3530
|
+
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$8) {
|
|
3537
3531
|
const results = searchKbSimple(dataDir, input.query, { ...input.publicOnly ? { publicOnly: true } : {} });
|
|
3538
3532
|
const limited = (input.category ? results.filter((a) => a.category === input.category) : results).slice(0, input.limit ?? 10);
|
|
3539
3533
|
return { content: [{
|
|
@@ -3548,7 +3542,7 @@ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$7) {
|
|
|
3548
3542
|
}, null, 2)
|
|
3549
3543
|
}] };
|
|
3550
3544
|
}
|
|
3551
|
-
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$
|
|
3545
|
+
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$8) {
|
|
3552
3546
|
server.registerTool("search_knowledge_base", {
|
|
3553
3547
|
description: `Search the knowledge base for articles. Text search on title, body, and tags.
|
|
3554
3548
|
Returns: { count, articles[] } with excerpts`,
|
|
@@ -3567,8 +3561,8 @@ Returns: { count, articles[] } with excerpts`,
|
|
|
3567
3561
|
}
|
|
3568
3562
|
//#endregion
|
|
3569
3563
|
//#region src/mcp/tools/create-kb-article.ts
|
|
3570
|
-
const DATA_DIR$
|
|
3571
|
-
async function handleCreateKbArticle(input, dataDir = DATA_DIR$
|
|
3564
|
+
const DATA_DIR$7 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3565
|
+
async function handleCreateKbArticle(input, dataDir = DATA_DIR$7) {
|
|
3572
3566
|
if (getKbArticle(dataDir, input.id)) return { content: [{
|
|
3573
3567
|
type: "text",
|
|
3574
3568
|
text: JSON.stringify({ error: `Article '${input.id}' already exists` })
|
|
@@ -3596,7 +3590,7 @@ async function handleCreateKbArticle(input, dataDir = DATA_DIR$6) {
|
|
|
3596
3590
|
}, null, 2)
|
|
3597
3591
|
}] };
|
|
3598
3592
|
}
|
|
3599
|
-
function registerCreateKbArticle(server, dataDir = DATA_DIR$
|
|
3593
|
+
function registerCreateKbArticle(server, dataDir = DATA_DIR$7) {
|
|
3600
3594
|
server.registerTool("create_kb_article", {
|
|
3601
3595
|
description: `Create a new knowledge base article. Articles are stored as Markdown files in .agentic/knowledge-base/.
|
|
3602
3596
|
Returns: { id, title, category, path }`,
|
|
@@ -3621,8 +3615,8 @@ Returns: { id, title, category, path }`,
|
|
|
3621
3615
|
}
|
|
3622
3616
|
//#endregion
|
|
3623
3617
|
//#region src/mcp/tools/backup-now.ts
|
|
3624
|
-
const DATA_DIR$
|
|
3625
|
-
async function handleBackupNow(input, dataDir = DATA_DIR$
|
|
3618
|
+
const DATA_DIR$6 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3619
|
+
async function handleBackupNow(input, dataDir = DATA_DIR$6) {
|
|
3626
3620
|
const zipPath = path.join(dataDir, `dxcrm-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.zip`);
|
|
3627
3621
|
const manifest = await runBackup(zipPath, dataDir, { ...input.remote ? { remote: input.remote } : {} }).catch(() => null);
|
|
3628
3622
|
if (!manifest) return { content: [{
|
|
@@ -3659,8 +3653,8 @@ function registerBackupNow(server) {
|
|
|
3659
3653
|
}
|
|
3660
3654
|
//#endregion
|
|
3661
3655
|
//#region src/mcp/tools/list-backups.ts
|
|
3662
|
-
const DATA_DIR$
|
|
3663
|
-
async function handleListBackups(input, dataDir = DATA_DIR$
|
|
3656
|
+
const DATA_DIR$5 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3657
|
+
async function handleListBackups(input, dataDir = DATA_DIR$5) {
|
|
3664
3658
|
const logEntries = readBackupLog(dataDir);
|
|
3665
3659
|
const fileEntries = listBackupsInDir(dataDir);
|
|
3666
3660
|
const entries = logEntries.length > 0 ? logEntries : fileEntries;
|
|
@@ -3694,8 +3688,8 @@ function registerListBackups(server) {
|
|
|
3694
3688
|
}
|
|
3695
3689
|
//#endregion
|
|
3696
3690
|
//#region src/mcp/tools/trigger-sync.ts
|
|
3697
|
-
const DATA_DIR$
|
|
3698
|
-
async function handleTriggerSync(input, dataDir = DATA_DIR$
|
|
3691
|
+
const DATA_DIR$4 = process.cwd();
|
|
3692
|
+
async function handleTriggerSync(input, dataDir = DATA_DIR$4) {
|
|
3699
3693
|
const auth = getGmailAuth();
|
|
3700
3694
|
if (!auth) return { content: [{
|
|
3701
3695
|
type: "text",
|
|
@@ -3730,7 +3724,7 @@ async function handleTriggerSync(input, dataDir = DATA_DIR$3) {
|
|
|
3730
3724
|
try {
|
|
3731
3725
|
const sources = JSON.parse(fs.readFileSync(sourcesPath, "utf-8"));
|
|
3732
3726
|
if (!sources.gmail?.enabled || !sources.gmail.query) continue;
|
|
3733
|
-
const { syncGmail } = await import("./gmail-sync-
|
|
3727
|
+
const { syncGmail } = await import("./gmail-sync-DueE6tl5.js");
|
|
3734
3728
|
const result = await syncGmail({
|
|
3735
3729
|
slug,
|
|
3736
3730
|
dataDir,
|
|
@@ -3789,8 +3783,8 @@ Returns: { success: boolean, synced: number, skipped: number, customers: [...],
|
|
|
3789
3783
|
}
|
|
3790
3784
|
//#endregion
|
|
3791
3785
|
//#region src/mcp/tools/get-audit-log.ts
|
|
3792
|
-
const DATA_DIR$
|
|
3793
|
-
async function handleGetAuditLog(input, dataDir = DATA_DIR$
|
|
3786
|
+
const DATA_DIR$3 = process.cwd();
|
|
3787
|
+
async function handleGetAuditLog(input, dataDir = DATA_DIR$3) {
|
|
3794
3788
|
const entries = readAuditLog(dataDir);
|
|
3795
3789
|
const filterOpts = { limit: input.limit ?? 50 };
|
|
3796
3790
|
if (input.slug !== void 0) filterOpts.slug = input.slug;
|
|
@@ -3831,6 +3825,69 @@ Returns: { total: number, returned: number, entries: [{timestamp, actor, tool, s
|
|
|
3831
3825
|
});
|
|
3832
3826
|
}
|
|
3833
3827
|
//#endregion
|
|
3828
|
+
//#region src/mcp/tools/get-logs.ts
|
|
3829
|
+
const DATA_DIR$2 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3830
|
+
async function handleGetLogs(input, dataDir = DATA_DIR$2) {
|
|
3831
|
+
const query = {
|
|
3832
|
+
...input.level !== void 0 ? { level: input.level } : {},
|
|
3833
|
+
...input.component !== void 0 ? { component: input.component } : {},
|
|
3834
|
+
...input.since !== void 0 ? { since: input.since } : {},
|
|
3835
|
+
...input.contains !== void 0 ? { contains: input.contains } : {},
|
|
3836
|
+
limit: input.limit ?? 100
|
|
3837
|
+
};
|
|
3838
|
+
const payload = input.summary ? summarizeLogs(dataDir, query) : (() => {
|
|
3839
|
+
const entries = queryLogs(dataDir, query);
|
|
3840
|
+
return {
|
|
3841
|
+
returned: entries.length,
|
|
3842
|
+
entries
|
|
3843
|
+
};
|
|
3844
|
+
})();
|
|
3845
|
+
return { content: [{
|
|
3846
|
+
type: "text",
|
|
3847
|
+
text: JSON.stringify(payload, null, 2)
|
|
3848
|
+
}] };
|
|
3849
|
+
}
|
|
3850
|
+
function registerGetLogs(server) {
|
|
3851
|
+
server.registerTool("get_logs", {
|
|
3852
|
+
title: "Get Logs",
|
|
3853
|
+
description: `Read and analyze the structured application log (.agentic/logs.ndjson).
|
|
3854
|
+
Use to answer "what went wrong recently?", "show errors from gmail sync", or "summarize today's activity".
|
|
3855
|
+
|
|
3856
|
+
Args:
|
|
3857
|
+
level: Minimum level to include — debug | info | warn | error (optional)
|
|
3858
|
+
component: Filter by component, e.g. "gmail-sync", "lancedb" (optional)
|
|
3859
|
+
since: ISO timestamp; only entries at or after it (optional)
|
|
3860
|
+
contains: Case-insensitive substring of the message (optional)
|
|
3861
|
+
limit: Max entries to return (default 100, most recent)
|
|
3862
|
+
summary: When true, return aggregated counts (by level + component) and recent errors instead of raw entries
|
|
3863
|
+
|
|
3864
|
+
Returns (entries): { returned: number, entries: [{ts, level, component, message, context?}] }
|
|
3865
|
+
Returns (summary): { total, byLevel, byComponent, firstTs, lastTs, recentErrors }`,
|
|
3866
|
+
inputSchema: z.object({
|
|
3867
|
+
level: z.enum([
|
|
3868
|
+
"debug",
|
|
3869
|
+
"info",
|
|
3870
|
+
"warn",
|
|
3871
|
+
"error"
|
|
3872
|
+
]).optional().describe("Minimum level"),
|
|
3873
|
+
component: z.string().optional().describe("Filter by component"),
|
|
3874
|
+
since: z.string().optional().describe("ISO timestamp lower bound"),
|
|
3875
|
+
contains: z.string().optional().describe("Message substring filter"),
|
|
3876
|
+
limit: z.number().int().min(1).max(1e3).optional().describe("Max entries (default 100)"),
|
|
3877
|
+
summary: z.boolean().optional().describe("Return aggregated summary instead of entries")
|
|
3878
|
+
})
|
|
3879
|
+
}, async ({ level, component, since, contains, limit, summary }) => {
|
|
3880
|
+
const input = {};
|
|
3881
|
+
if (level !== void 0) input.level = level;
|
|
3882
|
+
if (component !== void 0) input.component = component;
|
|
3883
|
+
if (since !== void 0) input.since = since;
|
|
3884
|
+
if (contains !== void 0) input.contains = contains;
|
|
3885
|
+
if (limit !== void 0) input.limit = limit;
|
|
3886
|
+
if (summary !== void 0) input.summary = summary;
|
|
3887
|
+
return handleGetLogs(input);
|
|
3888
|
+
});
|
|
3889
|
+
}
|
|
3890
|
+
//#endregion
|
|
3834
3891
|
//#region src/mcp/prompts.ts
|
|
3835
3892
|
/**
|
|
3836
3893
|
* CRM playbook prompts exposed via MCP `prompts/list` + `prompts/get`.
|
|
@@ -3899,7 +3956,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
|
|
|
3899
3956
|
description: "LLM-ready briefing (main facts, recent interactions, pipeline) for a customer",
|
|
3900
3957
|
mimeType: "text/markdown"
|
|
3901
3958
|
}, async (uri, variables) => {
|
|
3902
|
-
const { buildContext } = await import("./context-builder-
|
|
3959
|
+
const { buildContext } = await import("./context-builder-hmOPvgso.js");
|
|
3903
3960
|
const text = await buildContext(dataDir, String(variables["slug"]));
|
|
3904
3961
|
return { contents: [{
|
|
3905
3962
|
uri: uri.href,
|
|
@@ -3912,7 +3969,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
|
|
|
3912
3969
|
description: "Open and closed deals for a customer",
|
|
3913
3970
|
mimeType: "application/json"
|
|
3914
3971
|
}, async (uri, variables) => {
|
|
3915
|
-
const { readPipeline } = await import("./pipeline-writer-
|
|
3972
|
+
const { readPipeline } = await import("./pipeline-writer-0LJ6Qkat.js");
|
|
3916
3973
|
const deals = await readPipeline(dataDir, String(variables["slug"]));
|
|
3917
3974
|
return { contents: [{
|
|
3918
3975
|
uri: uri.href,
|
|
@@ -3925,7 +3982,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
|
|
|
3925
3982
|
description: "Newest-first interaction history for a customer",
|
|
3926
3983
|
mimeType: "text/markdown"
|
|
3927
3984
|
}, async (uri, variables) => {
|
|
3928
|
-
const { readInteractions } = await import("./interactions-writer-
|
|
3985
|
+
const { readInteractions } = await import("./interactions-writer-RJB8SWf2.js");
|
|
3929
3986
|
const text = await readInteractions(dataDir, String(variables["slug"]));
|
|
3930
3987
|
return { contents: [{
|
|
3931
3988
|
uri: uri.href,
|
|
@@ -3966,7 +4023,7 @@ function handleCreateRecord(input, dataDir = DATA_DIR) {
|
|
|
3966
4023
|
enforceRbac(dataDir, "create_record");
|
|
3967
4024
|
const res = createRecord(dataDir, input.object, input.values);
|
|
3968
4025
|
if (!res.ok) return json({ error: (res.errors ?? []).join("; ") });
|
|
3969
|
-
import("./webhooks-
|
|
4026
|
+
import("./webhooks-DXr1IoKn.js").then(({ emitEvent }) => emitEvent(dataDir, "record.created", {
|
|
3970
4027
|
object: input.object,
|
|
3971
4028
|
record: res.record
|
|
3972
4029
|
}));
|
|
@@ -4086,6 +4143,7 @@ function createMcpServer() {
|
|
|
4086
4143
|
registerListBackups(server);
|
|
4087
4144
|
registerTriggerSync(server);
|
|
4088
4145
|
registerGetAuditLog(server);
|
|
4146
|
+
registerGetLogs(server);
|
|
4089
4147
|
registerCustomObjectTools(server);
|
|
4090
4148
|
registerPrompts(server);
|
|
4091
4149
|
registerResources(server);
|
|
@@ -4096,7 +4154,7 @@ async function startStdio() {
|
|
|
4096
4154
|
const server = createMcpServer();
|
|
4097
4155
|
const transport = new StdioServerTransport();
|
|
4098
4156
|
await server.connect(transport);
|
|
4099
|
-
|
|
4157
|
+
logger.info("mcp-server", "running via stdio");
|
|
4100
4158
|
}
|
|
4101
4159
|
async function startHttp(port = 3847) {
|
|
4102
4160
|
await initOAuthFromDisk(process.cwd());
|
|
@@ -4136,7 +4194,7 @@ async function startHttp(port = 3847) {
|
|
|
4136
4194
|
});
|
|
4137
4195
|
app.get("/sessions", async (_req, res) => {
|
|
4138
4196
|
try {
|
|
4139
|
-
const { readAllSessions } = await import("./session-
|
|
4197
|
+
const { readAllSessions } = await import("./session-Bp4zTh4l.js");
|
|
4140
4198
|
const sessions = readAllSessions(dataDir);
|
|
4141
4199
|
res.json({ sessions });
|
|
4142
4200
|
} catch {
|
|
@@ -4248,7 +4306,7 @@ button{margin-top:12px;padding:12px 28px;background:#1a1a2e;color:#fff;border:no
|
|
|
4248
4306
|
res.status(400).send("<h2>Invalid score. Please use the link from your email.</h2>");
|
|
4249
4307
|
return;
|
|
4250
4308
|
}
|
|
4251
|
-
const { recordSurveyResponse } = await import("./survey-engine-
|
|
4309
|
+
const { recordSurveyResponse } = await import("./survey-engine-DKctGcLQ.js");
|
|
4252
4310
|
await recordSurveyResponse(dataDir, token, numScore).catch(() => null);
|
|
4253
4311
|
res.setHeader("content-type", "text/html");
|
|
4254
4312
|
res.send(surveyThankYouPage(numScore));
|
|
@@ -4264,24 +4322,24 @@ button{margin-top:12px;padding:12px 28px;background:#1a1a2e;color:#fff;border:no
|
|
|
4264
4322
|
res.status(400).send("<h2>Invalid score. Please go back and enter a number between 0 and 10.</h2>");
|
|
4265
4323
|
return;
|
|
4266
4324
|
}
|
|
4267
|
-
const { recordSurveyResponse } = await import("./survey-engine-
|
|
4325
|
+
const { recordSurveyResponse } = await import("./survey-engine-DKctGcLQ.js");
|
|
4268
4326
|
await recordSurveyResponse(dataDir, token, numScore, commentText || void 0).catch(() => null);
|
|
4269
4327
|
res.setHeader("content-type", "text/html");
|
|
4270
4328
|
res.send(surveyThankYouPage(numScore, commentText));
|
|
4271
4329
|
});
|
|
4272
4330
|
app.listen(port, () => {
|
|
4273
|
-
|
|
4331
|
+
logger.info("mcp-server", "running over http", { url: `http://0.0.0.0:${port}/mcp` });
|
|
4274
4332
|
});
|
|
4275
4333
|
}
|
|
4276
4334
|
if ((process.env["DXCRM_MCP_MODE"] ?? "stdio") === "http") startHttp(parseInt(process.env["DXCRM_MCP_PORT"] ?? "3847", 10)).catch((err) => {
|
|
4277
|
-
|
|
4335
|
+
logger.error("mcp-server", "fatal error", { error: err.message });
|
|
4278
4336
|
process.exit(1);
|
|
4279
4337
|
});
|
|
4280
4338
|
else startStdio().catch((err) => {
|
|
4281
|
-
|
|
4339
|
+
logger.error("mcp-server", "fatal error", { error: err.message });
|
|
4282
4340
|
process.exit(1);
|
|
4283
4341
|
});
|
|
4284
4342
|
//#endregion
|
|
4285
4343
|
export { startHttp, startStdio };
|
|
4286
4344
|
|
|
4287
|
-
//# sourceMappingURL=server-
|
|
4345
|
+
//# sourceMappingURL=server-DqSMYhSA.js.map
|