Compare commits

...

21 Commits

Author SHA1 Message Date
Bellevue
71822e3ca6
Merge 43d5c1188b into 037987b917 2026-07-07 03:35:01 +09:00
Dr.Lt.Data
037987b917 fix(custom-node-list): §4.7-C-bis #2958 younestft/Comfy_EverAnimate — manual register (CONFLICTING)
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
2026-07-06 19:48:37 +09:00
Dr.Lt.Data
8076c200fc fix(custom-node-list): §4.7-C-bis-variant #3017 Moon-NE/MoonNe_Nodes — manual register (DESTRUCTIVE + CONFLICTING + non-standard schema) 2026-07-06 19:38:11 +09:00
Dr.Lt.Data
69bad851e0 fix(custom-node-list): §4.7-C-bis #2939 TechnoWarrior2 2-pack — manual register (CONFLICTING) + node_db/new sync
- ComfyUI Image Picker / ComfyUI Live Preview
- New author, appended at end of git-clone block
- live-preview code-scan verified CLEAN (no security surface, English UI, WEB_DIRECTORY only)
- Prepend both to node_db/new (newest-first)
2026-07-06 19:27:05 +09:00
Dr.Lt.Data
47df9c702c fix(custom-node-list): §4.2 MERGE_RELOCATE #2965 shootthesound 4-pack — root relocate + node_db/new sync
- Lighthouse / CleanFreak / Finding LoRA / Image of the Day
- Relocate 4 entries from array head to adjacent to existing shootthesound block
- Prepend 4 entries to node_db/new (newest-first)
2026-07-06 19:25:33 +09:00
Dr.Lt.Data
d6df033a21
Merge pull request #2965 from shootthesound/add-shootthesound-nodes-batch
Add Lighthouse, CleanFreak, Finding LoRA, and Image of the Day
2026-07-06 19:24:00 +09:00
Dr.Lt.Data
d72007d1a8 update DB 2026-07-06 19:22:15 +09:00
craftingmod
43d5c1188b Merge branch 'main' into fix-cache-dir 2026-07-04 11:45:13 +09:00
craftingmod
f0919a4bbe Merge branch 'main' into fix-cache-dir 2026-07-01 02:17:47 +09:00
craftingmod
4da6b807f6 fix(cnr): wrong fallback in 'local' mode 2026-06-30 08:55:05 +09:00
craftingmod
b59eb64c22 perf(cnr): add cache 30-days expiration logic (again) 2026-06-30 08:46:22 +09:00
craftingmod
5513395ace fix(cnr): logical error while sync_mode = 'cache'
* Now correctly refresh cache if cache is created
 * Seperate cache update / cache created time
 * revert 7-day expiration logic
2026-06-30 08:24:42 +09:00
craftingmod
f3c003dd20 fix(cnr): propagate asyncio.TimeoutError in _get_cnr_data for correct bubble up 2026-06-30 07:28:05 +09:00
craftingmod
5427efda58 perf(cnr): add cache 7-day expiration logic
* for github star, download counts.
2026-06-30 07:19:49 +09:00
craftingmod
9a827e409a fix(cnr): eliminate client clock fallback dependency on timestamp sync 2026-06-30 06:47:41 +09:00
craftingmod
ec2023a5a3 refactor(cnr): fix cache-miss return type consistency to empty list 2026-06-30 06:38:06 +09:00
craftingmod
9a0b2c40f1 perf(cnr): optimize event loop blocking with asyncio.sleep and fix parameter encoding in fetch_all 2026-06-30 06:29:17 +09:00
craftingmod
62fd58524f Merge branch 'main' into fix-cache-dir 2026-06-30 06:14:09 +09:00
craftingmod
fb822c6f24 Perf(cnr): optimize ComfyRegistry loading using server-time incremental caching. 2026-06-30 06:07:52 +09:00
craftingmod
edcfb6a35a Chore: Replace print to logging in cnr_utils.py 2026-06-30 04:47:56 +09:00
shootthesound
396308854d Add Lighthouse, CleanFreak, Finding LoRA, Image of the Day to custom-node-list 2026-06-07 19:29:39 +01:00
10 changed files with 2009 additions and 1677 deletions

View File

@ -40995,6 +40995,46 @@
"install_type": "git-clone",
"description": "Click-to-refine sampler. Generate, then click or paint regions to refine them in place. First-class support for FLUX 2 Klein 9B and Qwen-Image-Edit (Smart Inpaint / Smart Guided Inpaint / Xtra-Fine), works with any sampler-compatible model for Refine + Area Prompt. Optional SAM 3 Detect for text-prompted segmentation, and a companion Overrides node for custom samplers (power-sigma, Flux 2 scheduler, NAG)."
},
{
"author": "shootthesound",
"title": "Lighthouse",
"reference": "https://github.com/shootthesound/comfyui-lighthouse",
"files": [
"https://github.com/shootthesound/comfyui-lighthouse"
],
"install_type": "git-clone",
"description": "A non-destructive overlay that lights up every node by graph distance from the one you click. Diagnostic for big workflows, educational for understanding workflows others built, and surgical when you need to focus on one neighbourhood at a time."
},
{
"author": "shootthesound",
"title": "CleanFreak",
"reference": "https://github.com/shootthesound/comfyui-CleanFreak",
"files": [
"https://github.com/shootthesound/comfyui-CleanFreak"
],
"install_type": "git-clone",
"description": "One-click tidy-by-role for any ComfyUI workflow — loaders, encoders, samplers, decoders, and outputs each sorted into their own column with coloured group cards and connections preserved. 1200+ node classes pre-classified out of the box."
},
{
"author": "shootthesound",
"title": "Finding LoRA",
"reference": "https://github.com/shootthesound/comfyui-lora-FindingLora",
"files": [
"https://github.com/shootthesound/comfyui-lora-FindingLora"
],
"install_type": "git-clone",
"description": "A LoRA loader with bookmarks, trigger-word storage and click-to-copy, fuzzy search, and a one-click button to drop another loader inline and wire it into the model chain automatically."
},
{
"author": "shootthesound",
"title": "Image of the Day",
"reference": "https://github.com/shootthesound/comfyui-image-of-the-day",
"files": [
"https://github.com/shootthesound/comfyui-image-of-the-day"
],
"install_type": "git-clone",
"description": "Fetch a fresh image straight into your workflow from 8 daily/random sources. Useful for prompt testing, style references, daily-image automations, or just kicking off a workflow with something interesting."
},
{
"author": "HackAfterDark",
"title": "AfterDark Film AR Selector",
@ -54093,6 +54133,46 @@
],
"install_type": "git-clone",
"description": "A soft, Anima-friendly Perturbed Attention Guidance node for ComfyUI."
},
{
"author": "TechnoWarrior2",
"title": "ComfyUI Image Picker",
"reference": "https://github.com/TechnoWarrior2/comfyui-image-picker",
"files": [
"https://github.com/TechnoWarrior2/comfyui-image-picker"
],
"install_type": "git-clone",
"description": "Pauses your workflow and opens a popup window to manually pick which generated images pass through to the rest of the graph."
},
{
"author": "TechnoWarrior2",
"title": "ComfyUI Live Preview",
"reference": "https://github.com/TechnoWarrior2/comfyui-live-preview",
"files": [
"https://github.com/TechnoWarrior2/comfyui-live-preview"
],
"install_type": "git-clone",
"description": "Displays a large draggable floating window with live denoising step previews as your image generates, similar to A1111 and Forge."
},
{
"author": "Moon-NE",
"title": "MoonNe_Nodes",
"reference": "https://github.com/Moon-NE/MoonNe_Nodes",
"files": [
"https://github.com/Moon-NE/MoonNe_Nodes"
],
"install_type": "git-clone",
"description": "Custom nodes for text operations, including concatenation, horizontal-to-vertical conversion, and batch processing."
},
{
"author": "younestft",
"title": "Comfy EverAnimate",
"reference": "https://github.com/younestft/Comfy_EverAnimate",
"files": [
"https://github.com/younestft/Comfy_EverAnimate"
],
"install_type": "git-clone",
"description": "Native ComfyUI nodes for EverAnimate-style chunked WanAnimate workflows, including master/chunk settings, chunk calculation, image carry-over, and boundary color correction."
}
]
}

View File

@ -3876,6 +3876,7 @@
"Beaufort",
"Bifid",
"Binary2String",
"BitsCounter",
"BitwiseAND",
"BitwiseLS",
"BitwiseNOT",
@ -3897,6 +3898,11 @@
"ConcatKDFHash_Derive",
"ConcatKDFHash_Verify",
"ConstantTimeCompare",
"DERPrivateKey",
"DERPublicKey",
"ECPrivateKey",
"ECPublicKey",
"ECSign",
"EdDSAPrivateKeyFormat",
"EdDSAPublicKeyFormat",
"EdDSASignature",
@ -3921,6 +3927,8 @@
"Nihilist",
"PBKDF2HMAC_Derive",
"PBKDF2HMAC_Verify",
"PEMPrivateKey",
"PEMPublicKey",
"Padding",
"Playfair",
"Polybius",
@ -3956,6 +3964,7 @@
"X963KDF_Derive",
"X963KDF_Verify",
"XExchange",
"XOFHash",
"XPrivateKeyFormat",
"XPublicKeyFormat",
"Zigzag"
@ -26816,6 +26825,7 @@
"XB_AutoBubbleTextRenderer",
"XB_BatchFolderLoader",
"XB_BerniniConditioning",
"XB_BerniniPromptRouter",
"XB_CLIPNameBroadcaster",
"XB_CanvasLabel",
"XB_CheckpointBlockSwap",
@ -26827,6 +26837,7 @@
"XB_HumanSegModelLoader",
"XB_HumanSegmentation",
"XB_ImageParamsMaster",
"XB_K2StyleRouter",
"XB_KSampler",
"XB_KSamplerAdvanced",
"XB_MSR",

File diff suppressed because it is too large Load Diff

View File

@ -2,10 +2,12 @@ import asyncio
import json
import os
import platform
import time
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from typing import List
from urllib.parse import urlencode
import logging
import manager_core
import manager_util
import requests
@ -17,108 +19,242 @@ base_url = "https://api.comfy.org"
lock = asyncio.Lock()
is_cache_loading = False
force_refresh_days = 30
async def get_cnr_data(cache_mode=True, dont_wait=True):
async def get_cnr_data(sync_mode=None, dont_wait=True, **kwargs):
# For backwards compatibility with keyword argument cache_mode
if sync_mode is None:
sync_mode = kwargs.get('cache_mode', 'cache')
try:
return await _get_cnr_data(cache_mode, dont_wait)
return await _get_cnr_data(sync_mode, dont_wait)
except asyncio.TimeoutError:
print("A timeout occurred during the fetch process from ComfyRegistry.")
return await _get_cnr_data(cache_mode=True, dont_wait=True) # timeout fallback
logging.error(f"[ComfyUI-Manager] A timeout occurred during the fetch process from ComfyRegistry.")
return await _get_cnr_data(sync_mode='local', dont_wait=True) # timeout fallback
async def _get_cnr_data(cache_mode=True, dont_wait=True):
def get_comfyui_ver():
is_desktop = bool(os.environ.get('__COMFYUI_DESKTOP_VERSION__'))
if is_desktop:
return manager_core.get_current_comfyui_ver() or 'unknown'
else:
return manager_core.get_comfyui_tag() or 'unknown'
def get_form_factor():
is_desktop = bool(os.environ.get('__COMFYUI_DESKTOP_VERSION__'))
system = platform.system().lower()
is_windows = system == 'windows'
is_mac = system == 'darwin'
is_linux = system == 'linux'
if is_desktop:
if is_windows:
return 'desktop-win'
elif is_mac:
return 'desktop-mac'
else:
return 'other'
else:
if is_windows:
return 'git-windows'
elif is_mac:
return 'git-mac'
elif is_linux:
return 'git-linux'
else:
return 'other'
def get_node_timestamp(node):
latest_ver = node.get('latest_version')
if isinstance(latest_ver, dict):
t = latest_ver.get('createdAt')
if t:
return t
return node.get('created_at')
async def _get_cnr_data(sync_mode=None, dont_wait=True, **kwargs):
global is_cache_loading
uri = f'{base_url}/nodes'
# For backwards compatibility with keyword argument cache_mode
if sync_mode is None:
sync_mode = kwargs.get('cache_mode', 'cache')
async def fetch_all():
# Normalize sync_mode for backwards compatibility
if sync_mode is True or sync_mode == 'cache' or sync_mode == 'local':
normalized_mode = 'cache'
elif sync_mode == 'force':
normalized_mode = 'force'
else:
normalized_mode = 'remote'
uri = f'{base_url}/nodes'
cache_path = manager_util.get_cache_path(uri)
comfyui_ver = get_comfyui_ver()
form_factor = get_form_factor()
cached_data = None
last_updated = None
full_nodes = {}
is_cache_expired = True
cache_built_at = None
cache_created_at = None
# Load local cache
if normalized_mode != 'force' and manager_util.get_cache_state(uri, expired_days=None) == 'cached':
try:
with open(cache_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
cached_data = json.load(json_file)
# Check `force_refresh_days` cache database expiration for a full refresh sync
is_db_expired = True
cache_created_at = cached_data.get('cache_created_at')
if cache_created_at:
try:
created_dt = datetime.fromisoformat(cache_created_at.replace('Z', '+00:00'))
current_dt = datetime.now(timezone.utc)
delta_created = current_dt - created_dt
if timedelta(seconds=0) <= delta_created and delta_created < timedelta(days=force_refresh_days):
is_db_expired = False
except Exception:
pass
if not is_db_expired and (cached_data.get('comfyui_ver') == comfyui_ver and
cached_data.get('form_factor') == form_factor):
last_updated = cached_data.get('last_updated')
for node in cached_data.get('nodes', []):
full_nodes[node['id']] = node
else:
logging.info(f"[ComfyUI-Manager] Registry cache DB expired ({force_refresh_days} days) or environment changed. Invalidating local cache.")
cached_data = None
full_nodes = {}
last_updated = None
cache_created_at = None
except Exception as e:
logging.error(f"[ComfyUI-Manager] Failed to read cached data: {e}")
cached_data = None
full_nodes = {}
last_updated = None
# Separate cache expiration check (1-day period)
# It just determines cache is expired, not cache is exist.
if cached_data is not None:
cache_built_at = cached_data.get('cache_built_at')
if cache_built_at:
try:
built_dt = datetime.fromisoformat(cache_built_at.replace('Z', '+00:00'))
current_dt = datetime.now(timezone.utc)
delta_dt = current_dt - built_dt
if timedelta(seconds=0) <= delta_dt and delta_dt < timedelta(days=1):
is_cache_expired = False
except Exception:
pass
# Return Cached data when mode is 'cache'
if normalized_mode == 'cache':
is_cache_loading = True
if dont_wait and cached_data is not None:
is_cache_loading = False
return cached_data.get('nodes', [])
if cached_data is not None and (sync_mode == 'local' or not is_cache_expired):
is_cache_loading = False
return cached_data.get('nodes', [])
if sync_mode == 'local':
is_cache_loading = False
return []
# Fetch CNR
async def fetch_all(timestamp_filter, existing_nodes):
remained = True
page = 1
nodes_map = dict(existing_nodes)
full_nodes = {}
# Determine form factor based on environment and platform
is_desktop = bool(os.environ.get('__COMFYUI_DESKTOP_VERSION__'))
system = platform.system().lower()
is_windows = system == 'windows'
is_mac = system == 'darwin'
is_linux = system == 'linux'
# Get ComfyUI version tag
if is_desktop:
# extract version from pyproject.toml instead of git tag
comfyui_ver = manager_core.get_current_comfyui_ver() or 'unknown'
else:
comfyui_ver = manager_core.get_comfyui_tag() or 'unknown'
if is_desktop:
if is_windows:
form_factor = 'desktop-win'
elif is_mac:
form_factor = 'desktop-mac'
else:
form_factor = 'other'
else:
if is_windows:
form_factor = 'git-windows'
elif is_mac:
form_factor = 'git-mac'
elif is_linux:
form_factor = 'git-linux'
else:
form_factor = 'other'
while remained:
# Add comfyui_version and form_factor to the API request
sub_uri = f'{base_url}/nodes?page={page}&limit=30&comfyui_version={comfyui_ver}&form_factor={form_factor}'
sub_json_obj = await asyncio.wait_for(manager_util.get_data_with_cache(sub_uri, cache_mode=False, silent=True, dont_cache=True), timeout=30)
params = {
'page': page,
'limit': 30,
'comfyui_version': comfyui_ver,
'form_factor': form_factor,
}
if timestamp_filter:
params['timestamp'] = timestamp_filter
sub_uri = f'{base_url}/nodes?{urlencode(params)}'
sub_json_obj = await asyncio.wait_for(
manager_util.get_data_with_cache(sub_uri, cache_mode=False, silent=True, dont_cache=True),
timeout=30
)
remained = page < sub_json_obj['totalPages']
for x in sub_json_obj['nodes']:
full_nodes[x['id']] = x
nodes_map[x['id']] = x
if page % 5 == 0:
print(f"FETCH ComfyRegistry Data: {page}/{sub_json_obj['totalPages']}")
logging.info(f"[ComfyUI-Manager] FETCH ComfyRegistry Data: {page}/{sub_json_obj['totalPages']}")
page += 1
time.sleep(0.5)
await asyncio.sleep(0.5)
print("FETCH ComfyRegistry Data [DONE]")
logging.info(f"[ComfyUI-Manager] FETCH ComfyRegistry Data [DONE]")
for v in full_nodes.values():
for v in nodes_map.values():
if 'latest_version' not in v:
v['latest_version'] = dict(version='nightly')
return {'nodes': list(full_nodes.values())}
if cache_mode:
is_cache_loading = True
cache_state = manager_util.get_cache_state(uri)
if dont_wait:
if cache_state == 'not-cached':
return {}
else:
print("[ComfyUI-Manager] The ComfyRegistry cache update is still in progress, so an outdated cache is being used.")
with open(manager_util.get_cache_path(uri), 'r', encoding="UTF-8", errors="ignore") as json_file:
return json.load(json_file)['nodes']
if cache_state == 'cached':
with open(manager_util.get_cache_path(uri), 'r', encoding="UTF-8", errors="ignore") as json_file:
return json.load(json_file)['nodes']
return {'nodes': list(nodes_map.values())}
try:
json_obj = await fetch_all()
manager_util.save_to_cache(uri, json_obj)
return json_obj['nodes']
except:
res = {}
print("Cannot connect to comfyregistry.")
finally:
if cache_mode:
is_cache_loading = False
json_obj = await fetch_all(last_updated, full_nodes)
return res
# Set cache's timestamp as the maximum timestamp from fetched nodes.
# This way, in the next run, only the latest updates will be fetched.
timestamps = [get_node_timestamp(node) for node in json_obj['nodes'] if get_node_timestamp(node)]
max_timestamp = max(timestamps) if timestamps else None
timestamp_format = "%Y-%m-%dT%H:%M:%SZ"
if max_timestamp:
try:
ts_str = max_timestamp.replace('Z', '+00:00')
dt = datetime.fromisoformat(ts_str) - timedelta(seconds=10)
new_timestamp = dt.strftime(timestamp_format)
except Exception:
new_timestamp = max_timestamp
else:
new_timestamp = last_updated
new_cache_built_at = datetime.now(timezone.utc).strftime(timestamp_format)
if normalized_mode == 'force' or not cache_created_at:
new_cache_created_at = datetime.now(timezone.utc).strftime(timestamp_format)
else:
new_cache_created_at = cache_created_at
cache_to_save = {
'nodes': json_obj['nodes'],
'comfyui_ver': comfyui_ver,
'form_factor': form_factor,
'last_updated': new_timestamp,
'cache_built_at': new_cache_built_at,
'cache_created_at': new_cache_created_at
}
manager_util.save_to_cache(uri, cache_to_save)
return json_obj['nodes']
except asyncio.TimeoutError:
raise
except Exception as e:
logging.error(f"[ComfyUI-Manager] Cannot connect to comfyregistry or failed sync: {e}")
if cached_data is not None:
return cached_data.get('nodes', [])
return []
finally:
if normalized_mode == 'cache':
is_cache_loading = False
@dataclass
@ -237,7 +373,7 @@ def generate_cnr_id(fullpath, cnr_id):
with open(cnr_id_path, "w") as f:
return f.write(cnr_id)
except:
print(f"[ComfyUI Manager] unable to create file: {cnr_id_path}")
logging.error(f"[ComfyUI-Manager] unable to create file: {cnr_id_path}")
def read_cnr_id(fullpath):

View File

@ -811,7 +811,7 @@ class UnifiedManager:
dont_wait = True
# reload 'cnr_map' and 'repo_cnr_map'
cnrs = await cnr_utils.get_cnr_data(cache_mode=cache_mode=='cache', dont_wait=dont_wait)
cnrs = await cnr_utils.get_cnr_data(sync_mode=cache_mode, dont_wait=dont_wait)
for x in cnrs:
self.cnr_map[x['id']] = x

View File

@ -166,8 +166,10 @@ def simple_hash(input_string):
return hash_value
def is_file_created_within_days(file_path, days):
if days is None:
return True
def is_file_created_within_one_day(file_path):
if not os.path.exists(file_path):
return False
@ -175,8 +177,10 @@ def is_file_created_within_one_day(file_path):
current_time = datetime.now().timestamp()
time_difference = current_time - file_creation_time
return time_difference <= 86400
return time_difference <= (days * 86400)
def is_file_created_within_one_day(file_path):
return is_file_created_within_days(file_path, 1)
async def get_data(uri, silent=False):
if not silent:
@ -214,12 +218,12 @@ def get_cache_path(uri):
return os.path.join(cache_dir, cache_uri+'.json')
def get_cache_state(uri):
def get_cache_state(uri, expired_days=1):
cache_uri = get_cache_path(uri)
if not os.path.exists(cache_uri):
return "not-cached"
elif is_file_created_within_one_day(cache_uri):
elif is_file_created_within_days(cache_uri, expired_days):
return "cached"
return "expired"

View File

@ -1874,9 +1874,14 @@
"DonutSave",
"DonutTiledUpscale",
"DonutUniversalDetailer",
"DonutWeightVectorScale",
"DonutWidenMergeCLIP",
"DonutWidenMergeUNet",
"DonutZitConditioningRebalance",
"DonutZitHybridApply",
"DonutZitHybridLoader",
"DonutZitHybridOverride",
"DonutZitHybridSave",
"DonutZitLayerBlendEncode",
"LoadLBW //Inspire",
"LoraBlockInfo //Inspire",
@ -3484,6 +3489,7 @@
"MpiReroute",
"MpiRoundToMultiple",
"MpiRoundToMultipleRes",
"MpiSaveVideo",
"MpiScaledDimensions",
"MpiSimpleBoolean",
"MpiString",
@ -7217,7 +7223,10 @@
"WanMoveSVI_FLF_Mask",
"WanMoveSVI_FLF_Stitch",
"WanMoveSVI_FLF_Visualize",
"WanMoveSVI_FLF_v2"
"WanMoveSVI_FLF_v2",
"Wan_Float",
"Wan_Integer",
"Wan_Length"
],
{
"title_aux": "ComfyUI-WanMoveSVI_FLF_v2"
@ -8889,6 +8898,7 @@
"ETNodes-Color-Selector",
"ETNodes-Gemini-API-Image",
"ETNodes-Gemini-API-Text",
"ETNodes-Gemini-API-Video",
"ETNodes-List-Items",
"ETNodes-List-Selector",
"ETNodes-Text-Preview"

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,85 @@
{
"custom_nodes": [
{
"author": "younestft",
"title": "Comfy EverAnimate",
"reference": "https://github.com/younestft/Comfy_EverAnimate",
"files": [
"https://github.com/younestft/Comfy_EverAnimate"
],
"install_type": "git-clone",
"description": "Native ComfyUI nodes for EverAnimate-style chunked WanAnimate workflows, including master/chunk settings, chunk calculation, image carry-over, and boundary color correction."
},
{
"author": "Moon-NE",
"title": "MoonNe_Nodes",
"reference": "https://github.com/Moon-NE/MoonNe_Nodes",
"files": [
"https://github.com/Moon-NE/MoonNe_Nodes"
],
"install_type": "git-clone",
"description": "Custom nodes for text operations, including concatenation, horizontal-to-vertical conversion, and batch processing."
},
{
"author": "TechnoWarrior2",
"title": "ComfyUI Image Picker",
"reference": "https://github.com/TechnoWarrior2/comfyui-image-picker",
"files": [
"https://github.com/TechnoWarrior2/comfyui-image-picker"
],
"install_type": "git-clone",
"description": "Pauses your workflow and opens a popup window to manually pick which generated images pass through to the rest of the graph."
},
{
"author": "TechnoWarrior2",
"title": "ComfyUI Live Preview",
"reference": "https://github.com/TechnoWarrior2/comfyui-live-preview",
"files": [
"https://github.com/TechnoWarrior2/comfyui-live-preview"
],
"install_type": "git-clone",
"description": "Displays a large draggable floating window with live denoising step previews as your image generates, similar to A1111 and Forge."
},
{
"author": "shootthesound",
"title": "Lighthouse",
"reference": "https://github.com/shootthesound/comfyui-lighthouse",
"files": [
"https://github.com/shootthesound/comfyui-lighthouse"
],
"install_type": "git-clone",
"description": "A non-destructive overlay that lights up every node by graph distance from the one you click. Diagnostic for big workflows, educational for understanding workflows others built, and surgical when you need to focus on one neighbourhood at a time."
},
{
"author": "shootthesound",
"title": "CleanFreak",
"reference": "https://github.com/shootthesound/comfyui-CleanFreak",
"files": [
"https://github.com/shootthesound/comfyui-CleanFreak"
],
"install_type": "git-clone",
"description": "One-click tidy-by-role for any ComfyUI workflow — loaders, encoders, samplers, decoders, and outputs each sorted into their own column with coloured group cards and connections preserved. 1200+ node classes pre-classified out of the box."
},
{
"author": "shootthesound",
"title": "Finding LoRA",
"reference": "https://github.com/shootthesound/comfyui-lora-FindingLora",
"files": [
"https://github.com/shootthesound/comfyui-lora-FindingLora"
],
"install_type": "git-clone",
"description": "A LoRA loader with bookmarks, trigger-word storage and click-to-copy, fuzzy search, and a one-click button to drop another loader inline and wire it into the model chain automatically."
},
{
"author": "shootthesound",
"title": "Image of the Day",
"reference": "https://github.com/shootthesound/comfyui-image-of-the-day",
"files": [
"https://github.com/shootthesound/comfyui-image-of-the-day"
],
"install_type": "git-clone",
"description": "Fetch a fresh image straight into your workflow from 8 daily/random sources. Useful for prompt testing, style references, daily-image automations, or just kicking off a workflow with something interesting."
},
{
"author": "boobkake22",
"title": "Sampling Planner",

View File

@ -3876,6 +3876,7 @@
"Beaufort",
"Bifid",
"Binary2String",
"BitsCounter",
"BitwiseAND",
"BitwiseLS",
"BitwiseNOT",
@ -3897,6 +3898,11 @@
"ConcatKDFHash_Derive",
"ConcatKDFHash_Verify",
"ConstantTimeCompare",
"DERPrivateKey",
"DERPublicKey",
"ECPrivateKey",
"ECPublicKey",
"ECSign",
"EdDSAPrivateKeyFormat",
"EdDSAPublicKeyFormat",
"EdDSASignature",
@ -3921,6 +3927,8 @@
"Nihilist",
"PBKDF2HMAC_Derive",
"PBKDF2HMAC_Verify",
"PEMPrivateKey",
"PEMPublicKey",
"Padding",
"Playfair",
"Polybius",
@ -3956,6 +3964,7 @@
"X963KDF_Derive",
"X963KDF_Verify",
"XExchange",
"XOFHash",
"XPrivateKeyFormat",
"XPublicKeyFormat",
"Zigzag"
@ -26816,6 +26825,7 @@
"XB_AutoBubbleTextRenderer",
"XB_BatchFolderLoader",
"XB_BerniniConditioning",
"XB_BerniniPromptRouter",
"XB_CLIPNameBroadcaster",
"XB_CanvasLabel",
"XB_CheckpointBlockSwap",
@ -26827,6 +26837,7 @@
"XB_HumanSegModelLoader",
"XB_HumanSegmentation",
"XB_ImageParamsMaster",
"XB_K2StyleRouter",
"XB_KSampler",
"XB_KSamplerAdvanced",
"XB_MSR",