comfyui-mcp 0.52.172 → 0.52.174

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.
@@ -2555,6 +2555,32 @@ function proxyTargetBindsPanel(ctx, target) {
2555
2555
  ctx.bridge?.tabIsLocal?.(ctx.tabId) === true &&
2556
2556
  sameHttpBase(ctx.bridge?.tabServerOrigin?.(ctx.tabId), target.proxyBase));
2557
2557
  }
2558
+ /**
2559
+ * A live local Panel can safely own a Manager reboot even when the MCP process
2560
+ * started before the Panel selected a different loopback port (for example,
2561
+ * ComfyUI Desktop's dynamic port). This is a DISPATCH-ONLY binding:
2562
+ *
2563
+ * - the target must be a concrete loopback URL;
2564
+ * - the socket must have arrived on the server-trusted local listener; and
2565
+ * - the server-observed WebSocket Origin must identify the current target.
2566
+ *
2567
+ * The result must never be used as the MCP health-probe or headless-restart
2568
+ * target. Those paths still require the immutable boot target from
2569
+ * captureRebootHealthBase/configuredBootRestartBase. The Panel's own
2570
+ * authenticated relative Manager request is the only reboot authority this
2571
+ * exception grants (#2068).
2572
+ */
2573
+ function currentPanelRestartTarget(ctx) {
2574
+ if (ctx.bridge?.tabIsLocal?.(ctx.tabId) !== true)
2575
+ return null;
2576
+ const target = getComfyUIBaseUrl().replace(/\/+$/, "");
2577
+ if (!target || !isLoopbackOrigin(target))
2578
+ return null;
2579
+ const observedOrigin = ctx.bridge?.tabServerOrigin?.(ctx.tabId);
2580
+ if (!sameHttpBase(observedOrigin, target))
2581
+ return null;
2582
+ return target;
2583
+ }
2558
2584
  /** Test injection for the #742 decline-probe recheck window, so tests don't
2559
2585
  * wait the real ~6s. null → the DECLINE_PROBE_* constants. */
2560
2586
  let declineProbeTimingOverride = null;
@@ -21622,6 +21648,11 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
21622
21648
  // awaits. The proxy is never treated as a ComfyUI process; it only lets
21623
21649
  // the tab-scoped Manager request be observed against the immutable backend.
21624
21650
  let proxyRestartTarget;
21651
+ // #2068: a Panel may front a concrete local Desktop port selected after
21652
+ // this MCP process started. This binding authorizes only the Panel's
21653
+ // authenticated relative Manager dispatch; it is never a health or
21654
+ // headless-restart target.
21655
+ let panelRestartTarget;
21625
21656
  // #1819: resolve instance identity BEFORE the confirmation card. Asking the
21626
21657
  // user to confirm a restart, then refusing because we cannot tell which
21627
21658
  // ComfyUI this tab fronts, is two contradictory outcomes (timeout vs refuse)
@@ -21640,10 +21671,13 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
21640
21671
  if (proxyTargetBindsPanel(ctx, candidate)) {
21641
21672
  proxyRestartTarget = candidate;
21642
21673
  }
21674
+ if (proxyRestartTarget == null) {
21675
+ panelRestartTarget = currentPanelRestartTarget(ctx) ?? undefined;
21676
+ }
21643
21677
  const tabStillHere = typeof ctx.bridge?.canReach === "function"
21644
21678
  ? ctx.bridge.canReach(ctx.tabId) === true
21645
21679
  : true;
21646
- if (tabStillHere && proxyRestartTarget == null) {
21680
+ if (tabStillHere && proxyRestartTarget == null && panelRestartTarget == null) {
21647
21681
  return restartRefusedPreservingBinding(ctx, unboundLocalRestartRefusalNote(ctx, identityHealthBase, identityBinding.blocker));
21648
21682
  }
21649
21683
  // Tab is gone: confirm will be unreachable and #1671 crash-recovery
@@ -22364,9 +22398,17 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
22364
22398
  ? refreshedProxy
22365
22399
  : undefined;
22366
22400
  }
22401
+ if (proxyRestartTarget == null && panelRestartTarget != null) {
22402
+ const refreshedPanelTarget = currentPanelRestartTarget(ctx);
22403
+ panelRestartTarget =
22404
+ refreshedPanelTarget != null && sameHttpBase(refreshedPanelTarget, panelRestartTarget)
22405
+ ? refreshedPanelTarget
22406
+ : undefined;
22407
+ }
22367
22408
  const preflightBinding = resolveRebootHealthBinding(ctx);
22368
- const preflightHealthBase = proxyRestartTarget?.backendBase ?? preflightBinding.base;
22409
+ const preflightHealthBase = proxyRestartTarget?.backendBase ?? panelRestartTarget ?? preflightBinding.base;
22369
22410
  const preflightBound = proxyRestartTarget != null ||
22411
+ panelRestartTarget != null ||
22370
22412
  (preflightHealthBase != null &&
22371
22413
  sameHttpBase(getComfyUIBaseUrl(), preflightHealthBase));
22372
22414
  // #848: what the instance was OBSERVED running with, taken from the preflight
@@ -22430,9 +22472,13 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
22430
22472
  }
22431
22473
  ctx.ensureReachable?.();
22432
22474
  const postPreflightHealthBase = captureRebootHealthBase(ctx);
22475
+ const postPreflightPanelTarget = panelRestartTarget != null ? currentPanelRestartTarget(ctx) : null;
22433
22476
  const tabFrontsSameInstance = proxyRestartTarget != null ||
22434
- (postPreflightHealthBase != null &&
22435
- sameHttpBase(preflightHealthBase, postPreflightHealthBase));
22477
+ (panelRestartTarget != null
22478
+ ? postPreflightPanelTarget != null &&
22479
+ sameHttpBase(preflightHealthBase, postPreflightPanelTarget)
22480
+ : postPreflightHealthBase != null &&
22481
+ sameHttpBase(preflightHealthBase, postPreflightHealthBase));
22436
22482
  const configStable = proxyRestartTarget != null
22437
22483
  ? getComfyuiTargetGeneration() === proxyRestartTarget.generation
22438
22484
  : getComfyuiTargetGeneration() === preflightTargetGeneration;
@@ -22523,6 +22569,13 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
22523
22569
  preflightArgvGeneration = proxyRestartTarget.generation;
22524
22570
  }
22525
22571
  }
22572
+ if (proxyRestartTarget == null && panelRestartTarget != null) {
22573
+ const dispatchPanelTarget = currentPanelRestartTarget(ctx);
22574
+ panelRestartTarget =
22575
+ dispatchPanelTarget != null && sameHttpBase(dispatchPanelTarget, panelRestartTarget)
22576
+ ? dispatchPanelTarget
22577
+ : undefined;
22578
+ }
22526
22579
  const healthBase = proxyRestartTarget?.backendBase ?? captureRebootHealthBase(ctx);
22527
22580
  // THE BINDING RULE APPLIES AT THE DISPATCH POINT, NOT ONLY BEFORE THE AWAIT.
22528
22581
  //
@@ -22537,7 +22590,9 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
22537
22590
  // Same rule, same exclusions: only a LOCAL target we cannot tie to the
22538
22591
  // instance this server accounts for is refused.
22539
22592
  const dispatchBound = proxyRestartTarget != null ||
22540
- (healthBase != null && sameHttpBase(getComfyUIBaseUrl(), healthBase));
22593
+ (healthBase != null && sameHttpBase(getComfyUIBaseUrl(), healthBase)) ||
22594
+ (panelRestartTarget != null &&
22595
+ sameHttpBase(getComfyUIBaseUrl(), panelRestartTarget));
22541
22596
  if (!dispatchBound && !isRemoteMode() && !isCloudMode()) {
22542
22597
  return restartRefusedPreservingBinding(ctx, "Refusing to restart ComfyUI: the panel connection changed while the restart " +
22543
22598
  "was being prepared, and I can no longer confirm which ComfyUI this tab " +