Two fixes from code review:
1. Only load node_replacements.json from directory-based custom nodes.
Single-file .py nodes share a parent dir (custom_nodes/), so checking
there would incorrectly pick up a stray file.
2. Skip entries with missing or empty new_node_id instead of registering
a replacement pointing to nothing.
Custom node authors can now ship a `node_replacements.json` in their
repo root to define replacements declaratively. During node loading,
ComfyUI reads these files and registers entries via the existing
NodeReplaceManager — no Python registration code needed.
This enables two use cases:
1. Authors deprecate/rename nodes with a migration path for old workflows
2. Authors offer their nodes as drop-in replacements for other packs