@datasynx/agentic-crm 1.6.0 → 1.8.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 +39 -70
- package/dist/cli.js.map +1 -1
- package/dist/daemon/worker.js +24 -1
- package/dist/daemon/worker.js.map +1 -1
- package/dist/{imap-o6PRuBvm.js → imap-BRgNh3T3.js} +2 -2
- package/dist/{imap-o6PRuBvm.js.map → imap-BRgNh3T3.js.map} +1 -1
- package/dist/imap-DzeqMdZ3.js +2 -0
- package/dist/{index-BBAlKZg6.d.ts → index-DoYT-azq.d.ts} +8 -8
- package/dist/index-DoYT-azq.d.ts.map +1 -0
- package/dist/{index-DNHsURo5.d.cts → index-Ewy4f1XW.d.cts} +12 -12
- package/dist/{index-DNHsURo5.d.cts.map → index-Ewy4f1XW.d.cts.map} +1 -1
- package/dist/index.d.cts +12 -12
- 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-Cc0niBFf.js → knowledge-base-Byo0zwM5.js} +2 -1
- package/dist/knowledge-base-Byo0zwM5.js.map +1 -0
- package/dist/{login-CYgla6-A.js → login-yt9OOQQk.js} +3 -2
- package/dist/{login-CYgla6-A.js.map → login-yt9OOQQk.js.map} +1 -1
- package/dist/mailbox-config-Bu-J1O4I.js +2 -0
- package/dist/mailbox-config-Dn2xTn9N.js +67 -0
- package/dist/mailbox-config-Dn2xTn9N.js.map +1 -0
- package/dist/mailbox-poll-B8dvFAXT.js +80 -0
- package/dist/mailbox-poll-B8dvFAXT.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 +303 -137
- 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 +303 -137
- package/dist/mcp.js.map +1 -1
- package/dist/{microsoft-DgbVlHdT.js → microsoft-dsC1fQQG.js} +2 -38
- package/dist/microsoft-dsC1fQQG.js.map +1 -0
- package/dist/{server-BbInMUgp.js → server-C0XkJQBo.js} +167 -132
- package/dist/server-C0XkJQBo.js.map +1 -0
- package/dist/{token-resolver-BRLOmRvF.js → token-resolver-D98qPOOf.js} +3 -2
- package/dist/{token-resolver-BRLOmRvF.js.map → token-resolver-D98qPOOf.js.map} +1 -1
- package/dist/token-store-B0h0USqe.js +43 -0
- package/dist/token-store-B0h0USqe.js.map +1 -0
- package/dist/token-store-CEmz8d-0.js +2 -0
- package/dist/velocity-BtX1l5Gh.js +2 -0
- package/dist/velocity-C2l4cW0K.js +123 -0
- package/dist/velocity-C2l4cW0K.js.map +1 -0
- package/package.json +1 -1
- package/dist/index-BBAlKZg6.d.ts.map +0 -1
- package/dist/knowledge-base-Cc0niBFf.js.map +0 -1
- package/dist/microsoft-DgbVlHdT.js.map +0 -1
- package/dist/server-BbInMUgp.js.map +0 -1
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-Byo0zwM5.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,6 +23,7 @@ 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-Dn2xTn9N.js";
|
|
26
27
|
import { Command } from "commander";
|
|
27
28
|
import path from "path";
|
|
28
29
|
import fs from "fs";
|
|
@@ -241,14 +242,14 @@ mcpCommand.command("start").description("Start MCP server (stdio by default)").o
|
|
|
241
242
|
if (opts.http) {
|
|
242
243
|
const port = parseInt(opts.port, 10);
|
|
243
244
|
console.error(info(`Starting MCP server in HTTP mode on port ${port}...`));
|
|
244
|
-
const { startHttp } = await import("./server-
|
|
245
|
+
const { startHttp } = await import("./server-C0XkJQBo.js");
|
|
245
246
|
await startHttp(port);
|
|
246
247
|
} else {
|
|
247
|
-
const { startStdio } = await import("./server-
|
|
248
|
+
const { startStdio } = await import("./server-C0XkJQBo.js");
|
|
248
249
|
await startStdio();
|
|
249
250
|
}
|
|
250
251
|
});
|
|
251
|
-
const TOOL_COUNT =
|
|
252
|
+
const TOOL_COUNT = 60;
|
|
252
253
|
/** Claude Code: CLAUDE.md in CRM dataDir */
|
|
253
254
|
function buildClaudeMd(dataDir) {
|
|
254
255
|
return `# DatasynxOpenCRM v2 — Agent Instructions (${TOOL_COUNT} MCP Tools)
|
|
@@ -377,6 +378,7 @@ It combines graph, health, revenue simulation, playbook, and org intelligence in
|
|
|
377
378
|
- \`get_logs({ level?, component?, since?, contains?, limit?, summary? })\` — query/aggregate the structured application log
|
|
378
379
|
- \`get_diagnostics({ fix? })\` — self-diagnostic health check (data integrity, temp files, log errors, backups)
|
|
379
380
|
- \`get_pipeline_changes({ since?, days? })\` — pipeline time-travel: what changed (won/lost/moved/value) since a date
|
|
381
|
+
- \`get_pipeline_velocity({ stalledDays? })\` — stage dwell times, sales cycle, and stalled deals from snapshot history
|
|
380
382
|
|
|
381
383
|
### Custom Objects (Platform / metadata)
|
|
382
384
|
- \`define_custom_object({ name, label?, fields })\` — define a runtime entity type with typed fields (no migration), admin
|
|
@@ -638,7 +640,8 @@ create_ticket · update_ticket · list_tickets · close_ticket ·
|
|
|
638
640
|
send_nps_survey · get_survey_results ·
|
|
639
641
|
search_knowledge_base · create_kb_article ·
|
|
640
642
|
backup_now · list_backups ·
|
|
641
|
-
trigger_sync · get_audit_log · get_logs · get_diagnostics ·
|
|
643
|
+
trigger_sync · get_audit_log · get_logs · get_diagnostics ·
|
|
644
|
+
get_pipeline_changes · get_pipeline_velocity ·
|
|
642
645
|
define_custom_object · create_record · list_records · list_custom_objects
|
|
643
646
|
|
|
644
647
|
## Data: ${dataDir}`.trim();
|
|
@@ -3017,6 +3020,34 @@ pipelineCommand.command("changes").description("Show what changed in the pipelin
|
|
|
3017
3020
|
for (const d of diff.added) console.log(` ${d.slug}/${d.name}`);
|
|
3018
3021
|
}
|
|
3019
3022
|
});
|
|
3023
|
+
pipelineCommand.command("velocity").description("Stage dwell times, sales cycle, and stalled deals from snapshot history").option("--stalled-days <n>", "Days in one stage before a deal counts as stalled (default 14)").action(async (opts) => {
|
|
3024
|
+
const { analyzeVelocity } = await import("./velocity-BtX1l5Gh.js");
|
|
3025
|
+
const analyzeOpts = {};
|
|
3026
|
+
if (opts.stalledDays !== void 0) {
|
|
3027
|
+
const n = parseInt(opts.stalledDays, 10);
|
|
3028
|
+
if (Number.isFinite(n) && n > 0) analyzeOpts.stalledDays = n;
|
|
3029
|
+
}
|
|
3030
|
+
const report = analyzeVelocity(dataDir$17(), analyzeOpts);
|
|
3031
|
+
if (report.snapshotCount === 0) {
|
|
3032
|
+
console.log(info("No snapshots yet. Run 'dxcrm pipeline snapshot' (or let the daemon take daily ones)."));
|
|
3033
|
+
return;
|
|
3034
|
+
}
|
|
3035
|
+
console.log(bold(`Pipeline velocity (${report.snapshotCount} snapshots, ${report.fromId} → ${report.toId})`));
|
|
3036
|
+
if (report.stageDurations.length) {
|
|
3037
|
+
console.log(info("\nAvg time in stage:"));
|
|
3038
|
+
for (const s of report.stageDurations) {
|
|
3039
|
+
const samples = `${s.samples} sample${s.samples === 1 ? "" : "s"}`;
|
|
3040
|
+
console.log(` ${s.stage.padEnd(14)} ${s.avgDays}d (${samples})`);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
const cycle = report.avgSalesCycleDays;
|
|
3044
|
+
const cycleStr = cycle === null ? "n/a (no won deals yet)" : `${cycle}d avg`;
|
|
3045
|
+
console.log(`\n ${"Sales cycle".padEnd(14)} ${cycleStr} over ${report.wonCount} won`);
|
|
3046
|
+
if (report.stalledDeals.length) {
|
|
3047
|
+
console.log(error(`\nStalled deals (> ${report.stalledThresholdDays}d in stage):`));
|
|
3048
|
+
for (const d of report.stalledDeals) console.log(` ${d.slug}/${d.name}: ${d.stage}, ${d.daysInStage}d €${d.value.toLocaleString()}`);
|
|
3049
|
+
} else console.log(success(`\nNo stalled deals (threshold ${report.stalledThresholdDays}d).`));
|
|
3050
|
+
});
|
|
3020
3051
|
//#endregion
|
|
3021
3052
|
//#region src/commands/rbac.ts
|
|
3022
3053
|
const ROLES = [
|
|
@@ -4482,68 +4513,6 @@ complianceCommand.command("status", { isDefault: true }).description("Show the a
|
|
|
4482
4513
|
});
|
|
4483
4514
|
//#endregion
|
|
4484
4515
|
//#region src/commands/mailbox.ts
|
|
4485
|
-
/** Default IMAP endpoints for OAuth providers. */
|
|
4486
|
-
const PROVIDER_IMAP_HOST = {
|
|
4487
|
-
gmail: {
|
|
4488
|
-
host: "imap.gmail.com",
|
|
4489
|
-
port: 993
|
|
4490
|
-
},
|
|
4491
|
-
microsoft: {
|
|
4492
|
-
host: "outlook.office365.com",
|
|
4493
|
-
port: 993
|
|
4494
|
-
}
|
|
4495
|
-
};
|
|
4496
|
-
/** Read IMAP mailbox connection settings from the environment. */
|
|
4497
|
-
function imapConfigFromEnv(env = process.env) {
|
|
4498
|
-
const host = env["DXCRM_IMAP_HOST"];
|
|
4499
|
-
const user = env["DXCRM_IMAP_USER"];
|
|
4500
|
-
const pass = env["DXCRM_IMAP_PASS"];
|
|
4501
|
-
const accessToken = env["DXCRM_IMAP_TOKEN"];
|
|
4502
|
-
if (!host || !user || !pass && !accessToken) return null;
|
|
4503
|
-
return {
|
|
4504
|
-
host,
|
|
4505
|
-
port: env["DXCRM_IMAP_PORT"] ? Number(env["DXCRM_IMAP_PORT"]) : 993,
|
|
4506
|
-
secure: env["DXCRM_IMAP_SECURE"] !== "false",
|
|
4507
|
-
mailbox: env["DXCRM_IMAP_MAILBOX"] ?? "INBOX",
|
|
4508
|
-
auth: accessToken ? {
|
|
4509
|
-
user,
|
|
4510
|
-
accessToken
|
|
4511
|
-
} : {
|
|
4512
|
-
user,
|
|
4513
|
-
pass
|
|
4514
|
-
}
|
|
4515
|
-
};
|
|
4516
|
-
}
|
|
4517
|
-
/** Parse a "provider:user" account string. */
|
|
4518
|
-
function parseAccount(account) {
|
|
4519
|
-
const idx = account.indexOf(":");
|
|
4520
|
-
if (idx < 0) return null;
|
|
4521
|
-
const provider = account.slice(0, idx);
|
|
4522
|
-
const user = account.slice(idx + 1);
|
|
4523
|
-
if (provider !== "gmail" && provider !== "microsoft" || !user) return null;
|
|
4524
|
-
return {
|
|
4525
|
-
provider,
|
|
4526
|
-
user
|
|
4527
|
-
};
|
|
4528
|
-
}
|
|
4529
|
-
/** Build an IMAP config for a stored OAuth account, refreshing the token if needed. */
|
|
4530
|
-
async function resolveAccountConfig(dataDir, account, env = process.env, mailbox) {
|
|
4531
|
-
const parsed = parseAccount(account);
|
|
4532
|
-
if (!parsed) throw new Error(`Invalid --account '${account}'. Use 'gmail:you@gmail.com' or 'microsoft:you@org.com'.`);
|
|
4533
|
-
const { getFreshAccessToken } = await import("./token-resolver-BRLOmRvF.js");
|
|
4534
|
-
const accessToken = await getFreshAccessToken(dataDir, parsed.provider, parsed.user, { env });
|
|
4535
|
-
const { host, port } = PROVIDER_IMAP_HOST[parsed.provider];
|
|
4536
|
-
return {
|
|
4537
|
-
host,
|
|
4538
|
-
port,
|
|
4539
|
-
secure: true,
|
|
4540
|
-
mailbox: mailbox ?? env["DXCRM_IMAP_MAILBOX"] ?? "INBOX",
|
|
4541
|
-
auth: {
|
|
4542
|
-
user: parsed.user,
|
|
4543
|
-
accessToken
|
|
4544
|
-
}
|
|
4545
|
-
};
|
|
4546
|
-
}
|
|
4547
4516
|
/**
|
|
4548
4517
|
* Sync an IMAP mailbox (any provider). With a slug, all mail goes to that one
|
|
4549
4518
|
* customer; without, mail is auto-routed to customers by sender/recipient
|
|
@@ -4565,7 +4534,7 @@ async function runMailboxSync(opts) {
|
|
|
4565
4534
|
console.error(error(msg));
|
|
4566
4535
|
return { error: msg };
|
|
4567
4536
|
}
|
|
4568
|
-
const { syncImapMailbox } = await import("./imap-
|
|
4537
|
+
const { syncImapMailbox } = await import("./imap-DzeqMdZ3.js");
|
|
4569
4538
|
const result = await syncImapMailbox({
|
|
4570
4539
|
dataDir: opts.dataDir,
|
|
4571
4540
|
config,
|
|
@@ -4597,7 +4566,7 @@ async function runLogin(provider, user) {
|
|
|
4597
4566
|
return;
|
|
4598
4567
|
}
|
|
4599
4568
|
const account = user ?? (await ask("Gmail address: ")).trim();
|
|
4600
|
-
const { runGmailLogin } = await import("./login-
|
|
4569
|
+
const { runGmailLogin } = await import("./login-yt9OOQQk.js");
|
|
4601
4570
|
await runGmailLogin({
|
|
4602
4571
|
dataDir,
|
|
4603
4572
|
clientId,
|
|
@@ -4617,7 +4586,7 @@ async function runLogin(provider, user) {
|
|
|
4617
4586
|
}
|
|
4618
4587
|
const tenant = process.env["DXCRM_MS_TENANT"] ?? "common";
|
|
4619
4588
|
const account = user ?? (await ask("Outlook/Microsoft address: ")).trim();
|
|
4620
|
-
const { runMicrosoftLogin } = await import("./login-
|
|
4589
|
+
const { runMicrosoftLogin } = await import("./login-yt9OOQQk.js");
|
|
4621
4590
|
await runMicrosoftLogin({
|
|
4622
4591
|
dataDir,
|
|
4623
4592
|
clientId,
|