comfyui-mcp 0.52.107 → 0.52.108

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.
@@ -38,6 +38,7 @@ import { sanitizePanelUpdateNodeResult } from "../services/manager-update-error.
38
38
  import { formatQueueStatusPartialNote, getManifestPartialLeftover, } from "../services/manifest-partial.js";
39
39
  import { searchPanelNodes } from "../services/manager-node-search.js";
40
40
  import { isPanelAnsweredError } from "../services/panel-answered.js";
41
+ import { readWorkflowListReadiness, workflowListReadinessOf, } from "../services/panel-workflow-readiness.js";
41
42
  import { isPreExecutorRefusal } from "../services/panel-refusal.js";
42
43
  import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
43
44
  import { parse as parseYaml } from "yaml";
@@ -2645,6 +2646,32 @@ function carryPanelAnsweredMark(err, res) {
2645
2646
  });
2646
2647
  return res;
2647
2648
  }
2649
+ /** #1785 — preserve the Panel's typed workflow-list readiness refusal across the
2650
+ * bridge-to-ToolResult conversion. The refusal is an explicit answer, not a
2651
+ * silent read failure, and its distinction controls whether a concurrent
2652
+ * re-hello may be treated as successful healing. */
2653
+ const WORKFLOW_LIST_READINESS_RESULT = Symbol("panel.workflowListReadinessResult");
2654
+ function carryWorkflowListReadinessMark(err, res) {
2655
+ if (res?.isError !== true)
2656
+ return res;
2657
+ const refusal = workflowListReadinessOf(err);
2658
+ if (!refusal)
2659
+ return res;
2660
+ Object.defineProperty(res, WORKFLOW_LIST_READINESS_RESULT, {
2661
+ value: refusal,
2662
+ enumerable: false,
2663
+ configurable: true,
2664
+ });
2665
+ return res;
2666
+ }
2667
+ function workflowListReadinessResultOf(res) {
2668
+ if (res?.isError !== true)
2669
+ return null;
2670
+ const refusal = res[WORKFLOW_LIST_READINESS_RESULT];
2671
+ return refusal && typeof refusal === "object"
2672
+ ? readWorkflowListReadiness(refusal)
2673
+ : null;
2674
+ }
2648
2675
  /** True only for a ToolResult `ctx.call` produced from an error the BRIDGE minted
2649
2676
  * out of a received reply. A timeout, a routing refusal or a dead socket can never
2650
2677
  * carry this, whatever their text says — and neither can an error from a panel too
@@ -7391,6 +7418,17 @@ async function rebindWorkflowFence(ctx, opts) {
7391
7418
  const res = await ctx.call({ cmd: "workflow_list" }, 6000);
7392
7419
  syncFenceToCurrentTab();
7393
7420
  if (res?.isError) {
7421
+ const readiness = workflowListReadinessResultOf(res);
7422
+ if (readiness) {
7423
+ return {
7424
+ done: {
7425
+ status: "readiness_refused",
7426
+ before,
7427
+ detail: toolResultText(res),
7428
+ readiness,
7429
+ },
7430
+ };
7431
+ }
7394
7432
  return { done: await unreadableOrHealed(ctx, before, toolResultText(res)) };
7395
7433
  }
7396
7434
  parsed = parseToolResultJson(res);
@@ -7885,6 +7923,17 @@ panelGapNote = "") {
7885
7923
  `keeps throwing: ${RELOAD_TAB_REMEDY}` +
7886
7924
  `\n\nUNDERLYING CAUSE: ${r.detail}`,
7887
7925
  };
7926
+ case "readiness_refused":
7927
+ return {
7928
+ binding: "not_recovered",
7929
+ note: ` The panel ANSWERED the workflow_list probe with its typed reconnect-readiness ` +
7930
+ `refusal (${r.readiness.code}): the probe was not run, changed no workflow target, ` +
7931
+ `and the live workflow identity was not ready within the panel's bounded window. ` +
7932
+ `A concurrent re-hello or fence change is not a successful workflow_list proof, so ` +
7933
+ `this call did NOT restore graph binding. Retry after the panel reports readiness, or ` +
7934
+ `use panel_open_workflow(<path>) to explicitly re-establish the tab.` +
7935
+ `\n\nUNDERLYING CAUSE (quoted verbatim): ${r.detail}`,
7936
+ };
7888
7937
  case "unreadable":
7889
7938
  // ALWAYS not_recovered, with or without a prior fence (codex gate). The read
7890
7939
  // we just attempted FAILED, so nothing about this session was observed —
@@ -10838,7 +10887,7 @@ export function makePanelToolCtx(bridge, tabId, workflowTargets, onRunTicketOpen
10838
10887
  const res = await callOnce(cmd, timeoutMs, onDispatchedRid, (err) => {
10839
10888
  failure = err;
10840
10889
  });
10841
- return carryMidCommandDisconnectMark(failure, carryPanelAnsweredMark(failure, res));
10890
+ return carryWorkflowListReadinessMark(failure, carryMidCommandDisconnectMark(failure, carryPanelAnsweredMark(failure, res)));
10842
10891
  };
10843
10892
  // Human-in-the-loop confirmation for a DESTRUCTIVE op: render a yes/no card in
10844
10893
  // the panel and block on the user's pick. Returns false on decline, timeout, or