@datasynx/agentic-crm 1.7.0 → 1.9.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 (44) hide show
  1. package/dist/cli.js +101 -8
  2. package/dist/cli.js.map +1 -1
  3. package/dist/daemon/worker.js +3 -3
  4. package/dist/funnel-B2mwpZE1.js +89 -0
  5. package/dist/funnel-B2mwpZE1.js.map +1 -0
  6. package/dist/funnel-CJ7fy7hG.js +2 -0
  7. package/dist/{index-DcDaz_cu.d.cts → index-BAutNcAT.d.cts} +11 -11
  8. package/dist/index-BAutNcAT.d.cts.map +1 -0
  9. package/dist/index.d.cts +11 -11
  10. package/dist/index.d.cts.map +1 -1
  11. package/dist/{knowledge-base-Cc0niBFf.js → knowledge-base-yo-BLUcB.js} +3 -1
  12. package/dist/knowledge-base-yo-BLUcB.js.map +1 -0
  13. package/dist/{login-yt9OOQQk.js → login-dc_Hqosw.js} +2 -2
  14. package/dist/{login-yt9OOQQk.js.map → login-dc_Hqosw.js.map} +1 -1
  15. package/dist/mailbox-config-BU3vib2T.js +2 -0
  16. package/dist/{mailbox-config-Dn2xTn9N.js → mailbox-config-trjLPHPG.js} +2 -2
  17. package/dist/{mailbox-config-Dn2xTn9N.js.map → mailbox-config-trjLPHPG.js.map} +1 -1
  18. package/dist/{mailbox-poll-B8dvFAXT.js → mailbox-poll-Ban7C3X0.js} +3 -3
  19. package/dist/{mailbox-poll-B8dvFAXT.js.map → mailbox-poll-Ban7C3X0.js.map} +1 -1
  20. package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
  21. package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
  22. package/dist/mcp.cjs +415 -137
  23. package/dist/mcp.cjs.map +1 -1
  24. package/dist/mcp.d.cts.map +1 -1
  25. package/dist/mcp.d.ts.map +1 -1
  26. package/dist/mcp.js +415 -137
  27. package/dist/mcp.js.map +1 -1
  28. package/dist/{server-BbInMUgp.js → server-DAcwmRPE.js} +195 -133
  29. package/dist/server-DAcwmRPE.js.map +1 -0
  30. package/dist/{token-resolver-D98qPOOf.js → token-resolver-CL8-CSgZ.js} +2 -2
  31. package/dist/{token-resolver-D98qPOOf.js.map → token-resolver-CL8-CSgZ.js.map} +1 -1
  32. package/dist/{token-store-B0h0USqe.js → token-store-BPDwePNT.js} +13 -2
  33. package/dist/token-store-BPDwePNT.js.map +1 -0
  34. package/dist/token-store-D3HCeXmE.js +2 -0
  35. package/dist/velocity-BtX1l5Gh.js +2 -0
  36. package/dist/velocity-C2l4cW0K.js +123 -0
  37. package/dist/velocity-C2l4cW0K.js.map +1 -0
  38. package/package.json +1 -1
  39. package/dist/index-DcDaz_cu.d.cts.map +0 -1
  40. package/dist/knowledge-base-Cc0niBFf.js.map +0 -1
  41. package/dist/mailbox-config-Bu-J1O4I.js +0 -2
  42. package/dist/server-BbInMUgp.js.map +0 -1
  43. package/dist/token-store-B0h0USqe.js.map +0 -1
  44. package/dist/token-store-CEmz8d-0.js +0 -2
@@ -2,7 +2,7 @@ import { a as readMainFacts, i as listCustomerSlugs, n as customerExists, o as w
2
2
  import { t as writeFileAtomic } from "./atomic-write-8yjqqLtS.js";
3
3
  import { i as writeJsonFile } from "./json-store-WWsFzXub.js";
4
4
  import { n as getSession } from "./session-store-CEa39Dxs.js";
5
- import { a as searchKbSimple, n as getKbArticle, o as writeKbArticle, r as getKbMetaForExport, s as CAPABILITIES_TEXT } from "./knowledge-base-Cc0niBFf.js";
5
+ import { a as searchKbSimple, n as getKbArticle, o as writeKbArticle, r as getKbMetaForExport, s as CAPABILITIES_TEXT } from "./knowledge-base-yo-BLUcB.js";
6
6
  import { i as readBackupLog, n as listBackupsInDir, o as runBackup } from "./backup-CTlIxUdO.js";
7
7
  import { r as updateSlugSyncState, t as getLastGmailSync } from "./sync-state-DMZgzpez.js";
8
8
  import { t as withFileQueue } from "./write-queue-IbsAjUnh.js";
@@ -24,9 +24,11 @@ import { i as getSurvey, l as savePendingSurvey, n as calcNpsScore, o as loadSur
24
24
  import { t as buildContext } from "./context-builder-7Uab5-G4.js";
25
25
  import { a as loadCustomObjects, i as listRecords, n as defineCustomObject, t as createRecord } from "./custom-objects-CxW1gHwJ.js";
26
26
  import { n as runDiagnostics } from "./doctor-BFeelnq8.js";
27
+ import { n as diffAgainstNow } from "./snapshots-CQSOaIMs.js";
28
+ import { t as analyzeFunnel } from "./funnel-B2mwpZE1.js";
27
29
  import { r as searchKnowledge } from "./lancedb-CuHKNsNZ.js";
28
30
  import { t as buildDailyBriefing } from "./proactive-agent-B7u3Bj_l.js";
29
- import { n as diffAgainstNow } from "./snapshots-CQSOaIMs.js";
31
+ import { t as analyzeVelocity } from "./velocity-C2l4cW0K.js";
30
32
  import { a as protectedResourceMetadata, o as verifyBearer, r as isAuthRequired, s as wwwAuthenticateHeader } from "./auth-DDXZTwS0.js";
31
33
  import { i as verifyGmailPubSubSignature, n as decodeGmailPubSubPayload, r as handleGmailPushEvent } from "./gmail-webhook-handler-BzOFbvgh.js";
32
34
  import { n as registerUpdateDeal } from "./update-deal-DSzr_Aau.js";
@@ -256,7 +258,7 @@ function registerGetActiveSession(server) {
256
258
  }
257
259
  //#endregion
258
260
  //#region src/mcp/tools/get-customer-context.ts
259
- const DATA_DIR$53 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
261
+ const DATA_DIR$55 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
260
262
  function triggerOnQuerySync(dataDir, slug) {
261
263
  const auth = getGmailAuth();
262
264
  if (!auth) return;
@@ -277,7 +279,7 @@ function triggerOnQuerySync(dataDir, slug) {
277
279
  }).then(() => updateSlugSyncState(dataDir, slug, { lastGmailSync: (/* @__PURE__ */ new Date()).toISOString() })).catch(() => {})).catch(() => {});
278
280
  } catch {}
279
281
  }
280
- async function handleGetCustomerContext(input, dataDir = DATA_DIR$53) {
282
+ async function handleGetCustomerContext(input, dataDir = DATA_DIR$55) {
281
283
  const targetSlug = input.slug ?? getSession()?.customerSlug;
282
284
  if (!targetSlug) return {
283
285
  content: [{
@@ -329,8 +331,8 @@ Performance: <3 seconds. Token budget: <3000.`,
329
331
  }
330
332
  //#endregion
331
333
  //#region src/mcp/tools/search-customer-knowledge.ts
332
- const DATA_DIR$52 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
333
- async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$52) {
334
+ const DATA_DIR$54 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
335
+ async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$54) {
334
336
  const limit = input.limit ?? 5;
335
337
  try {
336
338
  const results = await searchKnowledge(dataDir, input.slug, input.query, limit);
@@ -378,14 +380,14 @@ If no results: returns empty array with a helpful sync suggestion.`,
378
380
  }
379
381
  //#endregion
380
382
  //#region src/mcp/tools/list-customers.ts
381
- const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
383
+ const DATA_DIR$53 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
382
384
  function extractLastInteractionDate(interactionsPath) {
383
385
  if (!fs.existsSync(interactionsPath)) return void 0;
384
386
  const content = fs.readFileSync(interactionsPath, "utf-8");
385
387
  const match = /^## (\d{4}-\d{2}-\d{2})/m.exec(content);
386
388
  return match ? match[1] : void 0;
387
389
  }
388
- async function handleListCustomers(input, dataDir = DATA_DIR$51) {
390
+ async function handleListCustomers(input, dataDir = DATA_DIR$53) {
389
391
  const customersDir = path.join(dataDir, "customers");
390
392
  const customers = [];
391
393
  if (!fs.existsSync(customersDir)) return { content: [{
@@ -446,8 +448,8 @@ Returns: Array of { slug, name, stage, lastInteraction?, dealValue? }`,
446
448
  }
447
449
  //#endregion
448
450
  //#region src/mcp/tools/log-interaction.ts
449
- const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
450
- async function handleLogInteraction(input, dataDir = DATA_DIR$50) {
451
+ const DATA_DIR$52 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
452
+ async function handleLogInteraction(input, dataDir = DATA_DIR$52) {
451
453
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
452
454
  const interactionDate = input.date ?? today;
453
455
  const sourceRef = input.source ?? `agent://log/${Date.now()}`;
@@ -552,12 +554,12 @@ Returns: { success: boolean, path: string, entry: string }`,
552
554
  }
553
555
  //#endregion
554
556
  //#region src/mcp/tools/export-customer.ts
555
- const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
557
+ const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
556
558
  function countInteractions(content) {
557
559
  const matches = content.match(/^## \d{4}-\d{2}-\d{2}/gm);
558
560
  return matches ? matches.length : 0;
559
561
  }
560
- async function handleExportCustomer(input, dataDir = DATA_DIR$49) {
562
+ async function handleExportCustomer(input, dataDir = DATA_DIR$51) {
561
563
  enforceRbac(dataDir, "export_customer");
562
564
  const customerDir = path.join(dataDir, "customers", input.slug);
563
565
  if (!fs.existsSync(customerDir)) return {
@@ -670,8 +672,8 @@ Returns:
670
672
  }
671
673
  //#endregion
672
674
  //#region src/mcp/tools/update-customer-facts.ts
673
- const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
674
- async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$48) {
675
+ const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
676
+ async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$50) {
675
677
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
676
678
  try {
677
679
  enforceRbac(dataDir, "update_customer_facts");
@@ -849,8 +851,8 @@ function scoreDealForToday(deal, todayDate) {
849
851
  }
850
852
  //#endregion
851
853
  //#region src/mcp/tools/get-deal-health.ts
852
- const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
853
- async function handleGetDealHealth(input, dataDir = DATA_DIR$47) {
854
+ const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
855
+ async function handleGetDealHealth(input, dataDir = DATA_DIR$49) {
854
856
  try {
855
857
  const deals = await readPipeline(dataDir, input.slug);
856
858
  const today = /* @__PURE__ */ new Date();
@@ -899,8 +901,8 @@ Returns: { slug, deals: [{ deal, stage, score, grade, signals, warnings }] }`,
899
901
  }
900
902
  //#endregion
901
903
  //#region src/mcp/tools/get-pipeline-forecast.ts
902
- const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
903
- async function handleGetPipelineForecast(input, dataDir = DATA_DIR$46) {
904
+ const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
905
+ async function handleGetPipelineForecast(input, dataDir = DATA_DIR$48) {
904
906
  try {
905
907
  const slugs = listCustomerSlugs(dataDir).filter((d) => !input.filter || d.includes(input.filter));
906
908
  const allDeals = [];
@@ -961,8 +963,8 @@ Returns: { deals: [...], totalWeightedValue: number, byStage: { stage: { count,
961
963
  }
962
964
  //#endregion
963
965
  //#region src/mcp/tools/summarize-meeting.ts
964
- const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
965
- async function handleSummarizeMeeting(input, dataDir = DATA_DIR$45) {
966
+ const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
967
+ async function handleSummarizeMeeting(input, dataDir = DATA_DIR$47) {
966
968
  try {
967
969
  let summary = input.transcript.slice(0, 400);
968
970
  let nextSteps = [];
@@ -1037,8 +1039,8 @@ Returns: { success, summary, nextSteps, sourceRef }`,
1037
1039
  }
1038
1040
  //#endregion
1039
1041
  //#region src/mcp/tools/get-pipeline-stages.ts
1040
- const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1041
- async function handleGetPipelineStages(_input, dataDir = DATA_DIR$44) {
1042
+ const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1043
+ async function handleGetPipelineStages(_input, dataDir = DATA_DIR$46) {
1042
1044
  const stages = getPipelineStages(dataDir);
1043
1045
  return { content: [{
1044
1046
  type: "text",
@@ -1066,8 +1068,8 @@ async function searchAcrossCustomers(dataDir, query, limit = 5, excludeSlug) {
1066
1068
  }
1067
1069
  //#endregion
1068
1070
  //#region src/mcp/tools/get-market-intelligence.ts
1069
- const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1070
- async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$43) {
1071
+ const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1072
+ async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$45) {
1071
1073
  const excludeSlug = input.excludeCurrentCustomer ? input.slug : void 0;
1072
1074
  const all = listCustomerSlugs(dataDir);
1073
1075
  const totalCustomersSearched = excludeSlug ? all.filter((s) => s !== excludeSlug).length : all.length;
@@ -1098,7 +1100,7 @@ function registerGetMarketIntelligence(server) {
1098
1100
  }
1099
1101
  //#endregion
1100
1102
  //#region src/mcp/tools/get-relationship-graph.ts
1101
- const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1103
+ const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1102
1104
  function summarizeNode(n) {
1103
1105
  return {
1104
1106
  id: n.id,
@@ -1106,7 +1108,7 @@ function summarizeNode(n) {
1106
1108
  email: n.properties["email"]
1107
1109
  };
1108
1110
  }
1109
- async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$42) {
1111
+ async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$44) {
1110
1112
  try {
1111
1113
  const graph = readGraph(dataDir, input.slug);
1112
1114
  const stakeholders = getStakeholders(graph);
@@ -1174,9 +1176,9 @@ Returns: {
1174
1176
  }
1175
1177
  //#endregion
1176
1178
  //#region src/mcp/tools/get-relationship-health.ts
1177
- const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1179
+ const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1178
1180
  const MAX_HEALTH_AGE_MS = 3600 * 1e3;
1179
- async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$41) {
1181
+ async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$43) {
1180
1182
  try {
1181
1183
  let health = readHealth(dataDir, input.slug);
1182
1184
  if (health === null || Date.now() - new Date(health.updatedAt).getTime() > MAX_HEALTH_AGE_MS) {
@@ -1845,8 +1847,8 @@ async function runDealAgent(config, dataDir, llmFn = callLlm) {
1845
1847
  }
1846
1848
  //#endregion
1847
1849
  //#region src/mcp/tools/run-deal-agent.ts
1848
- const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1849
- async function handleRunDealAgent(input, dataDir = DATA_DIR$40) {
1850
+ const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1851
+ async function handleRunDealAgent(input, dataDir = DATA_DIR$42) {
1850
1852
  try {
1851
1853
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1852
1854
  const result = await runDealAgent({
@@ -1913,8 +1915,8 @@ Returns: { assessment, riskLevel, plan[], actionsQueued[], actionsExecuted[], tr
1913
1915
  }
1914
1916
  //#endregion
1915
1917
  //#region src/mcp/tools/approve-agent-action.ts
1916
- const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1917
- async function handleApproveAgentAction(input, dataDir = DATA_DIR$39) {
1918
+ const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1919
+ async function handleApproveAgentAction(input, dataDir = DATA_DIR$41) {
1918
1920
  try {
1919
1921
  const queue = readAgentQueue(dataDir, input.slug);
1920
1922
  const idx = queue.pendingActions.findIndex((a) => a.actionId === input.actionId);
@@ -1991,8 +1993,8 @@ Returns: { success, actionId, status }`,
1991
1993
  }
1992
1994
  //#endregion
1993
1995
  //#region src/mcp/tools/simulate-revenue.ts
1994
- const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1995
- async function handleSimulateRevenue(input, dataDir = DATA_DIR$38) {
1996
+ const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
1997
+ async function handleSimulateRevenue(input, dataDir = DATA_DIR$40) {
1996
1998
  try {
1997
1999
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
1998
2000
  const horizon = input.horizon ?? "quarter";
@@ -2050,8 +2052,8 @@ Returns: { forecast: { p10, p50, p90, expected, stdDev, atRiskRevenue, byCloseMo
2050
2052
  }
2051
2053
  //#endregion
2052
2054
  //#region src/mcp/tools/get-playbook.ts
2053
- const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2054
- async function handleGetPlaybook(input, dataDir = DATA_DIR$37) {
2055
+ const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2056
+ async function handleGetPlaybook(input, dataDir = DATA_DIR$39) {
2055
2057
  try {
2056
2058
  const playbooks = listPlaybooks(dataDir, input.slug);
2057
2059
  if (!(input.stage !== void 0 || input.value !== void 0 || input.healthScore !== void 0)) return { content: [{
@@ -2136,12 +2138,12 @@ Returns: { matches: [{ name, score, trigger, successRate, usedCount, content }],
2136
2138
  ...healthScore !== void 0 ? { healthScore } : {},
2137
2139
  ...daysSinceContact !== void 0 ? { daysSinceContact } : {},
2138
2140
  ...championPresent !== void 0 ? { championPresent } : {}
2139
- }, DATA_DIR$37));
2141
+ }, DATA_DIR$39));
2140
2142
  }
2141
2143
  //#endregion
2142
2144
  //#region src/mcp/tools/create-playbook.ts
2143
- const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2144
- async function handleCreatePlaybook(input, dataDir = DATA_DIR$36) {
2145
+ const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2146
+ async function handleCreatePlaybook(input, dataDir = DATA_DIR$38) {
2145
2147
  try {
2146
2148
  const name = toKebabCase(input.name);
2147
2149
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -2214,12 +2216,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path } }`,
2214
2216
  trigger,
2215
2217
  content,
2216
2218
  ...successRate !== void 0 ? { successRate } : {}
2217
- }, DATA_DIR$36));
2219
+ }, DATA_DIR$38));
2218
2220
  }
2219
2221
  //#endregion
2220
2222
  //#region src/mcp/tools/list-playbooks.ts
2221
- const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2222
- async function handleListPlaybooks(input, dataDir = DATA_DIR$35) {
2223
+ const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2224
+ async function handleListPlaybooks(input, dataDir = DATA_DIR$37) {
2223
2225
  try {
2224
2226
  const playbooks = listPlaybooks(dataDir, input.slug);
2225
2227
  return { content: [{
@@ -2258,12 +2260,12 @@ Args:
2258
2260
 
2259
2261
  Returns: { playbooks: [{ name, trigger, successRate, usedCount, lastUpdated }], count, slug }`,
2260
2262
  inputSchema: z.object({ slug: z.string().describe("Customer ID") })
2261
- }, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$35));
2263
+ }, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$37));
2262
2264
  }
2263
2265
  //#endregion
2264
2266
  //#region src/mcp/tools/distill-playbook.ts
2265
- const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2266
- async function handleDistillPlaybook(input, dataDir = DATA_DIR$34, llmFn = callLlm) {
2267
+ const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2268
+ async function handleDistillPlaybook(input, dataDir = DATA_DIR$36, llmFn = callLlm) {
2267
2269
  try {
2268
2270
  const result = await distillPlaybook(dataDir, input.slug, input.dealName, input.outcome, llmFn);
2269
2271
  if (!result.ok) {
@@ -2322,12 +2324,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path }, reason
2322
2324
  slug,
2323
2325
  dealName,
2324
2326
  outcome
2325
- }, DATA_DIR$34));
2327
+ }, DATA_DIR$36));
2326
2328
  }
2327
2329
  //#endregion
2328
2330
  //#region src/mcp/tools/pursue-goal.ts
2329
- const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2330
- async function handlePursueGoal(input, dataDir = DATA_DIR$33, options = {}) {
2331
+ const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2332
+ async function handlePursueGoal(input, dataDir = DATA_DIR$35, options = {}) {
2331
2333
  try {
2332
2334
  enforceRbac(dataDir, "pursue_goal");
2333
2335
  const goal = await pursueGoal(dataDir, {
@@ -2390,12 +2392,12 @@ Returns: { goalId, description, target, deadline, decomposition: { analysis, cur
2390
2392
  goal,
2391
2393
  deadline,
2392
2394
  ...context !== void 0 ? { context } : {}
2393
- }, DATA_DIR$33));
2395
+ }, DATA_DIR$35));
2394
2396
  }
2395
2397
  //#endregion
2396
2398
  //#region src/mcp/tools/get-goal-status.ts
2397
- const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2398
- async function handleGetGoalStatus(input, dataDir = DATA_DIR$32) {
2399
+ const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2400
+ async function handleGetGoalStatus(input, dataDir = DATA_DIR$34) {
2399
2401
  try {
2400
2402
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2401
2403
  const allGoals = input.goalId ? readGoals(dataDir).filter((g) => g.id === input.goalId) : getActiveGoals(dataDir);
@@ -2454,17 +2456,17 @@ Args:
2454
2456
 
2455
2457
  Returns: { goals: [{ id, description, target, progress, status, deadline, daysRemaining, subGoals }], activeCount, completedCount }`,
2456
2458
  inputSchema: z.object({ goalId: z.string().optional().describe("Specific goal ID (omit for all active goals)") })
2457
- }, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$32));
2459
+ }, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$34));
2458
2460
  }
2459
2461
  //#endregion
2460
2462
  //#region src/mcp/tools/register-push-subscription.ts
2461
- const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2463
+ const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2462
2464
  const VALID_PROVIDERS = [
2463
2465
  "gmail",
2464
2466
  "microsoft-graph",
2465
2467
  "slack"
2466
2468
  ];
2467
- async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$31) {
2469
+ async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$33) {
2468
2470
  try {
2469
2471
  if (!VALID_PROVIDERS.includes(input.provider)) return { content: [{
2470
2472
  type: "text",
@@ -2550,12 +2552,12 @@ Returns: { subscriptionId, provider, slug, status, expiresAt, createdAt, warning
2550
2552
  ...microsoftResource !== void 0 ? { microsoftResource } : {},
2551
2553
  ...slackTeamId !== void 0 ? { slackTeamId } : {},
2552
2554
  ...slackChannelId !== void 0 ? { slackChannelId } : {}
2553
- }, DATA_DIR$31));
2555
+ }, DATA_DIR$33));
2554
2556
  }
2555
2557
  //#endregion
2556
2558
  //#region src/mcp/tools/get-push-status.ts
2557
- const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2558
- async function handleGetPushStatus(input, dataDir = DATA_DIR$30) {
2559
+ const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2560
+ async function handleGetPushStatus(input, dataDir = DATA_DIR$32) {
2559
2561
  try {
2560
2562
  let subs = await readSubscriptions(dataDir);
2561
2563
  if (input.slug) subs = subs.filter((s) => s.slug === input.slug);
@@ -2627,7 +2629,7 @@ Returns: { subscriptions: [{ id, provider, slug, status, expiresAt, expiresInHou
2627
2629
  }, async ({ slug, provider }) => handleGetPushStatus({
2628
2630
  ...slug !== void 0 ? { slug } : {},
2629
2631
  ...provider !== void 0 ? { provider } : {}
2630
- }, DATA_DIR$30));
2632
+ }, DATA_DIR$32));
2631
2633
  }
2632
2634
  //#endregion
2633
2635
  //#region src/core/org-intelligence.ts
@@ -2693,8 +2695,8 @@ function deriveRecommendation(people, missingRoles) {
2693
2695
  }
2694
2696
  //#endregion
2695
2697
  //#region src/mcp/tools/get-org-intelligence.ts
2696
- const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2697
- async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$29) {
2698
+ const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2699
+ async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$31) {
2698
2700
  try {
2699
2701
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2700
2702
  const map = buildStakeholderMap(dataDir, input.slug, today, input.dealName);
@@ -2827,8 +2829,8 @@ function buildExecutiveSummary(slug, dealName, stakeholders, overallHealth, sim,
2827
2829
  }
2828
2830
  //#endregion
2829
2831
  //#region src/mcp/tools/open-deal-room.ts
2830
- const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2831
- async function handleOpenDealRoom(input, dataDir = DATA_DIR$28) {
2832
+ const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2833
+ async function handleOpenDealRoom(input, dataDir = DATA_DIR$30) {
2832
2834
  try {
2833
2835
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2834
2836
  const brief = await buildDealRoom(dataDir, input.slug, input.dealName, today);
@@ -2863,8 +2865,8 @@ Returns: { slug, dealName, generatedAt, stakeholders, relationshipHealth, dealHe
2863
2865
  }
2864
2866
  //#endregion
2865
2867
  //#region src/mcp/tools/get-proactive-briefing.ts
2866
- const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2867
- async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$27) {
2868
+ const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2869
+ async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$29) {
2868
2870
  try {
2869
2871
  const briefing = await buildDailyBriefing(dataDir, input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
2870
2872
  return { content: [{
@@ -2892,15 +2894,15 @@ Returns: { date, generatedAt, urgent: string[], opportunities: string[], forecas
2892
2894
  }
2893
2895
  //#endregion
2894
2896
  //#region src/mcp/tools/list-email-templates.ts
2895
- const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2896
- async function handleListEmailTemplates(input, dataDir = DATA_DIR$26) {
2897
+ const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2898
+ async function handleListEmailTemplates(input, dataDir = DATA_DIR$28) {
2897
2899
  const summary = listTemplates(dataDir, input.category ? { category: input.category } : {}).map(({ body: _body, ...meta }) => meta);
2898
2900
  return { content: [{
2899
2901
  type: "text",
2900
2902
  text: JSON.stringify(summary, null, 2)
2901
2903
  }] };
2902
2904
  }
2903
- function registerListEmailTemplates(server, dataDir = DATA_DIR$26) {
2905
+ function registerListEmailTemplates(server, dataDir = DATA_DIR$28) {
2904
2906
  server.registerTool("list_email_templates", {
2905
2907
  description: "List available email templates. Optionally filter by category (e.g. 'outreach', 'followup', 'support').",
2906
2908
  inputSchema: z.object({ category: z.string().optional().describe("Filter by category") })
@@ -2908,8 +2910,8 @@ function registerListEmailTemplates(server, dataDir = DATA_DIR$26) {
2908
2910
  }
2909
2911
  //#endregion
2910
2912
  //#region src/mcp/tools/get-email-template.ts
2911
- const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2912
- async function handleGetEmailTemplate(input, dataDir = DATA_DIR$25) {
2913
+ const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2914
+ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$27) {
2913
2915
  const tmpl = getTemplate(dataDir, input.id);
2914
2916
  if (!tmpl) return { content: [{
2915
2917
  type: "text",
@@ -2925,7 +2927,7 @@ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$25) {
2925
2927
  }, null, 2)
2926
2928
  }] };
2927
2929
  }
2928
- function registerGetEmailTemplate(server, dataDir = DATA_DIR$25) {
2930
+ function registerGetEmailTemplate(server, dataDir = DATA_DIR$27) {
2929
2931
  server.registerTool("get_email_template", {
2930
2932
  description: "Get a specific email template by ID, including its body and detected variables.",
2931
2933
  inputSchema: z.object({ id: z.string().describe("Template ID (e.g. 'enterprise-intro')") })
@@ -2933,8 +2935,8 @@ function registerGetEmailTemplate(server, dataDir = DATA_DIR$25) {
2933
2935
  }
2934
2936
  //#endregion
2935
2937
  //#region src/mcp/tools/draft-email.ts
2936
- const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2937
- async function handleDraftEmail(input, dataDir = DATA_DIR$24) {
2938
+ const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
2939
+ async function handleDraftEmail(input, dataDir = DATA_DIR$26) {
2938
2940
  const tmpl = getTemplate(dataDir, input.templateId);
2939
2941
  if (!tmpl) return { content: [{
2940
2942
  type: "text",
@@ -2978,7 +2980,7 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$24) {
2978
2980
  }, null, 2)
2979
2981
  }] };
2980
2982
  }
2981
- function registerDraftEmail(server, dataDir = DATA_DIR$24) {
2983
+ function registerDraftEmail(server, dataDir = DATA_DIR$26) {
2982
2984
  server.registerTool("draft_email", {
2983
2985
  description: `Draft a personalized email for a customer using a stored template.
2984
2986
  Variables are auto-filled from the customer's main_facts.md. Override any variable manually.
@@ -3000,8 +3002,8 @@ Returns: { subject, body, to, tone, polished, resolvedVariables } — does NOT s
3000
3002
  }
3001
3003
  //#endregion
3002
3004
  //#region src/mcp/tools/enroll-in-sequence.ts
3003
- const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3004
- async function handleEnrollInSequence(input, dataDir = DATA_DIR$23) {
3005
+ const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3006
+ async function handleEnrollInSequence(input, dataDir = DATA_DIR$25) {
3005
3007
  const sequence = getSequence(dataDir, input.sequenceId);
3006
3008
  if (!sequence) return { content: [{
3007
3009
  type: "text",
@@ -3033,7 +3035,7 @@ async function handleEnrollInSequence(input, dataDir = DATA_DIR$23) {
3033
3035
  })
3034
3036
  }] };
3035
3037
  }
3036
- function registerEnrollInSequence(server, dataDir = DATA_DIR$23) {
3038
+ function registerEnrollInSequence(server, dataDir = DATA_DIR$25) {
3037
3039
  server.registerTool("enroll_in_sequence", {
3038
3040
  description: `Enroll a contact in an email sequence. Validates that the sequence and its first template exist.
3039
3041
  Returns: { enrollmentId, sequenceName, totalSteps }`,
@@ -3050,8 +3052,8 @@ Returns: { enrollmentId, sequenceName, totalSteps }`,
3050
3052
  }
3051
3053
  //#endregion
3052
3054
  //#region src/mcp/tools/list-sequence-enrollments.ts
3053
- const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3054
- async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$22) {
3055
+ const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3056
+ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$24) {
3055
3057
  let enrollments = readEnrollments(dataDir);
3056
3058
  if (input.slug !== void 0) enrollments = enrollments.filter((e) => e.slug === input.slug);
3057
3059
  if (input.status !== void 0) enrollments = enrollments.filter((e) => e.status === input.status);
@@ -3060,7 +3062,7 @@ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$22) {
3060
3062
  text: JSON.stringify({ enrollments }, null, 2)
3061
3063
  }] };
3062
3064
  }
3063
- function registerListSequenceEnrollments(server, dataDir = DATA_DIR$22) {
3065
+ function registerListSequenceEnrollments(server, dataDir = DATA_DIR$24) {
3064
3066
  server.registerTool("list_sequence_enrollments", {
3065
3067
  description: `List email sequence enrollments. Filter by customer slug or status.
3066
3068
  Returns: { enrollments: SequenceEnrollment[] }`,
@@ -3079,8 +3081,8 @@ Returns: { enrollments: SequenceEnrollment[] }`,
3079
3081
  }
3080
3082
  //#endregion
3081
3083
  //#region src/mcp/tools/unenroll-from-sequence.ts
3082
- const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3083
- async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$21) {
3084
+ const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3085
+ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$23) {
3084
3086
  if (!await updateEnrollment(dataDir, input.enrollmentId, { status: "paused" })) return { content: [{
3085
3087
  type: "text",
3086
3088
  text: JSON.stringify({
@@ -3093,7 +3095,7 @@ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$21) {
3093
3095
  text: JSON.stringify({ success: true })
3094
3096
  }] };
3095
3097
  }
3096
- function registerUnenrollFromSequence(server, dataDir = DATA_DIR$21) {
3098
+ function registerUnenrollFromSequence(server, dataDir = DATA_DIR$23) {
3097
3099
  server.registerTool("unenroll_from_sequence", {
3098
3100
  description: `Unenroll (pause) a contact from an email sequence. Sets status to "paused" (soft delete).
3099
3101
  Returns: { success: boolean }`,
@@ -3102,8 +3104,8 @@ Returns: { success: boolean }`,
3102
3104
  }
3103
3105
  //#endregion
3104
3106
  //#region src/mcp/tools/list-sequences.ts
3105
- const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3106
- async function handleListSequences(_input, dataDir = DATA_DIR$20) {
3107
+ const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3108
+ async function handleListSequences(_input, dataDir = DATA_DIR$22) {
3107
3109
  const sequences = listSequences(dataDir);
3108
3110
  const enrollments = readEnrollments(dataDir);
3109
3111
  const result = sequences.map((seq) => ({
@@ -3117,7 +3119,7 @@ async function handleListSequences(_input, dataDir = DATA_DIR$20) {
3117
3119
  text: JSON.stringify({ sequences: result }, null, 2)
3118
3120
  }] };
3119
3121
  }
3120
- function registerListSequences(server, dataDir = DATA_DIR$20) {
3122
+ function registerListSequences(server, dataDir = DATA_DIR$22) {
3121
3123
  server.registerTool("list_sequences", {
3122
3124
  description: `List all email sequences with step count and enrollment count.
3123
3125
  Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
@@ -3126,8 +3128,8 @@ Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
3126
3128
  }
3127
3129
  //#endregion
3128
3130
  //#region src/mcp/tools/generate-quote.ts
3129
- const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3130
- async function handleGenerateQuote(input, dataDir = DATA_DIR$19) {
3131
+ const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3132
+ async function handleGenerateQuote(input, dataDir = DATA_DIR$21) {
3131
3133
  try {
3132
3134
  const quote = await generateQuote(dataDir, input);
3133
3135
  return { content: [{
@@ -3151,7 +3153,7 @@ async function handleGenerateQuote(input, dataDir = DATA_DIR$19) {
3151
3153
  }] };
3152
3154
  }
3153
3155
  }
3154
- function registerGenerateQuote(server, dataDir = DATA_DIR$19) {
3156
+ function registerGenerateQuote(server, dataDir = DATA_DIR$21) {
3155
3157
  server.registerTool("generate_quote", {
3156
3158
  description: `Generate a professional HTML quote/offer for a customer deal.
3157
3159
  Calculates subtotal, VAT, and total. Saves JSON + HTML to .agentic/quotes/.
@@ -3179,8 +3181,8 @@ Returns: { quoteNumber, htmlPath, total, currency, validUntil }`,
3179
3181
  }
3180
3182
  //#endregion
3181
3183
  //#region src/mcp/tools/get-quote-status.ts
3182
- const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3183
- async function handleGetQuoteStatus(input, dataDir = DATA_DIR$18) {
3184
+ const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3185
+ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$20) {
3184
3186
  if (input.quoteNumber) {
3185
3187
  const quote = readQuote(dataDir, input.quoteNumber);
3186
3188
  if (!quote) return { content: [{
@@ -3198,7 +3200,7 @@ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$18) {
3198
3200
  text: JSON.stringify({ quotes }, null, 2)
3199
3201
  }] };
3200
3202
  }
3201
- function registerGetQuoteStatus(server, dataDir = DATA_DIR$18) {
3203
+ function registerGetQuoteStatus(server, dataDir = DATA_DIR$20) {
3202
3204
  server.registerTool("get_quote_status", {
3203
3205
  description: `Get quote status and details. Filter by quoteNumber (single quote) or slug (all quotes for a customer).
3204
3206
  Returns quote with status: draft | sent | viewed | accepted | declined`,
@@ -3213,7 +3215,7 @@ Returns quote with status: draft | sent | viewed | accepted | declined`,
3213
3215
  }
3214
3216
  //#endregion
3215
3217
  //#region src/mcp/tools/get-booking-link.ts
3216
- const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3218
+ const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3217
3219
  function loadCalendlyConfig(dataDir) {
3218
3220
  const p = path.join(dataDir, ".agentic", "integrations", "calendly.yaml");
3219
3221
  if (!fs.existsSync(p)) return {};
@@ -3236,7 +3238,7 @@ function readCustomerFacts(dataDir, slug) {
3236
3238
  ...email ? { email } : {}
3237
3239
  };
3238
3240
  }
3239
- async function handleGetBookingLink(input, dataDir = DATA_DIR$17) {
3241
+ async function handleGetBookingLink(input, dataDir = DATA_DIR$19) {
3240
3242
  const config = loadCalendlyConfig(dataDir);
3241
3243
  const apiKey = config.apiKey ?? process.env["CALENDLY_API_KEY"] ?? "";
3242
3244
  if (!apiKey) return { content: [{
@@ -3264,7 +3266,7 @@ async function handleGetBookingLink(input, dataDir = DATA_DIR$17) {
3264
3266
  }] };
3265
3267
  }
3266
3268
  }
3267
- function registerGetBookingLink(server, dataDir = DATA_DIR$17) {
3269
+ function registerGetBookingLink(server, dataDir = DATA_DIR$19) {
3268
3270
  server.registerTool("get_booking_link", {
3269
3271
  description: `Get a Calendly booking link for a customer. Optionally pre-fills the customer's name/email.
3270
3272
  Requires CALENDLY_API_KEY env var or .agentic/integrations/calendly.yaml config.
@@ -3282,8 +3284,8 @@ Returns: { bookingUrl, eventType, duration }`,
3282
3284
  }
3283
3285
  //#endregion
3284
3286
  //#region src/mcp/tools/create-ticket.ts
3285
- const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3286
- async function handleCreateTicket(input, dataDir = DATA_DIR$16) {
3287
+ const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3288
+ async function handleCreateTicket(input, dataDir = DATA_DIR$18) {
3287
3289
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3288
3290
  const rules = loadSlaRules(dataDir);
3289
3291
  const priority = input.priority ?? "normal";
@@ -3305,7 +3307,7 @@ async function handleCreateTicket(input, dataDir = DATA_DIR$16) {
3305
3307
  text: JSON.stringify({ ticket }, null, 2)
3306
3308
  }] };
3307
3309
  }
3308
- function registerCreateTicket(server, dataDir = DATA_DIR$16) {
3310
+ function registerCreateTicket(server, dataDir = DATA_DIR$18) {
3309
3311
  server.registerTool("create_ticket", {
3310
3312
  description: `Create a support ticket for a customer. Auto-calculates SLA due date based on priority.
3311
3313
  Returns: { ticket } with id T-NNN, status=open, slaDue`,
@@ -3331,8 +3333,8 @@ Returns: { ticket } with id T-NNN, status=open, slaDue`,
3331
3333
  }
3332
3334
  //#endregion
3333
3335
  //#region src/mcp/tools/update-ticket.ts
3334
- const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3335
- async function handleUpdateTicket(input, dataDir = DATA_DIR$15) {
3336
+ const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3337
+ async function handleUpdateTicket(input, dataDir = DATA_DIR$17) {
3336
3338
  const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
3337
3339
  if (!ticket) return { content: [{
3338
3340
  type: "text",
@@ -3351,7 +3353,7 @@ async function handleUpdateTicket(input, dataDir = DATA_DIR$15) {
3351
3353
  text: JSON.stringify({ ticket: updated }, null, 2)
3352
3354
  }] };
3353
3355
  }
3354
- function registerUpdateTicket(server, dataDir = DATA_DIR$15) {
3356
+ function registerUpdateTicket(server, dataDir = DATA_DIR$17) {
3355
3357
  server.registerTool("update_ticket", {
3356
3358
  description: `Update a ticket's status or assignee. Setting status=resolved auto-sets resolved date.
3357
3359
  Returns: { ticket }`,
@@ -3376,8 +3378,8 @@ Returns: { ticket }`,
3376
3378
  }
3377
3379
  //#endregion
3378
3380
  //#region src/mcp/tools/list-tickets.ts
3379
- const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3380
- async function handleListTickets(input, dataDir = DATA_DIR$14) {
3381
+ const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3382
+ async function handleListTickets(input, dataDir = DATA_DIR$16) {
3381
3383
  const results = await listAllTickets(dataDir, {
3382
3384
  ...input.slug !== void 0 ? { slug: input.slug } : {},
3383
3385
  ...input.status !== void 0 ? { status: input.status } : {},
@@ -3389,7 +3391,7 @@ async function handleListTickets(input, dataDir = DATA_DIR$14) {
3389
3391
  text: JSON.stringify({ tickets: results }, null, 2)
3390
3392
  }] };
3391
3393
  }
3392
- function registerListTickets(server, dataDir = DATA_DIR$14) {
3394
+ function registerListTickets(server, dataDir = DATA_DIR$16) {
3393
3395
  server.registerTool("list_tickets", {
3394
3396
  description: `List support tickets. Filter by customer, status, priority, or assignee. Sorted by priority then date.
3395
3397
  Returns: { tickets: Array<{ slug, ticket }> }`,
@@ -3419,8 +3421,8 @@ Returns: { tickets: Array<{ slug, ticket }> }`,
3419
3421
  }
3420
3422
  //#endregion
3421
3423
  //#region src/mcp/tools/close-ticket.ts
3422
- const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3423
- async function handleCloseTicket(input, dataDir = DATA_DIR$13) {
3424
+ const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3425
+ async function handleCloseTicket(input, dataDir = DATA_DIR$15) {
3424
3426
  const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
3425
3427
  if (!ticket) return { content: [{
3426
3428
  type: "text",
@@ -3447,7 +3449,7 @@ async function handleCloseTicket(input, dataDir = DATA_DIR$13) {
3447
3449
  text: JSON.stringify({ ticket: updated }, null, 2)
3448
3450
  }] };
3449
3451
  }
3450
- function registerCloseTicket(server, dataDir = DATA_DIR$13) {
3452
+ function registerCloseTicket(server, dataDir = DATA_DIR$15) {
3451
3453
  server.registerTool("close_ticket", {
3452
3454
  description: `Close a support ticket. Optionally logs the resolution as an interaction.
3453
3455
  Returns: { ticket } with status=closed`,
@@ -3464,8 +3466,8 @@ Returns: { ticket } with status=closed`,
3464
3466
  }
3465
3467
  //#endregion
3466
3468
  //#region src/mcp/tools/send-nps-survey.ts
3467
- const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3468
- async function handleSendNpsSurvey(input, dataDir = DATA_DIR$12) {
3469
+ const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3470
+ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$14) {
3469
3471
  const survey = getSurvey(dataDir, input.surveyId);
3470
3472
  if (!survey) return { content: [{
3471
3473
  type: "text",
@@ -3486,7 +3488,7 @@ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$12) {
3486
3488
  }, null, 2)
3487
3489
  }] };
3488
3490
  }
3489
- function registerSendNpsSurvey(server, dataDir = DATA_DIR$12) {
3491
+ function registerSendNpsSurvey(server, dataDir = DATA_DIR$14) {
3490
3492
  server.registerTool("send_nps_survey", {
3491
3493
  description: `Generate an NPS/CSAT survey email for a customer contact. Returns subject, HTML body, and a token-based response URL.
3492
3494
  Does NOT send automatically — returns draft for review.
@@ -3506,8 +3508,8 @@ Returns: { token, subject, body, surveyUrl }`,
3506
3508
  }
3507
3509
  //#endregion
3508
3510
  //#region src/mcp/tools/get-survey-results.ts
3509
- const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3510
- async function handleGetSurveyResults(input, dataDir = DATA_DIR$11) {
3511
+ const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3512
+ async function handleGetSurveyResults(input, dataDir = DATA_DIR$13) {
3511
3513
  const responses = loadSurveyResponses(dataDir, input.surveyId, input.slug);
3512
3514
  const nps = calcNpsScore(responses);
3513
3515
  const promoters = responses.filter((r) => r.score >= 9).length;
@@ -3533,7 +3535,7 @@ async function handleGetSurveyResults(input, dataDir = DATA_DIR$11) {
3533
3535
  }, null, 2)
3534
3536
  }] };
3535
3537
  }
3536
- function registerGetSurveyResults(server, dataDir = DATA_DIR$11) {
3538
+ function registerGetSurveyResults(server, dataDir = DATA_DIR$13) {
3537
3539
  server.registerTool("get_survey_results", {
3538
3540
  description: `Get NPS/CSAT survey results with score breakdown. Calculates Net Promoter Score.
3539
3541
  Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[] }`,
@@ -3548,8 +3550,8 @@ Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[
3548
3550
  }
3549
3551
  //#endregion
3550
3552
  //#region src/mcp/tools/search-knowledge-base.ts
3551
- const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3552
- async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$10) {
3553
+ const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3554
+ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$12) {
3553
3555
  const results = searchKbSimple(dataDir, input.query, { ...input.publicOnly ? { publicOnly: true } : {} });
3554
3556
  const limited = (input.category ? results.filter((a) => a.category === input.category) : results).slice(0, input.limit ?? 10);
3555
3557
  return { content: [{
@@ -3564,7 +3566,7 @@ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$10) {
3564
3566
  }, null, 2)
3565
3567
  }] };
3566
3568
  }
3567
- function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$10) {
3569
+ function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$12) {
3568
3570
  server.registerTool("search_knowledge_base", {
3569
3571
  description: `Search the knowledge base for articles. Text search on title, body, and tags.
3570
3572
  Returns: { count, articles[] } with excerpts`,
@@ -3583,8 +3585,8 @@ Returns: { count, articles[] } with excerpts`,
3583
3585
  }
3584
3586
  //#endregion
3585
3587
  //#region src/mcp/tools/create-kb-article.ts
3586
- const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3587
- async function handleCreateKbArticle(input, dataDir = DATA_DIR$9) {
3588
+ const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3589
+ async function handleCreateKbArticle(input, dataDir = DATA_DIR$11) {
3588
3590
  if (getKbArticle(dataDir, input.id)) return { content: [{
3589
3591
  type: "text",
3590
3592
  text: JSON.stringify({ error: `Article '${input.id}' already exists` })
@@ -3612,7 +3614,7 @@ async function handleCreateKbArticle(input, dataDir = DATA_DIR$9) {
3612
3614
  }, null, 2)
3613
3615
  }] };
3614
3616
  }
3615
- function registerCreateKbArticle(server, dataDir = DATA_DIR$9) {
3617
+ function registerCreateKbArticle(server, dataDir = DATA_DIR$11) {
3616
3618
  server.registerTool("create_kb_article", {
3617
3619
  description: `Create a new knowledge base article. Articles are stored as Markdown files in .agentic/knowledge-base/.
3618
3620
  Returns: { id, title, category, path }`,
@@ -3637,8 +3639,8 @@ Returns: { id, title, category, path }`,
3637
3639
  }
3638
3640
  //#endregion
3639
3641
  //#region src/mcp/tools/backup-now.ts
3640
- const DATA_DIR$8 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3641
- async function handleBackupNow(input, dataDir = DATA_DIR$8) {
3642
+ const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3643
+ async function handleBackupNow(input, dataDir = DATA_DIR$10) {
3642
3644
  const zipPath = path.join(dataDir, `dxcrm-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.zip`);
3643
3645
  const manifest = await runBackup(zipPath, dataDir, { ...input.remote ? { remote: input.remote } : {} }).catch(() => null);
3644
3646
  if (!manifest) return { content: [{
@@ -3675,8 +3677,8 @@ function registerBackupNow(server) {
3675
3677
  }
3676
3678
  //#endregion
3677
3679
  //#region src/mcp/tools/list-backups.ts
3678
- const DATA_DIR$7 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3679
- async function handleListBackups(input, dataDir = DATA_DIR$7) {
3680
+ const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3681
+ async function handleListBackups(input, dataDir = DATA_DIR$9) {
3680
3682
  const logEntries = readBackupLog(dataDir);
3681
3683
  const fileEntries = listBackupsInDir(dataDir);
3682
3684
  const entries = logEntries.length > 0 ? logEntries : fileEntries;
@@ -3710,8 +3712,8 @@ function registerListBackups(server) {
3710
3712
  }
3711
3713
  //#endregion
3712
3714
  //#region src/mcp/tools/trigger-sync.ts
3713
- const DATA_DIR$6 = process.cwd();
3714
- async function handleTriggerSync(input, dataDir = DATA_DIR$6) {
3715
+ const DATA_DIR$8 = process.cwd();
3716
+ async function handleTriggerSync(input, dataDir = DATA_DIR$8) {
3715
3717
  const auth = getGmailAuth();
3716
3718
  if (!auth) return { content: [{
3717
3719
  type: "text",
@@ -3805,8 +3807,8 @@ Returns: { success: boolean, synced: number, skipped: number, customers: [...],
3805
3807
  }
3806
3808
  //#endregion
3807
3809
  //#region src/mcp/tools/get-audit-log.ts
3808
- const DATA_DIR$5 = process.cwd();
3809
- async function handleGetAuditLog(input, dataDir = DATA_DIR$5) {
3810
+ const DATA_DIR$7 = process.cwd();
3811
+ async function handleGetAuditLog(input, dataDir = DATA_DIR$7) {
3810
3812
  const entries = readAuditLog(dataDir);
3811
3813
  const filterOpts = { limit: input.limit ?? 50 };
3812
3814
  if (input.slug !== void 0) filterOpts.slug = input.slug;
@@ -3848,8 +3850,8 @@ Returns: { total: number, returned: number, entries: [{timestamp, actor, tool, s
3848
3850
  }
3849
3851
  //#endregion
3850
3852
  //#region src/mcp/tools/get-logs.ts
3851
- const DATA_DIR$4 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3852
- async function handleGetLogs(input, dataDir = DATA_DIR$4) {
3853
+ const DATA_DIR$6 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3854
+ async function handleGetLogs(input, dataDir = DATA_DIR$6) {
3853
3855
  const query = {
3854
3856
  ...input.level !== void 0 ? { level: input.level } : {},
3855
3857
  ...input.component !== void 0 ? { component: input.component } : {},
@@ -3911,8 +3913,8 @@ Returns (summary): { total, byLevel, byComponent, firstTs, lastTs, recentErrors
3911
3913
  }
3912
3914
  //#endregion
3913
3915
  //#region src/mcp/tools/get-diagnostics.ts
3914
- const DATA_DIR$3 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3915
- async function handleGetDiagnostics(input, dataDir = DATA_DIR$3) {
3916
+ const DATA_DIR$5 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3917
+ async function handleGetDiagnostics(input, dataDir = DATA_DIR$5) {
3916
3918
  let cleaned = 0;
3917
3919
  if (input.fix) {
3918
3920
  const { cleanupTempFiles } = await import("./doctor-CYDaNmFn.js");
@@ -3945,11 +3947,11 @@ Returns: { ok: boolean, tempFilesRemoved?: number, checks: [{ name, status: "ok"
3945
3947
  }
3946
3948
  //#endregion
3947
3949
  //#region src/mcp/tools/get-pipeline-changes.ts
3948
- const DATA_DIR$2 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3950
+ const DATA_DIR$4 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3949
3951
  function daysAgoIso(days) {
3950
3952
  return (/* @__PURE__ */ new Date(Date.now() - days * 864e5)).toISOString().slice(0, 10);
3951
3953
  }
3952
- async function handleGetPipelineChanges(input, dataDir = DATA_DIR$2) {
3954
+ async function handleGetPipelineChanges(input, dataDir = DATA_DIR$4) {
3953
3955
  const since = input.since ?? daysAgoIso(input.days ?? 7);
3954
3956
  const diff = diffAgainstNow(dataDir, since);
3955
3957
  const payload = diff ? diff : { error: `No pipeline snapshot at or before ${since}. Snapshots accrue daily via the daemon.` };
@@ -3984,6 +3986,64 @@ or { error } when no baseline snapshot exists yet.`,
3984
3986
  });
3985
3987
  }
3986
3988
  //#endregion
3989
+ //#region src/mcp/tools/get-pipeline-velocity.ts
3990
+ const DATA_DIR$3 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
3991
+ async function handleGetPipelineVelocity(input, dataDir = DATA_DIR$3) {
3992
+ const opts = {};
3993
+ if (input.stalledDays !== void 0) opts.stalledDays = input.stalledDays;
3994
+ const report = analyzeVelocity(dataDir, opts);
3995
+ return { content: [{
3996
+ type: "text",
3997
+ text: JSON.stringify(report, null, 2)
3998
+ }] };
3999
+ }
4000
+ function registerGetPipelineVelocity(server) {
4001
+ server.registerTool("get_pipeline_velocity", {
4002
+ title: "Get Pipeline Velocity",
4003
+ description: `Pipeline velocity analytics from the daily snapshot history.
4004
+ Reconstructs each deal's stage journey to answer "where do deals get stuck?"
4005
+ and "which deals are rotting?".
4006
+
4007
+ Args:
4008
+ stalledDays: A deal open in the same stage longer than this is "stalled"
4009
+ (default 14).
4010
+
4011
+ Returns: { fromId, toId, snapshotCount, stageDurations[{stage,avgDays,samples}],
4012
+ avgSalesCycleDays, wonCount, stalledDeals[{slug,name,stage,daysInStage,value}],
4013
+ stalledThresholdDays }. snapshotCount is 0 until the daemon has taken snapshots.`,
4014
+ inputSchema: z.object({ stalledDays: z.number().int().min(1).max(365).optional().describe("Days in one stage before a deal counts as stalled (default 14)") })
4015
+ }, async ({ stalledDays }) => {
4016
+ const input = {};
4017
+ if (stalledDays !== void 0) input.stalledDays = stalledDays;
4018
+ return handleGetPipelineVelocity(input);
4019
+ });
4020
+ }
4021
+ //#endregion
4022
+ //#region src/mcp/tools/get-pipeline-funnel.ts
4023
+ const DATA_DIR$2 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
4024
+ async function handleGetPipelineFunnel(_input, dataDir = DATA_DIR$2) {
4025
+ const report = analyzeFunnel(dataDir);
4026
+ return { content: [{
4027
+ type: "text",
4028
+ text: JSON.stringify(report, null, 2)
4029
+ }] };
4030
+ }
4031
+ function registerGetPipelineFunnel(server) {
4032
+ server.registerTool("get_pipeline_funnel", {
4033
+ title: "Get Pipeline Funnel",
4034
+ description: `Pipeline conversion funnel & win-rate from the daily snapshot history.
4035
+ For each deal it tracks the furthest stage reached and the win/lost outcome,
4036
+ then builds a cumulative funnel. Answers "where do deals leak out of my
4037
+ pipeline?" and "what's my win rate?".
4038
+
4039
+ Returns: { fromId, toId, snapshotCount,
4040
+ stages[{stage, reached, conversionPctToNext}], wonCount, lostCount, winRatePct,
4041
+ biggestLeak{from,to,conversionPct} }. snapshotCount is 0 until the daemon has
4042
+ taken snapshots.`,
4043
+ inputSchema: z.object({})
4044
+ }, async () => handleGetPipelineFunnel({}));
4045
+ }
4046
+ //#endregion
3987
4047
  //#region src/mcp/prompts.ts
3988
4048
  /**
3989
4049
  * CRM playbook prompts exposed via MCP `prompts/list` + `prompts/get`.
@@ -4242,6 +4302,8 @@ function createMcpServer() {
4242
4302
  registerGetLogs(server);
4243
4303
  registerGetDiagnostics(server);
4244
4304
  registerGetPipelineChanges(server);
4305
+ registerGetPipelineVelocity(server);
4306
+ registerGetPipelineFunnel(server);
4245
4307
  registerCustomObjectTools(server);
4246
4308
  registerPrompts(server);
4247
4309
  registerResources(server);
@@ -4440,4 +4502,4 @@ else startStdio().catch((err) => {
4440
4502
  //#endregion
4441
4503
  export { startHttp, startStdio };
4442
4504
 
4443
- //# sourceMappingURL=server-BbInMUgp.js.map
4505
+ //# sourceMappingURL=server-DAcwmRPE.js.map