comfyui-mcp 0.50.101 → 0.50.103

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.
@@ -2509,6 +2509,67 @@ export function readOpenActiveAgainstTarget(active, path, activeConfirmed) {
2509
2509
  * all. Requiring corroboration there is what kept the reporter's own case
2510
2510
  * unexamined.
2511
2511
  */
2512
+ /**
2513
+ * #1337 — CLEAR THE FENCE ON THE VERDICT THAT PROVED IDENTITY.
2514
+ *
2515
+ * A reporter's session lost the canvas permanently: every graph call refused with
2516
+ * `workflow instance mismatch`, and the one fence-EXEMPT recovery could not clear it.
2517
+ *
2518
+ * `workflow_open` re-derives the fence only on its success branch. The verdict
2519
+ *
2520
+ * "workflow_open RAN and the canvas IS bound to X — that much was proven — but the
2521
+ * graph on it does not match the state that was loaded … You are NOT on the wrong
2522
+ * workflow: X IS the active one."
2523
+ *
2524
+ * is delivered as an ERROR, so control never reaches the re-derivation. That mismatches
2525
+ * two different levels: the verdict asserts IDENTITY was proven, and what it withholds
2526
+ * is CONTENT (frontend normalisation vs a partial load). Applying content-level
2527
+ * uncertainty to an identity-level fence is what leaves the session with no in-band
2528
+ * recovery — the only remaining move is a browser reload, which destroys unsaved work.
2529
+ *
2530
+ * MEASURED, because the comment that justified the old behaviour asserts otherwise:
2531
+ * • the panel really does publish NO workflow_uuid on this reply (its own
2532
+ * FENCE_NOT_REFRESHED text), so there is nothing to adopt FROM THE REPLY — true;
2533
+ * • but `workflow_list` IS fence-exempt (commandIsCanvasTargetless in the panel's
2534
+ * workflow-chat-identity.js), and the panel's own recovery text names
2535
+ * panel_list_workflows as "exempt from the fence" and says it "republishes the
2536
+ * active identity". So the fence CAN be re-derived here; nothing tried.
2537
+ *
2538
+ * This runs that exempt re-derivation and reports what it achieved. The open still
2539
+ * FAILS — the content warning is preserved verbatim, because "re-read before editing"
2540
+ * is still the right instruction — and nothing is adopted on the UNPROVEN verdict,
2541
+ * where identity itself is in doubt.
2542
+ */
2543
+ async function clearFenceOnIdentityProvenOpen(ctx, res) {
2544
+ const text = toolResultText(res);
2545
+ // ONLY the class that states identity was proven. The UNPROVEN verdict ("could not
2546
+ // prove that the active canvas was rebound") must keep failing closed: re-deriving a
2547
+ // fence onto a canvas we cannot identify is how an edit lands on the wrong graph.
2548
+ if (!/the canvas IS bound to/i.test(text))
2549
+ return res;
2550
+ let note;
2551
+ try {
2552
+ const rebind = await rebindWorkflowFence(ctx);
2553
+ note =
2554
+ rebind.status === "refreshed" || rebind.status === "already_current"
2555
+ ? `\n\nFENCE: CLEARED. This reply published no workflow_uuid, so the fence was re-derived ` +
2556
+ `from the panel's own fence-EXEMPT workflow_list read instead — the active identity is ` +
2557
+ `${rebind.uuid}, and graph commands from this session are stamped with it again. You do ` +
2558
+ `NOT need to reload the browser tab, and no unsaved canvas work is at risk. The content ` +
2559
+ `warning above still stands: re-read the graph before editing.`
2560
+ : `\n\nFENCE: NOT cleared (${rebind.status}). The re-derivation was attempted — the panel ` +
2561
+ `publishes no workflow_uuid on this verdict, so the fence-exempt workflow_list read is ` +
2562
+ `the only way to refresh it — and it did not establish an identity. Graph commands stay ` +
2563
+ `refused. Try panel_list_workflows directly; if that also fails, the panel tab is the ` +
2564
+ `thing to fix.`;
2565
+ }
2566
+ catch (err) {
2567
+ note =
2568
+ `\n\nFENCE: NOT cleared — the re-derivation threw, so the fence state is UNKNOWN and graph ` +
2569
+ `commands may still be refused. (${err instanceof Error ? err.message : String(err)})`;
2570
+ }
2571
+ return appendToolResultText(res, note);
2572
+ }
2512
2573
  async function observeActiveAfterOpen(ctx, requestedPath) {
2513
2574
  let list = null;
2514
2575
  try {
@@ -3643,7 +3704,7 @@ async function openWorkflowWithVerify(path, ctx) {
3643
3704
  return res;
3644
3705
  const drift = await observeActiveAfterOpen(ctx, path);
3645
3706
  if (!drift)
3646
- return res;
3707
+ return await clearFenceOnIdentityProvenOpen(ctx, res);
3647
3708
  return fail(`${toolResultText(res)}\n\nAND — checked after that failure — ${drift.activeLabel} is the ` +
3648
3709
  `ACTIVE workflow now, not ${path}. Whatever that message says about ${path} being active, ` +
3649
3710
  `it is not: the canvas you would read or write is ${drift.activeLabel}. Do NOT save, ` +