@datasynx/agentic-crm 1.5.0 → 1.7.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 +70 -76
- package/dist/cli.js.map +1 -1
- package/dist/daemon/worker.js +40 -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-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-B5_QnkG8.d.cts → index-DcDaz_cu.d.cts} +16 -16
- package/dist/index-DcDaz_cu.d.cts.map +1 -0
- package/dist/index.d.cts +16 -16
- 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-Bx2PKQR2.js → knowledge-base-Cc0niBFf.js} +2 -1
- package/dist/knowledge-base-Cc0niBFf.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 +289 -130
- 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 +289 -130
- 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-uqXUhF4H.js → server-BbInMUgp.js} +172 -130
- package/dist/server-BbInMUgp.js.map +1 -0
- package/dist/snapshots-B6aOhoXs.js +2 -0
- package/dist/snapshots-CQSOaIMs.js +161 -0
- package/dist/snapshots-CQSOaIMs.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/package.json +2 -2
- package/dist/index-B5_QnkG8.d.cts.map +0 -1
- package/dist/knowledge-base-Bx2PKQR2.js.map +0 -1
- package/dist/microsoft-DgbVlHdT.js.map +0 -1
- package/dist/server-uqXUhF4H.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-Cc0niBFf.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-BbInMUgp.js");
|
|
245
246
|
await startHttp(port);
|
|
246
247
|
} else {
|
|
247
|
-
const { startStdio } = await import("./server-
|
|
248
|
+
const { startStdio } = await import("./server-BbInMUgp.js");
|
|
248
249
|
await startStdio();
|
|
249
250
|
}
|
|
250
251
|
});
|
|
251
|
-
const TOOL_COUNT =
|
|
252
|
+
const TOOL_COUNT = 59;
|
|
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)
|
|
@@ -376,6 +377,7 @@ It combines graph, health, revenue simulation, playbook, and org intelligence in
|
|
|
376
377
|
- \`get_audit_log({ slug?, actor?, limit? })\` — read append-only audit log of all write operations
|
|
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)
|
|
380
|
+
- \`get_pipeline_changes({ since?, days? })\` — pipeline time-travel: what changed (won/lost/moved/value) since a date
|
|
379
381
|
|
|
380
382
|
### Custom Objects (Platform / metadata)
|
|
381
383
|
- \`define_custom_object({ name, label?, fields })\` — define a runtime entity type with typed fields (no migration), admin
|
|
@@ -637,7 +639,7 @@ create_ticket · update_ticket · list_tickets · close_ticket ·
|
|
|
637
639
|
send_nps_survey · get_survey_results ·
|
|
638
640
|
search_knowledge_base · create_kb_article ·
|
|
639
641
|
backup_now · list_backups ·
|
|
640
|
-
trigger_sync · get_audit_log · get_logs · get_diagnostics ·
|
|
642
|
+
trigger_sync · get_audit_log · get_logs · get_diagnostics · get_pipeline_changes ·
|
|
641
643
|
define_custom_object · create_record · list_records · list_custom_objects
|
|
642
644
|
|
|
643
645
|
## Data: ${dataDir}`.trim();
|
|
@@ -2902,14 +2904,14 @@ function buildQuery(opts) {
|
|
|
2902
2904
|
limit: opts.limit ?? 50
|
|
2903
2905
|
};
|
|
2904
2906
|
}
|
|
2905
|
-
function dataDir$
|
|
2907
|
+
function dataDir$19() {
|
|
2906
2908
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2907
2909
|
}
|
|
2908
2910
|
const logsCommand = new Command("logs").description("View and analyze the structured application log").option("--level <level>", "Minimum level: debug | info | warn | error").option("--component <name>", "Filter by component (e.g. gmail-sync, lancedb)").option("--since <iso>", "Only entries at or after this ISO timestamp").option("--contains <text>", "Filter by message substring").option("--limit <n>", "Max entries to show (default: 50)", parseInt).option("--summary", "Show aggregated counts (by level + component) instead of entries").action(async (opts) => {
|
|
2909
2911
|
const query = buildQuery(opts);
|
|
2910
2912
|
if (opts.summary) {
|
|
2911
2913
|
const { summarizeLogs } = await import("./logger-vKQS34w9.js");
|
|
2912
|
-
const s = summarizeLogs(dataDir$
|
|
2914
|
+
const s = summarizeLogs(dataDir$19(), query);
|
|
2913
2915
|
console.log(bold(`Logs — ${s.total} entr${s.total === 1 ? "y" : "ies"}`));
|
|
2914
2916
|
if (s.firstTs) console.log(info(` ${s.firstTs} → ${s.lastTs}`));
|
|
2915
2917
|
console.log(" By level:");
|
|
@@ -2926,7 +2928,7 @@ const logsCommand = new Command("logs").description("View and analyze the struct
|
|
|
2926
2928
|
return;
|
|
2927
2929
|
}
|
|
2928
2930
|
const { queryLogs } = await import("./logger-vKQS34w9.js");
|
|
2929
|
-
const entries = queryLogs(dataDir$
|
|
2931
|
+
const entries = queryLogs(dataDir$19(), query);
|
|
2930
2932
|
if (entries.length === 0) {
|
|
2931
2933
|
console.log(success("No matching log entries."));
|
|
2932
2934
|
return;
|
|
@@ -2938,7 +2940,7 @@ const logsCommand = new Command("logs").description("View and analyze the struct
|
|
|
2938
2940
|
});
|
|
2939
2941
|
//#endregion
|
|
2940
2942
|
//#region src/commands/doctor.ts
|
|
2941
|
-
function dataDir$
|
|
2943
|
+
function dataDir$18() {
|
|
2942
2944
|
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2943
2945
|
}
|
|
2944
2946
|
function icon(status) {
|
|
@@ -2949,10 +2951,10 @@ function icon(status) {
|
|
|
2949
2951
|
const doctorCommand = new Command("doctor").description("Run self-diagnostics: data integrity, temp files, log errors, backup freshness").option("--fix", "Clean up safely-fixable issues (orphaned temp files)").action(async (opts) => {
|
|
2950
2952
|
const { runDiagnostics, cleanupTempFiles } = await import("./doctor-CYDaNmFn.js");
|
|
2951
2953
|
if (opts.fix) {
|
|
2952
|
-
const removed = cleanupTempFiles(dataDir$
|
|
2954
|
+
const removed = cleanupTempFiles(dataDir$18());
|
|
2953
2955
|
console.log(removed.length > 0 ? success(`Removed ${removed.length} orphaned temp file(s).`) : warning("Nothing to fix."));
|
|
2954
2956
|
}
|
|
2955
|
-
const report = await runDiagnostics(dataDir$
|
|
2957
|
+
const report = await runDiagnostics(dataDir$18());
|
|
2956
2958
|
console.log(bold("dxcrm doctor"));
|
|
2957
2959
|
for (const c of report.checks) console.log(` ${icon(c.status)} ${c.name.padEnd(16)} ${c.detail}`);
|
|
2958
2960
|
if (report.ok) {
|
|
@@ -2964,6 +2966,59 @@ const doctorCommand = new Command("doctor").description("Run self-diagnostics: d
|
|
|
2964
2966
|
}
|
|
2965
2967
|
});
|
|
2966
2968
|
//#endregion
|
|
2969
|
+
//#region src/commands/pipeline.ts
|
|
2970
|
+
function dataDir$17() {
|
|
2971
|
+
return process.env["DXCRM_DATA_DIR"] ?? process.cwd();
|
|
2972
|
+
}
|
|
2973
|
+
function daysAgoIso(days) {
|
|
2974
|
+
return (/* @__PURE__ */ new Date(Date.now() - days * 864e5)).toISOString().slice(0, 10);
|
|
2975
|
+
}
|
|
2976
|
+
const pipelineCommand = new Command("pipeline").description("Pipeline time-travel: daily snapshots and 'what changed?' diffs");
|
|
2977
|
+
pipelineCommand.command("snapshot").description("Capture a snapshot of the current pipeline across all customers").action(async () => {
|
|
2978
|
+
const { takeSnapshot } = await import("./snapshots-B6aOhoXs.js");
|
|
2979
|
+
const snap = takeSnapshot(dataDir$17());
|
|
2980
|
+
console.log(success(`Snapshot ${snap.id} taken — ${snap.deals.length} deal(s).`));
|
|
2981
|
+
});
|
|
2982
|
+
pipelineCommand.command("list").description("List available pipeline snapshots").action(async () => {
|
|
2983
|
+
const { listSnapshots } = await import("./snapshots-B6aOhoXs.js");
|
|
2984
|
+
const snaps = listSnapshots(dataDir$17());
|
|
2985
|
+
if (snaps.length === 0) {
|
|
2986
|
+
console.log(info("No snapshots yet. Run 'dxcrm pipeline snapshot' (or let the daemon take daily ones)."));
|
|
2987
|
+
return;
|
|
2988
|
+
}
|
|
2989
|
+
for (const s of snaps) console.log(`${s.id} ${String(s.dealCount).padStart(4)} deals open €${s.openValue.toLocaleString()}`);
|
|
2990
|
+
});
|
|
2991
|
+
pipelineCommand.command("changes").description("Show what changed in the pipeline since a date (default: 7 days ago)").option("--since <YYYY-MM-DD>", "Baseline date (default: 7 days ago)").action(async (opts) => {
|
|
2992
|
+
const since = opts.since ?? daysAgoIso(7);
|
|
2993
|
+
const { diffAgainstNow } = await import("./snapshots-B6aOhoXs.js");
|
|
2994
|
+
const diff = diffAgainstNow(dataDir$17(), since);
|
|
2995
|
+
if (!diff) {
|
|
2996
|
+
console.log(warning(`No snapshot at or before ${since}. Take snapshots first (or wait for the daemon).`));
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2999
|
+
console.log(bold(`Pipeline changes since ${diff.fromId}`));
|
|
3000
|
+
const line = (label, n) => ` ${label.padEnd(16)} ${n}`;
|
|
3001
|
+
console.log(success(line("Won", diff.won.length)));
|
|
3002
|
+
console.log(error(line("Lost", diff.lost.length)));
|
|
3003
|
+
console.log(line("New deals", diff.added.length));
|
|
3004
|
+
console.log(line("Removed", diff.removed.length));
|
|
3005
|
+
console.log(line("Stage moves", diff.advanced.length));
|
|
3006
|
+
console.log(line("Value changes", diff.valueChanged.length));
|
|
3007
|
+
const delta = diff.openValueDelta;
|
|
3008
|
+
const deltaStr = `${delta >= 0 ? "+" : ""}€${delta.toLocaleString()}`;
|
|
3009
|
+
console.log(` ${"Open value".padEnd(16)} €${diff.openValueAfter.toLocaleString()} (${delta >= 0 ? success(deltaStr) : error(deltaStr)})`);
|
|
3010
|
+
if (diff.won.length) console.log(success(`\nWon: ${diff.won.map((d) => d.name).join(", ")}`));
|
|
3011
|
+
if (diff.lost.length) console.log(error(`Lost: ${diff.lost.map((d) => d.name).join(", ")}`));
|
|
3012
|
+
if (diff.advanced.length) {
|
|
3013
|
+
console.log(info("\nStage moves:"));
|
|
3014
|
+
for (const m of diff.advanced) console.log(` ${m.slug}/${m.name}: ${m.from} → ${m.to}`);
|
|
3015
|
+
}
|
|
3016
|
+
if (diff.added.length) {
|
|
3017
|
+
console.log(info("\nNew deals:"));
|
|
3018
|
+
for (const d of diff.added) console.log(` ${d.slug}/${d.name}`);
|
|
3019
|
+
}
|
|
3020
|
+
});
|
|
3021
|
+
//#endregion
|
|
2967
3022
|
//#region src/commands/rbac.ts
|
|
2968
3023
|
const ROLES = [
|
|
2969
3024
|
"admin",
|
|
@@ -4428,68 +4483,6 @@ complianceCommand.command("status", { isDefault: true }).description("Show the a
|
|
|
4428
4483
|
});
|
|
4429
4484
|
//#endregion
|
|
4430
4485
|
//#region src/commands/mailbox.ts
|
|
4431
|
-
/** Default IMAP endpoints for OAuth providers. */
|
|
4432
|
-
const PROVIDER_IMAP_HOST = {
|
|
4433
|
-
gmail: {
|
|
4434
|
-
host: "imap.gmail.com",
|
|
4435
|
-
port: 993
|
|
4436
|
-
},
|
|
4437
|
-
microsoft: {
|
|
4438
|
-
host: "outlook.office365.com",
|
|
4439
|
-
port: 993
|
|
4440
|
-
}
|
|
4441
|
-
};
|
|
4442
|
-
/** Read IMAP mailbox connection settings from the environment. */
|
|
4443
|
-
function imapConfigFromEnv(env = process.env) {
|
|
4444
|
-
const host = env["DXCRM_IMAP_HOST"];
|
|
4445
|
-
const user = env["DXCRM_IMAP_USER"];
|
|
4446
|
-
const pass = env["DXCRM_IMAP_PASS"];
|
|
4447
|
-
const accessToken = env["DXCRM_IMAP_TOKEN"];
|
|
4448
|
-
if (!host || !user || !pass && !accessToken) return null;
|
|
4449
|
-
return {
|
|
4450
|
-
host,
|
|
4451
|
-
port: env["DXCRM_IMAP_PORT"] ? Number(env["DXCRM_IMAP_PORT"]) : 993,
|
|
4452
|
-
secure: env["DXCRM_IMAP_SECURE"] !== "false",
|
|
4453
|
-
mailbox: env["DXCRM_IMAP_MAILBOX"] ?? "INBOX",
|
|
4454
|
-
auth: accessToken ? {
|
|
4455
|
-
user,
|
|
4456
|
-
accessToken
|
|
4457
|
-
} : {
|
|
4458
|
-
user,
|
|
4459
|
-
pass
|
|
4460
|
-
}
|
|
4461
|
-
};
|
|
4462
|
-
}
|
|
4463
|
-
/** Parse a "provider:user" account string. */
|
|
4464
|
-
function parseAccount(account) {
|
|
4465
|
-
const idx = account.indexOf(":");
|
|
4466
|
-
if (idx < 0) return null;
|
|
4467
|
-
const provider = account.slice(0, idx);
|
|
4468
|
-
const user = account.slice(idx + 1);
|
|
4469
|
-
if (provider !== "gmail" && provider !== "microsoft" || !user) return null;
|
|
4470
|
-
return {
|
|
4471
|
-
provider,
|
|
4472
|
-
user
|
|
4473
|
-
};
|
|
4474
|
-
}
|
|
4475
|
-
/** Build an IMAP config for a stored OAuth account, refreshing the token if needed. */
|
|
4476
|
-
async function resolveAccountConfig(dataDir, account, env = process.env, mailbox) {
|
|
4477
|
-
const parsed = parseAccount(account);
|
|
4478
|
-
if (!parsed) throw new Error(`Invalid --account '${account}'. Use 'gmail:you@gmail.com' or 'microsoft:you@org.com'.`);
|
|
4479
|
-
const { getFreshAccessToken } = await import("./token-resolver-BRLOmRvF.js");
|
|
4480
|
-
const accessToken = await getFreshAccessToken(dataDir, parsed.provider, parsed.user, { env });
|
|
4481
|
-
const { host, port } = PROVIDER_IMAP_HOST[parsed.provider];
|
|
4482
|
-
return {
|
|
4483
|
-
host,
|
|
4484
|
-
port,
|
|
4485
|
-
secure: true,
|
|
4486
|
-
mailbox: mailbox ?? env["DXCRM_IMAP_MAILBOX"] ?? "INBOX",
|
|
4487
|
-
auth: {
|
|
4488
|
-
user: parsed.user,
|
|
4489
|
-
accessToken
|
|
4490
|
-
}
|
|
4491
|
-
};
|
|
4492
|
-
}
|
|
4493
4486
|
/**
|
|
4494
4487
|
* Sync an IMAP mailbox (any provider). With a slug, all mail goes to that one
|
|
4495
4488
|
* customer; without, mail is auto-routed to customers by sender/recipient
|
|
@@ -4511,7 +4504,7 @@ async function runMailboxSync(opts) {
|
|
|
4511
4504
|
console.error(error(msg));
|
|
4512
4505
|
return { error: msg };
|
|
4513
4506
|
}
|
|
4514
|
-
const { syncImapMailbox } = await import("./imap-
|
|
4507
|
+
const { syncImapMailbox } = await import("./imap-DzeqMdZ3.js");
|
|
4515
4508
|
const result = await syncImapMailbox({
|
|
4516
4509
|
dataDir: opts.dataDir,
|
|
4517
4510
|
config,
|
|
@@ -4543,7 +4536,7 @@ async function runLogin(provider, user) {
|
|
|
4543
4536
|
return;
|
|
4544
4537
|
}
|
|
4545
4538
|
const account = user ?? (await ask("Gmail address: ")).trim();
|
|
4546
|
-
const { runGmailLogin } = await import("./login-
|
|
4539
|
+
const { runGmailLogin } = await import("./login-yt9OOQQk.js");
|
|
4547
4540
|
await runGmailLogin({
|
|
4548
4541
|
dataDir,
|
|
4549
4542
|
clientId,
|
|
@@ -4563,7 +4556,7 @@ async function runLogin(provider, user) {
|
|
|
4563
4556
|
}
|
|
4564
4557
|
const tenant = process.env["DXCRM_MS_TENANT"] ?? "common";
|
|
4565
4558
|
const account = user ?? (await ask("Outlook/Microsoft address: ")).trim();
|
|
4566
|
-
const { runMicrosoftLogin } = await import("./login-
|
|
4559
|
+
const { runMicrosoftLogin } = await import("./login-yt9OOQQk.js");
|
|
4567
4560
|
await runMicrosoftLogin({
|
|
4568
4561
|
dataDir,
|
|
4569
4562
|
clientId,
|
|
@@ -4612,6 +4605,7 @@ const ALL_COMMANDS = [
|
|
|
4612
4605
|
auditCommand,
|
|
4613
4606
|
logsCommand,
|
|
4614
4607
|
doctorCommand,
|
|
4608
|
+
pipelineCommand,
|
|
4615
4609
|
rbacCommand,
|
|
4616
4610
|
gdprCommand,
|
|
4617
4611
|
securityReportCommand,
|