@daeda/mcp-pro 0.1.21 → 0.1.23
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/index.js +614 -181
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -372,6 +372,7 @@ var DATA_ROOT = () => _dataRoot;
|
|
|
372
372
|
var PORTALS_DIR = () => path2.join(_dataRoot, "portals");
|
|
373
373
|
var portalDir = (portalId) => path2.join(PORTALS_DIR(), String(portalId));
|
|
374
374
|
var dbPath = (portalId) => path2.join(portalDir(portalId), "hubspot.duckdb");
|
|
375
|
+
var replicaDbPath = (portalId) => path2.join(portalDir(portalId), "hubspot.replica.duckdb");
|
|
375
376
|
var stateFilePath = () => path2.join(_dataRoot, "client_state.json");
|
|
376
377
|
var portalStatePath = (portalId) => path2.join(portalDir(portalId), "portal_state.json");
|
|
377
378
|
var errorsDirPath = (portalId) => path2.join(portalDir(portalId), "errors");
|
|
@@ -402,7 +403,7 @@ import { Effect as Effect10, pipe as pipe5 } from "effect";
|
|
|
402
403
|
import fs4 from "fs";
|
|
403
404
|
|
|
404
405
|
// src/layers/DatabaseLayerLive.ts
|
|
405
|
-
import { Effect as Effect9, Layer, pipe as pipe4 } from "effect";
|
|
406
|
+
import { Effect as Effect9, FiberRef, Layer, pipe as pipe4 } from "effect";
|
|
406
407
|
import { DuckDBInstance as DuckDBInstance2, DuckDBDataChunk, VARCHAR } from "@duckdb/node-api";
|
|
407
408
|
|
|
408
409
|
// src/services/ConfigService.ts
|
|
@@ -461,6 +462,11 @@ var LOCK_ERROR_PATTERNS = [
|
|
|
461
462
|
"lock on file",
|
|
462
463
|
"already locked"
|
|
463
464
|
];
|
|
465
|
+
var PORTAL_DB_ALIAS = "portal_db";
|
|
466
|
+
var REPLICA_DB_ALIAS = "portal_replica";
|
|
467
|
+
var writeTransactionRef = FiberRef.unsafeMake(false);
|
|
468
|
+
var DEFAULT_REPLICA_PUBLISH_DEBOUNCE_MS = 5 * 60 * 1e3;
|
|
469
|
+
var replicaPublishDebounceMs = DEFAULT_REPLICA_PUBLISH_DEBOUNCE_MS;
|
|
464
470
|
var isLockedDatabaseError = (e) => {
|
|
465
471
|
const msg = String(e);
|
|
466
472
|
return LOCK_ERROR_PATTERNS.some((p) => msg.includes(p));
|
|
@@ -570,10 +576,134 @@ var insertAssociationsViaStaging = (conn, rows) => pipe4(
|
|
|
570
576
|
)
|
|
571
577
|
);
|
|
572
578
|
var portalDbCache = /* @__PURE__ */ new Map();
|
|
579
|
+
var escapeSqlString = (value) => value.replace(/'/g, "''");
|
|
580
|
+
var buildAttachSql = (filePath, alias, encryptionKey, readOnly) => {
|
|
581
|
+
const options2 = [];
|
|
582
|
+
if (encryptionKey) {
|
|
583
|
+
options2.push(`ENCRYPTION_KEY '${escapeSqlString(encryptionKey)}'`);
|
|
584
|
+
}
|
|
585
|
+
if (readOnly) {
|
|
586
|
+
options2.push("READ_ONLY");
|
|
587
|
+
}
|
|
588
|
+
const escapedFile = escapeSqlString(filePath);
|
|
589
|
+
return options2.length > 0 ? `ATTACH '${escapedFile}' AS ${alias} (${options2.join(", ")})` : `ATTACH '${escapedFile}' AS ${alias}`;
|
|
590
|
+
};
|
|
591
|
+
var getReplicaVersion = (portalId) => {
|
|
592
|
+
try {
|
|
593
|
+
return fs3.statSync(replicaDbPath(portalId)).mtimeMs;
|
|
594
|
+
} catch {
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
var cleanupDbArtifacts = (filePath) => {
|
|
599
|
+
try {
|
|
600
|
+
fs3.unlinkSync(filePath);
|
|
601
|
+
} catch {
|
|
602
|
+
}
|
|
603
|
+
try {
|
|
604
|
+
fs3.unlinkSync(filePath + ".wal");
|
|
605
|
+
} catch {
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
var createPendingReplicaPublish = () => {
|
|
609
|
+
let resolve;
|
|
610
|
+
const promise = new Promise((res) => {
|
|
611
|
+
resolve = res;
|
|
612
|
+
});
|
|
613
|
+
return { promise, resolve };
|
|
614
|
+
};
|
|
615
|
+
var publishReplica = async (conn, portalId, encryptionKey) => {
|
|
616
|
+
const replicaPath = replicaDbPath(portalId);
|
|
617
|
+
const nextReplicaPath = `${replicaPath}.next`;
|
|
618
|
+
cleanupDbArtifacts(nextReplicaPath);
|
|
619
|
+
await conn.run(`CHECKPOINT ${PORTAL_DB_ALIAS}`);
|
|
620
|
+
await conn.run(buildAttachSql(nextReplicaPath, REPLICA_DB_ALIAS, encryptionKey, false));
|
|
621
|
+
try {
|
|
622
|
+
await conn.run(`COPY FROM DATABASE ${PORTAL_DB_ALIAS} TO ${REPLICA_DB_ALIAS}`);
|
|
623
|
+
await conn.run(`CHECKPOINT ${REPLICA_DB_ALIAS}`);
|
|
624
|
+
} finally {
|
|
625
|
+
try {
|
|
626
|
+
await conn.run(`DETACH ${REPLICA_DB_ALIAS}`);
|
|
627
|
+
} catch {
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
cleanupDbArtifacts(replicaPath);
|
|
631
|
+
fs3.renameSync(nextReplicaPath, replicaPath);
|
|
632
|
+
const version = getReplicaVersion(portalId);
|
|
633
|
+
if (version === null) {
|
|
634
|
+
throw new Error(`Replica publish failed for portal ${portalId}`);
|
|
635
|
+
}
|
|
636
|
+
return version;
|
|
637
|
+
};
|
|
638
|
+
var closePortalDb = (portalDb) => {
|
|
639
|
+
clearScheduledReplicaPublish(portalDb);
|
|
640
|
+
portalDb.pendingReplicaPublish?.resolve();
|
|
641
|
+
portalDb.pendingReplicaPublish = null;
|
|
642
|
+
const { conn, instance } = portalDb;
|
|
643
|
+
try {
|
|
644
|
+
conn.closeSync();
|
|
645
|
+
} catch {
|
|
646
|
+
}
|
|
647
|
+
try {
|
|
648
|
+
instance.closeSync();
|
|
649
|
+
} catch {
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
var clearScheduledReplicaPublish = (portalDb) => {
|
|
653
|
+
if (portalDb.replicaPublishTimer !== null) {
|
|
654
|
+
clearTimeout(portalDb.replicaPublishTimer);
|
|
655
|
+
portalDb.replicaPublishTimer = null;
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
var scheduleReplicaPublish = (portalDb, portalId, encryptionKey) => {
|
|
659
|
+
if (portalDb.readOnly) return;
|
|
660
|
+
portalDb.replicaDirty = true;
|
|
661
|
+
const pending = portalDb.pendingReplicaPublish ?? createPendingReplicaPublish();
|
|
662
|
+
portalDb.pendingReplicaPublish = pending;
|
|
663
|
+
clearScheduledReplicaPublish(portalDb);
|
|
664
|
+
portalDb.replicaPublishTimer = setTimeout(() => {
|
|
665
|
+
portalDb.replicaPublishTimer = null;
|
|
666
|
+
void Effect9.runPromise(
|
|
667
|
+
pipe4(
|
|
668
|
+
portalDb.txMutex.withPermits(1)(
|
|
669
|
+
Effect9.tryPromise({
|
|
670
|
+
try: async () => {
|
|
671
|
+
try {
|
|
672
|
+
if (!portalDb.replicaDirty) return;
|
|
673
|
+
portalDb.replicaVersion = await publishReplica(portalDb.conn, portalId, encryptionKey);
|
|
674
|
+
portalDb.replicaDirty = false;
|
|
675
|
+
} finally {
|
|
676
|
+
if (portalDb.pendingReplicaPublish === pending) {
|
|
677
|
+
portalDb.pendingReplicaPublish = null;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
},
|
|
681
|
+
catch: (e) => new DatabaseError({ message: `Failed to publish replica for portal ${portalId}`, cause: e })
|
|
682
|
+
})
|
|
683
|
+
),
|
|
684
|
+
Effect9.matchEffect({
|
|
685
|
+
onFailure: (error) => Effect9.sync(() => {
|
|
686
|
+
console.error(`[db] Failed to publish replica for portal ${portalId}:`, error);
|
|
687
|
+
pending.resolve();
|
|
688
|
+
}),
|
|
689
|
+
onSuccess: () => Effect9.sync(() => {
|
|
690
|
+
pending.resolve();
|
|
691
|
+
})
|
|
692
|
+
})
|
|
693
|
+
)
|
|
694
|
+
);
|
|
695
|
+
}, replicaPublishDebounceMs);
|
|
696
|
+
};
|
|
697
|
+
var shouldRefreshPortalDb = (portalId, portalDb) => {
|
|
698
|
+
if (!portalDb.readOnly) return false;
|
|
699
|
+
return getReplicaVersion(portalId) !== portalDb.replicaVersion;
|
|
700
|
+
};
|
|
573
701
|
var initializePortalDb = async (portalId, encryptionKey) => {
|
|
574
702
|
fs3.mkdirSync(portalDir(portalId), { recursive: true });
|
|
703
|
+
const liveDbPath = dbPath(portalId);
|
|
704
|
+
const replicaPath = replicaDbPath(portalId);
|
|
575
705
|
if (encryptionKey) {
|
|
576
|
-
const existingDb =
|
|
706
|
+
const existingDb = liveDbPath;
|
|
577
707
|
const walFile = existingDb + ".wal";
|
|
578
708
|
if (fs3.existsSync(existingDb)) {
|
|
579
709
|
const HEADER_SIZE = 24;
|
|
@@ -600,46 +730,64 @@ var initializePortalDb = async (portalId, encryptionKey) => {
|
|
|
600
730
|
}
|
|
601
731
|
const instance = await DuckDBInstance2.create(":memory:");
|
|
602
732
|
const conn = await instance.connect();
|
|
603
|
-
|
|
604
|
-
|
|
733
|
+
let readOnly = false;
|
|
734
|
+
let sourcePath = liveDbPath;
|
|
735
|
+
let replicaVersion = null;
|
|
605
736
|
try {
|
|
606
|
-
await conn.run(
|
|
737
|
+
await conn.run(buildAttachSql(liveDbPath, PORTAL_DB_ALIAS, encryptionKey, false));
|
|
607
738
|
} catch (e) {
|
|
608
739
|
if (isLockedDatabaseError(e)) {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
fs3.unlinkSync(file);
|
|
624
|
-
} catch {
|
|
625
|
-
}
|
|
626
|
-
try {
|
|
627
|
-
fs3.unlinkSync(file + ".wal");
|
|
628
|
-
} catch {
|
|
740
|
+
console.error(`[db] Portal ${portalId} is locked for writes by another process; opening published replica read-only`);
|
|
741
|
+
replicaVersion = getReplicaVersion(portalId);
|
|
742
|
+
if (replicaVersion === null) {
|
|
743
|
+
throw new Error(`No published replica is available for portal ${portalId}`);
|
|
744
|
+
}
|
|
745
|
+
await conn.run(buildAttachSql(replicaPath, PORTAL_DB_ALIAS, encryptionKey, true));
|
|
746
|
+
readOnly = true;
|
|
747
|
+
sourcePath = replicaPath;
|
|
748
|
+
} else {
|
|
749
|
+
if (!isCorruptedDatabaseError(e)) throw e;
|
|
750
|
+
const file = liveDbPath;
|
|
751
|
+
console.error(`[recovery] Corrupted database detected during ATTACH for portal ${portalId}, deleting and retrying`);
|
|
752
|
+
cleanupDbArtifacts(file);
|
|
753
|
+
await conn.run(buildAttachSql(liveDbPath, PORTAL_DB_ALIAS, encryptionKey, false));
|
|
629
754
|
}
|
|
630
|
-
await conn.run(attachSql);
|
|
631
755
|
}
|
|
632
|
-
await conn.run(
|
|
633
|
-
|
|
756
|
+
await conn.run(`USE ${PORTAL_DB_ALIAS}`);
|
|
757
|
+
if (!readOnly) {
|
|
758
|
+
replicaVersion = await publishReplica(conn, portalId, encryptionKey);
|
|
759
|
+
}
|
|
760
|
+
return {
|
|
761
|
+
instance,
|
|
762
|
+
conn,
|
|
763
|
+
txMutex: Effect9.unsafeMakeSemaphore(1),
|
|
764
|
+
readOnly,
|
|
765
|
+
sourcePath,
|
|
766
|
+
replicaVersion,
|
|
767
|
+
replicaDirty: false,
|
|
768
|
+
replicaPublishTimer: null,
|
|
769
|
+
pendingReplicaPublish: null
|
|
770
|
+
};
|
|
634
771
|
};
|
|
635
|
-
var
|
|
636
|
-
const cached = portalDbCache.get(portalId);
|
|
637
|
-
if (cached) return cached;
|
|
772
|
+
var createPortalDb = (portalId, encryptionKey) => {
|
|
638
773
|
const creating = initializePortalDb(portalId, encryptionKey);
|
|
639
774
|
portalDbCache.set(portalId, creating);
|
|
640
775
|
creating.catch(() => portalDbCache.delete(portalId));
|
|
641
776
|
return creating;
|
|
642
777
|
};
|
|
778
|
+
var getOrCreatePortalDb = async (portalId, encryptionKey) => {
|
|
779
|
+
const cached = portalDbCache.get(portalId);
|
|
780
|
+
if (!cached) {
|
|
781
|
+
return createPortalDb(portalId, encryptionKey);
|
|
782
|
+
}
|
|
783
|
+
const portalDb = await cached;
|
|
784
|
+
if (!shouldRefreshPortalDb(portalId, portalDb)) {
|
|
785
|
+
return portalDb;
|
|
786
|
+
}
|
|
787
|
+
portalDbCache.delete(portalId);
|
|
788
|
+
closePortalDb(portalDb);
|
|
789
|
+
return createPortalDb(portalId, encryptionKey);
|
|
790
|
+
};
|
|
643
791
|
var getPortalInstance = async (portalId, encryptionKey) => {
|
|
644
792
|
const portalDb = await getOrCreatePortalDb(portalId, encryptionKey);
|
|
645
793
|
return portalDb.instance;
|
|
@@ -648,16 +796,7 @@ var evictPortalDb = (portalId) => {
|
|
|
648
796
|
const cached = portalDbCache.get(portalId);
|
|
649
797
|
if (!cached) return;
|
|
650
798
|
portalDbCache.delete(portalId);
|
|
651
|
-
cached.then((
|
|
652
|
-
try {
|
|
653
|
-
conn.closeSync();
|
|
654
|
-
} catch {
|
|
655
|
-
}
|
|
656
|
-
try {
|
|
657
|
-
instance.closeSync();
|
|
658
|
-
} catch {
|
|
659
|
-
}
|
|
660
|
-
}).catch(() => {
|
|
799
|
+
cached.then(closePortalDb).catch(() => {
|
|
661
800
|
});
|
|
662
801
|
};
|
|
663
802
|
var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
@@ -667,10 +806,36 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
667
806
|
try: () => getOrCreatePortalDb(portalId, encryptionKey),
|
|
668
807
|
catch: (e) => new DatabaseError({ message: "Failed to acquire database connection", cause: e })
|
|
669
808
|
}),
|
|
670
|
-
Effect9.map((
|
|
809
|
+
Effect9.map((portalDb) => {
|
|
810
|
+
const { conn, txMutex, readOnly } = portalDb;
|
|
671
811
|
const pluginTableNames = new Set(
|
|
672
812
|
getAllTableNames().map((tableName) => sanitizeTableName(tableName))
|
|
673
813
|
);
|
|
814
|
+
const failReadOnly = () => new DatabaseError({
|
|
815
|
+
message: `Portal ${portalId} is opened in read-only mode because another MCP process holds the write lock`
|
|
816
|
+
});
|
|
817
|
+
const requireWritable = (effect) => readOnly ? Effect9.fail(failReadOnly()) : effect;
|
|
818
|
+
const scheduleReplicaPublishEffect = () => Effect9.sync(() => {
|
|
819
|
+
scheduleReplicaPublish(portalDb, portalId, encryptionKey);
|
|
820
|
+
});
|
|
821
|
+
const serializeWrite = (effect) => pipe4(
|
|
822
|
+
FiberRef.get(writeTransactionRef),
|
|
823
|
+
Effect9.flatMap(
|
|
824
|
+
(inWriteTransaction) => inWriteTransaction ? requireWritable(effect) : requireWritable(
|
|
825
|
+
txMutex.withPermits(1)(
|
|
826
|
+
pipe4(
|
|
827
|
+
effect,
|
|
828
|
+
Effect9.flatMap(
|
|
829
|
+
(result) => pipe4(
|
|
830
|
+
scheduleReplicaPublishEffect(),
|
|
831
|
+
Effect9.as(result)
|
|
832
|
+
)
|
|
833
|
+
)
|
|
834
|
+
)
|
|
835
|
+
)
|
|
836
|
+
)
|
|
837
|
+
)
|
|
838
|
+
);
|
|
674
839
|
const initializeDb = (_portalId) => Effect9.tryPromise({
|
|
675
840
|
try: async () => {
|
|
676
841
|
await conn.run(SYNC_METADATA_TABLE_STATEMENT);
|
|
@@ -762,6 +927,7 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
762
927
|
catch: (e) => new DatabaseError({ message: "Failed to commit transaction", cause: e })
|
|
763
928
|
})
|
|
764
929
|
),
|
|
930
|
+
Effect9.flatMap(() => scheduleReplicaPublishEffect()),
|
|
765
931
|
Effect9.map(() => rows.length),
|
|
766
932
|
Effect9.catchAll(
|
|
767
933
|
(e) => pipe4(
|
|
@@ -840,6 +1006,7 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
840
1006
|
catch: (e) => new DatabaseError({ message: "Failed to commit plugin schema migration", cause: e })
|
|
841
1007
|
})
|
|
842
1008
|
),
|
|
1009
|
+
Effect9.flatMap(() => scheduleReplicaPublishEffect()),
|
|
843
1010
|
Effect9.asVoid,
|
|
844
1011
|
Effect9.catchAll(
|
|
845
1012
|
(e) => pipe4(
|
|
@@ -943,6 +1110,7 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
943
1110
|
await bulkAppend(conn, name, columns);
|
|
944
1111
|
}
|
|
945
1112
|
await conn.run("COMMIT");
|
|
1113
|
+
scheduleReplicaPublish(portalDb, portalId, encryptionKey);
|
|
946
1114
|
} catch (e) {
|
|
947
1115
|
try {
|
|
948
1116
|
await conn.run("ROLLBACK");
|
|
@@ -962,14 +1130,19 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
962
1130
|
try: () => conn.run("BEGIN TRANSACTION"),
|
|
963
1131
|
catch: (e) => new DatabaseError({ message: "Failed to begin transaction", cause: e })
|
|
964
1132
|
}),
|
|
965
|
-
Effect9.flatMap(() => effect),
|
|
1133
|
+
Effect9.flatMap(() => pipe4(effect, Effect9.locally(writeTransactionRef, true))),
|
|
966
1134
|
Effect9.flatMap(
|
|
967
1135
|
(result) => pipe4(
|
|
968
1136
|
Effect9.tryPromise({
|
|
969
1137
|
try: () => conn.run("COMMIT"),
|
|
970
1138
|
catch: (e) => new DatabaseError({ message: "Failed to commit transaction", cause: e })
|
|
971
1139
|
}),
|
|
972
|
-
Effect9.
|
|
1140
|
+
Effect9.flatMap(
|
|
1141
|
+
() => pipe4(
|
|
1142
|
+
scheduleReplicaPublishEffect(),
|
|
1143
|
+
Effect9.as(result)
|
|
1144
|
+
)
|
|
1145
|
+
)
|
|
973
1146
|
)
|
|
974
1147
|
),
|
|
975
1148
|
Effect9.catchAll(
|
|
@@ -1031,6 +1204,7 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
1031
1204
|
);
|
|
1032
1205
|
const countResult = await conn.runAndReadAll(`SELECT COUNT(*) as count FROM "${name}"`);
|
|
1033
1206
|
await conn.run("COMMIT");
|
|
1207
|
+
scheduleReplicaPublish(portalDb, portalId, encryptionKey);
|
|
1034
1208
|
const row = countResult.getRowObjects()[0];
|
|
1035
1209
|
return Number(row.count);
|
|
1036
1210
|
} catch (e) {
|
|
@@ -1073,6 +1247,7 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
1073
1247
|
);
|
|
1074
1248
|
await conn.run(`DROP TABLE IF EXISTS "${staging}"`);
|
|
1075
1249
|
await conn.run("COMMIT");
|
|
1250
|
+
scheduleReplicaPublish(portalDb, portalId, encryptionKey);
|
|
1076
1251
|
const row = countResult.getRowObjects()[0];
|
|
1077
1252
|
return Number(row.count);
|
|
1078
1253
|
} catch (e) {
|
|
@@ -1090,26 +1265,26 @@ var makeDatabaseLive = (portalId, encryptionKey) => Layer.effect(
|
|
|
1090
1265
|
catch: (e) => new DatabaseError({ message: `Failed to atomically replace association CSV`, cause: e })
|
|
1091
1266
|
}));
|
|
1092
1267
|
return {
|
|
1093
|
-
initializeDb,
|
|
1094
|
-
ensureObjectTable,
|
|
1095
|
-
insertObjects,
|
|
1096
|
-
insertAssociations,
|
|
1097
|
-
upsertObjects,
|
|
1098
|
-
upsertAssociations,
|
|
1099
|
-
importObjectsFromCsv,
|
|
1100
|
-
importAssociationsFromCsv,
|
|
1101
|
-
atomicReplaceObjectsFromCsv,
|
|
1102
|
-
atomicReplaceAssociationsFromCsv,
|
|
1268
|
+
initializeDb: (targetPortalId) => serializeWrite(initializeDb(targetPortalId)),
|
|
1269
|
+
ensureObjectTable: (objectType) => serializeWrite(ensureObjectTable(objectType)),
|
|
1270
|
+
insertObjects: (tableName, rows) => serializeWrite(insertObjects(tableName, rows)),
|
|
1271
|
+
insertAssociations: (rows) => serializeWrite(insertAssociations(rows)),
|
|
1272
|
+
upsertObjects: (tableName, rows) => serializeWrite(upsertObjects(tableName, rows)),
|
|
1273
|
+
upsertAssociations: (changedObjectIds, changedObjectType, rows) => requireWritable(upsertAssociations(changedObjectIds, changedObjectType, rows)),
|
|
1274
|
+
importObjectsFromCsv: (tableName, csvPath) => serializeWrite(importObjectsFromCsv(tableName, csvPath)),
|
|
1275
|
+
importAssociationsFromCsv: (csvPath, fromType, toType) => serializeWrite(importAssociationsFromCsv(csvPath, fromType, toType)),
|
|
1276
|
+
atomicReplaceObjectsFromCsv: (tableName, csvPath) => requireWritable(atomicReplaceObjectsFromCsv(tableName, csvPath)),
|
|
1277
|
+
atomicReplaceAssociationsFromCsv: (csvPath, fromType, toType) => requireWritable(atomicReplaceAssociationsFromCsv(csvPath, fromType, toType)),
|
|
1103
1278
|
getObjectSyncTimes,
|
|
1104
|
-
clearObjectTable,
|
|
1105
|
-
clearAssociations,
|
|
1106
|
-
rebuildPluginTables,
|
|
1279
|
+
clearObjectTable: (tableName) => serializeWrite(clearObjectTable(tableName)),
|
|
1280
|
+
clearAssociations: (fromType, toType) => serializeWrite(clearAssociations(fromType, toType)),
|
|
1281
|
+
rebuildPluginTables: (tableNames, ddlStatements) => requireWritable(rebuildPluginTables(tableNames, ddlStatements)),
|
|
1107
1282
|
executeReadQuery,
|
|
1108
1283
|
getRecordCounts,
|
|
1109
1284
|
getMetadata,
|
|
1110
|
-
setMetadata,
|
|
1111
|
-
replacePluginTable,
|
|
1112
|
-
withTransaction
|
|
1285
|
+
setMetadata: (key, value) => serializeWrite(setMetadata(key, value)),
|
|
1286
|
+
replacePluginTable: (tableName, columns) => requireWritable(replacePluginTable(tableName, columns)),
|
|
1287
|
+
withTransaction: (effect) => requireWritable(withTransaction(effect))
|
|
1113
1288
|
};
|
|
1114
1289
|
})
|
|
1115
1290
|
)
|
|
@@ -1126,12 +1301,11 @@ var closeHandle = (portalId) => {
|
|
|
1126
1301
|
}
|
|
1127
1302
|
handles.delete(portalId);
|
|
1128
1303
|
};
|
|
1129
|
-
var openReadHandle = (portalId, encryptionKey) => Effect10.tryPromise({
|
|
1304
|
+
var openReadHandle = (portalId, encryptionKey, instance) => Effect10.tryPromise({
|
|
1130
1305
|
try: async () => {
|
|
1131
|
-
const instance = await getPortalInstance(portalId, encryptionKey);
|
|
1132
1306
|
const conn = await instance.connect();
|
|
1133
1307
|
await conn.run("USE portal_db");
|
|
1134
|
-
handles.set(portalId, { conn });
|
|
1308
|
+
handles.set(portalId, { conn, instance });
|
|
1135
1309
|
return conn;
|
|
1136
1310
|
},
|
|
1137
1311
|
catch: (e) => new DatabaseError({
|
|
@@ -1147,9 +1321,21 @@ var getReadConnection = (portalId, encryptionKey) => pipe5(
|
|
|
1147
1321
|
message: `Database not found for portal ${portalId}. Has it been synced?`
|
|
1148
1322
|
})
|
|
1149
1323
|
),
|
|
1150
|
-
Effect10.flatMap(
|
|
1324
|
+
Effect10.flatMap(
|
|
1325
|
+
() => Effect10.tryPromise({
|
|
1326
|
+
try: () => getPortalInstance(portalId, encryptionKey),
|
|
1327
|
+
catch: (e) => new DatabaseError({
|
|
1328
|
+
message: `Failed to resolve database instance for portal ${portalId}`,
|
|
1329
|
+
cause: e
|
|
1330
|
+
})
|
|
1331
|
+
})
|
|
1332
|
+
),
|
|
1333
|
+
Effect10.flatMap((instance) => {
|
|
1151
1334
|
const existing = handles.get(portalId);
|
|
1152
|
-
|
|
1335
|
+
if (existing && existing.instance !== instance) {
|
|
1336
|
+
closeHandle(portalId);
|
|
1337
|
+
}
|
|
1338
|
+
return existing && existing.instance === instance ? Effect10.succeed(existing.conn) : openReadHandle(portalId, encryptionKey, instance);
|
|
1153
1339
|
})
|
|
1154
1340
|
);
|
|
1155
1341
|
var closeReadConnection = (portalId) => Effect10.sync(() => {
|
|
@@ -4500,7 +4686,7 @@ Use "all" to get everything at once.`,
|
|
|
4500
4686
|
}
|
|
4501
4687
|
|
|
4502
4688
|
// src/tools/build_plan.ts
|
|
4503
|
-
import { z as
|
|
4689
|
+
import { z as z68 } from "zod";
|
|
4504
4690
|
|
|
4505
4691
|
// src/tools/draft_state.ts
|
|
4506
4692
|
var drafts = /* @__PURE__ */ new Map();
|
|
@@ -4539,10 +4725,10 @@ var clearDraft = (portalId) => {
|
|
|
4539
4725
|
};
|
|
4540
4726
|
|
|
4541
4727
|
// src/pure/operation-conversion.ts
|
|
4542
|
-
import { z as
|
|
4728
|
+
import { z as z67 } from "zod";
|
|
4543
4729
|
|
|
4544
4730
|
// ../shared/types/plan.ts
|
|
4545
|
-
import { z as
|
|
4731
|
+
import { z as z66 } from "zod";
|
|
4546
4732
|
|
|
4547
4733
|
// ../shared/operations/create-property/meta.ts
|
|
4548
4734
|
import { z as z17 } from "zod";
|
|
@@ -7070,65 +7256,298 @@ var deleteSnippetMeta = {
|
|
|
7070
7256
|
};
|
|
7071
7257
|
|
|
7072
7258
|
// ../shared/operations/create-workflow/meta.ts
|
|
7073
|
-
import { z as
|
|
7259
|
+
import { z as z62 } from "zod";
|
|
7074
7260
|
|
|
7075
7261
|
// ../shared/pure/workflow-operation-schema.ts
|
|
7262
|
+
import { z as z61 } from "zod";
|
|
7263
|
+
|
|
7264
|
+
// ../shared/types/workflow-actions-types/index.ts
|
|
7076
7265
|
import { z as z60 } from "zod";
|
|
7266
|
+
var NonEmptyStringSchema = z60.string().min(1);
|
|
7077
7267
|
var WorkflowConnectionSchema = z60.object({
|
|
7078
|
-
edgeType:
|
|
7079
|
-
nextActionId:
|
|
7268
|
+
edgeType: NonEmptyStringSchema,
|
|
7269
|
+
nextActionId: NonEmptyStringSchema
|
|
7270
|
+
}).passthrough();
|
|
7271
|
+
var WorkflowStaticBranchSchema = z60.object({
|
|
7272
|
+
branchValue: NonEmptyStringSchema,
|
|
7273
|
+
connection: WorkflowConnectionSchema.optional()
|
|
7274
|
+
}).passthrough();
|
|
7275
|
+
var AssociationSpecSchema = z60.object({
|
|
7276
|
+
associationCategory: NonEmptyStringSchema,
|
|
7277
|
+
associationTypeId: z60.number().int()
|
|
7278
|
+
}).passthrough();
|
|
7279
|
+
var StaticValueSchema = z60.object({
|
|
7280
|
+
type: z60.literal("STATIC_VALUE"),
|
|
7281
|
+
staticValue: z60.string()
|
|
7282
|
+
}).passthrough();
|
|
7283
|
+
var ObjectPropertyValueSchema = z60.object({
|
|
7284
|
+
type: z60.literal("OBJECT_PROPERTY"),
|
|
7285
|
+
propertyName: NonEmptyStringSchema
|
|
7286
|
+
}).passthrough();
|
|
7287
|
+
var ActionValueSchema = z60.union([
|
|
7288
|
+
StaticValueSchema,
|
|
7289
|
+
ObjectPropertyValueSchema
|
|
7290
|
+
]);
|
|
7291
|
+
var AssociationValueSchema = z60.union([
|
|
7292
|
+
z60.object({
|
|
7293
|
+
type: z60.literal("ENROLLED_OBJECT")
|
|
7294
|
+
}).passthrough(),
|
|
7295
|
+
z60.object({
|
|
7296
|
+
type: z60.literal("COPY_ASSOCIATION"),
|
|
7297
|
+
sourceSpec: AssociationSpecSchema
|
|
7298
|
+
}).passthrough()
|
|
7299
|
+
]);
|
|
7300
|
+
var ActionAssociationSchema = z60.object({
|
|
7301
|
+
target: AssociationSpecSchema,
|
|
7302
|
+
value: AssociationValueSchema
|
|
7080
7303
|
}).passthrough();
|
|
7081
|
-
var
|
|
7082
|
-
|
|
7083
|
-
|
|
7304
|
+
var TimeOfDaySchema = z60.object({
|
|
7305
|
+
hour: z60.number().int().min(0).max(23),
|
|
7306
|
+
minute: z60.number().int().min(0).max(59)
|
|
7084
7307
|
}).passthrough();
|
|
7085
|
-
var
|
|
7086
|
-
|
|
7087
|
-
|
|
7308
|
+
var RelativeTimeSchema = z60.object({
|
|
7309
|
+
delta: z60.number().int(),
|
|
7310
|
+
timeUnit: NonEmptyStringSchema,
|
|
7311
|
+
timeOfDay: TimeOfDaySchema,
|
|
7312
|
+
daysOfWeek: z60.array(NonEmptyStringSchema)
|
|
7313
|
+
}).passthrough();
|
|
7314
|
+
var ActionFieldDataInputSchema = z60.object({
|
|
7315
|
+
actionId: NonEmptyStringSchema,
|
|
7316
|
+
dataKey: NonEmptyStringSchema,
|
|
7317
|
+
type: z60.literal("FIELD_DATA")
|
|
7318
|
+
}).passthrough();
|
|
7319
|
+
var SingleConnectionActionBaseSchema = z60.object({
|
|
7320
|
+
actionId: NonEmptyStringSchema,
|
|
7321
|
+
actionTypeVersion: z60.number().int().optional(),
|
|
7322
|
+
connection: WorkflowConnectionSchema.optional(),
|
|
7323
|
+
type: z60.literal("SINGLE_CONNECTION")
|
|
7324
|
+
}).passthrough();
|
|
7325
|
+
var buildSingleConnectionActionSchema = (actionTypeId, fields48) => SingleConnectionActionBaseSchema.extend({
|
|
7326
|
+
actionTypeId: z60.literal(actionTypeId),
|
|
7327
|
+
fields: fields48
|
|
7328
|
+
});
|
|
7329
|
+
var BooleanStringSchema = z60.enum(["true", "false"]);
|
|
7330
|
+
var DelayForSetAmountOfTimeActionSchema = buildSingleConnectionActionSchema("0-1", z60.object({
|
|
7331
|
+
delta: NonEmptyStringSchema,
|
|
7332
|
+
time_unit: NonEmptyStringSchema
|
|
7333
|
+
}).passthrough());
|
|
7334
|
+
var RotateRecordToOwnerActionSchema = buildSingleConnectionActionSchema("0-11", z60.object({
|
|
7335
|
+
user_ids: z60.array(NonEmptyStringSchema).min(1),
|
|
7336
|
+
target_property: NonEmptyStringSchema,
|
|
7337
|
+
overwrite_current_owner: BooleanStringSchema
|
|
7338
|
+
}).passthrough());
|
|
7339
|
+
var CreateRecordPropertySchema = z60.object({
|
|
7340
|
+
targetProperty: NonEmptyStringSchema,
|
|
7341
|
+
value: ActionValueSchema
|
|
7342
|
+
}).passthrough();
|
|
7343
|
+
var CreateRecordActionSchema = buildSingleConnectionActionSchema("0-14", z60.object({
|
|
7344
|
+
object_type_id: NonEmptyStringSchema,
|
|
7345
|
+
properties: z60.array(CreateRecordPropertySchema).optional(),
|
|
7346
|
+
associations: z60.array(ActionAssociationSchema).optional(),
|
|
7347
|
+
use_explicit_associations: BooleanStringSchema.optional()
|
|
7348
|
+
}).passthrough());
|
|
7349
|
+
var GoToWorkflowActionSchema = buildSingleConnectionActionSchema("0-15", z60.object({
|
|
7350
|
+
flow_id: NonEmptyStringSchema
|
|
7351
|
+
}).passthrough());
|
|
7352
|
+
var CreateNoteActionSchema = buildSingleConnectionActionSchema("0-169425243", z60.object({
|
|
7353
|
+
note_body: z60.string(),
|
|
7354
|
+
pin_note: BooleanStringSchema
|
|
7355
|
+
}).passthrough());
|
|
7356
|
+
var SummarizeRecordActionSchema = buildSingleConnectionActionSchema("0-195318603", z60.object({}).passthrough());
|
|
7357
|
+
var TrackIntentSignalsActionSchema = buildSingleConnectionActionSchema("0-219160146", z60.object({
|
|
7358
|
+
targetCompany: NonEmptyStringSchema
|
|
7359
|
+
}).passthrough());
|
|
7360
|
+
var StopTrackingIntentSignalsActionSchema = buildSingleConnectionActionSchema("0-219161394", z60.object({
|
|
7361
|
+
targetCompany: NonEmptyStringSchema
|
|
7362
|
+
}).passthrough());
|
|
7363
|
+
var ValidateAndFormatPhoneNumberActionSchema = buildSingleConnectionActionSchema("0-225935194", z60.object({
|
|
7364
|
+
defaultCountryCodeMode: NonEmptyStringSchema
|
|
7365
|
+
}).passthrough());
|
|
7366
|
+
var DelayUntilEventOccursActionSchema = buildSingleConnectionActionSchema("0-29", z60.object({
|
|
7367
|
+
expiration_minutes: NonEmptyStringSchema
|
|
7368
|
+
}).passthrough());
|
|
7369
|
+
var TaskOwnerAssignmentSchema = z60.object({
|
|
7370
|
+
type: NonEmptyStringSchema,
|
|
7371
|
+
value: StaticValueSchema
|
|
7372
|
+
}).passthrough();
|
|
7373
|
+
var CreateTaskActionSchema = buildSingleConnectionActionSchema("0-3", z60.object({
|
|
7374
|
+
task_type: NonEmptyStringSchema,
|
|
7375
|
+
subject: NonEmptyStringSchema,
|
|
7376
|
+
body: z60.string(),
|
|
7377
|
+
associations: z60.array(ActionAssociationSchema).optional(),
|
|
7378
|
+
use_explicit_associations: BooleanStringSchema.optional(),
|
|
7379
|
+
priority: NonEmptyStringSchema.optional(),
|
|
7380
|
+
due_time: RelativeTimeSchema.optional(),
|
|
7381
|
+
reminder_time: RelativeTimeSchema.optional(),
|
|
7382
|
+
owner_assignment: TaskOwnerAssignmentSchema.optional()
|
|
7383
|
+
}).passthrough());
|
|
7384
|
+
var SetMarketingContactStatusActionSchema = buildSingleConnectionActionSchema("0-31", z60.object({
|
|
7385
|
+
targetContact: NonEmptyStringSchema,
|
|
7386
|
+
marketableType: NonEmptyStringSchema
|
|
7387
|
+
}).passthrough());
|
|
7388
|
+
var DelayUntilDateActionSchema = buildSingleConnectionActionSchema("0-35", z60.object({
|
|
7389
|
+
date: ActionValueSchema,
|
|
7390
|
+
delta: NonEmptyStringSchema,
|
|
7391
|
+
time_unit: NonEmptyStringSchema,
|
|
7392
|
+
time_of_day: TimeOfDaySchema
|
|
7393
|
+
}).passthrough());
|
|
7394
|
+
var EditRecordsSetPropertyActionSchema = buildSingleConnectionActionSchema("0-5", z60.object({
|
|
7395
|
+
property_name: NonEmptyStringSchema,
|
|
7396
|
+
association: AssociationSpecSchema.optional(),
|
|
7397
|
+
value: ActionValueSchema
|
|
7398
|
+
}).passthrough());
|
|
7399
|
+
var RemoveAssociationLabelsActionSchema = buildSingleConnectionActionSchema("0-61139476", z60.object({
|
|
7400
|
+
fromObjectType: NonEmptyStringSchema,
|
|
7401
|
+
toObjectType: NonEmptyStringSchema,
|
|
7402
|
+
labelToRemove: NonEmptyStringSchema,
|
|
7403
|
+
fullyDissociate: BooleanStringSchema
|
|
7404
|
+
}).passthrough());
|
|
7405
|
+
var CreateAssociationsActionSchema = buildSingleConnectionActionSchema("0-63189541", z60.object({
|
|
7406
|
+
fromObjectType: NonEmptyStringSchema,
|
|
7407
|
+
toObjectType: NonEmptyStringSchema,
|
|
7408
|
+
createAssociationOnly: BooleanStringSchema,
|
|
7409
|
+
labelToApply: NonEmptyStringSchema,
|
|
7410
|
+
matchBy: NonEmptyStringSchema,
|
|
7411
|
+
enrolledObjectPropertyNameToMatch: NonEmptyStringSchema,
|
|
7412
|
+
associatedObjectPropertyNameToMatch: NonEmptyStringSchema
|
|
7413
|
+
}).passthrough());
|
|
7414
|
+
var AddToStaticListActionSchema = buildSingleConnectionActionSchema("0-63809083", z60.object({
|
|
7415
|
+
listId: NonEmptyStringSchema
|
|
7416
|
+
}).passthrough());
|
|
7417
|
+
var RemoveFromStaticListActionSchema = buildSingleConnectionActionSchema("0-63863438", z60.object({
|
|
7418
|
+
listId: NonEmptyStringSchema
|
|
7419
|
+
}).passthrough());
|
|
7420
|
+
var ApplyAssociationLabelsActionSchema = buildSingleConnectionActionSchema("0-73444249", z60.object({
|
|
7421
|
+
fromObjectType: NonEmptyStringSchema,
|
|
7422
|
+
toObjectType: NonEmptyStringSchema,
|
|
7423
|
+
labelToApply: NonEmptyStringSchema,
|
|
7424
|
+
applyLabelToAllAssociatedObjects: BooleanStringSchema
|
|
7425
|
+
}).passthrough());
|
|
7426
|
+
var SendInternalEmailNotificationActionSchema = buildSingleConnectionActionSchema("0-8", z60.object({
|
|
7427
|
+
user_ids: z60.array(NonEmptyStringSchema).min(1),
|
|
7428
|
+
subject: NonEmptyStringSchema,
|
|
7429
|
+
body: NonEmptyStringSchema,
|
|
7430
|
+
owner_properties: z60.array(NonEmptyStringSchema).optional()
|
|
7431
|
+
}).passthrough());
|
|
7432
|
+
var SendInAppNotificationActionSchema = buildSingleConnectionActionSchema("0-9", z60.object({
|
|
7433
|
+
user_ids: z60.array(NonEmptyStringSchema).min(1),
|
|
7434
|
+
delivery_method: z60.enum(["APP", "MOBILE"]),
|
|
7435
|
+
subject: NonEmptyStringSchema,
|
|
7436
|
+
body: NonEmptyStringSchema,
|
|
7437
|
+
owner_properties: z60.array(NonEmptyStringSchema).optional()
|
|
7438
|
+
}).passthrough());
|
|
7439
|
+
var StaticBranchWorkflowActionSchema = z60.object({
|
|
7440
|
+
actionId: NonEmptyStringSchema,
|
|
7441
|
+
inputValue: ActionFieldDataInputSchema,
|
|
7442
|
+
staticBranches: z60.array(WorkflowStaticBranchSchema).min(1),
|
|
7443
|
+
defaultBranchName: NonEmptyStringSchema,
|
|
7444
|
+
type: z60.literal("STATIC_BRANCH")
|
|
7445
|
+
}).passthrough();
|
|
7446
|
+
var WorkflowActionSchemasByDefinitionKey = {
|
|
7447
|
+
"0-1": DelayForSetAmountOfTimeActionSchema,
|
|
7448
|
+
"0-11": RotateRecordToOwnerActionSchema,
|
|
7449
|
+
"0-14": CreateRecordActionSchema,
|
|
7450
|
+
"0-15": GoToWorkflowActionSchema,
|
|
7451
|
+
"0-169425243": CreateNoteActionSchema,
|
|
7452
|
+
"0-195318603": SummarizeRecordActionSchema,
|
|
7453
|
+
"0-219160146": TrackIntentSignalsActionSchema,
|
|
7454
|
+
"0-219161394": StopTrackingIntentSignalsActionSchema,
|
|
7455
|
+
"0-225935194": ValidateAndFormatPhoneNumberActionSchema,
|
|
7456
|
+
"0-29": DelayUntilEventOccursActionSchema,
|
|
7457
|
+
"0-3": CreateTaskActionSchema,
|
|
7458
|
+
"0-31": SetMarketingContactStatusActionSchema,
|
|
7459
|
+
"0-35": DelayUntilDateActionSchema,
|
|
7460
|
+
"0-5": EditRecordsSetPropertyActionSchema,
|
|
7461
|
+
"0-61139476": RemoveAssociationLabelsActionSchema,
|
|
7462
|
+
"0-63189541": CreateAssociationsActionSchema,
|
|
7463
|
+
"0-63809083": AddToStaticListActionSchema,
|
|
7464
|
+
"0-63863438": RemoveFromStaticListActionSchema,
|
|
7465
|
+
"0-73444249": ApplyAssociationLabelsActionSchema,
|
|
7466
|
+
"0-8": SendInternalEmailNotificationActionSchema,
|
|
7467
|
+
"0-9": SendInAppNotificationActionSchema,
|
|
7468
|
+
STATIC_BRANCH: StaticBranchWorkflowActionSchema
|
|
7469
|
+
};
|
|
7470
|
+
var WorkflowDefinitionActionSchema = z60.union([
|
|
7471
|
+
DelayForSetAmountOfTimeActionSchema,
|
|
7472
|
+
RotateRecordToOwnerActionSchema,
|
|
7473
|
+
CreateRecordActionSchema,
|
|
7474
|
+
GoToWorkflowActionSchema,
|
|
7475
|
+
CreateNoteActionSchema,
|
|
7476
|
+
SummarizeRecordActionSchema,
|
|
7477
|
+
TrackIntentSignalsActionSchema,
|
|
7478
|
+
StopTrackingIntentSignalsActionSchema,
|
|
7479
|
+
ValidateAndFormatPhoneNumberActionSchema,
|
|
7480
|
+
DelayUntilEventOccursActionSchema,
|
|
7481
|
+
CreateTaskActionSchema,
|
|
7482
|
+
SetMarketingContactStatusActionSchema,
|
|
7483
|
+
DelayUntilDateActionSchema,
|
|
7484
|
+
EditRecordsSetPropertyActionSchema,
|
|
7485
|
+
RemoveAssociationLabelsActionSchema,
|
|
7486
|
+
CreateAssociationsActionSchema,
|
|
7487
|
+
AddToStaticListActionSchema,
|
|
7488
|
+
RemoveFromStaticListActionSchema,
|
|
7489
|
+
ApplyAssociationLabelsActionSchema,
|
|
7490
|
+
SendInternalEmailNotificationActionSchema,
|
|
7491
|
+
SendInAppNotificationActionSchema,
|
|
7492
|
+
StaticBranchWorkflowActionSchema
|
|
7493
|
+
]);
|
|
7494
|
+
|
|
7495
|
+
// ../shared/pure/workflow-operation-schema.ts
|
|
7496
|
+
var WorkflowConnectionSchema2 = z61.object({
|
|
7497
|
+
edgeType: z61.string().min(1),
|
|
7498
|
+
nextActionId: z61.string().min(1)
|
|
7499
|
+
}).passthrough();
|
|
7500
|
+
var WorkflowFilterOperationSchema = z61.object({
|
|
7501
|
+
operationType: z61.string().min(1, "operation.operationType is required for workflow property filters"),
|
|
7502
|
+
operator: z61.string().min(1)
|
|
7503
|
+
}).passthrough();
|
|
7504
|
+
var WorkflowFilterSchema = z61.object({
|
|
7505
|
+
filterType: z61.string().min(1),
|
|
7506
|
+
property: z61.string().optional(),
|
|
7088
7507
|
operation: WorkflowFilterOperationSchema.optional()
|
|
7089
7508
|
}).passthrough().superRefine((value, ctx) => {
|
|
7090
7509
|
if (value.filterType !== "PROPERTY") return;
|
|
7091
7510
|
if (!value.property || value.property.length === 0) {
|
|
7092
7511
|
ctx.addIssue({
|
|
7093
|
-
code:
|
|
7512
|
+
code: z61.ZodIssueCode.custom,
|
|
7094
7513
|
message: "property filters require property",
|
|
7095
7514
|
path: ["property"]
|
|
7096
7515
|
});
|
|
7097
7516
|
}
|
|
7098
7517
|
if (!value.operation) {
|
|
7099
7518
|
ctx.addIssue({
|
|
7100
|
-
code:
|
|
7519
|
+
code: z61.ZodIssueCode.custom,
|
|
7101
7520
|
message: "property filters require operation",
|
|
7102
7521
|
path: ["operation"]
|
|
7103
7522
|
});
|
|
7104
7523
|
}
|
|
7105
7524
|
});
|
|
7106
|
-
var WorkflowBranchSchema =
|
|
7107
|
-
connection:
|
|
7108
|
-
nextActionId:
|
|
7525
|
+
var WorkflowBranchSchema = z61.object({
|
|
7526
|
+
connection: WorkflowConnectionSchema2.optional(),
|
|
7527
|
+
nextActionId: z61.string().min(1).optional()
|
|
7109
7528
|
}).passthrough().superRefine((value, ctx) => {
|
|
7110
7529
|
if (value.connection || value.nextActionId) return;
|
|
7111
7530
|
ctx.addIssue({
|
|
7112
|
-
code:
|
|
7531
|
+
code: z61.ZodIssueCode.custom,
|
|
7113
7532
|
message: "workflow branches require connection.nextActionId or nextActionId",
|
|
7114
7533
|
path: ["connection"]
|
|
7115
7534
|
});
|
|
7116
7535
|
});
|
|
7117
|
-
var WorkflowEnrollmentBranchSchema =
|
|
7118
|
-
filterBranchType:
|
|
7119
|
-
filterBranchOperator:
|
|
7120
|
-
filterBranches:
|
|
7121
|
-
filters:
|
|
7122
|
-
eventTypeId:
|
|
7123
|
-
operator:
|
|
7124
|
-
objectTypeId:
|
|
7125
|
-
associationTypeId:
|
|
7126
|
-
associationCategory:
|
|
7536
|
+
var WorkflowEnrollmentBranchSchema = z61.object({
|
|
7537
|
+
filterBranchType: z61.string().min(1),
|
|
7538
|
+
filterBranchOperator: z61.string().optional(),
|
|
7539
|
+
filterBranches: z61.array(z61.lazy(() => WorkflowEnrollmentBranchSchema)).default([]),
|
|
7540
|
+
filters: z61.array(WorkflowFilterSchema).default([]),
|
|
7541
|
+
eventTypeId: z61.string().optional(),
|
|
7542
|
+
operator: z61.string().optional(),
|
|
7543
|
+
objectTypeId: z61.string().optional(),
|
|
7544
|
+
associationTypeId: z61.number().optional(),
|
|
7545
|
+
associationCategory: z61.string().optional()
|
|
7127
7546
|
}).passthrough().superRefine((value, ctx) => {
|
|
7128
7547
|
if (value.filterBranchType !== "UNIFIED_EVENTS") return;
|
|
7129
7548
|
if (!value.eventTypeId || value.eventTypeId.length === 0) {
|
|
7130
7549
|
ctx.addIssue({
|
|
7131
|
-
code:
|
|
7550
|
+
code: z61.ZodIssueCode.custom,
|
|
7132
7551
|
message: "UNIFIED_EVENTS filter branches require eventTypeId (e.g. '4-655002' for property change). Query workflow_event_types for valid IDs.",
|
|
7133
7552
|
path: ["eventTypeId"]
|
|
7134
7553
|
});
|
|
@@ -7136,39 +7555,39 @@ var WorkflowEnrollmentBranchSchema = z60.object({
|
|
|
7136
7555
|
}
|
|
7137
7556
|
if (/^0-\d+$/.test(value.eventTypeId)) {
|
|
7138
7557
|
ctx.addIssue({
|
|
7139
|
-
code:
|
|
7558
|
+
code: z61.ZodIssueCode.custom,
|
|
7140
7559
|
message: `eventTypeId '${value.eventTypeId}' looks like a CRM object type ID, not an event type ID. Event type IDs use '4-*' or '6-*' prefix (e.g. '4-655002' for property change). Query workflow_event_types for valid IDs.`,
|
|
7141
7560
|
path: ["eventTypeId"]
|
|
7142
7561
|
});
|
|
7143
7562
|
}
|
|
7144
7563
|
});
|
|
7145
|
-
var EventBasedEnrollmentCriteriaSchema =
|
|
7146
|
-
type:
|
|
7147
|
-
shouldReEnroll:
|
|
7148
|
-
eventFilterBranches:
|
|
7149
|
-
listMembershipFilterBranches:
|
|
7564
|
+
var EventBasedEnrollmentCriteriaSchema = z61.object({
|
|
7565
|
+
type: z61.literal("EVENT_BASED"),
|
|
7566
|
+
shouldReEnroll: z61.boolean(),
|
|
7567
|
+
eventFilterBranches: z61.array(WorkflowEnrollmentBranchSchema).min(1),
|
|
7568
|
+
listMembershipFilterBranches: z61.array(WorkflowEnrollmentBranchSchema).default([])
|
|
7150
7569
|
}).passthrough();
|
|
7151
|
-
var ListBasedEnrollmentCriteriaSchema =
|
|
7152
|
-
type:
|
|
7153
|
-
shouldReEnroll:
|
|
7570
|
+
var ListBasedEnrollmentCriteriaSchema = z61.object({
|
|
7571
|
+
type: z61.literal("LIST_BASED"),
|
|
7572
|
+
shouldReEnroll: z61.boolean(),
|
|
7154
7573
|
listFilterBranch: WorkflowEnrollmentBranchSchema,
|
|
7155
|
-
reEnrollmentTriggersFilterBranches:
|
|
7574
|
+
reEnrollmentTriggersFilterBranches: z61.array(WorkflowEnrollmentBranchSchema).default([])
|
|
7156
7575
|
}).passthrough();
|
|
7157
|
-
var WorkflowEnrollmentCriteriaSchema =
|
|
7576
|
+
var WorkflowEnrollmentCriteriaSchema = z61.union([
|
|
7158
7577
|
EventBasedEnrollmentCriteriaSchema,
|
|
7159
7578
|
ListBasedEnrollmentCriteriaSchema
|
|
7160
7579
|
]);
|
|
7161
|
-
var
|
|
7162
|
-
actionId:
|
|
7163
|
-
type:
|
|
7164
|
-
actionTypeId:
|
|
7165
|
-
actionTypeVersion:
|
|
7166
|
-
connection:
|
|
7167
|
-
fields:
|
|
7168
|
-
staticBranches:
|
|
7169
|
-
listBranches:
|
|
7580
|
+
var BaseWorkflowActionSchema = z61.object({
|
|
7581
|
+
actionId: z61.string().min(1),
|
|
7582
|
+
type: z61.string().min(1),
|
|
7583
|
+
actionTypeId: z61.string().optional(),
|
|
7584
|
+
actionTypeVersion: z61.number().int().optional(),
|
|
7585
|
+
connection: WorkflowConnectionSchema2.optional(),
|
|
7586
|
+
fields: z61.record(z61.string(), z61.unknown()).optional(),
|
|
7587
|
+
staticBranches: z61.array(WorkflowBranchSchema).optional(),
|
|
7588
|
+
listBranches: z61.array(WorkflowBranchSchema).optional(),
|
|
7170
7589
|
defaultBranch: WorkflowBranchSchema.optional(),
|
|
7171
|
-
defaultBranchName:
|
|
7590
|
+
defaultBranchName: z61.string().optional()
|
|
7172
7591
|
}).passthrough().superRefine((value, ctx) => {
|
|
7173
7592
|
if (value.type !== "BRANCH") return;
|
|
7174
7593
|
const hasStaticBranches = (value.staticBranches?.length ?? 0) > 0;
|
|
@@ -7176,25 +7595,40 @@ var WorkflowActionSchema = z60.object({
|
|
|
7176
7595
|
const hasDefaultBranch = value.defaultBranch != null;
|
|
7177
7596
|
if (hasStaticBranches || hasListBranches || hasDefaultBranch) return;
|
|
7178
7597
|
ctx.addIssue({
|
|
7179
|
-
code:
|
|
7598
|
+
code: z61.ZodIssueCode.custom,
|
|
7180
7599
|
message: "BRANCH actions require at least one branch target",
|
|
7181
7600
|
path: ["type"]
|
|
7182
7601
|
});
|
|
7183
7602
|
});
|
|
7603
|
+
var TypedWorkflowActionSchema = BaseWorkflowActionSchema.superRefine((value, ctx) => {
|
|
7604
|
+
const definitionKey = value.actionTypeId ?? value.type;
|
|
7605
|
+
if (definitionKey === "STATIC_BRANCH") return;
|
|
7606
|
+
const typedSchema = WorkflowActionSchemasByDefinitionKey[definitionKey];
|
|
7607
|
+
if (!typedSchema) return;
|
|
7608
|
+
const result = typedSchema.safeParse(value);
|
|
7609
|
+
if (result.success) return;
|
|
7610
|
+
for (const issue of result.error.issues) {
|
|
7611
|
+
ctx.addIssue(issue);
|
|
7612
|
+
}
|
|
7613
|
+
});
|
|
7614
|
+
var WorkflowActionSchema = z61.union([
|
|
7615
|
+
TypedWorkflowActionSchema,
|
|
7616
|
+
StaticBranchWorkflowActionSchema
|
|
7617
|
+
]);
|
|
7184
7618
|
|
|
7185
7619
|
// ../shared/operations/create-workflow/meta.ts
|
|
7186
|
-
var CreateWorkflowOperationSchema =
|
|
7187
|
-
type:
|
|
7188
|
-
description:
|
|
7189
|
-
name:
|
|
7190
|
-
workflow_type:
|
|
7191
|
-
object_type_id:
|
|
7192
|
-
is_enabled:
|
|
7193
|
-
actions:
|
|
7620
|
+
var CreateWorkflowOperationSchema = z62.object({
|
|
7621
|
+
type: z62.literal("create_workflow"),
|
|
7622
|
+
description: z62.string().min(1),
|
|
7623
|
+
name: z62.string().min(1),
|
|
7624
|
+
workflow_type: z62.enum(["CONTACT_FLOW", "PLATFORM_FLOW"]),
|
|
7625
|
+
object_type_id: z62.string().min(1),
|
|
7626
|
+
is_enabled: z62.boolean().optional().default(false),
|
|
7627
|
+
actions: z62.array(WorkflowActionSchema).min(1),
|
|
7194
7628
|
enrollment_criteria: WorkflowEnrollmentCriteriaSchema.optional(),
|
|
7195
|
-
suppression_list_ids:
|
|
7196
|
-
time_windows:
|
|
7197
|
-
blocked_dates:
|
|
7629
|
+
suppression_list_ids: z62.array(z62.number()).optional(),
|
|
7630
|
+
time_windows: z62.array(z62.record(z62.string(), z62.unknown())).optional(),
|
|
7631
|
+
blocked_dates: z62.array(z62.record(z62.string(), z62.unknown())).optional()
|
|
7198
7632
|
});
|
|
7199
7633
|
var fields44 = [
|
|
7200
7634
|
{ name: "name", type: "string", required: true, description: "Workflow name" },
|
|
@@ -7312,17 +7746,17 @@ var createWorkflowMeta = {
|
|
|
7312
7746
|
};
|
|
7313
7747
|
|
|
7314
7748
|
// ../shared/operations/update-workflow/meta.ts
|
|
7315
|
-
import { z as
|
|
7316
|
-
var UpdateWorkflowOperationSchema =
|
|
7317
|
-
type:
|
|
7318
|
-
description:
|
|
7319
|
-
workflow_id:
|
|
7320
|
-
name:
|
|
7321
|
-
actions:
|
|
7749
|
+
import { z as z63 } from "zod";
|
|
7750
|
+
var UpdateWorkflowOperationSchema = z63.object({
|
|
7751
|
+
type: z63.literal("update_workflow"),
|
|
7752
|
+
description: z63.string().min(1),
|
|
7753
|
+
workflow_id: z63.string().min(1),
|
|
7754
|
+
name: z63.string().optional(),
|
|
7755
|
+
actions: z63.array(WorkflowActionSchema).optional(),
|
|
7322
7756
|
enrollment_criteria: WorkflowEnrollmentCriteriaSchema.optional(),
|
|
7323
|
-
suppression_list_ids:
|
|
7324
|
-
time_windows:
|
|
7325
|
-
blocked_dates:
|
|
7757
|
+
suppression_list_ids: z63.array(z63.number()).optional(),
|
|
7758
|
+
time_windows: z63.array(z63.record(z63.string(), z63.unknown())).optional(),
|
|
7759
|
+
blocked_dates: z63.array(z63.record(z63.string(), z63.unknown())).optional()
|
|
7326
7760
|
});
|
|
7327
7761
|
var fields45 = [
|
|
7328
7762
|
{ name: "workflow_id", type: "string", required: true, description: "ID of the workflow to update (query workflows table)" },
|
|
@@ -7366,12 +7800,12 @@ var updateWorkflowMeta = {
|
|
|
7366
7800
|
};
|
|
7367
7801
|
|
|
7368
7802
|
// ../shared/operations/set-workflow-enabled/meta.ts
|
|
7369
|
-
import { z as
|
|
7370
|
-
var SetWorkflowEnabledOperationSchema =
|
|
7371
|
-
type:
|
|
7372
|
-
description:
|
|
7373
|
-
workflow_id:
|
|
7374
|
-
enabled:
|
|
7803
|
+
import { z as z64 } from "zod";
|
|
7804
|
+
var SetWorkflowEnabledOperationSchema = z64.object({
|
|
7805
|
+
type: z64.literal("set_workflow_enabled"),
|
|
7806
|
+
description: z64.string().min(1),
|
|
7807
|
+
workflow_id: z64.string().min(1),
|
|
7808
|
+
enabled: z64.boolean()
|
|
7375
7809
|
});
|
|
7376
7810
|
var fields46 = [
|
|
7377
7811
|
{ name: "workflow_id", type: "string", required: true, description: "ID of the workflow to enable or disable" },
|
|
@@ -7408,11 +7842,11 @@ var setWorkflowEnabledMeta = {
|
|
|
7408
7842
|
};
|
|
7409
7843
|
|
|
7410
7844
|
// ../shared/operations/delete-workflow/meta.ts
|
|
7411
|
-
import { z as
|
|
7412
|
-
var DeleteWorkflowOperationSchema =
|
|
7413
|
-
type:
|
|
7414
|
-
description:
|
|
7415
|
-
workflow_id:
|
|
7845
|
+
import { z as z65 } from "zod";
|
|
7846
|
+
var DeleteWorkflowOperationSchema = z65.object({
|
|
7847
|
+
type: z65.literal("delete_workflow"),
|
|
7848
|
+
description: z65.string().min(1),
|
|
7849
|
+
workflow_id: z65.string().min(1)
|
|
7416
7850
|
});
|
|
7417
7851
|
var fields47 = [
|
|
7418
7852
|
{ name: "workflow_id", type: "string", required: true, description: "ID of the workflow to delete (irreversible \u2014 cannot be restored via API)" }
|
|
@@ -7446,7 +7880,7 @@ var deleteWorkflowMeta = {
|
|
|
7446
7880
|
};
|
|
7447
7881
|
|
|
7448
7882
|
// ../shared/types/plan.ts
|
|
7449
|
-
var OperationSchema =
|
|
7883
|
+
var OperationSchema = z66.discriminatedUnion("type", [
|
|
7450
7884
|
CreatePropertyOperationSchema,
|
|
7451
7885
|
CreatePipelineOperationSchema,
|
|
7452
7886
|
CreateAssociationLabelOperationSchema,
|
|
@@ -7495,10 +7929,10 @@ var OperationSchema = z65.discriminatedUnion("type", [
|
|
|
7495
7929
|
SetWorkflowEnabledOperationSchema,
|
|
7496
7930
|
DeleteWorkflowOperationSchema
|
|
7497
7931
|
]);
|
|
7498
|
-
var WritePlanInputSchema =
|
|
7499
|
-
title:
|
|
7500
|
-
description:
|
|
7501
|
-
operations:
|
|
7932
|
+
var WritePlanInputSchema = z66.object({
|
|
7933
|
+
title: z66.string().min(1),
|
|
7934
|
+
description: z66.string().min(1),
|
|
7935
|
+
operations: z66.array(OperationSchema).min(1)
|
|
7502
7936
|
});
|
|
7503
7937
|
|
|
7504
7938
|
// ../shared/operations/create-property/index.ts
|
|
@@ -11878,7 +12312,7 @@ var BUILT_IN_ACTION_TYPES = {
|
|
|
11878
12312
|
description: "Set, edit, copy, or clear property values for enrolled or associated records",
|
|
11879
12313
|
connectionType: "SINGLE_CONNECTION",
|
|
11880
12314
|
fields: [
|
|
11881
|
-
{ name: "
|
|
12315
|
+
{ name: "property", type: "string", required: true, description: "Internal property name to set" },
|
|
11882
12316
|
{ name: "value", type: "object", required: true, description: "MUST include type: 'STATIC_VALUE' when setting a value, e.g. { type: 'STATIC_VALUE', staticValue: 'value' }. Omitting type causes HTTP 500." },
|
|
11883
12317
|
{ name: "association", type: "object", required: false, description: "Association spec if setting on an associated record: { associationCategory: 'HUBSPOT_DEFINED', associationTypeId: <number> }" }
|
|
11884
12318
|
]
|
|
@@ -12444,7 +12878,7 @@ var collectWorkflowAssociatedPropertyActionRefs = (actions) => actions.flatMap((
|
|
|
12444
12878
|
if (actionTypeId !== "0-5") return [];
|
|
12445
12879
|
const fields48 = isRecord(action.fields) ? action.fields : void 0;
|
|
12446
12880
|
const association = isRecord(fields48?.association) ? fields48.association : void 0;
|
|
12447
|
-
const propertyName = typeof fields48?.property_name === "string" ? fields48.property_name : void 0;
|
|
12881
|
+
const propertyName = typeof fields48?.property === "string" ? fields48.property : typeof fields48?.property_name === "string" ? fields48.property_name : void 0;
|
|
12448
12882
|
const associationTypeId = typeof association?.associationTypeId === "number" ? association.associationTypeId : void 0;
|
|
12449
12883
|
if (!propertyName || associationTypeId === void 0) return [];
|
|
12450
12884
|
return [{
|
|
@@ -12718,10 +13152,9 @@ var normalizeWorkflowActionValues = (actions) => actions.map((action) => {
|
|
|
12718
13152
|
if (!fields48) return { ...action };
|
|
12719
13153
|
const actionTypeId = typeof action.actionTypeId === "string" ? action.actionTypeId : "";
|
|
12720
13154
|
if (actionTypeId === "0-5") {
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
};
|
|
13155
|
+
const { property_name, ...restFields } = fields48;
|
|
13156
|
+
const normalizedFields = property_name && !restFields.property ? { ...restFields, property: property_name, value: injectStaticValueType(restFields.value) } : { ...restFields, value: injectStaticValueType(restFields.value) };
|
|
13157
|
+
return { ...action, fields: normalizedFields };
|
|
12725
13158
|
}
|
|
12726
13159
|
if (actionTypeId === "0-14" && Array.isArray(fields48.properties)) {
|
|
12727
13160
|
return {
|
|
@@ -12753,7 +13186,7 @@ var collectWorkflowPropertyActionRefs = (actions) => actions.flatMap((action) =>
|
|
|
12753
13186
|
const fields48 = typeof action.fields === "object" && action.fields !== null ? action.fields : void 0;
|
|
12754
13187
|
const association = typeof fields48?.association === "object" && fields48.association !== null ? fields48.association : void 0;
|
|
12755
13188
|
const value = typeof fields48?.value === "object" && fields48.value !== null ? fields48.value : void 0;
|
|
12756
|
-
const propertyName = typeof fields48?.property_name === "string" ? fields48.property_name : void 0;
|
|
13189
|
+
const propertyName = typeof fields48?.property === "string" ? fields48.property : typeof fields48?.property_name === "string" ? fields48.property_name : void 0;
|
|
12757
13190
|
if (!propertyName) return [];
|
|
12758
13191
|
return [{
|
|
12759
13192
|
actionId: typeof action.actionId === "string" ? action.actionId : "<missing>",
|
|
@@ -13661,10 +14094,10 @@ var formatOperationDetail = (def) => {
|
|
|
13661
14094
|
};
|
|
13662
14095
|
|
|
13663
14096
|
// src/pure/operation-conversion.ts
|
|
13664
|
-
var FlatOperationSchema =
|
|
13665
|
-
type:
|
|
13666
|
-
description:
|
|
13667
|
-
fields:
|
|
14097
|
+
var FlatOperationSchema = z67.object({
|
|
14098
|
+
type: z67.string().describe("Operation type (use describe_operations to see available types)"),
|
|
14099
|
+
description: z67.string().describe("What this operation does"),
|
|
14100
|
+
fields: z67.record(z67.string(), z67.unknown()).describe("Operation-specific fields (use describe_operations to see the required fields for each type)")
|
|
13668
14101
|
});
|
|
13669
14102
|
var nestOperation = (flat) => {
|
|
13670
14103
|
const def = getOperationDef(flat.type);
|
|
@@ -13700,9 +14133,9 @@ var convertAndValidateOperations = (operations, startIndex = 1) => {
|
|
|
13700
14133
|
|
|
13701
14134
|
// src/tools/build_plan.ts
|
|
13702
14135
|
var OPERATION_TYPE_COUNT = OPERATION_REGISTRY.length;
|
|
13703
|
-
var EditSchema =
|
|
13704
|
-
action:
|
|
13705
|
-
index:
|
|
14136
|
+
var EditSchema = z68.object({
|
|
14137
|
+
action: z68.enum(["replace", "remove"]).describe("'replace' swaps an operation, 'remove' deletes it"),
|
|
14138
|
+
index: z68.number().int().min(1).describe("1-based operation index"),
|
|
13706
14139
|
operation: FlatOperationSchema.optional().describe("Required for replace, ignored for remove")
|
|
13707
14140
|
});
|
|
13708
14141
|
var summariseFields = (op) => {
|
|
@@ -13815,12 +14248,12 @@ WORKFLOW:
|
|
|
13815
14248
|
4. submit_plan (dry_run: true) - Validate without saving (optional)
|
|
13816
14249
|
5. submit_plan - Submit after user confirms`,
|
|
13817
14250
|
inputSchema: {
|
|
13818
|
-
title:
|
|
13819
|
-
description:
|
|
13820
|
-
operations:
|
|
13821
|
-
edits:
|
|
13822
|
-
force:
|
|
13823
|
-
portalIds:
|
|
14251
|
+
title: z68.string().optional().describe("Short, descriptive title (required when creating a new draft)"),
|
|
14252
|
+
description: z68.string().optional().describe("Detailed explanation of what the plan does and why (required when creating a new draft)"),
|
|
14253
|
+
operations: z68.array(FlatOperationSchema).optional().describe("Operations to add to targeted draft(s)"),
|
|
14254
|
+
edits: z68.array(EditSchema).optional().describe("Edits to apply: replace or remove operations by 1-based index"),
|
|
14255
|
+
force: z68.boolean().optional().describe("If true, discard targeted draft(s) and start fresh"),
|
|
14256
|
+
portalIds: z68.array(z68.number()).optional().describe("Optional explicit portal IDs to target. If provided, responses are keyed by portal ID.")
|
|
13824
14257
|
}
|
|
13825
14258
|
}, async ({ title, description, operations, edits, force, portalIds }) => {
|
|
13826
14259
|
const portalResolution = resolvePortalIds(
|
|
@@ -13988,7 +14421,7 @@ Use describe_operations to see the required fields for each operation type.`
|
|
|
13988
14421
|
}
|
|
13989
14422
|
|
|
13990
14423
|
// src/tools/describe_operations.ts
|
|
13991
|
-
import { z as
|
|
14424
|
+
import { z as z69 } from "zod";
|
|
13992
14425
|
var OPERATION_TYPE_COUNT2 = OPERATION_REGISTRY.length;
|
|
13993
14426
|
function registerDescribeOperationsTool(server2) {
|
|
13994
14427
|
server2.registerTool("describe_operations", {
|
|
@@ -14001,7 +14434,7 @@ Use cases:
|
|
|
14001
14434
|
- Call with no arguments to list all available operation types.
|
|
14002
14435
|
- Call with specific types to see their full field schemas and examples.`,
|
|
14003
14436
|
inputSchema: {
|
|
14004
|
-
operation_types:
|
|
14437
|
+
operation_types: z69.array(z69.string()).optional().describe("Operation types to describe (e.g. ['create_property', 'delete_pipeline']). Omit to list all available types.")
|
|
14005
14438
|
}
|
|
14006
14439
|
}, async ({ operation_types }) => {
|
|
14007
14440
|
if (!operation_types || operation_types.length === 0) {
|
|
@@ -14026,7 +14459,7 @@ Call describe_operations with no arguments to see all available types.`);
|
|
|
14026
14459
|
}
|
|
14027
14460
|
|
|
14028
14461
|
// src/tools/submit_plan.ts
|
|
14029
|
-
import { z as
|
|
14462
|
+
import { z as z70 } from "zod";
|
|
14030
14463
|
import { Effect as Effect97 } from "effect";
|
|
14031
14464
|
var formatFixHint = (issue, summary) => {
|
|
14032
14465
|
const opNum = issue.operation_index + 1;
|
|
@@ -14250,8 +14683,8 @@ RECOMMENDED WORKFLOW:
|
|
|
14250
14683
|
4. Fix any issues with build_plan(edits: [...])
|
|
14251
14684
|
5. Call submit_plan() to save after user confirms`,
|
|
14252
14685
|
inputSchema: {
|
|
14253
|
-
dry_run:
|
|
14254
|
-
portalIds:
|
|
14686
|
+
dry_run: z70.boolean().optional().describe("If true, validate only without saving. Defaults to false."),
|
|
14687
|
+
portalIds: z70.array(z70.number()).optional().describe("Optional explicit portal IDs to submit. If provided, results are keyed by portal ID.")
|
|
14255
14688
|
}
|
|
14256
14689
|
}, async ({ dry_run, portalIds }) => {
|
|
14257
14690
|
const portalResolution = resolvePortalIds(
|
|
@@ -14294,7 +14727,7 @@ RECOMMENDED WORKFLOW:
|
|
|
14294
14727
|
}
|
|
14295
14728
|
|
|
14296
14729
|
// src/tools/get_plans.ts
|
|
14297
|
-
import { z as
|
|
14730
|
+
import { z as z71 } from "zod";
|
|
14298
14731
|
import { Effect as Effect98 } from "effect";
|
|
14299
14732
|
var serialiseDraft2 = (portalId) => {
|
|
14300
14733
|
const draft = getDraft(portalId);
|
|
@@ -14323,8 +14756,8 @@ Statuses:
|
|
|
14323
14756
|
- FAILED: Execution failed
|
|
14324
14757
|
- REJECTED: User rejected the plan`,
|
|
14325
14758
|
inputSchema: {
|
|
14326
|
-
status:
|
|
14327
|
-
portalIds:
|
|
14759
|
+
status: z71.enum(["DRAFT", "REJECTED", "EXECUTING", "EXECUTED", "FAILED"]).optional().describe("Filter by plan status. Omit to show all plans."),
|
|
14760
|
+
portalIds: z71.array(z71.number()).optional().describe("Optional explicit portal IDs. If provided, results are keyed by portal ID.")
|
|
14328
14761
|
}
|
|
14329
14762
|
}, async ({ status, portalIds }) => {
|
|
14330
14763
|
const portalResolution = resolvePortalIds(
|