@datasynx/agentic-crm 0.1.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/README.md +270 -669
  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-CDysGnRg.js} +6 -6
  5. package/dist/{ask-CID3jnuL.js.map → ask-CDysGnRg.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/attachments-CX2GAtsw.cjs +517 -0
  11. package/dist/attachments-CX2GAtsw.cjs.map +1 -0
  12. package/dist/attachments-D207gXfN.js +514 -0
  13. package/dist/attachments-D207gXfN.js.map +1 -0
  14. package/dist/attachments-rLa96rOK.js +514 -0
  15. package/dist/attachments-rLa96rOK.js.map +1 -0
  16. package/dist/auth-B5DcjJ_6.js +2 -0
  17. package/dist/{auth-DFWwWcYD.js → auth-DDXZTwS0.js} +4 -13
  18. package/dist/auth-DDXZTwS0.js.map +1 -0
  19. package/dist/{autofill-Di_-SP7t.js → autofill-B9VtlR2j.js} +2 -2
  20. package/dist/{autofill-Di_-SP7t.js.map → autofill-B9VtlR2j.js.map} +1 -1
  21. package/dist/{backup-CeMk9z86.js → backup-CTlIxUdO.js} +5 -7
  22. package/dist/backup-CTlIxUdO.js.map +1 -0
  23. package/dist/backup-LFnC09oV.js +2 -0
  24. package/dist/chunk-BfDYWZQ8.cjs +32 -0
  25. package/dist/chunk-BfDYWZQ8.cjs.map +1 -0
  26. package/dist/chunk-BhUZmQg5.js +32 -0
  27. package/dist/chunk-BhUZmQg5.js.map +1 -0
  28. package/dist/chunk-ChC83jai.js +2 -0
  29. package/dist/chunk-e_w8qqtP.js +32 -0
  30. package/dist/chunk-e_w8qqtP.js.map +1 -0
  31. package/dist/{churn-C28IgnAj.js → churn-DN9WDGNM.js} +3 -3
  32. package/dist/{churn-C28IgnAj.js.map → churn-DN9WDGNM.js.map} +1 -1
  33. package/dist/cli.js +285 -186
  34. package/dist/cli.js.map +1 -1
  35. package/dist/{compliance-CKSBoQUe.js → compliance-Bc12Hn9a.js} +3 -3
  36. package/dist/{compliance-CKSBoQUe.js.map → compliance-Bc12Hn9a.js.map} +1 -1
  37. package/dist/{compliance-CujOqAKk.js → compliance-TqYQXhBj.js} +1 -1
  38. package/dist/{compliance-B1kk5-YS.js → compliance-kq0xHRw3.js} +3 -3
  39. package/dist/{compliance-B1kk5-YS.js.map → compliance-kq0xHRw3.js.map} +1 -1
  40. package/dist/{compliance-B91zNvCR.cjs → compliance-pAj9FcGI.cjs} +3 -3
  41. package/dist/{compliance-B91zNvCR.cjs.map → compliance-pAj9FcGI.cjs.map} +1 -1
  42. package/dist/{context-builder-BzWAp3Zs.js → context-builder-7Uab5-G4.js} +3 -2
  43. package/dist/context-builder-7Uab5-G4.js.map +1 -0
  44. package/dist/context-builder-hmOPvgso.js +2 -0
  45. package/dist/{custom-fields-CzNeD3_v.js → custom-fields-BMyz5Ruh.js} +1 -1
  46. package/dist/{custom-fields-Pl2t9xzp.js → custom-fields-GzpOHW_2.js} +4 -13
  47. package/dist/custom-fields-GzpOHW_2.js.map +1 -0
  48. package/dist/{custom-objects-CIFrmQ2V.js → custom-objects-BNy-ayR-.js} +1 -1
  49. package/dist/{custom-objects-BHgn1GEX.js → custom-objects-CxW1gHwJ.js} +10 -25
  50. package/dist/custom-objects-CxW1gHwJ.js.map +1 -0
  51. package/dist/{customer-dir-DIylZ8Q6.js → customer-dir-CkMMXhb0.js} +9 -4
  52. package/dist/customer-dir-CkMMXhb0.js.map +1 -0
  53. package/dist/daemon/worker.js +66 -40
  54. package/dist/daemon/worker.js.map +1 -1
  55. package/dist/doctor-C14-vnJ1.js +103 -0
  56. package/dist/doctor-C14-vnJ1.js.map +1 -0
  57. package/dist/email-body-BFSRa0AW.cjs +42 -0
  58. package/dist/email-body-BFSRa0AW.cjs.map +1 -0
  59. package/dist/email-body-BOd7U-D2.js +42 -0
  60. package/dist/email-body-BOd7U-D2.js.map +1 -0
  61. package/dist/{enrichment-3XvgGDfB.js → enrichment-CDFdWmvD.js} +3 -3
  62. package/dist/{enrichment-3XvgGDfB.js.map → enrichment-CDFdWmvD.js.map} +1 -1
  63. package/dist/{file-lock-B_zi7NQl.js → file-lock-CcHotQkZ.js} +3 -4
  64. package/dist/file-lock-CcHotQkZ.js.map +1 -0
  65. package/dist/{gmail-sync-DIaxInDT.js → gmail-sync-B4Iu3AQb.js} +56 -22
  66. package/dist/gmail-sync-B4Iu3AQb.js.map +1 -0
  67. package/dist/{gmail-sync-hHm9gaWd.cjs → gmail-sync-BpSVESSe.cjs} +55 -21
  68. package/dist/gmail-sync-BpSVESSe.cjs.map +1 -0
  69. package/dist/{gmail-sync-rQaVqKWd.js → gmail-sync-DIbrPnTK.js} +55 -21
  70. package/dist/gmail-sync-DIbrPnTK.js.map +1 -0
  71. package/dist/{gmail-webhook-handler-e5Od25FX.js → gmail-webhook-handler-BzOFbvgh.js} +4 -4
  72. package/dist/{gmail-webhook-handler-e5Od25FX.js.map → gmail-webhook-handler-BzOFbvgh.js.map} +1 -1
  73. package/dist/{gmail-webhook-handler-DS7OlRPX.js → gmail-webhook-handler-CvSDW_Js.js} +2 -2
  74. package/dist/{goal-engine-KpBftn4V.js → goal-engine-BbroPhqm.js} +10 -11
  75. package/dist/goal-engine-BbroPhqm.js.map +1 -0
  76. package/dist/{goal-engine-CUZSpERI.js → goal-engine-CfDAJTFt.js} +1 -1
  77. package/dist/{google-drive-sync-DEPcqFca.js → google-drive-sync-B_I1d54Y.js} +3 -3
  78. package/dist/{google-drive-sync-DEPcqFca.js.map → google-drive-sync-B_I1d54Y.js.map} +1 -1
  79. package/dist/html-BaeOCZKE.js +36 -0
  80. package/dist/html-BaeOCZKE.js.map +1 -0
  81. package/dist/html-CmOku6jS.cjs +47 -0
  82. package/dist/html-CmOku6jS.cjs.map +1 -0
  83. package/dist/{hygiene-DZqfYpFf.js → hygiene-DzQPnc6P.js} +3 -3
  84. package/dist/{hygiene-DZqfYpFf.js.map → hygiene-DzQPnc6P.js.map} +1 -1
  85. package/dist/identity-CB7j-Zr1.js +2 -0
  86. package/dist/{identity-CI6olMNm.js → identity-_uZ3Lbr2.js} +2 -2
  87. package/dist/{identity-CI6olMNm.js.map → identity-_uZ3Lbr2.js.map} +1 -1
  88. package/dist/{import-hubspot-BaK71U_K.js → import-hubspot-CTId9IGV.js} +51 -45
  89. package/dist/import-hubspot-CTId9IGV.js.map +1 -0
  90. package/dist/{index-YqwMd6aQ.d.cts → index-BAutNcAT.d.cts} +20 -12
  91. package/dist/index-BAutNcAT.d.cts.map +1 -0
  92. package/dist/{index-V8BFaH-b.d.ts → index-FzDsNSSb.d.ts} +12 -4
  93. package/dist/index-FzDsNSSb.d.ts.map +1 -0
  94. package/dist/index.cjs +19 -21
  95. package/dist/index.cjs.map +1 -1
  96. package/dist/index.d.cts +20 -12
  97. package/dist/index.d.cts.map +1 -1
  98. package/dist/index.d.ts +12 -4
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +19 -21
  101. package/dist/index.js.map +1 -1
  102. package/dist/interactions-writer-B2y-73lh.js +2 -0
  103. package/dist/{interactions-writer-SLHnoEeE.js → interactions-writer-B8XAzdqR.js} +34 -4
  104. package/dist/interactions-writer-B8XAzdqR.js.map +1 -0
  105. package/dist/{interactions-writer-CrPStUll.cjs → interactions-writer-BRJNrefF.cjs} +7 -3
  106. package/dist/interactions-writer-BRJNrefF.cjs.map +1 -0
  107. package/dist/{interactions-writer-DO3KcSR3.js → interactions-writer-ZQcpFOh9.js} +7 -3
  108. package/dist/interactions-writer-ZQcpFOh9.js.map +1 -0
  109. package/dist/json-store-WWsFzXub.js +43 -0
  110. package/dist/json-store-WWsFzXub.js.map +1 -0
  111. package/dist/{knowledge-base-D0Fh40kc.js → knowledge-base--063Kpa3.js} +51 -22
  112. package/dist/knowledge-base--063Kpa3.js.map +1 -0
  113. package/dist/{lancedb-CCBbpulq.js → lancedb-CswQEE5K.js} +1 -1
  114. package/dist/{lancedb-rlvWoPwl.js → lancedb-CuHKNsNZ.js} +4 -3
  115. package/dist/lancedb-CuHKNsNZ.js.map +1 -0
  116. package/dist/{lead-model-BCFzyktm.js → lead-model-CEmx7te7.js} +6 -14
  117. package/dist/lead-model-CEmx7te7.js.map +1 -0
  118. package/dist/{llm-Z8RIYkpF.js → llm-BnSUBisu.js} +2 -2
  119. package/dist/{llm-Z8RIYkpF.js.map → llm-BnSUBisu.js.map} +1 -1
  120. package/dist/{llm-iijeXmgq.cjs → llm-CXycmEl9.cjs} +2 -2
  121. package/dist/{llm-iijeXmgq.cjs.map → llm-CXycmEl9.cjs.map} +1 -1
  122. package/dist/{llm-DEjWcqmW.js → llm-DSX1-wFu.js} +1 -1
  123. package/dist/{llm-DvzZqva0.js → llm-PZzgPphl.js} +3 -3
  124. package/dist/{llm-DvzZqva0.js.map → llm-PZzgPphl.js.map} +1 -1
  125. package/dist/logger-BkInaGoV.cjs +167 -0
  126. package/dist/logger-BkInaGoV.cjs.map +1 -0
  127. package/dist/logger-Dyl4VcLO.js +147 -0
  128. package/dist/logger-Dyl4VcLO.js.map +1 -0
  129. package/dist/logger-UaF5p9d1.js +147 -0
  130. package/dist/logger-UaF5p9d1.js.map +1 -0
  131. package/dist/logger-vKQS34w9.js +2 -0
  132. package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
  133. package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
  134. package/dist/mcp.cjs +365 -319
  135. package/dist/mcp.cjs.map +1 -1
  136. package/dist/mcp.d.cts.map +1 -1
  137. package/dist/mcp.d.ts.map +1 -1
  138. package/dist/mcp.js +365 -319
  139. package/dist/mcp.js.map +1 -1
  140. package/dist/{memory-Cy6-Tbyl.js → memory-D8hmgD9d.js} +1 -1
  141. package/dist/{memory-Bb6ky3kb.js → memory-Dzr9dXSM.js} +4 -11
  142. package/dist/memory-Dzr9dXSM.js.map +1 -0
  143. package/dist/{microsoft-calendar-B6MMtUQK.js → microsoft-calendar-BgVR8GDv.js} +4 -4
  144. package/dist/{microsoft-calendar-B6MMtUQK.js.map → microsoft-calendar-BgVR8GDv.js.map} +1 -1
  145. package/dist/{microsoft-sync-CpZVoSuq.js → microsoft-sync-D30_XksI.js} +5 -5
  146. package/dist/{microsoft-sync-CpZVoSuq.js.map → microsoft-sync-D30_XksI.js.map} +1 -1
  147. package/dist/{nba-3wanmJ0U.js → nba-DwdfM93s.js} +3 -3
  148. package/dist/{nba-3wanmJ0U.js.map → nba-DwdfM93s.js.map} +1 -1
  149. package/dist/{notification-dispatcher-0vYNngWe.js → notification-dispatcher-inpKyuBz.js} +7 -3
  150. package/dist/notification-dispatcher-inpKyuBz.js.map +1 -0
  151. package/dist/{pipeline-writer-BqBrYrQc.js → pipeline-writer-0LJ6Qkat.js} +1 -1
  152. package/dist/{pipeline-writer-N2omexxp.cjs → pipeline-writer-B1tRAhuD.cjs} +11 -3
  153. package/dist/pipeline-writer-B1tRAhuD.cjs.map +1 -0
  154. package/dist/{pipeline-writer-BvVquKIe.js → pipeline-writer-CIllfnZl.js} +5 -3
  155. package/dist/pipeline-writer-CIllfnZl.js.map +1 -0
  156. package/dist/{pipeline-writer-eufx_0o1.js → pipeline-writer-rDj-ni6q.js} +6 -4
  157. package/dist/pipeline-writer-rDj-ni6q.js.map +1 -0
  158. package/dist/{proactive-agent-BgQXw3ac.js → proactive-agent-B7u3Bj_l.js} +6 -6
  159. package/dist/{proactive-agent-BgQXw3ac.js.map → proactive-agent-B7u3Bj_l.js.map} +1 -1
  160. package/dist/{proactive-worker-BrLHNhjH.js → proactive-worker-1zkm6aJD.js} +7 -8
  161. package/dist/proactive-worker-1zkm6aJD.js.map +1 -0
  162. package/dist/{push-manager-CowY-0IK.js → push-manager-BXM-IHfP.js} +1 -1
  163. package/dist/{push-manager-CdqIIkuh.js → push-manager-C0ECQgva.js} +4 -4
  164. package/dist/push-manager-C0ECQgva.js.map +1 -0
  165. package/dist/{quote-generator-OhSFsi3x.js → quote-generator-ByUyIYtw.js} +1 -1
  166. package/dist/{quote-generator-BfwENXzg.js → quote-generator-CTdR8eEI.js} +5 -5
  167. package/dist/quote-generator-CTdR8eEI.js.map +1 -0
  168. package/dist/rbac-DzbyFhVH.js +2 -0
  169. package/dist/{rbac-CTIktZaC.js → rbac-msmBc_tK.js} +19 -12
  170. package/dist/rbac-msmBc_tK.js.map +1 -0
  171. package/dist/regex-Jt5DatPi.js +13 -0
  172. package/dist/regex-Jt5DatPi.js.map +1 -0
  173. package/dist/{relationship-health-odxEoQdJ.js → relationship-health-ZZNXR1RZ.js} +8 -16
  174. package/dist/relationship-health-ZZNXR1RZ.js.map +1 -0
  175. package/dist/{revenue-simulation-Bqf2DLVB.js → revenue-simulation-D8f_YkUY.js} +9 -19
  176. package/dist/revenue-simulation-D8f_YkUY.js.map +1 -0
  177. package/dist/{revenue-simulation-BJdRTEHc.js → revenue-simulation-njJZlTqm.js} +1 -1
  178. package/dist/safe-path-mpp0dKtO.js +18 -0
  179. package/dist/safe-path-mpp0dKtO.js.map +1 -0
  180. package/dist/{segments-BqcD5HIl.js → segments-DI3LOQNe.js} +5 -14
  181. package/dist/segments-DI3LOQNe.js.map +1 -0
  182. package/dist/sequence-engine-C6nnewHX.js +2 -0
  183. package/dist/{sequence-engine-J1lTW_in.js → sequence-engine-DNTVLq7o.js} +15 -8
  184. package/dist/sequence-engine-DNTVLq7o.js.map +1 -0
  185. package/dist/{sequence-store-DaaWr0Os.js → sequence-store-CmYb6s0g.js} +6 -5
  186. package/dist/sequence-store-CmYb6s0g.js.map +1 -0
  187. package/dist/{server-Dyva03K8.js → server-DoRPPOeR.js} +308 -230
  188. package/dist/server-DoRPPOeR.js.map +1 -0
  189. package/dist/{session-D9ub6Wl1.js → session-B6XaP83h.js} +3 -3
  190. package/dist/session-B6XaP83h.js.map +1 -0
  191. package/dist/{session-B9AilxOE.js → session-BgGDyP2C.js} +3 -3
  192. package/dist/session-BgGDyP2C.js.map +1 -0
  193. package/dist/session-Bp4zTh4l.js +2 -0
  194. package/dist/{session-D0qFkBla.cjs → session-Mm7GQbSH.cjs} +3 -3
  195. package/dist/session-Mm7GQbSH.cjs.map +1 -0
  196. package/dist/{session-store-C8tEvMPw.js → session-store-DWxJ5Pof.js} +79 -17
  197. package/dist/session-store-DWxJ5Pof.js.map +1 -0
  198. package/dist/{session-store-B0QZE8Bx.cjs → session-store-yfwnj0OC.cjs} +126 -16
  199. package/dist/session-store-yfwnj0OC.cjs.map +1 -0
  200. package/dist/{sla-engine-5IhTsBUR.js → sla-engine-CP2KiKDS.js} +1 -1
  201. package/dist/{sla-engine-BqX-7u-7.js → sla-engine-O-A1ntu_.js} +2 -2
  202. package/dist/{sla-engine-BqX-7u-7.js.map → sla-engine-O-A1ntu_.js.map} +1 -1
  203. package/dist/{sop-Vp0UPWFW.js → sop-BV7ICAFR.js} +4 -11
  204. package/dist/sop-BV7ICAFR.js.map +1 -0
  205. package/dist/{sop-DkhVChGy.js → sop-D33qTHUb.js} +1 -1
  206. package/dist/survey-engine-DKctGcLQ.js +2 -0
  207. package/dist/{survey-engine-DBjCYqCv.js → survey-engine-DngXBv47.js} +5 -4
  208. package/dist/survey-engine-DngXBv47.js.map +1 -0
  209. package/dist/{sync-state-CwLSt_1m.js → sync-state-BaA8LbTI.js} +1 -1
  210. package/dist/{sync-state-ChaLbamC.js → sync-state-DMZgzpez.js} +4 -12
  211. package/dist/sync-state-DMZgzpez.js.map +1 -0
  212. package/dist/{ticket-writer-CjqKeIRD.js → ticket-writer-DsfpeLGZ.js} +1 -1
  213. package/dist/{ticket-writer-j2oX_Wal.js → ticket-writer-a9on36Wb.js} +12 -24
  214. package/dist/ticket-writer-a9on36Wb.js.map +1 -0
  215. package/dist/{tone-Bdm5uaht.js → tone-C7bqK69y.js} +5 -12
  216. package/dist/tone-C7bqK69y.js.map +1 -0
  217. package/dist/{tone-DRKlZgPr.cjs → tone-Cmc7O2Fx.cjs} +3 -9
  218. package/dist/tone-Cmc7O2Fx.cjs.map +1 -0
  219. package/dist/{tone-vNb2DAAD.js → tone-mXSftvTn.js} +3 -8
  220. package/dist/tone-mXSftvTn.js.map +1 -0
  221. package/dist/{transcript-watcher-CL2QUygI.js → transcript-watcher-BoClrJAz.js} +18 -11
  222. package/dist/transcript-watcher-BoClrJAz.js.map +1 -0
  223. package/dist/unmatched-transcripts-C92zAoM4.js +2 -0
  224. package/dist/unmatched-transcripts-DC-VQ9YS.js +16 -0
  225. package/dist/unmatched-transcripts-DC-VQ9YS.js.map +1 -0
  226. package/dist/update-deal-CWy1eLJI.js +2 -0
  227. package/dist/{update-deal-DKC79skb.js → update-deal-DSzr_Aau.js} +3 -3
  228. package/dist/{update-deal-DKC79skb.js.map → update-deal-DSzr_Aau.js.map} +1 -1
  229. package/dist/{usage-D0-TYJkw.js → usage-BVlFlKW_.js} +8 -6
  230. package/dist/usage-BVlFlKW_.js.map +1 -0
  231. package/dist/usage-CClTf5e6.cjs.map +1 -1
  232. package/dist/usage-D0u9a-lV.js.map +1 -1
  233. package/dist/{vault-DXCg29W-.js → vault-CfwZdNzC.js} +3 -4
  234. package/dist/vault-CfwZdNzC.js.map +1 -0
  235. package/dist/{vault-C1D3zScD.js → vault-DxKP4_R2.js} +1 -1
  236. package/dist/{webhooks-Xn6zO6kd.cjs → webhooks-CwW-3kvG.cjs} +5 -19
  237. package/dist/webhooks-CwW-3kvG.cjs.map +1 -0
  238. package/dist/{webhooks-7EpA05Qr.js → webhooks-DXr1IoKn.js} +8 -21
  239. package/dist/webhooks-DXr1IoKn.js.map +1 -0
  240. package/dist/{webhooks-BO2UAnmn.js → webhooks-sWZ8CJtR.js} +5 -18
  241. package/dist/webhooks-sWZ8CJtR.js.map +1 -0
  242. package/package.json +22 -2
  243. package/dist/approvals-DpjxGHFp.js.map +0 -1
  244. package/dist/auth-CyFuu9X_.js +0 -2
  245. package/dist/auth-DFWwWcYD.js.map +0 -1
  246. package/dist/backup-CeMk9z86.js.map +0 -1
  247. package/dist/backup-f_hC7rBV.js +0 -2
  248. package/dist/context-builder-BzWAp3Zs.js.map +0 -1
  249. package/dist/context-builder-DlrRcqmJ.js +0 -2
  250. package/dist/custom-fields-Pl2t9xzp.js.map +0 -1
  251. package/dist/custom-objects-BHgn1GEX.js.map +0 -1
  252. package/dist/customer-dir-DIylZ8Q6.js.map +0 -1
  253. package/dist/file-lock-B_zi7NQl.js.map +0 -1
  254. package/dist/gmail-sync-DIaxInDT.js.map +0 -1
  255. package/dist/gmail-sync-hHm9gaWd.cjs.map +0 -1
  256. package/dist/gmail-sync-rQaVqKWd.js.map +0 -1
  257. package/dist/goal-engine-KpBftn4V.js.map +0 -1
  258. package/dist/identity-gyfWdrcX.js +0 -2
  259. package/dist/import-hubspot-BaK71U_K.js.map +0 -1
  260. package/dist/index-V8BFaH-b.d.ts.map +0 -1
  261. package/dist/index-YqwMd6aQ.d.cts.map +0 -1
  262. package/dist/interactions-writer-CrPStUll.cjs.map +0 -1
  263. package/dist/interactions-writer-DO3KcSR3.js.map +0 -1
  264. package/dist/interactions-writer-SLHnoEeE.js.map +0 -1
  265. package/dist/interactions-writer-dSPy1XfO.js +0 -2
  266. package/dist/knowledge-base-D0Fh40kc.js.map +0 -1
  267. package/dist/lancedb-rlvWoPwl.js.map +0 -1
  268. package/dist/lead-model-BCFzyktm.js.map +0 -1
  269. package/dist/memory-Bb6ky3kb.js.map +0 -1
  270. package/dist/notification-dispatcher-0vYNngWe.js.map +0 -1
  271. package/dist/pipeline-writer-BvVquKIe.js.map +0 -1
  272. package/dist/pipeline-writer-N2omexxp.cjs.map +0 -1
  273. package/dist/pipeline-writer-eufx_0o1.js.map +0 -1
  274. package/dist/proactive-worker-BrLHNhjH.js.map +0 -1
  275. package/dist/push-manager-CdqIIkuh.js.map +0 -1
  276. package/dist/quote-generator-BfwENXzg.js.map +0 -1
  277. package/dist/rbac-C7c8tcES.js +0 -2
  278. package/dist/rbac-CTIktZaC.js.map +0 -1
  279. package/dist/relationship-health-odxEoQdJ.js.map +0 -1
  280. package/dist/revenue-simulation-Bqf2DLVB.js.map +0 -1
  281. package/dist/segments-BqcD5HIl.js.map +0 -1
  282. package/dist/sequence-engine-CCTHEBgi.js +0 -2
  283. package/dist/sequence-engine-J1lTW_in.js.map +0 -1
  284. package/dist/sequence-store-DaaWr0Os.js.map +0 -1
  285. package/dist/server-Dyva03K8.js.map +0 -1
  286. package/dist/session-B9AilxOE.js.map +0 -1
  287. package/dist/session-D0qFkBla.cjs.map +0 -1
  288. package/dist/session-D9ub6Wl1.js.map +0 -1
  289. package/dist/session-mWHA71Lw.js +0 -2
  290. package/dist/session-store-B0QZE8Bx.cjs.map +0 -1
  291. package/dist/session-store-C8tEvMPw.js.map +0 -1
  292. package/dist/sop-Vp0UPWFW.js.map +0 -1
  293. package/dist/survey-engine-C06hcQt3.js +0 -2
  294. package/dist/survey-engine-DBjCYqCv.js.map +0 -1
  295. package/dist/sync-state-ChaLbamC.js.map +0 -1
  296. package/dist/ticket-writer-j2oX_Wal.js.map +0 -1
  297. package/dist/tone-Bdm5uaht.js.map +0 -1
  298. package/dist/tone-DRKlZgPr.cjs.map +0 -1
  299. package/dist/tone-vNb2DAAD.js.map +0 -1
  300. package/dist/transcript-watcher-CL2QUygI.js.map +0 -1
  301. package/dist/unmatched-transcripts-BsH5bhkU.js +0 -26
  302. package/dist/unmatched-transcripts-BsH5bhkU.js.map +0 -1
  303. package/dist/unmatched-transcripts-D0PrJ9iz.js +0 -2
  304. package/dist/update-deal-BNwPGaTV.js +0 -2
  305. package/dist/usage-D0-TYJkw.js.map +0 -1
  306. package/dist/vault-DXCg29W-.js.map +0 -1
  307. package/dist/webhooks-7EpA05Qr.js.map +0 -1
  308. package/dist/webhooks-BO2UAnmn.js.map +0 -1
  309. package/dist/webhooks-Xn6zO6kd.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"autofill-Di_-SP7t.js","names":[],"sources":["../src/core/autofill.ts"],"sourcesContent":["/**\n * Call/Meeting → CRM autofill (domino D9 / C1): extract structured fields from a\n * transcript so they can be written to the CRM (through the D4 approval gate).\n * Uses the LLM when available, with a deterministic heuristic fallback so it\n * always returns something useful and is testable offline.\n */\nexport type StageName = \"lead\" | \"qualified\" | \"proposal\" | \"negotiation\" | \"won\" | \"lost\";\n\nexport interface AutofillResult {\n summary: string;\n nextSteps: string[];\n objections: string[];\n stage?: StageName;\n}\n\nconst NEXT_STEP_RE = /^(?:-?\\s*\\[ \\]|next step|todo|follow.?up|action item)\\b[:\\-\\s]*/i;\nconst OBJECTION_RE = /\\b(concern|worried|too expensive|expensive|hesitant|however|push back)\\b/i;\n\nfunction detectStage(text: string): StageName | undefined {\n const t = text.toLowerCase();\n if (t.includes(\"closed won\") || t.includes(\"signed\")) return \"won\";\n if (t.includes(\"closed lost\") || t.includes(\"lost the deal\")) return \"lost\";\n if (t.includes(\"negotiat\")) return \"negotiation\";\n if (t.includes(\"proposal\") || t.includes(\"quote\")) return \"proposal\";\n if (t.includes(\"qualif\")) return \"qualified\";\n return undefined;\n}\n\nexport function heuristicExtract(transcript: string): AutofillResult {\n const lines = transcript\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n\n const nextSteps = lines\n .filter((l) => NEXT_STEP_RE.test(l))\n .map((l) => l.replace(NEXT_STEP_RE, \"\").trim())\n .filter(Boolean)\n .slice(0, 10);\n\n const objections = lines.filter((l) => OBJECTION_RE.test(l)).slice(0, 10);\n\n const base = { summary: transcript.slice(0, 400), nextSteps, objections };\n const stage = detectStage(transcript);\n return stage === undefined ? base : { ...base, stage };\n}\n\nexport async function extractAutofill(\n transcript: string,\n ctx?: { slug?: string }\n): Promise<AutofillResult> {\n try {\n const { callLlm } = await import(\"./llm.js\");\n const prompt =\n `Extract CRM fields from this meeting transcript. Return ONLY JSON: ` +\n `{ \"summary\": string, \"nextSteps\": string[], \"objections\": string[], ` +\n `\"stage\": \"lead\"|\"qualified\"|\"proposal\"|\"negotiation\"|\"won\"|\"lost\"|null }.\\n\\n${transcript}`;\n const raw = await callLlm(prompt, {\n tool: \"autofill\",\n ...(ctx?.slug ? { slug: ctx.slug } : {}),\n });\n const parsed = JSON.parse(raw) as Partial<AutofillResult> & { stage?: string | null };\n const base = {\n summary: parsed.summary ?? transcript.slice(0, 400),\n nextSteps: Array.isArray(parsed.nextSteps) ? parsed.nextSteps : [],\n objections: Array.isArray(parsed.objections) ? parsed.objections : [],\n };\n return parsed.stage ? { ...base, stage: parsed.stage as StageName } : base;\n } catch {\n return heuristicExtract(transcript);\n }\n}\n"],"mappings":";AAeA,MAAM,eAAe;AACrB,MAAM,eAAe;AAErB,SAAS,YAAY,MAAqC;CACxD,MAAM,IAAI,KAAK,YAAY;CAC3B,IAAI,EAAE,SAAS,YAAY,KAAK,EAAE,SAAS,QAAQ,GAAG,OAAO;CAC7D,IAAI,EAAE,SAAS,aAAa,KAAK,EAAE,SAAS,eAAe,GAAG,OAAO;CACrE,IAAI,EAAE,SAAS,UAAU,GAAG,OAAO;CACnC,IAAI,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,OAAO,GAAG,OAAO;CAC1D,IAAI,EAAE,SAAS,QAAQ,GAAG,OAAO;AAEnC;AAEA,SAAgB,iBAAiB,YAAoC;CACnE,MAAM,QAAQ,WACX,MAAM,IAAI,EACV,KAAK,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;CAEjB,MAAM,YAAY,MACf,QAAQ,MAAM,aAAa,KAAK,CAAC,CAAC,EAClC,KAAK,MAAM,EAAE,QAAQ,cAAc,EAAE,EAAE,KAAK,CAAC,EAC7C,OAAO,OAAO,EACd,MAAM,GAAG,EAAE;CAEd,MAAM,aAAa,MAAM,QAAQ,MAAM,aAAa,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,EAAE;CAExE,MAAM,OAAO;EAAE,SAAS,WAAW,MAAM,GAAG,GAAG;EAAG;EAAW;CAAW;CACxE,MAAM,QAAQ,YAAY,UAAU;CACpC,OAAO,UAAU,KAAA,IAAY,OAAO;EAAE,GAAG;EAAM;CAAM;AACvD;AAEA,eAAsB,gBACpB,YACA,KACyB;CACzB,IAAI;EACF,MAAM,EAAE,YAAY,MAAM,OAAO;EAKjC,MAAM,MAAM,MAAM,QAAQ,uNADwD,cAChD;GAChC,MAAM;GACN,GAAI,KAAK,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;EACxC,CAAC;EACD,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,MAAM,OAAO;GACX,SAAS,OAAO,WAAW,WAAW,MAAM,GAAG,GAAG;GAClD,WAAW,MAAM,QAAQ,OAAO,SAAS,IAAI,OAAO,YAAY,CAAC;GACjE,YAAY,MAAM,QAAQ,OAAO,UAAU,IAAI,OAAO,aAAa,CAAC;EACtE;EACA,OAAO,OAAO,QAAQ;GAAE,GAAG;GAAM,OAAO,OAAO;EAAmB,IAAI;CACxE,QAAQ;EACN,OAAO,iBAAiB,UAAU;CACpC;AACF"}
1
+ {"version":3,"file":"autofill-B9VtlR2j.js","names":[],"sources":["../src/core/autofill.ts"],"sourcesContent":["/**\n * Call/Meeting → CRM autofill (domino D9 / C1): extract structured fields from a\n * transcript so they can be written to the CRM (through the D4 approval gate).\n * Uses the LLM when available, with a deterministic heuristic fallback so it\n * always returns something useful and is testable offline.\n */\nexport type StageName = \"lead\" | \"qualified\" | \"proposal\" | \"negotiation\" | \"won\" | \"lost\";\n\nexport interface AutofillResult {\n summary: string;\n nextSteps: string[];\n objections: string[];\n stage?: StageName;\n}\n\nconst NEXT_STEP_RE = /^(?:-?\\s*\\[ \\]|next step|todo|follow.?up|action item)\\b[:\\-\\s]*/i;\nconst OBJECTION_RE = /\\b(concern|worried|too expensive|expensive|hesitant|however|push back)\\b/i;\n\nfunction detectStage(text: string): StageName | undefined {\n const t = text.toLowerCase();\n if (t.includes(\"closed won\") || t.includes(\"signed\")) return \"won\";\n if (t.includes(\"closed lost\") || t.includes(\"lost the deal\")) return \"lost\";\n if (t.includes(\"negotiat\")) return \"negotiation\";\n if (t.includes(\"proposal\") || t.includes(\"quote\")) return \"proposal\";\n if (t.includes(\"qualif\")) return \"qualified\";\n return undefined;\n}\n\nexport function heuristicExtract(transcript: string): AutofillResult {\n const lines = transcript\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n\n const nextSteps = lines\n .filter((l) => NEXT_STEP_RE.test(l))\n .map((l) => l.replace(NEXT_STEP_RE, \"\").trim())\n .filter(Boolean)\n .slice(0, 10);\n\n const objections = lines.filter((l) => OBJECTION_RE.test(l)).slice(0, 10);\n\n const base = { summary: transcript.slice(0, 400), nextSteps, objections };\n const stage = detectStage(transcript);\n return stage === undefined ? base : { ...base, stage };\n}\n\nexport async function extractAutofill(\n transcript: string,\n ctx?: { slug?: string }\n): Promise<AutofillResult> {\n try {\n const { callLlm } = await import(\"./llm.js\");\n const prompt =\n `Extract CRM fields from this meeting transcript. Return ONLY JSON: ` +\n `{ \"summary\": string, \"nextSteps\": string[], \"objections\": string[], ` +\n `\"stage\": \"lead\"|\"qualified\"|\"proposal\"|\"negotiation\"|\"won\"|\"lost\"|null }.\\n\\n${transcript}`;\n const raw = await callLlm(prompt, {\n tool: \"autofill\",\n ...(ctx?.slug ? { slug: ctx.slug } : {}),\n });\n const parsed = JSON.parse(raw) as Partial<AutofillResult> & { stage?: string | null };\n const base = {\n summary: parsed.summary ?? transcript.slice(0, 400),\n nextSteps: Array.isArray(parsed.nextSteps) ? parsed.nextSteps : [],\n objections: Array.isArray(parsed.objections) ? parsed.objections : [],\n };\n return parsed.stage ? { ...base, stage: parsed.stage as StageName } : base;\n } catch {\n return heuristicExtract(transcript);\n }\n}\n"],"mappings":";AAeA,MAAM,eAAe;AACrB,MAAM,eAAe;AAErB,SAAS,YAAY,MAAqC;CACxD,MAAM,IAAI,KAAK,YAAY;CAC3B,IAAI,EAAE,SAAS,YAAY,KAAK,EAAE,SAAS,QAAQ,GAAG,OAAO;CAC7D,IAAI,EAAE,SAAS,aAAa,KAAK,EAAE,SAAS,eAAe,GAAG,OAAO;CACrE,IAAI,EAAE,SAAS,UAAU,GAAG,OAAO;CACnC,IAAI,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,OAAO,GAAG,OAAO;CAC1D,IAAI,EAAE,SAAS,QAAQ,GAAG,OAAO;AAEnC;AAEA,SAAgB,iBAAiB,YAAoC;CACnE,MAAM,QAAQ,WACX,MAAM,IAAI,EACV,KAAK,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;CAEjB,MAAM,YAAY,MACf,QAAQ,MAAM,aAAa,KAAK,CAAC,CAAC,EAClC,KAAK,MAAM,EAAE,QAAQ,cAAc,EAAE,EAAE,KAAK,CAAC,EAC7C,OAAO,OAAO,EACd,MAAM,GAAG,EAAE;CAEd,MAAM,aAAa,MAAM,QAAQ,MAAM,aAAa,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,EAAE;CAExE,MAAM,OAAO;EAAE,SAAS,WAAW,MAAM,GAAG,GAAG;EAAG;EAAW;CAAW;CACxE,MAAM,QAAQ,YAAY,UAAU;CACpC,OAAO,UAAU,KAAA,IAAY,OAAO;EAAE,GAAG;EAAM;CAAM;AACvD;AAEA,eAAsB,gBACpB,YACA,KACyB;CACzB,IAAI;EACF,MAAM,EAAE,YAAY,MAAM,OAAO;EAKjC,MAAM,MAAM,MAAM,QAAQ,uNADwD,cAChD;GAChC,MAAM;GACN,GAAI,KAAK,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;EACxC,CAAC;EACD,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,MAAM,OAAO;GACX,SAAS,OAAO,WAAW,WAAW,MAAM,GAAG,GAAG;GAClD,WAAW,MAAM,QAAQ,OAAO,SAAS,IAAI,OAAO,YAAY,CAAC;GACjE,YAAY,MAAM,QAAQ,OAAO,UAAU,IAAI,OAAO,aAAa,CAAC;EACtE;EACA,OAAO,OAAO,QAAQ;GAAE,GAAG;GAAM,OAAO,OAAO;EAAmB,IAAI;CACxE,QAAQ;EACN,OAAO,iBAAiB,UAAU;CACpC;AACF"}
@@ -1,9 +1,10 @@
1
+ import { i as writeJsonFile } from "./json-store-WWsFzXub.js";
1
2
  import { i as success, n as error, r as info, t as bold } from "./colors-BG07TZQz.js";
2
3
  import { Command } from "commander";
3
4
  import path from "path";
4
5
  import fs from "fs";
5
- import { execSync } from "child_process";
6
6
  import { createHash } from "crypto";
7
+ import { execSync } from "child_process";
7
8
  //#region src/commands/backup.ts
8
9
  function getConfigPath(dataDir) {
9
10
  return path.join(dataDir, ".agentic", "config.json");
@@ -18,9 +19,7 @@ function readAgenticConfig(dataDir) {
18
19
  }
19
20
  }
20
21
  function writeAgenticConfig(dataDir, config) {
21
- const filePath = getConfigPath(dataDir);
22
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
23
- fs.writeFileSync(filePath, JSON.stringify(config, null, 2), "utf-8");
22
+ writeJsonFile(getConfigPath(dataDir), config);
24
23
  }
25
24
  function countDir(dir) {
26
25
  let files = 0;
@@ -102,8 +101,7 @@ function appendBackupLog(dataDir, entry) {
102
101
  entries = entries.filter((e) => e.filename !== entry.filename);
103
102
  entries.unshift(entry);
104
103
  if (entries.length > 100) entries = entries.slice(0, 100);
105
- fs.mkdirSync(path.dirname(logPath), { recursive: true });
106
- fs.writeFileSync(logPath, JSON.stringify(entries, null, 2), "utf-8");
104
+ writeJsonFile(logPath, entries);
107
105
  }
108
106
  function readBackupLog(dataDir) {
109
107
  const logPath = path.join(dataDir, ".agentic", "backup-log.json");
@@ -414,4 +412,4 @@ const restoreCommand = new Command("restore").argument("<path>", "Path to backup
414
412
  //#endregion
415
413
  export { restoreCommand as a, runRestore as c, runVerify as d, shouldRunScheduledBackup as f, readBackupLog as i, runRestoreDrill as l, verifyBackupFile as m, listBackupsInDir as n, runBackup as o, uploadBackup as p, pruneOldBackups as r, runBackupSchedule as s, backupCommand as t, runScheduledBackupIfDue as u };
416
414
 
417
- //# sourceMappingURL=backup-CeMk9z86.js.map
415
+ //# sourceMappingURL=backup-CTlIxUdO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-CTlIxUdO.js","names":[],"sources":["../src/commands/backup.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { execSync } from \"child_process\";\nimport { createHash } from \"crypto\";\nimport { success, error, info, bold } from \"../ui/colors.js\";\nimport { writeJsonFile } from \"../fs/json-store.js\";\n\nexport interface BackupManifest {\n version: \"1\";\n createdAt: string;\n dxcrmVersion: string;\n directories: string[];\n customerCount: number;\n fileCount: number;\n totalBytes: number;\n sha256: string;\n encrypted: boolean;\n retentionTier?: \"daily\" | \"weekly\" | \"monthly\";\n}\n\nexport interface BackupScheduleConfig {\n every: string;\n keep: number;\n weekly?: number;\n monthly?: number;\n lastBackup: string | null;\n remote?: string;\n}\n\nexport interface AgenticConfig {\n backupSchedule?: BackupScheduleConfig;\n}\n\nexport interface BackupEntry {\n filename: string;\n path: string;\n createdAt: string;\n sizeBytes: number;\n verified: boolean;\n encrypted: boolean;\n customerCount: number;\n fileCount: number;\n}\n\n// ─── Config helpers ────────────────────────────────────────────────────────────\n\nfunction getConfigPath(dataDir: string): string {\n return path.join(dataDir, \".agentic\", \"config.json\");\n}\n\nfunction readAgenticConfig(dataDir: string): AgenticConfig {\n const filePath = getConfigPath(dataDir);\n if (!fs.existsSync(filePath)) return {};\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\") as string) as AgenticConfig;\n } catch {\n return {};\n }\n}\n\nfunction writeAgenticConfig(dataDir: string, config: AgenticConfig): void {\n writeJsonFile(getConfigPath(dataDir), config);\n}\n\n// ─── Manifest ─────────────────────────────────────────────────────────────────\n\nfunction countDir(dir: string): { files: number; bytes: number } {\n let files = 0;\n let bytes = 0;\n if (!fs.existsSync(dir)) return { files, bytes };\n const walk = (d: string) => {\n try {\n for (const entry of fs.readdirSync(d)) {\n const full = path.join(d, entry);\n try {\n const stat = fs.statSync(full);\n if (stat.isDirectory()) walk(full);\n else {\n files++;\n bytes += stat.size;\n }\n } catch {\n /* skip */\n }\n }\n } catch {\n /* skip */\n }\n };\n walk(dir);\n return { files, bytes };\n}\n\nfunction countCustomers(dataDir: string): number {\n const dir = path.join(dataDir, \"customers\");\n if (!fs.existsSync(dir)) return 0;\n try {\n return fs.readdirSync(dir).filter((f) => {\n try {\n return fs.statSync(path.join(dir, f)).isDirectory();\n } catch {\n return false;\n }\n }).length;\n } catch {\n return 0;\n }\n}\n\nfunction sha256File(filePath: string): string {\n if (!fs.existsSync(filePath)) return \"\";\n const hash = createHash(\"sha256\");\n hash.update(fs.readFileSync(filePath));\n return hash.digest(\"hex\");\n}\n\nfunction buildManifest(\n dataDir: string,\n dirs: string[],\n zipPath: string,\n encrypted: boolean\n): BackupManifest {\n let totalFiles = 0;\n let totalBytes = 0;\n for (const d of dirs) {\n const full = path.join(dataDir, d);\n const { files, bytes } = countDir(full);\n totalFiles += files;\n totalBytes += bytes;\n }\n return {\n version: \"1\",\n createdAt: new Date().toISOString(),\n dxcrmVersion: \"0.1.0\",\n directories: dirs,\n customerCount: countCustomers(dataDir),\n fileCount: totalFiles,\n totalBytes,\n sha256: sha256File(zipPath),\n encrypted,\n };\n}\n\n// ─── Manifest log ──────────────────────────────────────────────────────────────\n\nfunction appendBackupLog(dataDir: string, entry: BackupEntry): void {\n const logPath = path.join(dataDir, \".agentic\", \"backup-log.json\");\n let entries: BackupEntry[] = [];\n if (fs.existsSync(logPath)) {\n try {\n entries = JSON.parse(fs.readFileSync(logPath, \"utf-8\") as string) as BackupEntry[];\n } catch {\n entries = [];\n }\n }\n // Deduplicate by filename — update existing entry if same file backed up again\n entries = entries.filter((e) => e.filename !== entry.filename);\n entries.unshift(entry);\n // Keep last 100 entries\n if (entries.length > 100) entries = entries.slice(0, 100);\n writeJsonFile(logPath, entries);\n}\n\nexport function readBackupLog(dataDir: string): BackupEntry[] {\n const logPath = path.join(dataDir, \".agentic\", \"backup-log.json\");\n if (!fs.existsSync(logPath)) return [];\n try {\n return JSON.parse(fs.readFileSync(logPath, \"utf-8\") as string) as BackupEntry[];\n } catch {\n return [];\n }\n}\n\n// ─── runBackup ────────────────────────────────────────────────────────────────\n\nexport async function runBackup(\n output?: string,\n dataDir?: string,\n opts: { encrypt?: boolean; remote?: string } = {}\n): Promise<BackupManifest | null> {\n const dir = dataDir ?? process.cwd();\n const customersDir = path.join(dir, \"customers\");\n\n if (!fs.existsSync(customersDir)) {\n console.error(error(\"✗ No customers directory found.\"));\n process.exit(1);\n }\n\n const zipPath =\n output ?? path.join(dir, `dxcrm-backup-${new Date().toISOString().slice(0, 10)}.zip`);\n\n // Determine which directories to include\n const includeDirs = [\"customers/\"];\n if (fs.existsSync(path.join(dir, \".agentic\"))) {\n includeDirs.push(\".agentic/\");\n }\n\n try {\n execSync(`zip -r \"${zipPath}\" ${includeDirs.join(\" \")}`, { cwd: dir });\n\n // Build manifest and append to zip\n const manifest = buildManifest(dir, includeDirs, zipPath, opts.encrypt ?? false);\n const manifestPath = path.join(dir, \".dxcrm-manifest-tmp.json\");\n fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), \"utf-8\");\n try {\n execSync(`zip -j \"${zipPath}\" \"${manifestPath}\"`, { cwd: dir });\n } catch {\n /* non-fatal */\n }\n fs.unlinkSync(manifestPath);\n\n // Verify integrity\n const verified = verifyBackupFile(zipPath);\n\n const entry: BackupEntry = {\n filename: path.basename(zipPath),\n path: zipPath,\n createdAt: manifest.createdAt,\n sizeBytes: fs.existsSync(zipPath) ? fs.statSync(zipPath).size : 0,\n verified,\n encrypted: opts.encrypt ?? false,\n customerCount: manifest.customerCount,\n fileCount: manifest.fileCount,\n };\n appendBackupLog(dir, entry);\n\n // Remote upload\n if (opts.remote) {\n await uploadBackup(zipPath, opts.remote);\n }\n\n console.log(success(`✓ Backup saved: ${zipPath}`));\n console.log(\n info(\n ` Customers: ${manifest.customerCount} Files: ${manifest.fileCount} Size: ${(manifest.totalBytes / 1024 / 1024).toFixed(1)} MB`\n )\n );\n if (!verified) console.log(info(\" ⚠ Integrity check failed — backup may be incomplete\"));\n\n return manifest;\n } catch (err) {\n console.error(error(`✗ Backup failed: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n// ─── Verify ───────────────────────────────────────────────────────────────────\n\nexport function verifyBackupFile(zipPath: string): boolean {\n if (!fs.existsSync(zipPath)) return false;\n try {\n execSync(`unzip -t \"${zipPath}\"`, { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function runVerify(zipPath: string): Promise<void> {\n if (!fs.existsSync(zipPath)) {\n console.error(error(`✗ File not found: ${zipPath}`));\n process.exit(1);\n }\n\n console.log(info(`Verifying ${path.basename(zipPath)}...`));\n const ok = verifyBackupFile(zipPath);\n\n if (ok) {\n const size = fs.statSync(zipPath).size;\n const sha = sha256File(zipPath);\n console.log(success(\"✓ ZIP integrity OK\"));\n console.log(info(` Size: ${(size / 1024 / 1024).toFixed(1)} MB`));\n console.log(info(` SHA-256: ${sha}`));\n } else {\n console.error(error(\"✗ Integrity check failed\"));\n process.exit(1);\n }\n}\n\n// ─── Remote Upload ────────────────────────────────────────────────────────────\n\nexport async function uploadBackup(localPath: string, remote: string): Promise<void> {\n if (remote.startsWith(\"s3://\")) {\n // Requires AWS CLI or @aws-sdk/client-s3 to be installed\n try {\n execSync(`aws s3 cp \"${localPath}\" \"${remote}${path.basename(localPath)}\"`, {\n stdio: \"pipe\",\n });\n console.log(info(` ✓ Uploaded to ${remote}${path.basename(localPath)}`));\n } catch (err) {\n console.error(\n error(\n ` ✗ S3 upload failed (install aws-cli or @aws-sdk/client-s3): ${(err as Error).message}`\n )\n );\n }\n } else if (remote.startsWith(\"rsync://\")) {\n const dest = remote.replace(\"rsync://\", \"\");\n try {\n execSync(`rsync -az \"${localPath}\" \"${dest}\"`, { stdio: \"pipe\" });\n console.log(info(` ✓ Synced to ${dest}`));\n } catch (err) {\n console.error(error(` ✗ rsync failed: ${(err as Error).message}`));\n }\n } else {\n // Local directory copy\n try {\n const destPath = path.join(remote, path.basename(localPath));\n fs.mkdirSync(remote, { recursive: true });\n fs.copyFileSync(localPath, destPath);\n console.log(info(` ✓ Copied to ${destPath}`));\n } catch (err) {\n console.error(error(` ✗ Copy failed: ${(err as Error).message}`));\n }\n }\n}\n\n// ─── List Backups ─────────────────────────────────────────────────────────────\n\nexport function listBackupsInDir(dir: string): BackupEntry[] {\n if (!fs.existsSync(dir)) return [];\n try {\n return fs\n .readdirSync(dir)\n .filter((f) => f.match(/^dxcrm-backup-.*\\.(zip|dxbak)$/))\n .map((f) => {\n const fullPath = path.join(dir, f);\n const stat = fs.statSync(fullPath);\n return {\n filename: f,\n path: fullPath,\n createdAt: stat.mtime.toISOString(),\n sizeBytes: stat.size,\n verified: false,\n encrypted: f.endsWith(\".dxbak\"),\n customerCount: 0,\n fileCount: 0,\n } satisfies BackupEntry;\n })\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n } catch {\n return [];\n }\n}\n\n// ─── Retention Policy ─────────────────────────────────────────────────────────\n\nexport interface RetentionConfig {\n daily?: number;\n weekly?: number;\n monthly?: number;\n}\n\nexport function pruneOldBackups(dir: string, keep: number, retention?: RetentionConfig): void {\n const files = fs\n .readdirSync(dir)\n .filter((f) => f.match(/^dxcrm-backup-\\d{4}-\\d{2}-\\d{2}.*\\.(zip|dxbak)$/))\n .sort();\n\n if (!retention) {\n // Legacy: keep last N\n const toDelete = files.slice(0, Math.max(0, files.length - keep));\n for (const f of toDelete) {\n try {\n fs.unlinkSync(path.join(dir, f));\n } catch {\n /* ignore */\n }\n }\n return;\n }\n\n // Grandfathering: daily → weekly → monthly\n const daily = retention.daily ?? keep;\n const weekly = retention.weekly ?? 0;\n const monthly = retention.monthly ?? 0;\n\n const kept = new Set<string>();\n\n // Keep last N daily\n for (const f of files.slice(-daily)) kept.add(f);\n\n // Keep last backup of each week (up to 'weekly' weeks)\n if (weekly > 0) {\n const byWeek = new Map<string, string>();\n for (const f of files) {\n const dateMatch = f.match(/dxcrm-backup-(\\d{4}-\\d{2}-\\d{2})/);\n if (!dateMatch?.[1]) continue;\n const d = new Date(dateMatch[1]);\n // ISO week: year + week number\n const week = `${d.getFullYear()}-W${String(Math.ceil((d.getDate() + new Date(d.getFullYear(), 0, 1).getDay()) / 7)).padStart(2, \"0\")}`;\n byWeek.set(week, f); // last backup of the week wins\n }\n Array.from(byWeek.values())\n .slice(-weekly)\n .forEach((f) => kept.add(f));\n }\n\n // Keep last backup of each month (up to 'monthly' months)\n if (monthly > 0) {\n const byMonth = new Map<string, string>();\n for (const f of files) {\n const dateMatch = f.match(/dxcrm-backup-(\\d{4}-\\d{2})/);\n if (!dateMatch?.[1]) continue;\n byMonth.set(dateMatch[1], f); // last backup of the month wins\n }\n Array.from(byMonth.values())\n .slice(-monthly)\n .forEach((f) => kept.add(f));\n }\n\n for (const f of files) {\n if (!kept.has(f)) {\n try {\n fs.unlinkSync(path.join(dir, f));\n } catch {\n /* ignore */\n }\n }\n }\n}\n\n// ─── Schedule ─────────────────────────────────────────────────────────────────\n\nexport async function runBackupSchedule(\n opts: {\n every?: string;\n keep?: string;\n weekly?: string;\n monthly?: string;\n remote?: string;\n status?: boolean;\n clear?: boolean;\n },\n dataDir?: string\n): Promise<void> {\n const dir = dataDir ?? process.cwd();\n\n if (opts.clear) {\n const config = readAgenticConfig(dir);\n delete config.backupSchedule;\n writeAgenticConfig(dir, config);\n console.log(success(\"✓ Backup schedule cleared.\"));\n return;\n }\n\n if (!opts.every && !opts.status) {\n console.error(error(\"✗ --every is required (e.g. --every day)\"));\n process.exit(1);\n return;\n }\n\n if (opts.every) {\n const keep = opts.keep ? parseInt(opts.keep, 10) : 7;\n const config = readAgenticConfig(dir);\n config.backupSchedule = {\n every: opts.every,\n keep,\n ...(opts.weekly ? { weekly: parseInt(opts.weekly, 10) } : {}),\n ...(opts.monthly ? { monthly: parseInt(opts.monthly, 10) } : {}),\n ...(opts.remote ? { remote: opts.remote } : {}),\n lastBackup: null,\n };\n writeAgenticConfig(dir, config);\n if (!opts.status) {\n console.log(\n success(\n `✓ Backup schedule set: every ${opts.every}, keep ${keep} daily${opts.weekly ? ` / ${opts.weekly} weekly` : \"\"}${opts.monthly ? ` / ${opts.monthly} monthly` : \"\"}.`\n )\n );\n }\n }\n\n if (opts.status) {\n const config = readAgenticConfig(dir);\n const sched = config.backupSchedule;\n if (!sched) {\n console.log(info(\"No backup schedule configured.\"));\n } else {\n console.log(bold(\"Backup Schedule:\"));\n console.log(` every: ${sched.every}`);\n console.log(` keep: ${sched.keep} daily backups`);\n if (sched.weekly) console.log(` weekly: ${sched.weekly} weekly backups`);\n if (sched.monthly) console.log(` monthly: ${sched.monthly} monthly backups`);\n if (sched.remote) console.log(` remote: ${sched.remote}`);\n console.log(` lastBackup: ${sched.lastBackup ?? \"never\"}`);\n }\n }\n}\n\nexport function shouldRunScheduledBackup(dataDir: string): boolean {\n const config = readAgenticConfig(dataDir);\n const sched = config.backupSchedule;\n if (!sched) return false;\n if (!sched.lastBackup) return true;\n const last = new Date(sched.lastBackup).getTime();\n const oneDayMs = 24 * 60 * 60 * 1000;\n return Date.now() - last >= oneDayMs;\n}\n\nexport async function runScheduledBackupIfDue(dataDir: string): Promise<void> {\n if (!shouldRunScheduledBackup(dataDir)) return;\n const config = readAgenticConfig(dataDir);\n const sched = config.backupSchedule!;\n const customersDir = path.join(dataDir, \"customers\");\n if (!fs.existsSync(customersDir)) return;\n\n const zipPath = path.join(dataDir, `dxcrm-backup-${new Date().toISOString().slice(0, 10)}.zip`);\n const includeDirs = [\"customers/\"];\n if (fs.existsSync(path.join(dataDir, \".agentic\"))) includeDirs.push(\".agentic/\");\n\n try {\n execSync(`zip -r \"${zipPath}\" ${includeDirs.join(\" \")}`, { cwd: dataDir });\n\n const retention: RetentionConfig | undefined =\n (sched.weekly ?? sched.monthly)\n ? {\n daily: sched.keep,\n ...(sched.weekly ? { weekly: sched.weekly } : {}),\n ...(sched.monthly ? { monthly: sched.monthly } : {}),\n }\n : undefined;\n pruneOldBackups(dataDir, sched.keep, retention);\n\n if (sched.remote) {\n await uploadBackup(zipPath, sched.remote).catch(() => {\n /* non-fatal */\n });\n }\n\n config.backupSchedule!.lastBackup = new Date().toISOString();\n writeAgenticConfig(dataDir, config);\n process.stderr.write(`[daemon] Scheduled backup saved: ${zipPath}\\n`);\n } catch (err) {\n process.stderr.write(`[daemon] Scheduled backup failed: ${(err as Error).message}\\n`);\n }\n}\n\n// ─── Restore ──────────────────────────────────────────────────────────────────\n\nexport async function runRestore(zipPath: string, dataDir?: string): Promise<void> {\n const dir = dataDir ?? process.cwd();\n try {\n execSync(`unzip -o \"${path.resolve(zipPath)}\" -d \"${dir}\"`, { cwd: dir });\n console.log(success(\"✓ Restore complete.\"));\n } catch (err) {\n console.error(error(`✗ Restore failed: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\nexport interface RestoreDrillReport {\n ok: boolean;\n verified: boolean;\n hasCustomers: boolean;\n hasAgentic: boolean;\n reason?: string;\n}\n\n/**\n * Restore-drill: verify a backup is actually restorable WITHOUT touching live\n * data — checks integrity (unzip -t) and that the archive contains the expected\n * top-level state (customers/, .agentic/). Returns a report for monitoring.\n */\nexport async function runRestoreDrill(\n zipPath: string,\n opts: { silent?: boolean } = {}\n): Promise<RestoreDrillReport> {\n const resolved = path.resolve(zipPath);\n if (!fs.existsSync(resolved)) {\n if (!opts.silent) console.error(error(`✗ File not found: ${zipPath}`));\n return {\n ok: false,\n verified: false,\n hasCustomers: false,\n hasAgentic: false,\n reason: \"not_found\",\n };\n }\n\n const verified = verifyBackupFile(resolved);\n let hasCustomers = false;\n let hasAgentic = false;\n if (verified) {\n try {\n const listing = execSync(`unzip -l \"${resolved}\"`, { stdio: \"pipe\" }).toString();\n hasCustomers = listing.includes(\"customers/\");\n hasAgentic = listing.includes(\".agentic/\");\n } catch {\n /* listing failed — treated as incomplete */\n }\n }\n\n const ok = verified && hasCustomers;\n if (!opts.silent) {\n if (ok) {\n console.log(\n success(\n `✓ Restore drill OK — integrity verified; customers/${hasAgentic ? \" + .agentic/\" : \"\"} present`\n )\n );\n } else {\n console.error(\n error(`✗ Restore drill failed (verified=${verified}, customers=${hasCustomers})`)\n );\n }\n }\n return { ok, verified, hasCustomers, hasAgentic };\n}\n\n// ─── Commands ─────────────────────────────────────────────────────────────────\n\nconst scheduleSubCommand = new Command(\"schedule\")\n .description(\"Configure automatic backup schedule\")\n .option(\"--every <interval>\", \"Backup interval (e.g. day)\")\n .option(\"--keep <n>\", \"Daily backups to keep (default: 7)\")\n .option(\"--weekly <n>\", \"Weekly backups to keep (e.g. 4)\")\n .option(\"--monthly <n>\", \"Monthly backups to keep (e.g. 12)\")\n .option(\"--remote <url>\", \"Remote destination (s3://, rsync://, or local path)\")\n .option(\"--status\", \"Show current schedule\")\n .option(\"--clear\", \"Remove backup schedule\")\n .action((opts) => runBackupSchedule(opts, process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd()));\n\nconst verifySubCommand = new Command(\"verify\")\n .argument(\"<path>\", \"Path to backup zip\")\n .description(\"Verify backup integrity (SHA-256 + zip test)\")\n .action((zipPath: string) => runVerify(zipPath));\n\nconst drillSubCommand = new Command(\"drill\")\n .argument(\"<path>\", \"Path to backup zip\")\n .description(\"Restore-drill: verify a backup is restorable without touching live data\")\n .action(async (zipPath: string) => {\n const report = await runRestoreDrill(zipPath);\n if (!report.ok) process.exitCode = 1;\n });\n\nconst listSubCommand = new Command(\"list\").description(\"List available backups\").action(() => {\n const dir = process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd();\n const entries = readBackupLog(dir);\n const fileEntries = listBackupsInDir(dir);\n const combined = entries.length > 0 ? entries : fileEntries;\n if (combined.length === 0) {\n console.log(info(\"No backups found.\"));\n return;\n }\n for (const e of combined) {\n const enc = e.encrypted ? \" [encrypted]\" : \"\";\n const ver = e.verified ? \" ✓\" : \"\";\n const mb = e.sizeBytes > 0 ? ` ${(e.sizeBytes / 1024 / 1024).toFixed(1)} MB` : \"\";\n console.log(` ${bold(e.filename)}${enc}${ver}${mb} ${e.createdAt.slice(0, 10)}`);\n }\n});\n\nexport const backupCommand = new Command(\"backup\")\n .argument(\"[output]\", \"Output path for backup zip\")\n .description(\"Backup customers/ + .agentic/ directories\")\n .option(\"--encrypt\", \"Encrypt the backup (AES-256-GCM)\")\n .option(\"--remote <url>\", \"Also upload to remote (s3://, rsync://, or path)\")\n .action((output?: string, opts?: { encrypt?: boolean; remote?: string }) => {\n void runBackup(output, process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd(), opts ?? {});\n });\n\nbackupCommand.addCommand(scheduleSubCommand);\nbackupCommand.addCommand(verifySubCommand);\nbackupCommand.addCommand(drillSubCommand);\nbackupCommand.addCommand(listSubCommand);\n\nexport const restoreCommand = new Command(\"restore\")\n .argument(\"<path>\", \"Path to backup zip\")\n .description(\"Restore from backup zip\")\n .action((zipPath: string) => runRestore(zipPath, process.env[\"DXCRM_DATA_DIR\"] ?? process.cwd()));\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { u as runScheduledBackupIfDue } from "./backup-CTlIxUdO.js";
2
+ export { runScheduledBackupIfDue };
@@ -0,0 +1,32 @@
1
+ //#region src/core/chunk.ts
2
+ /**
3
+ * Split long text into overlapping chunks for embedding/indexing. Each chunk is
4
+ * at most `maxChars`; chunks overlap by `overlap` characters so a query that
5
+ * straddles a boundary still matches. Splits prefer the nearest whitespace
6
+ * before the limit to avoid cutting words mid-token. Short text returns a single
7
+ * trimmed chunk; empty/whitespace-only text returns no chunks.
8
+ */
9
+ function chunkText(text, options = {}) {
10
+ const maxChars = options.maxChars ?? 1500;
11
+ const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));
12
+ const trimmed = text.trim();
13
+ if (!trimmed) return [];
14
+ if (trimmed.length <= maxChars) return [trimmed];
15
+ const chunks = [];
16
+ let start = 0;
17
+ while (start < trimmed.length) {
18
+ let end = Math.min(start + maxChars, trimmed.length);
19
+ if (end < trimmed.length) {
20
+ const lastSpace = trimmed.lastIndexOf(" ", end);
21
+ if (lastSpace > start + maxChars / 2) end = lastSpace;
22
+ }
23
+ chunks.push(trimmed.slice(start, end).trim());
24
+ if (end >= trimmed.length) break;
25
+ start = end - overlap;
26
+ }
27
+ return chunks.filter((c) => c.length > 0);
28
+ }
29
+ //#endregion
30
+ exports.chunkText = chunkText;
31
+
32
+ //# sourceMappingURL=chunk-BfDYWZQ8.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-BfDYWZQ8.cjs","names":[],"sources":["../src/core/chunk.ts"],"sourcesContent":["// src/core/chunk.ts\n\nexport interface ChunkOptions {\n /** Target maximum characters per chunk. */\n maxChars?: number;\n /** Characters of overlap carried from the end of one chunk into the next. */\n overlap?: number;\n}\n\n/**\n * Split long text into overlapping chunks for embedding/indexing. Each chunk is\n * at most `maxChars`; chunks overlap by `overlap` characters so a query that\n * straddles a boundary still matches. Splits prefer the nearest whitespace\n * before the limit to avoid cutting words mid-token. Short text returns a single\n * trimmed chunk; empty/whitespace-only text returns no chunks.\n */\nexport function chunkText(text: string, options: ChunkOptions = {}): string[] {\n const maxChars = options.maxChars ?? 1500;\n const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));\n const trimmed = text.trim();\n if (!trimmed) return [];\n if (trimmed.length <= maxChars) return [trimmed];\n\n const chunks: string[] = [];\n let start = 0;\n while (start < trimmed.length) {\n let end = Math.min(start + maxChars, trimmed.length);\n // Prefer breaking on whitespace, but only if it doesn't shrink the chunk too much.\n if (end < trimmed.length) {\n const lastSpace = trimmed.lastIndexOf(\" \", end);\n if (lastSpace > start + maxChars / 2) end = lastSpace;\n }\n chunks.push(trimmed.slice(start, end).trim());\n if (end >= trimmed.length) break;\n start = end - overlap;\n }\n return chunks.filter((c) => c.length > 0);\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,UAAU,MAAc,UAAwB,CAAC,GAAa;CAC5E,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,UAAU,KAAK,IAAI,QAAQ,WAAW,KAAK,KAAK,MAAM,WAAW,CAAC,CAAC;CACzE,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAI,CAAC,SAAS,OAAO,CAAC;CACtB,IAAI,QAAQ,UAAU,UAAU,OAAO,CAAC,OAAO;CAE/C,MAAM,SAAmB,CAAC;CAC1B,IAAI,QAAQ;CACZ,OAAO,QAAQ,QAAQ,QAAQ;EAC7B,IAAI,MAAM,KAAK,IAAI,QAAQ,UAAU,QAAQ,MAAM;EAEnD,IAAI,MAAM,QAAQ,QAAQ;GACxB,MAAM,YAAY,QAAQ,YAAY,KAAK,GAAG;GAC9C,IAAI,YAAY,QAAQ,WAAW,GAAG,MAAM;EAC9C;EACA,OAAO,KAAK,QAAQ,MAAM,OAAO,GAAG,EAAE,KAAK,CAAC;EAC5C,IAAI,OAAO,QAAQ,QAAQ;EAC3B,QAAQ,MAAM;CAChB;CACA,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,CAAC;AAC1C"}
@@ -0,0 +1,32 @@
1
+ //#region src/core/chunk.ts
2
+ /**
3
+ * Split long text into overlapping chunks for embedding/indexing. Each chunk is
4
+ * at most `maxChars`; chunks overlap by `overlap` characters so a query that
5
+ * straddles a boundary still matches. Splits prefer the nearest whitespace
6
+ * before the limit to avoid cutting words mid-token. Short text returns a single
7
+ * trimmed chunk; empty/whitespace-only text returns no chunks.
8
+ */
9
+ function chunkText(text, options = {}) {
10
+ const maxChars = options.maxChars ?? 1500;
11
+ const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));
12
+ const trimmed = text.trim();
13
+ if (!trimmed) return [];
14
+ if (trimmed.length <= maxChars) return [trimmed];
15
+ const chunks = [];
16
+ let start = 0;
17
+ while (start < trimmed.length) {
18
+ let end = Math.min(start + maxChars, trimmed.length);
19
+ if (end < trimmed.length) {
20
+ const lastSpace = trimmed.lastIndexOf(" ", end);
21
+ if (lastSpace > start + maxChars / 2) end = lastSpace;
22
+ }
23
+ chunks.push(trimmed.slice(start, end).trim());
24
+ if (end >= trimmed.length) break;
25
+ start = end - overlap;
26
+ }
27
+ return chunks.filter((c) => c.length > 0);
28
+ }
29
+ //#endregion
30
+ export { chunkText as t };
31
+
32
+ //# sourceMappingURL=chunk-BhUZmQg5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-BhUZmQg5.js","names":[],"sources":["../src/core/chunk.ts"],"sourcesContent":["// src/core/chunk.ts\n\nexport interface ChunkOptions {\n /** Target maximum characters per chunk. */\n maxChars?: number;\n /** Characters of overlap carried from the end of one chunk into the next. */\n overlap?: number;\n}\n\n/**\n * Split long text into overlapping chunks for embedding/indexing. Each chunk is\n * at most `maxChars`; chunks overlap by `overlap` characters so a query that\n * straddles a boundary still matches. Splits prefer the nearest whitespace\n * before the limit to avoid cutting words mid-token. Short text returns a single\n * trimmed chunk; empty/whitespace-only text returns no chunks.\n */\nexport function chunkText(text: string, options: ChunkOptions = {}): string[] {\n const maxChars = options.maxChars ?? 1500;\n const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));\n const trimmed = text.trim();\n if (!trimmed) return [];\n if (trimmed.length <= maxChars) return [trimmed];\n\n const chunks: string[] = [];\n let start = 0;\n while (start < trimmed.length) {\n let end = Math.min(start + maxChars, trimmed.length);\n // Prefer breaking on whitespace, but only if it doesn't shrink the chunk too much.\n if (end < trimmed.length) {\n const lastSpace = trimmed.lastIndexOf(\" \", end);\n if (lastSpace > start + maxChars / 2) end = lastSpace;\n }\n chunks.push(trimmed.slice(start, end).trim());\n if (end >= trimmed.length) break;\n start = end - overlap;\n }\n return chunks.filter((c) => c.length > 0);\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,UAAU,MAAc,UAAwB,CAAC,GAAa;CAC5E,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,UAAU,KAAK,IAAI,QAAQ,WAAW,KAAK,KAAK,MAAM,WAAW,CAAC,CAAC;CACzE,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAI,CAAC,SAAS,OAAO,CAAC;CACtB,IAAI,QAAQ,UAAU,UAAU,OAAO,CAAC,OAAO;CAE/C,MAAM,SAAmB,CAAC;CAC1B,IAAI,QAAQ;CACZ,OAAO,QAAQ,QAAQ,QAAQ;EAC7B,IAAI,MAAM,KAAK,IAAI,QAAQ,UAAU,QAAQ,MAAM;EAEnD,IAAI,MAAM,QAAQ,QAAQ;GACxB,MAAM,YAAY,QAAQ,YAAY,KAAK,GAAG;GAC9C,IAAI,YAAY,QAAQ,WAAW,GAAG,MAAM;EAC9C;EACA,OAAO,KAAK,QAAQ,MAAM,OAAO,GAAG,EAAE,KAAK,CAAC;EAC5C,IAAI,OAAO,QAAQ,QAAQ;EAC3B,QAAQ,MAAM;CAChB;CACA,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,CAAC;AAC1C"}
@@ -0,0 +1,2 @@
1
+ import { t as chunkText } from "./chunk-BhUZmQg5.js";
2
+ export { chunkText };
@@ -0,0 +1,32 @@
1
+ //#region src/core/chunk.ts
2
+ /**
3
+ * Split long text into overlapping chunks for embedding/indexing. Each chunk is
4
+ * at most `maxChars`; chunks overlap by `overlap` characters so a query that
5
+ * straddles a boundary still matches. Splits prefer the nearest whitespace
6
+ * before the limit to avoid cutting words mid-token. Short text returns a single
7
+ * trimmed chunk; empty/whitespace-only text returns no chunks.
8
+ */
9
+ function chunkText(text, options = {}) {
10
+ const maxChars = options.maxChars ?? 1500;
11
+ const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));
12
+ const trimmed = text.trim();
13
+ if (!trimmed) return [];
14
+ if (trimmed.length <= maxChars) return [trimmed];
15
+ const chunks = [];
16
+ let start = 0;
17
+ while (start < trimmed.length) {
18
+ let end = Math.min(start + maxChars, trimmed.length);
19
+ if (end < trimmed.length) {
20
+ const lastSpace = trimmed.lastIndexOf(" ", end);
21
+ if (lastSpace > start + maxChars / 2) end = lastSpace;
22
+ }
23
+ chunks.push(trimmed.slice(start, end).trim());
24
+ if (end >= trimmed.length) break;
25
+ start = end - overlap;
26
+ }
27
+ return chunks.filter((c) => c.length > 0);
28
+ }
29
+ //#endregion
30
+ export { chunkText };
31
+
32
+ //# sourceMappingURL=chunk-e_w8qqtP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-e_w8qqtP.js","names":[],"sources":["../src/core/chunk.ts"],"sourcesContent":["// src/core/chunk.ts\n\nexport interface ChunkOptions {\n /** Target maximum characters per chunk. */\n maxChars?: number;\n /** Characters of overlap carried from the end of one chunk into the next. */\n overlap?: number;\n}\n\n/**\n * Split long text into overlapping chunks for embedding/indexing. Each chunk is\n * at most `maxChars`; chunks overlap by `overlap` characters so a query that\n * straddles a boundary still matches. Splits prefer the nearest whitespace\n * before the limit to avoid cutting words mid-token. Short text returns a single\n * trimmed chunk; empty/whitespace-only text returns no chunks.\n */\nexport function chunkText(text: string, options: ChunkOptions = {}): string[] {\n const maxChars = options.maxChars ?? 1500;\n const overlap = Math.min(options.overlap ?? 150, Math.floor(maxChars / 2));\n const trimmed = text.trim();\n if (!trimmed) return [];\n if (trimmed.length <= maxChars) return [trimmed];\n\n const chunks: string[] = [];\n let start = 0;\n while (start < trimmed.length) {\n let end = Math.min(start + maxChars, trimmed.length);\n // Prefer breaking on whitespace, but only if it doesn't shrink the chunk too much.\n if (end < trimmed.length) {\n const lastSpace = trimmed.lastIndexOf(\" \", end);\n if (lastSpace > start + maxChars / 2) end = lastSpace;\n }\n chunks.push(trimmed.slice(start, end).trim());\n if (end >= trimmed.length) break;\n start = end - overlap;\n }\n return chunks.filter((c) => c.length > 0);\n}\n"],"mappings":";;;;;;;;AAgBA,SAAgB,UAAU,MAAc,UAAwB,CAAC,GAAa;CAC5E,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,UAAU,KAAK,IAAI,QAAQ,WAAW,KAAK,KAAK,MAAM,WAAW,CAAC,CAAC;CACzE,MAAM,UAAU,KAAK,KAAK;CAC1B,IAAI,CAAC,SAAS,OAAO,CAAC;CACtB,IAAI,QAAQ,UAAU,UAAU,OAAO,CAAC,OAAO;CAE/C,MAAM,SAAmB,CAAC;CAC1B,IAAI,QAAQ;CACZ,OAAO,QAAQ,QAAQ,QAAQ;EAC7B,IAAI,MAAM,KAAK,IAAI,QAAQ,UAAU,QAAQ,MAAM;EAEnD,IAAI,MAAM,QAAQ,QAAQ;GACxB,MAAM,YAAY,QAAQ,YAAY,KAAK,GAAG;GAC9C,IAAI,YAAY,QAAQ,WAAW,GAAG,MAAM;EAC9C;EACA,OAAO,KAAK,QAAQ,MAAM,OAAO,GAAG,EAAE,KAAK,CAAC;EAC5C,IAAI,OAAO,QAAQ,QAAQ;EAC3B,QAAQ,MAAM;CAChB;CACA,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,CAAC;AAC1C"}
@@ -1,5 +1,5 @@
1
- import { r as listCustomerSlugs } from "./customer-dir-DIylZ8Q6.js";
2
- import { t as computeCustomerHealth } from "./relationship-health-odxEoQdJ.js";
1
+ import { i as listCustomerSlugs } from "./customer-dir-CkMMXhb0.js";
2
+ import { t as computeCustomerHealth } from "./relationship-health-ZZNXR1RZ.js";
3
3
  //#region src/core/churn.ts
4
4
  function levelFromScore(score) {
5
5
  if (score >= 60) return "high";
@@ -51,4 +51,4 @@ function scanChurn(dataDir, today = (/* @__PURE__ */ new Date()).toISOString().s
51
51
  //#endregion
52
52
  export { assessChurn, scanChurn };
53
53
 
54
- //# sourceMappingURL=churn-C28IgnAj.js.map
54
+ //# sourceMappingURL=churn-DN9WDGNM.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"churn-C28IgnAj.js","names":[],"sources":["../src/core/churn.ts"],"sourcesContent":["import { computeCustomerHealth } from \"./relationship-health.js\";\nimport { listCustomerSlugs } from \"../fs/customer-dir.js\";\n\n/**\n * Churn early-warning (domino D13 / C4): turns the per-contact relationship\n * health signals (recency, cadence, momentum, champion-silence) into an\n * account-level churn-risk read with plain-language signals, so the agent can\n * surface at-risk customers before they quietly lapse. Builds on the D5-clean\n * data and the existing relationship-health engine — no new data required.\n */\nexport type ChurnLevel = \"low\" | \"medium\" | \"high\";\n\nexport interface ChurnAssessment {\n slug: string;\n riskScore: number; // 0–100, higher = more likely to churn\n level: ChurnLevel;\n signals: string[];\n}\n\nfunction levelFromScore(score: number): ChurnLevel {\n if (score >= 60) return \"high\";\n if (score >= 30) return \"medium\";\n return \"low\";\n}\n\n/**\n * Assess one customer's churn risk. Risk is the inverse of relationship health,\n * amplified by explicit risk flags (no-contact windows, silent champions) and\n * declining/cold trends across the customer's contacts.\n */\nexport function assessChurn(\n dataDir: string,\n slug: string,\n today: string = new Date().toISOString().slice(0, 10)\n): ChurnAssessment {\n const health = computeCustomerHealth(dataDir, slug, today);\n const signals: string[] = [];\n\n // Base risk is the inverse of overall relationship health.\n let risk = 100 - health.overallHealth;\n\n if (health.contacts.length === 0) {\n signals.push(\"No logged interactions — relationship never established\");\n risk = Math.max(risk, 65);\n }\n\n const flagged = new Set<string>();\n for (const c of health.contacts) {\n for (const f of c.riskFlags) flagged.add(f);\n if (c.trend === \"cold\") signals.push(`${c.name} has gone cold (${c.daysSinceContact}d silent)`);\n else if (c.trend === \"declining\") signals.push(`${c.name}'s engagement is declining`);\n }\n\n if (flagged.has(\"NO_CONTACT_30D\")) {\n signals.push(\"A key contact has had no contact in 30+ days\");\n risk += 15;\n } else if (flagged.has(\"NO_CONTACT_14D\")) {\n signals.push(\"A key contact has had no contact in 14+ days\");\n risk += 5;\n }\n if (flagged.has(\"CHAMPION_SILENT\")) {\n signals.push(\"Champion has gone silent — high-leverage risk\");\n risk += 20;\n }\n\n const riskScore = Math.max(0, Math.min(100, Math.round(risk)));\n return { slug, riskScore, level: levelFromScore(riskScore), signals };\n}\n\n/** Assess every customer and return them ranked by churn risk (highest first). */\nexport function scanChurn(\n dataDir: string,\n today: string = new Date().toISOString().slice(0, 10)\n): ChurnAssessment[] {\n return listCustomerSlugs(dataDir)\n .map((slug) => assessChurn(dataDir, slug, today))\n .sort((a, b) => b.riskScore - a.riskScore);\n}\n"],"mappings":";;;AAmBA,SAAS,eAAe,OAA2B;CACjD,IAAI,SAAS,IAAI,OAAO;CACxB,IAAI,SAAS,IAAI,OAAO;CACxB,OAAO;AACT;;;;;;AAOA,SAAgB,YACd,SACA,MACA,yBAAgB,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,GACnC;CACjB,MAAM,SAAS,sBAAsB,SAAS,MAAM,KAAK;CACzD,MAAM,UAAoB,CAAC;CAG3B,IAAI,OAAO,MAAM,OAAO;CAExB,IAAI,OAAO,SAAS,WAAW,GAAG;EAChC,QAAQ,KAAK,yDAAyD;EACtE,OAAO,KAAK,IAAI,MAAM,EAAE;CAC1B;CAEA,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,KAAK,OAAO,UAAU;EAC/B,KAAK,MAAM,KAAK,EAAE,WAAW,QAAQ,IAAI,CAAC;EAC1C,IAAI,EAAE,UAAU,QAAQ,QAAQ,KAAK,GAAG,EAAE,KAAK,kBAAkB,EAAE,iBAAiB,UAAU;OACzF,IAAI,EAAE,UAAU,aAAa,QAAQ,KAAK,GAAG,EAAE,KAAK,2BAA2B;CACtF;CAEA,IAAI,QAAQ,IAAI,gBAAgB,GAAG;EACjC,QAAQ,KAAK,8CAA8C;EAC3D,QAAQ;CACV,OAAO,IAAI,QAAQ,IAAI,gBAAgB,GAAG;EACxC,QAAQ,KAAK,8CAA8C;EAC3D,QAAQ;CACV;CACA,IAAI,QAAQ,IAAI,iBAAiB,GAAG;EAClC,QAAQ,KAAK,+CAA+C;EAC5D,QAAQ;CACV;CAEA,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;CAC7D,OAAO;EAAE;EAAM;EAAW,OAAO,eAAe,SAAS;EAAG;CAAQ;AACtE;;AAGA,SAAgB,UACd,SACA,yBAAgB,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,GACjC;CACnB,OAAO,kBAAkB,OAAO,EAC7B,KAAK,SAAS,YAAY,SAAS,MAAM,KAAK,CAAC,EAC/C,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAC7C"}
1
+ {"version":3,"file":"churn-DN9WDGNM.js","names":[],"sources":["../src/core/churn.ts"],"sourcesContent":["import { computeCustomerHealth } from \"./relationship-health.js\";\nimport { listCustomerSlugs } from \"../fs/customer-dir.js\";\n\n/**\n * Churn early-warning (domino D13 / C4): turns the per-contact relationship\n * health signals (recency, cadence, momentum, champion-silence) into an\n * account-level churn-risk read with plain-language signals, so the agent can\n * surface at-risk customers before they quietly lapse. Builds on the D5-clean\n * data and the existing relationship-health engine — no new data required.\n */\nexport type ChurnLevel = \"low\" | \"medium\" | \"high\";\n\nexport interface ChurnAssessment {\n slug: string;\n riskScore: number; // 0–100, higher = more likely to churn\n level: ChurnLevel;\n signals: string[];\n}\n\nfunction levelFromScore(score: number): ChurnLevel {\n if (score >= 60) return \"high\";\n if (score >= 30) return \"medium\";\n return \"low\";\n}\n\n/**\n * Assess one customer's churn risk. Risk is the inverse of relationship health,\n * amplified by explicit risk flags (no-contact windows, silent champions) and\n * declining/cold trends across the customer's contacts.\n */\nexport function assessChurn(\n dataDir: string,\n slug: string,\n today: string = new Date().toISOString().slice(0, 10)\n): ChurnAssessment {\n const health = computeCustomerHealth(dataDir, slug, today);\n const signals: string[] = [];\n\n // Base risk is the inverse of overall relationship health.\n let risk = 100 - health.overallHealth;\n\n if (health.contacts.length === 0) {\n signals.push(\"No logged interactions — relationship never established\");\n risk = Math.max(risk, 65);\n }\n\n const flagged = new Set<string>();\n for (const c of health.contacts) {\n for (const f of c.riskFlags) flagged.add(f);\n if (c.trend === \"cold\") signals.push(`${c.name} has gone cold (${c.daysSinceContact}d silent)`);\n else if (c.trend === \"declining\") signals.push(`${c.name}'s engagement is declining`);\n }\n\n if (flagged.has(\"NO_CONTACT_30D\")) {\n signals.push(\"A key contact has had no contact in 30+ days\");\n risk += 15;\n } else if (flagged.has(\"NO_CONTACT_14D\")) {\n signals.push(\"A key contact has had no contact in 14+ days\");\n risk += 5;\n }\n if (flagged.has(\"CHAMPION_SILENT\")) {\n signals.push(\"Champion has gone silent — high-leverage risk\");\n risk += 20;\n }\n\n const riskScore = Math.max(0, Math.min(100, Math.round(risk)));\n return { slug, riskScore, level: levelFromScore(riskScore), signals };\n}\n\n/** Assess every customer and return them ranked by churn risk (highest first). */\nexport function scanChurn(\n dataDir: string,\n today: string = new Date().toISOString().slice(0, 10)\n): ChurnAssessment[] {\n return listCustomerSlugs(dataDir)\n .map((slug) => assessChurn(dataDir, slug, today))\n .sort((a, b) => b.riskScore - a.riskScore);\n}\n"],"mappings":";;;AAmBA,SAAS,eAAe,OAA2B;CACjD,IAAI,SAAS,IAAI,OAAO;CACxB,IAAI,SAAS,IAAI,OAAO;CACxB,OAAO;AACT;;;;;;AAOA,SAAgB,YACd,SACA,MACA,yBAAgB,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,GACnC;CACjB,MAAM,SAAS,sBAAsB,SAAS,MAAM,KAAK;CACzD,MAAM,UAAoB,CAAC;CAG3B,IAAI,OAAO,MAAM,OAAO;CAExB,IAAI,OAAO,SAAS,WAAW,GAAG;EAChC,QAAQ,KAAK,yDAAyD;EACtE,OAAO,KAAK,IAAI,MAAM,EAAE;CAC1B;CAEA,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,KAAK,OAAO,UAAU;EAC/B,KAAK,MAAM,KAAK,EAAE,WAAW,QAAQ,IAAI,CAAC;EAC1C,IAAI,EAAE,UAAU,QAAQ,QAAQ,KAAK,GAAG,EAAE,KAAK,kBAAkB,EAAE,iBAAiB,UAAU;OACzF,IAAI,EAAE,UAAU,aAAa,QAAQ,KAAK,GAAG,EAAE,KAAK,2BAA2B;CACtF;CAEA,IAAI,QAAQ,IAAI,gBAAgB,GAAG;EACjC,QAAQ,KAAK,8CAA8C;EAC3D,QAAQ;CACV,OAAO,IAAI,QAAQ,IAAI,gBAAgB,GAAG;EACxC,QAAQ,KAAK,8CAA8C;EAC3D,QAAQ;CACV;CACA,IAAI,QAAQ,IAAI,iBAAiB,GAAG;EAClC,QAAQ,KAAK,+CAA+C;EAC5D,QAAQ;CACV;CAEA,MAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;CAC7D,OAAO;EAAE;EAAM;EAAW,OAAO,eAAe,SAAS;EAAG;CAAQ;AACtE;;AAGA,SAAgB,UACd,SACA,yBAAgB,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,GACjC;CACnB,OAAO,kBAAkB,OAAO,EAC7B,KAAK,SAAS,YAAY,SAAS,MAAM,KAAK,CAAC,EAC/C,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAC7C"}