@datasynx/agentic-crm 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +264 -670
- package/dist/{approvals-DpjxGHFp.js → approvals-CmDT2eUg.js} +7 -24
- package/dist/approvals-CmDT2eUg.js.map +1 -0
- package/dist/{ask-CID3jnuL.js → ask-D8iYqDAr.js} +6 -6
- package/dist/{ask-CID3jnuL.js.map → ask-D8iYqDAr.js.map} +1 -1
- package/dist/atomic-write-8yjqqLtS.js +29 -0
- package/dist/atomic-write-8yjqqLtS.js.map +1 -0
- package/dist/atomic-write-BYmF-ThH.cjs +37 -0
- package/dist/atomic-write-BYmF-ThH.cjs.map +1 -0
- package/dist/auth-B5DcjJ_6.js +2 -0
- package/dist/{auth-DFWwWcYD.js → auth-DDXZTwS0.js} +4 -13
- package/dist/auth-DDXZTwS0.js.map +1 -0
- package/dist/{autofill-Di_-SP7t.js → autofill-B9VtlR2j.js} +2 -2
- package/dist/{autofill-Di_-SP7t.js.map → autofill-B9VtlR2j.js.map} +1 -1
- package/dist/{backup-CeMk9z86.js → backup-CTlIxUdO.js} +5 -7
- package/dist/backup-CTlIxUdO.js.map +1 -0
- package/dist/backup-LFnC09oV.js +2 -0
- package/dist/{churn-C28IgnAj.js → churn-DN9WDGNM.js} +3 -3
- package/dist/{churn-C28IgnAj.js.map → churn-DN9WDGNM.js.map} +1 -1
- package/dist/cli.js +282 -184
- package/dist/cli.js.map +1 -1
- package/dist/{compliance-CKSBoQUe.js → compliance-Bc12Hn9a.js} +3 -3
- package/dist/{compliance-CKSBoQUe.js.map → compliance-Bc12Hn9a.js.map} +1 -1
- package/dist/{compliance-CujOqAKk.js → compliance-TqYQXhBj.js} +1 -1
- package/dist/{compliance-B1kk5-YS.js → compliance-kq0xHRw3.js} +3 -3
- package/dist/{compliance-B1kk5-YS.js.map → compliance-kq0xHRw3.js.map} +1 -1
- package/dist/{compliance-B91zNvCR.cjs → compliance-pAj9FcGI.cjs} +3 -3
- package/dist/{compliance-B91zNvCR.cjs.map → compliance-pAj9FcGI.cjs.map} +1 -1
- package/dist/{context-builder-BzWAp3Zs.js → context-builder-7Uab5-G4.js} +3 -2
- package/dist/context-builder-7Uab5-G4.js.map +1 -0
- package/dist/context-builder-hmOPvgso.js +2 -0
- package/dist/{custom-fields-CzNeD3_v.js → custom-fields-BMyz5Ruh.js} +1 -1
- package/dist/{custom-fields-Pl2t9xzp.js → custom-fields-GzpOHW_2.js} +4 -13
- package/dist/custom-fields-GzpOHW_2.js.map +1 -0
- package/dist/{custom-objects-CIFrmQ2V.js → custom-objects-BNy-ayR-.js} +1 -1
- package/dist/{custom-objects-BHgn1GEX.js → custom-objects-CxW1gHwJ.js} +10 -25
- package/dist/custom-objects-CxW1gHwJ.js.map +1 -0
- package/dist/{customer-dir-DIylZ8Q6.js → customer-dir-CkMMXhb0.js} +9 -4
- package/dist/customer-dir-CkMMXhb0.js.map +1 -0
- package/dist/daemon/worker.js +66 -40
- package/dist/daemon/worker.js.map +1 -1
- package/dist/doctor-C14-vnJ1.js +103 -0
- package/dist/doctor-C14-vnJ1.js.map +1 -0
- package/dist/{enrichment-3XvgGDfB.js → enrichment-CDFdWmvD.js} +3 -3
- package/dist/{enrichment-3XvgGDfB.js.map → enrichment-CDFdWmvD.js.map} +1 -1
- package/dist/{file-lock-B_zi7NQl.js → file-lock-CcHotQkZ.js} +3 -4
- package/dist/file-lock-CcHotQkZ.js.map +1 -0
- package/dist/{gmail-sync-rQaVqKWd.js → gmail-sync-C-NmibzS.js} +13 -9
- package/dist/gmail-sync-C-NmibzS.js.map +1 -0
- package/dist/{gmail-sync-DIaxInDT.js → gmail-sync-DueE6tl5.js} +14 -10
- package/dist/gmail-sync-DueE6tl5.js.map +1 -0
- package/dist/{gmail-sync-hHm9gaWd.cjs → gmail-sync-GEy3oVvw.cjs} +13 -9
- package/dist/gmail-sync-GEy3oVvw.cjs.map +1 -0
- package/dist/{gmail-webhook-handler-DS7OlRPX.js → gmail-webhook-handler-B26COilD.js} +2 -2
- package/dist/{gmail-webhook-handler-e5Od25FX.js → gmail-webhook-handler-kGKpbY9h.js} +4 -4
- package/dist/{gmail-webhook-handler-e5Od25FX.js.map → gmail-webhook-handler-kGKpbY9h.js.map} +1 -1
- package/dist/{goal-engine-KpBftn4V.js → goal-engine-BbroPhqm.js} +10 -11
- package/dist/goal-engine-BbroPhqm.js.map +1 -0
- package/dist/{goal-engine-CUZSpERI.js → goal-engine-CfDAJTFt.js} +1 -1
- package/dist/{google-drive-sync-DEPcqFca.js → google-drive-sync-D1n7WKZn.js} +3 -3
- package/dist/{google-drive-sync-DEPcqFca.js.map → google-drive-sync-D1n7WKZn.js.map} +1 -1
- package/dist/{hygiene-DZqfYpFf.js → hygiene-DzQPnc6P.js} +3 -3
- package/dist/{hygiene-DZqfYpFf.js.map → hygiene-DzQPnc6P.js.map} +1 -1
- package/dist/identity-CB7j-Zr1.js +2 -0
- package/dist/{identity-CI6olMNm.js → identity-_uZ3Lbr2.js} +2 -2
- package/dist/{identity-CI6olMNm.js.map → identity-_uZ3Lbr2.js.map} +1 -1
- package/dist/{import-hubspot-BaK71U_K.js → import-hubspot-DB4n89jy.js} +51 -45
- package/dist/import-hubspot-DB4n89jy.js.map +1 -0
- package/dist/{index-V8BFaH-b.d.ts → index-B0IMMrp_.d.ts} +8 -4
- package/dist/{index-V8BFaH-b.d.ts.map → index-B0IMMrp_.d.ts.map} +1 -1
- package/dist/{index-YqwMd6aQ.d.cts → index-pY7tYXwH.d.cts} +8 -4
- package/dist/{index-YqwMd6aQ.d.cts.map → index-pY7tYXwH.d.cts.map} +1 -1
- package/dist/index.cjs +19 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -21
- package/dist/index.js.map +1 -1
- package/dist/{interactions-writer-DO3KcSR3.js → interactions-writer-BZzUIgJd.js} +5 -2
- package/dist/interactions-writer-BZzUIgJd.js.map +1 -0
- package/dist/{interactions-writer-SLHnoEeE.js → interactions-writer-DbSyI2rt.js} +32 -3
- package/dist/interactions-writer-DbSyI2rt.js.map +1 -0
- package/dist/interactions-writer-RJB8SWf2.js +2 -0
- package/dist/{interactions-writer-CrPStUll.cjs → interactions-writer-a2yzBd7T.cjs} +5 -2
- package/dist/interactions-writer-a2yzBd7T.cjs.map +1 -0
- package/dist/json-store-WWsFzXub.js +43 -0
- package/dist/json-store-WWsFzXub.js.map +1 -0
- package/dist/{knowledge-base-D0Fh40kc.js → knowledge-base-DHNc4hVj.js} +43 -16
- package/dist/knowledge-base-DHNc4hVj.js.map +1 -0
- package/dist/{lancedb-CCBbpulq.js → lancedb-CswQEE5K.js} +1 -1
- package/dist/{lancedb-rlvWoPwl.js → lancedb-CuHKNsNZ.js} +4 -3
- package/dist/lancedb-CuHKNsNZ.js.map +1 -0
- package/dist/{lead-model-BCFzyktm.js → lead-model-CEmx7te7.js} +6 -14
- package/dist/lead-model-CEmx7te7.js.map +1 -0
- package/dist/{llm-Z8RIYkpF.js → llm-BnSUBisu.js} +2 -2
- package/dist/{llm-Z8RIYkpF.js.map → llm-BnSUBisu.js.map} +1 -1
- package/dist/{llm-iijeXmgq.cjs → llm-CXycmEl9.cjs} +2 -2
- package/dist/{llm-iijeXmgq.cjs.map → llm-CXycmEl9.cjs.map} +1 -1
- package/dist/{llm-DEjWcqmW.js → llm-DSX1-wFu.js} +1 -1
- package/dist/{llm-DvzZqva0.js → llm-PZzgPphl.js} +3 -3
- package/dist/{llm-DvzZqva0.js.map → llm-PZzgPphl.js.map} +1 -1
- package/dist/logger-BkInaGoV.cjs +167 -0
- package/dist/logger-BkInaGoV.cjs.map +1 -0
- package/dist/logger-Dyl4VcLO.js +147 -0
- package/dist/logger-Dyl4VcLO.js.map +1 -0
- package/dist/logger-UaF5p9d1.js +147 -0
- package/dist/logger-UaF5p9d1.js.map +1 -0
- package/dist/logger-vKQS34w9.js +2 -0
- package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
- package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
- package/dist/mcp.cjs +327 -303
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.d.cts.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +327 -303
- package/dist/mcp.js.map +1 -1
- package/dist/{memory-Cy6-Tbyl.js → memory-D8hmgD9d.js} +1 -1
- package/dist/{memory-Bb6ky3kb.js → memory-Dzr9dXSM.js} +4 -11
- package/dist/memory-Dzr9dXSM.js.map +1 -0
- package/dist/{microsoft-calendar-B6MMtUQK.js → microsoft-calendar-jIu9K5zX.js} +4 -4
- package/dist/{microsoft-calendar-B6MMtUQK.js.map → microsoft-calendar-jIu9K5zX.js.map} +1 -1
- package/dist/{microsoft-sync-CpZVoSuq.js → microsoft-sync-R_r8HL-B.js} +5 -5
- package/dist/{microsoft-sync-CpZVoSuq.js.map → microsoft-sync-R_r8HL-B.js.map} +1 -1
- package/dist/{nba-3wanmJ0U.js → nba-mTJ4yEqD.js} +3 -3
- package/dist/{nba-3wanmJ0U.js.map → nba-mTJ4yEqD.js.map} +1 -1
- package/dist/{notification-dispatcher-0vYNngWe.js → notification-dispatcher-inpKyuBz.js} +7 -3
- package/dist/notification-dispatcher-inpKyuBz.js.map +1 -0
- package/dist/{pipeline-writer-BqBrYrQc.js → pipeline-writer-0LJ6Qkat.js} +1 -1
- package/dist/{pipeline-writer-N2omexxp.cjs → pipeline-writer-B1tRAhuD.cjs} +11 -3
- package/dist/pipeline-writer-B1tRAhuD.cjs.map +1 -0
- package/dist/{pipeline-writer-BvVquKIe.js → pipeline-writer-CIllfnZl.js} +5 -3
- package/dist/pipeline-writer-CIllfnZl.js.map +1 -0
- package/dist/{pipeline-writer-eufx_0o1.js → pipeline-writer-rDj-ni6q.js} +6 -4
- package/dist/pipeline-writer-rDj-ni6q.js.map +1 -0
- package/dist/{proactive-agent-BgQXw3ac.js → proactive-agent-B7u3Bj_l.js} +6 -6
- package/dist/{proactive-agent-BgQXw3ac.js.map → proactive-agent-B7u3Bj_l.js.map} +1 -1
- package/dist/{proactive-worker-BrLHNhjH.js → proactive-worker-1zkm6aJD.js} +7 -8
- package/dist/proactive-worker-1zkm6aJD.js.map +1 -0
- package/dist/{push-manager-CowY-0IK.js → push-manager-BXM-IHfP.js} +1 -1
- package/dist/{push-manager-CdqIIkuh.js → push-manager-C0ECQgva.js} +4 -4
- package/dist/push-manager-C0ECQgva.js.map +1 -0
- package/dist/{quote-generator-OhSFsi3x.js → quote-generator-ByUyIYtw.js} +1 -1
- package/dist/{quote-generator-BfwENXzg.js → quote-generator-CTdR8eEI.js} +5 -5
- package/dist/quote-generator-CTdR8eEI.js.map +1 -0
- package/dist/rbac-DzbyFhVH.js +2 -0
- package/dist/{rbac-CTIktZaC.js → rbac-msmBc_tK.js} +19 -12
- package/dist/rbac-msmBc_tK.js.map +1 -0
- package/dist/regex-Jt5DatPi.js +13 -0
- package/dist/regex-Jt5DatPi.js.map +1 -0
- package/dist/{relationship-health-odxEoQdJ.js → relationship-health-ZZNXR1RZ.js} +8 -16
- package/dist/relationship-health-ZZNXR1RZ.js.map +1 -0
- package/dist/{revenue-simulation-Bqf2DLVB.js → revenue-simulation-D8f_YkUY.js} +9 -19
- package/dist/revenue-simulation-D8f_YkUY.js.map +1 -0
- package/dist/{revenue-simulation-BJdRTEHc.js → revenue-simulation-njJZlTqm.js} +1 -1
- package/dist/safe-path-mpp0dKtO.js +18 -0
- package/dist/safe-path-mpp0dKtO.js.map +1 -0
- package/dist/{segments-BqcD5HIl.js → segments-DI3LOQNe.js} +5 -14
- package/dist/segments-DI3LOQNe.js.map +1 -0
- package/dist/sequence-engine-C6nnewHX.js +2 -0
- package/dist/{sequence-engine-J1lTW_in.js → sequence-engine-DNTVLq7o.js} +15 -8
- package/dist/sequence-engine-DNTVLq7o.js.map +1 -0
- package/dist/{sequence-store-DaaWr0Os.js → sequence-store-CmYb6s0g.js} +6 -5
- package/dist/sequence-store-CmYb6s0g.js.map +1 -0
- package/dist/{server-Dyva03K8.js → server-DqSMYhSA.js} +278 -220
- package/dist/server-DqSMYhSA.js.map +1 -0
- package/dist/{session-D9ub6Wl1.js → session-B6XaP83h.js} +3 -3
- package/dist/session-B6XaP83h.js.map +1 -0
- package/dist/{session-B9AilxOE.js → session-BgGDyP2C.js} +3 -3
- package/dist/session-BgGDyP2C.js.map +1 -0
- package/dist/session-Bp4zTh4l.js +2 -0
- package/dist/{session-D0qFkBla.cjs → session-Mm7GQbSH.cjs} +3 -3
- package/dist/session-Mm7GQbSH.cjs.map +1 -0
- package/dist/{session-store-C8tEvMPw.js → session-store-DWxJ5Pof.js} +79 -17
- package/dist/session-store-DWxJ5Pof.js.map +1 -0
- package/dist/{session-store-B0QZE8Bx.cjs → session-store-yfwnj0OC.cjs} +126 -16
- package/dist/session-store-yfwnj0OC.cjs.map +1 -0
- package/dist/{sla-engine-5IhTsBUR.js → sla-engine-CP2KiKDS.js} +1 -1
- package/dist/{sla-engine-BqX-7u-7.js → sla-engine-O-A1ntu_.js} +2 -2
- package/dist/{sla-engine-BqX-7u-7.js.map → sla-engine-O-A1ntu_.js.map} +1 -1
- package/dist/{sop-Vp0UPWFW.js → sop-BV7ICAFR.js} +4 -11
- package/dist/sop-BV7ICAFR.js.map +1 -0
- package/dist/{sop-DkhVChGy.js → sop-D33qTHUb.js} +1 -1
- package/dist/survey-engine-DKctGcLQ.js +2 -0
- package/dist/{survey-engine-DBjCYqCv.js → survey-engine-DngXBv47.js} +5 -4
- package/dist/survey-engine-DngXBv47.js.map +1 -0
- package/dist/{sync-state-CwLSt_1m.js → sync-state-BaA8LbTI.js} +1 -1
- package/dist/{sync-state-ChaLbamC.js → sync-state-DMZgzpez.js} +4 -12
- package/dist/sync-state-DMZgzpez.js.map +1 -0
- package/dist/{ticket-writer-CjqKeIRD.js → ticket-writer-DsfpeLGZ.js} +1 -1
- package/dist/{ticket-writer-j2oX_Wal.js → ticket-writer-a9on36Wb.js} +12 -24
- package/dist/ticket-writer-a9on36Wb.js.map +1 -0
- package/dist/{tone-Bdm5uaht.js → tone-C7bqK69y.js} +5 -12
- package/dist/tone-C7bqK69y.js.map +1 -0
- package/dist/{tone-DRKlZgPr.cjs → tone-Cmc7O2Fx.cjs} +3 -9
- package/dist/tone-Cmc7O2Fx.cjs.map +1 -0
- package/dist/{tone-vNb2DAAD.js → tone-mXSftvTn.js} +3 -8
- package/dist/tone-mXSftvTn.js.map +1 -0
- package/dist/{transcript-watcher-CL2QUygI.js → transcript-watcher-0mh2ZhmH.js} +18 -11
- package/dist/transcript-watcher-0mh2ZhmH.js.map +1 -0
- package/dist/unmatched-transcripts-C92zAoM4.js +2 -0
- package/dist/unmatched-transcripts-DC-VQ9YS.js +16 -0
- package/dist/unmatched-transcripts-DC-VQ9YS.js.map +1 -0
- package/dist/update-deal-CWy1eLJI.js +2 -0
- package/dist/{update-deal-DKC79skb.js → update-deal-DSzr_Aau.js} +3 -3
- package/dist/{update-deal-DKC79skb.js.map → update-deal-DSzr_Aau.js.map} +1 -1
- package/dist/{usage-D0-TYJkw.js → usage-BVlFlKW_.js} +8 -6
- package/dist/usage-BVlFlKW_.js.map +1 -0
- package/dist/usage-CClTf5e6.cjs.map +1 -1
- package/dist/usage-D0u9a-lV.js.map +1 -1
- package/dist/{vault-DXCg29W-.js → vault-CfwZdNzC.js} +3 -4
- package/dist/vault-CfwZdNzC.js.map +1 -0
- package/dist/{vault-C1D3zScD.js → vault-DxKP4_R2.js} +1 -1
- package/dist/{webhooks-Xn6zO6kd.cjs → webhooks-CwW-3kvG.cjs} +5 -19
- package/dist/webhooks-CwW-3kvG.cjs.map +1 -0
- package/dist/{webhooks-7EpA05Qr.js → webhooks-DXr1IoKn.js} +8 -21
- package/dist/webhooks-DXr1IoKn.js.map +1 -0
- package/dist/{webhooks-BO2UAnmn.js → webhooks-sWZ8CJtR.js} +5 -18
- package/dist/webhooks-sWZ8CJtR.js.map +1 -0
- package/package.json +11 -2
- package/dist/approvals-DpjxGHFp.js.map +0 -1
- package/dist/auth-CyFuu9X_.js +0 -2
- package/dist/auth-DFWwWcYD.js.map +0 -1
- package/dist/backup-CeMk9z86.js.map +0 -1
- package/dist/backup-f_hC7rBV.js +0 -2
- package/dist/context-builder-BzWAp3Zs.js.map +0 -1
- package/dist/context-builder-DlrRcqmJ.js +0 -2
- package/dist/custom-fields-Pl2t9xzp.js.map +0 -1
- package/dist/custom-objects-BHgn1GEX.js.map +0 -1
- package/dist/customer-dir-DIylZ8Q6.js.map +0 -1
- package/dist/file-lock-B_zi7NQl.js.map +0 -1
- package/dist/gmail-sync-DIaxInDT.js.map +0 -1
- package/dist/gmail-sync-hHm9gaWd.cjs.map +0 -1
- package/dist/gmail-sync-rQaVqKWd.js.map +0 -1
- package/dist/goal-engine-KpBftn4V.js.map +0 -1
- package/dist/identity-gyfWdrcX.js +0 -2
- package/dist/import-hubspot-BaK71U_K.js.map +0 -1
- package/dist/interactions-writer-CrPStUll.cjs.map +0 -1
- package/dist/interactions-writer-DO3KcSR3.js.map +0 -1
- package/dist/interactions-writer-SLHnoEeE.js.map +0 -1
- package/dist/interactions-writer-dSPy1XfO.js +0 -2
- package/dist/knowledge-base-D0Fh40kc.js.map +0 -1
- package/dist/lancedb-rlvWoPwl.js.map +0 -1
- package/dist/lead-model-BCFzyktm.js.map +0 -1
- package/dist/memory-Bb6ky3kb.js.map +0 -1
- package/dist/notification-dispatcher-0vYNngWe.js.map +0 -1
- package/dist/pipeline-writer-BvVquKIe.js.map +0 -1
- package/dist/pipeline-writer-N2omexxp.cjs.map +0 -1
- package/dist/pipeline-writer-eufx_0o1.js.map +0 -1
- package/dist/proactive-worker-BrLHNhjH.js.map +0 -1
- package/dist/push-manager-CdqIIkuh.js.map +0 -1
- package/dist/quote-generator-BfwENXzg.js.map +0 -1
- package/dist/rbac-C7c8tcES.js +0 -2
- package/dist/rbac-CTIktZaC.js.map +0 -1
- package/dist/relationship-health-odxEoQdJ.js.map +0 -1
- package/dist/revenue-simulation-Bqf2DLVB.js.map +0 -1
- package/dist/segments-BqcD5HIl.js.map +0 -1
- package/dist/sequence-engine-CCTHEBgi.js +0 -2
- package/dist/sequence-engine-J1lTW_in.js.map +0 -1
- package/dist/sequence-store-DaaWr0Os.js.map +0 -1
- package/dist/server-Dyva03K8.js.map +0 -1
- package/dist/session-B9AilxOE.js.map +0 -1
- package/dist/session-D0qFkBla.cjs.map +0 -1
- package/dist/session-D9ub6Wl1.js.map +0 -1
- package/dist/session-mWHA71Lw.js +0 -2
- package/dist/session-store-B0QZE8Bx.cjs.map +0 -1
- package/dist/session-store-C8tEvMPw.js.map +0 -1
- package/dist/sop-Vp0UPWFW.js.map +0 -1
- package/dist/survey-engine-C06hcQt3.js +0 -2
- package/dist/survey-engine-DBjCYqCv.js.map +0 -1
- package/dist/sync-state-ChaLbamC.js.map +0 -1
- package/dist/ticket-writer-j2oX_Wal.js.map +0 -1
- package/dist/tone-Bdm5uaht.js.map +0 -1
- package/dist/tone-DRKlZgPr.cjs.map +0 -1
- package/dist/tone-vNb2DAAD.js.map +0 -1
- package/dist/transcript-watcher-CL2QUygI.js.map +0 -1
- package/dist/unmatched-transcripts-BsH5bhkU.js +0 -26
- package/dist/unmatched-transcripts-BsH5bhkU.js.map +0 -1
- package/dist/unmatched-transcripts-D0PrJ9iz.js +0 -2
- package/dist/update-deal-BNwPGaTV.js +0 -2
- package/dist/usage-D0-TYJkw.js.map +0 -1
- package/dist/vault-DXCg29W-.js.map +0 -1
- package/dist/webhooks-7EpA05Qr.js.map +0 -1
- package/dist/webhooks-BO2UAnmn.js.map +0 -1
- package/dist/webhooks-Xn6zO6kd.cjs.map +0 -1
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-DHNc4hVj.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-DbSyI2rt.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-DqSMYhSA.js");
|
|
245
244
|
await startHttp(port);
|
|
246
245
|
} else {
|
|
247
|
-
const { startStdio } = await import("./server-
|
|
246
|
+
const { startStdio } = await import("./server-DqSMYhSA.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();
|
|
@@ -1631,7 +1631,7 @@ 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-DueE6tl5.js");
|
|
1635
1635
|
const result = await doGmailSync({
|
|
1636
1636
|
slug,
|
|
1637
1637
|
dataDir,
|
|
@@ -1651,7 +1651,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1651
1651
|
const token = await getMicrosoftToken(dataDir);
|
|
1652
1652
|
if (!token) console.log(info(" Microsoft: no token found (.agentic/microsoft-token.json)"));
|
|
1653
1653
|
else {
|
|
1654
|
-
const { syncMicrosoft: doMsSync } = await import("./microsoft-sync-
|
|
1654
|
+
const { syncMicrosoft: doMsSync } = await import("./microsoft-sync-R_r8HL-B.js");
|
|
1655
1655
|
const emailResult = await doMsSync({
|
|
1656
1656
|
slug,
|
|
1657
1657
|
dataDir,
|
|
@@ -1660,7 +1660,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1660
1660
|
});
|
|
1661
1661
|
totalSynced += emailResult.synced;
|
|
1662
1662
|
console.log(success(` ✓ Microsoft Email: +${emailResult.synced} synced, ${emailResult.skipped} skipped`));
|
|
1663
|
-
const { syncMicrosoftCalendar } = await import("./microsoft-calendar-
|
|
1663
|
+
const { syncMicrosoftCalendar } = await import("./microsoft-calendar-jIu9K5zX.js");
|
|
1664
1664
|
const calResult = await syncMicrosoftCalendar({
|
|
1665
1665
|
slug,
|
|
1666
1666
|
dataDir,
|
|
@@ -1678,7 +1678,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1678
1678
|
if (fs.existsSync(agenticSourcesPath)) try {
|
|
1679
1679
|
const agenticSources = JSON.parse(fs.readFileSync(agenticSourcesPath, "utf-8"));
|
|
1680
1680
|
if (agenticSources.transcripts?.enabled && agenticSources.transcripts.paths?.length) {
|
|
1681
|
-
const { processTranscriptFile } = await import("./transcript-watcher-
|
|
1681
|
+
const { processTranscriptFile } = await import("./transcript-watcher-0mh2ZhmH.js");
|
|
1682
1682
|
const exts = agenticSources.transcripts.extensions ?? [".txt", ".vtt"];
|
|
1683
1683
|
let transcriptSynced = 0;
|
|
1684
1684
|
for (const watchPath of agenticSources.transcripts.paths) {
|
|
@@ -1707,7 +1707,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1707
1707
|
if (!accessToken) console.log(info(" Google Drive: accessToken not found in token file"));
|
|
1708
1708
|
else {
|
|
1709
1709
|
console.log(info(` Syncing Google Drive for ${bold(slug)}...`));
|
|
1710
|
-
const { syncGoogleDriveFiles } = await import("./google-drive-sync-
|
|
1710
|
+
const { syncGoogleDriveFiles } = await import("./google-drive-sync-D1n7WKZn.js");
|
|
1711
1711
|
const result = await syncGoogleDriveFiles({
|
|
1712
1712
|
slug,
|
|
1713
1713
|
dataDir,
|
|
@@ -1730,7 +1730,7 @@ const syncCommand = new Command("sync").argument("<slug>", "Customer slug to syn
|
|
|
1730
1730
|
function getPidFile$1() {
|
|
1731
1731
|
return path.join(process.cwd(), ".agentic", "daemon.pid");
|
|
1732
1732
|
}
|
|
1733
|
-
const daemonCommand = new Command("daemon");
|
|
1733
|
+
const daemonCommand = new Command("daemon").description("Manage the background sync daemon");
|
|
1734
1734
|
daemonCommand.command("start").action(async () => {
|
|
1735
1735
|
const pidFile = getPidFile$1();
|
|
1736
1736
|
if (fs.existsSync(pidFile)) {
|
|
@@ -1895,8 +1895,7 @@ async function runAgentSpawn(slug, opts, dataDir) {
|
|
|
1895
1895
|
lastWake: null,
|
|
1896
1896
|
...opts.chatId !== void 0 ? { telegramChatId: opts.chatId } : {}
|
|
1897
1897
|
});
|
|
1898
|
-
|
|
1899
|
-
fs.writeFileSync(agentConfigPath(dir, slug), JSON.stringify(config, null, 2), "utf-8");
|
|
1898
|
+
writeJsonFile(agentConfigPath(dir, slug), config);
|
|
1900
1899
|
console.log(success(`✓ Agent spawned: ${bold(slug)}`));
|
|
1901
1900
|
console.log(info(` Channel: ${channel}`));
|
|
1902
1901
|
console.log(info(` Wake on: ${wakeOn.join(", ")}`));
|
|
@@ -2008,7 +2007,7 @@ function ensureCustomer(dataDir, name, domain, email, dryRun) {
|
|
|
2008
2007
|
};
|
|
2009
2008
|
fs.mkdirSync(customerDir, { recursive: true });
|
|
2010
2009
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2011
|
-
|
|
2010
|
+
writeFileAtomic(mainFactsPath, `${[
|
|
2012
2011
|
"---",
|
|
2013
2012
|
`name: ${name}`,
|
|
2014
2013
|
domain ? `domain: ${domain}` : null,
|
|
@@ -2019,11 +2018,10 @@ function ensureCustomer(dataDir, name, domain, email, dryRun) {
|
|
|
2019
2018
|
`last_touchpoint: ${today}`,
|
|
2020
2019
|
"tags: []",
|
|
2021
2020
|
"---"
|
|
2022
|
-
].filter(Boolean).join("\n");
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
fs.writeFileSync(path.join(customerDir, "sources.json"), JSON.stringify({
|
|
2021
|
+
].filter(Boolean).join("\n")}\n\n# Customer: ${name}\n`);
|
|
2022
|
+
writeFileAtomic(path.join(customerDir, "interactions.md"), `# Interactions — ${name}\n\n`);
|
|
2023
|
+
writeFileAtomic(path.join(customerDir, "pipeline.md"), `# Pipeline — ${name}\n\n`);
|
|
2024
|
+
writeJsonFile(path.join(customerDir, "sources.json"), {
|
|
2027
2025
|
gmail: {
|
|
2028
2026
|
query: domain ? `from:${domain} OR to:${domain}` : email ? `from:${email} OR to:${email}` : "",
|
|
2029
2027
|
enabled: true
|
|
@@ -2033,7 +2031,7 @@ function ensureCustomer(dataDir, name, domain, email, dryRun) {
|
|
|
2033
2031
|
extensions: [".txt", ".vtt"],
|
|
2034
2032
|
enabled: false
|
|
2035
2033
|
}
|
|
2036
|
-
}
|
|
2034
|
+
});
|
|
2037
2035
|
return {
|
|
2038
2036
|
slug,
|
|
2039
2037
|
created: true
|
|
@@ -2107,14 +2105,14 @@ async function runSalesforceFileImport(sourcePath, opts, dir) {
|
|
|
2107
2105
|
result.errors.push(`Account '${name}': ${err.message}`);
|
|
2108
2106
|
}
|
|
2109
2107
|
}
|
|
2108
|
+
const dedup = new InteractionDedup(dir);
|
|
2110
2109
|
for (const row of activities) {
|
|
2111
2110
|
const accountId = row["AccountId"] ?? row["WhatId"] ?? "";
|
|
2112
2111
|
const slug = accountId ? slugMap.get(accountId) : void 0;
|
|
2113
2112
|
if (!slug) continue;
|
|
2114
2113
|
const id = row["Id"] ?? hashRow(row);
|
|
2115
2114
|
const sourceRef = `salesforce://row/${id}`;
|
|
2116
|
-
|
|
2117
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2115
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2118
2116
|
result.skipped++;
|
|
2119
2117
|
continue;
|
|
2120
2118
|
}
|
|
@@ -2132,6 +2130,7 @@ async function runSalesforceFileImport(sourcePath, opts, dir) {
|
|
|
2132
2130
|
sourceRef,
|
|
2133
2131
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2134
2132
|
});
|
|
2133
|
+
dedup.markAppended(slug, sourceRef);
|
|
2135
2134
|
result.interactionsImported++;
|
|
2136
2135
|
} catch (err) {
|
|
2137
2136
|
result.errors.push(`Activity ${id}: ${err.message}`);
|
|
@@ -2185,14 +2184,14 @@ async function runPipedriveFileImport(sourcePath, opts, dir) {
|
|
|
2185
2184
|
result.errors.push(`Organization '${name}': ${err.message}`);
|
|
2186
2185
|
}
|
|
2187
2186
|
}
|
|
2187
|
+
const dedup = new InteractionDedup(dir);
|
|
2188
2188
|
for (const row of activities) {
|
|
2189
2189
|
const orgId = row["org_id"] ?? row["organization_id"] ?? "";
|
|
2190
2190
|
const slug = orgId ? slugMap.get(orgId) : void 0;
|
|
2191
2191
|
if (!slug) continue;
|
|
2192
2192
|
const id = row["id"] ?? hashRow(row);
|
|
2193
2193
|
const sourceRef = `pipedrive://row/${id}`;
|
|
2194
|
-
|
|
2195
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2194
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2196
2195
|
result.skipped++;
|
|
2197
2196
|
continue;
|
|
2198
2197
|
}
|
|
@@ -2210,6 +2209,7 @@ async function runPipedriveFileImport(sourcePath, opts, dir) {
|
|
|
2210
2209
|
sourceRef,
|
|
2211
2210
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2212
2211
|
});
|
|
2212
|
+
dedup.markAppended(slug, sourceRef);
|
|
2213
2213
|
result.interactionsImported++;
|
|
2214
2214
|
} catch (err) {
|
|
2215
2215
|
result.errors.push(`Activity ${id}: ${err.message}`);
|
|
@@ -2229,7 +2229,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2229
2229
|
if (opts.from === "salesforce" && opts.mode === "api") return runSalesforceApiImport(opts, dir);
|
|
2230
2230
|
if (opts.from === "pipedrive" && opts.mode === "api") return runPipedriveApiImport(opts, dir);
|
|
2231
2231
|
if (opts.from === "hubspot" && sourcePath && fs.existsSync(sourcePath) && fs.statSync(sourcePath).isDirectory()) {
|
|
2232
|
-
const { runHubSpotCsvImport } = await import("./import-hubspot-
|
|
2232
|
+
const { runHubSpotCsvImport } = await import("./import-hubspot-DB4n89jy.js");
|
|
2233
2233
|
const r = await runHubSpotCsvImport(sourcePath, dir, {
|
|
2234
2234
|
...opts.dryRun ? { dryRun: true } : {},
|
|
2235
2235
|
...opts.resume ? { resume: true } : {},
|
|
@@ -2256,7 +2256,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2256
2256
|
return result;
|
|
2257
2257
|
}
|
|
2258
2258
|
const headers = Object.keys(rows[0]);
|
|
2259
|
-
const { mapCsvFields } = await import("./llm-
|
|
2259
|
+
const { mapCsvFields } = await import("./llm-DSX1-wFu.js");
|
|
2260
2260
|
const mapping = await mapCsvFields(headers, [...IMPORT_TARGET_FIELDS]);
|
|
2261
2261
|
if (opts.dryRun) {
|
|
2262
2262
|
console.log(info(`Dry run — ${rows.length} rows, field mapping:`));
|
|
@@ -2281,6 +2281,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2281
2281
|
result.errors.push(`Customer '${name}': ${err.message}`);
|
|
2282
2282
|
}
|
|
2283
2283
|
}
|
|
2284
|
+
const dedup = new InteractionDedup(dir);
|
|
2284
2285
|
for (const row of rows) {
|
|
2285
2286
|
const activityType = (row[mapping["activityType"] ?? ""] ?? "").trim();
|
|
2286
2287
|
const notes = (row[mapping["notes"] ?? ""] ?? "").trim();
|
|
@@ -2309,8 +2310,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2309
2310
|
return "Note";
|
|
2310
2311
|
})();
|
|
2311
2312
|
try {
|
|
2312
|
-
|
|
2313
|
-
if ((await readInteractions(dir, slug)).includes(sourceRef)) {
|
|
2313
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2314
2314
|
result.skipped++;
|
|
2315
2315
|
continue;
|
|
2316
2316
|
}
|
|
@@ -2323,6 +2323,7 @@ async function runImport(sourcePath, opts, dataDir) {
|
|
|
2323
2323
|
sourceRef,
|
|
2324
2324
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2325
2325
|
});
|
|
2326
|
+
dedup.markAppended(slug, sourceRef);
|
|
2326
2327
|
result.interactionsImported++;
|
|
2327
2328
|
} catch (err) {
|
|
2328
2329
|
result.errors.push(`Activity for '${name}': ${err.message}`);
|
|
@@ -2386,12 +2387,12 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2386
2387
|
result.errors.push(`Contact '${name}': ${err.message}`);
|
|
2387
2388
|
}
|
|
2388
2389
|
}
|
|
2390
|
+
const dedup = new InteractionDedup(dir);
|
|
2389
2391
|
for (const task of tasks) {
|
|
2390
2392
|
const slug = task.WhoId ? slugMap.get(task.WhoId) : void 0;
|
|
2391
2393
|
if (!slug) continue;
|
|
2392
2394
|
const sourceRef = `salesforce://task/${task.Id}`;
|
|
2393
|
-
|
|
2394
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2395
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2395
2396
|
result.skipped++;
|
|
2396
2397
|
continue;
|
|
2397
2398
|
}
|
|
@@ -2409,12 +2410,13 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2409
2410
|
sourceRef,
|
|
2410
2411
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2411
2412
|
});
|
|
2413
|
+
dedup.markAppended(slug, sourceRef);
|
|
2412
2414
|
result.interactionsImported++;
|
|
2413
2415
|
} catch (err) {
|
|
2414
2416
|
result.errors.push(`Task ${task.Id}: ${err.message}`);
|
|
2415
2417
|
}
|
|
2416
2418
|
}
|
|
2417
|
-
const { upsertDeal } = await import("./pipeline-writer-
|
|
2419
|
+
const { upsertDeal } = await import("./pipeline-writer-0LJ6Qkat.js");
|
|
2418
2420
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2419
2421
|
const oppSlugById = /* @__PURE__ */ new Map();
|
|
2420
2422
|
for (const opp of opportunities) {
|
|
@@ -2453,7 +2455,6 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2453
2455
|
result.errors.push(`Opportunity '${opp.Name}': ${err.message}`);
|
|
2454
2456
|
}
|
|
2455
2457
|
}
|
|
2456
|
-
const { readInteractions } = await import("./interactions-writer-dSPy1XfO.js");
|
|
2457
2458
|
for (const lead of leads) {
|
|
2458
2459
|
const name = lead.Company?.trim() || lead.Name?.trim();
|
|
2459
2460
|
if (!name) continue;
|
|
@@ -2469,7 +2470,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2469
2470
|
continue;
|
|
2470
2471
|
}
|
|
2471
2472
|
const sourceRef = `salesforce://lead/${lead.Id}`;
|
|
2472
|
-
if (
|
|
2473
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2473
2474
|
result.skipped++;
|
|
2474
2475
|
continue;
|
|
2475
2476
|
}
|
|
@@ -2484,6 +2485,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2484
2485
|
sourceRef,
|
|
2485
2486
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2486
2487
|
});
|
|
2488
|
+
dedup.markAppended(slug, sourceRef);
|
|
2487
2489
|
result.leadsImported = (result.leadsImported ?? 0) + 1;
|
|
2488
2490
|
} catch (err) {
|
|
2489
2491
|
result.errors.push(`Lead ${lead.Id}: ${err.message}`);
|
|
@@ -2496,7 +2498,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2496
2498
|
continue;
|
|
2497
2499
|
}
|
|
2498
2500
|
const sourceRef = `salesforce://event/${event.Id}`;
|
|
2499
|
-
if (
|
|
2501
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2500
2502
|
result.skipped++;
|
|
2501
2503
|
continue;
|
|
2502
2504
|
}
|
|
@@ -2512,13 +2514,14 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2512
2514
|
sourceRef,
|
|
2513
2515
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2514
2516
|
});
|
|
2517
|
+
dedup.markAppended(slug, sourceRef);
|
|
2515
2518
|
result.eventsImported = (result.eventsImported ?? 0) + 1;
|
|
2516
2519
|
} catch (err) {
|
|
2517
2520
|
result.errors.push(`Event ${event.Id}: ${err.message}`);
|
|
2518
2521
|
}
|
|
2519
2522
|
}
|
|
2520
|
-
const { readTickets, upsertTicket, nextTicketId } = await import("./ticket-writer-
|
|
2521
|
-
const { calcSlaDue, loadSlaRules } = await import("./sla-engine-
|
|
2523
|
+
const { readTickets, upsertTicket, nextTicketId } = await import("./ticket-writer-DsfpeLGZ.js");
|
|
2524
|
+
const { calcSlaDue, loadSlaRules } = await import("./sla-engine-CP2KiKDS.js");
|
|
2522
2525
|
const slaRules = loadSlaRules(dir);
|
|
2523
2526
|
for (const c of cases) {
|
|
2524
2527
|
const accountName = c.Account?.Name?.trim();
|
|
@@ -2565,7 +2568,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2565
2568
|
}
|
|
2566
2569
|
}
|
|
2567
2570
|
if (lineItems.length > 0 && oppSlugById.size > 0) {
|
|
2568
|
-
const { generateQuote, listQuotes } = await import("./quote-generator-
|
|
2571
|
+
const { generateQuote, listQuotes } = await import("./quote-generator-ByUyIYtw.js");
|
|
2569
2572
|
const byOpp = /* @__PURE__ */ new Map();
|
|
2570
2573
|
for (const li of lineItems) {
|
|
2571
2574
|
if (!li.OpportunityId) continue;
|
|
@@ -2608,7 +2611,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2608
2611
|
continue;
|
|
2609
2612
|
}
|
|
2610
2613
|
const sourceRef = `salesforce://note/${note.Id}`;
|
|
2611
|
-
if (
|
|
2614
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2612
2615
|
result.skipped++;
|
|
2613
2616
|
continue;
|
|
2614
2617
|
}
|
|
@@ -2625,6 +2628,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2625
2628
|
sourceRef,
|
|
2626
2629
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2627
2630
|
});
|
|
2631
|
+
dedup.markAppended(slug, sourceRef);
|
|
2628
2632
|
result.notesImported = (result.notesImported ?? 0) + 1;
|
|
2629
2633
|
} catch (err) {
|
|
2630
2634
|
result.errors.push(`Note ${note.Id}: ${err.message}`);
|
|
@@ -2637,7 +2641,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2637
2641
|
continue;
|
|
2638
2642
|
}
|
|
2639
2643
|
const sourceRef = `salesforce://campaignmember/${cm.Id}`;
|
|
2640
|
-
if (
|
|
2644
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2641
2645
|
result.skipped++;
|
|
2642
2646
|
continue;
|
|
2643
2647
|
}
|
|
@@ -2653,6 +2657,7 @@ async function runSalesforceApiImport(opts, dir) {
|
|
|
2653
2657
|
sourceRef,
|
|
2654
2658
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2655
2659
|
});
|
|
2660
|
+
dedup.markAppended(slug, sourceRef);
|
|
2656
2661
|
result.campaignsImported = (result.campaignsImported ?? 0) + 1;
|
|
2657
2662
|
} catch (err) {
|
|
2658
2663
|
result.errors.push(`CampaignMember ${cm.Id}: ${err.message}`);
|
|
@@ -2701,12 +2706,12 @@ async function runPipedriveApiImport(opts, dir = process.cwd()) {
|
|
|
2701
2706
|
result.errors.push(`Person '${name}': ${err.message}`);
|
|
2702
2707
|
}
|
|
2703
2708
|
}
|
|
2709
|
+
const dedup = new InteractionDedup(dir);
|
|
2704
2710
|
for (const activity of activities) {
|
|
2705
2711
|
const slug = (activity.person_id && slugByPersonId.get(activity.person_id)) ?? (activity.org_id && slugByOrgId.get(activity.org_id)) ?? void 0;
|
|
2706
2712
|
if (!slug) continue;
|
|
2707
2713
|
const sourceRef = `pipedrive://activity/${activity.id}`;
|
|
2708
|
-
|
|
2709
|
-
if ((await readInteractions(dir, slug).catch(() => "")).includes(sourceRef)) {
|
|
2714
|
+
if (await dedup.seen(slug, sourceRef)) {
|
|
2710
2715
|
result.skipped++;
|
|
2711
2716
|
continue;
|
|
2712
2717
|
}
|
|
@@ -2724,6 +2729,7 @@ async function runPipedriveApiImport(opts, dir = process.cwd()) {
|
|
|
2724
2729
|
sourceRef,
|
|
2725
2730
|
synced: (/* @__PURE__ */ new Date()).toISOString()
|
|
2726
2731
|
});
|
|
2732
|
+
dedup.markAppended(slug, sourceRef);
|
|
2727
2733
|
result.interactionsImported++;
|
|
2728
2734
|
} catch (err) {
|
|
2729
2735
|
result.errors.push(`Activity ${activity.id}: ${err.message}`);
|
|
@@ -2739,7 +2745,7 @@ const importCommand = new Command("import").description("Import customers and in
|
|
|
2739
2745
|
if (hs && rep) ownerMap[hs.trim()] = rep.trim();
|
|
2740
2746
|
}
|
|
2741
2747
|
if (opts.analyze && opts.from === "hubspot" && sourcePath) {
|
|
2742
|
-
const { analyzeHubSpotExport } = await import("./import-hubspot-
|
|
2748
|
+
const { analyzeHubSpotExport } = await import("./import-hubspot-DB4n89jy.js");
|
|
2743
2749
|
const analysis = await analyzeHubSpotExport(sourcePath);
|
|
2744
2750
|
console.log(bold("\nDatasynxOpenCRM — HubSpot Import Analysis"));
|
|
2745
2751
|
console.log("==========================================");
|
|
@@ -2840,7 +2846,7 @@ function runServerStatus(dataDir) {
|
|
|
2840
2846
|
} catch {}
|
|
2841
2847
|
}
|
|
2842
2848
|
}
|
|
2843
|
-
const serverCommand = new Command("server");
|
|
2849
|
+
const serverCommand = new Command("server").description("Start the shared HTTP MCP server for team use");
|
|
2844
2850
|
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
2851
|
serverCommand.command("status").description("Check if the server is running").action(() => runServerStatus());
|
|
2846
2852
|
//#endregion
|
|
@@ -2871,6 +2877,90 @@ async function runAudit(opts, dataDir) {
|
|
|
2871
2877
|
}
|
|
2872
2878
|
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
2879
|
//#endregion
|
|
2880
|
+
//#region src/commands/logs.ts
|
|
2881
|
+
const LEVELS = [
|
|
2882
|
+
"debug",
|
|
2883
|
+
"info",
|
|
2884
|
+
"warn",
|
|
2885
|
+
"error"
|
|
2886
|
+
];
|
|
2887
|
+
function paintLevel(level, text) {
|
|
2888
|
+
if (level === "error") return error(text);
|
|
2889
|
+
if (level === "warn") return warning(text);
|
|
2890
|
+
if (level === "info") return info(text);
|
|
2891
|
+
return text;
|
|
2892
|
+
}
|
|
2893
|
+
function buildQuery(opts) {
|
|
2894
|
+
return {
|
|
2895
|
+
...opts.level && LEVELS.includes(opts.level) ? { level: opts.level } : {},
|
|
2896
|
+
...opts.component !== void 0 ? { component: opts.component } : {},
|
|
2897
|
+
...opts.since !== void 0 ? { since: opts.since } : {},
|
|
2898
|
+
...opts.contains !== void 0 ? { contains: opts.contains } : {},
|
|
2899
|
+
limit: opts.limit ?? 50
|
|
2900
|
+
};
|
|
2901
|
+
}
|
|
2902
|
+
function dataDir$18() {
|
|
2903
|
+
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2904
|
+
}
|
|
2905
|
+
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) => {
|
|
2906
|
+
const query = buildQuery(opts);
|
|
2907
|
+
if (opts.summary) {
|
|
2908
|
+
const { summarizeLogs } = await import("./logger-vKQS34w9.js");
|
|
2909
|
+
const s = summarizeLogs(dataDir$18(), query);
|
|
2910
|
+
console.log(bold(`Logs — ${s.total} entr${s.total === 1 ? "y" : "ies"}`));
|
|
2911
|
+
if (s.firstTs) console.log(info(` ${s.firstTs} → ${s.lastTs}`));
|
|
2912
|
+
console.log(" By level:");
|
|
2913
|
+
for (const lvl of LEVELS) {
|
|
2914
|
+
const n = s.byLevel[lvl];
|
|
2915
|
+
if (n > 0) console.log(` ${paintLevel(lvl, lvl.padEnd(6))} ${n}`);
|
|
2916
|
+
}
|
|
2917
|
+
console.log(" By component:");
|
|
2918
|
+
for (const [comp, n] of Object.entries(s.byComponent).sort((a, b) => b[1] - a[1])) console.log(` ${comp.padEnd(22)} ${n}`);
|
|
2919
|
+
if (s.recentErrors.length > 0) {
|
|
2920
|
+
console.log(error(" Recent errors:"));
|
|
2921
|
+
for (const e of s.recentErrors) console.log(` ${e.ts} [${e.component}] ${e.message}`);
|
|
2922
|
+
}
|
|
2923
|
+
return;
|
|
2924
|
+
}
|
|
2925
|
+
const { queryLogs } = await import("./logger-vKQS34w9.js");
|
|
2926
|
+
const entries = queryLogs(dataDir$18(), query);
|
|
2927
|
+
if (entries.length === 0) {
|
|
2928
|
+
console.log(success("No matching log entries."));
|
|
2929
|
+
return;
|
|
2930
|
+
}
|
|
2931
|
+
for (const e of entries) {
|
|
2932
|
+
const ctx = e.context ? ` ${JSON.stringify(e.context)}` : "";
|
|
2933
|
+
console.log(`${e.ts} ${paintLevel(e.level, e.level.padEnd(5))} ${e.component.padEnd(18)} ${e.message}${ctx}`);
|
|
2934
|
+
}
|
|
2935
|
+
});
|
|
2936
|
+
//#endregion
|
|
2937
|
+
//#region src/commands/doctor.ts
|
|
2938
|
+
function dataDir$17() {
|
|
2939
|
+
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2940
|
+
}
|
|
2941
|
+
function icon(status) {
|
|
2942
|
+
if (status === "ok") return success("✓");
|
|
2943
|
+
if (status === "warn") return warning("⚠");
|
|
2944
|
+
return error("✗");
|
|
2945
|
+
}
|
|
2946
|
+
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) => {
|
|
2947
|
+
const { runDiagnostics, cleanupTempFiles } = await import("./doctor-C14-vnJ1.js");
|
|
2948
|
+
if (opts.fix) {
|
|
2949
|
+
const removed = cleanupTempFiles(dataDir$17());
|
|
2950
|
+
console.log(removed.length > 0 ? success(`Removed ${removed.length} orphaned temp file(s).`) : warning("Nothing to fix."));
|
|
2951
|
+
}
|
|
2952
|
+
const report = await runDiagnostics(dataDir$17());
|
|
2953
|
+
console.log(bold("dxcrm doctor"));
|
|
2954
|
+
for (const c of report.checks) console.log(` ${icon(c.status)} ${c.name.padEnd(16)} ${c.detail}`);
|
|
2955
|
+
if (report.ok) {
|
|
2956
|
+
const warns = report.checks.filter((c) => c.status === "warn").length;
|
|
2957
|
+
console.log(warns > 0 ? warning(`\nHealthy, with ${warns} warning(s).`) : success("\nAll healthy."));
|
|
2958
|
+
} else {
|
|
2959
|
+
console.log(error("\nProblems found — see the ✗ checks above."));
|
|
2960
|
+
process.exitCode = 1;
|
|
2961
|
+
}
|
|
2962
|
+
});
|
|
2963
|
+
//#endregion
|
|
2874
2964
|
//#region src/commands/rbac.ts
|
|
2875
2965
|
const ROLES = [
|
|
2876
2966
|
"admin",
|
|
@@ -2900,7 +2990,7 @@ async function runRbacShow(dataDir) {
|
|
|
2900
2990
|
}
|
|
2901
2991
|
async function runRbacCheck(actor, tool, dataDir) {
|
|
2902
2992
|
const dir = dataDir ?? process.cwd();
|
|
2903
|
-
const { getRole } = await import("./rbac-
|
|
2993
|
+
const { getRole } = await import("./rbac-DzbyFhVH.js");
|
|
2904
2994
|
const role = getRole(dir, actor);
|
|
2905
2995
|
if (canWrite(role, tool)) console.log(success(`✓ ${actor} (${role}) CAN use '${tool}'`));
|
|
2906
2996
|
else console.log(error(`✗ ${actor} (${role}) CANNOT use '${tool}'`));
|
|
@@ -2928,7 +3018,7 @@ function appendErasure(dataDir, record) {
|
|
|
2928
3018
|
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
2929
3019
|
const existing = readErasures(dataDir);
|
|
2930
3020
|
existing.push(record);
|
|
2931
|
-
|
|
3021
|
+
writeJsonFile(p, existing);
|
|
2932
3022
|
}
|
|
2933
3023
|
async function runGdprErase(slug, opts, dataDir) {
|
|
2934
3024
|
const dir = dataDir ?? process.cwd();
|
|
@@ -2948,7 +3038,7 @@ async function runGdprErase(slug, opts, dataDir) {
|
|
|
2948
3038
|
force: true
|
|
2949
3039
|
});
|
|
2950
3040
|
try {
|
|
2951
|
-
const { dropCustomerTable } = await import("./lancedb-
|
|
3041
|
+
const { dropCustomerTable } = await import("./lancedb-CswQEE5K.js");
|
|
2952
3042
|
await dropCustomerTable(dir, slug);
|
|
2953
3043
|
} catch {}
|
|
2954
3044
|
}
|
|
@@ -2956,7 +3046,7 @@ async function runGdprErase(slug, opts, dataDir) {
|
|
|
2956
3046
|
if (fs.existsSync(globalQueuePath)) await withJsonFile(globalQueuePath, (tasks) => (Array.isArray(tasks) ? tasks : []).filter((t) => t.slug !== slug));
|
|
2957
3047
|
const goalsPath = path.join(dir, ".agentic", "goals.json");
|
|
2958
3048
|
if (fs.existsSync(goalsPath)) {
|
|
2959
|
-
const { readGoals, writeGoals } = await import("./goal-engine-
|
|
3049
|
+
const { readGoals, writeGoals } = await import("./goal-engine-CfDAJTFt.js");
|
|
2960
3050
|
writeGoals(dir, readGoals(dir).map((g) => ({
|
|
2961
3051
|
...g,
|
|
2962
3052
|
decomposition: {
|
|
@@ -2965,7 +3055,7 @@ async function runGdprErase(slug, opts, dataDir) {
|
|
|
2965
3055
|
}
|
|
2966
3056
|
})));
|
|
2967
3057
|
}
|
|
2968
|
-
const { readSubscriptions, writeSubscriptions } = await import("./push-manager-
|
|
3058
|
+
const { readSubscriptions, writeSubscriptions } = await import("./push-manager-BXM-IHfP.js");
|
|
2969
3059
|
const subs = await readSubscriptions(dir);
|
|
2970
3060
|
const remaining = subs.filter((s) => s.slug !== slug);
|
|
2971
3061
|
if (remaining.length !== subs.length) await writeSubscriptions(dir, remaining);
|
|
@@ -3396,7 +3486,7 @@ templateCommand.command("create <id>").option("--category <category>", "Category
|
|
|
3396
3486
|
variables: [],
|
|
3397
3487
|
language: "de",
|
|
3398
3488
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3399
|
-
body: `Hi {{firstName}},\n\n[your message here]\n\
|
|
3489
|
+
body: `Hi {{firstName}},\n\n[your message here]\n\nBest regards,\n{{senderName}}`
|
|
3400
3490
|
});
|
|
3401
3491
|
console.log(success(`✓ Template '${id}' created in category '${opts.category}'`));
|
|
3402
3492
|
});
|
|
@@ -3761,7 +3851,7 @@ function parseFieldSpec(spec) {
|
|
|
3761
3851
|
}
|
|
3762
3852
|
const fieldsCommand = new Command("fields").description("Manage custom fields (metadata-driven extensibility)");
|
|
3763
3853
|
fieldsCommand.command("list").description("List defined custom fields").action(async () => {
|
|
3764
|
-
const { loadFieldDefinitions } = await import("./custom-fields-
|
|
3854
|
+
const { loadFieldDefinitions } = await import("./custom-fields-BMyz5Ruh.js");
|
|
3765
3855
|
const defs = loadFieldDefinitions(dataDir$16());
|
|
3766
3856
|
if (defs.length === 0) {
|
|
3767
3857
|
console.log(info("No custom fields defined. Add one with: dxcrm fields add <name> <type>"));
|
|
@@ -3778,7 +3868,7 @@ fieldsCommand.command("add <name> <type>").description("Define a custom field (t
|
|
|
3778
3868
|
process.exitCode = 1;
|
|
3779
3869
|
return;
|
|
3780
3870
|
}
|
|
3781
|
-
const { defineCustomField } = await import("./custom-fields-
|
|
3871
|
+
const { defineCustomField } = await import("./custom-fields-BMyz5Ruh.js");
|
|
3782
3872
|
defineCustomField(dataDir$16(), {
|
|
3783
3873
|
name,
|
|
3784
3874
|
type,
|
|
@@ -3799,7 +3889,7 @@ objectCommand.command("define <name>").description("Define a custom object with
|
|
|
3799
3889
|
}
|
|
3800
3890
|
fields.push(f);
|
|
3801
3891
|
}
|
|
3802
|
-
const { defineCustomObject } = await import("./custom-objects-
|
|
3892
|
+
const { defineCustomObject } = await import("./custom-objects-BNy-ayR-.js");
|
|
3803
3893
|
defineCustomObject(dataDir$16(), {
|
|
3804
3894
|
name,
|
|
3805
3895
|
...opts.label ? { label: opts.label } : {},
|
|
@@ -3814,7 +3904,7 @@ objectCommand.command("add <name>").description("Create a record (--set key=valu
|
|
|
3814
3904
|
if (eq < 0) continue;
|
|
3815
3905
|
values[kv.slice(0, eq).trim()] = kv.slice(eq + 1).trim();
|
|
3816
3906
|
}
|
|
3817
|
-
const { createRecord } = await import("./custom-objects-
|
|
3907
|
+
const { createRecord } = await import("./custom-objects-BNy-ayR-.js");
|
|
3818
3908
|
const res = createRecord(dataDir$16(), name, values);
|
|
3819
3909
|
if (!res.ok) {
|
|
3820
3910
|
console.error(error(`Could not create record: ${(res.errors ?? []).join("; ")}`));
|
|
@@ -3824,7 +3914,7 @@ objectCommand.command("add <name>").description("Create a record (--set key=valu
|
|
|
3824
3914
|
console.log(success(`Created ${name} record ${res.record.id}`));
|
|
3825
3915
|
});
|
|
3826
3916
|
objectCommand.command("list <name>").description("List records of a custom object").action(async (name) => {
|
|
3827
|
-
const { listRecords } = await import("./custom-objects-
|
|
3917
|
+
const { listRecords } = await import("./custom-objects-BNy-ayR-.js");
|
|
3828
3918
|
const records = listRecords(dataDir$16(), name);
|
|
3829
3919
|
if (records.length === 0) {
|
|
3830
3920
|
console.log(info(`No records for '${name}'.`));
|
|
@@ -3839,13 +3929,13 @@ function dataDir$15() {
|
|
|
3839
3929
|
}
|
|
3840
3930
|
const webhookCommand = new Command("webhook").description("Manage outbound webhooks (event-driven integrations)");
|
|
3841
3931
|
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-
|
|
3932
|
+
const { addWebhook } = await import("./webhooks-DXr1IoKn.js");
|
|
3843
3933
|
const events = opts.events.split(",").map((s) => s.trim()).filter(Boolean);
|
|
3844
3934
|
const sub = addWebhook(dataDir$15(), url, events, opts.secret);
|
|
3845
3935
|
console.log(success(`Webhook ${sub.id} → ${url} [${events.join(", ")}]`));
|
|
3846
3936
|
});
|
|
3847
3937
|
webhookCommand.command("list").description("List webhook subscriptions").action(async () => {
|
|
3848
|
-
const { loadWebhooks } = await import("./webhooks-
|
|
3938
|
+
const { loadWebhooks } = await import("./webhooks-DXr1IoKn.js");
|
|
3849
3939
|
const subs = loadWebhooks(dataDir$15());
|
|
3850
3940
|
if (subs.length === 0) {
|
|
3851
3941
|
console.log(info("No webhooks configured."));
|
|
@@ -3854,7 +3944,7 @@ webhookCommand.command("list").description("List webhook subscriptions").action(
|
|
|
3854
3944
|
for (const s of subs) console.log(`${s.id} ${s.url} [${s.events.join(", ")}]`);
|
|
3855
3945
|
});
|
|
3856
3946
|
webhookCommand.command("remove <id>").description("Remove a webhook subscription").action(async (id) => {
|
|
3857
|
-
const { removeWebhook } = await import("./webhooks-
|
|
3947
|
+
const { removeWebhook } = await import("./webhooks-DXr1IoKn.js");
|
|
3858
3948
|
if (removeWebhook(dataDir$15(), id)) console.log(success(`Removed ${id}`));
|
|
3859
3949
|
else {
|
|
3860
3950
|
console.error(error(`Not found: ${id}`));
|
|
@@ -3862,7 +3952,7 @@ webhookCommand.command("remove <id>").description("Remove a webhook subscription
|
|
|
3862
3952
|
}
|
|
3863
3953
|
});
|
|
3864
3954
|
webhookCommand.command("retry").description("Re-attempt failed webhook deliveries (replay store)").action(async () => {
|
|
3865
|
-
const { retryFailures } = await import("./webhooks-
|
|
3955
|
+
const { retryFailures } = await import("./webhooks-DXr1IoKn.js");
|
|
3866
3956
|
const r = await retryFailures(dataDir$15());
|
|
3867
3957
|
console.log(info(`Retried ${r.retried}, still failing ${r.stillFailing}.`));
|
|
3868
3958
|
});
|
|
@@ -3879,12 +3969,12 @@ segmentCommand.command("define <name>").description("Define a segment by criteri
|
|
|
3879
3969
|
...opts.minDealValue ? { minDealValue: Number(opts.minDealValue) } : {},
|
|
3880
3970
|
...opts.staleDays ? { staleDays: Number(opts.staleDays) } : {}
|
|
3881
3971
|
};
|
|
3882
|
-
const { defineSegment } = await import("./segments-
|
|
3972
|
+
const { defineSegment } = await import("./segments-DI3LOQNe.js");
|
|
3883
3973
|
defineSegment(dataDir$14(), name, criteria);
|
|
3884
3974
|
console.log(success(`Segment '${name}' defined: ${JSON.stringify(criteria)}`));
|
|
3885
3975
|
});
|
|
3886
3976
|
segmentCommand.command("list").description("List defined segments").action(async () => {
|
|
3887
|
-
const { loadSegments } = await import("./segments-
|
|
3977
|
+
const { loadSegments } = await import("./segments-DI3LOQNe.js");
|
|
3888
3978
|
const segs = loadSegments(dataDir$14());
|
|
3889
3979
|
if (segs.length === 0) {
|
|
3890
3980
|
console.log(info("No segments defined."));
|
|
@@ -3893,7 +3983,7 @@ segmentCommand.command("list").description("List defined segments").action(async
|
|
|
3893
3983
|
for (const s of segs) console.log(`${s.name} ${JSON.stringify(s.criteria)}`);
|
|
3894
3984
|
});
|
|
3895
3985
|
segmentCommand.command("members <name>").description("List customers matching a segment").action(async (name) => {
|
|
3896
|
-
const { loadSegments, evaluateSegment } = await import("./segments-
|
|
3986
|
+
const { loadSegments, evaluateSegment } = await import("./segments-DI3LOQNe.js");
|
|
3897
3987
|
const seg = loadSegments(dataDir$14()).find((s) => s.name === name);
|
|
3898
3988
|
if (!seg) {
|
|
3899
3989
|
console.error(error(`Segment not found: ${name}`));
|
|
@@ -3911,7 +4001,7 @@ function dataDir$13() {
|
|
|
3911
4001
|
}
|
|
3912
4002
|
const identityCommand = new Command("identity").description("Identity resolution / deduplication (CDP)");
|
|
3913
4003
|
identityCommand.command("duplicates").description("Find clusters of likely-duplicate customers (by canonical domain)").action(async () => {
|
|
3914
|
-
const { findDuplicateClusters } = await import("./identity-
|
|
4004
|
+
const { findDuplicateClusters } = await import("./identity-CB7j-Zr1.js");
|
|
3915
4005
|
const clusters = await findDuplicateClusters(dataDir$13());
|
|
3916
4006
|
if (clusters.length === 0) {
|
|
3917
4007
|
console.log(info("No duplicate clusters found."));
|
|
@@ -3943,7 +4033,7 @@ function dataDir$11() {
|
|
|
3943
4033
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3944
4034
|
}
|
|
3945
4035
|
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-
|
|
4036
|
+
const { aggregateUsage } = await import("./usage-BVlFlKW_.js");
|
|
3947
4037
|
const agg = aggregateUsage(dataDir$11(), opts.slug ? { slug: opts.slug } : {});
|
|
3948
4038
|
console.log(bold("LLM Usage"));
|
|
3949
4039
|
console.log(`Calls: ${agg.calls}`);
|
|
@@ -3962,7 +4052,7 @@ function dataDir$10() {
|
|
|
3962
4052
|
}
|
|
3963
4053
|
const approvalsCommand = new Command("approvals").description("Human-in-the-loop approval queue");
|
|
3964
4054
|
approvalsCommand.command("list").description("List approvals (default: pending)").option("--status <status>", "pending | approved | rejected", "pending").action(async (opts) => {
|
|
3965
|
-
const { listApprovals } = await import("./approvals-
|
|
4055
|
+
const { listApprovals } = await import("./approvals-CmDT2eUg.js");
|
|
3966
4056
|
const list = listApprovals(dataDir$10(), opts.status);
|
|
3967
4057
|
if (list.length === 0) {
|
|
3968
4058
|
console.log(info(`No ${opts.status} approvals.`));
|
|
@@ -3971,7 +4061,7 @@ approvalsCommand.command("list").description("List approvals (default: pending)"
|
|
|
3971
4061
|
for (const a of list) console.log(`${a.id} ${a.tool} ${a.slug ?? "-"} ${a.requestedAt}`);
|
|
3972
4062
|
});
|
|
3973
4063
|
approvalsCommand.command("approve <id>").description("Approve a pending action").action(async (id) => {
|
|
3974
|
-
const { decideApproval } = await import("./approvals-
|
|
4064
|
+
const { decideApproval } = await import("./approvals-CmDT2eUg.js");
|
|
3975
4065
|
if (decideApproval(dataDir$10(), id, "approved")) console.log(success(`Approved ${id}`));
|
|
3976
4066
|
else {
|
|
3977
4067
|
console.error(error(`Not found: ${id}`));
|
|
@@ -3979,7 +4069,7 @@ approvalsCommand.command("approve <id>").description("Approve a pending action")
|
|
|
3979
4069
|
}
|
|
3980
4070
|
});
|
|
3981
4071
|
approvalsCommand.command("reject <id>").description("Reject a pending action").action(async (id) => {
|
|
3982
|
-
const { decideApproval } = await import("./approvals-
|
|
4072
|
+
const { decideApproval } = await import("./approvals-CmDT2eUg.js");
|
|
3983
4073
|
if (decideApproval(dataDir$10(), id, "rejected")) console.log(success(`Rejected ${id}`));
|
|
3984
4074
|
else {
|
|
3985
4075
|
console.error(error(`Not found: ${id}`));
|
|
@@ -3997,7 +4087,7 @@ policyCommand.command("set <tool> <policy>").description("Set autonomy policy fo
|
|
|
3997
4087
|
process.exitCode = 1;
|
|
3998
4088
|
return;
|
|
3999
4089
|
}
|
|
4000
|
-
const { setPolicy } = await import("./approvals-
|
|
4090
|
+
const { setPolicy } = await import("./approvals-CmDT2eUg.js");
|
|
4001
4091
|
setPolicy(dataDir$10(), tool, policy, opts.slug);
|
|
4002
4092
|
console.log(success(`Policy ${tool}${opts.slug ? `@${opts.slug}` : ""} = ${policy}`));
|
|
4003
4093
|
});
|
|
@@ -4008,7 +4098,7 @@ function dataDir$9() {
|
|
|
4008
4098
|
}
|
|
4009
4099
|
const hygieneCommand = new Command("hygiene").description("Data-quality scanning");
|
|
4010
4100
|
hygieneCommand.command("scan").description("Scan customers for data-quality issues (missing/malformed/duplicate)").action(async () => {
|
|
4011
|
-
const { scanHygiene } = await import("./hygiene-
|
|
4101
|
+
const { scanHygiene } = await import("./hygiene-DzQPnc6P.js");
|
|
4012
4102
|
const issues = await scanHygiene(dataDir$9());
|
|
4013
4103
|
if (issues.length === 0) {
|
|
4014
4104
|
console.log(success("✓ No data-quality issues found."));
|
|
@@ -4034,7 +4124,7 @@ const TYPES = [
|
|
|
4034
4124
|
const memoryCommand = new Command("memory").description("Agent memories (per customer + global)");
|
|
4035
4125
|
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
4126
|
const type = TYPES.includes(opts.type) ? opts.type : "fact";
|
|
4037
|
-
const { addMemory } = await import("./memory-
|
|
4127
|
+
const { addMemory } = await import("./memory-D8hmgD9d.js");
|
|
4038
4128
|
const m = addMemory(dataDir$8(), {
|
|
4039
4129
|
scope: opts.slug ? "customer" : "global",
|
|
4040
4130
|
...opts.slug ? { slug: opts.slug } : {},
|
|
@@ -4044,7 +4134,7 @@ memoryCommand.command("add <text>").description("Add a memory (global unless --s
|
|
|
4044
4134
|
console.log(success(`Memory ${m.id} stored (${m.scope}${opts.slug ? `:${opts.slug}` : ""}).`));
|
|
4045
4135
|
});
|
|
4046
4136
|
memoryCommand.command("list").description("List memories (global + customer if --slug)").option("--slug <slug>", "Customer slug").action(async (opts) => {
|
|
4047
|
-
const { loadMemories } = await import("./memory-
|
|
4137
|
+
const { loadMemories } = await import("./memory-D8hmgD9d.js");
|
|
4048
4138
|
const mems = loadMemories(dataDir$8(), opts.slug);
|
|
4049
4139
|
if (mems.length === 0) {
|
|
4050
4140
|
console.log(info("No memories."));
|
|
@@ -4053,7 +4143,7 @@ memoryCommand.command("list").description("List memories (global + customer if -
|
|
|
4053
4143
|
for (const m of mems) console.log(`[${m.scope}/${m.type}] ${m.text}`);
|
|
4054
4144
|
});
|
|
4055
4145
|
memoryCommand.command("search <query>").description("Search memories by relevance").option("--slug <slug>", "Customer slug").action(async (query, opts) => {
|
|
4056
|
-
const { searchMemory } = await import("./memory-
|
|
4146
|
+
const { searchMemory } = await import("./memory-D8hmgD9d.js");
|
|
4057
4147
|
const hits = await searchMemory(dataDir$8(), query, opts.slug);
|
|
4058
4148
|
if (hits.length === 0) {
|
|
4059
4149
|
console.log(info("No matching memories."));
|
|
@@ -4068,7 +4158,7 @@ function dataDir$7() {
|
|
|
4068
4158
|
}
|
|
4069
4159
|
const sopCommand = new Command("sop").description("Standard Operating Procedures (global / per customer)");
|
|
4070
4160
|
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-
|
|
4161
|
+
const { addSop } = await import("./sop-D33qTHUb.js");
|
|
4072
4162
|
const triggers = opts.triggers.split(",").map((s) => s.trim()).filter(Boolean);
|
|
4073
4163
|
const s = addSop(dataDir$7(), {
|
|
4074
4164
|
scope: opts.slug ? "customer" : "global",
|
|
@@ -4080,7 +4170,7 @@ sopCommand.command("add <title>").description("Add an SOP (global unless --slug
|
|
|
4080
4170
|
console.log(success(`SOP ${s.id} added (${s.scope}${opts.slug ? `:${opts.slug}` : ""}).`));
|
|
4081
4171
|
});
|
|
4082
4172
|
sopCommand.command("list").description("List SOPs (global + customer if --slug)").option("--slug <slug>", "Customer slug").action(async (opts) => {
|
|
4083
|
-
const { loadSops } = await import("./sop-
|
|
4173
|
+
const { loadSops } = await import("./sop-D33qTHUb.js");
|
|
4084
4174
|
const sops = loadSops(dataDir$7(), opts.slug);
|
|
4085
4175
|
if (sops.length === 0) {
|
|
4086
4176
|
console.log(info("No SOPs."));
|
|
@@ -4089,7 +4179,7 @@ sopCommand.command("list").description("List SOPs (global + customer if --slug)"
|
|
|
4089
4179
|
for (const s of sops) console.log(`[${s.scope}] ${s.title} (${s.triggers.join(", ")})`);
|
|
4090
4180
|
});
|
|
4091
4181
|
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-
|
|
4182
|
+
const { findSops } = await import("./sop-D33qTHUb.js");
|
|
4093
4183
|
const hits = await findSops(dataDir$7(), query, opts.slug);
|
|
4094
4184
|
if (hits.length === 0) {
|
|
4095
4185
|
console.log(info("No matching SOPs."));
|
|
@@ -4104,7 +4194,7 @@ function dataDir$6() {
|
|
|
4104
4194
|
}
|
|
4105
4195
|
const toneCommand = new Command("tone").description("Customer tonality profiles (per customer + global)");
|
|
4106
4196
|
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-
|
|
4197
|
+
const { setTone } = await import("./tone-C7bqK69y.js");
|
|
4108
4198
|
setTone(dataDir$6(), {
|
|
4109
4199
|
...opts.formality ? { formality: opts.formality } : {},
|
|
4110
4200
|
...opts.language ? { language: opts.language } : {},
|
|
@@ -4114,7 +4204,7 @@ toneCommand.command("set").description("Set tone profile (global unless --slug g
|
|
|
4114
4204
|
console.log(success(`Tone profile saved (${opts.slug ? `customer:${opts.slug}` : "global"}).`));
|
|
4115
4205
|
});
|
|
4116
4206
|
toneCommand.command("show").description("Show the effective tone profile").option("--slug <slug>", "Customer slug").action(async (opts) => {
|
|
4117
|
-
const { resolveTone, toneInstruction } = await import("./tone-
|
|
4207
|
+
const { resolveTone, toneInstruction } = await import("./tone-C7bqK69y.js");
|
|
4118
4208
|
const profile = resolveTone(dataDir$6(), opts.slug);
|
|
4119
4209
|
console.log(info(JSON.stringify(profile)));
|
|
4120
4210
|
console.log(`instruction: ${toneInstruction(profile) || "(none)"}`);
|
|
@@ -4128,7 +4218,7 @@ const autofillCommand = new Command("autofill").description("Extract structured
|
|
|
4128
4218
|
return;
|
|
4129
4219
|
}
|
|
4130
4220
|
const transcript = fs.readFileSync(file, "utf-8");
|
|
4131
|
-
const { extractAutofill } = await import("./autofill-
|
|
4221
|
+
const { extractAutofill } = await import("./autofill-B9VtlR2j.js");
|
|
4132
4222
|
const result = await extractAutofill(transcript, opts.slug ? { slug: opts.slug } : {});
|
|
4133
4223
|
console.log(info("Extracted fields (review before applying):"));
|
|
4134
4224
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -4139,7 +4229,7 @@ function dataDir$5() {
|
|
|
4139
4229
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4140
4230
|
}
|
|
4141
4231
|
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-
|
|
4232
|
+
const { askCrm } = await import("./ask-D8iYqDAr.js");
|
|
4143
4233
|
const res = await askCrm(dataDir$5(), question, opts.slug);
|
|
4144
4234
|
if (res.answer) {
|
|
4145
4235
|
console.log(bold("Answer:"));
|
|
@@ -4158,7 +4248,7 @@ function dataDir$4() {
|
|
|
4158
4248
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4159
4249
|
}
|
|
4160
4250
|
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-
|
|
4251
|
+
const { nextBestAction } = await import("./nba-mTJ4yEqD.js");
|
|
4162
4252
|
const actions = await nextBestAction(dataDir$4(), slug);
|
|
4163
4253
|
if (actions.length === 0) {
|
|
4164
4254
|
console.log(info("No recommendations."));
|
|
@@ -4191,12 +4281,12 @@ async function guard(fn) {
|
|
|
4191
4281
|
}
|
|
4192
4282
|
const vaultCommand = new Command("vault").description("Local encrypted credential vault (AES-256-GCM)");
|
|
4193
4283
|
vaultCommand.command("set <name> <value>").description("Store (or overwrite) a secret").action((name, value) => guard(async () => {
|
|
4194
|
-
const { setSecret } = await import("./vault-
|
|
4284
|
+
const { setSecret } = await import("./vault-DxKP4_R2.js");
|
|
4195
4285
|
setSecret(dataDir$3(), masterKey(), name, value);
|
|
4196
4286
|
console.log(success(`Secret '${name}' stored.`));
|
|
4197
4287
|
}));
|
|
4198
4288
|
vaultCommand.command("get <name>").description("Retrieve a secret").action((name) => guard(async () => {
|
|
4199
|
-
const { getSecret } = await import("./vault-
|
|
4289
|
+
const { getSecret } = await import("./vault-DxKP4_R2.js");
|
|
4200
4290
|
const value = getSecret(dataDir$3(), masterKey(), name);
|
|
4201
4291
|
if (value === void 0) {
|
|
4202
4292
|
console.log(info(`No secret named '${name}'.`));
|
|
@@ -4205,7 +4295,7 @@ vaultCommand.command("get <name>").description("Retrieve a secret").action((name
|
|
|
4205
4295
|
console.log(value);
|
|
4206
4296
|
}));
|
|
4207
4297
|
vaultCommand.command("list").description("List secret names (values stay encrypted)").action(() => guard(async () => {
|
|
4208
|
-
const { listSecretKeys } = await import("./vault-
|
|
4298
|
+
const { listSecretKeys } = await import("./vault-DxKP4_R2.js");
|
|
4209
4299
|
const names = listSecretKeys(dataDir$3(), masterKey());
|
|
4210
4300
|
if (names.length === 0) {
|
|
4211
4301
|
console.log(info("Vault is empty."));
|
|
@@ -4214,7 +4304,7 @@ vaultCommand.command("list").description("List secret names (values stay encrypt
|
|
|
4214
4304
|
for (const n of names.sort()) console.log(n);
|
|
4215
4305
|
}));
|
|
4216
4306
|
vaultCommand.command("rm <name>").description("Remove a secret").action((name) => guard(async () => {
|
|
4217
|
-
const { removeSecret } = await import("./vault-
|
|
4307
|
+
const { removeSecret } = await import("./vault-DxKP4_R2.js");
|
|
4218
4308
|
const removed = removeSecret(dataDir$3(), masterKey(), name);
|
|
4219
4309
|
console.log(removed ? success(`Secret '${name}' removed.`) : info(`No secret named '${name}'.`));
|
|
4220
4310
|
}));
|
|
@@ -4230,13 +4320,13 @@ function paint(level, text) {
|
|
|
4230
4320
|
}
|
|
4231
4321
|
const churnCommand = new Command("churn").description("Churn early-warning (relationship-health based)");
|
|
4232
4322
|
churnCommand.command("assess <slug>").description("Assess churn risk for one customer").action(async (slug) => {
|
|
4233
|
-
const { assessChurn } = await import("./churn-
|
|
4323
|
+
const { assessChurn } = await import("./churn-DN9WDGNM.js");
|
|
4234
4324
|
const r = assessChurn(dataDir$2(), slug);
|
|
4235
4325
|
console.log(paint(r.level, `${slug}: ${r.level.toUpperCase()} risk (${r.riskScore}/100)`));
|
|
4236
4326
|
for (const s of r.signals) console.log(` • ${s}`);
|
|
4237
4327
|
});
|
|
4238
4328
|
churnCommand.command("scan").description("Rank all customers by churn risk (highest first)").action(async () => {
|
|
4239
|
-
const { scanChurn } = await import("./churn-
|
|
4329
|
+
const { scanChurn } = await import("./churn-DN9WDGNM.js");
|
|
4240
4330
|
const ranked = scanChurn(dataDir$2());
|
|
4241
4331
|
if (ranked.length === 0) {
|
|
4242
4332
|
console.log(info("No customers to assess."));
|
|
@@ -4251,7 +4341,7 @@ function dataDir$1() {
|
|
|
4251
4341
|
}
|
|
4252
4342
|
const leadscoreCommand = new Command("leadscore").description("Predictive lead scoring (logistic regression on won/lost history)");
|
|
4253
4343
|
leadscoreCommand.command("train").description("Train the model from won/lost history and persist it").action(async () => {
|
|
4254
|
-
const { buildLeadModel, saveLeadModel } = await import("./lead-model-
|
|
4344
|
+
const { buildLeadModel, saveLeadModel } = await import("./lead-model-CEmx7te7.js");
|
|
4255
4345
|
const model = buildLeadModel(dataDir$1());
|
|
4256
4346
|
if (!model.sufficient) {
|
|
4257
4347
|
console.log(warning(`Not enough closed history to train (${model.trainedOn} deals, need ≥4 with both outcomes).`));
|
|
@@ -4262,8 +4352,8 @@ leadscoreCommand.command("train").description("Train the model from won/lost his
|
|
|
4262
4352
|
console.log(success(`Trained on ${model.trainedOn} closed deals. Model saved.`));
|
|
4263
4353
|
});
|
|
4264
4354
|
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-
|
|
4355
|
+
const { loadLeadModel, buildLeadModel, predictWin } = await import("./lead-model-CEmx7te7.js");
|
|
4356
|
+
const { readPipelineSync } = await import("./pipeline-writer-0LJ6Qkat.js");
|
|
4267
4357
|
const model = loadLeadModel(dataDir$1()) ?? buildLeadModel(dataDir$1());
|
|
4268
4358
|
const open = readPipelineSync(dataDir$1(), slug).filter((d) => d.stage !== "won" && d.stage !== "lost");
|
|
4269
4359
|
if (open.length === 0) {
|
|
@@ -4283,7 +4373,7 @@ function dataDir() {
|
|
|
4283
4373
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4284
4374
|
}
|
|
4285
4375
|
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-
|
|
4376
|
+
const { enrichCustomer } = await import("./enrichment-CDFdWmvD.js");
|
|
4287
4377
|
const res = await enrichCustomer(dataDir(), slug, { write: opts.write ?? false });
|
|
4288
4378
|
const applied = Object.entries(res.applied);
|
|
4289
4379
|
if (applied.length === 0) {
|
|
@@ -4318,7 +4408,7 @@ const coachCommand = new Command("coach").description("Conversation-intelligence
|
|
|
4318
4408
|
//#region src/commands/compliance.ts
|
|
4319
4409
|
const complianceCommand = new Command("compliance").description("Privacy/compliance posture (AI-Act Art. 50, local-LLM, PII, guardrails)");
|
|
4320
4410
|
complianceCommand.command("status", { isDefault: true }).description("Show the active compliance configuration").action(async () => {
|
|
4321
|
-
const { complianceConfig, aiDisclosure } = await import("./compliance-
|
|
4411
|
+
const { complianceConfig, aiDisclosure } = await import("./compliance-TqYQXhBj.js");
|
|
4322
4412
|
const cfg = complianceConfig();
|
|
4323
4413
|
const onOff = (b) => b ? success("on") : warning("off");
|
|
4324
4414
|
console.log(info("Compliance posture"));
|
|
@@ -4334,61 +4424,69 @@ complianceCommand.command("status", { isDefault: true }).description("Show the a
|
|
|
4334
4424
|
if (cfg.aiDisclosure) console.log(info(` Disclosure: "${aiDisclosure()}"`));
|
|
4335
4425
|
});
|
|
4336
4426
|
//#endregion
|
|
4427
|
+
//#region src/commands/registry.ts
|
|
4428
|
+
/** Every top-level `dxcrm` command, in display order. */
|
|
4429
|
+
const ALL_COMMANDS = [
|
|
4430
|
+
initCommand,
|
|
4431
|
+
createCommand,
|
|
4432
|
+
listCommand,
|
|
4433
|
+
validateCommand,
|
|
4434
|
+
sessionCommand,
|
|
4435
|
+
guideCommand,
|
|
4436
|
+
mcpCommand,
|
|
4437
|
+
syncCommand,
|
|
4438
|
+
backupCommand,
|
|
4439
|
+
restoreCommand,
|
|
4440
|
+
daemonCommand,
|
|
4441
|
+
statusCommand,
|
|
4442
|
+
agentCommand,
|
|
4443
|
+
importCommand,
|
|
4444
|
+
serverCommand,
|
|
4445
|
+
auditCommand,
|
|
4446
|
+
logsCommand,
|
|
4447
|
+
doctorCommand,
|
|
4448
|
+
rbacCommand,
|
|
4449
|
+
gdprCommand,
|
|
4450
|
+
securityReportCommand,
|
|
4451
|
+
stagesCommand,
|
|
4452
|
+
pluginCommand,
|
|
4453
|
+
goalCommand,
|
|
4454
|
+
pushCommand,
|
|
4455
|
+
attachCommand,
|
|
4456
|
+
templateCommand,
|
|
4457
|
+
sequenceCommand,
|
|
4458
|
+
quoteCommand,
|
|
4459
|
+
ticketCommand,
|
|
4460
|
+
surveyCommand,
|
|
4461
|
+
kbCommand,
|
|
4462
|
+
fieldsCommand,
|
|
4463
|
+
objectCommand,
|
|
4464
|
+
webhookCommand,
|
|
4465
|
+
segmentCommand,
|
|
4466
|
+
identityCommand,
|
|
4467
|
+
metricsCommand,
|
|
4468
|
+
usageCommand,
|
|
4469
|
+
approvalsCommand,
|
|
4470
|
+
policyCommand,
|
|
4471
|
+
hygieneCommand,
|
|
4472
|
+
memoryCommand,
|
|
4473
|
+
sopCommand,
|
|
4474
|
+
toneCommand,
|
|
4475
|
+
autofillCommand,
|
|
4476
|
+
askCommand,
|
|
4477
|
+
nbaCommand,
|
|
4478
|
+
vaultCommand,
|
|
4479
|
+
churnCommand,
|
|
4480
|
+
leadscoreCommand,
|
|
4481
|
+
enrichCommand,
|
|
4482
|
+
coachCommand,
|
|
4483
|
+
complianceCommand
|
|
4484
|
+
];
|
|
4485
|
+
//#endregion
|
|
4337
4486
|
//#region src/cli.ts
|
|
4338
4487
|
const program = new Command();
|
|
4339
4488
|
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);
|
|
4489
|
+
for (const command of ALL_COMMANDS) program.addCommand(command);
|
|
4392
4490
|
await program.parseAsync(process.argv);
|
|
4393
4491
|
//#endregion
|
|
4394
4492
|
export {};
|