16f4e93a3a
A ComfyUI companion that suggests core / available equivalents for custom nodes and replaces them in a workflow. - Backend (utfcn_core.py, __init__.py): read-only /utfcn/scan analysis that ranks equivalents in three tiers (curated → exact-signature → partial heuristic) from the live node registry. - Frontend (web/utfcn.js): on-add mode (Off / Suggest / Force auto-replace), bulk "Replace with core / available…" command + Extensions menu with a preview-then-confirm dialog, and a right-click single-node replace. The swap engine only rewires losslessly. - mappings.json: 7 hand-verified curated rules mined from installed packs (essentials, KJNodes, WAS); user_mappings.json for user overrides. - Docs + branding: README, icon and social banner (SVG + PNG), GPL-3.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
2.9 KiB
JSON
85 lines
2.9 KiB
JSON
{
|
|
"_readme": [
|
|
"UTFCN curated equivalence rules (the 'verified' tier — safe to auto-apply, incl. Force mode).",
|
|
"",
|
|
"You rarely NEED rules: UTFCN already auto-detects any custom node whose input",
|
|
"name->type map and ordered output types are IDENTICAL to a core node ('exact'",
|
|
"tier), and surfaces looser 'partial' matches as suggestions. Add a rule here",
|
|
"only to (a) bless a partial match as safe to auto-apply, or (b) fix up slots",
|
|
"whose NAMES differ so the swap stays lossless.",
|
|
"",
|
|
"Schema — 'rules' maps a source node type to ONE target or an ordered list of",
|
|
"targets (first installed one wins, so put the core node first):",
|
|
"",
|
|
" \"rules\": {",
|
|
" \"SourceNodeType\": [",
|
|
" {",
|
|
" \"to\": \"TargetNodeType\",",
|
|
" \"note\": \"why this is equivalent (shown in the preview)\",",
|
|
" \"inputs\": { \"srcInputName\": \"dstInputName\" },",
|
|
" \"widgets\": { \"srcWidgetName\": \"dstWidgetName\" },",
|
|
" \"outputs\": { \"srcOutputName\": \"dstOutputName\" }",
|
|
" }",
|
|
" ]",
|
|
" }",
|
|
"",
|
|
"Any input/widget/output slot you don't list is matched by identical name, then",
|
|
"by type+order. Don't edit this file for your own rules — put those in",
|
|
"user_mappings.json (same schema); it is merged on top and survives updates.",
|
|
"",
|
|
"The rules below were mined from installed packs (ComfyUI_essentials, KJNodes,",
|
|
"was-node-suite) and verified lossless against the real core signatures. Rules",
|
|
"for nodes you don't have installed are simply ignored."
|
|
],
|
|
|
|
"rules": {
|
|
"GetImageSize+": [
|
|
{
|
|
"to": "GetImageSize",
|
|
"note": "essentials Get Image Size == core Get Image Size; 'count' is core's 'batch_size'.",
|
|
"outputs": { "count": "batch_size" }
|
|
}
|
|
],
|
|
"MaskPreview+": [
|
|
{
|
|
"to": "MaskPreview",
|
|
"note": "essentials mask preview == core MaskPreview (same single-MASK preview node)."
|
|
}
|
|
],
|
|
|
|
"BOOLConstant": [
|
|
{
|
|
"to": "PrimitiveBoolean",
|
|
"note": "KJ boolean constant == core Primitive Boolean (single BOOLEAN passthrough)."
|
|
}
|
|
],
|
|
"INTConstant": [
|
|
{
|
|
"to": "PrimitiveInt",
|
|
"note": "KJ int constant == core Primitive Int. Core adds a (fixed) control_after_generate; value is identical."
|
|
}
|
|
],
|
|
"FloatConstant": [
|
|
{
|
|
"to": "PrimitiveFloat",
|
|
"note": "KJ float constant == core Primitive Float. KJ rounds to 6 decimals; negligible for a UI constant."
|
|
}
|
|
],
|
|
|
|
"Convert Masks to Images": [
|
|
{
|
|
"to": "MaskToImage",
|
|
"note": "WAS mask->image == core MaskToImage (broadcast MASK to a 3-channel IMAGE).",
|
|
"inputs": { "masks": "mask" }
|
|
}
|
|
],
|
|
"Mask Invert": [
|
|
{
|
|
"to": "InvertMask",
|
|
"note": "WAS mask invert == core InvertMask (1.0 - mask).",
|
|
"inputs": { "masks": "mask" }
|
|
}
|
|
]
|
|
}
|
|
}
|