@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
package/dist/mcp.cjs
CHANGED
|
@@ -450,6 +450,7 @@ Config: \`.agentic/rbac.json\` | Actor: \`DXCRM_ACTOR\` env var
|
|
|
450
450
|
| trigger_sync | Force immediate Gmail sync for one or all customers | rep+ |
|
|
451
451
|
| get_audit_log | Read audit log — all write operations with actor, tool, customer | admin |
|
|
452
452
|
| get_logs | Query/aggregate the structured application log (level, component, errors) | admin |
|
|
453
|
+
| get_diagnostics | Self-diagnostic health check (data integrity, temp files, log errors, backups) | admin |
|
|
453
454
|
| define_custom_object | Define a runtime custom object type with typed fields (no migration) | admin |
|
|
454
455
|
| create_record | Create a record of a custom object (validated against its schema) | rep+ |
|
|
455
456
|
| list_records | List records of a custom object | any |
|
|
@@ -1428,7 +1429,7 @@ async function buildContext(dataDir, slug) {
|
|
|
1428
1429
|
}
|
|
1429
1430
|
//#endregion
|
|
1430
1431
|
//#region src/mcp/tools/get-customer-context.ts
|
|
1431
|
-
const DATA_DIR$
|
|
1432
|
+
const DATA_DIR$53 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1432
1433
|
function triggerOnQuerySync(dataDir, slug) {
|
|
1433
1434
|
const auth = getGmailAuth();
|
|
1434
1435
|
if (!auth) return;
|
|
@@ -1449,7 +1450,7 @@ function triggerOnQuerySync(dataDir, slug) {
|
|
|
1449
1450
|
}).then(() => updateSlugSyncState(dataDir, slug, { lastGmailSync: (/* @__PURE__ */ new Date()).toISOString() })).catch(() => {})).catch(() => {});
|
|
1450
1451
|
} catch {}
|
|
1451
1452
|
}
|
|
1452
|
-
async function handleGetCustomerContext(input, dataDir = DATA_DIR$
|
|
1453
|
+
async function handleGetCustomerContext(input, dataDir = DATA_DIR$53) {
|
|
1453
1454
|
const targetSlug = input.slug ?? require_session_store.getSession()?.customerSlug;
|
|
1454
1455
|
if (!targetSlug) return {
|
|
1455
1456
|
content: [{
|
|
@@ -1585,8 +1586,8 @@ async function searchKnowledge(dataDir, slug, query, limit) {
|
|
|
1585
1586
|
}
|
|
1586
1587
|
//#endregion
|
|
1587
1588
|
//#region src/mcp/tools/search-customer-knowledge.ts
|
|
1588
|
-
const DATA_DIR$
|
|
1589
|
-
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$
|
|
1589
|
+
const DATA_DIR$52 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1590
|
+
async function handleSearchCustomerKnowledge(input, dataDir = DATA_DIR$52) {
|
|
1590
1591
|
const limit = input.limit ?? 5;
|
|
1591
1592
|
try {
|
|
1592
1593
|
const results = await searchKnowledge(dataDir, input.slug, input.query, limit);
|
|
@@ -1634,14 +1635,14 @@ If no results: returns empty array with a helpful sync suggestion.`,
|
|
|
1634
1635
|
}
|
|
1635
1636
|
//#endregion
|
|
1636
1637
|
//#region src/mcp/tools/list-customers.ts
|
|
1637
|
-
const DATA_DIR$
|
|
1638
|
+
const DATA_DIR$51 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
1638
1639
|
function extractLastInteractionDate(interactionsPath) {
|
|
1639
1640
|
if (!fs.default.existsSync(interactionsPath)) return void 0;
|
|
1640
1641
|
const content = fs.default.readFileSync(interactionsPath, "utf-8");
|
|
1641
1642
|
const match = /^## (\d{4}-\d{2}-\d{2})/m.exec(content);
|
|
1642
1643
|
return match ? match[1] : void 0;
|
|
1643
1644
|
}
|
|
1644
|
-
async function handleListCustomers(input, dataDir = DATA_DIR$
|
|
1645
|
+
async function handleListCustomers(input, dataDir = DATA_DIR$51) {
|
|
1645
1646
|
const customersDir = path.default.join(dataDir, "customers");
|
|
1646
1647
|
const customers = [];
|
|
1647
1648
|
if (!fs.default.existsSync(customersDir)) return { content: [{
|
|
@@ -2154,8 +2155,8 @@ async function updateHealthFromInteraction(dataDir, slug) {
|
|
|
2154
2155
|
}
|
|
2155
2156
|
//#endregion
|
|
2156
2157
|
//#region src/mcp/tools/log-interaction.ts
|
|
2157
|
-
const DATA_DIR$
|
|
2158
|
-
async function handleLogInteraction(input, dataDir = DATA_DIR$
|
|
2158
|
+
const DATA_DIR$50 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2159
|
+
async function handleLogInteraction(input, dataDir = DATA_DIR$50) {
|
|
2159
2160
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2160
2161
|
const interactionDate = input.date ?? today;
|
|
2161
2162
|
const sourceRef = input.source ?? `agent://log/${Date.now()}`;
|
|
@@ -2264,8 +2265,8 @@ var update_deal_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
|
2264
2265
|
handleUpdateDeal: () => handleUpdateDeal,
|
|
2265
2266
|
registerUpdateDeal: () => registerUpdateDeal
|
|
2266
2267
|
});
|
|
2267
|
-
const DATA_DIR$
|
|
2268
|
-
async function handleUpdateDeal(input, dataDir = DATA_DIR$
|
|
2268
|
+
const DATA_DIR$49 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2269
|
+
async function handleUpdateDeal(input, dataDir = DATA_DIR$49) {
|
|
2269
2270
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2270
2271
|
const deal = {
|
|
2271
2272
|
name: input.dealName,
|
|
@@ -2348,12 +2349,12 @@ Returns: { success: boolean, deal: object }`,
|
|
|
2348
2349
|
}
|
|
2349
2350
|
//#endregion
|
|
2350
2351
|
//#region src/mcp/tools/export-customer.ts
|
|
2351
|
-
const DATA_DIR$
|
|
2352
|
+
const DATA_DIR$48 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2352
2353
|
function countInteractions(content) {
|
|
2353
2354
|
const matches = content.match(/^## \d{4}-\d{2}-\d{2}/gm);
|
|
2354
2355
|
return matches ? matches.length : 0;
|
|
2355
2356
|
}
|
|
2356
|
-
async function handleExportCustomer(input, dataDir = DATA_DIR$
|
|
2357
|
+
async function handleExportCustomer(input, dataDir = DATA_DIR$48) {
|
|
2357
2358
|
require_session_store.enforceRbac(dataDir, "export_customer");
|
|
2358
2359
|
const customerDir = path.default.join(dataDir, "customers", input.slug);
|
|
2359
2360
|
if (!fs.default.existsSync(customerDir)) return {
|
|
@@ -2466,8 +2467,8 @@ Returns:
|
|
|
2466
2467
|
}
|
|
2467
2468
|
//#endregion
|
|
2468
2469
|
//#region src/mcp/tools/update-customer-facts.ts
|
|
2469
|
-
const DATA_DIR$
|
|
2470
|
-
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$
|
|
2470
|
+
const DATA_DIR$47 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2471
|
+
async function handleUpdateCustomerFacts(input, dataDir = DATA_DIR$47) {
|
|
2471
2472
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2472
2473
|
try {
|
|
2473
2474
|
require_session_store.enforceRbac(dataDir, "update_customer_facts");
|
|
@@ -2645,8 +2646,8 @@ function scoreDealForToday(deal, todayDate) {
|
|
|
2645
2646
|
}
|
|
2646
2647
|
//#endregion
|
|
2647
2648
|
//#region src/mcp/tools/get-deal-health.ts
|
|
2648
|
-
const DATA_DIR$
|
|
2649
|
-
async function handleGetDealHealth(input, dataDir = DATA_DIR$
|
|
2649
|
+
const DATA_DIR$46 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2650
|
+
async function handleGetDealHealth(input, dataDir = DATA_DIR$46) {
|
|
2650
2651
|
try {
|
|
2651
2652
|
const deals = await require_pipeline_writer.readPipeline(dataDir, input.slug);
|
|
2652
2653
|
const today = /* @__PURE__ */ new Date();
|
|
@@ -2695,8 +2696,8 @@ Returns: { slug, deals: [{ deal, stage, score, grade, signals, warnings }] }`,
|
|
|
2695
2696
|
}
|
|
2696
2697
|
//#endregion
|
|
2697
2698
|
//#region src/mcp/tools/get-pipeline-forecast.ts
|
|
2698
|
-
const DATA_DIR$
|
|
2699
|
-
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$
|
|
2699
|
+
const DATA_DIR$45 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2700
|
+
async function handleGetPipelineForecast(input, dataDir = DATA_DIR$45) {
|
|
2700
2701
|
try {
|
|
2701
2702
|
const slugs = require_session_store.listCustomerSlugs(dataDir).filter((d) => !input.filter || d.includes(input.filter));
|
|
2702
2703
|
const allDeals = [];
|
|
@@ -2757,8 +2758,8 @@ Returns: { deals: [...], totalWeightedValue: number, byStage: { stage: { count,
|
|
|
2757
2758
|
}
|
|
2758
2759
|
//#endregion
|
|
2759
2760
|
//#region src/mcp/tools/summarize-meeting.ts
|
|
2760
|
-
const DATA_DIR$
|
|
2761
|
-
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$
|
|
2761
|
+
const DATA_DIR$44 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2762
|
+
async function handleSummarizeMeeting(input, dataDir = DATA_DIR$44) {
|
|
2762
2763
|
try {
|
|
2763
2764
|
let summary = input.transcript.slice(0, 400);
|
|
2764
2765
|
let nextSteps = [];
|
|
@@ -2881,8 +2882,8 @@ function getPipelineStages(dataDir) {
|
|
|
2881
2882
|
}
|
|
2882
2883
|
//#endregion
|
|
2883
2884
|
//#region src/mcp/tools/get-pipeline-stages.ts
|
|
2884
|
-
const DATA_DIR$
|
|
2885
|
-
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$
|
|
2885
|
+
const DATA_DIR$43 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2886
|
+
async function handleGetPipelineStages(_input, dataDir = DATA_DIR$43) {
|
|
2886
2887
|
const stages = getPipelineStages(dataDir);
|
|
2887
2888
|
return { content: [{
|
|
2888
2889
|
type: "text",
|
|
@@ -2910,8 +2911,8 @@ async function searchAcrossCustomers(dataDir, query, limit = 5, excludeSlug) {
|
|
|
2910
2911
|
}
|
|
2911
2912
|
//#endregion
|
|
2912
2913
|
//#region src/mcp/tools/get-market-intelligence.ts
|
|
2913
|
-
const DATA_DIR$
|
|
2914
|
-
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$
|
|
2914
|
+
const DATA_DIR$42 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2915
|
+
async function handleGetMarketIntelligence(input, dataDir = DATA_DIR$42) {
|
|
2915
2916
|
const excludeSlug = input.excludeCurrentCustomer ? input.slug : void 0;
|
|
2916
2917
|
const all = require_session_store.listCustomerSlugs(dataDir);
|
|
2917
2918
|
const totalCustomersSearched = excludeSlug ? all.filter((s) => s !== excludeSlug).length : all.length;
|
|
@@ -2942,7 +2943,7 @@ function registerGetMarketIntelligence(server) {
|
|
|
2942
2943
|
}
|
|
2943
2944
|
//#endregion
|
|
2944
2945
|
//#region src/mcp/tools/get-relationship-graph.ts
|
|
2945
|
-
const DATA_DIR$
|
|
2946
|
+
const DATA_DIR$41 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2946
2947
|
function summarizeNode(n) {
|
|
2947
2948
|
return {
|
|
2948
2949
|
id: n.id,
|
|
@@ -2950,7 +2951,7 @@ function summarizeNode(n) {
|
|
|
2950
2951
|
email: n.properties["email"]
|
|
2951
2952
|
};
|
|
2952
2953
|
}
|
|
2953
|
-
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$
|
|
2954
|
+
async function handleGetRelationshipGraph(input, dataDir = DATA_DIR$41) {
|
|
2954
2955
|
try {
|
|
2955
2956
|
const graph = readGraph(dataDir, input.slug);
|
|
2956
2957
|
const stakeholders = getStakeholders(graph);
|
|
@@ -3018,9 +3019,9 @@ Returns: {
|
|
|
3018
3019
|
}
|
|
3019
3020
|
//#endregion
|
|
3020
3021
|
//#region src/mcp/tools/get-relationship-health.ts
|
|
3021
|
-
const DATA_DIR$
|
|
3022
|
+
const DATA_DIR$40 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3022
3023
|
const MAX_HEALTH_AGE_MS = 3600 * 1e3;
|
|
3023
|
-
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$
|
|
3024
|
+
async function handleGetRelationshipHealth(input, dataDir = DATA_DIR$40) {
|
|
3024
3025
|
try {
|
|
3025
3026
|
let health = readHealth(dataDir, input.slug);
|
|
3026
3027
|
if (health === null || Date.now() - new Date(health.updatedAt).getTime() > MAX_HEALTH_AGE_MS) {
|
|
@@ -3689,8 +3690,8 @@ async function runDealAgent(config, dataDir, llmFn = require_llm.callLlm) {
|
|
|
3689
3690
|
}
|
|
3690
3691
|
//#endregion
|
|
3691
3692
|
//#region src/mcp/tools/run-deal-agent.ts
|
|
3692
|
-
const DATA_DIR$
|
|
3693
|
-
async function handleRunDealAgent(input, dataDir = DATA_DIR$
|
|
3693
|
+
const DATA_DIR$39 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3694
|
+
async function handleRunDealAgent(input, dataDir = DATA_DIR$39) {
|
|
3694
3695
|
try {
|
|
3695
3696
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3696
3697
|
const result = await runDealAgent({
|
|
@@ -3757,8 +3758,8 @@ Returns: { assessment, riskLevel, plan[], actionsQueued[], actionsExecuted[], tr
|
|
|
3757
3758
|
}
|
|
3758
3759
|
//#endregion
|
|
3759
3760
|
//#region src/mcp/tools/approve-agent-action.ts
|
|
3760
|
-
const DATA_DIR$
|
|
3761
|
-
async function handleApproveAgentAction(input, dataDir = DATA_DIR$
|
|
3761
|
+
const DATA_DIR$38 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
3762
|
+
async function handleApproveAgentAction(input, dataDir = DATA_DIR$38) {
|
|
3762
3763
|
try {
|
|
3763
3764
|
const queue = readAgentQueue(dataDir, input.slug);
|
|
3764
3765
|
const idx = queue.pendingActions.findIndex((a) => a.actionId === input.actionId);
|
|
@@ -4018,8 +4019,8 @@ async function buildSimulationInput(dataDir, horizon, today, externalSignals = [
|
|
|
4018
4019
|
}
|
|
4019
4020
|
//#endregion
|
|
4020
4021
|
//#region src/mcp/tools/simulate-revenue.ts
|
|
4021
|
-
const DATA_DIR$
|
|
4022
|
-
async function handleSimulateRevenue(input, dataDir = DATA_DIR$
|
|
4022
|
+
const DATA_DIR$37 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4023
|
+
async function handleSimulateRevenue(input, dataDir = DATA_DIR$37) {
|
|
4023
4024
|
try {
|
|
4024
4025
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4025
4026
|
const horizon = input.horizon ?? "quarter";
|
|
@@ -4077,8 +4078,8 @@ Returns: { forecast: { p10, p50, p90, expected, stdDev, atRiskRevenue, byCloseMo
|
|
|
4077
4078
|
}
|
|
4078
4079
|
//#endregion
|
|
4079
4080
|
//#region src/mcp/tools/get-playbook.ts
|
|
4080
|
-
const DATA_DIR$
|
|
4081
|
-
async function handleGetPlaybook(input, dataDir = DATA_DIR$
|
|
4081
|
+
const DATA_DIR$36 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4082
|
+
async function handleGetPlaybook(input, dataDir = DATA_DIR$36) {
|
|
4082
4083
|
try {
|
|
4083
4084
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
4084
4085
|
if (!(input.stage !== void 0 || input.value !== void 0 || input.healthScore !== void 0)) return { content: [{
|
|
@@ -4163,12 +4164,12 @@ Returns: { matches: [{ name, score, trigger, successRate, usedCount, content }],
|
|
|
4163
4164
|
...healthScore !== void 0 ? { healthScore } : {},
|
|
4164
4165
|
...daysSinceContact !== void 0 ? { daysSinceContact } : {},
|
|
4165
4166
|
...championPresent !== void 0 ? { championPresent } : {}
|
|
4166
|
-
}, DATA_DIR$
|
|
4167
|
+
}, DATA_DIR$36));
|
|
4167
4168
|
}
|
|
4168
4169
|
//#endregion
|
|
4169
4170
|
//#region src/mcp/tools/create-playbook.ts
|
|
4170
|
-
const DATA_DIR$
|
|
4171
|
-
async function handleCreatePlaybook(input, dataDir = DATA_DIR$
|
|
4171
|
+
const DATA_DIR$35 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4172
|
+
async function handleCreatePlaybook(input, dataDir = DATA_DIR$35) {
|
|
4172
4173
|
try {
|
|
4173
4174
|
const name = toKebabCase(input.name);
|
|
4174
4175
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -4241,12 +4242,12 @@ Returns: { success: true, playbook: { name, trigger, successRate, path } }`,
|
|
|
4241
4242
|
trigger,
|
|
4242
4243
|
content,
|
|
4243
4244
|
...successRate !== void 0 ? { successRate } : {}
|
|
4244
|
-
}, DATA_DIR$
|
|
4245
|
+
}, DATA_DIR$35));
|
|
4245
4246
|
}
|
|
4246
4247
|
//#endregion
|
|
4247
4248
|
//#region src/mcp/tools/list-playbooks.ts
|
|
4248
|
-
const DATA_DIR$
|
|
4249
|
-
async function handleListPlaybooks(input, dataDir = DATA_DIR$
|
|
4249
|
+
const DATA_DIR$34 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4250
|
+
async function handleListPlaybooks(input, dataDir = DATA_DIR$34) {
|
|
4250
4251
|
try {
|
|
4251
4252
|
const playbooks = listPlaybooks(dataDir, input.slug);
|
|
4252
4253
|
return { content: [{
|
|
@@ -4285,12 +4286,12 @@ Args:
|
|
|
4285
4286
|
|
|
4286
4287
|
Returns: { playbooks: [{ name, trigger, successRate, usedCount, lastUpdated }], count, slug }`,
|
|
4287
4288
|
inputSchema: zod.z.object({ slug: zod.z.string().describe("Customer ID") })
|
|
4288
|
-
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$
|
|
4289
|
+
}, async ({ slug }) => handleListPlaybooks({ slug }, DATA_DIR$34));
|
|
4289
4290
|
}
|
|
4290
4291
|
//#endregion
|
|
4291
4292
|
//#region src/mcp/tools/distill-playbook.ts
|
|
4292
|
-
const DATA_DIR$
|
|
4293
|
-
async function handleDistillPlaybook(input, dataDir = DATA_DIR$
|
|
4293
|
+
const DATA_DIR$33 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4294
|
+
async function handleDistillPlaybook(input, dataDir = DATA_DIR$33, llmFn = require_llm.callLlm) {
|
|
4294
4295
|
try {
|
|
4295
4296
|
const result = await distillPlaybook(dataDir, input.slug, input.dealName, input.outcome, llmFn);
|
|
4296
4297
|
if (!result.ok) {
|
|
@@ -4349,7 +4350,7 @@ Returns: { success: true, playbook: { name, trigger, successRate, path }, reason
|
|
|
4349
4350
|
slug,
|
|
4350
4351
|
dealName,
|
|
4351
4352
|
outcome
|
|
4352
|
-
}, DATA_DIR$
|
|
4353
|
+
}, DATA_DIR$33));
|
|
4353
4354
|
}
|
|
4354
4355
|
//#endregion
|
|
4355
4356
|
//#region src/core/goal-engine.ts
|
|
@@ -4567,8 +4568,8 @@ function getActiveGoals(dataDir) {
|
|
|
4567
4568
|
}
|
|
4568
4569
|
//#endregion
|
|
4569
4570
|
//#region src/mcp/tools/pursue-goal.ts
|
|
4570
|
-
const DATA_DIR$
|
|
4571
|
-
async function handlePursueGoal(input, dataDir = DATA_DIR$
|
|
4571
|
+
const DATA_DIR$32 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4572
|
+
async function handlePursueGoal(input, dataDir = DATA_DIR$32, options = {}) {
|
|
4572
4573
|
try {
|
|
4573
4574
|
require_session_store.enforceRbac(dataDir, "pursue_goal");
|
|
4574
4575
|
const goal = await pursueGoal(dataDir, {
|
|
@@ -4631,12 +4632,12 @@ Returns: { goalId, description, target, deadline, decomposition: { analysis, cur
|
|
|
4631
4632
|
goal,
|
|
4632
4633
|
deadline,
|
|
4633
4634
|
...context !== void 0 ? { context } : {}
|
|
4634
|
-
}, DATA_DIR$
|
|
4635
|
+
}, DATA_DIR$32));
|
|
4635
4636
|
}
|
|
4636
4637
|
//#endregion
|
|
4637
4638
|
//#region src/mcp/tools/get-goal-status.ts
|
|
4638
|
-
const DATA_DIR$
|
|
4639
|
-
async function handleGetGoalStatus(input, dataDir = DATA_DIR$
|
|
4639
|
+
const DATA_DIR$31 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4640
|
+
async function handleGetGoalStatus(input, dataDir = DATA_DIR$31) {
|
|
4640
4641
|
try {
|
|
4641
4642
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4642
4643
|
const allGoals = input.goalId ? readGoals(dataDir).filter((g) => g.id === input.goalId) : getActiveGoals(dataDir);
|
|
@@ -4695,17 +4696,17 @@ Args:
|
|
|
4695
4696
|
|
|
4696
4697
|
Returns: { goals: [{ id, description, target, progress, status, deadline, daysRemaining, subGoals }], activeCount, completedCount }`,
|
|
4697
4698
|
inputSchema: zod.z.object({ goalId: zod.z.string().optional().describe("Specific goal ID (omit for all active goals)") })
|
|
4698
|
-
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$
|
|
4699
|
+
}, async ({ goalId }) => handleGetGoalStatus({ ...goalId !== void 0 ? { goalId } : {} }, DATA_DIR$31));
|
|
4699
4700
|
}
|
|
4700
4701
|
//#endregion
|
|
4701
4702
|
//#region src/mcp/tools/register-push-subscription.ts
|
|
4702
|
-
const DATA_DIR$
|
|
4703
|
+
const DATA_DIR$30 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4703
4704
|
const VALID_PROVIDERS = [
|
|
4704
4705
|
"gmail",
|
|
4705
4706
|
"microsoft-graph",
|
|
4706
4707
|
"slack"
|
|
4707
4708
|
];
|
|
4708
|
-
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$
|
|
4709
|
+
async function handleRegisterPushSubscription(input, dataDir = DATA_DIR$30) {
|
|
4709
4710
|
try {
|
|
4710
4711
|
if (!VALID_PROVIDERS.includes(input.provider)) return { content: [{
|
|
4711
4712
|
type: "text",
|
|
@@ -4791,12 +4792,12 @@ Returns: { subscriptionId, provider, slug, status, expiresAt, createdAt, warning
|
|
|
4791
4792
|
...microsoftResource !== void 0 ? { microsoftResource } : {},
|
|
4792
4793
|
...slackTeamId !== void 0 ? { slackTeamId } : {},
|
|
4793
4794
|
...slackChannelId !== void 0 ? { slackChannelId } : {}
|
|
4794
|
-
}, DATA_DIR$
|
|
4795
|
+
}, DATA_DIR$30));
|
|
4795
4796
|
}
|
|
4796
4797
|
//#endregion
|
|
4797
4798
|
//#region src/mcp/tools/get-push-status.ts
|
|
4798
|
-
const DATA_DIR$
|
|
4799
|
-
async function handleGetPushStatus(input, dataDir = DATA_DIR$
|
|
4799
|
+
const DATA_DIR$29 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4800
|
+
async function handleGetPushStatus(input, dataDir = DATA_DIR$29) {
|
|
4800
4801
|
try {
|
|
4801
4802
|
let subs = await readSubscriptions(dataDir);
|
|
4802
4803
|
if (input.slug) subs = subs.filter((s) => s.slug === input.slug);
|
|
@@ -4868,7 +4869,7 @@ Returns: { subscriptions: [{ id, provider, slug, status, expiresAt, expiresInHou
|
|
|
4868
4869
|
}, async ({ slug, provider }) => handleGetPushStatus({
|
|
4869
4870
|
...slug !== void 0 ? { slug } : {},
|
|
4870
4871
|
...provider !== void 0 ? { provider } : {}
|
|
4871
|
-
}, DATA_DIR$
|
|
4872
|
+
}, DATA_DIR$29));
|
|
4872
4873
|
}
|
|
4873
4874
|
//#endregion
|
|
4874
4875
|
//#region src/core/org-intelligence.ts
|
|
@@ -4934,8 +4935,8 @@ function deriveRecommendation(people, missingRoles) {
|
|
|
4934
4935
|
}
|
|
4935
4936
|
//#endregion
|
|
4936
4937
|
//#region src/mcp/tools/get-org-intelligence.ts
|
|
4937
|
-
const DATA_DIR$
|
|
4938
|
-
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$
|
|
4938
|
+
const DATA_DIR$28 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
4939
|
+
async function handleGetOrgIntelligence(input, dataDir = DATA_DIR$28) {
|
|
4939
4940
|
try {
|
|
4940
4941
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4941
4942
|
const map = buildStakeholderMap(dataDir, input.slug, today, input.dealName);
|
|
@@ -5068,8 +5069,8 @@ function buildExecutiveSummary(slug, dealName, stakeholders, overallHealth, sim,
|
|
|
5068
5069
|
}
|
|
5069
5070
|
//#endregion
|
|
5070
5071
|
//#region src/mcp/tools/open-deal-room.ts
|
|
5071
|
-
const DATA_DIR$
|
|
5072
|
-
async function handleOpenDealRoom(input, dataDir = DATA_DIR$
|
|
5072
|
+
const DATA_DIR$27 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5073
|
+
async function handleOpenDealRoom(input, dataDir = DATA_DIR$27) {
|
|
5073
5074
|
try {
|
|
5074
5075
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5075
5076
|
const brief = await buildDealRoom(dataDir, input.slug, input.dealName, today);
|
|
@@ -5152,8 +5153,8 @@ async function buildDailyBriefing(dataDir, today) {
|
|
|
5152
5153
|
}
|
|
5153
5154
|
//#endregion
|
|
5154
5155
|
//#region src/mcp/tools/get-proactive-briefing.ts
|
|
5155
|
-
const DATA_DIR$
|
|
5156
|
-
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$
|
|
5156
|
+
const DATA_DIR$26 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5157
|
+
async function handleGetProactiveBriefing(input, dataDir = DATA_DIR$26) {
|
|
5157
5158
|
try {
|
|
5158
5159
|
const briefing = await buildDailyBriefing(dataDir, input.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
|
|
5159
5160
|
return { content: [{
|
|
@@ -5253,15 +5254,15 @@ function getTemplate(dataDir, id) {
|
|
|
5253
5254
|
}
|
|
5254
5255
|
//#endregion
|
|
5255
5256
|
//#region src/mcp/tools/list-email-templates.ts
|
|
5256
|
-
const DATA_DIR$
|
|
5257
|
-
async function handleListEmailTemplates(input, dataDir = DATA_DIR$
|
|
5257
|
+
const DATA_DIR$25 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5258
|
+
async function handleListEmailTemplates(input, dataDir = DATA_DIR$25) {
|
|
5258
5259
|
const summary = listTemplates(dataDir, input.category ? { category: input.category } : {}).map(({ body: _body, ...meta }) => meta);
|
|
5259
5260
|
return { content: [{
|
|
5260
5261
|
type: "text",
|
|
5261
5262
|
text: JSON.stringify(summary, null, 2)
|
|
5262
5263
|
}] };
|
|
5263
5264
|
}
|
|
5264
|
-
function registerListEmailTemplates(server, dataDir = DATA_DIR$
|
|
5265
|
+
function registerListEmailTemplates(server, dataDir = DATA_DIR$25) {
|
|
5265
5266
|
server.registerTool("list_email_templates", {
|
|
5266
5267
|
description: "List available email templates. Optionally filter by category (e.g. 'outreach', 'followup', 'support').",
|
|
5267
5268
|
inputSchema: zod.z.object({ category: zod.z.string().optional().describe("Filter by category") })
|
|
@@ -5295,8 +5296,8 @@ async function buildVariablesFromCustomer(dataDir, slug) {
|
|
|
5295
5296
|
}
|
|
5296
5297
|
//#endregion
|
|
5297
5298
|
//#region src/mcp/tools/get-email-template.ts
|
|
5298
|
-
const DATA_DIR$
|
|
5299
|
-
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$
|
|
5299
|
+
const DATA_DIR$24 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5300
|
+
async function handleGetEmailTemplate(input, dataDir = DATA_DIR$24) {
|
|
5300
5301
|
const tmpl = getTemplate(dataDir, input.id);
|
|
5301
5302
|
if (!tmpl) return { content: [{
|
|
5302
5303
|
type: "text",
|
|
@@ -5312,7 +5313,7 @@ async function handleGetEmailTemplate(input, dataDir = DATA_DIR$23) {
|
|
|
5312
5313
|
}, null, 2)
|
|
5313
5314
|
}] };
|
|
5314
5315
|
}
|
|
5315
|
-
function registerGetEmailTemplate(server, dataDir = DATA_DIR$
|
|
5316
|
+
function registerGetEmailTemplate(server, dataDir = DATA_DIR$24) {
|
|
5316
5317
|
server.registerTool("get_email_template", {
|
|
5317
5318
|
description: "Get a specific email template by ID, including its body and detected variables.",
|
|
5318
5319
|
inputSchema: zod.z.object({ id: zod.z.string().describe("Template ID (e.g. 'enterprise-intro')") })
|
|
@@ -5320,8 +5321,8 @@ function registerGetEmailTemplate(server, dataDir = DATA_DIR$23) {
|
|
|
5320
5321
|
}
|
|
5321
5322
|
//#endregion
|
|
5322
5323
|
//#region src/mcp/tools/draft-email.ts
|
|
5323
|
-
const DATA_DIR$
|
|
5324
|
-
async function handleDraftEmail(input, dataDir = DATA_DIR$
|
|
5324
|
+
const DATA_DIR$23 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5325
|
+
async function handleDraftEmail(input, dataDir = DATA_DIR$23) {
|
|
5325
5326
|
const tmpl = getTemplate(dataDir, input.templateId);
|
|
5326
5327
|
if (!tmpl) return { content: [{
|
|
5327
5328
|
type: "text",
|
|
@@ -5365,7 +5366,7 @@ async function handleDraftEmail(input, dataDir = DATA_DIR$22) {
|
|
|
5365
5366
|
}, null, 2)
|
|
5366
5367
|
}] };
|
|
5367
5368
|
}
|
|
5368
|
-
function registerDraftEmail(server, dataDir = DATA_DIR$
|
|
5369
|
+
function registerDraftEmail(server, dataDir = DATA_DIR$23) {
|
|
5369
5370
|
server.registerTool("draft_email", {
|
|
5370
5371
|
description: `Draft a personalized email for a customer using a stored template.
|
|
5371
5372
|
Variables are auto-filled from the customer's main_facts.md. Override any variable manually.
|
|
@@ -5473,8 +5474,8 @@ async function updateEnrollment(dataDir, id, updates) {
|
|
|
5473
5474
|
}
|
|
5474
5475
|
//#endregion
|
|
5475
5476
|
//#region src/mcp/tools/enroll-in-sequence.ts
|
|
5476
|
-
const DATA_DIR$
|
|
5477
|
-
async function handleEnrollInSequence(input, dataDir = DATA_DIR$
|
|
5477
|
+
const DATA_DIR$22 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5478
|
+
async function handleEnrollInSequence(input, dataDir = DATA_DIR$22) {
|
|
5478
5479
|
const sequence = getSequence(dataDir, input.sequenceId);
|
|
5479
5480
|
if (!sequence) return { content: [{
|
|
5480
5481
|
type: "text",
|
|
@@ -5506,7 +5507,7 @@ async function handleEnrollInSequence(input, dataDir = DATA_DIR$21) {
|
|
|
5506
5507
|
})
|
|
5507
5508
|
}] };
|
|
5508
5509
|
}
|
|
5509
|
-
function registerEnrollInSequence(server, dataDir = DATA_DIR$
|
|
5510
|
+
function registerEnrollInSequence(server, dataDir = DATA_DIR$22) {
|
|
5510
5511
|
server.registerTool("enroll_in_sequence", {
|
|
5511
5512
|
description: `Enroll a contact in an email sequence. Validates that the sequence and its first template exist.
|
|
5512
5513
|
Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
@@ -5523,8 +5524,8 @@ Returns: { enrollmentId, sequenceName, totalSteps }`,
|
|
|
5523
5524
|
}
|
|
5524
5525
|
//#endregion
|
|
5525
5526
|
//#region src/mcp/tools/list-sequence-enrollments.ts
|
|
5526
|
-
const DATA_DIR$
|
|
5527
|
-
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$
|
|
5527
|
+
const DATA_DIR$21 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5528
|
+
async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$21) {
|
|
5528
5529
|
let enrollments = readEnrollments(dataDir);
|
|
5529
5530
|
if (input.slug !== void 0) enrollments = enrollments.filter((e) => e.slug === input.slug);
|
|
5530
5531
|
if (input.status !== void 0) enrollments = enrollments.filter((e) => e.status === input.status);
|
|
@@ -5533,7 +5534,7 @@ async function handleListSequenceEnrollments(input, dataDir = DATA_DIR$20) {
|
|
|
5533
5534
|
text: JSON.stringify({ enrollments }, null, 2)
|
|
5534
5535
|
}] };
|
|
5535
5536
|
}
|
|
5536
|
-
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$
|
|
5537
|
+
function registerListSequenceEnrollments(server, dataDir = DATA_DIR$21) {
|
|
5537
5538
|
server.registerTool("list_sequence_enrollments", {
|
|
5538
5539
|
description: `List email sequence enrollments. Filter by customer slug or status.
|
|
5539
5540
|
Returns: { enrollments: SequenceEnrollment[] }`,
|
|
@@ -5552,8 +5553,8 @@ Returns: { enrollments: SequenceEnrollment[] }`,
|
|
|
5552
5553
|
}
|
|
5553
5554
|
//#endregion
|
|
5554
5555
|
//#region src/mcp/tools/unenroll-from-sequence.ts
|
|
5555
|
-
const DATA_DIR$
|
|
5556
|
-
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$
|
|
5556
|
+
const DATA_DIR$20 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5557
|
+
async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$20) {
|
|
5557
5558
|
if (!await updateEnrollment(dataDir, input.enrollmentId, { status: "paused" })) return { content: [{
|
|
5558
5559
|
type: "text",
|
|
5559
5560
|
text: JSON.stringify({
|
|
@@ -5566,7 +5567,7 @@ async function handleUnenrollFromSequence(input, dataDir = DATA_DIR$19) {
|
|
|
5566
5567
|
text: JSON.stringify({ success: true })
|
|
5567
5568
|
}] };
|
|
5568
5569
|
}
|
|
5569
|
-
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$
|
|
5570
|
+
function registerUnenrollFromSequence(server, dataDir = DATA_DIR$20) {
|
|
5570
5571
|
server.registerTool("unenroll_from_sequence", {
|
|
5571
5572
|
description: `Unenroll (pause) a contact from an email sequence. Sets status to "paused" (soft delete).
|
|
5572
5573
|
Returns: { success: boolean }`,
|
|
@@ -5575,8 +5576,8 @@ Returns: { success: boolean }`,
|
|
|
5575
5576
|
}
|
|
5576
5577
|
//#endregion
|
|
5577
5578
|
//#region src/mcp/tools/list-sequences.ts
|
|
5578
|
-
const DATA_DIR$
|
|
5579
|
-
async function handleListSequences(_input, dataDir = DATA_DIR$
|
|
5579
|
+
const DATA_DIR$19 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5580
|
+
async function handleListSequences(_input, dataDir = DATA_DIR$19) {
|
|
5580
5581
|
const sequences = listSequences(dataDir);
|
|
5581
5582
|
const enrollments = readEnrollments(dataDir);
|
|
5582
5583
|
const result = sequences.map((seq) => ({
|
|
@@ -5590,7 +5591,7 @@ async function handleListSequences(_input, dataDir = DATA_DIR$18) {
|
|
|
5590
5591
|
text: JSON.stringify({ sequences: result }, null, 2)
|
|
5591
5592
|
}] };
|
|
5592
5593
|
}
|
|
5593
|
-
function registerListSequences(server, dataDir = DATA_DIR$
|
|
5594
|
+
function registerListSequences(server, dataDir = DATA_DIR$19) {
|
|
5594
5595
|
server.registerTool("list_sequences", {
|
|
5595
5596
|
description: `List all email sequences with step count and enrollment count.
|
|
5596
5597
|
Returns: { sequences: Array<{ id, name, stepCount, enrollmentCount }> }`,
|
|
@@ -5725,8 +5726,8 @@ async function generateQuote(dataDir, input) {
|
|
|
5725
5726
|
}
|
|
5726
5727
|
//#endregion
|
|
5727
5728
|
//#region src/mcp/tools/generate-quote.ts
|
|
5728
|
-
const DATA_DIR$
|
|
5729
|
-
async function handleGenerateQuote(input, dataDir = DATA_DIR$
|
|
5729
|
+
const DATA_DIR$18 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5730
|
+
async function handleGenerateQuote(input, dataDir = DATA_DIR$18) {
|
|
5730
5731
|
try {
|
|
5731
5732
|
const quote = await generateQuote(dataDir, input);
|
|
5732
5733
|
return { content: [{
|
|
@@ -5750,7 +5751,7 @@ async function handleGenerateQuote(input, dataDir = DATA_DIR$17) {
|
|
|
5750
5751
|
}] };
|
|
5751
5752
|
}
|
|
5752
5753
|
}
|
|
5753
|
-
function registerGenerateQuote(server, dataDir = DATA_DIR$
|
|
5754
|
+
function registerGenerateQuote(server, dataDir = DATA_DIR$18) {
|
|
5754
5755
|
server.registerTool("generate_quote", {
|
|
5755
5756
|
description: `Generate a professional HTML quote/offer for a customer deal.
|
|
5756
5757
|
Calculates subtotal, VAT, and total. Saves JSON + HTML to .agentic/quotes/.
|
|
@@ -5778,8 +5779,8 @@ Returns: { quoteNumber, htmlPath, total, currency, validUntil }`,
|
|
|
5778
5779
|
}
|
|
5779
5780
|
//#endregion
|
|
5780
5781
|
//#region src/mcp/tools/get-quote-status.ts
|
|
5781
|
-
const DATA_DIR$
|
|
5782
|
-
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$
|
|
5782
|
+
const DATA_DIR$17 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5783
|
+
async function handleGetQuoteStatus(input, dataDir = DATA_DIR$17) {
|
|
5783
5784
|
if (input.quoteNumber) {
|
|
5784
5785
|
const quote = readQuote(dataDir, input.quoteNumber);
|
|
5785
5786
|
if (!quote) return { content: [{
|
|
@@ -5797,7 +5798,7 @@ async function handleGetQuoteStatus(input, dataDir = DATA_DIR$16) {
|
|
|
5797
5798
|
text: JSON.stringify({ quotes }, null, 2)
|
|
5798
5799
|
}] };
|
|
5799
5800
|
}
|
|
5800
|
-
function registerGetQuoteStatus(server, dataDir = DATA_DIR$
|
|
5801
|
+
function registerGetQuoteStatus(server, dataDir = DATA_DIR$17) {
|
|
5801
5802
|
server.registerTool("get_quote_status", {
|
|
5802
5803
|
description: `Get quote status and details. Filter by quoteNumber (single quote) or slug (all quotes for a customer).
|
|
5803
5804
|
Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
@@ -5812,7 +5813,7 @@ Returns quote with status: draft | sent | viewed | accepted | declined`,
|
|
|
5812
5813
|
}
|
|
5813
5814
|
//#endregion
|
|
5814
5815
|
//#region src/mcp/tools/get-booking-link.ts
|
|
5815
|
-
const DATA_DIR$
|
|
5816
|
+
const DATA_DIR$16 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
5816
5817
|
function loadCalendlyConfig(dataDir) {
|
|
5817
5818
|
const p = path.default.join(dataDir, ".agentic", "integrations", "calendly.yaml");
|
|
5818
5819
|
if (!fs.default.existsSync(p)) return {};
|
|
@@ -5835,7 +5836,7 @@ function readCustomerFacts(dataDir, slug) {
|
|
|
5835
5836
|
...email ? { email } : {}
|
|
5836
5837
|
};
|
|
5837
5838
|
}
|
|
5838
|
-
async function handleGetBookingLink(input, dataDir = DATA_DIR$
|
|
5839
|
+
async function handleGetBookingLink(input, dataDir = DATA_DIR$16) {
|
|
5839
5840
|
const config = loadCalendlyConfig(dataDir);
|
|
5840
5841
|
const apiKey = config.apiKey ?? process.env["CALENDLY_API_KEY"] ?? "";
|
|
5841
5842
|
if (!apiKey) return { content: [{
|
|
@@ -5863,7 +5864,7 @@ async function handleGetBookingLink(input, dataDir = DATA_DIR$15) {
|
|
|
5863
5864
|
}] };
|
|
5864
5865
|
}
|
|
5865
5866
|
}
|
|
5866
|
-
function registerGetBookingLink(server, dataDir = DATA_DIR$
|
|
5867
|
+
function registerGetBookingLink(server, dataDir = DATA_DIR$16) {
|
|
5867
5868
|
server.registerTool("get_booking_link", {
|
|
5868
5869
|
description: `Get a Calendly booking link for a customer. Optionally pre-fills the customer's name/email.
|
|
5869
5870
|
Requires CALENDLY_API_KEY env var or .agentic/integrations/calendly.yaml config.
|
|
@@ -6033,8 +6034,8 @@ function calcSlaDue(createdDate, priority, rules) {
|
|
|
6033
6034
|
}
|
|
6034
6035
|
//#endregion
|
|
6035
6036
|
//#region src/mcp/tools/create-ticket.ts
|
|
6036
|
-
const DATA_DIR$
|
|
6037
|
-
async function handleCreateTicket(input, dataDir = DATA_DIR$
|
|
6037
|
+
const DATA_DIR$15 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6038
|
+
async function handleCreateTicket(input, dataDir = DATA_DIR$15) {
|
|
6038
6039
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
6039
6040
|
const rules = loadSlaRules(dataDir);
|
|
6040
6041
|
const priority = input.priority ?? "normal";
|
|
@@ -6056,7 +6057,7 @@ async function handleCreateTicket(input, dataDir = DATA_DIR$14) {
|
|
|
6056
6057
|
text: JSON.stringify({ ticket }, null, 2)
|
|
6057
6058
|
}] };
|
|
6058
6059
|
}
|
|
6059
|
-
function registerCreateTicket(server, dataDir = DATA_DIR$
|
|
6060
|
+
function registerCreateTicket(server, dataDir = DATA_DIR$15) {
|
|
6060
6061
|
server.registerTool("create_ticket", {
|
|
6061
6062
|
description: `Create a support ticket for a customer. Auto-calculates SLA due date based on priority.
|
|
6062
6063
|
Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
@@ -6082,8 +6083,8 @@ Returns: { ticket } with id T-NNN, status=open, slaDue`,
|
|
|
6082
6083
|
}
|
|
6083
6084
|
//#endregion
|
|
6084
6085
|
//#region src/mcp/tools/update-ticket.ts
|
|
6085
|
-
const DATA_DIR$
|
|
6086
|
-
async function handleUpdateTicket(input, dataDir = DATA_DIR$
|
|
6086
|
+
const DATA_DIR$14 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6087
|
+
async function handleUpdateTicket(input, dataDir = DATA_DIR$14) {
|
|
6087
6088
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
6088
6089
|
if (!ticket) return { content: [{
|
|
6089
6090
|
type: "text",
|
|
@@ -6102,7 +6103,7 @@ async function handleUpdateTicket(input, dataDir = DATA_DIR$13) {
|
|
|
6102
6103
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
6103
6104
|
}] };
|
|
6104
6105
|
}
|
|
6105
|
-
function registerUpdateTicket(server, dataDir = DATA_DIR$
|
|
6106
|
+
function registerUpdateTicket(server, dataDir = DATA_DIR$14) {
|
|
6106
6107
|
server.registerTool("update_ticket", {
|
|
6107
6108
|
description: `Update a ticket's status or assignee. Setting status=resolved auto-sets resolved date.
|
|
6108
6109
|
Returns: { ticket }`,
|
|
@@ -6127,8 +6128,8 @@ Returns: { ticket }`,
|
|
|
6127
6128
|
}
|
|
6128
6129
|
//#endregion
|
|
6129
6130
|
//#region src/mcp/tools/list-tickets.ts
|
|
6130
|
-
const DATA_DIR$
|
|
6131
|
-
async function handleListTickets(input, dataDir = DATA_DIR$
|
|
6131
|
+
const DATA_DIR$13 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6132
|
+
async function handleListTickets(input, dataDir = DATA_DIR$13) {
|
|
6132
6133
|
const results = await listAllTickets(dataDir, {
|
|
6133
6134
|
...input.slug !== void 0 ? { slug: input.slug } : {},
|
|
6134
6135
|
...input.status !== void 0 ? { status: input.status } : {},
|
|
@@ -6140,7 +6141,7 @@ async function handleListTickets(input, dataDir = DATA_DIR$12) {
|
|
|
6140
6141
|
text: JSON.stringify({ tickets: results }, null, 2)
|
|
6141
6142
|
}] };
|
|
6142
6143
|
}
|
|
6143
|
-
function registerListTickets(server, dataDir = DATA_DIR$
|
|
6144
|
+
function registerListTickets(server, dataDir = DATA_DIR$13) {
|
|
6144
6145
|
server.registerTool("list_tickets", {
|
|
6145
6146
|
description: `List support tickets. Filter by customer, status, priority, or assignee. Sorted by priority then date.
|
|
6146
6147
|
Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
@@ -6170,8 +6171,8 @@ Returns: { tickets: Array<{ slug, ticket }> }`,
|
|
|
6170
6171
|
}
|
|
6171
6172
|
//#endregion
|
|
6172
6173
|
//#region src/mcp/tools/close-ticket.ts
|
|
6173
|
-
const DATA_DIR$
|
|
6174
|
-
async function handleCloseTicket(input, dataDir = DATA_DIR$
|
|
6174
|
+
const DATA_DIR$12 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6175
|
+
async function handleCloseTicket(input, dataDir = DATA_DIR$12) {
|
|
6175
6176
|
const ticket = (await readTickets(dataDir, input.slug)).find((t) => t.id === input.ticketId);
|
|
6176
6177
|
if (!ticket) return { content: [{
|
|
6177
6178
|
type: "text",
|
|
@@ -6198,7 +6199,7 @@ async function handleCloseTicket(input, dataDir = DATA_DIR$11) {
|
|
|
6198
6199
|
text: JSON.stringify({ ticket: updated }, null, 2)
|
|
6199
6200
|
}] };
|
|
6200
6201
|
}
|
|
6201
|
-
function registerCloseTicket(server, dataDir = DATA_DIR$
|
|
6202
|
+
function registerCloseTicket(server, dataDir = DATA_DIR$12) {
|
|
6202
6203
|
server.registerTool("close_ticket", {
|
|
6203
6204
|
description: `Close a support ticket. Optionally logs the resolution as an interaction.
|
|
6204
6205
|
Returns: { ticket } with status=closed`,
|
|
@@ -6352,8 +6353,8 @@ async function savePendingSurvey(dataDir, surveyId, slug, contactEmail, token) {
|
|
|
6352
6353
|
}
|
|
6353
6354
|
//#endregion
|
|
6354
6355
|
//#region src/mcp/tools/send-nps-survey.ts
|
|
6355
|
-
const DATA_DIR$
|
|
6356
|
-
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$
|
|
6356
|
+
const DATA_DIR$11 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6357
|
+
async function handleSendNpsSurvey(input, dataDir = DATA_DIR$11) {
|
|
6357
6358
|
const survey = getSurvey(dataDir, input.surveyId);
|
|
6358
6359
|
if (!survey) return { content: [{
|
|
6359
6360
|
type: "text",
|
|
@@ -6374,7 +6375,7 @@ async function handleSendNpsSurvey(input, dataDir = DATA_DIR$10) {
|
|
|
6374
6375
|
}, null, 2)
|
|
6375
6376
|
}] };
|
|
6376
6377
|
}
|
|
6377
|
-
function registerSendNpsSurvey(server, dataDir = DATA_DIR$
|
|
6378
|
+
function registerSendNpsSurvey(server, dataDir = DATA_DIR$11) {
|
|
6378
6379
|
server.registerTool("send_nps_survey", {
|
|
6379
6380
|
description: `Generate an NPS/CSAT survey email for a customer contact. Returns subject, HTML body, and a token-based response URL.
|
|
6380
6381
|
Does NOT send automatically — returns draft for review.
|
|
@@ -6394,8 +6395,8 @@ Returns: { token, subject, body, surveyUrl }`,
|
|
|
6394
6395
|
}
|
|
6395
6396
|
//#endregion
|
|
6396
6397
|
//#region src/mcp/tools/get-survey-results.ts
|
|
6397
|
-
const DATA_DIR$
|
|
6398
|
-
async function handleGetSurveyResults(input, dataDir = DATA_DIR$
|
|
6398
|
+
const DATA_DIR$10 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6399
|
+
async function handleGetSurveyResults(input, dataDir = DATA_DIR$10) {
|
|
6399
6400
|
const responses = loadSurveyResponses(dataDir, input.surveyId, input.slug);
|
|
6400
6401
|
const nps = calcNpsScore(responses);
|
|
6401
6402
|
const promoters = responses.filter((r) => r.score >= 9).length;
|
|
@@ -6421,7 +6422,7 @@ async function handleGetSurveyResults(input, dataDir = DATA_DIR$9) {
|
|
|
6421
6422
|
}, null, 2)
|
|
6422
6423
|
}] };
|
|
6423
6424
|
}
|
|
6424
|
-
function registerGetSurveyResults(server, dataDir = DATA_DIR$
|
|
6425
|
+
function registerGetSurveyResults(server, dataDir = DATA_DIR$10) {
|
|
6425
6426
|
server.registerTool("get_survey_results", {
|
|
6426
6427
|
description: `Get NPS/CSAT survey results with score breakdown. Calculates Net Promoter Score.
|
|
6427
6428
|
Returns: { npsScore, totalResponses, promoters, passives, detractors, responses[] }`,
|
|
@@ -6522,8 +6523,8 @@ function getKbMetaForExport(article) {
|
|
|
6522
6523
|
}
|
|
6523
6524
|
//#endregion
|
|
6524
6525
|
//#region src/mcp/tools/search-knowledge-base.ts
|
|
6525
|
-
const DATA_DIR$
|
|
6526
|
-
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$
|
|
6526
|
+
const DATA_DIR$9 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6527
|
+
async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$9) {
|
|
6527
6528
|
const results = searchKbSimple(dataDir, input.query, { ...input.publicOnly ? { publicOnly: true } : {} });
|
|
6528
6529
|
const limited = (input.category ? results.filter((a) => a.category === input.category) : results).slice(0, input.limit ?? 10);
|
|
6529
6530
|
return { content: [{
|
|
@@ -6538,7 +6539,7 @@ async function handleSearchKnowledgeBase(input, dataDir = DATA_DIR$8) {
|
|
|
6538
6539
|
}, null, 2)
|
|
6539
6540
|
}] };
|
|
6540
6541
|
}
|
|
6541
|
-
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$
|
|
6542
|
+
function registerSearchKnowledgeBase(server, dataDir = DATA_DIR$9) {
|
|
6542
6543
|
server.registerTool("search_knowledge_base", {
|
|
6543
6544
|
description: `Search the knowledge base for articles. Text search on title, body, and tags.
|
|
6544
6545
|
Returns: { count, articles[] } with excerpts`,
|
|
@@ -6557,8 +6558,8 @@ Returns: { count, articles[] } with excerpts`,
|
|
|
6557
6558
|
}
|
|
6558
6559
|
//#endregion
|
|
6559
6560
|
//#region src/mcp/tools/create-kb-article.ts
|
|
6560
|
-
const DATA_DIR$
|
|
6561
|
-
async function handleCreateKbArticle(input, dataDir = DATA_DIR$
|
|
6561
|
+
const DATA_DIR$8 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6562
|
+
async function handleCreateKbArticle(input, dataDir = DATA_DIR$8) {
|
|
6562
6563
|
if (getKbArticle(dataDir, input.id)) return { content: [{
|
|
6563
6564
|
type: "text",
|
|
6564
6565
|
text: JSON.stringify({ error: `Article '${input.id}' already exists` })
|
|
@@ -6586,7 +6587,7 @@ async function handleCreateKbArticle(input, dataDir = DATA_DIR$7) {
|
|
|
6586
6587
|
}, null, 2)
|
|
6587
6588
|
}] };
|
|
6588
6589
|
}
|
|
6589
|
-
function registerCreateKbArticle(server, dataDir = DATA_DIR$
|
|
6590
|
+
function registerCreateKbArticle(server, dataDir = DATA_DIR$8) {
|
|
6590
6591
|
server.registerTool("create_kb_article", {
|
|
6591
6592
|
description: `Create a new knowledge base article. Articles are stored as Markdown files in .agentic/knowledge-base/.
|
|
6592
6593
|
Returns: { id, title, category, path }`,
|
|
@@ -6611,8 +6612,8 @@ Returns: { id, title, category, path }`,
|
|
|
6611
6612
|
}
|
|
6612
6613
|
//#endregion
|
|
6613
6614
|
//#region src/mcp/tools/backup-now.ts
|
|
6614
|
-
const DATA_DIR$
|
|
6615
|
-
async function handleBackupNow(input, dataDir = DATA_DIR$
|
|
6615
|
+
const DATA_DIR$7 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6616
|
+
async function handleBackupNow(input, dataDir = DATA_DIR$7) {
|
|
6616
6617
|
const zipPath = path.default.join(dataDir, `dxcrm-backup-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.zip`);
|
|
6617
6618
|
const manifest = await require_session_store.runBackup(zipPath, dataDir, { ...input.remote ? { remote: input.remote } : {} }).catch(() => null);
|
|
6618
6619
|
if (!manifest) return { content: [{
|
|
@@ -6649,8 +6650,8 @@ function registerBackupNow(server) {
|
|
|
6649
6650
|
}
|
|
6650
6651
|
//#endregion
|
|
6651
6652
|
//#region src/mcp/tools/list-backups.ts
|
|
6652
|
-
const DATA_DIR$
|
|
6653
|
-
async function handleListBackups(input, dataDir = DATA_DIR$
|
|
6653
|
+
const DATA_DIR$6 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6654
|
+
async function handleListBackups(input, dataDir = DATA_DIR$6) {
|
|
6654
6655
|
const logEntries = require_session_store.readBackupLog(dataDir);
|
|
6655
6656
|
const fileEntries = require_session_store.listBackupsInDir(dataDir);
|
|
6656
6657
|
const entries = logEntries.length > 0 ? logEntries : fileEntries;
|
|
@@ -6684,8 +6685,8 @@ function registerListBackups(server) {
|
|
|
6684
6685
|
}
|
|
6685
6686
|
//#endregion
|
|
6686
6687
|
//#region src/mcp/tools/trigger-sync.ts
|
|
6687
|
-
const DATA_DIR$
|
|
6688
|
-
async function handleTriggerSync(input, dataDir = DATA_DIR$
|
|
6688
|
+
const DATA_DIR$5 = process.cwd();
|
|
6689
|
+
async function handleTriggerSync(input, dataDir = DATA_DIR$5) {
|
|
6689
6690
|
const auth = getGmailAuth();
|
|
6690
6691
|
if (!auth) return { content: [{
|
|
6691
6692
|
type: "text",
|
|
@@ -6779,8 +6780,8 @@ Returns: { success: boolean, synced: number, skipped: number, customers: [...],
|
|
|
6779
6780
|
}
|
|
6780
6781
|
//#endregion
|
|
6781
6782
|
//#region src/mcp/tools/get-audit-log.ts
|
|
6782
|
-
const DATA_DIR$
|
|
6783
|
-
async function handleGetAuditLog(input, dataDir = DATA_DIR$
|
|
6783
|
+
const DATA_DIR$4 = process.cwd();
|
|
6784
|
+
async function handleGetAuditLog(input, dataDir = DATA_DIR$4) {
|
|
6784
6785
|
const entries = require_session_store.readAuditLog(dataDir);
|
|
6785
6786
|
const filterOpts = { limit: input.limit ?? 50 };
|
|
6786
6787
|
if (input.slug !== void 0) filterOpts.slug = input.slug;
|
|
@@ -6822,8 +6823,8 @@ Returns: { total: number, returned: number, entries: [{timestamp, actor, tool, s
|
|
|
6822
6823
|
}
|
|
6823
6824
|
//#endregion
|
|
6824
6825
|
//#region src/mcp/tools/get-logs.ts
|
|
6825
|
-
const DATA_DIR$
|
|
6826
|
-
async function handleGetLogs(input, dataDir = DATA_DIR$
|
|
6826
|
+
const DATA_DIR$3 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6827
|
+
async function handleGetLogs(input, dataDir = DATA_DIR$3) {
|
|
6827
6828
|
const query = {
|
|
6828
6829
|
...input.level !== void 0 ? { level: input.level } : {},
|
|
6829
6830
|
...input.component !== void 0 ? { component: input.component } : {},
|
|
@@ -6884,6 +6885,140 @@ Returns (summary): { total, byLevel, byComponent, firstTs, lastTs, recentErrors
|
|
|
6884
6885
|
});
|
|
6885
6886
|
}
|
|
6886
6887
|
//#endregion
|
|
6888
|
+
//#region src/core/doctor.ts
|
|
6889
|
+
var doctor_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
6890
|
+
cleanupTempFiles: () => cleanupTempFiles,
|
|
6891
|
+
runDiagnostics: () => runDiagnostics
|
|
6892
|
+
});
|
|
6893
|
+
/** Recursively collect files whose name matches the atomic-write temp pattern. */
|
|
6894
|
+
function findOrphanedTempFiles(dir, depth = 0) {
|
|
6895
|
+
if (depth > 3 || !fs.default.existsSync(dir)) return [];
|
|
6896
|
+
const out = [];
|
|
6897
|
+
let entries;
|
|
6898
|
+
try {
|
|
6899
|
+
entries = fs.default.readdirSync(dir);
|
|
6900
|
+
} catch {
|
|
6901
|
+
return [];
|
|
6902
|
+
}
|
|
6903
|
+
for (const entry of entries) {
|
|
6904
|
+
const full = path.default.join(dir, entry);
|
|
6905
|
+
let isDir = false;
|
|
6906
|
+
try {
|
|
6907
|
+
isDir = fs.default.statSync(full).isDirectory();
|
|
6908
|
+
} catch {
|
|
6909
|
+
continue;
|
|
6910
|
+
}
|
|
6911
|
+
if (isDir) out.push(...findOrphanedTempFiles(full, depth + 1));
|
|
6912
|
+
else if (/\.\d+\.[0-9a-f]+\.tmp$/.test(entry)) out.push(full);
|
|
6913
|
+
}
|
|
6914
|
+
return out;
|
|
6915
|
+
}
|
|
6916
|
+
/** Delete orphaned atomic-write temp files; returns the paths removed. */
|
|
6917
|
+
function cleanupTempFiles(dataDir) {
|
|
6918
|
+
const temps = [...findOrphanedTempFiles(path.default.join(dataDir, ".agentic")), ...findOrphanedTempFiles(path.default.join(dataDir, "customers"))];
|
|
6919
|
+
const removed = [];
|
|
6920
|
+
for (const f of temps) try {
|
|
6921
|
+
fs.default.rmSync(f, { force: true });
|
|
6922
|
+
removed.push(f);
|
|
6923
|
+
} catch {}
|
|
6924
|
+
return removed;
|
|
6925
|
+
}
|
|
6926
|
+
async function runDiagnostics(dataDir) {
|
|
6927
|
+
const checks = [];
|
|
6928
|
+
const agenticDir = path.default.join(dataDir, ".agentic");
|
|
6929
|
+
const customersDir = path.default.join(dataDir, "customers");
|
|
6930
|
+
if (!fs.default.existsSync(agenticDir) && !fs.default.existsSync(customersDir)) checks.push({
|
|
6931
|
+
name: "data directory",
|
|
6932
|
+
status: "fail",
|
|
6933
|
+
detail: `Neither .agentic/ nor customers/ found under ${dataDir} — run 'dxcrm init'`
|
|
6934
|
+
});
|
|
6935
|
+
else checks.push({
|
|
6936
|
+
name: "data directory",
|
|
6937
|
+
status: "ok",
|
|
6938
|
+
detail: dataDir
|
|
6939
|
+
});
|
|
6940
|
+
const slugs = require_session_store.listCustomerSlugs(dataDir);
|
|
6941
|
+
const invalid = [];
|
|
6942
|
+
for (const slug of slugs) try {
|
|
6943
|
+
await require_session_store.readMainFacts(dataDir, slug);
|
|
6944
|
+
} catch {
|
|
6945
|
+
invalid.push(slug);
|
|
6946
|
+
}
|
|
6947
|
+
checks.push({
|
|
6948
|
+
name: "customer data",
|
|
6949
|
+
status: invalid.length > 0 ? "fail" : "ok",
|
|
6950
|
+
detail: invalid.length > 0 ? `${invalid.length} of ${slugs.length} invalid: ${invalid.slice(0, 5).join(", ")}` : `${slugs.length} customer(s) valid`
|
|
6951
|
+
});
|
|
6952
|
+
const temps = [...findOrphanedTempFiles(agenticDir), ...findOrphanedTempFiles(customersDir)];
|
|
6953
|
+
checks.push({
|
|
6954
|
+
name: "temp files",
|
|
6955
|
+
status: temps.length > 0 ? "warn" : "ok",
|
|
6956
|
+
detail: temps.length > 0 ? `${temps.length} orphaned temp file(s) from interrupted writes — safe to delete` : "no orphaned temp files"
|
|
6957
|
+
});
|
|
6958
|
+
const summary = require_logger.summarizeLogs(dataDir);
|
|
6959
|
+
const errorCount = summary.byLevel.error;
|
|
6960
|
+
checks.push({
|
|
6961
|
+
name: "logs",
|
|
6962
|
+
status: errorCount > 0 ? "warn" : "ok",
|
|
6963
|
+
detail: errorCount > 0 ? `${errorCount} error entr${errorCount === 1 ? "y" : "ies"} in the log (dxcrm logs --level error)` : `${summary.total} log entr${summary.total === 1 ? "y" : "ies"}, no errors`
|
|
6964
|
+
});
|
|
6965
|
+
const backupLogPath = path.default.join(agenticDir, "backup-log.json");
|
|
6966
|
+
if (fs.default.existsSync(backupLogPath)) try {
|
|
6967
|
+
const entries = JSON.parse(fs.default.readFileSync(backupLogPath, "utf-8"));
|
|
6968
|
+
const last = entries[entries.length - 1]?.createdAt;
|
|
6969
|
+
const ageDays = last ? Math.floor((Date.now() - new Date(last).getTime()) / 864e5) : Infinity;
|
|
6970
|
+
checks.push({
|
|
6971
|
+
name: "backups",
|
|
6972
|
+
status: ageDays > 7 ? "warn" : "ok",
|
|
6973
|
+
detail: last ? `last backup ${ageDays}d ago` : "no backups recorded"
|
|
6974
|
+
});
|
|
6975
|
+
} catch {
|
|
6976
|
+
checks.push({
|
|
6977
|
+
name: "backups",
|
|
6978
|
+
status: "warn",
|
|
6979
|
+
detail: "backup log unreadable"
|
|
6980
|
+
});
|
|
6981
|
+
}
|
|
6982
|
+
return {
|
|
6983
|
+
ok: !checks.some((c) => c.status === "fail"),
|
|
6984
|
+
checks
|
|
6985
|
+
};
|
|
6986
|
+
}
|
|
6987
|
+
//#endregion
|
|
6988
|
+
//#region src/mcp/tools/get-diagnostics.ts
|
|
6989
|
+
const DATA_DIR$2 = process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
6990
|
+
async function handleGetDiagnostics(input, dataDir = DATA_DIR$2) {
|
|
6991
|
+
let cleaned = 0;
|
|
6992
|
+
if (input.fix) {
|
|
6993
|
+
const { cleanupTempFiles } = await Promise.resolve().then(() => doctor_exports);
|
|
6994
|
+
cleaned = cleanupTempFiles(dataDir).length;
|
|
6995
|
+
}
|
|
6996
|
+
const report = await runDiagnostics(dataDir);
|
|
6997
|
+
return { content: [{
|
|
6998
|
+
type: "text",
|
|
6999
|
+
text: JSON.stringify({
|
|
7000
|
+
ok: report.ok,
|
|
7001
|
+
...input.fix ? { tempFilesRemoved: cleaned } : {},
|
|
7002
|
+
checks: report.checks
|
|
7003
|
+
}, null, 2)
|
|
7004
|
+
}] };
|
|
7005
|
+
}
|
|
7006
|
+
function registerGetDiagnostics(server) {
|
|
7007
|
+
server.registerTool("get_diagnostics", {
|
|
7008
|
+
title: "Get Diagnostics",
|
|
7009
|
+
description: `Run a self-diagnostic health check of the CRM workspace.
|
|
7010
|
+
Verifies the data directory, validates every customer's profile, detects orphaned
|
|
7011
|
+
atomic-write temp files (a crash signature), surfaces recent log errors, and checks
|
|
7012
|
+
backup freshness. Use to answer "is everything healthy?" before/after bulk operations.
|
|
7013
|
+
|
|
7014
|
+
Args:
|
|
7015
|
+
fix: When true, first remove orphaned temp files (the only safely auto-fixable issue)
|
|
7016
|
+
|
|
7017
|
+
Returns: { ok: boolean, tempFilesRemoved?: number, checks: [{ name, status: "ok"|"warn"|"fail", detail }] }`,
|
|
7018
|
+
inputSchema: zod.z.object({ fix: zod.z.boolean().optional().describe("Clean orphaned temp files before reporting") })
|
|
7019
|
+
}, async ({ fix }) => handleGetDiagnostics(fix !== void 0 ? { fix } : {}));
|
|
7020
|
+
}
|
|
7021
|
+
//#endregion
|
|
6887
7022
|
//#region src/mcp/prompts.ts
|
|
6888
7023
|
/**
|
|
6889
7024
|
* CRM playbook prompts exposed via MCP `prompts/list` + `prompts/get`.
|
|
@@ -7300,6 +7435,7 @@ function createMcpServer() {
|
|
|
7300
7435
|
registerTriggerSync(server);
|
|
7301
7436
|
registerGetAuditLog(server);
|
|
7302
7437
|
registerGetLogs(server);
|
|
7438
|
+
registerGetDiagnostics(server);
|
|
7303
7439
|
registerCustomObjectTools(server);
|
|
7304
7440
|
registerPrompts(server);
|
|
7305
7441
|
registerResources(server);
|