@datasynx/agentic-crm 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +7 -6
- package/dist/cli.js.map +1 -1
- package/dist/daemon/worker.js +18 -0
- package/dist/daemon/worker.js.map +1 -1
- package/dist/{doctor-C14-vnJ1.js → doctor-BFeelnq8.js} +2 -2
- package/dist/{doctor-C14-vnJ1.js.map → doctor-BFeelnq8.js.map} +1 -1
- package/dist/doctor-CYDaNmFn.js +2 -0
- package/dist/{index-FzDsNSSb.d.ts → index-BBAlKZg6.d.ts} +3 -3
- package/dist/{index-FzDsNSSb.d.ts.map → index-BBAlKZg6.d.ts.map} +1 -1
- package/dist/{index-BAutNcAT.d.cts → index-DMTVVYwr.d.cts} +18 -18
- package/dist/{index-BAutNcAT.d.cts.map → index-DMTVVYwr.d.cts.map} +1 -1
- package/dist/index.d.cts +18 -18
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/{knowledge-base--063Kpa3.js → knowledge-base-Bx2PKQR2.js} +2 -1
- package/dist/knowledge-base-Bx2PKQR2.js.map +1 -0
- package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
- package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
- package/dist/mcp.cjs +264 -128
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.d.cts.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +264 -128
- package/dist/mcp.js.map +1 -1
- package/dist/{server-DoRPPOeR.js → server-BhNLrnAD.js} +164 -128
- package/dist/server-BhNLrnAD.js.map +1 -0
- package/package.json +2 -2
- package/dist/knowledge-base--063Kpa3.js.map +0 -1
- package/dist/server-DoRPPOeR.js.map +0 -1
|
@@ -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
|
|
5
|
+
import { a as searchKbSimple, n as getKbArticle, o as writeKbArticle, r as getKbMetaForExport, s as CAPABILITIES_TEXT } from "./knowledge-base-Bx2PKQR2.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";
|
|
@@ -23,6 +23,7 @@ import { i as loadSlaRules, t as calcSlaDue } from "./sla-engine-O-A1ntu_.js";
|
|
|
23
23
|
import { i as getSurvey, l as savePendingSurvey, n as calcNpsScore, o as loadSurveyResponses, r as generateSurveyToken, t as buildSurveyEmail } from "./survey-engine-DngXBv47.js";
|
|
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
|
+
import { n as runDiagnostics } from "./doctor-BFeelnq8.js";
|
|
26
27
|
import { r as searchKnowledge } from "./lancedb-CuHKNsNZ.js";
|
|
27
28
|
import { t as buildDailyBriefing } from "./proactive-agent-B7u3Bj_l.js";
|
|
28
29
|
import { a as protectedResourceMetadata, o as verifyBearer, r as isAuthRequired, s as wwwAuthenticateHeader } from "./auth-DDXZTwS0.js";
|
|
@@ -254,7 +255,7 @@ function registerGetActiveSession(server) {
|
|
|
254
255
|
}
|
|
255
256
|
//#endregion
|
|
256
257
|
//#region src/mcp/tools/get-customer-context.ts
|
|
257
|
-
const DATA_DIR$
|
|
258
|
+
const DATA_DIR$52 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
258
259
|
function triggerOnQuerySync(dataDir, slug) {
|
|
259
260
|
const auth = getGmailAuth();
|
|
260
261
|
if (!auth) return;
|
|
@@ -275,7 +276,7 @@ function triggerOnQuerySync(dataDir, slug) {
|
|
|
275
276
|
}).then(() => updateSlugSyncState(dataDir, slug, { lastGmailSync: (/* @__PURE__ */ new Date()).toISOString() })).catch(() => {})).catch(() => {});
|
|
276
277
|
} catch {}
|
|
277
278
|
}
|
|
278
|
-
async function handleGetCustomerContext(input, dataDir = DATA_DIR$
|
|
279
|
+
async function handleGetCustomerContext(input, dataDir = DATA_DIR$52) {
|
|
279
280
|
const targetSlug = input.slug ?? getSession()?.customerSlug;
|
|
280
281
|
if (!targetSlug) return {
|
|
281
282
|
content: [{
|
|
@@ -327,8 +328,8 @@ Performance: <3 seconds. Token budget: <3000.`,
|
|
|
327
328
|
}
|
|
328
329
|
//#endregion
|
|
329
330
|
//#region src/mcp/tools/search-customer-knowledge.ts
|
|
330
|
-
const DATA_DIR$
|
|
331
|
-
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$
|
|
331
|
+
const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
332
|
+
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$51) {
|
|
332
333
|
const limit = input.limit ?? 5;
|
|
333
334
|
try {
|
|
334
335
|
const results = await searchKnowledge(dataDir, input.slug, input.query, limit);
|
|
@@ -376,14 +377,14 @@ If no results: returns empty array with a helpful sync suggestion.`,
|
|
|
376
377
|
}
|
|
377
378
|
//#endregion
|
|
378
379
|
//#region src/mcp/tools/list-customers.ts
|
|
379
|
-
const DATA_DIR$
|
|
380
|
+
const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
380
381
|
function extractLastInteractionDate(interactionsPath) {
|
|
381
382
|
if (!fs.existsSync(interactionsPath)) return void 0;
|
|
382
383
|
const content = fs.readFileSync(interactionsPath, "utf-8");
|
|
383
384
|
const match = /^## (\d{4}-\d{2}-\d{2})/m.exec(content);
|
|
384
385
|
return match ? match[1] : void 0;
|
|
385
386
|
}
|
|
386
|
-
async function handleListCustomers(input, dataDir = DATA_DIR$
|
|
387
|
+
async function handleListCustomers(input, dataDir = DATA_DIR$50) {
|
|
387
388
|
const customersDir = path.join(dataDir, "customers");
|
|
388
389
|
const customers = [];
|
|
389
390
|
if (!fs.existsSync(customersDir)) return { content: [{
|
|
@@ -444,8 +445,8 @@ Returns: Array of { slug, name, stage, lastInteraction?, dealValue? }`,
|
|
|
444
445
|
}
|
|
445
446
|
//#endregion
|
|
446
447
|
//#region src/mcp/tools/log-interaction.ts
|
|
447
|
-
const DATA_DIR$
|
|
448
|
-
async function handleLogInteraction(input, dataDir = DATA_DIR$
|
|
448
|
+
const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
449
|
+
async function handleLogInteraction(input, dataDir = DATA_DIR$49) {
|
|
449
450
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
450
451
|
const interactionDate = input.date ?? today;
|
|
451
452
|
const sourceRef = input.source ?? `agent://log/${Date.now()}`;
|
|
@@ -550,12 +551,12 @@ Returns: { success: boolean, path: string, entry: string }`,
|
|
|
550
551
|
}
|
|
551
552
|
//#endregion
|
|
552
553
|
//#region src/mcp/tools/export-customer.ts
|
|
553
|
-
const DATA_DIR$
|
|
554
|
+
const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
554
555
|
function countInteractions(content) {
|
|
555
556
|
const matches = content.match(/^## \d{4}-\d{2}-\d{2}/gm);
|
|
556
557
|
return matches ? matches.length : 0;
|
|
557
558
|
}
|
|
558
|
-
async function handleExportCustomer(input, dataDir = DATA_DIR$
|
|
559
|
+
async function handleExportCustomer(input, dataDir = DATA_DIR$48) {
|
|
559
560
|
enforceRbac(dataDir, "export_customer");
|
|
560
561
|
const customerDir = path.join(dataDir, "customers", input.slug);
|
|
561
562
|
if (!fs.existsSync(customerDir)) return {
|
|
@@ -668,8 +669,8 @@ Returns:
|
|
|
668
669
|
}
|
|
669
670
|
//#endregion
|
|
670
671
|
//#region src/mcp/tools/update-customer-facts.ts
|
|
671
|
-
const DATA_DIR$
|
|
672
|
-
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$
|
|
672
|
+
const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
673
|
+
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$47) {
|
|
673
674
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
674
675
|
try {
|
|
675
676
|
enforceRbac(dataDir, "update_customer_facts");
|
|
@@ -847,8 +848,8 @@ function scoreDealForToday(deal, todayDate) {
|
|
|
847
848
|
}
|
|
848
849
|
//#endregion
|
|
849
850
|
//#region src/mcp/tools/get-deal-health.ts
|
|
850
|
-
const DATA_DIR$
|
|
851
|
-
async function handleGetDealHealth(input, dataDir = DATA_DIR$
|
|
851
|
+
const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
852
|
+
async function handleGetDealHealth(input, dataDir = DATA_DIR$46) {
|
|
852
853
|
try {
|
|
853
854
|
const deals = await readPipeline(dataDir, input.slug);
|
|
854
855
|
const today = /* @__PURE__ */ new Date();
|
|
@@ -897,8 +898,8 @@ Returns: { slug, deals: [{ deal, stage, score, grade, signals, warnings }] }`,
|
|
|
897
898
|
}
|
|
898
899
|
//#endregion
|
|
899
900
|
//#region src/mcp/tools/get-pipeline-forecast.ts
|
|
900
|
-
const DATA_DIR$
|
|
901
|
-
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$
|
|
901
|
+
const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
902
|
+
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$45) {
|
|
902
903
|
try {
|
|
903
904
|
const slugs = listCustomerSlugs(dataDir).filter((d) => !input.filter || d.includes(input.filter));
|
|
904
905
|
const allDeals = [];
|
|
@@ -959,8 +960,8 @@ Returns: { deals: [...], totalWeightedValue: number, byStage: { stage: { count,
|
|
|
959
960
|
}
|
|
960
961
|
//#endregion
|
|
961
962
|
//#region src/mcp/tools/summarize-meeting.ts
|
|
962
|
-
const DATA_DIR$
|
|
963
|
-
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$
|
|
963
|
+
const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
964
|
+
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$44) {
|
|
964
965
|
try {
|
|
965
966
|
let summary = input.transcript.slice(0, 400);
|
|
966
967
|
let nextSteps = [];
|
|
@@ -1035,8 +1036,8 @@ Returns: { success, summary, nextSteps, sourceRef }`,
|
|
|
1035
1036
|
}
|
|
1036
1037
|
//#endregion
|
|
1037
1038
|
//#region src/mcp/tools/get-pipeline-stages.ts
|
|
1038
|
-
const DATA_DIR$
|
|
1039
|
-
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$
|
|
1039
|
+
const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1040
|
+
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$43) {
|
|
1040
1041
|
const stages = getPipelineStages(dataDir);
|
|
1041
1042
|
return { content: [{
|
|
1042
1043
|
type: "text",
|
|
@@ -1064,8 +1065,8 @@ async function searchAcrossCustomers(dataDir, query, limit = 5, excludeSlug) {
|
|
|
1064
1065
|
}
|
|
1065
1066
|
//#endregion
|
|
1066
1067
|
//#region src/mcp/tools/get-market-intelligence.ts
|
|
1067
|
-
const DATA_DIR$
|
|
1068
|
-
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$
|
|
1068
|
+
const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1069
|
+
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$42) {
|
|
1069
1070
|
const excludeSlug = input.excludeCurrentCustomer ? input.slug : void 0;
|
|
1070
1071
|
const all = listCustomerSlugs(dataDir);
|
|
1071
1072
|
const totalCustomersSearched = excludeSlug ? all.filter((s) => s !== excludeSlug).length : all.length;
|
|
@@ -1096,7 +1097,7 @@ function registerGetMarketIntelligence(server) {
|
|
|
1096
1097
|
}
|
|
1097
1098
|
//#endregion
|
|
1098
1099
|
//#region src/mcp/tools/get-relationship-graph.ts
|
|
1099
|
-
const DATA_DIR$
|
|
1100
|
+
const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1100
1101
|
function summarizeNode(n) {
|
|
1101
1102
|
return {
|
|
1102
1103
|
id: n.id,
|
|
@@ -1104,7 +1105,7 @@ function summarizeNode(n) {
|
|
|
1104
1105
|
email: n.properties["email"]
|
|
1105
1106
|
};
|
|
1106
1107
|
}
|
|
1107
|
-
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$
|
|
1108
|
+
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$41) {
|
|
1108
1109
|
try {
|
|
1109
1110
|
const graph = readGraph(dataDir, input.slug);
|
|
1110
1111
|
const stakeholders = getStakeholders(graph);
|
|
@@ -1172,9 +1173,9 @@ Returns: {
|
|
|
1172
1173
|
}
|
|
1173
1174
|
//#endregion
|
|
1174
1175
|
//#region src/mcp/tools/get-relationship-health.ts
|
|
1175
|
-
const DATA_DIR$
|
|
1176
|
+
const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1176
1177
|
const MAX_HEALTH_AGE_MS = 3600 * 1e3;
|
|
1177
|
-
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$
|
|
1178
|
+
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$40) {
|
|
1178
1179
|
try {
|
|
1179
1180
|
let health = readHealth(dataDir, input.slug);
|
|
1180
1181
|
if (health === null || Date.now() - new Date(health.updatedAt).getTime() > MAX_HEALTH_AGE_MS) {
|
|
@@ -1843,8 +1844,8 @@ async function runDealAgent(config, dataDir, llmFn = callLlm) {
|
|
|
1843
1844
|
}
|
|
1844
1845
|
//#endregion
|
|
1845
1846
|
//#region src/mcp/tools/run-deal-agent.ts
|
|
1846
|
-
const DATA_DIR$
|
|
1847
|
-
async function handleRunDealAgent(input, dataDir = DATA_DIR$
|
|
1847
|
+
const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1848
|
+
async function handleRunDealAgent(input, dataDir = DATA_DIR$39) {
|
|
1848
1849
|
try {
|
|
1849
1850
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1850
1851
|
const result = await runDealAgent({
|
|
@@ -1911,8 +1912,8 @@ Returns: { assessment, riskLevel, plan[], actionsQueued[], actionsExecuted[], tr
|
|
|
1911
1912
|
}
|
|
1912
1913
|
//#endregion
|
|
1913
1914
|
//#region src/mcp/tools/approve-agent-action.ts
|
|
1914
|
-
const DATA_DIR$
|
|
1915
|
-
async function handleApproveAgentAction(input, dataDir = DATA_DIR$
|
|
1915
|
+
const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1916
|
+
async function handleApproveAgentAction(input, dataDir = DATA_DIR$38) {
|
|
1916
1917
|
try {
|
|
1917
1918
|
const queue = readAgentQueue(dataDir, input.slug);
|
|
1918
1919
|
const idx = queue.pendingActions.findIndex((a) => a.actionId === input.actionId);
|
|
@@ -1989,8 +1990,8 @@ Returns: { success, actionId, status }`,
|
|
|
1989
1990
|
}
|
|
1990
1991
|
//#endregion
|
|
1991
1992
|
//#region src/mcp/tools/simulate-revenue.ts
|
|
1992
|
-
const DATA_DIR$
|
|
1993
|
-
async function handleSimulateRevenue(input, dataDir = DATA_DIR$
|
|
1993
|
+
const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1994
|
+
async function handleSimulateRevenue(input, dataDir = DATA_DIR$37) {
|
|
1994
1995
|
try {
|
|
1995
1996
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1996
1997
|
const horizon = input.horizon ?? "quarter";
|
|
@@ -2048,8 +2049,8 @@ Returns: { forecast: { p10, p50, p90, expected, stdDev, atRiskRevenue, byCloseMo
|
|
|
2048
2049
|
}
|
|
2049
2050
|
//#endregion
|
|
2050
2051
|
//#region src/mcp/tools/get-playbook.ts
|
|
2051
|
-
const DATA_DIR$
|
|
2052
|
-
async function handleGetPlaybook(input, dataDir = DATA_DIR$
|
|
2052
|
+
const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2053
|
+
async function handleGetPlaybook(input, dataDir = DATA_DIR$36) {
|
|
2053
2054
|
try {
|
|
2054
2055
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
2055
2056
|
if (!(input.stage !== void 0 || input.value !== void 0 || input.healthScore !== void 0)) return { content: [{
|
|
@@ -2134,12 +2135,12 @@ Returns: { matches: [{ name, score, trigger, successRate, usedCount, content }],
|
|
|
2134
2135
|
...healthScore !== void 0 ? { healthScore } : {},
|
|
2135
2136
|
...daysSinceContact !== void 0 ? { daysSinceContact } : {},
|
|
2136
2137
|
...championPresent !== void 0 ? { championPresent } : {}
|
|
2137
|
-
}, DATA_DIR$
|
|
2138
|
+
}, DATA_DIR$36));
|
|
2138
2139
|
}
|
|
2139
2140
|
//#endregion
|
|
2140
2141
|
//#region src/mcp/tools/create-playbook.ts
|
|
2141
|
-
const DATA_DIR$
|
|
2142
|
-
async function handleCreatePlaybook(input, dataDir = DATA_DIR$
|
|
2142
|
+
const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2143
|
+
async function handleCreatePlaybook(input, dataDir = DATA_DIR$35) {
|
|
2143
2144
|
try {
|
|
2144
2145
|
const name = toKebabCase(input.name);
|
|
2145
2146
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -2212,12 +2213,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path } }`,
|
|
|
2212
2213
|
trigger,
|
|
2213
2214
|
content,
|
|
2214
2215
|
...successRate !== void 0 ? { successRate } : {}
|
|
2215
|
-
}, DATA_DIR$
|
|
2216
|
+
}, DATA_DIR$35));
|
|
2216
2217
|
}
|
|
2217
2218
|
//#endregion
|
|
2218
2219
|
//#region src/mcp/tools/list-playbooks.ts
|
|
2219
|
-
const DATA_DIR$
|
|
2220
|
-
async function handleListPlaybooks(input, dataDir = DATA_DIR$
|
|
2220
|
+
const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2221
|
+
async function handleListPlaybooks(input, dataDir = DATA_DIR$34) {
|
|
2221
2222
|
try {
|
|
2222
2223
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
2223
2224
|
return { content: [{
|
|
@@ -2256,12 +2257,12 @@ Args:
|
|
|
2256
2257
|
|
|
2257
2258
|
Returns: { playbooks: [{ name, trigger, successRate, usedCount, lastUpdated }], count, slug }`,
|
|
2258
2259
|
inputSchema: z.object({ slug: z.string().describe("Customer ID") })
|
|
2259
|
-
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$
|
|
2260
|
+
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$34));
|
|
2260
2261
|
}
|
|
2261
2262
|
//#endregion
|
|
2262
2263
|
//#region src/mcp/tools/distill-playbook.ts
|
|
2263
|
-
const DATA_DIR$
|
|
2264
|
-
async function handleDistillPlaybook(input, dataDir = DATA_DIR$
|
|
2264
|
+
const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2265
|
+
async function handleDistillPlaybook(input, dataDir = DATA_DIR$33, llmFn = callLlm) {
|
|
2265
2266
|
try {
|
|
2266
2267
|
const result = await distillPlaybook(dataDir, input.slug, input.dealName, input.outcome, llmFn);
|
|
2267
2268
|
if (!result.ok) {
|
|
@@ -2320,12 +2321,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path }, reason
|
|
|
2320
2321
|
slug,
|
|
2321
2322
|
dealName,
|
|
2322
2323
|
outcome
|
|
2323
|
-
}, DATA_DIR$
|
|
2324
|
+
}, DATA_DIR$33));
|
|
2324
2325
|
}
|
|
2325
2326
|
//#endregion
|
|
2326
2327
|
//#region src/mcp/tools/pursue-goal.ts
|
|
2327
|
-
const DATA_DIR$
|
|
2328
|
-
async function handlePursueGoal(input, dataDir = DATA_DIR$
|
|
2328
|
+
const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2329
|
+
async function handlePursueGoal(input, dataDir = DATA_DIR$32, options = {}) {
|
|
2329
2330
|
try {
|
|
2330
2331
|
enforceRbac(dataDir, "pursue_goal");
|
|
2331
2332
|
const goal = await pursueGoal(dataDir, {
|
|
@@ -2388,12 +2389,12 @@ Returns: { goalId, description, target, deadline, decomposition: { analysis, cur
|
|
|
2388
2389
|
goal,
|
|
2389
2390
|
deadline,
|
|
2390
2391
|
...context !== void 0 ? { context } : {}
|
|
2391
|
-
}, DATA_DIR$
|
|
2392
|
+
}, DATA_DIR$32));
|
|
2392
2393
|
}
|
|
2393
2394
|
//#endregion
|
|
2394
2395
|
//#region src/mcp/tools/get-goal-status.ts
|
|
2395
|
-
const DATA_DIR$
|
|
2396
|
-
async function handleGetGoalStatus(input, dataDir = DATA_DIR$
|
|
2396
|
+
const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2397
|
+
async function handleGetGoalStatus(input, dataDir = DATA_DIR$31) {
|
|
2397
2398
|
try {
|
|
2398
2399
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2399
2400
|
const allGoals = input.goalId ? readGoals(dataDir).filter((g) => g.id === input.goalId) : getActiveGoals(dataDir);
|
|
@@ -2452,17 +2453,17 @@ Args:
|
|
|
2452
2453
|
|
|
2453
2454
|
Returns: { goals: [{ id, description, target, progress, status, deadline, daysRemaining, subGoals }], activeCount, completedCount }`,
|
|
2454
2455
|
inputSchema: z.object({ goalId: z.string().optional().describe("Specific goal ID (omit for all active goals)") })
|
|
2455
|
-
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$
|
|
2456
|
+
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$31));
|
|
2456
2457
|
}
|
|
2457
2458
|
//#endregion
|
|
2458
2459
|
//#region src/mcp/tools/register-push-subscription.ts
|
|
2459
|
-
const DATA_DIR$
|
|
2460
|
+
const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2460
2461
|
const VALID_PROVIDERS = [
|
|
2461
2462
|
"gmail",
|
|
2462
2463
|
"microsoft-graph",
|
|
2463
2464
|
"slack"
|
|
2464
2465
|
];
|
|
2465
|
-
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$
|
|
2466
|
+
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$30) {
|
|
2466
2467
|
try {
|
|
2467
2468
|
if (!VALID_PROVIDERS.includes(input.provider)) return { content: [{
|
|
2468
2469
|
type: "text",
|
|
@@ -2548,12 +2549,12 @@ Returns: { subscriptionId, provider, slug, status, expiresAt, createdAt, warning
|
|
|
2548
2549
|
...microsoftResource !== void 0 ? { microsoftResource } : {},
|
|
2549
2550
|
...slackTeamId !== void 0 ? { slackTeamId } : {},
|
|
2550
2551
|
...slackChannelId !== void 0 ? { slackChannelId } : {}
|
|
2551
|
-
}, DATA_DIR$
|
|
2552
|
+
}, DATA_DIR$30));
|
|
2552
2553
|
}
|
|
2553
2554
|
//#endregion
|
|
2554
2555
|
//#region src/mcp/tools/get-push-status.ts
|
|
2555
|
-
const DATA_DIR$
|
|
2556
|
-
async function handleGetPushStatus(input, dataDir = DATA_DIR$
|
|
2556
|
+
const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2557
|
+
async function handleGetPushStatus(input, dataDir = DATA_DIR$29) {
|
|
2557
2558
|
try {
|
|
2558
2559
|
let subs = await readSubscriptions(dataDir);
|
|
2559
2560
|
if (input.slug) subs = subs.filter((s) => s.slug === input.slug);
|
|
@@ -2625,7 +2626,7 @@ Returns: { subscriptions: [{ id, provider, slug, status, expiresAt, expiresInHou
|
|
|
2625
2626
|
}, async ({ slug, provider }) => handleGetPushStatus({
|
|
2626
2627
|
...slug !== void 0 ? { slug } : {},
|
|
2627
2628
|
...provider !== void 0 ? { provider } : {}
|
|
2628
|
-
}, DATA_DIR$
|
|
2629
|
+
}, DATA_DIR$29));
|
|
2629
2630
|
}
|
|
2630
2631
|
//#endregion
|
|
2631
2632
|
//#region src/core/org-intelligence.ts
|
|
@@ -2691,8 +2692,8 @@ function deriveRecommendation(people, missingRoles) {
|
|
|
2691
2692
|
}
|
|
2692
2693
|
//#endregion
|
|
2693
2694
|
//#region src/mcp/tools/get-org-intelligence.ts
|
|
2694
|
-
const DATA_DIR$
|
|
2695
|
-
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$
|
|
2695
|
+
const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2696
|
+
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$28) {
|
|
2696
2697
|
try {
|
|
2697
2698
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2698
2699
|
const map = buildStakeholderMap(dataDir, input.slug, today, input.dealName);
|
|
@@ -2825,8 +2826,8 @@ function buildExecutiveSummary(slug, dealName, stakeholders, overallHealth, sim,
|
|
|
2825
2826
|
}
|
|
2826
2827
|
//#endregion
|
|
2827
2828
|
//#region src/mcp/tools/open-deal-room.ts
|
|
2828
|
-
const DATA_DIR$
|
|
2829
|
-
async function handleOpenDealRoom(input, dataDir = DATA_DIR$
|
|
2829
|
+
const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2830
|
+
async function handleOpenDealRoom(input, dataDir = DATA_DIR$27) {
|
|
2830
2831
|
try {
|
|
2831
2832
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2832
2833
|
const brief = await buildDealRoom(dataDir, input.slug, input.dealName, today);
|
|
@@ -2861,8 +2862,8 @@ Returns: { slug, dealName, generatedAt, stakeholders, relationshipHealth, dealHe
|
|
|
2861
2862
|
}
|
|
2862
2863
|
//#endregion
|
|
2863
2864
|
//#region src/mcp/tools/get-proactive-briefing.ts
|
|
2864
|
-
const DATA_DIR$
|
|
2865
|
-
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$
|
|
2865
|
+
const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2866
|
+
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$26) {
|
|
2866
2867
|
try {
|
|
2867
2868
|
const briefing = await buildDailyBriefing(dataDir, input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
|
|
2868
2869
|
return { content: [{
|
|
@@ -2890,15 +2891,15 @@ Returns: { date, generatedAt, urgent: string[], opportunities: string[], forecas
|
|
|
2890
2891
|
}
|
|
2891
2892
|
//#endregion
|
|
2892
2893
|
//#region src/mcp/tools/list-email-templates.ts
|
|
2893
|
-
const DATA_DIR$
|
|
2894
|
-
async function handleListEmailTemplates(input, dataDir = DATA_DIR$
|
|
2894
|
+
const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2895
|
+
async function handleListEmailTemplates(input, dataDir = DATA_DIR$25) {
|
|
2895
2896
|
const summary = listTemplates(dataDir, input.category ? { category: input.category } : {}).map(({ body: _body, ...meta }) => meta);
|
|
2896
2897
|
return { content: [{
|
|
2897
2898
|
type: "text",
|
|
2898
2899
|
text: JSON.stringify(summary, null, 2)
|
|
2899
2900
|
}] };
|
|
2900
2901
|
}
|
|
2901
|
-
function registerListEmailTemplates(server, dataDir = DATA_DIR$
|
|
2902
|
+
function registerListEmailTemplates(server, dataDir = DATA_DIR$25) {
|
|
2902
2903
|
server.registerTool("list_email_templates", {
|
|
2903
2904
|
description: "List available email templates. Optionally filter by category (e.g. 'outreach', 'followup', 'support').",
|
|
2904
2905
|
inputSchema: z.object({ category: z.string().optional().describe("Filter by category") })
|
|
@@ -2906,8 +2907,8 @@ function registerListEmailTemplates(server, dataDir = DATA_DIR$24) {
|
|
|
2906
2907
|
}
|
|
2907
2908
|
//#endregion
|
|
2908
2909
|
//#region src/mcp/tools/get-email-template.ts
|
|
2909
|
-
const DATA_DIR$
|
|
2910
|
-
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$
|
|
2910
|
+
const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2911
|
+
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$24) {
|
|
2911
2912
|
const tmpl = getTemplate(dataDir, input.id);
|
|
2912
2913
|
if (!tmpl) return { content: [{
|
|
2913
2914
|
type: "text",
|
|
@@ -2923,7 +2924,7 @@ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$23) {
|
|
|
2923
2924
|
}, null, 2)
|
|
2924
2925
|
}] };
|
|
2925
2926
|
}
|
|
2926
|
-
function registerGetEmailTemplate(server, dataDir = DATA_DIR$
|
|
2927
|
+
function registerGetEmailTemplate(server, dataDir = DATA_DIR$24) {
|
|
2927
2928
|
server.registerTool("get_email_template", {
|
|
2928
2929
|
description: "Get a specific email template by ID, including its body and detected variables.",
|
|
2929
2930
|
inputSchema: z.object({ id: z.string().describe("Template ID (e.g. 'enterprise-intro')") })
|
|
@@ -2931,8 +2932,8 @@ function registerGetEmailTemplate(server, dataDir = DATA_DIR$23) {
|
|
|
2931
2932
|
}
|
|
2932
2933
|
//#endregion
|
|
2933
2934
|
//#region src/mcp/tools/draft-email.ts
|
|
2934
|
-
const DATA_DIR$
|
|
2935
|
-
async function handleDraftEmail(input, dataDir = DATA_DIR$
|
|
2935
|
+
const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2936
|
+
async function handleDraftEmail(input, dataDir = DATA_DIR$23) {
|
|
2936
2937
|
const tmpl = getTemplate(dataDir, input.templateId);
|
|
2937
2938
|
if (!tmpl) return { content: [{
|
|
2938
2939
|
type: "text",
|
|
@@ -2976,7 +2977,7 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$22) {
|
|
|
2976
2977
|
}, null, 2)
|
|
2977
2978
|
}] };
|
|
2978
2979
|
}
|
|
2979
|
-
function registerDraftEmail(server, dataDir = DATA_DIR$
|
|
2980
|
+
function registerDraftEmail(server, dataDir = DATA_DIR$23) {
|
|
2980
2981
|
server.registerTool("draft_email", {
|
|
2981
2982
|
description: `Draft a personalized email for a customer using a stored template.
|
|
2982
2983
|
Variables are auto-filled from the customer's main_facts.md. Override any variable manually.
|
|
@@ -2998,8 +2999,8 @@ Returns: { subject, body, to, tone, polished, resolvedVariables } — does NOT s
|
|
|
2998
2999
|
}
|
|
2999
3000
|
//#endregion
|
|
3000
3001
|
//#region src/mcp/tools/enroll-in-sequence.ts
|
|
3001
|
-
const DATA_DIR$
|
|
3002
|
-
async function handleEnrollInSequence(input, dataDir = DATA_DIR$
|
|
3002
|
+
const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3003
|
+
async function handleEnrollInSequence(input, dataDir = DATA_DIR$22) {
|
|
3003
3004
|
const sequence = getSequence(dataDir, input.sequenceId);
|
|
3004
3005
|
if (!sequence) return { content: [{
|
|
3005
3006
|
type: "text",
|
|
@@ -3031,7 +3032,7 @@ async function handleEnrollInSequence(input, dataDir = DATA_DIR$21) {
|
|
|
3031
3032
|
})
|
|
3032
3033
|
}] };
|
|
3033
3034
|
}
|
|
3034
|
-
function registerEnrollInSequence(server, dataDir = DATA_DIR$
|
|
3035
|
+
function registerEnrollInSequence(server, dataDir = DATA_DIR$22) {
|
|
3035
3036
|
server.registerTool("enroll_in_sequence", {
|
|
3036
3037
|
description: `Enroll a contact in an email sequence. Validates that the sequence and its first template exist.
|
|
3037
3038
|
Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
@@ -3048,8 +3049,8 @@ Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
|
3048
3049
|
}
|
|
3049
3050
|
//#endregion
|
|
3050
3051
|
//#region src/mcp/tools/list-sequence-enrollments.ts
|
|
3051
|
-
const DATA_DIR$
|
|
3052
|
-
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$
|
|
3052
|
+
const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3053
|
+
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$21) {
|
|
3053
3054
|
let enrollments = readEnrollments(dataDir);
|
|
3054
3055
|
if (input.slug !== void 0) enrollments = enrollments.filter((e) => e.slug === input.slug);
|
|
3055
3056
|
if (input.status !== void 0) enrollments = enrollments.filter((e) => e.status === input.status);
|
|
@@ -3058,7 +3059,7 @@ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$20) {
|
|
|
3058
3059
|
text: JSON.stringify({ enrollments }, null, 2)
|
|
3059
3060
|
}] };
|
|
3060
3061
|
}
|
|
3061
|
-
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$
|
|
3062
|
+
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$21) {
|
|
3062
3063
|
server.registerTool("list_sequence_enrollments", {
|
|
3063
3064
|
description: `List email sequence enrollments. Filter by customer slug or status.
|
|
3064
3065
|
Returns: { enrollments: SequenceEnrollment[] }`,
|
|
@@ -3077,8 +3078,8 @@ Returns: { enrollments: SequenceEnrollment[] }`,
|
|
|
3077
3078
|
}
|
|
3078
3079
|
//#endregion
|
|
3079
3080
|
//#region src/mcp/tools/unenroll-from-sequence.ts
|
|
3080
|
-
const DATA_DIR$
|
|
3081
|
-
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$
|
|
3081
|
+
const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3082
|
+
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$20) {
|
|
3082
3083
|
if (!await updateEnrollment(dataDir, input.enrollmentId, { status: "paused" })) return { content: [{
|
|
3083
3084
|
type: "text",
|
|
3084
3085
|
text: JSON.stringify({
|
|
@@ -3091,7 +3092,7 @@ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$19) {
|
|
|
3091
3092
|
text: JSON.stringify({ success: true })
|
|
3092
3093
|
}] };
|
|
3093
3094
|
}
|
|
3094
|
-
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$
|
|
3095
|
+
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$20) {
|
|
3095
3096
|
server.registerTool("unenroll_from_sequence", {
|
|
3096
3097
|
description: `Unenroll (pause) a contact from an email sequence. Sets status to "paused" (soft delete).
|
|
3097
3098
|
Returns: { success: boolean }`,
|
|
@@ -3100,8 +3101,8 @@ Returns: { success: boolean }`,
|
|
|
3100
3101
|
}
|
|
3101
3102
|
//#endregion
|
|
3102
3103
|
//#region src/mcp/tools/list-sequences.ts
|
|
3103
|
-
const DATA_DIR$
|
|
3104
|
-
async function handleListSequences(_input, dataDir = DATA_DIR$
|
|
3104
|
+
const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3105
|
+
async function handleListSequences(_input, dataDir = DATA_DIR$19) {
|
|
3105
3106
|
const sequences = listSequences(dataDir);
|
|
3106
3107
|
const enrollments = readEnrollments(dataDir);
|
|
3107
3108
|
const result = sequences.map((seq) => ({
|
|
@@ -3115,7 +3116,7 @@ async function handleListSequences(_input, dataDir = DATA_DIR$18) {
|
|
|
3115
3116
|
text: JSON.stringify({ sequences: result }, null, 2)
|
|
3116
3117
|
}] };
|
|
3117
3118
|
}
|
|
3118
|
-
function registerListSequences(server, dataDir = DATA_DIR$
|
|
3119
|
+
function registerListSequences(server, dataDir = DATA_DIR$19) {
|
|
3119
3120
|
server.registerTool("list_sequences", {
|
|
3120
3121
|
description: `List all email sequences with step count and enrollment count.
|
|
3121
3122
|
Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
|
|
@@ -3124,8 +3125,8 @@ Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
|
|
|
3124
3125
|
}
|
|
3125
3126
|
//#endregion
|
|
3126
3127
|
//#region src/mcp/tools/generate-quote.ts
|
|
3127
|
-
const DATA_DIR$
|
|
3128
|
-
async function handleGenerateQuote(input, dataDir = DATA_DIR$
|
|
3128
|
+
const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3129
|
+
async function handleGenerateQuote(input, dataDir = DATA_DIR$18) {
|
|
3129
3130
|
try {
|
|
3130
3131
|
const quote = await generateQuote(dataDir, input);
|
|
3131
3132
|
return { content: [{
|
|
@@ -3149,7 +3150,7 @@ async function handleGenerateQuote(input, dataDir = DATA_DIR$17) {
|
|
|
3149
3150
|
}] };
|
|
3150
3151
|
}
|
|
3151
3152
|
}
|
|
3152
|
-
function registerGenerateQuote(server, dataDir = DATA_DIR$
|
|
3153
|
+
function registerGenerateQuote(server, dataDir = DATA_DIR$18) {
|
|
3153
3154
|
server.registerTool("generate_quote", {
|
|
3154
3155
|
description: `Generate a professional HTML quote/offer for a customer deal.
|
|
3155
3156
|
Calculates subtotal, VAT, and total. Saves JSON + HTML to .agentic/quotes/.
|
|
@@ -3177,8 +3178,8 @@ Returns: { quoteNumber, htmlPath, total, currency, validUntil }`,
|
|
|
3177
3178
|
}
|
|
3178
3179
|
//#endregion
|
|
3179
3180
|
//#region src/mcp/tools/get-quote-status.ts
|
|
3180
|
-
const DATA_DIR$
|
|
3181
|
-
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$
|
|
3181
|
+
const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3182
|
+
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$17) {
|
|
3182
3183
|
if (input.quoteNumber) {
|
|
3183
3184
|
const quote = readQuote(dataDir, input.quoteNumber);
|
|
3184
3185
|
if (!quote) return { content: [{
|
|
@@ -3196,7 +3197,7 @@ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$16) {
|
|
|
3196
3197
|
text: JSON.stringify({ quotes }, null, 2)
|
|
3197
3198
|
}] };
|
|
3198
3199
|
}
|
|
3199
|
-
function registerGetQuoteStatus(server, dataDir = DATA_DIR$
|
|
3200
|
+
function registerGetQuoteStatus(server, dataDir = DATA_DIR$17) {
|
|
3200
3201
|
server.registerTool("get_quote_status", {
|
|
3201
3202
|
description: `Get quote status and details. Filter by quoteNumber (single quote) or slug (all quotes for a customer).
|
|
3202
3203
|
Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
@@ -3211,7 +3212,7 @@ Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
|
3211
3212
|
}
|
|
3212
3213
|
//#endregion
|
|
3213
3214
|
//#region src/mcp/tools/get-booking-link.ts
|
|
3214
|
-
const DATA_DIR$
|
|
3215
|
+
const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3215
3216
|
function loadCalendlyConfig(dataDir) {
|
|
3216
3217
|
const p = path.join(dataDir, ".agentic", "integrations", "calendly.yaml");
|
|
3217
3218
|
if (!fs.existsSync(p)) return {};
|
|
@@ -3234,7 +3235,7 @@ function readCustomerFacts(dataDir, slug) {
|
|
|
3234
3235
|
...email ? { email } : {}
|
|
3235
3236
|
};
|
|
3236
3237
|
}
|
|
3237
|
-
async function handleGetBookingLink(input, dataDir = DATA_DIR$
|
|
3238
|
+
async function handleGetBookingLink(input, dataDir = DATA_DIR$16) {
|
|
3238
3239
|
const config = loadCalendlyConfig(dataDir);
|
|
3239
3240
|
const apiKey = config.apiKey ?? process.env["CALENDLY_API_KEY"] ?? "";
|
|
3240
3241
|
if (!apiKey) return { content: [{
|
|
@@ -3262,7 +3263,7 @@ async function handleGetBookingLink(input, dataDir = DATA_DIR$15) {
|
|
|
3262
3263
|
}] };
|
|
3263
3264
|
}
|
|
3264
3265
|
}
|
|
3265
|
-
function registerGetBookingLink(server, dataDir = DATA_DIR$
|
|
3266
|
+
function registerGetBookingLink(server, dataDir = DATA_DIR$16) {
|
|
3266
3267
|
server.registerTool("get_booking_link", {
|
|
3267
3268
|
description: `Get a Calendly booking link for a customer. Optionally pre-fills the customer's name/email.
|
|
3268
3269
|
Requires CALENDLY_API_KEY env var or .agentic/integrations/calendly.yaml config.
|
|
@@ -3280,8 +3281,8 @@ Returns: { bookingUrl, eventType, duration }`,
|
|
|
3280
3281
|
}
|
|
3281
3282
|
//#endregion
|
|
3282
3283
|
//#region src/mcp/tools/create-ticket.ts
|
|
3283
|
-
const DATA_DIR$
|
|
3284
|
-
async function handleCreateTicket(input, dataDir = DATA_DIR$
|
|
3284
|
+
const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3285
|
+
async function handleCreateTicket(input, dataDir = DATA_DIR$15) {
|
|
3285
3286
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3286
3287
|
const rules = loadSlaRules(dataDir);
|
|
3287
3288
|
const priority = input.priority ?? "normal";
|
|
@@ -3303,7 +3304,7 @@ async function handleCreateTicket(input, dataDir = DATA_DIR$14) {
|
|
|
3303
3304
|
text: JSON.stringify({ ticket }, null, 2)
|
|
3304
3305
|
}] };
|
|
3305
3306
|
}
|
|
3306
|
-
function registerCreateTicket(server, dataDir = DATA_DIR$
|
|
3307
|
+
function registerCreateTicket(server, dataDir = DATA_DIR$15) {
|
|
3307
3308
|
server.registerTool("create_ticket", {
|
|
3308
3309
|
description: `Create a support ticket for a customer. Auto-calculates SLA due date based on priority.
|
|
3309
3310
|
Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
@@ -3329,8 +3330,8 @@ Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
|
3329
3330
|
}
|
|
3330
3331
|
//#endregion
|
|
3331
3332
|
//#region src/mcp/tools/update-ticket.ts
|
|
3332
|
-
const DATA_DIR$
|
|
3333
|
-
async function handleUpdateTicket(input, dataDir = DATA_DIR$
|
|
3333
|
+
const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3334
|
+
async function handleUpdateTicket(input, dataDir = DATA_DIR$14) {
|
|
3334
3335
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
3335
3336
|
if (!ticket) return { content: [{
|
|
3336
3337
|
type: "text",
|
|
@@ -3349,7 +3350,7 @@ async function handleUpdateTicket(input, dataDir = DATA_DIR$13) {
|
|
|
3349
3350
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
3350
3351
|
}] };
|
|
3351
3352
|
}
|
|
3352
|
-
function registerUpdateTicket(server, dataDir = DATA_DIR$
|
|
3353
|
+
function registerUpdateTicket(server, dataDir = DATA_DIR$14) {
|
|
3353
3354
|
server.registerTool("update_ticket", {
|
|
3354
3355
|
description: `Update a ticket's status or assignee. Setting status=resolved auto-sets resolved date.
|
|
3355
3356
|
Returns: { ticket }`,
|
|
@@ -3374,8 +3375,8 @@ Returns: { ticket }`,
|
|
|
3374
3375
|
}
|
|
3375
3376
|
//#endregion
|
|
3376
3377
|
//#region src/mcp/tools/list-tickets.ts
|
|
3377
|
-
const DATA_DIR$
|
|
3378
|
-
async function handleListTickets(input, dataDir = DATA_DIR$
|
|
3378
|
+
const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3379
|
+
async function handleListTickets(input, dataDir = DATA_DIR$13) {
|
|
3379
3380
|
const results = await listAllTickets(dataDir, {
|
|
3380
3381
|
...input.slug !== void 0 ? { slug: input.slug } : {},
|
|
3381
3382
|
...input.status !== void 0 ? { status: input.status } : {},
|
|
@@ -3387,7 +3388,7 @@ async function handleListTickets(input, dataDir = DATA_DIR$12) {
|
|
|
3387
3388
|
text: JSON.stringify({ tickets: results }, null, 2)
|
|
3388
3389
|
}] };
|
|
3389
3390
|
}
|
|
3390
|
-
function registerListTickets(server, dataDir = DATA_DIR$
|
|
3391
|
+
function registerListTickets(server, dataDir = DATA_DIR$13) {
|
|
3391
3392
|
server.registerTool("list_tickets", {
|
|
3392
3393
|
description: `List support tickets. Filter by customer, status, priority, or assignee. Sorted by priority then date.
|
|
3393
3394
|
Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
@@ -3417,8 +3418,8 @@ Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
|
3417
3418
|
}
|
|
3418
3419
|
//#endregion
|
|
3419
3420
|
//#region src/mcp/tools/close-ticket.ts
|
|
3420
|
-
const DATA_DIR$
|
|
3421
|
-
async function handleCloseTicket(input, dataDir = DATA_DIR$
|
|
3421
|
+
const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3422
|
+
async function handleCloseTicket(input, dataDir = DATA_DIR$12) {
|
|
3422
3423
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
3423
3424
|
if (!ticket) return { content: [{
|
|
3424
3425
|
type: "text",
|
|
@@ -3445,7 +3446,7 @@ async function handleCloseTicket(input, dataDir = DATA_DIR$11) {
|
|
|
3445
3446
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
3446
3447
|
}] };
|
|
3447
3448
|
}
|
|
3448
|
-
function registerCloseTicket(server, dataDir = DATA_DIR$
|
|
3449
|
+
function registerCloseTicket(server, dataDir = DATA_DIR$12) {
|
|
3449
3450
|
server.registerTool("close_ticket", {
|
|
3450
3451
|
description: `Close a support ticket. Optionally logs the resolution as an interaction.
|
|
3451
3452
|
Returns: { ticket } with status=closed`,
|
|
@@ -3462,8 +3463,8 @@ Returns: { ticket } with status=closed`,
|
|
|
3462
3463
|
}
|
|
3463
3464
|
//#endregion
|
|
3464
3465
|
//#region src/mcp/tools/send-nps-survey.ts
|
|
3465
|
-
const DATA_DIR$
|
|
3466
|
-
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$
|
|
3466
|
+
const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3467
|
+
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$11) {
|
|
3467
3468
|
const survey = getSurvey(dataDir, input.surveyId);
|
|
3468
3469
|
if (!survey) return { content: [{
|
|
3469
3470
|
type: "text",
|
|
@@ -3484,7 +3485,7 @@ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$10) {
|
|
|
3484
3485
|
}, null, 2)
|
|
3485
3486
|
}] };
|
|
3486
3487
|
}
|
|
3487
|
-
function registerSendNpsSurvey(server, dataDir = DATA_DIR$
|
|
3488
|
+
function registerSendNpsSurvey(server, dataDir = DATA_DIR$11) {
|
|
3488
3489
|
server.registerTool("send_nps_survey", {
|
|
3489
3490
|
description: `Generate an NPS/CSAT survey email for a customer contact. Returns subject, HTML body, and a token-based response URL.
|
|
3490
3491
|
Does NOT send automatically — returns draft for review.
|
|
@@ -3504,8 +3505,8 @@ Returns: { token, subject, body, surveyUrl }`,
|
|
|
3504
3505
|
}
|
|
3505
3506
|
//#endregion
|
|
3506
3507
|
//#region src/mcp/tools/get-survey-results.ts
|
|
3507
|
-
const DATA_DIR$
|
|
3508
|
-
async function handleGetSurveyResults(input, dataDir = DATA_DIR$
|
|
3508
|
+
const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3509
|
+
async function handleGetSurveyResults(input, dataDir = DATA_DIR$10) {
|
|
3509
3510
|
const responses = loadSurveyResponses(dataDir, input.surveyId, input.slug);
|
|
3510
3511
|
const nps = calcNpsScore(responses);
|
|
3511
3512
|
const promoters = responses.filter((r) => r.score >= 9).length;
|
|
@@ -3531,7 +3532,7 @@ async function handleGetSurveyResults(input, dataDir = DATA_DIR$9) {
|
|
|
3531
3532
|
}, null, 2)
|
|
3532
3533
|
}] };
|
|
3533
3534
|
}
|
|
3534
|
-
function registerGetSurveyResults(server, dataDir = DATA_DIR$
|
|
3535
|
+
function registerGetSurveyResults(server, dataDir = DATA_DIR$10) {
|
|
3535
3536
|
server.registerTool("get_survey_results", {
|
|
3536
3537
|
description: `Get NPS/CSAT survey results with score breakdown. Calculates Net Promoter Score.
|
|
3537
3538
|
Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[] }`,
|
|
@@ -3546,8 +3547,8 @@ Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[
|
|
|
3546
3547
|
}
|
|
3547
3548
|
//#endregion
|
|
3548
3549
|
//#region src/mcp/tools/search-knowledge-base.ts
|
|
3549
|
-
const DATA_DIR$
|
|
3550
|
-
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$
|
|
3550
|
+
const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3551
|
+
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$9) {
|
|
3551
3552
|
const results = searchKbSimple(dataDir, input.query, { ...input.publicOnly ? { publicOnly: true } : {} });
|
|
3552
3553
|
const limited = (input.category ? results.filter((a) => a.category === input.category) : results).slice(0, input.limit ?? 10);
|
|
3553
3554
|
return { content: [{
|
|
@@ -3562,7 +3563,7 @@ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$8) {
|
|
|
3562
3563
|
}, null, 2)
|
|
3563
3564
|
}] };
|
|
3564
3565
|
}
|
|
3565
|
-
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$
|
|
3566
|
+
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$9) {
|
|
3566
3567
|
server.registerTool("search_knowledge_base", {
|
|
3567
3568
|
description: `Search the knowledge base for articles. Text search on title, body, and tags.
|
|
3568
3569
|
Returns: { count, articles[] } with excerpts`,
|
|
@@ -3581,8 +3582,8 @@ Returns: { count, articles[] } with excerpts`,
|
|
|
3581
3582
|
}
|
|
3582
3583
|
//#endregion
|
|
3583
3584
|
//#region src/mcp/tools/create-kb-article.ts
|
|
3584
|
-
const DATA_DIR$
|
|
3585
|
-
async function handleCreateKbArticle(input, dataDir = DATA_DIR$
|
|
3585
|
+
const DATA_DIR$8 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3586
|
+
async function handleCreateKbArticle(input, dataDir = DATA_DIR$8) {
|
|
3586
3587
|
if (getKbArticle(dataDir, input.id)) return { content: [{
|
|
3587
3588
|
type: "text",
|
|
3588
3589
|
text: JSON.stringify({ error: `Article '${input.id}' already exists` })
|
|
@@ -3610,7 +3611,7 @@ async function handleCreateKbArticle(input, dataDir = DATA_DIR$7) {
|
|
|
3610
3611
|
}, null, 2)
|
|
3611
3612
|
}] };
|
|
3612
3613
|
}
|
|
3613
|
-
function registerCreateKbArticle(server, dataDir = DATA_DIR$
|
|
3614
|
+
function registerCreateKbArticle(server, dataDir = DATA_DIR$8) {
|
|
3614
3615
|
server.registerTool("create_kb_article", {
|
|
3615
3616
|
description: `Create a new knowledge base article. Articles are stored as Markdown files in .agentic/knowledge-base/.
|
|
3616
3617
|
Returns: { id, title, category, path }`,
|
|
@@ -3635,8 +3636,8 @@ Returns: { id, title, category, path }`,
|
|
|
3635
3636
|
}
|
|
3636
3637
|
//#endregion
|
|
3637
3638
|
//#region src/mcp/tools/backup-now.ts
|
|
3638
|
-
const DATA_DIR$
|
|
3639
|
-
async function handleBackupNow(input, dataDir = DATA_DIR$
|
|
3639
|
+
const DATA_DIR$7 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3640
|
+
async function handleBackupNow(input, dataDir = DATA_DIR$7) {
|
|
3640
3641
|
const zipPath = path.join(dataDir, `dxcrm-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.zip`);
|
|
3641
3642
|
const manifest = await runBackup(zipPath, dataDir, { ...input.remote ? { remote: input.remote } : {} }).catch(() => null);
|
|
3642
3643
|
if (!manifest) return { content: [{
|
|
@@ -3673,8 +3674,8 @@ function registerBackupNow(server) {
|
|
|
3673
3674
|
}
|
|
3674
3675
|
//#endregion
|
|
3675
3676
|
//#region src/mcp/tools/list-backups.ts
|
|
3676
|
-
const DATA_DIR$
|
|
3677
|
-
async function handleListBackups(input, dataDir = DATA_DIR$
|
|
3677
|
+
const DATA_DIR$6 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3678
|
+
async function handleListBackups(input, dataDir = DATA_DIR$6) {
|
|
3678
3679
|
const logEntries = readBackupLog(dataDir);
|
|
3679
3680
|
const fileEntries = listBackupsInDir(dataDir);
|
|
3680
3681
|
const entries = logEntries.length > 0 ? logEntries : fileEntries;
|
|
@@ -3708,8 +3709,8 @@ function registerListBackups(server) {
|
|
|
3708
3709
|
}
|
|
3709
3710
|
//#endregion
|
|
3710
3711
|
//#region src/mcp/tools/trigger-sync.ts
|
|
3711
|
-
const DATA_DIR$
|
|
3712
|
-
async function handleTriggerSync(input, dataDir = DATA_DIR$
|
|
3712
|
+
const DATA_DIR$5 = process.cwd();
|
|
3713
|
+
async function handleTriggerSync(input, dataDir = DATA_DIR$5) {
|
|
3713
3714
|
const auth = getGmailAuth();
|
|
3714
3715
|
if (!auth) return { content: [{
|
|
3715
3716
|
type: "text",
|
|
@@ -3803,8 +3804,8 @@ Returns: { success: boolean, synced: number, skipped: number, customers: [...],
|
|
|
3803
3804
|
}
|
|
3804
3805
|
//#endregion
|
|
3805
3806
|
//#region src/mcp/tools/get-audit-log.ts
|
|
3806
|
-
const DATA_DIR$
|
|
3807
|
-
async function handleGetAuditLog(input, dataDir = DATA_DIR$
|
|
3807
|
+
const DATA_DIR$4 = process.cwd();
|
|
3808
|
+
async function handleGetAuditLog(input, dataDir = DATA_DIR$4) {
|
|
3808
3809
|
const entries = readAuditLog(dataDir);
|
|
3809
3810
|
const filterOpts = { limit: input.limit ?? 50 };
|
|
3810
3811
|
if (input.slug !== void 0) filterOpts.slug = input.slug;
|
|
@@ -3846,8 +3847,8 @@ Returns: { total: number, returned: number, entries: [{timestamp, actor, tool, s
|
|
|
3846
3847
|
}
|
|
3847
3848
|
//#endregion
|
|
3848
3849
|
//#region src/mcp/tools/get-logs.ts
|
|
3849
|
-
const DATA_DIR$
|
|
3850
|
-
async function handleGetLogs(input, dataDir = DATA_DIR$
|
|
3850
|
+
const DATA_DIR$3 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3851
|
+
async function handleGetLogs(input, dataDir = DATA_DIR$3) {
|
|
3851
3852
|
const query = {
|
|
3852
3853
|
...input.level !== void 0 ? { level: input.level } : {},
|
|
3853
3854
|
...input.component !== void 0 ? { component: input.component } : {},
|
|
@@ -3908,6 +3909,40 @@ Returns (summary): { total, byLevel, byComponent, firstTs, lastTs, recentErrors
|
|
|
3908
3909
|
});
|
|
3909
3910
|
}
|
|
3910
3911
|
//#endregion
|
|
3912
|
+
//#region src/mcp/tools/get-diagnostics.ts
|
|
3913
|
+
const DATA_DIR$2 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3914
|
+
async function handleGetDiagnostics(input, dataDir = DATA_DIR$2) {
|
|
3915
|
+
let cleaned = 0;
|
|
3916
|
+
if (input.fix) {
|
|
3917
|
+
const { cleanupTempFiles } = await import("./doctor-CYDaNmFn.js");
|
|
3918
|
+
cleaned = cleanupTempFiles(dataDir).length;
|
|
3919
|
+
}
|
|
3920
|
+
const report = await runDiagnostics(dataDir);
|
|
3921
|
+
return { content: [{
|
|
3922
|
+
type: "text",
|
|
3923
|
+
text: JSON.stringify({
|
|
3924
|
+
ok: report.ok,
|
|
3925
|
+
...input.fix ? { tempFilesRemoved: cleaned } : {},
|
|
3926
|
+
checks: report.checks
|
|
3927
|
+
}, null, 2)
|
|
3928
|
+
}] };
|
|
3929
|
+
}
|
|
3930
|
+
function registerGetDiagnostics(server) {
|
|
3931
|
+
server.registerTool("get_diagnostics", {
|
|
3932
|
+
title: "Get Diagnostics",
|
|
3933
|
+
description: `Run a self-diagnostic health check of the CRM workspace.
|
|
3934
|
+
Verifies the data directory, validates every customer's profile, detects orphaned
|
|
3935
|
+
atomic-write temp files (a crash signature), surfaces recent log errors, and checks
|
|
3936
|
+
backup freshness. Use to answer "is everything healthy?" before/after bulk operations.
|
|
3937
|
+
|
|
3938
|
+
Args:
|
|
3939
|
+
fix: When true, first remove orphaned temp files (the only safely auto-fixable issue)
|
|
3940
|
+
|
|
3941
|
+
Returns: { ok: boolean, tempFilesRemoved?: number, checks: [{ name, status: "ok"|"warn"|"fail", detail }] }`,
|
|
3942
|
+
inputSchema: z.object({ fix: z.boolean().optional().describe("Clean orphaned temp files before reporting") })
|
|
3943
|
+
}, async ({ fix }) => handleGetDiagnostics(fix !== void 0 ? { fix } : {}));
|
|
3944
|
+
}
|
|
3945
|
+
//#endregion
|
|
3911
3946
|
//#region src/mcp/prompts.ts
|
|
3912
3947
|
/**
|
|
3913
3948
|
* CRM playbook prompts exposed via MCP `prompts/list` + `prompts/get`.
|
|
@@ -4164,6 +4199,7 @@ function createMcpServer() {
|
|
|
4164
4199
|
registerTriggerSync(server);
|
|
4165
4200
|
registerGetAuditLog(server);
|
|
4166
4201
|
registerGetLogs(server);
|
|
4202
|
+
registerGetDiagnostics(server);
|
|
4167
4203
|
registerCustomObjectTools(server);
|
|
4168
4204
|
registerPrompts(server);
|
|
4169
4205
|
registerResources(server);
|
|
@@ -4362,4 +4398,4 @@ else startStdio().catch((err) => {
|
|
|
4362
4398
|
//#endregion
|
|
4363
4399
|
export { startHttp, startStdio };
|
|
4364
4400
|
|
|
4365
|
-
//# sourceMappingURL=server-
|
|
4401
|
+
//# sourceMappingURL=server-BhNLrnAD.js.map
|