comfyui-mcp 0.50.15 → 0.50.17

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.
@@ -6810,9 +6810,53 @@ export function buildPanelToolDefs() {
6810
6810
  if (ctx.awaitReachable && !(await ctx.awaitReachable())) {
6811
6811
  return noReachableTabFail(args.name ? "workflow_save_as" : "workflow_save");
6812
6812
  }
6813
- return args.name
6814
- ? ctx.call({ cmd: "workflow_save_as", name: args.name }, 15000)
6815
- : ctx.call({ cmd: "workflow_save" }, 15000);
6813
+ const res = args.name
6814
+ ? await ctx.call({ cmd: "workflow_save_as", name: args.name }, 15000)
6815
+ : await ctx.call({ cmd: "workflow_save" }, 15000);
6816
+ if (res.isError)
6817
+ return res;
6818
+ // #1045 — a SAVE-AS replaces the active workflow instance: the canvas is
6819
+ // now the NEW file, with its own identity, while this session's command
6820
+ // fence still names the pre-save one. Every graph call afterwards fails
6821
+ // with "workflow instance mismatch" — a reporter lost the session right
6822
+ // after a successful save of ~40 nodes' work.
6823
+ //
6824
+ // Same shape as #932 (panel_new_workflow), and the same fix: re-derive
6825
+ // the fence from the panel's live active record. I closed that path and
6826
+ // missed this one; workflow_new and workflow_save_as both re-point the
6827
+ // active workflow, so both have to re-anchor.
6828
+ //
6829
+ // A plain in-place save is included deliberately. Its identity normally
6830
+ // FOLLOWS the workflow across the save (tmp: -> wf:), so the refresh
6831
+ // re-derives the same value and changes nothing — but "normally" is the
6832
+ // whole problem here, and re-reading costs one round trip against a
6833
+ // session that is otherwise silently unusable.
6834
+ //
6835
+ // NEVER fails the call: the file WAS written. Retracting a completed save
6836
+ // would be the worse lie, so a fence that could not be re-established is
6837
+ // DISCLOSED instead.
6838
+ const fenceRebind = await rebindWorkflowFence(ctx);
6839
+ let canMutateNow;
6840
+ let refusalCause;
6841
+ try {
6842
+ if (ctx.tabGraphMutationCapability) {
6843
+ const cap = ctx.tabGraphMutationCapability();
6844
+ canMutateNow = cap.known ? cap.canMutate : undefined;
6845
+ if (cap.known && !cap.canMutate)
6846
+ refusalCause = cap.because;
6847
+ }
6848
+ else {
6849
+ canMutateNow = ctx.tabCanMutateGraph?.();
6850
+ }
6851
+ }
6852
+ catch {
6853
+ canMutateNow = undefined;
6854
+ refusalCause = undefined;
6855
+ }
6856
+ const fence = describeFenceRebind(fenceRebind, canMutateNow, refusalCause);
6857
+ if (!fence || fence.binding === "bound")
6858
+ return res;
6859
+ return appendNote(res, `The workflow WAS saved.${fence.note}`);
6816
6860
  }),
6817
6861
  def("panel_list_workflows", "List the user's OPEN workflow tabs and which one is active (path, filename, modified, persisted). Use this to know what's open before switching/renaming/closing. Read-only.", {}, async (_args, ctx) => ctx.call({ cmd: "workflow_list" })),
6818
6862
  def("panel_get_workflow_target", "Read which workflow this agent is bound to edit. mode 'current' means graph tools follow whatever tab the user is viewing; mode 'pinned' means edits are bound to the pinned workflow (which was the active canvas at pin time) — if the user later switches to another tab, your next graph call FAILS LOUDLY rather than silently editing the wrong graph. Call this when unsure which workflow your panel_* edits will affect.", {}, async (_args, ctx) => {