@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.
Files changed (286) hide show
  1. package/README.md +264 -670
  2. package/dist/{approvals-DpjxGHFp.js → approvals-CmDT2eUg.js} +7 -24
  3. package/dist/approvals-CmDT2eUg.js.map +1 -0
  4. package/dist/{ask-CID3jnuL.js → ask-D8iYqDAr.js} +6 -6
  5. package/dist/{ask-CID3jnuL.js.map → ask-D8iYqDAr.js.map} +1 -1
  6. package/dist/atomic-write-8yjqqLtS.js +29 -0
  7. package/dist/atomic-write-8yjqqLtS.js.map +1 -0
  8. package/dist/atomic-write-BYmF-ThH.cjs +37 -0
  9. package/dist/atomic-write-BYmF-ThH.cjs.map +1 -0
  10. package/dist/auth-B5DcjJ_6.js +2 -0
  11. package/dist/{auth-DFWwWcYD.js → auth-DDXZTwS0.js} +4 -13
  12. package/dist/auth-DDXZTwS0.js.map +1 -0
  13. package/dist/{autofill-Di_-SP7t.js → autofill-B9VtlR2j.js} +2 -2
  14. package/dist/{autofill-Di_-SP7t.js.map → autofill-B9VtlR2j.js.map} +1 -1
  15. package/dist/{backup-CeMk9z86.js → backup-CTlIxUdO.js} +5 -7
  16. package/dist/backup-CTlIxUdO.js.map +1 -0
  17. package/dist/backup-LFnC09oV.js +2 -0
  18. package/dist/{churn-C28IgnAj.js → churn-DN9WDGNM.js} +3 -3
  19. package/dist/{churn-C28IgnAj.js.map → churn-DN9WDGNM.js.map} +1 -1
  20. package/dist/cli.js +282 -184
  21. package/dist/cli.js.map +1 -1
  22. package/dist/{compliance-CKSBoQUe.js → compliance-Bc12Hn9a.js} +3 -3
  23. package/dist/{compliance-CKSBoQUe.js.map → compliance-Bc12Hn9a.js.map} +1 -1
  24. package/dist/{compliance-CujOqAKk.js → compliance-TqYQXhBj.js} +1 -1
  25. package/dist/{compliance-B1kk5-YS.js → compliance-kq0xHRw3.js} +3 -3
  26. package/dist/{compliance-B1kk5-YS.js.map → compliance-kq0xHRw3.js.map} +1 -1
  27. package/dist/{compliance-B91zNvCR.cjs → compliance-pAj9FcGI.cjs} +3 -3
  28. package/dist/{compliance-B91zNvCR.cjs.map → compliance-pAj9FcGI.cjs.map} +1 -1
  29. package/dist/{context-builder-BzWAp3Zs.js → context-builder-7Uab5-G4.js} +3 -2
  30. package/dist/context-builder-7Uab5-G4.js.map +1 -0
  31. package/dist/context-builder-hmOPvgso.js +2 -0
  32. package/dist/{custom-fields-CzNeD3_v.js → custom-fields-BMyz5Ruh.js} +1 -1
  33. package/dist/{custom-fields-Pl2t9xzp.js → custom-fields-GzpOHW_2.js} +4 -13
  34. package/dist/custom-fields-GzpOHW_2.js.map +1 -0
  35. package/dist/{custom-objects-CIFrmQ2V.js → custom-objects-BNy-ayR-.js} +1 -1
  36. package/dist/{custom-objects-BHgn1GEX.js → custom-objects-CxW1gHwJ.js} +10 -25
  37. package/dist/custom-objects-CxW1gHwJ.js.map +1 -0
  38. package/dist/{customer-dir-DIylZ8Q6.js → customer-dir-CkMMXhb0.js} +9 -4
  39. package/dist/customer-dir-CkMMXhb0.js.map +1 -0
  40. package/dist/daemon/worker.js +66 -40
  41. package/dist/daemon/worker.js.map +1 -1
  42. package/dist/doctor-C14-vnJ1.js +103 -0
  43. package/dist/doctor-C14-vnJ1.js.map +1 -0
  44. package/dist/{enrichment-3XvgGDfB.js → enrichment-CDFdWmvD.js} +3 -3
  45. package/dist/{enrichment-3XvgGDfB.js.map → enrichment-CDFdWmvD.js.map} +1 -1
  46. package/dist/{file-lock-B_zi7NQl.js → file-lock-CcHotQkZ.js} +3 -4
  47. package/dist/file-lock-CcHotQkZ.js.map +1 -0
  48. package/dist/{gmail-sync-rQaVqKWd.js → gmail-sync-C-NmibzS.js} +13 -9
  49. package/dist/gmail-sync-C-NmibzS.js.map +1 -0
  50. package/dist/{gmail-sync-DIaxInDT.js → gmail-sync-DueE6tl5.js} +14 -10
  51. package/dist/gmail-sync-DueE6tl5.js.map +1 -0
  52. package/dist/{gmail-sync-hHm9gaWd.cjs → gmail-sync-GEy3oVvw.cjs} +13 -9
  53. package/dist/gmail-sync-GEy3oVvw.cjs.map +1 -0
  54. package/dist/{gmail-webhook-handler-DS7OlRPX.js → gmail-webhook-handler-B26COilD.js} +2 -2
  55. package/dist/{gmail-webhook-handler-e5Od25FX.js → gmail-webhook-handler-kGKpbY9h.js} +4 -4
  56. package/dist/{gmail-webhook-handler-e5Od25FX.js.map → gmail-webhook-handler-kGKpbY9h.js.map} +1 -1
  57. package/dist/{goal-engine-KpBftn4V.js → goal-engine-BbroPhqm.js} +10 -11
  58. package/dist/goal-engine-BbroPhqm.js.map +1 -0
  59. package/dist/{goal-engine-CUZSpERI.js → goal-engine-CfDAJTFt.js} +1 -1
  60. package/dist/{google-drive-sync-DEPcqFca.js → google-drive-sync-D1n7WKZn.js} +3 -3
  61. package/dist/{google-drive-sync-DEPcqFca.js.map → google-drive-sync-D1n7WKZn.js.map} +1 -1
  62. package/dist/{hygiene-DZqfYpFf.js → hygiene-DzQPnc6P.js} +3 -3
  63. package/dist/{hygiene-DZqfYpFf.js.map → hygiene-DzQPnc6P.js.map} +1 -1
  64. package/dist/identity-CB7j-Zr1.js +2 -0
  65. package/dist/{identity-CI6olMNm.js → identity-_uZ3Lbr2.js} +2 -2
  66. package/dist/{identity-CI6olMNm.js.map → identity-_uZ3Lbr2.js.map} +1 -1
  67. package/dist/{import-hubspot-BaK71U_K.js → import-hubspot-DB4n89jy.js} +51 -45
  68. package/dist/import-hubspot-DB4n89jy.js.map +1 -0
  69. package/dist/{index-V8BFaH-b.d.ts → index-B0IMMrp_.d.ts} +8 -4
  70. package/dist/{index-V8BFaH-b.d.ts.map → index-B0IMMrp_.d.ts.map} +1 -1
  71. package/dist/{index-YqwMd6aQ.d.cts → index-pY7tYXwH.d.cts} +8 -4
  72. package/dist/{index-YqwMd6aQ.d.cts.map → index-pY7tYXwH.d.cts.map} +1 -1
  73. package/dist/index.cjs +19 -21
  74. package/dist/index.cjs.map +1 -1
  75. package/dist/index.d.cts +8 -4
  76. package/dist/index.d.cts.map +1 -1
  77. package/dist/index.d.ts +8 -4
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +19 -21
  80. package/dist/index.js.map +1 -1
  81. package/dist/{interactions-writer-DO3KcSR3.js → interactions-writer-BZzUIgJd.js} +5 -2
  82. package/dist/interactions-writer-BZzUIgJd.js.map +1 -0
  83. package/dist/{interactions-writer-SLHnoEeE.js → interactions-writer-DbSyI2rt.js} +32 -3
  84. package/dist/interactions-writer-DbSyI2rt.js.map +1 -0
  85. package/dist/interactions-writer-RJB8SWf2.js +2 -0
  86. package/dist/{interactions-writer-CrPStUll.cjs → interactions-writer-a2yzBd7T.cjs} +5 -2
  87. package/dist/interactions-writer-a2yzBd7T.cjs.map +1 -0
  88. package/dist/json-store-WWsFzXub.js +43 -0
  89. package/dist/json-store-WWsFzXub.js.map +1 -0
  90. package/dist/{knowledge-base-D0Fh40kc.js → knowledge-base-DHNc4hVj.js} +43 -16
  91. package/dist/knowledge-base-DHNc4hVj.js.map +1 -0
  92. package/dist/{lancedb-CCBbpulq.js → lancedb-CswQEE5K.js} +1 -1
  93. package/dist/{lancedb-rlvWoPwl.js → lancedb-CuHKNsNZ.js} +4 -3
  94. package/dist/lancedb-CuHKNsNZ.js.map +1 -0
  95. package/dist/{lead-model-BCFzyktm.js → lead-model-CEmx7te7.js} +6 -14
  96. package/dist/lead-model-CEmx7te7.js.map +1 -0
  97. package/dist/{llm-Z8RIYkpF.js → llm-BnSUBisu.js} +2 -2
  98. package/dist/{llm-Z8RIYkpF.js.map → llm-BnSUBisu.js.map} +1 -1
  99. package/dist/{llm-iijeXmgq.cjs → llm-CXycmEl9.cjs} +2 -2
  100. package/dist/{llm-iijeXmgq.cjs.map → llm-CXycmEl9.cjs.map} +1 -1
  101. package/dist/{llm-DEjWcqmW.js → llm-DSX1-wFu.js} +1 -1
  102. package/dist/{llm-DvzZqva0.js → llm-PZzgPphl.js} +3 -3
  103. package/dist/{llm-DvzZqva0.js.map → llm-PZzgPphl.js.map} +1 -1
  104. package/dist/logger-BkInaGoV.cjs +167 -0
  105. package/dist/logger-BkInaGoV.cjs.map +1 -0
  106. package/dist/logger-Dyl4VcLO.js +147 -0
  107. package/dist/logger-Dyl4VcLO.js.map +1 -0
  108. package/dist/logger-UaF5p9d1.js +147 -0
  109. package/dist/logger-UaF5p9d1.js.map +1 -0
  110. package/dist/logger-vKQS34w9.js +2 -0
  111. package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
  112. package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
  113. package/dist/mcp.cjs +327 -303
  114. package/dist/mcp.cjs.map +1 -1
  115. package/dist/mcp.d.cts.map +1 -1
  116. package/dist/mcp.d.ts.map +1 -1
  117. package/dist/mcp.js +327 -303
  118. package/dist/mcp.js.map +1 -1
  119. package/dist/{memory-Cy6-Tbyl.js → memory-D8hmgD9d.js} +1 -1
  120. package/dist/{memory-Bb6ky3kb.js → memory-Dzr9dXSM.js} +4 -11
  121. package/dist/memory-Dzr9dXSM.js.map +1 -0
  122. package/dist/{microsoft-calendar-B6MMtUQK.js → microsoft-calendar-jIu9K5zX.js} +4 -4
  123. package/dist/{microsoft-calendar-B6MMtUQK.js.map → microsoft-calendar-jIu9K5zX.js.map} +1 -1
  124. package/dist/{microsoft-sync-CpZVoSuq.js → microsoft-sync-R_r8HL-B.js} +5 -5
  125. package/dist/{microsoft-sync-CpZVoSuq.js.map → microsoft-sync-R_r8HL-B.js.map} +1 -1
  126. package/dist/{nba-3wanmJ0U.js → nba-mTJ4yEqD.js} +3 -3
  127. package/dist/{nba-3wanmJ0U.js.map → nba-mTJ4yEqD.js.map} +1 -1
  128. package/dist/{notification-dispatcher-0vYNngWe.js → notification-dispatcher-inpKyuBz.js} +7 -3
  129. package/dist/notification-dispatcher-inpKyuBz.js.map +1 -0
  130. package/dist/{pipeline-writer-BqBrYrQc.js → pipeline-writer-0LJ6Qkat.js} +1 -1
  131. package/dist/{pipeline-writer-N2omexxp.cjs → pipeline-writer-B1tRAhuD.cjs} +11 -3
  132. package/dist/pipeline-writer-B1tRAhuD.cjs.map +1 -0
  133. package/dist/{pipeline-writer-BvVquKIe.js → pipeline-writer-CIllfnZl.js} +5 -3
  134. package/dist/pipeline-writer-CIllfnZl.js.map +1 -0
  135. package/dist/{pipeline-writer-eufx_0o1.js → pipeline-writer-rDj-ni6q.js} +6 -4
  136. package/dist/pipeline-writer-rDj-ni6q.js.map +1 -0
  137. package/dist/{proactive-agent-BgQXw3ac.js → proactive-agent-B7u3Bj_l.js} +6 -6
  138. package/dist/{proactive-agent-BgQXw3ac.js.map → proactive-agent-B7u3Bj_l.js.map} +1 -1
  139. package/dist/{proactive-worker-BrLHNhjH.js → proactive-worker-1zkm6aJD.js} +7 -8
  140. package/dist/proactive-worker-1zkm6aJD.js.map +1 -0
  141. package/dist/{push-manager-CowY-0IK.js → push-manager-BXM-IHfP.js} +1 -1
  142. package/dist/{push-manager-CdqIIkuh.js → push-manager-C0ECQgva.js} +4 -4
  143. package/dist/push-manager-C0ECQgva.js.map +1 -0
  144. package/dist/{quote-generator-OhSFsi3x.js → quote-generator-ByUyIYtw.js} +1 -1
  145. package/dist/{quote-generator-BfwENXzg.js → quote-generator-CTdR8eEI.js} +5 -5
  146. package/dist/quote-generator-CTdR8eEI.js.map +1 -0
  147. package/dist/rbac-DzbyFhVH.js +2 -0
  148. package/dist/{rbac-CTIktZaC.js → rbac-msmBc_tK.js} +19 -12
  149. package/dist/rbac-msmBc_tK.js.map +1 -0
  150. package/dist/regex-Jt5DatPi.js +13 -0
  151. package/dist/regex-Jt5DatPi.js.map +1 -0
  152. package/dist/{relationship-health-odxEoQdJ.js → relationship-health-ZZNXR1RZ.js} +8 -16
  153. package/dist/relationship-health-ZZNXR1RZ.js.map +1 -0
  154. package/dist/{revenue-simulation-Bqf2DLVB.js → revenue-simulation-D8f_YkUY.js} +9 -19
  155. package/dist/revenue-simulation-D8f_YkUY.js.map +1 -0
  156. package/dist/{revenue-simulation-BJdRTEHc.js → revenue-simulation-njJZlTqm.js} +1 -1
  157. package/dist/safe-path-mpp0dKtO.js +18 -0
  158. package/dist/safe-path-mpp0dKtO.js.map +1 -0
  159. package/dist/{segments-BqcD5HIl.js → segments-DI3LOQNe.js} +5 -14
  160. package/dist/segments-DI3LOQNe.js.map +1 -0
  161. package/dist/sequence-engine-C6nnewHX.js +2 -0
  162. package/dist/{sequence-engine-J1lTW_in.js → sequence-engine-DNTVLq7o.js} +15 -8
  163. package/dist/sequence-engine-DNTVLq7o.js.map +1 -0
  164. package/dist/{sequence-store-DaaWr0Os.js → sequence-store-CmYb6s0g.js} +6 -5
  165. package/dist/sequence-store-CmYb6s0g.js.map +1 -0
  166. package/dist/{server-Dyva03K8.js → server-DqSMYhSA.js} +278 -220
  167. package/dist/server-DqSMYhSA.js.map +1 -0
  168. package/dist/{session-D9ub6Wl1.js → session-B6XaP83h.js} +3 -3
  169. package/dist/session-B6XaP83h.js.map +1 -0
  170. package/dist/{session-B9AilxOE.js → session-BgGDyP2C.js} +3 -3
  171. package/dist/session-BgGDyP2C.js.map +1 -0
  172. package/dist/session-Bp4zTh4l.js +2 -0
  173. package/dist/{session-D0qFkBla.cjs → session-Mm7GQbSH.cjs} +3 -3
  174. package/dist/session-Mm7GQbSH.cjs.map +1 -0
  175. package/dist/{session-store-C8tEvMPw.js → session-store-DWxJ5Pof.js} +79 -17
  176. package/dist/session-store-DWxJ5Pof.js.map +1 -0
  177. package/dist/{session-store-B0QZE8Bx.cjs → session-store-yfwnj0OC.cjs} +126 -16
  178. package/dist/session-store-yfwnj0OC.cjs.map +1 -0
  179. package/dist/{sla-engine-5IhTsBUR.js → sla-engine-CP2KiKDS.js} +1 -1
  180. package/dist/{sla-engine-BqX-7u-7.js → sla-engine-O-A1ntu_.js} +2 -2
  181. package/dist/{sla-engine-BqX-7u-7.js.map → sla-engine-O-A1ntu_.js.map} +1 -1
  182. package/dist/{sop-Vp0UPWFW.js → sop-BV7ICAFR.js} +4 -11
  183. package/dist/sop-BV7ICAFR.js.map +1 -0
  184. package/dist/{sop-DkhVChGy.js → sop-D33qTHUb.js} +1 -1
  185. package/dist/survey-engine-DKctGcLQ.js +2 -0
  186. package/dist/{survey-engine-DBjCYqCv.js → survey-engine-DngXBv47.js} +5 -4
  187. package/dist/survey-engine-DngXBv47.js.map +1 -0
  188. package/dist/{sync-state-CwLSt_1m.js → sync-state-BaA8LbTI.js} +1 -1
  189. package/dist/{sync-state-ChaLbamC.js → sync-state-DMZgzpez.js} +4 -12
  190. package/dist/sync-state-DMZgzpez.js.map +1 -0
  191. package/dist/{ticket-writer-CjqKeIRD.js → ticket-writer-DsfpeLGZ.js} +1 -1
  192. package/dist/{ticket-writer-j2oX_Wal.js → ticket-writer-a9on36Wb.js} +12 -24
  193. package/dist/ticket-writer-a9on36Wb.js.map +1 -0
  194. package/dist/{tone-Bdm5uaht.js → tone-C7bqK69y.js} +5 -12
  195. package/dist/tone-C7bqK69y.js.map +1 -0
  196. package/dist/{tone-DRKlZgPr.cjs → tone-Cmc7O2Fx.cjs} +3 -9
  197. package/dist/tone-Cmc7O2Fx.cjs.map +1 -0
  198. package/dist/{tone-vNb2DAAD.js → tone-mXSftvTn.js} +3 -8
  199. package/dist/tone-mXSftvTn.js.map +1 -0
  200. package/dist/{transcript-watcher-CL2QUygI.js → transcript-watcher-0mh2ZhmH.js} +18 -11
  201. package/dist/transcript-watcher-0mh2ZhmH.js.map +1 -0
  202. package/dist/unmatched-transcripts-C92zAoM4.js +2 -0
  203. package/dist/unmatched-transcripts-DC-VQ9YS.js +16 -0
  204. package/dist/unmatched-transcripts-DC-VQ9YS.js.map +1 -0
  205. package/dist/update-deal-CWy1eLJI.js +2 -0
  206. package/dist/{update-deal-DKC79skb.js → update-deal-DSzr_Aau.js} +3 -3
  207. package/dist/{update-deal-DKC79skb.js.map → update-deal-DSzr_Aau.js.map} +1 -1
  208. package/dist/{usage-D0-TYJkw.js → usage-BVlFlKW_.js} +8 -6
  209. package/dist/usage-BVlFlKW_.js.map +1 -0
  210. package/dist/usage-CClTf5e6.cjs.map +1 -1
  211. package/dist/usage-D0u9a-lV.js.map +1 -1
  212. package/dist/{vault-DXCg29W-.js → vault-CfwZdNzC.js} +3 -4
  213. package/dist/vault-CfwZdNzC.js.map +1 -0
  214. package/dist/{vault-C1D3zScD.js → vault-DxKP4_R2.js} +1 -1
  215. package/dist/{webhooks-Xn6zO6kd.cjs → webhooks-CwW-3kvG.cjs} +5 -19
  216. package/dist/webhooks-CwW-3kvG.cjs.map +1 -0
  217. package/dist/{webhooks-7EpA05Qr.js → webhooks-DXr1IoKn.js} +8 -21
  218. package/dist/webhooks-DXr1IoKn.js.map +1 -0
  219. package/dist/{webhooks-BO2UAnmn.js → webhooks-sWZ8CJtR.js} +5 -18
  220. package/dist/webhooks-sWZ8CJtR.js.map +1 -0
  221. package/package.json +11 -2
  222. package/dist/approvals-DpjxGHFp.js.map +0 -1
  223. package/dist/auth-CyFuu9X_.js +0 -2
  224. package/dist/auth-DFWwWcYD.js.map +0 -1
  225. package/dist/backup-CeMk9z86.js.map +0 -1
  226. package/dist/backup-f_hC7rBV.js +0 -2
  227. package/dist/context-builder-BzWAp3Zs.js.map +0 -1
  228. package/dist/context-builder-DlrRcqmJ.js +0 -2
  229. package/dist/custom-fields-Pl2t9xzp.js.map +0 -1
  230. package/dist/custom-objects-BHgn1GEX.js.map +0 -1
  231. package/dist/customer-dir-DIylZ8Q6.js.map +0 -1
  232. package/dist/file-lock-B_zi7NQl.js.map +0 -1
  233. package/dist/gmail-sync-DIaxInDT.js.map +0 -1
  234. package/dist/gmail-sync-hHm9gaWd.cjs.map +0 -1
  235. package/dist/gmail-sync-rQaVqKWd.js.map +0 -1
  236. package/dist/goal-engine-KpBftn4V.js.map +0 -1
  237. package/dist/identity-gyfWdrcX.js +0 -2
  238. package/dist/import-hubspot-BaK71U_K.js.map +0 -1
  239. package/dist/interactions-writer-CrPStUll.cjs.map +0 -1
  240. package/dist/interactions-writer-DO3KcSR3.js.map +0 -1
  241. package/dist/interactions-writer-SLHnoEeE.js.map +0 -1
  242. package/dist/interactions-writer-dSPy1XfO.js +0 -2
  243. package/dist/knowledge-base-D0Fh40kc.js.map +0 -1
  244. package/dist/lancedb-rlvWoPwl.js.map +0 -1
  245. package/dist/lead-model-BCFzyktm.js.map +0 -1
  246. package/dist/memory-Bb6ky3kb.js.map +0 -1
  247. package/dist/notification-dispatcher-0vYNngWe.js.map +0 -1
  248. package/dist/pipeline-writer-BvVquKIe.js.map +0 -1
  249. package/dist/pipeline-writer-N2omexxp.cjs.map +0 -1
  250. package/dist/pipeline-writer-eufx_0o1.js.map +0 -1
  251. package/dist/proactive-worker-BrLHNhjH.js.map +0 -1
  252. package/dist/push-manager-CdqIIkuh.js.map +0 -1
  253. package/dist/quote-generator-BfwENXzg.js.map +0 -1
  254. package/dist/rbac-C7c8tcES.js +0 -2
  255. package/dist/rbac-CTIktZaC.js.map +0 -1
  256. package/dist/relationship-health-odxEoQdJ.js.map +0 -1
  257. package/dist/revenue-simulation-Bqf2DLVB.js.map +0 -1
  258. package/dist/segments-BqcD5HIl.js.map +0 -1
  259. package/dist/sequence-engine-CCTHEBgi.js +0 -2
  260. package/dist/sequence-engine-J1lTW_in.js.map +0 -1
  261. package/dist/sequence-store-DaaWr0Os.js.map +0 -1
  262. package/dist/server-Dyva03K8.js.map +0 -1
  263. package/dist/session-B9AilxOE.js.map +0 -1
  264. package/dist/session-D0qFkBla.cjs.map +0 -1
  265. package/dist/session-D9ub6Wl1.js.map +0 -1
  266. package/dist/session-mWHA71Lw.js +0 -2
  267. package/dist/session-store-B0QZE8Bx.cjs.map +0 -1
  268. package/dist/session-store-C8tEvMPw.js.map +0 -1
  269. package/dist/sop-Vp0UPWFW.js.map +0 -1
  270. package/dist/survey-engine-C06hcQt3.js +0 -2
  271. package/dist/survey-engine-DBjCYqCv.js.map +0 -1
  272. package/dist/sync-state-ChaLbamC.js.map +0 -1
  273. package/dist/ticket-writer-j2oX_Wal.js.map +0 -1
  274. package/dist/tone-Bdm5uaht.js.map +0 -1
  275. package/dist/tone-DRKlZgPr.cjs.map +0 -1
  276. package/dist/tone-vNb2DAAD.js.map +0 -1
  277. package/dist/transcript-watcher-CL2QUygI.js.map +0 -1
  278. package/dist/unmatched-transcripts-BsH5bhkU.js +0 -26
  279. package/dist/unmatched-transcripts-BsH5bhkU.js.map +0 -1
  280. package/dist/unmatched-transcripts-D0PrJ9iz.js +0 -2
  281. package/dist/update-deal-BNwPGaTV.js +0 -2
  282. package/dist/usage-D0-TYJkw.js.map +0 -1
  283. package/dist/vault-DXCg29W-.js.map +0 -1
  284. package/dist/webhooks-7EpA05Qr.js.map +0 -1
  285. package/dist/webhooks-BO2UAnmn.js.map +0 -1
  286. package/dist/webhooks-Xn6zO6kd.cjs.map +0 -1
package/dist/mcp.cjs CHANGED
@@ -1,10 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-DakpK96I.cjs");
3
- const require_session_store = require("./session-store-B0QZE8Bx.cjs");
3
+ const require_session_store = require("./session-store-yfwnj0OC.cjs");
4
+ const require_atomic_write = require("./atomic-write-BYmF-ThH.cjs");
4
5
  const require_write_queue = require("./write-queue-BDolUxfs.cjs");
5
- const require_interactions_writer = require("./interactions-writer-CrPStUll.cjs");
6
- const require_pipeline_writer = require("./pipeline-writer-N2omexxp.cjs");
7
- const require_llm = require("./llm-iijeXmgq.cjs");
6
+ const require_interactions_writer = require("./interactions-writer-a2yzBd7T.cjs");
7
+ const require_logger = require("./logger-BkInaGoV.cjs");
8
+ const require_pipeline_writer = require("./pipeline-writer-B1tRAhuD.cjs");
9
+ const require_llm = require("./llm-CXycmEl9.cjs");
8
10
  let path = require("path");
9
11
  path = require_chunk.__toESM(path, 1);
10
12
  let fs = require("fs");
@@ -63,11 +65,10 @@ async function readSubscriptions(dataDir) {
63
65
  async function writeSubscriptions(dataDir, subs) {
64
66
  const filePath = subscriptionsPath(dataDir);
65
67
  fs.default.mkdirSync(path.default.dirname(filePath), { recursive: true });
66
- const file = {
68
+ require_session_store.writeJsonFile(filePath, {
67
69
  subscriptions: subs,
68
70
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
69
- };
70
- fs.default.writeFileSync(filePath, JSON.stringify(file, null, 2), "utf-8");
71
+ });
71
72
  }
72
73
  function expiresAtForProvider(provider) {
73
74
  if (provider === "gmail") return new Date(Date.now() + 10080 * 60 * 1e3).toISOString();
@@ -98,23 +99,15 @@ function getSyncStatePath(dataDir) {
98
99
  return path.default.join(dataDir, ".agentic", "sync-state.json");
99
100
  }
100
101
  function readSyncState(dataDir) {
101
- const filePath = getSyncStatePath(dataDir);
102
- if (!fs.default.existsSync(filePath)) return {};
103
- try {
104
- return JSON.parse(fs.default.readFileSync(filePath, "utf-8"));
105
- } catch {
106
- return {};
107
- }
102
+ return require_session_store.readJsonFile(getSyncStatePath(dataDir), {});
108
103
  }
109
104
  function updateSlugSyncState(dataDir, slug, update) {
110
- const filePath = getSyncStatePath(dataDir);
111
- fs.default.mkdirSync(path.default.dirname(filePath), { recursive: true });
112
105
  const state = readSyncState(dataDir);
113
106
  state[slug] = {
114
107
  ...state[slug],
115
108
  ...update
116
109
  };
117
- fs.default.writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
110
+ require_session_store.writeJsonFile(getSyncStatePath(dataDir), state);
118
111
  }
119
112
  function getLastGmailSync(dataDir, slug) {
120
113
  const ts = readSyncState(dataDir)[slug]?.lastGmailSync;
@@ -456,6 +449,7 @@ Config: \`.agentic/rbac.json\` | Actor: \`DXCRM_ACTOR\` env var
456
449
  | list_backups | List available backups with date, size, verification status, and customer count | any |
457
450
  | trigger_sync | Force immediate Gmail sync for one or all customers | rep+ |
458
451
  | get_audit_log | Read audit log — all write operations with actor, tool, customer | admin |
452
+ | get_logs | Query/aggregate the structured application log (level, component, errors) | admin |
459
453
  | define_custom_object | Define a runtime custom object type with typed fields (no migration) | admin |
460
454
  | create_record | Create a record of a custom object (validated against its schema) | rep+ |
461
455
  | list_records | List records of a custom object | any |
@@ -1330,6 +1324,16 @@ function registerGetActiveSession(server) {
1330
1324
  }, async () => handleGetActiveSession());
1331
1325
  }
1332
1326
  //#endregion
1327
+ //#region src/core/regex.ts
1328
+ /**
1329
+ * Escape a string so it can be embedded safely as a literal inside a `RegExp`.
1330
+ * Prevents both broken patterns and ReDoS/injection when interpolating
1331
+ * field names, section headers, or other dynamic values into a regex.
1332
+ */
1333
+ function escapeRegExp(value) {
1334
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1335
+ }
1336
+ //#endregion
1333
1337
  //#region src/core/context-builder.ts
1334
1338
  var context_builder_exports = /* @__PURE__ */ require_chunk.__exportAll({ buildContext: () => buildContext });
1335
1339
  const MAX_INTERACTIONS = 10;
@@ -1345,7 +1349,7 @@ function parsePipelineContent(filePath) {
1345
1349
  return fs.default.readFileSync(filePath, "utf-8").trim();
1346
1350
  }
1347
1351
  function extractSection(content, sectionName) {
1348
- const match = new RegExp(`## ${sectionName}([\\s\\S]*?)(?=^## |$)`, "m").exec(content);
1352
+ const match = new RegExp(`## ${escapeRegExp(sectionName)}([\\s\\S]*?)(?=^## |$)`, "m").exec(content);
1349
1353
  return match ? (match[1] ?? "").trim() : "";
1350
1354
  }
1351
1355
  async function buildContext(dataDir, slug) {
@@ -1422,7 +1426,7 @@ async function buildContext(dataDir, slug) {
1422
1426
  }
1423
1427
  //#endregion
1424
1428
  //#region src/mcp/tools/get-customer-context.ts
1425
- const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1429
+ const DATA_DIR$52 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1426
1430
  function triggerOnQuerySync(dataDir, slug) {
1427
1431
  const auth = getGmailAuth();
1428
1432
  if (!auth) return;
@@ -1435,7 +1439,7 @@ function triggerOnQuerySync(dataDir, slug) {
1435
1439
  const sources = JSON.parse(fs.default.readFileSync(sourcesPath, "utf-8"));
1436
1440
  if (!sources.gmail?.enabled || !sources.gmail.query) return;
1437
1441
  const query = sources.gmail.query;
1438
- Promise.resolve().then(() => require("./gmail-sync-hHm9gaWd.cjs")).then(({ syncGmail }) => syncGmail({
1442
+ Promise.resolve().then(() => require("./gmail-sync-GEy3oVvw.cjs")).then(({ syncGmail }) => syncGmail({
1439
1443
  slug,
1440
1444
  dataDir,
1441
1445
  auth,
@@ -1443,7 +1447,7 @@ function triggerOnQuerySync(dataDir, slug) {
1443
1447
  }).then(() => updateSlugSyncState(dataDir, slug, { lastGmailSync: (/* @__PURE__ */ new Date()).toISOString() })).catch(() => {})).catch(() => {});
1444
1448
  } catch {}
1445
1449
  }
1446
- async function handleGetCustomerContext(input, dataDir = DATA_DIR$51) {
1450
+ async function handleGetCustomerContext(input, dataDir = DATA_DIR$52) {
1447
1451
  const targetSlug = input.slug ?? require_session_store.getSession()?.customerSlug;
1448
1452
  if (!targetSlug) return {
1449
1453
  content: [{
@@ -1559,7 +1563,7 @@ async function indexInLanceDB(dataDir, slug, text, sourceRef, meta) {
1559
1563
  }]);
1560
1564
  await table.mergeInsert("source_ref").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute(data);
1561
1565
  } catch (err) {
1562
- process.stderr.write(`[lancedb] indexInLanceDB failed: ${err.message}\n`);
1566
+ require_logger.logger.error("lancedb", "indexInLanceDB failed", { error: err.message });
1563
1567
  }
1564
1568
  }
1565
1569
  async function searchKnowledge(dataDir, slug, query, limit) {
@@ -1579,8 +1583,8 @@ async function searchKnowledge(dataDir, slug, query, limit) {
1579
1583
  }
1580
1584
  //#endregion
1581
1585
  //#region src/mcp/tools/search-customer-knowledge.ts
1582
- const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1583
- async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$50) {
1586
+ const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1587
+ async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$51) {
1584
1588
  const limit = input.limit ?? 5;
1585
1589
  try {
1586
1590
  const results = await searchKnowledge(dataDir, input.slug, input.query, limit);
@@ -1628,14 +1632,14 @@ If no results: returns empty array with a helpful sync suggestion.`,
1628
1632
  }
1629
1633
  //#endregion
1630
1634
  //#region src/mcp/tools/list-customers.ts
1631
- const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1635
+ const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1632
1636
  function extractLastInteractionDate(interactionsPath) {
1633
1637
  if (!fs.default.existsSync(interactionsPath)) return void 0;
1634
1638
  const content = fs.default.readFileSync(interactionsPath, "utf-8");
1635
1639
  const match = /^## (\d{4}-\d{2}-\d{2})/m.exec(content);
1636
1640
  return match ? match[1] : void 0;
1637
1641
  }
1638
- async function handleListCustomers(input, dataDir = DATA_DIR$49) {
1642
+ async function handleListCustomers(input, dataDir = DATA_DIR$50) {
1639
1643
  const customersDir = path.default.join(dataDir, "customers");
1640
1644
  const customers = [];
1641
1645
  if (!fs.default.existsSync(customersDir)) return { content: [{
@@ -1643,6 +1647,7 @@ async function handleListCustomers(input, dataDir = DATA_DIR$49) {
1643
1647
  text: JSON.stringify([], null, 2)
1644
1648
  }] };
1645
1649
  const entries = fs.default.readdirSync(customersDir);
1650
+ const canSee = require_session_store.customerVisibility(dataDir, process.env["DXCRM_ACTOR"] ?? "system");
1646
1651
  for (const entry of entries) {
1647
1652
  const customerDir = path.default.join(customersDir, entry);
1648
1653
  try {
@@ -1669,7 +1674,7 @@ async function handleListCustomers(input, dataDir = DATA_DIR$49) {
1669
1674
  const filterLower = input.filter.toLowerCase();
1670
1675
  if (!(name.toLowerCase().includes(filterLower) || entry.toLowerCase().includes(filterLower) || stage.toLowerCase().includes(filterLower))) continue;
1671
1676
  }
1672
- if (!require_session_store.canSeeCustomer(dataDir, process.env["DXCRM_ACTOR"] ?? "system", entry)) continue;
1677
+ if (!canSee(entry)) continue;
1673
1678
  customers.push(summary);
1674
1679
  } catch {
1675
1680
  continue;
@@ -1704,8 +1709,7 @@ async function withJsonFile(filePath, updater) {
1704
1709
  current = null;
1705
1710
  }
1706
1711
  const next = await updater(current);
1707
- fs.default.mkdirSync(path.default.dirname(filePath), { recursive: true });
1708
- fs.default.writeFileSync(filePath, JSON.stringify(next, null, 2), "utf-8");
1712
+ require_atomic_write.writeFileAtomic(filePath, JSON.stringify(next, null, 2));
1709
1713
  return next;
1710
1714
  });
1711
1715
  }
@@ -1729,7 +1733,7 @@ function readGraph(dataDir, slug) {
1729
1733
  try {
1730
1734
  return JSON.parse(fs.default.readFileSync(p, "utf-8"));
1731
1735
  } catch {
1732
- process.stderr.write(`[graph] failed to parse ${p} — returning empty graph\n`);
1736
+ require_logger.logger.warn("graph", "failed to parse graph file — returning empty graph", { path: p });
1733
1737
  return emptyGraph(slug);
1734
1738
  }
1735
1739
  }
@@ -1982,23 +1986,13 @@ function healthPath(dataDir, slug) {
1982
1986
  return path.default.join(dataDir, "customers", slug, "health.json");
1983
1987
  }
1984
1988
  function readHealth(dataDir, slug) {
1985
- const p = healthPath(dataDir, slug);
1986
- if (!fs.default.existsSync(p)) return null;
1987
- try {
1988
- return JSON.parse(fs.default.readFileSync(p, "utf-8"));
1989
- } catch {
1990
- return null;
1991
- }
1989
+ return require_session_store.readJsonFile(healthPath(dataDir, slug), null);
1992
1990
  }
1993
1991
  function writeHealth(dataDir, slug, health) {
1994
- const p = healthPath(dataDir, slug);
1995
- const dir = path.default.dirname(p);
1996
- if (!fs.default.existsSync(dir)) fs.default.mkdirSync(dir, { recursive: true });
1997
- const updated = {
1992
+ require_session_store.writeJsonFile(healthPath(dataDir, slug), {
1998
1993
  ...health,
1999
1994
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2000
- };
2001
- fs.default.writeFileSync(p, JSON.stringify(updated, null, 2), "utf-8");
1995
+ });
2002
1996
  }
2003
1997
  function parseContactInteractions(content) {
2004
1998
  const blocks = content.split(/(?=^## \d{4}-\d{2}-\d{2})/m).filter((b) => b.trim().length > 0);
@@ -2158,8 +2152,8 @@ async function updateHealthFromInteraction(dataDir, slug) {
2158
2152
  }
2159
2153
  //#endregion
2160
2154
  //#region src/mcp/tools/log-interaction.ts
2161
- const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2162
- async function handleLogInteraction(input, dataDir = DATA_DIR$48) {
2155
+ const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2156
+ async function handleLogInteraction(input, dataDir = DATA_DIR$49) {
2163
2157
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
2164
2158
  const interactionDate = input.date ?? today;
2165
2159
  const sourceRef = input.source ?? `agent://log/${Date.now()}`;
@@ -2189,7 +2183,7 @@ async function handleLogInteraction(input, dataDir = DATA_DIR$48) {
2189
2183
  raw.data.last_touchpoint = interactionDate;
2190
2184
  let serialized = gray_matter.default.stringify(raw.content, raw.data);
2191
2185
  serialized = serialized.replace(/^(last_touchpoint:\s*)['"](\d{4}-\d{2}-\d{2})['"]/m, "$1$2");
2192
- fs.default.writeFileSync(mainFactsPath, serialized, "utf-8");
2186
+ require_atomic_write.writeFileAtomic(mainFactsPath, serialized);
2193
2187
  } catch {}
2194
2188
  require_session_store.writeAuditEntry(dataDir, {
2195
2189
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -2268,8 +2262,8 @@ var update_deal_exports = /* @__PURE__ */ require_chunk.__exportAll({
2268
2262
  handleUpdateDeal: () => handleUpdateDeal,
2269
2263
  registerUpdateDeal: () => registerUpdateDeal
2270
2264
  });
2271
- const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2272
- async function handleUpdateDeal(input, dataDir = DATA_DIR$47) {
2265
+ const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2266
+ async function handleUpdateDeal(input, dataDir = DATA_DIR$48) {
2273
2267
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
2274
2268
  const deal = {
2275
2269
  name: input.dealName,
@@ -2352,12 +2346,12 @@ Returns: { success: boolean, deal: object }`,
2352
2346
  }
2353
2347
  //#endregion
2354
2348
  //#region src/mcp/tools/export-customer.ts
2355
- const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2349
+ const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2356
2350
  function countInteractions(content) {
2357
2351
  const matches = content.match(/^## \d{4}-\d{2}-\d{2}/gm);
2358
2352
  return matches ? matches.length : 0;
2359
2353
  }
2360
- async function handleExportCustomer(input, dataDir = DATA_DIR$46) {
2354
+ async function handleExportCustomer(input, dataDir = DATA_DIR$47) {
2361
2355
  require_session_store.enforceRbac(dataDir, "export_customer");
2362
2356
  const customerDir = path.default.join(dataDir, "customers", input.slug);
2363
2357
  if (!fs.default.existsSync(customerDir)) return {
@@ -2450,8 +2444,8 @@ Returns:
2450
2444
  }
2451
2445
  //#endregion
2452
2446
  //#region src/mcp/tools/update-customer-facts.ts
2453
- const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2454
- async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$45) {
2447
+ const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2448
+ async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$46) {
2455
2449
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2456
2450
  try {
2457
2451
  require_session_store.enforceRbac(dataDir, "update_customer_facts");
@@ -2601,10 +2595,36 @@ function scoreDeal(deal, signals) {
2601
2595
  warnings
2602
2596
  };
2603
2597
  }
2598
+ const MS_PER_DAY = 864e5;
2599
+ /**
2600
+ * Derive activity/close timing for a deal relative to `todayDate`. Centralizes
2601
+ * the day-diff math that deal-room and deal-agent each computed identically.
2602
+ * A blank/whitespace close_date yields `undefined` (not a NaN day count).
2603
+ */
2604
+ function deriveDealTiming(deal, todayDate) {
2605
+ const updatedDate = deal.updated ? new Date(deal.updated) : todayDate;
2606
+ const daysSinceLastActivity = Math.floor((todayDate.getTime() - updatedDate.getTime()) / MS_PER_DAY);
2607
+ const timing = {
2608
+ daysSinceLastActivity,
2609
+ daysInCurrentStage: daysSinceLastActivity
2610
+ };
2611
+ if (deal.close_date && deal.close_date.trim() !== "") timing.daysToClose = Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / MS_PER_DAY);
2612
+ return timing;
2613
+ }
2614
+ /** Score a deal using timing derived from `todayDate` plus the deal's probability. */
2615
+ function scoreDealForToday(deal, todayDate) {
2616
+ const timing = deriveDealTiming(deal, todayDate);
2617
+ return scoreDeal(deal, {
2618
+ daysSinceLastActivity: timing.daysSinceLastActivity,
2619
+ daysInCurrentStage: timing.daysInCurrentStage,
2620
+ ...timing.daysToClose !== void 0 ? { daysToClose: timing.daysToClose } : {},
2621
+ ...deal.probability !== void 0 ? { probability: deal.probability } : {}
2622
+ });
2623
+ }
2604
2624
  //#endregion
2605
2625
  //#region src/mcp/tools/get-deal-health.ts
2606
- const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2607
- async function handleGetDealHealth(input, dataDir = DATA_DIR$44) {
2626
+ const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2627
+ async function handleGetDealHealth(input, dataDir = DATA_DIR$45) {
2608
2628
  try {
2609
2629
  const deals = await require_pipeline_writer.readPipeline(dataDir, input.slug);
2610
2630
  const today = /* @__PURE__ */ new Date();
@@ -2653,28 +2673,13 @@ Returns: { slug, deals: [{ deal, stage, score, grade, signals, warnings }] }`,
2653
2673
  }
2654
2674
  //#endregion
2655
2675
  //#region src/mcp/tools/get-pipeline-forecast.ts
2656
- const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2657
- async function handleGetPipelineForecast(input, dataDir = DATA_DIR$43) {
2676
+ const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2677
+ async function handleGetPipelineForecast(input, dataDir = DATA_DIR$44) {
2658
2678
  try {
2659
- const customersDir = path.default.join(dataDir, "customers");
2660
- if (!fs.default.existsSync(customersDir)) return { content: [{
2661
- type: "text",
2662
- text: JSON.stringify({
2663
- deals: [],
2664
- totalWeightedValue: 0,
2665
- byStage: {}
2666
- }, null, 2)
2667
- }] };
2668
- const slugs = fs.default.readdirSync(customersDir).filter((d) => {
2669
- if (input.filter && !d.includes(input.filter)) return false;
2670
- return fs.default.statSync(path.default.join(customersDir, d)).isDirectory();
2671
- });
2679
+ const slugs = require_session_store.listCustomerSlugs(dataDir).filter((d) => !input.filter || d.includes(input.filter));
2672
2680
  const allDeals = [];
2673
2681
  for (const slug of slugs) {
2674
- const pipelinePath = path.default.join(customersDir, slug, "pipeline.md");
2675
- if (!fs.default.existsSync(pipelinePath)) continue;
2676
- const { readPipeline } = await Promise.resolve().then(() => require("./pipeline-writer-N2omexxp.cjs")).then((n) => n.pipeline_writer_exports);
2677
- const deals = await readPipeline(dataDir, slug).catch(() => []);
2682
+ const deals = require_pipeline_writer.readPipelineSync(dataDir, slug);
2678
2683
  for (const deal of deals) {
2679
2684
  if (deal.stage === "won" || deal.stage === "lost") continue;
2680
2685
  const prob = deal.probability ?? 50;
@@ -2730,13 +2735,13 @@ Returns: { deals: [...], totalWeightedValue: number, byStage: { stage: { count,
2730
2735
  }
2731
2736
  //#endregion
2732
2737
  //#region src/mcp/tools/summarize-meeting.ts
2733
- const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2734
- async function handleSummarizeMeeting(input, dataDir = DATA_DIR$42) {
2738
+ const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2739
+ async function handleSummarizeMeeting(input, dataDir = DATA_DIR$43) {
2735
2740
  try {
2736
2741
  let summary = input.transcript.slice(0, 400);
2737
2742
  let nextSteps = [];
2738
2743
  try {
2739
- const { callLlm } = await Promise.resolve().then(() => require("./llm-iijeXmgq.cjs")).then((n) => n.llm_exports);
2744
+ const { callLlm } = await Promise.resolve().then(() => require("./llm-CXycmEl9.cjs")).then((n) => n.llm_exports);
2740
2745
  const response = await callLlm(`Summarize this meeting transcript in 3-5 sentences and extract action items.\n\nTranscript:\n${input.transcript.slice(0, 3e3)}\n\nRespond as JSON: { "summary": "...", "nextSteps": ["..."] }`);
2741
2746
  const parsed = JSON.parse(response);
2742
2747
  summary = parsed.summary ?? summary;
@@ -2850,18 +2855,12 @@ function stagesPath(dataDir) {
2850
2855
  return path.default.join(dataDir, ".agentic", "pipeline-stages.json");
2851
2856
  }
2852
2857
  function getPipelineStages(dataDir) {
2853
- const p = stagesPath(dataDir);
2854
- if (!fs.default.existsSync(p)) return DEFAULT_STAGES;
2855
- try {
2856
- return JSON.parse(fs.default.readFileSync(p, "utf-8"));
2857
- } catch {
2858
- return DEFAULT_STAGES;
2859
- }
2858
+ return require_session_store.readJsonFile(stagesPath(dataDir), DEFAULT_STAGES);
2860
2859
  }
2861
2860
  //#endregion
2862
2861
  //#region src/mcp/tools/get-pipeline-stages.ts
2863
- const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2864
- async function handleGetPipelineStages(_input, dataDir = DATA_DIR$41) {
2862
+ const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2863
+ async function handleGetPipelineStages(_input, dataDir = DATA_DIR$42) {
2865
2864
  const stages = getPipelineStages(dataDir);
2866
2865
  return { content: [{
2867
2866
  type: "text",
@@ -2879,21 +2878,18 @@ function registerGetPipelineStages(server) {
2879
2878
  //#region src/core/cross-customer.ts
2880
2879
  async function searchAcrossCustomers(dataDir, query, limit = 5, excludeSlug) {
2881
2880
  const slugs = require_session_store.listCustomerSlugs(dataDir).filter((d) => d !== excludeSlug);
2882
- const allResults = [];
2883
- for (const slug of slugs) {
2884
- const results = await searchKnowledge(dataDir, slug, query, 2);
2885
- for (const r of results) allResults.push({
2881
+ return (await Promise.all(slugs.map(async (slug) => {
2882
+ return (await searchKnowledge(dataDir, slug, query, 2)).map((r) => ({
2886
2883
  slug,
2887
2884
  relevantContent: r.content.slice(0, 200),
2888
2885
  score: r.score
2889
- });
2890
- }
2891
- return allResults.sort((a, b) => b.score - a.score).slice(0, limit);
2886
+ }));
2887
+ }))).flat().sort((a, b) => b.score - a.score).slice(0, limit);
2892
2888
  }
2893
2889
  //#endregion
2894
2890
  //#region src/mcp/tools/get-market-intelligence.ts
2895
- const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2896
- async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$40) {
2891
+ const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2892
+ async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$41) {
2897
2893
  const excludeSlug = input.excludeCurrentCustomer ? input.slug : void 0;
2898
2894
  const all = require_session_store.listCustomerSlugs(dataDir);
2899
2895
  const totalCustomersSearched = excludeSlug ? all.filter((s) => s !== excludeSlug).length : all.length;
@@ -2924,7 +2920,7 @@ function registerGetMarketIntelligence(server) {
2924
2920
  }
2925
2921
  //#endregion
2926
2922
  //#region src/mcp/tools/get-relationship-graph.ts
2927
- const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2923
+ const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2928
2924
  function summarizeNode(n) {
2929
2925
  return {
2930
2926
  id: n.id,
@@ -2932,7 +2928,7 @@ function summarizeNode(n) {
2932
2928
  email: n.properties["email"]
2933
2929
  };
2934
2930
  }
2935
- async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$39) {
2931
+ async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$40) {
2936
2932
  try {
2937
2933
  const graph = readGraph(dataDir, input.slug);
2938
2934
  const stakeholders = getStakeholders(graph);
@@ -3000,9 +2996,9 @@ Returns: {
3000
2996
  }
3001
2997
  //#endregion
3002
2998
  //#region src/mcp/tools/get-relationship-health.ts
3003
- const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2999
+ const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3004
3000
  const MAX_HEALTH_AGE_MS = 3600 * 1e3;
3005
- async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$38) {
3001
+ async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$39) {
3006
3002
  try {
3007
3003
  let health = readHealth(dataDir, input.slug);
3008
3004
  if (health === null || Date.now() - new Date(health.updatedAt).getTime() > MAX_HEALTH_AGE_MS) {
@@ -3082,8 +3078,7 @@ async function writePlaybook(dataDir, slug, playbook) {
3082
3078
  const filePath = path.default.join(dir, `${playbook.name}.md`);
3083
3079
  await require_write_queue.withFileQueue(filePath, async () => {
3084
3080
  fs.default.mkdirSync(dir, { recursive: true });
3085
- const raw = gray_matter.default.stringify(playbook.content, playbook.frontmatter);
3086
- fs.default.writeFileSync(filePath, raw, "utf-8");
3081
+ require_atomic_write.writeFileAtomic(filePath, gray_matter.default.stringify(playbook.content, playbook.frontmatter));
3087
3082
  });
3088
3083
  }
3089
3084
  function toKebabCase(name) {
@@ -3285,11 +3280,10 @@ function writeAgentQueue(dataDir, slug, queue) {
3285
3280
  const p = agentQueuePath(dataDir, slug);
3286
3281
  const dir = path.default.dirname(p);
3287
3282
  if (!fs.default.existsSync(dir)) fs.default.mkdirSync(dir, { recursive: true });
3288
- const updated = {
3283
+ require_session_store.writeJsonFile(p, {
3289
3284
  ...queue,
3290
3285
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3291
- };
3292
- fs.default.writeFileSync(p, JSON.stringify(updated, null, 2), "utf-8");
3286
+ });
3293
3287
  }
3294
3288
  function makeActionId() {
3295
3289
  return `da_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
@@ -3324,17 +3318,9 @@ async function observeDeal(dataDir, slug, dealName, today) {
3324
3318
  const deal = (await require_pipeline_writer.readPipeline(dataDir, slug).catch(() => [])).find((d) => d.name.toLowerCase() === dealName.toLowerCase());
3325
3319
  if (!deal) return null;
3326
3320
  const todayDate = new Date(today);
3327
- const updatedDate = deal.updated ? new Date(deal.updated) : todayDate;
3328
- const daysSinceLastActivity = Math.floor((todayDate.getTime() - updatedDate.getTime()) / 864e5);
3329
- const daysInCurrentStage = daysSinceLastActivity;
3330
- const daysToClose = deal.close_date && deal.close_date.trim() !== "" ? Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / 864e5) : void 0;
3331
- const dealHealthScore = scoreDeal(deal, {
3332
- daysSinceLastActivity,
3333
- daysInCurrentStage,
3334
- ...daysToClose !== void 0 ? { daysToClose } : {},
3335
- ...deal.probability !== void 0 ? { probability: deal.probability } : {}
3336
- });
3337
- const health = computeCustomerHealth(dataDir, slug, today);
3321
+ const { daysSinceLastActivity, daysInCurrentStage, daysToClose } = deriveDealTiming(deal, todayDate);
3322
+ const dealHealthScore = scoreDealForToday(deal, todayDate);
3323
+ const health = readHealth(dataDir, slug) ?? computeCustomerHealth(dataDir, slug, today);
3338
3324
  const atRiskContacts = health.contacts.filter((c) => c.riskFlags.length > 0).map((c) => c.email ?? c.contactId);
3339
3325
  const coldContacts = health.contacts.filter((c) => c.trend === "cold").map((c) => c.email ?? c.contactId);
3340
3326
  const stakeholders = getStakeholders(readGraph(dataDir, slug));
@@ -3562,7 +3548,7 @@ async function executeAction(action, dataDir) {
3562
3548
  if (!slug) return "skipped";
3563
3549
  switch (action.type) {
3564
3550
  case "log_interaction": {
3565
- const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-CrPStUll.cjs")).then((n) => n.interactions_writer_exports);
3551
+ const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-a2yzBd7T.cjs")).then((n) => n.interactions_writer_exports);
3566
3552
  await appendInteraction(dataDir, slug, {
3567
3553
  date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
3568
3554
  type: action.payload["type"] ?? "Note",
@@ -3575,7 +3561,7 @@ async function executeAction(action, dataDir) {
3575
3561
  return "executed";
3576
3562
  }
3577
3563
  case "schedule_meeting": {
3578
- const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-CrPStUll.cjs")).then((n) => n.interactions_writer_exports);
3564
+ const { appendInteraction } = await Promise.resolve().then(() => require("./interactions-writer-a2yzBd7T.cjs")).then((n) => n.interactions_writer_exports);
3579
3565
  await appendInteraction(dataDir, slug, {
3580
3566
  date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
3581
3567
  type: "Note",
@@ -3681,8 +3667,8 @@ async function runDealAgent(config, dataDir, llmFn = require_llm.callLlm) {
3681
3667
  }
3682
3668
  //#endregion
3683
3669
  //#region src/mcp/tools/run-deal-agent.ts
3684
- const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3685
- async function handleRunDealAgent(input, dataDir = DATA_DIR$37) {
3670
+ const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3671
+ async function handleRunDealAgent(input, dataDir = DATA_DIR$38) {
3686
3672
  try {
3687
3673
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3688
3674
  const result = await runDealAgent({
@@ -3749,8 +3735,8 @@ Returns: { assessment, riskLevel, plan[], actionsQueued[], actionsExecuted[], tr
3749
3735
  }
3750
3736
  //#endregion
3751
3737
  //#region src/mcp/tools/approve-agent-action.ts
3752
- const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3753
- async function handleApproveAgentAction(input, dataDir = DATA_DIR$36) {
3738
+ const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3739
+ async function handleApproveAgentAction(input, dataDir = DATA_DIR$37) {
3754
3740
  try {
3755
3741
  const queue = readAgentQueue(dataDir, input.slug);
3756
3742
  const idx = queue.pendingActions.findIndex((a) => a.actionId === input.actionId);
@@ -4010,8 +3996,8 @@ async function buildSimulationInput(dataDir, horizon, today, externalSignals = [
4010
3996
  }
4011
3997
  //#endregion
4012
3998
  //#region src/mcp/tools/simulate-revenue.ts
4013
- const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4014
- async function handleSimulateRevenue(input, dataDir = DATA_DIR$35) {
3999
+ const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4000
+ async function handleSimulateRevenue(input, dataDir = DATA_DIR$36) {
4015
4001
  try {
4016
4002
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
4017
4003
  const horizon = input.horizon ?? "quarter";
@@ -4069,8 +4055,8 @@ Returns: { forecast: { p10, p50, p90, expected, stdDev, atRiskRevenue, byCloseMo
4069
4055
  }
4070
4056
  //#endregion
4071
4057
  //#region src/mcp/tools/get-playbook.ts
4072
- const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4073
- async function handleGetPlaybook(input, dataDir = DATA_DIR$34) {
4058
+ const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4059
+ async function handleGetPlaybook(input, dataDir = DATA_DIR$35) {
4074
4060
  try {
4075
4061
  const playbooks = listPlaybooks(dataDir, input.slug);
4076
4062
  if (!(input.stage !== void 0 || input.value !== void 0 || input.healthScore !== void 0)) return { content: [{
@@ -4155,12 +4141,12 @@ Returns: { matches: [{ name, score, trigger, successRate, usedCount, content }],
4155
4141
  ...healthScore !== void 0 ? { healthScore } : {},
4156
4142
  ...daysSinceContact !== void 0 ? { daysSinceContact } : {},
4157
4143
  ...championPresent !== void 0 ? { championPresent } : {}
4158
- }, DATA_DIR$34));
4144
+ }, DATA_DIR$35));
4159
4145
  }
4160
4146
  //#endregion
4161
4147
  //#region src/mcp/tools/create-playbook.ts
4162
- const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4163
- async function handleCreatePlaybook(input, dataDir = DATA_DIR$33) {
4148
+ const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4149
+ async function handleCreatePlaybook(input, dataDir = DATA_DIR$34) {
4164
4150
  try {
4165
4151
  const name = toKebabCase(input.name);
4166
4152
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -4233,12 +4219,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path } }`,
4233
4219
  trigger,
4234
4220
  content,
4235
4221
  ...successRate !== void 0 ? { successRate } : {}
4236
- }, DATA_DIR$33));
4222
+ }, DATA_DIR$34));
4237
4223
  }
4238
4224
  //#endregion
4239
4225
  //#region src/mcp/tools/list-playbooks.ts
4240
- const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4241
- async function handleListPlaybooks(input, dataDir = DATA_DIR$32) {
4226
+ const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4227
+ async function handleListPlaybooks(input, dataDir = DATA_DIR$33) {
4242
4228
  try {
4243
4229
  const playbooks = listPlaybooks(dataDir, input.slug);
4244
4230
  return { content: [{
@@ -4277,12 +4263,12 @@ Args:
4277
4263
 
4278
4264
  Returns: { playbooks: [{ name, trigger, successRate, usedCount, lastUpdated }], count, slug }`,
4279
4265
  inputSchema: zod.z.object({ slug: zod.z.string().describe("Customer ID") })
4280
- }, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$32));
4266
+ }, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$33));
4281
4267
  }
4282
4268
  //#endregion
4283
4269
  //#region src/mcp/tools/distill-playbook.ts
4284
- const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4285
- async function handleDistillPlaybook(input, dataDir = DATA_DIR$31, llmFn = require_llm.callLlm) {
4270
+ const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4271
+ async function handleDistillPlaybook(input, dataDir = DATA_DIR$32, llmFn = require_llm.callLlm) {
4286
4272
  try {
4287
4273
  const result = await distillPlaybook(dataDir, input.slug, input.dealName, input.outcome, llmFn);
4288
4274
  if (!result.ok) {
@@ -4341,7 +4327,7 @@ Returns: { success: true, playbook: { name, trigger, successRate, path }, reason
4341
4327
  slug,
4342
4328
  dealName,
4343
4329
  outcome
4344
- }, DATA_DIR$31));
4330
+ }, DATA_DIR$32));
4345
4331
  }
4346
4332
  //#endregion
4347
4333
  //#region src/core/goal-engine.ts
@@ -4559,8 +4545,8 @@ function getActiveGoals(dataDir) {
4559
4545
  }
4560
4546
  //#endregion
4561
4547
  //#region src/mcp/tools/pursue-goal.ts
4562
- const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4563
- async function handlePursueGoal(input, dataDir = DATA_DIR$30, options = {}) {
4548
+ const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4549
+ async function handlePursueGoal(input, dataDir = DATA_DIR$31, options = {}) {
4564
4550
  try {
4565
4551
  require_session_store.enforceRbac(dataDir, "pursue_goal");
4566
4552
  const goal = await pursueGoal(dataDir, {
@@ -4623,12 +4609,12 @@ Returns: { goalId, description, target, deadline, decomposition: { analysis, cur
4623
4609
  goal,
4624
4610
  deadline,
4625
4611
  ...context !== void 0 ? { context } : {}
4626
- }, DATA_DIR$30));
4612
+ }, DATA_DIR$31));
4627
4613
  }
4628
4614
  //#endregion
4629
4615
  //#region src/mcp/tools/get-goal-status.ts
4630
- const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4631
- async function handleGetGoalStatus(input, dataDir = DATA_DIR$29) {
4616
+ const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4617
+ async function handleGetGoalStatus(input, dataDir = DATA_DIR$30) {
4632
4618
  try {
4633
4619
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
4634
4620
  const allGoals = input.goalId ? readGoals(dataDir).filter((g) => g.id === input.goalId) : getActiveGoals(dataDir);
@@ -4687,17 +4673,17 @@ Args:
4687
4673
 
4688
4674
  Returns: { goals: [{ id, description, target, progress, status, deadline, daysRemaining, subGoals }], activeCount, completedCount }`,
4689
4675
  inputSchema: zod.z.object({ goalId: zod.z.string().optional().describe("Specific goal ID (omit for all active goals)") })
4690
- }, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$29));
4676
+ }, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$30));
4691
4677
  }
4692
4678
  //#endregion
4693
4679
  //#region src/mcp/tools/register-push-subscription.ts
4694
- const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4680
+ const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4695
4681
  const VALID_PROVIDERS = [
4696
4682
  "gmail",
4697
4683
  "microsoft-graph",
4698
4684
  "slack"
4699
4685
  ];
4700
- async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$28) {
4686
+ async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$29) {
4701
4687
  try {
4702
4688
  if (!VALID_PROVIDERS.includes(input.provider)) return { content: [{
4703
4689
  type: "text",
@@ -4783,12 +4769,12 @@ Returns: { subscriptionId, provider, slug, status, expiresAt, createdAt, warning
4783
4769
  ...microsoftResource !== void 0 ? { microsoftResource } : {},
4784
4770
  ...slackTeamId !== void 0 ? { slackTeamId } : {},
4785
4771
  ...slackChannelId !== void 0 ? { slackChannelId } : {}
4786
- }, DATA_DIR$28));
4772
+ }, DATA_DIR$29));
4787
4773
  }
4788
4774
  //#endregion
4789
4775
  //#region src/mcp/tools/get-push-status.ts
4790
- const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4791
- async function handleGetPushStatus(input, dataDir = DATA_DIR$27) {
4776
+ const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4777
+ async function handleGetPushStatus(input, dataDir = DATA_DIR$28) {
4792
4778
  try {
4793
4779
  let subs = await readSubscriptions(dataDir);
4794
4780
  if (input.slug) subs = subs.filter((s) => s.slug === input.slug);
@@ -4860,7 +4846,7 @@ Returns: { subscriptions: [{ id, provider, slug, status, expiresAt, expiresInHou
4860
4846
  }, async ({ slug, provider }) => handleGetPushStatus({
4861
4847
  ...slug !== void 0 ? { slug } : {},
4862
4848
  ...provider !== void 0 ? { provider } : {}
4863
- }, DATA_DIR$27));
4849
+ }, DATA_DIR$28));
4864
4850
  }
4865
4851
  //#endregion
4866
4852
  //#region src/core/org-intelligence.ts
@@ -4926,8 +4912,8 @@ function deriveRecommendation(people, missingRoles) {
4926
4912
  }
4927
4913
  //#endregion
4928
4914
  //#region src/mcp/tools/get-org-intelligence.ts
4929
- const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4930
- async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$26) {
4915
+ const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4916
+ async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$27) {
4931
4917
  try {
4932
4918
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
4933
4919
  const map = buildStakeholderMap(dataDir, input.slug, today, input.dealName);
@@ -4978,15 +4964,7 @@ async function buildDealRoom(dataDir, slug, dealName, today) {
4978
4964
  });
4979
4965
  const todayDate = new Date(today);
4980
4966
  const dealHealth = pipelineDeals.filter((d) => d.stage !== "won" && d.stage !== "lost").map((deal) => {
4981
- const updatedDate = deal.updated ? new Date(deal.updated) : todayDate;
4982
- const daysSinceLastActivity = Math.floor((todayDate.getTime() - updatedDate.getTime()) / 864e5);
4983
- const daysToClose = deal.close_date ? Math.floor((new Date(deal.close_date).getTime() - todayDate.getTime()) / 864e5) : void 0;
4984
- const scored = scoreDeal(deal, {
4985
- daysSinceLastActivity,
4986
- daysInCurrentStage: daysSinceLastActivity,
4987
- ...daysToClose !== void 0 ? { daysToClose } : {},
4988
- ...deal.probability !== void 0 ? { probability: deal.probability } : {}
4989
- });
4967
+ const scored = scoreDealForToday(deal, todayDate);
4990
4968
  return {
4991
4969
  deal: deal.name,
4992
4970
  stage: deal.stage,
@@ -5068,8 +5046,8 @@ function buildExecutiveSummary(slug, dealName, stakeholders, overallHealth, sim,
5068
5046
  }
5069
5047
  //#endregion
5070
5048
  //#region src/mcp/tools/open-deal-room.ts
5071
- const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5072
- async function handleOpenDealRoom(input, dataDir = DATA_DIR$25) {
5049
+ const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5050
+ async function handleOpenDealRoom(input, dataDir = DATA_DIR$26) {
5073
5051
  try {
5074
5052
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5075
5053
  const brief = await buildDealRoom(dataDir, input.slug, input.dealName, today);
@@ -5152,8 +5130,8 @@ async function buildDailyBriefing(dataDir, today) {
5152
5130
  }
5153
5131
  //#endregion
5154
5132
  //#region src/mcp/tools/get-proactive-briefing.ts
5155
- const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5156
- async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$24) {
5133
+ const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5134
+ async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$25) {
5157
5135
  try {
5158
5136
  const briefing = await buildDailyBriefing(dataDir, input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
5159
5137
  return { content: [{
@@ -5253,15 +5231,15 @@ function getTemplate(dataDir, id) {
5253
5231
  }
5254
5232
  //#endregion
5255
5233
  //#region src/mcp/tools/list-email-templates.ts
5256
- const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5257
- async function handleListEmailTemplates(input, dataDir = DATA_DIR$23) {
5234
+ const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5235
+ async function handleListEmailTemplates(input, dataDir = DATA_DIR$24) {
5258
5236
  const summary = listTemplates(dataDir, input.category ? { category: input.category } : {}).map(({ body: _body, ...meta }) => meta);
5259
5237
  return { content: [{
5260
5238
  type: "text",
5261
5239
  text: JSON.stringify(summary, null, 2)
5262
5240
  }] };
5263
5241
  }
5264
- function registerListEmailTemplates(server, dataDir = DATA_DIR$23) {
5242
+ function registerListEmailTemplates(server, dataDir = DATA_DIR$24) {
5265
5243
  server.registerTool("list_email_templates", {
5266
5244
  description: "List available email templates. Optionally filter by category (e.g. 'outreach', 'followup', 'support').",
5267
5245
  inputSchema: zod.z.object({ category: zod.z.string().optional().describe("Filter by category") })
@@ -5295,8 +5273,8 @@ async function buildVariablesFromCustomer(dataDir, slug) {
5295
5273
  }
5296
5274
  //#endregion
5297
5275
  //#region src/mcp/tools/get-email-template.ts
5298
- const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5299
- async function handleGetEmailTemplate(input, dataDir = DATA_DIR$22) {
5276
+ const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5277
+ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$23) {
5300
5278
  const tmpl = getTemplate(dataDir, input.id);
5301
5279
  if (!tmpl) return { content: [{
5302
5280
  type: "text",
@@ -5312,7 +5290,7 @@ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$22) {
5312
5290
  }, null, 2)
5313
5291
  }] };
5314
5292
  }
5315
- function registerGetEmailTemplate(server, dataDir = DATA_DIR$22) {
5293
+ function registerGetEmailTemplate(server, dataDir = DATA_DIR$23) {
5316
5294
  server.registerTool("get_email_template", {
5317
5295
  description: "Get a specific email template by ID, including its body and detected variables.",
5318
5296
  inputSchema: zod.z.object({ id: zod.z.string().describe("Template ID (e.g. 'enterprise-intro')") })
@@ -5320,8 +5298,8 @@ function registerGetEmailTemplate(server, dataDir = DATA_DIR$22) {
5320
5298
  }
5321
5299
  //#endregion
5322
5300
  //#region src/mcp/tools/draft-email.ts
5323
- const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5324
- async function handleDraftEmail(input, dataDir = DATA_DIR$21) {
5301
+ const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5302
+ async function handleDraftEmail(input, dataDir = DATA_DIR$22) {
5325
5303
  const tmpl = getTemplate(dataDir, input.templateId);
5326
5304
  if (!tmpl) return { content: [{
5327
5305
  type: "text",
@@ -5335,17 +5313,17 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$21) {
5335
5313
  const interpolatedBody = interpolate(tmpl.body, vars);
5336
5314
  let effectiveTone = input.tone;
5337
5315
  if (!effectiveTone) {
5338
- const { resolveTone, toneInstruction } = await Promise.resolve().then(() => require("./tone-DRKlZgPr.cjs"));
5316
+ const { resolveTone, toneInstruction } = await Promise.resolve().then(() => require("./tone-Cmc7O2Fx.cjs"));
5339
5317
  const instr = toneInstruction(resolveTone(dataDir, input.slug));
5340
5318
  if (instr) effectiveTone = instr;
5341
5319
  }
5342
5320
  let body = interpolatedBody;
5343
5321
  let polished = false;
5344
5322
  if (effectiveTone) try {
5345
- const { callLlm } = await Promise.resolve().then(() => require("./llm-iijeXmgq.cjs")).then((n) => n.llm_exports);
5323
+ const { callLlm } = await Promise.resolve().then(() => require("./llm-CXycmEl9.cjs")).then((n) => n.llm_exports);
5346
5324
  const refined = await callLlm(`Rewrite the following email in a ${effectiveTone} tone. Keep the same language, preserve all names and facts, and do not invent details. Return ONLY the rewritten email body, no preamble.\n\n---\n${interpolatedBody}`);
5347
5325
  if (refined && refined.trim()) {
5348
- const { labelAiContent } = await Promise.resolve().then(() => require("./compliance-B91zNvCR.cjs")).then((n) => n.compliance_exports);
5326
+ const { labelAiContent } = await Promise.resolve().then(() => require("./compliance-pAj9FcGI.cjs")).then((n) => n.compliance_exports);
5349
5327
  body = labelAiContent(refined.trim());
5350
5328
  polished = true;
5351
5329
  }
@@ -5365,7 +5343,7 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$21) {
5365
5343
  }, null, 2)
5366
5344
  }] };
5367
5345
  }
5368
- function registerDraftEmail(server, dataDir = DATA_DIR$21) {
5346
+ function registerDraftEmail(server, dataDir = DATA_DIR$22) {
5369
5347
  server.registerTool("draft_email", {
5370
5348
  description: `Draft a personalized email for a customer using a stored template.
5371
5349
  Variables are auto-filled from the customer's main_facts.md. Override any variable manually.
@@ -5473,8 +5451,8 @@ async function updateEnrollment(dataDir, id, updates) {
5473
5451
  }
5474
5452
  //#endregion
5475
5453
  //#region src/mcp/tools/enroll-in-sequence.ts
5476
- const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5477
- async function handleEnrollInSequence(input, dataDir = DATA_DIR$20) {
5454
+ const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5455
+ async function handleEnrollInSequence(input, dataDir = DATA_DIR$21) {
5478
5456
  const sequence = getSequence(dataDir, input.sequenceId);
5479
5457
  if (!sequence) return { content: [{
5480
5458
  type: "text",
@@ -5506,7 +5484,7 @@ async function handleEnrollInSequence(input, dataDir = DATA_DIR$20) {
5506
5484
  })
5507
5485
  }] };
5508
5486
  }
5509
- function registerEnrollInSequence(server, dataDir = DATA_DIR$20) {
5487
+ function registerEnrollInSequence(server, dataDir = DATA_DIR$21) {
5510
5488
  server.registerTool("enroll_in_sequence", {
5511
5489
  description: `Enroll a contact in an email sequence. Validates that the sequence and its first template exist.
5512
5490
  Returns: { enrollmentId, sequenceName, totalSteps }`,
@@ -5523,8 +5501,8 @@ Returns: { enrollmentId, sequenceName, totalSteps }`,
5523
5501
  }
5524
5502
  //#endregion
5525
5503
  //#region src/mcp/tools/list-sequence-enrollments.ts
5526
- const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5527
- async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$19) {
5504
+ const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5505
+ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$20) {
5528
5506
  let enrollments = readEnrollments(dataDir);
5529
5507
  if (input.slug !== void 0) enrollments = enrollments.filter((e) => e.slug === input.slug);
5530
5508
  if (input.status !== void 0) enrollments = enrollments.filter((e) => e.status === input.status);
@@ -5533,7 +5511,7 @@ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$19) {
5533
5511
  text: JSON.stringify({ enrollments }, null, 2)
5534
5512
  }] };
5535
5513
  }
5536
- function registerListSequenceEnrollments(server, dataDir = DATA_DIR$19) {
5514
+ function registerListSequenceEnrollments(server, dataDir = DATA_DIR$20) {
5537
5515
  server.registerTool("list_sequence_enrollments", {
5538
5516
  description: `List email sequence enrollments. Filter by customer slug or status.
5539
5517
  Returns: { enrollments: SequenceEnrollment[] }`,
@@ -5552,8 +5530,8 @@ Returns: { enrollments: SequenceEnrollment[] }`,
5552
5530
  }
5553
5531
  //#endregion
5554
5532
  //#region src/mcp/tools/unenroll-from-sequence.ts
5555
- const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5556
- async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$18) {
5533
+ const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5534
+ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$19) {
5557
5535
  if (!await updateEnrollment(dataDir, input.enrollmentId, { status: "paused" })) return { content: [{
5558
5536
  type: "text",
5559
5537
  text: JSON.stringify({
@@ -5566,7 +5544,7 @@ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$18) {
5566
5544
  text: JSON.stringify({ success: true })
5567
5545
  }] };
5568
5546
  }
5569
- function registerUnenrollFromSequence(server, dataDir = DATA_DIR$18) {
5547
+ function registerUnenrollFromSequence(server, dataDir = DATA_DIR$19) {
5570
5548
  server.registerTool("unenroll_from_sequence", {
5571
5549
  description: `Unenroll (pause) a contact from an email sequence. Sets status to "paused" (soft delete).
5572
5550
  Returns: { success: boolean }`,
@@ -5575,8 +5553,8 @@ Returns: { success: boolean }`,
5575
5553
  }
5576
5554
  //#endregion
5577
5555
  //#region src/mcp/tools/list-sequences.ts
5578
- const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5579
- async function handleListSequences(_input, dataDir = DATA_DIR$17) {
5556
+ const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5557
+ async function handleListSequences(_input, dataDir = DATA_DIR$18) {
5580
5558
  const sequences = listSequences(dataDir);
5581
5559
  const enrollments = readEnrollments(dataDir);
5582
5560
  const result = sequences.map((seq) => ({
@@ -5590,7 +5568,7 @@ async function handleListSequences(_input, dataDir = DATA_DIR$17) {
5590
5568
  text: JSON.stringify({ sequences: result }, null, 2)
5591
5569
  }] };
5592
5570
  }
5593
- function registerListSequences(server, dataDir = DATA_DIR$17) {
5571
+ function registerListSequences(server, dataDir = DATA_DIR$18) {
5594
5572
  server.registerTool("list_sequences", {
5595
5573
  description: `List all email sequences with step count and enrollment count.
5596
5574
  Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
@@ -5640,7 +5618,7 @@ function buildHtml(quote, config, customerName) {
5640
5618
  <p><strong>${config.companyName ?? ""}</strong><br>${config.companyAddress ?? ""}<br>${config.vatId ? `USt-IdNr.: ${config.vatId}` : ""}</p>
5641
5619
  <hr>
5642
5620
  <p><strong>An:</strong> ${customerName}</p>
5643
- <p><strong>Datum:</strong> ${quote.createdAt.slice(0, 10)} &nbsp;&nbsp; <strong>Gültig bis:</strong> ${quote.validUntil}</p>
5621
+ <p><strong>Date:</strong> ${quote.createdAt.slice(0, 10)} &nbsp;&nbsp; <strong>Valid until:</strong> ${quote.validUntil}</p>
5644
5622
  <h2>Leistungen</h2>
5645
5623
  <table>
5646
5624
  <thead><tr><th>Beschreibung</th><th style="text-align:right">Menge</th><th style="text-align:right">Einzelpreis</th><th style="text-align:right">Gesamt</th></tr></thead>
@@ -5719,15 +5697,14 @@ async function generateQuote(dataDir, input) {
5719
5697
  status: "draft",
5720
5698
  htmlPath
5721
5699
  };
5722
- fs.default.writeFileSync(path.default.join(dir, `${quoteNumber}.json`), JSON.stringify(quote, null, 2), "utf-8");
5723
- const html = buildHtml(quote, config, readCustomerName(dataDir, input.slug));
5724
- fs.default.writeFileSync(htmlPath, html, "utf-8");
5700
+ require_atomic_write.writeFileAtomic(path.default.join(dir, `${quoteNumber}.json`), JSON.stringify(quote, null, 2));
5701
+ require_atomic_write.writeFileAtomic(htmlPath, buildHtml(quote, config, readCustomerName(dataDir, input.slug)));
5725
5702
  return quote;
5726
5703
  }
5727
5704
  //#endregion
5728
5705
  //#region src/mcp/tools/generate-quote.ts
5729
- const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5730
- async function handleGenerateQuote(input, dataDir = DATA_DIR$16) {
5706
+ const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5707
+ async function handleGenerateQuote(input, dataDir = DATA_DIR$17) {
5731
5708
  try {
5732
5709
  const quote = await generateQuote(dataDir, input);
5733
5710
  return { content: [{
@@ -5751,7 +5728,7 @@ async function handleGenerateQuote(input, dataDir = DATA_DIR$16) {
5751
5728
  }] };
5752
5729
  }
5753
5730
  }
5754
- function registerGenerateQuote(server, dataDir = DATA_DIR$16) {
5731
+ function registerGenerateQuote(server, dataDir = DATA_DIR$17) {
5755
5732
  server.registerTool("generate_quote", {
5756
5733
  description: `Generate a professional HTML quote/offer for a customer deal.
5757
5734
  Calculates subtotal, VAT, and total. Saves JSON + HTML to .agentic/quotes/.
@@ -5779,8 +5756,8 @@ Returns: { quoteNumber, htmlPath, total, currency, validUntil }`,
5779
5756
  }
5780
5757
  //#endregion
5781
5758
  //#region src/mcp/tools/get-quote-status.ts
5782
- const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5783
- async function handleGetQuoteStatus(input, dataDir = DATA_DIR$15) {
5759
+ const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5760
+ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$16) {
5784
5761
  if (input.quoteNumber) {
5785
5762
  const quote = readQuote(dataDir, input.quoteNumber);
5786
5763
  if (!quote) return { content: [{
@@ -5798,7 +5775,7 @@ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$15) {
5798
5775
  text: JSON.stringify({ quotes }, null, 2)
5799
5776
  }] };
5800
5777
  }
5801
- function registerGetQuoteStatus(server, dataDir = DATA_DIR$15) {
5778
+ function registerGetQuoteStatus(server, dataDir = DATA_DIR$16) {
5802
5779
  server.registerTool("get_quote_status", {
5803
5780
  description: `Get quote status and details. Filter by quoteNumber (single quote) or slug (all quotes for a customer).
5804
5781
  Returns quote with status: draft | sent | viewed | accepted | declined`,
@@ -5813,7 +5790,7 @@ Returns quote with status: draft | sent | viewed | accepted | declined`,
5813
5790
  }
5814
5791
  //#endregion
5815
5792
  //#region src/mcp/tools/get-booking-link.ts
5816
- const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5793
+ const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
5817
5794
  function loadCalendlyConfig(dataDir) {
5818
5795
  const p = path.default.join(dataDir, ".agentic", "integrations", "calendly.yaml");
5819
5796
  if (!fs.default.existsSync(p)) return {};
@@ -5836,7 +5813,7 @@ function readCustomerFacts(dataDir, slug) {
5836
5813
  ...email ? { email } : {}
5837
5814
  };
5838
5815
  }
5839
- async function handleGetBookingLink(input, dataDir = DATA_DIR$14) {
5816
+ async function handleGetBookingLink(input, dataDir = DATA_DIR$15) {
5840
5817
  const config = loadCalendlyConfig(dataDir);
5841
5818
  const apiKey = config.apiKey ?? process.env["CALENDLY_API_KEY"] ?? "";
5842
5819
  if (!apiKey) return { content: [{
@@ -5864,7 +5841,7 @@ async function handleGetBookingLink(input, dataDir = DATA_DIR$14) {
5864
5841
  }] };
5865
5842
  }
5866
5843
  }
5867
- function registerGetBookingLink(server, dataDir = DATA_DIR$14) {
5844
+ function registerGetBookingLink(server, dataDir = DATA_DIR$15) {
5868
5845
  server.registerTool("get_booking_link", {
5869
5846
  description: `Get a Calendly booking link for a customer. Optionally pre-fills the customer's name/email.
5870
5847
  Requires CALENDLY_API_KEY env var or .agentic/integrations/calendly.yaml config.
@@ -5912,6 +5889,7 @@ const TICKET_HEADER = "# Tickets\n\n";
5912
5889
  const TABLE_HEADER = `| ID | Title | Status | Priority | Assignee | Created | SLA Due | Resolved |
5913
5890
  |----|-------|--------|----------|----------|---------|---------|---------|`;
5914
5891
  function ticketsPath(dataDir, slug) {
5892
+ require_session_store.assertSafeSlug(slug);
5915
5893
  return path.default.join(dataDir, "customers", slug, "tickets.md");
5916
5894
  }
5917
5895
  function escapeMd(s) {
@@ -5964,7 +5942,7 @@ async function upsertTicket(dataDir, slug, ticket) {
5964
5942
  const idx = existing.findIndex((t) => t.id === ticket.id);
5965
5943
  if (idx >= 0) existing[idx] = ticket;
5966
5944
  else existing.push(ticket);
5967
- fs.default.writeFileSync(p, serializeTickets(existing), "utf-8");
5945
+ require_atomic_write.writeFileAtomic(p, serializeTickets(existing));
5968
5946
  }
5969
5947
  function nextTicketId(tickets) {
5970
5948
  const nums = tickets.map((t) => parseInt(t.id.replace("T-", ""), 10)).filter((n) => !isNaN(n));
@@ -5972,28 +5950,13 @@ function nextTicketId(tickets) {
5972
5950
  return `T-${String(max + 1).padStart(3, "0")}`;
5973
5951
  }
5974
5952
  async function listAllTickets(dataDir, filter) {
5975
- const customersDir = path.default.join(dataDir, "customers");
5976
- if (!fs.default.existsSync(customersDir)) return [];
5977
- const slugs = filter?.slug ? [filter.slug] : fs.default.readdirSync(customersDir).filter((s) => {
5978
- try {
5979
- return fs.default.statSync(path.default.join(customersDir, s)).isDirectory();
5980
- } catch {
5981
- return false;
5982
- }
5983
- });
5984
- const results = [];
5985
- for (const slug of slugs) {
5986
- const tickets = await readTickets(dataDir, slug);
5987
- for (const ticket of tickets) {
5988
- if (filter?.status && ticket.status !== filter.status) continue;
5989
- if (filter?.priority && ticket.priority !== filter.priority) continue;
5990
- if (filter?.assignee && ticket.assignee !== filter.assignee) continue;
5991
- results.push({
5992
- slug,
5993
- ticket
5994
- });
5995
- }
5996
- }
5953
+ const slugs = filter?.slug ? [filter.slug] : require_session_store.listCustomerSlugs(dataDir);
5954
+ const results = (await Promise.all(slugs.map(async (slug) => {
5955
+ return (await readTickets(dataDir, slug)).filter((ticket) => (!filter?.status || ticket.status === filter.status) && (!filter?.priority || ticket.priority === filter.priority) && (!filter?.assignee || ticket.assignee === filter.assignee)).map((ticket) => ({
5956
+ slug,
5957
+ ticket
5958
+ }));
5959
+ }))).flat();
5997
5960
  const priorityOrder = {
5998
5961
  urgent: 0,
5999
5962
  high: 1,
@@ -6048,8 +6011,8 @@ function calcSlaDue(createdDate, priority, rules) {
6048
6011
  }
6049
6012
  //#endregion
6050
6013
  //#region src/mcp/tools/create-ticket.ts
6051
- const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6052
- async function handleCreateTicket(input, dataDir = DATA_DIR$13) {
6014
+ const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6015
+ async function handleCreateTicket(input, dataDir = DATA_DIR$14) {
6053
6016
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
6054
6017
  const rules = loadSlaRules(dataDir);
6055
6018
  const priority = input.priority ?? "normal";
@@ -6071,7 +6034,7 @@ async function handleCreateTicket(input, dataDir = DATA_DIR$13) {
6071
6034
  text: JSON.stringify({ ticket }, null, 2)
6072
6035
  }] };
6073
6036
  }
6074
- function registerCreateTicket(server, dataDir = DATA_DIR$13) {
6037
+ function registerCreateTicket(server, dataDir = DATA_DIR$14) {
6075
6038
  server.registerTool("create_ticket", {
6076
6039
  description: `Create a support ticket for a customer. Auto-calculates SLA due date based on priority.
6077
6040
  Returns: { ticket } with id T-NNN, status=open, slaDue`,
@@ -6097,8 +6060,8 @@ Returns: { ticket } with id T-NNN, status=open, slaDue`,
6097
6060
  }
6098
6061
  //#endregion
6099
6062
  //#region src/mcp/tools/update-ticket.ts
6100
- const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6101
- async function handleUpdateTicket(input, dataDir = DATA_DIR$12) {
6063
+ const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6064
+ async function handleUpdateTicket(input, dataDir = DATA_DIR$13) {
6102
6065
  const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
6103
6066
  if (!ticket) return { content: [{
6104
6067
  type: "text",
@@ -6117,7 +6080,7 @@ async function handleUpdateTicket(input, dataDir = DATA_DIR$12) {
6117
6080
  text: JSON.stringify({ ticket: updated }, null, 2)
6118
6081
  }] };
6119
6082
  }
6120
- function registerUpdateTicket(server, dataDir = DATA_DIR$12) {
6083
+ function registerUpdateTicket(server, dataDir = DATA_DIR$13) {
6121
6084
  server.registerTool("update_ticket", {
6122
6085
  description: `Update a ticket's status or assignee. Setting status=resolved auto-sets resolved date.
6123
6086
  Returns: { ticket }`,
@@ -6142,8 +6105,8 @@ Returns: { ticket }`,
6142
6105
  }
6143
6106
  //#endregion
6144
6107
  //#region src/mcp/tools/list-tickets.ts
6145
- const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6146
- async function handleListTickets(input, dataDir = DATA_DIR$11) {
6108
+ const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6109
+ async function handleListTickets(input, dataDir = DATA_DIR$12) {
6147
6110
  const results = await listAllTickets(dataDir, {
6148
6111
  ...input.slug !== void 0 ? { slug: input.slug } : {},
6149
6112
  ...input.status !== void 0 ? { status: input.status } : {},
@@ -6155,7 +6118,7 @@ async function handleListTickets(input, dataDir = DATA_DIR$11) {
6155
6118
  text: JSON.stringify({ tickets: results }, null, 2)
6156
6119
  }] };
6157
6120
  }
6158
- function registerListTickets(server, dataDir = DATA_DIR$11) {
6121
+ function registerListTickets(server, dataDir = DATA_DIR$12) {
6159
6122
  server.registerTool("list_tickets", {
6160
6123
  description: `List support tickets. Filter by customer, status, priority, or assignee. Sorted by priority then date.
6161
6124
  Returns: { tickets: Array<{ slug, ticket }> }`,
@@ -6185,8 +6148,8 @@ Returns: { tickets: Array<{ slug, ticket }> }`,
6185
6148
  }
6186
6149
  //#endregion
6187
6150
  //#region src/mcp/tools/close-ticket.ts
6188
- const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6189
- async function handleCloseTicket(input, dataDir = DATA_DIR$10) {
6151
+ const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6152
+ async function handleCloseTicket(input, dataDir = DATA_DIR$11) {
6190
6153
  const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
6191
6154
  if (!ticket) return { content: [{
6192
6155
  type: "text",
@@ -6213,7 +6176,7 @@ async function handleCloseTicket(input, dataDir = DATA_DIR$10) {
6213
6176
  text: JSON.stringify({ ticket: updated }, null, 2)
6214
6177
  }] };
6215
6178
  }
6216
- function registerCloseTicket(server, dataDir = DATA_DIR$10) {
6179
+ function registerCloseTicket(server, dataDir = DATA_DIR$11) {
6217
6180
  server.registerTool("close_ticket", {
6218
6181
  description: `Close a support ticket. Optionally logs the resolution as an interaction.
6219
6182
  Returns: { ticket } with status=closed`,
@@ -6323,7 +6286,7 @@ async function recordSurveyResponse(dataDir, token, score, comment) {
6323
6286
  const dir = responsesDir(dataDir, pending.surveyId);
6324
6287
  fs.default.mkdirSync(dir, { recursive: true });
6325
6288
  const filename = `${pending.slug}_${pending.contactEmail.replace("@", "_at_")}_${Date.now()}.json`;
6326
- fs.default.writeFileSync(path.default.join(dir, filename), JSON.stringify(response, null, 2), "utf-8");
6289
+ require_atomic_write.writeFileAtomic(path.default.join(dir, filename), JSON.stringify(response, null, 2));
6327
6290
  fs.default.unlinkSync(path.default.join(pendingDir, file));
6328
6291
  return response;
6329
6292
  } catch {
@@ -6363,12 +6326,12 @@ async function savePendingSurvey(dataDir, surveyId, slug, contactEmail, token) {
6363
6326
  contactEmail,
6364
6327
  sentAt: (/* @__PURE__ */ new Date()).toISOString()
6365
6328
  };
6366
- fs.default.writeFileSync(path.default.join(pendingDir, filename), JSON.stringify(pending, null, 2), "utf-8");
6329
+ require_atomic_write.writeFileAtomic(path.default.join(pendingDir, filename), JSON.stringify(pending, null, 2));
6367
6330
  }
6368
6331
  //#endregion
6369
6332
  //#region src/mcp/tools/send-nps-survey.ts
6370
- const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6371
- async function handleSendNpsSurvey(input, dataDir = DATA_DIR$9) {
6333
+ const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6334
+ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$10) {
6372
6335
  const survey = getSurvey(dataDir, input.surveyId);
6373
6336
  if (!survey) return { content: [{
6374
6337
  type: "text",
@@ -6389,7 +6352,7 @@ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$9) {
6389
6352
  }, null, 2)
6390
6353
  }] };
6391
6354
  }
6392
- function registerSendNpsSurvey(server, dataDir = DATA_DIR$9) {
6355
+ function registerSendNpsSurvey(server, dataDir = DATA_DIR$10) {
6393
6356
  server.registerTool("send_nps_survey", {
6394
6357
  description: `Generate an NPS/CSAT survey email for a customer contact. Returns subject, HTML body, and a token-based response URL.
6395
6358
  Does NOT send automatically — returns draft for review.
@@ -6409,8 +6372,8 @@ Returns: { token, subject, body, surveyUrl }`,
6409
6372
  }
6410
6373
  //#endregion
6411
6374
  //#region src/mcp/tools/get-survey-results.ts
6412
- const DATA_DIR$8 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6413
- async function handleGetSurveyResults(input, dataDir = DATA_DIR$8) {
6375
+ const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6376
+ async function handleGetSurveyResults(input, dataDir = DATA_DIR$9) {
6414
6377
  const responses = loadSurveyResponses(dataDir, input.surveyId, input.slug);
6415
6378
  const nps = calcNpsScore(responses);
6416
6379
  const promoters = responses.filter((r) => r.score >= 9).length;
@@ -6436,7 +6399,7 @@ async function handleGetSurveyResults(input, dataDir = DATA_DIR$8) {
6436
6399
  }, null, 2)
6437
6400
  }] };
6438
6401
  }
6439
- function registerGetSurveyResults(server, dataDir = DATA_DIR$8) {
6402
+ function registerGetSurveyResults(server, dataDir = DATA_DIR$9) {
6440
6403
  server.registerTool("get_survey_results", {
6441
6404
  description: `Get NPS/CSAT survey results with score breakdown. Calculates Net Promoter Score.
6442
6405
  Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[] }`,
@@ -6466,18 +6429,21 @@ const KbArticleSchema = zod.z.object({
6466
6429
  function kbDir(dataDir) {
6467
6430
  return path.default.join(dataDir, ".agentic", "knowledge-base");
6468
6431
  }
6469
- function listKbArticles(dataDir, opts) {
6470
- const dir = kbDir(dataDir);
6432
+ /** Category subdirectories of the knowledge base. */
6433
+ function kbCategories(dir) {
6471
6434
  if (!fs.default.existsSync(dir)) return [];
6472
- const results = [];
6473
- const categories = fs.default.readdirSync(dir).filter((f) => {
6435
+ return fs.default.readdirSync(dir).filter((f) => {
6474
6436
  try {
6475
6437
  return fs.default.statSync(path.default.join(dir, f)).isDirectory();
6476
6438
  } catch {
6477
6439
  return false;
6478
6440
  }
6479
6441
  });
6480
- for (const cat of categories) {
6442
+ }
6443
+ function listKbArticles(dataDir, opts) {
6444
+ const dir = kbDir(dataDir);
6445
+ const results = [];
6446
+ for (const cat of kbCategories(dir)) {
6481
6447
  const catDir = path.default.join(dir, cat);
6482
6448
  const files = fs.default.readdirSync(catDir).filter((f) => f.endsWith(".md"));
6483
6449
  for (const file of files) try {
@@ -6497,14 +6463,31 @@ function listKbArticles(dataDir, opts) {
6497
6463
  return results;
6498
6464
  }
6499
6465
  function getKbArticle(dataDir, id) {
6500
- return listKbArticles(dataDir).find((a) => a.id === id) ?? null;
6466
+ if (!require_session_store.isSafePathSegment(id)) return null;
6467
+ const dir = kbDir(dataDir);
6468
+ for (const cat of kbCategories(dir)) {
6469
+ const filePath = path.default.join(dir, cat, `${id}.md`);
6470
+ if (!fs.default.existsSync(filePath)) continue;
6471
+ try {
6472
+ const parsed = (0, gray_matter.default)(fs.default.readFileSync(filePath, "utf-8"));
6473
+ const meta = KbArticleSchema.safeParse(parsed.data);
6474
+ if (!meta.success) return null;
6475
+ return {
6476
+ ...meta.data,
6477
+ body: parsed.content.trim()
6478
+ };
6479
+ } catch {
6480
+ return null;
6481
+ }
6482
+ }
6483
+ return null;
6501
6484
  }
6502
6485
  function writeKbArticle(dataDir, article) {
6503
- const dir = path.default.join(kbDir(dataDir), article.category);
6504
- fs.default.mkdirSync(dir, { recursive: true });
6486
+ require_session_store.assertSafePathSegment(article.category, "knowledge-base category");
6487
+ require_session_store.assertSafePathSegment(article.id, "knowledge-base article id");
6505
6488
  const { body, ...meta } = article;
6506
6489
  const content = gray_matter.default.stringify(body, meta);
6507
- fs.default.writeFileSync(path.default.join(dir, `${article.id}.md`), content, "utf-8");
6490
+ require_atomic_write.writeFileAtomic(path.default.join(kbDir(dataDir), article.category, `${article.id}.md`), content);
6508
6491
  }
6509
6492
  function searchKbSimple(dataDir, query, opts) {
6510
6493
  const all = listKbArticles(dataDir, opts?.publicOnly ? { publicOnly: true } : {});
@@ -6517,8 +6500,8 @@ function getKbMetaForExport(article) {
6517
6500
  }
6518
6501
  //#endregion
6519
6502
  //#region src/mcp/tools/search-knowledge-base.ts
6520
- const DATA_DIR$7 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6521
- async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$7) {
6503
+ const DATA_DIR$8 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6504
+ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$8) {
6522
6505
  const results = searchKbSimple(dataDir, input.query, { ...input.publicOnly ? { publicOnly: true } : {} });
6523
6506
  const limited = (input.category ? results.filter((a) => a.category === input.category) : results).slice(0, input.limit ?? 10);
6524
6507
  return { content: [{
@@ -6533,7 +6516,7 @@ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$7) {
6533
6516
  }, null, 2)
6534
6517
  }] };
6535
6518
  }
6536
- function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$7) {
6519
+ function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$8) {
6537
6520
  server.registerTool("search_knowledge_base", {
6538
6521
  description: `Search the knowledge base for articles. Text search on title, body, and tags.
6539
6522
  Returns: { count, articles[] } with excerpts`,
@@ -6552,8 +6535,8 @@ Returns: { count, articles[] } with excerpts`,
6552
6535
  }
6553
6536
  //#endregion
6554
6537
  //#region src/mcp/tools/create-kb-article.ts
6555
- const DATA_DIR$6 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6556
- async function handleCreateKbArticle(input, dataDir = DATA_DIR$6) {
6538
+ const DATA_DIR$7 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6539
+ async function handleCreateKbArticle(input, dataDir = DATA_DIR$7) {
6557
6540
  if (getKbArticle(dataDir, input.id)) return { content: [{
6558
6541
  type: "text",
6559
6542
  text: JSON.stringify({ error: `Article '${input.id}' already exists` })
@@ -6581,7 +6564,7 @@ async function handleCreateKbArticle(input, dataDir = DATA_DIR$6) {
6581
6564
  }, null, 2)
6582
6565
  }] };
6583
6566
  }
6584
- function registerCreateKbArticle(server, dataDir = DATA_DIR$6) {
6567
+ function registerCreateKbArticle(server, dataDir = DATA_DIR$7) {
6585
6568
  server.registerTool("create_kb_article", {
6586
6569
  description: `Create a new knowledge base article. Articles are stored as Markdown files in .agentic/knowledge-base/.
6587
6570
  Returns: { id, title, category, path }`,
@@ -6606,8 +6589,8 @@ Returns: { id, title, category, path }`,
6606
6589
  }
6607
6590
  //#endregion
6608
6591
  //#region src/mcp/tools/backup-now.ts
6609
- const DATA_DIR$5 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6610
- async function handleBackupNow(input, dataDir = DATA_DIR$5) {
6592
+ const DATA_DIR$6 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6593
+ async function handleBackupNow(input, dataDir = DATA_DIR$6) {
6611
6594
  const zipPath = path.default.join(dataDir, `dxcrm-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.zip`);
6612
6595
  const manifest = await require_session_store.runBackup(zipPath, dataDir, { ...input.remote ? { remote: input.remote } : {} }).catch(() => null);
6613
6596
  if (!manifest) return { content: [{
@@ -6644,8 +6627,8 @@ function registerBackupNow(server) {
6644
6627
  }
6645
6628
  //#endregion
6646
6629
  //#region src/mcp/tools/list-backups.ts
6647
- const DATA_DIR$4 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6648
- async function handleListBackups(input, dataDir = DATA_DIR$4) {
6630
+ const DATA_DIR$5 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6631
+ async function handleListBackups(input, dataDir = DATA_DIR$5) {
6649
6632
  const logEntries = require_session_store.readBackupLog(dataDir);
6650
6633
  const fileEntries = require_session_store.listBackupsInDir(dataDir);
6651
6634
  const entries = logEntries.length > 0 ? logEntries : fileEntries;
@@ -6679,8 +6662,8 @@ function registerListBackups(server) {
6679
6662
  }
6680
6663
  //#endregion
6681
6664
  //#region src/mcp/tools/trigger-sync.ts
6682
- const DATA_DIR$3 = process.cwd();
6683
- async function handleTriggerSync(input, dataDir = DATA_DIR$3) {
6665
+ const DATA_DIR$4 = process.cwd();
6666
+ async function handleTriggerSync(input, dataDir = DATA_DIR$4) {
6684
6667
  const auth = getGmailAuth();
6685
6668
  if (!auth) return { content: [{
6686
6669
  type: "text",
@@ -6715,7 +6698,7 @@ async function handleTriggerSync(input, dataDir = DATA_DIR$3) {
6715
6698
  try {
6716
6699
  const sources = JSON.parse(fs.default.readFileSync(sourcesPath, "utf-8"));
6717
6700
  if (!sources.gmail?.enabled || !sources.gmail.query) continue;
6718
- const { syncGmail } = await Promise.resolve().then(() => require("./gmail-sync-hHm9gaWd.cjs"));
6701
+ const { syncGmail } = await Promise.resolve().then(() => require("./gmail-sync-GEy3oVvw.cjs"));
6719
6702
  const result = await syncGmail({
6720
6703
  slug,
6721
6704
  dataDir,
@@ -6774,8 +6757,8 @@ Returns: { success: boolean, synced: number, skipped: number, customers: [...],
6774
6757
  }
6775
6758
  //#endregion
6776
6759
  //#region src/mcp/tools/get-audit-log.ts
6777
- const DATA_DIR$2 = process.cwd();
6778
- async function handleGetAuditLog(input, dataDir = DATA_DIR$2) {
6760
+ const DATA_DIR$3 = process.cwd();
6761
+ async function handleGetAuditLog(input, dataDir = DATA_DIR$3) {
6779
6762
  const entries = require_session_store.readAuditLog(dataDir);
6780
6763
  const filterOpts = { limit: input.limit ?? 50 };
6781
6764
  if (input.slug !== void 0) filterOpts.slug = input.slug;
@@ -6816,6 +6799,69 @@ Returns: { total: number, returned: number, entries: [{timestamp, actor, tool, s
6816
6799
  });
6817
6800
  }
6818
6801
  //#endregion
6802
+ //#region src/mcp/tools/get-logs.ts
6803
+ const DATA_DIR$2 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
6804
+ async function handleGetLogs(input, dataDir = DATA_DIR$2) {
6805
+ const query = {
6806
+ ...input.level !== void 0 ? { level: input.level } : {},
6807
+ ...input.component !== void 0 ? { component: input.component } : {},
6808
+ ...input.since !== void 0 ? { since: input.since } : {},
6809
+ ...input.contains !== void 0 ? { contains: input.contains } : {},
6810
+ limit: input.limit ?? 100
6811
+ };
6812
+ const payload = input.summary ? require_logger.summarizeLogs(dataDir, query) : (() => {
6813
+ const entries = require_logger.queryLogs(dataDir, query);
6814
+ return {
6815
+ returned: entries.length,
6816
+ entries
6817
+ };
6818
+ })();
6819
+ return { content: [{
6820
+ type: "text",
6821
+ text: JSON.stringify(payload, null, 2)
6822
+ }] };
6823
+ }
6824
+ function registerGetLogs(server) {
6825
+ server.registerTool("get_logs", {
6826
+ title: "Get Logs",
6827
+ description: `Read and analyze the structured application log (.agentic/logs.ndjson).
6828
+ Use to answer "what went wrong recently?", "show errors from gmail sync", or "summarize today's activity".
6829
+
6830
+ Args:
6831
+ level: Minimum level to include — debug | info | warn | error (optional)
6832
+ component: Filter by component, e.g. "gmail-sync", "lancedb" (optional)
6833
+ since: ISO timestamp; only entries at or after it (optional)
6834
+ contains: Case-insensitive substring of the message (optional)
6835
+ limit: Max entries to return (default 100, most recent)
6836
+ summary: When true, return aggregated counts (by level + component) and recent errors instead of raw entries
6837
+
6838
+ Returns (entries): { returned: number, entries: [{ts, level, component, message, context?}] }
6839
+ Returns (summary): { total, byLevel, byComponent, firstTs, lastTs, recentErrors }`,
6840
+ inputSchema: zod.z.object({
6841
+ level: zod.z.enum([
6842
+ "debug",
6843
+ "info",
6844
+ "warn",
6845
+ "error"
6846
+ ]).optional().describe("Minimum level"),
6847
+ component: zod.z.string().optional().describe("Filter by component"),
6848
+ since: zod.z.string().optional().describe("ISO timestamp lower bound"),
6849
+ contains: zod.z.string().optional().describe("Message substring filter"),
6850
+ limit: zod.z.number().int().min(1).max(1e3).optional().describe("Max entries (default 100)"),
6851
+ summary: zod.z.boolean().optional().describe("Return aggregated summary instead of entries")
6852
+ })
6853
+ }, async ({ level, component, since, contains, limit, summary }) => {
6854
+ const input = {};
6855
+ if (level !== void 0) input.level = level;
6856
+ if (component !== void 0) input.component = component;
6857
+ if (since !== void 0) input.since = since;
6858
+ if (contains !== void 0) input.contains = contains;
6859
+ if (limit !== void 0) input.limit = limit;
6860
+ if (summary !== void 0) input.summary = summary;
6861
+ return handleGetLogs(input);
6862
+ });
6863
+ }
6864
+ //#endregion
6819
6865
  //#region src/mcp/prompts.ts
6820
6866
  /**
6821
6867
  * CRM playbook prompts exposed via MCP `prompts/list` + `prompts/get`.
@@ -6897,7 +6943,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
6897
6943
  description: "Open and closed deals for a customer",
6898
6944
  mimeType: "application/json"
6899
6945
  }, async (uri, variables) => {
6900
- const { readPipeline } = await Promise.resolve().then(() => require("./pipeline-writer-N2omexxp.cjs")).then((n) => n.pipeline_writer_exports);
6946
+ const { readPipeline } = await Promise.resolve().then(() => require("./pipeline-writer-B1tRAhuD.cjs")).then((n) => n.pipeline_writer_exports);
6901
6947
  const deals = await readPipeline(dataDir, String(variables["slug"]));
6902
6948
  return { contents: [{
6903
6949
  uri: uri.href,
@@ -6910,7 +6956,7 @@ function registerResources(server, dataDir = DATA_DIR$1) {
6910
6956
  description: "Newest-first interaction history for a customer",
6911
6957
  mimeType: "text/markdown"
6912
6958
  }, async (uri, variables) => {
6913
- const { readInteractions } = await Promise.resolve().then(() => require("./interactions-writer-CrPStUll.cjs")).then((n) => n.interactions_writer_exports);
6959
+ const { readInteractions } = await Promise.resolve().then(() => require("./interactions-writer-a2yzBd7T.cjs")).then((n) => n.interactions_writer_exports);
6914
6960
  const text = await readInteractions(dataDir, String(variables["slug"]));
6915
6961
  return { contents: [{
6916
6962
  uri: uri.href,
@@ -6969,46 +7015,30 @@ function objectsSchemaPath(dataDir) {
6969
7015
  return path.default.join(dataDir, ".agentic", "schema", "custom-objects.json");
6970
7016
  }
6971
7017
  function recordsPath(dataDir, name) {
7018
+ require_session_store.assertSafePathSegment(name, "custom object name");
6972
7019
  return path.default.join(dataDir, ".agentic", "objects", `${name}.json`);
6973
7020
  }
6974
7021
  function loadCustomObjects(dataDir) {
6975
- const p = objectsSchemaPath(dataDir);
6976
- if (!fs.default.existsSync(p)) return [];
6977
- try {
6978
- const data = JSON.parse(fs.default.readFileSync(p, "utf-8"));
6979
- return Array.isArray(data.objects) ? data.objects : [];
6980
- } catch {
6981
- return [];
6982
- }
7022
+ return require_session_store.readJsonArray(objectsSchemaPath(dataDir), "objects");
6983
7023
  }
6984
7024
  function getObjectDefinition(dataDir, name) {
6985
7025
  return loadCustomObjects(dataDir).find((o) => o.name === name);
6986
7026
  }
6987
7027
  /** Add or update (by name) a custom object definition. */
6988
7028
  function defineCustomObject(dataDir, def) {
7029
+ require_session_store.assertSafePathSegment(def.name, "custom object name");
6989
7030
  const objs = loadCustomObjects(dataDir);
6990
7031
  const idx = objs.findIndex((o) => o.name === def.name);
6991
7032
  if (idx >= 0) objs[idx] = def;
6992
7033
  else objs.push(def);
6993
- const p = objectsSchemaPath(dataDir);
6994
- fs.default.mkdirSync(path.default.dirname(p), { recursive: true });
6995
- fs.default.writeFileSync(p, JSON.stringify({ objects: objs }, null, 2), "utf-8");
7034
+ require_session_store.writeJsonArray(objectsSchemaPath(dataDir), "objects", objs);
6996
7035
  return objs;
6997
7036
  }
6998
7037
  function listRecords(dataDir, name) {
6999
- const p = recordsPath(dataDir, name);
7000
- if (!fs.default.existsSync(p)) return [];
7001
- try {
7002
- const data = JSON.parse(fs.default.readFileSync(p, "utf-8"));
7003
- return Array.isArray(data.records) ? data.records : [];
7004
- } catch {
7005
- return [];
7006
- }
7038
+ return require_session_store.readJsonArray(recordsPath(dataDir, name), "records");
7007
7039
  }
7008
7040
  function writeRecords(dataDir, name, records) {
7009
- const p = recordsPath(dataDir, name);
7010
- fs.default.mkdirSync(path.default.dirname(p), { recursive: true });
7011
- fs.default.writeFileSync(p, JSON.stringify({ records }, null, 2), "utf-8");
7041
+ require_session_store.writeJsonArray(recordsPath(dataDir, name), "records", records);
7012
7042
  }
7013
7043
  function createRecord(dataDir, name, values) {
7014
7044
  const def = getObjectDefinition(dataDir, name);
@@ -7066,7 +7096,7 @@ function handleCreateRecord(input, dataDir = DATA_DIR) {
7066
7096
  require_session_store.enforceRbac(dataDir, "create_record");
7067
7097
  const res = createRecord(dataDir, input.object, input.values);
7068
7098
  if (!res.ok) return json({ error: (res.errors ?? []).join("; ") });
7069
- Promise.resolve().then(() => require("./webhooks-Xn6zO6kd.cjs")).then(({ emitEvent }) => emitEvent(dataDir, "record.created", {
7099
+ Promise.resolve().then(() => require("./webhooks-CwW-3kvG.cjs")).then(({ emitEvent }) => emitEvent(dataDir, "record.created", {
7070
7100
  object: input.object,
7071
7101
  record: res.record
7072
7102
  }));
@@ -7128,14 +7158,7 @@ function hashToken(token) {
7128
7158
  return (0, crypto.createHash)("sha256").update(token).digest("hex");
7129
7159
  }
7130
7160
  function loadMcpTokens(dataDir) {
7131
- const p = tokensPath(dataDir);
7132
- if (!fs.default.existsSync(p)) return [];
7133
- try {
7134
- const data = JSON.parse(fs.default.readFileSync(p, "utf-8"));
7135
- return Array.isArray(data.tokens) ? data.tokens : [];
7136
- } catch {
7137
- return [];
7138
- }
7161
+ return require_session_store.readJsonArray(tokensPath(dataDir), "tokens");
7139
7162
  }
7140
7163
  /**
7141
7164
  * Whether the HTTP MCP endpoint must require a bearer token.
@@ -7254,6 +7277,7 @@ function createMcpServer() {
7254
7277
  registerListBackups(server);
7255
7278
  registerTriggerSync(server);
7256
7279
  registerGetAuditLog(server);
7280
+ registerGetLogs(server);
7257
7281
  registerCustomObjectTools(server);
7258
7282
  registerPrompts(server);
7259
7283
  registerResources(server);
@@ -7264,7 +7288,7 @@ async function startStdio() {
7264
7288
  const server = createMcpServer();
7265
7289
  const transport = new _modelcontextprotocol_sdk_server_stdio_js.StdioServerTransport();
7266
7290
  await server.connect(transport);
7267
- console.error("DatasynxOpenCRM MCP Server running via stdio");
7291
+ require_logger.logger.info("mcp-server", "running via stdio");
7268
7292
  }
7269
7293
  async function startHttp(port = 3847) {
7270
7294
  await initOAuthFromDisk(process.cwd());
@@ -7304,7 +7328,7 @@ async function startHttp(port = 3847) {
7304
7328
  });
7305
7329
  app.get("/sessions", async (_req, res) => {
7306
7330
  try {
7307
- const { readAllSessions } = await Promise.resolve().then(() => require("./session-D0qFkBla.cjs"));
7331
+ const { readAllSessions } = await Promise.resolve().then(() => require("./session-Mm7GQbSH.cjs"));
7308
7332
  const sessions = readAllSessions(dataDir);
7309
7333
  res.json({ sessions });
7310
7334
  } catch {
@@ -7438,15 +7462,15 @@ button{margin-top:12px;padding:12px 28px;background:#1a1a2e;color:#fff;border:no
7438
7462
  res.send(surveyThankYouPage(numScore, commentText));
7439
7463
  });
7440
7464
  app.listen(port, () => {
7441
- console.error(`DatasynxOpenCRM MCP Server running on http://0.0.0.0:${port}/mcp`);
7465
+ require_logger.logger.info("mcp-server", "running over http", { url: `http://0.0.0.0:${port}/mcp` });
7442
7466
  });
7443
7467
  }
7444
7468
  if ((process.env["DXCRM_MCP_MODE"] ?? "stdio") === "http") startHttp(parseInt(process.env["DXCRM_MCP_PORT"] ?? "3847", 10)).catch((err) => {
7445
- console.error("MCP Server fatal error:", err.message);
7469
+ require_logger.logger.error("mcp-server", "fatal error", { error: err.message });
7446
7470
  process.exit(1);
7447
7471
  });
7448
7472
  else startStdio().catch((err) => {
7449
- console.error("MCP Server fatal error:", err.message);
7473
+ require_logger.logger.error("mcp-server", "fatal error", { error: err.message });
7450
7474
  process.exit(1);
7451
7475
  });
7452
7476
  //#endregion