@dypai-ai/mcp 1.7.3 → 1.7.5
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/package.json +1 -1
- package/src/lib/cloudBackendCompiler.js +4 -1
- package/src/tools/proxy.js +16 -6
- package/src/tools/sync/planner.js +65 -10
- package/src/tools/sync/pull.js +44 -17
- package/src/tools/sync/push.js +66 -1
package/package.json
CHANGED
|
@@ -23,7 +23,10 @@ async function compileSnapshot(projectId, command, files, endpoint = undefined)
|
|
|
23
23
|
files,
|
|
24
24
|
}
|
|
25
25
|
if (endpoint) args.endpoint = endpoint
|
|
26
|
-
|
|
26
|
+
// Compiler `ok:false` is a domain validation result, not a transport/tool
|
|
27
|
+
// failure. It intentionally carries valid payloads plus diagnostics so the
|
|
28
|
+
// push pipeline can skip only broken flows instead of dropping all source.
|
|
29
|
+
return proxyToolCall("backend_compile_snapshot", args, { allowFailureResult: true })
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export async function buildSnapshotPayload(dypaiRootDir, projectRoot = null) {
|
package/src/tools/proxy.js
CHANGED
|
@@ -209,7 +209,15 @@ async function ensureInitialized() {
|
|
|
209
209
|
return initPromise
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
function shouldPromoteRemoteFailure(parsed, allowFailureResult = false) {
|
|
213
|
+
return !allowFailureResult
|
|
214
|
+
&& parsed
|
|
215
|
+
&& typeof parsed === "object"
|
|
216
|
+
&& !Array.isArray(parsed)
|
|
217
|
+
&& (parsed.success === false || parsed.ok === false)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export async function proxyToolCall(toolName, args, { allowFailureResult = false } = {}) {
|
|
213
221
|
async function callOnce() {
|
|
214
222
|
await ensureInitialized()
|
|
215
223
|
|
|
@@ -242,11 +250,9 @@ export async function proxyToolCall(toolName, args) {
|
|
|
242
250
|
// Other remote errors come as a JSON object with success:false but no isError
|
|
243
251
|
// flag. The push pipeline was treating these as successes — promote them to
|
|
244
252
|
// throws here so the caller's try/catch sees them.
|
|
245
|
-
if (parsed
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
throw new Error(typeof msg === "string" ? msg : JSON.stringify(msg))
|
|
249
|
-
}
|
|
253
|
+
if (shouldPromoteRemoteFailure(parsed, allowFailureResult)) {
|
|
254
|
+
const msg = parsed.error || parsed.message || parsed.detail || JSON.stringify(parsed).slice(0, 300)
|
|
255
|
+
throw new Error(typeof msg === "string" ? msg : JSON.stringify(msg))
|
|
250
256
|
}
|
|
251
257
|
return parsed
|
|
252
258
|
}
|
|
@@ -270,3 +276,7 @@ export async function proxyToolCall(toolName, args) {
|
|
|
270
276
|
throw error
|
|
271
277
|
}
|
|
272
278
|
}
|
|
279
|
+
|
|
280
|
+
export const __testing = {
|
|
281
|
+
shouldPromoteRemoteFailure,
|
|
282
|
+
}
|
|
@@ -539,15 +539,6 @@ export async function readLocalEffectiveState(rootDir, projectId = null, deps =
|
|
|
539
539
|
if (shadowedMeta) shadowed.push({ name: payload.name, shadowed: shadowedMeta })
|
|
540
540
|
}
|
|
541
541
|
|
|
542
|
-
for (const diagnostic of diagnostics) {
|
|
543
|
-
if (diagnostic?.severity !== "error") continue
|
|
544
|
-
yamlState.errors.push({
|
|
545
|
-
file: diagnostic.file || diagnostic.endpoint,
|
|
546
|
-
error: diagnostic.message || "Failed to build flow push payload",
|
|
547
|
-
rule: diagnostic.rule || "flow_push_payload_failed",
|
|
548
|
-
})
|
|
549
|
-
}
|
|
550
|
-
|
|
551
542
|
for (const item of rejected) {
|
|
552
543
|
if (!isBackendSourcePath(item?.path)) continue
|
|
553
544
|
yamlState.errors.push({
|
|
@@ -562,7 +553,14 @@ export async function readLocalEffectiveState(rootDir, projectId = null, deps =
|
|
|
562
553
|
byName[name] = { ...entry, source: "legacy-yaml" }
|
|
563
554
|
}
|
|
564
555
|
|
|
565
|
-
return {
|
|
556
|
+
return {
|
|
557
|
+
byName,
|
|
558
|
+
errors: yamlState.errors,
|
|
559
|
+
shadowed,
|
|
560
|
+
runnerWarning: null,
|
|
561
|
+
compilerDiagnostics: diagnostics,
|
|
562
|
+
automations: bulkResult.data?.automations ?? null,
|
|
563
|
+
}
|
|
566
564
|
}
|
|
567
565
|
|
|
568
566
|
// ─── Normalization + diff ──────────────────────────────────────────────────
|
|
@@ -664,6 +662,39 @@ function localToComparable(entry, mapsCtx) {
|
|
|
664
662
|
return remoteToComparable(row, mapsCtx)
|
|
665
663
|
}
|
|
666
664
|
|
|
665
|
+
export function flowSourceHashesMatch(entry, remoteRow) {
|
|
666
|
+
if (entry?.source !== "flow" || !entry.pushPayload || !remoteRow) return false
|
|
667
|
+
const localHash = entry.pushPayload.workflow_code?.metadata?.source_hash
|
|
668
|
+
const remoteHash = remoteRow.workflow_code?.metadata?.source_hash
|
|
669
|
+
return typeof localHash === "string"
|
|
670
|
+
&& localHash.length > 0
|
|
671
|
+
&& localHash === remoteHash
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
export function preserveMatchingRemoteFileRefs(rawLocalDoc, localComparable, remoteComparable) {
|
|
675
|
+
if (!rawLocalDoc || !localComparable || !remoteComparable) return localComparable
|
|
676
|
+
if (Array.isArray(rawLocalDoc)) {
|
|
677
|
+
if (!Array.isArray(localComparable) || !Array.isArray(remoteComparable)) return localComparable
|
|
678
|
+
rawLocalDoc.forEach((item, index) => {
|
|
679
|
+
preserveMatchingRemoteFileRefs(item, localComparable[index], remoteComparable[index])
|
|
680
|
+
})
|
|
681
|
+
return localComparable
|
|
682
|
+
}
|
|
683
|
+
if (typeof rawLocalDoc !== "object" || Array.isArray(localComparable) || Array.isArray(remoteComparable)) {
|
|
684
|
+
return localComparable
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
for (const [key, value] of Object.entries(rawLocalDoc)) {
|
|
688
|
+
if (key.endsWith("_file") && typeof value === "string" && remoteComparable[key] === value) {
|
|
689
|
+
delete localComparable[key.replace(/_file$/, "")]
|
|
690
|
+
localComparable[key] = value
|
|
691
|
+
continue
|
|
692
|
+
}
|
|
693
|
+
preserveMatchingRemoteFileRefs(value, localComparable[key], remoteComparable[key])
|
|
694
|
+
}
|
|
695
|
+
return localComparable
|
|
696
|
+
}
|
|
697
|
+
|
|
667
698
|
function deepEqual(a, b) {
|
|
668
699
|
if (a === b) return true
|
|
669
700
|
if (typeof a !== typeof b) return false
|
|
@@ -771,6 +802,7 @@ export function detectConflicts(stateSnapshot, remoteByName) {
|
|
|
771
802
|
export function computePlan(local, remote, mapsCtx, { deleteOrphans = false, stateSnapshot = null, liveRemote = null } = {}) {
|
|
772
803
|
const plan = { create: [], update: [], delete: [], unchanged: [] }
|
|
773
804
|
const warnings = []
|
|
805
|
+
const compilerOnlyDrift = []
|
|
774
806
|
|
|
775
807
|
const endpointNameCollisions = findEndpointNameCollisions(Object.keys(remote?.byName || {}))
|
|
776
808
|
if (endpointNameCollisions.length) {
|
|
@@ -824,6 +856,19 @@ export function computePlan(local, remote, mapsCtx, { deleteOrphans = false, sta
|
|
|
824
856
|
}
|
|
825
857
|
|
|
826
858
|
const remoteCanonical = remoteToComparable(remoteRow, mapsCtx)
|
|
859
|
+
if (entry.doc) {
|
|
860
|
+
preserveMatchingRemoteFileRefs(entry.doc, localCanonical, remoteCanonical)
|
|
861
|
+
}
|
|
862
|
+
if (
|
|
863
|
+
flowSourceHashesMatch(entry, remoteRow)
|
|
864
|
+
&& !deepEqual(localCanonical.workflow, remoteCanonical.workflow)
|
|
865
|
+
) {
|
|
866
|
+
// Same authored source, different compiler artifact (for example after
|
|
867
|
+
// a compiler upgrade). Keep comparing roles/contracts/description, but
|
|
868
|
+
// do not stage a mass endpoint update solely to rewrite generated IR.
|
|
869
|
+
localCanonical.workflow = remoteCanonical.workflow
|
|
870
|
+
compilerOnlyDrift.push(name)
|
|
871
|
+
}
|
|
827
872
|
if (deepEqual(localCanonical, remoteCanonical)) {
|
|
828
873
|
plan.unchanged.push(name)
|
|
829
874
|
} else {
|
|
@@ -832,6 +877,16 @@ export function computePlan(local, remote, mapsCtx, { deleteOrphans = false, sta
|
|
|
832
877
|
}
|
|
833
878
|
}
|
|
834
879
|
|
|
880
|
+
if (compilerOnlyDrift.length) {
|
|
881
|
+
warnings.push({
|
|
882
|
+
type: "compiler_artifact_drift_ignored",
|
|
883
|
+
count: compilerOnlyDrift.length,
|
|
884
|
+
examples: compilerOnlyDrift.slice(0, 25),
|
|
885
|
+
truncated: compilerOnlyDrift.length > 25,
|
|
886
|
+
hint: "Authored Flow source_hash matches live. Generated workflow differences from a compiler upgrade were not staged.",
|
|
887
|
+
})
|
|
888
|
+
}
|
|
889
|
+
|
|
835
890
|
if (deleteOrphans) {
|
|
836
891
|
for (const name of Object.keys(remote.byName)) {
|
|
837
892
|
if (!local.byName[name]) plan.delete.push({ name })
|
package/src/tools/sync/pull.js
CHANGED
|
@@ -761,10 +761,15 @@ export const dypaiPullTool = {
|
|
|
761
761
|
description: "If true, removes existing endpoints/, sql/, prompts/ before writing and allows persisted Flow source to overwrite differing local .flow.ts files.",
|
|
762
762
|
default: false,
|
|
763
763
|
},
|
|
764
|
+
live_authoritative: {
|
|
765
|
+
type: "boolean",
|
|
766
|
+
description: "Recovery mode. Export every live workflow as legacy YAML instead of trusting persisted Flow/Automation source. Use only when live is intentionally authoritative and source has drifted.",
|
|
767
|
+
default: false,
|
|
768
|
+
},
|
|
764
769
|
},
|
|
765
770
|
},
|
|
766
771
|
|
|
767
|
-
async execute({ project_id, out_dir = "./dypai", clean = false } = {}) {
|
|
772
|
+
async execute({ project_id, out_dir = "./dypai", clean = false, live_authoritative = false } = {}) {
|
|
768
773
|
const { path: outDir, source: outDirSource } = resolveOutDir(out_dir)
|
|
769
774
|
const suspiciousWarning = suspiciousPathWarning(outDir, outDirSource)
|
|
770
775
|
|
|
@@ -864,6 +869,7 @@ export const dypaiPullTool = {
|
|
|
864
869
|
|
|
865
870
|
const filesWritten = []
|
|
866
871
|
const errors = []
|
|
872
|
+
const sourceRecoveryWarnings = []
|
|
867
873
|
|
|
868
874
|
const capabilityGroups = capabilityCatalogResult?.groups || []
|
|
869
875
|
const capabilityDoc = {
|
|
@@ -939,7 +945,7 @@ export const dypaiPullTool = {
|
|
|
939
945
|
row.workflow_source = parseMaybeJson(row.workflow_source)
|
|
940
946
|
try {
|
|
941
947
|
const workflowSource = row.workflow_source
|
|
942
|
-
if (isEditableTsSource(workflowSource)) {
|
|
948
|
+
if (isEditableTsSource(workflowSource) && !live_authoritative) {
|
|
943
949
|
const groupName = row.group_id ? (mapsCtx.groupIdToName[row.group_id] || null) : null
|
|
944
950
|
const sourceFile = normalizeEditableSourceFile(workflowSource, row.name)
|
|
945
951
|
const relFlowPath = flowSourceRelPath(sourceFile)
|
|
@@ -985,18 +991,30 @@ export const dypaiPullTool = {
|
|
|
985
991
|
continue
|
|
986
992
|
}
|
|
987
993
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
+
// The editable TS source has been lost, but live still contains the
|
|
995
|
+
// complete executable workflow. Recover it as legacy YAML so a live
|
|
996
|
+
// repair pull remains complete and its state baseline stays honest.
|
|
997
|
+
// The warning makes the source loss visible without dropping the
|
|
998
|
+
// endpoint from disk or producing a false clean dry-run.
|
|
999
|
+
sourceRecoveryWarnings.push({
|
|
994
1000
|
endpoint: row.name,
|
|
995
|
-
|
|
1001
|
+
source_file: sourceFile,
|
|
1002
|
+
recovered_as: "legacy_yaml",
|
|
1003
|
+
warning:
|
|
996
1004
|
`Endpoint is source-authored but ${sourceFile} was not found in persisted project source. ` +
|
|
997
|
-
|
|
1005
|
+
"Recovered the live workflow as legacy YAML; restore editable TypeScript later if desired.",
|
|
998
1006
|
})
|
|
999
|
-
|
|
1007
|
+
row.workflow_source = null
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
if (isEditableTsSource(workflowSource) && live_authoritative) {
|
|
1011
|
+
sourceRecoveryWarnings.push({
|
|
1012
|
+
endpoint: row.name,
|
|
1013
|
+
source_file: normalizeEditableSourceFile(workflowSource, row.name),
|
|
1014
|
+
recovered_as: "legacy_yaml",
|
|
1015
|
+
warning: "Live-authoritative recovery exported the executable workflow as legacy YAML. The previous editable TypeScript source remains available in the backup/history.",
|
|
1016
|
+
})
|
|
1017
|
+
row.workflow_source = null
|
|
1000
1018
|
}
|
|
1001
1019
|
|
|
1002
1020
|
const { doc, extractedFiles } = serializeEndpoint(row, mapsCtx)
|
|
@@ -1191,12 +1209,26 @@ export const dypaiPullTool = {
|
|
|
1191
1209
|
: ["Read dypai/schema.sql before writing queries.", "Edit Flow in dypai/flows/, Automations in dypai/automations/, or legacy YAML in dypai/endpoints/, then dypai_diff → dypai_push."],
|
|
1192
1210
|
}
|
|
1193
1211
|
|
|
1212
|
+
const safetyWarnings = [
|
|
1213
|
+
...(endpointNameCollisions.length ? [{
|
|
1214
|
+
type: "canonical_endpoint_name_collisions",
|
|
1215
|
+
count: endpointNameCollisions.length,
|
|
1216
|
+
examples: endpointNameCollisions.slice(0, 10),
|
|
1217
|
+
hint: "Legacy underscore and canonical hyphen slugs coexist. Treat them as separate live APIs; audit traffic and migrate/delete deliberately.",
|
|
1218
|
+
}] : []),
|
|
1219
|
+
...sourceRecoveryWarnings.map((item) => ({
|
|
1220
|
+
type: "missing_editable_source_recovered",
|
|
1221
|
+
...item,
|
|
1222
|
+
})),
|
|
1223
|
+
]
|
|
1224
|
+
|
|
1194
1225
|
return {
|
|
1195
1226
|
success: errors.length === 0,
|
|
1196
1227
|
endpoints: endpoints.length,
|
|
1197
1228
|
files_written: filesWritten.length,
|
|
1198
1229
|
files_kept_local: keptLocalEndpoints.length,
|
|
1199
1230
|
kept_local_endpoints: keptLocalEndpoints.length ? keptLocalEndpoints : undefined,
|
|
1231
|
+
source_recovery_warnings: sourceRecoveryWarnings.length ? sourceRecoveryWarnings : undefined,
|
|
1200
1232
|
name_collisions: endpointNameCollisions.length,
|
|
1201
1233
|
output_dir: outDir,
|
|
1202
1234
|
out_dir_resolved_via: outDirSource,
|
|
@@ -1206,12 +1238,7 @@ export const dypaiPullTool = {
|
|
|
1206
1238
|
overview,
|
|
1207
1239
|
errors: errors.length ? errors : undefined,
|
|
1208
1240
|
warning: suspiciousWarning || undefined,
|
|
1209
|
-
safety_warnings:
|
|
1210
|
-
type: "canonical_endpoint_name_collisions",
|
|
1211
|
-
count: endpointNameCollisions.length,
|
|
1212
|
-
examples: endpointNameCollisions.slice(0, 10),
|
|
1213
|
-
hint: "Legacy underscore and canonical hyphen slugs coexist. Treat them as separate live APIs; audit traffic and migrate/delete deliberately.",
|
|
1214
|
-
}] : undefined,
|
|
1241
|
+
safety_warnings: safetyWarnings.length ? safetyWarnings : undefined,
|
|
1215
1242
|
hint: errors.length
|
|
1216
1243
|
? keptLocalEndpoints.length
|
|
1217
1244
|
? `${keptLocalEndpoints.length} local Flow file(s) differed and were kept. They were excluded from .dypai/state.json, so a later push will continue to block on remote drift. Review the files or rerun with clean:true only when remote is intentionally authoritative.`
|
package/src/tools/sync/push.js
CHANGED
|
@@ -310,6 +310,41 @@ function dropErroringFromPlan(plan, erroringEndpoints, skippedDiagnostics) {
|
|
|
310
310
|
: undefined
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
function skippedEndpointsFromDiagnostics(diagnostics) {
|
|
314
|
+
const names = [...new Set(
|
|
315
|
+
(diagnostics || [])
|
|
316
|
+
.filter((item) => item?.severity === "error" && item.endpoint)
|
|
317
|
+
.map((item) => item.endpoint),
|
|
318
|
+
)]
|
|
319
|
+
return names.length
|
|
320
|
+
? names.map((name) => ({
|
|
321
|
+
endpoint: name,
|
|
322
|
+
errors: diagnostics
|
|
323
|
+
.filter((item) => item.endpoint === name && item.severity === "error")
|
|
324
|
+
.slice(0, 5)
|
|
325
|
+
.map((item) => ({
|
|
326
|
+
rule: item.rule,
|
|
327
|
+
message: item.message,
|
|
328
|
+
file: item.file,
|
|
329
|
+
loc: item.loc,
|
|
330
|
+
})),
|
|
331
|
+
}))
|
|
332
|
+
: undefined
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function mergeSkippedEndpointSummaries(...groups) {
|
|
336
|
+
const merged = new Map()
|
|
337
|
+
for (const group of groups) {
|
|
338
|
+
for (const item of group || []) {
|
|
339
|
+
const current = merged.get(item.endpoint)
|
|
340
|
+
merged.set(item.endpoint, current
|
|
341
|
+
? { ...current, errors: [...(current.errors || []), ...(item.errors || [])].slice(0, 5) }
|
|
342
|
+
: item)
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return merged.size ? [...merged.values()] : undefined
|
|
346
|
+
}
|
|
347
|
+
|
|
313
348
|
function splitBlockingConflicts(plan, conflicts) {
|
|
314
349
|
const touched = new Set([
|
|
315
350
|
...(plan.update || []).map((item) => item.name),
|
|
@@ -741,6 +776,20 @@ export const dypaiPushTool = {
|
|
|
741
776
|
error: e.message,
|
|
742
777
|
}
|
|
743
778
|
}
|
|
779
|
+
const compilerValidation = partitionValidationErrors(local.compilerDiagnostics)
|
|
780
|
+
if (compilerValidation.projectLevel.length) {
|
|
781
|
+
return {
|
|
782
|
+
success: false,
|
|
783
|
+
applied: false,
|
|
784
|
+
reason: "compiler_validation_failed",
|
|
785
|
+
diagnostics: compilerValidation.projectLevel.slice(0, 20),
|
|
786
|
+
hint: "The compiler reported project-level errors that cannot be isolated to one endpoint.",
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
for (const endpoint of compilerValidation.erroringEndpoints) {
|
|
790
|
+
erroringEndpoints.add(endpoint)
|
|
791
|
+
}
|
|
792
|
+
skippedDiagnostics.push(...compilerValidation.errorDiags)
|
|
744
793
|
try {
|
|
745
794
|
remote = await fetchRemoteState(targetProjectId)
|
|
746
795
|
} catch (e) {
|
|
@@ -817,7 +866,10 @@ export const dypaiPushTool = {
|
|
|
817
866
|
// they aren't pushed (they keep their live version). Deletes stay — a broken
|
|
818
867
|
// local flow shouldn't block removing endpoints. skip_validation leaves
|
|
819
868
|
// erroringEndpoints empty, so nothing is dropped.
|
|
820
|
-
const skipped_endpoints =
|
|
869
|
+
const skipped_endpoints = mergeSkippedEndpointSummaries(
|
|
870
|
+
dropErroringFromPlan(plan, erroringEndpoints, skippedDiagnostics),
|
|
871
|
+
skippedEndpointsFromDiagnostics(compilerValidation.errorDiags),
|
|
872
|
+
)
|
|
821
873
|
|
|
822
874
|
const groupChanges = (plan.groups?.create?.length || 0) + (plan.groups?.delete?.length || 0)
|
|
823
875
|
const totalChanges = plan.create.length + plan.update.length + plan.delete.length + groupChanges
|
|
@@ -830,8 +882,13 @@ export const dypaiPushTool = {
|
|
|
830
882
|
success: false,
|
|
831
883
|
applied: false,
|
|
832
884
|
reason: "conflicts_detected",
|
|
885
|
+
summary: summaryFromPlan(plan),
|
|
833
886
|
conflicts: conflictSplit.blocking,
|
|
834
887
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
888
|
+
skipped_endpoints,
|
|
889
|
+
compiler_diagnostics: local.compilerDiagnostics?.length
|
|
890
|
+
? local.compilerDiagnostics.slice(0, 50)
|
|
891
|
+
: undefined,
|
|
835
892
|
hint: "Remote changes overlap endpoints this push would update/delete. Run dypai_pull to refresh local state, resolve the overlap, then push again. To override, pass force=true.",
|
|
836
893
|
}
|
|
837
894
|
}
|
|
@@ -861,6 +918,9 @@ export const dypaiPushTool = {
|
|
|
861
918
|
: totalChanges === 0 ? "no_changes" : "dry_run",
|
|
862
919
|
summary: summaryFromPlan(plan),
|
|
863
920
|
skipped_endpoints,
|
|
921
|
+
compiler_diagnostics: local.compilerDiagnostics?.length
|
|
922
|
+
? local.compilerDiagnostics.slice(0, 50)
|
|
923
|
+
: undefined,
|
|
864
924
|
plan,
|
|
865
925
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
866
926
|
types: typesGenerated,
|
|
@@ -1073,6 +1133,9 @@ export const dypaiPushTool = {
|
|
|
1073
1133
|
details: applied,
|
|
1074
1134
|
endpoint_results,
|
|
1075
1135
|
skipped_endpoints,
|
|
1136
|
+
compiler_diagnostics: local.compilerDiagnostics?.length
|
|
1137
|
+
? local.compilerDiagnostics.slice(0, 50)
|
|
1138
|
+
: undefined,
|
|
1076
1139
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
1077
1140
|
errors: errors.length ? errors : undefined,
|
|
1078
1141
|
types: typesGenerated,
|
|
@@ -1131,6 +1194,8 @@ export const __testing = {
|
|
|
1131
1194
|
syncAutomationMetadata,
|
|
1132
1195
|
partitionValidationErrors,
|
|
1133
1196
|
dropErroringFromPlan,
|
|
1197
|
+
skippedEndpointsFromDiagnostics,
|
|
1198
|
+
mergeSkippedEndpointSummaries,
|
|
1134
1199
|
normalizeEndpointSelection,
|
|
1135
1200
|
scopePlanToEndpoints,
|
|
1136
1201
|
backendSourcePathsForEndpointSelection,
|