@fleox-agent-crm/agentcrm 0.4.0 → 0.6.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/README.md +16 -16
- package/changelog.json +18 -0
- package/dist/admin/admin-files.json +1 -1
- package/dist/agent/agentcrm.mjs +188 -76
- package/dist/agent/chunks/{activities-Cj_SIOay.mjs → activities-be260oPg.mjs} +1 -1
- package/dist/agent/chunks/{automations-DwWruxmu.mjs → automations-gCDYNS88.mjs} +5 -5
- package/dist/agent/chunks/{backup-W3CjgkAJ.mjs → backup-DDqTRbuW.mjs} +4 -4
- package/dist/agent/chunks/{compact-BGHI92tm.mjs → compact-C_WX0_F5.mjs} +5 -5
- package/dist/agent/chunks/{dedupe-BepmsaHv.mjs → dedupe-isAmKHQV.mjs} +1 -1
- package/dist/agent/chunks/{exportCsv-C6e6XEmB.mjs → exportCsv-9ZMyqTdH.mjs} +3 -3
- package/dist/agent/chunks/{extCheck-GgHG1dYB.mjs → extCheck-BKh_9aLA.mjs} +4 -4
- package/dist/agent/chunks/{files-D1daDgY0.mjs → files-Be7DZd1a.mjs} +6 -6
- package/dist/agent/chunks/{forms-BfuWaQjA.mjs → forms-Bb0zztBM.mjs} +4 -4
- package/dist/agent/chunks/{importCsv-LVmMTaWU.mjs → importCsv-BuSYG4ja.mjs} +3 -3
- package/dist/agent/chunks/{install-BLNflFes.mjs → install-D1lgtRIH.mjs} +1 -1
- package/dist/agent/chunks/{loader-MPD9iAvh.mjs → loader-Bnu3GnMW.mjs} +14 -14
- package/dist/agent/chunks/{migrate-CsClnnN8.mjs → migrate-Cc_8MHZv.mjs} +1 -1
- package/dist/agent/chunks/{pipelines-BAKpPk1w.mjs → pipelines-G-c23x-s.mjs} +4 -4
- package/dist/agent/chunks/{records-DcHFelq5.mjs → records-BJLSmv0O.mjs} +2 -2
- package/dist/agent/chunks/{registry-COfJrSmg.mjs → registry-BpTyK6yU.mjs} +13 -13
- package/dist/agent/chunks/{relations-B9TynBmA.mjs → relations-bmUKPT0G.mjs} +4 -4
- package/dist/agent/chunks/{reports-BACHGccj.mjs → reports-ogUa41jr.mjs} +5 -5
- package/dist/agent/chunks/{runtime-C0Xf0Axi.mjs → runtime-D-hzk6s9.mjs} +20 -20
- package/dist/agent/chunks/{schema-C4lSslXv.mjs → schema-CYm_n5BN.mjs} +4 -4
- package/dist/agent/chunks/schemaApply-j5hbwPrH.mjs +169 -0
- package/dist/agent/chunks/{seed-6MRmQQBR.mjs → seed-Bb26Zsni.mjs} +2 -2
- package/dist/agent/chunks/{server-DC3t8r30.mjs → server-BAQwVNtC.mjs} +3 -3
- package/dist/agent/chunks/{standardObjects-CheqfDqa.mjs → standardObjects-vrmqIVLH.mjs} +1 -1
- package/dist/agent/chunks/{stats-BfuLWhVV.mjs → stats-bInarNLK.mjs} +4 -4
- package/dist/agent/chunks/syncRecords-69hcCgOK.mjs +102 -0
- package/dist/agent/chunks/{tools-iSH-yMpl.mjs → tools-BHmVIyP_.mjs} +12 -12
- package/dist/agent/chunks/{views-DH1n9Lrt.mjs → views-zRdsphZl.mjs} +5 -5
- package/dist/version.json +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/skills/agentcrm-admin/SKILL.md +67 -67
- package/plugin/skills/agentcrm-admin/references/records.md +5 -5
- package/plugin/skills/agentcrm-admin/references/schema.md +19 -19
- package/plugin/skills/agentcrm-extensions/SKILL.md +8 -8
- package/plugin/skills/agentcrm-extensions/references/module-recipes.md +2 -2
- package/plugin/skills/agentcrm-extensions/references/testing.md +14 -14
- package/plugin/skills/agentcrm-extensions/references/theme-recipes.md +3 -3
- package/plugin/skills/agentcrm-install/SKILL.md +13 -13
- package/plugin/skills/agentcrm-install/references/firebase.md +1 -1
- package/plugin/skills/agentcrm-install/references/github.md +1 -1
- package/plugin/skills/agentcrm-install/references/mcp.md +2 -2
- package/plugin/skills/agentcrm-install/references/plans.md +1 -1
- package/plugin/skills/agentcrm-install/references/s3.md +1 -1
- package/plugin/skills/agentcrm-manage/SKILL.md +15 -15
- package/plugin/skills/agentcrm-sales/SKILL.md +18 -18
package/dist/agent/agentcrm.mjs
CHANGED
|
@@ -142,7 +142,7 @@ const output = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
|
|
|
142
142
|
toCliError
|
|
143
143
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
144
144
|
const name = "@fleox-agent-crm/agentcrm";
|
|
145
|
-
const version = "0.
|
|
145
|
+
const version = "0.6.0";
|
|
146
146
|
const type = "module";
|
|
147
147
|
const description = "The static CRM your AI agent can run: a Twenty / HubSpot-style CRM that runs entirely in the browser or headless through the agentcrm CLI, with data on storage you own.";
|
|
148
148
|
const license = "SEE LICENSE IN LICENSE";
|
|
@@ -524,7 +524,7 @@ function tmpFolder() {
|
|
|
524
524
|
return tmpBase;
|
|
525
525
|
}
|
|
526
526
|
async function nodeImportBundle() {
|
|
527
|
-
await import("./chunks/runtime-
|
|
527
|
+
await import("./chunks/runtime-D-hzk6s9.mjs");
|
|
528
528
|
const { createNodeImportBundle } = await import("./chunks/nodeImport-ylfRDvqt.mjs");
|
|
529
529
|
return createNodeImportBundle({ runtimeDir: runtimeDir(), tmpDir: tmpFolder() });
|
|
530
530
|
}
|
|
@@ -539,7 +539,7 @@ async function loadSessionExtensions(store, opts = {}) {
|
|
|
539
539
|
if (!loadedAny && !opts.force && !hasEnabledExtensions(store)) return null;
|
|
540
540
|
try {
|
|
541
541
|
const importBundle = await nodeImportBundle();
|
|
542
|
-
const { syncExtensions } = await import("./chunks/loader-
|
|
542
|
+
const { syncExtensions } = await import("./chunks/loader-Bnu3GnMW.mjs");
|
|
543
543
|
loadedAny = true;
|
|
544
544
|
return await syncExtensions(store, { importBundle, onError: () => void 0 });
|
|
545
545
|
} catch (err) {
|
|
@@ -553,7 +553,7 @@ async function loadSessionExtensions(store, opts = {}) {
|
|
|
553
553
|
sync,
|
|
554
554
|
async close() {
|
|
555
555
|
if (!loadedAny) return;
|
|
556
|
-
(await import("./chunks/registry-
|
|
556
|
+
(await import("./chunks/registry-BpTyK6yU.mjs")).deactivateAllExtensions();
|
|
557
557
|
}
|
|
558
558
|
};
|
|
559
559
|
}
|
|
@@ -681,7 +681,7 @@ async function openSession(alias, opts = {}) {
|
|
|
681
681
|
const [{ createOpsContext }, { createPluginRegistry, plugins: defaultPlugins }, { installAutomations }] = await Promise.all([
|
|
682
682
|
import("./chunks/context-CxFfqS4D.mjs"),
|
|
683
683
|
import("./chunks/pluginRegistry-DyHtlkcr.mjs"),
|
|
684
|
-
import("./chunks/automations-
|
|
684
|
+
import("./chunks/automations-gCDYNS88.mjs")
|
|
685
685
|
]);
|
|
686
686
|
const own = createPluginRegistry((hook, err) => process.stderr.write(`[agentcrm] ${hook} handler failed: ${String(err?.message ?? err)}
|
|
687
687
|
`));
|
|
@@ -695,7 +695,7 @@ async function openSession(alias, opts = {}) {
|
|
|
695
695
|
const ctx = createOpsContext(store, user, { plugins, log });
|
|
696
696
|
const system = createOpsContext(store, null, { plugins, log });
|
|
697
697
|
if (opts.lock && (!user || user.role === "admin") && store.list("objects").length) {
|
|
698
|
-
const { migrateSchema } = await import("./chunks/migrate-
|
|
698
|
+
const { migrateSchema } = await import("./chunks/migrate-Cc_8MHZv.mjs").then((n) => n.c);
|
|
699
699
|
await migrateSchema(ctx).catch((err) => warnings.push(`Schema migration skipped: ${err.message}`));
|
|
700
700
|
}
|
|
701
701
|
if (site.hosting) {
|
|
@@ -714,7 +714,7 @@ async function openSession(alias, opts = {}) {
|
|
|
714
714
|
}
|
|
715
715
|
}
|
|
716
716
|
{
|
|
717
|
-
const forms = await import("./chunks/forms-
|
|
717
|
+
const forms = await import("./chunks/forms-Bb0zztBM.mjs");
|
|
718
718
|
const { buildConnector } = await import("./chunks/hosting-C_UDyMkm.mjs");
|
|
719
719
|
forms.setInboxSourceResolver((_ctx, form) => {
|
|
720
720
|
if (form.inbox.kind !== "s3") return null;
|
|
@@ -914,6 +914,29 @@ function table(rows, columns) {
|
|
|
914
914
|
const SITE_OPTION = { name: "site", type: "string", description: "Site alias (default: $AGENTCRM_SITE, ./agentcrm.json, the only site, or `site use`)." };
|
|
915
915
|
const AS_OPTION = { name: "as", type: "string", description: "Act as this CRM user (email or id) instead of the site's user." };
|
|
916
916
|
const YES_OPTION = { name: "yes", type: "boolean", description: "Apply — only after the user confirmed the plan." };
|
|
917
|
+
const util = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
918
|
+
__proto__: null,
|
|
919
|
+
AS_OPTION,
|
|
920
|
+
SITE_OPTION,
|
|
921
|
+
YES_OPTION,
|
|
922
|
+
boolOpt,
|
|
923
|
+
fieldsInput,
|
|
924
|
+
jsonObjectOpt,
|
|
925
|
+
jsonOpt,
|
|
926
|
+
listOpt,
|
|
927
|
+
multiOpt,
|
|
928
|
+
numOpt,
|
|
929
|
+
parseFilters,
|
|
930
|
+
parseScalar,
|
|
931
|
+
parseSorts,
|
|
932
|
+
positional,
|
|
933
|
+
readTextValue,
|
|
934
|
+
requireStr,
|
|
935
|
+
strOpt,
|
|
936
|
+
table,
|
|
937
|
+
usage,
|
|
938
|
+
writeOutFile
|
|
939
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
917
940
|
function fileOut(f) {
|
|
918
941
|
return {
|
|
919
942
|
id: f.id,
|
|
@@ -936,7 +959,7 @@ function readLocalFile(path) {
|
|
|
936
959
|
return { name: basename(full), bytes: new Uint8Array(readFileSync(full)) };
|
|
937
960
|
}
|
|
938
961
|
async function uploadLocalFiles(ctx, paths, targets2 = []) {
|
|
939
|
-
const { uploadFile } = await import("./chunks/files-
|
|
962
|
+
const { uploadFile } = await import("./chunks/files-Be7DZd1a.mjs");
|
|
940
963
|
const { guessMime, imageDimensions } = await import("./chunks/files-CjsPJSR6.mjs");
|
|
941
964
|
const out = [];
|
|
942
965
|
for (const p of paths) {
|
|
@@ -984,7 +1007,7 @@ const filesCommand = {
|
|
|
984
1007
|
switch (action) {
|
|
985
1008
|
case "list":
|
|
986
1009
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
987
|
-
const { listFiles } = await import("./chunks/files-
|
|
1010
|
+
const { listFiles } = await import("./chunks/files-Be7DZd1a.mjs");
|
|
988
1011
|
const target = strOpt(options, "record") ?? strOpt(options, "activity") ?? null;
|
|
989
1012
|
const items = listFiles(ctx, target, { includeRelated: boolOpt(options, "related"), kind: strOpt(options, "kind"), search: strOpt(options, "search") });
|
|
990
1013
|
const limit = Math.min(1e3, numOpt(options, "limit") ?? 100);
|
|
@@ -999,7 +1022,7 @@ ${table(r.files, ["id", "name", "mime", "size", "createdAt"])}`);
|
|
|
999
1022
|
if (record && activity) usage("Give --record or --activity, not both.");
|
|
1000
1023
|
for (const p of args) readLocalFile(p);
|
|
1001
1024
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1002
|
-
const { attachFile } = await import("./chunks/files-
|
|
1025
|
+
const { attachFile } = await import("./chunks/files-Be7DZd1a.mjs");
|
|
1003
1026
|
const files2 = await uploadLocalFiles(ctx, args, record ? [record] : []);
|
|
1004
1027
|
if (activity) for (const f of files2) await attachFile(ctx, f.id, { kind: "activity", id: activity });
|
|
1005
1028
|
const { requireFile } = await import("./chunks/store-5gqRSKXg.mjs");
|
|
@@ -1012,7 +1035,7 @@ ${table(r.uploaded, ["id", "name", "size"])}`);
|
|
|
1012
1035
|
const out = strOpt(options, "out");
|
|
1013
1036
|
if (!out) usage("files get needs --out <path>.");
|
|
1014
1037
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
1015
|
-
const { getFile, getFileBytes } = await import("./chunks/files-
|
|
1038
|
+
const { getFile, getFileBytes } = await import("./chunks/files-Be7DZd1a.mjs");
|
|
1016
1039
|
const meta = getFile(ctx, id);
|
|
1017
1040
|
const bytes = await getFileBytes(ctx, id, { thumb: boolOpt(options, "thumb") });
|
|
1018
1041
|
writeOutFile(out, bytes);
|
|
@@ -1022,7 +1045,7 @@ ${table(r.uploaded, ["id", "name", "size"])}`);
|
|
|
1022
1045
|
case "delete": {
|
|
1023
1046
|
const id = positional(args, 0, "file id", U$1.delete);
|
|
1024
1047
|
return withSession(io, options, { lock: options.yes === true }, async ({ ctx }) => {
|
|
1025
|
-
const { getFile, deleteFile } = await import("./chunks/files-
|
|
1048
|
+
const { getFile, deleteFile } = await import("./chunks/files-Be7DZd1a.mjs");
|
|
1026
1049
|
const meta = fileOut(getFile(ctx, id));
|
|
1027
1050
|
if (options.yes !== true) return { needsConfirmation: true, plan: { delete: meta } };
|
|
1028
1051
|
await deleteFile(ctx, id);
|
|
@@ -1030,7 +1053,7 @@ ${table(r.uploaded, ["id", "name", "size"])}`);
|
|
|
1030
1053
|
}, (r) => "plan" in r && r.plan ? `Would delete ${r.plan.delete.name} (${r.plan.delete.id}). Re-run with --yes once the user agrees.` : `Deleted ${"deleted" in r ? r.deleted : id} (bytes purged by \`agentcrm compact\`).`);
|
|
1031
1054
|
}
|
|
1032
1055
|
case "usage":
|
|
1033
|
-
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/files-
|
|
1056
|
+
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/files-Be7DZd1a.mjs")).fileUsage(ctx));
|
|
1034
1057
|
default:
|
|
1035
1058
|
usage(`Unknown files action "${action ?? ""}".`, "Use list, upload, get, delete or usage.");
|
|
1036
1059
|
}
|
|
@@ -1043,7 +1066,7 @@ async function recordImageAction(io, options, args) {
|
|
|
1043
1066
|
if (!remove && !path) usage("records image needs an image path (or --remove).");
|
|
1044
1067
|
const local = remove ? null : readLocalFile(path);
|
|
1045
1068
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1046
|
-
const { setRecordImage, clearRecordImage } = await import("./chunks/files-
|
|
1069
|
+
const { setRecordImage, clearRecordImage } = await import("./chunks/files-Be7DZd1a.mjs");
|
|
1047
1070
|
const field = strOpt(options, "field");
|
|
1048
1071
|
if (!local) {
|
|
1049
1072
|
const r = await clearRecordImage(ctx, recordId, field);
|
|
@@ -1137,7 +1160,7 @@ const activitiesCommand = {
|
|
|
1137
1160
|
const recs = multiOpt(options, "record");
|
|
1138
1161
|
if (!recs.length && type2 !== "task") usage("activities add needs --record <id> (repeatable).");
|
|
1139
1162
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1140
|
-
const { addActivity } = await import("./chunks/activities-
|
|
1163
|
+
const { addActivity } = await import("./chunks/activities-be260oPg.mjs");
|
|
1141
1164
|
return activityOut(
|
|
1142
1165
|
await addActivity(ctx, {
|
|
1143
1166
|
type: type2,
|
|
@@ -1154,7 +1177,7 @@ const activitiesCommand = {
|
|
|
1154
1177
|
}
|
|
1155
1178
|
case "list":
|
|
1156
1179
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
1157
|
-
const { listActivities } = await import("./chunks/activities-
|
|
1180
|
+
const { listActivities } = await import("./chunks/activities-be260oPg.mjs");
|
|
1158
1181
|
const types = listOpt(options, "type");
|
|
1159
1182
|
const page = listActivities(ctx, { target: multiOpt(options, "record")[0], types, includeRelated: boolOpt(options, "related"), limit: Math.min(500, numOpt(options, "limit") ?? 50) });
|
|
1160
1183
|
return { total: page.total, activities: page.items.map(activityOut) };
|
|
@@ -1162,7 +1185,7 @@ const activitiesCommand = {
|
|
|
1162
1185
|
${table(r.activities, ["id", "type", "title", "createdAt"])}`);
|
|
1163
1186
|
case "done": {
|
|
1164
1187
|
if (!id) usage("activities done needs an id.");
|
|
1165
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => activityOut(await (await import("./chunks/activities-
|
|
1188
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => activityOut(await (await import("./chunks/activities-be260oPg.mjs")).completeTask(ctx, id, !boolOpt(options, "undo"))));
|
|
1166
1189
|
}
|
|
1167
1190
|
default:
|
|
1168
1191
|
usage(`Unknown activities action "${action ?? ""}".`, "Use add, list or done.");
|
|
@@ -1183,7 +1206,7 @@ const notesCommand = {
|
|
|
1183
1206
|
if (!text?.trim()) usage("notes add needs --body.");
|
|
1184
1207
|
const files2 = attachPaths(options);
|
|
1185
1208
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1186
|
-
const ops = await import("./chunks/activities-
|
|
1209
|
+
const ops = await import("./chunks/activities-be260oPg.mjs");
|
|
1187
1210
|
const { recordOf } = await import("./chunks/store-5gqRSKXg.mjs");
|
|
1188
1211
|
const r = recordOf(ctx.store, id);
|
|
1189
1212
|
if (!files2.length || !r) return activityOut(await ops.addNote(ctx, id, text, strOpt(options, "title")));
|
|
@@ -1226,7 +1249,7 @@ const tasksCommand = {
|
|
|
1226
1249
|
switch (action) {
|
|
1227
1250
|
case "list":
|
|
1228
1251
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
1229
|
-
const { listTasks } = await import("./chunks/activities-
|
|
1252
|
+
const { listTasks } = await import("./chunks/activities-be260oPg.mjs");
|
|
1230
1253
|
const status = strOpt(options, "status") ?? "open";
|
|
1231
1254
|
if (!["open", "done", "all"].includes(status)) usage("--status must be open, done or all.");
|
|
1232
1255
|
const page = listTasks(ctx, { assigneeId: await assignee(ctx), target: multiOpt(options, "record")[0], status, overdue: boolOpt(options, "overdue"), dueWithinDays: numOpt(options, "due-within"), limit: Math.min(500, numOpt(options, "limit") ?? 50) });
|
|
@@ -1237,17 +1260,17 @@ ${table(r.tasks, ["id", "title", "dueAt", "assigneeId"])}`);
|
|
|
1237
1260
|
const title = requireStr(options, "title");
|
|
1238
1261
|
const files2 = attachPaths(options);
|
|
1239
1262
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1240
|
-
const { addActivity } = await import("./chunks/activities-
|
|
1263
|
+
const { addActivity } = await import("./chunks/activities-be260oPg.mjs");
|
|
1241
1264
|
return activityOut(await addActivity(ctx, { type: "task", title, body: body(options), dueAt: strOpt(options, "due"), assigneeId: await assignee(ctx) ?? ctx.user?.id, targets: targets(multiOpt(options, "record")), attachments: await attachments(ctx, files2) }));
|
|
1242
1265
|
});
|
|
1243
1266
|
}
|
|
1244
1267
|
case "done":
|
|
1245
1268
|
if (!id) usage("tasks done needs a task id.");
|
|
1246
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => activityOut(await (await import("./chunks/activities-
|
|
1269
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => activityOut(await (await import("./chunks/activities-be260oPg.mjs")).completeTask(ctx, id, !boolOpt(options, "undo"))));
|
|
1247
1270
|
case "reassign":
|
|
1248
1271
|
if (!id) usage("tasks reassign needs a task id.");
|
|
1249
1272
|
requireStr(options, "assignee");
|
|
1250
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => activityOut(await (await import("./chunks/activities-
|
|
1273
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => activityOut(await (await import("./chunks/activities-be260oPg.mjs")).updateActivity(ctx, id, { assigneeId: await assignee(ctx) ?? null })));
|
|
1251
1274
|
default:
|
|
1252
1275
|
usage(`Unknown tasks action "${action ?? ""}".`, "Use list, add, done or reassign.");
|
|
1253
1276
|
}
|
|
@@ -1278,11 +1301,12 @@ const U = {
|
|
|
1278
1301
|
search: "records search <query> [--object <id>]… [--limit n]",
|
|
1279
1302
|
duplicates: "records duplicates --object <id> [--by email,domain,name,phone]",
|
|
1280
1303
|
merge: "records merge <primaryId> <duplicateId>… [--yes]",
|
|
1281
|
-
image: "records image <recordId> <path> | --remove [--field <imageFieldId>]"
|
|
1304
|
+
image: "records image <recordId> <path> | --remove [--field <imageFieldId>]",
|
|
1305
|
+
sync: "records sync --object <id> --key <fieldId> --rows <json|@file|-> [--archive-field <fieldId>] [--ref-key <fieldId>] [--yes]"
|
|
1282
1306
|
};
|
|
1283
1307
|
const recordsCommand = {
|
|
1284
1308
|
name: "records",
|
|
1285
|
-
usage: "records <list|get|create|update|delete|restore|search|duplicates|merge|image> …",
|
|
1309
|
+
usage: "records <list|get|create|update|delete|restore|search|duplicates|merge|image|sync> …",
|
|
1286
1310
|
summary: "Records of any object (companies, people, deals, custom objects): list with filters / sorts / pagination, get with relations and timeline counts, create, update (only the given fields), soft delete / restore, full-text search, find and merge duplicates.",
|
|
1287
1311
|
subcommands: [
|
|
1288
1312
|
{ name: "list", usage: U.list, summary: `List records. Filter ops: ${FILTER_OPS.join(", ")}. Values: in/notIn comma-separated; dates YYYY-MM-DD, today, +30d.` },
|
|
@@ -1294,7 +1318,13 @@ const recordsCommand = {
|
|
|
1294
1318
|
{ name: "search", usage: U.search, summary: "Full-text search (names, emails, domains, phones)." },
|
|
1295
1319
|
{ name: "duplicates", usage: U.duplicates, summary: "Groups of likely duplicates (same email / domain / name / phone)." },
|
|
1296
1320
|
{ name: "merge", usage: U.merge, summary: "Merge duplicates into the primary (empty fields filled, relations and activities moved). Plan unless --yes.", writes: true, destructive: true },
|
|
1297
|
-
{ name: "image", usage: U.image, summary: "Set the record's avatar / logo from a local image (the object's image field), or --remove it.", writes: true }
|
|
1321
|
+
{ name: "image", usage: U.image, summary: "Set the record's avatar / logo from a local image (the object's image field), or --remove it.", writes: true },
|
|
1322
|
+
{
|
|
1323
|
+
name: "sync",
|
|
1324
|
+
usage: U.sync,
|
|
1325
|
+
summary: 'Mirror an external source into one object: rows [{ key, fields }] matched on the --key field, created / updated only where a value differs; relation values reference other mirrored records by their key ({ "$key": "12" } or { "$key": ["12","13"] }); records whose key is missing get --archive-field = true (never deleted). No automation fires. Plan unless --yes.',
|
|
1326
|
+
writes: true
|
|
1327
|
+
}
|
|
1298
1328
|
],
|
|
1299
1329
|
options: [
|
|
1300
1330
|
SITE_OPTION,
|
|
@@ -1315,7 +1345,11 @@ const recordsCommand = {
|
|
|
1315
1345
|
{ name: "hard", type: "boolean", description: "delete: remove immediately (no restore)." },
|
|
1316
1346
|
{ name: "by", type: "string", description: "duplicates: email,domain,name,phone." },
|
|
1317
1347
|
{ name: "remove", type: "boolean", description: "image: remove the record's image." },
|
|
1318
|
-
{ name: "field", type: "string", description: "image: image field id (default: the object's image field)." }
|
|
1348
|
+
{ name: "field", type: "string", description: "image: image field id (default: the object's image field)." },
|
|
1349
|
+
{ name: "key", type: "string", description: "sync: field holding the source id (match key)." },
|
|
1350
|
+
{ name: "rows", type: "string", description: "sync: rows as a JSON array [{ key, fields }], @file.json or - (stdin)." },
|
|
1351
|
+
{ name: "archive-field", type: "string", description: "sync: boolean field set to true on records whose key is missing from the rows." },
|
|
1352
|
+
{ name: "ref-key", type: "string", description: 'sync: key field of related objects for { "$key": … } (default: --key).' }
|
|
1319
1353
|
],
|
|
1320
1354
|
async run({ io, options, positionals }) {
|
|
1321
1355
|
const [action, ...args] = positionals;
|
|
@@ -1331,7 +1365,7 @@ const recordsCommand = {
|
|
|
1331
1365
|
const filters = parseFilters(multiOpt(options, "filter"), FILTER_OPS);
|
|
1332
1366
|
const sorts = parseSorts(multiOpt(options, "sort"));
|
|
1333
1367
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
1334
|
-
const { listRecords } = await import("./chunks/records-
|
|
1368
|
+
const { listRecords } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1335
1369
|
const page = listRecords(ctx, objectId, {
|
|
1336
1370
|
filters,
|
|
1337
1371
|
sorts,
|
|
@@ -1349,7 +1383,7 @@ ${table(r.records, ["id", "label", "updatedAt"])}`);
|
|
|
1349
1383
|
case "get": {
|
|
1350
1384
|
const id = positional(args, 0, "record id", U.get);
|
|
1351
1385
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
1352
|
-
const { getRecordDetails } = await import("./chunks/records-
|
|
1386
|
+
const { getRecordDetails } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1353
1387
|
const d = getRecordDetails(ctx, id);
|
|
1354
1388
|
return { ...await recordOut(ctx, d.record), relations: d.relations, related: d.inverse.filter((i) => i.records.length), activityCount: d.activityCount };
|
|
1355
1389
|
});
|
|
@@ -1360,7 +1394,7 @@ ${table(r.records, ["id", "label", "updatedAt"])}`);
|
|
|
1360
1394
|
if (!Object.keys(fields).length) usage("records create needs --fields or --set.", `Usage: agentcrm ${U.create}`);
|
|
1361
1395
|
const owner = strOpt(options, "owner");
|
|
1362
1396
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1363
|
-
const { createRecord } = await import("./chunks/records-
|
|
1397
|
+
const { createRecord } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1364
1398
|
return recordOut(ctx, await createRecord(ctx, objectId, fields, owner ? { ownerId: owner } : {}));
|
|
1365
1399
|
}, (r) => `Created ${r.object} ${r.id} (${String(r.label)})`);
|
|
1366
1400
|
}
|
|
@@ -1370,7 +1404,7 @@ ${table(r.records, ["id", "label", "updatedAt"])}`);
|
|
|
1370
1404
|
const owner = strOpt(options, "owner");
|
|
1371
1405
|
if (!Object.keys(fields).length && owner === void 0) usage("records update needs --fields, --set or --owner.");
|
|
1372
1406
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1373
|
-
const { updateRecord } = await import("./chunks/records-
|
|
1407
|
+
const { updateRecord } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1374
1408
|
return recordOut(ctx, await updateRecord(ctx, id, fields, owner !== void 0 ? { ownerId: owner || null } : {}));
|
|
1375
1409
|
}, (r) => `Updated ${r.id} (${String(r.label)})`);
|
|
1376
1410
|
}
|
|
@@ -1378,7 +1412,7 @@ ${table(r.records, ["id", "label", "updatedAt"])}`);
|
|
|
1378
1412
|
if (!args.length) usage("records delete needs at least one id.", `Usage: agentcrm ${U.delete}`);
|
|
1379
1413
|
const hard = boolOpt(options, "hard");
|
|
1380
1414
|
return withSession(io, options, { lock: options.yes === true }, async ({ ctx }) => {
|
|
1381
|
-
const { getRecord, deleteRecord, bulkDelete } = await import("./chunks/records-
|
|
1415
|
+
const { getRecord, deleteRecord, bulkDelete } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1382
1416
|
const { recordLabel } = await import("./chunks/fields-B0bitgmr.mjs");
|
|
1383
1417
|
const { objectOf } = await import("./chunks/store-5gqRSKXg.mjs");
|
|
1384
1418
|
const targets2 = args.map((id) => getRecord(ctx, id, { includeDeleted: true }));
|
|
@@ -1391,7 +1425,7 @@ ${table(r.records, ["id", "label", "updatedAt"])}`);
|
|
|
1391
1425
|
case "restore": {
|
|
1392
1426
|
const id = positional(args, 0, "record id", U.restore);
|
|
1393
1427
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
1394
|
-
const { restoreRecord } = await import("./chunks/records-
|
|
1428
|
+
const { restoreRecord } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1395
1429
|
return recordOut(ctx, await restoreRecord(ctx, id));
|
|
1396
1430
|
});
|
|
1397
1431
|
}
|
|
@@ -1399,14 +1433,14 @@ ${table(r.records, ["id", "label", "updatedAt"])}`);
|
|
|
1399
1433
|
const query = args.join(" ").trim();
|
|
1400
1434
|
if (!query) usage("records search needs a query.", `Usage: agentcrm ${U.search}`);
|
|
1401
1435
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
1402
|
-
const { searchRecords } = await import("./chunks/records-
|
|
1436
|
+
const { searchRecords } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1403
1437
|
return searchRecords(ctx, query, { objects: listOpt(options, "object"), limit: Math.min(100, numOpt(options, "limit") ?? 20) });
|
|
1404
1438
|
});
|
|
1405
1439
|
}
|
|
1406
1440
|
case "duplicates": {
|
|
1407
1441
|
const objectId = object();
|
|
1408
1442
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
1409
|
-
const { findDuplicates } = await import("./chunks/dedupe-
|
|
1443
|
+
const { findDuplicates } = await import("./chunks/dedupe-isAmKHQV.mjs");
|
|
1410
1444
|
const by = listOpt(options, "by");
|
|
1411
1445
|
const groups = findDuplicates(ctx, objectId, by ? { by } : {});
|
|
1412
1446
|
return { object: objectId, groups: groups.length, duplicates: groups };
|
|
@@ -1416,19 +1450,48 @@ ${table(r.records, ["id", "label", "updatedAt"])}`);
|
|
|
1416
1450
|
const [primary, ...dups] = args;
|
|
1417
1451
|
if (!primary || !dups.length) usage("records merge needs <primaryId> <duplicateId>….", `Usage: agentcrm ${U.merge}`);
|
|
1418
1452
|
return withSession(io, options, { lock: options.yes === true }, async ({ ctx }) => {
|
|
1419
|
-
const { getRecord } = await import("./chunks/records-
|
|
1453
|
+
const { getRecord } = await import("./chunks/records-BJLSmv0O.mjs");
|
|
1420
1454
|
const all = [primary, ...dups].map((id) => getRecord(ctx, id));
|
|
1421
1455
|
const plan = { primary: await recordOut(ctx, all[0]), duplicates: await Promise.all(all.slice(1).map((r) => recordOut(ctx, r))) };
|
|
1422
1456
|
if (options.yes !== true) return { needsConfirmation: true, plan };
|
|
1423
|
-
const { mergeRecords } = await import("./chunks/dedupe-
|
|
1457
|
+
const { mergeRecords } = await import("./chunks/dedupe-isAmKHQV.mjs");
|
|
1424
1458
|
const res = await mergeRecords(ctx, primary, dups);
|
|
1425
1459
|
return { record: await recordOut(ctx, res.record), merged: res.merged, movedActivities: res.movedActivities };
|
|
1426
1460
|
}, (r) => "plan" in r && r.plan ? `Would merge ${r.plan.duplicates.length} duplicate(s) into ${r.plan.primary.id}. Re-run with --yes once the user agrees.` : "merged" in r ? `Merged ${r.merged.length} into ${r.record.id}` : "");
|
|
1427
1461
|
}
|
|
1428
1462
|
case "image":
|
|
1429
1463
|
return (await Promise.resolve().then(() => files)).recordImageAction(io, options, args);
|
|
1464
|
+
case "sync": {
|
|
1465
|
+
const objectId = Array.isArray(options.object) ? options.object[0] : options.object;
|
|
1466
|
+
const key = strOpt(options, "key");
|
|
1467
|
+
const rowsRaw = strOpt(options, "rows");
|
|
1468
|
+
if (!objectId || !key || !rowsRaw) usage("records sync needs --object, --key and --rows.", `Usage: agentcrm ${U.sync}`);
|
|
1469
|
+
const { readTextValue: readTextValue2 } = await Promise.resolve().then(() => util);
|
|
1470
|
+
let rows;
|
|
1471
|
+
try {
|
|
1472
|
+
rows = JSON.parse(readTextValue2(rowsRaw, "rows"));
|
|
1473
|
+
} catch (err) {
|
|
1474
|
+
usage(`--rows is not valid JSON: ${err.message}`);
|
|
1475
|
+
}
|
|
1476
|
+
if (!Array.isArray(rows)) usage("--rows must be a JSON array of { key, fields }.");
|
|
1477
|
+
const spec = { object: objectId, key, rows, archiveField: strOpt(options, "archive-field"), refKey: strOpt(options, "ref-key") };
|
|
1478
|
+
const apply = options.yes === true;
|
|
1479
|
+
return withSession(io, options, { lock: apply }, async ({ ctx }) => {
|
|
1480
|
+
const { syncRecords } = await import("./chunks/syncRecords-69hcCgOK.mjs");
|
|
1481
|
+
if (apply) return syncRecords(ctx, spec);
|
|
1482
|
+
const { dryRun: dryRun2 } = await Promise.resolve().then(() => dryRun$1);
|
|
1483
|
+
const { result } = await dryRun2(ctx, (copy) => syncRecords(copy, spec));
|
|
1484
|
+
const pending = result.created + result.updated + result.archived;
|
|
1485
|
+
return pending ? { needsConfirmation: true, plan: result } : result;
|
|
1486
|
+
}, (r) => {
|
|
1487
|
+
const s = "needsConfirmation" in r ? r.plan : r;
|
|
1488
|
+
const line = `${s.object}: ${s.rows} rows → ${s.created} new, ${s.updated} updated, ${s.unchanged} unchanged, ${s.archived} archived${s.unresolved ? `, ${s.unresolved} unresolved references` : ""}${s.errors.length ? `, ${s.errors.length} errors (first: ${s.errors[0].key}: ${s.errors[0].message})` : ""}`;
|
|
1489
|
+
return "needsConfirmation" in r ? `${line}
|
|
1490
|
+
Nothing changed — re-run with --yes once the user agrees.` : line;
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1430
1493
|
default:
|
|
1431
|
-
usage(`Unknown records action "${action ?? ""}".`, "Use list, get, create, update, delete, restore, search, duplicates, merge or
|
|
1494
|
+
usage(`Unknown records action "${action ?? ""}".`, "Use list, get, create, update, delete, restore, search, duplicates, merge, image or sync.");
|
|
1432
1495
|
}
|
|
1433
1496
|
}
|
|
1434
1497
|
};
|
|
@@ -1448,13 +1511,13 @@ const pipelinesCommand = {
|
|
|
1448
1511
|
io,
|
|
1449
1512
|
options,
|
|
1450
1513
|
{},
|
|
1451
|
-
async ({ ctx }) => (await import("./chunks/pipelines-
|
|
1514
|
+
async ({ ctx }) => (await import("./chunks/pipelines-G-c23x-s.mjs")).listPipelines(ctx, strOpt(options, "object")),
|
|
1452
1515
|
(ps) => ps.map((p) => `${p.id} (${p.name}, ${p.object}): ${p.stages.map((s) => `${s.label} ${Math.round(s.probability * (s.probability <= 1 ? 100 : 1))}%`).join(" → ")}`).join("\n")
|
|
1453
1516
|
);
|
|
1454
1517
|
}
|
|
1455
1518
|
if (action === "move") {
|
|
1456
1519
|
if (!id || !stage.length) usage("pipelines move needs <recordId> <stage>.");
|
|
1457
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => recordOut(ctx, await (await import("./chunks/pipelines-
|
|
1520
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => recordOut(ctx, await (await import("./chunks/pipelines-G-c23x-s.mjs")).moveStage(ctx, id, stage.join(" "), { lostReason: strOpt(options, "lost-reason") })));
|
|
1458
1521
|
}
|
|
1459
1522
|
usage(`Unknown pipelines action "${action}".`, "Use list or move.");
|
|
1460
1523
|
}
|
|
@@ -1486,7 +1549,7 @@ const viewsCommand = {
|
|
|
1486
1549
|
const [action = "list", id] = positionals;
|
|
1487
1550
|
switch (action) {
|
|
1488
1551
|
case "list":
|
|
1489
|
-
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/views-
|
|
1552
|
+
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/views-zRdsphZl.mjs")).listViews(ctx, strOpt(options, "object")), (vs) => table(vs, ["id", "object", "name", "type", "shared"]));
|
|
1490
1553
|
case "create": {
|
|
1491
1554
|
const type2 = strOpt(options, "type") ?? "table";
|
|
1492
1555
|
if (type2 !== "table" && type2 !== "kanban") usage("--type must be table or kanban.");
|
|
@@ -1501,12 +1564,12 @@ const viewsCommand = {
|
|
|
1501
1564
|
...strOpt(options, "pipeline") ? { pipelineId: strOpt(options, "pipeline") } : {},
|
|
1502
1565
|
shared: boolOpt(options, "shared")
|
|
1503
1566
|
};
|
|
1504
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/views-
|
|
1567
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/views-zRdsphZl.mjs")).createView(ctx, input));
|
|
1505
1568
|
}
|
|
1506
1569
|
case "delete":
|
|
1507
1570
|
if (!id) usage("views delete needs a view id.");
|
|
1508
1571
|
return withSession(io, options, { lock: options.yes === true }, async ({ ctx }) => {
|
|
1509
|
-
const { getView, deleteView } = await import("./chunks/views-
|
|
1572
|
+
const { getView, deleteView } = await import("./chunks/views-zRdsphZl.mjs");
|
|
1510
1573
|
const v = getView(ctx, id);
|
|
1511
1574
|
if (options.yes !== true) return { needsConfirmation: true, plan: { delete: { id: v.id, name: v.name, object: v.object, shared: v.shared } } };
|
|
1512
1575
|
return deleteView(ctx, id);
|
|
@@ -1833,6 +1896,10 @@ async function dryRun(ctx, work) {
|
|
|
1833
1896
|
const copy = createOpsContext(store, ctx.user, { now: ctx.now, plugins: createPluginRegistry(() => void 0) });
|
|
1834
1897
|
return { result: await work(copy), store };
|
|
1835
1898
|
}
|
|
1899
|
+
const dryRun$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1900
|
+
__proto__: null,
|
|
1901
|
+
dryRun
|
|
1902
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1836
1903
|
const CASCADE_OPTION = { name: "cascade", type: "boolean", description: "enable / disable: also enable the dependencies / disable the dependents." };
|
|
1837
1904
|
function parseJsonValue(raw, name2) {
|
|
1838
1905
|
const text = readTextValue(raw, name2);
|
|
@@ -2097,7 +2164,7 @@ async function check({ io, options, positionals }) {
|
|
|
2097
2164
|
const kind = strOpt(options, "kind");
|
|
2098
2165
|
if (kind && kind !== "module" && kind !== "theme") usage("--kind is module or theme.");
|
|
2099
2166
|
const { readRawPackage } = await import("./chunks/extPackage-DuZ6GZhp.mjs");
|
|
2100
|
-
const { checkExtension } = await import("./chunks/extCheck-
|
|
2167
|
+
const { checkExtension } = await import("./chunks/extCheck-BKh_9aLA.mjs");
|
|
2101
2168
|
const raw = await readRawPackage(target);
|
|
2102
2169
|
const report = await checkExtension(raw, { kind, callTools: !boolOpt(options, "no-call") });
|
|
2103
2170
|
printResult(io, report, () => {
|
|
@@ -2144,7 +2211,7 @@ async function install({ io, options, positionals }) {
|
|
|
2144
2211
|
const apply = options.yes === true;
|
|
2145
2212
|
const disabled = boolOpt(options, "disabled");
|
|
2146
2213
|
if (!boolOpt(options, "force")) {
|
|
2147
|
-
const { checkExtension } = await import("./chunks/extCheck-
|
|
2214
|
+
const { checkExtension } = await import("./chunks/extCheck-BKh_9aLA.mjs");
|
|
2148
2215
|
const report = await checkExtension(raw, { callTools: false });
|
|
2149
2216
|
if (!report.valid) {
|
|
2150
2217
|
throw new CliError(
|
|
@@ -2180,7 +2247,7 @@ async function install({ io, options, positionals }) {
|
|
|
2180
2247
|
}
|
|
2181
2248
|
const result = await ext.installExtension(s.ctx, pkg2, disabled ? { enabled: false } : {});
|
|
2182
2249
|
const report = await s.extensions.sync();
|
|
2183
|
-
const { getLoadedExtension } = await import("./chunks/registry-
|
|
2250
|
+
const { getLoadedExtension } = await import("./chunks/registry-BpTyK6yU.mjs");
|
|
2184
2251
|
const loaded = getLoadedExtension(m.id);
|
|
2185
2252
|
const failure = report?.failed.find((f) => f.id === m.id || f.id === "*");
|
|
2186
2253
|
if (failure && !loaded) return { ...result, author: m.author ?? null, load: { status: "error", error: failure.error } };
|
|
@@ -2242,7 +2309,7 @@ const extCommand = {
|
|
|
2242
2309
|
if (kind && kind !== "module" && kind !== "theme") usage("--kind is module or theme.");
|
|
2243
2310
|
return withSession(io, options, {}, async (s) => {
|
|
2244
2311
|
const { listExtensions } = await import("./chunks/extensions-Bp72uZ9a.mjs");
|
|
2245
|
-
const { getLoadedExtension } = await import("./chunks/registry-
|
|
2312
|
+
const { getLoadedExtension } = await import("./chunks/registry-BpTyK6yU.mjs");
|
|
2246
2313
|
return listExtensions(s.ctx, kind ? { kind } : {}).map((e) => ({ ...e, load: s.extensions.safeMode ? "skipped" : getLoadedExtension(e.id)?.status ?? (e.enabled ? "not loaded" : "disabled"), ...getLoadedExtension(e.id)?.error ? { loadError: getLoadedExtension(e.id)?.error } : {} }));
|
|
2247
2314
|
}, (rows) => table(rows.map((r) => ({ ...r, enabled: r.enabled ? "yes" : "no" })), ["id", "kind", "name", "version", "enabled", "load", "author"]));
|
|
2248
2315
|
}
|
|
@@ -2357,7 +2424,7 @@ const importCommand = {
|
|
|
2357
2424
|
options,
|
|
2358
2425
|
{},
|
|
2359
2426
|
async ({ ctx }) => {
|
|
2360
|
-
const plan = await (await import("./chunks/backup-
|
|
2427
|
+
const plan = await (await import("./chunks/backup-DDqTRbuW.mjs")).planBackupZip(ctx, bytes, { mode: options.replace === true ? "replace" : "merge" });
|
|
2361
2428
|
return { needsConfirmation: true, plan: { restore: resolve(path), bytes: bytes.length, ...plan } };
|
|
2362
2429
|
},
|
|
2363
2430
|
(r) => [
|
|
@@ -2367,7 +2434,7 @@ const importCommand = {
|
|
|
2367
2434
|
].join("\n")
|
|
2368
2435
|
);
|
|
2369
2436
|
}
|
|
2370
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/backup-
|
|
2437
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/backup-DDqTRbuW.mjs")).importBackupZip(ctx, bytes, { mode: options.replace === true ? "replace" : "merge" }), (r) => `Restored ${r.written} document(s) and ${r.files} file(s)`);
|
|
2371
2438
|
}
|
|
2372
2439
|
if (kind !== "csv") usage('Only "import csv" and "import zip" are supported.', "Usage: agentcrm import csv <file> --object <id>");
|
|
2373
2440
|
const source = positional(positionals, 1, "CSV file (or -)", "import csv <file|-> --object <id>");
|
|
@@ -2378,7 +2445,7 @@ const importCommand = {
|
|
|
2378
2445
|
const apply = options.yes === true && options["dry-run"] !== true;
|
|
2379
2446
|
const shown = numOpt(options, "rows") ?? 100;
|
|
2380
2447
|
return withSession(io, options, { lock: apply }, async ({ ctx }) => {
|
|
2381
|
-
const { importCsv } = await import("./chunks/importCsv-
|
|
2448
|
+
const { importCsv } = await import("./chunks/importCsv-BuSYG4ja.mjs");
|
|
2382
2449
|
const report = await importCsv(ctx, {
|
|
2383
2450
|
object: objectId,
|
|
2384
2451
|
csv,
|
|
@@ -2427,7 +2494,7 @@ const exportCommand = {
|
|
|
2427
2494
|
const file2 = strOpt(options, "out");
|
|
2428
2495
|
if (!file2) usage("export zip needs --out <file.zip>.");
|
|
2429
2496
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
2430
|
-
const { exportBackupZip } = await import("./chunks/backup-
|
|
2497
|
+
const { exportBackupZip } = await import("./chunks/backup-DDqTRbuW.mjs");
|
|
2431
2498
|
const { zip, report } = await exportBackupZip(ctx, { includeFiles: options["no-files"] !== true });
|
|
2432
2499
|
writeOutFile(file2, zip);
|
|
2433
2500
|
return { file: resolve(file2), zipBytes: zip.length, files: report.files, missing: report.missing, fileBytes: report.bytes };
|
|
@@ -2446,7 +2513,7 @@ const exportCommand = {
|
|
|
2446
2513
|
const filters = parseFilters(multiOpt(options, "filter"), FILTER_OPS);
|
|
2447
2514
|
const sorts = parseSorts(multiOpt(options, "sort"));
|
|
2448
2515
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
2449
|
-
const { exportCsv } = await import("./chunks/exportCsv-
|
|
2516
|
+
const { exportCsv } = await import("./chunks/exportCsv-9ZMyqTdH.mjs");
|
|
2450
2517
|
const csv = exportCsv(ctx, objectId, {
|
|
2451
2518
|
viewId: strOpt(options, "view"),
|
|
2452
2519
|
filters,
|
|
@@ -2462,7 +2529,7 @@ const exportCommand = {
|
|
|
2462
2529
|
}
|
|
2463
2530
|
if (kind === "json") {
|
|
2464
2531
|
return withSession(io, options, {}, async ({ ctx }) => {
|
|
2465
|
-
const { exportJson } = await import("./chunks/exportCsv-
|
|
2532
|
+
const { exportJson } = await import("./chunks/exportCsv-9ZMyqTdH.mjs");
|
|
2466
2533
|
const data = exportJson(ctx, { collections: listOpt(options, "collections") });
|
|
2467
2534
|
const text = JSON.stringify(data, null, 2);
|
|
2468
2535
|
if (out) return deliver(text, {});
|
|
@@ -2506,7 +2573,7 @@ const reportCommand = {
|
|
|
2506
2573
|
...strOpt(options, "pipeline") ? { pipelineId: strOpt(options, "pipeline") } : {},
|
|
2507
2574
|
...strOpt(options, "owner") ? { ownerId: strOpt(options, "owner") } : {}
|
|
2508
2575
|
};
|
|
2509
|
-
return withSession(io, options, {}, async ({ ctx }) => ({ report: name2, data: (await import("./chunks/reports-
|
|
2576
|
+
return withSession(io, options, {}, async ({ ctx }) => ({ report: name2, data: (await import("./chunks/reports-ogUa41jr.mjs")).runReport(ctx, internal, params) }));
|
|
2510
2577
|
}
|
|
2511
2578
|
};
|
|
2512
2579
|
const statsCommand = {
|
|
@@ -2516,7 +2583,7 @@ const statsCommand = {
|
|
|
2516
2583
|
options: [SITE_OPTION, AS_OPTION],
|
|
2517
2584
|
async run({ io, options }) {
|
|
2518
2585
|
return withSession(io, options, {}, async ({ ctx, store }) => {
|
|
2519
|
-
const stats = (await import("./chunks/stats-
|
|
2586
|
+
const stats = (await import("./chunks/stats-bInarNLK.mjs")).getStats(ctx);
|
|
2520
2587
|
const journal = store.stats;
|
|
2521
2588
|
return { ...stats, ...journal ? { journal: await journal.call(store) } : {} };
|
|
2522
2589
|
}, (s) => [`backend: ${s.backend}`, ...s.objects.map((o) => ` ${o.label}: ${o.count}${o.deleted ? ` (+${o.deleted} deleted)` : ""}`), `open tasks: ${s.openTasks} (${s.overdueTasks} overdue)`, `users: ${s.users}`].join("\n"));
|
|
@@ -2530,7 +2597,7 @@ const compactCommand = {
|
|
|
2530
2597
|
async run({ io, options }) {
|
|
2531
2598
|
const apply = options.yes === true;
|
|
2532
2599
|
return withSession(io, options, { lock: apply }, async ({ ctx }) => {
|
|
2533
|
-
const { compactData } = await import("./chunks/compact-
|
|
2600
|
+
const { compactData } = await import("./chunks/compact-C_WX0_F5.mjs");
|
|
2534
2601
|
const report = await compactData(ctx, { olderThanDays: numOpt(options, "older-than"), keepRuns: numOpt(options, "keep-runs"), dryRun: !apply });
|
|
2535
2602
|
return apply ? report : { needsConfirmation: true, plan: report };
|
|
2536
2603
|
}, (r) => "plan" in r ? `Would purge ${r.plan.purgedRecords.length} record(s), ${r.plan.purgedActivities} activit(ies), ${r.plan.purgedRuns} run(s), ${r.plan.purgedFiles} file(s). Re-run with --yes once the user agrees.` : `Purged ${r.purgedRecords.length} record(s), ${r.purgedFiles} file(s); storage compacted: ${r.storageCompacted}`);
|
|
@@ -2551,19 +2618,19 @@ const automationsCommand = {
|
|
|
2551
2618
|
const [action = "list", id] = positionals;
|
|
2552
2619
|
switch (action) {
|
|
2553
2620
|
case "list":
|
|
2554
|
-
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/automations-
|
|
2621
|
+
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/automations-gCDYNS88.mjs")).listAutomations(ctx).map((a) => ({ id: a.id, name: a.name, enabled: a.enabled, object: a.object, trigger: a.trigger, actions: a.actions.map((x) => x.type), lastRunAt: a.lastRunAt ? new Date(a.lastRunAt).toISOString() : null })), (rows) => table(rows, ["id", "name", "enabled", "object", "lastRunAt"]));
|
|
2555
2622
|
case "enable":
|
|
2556
2623
|
case "disable": {
|
|
2557
2624
|
if (!id) usage(`automations ${action} needs an id.`);
|
|
2558
2625
|
return withSession(io, options, { lock: true }, async ({ ctx }) => {
|
|
2559
|
-
const mod = await import("./chunks/automations-
|
|
2626
|
+
const mod = await import("./chunks/automations-gCDYNS88.mjs");
|
|
2560
2627
|
return mod.setAutomationEnabled(ctx, id, action === "enable");
|
|
2561
2628
|
});
|
|
2562
2629
|
}
|
|
2563
2630
|
case "run": {
|
|
2564
2631
|
const apply = options.yes === true;
|
|
2565
2632
|
return withSession(io, options, { lock: apply }, async ({ ctx }) => {
|
|
2566
|
-
const { runScheduled } = await import("./chunks/automations-
|
|
2633
|
+
const { runScheduled } = await import("./chunks/automations-gCDYNS88.mjs");
|
|
2567
2634
|
const report = await runScheduled(ctx, { dryRun: !apply, automationId: strOpt(options, "id"), force: boolOpt(options, "force") });
|
|
2568
2635
|
return apply ? report : { needsConfirmation: true, ...report };
|
|
2569
2636
|
}, (r) => `${"needsConfirmation" in r ? "DRY RUN — " : ""}ran ${r.ran}, skipped ${r.skipped}, errors ${r.errors}`);
|
|
@@ -2587,11 +2654,11 @@ const formsCommand = {
|
|
|
2587
2654
|
const [action = "list", id] = positionals;
|
|
2588
2655
|
switch (action) {
|
|
2589
2656
|
case "list":
|
|
2590
|
-
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/forms-
|
|
2657
|
+
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/forms-Bb0zztBM.mjs")).listForms(ctx), (fs) => table(fs, ["id", "name", "object", "publishedPath"]));
|
|
2591
2658
|
case "publish": {
|
|
2592
2659
|
if (!id) usage("forms publish needs a form id.");
|
|
2593
2660
|
return withSession(io, options, { lock: options.yes === true }, async (s) => {
|
|
2594
|
-
const forms = await import("./chunks/forms-
|
|
2661
|
+
const forms = await import("./chunks/forms-Bb0zztBM.mjs");
|
|
2595
2662
|
const built = await forms.buildFormHtml(s.ctx, id);
|
|
2596
2663
|
const target = s.hostingTarget();
|
|
2597
2664
|
if (!target) usage(`${s.site.alias} has no hosting to publish the form to.`);
|
|
@@ -2605,7 +2672,7 @@ const formsCommand = {
|
|
|
2605
2672
|
case "ingest": {
|
|
2606
2673
|
const apply = options.yes === true;
|
|
2607
2674
|
return withSession(io, options, { lock: apply }, async ({ ctx }) => {
|
|
2608
|
-
const { ingestInbox } = await import("./chunks/forms-
|
|
2675
|
+
const { ingestInbox } = await import("./chunks/forms-Bb0zztBM.mjs");
|
|
2609
2676
|
const report = await ingestInbox(ctx, strOpt(options, "form"), { dryRun: !apply, limit: numOpt(options, "limit") });
|
|
2610
2677
|
return apply ? report : { needsConfirmation: true, ...report };
|
|
2611
2678
|
}, (r) => `${"needsConfirmation" in r ? "DRY RUN — " : ""}processed ${r.processed}: ${r.created} created, ${r.updated} updated, ${r.failed} failed`);
|
|
@@ -2845,7 +2912,7 @@ async function runDoctor(site, opts = {}) {
|
|
|
2845
2912
|
installBrowserEnv();
|
|
2846
2913
|
try {
|
|
2847
2914
|
if (site.runtime.backend === "journal" && site.runtime.journal.connectorId === "git-pages") {
|
|
2848
|
-
const { probeTarget } = await import("./chunks/install-
|
|
2915
|
+
const { probeTarget } = await import("./chunks/install-D1lgtRIH.mjs");
|
|
2849
2916
|
const { dataTargetOf: dataTargetOf2 } = await Promise.resolve().then(() => session);
|
|
2850
2917
|
const probe = await probeTarget(dataTargetOf2(site), { requireSiteUrl: false, requirePrivate: true });
|
|
2851
2918
|
add(probe.ok ? { id: "data-repo", status: "ok", message: probe.detail } : { id: "data-repo", status: "fail", message: probe.detail, fix: "Make the data repository private and check the token's Contents permission." });
|
|
@@ -2871,7 +2938,7 @@ async function runDoctor(site, opts = {}) {
|
|
|
2871
2938
|
if (!settingsDoc(store)) missing.push("settings");
|
|
2872
2939
|
if (!usersOf(store).some((u) => u.role === "admin" && !u.disabled)) missing.push("an active admin user");
|
|
2873
2940
|
if (missing.length && opts.repair) {
|
|
2874
|
-
const { seedCrm } = await import("./chunks/seed-
|
|
2941
|
+
const { seedCrm } = await import("./chunks/seed-Bb26Zsni.mjs");
|
|
2875
2942
|
repaired = await seedCrm(session$1.system, { admin: site.user ? { name: site.user.split("@")[0], email: site.user } : void 0 });
|
|
2876
2943
|
add({ id: "dataset", status: "ok", message: `Repaired: seeded ${missing.join(", ")}.` });
|
|
2877
2944
|
} else {
|
|
@@ -3014,7 +3081,7 @@ const installCommand = {
|
|
|
3014
3081
|
const { resolvePlan } = await import("./chunks/plan-BmTat6-T.mjs");
|
|
3015
3082
|
const plan = resolvePlan(readPlan(planPath));
|
|
3016
3083
|
if (getSite(plan.alias)) throw new CliError("site-exists", `A site named "${plan.alias}" is already registered.`, "Use another alias, or `agentcrm site forget` it first.");
|
|
3017
|
-
const { checkPlan, runInstall } = await import("./chunks/install-
|
|
3084
|
+
const { checkPlan, runInstall } = await import("./chunks/install-D1lgtRIH.mjs");
|
|
3018
3085
|
io.err("Checking access…");
|
|
3019
3086
|
const checks = await checkPlan(plan);
|
|
3020
3087
|
const summary = {
|
|
@@ -3448,13 +3515,13 @@ const objectsCommand = {
|
|
|
3448
3515
|
switch (action) {
|
|
3449
3516
|
case "list":
|
|
3450
3517
|
return withSession(io, options, {}, async ({ ctx, store }) => {
|
|
3451
|
-
const { listObjects } = await import("./chunks/schema-
|
|
3518
|
+
const { listObjects } = await import("./chunks/schema-CYm_n5BN.mjs");
|
|
3452
3519
|
const { recordsOf } = await import("./chunks/store-5gqRSKXg.mjs");
|
|
3453
3520
|
return listObjects(ctx).map((o) => ({ id: o.id, labelSingular: o.labelSingular, labelPlural: o.labelPlural, standard: o.standard, labelField: o.labelField, fields: o.fields.length, records: recordsOf(store, o.id).length }));
|
|
3454
3521
|
}, (rows) => table(rows, ["id", "labelPlural", "fields", "records", "standard"]));
|
|
3455
3522
|
case "get": {
|
|
3456
3523
|
const objectId = positional(positionals, 1, "object id", "objects get <id>");
|
|
3457
|
-
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/schema-
|
|
3524
|
+
return withSession(io, options, {}, async ({ ctx }) => (await import("./chunks/schema-CYm_n5BN.mjs")).describeSchema(ctx, objectId)[0]);
|
|
3458
3525
|
}
|
|
3459
3526
|
case "create": {
|
|
3460
3527
|
const data = jsonObjectOpt(options, "data") ?? {};
|
|
@@ -3467,7 +3534,7 @@ const objectsCommand = {
|
|
|
3467
3534
|
...strOpt(options, "color") ? { color: strOpt(options, "color") } : {}
|
|
3468
3535
|
};
|
|
3469
3536
|
if (!input.labelSingular || !input.labelPlural) usage("objects create needs --singular and --plural (or --data).");
|
|
3470
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-
|
|
3537
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-CYm_n5BN.mjs")).createObject(ctx, input));
|
|
3471
3538
|
}
|
|
3472
3539
|
case "update": {
|
|
3473
3540
|
const objectId = positional(positionals, 1, "object id", "objects update <id> …");
|
|
@@ -3479,12 +3546,12 @@ const objectsCommand = {
|
|
|
3479
3546
|
...strOpt(options, "label-field") ? { labelField: strOpt(options, "label-field") } : {}
|
|
3480
3547
|
};
|
|
3481
3548
|
if (!Object.keys(patch).length) usage("objects update needs --singular, --plural, --icon, --color or --label-field.");
|
|
3482
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-
|
|
3549
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-CYm_n5BN.mjs")).updateObject(ctx, objectId, patch));
|
|
3483
3550
|
}
|
|
3484
3551
|
case "delete": {
|
|
3485
3552
|
if (!id) usage("objects delete needs an object id.");
|
|
3486
3553
|
return withSession(io, options, { lock: options.yes === true }, async ({ ctx, store }) => {
|
|
3487
|
-
const { getObject, deleteObject } = await import("./chunks/schema-
|
|
3554
|
+
const { getObject, deleteObject } = await import("./chunks/schema-CYm_n5BN.mjs");
|
|
3488
3555
|
const { recordsOf } = await import("./chunks/store-5gqRSKXg.mjs");
|
|
3489
3556
|
const o = getObject(ctx, id);
|
|
3490
3557
|
const plan = { object: o.id, label: o.labelPlural, standard: o.standard, recordsDeleted: recordsOf(store, o.id, { includeDeleted: true }).length };
|
|
@@ -3542,7 +3609,7 @@ const fieldsCommand = {
|
|
|
3542
3609
|
...boolOpt(options, "unique") ? { unique: true } : {},
|
|
3543
3610
|
...strOpt(options, "description") ? { description: strOpt(options, "description") } : {}
|
|
3544
3611
|
};
|
|
3545
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-
|
|
3612
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-CYm_n5BN.mjs")).createField(ctx, objectId, input));
|
|
3546
3613
|
}
|
|
3547
3614
|
case "update": {
|
|
3548
3615
|
if (!fieldId) usage("fields update needs a field id.");
|
|
@@ -3559,12 +3626,12 @@ const fieldsCommand = {
|
|
|
3559
3626
|
...strOpt(options, "description") !== void 0 ? { description: strOpt(options, "description") } : {}
|
|
3560
3627
|
};
|
|
3561
3628
|
if (!Object.keys(patch).length) usage("fields update needs at least one change.");
|
|
3562
|
-
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-
|
|
3629
|
+
return withSession(io, options, { lock: true }, async ({ ctx }) => (await import("./chunks/schema-CYm_n5BN.mjs")).updateField(ctx, objectId, fieldId, patch));
|
|
3563
3630
|
}
|
|
3564
3631
|
case "delete": {
|
|
3565
3632
|
if (!fieldId) usage("fields delete needs a field id.");
|
|
3566
3633
|
return withSession(io, options, { lock: options.yes === true }, async ({ ctx, store }) => {
|
|
3567
|
-
const { getObject, deleteField } = await import("./chunks/schema-
|
|
3634
|
+
const { getObject, deleteField } = await import("./chunks/schema-CYm_n5BN.mjs");
|
|
3568
3635
|
const { recordsOf } = await import("./chunks/store-5gqRSKXg.mjs");
|
|
3569
3636
|
const field = getObject(ctx, objectId).fields.find((f) => f.id === fieldId);
|
|
3570
3637
|
if (!field) usage(`No field "${fieldId}" on ${objectId}.`, `\`agentcrm objects get ${objectId}\` lists them.`);
|
|
@@ -3578,6 +3645,50 @@ const fieldsCommand = {
|
|
|
3578
3645
|
}
|
|
3579
3646
|
}
|
|
3580
3647
|
};
|
|
3648
|
+
const schemaCommand = {
|
|
3649
|
+
name: "schema",
|
|
3650
|
+
usage: "schema apply <file|-> [--yes]",
|
|
3651
|
+
summary: "Bring the data model in line with a JSON description ({ objects: [{ id, labelSingular, labelPlural, icon, color, labelField, fields: [{ id, label, type, options, relation… }] }], pipelines: [{ id, name, object, stages }], views: [{ object, name, columns, filters, sorts, groupBy, shared }] }). Creates what is missing and updates what differs; never deletes, never changes a field type (reported as a conflict), never removes a select option or a stage; reports custom fields the description doesn't list. Prints the plan unless --yes.",
|
|
3652
|
+
subcommands: [{ name: "apply", usage: "schema apply <file|-> [--yes]", summary: "Apply a schema description (plan unless --yes).", writes: true }],
|
|
3653
|
+
options: [SITE_OPTION, AS_OPTION, YES_OPTION],
|
|
3654
|
+
async run({ io, options, positionals }) {
|
|
3655
|
+
const [action, source] = positionals;
|
|
3656
|
+
if (action !== "apply") usage(`Unknown schema action "${action ?? ""}".`, "Use schema apply <file|-> [--yes].");
|
|
3657
|
+
if (!source) usage("schema apply needs a file (or - for stdin).", "Example: agentcrm schema apply crm-schema.json");
|
|
3658
|
+
const { readTextValue: readTextValue2 } = await Promise.resolve().then(() => util);
|
|
3659
|
+
const text = readTextValue2(source === "-" ? "-" : `@${source}`, "schema");
|
|
3660
|
+
let raw;
|
|
3661
|
+
try {
|
|
3662
|
+
raw = JSON.parse(text);
|
|
3663
|
+
} catch (err) {
|
|
3664
|
+
usage(`The schema is not valid JSON: ${err.message}`);
|
|
3665
|
+
}
|
|
3666
|
+
const apply = options.yes === true;
|
|
3667
|
+
const { applySchema, parseSchemaSpec } = await import("./chunks/schemaApply-j5hbwPrH.mjs");
|
|
3668
|
+
const spec = parseSchemaSpec(raw);
|
|
3669
|
+
return withSession(
|
|
3670
|
+
io,
|
|
3671
|
+
options,
|
|
3672
|
+
{ lock: apply },
|
|
3673
|
+
async ({ ctx }) => {
|
|
3674
|
+
if (apply) return applySchema(ctx, spec);
|
|
3675
|
+
const { dryRun: dryRun2 } = await Promise.resolve().then(() => dryRun$1);
|
|
3676
|
+
const { result } = await dryRun2(ctx, (copy) => applySchema(copy, spec));
|
|
3677
|
+
return result.changes.length ? { needsConfirmation: true, plan: result } : { ...result, upToDate: true };
|
|
3678
|
+
},
|
|
3679
|
+
(r) => {
|
|
3680
|
+
const report = "needsConfirmation" in r ? r.plan : r;
|
|
3681
|
+
const lines = report.changes.map((c) => ` ${c.action} ${c.kind} ${c.target}${c.changes?.length ? ` (${c.changes.join(", ")})` : ""}`);
|
|
3682
|
+
const extra = [
|
|
3683
|
+
...report.conflicts.map((c) => ` conflict: ${c}`),
|
|
3684
|
+
...report.extraFields.length ? [` not in the schema (kept): ${report.extraFields.join(", ")}`] : []
|
|
3685
|
+
];
|
|
3686
|
+
if ("needsConfirmation" in r) return [`Would change ${report.changes.length} thing(s):`, ...lines, ...extra, "Nothing changed — re-run with --yes once the user agrees."].join("\n");
|
|
3687
|
+
return [report.changes.length ? `Applied ${report.changes.length} change(s):` : "The data model already matches the schema.", ...lines, ...extra].join("\n");
|
|
3688
|
+
}
|
|
3689
|
+
);
|
|
3690
|
+
}
|
|
3691
|
+
};
|
|
3581
3692
|
const MIME = {
|
|
3582
3693
|
".html": "text/html; charset=utf-8",
|
|
3583
3694
|
".js": "text/javascript; charset=utf-8",
|
|
@@ -3871,7 +3982,7 @@ const toolsCommand = {
|
|
|
3871
3982
|
async run({ io, options, positionals }) {
|
|
3872
3983
|
const [action = "list"] = positionals;
|
|
3873
3984
|
if (action === "list") {
|
|
3874
|
-
const { listAiTools, AI_TOOLS } = await import("./chunks/tools-
|
|
3985
|
+
const { listAiTools, AI_TOOLS } = await import("./chunks/tools-BHmVIyP_.mjs");
|
|
3875
3986
|
const builtin = new Set(AI_TOOLS.map((t) => t.name));
|
|
3876
3987
|
const shape = () => listAiTools().map((t) => ({ name: t.name, description: t.description, mutating: t.mutating, source: builtin.has(t.name) ? "builtin" : "extension", inputSchema: t.inputSchema }));
|
|
3877
3988
|
const human = (r) => table(r.tools, ["name", "mutating", "source", "description"]);
|
|
@@ -3891,7 +4002,7 @@ const toolsCommand = {
|
|
|
3891
4002
|
}
|
|
3892
4003
|
if (action === "call") {
|
|
3893
4004
|
const name2 = positional(positionals, 1, "tool name", "tools call <name> --input <json>");
|
|
3894
|
-
const { findTool, callTool, listAiTools } = await import("./chunks/tools-
|
|
4005
|
+
const { findTool, callTool, listAiTools } = await import("./chunks/tools-BHmVIyP_.mjs");
|
|
3895
4006
|
const input = jsonObjectOpt(options, "input") ?? {};
|
|
3896
4007
|
const builtin = findTool(name2);
|
|
3897
4008
|
return withSession(io, options, { lock: builtin ? builtin.mutating : true }, async ({ ctx }) => {
|
|
@@ -3913,8 +4024,8 @@ const mcpCommand = {
|
|
|
3913
4024
|
const log = (msg) => process.stderr.write(`${msg}
|
|
3914
4025
|
`);
|
|
3915
4026
|
for (const w of session2.warnings) log(`[agentcrm mcp] note: ${w}`);
|
|
3916
|
-
const { listAiTools } = await import("./chunks/tools-
|
|
3917
|
-
const { createMcpServer, serveStdio } = await import("./chunks/server-
|
|
4027
|
+
const { listAiTools } = await import("./chunks/tools-BHmVIyP_.mjs");
|
|
4028
|
+
const { createMcpServer, serveStdio } = await import("./chunks/server-BAQwVNtC.mjs");
|
|
3918
4029
|
let lastRefresh = Date.now();
|
|
3919
4030
|
const server = createMcpServer({
|
|
3920
4031
|
readOnly,
|
|
@@ -4016,6 +4127,7 @@ const COMMANDS = [
|
|
|
4016
4127
|
deployAdminCommand,
|
|
4017
4128
|
recordsCommand,
|
|
4018
4129
|
objectsCommand,
|
|
4130
|
+
schemaCommand,
|
|
4019
4131
|
fieldsCommand,
|
|
4020
4132
|
activitiesCommand,
|
|
4021
4133
|
notesCommand,
|