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 &&
|
|
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
|
|
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
|
|
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.
|
|
4636
|
-
//
|
|
4637
|
-
//
|
|
4638
|
-
//
|
|
4639
|
-
managerBase:
|
|
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: {
|