comfyui-mcp 0.52.120 → 0.52.121

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.
package/README.md CHANGED
@@ -862,7 +862,8 @@ plugin/
862
862
  job-complete-notify.mjs # Job completion notification via temp files
863
863
  scripts/ # Background scripts
864
864
  monitor-progress.mjs # Real-time WebSocket progress monitor
865
- launch-server.mjs # MCP server launcher — prefers a global install over cold `npx` (#1447)
865
+ launch-server.mjs # MCP server launcher — global install if present, else npx with a
866
+ # cold-start handshake rescue so a first run cannot time out (#1447)
866
867
  ```
867
868
 
868
869
  ---
@@ -4946,6 +4946,17 @@ function parseVerifiedQueriedNodeDetail(payload) {
4946
4946
  *
4947
4947
  * So: prove STRING, or keep the normal setter path. */
4948
4948
  const DYNAMIC_COMBO_REFUSED_CHILD_TYPE = "STRING";
4949
+ /** Budget for the gate's own detail probe — the panel_query_graph `max_chars`
4950
+ * ceiling, not the default.
4951
+ *
4952
+ * This is a PINPOINT read: one id, `limit: 1`, one row. The survey cap exists to
4953
+ * keep a 200-node listing small and has nothing to protect here. Leaving it at the
4954
+ * default is what makes the gate miss the case it was written for: the panel caps a
4955
+ * detail row and, past a point, degrades it to an `{id, type, title}` stub — which
4956
+ * drops `inputs`, so the parse cannot prove the shape and the write falls open.
4957
+ * The node most likely to overflow that budget is the node already holding a long
4958
+ * prompt, i.e. exactly the #2299 report ("<any long prompt>"). */
4959
+ const DYNAMIC_COMBO_PROBE_MAX_CHARS = 60000;
4949
4960
  function dynamicComboSubWidgetRefusal(nodeType, parentInput, widget) {
4950
4961
  return fail(`panel_set_widget cannot set dynamic-combo sub-widget "${widget}" on ${nodeType}. ` +
4951
4962
  `The parent input "${parentInput}" is ${COMFY_DYNAMICCOMBO_V3} and "${widget}" is a ` +
@@ -4975,9 +4986,20 @@ async function refuseDynamicComboSubWidgetWrite(ctx, nodeId, widget) {
4975
4986
  ids: [nodeId],
4976
4987
  fields: "detail",
4977
4988
  limit: 1,
4989
+ max_chars: DYNAMIC_COMBO_PROBE_MAX_CHARS,
4978
4990
  });
4979
4991
  if (probe.isError)
4980
4992
  return null;
4993
+ // An unreadable or truncated probe is NOT evidence of a dynamic combo, so it
4994
+ // falls open — the same discipline as refuseAnimaRegionalPromptWrite. Failing
4995
+ // CLOSED here would refuse every dotted widget on every node whenever a probe
4996
+ // hiccups (rgthree `lora_N.*`, promoted subgraph paths, JSON composite fields),
4997
+ // which is a far larger blast radius than the residual it would close. The
4998
+ // residual is a slice of the PRE-EXISTING bug, not one this gate introduces:
4999
+ // without the gate every one of these writes is a false success. Shrinking that
5000
+ // slice is what the generous probe budget above is for. Closing it entirely
5001
+ // needs #2299's option 2 — an honest "written, not confirmed persistent" receipt
5002
+ // — which changes the success contract of the tool and is not this guard's call.
4981
5003
  const detail = parseVerifiedQueriedNodeDetail(parseToolResultJson(probe));
4982
5004
  const requestedId = canonicalQueriedNodeId(nodeId);
4983
5005
  if (!detail || !requestedId || detail.id !== requestedId)