@datasynx/agentic-crm 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +71 -8
- package/dist/cli.js.map +1 -1
- package/dist/daemon/worker.js +3 -3
- package/dist/funnel-B2mwpZE1.js +89 -0
- package/dist/funnel-B2mwpZE1.js.map +1 -0
- package/dist/funnel-CJ7fy7hG.js +2 -0
- package/dist/{index-Ewy4f1XW.d.cts → index-BAutNcAT.d.cts} +17 -17
- package/dist/index-BAutNcAT.d.cts.map +1 -0
- package/dist/{index-DoYT-azq.d.ts → index-BBAlKZg6.d.ts} +8 -8
- package/dist/index-BBAlKZg6.d.ts.map +1 -0
- package/dist/index.d.cts +17 -17
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/{knowledge-base-Byo0zwM5.js → knowledge-base-yo-BLUcB.js} +2 -1
- package/dist/knowledge-base-yo-BLUcB.js.map +1 -0
- package/dist/{login-yt9OOQQk.js → login-dc_Hqosw.js} +2 -2
- package/dist/{login-yt9OOQQk.js.map → login-dc_Hqosw.js.map} +1 -1
- package/dist/mailbox-config-BU3vib2T.js +2 -0
- package/dist/{mailbox-config-Dn2xTn9N.js → mailbox-config-trjLPHPG.js} +2 -2
- package/dist/{mailbox-config-Dn2xTn9N.js.map → mailbox-config-trjLPHPG.js.map} +1 -1
- package/dist/{mailbox-poll-B8dvFAXT.js → mailbox-poll-Ban7C3X0.js} +3 -3
- package/dist/{mailbox-poll-B8dvFAXT.js.map → mailbox-poll-Ban7C3X0.js.map} +1 -1
- package/dist/mcp-CdTJWTJf.d.cts.map +1 -1
- package/dist/mcp-CdTJWTJf.d.ts.map +1 -1
- package/dist/mcp.cjs +246 -134
- 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 +246 -134
- package/dist/mcp.js.map +1 -1
- package/dist/{server-C0XkJQBo.js → server-DAcwmRPE.js} +162 -135
- package/dist/server-DAcwmRPE.js.map +1 -0
- package/dist/{token-resolver-D98qPOOf.js → token-resolver-CL8-CSgZ.js} +2 -2
- package/dist/{token-resolver-D98qPOOf.js.map → token-resolver-CL8-CSgZ.js.map} +1 -1
- package/dist/{token-store-B0h0USqe.js → token-store-BPDwePNT.js} +13 -2
- package/dist/token-store-BPDwePNT.js.map +1 -0
- package/dist/token-store-D3HCeXmE.js +2 -0
- package/package.json +1 -1
- package/dist/index-DoYT-azq.d.ts.map +0 -1
- package/dist/index-Ewy4f1XW.d.cts.map +0 -1
- package/dist/knowledge-base-Byo0zwM5.js.map +0 -1
- package/dist/mailbox-config-Bu-J1O4I.js +0 -2
- package/dist/server-C0XkJQBo.js.map +0 -1
- package/dist/token-store-B0h0USqe.js.map +0 -1
- package/dist/token-store-CEmz8d-0.js +0 -2
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import { i as writeJsonFile } from "./json-store-WWsFzXub.js";
|
|
|
5
5
|
import { a as warning, i as success, n as error, r as info, t as bold } from "./colors-BG07TZQz.js";
|
|
6
6
|
import { n as getSession } from "./session-store-CEa39Dxs.js";
|
|
7
7
|
import { i as sessionCommand, r as readAllSessions } from "./session-BgGDyP2C.js";
|
|
8
|
-
import { a as searchKbSimple, i as listKbArticles, n as getKbArticle, o as writeKbArticle, s as CAPABILITIES_TEXT, t as deleteKbArticle } from "./knowledge-base-
|
|
8
|
+
import { a as searchKbSimple, i as listKbArticles, n as getKbArticle, o as writeKbArticle, s as CAPABILITIES_TEXT, t as deleteKbArticle } from "./knowledge-base-yo-BLUcB.js";
|
|
9
9
|
import { a as restoreCommand, t as backupCommand } from "./backup-CTlIxUdO.js";
|
|
10
10
|
import { n as readSyncState } from "./sync-state-DMZgzpez.js";
|
|
11
11
|
import { n as readUnmatched } from "./unmatched-transcripts-DC-VQ9YS.js";
|
|
@@ -23,7 +23,8 @@ import { n as listQuotes, r as readQuote, t as generateQuote } from "./quote-gen
|
|
|
23
23
|
import { i as upsertTicket, n as nextTicketId, r as readTickets, t as listAllTickets } from "./ticket-writer-a9on36Wb.js";
|
|
24
24
|
import { i as loadSlaRules, t as calcSlaDue } from "./sla-engine-O-A1ntu_.js";
|
|
25
25
|
import { a as listSurveys, d as writeSurvey, i as getSurvey, l as savePendingSurvey, n as calcNpsScore, o as loadSurveyResponses, r as generateSurveyToken } from "./survey-engine-DngXBv47.js";
|
|
26
|
-
import { i as resolveAccountConfig, n as imapConfigFromEnv } from "./mailbox-config-
|
|
26
|
+
import { i as resolveAccountConfig, n as imapConfigFromEnv, r as parseAccount } from "./mailbox-config-trjLPHPG.js";
|
|
27
|
+
import { i as removeMailboxToken, n as listMailboxTokens, t as isTokenExpired } from "./token-store-BPDwePNT.js";
|
|
27
28
|
import { Command } from "commander";
|
|
28
29
|
import path from "path";
|
|
29
30
|
import fs from "fs";
|
|
@@ -242,14 +243,14 @@ mcpCommand.command("start").description("Start MCP server (stdio by default)").o
|
|
|
242
243
|
if (opts.http) {
|
|
243
244
|
const port = parseInt(opts.port, 10);
|
|
244
245
|
console.error(info(`Starting MCP server in HTTP mode on port ${port}...`));
|
|
245
|
-
const { startHttp } = await import("./server-
|
|
246
|
+
const { startHttp } = await import("./server-DAcwmRPE.js");
|
|
246
247
|
await startHttp(port);
|
|
247
248
|
} else {
|
|
248
|
-
const { startStdio } = await import("./server-
|
|
249
|
+
const { startStdio } = await import("./server-DAcwmRPE.js");
|
|
249
250
|
await startStdio();
|
|
250
251
|
}
|
|
251
252
|
});
|
|
252
|
-
const TOOL_COUNT =
|
|
253
|
+
const TOOL_COUNT = 61;
|
|
253
254
|
/** Claude Code: CLAUDE.md in CRM dataDir */
|
|
254
255
|
function buildClaudeMd(dataDir) {
|
|
255
256
|
return `# DatasynxOpenCRM v2 — Agent Instructions (${TOOL_COUNT} MCP Tools)
|
|
@@ -379,6 +380,7 @@ It combines graph, health, revenue simulation, playbook, and org intelligence in
|
|
|
379
380
|
- \`get_diagnostics({ fix? })\` — self-diagnostic health check (data integrity, temp files, log errors, backups)
|
|
380
381
|
- \`get_pipeline_changes({ since?, days? })\` — pipeline time-travel: what changed (won/lost/moved/value) since a date
|
|
381
382
|
- \`get_pipeline_velocity({ stalledDays? })\` — stage dwell times, sales cycle, and stalled deals from snapshot history
|
|
383
|
+
- \`get_pipeline_funnel()\` — conversion funnel & win rate: where deals leak out of the pipeline
|
|
382
384
|
|
|
383
385
|
### Custom Objects (Platform / metadata)
|
|
384
386
|
- \`define_custom_object({ name, label?, fields })\` — define a runtime entity type with typed fields (no migration), admin
|
|
@@ -641,7 +643,7 @@ send_nps_survey · get_survey_results ·
|
|
|
641
643
|
search_knowledge_base · create_kb_article ·
|
|
642
644
|
backup_now · list_backups ·
|
|
643
645
|
trigger_sync · get_audit_log · get_logs · get_diagnostics ·
|
|
644
|
-
get_pipeline_changes · get_pipeline_velocity ·
|
|
646
|
+
get_pipeline_changes · get_pipeline_velocity · get_pipeline_funnel ·
|
|
645
647
|
define_custom_object · create_record · list_records · list_custom_objects
|
|
646
648
|
|
|
647
649
|
## Data: ${dataDir}`.trim();
|
|
@@ -1846,6 +1848,12 @@ async function runStatus(opts, dataDir) {
|
|
|
1846
1848
|
const daemonLine = daemon.running ? success(`running (PID ${daemon.pid})`) : error("not running");
|
|
1847
1849
|
console.log(` Daemon: ${daemonLine}`);
|
|
1848
1850
|
console.log(` Customers: ${slugs.length} active`);
|
|
1851
|
+
const { listMailboxTokens, isTokenExpired } = await import("./token-store-D3HCeXmE.js");
|
|
1852
|
+
const mailboxTokens = listMailboxTokens(dir);
|
|
1853
|
+
if (mailboxTokens.length > 0) {
|
|
1854
|
+
const valid = mailboxTokens.filter((t) => !isTokenExpired(t)).length;
|
|
1855
|
+
console.log(` Mailboxes: ${mailboxTokens.length} linked (${valid} valid)`);
|
|
1856
|
+
}
|
|
1849
1857
|
const session = getSession() ?? readAllSessions(dir)[0] ?? null;
|
|
1850
1858
|
if (session) {
|
|
1851
1859
|
const ownerPart = session.owner ? ` [${session.owner}]` : "";
|
|
@@ -3048,6 +3056,26 @@ pipelineCommand.command("velocity").description("Stage dwell times, sales cycle,
|
|
|
3048
3056
|
for (const d of report.stalledDeals) console.log(` ${d.slug}/${d.name}: ${d.stage}, ${d.daysInStage}d €${d.value.toLocaleString()}`);
|
|
3049
3057
|
} else console.log(success(`\nNo stalled deals (threshold ${report.stalledThresholdDays}d).`));
|
|
3050
3058
|
});
|
|
3059
|
+
pipelineCommand.command("funnel").description("Conversion funnel & win rate: where deals leak out of the pipeline").action(async () => {
|
|
3060
|
+
const { analyzeFunnel } = await import("./funnel-CJ7fy7hG.js");
|
|
3061
|
+
const report = analyzeFunnel(dataDir$17());
|
|
3062
|
+
if (report.snapshotCount === 0) {
|
|
3063
|
+
console.log(info("No snapshots yet. Run 'dxcrm pipeline snapshot' (or let the daemon take daily ones)."));
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3066
|
+
console.log(bold(`Pipeline funnel (${report.snapshotCount} snapshots, ${report.fromId} → ${report.toId})`));
|
|
3067
|
+
for (const s of report.stages) {
|
|
3068
|
+
const conv = s.conversionPctToNext === null ? "" : ` → ${s.conversionPctToNext}% convert`;
|
|
3069
|
+
console.log(` ${s.stage.padEnd(14)} ${String(s.reached).padStart(4)} reached${conv}`);
|
|
3070
|
+
}
|
|
3071
|
+
const wr = report.winRatePct;
|
|
3072
|
+
const wrStr = wr === null ? "n/a (nothing closed yet)" : `${wr}%`;
|
|
3073
|
+
console.log(`\n ${"Win rate".padEnd(14)} ${wrStr} (${report.wonCount} won / ${report.lostCount} lost)`);
|
|
3074
|
+
if (report.biggestLeak) {
|
|
3075
|
+
const l = report.biggestLeak;
|
|
3076
|
+
console.log(error(`\nBiggest leak: ${l.from} → ${l.to} (only ${l.conversionPct}% convert)`));
|
|
3077
|
+
}
|
|
3078
|
+
});
|
|
3051
3079
|
//#endregion
|
|
3052
3080
|
//#region src/commands/rbac.ts
|
|
3053
3081
|
const ROLES = [
|
|
@@ -4513,6 +4541,22 @@ complianceCommand.command("status", { isDefault: true }).description("Show the a
|
|
|
4513
4541
|
});
|
|
4514
4542
|
//#endregion
|
|
4515
4543
|
//#region src/commands/mailbox.ts
|
|
4544
|
+
/** Summarize every stored mailbox OAuth account. */
|
|
4545
|
+
function runMailboxList(dataDir) {
|
|
4546
|
+
return listMailboxTokens(dataDir).map((t) => ({
|
|
4547
|
+
account: `${t.provider}:${t.user}`,
|
|
4548
|
+
provider: t.provider,
|
|
4549
|
+
user: t.user,
|
|
4550
|
+
status: isTokenExpired(t) ? "expired" : "valid",
|
|
4551
|
+
expiresAt: new Date(t.expiresAt).toISOString()
|
|
4552
|
+
}));
|
|
4553
|
+
}
|
|
4554
|
+
/** Remove a stored mailbox account by "provider:user". */
|
|
4555
|
+
function runMailboxLogout(dataDir, account) {
|
|
4556
|
+
const parsed = parseAccount(account);
|
|
4557
|
+
if (!parsed) return { error: `Invalid account '${account}'. Use 'gmail:you@gmail.com' or 'microsoft:you@org.com'.` };
|
|
4558
|
+
return { removed: removeMailboxToken(dataDir, parsed.provider, parsed.user) };
|
|
4559
|
+
}
|
|
4516
4560
|
/**
|
|
4517
4561
|
* Sync an IMAP mailbox (any provider). With a slug, all mail goes to that one
|
|
4518
4562
|
* customer; without, mail is auto-routed to customers by sender/recipient
|
|
@@ -4566,7 +4610,7 @@ async function runLogin(provider, user) {
|
|
|
4566
4610
|
return;
|
|
4567
4611
|
}
|
|
4568
4612
|
const account = user ?? (await ask("Gmail address: ")).trim();
|
|
4569
|
-
const { runGmailLogin } = await import("./login-
|
|
4613
|
+
const { runGmailLogin } = await import("./login-dc_Hqosw.js");
|
|
4570
4614
|
await runGmailLogin({
|
|
4571
4615
|
dataDir,
|
|
4572
4616
|
clientId,
|
|
@@ -4586,7 +4630,7 @@ async function runLogin(provider, user) {
|
|
|
4586
4630
|
}
|
|
4587
4631
|
const tenant = process.env["DXCRM_MS_TENANT"] ?? "common";
|
|
4588
4632
|
const account = user ?? (await ask("Outlook/Microsoft address: ")).trim();
|
|
4589
|
-
const { runMicrosoftLogin } = await import("./login-
|
|
4633
|
+
const { runMicrosoftLogin } = await import("./login-dc_Hqosw.js");
|
|
4590
4634
|
await runMicrosoftLogin({
|
|
4591
4635
|
dataDir,
|
|
4592
4636
|
clientId,
|
|
@@ -4612,6 +4656,25 @@ mailboxCommand.command("sync").description("Sync an IMAP mailbox; auto-routes to
|
|
|
4612
4656
|
includeAttachments: options.attachments !== false
|
|
4613
4657
|
});
|
|
4614
4658
|
});
|
|
4659
|
+
mailboxCommand.command("list").description("List logged-in mailbox accounts and their token status").action(() => {
|
|
4660
|
+
const accounts = runMailboxList(process.env["DXCRM_DATA_DIR"] ?? process.cwd());
|
|
4661
|
+
if (accounts.length === 0) {
|
|
4662
|
+
console.log(info("No mailbox accounts. Run 'dxcrm mailbox login gmail|microsoft'."));
|
|
4663
|
+
return;
|
|
4664
|
+
}
|
|
4665
|
+
for (const a of accounts) {
|
|
4666
|
+
const tag = a.status === "valid" ? success("valid") : error("expired");
|
|
4667
|
+
console.log(`${bold(a.account)} — token ${tag} (expires ${a.expiresAt})`);
|
|
4668
|
+
}
|
|
4669
|
+
});
|
|
4670
|
+
mailboxCommand.command("logout").description("Remove a stored mailbox account").argument("<account>", "provider:user (e.g. gmail:you@gmail.com)").action((account) => {
|
|
4671
|
+
const result = runMailboxLogout(process.env["DXCRM_DATA_DIR"] ?? process.cwd(), account);
|
|
4672
|
+
if ("error" in result) {
|
|
4673
|
+
console.error(error(result.error));
|
|
4674
|
+
return;
|
|
4675
|
+
}
|
|
4676
|
+
console.log(result.removed ? success(`✓ Removed ${bold(account)}.`) : info(`No stored account '${account}'.`));
|
|
4677
|
+
});
|
|
4615
4678
|
//#endregion
|
|
4616
4679
|
//#region src/commands/registry.ts
|
|
4617
4680
|
/** Every top-level `dxcrm` command, in display order. */
|