@dypai-ai/mcp 1.7.1 → 1.7.2
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/tools/sync/push.js +54 -12
package/package.json
CHANGED
package/src/tools/sync/push.js
CHANGED
|
@@ -483,7 +483,8 @@ export const dypaiPushTool = {
|
|
|
483
483
|
"After validation, regenerates `dypai/types/endpoints.gen.ts` from effective Flow/YAML contracts (check the `types` field in the response). " +
|
|
484
484
|
"ALWAYS run dypai_diff first to preview what will be staged. " +
|
|
485
485
|
"The public dypai_push wrapper also saves frontend source to Studio. " +
|
|
486
|
-
"By default, endpoints in remote but missing locally are kept (safe). Pass delete_orphans: true to stage their deletion as a draft as well."
|
|
486
|
+
"By default, endpoints in remote but missing locally are kept (safe). Pass delete_orphans: true to stage their deletion as a draft as well. " +
|
|
487
|
+
"PARTIAL PUSH: an endpoint whose flow has errors is SKIPPED (it keeps its live version) and the rest are pushed — one broken endpoint no longer blocks the whole push. Skipped ones are listed in `skipped_endpoints` (with their errors) and `partial_success` is set. A project-level error still blocks. Use skip_validation:true to push everything, errors included.",
|
|
487
488
|
inputSchema: {
|
|
488
489
|
type: "object",
|
|
489
490
|
properties: {
|
|
@@ -513,7 +514,7 @@ export const dypaiPushTool = {
|
|
|
513
514
|
},
|
|
514
515
|
skip_validation: {
|
|
515
516
|
type: "boolean",
|
|
516
|
-
description: "Skip the dypai_validate pre-flight check.
|
|
517
|
+
description: "Skip the dypai_validate pre-flight check and push EVERY endpoint, including ones with errors (no per-endpoint skipping). By default the push already applies the valid endpoints and only skips the erroring ones — so use this only when you know the validator is wrong. Default: false.",
|
|
517
518
|
default: false,
|
|
518
519
|
},
|
|
519
520
|
},
|
|
@@ -529,19 +530,31 @@ export const dypaiPushTool = {
|
|
|
529
530
|
const configProjectId = config?.project_id || null
|
|
530
531
|
const targetProjectId = project_id || configProjectId
|
|
531
532
|
|
|
532
|
-
// Pre-flight validation (lint).
|
|
533
|
+
// Pre-flight validation (lint). Partial push: endpoints whose flow has an
|
|
534
|
+
// error are SKIPPED (they keep their live version) and the rest is pushed —
|
|
535
|
+
// one broken endpoint no longer tanks the whole push. A project-level error
|
|
536
|
+
// (no endpoint to isolate it to) still blocks, since it can't be scoped out.
|
|
537
|
+
// skip_validation bypasses all of this and pushes everything.
|
|
538
|
+
let erroringEndpoints = new Set()
|
|
539
|
+
let skippedDiagnostics = []
|
|
533
540
|
if (!skip_validation && !dry_run) {
|
|
534
541
|
try {
|
|
535
542
|
const validation = await runValidation(rootDir, project_id || configProjectId)
|
|
536
543
|
if (!validation.success) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
+
const errorDiags = (validation.diagnostics || []).filter(d => d.severity === "error")
|
|
545
|
+
const projectLevel = errorDiags.filter(d => !d.endpoint)
|
|
546
|
+
if (projectLevel.length) {
|
|
547
|
+
return {
|
|
548
|
+
success: false,
|
|
549
|
+
applied: false,
|
|
550
|
+
reason: "validation_failed",
|
|
551
|
+
summary: validation.summary,
|
|
552
|
+
diagnostics: projectLevel.slice(0, 20),
|
|
553
|
+
hint: `${projectLevel.length} project-level error(s) can't be isolated to a single endpoint. Fix them, or retry with skip_validation: true to override.`,
|
|
554
|
+
}
|
|
544
555
|
}
|
|
556
|
+
skippedDiagnostics = errorDiags
|
|
557
|
+
erroringEndpoints = new Set(errorDiags.map(d => d.endpoint).filter(Boolean))
|
|
545
558
|
}
|
|
546
559
|
} catch (e) {
|
|
547
560
|
// Don't block the push on a validator crash — just warn
|
|
@@ -640,6 +653,30 @@ export const dypaiPushTool = {
|
|
|
640
653
|
stateSnapshot,
|
|
641
654
|
liveRemote: remote,
|
|
642
655
|
})
|
|
656
|
+
|
|
657
|
+
// Partial push: drop endpoints that failed validation from create/update so
|
|
658
|
+
// they aren't pushed (they keep their live version). Deletes stay — a broken
|
|
659
|
+
// local flow shouldn't block removing endpoints. skip_validation leaves
|
|
660
|
+
// erroringEndpoints empty, so nothing is dropped.
|
|
661
|
+
const skippedNames = []
|
|
662
|
+
if (erroringEndpoints.size) {
|
|
663
|
+
const drop = (arr) => (arr || []).filter((item) => {
|
|
664
|
+
if (erroringEndpoints.has(item.name)) { skippedNames.push(item.name); return false }
|
|
665
|
+
return true
|
|
666
|
+
})
|
|
667
|
+
plan.create = drop(plan.create)
|
|
668
|
+
plan.update = drop(plan.update)
|
|
669
|
+
}
|
|
670
|
+
const skipped_endpoints = skippedNames.length
|
|
671
|
+
? [...new Set(skippedNames)].map((name) => ({
|
|
672
|
+
endpoint: name,
|
|
673
|
+
errors: skippedDiagnostics
|
|
674
|
+
.filter((d) => d.endpoint === name)
|
|
675
|
+
.slice(0, 5)
|
|
676
|
+
.map((d) => ({ rule: d.rule, message: d.message, file: d.file, loc: d.loc })),
|
|
677
|
+
}))
|
|
678
|
+
: undefined
|
|
679
|
+
|
|
643
680
|
const groupChanges = (plan.groups?.create?.length || 0) + (plan.groups?.delete?.length || 0)
|
|
644
681
|
const totalChanges = plan.create.length + plan.update.length + plan.delete.length + groupChanges
|
|
645
682
|
|
|
@@ -676,8 +713,10 @@ export const dypaiPushTool = {
|
|
|
676
713
|
? "source_checkpoint_failed"
|
|
677
714
|
: automationSyncHasFailed
|
|
678
715
|
? "automation_sync_failed"
|
|
716
|
+
: skipped_endpoints && totalChanges === 0 ? "all_skipped"
|
|
679
717
|
: totalChanges === 0 ? "no_changes" : "dry_run",
|
|
680
718
|
summary: summaryFromPlan(plan),
|
|
719
|
+
skipped_endpoints,
|
|
681
720
|
plan,
|
|
682
721
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
683
722
|
types: typesGenerated,
|
|
@@ -847,7 +886,7 @@ export const dypaiPushTool = {
|
|
|
847
886
|
return {
|
|
848
887
|
success: errors.length === 0 && !sourceCheckpointFailed && !automationSyncHasFailed,
|
|
849
888
|
applied: endpointTotal > 0 || (realtime && !realtime.skipped),
|
|
850
|
-
partial_success: partialSuccess || sourceCheckpointFailed || automationSyncHasFailed,
|
|
889
|
+
partial_success: partialSuccess || sourceCheckpointFailed || automationSyncHasFailed || !!skipped_endpoints,
|
|
851
890
|
reason: sourceCheckpointFailed
|
|
852
891
|
? "source_checkpoint_failed"
|
|
853
892
|
: automationSyncHasFailed
|
|
@@ -878,6 +917,7 @@ export const dypaiPushTool = {
|
|
|
878
917
|
},
|
|
879
918
|
details: applied,
|
|
880
919
|
endpoint_results,
|
|
920
|
+
skipped_endpoints,
|
|
881
921
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
882
922
|
errors: errors.length ? errors : undefined,
|
|
883
923
|
types: typesGenerated,
|
|
@@ -887,7 +927,9 @@ export const dypaiPushTool = {
|
|
|
887
927
|
// Only one next_step — and only when it's non-obvious. Drafts win
|
|
888
928
|
// over the test suggestion because tests against live won't see
|
|
889
929
|
// the change until the drafts are promoted.
|
|
890
|
-
next_step:
|
|
930
|
+
next_step: skipped_endpoints
|
|
931
|
+
? `⚠️ ${skipped_endpoints.length} endpoint(s) SKIPPED (they keep their live version) because their flow has errors: ${skipped_endpoints.map(s => s.endpoint).slice(0, 5).join(", ")}${skipped_endpoints.length > 5 ? "…" : ""}. Everything else was pushed. Fix the skipped ones (see skipped_endpoints[].errors) and push again — or use skip_validation:true to push them anyway.`
|
|
932
|
+
: errors.length
|
|
891
933
|
? partialSuccess
|
|
892
934
|
? `${endpointTotal} endpoint(s) saved, ${failedTotal} failed. Fix failed endpoints and push again. Failed: ${errors.slice(0, 3).map((item) => item.endpoint || item.group || item.op).join(", ")}${errors.length > 3 ? "…" : ""}`
|
|
893
935
|
: "Fix the offending YAMLs and push again."
|