Support uninstalled / missing nodes

Previously the index was built only from the live registry, so a custom node
that wasn't installed (a red "missing" node in a downloaded workflow) was
invisible — the main point of the tool. Now:

- Backend: utfcn_core split into build_context / build_index / match. build_index
  also emits curated candidates for uninstalled source types (curated-only), and
  a new POST /utfcn/match matches missing nodes by their serialized signature
  against installed core/other-pack nodes.
- Frontend: nodeType() reads a missing placeholder's last_serialization.type;
  matchMissing() feeds serialized slots to /utfcn/match and merges the results;
  the right-click item moved to a canvas-level getNodeMenuOptions patch so it
  reaches missing placeholders too. Bulk dialog labels them "not installed".

Replace a missing node with core without installing its pack. Links are rewired
losslessly; widget values can't be carried for a node whose def is absent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 10:43:13 +02:00
parent 16f4e93a3a
commit cc728eb50b
4 changed files with 202 additions and 70 deletions
+15
View File
@@ -23,6 +23,17 @@ It does three things:
Nothing is ever swapped without your say-so, and the engine only rewires slots
it can move *losslessly* — anything it can't map is reported, not guessed.
### Works on uninstalled ("missing") nodes
The headline case: open a downloaded workflow full of red **missing** nodes and
replace them with core equivalents **without installing the packs at all**.
ComfyUI keeps each missing node as a placeholder that remembers its original
type and wiring, so UTFCN can still match and swap it — via a curated rule (by
name) or by matching the node's *serialized* signature against your core nodes.
Both "Replace…" and the right-click item work on them; the bulk dialog labels
them `⚠ not installed`. (Widget values aren't carried for a node whose
definition you don't have — links are.)
## How it decides what's equivalent
The backend reads the live node registry (real `INPUT_TYPES` / `RETURN_TYPES`
@@ -37,6 +48,10 @@ and each node's source module) and ranks candidates in three tiers:
"Available" means core is preferred, and if there's no core match it will offer
an equivalent from a **different installed pack** as a fallback.
For an **uninstalled** node only *curated* (by name) and *partial* (by its
serialized link signature) can apply — the exact tier needs the widget-level
signature, which a node you haven't installed can't provide.
## Shipped equivalences
`mappings.json` ships a small, hand-verified set (each checked lossless against