comfyui-mcp 0.52.69 → 0.52.71

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.
@@ -23,10 +23,10 @@ import { execFileSync } from "node:child_process";
23
23
  import { closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
24
24
  import { createHash } from "node:crypto";
25
25
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
26
- import { isLocalMode } from "../config.js";
26
+ import { getComfyUIBaseUrl, isLocalMode } from "../config.js";
27
27
  import { logger } from "../utils/logger.js";
28
28
  import { parsePyproject } from "./node-authoring.js";
29
- import { installCustomNode, updateCustomNode, reinstallCustomNode, nonInteractiveGitEnv, } from "./node-management.js";
29
+ import { installCustomNode, updateCustomNode, reinstallCustomNode, nonInteractiveGitEnv, probeManagerQueueAvailability as probeManagerQueueAvailabilityOnHost, } from "./node-management.js";
30
30
  import { getSystemStats } from "../comfyui/client.js";
31
31
  import { describePanelPin, getPanelPinState, PANEL_PIN_ENV_VAR, } from "./panel-settings.js";
32
32
  import { withPanelMutationLock } from "./panel-pin-guard.js";
@@ -298,6 +298,7 @@ export function gitIgnoredPullConflicts(dir, upstreamRev) {
298
298
  }
299
299
  export const defaultDeps = {
300
300
  isLocalMode: () => isLocalMode(),
301
+ managerBase: () => getComfyUIBaseUrl(),
301
302
  // #766/#769 — LIVE-FIRST. The panel is not a file the user reads; it is a web
302
303
  // extension the RUNNING ComfyUI serves to the browser tab, so the only
303
304
  // custom_nodes that can matter is the one belonging to the server we are
@@ -1674,12 +1675,45 @@ async function readLiveQueueCounts(deps, base) {
1674
1675
  return undefined;
1675
1676
  }
1676
1677
  }
1678
+ /**
1679
+ * A missing queue count is normally an unreadable queue and must refuse. The
1680
+ * one safe exception is a probe that saw HTTP 404 from BOTH Manager dialects on
1681
+ * this same base: there is no Manager queue that could be writing the checkout.
1682
+ * Injected test deps without the probe stay fail-closed; production deps carry
1683
+ * the real probe through the default dependency set.
1684
+ */
1685
+ async function readLiveQueueObservation(deps, base) {
1686
+ const live = await readLiveQueueCounts(deps, base);
1687
+ if (live)
1688
+ return live;
1689
+ try {
1690
+ let availability;
1691
+ if (deps.probeManagerQueueAvailability) {
1692
+ availability = await deps.probeManagerQueueAvailability(base);
1693
+ }
1694
+ else if (isRealDeps(deps)) {
1695
+ availability = await probeManagerQueueAvailabilityOnHost(base);
1696
+ }
1697
+ else {
1698
+ return undefined;
1699
+ }
1700
+ return availability === "absent" ? { managerAbsent: true } : undefined;
1701
+ }
1702
+ catch {
1703
+ return undefined;
1704
+ }
1705
+ }
1677
1706
  /** True only when the probe SUCCEEDED and every live indicator reports clear. */
1678
1707
  function isLiveQueueIdle(c) {
1679
- return !!c && c.pending === 0 && c.inProgress === 0 && c.processing === false;
1708
+ return (!!c &&
1709
+ ("managerAbsent" in c ||
1710
+ (c.pending === 0 && c.inProgress === 0 && c.processing === false)));
1680
1711
  }
1681
1712
  /** Render a live probe for a message — including the "no answer at all" case. */
1682
1713
  function describeLiveQueue(c) {
1714
+ if (c && "managerAbsent" in c) {
1715
+ return `ComfyUI-Manager is confirmed absent (both queue/status endpoints returned HTTP 404)`;
1716
+ }
1683
1717
  return c
1684
1718
  ? `pending=${c.pending}, in_progress=${c.inProgress}, is_processing=${c.processing}`
1685
1719
  : `the live queue could not be read at all`;
@@ -2246,7 +2280,7 @@ async function updateViaGitCheckoutFallback(opts) {
2246
2280
  // Each pre-merge check refuses BEFORE any mutation, so its own failure is
2247
2281
  // free — the guard cannot itself damage the tree it is protecting.
2248
2282
  {
2249
- const live = await readLiveQueueCounts(deps, managerBase);
2283
+ const live = await readLiveQueueObservation(deps, managerBase);
2250
2284
  if (!isLiveQueueIdle(live)) {
2251
2285
  throw new PanelInstallError(`Panel update did NOT apply: ${managerReason}, and the git fallback is ` +
2252
2286
  `REFUSED: the queue counts that authorized it were a snapshot, so ` +
@@ -2441,7 +2475,7 @@ async function updateViaGitCheckoutFallback(opts) {
2441
2475
  `status / git log) and repair it before restarting ComfyUI.`);
2442
2476
  }
2443
2477
  {
2444
- const live = await readLiveQueueCounts(deps, managerBase);
2478
+ const live = await readLiveQueueObservation(deps, managerBase);
2445
2479
  if (!isLiveQueueIdle(live)) {
2446
2480
  throw new PanelInstallError(`Could not verify the panel update: the pinned fast-forward ALREADY RAN ` +
2447
2481
  `in ${dir}, but re-probing ComfyUI-Manager afterwards showed ` +
@@ -4471,6 +4505,17 @@ async function runPanelActionCore(action, depsIn, opts, carried) {
4471
4505
  // to propagate when the disk AGREES the pack is absent — then the message
4472
4506
  // is true and there is genuinely nothing to update.
4473
4507
  assertSameTarget("before the ComfyUI-Manager update");
4508
+ // updateCustomNode captures this same base before its first await, but a
4509
+ // Manager-absent failure has no NodeOpResult to carry it back. Capture it
4510
+ // here too so the absence probe cannot silently drift to a different
4511
+ // configured ComfyUI while this operation is in flight.
4512
+ let managerBaseForFailure;
4513
+ try {
4514
+ managerBaseForFailure = deps.managerBase?.();
4515
+ }
4516
+ catch {
4517
+ managerBaseForFailure = undefined;
4518
+ }
4474
4519
  let result;
4475
4520
  let managerFailure;
4476
4521
  try {
@@ -4632,11 +4677,11 @@ async function runPanelActionCore(action, depsIn, opts, carried) {
4632
4677
  // The Manager errored on its OWN pack list, not on its queue — and
4633
4678
  // an erroring Manager is no less likely to have a task writing to
4634
4679
  // this checkout, so the merge is bracketed here exactly as it is
4635
- // everywhere else. There is no observed base to pin to on this path
4636
- // (the call threw before returning one), so the re-probe resolves the
4637
- // configured Manager; the assertSameTarget checks around the mutation
4638
- // are what catch a retarget in the meantime.
4639
- managerBase: undefined,
4680
+ // everywhere else. The base was captured immediately before the
4681
+ // Manager call even though the thrown path has no NodeOpResult to
4682
+ // carry it back; the assertSameTarget checks around the mutation
4683
+ // still catch a local retarget in the meantime.
4684
+ managerBase: managerBaseForFailure,
4640
4685
  // Synthesize the shape the fallback reports around; there is no real
4641
4686
  // Manager result because the Manager call failed.
4642
4687
  result: {