Initial commit: UTFCN — Use The (F***ing) Core Nodes
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>
This commit is contained in:
+62
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
UTFCN — Use The F***ing Core Nodes.
|
||||
|
||||
A ComfyUI companion that nudges workflows back toward core nodes:
|
||||
|
||||
1. Suggests a core (or otherwise-available) equivalent when you add a custom
|
||||
node that re-implements something ComfyUI already ships.
|
||||
2. Adds a "Replace custom nodes with core / available…" command + menu entry
|
||||
that scans the open graph and, after a preview, swaps in equivalents.
|
||||
3. Adds a right-click "Replace with core / available" item on individual nodes.
|
||||
|
||||
All of that is frontend behaviour (see web/utfcn.js). This backend only serves
|
||||
the *analysis*: it has the live node registry, so it computes — accurately, from
|
||||
real INPUT_TYPES / RETURN_TYPES — which custom nodes have safe equivalents.
|
||||
|
||||
GET /utfcn/scan[?refresh=1] -> { sources, candidates, stats }
|
||||
|
||||
Curated overrides live in mappings.json (shipped) and user_mappings.json (yours).
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from aiohttp import web
|
||||
from server import PromptServer
|
||||
|
||||
from . import utfcn_core
|
||||
|
||||
VERSION = "1.0.0"
|
||||
_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# The scan walks the whole registry, so we cache it and only rebuild on demand.
|
||||
_INDEX_CACHE = None
|
||||
|
||||
|
||||
def _get_index(refresh=False):
|
||||
global _INDEX_CACHE
|
||||
if refresh or _INDEX_CACHE is None:
|
||||
rules = utfcn_core.load_rules(_DIR)
|
||||
_INDEX_CACHE = utfcn_core.build_index(rules)
|
||||
return _INDEX_CACHE
|
||||
|
||||
|
||||
routes = PromptServer.instance.routes
|
||||
|
||||
|
||||
@routes.get("/utfcn/scan")
|
||||
async def utfcn_scan(request):
|
||||
refresh = request.query.get("refresh") in ("1", "true", "yes")
|
||||
try:
|
||||
return web.json_response(_get_index(refresh))
|
||||
except Exception as e:
|
||||
# never let a scan failure break the editor — the frontend degrades gracefully
|
||||
print(f"[UTFCN] scan failed: {e}")
|
||||
return web.json_response({"sources": {}, "candidates": {}, "stats": {}, "error": str(e)}, status=500)
|
||||
|
||||
|
||||
WEB_DIRECTORY = "./web"
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
|
||||
|
||||
print(f"[UTFCN] loaded (v{VERSION}) — Use The F***ing Core Nodes")
|
||||
Reference in New Issue
Block a user