@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/cli.js
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as readMainFacts, i as listCustomerSlugs, o as writeMainFacts, r as ensureCustomerDir, s as MainFactsSchema } from "./customer-dir-CkMMXhb0.js";
|
|
3
|
+
import { t as writeFileAtomic } from "./atomic-write-8yjqqLtS.js";
|
|
4
|
+
import { i as writeJsonFile } from "./json-store-WWsFzXub.js";
|
|
3
5
|
import { a as warning, i as success, n as error, r as info, t as bold } from "./colors-BG07TZQz.js";
|
|
4
6
|
import { n as getSession } from "./session-store-CEa39Dxs.js";
|
|
5
|
-
import { i as sessionCommand, r as readAllSessions } from "./session-
|
|
6
|
-
import { a as searchKbSimple, i as listKbArticles, n as getKbArticle, o as writeKbArticle, s as CAPABILITIES_TEXT, t as deleteKbArticle } from "./knowledge-base
|
|
7
|
-
import { a as restoreCommand, t as backupCommand } from "./backup-
|
|
8
|
-
import { n as readSyncState } from "./sync-state-
|
|
9
|
-
import { n as readUnmatched } from "./unmatched-transcripts-
|
|
7
|
+
import { i as sessionCommand, r as readAllSessions } from "./session-BgGDyP2C.js";
|
|
8
|
+
import { a as searchKbSimple, i as listKbArticles, n as getKbArticle, o as writeKbArticle, s as CAPABILITIES_TEXT, t as deleteKbArticle } from "./knowledge-base--063Kpa3.js";
|
|
9
|
+
import { a as restoreCommand, t as backupCommand } from "./backup-CTlIxUdO.js";
|
|
10
|
+
import { n as readSyncState } from "./sync-state-DMZgzpez.js";
|
|
11
|
+
import { n as readUnmatched } from "./unmatched-transcripts-DC-VQ9YS.js";
|
|
10
12
|
import { t as AgentConfigSchema } from "./agent-config-zPvcqu07.js";
|
|
11
|
-
import {
|
|
13
|
+
import { n as appendInteraction, t as InteractionDedup } from "./interactions-writer-B8XAzdqR.js";
|
|
12
14
|
import { i as writeAuditEntry, n as getActor, r as readAuditLog, t as filterAuditLog } from "./audit-log-DNMY9mUZ.js";
|
|
13
|
-
import {
|
|
14
|
-
import { t as withJsonFile } from "./file-lock-
|
|
15
|
-
import { d as deletePipelineStage, f as getPipelineStages, m as setPipelineStage, p as resetToDefaults } from "./revenue-simulation-
|
|
16
|
-
import { d as pursueGoal, h as updateGoalProgress, i as getActiveGoals, n as cancelGoal } from "./goal-engine-
|
|
17
|
-
import { a as revoke, i as renewExpiringSubscriptions, n as readSubscriptions, r as register } from "./push-manager-
|
|
18
|
-
import { a as writeEnrollment, d as getTemplate, f as listTemplates, l as interpolate, n as listSequences, o as writeSequence, p as writeTemplate, r as readEnrollments, s as buildVariablesFromCustomer, t as getSequence, u as deleteTemplate } from "./sequence-store-
|
|
19
|
-
import { r as runSequenceCycle } from "./sequence-engine-
|
|
20
|
-
import { n as listQuotes, r as readQuote, t as generateQuote } from "./quote-generator-
|
|
21
|
-
import { i as upsertTicket, n as nextTicketId, r as readTickets, t as listAllTickets } from "./ticket-writer-
|
|
22
|
-
import { i as loadSlaRules, t as calcSlaDue } from "./sla-engine-
|
|
23
|
-
import { a as listSurveys, d as writeSurvey, i as getSurvey, l as savePendingSurvey, n as calcNpsScore, o as loadSurveyResponses, r as generateSurveyToken } from "./survey-engine-
|
|
15
|
+
import { d as setActorRole, i as canWrite, s as getRbacConfig } from "./rbac-msmBc_tK.js";
|
|
16
|
+
import { t as withJsonFile } from "./file-lock-CcHotQkZ.js";
|
|
17
|
+
import { d as deletePipelineStage, f as getPipelineStages, m as setPipelineStage, p as resetToDefaults } from "./revenue-simulation-D8f_YkUY.js";
|
|
18
|
+
import { d as pursueGoal, h as updateGoalProgress, i as getActiveGoals, n as cancelGoal } from "./goal-engine-BbroPhqm.js";
|
|
19
|
+
import { a as revoke, i as renewExpiringSubscriptions, n as readSubscriptions, r as register } from "./push-manager-C0ECQgva.js";
|
|
20
|
+
import { a as writeEnrollment, d as getTemplate, f as listTemplates, l as interpolate, n as listSequences, o as writeSequence, p as writeTemplate, r as readEnrollments, s as buildVariablesFromCustomer, t as getSequence, u as deleteTemplate } from "./sequence-store-CmYb6s0g.js";
|
|
21
|
+
import { r as runSequenceCycle } from "./sequence-engine-DNTVLq7o.js";
|
|
22
|
+
import { n as listQuotes, r as readQuote, t as generateQuote } from "./quote-generator-CTdR8eEI.js";
|
|
23
|
+
import { i as upsertTicket, n as nextTicketId, r as readTickets, t as listAllTickets } from "./ticket-writer-a9on36Wb.js";
|
|
24
|
+
import { i as loadSlaRules, t as calcSlaDue } from "./sla-engine-O-A1ntu_.js";
|
|
25
|
+
import { a as listSurveys, d as writeSurvey, i as getSurvey, l as savePendingSurvey, n as calcNpsScore, o as loadSurveyResponses, r as generateSurveyToken } from "./survey-engine-DngXBv47.js";
|
|
24
26
|
import { Command } from "commander";
|
|
25
27
|
import path from "path";
|
|
26
28
|
import fs from "fs";
|
|
27
29
|
import slugify from "slug";
|
|
28
30
|
import matter from "gray-matter";
|
|
31
|
+
import { createHash } from "crypto";
|
|
29
32
|
import Table from "cli-table3";
|
|
30
33
|
import os from "os";
|
|
31
34
|
import { execSync, spawn } from "child_process";
|
|
32
|
-
import { createHash } from "crypto";
|
|
33
35
|
//#region src/commands/create.ts
|
|
34
36
|
async function createCustomer(opts) {
|
|
35
37
|
const id = slugify(opts.name, { lower: true });
|
|
@@ -48,28 +50,25 @@ async function createCustomer(opts) {
|
|
|
48
50
|
updated: today
|
|
49
51
|
});
|
|
50
52
|
const interactionsPath = path.join(dir, "interactions.md");
|
|
51
|
-
if (!fs.existsSync(interactionsPath))
|
|
53
|
+
if (!fs.existsSync(interactionsPath)) writeFileAtomic(interactionsPath, `# Interactions — ${opts.name}\n\n`);
|
|
52
54
|
const pipelinePath = path.join(dir, "pipeline.md");
|
|
53
|
-
if (!fs.existsSync(pipelinePath))
|
|
55
|
+
if (!fs.existsSync(pipelinePath)) writeFileAtomic(pipelinePath, `# Pipeline — ${opts.name}\n\n| Deal | Stage | Value | Currency | Probability | Close Date | Updated | Notes |\n|---|---|---|---|---|---|---|---|\n`);
|
|
54
56
|
const sourcesPath = path.join(dir, "sources.json");
|
|
55
|
-
if (!fs.existsSync(sourcesPath)) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
};
|
|
65
|
-
fs.writeFileSync(sourcesPath, JSON.stringify(sources, null, 2));
|
|
66
|
-
}
|
|
57
|
+
if (!fs.existsSync(sourcesPath)) writeJsonFile(sourcesPath, {
|
|
58
|
+
gmail: {
|
|
59
|
+
type: "gmail",
|
|
60
|
+
query: opts.domain ? `from:${opts.domain} OR to:${opts.domain}` : opts.email ? `from:${opts.email} OR to:${opts.email}` : "",
|
|
61
|
+
enabled: true
|
|
62
|
+
},
|
|
63
|
+
version: 1,
|
|
64
|
+
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
65
|
+
});
|
|
67
66
|
return {
|
|
68
67
|
id,
|
|
69
68
|
dir
|
|
70
69
|
};
|
|
71
70
|
}
|
|
72
|
-
const createCommand = new Command("create").argument("<name>", "Customer name").option("--domain <domain>", "Primary domain (for Gmail sync)").option("--email <email>", "Primary contact email").action(async (name, opts) => {
|
|
71
|
+
const createCommand = new Command("create").description("Create a new customer").argument("<name>", "Customer name").option("--domain <domain>", "Primary domain (for Gmail sync)").option("--email <email>", "Primary contact email").action(async (name, opts) => {
|
|
73
72
|
try {
|
|
74
73
|
const { id, dir } = await createCustomer({
|
|
75
74
|
name,
|
|
@@ -118,7 +117,7 @@ function renderCustomerTable(customers) {
|
|
|
118
117
|
}
|
|
119
118
|
//#endregion
|
|
120
119
|
//#region src/commands/list.ts
|
|
121
|
-
const listCommand = new Command("list").option("--filter <query>", "Filter by name or slug").action(async (opts) => {
|
|
120
|
+
const listCommand = new Command("list").description("List all customers").option("--filter <query>", "Filter by name or slug").action(async (opts) => {
|
|
122
121
|
const dataDir = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
123
122
|
const slugs = listCustomerSlugs(dataDir);
|
|
124
123
|
if (slugs.length === 0) {
|
|
@@ -188,17 +187,17 @@ async function runValidate(opts, dataDir) {
|
|
|
188
187
|
}
|
|
189
188
|
try {
|
|
190
189
|
let content = fs.readFileSync(factsPath, "utf-8");
|
|
191
|
-
|
|
190
|
+
let parsed = matter(content);
|
|
192
191
|
if (opts.fix) {
|
|
193
|
-
const result = applyFix(factsPath, content, data);
|
|
192
|
+
const result = applyFix(factsPath, content, parsed.data);
|
|
194
193
|
if (result) {
|
|
195
194
|
content = result.content;
|
|
195
|
+
parsed = matter(content);
|
|
196
196
|
fixedCount++;
|
|
197
197
|
console.log(info(`⚙ ${slug}: fixed ${result.fixed.join(", ")}`));
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
|
|
201
|
-
MainFactsSchema.parse(refetchedData);
|
|
200
|
+
MainFactsSchema.parse(parsed.data);
|
|
202
201
|
if (!fs.existsSync(interactionsPath)) console.log(warning(`⚠ ${slug}: missing interactions.md`));
|
|
203
202
|
else console.log(success(`✓ ${slug}`));
|
|
204
203
|
} catch (err) {
|
|
@@ -212,7 +211,7 @@ async function runValidate(opts, dataDir) {
|
|
|
212
211
|
process.exit(1);
|
|
213
212
|
} else console.log(success("\n✓ All customers valid."));
|
|
214
213
|
}
|
|
215
|
-
const validateCommand = new Command("validate").option("--fix", "Auto-fix recoverable issues").action(async (opts) => {
|
|
214
|
+
const validateCommand = new Command("validate").description("Validate all customer data against schemas").option("--fix", "Auto-fix recoverable issues").action(async (opts) => {
|
|
216
215
|
await runValidate(opts, process.env["DXCRM_DATA_DIR"] ?? process.cwd());
|
|
217
216
|
});
|
|
218
217
|
//#endregion
|
|
@@ -220,7 +219,7 @@ const validateCommand = new Command("validate").option("--fix", "Auto-fix recove
|
|
|
220
219
|
const guideCommand = new Command("guide").description("Full CRM documentation in terminal").action(() => {
|
|
221
220
|
console.log(CAPABILITIES_TEXT);
|
|
222
221
|
});
|
|
223
|
-
const mcpCommand = new Command("mcp");
|
|
222
|
+
const mcpCommand = new Command("mcp").description("MCP server management and documentation");
|
|
224
223
|
mcpCommand.command("docs").action(() => {
|
|
225
224
|
console.log(CAPABILITIES_TEXT);
|
|
226
225
|
});
|
|
@@ -231,7 +230,7 @@ mcpCommand.command("token").description("Mint a bearer token for the HTTP MCP se
|
|
|
231
230
|
"rep"
|
|
232
231
|
].includes(opts.role) ? opts.role : "rep";
|
|
233
232
|
const dataDir = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
234
|
-
const { createMcpToken } = await import("./auth-
|
|
233
|
+
const { createMcpToken } = await import("./auth-B5DcjJ_6.js");
|
|
235
234
|
const token = createMcpToken(dataDir, opts.actor, role, opts.label);
|
|
236
235
|
console.log(info("MCP bearer token (store it now — it is not shown again):"));
|
|
237
236
|
console.log(token);
|
|
@@ -241,14 +240,14 @@ mcpCommand.command("start").description("Start MCP server (stdio by default)").o
|
|
|
241
240
|
if (opts.http) {
|
|
242
241
|
const port = parseInt(opts.port, 10);
|
|
243
242
|
console.error(info(`Starting MCP server in HTTP mode on port ${port}...`));
|
|
244
|
-
const { startHttp } = await import("./server-
|
|
243
|
+
const { startHttp } = await import("./server-DoRPPOeR.js");
|
|
245
244
|
await startHttp(port);
|
|
246
245
|
} else {
|
|
247
|
-
const { startStdio } = await import("./server-
|
|
246
|
+
const { startStdio } = await import("./server-DoRPPOeR.js");
|
|
248
247
|
await startStdio();
|
|
249
248
|
}
|
|
250
249
|
});
|
|
251
|
-
const TOOL_COUNT =
|
|
250
|
+
const TOOL_COUNT = 57;
|
|
252
251
|
/** Claude Code: CLAUDE.md in CRM dataDir */
|
|
253
252
|
function buildClaudeMd(dataDir) {
|
|
254
253
|
return `# DatasynxOpenCRM v2 — Agent Instructions (${TOOL_COUNT} MCP Tools)
|
|
@@ -374,6 +373,7 @@ It combines graph, health, revenue simulation, playbook, and org intelligence in
|
|
|
374
373
|
### Sync & Audit (Enterprise)
|
|
375
374
|
- \`trigger_sync({ slug?, since? })\` — force immediate Gmail sync for one or all customers (bypasses 30-min daemon cycle)
|
|
376
375
|
- \`get_audit_log({ slug?, actor?, limit? })\` — read append-only audit log of all write operations
|
|
376
|
+
- \`get_logs({ level?, component?, since?, contains?, limit?, summary? })\` — query/aggregate the structured application log
|
|
377
377
|
|
|
378
378
|
### Custom Objects (Platform / metadata)
|
|
379
379
|
- \`define_custom_object({ name, label?, fields })\` — define a runtime entity type with typed fields (no migration), admin
|
|
@@ -481,7 +481,7 @@ summarize_meeting · get_pipeline_stages · get_market_intelligence
|
|
|
481
481
|
|
|
482
482
|
**Backup (Enterprise):** backup_now · list_backups
|
|
483
483
|
|
|
484
|
-
**Sync & Audit (Enterprise):** trigger_sync · get_audit_log
|
|
484
|
+
**Sync & Audit (Enterprise):** trigger_sync · get_audit_log · get_logs
|
|
485
485
|
|
|
486
486
|
**Custom Objects (Platform):** define_custom_object · create_record · list_records · list_custom_objects
|
|
487
487
|
|
|
@@ -635,7 +635,7 @@ create_ticket · update_ticket · list_tickets · close_ticket ·
|
|
|
635
635
|
send_nps_survey · get_survey_results ·
|
|
636
636
|
search_knowledge_base · create_kb_article ·
|
|
637
637
|
backup_now · list_backups ·
|
|
638
|
-
trigger_sync · get_audit_log ·
|
|
638
|
+
trigger_sync · get_audit_log · get_logs ·
|
|
639
639
|
define_custom_object · create_record · list_records · list_custom_objects
|
|
640
640
|
|
|
641
641
|
## Data: ${dataDir}`.trim();
|
|
@@ -1604,7 +1604,7 @@ const initCommand = new Command("init").description("Initialize CRM and configur
|
|
|
1604
1604
|
});
|
|
1605
1605
|
//#endregion
|
|
1606
1606
|
//#region src/commands/sync.ts
|
|
1607
|
-
const syncCommand = new Command("sync").argument("<slug>", "Customer slug to sync").description("Sync Gmail and transcripts for a customer").option("--since <date>", "Only sync emails/files after this date (YYYY-MM-DD)").option("--gmail", "Sync Gmail only").option("--transcripts", "Sync transcripts only").option("--provider <provider>", "Sync provider: gmail | microsoft | transcripts").action(async (slug, opts) => {
|
|
1607
|
+
const syncCommand = new Command("sync").argument("<slug>", "Customer slug to sync").description("Sync Gmail and transcripts for a customer").option("--since <date>", "Only sync emails/files after this date (YYYY-MM-DD)").option("--gmail", "Sync Gmail only").option("--transcripts", "Sync transcripts only").option("--provider <provider>", "Sync provider: gmail | microsoft | transcripts").option("--no-attachments", "Skip downloading/converting/indexing email attachments").action(async (slug, opts) => {
|
|
1608
1608
|
const dataDir = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1609
1609
|
const customerDir = path.join(dataDir, "customers", slug);
|
|
1610
1610
|
if (!fs.existsSync(customerDir)) {
|
|
@@ -1631,13 +1631,14 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1631
1631
|
else try {
|
|
1632
1632
|
console.log(info(` Syncing Gmail for ${bold(slug)}...`));
|
|
1633
1633
|
const { getGmailAuth } = await import("./gmail-auth-OComS92L.js");
|
|
1634
|
-
const { syncGmail: doGmailSync } = await import("./gmail-sync-
|
|
1634
|
+
const { syncGmail: doGmailSync } = await import("./gmail-sync-B4Iu3AQb.js");
|
|
1635
1635
|
const result = await doGmailSync({
|
|
1636
1636
|
slug,
|
|
1637
1637
|
dataDir,
|
|
1638
1638
|
auth: await getGmailAuth(credPath, tokenPath),
|
|
1639
1639
|
query: sources.gmail.query,
|
|
1640
|
-
since
|
|
1640
|
+
since,
|
|
1641
|
+
includeAttachments: opts.attachments !== false
|
|
1641
1642
|
});
|
|
1642
1643
|
totalSynced += result.synced;
|
|
1643
1644
|
console.log(success(` ✓ Gmail: +${result.synced} synced, ${result.skipped} skipped`));
|
|
@@ -1651,7 +1652,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1651
1652
|
const token = await getMicrosoftToken(dataDir);
|
|
1652
1653
|
if (!token) console.log(info(" Microsoft: no token found (.agentic/microsoft-token.json)"));
|
|
1653
1654
|
else {
|
|
1654
|
-
const { syncMicrosoft: doMsSync } = await import("./microsoft-sync-
|
|
1655
|
+
const { syncMicrosoft: doMsSync } = await import("./microsoft-sync-D30_XksI.js");
|
|
1655
1656
|
const emailResult = await doMsSync({
|
|
1656
1657
|
slug,
|
|
1657
1658
|
dataDir,
|
|
@@ -1660,7 +1661,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1660
1661
|
});
|
|
1661
1662
|
totalSynced += emailResult.synced;
|
|
1662
1663
|
console.log(success(` ✓ Microsoft Email: +${emailResult.synced} synced, ${emailResult.skipped} skipped`));
|
|
1663
|
-
const { syncMicrosoftCalendar } = await import("./microsoft-calendar-
|
|
1664
|
+
const { syncMicrosoftCalendar } = await import("./microsoft-calendar-BgVR8GDv.js");
|
|
1664
1665
|
const calResult = await syncMicrosoftCalendar({
|
|
1665
1666
|
slug,
|
|
1666
1667
|
dataDir,
|
|
@@ -1678,7 +1679,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1678
1679
|
if (fs.existsSync(agenticSourcesPath)) try {
|
|
1679
1680
|
const agenticSources = JSON.parse(fs.readFileSync(agenticSourcesPath, "utf-8"));
|
|
1680
1681
|
if (agenticSources.transcripts?.enabled && agenticSources.transcripts.paths?.length) {
|
|
1681
|
-
const { processTranscriptFile } = await import("./transcript-watcher-
|
|
1682
|
+
const { processTranscriptFile } = await import("./transcript-watcher-BoClrJAz.js");
|
|
1682
1683
|
const exts = agenticSources.transcripts.extensions ?? [".txt", ".vtt"];
|
|
1683
1684
|
let transcriptSynced = 0;
|
|
1684
1685
|
for (const watchPath of agenticSources.transcripts.paths) {
|
|
@@ -1707,7 +1708,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1707
1708
|
if (!accessToken) console.log(info(" Google Drive: accessToken not found in token file"));
|
|
1708
1709
|
else {
|
|
1709
1710
|
console.log(info(` Syncing Google Drive for ${bold(slug)}...`));
|
|
1710
|
-
const { syncGoogleDriveFiles } = await import("./google-drive-sync-
|
|
1711
|
+
const { syncGoogleDriveFiles } = await import("./google-drive-sync-B_I1d54Y.js");
|
|
1711
1712
|
const result = await syncGoogleDriveFiles({
|
|
1712
1713
|
slug,
|
|
1713
1714
|
dataDir,
|
|
@@ -1730,7 +1731,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1730
1731
|
function getPidFile$1() {
|
|
1731
1732
|
return path.join(process.cwd(), ".agentic", "daemon.pid");
|
|
1732
1733
|
}
|
|
1733
|
-
const daemonCommand = new Command("daemon");
|
|
1734
|
+
const daemonCommand = new Command("daemon").description("Manage the background sync daemon");
|
|
1734
1735
|
daemonCommand.command("start").action(async () => {
|
|
1735
1736
|
const pidFile = getPidFile$1();
|
|
1736
1737
|
if (fs.existsSync(pidFile)) {
|
|
@@ -1895,8 +1896,7 @@ async function runAgentSpawn(slug, opts, dataDir) {
|
|
|
1895
1896
|
lastWake: null,
|
|
1896
1897
|
...opts.chatId !== void 0 ? { telegramChatId: opts.chatId } : {}
|
|
1897
1898
|
});
|
|
1898
|
-
|
|
1899
|
-
fs.writeFileSync(agentConfigPath(dir, slug), JSON.stringify(config, null, 2), "utf-8");
|
|
1899
|
+
writeJsonFile(agentConfigPath(dir, slug), config);
|
|
1900
1900
|
console.log(success(`✓ Agent spawned: ${bold(slug)}`));
|
|
1901
1901
|
console.log(info(` Channel: ${channel}`));
|
|
1902
1902
|
console.log(info(` Wake on: ${wakeOn.join(", ")}`));
|
|
@@ -2008,7 +2008,7 @@ function ensureCustomer(dataDir, name, domain, email, dryRun) {
|
|
|
2008
2008
|
};
|
|
2009
2009
|
fs.mkdirSync(customerDir, { recursive: true });
|
|
2010
2010
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2011
|
-
|
|
2011
|
+
writeFileAtomic(mainFactsPath, `${[
|
|
2012
2012
|
"---",
|
|
2013
2013
|
`name: ${name}`,
|
|
2014
2014
|
domain ? `domain: ${domain}` : null,
|
|
@@ -2019,11 +2019,10 @@ function ensureCustomer(dataDir, name, domain, email, dryRun) {
|
|
|
2019
2019
|
`last_touchpoint: ${today}`,
|
|
2020
2020
|
"tags: []",
|
|
2021
2021
|
"---"
|
|
2022
|
-
].filter(Boolean).join("\n");
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
fs.writeFileSync(path.join(customerDir, "sources.json"), JSON.stringify({
|
|
2022
|
+
].filter(Boolean).join("\n")}\n\n# Customer: ${name}\n`);
|
|
2023
|
+
writeFileAtomic(path.join(customerDir, "interactions.md"), `# Interactions — ${name}\n\n`);
|
|
2024
|
+
writeFileAtomic(path.join(customerDir, "pipeline.md"), `# Pipeline — ${name}\n\n`);
|
|
2025
|
+
writeJsonFile(path.join(customerDir, "sources.json"), {
|
|
2027
2026
|
gmail: {
|
|
2028
2027
|
query: domain ? `from:${domain} OR to:${domain}` : email ? `from:${email} OR to:${email}` : "",
|
|
2029
2028
|
enabled: true
|
|
@@ -2033,7 +2032,7 @@ function ensureCustomer(dataDir, name, domain, email, dryRun) {
|
|
|
2033
2032
|
extensions: [".txt", ".vtt"],
|
|
2034
2033
|
enabled: false
|
|
2035
2034
|
}
|
|
2036
|
-
}
|
|
2035
|
+
});
|
|
2037
2036
|
return {
|
|
2038
2037
|
slug,
|
|
2039
2038
|
created: true
|
|
@@ -2107,14 +2106,14 @@ async function runSalesforceFileImport(sourcePath, opts, dir) {
|
|
|
2107
2106
|
result.errors.push(`Account '${name}': ${err.message}`);
|
|
2108
2107
|
}
|
|
2109
2108
|
}
|
|
2109
|
+
const dedup = new InteractionDedup(dir);
|
|
2110
2110
|
for (const row of activities) {
|
|
2111
2111
|
const accountId = row["AccountId"] ?? row["WhatId"] ?? "";
|
|
2112
2112
|
const slug = accountId ? slugMap.get(accountId) : void 0;
|
|
2113
2113
|
if (!slug) continue;
|
|
2114
2114
|
const id = row["Id"] ?? hashRow(row);
|
|
2115
2115
|
const sourceRef = `salesforce://row/${id}`;
|
|
2116
|
-
|
|
2117
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2116
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2118
2117
|
result.skipped++;
|
|
2119
2118
|
continue;
|
|
2120
2119
|
}
|
|
@@ -2132,6 +2131,7 @@ async function runSalesforceFileImport(sourcePath, opts, dir) {
|
|
|
2132
2131
|
sourceRef,
|
|
2133
2132
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2134
2133
|
});
|
|
2134
|
+
dedup.markAppended(slug, sourceRef);
|
|
2135
2135
|
result.interactionsImported++;
|
|
2136
2136
|
} catch (err) {
|
|
2137
2137
|
result.errors.push(`Activity ${id}: ${err.message}`);
|
|
@@ -2185,14 +2185,14 @@ async function runPipedriveFileImport(sourcePath, opts, dir) {
|
|
|
2185
2185
|
result.errors.push(`Organization '${name}': ${err.message}`);
|
|
2186
2186
|
}
|
|
2187
2187
|
}
|
|
2188
|
+
const dedup = new InteractionDedup(dir);
|
|
2188
2189
|
for (const row of activities) {
|
|
2189
2190
|
const orgId = row["org_id"] ?? row["organization_id"] ?? "";
|
|
2190
2191
|
const slug = orgId ? slugMap.get(orgId) : void 0;
|
|
2191
2192
|
if (!slug) continue;
|
|
2192
2193
|
const id = row["id"] ?? hashRow(row);
|
|
2193
2194
|
const sourceRef = `pipedrive://row/${id}`;
|
|
2194
|
-
|
|
2195
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2195
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2196
2196
|
result.skipped++;
|
|
2197
2197
|
continue;
|
|
2198
2198
|
}
|
|
@@ -2210,6 +2210,7 @@ async function runPipedriveFileImport(sourcePath, opts, dir) {
|
|
|
2210
2210
|
sourceRef,
|
|
2211
2211
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2212
2212
|
});
|
|
2213
|
+
dedup.markAppended(slug, sourceRef);
|
|
2213
2214
|
result.interactionsImported++;
|
|
2214
2215
|
} catch (err) {
|
|
2215
2216
|
result.errors.push(`Activity ${id}: ${err.message}`);
|
|
@@ -2229,7 +2230,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2229
2230
|
if (opts.from === "salesforce" && opts.mode === "api") return runSalesforceApiImport(opts, dir);
|
|
2230
2231
|
if (opts.from === "pipedrive" && opts.mode === "api") return runPipedriveApiImport(opts, dir);
|
|
2231
2232
|
if (opts.from === "hubspot" && sourcePath && fs.existsSync(sourcePath) && fs.statSync(sourcePath).isDirectory()) {
|
|
2232
|
-
const { runHubSpotCsvImport } = await import("./import-hubspot-
|
|
2233
|
+
const { runHubSpotCsvImport } = await import("./import-hubspot-CTId9IGV.js");
|
|
2233
2234
|
const r = await runHubSpotCsvImport(sourcePath, dir, {
|
|
2234
2235
|
...opts.dryRun ? { dryRun: true } : {},
|
|
2235
2236
|
...opts.resume ? { resume: true } : {},
|
|
@@ -2256,7 +2257,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2256
2257
|
return result;
|
|
2257
2258
|
}
|
|
2258
2259
|
const headers = Object.keys(rows[0]);
|
|
2259
|
-
const { mapCsvFields } = await import("./llm-
|
|
2260
|
+
const { mapCsvFields } = await import("./llm-DSX1-wFu.js");
|
|
2260
2261
|
const mapping = await mapCsvFields(headers, [...IMPORT_TARGET_FIELDS]);
|
|
2261
2262
|
if (opts.dryRun) {
|
|
2262
2263
|
console.log(info(`Dry run — ${rows.length} rows, field mapping:`));
|
|
@@ -2281,6 +2282,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2281
2282
|
result.errors.push(`Customer '${name}': ${err.message}`);
|
|
2282
2283
|
}
|
|
2283
2284
|
}
|
|
2285
|
+
const dedup = new InteractionDedup(dir);
|
|
2284
2286
|
for (const row of rows) {
|
|
2285
2287
|
const activityType = (row[mapping["activityType"] ?? ""] ?? "").trim();
|
|
2286
2288
|
const notes = (row[mapping["notes"] ?? ""] ?? "").trim();
|
|
@@ -2309,8 +2311,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2309
2311
|
return "Note";
|
|
2310
2312
|
})();
|
|
2311
2313
|
try {
|
|
2312
|
-
|
|
2313
|
-
if ((await readInteractions(dir, slug)).includes(sourceRef)) {
|
|
2314
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2314
2315
|
result.skipped++;
|
|
2315
2316
|
continue;
|
|
2316
2317
|
}
|
|
@@ -2323,6 +2324,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2323
2324
|
sourceRef,
|
|
2324
2325
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2325
2326
|
});
|
|
2327
|
+
dedup.markAppended(slug, sourceRef);
|
|
2326
2328
|
result.interactionsImported++;
|
|
2327
2329
|
} catch (err) {
|
|
2328
2330
|
result.errors.push(`Activity for '${name}': ${err.message}`);
|
|
@@ -2386,12 +2388,12 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2386
2388
|
result.errors.push(`Contact '${name}': ${err.message}`);
|
|
2387
2389
|
}
|
|
2388
2390
|
}
|
|
2391
|
+
const dedup = new InteractionDedup(dir);
|
|
2389
2392
|
for (const task of tasks) {
|
|
2390
2393
|
const slug = task.WhoId ? slugMap.get(task.WhoId) : void 0;
|
|
2391
2394
|
if (!slug) continue;
|
|
2392
2395
|
const sourceRef = `salesforce://task/${task.Id}`;
|
|
2393
|
-
|
|
2394
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2396
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2395
2397
|
result.skipped++;
|
|
2396
2398
|
continue;
|
|
2397
2399
|
}
|
|
@@ -2409,12 +2411,13 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2409
2411
|
sourceRef,
|
|
2410
2412
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2411
2413
|
});
|
|
2414
|
+
dedup.markAppended(slug, sourceRef);
|
|
2412
2415
|
result.interactionsImported++;
|
|
2413
2416
|
} catch (err) {
|
|
2414
2417
|
result.errors.push(`Task ${task.Id}: ${err.message}`);
|
|
2415
2418
|
}
|
|
2416
2419
|
}
|
|
2417
|
-
const { upsertDeal } = await import("./pipeline-writer-
|
|
2420
|
+
const { upsertDeal } = await import("./pipeline-writer-0LJ6Qkat.js");
|
|
2418
2421
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2419
2422
|
const oppSlugById = /* @__PURE__ */ new Map();
|
|
2420
2423
|
for (const opp of opportunities) {
|
|
@@ -2453,7 +2456,6 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2453
2456
|
result.errors.push(`Opportunity '${opp.Name}': ${err.message}`);
|
|
2454
2457
|
}
|
|
2455
2458
|
}
|
|
2456
|
-
const { readInteractions } = await import("./interactions-writer-dSPy1XfO.js");
|
|
2457
2459
|
for (const lead of leads) {
|
|
2458
2460
|
const name = lead.Company?.trim() || lead.Name?.trim();
|
|
2459
2461
|
if (!name) continue;
|
|
@@ -2469,7 +2471,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2469
2471
|
continue;
|
|
2470
2472
|
}
|
|
2471
2473
|
const sourceRef = `salesforce://lead/${lead.Id}`;
|
|
2472
|
-
if (
|
|
2474
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2473
2475
|
result.skipped++;
|
|
2474
2476
|
continue;
|
|
2475
2477
|
}
|
|
@@ -2484,6 +2486,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2484
2486
|
sourceRef,
|
|
2485
2487
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2486
2488
|
});
|
|
2489
|
+
dedup.markAppended(slug, sourceRef);
|
|
2487
2490
|
result.leadsImported = (result.leadsImported ?? 0) + 1;
|
|
2488
2491
|
} catch (err) {
|
|
2489
2492
|
result.errors.push(`Lead ${lead.Id}: ${err.message}`);
|
|
@@ -2496,7 +2499,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2496
2499
|
continue;
|
|
2497
2500
|
}
|
|
2498
2501
|
const sourceRef = `salesforce://event/${event.Id}`;
|
|
2499
|
-
if (
|
|
2502
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2500
2503
|
result.skipped++;
|
|
2501
2504
|
continue;
|
|
2502
2505
|
}
|
|
@@ -2512,13 +2515,14 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2512
2515
|
sourceRef,
|
|
2513
2516
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2514
2517
|
});
|
|
2518
|
+
dedup.markAppended(slug, sourceRef);
|
|
2515
2519
|
result.eventsImported = (result.eventsImported ?? 0) + 1;
|
|
2516
2520
|
} catch (err) {
|
|
2517
2521
|
result.errors.push(`Event ${event.Id}: ${err.message}`);
|
|
2518
2522
|
}
|
|
2519
2523
|
}
|
|
2520
|
-
const { readTickets, upsertTicket, nextTicketId } = await import("./ticket-writer-
|
|
2521
|
-
const { calcSlaDue, loadSlaRules } = await import("./sla-engine-
|
|
2524
|
+
const { readTickets, upsertTicket, nextTicketId } = await import("./ticket-writer-DsfpeLGZ.js");
|
|
2525
|
+
const { calcSlaDue, loadSlaRules } = await import("./sla-engine-CP2KiKDS.js");
|
|
2522
2526
|
const slaRules = loadSlaRules(dir);
|
|
2523
2527
|
for (const c of cases) {
|
|
2524
2528
|
const accountName = c.Account?.Name?.trim();
|
|
@@ -2565,7 +2569,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2565
2569
|
}
|
|
2566
2570
|
}
|
|
2567
2571
|
if (lineItems.length > 0 && oppSlugById.size > 0) {
|
|
2568
|
-
const { generateQuote, listQuotes } = await import("./quote-generator-
|
|
2572
|
+
const { generateQuote, listQuotes } = await import("./quote-generator-ByUyIYtw.js");
|
|
2569
2573
|
const byOpp = /* @__PURE__ */ new Map();
|
|
2570
2574
|
for (const li of lineItems) {
|
|
2571
2575
|
if (!li.OpportunityId) continue;
|
|
@@ -2608,7 +2612,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2608
2612
|
continue;
|
|
2609
2613
|
}
|
|
2610
2614
|
const sourceRef = `salesforce://note/${note.Id}`;
|
|
2611
|
-
if (
|
|
2615
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2612
2616
|
result.skipped++;
|
|
2613
2617
|
continue;
|
|
2614
2618
|
}
|
|
@@ -2625,6 +2629,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2625
2629
|
sourceRef,
|
|
2626
2630
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2627
2631
|
});
|
|
2632
|
+
dedup.markAppended(slug, sourceRef);
|
|
2628
2633
|
result.notesImported = (result.notesImported ?? 0) + 1;
|
|
2629
2634
|
} catch (err) {
|
|
2630
2635
|
result.errors.push(`Note ${note.Id}: ${err.message}`);
|
|
@@ -2637,7 +2642,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2637
2642
|
continue;
|
|
2638
2643
|
}
|
|
2639
2644
|
const sourceRef = `salesforce://campaignmember/${cm.Id}`;
|
|
2640
|
-
if (
|
|
2645
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2641
2646
|
result.skipped++;
|
|
2642
2647
|
continue;
|
|
2643
2648
|
}
|
|
@@ -2653,6 +2658,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2653
2658
|
sourceRef,
|
|
2654
2659
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2655
2660
|
});
|
|
2661
|
+
dedup.markAppended(slug, sourceRef);
|
|
2656
2662
|
result.campaignsImported = (result.campaignsImported ?? 0) + 1;
|
|
2657
2663
|
} catch (err) {
|
|
2658
2664
|
result.errors.push(`CampaignMember ${cm.Id}: ${err.message}`);
|
|
@@ -2701,12 +2707,12 @@ async function runPipedriveApiImport(opts, dir = process.cwd()) {
|
|
|
2701
2707
|
result.errors.push(`Person '${name}': ${err.message}`);
|
|
2702
2708
|
}
|
|
2703
2709
|
}
|
|
2710
|
+
const dedup = new InteractionDedup(dir);
|
|
2704
2711
|
for (const activity of activities) {
|
|
2705
2712
|
const slug = (activity.person_id && slugByPersonId.get(activity.person_id)) ?? (activity.org_id && slugByOrgId.get(activity.org_id)) ?? void 0;
|
|
2706
2713
|
if (!slug) continue;
|
|
2707
2714
|
const sourceRef = `pipedrive://activity/${activity.id}`;
|
|
2708
|
-
|
|
2709
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2715
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2710
2716
|
result.skipped++;
|
|
2711
2717
|
continue;
|
|
2712
2718
|
}
|
|
@@ -2724,6 +2730,7 @@ async function runPipedriveApiImport(opts, dir = process.cwd()) {
|
|
|
2724
2730
|
sourceRef,
|
|
2725
2731
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2726
2732
|
});
|
|
2733
|
+
dedup.markAppended(slug, sourceRef);
|
|
2727
2734
|
result.interactionsImported++;
|
|
2728
2735
|
} catch (err) {
|
|
2729
2736
|
result.errors.push(`Activity ${activity.id}: ${err.message}`);
|
|
@@ -2739,7 +2746,7 @@ const importCommand = new Command("import").description("Import customers and in
|
|
|
2739
2746
|
if (hs && rep) ownerMap[hs.trim()] = rep.trim();
|
|
2740
2747
|
}
|
|
2741
2748
|
if (opts.analyze && opts.from === "hubspot" && sourcePath) {
|
|
2742
|
-
const { analyzeHubSpotExport } = await import("./import-hubspot-
|
|
2749
|
+
const { analyzeHubSpotExport } = await import("./import-hubspot-CTId9IGV.js");
|
|
2743
2750
|
const analysis = await analyzeHubSpotExport(sourcePath);
|
|
2744
2751
|
console.log(bold("\nDatasynxOpenCRM — HubSpot Import Analysis"));
|
|
2745
2752
|
console.log("==========================================");
|
|
@@ -2840,7 +2847,7 @@ function runServerStatus(dataDir) {
|
|
|
2840
2847
|
} catch {}
|
|
2841
2848
|
}
|
|
2842
2849
|
}
|
|
2843
|
-
const serverCommand = new Command("server");
|
|
2850
|
+
const serverCommand = new Command("server").description("Start the shared HTTP MCP server for team use");
|
|
2844
2851
|
serverCommand.command("start").description("Start the DatasynxOpenCRM HTTP MCP server").option("--port <port>", "HTTP port (default 3847)", "3847").option("--data <dir>", "Data directory (sets DXCRM_DATA_DIR)").action((opts) => runServerStart(opts));
|
|
2845
2852
|
serverCommand.command("status").description("Check if the server is running").action(() => runServerStatus());
|
|
2846
2853
|
//#endregion
|
|
@@ -2871,6 +2878,90 @@ async function runAudit(opts, dataDir) {
|
|
|
2871
2878
|
}
|
|
2872
2879
|
const auditCommand = new Command("audit").description("Show CRM audit trail — who changed what and when").option("--slug <slug>", "Filter by customer slug").option("--actor <actor>", "Filter by actor").option("--limit <n>", "Number of entries to show (default: 20)", parseInt).option("--tail", "Show all new entries (simplified: shows current entries)").action((opts) => runAudit(opts, process.env["DXCRM_DATA_DIR"]));
|
|
2873
2880
|
//#endregion
|
|
2881
|
+
//#region src/commands/logs.ts
|
|
2882
|
+
const LEVELS = [
|
|
2883
|
+
"debug",
|
|
2884
|
+
"info",
|
|
2885
|
+
"warn",
|
|
2886
|
+
"error"
|
|
2887
|
+
];
|
|
2888
|
+
function paintLevel(level, text) {
|
|
2889
|
+
if (level === "error") return error(text);
|
|
2890
|
+
if (level === "warn") return warning(text);
|
|
2891
|
+
if (level === "info") return info(text);
|
|
2892
|
+
return text;
|
|
2893
|
+
}
|
|
2894
|
+
function buildQuery(opts) {
|
|
2895
|
+
return {
|
|
2896
|
+
...opts.level && LEVELS.includes(opts.level) ? { level: opts.level } : {},
|
|
2897
|
+
...opts.component !== void 0 ? { component: opts.component } : {},
|
|
2898
|
+
...opts.since !== void 0 ? { since: opts.since } : {},
|
|
2899
|
+
...opts.contains !== void 0 ? { contains: opts.contains } : {},
|
|
2900
|
+
limit: opts.limit ?? 50
|
|
2901
|
+
};
|
|
2902
|
+
}
|
|
2903
|
+
function dataDir$18() {
|
|
2904
|
+
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2905
|
+
}
|
|
2906
|
+
const logsCommand = new Command("logs").description("View and analyze the structured application log").option("--level <level>", "Minimum level: debug | info | warn | error").option("--component <name>", "Filter by component (e.g. gmail-sync, lancedb)").option("--since <iso>", "Only entries at or after this ISO timestamp").option("--contains <text>", "Filter by message substring").option("--limit <n>", "Max entries to show (default: 50)", parseInt).option("--summary", "Show aggregated counts (by level + component) instead of entries").action(async (opts) => {
|
|
2907
|
+
const query = buildQuery(opts);
|
|
2908
|
+
if (opts.summary) {
|
|
2909
|
+
const { summarizeLogs } = await import("./logger-vKQS34w9.js");
|
|
2910
|
+
const s = summarizeLogs(dataDir$18(), query);
|
|
2911
|
+
console.log(bold(`Logs — ${s.total} entr${s.total === 1 ? "y" : "ies"}`));
|
|
2912
|
+
if (s.firstTs) console.log(info(` ${s.firstTs} → ${s.lastTs}`));
|
|
2913
|
+
console.log(" By level:");
|
|
2914
|
+
for (const lvl of LEVELS) {
|
|
2915
|
+
const n = s.byLevel[lvl];
|
|
2916
|
+
if (n > 0) console.log(` ${paintLevel(lvl, lvl.padEnd(6))} ${n}`);
|
|
2917
|
+
}
|
|
2918
|
+
console.log(" By component:");
|
|
2919
|
+
for (const [comp, n] of Object.entries(s.byComponent).sort((a, b) => b[1] - a[1])) console.log(` ${comp.padEnd(22)} ${n}`);
|
|
2920
|
+
if (s.recentErrors.length > 0) {
|
|
2921
|
+
console.log(error(" Recent errors:"));
|
|
2922
|
+
for (const e of s.recentErrors) console.log(` ${e.ts} [${e.component}] ${e.message}`);
|
|
2923
|
+
}
|
|
2924
|
+
return;
|
|
2925
|
+
}
|
|
2926
|
+
const { queryLogs } = await import("./logger-vKQS34w9.js");
|
|
2927
|
+
const entries = queryLogs(dataDir$18(), query);
|
|
2928
|
+
if (entries.length === 0) {
|
|
2929
|
+
console.log(success("No matching log entries."));
|
|
2930
|
+
return;
|
|
2931
|
+
}
|
|
2932
|
+
for (const e of entries) {
|
|
2933
|
+
const ctx = e.context ? ` ${JSON.stringify(e.context)}` : "";
|
|
2934
|
+
console.log(`${e.ts} ${paintLevel(e.level, e.level.padEnd(5))} ${e.component.padEnd(18)} ${e.message}${ctx}`);
|
|
2935
|
+
}
|
|
2936
|
+
});
|
|
2937
|
+
//#endregion
|
|
2938
|
+
//#region src/commands/doctor.ts
|
|
2939
|
+
function dataDir$17() {
|
|
2940
|
+
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2941
|
+
}
|
|
2942
|
+
function icon(status) {
|
|
2943
|
+
if (status === "ok") return success("✓");
|
|
2944
|
+
if (status === "warn") return warning("⚠");
|
|
2945
|
+
return error("✗");
|
|
2946
|
+
}
|
|
2947
|
+
const doctorCommand = new Command("doctor").description("Run self-diagnostics: data integrity, temp files, log errors, backup freshness").option("--fix", "Clean up safely-fixable issues (orphaned temp files)").action(async (opts) => {
|
|
2948
|
+
const { runDiagnostics, cleanupTempFiles } = await import("./doctor-C14-vnJ1.js");
|
|
2949
|
+
if (opts.fix) {
|
|
2950
|
+
const removed = cleanupTempFiles(dataDir$17());
|
|
2951
|
+
console.log(removed.length > 0 ? success(`Removed ${removed.length} orphaned temp file(s).`) : warning("Nothing to fix."));
|
|
2952
|
+
}
|
|
2953
|
+
const report = await runDiagnostics(dataDir$17());
|
|
2954
|
+
console.log(bold("dxcrm doctor"));
|
|
2955
|
+
for (const c of report.checks) console.log(` ${icon(c.status)} ${c.name.padEnd(16)} ${c.detail}`);
|
|
2956
|
+
if (report.ok) {
|
|
2957
|
+
const warns = report.checks.filter((c) => c.status === "warn").length;
|
|
2958
|
+
console.log(warns > 0 ? warning(`\nHealthy, with ${warns} warning(s).`) : success("\nAll healthy."));
|
|
2959
|
+
} else {
|
|
2960
|
+
console.log(error("\nProblems found — see the ✗ checks above."));
|
|
2961
|
+
process.exitCode = 1;
|
|
2962
|
+
}
|
|
2963
|
+
});
|
|
2964
|
+
//#endregion
|
|
2874
2965
|
//#region src/commands/rbac.ts
|
|
2875
2966
|
const ROLES = [
|
|
2876
2967
|
"admin",
|
|
@@ -2900,7 +2991,7 @@ async function runRbacShow(dataDir) {
|
|
|
2900
2991
|
}
|
|
2901
2992
|
async function runRbacCheck(actor, tool, dataDir) {
|
|
2902
2993
|
const dir = dataDir ?? process.cwd();
|
|
2903
|
-
const { getRole } = await import("./rbac-
|
|
2994
|
+
const { getRole } = await import("./rbac-DzbyFhVH.js");
|
|
2904
2995
|
const role = getRole(dir, actor);
|
|
2905
2996
|
if (canWrite(role, tool)) console.log(success(`✓ ${actor} (${role}) CAN use '${tool}'`));
|
|
2906
2997
|
else console.log(error(`✗ ${actor} (${role}) CANNOT use '${tool}'`));
|
|
@@ -2928,7 +3019,7 @@ function appendErasure(dataDir, record) {
|
|
|
2928
3019
|
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
2929
3020
|
const existing = readErasures(dataDir);
|
|
2930
3021
|
existing.push(record);
|
|
2931
|
-
|
|
3022
|
+
writeJsonFile(p, existing);
|
|
2932
3023
|
}
|
|
2933
3024
|
async function runGdprErase(slug, opts, dataDir) {
|
|
2934
3025
|
const dir = dataDir ?? process.cwd();
|
|
@@ -2948,7 +3039,7 @@ async function runGdprErase(slug, opts, dataDir) {
|
|
|
2948
3039
|
force: true
|
|
2949
3040
|
});
|
|
2950
3041
|
try {
|
|
2951
|
-
const { dropCustomerTable } = await import("./lancedb-
|
|
3042
|
+
const { dropCustomerTable } = await import("./lancedb-CswQEE5K.js");
|
|
2952
3043
|
await dropCustomerTable(dir, slug);
|
|
2953
3044
|
} catch {}
|
|
2954
3045
|
}
|
|
@@ -2956,7 +3047,7 @@ async function runGdprErase(slug, opts, dataDir) {
|
|
|
2956
3047
|
if (fs.existsSync(globalQueuePath)) await withJsonFile(globalQueuePath, (tasks) => (Array.isArray(tasks) ? tasks : []).filter((t) => t.slug !== slug));
|
|
2957
3048
|
const goalsPath = path.join(dir, ".agentic", "goals.json");
|
|
2958
3049
|
if (fs.existsSync(goalsPath)) {
|
|
2959
|
-
const { readGoals, writeGoals } = await import("./goal-engine-
|
|
3050
|
+
const { readGoals, writeGoals } = await import("./goal-engine-CfDAJTFt.js");
|
|
2960
3051
|
writeGoals(dir, readGoals(dir).map((g) => ({
|
|
2961
3052
|
...g,
|
|
2962
3053
|
decomposition: {
|
|
@@ -2965,7 +3056,7 @@ async function runGdprErase(slug, opts, dataDir) {
|
|
|
2965
3056
|
}
|
|
2966
3057
|
})));
|
|
2967
3058
|
}
|
|
2968
|
-
const { readSubscriptions, writeSubscriptions } = await import("./push-manager-
|
|
3059
|
+
const { readSubscriptions, writeSubscriptions } = await import("./push-manager-BXM-IHfP.js");
|
|
2969
3060
|
const subs = await readSubscriptions(dir);
|
|
2970
3061
|
const remaining = subs.filter((s) => s.slug !== slug);
|
|
2971
3062
|
if (remaining.length !== subs.length) await writeSubscriptions(dir, remaining);
|
|
@@ -3396,7 +3487,7 @@ templateCommand.command("create <id>").option("--category <category>", "Category
|
|
|
3396
3487
|
variables: [],
|
|
3397
3488
|
language: "de",
|
|
3398
3489
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3399
|
-
body: `Hi {{firstName}},\n\n[your message here]\n\
|
|
3490
|
+
body: `Hi {{firstName}},\n\n[your message here]\n\nBest regards,\n{{senderName}}`
|
|
3400
3491
|
});
|
|
3401
3492
|
console.log(success(`✓ Template '${id}' created in category '${opts.category}'`));
|
|
3402
3493
|
});
|
|
@@ -3761,7 +3852,7 @@ function parseFieldSpec(spec) {
|
|
|
3761
3852
|
}
|
|
3762
3853
|
const fieldsCommand = new Command("fields").description("Manage custom fields (metadata-driven extensibility)");
|
|
3763
3854
|
fieldsCommand.command("list").description("List defined custom fields").action(async () => {
|
|
3764
|
-
const { loadFieldDefinitions } = await import("./custom-fields-
|
|
3855
|
+
const { loadFieldDefinitions } = await import("./custom-fields-BMyz5Ruh.js");
|
|
3765
3856
|
const defs = loadFieldDefinitions(dataDir$16());
|
|
3766
3857
|
if (defs.length === 0) {
|
|
3767
3858
|
console.log(info("No custom fields defined. Add one with: dxcrm fields add <name> <type>"));
|
|
@@ -3778,7 +3869,7 @@ fieldsCommand.command("add <name> <type>").description("Define a custom field (t
|
|
|
3778
3869
|
process.exitCode = 1;
|
|
3779
3870
|
return;
|
|
3780
3871
|
}
|
|
3781
|
-
const { defineCustomField } = await import("./custom-fields-
|
|
3872
|
+
const { defineCustomField } = await import("./custom-fields-BMyz5Ruh.js");
|
|
3782
3873
|
defineCustomField(dataDir$16(), {
|
|
3783
3874
|
name,
|
|
3784
3875
|
type,
|
|
@@ -3799,7 +3890,7 @@ objectCommand.command("define <name>").description("Define a custom object with
|
|
|
3799
3890
|
}
|
|
3800
3891
|
fields.push(f);
|
|
3801
3892
|
}
|
|
3802
|
-
const { defineCustomObject } = await import("./custom-objects-
|
|
3893
|
+
const { defineCustomObject } = await import("./custom-objects-BNy-ayR-.js");
|
|
3803
3894
|
defineCustomObject(dataDir$16(), {
|
|
3804
3895
|
name,
|
|
3805
3896
|
...opts.label ? { label: opts.label } : {},
|
|
@@ -3814,7 +3905,7 @@ objectCommand.command("add <name>").description("Create a record (--set key=valu
|
|
|
3814
3905
|
if (eq < 0) continue;
|
|
3815
3906
|
values[kv.slice(0, eq).trim()] = kv.slice(eq + 1).trim();
|
|
3816
3907
|
}
|
|
3817
|
-
const { createRecord } = await import("./custom-objects-
|
|
3908
|
+
const { createRecord } = await import("./custom-objects-BNy-ayR-.js");
|
|
3818
3909
|
const res = createRecord(dataDir$16(), name, values);
|
|
3819
3910
|
if (!res.ok) {
|
|
3820
3911
|
console.error(error(`Could not create record: ${(res.errors ?? []).join("; ")}`));
|
|
@@ -3824,7 +3915,7 @@ objectCommand.command("add <name>").description("Create a record (--set key=valu
|
|
|
3824
3915
|
console.log(success(`Created ${name} record ${res.record.id}`));
|
|
3825
3916
|
});
|
|
3826
3917
|
objectCommand.command("list <name>").description("List records of a custom object").action(async (name) => {
|
|
3827
|
-
const { listRecords } = await import("./custom-objects-
|
|
3918
|
+
const { listRecords } = await import("./custom-objects-BNy-ayR-.js");
|
|
3828
3919
|
const records = listRecords(dataDir$16(), name);
|
|
3829
3920
|
if (records.length === 0) {
|
|
3830
3921
|
console.log(info(`No records for '${name}'.`));
|
|
@@ -3839,13 +3930,13 @@ function dataDir$15() {
|
|
|
3839
3930
|
}
|
|
3840
3931
|
const webhookCommand = new Command("webhook").description("Manage outbound webhooks (event-driven integrations)");
|
|
3841
3932
|
webhookCommand.command("add <url>").description("Subscribe a URL to events (--events record.created,deal.updated or '*')").option("--events <csv>", "Comma-separated event patterns", "*").option("--secret <secret>", "HMAC secret for X-DXCRM-Signature").action(async (url, opts) => {
|
|
3842
|
-
const { addWebhook } = await import("./webhooks-
|
|
3933
|
+
const { addWebhook } = await import("./webhooks-DXr1IoKn.js");
|
|
3843
3934
|
const events = opts.events.split(",").map((s) => s.trim()).filter(Boolean);
|
|
3844
3935
|
const sub = addWebhook(dataDir$15(), url, events, opts.secret);
|
|
3845
3936
|
console.log(success(`Webhook ${sub.id} → ${url} [${events.join(", ")}]`));
|
|
3846
3937
|
});
|
|
3847
3938
|
webhookCommand.command("list").description("List webhook subscriptions").action(async () => {
|
|
3848
|
-
const { loadWebhooks } = await import("./webhooks-
|
|
3939
|
+
const { loadWebhooks } = await import("./webhooks-DXr1IoKn.js");
|
|
3849
3940
|
const subs = loadWebhooks(dataDir$15());
|
|
3850
3941
|
if (subs.length === 0) {
|
|
3851
3942
|
console.log(info("No webhooks configured."));
|
|
@@ -3854,7 +3945,7 @@ webhookCommand.command("list").description("List webhook subscriptions").action(
|
|
|
3854
3945
|
for (const s of subs) console.log(`${s.id} ${s.url} [${s.events.join(", ")}]`);
|
|
3855
3946
|
});
|
|
3856
3947
|
webhookCommand.command("remove <id>").description("Remove a webhook subscription").action(async (id) => {
|
|
3857
|
-
const { removeWebhook } = await import("./webhooks-
|
|
3948
|
+
const { removeWebhook } = await import("./webhooks-DXr1IoKn.js");
|
|
3858
3949
|
if (removeWebhook(dataDir$15(), id)) console.log(success(`Removed ${id}`));
|
|
3859
3950
|
else {
|
|
3860
3951
|
console.error(error(`Not found: ${id}`));
|
|
@@ -3862,7 +3953,7 @@ webhookCommand.command("remove <id>").description("Remove a webhook subscription
|
|
|
3862
3953
|
}
|
|
3863
3954
|
});
|
|
3864
3955
|
webhookCommand.command("retry").description("Re-attempt failed webhook deliveries (replay store)").action(async () => {
|
|
3865
|
-
const { retryFailures } = await import("./webhooks-
|
|
3956
|
+
const { retryFailures } = await import("./webhooks-DXr1IoKn.js");
|
|
3866
3957
|
const r = await retryFailures(dataDir$15());
|
|
3867
3958
|
console.log(info(`Retried ${r.retried}, still failing ${r.stillFailing}.`));
|
|
3868
3959
|
});
|
|
@@ -3879,12 +3970,12 @@ segmentCommand.command("define <name>").description("Define a segment by criteri
|
|
|
3879
3970
|
...opts.minDealValue ? { minDealValue: Number(opts.minDealValue) } : {},
|
|
3880
3971
|
...opts.staleDays ? { staleDays: Number(opts.staleDays) } : {}
|
|
3881
3972
|
};
|
|
3882
|
-
const { defineSegment } = await import("./segments-
|
|
3973
|
+
const { defineSegment } = await import("./segments-DI3LOQNe.js");
|
|
3883
3974
|
defineSegment(dataDir$14(), name, criteria);
|
|
3884
3975
|
console.log(success(`Segment '${name}' defined: ${JSON.stringify(criteria)}`));
|
|
3885
3976
|
});
|
|
3886
3977
|
segmentCommand.command("list").description("List defined segments").action(async () => {
|
|
3887
|
-
const { loadSegments } = await import("./segments-
|
|
3978
|
+
const { loadSegments } = await import("./segments-DI3LOQNe.js");
|
|
3888
3979
|
const segs = loadSegments(dataDir$14());
|
|
3889
3980
|
if (segs.length === 0) {
|
|
3890
3981
|
console.log(info("No segments defined."));
|
|
@@ -3893,7 +3984,7 @@ segmentCommand.command("list").description("List defined segments").action(async
|
|
|
3893
3984
|
for (const s of segs) console.log(`${s.name} ${JSON.stringify(s.criteria)}`);
|
|
3894
3985
|
});
|
|
3895
3986
|
segmentCommand.command("members <name>").description("List customers matching a segment").action(async (name) => {
|
|
3896
|
-
const { loadSegments, evaluateSegment } = await import("./segments-
|
|
3987
|
+
const { loadSegments, evaluateSegment } = await import("./segments-DI3LOQNe.js");
|
|
3897
3988
|
const seg = loadSegments(dataDir$14()).find((s) => s.name === name);
|
|
3898
3989
|
if (!seg) {
|
|
3899
3990
|
console.error(error(`Segment not found: ${name}`));
|
|
@@ -3911,7 +4002,7 @@ function dataDir$13() {
|
|
|
3911
4002
|
}
|
|
3912
4003
|
const identityCommand = new Command("identity").description("Identity resolution / deduplication (CDP)");
|
|
3913
4004
|
identityCommand.command("duplicates").description("Find clusters of likely-duplicate customers (by canonical domain)").action(async () => {
|
|
3914
|
-
const { findDuplicateClusters } = await import("./identity-
|
|
4005
|
+
const { findDuplicateClusters } = await import("./identity-CB7j-Zr1.js");
|
|
3915
4006
|
const clusters = await findDuplicateClusters(dataDir$13());
|
|
3916
4007
|
if (clusters.length === 0) {
|
|
3917
4008
|
console.log(info("No duplicate clusters found."));
|
|
@@ -3943,7 +4034,7 @@ function dataDir$11() {
|
|
|
3943
4034
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3944
4035
|
}
|
|
3945
4036
|
const usageCommand = new Command("usage").description("LLM token usage & cost (per customer)").option("--slug <slug>", "Filter by customer").action(async (opts) => {
|
|
3946
|
-
const { aggregateUsage } = await import("./usage-
|
|
4037
|
+
const { aggregateUsage } = await import("./usage-BVlFlKW_.js");
|
|
3947
4038
|
const agg = aggregateUsage(dataDir$11(), opts.slug ? { slug: opts.slug } : {});
|
|
3948
4039
|
console.log(bold("LLM Usage"));
|
|
3949
4040
|
console.log(`Calls: ${agg.calls}`);
|
|
@@ -3962,7 +4053,7 @@ function dataDir$10() {
|
|
|
3962
4053
|
}
|
|
3963
4054
|
const approvalsCommand = new Command("approvals").description("Human-in-the-loop approval queue");
|
|
3964
4055
|
approvalsCommand.command("list").description("List approvals (default: pending)").option("--status <status>", "pending | approved | rejected", "pending").action(async (opts) => {
|
|
3965
|
-
const { listApprovals } = await import("./approvals-
|
|
4056
|
+
const { listApprovals } = await import("./approvals-CmDT2eUg.js");
|
|
3966
4057
|
const list = listApprovals(dataDir$10(), opts.status);
|
|
3967
4058
|
if (list.length === 0) {
|
|
3968
4059
|
console.log(info(`No ${opts.status} approvals.`));
|
|
@@ -3971,7 +4062,7 @@ approvalsCommand.command("list").description("List approvals (default: pending)"
|
|
|
3971
4062
|
for (const a of list) console.log(`${a.id} ${a.tool} ${a.slug ?? "-"} ${a.requestedAt}`);
|
|
3972
4063
|
});
|
|
3973
4064
|
approvalsCommand.command("approve <id>").description("Approve a pending action").action(async (id) => {
|
|
3974
|
-
const { decideApproval } = await import("./approvals-
|
|
4065
|
+
const { decideApproval } = await import("./approvals-CmDT2eUg.js");
|
|
3975
4066
|
if (decideApproval(dataDir$10(), id, "approved")) console.log(success(`Approved ${id}`));
|
|
3976
4067
|
else {
|
|
3977
4068
|
console.error(error(`Not found: ${id}`));
|
|
@@ -3979,7 +4070,7 @@ approvalsCommand.command("approve <id>").description("Approve a pending action")
|
|
|
3979
4070
|
}
|
|
3980
4071
|
});
|
|
3981
4072
|
approvalsCommand.command("reject <id>").description("Reject a pending action").action(async (id) => {
|
|
3982
|
-
const { decideApproval } = await import("./approvals-
|
|
4073
|
+
const { decideApproval } = await import("./approvals-CmDT2eUg.js");
|
|
3983
4074
|
if (decideApproval(dataDir$10(), id, "rejected")) console.log(success(`Rejected ${id}`));
|
|
3984
4075
|
else {
|
|
3985
4076
|
console.error(error(`Not found: ${id}`));
|
|
@@ -3997,7 +4088,7 @@ policyCommand.command("set <tool> <policy>").description("Set autonomy policy fo
|
|
|
3997
4088
|
process.exitCode = 1;
|
|
3998
4089
|
return;
|
|
3999
4090
|
}
|
|
4000
|
-
const { setPolicy } = await import("./approvals-
|
|
4091
|
+
const { setPolicy } = await import("./approvals-CmDT2eUg.js");
|
|
4001
4092
|
setPolicy(dataDir$10(), tool, policy, opts.slug);
|
|
4002
4093
|
console.log(success(`Policy ${tool}${opts.slug ? `@${opts.slug}` : ""} = ${policy}`));
|
|
4003
4094
|
});
|
|
@@ -4008,7 +4099,7 @@ function dataDir$9() {
|
|
|
4008
4099
|
}
|
|
4009
4100
|
const hygieneCommand = new Command("hygiene").description("Data-quality scanning");
|
|
4010
4101
|
hygieneCommand.command("scan").description("Scan customers for data-quality issues (missing/malformed/duplicate)").action(async () => {
|
|
4011
|
-
const { scanHygiene } = await import("./hygiene-
|
|
4102
|
+
const { scanHygiene } = await import("./hygiene-DzQPnc6P.js");
|
|
4012
4103
|
const issues = await scanHygiene(dataDir$9());
|
|
4013
4104
|
if (issues.length === 0) {
|
|
4014
4105
|
console.log(success("✓ No data-quality issues found."));
|
|
@@ -4034,7 +4125,7 @@ const TYPES = [
|
|
|
4034
4125
|
const memoryCommand = new Command("memory").description("Agent memories (per customer + global)");
|
|
4035
4126
|
memoryCommand.command("add <text>").description("Add a memory (global unless --slug given)").option("--type <type>", "fact | preference | learning | instruction", "fact").option("--slug <slug>", "Customer slug (omit for global)").action(async (text, opts) => {
|
|
4036
4127
|
const type = TYPES.includes(opts.type) ? opts.type : "fact";
|
|
4037
|
-
const { addMemory } = await import("./memory-
|
|
4128
|
+
const { addMemory } = await import("./memory-D8hmgD9d.js");
|
|
4038
4129
|
const m = addMemory(dataDir$8(), {
|
|
4039
4130
|
scope: opts.slug ? "customer" : "global",
|
|
4040
4131
|
...opts.slug ? { slug: opts.slug } : {},
|
|
@@ -4044,7 +4135,7 @@ memoryCommand.command("add <text>").description("Add a memory (global unless --s
|
|
|
4044
4135
|
console.log(success(`Memory ${m.id} stored (${m.scope}${opts.slug ? `:${opts.slug}` : ""}).`));
|
|
4045
4136
|
});
|
|
4046
4137
|
memoryCommand.command("list").description("List memories (global + customer if --slug)").option("--slug <slug>", "Customer slug").action(async (opts) => {
|
|
4047
|
-
const { loadMemories } = await import("./memory-
|
|
4138
|
+
const { loadMemories } = await import("./memory-D8hmgD9d.js");
|
|
4048
4139
|
const mems = loadMemories(dataDir$8(), opts.slug);
|
|
4049
4140
|
if (mems.length === 0) {
|
|
4050
4141
|
console.log(info("No memories."));
|
|
@@ -4053,7 +4144,7 @@ memoryCommand.command("list").description("List memories (global + customer if -
|
|
|
4053
4144
|
for (const m of mems) console.log(`[${m.scope}/${m.type}] ${m.text}`);
|
|
4054
4145
|
});
|
|
4055
4146
|
memoryCommand.command("search <query>").description("Search memories by relevance").option("--slug <slug>", "Customer slug").action(async (query, opts) => {
|
|
4056
|
-
const { searchMemory } = await import("./memory-
|
|
4147
|
+
const { searchMemory } = await import("./memory-D8hmgD9d.js");
|
|
4057
4148
|
const hits = await searchMemory(dataDir$8(), query, opts.slug);
|
|
4058
4149
|
if (hits.length === 0) {
|
|
4059
4150
|
console.log(info("No matching memories."));
|
|
@@ -4068,7 +4159,7 @@ function dataDir$7() {
|
|
|
4068
4159
|
}
|
|
4069
4160
|
const sopCommand = new Command("sop").description("Standard Operating Procedures (global / per customer)");
|
|
4070
4161
|
sopCommand.command("add <title>").description("Add an SOP (global unless --slug given)").option("--triggers <csv>", "Comma-separated trigger keywords", "").option("--body <text>", "SOP body / steps", "").option("--slug <slug>", "Customer slug (omit for global)").action(async (title, opts) => {
|
|
4071
|
-
const { addSop } = await import("./sop-
|
|
4162
|
+
const { addSop } = await import("./sop-D33qTHUb.js");
|
|
4072
4163
|
const triggers = opts.triggers.split(",").map((s) => s.trim()).filter(Boolean);
|
|
4073
4164
|
const s = addSop(dataDir$7(), {
|
|
4074
4165
|
scope: opts.slug ? "customer" : "global",
|
|
@@ -4080,7 +4171,7 @@ sopCommand.command("add <title>").description("Add an SOP (global unless --slug
|
|
|
4080
4171
|
console.log(success(`SOP ${s.id} added (${s.scope}${opts.slug ? `:${opts.slug}` : ""}).`));
|
|
4081
4172
|
});
|
|
4082
4173
|
sopCommand.command("list").description("List SOPs (global + customer if --slug)").option("--slug <slug>", "Customer slug").action(async (opts) => {
|
|
4083
|
-
const { loadSops } = await import("./sop-
|
|
4174
|
+
const { loadSops } = await import("./sop-D33qTHUb.js");
|
|
4084
4175
|
const sops = loadSops(dataDir$7(), opts.slug);
|
|
4085
4176
|
if (sops.length === 0) {
|
|
4086
4177
|
console.log(info("No SOPs."));
|
|
@@ -4089,7 +4180,7 @@ sopCommand.command("list").description("List SOPs (global + customer if --slug)"
|
|
|
4089
4180
|
for (const s of sops) console.log(`[${s.scope}] ${s.title} (${s.triggers.join(", ")})`);
|
|
4090
4181
|
});
|
|
4091
4182
|
sopCommand.command("find <query>").description("Find SOPs relevant to a task").option("--slug <slug>", "Customer slug").action(async (query, opts) => {
|
|
4092
|
-
const { findSops } = await import("./sop-
|
|
4183
|
+
const { findSops } = await import("./sop-D33qTHUb.js");
|
|
4093
4184
|
const hits = await findSops(dataDir$7(), query, opts.slug);
|
|
4094
4185
|
if (hits.length === 0) {
|
|
4095
4186
|
console.log(info("No matching SOPs."));
|
|
@@ -4104,7 +4195,7 @@ function dataDir$6() {
|
|
|
4104
4195
|
}
|
|
4105
4196
|
const toneCommand = new Command("tone").description("Customer tonality profiles (per customer + global)");
|
|
4106
4197
|
toneCommand.command("set").description("Set tone profile (global unless --slug given)").option("--formality <v>", "formal | casual | friendly").option("--language <v>", "Language code, e.g. de | en").option("--do <csv>", "Comma-separated phrases to prefer").option("--dont <csv>", "Comma-separated phrases to avoid").option("--slug <slug>", "Customer slug (omit for global)").action(async (opts) => {
|
|
4107
|
-
const { setTone } = await import("./tone-
|
|
4198
|
+
const { setTone } = await import("./tone-C7bqK69y.js");
|
|
4108
4199
|
setTone(dataDir$6(), {
|
|
4109
4200
|
...opts.formality ? { formality: opts.formality } : {},
|
|
4110
4201
|
...opts.language ? { language: opts.language } : {},
|
|
@@ -4114,7 +4205,7 @@ toneCommand.command("set").description("Set tone profile (global unless --slug g
|
|
|
4114
4205
|
console.log(success(`Tone profile saved (${opts.slug ? `customer:${opts.slug}` : "global"}).`));
|
|
4115
4206
|
});
|
|
4116
4207
|
toneCommand.command("show").description("Show the effective tone profile").option("--slug <slug>", "Customer slug").action(async (opts) => {
|
|
4117
|
-
const { resolveTone, toneInstruction } = await import("./tone-
|
|
4208
|
+
const { resolveTone, toneInstruction } = await import("./tone-C7bqK69y.js");
|
|
4118
4209
|
const profile = resolveTone(dataDir$6(), opts.slug);
|
|
4119
4210
|
console.log(info(JSON.stringify(profile)));
|
|
4120
4211
|
console.log(`instruction: ${toneInstruction(profile) || "(none)"}`);
|
|
@@ -4128,7 +4219,7 @@ const autofillCommand = new Command("autofill").description("Extract structured
|
|
|
4128
4219
|
return;
|
|
4129
4220
|
}
|
|
4130
4221
|
const transcript = fs.readFileSync(file, "utf-8");
|
|
4131
|
-
const { extractAutofill } = await import("./autofill-
|
|
4222
|
+
const { extractAutofill } = await import("./autofill-B9VtlR2j.js");
|
|
4132
4223
|
const result = await extractAutofill(transcript, opts.slug ? { slug: opts.slug } : {});
|
|
4133
4224
|
console.log(info("Extracted fields (review before applying):"));
|
|
4134
4225
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -4139,7 +4230,7 @@ function dataDir$5() {
|
|
|
4139
4230
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4140
4231
|
}
|
|
4141
4232
|
const askCommand = new Command("ask").description("Ask your CRM a natural-language question").argument("<question>", "The question").option("--slug <slug>", "Scope to a customer").action(async (question, opts) => {
|
|
4142
|
-
const { askCrm } = await import("./ask-
|
|
4233
|
+
const { askCrm } = await import("./ask-CDysGnRg.js");
|
|
4143
4234
|
const res = await askCrm(dataDir$5(), question, opts.slug);
|
|
4144
4235
|
if (res.answer) {
|
|
4145
4236
|
console.log(bold("Answer:"));
|
|
@@ -4158,7 +4249,7 @@ function dataDir$4() {
|
|
|
4158
4249
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4159
4250
|
}
|
|
4160
4251
|
const nbaCommand = new Command("nba").description("Next-best-action recommendations for a customer").argument("<slug>", "Customer slug").action(async (slug) => {
|
|
4161
|
-
const { nextBestAction } = await import("./nba-
|
|
4252
|
+
const { nextBestAction } = await import("./nba-DwdfM93s.js");
|
|
4162
4253
|
const actions = await nextBestAction(dataDir$4(), slug);
|
|
4163
4254
|
if (actions.length === 0) {
|
|
4164
4255
|
console.log(info("No recommendations."));
|
|
@@ -4191,12 +4282,12 @@ async function guard(fn) {
|
|
|
4191
4282
|
}
|
|
4192
4283
|
const vaultCommand = new Command("vault").description("Local encrypted credential vault (AES-256-GCM)");
|
|
4193
4284
|
vaultCommand.command("set <name> <value>").description("Store (or overwrite) a secret").action((name, value) => guard(async () => {
|
|
4194
|
-
const { setSecret } = await import("./vault-
|
|
4285
|
+
const { setSecret } = await import("./vault-DxKP4_R2.js");
|
|
4195
4286
|
setSecret(dataDir$3(), masterKey(), name, value);
|
|
4196
4287
|
console.log(success(`Secret '${name}' stored.`));
|
|
4197
4288
|
}));
|
|
4198
4289
|
vaultCommand.command("get <name>").description("Retrieve a secret").action((name) => guard(async () => {
|
|
4199
|
-
const { getSecret } = await import("./vault-
|
|
4290
|
+
const { getSecret } = await import("./vault-DxKP4_R2.js");
|
|
4200
4291
|
const value = getSecret(dataDir$3(), masterKey(), name);
|
|
4201
4292
|
if (value === void 0) {
|
|
4202
4293
|
console.log(info(`No secret named '${name}'.`));
|
|
@@ -4205,7 +4296,7 @@ vaultCommand.command("get <name>").description("Retrieve a secret").action((name
|
|
|
4205
4296
|
console.log(value);
|
|
4206
4297
|
}));
|
|
4207
4298
|
vaultCommand.command("list").description("List secret names (values stay encrypted)").action(() => guard(async () => {
|
|
4208
|
-
const { listSecretKeys } = await import("./vault-
|
|
4299
|
+
const { listSecretKeys } = await import("./vault-DxKP4_R2.js");
|
|
4209
4300
|
const names = listSecretKeys(dataDir$3(), masterKey());
|
|
4210
4301
|
if (names.length === 0) {
|
|
4211
4302
|
console.log(info("Vault is empty."));
|
|
@@ -4214,7 +4305,7 @@ vaultCommand.command("list").description("List secret names (values stay encrypt
|
|
|
4214
4305
|
for (const n of names.sort()) console.log(n);
|
|
4215
4306
|
}));
|
|
4216
4307
|
vaultCommand.command("rm <name>").description("Remove a secret").action((name) => guard(async () => {
|
|
4217
|
-
const { removeSecret } = await import("./vault-
|
|
4308
|
+
const { removeSecret } = await import("./vault-DxKP4_R2.js");
|
|
4218
4309
|
const removed = removeSecret(dataDir$3(), masterKey(), name);
|
|
4219
4310
|
console.log(removed ? success(`Secret '${name}' removed.`) : info(`No secret named '${name}'.`));
|
|
4220
4311
|
}));
|
|
@@ -4230,13 +4321,13 @@ function paint(level, text) {
|
|
|
4230
4321
|
}
|
|
4231
4322
|
const churnCommand = new Command("churn").description("Churn early-warning (relationship-health based)");
|
|
4232
4323
|
churnCommand.command("assess <slug>").description("Assess churn risk for one customer").action(async (slug) => {
|
|
4233
|
-
const { assessChurn } = await import("./churn-
|
|
4324
|
+
const { assessChurn } = await import("./churn-DN9WDGNM.js");
|
|
4234
4325
|
const r = assessChurn(dataDir$2(), slug);
|
|
4235
4326
|
console.log(paint(r.level, `${slug}: ${r.level.toUpperCase()} risk (${r.riskScore}/100)`));
|
|
4236
4327
|
for (const s of r.signals) console.log(` • ${s}`);
|
|
4237
4328
|
});
|
|
4238
4329
|
churnCommand.command("scan").description("Rank all customers by churn risk (highest first)").action(async () => {
|
|
4239
|
-
const { scanChurn } = await import("./churn-
|
|
4330
|
+
const { scanChurn } = await import("./churn-DN9WDGNM.js");
|
|
4240
4331
|
const ranked = scanChurn(dataDir$2());
|
|
4241
4332
|
if (ranked.length === 0) {
|
|
4242
4333
|
console.log(info("No customers to assess."));
|
|
@@ -4251,7 +4342,7 @@ function dataDir$1() {
|
|
|
4251
4342
|
}
|
|
4252
4343
|
const leadscoreCommand = new Command("leadscore").description("Predictive lead scoring (logistic regression on won/lost history)");
|
|
4253
4344
|
leadscoreCommand.command("train").description("Train the model from won/lost history and persist it").action(async () => {
|
|
4254
|
-
const { buildLeadModel, saveLeadModel } = await import("./lead-model-
|
|
4345
|
+
const { buildLeadModel, saveLeadModel } = await import("./lead-model-CEmx7te7.js");
|
|
4255
4346
|
const model = buildLeadModel(dataDir$1());
|
|
4256
4347
|
if (!model.sufficient) {
|
|
4257
4348
|
console.log(warning(`Not enough closed history to train (${model.trainedOn} deals, need ≥4 with both outcomes).`));
|
|
@@ -4262,8 +4353,8 @@ leadscoreCommand.command("train").description("Train the model from won/lost his
|
|
|
4262
4353
|
console.log(success(`Trained on ${model.trainedOn} closed deals. Model saved.`));
|
|
4263
4354
|
});
|
|
4264
4355
|
leadscoreCommand.command("predict <slug>").description("Score a customer's open deals with the trained model").action(async (slug) => {
|
|
4265
|
-
const { loadLeadModel, buildLeadModel, predictWin } = await import("./lead-model-
|
|
4266
|
-
const { readPipelineSync } = await import("./pipeline-writer-
|
|
4356
|
+
const { loadLeadModel, buildLeadModel, predictWin } = await import("./lead-model-CEmx7te7.js");
|
|
4357
|
+
const { readPipelineSync } = await import("./pipeline-writer-0LJ6Qkat.js");
|
|
4267
4358
|
const model = loadLeadModel(dataDir$1()) ?? buildLeadModel(dataDir$1());
|
|
4268
4359
|
const open = readPipelineSync(dataDir$1(), slug).filter((d) => d.stage !== "won" && d.stage !== "lost");
|
|
4269
4360
|
if (open.length === 0) {
|
|
@@ -4283,7 +4374,7 @@ function dataDir() {
|
|
|
4283
4374
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4284
4375
|
}
|
|
4285
4376
|
const enrichCommand = new Command("enrich").description("Enrich a customer's facts (offline domain-from-email + plugins)").argument("<slug>", "Customer slug").option("--write", "Write newly-derived fields back to main_facts.md").action(async (slug, opts) => {
|
|
4286
|
-
const { enrichCustomer } = await import("./enrichment-
|
|
4377
|
+
const { enrichCustomer } = await import("./enrichment-CDFdWmvD.js");
|
|
4287
4378
|
const res = await enrichCustomer(dataDir(), slug, { write: opts.write ?? false });
|
|
4288
4379
|
const applied = Object.entries(res.applied);
|
|
4289
4380
|
if (applied.length === 0) {
|
|
@@ -4318,7 +4409,7 @@ const coachCommand = new Command("coach").description("Conversation-intelligence
|
|
|
4318
4409
|
//#region src/commands/compliance.ts
|
|
4319
4410
|
const complianceCommand = new Command("compliance").description("Privacy/compliance posture (AI-Act Art. 50, local-LLM, PII, guardrails)");
|
|
4320
4411
|
complianceCommand.command("status", { isDefault: true }).description("Show the active compliance configuration").action(async () => {
|
|
4321
|
-
const { complianceConfig, aiDisclosure } = await import("./compliance-
|
|
4412
|
+
const { complianceConfig, aiDisclosure } = await import("./compliance-TqYQXhBj.js");
|
|
4322
4413
|
const cfg = complianceConfig();
|
|
4323
4414
|
const onOff = (b) => b ? success("on") : warning("off");
|
|
4324
4415
|
console.log(info("Compliance posture"));
|
|
@@ -4334,61 +4425,69 @@ complianceCommand.command("status", { isDefault: true }).description("Show the a
|
|
|
4334
4425
|
if (cfg.aiDisclosure) console.log(info(` Disclosure: "${aiDisclosure()}"`));
|
|
4335
4426
|
});
|
|
4336
4427
|
//#endregion
|
|
4428
|
+
//#region src/commands/registry.ts
|
|
4429
|
+
/** Every top-level `dxcrm` command, in display order. */
|
|
4430
|
+
const ALL_COMMANDS = [
|
|
4431
|
+
initCommand,
|
|
4432
|
+
createCommand,
|
|
4433
|
+
listCommand,
|
|
4434
|
+
validateCommand,
|
|
4435
|
+
sessionCommand,
|
|
4436
|
+
guideCommand,
|
|
4437
|
+
mcpCommand,
|
|
4438
|
+
syncCommand,
|
|
4439
|
+
backupCommand,
|
|
4440
|
+
restoreCommand,
|
|
4441
|
+
daemonCommand,
|
|
4442
|
+
statusCommand,
|
|
4443
|
+
agentCommand,
|
|
4444
|
+
importCommand,
|
|
4445
|
+
serverCommand,
|
|
4446
|
+
auditCommand,
|
|
4447
|
+
logsCommand,
|
|
4448
|
+
doctorCommand,
|
|
4449
|
+
rbacCommand,
|
|
4450
|
+
gdprCommand,
|
|
4451
|
+
securityReportCommand,
|
|
4452
|
+
stagesCommand,
|
|
4453
|
+
pluginCommand,
|
|
4454
|
+
goalCommand,
|
|
4455
|
+
pushCommand,
|
|
4456
|
+
attachCommand,
|
|
4457
|
+
templateCommand,
|
|
4458
|
+
sequenceCommand,
|
|
4459
|
+
quoteCommand,
|
|
4460
|
+
ticketCommand,
|
|
4461
|
+
surveyCommand,
|
|
4462
|
+
kbCommand,
|
|
4463
|
+
fieldsCommand,
|
|
4464
|
+
objectCommand,
|
|
4465
|
+
webhookCommand,
|
|
4466
|
+
segmentCommand,
|
|
4467
|
+
identityCommand,
|
|
4468
|
+
metricsCommand,
|
|
4469
|
+
usageCommand,
|
|
4470
|
+
approvalsCommand,
|
|
4471
|
+
policyCommand,
|
|
4472
|
+
hygieneCommand,
|
|
4473
|
+
memoryCommand,
|
|
4474
|
+
sopCommand,
|
|
4475
|
+
toneCommand,
|
|
4476
|
+
autofillCommand,
|
|
4477
|
+
askCommand,
|
|
4478
|
+
nbaCommand,
|
|
4479
|
+
vaultCommand,
|
|
4480
|
+
churnCommand,
|
|
4481
|
+
leadscoreCommand,
|
|
4482
|
+
enrichCommand,
|
|
4483
|
+
coachCommand,
|
|
4484
|
+
complianceCommand
|
|
4485
|
+
];
|
|
4486
|
+
//#endregion
|
|
4337
4487
|
//#region src/cli.ts
|
|
4338
4488
|
const program = new Command();
|
|
4339
4489
|
program.name("dxcrm").description("DatasynxOpenCRM — local-first, MCP-native CRM").version("0.1.0").exitOverride();
|
|
4340
|
-
program.addCommand(
|
|
4341
|
-
program.addCommand(createCommand);
|
|
4342
|
-
program.addCommand(listCommand);
|
|
4343
|
-
program.addCommand(validateCommand);
|
|
4344
|
-
program.addCommand(sessionCommand);
|
|
4345
|
-
program.addCommand(guideCommand);
|
|
4346
|
-
program.addCommand(mcpCommand);
|
|
4347
|
-
program.addCommand(syncCommand);
|
|
4348
|
-
program.addCommand(backupCommand);
|
|
4349
|
-
program.addCommand(restoreCommand);
|
|
4350
|
-
program.addCommand(daemonCommand);
|
|
4351
|
-
program.addCommand(statusCommand);
|
|
4352
|
-
program.addCommand(agentCommand);
|
|
4353
|
-
program.addCommand(importCommand);
|
|
4354
|
-
program.addCommand(serverCommand);
|
|
4355
|
-
program.addCommand(auditCommand);
|
|
4356
|
-
program.addCommand(rbacCommand);
|
|
4357
|
-
program.addCommand(gdprCommand);
|
|
4358
|
-
program.addCommand(securityReportCommand);
|
|
4359
|
-
program.addCommand(stagesCommand);
|
|
4360
|
-
program.addCommand(pluginCommand);
|
|
4361
|
-
program.addCommand(goalCommand);
|
|
4362
|
-
program.addCommand(pushCommand);
|
|
4363
|
-
program.addCommand(attachCommand);
|
|
4364
|
-
program.addCommand(templateCommand);
|
|
4365
|
-
program.addCommand(sequenceCommand);
|
|
4366
|
-
program.addCommand(quoteCommand);
|
|
4367
|
-
program.addCommand(ticketCommand);
|
|
4368
|
-
program.addCommand(surveyCommand);
|
|
4369
|
-
program.addCommand(kbCommand);
|
|
4370
|
-
program.addCommand(fieldsCommand);
|
|
4371
|
-
program.addCommand(objectCommand);
|
|
4372
|
-
program.addCommand(webhookCommand);
|
|
4373
|
-
program.addCommand(segmentCommand);
|
|
4374
|
-
program.addCommand(identityCommand);
|
|
4375
|
-
program.addCommand(metricsCommand);
|
|
4376
|
-
program.addCommand(usageCommand);
|
|
4377
|
-
program.addCommand(approvalsCommand);
|
|
4378
|
-
program.addCommand(policyCommand);
|
|
4379
|
-
program.addCommand(hygieneCommand);
|
|
4380
|
-
program.addCommand(memoryCommand);
|
|
4381
|
-
program.addCommand(sopCommand);
|
|
4382
|
-
program.addCommand(toneCommand);
|
|
4383
|
-
program.addCommand(autofillCommand);
|
|
4384
|
-
program.addCommand(askCommand);
|
|
4385
|
-
program.addCommand(nbaCommand);
|
|
4386
|
-
program.addCommand(vaultCommand);
|
|
4387
|
-
program.addCommand(churnCommand);
|
|
4388
|
-
program.addCommand(leadscoreCommand);
|
|
4389
|
-
program.addCommand(enrichCommand);
|
|
4390
|
-
program.addCommand(coachCommand);
|
|
4391
|
-
program.addCommand(complianceCommand);
|
|
4490
|
+
for (const command of ALL_COMMANDS) program.addCommand(command);
|
|
4392
4491
|
await program.parseAsync(process.argv);
|
|
4393
4492
|
//#endregion
|
|
4394
4493
|
export {};
|